#:########################################################################################:#
# PACKAGE: OpenHASP Thermostat / Gas Heater Control
# VERSION: v1.5 (2026-06-22)
# NODE/TOPIC ROOT: hasp/openhasp_1/
#
# PAGE 1: Gas heater / lounge environment
# - p1b1 = gas heater setpoint large display
# - p1b2 = actual lounge room temperature display
# - p1b3 = gas heater setpoint down
# - p1b4 = gas heater setpoint up
# - p1b5 = gas heater status text
# - p1b6 = gas heater operation / flame button
# - p1b7 = humidity display
#
# PAGE 2: Lounge climate heating control
# - p2b1 = climate.lounge setpoint large display
# - p2b2 = actual lounge room temperature display
# - p2b3 = climate.lounge setpoint down 0.5°C
# - p2b4 = climate.lounge setpoint up 0.5°C
# - p2b5 = climate.lounge status text
# - p2b6 = climate.lounge heat mode / sun button
# - p2b7 = humidity display
#
# PAGE 3: Lounge climate cooling control
# - p3b1 = climate.lounge setpoint large display
# - p3b2 = actual lounge room temperature display
# - p3b3 = climate.lounge setpoint down 0.5°C
# - p3b4 = climate.lounge setpoint up 0.5°C
# - p3b5 = climate.lounge status text
# - p3b6 = climate.lounge cool mode / snowflake button
# - p3b7 = humidity display
#
# NOTES:
# - The large top display is the setpoint for that device/page.
# - The middle-left temperature display is always the actual lounge room temp.
# - p1b3/p1b4 are yellow.
# - p1b6 is grey when OFF/BYPASS, yellow in AUTO, and red flame when firing.
# - p2b3/p2b4 are pink.
# - p2b6 turns climate.lounge ON and sets HVAC mode to heat.
# - p2b6 is pink only when climate.lounge is in heat mode.
# - p3b3/p3b4 are light blue.
# - p3b6 toggles climate.lounge OFF if already cooling; otherwise sets COOL.
# - p3b6 is light blue only when climate.lounge is in cool mode.
#:########################################################################################:#

#:########################################################################################:#
# MQTT ENTITIES
#:########################################################################################:#

mqtt:
  sensor:
    - name: "Lounge Environment Humidity MQTT"
      unique_id: "lounge_environment_humidity_mqtt"
      state_topic: "viewroad-status/lounge-environment/humidity"
      value_template: >
        {% set raw = value | trim %}
        {% if raw.startswith('{') %}
          {% set j = raw | from_json %}
          {{ j.humidity | default(j.value | default(raw)) }}
        {% else %}
          {{ raw | replace('%', '') | trim }}
        {% endif %}

  select:
    - name: "OpenHASP Lounge Page"
      unique_id: "openhasp_lounge_page"
      icon: mdi:tablet-dashboard
      state_topic: "hasp/openhasp_1/state/page"
      command_topic: "hasp/openhasp_1/command/page"
      options:
        - "1"
        - "2"
        - "3"
      value_template: >
        {% set raw = value | trim %}
        {% if raw.startswith('{') %}
          {% set j = raw | from_json %}
          {{ j.page | default(raw) }}
        {% else %}
          {{ raw }}
        {% endif %}

#:########################################################################################:#
# AUTOMATIONS
#:########################################################################################:#

