[SOLVED] Automatic watering rule and if statement

Hi,

I’m a bit stuck and can’t figure out how to fix it at this moment, I use the new Gardena API binding and everything is working fine from the control page.

So this is the setup:

Item:

  • SensorPlantenbak_Sensor_Humidity (measures the percentage of humidity in the ground)
  • WaterkraanAchter_Valve_commands_DurationWatering (this is a command item, before you start watering, it first want to know for how long, so you’ve to set it)
  • WaterkraanAchter_Valve_commands_OpenValveWithDuration (you can command this item with ON or OFF to set the valve to open or close)

This is the rule I created so far.

rule "Bewatering plantenbakken achter"
when 

Item Rule_Trigger changed

then
var Number w = SensorPlantenbak_Sensor_Humidity.state as Number
if (w < 15) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(60)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(OFF)

if (w < 30) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(30)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(OFF)

if (w < 50) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(15)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(OFF)
end 

Now the problem is that multiple if statement can be true resulting in multiple command to set different times, I would like to see that if the first if statement is true, the other part of the rule get cancelled, is that possible?

Who can help me in the right direction :slight_smile:

I’m not sure if I got your question right, but woul that help?

if(w < 15){
...
}

if(w >=15 && w < 30){
...
}

if(w >=30 && w<50){
...
}

Sounds like you need to discover the ‘else’ keyword.

if ( xx )

else if ( yy)

else

Only one of the code sections can be executed.

Thanks, I think this will work to, just wondering, is there another way…?

Oh yes you’re right, i’ve forgot the else statement :wink:

Yea I assumed that it must be done with that statement and was reading the documentation but still now quite sure how to use it in my rule.

But what if you have 4 or 5 statements?

I think I didn’t understand it well or did something wrong, this is what happening in the logging now:

2020-07-24 16:10:33.320 [ome.event.ItemCommandEvent] - Item ‘Rule_Trigger’ received command OFF

2020-07-24 16:10:33.351 [vent.ItemStateChangedEvent] - Rule_Trigger changed from ON to OFF

2020-07-24 16:10:33.849 [vent.ItemStateChangedEvent] - LocalRaspberry_Sensors_CPUTemperature changed from 39.2 to 39.7

2020-07-24 16:10:34.045 [ome.event.ItemCommandEvent] - Item ‘WaterkraanAchter_Valve_commands_DurationWatering’ received command 30

2020-07-24 16:10:34.066 [ome.event.ItemCommandEvent] - Item ‘WaterkraanAchter_Valve_commands_OpenValveWithDuration’ received command ON

2020-07-24 16:10:34.088 [ome.event.ItemCommandEvent] - Item ‘WaterkraanAchter_Valve_commands_DurationWatering’ received command 15

2020-07-24 16:10:34.107 [ome.event.ItemCommandEvent] - Item ‘WaterkraanAchter_Valve_commands_OpenValveWithDuration’ received command ON

2020-07-24 16:10:34.111 [nt.ItemStatePredictedEvent] - WaterkraanAchter_Valve_commands_DurationWatering predicted to become 30

2020-07-24 16:10:34.157 [nt.ItemStatePredictedEvent] - WaterkraanAchter_Valve_commands_OpenValveWithDuration predicted to become ON

2020-07-24 16:10:34.175 [nt.ItemStatePredictedEvent] - WaterkraanAchter_Valve_commands_DurationWatering predicted to become 15

2020-07-24 16:10:34.194 [nt.ItemStatePredictedEvent] - WaterkraanAchter_Valve_commands_OpenValveWithDuration predicted to become ON

2020-07-24 16:10:34.208 [vent.ItemStateChangedEvent] - WaterkraanAchter_Valve_commands_DurationWatering changed from 15.0 min to 30.0 min

2020-07-24 16:10:34.211 [vent.ItemStateChangedEvent] - WaterkraanAchter_Valve_commands_OpenValveWithDuration changed from OFF to ON

2020-07-24 16:10:34.214 [vent.ItemStateChangedEvent] - WaterkraanAchter_Valve_commands_DurationWatering changed from 30.0 min to 15.0 min

2020-07-24 16:10:34.871 [vent.ItemStateChangedEvent] - LocalRaspberry_Sensors_CPUTemperature changed from 39.7 to 39.2

2020-07-24 16:10:38.264 [vent.ItemStateChangedEvent] - WaterkraanAchter_Valve_commands_OpenValveWithDuration changed from ON to OFF

And this is the changed rule I ran:

rule “Bewatering plantenbakken achter”
when
Item Rule_Trigger changed

then
var Number w = SensorPlantenbak_Sensor_Humidity.state as Number
if (w < 15) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(60)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else if (w < 30) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(30)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else (w < 50) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(15)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
}
end

