Im currently rewriting my rule and have massive problems im ob openhabian 2.1:
Rule:
Rule "Livingroom Demand"
when
Item LivingrTemp received update or //Current Tmperature in the Room
Item LivingrTempTarget received update //Target Tmperature in the Room
then
if((LivingrHeatMan.state="ON")){} //Is manual control mode for the Room Set ( Set Valves via Valve and manually turn on or off Boiler at Switch)
else if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state="ON")){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer lower then target but demand already on
else if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state="OFF")){ // current temp - buffer lower then target turn on demand
LivingrHeatDemand.postUpdate(ON)
logWarn("Demo","This is a log entry of type Warn!")
}
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state="OFF")){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer higher then target but demand already off
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state="ON")){ // current temp - buffer higher then target turn off demand
LivingrHeatDemand.postUpdate(OFF)
logWarn("Demo","This is a log entry of type Warn!")
}
// the check if the state is already appropiate and then do nothing will reduce unnecesarry rule triggers
end
Error:
[.script.engine.ScriptExecutionThread] - Rule 'Livingroom Demand': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.core.library.items.SwitchItem.setState(org.eclipse.smarthome.core.types.State) on instance: LivingrHeatMan (Type=SwitchItem, State=OFF, Label=Manual Heating Mode Livingroom, Category=null, Groups=[GroupHeatingManual])
I looked multiple times into names etc. but i cant seem to find a error any thoughts?
Both Tipps diddnt do the trick but the error changed to:
2017-08-11 09:59:28.376 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Livingroom Demand': An error occurred during the script execution: The name '<XFeatureCallImplCustom>.state' cannot be resolved to an item or type.
current rule state:
ule "Livingroom Demand"
when
Item LivingrTemp received update or //Current Tmperature in the Room
Item LivingrTempTarget received update //Target Tmperature in the Room
then
if(LivingrHeatMan.state == "ON"){} //Is manual control mode for the Room Set ( Set Valves via Valve and manually turn on or off Boiler at Switch)
else if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == "ON")){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer lower then target but demand already on
else if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == "OFF")){ // current temp - buffer lower then target turn on demand
LivingrHeatDemand.postUpdate(ON)
logWarn("Demo","This is a log entry of type Warn!")
}
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == "OFF")){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer higher then target but demand already off
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == "ON")){ // current temp - buffer higher then target turn off demand
LivingrHeatDemand.postUpdate(OFF)
logWarn("Demo","This is a log entry of type Warn!")
}
// the check if the state is already appropiate and then do nothing will reduce unnecesarry rule triggers
end
if(LivingrHeatMan.state == ON){} //Is manual control mode for the Room Set ( Set Valves via Valve and manually turn on or off Boiler at Switch)
else if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == ON)){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer lower then target but demand already on
else if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == OFF)){ // current temp - buffer lower then target turn on demand
LivingrHeatDemand.postUpdate(ON)
logWarn("Demo","This is a log entry of type Warn!")
}
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == OFF)){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer higher then target but demand already off
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == ON)){ // current temp - buffer higher then target turn off demand
LivingrHeatDemand.postUpdate(OFF)
logWarn("Demo","This is a log entry of type Warn!")
}
// the check if the state is already appropiate and then do
I wonder if this part is correct:
((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && (LivingrHeatDemand.state == ON))
should it be like this?
(LivingrTempTarget.state as Number > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) && LivingrHeatDemand.state == ON)
if ( LivingrHeatMan.state != ON) { //simplify the nesting by testing the negative
if (LivingrHeatDemand.state == ON) {
if ((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number)) {
//current lower than target but demand already on hence a NO-OP
}
else { LivingrHeadDemand.postUpdate(OFF)
}
else { //demand state is OFF
if ((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number - LivingrTempBuffer.state as Number) {
LivingrHeatDemand.postUpdate(ON)
else { // current temp higher than target but demand already off so a NO-OP
}
} // end of LivingrHeatMan.state != ON test
Thanks a lot for that idea i will definatly consider this but would like to understand why its not working with my code first so very strange: i chaged to:
rule "Livingroom Demand"
when
Item LivingrTemp received update or //Current Tmperature in the Room
Item LivingrTempTarget received update //Target Tmperature in the Room
then
if(LivingrHeatMan.state == ON){} //Is manual control mode for the Room Set ( Set Valves via Valve and manually turn on or off Boiler at Switch)
else if((LivingrTempTarget.state as Number > LivingrTemp.state as Number ) && LivingrHeatDemand.state == ON){
logWarn("Demo","This is a log entry of type Warn!")
} // current temp - buffer lower then target but demand already on
else if((LivingrTempTarget.state as Number > LivingrTemp.state as Number ) && LivingrHeatDemand.state == OFF){ // current temp - buffer lower then target turn on demand
LivingrHeatDemand.postUpdate(ON)
logWarn("Demo","This is a log entry of type Warn!")
}
//else if((LivingrTempTarget.state as Number < LivingrTemp.state as Number ) && LivingrHeatDemand.state == OFF){
//logWarn("Demo","This is a log entry of type Warn!")
//} // current temp - buffer higher then target but demand already off
//else if((LivingrTempTarget.state as Number < LivingrTemp.state as Number ) && LivingrHeatDemand.state == ON){ // current temp - buffer higher then target turn off demand
//LivingrHeatDemand.postUpdate(OFF)
//logWarn("Demo","This is a log entry of type Warn!")
// }
// the check if the state is already appropiate and then do nothing will reduce unnecesarry rule triggers
end
it than gives me :
2017-08-11 12:18:37.222 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'newheating.rules' has errors, therefore ignoring it: [33,68]: missing '>' at 'as'
[37,68]: missing '>' at 'as'
if i comment the last two else if i dong get a error and it works. but can it really not work with < instead of > ?
so it works if i only use >. Is this an OH Limitation that i cant use <??? That was interseting. So know another question i change the temptarget via an setpoint in 0.1 steps between 16 and 23 degrees. the logs the gui shows 19.3 as an example. but the log shows me that the actual value is something like 19.2999999999999. How does this come? how can i solve it? just by manually setting the temp to 19.3 once via rest?
Simply leave the as Number part out. Then it should work fine.
As a side note, I think you’ll want to use LivingrHeatDemand.sendCommand(ON) and LivingrHeatDemand.sendCommand(OFF) unless you really only want to update the GUI.
rule "Livingroom Demand"
when
Item LivingrTemp received update or //Current Tmperature in the Room
Item LivingrTempTarget received update //Target Tmperature in the Room
then
if(LivingrHeatMan.state == ON){} //Is manual control mode for the Room Set ( Set Valves via Valve and manually turn on or off Boiler at Switch)
else if((LivingrTempTarget.state > LivingrTemp.state) && LivingrHeatDemand.state == ON){
logWarn("Livingroom Demand","LivingrTempTarget.state > LivingrTemp.state) && LivingrHeatDemand.state == ON")
} // current temp - buffer lower then target but demand already on
else if((LivingrTempTarget.state > LivingrTemp.state ) && LivingrHeatDemand.state == OFF){ // current temp - buffer lower then target turn on demand
LivingrHeatDemand.postUpdate(ON)
logWarn("Livingroom Demand","LivingrTempTarget.state > LivingrTemp.state ) && LivingrHeatDemand.state == OFF")
}
else if((LivingrTempTarget.state < LivingrTemp.state) && LivingrHeatDemand.state == OFF){
logWarn("Livingroom Demand","LivingrTempTarget.state < LivingrTemp.state) && LivingrHeatDemand.state == OFF")
} // current temp - buffer higher then target but demand already off
else if((LivingrTempTarget.state < LivingrTemp.state) && LivingrHeatDemand.state == ON){ // current temp - buffer higher then target turn off demand
LivingrHeatDemand.postUpdate(OFF)
logWarn("Livingroom Demand","LivingrTempTarget.state < LivingrTemp.state) && LivingrHeatDemand.state == ON")
}
// the check if the state is already appropiate and then do nothing will reduce unnecesarry rule triggers
thanks a lot deleting the states did the Deal. Wy is that exactly?
Also regarding the sendUpdate. I always thought for non physical Items like this ( just a proxy switch in OH) i should use sendUpdate and always when i want to do something with a physical Device i should use sendCommand. That confuses me a bit now.
Item is the item itself Item.state is the state of the item as a state.
So, if the item is of type OnOffType, this would be ON or OFF (without quotation marks!) "ON" is a string, where ON is a state, please keep that in mind
If dealing with numbers, you have to cast the state to a NumberType, so use (Item.state as Number) or (Item.state as DecimalType). If comparing two item states of type number, make sure the brackets are correct:
(item1.state as Number < item2.state as Number) //WRONG
((item1.state as Number) < (item2.state as Number)) //CORRECT
So the rule should be like
rule "Livingroom Demand"
when
Item LivingrTemp changed or //better trigger on changed
Item LivingrTempTarget changed
then
if(LivingrHeatMan.state != ON) {
logInfo("LivingDem","Livingromm Heat is auto")
logInfo("LivingDem","Target Temp {}°C",LivingrTempTarget.state)
logInfo("LivingDem","Current Temp {}°C",LivingrTemp.state)
if((LivingrTempTarget.state as Number) > (LivingrTemp.state as Number )){
logInfo("LivingDem","It's cold.")
if(LivingrHeatDemand.state == ON) {
logInfo("LivingDem","The heater is already on!")
}
else if(LivingrHeatDemand.state == OFF){
logInfo("LivingDem","Let's switch the heater on!")
LivingrHeatDemand.postUpdate(ON)
}
}
else if((LivingrTempTarget.state as Number) < (LivingrTemp.state as Number )){
logInfo("LivingDem","It's hot.")
if(LivingrHeatDemand.state == ON) {
logInfo("LivingDem","Let's switch the heater off!")
LivingrHeatDemand.postUpdate(ON)
}
else if(LivingrHeatDemand.state == OFF){
logInfo("LivingDem","The heater is already off!")
}
}
}
end
Okay so thats good info but just so that i get it 100%
I dont fully understand when i can work with he Item only and not the state.
In addition my current working code now looks like the following:
then
if(LivingrHeatMan.state == ON){} //Is manual control mode for the Room Set ( Set Valves via Valve and manually turn on or off Boiler at Switch)
else if((LivingrTempTarget.state > LivingrTemp.state ) && LivingrHeatDemand.state == ON){
logWarn("Demo","Target higher then current demand already on")
} // current temp - buffer lower then target but demand already on
else if((LivingrTempTarget.state > LivingrTemp.state ) && LivingrHeatDemand.state == OFF){ // current temp - buffer lower then target turn on demand
LivingrHeatDemand.sendCommand(ON)
logWarn("Demo","Target higher then current demand off")
}
else if(( LivingrTempTarget.state < LivingrTemp.state ) && LivingrHeatDemand.state == OFF){
logWarn("Demo","current higher then target demand already off")
} // current temp - buffer higher then target but demand already off
else if((LivingrTempTarget.state < LivingrTemp.state ) && LivingrHeatDemand.state == ON){ // current temp - buffer higher then target turn off demand
LivingrHeatDemand.sendCommand(OFF)
logWarn("Demo","current higher then target demand on")
}
// the check if the state is already appropriate and then do nothing will reduce unnecessary rule triggers
end
as you can see i am know working with states. But always without as number and it works. Also as you can see i only have a single backet around the full comparssion.
How would that look like if i add another var into the code? like this?
((item1.state as Number) < ((item2.state as Number)-var))