Switches, HTTP and OpenHAB

3,287 views
Skip to first unread message

Jonathan Giles

unread,
Jan 9, 2014, 5:02:35 AM1/9/14
to ope...@googlegroups.com
Hi all,

I have put a Raspberry Pi out in my garage, to serve as a wifi repeater for my new office (which otherwise wouldn't have been in range of wifi) and a means of controlling my garage door. I have a relay to open/close the garage door, and a reed switch to tell if the garage door is open or not. Everything is working quite well, but I am falling over at the OpenHAB stage.

The way things are implemented, I have built a small http server that is running on the pi, and it has a few rest urls for things like testing if the garage door is open, and for instructing it to do things like open, close and toggle from the current state into the opposite state. This all works fine outside of openhab - I'm seeing the data and results I expect.

There are two problems I have when bringing this into OpenHAB, and I really hope the community may have some ideas on how best to tackle this.

Problem 1: No matter what I do, I just can't seem to get the OpenHAB http binding to trigger an http call to the server. I assumed I could have an item like this:
Switch Garage_Door_Button        "Garage Door"        <garagedoor> { http=">[CHANGED:POST:http://192.168.1.104:8080/garagePi/garageDoor/toggle]" }

And a sitemap statement like this:
Switch item=Garage_Door_Button

and that when the button is pressed I would see the server receive a request and return a response - but from the openHAB log all I see is that the switch state has been toggled - the http url is never called. What am I doing wrong here?

Problem 2: This is a higher level issue: ideally I would have a single switch in my UI that reflects the current state of the garage door, and if I press it I would expect it to toggle state. Therefore, what I would like to do is define an item like this:

Switch Garage_Door_Open            "Garage Door"        <garagedoor> { http=">[ON:POST:http://192.168.1.104:8080/garagePi/garageDoor/open] >[OFF:POST:http://192.168.1.104:8080/garagePi/garageDoor/close] <[http://192.168.1.104:8080/garagePi/garageDoor/isOpen:3600000:REGEX((.*?))]" }

Because I'm stuck on problem 1 I don't know if this approach works, but assuming it doesn't - is there a recommended approach? The other (obvious) requirement is that I don't want to get into a feedback loop where the garage door state alternates based on the isOpen call being called (obviously the 3600000 is not the desired refresh rate and it would be much more frequently checked than that once everything is working).

I wonder if I am being too direct in my approach, and should separate out booleans that represent the current state from the desired state, and to then write a rule that triggers the change?

I hope I've clarified my two issues, and I do appreciate any help the community may offer.
Thanks,
-- Jonathan

Ben Jones

unread,
Jan 9, 2014, 5:22:52 AM1/9/14
to ope...@googlegroups.com
Yep - I think you need two items - since they are actually two different things - as you say one is the current state of the door, and the other is the switch to open/close the door. I have the same setup for my garage, connected to a RPi as well as it turns out (via a PiFace board)...

Contact    Door_GarageDoor               "Garage Door [%s]"              <garagedoor>     (Doors)         { piface="piface1:IN:3" }
Switch     Door_GarageDoorOpener     "Garage Door Opener"          <remotecontrol>  (Security)     { piface="piface1:OUT:1" }

The Contact is the door state, and the switch is the trigger to open/close the door - i.e. simulate a click on the remote door opener.

In my sitemap I have;

Switch item=Door_GarageDoorOpener mappings=[ON="Press"]
Text item=Door_GarageDoor

So this renders as a single push button for the opener - 'Press'. 

And my rules;

rule "Garage door opener"
when
    Item Door_GarageDoorOpener received command ON
then
    if (openGarageDoorTimer != null)
        openGarageDoorTimer.cancel()

    // release the garage door 'opener' after a short delay
    openGarageDoorTimer = createTimer(now.plusSeconds(1)) [|
        sendCommand(Door_GarageDoorOpener, OFF)
    ]
    
    // disarm the alarm if it is set
    if (Alarm_Armed.state == ON)
    sendCommand(Alarm_Disarm, ON)
end

This is to simulate a button press for 1s. 

This works like a charm. I can press the opener button and see the door open instantly. Conversely if I press the button when the door is open, it takes 10-15s before the state updates to closed, since it takes this long for the door to actually close.

This type of feedback is great as you know that even though you clicked the button to close the door, the door has actually closed, since the door sensor is reporting it as closed - and not just the fact you pressed a button.

Not sure about the HTTP binding sorry...

Jonathan Giles

unread,
Jan 9, 2014, 6:02:33 AM1/9/14
to ope...@googlegroups.com
Thanks Ben, that helps a bit - I wasn't aware of the Contact item. It seems like I won't need the rule at all the timer logic is on my server, rather than in OpenHAB.

Hopefully someone can now help clarify the issue around the http binding - I still don't know why that isn't working.... Also, for some reason even calling isOpen on the server results in oddness - in my server I just return the string 'true' or 'false' - but whilst that appears fine in my browser, in OpenHAB it is parsed in as "-", and I'm not sure why - the logs don't show anything.

Thanks,
-- Jonathan

Jonathan Giles

unread,
Jan 9, 2014, 6:13:53 AM1/9/14
to ope...@googlegroups.com
To answer (somewhat) my own question about the contact item being '-', I rebooted OpenHAB and noticed that the http binding was playing a bit better now (on the GET query, but the POST still doesn't happen). Anyway, the issue I have now is the type of the contact - I don't know what to set....

Here's my log:

00:08:51.444 DEBUG o.o.b.h.internal.HttpBinding[:155]- item 'Door_GarageDoor' is about to be refreshed now
00:08:51.520 DEBUG o.o.c.t.i.s.RegExTransformationService[:42]- about to transform 'false' by the function '(.*?)'
00:08:51.520 DEBUG o.o.b.h.internal.HttpBinding[:189]- transformed response is 'false'
00:08:51.520 DEBUG o.o.b.h.internal.HttpBinding[:252]- Couldn't create state of type 'class org.openhab.core.library.items.ContactItem' for value 'false'
00:08:51.550 DEBUG o.o.c.i.items.ItemUpdater[:73]- Received update of a not accepted type (StringType) for item Door_GarageDoor

Presently the item is implemented as follows:

Contact    Door_GarageDoor              "Garage Door [MAP(garageState.map):%s]"            <garagedoor>     (Doors)        { http="<[http://192.168.1.104:8080/garagePi/garageDoor/isOpen:10000:REGEX((.*?))]" }

But clearly that is wrong....It's times like these I wish the OpenHAB designer would work for me! :-)

Does anyone have a pointer on how to convert a 'true' / 'false' string into a type that can be set on a contact? Possibly I need a separate String item that is bound to the http request, and then a rule that updates the Contact based on the String?

Thanks,
-- Jonathan

Ben Jones

unread,
Jan 9, 2014, 1:45:44 PM1/9/14
to ope...@googlegroups.com
The Contact item will only accept OPEN/CLOSED I believe, and the Switch only ON/OFF. So you will either need to update your web server to return the appropriate values, add an intermediate item and write rules to do the conversion yourself, or add some sort of pattern replacing in your regex transformation.

Jonathan Giles

unread,
Jan 9, 2014, 4:59:00 PM1/9/14
to ope...@googlegroups.com
In the end I resolved this issue, using the following items:

String     Door_GarageDoor_state     "Garage Door [MAP(garageState.map):%s]"    <garagedoor>      { http="<[http://192.168.1.104:8080/garagePi/garageDoor/isOpen:10000:REGEX((.*?))]" }
Switch    Door_GarageDoor_button   "Garage Door Opener"                                   <remotecontrol>   { autoupdate="false" }

And the following rule:

rule updateGarageDoorContact
when
    Item Door_GarageDoor_button received command ON
then 
    sendHttpGetRequest("http://192.168.1.104:8080/garagePi/garageDoor/toggle")
end

Ideally the http request would be a post request, but an action appears to only exist for sending http get requests, so I changed the server to accept get queries to the toggle url.

I'm happy to receive suggestions on how to improve this....

@Ben - could you email me the remotecontrol image file that you use please?

Thanks!
-- Jonathan

Ben Jones

unread,
Jan 9, 2014, 5:27:02 PM1/9/14
to ope...@googlegroups.com
I did a search of the openHAB source and found these following in the HTTP action bundle...

sendHttpGetRequest(url)
sendHttpPutRequest(url)
sendHttpPutRequest(url, contentType, content)
sendHttpPostRequest(url)
sendHttpPostRequest(url, contentType, content)
sendHttpDeleteRequest(url)

d0t1...@gmail.com

unread,
Jan 9, 2014, 10:15:40 PM1/9/14
to ope...@googlegroups.com
This thread helped me to better understand and fix some of the switch control & state management issues I was facing.  Thanks all!
Reply all
Reply to author
Forward
0 new messages