UDP Listener

I’m trying to setup a switch which will listen to syslog data and change if the message contains a string.

My items file has the following:
Switch m_iPhone “Murray” (gUsers) {udp="<[ON:172.16.0.20:514:‘REGEX((‘STA ac:3c:0b:0b:72:b1 IEEE 802.11: associated’))’,<[OFF:172.16.0.20:514:‘REGEX((‘STA ac:3c:0b:0b:72:b1 IEEE 802.11: disassociated’))’"}

Currently the log says that the item could not be parsed correctly. The desired outcome is to have openhab listen on UDP port 514 and when it receives the following messages, turn the switch on or off:

ON - STA ac:3c:0b:0b:72:b1 IEEE 802.11: associated
OFF - STA ac:3c:0b:0b:72:b1 IEEE 802.11: disassociated

Is anyone able to assist with pointing out where I’ve gone wrong?

Cheers,
Murray.

If the TCP/UDP Binding page example is anything to go by, it looks like they don’t use quotes around the REGEX Parameter value. It also looks like you’re missing the “]” character(s) for each.

Thanks Mark,

Apologies, I did read the article but must have missed that simple syntax error.

Openhab is now parsing the rules fine and receives the messages ok however I think there is a problem with the Regex string. The log shows the following error however this should match the on command:

2015-08-24 11:04:45.943 [WARN ] [t.protocol.internal.UDPBinding] - Can not parse input <30>Aug 24 11:05:43 (BZ2,0418d690a32b,v3.2.12.2920) hostapd: ath0: STA ac:3c:0b:0b:72:b1 IEEE 802.11: associated to match command ON on item userMurray

The switch is configured as:

Switch userMurray "Murray" (gUsers) {udp="<[ON:172.16.0.50:*:REGEX((STA ac:3c:0b:0b:72:b1 IEEE 802.11: associated))],<[OFF:172.16.0.50:*:REGEX((STA ac:3c:0b:0b:72:b1 IEEE 802.11: disassociated))]"}

I’ve tested the regex string with regexr.com and it matches it ok. Anything else I’m missing?

Looks like there are two issues:

  1. One too many sets of single quotes were trimmed out.
    The ones prior to the Transform name, and after the )), are still needed.

  2. Your pattern isn’t complete.
    The REGEX Transform has an implied ^ at the beginning, and $ at the end. These are beginning-of-line and end-of-line respectively. The capture/pattern you’ve specified is only partial, so you need a .* at the beginning and end to match anything.

I wrote a small test Java program to validate the issue for item (2), given the internals/implementation of RegExTransformationService, but haven’t validated item (1)

Overall, it’ll end up something like:

Switch userMurray "Murray" (gUsers) {udp="<[ON:172.16.0.50:*:'REGEX(.*(STA ac:3c:0b:0b:72:b1 IEEE 802.11: associated).*)'],<[OFF:172.16.0.50:*:'REGEX(.*(STA ac:3c:0b:0b:72:b1 IEEE 802.11: disassociated).*)']"}

It’s possible that your IP/Port spec of 172.16.0.20:* may need to be explicitly specified as 172.16.0.20:514 (per your original example) - but it seems to get input in your example, so not sure how that works :wink:

If this works correctly, do you mind updating the TCP/UDP Binding page with your more worked example? I think it’ll help others.

Absolutely, happy to help by updating the documentation.

I found the * in the port was required as the access point would be sending the messages on higher ports such as 49xxx and would vary. Having the 514 defined here seemed to mean the syslog message was discarded straight away.

Thanks for the info. Handy to know there is the implied ^ and $. Now I have this information I’ll have a further play around and update some doc’s once I have some working configs.

Cool. Try out the one I posted above. I edited it after the forum-email was sent out, so it’ll be slightly different than what you got in email. It has the prefix/suffix .* now and should be complete.

@mscottco,
Did you get it working?

Hey, unfortunately I wasn’t able to get it working so didn’t touch the documentation.

I’ve been a bit short on time but my plan is to setup the bluetooth presence detection instead.

Hi,
I just thought I would share my experiences with this. I spent hours trying to do exactly this, before realising that it isn’t possible with the UDP binding, or more specifically the regex transform in it.

My solution was still to use syslog but log to the servers syslog and have a constantly running script to tail the syslog log and then have the notifications pushed from there. My script looks like this:

tail -fn0 /var/log/syslog/192.168.185.50_messages.log | \
while read line ; do
    echo "$line" | grep '.*type=association .*10.2F.6B.BE.91.1C.*'
    if [ $? = 0 ]
    then
          mosquitto_pub -t "/gfc/presence/james" -m "connected"

    fi

    echo "$line" | grep '.*type=disassociation .*10.2F.6B.BE.91.1C.*'
    if [ $? = 0 ]
    then
          mosquitto_pub -t "/gfc/presence/james" -m "disconnected"

    fi

            done

    echo "$line" | grep '.*type=association .*E0.66.78.C7.08.87.*'
    if [ $? = 0 ]
    then
          mosquitto_pub -t "/gfc/presence/laura" -m "connected"

    fi

    echo "$line" | grep '.*type=disassociation .*E0.66.78.C7.08.87.*'
    if [ $? = 0 ]
    then
          mosquitto_pub -t "/gfc/presence/laura" -m "disconnected"

    fi

            done

Not all that pretty, but it achieves what I need and has proven to be reliable so far.

Hope this helps anyone searching for this in the future!