# Component: Template Engine ## Purpose The Template Engine is the core modeling component that lives on the central cluster. It manages the definition, inheritance, composition, and resolution of machine templates — the blueprints from which all machine instances are created. It handles flattening templates into deployable configurations, calculating diffs between deployed and current states, and performing comprehensive pre-deployment validation. ## Location Central cluster only. Sites receive flattened output and have no awareness of templates. ## Responsibilities - Store and manage template definitions (attributes, alarms, scripts) in the configuration database. - Enforce inheritance (is-a) relationships between templates. - Enforce composition (has-a) relationships, including recursive nesting of feature modules. - Detect and reject naming collisions when composing feature modules (design-time error). - Resolve the attribute chain: Instance → Child Template → Parent Template → Composing Template → Composed Module. - Enforce locking rules — locked members cannot be overridden downstream, intermediate levels can lock previously unlocked members, and nothing can unlock what's locked above. - Support adding new attributes, alarms, and scripts in child templates. - Prevent removal of inherited members. - Flatten a fully resolved template + instance overrides into a deployable configuration (no template structure, just concrete attribute values with resolved data connection bindings). - Calculate diffs between deployed and template-derived configurations. - Perform comprehensive pre-deployment validation (see Validation section). - Provide on-demand validation for Design users during template authoring. - Enforce template deletion constraints — templates cannot be deleted if any instances or child templates reference them. ## Key Entities ### Template - Has a unique name/ID. - Optionally extends a parent template (inheritance). - Contains zero or more composed feature modules (composition). - Defines attributes, alarms, and scripts as first-class members. - Cannot be deleted if referenced by instances or child templates. - Concurrent editing uses **last-write-wins** — no pessimistic locking or conflict detection. ### Attribute - Name, Value, Data Type (Boolean, Integer, Float, String), Lock Flag, Description. - Optional Data Source Reference — a **relative path** within a data connection (e.g., `/Motor/Speed`). The template defines *what* to read but not *where* to read it from. The connection binding is an instance-level concern. - Value may be empty if intended to be set at instance level or via data connection binding. ### Alarm - Name, Description, Priority Level (0–1000), Lock Flag. - Trigger Definition: Value Match, Range Violation, or Rate of Change. - Optional On-Trigger Script reference. ### Script (Template-Level) - Name, Lock Flag, C# source code. - Trigger configuration: Interval, Value Change, Conditional, or invoked by alarm/other script. - Optional minimum time between runs. - **Parameter Definition** *(optional)*: Defines input parameters (name and data type per parameter). Scripts without parameters accept no arguments. - **Return Value Definition** *(optional)*: Defines the structure of the script's return value (field names and data types). Supports single objects and lists of objects. Scripts without a return definition return void. ### Instance - Associated with a specific template and a specific site. - Assigned to an area within the site. - Can override non-locked attribute values (no adding/removing attributes). - Bound to data connections at instance creation — **per-attribute binding** where each attribute with a data source reference individually selects its data connection. - Can be in **enabled** or **disabled** state. - Can be **deleted** — deletion is blocked if the site is unreachable. ### Area - Hierarchical groupings per site (parent-child). - Stored in the configuration database. - Used for filtering/organizing instances in the UI. ## Naming Collision Detection When a template composes two or more feature modules, the system must check for naming collisions across: - Attribute names - Alarm names - Script names If any composed module introduces a name that already exists (from another composed module or from the composing template itself), this is a **design-time error**. The template cannot be saved until the conflict is resolved. Collision detection is performed recursively for nested module compositions. ## Flattening Process When an instance is deployed, the Template Engine resolves the full configuration: 1. Start with the base template's attributes, alarms, and scripts. 2. Walk the inheritance chain, applying overrides at each level (respecting locks). 3. Resolve composed feature modules, applying overrides from composing templates (respecting locks). 4. Apply instance-level overrides (respecting locks). 5. Resolve data connection bindings — replace connection name references with concrete connection details from the site. 6. Output a flat structure: list of attributes with resolved values and data source addresses, list of alarms with resolved trigger definitions, list of scripts with resolved code and triggers. ## Diff Calculation The Template Engine can compare: - The **currently deployed** flat configuration of an instance. - The **current template-derived** flat configuration (what the instance would look like if redeployed now). The diff output identifies added, removed, and changed attributes/alarms/scripts. ## Pre-Deployment Validation Before a deployment is sent to a site, the Template Engine performs comprehensive validation: - **Flattening**: The full template hierarchy resolves and flattens without errors. - **Naming collision detection**: No duplicate attribute, alarm, or script names in the flattened configuration. - **Script compilation**: All instance scripts and alarm on-trigger scripts are test-compiled and must compile without errors. - **Alarm trigger references**: Alarm trigger definitions reference attributes that exist in the flattened configuration. - **Script trigger references**: Script triggers (value change, conditional) reference attributes that exist in the flattened configuration. - **Data connection binding completeness**: Every attribute with a data source reference has a data connection binding assigned on the instance, and the bound data connection name exists as a defined connection at the instance's site. - **Exception**: Validation does **not** verify that data source relative paths resolve to real tags on physical devices — that is a runtime concern. ### On-Demand Validation The same validation logic is available to Design users in the Central UI without triggering a deployment. This allows template authors to check their work for errors during authoring. ### Shared Script Validation For shared scripts, pre-compilation validation is performed before deployment. Since shared scripts have no instance context, validation is limited to C# syntax and structural correctness. ## Dependencies - **Configuration Database (MS SQL)**: Stores all templates, instances, areas, and their relationships. - **Security & Auth**: Enforces Design role for template authoring, Deployment role for instance management. - **Configuration Database (via IAuditService)**: All template and instance changes are audit logged. ## Interactions - **Deployment Manager**: Requests flattened configurations, diffs, and validation results from the Template Engine. - **Central UI**: Provides the data model for template authoring, instance management, and on-demand validation.