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'
Good suggestion. Attached my entire file. There is not a lot there at the moment
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
var Number counter = 1
var Timer timer = null
// Creates an item that stores the last update time of this item
rule "Records last weather update time"
when
Item Weather_Temperature received update
then
postUpdate(Weather_LastUpdate, new DateTimeType())
end
rule "Initialize Location"
when
System started
then
DemoLocation.postUpdate(new PointType ("51.44666,-0.85117"))
end
rule "Set daily max and min temperature"
when
Item Weather_Temperature changed or
Time cron "0 0 0 * * ?" or
System started
then
val max = Weather_Temperature.maximumSince(now.withTimeAtStartOfDay)
val min = Weather_Temperature.minimumSince(now.withTimeAtStartOfDay)
if (max !== null && min !== null) {
postUpdate(Weather_Temp_Max, max.state)
postUpdate(Weather_Temp_Min, min.state)
}
end
/** shows how to use sensor values from the past */
rule "Persistence Demo"
when
Time cron "0 * * * * ?"
then
if(Weather_Temperature.changedSince(now.minusMinutes(1))) {
logInfo("PersistenceDemo", "2 minutes ago, the temperature was " + Weather_Temperature.historicState(now.minusMinutes(2)) + " degrees.")
}
end
// Creates an item that stores the last update time of this item
rule "Records last weather update time"
when
Item Weather_Temperature received update
then
postUpdate(Weather_LastUpdate, new DateTimeType())
end
// This rule will be used to test Scale transformation service
rule "Compute humidex"
when
Item Weather_Temperature changed or
Item Weather_Humidity changed
then
var Number T = Weather_Temperature.state as DecimalType
var Number H = Weather_Humidity.state as DecimalType
var Number x = 7.5 * T/(237.7 + T)
var Number e = 6.112 * Math::pow(10, x.doubleValue) * H/100
var Number humidex = T + (new Double(5) / new Double(9)) * (e - 10)
postUpdate(Weather_Humidex, humidex)
end
// 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
// rule "TV State"
// when
// Item LGTVStatus changed
// then
// if (LGTVStatus.state == 0) LGTVStatus.postUpdate(OFF)
// if (LGTVStatus.state > 0) LGTVStatus.postUpdate(ON)
// end
var Number Epoch_Time = 0
var Number LGTVStatus_Runtime = 0
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
var Number Epoch_Time = 0
var Number LGTVStatus_Runtime = 0
Try moving the two global var’s to the top of the rules file or place them inside the rule.
This removes the error as long as you don’t need those two var’s in the rules above.
rule "Calculate TV Runtime"
when
Item LGTVStatus changed
then
var Number Epoch_Time = 0
var Number LGTVStatus_Runtime = 0
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
If you need the var’s this also removes the error:
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
var Number counter = 1
var Timer timer = null
var Number Epoch_Time = 0
var Number LGTVStatus_Runtime = 0
// Creates an item that stores the last update time of this item
rule "Records last weather update time"
when
Item Weather_Temperature received update
then
postUpdate(Weather_LastUpdate, new DateTimeType())
end
rule "Initialize Location"
when
System started
then
DemoLocation.postUpdate(new PointType ("51.24626,-0.75117"))
end
rule "Set daily max and min temperature"
when
Item Weather_Temperature changed or
Time cron "0 0 0 * * ?" or
System started
then
val max = Weather_Temperature.maximumSince(now.withTimeAtStartOfDay)
val min = Weather_Temperature.minimumSince(now.withTimeAtStartOfDay)
if (max !== null && min !== null) {
postUpdate(Weather_Temp_Max, max.state)
postUpdate(Weather_Temp_Min, min.state)
}
end
/** shows how to use sensor values from the past */
rule "Persistence Demo"
when
Time cron "0 * * * * ?"
then
if(Weather_Temperature.changedSince(now.minusMinutes(1))) {
logInfo("PersistenceDemo", "2 minutes ago, the temperature was " + Weather_Temperature.historicState(now.minusMinutes(2)) + " degrees.")
}
end
// Creates an item that stores the last update time of this item
rule "Records last weather update time"
when
Item Weather_Temperature received update
then
postUpdate(Weather_LastUpdate, new DateTimeType())
end
// This rule will be used to test Scale transformation service
rule "Compute humidex"
when
Item Weather_Temperature changed or
Item Weather_Humidity changed
then
var Number T = Weather_Temperature.state as DecimalType
var Number H = Weather_Humidity.state as DecimalType
var Number x = 7.5 * T/(237.7 + T)
var Number e = 6.112 * Math::pow(10, x.doubleValue) * H/100
var Number humidex = T + (new Double(5) / new Double(9)) * (e - 10)
postUpdate(Weather_Humidex, humidex)
end
// 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
// 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
Thanks @H102 by moving both var`s to the top of the rule this resolve issue with previous warning (missing EOF).
Looking at openhab log file it is showing me some additional validation issues but (INFO) not sure if this is anything to worry about.
2018-12-25 16:10:38.145 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'home.rules', using it anyway:
The use of wildcard imports is deprecated.
The use of wildcard imports is deprecated.
The use of wildcard imports is deprecated.
2018-12-25 16:10:38.153 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'home.rules'
2018-12-25 16:18:16.454 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'home.rules', using it anyway:
The use of wildcard imports is deprecated.
The use of wildcard imports is deprecated.
The use of wildcard imports is deprecated.
2018-12-25 16:18:16.584 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'home.rules'
But I still don’t get any calculations out of this rule.
Is my syntax correct ?
Sitemap
Text item=LGTVStatus_Runtime_Minutes label="Runtime Time [%d]"
Items
Number LGTVStatus_Runtime_Minutes "TV Runtime Minutes"
Should I set anything in rrd4j ? So far I only been adjusting rule file, sitemap & items.
Do you need the imports? Most rule’s with OH run without calling for imports. Maybe try the rule without and see if it still runs or try removing the *.
I didn’t really study the rule to much, wrapping paper is everywhere.
If you are trying to compare a current value to an older one then yes you will need to add the items to the persist file.
Example:
Strategies {
// for rrd chart cron strategy every minute
everyMinute : "0 * * * * ?"
// get data reduced for older values to keep database small
everyHour : "0 0 * * * ?"
everyDay : "0 0 0 * * ?"
default = everyChange
}
Items {
LGTVStatus_Runtime_Minutes : strategy = everyUpdate, everyMinute, restoreOnStartup
* : strategy = everyUpdate, everyMinute, restoreOnStartup
}
You can list all item separate or use the * to add all of them like the second line in items above. See the doc’s for more details and examples.
Thanks. At the moment my goal is to display total usage time in one day as bare minimum. Later will try to expand it to week/month & year primarily for internal analysis only
I just discovered some errors in log file with regards to rule.
2018-12-25 16:47:44.282 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Calculate TV Runtime': The name 'LGTVStatus_Stop_Time' cannot be resolved to an item or type; line 91, column 31, length 20
2018-12-25 16:48:31.928 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'home.sitemap', using it anyway:
Sitemap should contain either only frames or none at all
2018-12-25 16:48:31.964 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'home.sitemap'
2018-12-25 16:49:47.439 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Calculate TV Runtime': The name 'LGTVStatus_Start_Time' cannot be resolved to an item or type; line 92, column 30, length 21
2018-12-25 16:51:47.165 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'home.rules', using it anyway:
The use of wildcard imports is deprecated.
The use of wildcard imports is deprecated.
The use of wildcard imports is deprecated.
2018-12-25 16:51:47.268 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'home.rules'
It doesn’t like ‘LGTVStatus_Stop_Time’ & ‘LGTVStatus_Start_Time’
You can forget the persistence for now. Main goal is to get your this rule running. When you do so, you can set up a second rule to reset the counter item at midnight to see daily calculations.
I tried replacing LGTVStatus with another running item at home (light switch) but there is still nothing being populated in this rule. Should I be restarting openhab after updating rule file ?
I seen this topic earlier , probably with slightly easier rule and Vincent solution to increment counter. Will try test it quickly to see if it works.
And yes, you can experiment with something more simple.
Do you know what a virtual item is? You don’t have to replace your tv status item with some other actual item that is linked to a physical switch. Just one “test” item.
I gather the idea of virtual item. I will try to set up test switch which I could toggle freely and will see if it works. There must be some fundamental mistake in my syntax somewhere.