Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept patch for command-line argument to use libusb? #28

Open
dsandber opened this issue Jun 14, 2021 · 2 comments
Open

Accept patch for command-line argument to use libusb? #28

dsandber opened this issue Jun 14, 2021 · 2 comments

Comments

@dsandber
Copy link

Hi,

I used the temper.py code to quickly get readings from my Temper2 on MacOS using libusb. Since this library seems to be the most modern and sensor-supporting one around, I was wondering if you'd accept a patch to use libusb if requested via command line argument? That would enable this code to be used on Windows + Mac as well, and wouldn't affect the existing operation.

I was surprised that I couldn't find any code to read the sensor on a Mac, and it'd be great to help remedy that.

@ci-vamp
Copy link

ci-vamp commented Jan 11, 2023

@dsandber do you still have the fork for using libusb? i am trying to access multiple temper2 sensors from a w10 machine. unfortunately i am unable to access more than one through the GUI. i came across this project which seemed to give direct access to the sensors.

however it does not work on windows.

@dsandber
Copy link
Author

I haven't dealt with this in a long time so I don't remember where I left it. I believe I got it working with this code that uses hid, but I could be wrong:

import binascii
import hid
import struct

vid = 0x413d  # Change it for your device
pid = 0x2107  # Change it for your device


def _parse_bytes(name, offset, divisor, the_bytes, info):
    """
    Data is returned from several devices in a similar format. In the first
    8 bytes, the internal sensors are returned in bytes 2 and 3 (temperature)
    and in bytes 4 and 5 (humidity). In the second 8 bytes, external sensor
    information is returned. If there are only external sensors, then only 8
    bytes are returned, and the caller is expected to use the correct 'name'.
    The caller is also expected to detect the firmware version and provide the
    appropriate divisor, which is usually 100 or 256.

    There is no return value. Instead 'info[name]' is update directly, if a
    value is found.
    """
    try:
        if the_bytes[offset] == 0x4e and the_bytes[offset + 1] == 0x20:
            return
    except IndexError:
        return
    try:
        info[name] = struct.unpack_from('>h', the_bytes, offset)[0] / divisor
    except IndexError:
        return


def read_data(d: hid.Device):
    all_data = b''
    while True:
        data = d.read(8, timeout=100)
        if not data:
            break
        all_data += data
    return all_data


def process(d: hid.Device):
    query = struct.pack('8B', 0x01, 0x86, 0xff, 0x01, 0, 0, 0, 0)
    d.write(query)
    firmware = read_data(d)

    query = struct.pack('8B', 0x01, 0x80, 0x33, 0x01, 0, 0, 0, 0)
    d.write(query)
    sensor_reading = read_data(d)

    info = {}
    info['firmware'] = str(firmware, 'latin-1').strip()
    info['hex_firmware'] = str(binascii.b2a_hex(firmware), 'latin-1')

    info['firmware'] = info['firmware'][:12]
    _parse_bytes('internal temperature', 2, 100.0, sensor_reading, info)
    _parse_bytes('internal humidity', 4, 100.0, sensor_reading, info)
    _parse_bytes('external temperature', 10, 100.0, sensor_reading, info)
    _parse_bytes('external humidity', 12, 100.0, sensor_reading, info)
    print(f"Got: {info}")


def main():
    for device in hid.enumerate(vid, pid):
        try:
            with hid.Device(path=device['path']) as d:
                print(f"Opened via path: {device}")
                process(d)
        except hid.HIDException as e:
            print(f"Failed to open via path: {device} -- {e}")


main()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants