From 8a289112f6a71be24b7ba451da0e8d5883094716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bourgeois?= Date: Tue, 26 Dec 2017 14:32:16 +0100 Subject: [PATCH 01/64] Fixing the munin plugin --- etc/munin-temperature | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/etc/munin-temperature b/etc/munin-temperature index d914247..de54f42 100755 --- a/etc/munin-temperature +++ b/etc/munin-temperature @@ -9,6 +9,7 @@ #%# capabilities=autoconf +from __future__ import print_function import sys @@ -21,23 +22,23 @@ def autoconf(): try: handler = get_handler() except ImportError: - print "no (temper-python package is not installed)" + print ("no (temper-python package is not installed)") else: if len(handler.get_devices()): - print "yes" + print ("yes") else: - print "no (No devices found)" + print ("no (No devices found)") def config(): handler = get_handler() - print "graph_title Temperature" - print "graph_vlabel Degrees Celsius" - print "graph_category sensors" + print ("graph_title Temperature") + print ("graph_vlabel Degrees Celsius") + print ("graph_category sensors") for device in handler.get_devices(): port = device.get_ports() port_name = str(port).replace('.', '_') - print "temp_" + port_name + ".label Port {0:s} Temperature".format(str(port)) + print ("temp_" + port_name + ".label Port {0:s} Temperature".format(str(port))) def fetch(): @@ -49,7 +50,7 @@ def fetch(): temp = device.get_temperature() except Exception: temp = 'U' - print "temp_" + port_name + ".value {0:f}".format(temp) + print ("temp_" + port_name + ".value {0:f}".format(temp)) def main(): From dd0759f486c74306a2b7d24e037d76a8f042d522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bourgeois?= Date: Tue, 26 Dec 2017 14:35:02 +0100 Subject: [PATCH 02/64] Fixing the setup.py script for python 2 --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 83fdda2..38fc466 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ +from io import open from setuptools import setup setup( From f128c36d7cf07043efe867addf6790a1e0adcbb8 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Tue, 8 May 2018 22:05:01 +0100 Subject: [PATCH 03/64] Report TEMPerV1.2 devices as having a single sensor --- temperusb/temper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/temperusb/temper.py b/temperusb/temper.py index 41bb430..7dfc9ac 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -161,7 +161,8 @@ def lookup_sensor_count(self): """ Lookup the number of sensors on the device by product name. """ - if (self._device.product == 'TEMPer1F_V1.3') or \ + if (self._device.product == 'TEMPerV1.2') or \ + (self._device.product == 'TEMPer1F_V1.3') or \ (self._device.product == 'TEMPer1F_H1_V1.4'): return 1 From c4042edba2e5738656be875f42234141e9f45dae Mon Sep 17 00:00:00 2001 From: Rob Taft Date: Thu, 21 Mar 2019 05:28:15 -0400 Subject: [PATCH 04/64] Added support for 3 sensor tempers and TEMPerNTC1.O --- temperusb/temper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/temperusb/temper.py b/temperusb/temper.py index 41bb430..6bf3556 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -164,7 +164,7 @@ def lookup_sensor_count(self): if (self._device.product == 'TEMPer1F_V1.3') or \ (self._device.product == 'TEMPer1F_H1_V1.4'): return 1 - + if (self._device.product == 'TEMPerNTC1.O'): return 3 # All others are two - if not the case, contribute here: https://github.com/padelt/temper-python/issues return 2 @@ -183,8 +183,8 @@ def set_sensor_count(self, count): # Currently this only supports 1 and 2 sensor models. # If you have the 8 sensor model, please contribute to the # discussion here: https://github.com/padelt/temper-python/issues - if count not in [1, 2,]: - raise ValueError('Only sensor_count of 1 or 2 supported') + if count not in [1, 2, 3]: + raise ValueError('Only sensor_count of 1-3 supported') self._sensor_count = int(count) From f8c5edfc7809b9ca60b504d6920920b2c863fe96 Mon Sep 17 00:00:00 2001 From: Markus Neumann Date: Sat, 27 Apr 2019 21:59:08 +0200 Subject: [PATCH 05/64] typo fix just a typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20b6e14..c4e1162 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ you should end up with two scripts conveniently installed: /usr/local/bin/temper-poll /usr/local/bin/temper-snmp -If your system does not provide access as a normal user to the USB device, you need to rum them as root. See "USB device permissions" section for more on this. +If your system does not provide access as a normal user to the USB device, you need to run them as root. See "USB device permissions" section for more on this. temper-poll accepts -p option now, which adds the USB bus and port information each device is plugged on. From 4d3d040f43fe4bc5807b4c4dee6284ac035ff907 Mon Sep 17 00:00:00 2001 From: Dave T Date: Sat, 11 May 2019 16:20:55 +0100 Subject: [PATCH 06/64] Made error message about usb permissions display correction in python 3.6 --- temperusb/temper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temperusb/temper.py b/temperusb/temper.py index 41bb430..08e0bd7 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -94,7 +94,7 @@ def __init__(self, device, sensor_count=1): # https://github.com/padelt/temper-python/issues/63 self.lookup_sensor_count() except ValueError as e: - if 'langid' in e.message: + if 'langid' in str(e): raise usb.core.USBError("Error reading langids from device. "+ "This might be a permission issue. Please check that the device "+ "node for your TEMPer devices can be read and written by the "+ From 5f2e6946f943577197af9813119c11eb81f6baf2 Mon Sep 17 00:00:00 2001 From: Dave T Date: Sat, 11 May 2019 23:34:11 +0100 Subject: [PATCH 07/64] Added support for TemperHUM with si7021 type sensor. --- temperusb/cli.py | 2 +- temperusb/temper.py | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/temperusb/cli.py b/temperusb/cli.py index 17b41bc..a8de695 100644 --- a/temperusb/cli.py +++ b/temperusb/cli.py @@ -7,7 +7,7 @@ def parse_args(): - descr = "Temperature data from a TEMPer v1.2 sensor." + descr = "Temperature data from a TEMPer v1.2/v1.3 sensor." parser = argparse.ArgumentParser(description=descr) parser.add_argument("-p", "--disp_ports", action='store_true', diff --git a/temperusb/temper.py b/temperusb/temper.py index 08e0bd7..a1705ef 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -101,8 +101,8 @@ def __init__(self, device, sensor_count=1): "user running this code. The temperusb README.md contains hints "+ "about how to fix this. Search for 'USB device permissions'.") self.set_sensor_count(self.lookup_sensor_count()) - LOGGER.debug('Found device | Bus:{0} Ports:{1}'.format( - self._bus, self._ports)) + LOGGER.debug('Found device | Bus:{0} Ports:{1} SensorCount:{2}'.format( + self._bus, self._ports, self._sensor_count)) def set_calibration_data(self, scale=None, offset=None): """ @@ -154,7 +154,8 @@ def lookup_humidity_offset(self, sensor): if self._device.product == 'TEMPer1F_H1_V1.4': # Has only 1 sensor, and the humidity data is at offset = 4 return 4 - + if self._device.product == 'TEMPERHUM1V1.3': + return 4 return None def lookup_sensor_count(self): @@ -162,7 +163,8 @@ def lookup_sensor_count(self): Lookup the number of sensors on the device by product name. """ if (self._device.product == 'TEMPer1F_V1.3') or \ - (self._device.product == 'TEMPer1F_H1_V1.4'): + (self._device.product == 'TEMPer1F_H1_V1.4') or \ + (self._device.product == 'TEMPERHUM1V1.3'): return 1 # All others are two - if not the case, contribute here: https://github.com/padelt/temper-python/issues @@ -254,7 +256,9 @@ def get_data(self, reset_device=False): temp_data = self._interrupt_read() # Get humidity - if self._device.product == 'TEMPer1F_H1_V1.4': + LOGGER.debug("ID='%s'" % self._device.product) + if (self._device.product == 'TEMPer1F_H1_V1.4') or \ + (self._device.product == 'TEMPERHUM1V1.3'): humidity_data = temp_data else: humidity_data = None @@ -327,7 +331,10 @@ def get_temperatures(self, sensors=None): # Interpret device response for sensor in _sensors: offset = self.lookup_offset(sensor) - celsius = struct.unpack_from('>h', data, offset)[0] / 256.0 + if self._device.product == 'TEMPERHUM1V1.3': #si7021 type device. + celsius = struct.unpack_from('>h', data, offset)[0] * 175.72 / 65536 - 46.85 + else: # fm75 (?) type device + celsius = struct.unpack_from('>h', data, offset)[0] / 256.0 # Apply scaling and offset (if any) celsius = celsius * self._scale + self._offset results[sensor] = { @@ -365,10 +372,8 @@ def get_humidity(self, sensors=None): list(range(0, self._sensor_count)), ) ) - data = self.get_data() data = data['humidity_data'] - results = {} # Interpret device response @@ -376,7 +381,10 @@ def get_humidity(self, sensors=None): offset = self.lookup_humidity_offset(sensor) if offset is None: continue - humidity = (struct.unpack_from('>H', data, offset)[0] * 32) / 1000.0 + if self._device.product == 'TEMPERHUM1V1.3': #si7021 type device. + humidity = (struct.unpack_from('>H', data, offset)[0] * 125) / 65536 -6 + else: #fm75 (?) type device + humidity = (struct.unpack_from('>H', data, offset)[0] * 32) / 1000.0 results[sensor] = { 'ports': self.get_ports(), 'bus': self.get_bus(), From d6fd1c0412dcf4891f13eb0756927d184c1367df Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 7 Nov 2020 22:49:21 +0000 Subject: [PATCH 08/64] add first pytests --- tests/test_temper.py | 117 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 tests/test_temper.py diff --git a/tests/test_temper.py b/tests/test_temper.py new file mode 100644 index 0000000..7d9eb79 --- /dev/null +++ b/tests/test_temper.py @@ -0,0 +1,117 @@ +""" +pytests for temperusb + +run from the project root with: +pytest --cov=temperusb +""" + +import os + +import pytest +import usb +from unittest.mock import MagicMock, patch, Mock + +import temperusb + +from temperusb.temper import TIMEOUT + + +@pytest.mark.parametrize( + [ + "productname", + "vid", + "pid", + "ctrl_data_in_expected", + "data_out_raw", + "temperature_out_expected", + ], + [ + [ + "TEMPerV1.2", + 0x0C45, + 0x7401, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) + 32.1, + ], + # [ + # "TEMPer1F_V1.3", # Has 2 sensors + # 0x0C45, + # 0x7401, + # b"\x01\x80\x33\x01\x00\x00\x00\x00", + # b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) + # 32.1, + # ], + [ + "TEMPERHUM1V1.3", + 0x0C45, + 0x7401, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x56\x2C", # 0x562C converts to 12.3C (si7021) + 12.3, + ], + [ + "TEMPer1F_H1_V1.4", + 0x0C45, + 0x7401, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) + 32.1, + ], + [ + "TEMPerNTC1.O", + 0x0C45, + 0x7401, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A\x2B\x33\x36\x4D", # 0x201A,0x2B33,0x364D converts to 32.1,43.2,54.3C (fm75) + 32.1, + ], + ], +) +def test_TemperDevice( + productname, vid, pid, ctrl_data_in_expected, data_out_raw, temperature_out_expected +): + """ + Patches the underlying usb port call to allow us to verify the data + we would be sending, and fake the return data so that we can test the + conversion coming back. + """ + usbdev = Mock(bus="fakebus", product=productname) + usbdev.is_kernel_driver_active = MagicMock(return_value=False) + + def ctrl_transfer_dummy( + bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout + ): + assert data_or_wLength == ctrl_data_in_expected + assert timeout == TIMEOUT + + usbdev.ctrl_transfer = MagicMock( + bmRequestType=0x21, + bRequest=0x09, + wValue=0x0200, + wIndex=0x01, + data_or_wLength=None, + timeout=None, + side_effect=ctrl_transfer_dummy, + ) + # print("usbdev.bus=%s" % usbdev.bus) + usbdev.read = Mock(return_value=data_out_raw) + + def match_pids(find_all, idVendor, idProduct): + if idVendor == vid and idProduct == pid: + return [usbdev] + else: + return [] + + with patch("usb.core.find", side_effect=match_pids, return_value=[usbdev]): + th = temperusb.TemperHandler() + devs = th.get_devices() + # Check that we actually got any devices + assert devs != None + # Check that we only found one sensor + assert len(devs) == 1, "Should be only one sensor type matching" + + # read a temperature + results = devs[0].get_temperatures(None) + # check the temperature is what we were expecting. + assert results[0]["temperature_c"] == pytest.approx(temperature_out_expected, 0.01) From 18ddd768f677b640a9217f308f341882ddc29270 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 8 Nov 2020 23:03:31 +0000 Subject: [PATCH 09/64] Add ability to pytest humidty sensors --- tests/test_temper.py | 62 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index 7d9eb79..afc72cc 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -21,55 +21,83 @@ "productname", "vid", "pid", + "count", "ctrl_data_in_expected", "data_out_raw", "temperature_out_expected", + "humidity_out_expected", ], [ [ "TEMPerV1.2", 0x0C45, 0x7401, + 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) 32.1, + None, + ], + [ + "TEMPer1F_V1.3", # Has 1 sensor at offset 4 + 0x0C45, + 0x7401, + 1, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) + 32.1, + None, ], - # [ - # "TEMPer1F_V1.3", # Has 2 sensors - # 0x0C45, - # 0x7401, - # b"\x01\x80\x33\x01\x00\x00\x00\x00", - # b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) - # 32.1, - # ], [ "TEMPERHUM1V1.3", 0x0C45, 0x7401, + 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", - b"\x00\x00\x56\x2C", # 0x562C converts to 12.3C (si7021) + b"\x00\x00\x56\x2C\xBF\xB1", # 0x562C,0xBFB1 converts to 12.3C,87.6% (si7021) 12.3, + 87.6, ], [ "TEMPer1F_H1_V1.4", 0x0C45, 0x7401, + 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", - b"\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) + b"\x00\x00\x20\x1A\x0C\x0C", # 0x201A,0x0C0C converts to 32.1C,98.7% (fm75) 32.1, + 98.7, ], [ "TEMPerNTC1.O", 0x0C45, 0x7401, + 3, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x20\x1A\x2B\x33\x36\x4D", # 0x201A,0x2B33,0x364D converts to 32.1,43.2,54.3C (fm75) 32.1, + None, ], + # [ + # "????", # Has 2 sensors + # 0x0C45, + # 0x7401, + # 1, + # b"\x01\x80\x33\x01\x00\x00\x00\x00", + # b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) + # 32.1, + # ], ], ) def test_TemperDevice( - productname, vid, pid, ctrl_data_in_expected, data_out_raw, temperature_out_expected + productname, + vid, + pid, + count, + ctrl_data_in_expected, + data_out_raw, + temperature_out_expected, + humidity_out_expected, ): """ Patches the underlying usb port call to allow us to verify the data @@ -111,7 +139,17 @@ def match_pids(find_all, idVendor, idProduct): # Check that we only found one sensor assert len(devs) == 1, "Should be only one sensor type matching" + dev = devs[0] + + # check that the sensor count reported is what we expect + assert dev.get_sensor_count() == count # read a temperature - results = devs[0].get_temperatures(None) + results = dev.get_temperatures(None) + # check the temperature is what we were expecting. assert results[0]["temperature_c"] == pytest.approx(temperature_out_expected, 0.01) + + # if the device is expected to also report humidty + if humidity_out_expected: + results_h = dev.get_humidity(None) + results_h[0]["humidity_pc"] == pytest.approx(humidity_out_expected) From dfc6078952e09f0ec7e1d0d760eab316528ca858 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 8 Nov 2020 23:10:16 +0000 Subject: [PATCH 10/64] Allow pytesting of multiple sensors on one device. --- tests/test_temper.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index afc72cc..b85bc34 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -35,7 +35,7 @@ 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) - 32.1, + [32.1], None, ], [ @@ -45,7 +45,7 @@ 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) - 32.1, + [32.1], None, ], [ @@ -55,8 +55,8 @@ 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x56\x2C\xBF\xB1", # 0x562C,0xBFB1 converts to 12.3C,87.6% (si7021) - 12.3, - 87.6, + [12.3], + [87.6], ], [ "TEMPer1F_H1_V1.4", @@ -65,8 +65,8 @@ 1, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x20\x1A\x0C\x0C", # 0x201A,0x0C0C converts to 32.1C,98.7% (fm75) - 32.1, - 98.7, + [32.1], + [98.7], ], [ "TEMPerNTC1.O", @@ -75,7 +75,7 @@ 3, b"\x01\x80\x33\x01\x00\x00\x00\x00", b"\x00\x00\x20\x1A\x2B\x33\x36\x4D", # 0x201A,0x2B33,0x364D converts to 32.1,43.2,54.3C (fm75) - 32.1, + [32.1, 43.2, 54.3], None, ], # [ @@ -85,7 +85,7 @@ # 1, # b"\x01\x80\x33\x01\x00\x00\x00\x00", # b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) - # 32.1, + # [32.1,43.2], # ], ], ) @@ -146,10 +146,12 @@ def match_pids(find_all, idVendor, idProduct): # read a temperature results = dev.get_temperatures(None) - # check the temperature is what we were expecting. - assert results[0]["temperature_c"] == pytest.approx(temperature_out_expected, 0.01) + for i, temperature in enumerate(temperature_out_expected): + # check the temperature is what we were expecting. + assert results[i]["temperature_c"] == pytest.approx(temperature, 0.01) # if the device is expected to also report humidty if humidity_out_expected: - results_h = dev.get_humidity(None) - results_h[0]["humidity_pc"] == pytest.approx(humidity_out_expected) + for i, humidity in enumerate(humidity_out_expected): + results_h = dev.get_humidity(None) + results_h[i]["humidity_pc"] == pytest.approx(humidity) From 053eb5a2155094afcae11e6d53b08e8776302055 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 8 Nov 2020 23:20:11 +0000 Subject: [PATCH 11/64] clean up and documentation --- tests/test_temper.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index b85bc34..26993b6 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -2,30 +2,28 @@ pytests for temperusb run from the project root with: -pytest --cov=temperusb +pytest --cov=temperusb --cov-report term-missing """ import os - import pytest import usb from unittest.mock import MagicMock, patch, Mock import temperusb - from temperusb.temper import TIMEOUT @pytest.mark.parametrize( [ - "productname", - "vid", - "pid", - "count", - "ctrl_data_in_expected", - "data_out_raw", - "temperature_out_expected", - "humidity_out_expected", + "productname", # the faked usb device product name + "vid", # faked vendor ID + "pid", # faked vendor ID + "count", # number of sensors we are expect to be reported + "ctrl_data_in_expected", # the ctrl data we expect to be sent to the (faked) usb device + "data_out_raw", # the bytes that the usb device will return (our encoded temp/RHs needs to be in here) + "temperature_out_expected", # array of temperatures that we are expecting to see decoded. + "humidity_out_expected", # array of humidities that we are expecting to see decoded ], [ [ @@ -122,7 +120,6 @@ def ctrl_transfer_dummy( timeout=None, side_effect=ctrl_transfer_dummy, ) - # print("usbdev.bus=%s" % usbdev.bus) usbdev.read = Mock(return_value=data_out_raw) def match_pids(find_all, idVendor, idProduct): From 3bc3e566e936d21c78fc1b3185935e346df2f792 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 8 Nov 2020 23:28:37 +0000 Subject: [PATCH 12/64] Add case for generic unmatched sensor (default to 2x temperature) --- tests/test_temper.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index 26993b6..9a71996 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -26,6 +26,16 @@ "humidity_out_expected", # array of humidities that we are expecting to see decoded ], [ + [ + "generic_unmatched", # Default is to assume 2 fm75 style temperature sensors + 0x0C45, + 0x7401, + 2, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) + [32.1, 43.2], + None, + ], [ "TEMPerV1.2", 0x0C45, @@ -76,15 +86,6 @@ [32.1, 43.2, 54.3], None, ], - # [ - # "????", # Has 2 sensors - # 0x0C45, - # 0x7401, - # 1, - # b"\x01\x80\x33\x01\x00\x00\x00\x00", - # b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) - # [32.1,43.2], - # ], ], ) def test_TemperDevice( From b891058e1649073bd7e77fd09c2e373399c8c731 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 10 Nov 2020 11:10:39 +0000 Subject: [PATCH 13/64] Add reminder to restart after adding usb rule. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c4e1162..da287f3 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,8 @@ specific USB devices (with matching VID/PID) by anyone. Install like this: sudo cp etc/99-tempsensor.rules /etc/udev/rules.d/ +Then restart. + To check for success, find the bus and device IDs of the devices like this: pi@raspi-temper1 ~ $ lsusb | grep "0c45:7401" From e1270d40c840b5254d5c575c995ffd787185cb81 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 10 Nov 2020 11:30:47 +0000 Subject: [PATCH 14/64] Add library based configuration for temper-python --- temperusb/device_library.py | 62 +++++++++++++++++++++++++++++++++++++ temperusb/temper.py | 57 +++++++++++++++++----------------- 2 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 temperusb/device_library.py diff --git a/temperusb/device_library.py b/temperusb/device_library.py new file mode 100644 index 0000000..e08f5ec --- /dev/null +++ b/temperusb/device_library.py @@ -0,0 +1,62 @@ +# encoding: utf-8 +# +# TEMPer USB temperature/humidty sensor device driver settings. +# Handles devices reporting themselves as USB VID/PID 0C45:7401 (mine also says +# RDing TEMPerV1.2). +# +# Copyright 2012-2016 Philipp Adelt and contributors. +# +# This code is licensed under the GNU public license (GPL). See LICENSE.md for +# details. + +from enum import Enum + +class TemperType(Enum): + FM75 = 0 + SI7021 = 1 + +class TemperConfig: + def __init__( + self, + temp_sens_offsets: list, + hum_sens_offsets: list = None, + type: TemperType = TemperType.FM75, + ): + self.temp_sens_offsets = temp_sens_offsets + self.hum_sens_offsets = hum_sens_offsets + self.type = type + + +DEVICE_LIBRARY = { + "TEMPerV1.2": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=None, + type=TemperType.FM75, + ), + "TEMPer1F_V1.3": TemperConfig( + # Has only 1 sensor at offset 4 + temp_sens_offsets=[4], + hum_sens_offsets=None, + type=TemperType.FM75, + ), + "TEMPERHUM1V1.3": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=[4], + type=TemperType.SI7021, + ), + "TEMPer1F_H1_V1.4": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=[4], + type=TemperType.FM75, + ), + "TEMPerNTC1.O": TemperConfig( + temp_sens_offsets=[2, 4, 6], + hum_sens_offsets=None, + type=TemperType.FM75, + ), + "generic_fm75": TemperConfig( + temp_sens_offsets=[2, 4], + hum_sens_offsets=None, + type=TemperType.FM75, + ), +} diff --git a/temperusb/temper.py b/temperusb/temper.py index f4911c0..eb5e872 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -14,6 +14,8 @@ import logging import struct +from .device_library import DEVICE_LIBRARY, TemperType, TemperConfig + VIDPIDS = [ (0x0c45, 0x7401), (0x0c45, 0x7402), @@ -33,6 +35,7 @@ 'ini2': b'\x01\x86\xff\x01\x00\x00\x00\x00', } LOGGER = logging.getLogger(__name__) +CONTRIBUTE_URL = "https://github.com/padelt/temper-python/issues" def readattr(path, name): @@ -92,7 +95,7 @@ def __init__(self, device, sensor_count=1): # Try to trigger a USB permission issue early so the # user is not presented with seemingly unrelated error message. # https://github.com/padelt/temper-python/issues/63 - self.lookup_sensor_count() + productname = self._device.product except ValueError as e: if 'langid' in str(e): raise usb.core.USBError("Error reading langids from device. "+ @@ -100,6 +103,21 @@ def __init__(self, device, sensor_count=1): "node for your TEMPer devices can be read and written by the "+ "user running this code. The temperusb README.md contains hints "+ "about how to fix this. Search for 'USB device permissions'.") + + config = DEVICE_LIBRARY.get(productname) + if config is None: + LOGGER.warning( + "Unrecognised sensor type '%s'. " + "Trying to guess communication format. " + "Please add the configuration to 'device_library.py' " + "and submit to %s to benefit other users." + % (self._device.product, CONTRIBUTE_URL) + ) + config = DEVICE_LIBRARY["generic_fm75"] + self.temp_sens_offsets = config.temp_sens_offsets + self.hum_sens_offsets = config.hum_sens_offsets + self.type = config.type + self.set_sensor_count(self.lookup_sensor_count()) LOGGER.debug('Found device | Bus:{0} Ports:{1} SensorCount:{2}'.format( self._bus, self._ports, self._sensor_count)) @@ -138,38 +156,22 @@ def lookup_offset(self, sensor): """ Lookup the number of sensors on the device by product name. """ - if self._device.product == 'TEMPer1F_V1.3': - # Has only 1 sensor, and it's at offset = 4 - return 4 - - # All others follow this pattern - if not, contribute here: https://github.com/padelt/temper-python/issues - # Sensor 0 = Offset 2 - # Sensor 1 = Offset 4 - return (sensor + 1) * 2 + return self.temp_sens_offsets[sensor] def lookup_humidity_offset(self, sensor): """ - Lookup the offset of the humidity data by product name. + Get the the offset of the humidity data. """ - if self._device.product == 'TEMPer1F_H1_V1.4': - # Has only 1 sensor, and the humidity data is at offset = 4 - return 4 - if self._device.product == 'TEMPERHUM1V1.3': - return 4 - return None + if self.hum_sens_offsets: + return self.hum_sens_offsets[sensor] + else: + return None def lookup_sensor_count(self): """ Lookup the number of sensors on the device by product name. """ - if (self._device.product == 'TEMPerV1.2') or \ - (self._device.product == 'TEMPer1F_V1.3') or \ - (self._device.product == 'TEMPERHUM1V1.3') or \ - (self._device.product == 'TEMPer1F_H1_V1.4'): - return 1 - if (self._device.product == 'TEMPerNTC1.O'): return 3 - # All others are two - if not the case, contribute here: https://github.com/padelt/temper-python/issues - return 2 + return len(self.temp_sens_offsets) def get_sensor_count(self): """ @@ -258,8 +260,7 @@ def get_data(self, reset_device=False): # Get humidity LOGGER.debug("ID='%s'" % self._device.product) - if (self._device.product == 'TEMPer1F_H1_V1.4') or \ - (self._device.product == 'TEMPERHUM1V1.3'): + if self.hum_sens_offsets: humidity_data = temp_data else: humidity_data = None @@ -332,7 +333,7 @@ def get_temperatures(self, sensors=None): # Interpret device response for sensor in _sensors: offset = self.lookup_offset(sensor) - if self._device.product == 'TEMPERHUM1V1.3': #si7021 type device. + if self.type == TemperType.SI7021: celsius = struct.unpack_from('>h', data, offset)[0] * 175.72 / 65536 - 46.85 else: # fm75 (?) type device celsius = struct.unpack_from('>h', data, offset)[0] / 256.0 @@ -382,7 +383,7 @@ def get_humidity(self, sensors=None): offset = self.lookup_humidity_offset(sensor) if offset is None: continue - if self._device.product == 'TEMPERHUM1V1.3': #si7021 type device. + if self.type == TemperType.SI7021: humidity = (struct.unpack_from('>H', data, offset)[0] * 125) / 65536 -6 else: #fm75 (?) type device humidity = (struct.unpack_from('>H', data, offset)[0] * 32) / 1000.0 From 0b36a707581a68b4cd9e004721f5a6a1c68f088c Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:47:16 +0000 Subject: [PATCH 15/64] Add support for TEMPer1V1.4 --- temperusb/device_library.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index e08f5ec..6cc5a90 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -54,6 +54,15 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPer1V1.4": TemperConfig( + temp_sens_offsets=[2, 4], + hum_sens_offsets=None, + type=TemperType.FM75, + ), + # The config used if the sensor type is not recognised. + # If your sensor is working but showing as unrecognised, please + # add a new entry above based on "generic_fm75" below, and submit + # a PR to https://github.com/padelt/temper-python/pulls "generic_fm75": TemperConfig( temp_sens_offsets=[2, 4], hum_sens_offsets=None, From d405d460ee19a3cdfb9b5e68e68e10f8e87bb80f Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Wed, 11 Nov 2020 21:48:20 +0000 Subject: [PATCH 16/64] Add support for TEMPer1V1.4 --- temperusb/device_library.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index 6cc5a90..92029db 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -55,7 +55,7 @@ def __init__( type=TemperType.FM75, ), "TEMPer1V1.4": TemperConfig( - temp_sens_offsets=[2, 4], + temp_sens_offsets=[2], hum_sens_offsets=None, type=TemperType.FM75, ), From c5c56734611f21e19a3e6aa5248917e7f22fe957 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Mon, 16 Nov 2020 21:55:26 +0000 Subject: [PATCH 17/64] Add missing assert for humidity test --- tests/test_temper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index 9a71996..808fd0c 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -152,4 +152,4 @@ def match_pids(find_all, idVendor, idProduct): if humidity_out_expected: for i, humidity in enumerate(humidity_out_expected): results_h = dev.get_humidity(None) - results_h[i]["humidity_pc"] == pytest.approx(humidity) + assert results_h[i]["humidity_pc"] == pytest.approx(humidity, 0.1) From 3305f97998cae3cc273ddaf0408367b6f337e564 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Mon, 16 Nov 2020 22:01:08 +0000 Subject: [PATCH 18/64] Add missing assert for humidity test --- tests/test_temper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index 9a71996..808fd0c 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -152,4 +152,4 @@ def match_pids(find_all, idVendor, idProduct): if humidity_out_expected: for i, humidity in enumerate(humidity_out_expected): results_h = dev.get_humidity(None) - results_h[i]["humidity_pc"] == pytest.approx(humidity) + assert results_h[i]["humidity_pc"] == pytest.approx(humidity, 0.1) From 06b8a97b49df39b55d732559efc36c2781ab3bd6 Mon Sep 17 00:00:00 2001 From: Philipp Adelt Date: Tue, 1 Dec 2020 09:35:39 +0100 Subject: [PATCH 19/64] Update changelog --- .gitignore | 1 + CHANGELOG.md | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/.gitignore b/.gitignore index ff49171..3db74a3 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ nosetests.xml # virtualenv _/ +.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md index c30f2f5..e44a6d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,22 @@ All notable changes to this project will be documented in this file. No changes yet. +## [next-1.6.0] + +Major changes: +- A new architecture for supporting different device types. +- Tests using pytest + +### Added +- Add support for 3 sensor tempers and TEMPerNTC1.O +- Add support for TemperHUM with si7021 type sensor +- Add support for TEMPer1V1.4 + +### Fixed +- Fixes for the munin plugin +- Report TEMPerV1.2 devices as having a single sensor +- Fix error message about USB permissions to display correctly on Python 3.6 + ## [1.5.3] - 2017-04-03 - Commit ID: 4da8be1 ### Added - Support for 0c45:7402 (RDing TEMPer1F_H1_V1.4) including humidity From fa32ebefce28239d1f577d5757afdc935e82b861 Mon Sep 17 00:00:00 2001 From: Philipp Adelt Date: Tue, 1 Dec 2020 09:36:02 +0100 Subject: [PATCH 20/64] Bump copyright years --- temperusb/device_library.py | 2 +- temperusb/snmp.py | 2 +- temperusb/temper.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index 92029db..f5b08f9 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -4,7 +4,7 @@ # Handles devices reporting themselves as USB VID/PID 0C45:7401 (mine also says # RDing TEMPerV1.2). # -# Copyright 2012-2016 Philipp Adelt and contributors. +# Copyright 2012-2020 Philipp Adelt and contributors. # # This code is licensed under the GNU public license (GPL). See LICENSE.md for # details. diff --git a/temperusb/snmp.py b/temperusb/snmp.py index 2501dfb..a59ab03 100644 --- a/temperusb/snmp.py +++ b/temperusb/snmp.py @@ -3,7 +3,7 @@ # Run snmp_temper.py as a pass-persist module for NetSNMP. # See README.md for instructions. # -# Copyright 2012-2014 Philipp Adelt +# Copyright 2012-2020 Philipp Adelt # # This code is licensed under the GNU public license (GPL). See LICENSE.md for details. diff --git a/temperusb/temper.py b/temperusb/temper.py index eb5e872..28423e6 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -3,7 +3,7 @@ # Handles devices reporting themselves as USB VID/PID 0C45:7401 (mine also says # RDing TEMPerV1.2). # -# Copyright 2012-2016 Philipp Adelt and contributors. +# Copyright 2012-2020 Philipp Adelt and contributors. # # This code is licensed under the GNU public license (GPL). See LICENSE.md for # details. From 9b3ada176b46549aa9c9ddb36db9a9015fed54cd Mon Sep 17 00:00:00 2001 From: Philipp Adelt Date: Tue, 1 Dec 2020 09:36:33 +0100 Subject: [PATCH 21/64] Fix escapes for regex; fix typo --- temperusb/temper.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/temperusb/temper.py b/temperusb/temper.py index 28423e6..5085cd5 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -25,9 +25,9 @@ INTERFACE = 1 CONFIG_NO = 1 TIMEOUT = 5000 -USB_PORTS_STR = '^\s*(\d+)-(\d+(?:\.\d+)*)' +USB_PORTS_STR = r'^\s*(\d+)-(\d+(?:\.\d+)*)' CALIB_LINE_STR = USB_PORTS_STR +\ - '\s*:\s*scale\s*=\s*([+|-]?\d*\.\d+)\s*,\s*offset\s*=\s*([+|-]?\d*\.\d+)' + r'\s*:\s*scale\s*=\s*([+|-]?\d*\.\d+)\s*,\s*offset\s*=\s*([+|-]?\d*\.\d+)' USB_SYS_PREFIX = '/sys/bus/usb/devices/' COMMANDS = { 'temp': b'\x01\x80\x33\x01\x00\x00\x00\x00', @@ -160,7 +160,7 @@ def lookup_offset(self, sensor): def lookup_humidity_offset(self, sensor): """ - Get the the offset of the humidity data. + Get the offset of the humidity data. """ if self.hum_sens_offsets: return self.hum_sens_offsets[sensor] @@ -234,11 +234,11 @@ def get_data(self, reset_device=False): # does not hurt to explicitly claim the interface. usb.util.claim_interface(self._device, INTERFACE) - # Turns out we don't actually need that ctrl_transfer. - # Disabling this reduces number of USBErrors from ~7/30 to 0! - #self._device.ctrl_transfer(bmRequestType=0x21, bRequest=0x09, - # wValue=0x0201, wIndex=0x00, data_or_wLength='\x01\x01', - # timeout=TIMEOUT) + # Turns out we don't actually need that ctrl_transfer. + # Disabling this reduces number of USBErrors from ~7/30 to 0! + #self._device.ctrl_transfer(bmRequestType=0x21, bRequest=0x09, + # wValue=0x0201, wIndex=0x00, data_or_wLength='\x01\x01', + # timeout=TIMEOUT) # Magic: Our TEMPerV1.4 likes to be asked twice. When From ee093400c412ddebec0ba0433f549a570007b3a2 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 1 Dec 2020 12:48:13 +0000 Subject: [PATCH 22/64] Add davet2001 author. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index da287f3..6d35f8c 100644 --- a/README.md +++ b/README.md @@ -288,3 +288,4 @@ The `snmp_passpersist` mode is Python 2 only because the upstream package is not * Reduced kernel messages, support multiple sensors, and support TEMPer1F_V1.3 by Philip Jay (@ps-jay on Github) * Python 3 compatibility and rewrite of cli.py to use argparse by Will Furnass (@willfurnass on Github) * TEMPerV1.4 support by Christian von Roques (@roques on Github) +* Pytest and archicture improvement by Dave Thompson (@davet2001 on Github). From 38e90a730652edf8ec37a8d3d1f95ad9bae4665a Mon Sep 17 00:00:00 2001 From: Philipp Adelt Date: Tue, 1 Dec 2020 13:51:03 +0100 Subject: [PATCH 23/64] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d35f8c..10ff107 100644 --- a/README.md +++ b/README.md @@ -288,4 +288,4 @@ The `snmp_passpersist` mode is Python 2 only because the upstream package is not * Reduced kernel messages, support multiple sensors, and support TEMPer1F_V1.3 by Philip Jay (@ps-jay on Github) * Python 3 compatibility and rewrite of cli.py to use argparse by Will Furnass (@willfurnass on Github) * TEMPerV1.4 support by Christian von Roques (@roques on Github) -* Pytest and archicture improvement by Dave Thompson (@davet2001 on Github). +* Pytest and architecture improvement by Dave Thompson (@davet2001 on Github). From 728c97740bed34d00e0829cb2d5f8f6f3edf699a Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 1 Dec 2020 22:43:54 +0000 Subject: [PATCH 24/64] Add experimental support for TEMPERHUM1V1.2 --- temperusb/device_library.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index f5b08f9..c6ca090 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -39,6 +39,11 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPERHUM1V1.2": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=[4], + type=TemperType.SI7021, + ), "TEMPERHUM1V1.3": TemperConfig( temp_sens_offsets=[2], hum_sens_offsets=[4], From 49eef7c9fef968dca6879922ae78cb248c2150e4 Mon Sep 17 00:00:00 2001 From: CreativeThings Date: Sun, 7 Feb 2021 23:28:53 +0100 Subject: [PATCH 25/64] Added description for using temper-python with MQTT --- README.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/README.md b/README.md index 10ff107..80d5bf2 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,74 @@ Try running it manually and mimik a passpersist-request (`->` means you should e If you have a problem with the USB side and want to test SNMP, run the script with `--testmode`. +# Using MQTT +While temper-python does not directly support MQTT, it is fairly straightforeward to push the temperature values collected to a MQTT broker periodically, so they may be integrated in for example Home-Assistant. + +In the below example we will show how to push data to a Mosquitto MQTT broker using a small bash script and a CRON job. The setup was tested with temper-python installed on a RaspberryPi running Rasbian Buster and a Mosquitto MQTT broker installed as part of Home-Assistant. + +In this example we will publish one specific temperature value for one specific device, for example the temperatue in Celcius for device 0 +To test this, type on your console: + + $ /usr/local/bin/temper-poll -c -s 0 + 1.9 + +As you can see because of the "-c" option, temper-poll will present a single temperature value in degrees Celcius. To get degrees Farenheit, use option "-f" +The "-s 0" option makes sure temper-poll only looks at Device #0 + +We now need to install the Mosquitto client on the device where you installed temper-python. This will provide the mosquitto_pub client which we will use to push towards the MQTT broker + + sudo apt-get install mosquitto-clients + +To start pushing a value to your MQTT broker, you also need to know the MQTT server IP adress and optionally a username and password. +A mosquitto_pub command looks something like this: + + /usr/bin/mosquitto_pub -h MQTT_IP -m "Some message" -t MQTT_TOPIC -u MQTT_USERNAME -P MQTT_PASSWORD + +If you need more paramaters, have a look at the output of + + mosquitto_pub --help + +If needed, use the "-d" option for mosquitto_pub, which will print debug output about the connection. A successful connection debug print should look like: + + pi@raspberrypi:~ $ /usr/bin/mosquitto_pub -h 10.0.0.* -m "foobar" -t home-assistant/temper_schuur/temperature -u ****** -P ****** -d + Client mosqpub|2107-raspberryp sending CONNECT + Client mosqpub|2107-raspberryp received CONNACK (0) + Client mosqpub|2107-raspberryp sending PUBLISH (d0, q0, r0, m1, 'home-assistant/temper_schuur/temperature', ... (0 bytes)) + Client mosqpub|2107-raspberryp sending DISCONNECT + +We will now combine the two using a small bash script called "temper-push-mqtt". First create the script, then make it executable. + + sudo touch /usr/local/bin/temper-push-mqtt + sudo chmod a+x /usr/local/bin/temper-push-mqtt + sudo nano /usr/local/bin/temper-push-mqtt + +The script should contain: + + #! /bin/bash + T=$(/usr/local/bin/temper-poll -c -s 0) + /usr/bin/mosquitto_pub -h MQTT_IP -m "${T}" -t MQTT_TOPIC -u MQTT_USER -P MQTT_PASSWORD + +If you need other parameters for temper-poll, replace them here. Also replace all MQTT_* values with proper values for you local setup. +If you are using Home-Assistant you should add a sensor to you setup by defining it in configuration.yaml: + + sensor: + - platform: mqtt + name: "Temperatuur Schuur" + state_topic: "home-assistant/temper_schuur/temperature" + unit_of_measurement: "°C" + +Make sure the state_topic value matches the MQTT_TOPIC value in the temper-push-mqtt script + +Finally, to make sure we get periodic data, we create a cron job to run the script every 5 minutes + + sudo crontab -e + +To start a new crontab, which should contain + + */5 * * * * /usr/local/bin/temper-push-mqtt > /var/log/cron_temper-push-mqtt.log 2>&1 + +The above cronjob will run the temper-push-mqtt script every 5 minutes and will log any issues to a logfile /var/log/cron_temper-push-mqtt.log + # Note on multiple device usage The devices I have seen do not have any way to identify them. The serial number is 0. From 7b958dff63d1689d714555bd60f640fc1b80405f Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 4 Mar 2021 11:45:29 +0000 Subject: [PATCH 26/64] Add debug support from commandline. --- temperusb/cli.py | 9 +++++++-- temperusb/temper.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/temperusb/cli.py b/temperusb/cli.py index a8de695..3b3048c 100644 --- a/temperusb/cli.py +++ b/temperusb/cli.py @@ -24,6 +24,8 @@ def parse_args(): "(multisensor devices only)", default='0') parser.add_argument("-S", "--sensor_count", type=int, help="Override auto-detected number of sensors on the device") + parser.add_argument("-v", "--verbose", action='store_true', + help="Verbose: display all debug information") args = parser.parse_args() return args @@ -32,8 +34,11 @@ def parse_args(): def main(): args = parse_args() quiet = args.celsius or args.fahrenheit or args.humidity - - logging.basicConfig(level = logging.ERROR if quiet else logging.WARNING) + debug = args.verbose + lvl = logging.ERROR if quiet else logging.WARNING + if args.verbose: + lvl = logging.DEBUG + logging.basicConfig(level = lvl) th = TemperHandler() devs = th.get_devices() diff --git a/temperusb/temper.py b/temperusb/temper.py index 5085cd5..1d1adbf 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -410,7 +410,7 @@ def _interrupt_read(self): Read data from device. """ data = self._device.read(ENDPOINT, REQ_INT_LEN, timeout=TIMEOUT) - LOGGER.debug('Read data: %r', data) + LOGGER.debug('Read data: %r', ' '.join('{:02x}'.format(x) for x in data)) return data def close(self): From 1318a23c9e7072423f80c13def76a088b347a6a5 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 4 Mar 2021 11:47:20 +0000 Subject: [PATCH 27/64] Remove rendundant line --- temperusb/cli.py | 1 - 1 file changed, 1 deletion(-) diff --git a/temperusb/cli.py b/temperusb/cli.py index 3b3048c..daaa866 100644 --- a/temperusb/cli.py +++ b/temperusb/cli.py @@ -34,7 +34,6 @@ def parse_args(): def main(): args = parse_args() quiet = args.celsius or args.fahrenheit or args.humidity - debug = args.verbose lvl = logging.ERROR if quiet else logging.WARNING if args.verbose: lvl = logging.DEBUG From a2c35d50a56fbc2e568a983f75c4ad953972cbd4 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 4 Mar 2021 12:03:24 +0000 Subject: [PATCH 28/64] Add debug output of unrounded C, RH --- temperusb/temper.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/temperusb/temper.py b/temperusb/temper.py index 1d1adbf..f94cec4 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -339,6 +339,7 @@ def get_temperatures(self, sensors=None): celsius = struct.unpack_from('>h', data, offset)[0] / 256.0 # Apply scaling and offset (if any) celsius = celsius * self._scale + self._offset + LOGGER.debug("T=%.5fC" % celsius) results[sensor] = { 'ports': self.get_ports(), 'bus': self.get_bus(), @@ -387,6 +388,7 @@ def get_humidity(self, sensors=None): humidity = (struct.unpack_from('>H', data, offset)[0] * 125) / 65536 -6 else: #fm75 (?) type device humidity = (struct.unpack_from('>H', data, offset)[0] * 32) / 1000.0 + LOGGER.debug("RH=%.5f%%" % humidity) results[sensor] = { 'ports': self.get_ports(), 'bus': self.get_bus(), From 8f1c494ed6bc20f791583a3ca41a31b34f0269b8 Mon Sep 17 00:00:00 2001 From: endolith Date: Fri, 12 Mar 2021 20:00:19 -0500 Subject: [PATCH 29/64] README: Fix some typos --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 10ff107..ed458df 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ with -p option Found 1 devices Device #0 (bus 1 - port 1.3): 22.4°C 72.3°F -Which tells you there is a a USB hub plugged (internally or externally) on the port 1 of the bus 1 of the host, and your TEMPer device is on the port 3 of that hub. +Which tells you there is a USB hub plugged (internally or externally) on the port 1 of the bus 1 of the host, and your TEMPer device is on the port 3 of that hub. ## Tell kernel to leave TEMPer alone @@ -127,13 +127,13 @@ along with `snmpd`. ## What to add to snmpd.conf To emulate an APC Battery/Internal temperature value, add something like this to snmpd.conf. -The highest of all measured temperatures in degrees celcius as an integer is reported. +The highest of all measured temperatures in degrees Celsius as an integer is reported. pass_persist .1.3.6.1.4.1.318.1.1.1.2.2.2 /usr/local/bin/temper-snmp Alternatively, emulate a Cisco device's temperature information with the following. The first three detected devices will be reported as ..13.1.3.1.3.1, ..3.2 and ..3.3 . -The value is the temperature in degree celcius as an integer. +The value is the temperature in degree Celsius as an integer. pass_persist .1.3.6.1.4.1.9.9.13.1.3 /usr/local/bin/temper-snmp @@ -213,7 +213,7 @@ any plugging on the device. Even then, you are not safe. Sorry. ## Note by GM3D -Since calibration parameters must be set per each device, we need some way to identify them physically. As mentioned above, the serial number for all TEMPer devices is zero, so there is no true way to tell which is which programatically. The USB device number does not work either since it changes every time you reboot the machine or plug/unplug the device. The way that possibly can work is identifying them by the combination of the bus number and the USB port (possibly a chain of ports, if you have hubs in between), which is what I am doing for now. +Since calibration parameters must be set per each device, we need some way to identify them physically. As mentioned above, the serial number for all TEMPer devices is zero, so there is no true way to tell which is which programmatically. The USB device number does not work either since it changes every time you reboot the machine or plug/unplug the device. The way that possibly can work is identifying them by the combination of the bus number and the USB port (possibly a chain of ports, if you have hubs in between), which is what I am doing for now. This information is basically the same with what you can get with `lsusb -t` and is based on the information in the sysfs directory `/sys/bus/usb/devices` (see below). So far I am assuming this scheme is persistent enough for regular use cases, but even the bus number may change in some cases like - for example - if your machine is a tablet like machine and you hotplug it to a keyboard dock with a USB root hub in it. In such case you will need to re-run `lsusb` and adjust the bus-port numbers in the configuration file accordingly. At the moment I have no clue about SNMP OID persistence. From 3d3805905fb780b5c4eadef46878fa3234aaeb2d Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 13 May 2021 21:34:35 +0100 Subject: [PATCH 30/64] Support TEMPer2V1.4 based on #108 --- temperusb/device_library.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index f5b08f9..edab467 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -59,6 +59,11 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPer2V1.4": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=None, + type=TemperType.FM75, + ), # The config used if the sensor type is not recognised. # If your sensor is working but showing as unrecognised, please # add a new entry above based on "generic_fm75" below, and submit From 395464ac824918c83f75830cb26e8a11787e3852 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 4 Jul 2021 21:11:29 +0000 Subject: [PATCH 31/64] Add support for TEMPerV1.4 including tests --- temperusb/device_library.py | 5 +++++ tests/test_temper.py | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index f5b08f9..964cd22 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -33,6 +33,11 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPerV1.4": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=None, + type=TemperType.FM75, + ), "TEMPer1F_V1.3": TemperConfig( # Has only 1 sensor at offset 4 temp_sens_offsets=[4], diff --git a/tests/test_temper.py b/tests/test_temper.py index 808fd0c..a33b8c2 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -19,9 +19,9 @@ "productname", # the faked usb device product name "vid", # faked vendor ID "pid", # faked vendor ID - "count", # number of sensors we are expect to be reported + "count", # number of sensors we expect to be reported "ctrl_data_in_expected", # the ctrl data we expect to be sent to the (faked) usb device - "data_out_raw", # the bytes that the usb device will return (our encoded temp/RHs needs to be in here) + "data_out_raw", # the bytes that the usb device will return (our encoded temps/RHs need to be in here) "temperature_out_expected", # array of temperatures that we are expecting to see decoded. "humidity_out_expected", # array of humidities that we are expecting to see decoded ], @@ -46,6 +46,16 @@ [32.1], None, ], + [ + "TEMPerV1.4", + 0x0C45, + 0x7401, + 1, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A", # 0x201A converts to 32.1C (fm75) + [32.1], + None, + ], [ "TEMPer1F_V1.3", # Has 1 sensor at offset 4 0x0C45, From f955e69c185a61f89bbb457f2dbc0a1da8b9216c Mon Sep 17 00:00:00 2001 From: James Stewart Date: Wed, 3 Nov 2021 21:51:52 +1100 Subject: [PATCH 32/64] Release 1.6.0 --- CHANGELOG.md | 5 ++--- setup.py | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e44a6d1..0ee86c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,8 @@ All notable changes to this project will be documented in this file. No changes yet. -## [next-1.6.0] - -Major changes: +## [1.6.0] +### Added - A new architecture for supporting different device types. - Tests using pytest diff --git a/setup.py b/setup.py index 38fc466..4360b85 100644 --- a/setup.py +++ b/setup.py @@ -6,9 +6,10 @@ author='Philipp Adelt', author_email='autosort-github@philipp.adelt.net ', url='https://github.com/padelt/temper-python', - version='1.5.3', + version='1.6.0', description='Reads temperature from TEMPerV1 devices (USB 0c45:7401)', long_description=open('README.md', encoding='utf-8').read(), + long_description_content_type='text/markdown', packages=['temperusb'], install_requires=[ 'pyusb>=1.0.0rc1', From 7d101acc6eace3cafb4f15b9f81b4c28bb7f3d42 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 2 Dec 2021 20:01:55 +0000 Subject: [PATCH 33/64] Add support for TEMPer2V1.3 --- temperusb/device_library.py | 5 +++++ tests/test_temper.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index f5b08f9..1bcaf74 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -28,6 +28,11 @@ def __init__( DEVICE_LIBRARY = { + "TEMPer2V1.3": TemperConfig( + temp_sens_offsets=[2, 4], + hum_sens_offsets=None, + type=TemperType.FM75, + ), "TEMPerV1.2": TemperConfig( temp_sens_offsets=[2], hum_sens_offsets=None, diff --git a/tests/test_temper.py b/tests/test_temper.py index 808fd0c..a1a7c13 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -36,6 +36,16 @@ [32.1, 43.2], None, ], + [ + 'TEMPer2V1.3', + 0x0c45, + 0x7401, + 2, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x80\x04\x0a\xe0\x15\x00\x1d\x15", # 0x0AE0, 0x1500 converts to 10.9C, 21.0C (fm75) + [10.9, 21.0], + None, + ], [ "TEMPerV1.2", 0x0C45, From 47cfa55abca180e96448829feffd9e9fcea873f7 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 2 Dec 2021 20:07:30 +0000 Subject: [PATCH 34/64] Print the output for each sensor. --- temperusb/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temperusb/cli.py b/temperusb/cli.py index a8de695..e2a8942 100644 --- a/temperusb/cli.py +++ b/temperusb/cli.py @@ -99,7 +99,7 @@ def main(): huminfo = huminfo[0:len(output) - 2] output = 'Device #%i%s: %s %s' % (i, portinfo, tempinfo, huminfo) - print(output) + print(output) if __name__ == '__main__': From 3fc73253b355ce8eade0d19be28c725f01494fa9 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 2 Dec 2021 20:10:59 +0000 Subject: [PATCH 35/64] Revert print change. --- temperusb/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temperusb/cli.py b/temperusb/cli.py index e2a8942..a8de695 100644 --- a/temperusb/cli.py +++ b/temperusb/cli.py @@ -99,7 +99,7 @@ def main(): huminfo = huminfo[0:len(output) - 2] output = 'Device #%i%s: %s %s' % (i, portinfo, tempinfo, huminfo) - print(output) + print(output) if __name__ == '__main__': From 6f44d58ee010d179d352e79daf58b28de3c76090 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 4 Dec 2021 08:52:07 +0000 Subject: [PATCH 36/64] Add continuous integration --- .github/workflows/ci.yml | 23 +++++++++++++++++++++++ requirements_test.txt | 3 +++ 2 files changed, 26 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 requirements_test.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..598d303 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,23 @@ +name: CI + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements_test.txt + - name: Run unit tests + run: python -m pytest --import-mode=append tests/ + diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..3d2b9eb --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1,3 @@ +# Dependencies for running tests. +pytest +pyusb From f83aa0d20f77c26e37a396daddbfdd3875dd8851 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 4 Dec 2021 09:26:04 +0000 Subject: [PATCH 37/64] Test more python versions --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 598d303..6132299 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} From c334c5d50d70ab6122481a0bb8b077e1c4128ae5 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 4 Dec 2021 09:29:28 +0000 Subject: [PATCH 38/64] Test back to 3.5 but not 2.7 which fails --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6132299..a39d35b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} From e49a707fa4fdcfc554aaf402192372ecb2f9b6c1 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 4 Dec 2021 09:36:11 +0000 Subject: [PATCH 39/64] Update compatible python versions --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 387e7ca..1679628 100644 --- a/README.md +++ b/README.md @@ -343,8 +343,7 @@ as seen on [Google+](https://plus.google.com/105569853186899442987/posts/N9T7xAj # Compatibility with Python versions -This should work on both Python 2 and 3. It was tested with Python 2.7.3 and 3.2.3. -The `snmp_passpersist` mode is Python 2 only because the upstream package is not ready yet. +This should work on Python 3.5 and above. It was tested with Python 3.5, 3.6, 3.7, 3.8, 3.9, 3.10. # Authors From 48cd4086dd18c84300043dd04e3e69598919118c Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 4 Dec 2021 09:46:00 +0000 Subject: [PATCH 40/64] Add pip as an installation method --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1679628..43f547f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,11 @@ Under Debian/Ubuntu, treat yourself to some package goodness: # Installation and usage -Clone the repository, cd into its top-level directory, and run +To install using pip, run + + pip install temperusb + +To install from source, clone the repository, cd into its top-level directory, and run sudo python setup.py install From aa8d87c0c2809ed6b678e26d4e034398875193d4 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sat, 4 Dec 2021 09:52:59 +0000 Subject: [PATCH 41/64] Run CI on PR, not just on push --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a39d35b..bf86d52 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI -on: [push] +on: [push, pull_request] jobs: build: From 308c97b8634fb024fd75f299255b18166a0193cd Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Mon, 18 Apr 2022 18:10:28 +0100 Subject: [PATCH 42/64] Support TEMPerHumiV1.1 Add support for TEMPerHumiV1.1 Thank you @bjornenki --- temperusb/device_library.py | 5 +++++ tests/test_temper.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index 598065f..ddeb5e3 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -59,6 +59,11 @@ def __init__( hum_sens_offsets=[4], type=TemperType.SI7021, ), + "TEMPerHumiV1.1": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=[4], + type=TemperType.FM75, + ), "TEMPer1F_H1_V1.4": TemperConfig( temp_sens_offsets=[2], hum_sens_offsets=[4], diff --git a/tests/test_temper.py b/tests/test_temper.py index 8efce6e..9b239aa 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -96,6 +96,16 @@ [32.1], [98.7], ], + [ + "TEMPer1F_H1_V1.4", + 0x0C45, + 0x7401, + 1, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A\x0C\x0C", # 0x201A,0x0C0C converts to 32.1C,98.7% (fm75) + [32.1], + [98.7], + ], [ "TEMPerNTC1.O", 0x0C45, From 948e8cf86e478d6be0a7ae58d9ab6de79a44ccdc Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Mon, 18 Apr 2022 18:15:57 +0100 Subject: [PATCH 43/64] Fix test for TEMPerHumiV1.1 --- tests/test_temper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_temper.py b/tests/test_temper.py index 9b239aa..58e5222 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -87,7 +87,7 @@ [87.6], ], [ - "TEMPer1F_H1_V1.4", + "TEMPerHumiV1.1", 0x0C45, 0x7401, 1, From 9ce631b4d1f4cfc2a64c97127fb79edcedb741f3 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 21 Apr 2022 20:09:19 +0000 Subject: [PATCH 44/64] Support TEMPerHumiV1.0 --- temperusb/device_library.py | 5 +++++ tests/test_temper.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index ddeb5e3..f6969f8 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -59,6 +59,11 @@ def __init__( hum_sens_offsets=[4], type=TemperType.SI7021, ), + "TEMPerHumiV1.0": TemperConfig( + temp_sens_offsets=[2], + hum_sens_offsets=[4], + type=TemperType.FM75, + ), "TEMPerHumiV1.1": TemperConfig( temp_sens_offsets=[2], hum_sens_offsets=[4], diff --git a/tests/test_temper.py b/tests/test_temper.py index 58e5222..408269a 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -86,6 +86,16 @@ [12.3], [87.6], ], + [ + "TEMPerHumiV1.0", + 0x0C45, + 0x7401, + 1, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A\x0C\x0C", # 0x201A,0x0C0C converts to 32.1C,98.7% (fm75) + [32.1], + [98.7], + ], [ "TEMPerHumiV1.1", 0x0C45, From 99835b68c8488a10b5295b822aa345dcd4d16f31 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 2 May 2023 22:27:11 +0100 Subject: [PATCH 45/64] Drop old python <3.7, add 3.11 to CI tests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf86d52..484473f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} From df1fead5b309912765b7e752fd51a06204f59df6 Mon Sep 17 00:00:00 2001 From: Dave T Date: Tue, 2 May 2023 21:12:46 +0000 Subject: [PATCH 46/64] Add experimental support for TEMPer2_V3.7 --- temperusb/device_library.py | 5 +++++ temperusb/temper.py | 1 + 2 files changed, 6 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index f6969f8..2d2bc4c 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -84,6 +84,11 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPer2_V3.7": TemperConfig( + temp_sens_offsets=[2, 10], + hum_sens_offsets=None, + type=TemperType.FM75, + ), "TEMPer2V1.4": TemperConfig( temp_sens_offsets=[2], hum_sens_offsets=None, diff --git a/temperusb/temper.py b/temperusb/temper.py index f94cec4..dcfc965 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -19,6 +19,7 @@ VIDPIDS = [ (0x0c45, 0x7401), (0x0c45, 0x7402), + (0x1a86, 0xe025), ] REQ_INT_LEN = 8 ENDPOINT = 0x82 From d4a75051a2adeedd24d19f444ebd1d2c6ad01136 Mon Sep 17 00:00:00 2001 From: Dave T Date: Mon, 8 May 2023 09:57:29 +0000 Subject: [PATCH 47/64] Update permissions rule for new sensor id --- etc/99-tempsensor.rules | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/99-tempsensor.rules b/etc/99-tempsensor.rules index 037a343..6a8986d 100644 --- a/etc/99-tempsensor.rules +++ b/etc/99-tempsensor.rules @@ -1,2 +1,3 @@ SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7401", MODE="666" SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7402", MODE="666" +SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="e025", MODE="666" From 19dd9f88ebde56da626df0cabe0536e6ec8d87e7 Mon Sep 17 00:00:00 2001 From: Philipp Born Date: Sun, 18 Jun 2023 15:44:05 +0200 Subject: [PATCH 48/64] feat(TemperDevice): add get_product function Signed-off-by: Philipp Born --- temperusb/temper.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/temperusb/temper.py b/temperusb/temper.py index dcfc965..d8c77a6 100644 --- a/temperusb/temper.py +++ b/temperusb/temper.py @@ -194,6 +194,12 @@ def set_sensor_count(self, count): self._sensor_count = int(count) + def get_product(self): + """ + Get device product name. + """ + return self._device.product + def get_ports(self): """ Get device USB ports. From 7043ba9ce0713c7cba34d4df0568d2c464e6ed03 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:16:02 +0000 Subject: [PATCH 49/64] Add python 3.12 to tests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf86d52..f32f342 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.12"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} From 403bb0e82f674523aea7e563f5782790a49d3b8b Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:17:44 +0000 Subject: [PATCH 50/64] Add python 3.11 to tests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f32f342..26d35e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.12"] + python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} From 63e48f9ef628215b1172a3bc2fac39820c2f0753 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:37:47 +0000 Subject: [PATCH 51/64] Update compatible python versions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43f547f..b9901ca 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,7 @@ as seen on [Google+](https://plus.google.com/105569853186899442987/posts/N9T7xAj # Compatibility with Python versions -This should work on Python 3.5 and above. It was tested with Python 3.5, 3.6, 3.7, 3.8, 3.9, 3.10. +This should work on Python 3.7 and above. It was tested with Python 3.7, 3.8, 3.9, 3.10, 3.11, 3.12. # Authors From 8a86428fe46ad3bbae993f38584aa6bcef9121f1 Mon Sep 17 00:00:00 2001 From: Dave T Date: Tue, 2 May 2023 21:44:57 +0000 Subject: [PATCH 52/64] Add support for devcontainer development --- .devcontainer/Dockerfile | 22 +++++++++++++++++ .devcontainer/devcontainer.json | 43 +++++++++++++++++++++++++++++++++ .vscode/settings.json | 10 ++++++++ etc/99-tempsensor.rules | 1 - 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .vscode/settings.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..5e3b9e7 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,22 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.145.1/containers/python-3/.devcontainer/base.Dockerfile + +# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6 +ARG VARIANT="3" +FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} + +# [Option] Install Node.js +ARG INSTALL_NODE="true" +ARG NODE_VERSION="lts/*" +RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image. +# COPY requirements.txt /tmp/pip-tmp/ +# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ +# && rm -rf /tmp/pip-tmp + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..581e30a --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,43 @@ +{ + "name": "Python 3", + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "args": { + // Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9 + "VARIANT": "3", + // Options + "INSTALL_NODE": "false", + "NODE_VERSION": "lts/*" + } + }, + "containerEnv": { + "PYTHONPATH": "." + }, + // Set *default* container specific settings.json values on container create. + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + "python.pythonPath": "/usr/local/bin/python", + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", + "python.formatting.blackPath": "/usr/local/py-utils/bin/black", + "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", + "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", + "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", + "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", + "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", + "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", + "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-python.python" + ] + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "pip3 install --user -r requirements.txt", + // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. + // "remoteUser": "vscode" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..77694e9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "python.envFile": "${workspaceFolder}/.env", + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.nosetestsEnabled": false, + "python.testing.pytestEnabled": true, + "python.pythonPath": "/usr/local/bin/python", +} \ No newline at end of file diff --git a/etc/99-tempsensor.rules b/etc/99-tempsensor.rules index 6a8986d..037a343 100644 --- a/etc/99-tempsensor.rules +++ b/etc/99-tempsensor.rules @@ -1,3 +1,2 @@ SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7401", MODE="666" SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7402", MODE="666" -SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="e025", MODE="666" From e2a2c4e61a19bab5ddeb2eb54f7ac5b9e08b294e Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:48:29 +0000 Subject: [PATCH 53/64] Update devcontainer spec using newer template --- .devcontainer/devcontainer.json | 55 ++++++++++----------------------- requirements.txt | 1 + requirements_test.txt | 4 +-- tests/__init__.py | 0 4 files changed, 20 insertions(+), 40 deletions(-) create mode 100644 requirements.txt create mode 100644 tests/__init__.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 581e30a..2babca0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,43 +1,22 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/python { "name": "Python 3", - "build": { - "dockerfile": "Dockerfile", - "context": "..", - "args": { - // Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9 - "VARIANT": "3", - // Options - "INSTALL_NODE": "false", - "NODE_VERSION": "lts/*" - } - }, - "containerEnv": { - "PYTHONPATH": "." - }, - // Set *default* container specific settings.json values on container create. - "settings": { - "terminal.integrated.shell.linux": "/bin/bash", - "python.pythonPath": "/usr/local/bin/python", - "python.linting.enabled": true, - "python.linting.pylintEnabled": true, - "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", - "python.formatting.blackPath": "/usr/local/py-utils/bin/black", - "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", - "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", - "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", - "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", - "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", - "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", - "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" - }, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "ms-python.python" - ] + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye", + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "pip3 install --user -r requirements.txt", - // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. - // "remoteUser": "vscode" -} \ No newline at end of file + "postCreateCommand": "pip3 install --user -r requirements.txt -r requirements_test.txt", + + // Configure tool-specific properties. + "customizations": {} + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4f21f91 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pyusb==1.2.1 \ No newline at end of file diff --git a/requirements_test.txt b/requirements_test.txt index 3d2b9eb..448d54c 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,3 +1,3 @@ # Dependencies for running tests. -pytest -pyusb +pytest>=7.4.3 + diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 From eb048f87eae9ede97167ffe055ffd6f773d30a2b Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:49:48 +0000 Subject: [PATCH 54/64] Remove unnecessary dockerfile --- .devcontainer/Dockerfile | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 5e3b9e7..0000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.145.1/containers/python-3/.devcontainer/base.Dockerfile - -# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6 -ARG VARIANT="3" -FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} - -# [Option] Install Node.js -ARG INSTALL_NODE="true" -ARG NODE_VERSION="lts/*" -RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi - -# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image. -# COPY requirements.txt /tmp/pip-tmp/ -# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ -# && rm -rf /tmp/pip-tmp - -# [Optional] Uncomment this section to install additional OS packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends - -# [Optional] Uncomment this line to install global node packages. -# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 \ No newline at end of file From 87d89a083c77a45b26c561c1c9112dba47c4ed98 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:51:28 +0000 Subject: [PATCH 55/64] Update 99-tempsensor.rules --- etc/99-tempsensor.rules | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/99-tempsensor.rules b/etc/99-tempsensor.rules index 037a343..6a8986d 100644 --- a/etc/99-tempsensor.rules +++ b/etc/99-tempsensor.rules @@ -1,2 +1,3 @@ SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7401", MODE="666" SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7402", MODE="666" +SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="e025", MODE="666" From 84ed9dfe1e14c701506d8074c0176e02b4169633 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:54:55 +0000 Subject: [PATCH 56/64] Add pyusb to test requirements. --- requirements.txt | 2 +- requirements_test.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 4f21f91..7e2effa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -pyusb==1.2.1 \ No newline at end of file +pyusb==1.2.1 diff --git a/requirements_test.txt b/requirements_test.txt index 448d54c..8900955 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,3 +1,4 @@ # Dependencies for running tests. -pytest>=7.4.3 +pyusb==1.2.1 +pytest==7.4.3 From 441ab3104cf0829b74ee2754eb59c9d547f36a56 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 20:53:35 +0000 Subject: [PATCH 57/64] Modify devcontainer to give access to usb devices --- .devcontainer/Dockerfile | 5 +++++ .devcontainer/devcontainer.json | 16 +++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..41fcd25 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/devcontainers/base:alpine-3.18 + +RUN apk add --no-cache \ + libusb=1.0.26-r2 \ + py3-pip=23.1.2-r0 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2babca0..3c46125 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,9 +1,12 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/python +// README at: https://github.com/devcontainers/templates/tree/main/src/alpine { - "name": "Python 3", + "name": "Python Alpine", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, @@ -14,9 +17,12 @@ // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "pip3 install --user -r requirements.txt -r requirements_test.txt", + // Priviledged mode is necessary to get access to usb + "runArgs": ["--privileged"] + // Configure tool-specific properties. - "customizations": {} + // "customizations": {}, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" + //"remoteUser": "root" } From e3e10e8148176679f81c562e7bbefb3ebed42843 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:44:41 +0000 Subject: [PATCH 58/64] Update CHANGELOG.md --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ee86c2..07a6bc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,16 @@ All notable changes to this project will be documented in this file. No changes yet. -## [1.6.0] +## [1.6.1] - 2023-12-19 +### Added +- Support for for TEMPer2V1.3 +- Support for TEMPerHumiV1.1 +- Support for TEMPerHumiV1.0 +- Experimental support for TEMPer2_V3.7 +- get_product() function to get product name +- Updates to documentation + +## [1.6.0] - 2021-11-03 ### Added - A new architecture for supporting different device types. - Tests using pytest From 08cafca21b7b209157dce08bdd1c95b0c8a00188 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Tue, 19 Dec 2023 21:05:22 +0000 Subject: [PATCH 59/64] Update version info --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4360b85..b1cb6c9 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ author='Philipp Adelt', author_email='autosort-github@philipp.adelt.net ', url='https://github.com/padelt/temper-python', - version='1.6.0', + version='1.6.1', description='Reads temperature from TEMPerV1 devices (USB 0c45:7401)', long_description=open('README.md', encoding='utf-8').read(), long_description_content_type='text/markdown', @@ -24,7 +24,6 @@ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', - 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', ], ) From d30bf8b4c072bfc6d66e56a360f11853ccaf6b3d Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 21 Dec 2023 22:14:35 +0000 Subject: [PATCH 60/64] Add publish script --- .devcontainer/devcontainer.json | 7 ++++++- scripts/publish_to_pypi.sh | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100755 scripts/publish_to_pypi.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3c46125..b8c8fea 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,11 +18,16 @@ "postCreateCommand": "pip3 install --user -r requirements.txt -r requirements_test.txt", // Priviledged mode is necessary to get access to usb - "runArgs": ["--privileged"] + "runArgs": ["--privileged"], // Configure tool-specific properties. // "customizations": {}, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. //"remoteUser": "root" + + // Access local .pypi api keys + "mounts": [ + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.pypirc,target=/home/vscode/.pypirc,type=bind,consistency=cached" + ] } diff --git a/scripts/publish_to_pypi.sh b/scripts/publish_to_pypi.sh new file mode 100755 index 0000000..3d1b860 --- /dev/null +++ b/scripts/publish_to_pypi.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Script to automate publishing to pypi +# Dave T 2023-12-21 +pypi_config_file=~/.pypirc + +pip install twine + +if [ ! -f dist/*.tar.gz ]; then + echo "No releases found. Please run python3 -m setup.py sdist" + exit +fi +twine check dist/* + +echo "Ready to publish." +echo "Default is publishing to testpypi." +read -r -p "If you are fully ready, please publish to pypi by typing 'thisisnotatest': " response +echo "response=$response" +if [ "$response" = "thisisnotatest" ]; then + repository=pypi +else + repository=testpypi +fi + +if [ -f $pypi_config_file ]; then + echo "Using $pypi_config_file for API keys" +else + echo "$pypi_config_file not found, please paste pypi API token below:" + read twine_api_key + export TWINE_USERNAME=__token__ + export TWINE_PASSWORD=$twine_api_key +fi +echo "Publishing to $repository..." +twine upload --repository $repository dist/* +echo "Publishing complete!" +echo +echo "Don't forget to tag this release!" \ No newline at end of file From 75d356ed4ea348ff1d61365d43dffa6aa6078725 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 21 Dec 2023 22:20:30 +0000 Subject: [PATCH 61/64] Correct typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07a6bc0..155de48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ No changes yet. ## [1.6.1] - 2023-12-19 ### Added -- Support for for TEMPer2V1.3 +- Support for TEMPer2V1.3 - Support for TEMPerHumiV1.1 - Support for TEMPerHumiV1.0 - Experimental support for TEMPer2_V3.7 From 7a26fd21806a434bbe81495173b1d1cfccbe6fd2 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 18 Aug 2024 21:30:46 +0100 Subject: [PATCH 62/64] Add new sensor TEMPer2_M12_V1.3 --- temperusb/device_library.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index 2d2bc4c..d1f0b26 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -84,6 +84,11 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPer2_M12_V1.3": TemperConfig( + temp_sens_offsets=[2, 4], + hum_sens_offsets=None, + type=TemperType.FM75, + ), "TEMPer2_V3.7": TemperConfig( temp_sens_offsets=[2, 10], hum_sens_offsets=None, From 7638c7e7bec83f841957bc4875b7567a3002a289 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 9 Jan 2025 22:58:06 +0000 Subject: [PATCH 63/64] Support python 3.13, drop 3.7 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f32ca9..355f7c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} diff --git a/README.md b/README.md index b9901ca..ea57c0d 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,7 @@ as seen on [Google+](https://plus.google.com/105569853186899442987/posts/N9T7xAj # Compatibility with Python versions -This should work on Python 3.7 and above. It was tested with Python 3.7, 3.8, 3.9, 3.10, 3.11, 3.12. +This should work on Python 3.8 and above. It was tested with Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13. # Authors From 6a47e0a09337727c452ef4681e6bd7b295f66695 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Thu, 9 Jan 2025 22:52:13 +0000 Subject: [PATCH 64/64] Add TEMPer2_M12_V1.3 --- temperusb/device_library.py | 5 +++++ tests/test_temper.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index d1f0b26..90cdebb 100644 --- a/temperusb/device_library.py +++ b/temperusb/device_library.py @@ -99,6 +99,11 @@ def __init__( hum_sens_offsets=None, type=TemperType.FM75, ), + "TEMPer2_M12_V1.3": TemperConfig( + temp_sens_offsets=[2, 4], + hum_sens_offsets=None, + type=TemperType.FM75, + ), # The config used if the sensor type is not recognised. # If your sensor is working but showing as unrecognised, please # add a new entry above based on "generic_fm75" below, and submit diff --git a/tests/test_temper.py b/tests/test_temper.py index 408269a..e0c8a59 100644 --- a/tests/test_temper.py +++ b/tests/test_temper.py @@ -66,6 +66,16 @@ [32.1], None, ], + [ + "TEMPer2_M12_V1.3", + 0x0C45, + 0x7401, + 2, + b"\x01\x80\x33\x01\x00\x00\x00\x00", + b"\x00\x00\x20\x1A\x2B\x33", # 0x201A,0x2B33 converts to 32.1C, 43.2C (fm75) + [32.1, 43.2], + None, + ], [ "TEMPer1F_V1.3", # Has 1 sensor at offset 4 0x0C45,