Skip to main content
Version: 0.1

Import a WinCC Unified project

This guide walks through platform/tools/wincc-import, a command line tool that reads the folder a WinCC Unified Openness export produces and rebuilds the HMI on a gateway: an OPC UA connection, tags, alarms, screens, and the devices as tag type (UDT) instances. It is for the engineer migrating an existing Siemens panel. The tool was written against one export (HMI_Scadex_2026-11-01, HMI HMI_RT_NIRO, PLC S7_VN_NIRO), and that project is the one it has been run on.

Prerequisites​

  • The platform repository checked out, with its dependencies installed (node_modules/.bin/tsx is used to run the tool).
  • The export folder from TIA Portal Openness.
  • An API key with the engineer role (--api-key scx_...), or an account's --email and --password. See API keys.
  • The OPC UA driver module running on the gateway, and the PLC's OPC UA server switched on (OPC UA_1 in TIA) with the variables marked "accessible from HMI/OPC UA".
  • For convert and type-alarms: the project's tag types (CswMotor, CswMotorFreq, CswValve, CswValveAnalog, CswDigitalInput, CswAnalogInput, CswPID, CswTotalizer, CswGeneralMode, CswMode, CswAlarm) present on the gateway. They are found by name, wherever they are filed. Without them the devices stay plain tags.
node_modules/.bin/tsx tools/wincc-import/cli.ts <command> <export-folder> [options]

Commands​

CommandWhat it does
planReads the export and writes what it would create to --out. Touches no gateway.
applyCreates the OPC UA connection S7_VN_NIRO, its tags and their alarms. Running it again keeps what exists. On a gateway that has the project's tag types it then runs convert too (--keep-old keeps that from deleting anything).
rebindPoints the existing OPC UA tags at the nodes the plan now names; use it after changing --namespace. Devices that are instances take their nodes from their types (and the ID and OPCUA parameters), so rebind does not reach them: change the namespace in the type.
verifyReads every OPC UA tag once and lists those whose quality is not Good. Run it once the PLC is online.
convertReplaces the motors' and valves' imported tags with instances of the tag types, alarms carried over. Needs --url.
type-alarmsPuts the export's alarm texts onto the types and sets what each instance changes. Works from the export, not from the gateway, so alarm edits made in Scadex since convert are replaced.
viewsBuilds the screens, faceplates and popups as Scadex views (screens), and makes the pages start screens. Without --url it only reports what it would build. Views that already have content are kept; --force replaces them.

Options:

OptionCommandsMeaning
--url <gateway>all but planThe gateway
--api-key scx_... or --email, --passwordall but planWho the tool acts as (engineer role)
--out <file>planWhere the plan goes
--endpoint opc.tcp://10.1.2.47:4840applyThe PLC's OPC UA endpoint
--namespace 3apply, rebindThe namespace index of the data blocks; 3 is the default
--enableapplySwitch the connection on at once; otherwise it is created off
--flatapplyNo tag types: every variable stays a tag
--keep-oldapply, convertMake the instances, remove nothing
--dry-runtype-alarmsReport without changing
--family motor,pid,...type-alarmsOnly the named families
--force, --only "Overzicht,Droge zone"viewsReplace existing views; limit to the named screens

The command line is strict: an unknown option (--dryrun), a missing value, or an option given to a command it does nothing for (--dry-run belongs to type-alarms, and convert has none) is an error and nothing runs.

Order of operations​

1. Plan​

node_modules/.bin/tsx tools/wincc-import/cli.ts plan ../HMI_Scadex_2026-11-01 --out plan.json

Read the plan: the connection, the tag tree, the alarms, which blocks become which type. Nothing has touched the gateway yet.

2. Apply​

node_modules/.bin/tsx tools/wincc-import/cli.ts apply ../HMI_Scadex_2026-11-01 \
--url https://app.scadex.io --api-key scx_... --endpoint opc.tcp://10.1.2.47:4840 --namespace 3

What it makes:

  • Connection. S7_VN_NIRO, an OPC UA connection to the PLC's own server, created switched off unless --enable is given. Security is none to start with; change it on the connection afterwards.
  • Tags. One tag per PLC variable the HMI used, under a folder named for the PLC that mirrors the data blocks: HMI tag S7_VN_NIRO_P02_HP_Pomp_DB_fb_Csw becomes S7_VN_NIRO.P02_HP_Pomp_DB.fb.Csw with node id ns=3;s="P02_HP_Pomp_DB"."fb"."Csw". A structured tag (UDT_Confirm, UDT_Device_Conditions, UDT_LogEntry) is opened into one tag per member. An array element is a path segment of its own (Piping.ZoneNat[3] is Piping.ZoneNat.3). The HMI's own variables (NavMain, NavSub, ...) become memory tags under HMI, session-scoped where they say which page one person is on. The Device_Info_* tags are left out.
  • Alarms. Each of WinCC's 643 discrete alarms watches one bit of a status word, so each becomes a bitSet alarm on that word with the bit number as the setpoint. Priorities 1 to 4 become severities 200, 500, 700 and 900. The alarm text is the alarm's name.
  • Devices. On a gateway that has the types, apply runs convert as well (see step 4). With --flat, nothing becomes an instance.

Switch the connection on in Connections, OPC UA servers when the PLC is reachable.

3. Verify, and rebind if the namespace differs​

node_modules/.bin/tsx tools/wincc-import/cli.ts verify ../HMI_Scadex_2026-11-01 --url https://app.scadex.io --api-key scx_...

The namespace index is the one thing the export cannot tell. If verify reports everything as having no value while the connection shows connected, browse the connection in the dashboard to see the real index, then:

node_modules/.bin/tsx tools/wincc-import/cli.ts rebind ../HMI_Scadex_2026-11-01 --url https://app.scadex.io --api-key scx_... --namespace 4

Instances are not touched by rebind: their node ids come from the type, so change the namespace there.

4. Convert devices to type instances​

node_modules/.bin/tsx tools/wincc-import/cli.ts convert ../HMI_Scadex_2026-11-01 --url https://app.scadex.io --api-key scx_...

How a block is classified: a data block is a motor when a motor faceplate (MotorV20) is bound to its status word, a valve when a valve faceplate (ValveV20) is, a digital input when a digital-input or detection faceplate is (or a screen script only opens the digital popup for it), an analog input with AnalogInpV20, a PID with a PID faceplate, a totalizer with FCP_Totalizer, and so on. A motor with a speed set point and feedback is a CswMotorFreq, a valve with a position pair a CswValveAnalog. The instance is named after the block without _DB (C01_Exhaust_Fan_DB becomes C01_Exhaust_Fan), at the top level, because the types build their node ids from the instance name, so every value is read from the node it was read from before.

convert makes each instance, gives its Csw the alarms the old status word has, and only then deletes the old tags, a block at a time and only if the instance's word reads Good whenever the old one did. If the gateway cannot say whether the old word reads, the old tags stay and the block is reported. It is safe to run again: it leaves alone what has been changed on an instance since (a unit, the alarms). --keep-old stops short of deleting.

warning

convert has no dry run. Run plan first, make sure the types are the ones you mean, and consider --keep-old on the first pass.

Not carried over: history recorded against the old tags, and the alarm journal's links to them. Anything outside the tool that names an old path (a script, a view built before) has to be pointed at the instance.

5. Put the alarm texts on the types​

node_modules/.bin/tsx tools/wincc-import/cli.ts type-alarms ../HMI_Scadex_2026-11-01 --url https://app.scadex.io --api-key scx_... --dry-run
node_modules/.bin/tsx tools/wincc-import/cli.ts type-alarms ../HMI_Scadex_2026-11-01 --url https://app.scadex.io --api-key scx_... --family motor,valve

The type's Csw member gets the alarms with {Description}: ... names, each instance's description becomes the device name that stood in front, and each instance gets only the fields that differ from the type (alarmOverrides), or a list of its own where the type cannot express them. See Model a motor as a tag type for how such templates resolve.

warning

type-alarms rewrites from the export, not from what the gateway holds, so alarm edits made in Scadex since convert are replaced. Use --dry-run first, and --family for the families whose types you have not edited.

6. Build the screens​

node_modules/.bin/tsx tools/wincc-import/cli.ts views ../HMI_Scadex_2026-11-01 --url https://app.scadex.io --api-key scx_...

The 76 WinCC screens become 12 pages and 77 parts in the folders NIRO and WinCC: the pages (Overzicht, Stappen, six Parameters pages, Natte zone, Droge zone, Hardware, Alarmen) in the Kader frame with a navigation bar, parts under WinCC/Onderdelen, and faceplates and popups under WinCC/Faceplates, redesigned because WinCC could not export their geometry. Tag reads become tag('path'), named colors their values, each I/O field a field widget, and mm:ss times a field with the duration format. The pages become start screens (Start screens).

Left out on purpose: the empty Algemeen page, the Test page, the logo, the system diagnosis control, the alarm counters per class on the navigation buttons, and the @UserName label.

Existing views with content are kept; views --force rebuilds them and --only "Overzicht,Droge zone" limits that to the named ones.

Where to go next​