Refactor room and light configurations for Node-RED integration

- Updated global variable lists in GVL_IO.gvl and GVL_NVL_placeholders.gvl to reflect new room naming conventions and structures.
- Revised PLC_App.st to map new room configurations for lighting control.
- Enhanced documentation in all-lights-and-rooms.md and ha-lights-and-rooms.md to align with updated room and light entity naming.
- Adjusted room-config.js and related Node-RED flows to support the new configuration structure.

This update improves the organization and clarity of room and light management within the Node-RED integration, ensuring consistency across the system.
This commit is contained in:
2026-04-01 19:09:59 +03:00
parent d755d3c1ed
commit 0af21f4dc3
16 changed files with 579 additions and 220 deletions

View File

@@ -1,27 +1,27 @@
(* (*
GVL: GVL_IO GVL: GVL_IO
Option C relay feedback only. EL2809 DO: map channels directly in the device tree Option C relay feedback only. EL2809 DO: map channels directly in the device tree
to NVL_Out (e.g. NVL_Out.l_masterBedroom.l_1..l_6, ...) and boiler relay. to NVL_Out (e.g. NVL_Out.l_open_plan_living_room.l_1..l_6, ...) and boiler relay.
Initialize EtherCAT_RelayFeedback to zero at startup (or use default init). Initialize EtherCAT_RelayFeedback to zero at startup (or use default init).
*) *)
VAR_GLOBAL VAR_GLOBAL
// ---------- Option C: relay feedback (copy of output for next cycle) ---------- // ---------- Option C: relay feedback (copy of output for next cycle) ----------
EtherCAT_RelayFeedback: STRUCT EtherCAT_RelayFeedback: STRUCT
masterBedroom: struct_room_outs; open_plan_living_room: struct_room_outs;
masterBathroom: struct_room_outs; open_plan_dining_room: struct_room_outs;
bedroom_1: struct_room_outs; open_plan_entrance: struct_room_outs;
bedroom_2: struct_room_outs; open_plan_guest_wc: struct_room_outs;
bathroom: struct_room_outs; kitchen_kitchen: struct_room_outs;
guest_wc: struct_room_outs; kitchen_pantry: struct_room_outs;
kitchen: struct_room_outs; bedrooms_office: struct_room_outs;
pantry: struct_room_outs; bedrooms_hallway: struct_room_outs;
livingRoom: struct_room_outs; bedrooms_laundry: struct_room_outs;
diningRoom: struct_room_outs; bedrooms_shower: struct_room_outs;
entrance: struct_room_outs; bedrooms_bedroom: struct_room_outs;
hallway: struct_room_outs; master_bedroom_suite: struct_room_outs;
veranda: struct_room_outs; master_bedroom_bathroom: struct_room_outs;
front: struct_room_outs; exterior_veranda: struct_room_outs;
back: struct_room_outs; exterior_entrance: struct_room_outs;
side: struct_room_outs; exterior_yard: struct_room_outs;
END_STRUCT; END_STRUCT;
END_VAR END_VAR

View File

@@ -5,42 +5,42 @@
*) *)
VAR_GLOBAL VAR_GLOBAL
NVL_In: STRUCT NVL_In: STRUCT
masterBedroom: struct_room_cmds; open_plan_living_room: struct_room_cmds;
masterBathroom: struct_room_cmds; open_plan_dining_room: struct_room_cmds;
bedroom_1: struct_room_cmds; open_plan_entrance: struct_room_cmds;
bedroom_2: struct_room_cmds; open_plan_guest_wc: struct_room_cmds;
bathroom: struct_room_cmds; kitchen_kitchen: struct_room_cmds;
guestWc: struct_room_cmds; kitchen_pantry: struct_room_cmds;
kitchen: struct_room_cmds; bedrooms_office: struct_room_cmds;
pantry: struct_room_cmds; bedrooms_hallway: struct_room_cmds;
livingRoom: struct_room_cmds; bedrooms_laundry: struct_room_cmds;
dinningRoom: struct_room_cmds; bedrooms_shower: struct_room_cmds;
entrance: struct_room_cmds; bedrooms_bedroom: struct_room_cmds;
hallway: struct_room_cmds; master_bedroom_suite: struct_room_cmds;
outVeranda: struct_room_cmds; master_bedroom_bathroom: struct_room_cmds;
outFront: struct_room_cmds; exterior_veranda: struct_room_cmds;
outBack: struct_room_cmds; exterior_entrance: struct_room_cmds;
outSide: struct_room_cmds; exterior_yard: struct_room_cmds;
boiler: struct_boiler_cmd; boiler: struct_boiler_cmd;
END_STRUCT; END_STRUCT;
NVL_Out: STRUCT NVL_Out: STRUCT
l_masterBedroom: struct_room_outs; l_open_plan_living_room: struct_room_outs;
l_masterBathroom: struct_room_outs; l_open_plan_dining_room: struct_room_outs;
l_bedroom_1: struct_room_outs; l_open_plan_entrance: struct_room_outs;
l_bedroom_2: struct_room_outs; l_open_plan_guest_wc: struct_room_outs;
l_bathroom: struct_room_outs; l_kitchen_kitchen: struct_room_outs;
l_guestWc: struct_room_outs; l_kitchen_pantry: struct_room_outs;
l_kitchen: struct_room_outs; l_bedrooms_office: struct_room_outs;
l_pantry: struct_room_outs; l_bedrooms_hallway: struct_room_outs;
l_livingRoom: struct_room_outs; l_bedrooms_laundry: struct_room_outs;
l_dinningRoom: struct_room_outs; l_bedrooms_shower: struct_room_outs;
l_entrance: struct_room_outs; l_bedrooms_bedroom: struct_room_outs;
l_hallway: struct_room_outs; l_master_bedroom_suite: struct_room_outs;
l_outVeranda: struct_room_outs; l_master_bedroom_bathroom: struct_room_outs;
l_outFront: struct_room_outs; l_exterior_veranda: struct_room_outs;
l_outBack: struct_room_outs; l_exterior_entrance: struct_room_outs;
l_outSide: struct_room_outs; l_exterior_yard: struct_room_outs;
boiler_status: struct_boiler_status; boiler_status: struct_boiler_status;
END_STRUCT; END_STRUCT;

View File

@@ -23,12 +23,14 @@ This folder describes the **network variable** setup used for CODESYS ↔ Node-R
| Variable | Type | Description | | Variable | Type | Description |
|----------|------|-------------| |----------|------|-------------|
| `l_masterBedroom` | struct_room_outs | 12 BOOLs (l_1..l_6, l_1_status..l_6_status) | | `l_open_plan_living_room` | struct_room_outs | 6 BOOLs (`l_1..l_6`) |
| `l_masterBathroom` | struct_room_outs | same | | `l_open_plan_dining_room` | struct_room_outs | same |
| `l_bedroom_1` .. `l_bedroom_2` | struct_room_outs | same | | `l_open_plan_entrance` | struct_room_outs | same |
| `l_bathroom`, `l_guestWc`, `l_kitchen`, `l_pantry` | struct_room_outs | same | | `l_open_plan_guest_wc` | struct_room_outs | same |
| `l_livingRoom`, `l_dinningRoom`, `l_entrance`, `l_hallway` | struct_room_outs | same | | `l_kitchen_kitchen`, `l_kitchen_pantry` | struct_room_outs | same |
| `l_outVeranda`, `l_outFront`, `l_outBack`, `l_outSide` | struct_room_outs | same | | `l_bedrooms_office`, `l_bedrooms_hallway`, `l_bedrooms_laundry`, `l_bedrooms_shower`, `l_bedrooms_bedroom` | struct_room_outs | same |
| `l_master_bedroom_suite`, `l_master_bedroom_bathroom` | struct_room_outs | same |
| `l_exterior_veranda`, `l_exterior_entrance`, `l_exterior_yard` | struct_room_outs | same |
| `boiler_status` | struct_boiler_status | state, relay_output, on_time_minutes, remaining_minutes, emergency_active, time_limit_reached, error_state, error_code | | `boiler_status` | struct_boiler_status | state, relay_output, on_time_minutes, remaining_minutes, emergency_active, time_limit_reached, error_state, error_code |
**In CODESYS:** Create an **NVL Sender** (Network Variable List), bind it to the **NVL_Out** structure (the same struct as in `GVL_NVL_placeholders.gvl``NVL_Out`). Set protocol to UDP, destination IP/port to your Node-RED host, task and interval (e.g. EtherCAT_Task, 50 ms). **In CODESYS:** Create an **NVL Sender** (Network Variable List), bind it to the **NVL_Out** structure (the same struct as in `GVL_NVL_placeholders.gvl``NVL_Out`). Set protocol to UDP, destination IP/port to your Node-RED host, task and interval (e.g. EtherCAT_Task, 50 ms).
@@ -43,7 +45,7 @@ This folder describes the **network variable** setup used for CODESYS ↔ Node-R
| Variable | Type | Description | | Variable | Type | Description |
|----------|------|-------------| |----------|------|-------------|
| `masterBedroom` .. `side` (15 rooms) | struct_room_cmds | ha_l1_on, ha_l1_off, ... ha_l6_on, ha_l6_off, zigbee_sw1..6, ha_all_on, ha_all_off | | `open_plan_living_room` .. `exterior_yard` (16 rooms) | struct_room_cmds | ha_l1_on, ha_l1_off, ... ha_l6_on, ha_l6_off, zigbee_sw1..6, ha_all_on, ha_all_off |
| `boiler` | struct_boiler_cmd | ha_on, ha_off, schedule_on, schedule_off, emergency_stop, max_on_time_minutes | | `boiler` | struct_boiler_cmd | ha_on, ha_off, schedule_on, schedule_off, emergency_stop, max_on_time_minutes |
**In CODESYS:** Create an **NVL Receiver**, bind it to the **NVL_In** structure. Set protocol to UDP, listen port, task and interval. The PLC will overwrite `NVL_In` with received data each cycle. **In CODESYS:** Create an **NVL Receiver**, bind it to the **NVL_In** structure. Set protocol to UDP, listen port, task and interval. The PLC will overwrite `NVL_In` with received data each cycle.

View File

@@ -25,7 +25,7 @@ PLC sends one block: all rooms `struct_room_outs` followed by `struct_boiler_
6 BOOLs in order: `l_1, l_2, l_3, l_4, l_5, l_6` (light state; with Option C this is both output and status). 6 BOOLs in order: `l_1, l_2, l_3, l_4, l_5, l_6` (light state; with Option C this is both output and status).
- **Size per room:** 6 bytes. - **Size per room:** 6 bytes.
- **Rooms in order:** l_masterBedroom, l_masterBathroom, l_bedroom_1, l_bedroom_2, l_bathroom, l_guestWc, l_kitchen, l_pantry, l_livingRoom, l_dinningRoom, l_entrance, l_hallway, l_outVeranda, l_outFront, l_outBack, l_outSide. - **Rooms in order:** l_open_plan_living_room, l_open_plan_dining_room, l_open_plan_entrance, l_open_plan_guest_wc, l_kitchen_kitchen, l_kitchen_pantry, l_bedrooms_office, l_bedrooms_hallway, l_bedrooms_laundry, l_bedrooms_shower, l_bedrooms_bedroom, l_master_bedroom_suite, l_master_bedroom_bathroom, l_exterior_veranda, l_exterior_entrance, l_exterior_yard.
- **Total for lights:** 16 × 6 = **96 bytes**. - **Total for lights:** 16 × 6 = **96 bytes**.
### struct_boiler_status (after all rooms) ### struct_boiler_status (after all rooms)
@@ -50,7 +50,7 @@ PLC sends one block: all rooms `struct_room_outs` followed by `struct_boiler_
// msg.payload = Buffer (UDP payload from PLC) // msg.payload = Buffer (UDP payload from PLC)
const buf = msg.payload; const buf = msg.payload;
const roomSize = 6; const roomSize = 6;
const roomNames = ['l_masterBedroom','l_masterBathroom','l_bedroom_1','l_bedroom_2','l_bathroom','l_guestWc','l_kitchen','l_pantry','l_livingRoom','l_dinningRoom','l_entrance','l_hallway','l_outVeranda','l_outFront','l_outBack','l_outSide']; const roomNames = ['l_open_plan_living_room','l_open_plan_dining_room','l_open_plan_entrance','l_open_plan_guest_wc','l_kitchen_kitchen','l_kitchen_pantry','l_bedrooms_office','l_bedrooms_hallway','l_bedrooms_laundry','l_bedrooms_shower','l_bedrooms_bedroom','l_master_bedroom_suite','l_master_bedroom_bathroom','l_exterior_veranda','l_exterior_entrance','l_exterior_yard'];
const out = { rooms: {}, boiler_status: {} }; const out = { rooms: {}, boiler_status: {} };
@@ -90,7 +90,7 @@ PLC expects one block: all rooms `struct_room_cmds` followed by `struct_boile
ha_l1_on, ha_l1_off, ha_l2_on, ha_l2_off, ha_l3_on, ha_l3_off, ha_l4_on, ha_l4_off, ha_l5_on, ha_l5_off, ha_l6_on, ha_l6_off, zigbee_sw1..6, ha_all_on, ha_all_off. ha_l1_on, ha_l1_off, ha_l2_on, ha_l2_off, ha_l3_on, ha_l3_off, ha_l4_on, ha_l4_off, ha_l5_on, ha_l5_off, ha_l6_on, ha_l6_off, zigbee_sw1..6, ha_all_on, ha_all_off.
- **Size per room:** 20 bytes. - **Size per room:** 20 bytes.
- **Rooms in order:** masterBedroom, masterBathroom, bedroom_1, bedroom_2, bathroom, guestWc, kitchen, pantry, livingRoom, dinningRoom, entrance, hallway, outVeranda, outFront, outBack, outSide. - **Rooms in order:** open_plan_living_room, open_plan_dining_room, open_plan_entrance, open_plan_guest_wc, kitchen_kitchen, kitchen_pantry, bedrooms_office, bedrooms_hallway, bedrooms_laundry, bedrooms_shower, bedrooms_bedroom, master_bedroom_suite, master_bedroom_bathroom, exterior_veranda, exterior_entrance, exterior_yard.
- **Total for rooms:** 16 × 20 = **320 bytes**. - **Total for rooms:** 16 × 20 = **320 bytes**.
### struct_boiler_cmd ### struct_boiler_cmd
@@ -112,7 +112,7 @@ ha_l1_on, ha_l1_off, ha_l2_on, ha_l2_off, ha_l3_on, ha_l3_off, ha_l4_on, ha_l4_o
```javascript ```javascript
// Build binary payload for PLC from commands // Build binary payload for PLC from commands
const roomSize = 20; const roomSize = 20;
const roomNames = ['masterBedroom','masterBathroom','bedroom_1','bedroom_2','bathroom','guestWc','kitchen','pantry','livingRoom','dinningRoom','entrance','hallway','outVeranda','outFront','outBack','outSide']; const roomNames = ['open_plan_living_room','open_plan_dining_room','open_plan_entrance','open_plan_guest_wc','kitchen_kitchen','kitchen_pantry','bedrooms_office','bedrooms_hallway','bedrooms_laundry','bedrooms_shower','bedrooms_bedroom','master_bedroom_suite','master_bedroom_bathroom','exterior_veranda','exterior_entrance','exterior_yard'];
const buf = Buffer.alloc(328); const buf = Buffer.alloc(328);
const rooms = msg.payload.rooms || {}; const rooms = msg.payload.rooms || {};

View File

@@ -2,112 +2,112 @@
POU: PLC_App POU: PLC_App
Main program (Option C: copy of output as relay feedback). Main program (Option C: copy of output as relay feedback).
Requires: NVL_In, NVL_Out, GVL_IO (EtherCAT_RelayFeedback). Requires: NVL_In, NVL_Out, GVL_IO (EtherCAT_RelayFeedback).
Map EL2809 DO channels in the device tree directly to NVL_Out (e.g. Ch0..5 = l_masterBedroom.l_1..l_6) Map EL2809 DO channels in the device tree directly to NVL_Out (e.g. Ch0..5 = l_open_plan_living_room.l_1..l_6)
and Ch15 to boiler relay (e.g. NVL_Out.boiler_status.relay_output or a GVL BOOL). and Ch15 to boiler relay (e.g. NVL_Out.boiler_status.relay_output or a GVL BOOL).
Optional: DI_Emergency_Stop (physical E-Stop input). Optional: DI_Emergency_Stop (physical E-Stop input).
*) *)
PROGRAM PLC_App PROGRAM PLC_App
VAR VAR
masterBedroom: fb_room; open_plan_living_room: fb_room;
masterBathroom: fb_room; open_plan_dining_room: fb_room;
bedroom_1: fb_room; open_plan_entrance: fb_room;
bedroom_2: fb_room; open_plan_guest_wc: fb_room;
bathroom: fb_room; kitchen_kitchen: fb_room;
guest_wc: fb_room; kitchen_pantry: fb_room;
kitchen: fb_room; bedrooms_office: fb_room;
pantry: fb_room; bedrooms_hallway: fb_room;
livingRoom: fb_room; bedrooms_laundry: fb_room;
diningRoom: fb_room; bedrooms_shower: fb_room;
entrance: fb_room; bedrooms_bedroom: fb_room;
hallway: fb_room; master_bedroom_suite: fb_room;
veranda: fb_room; master_bedroom_bathroom: fb_room;
front: fb_room; exterior_veranda: fb_room;
back: fb_room; exterior_entrance: fb_room;
side: fb_room; exterior_yard: fb_room;
boiler: fb_boiler; boiler: fb_boiler;
END_VAR END_VAR
// ========== SECTION 1: LIGHTING (Option C: relay feedback = copy of output) ========== // ========== SECTION 1: LIGHTING (Option C: relay feedback = copy of output) ==========
// Master Bedroom // Open Plan - Living Room
masterBedroom(switches := NVL_In.masterBedroom, relay_status := EtherCAT_RelayFeedback.masterBedroom); open_plan_living_room(switches := NVL_In.open_plan_living_room, relay_status := EtherCAT_RelayFeedback.open_plan_living_room);
EtherCAT_RelayFeedback.masterBedroom := masterBedroom.lights; EtherCAT_RelayFeedback.open_plan_living_room := open_plan_living_room.lights;
NVL_Out.l_masterBedroom := masterBedroom.lights; NVL_Out.l_open_plan_living_room := open_plan_living_room.lights;
// Master Bathroom // Open Plan - Dining Room
masterBathroom(switches := NVL_In.masterBathroom, relay_status := EtherCAT_RelayFeedback.masterBathroom); open_plan_dining_room(switches := NVL_In.open_plan_dining_room, relay_status := EtherCAT_RelayFeedback.open_plan_dining_room);
EtherCAT_RelayFeedback.masterBathroom := masterBathroom.lights; EtherCAT_RelayFeedback.open_plan_dining_room := open_plan_dining_room.lights;
NVL_Out.l_masterBathroom := masterBathroom.lights; NVL_Out.l_open_plan_dining_room := open_plan_dining_room.lights;
// Bedroom 1 // Open Plan - Entrance
bedroom_1(switches := NVL_In.bedroom_1, relay_status := EtherCAT_RelayFeedback.bedroom_1); open_plan_entrance(switches := NVL_In.open_plan_entrance, relay_status := EtherCAT_RelayFeedback.open_plan_entrance);
EtherCAT_RelayFeedback.bedroom_1 := bedroom_1.lights; EtherCAT_RelayFeedback.open_plan_entrance := open_plan_entrance.lights;
NVL_Out.l_bedroom_1 := bedroom_1.lights; NVL_Out.l_open_plan_entrance := open_plan_entrance.lights;
// Bedroom 2 // Open Plan - Guest WC
bedroom_2(switches := NVL_In.bedroom_2, relay_status := EtherCAT_RelayFeedback.bedroom_2); open_plan_guest_wc(switches := NVL_In.open_plan_guest_wc, relay_status := EtherCAT_RelayFeedback.open_plan_guest_wc);
EtherCAT_RelayFeedback.bedroom_2 := bedroom_2.lights; EtherCAT_RelayFeedback.open_plan_guest_wc := open_plan_guest_wc.lights;
NVL_Out.l_bedroom_2 := bedroom_2.lights; NVL_Out.l_open_plan_guest_wc := open_plan_guest_wc.lights;
// Bathroom
bathroom(switches := NVL_In.bathroom, relay_status := EtherCAT_RelayFeedback.bathroom);
EtherCAT_RelayFeedback.bathroom := bathroom.lights;
NVL_Out.l_bathroom := bathroom.lights;
// Guest WC
guest_wc(switches := NVL_In.guestWc, relay_status := EtherCAT_RelayFeedback.guest_wc);
EtherCAT_RelayFeedback.guest_wc := guest_wc.lights;
NVL_Out.l_guestWc := guest_wc.lights;
// Kitchen // Kitchen
kitchen(switches := NVL_In.kitchen, relay_status := EtherCAT_RelayFeedback.kitchen); kitchen_kitchen(switches := NVL_In.kitchen_kitchen, relay_status := EtherCAT_RelayFeedback.kitchen_kitchen);
EtherCAT_RelayFeedback.kitchen := kitchen.lights; EtherCAT_RelayFeedback.kitchen_kitchen := kitchen_kitchen.lights;
NVL_Out.l_kitchen := kitchen.lights; NVL_Out.l_kitchen_kitchen := kitchen_kitchen.lights;
// Pantry // Pantry
pantry(switches := NVL_In.pantry, relay_status := EtherCAT_RelayFeedback.pantry); kitchen_pantry(switches := NVL_In.kitchen_pantry, relay_status := EtherCAT_RelayFeedback.kitchen_pantry);
EtherCAT_RelayFeedback.pantry := pantry.lights; EtherCAT_RelayFeedback.kitchen_pantry := kitchen_pantry.lights;
NVL_Out.l_pantry := pantry.lights; NVL_Out.l_kitchen_pantry := kitchen_pantry.lights;
// Living Room // Bedrooms - Office
livingRoom(switches := NVL_In.livingRoom, relay_status := EtherCAT_RelayFeedback.livingRoom); bedrooms_office(switches := NVL_In.bedrooms_office, relay_status := EtherCAT_RelayFeedback.bedrooms_office);
EtherCAT_RelayFeedback.livingRoom := livingRoom.lights; EtherCAT_RelayFeedback.bedrooms_office := bedrooms_office.lights;
NVL_Out.l_livingRoom := livingRoom.lights; NVL_Out.l_bedrooms_office := bedrooms_office.lights;
// Dining Room // Bedrooms - Hallway
diningRoom(switches := NVL_In.dinningRoom, relay_status := EtherCAT_RelayFeedback.diningRoom); bedrooms_hallway(switches := NVL_In.bedrooms_hallway, relay_status := EtherCAT_RelayFeedback.bedrooms_hallway);
EtherCAT_RelayFeedback.diningRoom := diningRoom.lights; EtherCAT_RelayFeedback.bedrooms_hallway := bedrooms_hallway.lights;
NVL_Out.l_dinningRoom := diningRoom.lights; NVL_Out.l_bedrooms_hallway := bedrooms_hallway.lights;
// Entrance // Bedrooms - Laundry
entrance(switches := NVL_In.entrance, relay_status := EtherCAT_RelayFeedback.entrance); bedrooms_laundry(switches := NVL_In.bedrooms_laundry, relay_status := EtherCAT_RelayFeedback.bedrooms_laundry);
EtherCAT_RelayFeedback.entrance := entrance.lights; EtherCAT_RelayFeedback.bedrooms_laundry := bedrooms_laundry.lights;
NVL_Out.l_entrance := entrance.lights; NVL_Out.l_bedrooms_laundry := bedrooms_laundry.lights;
// Hallway // Bedrooms - Shower
hallway(switches := NVL_In.hallway, relay_status := EtherCAT_RelayFeedback.hallway); bedrooms_shower(switches := NVL_In.bedrooms_shower, relay_status := EtherCAT_RelayFeedback.bedrooms_shower);
EtherCAT_RelayFeedback.hallway := hallway.lights; EtherCAT_RelayFeedback.bedrooms_shower := bedrooms_shower.lights;
NVL_Out.l_hallway := hallway.lights; NVL_Out.l_bedrooms_shower := bedrooms_shower.lights;
// Veranda // Bedrooms - Bedroom
veranda(switches := NVL_In.outVeranda, relay_status := EtherCAT_RelayFeedback.veranda); bedrooms_bedroom(switches := NVL_In.bedrooms_bedroom, relay_status := EtherCAT_RelayFeedback.bedrooms_bedroom);
EtherCAT_RelayFeedback.veranda := veranda.lights; EtherCAT_RelayFeedback.bedrooms_bedroom := bedrooms_bedroom.lights;
NVL_Out.l_outVeranda := veranda.lights; NVL_Out.l_bedrooms_bedroom := bedrooms_bedroom.lights;
// Front // Master Bedroom - Suite
front(switches := NVL_In.outFront, relay_status := EtherCAT_RelayFeedback.front); master_bedroom_suite(switches := NVL_In.master_bedroom_suite, relay_status := EtherCAT_RelayFeedback.master_bedroom_suite);
EtherCAT_RelayFeedback.front := front.lights; EtherCAT_RelayFeedback.master_bedroom_suite := master_bedroom_suite.lights;
NVL_Out.l_outFront := front.lights; NVL_Out.l_master_bedroom_suite := master_bedroom_suite.lights;
// Back // Master Bedroom - Bathroom
back(switches := NVL_In.outBack, relay_status := EtherCAT_RelayFeedback.back); master_bedroom_bathroom(switches := NVL_In.master_bedroom_bathroom, relay_status := EtherCAT_RelayFeedback.master_bedroom_bathroom);
EtherCAT_RelayFeedback.back := back.lights; EtherCAT_RelayFeedback.master_bedroom_bathroom := master_bedroom_bathroom.lights;
NVL_Out.l_outBack := back.lights; NVL_Out.l_master_bedroom_bathroom := master_bedroom_bathroom.lights;
// Side // Exterior - Veranda
side(switches := NVL_In.outSide, relay_status := EtherCAT_RelayFeedback.side); exterior_veranda(switches := NVL_In.exterior_veranda, relay_status := EtherCAT_RelayFeedback.exterior_veranda);
EtherCAT_RelayFeedback.side := side.lights; EtherCAT_RelayFeedback.exterior_veranda := exterior_veranda.lights;
NVL_Out.l_outSide := side.lights; NVL_Out.l_exterior_veranda := exterior_veranda.lights;
// Exterior - Entrance
exterior_entrance(switches := NVL_In.exterior_entrance, relay_status := EtherCAT_RelayFeedback.exterior_entrance);
EtherCAT_RelayFeedback.exterior_entrance := exterior_entrance.lights;
NVL_Out.l_exterior_entrance := exterior_entrance.lights;
// Exterior - Yard
exterior_yard(switches := NVL_In.exterior_yard, relay_status := EtherCAT_RelayFeedback.exterior_yard);
EtherCAT_RelayFeedback.exterior_yard := exterior_yard.lights;
NVL_Out.l_exterior_yard := exterior_yard.lights;
// ========== SECTION 2: BOILER ========== // ========== SECTION 2: BOILER ==========

View File

@@ -0,0 +1,42 @@
#,Zone,Area,Light
1,L1,Open Plan,Living Room Main
2,L1,Open Plan,Living Room Spots
3,L1,Open Plan,Dining room Main
4,L1,Open Plan,Dining room Spots
5,L1,Open Plan,Entrance Mirror
6,L1,Open Plan,Entrance Main
7,L1,Open Plan,Guest WC Main
8,L1,Open Plan,Guiest WC Strip
9,L1,Open Plan,Guest WC Fan
10,L1,Open Plan,Living Room Strip
11,L1,Open Plan,Living Room Strip
12,L2,Ktchen,Kitchen Main
13,L2,Ktchen,Island
14,L2,Ktchen,Kitchen Cabinets
15,L2,Ktchen,Fridge
16,L2,Ktchen,Pantry
17,L3,Bedrooms,Office Main
18,L3,Bedrooms,Office Strip
19,L3,Bedrooms,Hallway
20,L3,Bedrooms,Wachine Machine
21,L3,Bedrooms,Shower spots
22,L3,Bedrooms,Shower fan
23,L3,Bedrooms,Bedroom Main
24,L3,Bedrooms,Bedroom Spots
25,L4,Master Bedroom,Main
26,L4,Master Bedroom,Spots
27,L4,Master Bedroom,Strip
28,L4,Master Bedroom,Door
29,L4,Master Bedroom,Dresser
30,L4,Master Bedroom,bathroom spots
31,L4,Master Bedroom,bathroom fan
32,L5,Exterior,Veranda
33,L5,Exterior,BBQ
34,L5,Exterior,Entrance Door
35,L5,Exterior,Front Lights
36,L5,Exterior,backyard flood light 1
37,L5,Exterior,backyard flood light 2
38,L5,Exterior,Master Bedroom flood light
39,L5,exterior,Driveway
40,L5,,
41,L5,,
1 # Zone Area Light
2 1 L1 Open Plan Living Room Main
3 2 L1 Open Plan Living Room Spots
4 3 L1 Open Plan Dining room Main
5 4 L1 Open Plan Dining room Spots
6 5 L1 Open Plan Entrance Mirror
7 6 L1 Open Plan Entrance Main
8 7 L1 Open Plan Guest WC Main
9 8 L1 Open Plan Guiest WC Strip
10 9 L1 Open Plan Guest WC Fan
11 10 L1 Open Plan Living Room Strip
12 11 L1 Open Plan Living Room Strip
13 12 L2 Ktchen Kitchen Main
14 13 L2 Ktchen Island
15 14 L2 Ktchen Kitchen Cabinets
16 15 L2 Ktchen Fridge
17 16 L2 Ktchen Pantry
18 17 L3 Bedrooms Office Main
19 18 L3 Bedrooms Office Strip
20 19 L3 Bedrooms Hallway
21 20 L3 Bedrooms Wachine Machine
22 21 L3 Bedrooms Shower spots
23 22 L3 Bedrooms Shower fan
24 23 L3 Bedrooms Bedroom Main
25 24 L3 Bedrooms Bedroom Spots
26 25 L4 Master Bedroom Main
27 26 L4 Master Bedroom Spots
28 27 L4 Master Bedroom Strip
29 28 L4 Master Bedroom Door
30 29 L4 Master Bedroom Dresser
31 30 L4 Master Bedroom bathroom spots
32 31 L4 Master Bedroom bathroom fan
33 32 L5 Exterior Veranda
34 33 L5 Exterior BBQ
35 34 L5 Exterior Entrance Door
36 35 L5 Exterior Front Lights
37 36 L5 Exterior backyard flood light 1
38 37 L5 Exterior backyard flood light 2
39 38 L5 Exterior Master Bedroom flood light
40 39 L5 exterior Driveway
41 40 L5
42 41 L5

View File

@@ -0,0 +1,40 @@
circuit_no,zone,area,room,light_type,index,light_no,codesys_in_key,codesys_out_key,nodered_room_key,ha_entity_id,source_light_label
1,l1,open_plan,living_room,main,1,1,open_plan_living_room,l_open_plan_living_room,open_plan_living_room,input_boolean.open_plan_living_room_main_1,Living Room Main
2,l1,open_plan,living_room,spots,1,2,open_plan_living_room,l_open_plan_living_room,open_plan_living_room,input_boolean.open_plan_living_room_spots_1,Living Room Spots
3,l1,open_plan,dining_room,main,1,1,open_plan_dining_room,l_open_plan_dining_room,open_plan_dining_room,input_boolean.open_plan_dining_room_main_1,Dining room Main
4,l1,open_plan,dining_room,spots,1,2,open_plan_dining_room,l_open_plan_dining_room,open_plan_dining_room,input_boolean.open_plan_dining_room_spots_1,Dining room Spots
5,l1,open_plan,entrance,mirror,1,1,open_plan_entrance,l_open_plan_entrance,open_plan_entrance,input_boolean.open_plan_entrance_mirror_1,Entrance Mirror
6,l1,open_plan,entrance,main,1,2,open_plan_entrance,l_open_plan_entrance,open_plan_entrance,input_boolean.open_plan_entrance_main_1,Entrance Main
7,l1,open_plan,guest_wc,main,1,1,open_plan_guest_wc,l_open_plan_guest_wc,open_plan_guest_wc,input_boolean.open_plan_guest_wc_main_1,Guest WC Main
8,l1,open_plan,guest_wc,strip,1,2,open_plan_guest_wc,l_open_plan_guest_wc,open_plan_guest_wc,input_boolean.open_plan_guest_wc_strip_1,Guiest WC Strip
9,l1,open_plan,guest_wc,fan,1,3,open_plan_guest_wc,l_open_plan_guest_wc,open_plan_guest_wc,input_boolean.open_plan_guest_wc_fan_1,Guest WC Fan
10,l1,open_plan,living_room,strip,1,3,open_plan_living_room,l_open_plan_living_room,open_plan_living_room,input_boolean.open_plan_living_room_strip_1,Living Room Strip
11,l1,open_plan,living_room,strip,2,4,open_plan_living_room,l_open_plan_living_room,open_plan_living_room,input_boolean.open_plan_living_room_strip_2,Living Room Strip
12,l2,kitchen,kitchen,main,1,1,kitchen_kitchen,l_kitchen_kitchen,kitchen_kitchen,input_boolean.kitchen_kitchen_main_1,Kitchen Main
13,l2,kitchen,kitchen,island,1,2,kitchen_kitchen,l_kitchen_kitchen,kitchen_kitchen,input_boolean.kitchen_kitchen_island_1,Island
14,l2,kitchen,kitchen,cabinets,1,3,kitchen_kitchen,l_kitchen_kitchen,kitchen_kitchen,input_boolean.kitchen_kitchen_cabinets_1,Kitchen Cabinets
15,l2,kitchen,kitchen,fridge,1,4,kitchen_kitchen,l_kitchen_kitchen,kitchen_kitchen,input_boolean.kitchen_kitchen_fridge_1,Fridge
16,l2,kitchen,pantry,main,1,1,kitchen_pantry,l_kitchen_pantry,kitchen_pantry,input_boolean.kitchen_pantry_main_1,Pantry
17,l3,bedrooms,office,main,1,1,bedrooms_office,l_bedrooms_office,bedrooms_office,input_boolean.bedrooms_office_main_1,Office Main
18,l3,bedrooms,office,strip,1,2,bedrooms_office,l_bedrooms_office,bedrooms_office,input_boolean.bedrooms_office_strip_1,Office Strip
19,l3,bedrooms,hallway,main,1,1,bedrooms_hallway,l_bedrooms_hallway,bedrooms_hallway,input_boolean.bedrooms_hallway_main_1,Hallway
20,l3,bedrooms,laundry,main,1,1,bedrooms_laundry,l_bedrooms_laundry,bedrooms_laundry,input_boolean.bedrooms_laundry_main_1,Wachine Machine
21,l3,bedrooms,shower,spots,1,1,bedrooms_shower,l_bedrooms_shower,bedrooms_shower,input_boolean.bedrooms_shower_spots_1,Shower spots
22,l3,bedrooms,shower,fan,1,2,bedrooms_shower,l_bedrooms_shower,bedrooms_shower,input_boolean.bedrooms_shower_fan_1,Shower fan
23,l3,bedrooms,bedroom,main,1,1,bedrooms_bedroom,l_bedrooms_bedroom,bedrooms_bedroom,input_boolean.bedrooms_bedroom_main_1,Bedroom Main
24,l3,bedrooms,bedroom,spots,1,2,bedrooms_bedroom,l_bedrooms_bedroom,bedrooms_bedroom,input_boolean.bedrooms_bedroom_spots_1,Bedroom Spots
25,l4,master_bedroom,suite,main,1,1,master_bedroom_suite,l_master_bedroom_suite,master_bedroom_suite,input_boolean.master_bedroom_suite_main_1,Main
26,l4,master_bedroom,suite,spots,1,2,master_bedroom_suite,l_master_bedroom_suite,master_bedroom_suite,input_boolean.master_bedroom_suite_spots_1,Spots
27,l4,master_bedroom,suite,strip,1,3,master_bedroom_suite,l_master_bedroom_suite,master_bedroom_suite,input_boolean.master_bedroom_suite_strip_1,Strip
28,l4,master_bedroom,suite,door,1,4,master_bedroom_suite,l_master_bedroom_suite,master_bedroom_suite,input_boolean.master_bedroom_suite_door_1,Door
29,l4,master_bedroom,suite,dresser,1,5,master_bedroom_suite,l_master_bedroom_suite,master_bedroom_suite,input_boolean.master_bedroom_suite_dresser_1,Dresser
30,l4,master_bedroom,bathroom,spots,1,1,master_bedroom_bathroom,l_master_bedroom_bathroom,master_bedroom_bathroom,input_boolean.master_bedroom_bathroom_spots_1,bathroom spots
31,l4,master_bedroom,bathroom,fan,1,2,master_bedroom_bathroom,l_master_bedroom_bathroom,master_bedroom_bathroom,input_boolean.master_bedroom_bathroom_fan_1,bathroom fan
32,l5,exterior,veranda,main,1,1,exterior_veranda,l_exterior_veranda,exterior_veranda,input_boolean.exterior_veranda_main_1,Veranda
33,l5,exterior,yard,bbq,1,1,exterior_yard,l_exterior_yard,exterior_yard,input_boolean.exterior_yard_bbq_1,BBQ
34,l5,exterior,entrance,door,1,1,exterior_entrance,l_exterior_entrance,exterior_entrance,input_boolean.exterior_entrance_door_1,Entrance Door
35,l5,exterior,yard,front_lights,1,2,exterior_yard,l_exterior_yard,exterior_yard,input_boolean.exterior_yard_front_lights_1,Front Lights
36,l5,exterior,yard,backyard_flood_light,1,3,exterior_yard,l_exterior_yard,exterior_yard,input_boolean.exterior_yard_backyard_flood_light_1,backyard flood light 1
37,l5,exterior,yard,backyard_flood_light,2,4,exterior_yard,l_exterior_yard,exterior_yard,input_boolean.exterior_yard_backyard_flood_light_2,backyard flood light 2
38,l5,exterior,yard,master_bedroom_flood_light,1,5,exterior_yard,l_exterior_yard,exterior_yard,input_boolean.exterior_yard_master_bedroom_flood_light_1,Master Bedroom flood light
39,l5,exterior,yard,driveway,1,6,exterior_yard,l_exterior_yard,exterior_yard,input_boolean.exterior_yard_driveway_1,Driveway
1 circuit_no zone area room light_type index light_no codesys_in_key codesys_out_key nodered_room_key ha_entity_id source_light_label
2 1 l1 open_plan living_room main 1 1 open_plan_living_room l_open_plan_living_room open_plan_living_room input_boolean.open_plan_living_room_main_1 Living Room Main
3 2 l1 open_plan living_room spots 1 2 open_plan_living_room l_open_plan_living_room open_plan_living_room input_boolean.open_plan_living_room_spots_1 Living Room Spots
4 3 l1 open_plan dining_room main 1 1 open_plan_dining_room l_open_plan_dining_room open_plan_dining_room input_boolean.open_plan_dining_room_main_1 Dining room Main
5 4 l1 open_plan dining_room spots 1 2 open_plan_dining_room l_open_plan_dining_room open_plan_dining_room input_boolean.open_plan_dining_room_spots_1 Dining room Spots
6 5 l1 open_plan entrance mirror 1 1 open_plan_entrance l_open_plan_entrance open_plan_entrance input_boolean.open_plan_entrance_mirror_1 Entrance Mirror
7 6 l1 open_plan entrance main 1 2 open_plan_entrance l_open_plan_entrance open_plan_entrance input_boolean.open_plan_entrance_main_1 Entrance Main
8 7 l1 open_plan guest_wc main 1 1 open_plan_guest_wc l_open_plan_guest_wc open_plan_guest_wc input_boolean.open_plan_guest_wc_main_1 Guest WC Main
9 8 l1 open_plan guest_wc strip 1 2 open_plan_guest_wc l_open_plan_guest_wc open_plan_guest_wc input_boolean.open_plan_guest_wc_strip_1 Guiest WC Strip
10 9 l1 open_plan guest_wc fan 1 3 open_plan_guest_wc l_open_plan_guest_wc open_plan_guest_wc input_boolean.open_plan_guest_wc_fan_1 Guest WC Fan
11 10 l1 open_plan living_room strip 1 3 open_plan_living_room l_open_plan_living_room open_plan_living_room input_boolean.open_plan_living_room_strip_1 Living Room Strip
12 11 l1 open_plan living_room strip 2 4 open_plan_living_room l_open_plan_living_room open_plan_living_room input_boolean.open_plan_living_room_strip_2 Living Room Strip
13 12 l2 kitchen kitchen main 1 1 kitchen_kitchen l_kitchen_kitchen kitchen_kitchen input_boolean.kitchen_kitchen_main_1 Kitchen Main
14 13 l2 kitchen kitchen island 1 2 kitchen_kitchen l_kitchen_kitchen kitchen_kitchen input_boolean.kitchen_kitchen_island_1 Island
15 14 l2 kitchen kitchen cabinets 1 3 kitchen_kitchen l_kitchen_kitchen kitchen_kitchen input_boolean.kitchen_kitchen_cabinets_1 Kitchen Cabinets
16 15 l2 kitchen kitchen fridge 1 4 kitchen_kitchen l_kitchen_kitchen kitchen_kitchen input_boolean.kitchen_kitchen_fridge_1 Fridge
17 16 l2 kitchen pantry main 1 1 kitchen_pantry l_kitchen_pantry kitchen_pantry input_boolean.kitchen_pantry_main_1 Pantry
18 17 l3 bedrooms office main 1 1 bedrooms_office l_bedrooms_office bedrooms_office input_boolean.bedrooms_office_main_1 Office Main
19 18 l3 bedrooms office strip 1 2 bedrooms_office l_bedrooms_office bedrooms_office input_boolean.bedrooms_office_strip_1 Office Strip
20 19 l3 bedrooms hallway main 1 1 bedrooms_hallway l_bedrooms_hallway bedrooms_hallway input_boolean.bedrooms_hallway_main_1 Hallway
21 20 l3 bedrooms laundry main 1 1 bedrooms_laundry l_bedrooms_laundry bedrooms_laundry input_boolean.bedrooms_laundry_main_1 Wachine Machine
22 21 l3 bedrooms shower spots 1 1 bedrooms_shower l_bedrooms_shower bedrooms_shower input_boolean.bedrooms_shower_spots_1 Shower spots
23 22 l3 bedrooms shower fan 1 2 bedrooms_shower l_bedrooms_shower bedrooms_shower input_boolean.bedrooms_shower_fan_1 Shower fan
24 23 l3 bedrooms bedroom main 1 1 bedrooms_bedroom l_bedrooms_bedroom bedrooms_bedroom input_boolean.bedrooms_bedroom_main_1 Bedroom Main
25 24 l3 bedrooms bedroom spots 1 2 bedrooms_bedroom l_bedrooms_bedroom bedrooms_bedroom input_boolean.bedrooms_bedroom_spots_1 Bedroom Spots
26 25 l4 master_bedroom suite main 1 1 master_bedroom_suite l_master_bedroom_suite master_bedroom_suite input_boolean.master_bedroom_suite_main_1 Main
27 26 l4 master_bedroom suite spots 1 2 master_bedroom_suite l_master_bedroom_suite master_bedroom_suite input_boolean.master_bedroom_suite_spots_1 Spots
28 27 l4 master_bedroom suite strip 1 3 master_bedroom_suite l_master_bedroom_suite master_bedroom_suite input_boolean.master_bedroom_suite_strip_1 Strip
29 28 l4 master_bedroom suite door 1 4 master_bedroom_suite l_master_bedroom_suite master_bedroom_suite input_boolean.master_bedroom_suite_door_1 Door
30 29 l4 master_bedroom suite dresser 1 5 master_bedroom_suite l_master_bedroom_suite master_bedroom_suite input_boolean.master_bedroom_suite_dresser_1 Dresser
31 30 l4 master_bedroom bathroom spots 1 1 master_bedroom_bathroom l_master_bedroom_bathroom master_bedroom_bathroom input_boolean.master_bedroom_bathroom_spots_1 bathroom spots
32 31 l4 master_bedroom bathroom fan 1 2 master_bedroom_bathroom l_master_bedroom_bathroom master_bedroom_bathroom input_boolean.master_bedroom_bathroom_fan_1 bathroom fan
33 32 l5 exterior veranda main 1 1 exterior_veranda l_exterior_veranda exterior_veranda input_boolean.exterior_veranda_main_1 Veranda
34 33 l5 exterior yard bbq 1 1 exterior_yard l_exterior_yard exterior_yard input_boolean.exterior_yard_bbq_1 BBQ
35 34 l5 exterior entrance door 1 1 exterior_entrance l_exterior_entrance exterior_entrance input_boolean.exterior_entrance_door_1 Entrance Door
36 35 l5 exterior yard front_lights 1 2 exterior_yard l_exterior_yard exterior_yard input_boolean.exterior_yard_front_lights_1 Front Lights
37 36 l5 exterior yard backyard_flood_light 1 3 exterior_yard l_exterior_yard exterior_yard input_boolean.exterior_yard_backyard_flood_light_1 backyard flood light 1
38 37 l5 exterior yard backyard_flood_light 2 4 exterior_yard l_exterior_yard exterior_yard input_boolean.exterior_yard_backyard_flood_light_2 backyard flood light 2
39 38 l5 exterior yard master_bedroom_flood_light 1 5 exterior_yard l_exterior_yard exterior_yard input_boolean.exterior_yard_master_bedroom_flood_light_1 Master Bedroom flood light
40 39 l5 exterior yard driveway 1 6 exterior_yard l_exterior_yard exterior_yard input_boolean.exterior_yard_driveway_1 Driveway

View File

@@ -0,0 +1,40 @@
#,zone,area,light
1,l1,open_plan,living_room_main
2,l1,open_plan,living_room_spots
3,l1,open_plan,dining_room_main
4,l1,open_plan,dining_room_spots
5,l1,open_plan,entrance_mirror
6,l1,open_plan,entrance_main
7,l1,open_plan,guest_wc_main
8,l1,open_plan,guest_wc_strip
9,l1,open_plan,guest_wc_fan
10,l1,open_plan,living_room_strip
11,l1,open_plan,living_room_strip
12,l2,kitchen,kitchen_main
13,l2,kitchen,island
14,l2,kitchen,kitchen_cabinets
15,l2,kitchen,fridge
16,l2,kitchen,pantry
17,l3,bedrooms,office_main
18,l3,bedrooms,office_strip
19,l3,bedrooms,hallway
20,l3,bedrooms,laundry
21,l3,bedrooms,shower_spots
22,l3,bedrooms,shower_fan
23,l3,bedrooms,bedroom_main
24,l3,bedrooms,bedroom_spots
25,l4,master_bedroom,main
26,l4,master_bedroom,spots
27,l4,master_bedroom,strip
28,l4,master_bedroom,door
29,l4,master_bedroom,dresser
30,l4,master_bedroom,bathroom_spots
31,l4,master_bedroom,bathroom_fan
32,l5,exterior,veranda
33,l5,exterior,bbq
34,l5,exterior,entrance_door
35,l5,exterior,front_lights
36,l5,exterior,backyard_flood_light_1
37,l5,exterior,backyard_flood_light_2
38,l5,exterior,master_bedroom_flood_light
39,l5,exterior,driveway
1 # zone area light
2 1 l1 open_plan living_room_main
3 2 l1 open_plan living_room_spots
4 3 l1 open_plan dining_room_main
5 4 l1 open_plan dining_room_spots
6 5 l1 open_plan entrance_mirror
7 6 l1 open_plan entrance_main
8 7 l1 open_plan guest_wc_main
9 8 l1 open_plan guest_wc_strip
10 9 l1 open_plan guest_wc_fan
11 10 l1 open_plan living_room_strip
12 11 l1 open_plan living_room_strip
13 12 l2 kitchen kitchen_main
14 13 l2 kitchen island
15 14 l2 kitchen kitchen_cabinets
16 15 l2 kitchen fridge
17 16 l2 kitchen pantry
18 17 l3 bedrooms office_main
19 18 l3 bedrooms office_strip
20 19 l3 bedrooms hallway
21 20 l3 bedrooms laundry
22 21 l3 bedrooms shower_spots
23 22 l3 bedrooms shower_fan
24 23 l3 bedrooms bedroom_main
25 24 l3 bedrooms bedroom_spots
26 25 l4 master_bedroom main
27 26 l4 master_bedroom spots
28 27 l4 master_bedroom strip
29 28 l4 master_bedroom door
30 29 l4 master_bedroom dresser
31 30 l4 master_bedroom bathroom_spots
32 31 l4 master_bedroom bathroom_fan
33 32 l5 exterior veranda
34 33 l5 exterior bbq
35 34 l5 exterior entrance_door
36 35 l5 exterior front_lights
37 36 l5 exterior backyard_flood_light_1
38 37 l5 exterior backyard_flood_light_2
39 38 l5 exterior master_bedroom_flood_light
40 39 l5 exterior driveway

View File

@@ -0,0 +1,70 @@
# Uniform lighting naming rules
This project uses one canonical naming strategy for CODESYS, Node-RED, and Home Assistant.
## 1) Canonical token format
- All tokens are `snake_case`.
- Allowed chars: `a-z`, `0-9`, `_`.
- Normalize free text by:
- lowercasing
- trimming spaces
- replacing spaces and dashes with `_`
- collapsing repeated `_`
- applying typo fixes (`ktchen -> kitchen`, `guiest -> guest`, `wachine -> laundry`)
## 2) Canonical data columns
Source of truth is `lights_zones_canonical.csv` with:
- `circuit_no`
- `zone`
- `area`
- `room`
- `light_type`
- `index` (duplicate counter for same area+room+light_type)
- `light_no` (PLC light channel inside room, 1..6)
- `codesys_in_key`
- `codesys_out_key`
- `nodered_room_key`
- `ha_entity_id`
## 3) ID generation formulas
- `codesys_in_key` = `<area>_<room>`
- `codesys_out_key` = `l_<area>_<room>`
- `nodered_room_key` = `<area>_<room>`
- `ha_entity_id` = `input_boolean.<area>_<room>_<light_type>_<index>`
Examples:
- `input_boolean.open_plan_living_room_main_1`
- `open_plan_guest_wc`
- `l_master_bedroom_suite`
## 4) PLC mapping rule
- `light_no` maps to CODESYS `l_<N>` and Node-RED `light`:
- `light_no = 1` -> `l_1`
- `light_no = 2` -> `l_2`
- ...
- `light_no = 6` -> `l_6`
## 5) Reserved room keys used in this migration
- `open_plan_living_room`
- `open_plan_dining_room`
- `open_plan_entrance`
- `open_plan_guest_wc`
- `kitchen_kitchen`
- `kitchen_pantry`
- `bedrooms_office`
- `bedrooms_hallway`
- `bedrooms_laundry`
- `bedrooms_shower`
- `bedrooms_bedroom`
- `master_bedroom_suite`
- `master_bedroom_bathroom`
- `exterior_veranda`
- `exterior_entrance`
- `exterior_yard`

View File

@@ -0,0 +1,37 @@
# Validation report (uniform lighting naming migration)
## Static consistency checks completed
- Canonical lighting rows: `39` (`lights_zones_canonical.csv`)
- CODESYS `NVL_In` room structs: `16`
- CODESYS `NVL_Out` room structs: `16`
- Node-RED `roomNames` entries: `16`
- Node-RED `lightEntityMap` entries: `39`
## Mapping status
- `circuit_no -> area/room/type/index/light_no` is defined for all non-empty circuits.
- `codesys_in_key` / `codesys_out_key` are defined for every canonical row.
- `room-config.js` is aligned with canonical keys:
- `roomNames` matches the 16-room CODESYS layout.
- `lightEntityMap` has one entry per canonical row.
- `entityToRoom` base keys map all canonical HA entity patterns.
## Verified constraints
- Canonical naming style: `snake_case`
- Entity ID pattern: `input_boolean.<area>_<room>_<light_type>_<index>`
- CODESYS legacy room names replaced in `codesys/src` runtime files:
- `GVL_NVL_placeholders.gvl`
- `GVL_IO.gvl`
- `PLC_App.st`
## Residual runtime checks to perform on target system
Because this repository environment has no runtime binaries for Node-RED/CODESYS/HA validation, perform these on your deployed setup:
1. Deploy updated CODESYS project and confirm NVL sender/receiver symbol binding still resolves.
2. Load updated `/root/.node-red/room-config.js` and redeploy flows.
3. Import HA helpers from `lights_by_area_room_type_index.yaml`.
4. Test one circuit per area end-to-end:
- HA toggle -> Node-RED -> NVL_In -> PLC output -> NVL_Out -> HA sync.

View File

@@ -10,6 +10,11 @@ To avoid adding a new room or light in several places, use **one config file** t
**Config file:** [`node-red/config_files/room-config.js`](../../node-red/config_files/room-config.js) — exports `ROOM_CONFIG` with: **roomNames** (NVL SEND), **lightEntityMap** (NVL to HA Sync), **entityToRoom** (HA to NVL), **deviceToRoom** (Zigbee to NVL). **Config file:** [`node-red/config_files/room-config.js`](../../node-red/config_files/room-config.js) — exports `ROOM_CONFIG` with: **roomNames** (NVL SEND), **lightEntityMap** (NVL to HA Sync), **entityToRoom** (HA to NVL), **deviceToRoom** (Zigbee to NVL).
Canonical source-of-truth for this migration:
- Electrical mapping: [`../Electrical/lights_zones_canonical.csv`](../Electrical/lights_zones_canonical.csv)
- Naming rules: [`../Electrical/naming_rules.md`](../Electrical/naming_rules.md)
**Server location:** `/root/.node-red/room-config.js` (uploaded via `scp`). **Server location:** `/root/.node-red/room-config.js` (uploaded via `scp`).
**Loader:** [`node-red/room-config-loader.js`](../../node-red/room-config-loader.js) — paste this code into a **Function node** named "Load room config". Connect an **Inject node** (once after 0.5 s) to it and deploy. It `require()`s the config file, clears the cache (so edits are picked up on redeploy), and sets `global.set('roomConfig', ...)`. **Loader:** [`node-red/room-config-loader.js`](../../node-red/room-config-loader.js) — paste this code into a **Function node** named "Load room config". Connect an **Inject node** (once after 0.5 s) to it and deploy. It `require()`s the config file, clears the cache (so edits are picked up on redeploy), and sets `global.set('roomConfig', ...)`.
@@ -39,14 +44,14 @@ Use a single list of room keys everywhere. Example (match your CODESYS NVL order
| Room key (Node-RED / NVL) | PLC NVL_Out (receive) | Lights per room | | Room key (Node-RED / NVL) | PLC NVL_Out (receive) | Lights per room |
|---------------------------|------------------------|-----------------| |---------------------------|------------------------|-----------------|
| `livingRoom` | `l_livingRoom` | 1..6 | | `open_plan_living_room` | `l_open_plan_living_room` | 1..6 |
| `masterBedroom` | `l_masterBedroom` | 1..6 | | `open_plan_guest_wc` | `l_open_plan_guest_wc` | 1..6 |
| `kitchen` | `l_kitchen` | 1..6 | | `kitchen_kitchen` | `l_kitchen_kitchen` | 1..6 |
| `bathroom` | `l_bathroom` | 1..6 | | `master_bedroom_suite` | `l_master_bedroom_suite` | 1..6 |
| … | … | 1..6 | | … | … | 1..6 |
- **NVL send (to PLC):** same keys as NVL_In in CODESYS (e.g. `livingRoom`, `masterBedroom`, … or `cmd_livingroom` for the test slot). Order and names must match the PLC. - **NVL send (to PLC):** same keys as NVL_In in CODESYS (e.g. `open_plan_living_room`, `master_bedroom_suite`). Order and names must match the PLC.
- **NVL receive (from PLC):** keys in the nvl-receive output (e.g. `l_livingRoom`, `light_livingRoom`) — use the same key in **LIGHT_ENTITY_MAP** in the sync function. - **NVL receive (from PLC):** keys in the nvl-receive output (e.g. `l_open_plan_living_room`) — use the same key in **LIGHT_ENTITY_MAP** in the sync function.
Keep one list (e.g. in a comment or config file) and use it in: Keep one list (e.g. in a comment or config file) and use it in:
- **state-to-nvl-send-payload.js** → `roomNames` - **state-to-nvl-send-payload.js** → `roomNames`
@@ -254,9 +259,9 @@ Add or remove lines to match your rooms and light counts. Entity IDs become `inp
Use a **consistent pattern** so you can derive room + light in Node-RED and in YAML: Use a **consistent pattern** so you can derive room + light in Node-RED and in YAML:
- **Entity ID:** `input_boolean.<room>_<light>` - **Entity ID:** `input_boolean.<area>_<room>_<light_type>_<index>`
Examples: `living_room_1`, `kitchen_2`, `master_bedroom_1`. Examples: `input_boolean.open_plan_living_room_main_1`, `input_boolean.kitchen_kitchen_island_1`, `input_boolean.exterior_yard_driveway_1`.
- Then in HA to NVL you can parse: room from the first part, light from the trailing number. - In HA to NVL, parse room mapping from `entityToRoom` using the base without the trailing `_<index>`.
--- ---

