co2mon icon indicating copy to clipboard operation
co2mon copied to clipboard

Unexpected data from device (data[4] = fb, want 0x0d)

Open bahbka opened this issue 5 years ago • 14 comments

It seems there is new revision of ZGm053U hardware with new protocol, bought at dadget.ru. Doesn't works with apps from dadget.ru, but works with latest windows software from http://www.zyaura.com/

...
Unexpected data from device (data[4] = fa, want 0x0d)
Unexpected data from device (data[4] = fb, want 0x0d)
Unexpected data from device (data[4] = fa, want 0x0d)
Unexpected data from device (data[4] = ff, want 0x0d)
Unexpected data from device (data[4] = f9, want 0x0d)
Unexpected data from device (data[4] = f9, want 0x0d)
Unexpected data from device (data[4] = fc, want 0x0d)
Unexpected data from device (data[4] = fd, want 0x0d)
Unexpected data from device (data[4] = f9, want 0x0d)
Unexpected data from device (data[4] = fa, want 0x0d)
...

Does anyone have the same problems? Is there any chance to implement new protocol?

bahbka avatar Sep 04 '20 10:09 bahbka

I don't have the device, so it's unlikely that I'll be able to add support of the new revision. I'll keep this issue open, maybe someone else will be able to reverse engineer the protocol.

dmage avatar Sep 08 '20 22:09 dmage

How should one reverse-engineer the new protocol? install usb filter driver on windows and dump the communications?

4DA avatar Oct 22 '20 18:10 4DA

There is no ready-to-go solution. You can use everything you have: find something from the producer or analyse what you already have. Dumping the communications might be a good starting point.

dmage avatar Nov 01 '20 18:11 dmage

There is no ready-to-go solution. You can use everything you have: find something from the producer or analyse what you already have. Dumping the communications might be a good starting point.

I can share ssh (raspberry pi) with connected new device, if you can make update

and may be it can helps you: https://medgadgets.ru/wp-content/uploads/2015/03/AN135-CO2mini-usb-protocol.zip

sapeg-in avatar Nov 06 '20 20:11 sapeg-in

There is not easy, but very good workaround. I soldered pins to serial port inside device and connected Wemos D1 Mini in 3d printed case with esphome firmware. It seems protocol at serial port not changed, works very good and adds wireless functionality, easy integrate with home assistant. I prefer this solution :)

bahbka avatar Nov 07 '20 06:11 bahbka

I've mailed ZyAura last week but got no response. Seems like sniffing the communications of the windows software is the only option now to make it work through its USB port.

l29ah avatar Nov 08 '20 20:11 l29ah

You may want to read https://hackaday.io/project/5301-reverse-engineering-a-low-cost-usb-co-monitor. I'm almost sure you'll need IDA Pro.

dmage avatar Nov 08 '20 20:11 dmage

Guys, I've just bought the device off dadget.ru (AKA masterkit.ru) and got the same error message. Have looked into the protocol, and it turns out we just don't need decode_buf for this device. Replaced it with memcpy and voila! There is the same USB vendor:product, so I'm not sure how to distinguish this device from others (original?) ones. Having a CLI option to turn decoding on/off looks feasible.

tobotras avatar Nov 27 '20 14:11 tobotras

Here you go: https://github.com/tobotras/co2mon/commit/c60a11b51fd81f44d58e7bb959215501a6c424dd See also additional options there: -o only print values once and quit; -t only show temperature; -c only show CO2 concentration

tobotras avatar Nov 27 '20 14:11 tobotras

Here you go: tobotras/co2mon@c60a11b See also additional options there: -o only print values once and quit; -t only show temperature; -c only show CO2 concentration

you are my hero!

sapeg-in avatar Nov 27 '20 19:11 sapeg-in

@tobotras nice, I didn't expect they are making devices without this encoding. Thank you, I added your commit to master.

Can you attach output of lsusb -vd 04d9:a052? I'm curious if there is a way to detect whether the device encrypts data.

dmage avatar Nov 27 '20 20:11 dmage

@dmage, many thanks for the tool, to start from!

Here you go:

Bus 001 Device 012: ID 04d9:a052 Holtek Semiconductor, Inc. USB-zyTemp Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x04d9 Holtek Semiconductor, Inc. idProduct 0xa052 USB-zyTemp bcdDevice 2.00 iManufacturer 1 Holtek iProduct 2 USB-zyTemp iSerial 3 2.00 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0022 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 53 Report Descriptor: (length is 53) Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage Minimum, data= [ 0x00 ] 0 (null) Item(Local ): Usage Maximum, data= [ 0xff ] 255 (null) Item(Global): Report Count, data= [ 0x08 ] 8 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Main ): Feature, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage Minimum, data= [ 0x00 ] 0 (null) Item(Local ): Usage Maximum, data= [ 0xff ] 255 (null) Item(Global): Report Count, data= [ 0x08 ] 8 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage Minimum, data= [ 0x00 ] 0 (null) Item(Local ): Usage Maximum, data= [ 0xff ] 255 (null) Item(Global): Report Count, data= [ 0x08 ] 8 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Main ): Output, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 10 can't get debug descriptor: Resource temporarily unavailable Device Status: 0x0000 (Bus Powered)

tobotras avatar Nov 28 '20 03:11 tobotras

There is a way in doing guesswork trying with and without encoding :-D

tobotras avatar Nov 28 '20 03:11 tobotras

Try this patch: In src/co2mon.c

-    decode_buf(result, data, magic_table);
+    for (int i = 0; i < 8; i++) result[i] = data[i];

Device: mt8057s

Crutchmaster avatar Mar 25 '21 03:03 Crutchmaster

@Crutchmaster wrote:

Try this patch: In src/co2mon.c

-    decode_buf(result, data, magic_table);
+    for (int i = 0; i < 8; i++) result[i] = data[i];

Device: mt8057s

So this is equivalent to tobotras' change referenced in a comment posted one year before yours - that was merged into master, at that time.

gsauthof avatar Feb 13 '23 23:02 gsauthof

FWIW, the 'TFA AIRCO2NTROL MINI CO2 Monitor' (EAN 4009816027351, Kat.-Nr. 31.5006.02, ID-NR. 31.010 180, recently bought from Amazon.de) also only works without decoding, i.e. with co2mond -n.

It would be great if co2mond would auto-detect new-style devices, i.e. ones where the data isn't encoded.

Especially since the for those device required -n option isn't exactly obvious, from its description:

-n    don't decode the data

That means a new user basically has to find this issue in order to use this software.

Perhaps we are lucky and the release_number and or the serial_number USB device attribute are unique between new -style and old-style devices.

My device shows:

{
 'interface_number': 0,
 'manufacturer_string': 'Holtek',
 'path': b'2-3:1.0',
 'product_id': 0xa052
 'product_string': 'USB-zyTemp',
 'release_number': 512,
 'serial_number': '2.00',
 'usage': 0,
 'usage_page': 0,
 'vendor_id': 0x4d9
}

Perhaps somebody with access to an old-style device can share their relase_number/serial_number attributes.

Alternatively, the next best thing would be an auto-detection.

Last but not least a small hint in the -h help screen and a big hint in the readme probably would be a huge time saver for new co2mond users.

gsauthof avatar Feb 13 '23 23:02 gsauthof

My old-style device:

Bus 001 Device 055: ID 04d9:a052 Holtek Semiconductor, Inc. USB-zyTemp
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x04d9 Holtek Semiconductor, Inc.
  idProduct          0xa052 USB-zyTemp
  bcdDevice            1.00
  iManufacturer           1 Holtek
  iProduct                2 USB-zyTemp
  iSerial                 3 1.40
  bNumConfigurations      1

l29ah avatar Feb 14 '23 00:02 l29ah

This looks promising, i.e. we have:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                    old        new
――――――――――――――――――――――――――――――――――
serial_number      1.40       2.00
release_number   0x0100     0x0200
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

(where serial_number == iSerial and release_number == bcdDevice)

Thus, one could use either of those to automatically switch decoding on/off.

I'm leaning towards release_number.

Of course, one could still provide -n (and a new option for complement selection) to be able to override the auto-detection.

gsauthof avatar Feb 14 '23 23:02 gsauthof