ubruhin / python-dlogg-driver

Unofficial python package to read data from a USB D-LOGG device
GNU General Public License v3.0
4 stars 3 forks source link

IOError: Received 63 bytes instead of 65 #5

Open pocki80 opened 6 years ago

pocki80 commented 6 years ago

Hi - well done! Anyway, I was not yet sucessfull on retreiving data from my D-LOGG device using my Raspberry Pi 3 (Stretch).

Any Idea what could fix this? This is the output when running in python interactively:

with DLoggDevice("/dev/ttyUSB0") as device: ... print u"Type: {}".format(device.get_type()) ... print u"Firmware: {}".format(device.get_firmware_version()) ... print u"Mode: {}".format(device.get_mode()) ... print u"Logging criterion: {}".format(unicode(device.get_logging_criterion())) ... header = device.get_header() ... print u"Number of available samples: {}".format(header.get_sample_count()) ... data = device.fetch_data_range(header.start, 1) ... Type: Type.BL232_DLOGG_1DL Firmware: 2.9 Mode: Mode.ONE_DL Logging criterion: 3.0K Number of available samples: 21 Traceback (most recent call last): File "", line 8, in File "/usr/local/lib/python2.7/dist-packages/dlogg_driver/device.py", line 94, in fetch_data_range data.append(self.fetch_data(addr)) File "/usr/local/lib/python2.7/dist-packages/dlogg_driver/device.py", line 88, in fetch_data return Uvr1611MemoryData(self._transceive(tx_data, 65, checksum=True)) File "/usr/local/lib/python2.7/dist-packages/dlogg_driver/device.py", line 125, in _transceive raise IOError("Received {} bytes instead of {}".format(len(rx_data), rx_len)) IOError: Received 63 bytes instead of 65

Besides: I am wondering, why the device keeps telling "21" samples available all morning (last few hours). I installed the D-LOGG device on my UVR63-1 yesterday evening and it started with 1 sample, increasing all few minutes.

pocki80 commented 6 years ago

This is the header received by device.get_header():

binascii.hexlify(header.raw)

0f a8 c7 04 00 5a 00 00 00 00 0a 00 e6

print unicode(header)

{ identifier: 0x0F version: 0xA8 timestamp: 12230s start: 0 end: 20 }

get_current_data() expects 57 byty but receives only 55 fetch_data() expects 65 byte but receives only 63. In both cases, my DLOGG device transmits 2 bytes to less.

This is the raw-data returned for the queries: - hopefully someone can read that and recognize, what 2 bytes are missing?

fetch-data-range

Transceive:[0xac,0x00,0x00,0x00,0x01,0xad]--> [0xc9,0x22,0x84,0x22,0x22,0x21,0x93,0x22,0xff,0x2f,0xff,0x2f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x01,0x00, 0x00,0xea,0x08,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x01,0x01,0x0b,0x01, 0x00,0x00,0xf9]

fetch-current-data

Transceive:[0xab]--> [0x90,0xc9,0x22,0x53,0x22,0x26,0x21,0x63,0x22,0xff,0x2f,0xff, 0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x17,0x80,0x80,0x01, 0x11,0x00,0xfa,0x08,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x4d]

ubruhin commented 6 years ago

Hi,

Unfortunately the UVR63-1 is not supported yet by this driver, see https://github.com/ubruhin/python-dlogg-driver/issues/2#issuecomment-376649931.

Would you be interested in adding support for UVR63-1? Maybe I could give you some hints how the data format differs from UVR1611.

pocki80 commented 6 years ago

Hi. Thanks for the quick reply. I was already able to debug a bit and to get some things working by changing the expected tx_data length.

Yes, please support me by interpreting the data received. According the figures shown in Winsol, the device UVR61-3 has 6 temp. sensors, 9 external DL devices, 1 volume controller, 2 analog outputs, 3 pairs of power and energy counters and 3 digital outputs.

I saw that byte 1 of fetch_data_range is a counter that increases by 30 each line.

Further: the date and/or timestamp seem to be encoded differently.

From what I analyzed your code, it's almost not possible to reverse-engineer the sensor-data decoding without any insider knowledge. So would be great if you can support me on this topic, especially regarding the digital outputs, the volume controller and (if possible) the values from the DL-sensors (what are not shown from winsol btw).

ubruhin commented 6 years ago

According the figures shown in Winsol, the device UVR61-3 has 6 temp. sensors, 9 external DL devices, 1 volume controller, 2 analog outputs, 3 pairs of power and energy counters and 3 digital outputs.