View File

@@ -2,6 +2,15 @@
This guide covers how to create the light/switch entities that Node-RED and the PLC use, and how to assign them to **rooms** (HA **Areas**) so you can manage and display them by room. This guide covers how to create the light/switch entities that Node-RED and the PLC use, and how to assign them to **rooms** (HA **Areas**) so you can manage and display them by room.
Canonical naming in this project is now:
- `input_boolean.<area>_<room>_<light_type>_<index>`
- Example: `input_boolean.open_plan_living_room_main_1`
Pre-generated helper YAML for the current electrical plan:
- [`lights_by_area_room_type_index.yaml`](lights_by_area_room_type_index.yaml)
--- ---
## 1. Concepts ## 1. Concepts
@@ -41,18 +50,13 @@ Create one file per room (or one file with sections) so entities are grouped by
```yaml ```yaml
# PLC/Node-RED lights entity_id must match room-config.js (entityToRoom, lightEntityMap) # PLC/Node-RED lights entity_id must match room-config.js (entityToRoom, lightEntityMap)
# Naming: <room>_<light_num> e.g. living_room_1, kitchen_2 # Naming: <area>_<room>_<light_type>_<index> e.g. open_plan_living_room_main_1
input_boolean: input_boolean:
# Living room open_plan_living_room_main_1: { name: Open Plan Living Room Main 1 }
living_room_1: { name: Living Room 1 } open_plan_living_room_spots_1: { name: Open Plan Living Room Spots 1 }
living_room_2: { name: Living Room 2 } kitchen_kitchen_main_1: { name: Kitchen Main 1 }
# Kitchen bedrooms_hallway_main_1: { name: Bedrooms Hallway Main 1 }
kitchen_1: { name: Kitchen 1 }
kitchen_2: { name: Kitchen 2 }
# Hallway
hallway_1: { name: Hallway 1 }
# Add more: master_bedroom_1, bathroom_1, entrance_1, etc.
``` ```
Ensure `configuration.yaml` has: Ensure `configuration.yaml` has:
@@ -62,7 +66,7 @@ homeassistant:
packages: !include_dir_named packages packages: !include_dir_named packages
``` ```
Restart Home Assistant. All entities are created. Entity IDs will be `input_boolean.living_room_1`, etc. Restart Home Assistant. All entities are created. Entity IDs will be `input_boolean.open_plan_living_room_main_1`, etc.
### Option B: UI (one by one) ### Option B: UI (one by one)
@@ -99,9 +103,9 @@ Use the **same entity_id and room logic** in both places.
**Naming convention that works well:** **Naming convention that works well:**
- Entity ID: `input_boolean.<room>_<number>` - Entity ID: `input_boolean.<area>_<room>_<light_type>_<index>`
Examples: `living_room_1`, `kitchen_2`, `hallway_1`. Examples: `open_plan_living_room_main_1`, `kitchen_kitchen_island_1`, `exterior_yard_driveway_1`.
- In **entityToRoom** use the part without the number: `living_room`, `kitchen`, `hallway` (and any alias like `living_room_new` `cmd_livingroom`). - In **entityToRoom** use the part without trailing `_<index>`, e.g. `open_plan_living_room_main` or `exterior_yard_driveway`.
When you add a new light in HA (new entity_id), add or update: When you add a new light in HA (new entity_id), add or update:

