Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Copy [`examples/demo-house`](examples/demo-house) into its own (private) git rep
| `circuits.yaml` | Breaker circuits and what they feed |
| `signals.yaml` | Where software sees a port: PLC name and address, MQTT topic, openHAB item |

Every list can also be split over a folder: `devices.yaml` and `devices/*.yaml` are read together, like `points/`.

Cable and circuit ends are written as a point or device ID, or as `device:port` (for example `plc-di01:DI 01.1`). Plan images go in `plans/`, photos in `photos/`.

### Point IDs
Expand All @@ -68,6 +70,34 @@ types:

Room codes are defined per floor in `site.yaml`.

### Importing the WAGO PLC configuration

HAdoc reads the CODESYS 2.3 (WAGO-I/O-PRO) PLC configuration export directly, so the PLC side never has to be typed in:

1. In CODESYS, open the PLC configuration and choose **Project > Export**. Save it in your data folder, e.g. `imports/plc-configuration.exp`.
2. Point `settings.yaml` at it:

```yaml
imports:
wago:
config: imports/plc-configuration.exp
controller: plc # device ID of the PLC, optional
id_prefix: plc- # optional, the default
```

Each I/O module becomes a device named after its comment (`DI 01` becomes `plc-di01`), with one port per channel (`DI 01.1` to `DI 01.4`). Each channel with a symbolic name becomes a signal `PLC-<name>` with its IEC address; a real channel comment becomes the signal's name. Channels without a name show as spare ports.

The export is read on every load, so re-exporting after a change in CODESYS updates HAdoc. To add something to an imported record, write an entry with the same ID; its fields are laid over the import:

```yaml
# signals.yaml
- id: PLC-SB_0_1L
name: Hall switch
point: 0-HAL-SW-01
```

Imported signals that are not linked to a point yet are listed under "To check".

### Validate

