UX for remote reboots

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:

HARemoteRebooUX

  • 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

1 Like