- Reorganized project: codesys/, docs/codesys|redesign|integration|reference/, scripts/ - CODESYS project and exports in codesys/ - Documentation index in docs/README.md - Redesign and light naming configuration - Water boiler control and safety design Co-authored-by: Cursor <cursoragent@cursor.com>
363 lines
8.4 KiB
Markdown
363 lines
8.4 KiB
Markdown
# Structure Comparison - Visual Guide
|
||
|
||
## Current Structure (Room-Centric)
|
||
|
||
```
|
||
CODESYS:
|
||
┌─────────────────────────────────────┐
|
||
│ masterBedroom: fb_switch │
|
||
│ ├─ l_1 (Light 1) │
|
||
│ ├─ l_2 (Light 2) │
|
||
│ ├─ l_3 (Light 3) │
|
||
│ ├─ l_4 (Light 4) │
|
||
│ ├─ l_5 (Light 5) │
|
||
│ └─ l_6 (Light 6) │
|
||
└─────────────────────────────────────┘
|
||
|
||
Network Variable:
|
||
l_masterBedroom.l_1
|
||
l_masterBedroom.l_2
|
||
...
|
||
|
||
Home Assistant:
|
||
light.master_bedroom_l1
|
||
light.master_bedroom_l2
|
||
light.master_bedroom_l3
|
||
...
|
||
```
|
||
|
||
**Problems**:
|
||
- ❌ Generic names (l_1, l_2)
|
||
- ❌ Fixed 6 lights per room
|
||
- ❌ Wasted space (most rooms don't use all 6)
|
||
- ❌ Hard to identify which light is which
|
||
|
||
---
|
||
|
||
## Option 1: Flat Light-Centric
|
||
|
||
```
|
||
CODESYS:
|
||
┌─────────────────────────────────────┐
|
||
│ lights: struct_all_lights │
|
||
│ ├─ kitchen_main │
|
||
│ ├─ kitchen_under_cabinet │
|
||
│ ├─ master_bedroom_main │
|
||
│ ├─ master_bedroom_bedside_left │
|
||
│ ├─ master_bedroom_bedside_right │
|
||
│ └─ ... (all lights flat) │
|
||
└─────────────────────────────────────┘
|
||
|
||
Network Variable:
|
||
lights.kitchen_main.on
|
||
lights.kitchen_main.state
|
||
lights.master_bedroom_main.on
|
||
...
|
||
|
||
Home Assistant:
|
||
light.kitchen_main
|
||
light.kitchen_under_cabinet
|
||
light.master_bedroom_main
|
||
light.master_bedroom_bedside_left
|
||
```
|
||
|
||
**Benefits**:
|
||
- ✅ Clear, descriptive names
|
||
- ✅ Easy to find lights
|
||
- ✅ No wasted space
|
||
- ✅ Perfect for HA organization
|
||
|
||
---
|
||
|
||
## Option 4: Hybrid (Recommended)
|
||
|
||
```
|
||
CODESYS (Room-organized):
|
||
┌─────────────────────────────────────┐
|
||
│ rooms: struct_rooms │
|
||
│ ├─ kitchen │
|
||
│ │ ├─ main │
|
||
│ │ ├─ under_cabinet │
|
||
│ │ └─ island │
|
||
│ ├─ master_bedroom │
|
||
│ │ ├─ main │
|
||
│ │ ├─ bedside_left │
|
||
│ │ └─ bedside_right │
|
||
│ └─ ... │
|
||
└─────────────────────────────────────┘
|
||
|
||
Network Variable:
|
||
rooms.kitchen.main.on
|
||
rooms.kitchen.main.state
|
||
rooms.master_bedroom.main.on
|
||
...
|
||
|
||
Node-RED (Flattened):
|
||
kitchen_main → HA
|
||
kitchen_under_cabinet → HA
|
||
master_bedroom_main → HA
|
||
master_bedroom_bedside_left → HA
|
||
|
||
Home Assistant:
|
||
light.kitchen_main
|
||
light.kitchen_under_cabinet
|
||
light.master_bedroom_main
|
||
light.master_bedroom_bedside_left
|
||
```
|
||
|
||
**Benefits**:
|
||
- ✅ Organized in CODESYS (by room)
|
||
- ✅ Flat in Home Assistant (by light)
|
||
- ✅ Descriptive names
|
||
- ✅ Easy to add lights
|
||
- ✅ Best of both worlds
|
||
|
||
---
|
||
|
||
## Real-World Example Comparison
|
||
|
||
### Scenario: Kitchen with 3 lights
|
||
|
||
**Current Structure**:
|
||
```iec
|
||
kitchen: fb_switch
|
||
l_1 = ??? (which light?)
|
||
l_2 = ??? (which light?)
|
||
l_3 = ??? (which light?)
|
||
l_4 = unused
|
||
l_5 = unused
|
||
l_6 = unused
|
||
```
|
||
|
||
**Hybrid Structure**:
|
||
```iec
|
||
rooms.kitchen:
|
||
main = Main ceiling light
|
||
under_cabinet = Under cabinet lights
|
||
island = Island pendant
|
||
(no unused slots)
|
||
```
|
||
|
||
**Home Assistant**:
|
||
```
|
||
Current:
|
||
light.kitchen_l1 ← What is this?
|
||
light.kitchen_l2 ← What is this?
|
||
light.kitchen_l3 ← What is this?
|
||
|
||
Hybrid:
|
||
light.kitchen_main ← Clear!
|
||
light.kitchen_under_cabinet ← Clear!
|
||
light.kitchen_island ← Clear!
|
||
```
|
||
|
||
---
|
||
|
||
## MQTT Topic Comparison
|
||
|
||
### Current
|
||
```
|
||
homeassistant/light/master_bedroom_l1/state
|
||
homeassistant/light/master_bedroom_l2/state
|
||
homeassistant/light/kitchen_l1/state
|
||
```
|
||
|
||
**Problems**: Generic, hard to identify
|
||
|
||
### Hybrid
|
||
```
|
||
homeassistant/light/kitchen_main/state
|
||
homeassistant/light/kitchen_under_cabinet/state
|
||
homeassistant/light/master_bedroom_main/state
|
||
homeassistant/light/master_bedroom_bedside_left/state
|
||
```
|
||
|
||
**Benefits**: Self-documenting, clear purpose
|
||
|
||
---
|
||
|
||
## Home Assistant Dashboard Comparison
|
||
|
||
### Current
|
||
```
|
||
Kitchen
|
||
├─ Light 1 ← What is this?
|
||
├─ Light 2 ← What is this?
|
||
└─ Light 3 ← What is this?
|
||
|
||
Master Bedroom
|
||
├─ Light 1 ← What is this?
|
||
├─ Light 2 ← What is this?
|
||
└─ Light 3 ← What is this?
|
||
```
|
||
|
||
### Hybrid
|
||
```
|
||
Kitchen
|
||
├─ Main Light
|
||
├─ Under Cabinet
|
||
└─ Island
|
||
|
||
Master Bedroom
|
||
├─ Main Light
|
||
├─ Bedside Left
|
||
└─ Bedside Right
|
||
```
|
||
|
||
**Much clearer!**
|
||
|
||
---
|
||
|
||
## Network Variable Efficiency
|
||
|
||
### Current
|
||
- 15 rooms × 6 lights = 90 potential lights
|
||
- Most rooms use 2-3 lights
|
||
- **Waste**: ~60 unused light slots
|
||
- **Network traffic**: Sends all 90 values every 50ms
|
||
|
||
### Hybrid
|
||
- Only define lights that exist
|
||
- Kitchen: 3 lights (not 6)
|
||
- Master Bedroom: 3 lights (not 6)
|
||
- **Efficiency**: ~50% less network traffic
|
||
- **Clarity**: Only relevant data
|
||
|
||
---
|
||
|
||
## Scalability Comparison
|
||
|
||
### Adding a New Light
|
||
|
||
**Current**:
|
||
1. Find unused `l_X` slot in room
|
||
2. Hope it's available
|
||
3. Update documentation
|
||
4. Update HA manually
|
||
|
||
**Hybrid**:
|
||
1. Add `new_light: struct_light_control` to room
|
||
2. Done! Auto-discovered in HA
|
||
|
||
### Adding a New Room
|
||
|
||
**Current**:
|
||
1. Add new room structure
|
||
2. Add all 6 light slots (even if unused)
|
||
3. Update network variables
|
||
4. Update HA manually
|
||
|
||
**Hybrid**:
|
||
1. Add room with only needed lights
|
||
2. Done! Auto-discovered in HA
|
||
|
||
---
|
||
|
||
## Implementation Example
|
||
|
||
### Hybrid Structure in CODESYS
|
||
|
||
```iec
|
||
TYPE struct_light_control :
|
||
STRUCT
|
||
on: BOOL;
|
||
off: BOOL;
|
||
toggle: BOOL;
|
||
state: BOOL;
|
||
relay_status: BOOL;
|
||
END_STRUCT
|
||
END_TYPE
|
||
|
||
TYPE struct_room_lights :
|
||
STRUCT
|
||
main: struct_light_control;
|
||
secondary: struct_light_control;
|
||
task: struct_light_control;
|
||
ambient: struct_light_control;
|
||
accent: struct_light_control;
|
||
security: struct_light_control;
|
||
END_STRUCT
|
||
END_TYPE
|
||
|
||
VAR_GLOBAL
|
||
rooms: STRUCT
|
||
kitchen: STRUCT
|
||
main: struct_light_control;
|
||
under_cabinet: struct_light_control;
|
||
island: struct_light_control;
|
||
END_STRUCT;
|
||
|
||
master_bedroom: STRUCT
|
||
main: struct_light_control;
|
||
bedside_left: struct_light_control;
|
||
bedside_right: struct_light_control;
|
||
END_STRUCT;
|
||
|
||
// ... other rooms
|
||
END_STRUCT;
|
||
END_VAR
|
||
```
|
||
|
||
### Node-RED Transformation
|
||
|
||
```javascript
|
||
// Transform room-based to flat structure for HA
|
||
function transformToHA(msg) {
|
||
const rooms = msg.payload.rooms;
|
||
const result = {};
|
||
|
||
for (const [roomName, roomLights] of Object.entries(rooms)) {
|
||
for (const [lightName, lightControl] of Object.entries(roomLights)) {
|
||
const lightId = `${roomName}_${lightName}`;
|
||
result[lightId] = {
|
||
on: lightControl.on,
|
||
off: lightControl.off,
|
||
state: lightControl.state,
|
||
status: lightControl.relay_status
|
||
};
|
||
}
|
||
}
|
||
|
||
return { payload: result };
|
||
}
|
||
```
|
||
|
||
### Home Assistant Auto-Discovery
|
||
|
||
```yaml
|
||
# Node-RED publishes this automatically
|
||
homeassistant/light/kitchen_main/config:
|
||
name: "Kitchen Main"
|
||
unique_id: "kitchen_main"
|
||
state_topic: "homeassistant/light/kitchen_main/state"
|
||
command_topic: "homeassistant/light/kitchen_main/set"
|
||
state_value_template: "{{ value_json.state }}"
|
||
command_on_template: '{"on":true}'
|
||
command_off_template: '{"off":true}'
|
||
```
|
||
|
||
---
|
||
|
||
## Recommendation Summary
|
||
|
||
**Use Hybrid Structure (Option 4)** because:
|
||
|
||
1. ✅ **Best Organization**: Room-based in CODESYS, flat in HA
|
||
2. ✅ **Clear Naming**: `kitchen_main` vs `l_1`
|
||
3. ✅ **Efficiency**: Only define existing lights
|
||
4. ✅ **Scalability**: Easy to add lights/rooms
|
||
5. ✅ **Maintainability**: Self-documenting structure
|
||
6. ✅ **HA Integration**: Perfect for Home Assistant
|
||
7. ✅ **Future-Proof**: Easy to extend
|
||
|
||
**Key Changes**:
|
||
- Replace `l_1`, `l_2` with descriptive names
|
||
- Use function-based naming: `main`, `secondary`, `task`, etc.
|
||
- Flatten structure in Node-RED for HA
|
||
- Only define lights that exist
|
||
- Add metadata for better organization
|
||
|
||
---
|
||
|
||
**See**: [Full Structure Redesign Analysis](structure-redesign-analysis.md) for complete details.
|