Skip to content

Instantly share code, notes, and snippets.

@nickbalch
Last active October 27, 2019 12:55
Show Gist options
  • Save nickbalch/6eddda7ed01e5fc0999d27d6c4e43ed2 to your computer and use it in GitHub Desktop.
Save nickbalch/6eddda7ed01e5fc0999d27d6c4e43ed2 to your computer and use it in GitHub Desktop.
Openhab items and rules for a currentcost installation but should work for any energy monitoring solution where device state shall be derived from the energy consumption. To avoid flapping or false detection, a timer is used to ensure temporary fluctations are ignored
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.model.script.actions.Timer
var Timer timer_tumble
var Timer timer_dishwasher_on
var Timer timer_dishwasher_off
var Timer timer_washer
var Timer timer_m3d
rule "Update for Washer"
when
Item watts_washer received update
then
println ("washer rule")
if (watts_washer.state > 2 && (Washer.state == OFF || Washer.state == Uninitialized )) {
println ("washer - kicking off timer for on state")
timer_washer = createTimer(now.plusSeconds(30)) [|
sendCommand(Washer,ON)
]
} else {
if(timer_washer!=null) {
timer_washer.cancel
timer_washer = null
}
else if (watts_washer.state < 2 && (Washer.state == ON)) {
println ("washer - kicking off timer for off state")
timer_washer = createTimer(now.plusSeconds(55)) [|
sendCommand(Washer,OFF)
]
} else {
if(timer_washer!=null) {
timer_washer.cancel
timer_washer = null
}
}
end
rule "Update for Tumble Dryer"
when
Item watts_tumble received update
then
println("Tumble rule")
if (watts_tumble.state > 2 && (Tumble.state == OFF || Tumble.state == Uninitialized )) {
println ("tumble - kicking off timer for on state")
timer_tumble = createTimer(now.plusSeconds(60)) [|
sendCommand(Tumble,ON)
]
} else {
if(timer_tumble!=null) {
timer_tumble.cancel
timer_tumble = null
}
else if (watts_tumble.state < 2 && (Tumble.state == ON)) {
println ("tumble - kicking off timer for off state")
timer_tumble = createTimer(now.plusSeconds(30)) [|
sendCommand(Tumble,OFF)
]
} else {
if(timer_tumble!=null) {
timer_tumble.cancel
timer_tumble = null
}
}
end
rule "Update for 3dPrinter"
when
Item watts_3dprinter received update
then
println("3dprinter rule")
if (watts_3dprinter.state > 2 && (M3DPrinter.state == OFF || M3DPrinter.state == Uninitialized )) {
println ("kicking off timer for on state")
timer_m3d = createTimer(now.plusSeconds(45)) [|
sendCommand(M3DPrinter,ON)
]
} else {
if(timer_m3d!=null) {
timer_m3d.cancel
timer_m3d = null
}
else if (watts_3dprinter.state < 2 && (M3DPrinter.state == ON)) {
println ("kicking off timer for off state")
timer_m3d = createTimer(now.plusSeconds(45)) [|
sendCommand(M3DPrinter,OFF)
]
} else {
if(timer_m3d!=null) {
timer_m3d.cancel
timer_m3d = null
}
}
end
rule "Update for Dishwasher"
when
Item watts_dishwasher received update
then
println ("dishwasher rule")
println ("on timer" + timer_dishwasher_on)
println ("off timer" + timer_dishwasher_off)
//check to see if dishwasher is off, only initiate the flap check if there is no pending off check running
if (watts_dishwasher.state > 2 && (timer_dishwasher_on==null) && (timer_dishwasher_off==null)&& (Dishwasher.state == OFF || Dishwasher.state == Uninitialized )) {
println ("dishwasher - kicking off timer for on state")
timer_dishwasher_on = createTimer(now.plusSeconds(60)) [|
sendCommand(Dishwasher,ON)
]
} else if(timer_dishwasher_on!=null && watts_dishwasher.state < 2) {
println ("Cancelling ON timer ... out of threshold")
timer_dishwasher_on.cancel
timer_dishwasher_on = null
}
if (watts_dishwasher.state < 2 && (timer_dishwasher_off==null) && (Dishwasher.state == ON)) {
println ("dishwasher - kicking off timer for off state")
//timer_dishwasher_off = createTimer(now.plusSeconds(120)) [|
timer_dishwasher_off = createTimer(now.plusSeconds(1140)) [|
if (watts_dishwasher.state <2) {
println ("dishwasher off")
sendCommand(Dishwasher,OFF)
timer_dishwasher_off.cancel
timer_dishwasher_off = null
} else {
println ("Dishwasher was on again!")
}
println("cancelling off timer")
timer_dishwasher_off.cancel
timer_dishwasher_off = null
]
}
}
end
rule "Update max and min watts for house"
when
Item watts_house changed or
Time cron "0 0 0 * * ?" or
System started
then
postUpdate(Power_Max, watts_house.maximumSince(now.toDateMidnight).state)
postUpdate(Power_Min, watts_house.minimumSince(now.toDateMidnight).state)
postUpdate(Watts_LastUpdate, new DateTimeType())
end
Group Moteino (State)
Group Moteino_batt (Moteino,Battery)
Group Moteino_temp (Temperature)
Group Moteino_signal (Moteino)
Group Moteino_monitor (Moteino,Status)
Group Moteino_version
Switch moteino_0_monitor "Node 0 Monitor" (Moteino_monitor)
Switch moteino_1_monitor "Node 1 Monitor" (Moteino_monitor)
Switch moteino_2_monitor "Node 2 Monitor" (Moteino_monitor)
Switch moteino_3_monitor "Node 3 Monitor" (Moteino_monitor)
Switch moteino_4_monitor "Node 4 Monitor" (Moteino_monitor)
Switch moteino_5_monitor "Node 5 Monitor" (Moteino_monitor)
Number moteino_0_temp "Node 0 Temp [%.1f C]" (Moteino,Temperature,Moteino_temp) {mqtt="<[mosquitto:home/status/moteino_0_temp:state:default]"}
Number moteino_0_batt "Node 0 Batt [%.1f V]" (Moteino) {mqtt="<[mosquitto:home/status/moteino_0_battery:state:default]"}
Number moteino_0_signal "Node 0 Signal [%.1f Db]" (Moteino) {mqtt="<[mosquitto:home/status/moteino_0_signal:state:default]"}
Number moteino_0_version "Node 0 Version [%s]" (Moteino,Moteino_version) {mqtt="<[mosquitto:home/status/moteino_0_version:state:default]"}
Number moteino_1_temp "Node 1 Temp [%.1f C]" (Moteino,Temperature,Moteino_temp) {mqtt="<[mosquitto:home/status/moteino_1_temp:state:default]"}
Number moteino_1_signal "Node 1 Signal [%.1f Db]" (Moteino,Moteino_signal) {mqtt="<[mosquitto:home/status/moteino_1_signal:state:default]"}
Number moteino_1_batt "Node 1 Batt [%.1f V]" (Moteino,Moteino_batt) {mqtt="<[mosquitto:home/status/moteino_1_battery:state:default]"}
Number moteino_1_version "Node 1 Version [%s]" (Moteino,Moteino_version) {mqtt="<[mosquitto:home/status/moteino_1_version:state:default]"}
Number moteino_2_temp "Node 2 Temp [%.1f C]" (Moteino,Temperature,Moteino_temp) {mqtt="<[mosquitto:home/status/moteino_2_temp:state:default]"}
Number moteino_2_signal "Node 2 Signal [%.1f Db]" (Moteino,Moteino_signal) {mqtt="<[mosquitto:home/status/moteino_2_signal:state:default]"}
Number moteino_2_batt "Node 2 Batt [%.1f V]" (Moteino,Moteino_batt) {mqtt="<[mosquitto:home/status/moteino_2_battery:state:default]"}
Number moteino_2_version "Node 2 Version [%s]" (Moteino,Moteino_version) {mqtt="<[mosquitto:home/status/moteino_2_version:state:default]"}
Number moteino_3_temp "Node 3 Temp [%.1f C]" (Moteino,Temperature,Moteino_temp) {mqtt="<[mosquitto:home/status/moteino_3_temp:state:default]"}
Number moteino_3_signal "Node 3 Signal [%.1f Db]" (Moteino,Moteino_signal) {mqtt="<[mosquitto:home/status/moteino_3_signal:state:default]"}
Number moteino_3_batt "Node 3 Batt [%.1f V]" (Moteino,Moteino_batt) {mqtt="<[mosquitto:home/status/moteino_3_battery:state:default]"}
Number moteino_3_version "Node 3 Version [%s]" (Moteino,Moteino_version) {mqtt="<[mosquitto:home/status/moteino_3_version:state:default]"}
Number moteino_4_temp "Node 4 Temp [%.1f C]" (Moteino,Temperature,Moteino_temp) {mqtt="<[mosquitto:home/status/moteino_4_temp:state:default]"}
Number moteino_4_signal "Node 4 Signal [%.1f Db]" (Moteino,Moteino_signal) {mqtt="<[mosquitto:home/status/moteino_4_signal:state:default]"}
Number moteino_4_batt "Node 4 Batt [%.1f V]" (Moteino,Moteino_batt) {mqtt="<[mosquitto:home/status/moteino_4_battery:state:default]"}
Number moteino_4_version "Node 4 Version [%s]" (Moteino,Moteino_version) {mqtt="<[mosquitto:home/status/moteino_4_version:state:default]"}
Number moteino_5_temp "Node 5 Temp [%.1f C]" (Moteino,Temperature,Moteino_temp) {mqtt="<[mosquitto:home/status/moteino_5_temp:state:default]"}
Number moteino_5_signal "Node 5 Signal [%.1f Db]" (Moteino,Moteino_signal) {mqtt="<[mosquitto:home/status/moteino_5_signal:state:default]"}
Number moteino_5_batt "Node 5 Batt [%.1f V]" (Moteino,Moteino_batt) {mqtt="<[mosquitto:home/status/moteino_5_battery:state:default]"}
Number moteino_5_version "Node 5 Version [%s]" (Moteino,Moteino_version) {mqtt="<[mosquitto:home/status/moteino_5_version:state:default]"}
Number Moteino_Chart_Period "Chart Period"
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.joda.time.*
var String[] buffer
var String[] tmp
rule "Mapping Moteino nodes to temperature items"
when
Item Moteino_temp received update
then
Moteino_version.members.forEach[t |
tmp=t.name.toString.split("_")
// println(t.name+" which was updated at "+t.lastUpdate)
// println("Next line should be temp for Moteino_"+tmp.get(1))
// println(Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
if (t.lastUpdate.after(new java.util.Date(now.minusMinutes(2).millis))) {
switch (tmp.get(1)) {
case tmp.get(1) == "0" : postUpdate(Temperature_GF_Understairs,Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
case tmp.get(1) == "1" : postUpdate(Temperature_xx_Unused,Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
case tmp.get(1) == "2" : postUpdate(Temperature_FF_Spare,Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
case tmp.get(1) == "3" : postUpdate(Temperature_GF_Dining,Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
case tmp.get(1) == "4" : postUpdate(Temperature_FF_Bed,Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
case tmp.get(1) == "5" : postUpdate(Temperature_FF_Roan,Moteino_temp.members.findFirst[name.contains(tmp.get(1))].state)
}
}
]
end
rule "Check Last updated for Nodes"
when
Time cron "0 0/30 * * * ?"
then
Moteino_version.members.forEach[i |
buffer=i.name.toString.split("_")
println(i.name+" "+i.state+" "+i.lastUpdate)
if (i.lastUpdate.before(new java.util.Date(now.minusMinutes(30).millis)) || i.state==Uninitialized){
println(i.name+" not updated or not initialized")
if ( Moteino_monitor.members.findFirst[ name.contains(buffer.get(1))].state ==ON ) {
sendCommand(Alert_1,buffer.get(0)+" "+buffer.get(1)+" not updated for 30 minutes")
}
}
]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment