Hands-on exercises for navigating Designer interface and using productivity features.
[getting-started, new-solution, tags, simulator, display, beginner, quickstart]
Step-by-step guide for the first 5 minutes after creating a new FrameworX solution: create tags, simulate data, build a basic display, and run
Build a working solution from scratch in minutes: tags → simulated data → display → runtime. This is the foundation every other skill builds on.
Use this skill when:
Do NOT use this skill when:
create_solution or open_solution completed)Tools: get_table_schema, write_objects, list_protocols, list_elements Tables: UnsTags, DevicesChannels, DevicesNodes, DevicesPoints, DisplaysList
Tags are the foundation — all modules connect through them. Start with a small set that represents a realistic process.
get_table_schema('UnsTags')
Create tags organized by area using slash-separated folder paths:
{
"table_type": "UnsTags",
"data": [
{ "Name": "Plant/Reactor1/Temperature", "DataType": "Double", "Description": "Reactor temperature in °C" },
{ "Name": "Plant/Reactor1/Pressure", "DataType": "Double", "Description": "Reactor pressure in bar" },
{ "Name": "Plant/Reactor1/Level", "DataType": "Double", "Description": "Reactor level in %" },
{ "Name": "Plant/Reactor1/FlowRate", "DataType": "Double", "Description": "Inlet flow rate in L/min" },
{ "Name": "Plant/Reactor1/Status", "DataType": "Integer", "Description": "0=Off, 1=Running, 2=Alarm" }
]
}
Key decisions:
Double for analog measurements, Integer for states/enumsPlant/Reactor1/) create a browsable asset treeDescription — it appears in Designer tooltips and AI contextThe Value Simulator generates realistic changing values for testing — no real hardware needed.
First, get the protocol schema:
list_protocols('ValueSimulator')
Then create the device pipeline (Channel → Node → Points):
{
"tables": [
{
"table_type": "DevicesChannels",
"data": [
{ "Name": "Simulator", "Protocol": "ValueSimulator" }
]
},
{
"table_type": "DevicesNodes",
"data": [
{ "Name": "Simulator.SimNode1" }
]
},
{
"table_type": "DevicesPoints",
"data": [
{ "Name": "Simulator.SimNode1.Temperature", "TagName": "Plant/Reactor1/Temperature", "Address": "ramp(20,95,0.5)" },
{ "Name": "Simulator.SimNode1.Pressure", "TagName": "Plant/Reactor1/Pressure", "Address": "sin(1,5,0.1)" },
{ "Name": "Simulator.SimNode1.Level", "TagName": "Plant/Reactor1/Level", "Address": "random(0,100)" },
{ "Name": "Simulator.SimNode1.FlowRate", "TagName": "Plant/Reactor1/FlowRate", "Address": "sin(10,50,0.05)" },
{ "Name": "Simulator.SimNode1.Status", "TagName": "Plant/Reactor1/Status", "Address": "random(0,2)" }
]
}
]
}
Value Simulator address patterns:
random(min,max) — random value in rangesin(center,amplitude,frequency) — sine waveramp(min,max,step) — ramp up then resetImportant: Always call list_protocols('ValueSimulator') first to get the exact address syntax for the current version. The examples above are common patterns but the protocol schema is the source of truth.
Create a simple dashboard to visualize the live data.
list_elements('Dashboard')
get_table_schema('DisplaysList')
Create a dashboard with text displays for each tag:
{
"table_type": "DisplaysList",
"data": [
{
"Name": "MainPage",
"PanelType": "Dashboard",
"Columns": 2,
"Rows": 3,
"Title": "Reactor 1 Monitor",
"Elements": [
{
"Type": "TextBlock",
"Column": 0, "Row": 0,
"LinkedValue": "Tag.Plant/Reactor1/Temperature",
"Label": "Temperature (°C)"
},
{
"Type": "TextBlock",
"Column": 1, "Row": 0,
"LinkedValue": "Tag.Plant/Reactor1/Pressure",
"Label": "Pressure (bar)"
},
{
"Type": "TextBlock",
"Column": 0, "Row": 1,
"LinkedValue": "Tag.Plant/Reactor1/Level",
"Label": "Level (%)"
},
{
"Type": "TextBlock",
"Column": 1, "Row": 1,
"LinkedValue": "Tag.Plant/Reactor1/FlowRate",
"Label": "Flow Rate (L/min)"
},
{
"Type": "TrendChart",
"Column": 0, "Row": 2, "ColumnSpan": 2,
"Pens": [
{ "TagName": "Tag.Plant/Reactor1/Temperature", "Color": "#FF3498DB" },
{ "TagName": "Tag.Plant/Reactor1/Pressure", "Color": "#FFE74C3C" }
]
}
]
}
]
}
Key decisions:
PanelType: "Dashboard" — required, do not omit (defaults to Canvas otherwise)MainPage is the default startup displayLinkedValue with full runtime path: Tag.Plant/Reactor1/Temperaturedesigner_action('start_runtime')
Wait a few seconds, then verify:
get_runtime_state()
You should see tag values changing as the simulator feeds data.
get_objects('UnsTags') — confirm 5 tags existget_objects('DevicesChannels') — confirm Simulator channel existsget_objects('DevicesPoints') — confirm 5 points mapped to tagsget_runtime_state() — runtime should be running, tags should have changing valuesPanelType: Omitting PanelType on a display defaults to Canvas, which uses absolute positioning (Left/Top) instead of grid layout. Always set PanelType: "Dashboard" for grid-based layouts.Tag.Plant/Reactor1/Temperature (with Tag. prefix) in display bindings. The tag Name is Plant/Reactor1/Temperature but the runtime namespace path needs the Tag. prefix.list_protocols('ValueSimulator') for current syntax. Don't guess address formats from memory.TagName to map to a UNS tag. Points without TagName don't feed data anywhere.From here, the user can add:
skill-alarm-pipelineskill-historian-configurationskill-edge-ml-pipeline