Here is an intuitive User Experience (UX) for remote reboots, that I designed as components of our integrated home solution can occasionally go a bit flakey when I’m not home to manage operate them.
The end-user requirements are that it should:
- Indicate that something has started happening by a visual change
- Test more frequent whether its up, to update more quickly
- Show the difference between down and up clearly
- Put everything back as it was once the reboot is complete
Here are the 3 states of the ui:
- normal operation - on the left
- going down - as soon as you touch it to reboot, it looks like the top right
- down - whilst it’s down it looks like the bottom right
…and then it will revert back to normal again once the reboot has finished and it’s back up.
The elements of this solution are:
- a template switch that:
- senses the ping
- triggers the automation and
- changes its icon during the reboot
-
internal flags to indicate
- that reboot had been requested
- whether the device went down yet
- an automation to update the ping more frequently and change flag states
- an automation to kick off the process
- the binary ping sensor that detects when the device goes down
- a simple press button in the Lovelace user interface (UI)
My solution uses SSH for remote system operations but you can easily swap in your preferred mechanism. Equally, you might choose a higher level indicator of ‘up’ for your sensor, e.g. test an API call instead of a ping. You can put whatever switch and sensor settings you need behind the templated switch and automation.
Here are sample configurations - each of which can be multiplied up if you have many devices needing reboots
Switch
switch:
- platform: template
switches:
restart_myserver_template:
friendly_name: “Restart MyServer”
value_template: "{{ is_state('binary_sensor.ping_myserver', 'on') }}"
turn_on:
turn_off:
service: automation.trigger
data:
entity_id: automation.sysmain_myserver_restart
# credit https://community.home-assistant.io/t/push-button-with-status/47431
icon_template: >-
{% if is_state('input_boolean.rebooting_myserver', 'on') and is_state('input_boolean.rebooting_myserver_was_down', 'off') %}
mdi:power-on
{% elif is_state('input_boolean.rebooting_myserver', 'on') and is_state('input_boolean.rebooting_myserver_was_down', 'on') %}
mdi:power-off
{% else %}
mdi:music-note-half-dotted
{% endif %}
# if you have only one device to reboot use power-cycle as the default `else` icon
# mdi:power-cycle
# otherwise relate it to the service running on that device
Input booleans
input_boolean:
rebooting_myserver:
name: when this is true MyServer has been asked to reboot and it has not yet come back up
# for simplicity these reboot variables assume the reboots have finished
# before HA restarts
initial: off
icon: mdi:power-cycle
rebooting_myserver_was_down:
name: when this is true MyServer has been asked to reboot and has been down according to ping
initial: off
icon: mdi:power-cycle
dummy_boolean:
name: used in service templates as the else
Automation
automation:
- alias: Sysmain MyServer Restart
trigger:
action:
# initiate faster ping intervals
- service: input_boolean.turn_on
entity_id: input_boolean.rebooting_myserver
- service: shell_command.remote_operation
data:
# the templates are in the command,
# this does NOT need to be a data template as it's only passing values
cert: MyServer_sysmain_reboot_key
user: hareboot
host: MyServer
domain: !secret domain_suffix
- alias: MyServer ping faster
trigger:
# every five seconds
- platform: time_pattern
seconds: '/5'
condition:
# for as long as we are rebooting
- condition: state
entity_id: input_boolean.rebooting_myserver
state: 'on'
action:
# update to make the ping interval faster
- service: homeassistant.update_entity
entity_id: binary_sensor.ping_myserver
# if not was down but now doesn't ping
# was_down = true
# credit https://community.home-assistant.io/t/if-then-else-in-automation-action/152341/3
- service: input_boolean.turn_on
data_template:
entity_id: >
{% if is_state('input_boolean.rebooting_myserver_was_down', 'off') and is_state('binary_sensor.ping_myserver', 'off') %}
input_boolean.rebooting_myserver_was_down
{%- else -%}
input_boolean.dummy_boolean
{%- endif %}
# if was down and now pings
# rebooting has ended - turn it off
- service: input_boolean.turn_off
data_template:
entity_id: >
{% if is_state('input_boolean.rebooting_myserver_was_down', 'on') and is_state('binary_sensor.ping_myserver', 'on') %}
input_boolean.rebooting_myserver
{%- else -%}
input_boolean.dummy_boolean
{%- endif %}
Binary sensor
binary_sensor:
# some automations may update more frequently
- platform: ping
name: ping_myserver
host: MyServer
scan_interval: 300
count: 1
Lovelace Interface
views:
- title: Maintenance
id: view_maint
icon: mdi:settings
cards:
- type: glance
title: Restart services
entities:
- entity: switch.restart_myserver_template
name: MyServer
tap_action:
action: toggle
Shell command
This is a part of my solution but you might do your restart in a different way
# https://github.com/artmg/MuGammaPi/wiki/Home-Assistant#remote-system-operations
remote_operation: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /config/.storage/certs/{{ cert }} {{ user }}@{{ host }}{{ domain }}
# data:
# cert: name of public certificate under /config/.storage/certs/
# for remote system operations this also indicates the operation type
# user: user name for which the key to this certificate was installed
# host: local hostname of server to control
# domain: OPTIONAL domain suffix for host - MUST start with the . if specified
I hope this provides inspiration, ideas, and useable config code