PostUpdate and sendCommand not triggering a rule

I am using openHAB 2 and struggling with something which I guess is fairly basic! I have got a lot of rules working fine, but now I am trying to call one rule from within another. I been reading around the differences between sendCommand and postUpdate, but think I am missing something more fundamental. Please can you help?

I have hacked the remote for some RF remote controlled sockets, so that the buttons on the remote are operated by the Raspberry Pi’s GPIO. Each socket has an On button and an Off button. Because of the way the remote is wired, it is essential that you do not press the On and Off buttons together. So I have written a set of rules, each of which switches off all the GPIO outputs before switching on the button that is required. Each rule is attached to a switch item, one of which turns the lamps on and the other turns them off. This works fine.

But I am trying to get another rule working, using a cron job to switch the lamps off at a certain time. To make testing easier I have attached the same rule to a test switch:

Items

Switch GPIO_RFSocket_Two_On		{ gpio="pin:2 initialValue:low force:yes" }
Switch GPIO_RFSocket_Two_Off	        { gpio="pin:15 initialValue:low force:yes" }
Switch RF_Lamps_on "Lamps ON"
Switch RF_Lamps_off "Lamps OFF"
Switch Test_switch "Test"

In HABpanel I have the Lamps ON and Lamps OFF switches, as well as the Test switch. The Lamps ON and Lamps OFF switches work fine. The Test switch goes on and off but does not cause anything to change.

Rules

rule "Lamps on"
when
	Item RF_Lamps_on changed
then
	/* ensure all buttons are off before putting any button on */
	sendCommand(GPIO_RFSocket_One_On, OFF)
	sendCommand(GPIO_RFSocket_One_Off, OFF)

	/* press button TWO ON, wait 1 second then release it. */
	sendCommand(GPIO_RFSocket_Two_On, ON)
	createTimer(now.plusSeconds(1)) [|
		sendCommand(GPIO_RFSocket_Two_On, OFF)
    ]
	
	/* Change the switch on the panel back to OFF */
	sendCommand(RF_Lamps_on, OFF)
end

rule "Test rule"
when
	Item Test_switch changed
then
	sendCommand(RF_Lamps_off, ON)
end

You have defined GPIO_RFSocket_Two_Ox and use GPIO_RFSocket_One_Ox.
Are the buttons on the remote switches or push-buttons?
If this are push-buttons try

Switch RF_Lamps "Lamps"
Switch Test_switch "Test"
Switch GPIO_RFSocket_One_On		{ gpio="pin:2 initialValue:low force:yes" }
Switch GPIO_RFSocket_One_Off	        { gpio="pin:15 initialValue:low force:yes" }
rule "Lamps"
when
    Item RF_Lamps changed
then
    if (RF_Lamps.state == ON) {
        GPIO_RFSocket_One_Off.sendCommand(OFF)
        GPIO_RFSocket_One_On.sendCommand(ON)
        createTimer(now.plusSeconds(1)) [|GPIO_RFSocket_One_On.sendCommand(OFF)]}
    else {
        GPIO_RFSocket_One_On.sendCommand(OFF)
        GPIO_RFSocket_One_Off.sendCommand(ON)
        createTimer(now.plusSeconds(1)) [|GPIO_RFSocket_One_Off.sendCommand(OFF)]}
end

rule "Test rule"
when
	Item Test_switch changed
then
	RF_Lamps.sendCommand(Test_switch.state)
end

or

rule "Lamps ON"
when
    Item RF_Lamps changed to ON
then
    GPIO_RFSocket_One_Off.sendCommand(OFF)
    GPIO_RFSocket_One_On.sendCommand(ON)
    Thread::sleep(100)
    GPIO_RFSocket_One_On.sendCommand(OFF)
end

rule "Lamps OFF"
when
    Item RF_Lamps changed to OFF
then
    GPIO_RFSocket_One_On.sendCommand(OFF)
    GPIO_RFSocket_One_Off.sendCommand(ON)
    Thread::sleep(100)
    GPIO_RFSocket_One_Off.sendCommand(OFF)
end

Using Methods is better than Actions


as @hr3 already corrected it, it would be better to use the method RF_Lamps.sendCommand(Test_switch.state) than the Action in your original post sendCommand(RF_Lamps_off, ON)
If you want to stick with Actions, check your logs, you may see some error messages, as the Action requires two strings as arguments, ON may be autoconcerted into a string, but you will need to convert your item name into a string yourself (put it within quotation marks). Many of these issues fall away when using Methods as DSL will be able to do many more auto-conversions (see links to docs above).

This is where loginfo statements in your rules will come in handy.


Start using them generously, for example, right at the beginning of the rules to make sure you see whether the rules gets triggered at all. You can also log all the states of the items in question so that you can really see what actually is happening in your rules.

Thread::sleep by default requires milliseconds as arguments, this would make this thread wait only one tenth of a second.There are many good reasons to stick with a timer construct (as the OP already had) if you need a delay of 1s; thread::sleep statements of more than a few 10ms are not recommended. for more see here:

Reading your original post made think, why did you back the remote of the RF-plugs in the first place? Chances are high those plugs are using an Intertechno compatibile code. By using a RF transmitter in conjunction with the Intertechno binding you could send the commands directly. I did use a CUL Stick to do that ( shopped at busware.de).

I actually don’t have a problem with thread sleeps of up to 300 msecs. 100 is short enough it shouldn’t cause any problems. In that Why have my Rules stopped running post I think I set a max recommended length at 500 msecs.

If it makes the code simpler, and the sleep is less than 500 msecs, and there isn’t some other complicating factor (e.g. the Rule gets retriggered faster than one instance of it can complete because of the sleep) I would recommend using Thread::sleep.

The problem with all this sort of stuff is the world isn’t black or white. We can give advice but there will always be a gray area where either answer could be equally good.

1 Like

Thank-you everyone for your help and advice. This is what I love about the openHAB community - so many people who are happy to share advice, not just to solve the immediate problem but so that others can learn and get better at using the system.

I now have a much better idea what to do with this and will pick it up next week.