Full local solution for insteon integration?

local

no

and sorry but that was actually meant for @cwwilson08

Thanks for clarification. Could you please confirm physical changes (on/off from physical buttons on switches/dimmers, motion sensor) from insteon devices got updated to insteon server and then HE promptly? I never had any problem from ST -> Insteon devices, but the other path, from insteon devices to ST, is PITA.

If it was OTG port, no, you don't need to crack it open at all. Just need correct cabling outside, they could sell the cable :laughing:

yes it is very prompt.. I only have one device (bought a insteon hub and dimmer for 40 bucks) however @SmartHomePrimer has several and has been testing for a little awhile now. All seems pretty solid.

2 Likes

Great to hear that! Could I assign up for beta testing?

sure you can play - take a look at my github where the insteon direct dimmer driver is.

everything is there for the hubitat side lol except instructions.

in fact there are no instructions for anything. if you can figure out how to get it running feel free.

Start with the insteon node server i linked to above - once you have it setup install the hubitat drivers.

The PLM is available via the hub, but it’s limited. PLM isn’t a strict description of the USB or Serial devices.

Here’s info about Home Controller which is what the Insteon-Server application uses.

Thanks @cwwilson08. If I understood the setup correctly, there are two methods:

  1. direct method, basically, send HTTP request to insteon Hub directly.
  2. insteon server method. Basically, HE talks to insteon server, insteon server talks to Insteon hub, right? I dig more, if I am not mistaken, insteon server relies on "home-controller" library. And the library supports different models of HUB as well as PLMs, and for hub 2245, it does the same thing, send buffstatus.xml to insteon hub.

Basically, two methods use the same way to communicate with insteon hub..

There is the problem: if you had a few devices, it might works fine. However, you have more devices and a few scenes programmed, Insteon's API and implementation are very problematic:

  • The buffer has fixed size of 200 bytes shared with both commands and responses.
  • buffer is not auto cleared after each request, manually cleaning up buffer is required.
  • clearing buffer command will clear everything in the buffer including packets or even partial received packet that yet to be sent.

So if a command involves multiple devices, the aggregate responses could easily exceed 200 bytes buffers, and cause an overrun problem. I know two solutions:

  1. keep reading buffer without clearing it, and hopefully, filter out duplicated messages from multiple reads
  2. read the buffer, immediately clear it, and hopefully, no new message received in between.

First option might be better, as it won't lose anything, Not so, what makes thing even worse is that, the processor inside 2245 is under powered, HTTP response is slow when there were activities on its internal PLM, and the response may contains corrupted messages that caused by either a) PLM has higher priority, so there were buffer overrun occurred before sending back to HTTP, b) PLM doesn't have higher priority, while serving HTTP, part of PLM message gets lost.

To summarize, Using Hub 2245's local control is very unreliable even if you don't have too many devices. And it's why I want creating a new insteon bridge using PLM. (USB/serial port) not hub2245.

so you are partially right. the insteon server does have the ability to send commands to the insteon hub.

the driver i am using does not send commands to the insteon server - it sends commands via get to the insteon hub directly.

i am going to agree to disagree with you in that the insteon server is not always polling for status as you suggest. only if you send that command i believe.

there is an eventlistener setup on the insteon server that receives data broadcast from the from the insteon hub without polling - again this is the voodoo i do not understand.

sorry but seems i cant explain it any clearer.

The Insteon Hub uses SSE for remote status updating. This is probably the voodoo you are speaking of?

Understood, that's the method 1 I mentioned above (direct method)

Here is snap code from "home-controller" library for hub 2245 used by insteon server, it seems to me that code is for scheduled for polling (fetchBuf()).

  function delayFetch() {
    if (!running) {
      return;
    }
    if (!inRequest) {
      fetchBuf();
    }
    if (currentDelay < maxDelay) {
      currentDelay += 100;
    }
    setTimeout(delayFetch, currentDelay);
  }

Lol I thought I gave up a long time ago...

You could be right. This Is not the solution for you. My apologies.

1 Like

Thanks for your suggestions and help, @cwwilson08

Yes it can, I actually worked on an insteon integration last year, it was a real pain since the messages do not have an end delimiter and they are of differing lengths. We ended up not using it since our understanding is that not all insteon hubs support that raw socket, it was closed on the newer ones and the older ones could no longer be purchased.

docs are here: https://docs.hubitat.com/index.php?title=Raw_Socket_Interface

I have gotten some reports of slow down issues with this interface, I have not been able to reproduce them so feedback is welcome.

Chuck, compared to using a standard TCP message, is there additional overhead in the system involved with Raw sockets?

Also, can I use raw TCP sockets to send a global message and capture message from all responding devices? This would solve a issue I have in the TP-Link integration in discovering devices.

Dave Gutheinz

Are there any examples of the Raw Sockets code?

I've been unable to get sendMessage to be happy with the input I am providing.

This works for me during my testing. I get a proper return. Remember, the return is raw, not a parseLanMessage

//	=====	TCP TEST CODE	===================================================
private sendTcpCmd(command) {
	def message = tcpEncrypt(command)			//	See note in method tcpEncrypt
	interfaces.rawSocket.connect(deviceIP, 9999, 
								 byteInterface: true,
								 readDelay: 150)
	interfaces.rawSocket.sendMessage(message)
	runIn(5, closeSocket)
}
def parse(response) {
	log.warn "TCP Response is ${response}"
	def encrResponse = parseLanMessage(response)
	def cmdResponse = parseJson(inputXOR(encrResponse))
	log.warn "TCP Return message is ${cmdResponse}"
}
def closeSocket() {
	interfaces.rawSocket.close()
}
def socketStatus(response) {
	log.warn "TCP Socket is closed"
}
//	===========================================================================

Thanks. I'm pretty close to the same thing, but have not been able to get my message in the right format.

Are you able to share more of the "tcpEncrypt" method?

Code is below; however it is particular to the TP-Link devices. What it does is convert the ASCII (JSON) command to HEX and then complete an XOR conversion. Makes it hard to read, but not secure.

//	Utility Methods
private tcpEncrypt(command) {
	def str = ""
	def encrCmd = "000000" + Integer.toHexString(command.length())
 	def key = 0xAB
	for (int i = 0; i < command.length(); i++) {
		str = (command.charAt(i) as byte) ^ key
		key = str
		encrCmd += Integer.toHexString(str)
	}
	return encrCmd
}
private udpEncrypt(command) {
	def str = ""
	def encrCmd = ""
 	def key = 0xAB
	for (int i = 0; i < command.length(); i++) {
		str = (command.charAt(i) as byte) ^ key
		key = str
		encrCmd += Integer.toHexString(str)
	}
   	return encrCmd
}
private inputXOR(encrResponse) {
	String[] strBytes = encrResponse.split("(?<=\\G.{2})")
	def cmdResponse = ""
	def key = 0xAB
	def nextKey
	byte[] XORtemp
	for(int i = 0; i < strBytes.length; i++) {
		nextKey = (byte)Integer.parseInt(strBytes[i], 16)	// could be negative
		XORtemp = nextKey ^ key
		key = nextKey
		cmdResponse += new String(XORtemp)
	}
	return cmdResponse
}

It sounds like you are asking if you can send a broadcast message and then listen for the response. That is not possible with this interface. The raw socket interface is just like telnet in that it opens a connection to a specific device and starts up a listener for any responses, it maintains that connection so it is not a single message and response mechanism, you should use HubAction for that still.