Hi There,
First, I would like to thank all the contributors here for their amazing job.
I used this post as a base for my Versions Update notifications and I would like to share my solution for anyone who would like to use it.
Among the changes to the original package shared by @CentralCommand and other shares in this post:
- I added DeConz Updates
- I added the Supervisor version check (the supervisor itself, not the addons)
- I re-organised the sensors to a uniform reporting state
- I donât like alerts, especially many of them so I created an automation for the notifications instead
- I created a unified sensor with all available Updates and I am using it in my automation (and the custom UI that I wonât share here because it it out of scope)
- fixed minor bug with the way versions are compared (used split (â " ') instead of chars count for some network calls, wouldnât fail when version number passes from 0.9.1 to 0.10.0 for example)
remember to update !secret github_access_token
with your github account token.
So this is my new package:
# DeCONZ Firmware Updates:
sensor:
# Deconz Firmware version Installed
- platform: command_line
name: DeCONZ Firmware Installed #sensor.deconz_firmware_installed
command: 'cat /config/.storage/core.device_registry | grep -A 3 "Dresden Elektronik" | grep "sw_version"'
scan_interval: 3600
value_template: '{{ value.split("\"")[3] }}'
# HACS version Installed
- platform: command_line
name: HACS Version Installed #sensor.hacs_version_installed
command: 'cat /config/.storage/core.device_registry | grep -A 3 "hacs.xyz" | grep "sw_version"'
scan_interval: 3600
value_template: '{{ value.split("\"")[3] }}'
# Firmware-Update-Sensor for DeCONZ Dongle
- platform: github
access_token: !secret github_access_token
repositories:
- path: 'dresden-elektronik/deconz-rest-plugin'
name: "DeCONZ Firmware Repository" #sensor.deconz_firmware_repository
- path: 'hacs/integration'
name: "HACS Repository" #sensor.hacs_repository
scan_interval: 86400 #daily
- platform: template
sensors:
deconz_firmware_version:
friendly_name: "DeCONZ Firmware Version"
value_template: >-
{% set new = state_attr('sensor.deconz_firmware_repository', 'latest_release_tag').replace('v', '') %}
{% if ("beta" not in new) and (new != states('binary_sensor.deconz_firmware_installed')) %}
on
{% else %}
off
{% endif %}
attribute_templates:
beta: >-
{% set version = state_attr('sensor.deconz_firmware_repository', 'latest_release_tag') %}
{% if "beta" not in version %}
off
{% else %}
on
{% endif %}
latest_version: "{{state_attr('sensor.deconz_firmware_repository', 'latest_release_tag').replace('v', '') }}"
current_version: "{{states('sensor.deconz_firmware_installed')}}"
hacs_version:
friendly_name: "Hacs Version"
value_template: >-
{% if (states('sensor.hacs') | int > 0) or (state_attr('sensor.hacs_repository', 'latest_release_tag') != states('sensor.hacs_version_installed')) %}
on
{% else %}
off
{% endif %}
attribute_templates:
latest_version: "{{state_attr('sensor.hacs_repository', 'latest_release_tag') }}"
current_version: "{{states('sensor.hacs_version_installed')}}"
repositories: "{{state_attr('sensor.hacs', 'repositories')}}"
#--------------------------------------------------------
# Sensors to track updates to core components (core, audio, dns, CLI, observer and multicast)
- platform: command_line
name: Core Version # sensor.core_version
command: 'curl http://supervisor/core/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
- platform: command_line
name: HassOS Version # sensor.hassos_version
command: 'curl http://supervisor/os/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version,"update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
- platform: command_line
name: Audio Version # sensor.audio_version
command: 'curl http://supervisor/audio/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
- platform: command_line
name: DNS Version # sensor.dns_version
command: 'curl http://supervisor/dns/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
- platform: command_line
name: CLI Version # sensor.cli_version
command: 'curl http://supervisor/cli/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
- platform: command_line
name: Multicast Version # sensor.multicast_version
command: 'curl http://supervisor/multicast/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
- platform: command_line
name: Observer Version # sensor.observer_version
command: 'curl http://supervisor/observer/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600
json_attributes:
- latest_version
- current_version
#--------------------------------------------------------
# Sensor to track available updates for the supervisor & supervisor addons list
- platform: command_line
name: Supervisor Version # sensor.supervisor_version
command: 'curl http://supervisor/supervisor/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"latest_version":.data.version_latest,"current_version":.data.version,"update_available":.data.update_available,"addons":[.data.addons[] | select(.update_available)]}'''
value_template: "{% if (value_json.addons | length > 0) or value_json.update_available %}on{% else %}off{% endif %}"
scan_interval: 3600 #check every hour (default is 60- every minute)
json_attributes:
- latest_version
- current_version
- addons
binary_sensor:
- platform: template
sensors:
version_update_issues:
friendly_name: 'Version Update Issues'
device_class: problem
value_template: >-
{{ (state_attr('binary_sensor.version_update_issues', 'status')).outdated|count > 0 }}
attribute_templates:
status: >-
{% set ns = namespace(outdated = [], up_to_date = [], optional_updates = []) -%}
{%- for _updateSensor in (expand(states.sensor)|list) if _updateSensor.entity_id.endswith('_version') -%}
{%- set _sensorName = _updateSensor.entity_id -%}
{%- if _updateSensor.state == "on" -%}
{%- set ns.outdated = ns.outdated + [_sensorName] -%}
{%- else -%}
{%- if _updateSensor.attributes.current_version!=_updateSensor.attributes.latest_version -%}
{%- set ns.optional_updates = ns.optional_updates + [_sensorName] -%}
{%- else -%}
{%- set ns.up_to_date = ns.up_to_date + [_sensorName] -%}
{%- endif -%}
{%- endif -%}
{% endfor %}
{{ "{{\"up_to_date\": {}, \"optional_updates\": {}, \"outdated\": {} }}".format(ns.up_to_date, ns.optional_updates, ns.outdated) }}
And my notifications (using iOS, change the notifiers if you need):
alias: Device Health - Version Update Notification
description: ''
trigger:
- platform: state
entity_id: binary_sensor.version_update_issues
to: 'on'
- platform: time
at: '14:00:00'
condition:
- condition: state
entity_id: binary_sensor.version_update_issues
state: 'on'
action:
- service: notify.admin_devices
data:
title: â ď¸Version Updates Available
message: >-
{%- for _updateSensor in
states.binary_sensor.version_update_issues.attributes.status.outdated %}
{{- "Stable Updates:" if loop.first }}
{{- "\n "~states[_updateSensor].attributes.friendly_name ~ " [" ~ states[_updateSensor].attributes.current_version ~ "]"}}
{%- if states[_updateSensor].attributes.current_version!=states[_updateSensor].attributes.latest_version -%}
{{- "â["~ states[_updateSensor].attributes.latest_version ~"]"}}
{%- endif -%}
{%- if state_attr(_updateSensor, 'repositories') != None and state_attr(_updateSensor, 'repositories')|count > 0 -%} - repositories updates:
{% for repository in state_attr(_updateSensor, 'repositories') %}
{{"\n -"~ repository.display_name }}: [{{ repository.installed_version }} ]â[ {{ repository.available_version }}]
{% endfor %}
{%- endif -%}
{%- if state_attr(_updateSensor, 'addons') != None and state_attr(_updateSensor, 'addons')|count > 0-%} - addon updates:
{% for addon in state_attr(_updateSensor, 'addons') %}
- {{ addon.name }}: [{{ addon.version }} ]â[ {{ addon.version_latest }}]
{% endfor %}
{%- endif -%}
{% endfor %} {% for _updateSensor in
states.binary_sensor.version_update_issues.attributes.status.optional_updates
%}
{{- "\nOptional Updates:" if loop.first }}
{{- "\n "~states[_updateSensor].attributes.friendly_name ~ " [" ~ states[_updateSensor].attributes.current_version ~ "]"}}
{%- if states[_updateSensor].attributes.current_version!=states[_updateSensor].attributes.latest_version -%}
{{- "â["~ states[_updateSensor].attributes.latest_version ~"]"}}
{%- endif -%}
{%- if state_attr(_updateSensor, 'repositories') != None and state_attr(_updateSensor, 'repositories')|count > 0 -%} - repositories updates:
{% for repository in state_attr(_updateSensor, 'repositories') %}
{{"\n -"~ repository.display_name }}: [{{ repository.installed_version }} ]â[ {{ repository.available_version }}]
{% endfor %}
{%- endif -%}
{%- if state_attr(_updateSensor, 'addons') != None and state_attr(_updateSensor, 'addons')|count > 0-%} - addon updates:
{% for addon in state_attr(_updateSensor, 'addons') %}
- {{ addon.name }}: [{{ addon.version }} ]â[ {{ addon.version_latest }}]
{% endfor %}
{%- endif -%}
{% endfor %}
data:
url: /devices-health/health_panel
push:
thread-id: version-update-notification-group
apns_headers:
apns-collapse-id: version-update-issues
presentation_options:
- alert
mode: restart
alias: Device Health - Clear Version Update Notification
description: ''
trigger:
- platform: state
entity_id: binary_sensor.version_update_issues
to: 'off'
condition: []
action:
- service: notify.admin_devices
data:
title: â
Version Updates Installed
message: All components are up to date!
data:
url: /devices-health/health_panel
push:
thread-id: version-update-notification-group
apns_headers:
apns-collapse-id: version-update-issues
presentation_options:
- alert
mode: restart