{"id":50532891,"url":"https://github.com/moqui/moqui-device","last_synced_at":"2026-06-03T15:01:48.088Z","repository":{"id":362270180,"uuid":"1216267848","full_name":"moqui/moqui-device","owner":"moqui","description":"Foundational component that has the necessary entities, services, and configuration for controlling Industrial systems","archived":false,"fork":false,"pushed_at":"2026-06-03T11:28:26.000Z","size":49,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T12:15:39.899Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moqui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-20T18:30:05.000Z","updated_at":"2026-06-03T11:28:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/moqui/moqui-device","commit_stats":null,"previous_names":["moqui/moqui-device"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/moqui/moqui-device","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moqui%2Fmoqui-device","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moqui%2Fmoqui-device/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moqui%2Fmoqui-device/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moqui%2Fmoqui-device/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moqui","download_url":"https://codeload.github.com/moqui/moqui-device/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moqui%2Fmoqui-device/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33870026,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-03T15:01:46.913Z","updated_at":"2026-06-03T15:01:48.072Z","avatar_url":"https://github.com/moqui.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Moqui Device\n\n[![license](http://img.shields.io/badge/license-CC0%201.0%20Universal-blue.svg)](https://github.com/moqui/moqui-device/blob/master/LICENSE.md)\n\nMoqui Device is a Moqui Framework component that provides a **complete, universal\ndata model for physical devices (PLC, Drive/Inverter, remote IO, IoT devices, etc.)** — the dual of [moqui-math](https://github.com/moqui/moqui-math).\nIt models devices as digital twins, defines how to communicate with them\n(fieldbus protocols, message brokers, REST gateways), and governs their behaviour\nover time through a rule and configuration engine.\n\nA math model cannot run without a device; a device cannot be meaningfully\ndescribed without modelling what it computes. `moqui-device` is the device half\nof that pairing — the single, auditable source of truth for what a device *is*,\nwhat it *runs*, and what it *did*.\n\n## Trajectories and discrete-event systems\n\nA device's behaviour over time falls into one of two forms, and the model covers\nboth. Either it is a **trajectory** — a continuous path through a state space — or\nit is a **discrete-event system (DES)**, a sequence of state transitions fired by\nevents. A robot arm moving through space and a thermodynamic process following a\ntemperature profile are trajectories; a batch advancing through its phases or an\nindustrial bioprocess stepping between operating states is a DES.\n\nThe math/device duality captures the continuous case directly:\n`moqui.math.Trajectory` describes the path, and `TrajectoryAxisBinding` maps its\naxes (position, velocity, acceleration, jerk, snap) onto the concrete parameters\nof the device that executes it — a servo axis or a temperature ramp alike. The\ndiscrete case is captured by the device status flows (below), where state and\ntransition are the modelling primitives. The same component therefore lets you\nmodel, command, log, and audit both how a device *moves* and how it *switches*.\n\n## Contents\n\n| Domain | Entities |\n|---|---|\n| Digital Twin | `Device`, `PhysicalDevice`, `DeviceGroup`, `DeviceGroupMember`, `DeviceContent`, `DeviceStats`, `DeviceLog` |\n| Math Binding | `DeviceMathModel` — binds a `Device` to a `moqui.math.MathModel` for training, inference, simulation, or monitoring |\n| Connectivity | `DeviceConnection` — Modbus TCP, OPC UA, EtherNet/IP, CANopen, PROFINET, BACnet/IP, KNXnet/IP, MTConnect, Logix CIP/EIP |\n| Requests | `DeviceRequest`, `DeviceRequestItem` — Read, Write, ConfigWrite, Subscribe (Event / StateChange / Cyclic), Unsubscribe, ContentTransfer, Browse, Discovery |\n| Configuration | `DeviceConfig`, `DeviceConfigSet`, `DeviceConfigSetMember` — recipe and configuration definitions modelled along ISA-88 / IEC 61512 (batch control and recipe management) lines |\n| Rules | `DeviceRuleSet`, `DeviceRule` — apply, assert, and validate configurations; supports hierarchical rule sets and priority ordering, consistent with the ISA-88 / IEC 61512 separation of recipe logic from equipment control |\n| FSM definition (moqui-framework `BasicEntities.xml`) | `StatusType`, `StatusItem`, `StatusFlow`, `StatusFlowItem`, `StatusFlowTransition` — data-driven definition of the finite state machines that govern device behaviour |\n| Trajectory Binding | `TrajectoryAxisBinding` — maps `moqui.math.Trajectory` axes to device parameters (position, velocity, acceleration, jerk, snap) |\n| Dashboards | `DeviceDashboard` |\n\n### Device status flows, and why automation reduces to FSMs\n\nTwo built-in status flows are provided as seed data:\n\n- **DeviceBasicStatusFlow** — `Disabled → Standstill → Homing / Run / SynchronizedRun → Stopping → ErrorStop`\n- **DeviceAdvancedStatusFlow** — adds `OperationInhibited` and `EmergencyStop`\n\nBoth follow the IEC 61131-3 / PLCopen Motion Control state-machine conventions.\nThese status flows are not only documentation: combined with the device model\nthey are the source from which [moqui-plc](https://github.com/moqui/moqui-plc)\ngenerates the FSM logic that runs on the controller, defined data-driven through\nthe `StatusType`, `StatusItem`, `StatusFlow`, `StatusFlowItem`, and\n`StatusFlowTransition` entities of moqui-framework's `BasicEntities.xml`.\n\nThe architectural reason this works is worth stating, because it is the central\ndesign choice of the whole stack. The reusable components — `Actuator`,\n`ActuatorGroup`, `Axis`, `AxisGroup`, `SignalMgmt` — form a **Hardware\nAbstraction Layer**. Once the messy device-level detail (handshakes, motion\nfunction blocks, signal conditioning) is hidden behind that HAL, the *behaviour*\nof a machine or process can be expressed as a **finite state machine**: a small\nset of states, a set of input and output symbols, and the transition and output\nfunctions between them.\n\nThis is not a loose analogy. An FSM is a precise mathematical object — the\nordered quintuple (input alphabet, output alphabet, set of states, next-state\nfunction, output function) familiar from logic-network and automata theory.\nExpressing automation problems in this form gives them a **solid mathematical\nbasis**: the model is finite, enumerable, and analysable. Bringing this\nhardware-design discipline — the methods of synchronous logic networks — into the\nsoftware layer is what makes the approach valuable beyond convenience. Because the\nstate space and transitions are explicit and finite, the generated code can be\n**tested and validated as a mathematical object**: every state reachable, every\ntransition exercised, every output checked against the specification. The model\nthat defines the FSM is the same model against which its test suite is built.\n\nThe two flows above are the built-in starting points; real machines extend and\ncompose them, and the HAL keeps even complex coordinated systems expressible as\nFSMs over abstracted components rather than as ad hoc procedural code.\n\n### Device type taxonomy\n\n`DeviceData.xml` contains an extensive taxonomy of device types aligned with\nMTConnect, ISO 9787, and ISO 8373: controllers (PLC, PAC, CNC, motion, robot),\ndrives, sensors, actuators, RFID, network devices, IoT gateways, computing\nservers (GPU, HPC, twin servers), and device group types for clusters,\nmanufacturing cells, HVAC, and conveyor systems.\n\n## Math–Device duality\n\n`moqui.device` and `moqui.math` are two complementary faces of one problem. The\nbinding entity `DeviceMathModel` connects them so the *same* governance machinery\n— config history, rule evaluation, audit log, effective dating — serves a PLC\nmoving a servo and a GPU cluster training a transformer, unchanged. The only knob\nthat differs is the device type. This is the part general MLOps tooling lacks:\nthose tools come from the software side and treat the device as a deployment\ndetail; here it is co-primary.\n\n## Services\n\n| Service | Description |\n|---|---|\n| `moqui.device.DeviceServices.run#DeviceRequest` | Dispatches a single `DeviceRequest` to its configured implementation service |\n| `moqui.device.DeviceServices.run#DeviceRequestGroup` | Runs all requests in a named group; designed to be called as a scheduled service |\n| `moqui.device.DeviceServices.run#DeviceRequestInternal` | Interface that driver components (e.g. `moqui-plc4j`) must implement |\n| `moqui.device.DeviceServices.send#DeviceNotification` | Sends a Moqui notification for a device event |\n| `moqui.device.DeviceGatewayServices.run#GatewayDeviceRequest` | Dispatches requests via the `moqui-device-gateway` REST API (MQTT / OPC UA) |\n| `moqui.device.DeviceGatewayServices.transfer#DeviceContent` | Streams a file (G-Code, firmware, recipe) to a device via the gateway SFTP/file endpoint |\n\n## Service layer — Python ecosystem via moqui-jep\n\n`moqui.device` follows the same philosophy as `moqui.math`: it defines entities,\nseed data, and the service interfaces only. Driver implementations that\ncommunicate with physical devices over fieldbus protocols (Modbus, OPC UA,\nEtherNet/IP, CANopen, etc.) are provided by separate components such as\n**moqui-plc4j** (Apache PLC4X, JVM) or Python libraries (python-opcua, pymodbus,\npython-snap7, etc.) embedded via **moqui-jep**. Control algorithms and ML\ninference services likewise run through moqui-jep using NumPy, SciPy, JAX, or\npython-control.\n\n## Related components\n\n- **[moqui-math](https://github.com/moqui/moqui-math)** — the dual math model (models, runs, lineage, trajectories).\n- **[moqui-plc](https://github.com/moqui/moqui-plc)** — generates IEC 61131-3 PLC code from this device model and its status flows.\n- **[moqui-device-gateway](https://github.com/moqui/moqui-device-gateway)** — executes this model at the edge as Apache Camel routes.\n\n## Dependencies\n\n- **moqui-math** `1.0.0`\n\n## Install\n\n    ./gradlew getComponent -Pcomponent=moqui-device\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoqui%2Fmoqui-device","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoqui%2Fmoqui-device","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoqui%2Fmoqui-device/lists"}