Update notifications! Core, HACS, Supervisor and Addons (now a blueprint!)

Where do I put this code?

# Sensor to track available updates for supervisor & addons
- platform: command_line
  name: Supervisor updates
  command: 'curl http://supervisor/supervisor/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version,"addons":[.data.addons[] | select(.version != .installed)]}'''
  value_template: "{{ value_json.addons | length }}"
  json_attributes:
  - newest_version
  - current_version
  - addons

#  Binary sensors for HACS, Supervisor and the Addons
- platform: template
  sensors:
    # True if there's an update available for supervisor
    updater_supervisor:
      friendly_name: 'Updater - Supervisor'
      device_class: problem
      entity_id:
      - sensor.supervisor_updates
      value_template: "{{ state_attr('sensor.supervisor_updates', 'current_version') != state_attr('sensor.supervisor_updates', 'newest_version') }}"
      availability_template: "{{ (states('sensor.supervisor_updates') | int(-1)) > -1 }}"
    # True if there's updates available for any HACS components
    updater_hacs:
      friendly_name: 'Updater - HACS'
      device_class: problem
      entity_id:
      - sensor.hacs
      value_template: "{{ states('sensor.hacs') | int > 0 }}"
    # True if there's updates available for any addons
    updater_addons:
      friendly_name: 'Updater - Addons'
      device_class: problem
      entity_id:
      - sensor.supervisor_updates
      value_template: "{{ states('sensor.supervisor_updates') | int > 0 }}"

You can get the os info like the sensor for supervisor updates, on http://supervisor/os/info:

  - platform: command_line
    name: hassos_updates
    command: 'curl http://supervisor/os/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version}'''
    value_template: "{% if value_json.newest_version != value_json.current_version %}on{% else %}off{% endif %}"
    json_attributes:
    - newest_version
    - current_version
3 Likes

In a package file: https://www.home-assistant.io/docs/configuration/packages/

thanks got it working like this, just show the community how we can write it so it fits the page :wink:

  - platform: command_line
    name: Hassos updates
    command: >
      curl http://supervisor/os/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)"
      | jq '{"newest_version":.data.version_latest,"current_version":.data.version}'
    value_template: >
      {% if value_json.newest_version != value_json.current_version %}on
      {% else %}off
      {% endif %}
    json_attributes:
      - newest_version
      - current_version

too bad we cant this as a binary_sensor, (with the same attributes) and a value template like

 value_template: >
      {{value_json.newest_version != value_json.current_version }}

thanks!

btw, when entering ha su info on the cli, we see the list of add ons like this:

shouldn’t we be able to get that from the command_line sensor? seems like a wrong config we get nothing there now:

this gives the whole list of add-ons :wink:

    command: >
      curl http://supervisor/supervisor/info -H "Authorization: Bearer $SUPERVISOR_TOKEN"
      | jq '{"newest_version":.data.version_latest,"current_version":.data.version,
              "addons":[.data.addons[] ]}'


but of course this was an update sensor…hence the empty list

as for the supervisor updater sensors, I need to adjust it to:

{% for addon in state_attr('sensor.supervisor_updates','addons') %}
{{ addon.name }} in '{{addon.state}}' state and 
{%- if addon.update_available == false %} Up to date: {{ addon.version }}
{%- else %} Update available:  ({{ addon.version }} -> {{ addon.version_latest }})
{%- endif %}
{%- endfor %}

using version and version_latest, to pickup any changes. Strange how this seems to vary over the various install methods.
Homeassistant OS 117.0b4 here.

  - platform: command_line
    name: Supervisor updates
    command: >
      curl http://supervisor/supervisor/info -H "Authorization: Bearer $SUPERVISOR_TOKEN"
      | jq '{"newest_version":.data.version_latest,"current_version":.data.version,
              "addons":[.data.addons[] | select(.version != .installed)]}'
    value_template: >
      {{value_json.addons|length}}
    json_attributes:
      - newest_version
      - current_version
      - addons
    scan_interval: 3600

So this

  - platform: command_line
    name: Supervisor Installed
    command: 'curl http://supervisor/supervisor/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version,"addons":[.data.addons[] | select(.version != .installed)]}'''
    value_template: "{{ value_json.addons | length }}"
    unit_of_measurement: pending update(s)
    json_attributes:
      - newest_version
      - current_version
      - addons

is now returning the number of addons installed instead of the number of updates available.
All the addons in the sensor look like this:

    {
      "name": "ZeroTier One",
      "slug": "a0d7b954_zerotier",
      "description": "Radically simplify your network with a virtual networking layer that works the same everywhere",
      "state": "started",
      "version": "0.7.3",
      "version_latest": "0.7.3",
      "update_available": false,
      "repository": "a0d7b954",
      "icon": true,
      "logo": true
    },

So how do I add the number of update_available: true 's up and use that as the value for the state?

1 Like

Thinking I need:

select(.version != .version_latest)

I think they changed a key name in the json response to the curl command…

Yep, you’re correct. Looks like there’s actually an easier way to do it now though at least since they just return a boolean field for update_available. The curl command needs to either be updated as you describe or to this, the old one won’t work anymore:

command: 'curl http://supervisor/supervisor/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version,"addons":[.data.addons[] | select(.update_available)]}'''

Will update the main post in a sec. Since the data model for the addons changed that also means other things looking at that sensor need to be updated (alerts, node RED flows, etc.). Going to take me a sec to update those.

1 Like

I know this post is really old at this point, sorry has been a busy fall.

But FYI, actually doesn’t seem like updates can be tracked for this new container. When the other containers were introduced there was a matching addition to the CLI and API that could be used to find out info about it. There doesn’t seem to be anything about ‘observer’ in the CLI or API though. So either its updates are not independently trackable or there’s a new way to track them I’m not aware of.

Documentation always reflects the current API https://developers.home-assistant.io/docs/api/supervisor/endpoints#observer

3 Likes

Ok phew, everything updated. Actually made a number of changes besides just the bug fix, all the others are minor though. Locally I converted to using Threshold sensors instead of Template Binary Sensors when appropriate so now the package is updated for that. Also updated to leverage the new update_available field instead of comparing version identifiers as that seems preferrable.

@pergola.fabio pinging you since we were discussing on that other post. You should be able to pull the new package or just tweak the curl command in that one sensor and be all set.

Ah perfect, thanks! And I see there is an API for observer in there so added a sensor for that now as well @DavidFW1960

1 Like

Yeah I already had a sensor for that… found it earlier.

I changed to your code for the supervisor updates. Thanks.

Hi, I experience that only than “HACS” sensor provides me with an update. Since a while (don’t know when but longer time ago) I do not seem to get a notification for any of the other sensors…

Is this by design versus the recent update of home assistant? And others experiencing this?

Hello,

Could someone please help me out with this one?

I’m trying to get snapshots list from supervisor and would like to get latest slug so I could restore it automatically with an automation if necessary. I’m unable to even get the parsed listing in to HA.

This is my latest take on this:

  - platform: command_line
    name: Snapshots
    command: 'curl http://supervisor/snapshots -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq --slurpfile slugs found_snapshots.txt ''{"snapshots":[.data.snapshots[] | select(.slug as $slug | $slugs | index($slug) | not)]}'''
    value_template: '{{ value_json.snapshots | length }}'
    json_attributes:
    - snapshots
    - date
    - name
    - slug

And this results to error:

Logger: homeassistant.components.command_line
Source: components/command_line/__init__.py:41
Integration: command_line (documentation, issues)
First occurred: 19.32.06 (1 occurrences)
Last logged: 19.32.06

Command failed: curl http://supervisor/snapshots -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq --slurpfile slugs found_snapshots.txt '{"snapshots":[.data.snapshots[] | select(.slug as $slug | $slugs | index($slug) | not)]}'

I’m not really sure what to make of your “found_snapshots” file, not really understanding how that’s connected to your use case. It sounds like you want to find the latest snapshot and store its slug in a sensor. Based on that the command I would use is this:

curl http://supervisor/snapshots -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq '[.data.snapshots[]] | sort_by(.date) | last'

This gets the list of snapshots, sorts the list by date ascending, then just keeps the last one (which is the newest by date). You can then leverage that in a sensor like this:

- platform: command_line
  name: Latest snapshot
  command: 'curl http://supervisor/snapshots -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''[.data.snapshots[]] | sort_by(.date) | last'''
  value_template: '{{ value_json.slug }}'
  json_attributes:
  - name
  - date
  - type
  - protected

Seems like that gets you everything you need to do what I believe you’re trying to do.

Is there some reason your capturing a list of snapshot slugs in a text file and using it to filter the list? If so you’ll have to explain why so I can try and figure out what’s going wrong. Doesn’t seem necessary to get the slug of the latest snapshot though since the data of each snapshot includes a date.

1 Like

Thank you for your effort and this did indeed work.

Little bit more background for this: I’m trying to build redundant/highly available HA backup server which would launch automatically if the main server drops offline. Otherwise the backup servers overlapping automations and processes are turned off with automation. Updating configs to two server is quite hindrance so I was looking to this matter by trying to restore latest snapshot automatically in backup server.

I simplified the sensor even more for my purpose:

- platform: command_line
  name: Latest snapshot
  command: 'curl http://supervisor/snapshots -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''[.data.snapshots[]] | sort_by(.date) | last | .slug'''

This could have been enough for me but then I ran to another problem with shell_command: I tried to launch the restore in several ways:

shell_command:
   restore: 'ha snapshots restore "{{latest_snapshot}}"'

This didn’t work as the shell commands are run in homeassistant docker, not hassio-cli

Then I tried to proceed with

shell_command:
  restore: 'curl -X POST http://supervisor/snapshots/restore "{{latest_snapshot}}" -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)"'

But ran to 405 method not allowed error.

After total of 24 hours trying to solve this I’ve given up for now. Some sources indicate that calling ssh command could bypass limitations, but I see here so much breaking possibilites that I have decided for now to do the “cloning” of main server to backup server by hand.

My daily samba backup -goes straight to backup server so this is quite good emergency solution for now. Well maybe this way I have more control over the backup server and I can test&try with it and I don’t have to think about the automatic backup system running over my unfinished tinkering.

On my phone at the moment so I can’t test this myself but I notice the URL you are using to restore seems to be incorrect. Here is the API for interacting with snapshots via supervisor. There are two APIs you can use to restore a snapshot via the API -

  • /snapshots/<snapshot>/restore/full
  • /snapshots/<snapshot>/restore/partial

The slug goes in the URL as a resource path parameter, not the body. The body is just the password for a full restore or the details of what to restore for a partial restore (and the password).

If you’re trying to restore on another system you might have to use the upload snapshot API to get the snapshot into the correct place first unless the two share a folder for backups.

Also just an FYI, to get the value of the latest_snapshot sensor your template should be {{ states('sensor.latest_snapshot') }} not {{ latest_snapshot }}.

Cool idea though! If you get it all working you should make a thread or guide about your setup. Would be great to have things auto fail over to a backup replica.

Just FYI, the following sensor:

- platform: command_line
  name: HassOS Installed Version
  command: 'curl http://supervisor/host/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)"|jq ''{"hassos":.data.operating_system}'''
  value_template: "{{ value_json.hassos[7:] }}"

Needs to be updated to this in 2020.12:

- platform: command_line
  name: HassOS Installed Version
  command: 'curl http://supervisor/host/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)"|jq ''{"hassos":.data.operating_system}'''
  value_template: "{{ value_json.hassos[18:] }}"
1 Like

I know … but would be possible to put all this in a blueprint?
Thanks

1 Like

No. It’s a sensor not an automation.