-
Notifications
You must be signed in to change notification settings - Fork 0
/
PhidgetHelperFunctions.py
342 lines (274 loc) · 11.6 KB
/
PhidgetHelperFunctions.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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
import sys
from Phidget22.PhidgetException import *
from Phidget22.ErrorCode import *
from Phidget22.Phidget import *
from Phidget22.Net import *
class NetInfo():
def __init__(self):
self.isRemote = None
self.serverDiscovery = None
self.hostname = None
self.port = None
self.password = None
class ChannelInfo():
def __init__(self):
self.serialNumber = -1
self.hubPort = -1
self.isHubPortDevice = 0
self.channel = -1
self.netInfo = NetInfo()
class EndProgramSignal(Exception):
def __init__(self, value):
self.value = str(value )
class InputError(Exception):
"""Exception raised for errors in the input.
Attributes:
msg -- explanation of the error
"""
def __init__(self, msg):
self.msg = msg
# Returns None if an error occurred, True for 'Y' and False for 'N'
def ProcessYesNo_Input(default):
strvar = sys.stdin.readline(100)
if not strvar:
raise InputError("Empty Input String")
strvar = strvar.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
if (strvar[0] == '\n'):
if (default == -1):
raise InputError("Empty Input String")
return default
if (strvar[0] == 'N' or strvar[0] == 'n'):
return False
if (strvar[0] == 'Y' or strvar[0] == 'y'):
return True
raise InputError("Invalid Input")
def DisplayError(e):
sys.stderr.write("Desc: " + e.details + "\n")
def InputSerialNumber(channelInfo):
print("\nFor all questions, enter the value, or press ENTER to select the [Default]")
print("\n--------------------------------------")
print("\n | Some Phidgets have a unique serial number, printed on a white label on the device.\n"
" | For Phidgets and other devices plugged into a VINT Port, use the serial number of the VINT Hub.\n"
" | Specify the serial number to ensure you are only opening channels from that specific device.\n"
" | Otherwise, use -1 to open a channel on any device.")
while (True):
print("\nWhat is the Serial Number? [-1] ")
strvar = sys.stdin.readline(100)
if not strvar:
continue
strvar = strvar.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
if (strvar[0] == '\n'):
deviceSerialNumber = -1
break
try:
deviceSerialNumber = int(strvar)
except ValueError as e:
continue
if (deviceSerialNumber >= -1 and deviceSerialNumber != 0):
break
channelInfo.deviceSerialNumber = deviceSerialNumber
return
def InputIsHubPortDevice(channelInfo):
isHubPortDevice = -1
while (True):
print("\nIs this a \"HubPortDevice\"? [y/n] ")
try:
isHubPortDevice = ProcessYesNo_Input(-1)
break
except InputError as e:
pass
channelInfo.isHubPortDevice = isHubPortDevice
return
def InputVINTProperties(channelInfo, ph):
canBeHubPortDevice = 0
pcc = -1
hubPort = -1
isVINT = 0
print("\n--------------------------------------")
while (True):
print("\nDo you want to specify the hub port that your device is plugged into?\n"
"Choose No if your device is not plugged into a VINT Hub. (y/n) ")
try:
isVINT = ProcessYesNo_Input(-1)
break
except InputError as e:
pass
channelInfo.isVINT = isVINT
# Don't ask about the HubPort and the HubPortDevice if it's not a VINT device
if (not isVINT):
return
print("\n--------------------------------------")
print("\n | VINT Hubs have numbered ports that can be uniquely addressed.\n"
" | The HubPort# is identified by the number above the port it is plugged into.\n"
" | Specify the hub port to ensure you are only opening channels from that specific port.\n"
" | Otherwise, use -1 to open a channel on any port.")
while (True):
print("\nWhat HubPort is the device plugged into? [-1] ")
strvar = sys.stdin.readline(100)
if not strvar:
continue
strvar = strvar.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
if (strvar[0] == '\n'):
hubPort = -1
break
try:
hubPort = int(strvar)
except ValueError as e:
continue
if (hubPort >= -1 and hubPort <= 5):
break
channelInfo.hubPort = hubPort
try:
pcc = ph.getChannelClass()
except PhidgetException as e:
sys.stderr.write("Runtime Error -> Getting ChannelClass: \n\t")
DisplayError(e)
raise
if (pcc == ChannelClass.PHIDCHCLASS_VOLTAGEINPUT):
print("\n--------------------------------------")
print("\n | A VoltageInput HubPortDevice uses the VINT Hub's internal channel to measure the voltage on the white wire.\n"
" | If the device you are trying to interface returns an analog voltage between 0V-5V, open it as a HubPortDevice.")
canBeHubPortDevice = 1
elif (pcc == ChannelClass.PHIDCHCLASS_VOLTAGERATIOINPUT):
print("\n--------------------------------------")
print("\n | A VoltageRatioInput HubPortDevice uses the VINT Hub's internal channel to measure the voltage ratio on the white wire.\n"
" | If the device you are trying to interface returns an ratiometric voltage between 0V-5V, open it as a HubPortDevice.")
canBeHubPortDevice = 1
elif (pcc == ChannelClass.PHIDCHCLASS_DIGITALINPUT):
print("\n--------------------------------------")
print("\n | A DigitalInput HubPortDevice uses the VINT Hub's internal channel to detect digital changes on the white wire.\n"
" | If the device you are trying to interface outputs a 5V digital signal, open it as a HubPortDevice.")
canBeHubPortDevice = 1
elif (pcc == ChannelClass.PHIDCHCLASS_DIGITALOUTPUT):
print("\n--------------------------------------")
print("\n | A DigitalOutput HubPortDevice uses the VINT Hub's internal channel to output a 3.3V digital signal on the white wire.\n"
" | If the device you are trying to interface accepts a 3.3V digital signal, open it as a HubPortDevice.")
canBeHubPortDevice = 1
if (canBeHubPortDevice):
InputIsHubPortDevice(channelInfo)
return
def InputChannel(channelInfo):
isHubPortDevice = 0
channel = 0
# Hub port devices only have a single channel, so don't ask for the channel
if (channelInfo.isHubPortDevice):
return
print("\n--------------------------------------")
print("\n | Devices with multiple inputs or outputs of the same type will map them to channels.\n"
" | The API tab for the device on www.phidgets.com shows the channel breakdown.\n"
" | For example, a device with 4 DigitalInputs would use channels [0 - 3]\n"
" | A device with 1 VoltageInput would use channel 0")
while (True):
print("\nWhat channel# of the device do you want to open? [0] ")
strvar = sys.stdin.readline(100)
if not strvar:
continue
strvar = strvar.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
if (strvar[0] == '\n'):
channel = 0
break
try:
channel = int(strvar)
except ValueError as e:
continue
if (channel >= 0):
break
channelInfo.channel = channel
return
def SetupNetwork(channelInfo):
hostname = ""
password = ""
discovery = 0
isRemote = 0
port = 0
print("\n--------------------------------------")
print("\n | Devices can either be opened directly, or over the network.\n"
" | In order to open over the network, the target system must be running a Phidget Server.")
while (True):
print("\nIs this device being opened over the network? [y/N] ")
try:
isRemote = ProcessYesNo_Input(0)
break
except InputError as e:
pass
channelInfo.netInfo.isRemote = isRemote
# if it's not remote, don't need to ask about the network
if (not isRemote):
return
print("\n--------------------------------------")
print("\n | Server discovery enables the dynamic discovery of phidget servers that publish their identity to the network.\n"
" | This allows you to open devices over the network without specifying the hostname and port of the server.")
while (True):
print("\nDo you want to enable server discovery? [Y/n] ");
try:
discovery = ProcessYesNo_Input(1)
break
except InputError as e:
pass
if (discovery):
return EnableServerDiscovery(channelInfo)
print("\n--------------------------------------")
print("\nPlease provide the following information in order to open the device")
while (True):
print("\nWhat is the Hostname (or IP Address) of the server? [localhost] ")
hostname = sys.stdin.readline(100)
if not hostname:
continue
hostname = hostname.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
if (hostname[0] == '\n'):
hostname = "localhost"
break
# Remove trailing newline
hostname = hostname.split('\n')[0]
break
print("\n--------------------------------------")
while (True):
print("\nWhat port is the server on? [5661] ")
strvar = sys.stdin.readline(100)
if not strvar:
continue
strvar = strvar.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
if (strvar[0] == '\n'):
port = 5661
break
try:
port = int(strvar)
except ValueError as e:
continue
if (port <= 65535 and port > 0):
break
print("\n--------------------------------------")
while (True):
print("\nWhat is the password of the server? [] ")
password = sys.stdin.readline(100)
if not password:
continue
# Remove trailing newline
password = password.replace('\r\n', '\n') #sanitize newlines for Python 3.2 and older
password = password.split('\n')[0]
break
print("\n--------------------------------------")
channelInfo.netInfo.hostname = hostname
channelInfo.netInfo.port = port
channelInfo.netInfo.password = password
return
def PrintOpenErrorMessage(e, ph):
sys.stderr.write("Runtime Error -> Opening Phidget Channel: \n\t")
DisplayError(e)
if(e.code == ErrorCode.EPHIDGET_TIMEOUT):
sys.stderr.write("\nThis error commonly occurs if your device is not connected as specified, "
"or if another program is using the device, such as the Phidget Control Panel.\n")
if( ph.getChannelClass() != ChannelClass.PHIDCHCLASS_VOLTAGEINPUT
and ph.getChannelClass() != ChannelClass.PHIDCHCLASS_VOLTAGERATIOINPUT
and ph.getChannelClass() != ChannelClass.PHIDCHCLASS_DIGITALINPUT
and ph.getChannelClass() != ChannelClass.PHIDCHCLASS_DIGITALOUTPUT
):
sys.stderr.write("\nIf you are trying to connect to an analog sensor, you will need to use the "
"corresponding VoltageInput or VoltageRatioInput API with the appropriate SensorType.\n")
def AskForDeviceParameters(ph):
channelInfo = ChannelInfo()
InputSerialNumber(channelInfo)
InputVINTProperties(channelInfo, ph)
InputChannel(channelInfo)
SetupNetwork(channelInfo)
return channelInfo