# BusDiagram — authoring reference for language models BusDiagram draws instructional diagrams of KNX installations from a JSON document called a scenario, and can simulate the telegrams exchanged when the reader operates the diagram. This file explains how to write a valid scenario (format 2) from a textual description. The catalogs below are generated from the library and list every accepted behavior, port, equipment type, and data point type. Related files, relative to this one: `schema/scenario-v2.schema.json` (JSON Schema), `scenarios/*.json` (complete examples), `designer/index.html` (editor with validation), `player.html` (viewer). ## Output contract - Produce a single JSON object. Do not add comments or trailing commas. - Required at the root: `"formatVersion": 2`, `lines`, and `devices`. Recommended: `title`, `description`, and `groupAddresses` (names and DPTs shown in the monitor). - Lines: `{ "address": "1.1" }` with area and line numbers 1–15. The layout is derived from addresses; never provide coordinates. - Individual addresses: `area.line.device` with device 1–255 on a declared line. `A.L.0` is reserved for the line coupler. Each address is used once. - Group addresses: three levels, `main/middle/sub` with main 0–31, middle 0–7, sub 0–255. `0/0/0` is refused. - Identifiers (`id`) use letters, digits, `_`, `.`, and `-`, and are unique within their list. - Each device has `id`, `kind`, `behavior`, and `objects`. `kind` is a free classification used for display (for example `pushButton`, `switchActuator`, `supervisor`); `behavior` must be one of the identifiers listed below. - Each object has `id`, `ga`, `port`, and `flags`, usually `dpt` and `name`. `ga` is a string or an array; the first address is the sending address, the others are receive-only; `[]` leaves the object unassociated. `port` must belong to the device behavior, and `dpt` must be accepted by that port. - Flags: `W` (a received write updates the object), `T` (the object may transmit), optional `R` (answers a read on any of its addresses, on its sending address) and `U` (a response updates it). Inputs of an actuator use `W: true, T: false`; commands and status feedback use `W: false, T: true`. - Objects linked to the same group address must have the same payload size (all one-bit, all one-byte, and so on). - Buttons (`buttons`) belong to devices whose behavior accepts inputs. An action is `{ "object": "", "value": }` under `press`, or under `short`, `long`, and `release` for a two-function key. `led` names an object whose value lights the key indicator. - Numeric inputs (`inputs`) are `{ "id", "type": "number", "label", "object", "min", "max", "step" }`; the entered value is written to the object and transmitted. - Channels (`channels`) are actuator outputs: `{ id, label, parameters?, initialState?, equipment? }`. `equipment` connects a load such as a lamp or a shutter. Objects of an output port name their `channel`. - Topology beyond one line: `topology.mainLines`, `topology.backbone`, `topology.ip` (`"areaCouplers"` or `"lineCouplers"`), and `topology.couplers` for per-coupler `"filter"`, `"route"`, or `"block"` settings. Devices with `"medium": "IP"` connect to the IP network. - Simulated clock: `"clock": { "start": "2026-09-28T21:57:00", "speed": 60 }` at the root enables `clockMaster/v1`, `timeSwitch/v1`, and time windows of `logicGate/v1`; `speed` is clock seconds per simulated second. - Heated rooms: `"rooms": [{ "id": "living", "name": "Living room", "temperatureC": 19, "outsideTemperatureC": 5 }]` at the root (optional `windowOpen`, `timeConstantMs`). A `roomThermostat/v1`, `windowContact/v1`, or `temperatureSensor/v1` device sets `"room": "living"`; a radiator load uses `"equipment": { "type": "radiator", "room": "living" }`. - Line extension: `lines[].extension = { "address": "A.L.64", "mode": "repeater" }` (or `"segmentCoupler"`) adds a second segment connected to the main segment, one per line; devices on that segment set `"downstream": true`. - Use only behaviors, ports, DPTs, parameters, and equipment types from this file. When the description needs a device that is not listed, use `passive/v1` and state the limitation in `description`. ## Recommended workflow 1. Identify lines, devices, and group addresses in the description. Give every group address a name and a DPT. 2. Write the scenario, starting from the closest example below. 3. Validate. With a checkout of the project: `npm run validate -- file.json` (or `-` for standard input; `--json` for machine-readable output). Each problem gives a JSON path such as `devices[1].objects[0].dpt`, a code, and a message. 4. Fix each reported path and validate again until the scenario is valid. 5. Open the result: `designer/index.html#json=` loads it in the designer with inline diagnostics, and `player.html#json=` shows it full screen. Percent-encode the whole JSON text (for example with `encodeURIComponent`). ## Minimal complete example A push-button toggles a lamp through a switching actuator; the actuator status feedback keeps the key synchronized. ```json { "formatVersion": 2, "title": "Lighting on one line", "lines": [ { "address": "1.1", "name": "Ground floor" } ], "groupAddresses": [ { "address": "1/1/1", "name": "Hall light", "dpt": "1.001" }, { "address": "1/4/1", "name": "Hall light status", "dpt": "1.001" } ], "devices": [ { "id": "pushButton", "name": "Push-button", "address": "1.1.1", "kind": "pushButton", "behavior": "pushButton/v1", "objects": [ { "id": "key1", "name": "Key 1", "ga": [ "1/1/1", "1/4/1" ], "dpt": "1.001", "port": "input", "flags": { "W": true, "T": true } } ], "buttons": [ { "id": "key1", "label": "Key 1", "press": { "object": "key1", "value": "toggle" }, "led": "key1" } ] }, { "id": "switchActuator", "name": "Switching actuator", "address": "1.1.2", "kind": "switchActuator", "behavior": "switchActuator/v1", "objects": [ { "id": "c1", "name": "Channel 1", "ga": "1/1/1", "dpt": "1.001", "port": "switch", "channel": "s1", "flags": { "W": true, "T": false } }, { "id": "e1", "name": "Status 1", "ga": "1/4/1", "dpt": "1.001", "port": "status", "channel": "s1", "flags": { "W": false, "T": true } } ], "channels": [ { "id": "s1", "label": "Hall", "equipment": { "type": "lamp" } } ] } ] } ``` ## Behaviors ### `pushButton/v1` Push button or sensor: each gesture writes a value into a local object, then transmits it. Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `input` | any | none | out | object sent by a key or input | | `display` | any | none | in | object receiving a value (indicator or feedback) | Device `parameters`: - `longPressMs` (integer, default 500; ≥ 100 ; ≤ 10000): Press duration that counts as a long press (ms), for keys with short and long actions. ### `switchActuator/v1` Switch actuator: each channel drives a relay; optional timer, status feedback, and power and energy metering. Drives channel outputs with `switch` commands; connect a compatible equipment type. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `switch` | 1.001 | required | in | | | `status` | 1.001 | required | out | | | `scene` | 17.001 | optional | in | | | `forced` | 2.001 | required | in | | | `power` | 14.056, 9.024 | required | out | electrical power drawn by the load of the channel: W with 14.056, kW with 9.024 | | `energy` | 13.010, 13.013 | required | out | active energy counted for the channel, sent cyclically: Wh with 13.010, kWh with 13.013 | | `totalPower` | 14.056, 9.024 | none | out | sum of the power of all channels: W with 14.056, kW with 9.024 | | `powerLimit` | 1.005, 1.001 | none | out | 1 when the total power reaches powerLimitW, 0 after hysteresis (load shedding) | Device `parameters`: - `meterIntervalMs` (integer, default 5000; ≥ 1000): Cyclic sending of power and energy values (ms), for channels with metering objects. - `powerSendDeltaW` (number, default 10; ≥ 0): Send a power value when it changes by at least this many watts. - `energyTimeScale` (number, default 60; > 0): Energy counting speed: 60 counts one simulated second as one minute, so that the counter moves visibly; 1 counts real time. - `powerLimitW` (number, default 0; ≥ 0): Total power (W) of the actuator outputs at which the powerLimit object is set, for load shedding (0 disables it). - `sheddingTimeMs` (integer, default 20000; ≥ 0): A shed output is switched on again after this time, if its command still requests it; it is shed again if the limit is still exceeded. - `powerLimitHysteresisW` (number, default 50; ≥ 0): The powerLimit object is reset below limit − hysteresis (W). Channel `parameters`: - `timerMs` (integer | null, default null; > 0): Timer duration (ms); null disables the timer. - `timerRetrigger` (string, default "restart"; "restart" (Restarts), "none" (No effect), "add" (Extends)): When 1 is received during a timer: restart begins a full period, none ignores it, and add extends the period (up to five times). - `timerWarningMs` (integer, default 0; ≥ 0): Time before the timer ends when the output briefly opens for one second as a warning (0 disables the warning). - `timerOffAllowed` (boolean, default true): Allow a 0 write to switch off before the timer ends; otherwise ignore it. - `loadShedding` (boolean, default false): Switch this output off while the total power limit of the actuator is exceeded (load shedding). - `relayMode` (string, default "normallyOpen"; "normallyOpen" (Normally open), "normallyClosed" (Normally closed)): normallyOpen closes the contact when the channel is on; normallyClosed closes it when the channel is off, so the load is powered while the switching state is 0. Status feedback reports the switching state, not the contact. - `statusDelayMs` (integer, default 300; ≥ 0): Delay before sending status feedback (ms). - `afterForcing` (string, default "lastCommand"; "lastCommand" (Last command), "previous" (Previous state), "unchanged" (Unchanged), "on" (Start), "off" (Stop), "toggle" (Toggle)): State after a priority override ends: follow the latest command received during the override, restore the previous state, keep the forced state, switch on, switch off, or invert the forced state. Channel `initialState`: - `on` (boolean, default false): Switching state of the channel when the simulation starts. ### `shutterActuator/v1` Shutter actuator without sensor: position estimated from the configured travel time. Drives channel outputs with `motor` commands; connect a compatible equipment type. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `move` | 1.008 | required | in | | | `stopStep` | 1.007 | required | in | | | `positionCommand` | 5.001 | required | in | | | `positionStatus` | 5.001 | required | out | | | `scene` | 17.001 | optional | in | | | `slatCommand` | 5.001 | required | in | slat angle (0 % open, 100 % closed) of a venetian blind | | `slatStatus` | 5.001 | required | out | estimated slat angle, sent after stopping | | `windAlarm` | 1.005, 1.001 | optional | in | 1 raises the shutter and locks it against other commands; 0 releases it in place | Channel `parameters`: - `estimatedTravelTimeMs` (integer, required; > 0): Travel time configured in the actuator (ms): downwards, and upwards unless estimatedTravelTimeUpMs is set. - `estimatedTravelTimeUpMs` (integer; > 0): Upward travel time configured in the actuator (ms), when it differs from the downward time; many actuators take separate times because a shutter rises more slowly than it falls. - `startDelayMs` (integer, default 300; ≥ 0): Delay before starting or reversing motion (ms). - `statusDelayMs` (integer, default 300; ≥ 0): Delay before sending position feedback (ms). - `slatTravelMs` (integer, default 0; ≥ 0): Venetian blind: time configured for the slats to turn from open to closed (ms). A movement first turns the slats; a short press at rest turns them by slatStepPct. 0 for a roller shutter without slats. - `slatStepPct` (number, default 20; ≥ 1 ; ≤ 100): Slat angle change for a short press at rest (%). - `stepPct` (number, default 0; ≥ 0 ; ≤ 100): Position step for a stop/step command received at rest by a shutter without slats (%). 0 (default): no movement, as in the KNX stop/step function, where the step turns slats; some actuators move a roller shutter by this amount instead. - `endSupplementPct` (number, default 0; ≥ 0 ; ≤ 50): Extra travel time toward 0% or 100%, as a percentage of full travel. The motor runs even if the estimate is already at the limit; the end stop recalibrates the estimate (often 5–10% on a real actuator). - `invertOutput` (boolean, default false): Invert the up and down outputs to compensate a motor wired in reverse (shutter parameter wiringReversed). Without such wiring, enabling it makes the shutter move opposite to the commands. Channel `initialState`: - `estimatedPositionPct` (number, default 0; ≥ 0 ; ≤ 100): Position the actuator assumes at start (0 = fully open, 100 = fully closed); the connected shutter starts at its own position. - `estimatedSlatPct` (number, default 0; ≥ 0 ; ≤ 100): Slat angle the actuator assumes at start (venetian blinds). ### `display/v1` Display / supervisor: receives and shows values, with no output or retransmission. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `display` | any | none | in | | ### `passive/v1` Device without logic: it only keeps the values of its objects. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `input` | any | none | out | | | `display` | any | none | in | | ### `presenceDetector/v1` Presence detector: sends 1 on first detection, 0 when its hold time ends (restarted by each detection). Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `input` | 1.001, 1.018 | none | out | output object: 1 on detection, 0 when the timer expires | | `brightness` | 9.004 | none | out | measured brightness (lx), entered by the reader and sent; there is no light model | Device `parameters`: - `holdMs` (integer, default 10000; > 0): Time with no detected presence before sending 0 (ms); restarted on each detection. - `retrigger` (boolean, default true): Each activation restarts the timer; otherwise it runs from the first activation. - `sendOnEnd` (boolean, default true): Send 0 when the timer expires; otherwise the detector sends only 1 and the actuator handles switch-off. - `brightnessThresholdLux` (number, default 0; ≥ 0): A detection switches on only while the entered brightness is below this value (lx); an active presence is still extended. 0 disables the threshold. ### `usbInterface/v1` USB interface: writes and reads group addresses from the USB interface panel of the diagram. No communication objects (`objects: []`). Device `parameters`: - `groupAddresses` (string, default ""): Group addresses assigned to this interface in the project, separated by spaces or commas. Coupler filter tables include them, so telegrams on these addresses cross couplers to and from the interface. Without them, a coupler filters an address that is not used on the interface side. ### `dimmerActuator/v1` Dimmer: switching, relative (3.007) and absolute (5.001) dimming, tunable white (7.600), status feedback. Drives channel outputs with `dim` commands; connect a compatible equipment type. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `switch` | 1.001 | required | in | | | `dim` | 3.007 | required | in | | | `value` | 5.001 | required | in | | | `status` | 1.001 | required | out | | | `valueStatus` | 5.001 | required | out | | | `scene` | 17.001 | optional | in | | | `colourTemperature` | 7.600 | required | in | colour temperature setpoint (K) of a tunable white channel | | `colourTemperatureStatus` | 7.600 | required | out | applied colour temperature (K) | Channel `parameters`: - `onLevel` (string, default "fixed"; "fixed" (Set value), "last" (Last value)): Level when switched on: fixed uses onLevelPct; last restores the level before switch-off. - `onLevelPct` (number, default 100; ≥ 1 ; ≤ 100): Level reached when a value of 1 is received (fixed mode). - `dimTimeMs` (integer, default 5000; > 0): Time for a 0–100% relative dimming transition (DPT 3.007); smaller steps take less time. - `switchFadeMs` (integer, default 0; ≥ 0): Transition time when switching on or off (0 means immediate). - `valueFadeMs` (integer, default 0; ≥ 0): Transition time to a received value (5.001) or scene preset. - `minLevelPct` (number, default 1; ≥ 0 ; ≤ 50): Minimum relative dimming level. - `maxLevelPct` (number, default 100; ≥ 50 ; ≤ 100): Upper limit for relative dimming and received values. - `dimSwitchesOn` (boolean, default true): An increase command turns on a channel that is off. - `dimSwitchesOff` (boolean, default false): A decrease command may dim to off; otherwise it stops at the minimum level. - `valueSwitchesOn` (boolean, default true): A brightness value above 0 turns on a channel that is off; otherwise the value is ignored while the channel is off. - `valueSwitchesOff` (boolean, default true): A brightness value of 0 turns the channel off; otherwise the channel dims to its minimum level. - `statusDelayMs` (integer, default 300; ≥ 0): Delay before sending status feedback (ms), after a transition completes. - `minColourK` (integer, default 2700; ≥ 1000 ; ≤ 10000): Lowest colour temperature (K) of a tunable white channel; lower requests are limited to it. - `maxColourK` (integer, default 6500; ≥ 1000 ; ≤ 10000): Highest colour temperature (K) of a tunable white channel; higher requests are limited to it. Channel `initialState`: - `levelPct` (number, default 0; ≥ 0 ; ≤ 100): Level of the output when the simulation starts; 0 is off. - `colourTemperatureK` (integer, default 4000; ≥ 1000 ; ≤ 10000): Colour temperature (K) at start, for a channel with a colourTemperature object. ### `daliGateway/v1` KNX/DALI gateway: each channel is a DALI group of ballasts; broadcast, scenes and fault reporting. Drives channel outputs with `dim` commands; connect a compatible equipment type. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `switch` | 1.001 | required | in | | | `dim` | 3.007 | required | in | | | `value` | 5.001 | required | in | | | `status` | 1.001 | required | out | | | `valueStatus` | 5.001 | required | out | | | `scene` | 17.001 | optional | in | | | `error` | 1.005 | required | out | lamp or ballast fault in the group | | `broadcastSwitch` | 1.001 | none | in | | | `broadcastValue` | 5.001 | none | in | | | `generalError` | 1.005 | none | out | | Device `parameters`: - `pollMs` (integer, default 2000; ≥ 500): Interval between ballast status polls for faults. Channel `parameters`: - `onLevel` (string, default "fixed"; "fixed" (Set value), "last" (Last value)): Level when switched on: fixed uses onLevelPct; last restores the level before switch-off. - `onLevelPct` (number, default 100; ≥ 1 ; ≤ 100): Level reached when a value of 1 is received (fixed mode). - `dimTimeMs` (integer, default 5000; > 0): Time for a 0–100% relative dimming transition (DPT 3.007); smaller steps take less time. - `switchFadeMs` (integer, default 0; ≥ 0): Transition time when switching on or off (0 means immediate). - `valueFadeMs` (integer, default 0; ≥ 0): Transition time to a received value (5.001) or scene preset. - `minLevelPct` (number, default 1; ≥ 0 ; ≤ 50): Minimum relative dimming level. - `maxLevelPct` (number, default 100; ≥ 50 ; ≤ 100): Upper limit for relative dimming and received values. - `dimSwitchesOn` (boolean, default true): An increase command turns on a channel that is off. - `dimSwitchesOff` (boolean, default false): A decrease command may dim to off; otherwise it stops at the minimum level. - `valueSwitchesOn` (boolean, default true): A brightness value above 0 turns on a channel that is off; otherwise the value is ignored while the channel is off. - `valueSwitchesOff` (boolean, default true): A brightness value of 0 turns the channel off; otherwise the channel dims to its minimum level. - `statusDelayMs` (integer, default 300; ≥ 0): Delay before sending status feedback (ms), after a transition completes. - `minColourK` (integer, default 2700; ≥ 1000 ; ≤ 10000): Lowest colour temperature (K) of a tunable white channel; lower requests are limited to it. - `maxColourK` (integer, default 6500; ≥ 1000 ; ≤ 10000): Highest colour temperature (K) of a tunable white channel; higher requests are limited to it. Channel `initialState`: - `levelPct` (number, default 0; ≥ 0 ; ≤ 100): Level of the output when the simulation starts; 0 is off. - `colourTemperatureK` (integer, default 4000; ≥ 1000 ; ≤ 10000): Colour temperature (K) at start, for a channel with a colourTemperature object. ### `roomThermostat/v1` Room thermostat: comfort / standby / economy / protection modes (20.102), window and presence, PI control (5.001 or PWM) or two-point, heating and cooling. Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `actualTemp` | 9.001 | none | out | | | `externalTemp` | 9.001 | none | in | replaces the internal sensor after a value is received | | `baseSetpoint` | 9.001 | none | in | | | `setpointShift` | 9.002 | none | in | base setpoint = configured setpoint + offset | | `setpointStatus` | 9.001 | none | out | | | `hvacMode` | 20.102 | none | in | | | `hvacModeStatus` | 20.102 | none | out | | | `presence` | 1.018, 1.001 | none | in | 1 = presence: comfort mode | | `window` | 1.019, 1.001, 1.009 | none | in | open window (1.019 / 1.001: 1 = open; 1.009: 0 = open): protection mode, highest priority | | `heatCool` | 1.100 | none | in | 1 = heating, 0 = cooling | | `heatCoolStatus` | 1.100 | none | out | | | `heatingValue` | 5.001 | none | out | continuous control value from 0 to 100% | | `heatingSwitch` | 1.001 | none | out | two-point control, or PWM under PI control | | `coolingValue` | 5.001 | none | out | | | `coolingSwitch` | 1.001 | none | out | | Device `parameters`: - `controlType` (string, default "pi"; "pi" (PI (continuous or PWM)), "twoPoint" (Two-point)): pi uses proportional-integral control with a continuous value (5.001) or PWM (1 bit); twoPoint uses on/off control with hysteresis. - `comfortC` (number, default 21; ≥ 5 ; ≤ 35): Initial heating comfort setpoint (°C); the baseSetpoint object can replace it. - `standbyShiftK` (number, default 2; ≥ 0 ; ≤ 10): Standby setpoint offset (K): lower for heating, higher for cooling. - `economyShiftK` (number, default 4; ≥ 0 ; ≤ 15): Economy or night setpoint offset (K): lower for heating, higher for cooling. - `frostProtectionC` (number, default 7; ≥ 3 ; ≤ 15): Heating setpoint in protection mode (°C). - `heatProtectionC` (number, default 35; ≥ 25 ; ≤ 45): Cooling setpoint in protection mode (°C). - `deadZoneK` (number, default 3; ≥ 0 ; ≤ 10): Difference between heating and cooling comfort setpoints (K), for example 21 °C and 24 °C. - `minSetpointC` (number, default 5; ≥ 0 ; ≤ 30): Lowest base setpoint accepted (°C); lower received or entered values are raised to it. - `maxSetpointC` (number, default 35; ≥ 10 ; ≤ 50): Highest base setpoint accepted (°C); higher received or entered values are lowered to it. - `hysteresisK` (number, default 0.5; ≥ 0.1 ; ≤ 5): Two-point control switches on again when temperature differs from the setpoint by this amount (K). - `proportionalBandK` (number, default 2; ≥ 0.5 ; ≤ 10): Temperature difference (K) that produces 100% output from the proportional term. - `integralTimeMs` (integer, default 120000; ≥ 0): PI integral time: a constant error doubles the proportional response after this duration (0 selects P control). Real installations use 60–240 minutes; the default follows compressed simulated room time. - `pwmCycleMs` (integer, default 20000; ≥ 1000): PWM cycle period for a 1-bit control object (real installations typically use 10–20 minutes). - `controlPeriodMs` (integer, default 1000; ≥ 100): Interval at which the controller recalculates its control value from the measured temperature. - `valueSendDeltaPct` (number, default 5; ≥ 1 ; ≤ 50): Send the control value when it changes by at least this many percentage points. - `externalTempTimeoutMs` (integer, default 0; ≥ 0): If no externalTemp value arrives within this time, control uses the internal sensor again until a new value arrives (0 disables monitoring). - `valueCyclicMs` (integer, default 0; ≥ 0): Periodically resend the control value (0 disables it); needed when the actuator monitors incoming values. - `temperatureSendDeltaK` (number, default 0.2; ≥ 0.1 ; ≤ 5): Send measured temperature when it changes by at least this amount (K). - `temperatureCyclicMs` (integer, default 0; ≥ 0): Also send the measured temperature at this interval, even without change; 0 disables cyclic sending. ### `heatingActuator/v1` Heating actuator: each output drives an electrothermal valve; continuous control value (5.001) converted to PWM, or direct 1-bit command, monitoring and emergency mode. Drives channel outputs with `switch` commands; connect a compatible equipment type. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `value` | 5.001 | required | in | | | `switch` | 1.001 | required | in | two-point or thermostat PWM control | | `valueStatus` | 5.001 | required | out | | | `fault` | 1.005 | required | out | missing control value: fallback program | Channel `parameters`: - `valveType` (string, default "normallyClosed"; "normallyClosed" (Closed when de-energised), "normallyOpen" (Open when de-energised)): normallyClosed: valve closed without power (common); normallyOpen: valve open without power, so the output is inverted. - `cycleMs` (integer, default 20000; ≥ 1000): PWM period for a continuous control value: powered time equals value × period (real installations typically use 10–20 minutes). - `monitoringMs` (integer, default 0; ≥ 0): If no control value arrives within this time, enter fallback mode and report a fault (0 disables monitoring). - `emergencyPct` (number, default 30; ≥ 0 ; ≤ 100): Control value applied in fallback mode. ### `windowContact/v1` Window contact (binary input): sends the opening and closing of its room's window. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `contact` | 1.019, 1.001, 1.009 | none | out | 1.019 / 1.001: 1 means open; 1.009: 1 means closed | Device `parameters`: - `contactType` (string, default "normallyOpen"; "normallyOpen" (Normally open), "normallyClosed" (Normally closed)): Physical contact: a normally open contact is closed while the window is closed; a normally closed contact is open while the window is closed. - `invert` (boolean, default false): Interpret the electrical input for a normally closed contact. The transmitted value always follows the DPT (1.019: 1 = open; 1.009: 1 = closed). - `sendOnStart` (boolean, default true): Send contact state when the simulation starts, as after bus power returns, so a thermostat can detect an already open window. - `startDelayMs` (integer, default 1000; ≥ 0): Delay after the simulation starts before the contact state is sent. ### `temperatureSensor/v1` Room temperature sensor: sends its room's temperature on change and cyclically. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `temperature` | 9.001 | none | out | | Device `parameters`: - `sendDeltaK` (number, default 0.2; ≥ 0.1 ; ≤ 5): Temperature change (K) that triggers a transmission. - `cyclicMs` (integer, default 0; ≥ 0): Periodic retransmission (0 disables it). ### `logicGate/v1` Logic module: combines one-bit inputs (AND, OR, XOR, NOT) and sends the result; an optional enable object blocks the output. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `logicIn` | 1.001, 1.002, 1.003, 1.005, 1.018, 1.019 | none | in | one-bit input of the logic function | | `enable` | 1.003, 1.001 | none | in | 0 blocks the output; 1 enables it again and sends the current result | | `time` | 10.001 | none | in | time received from a clock master, used by the time window | | `logicOut` | 1.001, 1.002, 1.003, 1.005, 1.008, 1.009 | none | out | result of the logic function | Device `parameters`: - `operation` (string, default "and"; "and" (AND), "or" (OR), "xor" (XOR), "not" (NOT (first input))): Logic function applied to the inputs; an input with no value yet counts as 0. - `activeFrom` (string, default ""): Start of a daily time window (HH:MM). With activeTo and a time object, the output is 1 only inside the window; the window may cross midnight. - `activeTo` (string, default ""): End of the daily time window (HH:MM), excluded. - `sendOnChangeOnly` (boolean, default true): Send the result only when it differs from the last transmitted value. ### `weatherStation/v1` Weather station: sends measured wind speed, brightness, and temperature; sets one-bit outputs when wind or brightness thresholds are reached. Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `wind` | 9.005, 9.028 | none | out | measured wind speed, sent when entered: m/s with 9.005, km/h with 9.028 (thresholds stay in m/s) | | `brightness` | 9.004 | none | out | measured brightness (lux), sent when entered | | `outdoorTemp` | 9.001 | none | out | measured outdoor temperature (°C), sent when entered | | `windAlarm` | 1.005, 1.001 | none | out | 1 when the wind threshold is reached, 0 after hysteresis | | `sunProtection` | 1.001, 1.002 | none | out | 1 when the brightness threshold is reached, 0 after hysteresis | Device `parameters`: - `windThreshold` (number, default 10; ≥ 0): Wind speed (m/s) at which the wind alarm is set. - `windHysteresis` (number, default 2; ≥ 0): The alarm is reset when the wind speed falls below threshold − hysteresis (m/s). - `brightnessThreshold` (number, default 40000; ≥ 0): Brightness (lux) at which sun protection is requested. - `setsRoomOutdoorTemperature` (boolean, default true): An entered outdoor temperature also becomes the outdoor temperature of every room in the thermal model, so that the building reacts to it. - `brightnessHysteresis` (number, default 5000; ≥ 0): The request is reset when brightness falls below threshold − hysteresis (lux). ### `airQualitySensor/v1` Air quality sensor: sends measured temperature, relative humidity, and CO₂; sets alarms at thresholds and controls ventilation in three steps. Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `temperature` | 9.001 | none | out | measured temperature (°C), sent when entered | | `humidity` | 9.007, 5.001 | none | out | measured relative humidity (%), sent when entered: 2-byte float with 9.007, one byte with 5.001 | | `co2` | 9.008 | none | out | measured CO₂ concentration (ppm), sent when entered | | `co2Alarm` | 1.005, 1.001 | none | out | 1 when the CO₂ alarm threshold is reached, 0 after hysteresis | | `humidityAlarm` | 1.005, 1.001 | none | out | 1 when the humidity alarm threshold is reached, 0 after hysteresis | | `ventilation` | 5.001 | none | out | control value (%) of the current ventilation step | Device `parameters`: - `co2AlarmPpm` (number, default 1500; ≥ 0 ; ≤ 10000): CO₂ concentration (ppm) at which the CO₂ alarm is set. - `co2AlarmHysteresisPpm` (number, default 100; ≥ 0 ; ≤ 10000): The CO₂ alarm is reset below threshold − hysteresis (ppm). - `humidityAlarmPct` (number, default 70; ≥ 0 ; ≤ 100): Relative humidity (%) at which the humidity alarm is set. - `humidityAlarmHysteresisPct` (number, default 5; ≥ 0 ; ≤ 100): The humidity alarm is reset below threshold − hysteresis (%). - `step1Ppm` (number, default 800; ≥ 0 ; ≤ 10000): CO₂ concentration (ppm) between ventilation steps 0 and 1. - `step2Ppm` (number, default 1000; ≥ 0 ; ≤ 10000): CO₂ concentration (ppm) between ventilation steps 1 and 2. - `step3Ppm` (number, default 1200; ≥ 0 ; ≤ 10000): CO₂ concentration (ppm) between ventilation steps 2 and 3. - `stepHysteresisPpm` (number, default 50; ≥ 0 ; ≤ 10000): A step changes only above threshold + hysteresis or below threshold − hysteresis (ppm). - `step0Pct` (number, default 0; ≥ 0 ; ≤ 100): Ventilation control value (%) sent in step 0. - `step1Pct` (number, default 33; ≥ 0 ; ≤ 100): Ventilation control value (%) sent in step 1. - `step2Pct` (number, default 66; ≥ 0 ; ≤ 100): Ventilation control value (%) sent in step 2. - `step3Pct` (number, default 100; ≥ 0 ; ≤ 100): Ventilation control value (%) sent in step 3. - `minStepTimeMs` (integer, default 0; ≥ 0): A step is kept at least this long before the next change (0 disables it). ### `clockMaster/v1` Clock master: sends the time of day (10.001) and the date (11.001) of the simulated clock at a fixed period and after the clock is set. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `time` | 10.001 | none | out | day of week and time of the simulated clock | | `date` | 11.001 | none | out | date of the simulated clock | Device `parameters`: - `sendPeriodMin` (integer, default 1; ≥ 0 ; ≤ 1440): Clock minutes between two broadcasts, aligned on the clock (1 = every full minute); 0 sends only at start and after the clock is set. - `sendOnStart` (boolean, default true): Send time and date shortly after the simulation starts. - `startDelayMs` (integer, default 1000; ≥ 0): Delay after the simulation starts before time and date are sent. ### `timeSwitch/v1` Weekly time switch: sends the programmed value on its output objects at the programmed times of the simulated clock. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `output` | 1.001, 1.002, 1.003, 1.008, 5.001, 5.010, 17.001, 20.102 | none | out | object that receives the programmed values | Device `parameters`: - `program` (string, default ""): Switching points separated by semicolons: days, time, and value, for example “Mon-Fri 07:00 = 1; Sat,Sun 09:00 = 1; Daily 22:30 = 0”. Days: Mon … Sun, ranges (Mon-Fri), lists (Sat,Sun), or Daily. - `sendOnStart` (boolean, default true): At start, and after the clock is set, send the value of the most recent switching point. ### `systemGateway/v1` Gateway to another building system (Modbus, BACnet…): values from that system are entered and sent on KNX; KNX commands are received and forwarded to it, without simulating the other protocol. Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `value` | any | none | out | value read in the other system (temperature, state, meter…), sent on KNX when entered | | `command` | any | none | in | value received from KNX and forwarded to the other system (mode, setpoint, boost…) | Device `parameters`: - `system` (string, default "Modbus"): Name of the system on the other side of the gateway, shown on the device card and in the event log, such as Modbus, BACnet, or M-Bus. ### `energyMeter/v1` Energy meter: measures several circuits that other devices switch or that are always supplied; sends their power and integrated energy. Accepts `buttons` and numeric `inputs`. | Port | DPTs | Channel | Direction | Description | | --- | --- | --- | --- | --- | | `power` | 14.056, 9.024 | required | out | power measured on the circuit: W with 14.056, kW with 9.024; a numeric input on this object enters the measured power | | `energy` | 13.010, 13.013 | required | out | energy counted on the circuit, sent cyclically: Wh with 13.010, kWh with 13.013 | | `totalPower` | 14.056, 9.024 | none | out | sum of the measured circuits: W with 14.056, kW with 9.024 | Device `parameters`: - `meterIntervalMs` (integer, default 5000; ≥ 1000): Cyclic sending of power and energy values (ms). - `powerSendDeltaW` (number, default 10; ≥ 0): Send a power value when it changes by at least this many watts. - `energyTimeScale` (number, default 60; > 0): Energy counting speed: 60 counts one simulated second as one minute, so that the counter moves visibly; 1 counts real time. Channel `initialState`: - `powerW` (number, default 0; ≥ 0 ; ≤ 1000000): Power (W) drawn by the circuit when the simulation starts; a numeric input on the power object changes it. - `energyWh` (number, default 0; ≥ 0): Energy (Wh) already counted when the simulation starts. ## Equipment types ### `lamp` Lamp: lit while the relay output is closed. Accepts `switch` commands. `parameters`: - `powerW` (number, default 60; ≥ 0 ; ≤ 100000): Electrical power (W) drawn while the lamp is on; used by metering actuators. Any switched load can be represented with a matching power. `initialState`: - `on` (boolean, default false) ### `shutter` Roller shutter: receives up/down/stop commands and moves through its actual travel, limited to 0–100%. Accepts `motor` commands. `parameters`: - `actualTravelTimeMs` (integer, required; > 0): Actual time for one complete travel (ms): downwards, and upwards unless actualTravelTimeUpMs is set. - `actualTravelTimeUpMs` (integer; > 0): Actual time for one complete upward travel (ms), when it differs from the downward time. - `slatTravelMs` (integer, default 0; ≥ 0): Venetian blind: time for the slats to turn from open to closed (ms). The motor first turns the slats, then moves the blind. 0 describes a roller shutter without slats. - `wiringReversed` (boolean, default false): Physical wiring with the up and down wires swapped: the motor turns opposite to the command. The actuator's “Inverted wiring” parameter compensates it. `initialState`: - `positionPct` (number, default 0; ≥ 0 ; ≤ 100) - `slatPct` (number, default 0; ≥ 0 ; ≤ 100) ### `dimmableLamp` Dimmable lamp: follows the commanded level with the requested fade; a tunable white lamp also follows the commanded colour temperature. Accepts `dim` commands. `parameters`: - `powerW` (number, default 40; ≥ 0 ; ≤ 100000): Electrical power (W) at full level; the drawn power is proportional to the level. `initialState`: - `levelPct` (number, default 0; ≥ 0 ; ≤ 100) ### `daliGroup` DALI ballasts in a group: each has a short address (0–63) and follows the commanded level. Accepts `dim` commands. `parameters`: - `ballasts` (integer, default 2; ≥ 1 ; ≤ 16): Number of ballasts (luminaires) in the group. - `firstAddress` (integer, default 0; ≥ 0 ; ≤ 63): Short DALI address of the first ballast; subsequent ballasts use consecutive addresses. `initialState`: - `levelPct` (number, default 0; ≥ 0 ; ≤ 100) - `failed` (integer, default 0; ≥ 0 ; ≤ 16): Number of ballasts initially reporting a lamp or ballast fault. ### `radiator` Radiator with a thermoelectric valve: gradual opening while powered; heat or cooling output is proportional to valve opening. Accepts `switch` commands. `parameters`: - `openingTimeMs` (integer, default 8000; ≥ 1000): Time for the valve to open fully (ms). Real valves take about 3 minutes; this is compressed like room time and should be short relative to the PWM period. - `normallyOpen` (boolean, default false): Normally open valve: applying power closes it. - `powerK` (number, default 25; ≥ 1 ; ≤ 60): Temperature difference (K) from outdoors that this radiator can maintain alone with the valve fully open. - `emitter` (string, default "heating"; "heating" (Heating), "cooling" (Cooling)): heating warms the room; cooling cools it, for example a fan coil with condensate drainage. Humidity and condensation are not modeled. `initialState`: - `openPct` (number, default 0; ≥ 0 ; ≤ 100) ### `fan` Ventilation fan: runs at the commanded speed (0–100 %) after a short ramp. Accepts `dim` commands. `parameters`: - `powerW` (number, default 50; ≥ 0 ; ≤ 100000): Electrical power (W) at full speed; the drawn power is proportional to the speed. `initialState`: - `levelPct` (number, default 0; ≥ 0 ; ≤ 100) ### `appliance` Electrical appliance on a switched output (oven, water heater, socket): draws its rated power while powered. Accepts `switch` commands. `parameters`: - `powerW` (number, default 2000; ≥ 0 ; ≤ 100000): Electrical power (W) drawn while the appliance is powered. `initialState`: - `on` (boolean, default false) ## Data point types | DPT | Name | Size (bits) | Range | | --- | --- | --- | --- | | `1.001` | Switch | 1 | 0 … 1 | | `1.002` | Boolean | 1 | 0 … 1 | | `1.003` | Enable | 1 | 0 … 1 | | `1.005` | Alarm | 1 | 0 … 1 | | `1.007` | Step | 1 | 0 … 1 | | `1.008` | Up/Down | 1 | 0 … 1 | | `1.009` | Open/Closed | 1 | 0 … 1 | | `1.010` | Start/Stop | 1 | 0 … 1 | | `1.011` | State | 1 | 0 … 1 | | `1.012` | Invert | 1 | 0 … 1 | | `1.017` | Trigger | 1 | 0 … 1 | | `1.018` | Occupation | 1 | 0 … 1 | | `1.019` | Window/Door | 1 | 0 … 1 | | `1.100` | Heating/Cooling | 1 | 0 … 1 | | `2.001` | Priority control | 2 | 0 … 3 | | `3.007` | Relative dimming | 4 | 0 … 15 | | `5.001` | Percentage | 8 | 0 … 100 | | `5.004` | Percentage (0–255) | 8 | 0 … 255 | | `5.010` | Counter | 8 | 0 … 255 | | `7.600` | Colour temperature | 16 | 0 … 65535 | | `9.001` | Temperature | 16 | -273 … 670433.28 | | `9.002` | Temperature difference | 16 | -671088.64 … 670433.28 | | `9.004` | Lux | 16 | 0 … 670433.28 | | `9.005` | Wind speed | 16 | 0 … 670433.28 | | `9.007` | Humidity | 16 | 0 … 670433.28 | | `9.008` | Air quality | 16 | 0 … 670433.28 | | `9.024` | Power (kW) | 16 | -671088.64 … 670433.28 | | `9.028` | Wind speed (km/h) | 16 | 0 … 670433.28 | | `10.001` | Time of day | 24 | 0 … 691199 (00:00:00 … Sun 23:59:59) | | `11.001` | Date | 24 | 19900101 … 20891231 (1990-01-01 … 2089-12-31) | | `13.010` | Active energy | 32 | -2147483648 … 2147483647 | | `13.013` | Active energy (kWh) | 32 | -2147483648 … 2147483647 | | `14.056` | Power | 32 | -3.4e+38 … 3.4e+38 | | `17.001` | Scene number | 8 | 0 … 63 | | `20.102` | HVAC mode | 8 | 0 … 4 | ## Complete examples - `scenarios/air-quality.json`: Air quality: CO₂ and humidity control - `scenarios/boiler-room.json`: Heat pump and hot water behind a gateway - `scenarios/dali-gateway.json`: KNX/DALI gateway: groups, dimming, and faults - `scenarios/dimming.json`: Dimming actuator: switching, relative, and absolute dimming - `scenarios/energy-metering.json`: Energy metering and load shedding - `scenarios/full-topology.json`: KNX topology: couplers, repeater, and KNXnet/IP routers - `scenarios/lighting-control.json`: Control multiple outputs - `scenarios/object-flags.json`: W and T flags: six-output actuator - `scenarios/priority-control.json`: Force an output - `scenarios/room-heating.json`: Room-by-room heating control - `scenarios/scenes.json`: Scenes - `scenarios/shutter-calibrated.json`: Shutter with correct actuator settings - `scenarios/shutter-calibration.json`: Shutter: estimated versus actual travel - `scenarios/shutter-control.json`: Control roller shutters - `scenarios/status-feedback.json`: Toggle controls and status feedback - `scenarios/time-schedule.json`: Time schedule: clock master, time switch, and time window - `scenarios/timers.json`: Timer, clock, and presence detection - `scenarios/tunable-white.json`: Tunable white: level and colour temperature - `scenarios/usb-interface.json`: USB interface panel: write and read a group address - `scenarios/venetian-blind.json`: Venetian blind: travel and slat angle - `scenarios/weather-protection.json`: Weather protection: wind alarm and sun protection