Enable graceful shutdown by RPi UPSPACK v3?

Hi All,
I found an interesting UPS board with a 10.000mAh LiPo battery on Amazon to provide backup power to my Pi running HA in Greece (frequent power outages). I have added a link to the documentation below.
For the board to gracefully shutdown the Pi, it is wired to the UART pins on the GPIO headers. The software is a .py script that needs to be added to /etc/rc.local on the host os. It imports RPi.GPIO to connect to the pin signaling system_halt on battery low. Is python3 and RPi.GPIO available on HA OS?

I am running HA OS and would like to continue doing so because of the auto-updates of all components. I know that I can ssh as root into the host (after jumping through a few hoops with authorized_keys) and I would be willing to do that if there is no better alternative (existing integration)?

Has anyone done this or similar? Will it work if the host shutdowns? will the containers (core and supervisor) be gracefully stopped as well?

Docs: UPSPACK_V3/README_en.md at 9eac086a66ff03e24fa8408de79b1a84dee0a41b · rcdrones/UPSPACK_V3 · GitHub

1 Like

I have recently done this on an rpi4 with haos with a slightly newer version of this board. Is it still useful to you or anyone to share?

Im interested

Below is a textcopy of upspack.yaml that i include as a package in homeassistant for the ups. I have the hass install. NB you need to do some hardware connections and amend the config.txt of the rpi4.
I hope it is of use.

---
# upspack V3.2P integration for Home Assistant
# see: https://github.com/rcdrones/UPSPACK_V3/blob/9eac086a66ff03e24fa8408de79b1a84dee0a41b/README_en.md
# assumption is connection to rx/tx serial gpio of rpi4
# as follows:
#  pin 6 gnd           => upspack gnd
#  pin 8 gpio 14 txd   => upspack tx
#  pin 10 gpio 15 rxd  => upspack rx
#
# for amending the config one should have root access to ha host.
# see: https://developers.home-assistant.io/docs/operating-system/debugging/
#
# en /mnt/boot/config.txt should be amended with:
# enable_uart=1
#
# on rpi4 bluetooth should be off since it uses the uart
# dtoverlay=disable-bt
#
# this file can be imported as package in home assistant.
# it will create entities and automations for notification
#
# input_text.ha_instance can hold the name of your instance for messages
#
# identifier is used as a sort of check on receiving a valid message via the serial port
# this could be made more resilient
#
# current notification uses pushover integration. See below.
#
input_text:
  upspack_ha_instance:
    name: upspack ha instance
    initial: "homeassistant"
    icon: mdi:lighthouse

sensor:
  - platform: serial
    name: "upspack"
    serial_port: /dev/ttyAMA0
    baudrate: 9600

template:
  - sensor:
      - name: upspack_voltage
        unique_id: upspack_voltage
        unit_of_measurement: "V"
        state: >
          {% set prev = states('sensor.upspack_voltage') %}
          {% set curr = ((states('sensor.upspack').split(',')[3][5:][:4] | float )/ 1000) | round(1) %}
          {{  curr  if identifier != "illmsg" else prev }}
        icon: mdi:flash
        state_class: measurement

      - name: upspack_identifier
        state: >
          {% set identifier = states('sensor.upspack').split(',')[0][2:] %}
          {{ identifier if identifier == "SmartUPS V3.2P" else "illmsg" }}

      - name: upspack_soc
        unique_id: upspack_soc
        unit_of_measurement: "%"
        state: >
          {% set prev = states('sensor.upspack_soc') %}
          {% set curr = states('sensor.upspack').split(',')[2][7:] | float | round(0) %}
          {{  curr  if identifier != "illmsg" else prev }}
        icon: mdi:battery
        device_class: battery
        state_class: measurement

      - name: upspack_good
        state: >
          {% set prev = states('sensor.upspack_good') %}
          {% set curr = states('sensor.upspack').split(',')[1][4:][:4].lower() %}
          {{  curr  if identifier != "illmsg" else prev }}

  - binary_sensor:
      - name: upspack_on_utility
        unique_id: upspack_on_utility
        state: >
          {{ is_state('sensor.upspack_good','good') }}
        icon: mdi:battery-charging

automation upspack:
  - alias: "[upspack] utility notification"
    id: upspack_utl_msg
    description: ""
    triggers:
      - trigger: state
        entity_id:
          - binary_sensor.upspack_on_utility
    actions:
      - if:
          - condition: state
            entity_id: binary_sensor.upspack_on_utility
            state: "on"
        then:
          - action: notify.pushover
            metadata: {}
            data:
              message: "Charging of ups has resumed. ( {{ states('sensor.upspack_soc')}}% )"
              title: "{{ states('input_text.upspack_ha_instance') }}: upspack"
        else:
          - action: notify.pushover
            metadata: {}
            data:
              message: "Charging of ups halted. Is ac power present? ( {{ states('sensor.upspack_soc')}}% )"
              title: "{{ states('input_text.upspack_ha_instance') }}: upspack"

  - alias: "[upspack] battery too low"
    id: upspack_charg_too_low
    description: ""
    triggers:
      - trigger: numeric_state
        entity_id:
          - sensor.upspack_soc
        below: 5
        for:
          hours: 0
          minutes: 0
          seconds: 30
    conditions: []
    actions:
      - if:
          - condition: state
            entity_id: binary_sensor.upspack_on_utility
            state: "on"
        then:
          - action: notify.pushover
            metadata: {}
            data:
              message: >-
                upspack soc too low ( {{ states('sensor.upspack_soc')}}% ). Systeem
                shutdown to prevent dataloss
              title: "{{ states('input_text.upspack_ha_instance') }}: upspack"
      - action: hassio.host_shutdown
        data: {}
    mode: single

  - alias: "[upspack] battery charge drops notification"
    id: upspack_notify_charge_dropping
    description: ""
    triggers:
      - trigger: state
        entity_id:
          - sensor.upspack_soc
        for:
          hours: 0
          minutes: 0
          seconds: 19
    conditions:
      - condition: state
        entity_id: binary_sensor.upspack_on_utility
        state: "off"
      - condition: numeric_state
        entity_id: sensor.upspack_soc
        below: 51
      - condition: template
        value_template: >-
          {% set modulo = states('sensor.upspack_soc') | int % 10 %} {{  true  if
          modulo == 0  else false }}
    actions:
      - action: notify.pushover
        metadata: {}
        data:
          message: Charge of the ups battery is now  {{ states('sensor.upspack_soc')}}%.
          title: "{{ states('input_text.upspack_ha_instance') }}: upspack"
    mode: single