Receiving notifications from LAN devices

This seemed like it could use a dedicated topicā€¦

From what I understand, devices on Hubitat should be able to receive notifications from LAN devices, as long as the Hubitat device is using the same deviceNetworkId as the real LAN device.

In STā€™s Building the device type docs, they suggest doing the following to subscribe to device events (for devices that support SUBSCRIBE commands):

    new physicalgraph.device.HubAction(
        method: "SUBSCRIBE",
        path: path,
        headers: [
            HOST: ip,
            // ST docs have the /notify path, but aren't clear on where it comes from. I've
            // tried with and without.
            CALLBACK: "<http://${address}/notify$callbackPath>",
            NT: "upnp:event",
            TIMEOUT: "Second-28800"
        ]
    )

The host address is the address of the LAN device and the callback address is the address of the hub, which we can get with something like

def getHostAddress() {
 	def ip = getDataValue('ip')
 	def port = getDataValue('port')
 	"${convertHexToIP(ip)}:${convertHexToInt(port)}"
}

On my hub, the function above gives me a host address like ā€œ10.0.1.99:39501ā€, which looks reasonable enough.

It seems straightforward enough, but Iā€™ve noticed a couple of problems (or at least, some things arenā€™t working as I expect). For one, the above ā€˜SUBSCRIBEā€™ HubAction doesnā€™t seem to work. When I issue it (Iā€™m working with a WeMo switch), I never see a response from the device. However, the following HubAction does work (in that my deviceā€™s parse method gets a response with a subscription ID after this action is issued):

	new hubitat.device.HubAction("""SUBSCRIBE /upnp/event/basicevent1 HTTP/1.1
HOST: ${ip}
CALLBACK: <http://${callback}>
NT: upnp:event
TIMEOUT: Second-300

""", hubitat.device.Protocol.LAN)

The other issue is that my deviceā€™s parse method is never called with any event notifications. I know that the subscription is working. For one, I get a subscription ID back from the LAN device. I also tried setting up a simple server on my MacBook and used that address:port as the callback address when I created the device subscription; that server then received notifications from the LAN device.

My Hubitat device does receive request responses from the LAN device. For example, after issuing the ā€˜SUBSCRIBEā€™ command above, my deviceā€™s parse method is called with with a response containing the subscription ID. Similarly, parse is called with responses after I issue device control commands.

The deviceNetworkId property of the Hubitat device is set to the MAC address of the LAN device (WeMo switch), where the address is a hex string in all caps with no colons. This address matches the MAC address I see in the responses I receive from the LAN device, so it seems to be correct.

Is there anything else I need to configure to be able to receive LAN notifications?

This is my driver: hubitat/jason0x43-wemo_switch.groovy at master Ā· jason0x43/hubitat Ā· GitHub

Currently my smart app subscribes to the specific SSDP events that announce Belkin devices. I also tried making an unfiltered subscription to location events in the smart app (subscribe(location, null, [filterEvents: false])). My smart app then received SSDP messages for other devices in my house (Harmony hub, others) along with the Belkin messages, but still didnā€™t receive the state notification messages from the switch.

Any luck with this? Iā€™ve rewritten the Wemo Light Switch Driver and am in the same boat.

It works, but if you manually trigger the light it doesnā€™t notify hubitat. I think it has something to do with the callback. Just not sure what itā€™s suppose to be.

I was told by one of the devs that the ability to receive NOTIFY messages (which is whatā€™s currently broken for our WeMo drivers) should be available in the next release.

NICEā€¦ well that was a waste of an evening.

Good news is that as soon as its fixed I have the Wemo Light Switch ready to go. Cleaned up the code. Ripped out all the useless stuff and hopefully its just them fixing that and we are good to go.

Hah, I know the feeling. I spent a good chunk of a weekend tearing my hair out trying to figure out why Hubitat couldn't receive notifications.

Do you know if this was ever implemented? I have an app that is suffering from the same thing.

Yes, in v1.0.6. My WeMo driver has been working properly since then.

any suggestions on how to troubleshoot my issue then?

If you're willing to help here is my thread on what's going on

I am getting something in the logs, but it's not what I am sending. (I am trying to port this app from smartThings and it's the last piece I need)

Here is what I see:

parsedEvent = [mac:001788227989, networkAddress:0A000102, deviceAddress:50, ssdpPath:/description.xml, ssdpUSN:uuid:2f402f80-da50-11e1-9b23-001788227989, ssdpTerm:urn:schemas-upnp-org:device:basic:1, ssdpNTS:null]

Is there anyway for me to tell what is sending this?

Here is the code that sends the message:

It never reaches HE. I never see it in the log

                if (device.id && device.name && device.type) {
                        try {
                            var data = {
                                module: module,
                                id: device.id,
                                name: device.name,
                                type: device.type,
                                event: event.name,
                                value: event.data.value
                            };
                            for (attr in device) {
                                if (attr.substr(0, 5) == 'data-') {
                                    data[attr] = device[attr];
                                }
                            }
                            log({
                                info: 'Sending event to SmartThings: ' + (event.data.description || '')
                            });
                            node.request.put({
                                    url: 'http://' + config.server.ip + ':' + config.server.port + '/event',
                                    headers: {
                                        'Content-Type': 'application/json'
                                    },
                                    json: true,
                                    body: {
                                        event: 'event',
                                        data: data
                                    }
                                },
                                function (err, response, body) {
                                    if (err) {
                                        log({
                                            error: 'Failed sending event: ' + err
                                        });
                                    }
                                });
                            log({
                                info: 'Event should have been sent by now'
                            });

                        } catch (e) {
                            log({
                                error: 'Error parsing event data: ' + e
                            });
                        }
                    }
                }
            }
        } catch (e) {
            error('Failed to send event to SmartThings: ' + e);
        }
    },

Turns out this is my Hue bridge.

I've never tried sending messages directly to the HE, so I'm not 100% sure what's required. I believe the MAC address of the sending device has to match up with the device network ID of the device in HE; is that the case in your setup?

Yes, if a driver has a dni which is the source device Mac or ip in hex, sans separators, and said device directs it's output to the hub ip address on port 39501 then any data the device sends will be forwarded to the drivers parse method.

I have a nodejs module that connects to AT&T digital life and sends a discovery data to my HE App to create the Devices if they are not already in HE. I monitor the log and that initial call never shows up. If I use curl to pass a similar command I receive a 200 return, but still nothing in the logs of HE.

This is an app I am porting over from SmartThings, and it works fine over there. I have the HE app working, it's just the communication between nodejs and HE that isn't working.

im not sure how this was supposed to work previously, but why not modify the node js app to have it send it's output directly to an he driver, this has less system overhead than subscribing to location events.

Wouldn't I still need an app to create the devices in HE as they are discovered in ATTDL?

yes, but the driver that receives and parses the messages can create child devices directly (component devices), or more logically, send these requests to the parent app to create child devices.

This doesn't sound like a device notification issue. I mean, it sounds like there should just be an app running on HE with an open endpoint that the node app can communicate with.

yup, can be done that way as well.

I was thinking about rewriting the app to do that, but I'd like to understand why this works in smartThings but not in HE. I have the app part of it working, I just never see anything from nodejs. nodejs does send the notification.