HowTo: Get notified on empty batteries

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
    */
    //DAILY REPORT
    var percenttocheck = 65;
    var heading="Openhab daily low sensor battery report";

    //WEEKLY 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){
            sendmail="YES";
            console.info('Test',i.label,i.state);
            email_message = email_message + i.label + " " + i.state + "%" + "\r\n";
        }
    }

    if(sendmail=="YES"){
        message = "<H2>Sensor battery report <br>" +email_message +"</H2>" + "Percentage check was set at " +percenttocheck;
        actions.get("mail", "mail:smtp:213647137d").sendHtmlMail("jacekdebski76@gmail.com", heading, message );
        console.info(email_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: []
props:
  parameters:
    - 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
config:
  style:
    --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
slots:
  default:
    - component: oh-repeater
      config:
        for: index
        fragment: true
        groupItem: =props.item
        sourceType: itemsInGroup
      slots:
        default:
          - component: oh-list-item
            config:
              after: =loop.index.state
              footer: =loop.index.name
              icon: ="oh:battery"
              iconUseState: true
              item: =loop.index.name
              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:

How did you define the rule? I have a file named batterystatus.rules and it is structured this way. This might be the difference. Did you create the rule with the OH4 GUI?

//  Rule: Publish Battery Status
//
//  Process all items of group GRP_BatteryStatus. Check if battery is empty and create message that is published once a day.
rule "Publish Battery Status"
when

    //Time cron "0 0 18 ? * * *"
    Time cron "0 26 14 ? * * *"

then

    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
    */
    //DAILY REPORT
    var percenttocheck = 65;
    var heading="Openhab daily low sensor battery report";

    //WEEKLY 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){
            sendmail="YES";
            console.info('Test',i.label,i.state);
            email_message = email_message + i.label + " " + i.state + "%" + "\r\n";
        }
    }

    if(sendmail=="YES"){
        message = "<H2>Sensor battery report <br>" +email_message +"</H2>" + "Percentage check was set at " +percenttocheck;
        actions.get("mail", "mail:smtp:xxxxxd").sendHtmlMail("mymail@gmail.com", heading, message );
        console.info(email_message);
    }
end

I don’t do DSL its all GUI and I don’t have any files at all.
I converted all my rules from Nashorn and then removed the Nashorn addon.

can you send the code of the rule form GUI?

configuration: {}
triggers:
  - id: "1"
    configuration:
      time: 06:30
    type: timer.TimeOfDayTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    label: Check percentage of batteries and then email.
    description: Also send a weekly battery report once a week as well.
    configuration:
      type: application/javascript
      script: >+
        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 gBatterycheck group

        */

        //DAILY REPORT

        var percenttocheck = 15;

        var heading="Openhab daily low sensor battery report"


        //WEEKLY 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("gBatterycheck").members;

        for (var i_index in i_list) {
          i = i_list[i_index];
          if(i.state <= percenttocheck){sendmail="YES"
        //  console.info('Test',i.label,i.state);
          email_message = email_message + i.label + " " + i.state + "%" + "\r\n";
                                       }
        }

        if(sendmail=="YES"){
          message = "<H2>Sensor battery report <br>" +email_message +"</H2>" + "Percentage check was set at " +percenttocheck;
          actions.get("mail", "mail:smtp:a514b96247").sendHtmlMail("you@gmail.com", heading, message );
          console.info(email_message);  
        }

    type: script.ScriptAction

I understood the difference. I did not use the same way writing a script.
After correction I receive the following error:

2023-11-24 23:18:03.538 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - ScriptEngine for language 'application/javascript' could not be found for identifier: a534f39d-508f-49c6-8ed1-231ae579ced8

For testing phase I changed the battery status to <=65%

Go to rule on the GUI
Click the rule like you are going to edit it.
Click the ^ symbol on the bottom right hand side.
A pop up appears.
Select ECMAScript 262 Edition 11
Click save top right hand side.
Then click the run script to test.