-
Notifications
You must be signed in to change notification settings - Fork 2
/
temper.py
211 lines (185 loc) · 6.98 KB
/
temper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
"""
Temper - a class for managing a TEMPer USB temperature sensor
Bill Mania <[email protected]>
Source: http://www.manialabs.us/downloads/Temper.py
"""
import usb.core
import sys
class Temper():
def __init__(self):
self.devices = []
self.calibrationConstant = 15
self.units = 'C'
self.device_list = usb.core.find(
find_all=True,
idVendor = 0x1130,
idProduct = 0x660c
)
self.devices = [device for device in self.device_list]
if self.devices is None:
print 'Unable to find a temperature device'
return
# Try our best to detach the device from any previous state
try:
for device in self.devices:
if device.is_kernel_driver_active(0):
device.detach_kernel_driver(0)
if device.is_kernel_driver_active(1):
device.detach_kernel_driver(1)
except NotImplementedError as e:
#Note: some system do not implement is_kernel_driver_active
try:
for device in self.devices:
device.detach_kernel_driver(0)
device.detach_kernel_driver(1)
except Exception as e:
# I give up, maybe we will get lucky anyway
#print "Exception: " + e.__class__.__name__ + ": " + str(e)
pass
except Exception as e:
#print "Exception: " + e.__class__.__name__ + ": " + str(e)
pass
# Configure the device
for device in self.devices:
try:
# This attach would avoid the following kernel warning, but
# generates 2 other attach lines. A clean "claim" would be better.
# kernel warning: 'process xxx (python) did not claim interface 1 before use'
#device.attach_kernel_driver(0)
#device.attach_kernel_driver(1)
#device.reset()
device.set_configuration()
except Exception as e:
print "Error: Unable to setup the device"
raise e
#print "Exception: " + e.__class__.__name__ + ": " + str(e)
#return
#
# the following sequence appear to be necessary to
# either calibrate or initialize the TEMPer, but I
# have no idea why. therefore, I named them all "magic".
#
nullTrailer = ''
for i in range(0, 24):
nullTrailer = nullTrailer + chr(0)
firstMagicSequence = chr(10) + chr(11) + chr(12) + chr(13) + chr(0) + chr(0) + chr(2) + chr(0)
firstMagicSequence = firstMagicSequence + nullTrailer
secondMagicSequence = chr(0x54) + chr(0) + chr(0) + chr(0) + chr(0) + chr(0) + chr(0) + chr(0)
secondMagicSequence = secondMagicSequence + nullTrailer
thirdMagicSequence = chr(0) + chr(0) + chr(0) + chr(0) + chr(0) + chr(0) + chr(0) + chr(0)
thirdMagicSequence = thirdMagicSequence + nullTrailer
fourthMagicSequence = chr(10) + chr(11) + chr(12) + chr(13) + chr(0) + chr(0) + chr(1) + chr(0)
fourthMagicSequence = fourthMagicSequence + nullTrailer
for device in self.devices:
bytesSent = device.ctrl_transfer(
0x21,
9,
0x200,
0x1,
firstMagicSequence,
32
)
bytesSent = device.ctrl_transfer(
0x21,
9,
0x200,
0x1,
secondMagicSequence,
32
)
for i in range(0, 7):
bytesSent = device.ctrl_transfer(
0x21,
9,
0x200,
0x1,
thirdMagicSequence,
32
)
bytesSent = device.ctrl_transfer(
0x21,
9,
0x200,
0x1,
fourthMagicSequence,
32
)
return
def setCalibration(self, calibrationConstant):
self.calibrationConstant = calibrationConstant
return
def setUnits(self, units = 'C'):
self.units = units
return
def getUnits(self):
if self.units == 'C':
return 'Celsius'
elif self.units == 'F':
return 'Fahrenheit'
elif self.units == 'K':
return 'Kelvin'
else:
return 'Unknown'
def getTemperature(self, device):
nullTrailer = ''
for i in range(0, 24):
nullTrailer = nullTrailer + chr(0)
temperatureBuffer = device.ctrl_transfer(
0xa1,
1,
0x300,
0x1,
256,
0
)
if len(temperatureBuffer) > 1:
if temperatureBuffer[0] == 0 and temperatureBuffer[1] == 255:
print "Failed to retrieve temperature"
return 0.0
#print temperatureBuffer
temperature = int(temperatureBuffer[0] << 8) + int(temperatureBuffer[1] & 0xff) + self.calibrationConstant
temperature = temperature * (125.0 / 32000.0)
if self.units == 'F':
temperature = 9.0 / 5.0 * temperature + 32.0
elif self.units == 'K':
temperature = temperature + 273.15
else:
pass
else:
print "Failed to retrieve temperature"
temperature = 0.0
return temperature
if __name__ == '__main__':
temper = Temper()
for device in temper.devices:
tempc = temper.getTemperature(device)
tempcunits = temper.getUnits()
tempf = (tempc * 9/5) + 32
tempfunits = "Fahrenheit"
devicebus = device.bus
deviceaddress = device.address
if len(sys.argv) < 2:
# Example output: 0:7, 17.06 Celsius / 62.71 Fahrenheit
print '%d:%d, %0.2f %s / %0.2f %s' % (devicebus, deviceaddress, tempc, tempcunits, tempf, tempfunits)
else:
if sys.argv[1] == "-c":
# Example Celsius output: 17.06
print '%0.2f' % tempc
elif sys.argv[1] == "-C":
# Example Celsius output: 17
print '%0.0f' % tempc
elif sys.argv[1] == "-f":
# Example Fahrenheit output: 62.71
print '%0.2f' % tempf
elif sys.argv[1] == "-F":
# Example Fahrenheit output: 62
print '%0.0f' % tempf
else:
print "Usage: %s [options]" % sys.argv[0]
print "Options:"
print " -c # report Celsius"
print " -C # report Celsius rounded"
print " -f # report Fahrenheit"
print " -F # report Fahrenheit rounded"
print " -h # Help"
sys.exit(1)