How can I receive LAN messages on the ST hub (when the messages can come at any point)?

This is something that is possible, but I don’t believe it is documented (that I know of). I use it quite a bit in my esp8266 projects and other HTTP LAN projects. There are just a few guidelines that you need to follow:

  1. You need a device created in SmartThings to represent the Raspberry Pi. The device should have a Device Network Id (DNI) that matches the MAC address of the Raspberry Pi. It should be all uppercase and without any octet separators (000A959D6816).

  2. You need to send the data from the Raspberry Pi to the SmartThings Hub’s local ip and local server port. I haven’t seen a hub that doesn’t use port 39500 as its local server port, but you can use the following commands in your device handler to find the information dynamically: device.hub.getDataValue(“localIP”); device.hub.getDataValue(“localSrvPortTCP”).

  3. The Raspberry Pi should send its data using HTTP. The easiest method from Linux would be to use the curl binary.

Here is a simple example of a device handler that can parse messages that are sent to it in json format. You don’t have to use json, but I find it easy to parse and widely used.

import groovy.json.JsonSlurper

metadata {
	definition (name: "Simple LAN Example", namespace: "erocm123", author: "Eric Maycock") {
	capability "Sensor"
        
	}
   
	tiles (scale: 2){      
        valueTile("hubInfo", "device.hubInfo", decoration: "flat", height: 2, width: 6, inactiveLabel: false, canChangeIcon: false) {
            state "hubInfo", label:'${currentValue}'
        }
    }
	main("hubInfo")
	details(["hubInfo"])
}


def parse(description) {
    def events = []
    def descMap = parseDescriptionAsMap(description)
    def body = new String(descMap["body"].decodeBase64())
    def slurper = new JsonSlurper()
    def result = slurper.parseText(body)
    log.debug result

    if (result.containsKey("message")) {
       events << createEvent(name:"hubInfo", value:result.message)
    }
    return events
}

def parseDescriptionAsMap(description) {
	description.split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
        
        if (nameAndValue.length == 2) map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
        else map += [(nameAndValue[0].trim()):""]
	}
}

Here is an example of this in action. From the Raspberry Pi:

root@raspberrypi:~# curl -H “Content-Type: application/json” -X POST -d ‘{“message”:“This is a test”}’ http://x.x.x.x:39500
root@raspberrypi:~# curl -H “Content-Type: application/json” -X POST -d ‘{“message”:“Hi, this is Raspberry Pi”}’ http://x.x.x.x:39500
root@raspberrypi:~# curl -H “Content-Type: application/json” -X POST -d ‘{“message”:“Ping is down on PC1!”}’ http://x.x.x.x:39500

With this framework you can have the device handler create any kind of event that you would like and have any other device in the SmartThings ecosystem respond accordingly. For some more complex examples of the above technique you can reference this.

16 Likes