Add blueprints and HMI

This commit is contained in:
aderusha 2021-03-03 07:21:06 -05:00
parent bdaa5e7d90
commit 48c4ec7941
30 changed files with 3355 additions and 86 deletions

View File

@ -0,0 +1,125 @@
blueprint:
name: "HASP p[x].b[y] activates a page"
description: |
# Description
A button on the HASP will activate a page when pressed. Can be combined on a button with another blueprint which displays text.
## HASP Page and Button Reference
The images below show each available HASP 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/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Activate_Page.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11) for this page button. Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button for this page button. Refer to the HASP Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
targetpage:
name: "Page to activate"
description: "Select a destination page for this button to activate."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
targetpage: !input targetpage
pagecommandtopic: '{{ "hasp/" ~ haspname ~ "/command/page" }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- endif -%}
{%- endfor -%}
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
hasppage: !input hasppage
haspbutton: !input haspbutton
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
buttonjsonpayload: '{"event_type":"button_short_press","event":"{{haspobject}}","value":"ON"}'
trigger:
- platform: mqtt
topic: "{{jsontopic}}"
payload: "{{buttonjsonpayload}}"
condition:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
action:
- service: mqtt.publish
data:
topic: "{{pagecommandtopic}}"
payload: "{{targetpage}}"

View File

@ -24,7 +24,7 @@ blueprint:
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button.png)
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
@ -102,6 +102,7 @@ blueprint:
min: 0
max: 11
mode: slider
unit_of_measurement: page
page2text:
name: "Page select button 2 text"
description: "Enter text to appear on the center page select button #2. If page scrolling is enabled, use the Page Names list below."
@ -135,6 +136,7 @@ blueprint:
min: 0
max: 11
mode: slider
unit_of_measurement: page
page3text:
name: "Page select button 3 text"
description: "Enter text to appear on the right-most page select button #3"
@ -168,6 +170,7 @@ blueprint:
min: 0
max: 11
mode: slider
unit_of_measurement: page
page_scroll:
name: "Enable page scrolling instead of page select"
description: "If enabled, page buttons 1 and 3 will scroll up and down through available pages. The middle page button 2 will continue to select its assigned page number, but the label for page button 2 will be determined based on the Page Names defined below."
@ -318,7 +321,13 @@ trigger_variables:
{{ break }}
{%- endif -%}
{%- endfor -%}
statetopic: '{{ "hasp/" ~ haspname ~ "/state" }}'
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- endif -%}
{%- endfor -%}
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
@ -326,10 +335,8 @@ trigger_variables:
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
trigger:
- platform: mqtt
topic: "{{jsontopic}}"
payload: "online"
value_template: "{{ value_json.event }}"
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
@ -343,6 +350,10 @@ trigger:
- platform: mqtt
topic: "{{unselectedbgtopic}}"
condition:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
action:
- choose:
#########################################################################
@ -637,7 +648,12 @@ action:
# Push configuration to device when it connects or Home Assistant starts
- conditions:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') and ((trigger.platform == 'homeassistant') and (trigger.event == 'start')) or ((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))}}"
value_template: >-
{{-
((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 # send page button text
data:

View File

@ -24,7 +24,7 @@ blueprint:
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button.png)
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
@ -63,7 +63,6 @@ variables:
{{ break }}
{%- endif -%}
{%- endfor -%}
statetopic: '{{ "hasp/" ~ haspname ~ "/state" }}'
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
@ -78,13 +77,6 @@ variables:
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
@ -92,13 +84,10 @@ trigger_variables:
{{ break }}
{%- endif -%}
{%- endfor -%}
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
trigger:
- platform: mqtt
topic: "{{jsontopic}}"
payload: "online"
value_template: "{{ value_json.event }}"
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start

View File

@ -46,6 +46,7 @@ blueprint:
min: 2
max: 10
mode: slider
unit_of_measurement: digits
armservice:
name: "Alarm arm service"
description: 'Enter the alarm service call to issue when the ARM button is pressed. Typically this is one of "alarm_arm_away", "alarm_arm_home", "alarm_arm_night", or "alarm_arm_custom_bypass".'
@ -172,6 +173,8 @@ trigger:
entity_id: !input alarmpanel
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{jsontopic}}"
- platform: mqtt
@ -193,7 +196,14 @@ action:
# RUN ACTIONS or Home Assistant Startup or HASP Connect
- conditions:
- condition: template
value_template: "{{ (trigger is not defined) or ((trigger.platform == 'homeassistant') and (trigger.event == 'start')) or ((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))}}"
value_template: >-
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
# Apply themes and set numbered button labels
- service: mqtt.publish
@ -247,7 +257,8 @@ action:
{"name":"{{haspname}} alarmcode {{repeat.index}}",
"command_topic":"hasp/{{haspname}}/alarmcode/{{repeat.index}}",
"availability":{"topic":"hasp/{{haspname}}/alwayson","payload_available":"ON"},
"optimistic":"true",
"retain":true,
"optimistic":true,
"icon":"mdi:bell-plus-outline",
"unique_id":"{{haspClientId}}-alarmcode_{{repeat.index}}",
"device":{
@ -342,7 +353,7 @@ action:
# Arm was pressed
- conditions:
- condition: template
value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[7].b[15]") and (trigger.payload_json.value == "ON") and (alarmstate == "disarmed")}}'
value_template: '{{ (trigger.payload_json.event is defined) and (trigger.payload_json.event == "p[7].b[15]") and (trigger.payload_json.value == "ON") and (alarmstate == "disarmed")}}'
sequence:
- service_template: "{{armservice_name}}"
data:
@ -367,7 +378,7 @@ action:
# Disarm was pressed
- conditions:
- condition: template
value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[7].b[15]") and (trigger.payload_json.value == "ON")}}'
value_template: '{{ (trigger.payload_json.event is defined) and (trigger.payload_json.event == "p[7].b[15]") and (trigger.payload_json.value == "ON")}}'
sequence:
- service: alarm_control_panel.alarm_disarm
data:

View File

@ -40,6 +40,7 @@ blueprint:
min: 1
max: 3
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-7) for the calendar. Refer to the HASP Page and Button reference above."
@ -49,6 +50,7 @@ blueprint:
min: 4
max: 7
mode: slider
unit_of_measurement: button
mode: parallel
max_exceeded: silent
@ -169,6 +171,8 @@ trigger:
at: "00:00:00"
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{jsontopic}}"
- platform: mqtt
@ -195,9 +199,9 @@ action:
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish

View File

@ -24,7 +24,7 @@ blueprint:
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button.png)
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
@ -78,6 +78,7 @@ blueprint:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-15) for the clock. Refer to the HASP Page and Button reference above."
@ -87,6 +88,7 @@ blueprint:
min: 4
max: 15
mode: slider
unit_of_measurement: button
font_select:
name: "Clock Font"
description: "Select the font for the clock. Refer to the HASP Font reference above."
@ -261,10 +263,8 @@ trigger_variables:
trigger:
- platform: time_pattern
seconds: 0
- platform: mqtt
topic: "{{jsontopic}}"
payload: "online"
value_template: "{{ value_json.event }}"
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
@ -276,7 +276,6 @@ trigger:
- platform: mqtt
topic: "{{unselectedbgtopic}}"
condition:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
@ -288,13 +287,13 @@ action:
# Display clock and apply text style
- conditions:
- condition: template
value_template: >-
value_template: >-
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish

View File

@ -40,6 +40,7 @@ blueprint:
min: 1
max: 3
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-7) for the clock. Refer to the HASP Page and Button reference above."
@ -49,6 +50,7 @@ blueprint:
min: 4
max: 7
mode: slider
unit_of_measurement: button
hour24:
name: "24 hour clock display"
default: false
@ -175,6 +177,8 @@ trigger:
seconds: 0
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{jsontopic}}"
- platform: mqtt
@ -201,9 +205,9 @@ action:
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish

View File

@ -40,6 +40,7 @@ blueprint:
min: 4
max: 5
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (7-9) for the dimmer. Refer to the HASP Page and Button reference above."
@ -49,6 +50,7 @@ blueprint:
min: 7
max: 9
mode: slider
unit_of_measurement: button
dimmer:
name: "Light to control"
description: "Select a light device which supports dimming"
@ -259,6 +261,8 @@ trigger_variables:
trigger:
- platform: state
entity_id: !input dimmer
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
@ -287,9 +291,9 @@ action:
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish

View File

@ -0,0 +1,425 @@
blueprint:
name: "HASP p[x].b[y] displays the state or attribute value of an entity"
description: |
# Description
A HASP button displays the state or attribute value of an entity
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Entity_State_or_Attribute.png)
## Examples
<details>
### Show current weather condition
**Entity:** Select a weather provider of your choice
**Attribute:** `state`
**Title Case:** `true`
### Show current wind speed from Met.no
**Entity:** The default Met.no provider from Home Assistant. If you left your location named "Home", the entity should be `weather.home`
**Attribute:** `wind_speed`
### Show current track name on a media player
**Entity:** A media player with track information
**Attribute:** `media_title`
</details>
## HASP Page and Button Reference
The images below show each available HASP 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/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASP Font Reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASP 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/aderusha/HASwitchPlate/blob/master/Documentation/Images/hasp-fontawesome5.html)
### Font examples
![HASP Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_0-3.png) ![HASP Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_4-7.png) ![HASP Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_8-10.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Entity_State_or_Attribute.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11). Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-15) for the state display. Refer to the HASP Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
selected_entity:
name: "Select an entity"
selector:
entity:
selected_attribute:
name: "Enter the desired entity attribute"
description: "Enter `state` to track the state of the sensor above, or enter an attribute name if the sensor has a specific attribute you want to track."
default: "state"
selector:
text:
prefix:
name: "State display prefix"
description: "Prefix for state display, leave blank for no prefix"
default:
selector:
text:
suffix:
name: "State display suffix"
description: "Suffix for state display, leave blank for no suffix"
default:
selector:
text:
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASP Font Reference above."
default: "8 - Noto Sans 64"
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"
description: "Enable line-wrapping text if too long to fit in the button."
default: false
selector:
boolean:
title_case:
name: "Title Case"
description: "Apply The Title Case Filter To Capitalize The First Character Of Each Word In The Result"
default: false
selector:
boolean:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
selected_entity: !input selected_entity
selected_attribute: !input selected_attribute
prefix: !input prefix
suffix: !input suffix
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
title_case: !input title_case
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
selected_entity_attribute: "{{state_attr(selected_entity,selected_attribute)}}"
entity_text: >-
{%- if selected_attribute|lower == "state" -%}
{{- states(selected_entity) -}}
{%- else -%}
{{- state_attr(selected_entity, selected_attribute) -}}
{%- endif -%}
text: >-
{%- if prefix|lower != "none" -%}
{{ prefix }}
{%- endif -%}
{%- if title_case -%}
{{- entity_text | title -}}
{%- else -%}
{{ entity_text }}
{%- endif -%}
{%- if suffix|lower != "none" -%}
{{ suffix }}
{%- endif -%}
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- 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: state
entity_id: !input selected_entity
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
topic: "{{jsontopic}}"
- 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 HASP Connect
# Display attribute and apply text style
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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 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 == selected_entity) }}'
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 }}"
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 }}"
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 }}"
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 }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -0,0 +1,353 @@
blueprint:
name: "HASP p[8].b[all] Page 8 displays media controls"
description: |
# Description
Page 8 controls a selected media player with artist and track info, track back/play|pause/track forward, and volume control
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Media_Control_page8.png)
## HASP Page and Button reference
<details>
This automation is designed to work with the media controls found on page 8:
| Page 8 |
|--------|
| ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Media_Control_page8.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
mediaplayer:
name: "Media Player to control"
description: "Select a media player to control"
selector:
entity:
domain: media_player
button4attribute:
name: "Top button attribute"
description: "Enter the media_player attribute to show on the top-most button on the media player screen."
default: "media_artist"
selector:
text:
button5attribute:
name: "Second button attribute"
description: "Select the media_player attribute to show on the second-from-top button on the media player screen."
default: "media_title"
selector:
text:
mode: parallel
max_exceeded: silent
variables:
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- endif -%}
{%- endfor -%}
mediaplayer: !input mediaplayer
button4attribute: !input button4attribute
button5attribute: !input button5attribute
volumeobject: '{{ "p[8].b[9]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" }}'
volumecommandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ volumeobject ~ ".val" }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
volume: "{% if state_attr(mediaplayer, 'volume_level')|lower == 'none' %}0{% else %}{{(state_attr(mediaplayer, 'volume_level')*255)|int}}{% endif %}"
button4text: "{% if state_attr(mediaplayer, button4attribute)|lower == 'none' %}{% else %}{{state_attr(mediaplayer, button4attribute)|wordwrap(19, wrapstring='\\\\r')}}{% endif %}"
# button4text: '{{state_attr(mediaplayer, button4attribute)|wordwrap(19, wrapstring="\\\\r")}}'
button4font: "{% set attr_length = button4text|safe|length%}{% if attr_length <= 6 -%}9{% elif attr_length <= 8 %}8{% elif attr_length <= 10 %}7{% else %}6{%- endif %}"
button5text: "{% if state_attr(mediaplayer, button5attribute)|lower == 'none' %}{% else %}{{state_attr(mediaplayer, button5attribute)|wordwrap(19, wrapstring='\\\\r')}}{% endif %}"
# button5text: '{{state_attr(mediaplayer, button5attribute)|wordwrap(19, wrapstring="\\\\r")}}'
button5font: "{% set attr_length = button5text|safe|length%}{% if attr_length <= 6 -%}9{% elif attr_length <= 8 %}8{% elif attr_length <= 10 %}7{% else %}6{%- endif %}"
button6text: "" # prev track
button6font: 8
button7text: '{% if is_state(mediaplayer, "playing") %}{% else %}{% endif %}'
button7font: 8
button8text: "" # next track
button8font: 8
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- 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: state
entity_id: !input mediaplayer
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
topic: "{{jsontopic}}"
- 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 HASP Connect
# Apply styles and place text
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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: >-
["p[8].b[4].pco={{selectedfg}}","p[8].b[4].bco={{selectedbg}}","p[8].b[4].pco2={{unselectedfg}}","p[8].b[4].bco2={{unselectedbg}}","p[8].b[4].font={{button4font}}","p[8].b[4].txt=\"{{button4text}}\"",
"p[8].b[5].pco={{selectedfg}}","p[8].b[5].bco={{selectedbg}}","p[8].b[5].pco2={{unselectedfg}}","p[8].b[5].bco2={{unselectedbg}}","p[8].b[5].font={{button5font}}","p[8].b[5].txt=\"{{button5text}}\"",
"p[8].b[6].pco={{selectedfg}}","p[8].b[6].bco={{selectedbg}}","p[8].b[6].pco2={{unselectedfg}}","p[8].b[6].bco2={{unselectedbg}}","p[8].b[6].font={{button6font}}","p[8].b[6].txt=\"{{button6text}}\"",
"p[8].b[7].pco={{selectedfg}}","p[8].b[7].bco={{selectedbg}}","p[8].b[7].pco2={{unselectedfg}}","p[8].b[7].bco2={{unselectedbg}}","p[8].b[7].font={{button7font}}","p[8].b[7].txt=\"{{button7text}}\"",
"p[8].b[8].pco={{selectedfg}}","p[8].b[8].bco={{selectedbg}}","p[8].b[8].pco2={{unselectedfg}}","p[8].b[8].bco2={{unselectedbg}}","p[8].b[8].font={{button8font}}","p[8].b[8].txt=\"{{button8text}}\"",
"{{volumeobject}}.pco={{unselectedfg}}","{{volumeobject}}.bco={{unselectedbg}}","{{volumeobject}}.val={{volume}}"]
#########################################################################
# Update volume if it has changed state
- conditions: # volume has changed value
- condition: template
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == mediaplayer) and (trigger.from_state.attributes.volume_level != trigger.to_state.attributes.volume_level)}}'
sequence:
- service: mqtt.publish
data:
topic: "{{volumecommandtopic}}"
payload: "{{volume}}"
#########################################################################
# Update button4attribute and button5attribute
- conditions:
- condition: template
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == mediaplayer) }}'
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: '["p[8].b[4].font={{button4font}}","p[8].b[4].txt=\"{{button4text}}\"","p[8].b[5].font={{button5font}}","p[8].b[5].txt=\"{{button5text}}\"","p[8].b[7].txt=\"{{button7text}}\""]'
#########################################################################
# Handle MQTT message triggers
- conditions:
- condition: template
value_template: '{{ trigger.platform == "mqtt" }}'
sequence:
- choose:
#########################################################################
# Catch incoming JSON messages
- conditions:
- condition: template
value_template: "{{ (trigger.topic == jsontopic) and trigger.payload_json is defined }}"
sequence:
- choose:
#########################################################################
# Set the volume value when the HASP slider has moved
- conditions:
- condition: template
value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == volumeobject ~ ".val") }}'
sequence:
- service: media_player.volume_set
entity_id: !input mediaplayer
data:
volume_level: "{{trigger.payload_json.value/255}}"
#########################################################################
# Previous track button was pressed
- conditions:
- condition: template
value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[8].b[6]") and (trigger.payload_json.value == "ON")}}'
sequence:
- service: media_player.media_previous_track
entity_id: !input mediaplayer
#########################################################################
# Play/pause was pressed
- conditions:
- condition: template
value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[8].b[7]") and (trigger.payload_json.value == "ON")}}'
sequence:
- service: media_player.media_play_pause
entity_id: !input mediaplayer
#########################################################################
# Next track button was pressed
- conditions:
- condition: template
value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[8].b[8]") and (trigger.payload_json.value == "ON")}}'
sequence:
- service: media_player.media_next_track
entity_id: !input mediaplayer
#########################################################################
# Theme: Apply selected foreground color when it changes.
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedfgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
["p[8].b[4].pco={{selectedfg}}",
"p[8].b[5].pco={{selectedfg}}",
"p[8].b[6].pco={{selectedfg}}",
"p[8].b[7].pco={{selectedfg}}",
"p[8].b[8].pco={{selectedfg}}"]
#########################################################################
# Theme: Apply selected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedbgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
["p[8].b[4].bco={{selectedbg}}",
"p[8].b[5].bco={{selectedbg}}",
"p[8].b[6].bco={{selectedbg}}",
"p[8].b[7].bco={{selectedbg}}",
"p[8].b[8].bco={{selectedbg}}"]
#########################################################################
# Theme: Apply unselected foreground color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedfgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
["p[8].b[4].pco2={{unselectedfg}}",
"p[8].b[5].pco2={{unselectedfg}}",
"p[8].b[6].pco2={{unselectedfg}}",
"p[8].b[7].pco2={{unselectedfg}}",
"p[8].b[8].pco2={{unselectedfg}}",
"{{volumeobject}}.pco={{unselectedfg}}"]
#########################################################################
# Theme: Apply unselected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedbgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
["p[8].b[4].bco2={{unselectedbg}}",
"p[8].b[5].bco2={{unselectedbg}}",
"p[8].b[6].bco2={{unselectedbg}}",
"p[8].b[7].bco2={{unselectedbg}}",
"p[8].b[8].bco2={{unselectedbg}}",
"{{volumeobject}}.bco={{unselectedbg}}"]

View File

@ -61,6 +61,7 @@ blueprint:
min: 1
max: 3
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-7) for the temperature. Refer to the HASP Page and Button reference above."
@ -70,6 +71,7 @@ blueprint:
min: 4
max: 7
mode: slider
unit_of_measurement: button
weather_provider:
name: "Weather provider"
description: "Select the weather provider to obtain the current outdoor temperature. If a temperature sensor is selected below, that will override this selection."
@ -86,7 +88,7 @@ blueprint:
domain: sensor
temperature_attribute:
name: "Temperature sensor state or attribute to monitor"
description: 'Enter "state" to track the state of the sensor above, or enter an attribute name if the sensor has a specific attribute you want to track. Most uses will leave this set to "state".'
description: "Enter `state` to track the state of the sensor above, or enter an attribute name if the sensor has a specific attribute you want to track. Most uses will leave this set to `state`."
default: "state"
selector:
text:
@ -227,7 +229,6 @@ variables:
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
# temperature: '{{state_attr(weather_provider, "temperature")|int}}'
temperature: >-
{%- if temperature_sensor|lower == "none" -%}
{{- state_attr(weather_provider, "temperature") -}}
@ -374,6 +375,8 @@ trigger_variables:
trigger:
- platform: state
entity_id: !input weather_provider
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
@ -402,9 +405,9 @@ action:
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish

View File

@ -0,0 +1,396 @@
blueprint:
name: "HASP p[x].b[y] displays the output of a template"
description: |
# Description
A button on the HASP will display the output of a template. The template is updated when the state of a selected entity updates.
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Template.png)
## Examples
<details>
### Show tomorrow's high/low temperature from Met.no
**Trigger entity:** The default Met.no provider from Home Assistant. If you left your location named "Home", the entity should be `weather.home`
**Template:** `Tomorrow\\rHigh: {{state_attr(trigger_entity, "forecast")[0].temperature|int}} Low: {{state_attr(trigger_entity, "forecast")[0].templow|int}}`
**Font:** `6`
</details>
## HASP Page and Button Reference
The images below show each available HASP 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/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASP Font Reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASP 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/aderusha/HASwitchPlate/blob/master/Documentation/Images/hasp-fontawesome5.html)
### Font examples
![HASP Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_0-3.png) ![HASP Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_4-7.png) ![HASP Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_8-10.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Template.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11). Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-15) for the template display. Refer to the HASP Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
trigger_entity:
name: "Select an entity to trigger template update"
description: "Update the displayed template when the state or attributes of the selected entity update."
selector:
entity:
template:
name: "Template to output"
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:
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASP Font Reference above."
default: "8 - Noto Sans 64"
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"
description: "Enable line-wrapping text if too long to fit in the button."
default: false
selector:
boolean:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
trigger_entity: !input trigger_entity
text: !input template
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
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- 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: state
entity_id: !input trigger_entity
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: homeassistant
event: start
- platform: mqtt
topic: "{{jsontopic}}"
- 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 HASP Connect
# Display template and apply text style
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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 display if our entity has changed state, or if the user presses the button
- conditions:
- condition: template
value_template: >-
{{-
(
(trigger.platform == "state")
and
(trigger.entity_id == trigger_entity)
)
or
(
(trigger.topic == jsontopic)
and
(trigger.payload_json is defined)
and
(trigger.payload_json.event_type is defined)
and
(trigger.payload_json.event_type == "button_short_press")
and
(trigger.payload_json.event is defined)
and
(trigger.payload_json.event == haspobject)
)
-}}
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 }}"
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 }}"
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 }}"
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 }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -0,0 +1,345 @@
blueprint:
name: "HASP p[x].b[y] displays text"
description: |
## Description
A button on the HASP will display text. This can be useful when combined with other blueprints which perform an action, but don't apply a label to a button.
Deploy both blueprints on the same button, and now you have a button that says things things and does things.
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Text.png)
## HASP Page and Button Reference
The images below show each available HASP 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/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASP Font Reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASP 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/aderusha/HASwitchPlate/blob/master/Documentation/Images/hasp-fontawesome5.html)
### Font examples
![HASP Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_0-3.png) ![HASP Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_4-7.png) ![HASP Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_8-10.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Text.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11). Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-15) for the template display. Refer to the HASP Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
text:
name: "Text to display"
description: "Enter text to be displayed on the HASP."
default: "Text to display"
selector:
text:
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASP Font Reference above."
default: "8 - Noto Sans 64"
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"
description: "Enable line-wrapping text if too long to fit in the button."
default: false
selector:
boolean:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
text: !input text
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
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- 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 HASP Connect
# Display text and apply text style
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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}}\""
]
#########################################################################
# 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 }}"
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 }}"
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 }}"
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 }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -0,0 +1,535 @@
blueprint:
name: "HASP p[x].b[y] displays a toggle button"
description: |
# Description
Press a button on the HASP to toggle the state of an entity. The button colors will change in response to the on/off state or attribute of the selected entity.
There are a lot of options below! No worries, the defaults should work in a lot of cases.
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Toggle.gif)
## Examples
<details>
### Toggle play/pause on a media player
**Entity to toggle:** A media player that supports play and pause commands
**Entity state to be considered "on":** `playing`
**Service call to turn "on":** `media_player.media_play`
**Service call to turn "off":** `media_player.media_pause`
**Text to display when entity is "on":** ' Pause'
**Text to display when entity is "off":** ' Play'
### Lock or unlock a door
**Entity to toggle:** A lock that supports lock and unlock commands
**Entity state to be considered "on":** `locked`
**Service call to turn "on":** `lock.lock`
**Service call to turn "off":** `lock.unlock`
**Text to display when entity is "on":** ' Locked'
**Text to display when entity is "off":** ' Unlocked'
### Open or close a door
**Entity to toggle:** A cover entity that supports open and close commands
**Entity state to be considered "on":** `closed`
**Service call to turn "on":** `cover.close_cover`
**Service call to turn "off":** `cover.open_cover`
**Text to display when entity is "on":** ' Closed'
**Text to display when entity is "off":** ' Open'
</details>
## HASP Page and Button Reference
The images below show each available HASP 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/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASP Font Reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASP 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/aderusha/HASwitchPlate/blob/master/Documentation/Images/hasp-fontawesome5.html)
### Font examples
![HASP Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_0-3.png) ![HASP Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_4-7.png) ![HASP Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/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>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Toggle.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11) for this toggle. Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button for this toggle. Refer to the HASP Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
entity:
name: "Entity to toggle"
description: "Select an entity for this button to toggle"
selector:
entity:
attribute:
name: "Entity attribute or state to monitor"
description: 'Enter "state" to track the state of an entity, or enter an attribute name if the entity has a specific attribute you want to track. Most uses will leave this set to "state".'
default: "state"
selector:
text:
state_on:
name: 'Entity state to be considered "on"'
description: 'For most devices, this will be "on". If the selected entity state or attribute does not match this value (case insensitive), it will be considered "off"'
default: "on"
selector:
text:
action_on:
name: 'Action to turn "on"'
description: "Select an action that will turn the selected device on."
default:
selector:
action:
action_off:
name: 'Action to turn "off"'
description: "Select an action that will turn the selected device off"
default:
selector:
action:
text_on:
name: 'Text to display when entity is "on"'
description: 'Enter text to be displayed on the button when the selected entity is in the "on" state.'
default: "Entity on"
selector:
text:
text_off:
name: 'Text to display when entity is "off"'
description: 'Enter text to be displayed on the button when the selected entity is in the "off" state.'
default: "Entity off"
selector:
text:
on_fgcolor:
name: '"on" foreground color'
description: 'Text foreground color when the selected entity is "on" 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
on_bgcolor:
name: '"on" background color'
description: 'Text background color when the selected entity is "on" in Nextion RGB565 format. -1 = Current theme selected background color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
off_fgcolor:
name: '"off" foreground color'
description: 'Text foreground color when the selected entity is "off" in Nextion RGB565 format. -1 = Current theme unselected foreground color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
off_bgcolor:
name: '"off" background color'
description: 'Text background color when the selected entity is "off" in Nextion RGB565 format. -1 = Current theme unselected background color.'
default: -1
selector:
number:
min: -1
max: 65535
mode: slider
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASP Font Reference above."
default: "8 - Noto Sans 64"
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"
description: "Enable line-wrapping text if too long to fit in the button."
default: false
selector:
boolean:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
entity: !input entity
attribute: !input attribute
state_on: !input state_on
action_on: !input action_on
action_off: !input action_off
text_on: !input text_on
text_off: !input text_off
on_fgcolor: !input on_fgcolor
on_bgcolor: !input on_bgcolor
off_fgcolor: !input off_fgcolor
off_bgcolor: !input off_bgcolor
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
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
entity_attribute: '{% if attribute|lower == "state" %}{{states(entity)}}{% else %}{{state_attr(entity,attribute)}}{% endif %}'
entity_state: "{% if entity_attribute|lower == state_on %}{{true}}{% else %}{{false}}{% endif %}"
toggle_selectedfg: "{% if entity_state %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% endif %}"
toggle_selectedbg: "{% if entity_state %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% endif %}"
toggle_unselectedfg: "{% if not entity_state %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% endif %}"
toggle_unselectedbg: "{% if not entity_state %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% endif %}"
text: "{% if entity_state %}{{text_on}}{% else %}{{text_off}}{% endif %}"
button_trigger: "ON"
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- endif -%}
{%- endfor -%}
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
hasppage: !input hasppage
haspbutton: !input haspbutton
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
buttonjsonpayload: '{"event_type":"button_short_press","event":"{{haspobject}}","value":"ON"}'
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 entity
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{jsontopic}}"
payload: "{{buttonjsonpayload}}"
- 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:
#########################################################################
# Apply text and style when "RUN ACTIONS" is pressed by the user
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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={{toggle_selectedfg}}",
"{{haspobject}}.bco={{toggle_selectedbg}}",
"{{haspobject}}.pco2={{toggle_unselectedfg}}",
"{{haspobject}}.bco2={{toggle_unselectedbg}}",
"{{haspobject}}.txt=\"{{text}}\""
]
#########################################################################
# 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) }}'
sequence:
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"
payload: >-
[
"{{haspobject}}.pco={{toggle_selectedfg}}",
"{{haspobject}}.bco={{toggle_selectedbg}}",
"{{haspobject}}.pco2={{toggle_unselectedfg}}",
"{{haspobject}}.bco2={{toggle_unselectedbg}}",
"{{haspobject}}.txt=\"{{text}}\""
]
#########################################################################
# Catch triggers fired by incoming MQTT messages
- conditions:
- condition: template
value_template: '{{ trigger.platform == "mqtt" }}'
sequence:
- choose:
#########################################################################
# Catch incoming JSON messages
- conditions:
- condition: template
value_template: "{{ (trigger.topic == jsontopic) and trigger.payload_json is defined }}"
sequence:
- choose:
#########################################################################
# Catch button, toggle entity OFF if currently ON
- conditions:
- condition: template
value_template: "{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == haspobject) and (trigger.payload_json.value == button_trigger) and (entity_state)}}"
sequence: !input action_off
#########################################################################
# Catch button, toggle entity ON if currently OFF
- conditions:
- condition: template
value_template: "{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == haspobject) and (trigger.payload_json.value == button_trigger)}}"
sequence: !input action_on
#########################################################################
# Theme: Apply selected foreground color when it changes
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedfgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.pco"
payload: "{{toggle_selectedfg}}"
#########################################################################
# Theme: Apply selected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedbgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco"
payload: "{{toggle_selectedbg}}"
#########################################################################
# Theme: Apply unselected foreground color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedfgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.pco2"
payload: "{{toggle_unselectedfg}}"
#########################################################################
# Theme: Apply unselected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedbgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{toggle_unselectedbg}}"

View File

@ -0,0 +1,200 @@
blueprint:
name: "HASP p[8].b[9] The slider button on page 8 displays a volume control"
description: |
# Description
The slider button on page 8 displays a volume control
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Volume_Control_page8.png)
## HASP Page and Button reference
<details>
This automation is designed to work with the silder found on page 8:
| Page 8 |
|--------|
| ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Volume_Control_page8.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
volumeentity:
name: "Media Player to control"
description: "Select a media player to control volume"
selector:
entity:
domain: media_player
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
volumeentity: !input volumeentity
volumeobject: "p[8].b[9]"
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" }}'
volumecommandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ volumeobject }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
volume: '{% if state_attr(volumeentity, "volume_level")|lower == "none" %}0{% else %}{{(state_attr(volumeentity, "volume_level")*255)|int}}{% endif %}'
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- endif -%}
{%- endfor -%}
# jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
volumetopic: '{{ "hasp/" ~ haspname ~ "/state/p[8].b[9].val" }}'
unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
trigger:
- platform: state
entity_id: !input volumeentity
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{volumetopic}}"
- 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 HASP Connect
# Apply text and style
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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: >-
["{{volumeobject}}.pco={{unselectedfg}}",
"{{volumeobject}}.bco={{unselectedbg}}",
"{{volumeobject}}.val={{volume}}"]
#########################################################################
# Update display if our entity has changed state
- conditions: # volume has changed value, on/off state has also changed, and we're currently on the selected page
- condition: template
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == volumeentity) }}'
sequence:
- service: mqtt.publish
data:
topic: "{{volumecommandtopic}}.val"
payload: "{{volume}}"
#########################################################################
# Handle MQTT message triggers
- conditions:
- condition: template
value_template: '{{ trigger.platform == "mqtt" }}'
sequence:
- choose:
#########################################################################
# Catch incoming volume slider change message
- conditions:
- condition: template
value_template: "{{ trigger.topic == volumetopic }}"
sequence:
- service: media_player.volume_set
entity_id: !input volumeentity
data:
volume_level: "{{ (trigger.payload | int) / 255 }}"
#########################################################################
# Theme: Apply unselected foreground color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedfgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{volumecommandtopic}}.pco"
payload: "{{trigger.payload}}"
#########################################################################
# Theme: Apply unselected background color on change
- conditions:
- condition: template
value_template: "{{ trigger.topic == unselectedbgtopic }}"
sequence:
- service: mqtt.publish
data:
topic: "{{volumecommandtopic}}.bco"
payload: "{{trigger.payload}}"

View File

@ -0,0 +1,360 @@
blueprint:
name: "HASP p[x].b[y] displays the current weather condition"
description: |
# Description
A HASP button displays the current weather condition
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Weather_Condition.png)
## HASP Page and Button Reference
The images below show each available HASP 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/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASP Font Reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASP 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/aderusha/HASwitchPlate/blob/master/Documentation/Images/hasp-fontawesome5.html)
### Font examples
![HASP Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_0-3.png) ![HASP Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_4-7.png) ![HASP Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_8-10.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Weather_Condition.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11) for the weather condition. Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-15) for the weather condition. Refer to the HASP 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 weather condition"
selector:
entity:
domain: weather
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASP Font Reference above."
default: "8 - Noto Sans 64"
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"
description: "Enable line-wrapping text if too long to fit in the button."
default: false
selector:
boolean:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
weather_provider: !input weather_provider
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
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}'
jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
text: '{{states(weather_provider)|replace("windy-variant","windy")|replace("clear-night","clear night")|replace("partlycloudy","partly cloudy")|replace("lightning-rainy","lightning & rain")|replace("snowy-rainy","snow & rain")|title}}'
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- 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:
- choose:
#########################################################################
# RUN ACTIONS or Home Assistant Startup or HASP Connect
# Display weather condition and apply text style
- conditions:
- condition: template
value_template: >-
{{-
(trigger is not defined)
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 text if our weather provider changed state
- conditions:
- condition: template
value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == weather_provider) and (trigger.from_state.state != trigger.to_state.state) }}'
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.txt"
payload: '\"{{text}}\"'
#########################################################################
# Handle MQTT message triggers
- conditions:
- condition: template
value_template: '{{ trigger.platform == "mqtt" }}'
sequence:
- choose:
#########################################################################
# Theme: Apply selected foreground color when it changes.
# If the page is currently active, delay a moment before applying the overlay
# so it will fire after any other theme elements being applied.
- conditions:
- condition: template
value_template: "{{ trigger.topic == selectedfgtopic }}"
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 }}"
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 }}"
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 }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -39,6 +39,7 @@ blueprint:
min: 1
max: 3
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-7) for the temperature. Refer to the object map in the HASP documentation."
@ -48,6 +49,7 @@ blueprint:
min: 4
max: 7
mode: slider
unit_of_measurement: button
weather_provider:
name: "Weather provider"
description: "Select the weather provider to obtain the temperature"
@ -125,7 +127,15 @@ variables:
replace("snowy-rainy","snow & rain") |
title
-}}
font: '{%set weatherlength=states(weather_provider)|length %}{% if weatherlength < 7 -%}8{% elif weatherlength < 12 %}7{% else %}6{%- endif %}'
font: >-
{%- set weatherlength = text | length -%}
{%- if weatherlength < 7 -%}
8
{%- elif weatherlength < 12 -%}
7
{%- else -%}
6
{%- endif -%}
ypos: "{{(haspbutton|int - 4) * 67 + 2}}"
xpos: 0
iconwidth: 65
@ -226,6 +236,8 @@ trigger:
entity_id: !input weather_provider
- platform: homeassistant
event: start
- platform: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
- platform: mqtt
topic: "{{jsontopic}}"
- platform: mqtt
@ -252,11 +264,15 @@ action:
{{-
(trigger is not defined)
or
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
or
((trigger.platform == 'mqtt') and (trigger.topic == jsontopic) and (trigger.payload_json.event == 'online'))
((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
-}}
sequence:
- service: mqtt.publish
data:
topic: "debug"
payload: "weather condition text: {{text}} states(weather_provider): {{states(weather_provider)}}"
- service: mqtt.publish
data:
topic: "{{jsoncommandtopic}}"

View File

@ -0,0 +1,394 @@
blueprint:
name: "HASP p[x].b[y] displays the weather forecast"
description: |
## Description
A HASP button displays an attribute of a selected weather forecast. You can use this to display tomorrow's condition, or tonight's low temp.
Available forecast conditions will vary by weather provider, check your selected provider's state under `Developer Tools` > `States` to get
a sense of what your selected provider has to offer.
![Preview](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/hasp_Display_Weather_Forecast.png)
### HASP Page and Button reference
<details>
| Page 0 | Pages 1-3 | Pages 4-5 |
|--------|-----------|-----------|
| ![Page 0](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
## HASP Font reference
<details>
The Nextion display supports monospaced and proportional fonts. For monospace fonts, the HASP project includes [Consolas](https://docs.microsoft.com/en-us/typography/font-list/consolas) in 4 sizes and [Webdings](https://en.wikipedia.org/wiki/Webdings#Character_set) in 1 size.
| Number | Font | Characters per line | Lines per button |
|--------|-------------------|---------------------|------------------|
| 0 | Consolas 24 point | 20 characters | 2 lines |
| 1 | Consolas 32 point | 15 characters | 2 lines |
| 2 | Consolas 48 point | 10 characters | 1 lines |
| 3 | Consolas 80 point | 6 characters | 1 lines |
| 4 | Webdings 56 point | 8 characters | 1 lines |
The HASP also includes [Google's "Noto Sans"](https://github.com/googlefonts/noto-fonts) proportional font in 5 sizes.
| Number | Font |
|--------|----------------------------|
| 5 | Noto Sans Regular 24 point |
| 6 | Noto Sans Regular 32 point |
| 7 | Noto Sans Regular 48 point |
| 8 | Noto Sans Regular 64 point |
| 9 | Noto Sans Regular 80 point |
| 10 | Noto Sans Bold 80 point |
### Font examples
![HASP Fonts 0-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_0-3.png) ![HASP Fonts 4-7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_4-7.png) ![HASP Fonts 8-10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_Fonts_8-10.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Display_Weather_Forecast.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11) for the forecast. Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button (4-15) for the forecast. Refer to the HASP 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_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'
default: 0
selector:
number:
min: 0
max: 10
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.'
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:
selector:
text:
font_select:
name: "Font"
description: "Select the font for the displayed text. Refer to the HASP Font Reference above."
default: "8 - Noto Sans 64"
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:
title_case:
name: "Title Case"
description: "Apply The Title Case Filter To Capitalize The First Character Of Each Word In The Result"
default: true
selector:
boolean:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
weather_provider: !input weather_provider
forecast_index: !input forecast_index
forecast_attribute: !input forecast_attribute
prefix: !input prefix
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
title_case: !input title_case
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].get(forecast_attribute) | title }}
{%- else -%}
{{ state_attr(weather_provider, "forecast")[forecast_index|int].get(forecast_attribute) }}
{%- endif -%}
isbr: "{% if wrap == true %}1{% else %}0{% endif %}"
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: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
selectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedfg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
unselectedbg: >-
{%- set color = namespace() -%}
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
{%- set color.source=entity -%}
{{ break }}
{%- endif -%}
{%- endfor -%}
{%- set brightness = state_attr(color.source, "brightness")|int / 255 -%}
{%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int -%}
{%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int -%}
{%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int -%}
{{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- 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:
- 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 == '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 }}"
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 }}"
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 }}"
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 }}"
sequence:
- service: mqtt.publish
data:
topic: "{{commandtopic}}.bco2"
payload: "{{trigger.payload}}"

