HowTo: Get notified on empty batteries

Definetly. I just wanted to contribute my experiences as you asked for suggestions:

And for me it had to learn that battery level reporting is sometimes tricky.

1 Like

Nice Rule. I used something similar but I only trigger the Rule when the batteries change instead of every day. Though I have to say that the Rule I though I had in my setup has gone missing in action. I should probably do something about that. :wink: Git to the rescue!

The big difference is I defined the Group as

Group:Number:MIN gBatteries

and the Rule is triggered by Item gBatteries changed so the Rule only triggers when there is a new low battery value that is lower than the last lowest. It doesn’t really matter much, but I like my Rules to only have to run when necessary. But by doing then then I can quickly short circuit the Rule.

rule "Low battery alert"
when
    Item gBatteries changed
then
    if(gBatteries.state > 20) return;

    val lowBatteriesList = gBatteries.members.filter[ b | b.state < 20 ].map[ name ].reduce[ list, bat | list = list + ", " + transform("MAP", "batteries.map", bat) ]
    aAlert.sendCommand("The following batteries need to be replaced: " + lowBatteryList.subString(0, lowBatteryList.size-2) + ".")
end

I let it keep alerting me until I change the batteries. The squeaky wheel gets the grease. :wink:

6 Likes

@rlkoshak Very nice, especially the map/reduce approach. I have to think about that for my rule as well. The main difference i see is that you only use items with a battery level value whereas in my rule switches and levels are used.

If the wheel is too squeaky i will break it :triumph::angry:

@rlkoshak and @Dibbler42
both rules are really nice. I am using a smiliar method like @rlkoshak, but it works also.

my only things using batteries are homematic sensors. CCU returns a low bat warning <1.1V for AAA batteries and set a switch to ON. So:

Group:Switch:OR(ON, OFF)   gBatterie     <battery>
rule "Batteriewarnung"
when    Member of gBatterie changed to ON
then    val batterie = gBatterie.members.filter[ b | b.state == ON ].map[ label ].reduce[ s, label | s + ", " + label ]
        sendTelegram("marco" , "%s muss erneuert werden", batterie.toString)
end
3 Likes

Hi @rlkoshak
And what is the content of the batteries.map file, please?

See Design Pattern: Human Readable Names in Messages.

It is a mapping between Item names and something a little more human friendly. I wanted to use names for the message that differed from the label but I also wanted plain English names instead of Item names in the message.

2 Likes

Coolio. Thanks

I se the label in my rule and this is a bit anoying. Amap file is may be the solution. i hvae to think about it

I also opted for a daily reminder using Cron, instead of triggering the notification once when the battery goes low. This way I can’t miss the notification so easily.

I am thinking about a double opt in approach. First sens a daily reminder using cron and in addition create da dynamich group with empty batteries that is displayed in the ui

I do two things here.
monitor if the device is active by saving last battery update time and check if thsi is older then x hours. And with a cron job check every day if battery level is lower then x.

I need both, because sometimes the battery level stays at 100% but the device do not work anymore because battery is empty. This device will not report low battery or l0%.

Oh, checking on the last update time is actually a nice touch!

i run almost this exact same rule, but i have it also run at night and send me an email with a list of low batteries

Hi Rich

Im trying this rule but it doesnt like it with the following error:

06:34:08.094 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'batteries.rules', using it anyway:
The value of the local variable lowBatteriesList is not used
There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context.
There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context.
Assignment to final parameter

All of those are warnings and do not cause the Rule to not work.

But the warnings do point at other potential problems. Please post the Rule as YOU have implemented it. It could be as simple as a wrong capitalization or the like.

Hi Rich

Sure

rule "Low battery alert"
when
    Item gBatteries changed
then
    if(gBatteries.state > 20) return;

    val lowBatteriesList = gBatteries.members.filter[ b | b.state < 20 ].map[ name ].reduce[ list, bat | list = list + ", " + transform("MAP", "batteries.map", bat) ]
    sendBroadcastNotification("The following batteries need to be replaced: " + lowBatteryList.subString(0, lowBatteryList.size-2) + ".")
end


val lowBatteriesList

... lowBatteryList.

The variable is plural but when the variable is attempted to be used it is singular “Battery”.

Change to

val lowBatteryList = gBatteries...

That should clear up all the warnings. If not., add types to the filter.

.filter[ NumberItem b | b.state < 20 ].map[

Thanks

i made those changes and this is the message now:

06:53:11.719 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'batteries.rules', using it anyway:
There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context.
Assignment to final parameter
06:53:11.722 [INFO ] [del.core.internal.ModelRepositoryImpl] - Loading model 'batteries.rules'


Rule:

rule "Low battery alert"
when
    Item gBatteries changed
then
    if(gBatteries.state > 20) return;

    val lowBatteryList = gBatteries.members.filter[ NumberItem b | b.state < 20 ].map[ name ].reduce[ list, bat | list = list + ", " + transform("MAP", "batteries.map", bat) ]
    sendBroadcastNotification("The following batteries need to be replaced: " + lowBatteryList.subString(0, lowBatteryList.size-2) + ".")
end


Hmmm. the last one doesn’t make much sense.

The only other lambda missing a type that makes any sense is the reduce, so I guess add some Types there:

reduce[ String list, String bat | list = ...

Its improving :slight_smile:

lol!

06:58:39.112 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'batteries.rules', using it anyway:
Assignment to final parameter
06:58:39.133 [INFO ] [del.core.internal.ModelRepositoryImpl] - Refreshing model 'batteries.rules'