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 new file mode 100644 index 0000000..b8c8fea --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/alpine +{ + "name": "Python Alpine", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + + // 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 -r requirements_test.txt", + + // Priviledged mode is necessary to get access to usb + "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/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..355f7c5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,23 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + 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 }} + 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/.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/CHANGELOG.md b/CHANGELOG.md index 0ee86c2..155de48 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 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 diff --git a/README.md b/README.md index 387e7ca..ea57c0d 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 @@ -343,8 +347,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.8 and above. It was tested with Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13. # Authors 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" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7e2effa --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pyusb==1.2.1 diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..8900955 --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1,4 @@ +# Dependencies for running tests. +pyusb==1.2.1 +pytest==7.4.3 + 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 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', ], ) diff --git a/temperusb/device_library.py b/temperusb/device_library.py index 2e92346..90cdebb 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, @@ -54,6 +59,16 @@ 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], + type=TemperType.FM75, + ), "TEMPer1F_H1_V1.4": TemperConfig( temp_sens_offsets=[2], hum_sens_offsets=[4], @@ -69,11 +84,26 @@ 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, + type=TemperType.FM75, + ), "TEMPer2V1.4": TemperConfig( temp_sens_offsets=[2], 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/temperusb/temper.py b/temperusb/temper.py index f94cec4..d8c77a6 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 @@ -193,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. diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_temper.py b/tests/test_temper.py index a33b8c2..e0c8a59 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, @@ -56,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, @@ -76,6 +96,26 @@ [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, + 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], + ], [ "TEMPer1F_H1_V1.4", 0x0C45,