Websocket Client

Thank you for the JS Code. I already have a fully functioning JS client.

What I need is how to receive a socket message in a Hubitat groovy client module (driver) using "import hubitat.helper.InterfaceUtils", connection and sending are working.

You should be able to see any data coming back I the parse method?

Edit. Nm. I see that's not what you need.

Prior to posting I looked at the groovy code from both SmartThings and Hubitat. The Hubitat side does not appear to use "import hubitat.helper.InterfaceUtils", and I'm uncertain on how to use the code I did find for receiving messages.

Ok, I misunderstood.

So, you are looking to have a socket open on your Hubitat where you can connect to from an external application and send commands to your hubitat?

I don't think that is supported. Hubitat only supports connecting to a websocket application. Not being a server.

EDIT: However, a websocket is usually two way. So you should be able to post something to your websocket connection on the PHP end

I have some debugging logic in the parse method, but get nothing in the logs. What I want is to receive random unsolicited messages.

I also contacted support for "hubitat.helper.InterfaceUtils" documentation, I was advised to post questions on the forum.

Using Hubitat’s webSockets implementation, all replies are simply handled in the parse() routine. At least that’s how my Logitech Harmony Hub Driver works. It handles unsolicited messages.

Correct. I'm able to use the Maker API app, but was hoping to bypass it once the socket was connected.

WebSockets by definition are bi-directional. My Javascript client can receive and send messages. I want the Groovy client device to do the same. The websocket server runs on my local WAMP server.

That is how Hubitat’s webSocket implementation is designed. Works for my driver.

You are absolutely correct, had a brain lock here. Something like this here should work:

import hubitat.helper.InterfaceUtils

def connect()
{
	InterfaceUtils.webSocketConnect(device, "ws://192.168.10.207/eventsocket")
}

def webSocketStatus(String socketStatus)
{
	if (socketStatus.startsWith("status: open"))
	{
		log.info "Connected"
		return
	} 
	else if (socketStatus.startsWith("status: closing"))
	{
		log.info "Closing connection"
		return
	} 
	else if (socketStatus.startsWith("failure:"))
	{
		log.warn "Connection has failed with error [${socketStatus}]."
	} 
	else
	{
		log.warn "Connection to has been lost due to an unknown error"	
	}
}

def parse(String description)
{
	log.debug "Got Data ${description}"
}

The parse method gets called as long as the server posts on the channel. I am not sure if that has to be done in a driver though. Not sure that the parse message would get called in an app. Never tried it.....

1 Like

I believe it only works in a driver, but I’m not 100% sure about that.

It is a driver.

I followed @ogiewon's example, but nothing seems to happen in the parse method when a message is sent by my websocket server, although the Javasript client sees the general broadcast message, and the Hubitat groovy webSocketStatus open triggers

//Connect the webSocket
try {
    InterfaceUtils.webSocketConnect(device, "ws://192.168.0.101:9000/cz/shmdelay/Socket.php")
	} 
catch(e) 
	{
    log.error "WebSocket connect failed initialize error: ${e.message}"
	}
}

// parse 
def parse(String description) {
log.debug "Parsing ${description}"

I know @chuck.schwer also implemented the webSocket ping/pong keep alive functionality... Does your webSocket server implement this as well?

Maybe load up @ogiewon code and see if it connects to the ws at works? Likely to produce some errors but might help to see what is going awry.

I'm not sure what happened, but it now seems to be working. Thank you to everyone for the suggestions.

[dev:123]2019-06-17 12:47:50.907 [debug]Parsing {"type":"system","message":"192.168.0.nnn connected"}

[dev:123]2019-06-17 12:47:49.866 [info]websocket is open

1 Like

No idea. What is that?

Glad you got it working. I love happy endings to these mysteries.

There is an additional method you need to define that should give you some connection information, its called webSocketStatus. I've documented it on our wiki:

https://docs.hubitat.com/index.php?title=Websocket_Interface

1 Like

Thank You.

I suspect the problem was me not updating my Hubitat driver code or forgetting to do a device "Save Preferences". I'm dealing with 4 interacting modules in three languages, Javascript, Groovy and PHP on my Wamp server, along with using Maker API, and bumping into Javascript CORS issues.

Apparently not. I'm getting what appears to be an empty message every 30 seconds that causes issues on the socketserver. What is the expected response?

I've also tried stopping the ping with this that creates an error message
InterfaceUtils.webSocketConnect(device, "ws://192.168.0.101:9000/cz/shmdelay/SocketChat.php', [pingInterval:0])

and this that does not stop it
InterfaceUtils.webSocketConnect( [pingInterval:0], device, "ws://192.168.0.101:9000/cz/shmdelay/SocketChat.php)

tag @chuck.schwer

Set it to -1 to disable

When a default map is the first parameter of a method, it means that you can add named parameters after the defined parameters, so the call would look like this:

InterfaceUtils.webSocketConnect(device, "ws://192.168.0.101:9000/cz/shmdelay/SocketChat.php', pingInterval:-1)

The expected response to a ping is a pong.

1 Like