Getting Device Status

I’ve gotten OpenHAB up and running. I now have Zwave control of my devices and I have some devices I have built myself that I am now talking to over the tcp binding happily.

However, I cannot seem to figure out how to receive data over the TCP binding. I think this is a generic OpenHAB question so I posted in here.

Let’s say I have a sensor that monitors my garage door (open or closed). I need to create something in OpenHAB that connects to my TCP server (on a given interval) and queries the status of the door/contact.

For example:

Every 5 seconds send a tcp message to 192.168.x.x:5000 (port 5000) with a string:"garage door status"
My device will then respond with “garage door open”

How do I do this in Openhab? I have spent several hours trying to find this. I would think this would be a very simple task.

See the TCP/UDP Binding page. There are examples there of both publish and receive configurations.

You will need to create two Items, one that publishes the status message and a different one to receive the response.

I’ve studied this page quite a bit. I know I must be missing some simple concept. I have gotten the ON/OFF example to work with a switch, I do not know how to request information from a device using OpenHAB on its own. It seems everything is initiated by an event such as a device toggle etc.

Taking the example from the tcp bindings page:

tcp="<[192.168.0.2:3000:‘REGEX((.*))’]" // for a String Item that captures some state of a remote device that connects to openHAB

Can you provide an example on how to use the example? Where do I put this command? I tried putting it in my items file but I don’t see anything going out.

String Test “[%s]” { tcp=">[192.168.3.202:5016:‘testing’]" }
or
String Test “[%s]” tcp="<[192.168.3.202:5016:‘REGEX((.*))’]"

Neither of these seem to do anything. There has to be something more to this I am missing. Any help is of course appreciated.

Well you have to give an item a command before an item will do anything. So I suggest for testing doing something like this:

  1. make a file called virtual.items, add this line: Switch TEST_VIRTUAL_SWITCH “hit me” (Group_Test)

  2. modify your sitemap so that it shows Group_Test

  3. make a file called virtual.rules and add this:

rule "burn the quarterback"
when
Item TEST_VIRTUAL_SWITCH changed to ON
then
{
sendCommand(Test, “OMG the quarterback is TOAST!”)
sendCommand(TEST_VIRTUAL_SWITCH,OFF)
}
end

Turn the test virtual switch on, and hopefully smile. :smiley:

I don’t have any experience with the binding but you need to specify both the incoming AND the outgoing separately. You might be able to do it with a single Item, I don’t know. If you can it would look like this:

String Request { tcp=">[192.168.3.202:5000:'REGEX((.*))'], <[192.168.3.202:5016:'REGEX((.*))']"}

If that doesn’t work you may need to put the incoming (i.e. the one that starts with ‘>’) in a separate Item from the outgoing (i.e. the one that starts with ‘<’). In a single Item it may result in a loop.

String Request { tcp=">[192.168.3.202:5000:'REGEX((.*))']" }
String Result { <[192.168.3.202:5016:'REGEX((.*))']" }

Then you need a rule to trigger the request:

rule "Request update"
when
    Time cron "5 * * ? * *"
then
    Request.postUpdate("garage door status")
end

Thought postUpdate was for if you wanted to update the gui but not actually interact with the binding underneath, whereas sendcommand hits the binding and the gui?

Not really. Sending a postUpdate usually will cause the underlying binding to also trigger for String and Number Items in particular (I do this to publish to MQTT topics). I believe the purpose for the two is not to keep the binding from triggering but to give you the opportunity in your rules to only trigger when something is deliberately set (command) verses just updated because of something like a periodic poll (update). There is more going on under the covers as well but I’ve not reviewed the code so won’t speculate more.

I’ll admit I mainly do postUpdate to String Items because I saw that in an example early on and just started doing it that way. I’ve not done my due diligence and studied the real difference. I vaguely remember a posting indicating that you can’t send a command to a String or a Number, but suspect I’m remembering wrong.

In any case, assuming that my memory is wrong and you can send a command to a String, from the binding’s perspective, there is no difference and the underlying binding will be triggered in both cases. This behavior may be different for other Item types (Switches, Contacts, etc).

Thank you both for the help.

I have gotten further now thanks to this. I see the “request state updated to garagedoorstatus” in the debug window of OpenHAB, but I do not see the request come through on my TCP server. TCP negotiations must be happening though since OpenHAB does not complain about connecting. It does complain if I enter the incorrect port/ip address.

I am very unfamiliar with REGEX so there might be something there I am missing. I understand that I probably need to do some reading on that. But I would really like to get this working in the generic form. Can I replace the ‘REGEX((.*))’ in the request to send the string (‘garagedoorstatus’) that I need? I tried this with no luck that I can see. I might try pulling out Wireshark to help see what is actually going out of OpenHab.

That Regex just passes through what is passed to it unchanged. To change the text that is sent change the rule and leave the item alone.

Suggest you use tcpdump instead – much easier than dragging out a laptop to run wireshark and setting up a sniff port. Drag file into wireshark for analysis, of course!

Issue with tcpdump example

This makes total sense now! However I still don’t get the performance as I expect. Using Wireshark I see the connection is initiated but “garagedoorstatus” is never sent. The TCP transaction is there though so I know I’m close.

Thanks for the advice! TCPdump would probably be a better way to go. I was just redirecting the TCP request to my PC I am working on and setup a simple TCP server in Python. That way I could Wireshark the traffic coming to me.

I finally got this to work for the most part. However it was only after using sendCommand in the rules file.

Here is what my rules file looks like:

rule “Request update”
when
Time cron “5 * * ? * *”
then
//Request.postUpdate( “garage_door_status”)
sendCommand( Request, “garage_door_status” )
end

Here is what my items file looks like:

String Request "Garage Door Status: [%s]" (Garage, Window){ tcp=">[192.168.3.202:5017:'REGEX((.*))'],<[192.168.3.202:5017:'REGEX((.*))']"}

Thanks for closing the loop!

So now that I have one device working, I tried to add another. Both devices are on the same ip address so I immediately ran into an issue. When I added the second device (temperature) the strings are now filled with the same data. When OpenHAB queries the garage door, “closed” is inserted in the string for Garage Door Status and Temperature. When OpenHAB queries temp the Garage Door Status and Temperature are filled with temperature.

Items:

String Garage_Request “Garage Door Status [%s]” (Garage, Window){ tcp=“>[192.168.3.202:5017:‘REGEX((.))'],<[192.168.3.202:5017:'REGEX((.))’]” }
String Temp_Request “Temperature [%s]” (Garage, Window){ tcp=“>[192.168.3.202:5017:‘REGEX((.))'],<[192.168.3.202:5017:'REGEX((.))’]” }

Rules:

rule “Garage_Request update”
when
Time cron “5 * * ? * *”
then
sendCommand(Garage_Request, “garage_door_status” )
sendCommand(Temperature_Main_House, “get_house_temp” )

end

Any ideas?

Another side question: I tried reversing the process so my device sends statuses to OpenHAB instead of OpenHAB querying. However the default port is set to 25001 and when I try to connect to this port I get connection refused. Thoughts on that?

The bindings are identical so there is no way for OH to distinguish between the two. You can add some additional information and update your REGEX so each only grabs the relevant data. For example if your device returns “garage OPEN” or “temp 23” you would change your REGEX for GarageRequest to REGEX(garage (.*)) and Temp_Request to REGEX(temp (.*)).

What default port? Ideas I have are:

  • did you add that port to the OH start script like the wiki says so OH binds to that port for listening for incoming data?
  • did you create an Item with an incoming binding on that port?
  • check your firewall to make sure the port isn’t being blocked
  • have you considered using OH’s REST API to send updates using HTTP GET/POST commands?
  • have you considered using MQTT?
1 Like

Thanks again for the help Rich! To follow up, here is what I’ve done:

  1. I’ve moved to using JSON tranformations for handling the data. I continued to have trouble with REGEX and I found JSON much easier to use. This link pretty much summed up everything I needed to know: https://github.com/openhab/openhab/wiki/JSON-Transformations
    I really like JSON because it doesn’t seem to matter what order my strings are in, so it seems much less sensitives to mistakes that I make all over the place.

  2. As far as the connection refused issue, that problem was between the monitor and the chair. I hadn’t removed the commented line in the configurations to allow for incoming messages. :pensive: