UDP broadcast support

Perfectly fine to talk about it, we just don't want to share the code publicly yet as it is probably not final and make sure those testing it understand that.

2 Likes

@patrick Any updates on the availability of UDP? I'd like to take a stab at making local lifx control but doing that requires listening to and broadcasting UDP.

1 Like

Yeah, I was wondering about this as well. To implement anything to control a DMX device we need UDP.

Here are some examples of sending UDP messages

For sending regular strings:

String message = "Hello"
def myHubAction = new hubitat.device.HubAction(message, 
								hubitat.device.Protocol.LAN, 
								[type: hubitat.device.HubAction.Type.LAN_TYPE_UDPCLIENT, 
		                            destinationAddress: "192.168.1.100:6628"])
sendHubCommand(myHubAction)

for sending binary messages (message back to parse will also be hex string encoded):

byte[] rawBytes = [0x71, 0x23,  0x0F, 0xA3]
String stringBytes = hubitat.helper.HexUtils.byteArrayToHexString(rawBytes)
def myHubAction = new hubitat.device.HubAction(stringBytes, 
                           hubitat.device.Protocol.LAN, 
                           [type: hubitat.device.HubAction.Type.LAN_TYPE_UDPCLIENT, 
                            destinationAddress: "192.168.1.101:7815",
                            encoding: hubitat.device.HubAction.Encoding.HEX_STRING])
sendHubCommand(myHubAction)

HexUtils is documented here:
HexUtils

4 Likes

so is there a way to listen as well?

if you are asking about the hub receiving udp broadcasts from a device. No, we do not support that. You can only send out UDP messages and receive a reply to that message.

1 Like

ok, thanks. would be nice to have in the future

I would like UDP receive too. One of the protocols I use extensively (xAP) uses it to a broadcast address.

I think that means: An App on the hub must initiate the UDP exchange. The "reply" will be seen in the parse method of that App. That might mean Lifx can be implemented locally.

1 Like

Is there support for UDP unicast as well? The reason for asking is that the LIFX LAN protocol seems to recommend that unicast is used for addressing an individual bulb - although it looks as though broadcast might work as well but causing more wifi traffic than desirable.

1 Like

The only difference between broadcast and unicast is the address you send to. The examples I posted above are unicast messages.

1 Like

Great, thanks.

Would be nice to have listen capability too, i.e. parse to be called for every received packet on a specific port

1 Like

Two items:
a. When is the UDP support going live so I can test direct command of the TP-Link devices? It would greatly simplify installation and operations.

b. Another item I may need is straight TCP support (i.e., "net.connect" in node.js) to a device. Does or will Hubitat support this?

Dave

going live??

Back in September as far as I know.

Chuck pasted some code showing the basics 9 days ago.

Thanks.

Does anyone have answer to the second question. Again, currently I use Node.js (on a pc). Each command sends a net.connect, the actual data on the socket, and a socket.close. I need to try to port this to Hubitat to eliminate the pc Hub and also the alternative Kasa Cloud connection.

Ideas?

It would be great to see a slightly more fully worked example of an App that uses UDP, including processing the response.

I'm not sure if I'm missing something, but I think I'm sending a correct GetService packet to LIFX on 255.255.255.255:56700, but I'm not seeing any responses in the parse method, it doesn't look like that method is being called at all. I'm not ruling out mistakes on my part though, obviously.

Any thoughts on how to debug this? Here's the initialize and parse methods - not really ready to share the rest of the code in public yet

def initialize() {
  state.sequence = 1
  def buffer = []
  def getServiceSequence = makePacket(buffer, 0, messageTypes().DEVICE.GET_SERVICE, false, false, [])
  def rawBytes = asByteArray(buffer)
  log.debug "raw bytes: ${rawBytes}"
  String stringBytes = hubitat.helper.HexUtils.byteArrayToHexString(rawBytes)
  log.debug "sending bytes: ${stringBytes}"
  def myHubAction = new hubitat.device.HubAction(
        stringBytes,
        hubitat.device.Protocol.LAN,
        [
                type              : hubitat.device.HubAction.Type.LAN_TYPE_UDPCLIENT,
                destinationAddress: "255.255.255.255:56700",
                encoding          : hubitat.device.HubAction.Encoding.HEX_STRING
        ]
  )
  def response = sendHubCommand(myHubAction)
  log.debug "response from sendHubCommand ${response}"
}
 
def parse(String description) {
  log.debug "parse description: ${description}"
}

For what it's worth, I'm not seeing any errors in the logs. I'm trying to monitor UDP activity on port 56700 with Wireshark but not seeing anything showing up, but then I could have misconfigured it due to a lack of familiarity.

A bit more progress...
Now that I've got a slightly better understanding of Wireshark I can see that I'm broadcasting (I think) a UDP packet, but I'm just not getting any response. If I send the packet using PacketSender then I'm getting responses from my LIFX devices! The only apparent differences (apart from the IP/MAC address of the sender) is that HE is setting the don't fragment flag in the datagram, and also setting a header checksum, the TTL is different (64 from packet sender and 128 from HE). The payload for LIFX looks to be the same apart from the sequence number

This is very puzzling.

2 Likes

My current conjecture is that the socket on the hub has been closed before the LIFX devices have responded, not sure whether Wireshark would see any messages in that case. Is there another parameter that needs specifying to ensure that the socket stays open?