In addition to all the SmartHome functionality that makes life easier, the SmartHone unfortunately also requires frequent maintenance. Anyone who takes care of the SmartHome topic will quickly notice that the number of battery-powered devices is increasing by leaps and bounds. From the window contact to the thermostat to the plant sensors, everything has a battery that eventually runs out and has to be replaced.
In order to keep the effort to a minimum and not have to check all devices by hand regularly, the SmartHome has to support us in this task. What is the task?
Dear SmartHome, please inform me in time about a low battery level of one or more devices, so that I can still buy batteries and then change them.
The following collection of items, groups and rules does just that.
The items:
In my environment there are two kinds of battery status items. One is a switch that goes ON when the battery is low and the second is a percentage indicator of how much charge is left. Furthermore, Additonally i have structured my things/items so that all items of a thing are grouped together. Below you will find one thing of each type.
// Thing: Window Contact / Right Windows
Group GF_KI_WindowContactR "Kitchen: Window (right)" <fts_window_2w_open_r> (gGF_Kitchen)
Contact GF_KI_WindowContactR_State "Kitchen: Window (right) [MAP(cnt2ger.map):%s]" <fts_window_2w_open_r> (GF_KI_WindowContactR, gWindowContacts)
Switch GF_KI_WindowContactR_LowBattery "Kitchen: Window (right)[MAP(swt2battery.map):%s]" <measure_battery_50> (GF_KI_WindowContactR, gBatteryStatus)
// Thing: ZWave Multisensor Node 3
Group GF_GT_Multisensor "Guest WC: Multi sensor" <message_presence> (gGF_GuestToilet)
Switch GF_GT_Multisensor_Motion "Guest WC: Motion [MAP(swt2motion.map):%s]" <message_presence_active> (GF_GT_Multisensor, gPIRMotionTrigger)
Number GF_GT_Multisensor_BatteryLevel "Guest WC: Multi sensor [%d %%]" <measure_battery_50> (GF_GT_Multisensor, gBatteryStatus)
The group:
Only one group is needed to identify the battery status channels.
Group gBatteryStatus "Battery state" <measure_battery_75>
And last but not least - the rule:
Every day at 6 o’clock in the evening the rule is triggered. First the rule chekcs if there are any empty batteries. If not thats it. If there are any empty batteries create a loop and add the label of the battery channel to the message. So make sure that the battery state channel label has the right value. At the end i use Pushover to send the message
// 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 ? * * *"
then
val String ruleIdentifier = "Publish Battery Status"
val Integer batteryThreshold = 10 // %. This should be enough to change the battery within a few days
val StringBuilder aMessage = new StringBuilder
var Integer emptyBatteries = 0
emptyBatteries = gBatteryStatus.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")
gBatteryStatus.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 <-")
sendPushoverMessage(pushoverBuilder(aMessage.toString).withDevice("myMobile"))
logInfo(ruleIdentifier, "Information about {} empty batteries has been published!", emptyBatteries)
}
end
That’s it. Any suggestion to improve the rule are welcome. To have a life view on empty batteries with a second rule a group may be dynamically filled with empty batteries.