```bash
Expand All @@ -90,7 +120,7 @@ The server reloads the data when files in the data folder change.
## Roadmap

1. **MVP**: plan underlay, rooms, points, point pages, trace, checks *(this scaffold)*. Next: placing and editing points in the app, with each change committed to git.
2. **WAGO import** from CODESYS 2.3 `PLC CONFIGURATION.EXP`, seeding points from channel names and comments.
2. **WAGO import** from the CODESYS 2.3 PLC configuration export *(done)*.
3. **Cables and circuits**: drawing routes, terminals and cores, breaker colouring.
4. **Importers**: openHAB, UniFi (status and IP), ESPHome, Tasmota, MQTT, plus the "undocumented" report and the rules behind each item.
5. **PLC logic viewer** from POU exports, wall and enclosure views, QR labels.
Expand Down
22 changes: 1 addition & 21 deletions examples/demo-house/devices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,7 @@
model: WAGO 750-881
location: plc-cabinet
hostname: plc.lan
notes: Low-level logic for switches and blinds.

- id: plc-di01
kind: io-module
model: WAGO 750-403 (4 DI 24V)
label: DI 01
location: plc
ports:
- { name: "DI 01.1", signal: DI 24V }
- { name: "DI 01.2", signal: DI 24V }
- { name: "DI 01.3", signal: DI 24V }
- { name: "DI 01.4", signal: DI 24V }

- id: plc-do01
kind: io-module
model: WAGO 750-504 (4 DO 24V)
label: DO 01
location: plc
ports:
- { name: "DO 01.1", signal: DO 24V }
- { name: "DO 01.2", signal: DO 24V }
notes: Low-level logic for switches and blinds. Its I/O modules come from imports/plc-configuration.exp.

- id: esp-dressing
kind: esp
Expand Down
143 changes: 143 additions & 0 deletions examples/demo-house/imports/plc-configuration.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
PLC_CONFIGURATION
_GLOBAL
_VERSION: 3
_AUTOADR: 0
_CHECKADR: 0
_SAVECONFIGFILESINPROJECT: 0
_END_GLOBAL

_MODULE: '3S'
_SECTION_NAME: 'Root'
_INDEX_IN_PARENT: '-1'
_MODULE_NAME: 'Hardware configuration'
_NODE_ID: -1
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: ''

_MODULE: '3S'
_SECTION_NAME: 'K_Bus'
_INDEX_IN_PARENT: '1'
_MODULE_NAME: 'K-Bus'
_NODE_ID: 0
_IECIN: %IB0
_IECOUT: %QB0
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: 'Ethernet Controller 100MBit 2Port'

_MODULE: '3S'
_SECTION_NAME: 'Type_1_4_Channels'
_INDEX_IN_PARENT: '1'
_MODULE_NAME: '0750-0403 4 DI 24 V DC 0.2ms'
_NODE_ID: 0
_IECIN: %IB8
_IECOUT: %QB8
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: 'DI 01'

_PARAMETER
_PARAM 10000: 0, 'PLC'
_PARAM 10001: 0, 'plugged'
_END_PARAMETER

_CHANNEL
_SECTION_NAME: 'BOOLOnX_I'
_INDEX_IN_PARENT: '1'
_SYMBOLIC_NAME: 'SB_0_1L'
_COMMENT: 'Ch_1 Digital input'
_CHANNEL_MODE: 'I'
_IECADR: %IX4.0
_END_CHANNEL

_CHANNEL
_SECTION_NAME: 'BOOLOnX_I'
_INDEX_IN_PARENT: '2'
_SYMBOLIC_NAME: 'SB_0_1R'
_COMMENT: 'Ch_2 Digital input'
_CHANNEL_MODE: 'I'
_IECADR: %IX4.1
_END_CHANNEL

_CHANNEL
_SECTION_NAME: 'BOOLOnX_I'
_INDEX_IN_PARENT: '3'
_SYMBOLIC_NAME: 'SM_0_A'
_COMMENT: 'Voordeur'
_CHANNEL_MODE: 'I'
_IECADR: %IX4.2
_END_CHANNEL

_CHANNEL
_SECTION_NAME: 'BOOLOnX_I'
_INDEX_IN_PARENT: '4'
_SYMBOLIC_NAME: ''
_COMMENT: 'Ch_4 Digital input'
_CHANNEL_MODE: 'I'
_IECADR: %IX4.3
_END_CHANNEL
_END_MODULE

_MODULE: '3S'
_SECTION_NAME: 'Type_10_4_Channels'
_INDEX_IN_PARENT: '2'
_MODULE_NAME: '0750-0504 4 DO 24V DC 0.5A'
_NODE_ID: 1
_IECIN: %IB8
_IECOUT: %QB8
_IECDIAG: %MB0
_DOWNLOAD: 1
_EXCLUDEFROMAUTOADR: 0
_COMMENT: 'DO 01'

_PARAMETER
_PARAM 10000: 0, 'PLC'
_PARAM 10001: 0, 'plugged'
_END_PARAMETER

_CHANNEL
_SECTION_NAME: 'BOOLOnX_Q'
_INDEX_IN_PARENT: '1'
_SYMBOLIC_NAME: 'R_0_HAL'
_COMMENT: 'Ch_1 Digital output'
_CHANNEL_MODE: 'Q'
_IECADR: %QX4.0
_END_CHANNEL

_CHANNEL
_SECTION_NAME: 'BOOLOnX_Q'
_INDEX_IN_PARENT: '2'
_SYMBOLIC_NAME: 'R_1_BED_UP'
_COMMENT: 'Rolluik slaapkamer op'
_CHANNEL_MODE: 'Q'
_IECADR: %QX4.1
_END_CHANNEL

_CHANNEL
_SECTION_NAME: 'BOOLOnX_Q'
_INDEX_IN_PARENT: '3'
_SYMBOLIC_NAME: 'R_1_BED_DN'
_COMMENT: 'Rolluik slaapkamer neer'
_CHANNEL_MODE: 'Q'
_IECADR: %QX4.2
_END_CHANNEL

_CHANNEL
_SECTION_NAME: 'BOOLOnX_Q'
_INDEX_IN_PARENT: '4'
_SYMBOLIC_NAME: ''
_COMMENT: 'Ch_4 Digital output'
_CHANNEL_MODE: 'Q'
_IECADR: %QX4.3
_END_CHANNEL
_END_MODULE

_END_MODULE
_END_MODULE
PLC_END
6 changes: 6 additions & 0 deletions examples/demo-house/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ types:
- { code: BLD, name: Blind motor, layer: automation }
- { code: ESP, name: Hidden ESP board, layer: hidden }
- { code: JB, name: Junction box, layer: hidden }

# Exports from other systems, read every time the data loads.
imports:
wago:
config: imports/plc-configuration.exp
controller: plc
16 changes: 12 additions & 4 deletions examples/demo-house/signals.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# yaml-language-server: $schema=../../schema/signals.schema.json
- id: SIG-0-HAL-SW-01
# PLC signals are imported from imports/plc-configuration.exp.
# An entry with the same ID adds to the imported one, here to link it to a point.
- id: PLC-SB_0_1L
name: Hall switch
port: "plc-di01:DI 01.1"
point: 0-HAL-SW-01
plc: { name: SB_0_1L, address: "%IX4.0" }
logic: plc

- id: PLC-R_0_HAL
point: 0-HAL-LGT-01

- id: PLC-R_1_BED_UP
point: 1-BED-BLD-01

- id: PLC-R_1_BED_DN
point: 1-BED-BLD-01

- id: SIG-1-DRS-PIR-01
name: Dressing room motion
Expand Down
100 changes: 87 additions & 13 deletions schema/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,38 @@
"description": "House-wide settings, including the configurable point ID scheme and abbreviations.",
"type": "object",
"additionalProperties": false,
"required": ["ids", "levels", "types"],
"required": [
"ids",
"levels",
"types"
],
"properties": {
"name": { "type": "string", "description": "Name of the house, shown in the app header." },
"language": { "type": "string", "description": "UI language hint, e.g. 'nl' or 'en'." },
"name": {
"type": "string",
"description": "Name of the house, shown in the app header."
},
"language": {
"type": "string",
"description": "UI language hint, e.g. 'nl' or 'en'."
},
"ids": {
"type": "object",
"additionalProperties": false,
"required": ["pattern"],
"required": [
"pattern"
],
"properties": {
"pattern": {
"type": "string",
"description": "Point ID pattern. Placeholders: {level}, {room}, {type}, {nr}.",
"default": "{level}-{room}-{type}-{nr}"
},
"nr_digits": { "type": "integer", "minimum": 1, "maximum": 6, "default": 2 }
"nr_digits": {
"type": "integer",
"minimum": 1,
"maximum": 6,
"default": 2
}
}
},
"levels": {
Expand All @@ -28,10 +45,18 @@
"items": {
"type": "object",
"additionalProperties": false,
"required": ["code", "name"],
"required": [
"code",
"name"
],
"properties": {
"code": { "type": "string", "pattern": "^[A-Za-z0-9]+$" },
"name": { "type": "string" }
"code": {
"type": "string",
"pattern": "^[A-Za-z0-9]+$"
},
"name": {
"type": "string"
}
}
}
},
Expand All @@ -41,12 +66,61 @@
"items": {
"type": "object",
"additionalProperties": false,
"required": ["code", "name"],
"required": [
"code",
"name"
],
"properties": {
"code": { "type": "string", "pattern": "^[A-Za-z0-9]+$" },
"name": { "type": "string" },
"symbol": { "type": "string", "description": "Short text shown on the plan symbol; defaults to the code." },
"layer": { "enum": ["power", "data", "automation", "hidden"], "default": "power" }
"code": {
"type": "string",
"pattern": "^[A-Za-z0-9]+$"
},
"name": {
"type": "string"
},
"symbol": {
"type": "string",
"description": "Short text shown on the plan symbol; defaults to the code."
},
"layer": {
"enum": [
"power",
"data",
"automation",
"hidden"
],
"default": "power"
}
}
}
},
"imports": {
"type": "object",
"additionalProperties": false,
"description": "Files exported from other systems, read on every load.",
"properties": {
"wago": {
"type": "object",
"additionalProperties": false,
"required": [
"config"
],
"description": "CODESYS 2.3 PLC configuration export (Project > Export, PLC configuration).",
"properties": {
"config": {
"type": "string",
"description": "Path relative to the data folder, e.g. imports/PLC CONFIGURATION.EXP."
},
"controller": {
"type": "string",
"description": "Device ID of the PLC; modules get it as their location."
},
"id_prefix": {
"type": "string",
"default": "plc-",
"description": "Prefix for module device IDs."
}
}
}
}
}
Expand Down
Loading
Loading