Files
zorruno-homeassistant/packages/nspanel_lounge_controller.yaml
2026-05-23 23:53:04 +12:00

733 lines
27 KiB
YAML

# yaml-language-server: $schema=null
#:########################################################################################:#
# TITLE: NSPANEL LOUNGE CONTROLLER
# zorruno.com Home Assistant package
#:########################################################################################:#
# VERSIONS:
# V1.5 2026-05-19
# - Added Reading button brightness display.
# - Reading brightness is shown as the highest brightness percentage of either
# couch spot light.
# - Changed Balanced button icon to mdi:scale / \uE472.
# - Added startup panel page refresh before full button state refresh.
#
# V1.4 2026-05-19
# - Changed button highlighting to targeted updates.
# - Remembered scene changes update only the old scene button and new scene button.
# - Reading/Dining changes update only the Reading and Dining buttons.
# - Full refresh is only used at HA start or when manually called.
# - ON icon colour is black [0, 0, 0].
# - OFF icon colour is white [255, 255, 255].
#
# V1.3 2026-05-19
# - Tested page refresh method, but it did not reliably refresh remembered scenes.
#
# V1.2 2026-05-19
# - Added explicit NSPanel button refresh actions using esphome.esp_nspanel2lounge_button.
# - Button states were pushed to the NSPanel when lounge_last_scene or the
# Reading/Dining light states changed.
#
# V1.1 2026-05-18
# - Added template switches so remembered lighting scenes can stay highlighted
# on the NSPanel button page.
# - Updated Blueprint button entities from script.* to switch.*.
#
# V1.0 2026-05-18
# - Initial NSPanel Lounge Controller package using NSPanel Easy Blueprint.
#:########################################################################################:#
# PURPOSE:
# - Configures the Lounge NSPanel Easy button page.
# - Provides Home Assistant script wrappers for lounge lighting scene actions.
# - Provides template switches for NSPanel button state/highlighting.
# - Pushes targeted NSPanel button highlight updates when relevant states change.
#:########################################################################################:#
# OPERATION NOTES:
# - The NSPanel display is configured by the NSPanel Easy Blueprint automation.
# - The screen buttons point to switch.nspanel_lounge_scene_* entities.
# - Remembered scenes are highlighted from input_text.lounge_last_scene.
# - Reading On/Off is highlighted from either couch spot light being on.
# - Reading On/Off shows the highest couch spot brightness percentage.
# - Dining On/Off is highlighted from the dining table light being on.
# - Pressing any NSPanel touch button activates the assigned scene/action.
# - Normal remembered scene transitions update only:
# a) the previous remembered scene button to OFF
# b) the new remembered scene button to ON
#:########################################################################################:#
# DEPENDENCIES:
# - script.lounge_set_scene
# - input_text.lounge_last_scene
# - light.esp_lounge6chdimmer_couch_spots_left
# - light.esp_lounge6chdimmer_couch_spots_right
# - light.esp_lounge6chdimmer_dining_table_light
# - NSPanel Easy Blueprint:
# edwardtfn/nspanel_easy_blueprint.yaml
# - ESPHome actions:
# esphome.esp_nspanel2lounge_button
# esphome.esp_nspanel2lounge_command
#:########################################################################################:#
# NOTES:
# - This is Home Assistant package YAML, not ESPHome YAML.
# - The nspanel_name value is the Home Assistant device ID selected by the
# Blueprint dropdown. Do not replace it with an entity_id or ESPHome hostname.
# - The icon values used by esphome.esp_nspanel2lounge_button are HASP/Nextion
# icon codepoints, not mdi: icon names.
#:########################################################################################:#
#:########################################################################################:#
# AUTOMATIONS
#:########################################################################################:#
automation:
#:######################################################################################:#
# AUTOMATION: NSPanel Easy Blueprint Instance
#:######################################################################################:#
- id: nspanel_lounge_controller
alias: "NSPanel Lounge Controller"
description: "NSPanel Easy configuration for the lounge lighting scene panel."
use_blueprint:
path: edwardtfn/nspanel_easy_blueprint.yaml
input:
nspanel_name: 369e58c3779ff3dd9a0b4c59fadeac4f
########################################################################
# BUTTON PAGE 01: Lounge Lighting Scenes
########################################################################
button_page01_label: Lounge Lighting Scenes
button_pages_icon_size: "10"
entity01: switch.nspanel_lounge_scene_bright
entity01_name: "Bright"
entity01_icon: mdi:brightness-7
entity01_confirm: false
entity02: switch.nspanel_lounge_scene_tv_general
entity02_name: "TV General"
entity02_icon: mdi:television
entity02_confirm: false
entity03: switch.nspanel_lounge_scene_movie
entity03_name: "Movie"
entity03_icon: mdi:movie-open
entity03_confirm: false
entity04: switch.nspanel_lounge_scene_balanced
entity04_name: "Balance"
entity04_icon: mdi:scale
entity04_confirm: false
entity05: switch.nspanel_lounge_scene_warm_cozy
entity05_name: "Warm Cozy"
entity05_icon: mdi:fireplace
entity05_confirm: false
entity06: switch.nspanel_lounge_scene_reading
entity06_name: "Reading On/Off"
entity06_icon: mdi:book-open-page-variant
entity06_confirm: false
entity07: switch.nspanel_lounge_scene_dining
entity07_name: "Dining On/Off"
entity07_icon: mdi:silverware-fork-knife
entity07_confirm: false
entity08: switch.nspanel_lounge_scene_all_off
entity08_name: "All Off"
entity08_icon: mdi:power
entity08_confirm: false
mode: single
#:######################################################################################:#
# AUTOMATION: Refresh Remembered Scene Button Highlights
#
# Only updates the previous remembered scene button and the new remembered
# scene button when input_text.lounge_last_scene changes.
#:######################################################################################:#
- id: nspanel_lounge_refresh_remembered_scene_buttons
alias: "NSPanel Lounge - Refresh Remembered Scene Buttons"
description: "Update only the old and new remembered scene buttons on the NSPanel."
mode: restart
trigger:
- platform: state
entity_id: input_text.lounge_last_scene
action:
- delay:
milliseconds: 500
- variables:
old_scene: "{{ trigger.from_state.state if trigger.from_state is not none else '' }}"
new_scene: "{{ trigger.to_state.state if trigger.to_state is not none else states('input_text.lounge_last_scene') }}"
remembered_scenes:
- "Bright"
- "TV General"
- "Balanced"
- "Movie"
- "Warm Cozy"
- "All Off"
- choose:
- conditions: "{{ old_scene in remembered_scenes and old_scene != new_scene }}"
sequence:
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "{{ old_scene }}"
button_state: false
- delay:
milliseconds: 100
- choose:
- conditions: "{{ new_scene in remembered_scenes }}"
sequence:
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "{{ new_scene }}"
button_state: true
#:######################################################################################:#
# AUTOMATION: Refresh Reading And Dining Button Highlights
#
# Reading/Dining are toggle/action scenes, so they are updated from the real
# light states rather than input_text.lounge_last_scene.
#:######################################################################################:#
- id: nspanel_lounge_refresh_toggle_scene_buttons
alias: "NSPanel Lounge - Refresh Toggle Scene Buttons"
description: "Update Reading and Dining buttons when their lights change."
mode: restart
trigger:
- platform: state
entity_id:
- light.esp_lounge6chdimmer_couch_spots_left
- light.esp_lounge6chdimmer_couch_spots_right
- light.esp_lounge6chdimmer_dining_table_light
- platform: state
entity_id:
- light.esp_lounge6chdimmer_couch_spots_left
- light.esp_lounge6chdimmer_couch_spots_right
- light.esp_lounge6chdimmer_dining_table_light
attribute: brightness
action:
- delay:
milliseconds: 500
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Reading On/Off"
button_state: >-
{{
(
is_state('light.esp_lounge6chdimmer_couch_spots_left', 'on')
and (state_attr('light.esp_lounge6chdimmer_couch_spots_left', 'brightness') | int(0)) > 0
)
or
(
is_state('light.esp_lounge6chdimmer_couch_spots_right', 'on')
and (state_attr('light.esp_lounge6chdimmer_couch_spots_right', 'brightness') | int(0)) > 0
)
}}
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Dining On/Off"
button_state: >-
{{
is_state('light.esp_lounge6chdimmer_dining_table_light', 'on')
and (state_attr('light.esp_lounge6chdimmer_dining_table_light', 'brightness') | int(0)) > 0
}}
#:######################################################################################:#
# AUTOMATION: Initial NSPanel Button Refresh
#
# Full refresh happens when HA starts, or when the NSPanel comes back online.
# Normal scene changes update only the required buttons.
#:######################################################################################:#
- id: nspanel_lounge_refresh_all_buttons_on_start
alias: "NSPanel Lounge - Refresh All Buttons On Start"
description: "Refresh all NSPanel lounge buttons when HA starts or the panel reconnects."
mode: restart
trigger:
- platform: homeassistant
event: start
- platform: state
entity_id: number.lounge_nspanel_touchscreen_display_brightness
from: "unavailable"
- platform: state
entity_id: number.lounge_nspanel_touchscreen_display_brightness
from: "unknown"
action:
- delay:
seconds: 20
- action: esphome.esp_nspanel2lounge_command
data:
cmd: "page buttonpage01"
- delay:
seconds: 1
- action: script.nspanel_lounge_refresh_all_button_states
#:########################################################################################:#
# SCRIPTS
#:########################################################################################:#
script:
#:######################################################################################:#
# SCRIPTS: NSPanel Lounge Scene Button Actions
#:######################################################################################:#
nspanel_lounge_scene_bright:
alias: "NSPanel Lounge Scene - Bright"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "Bright"
nspanel_lounge_scene_tv_general:
alias: "NSPanel Lounge Scene - TV General"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "TV General"
nspanel_lounge_scene_movie:
alias: "NSPanel Lounge Scene - Movie"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "Movie"
nspanel_lounge_scene_balanced:
alias: "NSPanel Lounge Scene - Balanced"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "Balanced"
nspanel_lounge_scene_warm_cozy:
alias: "NSPanel Lounge Scene - Warm Cozy"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "Warm Cozy"
nspanel_lounge_scene_reading:
alias: "NSPanel Lounge Scene - Reading"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "Reading On/Off"
nspanel_lounge_scene_dining:
alias: "NSPanel Lounge Scene - Dining"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "Dining On/Off"
nspanel_lounge_scene_all_off:
alias: "NSPanel Lounge Scene - All Off"
mode: single
sequence:
- action: script.lounge_set_scene
data:
scene_name: "All Off"
#:######################################################################################:#
# SCRIPT: Push One NSPanel Button State
#
# ON state:
# - Button highlighted
# - Icon colour black [0, 0, 0]
#
# OFF state:
# - Button not highlighted
# - Icon colour white [255, 255, 255]
#:######################################################################################:#
nspanel_lounge_push_button_state:
alias: "NSPanel Lounge - Push Button State"
mode: queued
max: 20
fields:
button_id:
description: "NSPanel button id, for example button01"
button_state:
description: "True for highlighted, false for normal"
icon_code:
description: "HASwitchPlate/Nextion icon codepoint"
button_label:
description: "Button label text"
button_bri:
description: "Optional brightness/value text shown on the NSPanel button"
sequence:
- variables:
button_is_on: >-
{{
button_state in [true, 'true', 'True', 'on', 'On', '1', 1]
}}
button_bri_text: "{{ button_bri if button_bri is defined else '' }}"
- choose:
- conditions: "{{ button_is_on }}"
sequence:
- action: esphome.esp_nspanel2lounge_button
data:
page: buttonpage01
id: "{{ button_id }}"
state: true
icon: "{{ icon_code }}"
icon_color:
- 0
- 0
- 0
icon_font: 10
bri: "{{ button_bri_text }}"
label: "{{ button_label }}"
is_page_render: false
default:
- action: esphome.esp_nspanel2lounge_button
data:
page: buttonpage01
id: "{{ button_id }}"
state: false
icon: "{{ icon_code }}"
icon_color:
- 255
- 255
- 255
icon_font: 10
bri: "{{ button_bri_text }}"
label: "{{ button_label }}"
is_page_render: false
#:######################################################################################:#
# SCRIPT: Push One Scene Button State
#
# Maps scene/action names to NSPanel button ids, labels and icon codepoints.
#:######################################################################################:#
nspanel_lounge_push_scene_button_state:
alias: "NSPanel Lounge - Push Scene Button State"
mode: queued
max: 20
fields:
scene_name:
description: "Lounge scene/action name"
button_state:
description: "True for highlighted, false for normal"
sequence:
- choose:
- conditions: "{{ scene_name == 'Bright' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button01
button_state: "{{ button_state }}"
icon_code: "\uE0E0"
button_label: "Bright"
button_bri: ""
- conditions: "{{ scene_name == 'TV General' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button02
button_state: "{{ button_state }}"
icon_code: "\uE502"
button_label: "TV General"
button_bri: ""
- conditions: "{{ scene_name == 'Movie' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button03
button_state: "{{ button_state }}"
icon_code: "\uEFCE"
button_label: "Movie"
button_bri: ""
- conditions: "{{ scene_name == 'Balanced' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button04
button_state: "{{ button_state }}"
icon_code: "\uE472"
button_label: "Balance"
button_bri: ""
- conditions: "{{ scene_name == 'Warm Cozy' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button05
button_state: "{{ button_state }}"
icon_code: "\uEE2E"
button_label: "Warm Cozy"
button_bri: ""
- conditions: "{{ scene_name == 'Reading On/Off' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button06
button_state: "{{ button_state }}"
icon_code: "\uE5DA"
button_label: "Reading On/Off"
button_bri: >-
{% set left_on = is_state('light.esp_lounge6chdimmer_couch_spots_left', 'on') %}
{% set right_on = is_state('light.esp_lounge6chdimmer_couch_spots_right', 'on') %}
{% set left_raw = state_attr('light.esp_lounge6chdimmer_couch_spots_left', 'brightness') | int(0) if left_on else 0 %}
{% set right_raw = state_attr('light.esp_lounge6chdimmer_couch_spots_right', 'brightness') | int(0) if right_on else 0 %}
{% set left_pct = ((left_raw / 255) * 100) | round(0) | int %}
{% set right_pct = ((right_raw / 255) * 100) | round(0) | int %}
{% set reading_pct = [left_pct, right_pct] | max %}
{% if reading_pct > 0 %}{{ reading_pct }}%{% else %}{% endif %}
- conditions: "{{ scene_name == 'Dining On/Off' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button07
button_state: "{{ button_state }}"
icon_code: "\uEA70"
button_label: "Dining On/Off"
button_bri: ""
- conditions: "{{ scene_name == 'All Off' }}"
sequence:
- action: script.nspanel_lounge_push_button_state
data:
button_id: button08
button_state: "{{ button_state }}"
icon_code: "\uE425"
button_label: "All Off"
button_bri: ""
#:######################################################################################:#
# SCRIPT: Refresh All NSPanel Lounge Button States
#
# Use this manually after a panel restart, or automatically once at HA start.
# Normal scene changes do not call this script.
#:######################################################################################:#
nspanel_lounge_refresh_all_button_states:
alias: "NSPanel Lounge - Refresh All Button States"
mode: restart
sequence:
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Bright"
button_state: "{{ is_state('switch.nspanel_lounge_scene_bright', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "TV General"
button_state: "{{ is_state('switch.nspanel_lounge_scene_tv_general', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Movie"
button_state: "{{ is_state('switch.nspanel_lounge_scene_movie', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Balanced"
button_state: "{{ is_state('switch.nspanel_lounge_scene_balanced', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Warm Cozy"
button_state: "{{ is_state('switch.nspanel_lounge_scene_warm_cozy', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Reading On/Off"
button_state: "{{ is_state('switch.nspanel_lounge_scene_reading', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "Dining On/Off"
button_state: "{{ is_state('switch.nspanel_lounge_scene_dining', 'on') }}"
- delay:
milliseconds: 100
- action: script.nspanel_lounge_push_scene_button_state
data:
scene_name: "All Off"
button_state: "{{ is_state('switch.nspanel_lounge_scene_all_off', 'on') }}"
#:######################################################################################:#
# SCRIPT: Compatibility Wrapper
#
# Older versions used this script name. Keep it as a manual full refresh.
#:######################################################################################:#
nspanel_lounge_refresh_button_states:
alias: "NSPanel Lounge - Refresh Button States"
mode: restart
sequence:
- action: script.nspanel_lounge_refresh_all_button_states
#:########################################################################################:#
# TEMPLATE SWITCHES: NSPANEL BUTTON STATE AND HIGHLIGHTING
#:########################################################################################:#
template:
- switch:
##########################################################################
# Remembered scenes
# These switches stay on when input_text.lounge_last_scene matches the
# last remembered scene name. This allows the NSPanel button to remain
# highlighted for the selected remembered scene.
##########################################################################
- name: "NSPanel Lounge Scene Bright"
unique_id: nspanel_lounge_scene_switch_bright
state: "{{ is_state('input_text.lounge_last_scene', 'Bright') }}"
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "Bright"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "Bright"
- name: "NSPanel Lounge Scene TV General"
unique_id: nspanel_lounge_scene_switch_tv_general
state: "{{ is_state('input_text.lounge_last_scene', 'TV General') }}"
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "TV General"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "TV General"
- name: "NSPanel Lounge Scene Balanced"
unique_id: nspanel_lounge_scene_switch_balanced
state: "{{ is_state('input_text.lounge_last_scene', 'Balanced') }}"
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "Balanced"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "Balanced"
- name: "NSPanel Lounge Scene Movie"
unique_id: nspanel_lounge_scene_switch_movie
state: "{{ is_state('input_text.lounge_last_scene', 'Movie') }}"
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "Movie"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "Movie"
- name: "NSPanel Lounge Scene Warm Cozy"
unique_id: nspanel_lounge_scene_switch_warm_cozy
state: "{{ is_state('input_text.lounge_last_scene', 'Warm Cozy') }}"
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "Warm Cozy"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "Warm Cozy"
- name: "NSPanel Lounge Scene All Off"
unique_id: nspanel_lounge_scene_switch_all_off
state: "{{ is_state('input_text.lounge_last_scene', 'All Off') }}"
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "All Off"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "All Off"
##########################################################################
# Toggle/action scenes
# These are excluded from input_text.lounge_last_scene, so their displayed
# state comes from the actual light entities they control.
##########################################################################
- name: "NSPanel Lounge Scene Reading"
unique_id: nspanel_lounge_scene_switch_reading
state: >-
{{
(
is_state('light.esp_lounge6chdimmer_couch_spots_left', 'on')
and (state_attr('light.esp_lounge6chdimmer_couch_spots_left', 'brightness') | int(0)) > 0
)
or
(
is_state('light.esp_lounge6chdimmer_couch_spots_right', 'on')
and (state_attr('light.esp_lounge6chdimmer_couch_spots_right', 'brightness') | int(0)) > 0
)
}}
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "Reading On/Off"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "Reading On/Off"
- name: "NSPanel Lounge Scene Dining"
unique_id: nspanel_lounge_scene_switch_dining
state: >-
{{
is_state('light.esp_lounge6chdimmer_dining_table_light', 'on')
and (state_attr('light.esp_lounge6chdimmer_dining_table_light', 'brightness') | int(0)) > 0
}}
turn_on:
- action: script.lounge_set_scene
data:
scene_name: "Dining On/Off"
turn_off:
- action: script.lounge_set_scene
data:
scene_name: "Dining On/Off"