From af15ec6b79001636baf6db946c926b88f2cf39e5 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 18 Oct 2023 10:00:40 +0200 Subject: [PATCH] Splitting addon climate --- nspanel_esphome.yaml | 1 - nspanel_esphome_addon_climate_cool.yaml | 106 +--- nspanel_esphome_addon_climate_heat.yaml | 106 +--- nspanel_esphome_addon_climate_shared.yaml | 121 +++++ nspanel_esphome_advanced.yaml | 22 +- nspanel_esphome_core.yaml | 631 +++++++++++----------- 6 files changed, 449 insertions(+), 538 deletions(-) create mode 100644 nspanel_esphome_addon_climate_shared.yaml diff --git a/nspanel_esphome.yaml b/nspanel_esphome.yaml index 1347765..925aef0 100644 --- a/nspanel_esphome.yaml +++ b/nspanel_esphome.yaml @@ -1,4 +1,3 @@ packages: core_package: !include nspanel_esphome_core.yaml upload_tft_package: !include nspanel_esphome_addon_upload_tft.yaml - diff --git a/nspanel_esphome_addon_climate_cool.yaml b/nspanel_esphome_addon_climate_cool.yaml index 710479b..33bf0be 100644 --- a/nspanel_esphome_addon_climate_cool.yaml +++ b/nspanel_esphome_addon_climate_cool.yaml @@ -6,15 +6,10 @@ substitutions: ### Local thermostat defaults ### # https://esphome.io/components/climate/thermostat.html - temp_units: "°C" cooler_relay: "0" # Select 1 for "Relay 1", 2 for "Relay 2" or "0" to a dummy switch/disabled - min_off_time: "300" - min_run_time: "300" - min_idle_time: "30" # https://esphome.io/components/climate/index.html#base-climate-configuration temp_min: "15" temp_max: "45" - temp_step: "0.5" ##### DO NOT CHANGE THIS ##### addon_climate_cool: "true" @@ -52,102 +47,5 @@ climate: - script.execute: addon_climate_update_page_home - logger.log: Climate state changed - End -###### All the code bellow this point is shared between addon_climate_cool and addon_climate_heat ##### - -globals: - ##### Is embedded thermostat visible on climate page? ##### - - id: is_addon_climate_visible - type: bool - restore_value: false - initial_value: 'false' - ##### Embeded climate friendly name ##### - - id: addon_climate_friendly_name - type: std::string - restore_value: false - initial_value: '"${device_name} Thermostat"' - -script: - - id: !extend addon_climate_update_page_home - mode: restart - then: - - lambda: |- - // Update home.climate_entity variable - id(entity_id) = (id(is_embedded_thermostat)) ? "embedded_climate" : ""; - id(disp1).set_component_value("climate.embedded", (id(is_embedded_thermostat)) ? 1 : 0); - // Update chips - if (id(is_embedded_thermostat)) - id(update_climate_icon).execute("home.icon_top_03", int(id(thermostat_embedded).action), int(id(thermostat_embedded).mode)); - - - id: !extend addon_climate_service_call - then: - - lambda: |- - id(is_addon_climate_visible) = true; - id(disp1).set_component_value("climate.embedded", 1); - auto call = id(thermostat_embedded).make_call(); - if (key == "set_temperature") - call.set_target_temperature(stof(value) / 10); - else if (key == "hvac_mode") - call.set_mode(value); - call.perform(); - - - id: !extend addon_climate_set_climate - then: - - lambda: |- - id(is_addon_climate_visible) = embedded_climate; - - - id: !extend addon_climate_update_page_climate - then: - - lambda: |- - if (id(current_page).state == "climate" and id(is_addon_climate_visible)) - { - id(disp1).set_component_text_printf("page_label", id(addon_climate_friendly_name).c_str()); - float temp_step = ${temp_step}; - float temp_offset = ${temp_min}; - float temp_max = ${temp_max}; - float total_steps = (temp_max-temp_offset)/temp_step; - id(set_climate)->execute - ( - id(thermostat_embedded).current_temperature, // current_temp - id(thermostat_embedded).target_temperature, // target_temp - int(round(${temp_step}*10)), // temp_step - int(round(total_steps)), // total_steps //int(round((10*id(thermostat_embedded).target_temperature-temp_offset)/temp_step)), // slider_val - int(round(${temp_min}*10)), // temp_offset - "", // climate_icon - true // embedded_climate - ); - - // Update target temp icon - id(update_climate_icon).execute("climate.target_icon", int(id(thermostat_embedded).action), int(id(thermostat_embedded).mode)); - - // Update buttons bar - // Hide not supported hotspots - id(disp1).hide_component("button01"); - id(disp1).hide_component("button02"); - if (${addon_climate_heat}) id(disp1).show_component("button03"); else id(disp1).hide_component("button03"); //Heat - if (${addon_climate_cool}) id(disp1).show_component("button04"); else id(disp1).hide_component("button04"); //Cool - id(disp1).hide_component("button05"); - id(disp1).hide_component("button06"); - id(disp1).show_component("button07"); //Off - // Set buttons colors - id(disp1).set_component_font_color("climate.button01_icon", 6339); - id(disp1).set_component_font_color("climate.button02_icon", 6339); - id(disp1).set_component_font_color("climate.button03_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_HEAT) ? 64164 : ((${addon_climate_heat}) ? 48631 : 6339)); - id(disp1).set_component_font_color("climate.button04_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_COOL) ? 1055 : ((${addon_climate_cool}) ? 48631 : 6339)); - id(disp1).set_component_font_color("climate.button05_icon", 6339); - id(disp1).set_component_font_color("climate.button06_icon", 6339); - id(disp1).set_component_font_color("climate.button07_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_OFF) ? 10597 : 35921); - } - - - id: !extend addon_climate_set_climate_friendly_name - then: - - lambda: |- - id(addon_climate_friendly_name) = friendly_name; - -switch: - ##### PHYSICAL SWITCH 0 (Dummy) - Used when relay is not set ##### - - name: ${device_name} Relay 0 (dummy) - platform: template - id: relay_0 - lambda: !lambda return false; - internal: true - optimistic: true +packages: + core_package: !include nspanel_esphome_climate_shared.yaml diff --git a/nspanel_esphome_addon_climate_heat.yaml b/nspanel_esphome_addon_climate_heat.yaml index bfa5a59..6bdd509 100644 --- a/nspanel_esphome_addon_climate_heat.yaml +++ b/nspanel_esphome_addon_climate_heat.yaml @@ -6,15 +6,10 @@ substitutions: ### Local thermostat defaults ### # https://esphome.io/components/climate/thermostat.html - temp_units: "°C" heater_relay: "0" # Select 1 for "Relay 1", 2 for "Relay 2" or "0" to a dummy switch/disabled - min_off_time: "300" - min_run_time: "300" - min_idle_time: "30" # https://esphome.io/components/climate/index.html#base-climate-configuration temp_min: "5" temp_max: "25" - temp_step: "0.5" ##### DO NOT CHANGE THIS ##### addon_climate_cool: "false" @@ -52,102 +47,5 @@ climate: - script.execute: addon_climate_update_page_home - logger.log: Climate state changed - End -###### All the code bellow this point is shared between addon_climate_cool and addon_climate_heat ##### - -globals: - ##### Is embedded thermostat visible on climate page? ##### - - id: is_addon_climate_visible - type: bool - restore_value: false - initial_value: 'false' - ##### Embeded climate friendly name ##### - - id: addon_climate_friendly_name - type: std::string - restore_value: false - initial_value: '"${device_name} Thermostat"' - -script: - - id: !extend addon_climate_update_page_home - mode: restart - then: - - lambda: |- - // Update home.climate_entity variable - id(entity_id) = (id(is_embedded_thermostat)) ? "embedded_climate" : ""; - id(disp1).set_component_value("climate.embedded", (id(is_embedded_thermostat)) ? 1 : 0); - // Update chips - if (id(is_embedded_thermostat)) - id(update_climate_icon).execute("home.icon_top_03", int(id(thermostat_embedded).action), int(id(thermostat_embedded).mode)); - - - id: !extend addon_climate_service_call - then: - - lambda: |- - id(is_addon_climate_visible) = true; - id(disp1).set_component_value("climate.embedded", 1); - auto call = id(thermostat_embedded).make_call(); - if (key == "set_temperature") - call.set_target_temperature(stof(value) / 10); - else if (key == "hvac_mode") - call.set_mode(value); - call.perform(); - - - id: !extend addon_climate_set_climate - then: - - lambda: |- - id(is_addon_climate_visible) = embedded_climate; - - - id: !extend addon_climate_update_page_climate - then: - - lambda: |- - if (id(current_page).state == "climate" and id(is_addon_climate_visible)) - { - id(disp1).set_component_text_printf("page_label", id(addon_climate_friendly_name).c_str()); - float temp_step = ${temp_step}; - float temp_offset = ${temp_min}; - float temp_max = ${temp_max}; - float total_steps = (temp_max-temp_offset)/temp_step; - id(set_climate)->execute - ( - id(thermostat_embedded).current_temperature, // current_temp - id(thermostat_embedded).target_temperature, // target_temp - int(round(${temp_step}*10)), // temp_step - int(round(total_steps)), // total_steps //int(round((10*id(thermostat_embedded).target_temperature-temp_offset)/temp_step)), // slider_val - int(round(${temp_min}*10)), // temp_offset - "", // climate_icon - true // embedded_climate - ); - - // Update target temp icon - id(update_climate_icon).execute("climate.target_icon", int(id(thermostat_embedded).action), int(id(thermostat_embedded).mode)); - - // Update buttons bar - // Hide not supported hotspots - id(disp1).hide_component("button01"); - id(disp1).hide_component("button02"); - if (${addon_climate_heat}) id(disp1).show_component("button03"); else id(disp1).hide_component("button03"); //Heat - if (${addon_climate_cool}) id(disp1).show_component("button04"); else id(disp1).hide_component("button04"); //Cool - id(disp1).hide_component("button05"); - id(disp1).hide_component("button06"); - id(disp1).show_component("button07"); //Off - // Set buttons colors - id(disp1).set_component_font_color("climate.button01_icon", 6339); - id(disp1).set_component_font_color("climate.button02_icon", 6339); - id(disp1).set_component_font_color("climate.button03_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_HEAT) ? 64164 : ((${addon_climate_heat}) ? 48631 : 6339)); - id(disp1).set_component_font_color("climate.button04_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_COOL) ? 1055 : ((${addon_climate_cool}) ? 48631 : 6339)); - id(disp1).set_component_font_color("climate.button05_icon", 6339); - id(disp1).set_component_font_color("climate.button06_icon", 6339); - id(disp1).set_component_font_color("climate.button07_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_OFF) ? 10597 : 35921); - } - - - id: !extend addon_climate_set_climate_friendly_name - then: - - lambda: |- - id(addon_climate_friendly_name) = friendly_name; - -switch: - ##### PHYSICAL SWITCH 0 (Dummy) - Used when relay is not set ##### - - name: ${device_name} Relay 0 (dummy) - platform: template - id: relay_0 - lambda: !lambda return false; - internal: true - optimistic: true +packages: + core_package: !include nspanel_esphome_climate_shared.yaml diff --git a/nspanel_esphome_addon_climate_shared.yaml b/nspanel_esphome_addon_climate_shared.yaml new file mode 100644 index 0000000..7c77ecd --- /dev/null +++ b/nspanel_esphome_addon_climate_shared.yaml @@ -0,0 +1,121 @@ +#################################################################################################### +##### NSPanel ESPHome Add-on for Climate control - Shared - This will be called by heat/cool ##### +##### Add-on for https://github.com/Blackymas/NSPanel_HA_Blueprint ##### +#################################################################################################### + +substitutions: + ### Local thermostat defaults ### + # https://esphome.io/components/climate/thermostat.html + temp_units: "°C" + heater_relay: "0" # Select 1 for "Relay 1", 2 for "Relay 2" or "0" to a dummy switch/disabled + cooler_relay: "0" # Select 1 for "Relay 1", 2 for "Relay 2" or "0" to a dummy switch/disabled + min_off_time: "300" + min_run_time: "300" + min_idle_time: "30" + # https://esphome.io/components/climate/index.html#base-climate-configuration + temp_min: "5" + temp_max: "45" + temp_step: "0.5" + + ##### DO NOT CHANGE THIS ##### + addon_climate_cool: "false" + addon_climate_heat: "false" + ############################## + +globals: + ##### Is embedded thermostat visible on climate page? ##### + - id: is_addon_climate_visible + type: bool + restore_value: false + initial_value: 'false' + ##### Embeded climate friendly name ##### + - id: addon_climate_friendly_name + type: std::string + restore_value: false + initial_value: '"${device_name} Thermostat"' + +switch: + ##### PHYSICAL SWITCH 0 (Dummy) - Used when relay is not set ##### + - name: ${device_name} Relay 0 (dummy) + platform: template + id: relay_0 + lambda: !lambda return false; + internal: true + optimistic: true + +script: + - id: !extend addon_climate_update_page_home + mode: restart + then: + - lambda: |- + // Update home.climate_entity variable + id(entity_id) = (id(is_embedded_thermostat)) ? "embedded_climate" : ""; + id(disp1).set_component_value("climate.embedded", (id(is_embedded_thermostat)) ? 1 : 0); + // Update chips + if (id(is_embedded_thermostat)) + id(update_climate_icon).execute("home.icon_top_03", int(id(thermostat_embedded).action), int(id(thermostat_embedded).mode)); + + - id: !extend addon_climate_service_call + then: + - lambda: |- + id(is_addon_climate_visible) = true; + id(disp1).set_component_value("climate.embedded", 1); + auto call = id(thermostat_embedded).make_call(); + if (key == "set_temperature") + call.set_target_temperature(stof(value) / 10); + else if (key == "hvac_mode") + call.set_mode(value); + call.perform(); + + - id: !extend addon_climate_set_climate + then: + - lambda: |- + id(is_addon_climate_visible) = embedded_climate; + + - id: !extend addon_climate_update_page_climate + then: + - lambda: |- + if (id(current_page).state == "climate" and id(is_addon_climate_visible)) + { + id(disp1).set_component_text_printf("page_label", id(addon_climate_friendly_name).c_str()); + float temp_step = ${temp_step}; + float temp_offset = ${temp_min}; + float temp_max = ${temp_max}; + float total_steps = (temp_max-temp_offset)/temp_step; + id(set_climate)->execute + ( + id(thermostat_embedded).current_temperature, // current_temp + id(thermostat_embedded).target_temperature, // target_temp + int(round(${temp_step}*10)), // temp_step + int(round(total_steps)), // total_steps //int(round((10*id(thermostat_embedded).target_temperature-temp_offset)/temp_step)), // slider_val + int(round(${temp_min}*10)), // temp_offset + "", // climate_icon + true // embedded_climate + ); + + // Update target temp icon + id(update_climate_icon).execute("climate.target_icon", int(id(thermostat_embedded).action), int(id(thermostat_embedded).mode)); + + // Update buttons bar + // Hide not supported hotspots + id(disp1).hide_component("button01"); + id(disp1).hide_component("button02"); + if (${addon_climate_heat}) id(disp1).show_component("button03"); else id(disp1).hide_component("button03"); //Heat + if (${addon_climate_cool}) id(disp1).show_component("button04"); else id(disp1).hide_component("button04"); //Cool + id(disp1).hide_component("button05"); + id(disp1).hide_component("button06"); + id(disp1).show_component("button07"); //Off + // Set buttons colors + id(disp1).set_component_font_color("climate.button01_icon", 6339); + id(disp1).set_component_font_color("climate.button02_icon", 6339); + id(disp1).set_component_font_color("climate.button03_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_HEAT) ? 64164 : ((${addon_climate_heat}) ? 48631 : 6339)); + id(disp1).set_component_font_color("climate.button04_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_COOL) ? 1055 : ((${addon_climate_cool}) ? 48631 : 6339)); + id(disp1).set_component_font_color("climate.button05_icon", 6339); + id(disp1).set_component_font_color("climate.button06_icon", 6339); + id(disp1).set_component_font_color("climate.button07_icon", (id(thermostat_embedded).mode==climate::CLIMATE_MODE_OFF) ? 10597 : 35921); + } + + - id: !extend addon_climate_set_climate_friendly_name + then: + - lambda: |- + id(addon_climate_friendly_name) = friendly_name; diff --git a/nspanel_esphome_advanced.yaml b/nspanel_esphome_advanced.yaml index 907668d..b8b408b 100644 --- a/nspanel_esphome_advanced.yaml +++ b/nspanel_esphome_advanced.yaml @@ -16,6 +16,17 @@ time: - component.update: api_timestamp - component.update: device_timestamp +api: + services: + ##### Service to play a rtttl tones ##### + # Example tones : https://codebender.cc/sketch:109888#RTTTL%20Songs.ino + - service: play_rtttl + variables: + song_str: string + then: + - rtttl.play: + rtttl: !lambda 'return song_str;' + button: ##### EXIT REPARSE TFT DISPLAY ##### - name: ${device_name} Exit reparse @@ -32,17 +43,6 @@ button: id: tf_uart data: [0xFF, 0xFF, 0xFF] -api: - services: - ##### Service to play a rtttl tones ##### - # Example tones : https://codebender.cc/sketch:109888#RTTTL%20Songs.ino - - service: play_rtttl - variables: - song_str: string - then: - - rtttl.play: - rtttl: !lambda 'return song_str;' - sensor: ##### Uptime Sensors ##### - name: ${device_name} Uptime seconds diff --git a/nspanel_esphome_core.yaml b/nspanel_esphome_core.yaml index 266fac2..1494c53 100644 --- a/nspanel_esphome_core.yaml +++ b/nspanel_esphome_core.yaml @@ -18,24 +18,6 @@ substitutions: upload_tft_chunk_size_max: "32768" ############################# -##### WIFI SETUP ##### -wifi: - networks: - - id: wifi_default - ssid: ${wifi_ssid} - password: ${wifi_password} - ap: - ssid: "${device_name}" - password: ${wifi_password} - -##### WEB SERVER SETUP - Required for json parsing and tft upload ##### -web_server: - id: web_server_std - port: 80 - auth: - username: admin - password: ${wifi_password} - ##### ESPHOME CONFIGURATION ##### esphome: name: ${device_name} @@ -72,6 +54,24 @@ esp32: # framework: # type: esp-idf +##### WIFI SETUP ##### +wifi: + networks: + - id: wifi_default + ssid: ${wifi_ssid} + password: ${wifi_password} + ap: + ssid: "${device_name}" + password: ${wifi_password} + +##### WEB SERVER SETUP - Required for json parsing and tft upload ##### +web_server: + id: web_server_std + port: 80 + auth: + username: admin + password: ${wifi_password} + ##### OTA PASSWORD ##### ota: id: ota_std @@ -119,13 +119,6 @@ time: - script.execute: id: refresh_datetime -##### START - BUTTON CONFIGURATION ##### -button: - ###### REBOOT BUTTON ##### - - name: ${device_name} Restart - platform: restart - id: restart_nspanel - ##### START - API CONFIGURATION ##### api: id: api_server @@ -717,6 +710,61 @@ api: } } +##### START - DISPLAY START CONFIGURATION ##### +display: + - id: disp1 + platform: nextion + uart_id: tf_uart + #tft_url: ${nextion_update_url} + on_page: # I couldn't make this trigger to work, so used text_sensor nspanelevent and localevent instead + then: + - lambda: ESP_LOGW("display.disp1.on_page", "NEXTION PAGE CHANGED"); + on_setup: + then: + - lambda: |- + ESP_LOGV("display.disp1.on_setup", "Nextion starting"); + id(disp1).goto_page("boot"); + id(disp1).send_command_printf("bkcmd=3"); + id(disp1).set_component_text_printf("boot.esph_version", "%s", "${version}"); // ### esphome-version ### + id(disp1).show_component("bt_reboot"); + id(timer_reset_all).execute("boot"); + ESP_LOGV("display.disp1.on_setup", "Wait for API"); + - wait_until: + api.connected + - lambda: |- + ESP_LOGV("display.disp1.on_setup", "Publish IP address"); + auto ip = network::get_ip_address(); + id(disp1).set_component_text_printf("boot.ip_addr", "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + ESP_LOGV("display.disp1.on_setup", "Report to Home Assistant"); + auto ha_event = new esphome::api::CustomAPIDevice(); + ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint", + { + {"type", "boot"}, + {"step", "start"} + }); + - delay: 1s + - lambda: |- + // Set dimming values + id(display_brightness).publish_state(id(display_brightness_global)); + id(display_dim_brightness).publish_state(id(display_dim_brightness_global)); + id(disp1).send_command_printf("brightness=%i", id(display_brightness_global)); + id(disp1).send_command_printf("settings.brightslider.val=%i", id(display_brightness_global)); + id(disp1).send_command_printf("brightness_dim=%i", id(display_dim_brightness_global)); + id(disp1).send_command_printf("settings.dimslider.val=%i", id(display_dim_brightness_global)); + id(nextion_init).publish_state(true); + ESP_LOGV("display.disp1.on_setup", "Report to Home Assistant"); + auto ha_event = new esphome::api::CustomAPIDevice(); + ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint", + { + {"type", "boot"}, + {"step", "nextion_init"} + }); + id(home_relay1_icon) = "\uE3A5"; + id(home_relay1_icon) = "\uE3A8"; + id(timer_reset_all).execute("boot"); + - *notification_clear + - logger.log: "Nextion start - Done!" + ##### START - GLOBALS CONFIGURATION ##### globals: @@ -809,7 +857,6 @@ globals: type: std::string restore_value: no initial_value: '"%H:%M"' - - id: home_time_color type: int restore_value: true @@ -820,7 +867,6 @@ globals: type: std::string restore_value: false initial_value: '' - - id: home_relay1_icon_color type: int restore_value: true @@ -830,7 +876,6 @@ globals: type: std::string restore_value: false initial_value: '' - - id: home_relay2_icon_color type: int restore_value: true @@ -839,7 +884,6 @@ globals: - id: home_notify_icon_color_normal type: std::vector restore_value: false - - id: home_notify_icon_color_unread type: std::vector restore_value: false @@ -943,7 +987,6 @@ binary_sensor: internal: true on_click: - button.press: restart_nspanel - ##### Restart NSPanel Button - Boot Page ##### - name: ${device_name} Restart platform: nextion @@ -971,6 +1014,157 @@ binary_sensor: - script.execute: id: refresh_wifi_icon +##### START - BUTTON CONFIGURATION ##### +button: + ###### REBOOT BUTTON ##### + - name: ${device_name} Restart + platform: restart + id: restart_nspanel + +##### START - NUMBER CONFIGURATION ##### +number: + + ##### SCREEN BRIGHTNESS ##### + - name: ${device_name} Display Brightness + id: display_brightness + platform: template + entity_category: config + unit_of_measurement: '%' + min_value: 1 + max_value: 100 + step: 1 + restore_value: true + optimistic: true + set_action: + then: + - lambda: |- + id(display_brightness_global) = int(x); + id(disp1).send_command_printf("brightness=%i", int(x)); + id(disp1).send_command_printf("settings.brightslider.val=%i", int(x)); + if (id(current_page).state != "screensaver") + { + id(disp1).set_backlight_brightness(x/100); + id(timer_dim).execute(id(current_page).state.c_str(), int(id(timeout_dim).state)); + id(timer_sleep).execute(id(current_page).state.c_str(), int(id(timeout_sleep).state)); + if (id(current_page).state == "settings") id(disp1).set_component_text_printf("bright_text", "%i%%", int(x)); + } + + ##### SCREEN BRIGHTNESS DIMMED DOWN ##### + - name: ${device_name} Display Brightness Dimdown + id: display_dim_brightness + platform: template + entity_category: config + unit_of_measurement: '%' + min_value: 1 + max_value: 100 + step: 1 + restore_value: true + optimistic: true + set_action: + then: + - lambda: |- + id(display_dim_brightness_global) = int(x); + id(disp1).send_command_printf("brightness_dim=%i", int(x)); + id(disp1).send_command_printf("settings.dimslider.val=%i", int(x)); + if (id(current_page).state != "screensaver" and id(is_dim_brightness)) + { + id(disp1).set_backlight_brightness(x/100); + id(timer_sleep).execute(id(current_page).state.c_str(), int(id(timeout_sleep).state)); + if (id(current_page).state == "settings") id(disp1).set_component_text_printf("dim_text", "%i%%", int(x)); + } + + ##### Temperature Correction ##### + - name: ${device_name} Temperature Correction + platform: template + id: temperature_correction + entity_category: config + unit_of_measurement: '°C' + initial_value: 0 + min_value: -10 + max_value: 10 + step: 0.1 + restore_value: true + internal: false + optimistic: true + set_action: + - logger.log: Temperature correction changed. + - delay: 1s + - lambda: id(temp_nspanel).publish_state(id(temp_nspanel).raw_state); + + ##### Timers settings ##### + - name: ${device_name} Timeout Page + platform: template + id: timeout_page + entity_category: config + min_value: 0 + max_value: 300 + initial_value: 15 + step: 1 + restore_value: true + optimistic: true + icon: mdi:timer + unit_of_measurement: "s" + set_action: + - lambda: id(timer_page).execute(id(current_page).state.c_str(), int(x)); + - name: ${device_name} Timeout Dimming + platform: template + id: timeout_dim + entity_category: config + min_value: 0 + max_value: 300 + initial_value: 30 + step: 1 + restore_value: true + optimistic: true + icon: mdi:timer + unit_of_measurement: "s" + set_action: + - lambda: id(timer_dim).execute(id(current_page).state.c_str(), int(x)); + - name: ${device_name} Timeout Sleep + platform: template + id: timeout_sleep + entity_category: config + min_value: 0 + max_value: 300 + initial_value: 60 + step: 1 + restore_value: true + optimistic: true + icon: mdi:timer + unit_of_measurement: "s" + set_action: + - lambda: |- + id(timer_dim).execute(id(current_page).state.c_str(), int(id(timeout_dim).state)); + id(timer_sleep).execute(id(current_page).state.c_str(), int(x)); + +##### START - SELECT CONFIGURATION ##### +select: + - name: ${device_name} Wake-up page + id: wakeup_page_name + platform: template + options: + - home + - buttonpage01 + - buttonpage02 + - buttonpage03 + - buttonpage04 + - entitypage01 + - entitypage02 + - entitypage03 + - entitypage04 + - qrcode + - alarm + initial_option: home + optimistic: true + restore_value: true + internal: false + entity_category: config + icon: mdi:page-next-outline + set_action: + - script.execute: + id: page_screensaver + construct_page: false + ##### START - SENSOR CONFIGURATION ##### sensor: @@ -1043,6 +1237,95 @@ sensor: - lambda: |- id(timer_reset_all).execute("settings"); +##### START - SWITCH CONFIGURATION ##### +switch: + + ##### Notification unread ##### + - name: ${device_name} Notification unread + platform: template + id: notification_unread + entity_category: config + optimistic: true + restore_mode: ALWAYS_OFF + on_turn_on: + - lambda: id(set_component_color).execute("home.bt_notific", id(home_notify_icon_color_unread), {}); + on_turn_off: + - lambda: id(set_component_color).execute("home.bt_notific", id(home_notify_icon_color_normal), {}); + + ##### Notification sound ##### + - name: ${device_name} Notification sound + platform: template + id: notification_sound + entity_category: config + optimistic: true + restore_mode: RESTORE_DEFAULT_OFF + + ##### PHYSICAL SWITCH 1 ##### + - name: ${device_name} Relay 1 + platform: gpio + id: relay_1 + pin: + number: 22 + restore_mode: RESTORE_DEFAULT_OFF + on_turn_on: + then: + - script.execute: + id: refresh_relays + on_turn_off: + then: + - script.execute: + id: refresh_relays + ##### PHYSICAL SWITCH 2 ###### + - name: ${device_name} Relay 2 + platform: gpio + id: relay_2 + pin: + number: 19 + restore_mode: RESTORE_DEFAULT_OFF + on_turn_on: + then: + - script.execute: + id: refresh_relays + on_turn_off: + then: + - script.execute: + id: refresh_relays + + ##### DISPLAY ALWAYS ON ##### + - name: ${device_name} Screen Power + platform: gpio + id: screen_power + entity_category: config + pin: + number: 4 + inverted: true + restore_mode: ALWAYS_ON + internal: true + + ##### Relay Local control ##### + - name: ${device_name} Relay 1 Local + platform: template + id: relay1_local + entity_category: config + optimistic: true + restore_mode: RESTORE_DEFAULT_OFF + internal: true + on_turn_on: + - logger.log: "Relay 1 Local turned On!" + on_turn_off: + - logger.log: "Relay 1 Local turned Off!" + - name: ${device_name} Relay 2 Local + platform: template + id: relay2_local + entity_category: config + optimistic: true + restore_mode: RESTORE_DEFAULT_OFF + internal: true + on_turn_on: + - logger.log: "Relay 2 Local turned On!" + on_turn_off: + - logger.log: "Relay 2 Local turned Off!" + ##### START - TEXT SENSOR CONFIGURATION ##### text_sensor: @@ -1247,294 +1530,6 @@ text_sensor: else if (not key.empty()) id(ha_call_service).execute((std::string("media_player.") + key.c_str()), "", "", entity.c_str()); } -##### START - SWITCH CONFIGURATION ##### -switch: - - ##### Notification unread ##### - - name: ${device_name} Notification unread - platform: template - id: notification_unread - entity_category: config - optimistic: true - restore_mode: ALWAYS_OFF - on_turn_on: - - lambda: id(set_component_color).execute("home.bt_notific", id(home_notify_icon_color_unread), {}); - on_turn_off: - - lambda: id(set_component_color).execute("home.bt_notific", id(home_notify_icon_color_normal), {}); - - ##### Notification sound ##### - - name: ${device_name} Notification sound - platform: template - id: notification_sound - entity_category: config - optimistic: true - restore_mode: RESTORE_DEFAULT_OFF - - ##### PHYSICAL SWITCH 1 ##### - - name: ${device_name} Relay 1 - platform: gpio - id: relay_1 - pin: - number: 22 - restore_mode: RESTORE_DEFAULT_OFF - on_turn_on: - then: - - script.execute: - id: refresh_relays - on_turn_off: - then: - - script.execute: - id: refresh_relays - ##### PHYSICAL SWITCH 2 ###### - - name: ${device_name} Relay 2 - platform: gpio - id: relay_2 - pin: - number: 19 - restore_mode: RESTORE_DEFAULT_OFF - on_turn_on: - then: - - script.execute: - id: refresh_relays - on_turn_off: - then: - - script.execute: - id: refresh_relays - - ##### DISPLAY ALWAYS ON ##### - - name: ${device_name} Screen Power - platform: gpio - id: screen_power - entity_category: config - pin: - number: 4 - inverted: true - restore_mode: ALWAYS_ON - internal: true - - ##### Relay Local control ##### - - name: ${device_name} Relay 1 Local - platform: template - id: relay1_local - entity_category: config - optimistic: true - restore_mode: RESTORE_DEFAULT_OFF - internal: true - on_turn_on: - - logger.log: "Relay 1 Local turned On!" - on_turn_off: - - logger.log: "Relay 1 Local turned Off!" - - name: ${device_name} Relay 2 Local - platform: template - id: relay2_local - entity_category: config - optimistic: true - restore_mode: RESTORE_DEFAULT_OFF - internal: true - on_turn_on: - - logger.log: "Relay 2 Local turned On!" - on_turn_off: - - logger.log: "Relay 2 Local turned Off!" - -##### START - NUMBER CONFIGURATION ##### -number: - - ##### SCREEN BRIGHTNESS ##### - - name: ${device_name} Display Brightness - id: display_brightness - platform: template - entity_category: config - unit_of_measurement: '%' - min_value: 1 - max_value: 100 - step: 1 - restore_value: true - optimistic: true - set_action: - then: - - lambda: |- - id(display_brightness_global) = int(x); - id(disp1).send_command_printf("brightness=%i", int(x)); - id(disp1).send_command_printf("settings.brightslider.val=%i", int(x)); - if (id(current_page).state != "screensaver") - { - id(disp1).set_backlight_brightness(x/100); - id(timer_dim).execute(id(current_page).state.c_str(), int(id(timeout_dim).state)); - id(timer_sleep).execute(id(current_page).state.c_str(), int(id(timeout_sleep).state)); - if (id(current_page).state == "settings") id(disp1).set_component_text_printf("bright_text", "%i%%", int(x)); - } - - ##### SCREEN BRIGHTNESS DIMMED DOWN ##### - - name: ${device_name} Display Brightness Dimdown - id: display_dim_brightness - platform: template - entity_category: config - unit_of_measurement: '%' - min_value: 1 - max_value: 100 - step: 1 - restore_value: true - optimistic: true - set_action: - then: - - lambda: |- - id(display_dim_brightness_global) = int(x); - id(disp1).send_command_printf("brightness_dim=%i", int(x)); - id(disp1).send_command_printf("settings.dimslider.val=%i", int(x)); - if (id(current_page).state != "screensaver" and id(is_dim_brightness)) - { - id(disp1).set_backlight_brightness(x/100); - id(timer_sleep).execute(id(current_page).state.c_str(), int(id(timeout_sleep).state)); - if (id(current_page).state == "settings") id(disp1).set_component_text_printf("dim_text", "%i%%", int(x)); - } - - ##### Temperature Correction ##### - - name: ${device_name} Temperature Correction - platform: template - id: temperature_correction - entity_category: config - unit_of_measurement: '°C' - initial_value: 0 - min_value: -10 - max_value: 10 - step: 0.1 - restore_value: true - internal: false - optimistic: true - set_action: - - logger.log: Temperature correction changed. - - delay: 1s - - lambda: id(temp_nspanel).publish_state(id(temp_nspanel).raw_state); - - ##### Timers settings ##### - - name: ${device_name} Timeout Page - platform: template - id: timeout_page - entity_category: config - min_value: 0 - max_value: 300 - initial_value: 15 - step: 1 - restore_value: true - optimistic: true - icon: mdi:timer - unit_of_measurement: "s" - set_action: - - lambda: id(timer_page).execute(id(current_page).state.c_str(), int(x)); - - name: ${device_name} Timeout Dimming - platform: template - id: timeout_dim - entity_category: config - min_value: 0 - max_value: 300 - initial_value: 30 - step: 1 - restore_value: true - optimistic: true - icon: mdi:timer - unit_of_measurement: "s" - set_action: - - lambda: id(timer_dim).execute(id(current_page).state.c_str(), int(x)); - - name: ${device_name} Timeout Sleep - platform: template - id: timeout_sleep - entity_category: config - min_value: 0 - max_value: 300 - initial_value: 60 - step: 1 - restore_value: true - optimistic: true - icon: mdi:timer - unit_of_measurement: "s" - set_action: - - lambda: |- - id(timer_dim).execute(id(current_page).state.c_str(), int(id(timeout_dim).state)); - id(timer_sleep).execute(id(current_page).state.c_str(), int(x)); - -##### START - SELECT CONFIGURATION ##### -select: - - name: ${device_name} Wake-up page - id: wakeup_page_name - platform: template - options: - - home - - buttonpage01 - - buttonpage02 - - buttonpage03 - - buttonpage04 - - entitypage01 - - entitypage02 - - entitypage03 - - entitypage04 - - qrcode - - alarm - initial_option: home - optimistic: true - restore_value: true - internal: false - entity_category: config - icon: mdi:page-next-outline - set_action: - - script.execute: - id: page_screensaver - construct_page: false - -##### START - DISPLAY START CONFIGURATION ##### -display: - - id: disp1 - platform: nextion - uart_id: tf_uart - #tft_url: ${nextion_update_url} - on_page: # I couldn't make this trigger to work, so used text_sensor nspanelevent and localevent instead - then: - - lambda: ESP_LOGW("display.disp1.on_page", "NEXTION PAGE CHANGED"); - on_setup: - then: - - lambda: |- - ESP_LOGV("display.disp1.on_setup", "Nextion starting"); - id(disp1).goto_page("boot"); - id(disp1).send_command_printf("bkcmd=3"); - id(disp1).set_component_text_printf("boot.esph_version", "%s", "${version}"); // ### esphome-version ### - id(disp1).show_component("bt_reboot"); - id(timer_reset_all).execute("boot"); - ESP_LOGV("display.disp1.on_setup", "Wait for API"); - - wait_until: - api.connected - - lambda: |- - ESP_LOGV("display.disp1.on_setup", "Publish IP address"); - auto ip = network::get_ip_address(); - id(disp1).set_component_text_printf("boot.ip_addr", "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); - ESP_LOGV("display.disp1.on_setup", "Report to Home Assistant"); - auto ha_event = new esphome::api::CustomAPIDevice(); - ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint", - { - {"type", "boot"}, - {"step", "start"} - }); - - delay: 1s - - lambda: |- - // Set dimming values - id(display_brightness).publish_state(id(display_brightness_global)); - id(display_dim_brightness).publish_state(id(display_dim_brightness_global)); - id(disp1).send_command_printf("brightness=%i", id(display_brightness_global)); - id(disp1).send_command_printf("settings.brightslider.val=%i", id(display_brightness_global)); - id(disp1).send_command_printf("brightness_dim=%i", id(display_dim_brightness_global)); - id(disp1).send_command_printf("settings.dimslider.val=%i", id(display_dim_brightness_global)); - id(nextion_init).publish_state(true); - ESP_LOGV("display.disp1.on_setup", "Report to Home Assistant"); - auto ha_event = new esphome::api::CustomAPIDevice(); - ha_event->fire_homeassistant_event("esphome.nspanel_ha_blueprint", - { - {"type", "boot"}, - {"step", "nextion_init"} - }); - id(home_relay1_icon) = "\uE3A5"; - id(home_relay1_icon) = "\uE3A8"; - id(timer_reset_all).execute("boot"); - - *notification_clear - - logger.log: "Nextion start - Done!" - ### Scripts ###### script: ###### Timers ######