Skip to content

Repository files navigation

DeMoL

Hero

DeMoL logo

A textX-based DSL for declarative IoT device modeling with hardware-aware semantic validation and reproducible code generation for Raspberry Pi (Python) and RIOT (C).

CI

The Problem

Research and prototyping workflows for IoT devices share a common set of bottlenecks.

Device code is rewritten per platform with no shared source of truth. The same sensor logic takes different forms on Raspberry Pi, ESP32, and Arduino. Those implementations drift apart over time, and porting a design to a new target means starting from scratch or copying untested fragments from a sibling project. The absence of a single, authoritative device description makes it impossible to verify that two implementations for different platforms are functionally equivalent.

Pin assignments and protocol constraints are checked by hand, or not at all. An I2C address collision, a voltage mismatch between board and peripheral, or a GPIO shared across two outputs is typically caught at hardware bring-up, not during design. The cost of a late-stage fix ranges from a board respin to a damaged component. Manual inspection does not scale beyond a few peripherals.

Models are embedded in code spread across files. A hardware change -- swapping a sensor, rewiring a bus, changing the power source -- means editing multiple source files instead of updating a single declarative specification. There is no single artifact that describes the device as a whole. The wiring logic, protocol configuration, and pin assignments are scattered across initialization routines, header files, and configuration dictionaries.

There is no formal grounding for what constitutes a valid IoT device. The language of device design is informal, ad hoc, and varies across teams and projects. Reproducibility suffers because the design lives only in the implementer's head. Peer review of a device configuration is impossible without a shared, parseable representation that captures both structure and constraints.

DeMoL in One Sentence

DeMoL is a textX-based DSL that captures an IoT device as a single .dev model and compiles it to validated, reproducible code for Raspberry Pi (Python) and RIOT (C).

The .dev model serves as the authoritative specification: it describes the board, its peripherals, the electrical connections, the communication brokers, the sampling policies, the user-defined constraints, and the alert triggers. All generators read this single file and produce platform-specific artifacts from it.

How It Works

DeMoL conceptual model: device model, semantic validator, code generators

DeMoL follows a three-stage pipeline.

  1. Model -- A designer writes a .dev file describing the board, peripherals, connections, communication brokers, sampling policies, constraints, and alerts. The syntax mirrors the hardware structure: boards, sensors, actuators, pins, protocols, and buses are all first-class citizens in the grammar. The file is self-contained and serves as the single source of truth for the device.

  2. Validate -- The semantic engine checks 21 hardware-aware rules: voltage compatibility, pin conflict detection, I2C address uniqueness, protocol frequency constraints, power budget limits, user-defined CONSTRAINT expressions, and ALERT trigger consistency. Validation errors are collected with precise line and column information and rendered with actionable hints. No code is generated for an invalid model. The validation pass is deterministic and reproducible.

  3. Generate -- The validated model feeds platform-specific code generators. The RPi Python generator produces a commlib-based node with sensor initialization, MQTT publishing, and configurable sampling loops. The RIOT C generator produces bare-metal firmware with the same logical structure and the same connectivity pattern. Additional generators produce wiring diagrams (SVG), pin-mapping reports (MD + JSON), JSON model representations, and hardware construction guides.

A Real Model

DEVICE MixedConnectionDevice WITH
    description="Device mixing manual CONNECT and SMARTCONNECT",
    os=raspbian;

USE RaspberryPi_5_8GB;
USE BME680[EnvSensor], HCSR04[DistanceSensor];

BROKER[MQTT] Broker WITH host="localhost", port=1883;

// Manual wiring -- full control over pin assignments
CONNECT EnvSensor WITH
    POWER gnd -- GND_1, vcc -- power_5v_a
    DATA i2c[slave_address=0x76] sda -- GPIO2, scl -- GPIO3
    @ "sensors/env";

A device model is a single text file. The full example adds a SMARTCONNECT DistanceSensor block and lives at examples/rpi/rpi_mixed_connect.dev.

The DSL syntax distinguishes between manual CONNECT blocks for precise wiring control and SMARTCONNECT blocks for automatic pin assignment. The model also supports SAMPLING blocks for data acquisition configuration, CONSTRAINT blocks for user-defined invariants, and ALERT blocks for threshold-based triggers. Every keyword in the language corresponds to a first-class concept in the metamodel.

Show Me the Output

Running demol generate rpi examples/rpi/rpi_mixed_connect.dev --output-dir ./output produces envsensor_node.py (69 lines). The class shell shows the generator's structure: commlib imports, sensor initialization, and MQTT publisher wiring.

from commlib.node import Node
from commlib.utils import get_timestamp_ns, Rate
from commlib.transports.mqtt import ConnectionParameters
from .msg import EnvMessage
from .bme680_envsensor import BME680_EnvSensor


class BME680Node:
    _FREQUENCY = 10.0
    _SAMPLING_MODE = "continuous"

    def __init__(self):
        self.sensor = BME680_EnvSensor()
        self.node = Node(node_name='sensors.env.envsensor',
                         connection_params=ConnectionParameters(
                             host="localhost", port=1883))

