Initial commit: Home automation docs and CODESYS project
- 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>
This commit is contained in:
538
docs/redesign/structure-redesign-analysis.md
Normal file
538
docs/redesign/structure-redesign-analysis.md
Normal file
@@ -0,0 +1,538 @@
|
||||
# Room/Light Structure Redesign Analysis
|
||||
|
||||
## Current Structure Analysis
|
||||
|
||||
### Current Organization
|
||||
|
||||
**Room-Centric Approach**:
|
||||
- 15 rooms, each with 1 `fb_switch` instance
|
||||
- Each room controls up to 6 lights
|
||||
- Network variables organized by room name
|
||||
- Structure: `l_masterBedroom.l_1`, `l_masterBedroom.l_2`, etc.
|
||||
|
||||
**Current Data Flow**:
|
||||
```
|
||||
Room → fb_switch → 6 lights
|
||||
Network Variable: l_masterBedroom (struct_lights with l_1 to l_6)
|
||||
```
|
||||
|
||||
### Current Issues
|
||||
|
||||
1. **Limited Scalability**
|
||||
- Fixed 6 lights per room
|
||||
- Adding a 7th light requires structure changes
|
||||
- Some rooms may only need 1-2 lights (waste)
|
||||
|
||||
2. **Home Assistant Organization**
|
||||
- HA entities: `light.master_bedroom_l1`, `light.master_bedroom_l2`
|
||||
- Not intuitive - hard to find lights
|
||||
- No grouping by function or zone
|
||||
|
||||
3. **Network Variable Efficiency**
|
||||
- 15 room structures × 6 lights = 90 potential lights
|
||||
- Most rooms don't use all 6 lights
|
||||
- Wasted network bandwidth
|
||||
|
||||
4. **Maintenance Complexity**
|
||||
- Changes require updating room structures
|
||||
- Hard to add new rooms
|
||||
- No clear naming convention
|
||||
|
||||
5. **MQTT Topic Structure**
|
||||
- Topics like: `homeassistant/light/master_bedroom_l1`
|
||||
- Not standardized
|
||||
- Hard to discover and manage
|
||||
|
||||
## Alternative Structures
|
||||
|
||||
### Option 1: Flat Light-Centric Structure (Recommended)
|
||||
|
||||
**Concept**: All lights in a single flat structure, organized by unique IDs.
|
||||
|
||||
**Data Structure**:
|
||||
```iec
|
||||
TYPE struct_light :
|
||||
STRUCT
|
||||
// Control
|
||||
on: BOOL; // Turn ON command
|
||||
off: BOOL; // Turn OFF command
|
||||
toggle: BOOL; // Toggle command (for Zigbee)
|
||||
|
||||
// Status
|
||||
state: BOOL; // Current state
|
||||
relay_status: BOOL; // Actual relay status
|
||||
|
||||
// Metadata (for reference, not in network var)
|
||||
room: STRING; // Room name
|
||||
name: STRING; // Light name
|
||||
zone: STRING; // Zone (indoor/outdoor)
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
|
||||
TYPE struct_all_lights :
|
||||
STRUCT
|
||||
// Master Bedroom
|
||||
master_bedroom_main: struct_light;
|
||||
master_bedroom_bedside: struct_light;
|
||||
master_bedroom_closet: struct_light;
|
||||
|
||||
// Kitchen
|
||||
kitchen_ceiling: struct_light;
|
||||
kitchen_under_cabinet: struct_light;
|
||||
kitchen_island: struct_light;
|
||||
|
||||
// Living Room
|
||||
living_room_main: struct_light;
|
||||
living_room_reading: struct_light;
|
||||
living_room_tv: struct_light;
|
||||
|
||||
// Outdoor
|
||||
outdoor_front_porch: struct_light;
|
||||
outdoor_back_patio: struct_light;
|
||||
outdoor_side: struct_light;
|
||||
|
||||
// ... all other lights
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
```
|
||||
|
||||
**Network Variable**:
|
||||
```iec
|
||||
VAR_GLOBAL
|
||||
lights: struct_all_lights; // All lights in one structure
|
||||
END_VAR
|
||||
```
|
||||
|
||||
**Function Block**:
|
||||
```iec
|
||||
FUNCTION_BLOCK fb_lightControl
|
||||
VAR_INPUT
|
||||
light: struct_light;
|
||||
relay_output: BOOL; // Direct relay output
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
relay_control: BOOL;
|
||||
light_status: struct_light;
|
||||
END_VAR
|
||||
// Implementation...
|
||||
END_FUNCTION_BLOCK
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
- ✅ Each light is independent
|
||||
- ✅ Easy to add/remove lights
|
||||
- ✅ Clear naming: `lights.kitchen_ceiling.on`
|
||||
- ✅ Better for Home Assistant (one entity per light)
|
||||
- ✅ No wasted space
|
||||
- ✅ Easy to group in HA by room/zone
|
||||
|
||||
**Cons**:
|
||||
- ⚠️ Larger structure (but more efficient overall)
|
||||
- ⚠️ Need to update structure when adding lights
|
||||
|
||||
**Home Assistant Organization**:
|
||||
```
|
||||
light.kitchen_ceiling
|
||||
light.kitchen_under_cabinet
|
||||
light.master_bedroom_main
|
||||
light.master_bedroom_bedside
|
||||
```
|
||||
|
||||
**MQTT Topics**:
|
||||
```
|
||||
homeassistant/light/kitchen_ceiling/state
|
||||
homeassistant/light/kitchen_ceiling/set
|
||||
homeassistant/light/master_bedroom_main/state
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Hierarchical Room → Light Structure
|
||||
|
||||
**Concept**: Keep room structure but make it more flexible.
|
||||
|
||||
**Data Structure**:
|
||||
```iec
|
||||
TYPE struct_room :
|
||||
STRUCT
|
||||
room_id: STRING; // "master_bedroom"
|
||||
room_name: STRING; // "Master Bedroom"
|
||||
zone: STRING; // "indoor", "outdoor"
|
||||
|
||||
// Flexible light array (up to 10 lights)
|
||||
lights: ARRAY[1..10] OF struct_light;
|
||||
light_count: INT; // Actual number of lights
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
|
||||
TYPE struct_home :
|
||||
STRUCT
|
||||
rooms: ARRAY[1..20] OF struct_room;
|
||||
room_count: INT;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
- ✅ Maintains room grouping
|
||||
- ✅ Flexible number of lights per room
|
||||
- ✅ Can add rooms easily
|
||||
|
||||
**Cons**:
|
||||
- ⚠️ More complex array handling
|
||||
- ⚠️ CODESYS arrays less efficient for network vars
|
||||
- ⚠️ Harder to access specific lights
|
||||
|
||||
---
|
||||
|
||||
### Option 3: Zone-Based Structure
|
||||
|
||||
**Concept**: Organize by functional zones rather than rooms.
|
||||
|
||||
**Data Structure**:
|
||||
```iec
|
||||
TYPE struct_zone :
|
||||
STRUCT
|
||||
zone_id: STRING; // "indoor_main", "outdoor_security"
|
||||
zone_name: STRING; // "Indoor Main", "Outdoor Security"
|
||||
|
||||
// Lights in this zone
|
||||
lights: ARRAY[1..20] OF struct_light;
|
||||
light_count: INT;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
|
||||
TYPE struct_home_zones :
|
||||
STRUCT
|
||||
indoor_main: struct_zone;
|
||||
indoor_bedrooms: struct_zone;
|
||||
indoor_bathrooms: struct_zone;
|
||||
outdoor_security: struct_zone;
|
||||
outdoor_ambient: struct_zone;
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
```
|
||||
|
||||
**Zones**:
|
||||
- **Indoor Main**: Kitchen, Living Room, Dining Room, Hallway
|
||||
- **Indoor Bedrooms**: All bedrooms
|
||||
- **Indoor Bathrooms**: All bathrooms
|
||||
- **Outdoor Security**: Front, Back, Side (security-focused)
|
||||
- **Outdoor Ambient**: Veranda, Patio (ambient lighting)
|
||||
|
||||
**Pros**:
|
||||
- ✅ Logical grouping for automation
|
||||
- ✅ Easy to control all security lights
|
||||
- ✅ Better for scheduling (indoor vs outdoor)
|
||||
|
||||
**Cons**:
|
||||
- ⚠️ Less intuitive for room-based control
|
||||
- ⚠️ Lights may belong to multiple zones conceptually
|
||||
|
||||
---
|
||||
|
||||
### Option 4: Hybrid: Room + Light ID Structure (Best Balance)
|
||||
|
||||
**Concept**: Combine room organization with individual light control.
|
||||
|
||||
**Data Structure**:
|
||||
```iec
|
||||
TYPE struct_light_control :
|
||||
STRUCT
|
||||
// Control
|
||||
on: BOOL;
|
||||
off: BOOL;
|
||||
toggle: BOOL;
|
||||
|
||||
// Status
|
||||
state: BOOL;
|
||||
relay_status: BOOL;
|
||||
|
||||
// Metadata (for HA, not in network var)
|
||||
light_id: STRING; // Unique ID: "mb_main", "kit_ceiling"
|
||||
light_name: STRING; // Display name: "Main Light", "Ceiling Light"
|
||||
room: STRING; // Room: "master_bedroom", "kitchen"
|
||||
zone: STRING; // Zone: "indoor", "outdoor"
|
||||
function: STRING; // Function: "main", "task", "ambient", "security"
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
|
||||
// Organized by room for CODESYS, but flat for HA
|
||||
TYPE struct_rooms :
|
||||
STRUCT
|
||||
// Master Bedroom
|
||||
master_bedroom: STRUCT
|
||||
main: struct_light_control;
|
||||
bedside_left: struct_light_control;
|
||||
bedside_right: struct_light_control;
|
||||
closet: struct_light_control;
|
||||
END_STRUCT;
|
||||
|
||||
// Kitchen
|
||||
kitchen: STRUCT
|
||||
ceiling: struct_light_control;
|
||||
under_cabinet: struct_light_control;
|
||||
island: struct_light_control;
|
||||
END_STRUCT;
|
||||
|
||||
// ... other rooms
|
||||
END_STRUCT
|
||||
END_TYPE
|
||||
```
|
||||
|
||||
**Network Variable**:
|
||||
```iec
|
||||
VAR_GLOBAL
|
||||
rooms: struct_rooms; // Organized by room
|
||||
END_VAR
|
||||
```
|
||||
|
||||
**Access Pattern**:
|
||||
- CODESYS: `rooms.kitchen.ceiling.on`
|
||||
- Node-RED: Flatten to `kitchen_ceiling` for HA
|
||||
- Home Assistant: `light.kitchen_ceiling`
|
||||
|
||||
**Pros**:
|
||||
- ✅ Best of both worlds
|
||||
- ✅ Organized in CODESYS (by room)
|
||||
- ✅ Flat in Home Assistant (by light)
|
||||
- ✅ Easy to add lights to rooms
|
||||
- ✅ Clear naming convention
|
||||
|
||||
**Cons**:
|
||||
- ⚠️ Requires Node-RED transformation
|
||||
- ⚠️ Slightly more complex
|
||||
|
||||
---
|
||||
|
||||
## Recommended Structure: Option 4 (Hybrid)
|
||||
|
||||
### Implementation
|
||||
|
||||
**1. CODESYS Structure** (Room-organized):
|
||||
```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
|
||||
master_bedroom: struct_room_lights;
|
||||
master_bathroom: struct_room_lights;
|
||||
bedroom_1: struct_room_lights;
|
||||
bedroom_2: struct_room_lights;
|
||||
bathroom: struct_room_lights;
|
||||
kitchen: struct_room_lights;
|
||||
living_room: struct_room_lights;
|
||||
dining_room: struct_room_lights;
|
||||
hallway: struct_room_lights;
|
||||
pantry: struct_room_lights;
|
||||
entrance: struct_room_lights;
|
||||
guest_wc: struct_room_lights;
|
||||
outdoor_veranda: struct_room_lights;
|
||||
outdoor_front: struct_room_lights;
|
||||
outdoor_side: struct_room_lights;
|
||||
outdoor_back: struct_room_lights;
|
||||
END_STRUCT;
|
||||
END_VAR
|
||||
```
|
||||
|
||||
**2. Node-RED Transformation** (Flatten for HA):
|
||||
```javascript
|
||||
// Transform CODESYS structure to flat HA structure
|
||||
function transformToHA(msg) {
|
||||
const rooms = msg.payload.rooms;
|
||||
const haLights = {};
|
||||
|
||||
// Flatten structure
|
||||
for (const [roomName, roomLights] of Object.entries(rooms)) {
|
||||
for (const [lightName, lightControl] of Object.entries(roomLights)) {
|
||||
const lightId = `${roomName}_${lightName}`;
|
||||
haLights[lightId] = {
|
||||
on: lightControl.on,
|
||||
off: lightControl.off,
|
||||
state: lightControl.state,
|
||||
status: lightControl.relay_status,
|
||||
room: roomName,
|
||||
light: lightName
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { payload: haLights };
|
||||
}
|
||||
```
|
||||
|
||||
**3. Home Assistant Configuration**:
|
||||
```yaml
|
||||
# Auto-discovery via MQTT
|
||||
light:
|
||||
- platform: mqtt
|
||||
name: "Kitchen Main"
|
||||
unique_id: "kitchen_main"
|
||||
state_topic: "homeassistant/light/kitchen_main/state"
|
||||
command_topic: "homeassistant/light/kitchen_main/set"
|
||||
# ... config
|
||||
```
|
||||
|
||||
**4. MQTT Topic Structure**:
|
||||
```
|
||||
homeassistant/light/{room}_{light}/state
|
||||
homeassistant/light/{room}_{light}/set
|
||||
|
||||
Examples:
|
||||
homeassistant/light/kitchen_main/state
|
||||
homeassistant/light/master_bedroom_main/state
|
||||
homeassistant/light/outdoor_front_security/state
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comparison Matrix
|
||||
|
||||
| Aspect | Current | Option 1 (Flat) | Option 2 (Hierarchical) | Option 3 (Zone) | Option 4 (Hybrid) |
|
||||
|--------|---------|-----------------|-------------------------|------------------|-------------------|
|
||||
| **CODESYS Organization** | Room-based | Flat | Array-based | Zone-based | Room-based |
|
||||
| **HA Organization** | Room-based | Flat | Complex | Zone-based | Flat (transformed) |
|
||||
| **Scalability** | Poor | Excellent | Good | Good | Excellent |
|
||||
| **Maintainability** | Medium | Excellent | Medium | Medium | Excellent |
|
||||
| **Network Efficiency** | Poor | Good | Medium | Medium | Good |
|
||||
| **Naming Clarity** | Medium | Excellent | Medium | Good | Excellent |
|
||||
| **Implementation Complexity** | Low | Medium | High | Medium | Medium |
|
||||
| **Flexibility** | Low | High | High | Medium | High |
|
||||
|
||||
---
|
||||
|
||||
## Optimization Recommendations
|
||||
|
||||
### 1. Network Variable Optimization
|
||||
|
||||
**Current**: 15 rooms × 6 lights = 90 potential lights
|
||||
**Optimized**: Only include lights that exist
|
||||
|
||||
**Example**:
|
||||
```iec
|
||||
// Only define lights that exist
|
||||
master_bedroom: STRUCT
|
||||
main: struct_light_control;
|
||||
bedside: struct_light_control;
|
||||
// No closet light if it doesn't exist
|
||||
END_STRUCT;
|
||||
```
|
||||
|
||||
### 2. Function-Based Naming
|
||||
|
||||
Instead of `l_1`, `l_2`, use descriptive names:
|
||||
- `main` - Main/primary light
|
||||
- `secondary` - Secondary light
|
||||
- `task` - Task lighting
|
||||
- `ambient` - Ambient/atmospheric
|
||||
- `accent` - Accent lighting
|
||||
- `security` - Security/outdoor
|
||||
|
||||
### 3. Metadata for Home Assistant
|
||||
|
||||
Add metadata structure (not in network var, but in Node-RED):
|
||||
```javascript
|
||||
const lightMetadata = {
|
||||
"kitchen_main": {
|
||||
name: "Kitchen Main Light",
|
||||
room: "Kitchen",
|
||||
zone: "indoor",
|
||||
function: "main",
|
||||
icon: "mdi:ceiling-light"
|
||||
},
|
||||
// ... more lights
|
||||
};
|
||||
```
|
||||
|
||||
### 4. Grouping in Home Assistant
|
||||
|
||||
Use HA groups and areas:
|
||||
```yaml
|
||||
# Automatically group by room
|
||||
light:
|
||||
- platform: group
|
||||
name: "Kitchen Lights"
|
||||
entities:
|
||||
- light.kitchen_main
|
||||
- light.kitchen_under_cabinet
|
||||
- light.kitchen_island
|
||||
|
||||
# Use areas for room organization
|
||||
areas:
|
||||
- name: "Kitchen"
|
||||
entities:
|
||||
- light.kitchen_main
|
||||
- light.kitchen_under_cabinet
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Structure Redesign
|
||||
1. Define new data structures
|
||||
2. Create mapping from old to new
|
||||
3. Update function blocks
|
||||
|
||||
### Phase 2: Node-RED Update
|
||||
1. Update network variable mapping
|
||||
2. Add transformation functions
|
||||
3. Update MQTT topics
|
||||
|
||||
### Phase 3: Home Assistant Migration
|
||||
1. Create new entities with new structure
|
||||
2. Migrate automations
|
||||
3. Update dashboards
|
||||
|
||||
### Phase 4: Testing & Validation
|
||||
1. Test all control paths
|
||||
2. Verify status feedback
|
||||
3. Test HA integration
|
||||
|
||||
---
|
||||
|
||||
## Final Recommendation
|
||||
|
||||
**Use Option 4 (Hybrid Structure)** because:
|
||||
|
||||
1. ✅ **Best Organization**: Room-based in CODESYS, flat in HA
|
||||
2. ✅ **Scalability**: Easy to add lights to any room
|
||||
3. ✅ **Clarity**: Descriptive names (`kitchen_main` vs `l_1`)
|
||||
4. ✅ **Flexibility**: Can group by room, zone, or function
|
||||
5. ✅ **Efficiency**: Only define lights that exist
|
||||
6. ✅ **Maintainability**: Clear structure, easy to understand
|
||||
|
||||
**Key Improvements**:
|
||||
- Replace `l_1`, `l_2` with `main`, `secondary`, `task`, etc.
|
||||
- Use descriptive light IDs: `kitchen_main`, `master_bedroom_bedside`
|
||||
- Flatten structure in Node-RED for Home Assistant
|
||||
- Add metadata for better HA organization
|
||||
- Optimize network variables (only existing lights)
|
||||
|
||||
---
|
||||
|
||||
**Next Steps**:
|
||||
1. Review this analysis
|
||||
2. Choose structure option
|
||||
3. Plan migration
|
||||
4. Implement new structure
|
||||
5. Update Node-RED and HA
|
||||
Reference in New Issue
Block a user