Last active
August 12, 2018 20:27
-
-
Save jsternadel/29ed6a6e245629e77a59a232b08956b5 to your computer and use it in GitHub Desktop.
Battery Notification with custom MQTT topic and HTML5 nofitications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################ | |
## Packages / Battery Alert | |
################################################################ | |
################################################################ | |
## Changelog | |
################################################################ | |
## | |
## 1.0.0 (2018-02-14) | |
## Added | |
## - Added version number to enable better tracking | |
## | |
## 1.0.1 (2018-02-15) | |
## Added | |
## - Added battery_sensor_creation_disabled attibute to skip | |
## creating a battery sensor even when an battery attribute | |
## exists. | |
## | |
## 1.0.2 (2018-04-06) | |
## Added | |
## - Added battery icon to sensors. | |
## | |
## 1.0.3 (2018-05-10) | |
## Changed | |
## - Change device_class to battery and remove icon, which | |
## allows dynamic icons in 0.69. | |
## | |
## 1.0.4 (2018-05-11) | |
## Changed | |
## - Fixed condition battery_sensor_creation_disabled condition | |
## Added | |
## - Documented a jinja template that can be use to assist | |
## with creating a group containing all battery sensors. | |
## | |
## 1.0.5 (2018-05-14) | |
## Changed | |
## - Changed formatting of notifications to improve readability | |
## - Nofity via Slack immediately when thresholds are modified | |
## Added | |
## - Entities with device_class of battery no longer need | |
## battery in their friendly name to be monitored | |
## - Don't create a battery sensor from an entity if | |
## device_class is battery | |
## | |
## 1.0.6 (2018-05-14) | |
## Changed | |
## - Added object_id to notifications | |
## - Updated Battery Status group jinja code to check for | |
## battery device_class | |
## | |
## 1.0.7 (2018-05-16) | |
## Added | |
## - Added unique_id to disambiguate sensors with duplicate | |
## names | |
## - Added source info to mqtt config topic | |
## - Consider friendly names and entity_ids that end with _bat | |
## as a battery sensor (needed for rflink battery sensors) | |
## - Consider entities with icon of battery, battery-alert, or | |
## battery-unknown as a battery sensor regardles of its name | |
## - Consider entity_ids containing battery as a battery sensor | |
## Changed | |
## - Reduce code duplication using yaml anchors and references | |
## - Changed MQTT topic to be based on entity_id | |
## - Improve method of filtering non-battery devices that have | |
## battery in their name. Detection is now based on icon | |
## rather than keywords. | |
## | |
## 1.0.8 (2018-06-01) | |
## Added | |
## - Add support for defining battery_template attibute to | |
## allow manipulation of value of battery sensor | |
## - Support battery attributes that contain strings | |
## Removed | |
## - Cleaned up notifications by removing object id | |
## | |
## 1.0.9 (2018-06-08) | |
## Added | |
## - Automatically create Battery Status group containing all | |
## discovered batteries | |
## Removed | |
## - Removed sample jinja to create battery status group yaml | |
## | |
## 1.0.10 (2018-06-08) | |
## Added | |
## - Moved group.update_battery_status_group_members to Battery | |
## Alert group | |
## | |
## 1.1.0 (2018-08-09) | |
## Added | |
## - Added Batteries view | |
## - Added Telegram notification automation | |
## - Added Pushover notification automation | |
## - Added attributes to battery entities created via mqtt: | |
## entity_id, attribute, mqtt_config_topic, and mqtt_state_topic | |
## Changed | |
## - Simplified trigger for update_battery_status_group_members | |
## automation | |
## - Refactored conditions on automations to rely on | |
## group.battery_status members | |
## Breaking Changes | |
## - The attribute additions requires restarting Home Assistant | |
## after the first state change or clearing retained MQTT topics | |
## | |
## 1.1.1 (2018-08-11) | |
## Added | |
## - Added input text box named `MQTT Topic to Clear`, which can be used | |
## to clear MQTT topics with retained messages | |
## - Set initial_state to on for all automations to ensure they are enabled | |
## on startup | |
## Changed | |
## - Consider entities with battery in their entity_id or friendly_name a | |
## battery sensor if neither an icon nor a device class is defined | |
## - Consolidated the battery_sensor_from_* automations into a single | |
## automation | |
## | |
################################################################ | |
################################################################ | |
## Install Instructions | |
################################################################ | |
## | |
## 1. Enable MQTT using your preferred MQTT broker | |
## https://home-assistant.io/components/mqtt/ | |
## | |
## 2. Enable MQTT Discovery by adding `discovery: true` and | |
## `discovery_prefix: homeassistant` under the `mqtt:` section | |
## of your configuration.yaml | |
## | |
## mqtt: | |
## discovery: true | |
## discovery_prefix: homeassistant | |
## | |
## 3. Save this file as CONFIGDIR/packages/battery_alert.yaml | |
## | |
## 4. Add `packages: !include_dir_named packages` under the | |
## `homeassistant:` section of your configuration.yaml | |
## | |
## homeassistant: | |
## packages: !include_dir_named packages | |
## | |
## 5. Restart Home Assistant | |
## | |
## 6. Adjust Min Alert Threshold slider to the minimum battery | |
## level to alert on. Note: the input slider requires the | |
## recorder component to keep it's state through restarts. | |
## If recorder is not enabled, the threshold can be set by | |
## un-remarking `initial` and setting the preferred default. | |
## | |
## 7. Adjust Max Alert Threshold slider to the maximum battery | |
## level to alert on. Note: the input slider requires the | |
## recorder component to keep it's state through restarts. | |
## If recorder is not enabled, the threshold can be set by | |
## un-remarking `initial` and setting the preferred default. | |
## | |
## 8. To disable alerts for a specific entity, use customize to | |
## set `battery_alert_disabled` to `true` | |
## | |
## homeassistant: | |
## customize: | |
## sensor.sensor_name_to_ignore_battery: | |
## battery_alert_disabled: true | |
## | |
## 9. To disable creating a sensor from battery attributes for a specific entity, use customize to | |
## set `battery_sensor_creation_disabled` to `true` | |
## | |
## homeassistant: | |
## customize: | |
## sensor.sensor_with_battery_attibute: | |
## battery_sensor_creation_disabled: true | |
## | |
## 10. If a battery attribute requires a template to convert it into a usable percent | |
## or string, use customize to add `battery_template` with the necessary template. | |
## The template should result in either a percentage or a string ("Low" will | |
## trigger low battery notification). | |
## | |
## This example will create a battery sensor with the value of battery_level * 2 | |
## | |
## homeassistant: | |
## customize: | |
## sensor.sensor_with_battery_attibute_template: | |
## battery_template: "{{ value_json.value | int * 2 }}" | |
## | |
## This example will create a battery sensor that contains "Low" if battery_level | |
## is less than 2 | |
## | |
## homeassistant: | |
## customize: | |
## sensor.sensor_with_battery_attibute_template: | |
## battery_template: >- | |
## {%- if value < 2 -%} | |
## "Low" | |
## {%- else -%} | |
## "Full" | |
## {%- endif -%} | |
## | |
################################################################ | |
################################################ | |
## Customize | |
################################################ | |
homeassistant: | |
customize: | |
################################################ | |
## Node Anchors | |
################################################ | |
package.node_anchors: | |
customize: &customize | |
package: 'battery_alert' | |
################################################ | |
## Group | |
################################################ | |
group.battery_view: | |
<<: *customize | |
friendly_name: "Batteries" | |
icon: mdi:battery-alert | |
group.battery_alert: | |
<<: *customize | |
friendly_name: "Battery Alert" | |
icon: mdi:steam | |
control: hidden | |
group.battery_status: | |
<<: *customize | |
friendly_name: "Battery Status" | |
icon: mdi:battery-charging | |
control: hidden | |
################################################ | |
## Automation | |
################################################ | |
automation.battery_notification: | |
<<: *customize | |
friendly_name: "Battery Notification" | |
icon: mdi:comment-alert-outline | |
automation.battery_notification_clear: | |
<<: *customize | |
friendly_name: "Battery Notification Clear" | |
icon: mdi:comment-remove-outline | |
automation.battery_notification_slack: | |
<<: *customize | |
friendly_name: "Battery Notification Slack" | |
icon: mdi:comment-alert-outline | |
automation.battery_notification_telegram: | |
<<: *customize | |
friendly_name: "Battery Notification Telegram" | |
icon: mdi:comment-alert-outline | |
automation.battery_notification_pushover: | |
<<: *customize | |
friendly_name: "Battery Notification Pushover" | |
icon: mdi:comment-alert-outline | |
automation.battery_notification_html5: | |
<<: *customize | |
friendly_name: "Battery Notification HTML5" | |
icon: mdi:comment-alert-outline | |
automation.battery_notification_join: | |
<<: *customize | |
friendly_name: "Battery Notification Join" | |
icon: mdi:comment-alert-outline | |
automation.battery_sensor_from_attributes: | |
<<: *customize | |
friendly_name: "Create Battery Sensor from Attributes" | |
icon: mdi:battery-charging-wireless-outline | |
automation.update_battery_status_group_members: | |
<<: *customize | |
friendly_name: "Update Battery Status Group Members" | |
icon: mdi:group | |
automation.clear_mqtt_topic: | |
<<: *customize | |
friendly_name: "Clear a Retained MQTT Topic" | |
icon: mdi:server-remove | |
################################################ | |
## Group | |
################################################ | |
group: | |
battery_view: | |
view: yes | |
entities: | |
- group.battery_status | |
- group.battery_alert | |
battery_alert: | |
control: hidden | |
entities: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
- input_text.mqtt_topic | |
- input_text.clear_mqtt_topic | |
- input_text.html5_notify_name | |
- automation.battery_notification | |
- automation.battery_notification_clear | |
- automation.battery_notification_slack | |
- automation.battery_notification_telegram | |
- automation.battery_notification_pushover | |
- automation.battery_notification_html5 | |
- automation.battery_notification_join | |
- automation.battery_sensor_from_attributes | |
- automation.update_battery_status_group_members | |
- automation.clear_mqtt_topic | |
################################################ | |
## Input Number | |
################################################ | |
input_number: | |
battery_alert_threshold_max: | |
name: "Max Alert Threshold" | |
icon: mdi:arrow-collapse-up | |
mode: slider | |
min: -1 | |
max: 100 | |
# initial: 40 | |
battery_alert_threshold_min: | |
name: "Min Alert Threshold" | |
icon: mdi:arrow-collapse-down | |
mode: slider | |
min: -1 | |
max: 100 | |
# initial: -1 | |
################################################ | |
## Input Text | |
################################################ | |
input_text: | |
mqtt_topic: | |
name: MQTT Discovery Topic | |
mode: text | |
# initial: 'homeassistant' | |
clear_mqtt_topic: | |
name: MQTT Topic to Clear | |
mode: text | |
# initial: '' | |
html5_notify_name: | |
name: HTML5 Notifier Name | |
mode: text | |
# initial: '' | |
################################################ | |
## Automation | |
################################################ | |
automation: | |
- alias: battery_notification | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
minutes: '/15' | |
seconds: 00 | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: &low_battery_check > | |
{% macro battery_level() %} | |
{% for entity_id in states.group.battery_status.attributes.entity_id if ( | |
not is_state_attr(entity_id, 'battery_alert_disabled', true) | |
and ( | |
( | |
( | |
states(entity_id) is number | |
or states(entity_id) | length == states(entity_id)| int | string | length | |
or states(entity_id) | length == states(entity_id)| float | string | length | |
) | |
and states(entity_id) | int < states.input_number.battery_alert_threshold_max.state | int | |
and states(entity_id) | int > states.input_number.battery_alert_threshold_min.state | int | |
) | |
or states(entity_id) | lower == 'low' | |
or states(entity_id) | lower == 'unknown' | |
) | |
) -%} | |
{{ state_attr(entity_id, "friendly_name") }} ({{ states(entity_id) }}) | |
{% endfor -%} | |
{% endmacro %} | |
{{ battery_level() | trim != "" }} | |
- service: persistent_notification.create | |
data_template: | |
title: "Low Battery Levels" | |
notification_id: low_battery_alert | |
message: &message > | |
{% macro battery_level() %} | |
{% for entity_id in states.group.battery_status.attributes.entity_id if ( | |
not is_state_attr(entity_id, 'battery_alert_disabled', true) | |
and ( | |
( | |
( | |
states(entity_id) is number | |
or states(entity_id) | length == states(entity_id)| int | string | length | |
or states(entity_id) | length == states(entity_id)| float | string | length | |
) | |
and states(entity_id) | int < states.input_number.battery_alert_threshold_max.state | int | |
and states(entity_id) | int > states.input_number.battery_alert_threshold_min.state | int | |
) | |
or states(entity_id) | lower == 'low' | |
or states(entity_id) | lower == 'unknown' | |
) | |
) -%} | |
{{ state_attr(entity_id, "friendly_name") }} ({{ states(entity_id) }}) | |
{% endfor -%} | |
{% endmacro %} | |
{{ battery_level() }} | |
- alias: battery_notification_clear | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
minutes: '/15' | |
seconds: 00 | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: &low_battery_clear > | |
{% macro battery_level() %} | |
{% for entity_id in states.group.battery_status.attributes.entity_id if ( | |
not is_state_attr(entity_id, 'battery_alert_disabled', true) | |
and ( | |
( | |
( | |
states(entity_id) is number | |
or states(entity_id) | length == states(entity_id)| int | string | length | |
or states(entity_id) | length == states(entity_id)| float | string | length | |
) | |
and states(entity_id) | int < states.input_number.battery_alert_threshold_max.state | int | |
and states(entity_id) | int > states.input_number.battery_alert_threshold_min.state | int | |
) | |
or states(entity_id) | lower == 'low' | |
or states(entity_id) | lower == 'unknown' | |
) | |
) -%} | |
{{ state_attr(entity_id, "friendly_name") }} ({{ states(entity_id) }}) | |
{% endfor -%} | |
{% endmacro %} | |
{{ battery_level() | trim == "" }} | |
- service: persistent_notification.dismiss | |
data: | |
notification_id: low_battery_alert | |
- alias: battery_notification_slack | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
at: '10:00:00' | |
- platform: time | |
at: '18:00:00' | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: *low_battery_check | |
- service: notify.slack_notify | |
data_template: | |
message: "Low Battery Levels" | |
data: | |
attachments: | |
- color: '#52c0f2' | |
title: "These devices have low battery levels" | |
text: *message | |
- alias: battery_notification_telegram | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
at: '10:00:00' | |
- platform: time | |
at: '18:00:00' | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: *low_battery_check | |
- service: notify.telegram | |
data_template: | |
title: "Low Battery Levels" | |
message: *message | |
- alias: battery_notification_pushover | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
at: '10:00:00' | |
- platform: time | |
at: '18:00:00' | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: *low_battery_check | |
- service: notify.pushover | |
data_template: | |
title: "Low Battery Levels" | |
message: *message | |
- alias: battery_notification_html5 | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
at: '10:00:00' | |
- platform: time | |
at: '18:00:00' | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: *low_battery_check | |
- service_template: > | |
{% if states.input_text.html5_notify_name.state != "" %} | |
notify.{{ states.input_text.html5_notify_name.state }} | |
{% else %} | |
notify.notify | |
{% endif %} | |
data_template: | |
title: "Low Battery Levels" | |
message: *message | |
- alias: battery_notification_join | |
initial_state: 'on' | |
trigger: | |
- platform: time | |
at: '10:00:00' | |
- platform: time | |
at: '18:00:00' | |
- platform: state | |
entity_id: | |
- input_number.battery_alert_threshold_min | |
- input_number.battery_alert_threshold_max | |
action: | |
- condition: template | |
value_template: *low_battery_check | |
- service: notify.joaoapps_join | |
data_template: | |
title: "Low Battery Levels" | |
message: *message | |
- alias: battery_sensor_from_attributes | |
initial_state: 'on' | |
trigger: | |
- platform: event | |
event_type: state_changed | |
condition: | |
- condition: template | |
value_template: "{{ trigger.event.data is not none }}" | |
- condition: template | |
value_template: "{{ trigger.event.data.old_state is not none }}" | |
- condition: template | |
value_template: "{{ trigger.event.data.new_state is not none }}" | |
- condition: template | |
value_template: "{{ trigger.event.data.new_state.attributes is not none }}" | |
- condition: template | |
value_template: "{{ 'battery' not in trigger.event.data.new_state.name | lower }}" | |
- condition: template | |
value_template: "{{ not is_state_attr(trigger.event.data.entity_id, 'device_class', 'battery') }}" | |
- condition: template | |
value_template: "{{ not is_state_attr(trigger.event.data.entity_id, 'battery_sensor_creation_disabled', true) }}" | |
- condition: or | |
conditions: | |
- condition: template | |
value_template: "{{ trigger.event.data.new_state.attributes.battery_level is defined }}" | |
- condition: template | |
value_template: "{{ trigger.event.data.new_state.attributes.battery is defined }}" | |
- condition: template | |
value_template: "{{ trigger.event.data.new_state.attributes['Battery numeric'] is defined }}" | |
action: | |
- service: mqtt.publish | |
data_template: | |
# topic: "homeassistant/sensor/{{ trigger.event.data.entity_id.split('.')[1] }}_battery/config" | |
topic: "{{ states.input_text.mqtt_topic.state }}/sensor/{{ trigger.event.data.entity_id.split('.')[1] }}_battery/config" | |
retain: true | |
payload: &config_payload >- | |
{ | |
"device_class": "battery", | |
"name": "{{ trigger.event.data.new_state.name }} Battery", | |
"state_topic": "{{ states.input_text.mqtt_topic.state }}/sensor/{{ trigger.event.data.entity_id.split('.')[1] }}_battery/state", | |
"unit_of_measurement": "%", | |
{% if trigger.event.data.new_state.attributes.battery_template is defined -%} | |
"value_template": "{{ trigger.event.data.new_state.attributes.battery_template }}", | |
{% else -%} | |
"value_template": "{{ "{{" }} value_json.value | int {{ "}}" }}", | |
{% endif -%} | |
"unique_id": "{{ trigger.event.data.entity_id.split('.')[1] }}_battery", | |
"json_attributes": [ | |
"entity_id", | |
"attribute", | |
"mqtt_config_topic", | |
"mqtt_state_topic" | |
] | |
} | |
- service: mqtt.publish | |
data_template: | |
topic: "{{ states.input_text.mqtt_topic.state }}/sensor/{{ trigger.event.data.entity_id.split('.')[1] }}_battery/state" | |
retain: true | |
payload: >- | |
{ | |
{% if trigger.event.data.new_state.attributes.battery_level is defined -%} | |
{%- set attrib = trigger.event.data.new_state.attributes.battery_level -%} | |
{%- elif trigger.event.data.new_state.attributes.battery is defined -%} | |
{%- set attrib = trigger.event.data.new_state.attributes.battery -%} | |
{%- elif trigger.event.data.new_state.attributes['Battery numeric'] is defined -%} | |
{%- set attrib = (trigger.event.data.new_state.attributes['Battery numeric'] | int + 1) * 10 -%} | |
{%- else -%} | |
{%- set attrib = "unknown" -%} | |
{%- endif -%} | |
"value": {%- if attrib is number | |
or attrib | length == attrib | int | string | length | |
or attrib | length == attrib | float | string | length | |
-%} | |
{{ attrib | int }} | |
{%- else -%} | |
"{{ attrib }}" | |
{%- endif %}, | |
"entity_id": "{{ trigger.event.data.entity_id }}", | |
{% if trigger.event.data.new_state.attributes.battery_level is defined -%} | |
"attribute": "battery_level", | |
{%- elif trigger.event.data.new_state.attributes.battery is defined -%} | |
"attribute": "battery", | |
{%- elif trigger.event.data.new_state.attributes['Battery numeric'] is defined -%} | |
"attribute": "Battery numeric", | |
{%- else -%} | |
"attribute": "unknown", | |
{%- endif %} | |
"mqtt_config_topic": "{{ states.input_text.mqtt_topic.state }}/sensor/{{ trigger.event.data.entity_id.split('.')[1] }}_battery/config", | |
"mqtt_state_topic": "{{ states.input_text.mqtt_topic.state }}/sensor/{{ trigger.event.data.entity_id.split('.')[1] }}_battery/state" | |
} | |
- alias: update_battery_status_group_members | |
initial_state: 'on' | |
trigger: | |
- platform: homeassistant | |
event: start | |
- platform: time | |
minutes: '/5' | |
seconds: 00 | |
action: | |
- service: group.set | |
data_template: | |
object_id: "battery_status" | |
entities: >- | |
{%- for item in states.sensor if ( | |
is_state_attr(item.entity_id, 'device_class', 'battery') | |
or 'battery' in item.attributes.icon | lower | |
or (item.entity_id | lower).endswith('_bat') | |
or (item.name | lower).endswith('_bat') | |
) or ( | |
( | |
'battery' in item.entity_id | lower | |
or 'battery' in item.name | lower | |
) and ( | |
item.attributes.icon is not defined | |
) | |
) | |
-%} | |
{{ item.entity_id }}{% if not loop.last %}, {% endif %} | |
{%- endfor -%} | |
- alias: clear_mqtt_topic | |
initial_state: 'on' | |
trigger: | |
- platform: state | |
entity_id: | |
- input_text.clear_mqtt_topic | |
condition: | |
- condition: template | |
value_template: "{{ '{{ states.input_text.mqtt_topic.state }}/sensor/' in states.input_text.clear_mqtt_topic.state }}" | |
action: | |
- service: mqtt.publish | |
data_template: | |
topic: "{{ states.input_text.clear_mqtt_topic.state }}" | |
retain: true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment