Open parnic opened 4 years ago
Quick-and-dirty first shot at interpreting circuit RPMs: https://gist.github.com/parnic/998f0b1d89a0fecc25df2dd1c1916c8e
Example usage:
console.log(`pump 1 pool rpm=${config.getCircuitRPMs(0, 6)}`);
console.log(`pump 2 waterfall rpm=${config.getCircuitRPMs(1, 8)}`);
Feedback appreciated.
Quick-and-dirty first shot at interpreting circuit RPMs: https://gist.github.com/parnic/998f0b1d89a0fecc25df2dd1c1916c8e
Example usage:
console.log(`pump 1 pool rpm=${config.getCircuitRPMs(0, 6)}`); console.log(`pump 2 waterfall rpm=${config.getCircuitRPMs(1, 8)}`);
Feedback appreciated.
This seems to work for me, i tweaked the code to be:
for (var i = 0; i < this.controllerConfig.bodyArray.length; i++) {
let deviceId = this.controllerConfig.bodyArray[i].deviceId;
let circuitName = this.controllerConfig.bodyArray[i].name;
console.log('pump 1 ' + circuitName + ' rpm= ' + config.getCircuitRPMs(0, deviceId));
}
I get:
pump 1 Spa rpm= 2600
pump 1 Feat. Pump rpm= 2900
pump 1 Air Blower rpm= 3000
pump 1 Pool Light rpm= 0
pump 1 Spa Light rpm= 0
pump 1 Pool rpm= 1600
pump 1 Water Feature rpm= 0
pump 1 Jets rpm= 3450
pump 1 High Speed rpm= 2800
Which is correct
Also of note byte0 = 64 for me, i only have one VS pump so maybe that is why ( maybe a sort of length field?)
Also of note byte0 = 64 for me, i only have one VS pump so maybe that is why ( maybe a sort of length field?)
Interesting! The SLConfig log seems to deal with byte 0 like this, which seems nonsensical to me:
byte byCircuit = poolConfig.getEquipconfig().getFlowDataArray().get(iOffset).byteValue();
if ((byCircuit & 128) == 0) {
byte byCircuit2 = (byte) (byCircuit & 63);
}
This could be a decompilation or deobfuscation bug. Either way, I'm not sure that byte is actually important for anything (byCircuit
isn't used anywhere after this and obviously neither is byCircuit2
). Byte 2 seems to be the actually important one.
Also of note byte0 = 64 for me, i only have one VS pump so maybe that is why ( maybe a sort of length field?)
Interesting! The SLConfig log seems to deal with byte 0 like this, which seems nonsensical to me:
byte byCircuit = poolConfig.getEquipconfig().getFlowDataArray().get(iOffset).byteValue(); if ((byCircuit & 128) == 0) { byte byCircuit2 = (byte) (byCircuit & 63); }
This could be a decompilation or deobfuscation bug. Either way, I'm not sure that byte is actually important for anything (
byCircuit
isn't used anywhere after this and obviously neither isbyCircuit2
). Byte 2 seems to be the actually important one.
Hmmm, i looked at the code too and its unclear to me as well, it may not be important.
Interestingly i could not find the current speed/gpm/power use on that message, however I did find another message called GETPUMPSTATUS (msg 12584) that seems to have the needed info and also contains the set RPMs per circuit, unfortunately this message is not used in the android app so I'm guessing as to the meaning of the data (i interpreted everything as uint32, that may be wrong for the first couple of bytes):
Byte Range:Data
0-3:3 --> unknown
4-7:??--> unknown, sometimes value is 1 sometimes 4294967295 (FF FF FF FF)
8-12:1377 --> currently used watts
13-16:2800, --> currentl rpms
17-20:0, --> unknown
21-24:65, --> currentl GPM
25-28:255, --> unknown
Settings for different circuits starts at byte 29, each circuit is 12 bytes long
0-3:6 --> settings for CircuitId = 6
4-7:1600 --> set to 1600 RPM of GPM (see next byte),
8-12:1 --> 1 for RPM, 0 for GPM
(data repeats as above)
1, 2600, 1, --> same as above for circuit 1
2, 2900, 1,--> same as above for circuit 2
9, 2800, 1, --> same as above for circuit 9
3, 3000, 1, --> same as above for circuit 3
8, 3450, 1, --> same as above for circuit 8
132, 2200, 1,--> same as above for circuit 132 (freeze mode)
0, 30, 0 --> unknown (unused circuit maybe? since there should be 8 settings)
Hopefully the formatting is not confusing
See this gist for my current work on decoding the data, if I can figure out more on this or the EquipmentConfigurationMesage i'll post more: https://gist.github.com/bshep/5d7968639238832bd20c2fbb6769d990.js
Just a random thought, maybe a bit OT, could we use the SLEquipmentConfigurationMessage as a way to 'backup' our settings? Although most of the code dealing with its data is too complex for me to understand at the moment, it seems that the Android app sometimes edits values in memory and then sends it back to the controller, and looking at the field names it seems to be a pretty complete list of settings for the controller.
Yeah that could work. I'm not sure how complete this data is either. My slconfig app somehow wiped the circuits on my first pump while I was messing with it, but since I had a dump of one of these messages I was able to restore it all.
did some work on interpreting the valveDataArray, pretty much just ported the java code over and cleaned up some of the logic, TBH i'm not 100% sure what some of the checks are doing, but i do get appropriate data
Testing Needs:
https://github.com/bshep/node-screenlogic/commit/30dec79089505de461e788a54ce699d51f2de565
Also I was able to get the following info on SensorDataArray, MiscDataArray, DelayDataArray:
SensorDataArray:
DelayDataArray:
MiscDataArray:
See PR #32 for implementation of above decoding.
Still a lot of work to be done for the rest.
Also of note byte0 = 64 for me, i only have one VS pump so maybe that is why ( maybe a sort of length field?)
Interesting! The SLConfig log seems to deal with byte 0 like this, which seems nonsensical to me:
byte byCircuit = poolConfig.getEquipconfig().getFlowDataArray().get(iOffset).byteValue(); if ((byCircuit & 128) == 0) { byte byCircuit2 = (byte) (byCircuit & 63); }
This could be a decompilation or deobfuscation bug. Either way, I'm not sure that byte is actually important for anything (
byCircuit
isn't used anywhere after this and obviously neither isbyCircuit2
). Byte 2 seems to be the actually important one.Hmmm, i looked at the code too and its unclear to me as well, it may not be important.
Interestingly i could not find the current speed/gpm/power use on that message, however I did find another message called GETPUMPSTATUS (msg 12584) that seems to have the needed info and also contains the set RPMs per circuit, unfortunately this message is not used in the android app so I'm guessing as to the meaning of the data (i interpreted everything as uint32, that may be wrong for the first couple of bytes):
Byte Range:Data 0-3:3 --> unknown 4-7:??--> unknown, sometimes value is 1 sometimes 4294967295 (FF FF FF FF) 8-12:1377 --> currently used watts 13-16:2800, --> currentl rpms 17-20:0, --> unknown 21-24:65, --> currentl GPM 25-28:255, --> unknown Settings for different circuits starts at byte 29, each circuit is 12 bytes long 0-3:6 --> settings for CircuitId = 6 4-7:1600 --> set to 1600 RPM of GPM (see next byte), 8-12:1 --> 1 for RPM, 0 for GPM (data repeats as above) 1, 2600, 1, --> same as above for circuit 1 2, 2900, 1,--> same as above for circuit 2 9, 2800, 1, --> same as above for circuit 9 3, 3000, 1, --> same as above for circuit 3 8, 3450, 1, --> same as above for circuit 8 132, 2200, 1,--> same as above for circuit 132 (freeze mode) 0, 30, 0 --> unknown (unused circuit maybe? since there should be 8 settings)
Hopefully the formatting is not confusing
See this gist for my current work on decoding the data, if I can figure out more on this or the EquipmentConfigurationMesage i'll post more: https://gist.github.com/bshep/5d7968639238832bd20c2fbb6769d990.js
Based on some digging I was doing around the list and number of pumps, I believe that value of 64 indicates an IntelliFlo VSF pump. 0 is no pump, 128 is VS and 6 is VF. I just opened a case about getNumPumps() as it returns 8 pumps for me when I only have 1. By using byte0 of each 45 byte pump record in the FlowDataArray, you can determine if there really is a pump there or not. I added a 2nd pump in SLConfig to test even though I don't have a 2nd pump and the 2nd pump record started reporting its pump type (per the values I mentioned above) in byte0. No idea why they report different values for pump type in the FlowDataArray bytes vs. what you get in the pumpstatus message but I'm pretty sure of the mapping.
If your one pump is an IntelliFlo VSF (like mine) you should see 64 in that first byte of the first record.
@mikemucc @bshep @tomblevins Figured I'd go ahead and make an issue for decoding this thing so nobody's duplicating work.
As a reminder, most of this is coming from decompiling the slconfig app with jadx + experimentation.
versionDataArray
can be turned into a version integer like so:(this.versionDataArray[0] * 1000) + (this.versionDataArray[1])
controllerData
's top 2 bits indicate how many "slave" devices there are (which I'm calling "secondary" devices):(this.controllerData & 0x11000000) >> 6
. don't know about the rest of the bits (my controller returns a value of2
for this)flowDataArray
is where I've found the most interesting info so far. This contains information for up to 8 pumps worth of flow data. 45 bits are reserved for each pump and 24 of those contain data for the up-to-8 circuits that each pump supports. I've decoded a given pump's bits like this so far (values are from my equipment):Circuit id's are decoded via
SLControllerConfigMessage
'sbodyArray
array,deviceId
property. The circuit and priming rpms are really strange with the upper and lower bits separated in the array. Valid values for RPMs is 400 - 3450 with the default value being 1000 (upper 8 bits = 3, lower 8 bits = 232).I'm having trouble reconciling this information with what I'm seeing in the SLConfig code, though.
PageIntelliFloPriming
andPageIntelliFloFiltering
are both doing things with the flow data array, but the indices they're using don't match up quite right with what I'm seeing from my equipment. Still working on all this.