547 lines
20 KiB
YAML
547 lines
20 KiB
YAML
###############################################################################
|
|
# PACKAGE: OpenHASP Thermostat / Gas Heater Control
|
|
# NODE/TOPIC ROOT: hasp/openhasp_1/
|
|
#
|
|
# PAGE OBJECTS USED
|
|
# - p1b1 = main temperature display
|
|
# - p1b2 = alternating Setpoint / Humidity display
|
|
# - p1b3 = setpoint down
|
|
# - p1b4 = setpoint up
|
|
# - p1b5 = heater status text
|
|
# - p1b6 = heater operation / flame button
|
|
###############################################################################
|
|
|
|
###############################################################################
|
|
# HELPERS
|
|
###############################################################################
|
|
input_boolean:
|
|
hasp_setpoint_hold_active:
|
|
name: HASP Setpoint Hold Active
|
|
initial: false
|
|
|
|
input_number:
|
|
# How long Setpoint and Humidity are each shown before rotating
|
|
hasp_setpoint_humidity_cycle_seconds:
|
|
name: HASP Setpoint Humidity Cycle Seconds
|
|
min: 1
|
|
max: 60
|
|
step: 1
|
|
mode: box
|
|
unit_of_measurement: s
|
|
initial: 10
|
|
|
|
# After the setpoint changes, hold the setpoint screen for this long
|
|
hasp_setpoint_hold_seconds:
|
|
name: HASP Setpoint Hold Seconds
|
|
min: 1
|
|
max: 60
|
|
step: 1
|
|
mode: box
|
|
unit_of_measurement: s
|
|
initial: 15
|
|
|
|
###############################################################################
|
|
# MQTT ENTITIES
|
|
###############################################################################
|
|
mqtt:
|
|
sensor:
|
|
- name: "Lounge Environment Humidity MQTT"
|
|
unique_id: "lounge_environment_humidity_mqtt"
|
|
state_topic: "viewroad-status/lounge-environment/humidity"
|
|
|
|
###############################################################################
|
|
# AUTOMATIONS
|
|
###############################################################################
|
|
automation:
|
|
# -------------------------------------------------------------------------
|
|
# Main temperature display
|
|
# - Shows normal lounge temperature
|
|
# - If heater test mode is ON, shows the test temperature instead
|
|
# - Normalises values so we do not get duplicated °C or long float strings
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_temp_to_btn_text
|
|
alias: "HASP: update temp (p1b1.text)"
|
|
mode: queued
|
|
trigger:
|
|
- platform: state
|
|
entity_id:
|
|
- sensor.lounge_environment_lounge_environment_temperature
|
|
- switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode
|
|
- sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp
|
|
action:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b1.text"
|
|
payload: >
|
|
{% if is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode', 'on') %}
|
|
{% set raw = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp') %}
|
|
{% else %}
|
|
{% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
|
|
{% endif %}
|
|
{% set cleaned = raw
|
|
| replace('°C', '')
|
|
| replace('° C', '')
|
|
| replace('C', '')
|
|
| trim %}
|
|
{% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
|
|
{{ cleaned | float(0) | round(1) }} °C
|
|
{% else %}
|
|
-- °C
|
|
{% endif %}
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Heater status text at bottom of screen
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_heater_status_to_btn_text
|
|
alias: "HASP: update heater status (p1b5.text)"
|
|
mode: queued
|
|
trigger:
|
|
- platform: state
|
|
entity_id: sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text
|
|
action:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b5.text"
|
|
payload: >
|
|
{% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}
|
|
{{ s if s not in ['unknown', 'unavailable', ''] else 'HEATER --' }}
|
|
|
|
# -------------------------------------------------------------------------
|
|
# When setpoint changes:
|
|
# - immediately show Setpoint
|
|
# - hold it for hold_seconds
|
|
# - then allow normal Setpoint/Humidity rotation again
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_setpoint_changed_hold_display
|
|
alias: "HASP: show setpoint immediately and hold"
|
|
mode: restart
|
|
trigger:
|
|
- platform: state
|
|
entity_id: sensor.rinnai_neo_gas_heater_setpoint_text
|
|
action:
|
|
- service: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.hasp_setpoint_hold_active
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
|
payload: >
|
|
{% set s = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
|
|
{{ 'Setpoint: ' ~ (s if s not in ['unknown', 'unavailable', ''] else '--') }}
|
|
|
|
- delay:
|
|
seconds: "{{ states('input_number.hasp_setpoint_hold_seconds') | int(15) }}"
|
|
|
|
- service: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.hasp_setpoint_hold_active
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Up / Down buttons on the HASP plate
|
|
# These call the existing HA button entities
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_btn_up_press
|
|
alias: "HASP: p1b4 up -> heater setpoint UP"
|
|
mode: queued
|
|
trigger:
|
|
- platform: mqtt
|
|
topic: "hasp/openhasp_1/state/p1b4"
|
|
condition:
|
|
- condition: template
|
|
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
|
|
action:
|
|
- service: button.press
|
|
target:
|
|
entity_id: button.rinnai_neo_gas_heater_rinnai_neo_gas_heater_setpoint_up
|
|
|
|
- id: hasp_btn_down_press
|
|
alias: "HASP: p1b3 up -> heater setpoint DOWN"
|
|
mode: queued
|
|
trigger:
|
|
- platform: mqtt
|
|
topic: "hasp/openhasp_1/state/p1b3"
|
|
condition:
|
|
- condition: template
|
|
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
|
|
action:
|
|
- service: button.press
|
|
target:
|
|
entity_id: button.rinnai_neo_gas_heater_rinnai_neo_gas_heater_setpoint_down
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Middle flame button
|
|
# - Tap toggles heater operation
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_btn_heat_toggle
|
|
alias: "HASP: p1b6 up -> heater operation toggle"
|
|
mode: queued
|
|
trigger:
|
|
- platform: mqtt
|
|
topic: "hasp/openhasp_1/state/p1b6"
|
|
condition:
|
|
- condition: template
|
|
value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
|
|
action:
|
|
- service: switch.toggle
|
|
target:
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Flame button appearance
|
|
# - Operation OFF: solid light grey background, white flame
|
|
# - Operation ON, flame OFF: solid dark background, white flame
|
|
# - Operation ON, flame ON: solid dark background, continuous red/orange flicker
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_heat_button_state
|
|
alias: "HASP: update heat button state (p1b6)"
|
|
mode: restart
|
|
trigger:
|
|
- platform: state
|
|
entity_id:
|
|
- switch.rinnai_neo_gas_heater_heater_operation
|
|
- switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
|
action:
|
|
- choose:
|
|
# OFF → dark grey (same as your other inactive buttons)
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "off"
|
|
sequence:
|
|
- service: script.turn_off
|
|
target:
|
|
entity_id: script.hasp_heat_flame_flicker
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
|
payload: "\uE238"
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FFFFFF"
|
|
|
|
# solid dark grey (no gradient)
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
|
payload: "#2F3240"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
|
payload: "#2F3240"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
|
payload: "#2F3240"
|
|
|
|
# ON (not firing) → theme blue
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "on"
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
|
state: "off"
|
|
sequence:
|
|
- service: script.turn_off
|
|
target:
|
|
entity_id: script.hasp_heat_flame_flicker
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
|
payload: "\uE238"
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FFFFFF"
|
|
|
|
# MATCH THEME BLUE
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
|
payload: "#0095D9"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
|
payload: "#00B6FF"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
|
payload: "#0095D9"
|
|
|
|
# ON + flame → blue background + flicker
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "on"
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
|
state: "on"
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
|
payload: "\uE238"
|
|
|
|
# keep blue background
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
|
payload: "#0095D9"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
|
payload: "#00B6FF"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
|
payload: "#0095D9"
|
|
|
|
- service: script.turn_on
|
|
target:
|
|
entity_id: script.hasp_heat_flame_flicker
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Start / restart display when HA starts
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_start_on_ha_start
|
|
alias: "HASP: start display loop on HA start"
|
|
trigger:
|
|
- platform: homeassistant
|
|
event: start
|
|
action:
|
|
- service: script.hasp_push_static_texts
|
|
- service: script.turn_on
|
|
target:
|
|
entity_id: script.hasp_rotate_setpoint_humidity
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Re-push screen state when panel comes online
|
|
# -------------------------------------------------------------------------
|
|
- id: hasp_start_on_panel_online
|
|
alias: "HASP: start display loop when panel goes online"
|
|
trigger:
|
|
- platform: mqtt
|
|
topic: "hasp/openhasp_1/LWT"
|
|
condition:
|
|
- condition: template
|
|
value_template: "{{ trigger.payload == 'online' }}"
|
|
action:
|
|
- delay: "00:00:05"
|
|
- service: script.hasp_push_static_texts
|
|
- service: script.turn_on
|
|
target:
|
|
entity_id: script.hasp_rotate_setpoint_humidity
|
|
|
|
###############################################################################
|
|
# SCRIPTS
|
|
###############################################################################
|
|
script:
|
|
# -------------------------------------------------------------------------
|
|
# Push all current values / colours to the panel
|
|
# Useful on HA startup and panel reconnect
|
|
# -------------------------------------------------------------------------
|
|
hasp_push_static_texts:
|
|
alias: "HASP: push static texts"
|
|
mode: queued
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b1.text"
|
|
payload: >
|
|
{% if is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode', 'on') %}
|
|
{% set raw = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_test_mode_temp') %}
|
|
{% else %}
|
|
{% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
|
|
{% endif %}
|
|
{% set cleaned = raw
|
|
| replace('°C', '')
|
|
| replace('° C', '')
|
|
| replace('C', '')
|
|
| trim %}
|
|
{% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
|
|
{{ cleaned | float(0) | round(1) }} °C
|
|
{% else %}
|
|
-- °C
|
|
{% endif %}
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b5.text"
|
|
payload: >
|
|
{% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}
|
|
{{ s if s not in ['unknown', 'unavailable', ''] else 'HEATER --' }}
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
|
payload: >
|
|
{% set s = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
|
|
{{ 'Setpoint: ' ~ (s if s not in ['unknown', 'unavailable', ''] else '--') }}
|
|
|
|
# Push middle flame button state
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text"
|
|
payload: "\uE238"
|
|
|
|
- choose:
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "off"
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FFFFFF"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
|
payload: "#2F3240"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
|
payload: "#2F3240"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
|
payload: "#2F3240"
|
|
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "on"
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
|
state: "off"
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FFFFFF"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
|
payload: "#0095D9"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
|
payload: "#00B6FF"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
|
payload: "#0095D9"
|
|
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "on"
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
|
state: "on"
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_color"
|
|
payload: "#0095D9"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
|
|
payload: "#00B6FF"
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.border_color"
|
|
payload: "#0095D9"
|
|
- service: script.turn_on
|
|
target:
|
|
entity_id: script.hasp_heat_flame_flicker
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Rotate the middle information line between Setpoint and Humidity
|
|
# Pauses humidity display while the setpoint hold flag is active
|
|
# -------------------------------------------------------------------------
|
|
hasp_rotate_setpoint_humidity:
|
|
alias: "HASP: rotate setpoint and humidity"
|
|
mode: restart
|
|
sequence:
|
|
- repeat:
|
|
while:
|
|
- condition: template
|
|
value_template: "{{ true }}"
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
|
payload: >
|
|
{% set s = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
|
|
{{ 'Setpoint: ' ~ (s if s not in ['unknown', 'unavailable', ''] else '--') }}
|
|
|
|
- delay:
|
|
seconds: "{{ states('input_number.hasp_setpoint_humidity_cycle_seconds') | int(10) }}"
|
|
|
|
- condition: state
|
|
entity_id: input_boolean.hasp_setpoint_hold_active
|
|
state: "off"
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b2.text"
|
|
payload: >
|
|
{% set h = states('sensor.lounge_environment_humidity_mqtt') %}
|
|
{% if h in ['unknown', 'unavailable', ''] %}
|
|
Humidity: Unknown
|
|
{% else %}
|
|
Humidity: {{ h }}%
|
|
{% endif %}
|
|
|
|
- delay:
|
|
seconds: "{{ states('input_number.hasp_setpoint_humidity_cycle_seconds') | int(10) }}"
|
|
|
|
# -------------------------------------------------------------------------
|
|
# Continuous flame flicker while heater operation is ON and flame/power is ON
|
|
# Only the icon colour flickers. Background stays fixed.
|
|
# Flicker colours are red <-> orange
|
|
# -------------------------------------------------------------------------
|
|
hasp_heat_flame_flicker:
|
|
alias: "HASP: heat flame flicker"
|
|
mode: restart
|
|
sequence:
|
|
- repeat:
|
|
while:
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
|
state: "on"
|
|
- condition: state
|
|
entity_id: switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_power
|
|
state: "on"
|
|
sequence:
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FF3030"
|
|
- delay: "00:00:00.35"
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FF8C00"
|
|
- delay: "00:00:00.20"
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FF5A36"
|
|
- delay: "00:00:00.30"
|
|
|
|
- service: mqtt.publish
|
|
data:
|
|
topic: "hasp/openhasp_1/command/p1b6.text_color"
|
|
payload: "#FFA500"
|
|
- delay: "00:00:00.18"
|