-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7058e6f
Showing
6 changed files
with
830 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*~ | ||
/temper | ||
/temper-* | ||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
temper: temper.c | ||
@gcc $< -l hidapi-hidraw -o $@ | ||
|
||
release: temper | ||
@cp temper temper-linux-$$(git tag -l --points-at HEAD | cut -d/ -f2)-$$(uname -m) \ | ||
&& strip temper-linux-$$(git tag -l --points-at HEAD | cut -d/ -f2)-$$(uname -m) \ | ||
&& sha256sum temper-linux-$$(git tag -l --points-at HEAD | cut -d/ -f2)-$$(uname -m) > temper-linux-$$(git tag -l --points-at HEAD | cut -d/ -f2)-$$(uname -m).sha256sum | ||
|
||
clean: | ||
@rm -f temper temper-* *~ .*~ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Read the temperature of a TEMPer device with ID 413d:2107 | ||
There are many libraries (C, Python) out there for reading the TEMPer | ||
family of thermometer and hygrometer devices. | ||
|
||
Since I own only one device with USB ID `413d:2107` and wanted just simple JSON output, I | ||
wrote yet another program to read from this kind of USB device. | ||
|
||
## Dependencies | ||
It uses the [HIDAPI](https://github.com/signal11/hidapi) library as dependency. | ||
|
||
On Debian (based): | ||
|
||
sudo apt install libhidapi-hidraw0 | ||
|
||
On Arch: | ||
|
||
sudo pacman -S hidapi | ||
|
||
## Device | ||
|
||
### `dmesg` | ||
|
||
Example `dmesg` output: | ||
|
||
[35813.492854] usb 2-1.3: new full-speed USB device number 25 using ehci-pci | ||
[35813.591045] usb 2-1.3: New USB device found, idVendor=413d, idProduct=2107, bcdDevice= 0.00 | ||
[35813.591053] usb 2-1.3: New USB device strings: Mfr=0, Product=0, SerialNumber=0 | ||
[35813.603164] input: HID 413d:2107 as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/0003:413D:2107.0027/input/input39 | ||
[35813.660537] hid-generic 0003:413D:2107.0027: input,hidraw0: USB HID v1.11 Keyboard [HID 413d:2107] on usb-0000:00:1d.0-1.3/input0 | ||
[35813.662589] hid-generic 0003:413D:2107.0028: hiddev1,hidraw1: USB HID v1.10 Device [HID 413d:2107] on usb-0000:00:1d.0-1.3/input1 | ||
|
||
### `lsusb` | ||
|
||
Example `lsusb -d 413d:2107` output: | ||
|
||
Bus 002 Device 025: ID 413d:2107 | ||
|
||
### Photo | ||
|
||
Photo of my TEMPer device: | ||
|
||
![](TEMPer_413d_2107.jpg) | ||
|
||
## License | ||
The program is licensed under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) ([local copy](LICENSE-GPL-3.0.txt)). |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#include <limits.h> | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <hidapi/hidapi.h> | ||
|
||
#define MAX_STR 255 | ||
|
||
char* find_device_path(unsigned short vendor_id, unsigned short product_id); | ||
bool read_temperature(hid_device *handle, int* result); | ||
|
||
#define TEMPer_VendorId 0x413d | ||
#define TEMPer_ProductId 0x2107 | ||
|
||
int main(int argc, char* argv[]) { | ||
if(hid_init()) { | ||
fwprintf(stderr,L"failed to initialize HID API\n"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
char* path = find_device_path(TEMPer_VendorId, TEMPer_ProductId); | ||
|
||
if(!path) { | ||
fwprintf(stderr,L"cannot find matching HID device ID %x:%x, try 'lsusb' or 'lsusb -d %x:%x'\n", | ||
TEMPer_VendorId,TEMPer_ProductId, | ||
TEMPer_VendorId,TEMPer_ProductId); | ||
return EXIT_FAILURE; | ||
} else { | ||
hid_device *handle = hid_open_path(path); | ||
|
||
if (!handle) { | ||
fwprintf(stderr,L"failed to open device %s\n" | ||
"to avoid running this program as root, put the following udev rule in e.g. /etc/udev/rules.d/90-temper.rules\n\n" | ||
"SUBSYSTEMS==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"%x\", ATTRS{idProduct}==\"%x\", MODE=\"666\"\n\n", | ||
path,TEMPer_VendorId,TEMPer_ProductId); | ||
free(path); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
int temperature = INT_MIN; | ||
if(read_temperature(handle,&temperature)) { | ||
printf("{ \"temp_celsius\": %d.%d }\n",temperature/100,temperature%100); | ||
} | ||
hid_close(handle); | ||
free(path); | ||
} | ||
|
||
if(hid_exit()) { | ||
fwprintf(stderr,L"failed to shutdown HID API\n"); | ||
return EXIT_FAILURE; | ||
} | ||
return EXIT_SUCCESS; | ||
} | ||
|
||
bool read_temperature(hid_device *handle, int* result) { | ||
unsigned char buf[16]; | ||
unsigned char cmd[8] = { 0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00 }; | ||
|
||
memset(&buf,0,sizeof(buf)); | ||
|
||
int rc = hid_write(handle, cmd, sizeof(cmd)); | ||
|
||
if(-1 == rc) { | ||
return false; | ||
} | ||
|
||
// expected response is exactly 8 bytes | ||
bool ok = (8 == hid_read(handle, buf, sizeof(buf))); | ||
|
||
if (ok) { | ||
// temperature is stored in byte 2&3 => return value is a hundreth of °C | ||
*result = (buf[2]*256 + buf[3]); | ||
} | ||
return ok; | ||
} | ||
|
||
|
||
char* find_device_path(unsigned short vendor_id, unsigned short product_id) { | ||
|
||
struct hid_device_info *devices = hid_enumerate(vendor_id,product_id); | ||
struct hid_device_info *cur_dev = devices; | ||
|
||
while (cur_dev) { | ||
// the hardware provides two devices, we need the second one | ||
if (1 == cur_dev->interface_number && cur_dev->path) { | ||
char* path = malloc(strlen(cur_dev->path)+1); | ||
strcpy(path,cur_dev->path); | ||
hid_free_enumeration(devices); | ||
return path; | ||
} | ||
cur_dev = cur_dev->next; | ||
} | ||
hid_free_enumeration(devices); | ||
return NULL; | ||
} |