diff --git a/thermostat.yml b/thermostat.yml index 487be88..0aee503 100644 --- a/thermostat.yml +++ b/thermostat.yml @@ -93,6 +93,16 @@ time: text: !lambda |- auto time = id(hass_time).now(); return time.strftime("%a %b %e, %I:%M %p"); + - hours: 1,2,3,4 + minutes: 5 + seconds: 0 + then: + - switch.turn_on: switch_antiburn + - hours: 1,2,3,4 + minutes: 35 + seconds: 0 + then: + - switch.turn_off: switch_antiburn # - script.execute: update_date_time_label sensor: - platform: bme280_i2c @@ -115,11 +125,42 @@ sensor: humidity: name: "Humidity" id: humidity + on_value: + then: + - lvgl.label.update: + id: humidity_label + text: !lambda |- + return to_string(' : ') + to_string(x) + to_string('%'); + pressure: name: "Pressure" id: pressure address: 0x76 + - platform: template + name: "Altitude" + lambda: |- + const float STANDARD_SEA_LEVEL_PRESSURE = 1013.25; //in hPa, see note + return ((id(temperature).state + 273.15) / 0.0065) * + (powf((STANDARD_SEA_LEVEL_PRESSURE / id(pressure).state), 0.190234) - 1); // in meter + update_interval: 15s + icon: 'mdi:signal' + unit_of_measurement: 'm' + + - platform: absolute_humidity + name: "Absolute Humidity" + temperature: temperature + humidity: humidity + + - platform: template + name: "Dew Point" + lambda: |- + return (243.5*(log(id(humidity).state/100)+((17.67*id(temperature).state)/ + (243.5+id(temperature).state)))/(17.67-log(id(humidity).state/100)- + ((17.67*id(temperature).state)/(243.5+id(temperature).state)))); + unit_of_measurement: °C + icon: 'mdi:thermometer-alert' + switch: - platform: homeassistant id: heater @@ -130,6 +171,39 @@ switch: - platform: homeassistant id: fan entity_id: switch.hvac_fan + - platform: template + name: Antiburn + id: switch_antiburn + icon: mdi:television-shimmer + optimistic: true + entity_category: "config" + turn_on_action: + - logger.log: "Starting Antiburn" + - if: + condition: lvgl.is_paused + then: + - lvgl.resume: + - lvgl.widget.redraw: + - lvgl.pause: + show_snow: true + turn_off_action: + - logger.log: "Stopping Antiburn" + - if: + condition: lvgl.is_paused + then: + - lvgl.resume: + - lvgl.widget.redraw: + # - platform: gpio + # name: backlight + # id: display_backlight + # pin: + # ch422g: + # number: 2 + # allow_other_uses: true + # mode: + # output: true + # inverted: False + # restore_mode: ALWAYS_ON climate: - platform: thermostat @@ -324,6 +398,7 @@ display: number: 3 enable_pin: ch422g: + allow_other_uses: true number: 2 de_pin: number: 5 @@ -357,6 +432,21 @@ font: family: Quicksand weight: 400 id: h3 + size: 30 + extras: + - file: "fonts/vm.ttf" + glyphs: [ + "󰖩", # nf:wifi + "", # nf:up + "", # nf:down + "󱖞", # nf:off + "", # nf:humidity + ] + - file: + type: gfonts + family: Quicksand + weight: 400 + id: h4 size: 20 - file: type: gfonts @@ -375,6 +465,9 @@ font: size: 30 glyphs: [ "󰖩", # nf:wifi + "", # nf:up + "", # nf:down + "󱖞", # nf:off ] - file: "fonts/vm.ttf" id: sm_icons @@ -442,11 +535,51 @@ touchscreen: touch.x_raw, touch.y_raw ); + on_release: + then: + - if: + condition: lvgl.is_paused + then: + - lvgl.resume: + - lvgl.widget.redraw: + - switch.turn_on: display_backlight color: - id: bg hex: 282A36 +output: + - platform: ledc + pin: + ch422g: + number: 2 + allow_other_uses: true + mode: + output: true + inverted: False + frequency: 1220 + id: gpio_backlight_pwm + +light: + - platform: monochromatic + output: gpio_backlight_pwm + name: ${devicename} Display Backlight + id: back_light + restore_mode: ALWAYS_ON + +number: + - platform: template + name: LVGL Screen timeout + optimistic: true + id: display_timeout + unit_of_measurement: "s" + initial_value: 45 + restore_value: true + min_value: 10 + max_value: 180 + step: 5 + mode: box + lvgl: # buffer_size: 25% default_font: h2 @@ -455,6 +588,13 @@ lvgl: bg_color: 0x57c7ff knob: bg_color: 0x57c7ff + on_idle: + timeout: !lambda "return (id(display_timeout).state * 1000);" + then: + - logger.log: "LVGL is idle" + - switch.turn_off: display_backlight + - lvgl.pause: + pages: - id: main_page bg_color: 0x282A36 @@ -505,12 +645,12 @@ lvgl: widgets: - button: id: heat_button - height: 60 - width: 60 + height: 80 + width: 80 bg_color: 0x34353e border_width: 2 border_color: 0xE2E4E5 - radius: 20 + radius: 30 checkable: true checked: bg_color: 0xff5c57 @@ -539,15 +679,15 @@ lvgl: text_color: 0xE2E4E5 - button: id: cool_button - height: 60 - width: 60 + height: 80 + width: 80 bg_color: 0x34353e border_width: 2 border_color: 0xE2E4E5 - radius: 20 + radius: 30 checkable: true checked: - bg_color: 0x9aedfe + bg_color: ${color_dark_blue} on_click: then: - lvgl.widget.update: @@ -567,18 +707,21 @@ lvgl: mode: COOL widgets: - label: + id: cool_butt_text text: "\U000F0717" align: center text_font: icons text_color: 0xE2E4E5 + checked: + text_color: ${color_bg} - button: id: fan_button - height: 60 - width: 60 + height: 80 + width: 80 bg_color: 0x34353e border_width: 2 border_color: 0xE2E4E5 - radius: 20 + radius: 30 checkable: true checked: bg_color: 0x5AF78E @@ -607,12 +750,12 @@ lvgl: text_color: 0xE2E4E5 - button: id: off_button - height: 60 - width: 60 + height: 80 + width: 80 bg_color: 0x34353E border_width: 2 border_color: 0xE2E4E5 - radius: 20 + radius: 30 checkable: true checked: bg_color: 0xFF5C57 @@ -635,9 +778,10 @@ lvgl: mode: 'OFF' widgets: - label: - text: "\U000F09DF" - text_font: icons + text: "󱖞" + text_font: md_icons align: center + x: -5 text_color: 0xE2E4E5 # Arc Outer Ring only for visual effect @@ -712,7 +856,7 @@ lvgl: height: 335 y: -20 arc_width: 16 - change_rate: 30 + change_rate: 550 indicator: arc_opa: TRANSP arc_width: 16 @@ -746,56 +890,131 @@ lvgl: id: climape target_temperature_low: !lambda |- return x / 10; - - - - - - - # - arc: - # id: current_temp_arc - # adjustable: true - # min_value: 40 # 12°C (* 10 because decimals not supported) - # max_value: 95 # 34°C - # height: 360 - # width: 360 - # align: CENTER - # arc_width: 20 - # indicator: - # arc_width: 20 - # knob: - # width: 30 - # value: !lambda |- - # auto mode = id(climape).mode; - # if (mode == CLIMATE_MODE_COOL) - # return id(climape).target_temperature_high * (9.0 / 5.0) + 32; - # on_change: - # then: - # - if: - # condition: - # lambda: "return id(climape).mode == CLIMATE_MODE_COOL;" - # then: - # - climate.control: - # id: climape - # target_temperature_high: !lambda |- - # return (x - 32.0) / (9.0 / 5.0); - # - if: - # condition: - # lambda: "return id(climape).mode == CLIMATE_MODE_FAN_ONLY;" - # then: - # - climate.control: - # id: climape - # target_temperature_high: !lambda |- - # return (x - 32.0) / (9.0 / 5.0); - # - if: - # condition: - # lambda: "return id(climape).mode == CLIMATE_MODE_HEAT;" - # then: - # - climate.control: - # id: climape - # target_temperature_low: !lambda |- - # return (x - 32.0) / (9.0 / 5.0); - + - obj: + height: 50% + y: 100 + width: 150 + x: 580 + bg_opa: 0 + border_width: 0 + layout: + type: flex + pad_row: 40 + pad_column: 4 + flex_flow: COLUMN + flex_align_main: CENTER + flex_align_cross: CENTER + flex_align_track: CENTER + widgets: + - button: + id: temp_up_button + height: 80 + width: 80 + bg_color: ${color_bg_alt} + border_width: 2 + border_color: 0xE2E4E5 + radius: 30 + pressed: + bg_color: ${color_green} + on_click: + then: + - if: + condition: + lambda: "return id(climape).mode == CLIMATE_MODE_COOL;" + then: + - climate.control: + id: climape + target_temperature_high: !lambda |- + return ((id(climape).target_temperature_high * 1.8 + 32.0 + 1.0) - 32.0) / 1.8; + - if: + condition: + lambda: "return id(climape).mode == CLIMATE_MODE_FAN_ONLY;" + then: + - climate.control: + id: climape + target_temperature_high: !lambda |- + return ((id(climape).target_temperature_high * 1.8 + 32.0 + 1.0) - 32.0) / 1.8; + - if: + condition: + lambda: "return id(climape).mode == CLIMATE_MODE_HEAT;" + then: + - climate.control: + id: climape + target_temperature_low: !lambda |- + return ((id(climape).target_temperature_low * 1.8 + 32.0 + 1.0) - 32.0) / 1.8; + widgets: + - label: + text: "" + align: center + text_font: md_icons + text_color: 0xE2E4E5 + - button: + id: temp_down_button + height: 80 + width: 80 + bg_color: ${color_bg_alt} + border_width: 2 + border_color: 0xE2E4E5 + radius: 30 + pressed: + bg_color: ${color_green} + on_click: + then: + - if: + condition: + lambda: "return id(climape).mode == CLIMATE_MODE_COOL;" + then: + - climate.control: + id: climape + target_temperature_high: !lambda |- + return ((id(climape).target_temperature_high * 1.8 + 32.0 - 1.0) - 32.0) / 1.8; + - if: + condition: + lambda: "return id(climape).mode == CLIMATE_MODE_FAN_ONLY;" + then: + - climate.control: + id: climape + target_temperature_high: !lambda |- + return ((id(climape).target_temperature_high * 1.8 + 32.0 - 1.0) - 32.0) / 1.8; + - if: + condition: + lambda: "return id(climape).mode == CLIMATE_MODE_HEAT;" + then: + - climate.control: + id: climape + target_temperature_low: !lambda |- + return ((id(climape).target_temperature_low * 1.8 + 32.0 - 1.0) - 32.0) / 1.8; + widgets: + - label: + text: "" + align: center + text_font: md_icons + text_color: 0xE2E4E5 + + - obj: + height: 50% + y: 100 + width: 170 + x: 0 + bg_opa: 0 + border_width: 0 + layout: + type: flex + pad_row: 40 + pad_column: 4 + flex_flow: COLUMN + flex_align_main: CENTER + flex_align_cross: CENTER + flex_align_track: CENTER + widgets: + - label: + id: humidity_label + text_font: h3 + text: " : 50%" + text_color: ${color_white} + align: center + + - label: id: set_temp_label text_font: h2 @@ -805,7 +1024,7 @@ lvgl: text_color: 0xA5A5A9 - label: id: action_label - text_font: h3 + text_font: h4 text: "Loading..." align: center # x: 145