Code Monkey home page Code Monkey logo

temper's Introduction

temper.py

The USB temperature and temperature/humidity sensors sold by PCsensor are widely available from the parent site (http://pcsensor.com/usb-temperature-humidity.html), from Amazon, and from EBay.

Note

NOTE: Please submit all pull requests to https://github.com/ccwienk/temper

The repository at https://github.com/urwen/temper is not well maintained.

urwen has rebased to ccwienk/temper and encourages you to support Christian Cwienk's efforts to maintain temper -- with urwen's profound thanks and gratitude!

Design

There are several open source software projects that support these sensors, sometimes including complicated monitoring and graphing software. Unlike, these projects, the goal of this project is to simply read data from the sensors and do nothing else, given the following constraints:

  • must work under Linux,
  • must work with Python 3,
  • third-party software will be avoided when possible,
  • all third-party software must be provided as standard Debian packages.

libusb is not used

I tried to use libusb (apt-get install python3-usb; "import usb.core") and it provides a sophisticated interface to USB devices that was very nice. Unfortunately, I have one thermometer that didn't work with raw usb and that required access via the hidraw device; and I have another thermometer that has an undocumented HID protocol, but that is accessible via a serial tty.

hid and hidapi are not used

I tried using hid (apt-get install python3-hid) and hidapi (apt-get install python3-hidapi) and these worked ok for two of the thermometers I have, but not for the one that requires access via a serial tty.

pySerial is used

Although HID devices are accessed directly, pySerial is used for TTYs. This module is available as a Debian package: sudo apt-get install python3-serial

Supported Devices

I own five kinds of devices from PCsensors. These are all supported by temper.py.

In the following table "I" means the sensor is internal to the USB stick and "E" means the sensor is on a cable that is plugged into the USB stick.

Product Id Firmware Temp Hum Notes
TEMPer 0c45:7401 TEMPerF1.2 I Metal
TEMPer 0c45:7401 TEMPerF1.4 I Metal
TEMPer 413d:2107 TEMPerGold_V3.1 I Metal
TEMPer 1a86:e025 TEMPerGold_V3.3 I Metal
TEMPer 1a86:e025 TEMPerGold_V3.4 I Metal
TEMPerHUM 413d:2107 TEMPerX_V3.1 I I White plastic
TEMPerHUM 1a86:e025 TEMPerHUM_3.9 I White plastic with blue button
TEMPerHUM 0c45:7402 TEMPer1F_H1V1.5F I I White plastic with blue button
TEMPer2 413d:2107 TEMPerX_V3.3 I,E White plastic
TEMPer2 1a86:e025 TEMPer2_V3.7 I,E White plastic with red button
TEMPer2 1a86:e025 TEMPer2_V3.9 I,E White plastic with red button
TEMPer2 1a86:e025 TEMPer2_M12_V1.3 I,E White plastic with red button
TEMPer1F 413d:2107 TEMPerX_V3.3 E White plastic
TEMPerX232 1a86:5523 TEMPerX232_V2.0 I,E I White plastic
TEMPer1V1.1 0c45:7401 TEMPer1F1.1Per1F E Metal

The 1a86:5523 device may identify as 413d:2107 depending on button presses, but it cannot be used successfully when in that mode.

If you try other software that uses libusb, the hidraw device may be disconnected. In this case, remove and re-insert the USB stick.

The TEMPer1F has only an external sensor, but it is not possible to detect that it is external, so it is reported as an internal temperature.

TEMPer

This is a metal USB stick marked "TEMPer" with thermometer logo on one side, and "TEMPer" on the other side. The end opposite the USB connector has a screw hole. There is no humidity detector, but it appears water proof and I have submerged mine momentarily in ice water and in boiling water.

TEMPerHUM

This is a white plastic USB stick marked "TEMPerHUM", "-40C - +85C", and "0-100%RH"; with blue button marked "TXT". On the reverse, "PCsensor". This model does not have a jack on the end.

When the button is pressed the red LED will blink as messages of the following style are sent (the temperature line repeats every second).

www.pcsensor.com
temperx v3.1
caps lock:on/off/++
num lock:off/on/--
type:inner-h2
inner-temperinner-humidityinterval
32.73 [c]36.82 [%rh]1s

When the button is pressed again, the LED will either be off or be solid red. This is the mode that temper.py uses.

TEMPer2

physical description: White plastic USB stick marked "TEMPer2", "-40C - +125C"; with red button marked "TXT". On the reverse, "PCsensor". This model has a jack for an external sensor on the end.

notes: When the button is pressed, the red LED will blink as messages of the following form are sent (the temperature line repeats every second).

Without an external sensor:

www.pcsensor.com
temperx v3.3
caps lock:on/off/++
num lock:off/on/--
type:inner-tx
inner-tempinterval
27.93 [c]1s

With an external sensor:

www.pcsensor.com
temperx v3.3
caps lock:on/off/++
num lock:off/on/--
type:inner-tx;outer-tx
inner-tempintervalinterval
27.18 [c]29.62 [c]1s

This program uses the mode where the LED is either off or solid red.

TEMPer1F

White plastic USB stick marked "TEMPer1F", "-40C - +125C"; with pink button marked "TXT'. On the reverse, "PCsensor". This model has a jack for an external sensor and does not have an internal sensor.

When the button is pressed, the red LED will blink as messages of the following form are sent (the temperature line repeats every 1 second).

Without the probe inserted:

www.pcsensor.com
temperx v3.3
caps lock:on/off/++
num lock:off/on/--
type:unknown
1s

With the probe inserted:

www.pcsensor.com
temperx v3.3
caps lock:on/off/++
num lock:off/on/--
type:outer-tx
outer-tempinterval
24.93 [c]1s

This program uses the mode where the LED is either off or solid red.

TEMPerX232

White plastic USB stick marked "TEMPerX232", "0-100%RH", and "-40 - +85C"; with a green button marked "press". On the reverse, "PCsensor". On the end opposite the USB connector, there is a jack for an external temperature sensor (which I do not have and did not try).

When the button is pressed and held down until the red LED is solid, a blue LED will flash every second. In this mode, the USB vendor:product changes to 413d:2107, but only one HID device is available, and protocol sent to the hidraw device is rejected with an error.

When the LED is flashing blue, and the button is pressed momentarily, the following are sent (the temperature line repeats every second).

www.PCsensor.com
TEMPerX232-V2.0
type:inner-H2
inner-temperinner-humidityinterval
30.48 [C]40.19 [%RH]1

When the button is pressed and held down until the red LED is solid, a green LED will flash every second. This is the mode temper.py uses. In this mode, if "Help" is sent to the serial device, the following will be sent back:

   >>PCsensor<<
Welcome to use TEMPerX232!
Firmware Version:TEMPerX232_V2.0
The command is:
    ReadTemp                     -->read temperature,temp_value = sensor_value + calibration
    ReadCalib                    -->read calibration
    SetCalib-type:xx.x,xx.x>     -->set calibration, xx.x(-10.0~+10.0)
    EraseFlash                   -->erase calibration
    Version                      -->read firmware version
    ReadType                     -->read the sensor type
    ReadAlert-Temp               -->read temp alert value
    SetTempUpperAlert-type:xx.xx>-->set temp upper alert value,xx.xx(-40.00~+85.00)
    SetTempLowerAlert-type:xx.xx>-->set temp lower alert value,xx.xx(-40.00~+85.00)
    ReadAlert-Hum                -->read hum alert value
    SetHumUpperAlert-type:xx.xx> -->set hum upper alert value,xx.xx(00.00~99.99)
    SetHumLowerAlert-type:xx.xx> -->set hum lower alert value,xx.xx(00.00~99.99)
    SetMode-Temp:x>              -->set tempmode, x(0~1)
    ReadMode-Temp                -->read tempmode
    Help                         -->command help
    ?                            -->command help
The COM configuration is:
    Mode:       ASCII
    Baud Rate:  9600bps
    Data Bit:   8
    Parity Bit: None
    Stop Bit:   1
SHENZHEN RDing Tech CO.,LTD
www.PCsensor.com

This is the mode that temper.py uses. I was not successful getting this device to respond to any commands sent via the HID device.

I initially had trouble getting a reply to ReadTemp when using a terminal program (e.g., cu), but the example in the temper.py works without any problems, perhaps because no newline is sent after the command.

Example Command Output

Help

$ ./temper.py --help
usage: temper.py [-h] [-l] [--json] [--force VENDOR_ID:PRODUCT_ID]

temper

optional arguments:
-h, --help            show this help message and exit
-l, --list            List all USB devices
--json                Provide output as JSON
--force VENDOR_ID:PRODUCT_ID
                      Force the use of the hex id; ignore other ids

List Devices

In this example, one of the devices doesn't have the HID driver attached because I was using an libusb-based program to access it.

$ ./temper.py -l
Bus 001 Dev 023 413d:2107 * ??? ['hidraw0', 'hidraw1']
Bus 001 Dev 086 0c45:7401 * TEMPerV1.4 []
Bus 002 Dev 002 04d8:f5fe   TrueRNG ['ttyACM0']

Temperature

In this example, one of the devices doesn't have the HID driver attached because I was using an libusb-based program to access it.

$ ./temper.py
Bus 001 Dev 023 413d:2107 TEMPerX_V3.1 26.55C 79.79F 43.41%
Bus 001 Dev 086 0c45:7401 Error: no hid/tty devices available
$ ./temper.py --json
[
    {
        "path": "/sys/bus/usb/devices/1-1.2",
        "busnum": 1,
        "devnum": 23,
        "vendorid": 16701,
        "productid": 8455,
        "vendor_name": "",
        "product_name": "",
        "devices": [
            "hidraw0",
            "hidraw1"
        ],
        "ident": "TEMPerX_V3.1",
        "celsius": 26.55,
        "fahrenheit": 79.78999999999999,
        "humidity": 43.65
    },
    {
        "path": "/sys/bus/usb/devices/1-1.1.1",
        "busnum": 1,
        "devnum": 86,
        "vendorid": 3141,
        "productid": 29697,
        "vendor_name": "RDing",
        "product_name": "TEMPerV1.4",
        "devices": [
        ],
        "error": "no hid/tty devices available"
    }
]

Similar JSON output can be generated with the --list option.

Docker

The docker image is built with temper.py and temper-service.py. The default ENTRYPOINT points to temper-service.py which runs as web service listening on port 2610. The web service responds to two endpoints: /list and /metrics. The result is in JSON format. See DOCKER.md for more details.

temper's People

Contributors

andrerenaud avatar bartnv avatar c72578 avatar corsac-s avatar dgoffredo avatar dr1fter avatar e-minguez avatar eode avatar jaesivsm avatar mjarmstr avatar mrj avatar nemslinux avatar neofob avatar nigels-com avatar owenbrakeparallelsystems avatar phseiff avatar urwen avatar wiryonolau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

temper's Issues

Sub Zero temperatures (Celsius)

It seems like temper.py is not able to handle temperatures below zero degree Celsius.
I get following error:
File "./temper.py", line 235, in _read_serial
info['internal temperature'] = float(m.group(1))
ValueError: could not convert string to float:

Debugging serial interface show that negative temperatures are sendt to temper.py.

TEMPerF1.2

Hello,

I get the following error:

Bus 003 Dev 002 0c45:7401 TEMPerF1.2MPerF1 Error: Unknown firmware TEMPerF1.2MPerF1: b'80021a2065724631'

Changing "if info['firmware'][:10] == 'TEMPerF1.4':" to "...1.2" makes it work:

Bus 003 Dev 002 0c45:7401 TEMPerF1.2 26.25C 79.25F - - - -

I believe the current firmware check is unnecessarily too strict.

1a86:5523 TEMPerX232_V2.1 with external sensor show no humidity - review regexp

Regexp parsing outer sensor is not properly handling external sensor.
Here is output which should be parsed:

Temp-Outer:27.11 [C],36.72 [%RH]<Temp-Inner:28.15 [C],34.80 [%RH]<

Working regexp (should be review)

>>> m = re.search(r'Temp-Outer:([0-9]{1,2}.[0-9]{1,2}).{4},([0-9][0-9].[0-9][0-9]).*' , 'Temp-Outer:26.89 [C],36.23 [%RH]<Temp-Inner:28.17 [C],34.87 [%RH]<')
>>> m.group(1)
'26.89'
>>> m.group(2)
'36.23'
 and add line to show it, like
info['external temperature'] = float(k.group(1))
info['external humidity'] = float(k.group(2))

Working example:
Temp-Outer:27.11 [C],36.35 [%RH]<Temp-Inner:28.16 [C],34.64 [%RH]<
[
    {
        "vendorid": 6790,
        "productid": 21795,
        "manufacturer": "",
        "product": "",
        "busnum": 1,
        "devnum": 14,
        "devices": [
            "ttyUSB0"
        ],
        "firmware": "TEMPerX232_V2.1",
        "internal temperature": 28.16,
        "internal humidity": 34.64,
        "external temperature": 27.11,
        "external humidity": 36.35
    }
]

OR:
Temp-Outer:27.11 [C],37.33 [%RH]<Temp-Inner:28.18 [C],34.93 [%RH]<

Bus 001 Dev 014 1a86:5523 TEMPerX232_V2.1 28.18C 82.72F 34% 27.11C 80.80F 37%

Traceback - exit whitout action

$ python3 --version
Python 3.5.3
$ ./temper.py --help
Traceback (most recent call last):
  File "./temper.py", line 410, in <module>
    temper = Temper()
  File "./temper.py", line 258, in __init__
    self.usb_devices = usblist.get_usb_devices()
  File "./temper.py", line 99, in get_usb_devices
    with os.scandir(Temper.SYSPATH) as it:
AttributeError: __exit__

devnum doesn't consistently identify a device

While a device's "devnum" field changes each insertion/boot, making it hard for a program to identify a given device/sensor from the JSON output, a device's USB port-identifier reflects where it's plugged-in.

I've got this PR that adds a JSON field "port" to reliably associate a device with a USB socket. Would it be worthwhile to switch this PR to this repo?

Getting error: "could not open port ... Device or resource busy: '/dev/ttyUSB0' "

When I call 'temper' more than once, I often get this error:
serial.serialutil.SerialException: [Errno 16] could not open port /dev/ttyUSB0: [Errno 16] Device or resource busy: '/dev/ttyUSB0'

Calling it several times, I will eventually get a correct response. Increasing s.timeout and s.writeTimeout seems to have helped it somewhat.

Accept patch for command-line argument to use libusb?

Hi,

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

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

Add support for TemperHUM_V3.8

The latest shipment has an updated firmware:

(venv) [13:47] server102.place10:~/temper# python temper.py -l
Bus 001 Dev 001 1d6b:0002   xHCI Host Controller ['hidraw0', 'hidraw1']
Bus 001 Dev 002 046d:0825    
Bus 001 Dev 003 1b3f:2247   GENERAL WEBCAM 
Bus 001 Dev 004 1a86:e025    ['hidraw0', 'hidraw1']
Bus 002 Dev 001 1d6b:0003   xHCI Host Controller 
(venv) [13:47] server102.place10:~/temper# python temper.py --force 1a86:e025
Bus 001 Dev 004 1a86:e025 TEMPerHUM_V3.8 Error: Unknown firmware TEMPerHUM_V3.8: b'8020065a0c360000'

This looks exactly the same as the previous white temperhum devices

anyone have this working yet with TEMPerGold_V3.1 ?

I have not yet looked in depth, but it seems that this repo's temper.py succeeds in identifying my device but not in reading its temperature. I wonder if this version has changed the command interface somewhat. Here is what I see:

$ python3 temper.py --verbose
Firmware value: b'54454d506572476f6c645f56332e3120'
Data value: b''
Bus 002 Dev 034 413d:2107 TEMPerGold_V3.1 - - - - - -
$ python3 temper.py --json
[
{
"vendorid": 16701,
"productid": 8455,
"manufacturer": "",
"product": "",
"busnum": 2,
"devnum": 34,
"devices": [
"hidraw1",
"hidraw2"
],
"firmware": "TEMPerGold_V3.1",
"hex_firmware": "54454d506572476f6c645f56332e3120",
"hex_data": ""
}
]
$

I will try to debug more closely when I have a chance, but I'm posting here just in case someone else has already figured out how to use this version of the dongle with temper.py.

Rpi 3B+ with 0c45:7401 TEMPerF1.4

Made both of these changes and updated the timeout from 0.2 to 0.5 and still get failures every other read when running
while true; do sudo ./temper2.py; sleep 5; done
on an RPi 3 B+

Just investigating, the regularity of it made me call hardware into question, checking dmesg it shows brownout on each successful read, subsequently returning rubbish. Will confirm with new PSU.

__ Update:
PSU swapped for a high current one, no improvement - power drop out doesn't happen but still get errors.

Output modified as I don't need all the bumf, but....
--@--:/home/pi# ./temper2.py
21.5 2020-01-21 21:01:39
--@--:/home/pi# ./temper2.py
21.5 2020-01-21 21:01:41
--@--:/home/pi# ./temper2.py
Traceback (most recent call last):
File "./temper2.py", line 434, in
sys.exit(temper.main())
File "./temper2.py", line 427, in main
results = self.read(args.verbose)
File "./temper2.py", line 345, in read
results.append({ **info, **usbread.read() })
File "./temper2.py", line 272, in read
return self._read_hidraw(self.device)
File "./temper2.py", line 180, in _read_hidraw
firmware = self._read_hidraw_firmware(fd, self.verbose)
File "./temper2.py", line 159, in _read_hidraw_firmware
raise RuntimeError('Cannot read device firmware identifier')
RuntimeError: Cannot read device firmware identifier

Originally posted by @bucklevision in #16 (comment)

Support for TEMPer2_V3.9

Hi,

To make this device work, I modified:

if info['firmware'][:12] in [ 'TEMPerX_V3.1', 'TEMPerX_V3.3', 'TEMPer2_V3.9' ]:

to include the V3.9 version, and:

if vendorid == 0x1a86 and productid == 0xe025:
return True

to recognise the corresponding USB id (1a86:e025).

This trick works for temperature, but not for humidity:

Bus 001 Dev 031 1a86:e025 TEMPer2_V3.9 28.93C 84.07F - - - -

is it possible to add full compatibility for this device? can I help in any way?

Thanks in advance

Cannot read firmware identifier from device

root@raspberrypi:/home/pi/temper/# ./temper.py
Bus 001 Dev 005 413d:2107 TEMPerX_V3.2 Error: Unknown firmware TEMPerX.V3.2: b'80800a534e200000800109dd4e200000'
root@raspberrypi:/home/pi/temper# ./temper.py -l
Bus 001 Dev 006 413d:2107 * ['hidraw3', 'hidraw4']

Bought this "TEMPer2" off Amazon a few months back and finally got around to attempting setup. Been a bit of a headache as most software solutions don't seem to support this model. Any thoughts on resolving this issue?

Firmware compatibility issue [Jetson J3010 & PCSensor TEMPER1F V4.1]

I have installed and used the Pypi package 'temper_py' in the Jetson J3010 device, to read the sensor (PCSensor: TEMPER1F V4.1) values.
This sensor is connected through USB HUB. When running the program, it raised a firmware compatibility issue, Please instruct us to avoid this.
Here I attached screenshots for your reference.
J3010_TEMPER1F_V4 1

Script for python 2.7

Is it possible to change the script for python 2.7? I would like to run it on OpenWRT and its pyserial package is only for python 2.7. I tried to run temper.py on python 2.7 (with pyserial) and it gave the error:

File "/tmp/temper.py", line 322
results.append({ **info, **usbread.read() })

Thanks

Error Unknown Firmware

I noticed that these devices have had something changed, I found someone linking to this project saying that it worked for them. This is the error im getting now... Any suggestions on getting this to work? Thanks

jon@jon-ThinkPad-T540p:~/temper$ sudo ./temper.py --json
[
{
"vendorid": 16701,
"productid": 8455,
"manufacturer": "",
"product": "",
"busnum": 3,
"devnum": 4,
"devices": [
"hidraw0",
"hidraw1"
],
"error": "Unknown firmware TEMPerGold_V3.1: b'808009214e200000'"
}
]

Unknown firmware TEMPer2_V3.7

Hi
I tried temper.py but I get this error:

Bus 001 Dev 022 1a86:e025 TEMPer2_V3.7 Error: Unknown firmware TEMPer2_V3.7: b'808009b74e2000008001090e4e200000'

Any idea what I can try?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.