Skip to content

Device Types

A device type is a reusable, versioned definition of a piece of industrial equipment — its tags, alarms, commands, faceplate components, and state machine. A device instance is one of those types commissioned against real hardware at a specific site. The relationship mirrors a Rockwell AOI or an Ignition UDT (the type) and an AOI instance in a running PLC program (the instance).

Defining equipment once and instantiating it many times is what makes Consystence’s model tractable: a fix to a pump faceplate or an alarm threshold lands everywhere the type is deployed, and dependency tracking (which instances use which type version) stays explicit.

Device typeDevice instance
What it isReusable template: tags, alarms, commands, components, state machineA configured device at a site, based on a type
ScopeShared, versioned, portable across sites and orgsPer-site; never reused
IdentityDotted type id, e.g. consystence.pump.centrifugalSite-local asset, e.g. AssetNumber PP-01
DefinesThe shape of the equipmentThe mapping of that shape onto real controller tags
Lives inA library packageA commissioned site’s configuration

A type declares an abstract tag named Speed; an instance binds that tag to a concrete controller address (for example Program:DamTransfer.Pump1.Speed). An instance is live as soon as it is created — through the web console’s Add device form, the CLI or the API, or when a site configuration export is provisioned onto a server — with alarms, P&ID bindings, AI context, and historian attribution built on its tag mappings from that point. Confirming those mappings against the real controller is engineering discipline the platform does not yet enforce: a formal propose-then-commission workflow is planned, not shipped.

Tags should not float in a flat namespace — they have a known physical origin. Consystence’s engineering model is controller → module → channel → tag, with the controller’s Tag Register — its data points — as the authoritative namespace a device type may draw from.

flowchart TD
  C[Controller<br/>ControlLogix / PLCnext] --> M[Module<br/>slot-addressed I/O]
  M --> CH[Channel<br/>single I/O point]
  CH --> TR[(Tag Register<br/>flat tag namespace)]
  TR -. references .-> DT[Device Type<br/>reusable definition]
  DT --> DI[Device Instance<br/>commissioned per site]
  DI --> P[Process<br/>instances at a site]
  • Controller — owns the backplane and scan cycle; the root of all I/O ownership. Consystence uses the term controller (ControlLogix and PLCnext today), not “PLC”.
  • Module — passive, slot-addressed hardware (digital/analogue I/O, comms adapters, safety, power, compute). In the target model, modules are schemas, not state machines.
  • Channel — an individual I/O point that feeds the Tag Register.
  • Tag Register — the authoritative flat namespace of every data point (typed controller tag) the controller exposes, populated by browsing the controller.

Mapping validation: by design, a device type should reference data points that exist in the controller’s Tag Register. The platform does not yet check this — tag mappings are stored as given, and a mistyped path surfaces as a runtime read/write failure rather than an error when the instance is created. Validation of tag mappings against the register is planned.

For how those tags are read from the controller — gRPC to PLCnext GDS/PORT variables, or EtherNet/IP CIP direct to ControlLogix — see PLC communication.

A device type is a YAML manifest plus assets. A library groups related device types under a library.yaml manifest; a library’s page in the web console can also save it as a .cspkg package.

consystence.pump.centrifugal/
├── manifest.yaml # type id, tags, calculations, states, aiContext
├── simulation.yaml # optional simulation profile
├── components/ # faceplate, status card, detail view
├── alarms/ # alarm definitions
└── commands/ # command definitions (tag writes, preconditions, audit)

Each layer has its own page:

  • Type system — the manifest schema, versioning, dependencies, and the type/instance/library/marketplace hierarchy.
  • Tags — the tag schema: dataType (Bool / Int / DInt / Real / String), access (Read / Write / ReadWrite), rangeMin/rangeMax, and the physicalRole (Input / Output / Internal / System) that classifies a tag in the simulator–controller data flow.
  • Alarms & commands — condition-driven alarms and audited, precondition-gated commands.
  • Creating types — authoring a type package from scratch.

Shipped libraries — the Standard Library

Section titled “Shipped libraries — the Standard Library”

The four first-party libraries below make up the Consystence Standard Library — 42 device types today across pumps and industrial equipment, I/O and controllers, materials handling, and wet processing. Each library is versioned. The control behaviour beneath the types comes from a single behavioural master written in C#: the native simulator runs it directly, ControlLogix blocks are checked against test vectors the master produces, and a generated PLCnext runtime program is built from the same source and checked with live tests on a virtual PLCnext only, with no conformance replay yet; per-block vector replay on PLCnext is planned. Not every block has all three executions yet. On controllers, conformance testing and the device and sequence layers are ControlLogix today. The aim is equivalent behaviour, not identical execution. Type ids below are representative, not exhaustive — see each library manifest for the full set.

LibraryFocusExample type ids
consystence.pumps
(Industrial Equipment)
Pumps, VFD motors, process sensors, valves, PID, pump-start and generic sequencesconsystence.pump.centrifugal, consystence.motor.vfd, consystence.sensor.flow, consystence.valve.motorised, consystence.pid.controller
consystence.io
(I/O & Controllers)
Controllers, controller diagnostics, rack-mount I/O modules and the standard sequenceconsystence.controller.logix, consystence.controller.plcnext, consystence.io.di32, consystence.io.do16, consystence.io.remoteio, consystence.sequence
consystence.materials-handlingDry-bulk handling and condition monitoringconsystence.conveyor.belt, consystence.crusher, consystence.chute, consystence.screen.vibrating, consystence.feeder.apron, consystence.weightometer, consystence.sensor.vibration, consystence.positioner, consystence.magnet.tramp-metal
consystence.wet-processingThe wet side of a coal preparation plantconsystence.dmc.cyclone, consystence.dmc.magnetic-separator, consystence.thickener, consystence.stockpile

The library schema supports inter-library dependencies with semver constraints — though the first-party libraries currently declare none. The first-party libraries ship pre-registered in the platform-wide type catalogue, so any organisation can use them without an install step, and instances reference a type at a pinned version. Device types belong to that global catalogue, not to an organisation. Loading your own libraries into it, and customising a type per tenant through overrides against a pinned (typeId, version) rather than through per-organisation copies, are planned; see Marketplace.

Consystence’s AI helps you author device types. Today its tools read what the platform already holds: the site’s registered controllers (name, platform and status) and their browsed data points, device types, live values, trends, alarms and events. It can propose a live tag browse of a controller, which a person with engineering rights confirms on the controller’s page. Commands are propose-only (an operator confirms every execution); the assistant does not register controllers, change tag bindings or deploy controller code, and creating a device instance remains a human action. Richer onboarding — reading module and program structure, then proposing module profiles and device-type signal surfaces, confidence-scored, for an engineer to review device by device — is planned, not yet shipped. The platform also runs a shadow of each type’s state machine — fed by live tag values — so the AI can explain why a device is in a given state (for example, “Pump 1 is Interlocked because its Interlock input is active while it is not running”) rather than inferring it from raw booleans.