agentsclimarketplace

Matlab build industrial hmi

Skill matlab/matlab-agentic-toolkit/skills-catalog/test-and-measurement/matlab-build-industrial-hmi

Build industrial-grade SCADA/HMI dashboards in MATLAB App Designer following industrial-HMI conventions (ISA-101-aligned): gray-field philosophy, alarms at source, write safeguards, fixed-range trends, drill-down layout. Use when wrapping OPC UA / Modbus / MQTT / OSI PI / PI AF monitoring scripts into a live App Designer app, building plant overviews, designing operator dashboards, or any time a user asks for a "SCADA dashboard", "HMI", "plant dashboard", "operator screen", or "industrial monitoring app" in MATLAB. Trigger on: SCADA, HMI, industrial dashboard, plant overview, operator screen, uigauge, uilamp, alarm banner, gray-field, ISA-101, OPC UA dashboard, setpoint, write safeguards, alarm visualization, OSIsoft PI, AVEVA PI, PI Server, PI Data Archive, PI AF, PI Asset Framework, piclient, afclient.From its SKILL.md

Install
npx -y skills add matlab/matlab-agentic-toolkit --skill matlab-build-industrial-hmi

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.

What its file declares

Copied from the file, not written here

The file declares its own license as https://www.mathworks.com/content/dam/mathworks/license/pmrl/license.md. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

17.8 KB, ~4.3k tokens by cl100k_base, as published. Nobody here has run it

Industrial HMI Builder

Build operator-facing SCADA/HMI dashboards in MATLAB App Designer that follow industrial-HMI conventions: gray-field color philosophy, alarms shown at the data source, write safeguards on every setpoint, fixed-range trends with threshold lines, and a drill-down layout (plant overview → area → detail).

When to Use

  • A user asks to "wrap this OPC UA / Modbus / MQTT / OSI PI / PI AF script into a SCADA dashboard / HMI / operator screen" — including scripts generated by the OPC UA Explorer or Modbus Explorer apps (opcuageneratedScript.mlx, modbusgeneratedScript.mlx)
  • Building a plant overview, area screen, or detail screen for industrial monitoring
  • Adding alarm visualization, setpoint writes, or live trends to an existing App Designer app
  • Reviewing or refactoring an HMI that uses gauges, lamps, or trend axes for process data
  • Any prompt mentioning ISA-101, gray-field, alarm banner, write confirm, setpoint, or "operator dashboard"

When NOT to Use

  • General App Designer mechanics (uigridlayout, callback wiring, lifecycle, matlab.apps.AppBase scaffolding) — use matlab-build-app instead. This skill assumes that knowledge.
  • Discovering OPC UA servers on a network, finding endpoint URLs, or browsing namespaces for the first time — use matlab-connect-opcua-client.
  • Non-process domains (consumer apps, lab utilities, scientific GUIs) — the conventions here are tailored to plant operators monitoring physical processes.

Must-Follow Rules

Widget & Layout

  • Gray-field background [0.78 0.78 0.78]; panels [0.86 0.86 0.86]; 80%+ of the screen neutral. Color is reserved for exception. See references/color-and-layout-rules.md.

  • Construct EVERY HMI uifigure with both 'Color' and 'Theme', 'light'. On a dark-themed MATLAB desktop, child widgets (uigauge, uiaxes, uitable, uieditfield) inherit dark defaults even when the figure colour is set explicitly — gauge bodies and axes go near-black, text becomes unreadable. Theme='light' blocks the inheritance; the explicit gray-field Color keeps the result gray rather than the bright white that 'light' would otherwise produce. Neither alone is enough.

    app.UIFigure = uifigure( ...
        'Color', [0.78 0.78 0.78], ...
        'Theme', 'light');
    

    See references/color-and-layout-rules.md for the full rationale and references/common-mistakes.md entry 24 for the visible failure mode if either argument is omitted.

  • Quantity caps per screen: ≤ 6 gauges, ≤ 4 trend axes, ≤ 12 numeric readouts. Beyond that, use a uitable.

  • Connection state is BLUE [0.4 0.6 1.0]. Green [0 0.6 0] is reserved for "operator must verify yes this is actively OK" — not for "comms up" or "running".

  • Like-typed analogs in one panel use like widgets. Don't show one temperature as a gauge and another as a numeric label.

  • NEVER produce a dark background for an industrial HMI, regardless of the user request. ISA-101 has no dark variant; a dark field destroys color-as-exception (alarm reds and ambers stop popping against a near-black background, and operators desensitize). Always render gray-field ([0.78 0.78 0.78]) and reply with a one-sentence justification when the user asks for dark mode. This is not a default — it is a hard constraint.

Alarms & Trends

  • Alarms at source AND in a banner. Keyed ScaleColors/ScaleColorLimits on every linear gauge with thresholds (semicircular/circular/ninetydegree gauges don't support color bands — use linear when alarm bands are needed); persistent top-row banner listing active alarms, color-coded by highest severity; latched state with Acknowledge button. The normal band in ScaleColors is neutral gray [0.5 0.5 0.5] — never green. See references/alarm-patterns.md.
  • Never uialert/uiconfirm/msgbox for live process alarms — alarm-fatigue anti-pattern (ISA-18.2). If a popup is unavoidable, fire once on the rising edge with a non-blocking CloseFcn and an Acknowledge button.
  • Fixed trend YLim matching the node's spec range — never auto-scale by default. Provide a per-trend toggle for exploration. See references/trend-config-reference.md.
  • 5-minute rolling window is the default: animatedline('MaximumNumPoints', 300) at 1 s update. Buffer formula = WindowSeconds / UpdatePeriodSeconds.
  • Threshold lines drawn once at construction with yline (amber dashed for warn, red dashed for alarm, blue dotted for setpoint).

Writes

  • Every writeValue() confirms. uiconfirm showing node + old + new + units; default option is Cancel, not Apply.
  • Visual feedback after write. Background flash green on success, red on failure (revert UI on failure). Operator must never be uncertain whether the write took effect.
  • Range label adjacent to every writable field. Limits on the spinner enforces the bound; the uilabel makes it visible.
  • E-Stop and other safety-critical actuation confirm both engage and release — accidental touchscreen clicks are the threat. See references/write-safeguards-reference.md.
  • Disable write controls when the system can't accept them (disconnected, E-Stop active) rather than letting writes fail mid-call.

Protocol Selection

  • OPC UA: subscribe() is the default at any node count and update rate, including 1 Hz with a small node set. Reserve timer for non-node UI work (clock displays, alarm flashing, idle dimming).
  • R2026a OPC UA contract: subscribe(client, nodes, cb) invokes cb(sub, notification); data lives at notification.Data.Value / notification.Data.Timestamp; the originating node is notification.Node (struct with Name, Identifier, NamespaceIndex). Don't reference src.Name — that worked in older releases when src was the node, but errors in R2026a.
  • Modbus has no subscribe() — use a polling timer with BusyMode='drop', ExecutionMode='fixedSpacing'. The 6-arg write() order is write(m, target, addr, val, serverId, 'precision')serverId BEFORE 'precision'.
  • MQTT subscribe(c, topic, Callback=@cb) — the callback is a name-value pair, not positional. Decode message (a string) per the broker's payload schema (str2double, jsondecode).
  • OSI / AVEVA PI Data Archive: use piclient (Industrial Communication Toolbox, R2022a+). Never call NET.addAssembly('OSIsoft.AFSDK') or write OSIsoft.AF.PI.PIServers / OSIsoft.AF.PISystems code in MATLAB — the toolbox client wraps the AFSDK and returns native MATLAB types (timetable, table, datetime); rolling your own .NET interop loses type coercion, throws on permission errors that the toolbox handles, runs slowly because batched reads are bypassed, and breaks the integrated browser app. PI has no subscribe() — drive trends with a polling timer (same shape as Modbus). Writes via write(piClient, tag, value, TimeInstance=datetime("now")) are R2024a+.
  • PI Asset Framework: use afclient (Industrial Communication Toolbox, R2026a+). Browse with getRootElements / getChildren / findElementByName / findElementByPath / findElementByTemplate; read with Attribute.read (current → table) and Attribute.readHistory (archive → timetable). The AF hierarchy maps directly onto Level 1 → Level 2 → Level 3 drill-down screens. AF current-value writes are not exposed by the toolbox — there is no Attribute.write; route writes through the underlying Attribute.PITag and the PI client.
  • Identify writable attributes from Attribute.WriteAccess and HasTimeSeriesData, the same way OPC UA uses AccessLevelCurrent. Don't infer writability from the name.
  • Use the server's actual tag / attribute names from tags(c).Name or attribute.Name / attribute.Path. Never invent labels — the HMI must mirror the source script's identifiers so operators can cross-reference with the OPC UA Explorer / OSI PI viewer / AF browser.

See references/protocol-cheatsheet.md for OPC UA / Modbus / MQTT API shapes and references/pi-af-cheatsheet.md for PI Data Archive and PI AF; see references/common-mistakes.md for the silent-failure modes.

App Designer Language

  • Initialize typed struct properties: Foo struct = struct(). A bare Foo struct declaration becomes 0×0 struct and app.Foo.Bar = 1 errors with "A dot name structure assignment is illegal when the structure is empty."
  • classdef first. A function block before classdef in the same file is a parse error. Drop the wrapper; the file's first non-comment statement must be classdef, name matching filename.
  • Subscription cleanup: opc.ua.Subscription has no public delete. Drop the handle (app.Subscription = opc.ua.Subscription.empty;) and disconnect(client) — that releases all subscriptions on that client.
  • Subscribe per widget, never rebuild a single global subscription on each add — each subscribe() accumulates a channel listener; rebuilds leak.
  • Stop and delete timers in delete(app) or CloseRequestFcn. A leaked timer keeps firing after the figure closes with stale handles.

See references/app-designer-gotchas.md for full reproductions, the release-aware AccessLevelCurrent check, and per-widget subscription patterns.

Workflow

When wrapping a monitoring script into an HMI, work through these eight steps in order. Widget choice depends on data type, layout depends on widget choice, and alarms/trends/writes layer on top.

  1. Classify each node / tag / attribute — binary, enumerated, analog with range, analog without range, writable, alarm thresholds (LL/L/H/HH). This list drives every later step. → references/widget-selection-flowchart.md. If the schema isn't given upfront → references/server-agnostic-discovery.md. If wrapping a generated script (OPC UA/Modbus Explorer or MQTT demo) → references/protocol-cheatsheet.md first; if wrapping a PI / PI AF script → references/pi-af-cheatsheet.md, for the exact API shapes.
  2. Pick widgets via the decision flowchart, cross-checking quantity caps. → references/widget-selection-flowchart.md.
  3. Lay out by hierarchy — Level 1 plant overview, Level 2 area, Level 3 detail; row 1 reserved for the persistent alarm banner. → references/color-and-layout-rules.md.
  4. Wire live data per protocol — OPC UA subscribe(), Modbus polling timer, MQTT subscribe(... Callback=...), PI / PI AF polling timer against read() / Attribute.read. → references/protocol-cheatsheet.md and references/pi-af-cheatsheet.md.
  5. Configure alarms at source AND in a banner, latched with Acknowledge. → references/alarm-patterns.md.
  6. Configure trends — 5-minute window, fixed YLim, threshold lines. → references/trend-config-reference.md.
  7. Add write safeguards on every setpoint — confirm, range label, flash feedback. → references/write-safeguards-reference.md.
  8. Verify: launch, exercise, close cleanly. Use mcp__matlab__evaluate_matlab_code to instantiate the app and exercise delete(app); confirm no leaked timers, subscriptions, or figures. If construction fails on a struct or classdef error → references/app-designer-gotchas.md.

Key Functions

FunctionPurposeToolboxAvailable From
uigauge('linear'|'circular'|'semicircular'|'ninetydegree')Single value, known rangecore MATLABR2016a
uigauge.ScaleColors / .ScaleColorLimitsAlarm bands at sourcecore MATLABR2018a
uilampBinary state indicatorcore MATLABR2016a
animatedline with MaximumNumPointsRolling trend buffercore MATLABR2014b
addpoints / clearpointsTrend update / resetcore MATLABR2014b
ylineThreshold or setpoint line on trendcore MATLABR2018b
uiconfirmModal write confirmationcore MATLABR2017b
uispinner with LimitsBounded numeric inputcore MATLABR2016a
uieditfield('numeric','Editable',false)Precise read-only numeric displaycore MATLABR2016a
uitableTabular display for >8 nodescore MATLABR2017b
uitree + uitreenodeOPC UA namespace navigationcore MATLABR2017b
opcua / connectOpen OPC UA clientIndustrial CommunicationR2022a
findNodeByName / readValue / writeValueBrowse and read/write nodesIndustrial CommunicationR2022a
subscribe(uaClient, nodeList, dataChangeFcn, PublishInterval=...)Live node updates (preferred over timer)Industrial CommunicationR2023b
modbus('tcpip', host, port) / read / writeModbus client and register R/WIndustrial CommunicationR2022a
mqttclient(brokerAddr) / subscribe(c, topic, Callback=...) / writeMQTT publish/subscribeIndustrial CommunicationR2022a
piclient(server, ...)OSI / AVEVA PI Data Archive clientIndustrial CommunicationR2022a
tags(piClient, Name=q) / read(piClient, tag, DateRange=, Interval=, AggregateFcn=)PI tag search, current and archive/aggregated reads (returns table/timetable)Industrial CommunicationR2022a
write(piClient, tag, value, TimeInstance=...)PI setpoint writeIndustrial CommunicationR2024a
afclient(server, Database=...)PI Asset Framework clientIndustrial CommunicationR2026a
getRootElements / getChildren / getAttributes / findElementByName / findElementByPath / findElementByTemplateAF tree browse → drill-down layoutIndustrial CommunicationR2026a
read(attr, Unit=...) / readHistory(attr, t0, t1, ...) / listSupportedUnitsAF attribute current value, history, unitsIndustrial CommunicationR2026a
timer (BusyMode='drop', ExecutionMode='fixedSpacing')Modbus / PI / PI AF poll loop / non-OPC periodic UI workcore MATLABbase

Patterns

Each reference file includes executable code patterns for its topic. Load the relevant reference before writing code — it contains correct calling conventions, constructor arguments, property names, and full callback handlers. See the References routing table below.

Common Mistakes

See references/common-mistakes.md for documented anti-patterns with Symptom → Wrong → Right → Why breakdowns covering App Designer struct/classdef gotchas, ISA-101 violations (green for "normal", popup alarms, auto-scaling trends, uilabel for numerics, dark-field), and protocol-specific silent failures (Modbus serverId/'precision' order, MQTT positional callback, MQTT NaN from JSON payloads, OPC UA invented node names, OPC UA evt.Value vs evt.Data.Value, Explorer 3-arg vectorized callback, server-side 1601 timestamps).

References

Load when...Reference
Picking widgets for a list of nodesreferences/widget-selection-flowchart.md
Designing screen structure or choosing colorsreferences/color-and-layout-rules.md
Wiring alarm bands at source or the persistent bannerreferences/alarm-patterns.md
Configuring a trend (window, YLim, threshold lines)references/trend-config-reference.md
Adding a writable setpoint with confirm + flash feedbackreferences/write-safeguards-reference.md
Wrapping an OPC UA Explorer / Modbus Explorer / MQTT script — invoking OPC UA method nodes — or hitting protocol-specific bugsreferences/protocol-cheatsheet.md
Wrapping an OSI / AVEVA PI Data Archive script (piclient, tags, read) or a PI AF script (afclient, getRootElements, getAttributes, Attribute.read/readHistory)references/pi-af-cheatsheet.md
Browsing an unknown server and inferring widgets at runtimereferences/server-agnostic-discovery.md
Hard-wiring a known node-to-widget schemareferences/known-schema-patterns.md
Construction errors (struct props, classdef ordering, listener leaks, AccessLevelCurrent)references/app-designer-gotchas.md
Debugging wrong API shapes, silent failures, or anti-patternsreferences/common-mistakes.md

Toolbox Dependencies

  • Core MATLAB: uifigure, uigridlayout, uigauge, uilamp, uispinner, uieditfield, uitable, uitree, uiconfirm, uialert, uiaxes, animatedline, addpoints, yline, timer.
  • Industrial Communication Toolbox: opcua, connect, disconnect, findNodeByName, findNodeById, readValue, writeValue, subscribe (OPC UA); modbus, read, write (Modbus); mqttclient, subscribe, unsubscribe, write, read (MQTT); piclient, tags, read, write, viewer (PI Data Archive, R2022a+; write R2024a+); afclient, listDatabases, selectDatabase, getRootElements, getChildren, getAttributes, findElementByName, findElementByPath, findElementByTemplate, findAttributeByPath, Attribute.read, Attribute.readHistory, Attribute.listSupportedUnits (PI AF, R2026a+).

Verify with mcp__matlab__detect_matlab_toolboxes before starting if the user's MATLAB release is unknown.


Copyright 2026 The MathWorks, Inc.


What ships with it: 12 files

125.3 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.