View File

@@ -0,0 +1,47 @@
# Home Assistant helpers for the canonical lighting naming model.
# Naming: input_boolean.<area>_<room>_<light_type>_<index>
input_boolean:
open_plan_living_room_main_1: { name: Open Plan Living Room Main 1 }
open_plan_living_room_spots_1: { name: Open Plan Living Room Spots 1 }
open_plan_dining_room_main_1: { name: Open Plan Dining Room Main 1 }
open_plan_dining_room_spots_1: { name: Open Plan Dining Room Spots 1 }
open_plan_entrance_mirror_1: { name: Open Plan Entrance Mirror 1 }
open_plan_entrance_main_1: { name: Open Plan Entrance Main 1 }
open_plan_guest_wc_main_1: { name: Open Plan Guest WC Main 1 }
open_plan_guest_wc_strip_1: { name: Open Plan Guest WC Strip 1 }
open_plan_guest_wc_fan_1: { name: Open Plan Guest WC Fan 1 }
open_plan_living_room_strip_1: { name: Open Plan Living Room Strip 1 }
open_plan_living_room_strip_2: { name: Open Plan Living Room Strip 2 }
kitchen_kitchen_main_1: { name: Kitchen Main 1 }
kitchen_kitchen_island_1: { name: Kitchen Island 1 }
kitchen_kitchen_cabinets_1: { name: Kitchen Cabinets 1 }
kitchen_kitchen_fridge_1: { name: Kitchen Fridge 1 }
kitchen_pantry_main_1: { name: Kitchen Pantry Main 1 }
bedrooms_office_main_1: { name: Bedrooms Office Main 1 }
bedrooms_office_strip_1: { name: Bedrooms Office Strip 1 }
bedrooms_hallway_main_1: { name: Bedrooms Hallway Main 1 }
bedrooms_laundry_main_1: { name: Bedrooms Laundry Main 1 }
bedrooms_shower_spots_1: { name: Bedrooms Shower Spots 1 }
bedrooms_shower_fan_1: { name: Bedrooms Shower Fan 1 }
bedrooms_bedroom_main_1: { name: Bedrooms Bedroom Main 1 }
bedrooms_bedroom_spots_1: { name: Bedrooms Bedroom Spots 1 }
master_bedroom_suite_main_1: { name: Master Bedroom Suite Main 1 }
master_bedroom_suite_spots_1: { name: Master Bedroom Suite Spots 1 }
master_bedroom_suite_strip_1: { name: Master Bedroom Suite Strip 1 }
master_bedroom_suite_door_1: { name: Master Bedroom Suite Door 1 }
master_bedroom_suite_dresser_1: { name: Master Bedroom Suite Dresser 1 }
master_bedroom_bathroom_spots_1: { name: Master Bedroom Bathroom Spots 1 }
master_bedroom_bathroom_fan_1: { name: Master Bedroom Bathroom Fan 1 }
exterior_veranda_main_1: { name: Exterior Veranda Main 1 }
exterior_entrance_door_1: { name: Exterior Entrance Door 1 }
exterior_yard_bbq_1: { name: Exterior Yard BBQ 1 }
exterior_yard_front_lights_1: { name: Exterior Yard Front Lights 1 }
exterior_yard_backyard_flood_light_1: { name: Exterior Yard Backyard Flood Light 1 }
exterior_yard_backyard_flood_light_2: { name: Exterior Yard Backyard Flood Light 2 }
exterior_yard_master_bedroom_flood_light_1: { name: Exterior Yard Master Bedroom Flood Light 1 }
exterior_yard_driveway_1: { name: Exterior Yard Driveway 1 }

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
ccc/** /**
* Single source of truth for rooms and lights. * Single source of truth for rooms and lights.
* Lives on the Node-RED server at /root/.node-red/room-config.js * Lives on the Node-RED server at /root/.node-red/room-config.js
* All function nodes use: global.get('roomConfig') * All function nodes use: global.get('roomConfig')
@@ -9,56 +9,111 @@ ccc/**
const ROOM_CONFIG = { const ROOM_CONFIG = {
// Order must match CODESYS NVL_In. Used by NVL SEND (state-to-nvl-send-payload). // Order must match CODESYS NVL_In. Used by NVL SEND (state-to-nvl-send-payload).
roomNames: [ roomNames: [
'cmd_livingroom', 'open_plan_living_room',
'cmd_out', // add other NVL room keys as needed 'open_plan_dining_room',
// 'masterBedroom', 'open_plan_entrance',
// 'masterBathroom', 'open_plan_guest_wc',
// 'bedroom_1', 'kitchen_kitchen',
// 'bedroom_2', 'kitchen_pantry',
// 'bathroom', 'bedrooms_office',
// 'guestWc', 'bedrooms_hallway',
// 'kitchen', 'bedrooms_laundry',
// 'pantry', 'bedrooms_shower',
// 'livingRoom', 'bedrooms_bedroom',
// 'dinningRoom', 'master_bedroom_suite',
// 'entrance', 'master_bedroom_bathroom',
// 'hallway', 'exterior_veranda',
// 'outVeranda', 'exterior_entrance',
// 'outFront', 'exterior_yard',
// 'outBack',
// 'outSide',
], ],
// PLC → HA sync. room = key in nvl-receive payload, light = 1..6, entityId = HA entity. // PLC → HA sync. room = key in nvl-receive payload, light = 1..6, entityId = HA entity.
lightEntityMap: [ lightEntityMap: [
{ room: 'light_livingRoom', light: 1, entityId: 'input_boolean.living_room_new' }, { room: 'l_open_plan_living_room', light: 1, entityId: 'input_boolean.open_plan_living_room_main_1' },
// { room: 'light_livingRoom', light: 2, entityId: 'input_boolean.living_room_2' }, { room: 'l_open_plan_living_room', light: 2, entityId: 'input_boolean.open_plan_living_room_spots_1' },
// { room: 'l_kitchen', light: 1, entityId: 'input_boolean.kitchen_1' }, { room: 'l_open_plan_dining_room', light: 1, entityId: 'input_boolean.open_plan_dining_room_main_1' },
{ room: 'l_open_plan_dining_room', light: 2, entityId: 'input_boolean.open_plan_dining_room_spots_1' },
{ room: 'l_open_plan_entrance', light: 1, entityId: 'input_boolean.open_plan_entrance_mirror_1' },
{ room: 'l_open_plan_entrance', light: 2, entityId: 'input_boolean.open_plan_entrance_main_1' },
{ room: 'l_open_plan_guest_wc', light: 1, entityId: 'input_boolean.open_plan_guest_wc_main_1' },
{ room: 'l_open_plan_guest_wc', light: 2, entityId: 'input_boolean.open_plan_guest_wc_strip_1' },
{ room: 'l_open_plan_guest_wc', light: 3, entityId: 'input_boolean.open_plan_guest_wc_fan_1' },
{ room: 'l_open_plan_living_room', light: 3, entityId: 'input_boolean.open_plan_living_room_strip_1' },
{ room: 'l_open_plan_living_room', light: 4, entityId: 'input_boolean.open_plan_living_room_strip_2' },
{ room: 'l_kitchen_kitchen', light: 1, entityId: 'input_boolean.kitchen_kitchen_main_1' },
{ room: 'l_kitchen_kitchen', light: 2, entityId: 'input_boolean.kitchen_kitchen_island_1' },
{ room: 'l_kitchen_kitchen', light: 3, entityId: 'input_boolean.kitchen_kitchen_cabinets_1' },
{ room: 'l_kitchen_kitchen', light: 4, entityId: 'input_boolean.kitchen_kitchen_fridge_1' },
{ room: 'l_kitchen_pantry', light: 1, entityId: 'input_boolean.kitchen_pantry_main_1' },
{ room: 'l_bedrooms_office', light: 1, entityId: 'input_boolean.bedrooms_office_main_1' },
{ room: 'l_bedrooms_office', light: 2, entityId: 'input_boolean.bedrooms_office_strip_1' },
{ room: 'l_bedrooms_hallway', light: 1, entityId: 'input_boolean.bedrooms_hallway_main_1' },
{ room: 'l_bedrooms_laundry', light: 1, entityId: 'input_boolean.bedrooms_laundry_main_1' },
{ room: 'l_bedrooms_shower', light: 1, entityId: 'input_boolean.bedrooms_shower_spots_1' },
{ room: 'l_bedrooms_shower', light: 2, entityId: 'input_boolean.bedrooms_shower_fan_1' },
{ room: 'l_bedrooms_bedroom', light: 1, entityId: 'input_boolean.bedrooms_bedroom_main_1' },
{ room: 'l_bedrooms_bedroom', light: 2, entityId: 'input_boolean.bedrooms_bedroom_spots_1' },
{ room: 'l_master_bedroom_suite', light: 1, entityId: 'input_boolean.master_bedroom_suite_main_1' },
{ room: 'l_master_bedroom_suite', light: 2, entityId: 'input_boolean.master_bedroom_suite_spots_1' },
{ room: 'l_master_bedroom_suite', light: 3, entityId: 'input_boolean.master_bedroom_suite_strip_1' },
{ room: 'l_master_bedroom_suite', light: 4, entityId: 'input_boolean.master_bedroom_suite_door_1' },
{ room: 'l_master_bedroom_suite', light: 5, entityId: 'input_boolean.master_bedroom_suite_dresser_1' },
{ room: 'l_master_bedroom_bathroom', light: 1, entityId: 'input_boolean.master_bedroom_bathroom_spots_1' },
{ room: 'l_master_bedroom_bathroom', light: 2, entityId: 'input_boolean.master_bedroom_bathroom_fan_1' },
{ room: 'l_exterior_veranda', light: 1, entityId: 'input_boolean.exterior_veranda_main_1' },
{ room: 'l_exterior_yard', light: 1, entityId: 'input_boolean.exterior_yard_bbq_1' },
{ room: 'l_exterior_entrance', light: 1, entityId: 'input_boolean.exterior_entrance_door_1' },
{ room: 'l_exterior_yard', light: 2, entityId: 'input_boolean.exterior_yard_front_lights_1' },
{ room: 'l_exterior_yard', light: 3, entityId: 'input_boolean.exterior_yard_backyard_flood_light_1' },
{ room: 'l_exterior_yard', light: 4, entityId: 'input_boolean.exterior_yard_backyard_flood_light_2' },
{ room: 'l_exterior_yard', light: 5, entityId: 'input_boolean.exterior_yard_master_bedroom_flood_light_1' },
{ room: 'l_exterior_yard', light: 6, entityId: 'input_boolean.exterior_yard_driveway_1' },
], ],
// HA entity_id substring (after domain.) without trailing _N → NVL room key. For HA to NVL. // HA entity_id substring (after domain.) without trailing _N → NVL room key. For HA to NVL.
entityToRoom: { entityToRoom: {
// living_room: 'livingRoom', open_plan_living_room_main: 'open_plan_living_room',
living_room_new: 'cmd_livingroom', open_plan_living_room_spots: 'open_plan_living_room',
// kitchen: 'kitchen', open_plan_living_room_strip: 'open_plan_living_room',
// master_bedroom: 'masterBedroom', open_plan_dining_room_main: 'open_plan_dining_room',
// bathroom: 'bathroom', open_plan_dining_room_spots: 'open_plan_dining_room',
// bedroom_1: 'bedroom_1', open_plan_entrance_mirror: 'open_plan_entrance',
// bedroom_2: 'bedroom_2', open_plan_entrance_main: 'open_plan_entrance',
// dinning_room: 'dinningRoom', open_plan_guest_wc_main: 'open_plan_guest_wc',
// entrance: 'entrance', open_plan_guest_wc_strip: 'open_plan_guest_wc',
// hallway: 'hallway', open_plan_guest_wc_fan: 'open_plan_guest_wc',
// pantry: 'pantry', kitchen_kitchen_main: 'kitchen_kitchen',
// guest_wc: 'guestWc', kitchen_kitchen_island: 'kitchen_kitchen',
// out_veranda: 'outVeranda', kitchen_kitchen_cabinets: 'kitchen_kitchen',
// out_front: 'outFront', kitchen_kitchen_fridge: 'kitchen_kitchen',
// out_back: 'outBack', kitchen_pantry_main: 'kitchen_pantry',
// out_side: 'outSide', bedrooms_office_main: 'bedrooms_office',
bedrooms_office_strip: 'bedrooms_office',
bedrooms_hallway_main: 'bedrooms_hallway',
bedrooms_laundry_main: 'bedrooms_laundry',
bedrooms_shower_spots: 'bedrooms_shower',
bedrooms_shower_fan: 'bedrooms_shower',
bedrooms_bedroom_main: 'bedrooms_bedroom',
bedrooms_bedroom_spots: 'bedrooms_bedroom',
master_bedroom_suite_main: 'master_bedroom_suite',
master_bedroom_suite_spots: 'master_bedroom_suite',
master_bedroom_suite_strip: 'master_bedroom_suite',
master_bedroom_suite_door: 'master_bedroom_suite',
master_bedroom_suite_dresser: 'master_bedroom_suite',
master_bedroom_bathroom_spots: 'master_bedroom_bathroom',
master_bedroom_bathroom_fan: 'master_bedroom_bathroom',
exterior_veranda_main: 'exterior_veranda',
exterior_yard_bbq: 'exterior_yard',
exterior_entrance_door: 'exterior_entrance',
exterior_yard_front_lights: 'exterior_yard',
exterior_yard_backyard_flood_light: 'exterior_yard',
exterior_yard_master_bedroom_flood_light: 'exterior_yard',
exterior_yard_driveway: 'exterior_yard',
}, },
// // Zigbee: friendly_name → single room (fallback when switchBindings missing). // // Zigbee: friendly_name → single room (fallback when switchBindings missing).
// deviceToRoom: { // deviceToRoom: {
// 'Office Switch': 'cmd_livingroom', // 'Office Switch': 'open_plan_living_room',
// }, // },
// When using a multi-device Zigbee node, payload is keyed by IEEE (e.g. 0xa4c138a5b9771b05). Map IEEE → friendly name so switchBindings by name still works. // When using a multi-device Zigbee node, payload is keyed by IEEE (e.g. 0xa4c138a5b9771b05). Map IEEE → friendly name so switchBindings by name still works.
@@ -68,7 +123,7 @@ const ROOM_CONFIG = {
// Optional: bind by IEEE instead of friendly name (same shape as switchBindings). Use if the node never sends friendly_name. // Optional: bind by IEEE instead of friendly name (same shape as switchBindings). Use if the node never sends friendly_name.
// switchBindingsByDeviceId: { // switchBindingsByDeviceId: {
// '0xa4c138a5b9771b05': { 1: { room: 'cmd_livingroom', light: 1 }, 2: { room: 'cmd_out', light: 2 } }, // '0xa4c138a5b9771b05': { 1: { room: 'open_plan_living_room', light: 1 }, 2: { room: 'open_plan_dining_room', light: 1 } },
// }, // },
/** /**
@@ -78,8 +133,8 @@ const ROOM_CONFIG = {
*/ */
switchBindings: { switchBindings: {
'Office Switch': { 'Office Switch': {
1: { room: 'cmd_livingroom', light: 1 }, // button 1 → light 1 1: { room: 'open_plan_living_room', light: 1 },
2: { room: 'cmd_livingroom', light: 2 }, // button 2 → light 1 (same light; other switches could do button 2 → light 2) 2: { room: 'open_plan_dining_room', light: 1 },
}, },
}, },
}; };

View File

@@ -4,17 +4,34 @@
// 3. Replace the ROOM_CONFIG below with your paste. Keep the two lines at the end. // 3. Replace the ROOM_CONFIG below with your paste. Keep the two lines at the end.
const ROOM_CONFIG = { const ROOM_CONFIG = {
roomNames: ['cmd_livingroom', 'cmd_out'], roomNames: [
lightEntityMap: [ 'open_plan_living_room',
{ room: 'light_livingRoom', light: 1, entityId: 'input_boolean.living_room_new' }, 'open_plan_dining_room',
'open_plan_entrance',
'open_plan_guest_wc',
'kitchen_kitchen',
'kitchen_pantry',
'bedrooms_office',
'bedrooms_hallway',
'bedrooms_laundry',
'bedrooms_shower',
'bedrooms_bedroom',
'master_bedroom_suite',
'master_bedroom_bathroom',
'exterior_veranda',
'exterior_entrance',
'exterior_yard',
], ],
entityToRoom: { living_room_new: 'cmd_livingroom' }, lightEntityMap: [
deviceToRoom: { 'Office Switch': 'cmd_livingroom' }, { room: 'l_open_plan_living_room', light: 1, entityId: 'input_boolean.open_plan_living_room_main_1' },
],
entityToRoom: { open_plan_living_room_main: 'open_plan_living_room' },
deviceToRoom: { 'Office Switch': 'open_plan_living_room' },
deviceIdToName: {}, deviceIdToName: {},
switchBindings: { switchBindings: {
'Office Switch': { 'Office Switch': {
1: { room: 'cmd_livingroom', light: 1 }, 1: { room: 'open_plan_living_room', light: 1 },
2: { room: 'cmd_livingroom', light: 1 }, 2: { room: 'open_plan_dining_room', light: 1 },
}, },
}, },
}; };