domo_hum: "520"
domo_temp: "521"
domo_thresh: "902"
+ room_name: "Bathroom"
esphome:
name: bathroom
framework:
type: esp-idf
-# Enable logging
-logger:
- level: DEBUG
-
-ota:
- platform: esphome
- password: !secret ota_upgrade_pw
-
-external_components:
- - source:
- type: local
- path: ../git/esphome_syslog/components
- components: [syslog]
+packages:
+ base: !include base.yaml
+ hum: !include humidity.yaml
wifi:
- power_save_mode: none
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_pw
bssid: !secret wndr3800_bssid
priority: 1
- - ssid: !secret wifi_ssid
- password: !secret wifi_pw
-
-script:
- # Publish a value to Domoticz as an nvalue
- - id: tell_domo_nvalue
- mode: queued
- parameters:
- udevice: int
- nvalue: int
- then:
- lambda: |-
- id(mqtt_client).publish_json("domoticz/in", [=](JsonObject root) {
- root["command"] = "udevice";
- root["idx"] = udevice;
- root["nvalue"] = nvalue;
- });
-
- # Publish a value to Domoticz as an svalue
- - id: tell_domo_svalue
- mode: queued
- parameters:
- udevice: int
- svalue: string
- then:
- lambda: |-
- id(mqtt_client).publish_json("domoticz/in", [=](JsonObject root) {
- root["command"] = "udevice";
- root["idx"] = udevice;
- root["svalue"] = svalue;
- });
-
- # Publishto Domoticz as nvalue and svalues
- - id: tell_domo_nsvalues
- mode: queued
- parameters:
- udevice: int
- nvalue: int
- svalue: string
- then:
- lambda: |-
- id(mqtt_client).publish_json("domoticz/in", [=](JsonObject root) {
- root["command"] = "udevice";
- root["idx"] = udevice;
- root["nvalue"] = nvalue;
- root["svalue"] = svalue;
- });
-
-# # Enable fallback hotspot (captive portal) in case wifi connection fails
-# ap:
-# ssid: "Pool Fallback Hotspot"
-# password: "JWWHJb38UzxY"
-#
-# manual_ip: !include poolup.yaml
-#
-#captive_portal:
-
-syslog:
- ip_address: !secret syslog_ip
-
-globals:
- - id: relay_off_time
- type: time_t
- initial_value: '0'
-
- - id: hum_threshold
- type: float
- initial_value: '70.0'
- restore_value: true
-
- - id: fan_delay
- type: int
- initial_value: '600'
- restore_value: true
-
-time:
- - platform: sntp
- id: sntp_time
- servers: !secret ntp_servers
- on_time:
- - seconds: /5
- then:
- lambda: |-
- //ESP_LOGD("time", "off time %ld", (long)id(relay_off_time));
- if (id(relay_off_time) && id(relay_off_time) < ::time(NULL)) {
- id(fan_relay).turn_off();
- }
-
-
-network:
- enable_ipv6: true
-
-mqtt:
- broker: !secret mqtt_server
- port: 1884
- discovery_prefix: ${mqtt_prefix}/homeassistant
- log_topic: ${mqtt_prefix}/logs
- username: "pool"
- password: !secret pool_mqtt_pw
- id: mqtt_client
- 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_fan}, id(fan_relay).state);
- id(tell_domo_nsvalues)->execute(${domo_thresh}, 2, std::to_string(id(hum_threshold)));
-
- 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<int>();
-
- // ESP_LOGD("on_json_message", x["name"]);
- switch (idx) {
- case ${domo_fan}: /* Fan relay */
- if (nvalue) {
- id(fan_relay).turn_on();
- id(relay_off_time) = ::time(NULL) + id(fan_delay);
- } else {
- id(fan_relay).turn_off();
- }
- break;
-
- case ${domo_thresh}: /* Humidity threshold */
- id(hum_threshold) = x["svalue1"].as<float>();
- ESP_LOGD("mqtt", "Got hum_threshold %f", id(hum_threshold));
- break;
- }
-
-
-light:
- - platform: binary
- name: "Blue LED"
- id: blue_led
- output: led_output
-
-output:
- - id: led_output
- platform: gpio
- pin: GPIO23
-
-switch:
- - platform: gpio
- name: "Fan"
- id: fan_relay
- pin: GPIO16
- on_turn_on:
- then:
- - lambda: |-
- id(tell_domo_nvalue)->execute(${domo_fan}, 1);
- id(relay_off_time) = 0;
- on_turn_off:
- then:
- - lambda: |-
- id(tell_domo_nvalue)->execute(${domo_fan}, 0);
- id(relay_off_time) = 0;
-
-sensor:
- - platform: dht
- pin: GPIO13
- model: DHT22
- temperature:
- name: "Bathroom Temperature"
- on_value:
- then:
- lambda: |-
- if (!isnan(x))
- id(tell_domo_svalue)->execute(${domo_temp}, std::to_string(x));
- humidity:
- name: "Bathroom Humidity"
- on_value:
- then:
- lambda: |-
- const char *hum_stat;
- if (x > id(hum_threshold)) {
- id(fan_relay).turn_on();
- id(relay_off_time) = ::time(NULL) + id(fan_delay);
- hum_stat = "3"; // Wet
- } else {
- hum_stat = "2"; // Dry
- }
- if (!isnan(x))
- id(tell_domo_nsvalues)->execute(${domo_hum}, x, hum_stat);
- update_interval: 10s
--- /dev/null
+# Humidity-based fan/mirror controllers in both toilet and bathroom are
+#
+# https://www.aliexpress.com/item/1005004099215436.html
+#
+# GPIO23: Onboard blue LED (used to show MQTT connectivity)
+# GPIO16: Onboard relay (toilet fan)
+# GPIO13: DHT22
+
+globals:
+ - id: relay_off_time
+ type: time_t
+ initial_value: '0'
+
+ - id: hum_threshold
+ type: float
+ initial_value: '70.0'
+ restore_value: true
+
+ - id: fan_delay
+ type: int
+ initial_value: '600'
+ restore_value: true
+
+
+time:
+ - platform: sntp
+ on_time:
+ - seconds: /5
+ then:
+ lambda: |-
+ //ESP_LOGD("time", "off time %ld", (long)id(relay_off_time));
+ if (id(relay_off_time) && id(relay_off_time) < ::time(NULL)) {
+ id(fan_relay).turn_off();
+ }
+
+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_fan}, id(fan_relay).state);
+ id(tell_domo_nsvalues)->execute(${domo_thresh}, 2, std::to_string(id(hum_threshold)));
+
+ 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<int>();
+
+ // ESP_LOGD("on_json_message", x["name"]);
+ switch (idx) {
+ case ${domo_fan}: /* Fan relay */
+ if (nvalue) {
+ id(fan_relay).turn_on();
+ id(relay_off_time) = ::time(NULL) + id(fan_delay);
+ } else {
+ id(fan_relay).turn_off();
+ }
+ break;
+
+ case ${domo_thresh}: /* Humidity threshold */
+ id(hum_threshold) = x["svalue1"].as<float>();
+ ESP_LOGD("mqtt", "Got hum_threshold %f", id(hum_threshold));
+ break;
+ }
+
+
+light:
+ - platform: binary
+ name: "Blue LED"
+ id: blue_led
+ output: led_output
+
+output:
+ - id: led_output
+ platform: gpio
+ pin: GPIO23
+
+switch:
+ - platform: gpio
+ name: "Fan"
+ id: fan_relay
+ pin: GPIO16
+ on_turn_on:
+ then:
+ - lambda: |-
+ id(tell_domo_nvalue)->execute(${domo_fan}, 1);
+ id(relay_off_time) = 0;
+ on_turn_off:
+ then:
+ - lambda: |-
+ id(tell_domo_nvalue)->execute(${domo_fan}, 0);
+ id(relay_off_time) = 0;
+
+sensor:
+ - platform: dht
+ pin: GPIO13
+ model: DHT22
+ temperature:
+ name: "${room_name} Temperature"
+ on_value:
+ then:
+ lambda: |-
+ if (!isnan(x))
+ id(tell_domo_svalue)->execute(${domo_temp}, std::to_string(x));
+ humidity:
+ name: "${room_name} Humidity"
+ on_value:
+ then:
+ lambda: |-
+ const char *hum_stat;
+ if (x > id(hum_threshold)) {
+ id(fan_relay).turn_on();
+ id(relay_off_time) = ::time(NULL) + id(fan_delay);
+ hum_stat = "3"; // Wet
+ } else {
+ hum_stat = "2"; // Dry
+ }
+ if (!isnan(x))
+ id(tell_domo_nsvalues)->execute(${domo_hum}, x, hum_stat);
+ update_interval: 10s
domo_hum: "898"
domo_temp: "899"
domo_thresh: "901"
+ room_name: "Toilet"
esphome:
name: toilet
framework:
type: esp-idf
-# Enable logging
-logger:
- level: DEBUG
-
-ota:
- platform: esphome
- password: !secret ota_upgrade_pw
-
-external_components:
- - source:
- type: local
- path: ../git/esphome_syslog/components
- components: [syslog]
+packages:
+ base: !include base.yaml
+ hum: !include humidity.yaml
wifi:
- power_save_mode: none
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_pw
bssid: !secret garden_bssid
priority: 1
- - ssid: !secret wifi_ssid
- password: !secret wifi_pw
-
-script:
- # Publish a value to Domoticz as an nvalue
- - id: tell_domo_nvalue
- mode: queued
- parameters:
- udevice: int
- nvalue: int
- then:
- lambda: |-
- id(mqtt_client).publish_json("domoticz/in", [=](JsonObject root) {
- root["command"] = "udevice";
- root["idx"] = udevice;
- root["nvalue"] = nvalue;
- });
-
- # Publish a value to Domoticz as an svalue
- - id: tell_domo_svalue
- mode: queued
- parameters:
- udevice: int
- svalue: string
- then:
- lambda: |-
- id(mqtt_client).publish_json("domoticz/in", [=](JsonObject root) {
- root["command"] = "udevice";
- root["idx"] = udevice;
- root["svalue"] = svalue;
- });
-
- # Publishto Domoticz as nvalue and svalues
- - id: tell_domo_nsvalues
- mode: queued
- parameters:
- udevice: int
- nvalue: int
- svalue: string
- then:
- lambda: |-
- id(mqtt_client).publish_json("domoticz/in", [=](JsonObject root) {
- root["command"] = "udevice";
- root["idx"] = udevice;
- root["nvalue"] = nvalue;
- root["svalue"] = svalue;
- });
-
-# # Enable fallback hotspot (captive portal) in case wifi connection fails
-# ap:
-# ssid: "Pool Fallback Hotspot"
-# password: "JWWHJb38UzxY"
-#
-# manual_ip: !include poolup.yaml
-#
-#captive_portal:
-
-syslog:
- ip_address: !secret syslog_ip
-
-globals:
- - id: relay_off_time
- type: time_t
- initial_value: '0'
-
- - id: hum_threshold
- type: float
- initial_value: '70.0'
- restore_value: true
-
- - id: fan_delay
- type: int
- initial_value: '600'
- restore_value: true
-
-time:
- - platform: sntp
- id: sntp_time
- servers: !secret ntp_servers
- on_time:
- - seconds: /5
- then:
- lambda: |-
- //ESP_LOGD("time", "off time %ld", (long)id(relay_off_time));
- if (id(relay_off_time) && id(relay_off_time) < ::time(NULL)) {
- id(fan_relay).turn_off();
- }
-
-
-network:
- enable_ipv6: true
-
-mqtt:
- broker: !secret mqtt_server
- port: 1884
- discovery_prefix: ${mqtt_prefix}/homeassistant
- log_topic: ${mqtt_prefix}/logs
- username: "pool"
- password: !secret pool_mqtt_pw
- id: mqtt_client
- 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_fan}, id(fan_relay).state);
- id(tell_domo_nsvalues)->execute(${domo_thresh}, 2, std::to_string(id(hum_threshold)));
-
- 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<int>();
-
- // ESP_LOGD("on_json_message", x["name"]);
- switch (idx) {
- case ${domo_fan}: /* Fan relay */
- if (nvalue) {
- id(fan_relay).turn_on();
- id(relay_off_time) = ::time(NULL) + id(fan_delay);
- } else {
- id(fan_relay).turn_off();
- }
- break;
-
- case ${domo_thresh}: /* Humidity threshold */
- id(hum_threshold) = x["svalue1"].as<float>();
- ESP_LOGD("mqtt", "Got hum_threshold %f", id(hum_threshold));
- break;
- }
-
-
-light:
- - platform: binary
- name: "Blue LED"
- id: blue_led
- output: led_output
-
-output:
- - id: led_output
- platform: gpio
- pin: GPIO23
-
-switch:
- - platform: gpio
- name: "Fan"
- id: fan_relay
- pin: GPIO16
- on_turn_on:
- then:
- - lambda: |-
- id(tell_domo_nvalue)->execute(${domo_fan}, 1);
- id(relay_off_time) = 0;
- on_turn_off:
- then:
- - lambda: |-
- id(tell_domo_nvalue)->execute(${domo_fan}, 0);
- id(relay_off_time) = 0;
-
-sensor:
- - platform: dht
- pin: GPIO13
- model: DHT22
- temperature:
- name: "Toilet Temperature"
- on_value:
- then:
- lambda: |-
- if (!isnan(x))
- id(tell_domo_svalue)->execute(${domo_temp}, std::to_string(x));
- humidity:
- name: "Toilet Humidity"
- on_value:
- then:
- lambda: |-
- const char *hum_stat;
- if (x > id(hum_threshold)) {
- id(fan_relay).turn_on();
- id(relay_off_time) = ::time(NULL) + id(fan_delay);
- hum_stat = "3"; // Wet
- } else {
- hum_stat = "2"; // Dry
- }
- if (!isnan(x))
- id(tell_domo_nsvalues)->execute(${domo_hum}, x, hum_stat);
- update_interval: 10s