Моя записная книжка. Комментарии отключены из-за спама. Для вопросов используйте эту страничку

Подключаем Dadget CO2 к серваку

  1. Сначала сделаем чтобы любой пользователь мог обращаться к устройству
    создаем /etc/udev/rules.d/10-co2mon.rules
    с содержимым
ACTION=="add|change", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="a052", MODE:="0666"

щелкаем

udevadm control --reload
udevadm trigger

проверяем что /dev/usb/hiddev0 теперь crw-rw-rw-

  1. Подключаем библиотечку PyUSB hid. PyUSB глючное говно вызывающее странные эффекты, например пропадение устройства hiddev0.
    pip3 install hid (или hidapi уже не помню, это гуглится)
  1. Читаем (алгоритм расшифровки передрал с сишного проекта co2mod)
#!/usr/bin/env python3

import hid
import time

def decode_co(data):
    # кручу-верчу
    data[0], data[2] = data[2], data[0]
    data[1], data[4] = data[4], data[1]
    data[3], data[7] = data[7], data[3]
    data[5], data[6] = data[6], data[5]
    
    result = bytearray(8)

    # всех обмануть хочу
    result[7] = ((data[6] << 5) & 0xFF) | ((data[7] >> 3) & 0xFF)
    result[6] = ((data[5] << 5) & 0xFF) | ((data[6] >> 3) & 0xFF)
    result[5] = ((data[4] << 5) & 0xFF) | ((data[5] >> 3) & 0xFF)
    result[4] = ((data[3] << 5) & 0xFF) | ((data[4] >> 3) & 0xFF)
    result[3] = ((data[2] << 5) & 0xFF) | ((data[3] >> 3) & 0xFF)
    result[2] = ((data[1] << 5) & 0xFF) | ((data[2] >> 3) & 0xFF)
    result[1] = ((data[0] << 5) & 0xFF) | ((data[1] >> 3) & 0xFF)
    result[0] = ((data[7] << 5) & 0xFF) | ((data[0] >> 3) & 0xFF)
    
    magic_word = b'Htemp99e'
    for i in range(8):
        r = ((magic_word[i] << 4) & 0xFF) | ((magic_word[i] >> 4) & 0xFF)
        if result[i] < r:
            result[i] = 0xFF - r + result[i]
        else:
            result[i] = result[i] - r

    # не знаю почему, но у меня проверка чек-суммы никогда не сходилась    
    #if result[0]+result[1]+result[2] != result[3]:
    #    return 0

    res = (result[1] << 8) + result[2]

    if result[0] == 0x42:
        print("T={0}".format(res * 0.0625 - 273.15))
        return 1
    elif result[0] == 0x50:
        print("CO={0}".format(res))
        return 2
    return 0
    
try:
    h = hid.device()
    h.open(0x04d9, 0xa052)

    # хз, не вникал
    h.set_nonblocking(1)

    # по идее это отправка некой magic_table которой шифруется ответ, но и без любой из этих строк работает
    #h.write(b'8\x00\x00\x00\x00\x00\x00\x00\x00')
    h.send_feature_report([0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
    time.sleep(0.05)

    co = 1
    t = 1
    while co | t:
        d = h.read(8)
        if d:
            n = decode_co(d)
            if n == 1:
                t = 0
            elif n == 2:
                co = 0

    h.close()

except IOError as ex:
    print(ex)
 198   2020   co2   dadget   driver   linux   python   программирование
Ctrl ←Узел