You must have one if() part.
You can have as many or as few if else () parts as you like, including none.
You can have one or none else parts.

You can’t have an else() part that’s just silly syntax.

It sounds logical when you say it but I’m not sure how to get it done in one if statement, can you help me a bit further how I should do that?

if (xx) {
   This code will run if xx is true
} else if (zz) { 
   This code will run if zz is true but not xx
   This section is optional
} else if (yy) {
   This code will run if yy is true but not xx and not zz
   This section is optional
} else {
   This code will run if none of the above are true
   This section is optional
}

Always take care to have paired braces { }

if (today=="tuesday") {
   Put bins out
} else {
   Leave bins alone
}


if (forecast=="rain") {
   It is going to rain
} else if (forecast=="dry") {
   It is going to stay dry
}
// neither, if we have snow, or no forecast at all

EDIT - formatted for clarity, now I’m not on a phone.

So as far as I see you are translating the current humidity into a watering duration.
What about you put that relation into a formula, e.g.
Humidity 15 --> 60
Humidty 30 --> 30
Humidity 60 --> 15

The formula could be

Duration = (1/humidity) * 900

Of course you don’t want to have infinite watering time so you should limit it to e.g. 60

if(humitidy < 10)
{
  duration = 60
}
else
{
  duration = (1/humidity) * 900
}

WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(duration)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
1 Like

So this should be right the:

rule “Bewatering plantenbakken achter”
when
Item Rule_Trigger changed

then
var Number w = SensorPlantenbak_Sensor_Humidity.state as Number
if (w < 15) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(60)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else if (w < 30) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(30)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else (w < 50) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(15)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
}
end

But it still runs all statements…

You still cannot have else(condition)
You can have else if(condition) or just plain else.

I’m surprised openhab.log is not complaining about syntax errors.

That is also a possibility to get the outcome of watering longer with a lower humidity percentage.

I’m not that advanced yet in creating rules so I love to see examples how people automate there desired goal.

Thanks for the tip, I’ll also play around with this mechanism :slight_smile: and I’m sure it will come in handy in one of my future projects.
The next step when this rule works is to integrate the rain forecast as-well and lower or not watering at all in some scenario’s.

Ah that was the missing piece I needed to know, when I’m at home again in 1 hour I will try it, now I beter understand the functions in the rule with if/else/else if, thanks :slight_smile:

Just modified the rule again, and it is working now as I intended :smiley:
What I use now:

rule "Bewatering plantenbakken achter"
when 
	Time cron "0 00 21 ? * MON-FRI *"

then
var Number w = SensorPlantenbak_Sensor_Humidity.state as Number
    if (w < 15) {
    WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(60)
    WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
    } else if (w < 30) {
    WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(30)
    WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
    } else if (w < 50) {
    WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(15)
    WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
}
end  

The humidity is now 31% and I fired the rule with the trigger, it started the watering for 15 minutes as designed, THANKS A LOT!

One more question, do you know if there is a function for a rule to cancel the complete rule, I would also like to read the rain forecast for the next 24 hours and use this in another if statement, so when there is more rain coming for more then value X, I want to cancel till the next day when the rule will run.

Add some code at the top of your rule (or in another rule) to get the rain value as desired. Then add a check before your other if conditions like this:

Thanks, that wil work indeed :slight_smile:

I just discovered another strange behavior. When I fire the rule by the trigger item, the rule gets executed and the watering starts. I stopped the watering and tried to trigger the rule again, but the trigger items changes from state what should trigger the rule, but this doesn’t happen.

In the logging I see:

2020-07-24 18:31:11.286 [ome.event.ItemCommandEvent] - Item ‘Rule_Trigger’ received command ON

And that’s it, nothing happens :frowning:
When I restart OH and try it again, it will run the rule again, 1 time, after that it doesn’t seem te work anymore… any ideas?

The last rule that you have shown has nothing about Item Rule_Trigger.
Perhaps you are triggering from change - have you anything to change the Item to OFF? It can only change to ON once, no matter how many ON commands you send.

Maybe you meant to trigger on command instead.

This is the test rule:

rule “Bewatering plantenbakken achter”
when
Item Rule_Trigger changed

then
var Number w = SensorPlantenbak_Sensor_Humidity.state as Number
if (w < 15) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(60)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else if (w < 30) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(30)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
} else if (w < 50) {
WaterkraanAchter_Valve_commands_DurationWatering.sendCommand(15)
WaterkraanAchter_Valve_commands_OpenValveWithDuration.sendCommand(ON)
}
end

So it response to the item Rule_Trigger what is a switch that I flip from off to on, normally the rule runs every time it changes from state ON to OFF or OFF to ON. But not with this rule for some reason… It also worked before when I had the IF state wrong and all statement run. This happened every time I used the trigger.