From 10a9e417ea569b110ee4af3a64f884d29c901334 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:38:00 +0200 Subject: [PATCH 01/30] Code refactoring (#565) * Code refactoring - Nextion constants - Colors No changes in functionalities. Just renaming variables related to colors in order to improve readability. * Code refactoring - Nextion constants - Icons * Adding aliases on the first level actions This will make easier troubleshooting as aliases are shown in the logs. * Nextion constants - Pages * Nextion constants - Commands * Nextion constants - Other pics * Fixed typo in nextion.pics.hardware.button * Fixed " 'mui_weekday_today' is undefined" * Code refactoring/standardization Refactoring: - Weather pages - It might support any weather integration now, including OpenWeather) - New string for translation (when weather info is not available for a certain day) - Home page (partial) * Fix bug "'home_page_values' is undefined" * Code refactoring - Button pages Rebuilt button pages in order to improve readability and maintainability. No changes on functionalities, * Changed blueprint version to v3.2.2 * Refactoring entities pages * Reorganizing inputs to improve readability * Bug fixes: qrcode icon & weather provider - Fixed bug preventing to detect that QR Code was enabled in order to display the QR code icon on Home page - Fixed weather integration detection * Review states(entity_id) to make it more resilient Reduce the chances of crash if a `states(entity_id)` returns an error. * Make state_attr(entity_id, attr) more resilitent To avoid crashes with an invalid return. * Perf improv: Don't load weather vars unless needed Performance improvement - don't load weather vars when those are not needed. * Using alias for delay_value To make easier to maintain the code. * Code refactoring: Button press/status Optimizing code in order to improve readability & maintainability. * Reorganizing pages variables --- nspanel_blueprint.yaml | 10249 +++++++++++++++------------------------ 1 file changed, 3929 insertions(+), 6320 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 9c1cf87..f760767 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -35,7 +35,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l 🎉 Roadmap Roadmap can be found here [Roadmap](https://github.com/Blackymas/NSPanel_HA_Blueprint/labels/roadmap) -ℹ️ Version: v.3.2.2 +ℹ️ Version: v.3.2.3DEV ' @@ -46,2284 +46,2283 @@ The goal was to create a version that allows everyone to use the NSpanel fully l input: ##### MAIN NAME ##### - nspanel_name: - name: ESPhome Node Name - description: '* *"SYSTEM" - here you have to enter exactly the same **"device_name"** you entered in the Esphome file*' - default: [nspanel_name] - selector: - text: {} + nspanel_name: + name: ESPhome Node Name + description: '* *"SYSTEM" - here you have to enter exactly the same **"device_name"** you entered in the Esphome file*' + default: [nspanel_name] + selector: + text: {} ##### SYSTEM SETTINGS ##### - language: - name: Language for NSPanel - description: '* *"SYSTEM" - select the language for your NSPanel*' - default: 'ENG' - selector: - select: - mode: dropdown - options: - - label: 'Bulgarian' - value: BGR - - label: 'Czech' - value: CZE - - label: 'Danish' - value: DNK - - label: 'Dutch' - value: NLD - - label: 'English' - value: ENG - - label: 'Estonian' - value: EST - - label: 'Finnish' - value: FIN - - label: 'French' - value: FRA - - label: 'German' - value: DEU - - label: 'Greek' - value: GRC - - label: 'Hebrew' - value: HEB - - label: 'Hungarian' - value: HUN - - label: 'Indonesian' - value: IDN - - label: 'Italian' - value: ITA - - label: 'Latvian' - value: LVA - - label: 'Lithuanian' - value: LTU - - label: 'Norwegian' - value: NOR - - label: 'Polish' - value: POL - - label: 'Portuguese' - value: PRT - - label: 'Romanian' - value: ROU - - label: 'Russian' - value: RUS - - label: 'Swedish' - value: SWE - - label: 'Slovak' - value: SVK - - label: 'Slovene' - value: SVN - - label: 'Spanish' - value: ESP - - label: 'Turkish' - value: TUR - - label: 'Ukrainian' - value: UKR - date_format: - name: Date Format - description: '* *"SYSTEM" - select the format for date to display*' - default: '%d.%m' - selector: - select: - multiple: false - #mode: dropdown - options: - - label: 'DD.MM (ex. 22.03)' - value: '%d.%m' - - label: 'DD/MM (ex. 22/03)' - value: '%d/%m' - - label: 'D/M (ex. 3/22)' - value: '%-m/%-d' + language: + name: Language for NSPanel + description: '* *"SYSTEM" - select the language for your NSPanel*' + default: 'ENG' + selector: + select: + mode: dropdown + options: + - label: 'Bulgarian' + value: BGR + - label: 'Czech' + value: CZE + - label: 'Danish' + value: DNK + - label: 'Dutch' + value: NLD + - label: 'English' + value: ENG + - label: 'Estonian' + value: EST + - label: 'Finnish' + value: FIN + - label: 'French' + value: FRA + - label: 'German' + value: DEU + - label: 'Greek' + value: GRC + - label: 'Hebrew' + value: HEB + - label: 'Hungarian' + value: HUN + - label: 'Indonesian' + value: IDN + - label: 'Italian' + value: ITA + - label: 'Latvian' + value: LVA + - label: 'Lithuanian' + value: LTU + - label: 'Norwegian' + value: NOR + - label: 'Polish' + value: POL + - label: 'Portuguese' + value: PRT + - label: 'Romanian' + value: ROU + - label: 'Russian' + value: RUS + - label: 'Swedish' + value: SWE + - label: 'Slovak' + value: SVK + - label: 'Slovene' + value: SVN + - label: 'Spanish' + value: ESP + - label: 'Turkish' + value: TUR + - label: 'Ukrainian' + value: UKR + date_format: + name: Date Format + description: '* *"SYSTEM" - select the format for date to display*' + default: '%d.%m' + selector: + select: + multiple: false + #mode: dropdown + options: + - label: 'DD.MM (ex. 22.03)' + value: '%d.%m' + - label: 'DD/MM (ex. 22/03)' + value: '%d/%m' + - label: 'D/M (ex. 3/22)' + value: '%-m/%-d' - time_format: - name: Time Format - description: '* *"SYSTEM" - select the format for time to display*' - default: '%H:%M' - selector: - select: - multiple: false - #mode: dropdown - options: - - label: 'HH:MM (ex. 13:30)' - value: '%H:%M' - - label: 'H:MM AM/PM (ex. 1:30PM)' - value: '%-I:%M' + time_format: + name: Time Format + description: '* *"SYSTEM" - select the format for time to display*' + default: '%H:%M' + selector: + select: + multiple: false + #mode: dropdown + options: + - label: 'HH:MM (ex. 13:30)' + value: '%H:%M' + - label: 'H:MM AM/PM (ex. 1:30PM)' + value: '%-I:%M' - delay: - name: Delay to avoid synchronization problem - description: '* *"SYSTEM" - Synchronization Problems may occur due to the **NETWORK / WLAN**. To avoid this problem enter your value for the delay (milliseconds)*' - default: '1' - selector: - number: - min: 0 - max: 100 - - ##### PLACEHOLDER ###################################################################### - placeholder01: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ WEATHER AND TEMPERATURE ✅ ' - default: 'Weather and Temp' - selector: - select: - options: - - Weather and Temp - ##### PLACEHOLDER ###################################################################### + delay: + name: Delay to avoid synchronization problem + description: '* *"SYSTEM" - Synchronization Problems may occur due to the **NETWORK / WLAN**. To avoid this problem enter your value for the delay (milliseconds)*' + default: '1' + selector: + number: + min: 0 + max: 100 ##### WEATHER - Page Home / Weather 01-04 ##### - weather: - name: Weather Integration - description: '* *"SYSTEM" - select our Weather Integration*' - default: 'Default' - selector: - select: - options: - - Default - - AccuWeather - weather_entity: - name: Weather entity from HA - description: '* *"SYSTEM" - Select your weather entity.*' - default: [] - selector: - entity: - domain: - - weather + ##### PLACEHOLDER ###################################################################### + placeholder01: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ WEATHER AND TEMPERATURE ✅ ' + default: 'Weather and Temp' + selector: + select: + options: + - Weather and Temp + ##### PLACEHOLDER ###################################################################### + weather: + name: Weather Integration + description: '* *"SYSTEM" - select our Weather Integration*' + default: 'Default' + selector: + select: + options: + - Default + - AccuWeather + weather_entity: + name: Weather entity from HA + description: '* *"SYSTEM" - Select your weather entity.*' + default: [] + selector: + entity: + domain: + - weather - ##### Temp - Page Home ##### - outdoortemp: - name: Outdoor Temperature Sensor (Optional) - description: '* *Page "HOME" - If no outdoor sensor is available, leave the field empty and the value from your selected weather integration will be used automatically*' - default: [] - selector: - entity: - domain: - - sensor - home_outdoor_temp_label_color: - name: Outdoor Temperature Sensor - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed*' - default: [255,255,255] #65535 White - selector: &color-selector - color_rgb: - indoortemp: - name: Indoor Temperature Sensor - ENTITY (Optional) - description: '* *Page "HOME" - An indoor temperature sensor is not necessary. Leave the field empty if you want to use the temperature sensor of the NSPanel. Additionally a temperature correction for the NSPanel sensor is possible under HA Devices. So everyone can adjust the sensor exactly*' - default: [] - selector: - entity: - domain: - - sensor - home_indoor_temp_icon: - name: Indoor Temperature Sensor - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E50E)*' - default:  #E50E - selector: - text: {} - home_indoor_temp_icon_color: - name: Indoor Temperature Sensor - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [255,255,255] #65535 White - selector: *color-selector - home_indoor_temp_label_color: - name: Indoor Temperature Sensor - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed*' - default: [255,255,255] #65535 White - selector: *color-selector - - ##### PLACEHOLDER ###################################################################### - placeholder02: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ SENSOR HOME PAGE ✅ ' - default: 'sensor' - selector: - select: - options: - - sensor - ##### PLACEHOLDER ###################################################################### - - ##### Sensor - Page Home ##### - home_value01: - name: Sensor 01 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed*' - default: [] - selector: - entity: - domain: - - sensor - home_value01_icon: - name: Sensor 01 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: &icon-selector - text: {} - home_value01_icon_color: - name: Sensor 01 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - home_value01_label_color: - name: Sensor 01 - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - home_value02: - name: Sensor 02 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed*' - default: [] - selector: - entity: - domain: - - sensor - home_value02_icon: - name: Sensor 02 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: - text: {} - home_value02_icon_color: - name: Sensor 02 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - home_value02_label_color: - name: Sensor 02 - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - home_value03: - name: Sensor 03 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed*' - default: [] - selector: - entity: - domain: - - sensor - home_value03_icon: - name: Sensor 03 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - home_value03_icon_color: - name: Sensor 03 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - home_value03_label_color: - name: Sensor 03 - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - - ##### PLACEHOLDER ###################################################################### - placeholder03: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ CHIPS ✅ ' - default: 'chips' - selector: - select: - options: - - chips - ##### PLACEHOLDER ###################################################################### - - ##### Chips - Page Home ##### - chip01: - name: Chip 01 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: &chip-entity-selector - entity: - domain: - - binary_sensor - - input_boolean - - light - - sensor - - switch - chip01_icon: - name: Chip 01 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: - text: {} - chip01_icon_color: - name: Chip 01 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - chip02: - name: Chip 02 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: *chip-entity-selector - chip02_icon: - name: Chip 02 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - chip02_icon_color: - name: Chip 02 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - chip03: - name: Chip 03 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: *chip-entity-selector - chip03_icon: - name: Chip 03 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - chip03_icon_color: - name: Chip 03 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - chip04: - name: Chip 04 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: *chip-entity-selector - chip04_icon: - name: Chip 04 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - chip04_icon_color: - name: Chip 04 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - chip05: - name: Chip 05 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: *chip-entity-selector - chip05_icon: - name: Chip 05 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - chip05_icon_color: - name: Chip 05 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - chip06: - name: Chip 06 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: *chip-entity-selector - chip06_icon: - name: Chip 06 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - chip06_icon_color: - name: Chip 06 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - chip07: - name: Chip 07 - ENTITY (Optional) - description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' - default: [] - selector: *chip-entity-selector - chip07_icon: - name: Chip 07 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - chip07_icon_color: - name: Chip 07 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - - ##### PLACEHOLDER ###################################################################### - placeholder04: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ CLIMATE ✅ ' - default: 'climate' - selector: - select: - options: - - climate - ##### PLACEHOLDER ###################################################################### + ##### Page Home ##### + ##### Temperature - Page Home ##### + outdoortemp: + name: Outdoor Temperature Sensor (Optional) + description: '* *Page "HOME" - If no outdoor sensor is available, leave the field empty and the value from your selected weather integration will be used automatically*' + default: [] + selector: + entity: + domain: + - sensor + home_outdoor_temp_label_color: + name: Outdoor Temperature Sensor - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed*' + default: [255,255,255] #65535 White + selector: &color-selector + color_rgb: + indoortemp: + name: Indoor Temperature Sensor - ENTITY (Optional) + description: '* *Page "HOME" - An indoor temperature sensor is not necessary. Leave the field empty if you want to use the temperature sensor of the NSPanel. Additionally a temperature correction for the NSPanel sensor is possible under HA Devices. So everyone can adjust the sensor exactly*' + default: [] + selector: + entity: + domain: + - sensor + home_indoor_temp_icon: + name: Indoor Temperature Sensor - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E50E)*' + default:  #E50E + selector: + text: {} + home_indoor_temp_icon_color: + name: Indoor Temperature Sensor - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [255,255,255] #65535 White + selector: *color-selector + home_indoor_temp_label_color: + name: Indoor Temperature Sensor - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed*' + default: [255,255,255] #65535 White + selector: *color-selector + ##### Sensors - Page Home ##### + ##### PLACEHOLDER ###################################################################### + placeholder02: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ SENSOR HOME PAGE ✅ ' + default: 'sensor' + selector: + select: + options: + - sensor + ##### PLACEHOLDER ###################################################################### + home_value01: + name: Sensor 01 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed*' + default: [] + selector: + entity: + domain: + - sensor + home_value01_icon: + name: Sensor 01 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: &icon-selector + text: {} + home_value01_icon_color: + name: Sensor 01 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + home_value01_label_color: + name: Sensor 01 - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + home_value02: + name: Sensor 02 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed*' + default: [] + selector: + entity: + domain: + - sensor + home_value02_icon: + name: Sensor 02 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: + text: {} + home_value02_icon_color: + name: Sensor 02 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + home_value02_label_color: + name: Sensor 02 - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + home_value03: + name: Sensor 03 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed*' + default: [] + selector: + entity: + domain: + - sensor + home_value03_icon: + name: Sensor 03 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + home_value03_icon_color: + name: Sensor 03 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + home_value03_label_color: + name: Sensor 03 - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + ##### Chips - Page Home ##### + ##### PLACEHOLDER ###################################################################### + placeholder03: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ CHIPS ✅ ' + default: 'chips' + selector: + select: + options: + - chips + ##### PLACEHOLDER ###################################################################### + chip01: + name: Chip 01 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: &chip-entity-selector + entity: + domain: + - binary_sensor + - input_boolean + - light + - sensor + - switch + chip01_icon: + name: Chip 01 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: + text: {} + chip01_icon_color: + name: Chip 01 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + chip02: + name: Chip 02 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: *chip-entity-selector + chip02_icon: + name: Chip 02 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + chip02_icon_color: + name: Chip 02 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + chip03: + name: Chip 03 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: *chip-entity-selector + chip03_icon: + name: Chip 03 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + chip03_icon_color: + name: Chip 03 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + chip04: + name: Chip 04 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: *chip-entity-selector + chip04_icon: + name: Chip 04 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + chip04_icon_color: + name: Chip 04 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + chip05: + name: Chip 05 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: *chip-entity-selector + chip05_icon: + name: Chip 05 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + chip05_icon_color: + name: Chip 05 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + chip06: + name: Chip 06 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: *chip-entity-selector + chip06_icon: + name: Chip 06 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + chip06_icon_color: + name: Chip 06 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + chip07: + name: Chip 07 - ENTITY (Optional) + description: '* *Page "HOME" - Entity which should be displayed (ONLY light | switch | binary_sensor | sensor | with state ON/OFF)*' + default: [] + selector: *chip-entity-selector + chip07_icon: + name: Chip 07 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed when state ON (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + chip07_icon_color: + name: Chip 07 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed*' + default: [128,128,128] #33808 Grey light + selector: *color-selector ##### Climate - Page Climate ##### - climate: - name: Climate to control - ENTITY (Optional) - description: '* *Page "CLIMATE" - If an entity is selected, the **"Thermostat page"** is activated and enabled. If you have **"Underfloor Heating System"** and want to switch it via the relay, you must create a separate climate in HA. See HowTo*' - default: [] - selector: - entity: - domain: climate - climate_optimistic: - name: Climate control optimistic mode - TRUE/FALSE (Optional) - default: true - description: '* *Page "CLIMATE" - Depends on your climate device and HA-Integration. If optimisitc mode is **OFF** then changes are made will wait for response from device to update temperature in the display. This can cause delays or jumping values. If **ON** the script update the display immediately but apply changes after closing climate-page* ' - selector: - boolean: - hotwatercharge: - name: Hot Water Charge Button - ENTITY (Optional) - description: '* *Page "CLIMATE" - Choose your switch to turn on/off*' - default: [] - selector: - entity: - domain: - - switch - - input_boolean - - ##### PLACEHOLDER ###################################################################### - placeholder05: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ QR CODE ✅ ' - default: 'qrcode' - selector: - select: - options: - - qrcode - ##### PLACEHOLDER ###################################################################### + ##### PLACEHOLDER ###################################################################### + placeholder04: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ CLIMATE ✅ ' + default: 'climate' + selector: + select: + options: + - climate + ##### PLACEHOLDER ###################################################################### + climate: + name: Climate to control - ENTITY (Optional) + description: '* *Page "CLIMATE" - If an entity is selected, the **"Thermostat page"** is activated and enabled. If you have **"Underfloor Heating System"** and want to switch it via the relay, you must create a separate climate in HA. See HowTo*' + default: [] + selector: + entity: + domain: climate + climate_optimistic: + name: Climate control optimistic mode - TRUE/FALSE (Optional) + default: true + description: '* *Page "CLIMATE" - Depends on your climate device and HA-Integration. If optimisitc mode is **OFF** then changes are made will wait for response from device to update temperature in the display. This can cause delays or jumping values. If **ON** the script update the display immediately but apply changes after closing climate-page* ' + selector: + boolean: + hotwatercharge: + name: Hot Water Charge Button - ENTITY (Optional) + description: '* *Page "CLIMATE" - Choose your switch to turn on/off*' + default: [] + selector: + entity: + domain: + - switch + - input_boolean ##### QR Code - Page Home/QR Code ##### - qrcode_enabled: - name: Activate QR Code - TRUE/FALSE (Optional) - default: false - description: '* *Page "HOME" - activate QR Code page and QR Code Button on the home page* ' - selector: - boolean: + ##### PLACEHOLDER ###################################################################### + placeholder05: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ QR CODE ✅ ' + default: 'qrcode' + selector: + select: + options: + - qrcode + ##### PLACEHOLDER ###################################################################### + qrcode_enabled: + name: Activate QR Code - TRUE/FALSE (Optional) + default: false + description: '* *Page "HOME" - activate QR Code page and QR Code Button on the home page* ' + selector: + boolean: + qrcode_label: + name: QR Code page name - LABEL (Optional) + description: '* *Page "QRCODE" - Label which should be displayed*' + default: [] + selector: + text: {} + qrcode_value: + name: QR Code content - VALUE (Optional) + description: '* *Page "QRCODE" - Value you want to display as QR code*' + default: [] + selector: + text: {} + home_button05_icon: + name: QR Code - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E432)*' + default:  #E432 + selector: *icon-selector + home_button05_icon_color: + name: QR Code - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector - qrcode_label: - name: QR Code page name - LABEL (Optional) - description: '* *Page "QRCODE" - Label which should be displayed*' - default: [] - selector: - text: {} + ##### Page Home - Hardware Buttons ##### + ##### PLACEHOLDER ###################################################################### + placeholder06: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ HARDWARE BUTTONS ✅ ' + default: 'hardwarebuttons' + selector: + select: + options: + - hardwarebuttons + ##### PLACEHOLDER ###################################################################### + hold_delay: + name: Delay for HW-Button hold in seconds - VALUE + description: '* *"SYSTEM" - Time in seconds to detect a hold*' + default: 1.0 + selector: + number: + min: 1.0 + max: 10.0 + step: 1.0 + unit_of_measurement: seconds + relay_1_local_fallback: + name: Activate relay 1 local fallback - TRUE/FALSE (Optional) + default: false + description: '* *"SYSTEM" - activate this to use left button to toggle relay 1 if display is offline* ' + selector: + boolean: + left_button_entity: + name: Left hardware button - ENTITY (Optional) + description: '* *"SYSTEM" - Entity which should be switched*' + default: [] + selector: &hardware-button-selector + entity: + domain: + - light + - switch + - input_boolean + - cover + - automation + - button + - input_button + - scene + - script + - fan + left_button_name: + name: Left hardware button name - LABEL (Optional) + description: '* *Page "HOME" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + left_button_hold_select: + name: Left hardware button hold assignment - VALUE (Optional) + description: '* *"SYSTEM" - select what shold happen on hold*' + default: 'Default' + selector: &hardware-button-hold-selector + select: + options: + - Default + - Custom Action + left_button_hold_custom_action: + name: Left hardware button custom hold action - VALUE (Optional) + description: '*"SYSTEM" - The action(s) to launch on hold**' + default: [] + selector: + action: + left_button_color: + name: Left hardware button - LABEL COLOR (Optional) + description: '* *Page "HOME" - LABEL color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + relay_2_local_fallback: + name: Activate relay 2 local fallback - TRUE/FALSE (Optional) + default: false + description: '* *"SYSTEM" - activate this to use right button to toggle relay 2 if display is offline* ' + selector: + boolean: + right_button_entity: + name: Right hardware button - ENTITY (Optional) + description: '* *"SYSTEM" - Entity which should be switched*' + default: [] + selector: *hardware-button-selector + right_button_name: + name: Right hardware button name - LABEL (Optional) + description: '* *Page "HOME" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + right_button_hold_select: + name: Right button hold assignment - VALUE (Optional) + description: '* *"SYSTEM" - select what shold happen on hold*' + default: 'Default' + selector: *hardware-button-hold-selector + right_button_hold_custom_action: + name: Right button custom hold action - VALUE (Optional) + description: '*"SYSTEM" - The action(s) to launch on hold**' + default: [] + selector: + action: + right_button_color: + name: Right hardware button - LABEL COLOR (Optional) + description: '* *Page "HOME" - LABEL color which should be displayed*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector - qrcode_value: - name: QR Code content - VALUE (Optional) - description: '* *Page "QRCODE" - Value you want to display as QR code*' - default: [] - selector: - text: {} - home_button05_icon: - name: QR Code - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E432)*' - default:  #E432 - selector: *icon-selector - home_button05_icon_color: - name: QR Code - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector + ##### Button pages ##### + ##### Button page - Labels ##### + ##### PLACEHOLDER ###################################################################### + placeholder17: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ BUTTON PAGES LABELS ✅ ' + default: 'Button pages labels' + selector: + select: + options: + - Button pages labels + ##### PLACEHOLDER ###################################################################### + button_page01_label: + name: Button page 01 name - LABEL (Optional) + description: '* *Page "ButtonPage01" - Label which should be displayed*' + default: [] + selector: + text: {} + button_page02_label: + name: Button page 02 name - LABEL (Optional) + description: '* *Page "ButtonPage02" - Label which should be displayed*' + default: [] + selector: + text: {} + button_page03_label: + name: Button page 03 name - LABEL (Optional) + description: '* *Page "ButtonPage03" - Label which should be displayed*' + default: [] + selector: + text: {} + button_page04_label: + name: Button page 04 name - LABEL (Optional) + description: '* *Page "ButtonPage04" - Label which should be displayed*' + default: [] + selector: + text: {} + ##### Button page 01 ##### + ##### PLACEHOLDER ###################################################################### + placeholder07: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ BUTTON PAGES 01 ✅ ' + default: 'buttonpage01' + selector: + select: + options: + - buttonpage01 + ##### PLACEHOLDER ###################################################################### + entity01: + name: Button 01 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: &button-entity-selector + entity: + domain: + - light + - switch + - cover + - input_boolean + - automation + - button + - input_button + - scene + - person + - script + - binary_sensor + - fan + - climate + entity01_name: + name: Button 01 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity01_icon: + name: Button 01 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity01_icon_color: + name: Button 01 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity01_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button01** action*' + selector: + boolean: + entity02: + name: Button 02 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity02_name: + name: Button 02 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity02_icon: + name: Button 02 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity02_icon_color: + name: Button 02 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity02_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button02** action*' + selector: + boolean: + entity03: + name: Button 03 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity03_name: + name: Button 03 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity03_icon: + name: Button 03 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity03_icon_color: + name: Button 03 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity03_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button03** action*' + selector: + boolean: + entity04: + name: Button 04 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity04_name: + name: Button 04 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity04_icon: + name: Button 04 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity04_icon_color: + name: Button 04 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity04_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button04** action*' + selector: + boolean: + entity05: + name: Button 05 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity05_name: + name: Button 05 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity05_icon: + name: Button 05 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity05_icon_color: + name: Button 05 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity05_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button05** action*' + selector: + boolean: + entity06: + name: Button 06 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity06_name: + name: Button 06 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity06_icon: + name: Button 06 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity06_icon_color: + name: Button 06 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity06_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button06** action*' + selector: + boolean: + entity07: + name: Button 07 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity07_name: + name: Button 07 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity07_icon: + name: Button 07 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity07_icon_color: + name: Button 07 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity07_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button07** action*' + selector: + boolean: + entity08: + name: Button 08 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity08_name: + name: Button 08 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity08_icon: + name: Button 08 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity08_icon_color: + name: Button 08 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity08_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button08** action*' + selector: + boolean: + ##### Button page 02 ##### + ##### PLACEHOLDER ###################################################################### + placeholder08: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ BUTTON PAGE 02 ✅ ' + default: 'buttonpage02' + selector: + select: + options: + - buttonpage02 + ##### PLACEHOLDER ###################################################################### + entity09: + name: Button 09 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity09_name: + name: Button 09 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity09_icon: + name: Button 09 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity09_icon_color: + name: Button 09 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity09_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button09** action*' + selector: + boolean: + entity10: + name: Button 10 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity10_name: + name: Button 10 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity10_icon: + name: Button 10 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity10_icon_color: + name: Button 10 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity10_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button10** action*' + selector: + boolean: + entity11: + name: Button 11 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity11_name: + name: Button 11 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity11_icon: + name: Button 11 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity11_icon_color: + name: Button 11 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity11_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button11** action*' + selector: + boolean: + entity12: + name: Button 12 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity12_name: + name: Button 12 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity12_icon: + name: Button 12 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity12_icon_color: + name: Button 12 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity12_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button12** action*' + selector: + boolean: + entity13: + name: Button 13 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity13_name: + name: Button 13 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity13_icon: + name: Button 13 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity13_icon_color: + name: Button 13 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity13_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button13** action*' + selector: + boolean: + entity14: + name: Button 14 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity14_name: + name: Button 14 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity14_icon: + name: Button 14 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity14_icon_color: + name: Button 14 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity14_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button14** action*' + selector: + boolean: + entity15: + name: Button 15 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity15_name: + name: Button 15 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity15_icon: + name: Button 15 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity15_icon_color: + name: Button 15 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity15_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button15** action*' + selector: + boolean: + entity16: + name: Button 16 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity16_name: + name: Button 16 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity16_icon: + name: Button 16 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity16_icon_color: + name: Button 16 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity16_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button16** action*' + selector: + boolean: + ##### Button page 03 ##### + ##### PLACEHOLDER ###################################################################### + placeholder09: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ BUTTON PAGE 03 ✅ ' + default: 'buttonpage03' + selector: + select: + options: + - buttonpage03 + ##### PLACEHOLDER ###################################################################### + entity17: + name: Button 17 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity17_name: + name: Button 17 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity17_icon: + name: Button 17 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity17_icon_color: + name: Button 17 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity17_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button17** action*' + selector: + boolean: + entity18: + name: Button 18 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity18_name: + name: Button 18 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity18_icon: + name: Button 18 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity18_icon_color: + name: Button 18 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity18_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button18** action*' + selector: + boolean: + entity19: + name: Button 19 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity19_name: + name: Button 19 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity19_icon: + name: Button 19 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity19_icon_color: + name: Button 19 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity19_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button19** action*' + selector: + boolean: + entity20: + name: Button 20 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity20_name: + name: Button 20 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity20_icon: + name: Button 20 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity20_icon_color: + name: Button 20 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity20_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button20** action*' + selector: + boolean: + entity21: + name: Button 21 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity21_name: + name: Button 21 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity21_icon: + name: Button 21 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity21_icon_color: + name: Button 21 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity21_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button21** action*' + selector: + boolean: + entity22: + name: Button 22 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity22_name: + name: Button 22 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity22_icon: + name: Button 22 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity22_icon_color: + name: Button 22 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity22_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button22** action*' + selector: + boolean: + entity23: + name: Button 23 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity23_name: + name: Button 23 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity23_icon: + name: Button 23 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity23_icon_color: + name: Button 23 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity23_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button23** action*' + selector: + boolean: + entity24: + name: Button 24 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity24_name: + name: Button 24 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity24_icon: + name: Button 24 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity24_icon_color: + name: Button 24 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity24_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button24** action*' + selector: + boolean: + ##### Button page 04 ##### + ##### PLACEHOLDER ###################################################################### + placeholder10: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ BUTTON PAGE 04 ✅ ' + default: 'buttonpage04' + selector: + select: + options: + - buttonpage04 + ##### PLACEHOLDER ###################################################################### + entity25: + name: Button 25 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity25_name: + name: Button 25 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity25_icon: + name: Button 25 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity25_icon_color: + name: Button 25 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity25_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button25** action*' + selector: + boolean: + entity26: + name: Button 26 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity26_name: + name: Button 26 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity26_icon: + name: Button 26 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity26_icon_color: + name: Button 26 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity26_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button26** action*' + selector: + boolean: + entity27: + name: Button 27 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity27_name: + name: Button 27 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity27_icon: + name: Button 27 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity27_icon_color: + name: Button 27 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity27_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button27** action*' + selector: + boolean: + entity28: + name: Button 28 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity28_name: + name: Button 28 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity28_icon: + name: Button 28 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity28_icon_color: + name: Button 28 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity28_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button28** action*' + selector: + boolean: + entity29: + name: Button 29 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity29_name: + name: Button 29 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity29_icon: + name: Button 29 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity29_icon_color: + name: Button 29 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity29_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button29** action*' + selector: + boolean: + entity30: + name: Button 30 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity30_name: + name: Button 30 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity30_icon: + name: Button 30 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity30_icon_color: + name: Button 30 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity30_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button30** action*' + selector: + boolean: + entity31: + name: Button 31 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity31_name: + name: Button 31 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: + text: {} + entity31_icon: + name: Button 31 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: *icon-selector + entity31_icon_color: + name: Button 31 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity31_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button31** action*' + selector: + boolean: + entity32: + name: Button 32 - ENTITY (Optional) + description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' + default: [] + selector: *button-entity-selector + entity32_name: + name: Button 32 name - LABEL (Optional) + description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' + default: [] + selector: *icon-selector + entity32_icon: + name: Button 32 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' + default: [] + selector: + text: {} + entity32_icon_color: + name: Button 32 - ICON COLOR (Optional) + description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' + default: [0,128,248] #1055 Blue + selector: *color-selector + entity32_confirm: + name: Confirm execution of the button press - TRUE/FALSE (Optional) + default: false + description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button32** action*' + selector: + boolean: - ##### PLACEHOLDER ###################################################################### - placeholder06: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ HARDWARE BUTTONS ✅ ' - default: 'hardwarebuttons' - selector: - select: - options: - - hardwarebuttons - ##### PLACEHOLDER ###################################################################### - - ##### Hardware Buttons - Page Home ##### - hold_delay: - name: Delay for HW-Button hold in seconds - VALUE - description: '* *"SYSTEM" - Time in seconds to detect a hold*' - default: 1.0 - selector: - number: - min: 1.0 - max: 10.0 - step: 1.0 - unit_of_measurement: seconds - relay_1_local_fallback: - name: Activate relay 1 local fallback - TRUE/FALSE (Optional) - default: false - description: '* *"SYSTEM" - activate this to use left button to toggle relay 1 if display is offline* ' - selector: - boolean: - left_button_entity: - name: Left hardware button - ENTITY (Optional) - description: '* *"SYSTEM" - Entity which should be switched*' - default: [] - selector: &hardware-button-selector - entity: - domain: - - light - - switch - - input_boolean - - cover - - automation - - button - - input_button - - scene - - script - - fan - left_button_name: - name: Left hardware button name - LABEL (Optional) - description: '* *Page "HOME" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - left_button_hold_select: - name: Left hardware button hold assignment - VALUE (Optional) - description: '* *"SYSTEM" - select what shold happen on hold*' - default: 'Default' - selector: &hardware-button-hold-selector - select: - options: - - Default - - Custom Action - left_button_hold_custom_action: - name: Left hardware button custom hold action - VALUE (Optional) - description: '*"SYSTEM" - The action(s) to launch on hold**' - default: [] - selector: - action: - left_button_color: - name: Left hardware button - LABEL COLOR (Optional) - description: '* *Page "HOME" - LABEL color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - relay_2_local_fallback: - name: Activate relay 2 local fallback - TRUE/FALSE (Optional) - default: false - description: '* *"SYSTEM" - activate this to use right button to toggle relay 2 if display is offline* ' - selector: - boolean: - right_button_entity: - name: Right hardware button - ENTITY (Optional) - description: '* *"SYSTEM" - Entity which should be switched*' - default: [] - selector: *hardware-button-selector - right_button_name: - name: Right hardware button name - LABEL (Optional) - description: '* *Page "HOME" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - right_button_hold_select: - name: Right button hold assignment - VALUE (Optional) - description: '* *"SYSTEM" - select what shold happen on hold*' - default: 'Default' - selector: *hardware-button-hold-selector - right_button_hold_custom_action: - name: Right button custom hold action - VALUE (Optional) - description: '*"SYSTEM" - The action(s) to launch on hold**' - default: [] - selector: - action: - right_button_color: - name: Right hardware button - LABEL COLOR (Optional) - description: '* *Page "HOME" - LABEL color which should be displayed*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - - ##### PLACEHOLDER ###################################################################### - placeholder07: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ BUTTON PAGE 01 ✅ ' - default: 'buttonpage01' - selector: - select: - options: - - buttonpage01 - ##### PLACEHOLDER ###################################################################### - - ##### BUTTON Page Labels ##### - button_page01_label: - name: Button page 01 name - LABEL (Optional) - description: '* *Page "ButtonPage01" - Label which should be displayed*' - default: [] - selector: - text: {} - - button_page02_label: - name: Button page 02 name - LABEL (Optional) - description: '* *Page "ButtonPage02" - Label which should be displayed*' - default: [] - selector: - text: {} - - button_page03_label: - name: Button page 03 name - LABEL (Optional) - description: '* *Page "ButtonPage03" - Label which should be displayed*' - default: [] - selector: - text: {} - - button_page04_label: - name: Button page 04 name - LABEL (Optional) - description: '* *Page "ButtonPage04" - Label which should be displayed*' - default: [] - selector: - text: {} - - ##### BUTTONS ##### - entity01: - name: Button 01 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: &button-entity-selector - entity: - domain: - - light - - switch - - cover - - input_boolean - - automation - - button - - input_button - - scene - - person - - script - - binary_sensor - - fan - - climate - entity01_name: - name: Button 01 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity01_icon: - name: Button 01 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity01_icon_color: - name: Button 01 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity01_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button01** action*' - selector: - boolean: - entity02: - name: Button 02 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity02_name: - name: Button 02 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity02_icon: - name: Button 02 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity02_icon_color: - name: Button 02 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity02_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button02** action*' - selector: - boolean: - entity03: - name: Button 03 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity03_name: - name: Button 03 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity03_icon: - name: Button 03 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity03_icon_color: - name: Button 03 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity03_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button03** action*' - selector: - boolean: - entity04: - name: Button 04 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity04_name: - name: Button 04 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity04_icon: - name: Button 04 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity04_icon_color: - name: Button 04 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity04_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button04** action*' - selector: - boolean: - entity05: - name: Button 05 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity05_name: - name: Button 05 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity05_icon: - name: Button 05 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity05_icon_color: - name: Button 05 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity05_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button05** action*' - selector: - boolean: - entity06: - name: Button 06 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity06_name: - name: Button 06 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity06_icon: - name: Button 06 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity06_icon_color: - name: Button 06 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity06_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button06** action*' - selector: - boolean: - entity07: - name: Button 07 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity07_name: - name: Button 07 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity07_icon: - name: Button 07 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity07_icon_color: - name: Button 07 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity07_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button07** action*' - selector: - boolean: - entity08: - name: Button 08 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE01" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity08_name: - name: Button 08 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE01" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity08_icon: - name: Button 08 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity08_icon_color: - name: Button 08 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE01" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity08_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE01" - Ask for confirmation to execute **Button08** action*' - selector: - boolean: - ##### PLACEHOLDER ###################################################################### - placeholder08: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ BUTTON PAGE 02 ✅ ' - default: 'buttonpage02' - selector: - select: - options: - - buttonpage02 - ##### PLACEHOLDER ###################################################################### - entity09: - name: Button 09 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity09_name: - name: Button 09 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity09_icon: - name: Button 09 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity09_icon_color: - name: Button 09 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity09_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button09** action*' - selector: - boolean: - entity10: - name: Button 10 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity10_name: - name: Button 10 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity10_icon: - name: Button 10 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity10_icon_color: - name: Button 10 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity10_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button10** action*' - selector: - boolean: - entity11: - name: Button 11 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity11_name: - name: Button 11 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity11_icon: - name: Button 11 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity11_icon_color: - name: Button 11 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity11_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button11** action*' - selector: - boolean: - entity12: - name: Button 12 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity12_name: - name: Button 12 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity12_icon: - name: Button 12 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity12_icon_color: - name: Button 12 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity12_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button12** action*' - selector: - boolean: - entity13: - name: Button 13 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity13_name: - name: Button 13 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity13_icon: - name: Button 13 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity13_icon_color: - name: Button 13 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity13_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button13** action*' - selector: - boolean: - entity14: - name: Button 14 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity14_name: - name: Button 14 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity14_icon: - name: Button 14 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity14_icon_color: - name: Button 14 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity14_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button14** action*' - selector: - boolean: - entity15: - name: Button 15 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity15_name: - name: Button 15 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity15_icon: - name: Button 15 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity15_icon_color: - name: Button 15 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity15_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button15** action*' - selector: - boolean: - entity16: - name: Button 16 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE02" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity16_name: - name: Button 16 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE02" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity16_icon: - name: Button 16 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity16_icon_color: - name: Button 16 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE02" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity16_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE02" - Ask for confirmation to execute **Button16** action*' - selector: - boolean: - ##### PLACEHOLDER ###################################################################### - placeholder09: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ BUTTON PAGE 03 ✅ ' - default: 'buttonpage03' - selector: - select: - options: - - buttonpage03 - ##### PLACEHOLDER ###################################################################### - entity17: - name: Button 17 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity17_name: - name: Button 17 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity17_icon: - name: Button 17 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity17_icon_color: - name: Button 17 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity17_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button17** action*' - selector: - boolean: - entity18: - name: Button 18 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity18_name: - name: Button 18 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity18_icon: - name: Button 18 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity18_icon_color: - name: Button 18 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity18_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button18** action*' - selector: - boolean: - entity19: - name: Button 19 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity19_name: - name: Button 19 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity19_icon: - name: Button 19 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity19_icon_color: - name: Button 19 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity19_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button19** action*' - selector: - boolean: - entity20: - name: Button 20 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity20_name: - name: Button 20 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity20_icon: - name: Button 20 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity20_icon_color: - name: Button 20 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity20_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button20** action*' - selector: - boolean: - entity21: - name: Button 21 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity21_name: - name: Button 21 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity21_icon: - name: Button 21 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity21_icon_color: - name: Button 21 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity21_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button21** action*' - selector: - boolean: - entity22: - name: Button 22 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity22_name: - name: Button 22 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity22_icon: - name: Button 22 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity22_icon_color: - name: Button 22 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity22_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button22** action*' - selector: - boolean: - entity23: - name: Button 23 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity23_name: - name: Button 23 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity23_icon: - name: Button 23 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity23_icon_color: - name: Button 23 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity23_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button23** action*' - selector: - boolean: - entity24: - name: Button 24 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE03" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity24_name: - name: Button 24 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE03" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity24_icon: - name: Button 24 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity24_icon_color: - name: Button 24 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE03" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity24_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE03" - Ask for confirmation to execute **Button24** action*' - selector: - boolean: - ##### PLACEHOLDER ###################################################################### - placeholder10: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ BUTTON PAGE 04 ✅ ' - default: 'buttonpage04' - selector: - select: - options: - - buttonpage04 - ##### PLACEHOLDER ###################################################################### - entity25: - name: Button 25 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity25_name: - name: Button 25 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity25_icon: - name: Button 25 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity25_icon_color: - name: Button 25 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity25_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button25** action*' - selector: - boolean: - entity26: - name: Button 26 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity26_name: - name: Button 26 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity26_icon: - name: Button 26 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity26_icon_color: - name: Button 26 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity26_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button26** action*' - selector: - boolean: - entity27: - name: Button 27 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity27_name: - name: Button 27 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity27_icon: - name: Button 27 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity27_icon_color: - name: Button 27 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity27_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button27** action*' - selector: - boolean: - entity28: - name: Button 28 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity28_name: - name: Button 28 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity28_icon: - name: Button 28 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity28_icon_color: - name: Button 28 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity28_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button28** action*' - selector: - boolean: - entity29: - name: Button 29 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity29_name: - name: Button 29 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity29_icon: - name: Button 29 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity29_icon_color: - name: Button 29 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity29_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button29** action*' - selector: - boolean: - entity30: - name: Button 30 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity30_name: - name: Button 30 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity30_icon: - name: Button 30 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity30_icon_color: - name: Button 30 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity30_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button30** action*' - selector: - boolean: - entity31: - name: Button 31 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity31_name: - name: Button 31 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: - text: {} - entity31_icon: - name: Button 31 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: *icon-selector - entity31_icon_color: - name: Button 31 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity31_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button31** action*' - selector: - boolean: - entity32: - name: Button 32 - ENTITY (Optional) - description: '* *Page "BUTTONPAGE04" - Entity which should be switched (ONLY light | switch | cover | input_boolean | automation | button | input_button | scene | person | script | binary_sensor | fan | climate)*' - default: [] - selector: *button-entity-selector - entity32_name: - name: Button 32 name - LABEL (Optional) - description: '* *Page "BUTTONPAGE04" - Label which should be displayed (10 characters are supported)*' - default: [] - selector: *icon-selector - entity32_icon: - name: Button 32 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (Default - an icon matching the entity will be set automatically)*' - default: [] - selector: - text: {} - entity32_icon_color: - name: Button 32 - ICON COLOR (Optional) - description: '* *Page "BUTTONPAGE04" - Icon color which should be displayed when button is on*' - default: [0,128,248] #1055 Blue - selector: *color-selector - entity32_confirm: - name: Confirm execution of the button press - TRUE/FALSE (Optional) - default: false - description: '* *Page "BUTTONPAGE04" - Ask for confirmation to execute **Button32** action*' - selector: - boolean: - - ##### PLACEHOLDER ###################################################################### - placeholder11: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ ENTITY PAGE SETTINGS ✅ ' - default: 'entitypage' - selector: - select: - options: - - entitypage - ##### PLACEHOLDER ###################################################################### - - ##### ENTITY Pages Config ##### - entitypages_enabled: - name: Activate entity page - TRUE/FALSE (Optional) - default: false - description: '* *"SYSTEM" - activate entity page and entity page Button on the home page* ' - selector: - boolean: - home_button06_icon: - name: Entity page - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #EDCF) *' - default:  #EDCF - selector: *icon-selector - home_button06_icon_color: - name: Entity page - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [200,204,200] #52857 Grey super light - selector: *color-selector - ##### ENTITY Page Labels ##### - ##### PLACEHOLDER ###################################################################### - placeholder12: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ ENTITY PAGE 01 ✅ ' - default: 'entitypage01' - selector: - select: - options: - - entitypage01 - ##### PLACEHOLDER ###################################################################### - entity_page01_label: - name: Entity page 01 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed*' - default: [] - selector: - text: {} - entity_page02_label: - name: Entity page 02 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed*' - default: [] - selector: - text: {} - entity_page03_label: - name: Entity page 03 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed*' - default: [] - selector: - text: {} - entity_page04_label: - name: Entity page 04 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed*' - default: [] - selector: - text: {} - - ##### ENTITIES ##### - entities_entity01: - name: Entity 01 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity01_name: - name: Entity 01 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity01_icon: - name: Entity 01 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity02: - name: Entity 02 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity02_name: - name: Entity 02 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity02_icon: - name: Entity 02 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity03: - name: Entity 03 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity03_name: - name: Entity 03 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity03_icon: - name: Entity 03 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity04: - name: Entity 04 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity04_name: - name: Entity 04 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity04_icon: - name: Entity 04 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity05: - name: Entity 05 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity05_name: - name: Entity 05 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity05_icon: - name: Entity 05 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity06: - name: Entity 06 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity06_name: - name: Entity 06 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity06_icon: - name: Entity 06 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity07: - name: Entity 07 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity07_name: - name: Entity 07 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity07_icon: - name: Entity 07 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity08: - name: Entity 08 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity08_name: - name: Entity 08 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity08_icon: - name: Entity 08 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - ##### PLACEHOLDER ###################################################################### - placeholder13: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ ENTITY PAGE 02 ✅ ' - default: 'entitypage02' - selector: - select: - options: - - entitypage02 - ##### PLACEHOLDER ###################################################################### - entities_entity09: - name: Entity 09 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity09_name: - name: Entity 09 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity09_icon: - name: Entity 09 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity10: - name: Entity 10 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity10_name: - name: Entity 10 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity10_icon: - name: Entity 10 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity11: - name: Entity 11 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity11_name: - name: Entity 11 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity11_icon: - name: Entity 11 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity12: - name: Entity 12 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity12_name: - name: Entity 12 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity12_icon: - name: Entity 12 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity13: - name: Entity 13 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity13_name: - name: Entity 13 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity13_icon: - name: Entity 13 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity14: - name: Entity 14 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity14_name: - name: Entity 14 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity14_icon: - name: Entity 14 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity15: - name: Entity 15 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity15_name: - name: Entity 15 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity15_icon: - name: Entity 15 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity16: - name: Entity 16 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity16_name: - name: Entity 16 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity16_icon: - name: Entity 16 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - ##### PLACEHOLDER ###################################################################### - placeholder14: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ ENTITY PAGE 03 ✅ ' - default: 'entitypage03' - selector: - select: - options: - - entitypage03 - ##### PLACEHOLDER ###################################################################### - entities_entity17: - name: Entity 17 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity17_name: - name: Entity 17 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity17_icon: - name: Entity 17 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity18: - name: Entity 18 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity18_name: - name: Entity 18 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity18_icon: - name: Entity 18 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity19: - name: Entity 19 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity19_name: - name: Entity 19 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity19_icon: - name: Entity 19 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity20: - name: Entity 20 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity20_name: - name: Entity 20 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity20_icon: - name: Entity 20 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity21: - name: Entity 21 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity21_name: - name: Entity 21 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity21_icon: - name: Entity 21 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity22: - name: Entity 22 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity22_name: - name: Entity 22 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity22_icon: - name: Entity 22 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity23: - name: Entity 23 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity23_name: - name: Entity 23 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity23_icon: - name: Entity 23 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity24: - name: Entity 24 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity24_name: - name: Entity 24 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity24_icon: - name: Entity 24 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - ##### PLACEHOLDER ###################################################################### - placeholder15: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ ENTITY PAGE 04 ✅ ' - default: 'entitypage04' - selector: - select: - options: - - entitypage04 - ##### PLACEHOLDER ###################################################################### - entities_entity25: - name: Entity 25 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity25_name: - name: Entity 25 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity25_icon: - name: Entity 25 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity26: - name: Entity 26 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity26_name: - name: Entity 26 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity26_icon: - name: Entity 26 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity27: - name: Entity 27 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity27_name: - name: Entity 27 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity27_icon: - name: Entity 27 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity28: - name: Entity 28 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity28_name: - name: Entity 28 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity28_icon: - name: Entity 28 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity29: - name: Entity 29 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity29_name: - name: Entity 29 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity29_icon: - name: Entity 29 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity30: - name: Entity 30 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity30_name: - name: Entity 30 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity30_icon: - name: Entity 30 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity31: - name: Entity 31 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity31_name: - name: Entity 31 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity31_icon: - name: Entity 31 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - entities_entity32: - name: Entity 32 - ENTITY (Optional) - description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' - default: [] - selector: - entity: - entities_entity32_name: - name: Entity 32 name - LABEL (Optional) - description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' - default: [] - selector: - text: {} - entities_entity32_icon: - name: Entity 32 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' - default: [] - selector: *icon-selector - - ##### PLACEHOLDER ###################################################################### - placeholder16: - name: 'Is only a placeholder without function for a better overview' - description: '# ✅ CUSTOM CONFIGURATION ✅ ' - default: 'configuration' - selector: - select: - options: - - configuration - ##### PLACEHOLDER ###################################################################### + ##### Entity pages ##### + ##### Entity pages - Config ##### + ##### PLACEHOLDER ###################################################################### + placeholder11: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ ENTITY PAGE SETTINGS ✅ ' + default: 'entitypage' + selector: + select: + options: + - entitypage + ##### PLACEHOLDER ###################################################################### + entitypages_enabled: + name: Activate entity page - TRUE/FALSE (Optional) + default: false + description: '* *"SYSTEM" - activate entity page and entity page Button on the home page* ' + selector: + boolean: + home_button06_icon: + name: Entity page - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #EDCF) *' + default:  #EDCF + selector: *icon-selector + home_button06_icon_color: + name: Entity page - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [200,204,200] #52857 Grey super light + selector: *color-selector + ##### Entity pages - Labels ##### + ##### PLACEHOLDER ###################################################################### + placeholder12: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ ENTITY PAGE 01 ✅ ' + default: 'entitypage01' + selector: + select: + options: + - entitypage01 + ##### PLACEHOLDER ###################################################################### + entity_page01_label: + name: Entity page 01 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed*' + default: [] + selector: + text: {} + entity_page02_label: + name: Entity page 02 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed*' + default: [] + selector: + text: {} + entity_page03_label: + name: Entity page 03 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed*' + default: [] + selector: + text: {} + entity_page04_label: + name: Entity page 04 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed*' + default: [] + selector: + text: {} + ##### Entity page 01 - Entities ##### + entities_entity01: + name: Entity 01 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity01_name: + name: Entity 01 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity01_icon: + name: Entity 01 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity02: + name: Entity 02 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity02_name: + name: Entity 02 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity02_icon: + name: Entity 02 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity03: + name: Entity 03 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity03_name: + name: Entity 03 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity03_icon: + name: Entity 03 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity04: + name: Entity 04 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity04_name: + name: Entity 04 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity04_icon: + name: Entity 04 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity05: + name: Entity 05 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity05_name: + name: Entity 05 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity05_icon: + name: Entity 05 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity06: + name: Entity 06 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity06_name: + name: Entity 06 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity06_icon: + name: Entity 06 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity07: + name: Entity 07 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity07_name: + name: Entity 07 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity07_icon: + name: Entity 07 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity08: + name: Entity 08 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE01" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity08_name: + name: Entity 08 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE01" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity08_icon: + name: Entity 08 - ICON (Optional) + description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + ##### Entity page 02 - Entities ##### + ##### PLACEHOLDER ###################################################################### + placeholder13: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ ENTITY PAGE 02 ✅ ' + default: 'entitypage02' + selector: + select: + options: + - entitypage02 + ##### PLACEHOLDER ###################################################################### + entities_entity09: + name: Entity 09 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity09_name: + name: Entity 09 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity09_icon: + name: Entity 09 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity10: + name: Entity 10 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity10_name: + name: Entity 10 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity10_icon: + name: Entity 10 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity11: + name: Entity 11 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity11_name: + name: Entity 11 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity11_icon: + name: Entity 11 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity12: + name: Entity 12 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity12_name: + name: Entity 12 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity12_icon: + name: Entity 12 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity13: + name: Entity 13 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity13_name: + name: Entity 13 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity13_icon: + name: Entity 13 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity14: + name: Entity 14 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity14_name: + name: Entity 14 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity14_icon: + name: Entity 14 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity15: + name: Entity 15 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity15_name: + name: Entity 15 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity15_icon: + name: Entity 15 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity16: + name: Entity 16 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE02" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity16_name: + name: Entity 16 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE02" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity16_icon: + name: Entity 16 - ICON (Optional) + description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + ##### Entity page 03 - Entities ##### + ##### PLACEHOLDER ###################################################################### + placeholder14: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ ENTITY PAGE 03 ✅ ' + default: 'entitypage03' + selector: + select: + options: + - entitypage03 + ##### PLACEHOLDER ###################################################################### + entities_entity17: + name: Entity 17 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity17_name: + name: Entity 17 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity17_icon: + name: Entity 17 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity18: + name: Entity 18 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity18_name: + name: Entity 18 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity18_icon: + name: Entity 18 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity19: + name: Entity 19 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity19_name: + name: Entity 19 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity19_icon: + name: Entity 19 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity20: + name: Entity 20 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity20_name: + name: Entity 20 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity20_icon: + name: Entity 20 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity21: + name: Entity 21 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity21_name: + name: Entity 21 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity21_icon: + name: Entity 21 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity22: + name: Entity 22 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity22_name: + name: Entity 22 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity22_icon: + name: Entity 22 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity23: + name: Entity 23 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity23_name: + name: Entity 23 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity23_icon: + name: Entity 23 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity24: + name: Entity 24 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE03" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity24_name: + name: Entity 24 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE03" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity24_icon: + name: Entity 24 - ICON (Optional) + description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + ##### Entity page 04 - Entities ##### + ##### PLACEHOLDER ###################################################################### + placeholder15: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ ENTITY PAGE 04 ✅ ' + default: 'entitypage04' + selector: + select: + options: + - entitypage04 + ##### PLACEHOLDER ###################################################################### + entities_entity25: + name: Entity 25 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity25_name: + name: Entity 25 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity25_icon: + name: Entity 25 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity26: + name: Entity 26 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity26_name: + name: Entity 26 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity26_icon: + name: Entity 26 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity27: + name: Entity 27 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity27_name: + name: Entity 27 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity27_icon: + name: Entity 27 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity28: + name: Entity 28 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity28_name: + name: Entity 28 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity28_icon: + name: Entity 28 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity29: + name: Entity 29 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity29_name: + name: Entity 29 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity29_icon: + name: Entity 29 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity30: + name: Entity 30 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity30_name: + name: Entity 30 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity30_icon: + name: Entity 30 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity31: + name: Entity 31 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity31_name: + name: Entity 31 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity31_icon: + name: Entity 31 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector + entities_entity32: + name: Entity 32 - ENTITY (Optional) + description: '* *Page "ENTITYPAGE04" - entity which should be displayed*' + default: [] + selector: + entity: + entities_entity32_name: + name: Entity 32 name - LABEL (Optional) + description: '* *Page "ENTITYPAGE04" - Label which should be displayed (replaces the **"friendly_name"** of the entity)*' + default: [] + selector: + text: {} + entities_entity32_icon: + name: Entity 32 - ICON (Optional) + description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + default: [] + selector: *icon-selector ##### General Custom Design ##### - home_button04_icon: - name: Notification - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E1ED) *' - default:  #E1ED - selector: *icon-selector - home_button04_icon_color01: - name: Notification read - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [200,204,200] #52857 Grey super light #Grey super light - selector: *color-selector - home_button04_icon_color02: - name: Notification unread - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [248,0,0] #63488 Red - selector: *color-selector - relay01_icon: - name: Relay 01 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E3A5) *' - default:  #E3A5 - selector: *icon-selector - relay01_icon_color: - name: Relay 01 - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - relay02_icon: - name: Relay 02 - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E3A8) *' - default:  #E3A8 - selector: *icon-selector - relay02_icon_color: - name: Relay - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - thermostat_icon: - name: Thermostat - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E50E) *' - default:  #E50E - selector: *icon-selector - heat_icon: - name: Thermostat - ICON (Optional) - description: '* *Page "HOME" - Icon which should be displayed (Default #E50F) *' - default:  #E50F - selector: *icon-selector - thermostat_icon_color: - name: Thermostat / Heat - ICON COLOR (Optional) - description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' - default: [128,128,128] #33808 Grey light - selector: *color-selector - time_label_color: - name: Time - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed (default color is set)*' - default: [255,255,255] #65535 White - selector: *color-selector - date_label_color: - name: Date - LABEL COLOR (Optional) - description: '* *Page "HOME" - Label color which should be displayed (default color is set)*' - default: [255,255,255] #65535 White - selector: *color-selector + ##### PLACEHOLDER ###################################################################### + placeholder16: + name: 'Is only a placeholder without function for a better overview' + description: '# ✅ CUSTOM CONFIGURATION ✅ ' + default: 'configuration' + selector: + select: + options: + - configuration + ##### PLACEHOLDER ###################################################################### + home_button04_icon: + name: Notification - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E1ED) *' + default:  #E1ED + selector: *icon-selector + home_button04_icon_color01: + name: Notification read - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [200,204,200] #52857 Grey super light #Grey super light + selector: *color-selector + home_button04_icon_color02: + name: Notification unread - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [248,0,0] #63488 Red + selector: *color-selector + relay01_icon: + name: Relay 01 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E3A5) *' + default:  #E3A5 + selector: *icon-selector + relay01_icon_color: + name: Relay 01 - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + relay02_icon: + name: Relay 02 - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E3A8) *' + default:  #E3A8 + selector: *icon-selector + relay02_icon_color: + name: Relay - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + thermostat_icon: + name: Thermostat - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E50E) *' + default:  #E50E + selector: *icon-selector + heat_icon: + name: Thermostat - ICON (Optional) + description: '* *Page "HOME" - Icon which should be displayed (Default #E50F) *' + default:  #E50F + selector: *icon-selector + thermostat_icon_color: + name: Thermostat / Heat - ICON COLOR (Optional) + description: '* *Page "HOME" - Icon color which should be displayed (default color is set)*' + default: [128,128,128] #33808 Grey light + selector: *color-selector + time_label_color: + name: Time - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed (default color is set)*' + default: [255,255,255] #65535 White + selector: *color-selector + date_label_color: + name: Date - LABEL COLOR (Optional) + description: '* *Page "HOME" - Label color which should be displayed (default color is set)*' + default: [255,255,255] #65535 White + selector: *color-selector -###### Muss noch Raus ############################################################################################################################################################################### - hotwatertemp: - name: Hot Water Temperature Sensor (Optional) - description: '* *Choose your hot water sensor*' - default: [] - selector: - entity: - domain: - - sensor - tft_path: - name: Nextion TFT File Folder (Optional) - description: '* *TFT Path where the Nextion TFT File is stored. Attention! The **"Folder-Watcher"** must also be configured in the configuration.yaml. **Only necessary for manual upload of TFT file in ESPHome Advaced mode.** See HowTo*' - default: [] - selector: - text: {} - sync_value_ha: - name: Synchronization of all values (Optional) - description: '* *Synchronization of values between HA and NSPanel for Lightsetting and Coversetting Page -> Maybe causes number jumps*' - default: 'select_no' - selector: &sync-selector-bool - select: - options: - - label: 'No' - value: select_no - - label: 'Yes' - value: select_yes - sync_slider_ha: - name: Synchronization of all Sliders (Optional) - description: '* *Synchronization of sliders between HA and NSPanel for Lightsetting and Coversetting Page -> Maybe causes flickering on the Slider*' - default: 'select_no' - selector: *sync-selector-bool - - -mode: parallel -max: 5000 -trace: - stored_traces: 10 + ###### Muss noch Raus ############################################################################################################################################################################### + hotwatertemp: + name: Hot Water Temperature Sensor (Optional) + description: '* *Choose your hot water sensor*' + default: [] + selector: + entity: + domain: + - sensor + tft_path: + name: Nextion TFT File Folder (Optional) + description: '* *TFT Path where the Nextion TFT File is stored. Attention! The **"Folder-Watcher"** must also be configured in the configuration.yaml. **Only necessary for manual upload of TFT file in ESPHome Advaced mode.** See HowTo*' + default: [] + selector: + text: {} + sync_value_ha: + name: Synchronization of all values (Optional) + description: '* *Synchronization of values between HA and NSPanel for Lightsetting and Coversetting Page -> Maybe causes number jumps*' + default: 'select_no' + selector: &sync-selector-bool + select: + options: + - label: 'No' + value: select_no + - label: 'Yes' + value: select_yes + sync_slider_ha: + name: Synchronization of all Sliders (Optional) + description: '* *Synchronization of sliders between HA and NSPanel for Lightsetting and Coversetting Page -> Maybe causes flickering on the Slider*' + default: 'select_no' + selector: *sync-selector-bool ############################################################# ##### CLOSE - INPUT ##### ############################################################# +mode: parallel +max: 5000 +trace: + stored_traces: 10 ############################################################# ##### START - Variables ##### @@ -2356,28 +2355,111 @@ trigger_variables: variables: ##### GENERAL ##### - blueprint_version: "3.2.2" + blueprint_version: "3.2.3DEV" language: !input "language" - date_format: !input "date_format" time_format: !input "time_format" time: "{{ as_timestamp(now()) | timestamp_custom(time_format) }}" meridiem: "{{ as_timestamp(now()) | timestamp_custom('%p') if time_format == '%-I:%M' else '' }}" + sun_is_up: "{{ is_state('sun.sun', 'above_horizon') }}" notification_sound: "switch.{{ nspanel_name }}_notification_sound" confirmation_message: "switch.{{ nspanel_name }}_confirmation_message" ##### Nextion dict #### nextion: + colors: + blue: "1055" # rgb(0,128,248) + grey_dark: "10597" # rgb(40,44,40) + grey_light: "33808" # rgb(128,128,128) + grey_super_light: "52857" # rgb(200,204,200) + red: "63488" # rgb(248,0,0) + white: "65535" # rgb(255,255,255) + yellow: "65472" # rgb(248,248,0) + commands: + text_printf: "esphome.{{ nspanel_name }}_send_command_text_printf" + value: "esphome.{{ nspanel_name }}_send_command_value" + printf: "esphome.{{ nspanel_name }}_send_command_printf" + font_color: "esphome.{{ nspanel_name }}_send_command_font_color" + background_color: "esphome.{{ nspanel_name }}_send_command_background_color" + thermostat_cycle: "esphome.{{ nspanel_name }}_send_thermostat_cycle_state" + notification_show: "esphome.{{ nspanel_name }}_notification_show" + notification_clear: "esphome.{{ nspanel_name }}_notification_clear" + play_rtttl: "esphome.{{ nspanel_name }}_play_rtttl" + set_settings_entity: "esphome.{{ nspanel_name }}_set_settings_entity" + show_all: "esphome.{{ nspanel_name }}_send_command_show_all" + tft_upload: "esphome.{{ nspanel_name }}_upload_tft" + set_button: "esphome.{{ nspanel_name }}_set_button" icons: + battery: "\U0000F2A1" #F2A1 + blank: "\U0000FFFF" #blank macbook bug + buttons: + automation: "\U0000F6FC" #F6FC + binary_sensor: "\U0000E7C0" #E7C0 + button: "\U0000ED76" #ED76 + climate: "\U0000E392" #E392 + cover: "\U0000E0AB" #E0AB + fan: "\U0000E20F" #E20F + input_boolean: "\U0000EA19" #EA19 + input_button: "\U0000F2A7" #F2A7 + light: "\U0000E334" #E334 + person: "\U0000E003" #E003 + scene: "\U0000EE0B" #EE0B + script: "\U0000F45D" #F45D + switch: "\U0000E97D" #E97D + unknown: "\U00000E27" #E027 weather: lightning: "\U0000E592" #E592 protect: "\U0000F05C" #F05C - rain: "\U0000E595" #E595 + rain: "\U0000E595" #E595 sun: "\U0000E5A7" #E5A7 - wind: "\U0000E59C" #E59C + wind: "\U0000E59C" #E59C + pages: + home: "home" + weatherpages: + - "weather01" + - "weather02" + - "weather03" + - "weather04" + - "weather05" + climate: "climate" + settings: "settings" + boot: "boot" + screensaver: "screensaver" + light: "lightsettings" + cover: "coversettings" + buttonpages: + - "buttonpage01" + - "buttonpage02" + - "buttonpage03" + - "buttonpage04" + notification: "notification" + qrcode: "qrcode" + entitypages: + - "entitypage01" + - "entitypage02" + - "entitypage03" + - "entitypage04" + current: "{{ states(current_page) | default('unavailable') if current_page is string else 'unavailable' }}" pics: + hvac: + button: + blank: "79" + 'off': "80" + 'on': "81" + unknown: "79" + hardware: + button: + "off": "77" + "on": "78" + button: + 'off': "101" + 'on': "102" + heating: + button: + "off": "82" + "on": "83" weather: - sunny: "{{ '2' if is_state('sun.sun', 'above_horizon') else '15'}}" #some weather providers returns 'sunny' for 'clear-night' + sunny: "{{ '2' if sun_is_up else '15'}}" #some weather providers returns 'sunny' for 'clear-night' cloudy: "3" rainy: "4" pouring: "5" @@ -2387,636 +2469,18 @@ variables: fog: "8" windy: "9" windy_variant: "9" + windy-variant: "9" lightning: "10" - partlycloudy: "{{ '11' if is_state('sun.sun', 'above_horizon') else '12'}}" - lightning_rainy: "{{ '13' if is_state('sun.sun', 'above_horizon') else '14'}}" - execptional: "{{ '13' if is_state('sun.sun', 'above_horizon') else '14'}}" + partlycloudy: "{{ '11' if sun_is_up else '12'}}" + lightning_rainy: "{{ '13' if sun_is_up else '14'}}" + execptional: "{{ '13' if sun_is_up else '14'}}" clear_night: "15" - unknown: "" - unavailable: "" - - ##### WEATHER #### - weather_entity: !input "weather_entity" # used only during the creation of weather in variables - weather: - type: !input "weather" - entity: !input "weather_entity" - name: '{{ weather_entity | replace("weather.","") }}' # used only during the creation of accuweather in variables - units: - hours_of_sun: "{{ state_attr(weather_entity, 'hours_of_sun_unit') if state_attr(weather_entity, 'hours_of_sun_unit') else 'h' }}" - precipitation: "{{ state_attr(weather_entity, 'precipitation_unit') if state_attr(weather_entity, 'precipitation_unit') else 'mm' }}" - precipitation_probability: "{{ state_attr(weather_entity, 'precipitation_probability_unit') if state_attr(weather_entity, 'precipitation_probability_unit') else '%' }}" - pressure: "{{ state_attr(weather_entity, 'temperature_unit') if state_attr(weather_entity, 'pressure_unit') }}" - temperature: "{{ state_attr(weather_entity, 'temperature_unit') if state_attr(weather_entity, 'temperature_unit') else '°' }}" - thunderstorm_probability: "{{ state_attr(weather_entity, 'thunderstorm_probability_unit') if state_attr(weather_entity, 'thunderstorm_probability_unit') else '%' }}" - uv_index: "{{ state_attr(weather_entity, 'uv_index_unit') if state_attr(weather_entity, 'uv_index_unit') }}" - visibility: "{{ state_attr(weather_entity, 'visibility_unit') if state_attr(weather_entity, 'visibility_unit') }}" - wind_speed: "{{ state_attr(weather_entity, 'wind_speed_unit') if state_attr(weather_entity, 'wind_speed_unit') }}" - - ##### PUSH TO NEXTION DISPLAY ##### - command_text_printf: "esphome.{{ nspanel_name }}_send_command_text_printf" - command_value: "esphome.{{ nspanel_name }}_send_command_value" - command_printf: "esphome.{{ nspanel_name }}_send_command_printf" - command_font_color: "esphome.{{ nspanel_name }}_send_command_font_color" - command_background_color: "esphome.{{ nspanel_name }}_send_command_background_color" - command_thermostat_cycle: "esphome.{{ nspanel_name }}_send_thermostat_cycle_state" - command_notification_show: "esphome.{{ nspanel_name }}_notification_show" - command_notification_clear: "esphome.{{ nspanel_name }}_notification_clear" - command_play_rtttl: "esphome.{{ nspanel_name }}_play_rtttl" - command_set_settings_entity: "esphome.{{ nspanel_name }}_set_settings_entity" - command_show_all: "esphome.{{ nspanel_name }}_send_command_show_all" - command_set_button: "esphome.{{ nspanel_name }}_set_button" - - ###### SYNC SETTINGS ##### - delay_boot: !input "delay" - delay_value: !input "delay" - delay_jump_page: !input "delay" - sync_slider_ha: !input "sync_slider_ha" - sync_value_ha: !input "sync_value_ha" - climate_optimistic: !input "climate_optimistic" - - ##### TFT UPLOAD ##### - tft_upload: "esphome.{{ nspanel_name }}_upload_tft" - tft_path: !input "tft_path" - - ##### GENERAL ENTITYS ##### - hotwatertemp: !input "hotwatertemp" - outdoortemp: !input "outdoortemp" - indoortemp: !input "indoortemp" - climate: !input "climate" - qrcode_label: !input "qrcode_label" - qrcode_value: !input "qrcode_value" - qrcode_enabled: !input "qrcode_enabled" - relay_1_local_fallback: !input "relay_1_local_fallback" - relay_2_local_fallback: !input "relay_2_local_fallback" - - #### HARDWARE BUTTONS ##### - left_button_entity: !input "left_button_entity" - left_button_name: !input "left_button_name" - right_button_entity: !input "right_button_entity" - right_button_name: !input "right_button_name" - left_button_hold_select: !input "left_button_hold_select" - right_button_hold_select: !input "right_button_hold_select" - - ##### NEXTION PIC MAPPING ##### - - # button_light_off: "62" - # button_light_on: "63" - # button_switch_off: "64" - # button_switch_on: "65" - # button_cover_off: "66" - # button_cover_on: "67" - # button_automation_off: "107" - # button_automation_on: "108" - # button_button_off: "109" - # button_button_on: "110" - # button_scene_off: "113" - # button_scene_on: "114" - # button_person_off: "111" - # button_person_on: "112" - # button_script_off: "107" - # button_script_on: "108" - # button_binary_sensor_off: '107' - # button_binary_sensor_on: '108' - # button_fan_off: "121" - # button_fan_on: "122" - # button_climate_off: "121" - # button_climate_on: "122" + clear-night: "15" + unknown: '' + unavailable: '' - # cover_pic_closed: "78" - # cover_pic_open: "79" - # light_pic_off: "96" - # light_pic_on: "97" - # # hotwater_pic_off: "60" - # hotwater_pic_on: "61" - # flame_pic_on: "57" - # # flame_pic_off: "60" - # top_menu_blank: "60" - - hotw_bt_blank: "79" - hotw_bt_off: "80" - hotw_bt_on: "81" - - - -##### CHANGE ME START ########################################################################################################## - ###### GENERAL - NEXTION COLOR MAPPING ##### - color_01: "65535" #White rgb(255,255,255) - color_02: "10597" #Grey dark rgb(40,44,40) - color_03: "33808" #Grey light rgb(128,128,128) - color_04: "1055" #Blue rgb(0,128,248) - color_05: "63488" #Red rgb(248,0,0) - color_06: "52857" #Grey super light rgb(200,204,200) - color_07: "65472" #Yellow rgb(248,248,0) - - ###### "GENERAL" NEXTION FONT ICON MAPPING ##### - blank_icon: "\U0000FFFF" #blank macbook bug - battery_icon: "\U0000F2A1" #F2A1 - battery_icon_color: "52857" #Grey super light - - ###### "BUTTON" NEXTION FONT ICON MAPPING ##### - button_icon_unknown: "\U00000E27" #E027 - button_icon_light: "\U0000E334" #E334 - button_icon_switch: "\U0000E97D" #E97D - button_icon_input_boolan: "\U0000EA19" #EA19 - button_icon_cover: "\U0000E0AB" #E0AB - button_icon_automation: "\U0000F6FC" #F6FC - button_icon_button: "\U0000ED76" #ED76 - button_icon_input_button: "\U0000F2A7" #F2A7 - button_icon_scene: "\U0000EE0B" #EE0B - button_icon_script: "\U0000F45D" #F45D - button_icon_person: "\U0000E003" #E003 - button_icon_binary_sensor: "\U0000E7C0" #E7C0 - button_icon_fan: "\U0000E20F" #E20F - button_icon_climate: "\U0000E392" #E392 - -##### CHANGE ME END ########################################################################################################## - - - - ### Home Page - Feature Buttons ### - home_button01_icon: "" - home_button01_icon_color01: "" - home_button02_icon: "" - home_button02_icon_color02: "" - home_button03_icon: "" - home_button03_icon_color03: "" - home_button04_icon: !input "home_button04_icon" #E1ED - home_button04_icon_color01_value: !input "home_button04_icon_color01" - home_button04_icon_color01: '{% set rgb = home_button04_icon_color01_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_button04_icon_color02_value: !input "home_button04_icon_color02" - home_button04_icon_color02: '{% set rgb = home_button04_icon_color02_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_button05_icon: !input "home_button05_icon" #E432 - home_button05_icon_color_value: !input "home_button05_icon_color" - home_button05_icon_color: '{% set rgb = home_button05_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_button06_icon: !input "home_button06_icon" #EDCF - home_button06_icon_color_value: !input "home_button06_icon_color" - home_button06_icon_color: '{% set rgb = home_button06_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_button07_icon: "" - home_button07_icon_color: "" - - ### Home Page - Value 01 - 03 - home_value01: !input "home_value01" - home_value01_icon: !input "home_value01_icon" - home_value01_icon_color_value: !input "home_value01_icon_color" - home_value01_icon_color: '{% set rgb = home_value01_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_value01_label_color_value: !input "home_value01_label_color" - home_value01_label_color: '{% set rgb = home_value01_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_value02: !input "home_value02" - home_value02_icon: !input "home_value02_icon" - home_value02_icon_color_value: !input "home_value02_icon_color" - home_value02_icon_color: '{% set rgb = home_value02_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_value02_label_color_value: !input "home_value02_label_color" - home_value02_label_color: '{% set rgb = home_value02_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_value03: !input "home_value03" - home_value03_icon: !input "home_value03_icon" - home_value03_icon_color_value: !input "home_value03_icon_color" - home_value03_icon_color: '{% set rgb = home_value03_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_value03_label_color_value: !input "home_value03_label_color" - home_value03_label_color: '{% set rgb = home_value03_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - - ### Home Page - Chips ### - chip01: !input "chip01" - chip01_icon: !input "chip01_icon" - chip01_icon_color_value: !input "chip01_icon_color" - chip01_icon_color: '{% set rgb = chip01_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - chip02: !input "chip02" - chip02_icon: !input "chip02_icon" - chip02_icon_color_value: !input "chip02_icon_color" - chip02_icon_color: '{% set rgb = chip02_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - chip03: !input "chip03" - chip03_icon: !input "chip03_icon" - chip03_icon_color_value: !input "chip03_icon_color" - chip03_icon_color: '{% set rgb = chip03_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - chip04: !input "chip04" - chip04_icon: !input "chip04_icon" - chip04_icon_color_value: !input "chip04_icon_color" - chip04_icon_color: '{% set rgb = chip04_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - chip05: !input "chip05" - chip05_icon: !input "chip05_icon" - chip05_icon_color_value: !input "chip05_icon_color" - chip05_icon_color: '{% set rgb = chip05_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - chip06: !input "chip06" - chip06_icon: !input "chip06_icon" - chip06_icon_color_value: !input "chip06_icon_color" - chip06_icon_color: '{% set rgb = chip06_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - chip07: !input "chip07" - chip07_icon: !input "chip07_icon" - chip07_icon_color_value: !input "chip07_icon_color" - chip07_icon_color: '{% set rgb = chip07_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - - ### Home Page - Chips General ### - relay01_icon: !input "relay01_icon" #E3A5 - relay01_icon_color_value: !input "relay01_icon_color" - relay01_icon_color: '{% set rgb = relay01_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - relay02_icon: !input "relay02_icon" #E3A8 - relay02_icon_color_value: !input "relay02_icon_color" - relay02_icon_color: '{% set rgb = relay02_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - thermostat_icon: !input "thermostat_icon" #E50E - thermostat_icon_color_value: !input "thermostat_icon_color" - thermostat_icon_color: '{% set rgb = thermostat_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - heat_icon: !input "heat_icon" #\U0000E50F - - ### Home Page - General ### - home_outdoor_temp_label_color_value: !input "home_outdoor_temp_label_color" - home_outdoor_temp_label_color: '{% set rgb = home_outdoor_temp_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_indoor_temp_icon: !input "home_indoor_temp_icon" #E50E - home_indoor_temp_icon_color_value: !input "home_indoor_temp_icon_color" - home_indoor_temp_icon_color: '{% set rgb = home_indoor_temp_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - home_indoor_temp_label_color_value: !input "home_indoor_temp_label_color" - home_indoor_temp_label_color: '{% set rgb = home_indoor_temp_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - time_label_color_value: !input "time_label_color" - time_label_color: '{% set rgb = time_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - date_label_color_value: !input "date_label_color" - date_label_color: '{% set rgb = date_label_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - right_button_color_value: !input "right_button_color" - right_button_color: '{% set rgb = right_button_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - left_button_color_value: !input "left_button_color" - left_button_color: '{% set rgb = left_button_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - - ##### BUTTON Page Labels ##### - button_page01_label: !input button_page01_label - button_page02_label: !input button_page02_label - button_page03_label: !input button_page03_label - button_page04_label: !input button_page04_label - - ##### BUTTONS 1- 32 ##### - entity01: !input "entity01" - entity01_name: !input "entity01_name" - entity01_icon: !input "entity01_icon" - entity01_icon_color_value: !input "entity01_icon_color" - entity01_icon_color: '{% set rgb = entity01_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity01_confirm: !input "entity01_confirm" - - entity02: !input "entity02" - entity02_name: !input "entity02_name" - entity02_icon: !input "entity02_icon" - entity02_icon_color_value: !input "entity02_icon_color" - entity02_icon_color: '{% set rgb = entity02_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity02_confirm: !input "entity02_confirm" - - entity03: !input "entity03" - entity03_name: !input "entity03_name" - entity03_icon: !input "entity03_icon" - entity03_icon_color_value: !input "entity03_icon_color" - entity03_icon_color: '{% set rgb = entity03_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity03_confirm: !input "entity03_confirm" - - entity04: !input "entity04" - entity04_name: !input "entity04_name" - entity04_icon: !input "entity04_icon" - entity04_icon_color_value: !input "entity04_icon_color" - entity04_icon_color: '{% set rgb = entity04_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity04_confirm: !input "entity04_confirm" - - entity05: !input "entity05" - entity05_name: !input "entity05_name" - entity05_icon: !input "entity05_icon" - entity05_icon_color_value: !input "entity05_icon_color" - entity05_icon_color: '{% set rgb = entity05_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity05_confirm: !input "entity05_confirm" - - entity06: !input "entity06" - entity06_name: !input "entity06_name" - entity06_icon: !input "entity06_icon" - entity06_icon_color_value: !input "entity06_icon_color" - entity06_icon_color: '{% set rgb = entity06_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity06_confirm: !input "entity06_confirm" - - entity07: !input "entity07" - entity07_name: !input "entity07_name" - entity07_icon: !input "entity07_icon" - entity07_icon_color_value: !input "entity07_icon_color" - entity07_icon_color: '{% set rgb = entity07_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity07_confirm: !input "entity07_confirm" - - entity08: !input "entity08" - entity08_name: !input "entity08_name" - entity08_icon: !input "entity08_icon" - entity08_icon_color_value: !input "entity08_icon_color" - entity08_icon_color: '{% set rgb = entity08_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity08_confirm: !input "entity08_confirm" - - entity09: !input "entity09" - entity09_name: !input "entity09_name" - entity09_icon: !input "entity09_icon" - entity09_icon_color_value: !input "entity09_icon_color" - entity09_icon_color: '{% set rgb = entity09_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity09_confirm: !input "entity09_confirm" - - entity10: !input "entity10" - entity10_name: !input "entity10_name" - entity10_icon: !input "entity10_icon" - entity10_icon_color_value: !input "entity10_icon_color" - entity10_icon_color: '{% set rgb = entity10_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity10_confirm: !input "entity10_confirm" - - entity11: !input "entity11" - entity11_name: !input "entity11_name" - entity11_icon: !input "entity11_icon" - entity11_icon_color_value: !input "entity11_icon_color" - entity11_icon_color: '{% set rgb = entity11_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity11_confirm: !input "entity11_confirm" - - entity12: !input "entity12" - entity12_name: !input "entity12_name" - entity12_icon: !input "entity12_icon" - entity12_icon_color_value: !input "entity12_icon_color" - entity12_icon_color: '{% set rgb = entity12_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity12_confirm: !input "entity12_confirm" - - entity13: !input "entity13" - entity13_name: !input "entity13_name" - entity13_icon: !input "entity13_icon" - entity13_icon_color_value: !input "entity13_icon_color" - entity13_icon_color: '{% set rgb = entity13_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity13_confirm: !input "entity13_confirm" - - entity14: !input "entity14" - entity14_name: !input "entity14_name" - entity14_icon: !input "entity14_icon" - entity14_icon_color_value: !input "entity14_icon_color" - entity14_icon_color: '{% set rgb = entity14_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity14_confirm: !input "entity14_confirm" - - entity15: !input "entity15" - entity15_name: !input "entity15_name" - entity15_icon: !input "entity15_icon" - entity15_icon_color_value: !input "entity15_icon_color" - entity15_icon_color: '{% set rgb = entity15_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity15_confirm: !input "entity15_confirm" - - entity16: !input "entity16" - entity16_name: !input "entity16_name" - entity16_icon: !input "entity16_icon" - entity16_icon_color_value: !input "entity16_icon_color" - entity16_icon_color: '{% set rgb = entity16_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity16_confirm: !input "entity16_confirm" - - entity17: !input "entity17" - entity17_name: !input "entity17_name" - entity17_icon: !input "entity17_icon" - entity17_icon_color_value: !input "entity17_icon_color" - entity17_icon_color: '{% set rgb = entity17_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity17_confirm: !input "entity17_confirm" - - entity18: !input "entity18" - entity18_name: !input "entity18_name" - entity18_icon: !input "entity18_icon" - entity18_icon_color_value: !input "entity18_icon_color" - entity18_icon_color: '{% set rgb = entity18_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity18_confirm: !input "entity18_confirm" - - entity19: !input "entity19" - entity19_name: !input "entity19_name" - entity19_icon: !input "entity19_icon" - entity19_icon_color_value: !input "entity19_icon_color" - entity19_icon_color: '{% set rgb = entity19_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity19_confirm: !input "entity19_confirm" - - entity20: !input "entity20" - entity20_name: !input "entity20_name" - entity20_icon: !input "entity20_icon" - entity20_icon_color_value: !input "entity20_icon_color" - entity20_icon_color: '{% set rgb = entity20_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity20_confirm: !input "entity20_confirm" - - entity21: !input "entity21" - entity21_name: !input "entity21_name" - entity21_icon: !input "entity21_icon" - entity21_icon_color_value: !input "entity21_icon_color" - entity21_icon_color: '{% set rgb = entity21_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity21_confirm: !input "entity21_confirm" - - entity22: !input "entity22" - entity22_name: !input "entity22_name" - entity22_icon: !input "entity22_icon" - entity22_icon_color_value: !input "entity22_icon_color" - entity22_icon_color: '{% set rgb = entity22_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity22_confirm: !input "entity22_confirm" - - entity23: !input "entity23" - entity23_name: !input "entity23_name" - entity23_icon: !input "entity23_icon" - entity23_icon_color_value: !input "entity23_icon_color" - entity23_icon_color: '{% set rgb = entity23_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity23_confirm: !input "entity23_confirm" - - entity24: !input "entity24" - entity24_name: !input "entity24_name" - entity24_icon: !input "entity24_icon" - entity24_icon_color_value: !input "entity24_icon_color" - entity24_icon_color: '{% set rgb = entity24_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity24_confirm: !input "entity24_confirm" - - entity25: !input "entity25" - entity25_name: !input "entity25_name" - entity25_icon: !input "entity25_icon" - entity25_icon_color_value: !input "entity25_icon_color" - entity25_icon_color: '{% set rgb = entity25_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity25_confirm: !input "entity25_confirm" - - entity26: !input "entity26" - entity26_name: !input "entity26_name" - entity26_icon: !input "entity26_icon" - entity26_icon_color_value: !input "entity26_icon_color" - entity26_icon_color: '{% set rgb = entity26_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity26_confirm: !input "entity26_confirm" - - entity27: !input "entity27" - entity27_name: !input "entity27_name" - entity27_icon: !input "entity27_icon" - entity27_icon_color_value: !input "entity27_icon_color" - entity27_icon_color: '{% set rgb = entity27_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity27_confirm: !input "entity27_confirm" - - entity28: !input "entity28" - entity28_name: !input "entity28_name" - entity28_icon: !input "entity28_icon" - entity28_icon_color_value: !input "entity28_icon_color" - entity28_icon_color: '{% set rgb = entity28_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity28_confirm: !input "entity28_confirm" - - entity29: !input "entity29" - entity29_name: !input "entity29_name" - entity29_icon: !input "entity29_icon" - entity29_icon_color_value: !input "entity29_icon_color" - entity29_icon_color: '{% set rgb = entity29_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity29_confirm: !input "entity29_confirm" - - entity30: !input "entity30" - entity30_name: !input "entity30_name" - entity30_icon: !input "entity30_icon" - entity30_icon_color_value: !input "entity30_icon_color" - entity30_icon_color: '{% set rgb = entity30_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity30_confirm: !input "entity30_confirm" - - entity31: !input "entity31" - entity31_name: !input "entity31_name" - entity31_icon: !input "entity31_icon" - entity31_icon_color_value: !input "entity31_icon_color" - entity31_icon_color: '{% set rgb = entity31_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity31_confirm: !input "entity31_confirm" - - entity32: !input "entity32" - entity32_name: !input "entity32_name" - entity32_icon: !input "entity32_icon" - entity32_icon_color_value: !input "entity32_icon_color" - entity32_icon_color: '{% set rgb = entity32_icon_color_value %}{{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }}' - entity32_confirm: !input "entity32_confirm" - - ##### ENTITIES ##### - entitypages_enabled: !input "entitypages_enabled" - - ##### ENTITY Page Labels ##### - entity_page01_label: !input "entity_page01_label" - entity_page02_label: !input "entity_page02_label" - entity_page03_label: !input "entity_page03_label" - entity_page04_label: !input "entity_page04_label" - - ##### ENTITIES 1- 32 ##### - ## page 01 - entities_entity01: !input "entities_entity01" - entities_entity02: !input "entities_entity02" - entities_entity03: !input "entities_entity03" - entities_entity04: !input "entities_entity04" - entities_entity05: !input "entities_entity05" - entities_entity06: !input "entities_entity06" - entities_entity07: !input "entities_entity07" - entities_entity08: !input "entities_entity08" - ## page 02 - entities_entity09: !input "entities_entity09" - entities_entity10: !input "entities_entity10" - entities_entity11: !input "entities_entity11" - entities_entity12: !input "entities_entity12" - entities_entity13: !input "entities_entity13" - entities_entity14: !input "entities_entity14" - entities_entity15: !input "entities_entity15" - entities_entity16: !input "entities_entity16" - ## page 03 - entities_entity17: !input "entities_entity17" - entities_entity18: !input "entities_entity18" - entities_entity19: !input "entities_entity19" - entities_entity20: !input "entities_entity20" - entities_entity21: !input "entities_entity21" - entities_entity22: !input "entities_entity22" - entities_entity23: !input "entities_entity23" - entities_entity24: !input "entities_entity24" - ## page 04 - entities_entity25: !input "entities_entity25" - entities_entity26: !input "entities_entity26" - entities_entity27: !input "entities_entity27" - entities_entity28: !input "entities_entity28" - entities_entity29: !input "entities_entity29" - entities_entity30: !input "entities_entity30" - entities_entity31: !input "entities_entity31" - entities_entity32: !input "entities_entity32" - ## page 01 - name - entities_entity01_name: !input "entities_entity01_name" - entities_entity02_name: !input "entities_entity02_name" - entities_entity03_name: !input "entities_entity03_name" - entities_entity04_name: !input "entities_entity04_name" - entities_entity05_name: !input "entities_entity05_name" - entities_entity06_name: !input "entities_entity06_name" - entities_entity07_name: !input "entities_entity07_name" - entities_entity08_name: !input "entities_entity08_name" - ## page 02 - name - entities_entity09_name: !input "entities_entity09_name" - entities_entity10_name: !input "entities_entity10_name" - entities_entity11_name: !input "entities_entity11_name" - entities_entity12_name: !input "entities_entity12_name" - entities_entity13_name: !input "entities_entity13_name" - entities_entity14_name: !input "entities_entity14_name" - entities_entity15_name: !input "entities_entity15_name" - entities_entity16_name: !input "entities_entity16_name" - ## page 03 - name - entities_entity17_name: !input "entities_entity17_name" - entities_entity18_name: !input "entities_entity18_name" - entities_entity19_name: !input "entities_entity19_name" - entities_entity20_name: !input "entities_entity20_name" - entities_entity21_name: !input "entities_entity21_name" - entities_entity22_name: !input "entities_entity22_name" - entities_entity23_name: !input "entities_entity23_name" - entities_entity24_name: !input "entities_entity24_name" - ## page 04 - name - entities_entity25_name: !input "entities_entity25_name" - entities_entity26_name: !input "entities_entity26_name" - entities_entity27_name: !input "entities_entity27_name" - entities_entity28_name: !input "entities_entity28_name" - entities_entity29_name: !input "entities_entity29_name" - entities_entity30_name: !input "entities_entity30_name" - entities_entity31_name: !input "entities_entity31_name" - entities_entity32_name: !input "entities_entity32_name" - ## page 01 - icon - entities_entity01_icon: !input "entities_entity01_icon" - entities_entity02_icon: !input "entities_entity02_icon" - entities_entity03_icon: !input "entities_entity03_icon" - entities_entity04_icon: !input "entities_entity04_icon" - entities_entity05_icon: !input "entities_entity05_icon" - entities_entity06_icon: !input "entities_entity06_icon" - entities_entity07_icon: !input "entities_entity07_icon" - entities_entity08_icon: !input "entities_entity08_icon" - ## page 02 - icon - entities_entity09_icon: !input "entities_entity09_icon" - entities_entity10_icon: !input "entities_entity10_icon" - entities_entity11_icon: !input "entities_entity11_icon" - entities_entity12_icon: !input "entities_entity12_icon" - entities_entity13_icon: !input "entities_entity13_icon" - entities_entity14_icon: !input "entities_entity14_icon" - entities_entity15_icon: !input "entities_entity15_icon" - entities_entity16_icon: !input "entities_entity16_icon" - ## page 03 - icon - entities_entity17_icon: !input "entities_entity17_icon" - entities_entity18_icon: !input "entities_entity18_icon" - entities_entity19_icon: !input "entities_entity19_icon" - entities_entity20_icon: !input "entities_entity20_icon" - entities_entity21_icon: !input "entities_entity21_icon" - entities_entity22_icon: !input "entities_entity22_icon" - entities_entity23_icon: !input "entities_entity23_icon" - entities_entity24_icon: !input "entities_entity24_icon" - ## page 04 - icon - entities_entity25_icon: !input "entities_entity25_icon" - entities_entity26_icon: !input "entities_entity26_icon" - entities_entity27_icon: !input "entities_entity27_icon" - entities_entity28_icon: !input "entities_entity28_icon" - entities_entity29_icon: !input "entities_entity29_icon" - entities_entity30_icon: !input "entities_entity30_icon" - entities_entity31_icon: !input "entities_entity31_icon" - entities_entity32_icon: !input "entities_entity32_icon" - - ###### NEXTION PIC MAPPING ##### - hardware_button_pic_off: "77" - hardware_button_pic_on: "78" - button_off: "101" - button_on: "102" - heating_bt_pic_off: "82" - heating_bt_pic_on: "83" - - ###### NEXTION PAGE MAPPING ##### - page_home: "home" - page_weather01: "weather01" - page_weather02: "weather02" - page_weather03: "weather03" - page_weather04: "weather04" - page_weather05: "weather05" - page_climate: "climate" - page_settings: "settings" - page_boot: "boot" - page_screensaver: "screensaver" - page_lightsettings: "lightsettings" - page_coversettings: "coversettings" - page_buttonpage01: "buttonpage01" - page_buttonpage02: "buttonpage02" - page_buttonpage03: "buttonpage03" - page_buttonpage04: "buttonpage04" - page_notification: "notification" - page_qrcode: "qrcode" - page_entitypage01: "entitypage01" - page_entitypage02: "entitypage02" - page_entitypage03: "entitypage03" - page_entitypage04: "entitypage04" - -##### MUI Multilingual User Interface (DE/EN) ##### + ##### MUI Multilingual User Interface ##### mui: BGR: weekdays: @@ -3039,6 +2503,8 @@ variables: "off": изключване heat: топлина please_confirm: Моля, потвърдете + unavailable: Unavailable + no_name: No name CZE: weekdays: mon: Pondělí @@ -3060,6 +2526,8 @@ variables: "off": vypnuto heat: topení please_confirm: Potvrďte prosím + unavailable: Unavailable + no_name: No name DEU: weekdays: mon: Montag @@ -3081,6 +2549,8 @@ variables: "off": aus heat: heizen please_confirm: Bitte bestätigen + unavailable: Unavailable + no_name: No name DNK: weekdays: mon: Mandag @@ -3102,6 +2572,8 @@ variables: "off": off heat: varme please_confirm: Bekræft venligst + unavailable: Unavailable + no_name: No name ENG: weekdays: mon: Monday @@ -3123,6 +2595,8 @@ variables: "off": off heat: heat please_confirm: Please confirm + unavailable: Unavailable + no_name: No name ESP: weekdays: mon: Lunes @@ -3144,6 +2618,8 @@ variables: "off": off heat: calor please_confirm: Por favor, confirme + unavailable: Unavailable + no_name: No name EST: weekdays: mon: Esmaspäev @@ -3165,6 +2641,8 @@ variables: "off": välja heat: soojus please_confirm: Palun kinnitage + unavailable: Unavailable + no_name: No name FIN: weekdays: mon: Maanantai @@ -3186,6 +2664,8 @@ variables: "off": off heat: lämpö please_confirm: Vahvistakaa + unavailable: Unavailable + no_name: No name FRA: weekdays: mon: Lundi @@ -3207,6 +2687,8 @@ variables: "off": off heat: Chaleur please_confirm: Veuillez confirmer + unavailable: Unavailable + no_name: No name GRC: weekdays: mon: Δευτέρα @@ -3228,6 +2710,8 @@ variables: "off": Ανενεργό heat: Θέρμανση please_confirm: Παρακαλώ επιβεβαιώστε + unavailable: Unavailable + no_name: No name HEB: weekdays: mon: ינש @@ -3249,6 +2733,8 @@ variables: "off": יובכ heat: םוח please_confirm: רשא השקבב + unavailable: Unavailable + no_name: No name HUN: weekdays: mon: Hétfő @@ -3270,6 +2756,8 @@ variables: "off": off heat: hő please_confirm: Kérjük, erősítse meg + unavailable: Unavailable + no_name: No name IDN: weekdays: mon: Senin @@ -3291,6 +2779,8 @@ variables: "off": off heat: panas please_confirm: Mohon konfirmasi + unavailable: Unavailable + no_name: No name ITA: weekdays: mon: Lunedì @@ -3312,6 +2802,8 @@ variables: "off": off heat: caldo please_confirm: Confermare + unavailable: Unavailable + no_name: No name LTU: weekdays: mon: Pirmadienis @@ -3333,6 +2825,8 @@ variables: "off": išjungta heat: šiluma please_confirm: Prašome patvirtinti + unavailable: Unavailable + no_name: No name LVA: weekdays: mon: Pirmdiena @@ -3354,6 +2848,8 @@ variables: "off": izslēgts heat: siltums please_confirm: Lūdzu, apstipriniet + unavailable: Unavailable + no_name: No name NLD: weekdays: mon: Maandag @@ -3375,6 +2871,8 @@ variables: "off": uit heat: verwarm please_confirm: Bevestig alstublieft + unavailable: Unavailable + no_name: No name NOR: weekdays: mon: Mandag @@ -3396,6 +2894,8 @@ variables: "off": av heat: varme please_confirm: Vennligst bekreft + unavailable: Unavailable + no_name: No name POL: weekdays: mon: Poniedziałek @@ -3417,6 +2917,8 @@ variables: "off": off heat: ciepło please_confirm: Proszę o potwierdzenie + unavailable: Unavailable + no_name: No name PRT: weekdays: mon: Segunda-feira @@ -3438,6 +2940,8 @@ variables: "off": desligado heat: Aquecimento please_confirm: Confirme, por favor + unavailable: Indisponível + no_name: Sem nome ROU: weekdays: mon: Luni @@ -3459,6 +2963,8 @@ variables: "off": off heat: căldură please_confirm: Vă rugăm să confirmați + unavailable: Unavailable + no_name: No name RUS: weekdays: mon: Понедельник @@ -3480,6 +2986,8 @@ variables: "off": выключено heat: нагрев please_confirm: Пожалуйста, подтвердите + unavailable: Unavailable + no_name: No name SVK: weekdays: mon: Pondelok @@ -3501,6 +3009,8 @@ variables: "off": vypnuté heat: kúrenie please_confirm: Potvrďte, prosím + unavailable: Unavailable + no_name: No name SVN: weekdays: mon: Ponedeljek @@ -3522,6 +3032,8 @@ variables: "off": izklop heat: toplota please_confirm: Prosimo, potrdite + unavailable: Unavailable + no_name: No name SWE: weekdays: mon: Måndag @@ -3543,6 +3055,8 @@ variables: "off": av heat: värme please_confirm: Vänligen bekräfta + unavailable: Unavailable + no_name: No name TUR: weekdays: mon: Pazartesi @@ -3564,6 +3078,8 @@ variables: "off": kapalı heat: ısı please_confirm: Lütfen onaylayın + unavailable: Unavailable + no_name: No name UKR: weekdays: mon: Понеділок @@ -3585,14 +3101,93 @@ variables: "off": вимк heat: нагрів please_confirm: Будь ласка, підтвердіть + unavailable: Unavailable + no_name: No name - mui_weekday_today: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom(date_format) }}" - mui_weekday_tomorrow: "{{ (dict.values(mui[language].weekdays) | list)[(now() + timedelta(days=1)).weekday()] ~ ', ' ~ as_timestamp(now() + timedelta(days=1)) | timestamp_custom(date_format) }}" - mui_weekday_in_2_days: "{{ (dict.values(mui[language].weekdays) | list)[(now() + timedelta(days=2)).weekday()] ~ ', ' ~ as_timestamp(now() + timedelta(days=2)) | timestamp_custom(date_format) }}" - mui_weekday_in_3_days: "{{ (dict.values(mui[language].weekdays) | list)[(now() + timedelta(days=3)).weekday()] ~ ', ' ~ as_timestamp(now() + timedelta(days=3)) | timestamp_custom(date_format) }}" - mui_weekday_in_4_days: "{{ (dict.values(mui[language].weekdays) | list)[(now() + timedelta(days=4)).weekday()] ~ ', ' ~ as_timestamp(now() + timedelta(days=4)) | timestamp_custom(date_format) }}" - #heat_mui: "{{ mui[language].climate.heat }}" + ##### WEATHER #### + weather_entity: !input "weather_entity" # used only during the creation of weather in variables + ##### Home page ##### + page_home: + buttons: ### Feature Buttons ### + - icon: '' # NOT IN USE + color_rgb: + 'on': '' # NOT IN USE + 'off': '' # NOT IN USE + - icon: '' # NOT IN USE + color_rgb: + 'on': '' # NOT IN USE + 'off': '' # NOT IN USE + - icon: '' # NOT IN USE + color_rgb: + 'on': '' # NOT IN USE + 'off': '' # NOT IN USE + - icon: !input "home_button04_icon" #E1ED + color_rgb: + 'on': !input "home_button04_icon_color01" + 'off': !input "home_button04_icon_color02" + - icon: !input "home_button05_icon" #E432 + color_rgb: + 'on': !input "home_button05_icon_color" + 'off': '' # NOT IN USE + - icon: !input "home_button06_icon" #EDCF + color_rgb: + 'on': !input "home_button06_icon_color" + 'off': '' # NOT IN USE + - icon: '' # NOT IN USE + color_rgb: + 'on': '' # NOT IN USE + 'off': '' # NOT IN USE + general: + outdoor_temp: + label: + color_rgb: !input "home_outdoor_temp_label_color" + indoor_temp: + icon: + icon: !input "home_indoor_temp_icon" #E50E + color_rgb: !input "home_indoor_temp_icon_color" + label: + color_rgb: !input "home_indoor_temp_label_color" + time: + label: + color_rgb: !input "time_label_color" + date: + label: + color_rgb: !input "date_label_color" + hardware: + buttons: #### HARDWARE BUTTONS ##### + left: + entity: !input "left_button_entity" + name: !input "left_button_name" + color_rgb: !input "left_button_color" + hold_select: !input "left_button_hold_select" + #sequence: !input left_button_hold_custom_action + right: + entity: !input "right_button_entity" + name: !input "right_button_name" + color_rgb: !input "right_button_color" + hold_select: !input "right_button_hold_select" + #sequence: !input right_button_hold_custom_action + qrcode_enabled: !input "qrcode_enabled" + + ###### SYNC SETTINGS ##### + #delay_boot: !input "delay" # NOT IN USE + delay_value: !input "delay" + #delay_jump_page: !input "delay" # NOT IN USE + #sync_slider_ha: !input "sync_slider_ha" # NOT IN USE + #sync_value_ha: !input "sync_value_ha" # NOT IN USE + climate_optimistic: !input "climate_optimistic" + + ##### GENERAL ENTITYS ##### + hotwatertemp: !input "hotwatertemp" + outdoortemp: !input "outdoortemp" + indoortemp: !input "indoortemp" + climate: !input "climate" + relay_1_local_fallback: !input "relay_1_local_fallback" + relay_2_local_fallback: !input "relay_2_local_fallback" + + ##### ENTITIES ##### + entitypages_enabled: !input "entitypages_enabled" ############################################################# ##### CLOSE - Variables ##### @@ -3610,12 +3205,12 @@ trigger: ###### DELME - Trigger "nspanel_boot_init" ###### - platform: state entity_id: input_boolean.trigger_nspanel_boot - to: "on" + to: 'on' id: nspanel_boot_init ##### Reboot - Trigger "nspanel_boot_init" ##### - platform: template - value_template: '{{ states(nextion_inited_trigger) is match "on" }}' + value_template: "{{ is_state(nextion_inited_trigger, 'on') | default(false) if nextion_inited_trigger is string else false }}" for: seconds: 1 id: nspanel_boot_init @@ -3653,24 +3248,27 @@ trigger: id: weather_state_change ##### HOME Value 01 - Trigger "home_value01_state" ##### - - platform: event - event_type: state_changed - event_data: - entity_id: !input "home_value01" + - platform: state + entity_id: !input "home_value01" + not_to: + - unknown + - unavailable id: home_value01_state - ##### HOME Value 02 - Trigger "home_value02_state" ##### - - platform: event - event_type: state_changed - event_data: - entity_id: !input "home_value02" + ##### HOME Value 01 - Trigger "home_value02_state" ##### + - platform: state + entity_id: !input "home_value02" + not_to: + - unknown + - unavailable id: home_value02_state - ##### HOME Value 03 - Trigger "home_value03_state" ##### - - platform: event - event_type: state_changed - event_data: - entity_id: !input "home_value03" + ##### HOME Value 01 - Trigger "home_value03_state" ##### + - platform: state + entity_id: !input "home_value03" + not_to: + - unknown + - unavailable id: home_value03_state ##### Climate - Trigger "climate_state" ##### @@ -3705,7 +3303,7 @@ trigger: - platform: event event_type: state_changed event_data: - entity_id: '{{ nspaneltemp }}' + entity_id: "{{ nspaneltemp }}" id: nspaneltemp_state ##### Hot Water Charge - Trigger "hotwatercharge_state" ##### @@ -3768,99 +3366,101 @@ trigger: - platform: event event_type: state_changed event_data: - entity_id: '{{ relay01_entity }}' + entity_id: "{{ relay01_entity }}" id: relay01_state ##### Relay02 - Trigger "relay02_state" ##### - platform: event event_type: state_changed event_data: - entity_id: '{{ relay02_entity }}' + entity_id: "{{ relay02_entity }}" id: relay02_state ##### Left Button - Trigger "left_button_press" ##### - platform: template - value_template: '{{ states(left_button) is match "on" }}' + value_template: "{{ is_state(left_button, 'on') | default(false) if left_button is string else false }}" id: left_button_press ##### Right Button - Trigger "right_button_press" ##### - platform: template - value_template: '{{ states(right_button) is match "on" }}' + value_template: "{{ is_state(right_button, 'on') | default(false) if right_button is string else false }}" id: right_button_press ##### Left Button - State "left_button_state" ##### - - platform: event - event_type: state_changed - event_data: - entity_id: !input "left_button_entity" + - platform: state + entity_id: !input "left_button_entity" + to: + - 'on' + - 'off' id: left_button_state ##### Right Button - State "right_button_state" ##### - - platform: event - event_type: state_changed - event_data: - entity_id: !input "right_button_entity" + - platform: state + entity_id: !input "right_button_entity" + to: + - 'on' + - 'off' id: right_button_state ##### Notification Text - Trigger "notification_text_state" ##### - platform: event event_type: state_changed event_data: - entity_id: '{{ notification_text }}' + entity_id: "{{ notification_text }}" id: notification_text_state ##### Notification Text - Trigger "notification_text_state" ##### - platform: event event_type: state_changed event_data: - entity_id: '{{ notification_unread }}' + entity_id: "{{ notification_unread }}" id: notification_unread_state #### Show notification - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "homebutton04release" }}' + value_template: "{{ is_state(last_click, 'homebutton04release') | default(false) if last_click is string else false }}" id: open_notification_page #### Notification clear - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "notificationclearrelease" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'notificationclearrelease') if last_click is string else false }}" id: btn_notificationclearrelease #### Notification accept - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "notificationacceptrelease" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'notificationacceptrelease') if last_click is string else false }}" id: btn_notificationacceptrelease #### Show QR code - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "homebutton05release" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'homebutton05release') if last_click is string else false }}" id: open_qrcode_page #### Show ENTITIES - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "homebutton06release" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'homebutton06release') if last_click is string else false }}" id: open_entity_page #### Show Climate - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "weatherpagerelease" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'weatherpagerelease') if last_click is string else false }}" id: open_weather_page #### Climate - Trigger #### - platform: template - value_template: '{{ states(last_click) is match "climaterelease" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'climaterelease') if last_click is string else false }}" id: open_climate_page ##### Trigger - Button General ################################################################################################################# ##### Page Button - Trigger "short_press" - SHORT Press via "last_click" ##### - platform: template - value_template: '{{ states(last_click) is match "releasebutton" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'releasebutton') if last_click is string else false }}" id: short_press ##### Page Button - Trigger "long_press" - LONG Press via "last_click" - Button LONG Press for jump to Lightsetting or Coversetting Page ##### - platform: template - value_template: '{{ states(last_click) is match "press" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'press') if last_click is string else false }}" for: seconds: 1 id: long_press @@ -3895,7 +3495,7 @@ trigger: ##### Page Button - Trigger "button_page" Entity sync ##### - platform: template - value_template: '{{ states(last_click) is match "button" }}' + value_template: "{{ (states(last_click) | default('unavailable') is match 'button') if last_click is string else false }}" id: button_page @@ -4067,129 +3667,82 @@ trigger: ##### CLOSE - Trigger ##### ############################################################# +condition: "{{ is_state(nextion_inited_trigger, 'on') | default(false) if nextion_inited_trigger is string else false }}" ############################################################# ##### START - Action ##### ############################################################# -#condition: '{{ states(relay01_entity) != "unavailable" and states(relay02_entity) != "unavailable" }}' -condition: '{{ states(nextion_inited_trigger) == "on" }}' action: - variables: - #settings_entity_value: '{{ states(settings_entity) }}' - settings_entity_value: >- - {%- if states(settings_entity) != "unavailable" -%} {{ states(settings_entity) }} - {%- else -%} unknown - {%- endif -%} - entity_long: >- - {%- if settings_entity_value != "unknown" and settings_entity_value.split(',') | count >= 1 -%} {{ settings_entity_value.split(',')[0] }} - {%- else -%} unknown - {%- endif -%} - entity_back: >- - {%- if settings_entity_value != "unknown" and settings_entity_value.split(',') | count >= 2 -%} {{ settings_entity_value.split(',')[1] }} - {%- else -%} unknown - {%- endif -%} - entity_long_name: >- - {%- if settings_entity_value != "unknown" and settings_entity_value.split(',') | count >= 3 -%} {{ settings_entity_value.split(',')[2] }} - {%- else -%} unknown - {%- endif -%} - entity_long_icon: >- - {%- if settings_entity_value != "unknown" and settings_entity_value.split(',') | count >= 4 -%} {{ settings_entity_value.split(',')[3] }} - {%- else -%} unknown - {%- endif -%} - entity_long_icon_color: >- - {%- if settings_entity_value != "unknown" and settings_entity_value.split(',') | count >= 5 -%} {{ settings_entity_value.split(',')[4] }} - {%- else -%} unknown - {%- endif -%} + #settings_entity_value: "{{ states(settings_entity) }}" + settings_entity_value: "{{ states(settings_entity) | default('unavailable') if settings_entity is string else 'unavailable' }}" + settings_entity_split: "{{ settings_entity_value.split(',') if settings_entity_value is string and settings_entity_value not in ['unavailable', 'unknown', None] else [] }}" + settings_entity_count: "{{ settings_entity_split | count if settings_entity_split else 0 }}" + entity_long: "{{ settings_entity_split[0] if settings_entity_count >= 1 else 'unknown' }}" + entity_back: "{{ settings_entity_split[1] if settings_entity_count >= 2 else 'unknown' }}" + entity_long_name: "{{ settings_entity_split[2] if settings_entity_count >= 3 else 'unknown' }}" + entity_long_icon: "{{ settings_entity_split[3] if settings_entity_count >= 4 else 'unknown' }}" + entity_long_icon_color: "{{ settings_entity_split[4] if settings_entity_count >= 5 else 'unknown' }}" + entity_long_domain: "{{ entity_long.split('.')[0] if entity_long.split('.') | count > 0 else 'unknown' }}" ######################################################################################################################## # main - alias: "choose alias (name)" - alias: Main choices choose: - ##### JUMP TO - settings page lightsettings /coversettings / climate (SETTINGS ENTITY CHANGED) ##### - - conditions: + - alias: "Jump to light/cover/climate settings page" + conditions: - condition: trigger id: settings_entity - - condition: template - value_template: "{{ trigger.event.data.new_state.state != 'unknown' }}" + - "{{ trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" + - "{{ entity_long_domain in ['light', 'cover', 'climate'] }}" sequence: - - choose: - - conditions: '{{ entity_long is match "light." }}' - sequence: - - service: "{{ command_printf }}" - data: - cmd: "page {{ page_lightsettings }}" - - conditions: '{{ entity_long is match "cover." }}' - sequence: - - service: "{{ command_printf }}" - data: - cmd: "page {{ page_coversettings }}" - - conditions: '{{ entity_long is match "climate." }}' - sequence: - - service: "{{ command_printf }}" - data: - cmd: "page {{ page_climate }}" + - service: "{{ nextion.commands.printf }}" + data: + cmd: "page {{ nextion.pages[entity_long_domain] }}" ##### BOOT NSPANEL - boot init ##### - - conditions: + - alias: Boot init + conditions: - condition: trigger id: nspanel_boot_init - - condition: template - value_template: '{{ states(current_page) != page_home or states(last_click) == "unknown" }}' + - "{{ nextion.pages.current != nextion.pages.home or (is_state(last_click, ['unavailable', 'unknown', None]) | default(False) if last_click is string else False) }}" sequence: + ##### NSPanel boot init only ##### - delay: milliseconds: 100 - - ##### NSPanel boot init only ##### - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: boot.bluep_version message: "{{ blueprint_version }}" ###### Set local fallback ###### - - if: - - condition: template - value_template: '{{ relay_1_local_fallback }}' - then: - - service: switch.turn_on - data: - entity_id: 'switch.{{ nspanel_name }}_relay_1_local_fallback' - else: - - service: switch.turn_off - data: - entity_id: 'switch.{{ nspanel_name }}_relay_1_local_fallback' - - if: - - condition: template - value_template: '{{ relay_2_local_fallback }}' - then: - - service: switch.turn_on - data: - entity_id: 'switch.{{ nspanel_name }}_relay_2_local_fallback' - else: - - service: switch.turn_off - data: - entity_id: 'switch.{{ nspanel_name }}_relay_2_local_fallback' + - service: "switch.turn_{{ 'on' if relay_1_local_fallback else 'off' }}" + data: + entity_id: 'switch.{{ nspanel_name }}_relay_1_local_fallback' + - service: "switch.turn_{{ 'on' if relay_2_local_fallback else 'off' }}" + data: + entity_id: 'switch.{{ nspanel_name }}_relay_2_local_fallback' ##### clear notification icon ##### - - service: "{{ command_notification_clear }}" + - service: "{{ nextion.commands.notification_clear }}" data: {} ###### NSPanel beep ###### - delay: milliseconds: 2000 - - if: - - condition: template - value_template: '{{ is_state(notification_sound, "on") }}' + - if: "{{ is_state(notification_sound, 'on') }}" then: - - service: "{{ command_play_rtttl }}" + - service: "{{ nextion.commands.play_rtttl }}" data: song_str: "two short:d=4,o=5,b=100:16e6,16e6" ##### NSPanel boot init finished and jump to Home Page##### - - delay: + - &delay-default + delay: milliseconds: "{{ delay_value }}" - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: cmd: page home @@ -4200,1748 +3753,1021 @@ action: id: current_page_changed sequence: ##### climate-page left - apply climate temperature if climate_optimistic ##### ## TODO - remove from here - - if: - - condition: template - value_template: '{{ trigger.event.data.old_state.state == page_climate and climate_optimistic and is_number(states(display_target_temperature)) and states(display_target_temperature) | float(0) != 0.0 }}' + - if: "{{ trigger.event.data.old_state.state == nextion.pages.climate and climate_optimistic }}" then: - - service: climate.set_temperature - data: - entity_id: '{{ entity_long }}' - #hvac_mode: 'heat' - temperature: "{{ states(display_target_temperature) | round(1) }}" + - variables: + display_target_temperature_state: "{{ states(display_target_temperature) | default('unavailable') if display_target_temperature is string else 'unavailable' }}" + - if: "{{ is_number(display_target_temperature_state) }}" + then: + - service: climate.set_temperature + data: + entity_id: "{{ entity_long }}" + #hvac_mode: 'heat' + temperature: "{{ display_target_temperature_state }}" - choose: ## PAGE HOME ## - - conditions: '{{ trigger.event.data.new_state.state == page_home }}' - alias: 'home page' + - alias: Home page + conditions: "{{ trigger.event.data.new_state.state == nextion.pages.home }}" sequence: &refresh_page_home - - service: '{{ command_set_settings_entity }}' + - &variables-weather + variables: + weather_attribution: "{{ state_attr(weather_entity, 'attribution') | default('unavailable') if weather_entity is string else 'unavailable' }}" + weather_type: > + {% if 'AccuWeather' in weather_attribution %} AccuWeather + {% elif 'OpenWeatherMap' in weather_attribution %} OpenWeather + {% elif 'SMHI' in weather_attribution %} SMHI + {% elif 'met.no' in weather_attribution %} Met.no + {% elif 'OpenWeatherMap' in weather_attribution %} OpenWeather + {% else %} Other + {% endif %} + weather_units: + hours_of_sun: "{{ state_attr(weather_entity, 'hours_of_sun_unit') | default('h') if weather_entity is string and state_attr(weather_entity, 'hours_of_sun_unit') else 'h' }}" + precipitation: "{{ state_attr(weather_entity, 'precipitation_unit') | default('mm') if weather_entity is string and state_attr(weather_entity, 'precipitation_unit') else 'mm' }}" + precipitation_probability: "{{ state_attr(weather_entity, 'precipitation_probability_unit') | default('%') if weather_entity is string and state_attr(weather_entity, 'precipitation_probability_unit') else '%' }}" + pressure: "{{ state_attr(weather_entity, 'pressure_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'pressure_unit') }}" + temperature: "{{ state_attr(weather_entity, 'temperature_unit') | default('°') if weather_entity is string and state_attr(weather_entity, 'temperature_unit') else '°' }}" + thunderstorm_probability: "{{ state_attr(weather_entity, 'thunderstorm_probability_unit') | default('%') if weather_entity is string and state_attr(weather_entity, 'thunderstorm_probability_unit') else '%' }}" + uv_index: "{{ state_attr(weather_entity, 'uv_index_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'uv_index_unit') }}" + visibility: "{{ state_attr(weather_entity, 'visibility_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'visibility_unit') }}" + wind_speed: "{{ state_attr(weather_entity, 'wind_speed_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'wind_speed_unit') }}" + + - service: "{{ nextion.commands.set_settings_entity }}" data: entity: 'unknown' ##### NSPanel Date ##### ### DATE Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.date - message: "{{ date_label_color }}" + message: "{{ page_home.general.date.label.color_rgb if is_number(page_home.general.date.label.color_rgb) else ((page_home.general.date.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.date.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.date.label.color_rgb[2] //(2**3)) }}" ### DATE Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.date - message: "{{ mui_weekday_today }}" + message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom('%d.%m') }}" ##### NSPanel Time ##### ### TIME Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.time - message: "{{ time_label_color }}" + message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" ### TIME Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.time message: "{{ time }}" ### TIME Meridiem Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.meridiem - message: "{{ time_label_color }}" + message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" ### TIME Meridiem Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.meridiem message: "{{ meridiem }}" ##### NSPanel Outdoor Temp ##### - variables: - outdoor_temp: >- - {%- if outdoortemp and is_number(states(outdoortemp)) -%}{{ states(outdoortemp) | round(1) }} - {%- else -%} {{state_attr(weather.entity,"temperature") | round(1) if state_attr(weather.entity, "temperature") else 0 }} - {%- endif -%} + outdoor_temp_state: "{{ states(outdoortemp) | default('unavailable') if outdoortemp is string else 'unavailable' }}" + outdoor_temp: "{{ outdoor_temp_state if is_number(outdoor_temp_state) else state_attr(weather_entity, 'temperature') | default('unavailable') if weather_entity is string else 'unavailable' }}" ### LABEL Outdoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.outdoor_temp - message: "{{ home_outdoor_temp_label_color }}" + message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" ### LABEL Outdoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp - message: '{{ outdoor_temp }}{{ weather.units.temperature }}' + message: "{{ (outdoor_temp | round(1) ~ weather_units.temperature) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" ##### NSPanel Indoor Temp ##### + - variables: + indoor_temp_state: "{{ states(indoortemp) | default('unavailable') if indoortemp is string else 'unavailable' }}" ### ICON Indoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.indoortempicon - message: "{{ home_indoor_temp_icon_color }}" + message: "{{ page_home.general.indoor_temp.icon.color_rgb if is_number(page_home.general.indoor_temp.icon.color_rgb) else ((page_home.general.indoor_temp.icon.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.icon.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.icon.color_rgb[2] //(2**3)) }}" ### ICON Indoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.indoortempicon - message: "{{ home_indoor_temp_icon }}" + message: "{{ page_home.general.indoor_temp.icon.icon }}" ### LABEL Indoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.current_temp - message: "{{ home_indoor_temp_label_color }}" + message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" ### LABEL Indoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp - message: "{{ states(indoortemp) | round(1) if indoortemp is match 'sensor.' and states(indoortemp) not in ['unavailable', 'unknown', 'none'] else states(nspaneltemp) | round(1) }}{{ weather.units.temperature }}" + message: "{{ (indoor_temp_state | round(1) ~ weather_units.temperature) if is_number(indoor_temp_state) else (mui[language].unavailable if indoor_temp_state in ['unavailable', 'unknown', None] else indoor_temp_state) }}" ##### Weather Icon Home Page ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_printf }}" + - *delay-default + - service: "{{ nextion.commands.printf }}" data: - cmd: home.weather.pic={{ nextion.pics.weather[states(weather_entity) | default('unknown')] }} + cmd: home.weather.pic={{ nextion.pics.weather[states(weather_entity) | default('unavailable') if weather_entity is string else 'unavailable'] | default(None) }} + + ##### NSPanel Buttons ##### + - variables: + left_button_state: "{{ states(page_home.hardware.buttons.left.entity) | default('unavailable') if page_home.hardware.buttons.left.entity is string else 'unavailable' }}" + right_button_state: "{{ states(page_home.hardware.buttons.right.entity) | default('unavailable') if page_home.hardware.buttons.right.entity is string else 'unavailable' }}" ##### NSPanel Left Button Name ##### - - if: - - condition: template - value_template: '{{ left_button_name |length > 0 }}' + - if: "{{ page_home.hardware.buttons.left.name | length > 0 }}" then: ### LABEL Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.left_bt_text - message: "{{ left_button_color }}" + message: "{{ page_home.hardware.buttons.left.color_rgb if is_number(page_home.hardware.buttons.left.color_rgb) else ((page_home.hardware.buttons.left.color_rgb[0] //(2**3)) *(2**11))+((page_home.hardware.buttons.left.color_rgb[1] //(2**2)) *(2**5))+(page_home.hardware.buttons.left.color_rgb[2] //(2**3)) }}" ### LABEL Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.left_bt_text - message: "{{ left_button_name }}" + message: "{{ page_home.hardware.buttons.left.name }}" ##### SET Left Hardware Button PIC on Home Page #### - - if: - - condition: template - value_template: '{{ left_button_entity |length > 0 and states(left_button_entity).state != "unavailable" }}' + - if: "{{ left_button_state not in ['unavailable', 'unknown', None] }}" then: - variables: # Hardware Button PIC - left_hardware_button_state: >- - {%- if states(left_button_entity) == 'off' -%} {{ hardware_button_pic_off }} - {%- elif states(left_button_entity) == 'on' -%} {{ hardware_button_pic_on }} - {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_printf }}" + left_hardware_button_state: "{{ nextion.pics.hardware.button[left_button_state] | default(None) }}" + - *delay-default + - service: "{{ nextion.commands.printf }}" data: cmd: home.left_bt_pic.pic={{ left_hardware_button_state }} ##### NSPanel Right Button Name ##### - - if: - - condition: template - value_template: '{{ right_button_name |length > 0 }}' + - if: "{{ page_home.hardware.buttons.right.name | length > 0 }}" then: ### LABEL Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.right_bt_text - message: "{{ right_button_color }}" + message: "{{ page_home.hardware.buttons.right.color_rgb if is_number(page_home.hardware.buttons.right.color_rgb) else ((page_home.hardware.buttons.right.color_rgb[0] //(2**3)) *(2**11))+((page_home.hardware.buttons.right.color_rgb[1] //(2**2)) *(2**5))+(page_home.hardware.buttons.right.color_rgb[2] //(2**3)) }}" ### LABEL Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.right_bt_text - message: "{{ right_button_name }}" + message: "{{ page_home.hardware.buttons.right.name }}" ##### SET Right Hardware Button PIC on Home Page ##### - - if: - - condition: template - value_template: '{{ right_button_entity |length > 0 and states(right_button_entity).state != "unavailable" }}' + - if: "{{ right_button_state not in ['unavailable', 'unknown', None] }}" then: - variables: # Hardware Button PIC - right_hardware_button_state: >- - {%- if states(right_button_entity) == 'off' -%} {{ hardware_button_pic_off }} - {%- elif states(right_button_entity) == 'on' -%} {{ hardware_button_pic_on }} - {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_printf }}" + right_hardware_button_state: "{{ nextion.pics.hardware.button[right_button_state] | default(None) }}" + - *delay-default + - service: "{{ nextion.commands.printf }}" data: cmd: home.right_bt_pic.pic={{ right_hardware_button_state }} - ##### StatusBar - Climate Symbol ###### - - if: - - condition: template - value_template: '{{ climate |length > 0 }}' - then: - - variables: - chip_climate: >- - {%- if states(climate) == "heat" and state_attr(climate, "hvac_action") != None and state_attr(climate, "hvac_action") == "heating" -%} {{ heat_icon }} - {%- elif states(climate) == "heat" -%} {{ thermostat_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Thermostat Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_03 - message: "{{ thermostat_icon_color }}" - ### ICON Thermostat Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_03 - message: "{{ chip_climate }}" - - ##### StatusBar - Relay Symbols ###### - - variables: - chip_relay01: >- - {%- if states(relay01_entity) == 'on' -%} {{ relay01_icon }} - {%- else -%} {{ blank_icon}} - {%- endif -%} - chip_relay02: >- - {%- if states(relay02_entity) == 'on' -%} {{ relay02_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Relay01 Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_01 - message: "{{ relay01_icon_color }}" - ### ICON Relay01 Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_01 - message: "{{ chip_relay01 }}" - - ### ICON Relay02 Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_02 - message: "{{ relay02_icon_color }}" - ### ICON Relay02 Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_02 - message: "{{ chip_relay02 }}" - - ###### CHIPS 01 - 07 - Statusbar 04 - 10 ###### - - delay: - milliseconds: "{{ delay_value }}" + ###### Status bar ###### + - &variables-home_page_status_bar + variables: + thermostat_icon: !input "thermostat_icon" #E50E + heat_icon: !input "heat_icon" #\U0000E50F + climate_state: "{{ states(climate) | default('unavailable') if climate is string else 'unavailable' }}" + climate_action: "{{ state_attr(climate, 'hvac_action') | default('unavailable') if climate is string else 'unavailable' }}" + home_page_status_bar: + - entity: "{{ relay01_entity }}" + icon: !input "relay01_icon" #E3A5 + icon_color_rgb: !input "relay01_icon_color" + - entity: "{{ relay02_entity }}" + icon: !input "relay02_icon" #E3A8 + icon_color_rgb: !input "relay02_icon_color" + - entity: "{{ climate }}" + icon: "{{ (heat_icon if climate_action == 'heating' else thermostat_icon) if climate_state == 'heat' else nextion.icons.blank }}" + icon_color_rgb: !input "thermostat_icon_color" + - entity: !input "chip01" + icon: !input "chip01_icon" + icon_color_rgb: !input "chip01_icon_color" + - entity: !input "chip02" + icon: !input "chip02_icon" + icon_color_rgb: !input "chip02_icon_color" + - entity: !input "chip03" + icon: !input "chip03_icon" + icon_color_rgb: !input "chip03_icon_color" + - entity: !input "chip04" + icon: !input "chip04_icon" + icon_color_rgb: !input "chip04_icon_color" + - entity: !input "chip05" + icon: !input "chip05_icon" + icon_color_rgb: !input "chip05_icon_color" + - entity: !input "chip06" + icon: !input "chip06_icon" + icon_color_rgb: !input "chip06_icon_color" + - entity: !input "chip07" + icon: !input "chip07_icon" + icon_color_rgb: !input "chip07_icon_color" - repeat: - for_each: - - position: home.icon_top_04 - entity: "{{ chip01 }}" - entity_icon: "{{ chip01_icon }}" - entity_icon_color: "{{ chip01_icon_color }}" - - position: home.icon_top_05 - entity: "{{ chip02 }}" - entity_icon: "{{ chip02_icon }}" - entity_icon_color: "{{ chip02_icon_color }}" - - position: home.icon_top_06 - entity: "{{ chip03 }}" - entity_icon: "{{ chip03_icon }}" - entity_icon_color: "{{ chip03_icon_color }}" - - position: home.icon_top_07 - entity: "{{ chip04 }}" - entity_icon: "{{ chip04_icon }}" - entity_icon_color: "{{ chip04_icon_color }}" - - position: home.icon_top_08 - entity: "{{ chip05 }}" - entity_icon: "{{ chip05_icon }}" - entity_icon_color: "{{ chip05_icon_color }}" - - position: home.icon_top_09 - entity: "{{ chip06 }}" - entity_icon: "{{ chip06_icon }}" - entity_icon_color: "{{ chip06_icon_color }}" - - position: home.icon_top_10 - entity: "{{ chip07 }}" - entity_icon: "{{ chip07_icon }}" - entity_icon_color: "{{ chip07_icon_color }}" + for_each: "{{ home_page_status_bar }}" sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity |length > 0 }}' + - &display-home_page_status_bar + if: "{{ repeat.item.entity is defined and repeat.item.entity is string and repeat.item.entity | length > 0 }}" then: ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: - component: "{{ repeat.item.position }}" - message: "{{ repeat.item.entity_icon_color }}" + component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" + message: "{{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }}" ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ repeat.item.position }}" - message: >- - {%- if states(repeat.item.entity) == 'on' -%} {{ repeat.item.entity_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} + component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" + message: "{{ repeat.item.icon if is_state(repeat.item.entity, 'on') | default(False) else nextion.icons.blank }}" + # {{ is_state(repeat.item.entity, 'on') | default(False) if repeat.item.entity is string else 'unavailable' }} ##### HOME VALUE 01 - 03 - - delay: - milliseconds: "{{ delay_value }}" + - *delay-default + - &variables-home_page_values + variables: + home_page_values: + - entity: !input "home_value01" + icon: !input "home_value01_icon" + icon_color_rgb: !input "home_value01_icon_color" + label_color_rgb: !input "home_value01_label_color" + - entity: !input "home_value02" + icon: !input "home_value02_icon" + icon_color_rgb: !input "home_value02_icon_color" + label_color_rgb: !input "home_value02_label_color" + - entity: !input "home_value03" + icon: !input "home_value03_icon" + icon_color_rgb: !input "home_value03_icon_color" + label_color_rgb: !input "home_value03_label_color" - repeat: - for_each: - - row: home.value01 - entity: "{{ home_value01 }}" - entity_icon: "{{ home_value01_icon }}" - entity_icon_color: "{{ home_value01_icon_color }}" - entity_label_color: "{{ home_value01_label_color }}" - - row: home.value02 - entity: "{{ home_value02 }}" - entity_icon: "{{ home_value02_icon }}" - entity_icon_color: "{{ home_value02_icon_color }}" - entity_label_color: "{{ home_value02_label_color }}" - - row: home.value03 - entity: "{{ home_value03 }}" - entity_icon: "{{ home_value03_icon }}" - entity_icon_color: "{{ home_value03_icon_color }}" - entity_label_color: "{{ home_value03_label_color }}" + for_each: "{{ home_page_values }}" sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity is match "sensor." and states(repeat.item.entity) != "unavailable" }}' + - &display-home_page_value + if: "{{ repeat.item.entity is string and repeat.item.entity is match 'sensor.' and states(repeat.item.entity) not in ['unavailable', 'unknown', None] }}" then: - - if: - - condition: template - value_template: '{{ repeat.item.entity_icon |length > 0 }}' + - if: "{{ repeat.item.entity_icon | length > 0 }}" then: ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: - component: "{{ repeat.item.row }}_icon" - message: "{{ repeat.item.entity_icon_color }}" + component: "{{ 'home.value%02d_icon' | format(repeat.index) }}" + message: "{{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }}" ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ repeat.item.row }}_icon" - message: "{{ repeat.item.entity_icon }}" + component: "{{ 'home.value%02d_icon' | format(repeat.index) }}" + message: "{{ repeat.item.icon }}" ### LABEL Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: - component: "{{ repeat.item.row }}_state" - message: "{{ repeat.item.entity_label_color }}" + component: "{{ 'home.value%02d_state' | format(repeat.index) }}" + message: "{{ repeat.item.label_color_rgb if is_number(repeat.item.label_color_rgb) else ((repeat.item.label_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.label_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.label_color_rgb[2] //(2**3)) }}" ### LABEL Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ repeat.item.row }}_state" - message: > - {% if is_number(states(repeat.item.entity)) %} - {{ states(repeat.item.entity) | round(1) }}{{ state_attr(repeat.item.entity, "unit_of_measurement") if state_attr(repeat.item.entity, "unit_of_measurement") else '' }} - {% else %} - {{ states(repeat.item.entity) | default('unknown') }} - {% endif %} + component: "{{ 'home.value%02d_state' | format(repeat.index) }}" + message: "{{ (states(repeat.item.entity) | round(1) ~ (state_attr(repeat.item.entity, 'unit_of_measurement') if state_attr(repeat.item.entity, 'unit_of_measurement') else '')) if is_number(states(repeat.item.entity)) else states(repeat.item.entity) | default('unknown') }}" ##### Set notify icon ##### - variables: + notification_unread_state: "{{ states(notification_unread) | default('unavailable') if notification_unread is string else 'unavailable' }}" + notification_text_state: "{{ states(notification_text) | default(None) if notification_text is string else None }}" set_button04_icon: >- - {%- if is_state(notification_unread, 'on') and states(notification_text) |length > 0 -%} {{ home_button04_icon}} - {%- elif is_state(notification_unread, 'off') and states(notification_text) |length > 0 -%} {{ home_button04_icon }} - {%- else -%} {{ blank_icon }} + {%- if notification_unread_state == 'on' and notification_text_state | length > 0 -%} {{ page_home.buttons[3].icon}} + {%- elif notification_unread_state == 'off' and notification_text_state | length > 0 -%} {{ page_home.buttons[3].icon }} + {%- else -%} {{ nextion.icons.blank }} {%- endif -%} set_button04_icon_font: >- - {%- if is_state(notification_unread, 'on') and states(notification_text) |length > 0 -%} {{ home_button04_icon_color01 }} - {%- elif is_state(notification_unread, 'off') and states(notification_text) |length > 0 -%} {{ home_button04_icon_color02 }} - {%- else -%} {{ color_03 }} + {%- if notification_unread_state == 'on' and notification_text_state | length > 0 -%} + {% set rgb = page_home.buttons[3].color_rgb.on %} + {{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }} + {%- elif notification_unread_state == 'off' and notification_text_state | length > 0 -%} + {% set rgb = page_home.buttons[3].color_rgb.off %} + {{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }} + {%- else -%} {{ nextion.colors.grey_light }} {%- endif -%} ##### SET ICON Font - Notify ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.button04_icon message: "{{ set_button04_icon }}" ##### SET ICON Font Color - Notify ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.button04_icon message: "{{ set_button04_icon_font }}" ###### QR Code - Icon ###### - - if: - - condition: template - value_template: '{{ qrcode_enabled == true }}' - then: - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - if: "{{ qrcode_enabled == true }}" + then: # Display QR code icon + ### ICON Font Color ### + - service: "{{ nextion.commands.font_color }}" data: component: home.button05_icon - message: "{{ home_button05_icon_color }}" + message: "{{ page_home.buttons[4].color_rgb.on if is_number(page_home.buttons[4].color_rgb.on) else ((page_home.buttons[4].color_rgb.on[0] //(2**3)) *(2**11))+((page_home.buttons[4].color_rgb.on[1] //(2**2)) *(2**5))+(page_home.buttons[4].color_rgb.on[2] //(2**3)) }}" ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.button05_icon - message: "{{ home_button05_icon }}" - else: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ page_home.buttons[4].icon }}" + else: # Display blank icon + - service: "{{ nextion.commands.text_printf }}" data: component: home.button05_icon - message: "{{ blank_icon }}" + message: "{{ nextion.icons.blank }}" ###### ENTITIES - Icon ###### - - if: - - condition: template - value_template: '{{ entitypages_enabled }}' - then: + - *delay-default + - if: "{{ entitypages_enabled }}" + then: # Display entities icon ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - service: "{{ nextion.commands.font_color }}" data: component: home.button06_icon - message: "{{ home_button06_icon_color }}" + message: "{{ page_home.buttons[5].color_rgb.on if is_number(page_home.buttons[5].color_rgb.on) else ((page_home.buttons[5].color_rgb.on[0] //(2**3)) *(2**11))+((page_home.buttons[5].color_rgb.on[1] //(2**2)) *(2**5))+(page_home.buttons[5].color_rgb.on[2] //(2**3)) }}" ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.button06_icon - message: "{{ home_button06_icon }}" - else: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ page_home.buttons[5].icon }}" + else: # Display blank icon + - service: "{{ nextion.commands.text_printf }}" data: component: home.button06_icon - message: "{{ blank_icon }}" + message: "{{ nextion.icons.blank }}" + ###### SHOW All component when page loading done ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_show_all }}" + - *delay-default + - service: "{{ nextion.commands.show_all }}" - ## PAGE BUTTONPAGE01 ## - - conditions: '{{ trigger.event.data.new_state.state == page_buttonpage01 }}' - alias: 'buttonpage01 page' - sequence: &refresh_page_buttonpage01 - - service: '{{ command_set_settings_entity }}' - data: - entity: 'unknown' - ##### Button Page Label ##### - - if: - - condition: template - value_template: '{{ button_page01_label |length > 0 }}' + ## BUTTON PAGES 01 - 04 ## + - alias: Button pages + conditions: "{{ trigger.event.data.new_state.state in nextion.pages.buttonpages }}" + sequence: &refresh_page_buttonpage + - &variables-page_buttons + variables: + button_page_index: "{{ (nextion.pages.current[-2:] | int(-1)) - 1 }}" + first_button: "{{ button_page_index * 8 }}" + last_button: "{{ first_button + 8 }}" + ##### BUTTON Page Labels ##### + button_pages_labels: + - label: !input button_page01_label + - label: !input button_page02_label + - label: !input button_page03_label + - label: !input button_page04_label + ##### BUTTONS Page - Buttons 1 - 32 ##### + button_pages_buttons: + - entity: !input "entity01" + name: !input "entity01_name" + icon: !input "entity01_icon" + icon_color_rgb: !input "entity01_icon_color" + confirm: !input "entity01_confirm" + component: buttonpage01.button01 + - entity: !input "entity02" + name: !input "entity02_name" + icon: !input "entity02_icon" + icon_color_rgb: !input "entity02_icon_color" + confirm: !input "entity02_confirm" + component: buttonpage01.button02 + - entity: !input "entity03" + name: !input "entity03_name" + icon: !input "entity03_icon" + icon_color_rgb: !input "entity03_icon_color" + confirm: !input "entity03_confirm" + component: buttonpage01.button03 + - entity: !input "entity04" + name: !input "entity04_name" + icon: !input "entity04_icon" + icon_color_rgb: !input "entity04_icon_color" + confirm: !input "entity04_confirm" + component: buttonpage01.button04 + - entity: !input "entity05" + name: !input "entity05_name" + icon: !input "entity05_icon" + icon_color_rgb: !input "entity05_icon_color" + confirm: !input "entity05_confirm" + component: buttonpage01.button05 + - entity: !input "entity06" + name: !input "entity06_name" + icon: !input "entity06_icon" + icon_color_rgb: !input "entity06_icon_color" + confirm: !input "entity06_confirm" + component: buttonpage01.button06 + - entity: !input "entity07" + name: !input "entity07_name" + icon: !input "entity07_icon" + icon_color_rgb: !input "entity07_icon_color" + confirm: !input "entity07_confirm" + component: buttonpage01.button07 + - entity: !input "entity08" + name: !input "entity08_name" + icon: !input "entity08_icon" + icon_color_rgb: !input "entity08_icon_color" + confirm: !input "entity08_confirm" + component: buttonpage01.button08 + - entity: !input "entity09" + name: !input "entity09_name" + icon: !input "entity09_icon" + icon_color_rgb: !input "entity09_icon_color" + confirm: !input "entity09_confirm" + component: buttonpage02.button01 + - entity: !input "entity10" + name: !input "entity10_name" + icon: !input "entity10_icon" + icon_color_rgb: !input "entity10_icon_color" + confirm: !input "entity10_confirm" + component: buttonpage02.button02 + - entity: !input "entity11" + name: !input "entity11_name" + icon: !input "entity11_icon" + icon_color_rgb: !input "entity11_icon_color" + confirm: !input "entity11_confirm" + component: buttonpage02.button03 + - entity: !input "entity12" + name: !input "entity12_name" + icon: !input "entity12_icon" + icon_color_rgb: !input "entity12_icon_color" + confirm: !input "entity12_confirm" + component: buttonpage02.button04 + - entity: !input "entity13" + name: !input "entity13_name" + icon: !input "entity13_icon" + icon_color_rgb: !input "entity13_icon_color" + confirm: !input "entity13_confirm" + component: buttonpage02.button05 + - entity: !input "entity14" + name: !input "entity14_name" + icon: !input "entity14_icon" + icon_color_rgb: !input "entity14_icon_color" + confirm: !input "entity14_confirm" + component: buttonpage02.button06 + - entity: !input "entity15" + name: !input "entity15_name" + icon: !input "entity15_icon" + icon_color_rgb: !input "entity15_icon_color" + confirm: !input "entity15_confirm" + component: buttonpage02.button07 + - entity: !input "entity16" + name: !input "entity16_name" + icon: !input "entity16_icon" + icon_color_rgb: !input "entity16_icon_color" + confirm: !input "entity16_confirm" + component: buttonpage02.button08 + - entity: !input "entity17" + name: !input "entity17_name" + icon: !input "entity17_icon" + icon_color_rgb: !input "entity17_icon_color" + confirm: !input "entity17_confirm" + component: buttonpage03.button01 + - entity: !input "entity18" + name: !input "entity18_name" + icon: !input "entity18_icon" + icon_color_rgb: !input "entity18_icon_color" + confirm: !input "entity18_confirm" + component: buttonpage03.button02 + - entity: !input "entity19" + name: !input "entity19_name" + icon: !input "entity19_icon" + icon_color_rgb: !input "entity19_icon_color" + confirm: !input "entity19_confirm" + component: buttonpage03.button03 + - entity: !input "entity20" + name: !input "entity20_name" + icon: !input "entity20_icon" + icon_color_rgb: !input "entity20_icon_color" + confirm: !input "entity20_confirm" + component: buttonpage03.button04 + - entity: !input "entity21" + name: !input "entity21_name" + icon: !input "entity21_icon" + icon_color_rgb: !input "entity21_icon_color" + confirm: !input "entity21_confirm" + component: buttonpage03.button05 + - entity: !input "entity22" + name: !input "entity22_name" + icon: !input "entity22_icon" + icon_color_rgb: !input "entity22_icon_color" + confirm: !input "entity22_confirm" + component: buttonpage03.button06 + - entity: !input "entity23" + name: !input "entity23_name" + icon: !input "entity23_icon" + icon_color_rgb: !input "entity23_icon_color" + confirm: !input "entity23_confirm" + component: buttonpage03.button07 + - entity: !input "entity24" + name: !input "entity24_name" + icon: !input "entity24_icon" + icon_color_rgb: !input "entity24_icon_color" + confirm: !input "entity24_confirm" + component: buttonpage03.button08 + - entity: !input "entity25" + name: !input "entity25_name" + icon: !input "entity25_icon" + icon_color_rgb: !input "entity25_icon_color" + confirm: !input "entity25_confirm" + component: buttonpage04.button01 + - entity: !input "entity26" + name: !input "entity26_name" + icon: !input "entity26_icon" + icon_color_rgb: !input "entity26_icon_color" + confirm: !input "entity26_confirm" + component: buttonpage04.button02 + - entity: !input "entity27" + name: !input "entity27_name" + icon: !input "entity27_icon" + icon_color_rgb: !input "entity27_icon_color" + confirm: !input "entity27_confirm" + component: buttonpage04.button03 + - entity: !input "entity28" + name: !input "entity28_name" + icon: !input "entity28_icon" + icon_color_rgb: !input "entity28_icon_color" + confirm: !input "entity28_confirm" + component: buttonpage04.button04 + - entity: !input "entity29" + name: !input "entity29_name" + icon: !input "entity29_icon" + icon_color_rgb: !input "entity29_icon_color" + confirm: !input "entity29_confirm" + component: buttonpage04.button05 + - entity: !input "entity30" + name: !input "entity30_name" + icon: !input "entity30_icon" + icon_color_rgb: !input "entity30_icon_color" + confirm: !input "entity30_confirm" + component: buttonpage04.button06 + - entity: !input "entity31" + name: !input "entity31_name" + icon: !input "entity31_icon" + icon_color_rgb: !input "entity31_icon_color" + confirm: !input "entity31_confirm" + component: buttonpage04.button07 + - entity: !input "entity32" + name: !input "entity32_name" + icon: !input "entity32_icon" + icon_color_rgb: !input "entity32_icon_color" + confirm: !input "entity32_confirm" + component: buttonpage04.button08 + - if: "{{ button_page_index >= 0 and button_page_index <= 3 }}" then: - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.set_settings_entity }}" data: - component: "bpage01_label" - message: "{{ button_page01_label }}" + entity: 'unknown' + ##### Button Page Label ##### + - if: "{{ button_pages_labels[button_page_index].label | length > 0 }}" + then: + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ 'bpage%02d_label' | format(button_page_index+1) }}" + message: "{{ button_pages_labels[button_page_index].label }}" - ##### NSPanel build buttons Buttonpage01 ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - entity: "{{ entity01 }}" - button_icon: "{{ entity01_icon }}" - button_label: "{{ entity01_name }}" - button_icon_color: "{{ entity01_icon_color }}" - button: buttonpage01.button01 - - entity: "{{ entity02 }}" - button_icon: "{{ entity02_icon }}" - button_label: "{{ entity02_name }}" - button_icon_color: "{{ entity02_icon_color }}" - button: buttonpage01.button02 - - entity: "{{ entity03 }}" - button_icon: "{{ entity03_icon }}" - button_label: "{{ entity03_name }}" - button_icon_color: "{{ entity03_icon_color }}" - button: buttonpage01.button03 - - entity: "{{ entity04 }}" - button_icon: "{{ entity04_icon }}" - button_label: "{{ entity04_name }}" - button_icon_color: "{{ entity04_icon_color }}" - button: buttonpage01.button04 - - entity: "{{ entity05 }}" - button_icon: "{{ entity05_icon }}" - button_label: "{{ entity05_name }}" - button_icon_color: "{{ entity05_icon_color }}" - button: buttonpage01.button05 - - entity: "{{ entity06 }}" - button_icon: "{{ entity06_icon }}" - button_label: "{{ entity06_name }}" - button_icon_color: "{{ entity06_icon_color }}" - button: buttonpage01.button06 - - entity: "{{ entity07 }}" - button_icon: "{{ entity07_icon }}" - button_label: "{{ entity07_name }}" - button_icon_color: "{{ entity07_icon_color }}" - button: buttonpage01.button07 - - entity: "{{ entity08 }}" - button_icon: "{{ entity08_icon }}" - button_label: "{{ entity08_name }}" - button_icon_color: "{{ entity08_icon_color }}" - button: buttonpage01.button08 - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - variables: - ### component_to_update: "{{ repeat.item.button }}" - current_entity_state: "{{ states(repeat.item.entity) }}" - # Button PIC GRAY/WHITE - btn_pic: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_off }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' -%} {{ button_on }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'closed' -%} {{ button_off }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_off }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ button_on }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ button_off }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ button_on }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ button_off }} - {%- endif -%} - # TEXT, BRIGHTNESS and ICON Background - btn_bg: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_02 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_01 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_02 }} - {%- endif -%} - # ICON Font Color - btn_icon_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_05 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_03 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ repeat.item.button_icon_color }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_03 }} - {%- endif -%} - # LABEL Font Color - btn_txt_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_01 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_02 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_01 }} - {%- endif -%} - # BRIGHTNESS Font Color - btn_bri_font: "{{ color_02 }}" - # ICON Value - btn_icon: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_icon_unknown }} - {%- elif repeat.item.button_icon |length > 0 -%} {{ repeat.item.button_icon }} - {%- elif repeat.item.entity is match "light." -%} {{ button_icon_light }} - {%- elif repeat.item.entity is match "switch." -%} {{ button_icon_switch }} - {%- elif repeat.item.entity is match "input_boolean." -%} {{ button_icon_input_boolan }} - {%- elif repeat.item.entity is match "cover." -%} {{ button_icon_cover }} - {%- elif repeat.item.entity is match "automation." -%} {{ button_icon_automation }} - {%- elif repeat.item.entity is match "button." -%} {{ button_icon_button }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_icon_input_button }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_icon_scene }} - {%- elif repeat.item.entity is match "script." -%} {{ button_icon_script }} - {%- elif repeat.item.entity is match "person." -%} {{ button_icon_person }} - {%- elif repeat.item.entity is match "binary_sensor." -%} {{ button_icon_binary_sensor }} - {%- elif repeat.item.entity is match "fan." -%} {{ button_icon_fan }} - {%- elif repeat.item.entity is match "climate." -%} {{ button_icon_climate }} - {%- endif -%} - # LABEL Value - btn_label: "{{ repeat.item.button_label }}" - # BRIGHTNESS Value - btn_bri_txt: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} 0 - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' and state_attr(repeat.item.entity, "brightness") != None -%} {{ (state_attr(repeat.item.entity, "brightness") | int * 100 /255) | round(0) }}% - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' and state_attr(repeat.item.entity, "current_position") != None -%} {{ (state_attr(repeat.item.entity, "current_position") | int(100)) | round(0) }}% - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None -%} {{ (state_attr(repeat.item.entity, "current_temperature") | int) | round(0) }}{{ weather.units.temperature }} - {%- else -%} 0 - {%- endif -%} - - ##### Set buttton ##### - - service: "{{ command_set_button }}" - data: - btn_id: "{{ repeat.item.button }}" - btn_pic: "{{ btn_pic }}" - btn_bg: "{{ btn_bg }}" - btn_icon_font: "{{ btn_icon_font }}" - btn_txt_font: "{{ btn_txt_font }}" - btn_bri_font: "{{ btn_bri_font }}" - btn_icon: "{{ btn_icon }}" - btn_label: "{{ btn_label }}" - btn_bri_txt: "{{ btn_bri_txt }}" + - *variables-weather + ##### NSPanel build Button page ##### + - repeat: + for_each: "{{ button_pages_buttons[first_button:last_button] }}" + sequence: &display-button_page_button + - if: "{{ repeat.item.entity is string and repeat.item.entity | length > 0 and repeat.item.entity.split('.') | default([]) | count > 0 }}" + then: + - variables: + item_domain: "{{ repeat.item.entity.split('.')[0] | default('unknown') }}" + # {{ states(entity_id) | default('unavailable') if entity_id is string else 'unavailable' }} + current_entity_state: "{{ states(repeat.item.entity) | default('unavailable') }}" + current_entity_state_available: "{{ current_entity_state not in ['unknown', 'unavailable', None] }}" + # Button PIC GRAY/WHITE + btn_pic: "{{ nextion.pics.button.on if current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') else nextion.pics.button.off }}" + # TEXT, BRIGHTNESS and ICON Background + btn_bg: "{{ nextion.colors.white if current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') else nextion.colors.grey_dark }}" + # ICON Font Color + btn_icon_font: > + {% if not current_entity_state_available %} {{ nextion.colors.red }} + {% elif item_domain in ['button', 'input_button', 'scene'] or current_entity_state in ['off', 'closed'] or (item_domain == 'person' and current_entity_state != 'home') %} {{ nextion.colors.grey_light }} + {% elif current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') %} {{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }} + {% else %} {{ nextion.colors.red }} + {% endif %} + # LABEL Font Color + btn_txt_font: >- + {% if not current_entity_state_available %} {{ nextion.colors.white }} + {% elif item_domain in ['button', 'input_button', 'scene'] or current_entity_state in ['off', 'closed'] or (item_domain == 'person' and current_entity_state != 'home') %} {{ nextion.colors.white }} + {% elif current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') %} {{ nextion.colors.grey_dark }} + {% else %} {{ nextion.colors.white }} + {% endif %} + # BRIGHTNESS Font Color + btn_bri_font: "{{ nextion.colors.grey_dark }}" + # ICON Value + btn_icon: "{{ repeat.item.icon if repeat.item.icon | length > 0 else nextion.icons.buttons[repeat.item.entity.split('.')[0] if repeat.item.entity else 'unknown'] }}" + # LABEL Value + btn_label: "{{ repeat.item.name }}" + # BRIGHTNESS Value + btn_bri_txt: >- + {% if not current_entity_state_available %} 0 + {% elif item_domain == 'light' and current_entity_state == 'on' and state_attr(repeat.item.entity, 'brightness') != None %} {{ (state_attr(repeat.item.entity, 'brightness') | int * 100 /255) | round(0) }}% + {% elif item_domain == 'cover' and current_entity_state == 'open' and state_attr(repeat.item.entity, 'current_position') != None %} {{ (state_attr(repeat.item.entity, 'current_position') | int(100)) | round(0) }}% + {% elif item_domain == 'climate' and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None %} {{ (state_attr(repeat.item.entity, "current_temperature") | float) | round(0) }}{{ weather_units.temperature }} + {% else -%} 0 + {% endif -%} + - *delay-default + - service: "{{ nextion.commands.set_button }}" + data: + btn_id: "{{ repeat.item.component }}" + btn_pic: "{{ btn_pic }}" + btn_bg: "{{ btn_bg }}" + btn_icon_font: "{{ btn_icon_font }}" + btn_txt_font: "{{ btn_txt_font }}" + btn_bri_font: "{{ btn_bri_font }}" + btn_icon: "{{ btn_icon }}" + btn_label: "{{ btn_label }}" + btn_bri_txt: "{{ btn_bri_txt }}" ###### SHOW All component when page loading done ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_show_all }}" + - *delay-default + - service: "{{ nextion.commands.show_all }}" - ## PAGE BUTTONPAGE02 ## - - conditions: '{{ trigger.event.data.new_state.state == page_buttonpage02 }}' - alias: 'buttonpage02 page' - sequence: &refresh_page_buttonpage02 - - service: '{{ command_set_settings_entity }}' - data: - entity: 'unknown' - ##### Button Page Label ##### - - if: - - condition: template - value_template: '{{ button_page02_label |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "bpage02_label" - message: "{{ button_page02_label }}" - - ##### NSPanel build buttons Buttonpage01 ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - entity: "{{ entity09 }}" - button_icon: "{{ entity09_icon }}" - button_label: "{{ entity09_name }}" - button_icon_color: "{{ entity09_icon_color }}" - button: buttonpage02.button01 - - entity: "{{ entity10 }}" - button_icon: "{{ entity10_icon }}" - button_label: "{{ entity10_name }}" - button_icon_color: "{{ entity10_icon_color }}" - button: buttonpage02.button02 - - entity: "{{ entity11 }}" - button_icon: "{{ entity11_icon }}" - button_label: "{{ entity11_name }}" - button_icon_color: "{{ entity11_icon_color }}" - button: buttonpage02.button03 - - entity: "{{ entity12 }}" - button_icon: "{{ entity12_icon }}" - button_label: "{{ entity12_name }}" - button_icon_color: "{{ entity12_icon_color }}" - button: buttonpage02.button04 - - entity: "{{ entity13 }}" - button_icon: "{{ entity13_icon }}" - button_label: "{{ entity13_name }}" - button_icon_color: "{{ entity13_icon_color }}" - button: buttonpage02.button05 - - entity: "{{ entity14 }}" - button_icon: "{{ entity14_icon }}" - button_label: "{{ entity14_name }}" - button_icon_color: "{{ entity14_icon_color }}" - button: buttonpage02.button06 - - entity: "{{ entity15 }}" - button_icon: "{{ entity15_icon }}" - button_label: "{{ entity15_name }}" - button_icon_color: "{{ entity15_icon_color }}" - button: buttonpage02.button07 - - entity: "{{ entity16 }}" - button_icon: "{{ entity16_icon }}" - button_label: "{{ entity16_name }}" - button_icon_color: "{{ entity16_icon_color }}" - button: buttonpage02.button08 - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - variables: - ### component_to_update: "{{ repeat.item.button }}" - current_entity_state: "{{ states(repeat.item.entity) }}" - # Button PIC GRAY/WHITE - btn_pic: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_off }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' -%} {{ button_on }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'closed' -%} {{ button_off }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_off }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ button_on }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ button_off }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ button_on }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ button_off }} - {%- endif -%} - # TEXT, BRIGHTNESS and ICON Background - btn_bg: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_02 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_01 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_02 }} - {%- endif -%} - # ICON Font Color - btn_icon_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_05 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_03 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ repeat.item.button_icon_color }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_03 }} - {%- endif -%} - # LABEL Font Color - btn_txt_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_01 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_02 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_01 }} - {%- endif -%} - # BRIGHTNESS Font Color - btn_bri_font: "{{ color_02 }}" - # ICON Value - btn_icon: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_icon_unknown }} - {%- elif repeat.item.button_icon |length > 0 -%} {{ repeat.item.button_icon }} - {%- elif repeat.item.entity is match "light." -%} {{ button_icon_light }} - {%- elif repeat.item.entity is match "switch." -%} {{ button_icon_switch }} - {%- elif repeat.item.entity is match "input_boolean." -%} {{ button_icon_input_boolan }} - {%- elif repeat.item.entity is match "cover." -%} {{ button_icon_cover }} - {%- elif repeat.item.entity is match "automation." -%} {{ button_icon_automation }} - {%- elif repeat.item.entity is match "button." -%} {{ button_icon_button }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_icon_input_button }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_icon_scene }} - {%- elif repeat.item.entity is match "script." -%} {{ button_icon_script }} - {%- elif repeat.item.entity is match "person." -%} {{ button_icon_person }} - {%- elif repeat.item.entity is match "binary_sensor." -%} {{ button_icon_binary_sensor }} - {%- elif repeat.item.entity is match "fan." -%} {{ button_icon_fan }} - {%- elif repeat.item.entity is match "climate." -%} {{ button_icon_climate }} - {%- endif -%} - # LABEL Value - btn_label: "{{ repeat.item.button_label }}" - # BRIGHTNESS Value - btn_bri_txt: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} 0 - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' and state_attr(repeat.item.entity, "brightness") != None -%} {{ (state_attr(repeat.item.entity, "brightness") | int * 100 /255) | round(0) }}% - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' and state_attr(repeat.item.entity, "current_position") != None -%} {{ (state_attr(repeat.item.entity, "current_position") | int(100)) | round(0) }}% - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None -%} {{ (state_attr(repeat.item.entity, "current_temperature") | int) | round(0) }}{{ weather.units.temperature }} - {%- else -%} 0 - {%- endif -%} - - ##### Set buttton ##### - - service: "{{ command_set_button }}" - data: - btn_id: "{{ repeat.item.button }}" - btn_pic: "{{ btn_pic }}" - btn_bg: "{{ btn_bg }}" - btn_icon_font: "{{ btn_icon_font }}" - btn_txt_font: "{{ btn_txt_font }}" - btn_bri_font: "{{ btn_bri_font }}" - btn_icon: "{{ btn_icon }}" - btn_label: "{{ btn_label }}" - btn_bri_txt: "{{ btn_bri_txt }}" - - ###### SHOW All component when page loading done ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_show_all }}" - - ## PAGE BUTTONPAGE03 ## - - conditions: '{{ trigger.event.data.new_state.state == page_buttonpage03 }}' - alias: 'buttonpage03 page' - sequence: &refresh_page_buttonpage03 - - service: '{{ command_set_settings_entity }}' - data: - entity: 'unknown' - ##### Button Page Label ##### - - if: - - condition: template - value_template: '{{ button_page03_label |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "bpage03_label" - message: "{{ button_page03_label }}" - - ##### NSPanel build buttons Buttonpage01 ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - entity: "{{ entity17 }}" - button_icon: "{{ entity17_icon }}" - button_label: "{{ entity17_name }}" - button_icon_color: "{{ entity17_icon_color }}" - button: buttonpage03.button01 - - entity: "{{ entity18 }}" - button_icon: "{{ entity18_icon }}" - button_label: "{{ entity18_name }}" - button_icon_color: "{{ entity18_icon_color }}" - button: buttonpage03.button02 - - entity: "{{ entity19 }}" - button_icon: "{{ entity19_icon }}" - button_label: "{{ entity19_name }}" - button_icon_color: "{{ entity19_icon_color }}" - button: buttonpage03.button03 - - entity: "{{ entity20 }}" - button_icon: "{{ entity20_icon }}" - button_label: "{{ entity20_name }}" - button_icon_color: "{{ entity20_icon_color }}" - button: buttonpage03.button04 - - entity: "{{ entity21 }}" - button_icon: "{{ entity21_icon }}" - button_label: "{{ entity21_name }}" - button_icon_color: "{{ entity21_icon_color }}" - button: buttonpage03.button05 - - entity: "{{ entity22 }}" - button_icon: "{{ entity22_icon }}" - button_label: "{{ entity22_name }}" - button_icon_color: "{{ entity22_icon_color }}" - button: buttonpage03.button06 - - entity: "{{ entity23 }}" - button_icon: "{{ entity23_icon }}" - button_label: "{{ entity23_name }}" - button_icon_color: "{{ entity23_icon_color }}" - button: buttonpage03.button07 - - entity: "{{ entity24 }}" - button_icon: "{{ entity24_icon }}" - button_label: "{{ entity24_name }}" - button_icon_color: "{{ entity24_icon_color }}" - button: buttonpage03.button08 - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - variables: - ### component_to_update: "{{ repeat.item.button }}" - current_entity_state: "{{ states(repeat.item.entity) }}" - # Button PIC GRAY/WHITE - btn_pic: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_off }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' -%} {{ button_on }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'closed' -%} {{ button_off }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_off }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ button_on }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ button_off }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ button_on }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ button_off }} - {%- endif -%} - # TEXT, BRIGHTNESS and ICON Background - btn_bg: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_02 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_01 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_02 }} - {%- endif -%} - # ICON Font Color - btn_icon_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_05 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_03 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ repeat.item.button_icon_color }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_03 }} - {%- endif -%} - # LABEL Font Color - btn_txt_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_01 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_02 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_01 }} - {%- endif -%} - # BRIGHTNESS Font Color - btn_bri_font: "{{ color_02 }}" - # ICON Value - btn_icon: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_icon_unknown }} - {%- elif repeat.item.button_icon |length > 0 -%} {{ repeat.item.button_icon }} - {%- elif repeat.item.entity is match "light." -%} {{ button_icon_light }} - {%- elif repeat.item.entity is match "switch." -%} {{ button_icon_switch }} - {%- elif repeat.item.entity is match "input_boolean." -%} {{ button_icon_input_boolan }} - {%- elif repeat.item.entity is match "cover." -%} {{ button_icon_cover }} - {%- elif repeat.item.entity is match "automation." -%} {{ button_icon_automation }} - {%- elif repeat.item.entity is match "button." -%} {{ button_icon_button }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_icon_input_button }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_icon_scene }} - {%- elif repeat.item.entity is match "script." -%} {{ button_icon_script }} - {%- elif repeat.item.entity is match "person." -%} {{ button_icon_person }} - {%- elif repeat.item.entity is match "binary_sensor." -%} {{ button_icon_binary_sensor }} - {%- elif repeat.item.entity is match "fan." -%} {{ button_icon_fan }} - {%- elif repeat.item.entity is match "climate." -%} {{ button_icon_climate }} - {%- endif -%} - # LABEL Value - btn_label: "{{ repeat.item.button_label }}" - # BRIGHTNESS Value - btn_bri_txt: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} 0 - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' and state_attr(repeat.item.entity, "brightness") != None -%} {{ (state_attr(repeat.item.entity, "brightness") | int * 100 /255) | round(0) }}% - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' and state_attr(repeat.item.entity, "current_position") != None -%} {{ (state_attr(repeat.item.entity, "current_position") | int(100)) | round(0) }}% - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None -%} {{ (state_attr(repeat.item.entity, "current_temperature") | int) | round(0) }}{{ weather.units.temperature }} - {%- else -%} 0 - {%- endif -%} - - ##### Set buttton ##### - - service: "{{ command_set_button }}" - data: - btn_id: "{{ repeat.item.button }}" - btn_pic: "{{ btn_pic }}" - btn_bg: "{{ btn_bg }}" - btn_icon_font: "{{ btn_icon_font }}" - btn_txt_font: "{{ btn_txt_font }}" - btn_bri_font: "{{ btn_bri_font }}" - btn_icon: "{{ btn_icon }}" - btn_label: "{{ btn_label }}" - btn_bri_txt: "{{ btn_bri_txt }}" - - ###### SHOW All component when page loading done ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_show_all }}" - - ## PAGE BUTTONPAGE04 ## - - conditions: '{{ trigger.event.data.new_state.state == page_buttonpage04 }}' - alias: 'buttonpage04 page' - sequence: &refresh_page_buttonpage04 - - service: '{{ command_set_settings_entity }}' - data: - entity: 'unknown' - ##### Button Page Label ##### - - if: - - condition: template - value_template: '{{ button_page04_label |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "bpage04_label" - message: "{{ button_page04_label }}" - - ##### NSPanel build buttons Buttonpage01 ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - entity: "{{ entity25 }}" - button_icon: "{{ entity25_icon }}" - button_label: "{{ entity25_name }}" - button_icon_color: "{{ entity25_icon_color }}" - button: buttonpage04.button01 - - entity: "{{ entity26 }}" - button_icon: "{{ entity26_icon }}" - button_label: "{{ entity26_name }}" - button_icon_color: "{{ entity26_icon_color }}" - button: buttonpage04.button02 - - entity: "{{ entity27 }}" - button_icon: "{{ entity27_icon }}" - button_label: "{{ entity27_name }}" - button_icon_color: "{{ entity27_icon_color }}" - button: buttonpage04.button03 - - entity: "{{ entity28 }}" - button_icon: "{{ entity28_icon }}" - button_label: "{{ entity28_name }}" - button_icon_color: "{{ entity28_icon_color }}" - button: buttonpage04.button04 - - entity: "{{ entity29 }}" - button_icon: "{{ entity29_icon }}" - button_label: "{{ entity29_name }}" - button_icon_color: "{{ entity29_icon_color }}" - button: buttonpage04.button05 - - entity: "{{ entity30 }}" - button_icon: "{{ entity30_icon }}" - button_label: "{{ entity30_name }}" - button_icon_color: "{{ entity30_icon_color }}" - button: buttonpage04.button06 - - entity: "{{ entity31 }}" - button_icon: "{{ entity31_icon }}" - button_label: "{{ entity31_name }}" - button_icon_color: "{{ entity31_icon_color }}" - button: buttonpage04.button07 - - entity: "{{ entity32 }}" - button_icon: "{{ entity32_icon }}" - button_label: "{{ entity32_name }}" - button_icon_color: "{{ entity32_icon_color }}" - button: buttonpage04.button08 - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - variables: - ### component_to_update: "{{ repeat.item.button }}" - current_entity_state: "{{ states(repeat.item.entity) }}" - # Button PIC GRAY/WHITE - btn_pic: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_off }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "light." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "switch." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "input_boolean." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' -%} {{ button_on }} - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'closed' -%} {{ button_off }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "automation." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_off }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_off }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "script." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ button_on }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ button_off }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "binary_sensor." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'on' -%} {{ button_on }} - {%- elif repeat.item.entity is match "fan." and current_entity_state == 'off' -%} {{ button_off }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ button_on }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ button_off }} - {%- endif -%} - # TEXT, BRIGHTNESS and ICON Background - btn_bg: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_02 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_01 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_02 }} - {%- endif -%} - # ICON Font Color - btn_icon_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_05 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_03 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ repeat.item.button_icon_color }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_03 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ repeat.item.button_icon_color }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_03 }} - {%- endif -%} - # LABEL Font Color - btn_txt_font: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "button." or repeat.item.entity is match "input_button." or repeat.item.entity is match "scene." -%} {{ color_01 }} - {%- elif current_entity_state == 'on' or current_entity_state == 'open' -%} {{ color_02 }} - {%- elif current_entity_state == 'off' or current_entity_state == 'closed' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "person." and current_entity_state == 'home' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "person." and current_entity_state != 'home' -%} {{ color_01 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' -%} {{ color_02 }} - {%- elif repeat.item.entity is match "climate." and current_entity_state == 'off' -%} {{ color_01 }} - {%- endif -%} - # BRIGHTNESS Font Color - btn_bri_font: "{{ color_02 }}" - # ICON Value - btn_icon: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} {{ button_icon_unknown }} - {%- elif repeat.item.button_icon |length > 0 -%} {{ repeat.item.button_icon }} - {%- elif repeat.item.entity is match "light." -%} {{ button_icon_light }} - {%- elif repeat.item.entity is match "switch." -%} {{ button_icon_switch }} - {%- elif repeat.item.entity is match "input_boolean." -%} {{ button_icon_input_boolan }} - {%- elif repeat.item.entity is match "cover." -%} {{ button_icon_cover }} - {%- elif repeat.item.entity is match "automation." -%} {{ button_icon_automation }} - {%- elif repeat.item.entity is match "button." -%} {{ button_icon_button }} - {%- elif repeat.item.entity is match "input_button." -%} {{ button_icon_input_button }} - {%- elif repeat.item.entity is match "scene." -%} {{ button_icon_scene }} - {%- elif repeat.item.entity is match "script." -%} {{ button_icon_script }} - {%- elif repeat.item.entity is match "person." -%} {{ button_icon_person }} - {%- elif repeat.item.entity is match "binary_sensor." -%} {{ button_icon_binary_sensor }} - {%- elif repeat.item.entity is match "fan." -%} {{ button_icon_fan }} - {%- elif repeat.item.entity is match "climate." -%} {{ button_icon_climate }} - {%- endif -%} - # LABEL Value - btn_label: "{{ repeat.item.button_label }}" - # BRIGHTNESS Value - btn_bri_txt: >- - {%- if current_entity_state == 'unknown' or current_entity_state == 'unavailable' -%} 0 - {%- elif repeat.item.entity is match "light." and current_entity_state == 'on' and state_attr(repeat.item.entity, "brightness") != None -%} {{ (state_attr(repeat.item.entity, "brightness") | int * 100 /255) | round(0) }}% - {%- elif repeat.item.entity is match "cover." and current_entity_state == 'open' and state_attr(repeat.item.entity, "current_position") != None -%} {{ (state_attr(repeat.item.entity, "current_position") | int(100)) | round(0) }}% - {%- elif repeat.item.entity is match "climate." and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None -%} {{ (state_attr(repeat.item.entity, "current_temperature") | int) | round(0) }}{{ weather.units.temperature }} - {%- else -%} 0 - {%- endif -%} - - ##### Set buttton ##### - - service: "{{ command_set_button }}" - data: - btn_id: "{{ repeat.item.button }}" - btn_pic: "{{ btn_pic }}" - btn_bg: "{{ btn_bg }}" - btn_icon_font: "{{ btn_icon_font }}" - btn_txt_font: "{{ btn_txt_font }}" - btn_bri_font: "{{ btn_bri_font }}" - btn_icon: "{{ btn_icon }}" - btn_label: "{{ btn_label }}" - btn_bri_txt: "{{ btn_bri_txt }}" - - ###### SHOW All component when page loading done ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_show_all }}" - - ## PAGE LIGHTSETTUNGS ## - - conditions: '{{ trigger.event.data.new_state.state == page_lightsettings }}' - alias: 'lightsettings page' + ## PAGE LIGHTSETTINGS ## + - alias: Light settings page + conditions: "{{ trigger.event.data.new_state.state == nextion.pages.light }}" sequence: - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_name - message: '{{ entity_long_name }}' + message: "{{ entity_long_name }}" ##### LIGHT ICON - ON / OFF ##### - variables: - lightsettings_icon_font: >- - {%- if entity_long_icon |length > 0 -%} {{ entity_long_icon }} - {%- else -%} {{ button_icon_light }} - {%- endif -%} - lightsettings_icon_font_color: >- - {%- if states(entity_long) == 'on' -%} {{ entity_long_icon_color }} - {%- else -%} {{ color_03 }} - {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + lightsettings_icon_font: "{{ entity_long_icon if entity_long_icon not in ['unavailable', 'unknown', None] and entity_long_icon | length > 0 else nextion.icons.buttons.light }}" + lightsettings_icon_font_color: "{{ entity_long_icon_color if is_state(entity_long, 'on') else nextion.colors.grey_light }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.icon_state message: "{{ lightsettings_icon_font }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: lightsettings.icon_state message: "{{ lightsettings_icon_font_color }}" ##### LIGHT State ##### - - delay: - milliseconds: "{{ delay_value }}" - - if: - - condition: template - value_template: "{{ state_attr(entity_long, 'brightness') != none }}" + - *delay-default + - if: "{{ state_attr(entity_long, 'brightness') != none }}" then: - - service: "{{ command_value }}" + - service: "{{ nextion.commands.value }}" data: component: lightsettings.lightslider - message: '{{ (state_attr(entity_long, "brightness") | int * 100 / 255) |round(0) }}' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ (state_attr(entity_long, 'brightness') | int * 100 / 255) | round(0) }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value - message: '{{ (state_attr(entity_long, "brightness") | int * 100 / 255) | round(0) }}%' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ (state_attr(entity_long, 'brightness') | int * 100 / 255) | round(0) }}%" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value_2 - message: '{{ (state_attr(entity_long, "brightness") | int * 100 /255) | round(0) }}%' + message: "{{ (state_attr(entity_long, 'brightness') | int * 100 /255) | round(0) }}%" else: - - service: "{{ command_value }}" + - service: "{{ nextion.commands.value }}" data: component: lightsettings.lightslider message: '0' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value message: '0 %' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value_2 message: '0 %' ##### LIGHT Check Color_Temp Value is available when yes send some current Values ##### - - if: - - condition: template - value_template: "{{ state_attr(entity_long, 'color_temp') != none }}" + - if: "{{ state_attr(entity_long, 'color_temp') != none }}" then: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.temp_value - message: '{{ (state_attr(entity_long, "color_temp") | int ) |round(0) }}' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ (state_attr(entity_long, 'color_temp') | int ) | round(0) }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.temp_value_2 - message: '{{ (state_attr(entity_long, "color_temp") | int ) |round(0) }}' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_value }}" + message: "{{ (state_attr(entity_long, 'color_temp') | int ) | round(0) }}" + - *delay-default + - service: "{{ nextion.commands.value }}" data: component: lightsettings.tempslider - message: '{{ (state_attr(entity_long, "color_temp") | int ) |round(0) }}' + message: "{{ (state_attr(entity_long, 'color_temp') | int ) | round(0) }}" ## PAGE COVERSETTINGS ## - - conditions: '{{ trigger.event.data.new_state.state == page_coversettings }}' - alias: 'coversettings page' + - alias: Cover settings page + conditions: "{{ trigger.event.data.new_state.state == nextion.pages.cover }}" sequence: ##### COVER - OPEN / CLOSE ##### - variables: - coversettings_icon_font: >- - {%- if entity_long_icon |length > 0 -%} {{ entity_long_icon }} - {%- else -%} {{ button_icon_cover }} - {%- endif -%} - coversettings_icon_font_color: >- - {%- if states(entity_long) == 'open' -%} {{ entity_long_icon_color }} - {%- else -%} {{ color_03 }} - {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + coversettings_icon_font: "{{ entity_long_icon if entity_long_icon | length > 0 else nextion.icons.buttons.cover }}" + coversettings_icon_font_color: "{{ entity_long_icon_color if is_state(entity_long, 'open') else nextion.colors.grey_light }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.icon_state message: "{{ coversettings_icon_font }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: coversettings.icon_state message: "{{ coversettings_icon_font_color }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.cover_name - message: '{{ entity_long_name }}' + message: "{{ entity_long_name }}" ##### COVER State - - service: "{{ command_value }}" + - service: "{{ nextion.commands.value }}" data: component: coversettings.coverslider - message: '{{ (state_attr(entity_long, "current_position") | int ) |round(0) }}' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ (state_attr(entity_long, 'current_position') | int ) | round(0) }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.cover_value - message: '{{ (state_attr(entity_long, "current_position") | int ) |round(0) }} %' + message: "{{ (state_attr(entity_long, 'current_position') | int ) | round(0) }} %" ##### COVER Battery ICON Yes / NO ##### - - if: - - condition: template - value_template: "{{ state_attr(entity_long, 'battery') != none }}" + - if: "{{ state_attr(entity_long, 'battery') != none }}" then: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.battery_value - message: '{{ (state_attr(entity_long, "battery") | int ) |round(0) }} %' + message: "{{ (state_attr(entity_long, 'battery') | int ) | round(0) }} %" ### ICON Battery Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: coversettings.battery_icon - message: "{{ battery_icon_color }}" + message: "{{ nextion.colors.grey_super_light }}" ### ICON Battery Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.battery_icon - message: "{{ battery_icon }}" + message: "{{ nextion.icons.battery }}" - ## ENTITY PAGE 01 ## - - conditions: '{{ trigger.event.data.new_state.state == page_entitypage01 }}' - alias: 'entity01 page' - sequence: &refresh_page_entitypage01 - ##### ENTITY Page Label ##### - - if: - - condition: template - value_template: '{{ entity_page01_label |length > 0 }}' + ## ENTITY PAGES 01 - 04 ## + - alias: Entity pages + conditions: "{{ trigger.event.data.new_state.state in nextion.pages.entitypages }}" + sequence: &refresh-entity_pages + - &variables-entity_pages + variables: + ##### Entity pages ##### + entity_pages_labels: + - label: !input "entity_page01_label" + - label: !input "entity_page02_label" + - label: !input "entity_page03_label" + - label: !input "entity_page04_label" + entity_pages_entities: + - entity: !input "entities_entity01" + name: !input "entities_entity01_name" + icon: !input "entities_entity01_icon" + component: entitypage01.value01 + - entity: !input "entities_entity02" + name: !input "entities_entity02_name" + icon: !input "entities_entity02_icon" + component: entitypage01.value02 + - entity: !input "entities_entity03" + name: !input "entities_entity03_name" + icon: !input "entities_entity03_icon" + component: entitypage01.value03 + - entity: !input "entities_entity04" + name: !input "entities_entity04_name" + icon: !input "entities_entity04_icon" + component: entitypage01.value04 + - entity: !input "entities_entity05" + name: !input "entities_entity05_name" + icon: !input "entities_entity05_icon" + component: entitypage01.value05 + - entity: !input "entities_entity06" + name: !input "entities_entity06_name" + icon: !input "entities_entity06_icon" + component: entitypage01.value06 + - entity: !input "entities_entity07" + name: !input "entities_entity07_name" + icon: !input "entities_entity07_icon" + component: entitypage01.value07 + - entity: !input "entities_entity08" + name: !input "entities_entity08_name" + icon: !input "entities_entity08_icon" + component: entitypage01.value08 + - entity: !input "entities_entity09" + name: !input "entities_entity09_name" + icon: !input "entities_entity09_icon" + component: entitypage02.value01 + - entity: !input "entities_entity10" + name: !input "entities_entity10_name" + icon: !input "entities_entity10_icon" + component: entitypage02.value02 + - entity: !input "entities_entity11" + name: !input "entities_entity11_name" + icon: !input "entities_entity11_icon" + component: entitypage02.value03 + - entity: !input "entities_entity12" + name: !input "entities_entity12_name" + icon: !input "entities_entity12_icon" + component: entitypage02.value04 + - entity: !input "entities_entity13" + name: !input "entities_entity13_name" + icon: !input "entities_entity13_icon" + component: entitypage02.value05 + - entity: !input "entities_entity14" + name: !input "entities_entity14_name" + icon: !input "entities_entity14_icon" + component: entitypage02.value06 + - entity: !input "entities_entity15" + name: !input "entities_entity15_name" + icon: !input "entities_entity15_icon" + component: entitypage02.value07 + - entity: !input "entities_entity16" + name: !input "entities_entity16_name" + icon: !input "entities_entity16_icon" + component: entitypage02.value08 + - entity: !input "entities_entity17" + name: !input "entities_entity17_name" + icon: !input "entities_entity17_icon" + component: entitypage03.value01 + - entity: !input "entities_entity18" + name: !input "entities_entity18_name" + icon: !input "entities_entity18_icon" + component: entitypage03.value02 + - entity: !input "entities_entity19" + name: !input "entities_entity19_name" + icon: !input "entities_entity19_icon" + component: entitypage03.value03 + - entity: !input "entities_entity20" + name: !input "entities_entity20_name" + icon: !input "entities_entity20_icon" + component: entitypage03.value04 + - entity: !input "entities_entity21" + name: !input "entities_entity21_name" + icon: !input "entities_entity21_icon" + component: entitypage03.value05 + - entity: !input "entities_entity22" + name: !input "entities_entity22_name" + icon: !input "entities_entity22_icon" + component: entitypage03.value06 + - entity: !input "entities_entity23" + name: !input "entities_entity23_name" + icon: !input "entities_entity23_icon" + component: entitypage03.value07 + - entity: !input "entities_entity24" + name: !input "entities_entity24_name" + icon: !input "entities_entity24_icon" + component: entitypage03.value08 + - entity: !input "entities_entity25" + name: !input "entities_entity25_name" + icon: !input "entities_entity25_icon" + component: entitypage04.value01 + - entity: !input "entities_entity26" + name: !input "entities_entity26_name" + icon: !input "entities_entity26_icon" + component: entitypage04.value02 + - entity: !input "entities_entity27" + name: !input "entities_entity27_name" + icon: !input "entities_entity27_icon" + component: entitypage04.value03 + - entity: !input "entities_entity28" + name: !input "entities_entity28_name" + icon: !input "entities_entity28_icon" + component: entitypage04.value04 + - entity: !input "entities_entity29" + name: !input "entities_entity29_name" + icon: !input "entities_entity29_icon" + component: entitypage04.value05 + - entity: !input "entities_entity30" + name: !input "entities_entity30_name" + icon: !input "entities_entity30_icon" + component: entitypage04.value06 + - entity: !input "entities_entity31" + name: !input "entities_entity31_name" + icon: !input "entities_entity31_icon" + component: entitypage04.value07 + - entity: !input "entities_entity32" + name: !input "entities_entity32_name" + icon: !input "entities_entity32_icon" + component: entitypage04.value08 + - variables: + entity_page_index: "{{ (nextion.pages.current[-2:] | int(-1)) - 1 }}" + first_entity: "{{ entity_page_index * 8 }}" + last_entity: "{{ first_entity + 8 }}" + ##### Entity page - Label ##### + - if: "{{ entity_pages_labels[entity_page_index].label | length > 0 }}" then: - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: - component: "entity01_label" - message: "{{ entity_page01_label }}" + component: "{{ 'entity%02d_label' | format(entity_page_index + 1) }}" + message: "{{ entity_pages_labels[entity_page_index].label }}" + - *delay-default ##### Entities ##### - - delay: - milliseconds: "{{ delay_value }}" - repeat: - for_each: - - row: entitypage01.value01 - entity: "{{ entities_entity01 }}" - entity_name: "{{ entities_entity01_name }}" - entity_icon: "{{ entities_entity01_icon }}" - - row: entitypage01.value02 - entity: "{{ entities_entity02 }}" - entity_name: "{{ entities_entity02_name }}" - entity_icon: "{{ entities_entity02_icon }}" - - row: entitypage01.value03 - entity: "{{ entities_entity03 }}" - entity_name: "{{ entities_entity03_name }}" - entity_icon: "{{ entities_entity03_icon }}" - - row: entitypage01.value04 - entity: "{{ entities_entity04 }}" - entity_name: "{{ entities_entity04_name }}" - entity_icon: "{{ entities_entity04_icon }}" - - row: entitypage01.value05 - entity: "{{ entities_entity05 }}" - entity_name: "{{ entities_entity05_name }}" - entity_icon: "{{ entities_entity05_icon }}" - - row: entitypage01.value06 - entity: "{{ entities_entity06 }}" - entity_name: "{{ entities_entity06_name }}" - entity_icon: "{{ entities_entity06_icon }}" - - row: entitypage01.value07 - entity: "{{ entities_entity07 }}" - entity_name: "{{ entities_entity07_name }}" - entity_icon: "{{ entities_entity07_icon }}" - - row: entitypage01.value08 - entity: "{{ entities_entity08 }}" - entity_name: "{{ entities_entity08_name }}" - entity_icon: "{{ entities_entity08_icon }}" - - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' + for_each: "{{ entity_pages_entities[first_entity:last_entity] }}" + sequence: &update-entity_page_entity + - if: "{{ repeat.item.entity is string and repeat.item.entity | length > 0 }}" then: - - if: - - condition: template - value_template: '{{ repeat.item.entity_icon |length > 0 }}' + - variables: + repeat_item_state: "{{ states(repeat.item.entity) | default('unavailable') }}" + - if: "{{ repeat.item.icon | length > 0 }}" then: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ repeat.item.row }}_pic" - message: "{{ repeat.item.entity_icon }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + component: "{{ repeat.item.component }}_pic" + message: "{{ repeat.item.icon }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ repeat.item.row }}_label" + component: "{{ repeat.item.component }}_label" message: >- - {%- if repeat.item.entity_name |length > 0 -%} {{ repeat.item.entity_name }} - {%- elif states(repeat.item.entity) == 'unavailable' -%} {{ repeat.item.entity }} - {%- else -%} {{ state_attr(repeat.item.entity, "friendly_name")| default('no name') }} + {%- if repeat.item.name | length > 0 -%} {{ repeat.item.name }} + {%- elif repeat_item_state in ['unavailable', 'unknown', None] -%} {{ repeat.item.entity }} + {%- else -%} {{ state_attr(repeat.item.entity, 'friendly_name') | default(mui[language].no_name) }} {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ repeat.item.row }}" - #message: '{{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement")| default("") }}' - message: >- - {%- if state_attr(repeat.item.entity, "unit_of_measurement") == None -%} - {{ states(repeat.item.entity) }} - {%- else -%} - {{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement") }} - {%- endif -%} - - ## ENTITY PAGE 02 ## - - conditions: '{{ trigger.event.data.new_state.state == page_entitypage02 }}' - alias: 'entity02 page' - sequence: &refresh_page_entitypage02 - ##### ENTITY Page Label ##### - - if: - - condition: template - value_template: '{{ entity_page02_label |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "entity02_label" - message: "{{ entity_page02_label }}" - ##### Entities ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - row: entitypage02.value01 - entity: "{{ entities_entity09 }}" - entity_name: "{{ entities_entity09_name }}" - entity_icon: "{{ entities_entity09_icon }}" - - row: entitypage02.value02 - entity: "{{ entities_entity10 }}" - entity_name: "{{ entities_entity10_name }}" - entity_icon: "{{ entities_entity10_icon }}" - - row: entitypage02.value03 - entity: "{{ entities_entity11 }}" - entity_name: "{{ entities_entity11_name }}" - entity_icon: "{{ entities_entity11_icon }}" - - row: entitypage02.value04 - entity: "{{ entities_entity12 }}" - entity_name: "{{ entities_entity12_name }}" - entity_icon: "{{ entities_entity12_icon }}" - - row: entitypage02.value05 - entity: "{{ entities_entity13 }}" - entity_name: "{{ entities_entity13_name }}" - entity_icon: "{{ entities_entity13_icon }}" - - row: entitypage02.value06 - entity: "{{ entities_entity14 }}" - entity_name: "{{ entities_entity14_name }}" - entity_icon: "{{ entities_entity14_icon }}" - - row: entitypage02.value07 - entity: "{{ entities_entity15 }}" - entity_name: "{{ entities_entity15_name }}" - entity_icon: "{{ entities_entity15_icon }}" - - row: entitypage02.value08 - entity: "{{ entities_entity16 }}" - entity_name: "{{ entities_entity16_name }}" - entity_icon: "{{ entities_entity16_icon }}" - - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - if: - - condition: template - value_template: '{{ repeat.item.entity_icon |length > 0 }}' - then: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}_pic" - message: "{{ repeat.item.entity_icon }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}_label" - message: >- - {%- if repeat.item.entity_name |length > 0 -%} {{ repeat.item.entity_name }} - {%- elif states(repeat.item.entity) == 'unavailable' -%} {{ repeat.item.entity }} - {%- else -%} {{ state_attr(repeat.item.entity, "friendly_name")| default('no name') }} - {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}" - #message: '{{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement")| default("") }}' - message: >- - {%- if state_attr(repeat.item.entity, "unit_of_measurement") == None -%} - {{ states(repeat.item.entity) }} - {%- else -%} - {{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement") }} - {%- endif -%} - - ## ENTITY PAGE 03 ## - - conditions: '{{ trigger.event.data.new_state.state == page_entitypage03 }}' - alias: 'entity03 page' - sequence: &refresh_page_entitypage03 - ##### ENTITY Page Label ##### - - if: - - condition: template - value_template: '{{ entity_page03_label |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "entity03_label" - message: "{{ entity_page03_label }}" - ##### Entities ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - row: entitypage03.value01 - entity: "{{ entities_entity17 }}" - entity_name: "{{ entities_entity17_name }}" - entity_icon: "{{ entities_entity17_icon }}" - - row: entitypage03.value02 - entity: "{{ entities_entity18 }}" - entity_name: "{{ entities_entity18_name }}" - entity_icon: "{{ entities_entity18_icon }}" - - row: entitypage03.value03 - entity: "{{ entities_entity19 }}" - entity_name: "{{ entities_entity19_name }}" - entity_icon: "{{ entities_entity19_icon }}" - - row: entitypage03.value04 - entity: "{{ entities_entity20 }}" - entity_name: "{{ entities_entity20_name }}" - entity_icon: "{{ entities_entity20_icon }}" - - row: entitypage03.value05 - entity: "{{ entities_entity21 }}" - entity_name: "{{ entities_entity21_name }}" - entity_icon: "{{ entities_entity21_icon }}" - - row: entitypage03.value06 - entity: "{{ entities_entity22 }}" - entity_name: "{{ entities_entity22_name }}" - entity_icon: "{{ entities_entity22_icon }}" - - row: entitypage03.value07 - entity: "{{ entities_entity23 }}" - entity_name: "{{ entities_entity23_name }}" - entity_icon: "{{ entities_entity23_icon }}" - - row: entitypage03.value08 - entity: "{{ entities_entity24 }}" - entity_name: "{{ entities_entity24_name }}" - entity_icon: "{{ entities_entity24_icon }}" - - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - if: - - condition: template - value_template: '{{ repeat.item.entity_icon |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}_pic" - message: "{{ repeat.item.entity_icon }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}_label" - message: >- - {%- if repeat.item.entity_name |length > 0 -%} {{ repeat.item.entity_name }} - {%- elif states(repeat.item.entity) == 'unavailable' -%} {{ repeat.item.entity }} - {%- else -%} {{ state_attr(repeat.item.entity, "friendly_name")| default('no name') }} - {%- endif -%} - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}" - #message: '{{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement")| default("") }}' - message: >- - {%- if state_attr(repeat.item.entity, "unit_of_measurement") == None -%} - {{ states(repeat.item.entity) }} - {%- else -%} - {{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement") }} - {%- endif -%} - - ## ENTITY PAGE 04 ## - - conditions: '{{ trigger.event.data.new_state.state == page_entitypage04 }}' - alias: 'entity04 page' - sequence: &refresh_page_entitypage04 - ##### ENTITY Page Label ##### - - if: - - condition: template - value_template: '{{ entity_page04_label |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "entity04_label" - message: "{{ entity_page04_label }}" - ##### Entities ##### - - delay: - milliseconds: "{{ delay_value }}" - - repeat: - for_each: - - row: entitypage04.value01 - entity: "{{ entities_entity25 }}" - entity_name: "{{ entities_entity25_name }}" - entity_icon: "{{ entities_entity25_icon }}" - - row: entitypage04.value02 - entity: "{{ entities_entity26 }}" - entity_name: "{{ entities_entity26_name }}" - entity_icon: "{{ entities_entity26_icon }}" - - row: entitypage04.value03 - entity: "{{ entities_entity27 }}" - entity_name: "{{ entities_entity27_name }}" - entity_icon: "{{ entities_entity27_icon }}" - - row: entitypage04.value04 - entity: "{{ entities_entity28 }}" - entity_name: "{{ entities_entity28_name }}" - entity_icon: "{{ entities_entity28_icon }}" - - row: entitypage04.value05 - entity: "{{ entities_entity29 }}" - entity_name: "{{ entities_entity29_name }}" - entity_icon: "{{ entities_entity29_icon }}" - - row: entitypage04.value06 - entity: "{{ entities_entity30 }}" - entity_name: "{{ entities_entity30_name }}" - entity_icon: "{{ entities_entity30_icon }}" - - row: entitypage04.value07 - entity: "{{ entities_entity31 }}" - entity_name: "{{ entities_entity31_name }}" - entity_icon: "{{ entities_entity31_icon }}" - - row: entitypage04.value08 - entity: "{{ entities_entity32 }}" - entity_name: "{{ entities_entity32_name }}" - entity_icon: "{{ entities_entity32_icon }}" - - sequence: - - if: - - condition: template - value_template: '{{ repeat.item.entity|length > 0 }}' - then: - - if: - - condition: template - value_template: '{{ repeat.item.entity_icon |length > 0 }}' - then: - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}_pic" - message: "{{ repeat.item.entity_icon }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}_label" - message: >- - {%- if repeat.item.entity_name |length > 0 -%} {{ repeat.item.entity_name }} - {%- elif states(repeat.item.entity) == 'unavailable' -%} {{ repeat.item.entity }} - {%- else -%} {{ state_attr(repeat.item.entity, "friendly_name")| default('no name') }} - {%- endif -%} - - service: "{{ command_text_printf }}" - data: - component: "{{ repeat.item.row }}" - #message: '{{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement")| default("") }}' - message: >- - {%- if state_attr(repeat.item.entity, "unit_of_measurement") == None -%} - {{ states(repeat.item.entity) }} - {%- else -%} - {{ states(repeat.item.entity) }} {{ state_attr(repeat.item.entity, "unit_of_measurement") }} - {%- endif -%} + component: "{{ repeat.item.component }}" + message: "{{ repeat_item_state ~ ((state_attr(repeat.item.entity, 'unit_of_measurement') | default('')) if state_attr(repeat.item.entity, 'unit_of_measurement') else '') }}" ## PAGE CLIMATE ## - - alias: 'climate page' - conditions: '{{ trigger.event.data.new_state.state == page_climate }}' + - alias: Climate page + conditions: "{{ trigger.event.data.new_state.state == nextion.pages.climate }}" sequence: + - *variables-weather - variables: - hvac_mode: "{{ states(entity_long) }}" - outdoor_temp: >- - {%- if outdoortemp is match "sensor." - and states(outdoortemp) != "unavailable" - and states(outdoortemp).state is defined - and is_number(states(outdoortemp).state) -%} - {{ states(outdoortemp) | round(1) }} - {%- else -%} {{state_attr(weather.entity,"temperature") | round(1) if is_number(state_attr(weather.entity, "temperature")) else 0 }} - {%- endif -%} + hvac_mode: "{{ states(entity_long) | default('unavailable') if entity_long is string else 'unavailable' }}" + outdoor_temp_state: "{{ states(outdoortemp) | default('unavailable') if outdoortemp is string else 'unavailable' }}" + outdoor_temp: "{{ outdoor_temp_state if is_number(outdoor_temp_state) else state_attr(weather_entity, 'temperature') | default('unavailable') if weather_entity is string else 'unavailable' }}" heating_state: "{{ mui[language].climate.states.off if hvac_mode == 'off' else mui[language].climate.states.on }}" - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: climate.climate_label - message: '{{ entity_long_name }}' - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ entity_long_name }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: outdoor_temp - message: "{{ outdoor_temp ~ weather.units.temperature }}" - - service: "{{ command_text_printf }}" + message: "{{ (outdoor_temp | round(1) ~ weather_units.temperature) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" + + - service: "{{ nextion.commands.text_printf }}" data: component: current_temp - message: "{{ (state_attr(entity_long, 'current_temperature') | round(1) ~ weather.units.temperature) if is_number(state_attr(entity_long, 'current_temperature')) }}" - - if: - condition: template - value_template: '{{ hvac_mode != "off" and is_number(state_attr(entity_long, "temperature")) }}' + message: "{{ (state_attr(entity_long, 'current_temperature') | round(1) ~ weather_units.temperature) if is_number(state_attr(entity_long, 'current_temperature')) else '' }}" # mui[language].unavailable? + - if: "{{ hvac_mode != 'off' and is_number(state_attr(entity_long, 'temperature')) }}" then: - variables: target_temp: "{{state_attr(entity_long, 'temperature') | round(1)}}" - - service: "{{ command_thermostat_cycle }}" + - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{ target_temp }}" else: - - service: "{{ command_thermostat_cycle }}" + - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "0" - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: target_temp message: " " - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: heating_state message: "{{ heating_state }}" @@ -5949,261 +4775,232 @@ action: # HVAC Button PIC - variables: heating_bt_pic: >- - {%- if hvac_mode == "off" -%} {{ heating_bt_pic_off }} - {%- else -%} {{ heating_bt_pic_on }} + {%- if hvac_mode == 'off' -%} {{ nextion.pics.heating.button.off }} + {%- else -%} {{ nextion.pics.heating.button.on }} {%- endif -%} - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_printf }}" + - *delay-default + - service: "{{ nextion.commands.printf }}" data: cmd: heating_bt_pic.pic={{ heating_bt_pic }} - variables: - hotw_bt_pic: >- - {%- if hotwatercharge | length > 0 and states(hotwatercharge) == 'on' -%} {{ hotw_bt_on }} - {%- elif hotwatercharge | length > 0 and states(hotwatercharge) == 'off' -%} {{ hotw_bt_off }} - {%- else -%} {{ hotw_bt_blank }} - {%- endif -%} - - service: "{{ command_printf }}" + hotwatercharge_state: "{{ states(hotwatercharge) | default('unavailable') if hotwatercharge is string else 'unavailable' }}" + hotwatertemp_state: "{{ states(hotwatertemp) | default('unavailable') if hotwatertemp is string else 'unavailable' }}" + hotw_bt_pic: "{{ nextion.pics.hvac.button[hotwatercharge_state] | default(nextion.pics.hvac.button.blank) if hotwatercharge_state not in ['unavailable', 'unknown', None] else nextion.pics.hvac.button.blank }}" + - *delay-default + - service: "{{ nextion.commands.printf }}" data: cmd: hotw_bt_pic.pic={{ hotw_bt_pic }} - - - if: - - condition: template - value_template: '{{ hotwatertemp is match "sensor." }}' + - if: "{{ hotwatertemp_state not in ['unavailable', 'unknown', None] }}" then: - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: climate.hotwater_temp - message: "{{ (states(hotwatertemp) | round(1) ~ weather.units.temperature) if is_number(states(hotwatertemp)) }}" + message: "{{ (hotwatertemp_state | round(1) ~ weather_units.temperature) if is_number(hotwatertemp_state) else hotwatertemp_state }}" ## PAGE WEATHER (WEATHE01 to WEATHE05) ## - - alias: 'weather pages' - conditions: '{{ trigger.event.data.new_state.state in [page_weather01, page_weather02, page_weather03, page_weather04, page_weather05] }}' + - alias: Weather pages + conditions: "{{ trigger.event.data.new_state.state in nextion.pages.weatherpages }}" sequence: + - *variables-weather - variables: page_name: "{{ trigger.event.data.new_state.state }}" page_index: "{{ (page_name[-2:] | int(0)) - 1 }}" - accuweather_day_name: "{{ 'day_' ~ page_index }}" - accuweather_sensor_prefix: "{{ 'sensor.' ~ weather.name ~ '_' }}" - accuweather_sensor_sufix: "{{ '_' ~ page_index ~ 'd' }}" - temp_min: > - {% if weather.type == 'AccuWeather' %} - {{ states(accuweather_sensor_prefix ~ 'realfeel_temperature_min' ~ accuweather_sensor_sufix) | default('unknown') }} - {% else %} - {{ state_attr(weather.entity,'forecast')[page_index].templow | default('unknown') }} - {% endif %} - temp_max: > - {% if weather.type == 'AccuWeather' %} - {{ states(accuweather_sensor_prefix ~ 'realfeel_temperature_max' ~ accuweather_sensor_sufix) | default('unknown') }} - {% else %} - {{ state_attr(weather.entity,'forecast')[page_index].temperature | default('unknown') }} - {% endif %} - precipitation: "{{ state_attr(weather.entity,'forecast')[page_index].precipitation | default('unknown') }}" - precipitation_probability: "{{ state_attr(weather.entity,'forecast')[page_index].precipitation_probability | default('unknown') }}" - hours_of_sun: > - {% if weather.type == 'AccuWeather' %} - {{ states(accuweather_sensor_prefix ~ 'hours_of_sun' ~ accuweather_sensor_sufix) | default('unknown') }} - {% else %} - {{ state_attr(weather.entity,'forecast')[page_index].hours_of_sun | default('unknown') }} - {% endif %} - uv_index: > - {% if weather.type == 'AccuWeather' %} - {{ states(accuweather_sensor_prefix ~ 'uv_index' ~ accuweather_sensor_sufix) | default('unknown') }} - {% else %} - {{ state_attr(weather.entity,'forecast')[page_index].uv_index | default('unknown') }} - {% endif %} - wind_speed: "{{ state_attr(weather.entity,'forecast')[page_index].wind_speed | default('unknown') }}" - thunderstorm_probability: > - {% if weather.type == 'AccuWeather' %} - {{ states(accuweather_sensor_prefix ~ 'thunderstorm_probability_day' ~ accuweather_sensor_sufix) | default('unknown') }} - {% else %} - {{ state_attr(weather.entity,'forecast')[page_index].thunderstorm_probability | default('unknown') }} - {% endif %} - parameters: - - name: hours_of_sun - visibility: "{{ is_number(hours_of_sun) }}" - value: "{{ (hours_of_sun | round(0) ~ ' ' ~ weather.units.hours_of_sun) if is_number(hours_of_sun) }}" - icon: "{{ nextion.icons.weather.sun }}" - - name: thunderstorm_probability - visibility: "{{ is_number(thunderstorm_probability) }}" - value: "{{ (thunderstorm_probability | round(0) ~ weather.units.thunderstorm_probability) if is_number(thunderstorm_probability) }}" - icon: "{{ nextion.icons.weather.lightning }}" - - name: precipitation - visibility: "{{ is_number(precipitation) or is_number(precipitation_probability) }}" - value: > - {{ (precipitation | round(0) ~ ' ' ~ weather.units.precipitation) if is_number(precipitation) }} - {{ '-' if is_number(precipitation) and is_number(precipitation_probability) }} - {{ (precipitation_probability | round(0) ~ weather.units.precipitation_probability) if is_number(precipitation_probability) }} - icon: "{{ nextion.icons.weather.rain }}" - - name: uv_index - visibility: "{{ is_number(uv_index) }}" - value: > - {{ (state_attr(accuweather_sensor_prefix ~ 'uv_index' ~ accuweather_sensor_sufix, 'level') | default(None) ~ ': ') if weather.type == 'AccuWeather' }} - {{ (uv_index | round(0) ~ weather.units.uv_index) if is_number(uv_index) }} - icon: "{{ nextion.icons.weather.protect }}" - - name: wind_speed - visibility: "{{ is_number(wind_speed) }}" - value: "{{ (wind_speed | round(0) ~ ' ' ~ weather.units.wind_speed) if is_number(wind_speed) }}" - icon: "{{ nextion.icons.weather.wind }}" - ##### SET weather PIC on Home Page #### - - service: "{{ command_printf }}" - data: - cmd: "{{ page_name }}.weather_icon.pic={{ nextion.pics.weather[states(weather_entity) | default('unknown')] if page_name == page_weather01 else nextion.pics.weather[state_attr(weather_entity,'forecast')[page_index].condition | default('unknown')] }}" - - delay: - milliseconds: "{{ delay_value }}" - - - if: "{{ is_number(temp_min) }}" - then: - ##### SET TEMP MIN #### - - service: "{{ command_text_printf }}" - data: - component: "{{ page_name }}.temp_min" ### Temperature MIN ### - message: '{{temp_min | round(0)}}{{ weather.units.temperature }}' - - delay: - milliseconds: "{{ delay_value }}" - ##### Slash ##### - - service: "{{ command_text_printf }}" - data: - component: "{{ page_name }}.slash" - message: '/' - - delay: - milliseconds: "{{ delay_value }}" - - ##### SET TEMP MAX #### - - service: "{{ command_text_printf }}" - data: - component: "{{ page_name }}.temp_max" ### Temperature MAX ### - message: '{{temp_max | round(0)}}{{ weather.units.temperature }}' - - delay: - milliseconds: "{{ delay_value }}" - - ##### Day Name ##### - - service: "{{ command_text_printf }}" + ##### Display relative day ##### + - service: "{{ nextion.commands.text_printf }}" data: component: "{{ page_name }}.day" message: "{{ (dict.values(mui[language].relative_day) | list)[page_index] }}" - - delay: - milliseconds: "{{ delay_value }}" + - *delay-default - ##### Day Date ##### - - service: "{{ command_text_printf }}" + ##### Display date (long) ##### + - variables: + date_format: !input "date_format" + - service: "{{ nextion.commands.text_printf }}" data: component: "{{ page_name }}.date" message: "{{ (dict.values(mui[language].weekdays) | list)[(now() + timedelta(days= (page_index))).weekday()] ~ ', ' ~ as_timestamp(now() + timedelta(days= (page_index))) | timestamp_custom(date_format) }}" - - delay: - milliseconds: "{{ delay_value }}" + - *delay-default - ##### fields 1 to 5 (Parameters) ##### - - repeat: - for_each: "{{ (parameters | selectattr('visibility', 'eq', true) | list)[:5] }}" - sequence: - - service: "{{ command_text_printf }}" - data: - component: "{{ page_name }}.value0{{ repeat.index }}" - message: "{{ repeat.item.value }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ page_name }}.value0{{ repeat.index }}_icon" - message: "{{ repeat.item.icon }}" - - delay: - milliseconds: "{{ delay_value }}" + ##### Display weather data only when available ##### + - variables: + forecast_day: > + {{ state_attr(weather_entity, 'forecast') | default([]) + | selectattr('datetime', 'defined') + | selectattr('datetime', '>=', (today_at('00:00') + timedelta(days= page_index)) | as_timestamp | timestamp_local ) + | selectattr('datetime', '<', (today_at('00:00') + timedelta(days= (page_index+1))) | as_timestamp | timestamp_local ) + | list + }} + - if: "{{ forecast_day | count > 0 }}" + then: # Display forecast + - variables: + accuweather: "{{ weather_type == 'AccuWeather' }}" + accuweather_day_name: "{{ 'day_' ~ page_index }}" + accuweather_sensor_prefix: "{{ 'sensor.' ~ (weather_entity | replace('weather.','')) ~ '_' }}" + accuweather_sensor_sufix: "{{ '_' ~ page_index ~ 'd' }}" + temp_min: > + {{ forecast_day | selectattr('templow', 'defined') | map(attribute='templow') | map('float') | list | min + if forecast_day | selectattr('templow', 'defined') | map(attribute='templow') | map('float') | list | count > 0 + else forecast_day | selectattr('temperature', 'defined') | map(attribute='temperature') | map('float') | list | min | default('unknown') + }} + temp_max: "{{ forecast_day | selectattr('temperature', 'defined') | map(attribute='temperature') | map('float') | list | max | default('unknown') }}" + condition: "{{ forecast_day | selectattr('condition', 'defined') | map(attribute='condition') | list | first | default('unknown') }}" + precipitation: "{{ forecast_day | selectattr('precipitation', 'defined') | map(attribute='precipitation') | map('float') | list | sum | default('unknown') }}" + precipitation_probability: "{{ forecast_day | selectattr('precipitation_probability', 'defined') | map(attribute='precipitation_probability') | map('float') | list | sum | default('unknown') }}" + hours_of_sun: "{{ states(accuweather_sensor_prefix ~ 'hours_of_sun' ~ accuweather_sensor_sufix) | default('unknown') if accuweather else forecast_day | selectattr('hours_of_sun', 'defined') | map(attribute='hours_of_sun') | map('float') | list | sum | default('unknown') }}" + uv_index: "{{ states(accuweather_sensor_prefix ~ 'uv_index' ~ accuweather_sensor_sufix) | default('unknown') if accuweather else forecast_day | selectattr('uv_index', 'defined') | map(attribute='uv_index') | map('float') | list | max | default('unknown') }}" + wind_speed: "{{ forecast_day | selectattr('wind_speed', 'defined') | map(attribute='wind_speed') | map('float') | list | max | default('unknown') }}" + thunderstorm_probability: "{{ states(accuweather_sensor_prefix ~ 'thunderstorm_probability_day' ~ accuweather_sensor_sufix) | default('unknown') if accuweather else forecast_day | selectattr('thunderstorm_probability', 'defined') | map(attribute='thunderstorm_probability') | map('float') | list | max | default('unknown') }}" + parameters: + - name: hours_of_sun + visibility: "{{ is_number(hours_of_sun) }}" + value: "{{ (hours_of_sun | round(0) ~ ' ' ~ weather_units.hours_of_sun) if is_number(hours_of_sun) }}" + icon: "{{ nextion.icons.weather.sun }}" + - name: thunderstorm_probability + visibility: "{{ is_number(thunderstorm_probability) }}" + value: "{{ (thunderstorm_probability | round(0) ~ weather_units.thunderstorm_probability) if is_number(thunderstorm_probability) }}" + icon: "{{ nextion.icons.weather.lightning }}" + - name: precipitation + visibility: "{{ is_number(precipitation) or is_number(precipitation_probability) }}" + value: > + {{ (precipitation | round(0) ~ ' ' ~ weather_units.precipitation) if is_number(precipitation) }} + {{ '-' if is_number(precipitation) and is_number(precipitation_probability) }} + {{ (precipitation_probability | round(0) ~ weather_units.precipitation_probability) if is_number(precipitation_probability) }} + icon: "{{ nextion.icons.weather.rain }}" + - name: uv_index + visibility: "{{ is_number(uv_index) }}" + value: > + {{ (state_attr(accuweather_sensor_prefix ~ 'uv_index' ~ accuweather_sensor_sufix, 'level') | default(None) ~ ': ') if weather_type == 'AccuWeather' }} + {{ (uv_index | round(0) ~ weather_units.uv_index) if is_number(uv_index) }} + icon: "{{ nextion.icons.weather.protect }}" + - name: wind_speed + visibility: "{{ is_number(wind_speed) }}" + value: "{{ (wind_speed | round(0) ~ ' ' ~ weather_units.wind_speed) if is_number(wind_speed) }}" + icon: "{{ nextion.icons.weather.wind }}" + ##### Display weather PIC when available + - if: "{{ condition not in ['unknown', None] }}" + then: + - service: "{{ nextion.commands.printf }}" + data: + cmd: "{{ page_name }}.weather_icon.pic={{ nextion.pics.weather[states(weather_entity) | default('unavailable') if weather_entity is string else 'unavailable'] | default(None) if condition == 'unknown' and page_name == nextion.pages.weatherpages[0] else nextion.pics.weather[condition] | default(None) }}" + - *delay-default + ##### Display temperature (min) when available + - if: "{{ is_number(temp_min) }}" + then: + ##### SET TEMP MIN #### + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ page_name }}.temp_min" ### Temperature MIN ### + message: "{{temp_min | round(0)}}{{ weather_units.temperature }}" + - *delay-default + ##### Slash ##### + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ page_name }}.slash" + message: '/' + - *delay-default + ##### Display temperature (max)) when available + - if: "{{ is_number(temp_max) }}" + then: + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ page_name }}.temp_max" ### Temperature MAX ### + message: "{{ (temp_max | round(0) ~ weather_units.temperature) if is_number(temp_max) else '?' }}" + - *delay-default + + ##### fields 1 to 5 (Parameters) ##### + - repeat: + for_each: "{{ (parameters | selectattr('visibility', 'eq', true) | list)[:5] }}" + sequence: + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ page_name }}.value0{{ repeat.index }}" + message: "{{ repeat.item.value }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ page_name }}.value0{{ repeat.index }}_icon" + message: "{{ repeat.item.icon }}" + - *delay-default + else: # Display "Unavailable" + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ page_name }}.value01" + message: "{{ mui[language].unavailable }}" + - *delay-default + ## PAGE NOTIFICATION ## - - conditions: '{{ trigger.event.data.new_state.state == page_notification }}' - alias: 'notification page' + - alias: Notification page + conditions: "{{ trigger.event.data.new_state.state == nextion.pages.notification }}" sequence: - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: notification.notifi_text01 - message: "{{ states(notification_text) }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ states(notification_text) | default(mui[language].unavailable) if notification_text is string else mui[language].unavailable }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: notification.notifi_label - message: "{{ states(notification_label) }}" + message: "{{ states(notification_label) | default(mui[language].unavailable) if notification_label is string else mui[language].unavailable }}" ## PAGE QR Code ## - - conditions: '{{ trigger.event.data.new_state.state == page_qrcode }}' - alias: 'qrcode page' + - alias: QRCode page + conditions: "{{ trigger.event.data.new_state.state == nextion.pages.qrcode }}" sequence: - - if: - - condition: template - value_template: '{{ qrcode_label |length > 0 }}' + - variables: + qrcode_label: !input "qrcode_label" + qrcode_value: !input "qrcode_value" + - if: "{{ qrcode_label | length > 0 }}" then: - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: "qrcode_label" message: "{{ qrcode_label }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: "qrcode_value" message: "{{ qrcode_value }}" ## PAGE SETTINGS ## - #- conditions: '{{ trigger.event.data.new_state.state == page_settings }}' - # alias: 'settings page' + #- alias: Settings page + # conditions: "{{ trigger.event.data.new_state.state == nextion.pages.settings }}" # sequence: ## PAGE BOOT ## - #- conditions: '{{ trigger.event.data.new_state.state == page_boot }}' - # alias: 'boot page' + #- alias: Boot page + # conditions: "{{ trigger.event.data.new_state.state == nextion.pages.boot }}" # sequence: ## PAGE SCREENSAVER ## - #- conditions: '{{ trigger.event.data.new_state.state == page_screensaver }}' - # alias: 'screensaver page' + #- alias: Screensaver page + # conditions: "{{ trigger.event.data.new_state.state == nextion.pages.screensaver }}" # sequence: ##### BOOT NSPANEL - automation reload ##### - - conditions: + - alias: Automation reloaded + conditions: - condition: trigger id: automation_reloaded sequence: - choose: ## PAGE HOME ## - - conditions: '{{ states(current_page) == page_home }}' + - conditions: "{{ nextion.pages.current == nextion.pages.home }}" sequence: *refresh_page_home + + ## PAGE BUTTON PAGES 01 - 04 ## + - conditions: "{{ nextion.pages.current in nextion.pages.buttonpages }}" + sequence: *refresh_page_buttonpage - ## PAGE BUTTONPAGE01 ## - - conditions: '{{ states(current_page) == page_buttonpage01 }}' - sequence: *refresh_page_buttonpage01 - - ## PAGE BUTTONPAGE02 ## - - conditions: '{{ states(current_page) == page_buttonpage02 }}' - sequence: *refresh_page_buttonpage02 - - ## PAGE BUTTONPAGE03 ## - - conditions: '{{ states(current_page) == page_buttonpage03 }}' - sequence: *refresh_page_buttonpage03 - - ## PAGE BUTTONPAGE04 ## - - conditions: '{{ states(current_page) == page_buttonpage04 }}' - sequence: *refresh_page_buttonpage04 - - ## ENTITY PAGE 01 ## - - conditions: '{{ states(current_page) == page_entitypage01 }}' - sequence: *refresh_page_entitypage01 - - ## ENTITY PAGE 02 ## - - conditions: '{{ states(current_page) == page_entitypage02 }}' - sequence: *refresh_page_entitypage02 - - ## ENTITY PAGE 03 ## - - conditions: '{{ states(current_page) == page_entitypage03 }}' - sequence: *refresh_page_entitypage03 - - ## ENTITY PAGE 04 ## - - conditions: '{{ states(current_page) == page_entitypage04 }}' - sequence: *refresh_page_entitypage04 + ## ENTITY PAGES ## + - conditions: "{{ nextion.pages.current in nextion.pages.entitypages }}" + sequence: *refresh-entity_pages ##### UPDATE BUTTONS AND PAGES - button page / lightsettings page / coversettings page ##### - - conditions: + - alias: "Update buttons & pages" + conditions: - condition: trigger id: - current_state_entity01 @@ -6238,964 +5035,269 @@ action: - current_state_entity30 - current_state_entity31 - current_state_entity32 - - condition: template - value_template: "{{ states(current_page) == page_buttonpage01 or states(current_page) == page_buttonpage02 or states(current_page) == page_buttonpage03 or states(current_page) == page_buttonpage04 and trigger.to_state.state != 'unavailable' }}" + - "{{ nextion.pages.current in nextion.pages.buttonpages and trigger.to_state.state not in ['unavailable', 'unknown'] }}" sequence: - ##### SET Buttons #### - - alias: "Set variable(s) for entity change" - variables: - buttonpage: '{{ states(current_page) }}' - component_to_update: >- - {%- if trigger.entity_id == entity01 and buttonpage == 'buttonpage01' -%} buttonpage01.button01 - {%- elif trigger.entity_id == entity02 and buttonpage == 'buttonpage01' -%} buttonpage01.button02 - {%- elif trigger.entity_id == entity03 and buttonpage == 'buttonpage01' -%} buttonpage01.button03 - {%- elif trigger.entity_id == entity04 and buttonpage == 'buttonpage01' -%} buttonpage01.button04 - {%- elif trigger.entity_id == entity05 and buttonpage == 'buttonpage01' -%} buttonpage01.button05 - {%- elif trigger.entity_id == entity06 and buttonpage == 'buttonpage01' -%} buttonpage01.button06 - {%- elif trigger.entity_id == entity07 and buttonpage == 'buttonpage01' -%} buttonpage01.button07 - {%- elif trigger.entity_id == entity08 and buttonpage == 'buttonpage01' -%} buttonpage01.button08 - {%- elif trigger.entity_id == entity09 and buttonpage == 'buttonpage02' -%} buttonpage02.button01 - {%- elif trigger.entity_id == entity10 and buttonpage == 'buttonpage02' -%} buttonpage02.button02 - {%- elif trigger.entity_id == entity11 and buttonpage == 'buttonpage02' -%} buttonpage02.button03 - {%- elif trigger.entity_id == entity12 and buttonpage == 'buttonpage02' -%} buttonpage02.button04 - {%- elif trigger.entity_id == entity13 and buttonpage == 'buttonpage02' -%} buttonpage02.button05 - {%- elif trigger.entity_id == entity14 and buttonpage == 'buttonpage02' -%} buttonpage02.button06 - {%- elif trigger.entity_id == entity15 and buttonpage == 'buttonpage02' -%} buttonpage02.button07 - {%- elif trigger.entity_id == entity16 and buttonpage == 'buttonpage02' -%} buttonpage02.button08 - {%- elif trigger.entity_id == entity17 and buttonpage == 'buttonpage03' -%} buttonpage03.button01 - {%- elif trigger.entity_id == entity18 and buttonpage == 'buttonpage03' -%} buttonpage03.button02 - {%- elif trigger.entity_id == entity19 and buttonpage == 'buttonpage03' -%} buttonpage03.button03 - {%- elif trigger.entity_id == entity20 and buttonpage == 'buttonpage03' -%} buttonpage03.button04 - {%- elif trigger.entity_id == entity21 and buttonpage == 'buttonpage03' -%} buttonpage03.button05 - {%- elif trigger.entity_id == entity22 and buttonpage == 'buttonpage03' -%} buttonpage03.button06 - {%- elif trigger.entity_id == entity23 and buttonpage == 'buttonpage03' -%} buttonpage03.button07 - {%- elif trigger.entity_id == entity24 and buttonpage == 'buttonpage03' -%} buttonpage03.button08 - {%- elif trigger.entity_id == entity25 and buttonpage == 'buttonpage04' -%} buttonpage04.button01 - {%- elif trigger.entity_id == entity26 and buttonpage == 'buttonpage04' -%} buttonpage04.button02 - {%- elif trigger.entity_id == entity27 and buttonpage == 'buttonpage04' -%} buttonpage04.button03 - {%- elif trigger.entity_id == entity28 and buttonpage == 'buttonpage04' -%} buttonpage04.button04 - {%- elif trigger.entity_id == entity29 and buttonpage == 'buttonpage04' -%} buttonpage04.button05 - {%- elif trigger.entity_id == entity30 and buttonpage == 'buttonpage04' -%} buttonpage04.button06 - {%- elif trigger.entity_id == entity31 and buttonpage == 'buttonpage04' -%} buttonpage04.button07 - {%- elif trigger.entity_id == entity32 and buttonpage == 'buttonpage04' -%} buttonpage04.button08 - {%- endif -%} - # Button PIC - btn_pic: >- - {%- if trigger.to_state.entity_id is match "light." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "light." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "switch." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "switch." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "input_boolean." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "input_boolean." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "cover." and trigger.to_state.state == 'open' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "cover." and trigger.to_state.state == 'closed' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "automation." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "automation." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "button." -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "input_button." -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "scene." -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "script." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "script." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state != 'home' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "binary_sensor." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "binary_sensor." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "fan." and trigger.to_state.state == 'on' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "fan." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off' -%} {{ button_on }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state == 'off' -%} {{ button_off }} - {%- endif -%} - # TEXT and BRIGHTNESS and ICON Background - btn_bg: >- - {%- if trigger.to_state.entity_id is match "button." or trigger.to_state.entity_id is match "input_button." or trigger.to_state.entity_id is match "scene." -%} {{ color_01 }} - {%- elif trigger.to_state.state == 'on' or trigger.to_state.state == 'open' -%} {{ color_01 }} - {%- elif trigger.to_state.state == 'off' or trigger.to_state.state == 'closed' -%} {{ color_02 }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home' -%} {{ color_01 }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state != 'home' -%} {{ color_02 }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off' -%} {{ color_01 }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state == 'off' -%} {{ color_02 }} - {%- endif -%} - # ICON Font Color - btn_icon_font: >- - {%- if trigger.entity_id == entity01 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity01_icon_color }} - {%- elif trigger.entity_id == entity02 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity02_icon_color }} - {%- elif trigger.entity_id == entity03 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity03_icon_color }} - {%- elif trigger.entity_id == entity04 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity04_icon_color }} - {%- elif trigger.entity_id == entity05 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity05_icon_color }} - {%- elif trigger.entity_id == entity06 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity06_icon_color }} - {%- elif trigger.entity_id == entity07 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity07_icon_color }} - {%- elif trigger.entity_id == entity08 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity08_icon_color }} - {%- elif trigger.entity_id == entity09 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity09_icon_color }} - {%- elif trigger.entity_id == entity10 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity10_icon_color }} - {%- elif trigger.entity_id == entity11 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity11_icon_color }} - {%- elif trigger.entity_id == entity12 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity12_icon_color }} - {%- elif trigger.entity_id == entity13 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity13_icon_color }} - {%- elif trigger.entity_id == entity14 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity14_icon_color }} - {%- elif trigger.entity_id == entity15 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity15_icon_color }} - {%- elif trigger.entity_id == entity16 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity16_icon_color }} - {%- elif trigger.entity_id == entity17 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity17_icon_color }} - {%- elif trigger.entity_id == entity18 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity18_icon_color }} - {%- elif trigger.entity_id == entity19 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity19_icon_color }} - {%- elif trigger.entity_id == entity20 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity20_icon_color }} - {%- elif trigger.entity_id == entity21 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity21_icon_color }} - {%- elif trigger.entity_id == entity22 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity22_icon_color }} - {%- elif trigger.entity_id == entity23 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity23_icon_color }} - {%- elif trigger.entity_id == entity24 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity24_icon_color }} - {%- elif trigger.entity_id == entity25 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity25_icon_color }} - {%- elif trigger.entity_id == entity26 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity26_icon_color }} - {%- elif trigger.entity_id == entity27 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity27_icon_color }} - {%- elif trigger.entity_id == entity28 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity28_icon_color }} - {%- elif trigger.entity_id == entity29 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity29_icon_color }} - {%- elif trigger.entity_id == entity30 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity30_icon_color }} - {%- elif trigger.entity_id == entity31 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity31_icon_color }} - {%- elif trigger.entity_id == entity32 and ((trigger.to_state.state == 'on' or trigger.to_state.state == 'open') or (trigger.to_state.entity_id is match "button.") or (trigger.to_state.entity_id is match "input_button.") or (trigger.to_state.entity_id is match "scene.") or (trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home') or (trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off') ) -%} {{ entity32_icon_color }} - {%- elif trigger.to_state.state == 'off' or trigger.to_state.state == 'closed' -%} {{ color_03 }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state != 'home' -%} {{ color_03 }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state == 'off' -%} {{ color_03 }} - {%- endif -%} - - # LABEL Font Color - btn_txt_font: >- - {%- if trigger.to_state.entity_id is match "button." or trigger.to_state.entity_id is match "input_button." or trigger.to_state.entity_id is match "scene." -%} {{ color_02 }} - {%- elif trigger.to_state.state == 'on' or trigger.to_state.state == 'open' -%} {{ color_02 }} - {%- elif trigger.to_state.state == 'off' or trigger.to_state.state == 'closed' -%} {{ color_01 }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state == 'home' -%} {{ color_02 }} - {%- elif trigger.to_state.entity_id is match "person." and trigger.to_state.state != 'home' -%} {{ color_01 }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off' -%} {{ color_02 }} - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state == 'off' -%} {{ color_01 }} - {%- endif -%} - # BRIGHTNESS Font Color - btn_bri_font: "{{ color_02 }}" - # BRIGHTNESS Value - btn_bri_txt: >- - {%- if trigger.to_state.entity_id is match "light." and trigger.to_state.state == 'on' and trigger.to_state.attributes.brightness is defined -%} {{ (trigger.to_state.attributes.brightness | int * 100 /255) | round(0) }}% - {%- elif trigger.to_state.entity_id is match "cover." and trigger.to_state.state == 'open' and trigger.to_state.attributes.current_position is defined -%} {{ (trigger.to_state.attributes.current_position | int) | round(0) }}% - {%- elif trigger.to_state.entity_id is match "climate." and trigger.to_state.state != 'off' and trigger.to_state.attributes.current_temperature is defined -%} {{ (trigger.to_state.attributes.current_temperature | int) | round(0) }}{{ weather.units.temperature }} - {%- else -%} 0 - {%- endif -%} - ##### SET Button PIC - - service: "{{ command_printf }}" - data: - cmd: "{{ component_to_update }}pic.pic={{ btn_pic }}" - ##### SET ICON Background ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_background_color }}" - data: - component: "{{ component_to_update }}icon" - message: "{{ btn_bg }}" - ##### SET LABEL Background ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_background_color }}" - data: - component: "{{ component_to_update }}text" - message: "{{ btn_bg }}" - ##### SET BRIGHTNESS Background Color ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_background_color }}" - data: - component: "{{ component_to_update }}bri" - message: "{{ btn_bg }}" - ##### SET ICON Font Color ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: "{{ component_to_update }}icon" - message: "{{ btn_icon_font }}" - ##### SET LABEL Font Color ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: "{{ component_to_update }}text" - message: "{{ btn_txt_font }}" - ##### SET BRIGHTNESS Font Color ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: "{{ component_to_update }}bri" - message: "{{ btn_bri_font }}" - - ##### "BRIGHTNESS" Value ##### - - if: - - condition: template - value_template: "{{ btn_bri_txt == 0 }}" - then: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ component_to_update }}bri" - message: " " - else: - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: "{{ component_to_update }}bri" - message: "{{ btn_bri_txt }}" - + - *variables-page_buttons + - variables: + buttonpage: "{{ nextion.pages.current }}" + - repeat: + for_each: "{{ button_pages_buttons | selectattr('component', 'defined') | selectattr('component', 'match', buttonpage) | selectattr('entity', 'defined') | selectattr('entity', 'eq', trigger.entity_id) | list }}" + sequence: *display-button_page_button ##### release button/scene (stateless) ##### - - if: - - condition: template - value_template: '{{ trigger.to_state.entity_id is match "button." or trigger.to_state.entity_id is match "input_button." or trigger.to_state.entity_id is match "scene." }}' + - if: "{{ trigger.to_state.entity_id is match 'button.' or trigger.to_state.entity_id is match 'input_button.' or trigger.to_state.entity_id is match 'scene.' }}" then: - delay: milliseconds: "1000" - - variables: - btn_pic: >- - {%- if trigger.to_state.entity_id is match "button." -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "input_button." -%} {{ button_off }} - {%- elif trigger.to_state.entity_id is match "scene." -%} {{ button_off }} - {%- endif -%} - btn_bg: '{{ color_02 }}' - btn_txt_font: '{{ color_01 }}' - - ##### Button PIC ##### - - service: "{{ command_printf }}" - data: - cmd: "{{ component_to_update }}pic.pic={{ btn_pic }}" - - ##### LABEL Background ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_background_color }}" - data: - component: "{{ component_to_update }}text" - message: "{{ btn_bg }}" - - ##### TEXT Font Color ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: "{{ component_to_update }}text" - message: "{{ btn_txt_font }}" - - ##### BRIGHTNESS Background Color ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_background_color }}" - data: - component: "{{ component_to_update }}bri" - message: "{{ btn_bg }}" - - # ##### UPDATE LIGHTSETTING / COVERSETTING PAGE - # - choose: - # ##### LIGHTSETTINGS PAGE - LIGHT Entity ##### - # - conditions: - # - condition: template - # # value_template: '{{ entity_long is match "light." }}' TODO - # value_template: '{{ states(current_page) == page_lightsettings }}' - # sequence: - # ##### LIGHT ICON - ON / OFF ##### - # - variables: - # lightsettings_icon_font: >- - # {%- if entity_long_icon |length > 0 -%} {{ entity_long_icon }} - # {%- else -%} {{ button_icon_light }} - # {%- endif -%} - # lightsettings_icon_font_color: >- - # {%- if states(entity_long) == 'on' -%} {{ entity_long_icon_color }} - # {%- else -%} {{ color_03 }} - # {%- endif -%} - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" - # data: - # component: lightsettings.icon_state - # message: "{{ lightsettings_icon_font }}" - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_font_color }}" - # data: - # component: lightsettings.icon_state - # message: "{{ lightsettings_icon_font_color }}" - - # # ##### LIGHT ON / OFF ##### - # # - choose: - # # ##### LIGHT Settings ON ##### - # # - conditions: - # # - condition: template - # # value_template: '{{ states(entity_long) == "on" }}' - # # sequence: - # # ##### LIGHT Brightness Slider HA Sync - YES ##### - # # - if: - # # - condition: template - # # value_template: '{{ sync_slider_ha == "select_yes" }}' - # # then: - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_value }}" - # # data: - # # component: lightsettings.lightslider - # # message: '{{ (state_attr(entity_long, "brightness") | int ) |round(0) }}' - - # # ##### LIGHT Temp Slider HA Sync - YES ##### - # # - if: - # # - condition: template - # # value_template: '{{ sync_slider_ha == "select_yes" }}' - # # then: - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_value }}" - # # data: - # # component: lightsettings.tempslider - # # message: '{{ (state_attr(entity_long, "color_temp") | int ) |round(0) }}' - - # # ##### LIGHT Brightness Value HA Sync - YES ##### - # # - if: - # # - condition: template - # # value_template: '{{ sync_value_ha == "select_yes" }}' - # # then: - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_text_printf }}" - # # data: - # # component: lightsettings.light_value - # # message: '{{ (state_attr(entity_long, "brightness") | int * 100 / 255) |round(0) }}%' - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_text_printf }}" - # # data: - # # component: lightsettings.light_value_2 - # # message: '{{ (state_attr(entity_long, "brightness") | int * 100 / 255) |round(0) }}%' - - # # ##### LIGHT Temp Value HA Sync - YES ##### - # # - if: - # # - condition: template - # # value_template: '{{ sync_value_ha == "select_yes" }}' - # # then: - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_text_printf }}" - # # data: - # # component: lightsettings.temp_value - # # message: '{{ (state_attr(entity_long, "color_temp") | int ) |round(0) }}' - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_text_printf }}" - # # data: - # # component: lightsettings.temp_value_2 - # # message: '{{ (state_attr(entity_long, "color_temp") | int ) |round(0) }}' - - # # ##### LIGHT SETTINGS - OFF ##### - # # - conditions: - # # - condition: template - # # value_template: '{{ states(entity_long) == "off" }}' - # # sequence: - # # ##### LIGHT Brightness Slider HA Sync - YES ##### - # # - if: - # # - condition: template - # # value_template: '{{ sync_slider_ha == "select_yes" }}' - # # then: - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_value }}" - # # data: - # # component: lightsettings.lightslider - # # message: '0' - - # # ##### LIGHT Brightness Value HA Sync - YES ##### - # # - if: - # # - condition: template - # # value_template: '{{ sync_value_ha == "select_yes" }}' - # # then: - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_text_printf }}" - # # data: - # # component: lightsettings.light_value - # # message: '0 %' - # # - delay: - # # milliseconds: "{{ delay_value }}" - # # - service: "{{ command_text_printf }}" - # # data: - # # component: lightsettings.light_value_2 - # # message: '0 %' - - # ##### COVERSETTINGS PAGE - COVER Entity ##### - # - conditions: - # - condition: template - # # value_template: '{{ entity_long is match "cover." }}' TODO - # value_template: '{{ states(current_page) == page_coversettings }}' - # sequence: - # ##### COVER ICON - ON / OFF ##### - # - variables: - # coversettings_icon_font: >- - # {%- if entity_long_icon |length > 0 -%} {{ entity_long_icon }} - # {%- else -%} {{ button_icon_cover }} - # {%- endif -%} - # coversettings_icon_font_color: >- - # {%- if states(entity_long) == 'open' -%} {{ entity_long_icon_color }} - # {%- else -%} {{ color_03 }} - # {%- endif -%} - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" - # data: - # component: coversettings.icon_state - # message: "{{ coversettings_icon_font }}" - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_font_color }}" - # data: - # component: coversettings.icon_state - # message: "{{ coversettings_icon_font_color }}" - - # ##### COVER OPEN ##### - # - choose: - # - conditions: - # - condition: template - # value_template: '{{ states(entity_long) == "open" }}' - # sequence: - # ##### Cover Slider HA Sync - YES ##### - # - if: - # - condition: template - # value_template: '{{ sync_slider_ha == "select_yes" }}' - # then: - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_value }}" - # data: - # component: coversettings.coverslider - # message: '{{ (state_attr(entity_long, "current_position") | int ) |round(0) }}' - - # ##### Cover Value HA Sync - YES ##### - # - if: - # - condition: template - # value_template: '{{ sync_value_ha == "select_yes" }}' - # then: - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" - # data: - # component: coversettings.cover_value - # message: '{{ (state_attr(entity_long, "current_position") | int ) |round(0) }} %' - - # ##### Cover - Closed ##### - # - conditions: - # - condition: template - # value_template: '{{ states(entity_long) == "closed" }}' - # sequence: - # ##### Cover Slider HA Sync - YES ##### - # - if: - # - condition: template - # value_template: '{{ sync_slider_ha == "select_yes" }}' - # then: - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_value }}" - # data: - # component: coversettings.coverslider - # message: '0' - - # ##### Cover Value HA Sync - YES ##### - # - if: - # - condition: template - # value_template: '{{ sync_value_ha == "select_yes" }}' - # then: - # - delay: - # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" - # data: - # component: coversettings.cover_value - # message: '0 %' ##### SHORT PRESS BUTTON PAGE - toggle enities ##### - - conditions: + - alias: Button page - Short press + conditions: - condition: trigger id: short_press - - condition: template - value_template: '{{ states(current_page) == page_buttonpage01 or states(current_page) == page_buttonpage02 or states(current_page) == page_buttonpage03 or states(current_page) == page_buttonpage04}}' + - "{{ nextion.pages.current in nextion.pages.buttonpages }}" sequence: + - *variables-page_buttons - variables: ##### Entity - Page Button - Toggle Entity ##### - entity_short: >- - {%- if states(last_click) == "releasebuttonpage01button01" -%} {{ entity01 }} - {%- elif states(last_click) == "releasebuttonpage01button02" -%} {{ entity02 }} - {%- elif states(last_click) == "releasebuttonpage01button03" -%} {{ entity03 }} - {%- elif states(last_click) == "releasebuttonpage01button04" -%} {{ entity04 }} - {%- elif states(last_click) == "releasebuttonpage01button05" -%} {{ entity05 }} - {%- elif states(last_click) == "releasebuttonpage01button06" -%} {{ entity06 }} - {%- elif states(last_click) == "releasebuttonpage01button07" -%} {{ entity07 }} - {%- elif states(last_click) == "releasebuttonpage01button08" -%} {{ entity08 }} - {%- elif states(last_click) == "releasebuttonpage02button01" -%} {{ entity09 }} - {%- elif states(last_click) == "releasebuttonpage02button02" -%} {{ entity10 }} - {%- elif states(last_click) == "releasebuttonpage02button03" -%} {{ entity11 }} - {%- elif states(last_click) == "releasebuttonpage02button04" -%} {{ entity12 }} - {%- elif states(last_click) == "releasebuttonpage02button05" -%} {{ entity13 }} - {%- elif states(last_click) == "releasebuttonpage02button06" -%} {{ entity14 }} - {%- elif states(last_click) == "releasebuttonpage02button07" -%} {{ entity15 }} - {%- elif states(last_click) == "releasebuttonpage02button08" -%} {{ entity16 }} - {%- elif states(last_click) == "releasebuttonpage03button01" -%} {{ entity17 }} - {%- elif states(last_click) == "releasebuttonpage03button02" -%} {{ entity18 }} - {%- elif states(last_click) == "releasebuttonpage03button03" -%} {{ entity19 }} - {%- elif states(last_click) == "releasebuttonpage03button04" -%} {{ entity20 }} - {%- elif states(last_click) == "releasebuttonpage03button05" -%} {{ entity21 }} - {%- elif states(last_click) == "releasebuttonpage03button06" -%} {{ entity22 }} - {%- elif states(last_click) == "releasebuttonpage03button07" -%} {{ entity23 }} - {%- elif states(last_click) == "releasebuttonpage03button08" -%} {{ entity24 }} - {%- elif states(last_click) == "releasebuttonpage04button01" -%} {{ entity25 }} - {%- elif states(last_click) == "releasebuttonpage04button02" -%} {{ entity26 }} - {%- elif states(last_click) == "releasebuttonpage04button03" -%} {{ entity27 }} - {%- elif states(last_click) == "releasebuttonpage04button04" -%} {{ entity28 }} - {%- elif states(last_click) == "releasebuttonpage04button05" -%} {{ entity29 }} - {%- elif states(last_click) == "releasebuttonpage04button06" -%} {{ entity30 }} - {%- elif states(last_click) == "releasebuttonpage04button07" -%} {{ entity31 }} - {%- elif states(last_click) == "releasebuttonpage04button08" -%} {{ entity32 }} - {%- endif -%} - entity_confirm: >- - {%- if states(last_click) == "releasebuttonpage01button01" -%} {{ entity01_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button02" -%} {{ entity02_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button03" -%} {{ entity03_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button04" -%} {{ entity04_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button05" -%} {{ entity05_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button06" -%} {{ entity06_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button07" -%} {{ entity07_confirm }} - {%- elif states(last_click) == "releasebuttonpage01button08" -%} {{ entity08_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button01" -%} {{ entity09_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button02" -%} {{ entity10_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button03" -%} {{ entity11_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button04" -%} {{ entity12_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button05" -%} {{ entity13_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button06" -%} {{ entity14_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button07" -%} {{ entity15_confirm }} - {%- elif states(last_click) == "releasebuttonpage02button08" -%} {{ entity16_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button01" -%} {{ entity17_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button02" -%} {{ entity18_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button03" -%} {{ entity19_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button04" -%} {{ entity20_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button05" -%} {{ entity21_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button06" -%} {{ entity22_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button07" -%} {{ entity23_confirm }} - {%- elif states(last_click) == "releasebuttonpage03button08" -%} {{ entity24_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button01" -%} {{ entity25_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button02" -%} {{ entity26_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button03" -%} {{ entity27_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button04" -%} {{ entity28_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button05" -%} {{ entity29_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button06" -%} {{ entity30_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button07" -%} {{ entity31_confirm }} - {%- elif states(last_click) == "releasebuttonpage04button08" -%} {{ entity32_confirm }} - {%- endif -%} - - condition: template - value_template: '{{ entity_short |length > 0 and entity_short is not match "person." and entity_short is not match "binary_sensor." }}' - - if: - - condition: template - value_template: '{{ entity_short is match "climate." }}' + last_click_state: "{{ states(last_click) | default('unavailable') if last_click is string else 'unavailable' }}" + last_click_coordinates: "{{ last_click_state.replace('releasebuttonpage', '').split('button') if last_click_state not in ['unavailable', 'unknown', None] else [-1, -1] }}" + last_click_entity_index: "{{ (last_click_coordinates[0] | int(-99) -1)*8 + last_click_coordinates[1] | int(-99) - 1 }}" + - condition: "{{ last_click_entity_index > 0 }}" + - variables: + last_click_button: "{{ button_pages_buttons[last_click_entity_index] | default([]) }}" + entity_short: "{{ last_click_button.entity | default('unavailable') if last_click_button and last_click_button.entity is defined }}" + entity_domain: "{{ (entity_short.split('.')[0] | default('unknown')) if entity_short is string and entity_short | length > 0 else 'unknown' }}" + - condition: "{{ entity_domain not in ['unknown', 'person', 'binary_sensor', 'sensor'] }}" + - if: "{{ entity_domain == 'climate' }}" then: - variables: - entity_long: '{{ entity_short }}' - entity_long_name: >- - {%- if states(entity_short) == 'unavailable' -%} {{ entity_short }} - {%- else -%} {{ state_attr(entity_short, "friendly_name")| default('no name') }} - {%- endif -%} - entity_back: '{{ states(current_page) }}' - - service: '{{ command_set_settings_entity }}' + entity_long: "{{ entity_short }}" + entity_short_state: "{{ states(entity_short) | default('unavailable') if entity_short is string else 'unavailable' }}" + entity_long_name: "{{ entity_short if entity_short_state in ['unavailable', 'unknown'] else state_attr(entity_short, 'friendly_name') | default(mui[language].no_name) }}" + entity_back: "{{ nextion.pages.current }}" + - service: "{{ nextion.commands.set_settings_entity }}" data: - entity: '{{ entity_long }},{{ entity_back }},{{ entity_long_name }}' - - condition: template - value_template: '{{ entity_short is not match "climate." }}' - - if: - - condition: template - value_template: "{{ entity_confirm }}" - then: - - variables: - buttonpage: '{{ states(current_page) }}' - btn_entity_name: >- - {%- if state_attr(entity_short, "friendly_name") != None -%} {{ state_attr(entity_short, "friendly_name") }} - {%- elif state_attr(entity_short, "name") != None -%} {{ state_attr(entity_short, "name") }} - {%- else -%} "unknown" - {%- endif -%} - #### turn on switch confirmation_message - - service: switch.turn_on - data: - entity_id: '{{ confirmation_message }}' - - service: "{{ command_printf }}" - data: - cmd: "page {{ page_notification }}" - - service: "{{ command_text_printf }}" - data: - component: notification.notifi_text01 - message: "{{ btn_entity_name }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: notification.notifi_label - message: "{{ mui[language].please_confirm }}" - - wait_template: "{{ is_state(last_click, ['notificationacceptrelease','notificationclearrelease','homepage']) }}" - timeout: - seconds: 10 - continue_on_timeout: true - - choose: - - conditions: "{{ is_state(last_click, 'notificationacceptrelease') }}" - sequence: - - service: "{{ command_printf }}" - data: - cmd: "page {{ buttonpage }}" - - service: switch.turn_off - data: - entity_id: '{{ confirmation_message }}' - - service: >- - {% if entity_short is match 'light.' %} - light.toggle - {% elif entity_short is match 'switch.' %} - switch.toggle - {% elif entity_short is match 'cover.' %} - cover.toggle - {% elif entity_short is match 'input_boolean.' %} - input_boolean.toggle - {% elif entity_short is match 'automation.' %} - automation.toggle - {% elif entity_short is match 'button.' %} - button.press - {% elif entity_short is match 'input_button.' %} - input_button.press - {% elif entity_short is match 'scene.' %} - scene.turn_on - {% elif entity_short is match 'script.' %} - script.turn_on - {% elif entity_short is match 'fan.' %} - fan.toggle - {% endif %} - data: - entity_id: "{{ entity_short }}" - - - conditions: "{{ is_state(last_click, 'notificationclearrelease') }}" - sequence: - - service: "{{ command_printf }}" - data: - cmd: "page {{ buttonpage }}" - - service: switch.turn_off - data: - entity_id: '{{ confirmation_message }}' - - - conditions: "{{ is_state(last_click, 'homepage') }}" - sequence: - - service: switch.turn_off - data: - entity_id: '{{ confirmation_message }}' - - default: - - service: switch.turn_off - data: - entity_id: '{{ confirmation_message }}' - - service: "{{ command_printf }}" - data: - cmd: "page {{ page_home }}" - + entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }}" else: - - service: >- - {% if entity_short is match 'light.' %} - light.toggle - {% elif entity_short is match 'switch.' %} - switch.toggle - {% elif entity_short is match 'cover.' %} - cover.toggle - {% elif entity_short is match 'input_boolean.' %} - input_boolean.toggle - {% elif entity_short is match 'automation.' %} - automation.toggle - {% elif entity_short is match 'button.' %} - button.press - {% elif entity_short is match 'input_button.' %} - input_button.press - {% elif entity_short is match 'scene.' %} - scene.turn_on - {% elif entity_short is match 'script.' %} - script.turn_on - {% elif entity_short is match 'fan.' %} - fan.toggle - {% endif %} - data: - entity_id: "{{ entity_short }}" + - if: "{{ last_click_button.confirm }}" + then: + - variables: + buttonpage: "{{ nextion.pages.current }}" + btn_entity_name: >- + {%- if state_attr(entity_short, 'friendly_name') != None -%} {{ state_attr(entity_short, 'friendly_name') }} + {%- elif state_attr(entity_short, 'name') != None -%} {{ state_attr(entity_short, 'name') }} + {%- else -%} 'unknown' + {%- endif -%} + #### turn on switch confirmation_message + - service: switch.turn_on + data: + entity_id: "{{ confirmation_message }}" + - service: "{{ nextion.commands.printf }}" + data: + cmd: "page {{ nextion.pages.notification }}" + - service: "{{ nextion.commands.text_printf }}" + data: + component: notification.notifi_text01 + message: "{{ btn_entity_name }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: notification.notifi_label + message: "{{ mui[language].please_confirm }}" + - wait_template: "{{ is_state(last_click, ['notificationacceptrelease', 'notificationclearrelease', 'homepage']) }}" + timeout: + seconds: 10 + continue_on_timeout: true + - choose: + - conditions: "{{ is_state(last_click, 'notificationacceptrelease') }}" + sequence: + - service: "{{ nextion.commands.printf }}" + data: + cmd: "page {{ buttonpage }}" + - service: switch.turn_off + data: + entity_id: "{{ confirmation_message }}" + - &service-button_changed + service: >- + {% if entity_domain in ['light', 'switch', 'cover', 'input_boolean', 'automation', 'fan'] %} + {{ entity_domain }}.toggle + {% elif entity_domain in ['button', 'input_button'] %} + {{ entity_domain }}.press + {% elif entity_domain in ['scene', 'script'] %} + {{ entity_domain }}.turn_on + {% else %} + homeassistant.update_entity + {% endif %} + data: + entity_id: "{{ entity_short }}" + continue_on_error: true + - conditions: "{{ is_state(last_click, 'notificationclearrelease') }}" + sequence: + - service: "{{ nextion.commands.printf }}" + data: + cmd: "page {{ buttonpage }}" + - service: switch.turn_off + data: + entity_id: "{{ confirmation_message }}" + - conditions: "{{ is_state(last_click, 'homepage') }}" + sequence: + - service: switch.turn_off + data: + entity_id: "{{ confirmation_message }}" + default: + - service: switch.turn_off + data: + entity_id: "{{ confirmation_message }}" + - service: "{{ nextion.commands.printf }}" + data: + cmd: "page {{ nextion.pages.home }}" + else: + - *service-button_changed ##### LONG PRESS BUTTON PAGE - save entity for settings pages ##### - - conditions: + - alias: Button page - Long press + conditions: - condition: trigger id: long_press - - condition: template - value_template: '{{ states(current_page) == page_buttonpage01 or states(current_page) == page_buttonpage02 or states(current_page) == page_buttonpage03 or states(current_page) == page_buttonpage04}}' + - "{{ nextion.pages.current in nextion.pages.buttonpages }}" sequence: + - *variables-page_buttons - variables: + last_click_state: "{{ trigger.to_state.state }}" + last_click_coordinates: "{{ last_click_state.replace('pressbuttonpage', '').split('button') }}" + last_click_entity_index: "{{ (last_click_coordinates[0] | int(-99) -1)*8 + last_click_coordinates[1] | int(-99) - 1 }}" + last_click_button: "{{ button_pages_buttons[last_click_entity_index] }}" ##### Long Press Entity ##### - entity_long: >- - {%- if trigger.to_state.state == "pressbuttonpage01button01" -%} {{ entity01 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button02" -%} {{ entity02 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button03" -%} {{ entity03 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button04" -%} {{ entity04 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button05" -%} {{ entity05 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button06" -%} {{ entity06 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button07" -%} {{ entity07 }} - {%- elif trigger.to_state.state == "pressbuttonpage01button08" -%} {{ entity08 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button01" -%} {{ entity09 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button02" -%} {{ entity10 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button03" -%} {{ entity11 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button04" -%} {{ entity12 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button05" -%} {{ entity13 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button06" -%} {{ entity14 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button07" -%} {{ entity15 }} - {%- elif trigger.to_state.state == "pressbuttonpage02button08" -%} {{ entity16 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button01" -%} {{ entity17 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button02" -%} {{ entity18 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button03" -%} {{ entity19 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button04" -%} {{ entity20 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button05" -%} {{ entity21 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button06" -%} {{ entity22 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button07" -%} {{ entity23 }} - {%- elif trigger.to_state.state == "pressbuttonpage03button08" -%} {{ entity24 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button01" -%} {{ entity25 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button02" -%} {{ entity26 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button03" -%} {{ entity27 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button04" -%} {{ entity28 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button05" -%} {{ entity29 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button06" -%} {{ entity30 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button07" -%} {{ entity31 }} - {%- elif trigger.to_state.state == "pressbuttonpage04button08" -%} {{ entity32 }} - {%- endif -%} - + entity_long: "{{ last_click_button.entity }}" + entity_domain: "{{ (entity_long.split('.')[0] | default('unknown')) if entity_long | length > 0 else 'unknown' }}" ##### Long Press Entity Name ##### - entity_long_name: >- - {%- if trigger.to_state.state == "pressbuttonpage01button01" -%} {{ entity01_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button02" -%} {{ entity02_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button03" -%} {{ entity03_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button04" -%} {{ entity04_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button05" -%} {{ entity05_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button06" -%} {{ entity06_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button07" -%} {{ entity07_name }} - {%- elif trigger.to_state.state == "pressbuttonpage01button08" -%} {{ entity08_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button01" -%} {{ entity09_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button02" -%} {{ entity10_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button03" -%} {{ entity11_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button04" -%} {{ entity12_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button05" -%} {{ entity13_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button06" -%} {{ entity14_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button07" -%} {{ entity15_name }} - {%- elif trigger.to_state.state == "pressbuttonpage02button08" -%} {{ entity16_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button01" -%} {{ entity17_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button02" -%} {{ entity18_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button03" -%} {{ entity19_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button04" -%} {{ entity20_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button05" -%} {{ entity21_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button06" -%} {{ entity22_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button07" -%} {{ entity23_name }} - {%- elif trigger.to_state.state == "pressbuttonpage03button08" -%} {{ entity24_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button01" -%} {{ entity25_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button02" -%} {{ entity26_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button03" -%} {{ entity27_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button04" -%} {{ entity28_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button05" -%} {{ entity29_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button06" -%} {{ entity30_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button07" -%} {{ entity31_name }} - {%- elif trigger.to_state.state == "pressbuttonpage04button08" -%} {{ entity32_name }} - {%- endif -%} - + entity_long_name: "{{ last_click_button.name }}" ##### Long Press Entity Icon ##### - entity_long_icon: >- - {%- if trigger.to_state.state == "pressbuttonpage01button01" -%} {{ entity01_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button02" -%} {{ entity02_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button03" -%} {{ entity03_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button04" -%} {{ entity04_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button05" -%} {{ entity05_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button06" -%} {{ entity06_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button07" -%} {{ entity07_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage01button08" -%} {{ entity08_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button01" -%} {{ entity09_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button02" -%} {{ entity10_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button03" -%} {{ entity11_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button04" -%} {{ entity12_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button05" -%} {{ entity13_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button06" -%} {{ entity14_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button07" -%} {{ entity15_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage02button08" -%} {{ entity16_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button01" -%} {{ entity17_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button02" -%} {{ entity18_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button03" -%} {{ entity19_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button04" -%} {{ entity20_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button05" -%} {{ entity21_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button06" -%} {{ entity22_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button07" -%} {{ entity23_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage03button08" -%} {{ entity24_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button01" -%} {{ entity25_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button02" -%} {{ entity26_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button03" -%} {{ entity27_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button04" -%} {{ entity28_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button05" -%} {{ entity29_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button06" -%} {{ entity30_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button07" -%} {{ entity31_icon }} - {%- elif trigger.to_state.state == "pressbuttonpage04button08" -%} {{ entity32_icon }} - {%- endif -%} - + entity_long_icon: "{{ last_click_button.icon }}" ##### Long Press Entity Icon Color ##### - entity_long_icon_color: >- - {%- if trigger.to_state.state == "pressbuttonpage01button01" -%} {{ entity01_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button02" -%} {{ entity02_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button03" -%} {{ entity03_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button04" -%} {{ entity04_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button05" -%} {{ entity05_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button06" -%} {{ entity06_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button07" -%} {{ entity07_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage01button08" -%} {{ entity08_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button01" -%} {{ entity09_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button02" -%} {{ entity10_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button03" -%} {{ entity11_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button04" -%} {{ entity12_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button05" -%} {{ entity13_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button06" -%} {{ entity14_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button07" -%} {{ entity15_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage02button08" -%} {{ entity16_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button01" -%} {{ entity17_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button02" -%} {{ entity18_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button03" -%} {{ entity19_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button04" -%} {{ entity20_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button05" -%} {{ entity21_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button06" -%} {{ entity22_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button07" -%} {{ entity23_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage03button08" -%} {{ entity24_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button01" -%} {{ entity25_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button02" -%} {{ entity26_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button03" -%} {{ entity27_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button04" -%} {{ entity28_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button05" -%} {{ entity29_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button06" -%} {{ entity30_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button07" -%} {{ entity31_icon_color }} - {%- elif trigger.to_state.state == "pressbuttonpage04button08" -%} {{ entity32_icon_color }} - {%- endif -%} - - + entity_long_icon_color: "{{ last_click_button.icon_color_rgb if is_number(last_click_button.icon_color_rgb) else ((last_click_button.icon_color_rgb[0] //(2**3)) *(2**11))+((last_click_button.icon_color_rgb[1] //(2**2)) *(2**5))+(last_click_button.icon_color_rgb[2] //(2**3)) }}" ##### Current Page ##### - entity_back: '{{ states(current_page) }}' - - service: '{{ command_set_settings_entity }}' + entity_back: "{{ nextion.pages.current }}" + - service: "{{ nextion.commands.set_settings_entity }}" data: - entity: '{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}' + entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}" ##### LASTCLICK_LIGHTSETTINGS - changes on page lightsettings ##### - - conditions: + - alias: Changes on page lightsettings + conditions: - condition: trigger id: light_settings - - condition: template - value_template: "{{ states(current_page) == page_lightsettings }}" + - "{{ nextion.pages.current == nextion.pages.light }}" sequence: - choose: ##### Page Lightsettings - Brightness Slider MOVE ##### - conditions: - - condition: template - #value_template: '{{ trigger.event.data.new_state.state is match "brightness\d+" and trigger.event.data.new_state.state == states(last_click_lightsettings) }}' - value_template: '{{ trigger.event.data.new_state.state is match "brightness\d+" }}' + #- '{{ trigger.event.data.new_state.state is match "brightness\d+" and trigger.event.data.new_state.state == states(last_click_lightsettings) }}' + - '{{ trigger.event.data.new_state.state is match "brightness\d+" }}' sequence: - service: light.turn_on data: entity_id: "{{ entity_long }}" - brightness: '{{ (trigger.event.data.new_state.state |replace("brightness","") | int / 100 * 255) |round(0) }}' + brightness: "{{ (trigger.event.data.new_state.state | replace('brightness','') | int / 100 * 255) | round(0) }}" #### wird nicht mehr benötigt, da es im nextion editor nun direkt gemacht wird # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: lightsettings.light_value - # message: '{{ (trigger.event.data.new_state.state |replace("brightness","") | int * 100 /255) |round(0) }}%' + # message: "{{ (trigger.event.data.new_state.state | replace('brightness','') | int * 100 /255) | round(0) }}%' # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: lightsettings.light_value_2 - # message: '{{ (trigger.event.data.new_state.state |replace("brightness","") | int * 100 /255) |round(0) }}%' + # message: "{{ (trigger.event.data.new_state.state | replace('brightness','') | int * 100 /255) | round(0) }}%' - # value_template: '{{ states(last_click_lightsettings) is match "brightness\d+" }}' + # value_template: "{{ states(last_click_lightsettings) is match 'brightness\d+' }}" # sequence: # - service: light.turn_on # data: - # entity_id: '{{ entity_long }}' - # brightness: '{{ states(last_click_lightsettings) |replace("brightness","") | int }}' - # - service: "{{ command_text_printf }}" + # entity_id: "{{ entity_long }}" + # brightness: "{{ states(last_click_lightsettings) | replace('brightness','') | int }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: lightsettings.light_value - # message: '{{ (states(last_click_lightsettings) |replace("brightness","") | int * 100 /255) |round(0) }}' + # message: "{{ (states(last_click_lightsettings) | replace('brightness','') | int * 100 /255) | round(0) }}" ##### Page Lightsettings - color_Temp Slider MOVE ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state is match "colortemp\d+" and trigger.event.data.new_state.state == states(last_click_lightsettings) }}' + - '{{ trigger.event.data.new_state.state is match "colortemp\d+" and trigger.event.data.new_state.state == (states(last_click_lightsettings) | default("unavailable") if last_click_lightsettings is string else "unavailable") }}' sequence: - service: light.turn_on data: entity_id: "{{ entity_long }}" - color_temp: '{{ trigger.event.data.new_state.state |replace("colortemp","") | int }}' + color_temp: "{{ trigger.event.data.new_state.state | replace('colortemp','') | int }}" #### wird nicht mehr benötigt, da es im nextion editor nun direkt gemacht wird # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: lightsettings.temp_value - # message: '{{ trigger.event.data.new_state.state |replace("colortemp","") | int }}' + # message: "{{ trigger.event.data.new_state.state | replace('colortemp','') | int }}" # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: lightsettings.temp_value_2 - # message: '{{ trigger.event.data.new_state.state |replace("colortemp","") | int }}' + # message: "{{ trigger.event.data.new_state.state | replace('colortemp','') | int }}" ##### Page Lightsettings - Color RGB Slider MOVE ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state is match "\d+,\d+,\d+" }}' + - '{{ trigger.event.data.new_state.state is match "\d+,\d+,\d+" }}' sequence: - service: light.turn_on data: entity_id: "{{ entity_long }}" - rgb_color: '{{ trigger.event.data.new_state.state.split(",") }}' + rgb_color: "{{ trigger.event.data.new_state.state.split(',') }}" ##### Page Lightsettings - Close Lightsetting Page ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state == "releaselightsettingsclose" }}' + - "{{ trigger.event.data.new_state.state == 'releaselightsettingsclose' }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ entity_back }}" ##### LASTCLICK_COVERSETTINGS - changes on page coversettings ##### - - conditions: + - alias: Changes on page coversettings + conditions: - condition: trigger id: cover_settings - - condition: template - value_template: "{{ states(current_page) == page_coversettings }}" + - "{{ nextion.pages.current == nextion.pages.cover }}" sequence: - choose: ##### Page Coversettings - Cover Slider MOVE ##### - conditions: - - condition: template - #value_template: '{{ trigger.event.data.new_state.state is match "coverposition\d+" and trigger.event.data.new_state.state == states(last_click_coversettings) }}' - value_template: '{{ trigger.event.data.new_state.state is match "coverposition\d+" }}' + # - "{{ trigger.event.data.new_state.state is match 'coverposition\d+' and trigger.event.data.new_state.state == states(last_click_coversettings) }}" + - '{{ trigger.event.data.new_state.state is match "coverposition\d+" }}' sequence: - service: cover.set_cover_position data: entity_id: "{{ entity_long }}" - position: '{{ trigger.event.data.new_state.state |replace("coverposition","") | int }}' + position: "{{ trigger.event.data.new_state.state | replace('coverposition','') | int }}" #### wird nicht mehr benötigt, da es im nextion editor nun direkt gemacht wird # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: coversettings.cover_value - # message: '{{ trigger.event.data.new_state.state |replace("coverposition","") | int }} %' + # message: "{{ trigger.event.data.new_state.state | replace('coverposition','') | int }} %' # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_text_printf }}" + # - service: "{{ nextion.commands.text_printf }}" # data: # component: coversettings.cover_value_2 - # message: '{{ trigger.event.data.new_state.state |replace("coverposition","") | int }} %' + # message: "{{ trigger.event.data.new_state.state | replace('coverposition','') | int }} %' ##### Page Coversettings - Cover CLOSE Button ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state == "cover_close_press" }}' + - "{{ trigger.event.data.new_state.state == 'cover_close_press' }}" sequence: - service: cover.close_cover data: @@ -7203,8 +5305,7 @@ action: ##### Page Coversettings - Cover OPEN Button ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state == "cover_open_press" }}' + - "{{ trigger.event.data.new_state.state == 'cover_open_press' }}" sequence: - service: cover.open_cover data: @@ -7212,8 +5313,7 @@ action: ##### Page Coversettings - Cover STOP Button ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state == "cover_stop_press" }}' + - "{{ trigger.event.data.new_state.state == 'cover_stop_press' }}" sequence: - service: cover.stop_cover data: @@ -7221,23 +5321,24 @@ action: ##### Page Coversettings - Close Coversettings Page ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state == "releasecoversettingsclose" }}' + - "{{ trigger.event.data.new_state.state == 'releasecoversettingsclose' }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ entity_back }}" ##### LASTCLICK_CLIMATESETTINGS - changes on page climatesettings ##### - - conditions: + - alias: Changes on page climatesettings + conditions: - condition: trigger id: climate_settings - - condition: template - value_template: "{{ states(current_page) == page_climate }}" + - "{{ nextion.pages.current == nextion.pages.climate }}" sequence: + - variables: + entity_long_state: "{{ states(entity_long) | default('unavailable') if entity_long is string else 'unavailable' }}" - choose: ##### Page Climatesettings - hotwater ##### - - conditions: '{{ trigger.event.data.new_state.state == "releasehotwater" }}' + - conditions: "{{ trigger.event.data.new_state.state == 'releasehotwater' }}" sequence: - service: >- {% if hotwatercharge is match 'switch.' %} @@ -7249,15 +5350,13 @@ action: entity_id: "{{ hotwatercharge }}" ##### Page Climatesettings - heating ##### - - conditions: '{{ trigger.event.data.new_state.state == "releaseheating" }}' + - conditions: "{{ trigger.event.data.new_state.state == 'releaseheating' }}" sequence: - - if: - - condition: template - value_template: '{{ states(entity_long) == "off" }}' + - if: "{{ entity_long_state == 'off' }}" then: - service: climate.turn_on ############ data: - entity_id: '{{ entity_long }}' + entity_id: "{{ entity_long }}" # - service: climate.set_temperature # data: # entity_id: !input climate @@ -7266,1046 +5365,556 @@ action: else: - service: climate.turn_off ############ data: - entity_id: '{{ entity_long }}' + entity_id: "{{ entity_long }}" # - service: climate.set_temperature # data: # entity_id: !input climate # hvac_mode: 'off' # temperature: "{{ state_attr(climate, 'temperature') }}" - ##### Page Climatesettings - decreasetemp ##### - - conditions: '{{ trigger.event.data.new_state.state == "releasedecreasetemp" }}' + ##### Page Climatesettings - increase/decrease temp ##### + - conditions: "{{ trigger.event.data.new_state.state in [ 'releaseincreasetemp', 'releasedecreasetemp'] }}" sequence: - - if: - - condition: template - value_template: '{{ states(entity_long) != "off" }}' + - variables: + delta: "{{ +0.5 if trigger.event.data.new_state.state == 'releaseincreasetemp' else -0.5 }}" + - if: "{{ entity_long_state != 'off' }}" then: - - if: - - condition: template - value_template: '{{ climate_optimistic == true }}' ## TODO - remove from here + - if: "{{ climate_optimistic == true }}" ## TODO - remove from here then: - variables: - current_setpoint: "{{ states(display_target_temperature) | round(1) if is_number(states(display_target_temperature)) else states(display_target_temperature) }}" - - service: "{{ command_thermostat_cycle }}" - data: - value: "{{ current_setpoint -0.5 }}" + current_setpoint: "{{ states(display_target_temperature) | default('unavailable') if display_target_temperature is string else 'unavailable' }}" + - if: "{{ is_number(current_setpoint) }}" + then: + - service: "{{ nextion.commands.thermostat_cycle }}" + data: + value: "{{ (current_setpoint + delta) | round(1) }}" else: - variables: - current_setpoint: "{{state_attr(entity_long, 'temperature') | round(1)}}" - - service: climate.set_temperature - data: - entity_id: '{{ entity_long }}' - #hvac_mode: 'heat' - temperature: "{{ current_setpoint -0.5 }}" - - - ##### Page Climatesettings - increasetemp ##### - - conditions: '{{ trigger.event.data.new_state.state == "releaseincreasetemp" }}' - sequence: - - if: - - condition: template - value_template: '{{ states(entity_long) != "off" }}' - then: - - variables: - current_setpoint: "{{state_attr(entity_long, 'temperature') | round(1)}}" - - if: - - condition: template - value_template: '{{ climate_optimistic == true }}' ## TODO - remove from here - then: - - variables: - current_setpoint: "{{ states(display_target_temperature) | round(1) if is_number(states(display_target_temperature)) else states(display_target_temperature) }}" - - service: "{{ command_thermostat_cycle }}" - data: - value: "{{ current_setpoint +0.5 }}" - else: - - variables: - current_setpoint: "{{state_attr(entity_long, 'temperature') | round(1)}}" - - service: climate.set_temperature - data: - entity_id: '{{ entity_long }}' - #hvac_mode: 'heat' - temperature: "{{ current_setpoint +0.5 }}" - + current_setpoint: "{{state_attr(entity_long, 'temperature') | default('unavailable') if entity_long is string else 'unavailable' }}" + - if: "{{ is_number(current_setpoint) }}" + then: + - service: climate.set_temperature + data: + entity_id: "{{ entity_long }}" + #hvac_mode: 'heat' + temperature: "{{ (current_setpoint + delta) | round(1) }}" ##### Page Climatesettings - climateslider ##### - - conditions: '{{ trigger.event.data.new_state.state is match "climateslider\d+" and trigger.event.data.new_state.state == states(last_click_climatesettings) }}' + - conditions: '{{ trigger.event.data.new_state.state is match "climateslider\d+" and trigger.event.data.new_state.state == states(last_click_climatesettings) }}' sequence: - - if: - - condition: template - value_template: '{{ states(entity_long) != "off" }}' + - if: "{{ entity_long_state != 'off' }}" then: - variables: - #climateslider: '{{ trigger.event.data.new_state.state |replace("climateslider","") | int }}' - new_setpoint: >- - {%- if trigger.event.data.new_state.state == "climateslider0" -%} 13.0 - {%- elif trigger.event.data.new_state.state == "climateslider1" -%} 13.5 - {%- elif trigger.event.data.new_state.state == "climateslider2" -%} 14 - {%- elif trigger.event.data.new_state.state == "climateslider3" -%} 14.5 - {%- elif trigger.event.data.new_state.state == "climateslider4" -%} 15 - {%- elif trigger.event.data.new_state.state == "climateslider5" -%} 15.5 - {%- elif trigger.event.data.new_state.state == "climateslider6" -%} 16 - {%- elif trigger.event.data.new_state.state == "climateslider7" -%} 16.5 - {%- elif trigger.event.data.new_state.state == "climateslider8" -%} 17 - {%- elif trigger.event.data.new_state.state == "climateslider9" -%} 17.5 - {%- elif trigger.event.data.new_state.state == "climateslider10" -%} 18 - {%- elif trigger.event.data.new_state.state == "climateslider11" -%} 18.5 - {%- elif trigger.event.data.new_state.state == "climateslider12" -%} 19 - {%- elif trigger.event.data.new_state.state == "climateslider13" -%} 19.5 - {%- elif trigger.event.data.new_state.state == "climateslider14" -%} 20 - {%- elif trigger.event.data.new_state.state == "climateslider15" -%} 20.5 - {%- elif trigger.event.data.new_state.state == "climateslider16" -%} 21 - {%- elif trigger.event.data.new_state.state == "climateslider17" -%} 21.5 - {%- elif trigger.event.data.new_state.state == "climateslider18" -%} 22 - {%- elif trigger.event.data.new_state.state == "climateslider19" -%} 22.5 - {%- elif trigger.event.data.new_state.state == "climateslider20" -%} 23 - {%- elif trigger.event.data.new_state.state == "climateslider21" -%} 23.5 - {%- elif trigger.event.data.new_state.state == "climateslider22" -%} 24 - {%- elif trigger.event.data.new_state.state == "climateslider23" -%} 24.5 - {%- elif trigger.event.data.new_state.state == "climateslider24" -%} 25 - {%- elif trigger.event.data.new_state.state == "climateslider25" -%} 25.5 - {%- elif trigger.event.data.new_state.state == "climateslider26" -%} 26 - {%- elif trigger.event.data.new_state.state == "climateslider27" -%} 26.5 - {%- elif trigger.event.data.new_state.state == "climateslider28" -%} 27 - {%- endif -%} - - if: - - condition: template - value_template: '{{ climate_optimistic == true }}' ## TODO - remove from here + climateslider: "{{ trigger.event.data.new_state.state | replace('climateslider','') | int(-1) }}" + new_setpoint: "{{ (13.0 + (climateslider * 0.5)) if climateslider >= 0 and climateslider <= 27 }}" + - if: "{{ climate_optimistic == true }}" ## TODO - remove from here then: - - service: "{{ command_thermostat_cycle }}" + - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{ new_setpoint }}" else: - service: climate.set_temperature data: - entity_id: '{{ entity_long }}' + entity_id: "{{ entity_long }}" #hvac_mode: 'heat' temperature: "{{ new_setpoint }}" #### Page Climate - Close Climate Page ##### - conditions: - - condition: template - value_template: '{{ trigger.event.data.new_state.state == "releaseclimateclose" }}' + - "{{ trigger.event.data.new_state.state == 'releaseclimateclose' }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ entity_back }}" - ##### TRIGGER - HOME PAGE ###### - ##### HOME PAGE - value 01 ##### - - conditions: + ##### HOME PAGE - Values ##### + - alias: Home page - Values + conditions: - condition: trigger - id: home_value01_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" + id: + - home_value01_state + - home_value02_state + - home_value03_state + - "{{ nextion.pages.current == nextion.pages.home }}" sequence: - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.value01_state - message: "{{ home_value01_label_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.value01_state - message: '{{ trigger.event.data.new_state.state |round(1) }}{{ trigger.event.data.new_state.attributes.unit_of_measurement }}' + - *variables-home_page_values + #- *display-home_page_values + - repeat: + for_each: "{{ home_page_values | selectattr('entity', 'defined') | selectattr('entity', 'eq', trigger.entity_id) | list }}" + sequence: + - *display-home_page_value - ##### HOME PAGE - value 02 ##### - - conditions: + ##### HOME PAGE - Status bar ##### + - alias: Home page - status bar + conditions: - condition: trigger - id: home_value02_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" + id: + - relay01_state + - relay02_state + - climate_state + - chip01_state + - chip02_state + - chip03_state + - chip04_state + - chip05_state + - chip06_state + - chip07_state + - "{{ nextion.pages.current == nextion.pages.home and trigger.event.data.new_state.state not in ['unavailable', 'unknown'] }}" sequence: - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.value02_state - message: "{{ home_value02_label_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.value02_state - message: '{{ trigger.event.data.new_state.state |round(1) }}{{ trigger.event.data.new_state.attributes.unit_of_measurement }}' - - ##### HOME PAGE - value 03 ##### - - conditions: - - condition: trigger - id: home_value03_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.value03_state - message: "{{ home_value03_label_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.value03_state - message: '{{ trigger.event.data.new_state.state |round(1) }}{{ trigger.event.data.new_state.attributes.unit_of_measurement }}' - - ##### CHIP RELAY 01 - statusbar 01 ##### - - conditions: - - condition: trigger - id: relay01_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_relay01: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ relay01_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_01 - message: "{{ relay01_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_01 - message: "{{ chip_relay01 }}" - - ##### CHIP RELAY 02 - statusbar 02 ##### - - conditions: - - condition: trigger - id: relay02_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_relay02: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ relay02_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_02 - message: "{{ relay02_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_02 - message: "{{ chip_relay02 }}" - - ##### CHIP HEATING - statusbar 03 ##### - - conditions: - - condition: trigger - id: climate_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_climate: >- - {%- if trigger.event.data.new_state.state == "heat" and trigger.event.data.new_state.attributes.hvac_action is defined and trigger.event.data.new_state.attributes.hvac_action == "heating" -%} {{ heat_icon }} - {%- elif trigger.event.data.new_state.state == "heat" -%} {{ thermostat_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_03 - message: "{{ thermostat_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_03 - message: "{{ chip_climate }}" - - ##### CHIP 01 - statusbar 04 ##### - - conditions: - - condition: trigger - id: chip01_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip01_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_04 - message: "{{ chip01_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_04 - message: "{{ chip_icon }}" - - ##### CHIP 02 - statusbar 05 ##### - - conditions: - - condition: trigger - id: chip02_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip02_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_05 - message: "{{ chip02_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_05 - message: "{{ chip_icon }}" - - ##### CHIP 03 - statusbar 06 ##### - - conditions: - - condition: trigger - id: chip03_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip03_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_06 - message: "{{ chip03_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_06 - message: "{{ chip_icon }}" - - ##### CHIP 04 - statusbar 07 ##### - - conditions: - - condition: trigger - id: chip04_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip04_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_07 - message: "{{ chip04_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_07 - message: "{{ chip_icon }}" - - ##### CHIP 05 - statusbar 08 ##### - - conditions: - - condition: trigger - id: chip05_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip05_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_08 - message: "{{ chip05_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_08 - message: "{{ chip_icon }}" - - ##### CHIP 06 - statusbar 09 ##### - - conditions: - - condition: trigger - id: chip06_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip06_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_09 - message: "{{ chip06_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_09 - message: "{{ chip_icon }}" - - ##### CHIP 07 - statusbar 10 ##### - - conditions: - - condition: trigger - id: chip07_state - - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" - sequence: - - variables: - chip_icon: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ chip07_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - ### ICON Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" - data: - component: home.icon_top_10 - message: "{{ chip07_icon_color }}" - ### ICON Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" - data: - component: home.icon_top_10 - message: "{{ chip_icon }}" + - *variables-home_page_status_bar + - repeat: + for_each: "{{ home_page_status_bar | selectattr('entity', 'defined') | selectattr('entity', 'eq', trigger.event.data.entity_id) | list }}" + sequence: + - *display-home_page_status_bar ##### JUMP TO - climate page ##### - - conditions: + - alias: Jump to climate page + conditions: - condition: trigger id: open_climate_page - condition: template - value_template: "{{ states(current_page) == page_home and climate |length > 0 }} " + value_template: "{{ nextion.pages.current == nextion.pages.home and climate | length > 0 }} " sequence: - variables: - entity_long: '{{ climate }}' - entity_long_name: >- - {%- if states(climate) == 'unavailable' -%} {{ climate }} - {%- else -%} {{ state_attr(climate, "friendly_name")| default('no name') }} - {%- endif -%} - entity_back: '{{ page_home }}' - - service: '{{ command_set_settings_entity }}' + entity_long: "{{ climate }}" + entity_long_state: "{{ states(climate) | default('unavailable') if climate is string else 'unavailable' }}" + entity_long_name: "{{ climate if entity_long_state in ['unavailable', 'unknown', None] else (state_attr(climate, 'friendly_name') | default(mui[language].no_name) if climate is string else mui[language].unavailable )}}" + entity_back: "{{ nextion.pages.home }}" + - service: "{{ nextion.commands.set_settings_entity }}" data: - entity: '{{ entity_long }},{{ entity_back }},{{ entity_long_name }}' + entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }}" - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_climate }}" + cmd: "page {{ nextion.pages.climate }}" ##### JUMP TO - Weather Page ##### - - conditions: + - alias: Jump to weather page + conditions: - condition: trigger id: open_weather_page - condition: template - value_template: "{{ states(current_page) == page_home }}" + value_template: "{{ nextion.pages.current == nextion.pages.home }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_weather01 }}" + cmd: "page {{ nextion.pages.weatherpages[0] }}" ##### JUMP TO - QR Code Page ##### - - conditions: + - alias: Jump to QR code page + conditions: - condition: trigger id: open_qrcode_page - condition: template - value_template: "{{ states(current_page) == page_home and qrcode_enabled == true }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and qrcode_enabled == true }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_qrcode }}" + cmd: "page {{ nextion.pages.qrcode }}" ##### JUMP TO - ENTITY Page ##### - - conditions: + - alias: Jump to entity page + conditions: - condition: trigger id: open_entity_page - condition: template - value_template: "{{ states(current_page) == page_home and entitypages_enabled == true }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and entitypages_enabled == true }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_entitypage01 }}" + cmd: "page {{ nextion.pages.entitypages[0] }}" ##### JUMP TO - notification ##### - - conditions: + - alias: Jump to notification page + conditions: - condition: trigger id: open_notification_page - condition: template - value_template: "{{ states(current_page) == page_home and states(notification_text) |length > 0}}" + value_template: "{{ nextion.pages.current == nextion.pages.home and notification_text is string and states(notification_text) | length > 0 }}" sequence: - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_notification }}" + cmd: "page {{ nextion.pages.notification }}" #### SHOW BUTTON - notification #### - - conditions: + - alias: Show button - Notification + conditions: - condition: trigger id: - notification_text_state - notification_unread_state - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' and trigger.event.data.new_state.state != 'unknown' }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: - alias: "Set notifiy pic" variables: - set_button04_icon: >- - {%- if is_state(notification_unread, 'on') and states(notification_text) |length > 0 -%} {{ home_button04_icon}} - {%- elif is_state(notification_unread, 'off') and states(notification_text) |length > 0 -%} {{ home_button04_icon }} - {%- else -%} {{ blank_icon }} - {%- endif -%} - set_button04_icon_font: >- - {%- if is_state(notification_unread, 'on') and states(notification_text) |length > 0 -%} {{ home_button04_icon_color01 }} - {%- elif is_state(notification_unread, 'off') and states(notification_text) |length > 0 -%} {{ home_button04_icon_color02 }} - {%- else -%} {{ color_03 }} - {%- endif -%} + notification_text_state: "{{ states(notification_text) | default('unavailable') if notification_text is string else 'unavailable' }}" + notification_text_available: "{{ notification_text_state not in ['unavailable', 'unknown', None] }}" + notification_unread_state: "{{ states(notification_unread) | default('unavailable') if notification_unread is string else 'unavailable' }}" + set_button04_icon: "{{ page_home.buttons[3].icon if notification_unread_state in ['on', 'off'] and notification_text_available else nextion.icons.blank }}" + set_button04_icon_font: > + {{ + (page_home.buttons[3].color_rgb[notification_unread_state] if is_number(page_home.buttons[3].color_rgb[notification_unread_state]) else ((page_home.buttons[3].color_rgb[notification_unread_state][0] //(2**3)) *(2**11))+((page_home.buttons[3].color_rgb[notification_unread_state][1] //(2**2)) *(2**5))+(page_home.buttons[3].color_rgb[notification_unread_state][2] //(2**3))) + if notification_unread_state in ['on', 'off'] and notification_text_available + else nextion.colors.grey_light + }} ##### SET ICON Font - Notify ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.button04_icon message: "{{ set_button04_icon }}" ##### SET ICON Font Color - Notify ##### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.button04_icon message: "{{ set_button04_icon_font }}" ##### SHOW BUTTON - notification clear ##### - - conditions: + - alias: Show button - Notification clear + conditions: - condition: trigger id: btn_notificationclearrelease - condition: template - value_template: "{{ states(current_page) == page_notification and states(confirmation_message) != 'on'}}" + value_template: "{{ nextion.pages.current == nextion.pages.notification and confirmation_message is string and states(confirmation_message) | default('unavailable') != 'on' }}" sequence: - service: switch.turn_off data: entity_id: "{{ notification_unread }}" - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_home }}" + cmd: "page {{ nextion.pages.home }}" ##### SHOW BUTTON - notification accept ##### - - conditions: + - alias: Show button - Notification accept + conditions: - condition: trigger id: btn_notificationacceptrelease - condition: template - value_template: "{{ states(current_page) == page_notification and states(confirmation_message) != 'on'}}" + value_template: "{{ nextion.pages.current == nextion.pages.notification and confirmation_message is string and states(confirmation_message) | default('unavailable') != 'on' }}" sequence: - service: switch.turn_off data: entity_id: "{{ notification_unread }}" - - service: "{{ command_notification_clear }}" + - service: "{{ nextion.commands.notification_clear }}" data: {} - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: - cmd: "page {{ page_home }}" + cmd: "page {{ nextion.pages.home }}" - ##### LEFT BUTTON - press ##### - - conditions: + ##### BUTTON - press ##### + - alias: Button - Press + conditions: - condition: trigger - id: left_button_press + id: + - left_button_press + - right_button_press sequence: - - wait_template: "{{ is_state(left_button, 'off') }}" - timeout: !input hold_delay - continue_on_timeout: true - - if: - - condition: template - value_template: "{{ not wait.completed }}" - then: # Hold - - choose: - - conditions: '{{ left_button_hold_select == "Default" and left_button_entity |length > 0 }}' - sequence: - - variables: - entity_long: '{{ left_button_entity }}' - entity_long_name: >- - {%- if left_button_name |length > 0 -%} {{ left_button_name }} - {%- elif states(left_button_entity) == 'unavailable' -%} {{ left_button_entity }} - {%- else -%} {{ state_attr(left_button_entity, "friendly_name")| default('no name') }} - {%- endif -%} - entity_back: '{{ page_home }}' - entity_long_icon: >- - {%- if left_button_entity is match "light." -%} {{ button_icon_light }} - {%- elif left_button_entity is match "switch." -%} {{ button_icon_switch }} - {%- elif left_button_entity is match "input_boolean." -%} {{ button_icon_input_boolan }} - {%- elif left_button_entity is match "cover." -%} {{ button_icon_cover }} - {%- elif left_button_entity is match "automation." -%} {{ button_icon_automation }} - {%- elif left_button_entity is match "button." -%} {{ button_icon_button }} - {%- elif left_button_entity is match "input_button." -%} {{ button_icon_input_button }} - {%- elif left_button_entity is match "scene." -%} {{ button_icon_scene }} - {%- elif left_button_entity is match "script." -%} {{ button_icon_script }} - {%- elif left_button_entity is match "person." -%} {{ button_icon_person }} - {%- elif left_button_entity is match "binary_sensor." -%} {{ button_icon_binary_sensor }} - {%- elif left_button_entity is match "fan." -%} {{ button_icon_fan }} - {%- elif left_button_entity is match "climate." -%} {{ button_icon_climate }} - {%- endif -%} - entity_long_icon_color: 1055 - - service: '{{ command_set_settings_entity }}' - data: - entity: '{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}' - - - conditions: '{{ left_button_hold_select == "Custom Action" }}' - sequence: !input left_button_hold_custom_action - else: # Single Click - - condition: template - value_template: '{{ left_button_entity |length > 0 }}' - - service: >- - {% if left_button_entity is match 'light.' %} - light.toggle - {% elif left_button_entity is match 'switch.' %} - switch.toggle - {% elif left_button_entity is match 'cover.' %} - cover.toggle - {% elif left_button_entity is match 'input_boolean.' %} - input_boolean.toggle - {% elif left_button_entity is match 'automation.' %} - automation.toggle - {% elif left_button_entity is match 'button.' %} - button.press - {% elif left_button_entity is match 'input_button.' %} - input_button.press - {% elif left_button_entity is match 'scene.' %} - scene.turn_on - {% elif left_button_entity is match 'script.' %} - script.turn_on - {% elif left_button_entity is match 'fan.' %} - fan.toggle - {% endif %} - data: - entity_id: "{{ left_button_entity }}" - - ##### LEFT BUTTON - state ##### - - conditions: - - condition: trigger - id: left_button_state - - condition: template - value_template: "{{ states(current_page) == page_home }}" - sequence: - - ###### Left Hardware Button PIC ##### - variables: - # Hardware Button PIC - left_hardware_button_state: >- - {%- if trigger.event.data.new_state.state == 'off' -%} {{ hardware_button_pic_off }} - {%- elif trigger.event.data.new_state.state == 'on' -%} {{ hardware_button_pic_on }} - {%- endif -%} - - ##### SET Right hardware Button PIC on Home Page #### - - service: "{{ command_printf }}" - data: - cmd: home.left_bt_pic.pic={{ left_hardware_button_state }} - - ##### RIGHT BUTTON - press ##### - - conditions: - - condition: trigger - id: right_button_press - sequence: - - wait_template: "{{ is_state(right_button, 'off') }}" + button_context: "{{ page_home.hardware.buttons.left if trigger.id == 'left_button_press' else page_home.hardware.buttons.right }}" + - wait_template: "{{ is_state(left_button if trigger.id == 'left_button_press' else right_button, 'off') }}" timeout: !input hold_delay continue_on_timeout: true - - if: - - condition: template - value_template: "{{ not wait.completed }}" + - if: "{{ not wait.completed }}" then: # Hold - choose: - - conditions: '{{ right_button_hold_select == "Default" and right_button_entity |length > 0 }}' + - conditions: "{{ button_context.hold_select == 'Default' and button_context.entity | length > 0 }}" sequence: - variables: - entity_long: '{{ right_button_entity }}' + entity_long: "{{ button_context.entity }}" + button_status: "{{ states(button_context.entity) | default('unavailable') if button_context.entity is string else 'unavailable' }}" entity_long_name: >- - {%- if right_button_name |length > 0 -%} {{ right_button_name }} - {%- elif states(right_button_entity) == 'unavailable' -%} {{ right_button_entity }} - {%- else -%} {{ state_attr(right_button_entity, "friendly_name")| default('no name') }} - {%- endif -%} - entity_back: '{{ page_home }}' - entity_long_icon: >- - {%- if left_button_entity is match "light." -%} {{ button_icon_light }} - {%- elif left_button_entity is match "switch." -%} {{ button_icon_switch }} - {%- elif left_button_entity is match "input_boolean." -%} {{ button_icon_input_boolan }} - {%- elif left_button_entity is match "cover." -%} {{ button_icon_cover }} - {%- elif left_button_entity is match "automation." -%} {{ button_icon_automation }} - {%- elif left_button_entity is match "button." -%} {{ button_icon_button }} - {%- elif left_button_entity is match "input_button." -%} {{ button_icon_input_button }} - {%- elif left_button_entity is match "scene." -%} {{ button_icon_scene }} - {%- elif left_button_entity is match "script." -%} {{ button_icon_script }} - {%- elif left_button_entity is match "person." -%} {{ button_icon_person }} - {%- elif left_button_entity is match "binary_sensor." -%} {{ button_icon_binary_sensor }} - {%- elif left_button_entity is match "fan." -%} {{ button_icon_fan }} - {%- elif left_button_entity is match "climate." -%} {{ button_icon_climate }} + {%- if button_context.name | length > 0 -%} {{ button_context.name }} + {%- elif button_status in ['unavailable', 'unknown', None] -%} {{ button_context.entity }} + {%- else -%} {{ state_attr(button_context.entity, 'friendly_name') | default(mui[language].no_name) }} {%- endif -%} + entity_back: "{{ nextion.pages.home }}" + entity_long_icon: "{{ nextion.icons.buttons[button_context.entity.split('.')[0] if button_context.entity else 'unknown'] }}" entity_long_icon_color: 1055 - - service: '{{ command_set_settings_entity }}' + - service: "{{ nextion.commands.set_settings_entity }}" data: - entity: '{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}' - - - conditions: '{{ right_button_hold_select == "Custom Action" }}' + entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}" + - conditions: "{{ button_context.hold_select == 'Custom Action' and trigger.id == 'left_button_press' }}" + sequence: !input left_button_hold_custom_action + - conditions: "{{ button_context.hold_select == 'Custom Action' and trigger.id == 'right_button_press' }}" sequence: !input right_button_hold_custom_action else: # Single Click - condition: template - value_template: '{{ right_button_entity |length > 0 }}' - - service: >- - {% if right_button_entity is match 'light.' %} - light.toggle - {% elif right_button_entity is match 'switch.' %} - switch.toggle - {% elif right_button_entity is match 'cover.' %} - cover.toggle - {% elif right_button_entity is match 'input_boolean.' %} - input_boolean.toggle - {% elif right_button_entity is match 'automation.' %} - automation.toggle - {% elif right_button_entity is match 'button.' %} - button.press - {% elif right_button_entity is match 'input_button.' %} - input_button.press - {% elif right_button_entity is match 'scene.' %} - scene.turn_on - {% elif right_button_entity is match 'script.' %} - script.turn_on - {% elif right_button_entity is match 'fan.' %} - fan.toggle + value_template: "{{ button_context.entity | length > 0 }}" + - variables: + button_domain: "{{ (button_context.entity.split('.')[0] | default('unknown')) if button_context.entity | length > 0 else 'unknown' }}" + - service: > + {% if button_domain in ['light', 'switch', 'cover', 'input_boolean', 'automation', 'fan'] %} + {{ button_domain }}.toggle + {% elif button_domain in ['button', 'input_button'] %} + {{ button_domain }}.press + {% elif button_domain in ['scene', 'script'] %} + {{ button_domain }}.turn_on + {% else %} + homeassistant.update_entity {% endif %} data: - entity_id: "{{ right_button_entity }}" + entity_id: "{{ button_context.entity }}" - ##### RIGHT BUTTON - state ##### - - conditions: + ##### BUTTON - state ##### + - alias: Button - State + conditions: - condition: trigger - id: right_button_state + id: + - left_button_state + - right_button_state - condition: template - value_template: "{{ states(current_page) == page_home }}" + value_template: "{{ nextion.pages.current == nextion.pages.home }}" sequence: - - ###### Left Hardware Button PIC ##### - variables: # Hardware Button PIC - right_hardware_button_state: >- - {%- if trigger.event.data.new_state.state == 'off' -%} {{ hardware_button_pic_off }} - {%- elif trigger.event.data.new_state.state == 'on' -%} {{ hardware_button_pic_on }} - {%- endif -%} - - ##### SET Right hardware Button PIC on Home Page #### - - service: "{{ command_printf }}" + current_hardware_button_state: "{{ nextion.pics.hardware.button[trigger.to_state.state] }}" + ##### SET hardware Button PIC on Home Page #### + - service: "{{ nextion.commands.printf }}" data: - cmd: home.right_bt_pic.pic={{ right_hardware_button_state }} + cmd: "home.{{ 'left' if trigger.id == 'left_button_state' else 'right'}}_bt_pic.pic={{ current_hardware_button_state }}" ##### DATE AND TIME ##### - - conditions: + - alias: "Date & Time" + conditions: - condition: trigger id: time_state - condition: template - value_template: "{{ states(current_page) == page_home }}" + value_template: "{{ nextion.pages.current == nextion.pages.home }}" sequence: ### TIME Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.time - message: "{{ time_label_color }}" + message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" ### TIME Font ### - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: home.time message: "{{ time }}" ### TIME Meridiem Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.meridiem - message: "{{ time_label_color }}" + message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" ### TIME Meridiem Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.meridiem message: "{{ meridiem }}" ### DATE Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.date - message: "{{ date_label_color }}" + message: "{{ page_home.general.date.label.color_rgb if is_number(page_home.general.date.label.color_rgb) else ((page_home.general.date.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.date.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.date.label.color_rgb[2] //(2**3)) }}" ### DATE Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.date - message: "{{ mui_weekday_today }}" + message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom('%d.%m') }}" ##### OUTDOOR TEMP - entity ##### - - conditions: + - alias: Outdoor temp - Entity + conditions: - condition: trigger id: outdoortemp_state - condition: template - value_template: "{{ states(current_page) == page_home and is_number(trigger.event.data.new_state.state) }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and is_number(trigger.event.data.new_state.state) }}" sequence: + - *variables-weather ### LABEL Outdoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.outdoor_temp - message: "{{ home_outdoor_temp_label_color }}" + message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" ### LABEL Outdoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather.units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" ##### INDOOR TEMP - entity ##### - - conditions: + - alias: Indoor temp - Entity + conditions: - condition: trigger id: indoortemp_state - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: + - *variables-weather ### LABEL Indoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.current_temp - message: "{{ home_indoor_temp_label_color }}" + message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" ### LABEL Indoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather.units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" ##### INDOOR TEMP - nspanel ##### - - conditions: + - alias: Indoor temp - NSPanel + conditions: - condition: trigger id: nspaneltemp_state - condition: template - value_template: "{{ states(current_page) == page_home and is_number(trigger.event.data.new_state.state) }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and is_number(trigger.event.data.new_state.state) }}" sequence: - - if: - - condition: template - value_template: '{{ indoortemp is not match "sensor." }}' + - *variables-weather + - if: "{{ indoortemp is not match 'sensor.' }}" then: ### LABEL Indoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.current_temp - message: "{{ home_indoor_temp_label_color }}" + message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" ### LABEL Indoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather.units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" ##### WEATHER STATE - change update ##### - - conditions: + - alias: Weather - State changed + conditions: - condition: trigger id: weather_state_change - condition: template - value_template: "{{ states(current_page) == page_home and trigger.event.data.new_state.state != 'unavailable' }}" + value_template: "{{ nextion.pages.current == nextion.pages.home and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: - - if: - - condition: template - value_template: '{{ outdoortemp is not match "sensor." }}' + - *variables-weather + - if: "{{ outdoortemp is not match 'sensor.' }}" then: ### LABEL Outdoor Temp Font Color ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_font_color }}" + - *delay-default + - service: "{{ nextion.commands.font_color }}" data: component: home.outdoor_temp - message: "{{ home_outdoor_temp_label_color }}" + message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" ### LABEL Outdoor Temp Font ### - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp - message: '{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather.units.temperature }}' - - service: "{{ command_text_printf }}" + message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather_units.temperature }}" + - service: "{{ nextion.commands.text_printf }}" data: component: climate.outdoor_temp - message: '{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather.units.temperature }}' + message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather_units.temperature }}" - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: cmd: home.weather.pic={{ nextion.pics.weather[trigger.event.data.new_state.state | default('unknown')] }} - - -########################################################################################################### - - ##### Sync Climate ##### -> muss noch in page changed climate wwenn climate page fertig - - conditions: + - alias: Climate - Sync + conditions: - condition: trigger id: climate_state - - condition: template - value_template: "{{ trigger.event.data.new_state.state != 'unavailable' }}" + - "{{ trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" # - condition: template - # value_template: '{{ states(current_page) == page_climate }}' + # value_template: "{{ nextion.pages.current == nextion.pages.climate }}" # - condition: template - # value_template: '{{ climate_optimistic == false }}' + # value_template: "{{ climate_optimistic == false }}" sequence: + - *variables-weather - variables: - heating_state: "{{ mui[language].climate.states.off if trigger.event.data.new_state.state == 'off' else mui[language].climate.states.on }}" + heating_state: "{{ mui[language].climate.states.off if trigger.event.data.new_state.state == 'off' else mui[language].climate.states.on }}" heating_bt_pic: >- - {%- if trigger.event.data.new_state.state == "off" -%} {{ heating_bt_pic_off }} - {%- else -%} {{ heating_bt_pic_on }} + {%- if trigger.event.data.new_state.state == 'off' -%} {{ nextion.pics.heating.button.off }} + {%- else -%} {{ nextion.pics.heating.button.on }} {%- endif -%} - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: current_temp - message: "{{ trigger.event.data.new_state.attributes.current_temperature | round(1)}}{{ weather.units.temperature }}" - - service: "{{ command_text_printf }}" + message: "{{ trigger.event.data.new_state.attributes.current_temperature | round(1)}}{{ weather_units.temperature }}" + - service: "{{ nextion.commands.text_printf }}" data: component: heating_state message: "{{heating_state}}" - - service: "{{ command_printf }}" + - service: "{{ nextion.commands.printf }}" data: cmd: heating_bt_pic.pic={{ heating_bt_pic }} - - if: - - condition: template - value_template: '{{ trigger.event.data.new_state.state != "off" }}' #### TODO AND->OR (not) not optimistic-mode + - if: "{{ trigger.event.data.new_state.state != 'off' }}" #### TODO AND->OR (not) not optimistic-mode then: - - service: "{{ command_thermostat_cycle }}" + - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}" else: - - service: "{{ command_thermostat_cycle }}" + - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "0" - - service: "{{ command_text_printf }}" + - service: "{{ nextion.commands.text_printf }}" data: component: target_temp message: " " ##### Sync Hotwater Charge button-symbol ##### -> kann wenn climate page fertig - - conditions: + - alias: Hotwater - Sync + conditions: - condition: trigger id: hotwatercharge_state - - condition: template - value_template: "{{ states(current_page) == page_climate }}" + - "{{ nextion.pages.current == nextion.pages.climate }}" sequence: - variables: - hotw_bt_pic: >- - {%- if trigger.event.data.new_state.state == 'on' -%} {{ hotw_bt_on }} - {%- elif trigger.event.data.new_state.state == 'off' -%} {{ hotw_bt_off }} - {%- else -%} {{ hotw_bt_blank }} - {%- endif -%} - - service: "{{ command_printf }}" + hotw_bt_pic: "{{ nextion.pics.hvac.button[trigger.event.data.new_state.state] }}" + - service: "{{ nextion.commands.printf }}" data: cmd: hotw_bt_pic.pic={{ hotw_bt_pic }} ##### Hotwater Temp ##### kann raus und wird durch neue value 01 und value 02 ersetzt wenn climate page fertig - - conditions: + - alias: Hotwater - Temp + conditions: - condition: trigger id: hotwatertemp_state - - condition: template - value_template: "{{ states(current_page) == page_climate and trigger.event.data.new_state.state != 'unavailable' }}" + - "{{ nextion.pages.current == nextion.pages.climate and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: - - service: "{{ command_text_printf }}" + - *variables-weather + - service: "{{ nextion.commands.text_printf }}" data: component: home.hotwater_temp - message: "{{ trigger.event.data.new_state.state |round(1) }}{{ weather.units.temperature }}" - - delay: - milliseconds: "{{ delay_value }}" - - service: "{{ command_text_printf }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + - *delay-default + - service: "{{ nextion.commands.text_printf }}" data: component: climate.hotwater_temp - message: "{{ trigger.event.data.new_state.state |round(1) }}{{ weather.units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" # - delay: # milliseconds: "{{ delay_value }}" - # - service: "{{ command_printf }}" + # - service: "{{ nextion.commands.printf }}" # data: # cmd: home.hotwater_pic.pic={{ hotwater_pic_on }} #### TFT Upload Automation ##### - - conditions: + - alias: TFT auto-upload + conditions: - condition: trigger id: tft_upload sequence: - delay: seconds: 2 - - service: "{{ tft_upload }}" + - service: "{{ nextion.commands.tft_upload }}" data: {} - ############################################################# ##### CLOSE - Action ##### ############################################################# From a351eece0bc3f81a46db4fc7560a4bd56e84dcbf Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:41:56 +0200 Subject: [PATCH 02/30] Removing empty lines (merging conflicts) (#598) --- nspanel_blueprint.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index f760767..80b34f7 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -19,7 +19,6 @@ The goal was to create a version that allows everyone to use the NSpanel fully l 📕 Full documentation and installation video is available here [NSPanel Configuration, Setup and HowTo](https://github.com/Blackymas/NSPanel_HA_Blueprint/wiki). - 🖼️ Home Assistant [Icon Page](https://htmlpreview.github.io/?https://github.com/jobr99/Generate-HASP-Fonts/blob/master/cheatsheet.html) @@ -2479,7 +2478,6 @@ variables: unknown: '' unavailable: '' - ##### MUI Multilingual User Interface ##### mui: BGR: @@ -4126,7 +4124,6 @@ action: component: home.button06_icon message: "{{ nextion.icons.blank }}" - ###### SHOW All component when page loading done ##### - *delay-default - service: "{{ nextion.commands.show_all }}" @@ -4409,7 +4406,6 @@ action: btn_icon: "{{ btn_icon }}" btn_label: "{{ btn_label }}" btn_bri_txt: "{{ btn_bri_txt }}" - ###### SHOW All component when page loading done ##### - *delay-default - service: "{{ nextion.commands.show_all }}" From 601568b6f048ce7a06047115b75b998865819930 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:50:00 +0200 Subject: [PATCH 03/30] Fix on date format (copy #568 to DEV) (#600) https://github.com/Blackymas/NSPanel_HA_Blueprint/pull/568 --- nspanel_blueprint.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 80b34f7..2340b1f 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -128,8 +128,10 @@ The goal was to create a version that allows everyone to use the NSpanel fully l value: '%d.%m' - label: 'DD/MM (ex. 22/03)' value: '%d/%m' - - label: 'D/M (ex. 3/22)' + - label: 'M/D (ex. 3/22)' value: '%-m/%-d' + - label: 'D/M (ex. 22/3)' + value: '%-d/%-m' time_format: name: Time Format From 383835d71037c3254e7d1c4e62fc44d7aa31bde7 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 02:02:04 +0200 Subject: [PATCH 04/30] Add cover battery when not as an attribute (#601) - It will try to find a battery sensor withing the same device. This should fix #153 --- nspanel_blueprint.yaml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 2340b1f..6f9040b 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -4523,13 +4523,25 @@ action: message: "{{ (state_attr(entity_long, 'current_position') | int ) | round(0) }} %" ##### COVER Battery ICON Yes / NO ##### - - if: "{{ state_attr(entity_long, 'battery') != none }}" + - variables: + battery_level: > + {% if state_attr(entity_long, 'battery') | default('unavailable') not in ['unavailable', 'unknown', None] %} + {{ state_attr(entity_long, 'battery') | default('unavailable') }} + {% elif expand(device_entities(device_id(entity_long))) | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', 'battery') | map(attribute='state') | map('float') | list | count > 0 %} + {{ expand(device_entities(device_id(entity_long))) | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', 'battery') | map(attribute='state') | map('float') | list | first }} + {% elif states(entity_long | replace('cover.','sensor.') ~ '_battery') | default('unavailable') not in ['unavailable', 'unknown', None] %} + {{ states(entity_long | replace('cover.','sensor.') ~ '_battery') | default('unavailable') }} + {% elif states(entity_long | replace('cover.','sensor.') | replace('cover', 'battery')) | default('unavailable') not in ['unavailable', 'unknown', None] %} + {{ states(entity_long | replace('cover.','sensor.') | replace('cover', 'battery')) | default('unavailable') }} + {% else %} unavailable + {% endif %} + - if: "{{ is_number(battery_level) }}" then: - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.battery_value - message: "{{ (state_attr(entity_long, 'battery') | int ) | round(0) }} %" + message: "{{ battery_level | round(0) }} %" ### ICON Battery Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" From f871ef84e9893965e9d8e979f0bc7458dec449ee Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 02:02:32 +0200 Subject: [PATCH 05/30] Fix date format on home page (#602) * Fix date format on home page To use custom date format * Remove debug call --- nspanel_blueprint.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 6f9040b..678ef1b 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -128,10 +128,10 @@ The goal was to create a version that allows everyone to use the NSpanel fully l value: '%d.%m' - label: 'DD/MM (ex. 22/03)' value: '%d/%m' - - label: 'M/D (ex. 3/22)' - value: '%-m/%-d' - - label: 'D/M (ex. 22/3)' + - label: 'D/M (ex. 22/3)' value: '%-d/%-m' + - label: 'M/D (ex. 3/22)' + value: '%-m/%-d' time_format: name: Time Format @@ -3796,6 +3796,9 @@ action: entity: 'unknown' ##### NSPanel Date ##### ### DATE Font Color ### + - &variables-date_format + variables: + date_format: !input "date_format" - *delay-default - service: "{{ nextion.commands.font_color }}" data: @@ -3806,8 +3809,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.date - message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom('%d.%m') }}" - + message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom(date_format) }}" ##### NSPanel Time ##### ### TIME Font Color ### - *delay-default @@ -4825,8 +4827,7 @@ action: - *delay-default ##### Display date (long) ##### - - variables: - date_format: !input "date_format" + - *variables-date_format - service: "{{ nextion.commands.text_printf }}" data: component: "{{ page_name }}.date" From 2a5f3124d5718f1b8cd23b52dc1f29cdad912161 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 02:04:12 +0200 Subject: [PATCH 06/30] Fix first button not responding to short press (#603) --- nspanel_blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 678ef1b..dd9f276 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -5073,7 +5073,7 @@ action: last_click_state: "{{ states(last_click) | default('unavailable') if last_click is string else 'unavailable' }}" last_click_coordinates: "{{ last_click_state.replace('releasebuttonpage', '').split('button') if last_click_state not in ['unavailable', 'unknown', None] else [-1, -1] }}" last_click_entity_index: "{{ (last_click_coordinates[0] | int(-99) -1)*8 + last_click_coordinates[1] | int(-99) - 1 }}" - - condition: "{{ last_click_entity_index > 0 }}" + - condition: "{{ last_click_entity_index >= 0 }}" - variables: last_click_button: "{{ button_pages_buttons[last_click_entity_index] | default([]) }}" entity_short: "{{ last_click_button.entity | default('unavailable') if last_click_button and last_click_button.entity is defined }}" From a831d189d8f7e324de3ebadbe2f3986378715524 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 08:58:11 +0200 Subject: [PATCH 07/30] Code optimization --- nspanel_blueprint.yaml | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index dd9f276..90b11f9 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -4058,20 +4058,8 @@ action: - variables: notification_unread_state: "{{ states(notification_unread) | default('unavailable') if notification_unread is string else 'unavailable' }}" notification_text_state: "{{ states(notification_text) | default(None) if notification_text is string else None }}" - set_button04_icon: >- - {%- if notification_unread_state == 'on' and notification_text_state | length > 0 -%} {{ page_home.buttons[3].icon}} - {%- elif notification_unread_state == 'off' and notification_text_state | length > 0 -%} {{ page_home.buttons[3].icon }} - {%- else -%} {{ nextion.icons.blank }} - {%- endif -%} - set_button04_icon_font: >- - {%- if notification_unread_state == 'on' and notification_text_state | length > 0 -%} - {% set rgb = page_home.buttons[3].color_rgb.on %} - {{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }} - {%- elif notification_unread_state == 'off' and notification_text_state | length > 0 -%} - {% set rgb = page_home.buttons[3].color_rgb.off %} - {{ rgb if is_number(rgb) else ((rgb[0] //(2**3)) *(2**11))+((rgb[1] //(2**2)) *(2**5))+(rgb[2] //(2**3)) }} - {%- else -%} {{ nextion.colors.grey_light }} - {%- endif -%} + set_button04_icon: "{{ page_home.buttons[3].icon if notification_unread_state in ['on', 'off'] and notification_text_state | length > 0 else nextion.icons.blank }}" + set_button04_icon_font: "{{ (page_home.buttons[3].color_rgb[notification_unread_state] if is_number(page_home.buttons[3].color_rgb[notification_unread_state]) else ((page_home.buttons[3].color_rgb[notification_unread_state][0] //(2**3)) *(2**11))+((page_home.buttons[3].color_rgb[notification_unread_state][1] //(2**2)) *(2**5))+(page_home.buttons[3].color_rgb[notification_unread_state][2] //(2**3))) if notification_unread_state in ['on', 'off'] and notification_text_state | length > 0 else nextion.colors.grey_light }}" ##### SET ICON Font - Notify ##### - *delay-default - service: "{{ nextion.commands.text_printf }}" @@ -4786,10 +4774,7 @@ action: # HVAC Button PIC - variables: - heating_bt_pic: >- - {%- if hvac_mode == 'off' -%} {{ nextion.pics.heating.button.off }} - {%- else -%} {{ nextion.pics.heating.button.on }} - {%- endif -%} + heating_bt_pic: "{{ nextion.pics.heating.button.off if hvac_mode == 'off' else nextion.pics.heating.button.on }}" - *delay-default - service: "{{ nextion.commands.printf }}" data: @@ -5848,10 +5833,7 @@ action: - *variables-weather - variables: heating_state: "{{ mui[language].climate.states.off if trigger.event.data.new_state.state == 'off' else mui[language].climate.states.on }}" - heating_bt_pic: >- - {%- if trigger.event.data.new_state.state == 'off' -%} {{ nextion.pics.heating.button.off }} - {%- else -%} {{ nextion.pics.heating.button.on }} - {%- endif -%} + heating_bt_pic: "{{ nextion.pics.heating.button.off if trigger.event.data.new_state.state == 'off' else nextion.pics.heating.button.on }}" - service: "{{ nextion.commands.text_printf }}" data: From 0eef377ca959e23a7f2a536593c73e11d23c0e35 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 09:38:49 +0200 Subject: [PATCH 08/30] Support for `opening` &`closing` states on button - Button pages now displays cover status when is is `opening` or `closing`. This probably solves #451 --- nspanel_blueprint.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index dd9f276..dae9ff2 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -4367,25 +4367,25 @@ action: current_entity_state: "{{ states(repeat.item.entity) | default('unavailable') }}" current_entity_state_available: "{{ current_entity_state not in ['unknown', 'unavailable', None] }}" # Button PIC GRAY/WHITE - btn_pic: "{{ nextion.pics.button.on if current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') else nextion.pics.button.off }}" + btn_pic: "{{ nextion.pics.button.on if current_entity_state in ['on', 'open', 'opening', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') else nextion.pics.button.off }}" # TEXT, BRIGHTNESS and ICON Background - btn_bg: "{{ nextion.colors.white if current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') else nextion.colors.grey_dark }}" + btn_bg: "{{ nextion.colors.white if current_entity_state in ['on', 'open', 'opening', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') else nextion.colors.grey_dark }}" # ICON Font Color btn_icon_font: > {% if not current_entity_state_available %} {{ nextion.colors.red }} - {% elif item_domain in ['button', 'input_button', 'scene'] or current_entity_state in ['off', 'closed'] or (item_domain == 'person' and current_entity_state != 'home') %} {{ nextion.colors.grey_light }} - {% elif current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') %} {{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }} + {% elif item_domain in ['button', 'input_button', 'scene'] or current_entity_state in ['off', 'closed', 'closing'] or (item_domain == 'person' and current_entity_state != 'home') %} {{ nextion.colors.grey_light }} + {% elif current_entity_state in ['on', 'open', 'opening', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') %} {{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }} {% else %} {{ nextion.colors.red }} {% endif %} # LABEL Font Color btn_txt_font: >- {% if not current_entity_state_available %} {{ nextion.colors.white }} - {% elif item_domain in ['button', 'input_button', 'scene'] or current_entity_state in ['off', 'closed'] or (item_domain == 'person' and current_entity_state != 'home') %} {{ nextion.colors.white }} - {% elif current_entity_state in ['on', 'open', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') %} {{ nextion.colors.grey_dark }} + {% elif item_domain in ['button', 'input_button', 'scene'] or current_entity_state in ['off', 'closed', 'closing'] or (item_domain == 'person' and current_entity_state != 'home') %} {{ nextion.colors.white }} + {% elif current_entity_state in ['on', 'open', 'opening', 'home'] or (item_domain == 'climate' and current_entity_state != 'off') %} {{ nextion.colors.grey_dark }} {% else %} {{ nextion.colors.white }} {% endif %} # BRIGHTNESS Font Color - btn_bri_font: "{{ nextion.colors.grey_dark }}" + btn_bri_font: "{{ btn_txt_font }}" #"{{ nextion.colors.grey_dark }}" # ICON Value btn_icon: "{{ repeat.item.icon if repeat.item.icon | length > 0 else nextion.icons.buttons[repeat.item.entity.split('.')[0] if repeat.item.entity else 'unknown'] }}" # LABEL Value @@ -4394,7 +4394,7 @@ action: btn_bri_txt: >- {% if not current_entity_state_available %} 0 {% elif item_domain == 'light' and current_entity_state == 'on' and state_attr(repeat.item.entity, 'brightness') != None %} {{ (state_attr(repeat.item.entity, 'brightness') | int * 100 /255) | round(0) }}% - {% elif item_domain == 'cover' and current_entity_state == 'open' and state_attr(repeat.item.entity, 'current_position') != None %} {{ (state_attr(repeat.item.entity, 'current_position') | int(100)) | round(0) }}% + {% elif item_domain == 'cover' and current_entity_state in ['open', 'opening', 'closing'] and state_attr(repeat.item.entity, 'current_position') != None %} {{ (state_attr(repeat.item.entity, 'current_position') | int(100)) | round(0) }}% {% elif item_domain == 'climate' and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None %} {{ (state_attr(repeat.item.entity, "current_temperature") | float) | round(0) }}{{ weather_units.temperature }} {% else -%} 0 {% endif -%} From 92753d5ca45568e0e0948211b2328f82d752bd6e Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:09:43 +0200 Subject: [PATCH 09/30] Removed "Weather integration" selection from setup The weather integration is now automatically detected by the Blueprint, based on the attributes provided by the integration itself, so an user selection is not needed anymore. --- nspanel_blueprint.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index dd9f276..b1e3a40 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -167,15 +167,6 @@ The goal was to create a version that allows everyone to use the NSpanel fully l options: - Weather and Temp ##### PLACEHOLDER ###################################################################### - weather: - name: Weather Integration - description: '* *"SYSTEM" - select our Weather Integration*' - default: 'Default' - selector: - select: - options: - - Default - - AccuWeather weather_entity: name: Weather entity from HA description: '* *"SYSTEM" - Select your weather entity.*' From 342a5ae1b85b1f61882522bc6c91020c1a292f59 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:43:04 +0200 Subject: [PATCH 10/30] Fixed translation strings to Spanish & Portuguese --- nspanel_blueprint.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index dd9f276..46a77df 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2609,17 +2609,17 @@ variables: relative_day: today: Hoy tomorrow: Mañana - in_2_days: en 2 Días - in_3_days: en 3 Días - in_4_days: en 4 Días + in_2_days: En 2 días + in_3_days: En 3 días + in_4_days: En 4 días climate: states: - "on": on - "off": off + "on": Encendido + "off": Apagado heat: calor please_confirm: Por favor, confirme - unavailable: Unavailable - no_name: No name + unavailable: Indisponible + no_name: Sin nombre EST: weekdays: mon: Esmaspäev @@ -2936,8 +2936,8 @@ variables: in_4_days: Em 4 dias climate: states: - "on": ligado - "off": desligado + "on": Ligado + "off": Desligado heat: Aquecimento please_confirm: Confirme, por favor unavailable: Indisponível @@ -4810,7 +4810,7 @@ action: component: climate.hotwater_temp message: "{{ (hotwatertemp_state | round(1) ~ weather_units.temperature) if is_number(hotwatertemp_state) else hotwatertemp_state }}" - ## PAGE WEATHER (WEATHE01 to WEATHE05) ## + ## PAGE WEATHER (WEATHER01 to WEATHER05) ## - alias: Weather pages conditions: "{{ trigger.event.data.new_state.state in nextion.pages.weatherpages }}" sequence: From fa2ef5173b14fcec6657a02195390f66030128d9 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Wed, 5 Apr 2023 19:26:11 +0200 Subject: [PATCH 11/30] Performance improvement: Temperature min/max - Merge the 3 calls needed to create the temperature min/max display on the Weather pages into just one call per page. --- nspanel_blueprint.yaml | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index dd9f276..e06c5e3 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -4896,29 +4896,19 @@ action: data: cmd: "{{ page_name }}.weather_icon.pic={{ nextion.pics.weather[states(weather_entity) | default('unavailable') if weather_entity is string else 'unavailable'] | default(None) if condition == 'unknown' and page_name == nextion.pages.weatherpages[0] else nextion.pics.weather[condition] | default(None) }}" - *delay-default - ##### Display temperature (min) when available - - if: "{{ is_number(temp_min) }}" - then: - ##### SET TEMP MIN #### - - service: "{{ nextion.commands.text_printf }}" - data: - component: "{{ page_name }}.temp_min" ### Temperature MIN ### - message: "{{temp_min | round(0)}}{{ weather_units.temperature }}" - - *delay-default - ##### Slash ##### - - service: "{{ nextion.commands.text_printf }}" - data: - component: "{{ page_name }}.slash" - message: '/' - - *delay-default - ##### Display temperature (max)) when available - - if: "{{ is_number(temp_max) }}" + ##### Display temperature min/max when available + - variables: + temperature_string: > + {{ (temp_min | round(0) ~ weather_units.temperature) if is_number(temp_min) }} + {{ '/' if is_number(temp_min) and is_number(temp_max) }} + {{ (('+' if temp_min | float(1) <= 0 and temp_max | float(-1) > 0) ~ temp_max | round(0) ~ weather_units.temperature) if is_number(temp_max) }} + - if: "{{ (is_number(temp_min) or is_number(temp_max)) and temperature_string is string and temperature_string | length > 0 }}" then: - service: "{{ nextion.commands.text_printf }}" data: - component: "{{ page_name }}.temp_max" ### Temperature MAX ### - message: "{{ (temp_max | round(0) ~ weather_units.temperature) if is_number(temp_max) else '?' }}" + component: "{{ page_name }}.temperature" ### Temperature MIN/MAX ### + message: "{{ temperature_string }}" - *delay-default ##### fields 1 to 5 (Parameters) ##### From 9def80eae6380a68008be7d079bad85743d2f5fb Mon Sep 17 00:00:00 2001 From: Blackymas <41958506+Blackymas@users.noreply.github.com> Date: Wed, 5 Apr 2023 22:25:35 +0200 Subject: [PATCH 12/30] new temp field weather01-04 --- nspanel_eu.HMI | Bin 21307134 -> 21307134 bytes nspanel_eu.tft | Bin 6491188 -> 6477376 bytes nspanel_us.HMI | Bin 21307134 -> 21307134 bytes nspanel_us.tft | Bin 8065492 -> 8051692 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/nspanel_eu.HMI b/nspanel_eu.HMI index 4c03c6ffb63e252ecc1c8c164719b3aafcea617a..9595461663401c66dfdda92af99d8886634e294e 100644 GIT binary patch delta 10957 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 ai%SxhDO{4dOyx3-OA2mDt53zv8~zPblb^2u diff --git a/nspanel_eu.tft b/nspanel_eu.tft index 1368bf0c00d89e87d54b2bacb60ac228ad0521e7..6f8bf4ad86d88d347795d7f8765402dd0d895c8d 100644 GIT binary patch delta 75828 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]y_l+X#n@c=l%)*nc;kVHm)3xyidmJo^W{Ys9-c zt`YC@FG34HdiZ=rBc3}L2K=Kl|ER=>5A{suJ6QEnHD<^=SoP3|HyQ8BiEs8UmR?SL z{9P=41t&foPBWK&A13vlyY%3>^yHJ49z2(xyz9hMhnEKVq)P)lV?jR2iAS*-I`N&} z4V-w&Fcj>*AI~rp;JM`FT_>LX1KxGwT^-knclm?R!jBDwJ#IxOo&y*P{G&7PRpP{l zdS)+n!-;3Jb{`@kBYyWj8S(G#Ll9)dH+`SCjq*l(I(%dXfj;s^HwfSv1oEzL$o>pM zWjupGp7|s!-q4>xAYZN~aEu{2)FY zy}Q2>BR(C@Fr&nX?8G#~ECrq%pGi>y&nQ*KGfL!>qJ;j868R(}KE2F{uX6~q+qT~~ z;*0RAs;|Uzwu}YUc(lObb@>M1@uLTM#+vnW3Va>>Bapc^vXd zp#sl2RmOAi$R~vg{TV9qff0Z6zsijG83%E1NiyPjWG*j9xJEpAhKYPGo?)0A-ZkP~ z9oL9=`A*RBR~MI(b70qqC(khPz)4{O&oGg9jrdRp|5qPeO4(}6kWX+a$%s$;R7QNW zPZ1dz@$pX)nF>aHI;>|#hMu=;#FPJD?VWdA703GjXZOGX5m6Ks5m7WTiijF(jIl&x z7rVxWXOAU{h}cVrf<{F}1PhN9uy+ItDk6f4C@S`@SYj6uV~dUR{mje(Pkzb$eQ)mT zCcl4v-n-eE&oj^L?Cdk|GdsJ7!>>#oa(`5?5Rc>^7vgzI-uJu)%Y}IB-z~(uKjf3G z|6?JZyYh>`T`d>lxy~;F*DV*~Ep^L%V$&r9-t=QUWa!&_Ud!#{kIzYfn!^RDKl+hZ&E=zz|fIZLxxD zxekxJt3O+ZxBl~WcwP%10es!qavh%Qd<1aaavh%Q{4;^;mh13b=bs5&=aaR9NfvZI zKDhq7b$ASrKU;^Ft^dP1Jg=S)9A1s(Iy~3;0O7jjI=rQBxejkxkL5bNrT)8hcuRxj zIy~3^Y#pBK{DXow$Z{RtvK~H!3qH?LUM#_&{3jh5OmDCbKQl<_gRL*Ne%O4l_1_(& z7@CGoS#nZgcdf8=iqGt6wHP}#L1lq(?2i1Uruduw$ujSce6>!DJ<{ofeJ1i#`ZG4M zjm*a&f6gC2_%cuC_hRL?o7^7Rq4bF7*q`}_i z93+$JB*p)vwTlSQqny!-3?~du)NsC`82x<0(7@USE;A_ggrNjwA2-<3o;-tn5iXic z57}?{?+1SD(v^TbF$0q;j6qCtHu~wM! zR%rKl6}2fm&tPS}A60u&M5dvH5=e7T8A{u8#bk0++~Gx;d1!pVeM6n9r4?tTtm3Ma zQCwgsicS8jhLopLU8!PL9C%x5M?OH^L#yHU7DV0D_l0IpzdbbAt3#_%tjUm|FX_qH z&z|HvMsuSfXJ9DlNp24f3D&7F;Kx-?qX#~`hS$-@274uy=AJg}wjPe31-LG4elh5s z2It^7ygKDPf@2vk#%5Bjvv73XZM3Jw*>EgF{m#Pi5Nx$bIS-rt8aUcsfa4)AN`3;z z;Wcn8FO8wQal|1xa2!t6&l`5@OV`Bhc}>b#YjC5>7vWU8CWSra&4i%_ow>k|wiHKe zkSm(`@q%FoHQlSZ(w6l&&aFwBeW76(f+o{SbuB5~w9*j)uDW&VdULv%5-n0>ykw|H z6^6sHeJ{dvz3Tn~w`BD| zf!l78(wR&N`DXk*MDb>(kQP&^+st_c6ovV#BRjeSVxPu<06L zWEacGAK4cmnM^+wjO%-|F@aNvTZD$ZRZ8bRE@%?=qk3F#juqq8d*?$2U0uPE*8f&3T=@b<^hW^ z6c6Ay)hYN64(>S+7rP2tP?U=%Qz| z%bz0c8DRE;y#&yHMcD`Ds!gU(NRutSFAv6%rgv({*tCY^F&kvz$g$_be}`x(sHp~Z zzKd?WK9`e%gDa(>Aeyz`*Bm3#m<}Tcm+JSmpqk#f5#ZE_8jeGw1ht$SQP^p4|izu~+SMo*wlV$1&<@;M7n=f>ir;t@RkKJdl>TdH$o$+Uwo z;>V|+z?eM|M!~LwjmhggJpG#BE?*iO4Tq7lOZ98Q!M2?`4bxoJzGj}3!fe50nyCJi zKjd_i)hPuda=b{pZTfPH+?w!MhY?o=S{Lmb0Y8^9{JcQ>ib#H-Z zqPnlZQ&O37&7MJbj89N=)`>!H;1wjl+Iv z3yH}dEhHw-LwnRhV)AGUiAh~ciOJXBNleyk3B0zHn5@}SVloI?PD_c&pq9VKWc5~z z^~7d@$*RcyFPPK^pv?7FWS4;tT!Ba~`~!&8muSscaBFfIh!HCA$c29fk4ZREHFA81 z!TJf0T>KmGXg#D2XR$a~quG48azt|Rzk*1;Q(MrtEoIEjpVv9Hm3T~np$6T4kCVJ! zfX9@!a?vP4cm4cge@L-6bD??hdYYmwf!WyX50}Xy5jbd_3R% z_k0ZQ!PsVO7JU2(+5e4?hf$_xPYXVB;h*5+4?P*X(9?pCT=+-$XkYAmd}w0hmxr3( z!`xa-Ai4ZE5K^CndaL!am_TyjzeC3%y#U`{7IYlaOVZJ)H?T=79f6}ybad)1>6ijz z4H{Vj#!qxi=`AOaetkIQgz?h^(yx!?W2wHJa?MJ@^AjIS^_6@~fzgW`OT+kyk12g6 zAAS4rn|ERSG=cQ(Cnu0jK8#JJ+s^R(G=X&T`4d7WqvU@?$b-W1uMzTy@cFk1+4#Dl zwBqw`12R+8{+|HytnmCRfV>Eg7Fdbn5pVhLUjdSr{~H0Ba>8g`#3-BNHULZ;Ao-YQ zlza??7BN8bF<^k?Aqs4-eT>d*4 zS!@W9Jj8;LT=?%WG6^+R8*0JGq#<(2aL7==6NYq5Eyd0CkfHMC+Q}F2^tHITcJh^M zOo73Rlxm2%Pi#!_m2C7K#tA2kpV;U-OtR6*j}z{U=kM6)`67hQzUzs*IjV6C*`|8H}#qNx2Z zaxrhJR@zoL{uL~Gz+x6C4Sn_QFn{F(Hwa|`O1w*4^Nt&z8 z7^F<5xqO+j2_=4~ty1?-A)l67fReNR?vKd7`qZg837n>6b0}D0h(NOu21P zM`AGLwb2so#>2E0+li@ku&q|nX0#~UoIgDHDk8v{iUs4@NYi$j!R`et?$hubdKztN zhtqmCl``9*6~mxSokp|UqshajQ9^svdJS6XpYa8TpJ`GDl)W^KqB@|g2JQ6E)Y}^^ z=4q2DPDxQH=nSTk4v(>Vb=_Mt=u1w=BI$Jcwj*jRIi37FqQ-I1wqiRyoxbdZc8)^Y zWO`N5&MloZgUvIDHZvHtd!d!1nw@c)&!$u3&T#KE1IvEcHqIcmi&oL9J<@dAk1sMc zpujF#xSBqL9J->3$6={8lQO#E;KygsYpxBSi7POZu0F(C$mwpVcKA%n>ZaWel-W;nQ!C7+oPJuOL!Q}IKMWldMhQN!y_-uHeY6DYOlV(Id^fOn zO@GZ<%?zXD{?NzHW9*L9Lk)OF!t*B6R<@ry=4xf>s6kt(cMZqe(BWj%(2cI)6sDmY z4??REL2ZrD4u;b>BeWqAxSNTfj7*AQVoRPhNwxM7`4j##$|)oIzS;n_@_tOc4c<;Wrq;Yk*j7Ar`_G(#64A zW!12N@&;=OcAKG%TZAt(ETZHepl@DC_kYmttFISP<`7(?cd(gEcB(_cHOd`|Ym~Q$ zqI|XcHfkg{S0u-MMzKDTn*G?E4s*MYL!-s2ux{$^4u_b-xk3J1qOpX1~ zr-v8w2V=Dcps(#mXwG&#Z!&$x>M#nLZ*U>s`G(@udxSRC+IIUz7wv@6)qC+Px$CqoC)6!As zuArsHv#1JUF? z9^E!HhF6`SB#H-^6fgl@Iy{ElCc-vS*fN!~($;hmY-3|6XA*1^h3&rbSlWsO!uC@P zB?oE=E)7@nI^{nQ{i(!`1E6%d>+zi8f=GFQ{FV# z(uHj-n<#A+rfY!?{%d6eBe73jOPi)+VEeD-jY_c2h1QQckHtk@J_8pucP%B%fWBlM ze+9vPJao@iSgQ-4iC$c?j-qB_Tz|b@R`?V4ch=M35RB{k>uE*^y1wEDJOSH4SC6CX z4YS}>aRd3!f*}cpiW~W4(!-9YO{O$<0h}C#PmOW2wWW5wH_BRPZzPvFXkw3z)OZf? z`ecjL%Wfq#RI8|au!T{_Kx6ZWfZ`Mw3Zy^SikA?!ilB?fX-o%*J8VY?d~q}Scu*Tizn}epwY_&+R;1=?-<*Ak|0O76m~IcbMZ(>6FJoQza%*K9XQWN0;RWt}NgJa7 zDv>eoM9Lr>vw9-skaonb^*-6mT!q3aYo+xfJKyYAg+IbsrHBeXZaK`;_mR&E^x7<#U+p88C=BLV`>17)`CjWIXcNXR}-LV35_%$3wCUzrtQSBtLK+4~a3TUjPk1j`nT? z8nfV#7=Jdk4>J~Xn9=cV#&VIHaL%<4lfx#o{2UBT()eeZhkEWXy@uv6G7Xpf2x9}W ztv*7Dn{lQi(b-DJ520uHHUIKHE_K{4tum4d?BU!Rzu=YDz-J#Nnii zL%WI1`Z#0X9Vd@?9J_c1dB@{C20)v1ob0yaJO&)6dfPG56QMo8=5&JIZAaOJ*V4w>(L`W5AkQJJCs3PEgKHG-l#S-k3+qQ!}m; zcm$rL^fV2j*GATt+QdV2;}h^W2l;n;iOJ9&o+Y=ZIO+Ivc(aL8ck+{dij$5%N0|qpk3Y{?nADf2XwEw1=~<4p%O)F! z-XQAcXIfP?`#eRZqKo!iz)wM5q}~TL4;|8UAQvTrFXATSBBLLlqh#TYtNJruG(3@T5_wyb)q^ZVhR2zL21is4X$!jzq`YL4|#fg==CRRreaPl6* zi6Kv>H>mnH4Bj*{6^0YPq3YY$C^iEQTdwnABlN)Ia6q0;y@f;N8z2TXI|PU2@8D4R z22DPJw!DOH%%X-T(H5jB`aRlmFbhkoS&aI8KwA!Gk#{DlZgdl`E0SXxYH&S;s*$G= zA5pd4Ex?3sAAzA!9;&vxMQ*3za2a~8)U!{+0eNa-LiJs4;~Pu21-+`OU2ap(8I-PY zhhM|^qo^h6EJ`C!MHS;-n_ppY{RO9?7(Z8Y?ojeMl&<>=zI9B&87Lik9;K0|o2qe_ z^<@}ZQ0EgcY|$C9+V%^DUBG#+xQn;f?@`-}I8UT$o0V~w&7gaXoxR6sn64U}$fHs^8rwuPdlJ?Ez!8AJXG1s2XYN zXp6!N9^y4PN!+re#P<$$XD3tuDkje!Ce?0bD&;lc4UMqfL^;~iZ4I~wn)Tb_}_UG2Uu4wf1vAnbfbS@$69 zfnaiiko1gVA3#WfaH^DXmqX@D36LD@OTLl-$$TjR(&ZI8{gnhr%U2R0^Izu!Wcq6f zkONRIyp{kt@LB?-)*Hs6-bjGddLsa$e+O;wZ*=u3pz`jGfQLTiH_Y#UquD9Ad`L@h z)P0MO4ZNTuz)|I zNsay{tS`{>Y(54!HISFo@W8h{h*EQ4;MC9|PunsugkQl>gd%cb;Mh=KG0J?4XdQv~ zaBoPRQ$vS5O*w%f{Ee!x&8k9QpF|74Q7P&@N*C5CtP*Lzq82PE9Wzn=bQoSp z14oBCT}S>O;n39zudq_BmvG?Z&>>IdPs70-FKvEB%4--nI#hRSYHY$#TL!(5p5B>o zt&pZ?XV8|RdWBumE42A6+A>s64vH~R|Fw<62H8-iVyvvIZ==wGbEtMQ#K&~z4XWkT zP$%0^mTF9}cDGg7Tw3`SI){c1d75_tRo{o9YaxZ&T}0LQZ7J3YrDF>ztSpUukJ5qG zD2+Vzzl7>1*eUFuG;ngL6YOZR9uCb5D=dzheS`xChYoqFaRm+z_6iFmM-vQqUB_8< zuqSU@Bi_t|-nIzY6*7A0kS5br6yAjIusAQeZN#+$IMhu=$j#1}SUAuDZ~0>T%>g}d zU31q>K;qPOZLi%IMHMy<+uEX(QP@~ftyGk93d7?(w9ktvtXnaKe$0Z$>7oinXTf6{ z)C<_G9BFA0cuXlq$wlB%+fiZDvF&t3SKNX}4J1a~g2yjV>latp;Ns+46dpGnDXb_w z7D0Q2&AEg^W$(ZvqPRj$?!coJzErXdTSf_L=m?MICCJCocwhGlC5ztG?x}A}kXH!^ zA0gbl2SIV7JSPa&PKeeA5DGa_W+`Jr(b8oUOldIN$KI!mLVX_LKoDtLnqj}qGN^IL z6i$LV4~e2T4QW=_TrdRq=&B?6R>ft1!2+D44BP)gePSZ$X^|^#L;blA$6) z<)0!Tn!74&o2x?Co2P91<+sGPzolv8L<3c{pNIm*dFtWJiQU5++AL#!fA(Wxle z)=go%-O$v7DB0GHl56(xICP}t!L z)b<5RB27)wP}1F9VGZ0BdY^`p?(XFC5<_b-L_IZgLAda_hYoovnvO6UTv1`?qyZ0H zoz=k=$?G+$u2o54tt-*v*Qgq4x_K0ZH$W^&j;^SMlSJK6iSpi{_R*gy?3UC8NRXEx zY5cjudeH51a1bDA{J8|l9_W=RzC3gR666I)tY=hK*h^_>e-cNSQCYA=-|Y*9`F%mX zKcG2COO9khY(&BCs6}uj^9#w5Tc)f~Oh6AUNV%RdB@mF7z(s z{<*QlB6|!-WF<ZLHR8W=v8aamKn z1WNRwH5B%?1~s$+8IYD3=~+`@X{33g3W1THH3dejKgZWY7EmoO=zI>MLtdc7<^>Ge zmx%3asQN`M36iug6;`}9z7kN|43boo5FiPFdH`EaZ3z;;+7cw?>L|<~+lo47kd#3} zfaC;Jx4H`JP*;NFXdMZXKxmoRKGrpZWC9WbB%bvY7K9BiDGQKPsV6~_1?|iFXl{Ko zNUqj1gCrd4U2G*9NRWiqmmq1}zzmXa8%U6}gdjlDwt)nRHv|EaE)66|4EQ@c93(;5 zum8pj5{MEcccH#TMu6lp5&|TSP4Yov)x->v#*n%pBS3!AnEy?0Es>mVxyMi@(KeHX$g_#E%7-_ zS{p=`fXMQe0wUHwv{Kk)spC5g&N}2JNU~sPN446)L4YKyl>mu;V{3(#YD0;?p?0JN zL~O>iQCMgjg@zqRc#df!36cY`FDV^RgCGdD2ncYrdtE4Vw zBgjjNShZK!C|cPG4uT?9?FB{jXQ4OkKpuH$3(|rhHZdI(wx7+3G&a_mAA&#`1hz#niu(O@b6OlokB|55iQP@(t-4itkbRaJ$B5zLX1L4Aeov+pH6R`rzh==#0F)?hpLy_p^zkr4Dy zdtn@5o7PLxBky}jkL}Q`dV{;Y&Gd-vWu}J_Y67-g$4rl6 zNQi035vVTs234EBk{$>9NP3LvYo^D9zLFk+5ClDf`bv8I3_;K%q_3cdOQa_0k%0XT zbDGlxvw6PQt%IF9&NIXp8;-dWHxxHwNMWPXV~x&{WAVj!2O~L*#l){W)I&zf7;E%U zyBp~>G@Fmmh7Q0;_r_Y^>2WCi(MVb2P&#IS!gdd!rQ=aLW&j--kJ4|UISy3lcvqB; znSj!72T<$;V`9l(17$PGyyq=hLtDoiOWSl8(y@ZCab!<44zxRLE@w4}dQZYcEd}qh zOfn|hHW&o1V-u@jR-Qa{Yo`$p_OK%Uqj9;e)nG*7Hm#i6a4>lX8t)exGngOPNpY4d zPXRv}x2O{aliOt20)?$$iLB`q*n$RA&J@^w7Pc1niY@H2j0Wp8 zSn$W3MM?gspu$X4lQxXJW*YC?)bZnPQKW2_53xFh;KUmEQCzt4G5r|SfiUdAb=dUA(~bMU=lTwGPWU_Rs>MvaA?g(DlC2^y$grdd?aPXLCc2L zdlW5=hn78(9Ok2E7L8JvO3F<1%=P(L?O23Y0JcN_dbGkeNlFQ9UDj9OP~!OudplQ$!;mM;o~W1FWTrh zfq!N>hNJCCiD;wa1aeyjeGl}{>2?J4>}AmROrYd_(ECqRaCa^A&?M;nCsNLG)UBVS zu+fuf(+bqBpG0B%QFbdd7m8niI{GG~?AA$?90k4GkNn10=%LZjyZuN$2T;d*=tBd^ zB?Wc7|B=FCPi$wB;jozaYHthPHg1 zLV0UZc4H83=_qwMuVWp`ZVaNRBgXq`_h8CgkA1IT@;{1wzhH{mh`km}jWe(x1bs91 zLxaiT1fune8Rp@Oz5fgut{&9h~c zem@6y4|8OccAF!kbQv_8P#LAm@OA)?(#D|*+Y&0Hv~j46(g)DG&y`X70PhFzC=H*h zu)Mi4O2g;MDE%r7H|Sw9O1}z|QF;Sfn|U%yZ-j{`)d$bR{Cgg4N<{mD=gA1I60WdC z6d#AHAtJO&xQx(K&~clz9lD6nQ{f^)t;a=&sgt-#eA7a^ilUv9p_X5%q`GU_fj zUqq<>Ftl0=Xi_w^!}Dcy4qJfHvp`1Yumv(Yofh&tEcXN)OGKyBLK&U=p?lKv-OxpJ z?q4XQbLb-QN$Mgxhc1%QSu#?=3%jX%QC>u6$w(QUsnGF#u6?{79-XO?B08<{hz{Qn z6Z-Nr=)*}wsJ_f%OwATk;ySdu%widxX^Ula9$PG<^CWa0ooDba0FTZK(0O!TSuCTI zR>c@{>yz&1P>0}X%tp!4R-5qYE_K1tR-0s`=0NYe zSw?EkCK;);8GS{m7kM3=qqJE@YSS&a>y)~P)TUcxq-I0!LlKuzUPNm478$9Fw}Jqq zU4!{T@1x)V^^tQeAe*NNtF{wo67TG#RN;5O?g7kvbou;OPAX8L3wi zBu7i^#(np0$6RZLv>b+xN*RZLv>A=~HNZl4O)V z-6x|oG70wq`(>0yCdnvmvL6f5c%sce?VIeEQThwCj>$4gf7vfNIx`vTP05m@Gm~Y6 zdL6)$B)R9}YKRE+Iv^wT0`za``E%$ZLN6SU91Tpt;-=IEM*~wNM=PZ&EId_mv{I_% zXa=wpDrWwc)EnK#pUWNx>?Ts-$gox1-6 D9xp3k delta 85274 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 ZuL(HEU-Jx!zc;~$+qdPhb({I%{{YmJ*K+^> diff --git a/nspanel_us.HMI b/nspanel_us.HMI index 0be7c8f526802bf6b9dbcaf2f926db072329ecd5..ea19762be04dc2d481dc4cd04234ad85c166969c 100644 GIT binary patch delta 5531 zcmeH}4RBP|702J(O|pPS6Ov6rf=C1v$buokkPYNJRm1{|M6mHAL~4;%A&_W_(E=~0 zylgf?WH-5OsZCJuqZSE;@YD)Ps}0f?B+=R;l?1Q?wHg#qKneYy?7n?#NEw-_Gcsjo ze*ZapzuxY<=l<{M-s&094H}19=B*~k0#x|Q$QhIe4<*U+)T#RRS*iFT6*iEfR>q7hOXzJf3RLNw))Li#7R~<;P z_nNw)qw>E_O&{j;P2Kd=kSNoValPh_SmE-|9p9^OOPkS`+N&?mTJ4|L`{%abQ7z@k z{BtEKIdRM*^NhFPUJzd-OYXLKeoaT>lcR&`Pp@^k52ua`n!onVriyI4nr)YX37A0; z2nHcqw%zhv>*ju!Uii8B@r}Lk=GF>_U3Fkb9M};DcEo`labQOr*b#@_()eu|fFC0- z9zv;Pr!<;C6DgfCD3h`%n{p_Z^5{Es6WvUc=oXqxx6*fM3QeVHlPJyb}usfg~SIrM$HkA6UN>3*6=KcpYg1N0!xrv+3@3uzIRP$@k` z4^tWam=@C`R8Ei5WAqbRLQ82GDO5p3Kc(fH)uQ~+Gi!zf^Epq&HVzW8@46DgZ8$3< z%-%ziA0$Z;V&Mu`^pXgZw@DcwNhQAS6QPn+=8GQ)H{yelMqChM#BFg#Jn3pl8sJ;= zws=W;)VI#A;YK`pgg;&)wI=w#NI5qc@wOym(Hm1Fsnoa7^L9z^Sx557OSWyWO4sW&062`VXoXDvMSXmF)iB@qIHt0 z^h~mep-IXa(R~Qx8&ox;=OMnvj{Z)os99CjPwO7&ObP6HvA}87c868ZHH#}rjnnSA zX?bcuzZ@p;cO$i$T6Mfx)Pz;rwD2^g#4M(E)LKR2;|Gq(5!&=pXNW9Eitw3gqzGH( z`9$o=Rq(toJjX@W)B7>5t@OAYEuMI+DpIuMD6ff{cU;M$Yv&fLSZYy%g6~^YRQiyZ zp5%-Z#jli=i^f4ph}idWWteElzGzZCSoMr$=gH8HPE_0>YUU^> zsM0b=xsJ>UEw8OR$kwy^*f>E8Y3Qm zo#FS{fxf;qz}M{ozTO01*Dr;!@O3?24`0_GFdUw(d%O*vt$TbjJX`m8dzRtrIoU>h zYYuz7xORW#Ol|Z`H9o8^`C#P#$cZ@bdoGAAB`PwKEx+z9x6j~lHEcBXWW2~cUh8da z%7W?Fm8i3fqa(J(=of`|m4-6)+%tkX-F!vZ#Mwiok-jT}6TYu2;sulF$$DH2y3=Rb z6ga(ZqlZLGgeOibo}o8tL#tF%&(Y9FIU=eL`)`AL&Gkp)2g=?%K$zy?e(5}0@hKXN zTcF4Ldv1X%c75Qx1!9a_Aav@mu4*GyS9iKEI92s*`2Q(E3J$paB}n2~_xVZ?bO)3m zJ>UGsixNbi-A4(ccU@2kf=TC=AVy;^E9S@hh8uPq&=^pR_(xtW4jsBZ!IESo_NyJ0 zmlFFtHHL=TdWT+CH^w-7Dv5S6yR^zCV)Hzay=!ZskLj!0=%X(%>Gke*(dg7{Vv<#f z?NxlhpubkhtzoIJmK@%OujF~5*=xHfuu*Jy2N;>{ZMaynTFc(GI8Roi3aY{5UtL&s0DREfS-Y%gI|Ev;FsV@@GDRc8o(Ox6nGk}1?#{w;92k-cpm&3ya0X! z)`J(p2G9sLg5QEoU^8d}TYv^$0xyGC!0*7TU@O=Lnn4TrJ@^B74ZIHi2wK5*@CMic z{sjIE{sMM_UEocy8?=FT@D_L*{1vgCpQy;6w0l@DcbJbb+Jb6YwcG29ARh;4|a&uHco_zTA{{Thtq!$1H delta 4889 zcmeH}dt8)N8pqE&!!X=N80G@Za2dcGf&yNUG46QFT0^mPUFA|)d8@H7akU1<6T>hg zV#CadtVX--*6P9p@s^fYl3A7tR@=plaE;7Nt+Y%X_jzVs8Swx8eD;rh`FwwK_?_oG z@0sU4=e*;2yE()IwCSWAu_sESB;4U6qSf|XX%t7=@06A+V)PRXm1M~E%kQ6^> zyAllE7}8a0BgaM1i6gqx#cli3#Rtx>8PR>{iI8n~*~kVl^xbPOOMIA{YVS$JvYbww z6cyn9e0G67M;{$<0a)j-dY+`M+A^O$NQ$ z08haHPr(3B!2nOe08haHPr;y9lNAIT((B*UmT}fBb)$~F75H-*>^kMo4t)gq`qjVjurt9fn=?1!yK1Ls> zMp{E_sfli)ls-Z0I?R;|Wbr4@X5v=QhR3F5^Heqko84%QW~rBJ3yf8;G4QID6H+a- zFDw1+HPM8u75wkCgsczy`&uIGvDlXCs-)&fY%bbr*k_~Towi4n~Bvt7g2NllYQtbChwA&YpSA&=b=Vru53 ztS8B?WHnM#Anyqg0*Y9{o`zCy0NdQMUd@MHvS;~+_OhBxo0jiNwoUSyX>9vL=4)(k zv`OncW_PffNRyiP+-I)m@NQ|&U+b^2qvB>QU-PPUiJ0w7FlqUcSkth<{1;WK&a3r$ zf5Kj7sA^7SeW4Z=D_Lp|;tP^ZXE`>4nzbxqcK_2%cg3paUA)yTV*3=3y*#2hTf`^q zv!-w?Ckl*$G}EB*h6W5nso&UnYMqK@jIl}izHV!Um{anF2d$5a`GS#_>k{^$?U6vf zVxcKF&^-AiGe7yI`VG@$dqO+k8Ma7Lc~~FK9RIu8wkwQZB{j_zv7GuW@B4%qEtx?8IVF7OsA!L%!J{CsEM4>GS z2Vdr0<0LzlkO=SVh>+QF{`K3fBi^?WM&*z6`+LR^@|bYT>{LP)2sv%AafG&!^uf+i z3rR0!5TX!*f+rDDDzukO@hAEMzEh;&pP5F;9HBi0Hk3+e&&elbmeAf>NJyZNpB4Eh zr^gs?n1hX0bI|@K#|&Rp zIRuAo`^}+c54x=mR`F(on!Wvz{g+|=ZErMa860dv|2}7f+Ii9O^{^O=$D!>!W`Ay2 zW~a!h<;P!f40m1YHj6kdza{*pXxC3o;Ja#?MVy0g6FGx@xm-B!OU(6v<1Mx%&pl2& zHSBH{-s&6`P_2BAF!yrDXjazh94+1*7Rb1K_bBc?wyV`SM%)tC%}Q1{k~NEzo4hNw zOja&4%8U|Kq8xr)R+7&`+2$3Fkt)05M$bhBtZ8qoogG-=7-N)cVThy=HacFK*bAYA z%vTsCd9ojZeV#V<0`#JHHSB(2JH*DeLT3kfi-gTWNL;K7yidV<1a9KH;@t8raKey9 zN~5G)a=Z5~@ou@15DE8H7-Uq0`L4^}%s6R#V_sD>A)F^4#)r^dlf`E=zYi zlQU0|D=_kWB-&+i%?11n4JnftC2_J@FhAjJ@q6sVS!Y6NHB7-b0YV;^Yv6z(N4#Ii@4dnqB~!ggJ&`fB-kfAT zB;6gR!?A{N;pK5{ZNF+n!vP8RRpDc^*ZSQ3%Y?!ZVZII&DC|210b+ zV87>4%oE~HMz<$pd`3(-XhNC1vmEM;OdOoxU>r_RxQSW=uVTCkg9axZ6(e}> z!=$l7kZ;h#NiTyRp*|1a?{ML)UxxAw4Gi$#cyO>O;>L~nlS$@)U{+C8J(lgSc8q0h zRn^;7W8vGKg0)ftp9An&4WFlZ_nEaDM7(yRVQsFNpWVDQZd)Tmm#qD=S zvg_BKDn4_I z0eBI333wU!8}N7F72s9iAHYsv7w}J@6=(z8z-vG|&;h&-bOJo^2Jj}Z8`uN91-uRH z1-gKJz&pUZz%Lybl}%J^(%h4gntl9|MPhBfwFh2j~Tk0iOV$0-pi@0zL=6 z0KNpi0*(V;11ErQfIi?`pdUC1{2Mq0d4-_iaz$#7q^_X>fX)4MJd7CQg7W|_JW1u zE?pQo`@cW`oq_+(z<+1pzccXP8TjuE{C5Wae?J4&W5HM`mJ&;irNv6cO2^8?%ErpY z%Ev0iD#j|s(qkF1%CRc3saomNRxCSKBUUq3D^@#JCssFBFP0OlAIpt3h&7Bg ziZzZki8YNii#3ns#lo=`v6it`vDUFRvHV!uSi4yJSch20Sf^O$SeIDWShraBSdUmi ztY@rO?2K6NSf5zmSie~R*nrr;*r3>%vB9w+v7xbHvEi{1v5~Q}VrR$BiJcoeFE%Q6 ze(ZwSg|Ulb7sp1&#>B?P#>Fm)T^hSAHa<2XHZgX2?26cxu}QJ3Vpqo|Kj#c78~U?$ z@vySanA)ND%9?eJoLt(49h|Dg-!yXSrkIsIoib(Gg!9{V4!6lS)tWh@Yt;z^0%gmk z=6l}O;rzB?duBGZadOPqZcceK{A#Cyd99gqp1C~F8DTDO?u;^xx;b@B%dpeVWaK%Q znheLOVm{>Qi+Ro^rpHjHs+rpYrUK}1kBYjIS$tPQVH)49mr&+3pGc<^tNN0bjdQFiCKr2<{g zKJ(&AfgYcyUzQPgq*L?D%LM*BW9g(|;PG2FO|KI8_2v!NX9h0*;HTRIfoV|fdH7z7re+fFkCvU`O>>+&u6IcbINzspTKBlqyxJY!nO)#LFXDOYEIBVymopSy6lr3{ z40AH`t}D+gohh6loF$x1#PDvg7Dsc;gWWK{bIa=nv9I0GWDIxG^Bz*jBf^J;j|v|n zBJ@dXarC$)Syf)QiH{`BY#i>C%iF2Aw}fvB-xls7BK{p~akSeq?I~|Y_jDR2Fs9*m=Db(O1|<*iYD>h#UJ%THV+K#1R^ZZHpV*yRPMDV45c>Rg{;ql$S~?FI81uDx%FI87Ys$7zhUP=q}Sa!1ZrhxKNdF7>Q%1fDvc`3J#lb>?!uF2+^@lKXa zOdI+*nW1ZUndN<)nx(JZl@f59t0$bGM{%XT&ZHo7Qs=akz{!(Wn-O0}s+OduoUXjr z^TWX|y5~z{(gx?G+}t4$sEotl%@xdd{jgg~nT-BUc4&IKY2F`c3zqMtW?X;VbM-6Q z+yz^byZ+hV`B$i8MboAe-nL4i$N5g1@HrLnTEX*#=L$y&&nIH_F18j&7gV%~>%xjQ zag|y!1j!fgz2(ER6f#FRTR2yEJrSWdS&O3^T#_3r+T=wNo4dk~D&%qDW5QL!Cx{4r z%32&f>5{CjXzF#tZY4?E@Z0LWTewTON4S@WsQ0bK(K~MZyA{pJ$!>g8CB?o2y`*Tb zPC4-~oyv)&%>J{S`esZIrzR&bo)p7lE8#VQmk7rRFBM)!#4BEIEsn-lva>j$lFf>x zOwSQcGc!NxlndXgnA?T73GWczNkr@dYjJd!%QCN$(jo^_xzNcEuT%fO37-)@D}0WK zxEHL&(ep0D`bst(Y8-9DAF2Dt!oLeY5q?TU*nVqq^qEWWc_o_#MbK0UFdRrn?_fw6 z6s8DMiHI#@EsoOC?R1n%H_k}p(o$yZAiSrlwrQrAJYjQTSlEJy6xfDVDX^u>(hBzg zb08P5pYO&j&kv#ov7ReUjYr?IkV+5hKRur|^l>#~27|Ms2j|1S5{=Us~2m!rGY&3$k7b#vcU>E`kCkl&7^+nQ~3 z74yw`NPe(NesxEov2=z_ey~h_#VFi52Sar-Y~n+x5?|L0yil;au$!=luz-kl>uoKL zdS=)?+ABkek1rl%)>7)bR6*l~sDD8@K{%0!;7Qiv=yI3liVUSbm!`1_x9}Ybx=VPc zaGr2J5y6YB#nA$nW?_bspG%V;epdaT7d|IkFDxb^?qzFn^n%OqVusS6cRfsi;ZGFv znebEL=fZtN#C~Zlj`q7O2Qo~wyVJm9Q5l(+f_Ez1+`?30DPd_Mg3DWrqcW!cMOd@4 zmCcBVWjSybKG!M5Vxr?IHm{!u1_=8L2MPxfK{V7_9Gz(?2Uk{x<-mH4z&jOFY~EzW zM1+noDl8--cB-{FDzYq7D%%VT7G~JICF*{!&a%*w4)DkSKtOV;0BR_A0 zx^EJ06mAy2Mnu?lYjL#25^Sxk1nUwsu_fj~#T*iTBm7qQ9TBldt;Nw{%W|Z$5-eH9 z4RUJR44YmBy@Qp78Nw>UszhYiELvsQYE^g-Gz#KALxLp>Zh;0i#dcIoXJIE{7hzW- zMo?faj=G7ZVW@i*rC8EnwcGtgj(uD#PY72DpA@bpg6(N*akR$rHhBu3|1rn9Gw^?1 zWd2g-+p`1z?@P`9AjvKpk0d*C0xFKK6P&7U85uES&vB|V$>QU%lC5X)Ik+2>Y|~I7JaRdbEUc33Cv5z_icPYx zB^9P~1uD#xsy5LgoQXECepS3!uz@gF*ihJrh{bDWEsh$SXU2iLNmZL?K@iWgc>@)5 zrf`sOuy6!fS|#z1CVBO|>l3s@g1TS@QGl zQ}?C9`-RJd4-gUdptU$!ZV6UYwMo{!7$(`g%?jBfd`-AjxQ&R=H>}0cc1!YlRhwhI z8DUwP_pM?M3%?T{5q?iZ><`xB=%{5mR@LTMu$1IjoWyf%I9v^(!Ir`n!dAl8L=d&J z7DsKW+4sc!YBtG&CZ1%&XDjGj;W@(dgrkTEzQ|e}o$u0IP|app(5Q}`ss6KtvxIYm zbBTzHS&O6VU4|Q~*)(ehk{^CV{T~xPDtuhHiio&1*5c?1m*L53HqTlHn`gssDQK7Q zZQ*X=9wLI@vld5tU7B~Q*+dJPl0^GY1^r9-v+x(;uS6u;6SPXSzhNc@BGFc}i54vJ zM4MNqI(h}`3F``Tg!PFSLL+N&lxwbca3?jWZu2Zym}mduqx@YWnJ=6tTp(OX1lc{- z;^=PCHdzG6|Cnao>;Jz_v(y;>v(NI+Z5zJOYK*>5^#4JcJ%1|FZ2B~$*!*2g$r(+> z^D<}JWNe2(@T_bz?ph}&1bgGPPKVID)osd!Rm%P2K4*^^d%jc6?7YrtANsbs3C=(X z^+I*ic!tw1l%Hw4!$xO7C`ijRcg%1aRp9IKb;_oswl%G1IL-Y%Pq1hGOp`Se+XqZN zW;)&c?F(l*H-&D@HrcbBvuLk&?Q5>hnr;18xpuQ_Gv`?UB-d`5mA0J+3|M+FmzUzj5vNH`xBs8*Tiy8|~}VjM;t>*KT)h?VGH>(6u{U zTlZ$`pW@n`H$zc4CzJQvdBSsrqlD)ZaXVaWEsie8wCV7|Of&2jJ9E1EBUPX_-+v1} zht5*u9N}!?Tp_e^aouDsxNdN{Zp<{lyIjrhbefyGA3LQ@{~6G=hrQrH`|aga=+r6P zv2D0R>u_7dJu1G(g^vkW37;UM{V8j4^rZU=t252}w_<}~oiW-5rsi!t+A><+=e-V&A#2~ z@t2*hzTI|Od^@&ivn;dec01HBZg&RrwOZd{+s||D>^rbzmtq> zM7$d?3zV&v8Z0YsIbr#1bLTw!dR((EZCZ!h;J0J#@tZMZny~t`6t)ny61FDdqT5-E zqc+*@8+f*9KOfh_aewJlEuJ*rSsr8#EWgmXjvD26CBkH{cQFM_Xz$Rrb`#pvqCkLk zci9GIg8AGW9l)+l;&wRyng9i%K(K$d*>tzlpwd_bjnzagACwyA?jPP$n(5$Bw z&9g4eb2ZGr{4_o81wFn$U?F=IFil zN;B?rdUL4f+~-^uYF5*}qrrM_fFFfM)HK)ch3@_B{Z6IaK{fFL!J)#z!ePSUMC|&r zYnmEMo#t-8A!<7_dB4cpNIN5InuSZ9+!o%B^>(ZFdmuG9g0XGzUkWySfcqUTvwx{m zjpO=xsnaZU9rp4vCpWi9FEdSejc~f~S|WxvtEL&h%*k{6O;y{JaKKMMJx;W^vyKoGBu&)tClL`eMlC$&vJJ}U-- z3((v>w`ly7DOXIMSY)D?qg*&t(>(p8)6#TU=~NAus)hJq8DVK*Sz$RMF0+!gI4WPu z-g6adnWZc73&%rd^SzLMhfl&==I1MMi?mc=Yhf#48(}^X1Rbo!QCpX)T`kl7LHthD zN7cD?xFfz#fVWB9%fWL+FiLoy@Oh8PAzKDPK z-DLJHg*t%Yz3{NpKDs?#R6g=YOdQ-T-U^Q-e1go(} zf$s?S3f~pJM+Ct~*5c@Wm+FIB=HRJREguEdFADrk_^a@D;U7d01ZvCT=!8r4XDxHr zqa~x-)Y&QBrG2Mx+s0|iqg}d)W)%bBxMHE;lj0%f{Q-~m# zZY_?kajB-(Ha9@ik7XTI2Xz2KV9Z8g8QCm-y1c8mDmxcHdU)$99X5I{Q53WQOM=1jVQD zdf|=27?C@fR=NA8I(7nYu4DEVqtqE!$LxH{=^TDS{Z|X06s{3IMFhh$v|?E6GCWdovz$V z3a^-W`IO1yi;8md5Mqw)cCuRjpK%)JX{X+tUo?*2gue=Z7yd!SWd-WO27|&75tryy zZYR|9PvJ=*AFOoBR!nW%CO_N`g+(V;7eOu<7YZNB+Ow0lXjtNtrSQd$8ta_ubL#6g z8VGZR4TX(}7)djoH5cX)eIscsZxdltARpdHTDR9oI-fd{cI@OEN#t9M1UoX-yo%v) zwOE}MA6e&Ilj5D38P7QzLWk>_uFqp(XVo=BHaIma^78aXl9Jk{4Xf$qW z=E7#eJYkrK*K19yUD%?Y-N!BK#rN^CVyA$w)cOUdP2Y1B=WRfI`y&u+376e~I=v*v zJH^KeZ{uC+T;&u_8Gm)8WZ(7rKcNDX%H^`b)DEcZS=LXfXa0P_sl$=gdC?ir{wfTk zRX)E^!AT9|bq`(%4}N17NaJ#K4_;l;fev(-RL|W1qSGXFqK?_}qH`f_&Pyn@VSB#> z)d2Q#*WTsYzq$59*Z%R6^LVInUGwP6&SKiGuOJR~tZQ#_?US%`xZm>f^mdt>nij?& z!n$!e^`5u2yrCSsAfA`I4t0X-#rN$33hbVnt7CTej@b#v=n@Fwc})broerdR0+jBa z-?l{%gFEY0y!+zf=Dg~RnB%Rb_fr4K05Fs8%DRasjCJK8@^X2^A^fLfG{ZKaTpCxW z_=*iql^_phZFH*Y;OI zo9|MYX2({fncwwR)js@64u%!nAbeH0QMieSVQ;0?us7Rb*Le*dJ|KiM+7@LJ|1{=@cA#>WEuQ0$K3jcbD~zO`XUy1 zBiH+Dl?GB8%TGl-y>Lo1q@F3qg^=7dY*eex`03f^)mgjXu^A>o6FPue)Iv_L5$uF=>ikCaJQ4wBL}G}92`Kz1gn0T1@i84v7|u(90+!3z^rzuGj)7n z#3{OB$`#IJB$@%aDq(8<8xB){5AOBuxi*Qwo{~g{>~-=(6Y;x&y-xkyu^P)|!b^nX zg%gOFi7RvYQ5nA|-iy!Gw)3UxFfMs#E!E|@rrSGCt>jCESDyS15+G*h)_1T}IA8mY z)2QyPAmk&SLpp^!dpQI%_rp7QmxpcrE+!hWxWC-YfRh>T;#1CR8qrqa7U4GGb|QB4 zPFn5g*K>7~)!6|LA4xI;UP;nVo3`OL?ee{Raae@k3y%no3Xc)-691spOB}Z^5&9w5 zJouj78vNah+4NR+YVp6`bGC0%>?^Q7QTl(nkUybu!{`KMJ`_Vk<%d@Xv;3&whJRGn;{- zK6?Zk2y=xEg^h?{Xhy3cHEv`lx=AB*Ak9wniVk?Y-gf}MM(W?lENyO`o10^?3GetHY@TXXN2b~XrXX{@NVHEB4`Y)XcoIP_cSuc zOUG%3hn{a_o(M-YV|&B6-uD#$f$)9dhr*ADVEmL;jDL3-KW=2MZQ)*T3ox8e|C7Q$ zg@MM12?mK^NTU@)sIi@~l*VTB*X~B@jv2ePWu#rGL1VL_rKNqa9A@kck@OMv7WNhP zBZ77it!VqZv;!KOJ6gGWqZJq?ssGi&tAvw<4iOARv|@<34AI7B&o_2|ZmNcXr60m? z2p2XsZ?(2F_Dls_?>dqEP56xPS>ba;(7r$`+UH%`^^MK4Hulo?cE)#>hkc7rTz^;4 zC&G_~p9()Cg606NXg+so_BA$F=ErGjnNQA*^ybdTHxb&H&nrdBh3hmyOt7A?t}sVf zp9s!IwBpQdVwa*p6EmxAq#kKX3Z6OXkqY5{iX0&9FB~WwLBk~-7vp0cEe`%-y(cXxK+4~2!=Ok#jxFFc)f|awu8ITJAmOk z^*`4SoA6n7$a%s+JYW8)q(}FF2 zZg{--F*YU_n($+cn@E<;Xk9> z>K?vs1Aew_xVamel|SR7s5ckq6-43}S^OJXQq8*Q_$OER4WWL8VE<)R&b6!uP(4mp zT~Hb&7XInN=yz;!7aY~h9R1xH5L(yFmNx5KnGt`Wnt{diW|{eaAeX+`%$7E=C~bzD zl_^g7;zlQ&)L`g9Gh5#vUiD3&IbJOo5(b4S!c-!bybP_DJgvFid!?G&`UVWDZtoVq~5k`fDL@-XJ6=RXhIHkF* zZ@{4X#;E^&!h41H3zrhXu!2?$%Up&Bn%nvY461KlZEouuoU6Y1RPmn+KNIc~?k9rr zD_Suga2da7ZtEK`sJ=YF08!(jA zH}~b)`UXzbH!q0fCE<(0mxZqoLA!}ow6D6f8}e*@1BR0N=755}6n-K6O87MqG~d#S z=AcXSO`ff9EY0vx>9DPDc+UE!F+?={9z)nf*i6`*2*#GQV$2KMB?yOYeFKIStZ#;? z{|Mo5;Yi_GL@=C3D~7XOhI7KUz5xRgj9cGa6SnmYoT_gYi)4xL9-$H5O9bsQTG8I; z(%v7o^$i%FW_|Oj`fn6&5N;A~CW2ubtr%W&8McINeFKJ)`sT~9QGEla>YGptgauQD zDZ(^iDI#dg(TcWo3p-zUm!?e%Ti;k3x4ywi zNqyspAu5ar3x!2Qa89EY=Mvu)fKw+7dm2)rHlBnZhh07;4dqA=}h1A88b-(bASTAi#ZnPF^>4?;-3iED-i2 zf}jtr2zpt9Gg{i}1_a*Qt*vhI#w&25aDwo1;T1$sT}>;hD=pQembSP7RlK;#o2Qrs z!ui65!n=uJSwbt8MV4i8OIzE3g|$syvAVw~d_nk<@MR(hHqwgV6-)4HOIzCTiaJNe z@*P*D&1-tct!^sTij+1tb-{Z&Jb3S|Yu0y(G-WrHHVNHwvLdA_hVWK?O$6`ifuI)w zzamOXorJL6NyGH!UsClXL=4aNjRz;C%+78o@OTYw&FL0F{-`B2N`i1)%3OzXIKmBM?MX;ZEfo#5V1bW8;M_V;7c#UvxMge&n05pTtKUBbDrr{9sHwO+wuqm zERXVLsQWD8OyO+d93lvAq!qzjOK^Q_TOENw)zO2kZFPimR!4c86#klUvv7-WD-nb{ zXhpcq5^is8iz5)QILiB0-46@D6CM$MPXxgav?4fa368b4wGjwZ8>P3gwGqx$8?|hM zfM9E3D`6X9J`sc+XhqnzjeV17*T&XHU{Gyzp8B6J93{L!cp(uCV`#;2k;`y#8(SNJ zLABAWHmZ$qs@iCo!j}sl5UvoeB!ch}S`j|z5MZEeJJ)<)A6f1U7J;SAwSA{gh=ig8xH zd2krMU!QMFBM_)GdQjaT7Ct0=MEEEX1W(Y4;4ybdkLTOc2n;2q(d+rPG=fv5(Ls?M z5`H86R`?wev`1-0d)TEtl5a~RFt9YrOK*!F!OFr6VHIIjA{er0#ejc_k%wEjdRto= zfuN)^YTwqVGJ=zpQQq0&I9GU%@I2utB3Lh?73=wy^@6sxFaklmFv^>ym^s4P!nwlh ziD0>jRxCGImK)pJy2!HBGOP2U``{#A7v*gh!4~0b!mYw>L{Pp#E6VMb^7Xd1ECNen zS(Nvk0*?p}3%?g0C4%ZlT2URdRL9%est8miRZ&&^IvT}@u$nMam_-CjEn2Z;x3gQm zMmt*-fu^J?>ZYI`!tTNXVNW7x`p}A|mrHX-J6jcjMyk(v^`9u5AiP|71rZEa(~99r zmtj&nTNZ(VWl?yZ`Y#a97cLauO$5UdS}`ng85ZN$7F2z};JpL8s!y>ZUlhI|d`b8+ z5nLN-#r2BI^=dm?7=bHZ7=`yM=nLTi;g`a%h@d${E1IuenuG0ZWds_jK4tNB8GM&e zSWZ|$Sdj>Z%Cusr)ZVU7dV5=DzC=D~Ob_r4c-O>zzxF>Lc`3edO<3 zH6Opm@xFkd0x2Qx(ypj85LZ$qB?Pzqx4~7qq542@Nx|d~HjBEUKuCDCt=;UadCTP% zObJoFSq3FUP3dl5MkP~1UzJP=eN{JMNUEC>`l@b9=&RxheKF6joa76r;f(cVnygSzSL4z_N(pqs6m4)?(Y;zWyAtuKz#v`eZS~(R+$G#2+)D(*`?O+s$7Oi8gRPvvpvvhV9c<-Z<i-lu^V~L=>j8?ScT-r-I+1d#V zCAHH{3c5vjv+!2oZA8%AMJt-yU79;O+1km{3=ggDWNRm$vv%64__u^_3f~s)B7*T9 zS~2c+8TWLu#S<7*JpDuc|0(=Q__Od|L@@kLD~4ZOhF?3`;t32T#Z!&Wws?Y*#Zz7< zd@%@r1V`9e*j3n#2-=>sqU~;?!*G}P=xl2z5U6$uFA-iQ98Uzn6|^FlU*X~puMWqH4|t(`23t100mUOR=Wc0ow6y0DrsQG*`Mble*aI z2{a|u(>w(&5Y87a6y8k)%@SJCEOKcUcd^wIXjDBFtN)9_7lbbfUnYWKBdr)-aT#9i zVyh=GsCwG3{$B_W2)`75MFhhkS}}a>G92t;t0ypcZ^v%+RJJSn2FnY}2`dOI62VoO zR$P_3+LcQ0YO5!3l~hmp3Th{8D{L?9Km<(}TG4cLX*zYa)e~q`Jzc2&7Yi>Ejuws~ zg5gqHF^qK?#&xyT6EBL@6RfJI3GRFEoJ+mx2_C%xucJrR6Z)!p^7lQxdP;~>^@O;R z>M0@kwCX7#Sk)7POR6V-u&tgF0#rRAz*{c2dP;~=^^_2$>IqS*o)Y@1dP?Z4>Ir>S zJtg#2^_0+8)e}b(ubzAXH9~IRV$APfR8J0z3{+2(RcyG`Q?&xOdK%gdf7Suj(_`Ii z_4H|XQ~C;IQP`GOSU+-06SLxqNLF}%H&6w?5FQYIDg27a-A`+Ge>b~h4|X$Uu7scf zdgK=UL&f&^*L1C0hw-hdVA<~ED=#c3tRSpN*^^+of%KQ47ao;*w zrST2CK=4p^a}=$9ruJmYES=*vUwBm{KeVj7EhJ%8NS6E??B!QSx`dzCMHCCy3ttev zNW^8mN~_Cy$-S(XyW4;0k7?4^#PDxDQj2e#9JwUaY8g9s#vhVVkh^??CIkcJF{0Ge z6n=3KpO0)Uyr;XV7Desfw1?>t#ka;b_Auu~@pTB;>Cs60Q12dg;IO9*d_!TR55xFI z(!L}9{AxS>bK+?|@an;9h0}%C31<*-DRXFbDKpIh?weUX%)%nPBB=Ccva2XkwdM-N ztR$wKJW0mo@;unX{9c4bY1*T>{uKN!y>oB6u`$k|^%T-8@mEAox!6ivjc3uRdv3Jw zQs=Vq_TQkDFR+`qS8uaZlNUtl2g{phiXwH)g3Xa~X2nK)!DNEsE*DM|ULm}ai1^9Y z;%HKV-ON`Nm=hZ#4HBrvE(Fy)1uhWI7cLauO$5ObYjL#5rCMBIHY`k_DsN^#5h)*D zufP|C#ljbbFA+ho!CD->>{7i_V1{i@pvnw?u9*G8eZm96FNlaeXf2MuEHFQ;j&PPT z7L|}3pMgIhiq*mH>Ke}NiJ)LZVFO_!VPhipRC8MGsU|(`L^bVc{#+EPmoQN+wqT+L zDR8jxOyLmWP$EV%(pnr1bE$^+G}9Tg{S>Mm>p*ph0xuI@DjYAIKm@^+*5YWQOLciKQ+dZJRFm%m)$IzrQ+S8) zF5x^P2=2BPNAq2(1-(qKXHKE|ZAYY{Idf*DPO!DPVrHa^nRb7qX2NVPe*-;^&y0*R zDLYG=^p6I2|1DC<+&3#S#&ml&lIcZ7p2c@#&X|pWv)=UG3va@Eh~BIR;@&08BNfcp z2O{Oo?Q_u5@p*qsmT5T`&hy@mJ5A1dki0{0%B~V`&t33Ny&m4zSH!)bE^pFTg1_bs zX!)i%-eT6Rj5IBtc3Wg}YEEP31LW~W$_wtBRygX`9PN9Xw0U@!x~sQM*IW8CT~{*~ z&4Xft6Xooi<{@XV>TPrOs@}!S*}?Fp-XIRXCfqFCBHT*En(VL^N85Va?YF(R@-<&< z;R1Y9?U4F^C;V1;Sa^hpxZ~F1=zEvpXm6!ym!Zj$>mudzGWu{FRfLs=RfW}vh|RVZ zNBDCXH{(h&`zS%XB#q6iCn6Q{Iw_`$u(PnMup1GvJ*~x2cgxbFk8*RI<^IiJ8LOB} zgyV#l3NIrf_Ht`+G~TjI=%eIJ7X7IX{F%Kn=Hf;8mKr=v(Rq)E;4$H&!pDWHh)B_E zXqBR$u#`{sQHG8WjM+KwEye5-zAfA>+(X20-m?}*do9a5eUzNzEKJOKKPl#C;Xj4{ z68=I&>>t+R=vT|~TOZ|RUCcdL@!EaSF<4hvM_5moLqu3ZYjIS+uiZ1beU*;Mpdv>3 zxQ~MR3Hu8B3kMJpJlI+s4RmP+^;JHO)08CSs}wm|c(u?GMu=dTVl9rME>~e+CFDdd zW#q+*Tq3+jXoU9?!LZC)9Np(~-QQOkIgv{#`4vTO5WXthDBMH@!&Yl?wAtl)t*=sY zBA0UVSBg9+{95>p@DLFUN36xsw=UOreU+0Fxs;SE^g~RrlCYvMU6?@xLp5u0RJosB z!YcigloPp>mDem%R^GYD&B}>gl$J*}$gJ9`VQJm6koP&C6}?g`0Uf?p9*{kZvYs&s~z4XWWM- zW@a|&^TfK{NX^GrM$S#mS;hQ@)cm;eoST~Oy46k1#r@5MN0FM-2iVlycd$*(uRe;@ zj1#2huA$}wY*vO z4!@+JSA;JMUlnd3BKS3HakSB;*)+f=XOD)-IsAo!z7l>Z{91UBh~V$6#nCqdOyvfs zoCnzC43<-pGd!xF8xKTiu&J<#u$izq5y`nFt&(%zKs(Xlfi^pPBU9}>R6)aq!-OM* zBZ(N#xz^(7ESKi&fi^vRG^(4YDrmZJn($iTbwmWuwiZV-T$-5!ZGPtUFh4I>|CPcO z!Uu&95fS&8wK#g%Wq4$u&Cg&c$ z4YKJuflKLmo+1|r=L;7K?+@WYcp3m(p|2YNh8MtG)D`&_(Ha+iGS+ zrf0O3r02NR~ zd9&^@l=Q7OMBWc?9gG(bZWnG7zAoHB#Ol3eEsow8Y`5yp!8V0sKuY09)c>gPd*LzR zaU$Y=vKB`_xC}oIwkg~)*c4uE2*;5rtS-zFW)l%x+gcpe7-Gj!bBImhmc>os-4xVA z*j-p4>`6p$A8T>c%cVJEh)v-hjZ*k!3Ys7sFPtd6oQUA7ti{n4F3pugYz_y_DLEV- z=K}2w1s5hDuF3q1qY!2u3AcyDWutzXgSYOyc*pLW@rq<%9 zk=eVMYTQtp!a)#E;duiTGe|g4c&2bL5wXLq#nBMUGIXfT;2ujngXcvQSSXANi-c2% zAee3~j;^s(Q}Gvrp?L7t(tt$81fF-V0`C{zCtNCAMg+l1YjN~|rCL7J=I;b5=I^{s z3VcntS-3^Gl?Z|z*5YWJrP@B!=I;b5=I^{i3j9v^t?;n$2oVIwt;Nyzmg?wGo4ymM zl)f{DAtYEuSXo$ASd9pRY-@2;eV7?>CTf&nHhU*fF?)wQDX@#Mv#_hM8xaIOt;JFI zVfN1LG0a5oKXu-f<~wg;W@Vbk>y)JVFSdAT-g|ka`8&3vx6-`lR+?|K4Q{1**Ikn4 z-({21d`VN5nYJBXrFoA>X};F$a4XGwZl(E+bSur5aJXsy(j910nnx4Ud@-u<*{L~e zm;#aES1T2|8UC7LH^aX?ym;t)k*i**@hj4JBr6bDaOmX8V5yUV3i$5z*kB+q-MqUX z+N#E#Xg)ayFxNJhahubNYb}iSPnlEMA71)opgh_m2ycgHoECo4(*G&?@4;YN{{lYv z`BiWFGf(kXa{Wi(kH0?p^Yz((AfE6SA6OhcBUmQGI@62umPBg>Yut&(DGbDuk6@XT zfgpT$nlUEYDtIS80!8P~VXuVYqZfxy{~A2w!-t>4r$1r%@N@X|Ck!8c4xj#n;lt12 z)4w?wFb~`tjbbe6_eEQ2EcBPN1J;P!;GDh%c+U3u^IeX4@bkAEeDDfA|K0GTiyriQ zJd6Iqzc?7UAb_^h0`BpgXdw~*XB8Y!I?n&}y>Q4K&|PTrLgFuMTHPPb!ezpISalVe z6BefINi**Asnt!(rO_NS`s1PuGkR%sZg3U;uv|2&2D|er<110tuEZ*nzRYc|j3;%GFC@-mjy-@`UPbd^ zjjd=-nB{VI`)@V-mSg*GHR&s&^I=x3z$CKsNIc_njLzKcTg`5-Ibn07nRC3=oJ4aP zqbHhLE2Bl=o4*n}nI1mlbBqAaF?~DmjL$LroMZa8;~Af0pMNL(=%Po^$Mfc2_}@y{ z$-aQM5#T*Y#5v{*C(JSYoMZa8;pv6MU)VhTAm(^0&4)Giqd8%Y%iB5LZ&o}MZDlfh zVJm2>N)w`3wJ{V4z_DZKnl%>p9T^ zBJ*IcqU!h!rkz)g-~gUppZF^o=TXe-ewq*S{y_892#=@k3W$J@ejNJ!X5lMS>Y6dn zU6Y;?tPtS;)@;@sc1y)GKFx?>PN$y_zn{}jKYp8EGVkcmoKAm(Q~X>H`tg;9lD8!E zXHKU-7cb>&DBkZx8wbt$*p!TN!HRZw{1G%cPexms(a&9jO!s7Tt_J+Ge_-h84Vdd0 zA29shfNS^%2ERApQ~ln6EBObE{@#G`9%?RL9gT80NRO+L9=G2-C8H)s%h%>babv{y z5`K|%^OQ`rb5F6IcMN{?2v#&Xx47+Id@34A!w1@jd+i1IO*`Ycf8*~Z70q0 zIld;EY1ZE|CByu=Cc4A)$hjt?RZ<}%@lS|3m*umBB z!OroU76iOd`l{g>pJ@0w!Sq+bGk()nGW&0LU)YPwLOXu+z=dbrF(q>l2j;cc@EXyB zeonkMhWNz8&xNGFGM*Tc#}@&gE|fPR+xaM&aZdDhQ))gIX!N>hnP5XRaUIg%P&yu4 z7o9t>Awm+?Ale=2LPyFZ+Og9m)-HQ*S z5ma9LO0<_{Jg2y!Irg_`miYj$DW76Yy=UPobvGub<+IT;X6UogO=kHCyj9eF4wKi( zG14!kJmb?@*{n<9yr7-a%Jz|X z;>S)~WwYOF_u|h+V|;EZn~YTMO2l(l4mQq9n4f;B+?C#Inicd-h0m;g3A=LFOVLfi zv1b0ucvl{49)B5Aw zx^pJkb_t&G4O+#__1Za;Y@diHe)Pcqi) zwviBg87r}ECvU(89c#vHz!J>c5Z!9-ezGXrT)7edZ``3Xi*n5Jy3q_XbVhWz>9D$} zMH=eXt3qbobjimWA*?k1onG zC$~pi@ucUB=xEwKe~)C=T!!JS#M66lDhlw=)X;u>CW7A!nFSx?dm-%;)1n(jEqa*}qUl}awA52kvs6vYA`9`#5u!1R=5go%*M%Sp2f;SXAy@&Vm70j`j z(f*-6ZZz!JorvyZqj9R}K8PHUB)U)Wn75;gDkSI8IM>E|A$A2k*I#nF#lU4qW^;+H?6E-?zn{tpcy=q=p4qs*~S zF~j{PBk{NV40jnj`lShWWaUCXKd5?l8U4Hh`V+1IeqI6n30D9=uYmr9D}bL@KtD2; zY4JIviBV?7=lG;SAD`Zx#Mk5KDBy&o$xp*dFO=zgpWJ0`3QI&x*`pND6BW#H$^(4Vj}@N;G8_iGm+__;FlC#($o zTp9Ww!peMq0QLI8JPc>@7m!Rc!$lc28Os%6pXqqUSERJ*8OEC~+qp7qzYb3v>Jch! zB3`=}KNIcv@!D5$F(LD}+PG>0co;v^I*V=^9yVmM{Yp1V1$GNz|JU$V%aM%?Ds?)ggh ze5`xE2j^z!H^{SyKrZ|SpGY!)k6RkjK0N8`W8ACn6VGP#llxQ5y=RJ%9@-L5nM`H zGrVw$weI;`_k6B8`BJo=dh z;_F*ZpStUq4$F!%QqaqO24^?_XK;q|7NMVy_$mT4P{R39^AdXNR&VMAD6$+I%8Ow_@ak|kx z?P*Vsxu+4F)+8aTJ6;IpB3^qSdZq0?3<`^x_aj#MgXKjT#W;E-I49wnE7)uP6cqlC z#v%B5&GaW+8~nWHWPV;V{R!8M{=8=T-H*z}&-}!c*@6K|2tkK;HY5krgM zs?lE&*B0M<&=S7pACh^v2={?bX3t@#gsVa@SCW4Jhs_ZDyej$=t_pr$RWd)XivEPF zLVsQr{rL1*qW**`F3F!Z(R6&YDBT@gU9;<7(4Z$jT2!VcU!EI_VL#y+&({_4+jg!e z+L^D}{xhC9)B~5f$!quGe?dEby!PW>JNEU%GgliJ+ZRPHUF`fzM*uX3PnE z7Rxr%P9SkDS%p zgM;^Y>iva3CxpMv7@taCKz)ye#Re*dRn`Z@FT`#%NK&zYycF2)vri-VtuhJOF2 zVD{&H)1ONrJiZng_J*j>7G4UB9*kh#q@RxzQxGg{qJh&DUnO+o?9$g7&-iM<&sCzo zrWR5b`d4b9E39=$E1Wy06Bv3UI{wxUErjbw|AbTg6iYl*)do?PO}<=~7z=v7B1Q`lUAdxdin4rM6IIE4BIK z{8C$}GNrab{^nkw@E-IR)U>or7V!mup9{d3^UH6bqx`m^wC4Hg(wP0vOJnvM@5KLH zDtAUv*gRIDFvHB=IdvA*i;Jv!5sE;W_-tyHDVSLVW$r;wT7X;9LIkfe#WyPM%L05} zVmpKlb8vgKwz*^$*n3nfyekc=#htEdvDH;A@C!;f*0wvg{nMfN9O(HuW4B?bKB2N@$!BFuqqX(kmx_MUgd^q&#?GV~2 zNqD;ylQBEmzd4!`il1zI6JG^CKOn^4sIyO+>t{#nR(7d)qwo>R)-OKhus=Us#W&C;aj4jsD!;^rr{?=?Md+;#rj~e4vva zA@>UAz|XdLJ^~XrJADy6F)qio0gpi`UmI9Goayr9f8Vs&xZ* zJ3PJBq@Sxszh7FQpQ}cHCSJo^P5QZN^!ud+`nhWKd$QH_O$zPTY3NKZezR#|64@#R z!V2G8Mwye%kX9vI^=OW?N~Ogwj<6%IfPTMhML(~A{)8)lpI1PC!WF>JE1*B&3gG7z z(2okmbk8fKZ1r?r;pws!Uz0nFeJ{e(+gbE;XVLGMt^9t!Y~|SifxLZy1Lc z@gDRildb4aCR?SrveoBdWZF??cewC$*(wD}4_9W2+1LUrBiZWD7FZcdHwi0)j$9e~ z=iwROTkvyb=ucP~__;Fl`(-P>AXkR|gq4AxD?>kJs}n5?UD;}Ot3p?{Vk}pLeWv3X zUlCWfVmnuc?S9!R#g(o6@iWl}KYE~DvK8Bt$yR8mY*jWMZ|1kgyH=?dsH>N^F5E%I zNJ3RgT&SAUrm#e)+R&y@Le&}hg{KQujNt@A+{y>3gev+tNej#h_*|jt<@~}Dp{hsQ z!V;k>#TBYxB~-yms7fg#p$exGs$eBl!Ahutl~4sMp=xxyLRYB5ktITec|as75npQAZ>oBcu+n|Wbt%osGgLe-28g|1NbX9p~`gsK!*sDhPH zMN44{Rzel6doH00=Mt)5B~;N;sH)ou*Ce3|N2d!_DR>*<_VRSM)B zU4_}$4T~h9>d$Vti5chryvL5-czGkm#|ytVUjOGk_V>nns^1&0{{tZVd*h{0b)q|N zVhL5VdthZHRHay&YmG3+Ni;~Cl&s@Tp9&33;~1ttkq{`gGRFfV33SFV9RR6-$g{ltm& z6U#WiPzC>~Le=hm`25X&d?FL*!FbLvedLMHF#McZ`u#!``+I)BQ03?0_2K63Dz{1mos**S}7wr_PXwBMz&`Pq6Gl=4exn&R%mxQYAg9=Xetek54{X&)B?-#1*_jvq5mEWJ^7pnXXexZtfD^#Tq!J95$-!D|f!%P91G1)X` z@(^iNt%gbj=|5Cj)wH2Ww5k*+DV+Q;o_?*0eoj99eyxgrPCos0u}$Lda_}?P(C^o( z*q^IGf39DvLWAy!`fOn;fYE~yOr7-efwzI7Nwg|<;{>ytU#p^@3q^lRJiX6`em~ps zqlcfzuT}Z|30jrE!LL=(pG>QwKbck)=P@UTYnfT?jo&r!bN%SQF`-IH(5li$Cef<+ zT3jN=`n4+hxdin4wW<_XtMbSBwW<`WRr#C!S{41tv?}_OX;q-3R<-MF&GW{yG5bf) z{;yW`zoJ#8KoH?gOo79%Rl%QBt4jF`t%^L{-sJfe_iMbUg`eA-e!o`5{@mX5`?V_i zxxMN4YgP1fd()qwRiPodR>cOYZKrBgWa4HglV7W%pPQY2zgFe<`?V@Rk6)|u`xCS( ze}iAEqCc5dMSn7_%Fn~h7%#8T-&;zbKP6z-Y$+W6es42XbQ6_yF(yFwoq0^FR zRqV(spbq5Ms_5qx(4TMx@be1jPq+g3c?I+*Tmk&N0{S=O!_<)J(yBI2Poh=vHMz6c z_aZ#Ks*rx}Ec*RgmEZ5zs{A~Dt;+9D(5n0mQ6=!-{)x4RWR>fGZ2>VROGrl6OR>gL%4BP!$RjR91`QvAz4}SDOyR<5{C)29X zF0CpaZ&u90yOy-7wX=L$Rcc(Tnm^m8RqdK>wW^VGl4w1TCEDF(yCykRl!QDf|XVUE3Ins^`2IRBUh_R zjcZlIZovMKR(10Y(yG#LOrlk>Kd)wuDe#*8S{0jlVQY+oW>>4a<3>-bsuc6Is#I62 zf|XW9OKl2PS{1E(F0BgZ(yCykRnbzbYI&2VRpID#ttu6tKe+uV>hPn8mwe&(X;tpo z=~@-Tc~dZ)k9fj`pR+)}U#nt&-W2pVK!2}_r=Qb8zhA4OpEm{lx&A6JH9@ONg`%UY zFuQNVB1x;NbbAu5iXFZ2@4Rck>qttu6|3s;T0jbE!u^=no3&YmG3+Ni;~Co3 zs@Tp9&33<51tw`#{`gHR+S1Vh7(N<$gfq=&xxi#VWQ#ZL_?CJ%O}}5O^85W-m7mA2Rr&o1T9v=SuT{}+wW@me zC()|nVP+Vbp;ghC+4oDUDp)EJI^MSn{? zJ*~>`XFGoM@bmb!D!)HLtMWJawJQ3PX;t(m)2iY;CVjbAey$(;C#)a*TtE7o`tKU}xqkHDm{6r8XjS!A zB+;t)T3jN=`n4+hxdin4wW?HCtMbSBwW?IBRr#C!S{41tv?}_OX;q-3R`vOVn&;gQ zV)p-h@V{Es|B6JvEpS{3|BwW`#=(5lG8?M+5C&+Scrf>wowo} z==bXh^mEnd_bWa0bJghg>k0I8)#&%Mss}eGXjO+_OQuz&K~3Scj577MBCSfR8of1% zR>h9I0_s41t%`nL0sRSA06(vQ{)8)lpI1PC!WF>JE1(}min(~3w5r|Pl4we%)q zT2&h48LrF}v+s4RjI^q{JCbNs?8ud&4&>LW=;zANpRh9Ub7koFYgO#em7zajW#H$^ z&`+(Z&KsUqwfqfFt70rygng#t8D9}st71D>hV6c>D$UiZ{P8o<2S0kCU0M~}lWA3G zmsS;zH&5@xyOy-74Lf~WRa#uDTJfe&tNQ#+t5sd{RuZj>F`PjBW52gRDy@n>PSOIi z5k6O|`s6L2RyF!5Fo+Mfo`}1n>FZ{e_zgER&Uf3El2hFZlwRDfCRn^_=X;o>i zRs}1qik8|Gth6dx_gq>P&ZSksN~@x!R@LJjPpiVw=~`79#2{{eia|JxCtvt|T9tct zx>m(--V_YyBc5>K=Pc0g*Q(f`HwFC-(BG@#>F2c2@7Jp6=S@L>uD=RQOVFy)py=o- z%)Sq>NYbk6ewak7Vn=VhypiJLh2I;m|05s!d*eOT?~T{5aIn8OUTRf!KJv7xJ3hmOW{P7I*iYbni->ag4C9UeglhNXjP2n5-{4YRngC>rr)ns`Tc&a%FpB1s{H;0t;*lv*Q)5Z zT2-rWl4w=&Ff#_t(5h(6ylh)6}xev*v+q1(a(jV zza^fYR^|7z9Y1>bdHht@bqg{^jC2Geyxgrt{?j+tRMVbKl+>c?;7~Ie)Qj%P^Bbj zRjrOB(W>}bTq4H$wJQ3#1oZp0sx()t^2hnLsx+%r`J4S(75&MyD*BUYRiL9*b@Zs_ zdEZgYex+mo)vEqiw5l|pz~R@b;7_VmrTv9gMILT%3MIedevKEk@N;|9@7Jo>pWB;$ zzg9&*w>SNMt%`nbZ~7CoDl{b5s@RZBt0EIOJDL1i75&`o^!v3czu&J_`FZ?WmEWJB zRrwqIS{41tv?}_OX;pq6X2y7Vh5pRPya1m+C1BTV`z;59MR-oZ^BO#-;yJDOU~u|^ z1#>Fx3I;w+<;SENfnjX|fgaa}0y9B#4$c?%3DnyL6BV$>cg2X0*%m=l;c zA~jGAFL)wQHt_nxkddy(IXaXIHV$08ArLrtXKLV9wBv8L2bR7a2y{4dE~xepj7=bI*;J| zt98LZhr8_gBAk!HC&dZBmMMN?(e%%{28+z&yQkML`zyA87PfS{*}HrCi)m|{p=>ep z_e`%>u`*=BPa&KgftqE9j3N2uiFnLFQ^zCQm6v}c7+=iQpXJJRKy7e}!*0|7-uMH3sMqOlN7j15dQ_KwD0(O6JXv7_F(g1w70 zk&TMPE*bT7Zq+Tkh;A#6*_~NeTH4KEX?B|+shWUsd0C8r@gO(aJ!G3exIVtKgO$0 z$okrnHA3F6O#zRv$l-`ue?|w+sm?{8;VO)KnJ2^P{)+!t6dM~w})h1;#ReolwPJi@M%gHE1r0i5=ci3jKCx?Nmec>;S zCfk%9++?S+i<{i&ua=|GbaQqhra!Ehbig-CE0w4*W{nSUql;7%TQu#^6Zgu#sp?xgw+)x4FNf9L+yosv(ZT_oDr z;lu53J5bYt-)i?}=Z4d0%5h7xMm_C@0G)(j-+qp={0Ja)cZuM@w%x5~&0KOgE!8P5Q~H7G;1wFZJwv z?STy!)}qX_OcQKdgd2{}8`F!8CY^0>sI;iD!M27v+v?#{*lSVpmNaju z-#p0M&iRQ|uZcmtLRZkH<5$=WTm20tzCqTNCY1Y=DZa@9M1Mue>oISrUuxy`oF8R+ zzNXbs+<~XY2FhshM68D|m9LbhN^_+JRlW#%wM4j;(pqVzG*W2bMN?y2*QP>5G-bM$ zZ;9)g9Kf-LoFnvrrgc>Y8$|RX8I6rQ%oxd=8GSfZ8Lo^_Mk=H9iI%O|Tj`_pS3H%z zND6kb5PUe>E(*Mj z@2fh7jCY~f-@vW(d}~@?=XuQ4zdEgHtCh7pxpm5Vp3w_Y>eo~;+f<%@vHuHfZyHUu zDBHM6tP;m_xS5)Ntd^%6z0|s-!wExz&>ANRZ5ZGWS~I|#wGm=ln|uIo)`kI|gFuhA1p%JZh5;Vb7U!vL z-vRKTwhVB0eDrJ+O5R$?8@>K z;BFmoWI-ti@On@+?cD%3BX*}lL4fP}zXI^89fb((SPi7oW zCJ$VgpyX|*yy5!*Zt`G&yL7^>H(2B(-rYj)4|+1aU-ZaF@47wlrb|zz zcio;$?|IOk^vp-^c|DolpY#%9MX!SN{-hVv`#j<;dcT9-=X)`|{d;4+P~KjZn)W_= z`}bygSL-807|LJUy^r42`Y^q}N1G;n-$C#1`@BtWzrHxEpcJIH3F`aky&tjK{R+}s z*Z&oIkL-v0KK%;PTi5@;=v}hE5VQIhq<6{wZ|I$ZoKHLpZm;*zJEcF`Va>A>LCp9 z@41Wi}%MNFNry-%v2%hi!tMh#TPaDnvAB{E_-_h=U03SVq0ba^mh}qun z0C*|yw*h_-iT6+n0z3uk`v7h|QizEo3j$o%{}q78VnR-%3Ibf$|Gxmx1O z`;2-6aAhTm2@G&gXcH#V%+{)lRhNktfRCO;K5bNItAUdk z;EwtY@Q6u5#G$-GarC7wZP81_Bpu{C9miV>x61glvW-v{p+xzTdppD{`;uonHQr$x zw8JPBCJRw_GF57i*fw8k)n3g|I!`A14yvAX<%0@N1r+5(^XBfOGe-YO2xTUryH6kpss0e9-9ra zX)#xb9doI8cg%N-xjGBuZJg)fdFVWPp=-|bsA>=NGy_^Z%Eftfrw3N}w0UITQ;oNM z0j>CaLGp!K!68JrNN3!zjm0y%7xU<8Pc-a1ANM9ucFw1SUaE_APt>XS3bliNpR;an zHMsC;D4Nzr>7d_CtU?cas{w`1L;GR@GF`{vmTXiXEYtb<6w?QDHwE&|1?1fqb2nuH zh4oc)6t{)s*H6tU{N+Nut5{{HalenE`l~TY(}m>WiC9Y`mZ2Qy*w_JxwOvR~0}<&Qn-==>lx$>D@0Pg#mj#Vn=B!K$-zB!H3!W0_V!vkfHE5Y@G)Ue~no zVkZ8bt2?YTWekDCS_WcE1=66QSnigA6fhL+9zg3GMD4s(S3A9~X=&oDpzVp~a+DNm zcBE)8b+%1N5dIEukbY+5s)PiQ=PtPYMeHLZ z=A=~OSl~Fs%7s(o@rXGavHFTT#|BP7%q5)cC#vzvx(FH^Jnkd9G*K<1kKkF~&f+-t zbIXpvZG;uPm=vX&%h0JwSOeKenS>QK9ie+GD8g5DEvDBs%|mz^>*N~-M~*KxYt@xP zgsjxpx2sZhCB;m}(jAAUt-@t?B>7Ci(j8w(VN=lK%t#>~L{gWj$ekHUep8`UUyZv2 ztI6Gjspxf0dnjHTQ<3}t${b~KqzDsya0=lsqo|UK=BHMZhl=Ktqwt;GDE(y6wU}Pl zw6A1mTAvo1K^doSg;@NpaoR=>)3BgU-;&cb^pSx;{WWx98v4-dnihzs zUHZm1o_Bpn)%?_SW&9et?}t_GyGGAQlNrXtEpnKSRc%^B$50CQI9&$!*q77r`&mn?KNUuMNf`7FF=4+qthcfpFYG=+(AR7b_g~UI$`E4n~uG5KujA3r{3$ z3!M%Est047uI*GChKzTn4#7AS{T9O+RkrCFc-uD^N36$&SXkdIU8!yeobqTJUMY>G zh!7a<(KbpC!CbbF#YY8WX=W(2_OTQb3T-2_YWWH!C>f-;sc&%k)EQKw@!9~X5 z?UFdY5TdbRm{l1^eqm_Y50MFRI-$4s}iI#!=T* zh*n7iy%V{E*j4DDA_Pqv!zqrDs<%zkBs@AwqM4C6c-KQ6mq+?h@?$y`sYWWD_mR(P z)!DlFK5VFFTTR$d_W02c&UU6j;m3l;F*PbmO;%>?BhPPP;yFfax01lDo4y7nUa*g9 ztwn5!5zACg^Rf7=b!vcZ5VYKVd`&?Q*I_FJ?W5dv*gl^n3$Z$xUv()vUrfX1D}@ah zDD(hczqKlErD>&T?KZ4xn+><$}qSF+m#Q*D7#DwW1>!sgwQLXn#=yRB38tVLE!^}KqNx*3boK9zi;5$j~c z)>>`kSl|}Kx~5X&t%&tBVu@BM92@u@VtrG|J_eh->><5RO>2(f$U}VGFMH_Ce!L2L z;dK3&i*F=t!y>FY#QSlRbRoV=r-)d1O|SoDKhB9&!wOx6-tjQDR?>X^ye1CKuclK> z9H#3JxkCo7KvCi{X#93q&HpfkZAUB<+KMB1X9Pt%!e@(Pcc5`*2Knv42}z}+Jkwn< z++?XQ%y;CSDuVE3!n@*_m@1u)lGjc()#fVlo*tzdyD*`1N6BLs&YvG1BfqsKXY1?7 zbVr5iyS_b{cB|`@^2f<(4`!v}aUp&|DRu(S7EjQ%J!oC=I9bQT4`ZOsIU#6Ku3CYz z<1v3@PSE{$Y~D0P9-%m8()PXBys4;bnm;q++FFw}eVU+p+O*EZ8(f(boPcfII+KzU zunS*@_Vr0JCE^@Muj495o{==O5O%waL>yS=oTPvxY}5rO_24u4hvfjV4;yvKN%Bla zEXasCD2^7-ry#cMB-KhqjEq<{#g${7_v7Sm-DzH*X&Bx;O~oH#Dc7CmtDI_Qa2P#9 z2M*vWr`#FKRZjP_6mt+)Ic;$I_2+9oGtUYUewG%dVR2@j<=a$GpnY?Wq8~$ha+V?w zVG;M86QcTg>XQy_-#JQtf^|9TJl=#jZ`_rtsmwZ0K8KO`45HT$;gLAcpZ-*}x579r zeX8!UN&7*F&wk`9fKQKL#i#v1jgO$kk{|KI%OB~*5uE3tP6M8)du)}Tgc$dept8@^ znhIW(vOk6iW>o_utU&ITU7Y!`ew899z z`W>BSL-n{MDC83M?Wj!5L-s|A$;3RwToU5YCGtLrc|e^`zC?PJ%eXGMYyA2!&R^LVjYF5N8nT`x^6{m_;6^(Q~~kc;n@Y{>GoH73wrb zL#E8e(q)U~HO(~@oJlyHMdJ6+a1j8IW4^B&tQs82B>>!Q!BYn1#0QhQy;XIQQq^s8xw5xQcH)T%ddQFp^Y zTur6w4GQ=Phl*zqE8QfI3pg!#g5WkAWH!2qQ}CODM%tp&MmNdxB4#uTV!K;Z<`QNU zb@DHS%(b_01$bLfqr%8sdy8saM&`)dLi~7}?p#JD>eR^&i&QTMDUGa-I)M^K3`(Pie(l$nhsT6qVTA$J8GENZT4g%NsC6sg1R z3ULnV76+sbyGxPRutU53BE(#jUBA$v>(~+M{URu(m^rb?4TzuL!?FIJpjpMum6hyY z$ma%H1VOxpQtUp}xrr7_kg&7_T6}dMYYgS!ef&Dp5iP#BPmOP(#eX2Scz^@_gYesE za3ApjCDC9Fw5KRl9%AK}LW9T$WS@fu-5v_D0p;97I-P?Sosm%cL$pvH3DFB>-XlSe zKSYby4=L+sHOFc@gjXM#Z!5bWQOsQk2@p<}fsp)&{O&&` z35I2VV>Fz7%4q2I8!lCTV>ER5&4PyTXN-nL&+?(+&@)_1KVvi;dd6sI@ErT^G&K5Mh|RyhK?BAa4Ili0+r59}L&FDuFd9xF zaQhEN1L};1)-Q3X{?dYm)-M?i#d3x4%e9~ZBaDWNP#@B; zyIP@270x2j(MpP%R+28BMWUk>HJ0Xh+eHwcK|FX)t!af3dTsZY;CC0VC1d%fU>NSH^N4WA8aV%10|#~9n4~c`(Bdq_D#fMf zR$S8OH__r$F$ySw7PBD!fP%kf)5Q@j{E^V)7FyIRA;mnD-6bT++i3Aw3Gyt77B?Zf zIpT$RN2*i`Ev_P=XbxH|hxjwfM$32N&3%+Xwe)ASAJG+ zE5DYc+>gvTR?i`9y9?oENy;n(L4)9b4}w)GiYy1g7S`+ZK;2X9!?F@5A)3|zL(j63 zN<366TS25NH%uwEE1M<2T`Y&*52_WE%yQ)P)V#BZeuLDeycAC5 zB`r$Bw!#QiIBD8rYl3Ir#R#oFge}2m8jMW^y^eviu#o$?KqB^ z!w6kDj>K@N)-Ken7pxRsnR0(ek6tcPoOPk#OW3vb^9L&kv@H`eP`8Q{?W;%{c@i^F zw+dyxMEVwpA62D=xtIae$^R7k^{pz!^{V;s;9HgP(DY*|dVkD#K%McB2(fxK3my_b zW;`sYh6Sr;-~m;}L(l3`_*A#xp=Wi*Lng#VH7t0*2;+fjV99DS9;gQ6VMt9W%ry-> zpvrj2g4V&6@sL%M@vzlZiZY)t9#A*%VB`0R6q`Pwsy!UfI8D5rLGiq^|0>hS?G{hm+9aQ zaW6_vJ*I;f5)3+gSRcDH%JTXaI+Uo-bV!F-rhyb~8!#OXAiCgg#L5DW(Oot8-3_A2_!gMfU_-zvl9Uw9tvY9-{B($E&U7%f z0C*62LkB2KhvqG%=+n|dhvqGr4haxHZpCy!o#`;Ul@yO!8FZN4is|6dS_-e$7CK;r z>5u`nejBDkMr)=+SQ{ynw)yA)f$1=$trTio3mt~EWjb7h*rpxR0d=OshIUevXrGS` z8`?1)#P&~b5PNs9(BW=-ro-M2Sg?);9Z+RD%%??8;=yzX?Igw4P6i!NWjfe*hD|#&9qc9c^m!6D= z^1Y;3)QjWjyr4pMKhkacUtk-O7EpK#ZNPb6^a-tMH~u0 zbsOu4<`F~5&kuHf47sqEq*utn02`JnunXRD6aRf1+o) z+1|F3As+j4M%PU@d)XyhGINbgJd`xXZ~d9Hc!t^Arp_=aS`Xu{0@s@CZL31Sd6k~^ zF}0a#jLNlmt(`A$t!$wh|McA0FMj23d`DQdXu+DdjPT;@1hhyDF z8?1N0mpY9fN(Cc7X|%ra%hAKdSg`>{2aWz*XTRJw4YD~0v8fLwEWsw$>zdXBKQ6?E z*3(K;RF0`WeGyz8Bf6CsGVSYcmPg36sb>0$Q6%>?BA9q}ptG?v13fk<+0NiB#IO1xBIz6~& z+GF#{6kJ72q3C3YsMCP+5YIzwF_kW?M(guaC^-eK{iov6ZYmv!g62P!?ngm$Hc7GA zM1%H2b2d@Hek@}ev`ifV$D?R5VUU7q)45Hm+YW*n?{}+pgn^&#E+U;PjgkCO{3g& zXe<4sDCAEGhmp6^k7{j#*3utW&i-^~6SS88l$inT5wwBRY2guQkNhcjGqhFHafUa8 z5~884nof~Np|za>Jk6jrTcEX_L77{i{R(Z!OuPgL?bjLPa~#^YGo^5tMKw-9`*tQp zeh01NEZBb*^@)MjaTYbsH0LPKXOYh~3}4P7`%@Td(Bm+)noU{XV`w{@>~~;TWH!Z| zfeVk#XBXbZu=oPQg^<{Vofcp|7O)GOFJKqWUdS$-j8_D77sf5b1=%8YVcbG?Vb4WU z99op$g*_Ls3tuDRvzT4@dJ(&D^J1KyEnydKUd%4+vIJXW3A?b%5_aJ$Xw?JQg}*Oh z7d8u!A|`-c*erlucoSOJrR+k~*@Xd1rTAkhyAXADVS_+iatE>t8w9cov!S&QVi#ry zvI}PfNpUZTT{t6%U05YpilE^9F02yFE3Sk$H4q+D-3zcG8 zD7&y&D7$bMw2I5vg}Xx8g}s+yZ7yRM_Fl#=d_XJp zg<_)=V>hx3QD+x!fmnJIyKu`!c44n1Yh20N; zNe9@4-4Cz}pFmhdG%`|pl zz#%DK9%2^;9AX!`r(=&uXBWDsvkPxQ>wcJBcq^S<7wSb>cqfBh7u@#oQ$Y|h#9Hw0WqKiZ2?6A6UPWf%mN0+ zfCK|(g4b(SFz0v?v;5Xtr>eRdM&JAX-uwLi`Q5(u+STivz3SB2Rp;#9(|W(I`YQFc z+rCa+*(de2oOxIDzqtRph2gx%kInsU{gIsp?7L=6>U|rUzjoHa;#sK0YBnF+M4Nc>IX?k@2JAN5_wePmUiO zKQ4ZJd`f(3d|Ld3`1JUR@fq=x;wQ&XiJuxjEq;3ZjQGs>nekZMJff~|V3jZ>Ct1`Ks-rI(jQ$}74?x|#+ZoGFc)rlh3Qu9N1GrIGS35&OaH z?dTNBC8GyjDk5FcT4A2*;7s=1f(;S-A>h{Cx|PZ8jE)JnU_-=ypj)xIue(#%9*ij+zgjoyCEkpW#*_qavG#8?es!kT_RoF1cFKoqE_pgDB~~%-<${#oE^YWtqm;HY zUieQq<T95~ba0Bb*o&8BjvDDo~)7k9GjNNUbd3p8C`Yui<^UXG=mbp3R)Hc^tIL*Ti>zGF> z5UwcZZ?IDko?OrTRDovFjR>v&A(#fxy-__|E3g1%4 z{58aB9g3RWy_{xz!Wx)qJ)EP>sok9>0k&2~@ToMldODMv{r%$_N%9Onm}Y&zGuYrh zu}Plk-m__r=;ciD&gYSQlHCW^_lln6|P zXnZfHZsdU6LK$!ir3k~qR3hAKS&O5z4EtQx$k3W&=chMsx6l*Oc4o^lPJZMt`3@Ei z5)Kg#B|>AQwKy8)stwODH}wwOawWLgOGi0%BB#r7rtl2mnZj8_2vk~&BY0@Rh-R4G zlMj+=aV(^+l;hRHtAy7GR}mp_y|p+puGF;|<_D}n{*7CLYkOQin}kmYpA>E;!uKg_ zakRx%*_xq+GoVt}bQ*(6|4@z}3qKNmBK(vHfiJDa(PysI=NV?_aft!#dB#aMEBZMZ zk-GKZ5~?T65M~Oqh*($iXtl0p*R#`#T(I<;1v>10K^$giugLfB2%ort0I zwiZV{T&14%%n4_D_f$)>Ykjo7zfk8MvQXCvEYx+iP}kE!ogG-HGqg}=X`#;1LS0)6 zb=`|SZ zJM5IfSl_oHK8LLD+v;h3H(1{fGc|@dKZo8he-4qzhEd)U|MPGx@!e0t62I1X>_JQX z>Jk5oB|hNUD`_PU4avksg@y@-3Wp0v5OFt+u@*-oGj)fy83l$fcS}itCu6~>4-%URaqsM0;(Y%qcICCRxT?D<-o^~KnrnF~g)k*E=_5?(93jtKFa zti{pw_B7!eGVR8qscLNsPsT&{q8?d+RY^)l~r6X3%x^G!c1YdFoy`=2G-&z*TlwQyUfe7 z8%shY&2VQa?kd0T!fwJI!k$F<_q7&By{uC2EW5EtshNr1jHx~laTCYjM;p+pho3v+Y(Qm1ZWfl?;^QAmL%c!NMU# zY$YRTwUrEYrG{nOtwd6-wTql4motQ?3ug+?Bw`dXYjHHo6>+ldF5->{VQ;8iq;kU0 z8aCPrHa2uU*7BXcuwpvLfWJlH7jo4oAC4IGkb*jCUHF55_x9 zvF4|yuq9_2mSc4&F!Lrjee6!MV1m>7ANCJ!0o*^fYO8klk0*w^`$s(6^q+($_FYUo zzaVVSGYckR1A)D5lG7vqXN2aE4dmylA0|2DL*aTk`f5PuZGExb@w-8!82eHr)JYf- zb{3Wp5#lb^;;1yo-h5>_rtBoAWl*M8ui%%7NNAEIju0L$JW_ZR5mLumi=(5hXxn4J z@byn$K?38hbv=g*j$X(`cJEAOh#Bc7IAbU(${ex=reL z2yYjz72Zk2S?;wKM|ZgwcsH2936tc!4GJeb;V7q_-JD*M;48wHg*${hi4gvmwK&@4 z24;7THYWxKGHvyhC-NUT{UqEc+%No@2xJut8-x!MA+ph096jX9J)En( zNOH#_J=8ay*X8u4@D1Tx!ncWVe&1Rgz2nNfo2%W(m*KaZ;=kmSk_V^I0Ud{Q945lK zrnNXqH5*RCI*^v9J;_xmFK(;u?S<`x9fTc;aO-R>j*6{7Bv1Ph1+XTR7mro<@xpP! z3Brj)xE*ONjwV@w!}GKiQDFCSl(ClgbLthJEuV9R=LpXe&Ld(QT0pC9=zObkL7sLY zcNnd>4Hd7E%Pqp2g|`ZCBVqt|T8pFGt;ijD+Jz`GaEep$fBZe>m-H_VPx*iUZRUTv z1HC)dDervXK=hy;C~DUYA$Oo)yO}o4XA(;k#`!lYdzv_bL@2_F!J^jyAd{tO64_ zVUnEpB`N8INxMeqEy=$ld|UXg@I4|<^MSQEdfz?a9x#CuCdql55KfrbghCA<6-pI` zg=xYXL`%Wy9aqPsO|8yT} z>1ZE{9kdU{?9w6RJ``*>6C9^8N@+74l+w;{@ZADX+Z@d!Km*e#>J`$OMZH2Aj{d2T z#tntrQADelyB&2s-QAA9&o?i`upJFAFyF`UMd+hOrgo)MNLyU#bSpTqpqlOI!~$+d zpPDJNoe|-43(VcKk>)~S$84vf?5XNJM3(ZJu_>n14yBcqmPX3TdPG9k6qqh^>;NXu z`QLUgFY6L1>w>G=P++#eJ#9G7YTk|GZ)Bg%cA7N#he4Rw(r80-#97X1;k?FX>sihu z+6Hs2J>9iiTwDKa%b(`j&92Qm$MUD1<4mOgrgNMLv{~oc&nKSiT*%L#o$DM<+xI+c zuX61duI)e1^4H9>{TrQc{m(q#>OXb9ZEtviwX2zwIY*VkGc^>P(@H#8S4 z!tIHh%}aZbuV7H!yF|K`M!KNu@sgM-oFbeiJb{SzldQ$jbXWAmhNkF3q+k%mI#Xz# zERWVQXI|(uDBxYiR~p_koU>;&f(;>>*IkIKfZckb)9-IPHMq!j>T{9PG5lCVbLvHQ z;Fn(HjOMxCblVTOwrw1t`cY%uC;X4_C*gh~#{8SLIQrQg{Vxs8y>Wk1JDR<-@%NCl zi*e3|jZEpqPHX#Yy#D~cRH%*^ZGsLEVVN^5RANrJ z&S_*iUgngACp9+fFLMgah|BRigvFO(o-NbE>lMD-=^Q>c(W|@v;kwK5N4M)6Veco&`T zR#MNqQZF<%_Xea;DXrBLk6qUukshU54ZfDZx596P-wD4bLUJFiB!94yt$qZ<7Y%>h z5>T_pcHHgE4J(jxHfRF>P=PRC*ihJr2>oWX(r?_vUVW1$=9d-tQ9+5>aFf%<3|Q&Z zi}aJv0AYXOK;dCTs0^i*${<%|a1*m;WkTgMs+=O9(}brAPZyp+go;Bem6@)}nN7^l zE2M(^p_y5Hg_9Y+yop(Lg;SVTf(bCu=HBCpGC%&XeT9?7o9fRiobw7EgWMs-$j6#+ z5B@g%K@&6oDyL=9+Zw_9!gqyxgnNm2K0a<@wq50Pbo;%hws)%USMO>p9v?O_J+Ib? zo8RaZ6o0_3W%yqz(zFylCm~XOOL=&BVJiM~?y+X|)lP?S9XtW>FG|I?K>X=kSVNdD ztWCtY>NPd>u5pUpel^vW_BZ`FuDVUl;%jtIYg~2MHF;d54josWrd8iu<9rx0n{Ia& zneo>;*&R8rNJ1i^M|q$t!QU8fye=gL#rBliP1DNCnXQBho0?0n#qxAcQ?veBXJBNN zhIg&d2(J@fPsAmywiZV>G}W!x@58SNA`*hIzwY(Iy^mjU zmE&hzXbx?b@>by%;Wpt@M4Vx}wK#g(o-6!JQ}fAnSb~D0ruce1^`FY~bKz&gFN9wb zq42G>IQq)f`nsuEcD>a);aR73-3HCjQ?q@QiQeEeD#|1g$`xh{^Mv(@nAwKS%)K`t zYWdB~;2WGFZvPzh$@=I1Z`|Mv?!Om z>_fyA4zLzSeVf_kqF*!f*^S5olIE@RO_;Z7@|-R_L3pBY1`!IUT8pETT&adf#Wy1bd`y80kdbN*@!aJ@Vq6mAec zBz%|%g-5N$(Ic+b#%AVSSF7bSPMe;%=a7u|#Qlg)Z_4>?;akFYgzpm3zSmkDz30lk z-^|3<*e8T?X6G8Lk}1v6Jrov(gsH+bBAnB$#ZissHUu@Bo6a{|8GhlbT6(i{TR7aL zx#@HpcFWn#`S^7<1G+jH8Tj>IO6|I7q2&-Up;Mx5uUQyMt9tG>XK^TeU2`+;4yPpi zLvyq64s6P^i_CR*IBjXS-GS#fy9Ec9E6fq*3F{Mi)6#1BZqPyl!}scQ);rBIe!$7J zG^D1LnQa}SP52kX`jMXU?k(&k>?7<;gx)|}>GiXE;r=bmpKDQG#0ZsfZds3E;sa9_ zbJCqoi?OFjVR1|Asazu;RNoM(;-WT1qF%s<1clTPzhWx_RW!Zwv{O!PK%LCHI7S#mk5^$FC*gGR_fCg!YhfmPA|o~THw1p|W+v++qqJ<_qjK7pC&CPri zKM9<9H#S@j<)v-x>Qp*drn{k-i{#O>1uuN!c9aBVk@ogohJ+JL$bNhoV(s>T9-E?zn9cbO*0dk;ES(!6TP|K zDI4;sRJ{9#yK`tWD0{Q$G(>{wtKv~rFr)erx{QC`y<#KG3<65oe2%SXjLmc(v!xR+-SLLK?Jd) zd~p$v*zJFH_HQ?0(tc=Ol~d*9hIr8CQ72Cay&iMwgbJb@Y#Gj@(v|!3*l0^z^qJMo zsc(*W!WkEN8r|@-9N{yt zD44f4-8W%N`&vrh3cnG4C;XlW?R~V;{=sS&@_y!v2?Dgsx**3&5@(8)?LFc>x<^oa z$}KV++c$qeihGxx^PP52pEU=N#Sm7AqIN^9A zMs_%@MmC|yKCu&vOy*{%5mz2J@kidPV<(Wa{i=0B2zXe z+NK2vzTDX=ujmmet0?zsC^!xF@$yKmR&Wc|7N!g92Ks~s!qCn+I}bE9Dw3|Ce57 z(O{=R{wq{Ec%^y84BU-6$?{6)WAoDsPI>s}R;I&?_>TKM2NBvQ{89Lma6b`q_ggD| z$8BnszUXASo&Tc_KUCkDUvyjif;PU~H3^l?`N9Q6 zs9Z!Vm4#MiQEM~e6$}h2T${|+mm8*4t$D@S9`3-{aFKkO*86rmVYj;?t%6eDq7$9D zCsmr|*P=!MmTCy9z z1P-@oW6HjCiqgJ?y4jE(Eil74(^WVV_BDH5FEovg318mEw8)CKreeQl(ZeJ6 z$^QZ2{lay^^+YH>Oe@6=uHu7j%q_p-UV%cL=Fv%!f2;o+!q*kEgVBlg-wLbgw2T%E~1ri3o~Ia z?xn)E=DQYFch~RE;l+d0eTZ*8J7dPWcCaLSTcsKO}rm_^|L1 zA_N|zmB2Az?t{kxU^qpitqZLb*L+Kwo0(GDF#Ero@`B4H~c1lrL`ptbqnW6XJ*cIKUgK;AVw zqxeeE&P-?%ZENG1or^D++3z8qGo*B~@Fd|W!c&RRo=Ge1)2#OC?M%zI?sdP1iMw3g zR|uC2R|>BnLf{%&30!Ffu4-q#a|QO6Vi=|EFmVsHGkf3nW^OA-_w641i&`sFqnX98 zO7At{zl8r5zD~p$-lo+V-mqtQvz_@q)z07UJ zc&NSktG%y~XV&e-_p6reO<4_Z1_x$F8<_(iI1zJmjc8V603||)2?q)X2?rB#is7^x z;}G{0L))8BO*@aLcZ?nxIZge~5S}iaDLj)1g&3_AX1NOZbL~!7;hye{XRYWUJ`niT zLRq&S`WH6&N2~iKvrhPcaJ_H?5yFqqO87xn_@VY@%|}iPYAK~UEfTF4d0kF#3f~aE zC48F*nfGZW^NuU?ZhP~5BwA?ixbNp++ufQT?HM^Bw@?Rk52Xmh!c-!JYSBt4t%Hq5 zjSgmcCmRi?c64H-z4~_)b`TZ|BSa{a(n_I|tI)ZF+4TwPTeu>uA+62o&e5{S1UXF- zP81$4Jc0Lgrpt$=v12+}*)EUTOz|N9c&i%j&;F_=<3+a2F8@uhB|j zx2y1K2NU|jP6!?m-QekFz!y&M$WQY8S-4;Li||(>wEm=()^D!X?;T8brX3CL!`9}e z@@Svrpr@NZ%A`*)6&6(CmZzo}C@-NO3IF*d4nj4I-o=;WBk4{^9FCvb)p z-yo@l1LDxy%YneMx@l(Gt#dXc{sdXb+=$t0y0-gTNHX!wZ{u4jDXgP~KJRE&?Q@2Q2Nc`% zYG|2_PraWYjt_-DA-y`bxSI6p*kaRfV|2W^In}9K^~z69S|}VVw&~RX^iQN$#Vhd< zH4Nbu!mET=6LC9TORL-InrmXwHsMvpHo3x>m|PVYkdDJd=+&f^UTVayK4}q~T0udnRXg?XAZ#z} zC@dyIp@dcn5m%v8#HLnIP--|(Yp5ofhHpRjzlwv)h{!a=w2{#M35TWoitrWJp3fnr{6blN86bl~? zO0f<|CR76VP>L`tOeI3N7OjNSO5BvD#HLuhdj2F|DOP(qbrg0G77HUp$duAbrjskv zxx}Veny*BPH9>BZgcF5_3y&Z|=onfF9f@Bs@RztHHp9YjlwqBx?&k~V2`>=NCqm#t zS_v$0N3yWQW>`>2WLUS!=?>xT!nMLXiIBOMRx)?FGIzr=#exi;dt^51zeD(naHnt= z5el!-N@2IF@M?)ov7q2>;)5bT$?0d|e&H{|Ux|?UlU6dnxiY_(*c1ygO0k-w7#|50 z3R?(U3X6zPXiF=FR;4z?txIi+1%+A}1k zU3pfLSDn0ry?W=_(bvRSzE$7kMGsB3m?<&Ynyi$>O}2jh(@nN|m6^91Mu&&5 zEVIehwcVL)H83Zyj%J7PVL%sDq|R#;ZC!9bik62IF7Ge%GpXuWXo-jk0Da;~5A&*uH z+2vLt2bT3LC@ASFE4N7(J}c=OFaL?c3BpOj!--HlnpTQOxQa)X+oTH$O1jQf|9Qgm zgy#z{AVOggtrX_F3Jc0@(gg)2U2Dp1(xvH2Bwd>&vsJi7xJ~#J5yIPPCH%B2{7kt` zx*)8i>ofKLLioAxOW{{UD11jNg|A(OZ^~`b1%*V?Rj-Rpx+u$vR-_BuLY;-3geAgK zB4jIQC0k~0i6C<>?_zT<2&kfUgt{LkJW_bH@E9Tlj;EEtWGirN7n^fIAdz#;>!O@X zv*zVo#n(&dM&S*@n}n;0kiL~x(rc{r&0TED1!<;S#ZRmIv%+VD+l9{&A@CBd1fI77 zFLbdPmld!X*B4!E#-*_(GOqLr_=f5TYYXcNGlTR3VZuz!ZPFHg)`$SQ~xf) za$$wAD-jAkX{FH3Rp?$}GcG73GOnX4Y{sSW9h7m+mEbwTvxVmh&m-a#^J#U8dG0CB zudo>xPN9rzjr!jryjggw@HQe8?xdB%?XJQd6*l9t3U0>rY=zCZ>|>FfaeXYoPlcZd zKNEgV#3{a})hWJkPw{1i&A4z1WnA^TqDLr8m?_K_<`ALKfL02*U2QD#y4s8j3SP!l zVU`p}vlyL&(yj^8nk1YkJY0AL5$ea#O8v;LHqGg3vo6knpLLxlpYw(Dgck_s6QOb; ztyC7cV_ewPW?h=IMAmhi-0l$GE?g_TlL(=EX(e=*D|B~Pn|5J5O1oZG{~f|tggb@1 zh){TqRtmdag;%@UvC z`d12L!r8((L@1m?D}}RMg}L2q+69Hg{;#y_I(gn8yk2;t@FpU(ZlRUdYFBGbH=A}r zE0K03McqxiZr5hsDGZB!d?@EJkz(1#rsnM~NI7he=B921aujq^V&(O?q$1Gc@e1T4 z=z)N^IhEI~ch^9-nO&`rH|uUX<@Nn4*tcmnE1Afo&}~t-s0O~in;m#!)|54&M_G5< zV_J8czbHfUPEgt-TC-jl<)pKs{A*_jJf@&|75GC_B&Ie@k?vCx;-*M_ibA#?by;`Q zv@cHaad(>{ec9IxJPIk&)qRm7;Y0K&q)1QpMT&Hwdo?N2f$sX7Ulso5*DVxo(8H!j zAERp^J*wz|5rn!4y9&Dtdk}FG^r6*F(6fiVvwQWh=@CYy^yql?pDLUpoF+Vh2!)eq zr7+!9I1!fV5fqdjUDU&-NBFGt=vMjPF1$^6hj1+siuce;@lGkW3H7kq5d@SSy`=81 z2wxWN5bh*G;9s;7*yRpscMqE#K|$Hk54cGFwNJB^$d0mm!ZDO9%n{}Z>k}c|kXFJC zdfM5_?`g9m2rE14ss6o%y@Y*)eTh&QNGpYYu0sEwHamhsB0HMe(`HAMWl3tjL>3Ac z2p0)2BtmvEtz<89W#c_J$ zHoM0o`)kt6CP-GmCP=+|*#t?0^An`v$x=E_c&zYv;S?gYr_)M%s@0y>%jQSCaQ?~f zB6Yu57#A)UE+Il-8Lb4CT7gS?+4KkkiS+31UN$|_=#tZ;;^(FJqVNUbOTw3lIKwVl zo#7RGh8?|Zc7!u9J1YJ`-Tx!}QMga|6A=Qx(n?^z75KTAO^&R9n;aGNw#kuwDw30< zZoQ!p>LKhd>?!O;#2Nb0>I}Vm+ef2MZ<`$96iSY!s{aYXX~OBk6Nykbg;okPT!oW* z+vEreUUD>utI9!n(QT5sLwLJzt?*7Fgzu%5@LjI(-MwvM#H;rcqnG8hL->ktr*Ib$ zGOy7}X16QzYHynuX}%JP(NA*wS-4;Li||(>g#M(J&~L8L@4anegz+dbYTgGuLWRN> z!j{4!A{5%vN}*LBHy`O^6C)@j5~E>q8X+7m94Q<{gv>Zv$&7Yo#=tT$f{YTQsQOn5 zW5U_OIYcO&Lo0=|T!p!PY+?ijZ;KujxlT?u2(K63D7=XXnOkTjv)Ywe)5j)8kWpgv zl=?p-d|LRda61tSFVafkIalHNJ~lCeLSlBd>3h$$`G3CtJxxVuWrRCL`^E-8qz zv9`y`V{O)=#K=3rwBwQ!Bk-7l=2hSiO^le(FfrnPh0y;&)Xbr7V)TArGx`LaqFX@8eIFH=h`-72eX% zjGBQzfa5H$oQU6jywlHYoMF$}VMcT?dHmMCP57MtW|jLHzv(ZmRmjv5Wa>%L^885u zYO=qG`M^PXs9*LCJvrJdG6cQwA4C)m6%H4UAY#~KXf^DS{p}Qt>Tmzk0vLpTOxy01 z=*i&{o-NW7|1}=9lD3CXb@C_e#S7{|(uUqdUsbsGaORee zM$04n)&Cda&%$4YzY*d0m$f+h-BtKwfGN8r+KLK`Dx>Aa%?F}qs8HBK*iu+TgkM{0 zan#C$&c)5!dY~Emm@m-QjGrCNC>|=G;lg3U5yFu~_>Q#}N29FD=z%6{SwLmStx%aI zpQz9g#)Oqb_|CN!N3*TUoPp-%$F0hQ+oHXAQCKQ^H-AuW4+|d>J|f&mEHm+W(O%~2 zCs2yFv(VOja~b}_zje-!9&MhzJ=)Bt=WhbN{`}}v^TnoUzT}^bmYc~Jpku*W+wp|6 zqa~*1d@yC3qYc?dNye01n3FJ9=pSUeRcfJR|WIAjRE-^G%I7m1|IFyK)8)+?$h7GdM&+tJe^i;Ia zAL5j&AalB$W(v;`o++F~gma~}IC5N>=pa*eua(iijque|SY5A_)78SOgx3gH5#fBj zwKy`a%(a8esHbg6wNj72h9S5*S~v2zJU0oS5I!l~OoYNy*5YW3tF?8IS#%$6S;WNC zDu{e2r;mjn2|p2jN`&*5*5c?hSLX9U=9XsyGST~^1;up+qkAYrSXWq2m`Q|luC+MI zGFL2vclKa2=GlPC%4eZcE}sfv7hzXnHzIs{S&O6YR;9;alVcJptFFcDOf%8C#gpZC zobXuT@xm!Y_)oVMM^mlRw85rqU6N8k@r81U3ojC0EL=>4>!sG>Xo(eBik0uVgor6z zkBhoTKKBXl72Yp=fC%3Qt;NwgtFnHu`O{U=Z>gi#MYF3~To|2|R>)P9>+&O7$lU!Y zevX?uJUiIjzZi*7vmtgNo;1QP#A!>g5aR@o{}JvZ!uc0#arBcbvww(Po*|>< z8J5eldG5++vrw7&8NtuxT0gXf4AzS9{AaWw;DKaWy(>83v^nF zXc-2RScdaffz~qY(OQPLkk&Hn(OQPjFrc*zd$g9}f@?u*8TM!`!%vgeGVIY>hMyUR zNeOKiJ}Z1q_&gC)^s==$dSRHoeO?@9mtjvv%kbB7`d0Xj@H^r6L^$uW7Dqq0GCvNp z%P?dT%W(bS98JEkfv`Z>kO=3d*5atqa66jD!|gH*8E@%ym*GD0>?iCi>@OTZgu-BJ zaWrta+5K3wO=!4Xg#%Irks0ziS$LB06yd2v_|CKzN2j?XI(@iZg*_Rr!ja45v|M<( zaD{Ls5zbdzi=!)CnJb6eW!RJ9G8}nWP8)@f2&;sT65+hbS{yy*$~->YuEVa3zYa&< zmE-%u_k??ddx;SE*jgNY;7WZs+%Cikse>QuI5^ zPgb~V@URgkb2ZlBH6!dA{O>VbgWH5*wfru}hl0m(rbCk9$4A&?xXqeqUa0t04ed4I zzl8r5zD~pt-?kP~^KZSo0;T9e#i=zWpAZ4UoZXuxM zwul`%!aO-F-j@pg1Pf7cccDc0*?s7X)PNRjRgkywbiEy51Esn;yGUG?u z<<^tYa$6~xCEwcHLJ&Cm@O4ikV z!=%?!(P}$OK2f0~j0r1=@SSTdj%JUxH^7|HcD02}Vzpf*r)z~qc%ATiBAi!Si=!J{ znHxvj)fO@bt+t!xxmCDDxJ~#J5enO_#nIEQ)-$8+avRVphZOBqW#hexo&dleN1bZyYwD&r@QpNFveW?2$tTKW9`y=)I^*9zV!&wUwqK| z8{UZZx6jyW*55v3t5A%X6^a~=R{VEMg+~aF5*|&&XpgfNN5_n{VVykIuDv+3a^3UQ zf4=Yn;R4}8BK+dk;%JepaN$_H_(DO8@9pZpR(OZ-PT^fd_}ynMj_!69?ip(rU#s9Q zzAwvZhwv5QPT?*hoL{pRN4s5_SI64L*OSrWyH8I0g+B>@7XCtn^B>mY=vP_B1+b@dcyBcib~z zwD^KaEWW>!*5d2YT72((7PJ;$kJjQlX**~wz8 z$E1W_6uuyQN%%4mQ?$!k9KAB$-ab3V+tt^T(dzrXoPHGkApDPT9}&*KSc{{dT$%mj z?dl7e#Om8{0!PzW*htt!*pvw8LThoD~K0j+|_sd749c$)AG;Y=c&qt@c+Ojl;s1iSirGFp9C%IQks6~e28R}{MCVW)VQpbuVFnSd+1BEy-b5R)OssQUe7(!k z;#(@Ga$%XUi?D(S=N{JLsH-c}ZK7R#A>%K;RaktFOe^Gi$#u84o^yBIePy$|?v9#R zwg2Vl%uS7cLM|LFNJ&}w`GEtWng>!c@Kcd#p_G(zGw+gEN!y`lKCl3=&^D*L&2`Zw z!JCDHXV0w~dTH#La9hk*La^3>l)CVUqW8We-mL$9cK*l^+WFfQwl_rkE)28u7n})v zrpsRl-aiv~j)47>Mo`P_{U|!u)Lb5WHXRyluUYl4<*_Cq)Arf9+2*emvGmYFQ)^|c z#H=nmJKGFh8C$quA-W9<4lCUbmweK2!E;{7*9i_2Jcmy{Y53qdeDZkW6T=73;giSk zGlC5!wljK?`F1-7o4+zvn9DwV^L%`T(oN}ebMqUApi%B>T!?o5M$?ON zUA^{|Xdg*`ul*9VdoS|+Yua*DM;#BJ}rMFrM$BXLekvncZ?_tiXJG zWo+x!PMUf9#Mv2U^HpeAX`Z_(RzmK@f5$RR&8uSz`C;o3U)UqKjF+Dwb|e24jyNSQXo9 zrp&0!HuDWG_&&45;2x{FFPd$(o7h5=|8^|9aj1^H)cY_@zWqzBV+Op<^P!!WdY@Tw zEzURB^Wo*O|F+=e)xp0nfO~zFi4~f$L*`g@hLkPX>v6S<_u%6D-GHlo-VD0| zSNne3%5*dKJ@j0B10JjAF@_wB!N1D7_Ug$m$2-XLu_FI&Fu>@~*&yHGAfAsE`LDtI z0Y`t%6!}||9;>|=!iW}72#h!y6r58wV{WmbF;D`*sg1fME4y@%K zj1F_4;XZ*Wp^O75A#mg~l6g~he5_e68~Ab!9L&l)V)GY}PYMKtxEzz8h_@dI@C*d` zq(FdYAjl^@f#4Yk@=1XJ&p?nrg@1SSBZU74$j-4-a>4V3E_&g@bO9PDo&2akh!aZg zbG-dK8a%^9{!_gDFa`K8!3R#@>wNV${MVtB1%a7MocJ3!crS*4k>rW9K>DjAc&?7* zKf&8`VSn!es8L-g6MPyRGfZ~-O8l32A(j;TdN%ecVYBj`E%0Ej$81k zv3pX4(VY<{AH`t&2!m&Y$tOh^JR?j#X$J$(2$N5WFnC6oJa!lJ%B``O9n;X;V(ocU zV*#4{IHEhJf!)*a_TvbiaU{>_^WzxcYqAYp_zDGdYW)q*VewQg4tBu*w~PORklBzw zr$G@Fd1ju1|BYxraQ>OhwA*6^`0w$r!_TMcVkWG6_~Mi#}vGhlpwW@Y3 z-(=nsOP5xo;HaRbQJIo^Vg)tmI>L;)CpOz`uMOE9_h9SVkE6yRbfhSI6yojQAX%oc z4s!ss^G0EN5#IPmFZ@Mvyw~pew?-qRy!M4&dw={6g#NrK{pU8ztVero|NLgpy;y!f zt%K2hdvEM{v$<|8yLKqsPD!cRc^^0R476t6k0~iNEAGdXltOh}a7wbx)(p(aj{7ku zY)qOHh;dFz&3Evv!RAv;-3Kryi|avm`2(1fjW}w|v+|nQqXKV#PO{D3dYluqb57Wf z|F%M6PO|ZvFSp(E?}2uIPO{Aaubp#3|D-v|Hc_oGmsv(RzJdQ8t?Gj0Q>hyC$0oWvcIV-{v(dX{g%^sq5$dLYK>8En?U zw+5RpHZN_!^bE~`?$`%0J#%r?IE0QI9(xSO+n=5sb8`+aAMKnTwvWUc|JYk1$L#Xj zJ^#^Y^rt6hRj%vK*`a&V?BtkIwAc1eZ>Bzk**Q5EgPZjb?wFb%&cz**Yp3LBGwxwb z$>Kb;E`K<-u;bB?+mCVhPY*is`6s_DI7hi=K>b*LKML`AXM55#f#)=l&xD`3)v7pSR+3V-A5c zLCK_<$Ti=){db|i>0E`xuWdfgrK7P`v1hW9Zj-zNsIbKvq=s<7e8mhc;BfMkq;#AK z`J|c2vok~f?%>Sit!fy{9|aLj44acC20SN*eA2{#=fsdtN~19tedXHTFqWMd+J1a$ z%yaM-p-&WV{}#(Lg^f5fXy+})_Da0*kG;k6%y_Te^Phu8NO|oGy>`wl{gY-k&#d>_ zJ%2j-yAJ-3=FrZmW3rI95dKLsT_1lIdWix~JJ{b%6)z7;x!!_*v+6O@iR;P{Rb}Sa0DE@7y16E;PJ$Wfd2rJXTDB;4BnoLuVZ%ZQZQ)DU%O&k zL&updyK%g+^PFt+>2Bxg^h7nrYU&9xEtjbMU()n>i`u zgY`S`+9GPRfv>Px^Kaa{{K&U|@4}z6M2_Ee{aFI9-5K00y#0GOz*mCDsrBMGJe}Ep z!_Nt&bWGfH0f)2T;JqlsBEd}4;!V_)I4-8YUJw5~W*nL^$uwsEo48e%n*MKrT567Z z3)8>UEO`q{$x=8bO}|?&C4V2@{@Mth(@#EW`rY~|`C#=X44yYB`J{M&XFSLwQ%daF zaIgVk3twR~^(_R1ANlqJ0s&4Wxy$hO0|K4_A%7{}en0~Ja`5P)7YFF+;3qoO@+*@9 z5^%Tz4&IAG49HTm=N$xu=f4DRuZMpgll87*SYs^c;2}9XMr~w z-{F3+-isH@xbeinY8!cO0_5+&+jAlBT>v!#(ea~}%-bw&O7F9?Yll&!WoWmWHGA-t zZR{OLc;4TGO=2s^q)?(GCz5=ydP)I?l6+Dq!E^Z|pY;5JXDG=hg%UhNNgmZx^WI+6 z)-arObL0o8t+gG2Qa{hdD`lT&@b*Jh*Nh*55`Va^S-2bD@o3%8>)p@m@mcCUK#mT2l2cz^1-4U2goZU zUxZU7(tvulDA$-RN$XCgy*YmgnY~}4{L4!)&A*B*41>A(D}1A&2k!`ftnjd7HM_j_ z;P>P(+U?j@eI3iMLH7}+$=9*jR9yLWtn&g=eEZ7-Ja`6jf8g!kbKto=kpB&De|ZS- ze}P9Ay?AC%=fL0a=zMGn+75AGjn;cnh+m(*L3&@($a8rh|0~{y>X`N4;7b}V6!!H- zoTjA7b}OJ6X3e+QhBM60Z(}Q9rhbRbgPnu5zA!qI%P=dv=A>yxGp9MjY(aAk_B_SB z^IdE<^u~Q3D_J04u>LH=fwMzC8*hJ>!E=_$Q_!E~0G|sU|LDbWc{=znx>n2A4+k^x zfI|aM1yU5^Ec3)1q(95xIm_gE^ZT>x=@{n+?4}tsZ!{`IkEA(vOR9xt>W^4$U!RKP zeD#l5ZP_tc1`4AipGES)A|iR7ntalPgXeIn<2i5SGci^_B}acgi{vlHYJ1avVzJu% zz*pFm>_dXXk9_+vf)D4GTx-1j7=dSu$QR-5$0)$J1&@F9;x%|W?f!;upA@5jLkCZV z;{?wbd4u$01fDS>-x6;>MxKr-`3W&9lrd9&LJC@8TI>f^VY=@}Tx#yZIx}}a;=&4a zQe048Wn9QFgRZ~sfM;CDC&dLk<5C^ZxR6hZ3;HuI4`)~L@Ng)b2^z~FYPVfwoH%LE3 z;29$FUGerqoc)Y3Ri2_s2B46=w@JU+RP!?u?^89y+{r+CvyX|kNdxve^djWfO zLNEUTf;VGBK3I|sgJ*2W2TQW#85{D=q2nhd;29h8D>;eq~Rz}r9C^8|eRj~*O2{p6 zyGhtBV4n)b`ay5h;`LXL#f|15`t{BFj^|vsU=Vuvk%uQEPtTJN;u(4JpMv)zjQ)%~ z`J~8$XXMGZ#|8V52cPcp7ja|@`2P~dTLMGlcf>q;@a38mHt3fnY~b6EaecGvGd>!S zWK7w1I^KS)>#zFUZDt7B?BI=m^upDbqJ1RYz4n;b$n%5m-`M(b9r7avo)M$oX?Qc5 zd_ixecRt>$Z0F05+<(jQ{};;fv(hRLD#xe(O*x)C@7O+wMX;((o_8$yU^$*V?^yCf z88>&WBA@Q^sF#vQK@)dusx8N_&8gJyJn2`nYIbg=%JD1mDp`)dGp~~6_&4$@4=u;1 zqKwQ(Z8RMB;e_5JNS*^HpEPjr960&lcUSi3z{y`295{FmoID1e_=cBya5;WmUge?X zc*^p*pnI?!Po9q(`LTF=k6Vxrmg9pu!E$_%Pb$X;8-nF{^3|2&$@78afP&?CU&l<% zS1@SI^88Ac5g)W5YALOm%;;I$Qk=ZfSli0rSe5PVXU zz-uc6KRy^G@Ql)N;1Q)nIX*Q|j@KAfj;FjfBy^vKx0h37{8%h`vLw!p`)>lF=aDNRujzPOw+CjZt0oks3w(%R^?Ms zb>?Kv#K?kGdGeer^1*Tpc}~_$Q_{5Z(5gI}IX83*R^`DTT$L|rf?JsV`1W=P`g5|# z1*`Jpc?*-Dg|~kT2l!xBKByC{$_M$Rs(i2^Sd}MltMcobRUTTE_ub4MG-Hx!OlEUT z|5CHFIjE)Pv*wuorKX?-RumSIgVnH9)R;N_m0Oihb*u8Utg^$Z zDo@L*JpHSy%A;LXd018DGuva2P*omB2UX=$Q8nj0yo>V(tMcSI59E{P0X*k{eA1o? zp7TIHX&%6H9>{xD`Ld3c!K(bcV&q|mROM4q^kyVkmBnG=HV9VbQ~#kVPXS&T1^DtG zR`9$s@_oSj*#LN68TnvUo;tiT^1-S+d0rX$qTmVmgVm)t5jLOu)OlnvOHaQ({b2;;O*aZ;JFTv z50>TG-{XU2`Jhg)EFa{tXe7$=!G>U2o;=GeJTX^e@5>u`t`FpcW%+~-{)5DoD$Bzj zT9!{mVVSd?VM;2n52GGmQOUCWcNN$@IH|$1JUf%iFfF>e%}Mi&X3jH;@Mw0+@@I6d zWLbVs*UCf7^3>xjQ!`kWC(qd=PeDJO3Glh#@sD0XonTo$$kz|n6N3%GvOIatGEbZ| z%iuZ7NwvyphkuiT!VW=+B3dJj?Q(dR7L@@>_Z$!(kiWeue`d#)w?7EYC49 zM&yg|_G1*_gJpU4_jH0~`5@muDMkT@U|F6HjFC4;|49JP7?BT_<^2ObdHTxhgEE^}q1!ZH#h5Rzig}+FGXI#i9#RWX$QXS8@kWY#W z`ZF%%lgjd`2bbk{_C|= zU|F6H43RfTKSbaeBJ#nqynh0-pr7JFV;<;N>6YbFQA_3nG#q}xvV3Z=ERPTRkqA2_ z1rN>)9{FHdo}vsM`J~{1XYi`y89eey!9)Lam*1B39iqCjyd84qFfGgO90g-U)nHj3 z?JCQ&oiSm1uq=;umF0u&!LmGghJb!aD;ao(fPAnl4?UIT>E}%~mpDJKM0<5*`Bap9 z*`MX!U|Al#EzGJcpZYgtd3rN8^bVHg$ul!^0C#!`oj4!85GngJpU4_xR~(!#{cjb%JI2AfHs0 z4>knL^5m;4%ado^IiO%!KB&Wy`0+;n;7nK^WqE`$QI=0d>6pDvg=(-Y4?a+qPpzgb zPftdkp24y_c}AXmuq;oWktd%NdGL%p`Suuzztw?Hclo5UJcm|oS)L8mmgO;gmE}1E z#*U{7mgQ4zS)R?j71$gs%fnq|`CxmnEKk0=vOIZ4jC#ScJoHqSXS+A|Ns;?+S^od1 zEMJ9R$&X6@fqWV&=Db<^AiTjJ$dl*INpK?q!75Ow&k~#3v5DnIP$#dZ3lLii+11BH+ z-pc+QIQa{?N-O{@JaB+K2TmRXPgLa74z9@eKL&{lyYcNME_CN3LoQg6C(kF1{8+rb zRW-;5EAl~|U`0O2CspKw4Z(^$`RXe27b#&5u(>e$R0@Rz<$% z@m@u~+ws*@4^6w=nzh?cc)i=VXx!R^+M6TbTSTy!~4^zy~Yx?CSPbXNB5AsPB`C!8p5b|E+ZAJdT$<gB5x5)m7xlb1&e4f))9o4s`?3@uQZ^2P*PuC{i=DTg{f!y^8!_r&m*v zXGex|D>?@&^5hvx@=2it&rp(2dj7yOl;o2_37(-O&x-t?XLuF)xih_rJkP~YvClJj z`=N3x@@Z~Go|YAPSXJa{S&^rIbrpHEt0E7piu~#`y^1`JZcqN5d>Sg|oQHRD{$NF( zJm-OY(ma6YJdjV?Gr@Bn$S2JMc+LZPuOh$ANvg=#ja65XPeZ|*kz_#@hl$%DSdmZr zhl)G}cx4pe%YRtG^UBEg0qI4h&K^|*Hq97k^2o~hYv%ta=b20X6T;#btkPjB*6FO$s zIkq4VduTyE4W(vIHh$ZFt_t$sovVWUg7c~=$g?viI>W5=k&75bH-_h(AiXWKX86E1^G0TiaE!HX2AtsL4NZE)fD8}kAm2VIMgfOlL7onbkvB;HNdV6nkq;K+{S%mR3lXD288d&O3iACI zfvPY^E%FNTs}@yLkWWJ)nQ>tuc^T%yUn9XYF65Kq0-kZHj%QrRC&dN*85idV@_mv*6mSR@H5i+ct6v_O?OSddQ(7Uc1v+JZct8NA_m2MhA#89eey!2{3W zRmU@U5iE$J&nbp?4l1;I0{QEkPkKl3-aWvE69^)+&Q3NK|ZL%k@)dO z|KLnm9tC-XGEtCE3lxQe1$pp+f_z#v1$lZh@~7e*EXb2*Z5bo7+00vk&B1~^+*Obdwg(IH zIL>wk?20qatFBq9KYM8=^59dy7Vmv89>3Jd^pYJ^Nl9 z9{Bydm%R7>`jH&xoVE8kbLQ+lYi8D+3-W7gBIp0}d-9%8%{gO3u;zAEo^j4t#_i%Z zR{j zQRUIJRC!NP<%n}u?i)7XqRM-| zLY3!^95n98$Cw^8;2bo@GXxDd2aR#ND$nC^&=}7UG~gUG#xtn$JhRNIylcK0Re2tp z*PF+PLrIStaE=e-c2%DJ-MC$qw~w<4ebCkVvE!V$_@6Igc=)jG*sjVmo|P)kIA05R zLUvW&J`Rs-i%xpfGU7H>-V;JKhxP!q+2&T|Be!Lt%CjSf@&KIesyyQyO2#vU5;%vF z@eJo5a1JHo8A1u1L&-R+^7FR4Re7%+ZdIQ5#i3%KBPi*ia;fs3E>)hltjc3+sq(yK zRi682rOLx@sq)xbs(j^7-Ksol|D?)$LN(`gxQ6}PRe8pF9T?BB4#0UG7|(Fc1kUTg zc!qTV&g;OqTa|COD}yS(GBGPv-V>rXN0L=pR9~inU6uFzKU8@hfRBs^;Ggu96*wOm z;~~J)?*@SLkuh#p<#`-FGREzyJmY+1jF+)L7<;}-mG^|uEQdr3K6lIVX`hQM-*#^n zvOM>Yxzbd(-7d7SUFJsHV0XPIe`>GD@(uT8AZNI z(jI%7?>PQAz{^k+f;joQM`W+7XaEutU%kn%YjuGQ!P|{;$!|k#>`@6@n z%kp--e1;g=I@o1-?!Yl}Pcr>X0M0RD+%C(f?|^O|MT|;W8}d!DWcf2GfNIeF6t^s2 z?pPMGyeH&jjtk4lbFdcaBnh13!gz+b0Oz=5g>zgO&kz^*b6gnDAj^CHvn>BK1tDTL zF6kjccV1e??6N#hn?uC7U6!}wc3GZr_c(T0-j0W42$8LWU6$t#93uB5(?bNDL&UgU zmQUXStvX@FgEy3R!Y#{t+O%T3EbnQT<WvOL>4CTzFM@~~U7yxne>U6u!KljS{MAS)Or@4dVfrUHV-KaE=Y*c3GbNv%Byz8SXx^mgU)>kDkZjAGa(IJZo8=J8*co zLpVx03j*h`GH#dU+24)#fers#KlX9#vb-J7Aj{hgc3GbBtYmq{Iqp0myDV=Xhi8%= zZ}{6+LU73P2<1yz-qR)x+huv+Hd)>?3t66fa^wf1*kyUfIr5C#WqHOq@{DJQJaCRY zE^h+J^>@GZmEYDNRQkG{!ma;siZ^`mJ1&$r>$}Y=$iY(7&P6amGWqEYBWO=*Y zF3U5Xl`PLVM~ug_%kmh{lI7XX5n_9W$o+p={{NQci@ox<$;)q}pW%C9G|Cv1u_)tE z#_#sMFk!)hDg7^K>Kaah5LH~Qgp|E>s;;6z5}nZQ+!&I-kBrx{sb`4iZ3rQgV<4Y|X0!gPz;k?i{niFZ2>mB# zQw6a@Z!L!^xk;%fo6$yxyjnT6>!?!6pJh`sVXvtbQa_%@g{qLJ%8PbOt-31pi&Ep8 zd#YwQfXQh0Ev~6@x23%u?e%zW`^w>E+3%wLRbNegl-Jv8`|0`Al;IGsYsPu2RP3<4 z?xWs=MA$#oTeU^IhW?rwFiTTgZhI>ScF+m!Eiqz0_l=7*eU4t(1 z2-@p!fz*AkV@J-hIaTo5iummSK~!b0qg1X0m&ZYEEv;Pd*zFS*q*M}$i608s=O~gV zA5^Vt2+$*_Pq5PCkDR-z{|uMDmBfu*-9LA6hPt(%e9%y2{{uAmQ;C7jUD;#N$)~bX zwMrVoQ&v9cc z-PdYtFinR(Q|D>Vp+-(eA-dP!$e&}jK2ML-7wA!>ZFLl-YFivd@-2kdB7Lzw-|{xi zacp}dYNSuju?19c&8pD8s*+=hBLMr@=-S6Yjd9alt#7k>eQNEa=uX!Vyj%I%q3_ZY z^*xmDgrj(c_4)=qUf-n0=^Nn~o9>*1+UNK~8M|FbjC%$?V+*R_Ti8<=&UMOJ-taG4 z3HK@eaJDXhn!y&+Jg#3tziZsbkNTW4@_S#^Z|FDm+f=%OQM^K$envm1f2p6-q8MGb)iEeoi(WP4)&hz@L|DKY50$S=2$&* z;P)z6J$*g$NKbFNJq0`SvS8|2*6=U=6V7>eUUSVo#C&UrLLNnBh+-baWrzYYM1C2< zcZlIngBLq9?tYQgx3tIW(zl$)8`8I=^bL@{mCIrGOyODWo~$7%c~q4ls(DnGAu7rc zffk(KP%5}-Ow#?+#qkAW4fjlV2Y zn;v|OQ_)6mTG86HcaI~n+5y-r)sYFgGS}LK+1SHQeFtjOi!~T`0Q#J-L*++cTs!p* zsAExMcHg>6MW9epJBwUi@}F;AO8o>Q?1uIA5c;*V5diXe$$q=*TKt%c`7s;dJZfg;Om(-j*`^Ms4zuF0h!GfAESJ$|X52SuL4=*QBh_>v@LvMK3w_mU(V zHs)RYyCnIJ)$7lYWHYPhUn0pcYluHbl5MTNe~BbJSVR0PB_cf%|H8n&UKLXsY# zLXz(TTN)}PIWAO4a$7SY$+gXFBze6VUNmSXBze7=kYttSO2sr6lC08PNb)OSjay_U z$*-CVNlt2^)I$_^-nzH1BFRZDge1$hR4S@vW|A!1Qb_U??6t#i`eY)>Q!Rxg$HMw` zSZ0zO8}^bUOSHoEvsD%(S)!GYWC|Q=w9ZVDz%7!b{8t=B=(l8tPX>w{(b`Ut{%!Cs z4@zc=ECTdZ6xj>5)7&c)MfPeV6qy5Wa7;jPuc>?cDvHd}Rw(jQ^eNpg3yS=-tx#l- zc1oQ>$xM+w+6hH^zl+=2ce9{KHvFe3ay!N<(H_&tM3HRyUr=NR?EO&tEGUu<|7D8& z-P*;!OOYBLU`_MSP^72T^Dj|k4r_=%N0GU$zJG}#^I1duD-?O46R(nK-oiFpXQ9Xg zorEImcUG!>XQ9YyorNNYbrFgT?_#6K688{M6!+=t-oA<=>vR)}yp2AsyJx1z+uejBXLiT$oku$psMON*h z)T$ntDY9yhmlSygKFxY&L6KK_2t`issnqv9GgBmRxsMF$rPPXEneQWk+wLPT!^$JJk)%I*%;sL1NYX!CNHPW18oe{G?yE>LC0s~yB>LRwodrpb>@6f&tPkE4 zLdi^$#rgU9Nt%{D=3*sk}dxWlFSE?_OlSCQoOQ9_cHMk}>)bQUC8X|#~!ML0AWgI#BO*uFSgNb-GH zpN`3bB-!wvBFTzlF$FG}?j+grzaYsp>?dSg79`1r|1wEVz=sz9{=@b}tJj|)$thOP zzeJMLts(v#NzSnP{w0!}V-4}IkYpW$*VZ(yF( zk*Y=jJt=JX=nH4ii^AwWVy048XVM-&BQPh|P4h?Pq0#VeMlqV&(wU!%6fvfG7np_b zh0KzVjVQSY`WKi*sYQ&WoXM~}M9DXs78EtgcqgH5nvF$3%vsFnm$TMveDI7i&+;ft zk;M$3Y&8JT)c1{=Q6mHBhhj#!*ES$2v#E1&BT(Nqn?5Lx!3)m8=OQQ*=1?<#qfEBE zs8ieN((B=PJjMGgG4j$wf1{Sy3fOYYrSc`vf5jYnu^*o~jm)Ql$Ir#5dvhso0Pyj1 zDI@^nUIgYl4}Y0&-qMno^OtCv=1($bXGu(^EsO)_QISJfu0KlRaNEu!pHk?#9fk)e zIV0(8DRkY8x@lH)sbzuGqO`F*rv`Tb(r8w70S62xvPIVu@}xw&qd%hg8wyO}fCk5VdO zahfc}liN}XuZ(_8meSnH==UwKj>I=50YwX{!T2z;yy~l>6yv7(o%#nKos6;cO^mUC zl=_{hN)?Q;fT(*Fj1i0pf3l3vjKJJnH_dulD-Ge{bnv6$?-(^`MO7m_`wbX>LZR86 zo&FS14Owwx83k1{lDuj!S8B*|dQ{CQ=lvGyra4WLX>fI8q#m`Lu2sjXeXyKfR5y~n zPQv5nayn20`IBsU$FcY8|&)-hgZ@kZyDwE)D@KamXVm#FIuU)DEVV( zZcX5R(X_LsaZm3bL(#zq_23xZZ(jV(9oMINlw1p;9v(wOYr{O+GMCqb(#?@|U>+Ys zA$4JPTIPoOJL%@0Ax4D$+bTLxYD8iBA;c)c4WD{gv6`!u`gk=RuLsKDx@neGH5Bz6 z>?lUf20QXo`TE8*udiTf{4s5-kG1}4HC?NZo)I4__3g*BtO2-+>!vwYeSm*WbB1u$ zy#~hOoMqPFwrVY2oLoyEG{ljXSwjg8(fbmxCZF)<%K^oG@J9*C<2OcDSJ4{d_`pwn zWsP)MMoMgicu)BRZ-0NnCt#pH5t4r_`c#RI4#&&vnx*td-Mf%M=javMEM> zTGrT@=5rdBI_uf$`Y@X6zk`6EUPoc?V34seeZ8KtH^G5$9iMJ#F`X>ceD(cozq zXbpt&Lh3%|mOViGY z&9^yh=Qq&a=CEC|Z1=Q>V!P1-wrd+`Zc8IkUmh><>KcZ4p%LA|*g^GU9X|TE@l>M~ z7V~;MU(I%qZ)>AQ4v$Sdh03ZLui0xfytT1c_ufQ7ZID;FHc{$eM_?5Gutl~p#^KT|c2XM@x1fE%< z*E^e)+Ob*A-*IZEYLAE>!+(rRR+(lk9?Or`zlV4}1>S87U+V&>XGg5%)6F!rqmfiI zYK!dTJhrvBN*&(}#E%fsICWaRr@m7s)NXB_M3e)IL#xgGhoo;NUJ!=uA z%AGN?v6VtPV~Rz$;T?``{3H>Wo9m`|R9(QoR+{-y(=Nucock=?G#_oFvt2RbA6*O| z@6Rmo3D3R}FJhmrxE8kBDRY~+lRe9LH@Dh3IFjwCMK@e|LU-Y{v0c_RgVMTTBB8tJ zS~nxn`(qgP>~cM>{HQ|lc1AT-R&%J2chQmVnCb6uD40ky*WnOid!XmAM@BS?;D<;W&SM zcT>M`V1s~N+|3uM0IJ^`&VzPSSZ`bm{PxJPb-{L*tDgFb7!=q;HTvKJ^ca5GKEqu$ zO5=U>Yab-X<2~fx7o^%g8Cp#;UF!={ZG*aL2D`{9kh=CW`epCGA0KU?P<;pP1a9=h zqW3}5G~Z44d;4!jKd*@gaOF5a34g;t6HqtJVd)Nm{f&WMbP!*9J4nm=BO-H9H_e&s z@H)Rr5&g#cLyVZ_GuyFnX1PCzUvAkKx`r%5ktvQ+G<>CzKWb!l3cv0s7B#Y%yfjeE z>F}Z9uVc-=JVbK`;)JE_8pV7_yRf`%d# z_hIgEm=46^{-UUwh+TlOU$ z%jI2zf#TGdhw#`Q=WE^bUE!$C#6JqN*9uza`q(o>rwg*qj zZOo{XLNPxA>wSuE8v=^{inR&B=cU!PO^Wd>D8_rqDcrrJDmu{%CqtS8YqaDPU31{* zf>ZI%cq%P3aN*#(X^vMPDLPOP7Y^K!=ciu{W18;;Sk|0Y>Ntvb8qIWKeJ-R@f)m+Z zHVsegD1K*ffjdJZC&E@XjTTQdl6)P&ILkI-`^OpT9)TN%v1ceE0yhl7XYpdpS!y^5 z`B@Ql)AVD;c%33A8PR&vFDPiT5#U|>3$~PIO9NUk*;tcfjD-YgRpd%Bd>rrz410VKB{y zc&P@?)#=6u2=LAGH1|W;?pQWm_e#(CEg!*r|2%b{0rPj3xtJc1Zk{|7=BMW=Xcm_E zw~IWoX%@SrRHIAuY!;^c+eOj8CIee^iSm91Z1g30sM~ZI{NY>3@b`$lY*WB40e*6s zE+t_lE?pJ{ti=_jc3+{H^MJLuLXSSjDipYiE6i1DI2=b98Hpn-aFwDXVYm##v#YdV zADk~=rM>%rwZ5j*-fQGY2G;r-4P5}N*mZml?K+i@0#@ug&D{^|4zS;@^J{j2`km_( zvJhC;8%iC!LBB2p*7XK;KM1VsO*~!R*OWlOCIWl#H4R(_ zY~t6Hnu6;^(>svg?kFnVpRX6oanw!kP{eY0=ew&^g}YR1g%Rk1I>j6}c6rYM_;)nA zoG>crbM8{uN_ckp2FLRaWsim@>NM;mJm0vdRQ-FFGF3r;;~x3Pz%v$LuKRQ;2A-%> zy;NhD*P#12r2EW#f%>5P^e7h7s__74$pcH2s^EbJ9wz#_M{EhctH$+@k>g{*aoj#S~Dd&0k>P z8s90k`a4B~&f&0Xd`I0sf#=@=_J2f0*1;2Xn)D?+4?e<^&|^il&%^WJBMMp%&pD5= zDv#;GdU&EvtuDZ`%M&~UKT(w9D|mK!LN7MJv+PqmMLwlHaqvW)N?e5J4*+{T!!`RN zJb!pfsT;8Z`<^LP@q0xFFBug)(4fbcjL&k-{~lj=M9KAoqV1QB()yh5DS8u5?K(f; zEg+OVKTvprQO2Vt9QIv7kNW^?{RocuQPKNX(c{h!G;}k1ECu)wrRYyoWea*Ngu}dR z=+W#ad|ZTb;wRjoTt|<0exi`A=R>C}}V5zdM>17kK;QR-wAmC~6>+m`@E zgRUg5&vTJH+c8zMUK;Cx9PSMAa;b{Ova!}_J$Z*uD)k=6q=fKhB z)F?+ZJfm~a(39{SoKsWp=cMwd;E6hwh=J#AfUR?BbU6l|w{ucRD$a!j{6>tTJ{ld2 z#l+B{$FZ2$1RqV!_n}*-!5b5N$R`bBeh;iy?xnwDNK|RxY7DtQx27ujVqrEra2EiE z(D&!2YiDp*8ij8peeO%qXN__m^WZUW4cyNIY?ue}S&JE*_oaj{Fz$prn!1yR2A;#f zs8f$m;2DxvQycRlI_uyWl9wXBglD#Vni`dlYMqBC>QrexJktP% z8J%BKISNqrui%L~{k{R70}5#BLIFf34xR%FkpD$^zEx0DYYNh(i||C9PH)8Ft3sL@ zUWg7{!r`kz^ym^!xO2ct7RCw|rfrvT!lf0`C}tB*(MbSPQT|a_quvQPMe$^__X>Ih z`e|w+O1vLUy^0>?{E)nx(c?0}N<}o)y@*Ctx1h%bKbm_DJ>~$sj^b04+FnPG8E~k# z6+P+}MLbZFi)y58LyzF1)cpo}JO8S?4n+>wh#;GRIo zmO%<8A=}WP$BB+z-e-Z}b z+^i%_vAMFQj#L(=KwX%k?3S>&e|q+Zk<;TW+$_5AtFEc()m?PqS6%2L z31GPzLKmnDT}-K=sYf+jbTOrd&_(E5NY}T7E>IV`$X639Q`1Ek`DzMX+yodFEOddo z&_#T(ri#>Z(M5c)(1oLxroO2qbb-3iMdR9<+Fo1eqH%4Zi$ZlY)dwZ2j?hKEIxf06 z05DHoe9xq=i!S!o5xN)#Fd5}>U7?FXaIomYKLksMvMR(y7ezvZF46#&s;8+o^@J`? z!oi}8$pFuxX!Tum;jAZgQKi17rlD-FFLV(E2a7Il0jz(ad=wjPDLKkPT{pB4OT>uoisL=#h*d{KzD36Lo7rmRh z>7ql^mvj*c^pmD8xuceIM!BEH`}`C;#gaui$?9hA?<`NP#3z$gWs<*>0K9He z-W9q)UFf1idrci|@1lzi?S(E%LRXyI!9^En2wgk`s=p_6@vwu?ML&Ft>)d-5U7#v- zQLUq?}-yx-iAo&YJS? z;$n)eorNhTbkWq^F2WS33sW@eibd(_Vv0sxg(>oM(^Nz^VG7iRDXsu)*4@PvSGoyP z#C6wHp&r5%s0&k!>7l9HJ%lO7^bn?K(o<6lQ4aPLrfAgD#T3r~Ht2<`K`$3mJnAV- z5d-iEN{Mh`isf*ym?A73tA=tW+{F~l!i6dR0NA!Sn6I}m#cy!1m|_b+y^p4<_Hi*q zd~acjaDY2dZub$U=ne;qDe~e=c>Pco^>s0YPhVk*WB?XZ9O^4fkpjSCij#eXDbfH~ zOmVKS#T34`1`1QCL7IAF5S@M7S;hkxRT|*fo_Clg-!khC<3}izR?jFxX^ove-ks5e zC`E3~xJ7+fT1*)nJD8Te;|$Erb<=F1+Th>z?C(c6hTx-@U*B;~^J+0z zQ@aP#)Fw_S6@w|Ei8Imr88Gi58nt^HU$J;iEz(#%?ttI(^K39JZt6_*YCc3$y@ycS zP;_cOgd#$nNjWzH;~S*=L#SahXBqExR{KQy{F0hE`{gV+RGc~tWv9Yazd4R1uLa&s z_gvH5InZk+z?h+ww*`iZkY4QYI`wSfjMixwy=dVK@ScqYGEGYpZ$RNKouj>u0I4#Z zF12(9dZ11{suRjV{@&Qs7k)AoeBDg;k36kY-222 zZ|!d`#iy>s>?;m__woaRB#?qEhVv zMgz2%e)ni*`Zl;RjK_O4xG|&~9h}*{9stfih8}frmh--gx@p!+_D`~DPl|R3R|nOG_)IR?JV0Bbwg~C-Er(I#>=rMVS9T# zosGa@0+VA8n1F}b2}^qd%RfO5T{j%`sHZbPAL`%(PxM;v&{P3~j`u<;t#?qu6kuV7 zrjiUAI2Bl!LD#~8{S2(Hla}=c_On3|?*of<;xS<&)tUw@)=3F{kh`H1HMMJ^fc1G_ zQ)%y$V<@mb?^E}=z`Um6$~}#W%md~%jphym77wiObQ*aYSo|~!iUihrI@WSJJ%|L> zdOCF<0qh50;U7?uk-&bKPA}#ITloPVp+8(Y3ed_AC}^ zf%W-_W-bKwa$VI?beMHfVfVG@~-Oj)}g}_?QpwzLzegW2hCe0iN z?3WodbP2GvGm-MMsQgl3YiCmQc;`L6%`6HbY}?PGp$=?2%_5)W*meW%#J1Ngy0!w_ zzQ7}#iN2*HB?lW}I}q<$a1H{K99#!5DbmWp<-qv#)33~z96UW=a?pDLp2!wR4tg(; z9NY}7c$DPe<^__29i#A^5G6U-F-mgK1U77;ZfJPhp3<&uMk zmq`u|SgxrrmrD)~SS~r3YlWsJtdJbcwL)@mE3o1#B?q^zkQ{8k5?A|`l7sD6N)EmN zHYD20!51qf2jimg+!-S|7#A%$*daz!hhroMJH$v1s#r~ph?N{vv66!cz>2Su988Fn z9PGSGQ^!_G4t8E8Ihbv=rpBz69L%;_a&X&f$-$kgB?tGcmK@v*oOAF1-csNkJOZ3^ zaN0V_!8O>PSSL9MOmfg`Jtnf=%E8}&SvlAmpWZVMHrgOLIB|of9&C^toVY=9uyh<0 zk2uM}(s7c5CxO-4C^>jCPI7R}Mv(7D$-yxjB?tZEH8nflo`e4Jl7lB;`7vH{@Myf` zpwA{vIW|cS`fQRM+zPBjg5)6Tl7pQSG?kJdIoLTta!}ihwcji`sBM-Uj0aX|i!BG^ zH%kt-+=Ba!Es}#Rw@3~?1=ek=LJvR!iUwH;W?9g>5u?T{Qi2JEd*B?ph~kQ^NODV_~JwQ_Le zr;>yIJ8?SflpOTmDLHr?Snw{%!Q(q62gmM$h__2}aO^J0!BUCXZKC90sYJ=aRA6;? zOAe+cN)9@9<22kYIq29eIaqd&XfIDDTg2M;An4(>{p9DJG#bz{He;L~Ku!6o}O<#9lAaLInj!TJX@ zm2g0Eu>Jwb!TZ48J19ALA0MFewRpins2T_DIk@1U9vzY# zoO(!d@U_EG4-QKXqAod@3b4)*$-&gal7r)pVD0e{Ghd6x9g!RiII5{xM{PM6a8z<| zKMWO9BnS5&l^pDwf=7lF$-%xUl7rsIKn%wu2fdF;4sHVGcU*FC(=o}xHpij!9+wzo|GJ1a0;ZpG4j(!5wYXuL y|7IhX)E!nwl>Z$Qx`@Bar Date: Wed, 5 Apr 2023 23:11:00 +0200 Subject: [PATCH 13/30] fix weather temp field chars --- nspanel_eu.HMI | Bin 21307134 -> 21307134 bytes nspanel_eu.tft | Bin 6477376 -> 6477396 bytes nspanel_us.HMI | Bin 21307134 -> 21307134 bytes nspanel_us.tft | Bin 8051692 -> 8051712 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/nspanel_eu.HMI b/nspanel_eu.HMI index 9595461663401c66dfdda92af99d8886634e294e..c126f768937c27c65cec520ff55eb3d4f0db9a01 100644 GIT binary patch delta 1740 zcmdVYiC0u*9L8}jGc1B85hySWX=r5{&D5lTii|^r70tBRss(C`p=Q}OW(v*IT)_qC zf>%o+Of=i12D!G7mK9XQVr8~lQ5Km^;nJei^OLM|{0r=!^ZDNQyyt!2^PYQdZ&PJd zFO|2%&MufaCoMN`Qpi6~U7A*{BvtHRST!@R1i%GZ`m*7(5;WD`4!R5FDSK=y6#?`n6 z*Wx-{j~g%rQ*k41LOu#G4bw3LH{%xEirX*~x1$iVFdK7l2j=2V+=Y3#8~5N|+=u(& z#e6(~1$Yn(u?R&C#XTM7wKK3zFKF>68@W;b0WPJVUc1AauWxSi?$XOAFCAGE93HEb ztuU!xBWr!>A+zeUJVZW%;j=tkx6iyFtGmbG5hIT6HX8H%8|IsxrGpFmj*jlH{(H1} zXV;O0zUfu&|E5*1TQ$7y#hJC{h0A=^M;Fw1*CU1Ja!RI|^hMDn7JXAgRh1D;RhvWgqJdrYx@V7nP-C#Tc$n&Rlu#)x zp{2BpmQxv(Qw2Rj8dXvitstFN(kgnC9;4N?hN`KC9;aGbOHa@`s-yL^fu5v|^b|c! z&(O2<9Bra{dY)dO05#BNY9xcU(2MjEy-crA6TM1XX&b#puhVvVgWjaKsF_;mZF+~^ zrB-^6+Nhm6sFQZk`}6^QNIU5x+C?AJC-f5exiN!GX?1v`jvWUKOLZhbclYV-{}wflMd4n>ZQMyI2}qENkSziiCGdR3714j zA|?GKQIcp$f5`yJNs@t*7|F>J{{2qJDUvuzykwAMup~i}C`po7B*_x1Bt>$nWQb&_ zm{*oj?++b6^cU1T9?#dzJm&lTKE98c>F-z? z-%oYnM1!|%c2-gG6vJOfOIC2DVy-{XR39E3T&~2`?@S79P*PGAM`)Y5L{Y{CN2YDE zj?bFo{dGnU3J?PiXtPKD4Jq)w>`FX>wjTD z$ZfAXglyy>7ZWfMlaPnW$cGaJaG?-q;~boeB22+~I3E|F7#E@hZcN2RxEPmU8ZO0U zxE#}Q1+K≪SE}4G+ASiCMS?*Wx-{j~h^i8*vkE#x0nQTQLW>;dac$9k>&BVIJ;= z5A(4A_uyXKhx<|9RA%zc%vq{g`3GHrxe&D3U; z&rQ}nX7!+=<)^F3dRJl9OrzGhr^2GGZ)<4K`_k1dQCfLIZ>#3s6&R{_B~(?63i18x57RPQPAh07$=a)EHLamX=uv8+ zwX}{NqsQq9dXk=^r|B75Pp$MUJx3vGqvxreblN~K(2MjEy-Xdnkvgf1UZGcM6TL>8 z>2=ydVS0n!q_-$SZ_`%lrXJcx+vy#8m)@iI=>z(ZKBAB56Z({P&}Z~H?W8a0OZtj> z>1+CicG0)=9qpz)^gaDRd+A5&qkZ%f?WY5DkPgvd`k9WNwg$J5-W+593zRB94k3aGDvc~BtbG*a)N~atkW?>k|ar%43!L%q)1XFW{E|T zCb3F}OHP!Gkc^a^BuSTyl8ly|EICDTsw6{lnj}+lx@3$bOLB(9Cb3J-l#G=Oyo0mk nYMf-eBwLar$(2lyOq5KLD>jRa-U diff --git a/nspanel_eu.tft b/nspanel_eu.tft index 6f8bf4ad86d88d347795d7f8765402dd0d895c8d..acba335ff68b9c75e4be5d15c1fd95dd13cdf19f 100644 GIT binary patch delta 20788 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 HYW)8It)#$J diff --git a/nspanel_us.HMI b/nspanel_us.HMI index ea19762be04dc2d481dc4cd04234ad85c166969c..ef53475f39c1f266835e3a9d57ab86bce6438436 100644 GIT binary patch delta 1816 zcmdtgi&qq77{~E_*Og6#5)f8g5H>3{SClklbX9gSyV=D;rHhGXR(4@DNGVE|ePq@a z(Hz{dtibMxVzlaXQ@R+HTCOW)r3JY~b_K$)8*9HuJ9+9a=s4$mzURz4^PZXKoHw$) zIywTPZ-dA)8=IxTOtUj#WM*cDJjZbA>I%9Ib4TDF#{Bz{VS2=^)}$s!g`MSwTA}Vp zO;TG2mI{M9%W4rKP;9jr#n`}#REtP9{AcUt7O$Zy*I*E;)0Pkj4oWwQEVVP;st&dF zQ&Vg)LJADCby-XmOO9;vI3&d(2{1x0FhOsK(jAg{XVYmgf=8AV88gb5QO1liW|T3b zj2UIgysGJc@&bNFj7p z5ndcn>RjdE0fJ>vq1U;TZE>c;qA3eBd^JU@Z&e3q1y#NrJtO4X>cUT~50w-s?V18! zSgyBg4@upoL*07##1`G1r^M#|{i3O@w7&V|^1Q^#Q_Cs44wjr;-rM5+XITm5SHcRY zf|ale9){JRLN%-bKWMNP9)U+;9Xtk)!xK;gwXhzZgs0$Xcm|$@=iqsG0X9G#Y=liv z51ZjdXn>a>09#-yYy%x$hF9QKcnw~M?XUwH;SG2b-h#JbC%gkq@GiUu@53(G4SV1N z_z?C&5cWX`_Cqs#1Ruiz_yj(M&)^^&g3sX#Xn|Jv5)MNczJjlz4ZeXR@GX1?-@^~^ zBm4yI&;gzBGjzdG_yxM*82k#q!SC<~{0Th}f#beVzE}wyBc~U~#Ock6;+Q#SaQbkf zIej@XoLJ78oU=InIB}eKP6DStCy|rHv2X@(k~sr8R!#~hl{1Kw#!2VcIA?PPbI#$M z%Q=rTgfo;gjB`F`ILFQz!O7r^`i|GWibYI delta 2329 zcmdVZi(gY^9LMo>%@q6o*ox{esJ&kA&+FMa=h>d;?5uvTqiH>; zO}DA3MxC>wWR$UQU^gYMvt_)}_^K_pDoRI1Q9=3VDW&#?RausTb1B-TmPloo*k{WS7 z#87;5U4dpW$LFS+ZK-Azbf5Oo1=lX_8a>O+00A0< z=y{q>FVGB{Nwa7+&7mxMk>*l1&7+rSJ}ua8tu6Q67&WNj`Ao!f=2LXs8ZBIVW*Fw5 z)VUwwiF!rJ1Ablh#wDtIe8Z?H3p~f?G*cAe8T;3^Na@tD@u-Md?Zv+ z7JA0RS~q^qv9^km?LO|U435NPu_oBwLuAyR36i~?)>hu4#(p+hBkI*+v^XnBwyLmN^2V2m==C0xYGvCWFF~VezmSrx@p~@S<_RT)hSgj4! ziSi_SKj9ylV-g2Kb9#yTltm8t(p7Dk=S-j7i$^vb6w^eONjAHtCH#Gk|Jub)QMI8U zOzv-QAFCG&;_P8XC$vHl+b$zEkdN>KJE`SXh)Qnv*R|ru#b*b?yW5K%isfpW~#E#_`UUjpO)m$0eWQdGR{c zM`YYwF<7{o+k-@GNRCma56Hs?V((}%a`@<+z6Mb(Y)0GalpM$ff`yPLSEtxYn;34d z3HOpQOA4Zr`7VsN;d01_MY38fHeWN$EiAeya78OQv);Ng$bGZ6PQkMG2j)a}HVkcF zZErX)wz#wwGGj?WwkpS*)$j}WU&$ZRuo%ycxKmt!n}o$hsS=-1*{R_>4TqwQUEJSr z@_2!-XCclsyUm&QGAx0mund;N3edm-g-`?nUV&HPHCPF&;B|NdieWXZfj40-tb_Hi z0p5bQVI#Z)@4_b73|n9;ya(IheJFwLume5-2|M9K*af>`5A20~upbUUDIA24;A8j% z%HR+jhEL%L9EH!|bNB*|K{*@;C!ByU;VU=^r{FYv4d1}GPyye;_fQEgI0I+l9Gr(A z-~wEPAK@ps1V6)NsDdj{4K?r!T!mVwgJ0nqT!$O*8{CB7;TGJ6dbm^IOjDNvN5|1~ z3>+_xH^<1ii_?VDl+%pk!|~-b=lF5_Id^jcIDwoXj)@b@3E{NhgmPMP!Z@ustvTVG zHk`Jc2u?drdrl|&y_}AmD9(MHXif~L6Q?uheoibWj?;zn04JW)mD7!rz)9qo gIo&xuI7ytIoL-#XoIaesoPL~Sb-y#MzZz5a2Y%hXPXGV_ diff --git a/nspanel_us.tft b/nspanel_us.tft index 182435eab96ebb148ee2104e53e0e915ae622797..d85c712874b12c58a4bd916d9a33aa4bc41aeeed 100644 GIT binary patch delta 20070 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 delta 21061 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 z Date: Wed, 5 Apr 2023 23:46:42 +0200 Subject: [PATCH 14/30] change weather field temp chars --- nspanel_eu.HMI | Bin 21307134 -> 21307134 bytes nspanel_eu.tft | Bin 6477396 -> 6477436 bytes nspanel_us.HMI | Bin 21307134 -> 21307134 bytes nspanel_us.tft | Bin 8051712 -> 8051752 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/nspanel_eu.HMI b/nspanel_eu.HMI index c126f768937c27c65cec520ff55eb3d4f0db9a01..314db184a2414384b1991f8af5b15d8aab1827a7 100644 GIT binary patch delta 1706 zcmd7Ri&qq77{~E_cZW-$L0l9TmNc}|E!wS3L2+eSsXfEcBRt1REBl|_i0Da zWNCmQLs1K@Or;hXyAY(ATOnXqD>W<2k}$lWWk&rT(Eq_X=ktB%oSFBXcjlbwZK{aq z1%EI`=P8(z=E|L*J9pHjDXWFC{A6``Fj}b*;pGS80^3AFq8J_6W1J{Nx-v9*M{Gvg zT+jI#JkAXI6mv?V5^V|(5l)@XrkG5Fg-)4did9^u4lyc_n6fxVvhSa!DjgP^x78xI zS_J6901|{isMcx;JKKIiZp+s0bz5b(Re&B0AVCO(YHn*-ecOd_L%?nIpQ3cipfNO- zGHD#yX*^|-gR;pv-CeY1v3*Ab&bQ?`1H%+43=?=f-9>lP z44O&zP#)!zhi1{ebRXSM572}35EanF^awplvuO@JMssN%&8G$QI6Xm6(n5NQ3TY87 zrl;u{dX}D}qK4uV9a5EcW~J&0`jRzQgm0iz_4gEe)U9oWdsY9G<>uP%;W47D${-hN z_VuNwCE1&_1iV0+H|hDhqtZr0m|nvIBl_oRjk&%Ji=@oiUGw^vjT|7KTUP6glvg;V z@a@NI`YzQLt`Z_a&5!V9Y35@~opJo|0(FQ{Hmfs=7Q}1$M!83*S*dco){;{)%b+%Q z7AL7&8Y(Nb?o@e~UM-3`RIj=Z`vz$(Q6^;ID5;i(CF|t8YFW#xUOIWYXVI8~zuRY=d{;U3d@PhbH&{ znxO?ggzc~cK7yU_G38px_zixCBhU$dKo=Z^KcO3r!ErbNC!q&U!D;vl{)RK~51fU6 zp%?yJ=CFw};OIF9j>HM!gmS_-;hc*&5u8ZQ0M0H7xP^VulQXihpOgENLRmXpaD$FXz9bFw%NPBzCWnjN+r(RAd00vT^e delta 1695 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 K(fyPStu6s*Q%OYt delta 1610 zcmd7Q{eM<-9LMpUYu9!ujk0Fd+S*}vy1n;`5*Md^L5VSd%lnJ{XEXOGG9HUj4 zK4Y@&_oXJpH3vL#cD^swFrvl23CYI5=$c*!JVtJGc{k1@zj z@~0VjcD6sw?(6RwA4;jQ*QfW4n*J@R-dWRISJ;_>9#!Fh6%H8Wp?LCA0wucPfUj}u z|9E))<|;E_nVin#bS9@WIi1PrOipJ8e6>f)1`cEN?}I!9Fc?EH6!{p2;Rs>`3Q&j; zMq(63;~boeF*pxnaXyN00WQQvxEPlpjAC4h%Pg-&*xgRf zoJenX+pg+G-JL1pYDye4xw6P@>QXtt;{iXm9@FsY^PJ z-myKBROrOU%r0^GIMEqjRMTz+vu4u+ZZIp-I?=oHpxe^1xja_E&6?A@XU59rj>U?w z_1~h!Kban+IW(7QX&%idn-!`=X%Rg}i|KJ%LQClhdXk=^r|B75M$gi7 zw49!&I;y7?w31$+RrDggL{VBzYiKRG^fJ9d>u5c_N*m}k+DMzIfnKLK=uLWyHq+a* zh2Eie={;(st@J)^qbAx;AJB)?Odrt>`j|eUPw6xIoOaR|^d;@0ujp&qO)c~deM@`j zJ8Grx=?D6e_R>E3iP~sC{Y<~m0s57Gql5H29il(zPx_1grgn8f;7j#HAA?#khVj@MnP(nIN~^itB4-b%WXq4ZHQ z6~A(Va-x!@oTQwroTBtqvXy?ysY;G=nsT~whSFa-Q#nf+pbS*bRt71#N}du>1}j69 cp-R3oOc|~Ol@UsTQmBNCjiHp0#=1`b0+We2`2YX_ diff --git a/nspanel_us.tft b/nspanel_us.tft index d85c712874b12c58a4bd916d9a33aa4bc41aeeed..44525cb01ed94ae3f3210c97d8c964bbe3d52bb6 100644 GIT binary patch delta 20677 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 LES5UGPE7rOFgbmz delta 21014 zcmeHuhhG%O`~S?IbWk+d6^NLqpkl|wg1w@k#@)O|T?tqKU?uXw3cIvjdkSpXBxZ1Ae(MxtaI#>@&0Te&)TiyXV$@j|_<@ z$xS&+X*TQqw2qf+?EJmto5_P~wRo|#iycVw2E3Kt+M8;`Dy;z`&tz(K&z^Kpna%S z)2eGVv_LILtEtt}YHPt-9j&fbPphvr&>Cuuv=FVa_L26n)@-`Ydy42w4Pcot+&=k>#OzC`fCHUf!ZK# zuokHe(S~Znv?y)37OjoYMrxz9(OQf)MvK+P?lJyYS6Qu4p1-jQdDSzH;5NEY&lo^G zB8{b7-!W!j>esQ0`vg;qu*XVeTmE?YW&mk2zVB8Q^0 z{Fm-ddN_L48vb*wu5FAn{)(CrQ5e-IqlR?Tqt@+)s4?CC@2IVN!2go9Zx4s4%Odsj z4~xY4&%^m+lxri63;wSGE*XkYm8{!`I)ow&LCobEBVye$>am^}|L<5om=J5Y^{vS` zr97WY>O7-AkF~CxXDsK%`&f4`H^$ajn#kScY}YzsYyj)fBgRjPb1$p)ywSTVA7?%J z!q}=R-)r?KAJ?j?@>>OKc(b_LRe5#m)FE+^u6&R+e^i{&iBGkL8{?A7@)p+onQ@V2 z`Fd-MwQ=!fd1>pOz2bY0wffmOzeBF>j74(B+^pgAOcgo3xnS~k<1RMF0gk5`^G(5Y z>fJbRIx^psm@pn-Nyb=QS;mqd+HAtnLxCgk1}KiWX90c-{^wm7tMi-m_bR~4{0%Q& zfIkLqOThmUrN3(d-VsC{USKj&CmV*dXuipxET|=jG1L`MaLU0_{H?I#vn>G~s^(>2XBl0(U)* z&O$-#zvIG}F^Wqv9av&4Mu)DLJl(jfWGD0UWs3l;^w2*u8#1HKG6T=b7)9Qqf0IdJ?r`X}fetSCfb5`hGZqT?bg z0v9X_JO!oj5XX*1WIJ2%7c2_@f5Ih7brzcr(3|IRSbT2sfOIk}F$ME3jlczs0v`by`3eZ= z+&dV~MS_4HKrMm8M=&US&Y;*C1TGj9_$d@SgAVxDz~Q2Q9OIn(7yLYM{5kq3=p9@r zL}3zv1cRdEA`Ai-3<~@!l)^(CI~I}uhlK*izvKES7-g;mgWtoa2!kGy!S89tDy+iq zY4<9uLg7_}K6nZG1Rf_!;dK$XpikgM=mRe36L>jvZ(oJL1$_c9LLYEJpTK8{>)&du zLeUT(h32g?Rnx~LAY91x563ZrPJul{vC|1$&?)fyD0Vs>@SlLg<$vNl`WO5$X9<7N z;L!2UIH2$&1|;Yd9T%Y!xS&(uKcEyI;&=ighMhL}iv=nC|H3J9t?AVJV$`vYzMhCD z{D7m%Y&2<|sXE0~dC!F`>rAr~grOK5?2N%nFj;u|j<{e_;7##mXAJ&=Nr4Ca4Hrxb zJQVTmI~n*3CIw!FG3&HcQ(azJw2EY%mpny*d(pa0rkZld%7%g=zd{82(BND+WI?zi zUO43Pjzfcg;gJ817Y@0&)Fjjfbm8NgRT%zWbfN|RM4(?(YV(i6G z?0E-Vhr zV5bkbpikgMXaX+i`zKt`C-5Tl!C%aiz=iaG^|{G}u{7CY3f9LWa65PK72FA|9EzPg z;DS4WmqD>}=YUrLjz9gw9pY5{7rc_zy){0|1X?IZZ(}MUmaKx+Db^@>eP9gxM<&;=uLCC;i4@Zi!cXA!JNQj9hn0z zm=kyr=70<4{s|Y%3A_k%@OLf1KLc}fwu_7QEeyv!Ox-_f-!;DK>1rB9Ty|9 zGX{UbSaqtHZn{>!DGn(@lD9NBC666gTTQ9S4y-NVRfHjU35End55eqf3%FoN;6)e$ zE*SbJTrec?A`HRbwE*7;hC1%V+Gwm%96j@si2ed7Wf>0umV5)GC_O%6EFeUJ2D0ZeC;)s#hnF21D68?YT z^e_W!D*{*%+Db~_2s)h!+9K#}CTJ60MQDSUpiSW09BBhCXcKr5+JFn%{s|Yf3A_kx z@E5cR{IIy9?E-BPG-(%T6PPG=+Tbf_6WAvxcG`do+63Mm#ZH?8-U~SX^bdE4)B9iW zK1FDAIG}G~6oe9i1Z{@E3Fm-1l#|piAJ% z!0me`_zSuOUIkA&zS?Utl@|?hiulq$e~q?B7DoG1emukx2MX?l??@CoN5BPl0+0R| zd^B+U*<%;RiTM|N3~>9D%YLKv4q^+VAe0zTDB6XCw{r(va3}ELD1Qs2<6$L-djp5#!~}@r1nxsgm*RrBMop&14{j(B z(Q9GPj-IncF9jcghvLD3j8LLKqavf5xazGXv4vof5=RS7<)6n7@Lg&)#RmF##zQXJuHSfXRIZ!&u%?oY*!^G z)&VCl9&JA#&W7%h?JZ~zZOmDzFlXI<1MNivI6HDrw!M^+tjUNToQ<30!p@*WU&WJ^ z#Qtf+Iu~7x0+j$3FrBlX_P8)JI_QG7hDUN0-gnj8acKXBM@*d-$o68i$KY9j#Tqoi ze6uP2`M_M99`7@|lkX<;d0J>g^N&sD8#FZswVVSm{IVH_wU5l6bn0{SE!@>7e{z!Rh7)xO6-@ zjN@zX02D>G9p(qL@Jn+!`g5oGyrL=ebTlH}&p@Q;*=jlZIuo_7b5P6r0<~YZA^Mxq zh`Dwb0(2nbZu2>>i%4o4KF{!7hC1&t2k?tz++)slj%WyxXh`$dnyV;n8dBz3^KqU) zepzNeK8`}O%vPuLMvNV$w^`;OCA|?Prkb;yZGgsvP}BA1K*iRGy!V;2oHmCr_8y(y z2e-{36tMwrT^lo&)0hUFHwW^rl)v9>b$$(K_($~k0gim#nEW@vE%hT@P(P;0Hn^oy zMmGBF_%ZHgDJBQOI(|$oE}0KFzXIgnWZ7l&hx{2O97L>-nlQGd3C(|mSRXYZ?<f9nFqH8O(}UB+(Mc$wz(Otz6Q4t@;eN-JAlHQQ_UxE zyVHy!)8IC*Ib*Mz)0l7IHjkbh!N_WdGPau1j$&lBLn-lw`98l!xyL~A%}|QCWxh{` zj+vcl$#L^t%nSGV)w$vgEAz!w|Ly30uM;6BavaRH) zLp#Rywv#+{Xs7e!{0p!F?di-u`2EsOC(4Q1<62Ao&*P-1J>A}qa4kBZ%MOyL79Au} zKLYFBQ720Iu>)mh!*5YX2wf){lY=u^M4^|=*-oLI7#l^lOXg}ylTMU)5MI*(J?*4Z z#ivt=E11Zdof%t6r>~&Tnw=>k7hYEZwF#3&P4N&ACPI z$@O#_Sl8bAdQxupl041njXrxzp62wHJk{&NSZW{1Q@uWtr<=e!_SJb(ZuXH&YIa`; zZ(p&b6s@mLl+$TIAJM!=IOEfO<&v7vkFk6G^d+TC=qH)->(AJN{*o!b{&G!y1uSHM zzNVC~`s-9V#SdWY4h20yxcC8bO;sMq*qnj-no=qclvL#bt361kO353juPSBKAe}2E zc96cT6w@G`EM>wVeNiduAe}8`${@Lx z8qwHHMN6`3L`$+R0&6isl65g!k~L`rV?U0NWK9|&$*MXMm*A0-tg0g=Sr>r49jTLb zcBEWYKBE|$K1vFp&nU^(Az(E}OSTS;l5C9}&Dhn^lC6=WC0nIp@Gdk)vQ;WZF0342 zfn(&t%88M5MUP?Z;uuL+^cYE(TP$Or#!9-}VkKR>VkKQ!v68L>v68Msv68MMv68Oi zv68M+h|zegr0Z0yPM6m!lccN6IN0b>aWz1BWzyLy6$j`u6mby~A0Mt?2bHLCg_o>c zZ`Ds37q1iNl^&047D~zSjD1KOOCnNwyx?zF$+%)Hq#@ugC~Hu5(Y#V>0B=YcrBtie zVIbe2)SbXsJBoh~mcvBvsVDeQ8tkL`@t&06qdst3n;^!r9G8N_{&-t|W16K@N?dh1 zQ(Eorv;nq~6i`MD;u|QujB0i1n#kC}L`FYHS}IduS=AGl!;rG7)hTEil7ya@g=-M` zl>>4PNK?95P7QJsRhz9MEG3Vq6)CX1y4=k&9g2i0DI=4xcRo?^Jdna6NkVftt>H(7F#{>8)FiE2nhJk!rB? zCu4P32J4pZl)JiRQ4Mvn*W!61jLo(i-&d((AV$8JLIc%oFPHh!(j4C@-jWftHrk)FV!+?-F|HPtMq9e^s*>6)099rU^;CaU*BOgQbX1*A9S*8;+m@Klgi z)ds@pL~YgTyctNTWT8X8UOsFzi@;0_V<~JiWd!4ZFx>O*rMW$l$QmifSiQ}T#82&t&66<0#D^u{wm73H;Pb+CeJvH0uC6H=Vt-e}K`89Z`}yyDXCD*$2z;J9AkVy}1S%)0`$ZP%Ta~0j#384KOnn@@uGC-DWRltj7{OT&Mho zYBfHaTp9tr1SEASV_(yWMnEsolSY{GD$7LlVv4Ii<)s>fj1MWdF)V?)rIO;WTkd`Y zOKnQ}7?ygvrGe5|x9n;HOCuWGRJAHu%L%_!DnqrKspUiiJE~nC_+3ZHv*p-?tzhKU z%TgIn3W~9GymZ;YK4j09;|3Vnv}gs!v4S2qSH<3@Y$#T8>i+{e8rm3DK-i8^RIx1cgVybXqrcV?Cv5TsN4`kzaS1F6pLG zNPqpPRy|<4Mo)UE*78#~i-0!U=lK4*pf1`zGghFis!wR0ahH>6Md z0J#F>W2)a5$Q2sg7mB8ClZS7mfPQL#%LKjoix_&#lsIo%+fR*hbK4<(Ldc^(R)`Y? z_Xk^sop=tpQN*hkcoh1syIRTXIcv}A;lHZf%m$JT4o>@FJWtsJ zF^K*2U?4)3&R{GkL+l@XWvJ40ZV={cEbz}z#2h((GU?nvwJaY?*1*fSI8?P3-v%TP7Zv4|sR>Tos6Ib=VC zZ@)OC$f?(-647dIsU8RLEDojcWFE_Hfoppmn~gA4smcg-HLl*dBlN3x{s{Gfl9Vkr zC4uy8q?!Zi&KQNnrfd;rkFrk}kc*>{WveJ529|ZY<&1J3mMXMpj5^%ijJWJJLe*w#YY?YCC{B%ZItZXT9gRbjgY+a0Bk7ALDK^_2!vZ+fqf+BA#(|VO z4wfOhWxZjuZn+x|%Wz5>56dXsvfpq}x9pk#ODqkZ2%>5ol@r$!-&2lKr9iccQtPO` zX57S@$pBuN3}$Fh#!<@asb;x!JH}Y5pt&cvtp< z)I2}7%%Wy_rF_ZQpyPPLhjNsTT9EE3^uU6h)@>j=PB3-}tr?8={XQrnluH@4^C3*6!o~GoTA&~&AzTLzY+(%uU~`COjS4V zU@|74pZce8bA=Lcnz3P2KM^CSPrVbt(lj90+fBp#PNUFiYIfnLL;EE{!8aix^Zx>>Mnp@iA6r0JFql|bFHVU9Yvc-DD2tgHBbcb;m_ z1z}m|=(>MpH38gK>X`H)6-Uo5%S$Y}2Sh`GS4#I0GlXLd11fDKihQWv($c;~I@QjEH4u@M2tA zZv*Oboza4)Y7OP~HA*}JzwOrorMzvlbWZn((KaLGf$W81yY2$Jb7eeQjBbaiFF(b`e zfxQx{^y>+Augh6rKcKPWq*{ZYrFAPY!uH?damu%h&c0S_7|@`@U#WXtOMiz`L7}cq z)JnAS6b4zEjH@w6_kh0nj%uz^0}ZHC%4r1dm(SRVd`4Z)AaFklT?@w#ZsTlj>vBRB z)~TKb05s$*yr072dWTWvuW<%XZS3IlOy&k94 znDW;{R^9L6VK%MXpjI!2Je! zY(+#=$#fNdw}Ewi2rjM(dLNMgHgK`?q1gJ~+y+NfspWMzsy{OJ;73O9uA^&}o@`gM zJv#q{M?NSge!|x48})rddsIr^Q1`pN0^0Twu8_1U9jfr`C(27#4|r?@^a3T|G0ycS z4p{ey(Vd$(p!;LY6Ur5e*$FM^N=ZA>L9w41>xJ^!&p79A;m=U{;#>Id0qXh-9&J#Q zO!#Ng;7s^O1KEf2;1@;%^Wi@fm1+6#FY|=4(I_j(V;B5OQSdJHf#KK_M&0hHKk$=e z+l}@awBNsn_IWzD7wyYv|N6c9gL3@|rCQaj;`d+3weI{9ug6}>wSNDFzSf;a152RJ z`*FU5UdksI+g~l4ulg!$Udg3??G-%BjLm%W*GgB) zzoFz5M7#^b?=URFBE0)XU+YeN--;W&n8WC}?^}vojD;ES2VTnkA=f$&poAlc`7x=B&Qio2@eXXgqsL1z$`KTP3<=ioPlju)$Cn7%@K1fI8*GeKu*s#4os-{j zM6>{VV53dTF&K-D&M!yLZSm4(7vr>G1+uFxJvo7B-gt{uozhMs3sI%@E7iTubAkQF z>C9_%I+t?4!bYr*!r5_@zZSXy5SdmZX+Jb@*37`E)*6KUkdjU#>>6P1)cFj;qDn2- z!fzyg9(JV|ryWPlmG!00N7CT4aIWvfS!b&FHJnkUlBsas0j#1kr?aUDx`TqxVG&Mp z=Ilpcd)GsQ(4af()%`AATsZsG1w-GUet_Mo?L5vt8Q32#lydHTf+`xV$AFHYZX!|MOllUiIyUgdak z7D#We!x2^bbvu^NLcChPiQ-O=zQOXDOC@e#xqVcEv)L%t5}ekgW4Sd%<#0Ou?*k3- z=D4TMzKQj4w*=k3iS@q}(2pqPO5$91;(!!yPANNaK>L!Mtw1?R^S(s~ttsPMbnqHT z=Tdm>Q;JiwO!z;?fkQIkzYXYHltAjA5C6@SkPrX9?{T&R<<@&R_g(PsiAvpFSkNvM zeg_NM15c><9<)o4-#xV7L;J#Bw9C?y@6oP^_Ij(jw?vKdT;FSS#CKeIWYAnh14yPl z=7TOffF41k%YLBiQTbx6`Afsk6%c&BTG?dmI`z} z(BIK`Cr~u#*9G9BXC=-KS3(Xh1d0ZgJP5R6WzOnVMzS3QiUu7{0-6l;Pc-%(0*VIR zIRtcoFK1u*VpMU+VsWK60HKr=m_G31tf?PNi*NuM^hF-f)j-|+LB(O9XwZh&d1G>8*Iw+rC7Jqmh((5TY;$KiPpSYTC7o0r2A4Z5%#=4v24@RvP^GWoj=GeErvL{9N?A~z z)}T7)plgQ$Ijb2|pbKc|y5N)?#Ib`eVZ#mi{GeqQ5b+X_(3(;eP?xGOu_kACYf4p6 zCf20$7vb5Y7H3;)(fmv38+Bb5oD8**rIe;vf)qn-O1%ufvw)feOI<)+>cXmE&RpwA zT~Jm9Q`}W}M%Ur&aviF94G~e7%Fv)LXY1=0C_{s~x-vN10LIp%Kd!?QbzK_VFVy4A zw?5{tK0W>h+uXDD$omG?`eb0IQQp)q5C=0VLLA&{G{A~R+17w^ZsLd!8c21x4y0J6q&m3I1$qm`qY=&j7Dvp)E75P!$H$F81j@li1^Unk6`>FAkAXH1!Ei%p zKt7Imh5>~x=4&^CPiXCzIQh(5D9=%B%T6wYF;1`-viY}qH<_~NO+^7i$o{WoqUkA=U z=vW{V`#MOOn9-55RUM^Fpe}a~?*PVh(svHZyN*&PPItnobuOY4fTT{W0G`>oKqpq< zwWrVt?=a4$gh`!1UFyV5fE~Ix>cq`3sS}@f;p|WssS~J6o$&99ob6hm6aHPLPW%FJ zKzM;ppdt4UdExkl1W>VmP;$a`r7%QrW{i+Zfx1+R&jFU|R-hE0M@XfJ>BiahZc-^w zmph31-8oC`uJ0g}`rUP@aC!$UhECVD1Q}43N^!aeXN^B8P>R!dlPZ*A*(aRgjj65_ zs7s}Y>dD!Ko&`z~h4-o0LpTTb;%rSXsT8P7rQp3eUX)@6@nTdc#k*coDbj(xMG5Rv zpcGqs7br#FKAdew`KFIlik^L>Qn>cTbfL`aTc8xhP!anG_X9vZ`$78pNu|i@E0tn2 zutO+6_bX6}XjF8isMMdcu_$Z$OQk5+Un<2JVE*_`OZb2Sr8wEYKq)K(q*6?UMOTXH z1Ef;S1fVO$+yPQ476K4TQGE3fsT4W*zBhzCTU)B|)fC*?lI>J(C}*wcNoz|rgU?XR z{z!A{l(Di@A6x`3XCQe_D2~oyF?v6vbI(6#c0sZEtV!#B)w-drP+4 zaG>Jh%0`;h!4klS(7Fzm?9%58Q19W=Dm=E*y7rc`E@yPp_f+@{^}CLikxp&k*OxkX zLWIU->|{CN-XmHbnJ%9J8rnr;7W=EMX?17IIOjxIA4ii<7&f$t6dGoE;2tnS9MFun zM89DL)*R`nn~Sn{yeC+B0CNxW=!J{%gBWVu%aY|ZcMPsk^c)bj&VIcu58QqS zVzaGf8^rw8r&fI|>B>92$n9gf@5W<=Eel%&-Bzj}PREII`{6J*-SjoPC{1_!!{kLt z11#3!y^M0$6Y;&qNS;$HRSdxN^K`ud@Cgdlj=<@E4Om=^l!hj{J=Nl?R5vY4uw*$8 zHF0*%L^%myV<-hj;$&RMaW;`2MdD;!$IUvKh{}gx|rsDT= zQ|VR;ybTmS4ly$T`I1LGVrERGr;Fg#KLHYvK)V+!-QMB5DtS!73IZgvZOAMP07Yh7&sj3t_%h0$YVpHcGTT)2 ze{?qPjVL<-{U4o8bs{m!QFA!EHisTZVw9ukTp}nbH5c3Uxq7lGrRFXhYRPiR22^97 zL$dK~S~ndLqvnAG>OTV!qvp~1VU`2VCFkQ(FkjC#tP`V#h@Sw;n=e!Cllgk8Ill%r zd;txJ2Jx@w>$&EXx`4Cd^mZnqr7obj5g1>`g`8OzQq7SVUq>o28_}Kt8knT#n(}NR zwHO7r#Yvc&B>H0%+!j;*91JZand8aGs<{Xjl1$z)@VW`8eTq!Bo5?cS5>hyOl%gk_ zl8{2T$G|UO5obw@Xmu>2;hD?=bb10%{l$8=DJK?D=2*DJEXLd|rZGmi#ZY(>IxVpT z*IM#OMyDl~P-2`V%XJ^1YD*o{jqfAB6ft=~FVW2uF?mZVVjMzxFT+3iTSlJo2H}_PjZtvFV>K2m9*``!o-IS12nQ`9&>%3miIOW?^sc$pabM|7r zOu3os^^^PUV1lC}a%({~s zW!A-P!p>%s%(|FOQsI0yb2fdmu5gOaW|?*efdzf8r=4k zVT-?APdtUTNu6u5owF_5W#%>6E;BD5Sm!i7^OXGUQt4)-;XWlzS2|@zn#{eL>DZQ| zI7nU1bSZV$0k_|wOPz8(U1p!QgR|#5^z2i#9a8M-?8I}jox0d5b#}`9y9KOshMs@Q zt({WtW@m8rIzyK`Wp;+lzy_IEf|+^-Dh)Dq!BcK$>M5vvpQ$UJ@(?(3PGQ`2lbI-pg@5VL8vOu>9WU2L`W11BBg?7<j{~GpPZB#*yp6ozyT*^ a21cHg85jjz$lypa-n8s3mejY{ Date: Thu, 6 Apr 2023 00:13:08 +0200 Subject: [PATCH 15/30] Added `continue_on_error` to service calls (#608) This will make the automation more resilient, however it could hide some errors, making a bit harder to troubleshoot. --- nspanel_blueprint.yaml | 164 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 41bffaf..89cef98 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -3692,6 +3692,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages[entity_long_domain] }}" + continue_on_error: true ##### BOOT NSPANEL - boot init ##### - alias: Boot init @@ -3707,18 +3708,22 @@ action: data: component: boot.bluep_version message: "{{ blueprint_version }}" + continue_on_error: true ###### Set local fallback ###### - service: "switch.turn_{{ 'on' if relay_1_local_fallback else 'off' }}" data: entity_id: 'switch.{{ nspanel_name }}_relay_1_local_fallback' + continue_on_error: true - service: "switch.turn_{{ 'on' if relay_2_local_fallback else 'off' }}" data: entity_id: 'switch.{{ nspanel_name }}_relay_2_local_fallback' + continue_on_error: true ##### clear notification icon ##### - service: "{{ nextion.commands.notification_clear }}" data: {} + continue_on_error: true ###### NSPanel beep ###### - delay: @@ -3728,6 +3733,7 @@ action: - service: "{{ nextion.commands.play_rtttl }}" data: song_str: "two short:d=4,o=5,b=100:16e6,16e6" + continue_on_error: true ##### NSPanel boot init finished and jump to Home Page##### - &delay-default @@ -3736,6 +3742,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: page home + continue_on_error: true ##### PAGE CHANGED - changes when page changed ##### - alias: Page changed @@ -3755,6 +3762,7 @@ action: entity_id: "{{ entity_long }}" #hvac_mode: 'heat' temperature: "{{ display_target_temperature_state }}" + continue_on_error: true - choose: ## PAGE HOME ## - alias: Home page @@ -3785,6 +3793,7 @@ action: - service: "{{ nextion.commands.set_settings_entity }}" data: entity: 'unknown' + continue_on_error: true ##### NSPanel Date ##### ### DATE Font Color ### - &variables-date_format @@ -3795,12 +3804,14 @@ action: data: component: home.date message: "{{ page_home.general.date.label.color_rgb if is_number(page_home.general.date.label.color_rgb) else ((page_home.general.date.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.date.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.date.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### DATE Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.date message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom(date_format) }}" + continue_on_error: true ##### NSPanel Time ##### ### TIME Font Color ### - *delay-default @@ -3808,24 +3819,28 @@ action: data: component: home.time message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### TIME Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.time message: "{{ time }}" + continue_on_error: true ### TIME Meridiem Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: home.meridiem message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### TIME Meridiem Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.meridiem message: "{{ meridiem }}" + continue_on_error: true ##### NSPanel Outdoor Temp ##### - variables: @@ -3837,12 +3852,14 @@ action: data: component: home.outdoor_temp message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Outdoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp message: "{{ (outdoor_temp | round(1) ~ weather_units.temperature) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" + continue_on_error: true ##### NSPanel Indoor Temp ##### - variables: @@ -3853,30 +3870,35 @@ action: data: component: home.indoortempicon message: "{{ page_home.general.indoor_temp.icon.color_rgb if is_number(page_home.general.indoor_temp.icon.color_rgb) else ((page_home.general.indoor_temp.icon.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.icon.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.icon.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### ICON Indoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.indoortempicon message: "{{ page_home.general.indoor_temp.icon.icon }}" + continue_on_error: true ### LABEL Indoor Temp Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: home.current_temp message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Indoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp message: "{{ (indoor_temp_state | round(1) ~ weather_units.temperature) if is_number(indoor_temp_state) else (mui[language].unavailable if indoor_temp_state in ['unavailable', 'unknown', None] else indoor_temp_state) }}" + continue_on_error: true ##### Weather Icon Home Page ##### - *delay-default - service: "{{ nextion.commands.printf }}" data: cmd: home.weather.pic={{ nextion.pics.weather[states(weather_entity) | default('unavailable') if weather_entity is string else 'unavailable'] | default(None) }} + continue_on_error: true ##### NSPanel Buttons ##### - variables: @@ -3892,12 +3914,14 @@ action: data: component: home.left_bt_text message: "{{ page_home.hardware.buttons.left.color_rgb if is_number(page_home.hardware.buttons.left.color_rgb) else ((page_home.hardware.buttons.left.color_rgb[0] //(2**3)) *(2**11))+((page_home.hardware.buttons.left.color_rgb[1] //(2**2)) *(2**5))+(page_home.hardware.buttons.left.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.left_bt_text message: "{{ page_home.hardware.buttons.left.name }}" + continue_on_error: true ##### SET Left Hardware Button PIC on Home Page #### - if: "{{ left_button_state not in ['unavailable', 'unknown', None] }}" @@ -3909,6 +3933,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: home.left_bt_pic.pic={{ left_hardware_button_state }} + continue_on_error: true ##### NSPanel Right Button Name ##### - if: "{{ page_home.hardware.buttons.right.name | length > 0 }}" @@ -3919,12 +3944,14 @@ action: data: component: home.right_bt_text message: "{{ page_home.hardware.buttons.right.color_rgb if is_number(page_home.hardware.buttons.right.color_rgb) else ((page_home.hardware.buttons.right.color_rgb[0] //(2**3)) *(2**11))+((page_home.hardware.buttons.right.color_rgb[1] //(2**2)) *(2**5))+(page_home.hardware.buttons.right.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.right_bt_text message: "{{ page_home.hardware.buttons.right.name }}" + continue_on_error: true ##### SET Right Hardware Button PIC on Home Page ##### - if: "{{ right_button_state not in ['unavailable', 'unknown', None] }}" @@ -3936,6 +3963,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: home.right_bt_pic.pic={{ right_hardware_button_state }} + continue_on_error: true ###### Status bar ###### - &variables-home_page_status_bar @@ -3987,12 +4015,14 @@ action: data: component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" message: "{{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }}" + continue_on_error: true ### ICON Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" message: "{{ repeat.item.icon if is_state(repeat.item.entity, 'on') | default(False) else nextion.icons.blank }}" + continue_on_error: true # {{ is_state(repeat.item.entity, 'on') | default(False) if repeat.item.entity is string else 'unavailable' }} ##### HOME VALUE 01 - 03 @@ -4026,24 +4056,28 @@ action: data: component: "{{ 'home.value%02d_icon' | format(repeat.index) }}" message: "{{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }}" + continue_on_error: true ### ICON Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "{{ 'home.value%02d_icon' | format(repeat.index) }}" message: "{{ repeat.item.icon }}" + continue_on_error: true ### LABEL Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: "{{ 'home.value%02d_state' | format(repeat.index) }}" message: "{{ repeat.item.label_color_rgb if is_number(repeat.item.label_color_rgb) else ((repeat.item.label_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.label_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.label_color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "{{ 'home.value%02d_state' | format(repeat.index) }}" message: "{{ (states(repeat.item.entity) | round(1) ~ (state_attr(repeat.item.entity, 'unit_of_measurement') if state_attr(repeat.item.entity, 'unit_of_measurement') else '')) if is_number(states(repeat.item.entity)) else states(repeat.item.entity) | default('unknown') }}" + continue_on_error: true ##### Set notify icon ##### - variables: @@ -4057,6 +4091,7 @@ action: data: component: home.button04_icon message: "{{ set_button04_icon }}" + continue_on_error: true ##### SET ICON Font Color - Notify ##### - *delay-default @@ -4064,6 +4099,7 @@ action: data: component: home.button04_icon message: "{{ set_button04_icon_font }}" + continue_on_error: true ###### QR Code - Icon ###### - *delay-default @@ -4074,17 +4110,20 @@ action: data: component: home.button05_icon message: "{{ page_home.buttons[4].color_rgb.on if is_number(page_home.buttons[4].color_rgb.on) else ((page_home.buttons[4].color_rgb.on[0] //(2**3)) *(2**11))+((page_home.buttons[4].color_rgb.on[1] //(2**2)) *(2**5))+(page_home.buttons[4].color_rgb.on[2] //(2**3)) }}" + continue_on_error: true ### ICON Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.button05_icon message: "{{ page_home.buttons[4].icon }}" + continue_on_error: true else: # Display blank icon - service: "{{ nextion.commands.text_printf }}" data: component: home.button05_icon message: "{{ nextion.icons.blank }}" + continue_on_error: true ###### ENTITIES - Icon ###### - *delay-default @@ -4095,21 +4134,25 @@ action: data: component: home.button06_icon message: "{{ page_home.buttons[5].color_rgb.on if is_number(page_home.buttons[5].color_rgb.on) else ((page_home.buttons[5].color_rgb.on[0] //(2**3)) *(2**11))+((page_home.buttons[5].color_rgb.on[1] //(2**2)) *(2**5))+(page_home.buttons[5].color_rgb.on[2] //(2**3)) }}" + continue_on_error: true ### ICON Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.button06_icon message: "{{ page_home.buttons[5].icon }}" + continue_on_error: true else: # Display blank icon - service: "{{ nextion.commands.text_printf }}" data: component: home.button06_icon message: "{{ nextion.icons.blank }}" + continue_on_error: true ###### SHOW All component when page loading done ##### - *delay-default - service: "{{ nextion.commands.show_all }}" + continue_on_error: true ## BUTTON PAGES 01 - 04 ## - alias: Button pages @@ -4325,6 +4368,7 @@ action: - service: "{{ nextion.commands.set_settings_entity }}" data: entity: 'unknown' + continue_on_error: true ##### Button Page Label ##### - if: "{{ button_pages_labels[button_page_index].label | length > 0 }}" then: @@ -4332,6 +4376,7 @@ action: data: component: "{{ 'bpage%02d_label' | format(button_page_index+1) }}" message: "{{ button_pages_labels[button_page_index].label }}" + continue_on_error: true - *variables-weather ##### NSPanel build Button page ##### @@ -4389,9 +4434,11 @@ action: btn_icon: "{{ btn_icon }}" btn_label: "{{ btn_label }}" btn_bri_txt: "{{ btn_bri_txt }}" + continue_on_error: true ###### SHOW All component when page loading done ##### - *delay-default - service: "{{ nextion.commands.show_all }}" + continue_on_error: true ## PAGE LIGHTSETTINGS ## - alias: Light settings page @@ -4401,6 +4448,7 @@ action: data: component: lightsettings.light_name message: "{{ entity_long_name }}" + continue_on_error: true ##### LIGHT ICON - ON / OFF ##### - variables: lightsettings_icon_font: "{{ entity_long_icon if entity_long_icon not in ['unavailable', 'unknown', None] and entity_long_icon | length > 0 else nextion.icons.buttons.light }}" @@ -4410,11 +4458,13 @@ action: data: component: lightsettings.icon_state message: "{{ lightsettings_icon_font }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: lightsettings.icon_state message: "{{ lightsettings_icon_font_color }}" + continue_on_error: true ##### LIGHT State ##### - *delay-default - if: "{{ state_attr(entity_long, 'brightness') != none }}" @@ -4423,31 +4473,37 @@ action: data: component: lightsettings.lightslider message: "{{ (state_attr(entity_long, 'brightness') | int * 100 / 255) | round(0) }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value message: "{{ (state_attr(entity_long, 'brightness') | int * 100 / 255) | round(0) }}%" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value_2 message: "{{ (state_attr(entity_long, 'brightness') | int * 100 /255) | round(0) }}%" + continue_on_error: true else: - service: "{{ nextion.commands.value }}" data: component: lightsettings.lightslider message: '0' + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value message: '0 %' + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_value_2 message: '0 %' + continue_on_error: true ##### LIGHT Check Color_Temp Value is available when yes send some current Values ##### - if: "{{ state_attr(entity_long, 'color_temp') != none }}" @@ -4457,16 +4513,19 @@ action: data: component: lightsettings.temp_value message: "{{ (state_attr(entity_long, 'color_temp') | int ) | round(0) }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.temp_value_2 message: "{{ (state_attr(entity_long, 'color_temp') | int ) | round(0) }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.value }}" data: component: lightsettings.tempslider message: "{{ (state_attr(entity_long, 'color_temp') | int ) | round(0) }}" + continue_on_error: true ## PAGE COVERSETTINGS ## - alias: Cover settings page @@ -4481,27 +4540,32 @@ action: data: component: coversettings.icon_state message: "{{ coversettings_icon_font }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: coversettings.icon_state message: "{{ coversettings_icon_font_color }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.cover_name message: "{{ entity_long_name }}" + continue_on_error: true ##### COVER State - service: "{{ nextion.commands.value }}" data: component: coversettings.coverslider message: "{{ (state_attr(entity_long, 'current_position') | int ) | round(0) }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.cover_value message: "{{ (state_attr(entity_long, 'current_position') | int ) | round(0) }} %" + continue_on_error: true ##### COVER Battery ICON Yes / NO ##### - variables: @@ -4523,18 +4587,21 @@ action: data: component: coversettings.battery_value message: "{{ battery_level | round(0) }} %" + continue_on_error: true ### ICON Battery Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: coversettings.battery_icon message: "{{ nextion.colors.grey_super_light }}" + continue_on_error: true ### ICON Battery Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: coversettings.battery_icon message: "{{ nextion.icons.battery }}" + continue_on_error: true ## ENTITY PAGES 01 - 04 ## - alias: Entity pages @@ -4688,6 +4755,7 @@ action: data: component: "{{ 'entity%02d_label' | format(entity_page_index + 1) }}" message: "{{ entity_pages_labels[entity_page_index].label }}" + continue_on_error: true - *delay-default ##### Entities ##### - repeat: @@ -4704,6 +4772,7 @@ action: data: component: "{{ repeat.item.component }}_pic" message: "{{ repeat.item.icon }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: @@ -4713,11 +4782,13 @@ action: {%- elif repeat_item_state in ['unavailable', 'unknown', None] -%} {{ repeat.item.entity }} {%- else -%} {{ state_attr(repeat.item.entity, 'friendly_name') | default(mui[language].no_name) }} {%- endif -%} + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "{{ repeat.item.component }}" message: "{{ repeat_item_state ~ ((state_attr(repeat.item.entity, 'unit_of_measurement') | default('')) if state_attr(repeat.item.entity, 'unit_of_measurement') else '') }}" + continue_on_error: true ## PAGE CLIMATE ## - alias: Climate page @@ -4733,16 +4804,19 @@ action: data: component: climate.climate_label message: "{{ entity_long_name }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: outdoor_temp message: "{{ (outdoor_temp | round(1) ~ weather_units.temperature) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: current_temp message: "{{ (state_attr(entity_long, 'current_temperature') | round(1) ~ weather_units.temperature) if is_number(state_attr(entity_long, 'current_temperature')) else '' }}" # mui[language].unavailable? + continue_on_error: true - if: "{{ hvac_mode != 'off' and is_number(state_attr(entity_long, 'temperature')) }}" then: - variables: @@ -4750,18 +4824,22 @@ action: - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{ target_temp }}" + continue_on_error: true else: - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "0" + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: target_temp message: " " + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: heating_state message: "{{ heating_state }}" + continue_on_error: true # HVAC Button PIC - variables: @@ -4770,6 +4848,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: heating_bt_pic.pic={{ heating_bt_pic }} + continue_on_error: true - variables: hotwatercharge_state: "{{ states(hotwatercharge) | default('unavailable') if hotwatercharge is string else 'unavailable' }}" hotwatertemp_state: "{{ states(hotwatertemp) | default('unavailable') if hotwatertemp is string else 'unavailable' }}" @@ -4778,6 +4857,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: hotw_bt_pic.pic={{ hotw_bt_pic }} + continue_on_error: true - if: "{{ hotwatertemp_state not in ['unavailable', 'unknown', None] }}" then: - *delay-default @@ -4785,6 +4865,7 @@ action: data: component: climate.hotwater_temp message: "{{ (hotwatertemp_state | round(1) ~ weather_units.temperature) if is_number(hotwatertemp_state) else hotwatertemp_state }}" + continue_on_error: true ## PAGE WEATHER (WEATHER01 to WEATHER05) ## - alias: Weather pages @@ -4800,6 +4881,7 @@ action: data: component: "{{ page_name }}.day" message: "{{ (dict.values(mui[language].relative_day) | list)[page_index] }}" + continue_on_error: true - *delay-default ##### Display date (long) ##### @@ -4808,6 +4890,7 @@ action: data: component: "{{ page_name }}.date" message: "{{ (dict.values(mui[language].weekdays) | list)[(now() + timedelta(days= (page_index))).weekday()] ~ ', ' ~ as_timestamp(now() + timedelta(days= (page_index))) | timestamp_custom(date_format) }}" + continue_on_error: true - *delay-default ##### Display weather data only when available ##### @@ -4871,6 +4954,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "{{ page_name }}.weather_icon.pic={{ nextion.pics.weather[states(weather_entity) | default('unavailable') if weather_entity is string else 'unavailable'] | default(None) if condition == 'unknown' and page_name == nextion.pages.weatherpages[0] else nextion.pics.weather[condition] | default(None) }}" + continue_on_error: true - *delay-default ##### Display temperature min/max when available @@ -4885,6 +4969,7 @@ action: data: component: "{{ page_name }}.temperature" ### Temperature MIN/MAX ### message: "{{ temperature_string }}" + continue_on_error: true - *delay-default ##### fields 1 to 5 (Parameters) ##### @@ -4895,17 +4980,20 @@ action: data: component: "{{ page_name }}.value0{{ repeat.index }}" message: "{{ repeat.item.value }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "{{ page_name }}.value0{{ repeat.index }}_icon" message: "{{ repeat.item.icon }}" + continue_on_error: true - *delay-default else: # Display "Unavailable" - service: "{{ nextion.commands.text_printf }}" data: component: "{{ page_name }}.value01" message: "{{ mui[language].unavailable }}" + continue_on_error: true - *delay-default ## PAGE NOTIFICATION ## @@ -4916,11 +5004,13 @@ action: data: component: notification.notifi_text01 message: "{{ states(notification_text) | default(mui[language].unavailable) if notification_text is string else mui[language].unavailable }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: notification.notifi_label message: "{{ states(notification_label) | default(mui[language].unavailable) if notification_label is string else mui[language].unavailable }}" + continue_on_error: true ## PAGE QR Code ## - alias: QRCode page @@ -4935,11 +5025,13 @@ action: data: component: "qrcode_label" message: "{{ qrcode_label }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "qrcode_value" message: "{{ qrcode_value }}" + continue_on_error: true ## PAGE SETTINGS ## #- alias: Settings page @@ -5055,6 +5147,7 @@ action: - service: "{{ nextion.commands.set_settings_entity }}" data: entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }}" + continue_on_error: true else: - if: "{{ last_click_button.confirm }}" then: @@ -5069,18 +5162,22 @@ action: - service: switch.turn_on data: entity_id: "{{ confirmation_message }}" + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.notification }}" + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: notification.notifi_text01 message: "{{ btn_entity_name }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: notification.notifi_label message: "{{ mui[language].please_confirm }}" + continue_on_error: true - wait_template: "{{ is_state(last_click, ['notificationacceptrelease', 'notificationclearrelease', 'homepage']) }}" timeout: seconds: 10 @@ -5091,9 +5188,11 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ buttonpage }}" + continue_on_error: true - service: switch.turn_off data: entity_id: "{{ confirmation_message }}" + continue_on_error: true - &service-button_changed service: >- {% if entity_domain in ['light', 'switch', 'cover', 'input_boolean', 'automation', 'fan'] %} @@ -5113,21 +5212,26 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ buttonpage }}" + continue_on_error: true - service: switch.turn_off data: entity_id: "{{ confirmation_message }}" + continue_on_error: true - conditions: "{{ is_state(last_click, 'homepage') }}" sequence: - service: switch.turn_off data: entity_id: "{{ confirmation_message }}" + continue_on_error: true default: - service: switch.turn_off data: entity_id: "{{ confirmation_message }}" + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.home }}" + continue_on_error: true else: - *service-button_changed @@ -5158,6 +5262,7 @@ action: - service: "{{ nextion.commands.set_settings_entity }}" data: entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}" + continue_on_error: true ##### LASTCLICK_LIGHTSETTINGS - changes on page lightsettings ##### - alias: Changes on page lightsettings @@ -5176,6 +5281,7 @@ action: data: entity_id: "{{ entity_long }}" brightness: "{{ (trigger.event.data.new_state.state | replace('brightness','') | int / 100 * 255) | round(0) }}" + continue_on_error: true #### wird nicht mehr benötigt, da es im nextion editor nun direkt gemacht wird # - delay: # milliseconds: "{{ delay_value }}" @@ -5210,6 +5316,7 @@ action: data: entity_id: "{{ entity_long }}" color_temp: "{{ trigger.event.data.new_state.state | replace('colortemp','') | int }}" + continue_on_error: true #### wird nicht mehr benötigt, da es im nextion editor nun direkt gemacht wird # - delay: # milliseconds: "{{ delay_value }}" @@ -5232,6 +5339,7 @@ action: data: entity_id: "{{ entity_long }}" rgb_color: "{{ trigger.event.data.new_state.state.split(',') }}" + continue_on_error: true ##### Page Lightsettings - Close Lightsetting Page ##### - conditions: @@ -5240,6 +5348,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ entity_back }}" + continue_on_error: true ##### LASTCLICK_COVERSETTINGS - changes on page coversettings ##### - alias: Changes on page coversettings @@ -5258,6 +5367,7 @@ action: data: entity_id: "{{ entity_long }}" position: "{{ trigger.event.data.new_state.state | replace('coverposition','') | int }}" + continue_on_error: true #### wird nicht mehr benötigt, da es im nextion editor nun direkt gemacht wird # - delay: # milliseconds: "{{ delay_value }}" @@ -5279,6 +5389,7 @@ action: - service: cover.close_cover data: entity_id: "{{ entity_long }}" + continue_on_error: true ##### Page Coversettings - Cover OPEN Button ##### - conditions: @@ -5287,6 +5398,7 @@ action: - service: cover.open_cover data: entity_id: "{{ entity_long }}" + continue_on_error: true ##### Page Coversettings - Cover STOP Button ##### - conditions: @@ -5295,6 +5407,7 @@ action: - service: cover.stop_cover data: entity_id: "{{ entity_long }}" + continue_on_error: true ##### Page Coversettings - Close Coversettings Page ##### - conditions: @@ -5303,6 +5416,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ entity_back }}" + continue_on_error: true ##### LASTCLICK_CLIMATESETTINGS - changes on page climatesettings ##### - alias: Changes on page climatesettings @@ -5325,6 +5439,7 @@ action: {% endif %} data: entity_id: "{{ hotwatercharge }}" + continue_on_error: true ##### Page Climatesettings - heating ##### - conditions: "{{ trigger.event.data.new_state.state == 'releaseheating' }}" @@ -5334,6 +5449,7 @@ action: - service: climate.turn_on ############ data: entity_id: "{{ entity_long }}" + continue_on_error: true # - service: climate.set_temperature # data: # entity_id: !input climate @@ -5343,6 +5459,7 @@ action: - service: climate.turn_off ############ data: entity_id: "{{ entity_long }}" + continue_on_error: true # - service: climate.set_temperature # data: # entity_id: !input climate @@ -5365,6 +5482,7 @@ action: - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{ (current_setpoint + delta) | round(1) }}" + continue_on_error: true else: - variables: current_setpoint: "{{state_attr(entity_long, 'temperature') | default('unavailable') if entity_long is string else 'unavailable' }}" @@ -5375,6 +5493,7 @@ action: entity_id: "{{ entity_long }}" #hvac_mode: 'heat' temperature: "{{ (current_setpoint + delta) | round(1) }}" + continue_on_error: true ##### Page Climatesettings - climateslider ##### - conditions: '{{ trigger.event.data.new_state.state is match "climateslider\d+" and trigger.event.data.new_state.state == states(last_click_climatesettings) }}' @@ -5389,12 +5508,14 @@ action: - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{ new_setpoint }}" + continue_on_error: true else: - service: climate.set_temperature data: entity_id: "{{ entity_long }}" #hvac_mode: 'heat' temperature: "{{ new_setpoint }}" + continue_on_error: true #### Page Climate - Close Climate Page ##### - conditions: @@ -5403,6 +5524,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ entity_back }}" + continue_on_error: true ##### TRIGGER - HOME PAGE ###### @@ -5462,10 +5584,12 @@ action: - service: "{{ nextion.commands.set_settings_entity }}" data: entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }}" + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.climate }}" + continue_on_error: true ##### JUMP TO - Weather Page ##### - alias: Jump to weather page @@ -5478,6 +5602,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.weatherpages[0] }}" + continue_on_error: true ##### JUMP TO - QR Code Page ##### - alias: Jump to QR code page @@ -5490,6 +5615,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.qrcode }}" + continue_on_error: true ##### JUMP TO - ENTITY Page ##### - alias: Jump to entity page @@ -5502,6 +5628,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.entitypages[0] }}" + continue_on_error: true ##### JUMP TO - notification ##### - alias: Jump to notification page @@ -5514,6 +5641,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.notification }}" + continue_on_error: true #### SHOW BUTTON - notification #### - alias: Show button - Notification @@ -5543,6 +5671,7 @@ action: data: component: home.button04_icon message: "{{ set_button04_icon }}" + continue_on_error: true ##### SET ICON Font Color - Notify ##### - *delay-default @@ -5550,6 +5679,7 @@ action: data: component: home.button04_icon message: "{{ set_button04_icon_font }}" + continue_on_error: true ##### SHOW BUTTON - notification clear ##### - alias: Show button - Notification clear @@ -5562,9 +5692,11 @@ action: - service: switch.turn_off data: entity_id: "{{ notification_unread }}" + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.home }}" + continue_on_error: true ##### SHOW BUTTON - notification accept ##### - alias: Show button - Notification accept @@ -5577,11 +5709,14 @@ action: - service: switch.turn_off data: entity_id: "{{ notification_unread }}" + continue_on_error: true - service: "{{ nextion.commands.notification_clear }}" data: {} + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: "page {{ nextion.pages.home }}" + continue_on_error: true ##### BUTTON - press ##### - alias: Button - Press @@ -5615,6 +5750,7 @@ action: - service: "{{ nextion.commands.set_settings_entity }}" data: entity: "{{ entity_long }},{{ entity_back }},{{ entity_long_name }},{{ entity_long_icon }},{{ entity_long_icon_color }}" + continue_on_error: true - conditions: "{{ button_context.hold_select == 'Custom Action' and trigger.id == 'left_button_press' }}" sequence: !input left_button_hold_custom_action - conditions: "{{ button_context.hold_select == 'Custom Action' and trigger.id == 'right_button_press' }}" @@ -5636,6 +5772,7 @@ action: {% endif %} data: entity_id: "{{ button_context.entity }}" + continue_on_error: true ##### BUTTON - state ##### - alias: Button - State @@ -5654,6 +5791,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: "home.{{ 'left' if trigger.id == 'left_button_state' else 'right'}}_bt_pic.pic={{ current_hardware_button_state }}" + continue_on_error: true ##### DATE AND TIME ##### - alias: "Date & Time" @@ -5669,23 +5807,27 @@ action: data: component: home.time message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### TIME Font ### - service: "{{ nextion.commands.text_printf }}" data: component: home.time message: "{{ time }}" + continue_on_error: true ### TIME Meridiem Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" data: component: home.meridiem message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### TIME Meridiem Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.meridiem message: "{{ meridiem }}" + continue_on_error: true ### DATE Font Color ### - *delay-default @@ -5693,12 +5835,14 @@ action: data: component: home.date message: "{{ page_home.general.date.label.color_rgb if is_number(page_home.general.date.label.color_rgb) else ((page_home.general.date.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.date.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.date.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### DATE Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.date message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom('%d.%m') }}" + continue_on_error: true ##### OUTDOOR TEMP - entity ##### - alias: Outdoor temp - Entity @@ -5715,12 +5859,14 @@ action: data: component: home.outdoor_temp message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Outdoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + continue_on_error: true ##### INDOOR TEMP - entity ##### - alias: Indoor temp - Entity @@ -5737,12 +5883,14 @@ action: data: component: home.current_temp message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Indoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + continue_on_error: true ##### INDOOR TEMP - nspanel ##### - alias: Indoor temp - NSPanel @@ -5761,12 +5909,14 @@ action: data: component: home.current_temp message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Indoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + continue_on_error: true ##### WEATHER STATE - change update ##### - alias: Weather - State changed @@ -5785,20 +5935,24 @@ action: data: component: home.outdoor_temp message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true ### LABEL Outdoor Temp Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather_units.temperature }}" + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: climate.outdoor_temp message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather_units.temperature }}" + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: home.weather.pic={{ nextion.pics.weather[trigger.event.data.new_state.state | default('unknown')] }} + continue_on_error: true ##### Sync Climate ##### -> muss noch in page changed climate wwenn climate page fertig - alias: Climate - Sync @@ -5820,26 +5974,32 @@ action: data: component: current_temp message: "{{ trigger.event.data.new_state.attributes.current_temperature | round(1)}}{{ weather_units.temperature }}" + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: heating_state message: "{{heating_state}}" + continue_on_error: true - service: "{{ nextion.commands.printf }}" data: cmd: heating_bt_pic.pic={{ heating_bt_pic }} + continue_on_error: true - if: "{{ trigger.event.data.new_state.state != 'off' }}" #### TODO AND->OR (not) not optimistic-mode then: - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}" + continue_on_error: true else: - service: "{{ nextion.commands.thermostat_cycle }}" data: value: "0" + continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: target_temp message: " " + continue_on_error: true ##### Sync Hotwater Charge button-symbol ##### -> kann wenn climate page fertig - alias: Hotwater - Sync @@ -5853,6 +6013,7 @@ action: - service: "{{ nextion.commands.printf }}" data: cmd: hotw_bt_pic.pic={{ hotw_bt_pic }} + continue_on_error: true ##### Hotwater Temp ##### kann raus und wird durch neue value 01 und value 02 ersetzt wenn climate page fertig - alias: Hotwater - Temp @@ -5866,11 +6027,13 @@ action: data: component: home.hotwater_temp message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: climate.hotwater_temp message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + continue_on_error: true # - delay: # milliseconds: "{{ delay_value }}" # - service: "{{ nextion.commands.printf }}" @@ -5887,6 +6050,7 @@ action: seconds: 2 - service: "{{ nextion.commands.tft_upload }}" data: {} + continue_on_error: true ############################################################# From 124b9d87d5eb5ac35b96ca539246b125e327f3b8 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:14:10 +0200 Subject: [PATCH 16/30] Remove `+` from positive temperatures (#624) --- nspanel_blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 89cef98..574973d 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -4962,7 +4962,7 @@ action: temperature_string: > {{ (temp_min | round(0) ~ weather_units.temperature) if is_number(temp_min) }} {{ '/' if is_number(temp_min) and is_number(temp_max) }} - {{ (('+' if temp_min | float(1) <= 0 and temp_max | float(-1) > 0) ~ temp_max | round(0) ~ weather_units.temperature) if is_number(temp_max) }} + {{ (temp_max | round(0) ~ weather_units.temperature) if is_number(temp_max) }} - if: "{{ (is_number(temp_min) or is_number(temp_max)) and temperature_string is string and temperature_string | length > 0 }}" then: - service: "{{ nextion.commands.text_printf }}" From 5a0715064d385afc725332f01e4a639545d78cbf Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:19:43 +0200 Subject: [PATCH 17/30] Roll back temperature units to fit screen (#625) This should fix #617 --- nspanel_blueprint.yaml | 83 ++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 47 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 574973d..7f2dadc 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -3097,6 +3097,7 @@ variables: ##### WEATHER #### weather_entity: !input "weather_entity" # used only during the creation of weather in variables + temperature_units: '°' ##### Home page ##### page_home: @@ -3768,28 +3769,6 @@ action: - alias: Home page conditions: "{{ trigger.event.data.new_state.state == nextion.pages.home }}" sequence: &refresh_page_home - - &variables-weather - variables: - weather_attribution: "{{ state_attr(weather_entity, 'attribution') | default('unavailable') if weather_entity is string else 'unavailable' }}" - weather_type: > - {% if 'AccuWeather' in weather_attribution %} AccuWeather - {% elif 'OpenWeatherMap' in weather_attribution %} OpenWeather - {% elif 'SMHI' in weather_attribution %} SMHI - {% elif 'met.no' in weather_attribution %} Met.no - {% elif 'OpenWeatherMap' in weather_attribution %} OpenWeather - {% else %} Other - {% endif %} - weather_units: - hours_of_sun: "{{ state_attr(weather_entity, 'hours_of_sun_unit') | default('h') if weather_entity is string and state_attr(weather_entity, 'hours_of_sun_unit') else 'h' }}" - precipitation: "{{ state_attr(weather_entity, 'precipitation_unit') | default('mm') if weather_entity is string and state_attr(weather_entity, 'precipitation_unit') else 'mm' }}" - precipitation_probability: "{{ state_attr(weather_entity, 'precipitation_probability_unit') | default('%') if weather_entity is string and state_attr(weather_entity, 'precipitation_probability_unit') else '%' }}" - pressure: "{{ state_attr(weather_entity, 'pressure_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'pressure_unit') }}" - temperature: "{{ state_attr(weather_entity, 'temperature_unit') | default('°') if weather_entity is string and state_attr(weather_entity, 'temperature_unit') else '°' }}" - thunderstorm_probability: "{{ state_attr(weather_entity, 'thunderstorm_probability_unit') | default('%') if weather_entity is string and state_attr(weather_entity, 'thunderstorm_probability_unit') else '%' }}" - uv_index: "{{ state_attr(weather_entity, 'uv_index_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'uv_index_unit') }}" - visibility: "{{ state_attr(weather_entity, 'visibility_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'visibility_unit') }}" - wind_speed: "{{ state_attr(weather_entity, 'wind_speed_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'wind_speed_unit') }}" - - service: "{{ nextion.commands.set_settings_entity }}" data: entity: 'unknown' @@ -3858,7 +3837,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp - message: "{{ (outdoor_temp | round(1) ~ weather_units.temperature) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" + message: "{{ (outdoor_temp | round(1) ~ temperature_units) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" continue_on_error: true ##### NSPanel Indoor Temp ##### @@ -3890,7 +3869,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp - message: "{{ (indoor_temp_state | round(1) ~ weather_units.temperature) if is_number(indoor_temp_state) else (mui[language].unavailable if indoor_temp_state in ['unavailable', 'unknown', None] else indoor_temp_state) }}" + message: "{{ (indoor_temp_state | round(1) ~ temperature_units) if is_number(indoor_temp_state) else (mui[language].unavailable if indoor_temp_state in ['unavailable', 'unknown', None] else indoor_temp_state) }}" continue_on_error: true ##### Weather Icon Home Page ##### @@ -4378,7 +4357,6 @@ action: message: "{{ button_pages_labels[button_page_index].label }}" continue_on_error: true - - *variables-weather ##### NSPanel build Button page ##### - repeat: for_each: "{{ button_pages_buttons[first_button:last_button] }}" @@ -4419,7 +4397,7 @@ action: {% if not current_entity_state_available %} 0 {% elif item_domain == 'light' and current_entity_state == 'on' and state_attr(repeat.item.entity, 'brightness') != None %} {{ (state_attr(repeat.item.entity, 'brightness') | int * 100 /255) | round(0) }}% {% elif item_domain == 'cover' and current_entity_state in ['open', 'opening', 'closing'] and state_attr(repeat.item.entity, 'current_position') != None %} {{ (state_attr(repeat.item.entity, 'current_position') | int(100)) | round(0) }}% - {% elif item_domain == 'climate' and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None %} {{ (state_attr(repeat.item.entity, "current_temperature") | float) | round(0) }}{{ weather_units.temperature }} + {% elif item_domain == 'climate' and current_entity_state != 'off' and state_attr(repeat.item.entity, "current_temperature") != None %} {{ (state_attr(repeat.item.entity, "current_temperature") | float) | round(0) }}{{ temperature_units }} {% else -%} 0 {% endif -%} - *delay-default @@ -4794,7 +4772,6 @@ action: - alias: Climate page conditions: "{{ trigger.event.data.new_state.state == nextion.pages.climate }}" sequence: - - *variables-weather - variables: hvac_mode: "{{ states(entity_long) | default('unavailable') if entity_long is string else 'unavailable' }}" outdoor_temp_state: "{{ states(outdoortemp) | default('unavailable') if outdoortemp is string else 'unavailable' }}" @@ -4809,13 +4786,13 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: outdoor_temp - message: "{{ (outdoor_temp | round(1) ~ weather_units.temperature) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" + message: "{{ (outdoor_temp | round(1) ~ temperature_units) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: current_temp - message: "{{ (state_attr(entity_long, 'current_temperature') | round(1) ~ weather_units.temperature) if is_number(state_attr(entity_long, 'current_temperature')) else '' }}" # mui[language].unavailable? + message: "{{ (state_attr(entity_long, 'current_temperature') | round(1) ~ temperature_units) if is_number(state_attr(entity_long, 'current_temperature')) else '' }}" # mui[language].unavailable? continue_on_error: true - if: "{{ hvac_mode != 'off' and is_number(state_attr(entity_long, 'temperature')) }}" then: @@ -4864,15 +4841,33 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: climate.hotwater_temp - message: "{{ (hotwatertemp_state | round(1) ~ weather_units.temperature) if is_number(hotwatertemp_state) else hotwatertemp_state }}" + message: "{{ (hotwatertemp_state | round(1) ~ temperature_units) if is_number(hotwatertemp_state) else hotwatertemp_state }}" continue_on_error: true ## PAGE WEATHER (WEATHER01 to WEATHER05) ## - alias: Weather pages conditions: "{{ trigger.event.data.new_state.state in nextion.pages.weatherpages }}" sequence: - - *variables-weather - variables: + weather_attribution: "{{ state_attr(weather_entity, 'attribution') | default('unavailable') if weather_entity is string else 'unavailable' }}" + weather_type: > + {% if 'AccuWeather' in weather_attribution %} AccuWeather + {% elif 'OpenWeatherMap' in weather_attribution %} OpenWeather + {% elif 'SMHI' in weather_attribution %} SMHI + {% elif 'met.no' in weather_attribution %} Met.no + {% elif 'OpenWeatherMap' in weather_attribution %} OpenWeather + {% else %} Other + {% endif %} + weather_units: + hours_of_sun: "{{ state_attr(weather_entity, 'hours_of_sun_unit') | default('h') if weather_entity is string and state_attr(weather_entity, 'hours_of_sun_unit') else 'h' }}" + precipitation: "{{ state_attr(weather_entity, 'precipitation_unit') | default('mm') if weather_entity is string and state_attr(weather_entity, 'precipitation_unit') else 'mm' }}" + precipitation_probability: "{{ state_attr(weather_entity, 'precipitation_probability_unit') | default('%') if weather_entity is string and state_attr(weather_entity, 'precipitation_probability_unit') else '%' }}" + #pressure: "{{ state_attr(weather_entity, 'pressure_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'pressure_unit') }}" + #temperature: "{{ state_attr(weather_entity, 'temperature_unit') | default('°') if weather_entity is string and state_attr(weather_entity, 'temperature_unit') else '°' }}" + thunderstorm_probability: "{{ state_attr(weather_entity, 'thunderstorm_probability_unit') | default('%') if weather_entity is string and state_attr(weather_entity, 'thunderstorm_probability_unit') else '%' }}" + uv_index: "{{ state_attr(weather_entity, 'uv_index_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'uv_index_unit') }}" + #visibility: "{{ state_attr(weather_entity, 'visibility_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'visibility_unit') }}" + wind_speed: "{{ state_attr(weather_entity, 'wind_speed_unit') | default('') if weather_entity is string and state_attr(weather_entity, 'wind_speed_unit') }}" page_name: "{{ trigger.event.data.new_state.state }}" page_index: "{{ (page_name[-2:] | int(0)) - 1 }}" @@ -4960,9 +4955,9 @@ action: ##### Display temperature min/max when available - variables: temperature_string: > - {{ (temp_min | round(0) ~ weather_units.temperature) if is_number(temp_min) }} + {{ (temp_min | round(0) ~ temperature_units) if is_number(temp_min) }} {{ '/' if is_number(temp_min) and is_number(temp_max) }} - {{ (temp_max | round(0) ~ weather_units.temperature) if is_number(temp_max) }} + {{ (temp_max | round(0) ~ temperature_units) if is_number(temp_max) }} - if: "{{ (is_number(temp_min) or is_number(temp_max)) and temperature_string is string and temperature_string | length > 0 }}" then: - service: "{{ nextion.commands.text_printf }}" @@ -5852,7 +5847,6 @@ action: - condition: template value_template: "{{ nextion.pages.current == nextion.pages.home and is_number(trigger.event.data.new_state.state) }}" sequence: - - *variables-weather ### LABEL Outdoor Temp Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" @@ -5865,7 +5859,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ temperature_units }}" continue_on_error: true ##### INDOOR TEMP - entity ##### @@ -5876,7 +5870,6 @@ action: - condition: template value_template: "{{ nextion.pages.current == nextion.pages.home and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: - - *variables-weather ### LABEL Indoor Temp Font Color ### - *delay-default - service: "{{ nextion.commands.font_color }}" @@ -5889,7 +5882,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ temperature_units }}" continue_on_error: true ##### INDOOR TEMP - nspanel ##### @@ -5900,7 +5893,6 @@ action: - condition: template value_template: "{{ nextion.pages.current == nextion.pages.home and is_number(trigger.event.data.new_state.state) }}" sequence: - - *variables-weather - if: "{{ indoortemp is not match 'sensor.' }}" then: ### LABEL Indoor Temp Font Color ### @@ -5915,6 +5907,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.current_temp + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ temperature_units }}" message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" continue_on_error: true @@ -5926,7 +5919,6 @@ action: - condition: template value_template: "{{ nextion.pages.current == nextion.pages.home and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: - - *variables-weather - if: "{{ outdoortemp is not match 'sensor.' }}" then: ### LABEL Outdoor Temp Font Color ### @@ -5941,13 +5933,12 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.outdoor_temp - message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather_units.temperature }}" + message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ temperature_units }}" continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: component: climate.outdoor_temp - message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ weather_units.temperature }}" - continue_on_error: true + message: "{{trigger.event.data.new_state.attributes.temperature | round(1)}}{{ temperature_units }}" - service: "{{ nextion.commands.printf }}" data: @@ -5965,7 +5956,6 @@ action: # - condition: template # value_template: "{{ climate_optimistic == false }}" sequence: - - *variables-weather - variables: heating_state: "{{ mui[language].climate.states.off if trigger.event.data.new_state.state == 'off' else mui[language].climate.states.on }}" heating_bt_pic: "{{ nextion.pics.heating.button.off if trigger.event.data.new_state.state == 'off' else nextion.pics.heating.button.on }}" @@ -5973,7 +5963,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: current_temp - message: "{{ trigger.event.data.new_state.attributes.current_temperature | round(1)}}{{ weather_units.temperature }}" + message: "{{ trigger.event.data.new_state.attributes.current_temperature | round(1)}}{{ temperature_units }}" continue_on_error: true - service: "{{ nextion.commands.text_printf }}" data: @@ -6022,17 +6012,16 @@ action: id: hotwatertemp_state - "{{ nextion.pages.current == nextion.pages.climate and trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" sequence: - - *variables-weather - service: "{{ nextion.commands.text_printf }}" data: component: home.hotwater_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ temperature_units }}" continue_on_error: true - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: climate.hotwater_temp - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" + message: "{{ trigger.event.data.new_state.state | round(1) }}{{ temperature_units }}" continue_on_error: true # - delay: # milliseconds: "{{ delay_value }}" From 4fc9f98ce884b24388864a9c5e063832432b9599 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:27:00 +0200 Subject: [PATCH 18/30] Bump blueprint version to `3.2.3` --- nspanel_blueprint.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 7f2dadc..f57c31e 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -34,7 +34,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l 🎉 Roadmap Roadmap can be found here [Roadmap](https://github.com/Blackymas/NSPanel_HA_Blueprint/labels/roadmap) -ℹ️ Version: v.3.2.3DEV +ℹ️ Version: v.3.2.3 ' @@ -2347,7 +2347,7 @@ trigger_variables: variables: ##### GENERAL ##### - blueprint_version: "3.2.3DEV" + blueprint_version: "3.2.3" language: !input "language" time_format: !input "time_format" time: "{{ as_timestamp(now()) | timestamp_custom(time_format) }}" From c931e551c8ac032ecfea55b02794ace0733e9872 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 00:36:48 +0200 Subject: [PATCH 19/30] Bug fixed: Removed duplicated line --- nspanel_blueprint.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index f57c31e..9710e64 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -5908,7 +5908,6 @@ action: data: component: home.current_temp message: "{{ trigger.event.data.new_state.state | round(1) }}{{ temperature_units }}" - message: "{{ trigger.event.data.new_state.state | round(1) }}{{ weather_units.temperature }}" continue_on_error: true ##### WEATHER STATE - change update ##### From cee264d7690498d2218ea0fb37c94c7eab338910 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:41:58 +0200 Subject: [PATCH 20/30] Add time format 24h without leading zero To be consistent with the new date format added on v3.2.3. --- nspanel_blueprint.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 9710e64..e242d32 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -142,10 +142,12 @@ The goal was to create a version that allows everyone to use the NSpanel fully l multiple: false #mode: dropdown options: - - label: 'HH:MM (ex. 13:30)' + - label: 'HH:MM (ex. 08:30 and 20:30)' value: '%H:%M' - - label: 'H:MM AM/PM (ex. 1:30PM)' + - label: 'H:MM AM/PM (ex. 8:30AM and 8:30PM)' value: '%-I:%M' + - label: 'H:MM 24H (ex. 8:30 and 20:30)' + value: '%-H:%M' delay: name: Delay to avoid synchronization problem From 03498a2b79128f6f37e98873d05b3ad16029a2c8 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 12:41:19 +0200 Subject: [PATCH 21/30] Fix: Date format not applied when time changes --- nspanel_blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 9710e64..57cb4b2 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -5836,7 +5836,7 @@ action: - service: "{{ nextion.commands.text_printf }}" data: component: home.date - message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom('%d.%m') }}" + message: "{{ (dict.values(mui[language].weekdays) | list)[now().weekday()] ~ ', ' ~ as_timestamp(now()) | timestamp_custom(date_format) }}" continue_on_error: true ##### OUTDOOR TEMP - entity ##### From cf1ed9aa6676fac3bd39d9b10925d598e661cc6a Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 12:49:18 +0200 Subject: [PATCH 22/30] Fix: Variable date_format missing Moving the variable definition back to the root. --- nspanel_blueprint.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 57cb4b2..9747c84 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2349,6 +2349,7 @@ variables: ##### GENERAL ##### blueprint_version: "3.2.3" language: !input "language" + date_format: !input "date_format" time_format: !input "time_format" time: "{{ as_timestamp(now()) | timestamp_custom(time_format) }}" meridiem: "{{ as_timestamp(now()) | timestamp_custom('%p') if time_format == '%-I:%M' else '' }}" @@ -3775,9 +3776,6 @@ action: continue_on_error: true ##### NSPanel Date ##### ### DATE Font Color ### - - &variables-date_format - variables: - date_format: !input "date_format" - *delay-default - service: "{{ nextion.commands.font_color }}" data: @@ -4880,7 +4878,6 @@ action: - *delay-default ##### Display date (long) ##### - - *variables-date_format - service: "{{ nextion.commands.text_printf }}" data: component: "{{ page_name }}.date" From f5781d48b348275eb37dafb261798cf754771306 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Thu, 6 Apr 2023 21:45:40 +0200 Subject: [PATCH 23/30] Add "Croatian" as supported language (#632) #628 --- nspanel_blueprint.yaml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 9747c84..ee6238c 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -65,6 +65,8 @@ The goal was to create a version that allows everyone to use the NSpanel fully l value: BGR - label: 'Czech' value: CZE + - label: 'Croatian' + value: HRV - label: 'Danish' value: DNK - label: 'Dutch' @@ -103,14 +105,14 @@ The goal was to create a version that allows everyone to use the NSpanel fully l value: ROU - label: 'Russian' value: RUS - - label: 'Swedish' - value: SWE - label: 'Slovak' value: SVK - label: 'Slovene' value: SVN - label: 'Spanish' value: ESP + - label: 'Swedish' + value: SWE - label: 'Turkish' value: TUR - label: 'Ukrainian' @@ -2727,6 +2729,29 @@ variables: please_confirm: רשא השקבב unavailable: Unavailable no_name: No name + HRV: + weekdays: + mon: Ponedjeljak + tue: Utorak + wed: Srijeda + thu: Četvrtak + fri: Petak + sat: Subota + sun: Nedjelja + relative_day: + today: Danas + tomorrow: Sutra + in_2_days: za 2 dana + in_3_days: za 3 dana + in_4_days: za 4 dana + climate: + states: + "on": uključeno + "off": isključeno + heat: toplina + please_confirm: Molim potvrdite + unavailable: Unavailable + no_name: No name HUN: weekdays: mon: Hétfő From adbe6a4dc647f4a8e32b3b2ec864fbdca159c360 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 7 Apr 2023 08:22:27 +0200 Subject: [PATCH 24/30] Fix translations to Croatian #628 --- nspanel_blueprint.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index dc836bb..35b8a95 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2743,17 +2743,17 @@ variables: relative_day: today: Danas tomorrow: Sutra - in_2_days: za 2 dana - in_3_days: za 3 dana - in_4_days: za 4 dana + in_2_days: Za 2 dana + in_3_days: Za 3 dana + in_4_days: Za 4 dana climate: states: "on": uključeno "off": isključeno heat: toplina please_confirm: Molim potvrdite - unavailable: Unavailable - no_name: No name + unavailable: Nedostupno + no_name: Bez imena HUN: weekdays: mon: Hétfő From 36d2cf2f21fadb70d024d838bbd0e1687e1de881 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 7 Apr 2023 11:55:27 +0200 Subject: [PATCH 25/30] Fixes to Croatian string formats #628 --- nspanel_blueprint.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 35b8a95..7cffcb5 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2748,9 +2748,9 @@ variables: in_4_days: Za 4 dana climate: states: - "on": uključeno - "off": isključeno - heat: toplina + "on": Uključeno + "off": Isključeno + heat: Toplina please_confirm: Molim potvrdite unavailable: Nedostupno no_name: Bez imena From 3134f07671fc172b521fbdb6af51bea7a88281b6 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 7 Apr 2023 12:12:53 +0200 Subject: [PATCH 26/30] Fix input descriptions to entity pages (#634) It was incorrectly describing BUTTONPAGExx instead of ENTITYPAGExx. This fixes #633 --- nspanel_blueprint.yaml | 64 +++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 7cffcb5..83f8d72 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -1643,7 +1643,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity01_icon: name: Entity 01 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity02: @@ -1660,7 +1660,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity02_icon: name: Entity 02 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity03: @@ -1677,7 +1677,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity03_icon: name: Entity 03 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity04: @@ -1694,7 +1694,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity04_icon: name: Entity 04 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity05: @@ -1711,7 +1711,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity05_icon: name: Entity 05 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity06: @@ -1728,7 +1728,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity06_icon: name: Entity 06 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity07: @@ -1745,7 +1745,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity07_icon: name: Entity 07 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity08: @@ -1762,7 +1762,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity08_icon: name: Entity 08 - ICON (Optional) - description: '* *Page "BUTTONPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE01" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector ##### Entity page 02 - Entities ##### @@ -1790,7 +1790,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity09_icon: name: Entity 09 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity10: @@ -1807,7 +1807,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity10_icon: name: Entity 10 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity11: @@ -1824,7 +1824,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity11_icon: name: Entity 11 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity12: @@ -1841,7 +1841,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity12_icon: name: Entity 12 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity13: @@ -1858,7 +1858,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity13_icon: name: Entity 13 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity14: @@ -1875,7 +1875,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity14_icon: name: Entity 14 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity15: @@ -1892,7 +1892,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity15_icon: name: Entity 15 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity16: @@ -1909,7 +1909,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity16_icon: name: Entity 16 - ICON (Optional) - description: '* *Page "BUTTONPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE02" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector ##### Entity page 03 - Entities ##### @@ -1937,7 +1937,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity17_icon: name: Entity 17 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity18: @@ -1954,7 +1954,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity18_icon: name: Entity 18 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity19: @@ -1971,7 +1971,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity19_icon: name: Entity 19 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity20: @@ -1988,7 +1988,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity20_icon: name: Entity 20 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity21: @@ -2005,7 +2005,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity21_icon: name: Entity 21 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity22: @@ -2022,7 +2022,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity22_icon: name: Entity 22 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity23: @@ -2039,7 +2039,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity23_icon: name: Entity 23 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity24: @@ -2056,7 +2056,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity24_icon: name: Entity 24 - ICON (Optional) - description: '* *Page "BUTTONPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE03" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector ##### Entity page 04 - Entities ##### @@ -2084,7 +2084,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity25_icon: name: Entity 25 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity26: @@ -2101,7 +2101,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity26_icon: name: Entity 26 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity27: @@ -2118,7 +2118,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity27_icon: name: Entity 27 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity28: @@ -2135,7 +2135,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity28_icon: name: Entity 28 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity29: @@ -2152,7 +2152,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity29_icon: name: Entity 29 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity30: @@ -2169,7 +2169,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity30_icon: name: Entity 30 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity31: @@ -2186,7 +2186,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity31_icon: name: Entity 31 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector entities_entity32: @@ -2203,7 +2203,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l text: {} entities_entity32_icon: name: Entity 32 - ICON (Optional) - description: '* *Page "BUTTONPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' + description: '* *Page "ENTITYPAGE04" - Icon which should be displayed (if not set, no icon is shown)*' default: [] selector: *icon-selector From 1ea041c73118d3e91d8dc7b47022bdf6ccad566a Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 10 Apr 2023 17:43:15 +0200 Subject: [PATCH 27/30] Fixed translation (Spanish) As per https://github.com/Blackymas/NSPanel_HA_Blueprint/commit/342a5ae1b85b1f61882522bc6c91020c1a292f59#r108312227 --- nspanel_blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 83f8d72..f18c078 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2614,7 +2614,7 @@ variables: "off": Apagado heat: calor please_confirm: Por favor, confirme - unavailable: Indisponible + unavailable: No disponible no_name: Sin nombre EST: weekdays: From 59727e294da4e0cdada70687f9e22198539bc16a Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 10 Apr 2023 23:57:35 +0200 Subject: [PATCH 28/30] Home page: Removing unnecessary calls to panel (#629) Trying to gain a bit on performance by not sending calls to the panel when not needed (element not available, etc.). --- nspanel_blueprint.yaml | 266 ++++++++++++++++++++++------------------- 1 file changed, 146 insertions(+), 120 deletions(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index f18c078..7a1904e 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2317,6 +2317,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l mode: parallel max: 5000 + trace: stored_traces: 10 @@ -2356,7 +2357,7 @@ variables: date_format: !input "date_format" time_format: !input "time_format" time: "{{ as_timestamp(now()) | timestamp_custom(time_format) }}" - meridiem: "{{ as_timestamp(now()) | timestamp_custom('%p') if time_format == '%-I:%M' else '' }}" + meridiem: "{{ as_timestamp(now()) | timestamp_custom('%p') if time_format == '%-I:%M' }}" sun_is_up: "{{ is_state('sun.sun', 'above_horizon') }}" notification_sound: "switch.{{ nspanel_name }}_notification_sound" @@ -3693,20 +3694,6 @@ condition: "{{ is_state(nextion_inited_trigger, 'on') | default(false) if nextio ##### START - Action ##### ############################################################# action: - - variables: - #settings_entity_value: "{{ states(settings_entity) }}" - settings_entity_value: "{{ states(settings_entity) | default('unavailable') if settings_entity is string else 'unavailable' }}" - settings_entity_split: "{{ settings_entity_value.split(',') if settings_entity_value is string and settings_entity_value not in ['unavailable', 'unknown', None] else [] }}" - settings_entity_count: "{{ settings_entity_split | count if settings_entity_split else 0 }}" - entity_long: "{{ settings_entity_split[0] if settings_entity_count >= 1 else 'unknown' }}" - entity_back: "{{ settings_entity_split[1] if settings_entity_count >= 2 else 'unknown' }}" - entity_long_name: "{{ settings_entity_split[2] if settings_entity_count >= 3 else 'unknown' }}" - entity_long_icon: "{{ settings_entity_split[3] if settings_entity_count >= 4 else 'unknown' }}" - entity_long_icon_color: "{{ settings_entity_split[4] if settings_entity_count >= 5 else 'unknown' }}" - entity_long_domain: "{{ entity_long.split('.')[0] if entity_long.split('.') | count > 0 else 'unknown' }}" - - ######################################################################################################################## - # main - alias: "choose alias (name)" - alias: Main choices choose: @@ -3716,12 +3703,25 @@ action: - condition: trigger id: settings_entity - "{{ trigger.event.data.new_state.state not in ['unavailable', 'unknown', None] }}" - - "{{ entity_long_domain in ['light', 'cover', 'climate'] }}" sequence: - - service: "{{ nextion.commands.printf }}" - data: - cmd: "page {{ nextion.pages[entity_long_domain] }}" - continue_on_error: true + - &variables-settings_entity + variables: + settings_entity_value: "{{ states(settings_entity) | default('unavailable') if settings_entity is string else 'unavailable' }}" + settings_entity_split: "{{ settings_entity_value.split(',') if settings_entity_value is string and settings_entity_value not in ['unavailable', 'unknown', None] else [] }}" + settings_entity_count: "{{ settings_entity_split | count if settings_entity_split else 0 }}" + entity_long: "{{ settings_entity_split[0] if settings_entity_count >= 1 else 'unknown' }}" + entity_back: "{{ settings_entity_split[1] if settings_entity_count >= 2 else 'unknown' }}" + entity_long_name: "{{ settings_entity_split[2] if settings_entity_count >= 3 else 'unknown' }}" + entity_long_icon: "{{ settings_entity_split[3] if settings_entity_count >= 4 else 'unknown' }}" + entity_long_icon_color: "{{ settings_entity_split[4] if settings_entity_count >= 5 else 'unknown' }}" + - variables: + entity_long_domain: "{{ entity_long.split('.')[0] if entity_long.split('.') | count > 0 else 'unknown' }}" + - if: "{{ entity_long_domain in ['light', 'cover', 'climate'] }}" + then: + - service: "{{ nextion.commands.printf }}" + data: + cmd: "page {{ nextion.pages[entity_long_domain] }}" + continue_on_error: true ##### BOOT NSPANEL - boot init ##### - alias: Boot init @@ -3786,6 +3786,7 @@ action: display_target_temperature_state: "{{ states(display_target_temperature) | default('unavailable') if display_target_temperature is string else 'unavailable' }}" - if: "{{ is_number(display_target_temperature_state) }}" then: + - *variables-settings_entity - service: climate.set_temperature data: entity_id: "{{ entity_long }}" @@ -3831,71 +3832,77 @@ action: component: home.time message: "{{ time }}" continue_on_error: true - ### TIME Meridiem Font Color ### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: home.meridiem - message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" - continue_on_error: true - ### TIME Meridiem Font ### - - *delay-default - - service: "{{ nextion.commands.text_printf }}" - data: - component: home.meridiem - message: "{{ meridiem }}" - continue_on_error: true + - if: "{{ meridiem }}" + then: + ### TIME Meridiem Font Color ### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: home.meridiem + message: "{{ page_home.general.time.label.color_rgb if is_number(page_home.general.time.label.color_rgb) else ((page_home.general.time.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.time.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.time.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true + ### TIME Meridiem Font ### + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: home.meridiem + message: "{{ meridiem }}" + continue_on_error: true ##### NSPanel Outdoor Temp ##### - variables: outdoor_temp_state: "{{ states(outdoortemp) | default('unavailable') if outdoortemp is string else 'unavailable' }}" outdoor_temp: "{{ outdoor_temp_state if is_number(outdoor_temp_state) else state_attr(weather_entity, 'temperature') | default('unavailable') if weather_entity is string else 'unavailable' }}" - ### LABEL Outdoor Temp Font Color ### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: home.outdoor_temp - message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" - continue_on_error: true - ### LABEL Outdoor Temp Font ### - - *delay-default - - service: "{{ nextion.commands.text_printf }}" - data: - component: home.outdoor_temp - message: "{{ (outdoor_temp | round(1) ~ temperature_units) if is_number(outdoor_temp) else (mui[language].unavailable if outdoor_temp in ['unavailable', 'unknown', None] else outdoor_temp) }}" - continue_on_error: true + - if: "{{ is_number(outdoor_temp) }}" + then: + ### LABEL Outdoor Temp Font Color ### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: home.outdoor_temp + message: "{{ page_home.general.outdoor_temp.label.color_rgb if is_number(page_home.general.outdoor_temp.label.color_rgb) else ((page_home.general.outdoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.outdoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.outdoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true + ### LABEL Outdoor Temp Font ### + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: home.outdoor_temp + message: "{{ outdoor_temp | round(1) ~ temperature_units }}" + continue_on_error: true ##### NSPanel Indoor Temp ##### - variables: indoor_temp_state: "{{ states(indoortemp) | default('unavailable') if indoortemp is string else 'unavailable' }}" - ### ICON Indoor Temp Font Color ### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: home.indoortempicon - message: "{{ page_home.general.indoor_temp.icon.color_rgb if is_number(page_home.general.indoor_temp.icon.color_rgb) else ((page_home.general.indoor_temp.icon.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.icon.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.icon.color_rgb[2] //(2**3)) }}" - continue_on_error: true - ### ICON Indoor Temp Font ### - - *delay-default - - service: "{{ nextion.commands.text_printf }}" - data: - component: home.indoortempicon - message: "{{ page_home.general.indoor_temp.icon.icon }}" - continue_on_error: true - ### LABEL Indoor Temp Font Color ### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: home.current_temp - message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" - continue_on_error: true - ### LABEL Indoor Temp Font ### - - *delay-default - - service: "{{ nextion.commands.text_printf }}" - data: - component: home.current_temp - message: "{{ (indoor_temp_state | round(1) ~ temperature_units) if is_number(indoor_temp_state) else (mui[language].unavailable if indoor_temp_state in ['unavailable', 'unknown', None] else indoor_temp_state) }}" - continue_on_error: true + - if: "{{ is_number(indoor_temp_state) }}" + then: + ### ICON Indoor Temp Font Color ### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: home.indoortempicon + message: "{{ page_home.general.indoor_temp.icon.color_rgb if is_number(page_home.general.indoor_temp.icon.color_rgb) else ((page_home.general.indoor_temp.icon.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.icon.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.icon.color_rgb[2] //(2**3)) }}" + continue_on_error: true + ### ICON Indoor Temp Font ### + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: home.indoortempicon + message: "{{ page_home.general.indoor_temp.icon.icon }}" + continue_on_error: true + ### LABEL Indoor Temp Font Color ### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: home.current_temp + message: "{{ page_home.general.indoor_temp.label.color_rgb if is_number(page_home.general.indoor_temp.label.color_rgb) else ((page_home.general.indoor_temp.label.color_rgb[0] //(2**3)) *(2**11))+((page_home.general.indoor_temp.label.color_rgb[1] //(2**2)) *(2**5))+(page_home.general.indoor_temp.label.color_rgb[2] //(2**3)) }}" + continue_on_error: true + ### LABEL Indoor Temp Font ### + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: home.current_temp + message: "{{ (indoor_temp_state | round(1) ~ temperature_units) if is_number(indoor_temp_state) else (mui[language].unavailable if indoor_temp_state in ['unavailable', 'unknown', None] else indoor_temp_state) }}" + continue_on_error: true ##### Weather Icon Home Page ##### - *delay-default @@ -4013,19 +4020,24 @@ action: - &display-home_page_status_bar if: "{{ repeat.item.entity is defined and repeat.item.entity is string and repeat.item.entity | length > 0 }}" then: - ### ICON Font Color ### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" - message: "{{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }}" - continue_on_error: true + - variables: + repeat_item_state: "{{ states(repeat.item.entity) | default('unavailable') }}" + repeat_item_state_is_on: "{{ repeat_item_state in ['on', 'open'] }}" + - if: "{{ repeat_item_state_is_on }}" + then: + ### ICON Font Color ### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" + message: "{{ repeat.item.icon_color_rgb if is_number(repeat.item.icon_color_rgb) else ((repeat.item.icon_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.icon_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.icon_color_rgb[2] //(2**3)) }}" + continue_on_error: true ### ICON Font ### - *delay-default - service: "{{ nextion.commands.text_printf }}" data: component: "{{ 'home.icon_top_%02d' | format(repeat.index) }}" - message: "{{ repeat.item.icon if is_state(repeat.item.entity, 'on') | default(False) else nextion.icons.blank }}" + message: "{{ repeat.item.icon if repeat_item_state_is_on else nextion.icons.blank }}" continue_on_error: true # {{ is_state(repeat.item.entity, 'on') | default(False) if repeat.item.entity is string else 'unavailable' }} @@ -4052,7 +4064,7 @@ action: - &display-home_page_value if: "{{ repeat.item.entity is string and repeat.item.entity is match 'sensor.' and states(repeat.item.entity) not in ['unavailable', 'unknown', None] }}" then: - - if: "{{ repeat.item.entity_icon | length > 0 }}" + - if: "{{ repeat.item.icon | length > 0 }}" then: ### ICON Font Color ### - *delay-default @@ -4068,42 +4080,50 @@ action: component: "{{ 'home.value%02d_icon' | format(repeat.index) }}" message: "{{ repeat.item.icon }}" continue_on_error: true - ### LABEL Font Color ### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: "{{ 'home.value%02d_state' | format(repeat.index) }}" - message: "{{ repeat.item.label_color_rgb if is_number(repeat.item.label_color_rgb) else ((repeat.item.label_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.label_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.label_color_rgb[2] //(2**3)) }}" - continue_on_error: true - ### LABEL Font ### - - *delay-default - - service: "{{ nextion.commands.text_printf }}" - data: - component: "{{ 'home.value%02d_state' | format(repeat.index) }}" - message: "{{ (states(repeat.item.entity) | round(1) ~ (state_attr(repeat.item.entity, 'unit_of_measurement') if state_attr(repeat.item.entity, 'unit_of_measurement') else '')) if is_number(states(repeat.item.entity)) else states(repeat.item.entity) | default('unknown') }}" - continue_on_error: true + - variables: + repeat_item_state: "{{ states(repeat.item.entity) | default('unavailable') }}" + repeat_item_state_available: "{{ repeat_item_state not in ['unavailable', 'unknown', None] }}" + - if: "{{ repeat_item_state_available }}" + then: + ### LABEL Font Color ### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: "{{ 'home.value%02d_state' | format(repeat.index) }}" + message: "{{ repeat.item.label_color_rgb if is_number(repeat.item.label_color_rgb) else ((repeat.item.label_color_rgb[0] //(2**3)) *(2**11))+((repeat.item.label_color_rgb[1] //(2**2)) *(2**5))+(repeat.item.label_color_rgb[2] //(2**3)) }}" + continue_on_error: true + ### LABEL Font ### + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: "{{ 'home.value%02d_state' | format(repeat.index) }}" + message: "{{ (repeat_item_state | round(1) ~ state_attr(repeat.item.entity, 'unit_of_measurement') | default('')) if is_number(repeat_item_state) else repeat_item_state }}" + continue_on_error: true ##### Set notify icon ##### - variables: notification_unread_state: "{{ states(notification_unread) | default('unavailable') if notification_unread is string else 'unavailable' }}" - notification_text_state: "{{ states(notification_text) | default(None) if notification_text is string else None }}" - set_button04_icon: "{{ page_home.buttons[3].icon if notification_unread_state in ['on', 'off'] and notification_text_state | length > 0 else nextion.icons.blank }}" - set_button04_icon_font: "{{ (page_home.buttons[3].color_rgb[notification_unread_state] if is_number(page_home.buttons[3].color_rgb[notification_unread_state]) else ((page_home.buttons[3].color_rgb[notification_unread_state][0] //(2**3)) *(2**11))+((page_home.buttons[3].color_rgb[notification_unread_state][1] //(2**2)) *(2**5))+(page_home.buttons[3].color_rgb[notification_unread_state][2] //(2**3))) if notification_unread_state in ['on', 'off'] and notification_text_state | length > 0 else nextion.colors.grey_light }}" - ##### SET ICON Font - Notify ##### - - *delay-default - - service: "{{ nextion.commands.text_printf }}" - data: - component: home.button04_icon - message: "{{ set_button04_icon }}" - continue_on_error: true + - if: "{{ notification_unread_state in ['on', 'off'] }}" + then: + - variables: + notification_text_state: "{{ states(notification_text) | default(None) if notification_text is string else None }}" + set_button04_icon: "{{ page_home.buttons[3].icon if notification_unread_state == 'on' and notification_text_state | length > 0 else nextion.icons.blank }}" + set_button04_icon_font: "{{ (page_home.buttons[3].color_rgb[notification_unread_state] if is_number(page_home.buttons[3].color_rgb[notification_unread_state]) else ((page_home.buttons[3].color_rgb[notification_unread_state][0] //(2**3)) *(2**11))+((page_home.buttons[3].color_rgb[notification_unread_state][1] //(2**2)) *(2**5))+(page_home.buttons[3].color_rgb[notification_unread_state][2] //(2**3))) if notification_unread_state in ['on', 'off'] and notification_text_state | length > 0 else nextion.colors.grey_light }}" + ##### SET ICON Font - Notify ##### + - *delay-default + - service: "{{ nextion.commands.text_printf }}" + data: + component: home.button04_icon + message: "{{ set_button04_icon }}" + continue_on_error: true - ##### SET ICON Font Color - Notify ##### - - *delay-default - - service: "{{ nextion.commands.font_color }}" - data: - component: home.button04_icon - message: "{{ set_button04_icon_font }}" - continue_on_error: true + ##### SET ICON Font Color - Notify ##### + - *delay-default + - service: "{{ nextion.commands.font_color }}" + data: + component: home.button04_icon + message: "{{ set_button04_icon_font }}" + continue_on_error: true ###### QR Code - Icon ###### - *delay-default @@ -4447,6 +4467,7 @@ action: - alias: Light settings page conditions: "{{ trigger.event.data.new_state.state == nextion.pages.light }}" sequence: + - *variables-settings_entity - service: "{{ nextion.commands.text_printf }}" data: component: lightsettings.light_name @@ -4535,6 +4556,7 @@ action: conditions: "{{ trigger.event.data.new_state.state == nextion.pages.cover }}" sequence: ##### COVER - OPEN / CLOSE ##### + - *variables-settings_entity - variables: coversettings_icon_font: "{{ entity_long_icon if entity_long_icon | length > 0 else nextion.icons.buttons.cover }}" coversettings_icon_font_color: "{{ entity_long_icon_color if is_state(entity_long, 'open') else nextion.colors.grey_light }}" @@ -4797,6 +4819,7 @@ action: - alias: Climate page conditions: "{{ trigger.event.data.new_state.state == nextion.pages.climate }}" sequence: + - *variables-settings_entity - variables: hvac_mode: "{{ states(entity_long) | default('unavailable') if entity_long is string else 'unavailable' }}" outdoor_temp_state: "{{ states(outdoortemp) | default('unavailable') if outdoortemp is string else 'unavailable' }}" @@ -5014,7 +5037,7 @@ action: message: "{{ mui[language].unavailable }}" continue_on_error: true - *delay-default - + ## PAGE NOTIFICATION ## - alias: Notification page conditions: "{{ trigger.event.data.new_state.state == nextion.pages.notification }}" @@ -5148,13 +5171,13 @@ action: - variables: ##### Entity - Page Button - Toggle Entity ##### last_click_state: "{{ states(last_click) | default('unavailable') if last_click is string else 'unavailable' }}" - last_click_coordinates: "{{ last_click_state.replace('releasebuttonpage', '').split('button') if last_click_state not in ['unavailable', 'unknown', None] else [-1, -1] }}" - last_click_entity_index: "{{ (last_click_coordinates[0] | int(-99) -1)*8 + last_click_coordinates[1] | int(-99) - 1 }}" + last_click_coordinates: "{{ last_click_state.replace('releasebuttonpage', '').split('button') if last_click_state not in ['unavailable', 'unknown', None] else None }}" + last_click_entity_index: "{{ (last_click_coordinates[0] | int(-99) -1)*8 + last_click_coordinates[1] | int(-99) - 1 if last_click_coordinates and last_click_coordinates | count >= 1 else -1 }}" - condition: "{{ last_click_entity_index >= 0 }}" - variables: last_click_button: "{{ button_pages_buttons[last_click_entity_index] | default([]) }}" entity_short: "{{ last_click_button.entity | default('unavailable') if last_click_button and last_click_button.entity is defined }}" - entity_domain: "{{ (entity_short.split('.')[0] | default('unknown')) if entity_short is string and entity_short | length > 0 else 'unknown' }}" + entity_domain: "{{ (entity_short.split('.')[0] | default('unknown')) if entity_short is string and entity_short | length > 0 and entity_short.split('.') | count > 0 else 'unknown' }}" - condition: "{{ entity_domain not in ['unknown', 'person', 'binary_sensor', 'sensor'] }}" - if: "{{ entity_domain == 'climate' }}" then: @@ -5290,6 +5313,7 @@ action: id: light_settings - "{{ nextion.pages.current == nextion.pages.light }}" sequence: + - *variables-settings_entity - choose: ##### Page Lightsettings - Brightness Slider MOVE ##### - conditions: @@ -5376,6 +5400,7 @@ action: id: cover_settings - "{{ nextion.pages.current == nextion.pages.cover }}" sequence: + - *variables-settings_entity - choose: ##### Page Coversettings - Cover Slider MOVE ##### - conditions: @@ -5444,6 +5469,7 @@ action: id: climate_settings - "{{ nextion.pages.current == nextion.pages.climate }}" sequence: + - *variables-settings_entity - variables: entity_long_state: "{{ states(entity_long) | default('unavailable') if entity_long is string else 'unavailable' }}" - choose: From 95ff13d83125075fb3b99c5546a0c4b8fb520a0d Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Mon, 10 Apr 2023 23:58:12 +0200 Subject: [PATCH 29/30] Convert napanel_name to a valid format (#647) This supports users mistyping the NSPanel name in the blueprint settings. One of the most common mistakes is using `-` in the name, instead of `_` and this change will try to replace that when users type the name with this invalid char. --- nspanel_blueprint.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index 7a1904e..d7f8308 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2326,7 +2326,8 @@ trace: ############################################################# trigger_variables: - nspanel_name: !input "nspanel_name" + nspanel_name_temp: !input "nspanel_name" + nspanel_name: "{{ nspanel_name_temp | replace('-','_') | replace(' ','_') | replace('___','_') | replace('__','_') }}" last_click: "sensor.{{ nspanel_name }}_last_click" last_click_lightsettings: "sensor.{{ nspanel_name }}_last_click_lightsettings" last_click_coversettings: "sensor.{{ nspanel_name }}_last_click_coversettings" From 56f27d1a86900997ff5cf1ab1d95e516a3c6e3d6 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Tue, 11 Apr 2023 00:05:01 +0200 Subject: [PATCH 30/30] Reduce # of concurrent instances of blueprint This reduces the number of parallel instances of the blueprint running. I've done several tests and couldn't see more than 10 instances, so I believe if we should limit the concurrent runs and this will probably be an indication of a problem we want to know about. --- nspanel_blueprint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nspanel_blueprint.yaml b/nspanel_blueprint.yaml index d7f8308..d7842f7 100644 --- a/nspanel_blueprint.yaml +++ b/nspanel_blueprint.yaml @@ -2316,7 +2316,7 @@ The goal was to create a version that allows everyone to use the NSpanel fully l ############################################################# mode: parallel -max: 5000 +max: 50 trace: stored_traces: 10