Howto make a rule thats somthing on for x time when a value is reached

Hello,

I use Openhab 2.

I have a moister sensor in my bathroom, when the moister exceeds a certain value i want to turn on the fan for x time.
How can i do this.

Even bether, if the moister is raised within 5 minutes by x% then the fan needs to be turned on for x time.

val maxHumidity = 50
val int fanTime = 10

rule "Turn on fan"
when
    Item Bathroom_Humidity changed
then
    if(Bathroom_Fan.state != ON) {
        if(Bathroom_Humidity.state as Number > maxHumidity) {
            Bathroom_Fan.sendCommand(ON)
            createTimer(now.plusMinutes(fanTime), [| Bathroom_Fan.sendCommand(OFF) ])
        }
    }
end

You need Persistence installed and configured to store Bathroom_Humidity.

val deltaPercent = 0.05 // 5%
val int fanTime = 10

rule "Turn on fan"
when
    Item Bathroom_Humidity changed
then
    if(Bathroom_Fan.state != ON) {
        val pastHum = Bathroom_Humidity.historicState(now.minusMinutes(5)).state as Number
        val currHum = Bathroom_Humidity.state as Number

        if(pastHum < currHum) {
            val delta = currHum - pastHum

            if(delta / pastHum > deltaPercent) {
                Bathroom_Fan.sendCommand(ON)
                createTimer(now.plusMinutes(fanTime), [| Bathroom_Fan.sendCommand(OFF) ])
            }
        }
    }
end

If it were me, I’d want the fan to stay on until a desired humidity has been reached or a maximum amount of time has past with it on.

Switch Bathroom_Fan { expire="10m,command=OFF" } // add your Channel links and other options
val maxHumidity = 50
val hysteresis = 2

rule "Turn on fan"
when
    Item Bathroom_Humidity changed
then
    if(Bathroom_Humidity.state as Number > maxHumidity) {
        if(Bathroom_Fan.state != ON) Bathroom_Fan.sendCommand(ON)
    }
    else if(Bathroom_Humidity.state as Number < maxHumidity - hysteresis) {
         Bathroom_Fan.sendCommand(OFF)
    }
end

hysteresis keeps the fan from rapidly turning on and off if the humidity is right around maxHumidity.

3 Likes

Your last options looks good, but the humidity is not always the same. so there shoud be some kind of delta precent like in the second example.

is there a posiblitiy to build in the last example a max. run time ?

Again, this is just me, but if the room humidity were less than a threshold, I wouldn’t want to turn on the fan even if someone is taking a shower. But I live in a very dry area where it is a struggle to keep the humidity above 30% in the first place.

The last example already has a max runtime. That is what the expire does. If the humidity gets above maxHumidity the fan turns ON. The fan will stay on until the humidity drops below maxHumidity-hysteresis or 10 minutes pass ,which ever comes first.

ok, now i understand. maybe what you are doing in the last example is not that bad .
but i have some errors when loading the rule

val maxHumidity = 50
val hysteresis = 2

rule "Turn on fan"
when
    Item esp_douche_hum changed
then
    if(esp_douche_hum.state as Number > maxHumidity) {
        if(Douche.state != ON) Douche.sendCommand(ON)
    }
    else if(esp_douche_hum.state as Number < maxHumidity - hysteresis) {
         Douche.sendCommand(OFF)
    }
end

and the error, what is wrong ?

2018-01-10 21:17:41.496 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'fan.rules'
2018-01-10 21:17:41.569 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'fan.rules' is either empty or cannot be parsed correctly!
2018-01-10 21:17:41.942 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'fan.rules' has errors, therefore ignoring it: [11,58]: missing '>' at '-'

Probably need to put the subtraction into parens.

else if(esp_douche_hum.state as Number < (maxHumidity - hysteresis)) {

then i get these errors, i tryed it already

2018-01-10 21:48:47.023 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'fan.rules'
2018-01-10 21:48:47.109 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'fan.rules' is either empty or cannot be parsed correctly!
2018-01-10 21:48:47.615 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'fan.rules' has errors, therefore ignoring it: [11,59]: mismatched input '-' expecting ')'
[11,72]: no viable alternative at input ')'

That should work. Force it to treat the variables as Numbers:

val Number maxHumidity = 50
val Number hysteresis = 2

Stil the same error, do i need to install somthing else.
in the previous post you mentioned that i have to install Persistence, is this nessecary and how to do this.

You don’t need anything extra for this.

This makes no sense but I don’t have time to figure out why it doesn’t work.

Use:

val maxHumidity = 50
val minHumidity= 48

rule "Turn on fan"
when
    Item esp_douche_hum changed
then
    if(esp_douche_hum.state as Number > maxHumidity) {
        if(Douche.state != ON) Douche.sendCommand(ON)
    }
    else if(esp_douche_hum.state as Number < minHumidity) {
         Douche.sendCommand(OFF)
    }
end

Thanks for helping so much.

But this isn’t helping it looks like my rules aren’t exapting the less then sign <
if i changed that in > my rule file is accepted.

pretty strange, can’t find through google a solution for that. so if someone nows the anwser feel free to share.

Solved it, but in my items file the fan isn’t stopping after x time.
maybe i did something wrong, so any advise would be welcome.

Switch Douche "Douche ventilator" <fan> {mqtt=">,ajg:/Esp_vent/gpio/12:command:ON:1],>[ajg:/Esp_vent/gpio/12:command:OFF:0],[expire=1m,>[ajg:/Esp_vent/gpio/12:command:OFF:0]"}

What solved the error?

This very malformed syntax.

See https://docs.openhab.org/addons/bindings/mqtt1/readme.html for how to properly format the MQTT binding stuff.

See https://docs.openhab.org/addons/bindings/expire1/readme.html for how to properly format the Expire binding stuff.

Make sure you have installed the Expire binding.

At first glance you are missing the opening [ after your first > in the config string and you are trying to mix the expire and MQTT binding configs.

Because humidity is already a number, i don’t have to use as number. thats the way i solved it.

val maxHumidity = 65
val minHumidity= 3

rule "Turn on fan"
when
    Item esp_douche_hum changed
then
    if(esp_douche_hum.state > maxHumidity) {
        if(Douche.state != ON) Douche.sendCommand(ON)
    }
    else if(esp_douche_hum.state < (maxHumidity-minHumidity)) {
         if(Douche.state != OFF) Douche.sendCommand(OFF)
    }
end

For the MQTT part, my standard MQTT line worked, but i don’t know where to put the expired part.
that’s my problem, i can’t get that information from one of the wiki pages.

That doesn’t make much sense either. If the state is already a Number then the as Number would do nothing. It shouldn’t break the code. Very strange.

Example straight from the Expire binding docs:

Contact MotionSensor "MotionSensor [%s]" { http="<[http://motion/sensor:60000:JSONPATH($.state)]", expire="30s,state=CLOSED" }

Notice how the expire binding is on its own and there is a comma separating the http binding config and the expire binding config.

[quote="ageurtse, post:14, topic:38526, full:true"]

For the MQTT part, my standard MQTT line worked, but i don’t know where to put the expired part.
that’s my problem, i can’t get that information from one of the wiki pages.
[/quote]

i think i figurd it out by myself, by try and error.
and it looks like it is working, also instsalled the expired binding.

this is what i now have.

Switch Douche "Douche ventilator" <fan> {mqtt=">,ajg:/Esp_vent/gpio/12:command:ON:1],>[ajg:/Esp_vent/gpio/12:command:OFF:0]",expire="20m,command=OFF"}

This part is still wrong. It must be {mqtt=">[ajg

That must be a typo, thats why the switch in the gui is working. and the actual fan runing in high speed.

How should I write a rule for the fan to run for 10 minutes and stop for 50 minutes?

@rlkoshak - Hi Rich,
Im trying to use your rule example as above…but it seems the " if(pastHum < currHum)" isnt working due to the currHum var containing the %

I thought the ’ as Number" would strip this?

My test rule:

val int fanTime = 10

rule "Turn on fan"
when
    Item HumidSensor_OfficeFridge changed
then
    if(AeonModule_MainBathFan.state != ON) {
        val pastHum = HumidSensor_OfficeFridge.historicState(now.minusMinutes(5), "influxdb").state as Number
        val currHum = HumidSensor_OfficeFridge.state as Number
        logWarn("MainBathFanRule", "VarInfo PastHum : " + pastHum )
        logWarn("MainBathFanRule", "VarInfo Current : " + currHum )
        if(pastHum < currHum) {
            val delta = currHum - pastHum
            logWarn("MainBathFanRule", "Checkpoint1 : " + delta)

            if(delta / pastHum > deltaPercent) {
                logWarn("MainBathFanRule", "Starting Fan")
                AeonModule_MainBathFan.sendCommand(ON)
                createTimer(now.plusMinutes(fanTime), [| AeonModule_MainBathFan.sendCommand(OFF) ])
            }
        }
    }
end

An extract of the log - as you can see the currHum value contains the % :


==> /var/log/openhab2/openhab.log <==
2019-10-09 11:55:28.082 [WARN ] [arthome.model.script.MainBathFanRule] - VarInfo PastHum : 95.93
2019-10-09 11:55:28.083 [WARN ] [arthome.model.script.MainBathFanRule] - VarInfo Current : 90.63 %