Howto create battery alert without creating a template for every device

Thanks. That explains it.

How do i get this project to pick up the IKEA Tradfri remotes battery levels?

The battery entity should get created the next time there is a state change for that sensor. After that, you should start getting alerts for it.

Will this code work out of the box with Hass.io? Or do I need the MosquittoMQTT addon package installed?

Yes, it works with hassio. Yes, you need to install and configure the Mosquitto addon.

I added the MQTT addon, started it and added the below to my configuration.yaml file along with creating a package as described in your instructions. I’m trying to run the automation’s manually but no state card is showing up. Any advise would be appreciated.

mqtt:
  broker: core-mosquitto
  discovery: true
  discovery_prefix: homeassistant

HI @NotoriousBDG

very cool, thanks for your latest additions!

its getting very very precise though:

40
Maybe some rounding could be added :wink:

Also, all of a sudden i have 3 extra (mqtt) sensors showing up, and state inspector shows i already have them, since it adds _2… (they’re the Unknown ones, the real ones have a value…)
33
01

Is this the discovery: true setting in Mqtt, or your battery alert?

As you can see, the tradfri sensor doesn’t show in the battery alert while it has 60% and other batteries have higher levels and are showing.

Ive set the levels between 10 and 80, so the tradfri should show up?
04

Cheers,
Marius

Is there a way to ignore device trackers? I read through the progression of this project and saw how it was added, but with the newest code, I can’t figure out how to remove it. I don’t want to get notified every time one of our cell phones are below the threshold.

Thanks.

You can’t run the “Battery Sensor from…” automations manually because they rely on the entity that triggers the automation. You’ll have to trigger a state change on your devices to force the battery sensor to show up (or just wait for the next time the sensor reports in).

Hehe! A new version is below that rounds battery levels to integers.

Those definitely aren’t from this package.

Not following. None of those entities have “battery” in its name so they won’t be monitored. Which one represents a battery and how do you know that it represents a battery?

There isn’t an easy way to ignore devices by domain. The easiest way now is to create an entry in your customize section for each battery sensor you want to ignore.

homeassistant:
  customize:
    sensor.sensor_name_to_ignore_battery:
      battery_alert_disabled: true

Here’s the updated package that rounds battery levels.

################################################################
## Packages / Battery Alert
################################################################

################################################################
## 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
##
################################################################

################################################
## Customize
################################################

homeassistant:
  customize:
    ################################################
    ## Node Anchors
    ################################################

    package.node_anchors:
      customize: &customize
        package: 'battery_alert'

      expose: &expose
        <<: *customize
        haaska_hidden: false
        homebridge_hidden: false

    ################################################
    ## Group
    ################################################

    group.battery_alert:
      <<: *customize
      friendly_name: "Battery Alert"
      icon: mdi:steam

    ################################################
    ## 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_alert_slack:
      <<: *customize
      friendly_name: "Battery Slack Notification"
      icon: mdi:comment-alert-outline

    automation.battery_sensor_from_battery_level_attribute:
      <<: *customize
      friendly_name: "Battery Sensor from battery_level Attribute"
      icon: mdi:battery-alert

    automation.battery_sensor_from_battery_attribute:
      <<: *customize
      friendly_name: "Battery Sensor from battery Attribute"
      icon: mdi:battery-alert

    automation.battery_sensor_from_battery_numeric_attribute:
      <<: *customize
      friendly_name: "Battery Sensor from battery numeric Attribute"
      icon: mdi:battery-alert

################################################
## Group
################################################

group:
  battery_alert:
    control: hidden
    entities:
      - input_number.battery_alert_threshold_min
      - input_number.battery_alert_threshold_max
      - automation.battery_notification
      - automation.battery_notification_clear
      - automation.battery_alert_slack
      - automation.battery_sensor_from_battery_level_attribute
      - automation.battery_sensor_from_battery_attribute
      - automation.battery_sensor_from_battery_numeric_attribute

################################################
## 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

################################################
## Automation
################################################

automation:
- alias: battery_notification
  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: >
        {% macro battery_level() %}
          {%- for item in states.sensor if (
            "battery" in item.name | lower
            and not "voltage" in item.name | lower
            and not "runtime" in item.name | lower
            and not "setpoint" in item.name | lower
            and not "charge" in item.name | lower
            and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          ) and (
            (
              (
                item.state is number
                or item.state | length == item.state | int | string | length
                or item.state | length == item.state | float | string | length
              )
              and item.state | int < states.input_number.battery_alert_threshold_max.state | int
              and item.state | int > states.input_number.battery_alert_threshold_min.state | int
            )
            or item.state | lower == "low"
            or item.state | lower == "unknown"
          ) -%}
          {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
          {%- endfor -%}
        {% endmacro %}
        {{ battery_level() | trim != "" }}
    - service: persistent_notification.create
      data_template:
        title: "Low Battery levels"
        notification_id: low-battery-alert
        message: >
          {% macro battery_level() %}
            {%- for item in states.sensor if (
              "battery" in item.name | lower
              and not "voltage" in item.name | lower
              and not "runtime" in item.name | lower
              and not "setpoint" in item.name | lower
              and not "charge" in item.name | lower
              and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
            ) and (
              (
                (
                  item.state is number
                  or item.state | length == item.state | int | string | length
                  or item.state | length == item.state | float | string | length
                )
                and item.state | int < states.input_number.battery_alert_threshold_max.state | int
                and item.state | int > states.input_number.battery_alert_threshold_min.state | int
              )
              or item.state | lower == "low"
              or item.state | lower == "unknown"
            ) -%}
            {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
            {%- endfor -%}
          {% endmacro %}
          {{ battery_level() }}

- alias: battery_notification_clear
  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: >
        {% macro battery_level() %}
          {%- for item in states.sensor if (
            "battery" in item.name | lower
            and not "voltage" in item.name | lower
            and not "runtime" in item.name | lower
            and not "setpoint" in item.name | lower
            and not "charge" in item.name | lower
            and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          ) and (
            (
              (
                item.state is number
                or item.state | length == item.state | int | string | length
                or item.state | length == item.state | float | string | length
              )
              and item.state | int < states.input_number.battery_alert_threshold_max.state | int
              and item.state | int > states.input_number.battery_alert_threshold_min.state | int
            )
            or item.state | lower == "low"
            or item.state | lower == "unknown"
          ) -%}
          {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
          {%- endfor -%}
        {% endmacro %}
        {{ battery_level() | trim == "" }}
    - service: persistent_notification.dismiss
      data:
        notification_id: low-battery-alert

- alias: battery_alert_slack
  trigger:
    - platform: time
      at: '10:00:00'
    - platform: time
      at: '18:00:00'
  action:
    - condition: template
      value_template: >
        {% macro battery_level() %}
          {%- for item in states.sensor if (
            "battery" in item.name | lower
            and not "voltage" in item.name | lower
            and not "runtime" in item.name | lower
            and not "setpoint" in item.name | lower
            and not "charge" in item.name | lower
            and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          ) and (
            (
              (
                item.state is number
                or item.state | length == item.state | int | string | length
                or item.state | length == item.state | float | string | length
              )
              and item.state | int < states.input_number.battery_alert_threshold_max.state | int
              and item.state | int > states.input_number.battery_alert_threshold_min.state | int
            )
            or item.state | lower == "low"
            or item.state | lower == "unknown"
          ) -%}
          {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
          {%- endfor -%}
        {% endmacro %}
        {{ battery_level() | trim != "" }}
    - service: notify.slack_notify
      data_template:
        message: "Low Battery Levels"
        data:
          attachments:
          - color: '#52c0f2'
            title: "These devices have low battery levels"
            text: >
              {% macro battery_level() %}
                {%- for item in states.sensor if (
                  "battery" in item.name | lower
                  and not "voltage" in item.name | lower
                  and not "runtime" in item.name | lower
                  and not "setpoint" in item.name | lower
                  and not "charge" in item.name | lower
                  and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
                ) and (
                  (
                    (
                      item.state is number
                      or item.state | length == item.state | int | string | length
                      or item.state | length == item.state | float | string | length
                    )
                    and item.state | int < states.input_number.battery_alert_threshold_max.state | int
                    and item.state | int > states.input_number.battery_alert_threshold_min.state | int
                  )
                  or item.state | lower == "low"
                  or item.state | lower == "unknown"
                ) -%}
                {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
                {%- endfor -%}
              {% endmacro %}
              {{ battery_level() }}

- alias: battery_sensor_from_battery_level_attribute
  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.new_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.old_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes.battery_level is defined }}"
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/config"
        retain: true
        payload: >-
          {
            "device_class": "sensor",
            "name": "{{ trigger.event.data.new_state.name }} Battery",
            "state_topic": "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state",
            "unit_of_measurement": "%"
          }
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state"
        retain: true
        payload: "{{ trigger.event.data.new_state.attributes.battery_level | int }}"

- alias: battery_sensor_from_battery_attribute
  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.new_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.old_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes.battery is defined }}"
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/config"
        retain: true
        payload: >-
          {
            "device_class": "sensor",
            "name": "{{ trigger.event.data.new_state.name }} Battery",
            "state_topic": "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state",
            "unit_of_measurement": "%"
          }
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state"
        retain: true
        payload: "{{ trigger.event.data.new_state.attributes.battery | int }}"

- alias: battery_sensor_from_battery_numeric_attribute
  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.new_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.old_state is not none }}"
    - 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.new_state.object_id }}_battery/config"
        retain: true
        payload: >-
          {
            "device_class": "sensor",
            "name": "{{ trigger.event.data.new_state.name }} Battery",
            "state_topic": "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state",
            "unit_of_measurement": "%"
          }
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state"
        retain: true
        payload: "{{ (trigger.event.data.new_state.attributes['Battery numeric'] | int + 1) * 10 }}"
3 Likes

:+1:
cool, thanks!

they must be created by the mqtt: discovery: true then. Why I can’t see just yet, have many more and they’re un-duplicated…

Sorry, should have been more specific:

this are hue sensors:


and this is a Tradfri sensor:

Question/wish:
the automation runs every 15 minutes, and one can edit the frequency obviously. It is however very obtrusive if one has several batteries needing attention and this runs timebased as it does.
Could it be an option to only have it trigger if and when a battery needs attention? Waking up today showed 24 notifications waiting for me… just one persistent notification would suffice wouldnt it? After which a new lower threshold would kick in maybe.

Maybe the above behavior is caused by the iPhone very quickly depleting because of the HomeAssistant tracking iOS :wink: all the more reason to keep activity down a bit…
Not sure if commenting out the trigger
trigger:
- platform: time
minutes: ‘/15’
seconds: 00
won’t break the package too much?
Cheers and thanks,!
Marius

Everything was looking good. But after a reboot of ResinOS, I got the "Invalid Config - mgtt " message.

Anything to worry about?

Those are interesting. If I understand correctly, those sensors are battery sensors, but for some reason, they were created without “battery” in their name. That seems to be the same thing that @mcfrojd mentioned above. The way I see it, there are 3 options.

  1. Get the Tradfri and Hue components updated so battery sensors have battery in their name. This is probably the best solution long term, but out of scope for this discussion.
  2. Use customize to “fix” the entity name so that it includes “battery”. Use the updated package below to prevent creating duplicate sensors if you go this route.
  3. Force a state change for those sensors or just wait. A battery sensor will eventually be created, but it might take a while since battery levels don’t change very fast. The problem with this option is that you’ll essentially end up with 2 sensors that report the same state.

Options 2 and 3 will work with the updated package below, but I recommend using customize to add “battery” to those sensor names.

That is possible, but I’m intentionally avoiding that because I don’t want to be notified more than twice daily. I’m ok with persistent notifications updating anytime because those are just shown in the UI. Making it trigger when batteries need attention might cause the notification to come at an inconvenient time.

The persistent notification has a hardcoded id to make sure you only see 1 notification. I don’t understand how you are seeing 24 of them. Did you make any modifications to the package? If so, can you post the code you’re using?

I made a change to the persistent notification automation that will prevent calling the persistent_notification.create service if there is already a notification visible with the exact same content.

That would essentially disable the persistent notification.

Finally, here’s the updated package.

################################################################
## Packages / Battery Alert
################################################################

################################################################
## 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
##
################################################################

################################################
## Customize
################################################

homeassistant:
  customize:
    ################################################
    ## Node Anchors
    ################################################

    package.node_anchors:
      customize: &customize
        package: 'battery_alert'

      expose: &expose
        <<: *customize
        haaska_hidden: false
        homebridge_hidden: false

    ################################################
    ## Group
    ################################################

    group.battery_alert:
      <<: *customize
      friendly_name: "Battery Alert"
      icon: mdi:steam

    ################################################
    ## 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_alert_slack:
      <<: *customize
      friendly_name: "Battery Slack Notification"
      icon: mdi:comment-alert-outline

    automation.battery_sensor_from_battery_level_attribute:
      <<: *customize
      friendly_name: "Battery Sensor from battery_level Attribute"
      icon: mdi:battery-alert

    automation.battery_sensor_from_battery_attribute:
      <<: *customize
      friendly_name: "Battery Sensor from battery Attribute"
      icon: mdi:battery-alert

    automation.battery_sensor_from_battery_numeric_attribute:
      <<: *customize
      friendly_name: "Battery Sensor from battery numeric Attribute"
      icon: mdi:battery-alert

################################################
## Group
################################################

group:
  battery_alert:
    control: hidden
    entities:
      - input_number.battery_alert_threshold_min
      - input_number.battery_alert_threshold_max
      - automation.battery_notification
      - automation.battery_notification_clear
      - automation.battery_alert_slack
      - automation.battery_sensor_from_battery_level_attribute
      - automation.battery_sensor_from_battery_attribute
      - automation.battery_sensor_from_battery_numeric_attribute

################################################
## 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

################################################
## Automation
################################################

automation:
- alias: battery_notification
  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: >
        {% macro battery_level() %}
          {%- for item in states.sensor if (
            "battery" in item.name | lower
            and not "voltage" in item.name | lower
            and not "runtime" in item.name | lower
            and not "setpoint" in item.name | lower
            and not "charge" in item.name | lower
            and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          ) and (
            (
              (
                item.state is number
                or item.state | length == item.state | int | string | length
                or item.state | length == item.state | float | string | length
              )
              and item.state | int < states.input_number.battery_alert_threshold_max.state | int
              and item.state | int > states.input_number.battery_alert_threshold_min.state | int
            )
            or item.state | lower == "low"
            or item.state | lower == "unknown"
          ) -%}
          {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
          {%- endfor -%}
        {% endmacro %}
        {{ battery_level() | trim != "" and not is_state_attr('persistent_notification.lowbatteryalert', 'message', battery_level()) }}
    - service: persistent_notification.create
      data_template:
        title: "Low Battery levels"
        notification_id: low-battery-alert
        message: >
          {% macro battery_level() %}
            {%- for item in states.sensor if (
              "battery" in item.name | lower
              and not "voltage" in item.name | lower
              and not "runtime" in item.name | lower
              and not "setpoint" in item.name | lower
              and not "charge" in item.name | lower
              and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
            ) and (
              (
                (
                  item.state is number
                  or item.state | length == item.state | int | string | length
                  or item.state | length == item.state | float | string | length
                )
                and item.state | int < states.input_number.battery_alert_threshold_max.state | int
                and item.state | int > states.input_number.battery_alert_threshold_min.state | int
              )
              or item.state | lower == "low"
              or item.state | lower == "unknown"
            ) -%}
            {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
            {%- endfor -%}
          {% endmacro %}
          {{ battery_level() }}

- alias: battery_notification_clear
  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: >
        {% macro battery_level() %}
          {%- for item in states.sensor if (
            "battery" in item.name | lower
            and not "voltage" in item.name | lower
            and not "runtime" in item.name | lower
            and not "setpoint" in item.name | lower
            and not "charge" in item.name | lower
            and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          ) and (
            (
              (
                item.state is number
                or item.state | length == item.state | int | string | length
                or item.state | length == item.state | float | string | length
              )
              and item.state | int < states.input_number.battery_alert_threshold_max.state | int
              and item.state | int > states.input_number.battery_alert_threshold_min.state | int
            )
            or item.state | lower == "low"
            or item.state | lower == "unknown"
          ) -%}
          {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
          {%- endfor -%}
        {% endmacro %}
        {{ battery_level() | trim == "" }}
    - service: persistent_notification.dismiss
      data:
        notification_id: low-battery-alert

- alias: battery_alert_slack
  trigger:
    - platform: time
      at: '10:00:00'
    - platform: time
      at: '18:00:00'
  action:
    - condition: template
      value_template: >
        {% macro battery_level() %}
          {%- for item in states.sensor if (
            "battery" in item.name | lower
            and not "voltage" in item.name | lower
            and not "runtime" in item.name | lower
            and not "setpoint" in item.name | lower
            and not "charge" in item.name | lower
            and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
          ) and (
            (
              (
                item.state is number
                or item.state | length == item.state | int | string | length
                or item.state | length == item.state | float | string | length
              )
              and item.state | int < states.input_number.battery_alert_threshold_max.state | int
              and item.state | int > states.input_number.battery_alert_threshold_min.state | int
            )
            or item.state | lower == "low"
            or item.state | lower == "unknown"
          ) -%}
          {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
          {%- endfor -%}
        {% endmacro %}
        {{ battery_level() | trim != "" }}
    - service: notify.slack_notify
      data_template:
        message: "Low Battery Levels"
        data:
          attachments:
          - color: '#52c0f2'
            title: "These devices have low battery levels"
            text: >
              {% macro battery_level() %}
                {%- for item in states.sensor if (
                  "battery" in item.name | lower
                  and not "voltage" in item.name | lower
                  and not "runtime" in item.name | lower
                  and not "setpoint" in item.name | lower
                  and not "charge" in item.name | lower
                  and not is_state_attr(item.entity_id, 'battery_alert_disabled', true)
                ) and (
                  (
                    (
                      item.state is number
                      or item.state | length == item.state | int | string | length
                      or item.state | length == item.state | float | string | length
                    )
                    and item.state | int < states.input_number.battery_alert_threshold_max.state | int
                    and item.state | int > states.input_number.battery_alert_threshold_min.state | int
                  )
                  or item.state | lower == "low"
                  or item.state | lower == "unknown"
                ) -%}
                {{ item.name }} ({{ item.state }}){% if not loop.last %}, {% endif %}
                {%- endfor -%}
              {% endmacro %}
              {{ battery_level() }}

- alias: battery_sensor_from_battery_level_attribute
  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.new_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.old_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes.battery_level is defined }}"
    - condition: template
      value_template: "{{ 'battery' not in trigger.event.data.new_state.name | lower }}"
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/config"
        retain: true
        payload: >-
          {
            "device_class": "sensor",
            "name": "{{ trigger.event.data.new_state.name }} Battery",
            "state_topic": "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state",
            "unit_of_measurement": "%"
          }
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state"
        retain: true
        payload: "{{ trigger.event.data.new_state.attributes.battery_level | int }}"

- alias: battery_sensor_from_battery_attribute
  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.new_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.old_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes.battery is defined }}"
    - condition: template
      value_template: "{{ 'battery' not in trigger.event.data.new_state.name | lower }}"
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/config"
        retain: true
        payload: >-
          {
            "device_class": "sensor",
            "name": "{{ trigger.event.data.new_state.name }} Battery",
            "state_topic": "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state",
            "unit_of_measurement": "%"
          }
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state"
        retain: true
        payload: "{{ trigger.event.data.new_state.attributes.battery | int }}"

- alias: battery_sensor_from_battery_numeric_attribute
  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.new_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.old_state is not none }}"
    - condition: template
      value_template: "{{ trigger.event.data.new_state.attributes['Battery numeric'] is defined }}"
    - condition: template
      value_template: "{{ 'battery' not in trigger.event.data.new_state.name | lower }}"
  action:
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/config"
        retain: true
        payload: >-
          {
            "device_class": "sensor",
            "name": "{{ trigger.event.data.new_state.name }} Battery",
            "state_topic": "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state",
            "unit_of_measurement": "%"
          }
    - service: mqtt.publish
      data_template:
        topic: "homeassistant/sensor/{{ trigger.event.data.new_state.object_id }}_battery/state"
        retain: true
        payload: "{{ (trigger.event.data.new_state.attributes['Battery numeric'] | int + 1) * 10 }}"

Yes, it looks like there might be something wrong with mqtt. Try verifying mqtt is running and check the logs for an errors.

Mqtt not mgtt

1 Like

HI,
Maybe i should have phrased more carefully, i didnt receive that many persistent notifications in HA frontend, but on my iPhone, every 15 minutes…

they are motion sensors, with an attribute battery, or battery_level, and i have several customized sensors already, even template sensor only showing the battery level of that specific motion sensor: they have 100% so wont show up for a while …:wink: ill try and change the other ones too and see if that shows up, thanks for the suggestion!

No, ive copied pasted, your previous last version. Will do so again and report back.

Cheers,
Marius

This package only sends persistent notifications or notifications via Slack. I don’t know why those are even showing up on your phone because those don’t look like Slack messages.

Actually, they look like battery sensors for the motion sensor to me because the entity’s state matches the battery and battery_level attributes.

You are right.

File “/usr/lib/python3.6/site-packages/hbmqtt/broker.py”, line 280, in start
subprotocols=[‘mqtt’])
File “/usr/lib/python3.6/site-packages/websockets/server.py”, line 356, in serve
server = yield from loop.create_server(factory, host, port, **kwds)
File “uvloop/loop.pyx”, line 1527, in create_server
File “uvloop/loop.pyx”, line 1030, in uvloop.loop.Loop._create_server
OSError: [Errno 98] error while attempting to bind on address (‘0.0.0.0’, 8080): address in use

The enire log:
https://www.dropbox.com/s/slby03iysrr5fhg/Hassio%20Error%20Log-%20MQTT.txt?dl=0

Update: -Thanks @NotoriousBDG
Its the lates ZigBee - Conbee deCONZ webinterface Add/on, using port 80 and 8080

I use Mosquitto so I don’t have any experience with the embedded mqtt broker. That error suggests you’ve got something else running on port 8080, which is required by the embedded broker. Either use Mosquitto or move whatever is using port 8080 to another port.

@NotoriousBDG do you have your code in a github repository? Would be easier to see latest code and don’t have to scroll through the forum thread to find the latest Updated version of your code.

1 Like

you’re so unforgiving :wink:
Sorry… i might have changed notify.slack_notify into notify.notify, since i don’t use Slack.

other than that, i wouldn’t know. These alerts don’t show a title, as your notify automations are programmed to do . Maybe a specific notify.notify syntax would be needed for that, but never mind, ill try and figure that out locally…

for now im more concerned with the depletion of my iPhones battery which is quite clear following these q5 minute messages. If anything, you’re package proves IOS/HomeAssistant isn’t a very economical combination.