automation:
  # -------------------------------------------------------------------------
  # Actual lounge room temperature display on page 1, page 2, and page 3
  # -------------------------------------------------------------------------
  - id: hasp_lounge_temp_to_page_text
    alias: "HASP: update lounge actual temperature displays"
    mode: queued
    trigger:
      - platform: state
        entity_id: sensor.lounge_environment_lounge_environment_temperature
    action:
      - service: script.hasp_publish_lounge_temp_displays

  # -------------------------------------------------------------------------
  # Gas heater status text on page 1
  # -------------------------------------------------------------------------
  - 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
          - select.rinnai_neo_gas_heater_mode
          - switch.rinnai_neo_gas_heater_heater_operation
          - switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_activate_flame
    action:
      - service: script.hasp_publish_heater_status_text

  # -------------------------------------------------------------------------
  # Gas heater setpoint large display on page 1
  # -------------------------------------------------------------------------
  - id: hasp_setpoint_to_btn_text
    alias: "HASP: update gas heater setpoint (p1b1.text)"
    mode: queued
    trigger:
      - platform: state
        entity_id: sensor.rinnai_neo_gas_heater_setpoint_text
    action:
      - service: script.hasp_publish_heater_setpoint

  # -------------------------------------------------------------------------
  # Humidity display on page 1, page 2, and page 3
  # -------------------------------------------------------------------------
  - id: hasp_humidity_to_btn_text
    alias: "HASP: update humidity displays"
    mode: queued
    trigger:
      - platform: state
        entity_id: sensor.lounge_environment_humidity_mqtt
    action:
      - service: script.hasp_publish_humidity_displays

  # -------------------------------------------------------------------------
  # Page 1 gas heater setpoint up/down buttons
  # -------------------------------------------------------------------------
  - id: hasp_btn_up_press
    alias: "HASP: p1b4 up -> gas 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 -> gas 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

  # -------------------------------------------------------------------------
  # Page 1 gas heater middle flame button
  # -------------------------------------------------------------------------
  - id: hasp_btn_heat_toggle
    alias: "HASP: p1b6 up -> gas 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

  # -------------------------------------------------------------------------
  # Page 1 gas heater middle button appearance
  # -------------------------------------------------------------------------
  - id: hasp_heat_button_state
    alias: "HASP: update gas heat button state (p1b6)"
    mode: restart
    trigger:
      - platform: state
        entity_id:
          - select.rinnai_neo_gas_heater_mode
          - switch.rinnai_neo_gas_heater_heater_operation
          - switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_activate_flame
    action:
      - service: script.hasp_apply_heat_button_state

  # -------------------------------------------------------------------------
  # Page 2 and page 3 climate.lounge text and button state updates
  # -------------------------------------------------------------------------
  - id: hasp_lounge_climate_to_page2
    alias: "HASP: update lounge climate pages 2 and 3"
    mode: queued
    trigger:
      - platform: state
        entity_id: climate.lounge
    action:
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_apply_climate_heat_button_state
      - service: script.hasp_push_page3_climate_texts
      - service: script.hasp_apply_climate_cool_button_state

  # -------------------------------------------------------------------------
  # Page 2 climate.lounge setpoint down
  # -------------------------------------------------------------------------
  - id: hasp_page2_climate_down_press
    alias: "HASP: p2b3 up -> lounge climate setpoint DOWN 0.5"
    mode: queued
    trigger:
      - platform: mqtt
        topic: "hasp/openhasp_1/state/p2b3"
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
    action:
      - service: climate.set_temperature
        target:
          entity_id: climate.lounge
        data:
          temperature: >
            {% set current = state_attr('climate.lounge', 'temperature') | float(20) %}
            {{ (current - 0.5) | round(1) }}
      - delay: "00:00:01"
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_push_page3_climate_texts

  # -------------------------------------------------------------------------
  # Page 2 climate.lounge setpoint up
  # -------------------------------------------------------------------------
  - id: hasp_page2_climate_up_press
    alias: "HASP: p2b4 up -> lounge climate setpoint UP 0.5"
    mode: queued
    trigger:
      - platform: mqtt
        topic: "hasp/openhasp_1/state/p2b4"
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
    action:
      - service: climate.set_temperature
        target:
          entity_id: climate.lounge
        data:
          temperature: >
            {% set current = state_attr('climate.lounge', 'temperature') | float(20) %}
            {{ (current + 0.5) | round(1) }}
      - delay: "00:00:01"
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_push_page3_climate_texts

  # -------------------------------------------------------------------------
  # Page 2 climate.lounge heat mode button
  # -------------------------------------------------------------------------
  - id: hasp_page2_climate_heat_press
    alias: "HASP: p2b6 up -> lounge climate heat mode"
    mode: queued
    trigger:
      - platform: mqtt
        topic: "hasp/openhasp_1/state/p2b6"
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
    action:
      - service: climate.turn_on
        target:
          entity_id: climate.lounge
      - service: climate.set_hvac_mode
        target:
          entity_id: climate.lounge
        data:
          hvac_mode: heat
      - delay: "00:00:01"
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_apply_climate_heat_button_state
      - service: script.hasp_push_page3_climate_texts
      - service: script.hasp_apply_climate_cool_button_state

  # -------------------------------------------------------------------------
  # Page 3 climate.lounge setpoint down
  # -------------------------------------------------------------------------
  - id: hasp_page3_climate_down_press
    alias: "HASP: p3b3 up -> lounge climate setpoint DOWN 0.5"
    mode: queued
    trigger:
      - platform: mqtt
        topic: "hasp/openhasp_1/state/p3b3"
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
    action:
      - service: climate.set_temperature
        target:
          entity_id: climate.lounge
        data:
          temperature: >
            {% set current = state_attr('climate.lounge', 'temperature') | float(20) %}
            {{ (current - 0.5) | round(1) }}
      - delay: "00:00:01"
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_push_page3_climate_texts

  # -------------------------------------------------------------------------
  # Page 3 climate.lounge setpoint up
  # -------------------------------------------------------------------------
  - id: hasp_page3_climate_up_press
    alias: "HASP: p3b4 up -> lounge climate setpoint UP 0.5"
    mode: queued
    trigger:
      - platform: mqtt
        topic: "hasp/openhasp_1/state/p3b4"
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
    action:
      - service: climate.set_temperature
        target:
          entity_id: climate.lounge
        data:
          temperature: >
            {% set current = state_attr('climate.lounge', 'temperature') | float(20) %}
            {{ (current + 0.5) | round(1) }}
      - delay: "00:00:01"
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_push_page3_climate_texts

  # -------------------------------------------------------------------------
  # Page 3 climate.lounge cool mode button
  # - If already cooling, turn OFF
  # - Otherwise turn ON and set COOL
  # -------------------------------------------------------------------------
  - id: hasp_page3_climate_cool_press
    alias: "HASP: p3b6 up -> lounge climate cool toggle"
    mode: queued
    trigger:
      - platform: mqtt
        topic: "hasp/openhasp_1/state/p3b6"
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json.event | default('') == 'up' }}"
    action:
      - choose:
          - conditions:
              - condition: state
                entity_id: climate.lounge
                state: "cool"
            sequence:
              - service: climate.turn_off
                target:
                  entity_id: climate.lounge

        default:
          - service: climate.turn_on
            target:
              entity_id: climate.lounge
          - service: climate.set_hvac_mode
            target:
              entity_id: climate.lounge
            data:
              hvac_mode: cool

      - delay: "00:00:01"
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_apply_climate_heat_button_state
      - service: script.hasp_push_page3_climate_texts
      - service: script.hasp_apply_climate_cool_button_state

  # -------------------------------------------------------------------------
  # Push all screen state when Home Assistant 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

  # -------------------------------------------------------------------------
  # Push all screen state when the openHASP 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

