From 7d1b1e9efb888808a476766093d3c93a07c9f3a8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 2 Dec 2024 15:26:00 +0000 Subject: [PATCH] Add kitchen unit Runs the underfloor heating and humidity sensor above the cooker (which will be used to trigger the extractor fan) --- kitchen.yaml | 270 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 kitchen.yaml diff --git a/kitchen.yaml b/kitchen.yaml new file mode 100644 index 0000000..177e945 --- /dev/null +++ b/kitchen.yaml @@ -0,0 +1,270 @@ +# +# https://www.aliexpress.com/item/1005004099215436.html +# +# GPIO23: Onboard blue LED (used to show MQTT connectivity) +# GPIO16: Onboard relay (UFH) +# GPIO25: Used as output for NTC bridge +# GPIO32: ADC, midpoint of NTC bridge +# GPIO33: DHT22 for cooker humidity/temp +# +# The underfloor heating NTC thermistor is connected as follows: +# +# GPIO25 (3.3v) +# | +# ▯ 10 kΩ fixed resistor +# | +# --- GPIO32 (ADC) +# | +# ▯ 10 kΩ NTC under floor +# | +# ⏚ GND +# +# Rather than leaving current flowing through the thermistor at all times and +# potentially introducing errors by warming it up, we only turn GPIO25 on +# when it's time to take a reading. +# +# So we disable the periodic measurement on the ADC sensor, then periodically +# turn on GPIO25, trigger *three* readings a second apart, and turn GPIO25 off +# again. The ADC sensor has a filter to average the three readings. + +substitutions: + name: kitchen + room_name: "Kitchen" + domo_ufh: "916" + domo_temp: "917" + domo_thresh: "915" + +esphome: + name: ${name} + +esp32: + board: esp32-gateway + framework: + type: esp-idf + +packages: + base: !include base.yaml + +wifi: + power_save_mode: none + networks: + - ssid: !secret wifi_ssid + password: !secret wifi_pw + bssid: !secret wndr3800_bssid + priority: 1 + +script: + - id: back_to_auto + mode: restart + then: + - delay: 30 min + - climate.control: + id: ntc_climate + mode: HEAT + +time: + - platform: sntp + on_time: + - seconds: 0 + minutes: 0 + hours: 6 + then: + climate.control: + id: ntc_climate + mode: HEAT + target_temperature: 21°C + + - seconds: 0 + minutes: 30 + hours: 09 + then: + climate.control: + id: ntc_climate + mode: HEAT + target_temperature: 10°C + +mqtt: + on_connect: + then: + - light.turn_on: blue_led + - delay: 2s # Too soon and the first messages don't get through! + - lambda: |- + id(tell_domo_nvalue)->execute(${domo_ufh}, id(ufh_relay).state); + id(tell_domo_svalue)->execute(${domo_thresh}, + std::to_string(id(ntc_climate).target_temperature)); + + on_disconnect: + then: + - light.turn_off: blue_led + + on_json_message: + - topic: domoticz/out + then: + - lambda: |- + int idx = x["idx"]; + int nvalue = x["nvalue"].as(); + + // ESP_LOGD("on_json_message", x["name"]); + switch (idx) { + case ${domo_ufh}: /* UFH relay */ + if (nvalue) { + id(ufh_relay).turn_on(); + } else { + id(ufh_relay).turn_off(); + } + { + auto offcall = id(ntc_climate).make_call(); + offcall.set_mode("OFF"); + offcall.perform(); + } + id(back_to_auto).execute(); + break; + + case ${domo_thresh}: /* Temperature setpoint */ + double temp = x["svalue1"].as(); + auto call = id(ntc_climate).make_call(); + call.set_mode("HEAT"); + call.set_target_temperature(temp); + call.perform(); + ESP_LOGD("mqtt", "Got temp_setpoint %f", temp); + break; + } + +light: + - platform: status_led + pin: GPIO23 + id: blue_led + restore_mode: ALWAYS_OFF + +switch: + - platform: gpio + id: ntc_vcc + pin: GPIO25 + restore_mode: ALWAYS_OFF + + - platform: gpio + name: "Kitchen UFH" + id: ufh_relay + pin: GPIO16 + restore_mode: ALWAYS_OFF + on_turn_on: + then: + - lambda: |- + id(tell_domo_nvalue)->execute(${domo_ufh}, 1); + on_turn_off: + then: + - lambda: |- + id(tell_domo_nvalue)->execute(${domo_ufh}, 0); + +sensor: + - platform: dht + pin: + number: GPIO33 + mode: + input: true + pullup: true + model: DHT22 + temperature: + name: "${room_name} Temperature" + humidity: + name: "${room_name} Humidity" + update_interval: 10s + + - platform: ntc + id: ntc_temperature + sensor: ntc_resistance + calibration: + # Hiwell E91.716 gives these in detail. The SunStone Touchstat manual just says + # "10kΩ at 25°C, 12.1kΩ at 20°C, 14.7kΩ at 15°C, which looks basically the same. + # ESPHome only wants three. + # - 22.0706 kOhm -> 5°C + # - 17.9600 kOhm -> 10°C + # - 14.6962 kOhm -> 15°C + # - 12.0911 kOhm -> 20°C + # - 10.0000 kOhm -> 25°C + # - 8.3124 kOhm -> 30°C + # - 6.9434 kOhm -> 35°C + # - 5.82525 kOhm -> 40°C + # Actual readings from SunStone Touchstat + - 15.0 kOhm -> 13.9°C +# - 12.55 kOhm - > 17.6°C + - 12.30 kOhm -> 18.2°C + - 9.97 kOhm -> 23.5°C + filters: + - exponential_moving_average: + send_every: 1 + send_first_at: 1 + - clamp: + min_value: 5 + max_value: 35 + ignore_out_of_range: true + on_value: + then: + lambda: |- + if (!isnan(x)) + id(tell_domo_svalue)->execute(${domo_temp}, std::to_string(x)); + + - platform: resistance + id: ntc_resistance + sensor: ntc_adc + reference_voltage: 3.28v # measured + resistor: 9.97 kOhm + configuration: DOWNSTREAM + filters: + - median: + window_size: 5 + send_every: 5 + send_first_at: 5 + + - platform: adc + id: ntc_adc + attenuation: 12dB + update_interval: never + pin: GPIO32 + filters: + - multiply: 0.987 # Calibrated vs. multimeter + # 0.80 -> 0.78 + # 2.52 -> 2.49 + # 1.99 -> 1.96 + +climate: + - platform: thermostat + id: ntc_climate + name: "Kitchen floor" + sensor: ntc_temperature + min_heating_off_time: 300s + min_heating_run_time: 300s + min_idle_time: 30s + heat_deadband: 0.2°C + heat_action: + - switch.turn_on: ufh_relay + idle_action: + - switch.turn_off: ufh_relay + on_control: + - lambda: |- + auto temp = x.get_target_temperature(); + if (temp && temp.value() != id(ntc_climate).target_temperature) { + ESP_LOGI("CLIMATE", "on_control, set target %f to %f", + id(ntc_climate).target_temperature, temp.value()); + id(tell_domo_svalue)->execute(${domo_thresh}, + std::to_string(temp.value())); + } + + +interval: + - interval: 60s + then: + - switch.turn_on: ntc_vcc + - delay: 1s + - component.update: ntc_adc + - delay: 0.5s + - component.update: ntc_adc + - delay: 0.5s + - component.update: ntc_adc + - delay: 0.5s + - component.update: ntc_adc + - delay: 0.5s + - component.update: ntc_adc + - switch.turn_off: ntc_vcc + + -- 2.49.0