Websockets Interface Advice

I have a garage on my property with bi-fold carriage house doors. I made a door opener/closer that uses linear actuators controlled by an Arduino Mega.

I want to add a WiFi interface (via ESP8266) to allow the controller to send door status to HE, and receive commands from HE.

I think Websockets is the appropriate technology for this. I know I could use MQTT or the Maker API REST interface, or some Zigbee/ZWave contact sensors and a Shelly 1 relay, but I think Websockets is the appropriate technology for my situation.

I know how to implement a websockets server on the ESP8266, but I’m struggling with the Websockets interface to HE.

I read the HE Documentation Websocket Interface page, and I know I need to implement parse and webSocketStatus methods in a driver.

Is there an example Websockets HE driver I can look at to help me get started? Is there other documentation I should be looking at?

Thanks

Here is a Wemo driver @jason0x43 created. Wemo devices are WiFi based, so this should get you started.

1 Like

I have written several Hubitat integrations based on websockets.

What is it that you're struggling with? I can point to some code that may help.

1 Like

Thanks!
This will give me something to chew on for a while!

Just FYI, that source code appears to be a Zigbee driver, not websockets. @wayne.pirtle

@dbarck2000, if you can give some more info about what you're having trouble with I will gladly offer some specific suggestions or examples.

1 Like

Aw :poop:! Thanks Tom. I was thumbing out my post on my phone, and grabbed the wrong link. This one should be correct.

Thanks to @jason0x43 for all the work he has put into expanding the community driver base.

1 Like

That's definitely a LAN driver, but it still isn't websocket based. Still, good stuff, and thanks for sharing. :slight_smile:

1 Like

I can give an example from one of my drivers (an update to my SamsungTvRemote is is over 1000 lines and has a lot of different ws commands. I have simplified below:

/*	===== HUBITAT INTEGRATION VERSION =====================================================
====*/
def driverVer() { return "3.1.2" }
import groovy.json.JsonOutput

metadata {
	definition (name: "Websocket Example",
				namespace: "davegut",
				author: "David Gutheinz",
				importUrl: ""
			   ){
		capability "Switch"
	}
	preferences {
		input ("deviceIp", "text", title: "device Ip", defaultValue: "")
	}
}

//	===== Installation, setup and update =====
def installed() {
}

def updated() {
}

def on() {
	//	This is where you define the message to actually send.
	sendMessage("on")
}
def off() {
	sendMessage("off")
}

def sendCommand(command) {
	//	Check if socket is open.  If not, connect
	if (device.currentValue("wsStatus") != "open") {
		connect(funct)
		pauseExecution(300)
	}
	//	Wait then sent the command
	interfaces.webSocket.sendMessage(command)
	//	I usually close.  This will reschedule if another message is
	//	sent prior to the 30 seconds.
	runIn(30, close)
}

def connect() {
	//	Below are examples of the path and parameters for a command.  This will be SPECIFIC
	//	to you device.  Format is ip:port plus the path defined.  It may also contain other
	//	data (in the below: NAME and TOKEN)
	//	example for a not secure interface (http)
	def url = "ws://${deviceIp}:8001/api/v2/channels/samsung.remote.control?name=test"
	interfaces.webSocket.connect(url)
	//	for a secure interface (https)
	def url = "wss://${deviceIp}:8002/api/v2/channels/samsung.remote.control?name=${name}&token=tokenHere"
	interfaces.webSocket.connect(url, ignoreSSLIssues: true)
}

def close() {
	logDebug("close")
	interfaces.webSocket.close()
}

def webSocketStatus(message) {
	//	A good behaving sokey will send a response.  From that you
	//	will parse the status as open, closed, etc.
	def status
	if (message == "status: open") {
		status = "open"
	} else if (message == "status: closing") {
		status = "closed"
	} else if (message.substring(0,7) == "failure") {
		status = "closed-failure"
		//	if a failure is detected, close the interface
		close()
	}
	sendEvent(name: "wsStatus", value: status)
}

def parse(resp) {
	//	Will be specific to your device.  Here, the response is parsed json
	//	and from that I can get the event then switch for various state updates.
	//	I use try to isolate any error.
	def logData = [:]
	try {
		resp = parseJson(resp)
		def event = resp.event
		logData << [EVENT: event]
		switch(event) {
			case "ms.channel.connect":
				def newToken = resp.data.token
				if (newToken != null && newToken != state.token) {
					state.token = newToken
					logData << [TOKEN: "updated"]
				} else {
					logData << [TOKEN: "noChange"]
				}
				break
			case "ms.error":
				logData << [STATUS: "Error, Closing WS",DATA: resp.data]
				close()
				break
			case "ms.channel.ready":
			case "ms.channel.clientConnect":
			case "ms.channel.clientDisconnect":
				break
			default:
				logData << [STATUS: "Not Parsed", DATA: resp.data]
				break
		}
		logDebug("parse: ${logData}")
	} catch (e) {
		logData << [STATUS: "unhandled", ERROR: e]
		logWarn("parse: ${logData}")
	}
}
2 Likes

Thanks djgutheinz!

You could use @ogiewon’s HubDuino garage door sketch and drivers:

1 Like

Thanks for the Hubduino recommendation. I think I'll give it a try.

Do you know how Hubduino handles the communication over WiFi? What protocol?

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.