The RIOT C generator produces a structurally equivalent firmware in C with the same pin configuration, protocol setup, and topic subscription logic. Both generators derive their output from the same validated .dev model, guaranteeing that the RPi Python prototype and the RIOT C deployment share the same hardware configuration.

The same model produces a wiring diagram and a pinmap report via demol generate svg and demol generate pinmap.

Generated wiring diagram for a multi-peripheral device

A full list of all generator targets, their output formats, and usage examples is in docs/code-generation.md.

Why Researchers Choose DeMoL

DeMoL metamodel: Device, Board, Peripheral, Connection, Constraint

Formal semantics -- A 1,800-line mathematical specification in docs/semantics.md defines the device model, voltage/pin/protocol constraints, and the validation engine using inference rules and proof obligations. The specification covers the abstract syntax, static semantics, type system, and dynamic semantics of every language construct, including SAMPLING blocks, CONSTRAINT expressions, and ALERT triggers. This formal grounding supports verification of model properties and opens a path toward theorem-prover integration and model checking.

Reproducible code generation -- The same .dev model produces byte-identical RPi Python and RIOT C outputs across runs and machines. The generators in demol/transformations/m2t_rpi.py and demol/transformations/m2t_riot.py are deterministic and tested against golden-file snapshots in the test suite at tests/. A model round-trip through validate and generate always produces the same artifact set, which supports CI verification of generated code.

21 semantic validation rules -- The validator suite in demol/lang/semantics/validators/ covers power compatibility, pin conflicts, protocol frequency constraints, I2C address uniqueness, user-defined CONSTRAINT expressions, ALERT trigger correctness, sampling policy consistency, and multi-broker VIA routing. Running demol validate on a model reports every applicable rule and its outcome with precise source locations. The validator architecture is class-based and extensible: new rules inherit from BaseValidator and register themselves automatically.

Open hardware library -- A library of 12 boards (Raspberry Pi, ESP32, ESP8266, Arduino) and 32 sensors / 13 actuators / 2 power sources lives in demol/builtin_models/. Each entry is a validated .hwd component model that the DSL resolves at parse time via the component metamodel. The full catalog is documented in docs/sensors-actuators.md, with interface type, bus protocol, voltage range, and code-generation support status for each component.

Hardware Library

The full hardware library (boards, sensors, actuators, power sources) is in docs/sensors-actuators.md. Each entry is a validated .hwd component model loaded at parse time.

DeMoL vs. Alternatives

Approach Declarative model Semantic validation Multi-target codegen
Raw Python (per platform) no none one platform per codebase
Arduino sketch partial (.ino + comments) manual pin checks one board per sketch
PlatformIO partial (platformio.ini) library-level only C++/Arduino, MicroPython

Other tools (Zephyr / Devicetree, raw textX) cover adjacent niches; this comparison focuses on the most common prototyping path. DeMoL's combination of a formal semantic specification, a declarative model format, and multi-target code generation is distinctive among DSLs for IoT device design.

Quick Start

pip install demol
demol validate examples/rpi/rpi_mixed_connect.dev
demol generate rpi examples/rpi/rpi_mixed_connect.dev --output-dir ./output
demol generate svg examples/rpi/rpi_mixed_connect.dev --output-dir ./output

Generated code and reports land in the directory passed to --output-dir. See docs/code-generation.md for all codegen options including RPi Python, RIOT C, SVG wiring diagrams, pin-mapping reports (MD + JSON), JSON output, and SMAuto automation models.

The CLI also supports demol analyze power for battery runtime estimation, demol fix for auto-correcting common validation errors, and demol diff for semantic comparison of two model files.

Citing DeMoL in Research

A formal citation will be added here once a published artifact is available; in the meantime, please cite the GitHub release at https://github.com/robotics-4-all/demol/releases.

DeMoL's design is grounded in a formal semantic specification covering the device model, voltage/pin/protocol constraints, and the validation engine. The full 1,800-line mathematical specification is in docs/semantics.md, with inference rules and proof obligations for the 21 validation checks. The semantics document uses mathematical notation for voltage domains, pin functions, protocol constraints, power budgets, sampling configurations, and alert trigger conditions.

Documentation & Resources

Document Description
Language Reference Grammar, syntax, hardware components, connections, brokers
Semantic Validation Validation rules, safety checks, error examples
Code Generation & CLI Generators, CLI usage, deployment artifacts, diagrams
Formal Semantics Mathematical specification of the language
Sensors & Actuators Hardware library reference
Testing Test suite structure and coverage

License & Community

DeMoL is released under the MIT License. Copyright (c) 2023 robotics-4-all. Maintainer: Konstantinos Panayiotou (klpanagi@gmail.com). Issues and pull requests are tracked on GitHub.

About

Device Modeling Language - A DSL for modeling IoT devices with automated source code generation for RaspberryPi and RiotOS

Resources

Stars

1 star

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages