# Network Variables (NVL) for Node-RED This folder describes the **network variable** setup used for CODESYS ↔ Node-RED communication. The PLC sends light/boiler **status** to Node-RED and receives **commands** from Node-RED over UDP. ## Overview | Direction | CODESYS name | Node-RED role | Content | |-----------|--------------|---------------|---------| | **PLC → Node-RED** | **NVL_Out** (Sender) | Receive UDP | Light states + boiler status | | **Node-RED → PLC** | **NVL_In** (Receiver) | Send UDP | Light commands + boiler commands | - **Protocol**: UDP - **Typical interval**: 50 ms cyclic (configurable in CODESYS) - **Payload**: Binary (struct layout) or see [Payload layout for Node-RED](nodered-payload.md) for parsing. --- ## 1. NVL_Out (PLC → Node-RED) **Purpose:** PLC sends current light outputs and boiler status so Node-RED can forward them to Home Assistant / MQTT. **Variables sent (in order):** | Variable | Type | Description | |----------|------|-------------| | `l_masterBedroom` | struct_room_outs | 12 BOOLs (l_1..l_6, l_1_status..l_6_status) | | `l_masterBathroom` | struct_room_outs | same | | `l_bedroom_1` .. `l_bedroom_2` | struct_room_outs | same | | `l_bathroom`, `l_guestWc`, `l_kitchen`, `l_pantry` | struct_room_outs | same | | `l_livingRoom`, `l_dinningRoom`, `l_entrance`, `l_hallway` | struct_room_outs | same | | `l_outVeranda`, `l_outFront`, `l_outBack`, `l_outSide` | 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 | **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). --- ## 2. NVL_In (Node-RED → PLC) **Purpose:** Node-RED sends commands (HA ON/OFF, Zigbee toggle edges, boiler on/off, etc.) so the PLC can drive lights and the boiler. **Variables received (in order):** | 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 | | `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 Node-RED:** Send one UDP packet per update (or cyclic) with the same binary layout as `NVL_In` so CODESYS can unpack it into the receiver struct. --- ## 3. CODESYS configuration steps 1. **Add NVL Sender** - Device tree → Add Object → Network Variable List (Sender). - Set protocol to **UDP**, destination IP = Node-RED host, port = e.g. **5555** (receive port on Node-RED). - Add variables: add the **entire NVL_Out** struct (or add each member; see CODESYS help). - Set task (e.g. EtherCAT_Task) and interval (e.g. T#50ms). 2. **Add NVL Receiver** - Add Object → Network Variable List (Receiver). - Set protocol to **UDP**, listen port = e.g. **5556**. - Add variables: add the **entire NVL_In** struct. - Set task and interval. 3. **Bind to GVL** - Either the NVL Sender/Receiver **are** the GVL variables (you map the NVL to the symbols `NVL_Out` and `NVL_In`), or you copy NVL → GVL in the program. Typically you bind the NVL list to a GVL so that `NVL_Out` and `NVL_In` in your code are the same memory the NVL driver sends/receives. 4. **Ports and IP** - Fill in your PLC IP and Node-RED IP. Node-RED **receives** on the port you set as “destination port” in the NVL Sender. Node-RED **sends** to the PLC IP and the port you set as “listen port” in the NVL Receiver. --- ## 4. Node-RED usage - **Receive (PLC → Node-RED):** Use a **UDP in** node listening on the port configured in the CODESYS NVL Sender (e.g. 5555). The payload is binary; see [nodered-payload.md](nodered-payload.md) for struct layout and how to parse it to JSON for MQTT/HA. - **Send (Node-RED → PLC):** Use a **UDP out** node targeting the PLC IP and the NVL Receiver port (e.g. 5556). Build the payload buffer from your command (e.g. from MQTT/HA) using the same layout as [nodered-payload.md](nodered-payload.md). See **nodered-payload.md** in this folder for byte layout and example parsing/building.