Comprehensive product knowledge, for AI integration builders and advanced users.
Platform → Overview | Architecture | Technology | Security | FrameworX | Editions
This page provides a comprehensive view of the FrameworX platform architecture, covering every module, data model, syntax rule, and integration pattern. It is designed for AI assistants working with FrameworX MCP services, system integrators building complex solutions, and advanced users who want a single-page understanding of how all platform components connect.
For getting started, see [Quick Start Guide]. For module-specific tutorials, see [BUILD section]. This page is the architectural map — not a tutorial.
This page provides a comprehensive view of the FrameworX platform architecture, covering every module, data model, syntax rule, and integration pattern. It is designed for AI assistants working with FrameworX MCP services, system integrators building complex solutions, and advanced users who want a single-page understanding of how all platform components connect.
For getting started, see [Quick Start Guide]. For module-specific tutorials, see [BUILD section]. This page is the architectural map — not a tutorial.
FrameworX is a unified SCADA/HMI/IIoT platform built on .NET, designed for industrial automation, process monitoring, and real-time data management. The platform runs on dual frameworks — .NET Framework 4.8 for Windows deployments and .NET 8 for multiplatform deployments including Linux, Docker, and edge devices.
All modules ship in a single product with edition-based licensing. There is no module stacking — every installation includes the full platform: data management, device communication, alarms, historian, scripting, datasets, reports, displays, and security. Solutions scale from edge gateways to enterprise operations centers without changing the architecture.
Platform components:
The Solution Designer is the Windows-based configuration environment where solutions are built and tested. The Runtime Engine (TServer.exe) executes solutions on any supported platform. Operator interfaces run as Rich Clients (WPF desktop), Web Clients (WebAssembly via Blazor), or Mobile Clients. The Solution Manager provides a visual launcher for selecting and starting solutions.
FrameworX provides two AI integration services through the Model Context Protocol (MCP). The MCP for Designer service connects AI models to the Designer application for solution configuration — creating tags, displays, alarms, and all other objects through natural language. The MCP for Runtime service connects to running solutions for live data access — querying tag values, alarm status, and historian data. Both services enable AI-assisted industrial automation without requiring programming knowledge.
Everything in FrameworX is an object in a unified namespace. Configuration, runtime, and navigation are three views of the same data:
| Configuration Table | Runtime Namespace Path | What It Represents |
|---|---|---|
| UnsTags, row "Tank1/Level" | Tag.Tank1/Level | A process data point |
| AlarmsGroups, row "Critical" | Alarm.Group.Critical | An alarm behavior group |
| DevicesNodes, row "PLC1" | Device.Node.PLC1 | A connected field device |
| ScriptsTasks, row "Startup" | Script.Task.Startup | An automation script |
| DisplaysList, row "MainPage" | Display.MainPage | An operator screen |
When you create a row in a configuration table, it immediately becomes a runtime object accessible via its namespace path. There is no separate deployment or compilation step — the runtime reads directly from the solution database.
Solutions are stored as .dbSLN files (SQLite databases containing all configuration tables). This single-file format supports atomic solution management, JSON export/import per table for Git-based version control, and full solution export as ZIP archives for DevOps workflows.
FrameworX uses two separators with precise, distinct roles:
Forward slash (/) is used exclusively for folder hierarchy within the Unified Namespace asset tree. Only Tags and Symbols use slashes in their names to represent organizational folders:
Area1/Line1/Tank1
Dot (.) is used for namespace separation, UDT member access, and property access. Built-in namespaces (Server, Client, Alarm, Device, and all others) are .NET object hierarchies that always use dots:
Tag.Area1/Line1/Loop1.Setpoint.Quality
In this example, Tag is the namespace (dot), Area1/Line1/Loop1 is the folder path (slashes), Setpoint is a UDT member (dot), and Quality is a property (dot).
Mixing these separators is the most common integration error. Built-in namespaces never use slashes — Server.DateTimeInfo.Second is correct, Server/DateTimeInfo/Second is not. Tag paths never use dots for folders — Tag.Area1/Line1/Tank1 is correct, Tag.Area1.Line1.Tank1 is not.
Object references follow different syntax rules depending on where they appear:
In expressions (alarm limits, calculated fields, expression editor), use the object path directly without any prefix. The expression editor accepts a relaxed syntax compatible with C#, VB.NET, and JavaScript conventions:
Tag.Integer1 + Tag.Integer2
If(Tag.Integer1 < 100, Tag.Integer1 + 1, 0)
Tag.Integer1 + Math.Abs(Tag.Integer2)
Tag.Integer1 + Script.Class.Class1.Calculate(Tag.Integer2)
In code (Script Tasks, Script Classes, Display CodeBehind), prefix references with @ to distinguish runtime objects from local variables:
double level = @Tag.Tank1/Level.Value;
int second = @Server.DateTimeInfo.Second;
In display bindings (tag binding on display elements), use the @ prefix:
@Tag.Tank1/Level
In string interpolation contexts, use curly braces:
Current Level: {Tag.Tank1/Level}
.Value is the default property for Tags. Writing @Tag.Tank1 and @Tag.Tank1.Value is equivalent. Other tag properties must be specified explicitly: @Tag.Tank1.Quality, @Tag.Tank1.Min, @Tag.Tank1.Max, @Tag.Tank1.Timestamp.
Built-in namespaces do not use .Value — they expose named properties directly. Use @Server.DateTimeInfo.Second, not @Server.DateTimeInfo.Second.Value.
The Asset function provides dynamic access to the Unified Namespace:
Asset("Machine1/Level").Value — static path, equivalent to @Tag.Machine1/Level.Value
Asset(Tag.SelectedPath).Value — dynamic path resolved at runtime
Asset paths use no namespace prefix — they map directly to the UNS hierarchy. This function is essential for TagProvider-sourced tags with dynamic addresses, where the tag path is not known at configuration time.
Different tables use different key columns, and understanding which format each expects prevents common integration errors:
Name is used by most tables (UnsTags, AlarmsGroups, DevicesChannels, DevicesNodes, DisplaysList, ScriptsTasks, and others). It creates a standalone named object. Format: plain name or path like Machine1/Tag1 — no namespace prefix, no leading slash.
TagName is used by AlarmsItems, HistorianHistorianTags, and DevicesPoints. It binds configuration to an existing tag. Format: tag path only, like Machine1/Tag1 — no Tag. prefix, no leading slash.
ObjectName is used by ScriptsExpressions. It binds a calculation to a namespace object. Format: full namespace path like Tag.Machine1/Level — requires the namespace prefix, no @, no .Value.
Singleton tables (SolutionSettings, AlarmsGlobalSettings, RuntimeStartup) have no key column — they contain a single configuration row.
The Tags module provides the Unified Namespace (UNS) — the central real-time data repository that all other modules connect to.
UnsTags contains process data points organized in a hierarchical folder structure using / separators. The Name column holds the full path: Area1/Line1/Tank1/Level. Supported data types include Digital (Boolean), Integer, Double, String, DateTime, TimeSpan, and JSON.
Tags have a Domain property: Server domain (default) synchronizes values across all connected clients, while Client domain keeps values local to each client instance. Built-in client tags like @Client.UserName and @Client.Session.ComputerNameprovide session context.
UnsUserTypes defines custom tag templates (UDTs). When a UserType is defined with members such as Setpoint, ProcessValue, and AlarmLimit, creating a tag of that type automatically creates all member tags. Modifying the UserType definition auto-updates every tag instance — members are added, removed, or changed across the entire solution automatically. Members are accessed via dot notation: Tag.Loop1.Setpoint.
UnsTagProviders connects external data sources that dynamically populate the UNS with tags. When a TagProvider connects to an MQTT broker or OPC UA server, it discovers and creates tags automatically.
UnsEnumerations maps between numeric values and human-readable text labels.
The Devices module connects FrameworX to PLCs, sensors, controllers, and other field equipment through a three-layer architecture:
DevicesChannels configures the communication protocol. FrameworX includes 70+ native drivers: OPC UA, OPC DA, Modbus TCP/RTU, Siemens S7, Allen-Bradley EtherNet/IP, MQTT, MQTT Sparkplug B, BACnet, DNP3, IEC 61850, and many more.
DevicesNodes defines individual device addresses within a channel. Each node belongs to exactly one channel.
DevicesPoints maps tags to device addresses. Each point references an existing tag (via TagName) and specifies the device register or address to read/write. Points belong to nodes.
Six columns in Nodes and Points are protocol-dependent: ProtocolOptions, Interface, PrimaryStation, BackupStation, Address, and DataType. Their valid values change based on the protocol selected in the parent Channel. When configuring devices programmatically, always query the protocol schema to determine valid field values and formats.
AlarmsGroups defines behavior rules including notification methods, escalation procedures, and acknowledgment requirements. Three groups are predefined: Critical (highest severity), Warning (operational attention), and AuditTrail (logging without operator notification).
AlarmsItems creates individual alarm triggers bound to tags. Each item references a tag via the TagName column and belongs to a group. Items define the alarm condition (high limit, low limit, rate of change, digital state change, etc.).
AlarmsAreas provides optional organizational hierarchy for grouping alarms by plant area, equipment type, or other criteria. Areas are not required for basic alarm configuration.
AlarmsGlobalSettings is a singleton table containing alarm module defaults such as acknowledgment requirements and notification options.
HistorianStorageLocations defines where historical data is stored. The predefined TagHistorian location uses SQLite by default and can be changed to SQL Server, PostgreSQL, or other supported databases.
HistorianHistorianTables coordinates storage behavior — how frequently data is sampled, how long it is retained, and what compression is applied. The predefined Table1 provides default settings connected to the TagHistorian storage location.
HistorianHistorianTags specifies which tags are logged to which historian table, referenced via the TagName column.
The Datasets module provides bidirectional database access for SQL integration, reporting data sources, and external system connectivity.
DatasetsDBs stores database connection strings. Four databases are predefined and serve platform functions: TagHistorian (historian storage, default SQLite), AlarmHistorian (alarm event logging), Retentive (tag value persistence across restarts), and RuntimeUsers (runtime user management extending the Security module). These predefined databases can be reconfigured (for example, switching from SQLite to SQL Server) but cannot be deleted.
DatasetsQueries contains SQL query definitions for reading and writing data. These are document objects — when updated, the entire query definition is replaced rather than merged.
DatasetsTables provides direct binding to database tables without writing SQL.
DatasetsFiles handles file-based data operations independent of database connections.
The Scripts module supports three languages: C#, VB.NET, and Python. Cross-language interoperability is fully supported — a C# task can call a Python class and vice-versa.
ScriptsTasks are event-triggered code blocks that run when activated by server events, tag value changes, or timer intervals. Task code is written as a method body — the platform provides the execution wrapper including exception handling and thread management. Tasks execute independently and cannot be instantiated or called from other code. Predefined tasks ServerStartup and ServerShutdown run automatically at runtime start and stop.
ScriptsClasses are reusable code libraries defined as full class definitions. Classes can be instantiated, have methods with parameters and return values, and be called from tasks, other classes, display CodeBehind, and even from external systems via the MCP for Runtime service. At runtime, class methods are accessible as Script.Class.ClassName.MethodName().
ScriptsExpressions bind one-line calculations to namespace objects. The ObjectName column uses the full namespace format (Tag.Machine1/Level) — this is the only context where the Tag. prefix is required in a key column.
ScriptsReferences registers external .NET DLL libraries for use in scripts — an advanced feature for integrating custom compiled code.
The Displays module provides the visualization layer with two distinct display paradigms:
Canvas displays use absolute pixel positioning, giving full control over element placement. This is the traditional approach for HMI/SCADA screens with specific layout requirements.
Dashboard displays use a grid-based responsive layout that adapts to different screen sizes. This approach suits data-centric monitoring screens where precise positioning is less important than information density.
Displays can be classified as Pages (navigable screens loaded into layout regions) or Dialogs and Popups (modal or floating windows for focused interaction).
Every display has two editing surfaces. The Draw tab contains graphical elements — shapes, controls, gauges, charts, and symbols arranged visually. The CodeBehind tab contains C# or VB.NET code for event handling and custom actions such as DisplayOpening events, button click handlers, and custom logic. CodeBehind code lives inside the display object, separate from the Scripts module.
Display elements fall into several categories. Shapes (Rectangle, Ellipse, Polygon, Polyline, Path, Line) are basic drawing primitives. Controls (TextBlock, TextBox, Button, ComboBox, DataGrid, AlarmViewer, TrendChart, and approximately 50 others) are platform-provided components with configurable properties and fixed internal behavior. Gauges (CircularGauge, LinearGauge, DigitalGauge) visualize numeric data. Symbols are user-authored reusable graphic components that can be designed from scratch with any combination of shapes, controls, and dynamic behaviors.
Symbols deserve special attention. Unlike controls which have fixed behavior, symbols are fully customizable components created by solution developers. FrameworX provides five WizardSymbols (TANK, VALVE, PUMP, MOTOR, BLOWER) with built-in dynamic behavior and easy appearance customization — these cover the most common industrial visualization needs. The Symbols Library contains approximately 1,600 additional pre-built symbols (roughly 800 with dynamic behavior and 800 drawing-only) that can be imported into solutions. Symbols referenced in displays that are not present in the solution are auto-imported from the shared library automatically.
DisplaysLayouts defines the screen regions for the running application. A layout can include up to five regions: Header (top), Footer (bottom), Menu (left side), SubMenu (right side), and Content (center, filling remaining space). A StartupLayout object determines which regions are active and which display loads in each region when the solution starts.
MainPage plays a dual role. It is the default display loaded into the Content region at startup, and it also serves as the solution preview image — the Solution Manager shows whatever is rendered on MainPage as the solution thumbnail when selecting solutions to open.
ReportsForms defines document-based reports with formatted output. ReportsWebData provides JSON and XML data feeds. Both are independent of each other and depend only on the tags referenced within them.
The Security module manages authentication, authorization, and access control through four tables:
SecurityUsers defines user accounts. Three users are predefined: Administrator (full access), Guest (read-only), and User (standard operations).
SecurityPermissions defines permission groups used for command authorization. Displays reference these groups to control which users can execute specific actions (such as acknowledging alarms or changing setpoints). Seven groups are predefined for common industrial roles: Administrator, Guest, Maintenance, Engineering, Supervisor, Operator, and User. Additional placeholder groups are available for custom permission schemes.
SecurityPolicies defines session and password rules. Three policies are predefined: Default, Enhanced, and Critical. Additional placeholder policies are available for custom requirements.
SecuritySecrets stores credentials for external system authentication. Secret values are write-only and cannot be read back through any API.
Three singleton configuration tables control global solution behavior:
SolutionSettings contains global solution parameters. AlarmsGlobalSettings provides alarm module defaults. RuntimeStartup controls startup behavior, execution profile selection, and runtime options.
The FrameworX runtime follows a seven-step startup sequence:
Development profile provides unrestricted access for configuration, testing, and debugging. Production profile enforces operational restrictions appropriate for live industrial environments. The MCP for Designer service operates under the Development profile.
In addition to module namespaces (Tag, Alarm, Device, etc.), FrameworX provides built-in system namespaces:
Server exposes server-side system information including date/time components (Server.DateTimeInfo.Second, Server.DateTimeInfo.Hour), system monitoring (Server.SystemMonitor.CPUUsage), and solution state.
Client exposes client-side session information including the logged-in user (Client.UserName), session details (Client.Session.ComputerName), and UI simulation tags (Client.UI.*).
Info provides solution metadata including solution name and version information.
These namespaces are browseable at runtime — use the MCP browse functionality or Designer's runtime navigation to discover all available properties.
Tags with Server domain (the default) have their values synchronized across all connected clients. A value change made by one operator is immediately visible to all others.
Tags with Client domain maintain separate values for each client instance. These are used for UI state, user preferences, navigation context, and session-specific data that should not propagate to other users.
Solution configurations can be exchanged as JSON files organized per table. Each file contains a header identifying the solution and table type, followed by an array of objects:
{
"SolutionName": "MySolution",
"TableType": "UnsTags",
"ObjectCount": 42,
"Objects": [
{ "Name": "Tank1/Level", "Type": "Double", "Min": 0, "Max": 100 },
{ "Name": "Tank1/Temp", "Type": "Double", "Min": -40, "Max": 200 }
]
}
Full solution exports produce ZIP archives containing one JSON file per table.
Simple objects (Tags, Alarm Groups, Device Nodes, Historian Tags, and most other table rows) support property merge on write. When updating, only the fields included in the JSON are modified — all other fields retain their current or default values. This allows targeted updates without reading the full object first.
Document objects (Displays, Symbols, Script Tasks, Script Classes, Dataset Queries, Report Forms, and Report WebData) require full replacement on write. The entire object definition is replaced with the provided JSON. To modify a document object safely, first read its current configuration, apply changes to the JSON, then write the complete modified version back.
FrameworX provides built-in audit and diagnostic capabilities through four system tables:
RecentChanges maintains an audit trail of all configuration modifications — who changed which object, when, and what was modified.
VersionControl tracks table version numbers for change detection and synchronization.
CrossReference maps object usage across the entire solution, answering questions like "which displays reference Tag.Tank1/Level?" or "which alarm items use the Critical group?"
UseCount provides usage frequency statistics for optimization and cleanup — identifying unused tags, orphaned alarm items, or other configuration artifacts.
These tables are query-only diagnostic tools available through the MCP get_track_changes operation.
FrameworX provides two separate Model Context Protocol services for AI integration:
MCP for Designer connects AI models to the Solution Designer application. This service enables AI-assisted solution configuration: creating and modifying tags, displays, alarms, device connections, scripts, and all other solution objects. When AI executes a command, the Designer UI navigates to the relevant screen so users can observe changes in real time. This service operates at configuration time — it builds and modifies solutions.
MCP for Runtime connects AI models to running solutions via TServer.exe. This service provides live data access: querying current tag values, alarm status and history, historian data for trend analysis, and UNS structure exploration. The Runtime service also supports custom MCP tools created through Script Classes, allowing solution developers to expose solution-specific calculations, procedures, or business logic as AI-callable functions. This service operates at execution time — it queries and interacts with operational data.
The two services are completely independent processes with no shared state. They can run simultaneously, allowing AI to both configure solutions and query live data in the same workflow.
FrameworX uses a category label system to control which objects AI can modify through the MCP for Designer service. Objects created through MCP tools are automatically labeled for AI access. In new solutions created from templates, all predefined objects (MainPage, default alarm groups, predefined databases) are also labeled, giving AI full creative control from the start.
For existing solutions that were not created through AI, objects must be explicitly labeled for AI access by the solution developer. This prevents AI from accidentally modifying production configurations while still allowing intentional AI-assisted modification of specific objects.
| Term | Definition |
|---|---|
| Solution | A FrameworX project stored as a .dbSLN file containing all configuration |
| Tag | A data element in the Unified Namespace — the atomic unit of real-time data |
| UserType (UDT) | A custom tag template that defines member tags and auto-updates instances |
| Point | A tag mapped to a physical device address for reading/writing field data |
| Channel | A protocol configuration defining how to communicate with a class of devices |
| Node | A specific device address within a channel |
| Display | An operator interface screen (Canvas for absolute layout, Dashboard for grid layout) |
| Symbol | A user-authored reusable graphic component with customizable appearance and behavior |
| WizardSymbol | A pre-built symbol (TANK, VALVE, PUMP, MOTOR, BLOWER) with easy customization |
| CodeBehind | C# or VB.NET code embedded in a display for event handling and custom actions |
| Layout | A screen region definition (Header, Footer, Menu, SubMenu, Content) for the running application |
| Hot Reload | Applying configuration changes to a running solution without restart |
| Execution Profile | Development (unrestricted) or Production (operational restrictions) mode |
| TagProvider | An external data source that dynamically populates the UNS with tags |
| Asset() | A function for dynamic access to UNS paths, essential for TagProvider data |
| SolutionCenter | The application for selecting, launching, and managing solutions |
Getting Started: [Quick Start Guide] — Build your first solution in 30 minutes
Module Tutorials: [BUILD section] — Step-by-step guides for each module
Technical Reference: [Reference section] — Complete property documentation for all tables
Connection Library: [Connectors] — Protocol-specific configuration guides for 70+ drivers
AI Integration: [MCP for Designer Connector] | [MCP for Runtime Connector] — Setup and usage guides for AI-assisted workflows
Solution Examples: [Solution Examples] — Downloadable working solutions demonstrating common patterns
FrameworX 10.1 — The Modern SCADA Platform. Built on .NET. Unified by Design. © Tatsoft LLC