HowTo: Get notified on empty batteries

Logs seem correct, battery report notification on mobile is empty


21:17:36.554 [INFO ] [home.event.GroupItemStateChangedEvent] - gBatteries changed from 5 to 100 through LivingRoom_FibButton_Battery
21:17:36.785 [INFO ] [lipse.smarthome.model.script.REPORT: ] - EMPTY
21:17:40.722 [INFO ] [smarthome.event.ItemStateChangedEvent] - LivingRoom_FibButton_Battery changed from 100 to 10
21:17:40.724 [INFO ] [home.event.GroupItemStateChangedEvent] - gBatteries changed from 100 to 10 through LivingRoom_FibButton_Battery
21:17:40.731 [INFO ] [eclipse.smarthome.model.script.REPORT] - LivingRoom_FibButton_Battery: 10%
21:17:40.735 [INFO ] [ipse.smarthome.model.script.MESSAGE: ] - The following batteries need to be replaced : LivingRoom_FibButton_Battery: 10%

I am stumped…
Sorry mate

1 Like

Thats ok ! Thanks for trying Vincent :slight_smile:

Not sure if this is any help, but here’s my rule for low batteries. Although I’ve not done a great deal of testing, but it certainly works as expect and I get notifications.

rule "Low battery alert"
when
    Member of Batteries changed
then
    if(Batteries.state > 35) return;
    var String msg = ""
    val lowBatteryList = Batteries.members.filter[ b | b.state < 36 ]
    lowBatteryList.forEach [ i | 
        msg = msg + i.name + ': ' + i.state.toString + '%\n'
        logInfo("org.openhab","Battery Status: Low battery at " + i.name + ": " + i.state.toString + "%")
        sendPushoverMessage(pushoverBuilder("Battery Status: Low battery at " + i.name + ": " + i.state.toString + "%"))
        ]
end
1 Like

Thanks everyone. Finally have a working battery rule, took some goes!

Here it is:

RULE:


val Number lowBatteryThreshold = 20

rule "Battery Status Check"
when
    Item gBatteries changed
then
    var String msg = ""
    var triggertDevices = gBatteries.members.filter[s|s.state <= 20]

    triggertDevices.forEach [ i |
        msg = msg + (transform("MAP", "batteries.map", i.name) + ': ' + i.state.toString) + '%\n'
        logInfo("Battery Check","Low battery at " + i.name + ": " + i.state.toString + "%")
    ]

    if (msg != "") {
sendBroadcastNotification(msg + " of your battery remaining")
    }
end

Transform Map

LivingRoom_FibButton_Battery=Living Room Button Controller
FrontDoor_FibButton_Battery=Front Door BUtton Controller
100=Full
90=90%
80=80%
70=70%
60=60%
50=50%
40=40%
30=30%
25=25%
20=20%
15=15%
10=10%
5=5%

:slight_smile:

4 Likes

thanks for your sharing but whi in the rules using "val Number lowBatteryThreshold = 20 " ? there is no lowBatteryThreshold used in the rule ? or i don’t understand ? thanks for your help

@Boogieman thanks for this kind of script. Tried to use this for my Homematic devices today.
As “then” parameter I write into the logfile and sendnotification. But I’m getting only “%s muss erneuert werden”. I believe %s should be the device, which is in the group (gBatterie). Do you have an idea how I can get the necessary information, which device has the low battery warning? gBatterie show me the members of this group.

In OH3 sendPushoverMessage does not work anymore as I see. After proper configurating Pushover binding here is my solution if somebody has the same issue:

//  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 00 6 ? * * *"
    Channel 'mihome:sensor_cube:286C0785BE33:158d00027de327:action' triggered FLIP90

then
    val actions = getActions("pushover", "pushover:pushover-account:0fe2ba8e66")
    val String ruleIdentifier = "Publish Battery Status "
    val Integer batteryThreshold = 35 // %. This should be enough to change the battery within a few days
    val StringBuilder aMessage = new StringBuilder

    var Integer emptyBatteries = 0

    emptyBatteries = gBatteries.members.filter[ i | ((i.state instanceof DecimalType) && (i.state < batteryThreshold)) || ((i.state instanceof OnOffType) && (i.state == ON)) ].size

    logInfo(ruleIdentifier, "Daily battery check found {} empty batteries to report!", emptyBatteries)

    if (emptyBatteries != 0) {

        aMessage.append("-> Battery report <-\n")
        gBatteries.members.filter[ i | ((i.state instanceof DecimalType) && (i.state < batteryThreshold)) || ((i.state instanceof OnOffType) && (i.state == ON)) ].forEach[ aBattery | 
            aMessage.append(aBattery.label+"\n")
        ]
        aMessage.append("-> End <-")
        logInfo("loggerName", aMessage.toString)
        actions.sendHtmlMessage(ruleIdentifier + "Daily battery check found " + emptyBatteries + " empty batteries to report!" + aMessage.toString , "openHAB")
        logInfo(ruleIdentifier, "Information about {} empty batteries has been published!", emptyBatteries)
        }

end

hi,

"aBattery" 

is coming from ?
i try your rule and i have a

 "sendHtmlMessage" : "The method sendHtmlMessage(String, String) is undefined for the type "

thanks for your sharing

Hello, No it’s not coming from that.
Pls check this line and your pushover configuartion:

val actions = getActions("pushover", "pushover:pushover-account:0fe2ba8e66") // "pushover:pushover-account:YourPushoverID"

This is needs to be replaced by your pushover ID: 0fe2ba8e66
Then it will work.

i do , but i’m on “2.5” i try to setup to my test “3.0” thanks for that !:wink:

I do a battery check with JavaScript: It is nothing fancy. I also set the percentage to check in the rule. I add the batteries I want to check into the gBatterycheck group.

triggers:
  - id: "1"
    configuration:
      time: 06:30
    type: timer.TimeOfDayTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >
        var logger =
        Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' +
        ctx.ruleUID);

        var ArrayList = Java.type('java.util.ArrayList');

        battcheckList = new ArrayList();


        /*

        This will check the percentage of battery left and if it is low then email

        Add the items to check into gBatterycheck group

        */


        var whatitis = "";

        var percenttocheck = 15;


        ir.getItem("gBatterycheck").members
                           .stream()
                           .filter(function(batt) {return batt.state.intValue() <= percenttocheck; } )
                           .forEach(function(batt) { whatitis = whatitis + batt.label +": "+ batt.state +"%" + "\r\n"; } );
        if(whatitis != ""){
          battcheckList.add(whatitis);
            logger.info('\r\nBattery low: \r\n' + whatitis );
        }


        //If something in the array then send an email

        if(battcheckList.length !== 0){
          message = "<H4>Sensor battery is low " +battcheckList +"</H4>" + "Percentage check was set at " +percenttocheck;
          actions.get("mail", "mail:smtp:1032da1f").sendHtmlMail("user@gmail.com", "Openhab sensor battery low", message );
          logger.info('\r\nArray list: \r\n' + battcheckList );
        }
    type: script.ScriptAction

1 Like

thanks a lot for this, i never use javascript on Openhab, so is time to try ! thanks !:wink:

That’s OK I only wrote it today. I am not a JavaScript expert and there is probably a better way to do it but it works.
By the way I am on OH3 in case that matters.
I have converted all my scripts from DSL to JavaScript just to see if I can run without DSL. So far so good. :slightly_smiling_face:

You use files ? or on “UI” directly ?

setup jython javascript fail every time i try…

I only use the UI. That was another thing I wanted to see if I could do it all from UI. Also so far so good.

If you copy and paste the code into your rule it should just work. Let me know.

I tell you sure :slight_smile:

To test just change the percenttocheck to greater than 100 and you should see all the batteries in the group. Good luck.

:+1:

I use Jyhton rule engine and DSL rules mixed. No problem with any of them. Installing jython is not that easy. There are some things what you need to watch for.