HowTo: Get notified on empty batteries

I have implemented this way:

var whatitis = "";
var percenttocheck = 15;

           .filter(function(batt) {return batt.state == percenttocheck ; } )
           .forEach(function(batt) { whatitis = whatitis + " " + batt.label + " "; } );
        if (whatitis != "") {
1 Like

hey michaeljoos - i copy pasted and it works now :slight_smile: something with the IR part of my own didnt work. from a logic perspective you use == vs <= which is my implementation. basically you run so that you get an alert when it become 15 right? but what happens if for some reason a battery drops more than than one unit? wont you miss the alert?

Did you try the code I posted?
I run it once a day.
It will send an email if the battery is less than or equal to 15% and on Sunday it sends a list of all the batteries in the battery group.
It is for OH4 which is what you said you are using.

hi Greg,

thanks for sending it through. I went through it. however your code is email based and i prefer the notification element offered by my code (it sends an alert to the openhab app) - so i just adjusted my own with the part offered by michaeljoos

just playing with the logs now to wrap up.

Ok, thanks for the reply.
You can put your notification in the code below instead of using email.
Anyway if it works for you that is good.

1 Like

For future readers of this thread, there is a rule template on the marketplace that handles this use case.

  1. Install the rule templated from the Automation menu.
  2. Create a Rule of Script that sends the alert. This is where you send the alert. I use the following:
configuration: {}
triggers: []
conditions: []
  - inputs: {}
    id: "1"
      type: application/javascript;version=ECMAScript-2021
      script: >
        var {alerting} = require('rlk_personal');

        var logger = log('Low Battery');

        alerting.sendAlert('The following batteries are below 10%: ' + this.threshItemLabels, logger);
    type: script.ScriptAction

  1. Instantiate a new rule using Threshold Alert as the template. I use the following configuration.
Parameter Purpose Value
Triggering Group Group with all the battery level Items AllBatteries
Threshold State The threshold value to compare against, if the value is < this the alert rule is called. The rule handles UoM 15 %
Comparison Operator If Item State <operator> Threshold is true, the alert rule is called. <
Alert Rule UID of the rule created in step 2. battery_alert
Do Not Disturb Do not call the alert rule between these two times, wait until the end of the time period. This prevents alerts from being sent over night. Start: 22:00, End: 08:00
Rate Limit Do not call the alert rule more often than this. For example, don’t alert more than once every eight hours. PT8H

All the other properties are left at the defaults.

This rule template is pretty handy. I use it to send an alert when a door is left open too long, when a battery goes low and needs to be replaced soon, a sensor stops reporting, a service goes offline, and as a motion sensor timer.


Yes, corrrect. Should be < or <=
The code I have shared and updated here was for Homematic batteries where I have LowBattery == ON/OFF.

1 Like

I am a little bit confused. What is valid now for OH4.04 release?
What would be state of art implementation for Battery notification? The rule from Greg posted above for OH4 or your rule template @rlkoshak ?
I assume the rule from market will be maintained but I see some restrictions. Are they resolved now? Can I use the proposed template or shall I rather go with proven rule form @ubeaut ?

For some reasons I have a notification for this part of code. Raw 35 starts with
for (var i_index in i_list) {

    var datetoday = new Date();
    var numberofweek = datetoday.getDay();

    This will check the percentage of battery left and if it is low then email
    Add the items to check into gBatteries group
    var percenttocheck = 65;
    var heading="Openhab daily low sensor battery report";

    //Only do on Sundays (numberofweek is 0)
    if (numberofweek == 0){ 
        var percenttocheck = 100;
        var heading="Openhab weekly sensor battery report";

    var email_message = "";
    var i;
    var sendmail="";
    var i_list = items.getItem("gBatteries").members;

    for (var i_index in i_list) {
        i = i_list[i_index];
        if(i.state <= percenttocheck){
            email_message = email_message + i.label + " " + i.state + "%" + "\r\n";

        message = "<H2>Sensor battery report <br>" +email_message +"</H2>" + "Percentage check was set at " +percenttocheck;
        actions.get("mail", "mail:smtp:213647137d").sendHtmlMail("", heading, message );;
2023-11-24 14:40:42.549 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'batterystatus.rules' has errors, therefore ignoring it: [35,25]: missing ';' at 'i_list'

Well, obviously I’m going to say the rule template. But you should use what ever you are comfortable using.

That rule template though, while being rather complex, is my most tested template and probably my second most used template so it’s pretty solid.

The rule template has more features including a “do not disturb” period where, for example, if a batter goes low in the middle of the night it will wait until morning to tell you. It also supports a different threshold level per battery as it seems that each device has it’s own unique meaning for remaining battery. I’ve one device that when it gets to 20% I still have 3-6 months left before I need to replace the battery while another one should be replaced at 30% because it has a mere day or two left.

Do you have the battery level items in gBatteries group?
Add them to the group using direct add members.

I copied the script you posted and changed the group name and ran it and It worked for me. I even sent to email to you address.

I am not sure if the
for (i_index in i_list) { }

is structured properly.

I copied yours and changed the battery group as well.
In my code gBatterycheck has been replaced by gBatteries

My levels just show 100. Yours have a % on them. I wonder if that has anything to do with it?
Probably not but that’s the only difference I can see.

I run OH 4.0.4. Updated from OH3. I know in OH4 some items values were updated in case of units.
What OH version you have? If it is not the same I am wondering if your script will run with the latest build.

I am running 4.0.4 and mine was upgraded from OH3. To be honest I never used units for anything.

Here is a widget for batteries. Run it and see if works for you as well.

uid: Status-list-battery-level
tags: []
    - context: item
      default: gBatterycheck
      description: Group item to list
      label: Item
      name: item
      required: true
      type: TEXT
  parameterGroups: []
timestamp: May 23, 2023, 2:12:49 PM
component: oh-list
    --f7-list-item-after-font-size: 12px
    --f7-list-item-after-font-weight: bold
    --f7-list-item-after-text-color: var(--f7-text-color)
    min-width: 250px
    - component: oh-repeater
        for: index
        fragment: true
        groupItem: =props.item
        sourceType: itemsInGroup
          - component: oh-list-item
              after: =loop.index.state
              icon: ="oh:battery"
              iconUseState: true
              title: =loop.index.label

Yes. As widget it runs well. Also without %. My previos pisture was showing the Group Item driectly

Well, I am out of ideas.
Strange we are using the same versions of OH.

Officially the for shall look like that:

for(var i=1; i<4; i++) {


We do not have “;” in your code i do not understand the way you check the index matrix. But I am not a coding expert.
When I comment the whole for () loop, warning disappear. So definitively there is sth wrong with the for ()

I am not a coder either. I just got it to work and never looked at why it worked :grinning: