--- title: 'Node-RED: вентиляция по CO₂' tags: - family - home - automation - nodered - ventilation updated: '2026-05-17' --- Node-RED flow для управления вентиляцией по данным CO₂ датчиков. ## Структура ``` [room demand msgs] ↓ (1) Demand Aggregator ↓ (2) Intake Allocation ↓ (3) Discretization per damper ↓ (4) Intake Damper Outputs ↓ (5) Exhaust Arbitration ↓ (6) Exhaust Dampers ↓ (7) Exhaust Fans ↓ (8) Kitchen Hood ``` ## 1. Demand Aggregator (stateful) ```js let demands = flow.get("room_demands") || {}; demands[msg.room] = msg.raw_demand; flow.set("room_demands", demands); msg.demands = demands; return msg; ``` ## 2. Intake Allocation Комнаты с intake дамперами: bedroom, kids, living. Приоритеты: living = 1.2, остальные = 1.0. ```js const ROOMS = ["bedroom", "kids", "living"]; const PRIORITY = { bedroom: 1.0, kids: 1.0, living: 1.2 }; let weighted = {}, sum = 0; for (let r of ROOMS) { let d = msg.demands[r] || 0; weighted[r] = d * (PRIORITY[r] || 1); sum += weighted[r]; } if (sum === 0) return null; let allocation = {}; for (let r of ROOMS) { allocation[r] = 100 * weighted[r] / sum; } msg.intake_pct = allocation; return msg; ``` ## 3. Discretization **Bedroom/Kids** (0 / 33 / 66 / 100): ```js function snap(x) { if (x < 10) return 0; if (x < 33) return 33; if (x < 66) return 66; return 100; } msg.payload = snap(msg.payload); return msg; ``` **Living (dual-damper)**: ```js let p = msg.payload; let A = 0, B = 0; if (p < 10) { A=0; B=0; } else if (p < 30) { A=66; B=0; } else if (p < 55) { A=66; B=66; } else if (p < 80) { A=100; B=66; } else { A=100; B=100; } msg.damperA = A; msg.damperB = B; return msg; ``` ## 5. Exhaust Arbitration ```js let d = msg.demands; msg.exhaust = { at2_1: Math.max(d.toilet || 0, d.shower || 0, d.kitchen || 0), at2_2: Math.max(d.bathroom || 0, d.office || 0) }; return msg; ``` ## 7. Fan Speed ```js function speed(d) { if (d < 5) return 30; if (d < 20) return 50; if (d < 40) return 70; return 100; } msg.payload = speed(msg.payload); return msg; ``` ## 8. Kitchen Hood (3-speed) ```js let d = msg.demands.kitchen || 0; if (d < 10) msg.payload = 0; else if (d < 30) msg.payload = 1; else if (d < 60) msg.payload = 2; else msg.payload = 3; return msg; ``` Gate: current_state (manual override → block automation). Все дамперы: rate-limit 1 msg / 30–60 s. ## Связанные заметки - [[family/how-to/home-automation]] — общая автоматизация дома