--- /dev/null
+#
+# https://www.aliexpress.com/item/1005004099215436.html
+#
+# GPIO23: Onboard blue LED (used to show MQTT connectivity)
+# GPIO16: Onboard relay (bathroom fan)
+# GPIO13: DHT22
+
+esphome:
+ name: bathroom
+
+esp32:
+ board: esp32-gateway
+ framework:
+ type: arduino
+
+# Enable logging
+logger:
+ level: DEBUG
+
+ota:
+ password: !secret ota_upgrade_pw
+
+external_components:
+ - source:
+ type: local
+ path: ../git/esphome_syslog/components
+ components: [syslog]
+
+wifi:
+ 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: '50.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(522, id(fan_relay).state);
+ id(tell_domo_svalue)->execute(523, 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 522: /* 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 523: /* Humidity threshold */
+ id(hum_threshold) = x["svalue"].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(522, 1);
+ id(relay_off_time) = 0;
+ on_turn_off:
+ then:
+ - lambda: |-
+ id(tell_domo_nvalue)->execute(522, 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(521, 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(520, x, hum_stat);
+ update_interval: 10s