diff --git a/Home_Assistant/blueprints/hasp_Activate_Page.yaml b/Home_Assistant/blueprints/hasp_Activate_Page.yaml index bd061fe..c2de65d 100644 --- a/Home_Assistant/blueprints/hasp_Activate_Page.yaml +++ b/Home_Assistant/blueprints/hasp_Activate_Page.yaml @@ -26,7 +26,6 @@ blueprint: - source_url: "https://github.com/HASwitchPlate/Blueprints/blob/main/hasp_Activate_Page.yaml" domain: automation input: haspdevice: diff --git a/Home_Assistant/blueprints/hasp_Dim_Screen_on_Idle.yaml b/Home_Assistant/blueprints/hasp_Dim_Screen_on_Idle.yaml new file mode 100755 index 0000000..f4d00f5 --- /dev/null +++ b/Home_Assistant/blueprints/hasp_Dim_Screen_on_Idle.yaml @@ -0,0 +1,106 @@ +blueprint: + name: "HASP dim the display screen after a specified period of inactivity" + description: | + + # Description + + Dim the screen backlight after a specified period of inactivity. + + domain: automation + input: + haspdevice: + name: "HASP Device" + description: "Select the HASP device" + selector: + device: + integration: mqtt + manufacturer: "HASwitchPlate" + model: "HASPone v1.0.0" + darkvalue: + name: "Brightness to set on idle" + description: "Select the brightness value to become when idle" + default: 20 + selector: + number: + min: 1 + max: 100 + mode: slider + unit_of_measurement: percent + idletime: + name: "Idle Time" + description: "Idle time in seconds" + default: 30 + selector: + number: + min: 5 + max: 900 + step: 5 + mode: slider + unit_of_measurement: seconds + brightvalue: + name: "Brightness to set on activity" + description: "Select the brightness value to become when activity is sensed." + default: 60 + selector: + number: + min: 1 + max: 100 + mode: slider + unit_of_measurement: percent + +mode: restart +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 -%} + darkvalue: !input darkvalue + brightvalue: !input brightvalue + idletime: !input idletime + lightcommandtopic: '{{ "hasp/" ~ haspname ~ "/brightness/set" }}' + +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" }}' + +trigger: + - platform: mqtt + topic: "{{jsontopic}}" + +condition: + - condition: template + value_template: "{{ is_state(haspsensor, 'ON') }}" + - condition: template + value_template: "{{ ((trigger.payload_json.event_type is defined) and (trigger.payload_json.event_type == 'button_short_press')) }}" + +action: + - service: mqtt.publish + data: + topic: "{{lightcommandtopic}}" + payload: "{{brightvalue}}" + - delay: + seconds: "{{idletime|int}}" + - service: mqtt.publish + data: + topic: "{{lightcommandtopic}}" + payload: "{{darkvalue}}" diff --git a/Home_Assistant/blueprints/hasp_Display_Heatpump_Control_page6.yaml b/Home_Assistant/blueprints/hasp_Display_Heatpump_Control_page6.yaml new file mode 100755 index 0000000..ff61a22 --- /dev/null +++ b/Home_Assistant/blueprints/hasp_Display_Heatpump_Control_page6.yaml @@ -0,0 +1,543 @@ +blueprint: + name: "HASP p[6].b[all] Page 6 displays Heatpump controls" + description: | + + # Description + + Page 6 controls a Heatpump. Display target and mode. Change temperature and mode + + ![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Display_Heatpump_Control_page9.png) + + ## HASP Page and Button reference + +
+ + This automation is designed to work with the heat pump controls found on page 6: + + | page 6 | + |--------| + | ![page 6](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p6_8buttons.png) | + + +
+ + ## 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 | + +
+ + domain: automation + input: + haspdevice: + name: "HASP Device" + description: "Select the HASP device" + selector: + device: + integration: mqtt + manufacturer: "HASwitchPlate" + model: "HASPone v1.0.0" + heatpump: + name: "Heatpump to control" + description: "Select a heatpump to control" + selector: + entity: + domain: climate + suffix_select: + name: "Temperature display suffix" + description: "Suffix for temperature display." + default: "°" + selector: + select: + options: + - "No suffix" + - "°" + - "°F" + - "°C" + roundtemp: + name: "Round sensor values to nearest integer" + description: "Enable this if you don't want decimal places involved" + default: true + selector: + boolean: + on_fgcolor: + name: '"active" foreground color' + description: 'Text foreground color for the current operating mode, 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: '"active" background color' + description: 'Text background color for the current operating mode, in Nextion RGB565 format. -1 = Current theme selected background color.' + default: -1 + selector: + number: + min: -1 + max: 65535 + mode: slider + off_fgcolor: + name: '"inactive" foreground color' + description: 'Text foreground color for the modes that are not currently active, in Nextion RGB565 format. -1 = Current theme unselected foreground color.' + default: -1 + selector: + number: + min: -1 + max: 65535 + mode: slider + off_bgcolor: + name: '"inactive" background color' + description: 'Text background color for the modes that are not currently active, in Nextion RGB565 format. -1 = Current theme unselected background color.' + default: -1 + selector: + number: + min: -1 + max: 65535 + mode: slider + +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 -%} + heatpump: !input heatpump + on_fgcolor: !input on_fgcolor + on_bgcolor: !input on_bgcolor + off_fgcolor: !input off_fgcolor + off_bgcolor: !input off_bgcolor + roundtemp: !input roundtemp + #button4attribute: !input button4attribute + #button5attribute: !input button5attribute + 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 }} + + hp_is_heat: "{{is_state(heatpump, 'heat') }}" + hp_is_both: "{{is_state(heatpump, 'heat_cool') }}" + hp_is_cool: "{{is_state(heatpump, 'cool') }}" + hp_is_off: "{{is_state(heatpump, 'off') }}" + + selectedfgh: "{% if hp_is_heat %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + selectedbgh: "{% if hp_is_heat %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + unselectedfgh: "{% if not hp_is_heat %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + unselectedbgh: "{% if not hp_is_heat %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + selectedfgb: "{% if hp_is_both %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + selectedbgb: "{% if hp_is_both %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + unselectedfgb: "{% if not hp_is_both %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + unselectedbgb: "{% if not hp_is_both %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + selectedfgc: "{% if hp_is_cool %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + selectedbgc: "{% if hp_is_cool %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + unselectedfgc: "{% if not hp_is_cool %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + unselectedbgc: "{% if not hp_is_cool %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + selectedfgo: "{% if hp_is_off %}{{unselectedfg}}{% else %}{{selectedfg}}{% endif %}" + selectedbgo: "{% if hp_is_off %}{{unselectedbg}}{% else %}{{selectedbg}}{% endif %}" + unselectedfgo: "{% if not hp_is_off %}{{unselectedfg}}{% else %}{{selectedfg}}{% endif %}" + unselectedbgo: "{% if not hp_is_off %}{{unselectedbg}}{% else %}{{selectedbg}}{% endif %}" + + tgttemp: >- + {%- if roundtemp == true -%} + {{- state_attr(heatpump,'temperature')| round -}} + {%- else -%} + {{- state_attr(heatpump,'temperature') -}} + {%- endif -%} + currtemp: >- + {%- if roundtemp == true -%} + {{- state_attr(heatpump,'current_temperature')| round -}} + {%- else -%} + {{- state_attr(heatpump,'current_temperature') -}} + {%- endif -%} + + temp_inc: "{{state_attr(heatpump,'temperature') + 1.0}}" + temp_dec: "{{state_attr(heatpump,'temperature') - 1.0}}" + + suffix_select: !input suffix_select + suffixstring: "{% if suffix_select != 'No suffix' %}{{ suffix_select }}{% endif %}" + button4text: ' ' # Thermometer 3/4 + button4font: 7 + button5text: '' # Fire + button5font: 7 + button6text: "{{tgttemp}}{{suffixstring}}" + button6font: 8 + button7text: '/' # both + button7font: 7 + button8text: ' ' # Thermometer 1/4 + button8font: 7 + button9text: '' # Cool + button9font: 7 + button10text: '' # Power symbol + button10font: 7 + button11text: "{{currtemp}}{{suffixstring}}" + button11font: 6 +# button12text: >- +# {%- if hp_is_both -%} +# / +# {%- else -%} +# {{ states(heatpump) }} +# {%- endif -%} +# button12font: 8 + + +trigger_variables: + haspdevice: !input haspdevice +# heatpump: !input heatpump + 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 -%} + toggle_hp_state: "{%- if hp_is_off -%}heat_cool{%- else -%}off{%- endif -%}" + 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 heatpump + - 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[6].b[4].pco={{selectedfg}}","p[6].b[4].bco={{selectedbg}}","p[6].b[4].pco2={{unselectedfg}}","p[6].b[4].bco2={{unselectedbg}}","p[6].b[4].font={{button4font}}","p[6].b[4].txt=\"{{button4text}}\"", + "p[6].b[5].pco={{selectedfgh}}","p[6].b[5].bco={{selectedbgh}}","p[6].b[5].pco2={{unselectedfgh}}","p[6].b[5].bco2={{unselectedbgh}}","p[6].b[5].font={{button5font}}","p[6].b[5].txt=\"{{button5text}}\"", + "p[6].b[6].pco={{selectedfg}}","p[6].b[6].bco={{selectedbg}}","p[6].b[6].pco2={{unselectedfg}}","p[6].b[6].bco2={{unselectedbg}}","p[6].b[6].font={{button6font}}","p[6].b[6].txt=\"{{button6text}}\"", + "p[6].b[7].pco={{selectedfgb}}","p[6].b[7].bco={{selectedbgb}}","p[6].b[7].pco2={{unselectedfgb}}","p[6].b[7].bco2={{unselectedbgb}}","p[6].b[7].font={{button7font}}","p[6].b[7].txt=\"{{button7text}}\"", + "p[6].b[8].pco={{selectedfg}}","p[6].b[8].bco={{selectedbg}}","p[6].b[8].pco2={{unselectedfg}}","p[6].b[8].bco2={{unselectedbg}}","p[6].b[8].font={{button8font}}","p[6].b[8].txt=\"{{button8text}}\"", + "p[6].b[9].pco={{selectedfgc}}","p[6].b[9].bco={{selectedbgc}}","p[6].b[9].pco2={{unselectedfgc}}","p[6].b[9].bco2={{unselectedbgc}}","p[6].b[9].font={{button9font}}","p[6].b[9].txt=\"{{button9text}}\"", + "p[6].b[10].pco={{selectedfgo}}","p[6].b[10].bco={{selectedbgo}}","p[6].b[10].pco2={{unselectedfgo}}","p[6].b[10].bco2={{unselectedbgo}}","p[6].b[10].font={{button10font}}","p[6].b[10].txt=\"{{button10text}}\"", + "p[6].b[11].pco={{unselectedfg}}","p[6].b[11].bco={{unselectedbg}}","p[6].b[11].pco2={{selectedfg}}","p[6].b[11].bco2={{selectedbg}}","p[6].b[11].font={{button11font}}","p[6].b[11].txt=\"{{button11text}}\""] + + ######################################################################### + # Update volume if it has changed state +# - conditions: # volume has changed value +# - condition: template +# value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == heatpump) 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 == heatpump) }}' + sequence: + - service: mqtt.publish + data: + topic: "{{jsoncommandtopic}}" + payload: >- + ["p[6].b[5].pco={{selectedfgh}}","p[6].b[5].bco={{selectedbgh}}","p[6].b[5].pco2={{unselectedfgh}}","p[6].b[5].bco2={{unselectedbgh}}", + "p[6].b[6].font={{button6font}}","p[6].b[6].txt=\"{{button6text}}\"", + "p[6].b[7].pco={{selectedfgb}}","p[6].b[7].bco={{selectedbgb}}","p[6].b[7].pco2={{unselectedfgb}}","p[6].b[7].bco2={{unselectedbgb}}", + "p[6].b[9].pco={{selectedfgc}}","p[6].b[9].bco={{selectedbgc}}","p[6].b[9].pco2={{unselectedfgc}}","p[6].b[9].bco2={{unselectedbgc}}", + "p[6].b[10].pco={{selectedfgo}}","p[6].b[10].bco={{selectedbgo}}","p[6].b[10].pco2={{unselectedfgo}}","p[6].b[10].bco2={{unselectedbgo}}", + "p[6].b[11].font={{button11font}}","p[6].b[11].txt=\"{{button11text}}\""] + + ######################################################################### + # 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 heatpump +# data: +# volume_level: "{{trigger.payload_json.value/255}}" + ######################################################################### + # Target Up was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[4]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_temperature + entity_id: !input heatpump + data: + temperature: "{{temp_inc}}" + ######################################################################### + # Target Down was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[5]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_temperature + entity_id: !input heatpump + data: + temperature: "{{temp_dec}}" + ######################################################################### + # Target Temperature was Pressed + # p[6].b[6] + ######################################################################### + # Current Temperature was Pressed + # p[6].b[11] + ######################################################################### + # Mode=Heat was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[5]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'heat' + ######################################################################### + # Mode=Both was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[7]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'heat_cool' + ######################################################################### + # Mode=Cool was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[9]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'cool' + ######################################################################### + # Mode=Off was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[10]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'off' + ######################################################################### + # Mode Itself was Pressed, toggle auto/off +# - conditions: +# - condition: template +# value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[6].b[12]") and (trigger.payload_json.value == "ON")}}' +# sequence: +# - service: climate.set_hvac_mode +# entity_id: !input heatpump +# data: +# hvac_mode: "{{toggle_hp_state}}" + + ######################################################################### + # 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[6].b[4].pco={{selectedfg}}", + "p[6].b[5].pco={{selectedfgh}}", + "p[6].b[6].pco={{selectedfg}}", + "p[6].b[7].pco={{selectedfgb}}", + "p[6].b[8].pco={{selectedfg}}", + "p[6].b[9].pco={{selectedfgc}}", + "p[6].b[10].pco={{selectedfgo}}", + "p[6].b[11].pco={{unselectedfg}}"] + ######################################################################### + # Theme: Apply selected background color on change + - conditions: + - condition: template + value_template: "{{ trigger.topic == selectedbgtopic }}" + sequence: + - service: mqtt.publish + data: + topic: "{{jsoncommandtopic}}" + payload: >- + ["p[6].b[4].bco={{selectedbg}}", + "p[6].b[5].bco={{selectedbgh}}", + "p[6].b[6].bco={{selectedbg}}", + "p[6].b[7].bco={{selectedbgb}}", + "p[6].b[8].bco={{selectedbg}}", + "p[6].b[9].bco={{selectedbgc}}", + "p[6].b[10].bco={{selectedbgo}}", + "p[6].b[11].bco={{unselectedbg}}"] + ######################################################################### + # Theme: Apply unselected foreground color on change + - conditions: + - condition: template + value_template: "{{ trigger.topic == unselectedfgtopic }}" + sequence: + - service: mqtt.publish + data: + topic: "{{jsoncommandtopic}}" + payload: >- + ["p[6].b[4].pco2={{unselectedfg}}", + "p[6].b[5].pco2={{unselectedfgh}}", + "p[6].b[6].pco2={{unselectedfg}}", + "p[6].b[7].pco2={{unselectedfgb}}", + "p[6].b[8].pco2={{unselectedfg}}", + "p[6].b[9].pco2={{unselectedfgc}}", + "p[6].b[10].pco2={{unselectedfgo}}", + "p[6].b[11].pco2={{selectedfg}}"] + ######################################################################### + # Theme: Apply unselected background color on change + - conditions: + - condition: template + value_template: "{{ trigger.topic == unselectedbgtopic }}" + sequence: + - service: mqtt.publish + data: + topic: "{{jsoncommandtopic}}" + payload: >- + ["p[6].b[4].bco2={{unselectedbg}}", + "p[6].b[5].bco2={{unselectedbgh}}", + "p[6].b[6].bco2={{unselectedbg}}", + "p[6].b[7].bco2={{unselectedbgb}}", + "p[6].b[8].bco2={{unselectedbg}}", + "p[6].b[9].bco2={{unselectedbgc}}", + "p[6].b[10].bco2={{unselectedbgo}}", + "p[6].b[11].bco2={{selectedbg}}"] diff --git a/Home_Assistant/blueprints/hasp_Display_Heatpump_Control_page9.yaml b/Home_Assistant/blueprints/hasp_Display_Heatpump_Control_page9.yaml new file mode 100755 index 0000000..3a2002a --- /dev/null +++ b/Home_Assistant/blueprints/hasp_Display_Heatpump_Control_page9.yaml @@ -0,0 +1,549 @@ +blueprint: + name: "HASP p[9].b[all] Page 9 displays Heatpump controls" + description: | + + # Description + + Page 9 controls a Heatpump. Display target and mode. Change temperature and mode + + ![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Display_Heatpump_Control_page9.png) + + ## HASP Page and Button reference + +
+ + This automation is designed to work with the heat pump controls found on page 9: + + | Page 9 | + |--------| + | ![Page 9](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextibonUI_p9_9buttons.png) | + + +
+ + ## 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 | + +
+ + domain: automation + input: + haspdevice: + name: "HASP Device" + description: "Select the HASP device" + selector: + device: + integration: mqtt + manufacturer: "HASwitchPlate" + model: "HASPone v1.0.0" + heatpump: + name: "Heatpump to control" + description: "Select a heatpump to control" + selector: + entity: + domain: climate + suffix_select: + name: "Temperature display suffix" + description: "Suffix for temperature display." + default: "°" + selector: + select: + options: + - "No suffix" + - "°" + - "°F" + - "°C" + roundtemp: + name: "Round sensor values to nearest integer" + description: "Enable this if you don't want decimal places involved" + default: true + selector: + boolean: + on_fgcolor: + name: '"active" foreground color' + description: 'Text foreground color for the current operating mode, 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: '"active" background color' + description: 'Text background color for the current operating mode, in Nextion RGB565 format. -1 = Current theme selected background color.' + default: -1 + selector: + number: + min: -1 + max: 65535 + mode: slider + off_fgcolor: + name: '"inactive" foreground color' + description: 'Text foreground color for the modes that are not currently active, in Nextion RGB565 format. -1 = Current theme unselected foreground color.' + default: -1 + selector: + number: + min: -1 + max: 65535 + mode: slider + off_bgcolor: + name: '"inactive" background color' + description: 'Text background color for the modes that are not currently active, in Nextion RGB565 format. -1 = Current theme unselected background color.' + default: -1 + selector: + number: + min: -1 + max: 65535 + mode: slider + +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 -%} + heatpump: !input heatpump + on_fgcolor: !input on_fgcolor + on_bgcolor: !input on_bgcolor + off_fgcolor: !input off_fgcolor + off_bgcolor: !input off_bgcolor + roundtemp: !input roundtemp + #button4attribute: !input button4attribute + #button5attribute: !input button5attribute + 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 }} + + hp_is_heat: "{{is_state(heatpump, 'heat') }}" + hp_is_both: "{{is_state(heatpump, 'heat_cool') }}" + hp_is_cool: "{{is_state(heatpump, 'cool') }}" + hp_is_off: "{{is_state(heatpump, 'off') }}" + + selectedfg7: "{% if hp_is_heat %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + selectedbg7: "{% if hp_is_heat %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + unselectedfg7: "{% if not hp_is_heat %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + unselectedbg7: "{% if not hp_is_heat %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + selectedfg8: "{% if hp_is_both %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + selectedbg8: "{% if hp_is_both %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + unselectedfg8: "{% if not hp_is_both %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + unselectedbg8: "{% if not hp_is_both %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + selectedfg10: "{% if hp_is_cool %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + selectedbg10: "{% if hp_is_cool %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + unselectedfg10: "{% if not hp_is_cool %}{% if on_fgcolor|int >= 0 %}{{on_fgcolor}}{% else %}{{unselectedfg}}{% endif %}{% else %}{% if off_fgcolor|int >= 0 %}{{off_fgcolor}}{% else %}{{selectedfg}}{% endif %}{% endif %}" + unselectedbg10: "{% if not hp_is_cool %}{% if on_bgcolor|int >= 0 %}{{on_bgcolor}}{% else %}{{unselectedbg}}{% endif %}{% else %}{% if off_bgcolor|int >= 0 %}{{off_bgcolor}}{% else %}{{selectedbg}}{% endif %}{% endif %}" + selectedfg11: "{% if hp_is_off %}{{unselectedfg}}{% else %}{{selectedfg}}{% endif %}" + selectedbg11: "{% if hp_is_off %}{{unselectedbg}}{% else %}{{selectedbg}}{% endif %}" + unselectedfg11: "{% if not hp_is_off %}{{unselectedfg}}{% else %}{{selectedfg}}{% endif %}" + unselectedbg11: "{% if not hp_is_off %}{{unselectedbg}}{% else %}{{selectedbg}}{% endif %}" + + tgttemp: >- + {%- if roundtemp == true -%} + {{- state_attr(heatpump,'temperature')| round -}} + {%- else -%} + {{- state_attr(heatpump,'temperature') -}} + {%- endif -%} + currtemp: >- + {%- if roundtemp == true -%} + {{- state_attr(heatpump,'current_temperature')| round -}} + {%- else -%} + {{- state_attr(heatpump,'current_temperature') -}} + {%- endif -%} + + temp_inc: "{{state_attr(heatpump,'temperature') + 1.0}}" + temp_dec: "{{state_attr(heatpump,'temperature') - 1.0}}" + + suffix_select: !input suffix_select + suffixstring: "{% if suffix_select != 'No suffix' %}{{ suffix_select }}{% endif %}" + button4text: '+' # Thermometer 3/4 + button4font: 6 + button5text: '-' # Thermometer 1/4 + button5font: 6 + button6text: "{{tgttemp}}{{suffixstring}}" + button6font: 8 + button7text: '' # Fire + button7font: 6 + button8text: '/' # both + button8font: 6 + button9text: "{{currtemp}}{{suffixstring}}" + button9font: 7 + button10text: '' # Cool + button10font: 6 + button11text: '' # Power symbol + button11font: 6 + button12text: >- + {%- if hp_is_both -%} + / + {%- else -%} + {{ states(heatpump) }} + {%- endif -%} + button12font: 8 + + +trigger_variables: + haspdevice: !input haspdevice +# heatpump: !input heatpump + 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 -%} + toggle_hp_state: "{%- if hp_is_off -%}heat_cool{%- else -%}off{%- endif -%}" + 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 heatpump + - 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[9].b[4].pco={{selectedfg}}","p[9].b[4].bco={{selectedbg}}","p[9].b[4].pco2={{unselectedfg}}","p[9].b[4].bco2={{unselectedbg}}","p[9].b[4].font={{button4font}}","p[9].b[4].txt=\"{{button4text}}\"", + "p[9].b[5].pco={{selectedfg}}","p[9].b[5].bco={{selectedbg}}","p[9].b[5].pco2={{unselectedfg}}","p[9].b[5].bco2={{unselectedbg}}","p[9].b[5].font={{button5font}}","p[9].b[5].txt=\"{{button5text}}\"", + "p[9].b[6].pco={{selectedfg}}","p[9].b[6].bco={{selectedbg}}","p[9].b[6].pco2={{unselectedfg}}","p[9].b[6].bco2={{unselectedbg}}","p[9].b[6].font={{button6font}}","p[9].b[6].txt=\"{{button6text}}\"", + "p[9].b[7].pco={{selectedfg7}}","p[9].b[7].bco={{selectedbg7}}","p[9].b[7].pco2={{unselectedfg7}}","p[9].b[7].bco2={{unselectedbg7}}","p[9].b[7].font={{button7font}}","p[9].b[7].txt=\"{{button7text}}\"", + "p[9].b[8].pco={{selectedfg8}}","p[9].b[8].bco={{selectedbg8}}","p[9].b[8].pco2={{unselectedfg8}}","p[9].b[8].bco2={{unselectedbg8}}","p[9].b[8].font={{button8font}}","p[9].b[8].txt=\"{{button8text}}\"", + "p[9].b[9].pco={{unselectedfg}}","p[9].b[9].bco={{unselectedbg}}","p[9].b[9].pco2={{selectedfg}}","p[9].b[9].bco2={{selectedbg}}","p[9].b[9].font={{button9font}}","p[9].b[9].txt=\"{{button9text}}\"", + "p[9].b[10].pco={{selectedfg10}}","p[9].b[10].bco={{selectedbg10}}","p[9].b[10].pco2={{unselectedfg10}}","p[9].b[10].bco2={{unselectedbg10}}","p[9].b[10].font={{button10font}}","p[9].b[10].txt=\"{{button10text}}\"", + "p[9].b[11].pco={{selectedfg11}}","p[9].b[11].bco={{selectedbg11}}","p[9].b[11].pco2={{unselectedfg11}}","p[9].b[11].bco2={{unselectedbg11}}","p[9].b[11].font={{button11font}}","p[9].b[11].txt=\"{{button11text}}\"", + "p[9].b[12].pco={{selectedfg}}","p[9].b[12].bco={{selectedbg}}","p[9].b[12].pco2={{unselectedfg}}","p[9].b[12].bco2={{unselectedbg}}","p[9].b[12].font={{button12font}}","p[9].b[12].txt=\"{{button12text}}\""] + + ######################################################################### + # Update volume if it has changed state +# - conditions: # volume has changed value +# - condition: template +# value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == heatpump) 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 == heatpump) }}' + sequence: + - service: mqtt.publish + data: + topic: "{{jsoncommandtopic}}" + payload: >- + ["p[9].b[6].font={{button6font}}","p[9].b[6].txt=\"{{button6text}}\"", + "p[9].b[7].pco={{selectedfg7}}","p[9].b[7].bco={{selectedbg7}}","p[9].b[7].pco2={{unselectedfg7}}","p[9].b[7].bco2={{unselectedbg7}}", + "p[9].b[8].pco={{selectedfg8}}","p[9].b[8].bco={{selectedbg8}}","p[9].b[8].pco2={{unselectedfg8}}","p[9].b[8].bco2={{unselectedbg8}}", + "p[9].b[9].font={{button9font}}","p[9].b[9].txt=\"{{button9text}}\"", + "p[9].b[10].pco={{selectedfg10}}","p[9].b[10].bco={{selectedbg10}}","p[9].b[10].pco2={{unselectedfg10}}","p[9].b[10].bco2={{unselectedbg10}}", + "p[9].b[11].pco={{selectedfg11}}","p[9].b[11].bco={{selectedbg11}}","p[9].b[11].pco2={{unselectedfg11}}","p[9].b[11].bco2={{unselectedbg11}}", + "p[9].b[12].pco={{selectedfg}}","p[9].b[12].bco={{selectedbg}}","p[9].b[12].pco2={{unselectedfg}}","p[9].b[12].bco2={{unselectedbg}}","p[9].b[12].font={{button12font}}","p[9].b[12].txt=\"{{button12text}}\""] + + ######################################################################### + # 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 heatpump +# data: +# volume_level: "{{trigger.payload_json.value/255}}" + ######################################################################### + # Target Up was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[4]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_temperature + entity_id: !input heatpump + data: + temperature: "{{temp_inc}}" + ######################################################################### + # Target Down was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[5]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_temperature + entity_id: !input heatpump + data: + temperature: "{{temp_dec}}" + ######################################################################### + # Target Temperature was Pressed + # p[9].b[6] + ######################################################################### + # Current Temperature was Pressed + # p[9].b[9] + ######################################################################### + # Mode=Heat was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[7]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'heat' + ######################################################################### + # Mode=Both was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[8]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'heat_cool' + ######################################################################### + # Mode=Cool was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[10]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'cool' + ######################################################################### + # Mode=Off was Pressed + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[11]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: 'off' + ######################################################################### + # Mode Itself was Pressed, toggle auto/off + - conditions: + - condition: template + value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[9].b[12]") and (trigger.payload_json.value == "ON")}}' + sequence: + - service: climate.set_hvac_mode + entity_id: !input heatpump + data: + hvac_mode: "{{toggle_hp_state}}" + + ######################################################################### + # 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[9].b[4].pco={{selectedfg}}", + "p[9].b[5].pco={{selectedfg}}", + "p[9].b[6].pco={{selectedfg}}", + "p[9].b[7].pco={{selectedfg}}", + "p[9].b[8].pco={{selectedfg}}", + "p[9].b[9].pco={{selectedfg}}", + "p[9].b[10].pco={{selectedfg}}", + "p[9].b[11].pco={{selectedfg}}", + "p[9].b[12].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[9].b[4].bco={{selectedbg}}", + "p[9].b[5].bco={{selectedbg}}", + "p[9].b[6].bco={{selectedbg}}", + "p[9].b[7].bco={{selectedbg}}", + "p[9].b[8].bco={{selectedbg}}", + "p[9].b[9].bco={{selectedbg}}", + "p[9].b[10].bco={{selectedbg}}", + "p[9].b[11].bco={{selectedbg}}", + "p[9].b[12].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[9].b[4].pco2={{unselectedfg}}", + "p[9].b[5].pco2={{unselectedfg}}", + "p[9].b[6].pco2={{unselectedfg}}", + "p[9].b[7].pco2={{unselectedfg}}", + "p[9].b[8].pco2={{unselectedfg}}", + "p[9].b[9].pco2={{unselectedfg}}", + "p[9].b[10].pco2={{unselectedfg}}", + "p[9].b[11].pco2={{unselectedfg}}", + "p[9].b[12].pco2={{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[9].b[4].bco2={{unselectedbg}}", + "p[9].b[5].bco2={{unselectedbg}}", + "p[9].b[6].bco2={{unselectedbg}}", + "p[9].b[7].bco2={{unselectedbg}}", + "p[9].b[8].bco2={{unselectedbg}}", + "p[9].b[9].bco2={{unselectedbg}}", + "p[9].b[10].bco2={{unselectedbg}}", + "p[9].b[11].bco2={{unselectedbg}}", + "p[9].b[12].bco2={{unselectedbg}}"] diff --git a/Home_Assistant/blueprints/hasp_Display_Temperature_Color_Icon_Only.yaml b/Home_Assistant/blueprints/hasp_Display_Temperature_Color_Icon_Only.yaml new file mode 100644 index 0000000..a36d09e --- /dev/null +++ b/Home_Assistant/blueprints/hasp_Display_Temperature_Color_Icon_Only.yaml @@ -0,0 +1,457 @@ +blueprint: + name: "HASP p[x].b[y] displays the current temperature, coloured icon only" + description: | + + # Description + + A HASP button displays the current temperature as an icon that is optionally coloured. + + ![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Display_Temperature_Color_Icon_Only.png) + + ## HASP Page and Button reference + +
+ + This automation is designed to work with the full-width buttons found on pages 1-3 + + | Pages 1-3 | + |-----------| + | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p1-p3_4buttons.png) | + +
+ + ## 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 | + +
+ 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-3) for the temperature. 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-7) for the temperature. 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 current outdoor temperature. If a temperature sensor is selected below, that will override this selection." + default: + selector: + entity: + domain: weather + temperature_sensor: + name: "Temperature sensor" + description: "Select a temperature sensor. If selected, this state of this sensor will be displayed instead of the weather provider selected above." + default: + selector: + entity: + 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`." + default: "state" + selector: + text: + thermometer_empty_color: + name: "Thermometer empty color" + description: 'Icon color for an empty thermometer in Nextion RGB565 format (see "Nextion color codes" above for reference). -1 = Current theme foreground color, or 2047 = Ice blue' + default: 2047 + selector: + number: + min: -1 + max: 65535 + mode: slider + thermometer_quarter_threshold: + name: "Thermometer one quarter threshold" + description: "Temperatures above this threshold will show a one-quarter full thermometer. Below, show an empty thermometer." + default: 0 + selector: + number: + min: -20 + max: 125 + mode: slider + thermometer_quarter_color: + name: "Thermometer one quarter color" + description: "Icon color for a one-quarter full thermometer in Nextion RGB565 format. -1 = Current theme foreground color, or 31 = Blue" + default: 31 + selector: + number: + min: -1 + max: 65535 + mode: slider + thermometer_half_threshold: + name: "Thermometer half threshold" + description: "Temperatures above this threshold will show a half full thermometer. This value must be higher than the value selected above." + default: 32 + selector: + number: + min: -10 + max: 125 + mode: slider + thermometer_half_color: + name: "Thermometer half color" + description: "Icon color for a half full thermometer in Nextion RGB565 format. -1 = Current theme foreground color, or 1536 = Green" + default: 1536 + selector: + number: + min: -1 + max: 65535 + mode: slider + thermometer_three_quarter_threshold: + name: "Thermometer three quarter threshold" + description: "Temperatures above this threshold will show a three-quarters full thermometer. This value must be higher than the value selected above." + default: 80 + selector: + number: + min: 0 + max: 125 + mode: slider + thermometer_three_quarter_color: + name: "Thermometer three quarter color" + description: "Icon color for a three-quarter full thermometer in Nextion RGB565 format. -1 = Current theme foreground color, or 64512 = Orange" + default: 64512 + selector: + number: + min: -1 + max: 65535 + mode: slider + thermometer_full_threshold: + name: "Thermometer full threshold" + description: "Temperatures above this threshold will show a full thermometer. This value must be higher than the value selected above." + default: 95 + selector: + number: + min: 10 + max: 125 + mode: slider + thermometer_full_color: + name: "Thermometer full color" + description: "Icon color for a full thermometer in Nextion RGB565 format. -1 = Current theme foreground color, or 63488 = Red" + default: 63488 + selector: + number: + min: -1 + max: 65535 + mode: slider + +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 -%} + hasppage: !input hasppage + haspbutton: !input haspbutton + weather_provider: !input weather_provider + temperature_sensor: !input temperature_sensor + temperature_attribute: !input temperature_attribute + thermometer_empty_color: !input thermometer_empty_color + thermometer_quarter_threshold: !input thermometer_quarter_threshold + thermometer_quarter_color: !input thermometer_quarter_color + thermometer_half_threshold: !input thermometer_half_threshold + thermometer_half_color: !input thermometer_half_color + thermometer_three_quarter_threshold: !input thermometer_three_quarter_threshold + thermometer_three_quarter_color: !input thermometer_three_quarter_color + thermometer_full_threshold: !input thermometer_full_threshold + thermometer_full_color: !input thermometer_full_color + haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}' + commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}' + jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}' + jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}' + temperature_value: >- + {%- if temperature_sensor|lower == "none" -%} + {{- state_attr(weather_provider, "temperature") -}} + {%- elif temperature_attribute|lower == "state" -%} + {{- states(temperature_sensor) -}} + {%- else -%} + {{- state_attr(temperature_sensor, temperature_attribute) -}} + {%- endif -%} + icon: >- + {%- set temp = temperature_value|int -%} + {%- if temp <= thermometer_quarter_threshold|int -%} +  + {%- elif temp < thermometer_half_threshold|int -%} +  + {% elif temp < thermometer_three_quarter_threshold|int -%} +  + {%- elif temp < thermometer_full_threshold|int -%} +  + {%- else -%} +  + {%- endif -%} + text: "{{temperature_value}}" + font: 8 + ypos: "{{(haspbutton|int - 4) * 67 + 2}}" + xpos: 0 + iconwidth: 40 + iconheight: 65 + iconfont: 8 + xcen: 1 + ycen: 1 + activepage: >- + {%- set activepage = namespace() -%} + {%- for entity in device_entities(haspdevice) -%} + {%- if entity|regex_search("^number\..*_active_page(?:_\d+|)$") -%} + {%- set activepage.entity=entity -%} + {{ break }} + {%- endif -%} + {%- endfor -%} + {% if states(activepage.entity)|lower == "none" %}-1{% else %}{{ states(activepage.entity) | int }}{% 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 }} + tempcolor: >- + {%- set temp = temperature_value|int -%} + {%- if temp <= thermometer_quarter_threshold|int -%} + {%- set color = thermometer_empty_color -%} + {%- elif temp < thermometer_half_threshold|int -%} + {%- set color = thermometer_quarter_color -%} + {%- elif temp < thermometer_three_quarter_threshold|int -%} + {%- set color = thermometer_half_color -%} + {%- elif temp < thermometer_full_threshold|int -%} + {%- set color = thermometer_three_quarter_color -%} + {%- else -%} + {%- set color = thermometer_full_color -%} + {%- endif -%} + {%- if color|int < 0 -%} + {{- selectedfg -}} + {%- else -%} + {{- color -}} + {%- 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" }}' + 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: "{{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, place text, and then place icon if our target page is currently active + - 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}}.pco={{tempcolor}}", + "{{haspobject}}.bco={{selectedbg}}", + "{{haspobject}}.pco2={{unselectedfg}}", + "{{haspobject}}.bco2={{unselectedbg}}", + "{{haspobject}}.txt=\"{{icon}}\""] + ######################################################################### + # Update temperature 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: "{{jsoncommandtopic}}" + payload: >- + ["{{haspobject}}.pco={{tempcolor}}", + "{{haspobject}}.txt=\"{{icon}}\""] + ######################################################################### + # Catch triggers fired by incoming MQTT messages + - conditions: + - condition: template + value_template: '{{ trigger.platform == "mqtt" }}' + sequence: + - choose: + ######################################################################### + # Theme: Apply selected foreground color when it changes. + # Any change to the button will remove the overlaid icon. + - 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_Icon_Only.yaml b/Home_Assistant/blueprints/hasp_Display_Weather_Condition_Icon_Only.yaml new file mode 100644 index 0000000..27a0906 --- /dev/null +++ b/Home_Assistant/blueprints/hasp_Display_Weather_Condition_Icon_Only.yaml @@ -0,0 +1,343 @@ +blueprint: + name: "HASP p[x].b[y] displays the current weather condition icon only" + description: | + + # Description + + A HASP button displays the current weather condition icon only + + ![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Display_Weather_Condition_Icon_Only.png) + + ## HASP Page and Button reference + +
+ + This automation is designed to work with the full-width buttons found on pages 1-3 + + | Pages 1-3 | + |-----------| + | ![Pages 1-3](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p1-p3_4buttons.png) | + +
+ 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-3) for the temperature" + default: 1 + selector: + number: + min: 1 + max: 11 + 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." + 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 temperature" + selector: + entity: + domain: weather + +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 -%} + hasppage: !input hasppage + haspbutton: !input haspbutton + weather_provider: !input weather_provider + haspobject: '{{ "p[" ~ hasppage ~ "].b[" ~ haspbutton ~ "]" }}' + commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ haspobject }}' + jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}' + jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}' + icon: >- + {%- set condition=states(weather_provider) -%} + {%- if condition == "clear-night" -%} +  + {%- elif condition == "cloudy" -%} +  + {%- elif condition == "fog" -%} +  + {%- elif condition == "hail" -%} +  + {%- elif condition == "lightning" -%} +  + {%- elif condition == "lightning-rainy" -%} +  + {%- elif condition == "partlycloudy" -%} +  + {%- elif condition == "pouring" -%} +  + {%- elif condition == "rainy" -%} +  + {%- elif condition == "snowy" -%} +  + {%- elif condition == "snowy-rainy" -%} +  + {%- elif condition == "sunny" -%} +  + {%- elif condition == "windy" -%} +  + {%- elif condition == "windy-variant" -%} +  + {%- elif condition == "exceptional" -%} +  + {%- else -%} +  + {%- endif -%} + 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 + -}} + 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 + iconheight: 65 + iconfont: 7 + xcen: 1 + ycen: 1 + activepage: >- + {%- set activepage = namespace() -%} + {%- for entity in device_entities(haspdevice) -%} + {%- if entity|regex_search("^number\..*_active_page(?:_\d+|)$") -%} + {%- set activepage.entity=entity -%} + {{ break }} + {%- endif -%} + {%- endfor -%} + {% if states(activepage.entity)|lower == "none" %}-1{% else %}{{ states(activepage.entity) | int }}{% 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 weather_provider + - platform: homeassistant + event: start + - platform: template + value_template: "{{ is_state(haspsensor, 'ON') }}" + - 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, place text, and then place icon if our target page is currently active + - 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={{iconfont}}", + "{{haspobject}}.xcen={{xcen}}", + "{{haspobject}}.ycen={{ycen}}", + "{{haspobject}}.pco={{selectedfg}}", + "{{haspobject}}.bco={{selectedbg}}", + "{{haspobject}}.pco2={{unselectedfg}}", + "{{haspobject}}.bco2={{unselectedbg}}", + "{{haspobject}}.txt=\"{{icon}}\""] + ######################################################################### + # Update weather condition 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: "{{jsoncommandtopic}}" + payload: >- + ["{{haspobject}}.pco={{selectedfg}}", + "{{haspobject}}.font={{font}}", + "{{haspobject}}.txt=\"{{icon}} \""] + ######################################################################### + # Catch triggers fired by incoming MQTT messages + - conditions: + - condition: template + value_template: '{{ trigger.platform == "mqtt" }}' + sequence: + - choose: + ######################################################################### + # Theme: Apply selected foreground color when it changes. + # Any change to the button will remove the overlaid icon. + - 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_Theme_Light_on_BlueDark.yaml b/Home_Assistant/blueprints/hasp_Theme_Light_on_BlueDark.yaml new file mode 100644 index 0000000..1441671 --- /dev/null +++ b/Home_Assistant/blueprints/hasp_Theme_Light_on_BlueDark.yaml @@ -0,0 +1,98 @@ +blueprint: + name: "HASP Theme Light on Dark Blue" + description: | + + ## Description + + Press RUN ACTIONS to apply the theme Light on Dark Blue to the selected HASP device + + ![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Theme_Light_on_Dark.png) + + domain: automation + input: + haspdevice: + name: "HASP Device" + description: "Select the HASP device" + selector: + device: + integration: mqtt + manufacturer: "HASwitchPlate" + model: "HASPone v1.0.0" + +mode: single +max_exceeded: silent + +variables: + haspdevice: !input haspdevice + selectedfg_entity: >- + {%- for entity in device_entities(haspdevice) -%} + {%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%} + {{ entity }} + {{ break }} + {%- endif -%} + {%- endfor -%} + selectedbg_entity: >- + {%- for entity in device_entities(haspdevice) -%} + {%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%} + {{ entity }} + {{ break }} + {%- endif -%} + {%- endfor -%} + unselectedfg_entity: >- + {%- for entity in device_entities(haspdevice) -%} + {%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%} + {{ entity }} + {{ break }} + {%- endif -%} + {%- endfor -%} + unselectedbg_entity: >- + {%- for entity in device_entities(haspdevice) -%} + {%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%} + {{ entity }} + {{ break }} + {%- endif -%} + {%- endfor -%} + selected_foreground_brightness: "255" + selected_foreground_color: "[255, 255, 255]" + selected_background_brightness: "1" + selected_background_color: "[0, 0, 255]" + unselected_foreground_brightness: "224" + unselected_foreground_color: "[255, 255, 255]" + unselected_background_brightness: "64" + unselected_background_color: "[0, 0, 255]" + +trigger: [] + +action: + - service: light.turn_on + data: + entity_id: "{{selectedfg_entity}}" + rgb_color: "{{selected_foreground_color}}" + - service: light.turn_on + data: + entity_id: "{{selectedfg_entity}}" + brightness: "{{selected_foreground_brightness}}" + - service: light.turn_on + data: + entity_id: "{{selectedbg_entity}}" + rgb_color: "{{selected_background_color}}" + - service: light.turn_on + data: + entity_id: "{{selectedbg_entity}}" + brightness: "{{selected_background_brightness}}" + - service: light.turn_on + data: + entity_id: "{{unselectedfg_entity}}" + rgb_color: "{{unselected_foreground_color}}" + - service: light.turn_on + data: + entity_id: "{{unselectedfg_entity}}" + brightness: "{{unselected_foreground_brightness}}" + - service: light.turn_on + data: + entity_id: "{{unselectedbg_entity}}" + rgb_color: "{{unselected_background_color}}" + - service: light.turn_on + data: + entity_id: "{{unselectedbg_entity}}" + brightness: "{{unselected_background_brightness}}"