#:########################################################################################:#
# SCRIPTS
#:########################################################################################:#

script:
  # -------------------------------------------------------------------------
  # Push all current values and colours to the panel
  # -------------------------------------------------------------------------
  hasp_push_static_texts:
    alias: "HASP: push static texts"
    mode: queued
    sequence:
      - service: script.hasp_style_center_info_buttons
      - service: script.hasp_style_page1_control_buttons
      - service: script.hasp_style_page2_control_buttons
      - service: script.hasp_style_page3_control_buttons
      - service: script.hasp_publish_lounge_temp_displays
      - service: script.hasp_publish_heater_status_text
      - service: script.hasp_publish_heater_setpoint
      - service: script.hasp_publish_humidity_displays
      - service: script.hasp_apply_heat_button_state
      - service: script.hasp_push_page2_climate_texts
      - service: script.hasp_apply_climate_heat_button_state
      - service: script.hasp_push_page3_climate_texts
      - service: script.hasp_apply_climate_cool_button_state

  # -------------------------------------------------------------------------
  # Publish actual lounge room temperature to all middle-left displays
  # p1b2 = actual room temperature
  # p2b2 = actual room temperature
  # p3b2 = actual room temperature
  # -------------------------------------------------------------------------
  hasp_publish_lounge_temp_displays:
    alias: "HASP: publish lounge actual temperature displays"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b2.text"
          payload: >-
            {% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
            {% set cleaned = raw
              | replace('°C', '')
              | replace('° C', '')
              | replace('℃', '')
              | replace('C', '')
              | trim %}
            {% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE50F' }} {{ cleaned | float(0) | round(1) }}°C
            {% else %}
              {{ '\uE50F' }} --°C
            {% endif %}

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b2.text"
          payload: >-
            {% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
            {% set cleaned = raw
              | replace('°C', '')
              | replace('° C', '')
              | replace('℃', '')
              | replace('C', '')
              | trim %}
            {% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE50F' }} {{ cleaned | float(0) | round(1) }}°C
            {% else %}
              {{ '\uE50F' }} --°C
            {% endif %}

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b2.text"
          payload: >-
            {% set raw = states('sensor.lounge_environment_lounge_environment_temperature') %}
            {% set cleaned = raw
              | replace('°C', '')
              | replace('° C', '')
              | replace('℃', '')
              | replace('C', '')
              | trim %}
            {% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE50F' }} {{ cleaned | float(0) | round(1) }}°C
            {% else %}
              {{ '\uE50F' }} --°C
            {% endif %}

  # -------------------------------------------------------------------------
  # Publish gas heater setpoint to page 1 large top display
  # p1b1 = gas heater setpoint
  # -------------------------------------------------------------------------
  hasp_publish_heater_setpoint:
    alias: "HASP: publish gas heater setpoint"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b1.text"
          payload: >-
            {% set raw = states('sensor.rinnai_neo_gas_heater_setpoint_text') %}
            {% set cleaned = raw
              | replace('°C', '')
              | replace('° C', '')
              | replace('℃', '')
              | replace('C', '')
              | trim %}
            {% if cleaned not in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE238' }}{{ cleaned | float(0) | round(1) }}°C
            {% else %}
              {{ '\uE238' }}--°C
            {% endif %}

  # -------------------------------------------------------------------------
  # Publish humidity to page 1, page 2, and page 3
  # -------------------------------------------------------------------------
  hasp_publish_humidity_displays:
    alias: "HASP: publish humidity displays"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b7.text"
          payload: >-
            {% set raw = states('sensor.lounge_environment_humidity_mqtt') %}
            {% set cleaned = raw | replace('%', '') | trim %}
            {% if cleaned in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE58C' }} --%
            {% else %}
              {{ '\uE58C' }} {{ cleaned }}%
            {% endif %}

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b7.text"
          payload: >-
            {% set raw = states('sensor.lounge_environment_humidity_mqtt') %}
            {% set cleaned = raw | replace('%', '') | trim %}
            {% if cleaned in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE58C' }} --%
            {% else %}
              {{ '\uE58C' }} {{ cleaned }}%
            {% endif %}

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b7.text"
          payload: >-
            {% set raw = states('sensor.lounge_environment_humidity_mqtt') %}
            {% set cleaned = raw | replace('%', '') | trim %}
            {% if cleaned in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ '\uE58C' }} --%
            {% else %}
              {{ '\uE58C' }} {{ cleaned }}%
            {% endif %}

  # -------------------------------------------------------------------------
  # Publish gas heater status text to page 1 bottom label
  #
  # Display behaviour:
  # - OFF                    -> Off
  # - BYPASS (Remote Only)   -> Bypass (Remote Only)
  # - Auto but flame OFF     -> Auto (Up to Temp)
  # - Auto while firing      -> Auto (Level 1), Auto (Level 2), etc.
  # -------------------------------------------------------------------------
  hasp_publish_heater_status_text:
    alias: "HASP: publish heater status text"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b5.text"
          payload: >-
            {% set mode = states('select.rinnai_neo_gas_heater_mode') %}
            {% set op = states('switch.rinnai_neo_gas_heater_heater_operation') %}
            {% set flame_on = is_state('switch.rinnai_neo_gas_heater_rinnai_neo_gas_heater_activate_flame', 'on') %}
            {% set s = states('sensor.rinnai_neo_gas_heater_rinnai_neo_gas_heater_status_text') %}

            {% if mode == 'OFF' %}
              Off
            {% elif mode == 'BYPASS (Remote Only)' %}
              Bypass (Remote Only)
            {% elif op == 'on' and not flame_on %}
              Auto (Up to Temp)
            {% elif s not in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ s }}
            {% elif mode not in ['unknown', 'unavailable', '', 'none', 'None'] %}
              {{ mode }}
            {% else %}
              HEATER --
            {% endif %}

  # -------------------------------------------------------------------------
  # Apply page 1 gas heater middle flame button state
  # -------------------------------------------------------------------------
  hasp_apply_heat_button_state:
    alias: "HASP: apply gas heat button state"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b6.text"
          payload: "\uE238"

      - choose:
          # BYPASS -> grey button, amber flame
          - conditions:
              - condition: state
                entity_id: select.rinnai_neo_gas_heater_mode
                state: "BYPASS (Remote Only)"
            sequence:
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.text_color"
                  payload: "#FFB000"
              - 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"

          # OFF -> grey button, light grey flame
          - conditions:
              - condition: state
                entity_id: select.rinnai_neo_gas_heater_mode
                state: "OFF"
            sequence:
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.text_color"
                  payload: "#C0C0C0"
              - 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"

          # AUTO, flame ON -> yellow button, red flame
          - 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_activate_flame
                state: "on"
            sequence:
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.text_color"
                  payload: "#FF3030"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.bg_color"
                  payload: "#FFC107"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
                  payload: "#FFD54F"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.border_color"
                  payload: "#FFC107"

          # AUTO, flame OFF -> yellow button, black flame
          - 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_activate_flame
                state: "off"
            sequence:
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.text_color"
                  payload: "#000000"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.bg_color"
                  payload: "#FFC107"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.bg_grad_color"
                  payload: "#FFD54F"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p1b6.border_color"
                  payload: "#FFC107"

        default:
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p1b6.text_color"
              payload: "#C0C0C0"
          - 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"

  # -------------------------------------------------------------------------
  # Push page 2 climate.lounge setpoint and status text
  # -------------------------------------------------------------------------
  hasp_push_page2_climate_texts:
    alias: "HASP: push page 2 climate texts"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b1.text"
          payload: >-
            {% set target = state_attr('climate.lounge', 'temperature') %}
            {% if target is not none %}
              {{ '\uE5A8' }}{{ target | float(0) | round(1) }}°C
            {% else %}
              {{ '\uE5A8' }}--°C
            {% endif %}

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b5.text"
          payload: >-
            {% set mode = states('climate.lounge') %}
            {% set mode_map = {
              'off': 'Off',
              'heat': 'Heating',
              'cool': 'Cooling',
              'heat_cool': 'Auto',
              'auto': 'Auto',
              'dry': 'Dry',
              'fan_only': 'Fan'
            } %}
            {% set mode_text = mode_map.get(mode, mode | replace('_', ' ') | title) %}

            {% set preset = state_attr('climate.lounge', 'preset_mode') | default('', true) | string | lower %}
            {% set fan = state_attr('climate.lounge', 'fan_mode') | default('', true) | string | lower %}
            {% set swing = state_attr('climate.lounge', 'swing_mode') | default('', true) | string | lower %}

            {% set eco_attr = state_attr('climate.lounge', 'eco') | default('', true) | string | lower %}
            {% set powerful_attr = state_attr('climate.lounge', 'powerful') | default('', true) | string | lower %}
            {% set quiet_attr = state_attr('climate.lounge', 'quiet') | default('', true) | string | lower %}
            {% set nanoe_attr = state_attr('climate.lounge', 'nanoe') | default('', true) | string | lower %}
            {% set nanoe_x_attr = state_attr('climate.lounge', 'nanoe_x') | default('', true) | string | lower %}

            {% set ns = namespace(extras=[]) %}

            {% if 'eco' in preset or eco_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['Eco'] %}
            {% endif %}

            {% if 'powerful' in preset or 'boost' in preset or powerful_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['Powerful'] %}
            {% endif %}

            {% if 'quiet' in preset or 'quiet' in fan or quiet_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['Quiet'] %}
            {% endif %}

            {% if 'nanoe' in preset or 'nanoe' in swing or nanoe_attr in ['on', 'true', '1', 'yes'] or nanoe_x_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['nanoe-x'] %}
            {% endif %}

            {% if ns.extras | length > 0 %}
              {{ mode_text }} ({{ ns.extras | join(', ') }})
            {% else %}
              {{ mode_text }}
            {% endif %}

  # -------------------------------------------------------------------------
  # Push page 3 climate.lounge setpoint and status text
  # -------------------------------------------------------------------------
  hasp_push_page3_climate_texts:
    alias: "HASP: push page 3 climate texts"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b1.text"
          payload: >-
            {% set target = state_attr('climate.lounge', 'temperature') %}
            {% if target is not none %}
              {{ '\uE717' }}{{ target | float(0) | round(1) }}°C
            {% else %}
              {{ '\uE717' }}--°C
            {% endif %}

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b5.text"
          payload: >-
            {% set mode = states('climate.lounge') %}
            {% set mode_map = {
              'off': 'Off',
              'heat': 'Heating',
              'cool': 'Cooling',
              'heat_cool': 'Auto',
              'auto': 'Auto',
              'dry': 'Dry',
              'fan_only': 'Fan'
            } %}
            {% set mode_text = mode_map.get(mode, mode | replace('_', ' ') | title) %}

            {% set preset = state_attr('climate.lounge', 'preset_mode') | default('', true) | string | lower %}
            {% set fan = state_attr('climate.lounge', 'fan_mode') | default('', true) | string | lower %}
            {% set swing = state_attr('climate.lounge', 'swing_mode') | default('', true) | string | lower %}

            {% set eco_attr = state_attr('climate.lounge', 'eco') | default('', true) | string | lower %}
            {% set powerful_attr = state_attr('climate.lounge', 'powerful') | default('', true) | string | lower %}
            {% set quiet_attr = state_attr('climate.lounge', 'quiet') | default('', true) | string | lower %}
            {% set nanoe_attr = state_attr('climate.lounge', 'nanoe') | default('', true) | string | lower %}
            {% set nanoe_x_attr = state_attr('climate.lounge', 'nanoe_x') | default('', true) | string | lower %}

            {% set ns = namespace(extras=[]) %}

            {% if 'eco' in preset or eco_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['Eco'] %}
            {% endif %}

            {% if 'powerful' in preset or 'boost' in preset or powerful_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['Powerful'] %}
            {% endif %}

            {% if 'quiet' in preset or 'quiet' in fan or quiet_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['Quiet'] %}
            {% endif %}

            {% if 'nanoe' in preset or 'nanoe' in swing or nanoe_attr in ['on', 'true', '1', 'yes'] or nanoe_x_attr in ['on', 'true', '1', 'yes'] %}
              {% set ns.extras = ns.extras + ['nanoe-x'] %}
            {% endif %}

            {% if ns.extras | length > 0 %}
              {{ mode_text }} ({{ ns.extras | join(', ') }})
            {% else %}
              {{ mode_text }}
            {% endif %}

  # -------------------------------------------------------------------------
  # Apply page 2 climate.lounge heat button state
  # -------------------------------------------------------------------------
  hasp_apply_climate_heat_button_state:
    alias: "HASP: apply lounge climate heat button state"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b6.text"
          payload: "\uE5A8"

      - choose:
          # climate.lounge is ON and in HEAT mode -> pink sun
          - conditions:
              - condition: state
                entity_id: climate.lounge
                state: "heat"
            sequence:
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p2b6.text_color"
                  payload: "#FFFFFF"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p2b6.bg_color"
                  payload: "#C2185B"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p2b6.bg_grad_color"
                  payload: "#E91E63"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p2b6.border_color"
                  payload: "#C2185B"

        default:
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p2b6.text_color"
              payload: "#C0C0C0"
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p2b6.bg_color"
              payload: "#2F3240"
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p2b6.bg_grad_color"
              payload: "#2F3240"
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p2b6.border_color"
              payload: "#2F3240"

  # -------------------------------------------------------------------------
  # Apply page 3 climate.lounge cool button state
  # -------------------------------------------------------------------------
  hasp_apply_climate_cool_button_state:
    alias: "HASP: apply lounge climate cool button state"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b6.text"
          payload: "\uE717"

      - choose:
          # climate.lounge is ON and in COOL mode -> light blue snowflake
          - conditions:
              - condition: state
                entity_id: climate.lounge
                state: "cool"
            sequence:
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p3b6.text_color"
                  payload: "#FFFFFF"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p3b6.bg_color"
                  payload: "#0288D1"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p3b6.bg_grad_color"
                  payload: "#4FC3F7"
              - service: mqtt.publish
                data:
                  topic: "hasp/openhasp_1/command/p3b6.border_color"
                  payload: "#0288D1"

        default:
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p3b6.text_color"
              payload: "#C0C0C0"
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p3b6.bg_color"
              payload: "#2F3240"
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p3b6.bg_grad_color"
              payload: "#2F3240"
          - service: mqtt.publish
            data:
              topic: "hasp/openhasp_1/command/p3b6.border_color"
              payload: "#2F3240"

  # -------------------------------------------------------------------------
  # Style page 1, page 2, and page 3 actual temp/humidity displays
  # -------------------------------------------------------------------------
  hasp_style_center_info_buttons:
    alias: "HASP: style centre info buttons"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b2.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b2.bg_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b2.bg_grad_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b2.border_color"
          payload: "#000000"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b7.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b7.bg_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b7.bg_grad_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b7.border_color"
          payload: "#000000"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b2.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b2.bg_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b2.bg_grad_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b2.border_color"
          payload: "#000000"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b7.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b7.bg_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b7.bg_grad_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b7.border_color"
          payload: "#000000"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b2.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b2.bg_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b2.bg_grad_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b2.border_color"
          payload: "#000000"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b7.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b7.bg_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b7.bg_grad_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b7.border_color"
          payload: "#000000"

  # -------------------------------------------------------------------------
  # Style page 1 gas heater up/down buttons yellow
  # p1b6 is state-driven by hasp_apply_heat_button_state.
  # -------------------------------------------------------------------------
  hasp_style_page1_control_buttons:
    alias: "HASP: style page 1 control buttons"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b3.text_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b3.bg_color"
          payload: "#FFC107"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b3.bg_grad_color"
          payload: "#FFD54F"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b3.border_color"
          payload: "#FFC107"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b4.text_color"
          payload: "#000000"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b4.bg_color"
          payload: "#FFC107"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b4.bg_grad_color"
          payload: "#FFD54F"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p1b4.border_color"
          payload: "#FFC107"

  # -------------------------------------------------------------------------
  # Style page 2 climate up/down buttons pink
  # p2b6 is state-driven by hasp_apply_climate_heat_button_state.
  # -------------------------------------------------------------------------
  hasp_style_page2_control_buttons:
    alias: "HASP: style page 2 control buttons"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b3.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b3.bg_color"
          payload: "#C2185B"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b3.bg_grad_color"
          payload: "#E91E63"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b3.border_color"
          payload: "#C2185B"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b4.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b4.bg_color"
          payload: "#C2185B"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b4.bg_grad_color"
          payload: "#E91E63"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p2b4.border_color"
          payload: "#C2185B"

  # -------------------------------------------------------------------------
  # Style page 3 climate up/down buttons light blue
  # p3b6 is state-driven by hasp_apply_climate_cool_button_state.
  # -------------------------------------------------------------------------
  hasp_style_page3_control_buttons:
    alias: "HASP: style page 3 control buttons"
    mode: queued
    sequence:
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b3.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b3.bg_color"
          payload: "#0288D1"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b3.bg_grad_color"
          payload: "#4FC3F7"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b3.border_color"
          payload: "#0288D1"

      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b4.text_color"
          payload: "#FFFFFF"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b4.bg_color"
          payload: "#0288D1"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b4.bg_grad_color"
          payload: "#4FC3F7"
      - service: mqtt.publish
        data:
          topic: "hasp/openhasp_1/command/p3b4.border_color"
          payload: "#0288D1"
