Files
obsidian-vault/family/how-to/nodered-ventilation.md
T
2026-05-30 10:03:30 +00:00

135 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 / 3060 s.
## Связанные заметки
- [[family/how-to/home-automation]] — общая автоматизация дома