I've done a lot of work on my OWL CM160 integrating into Node-Red. As a result of electricowl and a couple of other websites, I got it going :). My contribution back is a desription of the protocol; which i'll post here as this is the fiirst place i found when looking...
OWL USB Serial Protocol:
Only after USB cable disconnect/reconnect is all historical data available. At other times, only UNSENT historical data is available.
each msg received is 11 bytes:
['\xa9', 'I', 'D', 'T', 'C', 'M', 'V', '0', '0', '1', '\x01']
Indicates that the device is present, and has not had a response from the PC for a while.
Respond with 0x5a ('Z') - within 1 second (250ms seems to work ok).
IF sent > 1s after the IDTC message, the 'Z' will be silently swallowed, then any subsequent 'Z' will work (leading to very confusing results).
This will cause the OWL to send historical data (lots of data, maybe as much as 32kbytes?)
The end of each chunk of historical data is indicated by ['\xa9', 'I', 'D', 'T', 'W', 'A', 'I', 'T', 'P', 'C', 'R']
at which time the Computer can process the received data before returning
0xa5
Which tells the owl to send more historical data.
each 11 byte message consists of a type, plus 9 bytes of information, and a checksum
the last byte is the sum of the first 10 bytes.
Types:
81 - Live data
89 - historical data
169 - IDTCMV001 or IDTWAITPC
basic processing:
switch (type)
case 81 (dec)
store/display live data
break
case 89 (dec)
if (message starts with 255,255,255)
ignore
else
place historical data into historical buffer
break
case 169 (dec)
if msg contains 001
respond 90 (dec)
break
if msg contains WAIT
process historical buffer
then respond 165
clear historical buffer
break
break
}
Live data format:
e.g. ['Q', '\x10', '\x0b', '\x05', '\n', '\x15', '\xe2', '\x04', '\x97', '\x00', '\r']
CostI = (data[7] << 8) | data[6];
data[2] & 128 indicates cost should be multiplied by 100.
data[2] === 'Data Unit'.
time is take as time of reciept? (time in message is not reliable - may be last time from last historical? - so ignore it).
Historical data format:
e.g. ['Y', '\x10', '\n', '\x06', '\n', '&', '\xe2', '\x04', 'l', '\x00', '\xfb']
data[1] is year
data[2] & 63 is mon (1-12)
data[2] & 64 is 'Data available' if 0 (i.e. it's set on the last one?)
data[2] & 128 is 'Tarrif Units'
data[3] is day
data[4] is hour
data[5] is minute
I've done a lot of work on my OWL CM160 integrating into Node-Red. As a result of electricowl and a couple of other websites, I got it going :). My contribution back is a desription of the protocol; which i'll post here as this is the fiirst place i found when looking...
OWL USB Serial Protocol:
Only after USB cable disconnect/reconnect is all historical data available. At other times, only UNSENT historical data is available.
each msg received is 11 bytes:
['\xa9', 'I', 'D', 'T', 'C', 'M', 'V', '0', '0', '1', '\x01']
Indicates that the device is present, and has not had a response from the PC for a while.
Respond with 0x5a ('Z') - within 1 second (250ms seems to work ok).
IF sent > 1s after the IDTC message, the 'Z' will be silently swallowed, then any subsequent 'Z' will work (leading to very confusing results).
This will cause the OWL to send historical data (lots of data, maybe as much as 32kbytes?)
The end of each chunk of historical data is indicated by
['\xa9', 'I', 'D', 'T', 'W', 'A', 'I', 'T', 'P', 'C', 'R']
at which time the Computer can process the received data before returning
0xa5
Which tells the owl to send more historical data.
each 11 byte message consists of a type, plus 9 bytes of information, and a checksum
the last byte is the sum of the first 10 bytes.
Types:
81 - Live data
89 - historical data
169 - IDTCMV001 or IDTWAITPC
basic processing:
switch (type)
case 81 (dec)
store/display live data
break
case 89 (dec)
if (message starts with 255,255,255)
ignore
else
place historical data into historical buffer
break
case 169 (dec)
if msg contains 001
respond 90 (dec)
break
if msg contains WAIT
process historical buffer
then respond 165
clear historical buffer
break
break
}
Live data format:
e.g.
['Q', '\x10', '\x0b', '\x05', '\n', '\x15', '\xe2', '\x04', '\x97', '\x00', '\r']
Amps = ((data[9] << 8) | data[8])
Watts = Amps * 0.7 * Voltage.
CostI = (data[7] << 8) | data[6];
data[2] & 128 indicates cost should be multiplied by 100.
data[2] === 'Data Unit'.
time is take as time of reciept? (time in message is not reliable - may be last time from last historical? - so ignore it).
(note: 'data unit' replaces month.... hence why funny month values...)
Historical data format:
e.g.
['Y', '\x10', '\n', '\x06', '\n', '&', '\xe2', '\x04', 'l', '\x00', '\xfb']
data[1] is year
data[2] & 63 is mon (1-12)
data[2] & 64 is 'Data available' if 0 (i.e. it's set on the last one?)
data[2] & 128 is 'Tarrif Units'
data[3] is day
data[4] is hour
data[5] is minute
Amps = ((data[9] << 8) | data[8])
Watts = Amps * 0.7 * Voltage.
CostI = (data[7] << 8) | data[6];
data[2] & 128 indicates cost should be multiplied by 100.
Also observed the following 'bad' message:
['Y', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\x80']