additional esphome devices and fixes
This commit is contained in:
@@ -0,0 +1,389 @@
|
||||
# yaml-language-server: $schema=null
|
||||
|
||||
###############################################################################
|
||||
# PACKAGE: 16A EV Charger Control
|
||||
###############################################################################
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-05-15
|
||||
# - Reworked 1hr topup logic to use a hard deadline and watchdog.
|
||||
# - Removed dependency on timer.finished event for relay shutoff.
|
||||
# - Offpeak until charged now continues past offpeak end until charging stops.
|
||||
# - 1hr topup now now rolls into Normal Offpeak if the hour ends during
|
||||
# the offpeak window, without switching the relay off and back on.
|
||||
#
|
||||
# V1.0 2026-05-11
|
||||
# - Initial package for 16A EV charger offpeak and charge-until-full control.
|
||||
#
|
||||
# PACKAGE SETTINGS:
|
||||
# Car display name:
|
||||
# - Leaf
|
||||
#
|
||||
# Charger relay output:
|
||||
# - switch.garage_db_control_16a_wallcharger_operation
|
||||
#
|
||||
# Vehicle charging sensor:
|
||||
# - binary_sensor.garage_db_control_16a_wallcharger_charging
|
||||
#
|
||||
# Default offpeak period:
|
||||
# - Start: 21:00:00
|
||||
# - End: 00:00:00
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
input_datetime:
|
||||
ev_16a_offpeak_start:
|
||||
name: 16A EV Offpeak Start
|
||||
has_date: false
|
||||
has_time: true
|
||||
initial: "21:00:00"
|
||||
|
||||
ev_16a_offpeak_end:
|
||||
name: 16A EV Offpeak End
|
||||
has_date: false
|
||||
has_time: true
|
||||
initial: "00:00:00"
|
||||
|
||||
ev_16a_1hr_topup_until:
|
||||
name: 16A EV 1hr topup until
|
||||
has_date: true
|
||||
has_time: true
|
||||
initial: "2000-01-01 00:00:00"
|
||||
|
||||
input_select:
|
||||
ev_16a_charge_mode:
|
||||
name: Leaf EV charge mode
|
||||
icon: mdi:ev-station
|
||||
options:
|
||||
- "Normal (Offpeak)"
|
||||
- "Offpeak until charged"
|
||||
- "1hr topup now"
|
||||
- "Charge now until full"
|
||||
- "Stop charging now"
|
||||
initial: "Normal (Offpeak)"
|
||||
|
||||
automation:
|
||||
#############################################################################
|
||||
# OFFPEAK START
|
||||
#############################################################################
|
||||
|
||||
- id: ev_16a_charger_offpeak_start
|
||||
alias: "16A EV Charger - Offpeak Start"
|
||||
mode: single
|
||||
|
||||
triggers:
|
||||
- trigger: time
|
||||
at: input_datetime.ev_16a_offpeak_start
|
||||
|
||||
conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ states('input_select.ev_16a_charge_mode') in
|
||||
['Normal (Offpeak)', 'Offpeak until charged'] }}
|
||||
|
||||
actions:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
state: "Offpeak until charged"
|
||||
sequence:
|
||||
# If the car never starts charging, or is already full, turn off
|
||||
# after a 5 minute grace period.
|
||||
- delay: "00:05:00"
|
||||
|
||||
- condition: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
state: "Offpeak until charged"
|
||||
|
||||
- condition: state
|
||||
entity_id: binary_sensor.garage_db_control_16a_wallcharger_charging
|
||||
state: "off"
|
||||
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
- action: input_select.select_option
|
||||
target:
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
data:
|
||||
option: "Normal (Offpeak)"
|
||||
|
||||
#############################################################################
|
||||
# OFFPEAK END
|
||||
#############################################################################
|
||||
|
||||
- id: ev_16a_charger_offpeak_end
|
||||
alias: "16A EV Charger - Offpeak End"
|
||||
mode: single
|
||||
|
||||
triggers:
|
||||
- trigger: time
|
||||
at: input_datetime.ev_16a_offpeak_end
|
||||
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
state: "Normal (Offpeak)"
|
||||
|
||||
actions:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
#############################################################################
|
||||
# USER CHARGE MODE SELECTIONS
|
||||
#############################################################################
|
||||
|
||||
- id: ev_16a_charger_charge_mode_selected
|
||||
alias: "16A EV Charger - Charge Mode Selected"
|
||||
mode: restart
|
||||
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
|
||||
actions:
|
||||
- variables:
|
||||
selected_mode: "{{ trigger.to_state.state }}"
|
||||
is_offpeak_now: >
|
||||
{% set start = states('input_datetime.ev_16a_offpeak_start') %}
|
||||
{% set end = states('input_datetime.ev_16a_offpeak_end') %}
|
||||
{% set now_time = now().strftime('%H:%M:%S') %}
|
||||
{% if start == end %}
|
||||
{{ true }}
|
||||
{% elif start < end %}
|
||||
{{ start <= now_time < end }}
|
||||
{% else %}
|
||||
{{ now_time >= start or now_time < end }}
|
||||
{% endif %}
|
||||
|
||||
- choose:
|
||||
#####################################################################
|
||||
# NORMAL OFFPEAK
|
||||
#####################################################################
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ selected_mode == 'Normal (Offpeak)' }}"
|
||||
sequence:
|
||||
# No immediate action.
|
||||
# Normal mode only acts when the offpeak start/end triggers fire.
|
||||
- stop: "Normal offpeak mode selected."
|
||||
|
||||
#####################################################################
|
||||
# OFFPEAK UNTIL CHARGED
|
||||
#####################################################################
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ selected_mode == 'Offpeak until charged' }}"
|
||||
sequence:
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: "{{ is_offpeak_now }}"
|
||||
then:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
# If the car never starts charging, or is already full, turn
|
||||
# off after a 5 minute grace period.
|
||||
- delay: "00:05:00"
|
||||
|
||||
- condition: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
state: "Offpeak until charged"
|
||||
|
||||
- condition: state
|
||||
entity_id: binary_sensor.garage_db_control_16a_wallcharger_charging
|
||||
state: "off"
|
||||
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
- action: input_select.select_option
|
||||
target:
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
data:
|
||||
option: "Normal (Offpeak)"
|
||||
|
||||
#####################################################################
|
||||
# 1 HOUR TOPUP NOW
|
||||
#####################################################################
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ selected_mode == '1hr topup now' }}"
|
||||
sequence:
|
||||
- action: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.ev_16a_1hr_topup_until
|
||||
data:
|
||||
datetime: >
|
||||
{{ (as_timestamp(now()) + 3600)
|
||||
| timestamp_custom('%Y-%m-%d %H:%M:%S', true) }}
|
||||
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
#####################################################################
|
||||
# CHARGE NOW UNTIL FULL
|
||||
#####################################################################
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ selected_mode == 'Charge now until full' }}"
|
||||
sequence:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
# If the car never starts charging, or is already full, turn off
|
||||
# after a 5 minute grace period.
|
||||
- delay: "00:05:00"
|
||||
|
||||
- condition: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
state: "Charge now until full"
|
||||
|
||||
- condition: state
|
||||
entity_id: binary_sensor.garage_db_control_16a_wallcharger_charging
|
||||
state: "off"
|
||||
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
- action: input_select.select_option
|
||||
target:
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
data:
|
||||
option: "Normal (Offpeak)"
|
||||
|
||||
#####################################################################
|
||||
# STOP CHARGING NOW
|
||||
#####################################################################
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ selected_mode == 'Stop charging now' }}"
|
||||
sequence:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
- action: input_select.select_option
|
||||
target:
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
data:
|
||||
option: "Normal (Offpeak)"
|
||||
|
||||
#############################################################################
|
||||
# 1 HOUR TOPUP WATCHDOG
|
||||
#############################################################################
|
||||
|
||||
- id: ev_16a_charger_1hr_topup_watchdog
|
||||
alias: "16A EV Charger - 1hr Topup Watchdog"
|
||||
mode: single
|
||||
|
||||
triggers:
|
||||
- trigger: time_pattern
|
||||
minutes: "/1"
|
||||
|
||||
- trigger: homeassistant
|
||||
event: start
|
||||
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
state: "1hr topup now"
|
||||
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ as_timestamp(now()) >=
|
||||
as_timestamp(states('input_datetime.ev_16a_1hr_topup_until')) }}
|
||||
|
||||
actions:
|
||||
- variables:
|
||||
is_offpeak_now: >
|
||||
{% set start = states('input_datetime.ev_16a_offpeak_start') %}
|
||||
{% set end = states('input_datetime.ev_16a_offpeak_end') %}
|
||||
{% set now_time = now().strftime('%H:%M:%S') %}
|
||||
{% if start == end %}
|
||||
{{ true }}
|
||||
{% elif start < end %}
|
||||
{{ start <= now_time < end }}
|
||||
{% else %}
|
||||
{{ now_time >= start or now_time < end }}
|
||||
{% endif %}
|
||||
|
||||
- action: input_select.select_option
|
||||
target:
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
data:
|
||||
option: "Normal (Offpeak)"
|
||||
|
||||
- choose:
|
||||
# If the 1 hour topup finishes during offpeak, do not flick the relay.
|
||||
# Leave it on and let the Normal Offpeak end automation turn it off.
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ is_offpeak_now }}"
|
||||
sequence:
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
state: "off"
|
||||
then:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
default:
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
#############################################################################
|
||||
# CHARGING COMPLETE MONITOR
|
||||
#############################################################################
|
||||
|
||||
- id: ev_16a_charger_stop_when_charging_complete
|
||||
alias: "16A EV Charger - Stop When Charging Complete"
|
||||
mode: single
|
||||
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: binary_sensor.garage_db_control_16a_wallcharger_charging
|
||||
to: "off"
|
||||
for: "00:05:00"
|
||||
|
||||
conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ states('input_select.ev_16a_charge_mode') in
|
||||
['Offpeak until charged', 'Charge now until full'] }}
|
||||
|
||||
actions:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.garage_db_control_16a_wallcharger_operation
|
||||
|
||||
- action: input_select.select_option
|
||||
target:
|
||||
entity_id: input_select.ev_16a_charge_mode
|
||||
data:
|
||||
option: "Normal (Offpeak)"
|
||||
@@ -17,14 +17,14 @@ automation:
|
||||
entity_id: input_button.announcement_test
|
||||
|
||||
action:
|
||||
- action: script.view_road_announcement
|
||||
data:
|
||||
channels: "sony_tv_lounge"
|
||||
title: "View Road Test"
|
||||
short_announcement: "Test announcement"
|
||||
long_announcement: "This is a test announcement from the package test button."
|
||||
payload: "On"
|
||||
indicator: ""
|
||||
# - action: script.view_road_announcement
|
||||
# data:
|
||||
# channels: "sony_tv_lounge"
|
||||
# title: "View Road Test"
|
||||
# short_announcement: "Test announcement"
|
||||
# long_announcement: "This is a test announcement from the package test button."
|
||||
# payload: "On"
|
||||
# indicator: ""
|
||||
|
||||
#- action: script.view_road_announcement
|
||||
# data:
|
||||
@@ -34,6 +34,7 @@ automation:
|
||||
|
||||
- action: script.view_road_announcement
|
||||
data:
|
||||
channels: "lounge_google_home_voice"
|
||||
title: "View Road Test"
|
||||
long_announcement: "This is a test announcement on the lounge Google Home."
|
||||
channels: "lounge_google_home_voice, sony_tv_lounge"
|
||||
title: "View Road "
|
||||
short_announcement: "9pm, Free Power time"
|
||||
long_announcement: "It is 9pm."
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
################################################################################
|
||||
# PACKAGE: Underhouse Entrance Auto Lights
|
||||
################################################################################
|
||||
#
|
||||
# Version:
|
||||
# 1.2 - 2026-05-12
|
||||
# - Added fast Zigbee2MQTT FP1-style event triggers:
|
||||
# sensor.underhouse_mmwave_sensor_x23ms_presence_event = enter
|
||||
# sensor.underhouse_mmwave_sensor_x23ms_presence_event = approach
|
||||
# - Keeps binary presence as a backup trigger and as the clear/off condition.
|
||||
# - This should behave closer to the previous Node-RED automation.
|
||||
#
|
||||
# Notes:
|
||||
# - The UI may show the binary sensor as "Detected", but the YAML state is
|
||||
# normally "on".
|
||||
# - The presence_event sensor can react earlier than the binary presence sensor.
|
||||
# - The event sensor is used to turn lights on quickly, but not to decide when
|
||||
# the area is clear, because it may remain on its last event value.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
automation:
|
||||
- id: underhouse_entrance_auto_lights
|
||||
alias: "Underhouse Entrance - Auto Lights"
|
||||
description: "Turns underhouse entrance lights on from Zigbee2MQTT mmWave enter/approach/presence, then off 400 seconds after presence clears."
|
||||
mode: restart
|
||||
max_exceeded: silent
|
||||
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: sensor.underhouse_mmwave_sensor_x23ms_presence_event
|
||||
to: "enter"
|
||||
|
||||
- platform: state
|
||||
entity_id: sensor.underhouse_mmwave_sensor_x23ms_presence_event
|
||||
to: "approach"
|
||||
|
||||
- platform: state
|
||||
entity_id: binary_sensor.underhouse_mmwave_sensor_x23ms_presence
|
||||
to: "on"
|
||||
|
||||
action:
|
||||
- alias: "Turn on the underhouse entrance lights"
|
||||
action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.esp_underhouselights_underhouse_entrance_lights
|
||||
|
||||
- alias: "Wait until the mmWave presence sensor is clear"
|
||||
wait_template: >
|
||||
{{ is_state('binary_sensor.underhouse_mmwave_sensor_x23ms_presence', 'off') }}
|
||||
|
||||
- alias: "Keep lights on for 400 seconds after presence clears"
|
||||
delay:
|
||||
seconds: 400
|
||||
|
||||
- alias: "Only continue if presence is still clear"
|
||||
condition: state
|
||||
entity_id: binary_sensor.underhouse_mmwave_sensor_x23ms_presence
|
||||
state: "off"
|
||||
|
||||
- alias: "Turn off the underhouse entrance lights"
|
||||
action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.esp_underhouselights_underhouse_entrance_lights
|
||||
@@ -0,0 +1,276 @@
|
||||
#:########################################################################################:#
|
||||
# TITLE: UNDERHOUSE STORAGE LIGHTS AUTO LIGHTS PACKAGE
|
||||
#:########################################################################################:#
|
||||
# DESCRIPTION:
|
||||
# Replaces the Node-RED automation for the underhouse storage lights.
|
||||
# Doors, PIR sensors, a remote switch, and local relay changes can start or
|
||||
# extend a 1 hour lighting timer.
|
||||
#
|
||||
# VERSION:
|
||||
# V1.0 2026-05-12
|
||||
# - Initial Home Assistant package version.
|
||||
#
|
||||
# EDIT NOTES:
|
||||
# - Add future door contacts in BOTH places marked FUTURE DOOR.
|
||||
# - Add future PIR sensors in the PIR group marked FUTURE PIR.
|
||||
# - The generated group entities used below should be:
|
||||
# binary_sensor.underhouse_storage_door_contacts
|
||||
# binary_sensor.underhouse_storage_pir_presence
|
||||
#:########################################################################################:#
|
||||
|
||||
binary_sensor:
|
||||
- platform: group
|
||||
name: Underhouse Storage Door Contacts
|
||||
unique_id: underhouse_storage_door_contacts
|
||||
device_class: door
|
||||
all: false
|
||||
entities:
|
||||
- binary_sensor.underhouse_stealth_door_x07rs_contact
|
||||
- binary_sensor.underhouse_north_door_door
|
||||
# FUTURE DOOR: add the next underhouse storage door contact here.
|
||||
# - binary_sensor.underhouse_future_door_contact
|
||||
|
||||
- platform: group
|
||||
name: Underhouse Storage PIR Presence
|
||||
unique_id: underhouse_storage_pir_presence
|
||||
device_class: occupancy
|
||||
all: false
|
||||
entities:
|
||||
- binary_sensor.underhouse_pir_sensor_south_occupancy
|
||||
# FUTURE PIR: uncomment this when the north PIR exists.
|
||||
# - binary_sensor.underhouse_pir_sensor_north_occupancy
|
||||
|
||||
timer:
|
||||
underhouse_storage_lights_runtime:
|
||||
name: Underhouse Storage Lights Runtime
|
||||
duration: "01:00:00"
|
||||
restore: true
|
||||
icon: mdi:timer-outline
|
||||
|
||||
script:
|
||||
underhouse_storage_lights_start_runtime:
|
||||
alias: Underhouse Storage Lights - Start Or Extend Runtime
|
||||
mode: restart
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
state: "off"
|
||||
sequence:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
|
||||
- action: timer.start
|
||||
target:
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
data:
|
||||
duration: "0:20:00"
|
||||
|
||||
underhouse_storage_lights_stop_runtime:
|
||||
alias: Underhouse Storage Lights - Stop Runtime
|
||||
mode: restart
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
state: "on"
|
||||
sequence:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ not is_state('timer.underhouse_storage_lights_runtime', 'idle') }}
|
||||
sequence:
|
||||
- action: timer.cancel
|
||||
target:
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
|
||||
automation:
|
||||
- id: underhouse_storage_lights_start_extend_runtime
|
||||
alias: Underhouse Storage Lights - Start Or Extend Runtime
|
||||
description: >-
|
||||
Turns the storage lights on and starts or restarts the 1 hour timer when
|
||||
a door opens, PIR detects occupancy, or the remote switch is pressed.
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.underhouse_storage_door_contacts
|
||||
to: "on"
|
||||
- platform: state
|
||||
entity_id: binary_sensor.underhouse_storage_pir_presence
|
||||
to: "on"
|
||||
- platform: state
|
||||
entity_id: binary_sensor.esp_underhouselights_underhouse_storage_lights_remote_switch
|
||||
to: "on"
|
||||
action:
|
||||
- action: script.underhouse_storage_lights_start_runtime
|
||||
|
||||
- id: underhouse_storage_lights_start_timer_when_relay_turned_on
|
||||
alias: Underhouse Storage Lights - Start Timer When Relay Turned On
|
||||
description: >-
|
||||
Starts the timer if the relay is turned on locally by ESPHome or
|
||||
by another Home Assistant automation.
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
to: "on"
|
||||
action:
|
||||
- action: timer.start
|
||||
target:
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
data:
|
||||
duration: "00:20:00"
|
||||
|
||||
- id: underhouse_storage_lights_timer_finished
|
||||
alias: Underhouse Storage Lights - Timer Finished
|
||||
description: >-
|
||||
Turns the storage lights off after the runtime expires, even if a
|
||||
door has been left open.
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: timer.finished
|
||||
event_data:
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
state: "on"
|
||||
sequence:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
|
||||
- id: underhouse_storage_lights_cancel_timer_when_relay_off
|
||||
alias: Underhouse Storage Lights - Cancel Timer When Relay Off
|
||||
description: >-
|
||||
Keeps the timer helper tidy if the relay is turned off manually, locally,
|
||||
or by another automation.
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
to: "off"
|
||||
condition:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ not is_state('timer.underhouse_storage_lights_runtime', 'idle') }}
|
||||
action:
|
||||
- action: timer.cancel
|
||||
target:
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
|
||||
- id: underhouse_storage_lights_all_doors_closed
|
||||
alias: Underhouse Storage Lights - All Doors Closed
|
||||
description: >-
|
||||
When all door contacts are closed, turn the lights off immediately if no
|
||||
PIR occupancy is active. If PIR is still active, the PIR clear automation
|
||||
below will turn them off after 60 seconds without occupancy.
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.underhouse_storage_door_contacts
|
||||
from: "on"
|
||||
to: "off"
|
||||
condition:
|
||||
- condition: state
|
||||
entity_id: binary_sensor.underhouse_storage_pir_presence
|
||||
state: "off"
|
||||
action:
|
||||
- action: script.underhouse_storage_lights_stop_runtime
|
||||
|
||||
- id: underhouse_storage_lights_individual_door_closed_check
|
||||
alias: Underhouse Storage Lights - Individual Door Closed No Motion Check
|
||||
description: >-
|
||||
When a real door contact closes, wait 60 seconds and then turn the relay
|
||||
off only if all doors are closed and there is no PIR occupancy.
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- binary_sensor.underhouse_stealth_door_x07rs_contact
|
||||
- binary_sensor.underhouse_north_door_door
|
||||
# FUTURE DOOR: add the next underhouse storage door contact here too.
|
||||
# - binary_sensor.underhouse_future_door_contact
|
||||
from: "on"
|
||||
to: "off"
|
||||
action:
|
||||
- delay: "00:01:00"
|
||||
- condition: state
|
||||
entity_id: binary_sensor.underhouse_storage_door_contacts
|
||||
state: "off"
|
||||
- condition: state
|
||||
entity_id: binary_sensor.underhouse_storage_pir_presence
|
||||
state: "off"
|
||||
- condition: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
state: "on"
|
||||
- action: script.underhouse_storage_lights_stop_runtime
|
||||
|
||||
- id: underhouse_storage_lights_pir_clear_after_doors_closed
|
||||
alias: Underhouse Storage Lights - PIR Clear After Doors Closed
|
||||
description: >-
|
||||
If the doors are closed and PIR occupancy clears for 60 seconds, turn the
|
||||
storage lights off.
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.underhouse_storage_pir_presence
|
||||
to: "off"
|
||||
for: "00:01:00"
|
||||
condition:
|
||||
- condition: state
|
||||
entity_id: binary_sensor.underhouse_storage_door_contacts
|
||||
state: "off"
|
||||
- condition: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
state: "on"
|
||||
action:
|
||||
- action: script.underhouse_storage_lights_stop_runtime
|
||||
|
||||
- id: underhouse_storage_lights_startup_sync
|
||||
alias: Underhouse Storage Lights - Startup Sync
|
||||
description: >-
|
||||
On Home Assistant startup, re-sync the package state so an already-open
|
||||
door or already-active PIR still controls the lights after a restart.
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: homeassistant
|
||||
event: start
|
||||
action:
|
||||
- delay: "00:00:20"
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{
|
||||
is_state('binary_sensor.underhouse_storage_door_contacts', 'on')
|
||||
or is_state('binary_sensor.underhouse_storage_pir_presence', 'on')
|
||||
or is_state('binary_sensor.esp_underhouselights_underhouse_storage_lights_remote_switch', 'on')
|
||||
}}
|
||||
sequence:
|
||||
- action: script.underhouse_storage_lights_start_runtime
|
||||
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: switch.esp_underhouselights_underhouse_storage_lights
|
||||
state: "on"
|
||||
- condition: state
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
state: "idle"
|
||||
sequence:
|
||||
- action: timer.start
|
||||
target:
|
||||
entity_id: timer.underhouse_storage_lights_runtime
|
||||
data:
|
||||
duration: "00:20:00"
|
||||
@@ -1,20 +1,26 @@
|
||||
###############################################################################
|
||||
# Bedroom 1 Ikea Air Filter Package
|
||||
# File: /config/packages/bedroom_1_ikea_air_filter.yaml
|
||||
# Version: 1.0
|
||||
# Date: 2026-04-29
|
||||
# Version: 1.1
|
||||
# Date: 2026-05-08
|
||||
#
|
||||
# Purpose:
|
||||
# - Creates a dropdown helper called "Bedroom 1 Ikea Fan".
|
||||
# - Auto mode controls the Bedroom 1 Ikea air filter speed by priority.
|
||||
# - Auto mode controls the Bedroom 1 Ikea air filter speed by event and timing.
|
||||
# - Manual dropdown modes set a fixed fan speed and disable auto control.
|
||||
#
|
||||
# Auto priority order:
|
||||
# 1. Quiet time on: fan speed 2
|
||||
# 2. Bedside light on: fan speed 2
|
||||
# 3. Free power time, 21:00 to midnight: fan speed 5
|
||||
# 4. Daytime, 09:00 to 15:00: fan speed 4
|
||||
# 5. Default: fan speed 2
|
||||
# Behaviour notes:
|
||||
# - Quiet time turning on sets fan speed to 2.
|
||||
# - Bedside lamp turning on sets fan speed to 2.
|
||||
# - Bedside lamp turning off does not change the fan speed.
|
||||
# - There is no 10-minute re-check, so the fan will not ramp back up just
|
||||
# because the bedside lamp was switched off.
|
||||
# - Time boundaries can still change the fan speed later.
|
||||
#
|
||||
# Auto timing:
|
||||
# - 21:00 to midnight: fan speed 5
|
||||
# - 09:00 to 15:00: fan speed 4
|
||||
# - Default: fan speed 2
|
||||
###############################################################################
|
||||
|
||||
input_select:
|
||||
@@ -68,13 +74,17 @@ automation:
|
||||
- trigger: homeassistant
|
||||
event: start
|
||||
|
||||
# Highest priority condition.
|
||||
# Quiet time only forces low when it turns on.
|
||||
# Turning quiet time off does not automatically ramp the fan back up.
|
||||
- trigger: state
|
||||
entity_id: input_boolean.quiet_time
|
||||
to: "on"
|
||||
|
||||
# Bedside lamp should force low speed while on.
|
||||
# Bedside lamp only forces low when it turns on.
|
||||
# Turning the lamp off does not change the fan speed.
|
||||
- trigger: state
|
||||
entity_id: light.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb
|
||||
to: "on"
|
||||
|
||||
# Main timing boundaries.
|
||||
- trigger: time
|
||||
@@ -84,10 +94,6 @@ automation:
|
||||
- "15:00:00"
|
||||
- "21:00:00"
|
||||
|
||||
# Safety/re-check trigger, especially for the bedside lamp rule.
|
||||
- trigger: time_pattern
|
||||
minutes: "/10"
|
||||
|
||||
conditions:
|
||||
# Manual dropdown modes disable automatic control.
|
||||
- condition: state
|
||||
@@ -96,10 +102,26 @@ automation:
|
||||
|
||||
actions:
|
||||
- variables:
|
||||
trigger_entity: "{{ trigger.entity_id | default('') }}"
|
||||
bedside_lamp_entity: light.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb
|
||||
bedside_lamp_on_trigger: >-
|
||||
{{
|
||||
trigger_entity == bedside_lamp_entity
|
||||
and trigger.to_state is defined
|
||||
and trigger.to_state.state == 'on'
|
||||
}}
|
||||
quiet_time_on_trigger: >-
|
||||
{{
|
||||
trigger_entity == 'input_boolean.quiet_time'
|
||||
and trigger.to_state is defined
|
||||
and trigger.to_state.state == 'on'
|
||||
}}
|
||||
auto_target_speed: >-
|
||||
{% if is_state('input_boolean.quiet_time', 'on') %}
|
||||
{% if bedside_lamp_on_trigger %}
|
||||
2
|
||||
{% elif is_state('light.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb', 'on') %}
|
||||
{% elif quiet_time_on_trigger %}
|
||||
2
|
||||
{% elif is_state('input_boolean.quiet_time', 'on') %}
|
||||
2
|
||||
{% elif now().hour >= 21 %}
|
||||
5
|
||||
@@ -142,7 +164,7 @@ automation:
|
||||
entity_id: automation.bedroom_1_ikea_air_filter_auto_control
|
||||
|
||||
# Auto starts at speed 2, then immediately evaluates the
|
||||
# current priority rules.
|
||||
# current timing rules.
|
||||
- action: script.bedroom_1_ikea_air_filter_set_speed_if_needed
|
||||
data:
|
||||
target_speed: 2
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
###############################################################################
|
||||
#
|
||||
# VERSION:
|
||||
# 1.4 - 2026-05-21
|
||||
# - Added delayed lounge NSPanel touchscreen brightness reduction to 5.
|
||||
#
|
||||
# 1.3 - 2026-05-07
|
||||
# - Added downstairs lights all off script.
|
||||
# - Added main hallway nightlights 60 minute bedtime timer.
|
||||
@@ -29,6 +32,7 @@
|
||||
# - climate entities are turned off if they are not already "off".
|
||||
# - Main hallway nightlights are turned on for 60 minutes when bedtime mode runs.
|
||||
# - If the main hallway nightlights are turned off manually, the timer is cancelled.
|
||||
# - Lounge NSPanel touchscreen brightness is set to 5 after 20 seconds.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
@@ -94,6 +98,18 @@ automation:
|
||||
delay_seconds: 0
|
||||
|
||||
action:
|
||||
# Turn hallway nightlights on immediately before any other bedtime actions.
|
||||
- service: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.main_hallway_nightlights_1_relay_1_main_hallway_nightlights
|
||||
|
||||
# Start or restart the 60 minute bedtime nightlight timer.
|
||||
- service: timer.start
|
||||
target:
|
||||
entity_id: timer.main_hallway_nightlights_bedtime
|
||||
data:
|
||||
duration: "01:00:00"
|
||||
|
||||
- service: script.downstairs_lights_all_off
|
||||
|
||||
- service: script.lounge_set_scene
|
||||
@@ -104,15 +120,10 @@ automation:
|
||||
target:
|
||||
entity_id: input_boolean.quiet_time
|
||||
|
||||
- service: switch.turn_on
|
||||
# Reduce the lounge NSPanel screen brightness after 20 seconds.
|
||||
- service: script.turn_on
|
||||
target:
|
||||
entity_id: switch.main_hallway_nightlights_1_relay_1_main_hallway_nightlights
|
||||
|
||||
- service: timer.start
|
||||
target:
|
||||
entity_id: timer.main_hallway_nightlights_bedtime
|
||||
data:
|
||||
duration: "01:00:00"
|
||||
entity_id: script.bedtime_mode_set_lounge_nspanel_brightness_after_delay
|
||||
|
||||
- repeat:
|
||||
for_each: "{{ bedtime_delayed_off_targets }}"
|
||||
@@ -232,3 +243,21 @@ script:
|
||||
|
||||
mode: parallel
|
||||
max: 50
|
||||
|
||||
bedtime_mode_set_lounge_nspanel_brightness_after_delay:
|
||||
alias: "Bedtime Mode - Set Lounge NSPanel Brightness After Delay"
|
||||
description: >
|
||||
Waits 20 seconds after bedtime mode starts, then sets the lounge NSPanel
|
||||
touchscreen display brightness to 5.
|
||||
|
||||
sequence:
|
||||
- delay:
|
||||
seconds: 20
|
||||
|
||||
- service: number.set_value
|
||||
target:
|
||||
entity_id: number.lounge_nspanel_touchscreen_display_brightness
|
||||
data:
|
||||
value: 1
|
||||
|
||||
mode: restart
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
mqtt:
|
||||
switch:
|
||||
- unique_id: lounge_blinds_control
|
||||
name: "Lounge Blinds Control"
|
||||
state_topic: "viewroad-status/blinds/lounge-verticalblinds"
|
||||
command_topic: "viewroad-commands/blinds/lounge-verticalblinds"
|
||||
payload_off: "off"
|
||||
payload_on: "on"
|
||||
state_on: "on"
|
||||
state_off: "off"
|
||||
icon: mdi:blinds
|
||||
retain: false
|
||||
|
||||
automation:
|
||||
- id: lounge_blinds_control_switch
|
||||
alias: Publish lounge blind control to mqtt
|
||||
trigger:
|
||||
platform: state
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
action:
|
||||
service: mqtt.publish
|
||||
data_template:
|
||||
payload: "{{trigger.to_state.state}}"
|
||||
topic: viewroad-status/blinds/lounge-verticalblinds
|
||||
@@ -4,6 +4,12 @@
|
||||
#
|
||||
# VERSION HISTORY
|
||||
#
|
||||
# 2026-05-07 - v1.0.2
|
||||
# - Added binary_sensor.downstairs_flat_any_lights_on.
|
||||
# - Updated all-on/all-off script to use the new binary sensor.
|
||||
# - Kept direct entity lists instead of using a Home Assistant group, to avoid
|
||||
# package merge errors from duplicate group/name keys.
|
||||
#
|
||||
# 2026-05-07 - v1.0.1
|
||||
# - Removed group.downstairs_flat_lights from this package to avoid duplicate
|
||||
# group/name package merge errors.
|
||||
@@ -30,6 +36,11 @@
|
||||
# - downstairs_light_toggle_all_group turns all listed lights OFF if any are ON.
|
||||
# - downstairs_light_toggle_all_group turns all listed lights ON if they are all OFF.
|
||||
#
|
||||
# - binary_sensor.downstairs_flat_any_lights_on:
|
||||
# - ON when any listed downstairs light is ON.
|
||||
# - OFF when all listed downstairs lights are OFF.
|
||||
# - This replaces the need for a group.downstairs_flat_lights entity.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
@@ -41,6 +52,27 @@ input_boolean:
|
||||
name: Downstairs Guest Occupied
|
||||
icon: mdi:home-account
|
||||
|
||||
###############################################################################
|
||||
# TEMPLATE SENSORS
|
||||
###############################################################################
|
||||
|
||||
template:
|
||||
- binary_sensor:
|
||||
- name: Downstairs Flat Any Lights On
|
||||
unique_id: downstairs_flat_any_lights_on
|
||||
icon: mdi:lightbulb-group
|
||||
state: >
|
||||
{{
|
||||
is_state('switch.esp_downstloungemain_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstloungemain_relay_2_back_wall_lights', 'on')
|
||||
or is_state('switch.esp_downstmasterbedrmlights_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstbedrm2lights_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstkitchlights_relay_2_kitchen_light', 'on')
|
||||
or is_state('switch.esp_downstkitchlights_relay_1_dining_light', 'on')
|
||||
or is_state('switch.esp_downstbathswitch_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstbathswitch_relay_2_cabinet_light', 'on')
|
||||
}}
|
||||
|
||||
###############################################################################
|
||||
# SCRIPTS
|
||||
###############################################################################
|
||||
@@ -169,18 +201,9 @@ script:
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{
|
||||
is_state('switch.esp_downstloungemain_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstloungemain_relay_2_back_wall_lights', 'on')
|
||||
or is_state('switch.esp_downstmasterbedrmlights_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstbedrm2lights_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstkitchlights_relay_2_kitchen_light', 'on')
|
||||
or is_state('switch.esp_downstkitchlights_relay_1_dining_light', 'on')
|
||||
or is_state('switch.esp_downstbathswitch_relay_1_main_lights', 'on')
|
||||
or is_state('switch.esp_downstbathswitch_relay_2_cabinet_light', 'on')
|
||||
}}
|
||||
- condition: state
|
||||
entity_id: binary_sensor.downstairs_flat_any_lights_on
|
||||
state: "on"
|
||||
sequence:
|
||||
- action: homeassistant.turn_off
|
||||
target:
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
mqtt:
|
||||
sensor:
|
||||
- unique_id: view_road_power_now
|
||||
name: "Power Now"
|
||||
state_topic: "viewroad-status/energy/PowerTotals"
|
||||
unit_of_measurement: "kW"
|
||||
- unique_id: view_road_power_now_red
|
||||
name: "Power Now (Red)"
|
||||
state_topic: "tele/tasmo-wemosd1-7280-powermon-1/SENSOR"
|
||||
unit_of_measurement: "kW"
|
||||
value_template: "{{ value_json.ENERGY.Power[0] }}"
|
||||
- unique_id: view_road_power_now_white
|
||||
name: "Power Now (White)"
|
||||
state_topic: "tele/tasmo-wemosd1-7280-powermon-1/SENSOR"
|
||||
unit_of_measurement: "kW"
|
||||
value_template: "{{ value_json.ENERGY.Power[1] }}"
|
||||
- unique_id: view_road_power_now_blue
|
||||
name: "Power Now (Blue)"
|
||||
state_topic: "tele/tasmo-wemosd1-7280-powermon-1/SENSOR"
|
||||
unit_of_measurement: "kW"
|
||||
value_template: "{{ value_json.ENERGY.Power[2] }}"
|
||||
|
||||
template:
|
||||
- sensor:
|
||||
- name: "Electricity Power Total"
|
||||
unique_id: electricity_power_total
|
||||
unit_of_measurement: "W"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
state: >
|
||||
{{
|
||||
states('sensor.tasmo_wemosd1_7280_powermon_1_energy_power_0') | float(0)
|
||||
+ states('sensor.tasmo_wemosd1_7280_powermon_1_energy_power_1') | float(0)
|
||||
+ states('sensor.tasmo_wemosd1_7280_powermon_1_energy_power_2') | float(0)
|
||||
}}
|
||||
@@ -1,105 +0,0 @@
|
||||
#mqtt:
|
||||
# sensor:
|
||||
# - unique_id: 32a_ev_wallcharger_power
|
||||
# name: "32A EV Wallcharger Power"
|
||||
# device_class: power
|
||||
# unit_of_measurement: kW
|
||||
# state_topic: "stat/tasmo-wemosd1-7280-powermon-1/EnergyMeterCount"
|
||||
# value_template: "{{ value_json.EVChargerWhCount * 2 * 60 / 1000 }}"
|
||||
# - unique_id: 16a_ev_wallcharger_power
|
||||
# name: "16A EV Wallcharger Power"
|
||||
# device_class: power
|
||||
# unit_of_measurement: kW
|
||||
# state_topic: "stat/tasmo-s4chan-7594-garage-1/EnergyMeterCount"
|
||||
# value_template: "{{ value_json.EVChargerWhCount * 2 * 60 / 1000 }}"
|
||||
|
||||
# Use the Riemann sum integral to calculate energy in kWh
|
||||
# from the contimuous power measuring sensors
|
||||
sensor:
|
||||
- platform: integration
|
||||
unique_id: 32a_ev_wallcharger_power_total
|
||||
name: "EV 32A Wallcharger Power Total (Integral)"
|
||||
source: sensor.main_house_3_phase_power_monitor_32a_wallcharger_power
|
||||
#device_class: energy
|
||||
#unit_of_measurement: Wh
|
||||
#unit_time: h
|
||||
#unit_prefix: k # Show in kWh
|
||||
round: 0 # Only need 0 decimals accuracy
|
||||
- platform: integration
|
||||
unique_id: 16a_ev_wallcharger_power_total
|
||||
name: "EV 16A EV Wallcharger Power Total (Integral)"
|
||||
source: sensor.garage_db_control_16a_wallcharger_power
|
||||
#device_class: energy
|
||||
#unit_of_measurement: Wh
|
||||
#unit_time: h
|
||||
#unit_prefix: k
|
||||
round: 0
|
||||
|
||||
# - platform: filter
|
||||
# name: "32A EV Charger Power 1m Avg"
|
||||
# unique_id: ev_charger_32a_power_1m_avg
|
||||
# entity_id: sensor.main_house_3_phase_power_monitor_ev_wallcharger_power
|
||||
# filters:
|
||||
# - filter: time_simple_moving_average
|
||||
# window_size: "00:01"
|
||||
# precision: 3
|
||||
|
||||
input_select:
|
||||
leaf_ev_charging_mode:
|
||||
icon: mdi:ev-plug-type1
|
||||
name: Leaf EV Charge Mode
|
||||
initial: "Normal (Offpeak)"
|
||||
options:
|
||||
- "Normal (Offpeak)"
|
||||
- "Offpeak until charged"
|
||||
- "1hr top-up now"
|
||||
- "Charge now until full"
|
||||
- "Stop charging now"
|
||||
|
||||
automation:
|
||||
- id: set_the_leaf_ev_charging_mode
|
||||
alias: Set the Leaf EV Charging Mode
|
||||
trigger:
|
||||
entity_id: input_select.leaf_ev_charging_mode
|
||||
platform: state
|
||||
action:
|
||||
service: mqtt.publish
|
||||
data:
|
||||
topic: viewroad-status/evcharging/leaf-chargemode
|
||||
payload:
|
||||
'{% set mapping = { "Normal (Offpeak)":"normal", "Offpeak until charged":"offpeak-full",
|
||||
"1hr top-up now":"boost", "Charge now until full":"now-full", "Stop charging now":"stop" } %} {% set dta = trigger.to_state.state %}
|
||||
{{ mapping[dta] }}
|
||||
'
|
||||
#template:
|
||||
# - trigger:
|
||||
# - platform: time_pattern
|
||||
# seconds: "/10"
|
||||
# - platform: homeassistant
|
||||
# event: start
|
||||
# binary_sensor:
|
||||
# - name: "32A EV Charger Charging"
|
||||
# unique_id: ev_charger_32a_charging
|
||||
# icon: mdi:car-electric
|
||||
# state: >-
|
||||
# {{ states('sensor.32a_ev_charger_power_1m_avg') | float(0) > 0.1 }}
|
||||
# delay_on:
|
||||
# seconds: 60
|
||||
# delay_off:
|
||||
# seconds: 60
|
||||
#
|
||||
# - name: "16A EV Charger Charging"
|
||||
# unique_id: ev_charger_16a_charging
|
||||
# icon: mdi:car-electric
|
||||
# state: >-
|
||||
# {{ (states('sensor.16a_ev_wallcharger_power') | float(0)) > 0.1 }}
|
||||
# delay_on:
|
||||
# seconds: 60
|
||||
# delay_off:
|
||||
# seconds: 60
|
||||
#
|
||||
# - binary_sensor:
|
||||
# - name: 32A EV Charger Charging UI
|
||||
# unique_id: ev_charger_charging_ui
|
||||
# state: "{{ is_state('sensor.32a_ev_charger_charging', 'on') }}"
|
||||
# icon: mdi:car-electric
|
||||
@@ -0,0 +1,299 @@
|
||||
###############################################################################
|
||||
# PACKAGE: Free Power Time Automation
|
||||
###############################################################################
|
||||
# VERSION:
|
||||
# 1.0.0 - 2026-05-08
|
||||
# - Initial package.
|
||||
# - Adds editable free power start/end times.
|
||||
# - Adds master enable switch and per-action enable switches.
|
||||
# - Adds announcement, gas-to-heatpump changeover, tool charger control,
|
||||
# and underhouse dehumidifier control.
|
||||
#
|
||||
# NOTES:
|
||||
# - Free power start/end times can be changed in Home Assistant.
|
||||
# - Start time default is 9:00pm.
|
||||
# - End time default is midnight.
|
||||
# - YAML-only gas heater settings are in script.free_power_gas_heater_changeover:
|
||||
# gas_heater_shutdown_delay_seconds
|
||||
# heatpump_setpoint_offset_c
|
||||
#
|
||||
# IMPORTANT:
|
||||
# - input_datetime initial values are used to provide defaults.
|
||||
# - If you later want UI changes to survive every HA restart, remove the
|
||||
# initial lines after the helpers have been created and set once.
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# INPUT DATETIME
|
||||
###############################################################################
|
||||
|
||||
input_datetime:
|
||||
free_power_start_time:
|
||||
name: Free Power - Start Time
|
||||
has_date: false
|
||||
has_time: true
|
||||
initial: "21:00:00"
|
||||
icon: mdi:clock-start
|
||||
|
||||
free_power_end_time:
|
||||
name: Free Power - End Time
|
||||
has_date: false
|
||||
has_time: true
|
||||
initial: "00:00:00"
|
||||
icon: mdi:clock-end
|
||||
|
||||
###############################################################################
|
||||
# ENABLE SWITCHES
|
||||
###############################################################################
|
||||
|
||||
input_boolean:
|
||||
free_power_automation_enabled:
|
||||
name: Free Power - Master Automation Enable
|
||||
icon: mdi:transmission-tower
|
||||
|
||||
free_power_announcement_enabled:
|
||||
name: Free Power - Announcement Enable
|
||||
icon: mdi:bullhorn
|
||||
|
||||
free_power_gas_heater_changeover_enabled:
|
||||
name: Free Power - Gas Heater Changeover Enable
|
||||
icon: mdi:heat-pump-outline
|
||||
|
||||
free_power_tool_battery_chargers_enabled:
|
||||
name: Free Power - Tool Battery Chargers Enable
|
||||
icon: mdi:battery-charging
|
||||
|
||||
free_power_underhouse_dehumidifier_enabled:
|
||||
name: Free Power - Underhouse Dehumidifier Enable
|
||||
icon: mdi:air-humidifier
|
||||
|
||||
###############################################################################
|
||||
# TEMPLATE SENSORS
|
||||
###############################################################################
|
||||
|
||||
template:
|
||||
- binary_sensor:
|
||||
- name: Free Power Time Active
|
||||
unique_id: free_power_time_active
|
||||
icon: mdi:transmission-tower
|
||||
state: >-
|
||||
{% set start = states('input_datetime.free_power_start_time') %}
|
||||
{% set end = states('input_datetime.free_power_end_time') %}
|
||||
{% set now_mins = now().hour * 60 + now().minute %}
|
||||
{% set start_mins = (start[0:2] | int(0)) * 60 + (start[3:5] | int(0)) %}
|
||||
{% set end_mins = (end[0:2] | int(0)) * 60 + (end[3:5] | int(0)) %}
|
||||
|
||||
{% if start_mins == end_mins %}
|
||||
false
|
||||
{% elif start_mins < end_mins %}
|
||||
{{ start_mins <= now_mins < end_mins }}
|
||||
{% else %}
|
||||
{{ now_mins >= start_mins or now_mins < end_mins }}
|
||||
{% endif %}
|
||||
|
||||
###############################################################################
|
||||
# SCRIPTS
|
||||
###############################################################################
|
||||
|
||||
script:
|
||||
free_power_start_actions:
|
||||
alias: Free Power - Start Actions
|
||||
mode: single
|
||||
sequence:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_automation_enabled
|
||||
state: "on"
|
||||
|
||||
- variables:
|
||||
free_power_time_label: >-
|
||||
{%- set raw_time = states('input_datetime.free_power_start_time') -%}
|
||||
{%- set hour = raw_time[0:2] | int(0) -%}
|
||||
{%- set minute = raw_time[3:5] | int(0) -%}
|
||||
{%- set suffix = 'am' if hour < 12 else 'pm' -%}
|
||||
{%- set hour12 = hour % 12 -%}
|
||||
{%- set hour12 = 12 if hour12 == 0 else hour12 -%}
|
||||
{{- hour12 ~ suffix if minute == 0 else hour12 ~ ':' ~ '%02d' | format(minute) ~ suffix -}}
|
||||
|
||||
###########################################################################
|
||||
# 1) Free Power Time Announcement
|
||||
###########################################################################
|
||||
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_announcement_enabled
|
||||
state: "on"
|
||||
then:
|
||||
- action: script.view_road_announcement
|
||||
data:
|
||||
channels: "lounge_google_home_voice, sony_tv_lounge"
|
||||
title: "View Road "
|
||||
short_announcement: "{{ free_power_time_label }}: Free power time"
|
||||
long_announcement: "It is {{ free_power_time_label }}."
|
||||
|
||||
###########################################################################
|
||||
# 2) Gas Heater Changeover
|
||||
###########################################################################
|
||||
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_gas_heater_changeover_enabled
|
||||
state: "on"
|
||||
then:
|
||||
- action: script.free_power_gas_heater_changeover
|
||||
|
||||
###########################################################################
|
||||
# 3) Tool Battery Chargers On
|
||||
###########################################################################
|
||||
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_tool_battery_chargers_enabled
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id:
|
||||
- switch.ryobi_charger_left_power_monitor_x17pp
|
||||
- switch.ryobi_charger_right_power_monitor_x16pp
|
||||
|
||||
###########################################################################
|
||||
# 4) Underhouse Dehumidifier On
|
||||
###########################################################################
|
||||
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_underhouse_dehumidifier_enabled
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_on
|
||||
target:
|
||||
entity_id:
|
||||
- switch.underhouse_dehumidifier_power_plug_x10pp
|
||||
|
||||
free_power_end_actions:
|
||||
alias: Free Power - End Actions
|
||||
mode: single
|
||||
sequence:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_automation_enabled
|
||||
state: "on"
|
||||
|
||||
###########################################################################
|
||||
# 3) Tool Battery Chargers Off
|
||||
#
|
||||
# If this action is enabled, the chargers are switched off at free power
|
||||
# end even if something else turned them on.
|
||||
###########################################################################
|
||||
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_tool_battery_chargers_enabled
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id:
|
||||
- switch.ryobi_charger_left_power_monitor_x17pp
|
||||
- switch.ryobi_charger_right_power_monitor_x16pp
|
||||
|
||||
###########################################################################
|
||||
# 4) Underhouse Dehumidifier Off
|
||||
#
|
||||
# If this action is enabled, the dehumidifier is switched off at free power
|
||||
# end even if something else turned it on.
|
||||
###########################################################################
|
||||
|
||||
- if:
|
||||
- condition: state
|
||||
entity_id: input_boolean.free_power_underhouse_dehumidifier_enabled
|
||||
state: "on"
|
||||
then:
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id:
|
||||
- switch.underhouse_dehumidifier_power_plug_x10pp
|
||||
|
||||
free_power_gas_heater_changeover:
|
||||
alias: Free Power - Gas Heater Changeover
|
||||
mode: single
|
||||
sequence:
|
||||
###########################################################################
|
||||
# YAML-only settings
|
||||
###########################################################################
|
||||
|
||||
- variables:
|
||||
gas_heater_operation_entity: switch.rinnai_neo_gas_heater_heater_operation
|
||||
gas_heater_setpoint_entity: number.rinnai_neo_gas_heater_rinnai_neo_gas_heater_setpoint
|
||||
heatpump_climate_entity: climate.lounge
|
||||
|
||||
gas_heater_shutdown_delay_seconds: 60
|
||||
heatpump_setpoint_offset_c: 0
|
||||
|
||||
heatpump_setpoint: >-
|
||||
{{
|
||||
(
|
||||
(states(gas_heater_setpoint_entity) | float(0))
|
||||
+ (heatpump_setpoint_offset_c | float(0))
|
||||
) | round(1)
|
||||
}}
|
||||
|
||||
###########################################################################
|
||||
# Only change over if the gas heater is currently on.
|
||||
###########################################################################
|
||||
|
||||
- condition: template
|
||||
value_template: "{{ is_state(gas_heater_operation_entity, 'on') }}"
|
||||
|
||||
###########################################################################
|
||||
# Only continue if the gas setpoint can be read.
|
||||
###########################################################################
|
||||
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ states(gas_heater_setpoint_entity) not in ['unknown', 'unavailable', 'none', 'None', ''] }}
|
||||
|
||||
###########################################################################
|
||||
# Set the Panasonic heatpump to heat mode and match the gas heater setpoint,
|
||||
# with the YAML-only offset applied.
|
||||
###########################################################################
|
||||
|
||||
- action: climate.set_temperature
|
||||
target:
|
||||
entity_id: climate.lounge
|
||||
data:
|
||||
hvac_mode: heat
|
||||
temperature: "{{ heatpump_setpoint }}"
|
||||
|
||||
###########################################################################
|
||||
# Give the heatpump time to start before turning the gas heater off.
|
||||
###########################################################################
|
||||
|
||||
- delay:
|
||||
seconds: "{{ gas_heater_shutdown_delay_seconds | int(60) }}"
|
||||
|
||||
- action: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.rinnai_neo_gas_heater_heater_operation
|
||||
|
||||
###############################################################################
|
||||
# AUTOMATIONS
|
||||
###############################################################################
|
||||
|
||||
automation:
|
||||
- id: free_power_time_start_actions
|
||||
alias: Free Power Time - Start Actions
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: time
|
||||
at: input_datetime.free_power_start_time
|
||||
actions:
|
||||
- action: script.free_power_start_actions
|
||||
|
||||
- id: free_power_time_end_actions
|
||||
alias: Free Power Time - End Actions
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: time
|
||||
at: input_datetime.free_power_end_time
|
||||
actions:
|
||||
- action: script.free_power_end_actions
|
||||
@@ -1,19 +0,0 @@
|
||||
mqtt:
|
||||
sensor:
|
||||
- unique_id: gas_heater_operating
|
||||
name: "Gas Heater Operating"
|
||||
state_topic: "viewroad-status/gasheater/operating"
|
||||
switch:
|
||||
- unique_id: gasheater_switch
|
||||
name: "Gas Heater"
|
||||
state_topic: "viewroad-status/gasheater/operating"
|
||||
command_topic: "viewroad-commands/gasheater/onoff"
|
||||
#availability:
|
||||
# - topic: "home/bedroom/switch1/available"
|
||||
payload_on: "ON"
|
||||
payload_off: "OFF"
|
||||
state_on: "ON"
|
||||
state_off: "OFF"
|
||||
optimistic: false
|
||||
qos: 0
|
||||
retain: true # need this, or fire starts on HA reboot. Could fix in Node red too.
|
||||
@@ -0,0 +1,368 @@
|
||||
###############################################################################
|
||||
# PACKAGE: Lounge Blinds - Sunrise / Sunset Automation
|
||||
###############################################################################
|
||||
#
|
||||
# VERSION:
|
||||
# v1.2 - 2026-05-08
|
||||
# - Updated input_boolean.lounge_blinds control logic.
|
||||
# - input_boolean.lounge_blinds ON now closes the blinds.
|
||||
# - input_boolean.lounge_blinds OFF now opens the blinds.
|
||||
# - Removed the sync guard helper.
|
||||
# - Added state checks so cover feedback does not create command loops.
|
||||
#
|
||||
# v1.1 - 2026-05-08
|
||||
# - Added input_boolean.lounge_blinds as a manual control/status helper.
|
||||
# - Added cover state sync back to input_boolean.lounge_blinds.
|
||||
#
|
||||
# v1.0 - 2026-05-08
|
||||
# - Initial package.
|
||||
# - Opens lounge blinds at sunrise.
|
||||
# - Closes lounge blinds at sunset.
|
||||
# - Includes sunrise/sunset minute offsets.
|
||||
# - Includes repeated command attempts for Zigbee reliability.
|
||||
# - Opens blinds in list order: A, B, C.
|
||||
# - Closes blinds in reverse list order: C, B, A.
|
||||
#
|
||||
# NOTES:
|
||||
# - input_boolean.lounge_blinds is treated as:
|
||||
# ON = blinds closed
|
||||
# OFF = blinds open
|
||||
#
|
||||
# - Turning input_boolean.lounge_blinds ON will close the blinds.
|
||||
# - Turning input_boolean.lounge_blinds OFF will open the blinds.
|
||||
# - If all blinds are closed by another method, the boolean will turn ON.
|
||||
# - If all blinds are opened by another method, the boolean will turn OFF.
|
||||
# - If blinds are in a mixed/partial state, the boolean is left unchanged.
|
||||
#
|
||||
# - The blind entity list is inside:
|
||||
# script.lounge_blinds_run_sequence
|
||||
# script.lounge_blinds_sync_status
|
||||
# automation.lounge_blinds_control_from_input_boolean
|
||||
#
|
||||
# - If you add more blinds, update the blind list in those three places.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
input_boolean:
|
||||
lounge_blinds:
|
||||
name: Lounge Blinds Closed
|
||||
icon: mdi:blinds
|
||||
|
||||
input_number:
|
||||
lounge_blinds_sunrise_offset_minutes:
|
||||
name: Lounge Blinds Sunrise Offset
|
||||
icon: mdi:weather-sunset-up
|
||||
min: -180
|
||||
max: 180
|
||||
step: 1
|
||||
mode: box
|
||||
unit_of_measurement: min
|
||||
initial: 0
|
||||
|
||||
lounge_blinds_sunset_offset_minutes:
|
||||
name: Lounge Blinds Sunset Offset
|
||||
icon: mdi:weather-sunset-down
|
||||
min: -180
|
||||
max: 180
|
||||
step: 1
|
||||
mode: box
|
||||
unit_of_measurement: min
|
||||
initial: 0
|
||||
|
||||
lounge_blinds_per_blind_delay_seconds:
|
||||
name: Lounge Blinds Per-Blind Delay
|
||||
icon: mdi:timer-outline
|
||||
min: 0
|
||||
max: 60
|
||||
step: 1
|
||||
mode: box
|
||||
unit_of_measurement: sec
|
||||
initial: 2
|
||||
|
||||
lounge_blinds_command_repeats:
|
||||
name: Lounge Blinds Command Repeats
|
||||
icon: mdi:repeat
|
||||
min: 1
|
||||
max: 5
|
||||
step: 1
|
||||
mode: box
|
||||
initial: 2
|
||||
|
||||
lounge_blinds_retry_delay_seconds:
|
||||
name: Lounge Blinds Retry Delay
|
||||
icon: mdi:timer-refresh-outline
|
||||
min: 0
|
||||
max: 120
|
||||
step: 1
|
||||
mode: box
|
||||
unit_of_measurement: sec
|
||||
initial: 10
|
||||
|
||||
input_datetime:
|
||||
lounge_blinds_next_open_time:
|
||||
name: Lounge Blinds Next Open Time
|
||||
has_date: true
|
||||
has_time: true
|
||||
|
||||
lounge_blinds_next_close_time:
|
||||
name: Lounge Blinds Next Close Time
|
||||
has_date: true
|
||||
has_time: true
|
||||
|
||||
script:
|
||||
lounge_blinds_update_sun_times:
|
||||
alias: Lounge Blinds - Update Sun Times
|
||||
mode: single
|
||||
sequence:
|
||||
- variables:
|
||||
sunrise_offset_seconds: >
|
||||
{{ states('input_number.lounge_blinds_sunrise_offset_minutes') | int(0) * 60 }}
|
||||
sunset_offset_seconds: >
|
||||
{{ states('input_number.lounge_blinds_sunset_offset_minutes') | int(0) * 60 }}
|
||||
next_sunrise_timestamp: >
|
||||
{{ as_timestamp(state_attr('sun.sun', 'next_rising')) + sunrise_offset_seconds }}
|
||||
next_sunset_timestamp: >
|
||||
{{ as_timestamp(state_attr('sun.sun', 'next_setting')) + sunset_offset_seconds }}
|
||||
|
||||
- action: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.lounge_blinds_next_open_time
|
||||
data:
|
||||
datetime: >
|
||||
{{ next_sunrise_timestamp | timestamp_custom('%Y-%m-%d %H:%M:%S', true) }}
|
||||
|
||||
- action: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.lounge_blinds_next_close_time
|
||||
data:
|
||||
datetime: >
|
||||
{{ next_sunset_timestamp | timestamp_custom('%Y-%m-%d %H:%M:%S', true) }}
|
||||
|
||||
lounge_blinds_run_sequence:
|
||||
alias: Lounge Blinds - Run Open/Close Sequence
|
||||
mode: queued
|
||||
fields:
|
||||
blind_action:
|
||||
name: Blind Action
|
||||
description: Use open or close.
|
||||
required: true
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- open
|
||||
- close
|
||||
|
||||
sequence:
|
||||
- variables:
|
||||
blind_list:
|
||||
- cover.lounge_blind_a_xbl11
|
||||
- cover.lounge_blind_b_xbl12
|
||||
- cover.lounge_blind_c_xbl13
|
||||
|
||||
command_repeats: >
|
||||
{{ states('input_number.lounge_blinds_command_repeats') | int(2) }}
|
||||
|
||||
retry_delay_seconds: >
|
||||
{{ states('input_number.lounge_blinds_retry_delay_seconds') | int(10) }}
|
||||
|
||||
per_blind_delay_seconds: >
|
||||
{{ states('input_number.lounge_blinds_per_blind_delay_seconds') | int(2) }}
|
||||
|
||||
- repeat:
|
||||
count: "{{ command_repeats }}"
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ blind_action == 'open' }}"
|
||||
sequence:
|
||||
- repeat:
|
||||
for_each: "{{ blind_list }}"
|
||||
sequence:
|
||||
- action: cover.open_cover
|
||||
target:
|
||||
entity_id: "{{ repeat.item }}"
|
||||
|
||||
- delay:
|
||||
seconds: "{{ per_blind_delay_seconds }}"
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ blind_action == 'close' }}"
|
||||
sequence:
|
||||
- repeat:
|
||||
for_each: "{{ blind_list | reverse | list }}"
|
||||
sequence:
|
||||
- action: cover.close_cover
|
||||
target:
|
||||
entity_id: "{{ repeat.item }}"
|
||||
|
||||
- delay:
|
||||
seconds: "{{ per_blind_delay_seconds }}"
|
||||
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: "{{ repeat.index < command_repeats }}"
|
||||
then:
|
||||
- delay:
|
||||
seconds: "{{ retry_delay_seconds }}"
|
||||
|
||||
- action: script.lounge_blinds_sync_status
|
||||
|
||||
lounge_blinds_sync_status:
|
||||
alias: Lounge Blinds - Sync Status
|
||||
mode: queued
|
||||
sequence:
|
||||
- variables:
|
||||
blind_list:
|
||||
- cover.lounge_blind_a_xbl11
|
||||
- cover.lounge_blind_b_xbl12
|
||||
- cover.lounge_blind_c_xbl13
|
||||
|
||||
blind_states: >
|
||||
{{ expand(blind_list) | map(attribute='state') | list }}
|
||||
|
||||
all_blinds_closed: >
|
||||
{{ blind_states | select('eq', 'closed') | list | count == blind_list | count }}
|
||||
|
||||
all_blinds_open: >
|
||||
{{ blind_states | select('eq', 'open') | list | count == blind_list | count }}
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ all_blinds_closed and is_state('input_boolean.lounge_blinds', 'off') }}
|
||||
sequence:
|
||||
- action: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ all_blinds_open and is_state('input_boolean.lounge_blinds', 'on') }}
|
||||
sequence:
|
||||
- action: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
|
||||
automation:
|
||||
- id: lounge_blinds_update_sun_times
|
||||
alias: Lounge Blinds - Update Sun Times
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: homeassistant
|
||||
event: start
|
||||
|
||||
- platform: time
|
||||
at: "00:05:00"
|
||||
|
||||
- platform: state
|
||||
entity_id:
|
||||
- input_number.lounge_blinds_sunrise_offset_minutes
|
||||
- input_number.lounge_blinds_sunset_offset_minutes
|
||||
|
||||
action:
|
||||
- action: script.lounge_blinds_update_sun_times
|
||||
|
||||
- id: lounge_blinds_open_at_sunrise
|
||||
alias: Lounge Blinds - Open At Sunrise
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: time
|
||||
at: input_datetime.lounge_blinds_next_open_time
|
||||
|
||||
action:
|
||||
- action: script.lounge_blinds_run_sequence
|
||||
data:
|
||||
blind_action: open
|
||||
|
||||
- id: lounge_blinds_close_at_sunset
|
||||
alias: Lounge Blinds - Close At Sunset
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: time
|
||||
at: input_datetime.lounge_blinds_next_close_time
|
||||
|
||||
action:
|
||||
- action: script.lounge_blinds_run_sequence
|
||||
data:
|
||||
blind_action: close
|
||||
|
||||
- id: lounge_blinds_control_from_input_boolean
|
||||
alias: Lounge Blinds - Control From Input Boolean
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
to: "on"
|
||||
|
||||
- platform: state
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
to: "off"
|
||||
|
||||
action:
|
||||
- variables:
|
||||
blind_list:
|
||||
- cover.lounge_blind_a_xbl11
|
||||
- cover.lounge_blind_b_xbl12
|
||||
- cover.lounge_blind_c_xbl13
|
||||
|
||||
blind_states: >
|
||||
{{ expand(blind_list) | map(attribute='state') | list }}
|
||||
|
||||
all_blinds_closed: >
|
||||
{{ blind_states | select('eq', 'closed') | list | count == blind_list | count }}
|
||||
|
||||
all_blinds_open: >
|
||||
{{ blind_states | select('eq', 'open') | list | count == blind_list | count }}
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
state: "on"
|
||||
|
||||
- condition: template
|
||||
value_template: "{{ not all_blinds_closed }}"
|
||||
sequence:
|
||||
- action: script.lounge_blinds_run_sequence
|
||||
data:
|
||||
blind_action: close
|
||||
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: input_boolean.lounge_blinds
|
||||
state: "off"
|
||||
|
||||
- condition: template
|
||||
value_template: "{{ not all_blinds_open }}"
|
||||
sequence:
|
||||
- action: script.lounge_blinds_run_sequence
|
||||
data:
|
||||
blind_action: open
|
||||
|
||||
- id: lounge_blinds_sync_input_boolean_from_cover_states
|
||||
alias: Lounge Blinds - Sync Input Boolean From Cover States
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: homeassistant
|
||||
event: start
|
||||
|
||||
- platform: state
|
||||
entity_id:
|
||||
- cover.lounge_blind_a_xbl11
|
||||
- cover.lounge_blind_b_xbl12
|
||||
- cover.lounge_blind_c_xbl13
|
||||
to: "open"
|
||||
|
||||
- platform: state
|
||||
entity_id:
|
||||
- cover.lounge_blind_a_xbl11
|
||||
- cover.lounge_blind_b_xbl12
|
||||
- cover.lounge_blind_c_xbl13
|
||||
to: "closed"
|
||||
|
||||
action:
|
||||
- action: script.lounge_blinds_sync_status
|
||||
@@ -46,8 +46,10 @@ input_select:
|
||||
- "Select Scene:"
|
||||
- Bright
|
||||
- TV General
|
||||
- Balanced
|
||||
- Movie
|
||||
- Reading On/Off
|
||||
- Dining On/Off
|
||||
- Night Light
|
||||
- Warm Cozy
|
||||
- All Off
|
||||
@@ -106,6 +108,7 @@ script:
|
||||
excluded_scenes:
|
||||
- "Select Scene:"
|
||||
- "Reading On/Off"
|
||||
- "Dining On/Off"
|
||||
#- "Night Light"
|
||||
|
||||
#####################################################################
|
||||
@@ -120,18 +123,20 @@ script:
|
||||
light.esp_lounge6chdimmer_lounge_downlights_centre: 100
|
||||
light.esp_lounge6chdimmer_lounge_downlights_south: 100
|
||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 100
|
||||
switch.esp_loungemiddleswitch_relay_3_downlights_north: "on"
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "on"
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "on" # non dimmable pair
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 90
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 90
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 90
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "on"
|
||||
switch.esp_loungesouthrightswitch_relay_2_wall_washer_right: "on"
|
||||
switch.tasmo_ks811t_0702_lounge_3c: "on"
|
||||
#switch.tasmo_ks811t_0702_lounge_3c: "on"
|
||||
#switch.esp_loungenorthswitch_relay_1_main_lights: "on"
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 100
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 100
|
||||
input_number.openhasp_1_backlight_level: 255
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 100
|
||||
|
||||
TV General:
|
||||
light.esp_lounge6chdimmer_couch_spots_left: 60
|
||||
@@ -143,7 +148,8 @@ script:
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 60
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 60
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 60
|
||||
switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
||||
switch.esp_loungesouthrightswitch_relay_2_wall_washer_right: "off"
|
||||
@@ -151,6 +157,28 @@ script:
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 60
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 60
|
||||
input_number.openhasp_1_backlight_level: 120
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 80
|
||||
|
||||
Balanced:
|
||||
light.esp_lounge6chdimmer_couch_spots_left: 40
|
||||
light.esp_lounge6chdimmer_couch_spots_right: 40
|
||||
#light.esp_lounge6chdimmer_dining_table_light: 100
|
||||
light.esp_lounge6chdimmer_lounge_downlights_centre: 40
|
||||
light.esp_lounge6chdimmer_lounge_downlights_south: 40
|
||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 30
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 50
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 50
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 50
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
||||
switch.esp_loungesouthrightswitch_relay_2_wall_washer_right: "off"
|
||||
#switch.esp_loungenorthswitch_relay_1_main_lights: "on"
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 50
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 50
|
||||
input_number.openhasp_1_backlight_level: 100
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 80
|
||||
|
||||
Movie:
|
||||
light.esp_lounge6chdimmer_couch_spots_left: 20
|
||||
@@ -162,7 +190,8 @@ script:
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 40
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 40
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 40
|
||||
switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
||||
switch.esp_loungesouthrightswitch_relay_2_wall_washer_right: "off"
|
||||
@@ -170,6 +199,17 @@ script:
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 40
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 40
|
||||
input_number.openhasp_1_backlight_level: 15
|
||||
switch.esp_mainkitchenlights_relay_1_main_lights: "off"
|
||||
switch.esp_mainkitchenlights_relay_2_benchtop_lights: "off"
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 40
|
||||
|
||||
Dining On/Off:
|
||||
light.esp_lounge6chdimmer_dining_table_light: "toggle_100"
|
||||
#light.esp_lounge6chdimmer_dining_table_light: 60
|
||||
#light.esp_lounge6chdimmer_lounge_downlights_centre: 45
|
||||
#light.esp_lounge6chdimmer_lounge_downlights_south: 35
|
||||
#light.esp_lounge6chdimmer_lounge_rafter_buttons: 20
|
||||
#switch.tasmo_ks811t_0702_lounge_3c: "on"
|
||||
|
||||
Reading On/Off:
|
||||
light.esp_lounge6chdimmer_couch_spots_left: "toggle_75"
|
||||
@@ -190,14 +230,16 @@ script:
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 5
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 5
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 5
|
||||
switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "off"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
||||
switch.esp_loungesouthrightswitch_relay_2_wall_washer_right: "off"
|
||||
#switch.esp_loungenorthswitch_relay_1_main_lights: "on"
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 5
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 5
|
||||
input_number.openhasp_1_backlight_level: 8
|
||||
input_number.openhasp_1_backlight_level: 10
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 30
|
||||
|
||||
Warm Cozy:
|
||||
light.esp_lounge6chdimmer_couch_spots_left: 20
|
||||
@@ -206,8 +248,9 @@ script:
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 25
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 30
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 30
|
||||
light.tasmo_h801_loungeled1_6180_a: 25
|
||||
light.tasmo_h801_loungeled1_6180_b: 25
|
||||
#light.tasmo_h801_loungeled1_6180_a: 25
|
||||
#light.tasmo_h801_loungeled1_6180_b: 25
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "on"
|
||||
switch.esp_loungesouthrightswitch_relay_2_wall_washer_right: "on"
|
||||
@@ -215,6 +258,7 @@ script:
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 20
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 20
|
||||
input_number.openhasp_1_backlight_level: 12
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 40
|
||||
|
||||
All Off:
|
||||
light.esp_lounge6chdimmer_couch_spots_left: 0
|
||||
@@ -223,7 +267,8 @@ script:
|
||||
light.esp_lounge6chdimmer_lounge_downlights_centre: 0
|
||||
light.esp_lounge6chdimmer_lounge_downlights_south: 0
|
||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 0
|
||||
switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 0
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 0
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 0
|
||||
@@ -234,6 +279,9 @@ script:
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_a_output_set_0_100: 0
|
||||
number.esp_loungepelmetleds2_lounge_pelmet_leds_b_output_set_0_100: 0
|
||||
#input_number.openhasp_1_backlight_level: 100
|
||||
#switch.esp_mainkitchenlights_relay_1_main_lights: "off"
|
||||
#switch.esp_mainkitchenlights_relay_2_benchtop_lights: "off"
|
||||
number.lounge_nspanel_touchscreen_display_brightness: 80
|
||||
|
||||
#########################################################################
|
||||
# REMEMBER LAST SCENE
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
input_text:
|
||||
teams_status:
|
||||
name: Microsoft Teams status
|
||||
icon: mdi:microsoft-teams
|
||||
teams_activity:
|
||||
name: Microsoft Teams activity
|
||||
icon: mdi:phone-off
|
||||
|
||||
sensor:
|
||||
- platform: template
|
||||
sensors:
|
||||
teams_status:
|
||||
friendly_name: "Microsoft Teams status"
|
||||
value_template: "{{states('input_text.teams_status')}}"
|
||||
icon_template: "{{state_attr('input_text.teams_status','icon')}}"
|
||||
unique_id: sensor.teams_status
|
||||
teams_activity:
|
||||
friendly_name: "Microsoft Teams activity"
|
||||
value_template: "{{states('input_text.teams_activity')}}"
|
||||
unique_id: sensor.teams_activity
|
||||
@@ -1,23 +0,0 @@
|
||||
template:
|
||||
- light:
|
||||
- name: "Inverted Quiet time as light"
|
||||
unique_id: inverted_quiet_time_as_light
|
||||
state: "{{ is_state('input_boolean.quiet_time', 'off') }}"
|
||||
turn_on:
|
||||
- service: light.turn_on
|
||||
target:
|
||||
entity_id: light.inverted_quiet_time_light
|
||||
turn_off:
|
||||
- service: light.turn_off
|
||||
target:
|
||||
entity_id: light.inverted_quiet_time_light
|
||||
|
||||
light:
|
||||
- platform: group
|
||||
name: "Entities to keep NSPanel Awake"
|
||||
unique_id: entities_to_keep_nspanel_awake
|
||||
entities:
|
||||
- light.inverted_quiet_time_as_light_2
|
||||
- light.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb
|
||||
- light.tasmo_ifan02_3793_bedrm1_1
|
||||
- light.tasmo_ks811t_3647_bedrm1_1b
|
||||
@@ -0,0 +1,732 @@
|
||||
# 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"
|
||||
@@ -0,0 +1,52 @@
|
||||
automation:
|
||||
- id: nspanel_lounge_controller
|
||||
alias: "NSPanel Master Bedroom Controller"
|
||||
description: ""
|
||||
use_blueprint:
|
||||
path: edwardtfn/nspanel_easy_blueprint.yaml
|
||||
input:
|
||||
nspanel_name: 084fb5b4a94e636d01244b1838156446
|
||||
|
||||
button_page01_label: Lounge Lighting Scenes
|
||||
button_pages_icon_size: "10"
|
||||
|
||||
entity01: script.nspanel_lounge_scene_bright
|
||||
entity01_name: "Bright"
|
||||
entity01_icon: mdi:brightness-7
|
||||
entity01_confirm: false
|
||||
|
||||
entity02: script.nspanel_lounge_scene_tv_general
|
||||
entity02_name: "TV General"
|
||||
entity02_icon: mdi:television
|
||||
entity02_confirm: false
|
||||
|
||||
entity03: script.nspanel_lounge_scene_movie
|
||||
entity03_name: "Movie"
|
||||
entity03_icon: mdi:movie-open
|
||||
entity03_confirm: false
|
||||
|
||||
entity04: script.nspanel_lounge_scene_balanced
|
||||
entity04_name: "Balance"
|
||||
entity04_icon: mdi:scale-balance
|
||||
entity04_confirm: false
|
||||
|
||||
entity05: script.nspanel_lounge_scene_warm_cozy
|
||||
entity05_name: "Warm Cozy"
|
||||
entity05_icon: mdi:fireplace
|
||||
entity05_confirm: false
|
||||
|
||||
entity06: script.nspanel_lounge_scene_reading
|
||||
entity06_name: "Reading On/Off"
|
||||
entity06_icon: mdi:book-open-page-variant
|
||||
entity06_confirm: false
|
||||
|
||||
entity07: script.nspanel_lounge_scene_dining
|
||||
entity07_name: "Dining On/Off"
|
||||
entity07_icon: mdi:silverware-fork-knife
|
||||
entity07_confirm: false
|
||||
|
||||
entity08: script.nspanel_lounge_scene_all_off
|
||||
entity08_name: "All Off"
|
||||
entity08_icon: mdi:power
|
||||
entity08_confirm: false
|
||||
mode: single
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,123 @@
|
||||
################################################################################
|
||||
# Quiet Time Package
|
||||
################################################################################
|
||||
#
|
||||
# TITLE:
|
||||
# Quiet Time
|
||||
#
|
||||
# VERSIONS:
|
||||
# V1.2 2026-05-21
|
||||
# - Added MQTT publishing when input_boolean.quiet_time changes.
|
||||
# - Publishes quiet_time state to viewroad-status/homeassistant/quiet-time.
|
||||
#
|
||||
# V1.1 2026-05-21
|
||||
# - Reduced daily reset check frequency from every minute to every 30 minutes.
|
||||
# - Reduced reset dropdown options to 00:30 through 10:00 only.
|
||||
#
|
||||
# V1.0 2026-05-21
|
||||
# - Initial package.
|
||||
# - Adds input_boolean.quiet_time.
|
||||
# - Adds input_select.quiet_time_daily_reset.
|
||||
# - Adds daily automation to turn quiet_time OFF at the selected reset time.
|
||||
#
|
||||
# OPERATION NOTES:
|
||||
# - input_boolean.quiet_time is the master quiet time toggle.
|
||||
# - Other packages can check input_boolean.quiet_time before sending
|
||||
# announcements, notifications, TTS messages, or similar.
|
||||
# - input_select.quiet_time_daily_reset selects the daily time that quiet_time
|
||||
# will automatically be turned OFF.
|
||||
# - Default reset time is 07:00.
|
||||
# - The quiet_time state is published to MQTT whenever it changes.
|
||||
#
|
||||
# MQTT STATUS:
|
||||
# - Topic:
|
||||
# viewroad-status/homeassistant/quiet-time
|
||||
# - Payload:
|
||||
# on
|
||||
# off
|
||||
#
|
||||
################################################################################
|
||||
|
||||
################################################################################
|
||||
# INPUT BOOLEAN
|
||||
################################################################################
|
||||
|
||||
input_boolean:
|
||||
quiet_time:
|
||||
name: Quiet Time
|
||||
icon: mdi:bell-off
|
||||
|
||||
################################################################################
|
||||
# INPUT SELECT
|
||||
################################################################################
|
||||
|
||||
input_select:
|
||||
quiet_time_daily_reset:
|
||||
name: Quiet time daily reset
|
||||
icon: mdi:clock-end
|
||||
options:
|
||||
- "00:30"
|
||||
- "01:00"
|
||||
- "01:30"
|
||||
- "02:00"
|
||||
- "02:30"
|
||||
- "03:00"
|
||||
- "03:30"
|
||||
- "04:00"
|
||||
- "04:30"
|
||||
- "05:00"
|
||||
- "05:30"
|
||||
- "06:00"
|
||||
- "06:30"
|
||||
- "07:00"
|
||||
- "07:30"
|
||||
- "08:00"
|
||||
- "08:30"
|
||||
- "09:00"
|
||||
- "09:30"
|
||||
- "10:00"
|
||||
initial: "07:00"
|
||||
|
||||
################################################################################
|
||||
# AUTOMATIONS
|
||||
################################################################################
|
||||
|
||||
automation:
|
||||
- id: quiet_time_daily_reset_turn_off
|
||||
alias: "Quiet Time - Daily Reset Off"
|
||||
description: "Turns Quiet Time off once per day at the selected reset time."
|
||||
mode: single
|
||||
|
||||
triggers:
|
||||
- trigger: time_pattern
|
||||
minutes: "/30"
|
||||
seconds: "0"
|
||||
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: input_boolean.quiet_time
|
||||
state: "on"
|
||||
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ states('input_select.quiet_time_daily_reset') == now().strftime('%H:%M') }}
|
||||
|
||||
actions:
|
||||
- action: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.quiet_time
|
||||
|
||||
- id: quiet_time_settings_to_mqtt
|
||||
alias: "Publish quiet time value to MQTT"
|
||||
description: "Publishes the Quiet Time boolean state to MQTT whenever it changes."
|
||||
mode: single
|
||||
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: input_boolean.quiet_time
|
||||
|
||||
actions:
|
||||
- action: mqtt.publish
|
||||
data:
|
||||
topic: viewroad-status/homeassistant/quiet-time
|
||||
payload: "{{ trigger.to_state.state }}"
|
||||
@@ -1,4 +0,0 @@
|
||||
# Text to speech
|
||||
tts:
|
||||
platform: google_translate
|
||||
service_name: google_say
|
||||
@@ -343,6 +343,31 @@ script:
|
||||
- condition: template
|
||||
value_template: "{{ ann_voice_message | string | trim | length > 0 }}"
|
||||
then:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ lounge_google_home_voice_suppress_cast_chime | bool(false) }}"
|
||||
- condition: template
|
||||
value_template: "{{ states(lounge_google_home_voice_media_player) in ['off', 'unavailable', 'unknown'] }}"
|
||||
sequence:
|
||||
- action: media_player.volume_set
|
||||
data:
|
||||
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
||||
volume_level: 0
|
||||
|
||||
- action: media_player.turn_on
|
||||
target:
|
||||
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
||||
|
||||
- wait_template: >-
|
||||
{{ states(lounge_google_home_voice_media_player) in ['idle', 'paused', 'playing', 'on'] }}
|
||||
timeout:
|
||||
seconds: 5
|
||||
continue_on_timeout: true
|
||||
|
||||
- delay:
|
||||
seconds: 1
|
||||
|
||||
- action: media_player.volume_set
|
||||
data:
|
||||
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
||||
|
||||
Reference in New Issue
Block a user