View File

@ -0,0 +1,111 @@
blueprint:
name: "HASP p[x].b[y] performs an action when pressed"
description: |
# Description
A button on the HASP will perform an action when pressed. Can be combined on a button with another blueprint which displays text.
### HASP Page and Button reference
<details>
| Page 0 | Pages 1-3 | Pages 4-5 |
|--------|-----------|-----------|
| ![Page 0](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p0_Init_Screen.png) | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p1-p3_4buttons.png) | ![Pages 4-5](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p4-p5_3sliders.png) |
| Page 6 | Page 7 | Page 8 |
|--------|--------|--------|
| ![Page 6](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p6_8buttons.png) | ![Page 7](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p7_12buttons.png) | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p8_5buttons+1slider.png) |
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
| ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p9_9buttons.png) | ![Page 10](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p10_5buttons.png) | ![Page 11](https://raw.githubusercontent.com/HASwitchPlate/Blueprints/main/images/NextionUI_p11_1button+1slider.png)
</details>
source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Perform_Action.yaml"
domain: automation
input:
haspdevice:
name: "HASP Device"
description: "Select the HASP device"
selector:
device:
integration: mqtt
manufacturer: "HASwitchPlate"
model: "HASPone v1.0.0"
hasppage:
name: "HASP Page"
description: "Select the HASP page (1-11) for this automation. Refer to the HASP Page and Button reference above."
default: 1
selector:
number:
min: 1
max: 11
mode: slider
unit_of_measurement: page
haspbutton:
name: "HASP Button"
description: "Select the HASP button for this automation. Refer to the HASP Page and Button reference above."
default: 4
selector:
number:
min: 4
max: 15
mode: slider
unit_of_measurement: button
selected_action:
name: "Action to perform"
description: "Select an action to be performed when this button is pressed."
default:
selector:
action:
mode: parallel
max_exceeded: silent
variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
hasppage: !input hasppage
haspbutton: !input haspbutton
trigger_variables:
haspdevice: !input haspdevice
haspname: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\.") -%}
{{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
{{ break }}
{%- endif -%}
{%- endfor -%}
haspsensor: >-
{%- for entity in device_entities(haspdevice) -%}
{%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
{{ entity }}
{{ break }}
{%- endif -%}
{%- endfor -%}
jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
hasppage: !input hasppage
haspbutton: !input haspbutton
haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}'
buttonjsonpayload: '{"event_type":"button_short_press","event":"{{haspobject}}","value":"ON"}'
trigger:
- platform: mqtt
topic: "{{jsontopic}}"
payload: "{{buttonjsonpayload}}"
condition:
- condition: template
value_template: "{{ is_state(haspsensor, 'ON') }}"
action: !input selected_action

29
LICENSE
View File

@ -1,21 +1,18 @@
MIT License
Copyright (c) 2021 HASwitchPlate
Copyright (c) 2021 Allen Derusha allen@derusha.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this hardware,
software, and associated documentation files (the "Product"), to deal in the Product without
restriction, including without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Product, and to permit persons to whom the
Product is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Product.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE PRODUCT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE PRODUCT OR THE USE OR OTHER DEALINGS IN THE PRODUCT.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,18 +0,0 @@
{
"d1_mini": {
"version": "0.41",
"firmware": "http://haswitchplate.com/update/HASwitchPlate.ino.d1_mini.bin"
},
"NX3224T024_011R": {
"version": 3,
"firmware": "http://haswitchplate.com/update/HASwitchPlate.tft"
},
"NX3224K024_011R": {
"version": 3,
"firmware": "http://haswitchplate.com/update/HASwitchPlate-Enhanced.tft"
},
"TJC3224T024_011R": {
"version": 3,
"firmware": "http://haswitchplate.com/update/HASwitchPlate-TJC.tft"
}
}

View File

@ -1,18 +1,18 @@
{
"d1_mini": {
"version": "0.41",
"firmware": "https://raw.githubusercontent.com/aderusha/HASwitchPlate/master/Arduino_Sketch/HASwitchPlate.ino.d1_mini.bin"
"version": "1.00",
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Arduino_Sketch/HASwitchPlate.ino.d1_mini.bin"
},
"NX3224T024_011R": {
"version": 3,
"firmware": "https://raw.githubusercontent.com/aderusha/HASwitchPlate/master/Nextion_HMI/HASwitchPlate.tft"
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate.tft"
},
"NX3224K024_011R": {
"version": 3,
"firmware": "https://raw.githubusercontent.com/aderusha/HASwitchPlate/master/Nextion_HMI/HASwitchPlate-Enhanced.tft"
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate-Enhanced.tft"
},
"TJC3224T024_011R": {
"version": 3,
"firmware": "https://raw.githubusercontent.com/aderusha/HASwitchPlate/master/Nextion_HMI/HASwitchPlate-TJC.tft"
"firmware": "https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/Nextion_HMI/HASwitchPlate-TJC.tft"
}
}