# 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_open_plan_living_room` | struct_room_outs | 6 BOOLs (`l_1..l_6`) |
| `l_open_plan_dining_room` | struct_room_outs | same |
| `l_open_plan_entrance` | struct_room_outs | same |
| `l_open_plan_guest_wc` | struct_room_outs | same |
| `l_kitchen_kitchen`, `l_kitchen_pantry` | 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 |

**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 |
|----------|------|-------------|
| `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 |

**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:** Use a **UDP out** node to the PLC IP and NVL Receiver port. Send one UDP packet per update with the same binary layout as `NVL_In`; see [nodered-payload.md](nodered-payload.md) for building the buffer.

---

## 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):** **UDP in** node on the NVL Sender port (e.g. 5555). Payload is binary; see [nodered-payload.md](nodered-payload.md) for layout and parsing.
- **Send (Node-RED → PLC):** **UDP out** node to PLC IP and NVL Receiver port (e.g. 5556). Build the buffer from [nodered-payload.md](nodered-payload.md).
