###################################################################### # @CCOSTAN - Follow Me on X # For more info visit https://www.vcloudinfo.com/click-here # Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig # ------------------------------------------------------------------- # Kiosk Tablets - Fully recovery and Kiosk Satellite display policy # Keeps the Bedroom tablet stable and drives state-based Kitchen Show camera views. # ------------------------------------------------------------------- # Related Issue: 1875 # Related Issue: 1890 # Related Issue: 1895 # Notes: `/dashboard-bedroom/home` remains the canonical desktop/future-hardware route. # Notes: The Android 5 Fully tablet uses `/local/bedroom-kiosk.html`, a lightweight renderer. # Notes: Shared camera, header, and alert sensors keep both Bedroom renderers DRY. # Notes: Fully controls apply only to the legacy Bedroom tablet. # Notes: Kitchen Show uses Kiosk Satellite's native ESPHome entities; `_2` is the live set while legacy MQTT registry entries coexist. # Notes: Kiosk Satellite owns HA kiosk-mode hiding, connection recovery, HA camera import, and HLS-first playback; no kiosk-mode custom resource is loaded. # Notes: Kitchen Show uses the Dim screensaver while empty or `group.bed` is on; true panel-off is disabled because this Crown build naps Wi-Fi and cannot accept a remote wake. # Notes: Kitchen Show volume is corrected to 13% at 08:00 and after HA or kiosk startup; manual changes otherwise persist. # Notes: Garage and Front Door retain priority; a Driveway alert takes over both kiosks until occupancy clears or ten minutes elapse. # Notes: At 07:00, Home Assistant stages a pending Kiosk Satellite release, then dispatches Joanna daily until installation is verified. # Notes: Wake events only restore brightness/focus; URL reloads require page drift. # Notes: Fully auto-reload on screen-on/screensaver-stop is disabled to avoid motion wake reload loops. # Notes: Startup recovery waits for HA's initial websocket state burst to settle. # Notes: Brightness recovery only runs when both SleepIQ in-bed sensors are off. # Notes: Fully availability/page/app/power plus Kitchen connectivity, current-page/screenshot freshness, and update state feed Systems telemetry. # Notes: Kitchen updates are advisory telemetry and do not raise kiosk or Systems fault rollups. # Notes: Kiosk attention sensors expose only their stable status attribute so recorder preserves problem transitions without heartbeat churn. # Notes: Nearby daytime rain or lightning starts a five-minute NOAA radar view; the ambient banner offers daylight replay while the event remains active. # Notes: Actionable Kitchen banner slides open one shared short-lived detail surface; camera events retain priority. # Notes: Phyn detail can restore a closed main valve only after an explicit on-screen confirmation. # Notes: Rheem faults outrank low-hot-water reminders and reuse the hot-water diagnostic detail surface. # Video: https://youtu.be/ChgEu0IDWzc ###################################################################### input_text: kitchen_kiosk_detail_view: name: "Kitchen Kiosk Detail View" initial: none max: 128 timer: kitchen_kiosk_radar_display: name: "Kitchen Kiosk Radar Display" duration: "00:05:00" restore: true icon: mdi:radar kitchen_kiosk_detail_display: name: "Kitchen Kiosk Detail Display" duration: "00:03:00" restore: false icon: mdi:card-text-outline kiosk_driveway_camera_display: name: "Kiosk Driveway Camera Display" duration: "00:10:00" restore: false icon: mdi:car-search automation: - alias: "Bedroom Kiosk Tablet - Return to Kiosk View" id: 11e50d2e-f66f-4fd0-86f4-bdca075c3a1c mode: single max_exceeded: silent trigger: - platform: state entity_id: switch.alarm_panel_1_screen to: "on" for: "00:00:03" id: wake - platform: state entity_id: switch.alarm_panel_1_screensaver to: "off" for: "00:00:03" id: wake - platform: state entity_id: - sensor.alarm_panel_1_current_page - sensor.alarm_panel_1_foreground_app - number.alarm_panel_1_screen_brightness for: "00:00:10" id: drift - platform: time_pattern minutes: "/1" id: periodic - platform: homeassistant event: start id: startup condition: - condition: state entity_id: switch.alarm_panel_1_screen state: "on" - condition: state entity_id: switch.alarm_panel_1_screensaver state: "off" - condition: template value_template: >- {% set current_page = states('sensor.alarm_panel_1_current_page') %} {% set foreground_app = states('sensor.alarm_panel_1_foreground_app') %} {% set brightness = states('number.alarm_panel_1_screen_brightness') %} {% set bed_clear = is_state('binary_sensor.sleepnumber_carlo_carlo_is_in_bed', 'off') and is_state('binary_sensor.sleepnumber_carlo_stacey_is_in_bed', 'off') %} {% set invalid = ['unknown', 'unavailable', 'none', ''] %} {{ (current_page not in invalid and '/local/bedroom-kiosk.html' not in current_page) or (foreground_app not in invalid and foreground_app != 'de.ozerov.fully') or (bed_clear and brightness not in invalid and brightness | float(100) < 40) }} action: - choose: - conditions: - condition: trigger id: startup sequence: - delay: "00:02:00" - variables: previous_page: "{{ states('sensor.alarm_panel_1_current_page') }}" previous_app: "{{ states('sensor.alarm_panel_1_foreground_app') }}" previous_brightness: "{{ states('number.alarm_panel_1_screen_brightness') }}" invalid: - unknown - unavailable - none - "" - variables: brightness_low: >- {{ is_state('binary_sensor.sleepnumber_carlo_carlo_is_in_bed', 'off') and is_state('binary_sensor.sleepnumber_carlo_stacey_is_in_bed', 'off') and previous_brightness not in invalid and previous_brightness | float(100) < 40 }} foreground_drift: >- {{ previous_app not in invalid and previous_app != 'de.ozerov.fully' }} page_drift: >- {{ previous_page not in invalid and '/local/bedroom-kiosk.html' not in previous_page }} - choose: - conditions: - condition: template value_template: "{{ brightness_low | bool }}" sequence: - service: number.set_value target: entity_id: number.alarm_panel_1_screen_brightness data: value: 100 - choose: - conditions: - condition: template value_template: "{{ foreground_drift | bool }}" sequence: - service: button.press target: entity_id: button.alarm_panel_1_bring_to_foreground - choose: - conditions: - condition: template value_template: "{{ page_drift | bool }}" sequence: - choose: - conditions: - condition: template value_template: "{{ foreground_drift | bool }}" sequence: - delay: "00:00:02" - service: button.press target: entity_id: button.alarm_panel_1_load_start_url - service: script.send_to_logbook data: topic: "KIOSK" message: >- Bedroom tablet reloaded after page drift from {{ previous_page }} (foreground app: {{ previous_app }}; brightness: {{ previous_brightness }}). - alias: "Kitchen Kiosk Satellite - State Camera Policy" id: 4c3ddc5b-1fe2-4c11-a77c-e2c15d374e77 mode: restart trigger: - platform: state entity_id: sensor.kiosk_active_camera_view condition: - condition: state entity_id: binary_sensor.kitchen_kiosk_should_be_on state: "on" action: - service: script.kitchen_kiosk_apply_camera_policy - alias: "Kitchen Kiosk Satellite - Screen Policy" id: 99d8d43b-9448-4916-b313-8117a038baaf mode: restart trigger: - platform: time at: "08:00:00" id: daily_volume - platform: homeassistant event: start id: startup_volume - platform: state entity_id: binary_sensor.kitchen_kiosk_should_be_on to: "on" - platform: state entity_id: light.kitchen_show_screen_2 to: "on" - platform: state entity_id: light.kitchen_show_screen_2 to: "off" - platform: state entity_id: binary_sensor.kitchen_show_connectivity_2 to: "on" id: startup_volume - platform: state entity_id: switch.kitchen_show_keep_screen_on_2 to: "off" - platform: state entity_id: binary_sensor.kitchen_kiosk_should_be_on to: "off" action: - if: - condition: template value_template: >- {{ trigger is defined and trigger.id in ['daily_volume', 'startup_volume'] }} - condition: template value_template: >- {% set volume = states('number.kitchen_show_volume_2') %} {{ volume not in ['unknown', 'unavailable', 'none', ''] and (volume | float(-1)) != 13.0 }} then: - service: number.set_value target: entity_id: number.kitchen_show_volume_2 data: value: 13 - condition: template value_template: >- {{ states('binary_sensor.kitchen_kiosk_should_be_on') in ['on', 'off'] }} - choose: - conditions: - condition: state entity_id: binary_sensor.kitchen_kiosk_should_be_on state: "on" sequence: # Keep Android from entering true panel-off and napping Wi-Fi. # Kiosk Satellite's Dim screensaver still owns idle brightness. - service: switch.turn_on target: entity_id: switch.kitchen_show_keep_screen_on_2 - service: light.turn_on target: entity_id: light.kitchen_show_screen_2 - service: button.press target: entity_id: button.kitchen_show_postpone_screensaver_2 - service: script.kitchen_kiosk_apply_camera_policy default: # This Crown build drops Wi-Fi in true panel-off, so preserve the # reachable display session and let the Dim screensaver go dark. - service: switch.turn_on target: entity_id: switch.kitchen_show_keep_screen_on_2 - service: timer.cancel target: entity_id: timer.kitchen_kiosk_detail_display - service: button.press target: entity_id: button.kitchen_show_close_camera_view_2 - service: light.turn_on target: entity_id: light.kitchen_show_screen_2 - service: switch.turn_on target: entity_id: switch.kitchen_show_screensaver_active_2 - alias: "Kitchen Kiosk Satellite - Daylight Radar Trigger" id: 411dc0c0-a291-48e7-a493-2481a8d9477d description: "Show NOAA radar for five minutes when a nearby daytime rain or lightning event begins." mode: restart trigger: - platform: state entity_id: binary_sensor.kiosk_rain_radar_weather_event to: "on" condition: - condition: state entity_id: binary_sensor.kiosk_rain_radar_weather_event state: "on" - condition: state entity_id: timer.kitchen_kiosk_radar_display state: idle action: - service: script.kitchen_kiosk_show_event data: event_type: radar - alias: "Kitchen Kiosk Satellite - Clear Detail View" id: 17bef67a-f68e-4b57-b04c-c2b890fafb77 description: "Clear transient banner detail state after timeout or household shutdown." mode: restart trigger: - platform: event event_type: timer.finished event_data: entity_id: timer.kitchen_kiosk_detail_display - platform: event event_type: timer.cancelled event_data: entity_id: timer.kitchen_kiosk_detail_display action: - service: input_text.set_value target: entity_id: input_text.kitchen_kiosk_detail_view data: value: none - alias: "Kitchen Kiosk Satellite - Refresh Systems Snapshot" id: e920cab1-59d3-4d45-8aad-67170127504f description: "Reconcile an active startup storm, then refresh the Systems dashboard screenshot." mode: single max_exceeded: silent trigger: - platform: event event_type: homeassistant_started id: startup - platform: time_pattern minutes: "/15" id: periodic action: - delay: "{{ '00:03:00' if trigger.id == 'startup' else '00:00:00' }}" - choose: - conditions: - condition: trigger id: startup sequence: - service: automation.trigger target: entity_id: automation.kitchen_kiosk_satellite_daylight_radar_trigger data: skip_condition: false - condition: template value_template: >- {% set last_seen = as_timestamp(states('sensor.kitchen_show_last_seen_2'), 0) %} {{ last_seen > 0 and (as_timestamp(now()) - last_seen) < 300 }} - service: button.press target: entity_id: button.kitchen_show_take_screenshot_2 - alias: "Kitchen Kiosk Satellite - Update Joanna Dispatch" id: 199e30f0-e28c-4842-953d-a65bc4b4e1d3 description: "At 07:00, stage and dispatch Joanna daily while a Kiosk Satellite release remains pending for the Kitchen Show." mode: single max_exceeded: silent trigger: - platform: time at: "07:00:00" condition: - condition: state entity_id: update.kitchen_show_update_2 state: "on" - condition: template value_template: >- {% set installed = state_attr('update.kitchen_show_update_2', 'installed_version') | default('', true) | string %} {% set latest = state_attr('update.kitchen_show_update_2', 'latest_version') | default('', true) | string %} {{ installed not in ['', 'unknown', 'unavailable'] and latest not in ['', 'unknown', 'unavailable'] and installed != latest }} action: - variables: installed_version: >- {{ state_attr('update.kitchen_show_update_2', 'installed_version') | default('unknown', true) }} latest_version: >- {{ state_attr('update.kitchen_show_update_2', 'latest_version') | default('unknown', true) }} release_url: >- {{ state_attr('update.kitchen_show_update_2', 'release_url') | default('not provided', true) }} structured_request: |- KITCHEN_KIOSK_SATELLITE_UPDATE_REQUEST target_device=Kitchen Show update_entity=update.kitchen_show_update_2 installed_version={{ installed_version }} target_version={{ latest_version }} release_url={{ release_url }} authorization=This dispatch authorizes installing the pending Kiosk Satellite application update on the Kitchen Show only. Do not update LineageOS, Home Assistant, or unrelated applications and do not factory-reset or re-enroll the tablet. required_action=Home Assistant already invoked update.install and allowed two minutes for the signed installer payload to stage. If the update is still pending, use the pre-authorized Joanna ops helper /opt/codex/bin/kitchen-kiosk-update --expected-version {{ latest_version }} to complete this Kiosk Satellite update over the existing LAN-only management path. required_verification=Do not stop at a successful service call. Verify update.kitchen_show_update_2 reports installed_version equal to latest_version, in_progress is false, the Kitchen Show returns online, sensor.kitchen_show_current_page_2 is the expected kiosk dashboard, sensor.kitchen_show_remote_admin_2 is available, and a fresh screenshot can be requested. failure_policy=If the signed release cannot be installed safely or the device does not recover, stop without changing unrelated software and report the blocking evidence. - service: update.install continue_on_error: true target: entity_id: update.kitchen_show_update_2 - delay: "00:02:00" - condition: state entity_id: update.kitchen_show_update_2 state: "on" - service: script.send_to_logbook data: topic: "KIOSK" message: >- Home Assistant staged and Joanna dispatched Kitchen Show Kiosk Satellite from {{ installed_version }} to {{ latest_version }}. - service: script.joanna_dispatch data: trigger_context: "HA automation kitchen_kiosk_satellite_update_joanna_dispatch (Kitchen Kiosk Satellite - Update Joanna Dispatch)" source: "home_assistant_automation.kitchen_kiosk_satellite_update_dispatch" summary: >- Kiosk Satellite {{ latest_version }} is available for Kitchen Show; installed version is {{ installed_version }}. request: "{{ structured_request }}" entity_ids: - update.kitchen_show_update_2 - sensor.kitchen_show_last_seen_2 - sensor.kitchen_show_current_page_2 - sensor.kitchen_show_remote_admin_2 - button.kitchen_show_take_screenshot_2 diagnostics: >- update_state={{ states('update.kitchen_show_update_2') }}; in_progress={{ state_attr('update.kitchen_show_update_2', 'in_progress') }}; last_seen={{ states('sensor.kitchen_show_last_seen_2') }}; current_page={{ states('sensor.kitchen_show_current_page_2') }}; remote_admin={{ states('sensor.kitchen_show_remote_admin_2') }} template: - sensor: - name: "Kiosk Active Camera View" unique_id: kiosk_active_camera_view icon: mdi:camera-switch state: >- {% if is_state('binary_sensor.kiosk_garage_camera_active', 'on') %} garage {% elif is_state('lock.front_door', 'unlocked') %} front_door {% elif is_state('timer.kiosk_driveway_camera_display', 'active') %} driveway {% else %} none {% endif %} - name: "Bedroom Kiosk Header" unique_id: bedroom_kiosk_header icon: mdi:bed-clock state: >- {% set alarm = states('sensor.bedroom_next_wake_alarm') %} {% set alarm_ts = as_timestamp(alarm, none) %} {% set alarm_source = states('sensor.bedroom_next_wake_alarm_source') | replace(' Bedroom', '') %} {% if alarm_ts is not none %} NEXT ALARM - {{ alarm_source }} · {{ alarm_ts | timestamp_custom('%a %-I:%M %p') }} {% else %} NO BEDROOM WAKE ALARM SET {% endif %} attributes: detail: >- {% set weather = states('weather.pirateweather') | replace('_', ' ') | title %} {% set temperature = state_attr('weather.pirateweather', 'temperature') %} {% set secure = is_state('group.garage_doors', 'closed') and is_state('group.locks', 'locked') and is_state('group.entry_points', 'off') %} {{ 'House secured' if secure else 'Check house security' }} · {{ temperature | round(0) if temperature is number else '--' }}° · {{ weather }} - name: "Kiosk Household Alert" unique_id: kiosk_household_alert icon: mdi:message-alert-outline state: >- {% set alerts = state_attr('sensor.nws_alerts_alerts', 'Alerts') | default([], true) %} {% set hot_water = states('sensor.rheem_wh_available_hot_water') | float(100) %} {% set rheem_alert_count = states('sensor.rheem_wh_alert_count') | int(0) %} {% set tomorrow = (now() + timedelta(days=1)).strftime('%Y-%m-%d') %} {% set battery = states('sensor.spaceship_battery_level') | float(100) %} {% set ns = namespace(name='', raw='') %} {% for name, person, location in [ ('Carlo', 'person.carlo', 'sensor.carlo_location_display'), ('Stacey', 'person.stacey', 'sensor.stacey_location_display'), ('Justin', 'person.justin', 'sensor.justin_location_display'), ('Paige', 'person.paige', 'sensor.paige_location_display') ] %} {% if not ns.name and states(person) not in ['home', 'unknown', 'unavailable'] %} {% set ns.name = name %} {% set ns.raw = states(location) if states(location) not in ['unknown', 'unavailable'] else states(person) %} {% endif %} {% endfor %} {% if alerts | count > 0 %} WEATHER ALERT - {{ alerts[0].Event | default('National Weather Service') }} {% elif is_state('binary_sensor.front_door_packages_present', 'on') %} PACKAGE AT THE FRONT DOOR {% elif is_state('group.entry_points', 'on') %} ENTRY POINT OPEN {% elif states('group.locks') not in ['locked', 'unknown', 'unavailable'] %} CHECK THE FRONT DOOR LOCK {% elif rheem_alert_count > 0 %} WATER HEATER ALERT - {{ rheem_alert_count }} ACTIVE {% elif hot_water < 30 %} HOT WATER IS RUNNING LOW {% elif now().strftime('%a') in ['Wed', 'Sun'] and not is_state('input_boolean.garbage_cans_out', 'on') %} {{ 'GARBAGE + RECYCLING' if now().strftime('%a') == 'Wed' else 'GARBAGE' }} DAY {% elif states('input_datetime.water_delivery_date') == tomorrow %} WATER DELIVERY TOMORROW {% elif battery < 50 and is_state('switch.spaceship_charge', 'off') and is_state('person.carlo', 'home') and is_state('person.stacey', 'home') %} PLUG IN THE TESLA {% elif ns.name %} {% set location = ns.raw | replace(ns.name ~ ' ', '') %} {{ ns.name }} - {{ location.split(' (since ')[0] }} {% else %} EVERYTHING IS HANDLED {% endif %} attributes: detail: >- {% set alerts = state_attr('sensor.nws_alerts_alerts', 'Alerts') | default([], true) %} {% set hot_water = states('sensor.rheem_wh_available_hot_water') | float(100) %} {% set rheem_alert_count = states('sensor.rheem_wh_alert_count') | int(0) %} {% set tomorrow = (now() + timedelta(days=1)).strftime('%Y-%m-%d') %} {% set battery = states('sensor.spaceship_battery_level') | float(100) %} {% set ns = namespace(name='', raw='') %} {% for name, person, location in [ ('Carlo', 'person.carlo', 'sensor.carlo_location_display'), ('Stacey', 'person.stacey', 'sensor.stacey_location_display'), ('Justin', 'person.justin', 'sensor.justin_location_display'), ('Paige', 'person.paige', 'sensor.paige_location_display') ] %} {% if not ns.name and states(person) not in ['home', 'unknown', 'unavailable'] %} {% set ns.name = name %} {% set ns.raw = states(location) if states(location) not in ['unknown', 'unavailable'] else states(person) %} {% endif %} {% endfor %} {% if alerts | count > 0 %} {{ (alerts[0].Headline | default(alerts[0].Description, true)) | replace('\n', ' ') | truncate(300, true) }} {% elif is_state('binary_sensor.front_door_packages_present', 'on') %} Remember to bring it inside. {% elif is_state('group.entry_points', 'on') %} Check the exterior doors and windows. {% elif states('group.locks') not in ['locked', 'unknown', 'unavailable'] %} Lock status is {{ states('group.locks') | replace('_', ' ') }}. {% elif rheem_alert_count > 0 %} Rheem reports {{ rheem_alert_count }} active {{ 'alert' if rheem_alert_count == 1 else 'alerts' }}. Status is {{ states('sensor.rheem_wh_diagnostic_status') | replace('_', ' ') }}. Check Home Assistant Repairs for the diagnostic snapshot. {% elif hot_water < 30 %} {{ hot_water | round(0) }}% is available - keep showers short. {% elif now().strftime('%a') in ['Wed', 'Sun'] and not is_state('input_boolean.garbage_cans_out', 'on') %} Put the cans at the curb. {% elif states('input_datetime.water_delivery_date') == tomorrow %} Put the empty bottles out. {% elif battery < 50 and is_state('switch.spaceship_charge', 'off') and is_state('person.carlo', 'home') and is_state('person.stacey', 'home') %} Model Y battery is {{ battery | round(0) }}%. {% elif ns.name %} {% set parts = ns.raw.split(' (since ') %} {{ 'Since ' ~ (parts[1] | replace(')', '')) if parts | count > 1 else 'Away from home' }} {% else %} No active household alerts or reminders. {% endif %} - binary_sensor: - name: "Kiosk Garage Camera Active" unique_id: kiosk_garage_camera_active icon: mdi:garage-alert delay_off: "00:03:00" state: >- {{ states('cover.large_garage_door') in ['opening', 'open', 'closing'] or states('cover.small_garage_door') in ['opening', 'open', 'closing'] }} - name: "Kiosk Rain Radar Weather Event" unique_id: kiosk_rain_radar_weather_event icon: mdi:radar delay_on: "00:02:00" state: >- {% set invalid = ['unknown', 'unavailable', 'none', ''] %} {% set precip = states('sensor.pirateweather_precip') | lower %} {% set intensity = states('sensor.pirateweather_precip_intensity') | float(0) %} {% set storm_distance_state = states('sensor.pirateweather_nearest_storm_distance') %} {% set storm_distance_miles = storm_distance_state | float(999) %} {% set lightning_count = states('sensor.blitzortung_lightning_counter') | int(0) %} {% set lightning_distance_state = states('sensor.blitzortung_lightning_distance') %} {% set lightning_distance_miles = lightning_distance_state | float(9999) / 1.609344 %} {{ is_state('binary_sensor.kitchen_kiosk_should_be_on', 'on') and is_state('sun.sun', 'above_horizon') and ( precip == 'rain' or intensity > 0.2 or (storm_distance_state not in invalid and storm_distance_miles <= 10) or (lightning_count > 0 and lightning_distance_state not in invalid and lightning_distance_miles <= 10) ) }} - name: "Kiosk Rain Radar Active" unique_id: kiosk_rain_radar_active icon: mdi:radar state: >- {{ is_state('binary_sensor.kitchen_kiosk_should_be_on', 'on') and is_state('sun.sun', 'above_horizon') and is_state('timer.kitchen_kiosk_radar_display', 'active') }} - name: "Kitchen Kiosk Should Be On" unique_id: kitchen_kiosk_should_be_on icon: mdi:monitor-eye state: >- {% set guest = is_state('input_boolean.guest_mode', 'on') %} {% set sitter = is_state('input_boolean.house_sitter_present', 'on') %} {% set family_home = is_state('group.family', 'home') %} {% set bedtime = is_state('group.bed', 'on') %} {{ guest or sitter or (family_home and not bedtime) }} attributes: reason: >- {% if is_state('input_boolean.guest_mode', 'on') %} guest mode {% elif is_state('input_boolean.house_sitter_present', 'on') %} house sitter present {% elif not is_state('group.family', 'home') %} nobody home {% elif is_state('group.bed', 'on') %} bed occupied {% else %} household active {% endif %} - name: "Bedroom Kiosk Needs Attention" unique_id: bedroom_kiosk_needs_attention device_class: problem icon: mdi:tablet-alert delay_on: "00:02:00" delay_off: "00:00:30" state: >- {% set invalid = ['unknown', 'unavailable', 'none', ''] %} {% set page = states('sensor.alarm_panel_1_current_page') %} {% set app = states('sensor.alarm_panel_1_foreground_app') %} {% set battery = states('sensor.alarm_panel_1_battery') | float(0) %} {{ page in invalid or app in invalid or '/local/bedroom-kiosk.html' not in page or app != 'de.ozerov.fully' or (battery < 20 and not is_state('binary_sensor.alarm_panel_1_plugged_in', 'on')) }} attributes: status: >- {% set invalid = ['unknown', 'unavailable', 'none', ''] %} {% set page = states('sensor.alarm_panel_1_current_page') %} {% set app = states('sensor.alarm_panel_1_foreground_app') %} {% set battery = states('sensor.alarm_panel_1_battery') | float(0) %} {% if page in invalid or app in invalid %} offline {% elif '/local/bedroom-kiosk.html' not in page %} page drift {% elif app != 'de.ozerov.fully' %} app drift {% elif battery < 20 and not is_state('binary_sensor.alarm_panel_1_plugged_in', 'on') %} low battery {% else %} online {% endif %} - name: "Kitchen Kiosk Needs Attention" unique_id: kitchen_kiosk_needs_attention device_class: problem icon: mdi:monitor-alert delay_on: "00:02:00" delay_off: "00:00:30" state: >- {% set invalid = ['unknown', 'unavailable', 'none', ''] %} {% set screenshot = as_timestamp(states('sensor.kitchen_show_last_screenshot_2'), 0) %} {% set page = states('sensor.kitchen_show_current_page_2') %} {% set remote_admin = states('sensor.kitchen_show_remote_admin_2') %} {% set connectivity = states('binary_sensor.kitchen_show_connectivity_2') %} {% set battery = states('sensor.kitchen_show_battery_2') | float(0) %} {% set device_offline = connectivity != 'on' %} {% set screenshot_stale = screenshot == 0 or (as_timestamp(now()) - screenshot) > 2700 %} {{ device_offline or page in invalid or remote_admin in invalid or '/dashboard-kiosk-satellite-staging/home' not in page or (battery < 20 and not is_state('binary_sensor.kitchen_show_charging_2', 'on')) or screenshot_stale }} attributes: status: >- {% set invalid = ['unknown', 'unavailable', 'none', ''] %} {% set screenshot = as_timestamp(states('sensor.kitchen_show_last_screenshot_2'), 0) %} {% set page = states('sensor.kitchen_show_current_page_2') %} {% set remote_admin = states('sensor.kitchen_show_remote_admin_2') %} {% set connectivity = states('binary_sensor.kitchen_show_connectivity_2') %} {% set battery = states('sensor.kitchen_show_battery_2') | float(0) %} {% if connectivity != 'on' %} offline {% elif page in invalid or remote_admin in invalid %} telemetry unavailable {% elif '/dashboard-kiosk-satellite-staging/home' not in page %} page drift {% elif battery < 20 and not is_state('binary_sensor.kitchen_show_charging_2', 'on') %} low battery {% elif screenshot == 0 or (as_timestamp(now()) - screenshot) > 2700 %} screenshot stale {% elif is_state('update.kitchen_show_update_2', 'on') %} update available {% else %} online {% endif %} - name: "Kiosk Devices Need Attention" unique_id: kiosk_devices_need_attention device_class: problem icon: mdi:tablet-cellphone state: >- {{ is_state('binary_sensor.bedroom_kiosk_needs_attention', 'on') or is_state('binary_sensor.kitchen_kiosk_needs_attention', 'on') }} attributes: status: >- {% set bedroom = is_state('binary_sensor.bedroom_kiosk_needs_attention', 'on') %} {% set kitchen = is_state('binary_sensor.kitchen_kiosk_needs_attention', 'on') %} {% if bedroom and kitchen %} Bedroom and Kitchen need attention {% elif bedroom %} Bedroom needs attention {% elif kitchen %} Kitchen needs attention {% else %} All kiosks online {% endif %} devices: >- {% set ns = namespace(items=[]) %} {% if is_state('binary_sensor.bedroom_kiosk_needs_attention', 'on') %} {% set ns.items = ns.items + ['Bedroom'] %} {% endif %} {% if is_state('binary_sensor.kitchen_kiosk_needs_attention', 'on') %} {% set ns.items = ns.items + ['Kitchen'] %} {% endif %} {{ ns.items }} script: kitchen_kiosk_apply_camera_policy: alias: "Kitchen Kiosk - Apply Camera Policy" mode: restart variables: desired_view: >- {{ {'garage': 'Garage', 'front_door': 'Front Door', 'driveway': 'Driveway'}.get( states('sensor.kiosk_active_camera_view'), 'none') }} desired_button: >- {{ 'button.kitchen_show_show_garage_2' if desired_view == 'Garage' else 'button.kitchen_show_show_front_door_2' }} sequence: - choose: - conditions: - condition: template value_template: "{{ desired_view in ['Garage', 'Front Door'] }}" sequence: - condition: template value_template: >- {{ states('sensor.kitchen_show_active_camera_view_2') != desired_view }} - service: script.kitchen_kiosk_show_event data: event_type: camera show_button: "{{ desired_button }}" - conditions: - condition: template value_template: "{{ desired_view == 'Driveway' }}" sequence: - choose: - conditions: - condition: template value_template: >- {{ states('sensor.kitchen_show_active_camera_view_2') not in ['none', 'unknown', 'unavailable'] }} sequence: - service: button.press target: entity_id: button.kitchen_show_close_camera_view_2 - service: script.kitchen_kiosk_show_event data: event_type: detail default: - choose: - conditions: - condition: template value_template: >- {{ states('sensor.kitchen_show_active_camera_view_2') not in ['none', 'unknown', 'unavailable'] }} sequence: - service: button.press target: entity_id: button.kitchen_show_close_camera_view_2 - service: button.press target: entity_id: button.kitchen_show_bring_to_front_2 kitchen_kiosk_show_event: alias: "Kitchen Kiosk - Show Display Event" mode: restart fields: event_type: name: Event type description: Event renderer to show on the Kitchen kiosk. required: true selector: select: options: - radar - camera - detail show_button: name: Camera view button description: Kiosk Satellite MQTT button for the native camera view. required: false selector: entity: domain: button sequence: - condition: template value_template: >- {{ event_type in ['camera', 'detail'] or ( event_type == 'radar' and is_state('binary_sensor.kitchen_kiosk_should_be_on', 'on') and is_state('sun.sun', 'above_horizon') and is_state('binary_sensor.kiosk_rain_radar_weather_event', 'on') ) }} - service: light.turn_on target: entity_id: light.kitchen_show_screen_2 - service: button.press target: entity_id: button.kitchen_show_postpone_screensaver_2 - service: button.press target: entity_id: button.kitchen_show_bring_to_front_2 - choose: - conditions: - condition: template value_template: "{{ event_type == 'radar' }}" sequence: - service: timer.cancel target: entity_id: timer.kitchen_kiosk_detail_display - service: timer.start target: entity_id: timer.kitchen_kiosk_radar_display data: duration: "00:05:00" - conditions: - condition: template value_template: "{{ event_type == 'camera' }}" sequence: - service: timer.cancel target: entity_id: timer.kitchen_kiosk_detail_display - condition: template value_template: >- {{ show_button is defined and show_button | string | length > 0 }} - delay: "00:00:01" - service: button.press target: entity_id: "{{ show_button }}" kitchen_kiosk_show_detail: alias: "Kitchen Kiosk - Show Banner Detail" mode: restart fields: detail_type: name: Detail type description: Contextual detail renderer requested by the active banner slide. required: true selector: select: options: - weather - package - family - entry_points - phyn - hot_water detail_subject: name: Detail subject description: Optional alert ID or person entity for the detail renderer. required: false selector: text: variables: normalized_type: "{{ detail_type | default('', true) | lower }}" normalized_subject: "{{ detail_subject | default('', true) | string }}" allowed_people: - person.carlo - person.stacey - person.justin - person.paige phyn_alert_entities: - binary_sensor.garage_phyn_battery_alert - binary_sensor.garage_phyn_freeze_warning_alert - binary_sensor.garage_phyn_high_pressure_alert - binary_sensor.garage_phyn_leak_alert - binary_sensor.garage_phyn_offline_leak_shutoff_alert - binary_sensor.garage_phyn_pinhole_leak_alert - binary_sensor.garage_phyn_recurring_flow_alert - binary_sensor.garage_phyn_temperature_alert detail_is_valid: >- {% set phyn_alert = expand(phyn_alert_entities) | selectattr('state', 'eq', 'on') | list | count > 0 %} {{ is_state('binary_sensor.kitchen_kiosk_should_be_on', 'on') and ( (normalized_type == 'weather' and states('sensor.nws_alerts_alerts') | int(0) > 0) or (normalized_type == 'package' and is_state('binary_sensor.front_door_packages_present', 'on')) or (normalized_type == 'family' and normalized_subject in allowed_people and states(normalized_subject) not in ['home', 'unknown', 'unavailable']) or (normalized_type == 'entry_points' and is_state('group.entry_points', 'on')) or (normalized_type == 'phyn' and (phyn_alert or states('valve.phyn_shutoff_valve') != 'open')) or (normalized_type == 'hot_water' and ( is_state('binary_sensor.rheem_wh_problem', 'on') or states('sensor.rheem_wh_available_hot_water') | float(100) < 30 )) ) }} detail_duration: >- {{ '00:05:00' if normalized_type in ['weather', 'phyn'] else '00:03:00' }} detail_value: >- {{ normalized_type ~ ('|' ~ normalized_subject if normalized_subject | length > 0 else '') }} sequence: - condition: template value_template: "{{ detail_is_valid }}" - service: timer.cancel target: entity_id: timer.kitchen_kiosk_radar_display - service: input_text.set_value target: entity_id: input_text.kitchen_kiosk_detail_view data: value: "{{ detail_value }}" - service: timer.start target: entity_id: timer.kitchen_kiosk_detail_display data: duration: "{{ detail_duration }}" - service: script.kitchen_kiosk_show_event data: event_type: detail kitchen_kiosk_restore_phyn_water: alias: "Kitchen Kiosk - Restore Phyn Water" mode: single sequence: - condition: state entity_id: timer.kitchen_kiosk_detail_display state: active - condition: template value_template: >- {{ states('input_text.kitchen_kiosk_detail_view').split('|')[0] == 'phyn' and is_state('valve.phyn_shutoff_valve', 'closed') }} - service: valve.open_valve target: entity_id: valve.phyn_shutoff_valve - service: script.send_to_logbook data: topic: WATER message: "Kitchen Show requested that the Phyn main water valve be turned on."