# SIMPLIFIED CONFIGURATION FILE FOR sthome-ut8 DEVICE external_components: - source: type: local path: components # Path relative to this YAML file components: [ ads1115_int, ads1115_pol, tlc59208f_ext ] #, ads131m08 ] packages: - !include common/wifi.yaml substitutions: name: sthome-ut8 friendly_name: "sthome-ut8" esphome: name: "${name}" friendly_name: "${friendly_name}" on_boot: then: - lambda: |- ESP_LOGI("esphome", "Device booted"); delay(300); //id(tlc59208f_1)->test(); //id(tlc59208f_1)->serial_test(); # esp32: board: esp32dev cpu_frequency: 240MHz flash_size: 4MB framework: type: esp-idf #arduino # esp-idf debug: update_interval: 15s # Enable logging logger: level: VERY_VERBOSE initial_level: INFO logs: canbus: INFO i2c: DEBUG i2c.idf: DEBUG uart: INFO light: INFO sensor: INFO ds1307: INFO tlc59208f_ext: VERBOSE text_sensor: INFO ads1115.sensor: INFO ads1115_pol: DEBUG ads1115_pol.sensor: INFO ads1115_int: DEBUG ads1115_int.sensor: INFO modbus: INFO modbus_controller: INFO modbus_controller.sensor: INFO # Enable Home Assistant API api: encryption: key: "lcdZmQW414LxtbHNpPpQkM1AyDnCKEYsGSy2c4TlodU=" ota: - platform: esphome password: "0f2e92e0c8764309d5de28191914f0ff" wifi: power_save_mode: none manual_ip: static_ip: 10.0.2.8 # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "${name} Fallback Hotspot" password: "h7BEJBrnZKSQ" captive_portal: spi: - id: spi_bus0 clk_pin: GPIO18 mosi_pin: GPIO23 miso_pin: GPIO19 interface: any time: # - platform: ds1307 # update_interval: never - platform: homeassistant id: time_source # on_time_sync: # - ds1307.write_time: # - lambda: |- # id(time_synched) = true; # id(init_holidays).execute(); // we need valid time to calculate holidays # // id(show_schedule).execute(); // for debugging # - logger.log: "Synchronized system clock" # tlc59208f_ext: address: 0x20 id: tlc59208f_1 i2c_id: bus_b reset_pin: number: GPIO25 mode: output: true pullup: true #interval: # - interval: 5s # then: # - lambda: |- # id(tlc59208f_1)->test(); binary_sensor: - platform: status # Status platform provides a connectivity sensor name: "Status" device_class: connectivity switch: - platform: restart name: "${name} Restart" id: "restart_switch" i2c: - id: bus_a sda: GPIO21 scl: GPIO22 scan: true frequency: 400kHz - id: bus_b sda: GPIO16 scl: GPIO17 scan: true frequency: 20kHz sda_pullup_enabled: true scl_pullup_enabled: true ads1115_int: - address: 0x4A id: ads1115_4A i2c_id: bus_a interleaved_mode: true continuous_mode: false alert_rdy_pin: number: GPIO27 mode: input: true pullup: false - address: 0x49 id: ads1115_49 i2c_id: bus_a interleaved_mode: true continuous_mode: false alert_rdy_pin: number: GPIO5 mode: input: true pullup: false - address: 0x48 id: ads1115_48 i2c_id: bus_a interleaved_mode: true continuous_mode: false alert_rdy_pin: number: GPIO3 mode: input: true pullup: false # external 10k pullup on ads1115 dev board sensor: - platform: debug loop_time: name: "Loop Time" # NB! Keep all ads1115 sample rates the same. Update intervals should be more than or equal to 1/sample_rate # ads1115_48 - platform: ads1115_int multiplexer: 'A0_A1' gain: 2.048 # 4.096 ads1115_id: ads1115_48 sample_rate: 860 # 475 #860 state_class: measurement device_class: current accuracy_decimals: 8 name: "ADC House Current" id: power_outlets_current unit_of_measurement: "A" icon: "mdi:current" - platform: ads1115_int multiplexer: 'A2_A3' gain: 2.048 # 4.096 ads1115_id: ads1115_48 name: "ADC Geyser Current" id: geyser_current sample_rate: 860 #860 state_class: measurement device_class: current accuracy_decimals: 8 unit_of_measurement: "A" icon: "mdi:current" filters: - lambda: return x * x; - sliding_window_moving_average: window_size: 625 #1250 #5000 send_every: 104 #208 #416 send_first_at: 104 #208 #416 - lambda: return sqrt(x); - multiply: 100 #92.1 #91.1 #88.44 - offset: 0.0 #-0.2 # - lambda: |- # if(abs(x) < 0.1) # return 0.0; # return x; on_value: then: - lambda: |- id(set_indicators).execute(0.0, x); on_value_range: - below: 5.0 then: - lambda: |- ESP_LOGI("geyser", "No geyser current detected. Geyser not heating."); - above: 5.0 then: - lambda: |- ESP_LOGI("geyser", "Geyser current detected. Geyser was energised."); # ads1115_49 - platform: ads1115_int multiplexer: 'A2_A3' gain: 2.048 # 4.096 ads1115_id: ads1115_49 name: "ADC Mains Current" id: mains_current sample_rate: 860 #475 state_class: measurement device_class: current accuracy_decimals: 8 unit_of_measurement: "A" icon: "mdi:current" - platform: ads1115_int multiplexer: A0_A1 gain: 2.048 # 4.096 ads1115_id: ads1115_49 name: "ADC Lights Current" id: lights_current sample_rate: 860 # update_interval: 10ms # id: lights_current_adc state_class: measurement device_class: current accuracy_decimals: 8 # mod ########################### unit_of_measurement: "A" icon: "mdi:current" filters: - lambda: return x * x; - sliding_window_moving_average: window_size: 625 #1250 #5000 send_every: 104 #208 #416 send_first_at: 104 #208 #416 - lambda: return sqrt(x); - multiply: 100 #92.1 #91.1 #88.44 - offset: 0.0 #-0.2 # - lambda: |- # if(abs(x) < 0.1) # return 0.0; # return x; # ads1115_4A # Inverter voltage sensor - platform: ads1115_int ads1115_id: ads1115_4A sample_rate: 860 name: "ADC Mains Voltage" id: mains_voltage_adc unit_of_measurement: "V" accuracy_decimals: 8 icon: "mdi:flash" multiplexer: A0_GND gain: 2.048 # 4.096 #update_interval: 8ms #5ms #23ms device_class: voltage state_class: measurement # filters: # - offset: -2.048 #-2.04794027 # 0.0131 # - lambda: return x * x; # - sliding_window_moving_average: # window_size: 1250 #1250 # send_every: 208 # send_first_at: 208 # - lambda: return sqrt(x); # - multiply: 766.6670 # 930 #650 #- lambda: |- # if(abs(x) < 10) # return 0; # return x;# # ads1115_4A # Mains voltage sensor - platform: ads1115_int ads1115_id: ads1115_4A sample_rate: 860 name: "ADC House Voltage" id: inverter_output_voltage_adc unit_of_measurement: "V" accuracy_decimals: 8 icon: "mdi:flash" multiplexer: A2_GND gain: 2.048 # 4.096 #update_interval: 8ms #5ms #23ms device_class: voltage state_class: measurement # filters: # - offset: -2.048 #-2.0491 #4.096 #0.0065 # - lambda: return x * x; # - sliding_window_moving_average: # window_size: 1250 #625 #1250 # send_every: 208 #104 # send_first_at: 208 #104 #416 # - lambda: return sqrt(x); # - multiply: 766.6670 # 930 #650 #- lambda: |- # if(abs(x) < 20) # return 0; # return x; - platform: ads1115_int ads1115_id: ads1115_4A sample_rate: 860 name: "ADC Spare1 Voltage" unit_of_measurement: "V" accuracy_decimals: 8 icon: "mdi:flash" multiplexer: A1_GND gain: 2.048 # 4.096 #update_interval: 8ms #5ms #23ms device_class: voltage state_class: measurement - platform: ads1115_int ads1115_id: ads1115_4A sample_rate: 860 name: "ADC Spare2 Voltage" unit_of_measurement: "V" accuracy_decimals: 8 icon: "mdi:flash" multiplexer: A3_GND gain: 2.048 # 4.096 #update_interval: 8ms #5ms #23ms device_class: voltage state_class: measurement # Report wifi signal strength every 5 min if changed - platform: wifi_signal name: WiFi Signal update_interval: 300s filters: - delta: 10% # human readable uptime sensor output to the text sensor above - platform: uptime name: Uptime in Days id: uptime_sensor_days update_interval: 10s on_raw_value: then: - text_sensor.template.publish: id: uptime_human state: !lambda |- int seconds = round(id(uptime_sensor_days).raw_state); int days = seconds / (24 * 3600); seconds = seconds % (24 * 3600); int hours = seconds / 3600; seconds = seconds % 3600; int minutes = seconds / 60; seconds = seconds % 60; auto days_str = std::to_string(days); auto hours_str = std::to_string(hours); auto minutes_str = std::to_string(minutes); auto seconds_str = std::to_string(seconds); return ( (days ? days_str + "d " : "") + (hours ? hours_str + "h " : "") + (minutes ? minutes_str + "m " : "") + (seconds_str + "s") ).c_str(); output: - platform: ledc pin: number: GPIO12 #GPIO26 # LED_LOW_BAT inverted: false #true id: led_inverter_battery_low - platform: tlc59208f_ext channel: 0 tlc59208f_id: 'tlc59208f_1' id: led0 - platform: tlc59208f_ext channel: 1 tlc59208f_id: 'tlc59208f_1' id: led1 - platform: tlc59208f_ext channel: 2 tlc59208f_id: 'tlc59208f_1' id: led2 - platform: tlc59208f_ext channel: 3 tlc59208f_id: 'tlc59208f_1' id: led3 - platform: tlc59208f_ext channel: 4 tlc59208f_id: 'tlc59208f_1' id: led4 - platform: tlc59208f_ext channel: 5 tlc59208f_id: 'tlc59208f_1' id: led5 - platform: tlc59208f_ext channel: 6 tlc59208f_id: 'tlc59208f_1' id: led6 - platform: tlc59208f_ext channel: 7 tlc59208f_id: 'tlc59208f_1' id: led7 light: - platform: monochromatic output: led0 name: "LED Geyser Temperature 0" id: led_geyser_temp0 default_transition_length: 20ms - platform: monochromatic output: led1 name: "LED Geyser Temperature 1" id: led_geyser_temp1 default_transition_length: 20ms - platform: monochromatic output: led2 name: "LED Geyser Temperature 2" id: led_geyser_temp2 default_transition_length: 20ms - platform: monochromatic output: led3 name: "LED Geyser Temperature 3" id: led_geyser_temp3 default_transition_length: 20ms - platform: monochromatic output: led4 name: "LED Geyser Temperature 4" id: led_geyser_temp4 default_transition_length: 20ms - platform: monochromatic output: led5 name: "LED Geyser Temperature 5" id: led_geyser_temp5 default_transition_length: 20ms - platform: monochromatic output: led6 name: "LED Geyser Temperature 6" id: led_geyser_temp6 default_transition_length: 20ms - platform: monochromatic output: led7 name: "LED Geyser Temperature 7" id: led_geyser_temp7 default_transition_length: 20ms text_sensor: - platform: debug device: name: "Device Info" reset_reason: name: "Reset Reason" - platform: template name: Uptime id: uptime_human icon: mdi:clock-start # Expose WiFi information as sensors - platform: wifi_info ip_address: name: IP mac_address: name: Mac Address script: - id: set_indicators parameters: low_value: double high_value: double then: - lambda: |- double led_on = 1.0; int led_count = 8; double min_value = 0.7; double max_value = 0.8; if(low_value < min_value) { low_value = min_value; } double step_size = (max_value - min_value) / led_count; double bottom_point = (low_value - min_value) / step_size; int led_bot = static_cast(std::trunc(bottom_point)); double led_bot_int = 1.0 + led_bot - bottom_point; double top_point = (high_value - min_value) / step_size; int led_top = static_cast(std::trunc(top_point)); double led_top_int = top_point - led_top; double led_0 = 0; double led_1 = 0; double led_2 = 0; double led_3 = 0; double led_4 = 0; double led_5 = 0; double led_6 = 0; double led_7 = 0; if (led_top == 0) led_0 = led_top_int * led_on; if (led_top == 1) led_1 = led_top_int * led_on; if (led_top == 2) led_2 = led_top_int * led_on; if (led_top == 3) led_3 = led_top_int * led_on; if (led_top == 4) led_4 = led_top_int * led_on; if (led_top == 5) led_5 = led_top_int * led_on; if (led_top == 6) led_6 = led_top_int * led_on; if (led_top == 7) led_7 = led_top_int * led_on; if (led_bot == 0) { led_0 = led_bot_int * led_on; if (led_top > 1) led_1 = led_on; if (led_top > 2) led_2 = led_on; if (led_top > 3) led_3 = led_on; if (led_top > 4) led_4 = led_on; if (led_top > 5) led_5 = led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 1) { led_1 = led_bot_int * led_on; if (led_top > 2) led_2 = led_on; if (led_top > 3) led_3 = led_on; if (led_top > 4) led_4 = led_on; if (led_top > 5) led_5 = led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 2) { led_2 = led_bot_int * led_on; if (led_top > 3) led_3 = led_on; if (led_top > 4) led_4 = led_on; if (led_top > 5) led_5 = led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 3) { led_3 = led_bot_int * led_on; if (led_top > 4) led_4 = led_on; if (led_top > 5) led_5 = led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 4) { led_4 = led_bot_int * led_on; if (led_top > 5) led_5 = led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 5) { led_5 = led_bot_int * led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 6) { led_6 = led_bot_int * led_on; if (led_top > 6) led_6 = led_on; if (led_top > 7) led_7 = led_on; } if (led_bot == 7) { led_7 = led_bot_int * led_on; if (led_top > 7) led_7 = 1; } id(led_geyser_temp0).turn_on().set_brightness(led_0).perform(); id(led_geyser_temp1).turn_on().set_brightness(led_1).perform(); id(led_geyser_temp2).turn_on().set_brightness(led_2).perform(); id(led_geyser_temp3).turn_on().set_brightness(led_3).perform(); id(led_geyser_temp4).turn_on().set_brightness(led_4).perform(); id(led_geyser_temp5).turn_on().set_brightness(led_5).perform(); id(led_geyser_temp6).turn_on().set_brightness(led_6).perform(); id(led_geyser_temp7).turn_on().set_brightness(led_7).perform(); //ESP_LOGI("geyser","bot: %f, top: %f 0: %0.2f 1: %0.2f 2: %0.2f 3: %0.2f 4: %0.2f 5: %0.2f 6: %0.2f 7: %0.2f ", low_value, high_value, led_0, led_1, led_2, led_3, led_4, led_5, led_6, led_7);