November 21Nov 21 I can successfully subscribe to all events on my EISY but that is not optimal since I have 100+ nodes.I receive a huge dump (212 kB) of the status of every node when I first connect. I am using a SOAPAction subscribe query to X_Insteon_Lighting_Service like so:POST /services HTTP/1.1 Host: 192.168.0.212 Content-Type: text/xml; charset=utf-8 Authorization: Basic MyPassword== Content-Length: 192 SOAPAction: "urn:udi-com:service:X_Insteon_Lighting_Service:1#Subscribe" <s:Envelope><s:Body><u:Subscribe xmlns:u="urn:udi-com:service:X_Insteon_Lighting_Service:1"><reportURL>REUSE_SOCKET</reportURL><duration>infinite</duration></u:Subscribe></s:Body></s:Envelope> Is there some other EISY service name I can use to receive events from only one node? Is there some parameter I can pass to X_Insteon_Lighting_Service that limits events to a single node (like 3C 80 F 1)Note: I am not talking abou PolyGlot/Portal subscriptions. I intend to subscribe to and parse EISY event text on some local hardware running on the same LAN as the EISY.
November 21Nov 21 In addition to the soap api there is the rest API.There you'll find:/rest/query/<node>queries the given nodeReturns: Success or Error statusEDIT: Scroll way down and there is a websockets section. Pretty sure you'd have to take all events as they came and filter on the handful you want, but you'd get just the updates coming from the ISY and opposed to getting all devices every time. Old school, I know but pre polyglot nodeservers like NODELINK made use of it and it can work well Edited November 21Nov 21 by paulbates
November 21Nov 21 Author 26 minutes ago, paulbates said:In addition to the soap api there is the rest API.There you'll find:/rest/query/<node>queries the given nodeReturns: Success or Error statusYes, my current Arduino software uses /rest/query/<node> but due to system loading issues, this isn't working reliably for me. Is the SOAP API documented somewhere? I tried doing a WSDL import query to get some basic documentation but was not successful. AI searches on Google indicate that the UD SOAP documentation is not up to date.I could not get a REST subscribe/WebSockets session to work. I reverse engineered UD Mobile and see that it is using SOAP to read/update its device screen in real-time. That method works OK for me, but it will be difficult to read the huge stream of data in an Arduino program. I am looking in to using streams and filtering out the node data I don't need.
November 21Nov 21 2 hours ago, skydvrz said:Yes, my current Arduino software uses /rest/query/<node> but due to system loading issues, this isn't working reliably for me.Is the SOAP API documented somewhere? I tried doing a WSDL import query to get some basic documentation but was not successful. AI searches on Google indicate that the UD SOAP documentation is not up to date.I could not get a REST subscribe/WebSockets session to work.I reverse engineered UD Mobile and see that it is using SOAP to read/update its device screen in real-time. That method works OK for me, but it will be difficult to read the huge stream of data in an Arduino program. I am looking in to using streams and filtering out the node data I don't need.rest/query queries the device, this is more resource intensive than a retained status lookup. Use /rest/status/address or rest/node/address instead.If you can subscribe then you just need to parse the events. Basically any <control> which does not start with "_" is a Device Property Status Event where the control is the Property ID.//<?xml version="1.0" encoding="UTF-8"?> //<Event seqnum=\"113\" sid=\"uuid:90\"> // <control>ST</control> // <action uom=\"2\" prec=\"0\">1</action> // <node>n003_po_pushover</node> // <eventInfo> // </eventInfo> // <fmtAct>True</fmtAct> // <fmtName>Last Status</fmtName> //</Event>
Wednesday at 09:44 PM2 days Author I have been running my Arduino/Insteon Thermostat code for several days now. The EISY SOAP-subscription code works great! It is way more reliable than my old polling code and seems to be less EISY-cpu intense. Subscription events are very fast.Dozens of Events are sent to my Arduino hardware on initial subscription, but then drop to a reasonable frequency. I filter out any events that do not belong to the Thermostat Node ID I am listening for. I wrote a simple XML parser that grabs the parameters out of the event stream. The reset of the code forms up an Infrared data stream that gets beamed to my AC unit.I can think of many alternate uses for the subscription paradigm so if anyone is interested, I'd be happy to publish my full code. Here is some partial code: // Send the SOAP/Subscribe query (This is part of Setup()) MyLogger(TLogDestinations(ESerial + ETCPIP), EStatus, "Subscribing to EISY"); client.println("POST /services HTTP/1.1"); client.printf("Host: %s\r\n", ISYAddress); client.println("Content-Type: text/xml; charset=utf-8"); client.printf("Authorization: Basic %s\r\n", ISYBasicAuth); client.println("Content-Length: 192"); client.println("SOAPAction: \"urn:udi-com:service:X_Insteon_Lighting_Service:1#Subscribe\"\r\n"); client.println("<s:Envelope><s:Body><u:Subscribe xmlns:u=\"urn:udi-com:service:X_Insteon_Lighting_Service:1\"><reportURL>REUSE_SOCKET</reportURL><duration>infinite</duration></u:Subscribe></s:Body></s:Envelope>\r\n"); String ExtractString(String InString, String BeginMarker, String EndMarker) { int ValueBegin; int ValueEnd; ValueBegin = InString.indexOf(BeginMarker); // try to find the BeginMarker if (ValueBegin >= 0) { ValueBegin += BeginMarker.length(); // move past the marker ValueEnd = InString.indexOf(EndMarker, ValueBegin); // try to find the EndMarker if (ValueEnd >= 0) return InString.substring(ValueBegin, ValueEnd); // Get the string found between the two markers else return ""; // no end marker } else return ""; // no begin marker } // In subscribe mode, each EISY XML line contains a single variable name and value // Something like this: // <?xml version="1.0" encoding="UTF-8"?><Event seqnum="952" sid="uuid:89" timestamp="2025-12-01T13:04:04.212685-05:00"><control>CLISPH</control><action uom="101" prec="0">148</action><node>3C 50 F 1</node><eventInfo></eventInfo><fmtAct>74.0°</fmtAct><fmtName>Heat Setpoint</fmtName></Event>POST reuse HTTP/1.1 void Process() { char NodeBuff[15]; String CurrVal; float fCurrVal; int TempVal; String NodeID = ExtractString(LineBuff, "<node>", "</node>"); // We are looking for the ""hh hh hh 1" node id for an Insteon 2441TH thermostat // Is this the droid we are looking for? if (NodeID.equals(THERMID)) { // Yes: Now get the thermostat varname String Control = ExtractString(LineBuff, "<control>", "</control>"); Control.toCharArray(NodeBuff, sizeof(NodeBuff)); // Now get the var value CurrVal = ExtractString(LineBuff, "<fmtAct>", "</fmtAct>"); CurrVal.toCharArray(NodeBuff, sizeof(NodeBuff) - 1); MyLogger(TLogDestinations(ESerial + ETCPIP), EStatus, "Node Traffic: %s = %s", Control.c_str(), CurrVal.c_str()); // now do something with the Control = CurrVal string pairs . . . . } } void loop() { int bytesRead; // Note: This loops every time we hear an EISY event line of http header/XML. This happens even if the event is not intended for us. while (true) { bytesRead = client.readBytesUntil('\n', LineBuff, sizeof(LineBuff) - 1); // read single line from EISY Subscription stream LineBuff[bytesRead] = '\0'; // overwrite the \n with a string termination Process(); // parse the XML payload, if any. Some lines are blank, contain HTTP Headers or are not intended for us if ((CurrMode != tmAuto) && (ModeChanged && SetpointTempChanged)) { SendIR(); ModeChanged = false; SetpointTempChanged = false; } } }
Create an account or sign in to comment