diff --git a/Home_Assistant/blueprints/hasp_Activate_Page.yaml b/Home_Assistant/blueprints/hasp_Activate_Page.yaml
new file mode 100644
index 0000000..c4f018e
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Activate_Page.yaml
@@ -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.
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ 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}}"
+
diff --git a/Home_Assistant/blueprints/hasp_Core_Functionality.yaml b/Home_Assistant/blueprints/hasp_Core_Functionality.yaml
index b799a82..104106a 100644
--- a/Home_Assistant/blueprints/hasp_Core_Functionality.yaml
+++ b/Home_Assistant/blueprints/hasp_Core_Functionality.yaml
@@ -24,7 +24,7 @@ blueprint:
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
- |  |  | 
+ |  |  | 
@@ -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:
diff --git a/Home_Assistant/blueprints/hasp_Create_Device_Triggers.yaml b/Home_Assistant/blueprints/hasp_Create_Device_Triggers.yaml
index 09f5f38..c355661 100644
--- a/Home_Assistant/blueprints/hasp_Create_Device_Triggers.yaml
+++ b/Home_Assistant/blueprints/hasp_Create_Device_Triggers.yaml
@@ -24,7 +24,7 @@ blueprint:
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
- |  |  | 
+ |  |  | 
@@ -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
diff --git a/Home_Assistant/blueprints/hasp_Display_Alarm_Control_page7.yaml b/Home_Assistant/blueprints/hasp_Display_Alarm_Control_page7.yaml
index 0df7e48..a236b71 100644
--- a/Home_Assistant/blueprints/hasp_Display_Alarm_Control_page7.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Alarm_Control_page7.yaml
@@ -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:
diff --git a/Home_Assistant/blueprints/hasp_Display_Calendar_with_Icon.yaml b/Home_Assistant/blueprints/hasp_Display_Calendar_with_Icon.yaml
index 03a715b..1224213 100644
--- a/Home_Assistant/blueprints/hasp_Display_Calendar_with_Icon.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Calendar_with_Icon.yaml
@@ -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
diff --git a/Home_Assistant/blueprints/hasp_Display_Clock.yaml b/Home_Assistant/blueprints/hasp_Display_Clock.yaml
index 5cfb904..3e19594 100644
--- a/Home_Assistant/blueprints/hasp_Display_Clock.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Clock.yaml
@@ -24,7 +24,7 @@ blueprint:
| Page 9 | Page 10 | Page 11 |
|--------|---------|---------|
- |  |  | 
+ |  |  | 
@@ -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
diff --git a/Home_Assistant/blueprints/hasp_Display_Clock_with_Icon.yaml b/Home_Assistant/blueprints/hasp_Display_Clock_with_Icon.yaml
index b1b4dba..337ae8b 100644
--- a/Home_Assistant/blueprints/hasp_Display_Clock_with_Icon.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Clock_with_Icon.yaml
@@ -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
diff --git a/Home_Assistant/blueprints/hasp_Display_Dimmer_with_Icon.yaml b/Home_Assistant/blueprints/hasp_Display_Dimmer_with_Icon.yaml
index cbc36b2..1ba669f 100644
--- a/Home_Assistant/blueprints/hasp_Display_Dimmer_with_Icon.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Dimmer_with_Icon.yaml
@@ -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
diff --git a/Home_Assistant/blueprints/hasp_Display_Entity_State_or_Attribute.yaml b/Home_Assistant/blueprints/hasp_Display_Entity_State_or_Attribute.yaml
new file mode 100644
index 0000000..8b9a463
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Entity_State_or_Attribute.yaml
@@ -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
+
+ 
+
+ ## Examples
+
+
+
+ ### 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`
+
+
+
+ ## HASP Page and Button Reference
+
+ The images below show each available HASP page along with the layout of available button objects.
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ ## HASP Font Reference
+
+
+
+ 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
+
+   
+
+
+
+ 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}}"
+
diff --git a/Home_Assistant/blueprints/hasp_Display_Media_Control_page8.yaml b/Home_Assistant/blueprints/hasp_Display_Media_Control_page8.yaml
new file mode 100644
index 0000000..26eafe1
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Media_Control_page8.yaml
@@ -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
+
+ 
+
+ ## HASP Page and Button reference
+
+
+
+ This automation is designed to work with the media controls found on page 8:
+
+ | Page 8 |
+ |--------|
+ |  |
+
+
+
+
+ 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}}"]
diff --git a/Home_Assistant/blueprints/hasp_Display_Temperature_with_Icon_and_Colors.yaml b/Home_Assistant/blueprints/hasp_Display_Temperature_with_Icon_and_Colors.yaml
index 773167f..3c187bc 100644
--- a/Home_Assistant/blueprints/hasp_Display_Temperature_with_Icon_and_Colors.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Temperature_with_Icon_and_Colors.yaml
@@ -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
diff --git a/Home_Assistant/blueprints/hasp_Display_Template.yaml b/Home_Assistant/blueprints/hasp_Display_Template.yaml
new file mode 100644
index 0000000..ea7ab07
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Template.yaml
@@ -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.
+
+ 
+
+ ## Examples
+
+
+
+ ### 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`
+
+
+
+ ## HASP Page and Button Reference
+
+ The images below show each available HASP page along with the layout of available button objects.
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ ## HASP Font Reference
+
+
+
+ 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
+
+   
+
+
+
+ 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}}"
diff --git a/Home_Assistant/blueprints/hasp_Display_Text.yaml b/Home_Assistant/blueprints/hasp_Display_Text.yaml
new file mode 100644
index 0000000..2d36458
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Text.yaml
@@ -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.
+
+ 
+
+ ## HASP Page and Button Reference
+
+ The images below show each available HASP page along with the layout of available button objects.
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ ## HASP Font Reference
+
+
+
+ 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
+
+   
+
+
+
+ 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}}"
+
diff --git a/Home_Assistant/blueprints/hasp_Display_Toggle.yaml b/Home_Assistant/blueprints/hasp_Display_Toggle.yaml
new file mode 100644
index 0000000..1ee58b5
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Toggle.yaml
@@ -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.
+
+ 
+
+ ## Examples
+
+
+
+ ### 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'
+
+
+
+ ## HASP Page and Button Reference
+
+ The images below show each available HASP page along with the layout of available button objects.
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ ## HASP Font Reference
+
+
+
+ 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
+
+   
+
+
+
+ ## Nextion color codes
+
+
+
+ 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 |
+
+
+
+ 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}}"
diff --git a/Home_Assistant/blueprints/hasp_Display_Volume_Control_page8.yaml b/Home_Assistant/blueprints/hasp_Display_Volume_Control_page8.yaml
new file mode 100644
index 0000000..7c00e85
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Volume_Control_page8.yaml
@@ -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
+
+ 
+
+ ## HASP Page and Button reference
+
+
+
+ This automation is designed to work with the silder found on page 8:
+
+ | Page 8 |
+ |--------|
+ |  |
+
+
+
+
+ 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}}"
diff --git a/Home_Assistant/blueprints/hasp_Display_Weather_Condition.yaml b/Home_Assistant/blueprints/hasp_Display_Weather_Condition.yaml
new file mode 100644
index 0000000..9cc394a
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Weather_Condition.yaml
@@ -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
+
+ 
+
+ ## HASP Page and Button Reference
+
+ The images below show each available HASP page along with the layout of available button objects.
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ ## HASP Font Reference
+
+
+
+ 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
+
+   
+
+
+
+ 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}}"
diff --git a/Home_Assistant/blueprints/hasp_Display_Weather_Condition_with_Icon.yaml b/Home_Assistant/blueprints/hasp_Display_Weather_Condition_with_Icon.yaml
index 08a9648..5f64252 100644
--- a/Home_Assistant/blueprints/hasp_Display_Weather_Condition_with_Icon.yaml
+++ b/Home_Assistant/blueprints/hasp_Display_Weather_Condition_with_Icon.yaml
@@ -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}}"
diff --git a/Home_Assistant/blueprints/hasp_Display_Weather_Forecast.yaml b/Home_Assistant/blueprints/hasp_Display_Weather_Forecast.yaml
new file mode 100644
index 0000000..c11a6a6
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Display_Weather_Forecast.yaml
@@ -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.
+
+ 
+
+ ### HASP Page and Button reference
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ ## HASP Font reference
+
+
+
+ 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
+
+   
+
+
+ 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}}"
diff --git a/Home_Assistant/blueprints/hasp_Perform_Action.yaml b/Home_Assistant/blueprints/hasp_Perform_Action.yaml
new file mode 100644
index 0000000..bb7bc4f
--- /dev/null
+++ b/Home_Assistant/blueprints/hasp_Perform_Action.yaml
@@ -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
+
+
+
+ | Page 0 | Pages 1-3 | Pages 4-5 |
+ |--------|-----------|-----------|
+ |  |  |  |
+
+ | Page 6 | Page 7 | Page 8 |
+ |--------|--------|--------|
+ |  |  |  |
+
+ | Page 9 | Page 10 | Page 11 |
+ |--------|---------|---------|
+ |  |  | 
+
+
+
+ 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
diff --git a/LICENSE b/LICENSE
index 3beac51..eacc545 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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.
\ No newline at end of file
diff --git a/Nextion_HMI/HASwitchPlate-Enhanced.tft b/Nextion_HMI/HASwitchPlate-Enhanced.tft
index d40b6c2..00f9c47 100644
Binary files a/Nextion_HMI/HASwitchPlate-Enhanced.tft and b/Nextion_HMI/HASwitchPlate-Enhanced.tft differ
diff --git a/Nextion_HMI/HASwitchPlate-Inverted.tft b/Nextion_HMI/HASwitchPlate-Inverted.tft
index 3f0395c..225f0fe 100644
Binary files a/Nextion_HMI/HASwitchPlate-Inverted.tft and b/Nextion_HMI/HASwitchPlate-Inverted.tft differ
diff --git a/Nextion_HMI/HASwitchPlate-TJC.HMI b/Nextion_HMI/HASwitchPlate-TJC.HMI
index 2867608..a000fca 100644
Binary files a/Nextion_HMI/HASwitchPlate-TJC.HMI and b/Nextion_HMI/HASwitchPlate-TJC.HMI differ
diff --git a/Nextion_HMI/HASwitchPlate-TJC.tft b/Nextion_HMI/HASwitchPlate-TJC.tft
index c5af768..32f3ba5 100644
Binary files a/Nextion_HMI/HASwitchPlate-TJC.tft and b/Nextion_HMI/HASwitchPlate-TJC.tft differ
diff --git a/Nextion_HMI/HASwitchPlate.HMI b/Nextion_HMI/HASwitchPlate.HMI
index 516c200..7091a17 100644
Binary files a/Nextion_HMI/HASwitchPlate.HMI and b/Nextion_HMI/HASwitchPlate.HMI differ
diff --git a/Nextion_HMI/HASwitchPlate.tft b/Nextion_HMI/HASwitchPlate.tft
index ccc100c..3108873 100644
Binary files a/Nextion_HMI/HASwitchPlate.tft and b/Nextion_HMI/HASwitchPlate.tft differ
diff --git a/images/hasp_Display_Text_and_Activate_Page.png b/images/hasp_Display_Text_and_Activate_Page.png
deleted file mode 100644
index 954d47f..0000000
Binary files a/images/hasp_Display_Text_and_Activate_Page.png and /dev/null differ
diff --git a/images/hasp_Display_Text_and_Trigger_Scene.png b/images/hasp_Display_Text_and_Trigger_Scene.png
deleted file mode 100644
index a1bd732..0000000
Binary files a/images/hasp_Display_Text_and_Trigger_Scene.png and /dev/null differ
diff --git a/update/version-insecure.json b/update/version-insecure.json
deleted file mode 100644
index 1438e4c..0000000
--- a/update/version-insecure.json
+++ /dev/null
@@ -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"
- }
-}
\ No newline at end of file
diff --git a/update/version.json b/update/version.json
index b92c1cb..37fd258 100644
--- a/update/version.json
+++ b/update/version.json
@@ -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"
}
}
\ No newline at end of file