Merge pull request #245 from HASwitchPlate/dev

HASPone 1.06
This commit is contained in:
Allen Derusha 2024-05-12 07:52:25 -04:00 committed by GitHub
commit 08130252d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
59 changed files with 6244 additions and 4051 deletions

Binary file not shown.

5
Arduino_Sketch/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@ -9,17 +9,17 @@
; https://docs.platformio.org/page/projectconf.html
[env:d1_mini]
platform = https://github.com/platformio/platform-espressif8266.git @ ^3.2.0
platform = https://github.com/platformio/platform-espressif8266.git @ ^4.2.1
board = d1_mini
framework = arduino
board_build.f_cpu = 160000000L
board_build.ldscript = eagle.flash.4m1m.ld
build_flags =
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
lib_deps =
bblanchon/ArduinoJson @ ^6.18.5
256dpi/MQTT @ ^2.5.0
dancol90/ESP8266Ping @ ^1.0
krzychb/EspSaveCrash @ ^1.2.0
https://github.com/tzapu/WiFiManager.git#8452df79bbc55265d6a999d7384204220f4d22c6
256dpi/MQTT @ ^2.5.2
dancol90/ESP8266Ping @ ^1.1.0
bblanchon/ArduinoJson @ ^7.0.4
krzychb/EspSaveCrash @ ^1.3.0
https://github.com/tzapu/WiFiManager.git#e978bc059c522404c01e06cd136fcf23234eb784

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] activates a page"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone activates a selected page after a specified period of inactivity"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -122,7 +122,7 @@ condition:
action:
- delay:
seconds: "{{idletime|int}}"
seconds: "{{idletime|int(default=30)}}"
- condition: template
value_template: >-
@ -142,4 +142,4 @@ action:
data:
topic: "{{pagecommandtopic}}"
payload: "{{targetpage}}"
retain: true
retain: true

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] has theme colors applied"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description

View File

@ -0,0 +1,326 @@
blueprint:
name: "HASPone buttons have theme colors applied"
description: |
## Blueprint Version: `1.06.00`
## Description
Several buttons on the HASPone will have the current device theme or custom colors applied.
## HASPone Page and Button Reference
<details>
The images below show each available HASPone page along with the layout of available button objects.
| Page 0 | Pages 1-3 | Pages 4-5 |
|--------|-----------|-----------|
| ![Page 0](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p11_1button+1slider.png)
</details>
## Nextion color codes
<details>
The Nextion environment utilizes RGB 565 encoding. [Use this handy convertor](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to select your colors and convert to the RGB 565 format.
Here are some example colors:
| Color | Code |
|--------|-------|
| White | 65535 |
| Black | 0 |
| Grey | 25388 |
| Red | 63488 |
| Green | 2016 |
| Blue | 31 |
| Yellow | 65504 |
| Orange | 64512 |
| Brown | 48192 |
</details>
domain: automation
input:
haspdevice:
name: "HASPone Device"
description: "Select the HASPone device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
objects:
name: "HASPone buttons"
description: "Apply the current theme or colors defined below to all of the objects in this list"
default:
- p[1].b[4]
- p[1].b[5]
- p[1].b[6]
- p[1].b[7]
selector:
object:
selected_fgcolor:
name: "Selected foreground color"
description: 'Selected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected foreground color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
selected_bgcolor:
name: "Selected background color"
description: 'Selected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected background color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
unselected_fgcolor:
name: "Unselected foreground color"
description: 'Unselected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected foreground color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
unselected_bgcolor:
name: "Unselected background color"
description: 'Unselected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected background color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{%- endif -%}
{%- endfor -%}
objects: !input objects
selected_fgcolor: !input selected_fgcolor
selected_bgcolor: !input selected_bgcolor
unselected_fgcolor: !input unselected_fgcolor
unselected_bgcolor: !input unselected_bgcolor
# haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
# commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
selectedfg: >-
{%- if (selected_fgcolor|int) >= 0 -%}
{{ selected_fgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
selectedbg: >-
{%- if (selected_bgcolor|int) >= 0 -%}
{{ selected_bgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
unselectedfg: >-
{%- if (unselected_fgcolor|int) >= 0 -%}
{{ unselected_fgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
unselectedbg: >-
{%- if (unselected_bgcolor|int) >= 0 -%}
{{ unselected_bgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{%- endif -%}
{%- endfor -%}
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
trigger:
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{selectedfgtopic}}"
- platform: mqtt
topic: "{{selectedbgtopic}}"
- platform: mqtt
topic: "{{unselectedfgtopic}}"
- platform: mqtt
topic: "{{unselectedbgtopic}}"
condition:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
action:
- choose:
#########################################################################
# RUN ACTIONS or Home Assistant Startup or HASPone Connect
# Apply text style
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
or
(trigger.platform is none)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- repeat:
count: "{{objects|length}}"
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[
"{{objects[repeat.index-1]}}.pco={{selectedfg}}",
"{{objects[repeat.index-1]}}.bco={{selectedbg}}",
"{{objects[repeat.index-1]}}.pco2={{unselectedfg}}",
"{{objects[repeat.index-1]}}.bco2={{unselectedbg}}"
]
#########################################################################
# Catch triggers fired by incoming MQTT messages
- conditions:
- condition: template
value_template: '{{ trigger.platform == "mqtt" }}'
sequence:
- choose:
#########################################################################
# Theme: Apply selected foreground color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == selectedfgtopic) and ((selected_fgcolor|int) == -1) }}"
sequence:
- repeat:
count: "{{objects|length}}"
sequence:
- service: mqtt.publish
data:
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".pco" }}'
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply selected background color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == selectedbgtopic) and ((selected_bgcolor|int) == -1) }}"
sequence:
- repeat:
count: "{{objects|length}}"
sequence:
- service: mqtt.publish
data:
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".bco" }}'
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply unselected foreground color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == unselectedfgtopic) and ((unselected_fgcolor|int) == -1) }}"
sequence:
- repeat:
count: "{{objects|length}}"
sequence:
- service: mqtt.publish
data:
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".pco2" }}'
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply unselected background color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == unselectedbgtopic) and ((unselected_bgcolor|int) == -1) }}"
sequence:
- repeat:
count: "{{objects|length}}"
sequence:
- service: mqtt.publish
data:
topic: '{{ "hasp/" ~ haspname ~ "/command/" ~ objects[repeat.index-1] ~ ".bco2" }}'
payload: "{{trigger.payload}}"

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone Core functionality"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description
@ -234,15 +234,15 @@ variables:
{%- endfor -%}
page1text: !input page1text
page1font_select: !input page1font_select
page1font: "{{ page1font_select.split(' - ')[0] | int }}"
page1font: "{{ page1font_select.split(' - ')[0] | int(default=6) }}"
page1page: !input page1page
page2text: !input page2text
page2font_select: !input page2font_select
page2font: "{{ page2font_select.split(' - ')[0] | int }}"
page2font: "{{ page2font_select.split(' - ')[0] | int(default=6) }}"
page2page: !input page2page
page3text: !input page3text
page3font_select: !input page3font_select
page3font: "{{ page3font_select.split(' - ')[0] | int }}"
page3font: "{{ page3font_select.split(' - ')[0] | int(default=6) }}"
page3page: !input page3page
page_scroll: !input page_scroll
page_scroll_list: !input page_scroll_list
@ -289,29 +289,29 @@ variables:
page_list: '{{page_scroll_list.split(",")}}'
page_previous: >
{%- set page = namespace() -%}
{%- set page.previous = page_list[(page_list|length)-1]|int -%}
{%- set page.next = page_list[0]|int -%}
{%- set page.previous = page_list[(page_list|length)-1]|int(default=10) -%}
{%- set page.next = page_list[0]|int(default=1) -%}
{%- for item in page_list -%}
{%- if item|int == activepage -%}
{%- if item|int(default=1) == activepage -%}
{%- if not loop.first -%}
{%- set page.previous = loop.previtem|int -%}
{%- set page.previous = loop.previtem|int(default=1) -%}
{%- endif -%}
{%- if not loop.last -%}
{%- set page.next = loop.nextitem|int -%}
{%- set page.next = loop.nextitem|int(default=1) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}{{page.previous}}
page_next: >
{%- set page = namespace() -%}
{%- set page.previous = page_list[(page_list|length)-1]|int -%}
{%- set page.next = page_list[0]|int -%}
{%- set page.previous = page_list[(page_list|length)-1]|int(default=10) -%}
{%- set page.next = page_list[0]|int(default=1) -%}
{%- for item in page_list -%}
{%- if item|int == activepage -%}
{%- if item|int(default=1) == activepage -%}
{%- if not loop.first -%}
{%- set page.previous = loop.previtem|int -%}
{%- set page.previous = loop.previtem|int(default=1) -%}
{%- endif -%}
{%- if not loop.last -%}
{%- set page.next = loop.nextitem|int -%}
{%- set page.next = loop.nextitem|int(default=1) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}{{page.next}}
@ -488,7 +488,7 @@ action:
- service: mqtt.publish
data:
topic: "hasp/{{haspname}}/command/nextionbaud"
payload: "115200"
payload: "115200"
# Send page select button config
- service: mqtt.publish
data:
@ -608,11 +608,11 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=0) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # apply selected background color to page select buttons
data:
@ -628,11 +628,11 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=65535) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # apply unselected foreground color to page select buttons
data:
@ -648,11 +648,11 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=59164) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # apply unselected background color to page select buttons
data:
@ -668,11 +668,11 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=16904) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
#########################################################################
@ -707,11 +707,12 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=0) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[2].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- else -%}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # apply selected background color to page select buttons
data:
@ -727,11 +728,12 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=65535) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco2={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[2].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco2={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # apply unselected foreground color to page select buttons
data:
@ -747,11 +749,12 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=59164) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].pco={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[2].pco2={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].pco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # apply unselected background color to page select buttons
data:
@ -767,11 +770,12 @@ action:
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- set colorcode = (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int(default=16904) -%}
[{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[1].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[2].bco={{colorcode}}"{%- endif -%},{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[2].bco2={{colorcode}}",{%- endfor -%}{%- endif -%}
{%- if not page_scroll -%}{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco2={{colorcode}}"{%- else -%}"p[{{p}}].b[3].bco={{colorcode}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}
{% else %}{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{colorcode}}"{% if not loop.last %},{% endif %}{%- endfor -%}{%- endif -%}]
- service: mqtt.publish # request sensor update
data:
@ -847,9 +851,9 @@ action:
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == selectedfgtopic) and page_scroll }}"
@ -859,7 +863,7 @@ action:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}"p[{{p}}].b[1].pco2={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[2].pco={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
@ -869,9 +873,9 @@ action:
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == selectedbgtopic) and page_scroll }}"
@ -881,7 +885,7 @@ action:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}"p[{{p}}].b[1].bco2={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[2].bco={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
@ -891,9 +895,9 @@ action:
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].pco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == unselectedfgtopic) and page_scroll }}"
@ -903,7 +907,7 @@ action:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}"p[{{p}}].b[1].pco={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].pco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].pco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[2].pco2={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[3].pco={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
@ -913,9 +917,9 @@ action:
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}{%- if p == page1page|int %}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
[{%- for p in range(1,12) %}{%- if p == page1page|int(default=1) %}"p[{{p}}].b[1].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[1].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int(default=2) %}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page3page|int(default=3) %}"p[{{p}}].b[3].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[3].bco={{trigger.payload}}"{%- endif -%}{% if not loop.last %},{% endif %}{%- endfor -%}]
- conditions:
- condition: template
value_template: "{{ (trigger.platform == 'mqtt') and (trigger.topic == unselectedbgtopic) and page_scroll }}"
@ -925,5 +929,5 @@ action:
topic: "{{jsoncommandtopic}}"
payload: >-
[{%- for p in range(1,12) %}"p[{{p}}].b[1].bco={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}{%- if p == page2page|int %}"p[{{p}}].b[2].bco2={{trigger.payload}}"{%- else -%}"p[{{p}}].b[2].bco={{trigger.payload}}"{%- endif -%},{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[2].bco2={{trigger.payload}}",{%- endfor -%}
{%- for p in range(1,12) %}"p[{{p}}].b[3].bco={{trigger.payload}}"{% if not loop.last %},{% endif %}{%- endfor -%}]

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone create device triggers"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] cycles through multiple automations"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone dim the display screen after a specified period of inactivity"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone dims the backlight with the sun"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[7].b[all] displays an alarm control panel"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the month + date with a calendar icon"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays a clock"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -165,11 +165,11 @@ variables:
hasppage: !input hasppage
haspbutton: !input haspbutton
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
hour24: !input hour24
ampm: !input ampm
wrap: !input wrap

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays a clock with a clock icon"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays a dimmer with a toggle on/off icon"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -144,11 +144,11 @@ variables:
text_on: !input text_on
text_off: !input text_off
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=6) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
wrap: !input wrap
icon_on: !input icon_on
icon_off: !input icon_off

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the state or attribute value of an entity"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -239,11 +239,11 @@ variables:
prefix: !input prefix
suffix: !input suffix
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
wrap: !input wrap
title_case: !input title_case
selected_fgcolor: !input selected_fgcolor
@ -391,7 +391,7 @@ action:
# Display attribute and apply text style
- conditions:
- condition: template
value_template: >-
value_template: >-
{{-
(trigger is not defined)
or
@ -474,4 +474,3 @@ action:
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[6].b[all] Page 6 displays Heatpump controls"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[9].b[all] Page 9 displays Heatpump controls"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[8].b[all] Page 8 displays media controls"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the output of a template"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -134,7 +134,7 @@ blueprint:
description: "Enter a well-formed [Home Assistant template](https://www.home-assistant.io/docs/configuration/templating/) string. The variable `trigger_entity` will contain the entity name selected above."
default: 'Forecast: {{state_attr("weather.home", "forecast")[0].condition|title}}'
selector:
text:
template:
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASPone Font Reference above."
@ -232,11 +232,11 @@ variables:
trigger_entity: !input trigger_entity
text: !input template
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
wrap: !input wrap
selected_fgcolor: !input selected_fgcolor
selected_bgcolor: !input selected_bgcolor

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays text"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description
@ -215,11 +215,11 @@ variables:
haspbutton: !input haspbutton
text: !input text
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
wrap: !input wrap
selected_fgcolor: !input selected_fgcolor
selected_bgcolor: !input selected_bgcolor

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays a toggle button"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -268,6 +268,12 @@ blueprint:
default: false
selector:
boolean:
text_enable:
name: "Text enabled"
description: "Enable text, font, and colors. If disabled, no output will be sent to the button but the toggle actions will still be activated on press. Useful to combine with other blueprints that might place output on this button."
default: true
selector:
boolean:
mode: parallel
max_exceeded: silent
@ -294,12 +300,13 @@ variables:
off_fgcolor: !input off_fgcolor
off_bgcolor: !input off_bgcolor
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
wrap: !input wrap
text_enable: !input text_enable
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
@ -429,6 +436,8 @@ action:
or
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish
data:
@ -450,7 +459,7 @@ action:
# Update display if our entity has changed state
- conditions: # Update display if our entity has changed state
- condition: template
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == entity) }}'
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == entity) and (text_enable == true) }}'
sequence:
- service: mqtt.publish
data:
@ -493,7 +502,7 @@ action:
# Theme: Apply selected foreground color when it changes
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedfgtopic }}"
value_template: "{{ (trigger.topic == selectedfgtopic) and (text_enable == true) }}"
sequence:
- service: mqtt.publish
data:
@ -503,7 +512,7 @@ action:
# Theme: Apply selected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedbgtopic }}"
value_template: "{{ (trigger.topic == selectedbgtopic) and (text_enable == true) }}"
sequence:
- service: mqtt.publish
data:
@ -513,7 +522,7 @@ action:
# Theme: Apply unselected foreground color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedfgtopic }}"
value_template: "{{ (trigger.topic == unselectedfgtopic) and (text_enable == true) }}"
sequence:
- service: mqtt.publish
data:
@ -523,7 +532,7 @@ action:
# Theme: Apply unselected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedbgtopic }}"
value_template: "{{ (trigger.topic == unselectedbgtopic) and (text_enable == true) }}"
sequence:
- service: mqtt.publish
data:

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the value of a given entity with icons and colors"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[8].b[9] The slider button on page 8 displays a volume control"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the current weather condition"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -214,11 +214,11 @@ variables:
haspbutton: !input haspbutton
weather_provider: !input weather_provider
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
wrap: !input wrap
selected_fgcolor: !input selected_fgcolor
selected_bgcolor: !input selected_bgcolor

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the current weather condition icon only"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -183,11 +183,11 @@ variables:
haspbutton: !input haspbutton
weather_provider: !input weather_provider
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
font: '{{ font_select.split(" - ")[0] | int(default=8) }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
xcen: '{{ xcen_select.split(" - ")[0] | int(default=1) }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
ycen: '{{ ycen_select.split(" - ")[0] | int(default=1) }}'
selected_fgcolor: !input selected_fgcolor
selected_bgcolor: !input selected_bgcolor
unselected_fgcolor: !input unselected_fgcolor
@ -346,7 +346,7 @@ variables:
{%- else -%}
{{ selected_fgcolor }}
{%- endif -%}
{%- endif -%}
{%- endif -%}
trigger_variables:
haspdevice: !input haspdevice
@ -397,7 +397,7 @@ action:
# Apply styles, place text, and then place icon if our target page is currently active
- conditions:
- condition: template
value_template: >-
value_template: >-
{{-
(trigger is not defined)
or

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the current weather condition with icons"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the weather forecast"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description
@ -120,26 +120,36 @@ blueprint:
selector:
entity:
domain: weather
forecast_interval:
name: "Forecast interval"
description: 'Forecast interval, one of "hourly", "twice daily", or "daily". Not all weather providers will offer all options.'
default: "daily"
selector:
select:
options:
- "hourly"
- "twice_daily"
- "daily"
forecast_index:
name: "Forecast index"
description: 'Weather forecasts are provided at intervals determined by your weather source. The next time interval will be index "0". Increment this number for future forecasts'
description: 'Select a specific forecast, the next time interval will be index "0". Increment this number for future forecasts'
default: 0
selector:
number:
min: 0
max: 10
max: 48
mode: slider
unit_of_measurement: index
forecast_attribute:
name: "Enter the desired forecast attribute"
description: 'Type in the name of the desired forecast attribute for your provider. "condition" is a common attribute for many providers.'
description: 'Type in the name of the desired forecast attribute for your provider. "condition" is a common attribute for many providers.'
default: "condition"
selector:
text:
prefix:
name: "Forecast display prefix"
description: 'Prefix for forecast display, maybe something like "tonight: " or "tomorrow: ". Leave blank for no prefix. Use "\\r" for a newline.'
default:
default:
selector:
text:
font_select:
@ -243,6 +253,7 @@ variables:
hasppage: !input hasppage
haspbutton: !input haspbutton
weather_provider: !input weather_provider
forecast_interval: !input forecast_interval
forecast_index: !input forecast_index
forecast_attribute: !input forecast_attribute
prefix: !input prefix
@ -261,15 +272,6 @@ variables:
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
text: >-
{%- if prefix|lower != "none" -%}
{{ prefix }}
{%- endif -%}
{%- if title_case -%}
{{ state_attr(weather_provider, "forecast")[forecast_index|int(default=0)].get(forecast_attribute)|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") | title }}
{%- else -%}
{{ state_attr(weather_provider, "forecast")[forecast_index|int(default=0)].get(forecast_attribute)|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") }}
{%- endif -%}
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
@ -380,6 +382,23 @@ condition:
value_template: "{{ is_state(haspsensor, 'ON') }}"
action:
- service: weather.get_forecasts
target:
entity_id: !input weather_provider
data:
type: "{{forecast_interval}}"
response_variable: weather_forecast
- variables:
text: >-
{%- if prefix|lower != "none" -%}
{{ prefix }}
{%- endif -%}
{%- if title_case -%}
{{ weather_forecast[weather_provider]['forecast'][forecast_index][forecast_attribute]|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") | title }}
{%- else -%}
{{ weather_forecast[weather_provider]['forecast'][forecast_index][forecast_attribute]|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain") }}
{%- endif -%}
- choose:
#########################################################################
# Display attribute and apply text style when "RUN ACTIONS" is pressed by the user

View File

@ -0,0 +1,459 @@
blueprint:
name: "HASPone p[x].b[y] displays the weather forecast High and Low temperature"
description: |
## Blueprint Version: `1.06.00`
## Description
A HASPone button displays the high and low temperatures from a selected weather forecast.
![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Display_Weather_Forecast.png)
## HASPone Page and Button Reference
The images below show each available HASPone page along with the layout of available button objects.
<details>
| Page 0 | Pages 1-3 | Pages 4-5 |
|--------|-----------|-----------|
| ![Page 0](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASPone Font Reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASPone project includes [Consolas](https://docs.microsoft.com/en-us/typography/font-list/consolas) monospace in 4 sizes, [Webdings](https://en.wikipedia.org/wiki/Webdings#Character_set) in 1 size, and [Google's "Noto Sans"](https://github.com/googlefonts/noto-fonts) proportional in 5 sizes
| Font | Name | Characters per line | Lines per button |
| :--- | :---------------- | :-------------------| :--------------- |
| 0 | Consolas 24 | 20 characters | 2 lines |
| 1 | Consolas 32 | 15 characters | 2 lines |
| 2 | Consolas 48 | 10 characters | 1 line |
| 3 | Consolas 80 | 6 characters | 1 line |
| 4 | Webdings 56 | 8 characters | 1 line |
| 5 | Noto Sans 24 | Proportional | 2 lines |
| 6 | Noto Sans 32 | Proportional | 2 lines |
| 7 | Noto Sans 48 | Proportional | 1 line |
| 8 | Noto Sans 64 | Proportional | 1 line |
| 9 | Noto Sans 80 | Proportional | 1 line |
| 10 | Noto Sans Bold 80 | Proportional | 1 line |
### Icons
Fonts 5-10 also include [1400+ icons which you can copy and paste from here](https://htmlpreview.github.io/?https://github.com/HASwitchPlate/HASPone/blob/main/images/hasp-fontawesome5.html)
### Font examples
![HASPone Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_Fonts_0-3.png) ![HASPone Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_Fonts_4-7.png) ![HASPone Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_Fonts_8-10.png)
</details>
## Nextion color codes
<details>
The Nextion environment utilizes RGB 565 encoding. [Use this handy convertor](https://nodtem66.github.io/nextion-hmi-color-convert/index.html) to select your colors and convert to the RGB 565 format.
Here are some example colors:
| Color | Code |
|--------|-------|
| White | 65535 |
| Black | 0 |
| Grey | 25388 |
| Red | 63488 |
| Green | 2016 |
| Blue | 31 |
| Yellow | 65504 |
| Orange | 64512 |
| Brown | 48192 |
</details>
domain: automation
input:
haspdevice:
name: "HASPone Device"
description: "Select the HASPone device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASPone Page"
description: "Select the HASPone page (1-11) for the forecast. Refer to the HASPone Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASPone Button"
description: "Select the HASPone button (4-15) for the forecast. Refer to the HASPone Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
weather_provider:
name: "Weather provider"
description: "Select the weather provider to obtain the forecast"
selector:
entity:
domain: weather
forecast_interval:
name: "Forecast interval"
description: 'Forecast interval, one of "hourly", "twice daily", or "daily". Not all weather providers will offer all options.'
default: "daily"
selector:
select:
options:
- "hourly"
- "twice_daily"
- "daily"
forecast_index:
name: "Forecast index"
description: 'Select a specific forecast, the next time interval will be index "0". Increment this number for future forecasts'
default: 0
selector:
number:
min: 0
max: 48
mode: slider
unit_of_measurement: index
font_select:
name: "Font"
description: "Select the font for the displayed text. You probably want to leave this as 10, refer to the HASPone Font Reference above."
default: "10 - Noto Sans Bold 80"
selector:
select:
options:
- "0 - Consolas 24"
- "1 - Consolas 32"
- "2 - Consolas 48"
- "3 - Consolas 80"
- "4 - Webdings 56"
- "5 - Noto Sans 24"
- "6 - Noto Sans 32"
- "7 - Noto Sans 48"
- "8 - Noto Sans 64"
- "9 - Noto Sans 80"
- "10 - Noto Sans Bold 80"
xcen_select:
name: "Text horizontal alignment"
description: "Horizontal text alignment: 0=Left 1=Center 2=Right"
default: "1 - Centered"
selector:
select:
options:
- "0 - Left aligned"
- "1 - Centered"
- "2 - Right aligned"
ycen_select:
name: "Text vertical alignment"
description: "Vertical text alignment: 0=Top 1=Center 2=Bottom"
default: "1 - Centered"
selector:
select:
options:
- "0 - Top aligned"
- "1 - Centered"
- "2 - Bottom aligned"
wrap:
name: "Text wrap"
default: false
description: "Enable line-wrapping text if too long to fit in the button."
selector:
boolean:
selected_fgcolor:
name: "Selected foreground color"
description: 'Selected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected foreground color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
selected_bgcolor:
name: "Selected background color"
description: 'Selected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme selected background color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
unselected_fgcolor:
name: "Unselected foreground color"
description: 'Unselected foreground color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected foreground color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
unselected_bgcolor:
name: "Unselected background color"
description: 'Unselected background color in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme unselected background color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
weather_provider: !input weather_provider
forecast_interval: !input forecast_interval
forecast_index: !input forecast_index
font_select: !input font_select
font: '{{ font_select.split(" - ")[0] | int }}'
xcen_select: !input xcen_select
xcen: '{{ xcen_select.split(" - ")[0] | int }}'
ycen_select: !input ycen_select
ycen: '{{ ycen_select.split(" - ")[0] | int }}'
wrap: !input wrap
selected_fgcolor: !input selected_fgcolor
selected_bgcolor: !input selected_bgcolor
unselected_fgcolor: !input unselected_fgcolor
unselected_bgcolor: !input unselected_bgcolor
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
selectedfg: >-
{%- if (selected_fgcolor|int) >= 0 -%}
{{ selected_fgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
selectedbg: >-
{%- if (selected_bgcolor|int) >= 0 -%}
{{ selected_bgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
unselectedfg: >-
{%- if (unselected_fgcolor|int) >= 0 -%}
{{ unselected_fgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
unselectedbg: >-
{%- if (unselected_bgcolor|int) >= 0 -%}
{{ unselected_bgcolor }}
{%- else -%}
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
{%- endif -%}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{%- endif -%}
{%- endfor -%}
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
trigger:
- platform: state
entity_id: !input weather_provider
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
topic: "{{selectedfgtopic}}"
- platform: mqtt
topic: "{{selectedbgtopic}}"
- platform: mqtt
topic: "{{unselectedfgtopic}}"
- platform: mqtt
topic: "{{unselectedbgtopic}}"
condition:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
action:
- service: weather.get_forecasts
target:
entity_id: !input weather_provider
data:
type: "{{forecast_interval}}"
response_variable: weather_forecast
- variables:
temphigh: '{{ weather_forecast[weather_provider]["forecast"][forecast_index]["temperature"] }}'
templow: '{{ weather_forecast[weather_provider]["forecast"][forecast_index]["templow"] }}'
text: "{{templow|int(default=0)}}° {{temphigh|int(default=0)}}°"
- choose:
#########################################################################
# Display attribute and apply text style when "RUN ACTIONS" is pressed by the user
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
or
(trigger.platform is none)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[
"{{haspobject}}.font={{font}}",
"{{haspobject}}.xcen={{xcen}}",
"{{haspobject}}.ycen={{ycen}}",
"{{haspobject}}.isbr={{isbr}}",
"{{haspobject}}.pco={{selectedfg}}",
"{{haspobject}}.bco={{selectedbg}}",
"{{haspobject}}.pco2={{unselectedfg}}",
"{{haspobject}}.bco2={{unselectedbg}}",
"{{haspobject}}.txt=\"{{text}}\""
]
#########################################################################
# Update forecast if our weather provider changed state
- conditions:
- condition: template
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == weather_provider) }}'
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.txt"
payload: '"{{text}}"'
#########################################################################
# Catch triggers fired by incoming MQTT messages
- conditions:
- condition: template
value_template: '{{ trigger.platform == "mqtt" }}'
sequence:
- choose:
#########################################################################
# Theme: Apply selected foreground color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == selectedfgtopic) and ((selected_fgcolor|int) == -1) }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.pco"
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply selected background color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == selectedbgtopic) and ((selected_bgcolor|int) == -1) }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco"
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply unselected foreground color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == unselectedfgtopic) and ((unselected_fgcolor|int) == -1) }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.pco2"
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply unselected background color on change
- conditions:
- condition: template
value_template: "{{ (trigger.topic == unselectedbgtopic) and ((unselected_bgcolor|int) == -1) }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the current temperature from a weather provider, coloured icon only"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -201,7 +201,7 @@ variables:
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
temperature: '{{ state_attr(weather_provider, "temperature") }}'
icon: >-
{%- set temp = temperature|int -%}
{%- set temp = temperature|int(default=0) -%}
{%- if temp <= thermometer_quarter_threshold|int -%}
{%- elif temp < thermometer_half_threshold|int -%}
@ -333,7 +333,7 @@ action:
# Apply styles, place text, and then place icon if our target page is currently active
- conditions:
- condition: template
value_template: >-
value_template: >-
{{-
(trigger is not defined)
or

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] displays the current temperature from a weather provider with icon and colors"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description
@ -224,10 +224,10 @@ variables:
{%- if roundtemp == true -%}
{{- state_attr(weather_provider, "temperature") | round(default=0) -}}
{%- else -%}
{{- state_attr(weather_provider, "temperature") -}}
{{- state_attr(weather_provider, "temperature") | float(default=0) -}}
{%- endif -%}
icon: >-
{%- set temp = temperature|int -%}
{%- set temp = temperature|int(default=0) -%}
{%- if temp <= thermometer_quarter_threshold|int -%}
{%- elif temp < thermometer_half_threshold|int -%}
@ -310,7 +310,7 @@ variables:
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
tempcolor: >-
{%- set temp = temperature|int -%}
{%- set temp = temperature|int(default=0) -%}
{%- if temp <= thermometer_quarter_threshold|int -%}
{%- set color = thermometer_empty_color -%}
{%- elif temp < thermometer_half_threshold|int -%}

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone p[x].b[y] performs an action when pressed"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone Remove MQTT discovery messages"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
# Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone Theme Dark on Light"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone Theme Light on Dark Blue"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description
@ -52,7 +52,7 @@ variables:
{%- endfor -%}
selected_foreground_brightness: "255"
selected_foreground_color: "[255, 255, 255]"
selected_background_brightness: "1"
selected_background_brightness: "32"
selected_background_color: "[0, 0, 255]"
unselected_foreground_brightness: "224"
unselected_foreground_color: "[255, 255, 255]"

View File

@ -2,7 +2,7 @@ blueprint:
name: "HASPone Theme Light on Dark"
description: |
## Blueprint Version: `1.05.00`
## Blueprint Version: `1.06.00`
## Description

View File

@ -15,4 +15,4 @@ Please [check the Nextion HMI documentation](../Documentation/02_Nextion_HMI.md)
* **[HASwitchPlate-Discovery-Inverted.tft](HASwitchPlate-Discovery-Inverted.tft)** Discovery series firmware but inverted, usable if the viewing angle on your display works better when mounted upside-down.
* **[HASwitchPlate-Enhanced.tft](HASwitchPlate-Enhanced.tft)** This is the compiled Nextion firmware for the HASPone usable on an enhanced Nextion 2.4" LCD, model `NX4024K032_011R`. This panel will not fit in the provided 3D printed enclosure and no enhanced features are used in this project. **Don't buy this panel**, but if you did (*and you shouldn't*), you can use this firmware.
* **[HASwitchPlate-TJC.hmi](HASwitchPlate-TJC.hmi)** This is the "source" file for the Chinese-market TJC LCD model `TJC3224T024_011`. This file cannot be used with the english language editor. If you purchase this panel, you will need to use the Chinese-language "USART HMI" editor to modify this file. **Don't buy this panel**.
* **[HASwitchPlate-TJC.tft](HASwitchPlate-TJC.tft)** This is the compiled Nextion firmware for the HASPone usable on a Chinese market TJC 2.4" LCD, model `TJC3224T024_011`.
* **[HASwitchPlate-TJC.tft](HASwitchPlate-TJC.tft)** This is the compiled Nextion firmware for the HASPone usable on a Chinese market TJC 2.4" LCD, model `TJC3224T024_011`.

75
esphome/haspone.yaml Normal file
View File

@ -0,0 +1,75 @@
# Example ESPhome configuration for use with the HASPone hardware
substitutions:
device_name: "haspone"
friendly_name: "HASPone hardware for ESPhome"
project_version: "0.0.1"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
comment: "http://haswitchplate.com"
project:
name: "esphome.${device_name}"
version: ${project_version}
on_boot:
then:
- switch.turn_on: switch_lcdpower # Power up the Nextion on boot
esp8266:
board: d1_mini
logger:
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
web_server:
port: 80
# HASPone switch controls power to the Nextion. Set HIGH at power on to enable the device at boot.
switch:
- platform: gpio
id: switch_lcdpower
name: "${friendly_name} Nextion Power"
pin: D6 #GPIO12
restore_mode: ALWAYS_ON
internal: false
# UART for HASPone communication to Nextion. This will utilize software serial and might not work well for TFT updates.
uart:
id: uart_nextion
tx_pin: D4 #GPIO2
rx_pin: D7 #GPIO13
baud_rate: 115200
# Nextion display device
display:
- platform: nextion
id: display_nextion
uart_id: uart_nextion
on_touch:
then:
lambda: |-
ESP_LOGD("nextion.on_touch", "Nextion touch event detected!");
ESP_LOGD("nextion.on_touch", "Page Id: %i", page_id);
ESP_LOGD("nextion.on_touch", "Component Id: %i", component_id);
ESP_LOGD("nextion.on_touch", "Event type: %s", touch_event ? "Press" : "Release");
# Nextion backlight control
number:
- platform: template
id: number_brightness
name: "${friendly_name} Nextion Brightness"
min_value: 0
max_value: 100
step: 1
initial_value: 100
optimistic: true
set_action:
- lambda: id(display_nextion)->set_backlight_brightness(x/100);

3
esphome/readme.md Normal file
View File

@ -0,0 +1,3 @@
# HASPone for ESPhome
Here you'll find an example ESPhome configuration for use with the HASPone hardware, this should be compatible with existing ESPhome-native Nextion projects for a 2.8" panel.

BIN
images/HASP PCB Back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

BIN
images/HASP PCB Front.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -1,18 +1,18 @@
{
"d1_mini": {
"version": "1.05",
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Arduino_Sketch/HASwitchPlate.ino.d1_mini.bin"
"version": "1.06",
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate.ino.d1_mini.bin"
},
"NX3224T024_011R": {
"version": 3,
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate.tft"
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate.tft"
},
"NX3224K024_011R": {
"version": 3,
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate-Enhanced.tft"
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate-Enhanced.tft"
},
"NX3224F024_011R": {
"version": 3,
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate-Discovery.tft"
"firmware": "https://haswitchplate.com/update/main/HASwitchPlate-Discovery.tft"
}
}