Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

title: "Getting Started New Solution — First Solution Creation with Tags, Simulator, and Dashboard" tags: [getting-started, beginner, first-solution, simulator, tutorial] description: "Create a complete starter solution: tags, Value Simulator device, historian logging, basic alarms, and a dashboard display" version: "1.0" author: "Tatsoft"

...

What This Skill Does

Build a complete starter solution from scratch: create tags organized by asset, connect a Value Simulator for testing, configure historian logging and basic alarms, and create a dashboard to visualize everything.

...

  1. UNS (Tags) → 2. Industrial (Devices, Alarms, Historian) → 3. Business (Scripts) → 4. Client (Displays)

When to Use This Skill

Use when:

  • User says "create a new solution" or "get me started"
  • User wants a demo or proof-of-concept
  • User is new to FrameworX
  • Building a solution with simulated data for testing

...

  • User has a specific protocol in mind (Modbus, OPC UA, etc.) — adapt the Devices steps accordingly, but the overall flow remains the same
  • User only needs to modify an existing solution
  • User wants a specific advanced feature (use the relevant module skill)

Prerequisites

  • FrameworX Designer installed and running
  • MCP tools connected

MCP Tools and Tables

CategoryItems
Toolsopen_solution, get_table_schema, write_objects, get_objects, list_protocols, list_elements, designer_action, get_solution_info
TablesUnsTags, DevicesChannels, DevicesNodes, DevicesPoints, HistorianHistorianTags, HistorianHistorianTables, AlarmsItems, DisplaysList

Implementation Steps

Step 1: Create the Solution

open_solution('MyFirstSolution', template='Blank')

...

After open_solution completes, the full engineering context is delivered. Proceed to the next step — do not pre-fetch schemas.

Step 2: Create Tags (Pillar 1 — UNS)

Fetch the tag schema first:

...

Naming convention: Use consistent asset paths so the same display template can be reused for Tank1, Tank2, etc. via asset navigation.

Step 3: Connect Value Simulator (Pillar 2a — Devices)

The Value Simulator generates changing data for testing — no real device needed. It's a built-in protocol.

3a: Get Protocol Details

list_protocols('ValueSimulator')

This returns the protocol-specific field formats for Channel, Node, and Point configuration. Never guess these formats — always fetch first.

3b: Fetch Device Schemas

get_table_schema('DevicesChannels,DevicesNodes,DevicesPoints')

3c: Create the 3-Table Pipeline

Devices follow a strict pipeline: Channel → Node → Point. All three are required, and dependencies must exist before referencing objects.

...

Adapt the protocol-specific fields (Address, ProtocolOptions, etc.) based on what list_protocols('ValueSimulator') returned.

Step 4: Configure Historian (Pillar 2b)

4a: Check if Default Table Exists

Most solutions include a default StorageLocation and Table1:

...

get_table_schema('HistorianStorageLocations,HistorianHistorianTables')

4b: Log Tags to Historian

get_table_schema('HistorianHistorianTags')

...

  • DeadBand: minimum value change before logging (0 = log every change)
  • Deviation: overrides interval-based logging when value changes significantly
  • Boolean tags (ValveOpen) typically don't need historian logging in a starter

Step 5: Add Basic Alarms (Pillar 2c)

Alarms use predefined groups: Critical, Warning, AuditTrail.

...

Repeat a similar pattern for Tank2 tags as appropriate.

Step 6: Create Dashboard (Pillar 4 — Displays)

Now build the operator interface. For a starter solution, write directly into the predefined MainPage display.

6a: Fetch Element Schemas

list_elements('Dashboard,TrendChart,CircularGauge,TextBlock')
get_table_schema('DisplaysList')

6b: Write the Dashboard

{
  "table_type": "DisplaysList",
  "data": [{
    "ObjectName": "MainPage",
    "PanelType": "Dashboard",
    "Columns": 4,
    "Rows": 3,
    "Content": [
      {
        "Type": "TextBlock",
        "Text": "Plant Overview",
        "Column": 0, "Row": 0, "ColumnSpan": 4,
        "FontSize": 24, "HorizontalAlignment": "Center"
      },
      {
        "Type": "CircularGauge",
        "Value": "@Tag.Plant/Tank1/Level.Value",
        "Minimum": 0, "Maximum": 100,
        "Column": 0, "Row": 1,
        "Header": "Tank 1 Level"
      },
      {
        "Type": "CircularGauge",
        "Value": "@Tag.Plant/Tank1/Temperature.Value",
        "Minimum": 0, "Maximum": 100,
        "Column": 1, "Row": 1,
        "Header": "Tank 1 Temp"
      },
      {
        "Type": "CircularGauge",
        "Value": "@Tag.Plant/Tank2/Level.Value",
        "Minimum": 0, "Maximum": 100,
        "Column": 2, "Row": 1,
        "Header": "Tank 2 Level"
      },
      {
        "Type": "CircularGauge",
        "Value": "@Tag.Plant/Tank2/Temperature.Value",
        "Minimum": 0, "Maximum": 100,
        "Column": 3, "Row": 1,
        "Header": "Tank 2 Temp"
      },
      {
        "Type": "TrendChart",
        "Column": 0, "Row": 2, "ColumnSpan": 4,
        "Pens": [
          { "TagName": "@Tag.Plant/Tank1/Level", "Color": "#FF2196F3", "Label": "T1 Level" },
          { "TagName": "@Tag.Plant/Tank2/Level", "Color": "#FFFF9800", "Label": "T2 Level" }
        ]
      }
    ]
  }]
}

...

Note: Verify TrendChart Pens schema against list_elements('TrendChart') output — the exact property names may vary.

Step 7: Start Runtime

designer_action('start_runtime')

The Value Simulator starts feeding changing data. Historian begins logging. Alarms evaluate against the setpoints. The dashboard shows live values.

Verification

After starting runtime:

  1. get_solution_info() — confirm object counts match expectations
  2. Navigate to MainPage: designer_action('navigate', 'Displays', 'Draw', 'MainPage') — dashboard should show live gauge values
  3. Navigate to AlarmsMonitor: designer_action('navigate', 'Alarms', 'AlarmsMonitor') — alarms should evaluate against limits when simulator values cross setpoints
  4. Navigate to HistorianMonitor: designer_action('navigate', 'Historian', 'HistorianMonitor') — confirm tag values are being logged

Adapting for Real Protocols

To adapt this starter for a real device instead of Value Simulator:

  1. In Step 3, replace list_protocols('ValueSimulator') with the target protocol (e.g., list_protocols('ModbusTCP'), list_protocols('OPCUA'))
  2. Configure Channel/Node with real connection parameters (IP, port, etc.)
  3. Map Points to real device addresses
  4. Everything else (Tags, Historian, Alarms, Dashboard) remains the same

Common Pitfalls

MistakeWhy It HappensHow to Avoid
Guessing protocol field formatsSkipping list_protocolsAlways call list_protocols before writing device tables
Bare tag names in DevicesPointsForgetting asset pathAlways use full path: Plant/Tank1/Level
Creating unnecessary HistorianTablesNot checking defaultsCheck get_objects('HistorianHistorianTables') first
Omitting PanelType on dashboardSeems optionalAlways set PanelType explicitly
Pre-fetching all schemas at onceOver-eager optimizationFetch each module's schema only when ready to write it
Screenshotting to verify writesUnnecessary self-validationTrust write_objects success. User sees live updates

...