gclib 2.0.9
Communications API for Galil controllers and PLCs
 
Loading...
Searching...
No Matches
gclib.py
Go to the documentation of this file.
1'''! \file gclib.py
2'''
3"""
4Python wrapper for Galil gclib.
5Contact softwaresupport@galil.com with questions, comments, and suggestions.
6"""
7
11import platform #for distinguishing 'Windows', 'Linux', 'Darwin'
12from ctypes import *
13
14if platform.system() == 'Windows':
15 if '64 bit' in platform.python_compiler():
16 WinDLL(r'C:\Program Files (x86)\Galil\gclib\dll\x64\libcrypto-1_1-x64.dll')
17 WinDLL(r'C:\Program Files (x86)\Galil\gclib\dll\x64\libssl-1_1-x64.dll')
18 _gclib_path = r'C:\Program Files (x86)\Galil\gclib\dll\x64\gclib.dll'
19 _gclibo_path = r'C:\Program Files (x86)\Galil\gclib\dll\x64\gclibo.dll'
20 _gclib = WinDLL(_gclib_path)
21 _gclibo = WinDLL(_gclibo_path)
22 else:
23 WinDLL(r'C:\Program Files (x86)\Galil\gclib\dll\x86\libcrypto-1_1.dll')
24 WinDLL(r'C:\Program Files (x86)\Galil\gclib\dll\x86\libssl-1_1.dll')
25 _gclib_path = r'C:\Program Files (x86)\Galil\gclib\dll\x86\gclib.dll'
26 _gclibo_path = r'C:\Program Files (x86)\Galil\gclib\dll\x86\gclibo.dll'
27 _gclib = WinDLL(_gclib_path)
28 _gclibo = WinDLL(_gclibo_path)
29 #Reassign symbol name, Python doesn't like @ in function names
30 #gclib calls
31 setattr(_gclib, 'GArrayDownload', getattr(_gclib, '_GArrayDownload@20'))
32 setattr(_gclib, 'GArrayUpload', getattr(_gclib, '_GArrayUpload@28'))
33 setattr(_gclib, 'GClose', getattr(_gclib, '_GClose@4'))
34 setattr(_gclib, 'GCommand', getattr(_gclib, '_GCommand@20'))
35 setattr(_gclib, 'GFirmwareDownload', getattr(_gclib, '_GFirmwareDownload@8'))
36 setattr(_gclib, 'GInterrupt', getattr(_gclib, '_GInterrupt@8'))
37 setattr(_gclib, 'GMessage', getattr(_gclib, '_GMessage@12'))
38 setattr(_gclib, 'GOpen', getattr(_gclib, '_GOpen@8'))
39 setattr(_gclib, 'GProgramDownload', getattr(_gclib, '_GProgramDownload@12'))
40 setattr(_gclib, 'GProgramUpload', getattr(_gclib, '_GProgramUpload@12'))
41 #gclibo calls (open source component/convenience functions)
42 setattr(_gclibo, 'GAddresses', getattr(_gclibo, '_GAddresses@8'))
43 setattr(_gclibo, 'GArrayDownloadFile', getattr(_gclibo, '_GArrayDownloadFile@8'))
44 setattr(_gclibo, 'GArrayUploadFile', getattr(_gclibo, '_GArrayUploadFile@12'))
45 setattr(_gclibo, 'GAssign', getattr(_gclibo, '_GAssign@8'))
46 setattr(_gclibo, 'GError', getattr(_gclibo, '_GError@12'))
47 setattr(_gclibo, 'GInfo', getattr(_gclibo, '_GInfo@12'))
48 setattr(_gclibo, 'GIpRequests', getattr(_gclibo, '_GIpRequests@8'))
49 setattr(_gclibo, 'GMotionComplete', getattr(_gclibo, '_GMotionComplete@8'))
50 setattr(_gclibo, 'GProgramDownloadFile', getattr(_gclibo, '_GProgramDownloadFile@12'))
51 setattr(_gclibo, 'GSleep', getattr(_gclibo, '_GSleep@4'))
52 setattr(_gclibo, 'GProgramUploadFile', getattr(_gclibo, '_GProgramUploadFile@8'))
53 setattr(_gclibo, 'GTimeout', getattr(_gclibo, '_GTimeout@8'))
54 setattr(_gclibo, 'GVersion', getattr(_gclibo, '_GVersion@8'))
55 setattr(_gclibo, 'GSetupDownloadFile', getattr(_gclibo, '_GSetupDownloadFile@20'))
56 setattr(_gclibo, 'GServerStatus', getattr(_gclibo, '_GServerStatus@8'))
57 setattr(_gclibo, 'GSetServer', getattr(_gclibo, '_GSetServer@4'))
58 setattr(_gclibo, 'GListServers', getattr(_gclibo, '_GListServers@8'))
59 setattr(_gclibo, 'GPublishServer', getattr(_gclibo, '_GPublishServer@12'))
60 setattr(_gclibo, 'GRemoteConnections', getattr(_gclibo, '_GRemoteConnections@8'))
61
62elif platform.system() == 'Linux':
63 cdll.LoadLibrary("libgclib.so.2")
64 _gclib = CDLL("libgclib.so.2")
65 cdll.LoadLibrary("libgclibo.so.2")
66 _gclibo = CDLL("libgclibo.so.2")
67
68elif platform.system() == 'Darwin': #OSX
69 _gclib_path = '/Applications/gclib/dylib/gclib.0.dylib'
70 _gclibo_path = '/Applications/gclib/dylib/gclibo.0.dylib'
71 cdll.LoadLibrary(_gclib_path)
72 _gclib = CDLL(_gclib_path)
73 cdll.LoadLibrary(_gclibo_path)
74 _gclibo = CDLL(_gclibo_path)
75
76
77
78# Python "typedefs"
79_GReturn = c_int #type for a return code
80_GCon = c_void_p #type for a Galil connection handle
81_GCon_ptr = POINTER(_GCon) #used for argtypes declaration
82_GSize = c_ulong #type for a Galil size variable
83_GSize_ptr = POINTER(_GSize) #used for argtypes declaration
84_GCStringIn = c_char_p #char*. In C it's const.
85_GCStringOut = c_char_p #char*
86_GOption = c_int #type for option variables, e.g. GArrayDownload
87_GStatus = c_ubyte #type for interrupt status bytes
88_GStatus_ptr = POINTER(_GStatus) #used for argtypes declaration
89
90#Define arguments and result type (if not C int type)
91#gclib calls
92_gclib.GArrayDownload.argtypes = [_GCon, _GCStringIn, _GOption, _GOption, _GCStringIn]
93_gclib.GArrayUpload.argtypes = [_GCon, _GCStringIn, _GOption, _GOption, _GOption, _GCStringOut, _GSize]
95_gclib.GCommand.argtypes = [_GCon, _GCStringIn, _GCStringOut, _GSize, _GSize_ptr]
96_gclib.GFirmwareDownload.argtypes = [_GCon, _GCStringIn]
97_gclib.GInterrupt.argtypes = [_GCon, _GStatus_ptr]
98_gclib.GMessage.argtypes = [_GCon, _GCStringOut, _GSize]
99_gclib.GOpen.argtypes = [_GCStringIn, _GCon_ptr]
100_gclib.GProgramDownload.argtypes = [_GCon, _GCStringIn, _GCStringIn]
101_gclib.GProgramUpload.argtypes = [_GCon, _GCStringOut, _GSize]
102#gclibo calls (open source component/convenience functions)
103_gclibo.GAddresses.argtypes = [_GCStringOut, _GSize]
104_gclibo.GArrayDownloadFile.argtypes = [_GCon, _GCStringIn]
105_gclibo.GArrayUploadFile.argtypes = [_GCon, _GCStringIn, _GCStringIn]
106_gclibo.GAssign.argtypes = [_GCStringIn, _GCStringIn]
107_gclibo.GError.argtypes = [_GReturn, _GCStringOut, _GSize]
109_gclibo.GError.argtypes = [_GCon, _GCStringOut, _GSize]
110_gclibo.GIpRequests.argtypes = [_GCStringOut, _GSize]
111_gclibo.GMotionComplete.argtypes = [_GCon, _GCStringIn]
112_gclibo.GProgramDownloadFile.argtypes = [_GCon, _GCStringIn, _GCStringIn]
115_gclibo.GProgramUploadFile.argtypes = [_GCon, _GCStringIn]
116_gclibo.GTimeout.argtypes = [_GCon, c_int]
117_gclibo.GVersion.argtypes = [_GCStringOut, _GSize]
118_gclibo.GServerStatus.argtypes = [_GCStringOut, _GSize]
119_gclibo.GSetServer.argtypes = [_GCStringIn]
120_gclibo.GListServers.argtypes = [_GCStringOut, _GSize]
121_gclibo.GPublishServer.argtypes = [_GCStringIn, _GOption, _GOption]
122_gclibo.GRemoteConnections.argtypes = [_GCStringOut, _GSize]
123_gclibo.GSetupDownloadFile.argtypes = [_GCon, _GCStringIn, _GOption, _GCStringOut, _GSize]
124
125#Set up some constants
126_enc = "ASCII" #byte encoding for going between python strings and c strings.
127_buf_size = 500000 #size of response buffer. Big enough to fit entire 4000 program via UL/LS, or 24000 elements of array data.
128_error_buf = create_string_buffer(128) #buffer for retrieving error code descriptions.
129
130def _rc(return_code):
131 """Checks return codes from gclib and raises a python error if result is exceptional."""
132 if return_code != 0:
133 _gclibo.GError(return_code, _error_buf, 128) #Get the library's error description
134 raise GclibError(str(_error_buf.value.decode(_enc)))
135 return
136
137class GclibError(Exception):
138 """Error class for non-zero gclib return codes."""
139 pass
140
141class py:
142 """Represents a single Python connection to a Galil Controller or PLC."""
143
144 def __init__(self):
145 """Constructor for the Connection class. Initializes gclib's handle and read buffer."""
146 self._gcon = _GCon(0) #handle to connection
147 self._buf = create_string_buffer(_buf_size)
148 self._timeout = 5000
149 return
150
151 def __del__(self):
152 """Destructor for the Connection class. Ensures close gets called to release Galil resource (Sockets, Kernel Driver, Com Port, etc)."""
153 self.GClose()
154 return
155
156 def _cc(self):
157 """Checks if connection is established, throws error if not."""
158 if self._gcon.value == None:
159 _rc(-1201) #G_CONNECTION_NOT_ESTABLISHED
160
161 def GOpen(self, address):
162 """
163 Opens a connection a galil controller.
164 See the gclib docs for address string formatting.
165 """
166 c_address = _GCStringIn(address.encode(_enc))
167 _rc(_gclib.GOpen(c_address, byref(self._gcon)))
168 return
169
170
171 def GClose(self):
172 """
173 Closes a connection to a Galil Controller.
174 """
175 if self._gcon.value != None:
176 _rc(_gclib.GClose(self._gcon))
177 self._gcon = _GCon(0)
178 return
179
180
181 def GCommand(self, command):
182 """
183 Performs a command-and-response transaction on the connection.
184 Trims the response.
185 """
186 self._cc()
187 c_command = _GCStringIn(command.encode(_enc))
188 _rc(_gclib.GCommand(self._gcon, c_command, self._buf, _buf_size, None))
189 response = str(self._buf.value.decode(_enc))
190 return response[:-3].strip() # trim trailing /r/n: and leading space
191
192
193 def GSleep(self, val):
194 """
195 Provides a blocking sleep call which can be useful for timing-based chores.
196 """
197 _gclibo.GSleep(val)
198 return
199
200
201 def GVersion(self):
202 """
203 Provides the gclib version number. Please include the output of this function on all support cases.
204 """
205 _rc(_gclibo.GVersion(self._buf, _buf_size))
206 return "py." + str(self._buf.value.decode(_enc))
207
208 def GServerStatus(self):
209 _rc(_gclibo.GServerStatus(self._buf, _buf_size))
210 return str(self._buf.value.decode(_enc))
211
212 def GSetServer(self, server_name):
213 c_server_name = _GCStringIn(server_name.encode(_enc))
214 _rc(_gclibo.GSetServer(c_server_name))
215 return
216
217 def GListServers(self):
218 _rc(_gclibo.GListServers(self._buf, _buf_size))
219 return str(self._buf.value.decode(_enc))
220
221 def GPublishServer(self, server_name, publish, save):
222 c_server_name = _GCStringIn(server_name.encode(_enc))
223 _rc(_gclibo.GPublishServer(c_server_name, publish, save))
224 return
225
226 def GRemoteConnections(self):
227 _rc(_gclibo.GRemoteConnections(self._buf, _buf_size))
228 return str(self._buf.value.decode(_enc))
229
230 def GInfo(self):
231 """
232 Provides a useful connection string. Please include the output of this function on all support cases.
233 """
234 _rc(_gclibo.GInfo(self._gcon, self._buf, _buf_size))
235 return str(self._buf.value.decode(_enc))
236
237
238 def GIpRequests(self):
239 """
240 Provides a dictionary of all Galil controllers requesting IP addresses via BOOT-P or DHCP.
241
242 Returns a dictionary mapping 'model-serial' --> 'mac address'
243 e.g. {'DMC4000-783': '00:50:4c:20:03:0f', 'DMC4103-9998': '00:50:4c:38:27:0e'}
244
245 Linux/OS X users must be root to use GIpRequests() and have UDP access to bind and listen on port 67.
246 """
247 _rc(_gclibo.GIpRequests(self._buf, _buf_size)) #get the c string from gclib
248 ip_req_dict = {}
249 for line in str(self._buf.value.decode(_enc)).splitlines():
250 line = line.replace(' ', '') #trim spaces throughout
251 if (line == ""): continue
252 fields = line.split(',')
253 #fields go [model, serial number, mac]
254 ip_req_dict[fields[0] + '-' + fields[1]] = fields[2] # e.g. DMC4000-783 maps to its MAC addr.
255 return ip_req_dict
256
257
258 def GAssign(self, ip, mac):
259 """
260 Assigns IP address over the Ethernet to a controller at a given MAC address.
261 Linux/OS X users must be root to use GAssign() and have UDP access to send on port 68.
262 """
263 c_ip = _GCStringIn(ip.encode(_enc))
264 c_mac = _GCStringIn(mac.encode(_enc))
265 _rc(_gclibo.GAssign(c_ip, c_mac))
266 return
267
268
269 def GAddresses(self):
270 """
271 Provides a dictionary of all available connection addresses.
272
273 Returns a dictionary mapping 'address' -> 'revision reports', where possible
274 e.g. {}
275 """
276 _rc(_gclibo.GAddresses(self._buf, _buf_size))
277 addr_dict = {}
278 for line in str(self._buf.value.decode(_enc)).splitlines():
279 fields = line.split(',')
280 if len(fields) >= 2:
281 addr_dict[fields[0]] = fields[1]
282 else:
283 addr_dict[fields[0]] = ''
284
285 return addr_dict
286
287
288 def GProgramDownload(self, program, preprocessor=""):
289 """
290 Downloads a program to the controller's program buffer.
291 See the gclib docs for preprocessor options.
292 """
293 self._cc()
294 c_prog = _GCStringIn(program.encode(_enc))
295 c_pre = _GCStringIn(preprocessor.encode(_enc))
296 _rc(_gclib.GProgramDownload(self._gcon, c_prog, c_pre))
297 return
298
299
300 def GProgramUpload(self):
301 """
302 Uploads a program from the controller's program buffer.
303 """
304 self._cc()
305 _rc(_gclib.GProgramUpload(self._gcon, self._buf, _buf_size))
306 return str(self._buf.value.decode(_enc))
307
308
309 def GProgramDownloadFile(self, file_path, preprocessor=""):
310 """
311 Program download from file.
312 See the gclib docs for preprocessor options.
313 """
314 self._cc()
315 c_path = _GCStringIn(file_path.encode(_enc))
316 c_pre = _GCStringIn(preprocessor.encode(_enc))
317 _rc(_gclibo.GProgramDownloadFile(self._gcon, c_path, c_pre))
318 return
319
320 def GProgramUploadFile(self, file_path):
321 """
322 Program upload to file.
323 """
324 self._cc()
325 c_path = _GCStringIn(file_path.encode(_enc))
326 _rc(_gclibo.GProgramUploadFile(self._gcon, c_path))
327 return
328
329 def GArrayDownload(self, name, first, last, array_data):
330 """
331 Downloads array data to a pre-dimensioned array in the controller's array table.
332 array_data should be a list of values (e.g. int or float)
333 """
334 self._cc()
335 c_name = _GCStringIn(name.encode(_enc))
336 array_string = ""
337 for val in array_data:
338 array_string += str(val) + ","
339 c_data = _GCStringIn(array_string[:-1].encode(_enc)) #trim trailing command
340 _rc(_gclib.GArrayDownload(self._gcon, c_name, first, last, c_data))
341 return
342
343
344 def GArrayUploadFile(self, file_path, names = []):
345 """
346 Uploads the entire controller array table or a subset and saves the data as a csv file specified by file_path.
347 names is optional and should be a list of array names on the controller.
348 """
349 self._cc()
350 c_path = _GCStringIn(file_path.encode(_enc))
351 names_string = ''
352 c_names = _GCStringIn(''.encode(_enc)) #in case empty list provided
353 for name in names:
354 names_string += name + ' '
355
356 c_names = _GCStringIn(names_string[:-1].encode(_enc)) #trim trailing space
357 _rc(_gclibo.GArrayUploadFile(self._gcon, c_path, c_names))
358 return
359
360
361 def GArrayDownloadFile(self, file_path):
362 """
363 Downloads a csv file containing array data at file_path.
364 """
365 self._cc()
366 c_path = _GCStringIn(file_path.encode(_enc))
367 _rc(_gclibo.GArrayDownloadFile(self._gcon, c_path))
368 return
369
370
371 def GArrayUpload(self, name, first, last):
372 """
373 Uploads array data from the controller's array table.
374 """
375 self._cc()
376 c_name = _GCStringIn(name.encode(_enc))
377 _rc(_gclib.GArrayUpload(self._gcon, c_name, first, last, 1, self._buf, _buf_size)) #1 is comma delimiter
378 string_list = str(self._buf.value.decode(_enc)).split(',')
379 float_list = []
380 for s in string_list:
382 return float_list
383
384
385 def GTimeout(self, timeout):
386 """
387 Set the library timeout. Set to -1 to use the intitial library timeout, as specified in GOpen.
388 """
389 self._cc()
390 _rc(_gclibo.GTimeout(self._gcon, timeout))
391 self._timeout = timeout
392 return
393
394
395 @property
396 def timeout(self):
397 """
398 Convenience property read access to timeout value. If -1, gclib uses the initial library timeout, as specified in GOpen.
399 """
400 return self._timeout
401
402 @timeout.setter
403 def timeout(self, timeout):
404 """
405 Convenience property write access to timeout value. Set to -1 to use the initial library timeout, as specified in GOpen.
406 """
407 self.GTimeout(timeout)
408 return
409
410
411 def GFirmwareDownload(self, file_path):
412 """
413 Upgrade firmware.
414 """
415 self._cc()
416 c_path = _GCStringIn(file_path.encode(_enc))
417 _rc(_gclib.GFirmwareDownload(self._gcon, c_path))
418 return
419
420
421 def GMessage(self):
422 """
423 Provides access to unsolicited messages from the controller.
424 """
425 self._cc()
426 _rc(_gclib.GMessage(self._gcon, self._buf, _buf_size))
427 return str(self._buf.value.decode(_enc))
428
429
430 def GMotionComplete(self, axes):
431 """
432 Blocking call that returns once all axes specified have completed their motion.
433 """
434 self._cc()
435 c_axes = _GCStringIn(axes.encode(_enc))
436 _rc(_gclibo.GMotionComplete(self._gcon, c_axes))
437 return
438
439 def GInterrupt(self):
440 """
441 Provides access to PCI and UDP interrupts from the controller.
442 """
443 self._cc()
444 status = _GStatus(0)
445 _rc(_gclib.GInterrupt(self._gcon, byref(status)))
446 return status.value
447
448 def GSetupDownloadFile(self, file_path, options):
449 """
450 Downloads specified sectors from a Galil compressed backup (gcb) file to a controller.
451
452 Returns a dictionary with the controller information stored in the gcb file.
453 If options is specified as 0, an additional "options" key will be in the dictionary indicating the info sectors available in the gcb
454 """
455 self._cc()
456 c_path = _GCStringIn(file_path.encode(_enc))
457
458 rc = _gclibo.GSetupDownloadFile(self._gcon, c_path, options, self._buf, _buf_size)
459 if (options != 0):
460 _rc(rc)
461
462 info_dict = {}
463 for line in str(self._buf.value.decode(_enc)).split("\"\n"):
464 fields = line.split(',',1)
465
466 if (fields[0] == ""): continue
467 elif len(fields) >= 2:
468 info_dict[fields[0].strip("\"\'")] = fields[1].strip("\"\'")
469 else:
470 info_dict[fields[0].strip("\"\'")] = ''
471
472 if (options == 0):
473 info_dict["options"] = rc
474
475 return info_dict
GProgramUploadFile(self, file_path)
Definition gclib.py:320
GFirmwareDownload(self, file_path)
Definition gclib.py:411
GInfo(self)
Definition gclib.py:230
GMotionComplete(self, axes)
Definition gclib.py:430
GProgramUpload(self)
Definition gclib.py:300
GSleep(self, val)
Definition gclib.py:193
GArrayUpload(self, name, first, last)
Definition gclib.py:371
GTimeout(self, timeout)
Definition gclib.py:385
GProgramDownloadFile(self, file_path, preprocessor="")
Definition gclib.py:309
GVersion(self)
Definition gclib.py:201
GSetupDownloadFile(self, file_path, options)
Definition gclib.py:448
GClose(self)
Definition gclib.py:171
GProgramDownload(self, program, preprocessor="")
Definition gclib.py:288
GAddresses(self)
Definition gclib.py:269
GIpRequests(self)
Definition gclib.py:238
GArrayDownloadFile(self, file_path)
Definition gclib.py:361
__del__(self)
Definition gclib.py:151
GMessage(self)
Definition gclib.py:421
__init__(self)
Definition gclib.py:144
GOpen(self, address)
Definition gclib.py:161
_cc(self)
Definition gclib.py:156
GCommand(self, command)
Definition gclib.py:181
GInterrupt(self)
Definition gclib.py:439
timeout(self)
Definition gclib.py:396
GAssign(self, ip, mac)
Definition gclib.py:258
GArrayDownload(self, name, first, last, array_data)
Definition gclib.py:329
GArrayUploadFile(self, file_path, names=[])
Definition gclib.py:344
GReturn vector(GCon g, char *file)
Puts controller into Vector Mode and accepts a file defining vector points.
Definition vector.cpp:36