[SOLVED] Configuration Help needed. Item only switches in UI but not from rule

I am controlling the watering of my garden from Openhab running on my raspi with a relais board attached to the raspi GPIO pins.

Controlling each of the valves from my basic UI works fine with each walve being resembled as a switch in the sitemap.

Now, for safety reasons I tried to add a watchdog rule that turns off all valves after a maximum active time, just in case I forgot to turn them off again in the UI

Rule:

val topf_timeout=1
rule "Watchdog für Blumentöpfe"
when 
	Item valve2Switch received command ON
then
	logInfo("watering.rules", "In rule Blumentopf")
	createTimer(now.plusMinutes(topf_timeout)) [| valve2Switch.sendCommand(OFF) ] 
end

What happens is that I see the delayed watchdog event is triggered after one minute (event.log) but the underlying python script is never being called and therefore the valve never turned off

event.log

2018-08-10 15:41:01.717 [ome.event.ItemCommandEvent] - Item 'valve2Switch' received command ON
2018-08-10 15:41:01.733 [vent.ItemStateChangedEvent] - valve2Switch changed from OFF to ON
2018-08-10 15:42:01.782 [ome.event.ItemCommandEvent] - Item 'valve2Switch' received command OFF

openhab2.log

2018-08-10 15:38:53.955 [INFO ] [marthome.model.script.watering.rules] - In rule Blumentopf
2018-08-10 15:41:01.762 [INFO ] [marthome.model.script.watering.rules] - In rule Blumentopf

The first two lines in the event log (15:41:01) are triggered by switching the valve on in the UI
The third line then must be the result of my watchdog rule (here set to 1 minute)
However, this second event never leads to the python script being called. The relais log only shows the call triggered by the UI, not the one from the rule

Maybe I still have some misunderstanding on how the things, items and events work together. Any debug hint would be appreciated.

myhome.sitemap

sitemap myhome label="Thomas Home and Castle" {
        Switch item=valve1Switch label="Hauptventil" icon="faucet" //mappings=[ "ON"="ON", "OFF"="OFF" ]
        Switch item=valve2Switch label="Blumentöpfe" icon="faucet" //mappings=[ "ON"="ON", "OFF"="OFF" ]
        Switch item=valve3Switch label="Blumenbeet" icon="faucet" //mappings=[ "ON"="ON", "OFF"="OFF" ]
        Switch item=valve4Switch label="Gemüsebeet" icon="faucet" //mappings=[ "ON"="ON", "OFF"="OFF" ]

}

valves.items

String valve1Switch  "Ventil 1" <switch>  [ "Switchable" ] { channel="exec:command:valve1-control:input", autoupdate="true" }
String valve2Switch  "Ventil 2" <switch>  [ "Switchable" ] { channel="exec:command:valve2-control:input", autoupdate="true" }
String valve3Switch  "Ventil 3" <switch>  [ "Switchable" ] { channel="exec:command:valve3-control:input", autoupdate="true" }
String valve4Switch  "Ventil 4" <switch>  [ "Switchable" ] { channel="exec:command:valve4-control:input", autoupdate="true" }
String valve5Switch  "Ventil 5" <switch>  [ "Switchable" ] { channel="exec:command:valve5-control:input", autoupdate="true" }
String valve6Switch  "Ventil 6" <switch>  [ "Switchable" ] { channel="exec:command:valve6-control:input", autoupdate="true" }
String valve7Switch  "Ventil 7" <switch>  [ "Switchable" ] { channel="exec:command:valve7-control:input", autoupdate="true" }

valves.things

Thing exec:command:valve1-control [ command="sudo /etc/openhab2/scripts/relais.py 9 %2$s", interval=0, autorun=true ]
Thing exec:command:valve2-control [ command="sudo /etc/openhab2/scripts/relais.py 10 %2$s", interval=0, autorun=true ]
Thing exec:command:valve3-control [ command="sudo /etc/openhab2/scripts/relais.py 22 %2$s", interval=0, autorun=true ]
Thing exec:command:valve4-control [ command="sudo /etc/openhab2/scripts/relais.py 27 %2$s", interval=0, autorun=true ]
Thing exec:command:valve5-control [ command="sudo /etc/openhab2/scripts/relais.py 17 %2$s", interval=0, autorun=true ]
Thing exec:command:valve6-control [ command="sudo /etc/openhab2/scripts/relais.py 18 %2$s", interval=0, autorun=true ]
Thing exec:command:valve7-control [ command="sudo /etc/openhab2/scripts/relais.py 2 %2$s", interval=0, autorun=true ]

/etc/openhab2/scripts/relais.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
import RPi.GPIO as GPIO
import sys,os
import logging
logging.basicConfig(filename='/tmp/relais.log',level=logging.DEBUG)
logging.debug('launching Relais')
logging.debug(os.getegid())
logging.debug(os.geteuid())


GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
#os.system("sudo echo "+str(sys.argv[0])+" > /home/openhabian/test")
logging.debug("Argv0:>>"+str(sys.argv[0])+"<<")
logging.debug("Argv1:>>"+str(sys.argv[1])+"<<")
logging.debug("Argv2:>>"+str(sys.argv[2])+"<<")
if len(sys.argv) > 2:
    logging.debug("more than 2 arguments")
    RELAIS_GPIO = int(sys.argv[1])# + int(sys.argv[2])
    GPIO.setup(RELAIS_GPIO, GPIO.OUT)
    #GPIO.output(RELAIS_GPIO, GPIO.LOW)

    GPIO.output(RELAIS_GPIO, GPIO.HIGH)
    if str(sys.argv[2]) == u"ON":
        logging.debug("Turning Relais on")
        GPIO.output(RELAIS_GPIO, GPIO.HIGH)
    elif str(sys.argv[2]) == u"OFF":
        logging.debug("Turning Relais off")
        GPIO.output(RELAIS_GPIO, GPIO.LOW) # an
else:
    logging.debug("WRong number of arguments")

/tmp/relais.log

DEBUG:root:launching Relais
DEBUG:root:0
DEBUG:root:0
DEBUG:root:Argv0:>>/etc/openhab2/scripts/relais.py<<
DEBUG:root:Argv1:>>10<<
DEBUG:root:Argv2:>>ON<<
DEBUG:root:more than 2 arguments
DEBUG:root:Turning Relais on

val topf_timeout=1
rule "Watchdog für Blumentöpfe"
when 
	Item valve2Switch received command ON
then
	logInfo("watering.rules", "In rule Blumentopf")
	createTimer(now.plusMinutes(topf_timeout)) [| valve2Switch.sendCommand(OFF) ] 
end

I think you need a comma between ) [ like this createTimer(now.plusMinutes(topf_timeout)), [| valve2Switch.sendCommand(OFF) ]

Don’t think so. Adding the comma leads to

Configuration model 'watering.rules' has errors, therefore ignoring it: [33,44]: mismatched input ',' expecting 'end'

I was just looking over the rule again, try using only one ) not two. I’ll put this in VScode and see what it complains about.

Try using this and see if your error goes away with good results.

var Timer waterTimer = null
val int timeoutMinutes = 1

rule "Watchdog fur Blumentopfe received ON"
when
    Item valve2Switch received update ON
then
    if(waterTimer === null) {
        waterTimer = createTimer(now.plusMinutes(timeoutMinutes ), [|
            valve2Switch.sendCommand(OFF)
            waterTimer = null
        ])
    }
end

Edit: had to rename the var inside the rule for your application.

What is missing in the events.log is the “Item ‘valve2Switch’ changed from ON to OFF.” Did you neglect to include that in your post or is that line truly missing? If it is truly missing that would explain why the script isn’t running because it is the change event that causes the Exec binding to run the script.

You are using autoupdate=true so that should not be the source of the problem, but try removing them to see what happens. Maybe it isn’t interpreting that correctly and the default behavior is autoupdate=true anyway so it listing it explicitly is redundant.

Also remove the interval filed from the Things. That is optional and probably doesn’t need to be defined. I doubt it is the source of the problem but we don’t know the source of the problem so anything that sticks out as odd is a candidate.

Thomas’s syntax is correct. Methods that take a lambda as the last argument can be defined by putting the lambda definition outside the parens. I don’t like this syntax because it obscures that you are actually passing a lambda to the method createTimer, but it is perfectly valid.

createTimer(now.plusMinutes(topf_timeout)) [| valve2Switch.sendCommand(OFF) ]    

is identical to

createTimer(now.plusMinutes(topf_timeout), [| valve2Switch.sendCommand(OFF) ])

What is missing in the events.log is the “Item ‘valve2Switch’ changed from ON to OFF.” Did you neglect to include that in your post or is that line truly missing? If it is truly missing that would explain why the script isn’t running because it is the change event that causes the Exec binding to run the script.

It is truly missing. I was expecting the watchdog to send the “OFF” command (which seems to have happened) and then I expected valve2Switch to switch state from ON to OFF, thereby executing the relais.py script with “OFF” as argument…

And, what I forgot to mention, I expected the UI to be updated as well to reflect the new OFF state of valve2, which also did not happen

I tried your code but without success. The behavior remains exactly the same. I see

Item 'valve2Switch' received command OFF

in the events.log but the ItemStateChangedEvent for valve2Switch never occurs and the relais.py script is not called

As you used a string Item, I guess you have to use

valve2Switch.sendCommand("OFF")

to explicitly send a string and not a state.

1 Like
valve2Switch.sendCommand("OFF")

Yes, this did the trick! The state change now happens correctly.

Thank you very much and thanks to all who took the time to answer my question

Good catch!

:blush:

1 Like