-
Notifications
You must be signed in to change notification settings - Fork 0
/
schuurvocht-pwm.yaml
381 lines (361 loc) · 9.84 KB
/
schuurvocht-pwm.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
esphome:
name: schuurvocht
on_boot:
- output.set_level:
id: led_fan_on
level: .1
- output.set_level:
id: led_auto
level: .1
esp8266:
board: d1_mini
restore_from_flash: true
preferences:
flash_write_interval: 3600s
logger:
level: debug
captive_portal:
<<: !include secrets.yaml
substitutions:
interval: "4s" # the AM2302 will work with smaller intervals, but at <2s it will start to heat up and skew the results!
averaging: "4" # HASS output and outside measurement smoothing: averages over n samples and computes/sends every n samples
smoothing: "150" # fan speed will smoothed using a moving window average over this number × $interval
sensor_pin_outside: D7
sensor_pin_inside: D6
fan_pwm_pin: D2
fan_enable_pin: D3
fan_sense_pin: D1
fan_rpm_divider: "2"
led_status_pin: D4
led_auto_pin: D5
led_fan_on_pin: D0
status_led:
pin:
number: $led_status_pin
inverted: true
switch:
- platform: template
name: "Fan control enable"
id: enable_auto
icon: mdi:fan-auto
optimistic: true
restore_mode: RESTORE_DEFAULT_ON
on_turn_on:
then:
- lambda: |-
ESP_LOGI("schuur", "enable auto fan control");
- output.turn_on: led_auto
on_turn_off:
then:
- lambda: |-
ESP_LOGI("schuur", "disable auto fan control");
- output.turn_off: led_auto
- platform: template
name: "Keep fan on at min speed"
id: fan_on_at_min
icon: mdi:fan-remove
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
number:
- platform: template
name: "Max auto fan speed"
id: fan_auto_max
entity_category: config
icon: mdi:fan-plus
optimistic: true
min_value: 0
max_value: 100
restore_value: true
initial_value: 100
step: 1
- platform: template
name: "Min auto fan speed"
id: fan_auto_min
entity_category: config
icon: mdi:fan-minus
optimistic: true
min_value: 0
max_value: 100
restore_value: true
initial_value: 0
step: 1
- platform: template
name: "RH diff for max speed"
id: fan_rh_speed_factor
entity_category: config
icon: mdi:fan-chevron-up
optimistic: true
min_value: 0
max_value: 100
restore_value: true
initial_value: 30
step: 1
- platform: template
name: "RH diff for min speed"
id: fan_min_rh_diff
entity_category: config
icon: mdi:fan-chevron-down
optimistic: true
min_value: 0
max_value: 100
restore_value: true
initial_value: 2
step: 1
- platform: template
name: "RH setpoint"
id: rh_setpoint
entity_category: config
icon: mdi:water-check
optimistic: true
min_value: 0
max_value: 100
restore_value: true
initial_value: 40
step: 1
- platform: template
name: "Temp buiten correctie"
id: out_t_correction
entity_category: config
icon: mdi:thermometer-plus
optimistic: true
min_value: -10
max_value: 10
restore_value: true
initial_value: 0
step: .1
- platform: template
name: "Temp binnen correctie"
id: in_t_correction
entity_category: config
icon: mdi:thermometer-plus
optimistic: true
min_value: -10
max_value: 10
restore_value: true
initial_value: 0
step: .1
fan:
- platform: speed
output: fan_pwm
name: "Schuur fan"
id: the_fan
on_speed_set:
sensor.template.publish:
id: fan_pwm_percent
state: !lambda |-
return id(the_fan).state ? id(the_fan).speed : 0;
on_turn_on:
- output.turn_on: led_fan_on
on_turn_off:
- output.turn_off: led_fan_on
output:
- platform: esp8266_pwm
pin:
number: $fan_pwm_pin
mode:
output: true
open_drain: true
frequency: 25000 Hz
id: fan_pwm
power_supply: fan_enable
- platform: esp8266_pwm
pin: $led_auto_pin
id: led_auto
frequency: 100 Hz
- platform: esp8266_pwm
pin: $led_fan_on_pin
id: led_fan_on
frequency: 100 Hz
power_supply:
- pin: $fan_enable_pin
id: fan_enable
enable_time: 1s
keep_on_time: 0s
globals:
- id: raw_in_t
type: double
- id: raw_in_rh
type: double
- id: raw_out_t
type: double
- id: raw_out_rh
type: double
- id: instant_desired_fan_speed
type: double
sensor:
- platform: wifi_signal
name: "Schuur WiFi RSSI"
id: wifi_rssi
update_interval: 10s
- platform: dht
pin: $sensor_pin_outside
model: AM2302
temperature:
name: "Temp buiten"
id: out_t
filters:
- median:
window_size: $averaging
send_every: $averaging
- lambda: return x + (float)id(out_t_correction).state;
on_raw_value:
then:
- lambda: id(raw_out_t) = x + (float)id(out_t_correction).state;
humidity:
name: "RH buiten"
id: out_rh
accuracy_decimals: 1
filters:
- median:
window_size: $averaging
send_every: $averaging
on_raw_value:
then:
- lambda: id(raw_out_rh) = x;
update_interval: $interval
- platform: dht
pin: $sensor_pin_inside
model: AM2302
temperature:
name: "Temp schuur"
id: in_t
filters:
- median:
window_size: $averaging
send_every: $averaging
- lambda: return x + (float)id(in_t_correction).state;
on_raw_value:
then:
- lambda: id(raw_in_t) = x + (float)id(in_t_correction).state;
humidity:
name: "RH schuur"
id: in_rh
accuracy_decimals: 1
filters:
- median:
window_size: $averaging
send_every: $averaging
on_raw_value:
then:
- lambda: id(raw_in_rh) = x;
- lambda: |-
auto t_i = id(raw_in_t);
auto rh_i = id(raw_in_rh);
auto m_i = 6.112 * exp((17.67*t_i)/(t_i+243.5))*rh_i*18.02 / ((273.15+t_i) * 100 * 0.08314);
auto t_o = id(raw_out_t);
auto rh_o = id(raw_out_rh);
auto m_o = 6.112 * exp((17.67*t_o)/(t_o+243.5))*rh_o*18.02 / ((273.15+t_o) * 100 * 0.08314);
auto rh_o_t_i = (m_o / ((t_i+273.15)/(t_o+273.15))) * exp(-(17.67*t_i)/(t_i+243.5))*(0.075487*t_i+20.6193);
id(in_m).publish_state(m_i);
id(out_m).publish_state(m_o);
id(out_rh_at_in_t).publish_state(rh_o_t_i);
update_interval: $interval
- platform: template
name: "Vochtgehalte schuur"
icon: mdi:water
id: in_m
unit_of_measurement: "g/m³"
accuracy_decimals: 2
filters:
- median:
window_size: $averaging
send_every: $averaging
- platform: template
name: "Vochtgehalte buiten"
icon: mdi:water
id: out_m
unit_of_measurement: "g/m³"
accuracy_decimals: 2
filters:
- median:
window_size: $averaging
send_every: $averaging
- platform: template
name: "RH buiten bij schuurtemperatuur"
icon: mdi:water-percent
id: out_rh_at_in_t
unit_of_measurement: "%"
filters:
- median:
window_size: $averaging
send_every: $averaging
on_value:
if:
condition:
switch.is_on: enable_auto
then:
- lambda: |-
auto fan_always_on = id(fan_on_at_min).state;
auto rh_in = id(raw_in_rh);
auto rh_couldbe = max(x, id(rh_setpoint).state);
if (isnan(rh_in) || isnan(rh_couldbe)) {
ESP_LOGD("schuur", "Input(s) NaN, skipping fan control");
return;
}
int min_speed = id(fan_auto_min).state;
int max_speed = id(fan_auto_max).state;
double rh_percent_for_max_speed = (double) id(fan_rh_speed_factor).state;
double rh_percent_for_min_speed = (double) id(fan_min_rh_diff).state;
double speed_frac = ((rh_in - rh_couldbe) - rh_percent_for_min_speed) / (rh_percent_for_max_speed - rh_percent_for_min_speed);
int desired_speed = round(min_speed + (max_speed - min_speed) * speed_frac);
if (desired_speed < min_speed) {
if (fan_always_on) {
desired_speed = min_speed;
} else {
desired_speed = 0;
}
}
desired_speed = min(max_speed, desired_speed);
ESP_LOGD("schuur", "Auto fan speed to %d%%", desired_speed);
id(instant_desired_fan_speed) = desired_speed;
- platform: template
id: smoothed_desired_fan_speed
internal: true
update_interval: $interval
lambda: return id(instant_desired_fan_speed);
filters:
- sliding_window_moving_average:
window_size: $smoothing
send_every: 1
on_value:
lambda: |-
auto call = (x > 0) ? id(the_fan).turn_on() : id(the_fan).turn_off();
call.set_speed(x);
call.perform();
- platform: template
id: fan_pwm_percent
icon: "mdi:fan"
name: "Schuur fan %"
unit_of_measurement: "%"
filters:
- median:
window_size: $averaging
send_every: $averaging
# Two options dependent on your fan's output:
# Option 1: Enable this part if your fan has an RPM output
# - platform: pulse_counter
# pin:
# number: $fan_sense_pin
# mode: INPUT_PULLUP
# id: fan_rpm
# icon: "mdi:fan"
# name: Schuur fan speed
# update_interval: $interval
# unit_of_measurement: "rpm"
# filters:
# - lambda: !lambda return x * 1.0/(double)($fan_rpm_divider);
# - median:
# window_size: $averaging
# send_every: $averaging
# Option 2: Enable this part if your fan has a 'locked rotor' output that is high when the fan rotor is stuck (e.g. failed bearing)
binary_sensor:
- platform: gpio
pin:
number: $fan_sense_pin
id: fan_locked_rotor
icon: "mdi:fan"
name: "Schuur fan locked rotor alarm"
filters:
- delayed_on_off: 1s
- lambda: !lambda |-
return id(the_fan).state && x;