The exact order and sizes are:

  1. 6x inputs, each 2 Bytes (same encoding as of UVR1611)
  2. 9x external DL devices, each 2 Bytes (same encoding as inputs)
  3. 3 digital outputs, 1 Byte total (lowest 3 bits)
  4. 1x pump speed, 1 Byte (same encoding as of UVR1611)
  5. 2x analog outputs, each 1 Byte
    • MSBit: 1=enabled, 0=disabled
    • Lower 7 bits: Voltage in 0.1V steps
  6. 3x energy counter enable flags, 1 Byte total (lowest 3 bits)
  7. 3x energy counter values, each 6 Bytes:
    • 2 Bytes: actual power in 0.1 kW steps
    • 2 Bytes: energy counter in 0.1 kWh
    • 2 Bytes: energy counter in MWh

Total: 53 Bytes (+ 6B datetime + 3B timestamp + 1B checksum = 63B total response)

Further: the date and/or timestamp seem to be encoded differently.

Should not, but maybe I implemented it wrong (I guess I never tested it) :wink:

Btw, in Uvr1611CurrentData there's a check that the first byte is 0x80. For UVR61-3 it should be 0x90.

pocki80 commented 6 years ago

Wow, rich Info! Thx. I will try to adopt your driver. Unfortunately I am not well enough on python programming skills in order to make your driver flexible to support both models in one class.

The external DL devices (18 byte) are all 0, even though the display shows sensors 2 and 3 with realistic temperature values. Looks like DLOGG does not collect their values. Is that maybe due to the connection of DLOGG to UVR61-3 using the same pins as the cable to the connectors? I connected DLOGG to DL/N on UVR61-3. Sensor 2 is in the same pins of UVR61, Sensor 3 ist "after" Sensor 2.

pocki80 commented 6 years ago

Do you have also further I do on the header? What about byte 5? What is the meaning of "timestamp"? Seconds since power-on?

pocki80 commented 6 years ago

I forked your repo to https://github.com/pocki80/python-dlogg-driver and put my two modified files there. They now seem to fully work with my UVR61-3:

Example of a reading:

Data [57]: { inputs: 68.5°C, 56.5°C, 28.0°C, 59.1°C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 outputs: True, False, False, 0.0V, 0.0V pump_speeds: [True] 24rpm power_meters: [True] 0.5kW 9233.6kWh, [False], [False] datetime: 2018-07-27_10:07:10 timestamp: 54200s }

So, to have that merged I think we should adopt the code in a way, that the device type is correctly recognized and the data-reading/decoding is done accordingly. Do you know how to recognize UVR1611 vs. UVR61-3? A byte within the header?

And: will your python-dlogg-db continue to work, as the set of values changes?

ubruhin commented 6 years ago

Unfortunately I am not well enough on python programming skills in order to make your driver flexible to support both models in one class.

Maybe I could do that some time, but I cannot promise it.

The external DL devices (18 byte) are all 0, even though the display shows sensors 2 and 3 with realistic temperature values. Looks like DLOGG does not collect their values. Is that maybe due to the connection of DLOGG to UVR61-3 using the same pins as the cable to the connectors? I connected DLOGG to DL/N on UVR61-3. Sensor 2 is in the same pins of UVR61, Sensor 3 ist "after" Sensor 2.

I'm sorry but I have no idea how to connect the UVR61-3 or why the external DL devices are all 0 ;)

Do you have also further I do on the header? What about byte 5?

I guess byte 5 indicates what device is connected. Should be 0x76 for UVR1611 and 0x5A for UVR61-3. Do you receive 0x5A?

What is the meaning of "timestamp"? Seconds since power-on?

I guess it's in 10 seconds since power-on.

I forked your repo to https://github.com/pocki80/python-dlogg-driver and put my two modified files there. They now seem to fully work with my UVR61-3:

Nice! :+1:

added analog outputs to array ´outputs´: false if off and 9.9V voltage if on (could be moved to an own object to separate on/off state and voltage)

Yeah I would suggest to use separate objects for digital and analog outputs, that's more explicit and easier to handle.

So, to have that merged I think we should adopt the code in a way, that the device type is correctly recognized and the data-reading/decoding is done accordingly. Do you know how to recognize UVR1611 vs. UVR61-3? A byte within the header?

Fetching data should be easy as the byte 5 of the header indicates what device is connected.

Reading current data is a bit cumbersome because the response length depends on the connected device, so we cannot know the "rx_len". But we could first receive only one byte to see what device is connected, and then receive the rest of the response.

And: will your python-dlogg-db continue to work, as the set of values changes?

Probably not ;)