substitutions: name: esphome-web-1dbf28 friendly_name: c3pico-therm-1dbf28 remote_sensor_entity_id: sensor.average_of_temperature_sensors esphome: name: ${name} friendly_name: ${friendly_name} min_version: 2024.6.0 name_add_mac_suffix: false project: name: esphome.web version: dev platformio_options: board_build.flash_mode: dio on_boot: priority: -100.0 then: - component.update: proxy_sensor esp32: board: esp32-c3-devkitm-1 framework: type: esp-idf # logger, api, ota, improv_serial, wifi, and web_server are in common.yaml packages: common: !include ../common/common.yaml wifi: output_power: 13 # output_power: 13 seems good for the lolin c3 pico i2c: sda: 8 scl: 10 scan: true id: bus_a frequency: 400kHz text_sensor: - platform: template id: message name: "Temperature data source" lambda: |- if ( id(connection_status).state && id(remote_sensor).state && (std::to_string(id(remote_sensor).state) != "nan") ) { return {"HA sensor"}; } else { return {"onboard sensor"}; } entity_category: diagnostic disabled_by_default: true update_interval: 60s # the if condition in the lambda above is probably *NOT* a good test if the sensor is connected and returning valid data. button: - platform: restart name: "Restart Device" disabled_by_default: true switch: - platform: gpio pin: number: 5 mode: output: true pullup: true name: "relay switch" id: relay_switch - platform: template id: onoff_switch lambda: |- if (tcc1->mode != 0) { return true; } else { return false; } turn_on_action: then: - logger.log: "onoff switch ON" - climate.control: id: tcc1 mode: HEAT turn_off_action: then: - logger.log: "onoff switch OFF" - climate.control: id: tcc1 mode: "OFF" binary_sensor: - platform: status name: "Connection status" id: connection_status disabled_by_default: true - platform: gpio pin: number: 4 mode: input: true pullup: true id: increase_temp on_press: then: - logger.log: "increase temp" - climate.control: id: tcc1 target_temperature: !lambda return id(tcc1).target_temperature + 1.0; - platform: gpio pin: number: 0 mode: input: true pullup: true id: decrease_temp on_press: then: - logger.log: "decrease temp" - climate.control: id: tcc1 target_temperature: !lambda return id(tcc1).target_temperature - 1.0; - platform: gpio pin: number: 1 inverted: true mode: input: true pullup: true id: onoff_button on_press: - switch.toggle: onoff_switch - platform: gpio pin: number: 2 inverted: true mode: input: true pullup: true id: cycle_button on_multi_click: - timing: - ON for at most 0.5s - OFF for at least 0.2s then: - script.execute: page_toggle_script - timing: - ON for at least 1.5s then: - script.execute: preset_cycle_script script: - id: preset_cycle_script then: - climate.control: id: tcc1 preset: !lambda |- switch (id(tcc1).preset.value()) { case CLIMATE_PRESET_HOME: return CLIMATE_PRESET_SLEEP; case CLIMATE_PRESET_SLEEP: return CLIMATE_PRESET_AWAY; case CLIMATE_PRESET_AWAY: return CLIMATE_PRESET_ECO; case CLIMATE_PRESET_ECO: return CLIMATE_PRESET_HOME; default: return CLIMATE_PRESET_HOME; } - id: page_toggle_script then: - display.page.show_next: my_display - component.update: my_display sensor: - platform: shtcx id: shtcx_sensor address: 0x70 temperature: id: onboard_sensor name: "Temperature" humidity: id: shtcx_hum name: "Humidity" update_interval: 60s - platform: homeassistant id: remote_sensor unit_of_measurement: "°C" device_class: "temperature" state_class: "measurement" accuracy_decimals: 3 entity_id: ${remote_sensor_entity_id} - platform: template id: proxy_sensor lambda: |- if( id(connection_status).state && id(remote_sensor).state && (std::to_string(id(remote_sensor).state) != "nan") ) { return id(remote_sensor).state; } else { return id(onboard_sensor).state; } update_interval: 60s # the if condition in the lambda above is probably *NOT* a good test if the sensor is connected and returning valid data. climate: - platform: thermostat name: "Thermostat Climate Controller" id: tcc1 visual: min_temperature: 4 sensor: proxy_sensor min_heating_off_time: 60s min_heating_run_time: 120s min_idle_time: 30s heat_action: - switch.turn_on: relay_switch idle_action: - switch.turn_off: relay_switch default_preset: HOME on_boot_restore_from: memory preset: - name: HOME default_target_temperature_low: 20 mode: heat - name: SLEEP default_target_temperature_low: 17.5 mode: heat - name: AWAY default_target_temperature_low: 10 mode: heat - name: ECO default_target_temperature_low: 16 mode: heat font: - file: type: gfonts family: "Roboto" id: myfont size: 14 - file: type: gfonts family: "Ultra" id: mylargefont size: 36 time: - platform: sntp timezone: "America/Los_Angeles" id: time1 display: - platform: ssd1306_i2c model: "SSD1306 128x64" address: 0x3C id: my_display pages: - id: page1 lambda: |- int l = 14; std::string mymode = (tcc1->mode == 0) ? "OFF" : "ON"; std::string myaction = ""; if(tcc1->action==0) {myaction="off";} if(tcc1->action==3) {myaction="heating";} if(tcc1->action==4) {myaction="idle";} it.printf(0, 0, id(myfont), "%s", mymode.c_str()); it.printf(it.get_width(), 0, id(myfont), TextAlign::TOP_RIGHT, "%s", myaction.c_str()); it.printf(0, l*1, id(myfont), "set"); it.printf(it.get_width(), l*1, id(myfont), TextAlign::RIGHT, "%.1f F", id(tcc1).target_temperature * (9.0/5.0) + 32.0); it.printf(0, l*2, id(myfont), "current"); it.printf(it.get_width(), l*2, id(myfont), TextAlign::RIGHT, "%.1f F", id(tcc1).current_temperature * (9.0/5.0) + 32.0); it.printf(0, l*3, id(myfont), "preset"); it.printf(it.get_width(), l*3, id(myfont), TextAlign::RIGHT, "%s", esphome::climate::climate_preset_to_string(id(tcc1).preset.value())); - id: page2 lambda: |- it.printf(it.get_width(), 0, id(myfont), TextAlign::TOP_RIGHT, "set %.1f", id(tcc1).target_temperature * (9.0/5.0) + 32.0); it.printf(it.get_width()/2, it.get_height()-6, id(mylargefont), TextAlign::BOTTOM_CENTER, "%.1f°F", id(tcc1).current_temperature * (9.0/5.0) + 32.0); it.printf(it.get_width()/2, it.get_height(), id(myfont), TextAlign::BOTTOM_CENTER, "currently"); - id: page3 lambda: |- it.strftime(it.get_width()/2, it.get_height()/2, id(mylargefont), TextAlign::CENTER, "%l:%M", id(time1).now()); it.strftime(it.get_width(), it.get_height(), id(myfont), TextAlign::BOTTOM_RIGHT, "%P", id(time1).now());