Rule simplification and code reuse

Posting a simple technique in the hope it’s helpful to others
(I feel guilty benefiting from the content here but have not contributed)

I have many (Xiaomi) motion sensors, door sensors, window sensors and buttons around the house
8 of these are important to the automation within my house - I don’t want them to stop working
These sensors all have a little 2032 battery which lasts a long time (a year or more) but I would like to be alerted when the battery is low
These items all have a lowBattery channel that you can code a rule to process/warn/notify
This would result in a lot of duplicated code (which is also a maintenance hassle)

Here is a way to simplify the solution with less code
This introduces a code reuse mechanism (like a subroutine or object method)

  1. Define an abstract string item
    This will be used to receive low battery warning messages
String LowBatteryWarn  "Low battery warning handler (non interactive)"
  1. Define a rule to process low battery warning messages
rule "LowBatteryWarn handler"
when
    Item LowBatteryWarn received command
then
    var String Msg = "Low battery warning: " + LowBatteryWarn.state.toString()
    sendNotification("joe@mail.com", Msg, "lowBattery", "Alert") // to myopenhab.org & mobile
    logWarn("lowBattery", Msg)
    say(Msg) // Output to google home speaker
end
  1. For each device define a one line rule to process low battery events
    These rules merely set the LowBatteryWarn item string to a message
    The LowBatteryWarn item rule will process it as per your requirements/implementation
    Make sure each rule has it’s own unique name!

(I’ve only published a subset of my low battery warnings to keep this post shorter)

rule "Front Door - Low battery warning"
when
    Item MiMagnet_Front_BattLow changed from NULL to ON
    or
    Item MiMagnet_Front_BattLow changed from OFF to ON
then
    LowBatteryWarn.sendCommand("Front door open/closed sensor")
end

rule "Motion UpStairs - Low battery warning"
when
    Item MiMotion_UpStairs_BattLow changed from NULL to ON
    or
    Item MiMotion_UpStairs_BattLow changed from OFF to ON
then
    LowBatteryWarn.sendCommand("Upstairs motion sensor")
end

rule "Temp Bedroom - Low battery warning"
when
    Item MiTemp_Bedroom_BattLow changed from NULL to ON
    or
    Item MiTemp_Bedroom_BattLow changed from OFF to ON
then
    LowBatteryWarn.sendCommand("Bedroom temperature sensor")
end

Hope that helps the community

1 Like

I’m a bit confused, because there is a simple solution with only one rule which which will “rule them all”

Setup a Group Item:

Group:Switch gLowBat "all low bat items"

and set all LowBat Items to be member of that group.

Now one Rule:

// imports at the begin of file
import java.util.HashMap

var HashMap<String, String> mapText = newHashMap(
    "MiMagnet_Front_BattLow"     ->    "Front door open/closed sensor",
    "MiMotion_UpStairs_BattLow"  ->    "Upstairs motion sensor",
    "MiTemp_Bedroom_BattLow"     ->    "Bedroom temperature sensor",
) as HashMap

rule "Low battery warning"
when
    Member of gLowBat changed to ON
then
    var String Msg = "Low battery warning: " + mapText.get(triggeringItem.name)
    sendNotification("joe@mail.com", Msg, "lowBattery", "Alert") // to myopenhab.org & mobile
    logWarn("lowBattery", Msg)
    say(Msg) // Output to google home speaker
end
3 Likes

There is always a more elegant solution to a specific problem, IF you know how to do it. :wink: I have no idea of Java, and I think Martins code is still useful (untested), as it allows to create a handler/method which can be used universally.
I just started scripting OH rules today and I guess it isn’t possible to use classic handlers, even with parameters?

1 Like

Well, you can do something similar with lambda functions. But to be honest, this is often not the smartest solution.
Please be aware that openHAB supports another way to script with jsr223. Will be default in openHAB3…

2 Likes

Thanks - that is helpful (despite the condescending tone)

Thank! I learned something new. One question remains, when saving the rules file, I see the following line in the log:

2020-05-05 10:43:07.238 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'xiaomi_battery.rules', using it anyway:
HashMap is a raw type. References to generic type HashMap<K, V> should be parameterized

Googled, but couldn’t find an answer for myself, my English is very bad :frowning: What is this?

Sorry. I’'m no native english speaker, I didn’t want to be rude.

3 Likes