I still using openhab 2.3.0 at the moment, will probably wait till next weekend with upgrade but reading forum there is a lot of positive opinions so far so can`t wait for that.
In the meantine I would like to calculate usage of a device at home which is monitored using Network Binding.
My item looks like this:
Text item=DeviceStatus label="Device A [%s]" valuecolor=[ON="green" ,OFF="red"]
Ideally I would like to calculate and display total usage in hour/day/week/month and one year. Will probably end up trimming this down but just want to experiment for now. What`s is the best way to achieve this. Does anyone has any proven rules available for sharing ? I will be grateful for any suggestions.
And by usage do you mean that you want to count how many times the switch has flipped to ON? Or maybe see a graph indicating how long it has been ON for a period of time?
I used the search function with “calculate time” and found this generator calculation thread. It’s old but it should get you started.
Sorry if I wasn`t clear. My intention is to display total usage of the device within certain time frame - basically need to know for how long this device was switched on during hour/day/week/month & year. Lets say we are talking about a simple lamp in bedroom. I probably will be happy just displaying as text in few lines - would that be to difficult ? I could consider using chart but maybe for this purpose getting this data as a text will be easier to read.
Also just started thinking that for maintenance knowledge I could start gathering information how many times the A switch has flipped to ON position so basically count number of position changes from OFF to ON. I will look into your old post now.
I think it depends on where and how you’d like to display the value(s). IMHO, few string items in your sitemap won’t work.
For example I’m running MySQL persistence and have a graphing script written in php to calculate ON durations and average temperatures. They are then drawn to a graph and displayed as images in my sitemap.
I’m not familiar with the network binding, but I calculated runtime on a washing machine like this. (The runtime was used for notification purposes.). It works, but I still have some tidying to do I think.
// Switch Washing_Machine_State "Washing Machine State" <switch> - Item Definition (z-wave.items)
// Number Washing_Machine_Start_Time "Washing Machine Stop Time [%d]" - Item Definition (z-wave.items) - Stores Epoch timestamp
// Number Washing_Machine_Stop_Time "Washing Machine Stop Time [%d]" - Item Definition (z-wave.items) - Stores Epoch timestamp
// Number Washing_Machine_Runtime_Minutes "Washing Machine Runtime Minutes [%d]" Item Definition (z-wave.items) - Stores runtime minutes
var Number Epoch_Time = 0
var Number Washing_Machine_Runtime = 0
rule "Washing Machine State"
when
Item zwave_washing_machine_meter_watts changed
then
if (zwave_washing_machine_meter_watts.state == 0) Washing_Machine_State.postUpdate(OFF)
if (zwave_washing_machine_meter_watts.state > 0) Washing_Machine_State.postUpdate(ON)
end
rule "Calculate Washing Machine Runtime"
when
Item Washing_Machine_State changed
then
Epoch_Time = now.millis
if (Washing_Machine_State.state == OFF) Washing_Machine_Stop_Time.postUpdate(Epoch_Time)
if (Washing_Machine_State.state == ON) Washing_Machine_Start_Time.postUpdate(Epoch_Time)
if ((Washing_Machine_Start_Time.state as DecimalType) > 0 && (Washing_Machine_Stop_Time.state as DecimalType) > 0) {
Washing_Machine_Runtime = ((Washing_Machine_Stop_Time.state as DecimalType) - (Washing_Machine_Start_Time.state as DecimalType)) / 60000
Washing_Machine_Runtime_Minutes.postUpdate(Washing_Machine_Runtime)
logInfo("Washing Machine", "Washing Machine Runtime - " + Washing_Machine_Runtime)
}
end
rule "Washing Machine Notification"
when
Item Washing_Machine_Runtime_Minutes changed
then
if ((Washing_Machine_State.state == OFF) && Washing_Machine_Runtime_Minutes.state >= 10) {
var Washing_Machine_Notification = String::format("Washing machine finished load in %.0f minutes.", Washing_Machine_Runtime.floatValue)
sendMail("3145504161@vzwpix.com", Washing_Machine_Notification, "")
logInfo("Washing Machine", Washing_Machine_Notification)
Washing_Machine_Start_Time.postUpdate(0)
//postUpdate(Washing_Machine_Start_Time, 0)
}
end
Thank you. I shall amend your sample for what I need and will test it.
I only have one feedback coming back to openhab via Network Binding for this device - status will change between ON and OFF. So really I want to capture total time when this device is switched ON over a period of time.
Text item=DeviceStatus label="Device A [%s]" valuecolor=[ON="green" ,OFF="red"]
At the moment is set to 60 seconds but I can reduce it down to whatever will be required. I only get one feedback from device informing me if is ON or OFF. Works well so far must say.
If I amend the sample code above do you think I can achieve the expected result ?
This is my first contact with rules so black magic at the moment
Edit: Just to add, mainly I will be planning to monitor household devices such as computers, TV`s. So generally if device is ON , it will be used for some time and there should be plenty of time to capture state change.
Yes you can. Just start coding and you’ll get familiar with rules. Create virtual items as needed and persist the final calculation in a number item. I’m not good when it comes to Rules DSL but I think that after above steps, you can use “persistence extensions” (don’t know what’s the proper name) to get historical states from that item and do further min/max/avg calculations.
Good luck and let us know how it goes. We’ll help you to get further.
First thing I noticed that the first rule “TV State” then block has only two if statements. It just checks them and then does nothing.
To see what is happening you have to see logs. Do you have frontail running? Always when I’m doing something with rules or oh itself, I have frontail open in a browser tab.
And if logs aren’t telling you enough you add more logging statements to your rule starting from the top.
To speed up your debugging and developing I suggest that you create virtual items and use them in your rule and sitemap:
Switch TVStatus_test
Number TVStatus_runtime_test
This way you don’t have to wait for the real item to switch on and off. After the rule is running properly, you replace those with real items.
I changed typos but this didnt make any difference. Checking event log, but cant find any evidence this rule works. Just to make it clear I only have one feedback from device informing me if the unit is in ON or OFF state.
Not sure what is the function of this line
var Number Epoch_Time = 0
This is my current rule:
// Switch LGTVStatus "TV State" <switch> - Item Definition (items)
// Number LGTVStatus_Start_Time "TV Start Time [%d]" - Item Definition (items) - Stores Epoch timestamp
// Number LGTVStatus_Stop_Time "TV Stop Time [%d]" - Item Definition (items) - Stores Epoch timestamp
// Number LGTVStatus_Runtime_Minutes "TV Runtime Minutes [%d]" Item Definition (items) - Stores runtime minutes
var Number Epoch_Time = 0
var Number LGTVStatus_Runtime = 0
rule "TV State"
when
Item LGTVStatus changed
then
if (LGTVStatus.state == 0) LGTVStatus.postUpdate(OFF)
if (LGTVStatus.state > 0) LGTVStatus.postUpdate(ON)
end
rule "Calculate TV Runtime"
when
Item LGTVStatus changed
then Epoch_Time = now.millis
if (LGTVStatus.state == OFF) LGTVStatus_Stop_Time.postUpdate(Epoch_Time)
if (LGTVStatus.state == ON) LGTVStatus_Start_Time.postUpdate(Epoch_Time)
if ((LGTVStatus_Start_Time.state as DecimalType) > 0 && (LGTVStatus_Stop_Time.state as DecimalType) > 0) {
LGTVStatus_Runtime = ((LGTVStatus_Stop_Time.state as DecimalType) - (LGTVStatus_Start_Time.state as DecimalType)) / 60000
LGTVStatus_Runtime_Minutes.postUpdate(LGTVStatus_Runtime)
logInfo("LGTV", "LGTV Runtime - " + LGTVStatus_Runtime)
}
end
Epoch_time holds current time in milliseconds. It is used for runtime calculation.
In Burzins code snippet the first rule is used to convert a power meters readings to ON/OFF state. As you already have your item as switch, you don’t need the first rule.
Add more logging into your rule to see what it does and what not.
I removed the first rule as advised (commented out for now). Still no getting any values out of this rule.
As it stands my rule looks like follow at the moment.
// Switch LGTVStatus "TV State" <switch> - Item Definition (items)
// Number LGTVStatus_Start_Time "TV Start Time [%d]" - Item Definition (items) - Stores Epoch timestamp
// Number LGTVStatus_Stop_Time "TV Stop Time [%d]" - Item Definition (items) - Stores Epoch timestamp
// Number LGTVStatus_Runtime_Minutes "TV Runtime Minutes [%d]" Item Definition (items) - Stores runtime minutes
var Number Epoch_Time = 0
var Number LGTVStatus_Runtime = 0
// rule "TV State"
// when
// Item LGTVStatus changed
// then
// if (LGTVStatus.state == 0) LGTVStatus.postUpdate(OFF)
// if (LGTVStatus.state > 0) LGTVStatus.postUpdate(ON)
// end
rule "Calculate TV Runtime"
when
Item LGTVStatus changed
then Epoch_Time = now.millis
if (LGTVStatus.state == OFF) LGTVStatus_Stop_Time.postUpdate(Epoch_Time)
if (LGTVStatus.state == ON) LGTVStatus_Start_Time.postUpdate(Epoch_Time)
if ((LGTVStatus_Start_Time.state as DecimalType) > 0 && (LGTVStatus_Stop_Time.state as DecimalType) > 0) {
LGTVStatus_Runtime = ((LGTVStatus_Stop_Time.state as DecimalType) - (LGTVStatus_Start_Time.state as DecimalType)) / 60000
LGTVStatus_Runtime_Minutes.postUpdate(LGTVStatus_Runtime)
logInfo("LGTV", "LGTV Runtime - " + LGTVStatus_Runtime)
}
end
Sitemap
```csv
Text item=LGTVStatus_Runtime_Minutes label="Runtime Time [%d]"
Items
```csv
Number LGTVStatus_Runtime_Minutes "TV Runtime Minutes"
Looking at the openhab log can see the following error.
2018-12-24 22:47:20.782 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'home.rules' has errors, therefore ignoring it: [77,1]: missing EOF at 'var'