MultiPyVu 3.1.0__tar.gz → 3.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {multipyvu-3.1.0/src/MultiPyVu.egg-info → multipyvu-3.1.2}/PKG-INFO +13 -3
- {multipyvu-3.1.0 → multipyvu-3.1.2}/README.md +12 -1
- {multipyvu-3.1.0 → multipyvu-3.1.2}/setup.py +3 -3
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/CommandMultiVu.py +1 -1
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/CommandSdo.py +56 -58
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/__version.py +1 -1
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/exceptions.py +1 -1
- multipyvu-3.1.2/src/MultiPyVu/logging_config.yaml +42 -0
- multipyvu-3.1.2/src/MultiPyVu/scripts/helper_scripts.py +118 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/sdo_object.py +37 -1
- {multipyvu-3.1.0 → multipyvu-3.1.2/src/MultiPyVu.egg-info}/PKG-INFO +13 -3
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu.egg-info/SOURCES.txt +2 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu.egg-info/requires.txt +0 -1
- {multipyvu-3.1.0 → multipyvu-3.1.2}/LICENSE +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/pyproject.toml +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/setup.cfg +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/BRT.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/CommandChamber.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/CommandField.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/CommandTemperature.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/CommandWaitFor.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/Command_factory.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/ICommand.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/IEventManager.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/IServer.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuClient.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuClient_base.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuDataFile/MultiVuDataFile.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuDataFile/__init__.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuDataFile/__version.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuDataFile/is_pathname_valid.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/MultiVuServer.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/ParseInputs.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/SocketMessage.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/SocketMessageClient.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/SocketMessageServer.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/__init__.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/__main__.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/check_windows_esc.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/font/Play-Bold.ttf +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/font/Play-Regular.ttf +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/generate_sdo_objects.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/gui/Controller.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/gui/IController.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/gui/IView.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/gui/ViewFactory.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/gui/ViewTk.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/gui/__init__.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/images/Q.png +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/images/QD_logo.jpg +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/instrument.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/logging_config.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/project_vars.py +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu/scripts/whats_my_ip_address.cmd +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu.egg-info/dependency_links.txt +0 -0
- {multipyvu-3.1.0 → multipyvu-3.1.2}/src/MultiPyVu.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: MultiPyVu
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.2
|
|
4
4
|
Summary: Control MultiVu using Python
|
|
5
5
|
Author-email: Damon D Jackson <djackson@qdusa.com>
|
|
6
6
|
Maintainer-email: "Quantum Design, Inc." <apps@qdusa.com>
|
|
@@ -38,7 +38,6 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
38
38
|
Requires-Python: >=3.8
|
|
39
39
|
Description-Content-Type: text/markdown
|
|
40
40
|
License-File: LICENSE
|
|
41
|
-
Requires-Dist: typing
|
|
42
41
|
Requires-Dist: pandas
|
|
43
42
|
Requires-Dist: pywin32>=300; platform_system == "Windows"
|
|
44
43
|
Requires-Dist: pillow
|
|
@@ -436,17 +435,28 @@ client = mpv.Client(port=6000)
|
|
|
436
435
|
- A log file named QdMultiVu.log shows the traffic between the server and client which can also be useful during troubleshooting.
|
|
437
436
|
|
|
438
437
|
## Changelog<a class="anchor" id="changelog"></a>
|
|
438
|
+
**3.1.2**
|
|
439
|
+
- October 2024
|
|
440
|
+
- Fixed a bug which truncated numbers
|
|
441
|
+
|
|
442
|
+
**3.1.1**
|
|
443
|
+
- October 2024
|
|
444
|
+
- Updated the installer to include missing files.
|
|
445
|
+
|
|
439
446
|
**3.1.0**
|
|
440
447
|
- October 2024
|
|
441
448
|
- Log the version number when the Client connects to the Server.
|
|
442
449
|
- Check that the Server and Client are running the same version.
|
|
443
450
|
- Increase the number of backup logs to 5.
|
|
444
451
|
- Bugfix to allow Client to run on Linux or Mac systems.
|
|
445
|
-
- Corrected a bug that prevented the Server from recognizing PPMS and MPMS3 MultiVu flavors
|
|
446
452
|
- Limit server to hosting only one client at a time.
|
|
447
453
|
- Add the ability to call -quit, -is_running, -status, -get_ip from the command line using python -m MultiPyVu
|
|
448
454
|
- Miscellaneous bug fixes and refactoring.
|
|
449
455
|
|
|
456
|
+
**2.2.0**
|
|
457
|
+
- January 2024
|
|
458
|
+
- Corrected a bug that prevented the Server from recognizing PPMS and MPMS3 MultiVu flavors
|
|
459
|
+
|
|
450
460
|
**2.1.4**
|
|
451
461
|
- October 2023
|
|
452
462
|
- Import full module as MultiPyVu. Instead of loading the three sub-modules as:
|
|
@@ -390,17 +390,28 @@ client = mpv.Client(port=6000)
|
|
|
390
390
|
- A log file named QdMultiVu.log shows the traffic between the server and client which can also be useful during troubleshooting.
|
|
391
391
|
|
|
392
392
|
## Changelog<a class="anchor" id="changelog"></a>
|
|
393
|
+
**3.1.2**
|
|
394
|
+
- October 2024
|
|
395
|
+
- Fixed a bug which truncated numbers
|
|
396
|
+
|
|
397
|
+
**3.1.1**
|
|
398
|
+
- October 2024
|
|
399
|
+
- Updated the installer to include missing files.
|
|
400
|
+
|
|
393
401
|
**3.1.0**
|
|
394
402
|
- October 2024
|
|
395
403
|
- Log the version number when the Client connects to the Server.
|
|
396
404
|
- Check that the Server and Client are running the same version.
|
|
397
405
|
- Increase the number of backup logs to 5.
|
|
398
406
|
- Bugfix to allow Client to run on Linux or Mac systems.
|
|
399
|
-
- Corrected a bug that prevented the Server from recognizing PPMS and MPMS3 MultiVu flavors
|
|
400
407
|
- Limit server to hosting only one client at a time.
|
|
401
408
|
- Add the ability to call -quit, -is_running, -status, -get_ip from the command line using python -m MultiPyVu
|
|
402
409
|
- Miscellaneous bug fixes and refactoring.
|
|
403
410
|
|
|
411
|
+
**2.2.0**
|
|
412
|
+
- January 2024
|
|
413
|
+
- Corrected a bug that prevented the Server from recognizing PPMS and MPMS3 MultiVu flavors
|
|
414
|
+
|
|
404
415
|
**2.1.4**
|
|
405
416
|
- October 2023
|
|
406
417
|
- Import full module as MultiPyVu. Instead of loading the three sub-modules as:
|
|
@@ -46,13 +46,13 @@ setup(
|
|
|
46
46
|
"images/*.jpg",
|
|
47
47
|
"images/*.png",
|
|
48
48
|
"font/*.ttf",
|
|
49
|
-
"scripts
|
|
50
|
-
"MultiVuDataFile/*.py"
|
|
49
|
+
"scripts/*",
|
|
50
|
+
"MultiVuDataFile/*.py",
|
|
51
|
+
"logging_config.yaml"
|
|
51
52
|
]
|
|
52
53
|
},
|
|
53
54
|
python_requires=">=3.8",
|
|
54
55
|
install_requires=[
|
|
55
|
-
"typing",
|
|
56
56
|
"pandas",
|
|
57
57
|
"pywin32>=300; platform_system=='Windows'",
|
|
58
58
|
"pillow",
|
|
@@ -110,7 +110,7 @@ class CommandMultiVuBase():
|
|
|
110
110
|
msg += 'which could mean MultiVu is not running.'
|
|
111
111
|
raise MultiPyVuError(msg)
|
|
112
112
|
|
|
113
|
-
result_string = result if isinstance(result, str) else
|
|
113
|
+
result_string = result if isinstance(result, str) else str(result)
|
|
114
114
|
return f'{result_string},{mv_command.units},{code_in_words}'
|
|
115
115
|
|
|
116
116
|
def set_state(self, command: str, arg_string: str) -> str:
|
|
@@ -157,8 +157,8 @@ class CommandSdoBase(ICommand):
|
|
|
157
157
|
|
|
158
158
|
@abstractmethod
|
|
159
159
|
def get_state_server(self,
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
value_variant,
|
|
161
|
+
state_variant,
|
|
162
162
|
params: str = ''):
|
|
163
163
|
raise NotImplementedError
|
|
164
164
|
|
|
@@ -187,7 +187,10 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
187
187
|
super().__init__()
|
|
188
188
|
self._mvu = multivu_win32com
|
|
189
189
|
|
|
190
|
-
def _binary_to_value(self,
|
|
190
|
+
def _binary_to_value(self,
|
|
191
|
+
sdo: SdoObject,
|
|
192
|
+
length: win32.VARIANT,
|
|
193
|
+
val: win32.VARIANT) -> Union[str, int, float]:
|
|
191
194
|
"""
|
|
192
195
|
Convert a binary value from reading an SDO into its correct
|
|
193
196
|
type.
|
|
@@ -195,9 +198,9 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
195
198
|
Parameters:
|
|
196
199
|
-----------
|
|
197
200
|
sdo: SdoObject
|
|
198
|
-
|
|
201
|
+
length: win32com.client.VARIANT
|
|
199
202
|
This is the parameter used in ReadSDO which
|
|
200
|
-
holds the length of the value
|
|
203
|
+
holds the length of the value that was read.
|
|
201
204
|
val: win32com.client.VARIANT
|
|
202
205
|
This is the parameter used in ReadSDO which
|
|
203
206
|
holds the value being read.
|
|
@@ -208,31 +211,34 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
208
211
|
python format of string, int, or float.
|
|
209
212
|
"""
|
|
210
213
|
if sdo.val_type is val_type.string_t:
|
|
211
|
-
var_memory = val.value[0:
|
|
214
|
+
var_memory = val.value[0:length.value - 1]
|
|
212
215
|
return_val = bytes(var_memory).decode('utf-8')
|
|
213
|
-
elif sdo.val_type
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
b = list(bytes(val.value)[0:
|
|
216
|
+
elif sdo.val_type in (val_type.short_t,
|
|
217
|
+
val_type.int_t,
|
|
218
|
+
val_type.long_t):
|
|
219
|
+
b = list(bytes(val.value)[0:length.value])
|
|
217
220
|
return_val = int.from_bytes(b,
|
|
218
221
|
byteorder='little',
|
|
219
222
|
signed=True)
|
|
220
|
-
elif sdo.val_type
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
b = list(bytes(val.value)[0:
|
|
223
|
+
elif sdo.val_type in (val_type.ushort_t,
|
|
224
|
+
val_type.uint_t,
|
|
225
|
+
val_type.ulong_t):
|
|
226
|
+
b = list(bytes(val.value)[0:length.value])
|
|
224
227
|
return_val = int.from_bytes(b,
|
|
225
228
|
byteorder='little',
|
|
226
229
|
signed=False)
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
elif sdo.val_type in (val_type.single_t,
|
|
231
|
+
val_type.double_t):
|
|
232
|
+
b = bytes(val.value)[0:length.value]
|
|
229
233
|
# format = '<f' means little endian ('>f' is big endian)
|
|
230
234
|
[return_val] = struct.unpack('<f', b)
|
|
235
|
+
else:
|
|
236
|
+
raise ValueError('unsupported variant type')
|
|
231
237
|
return return_val
|
|
232
238
|
|
|
233
239
|
def _value_to_binary(self,
|
|
234
240
|
sdo: SdoObject,
|
|
235
|
-
val: Union[str, int, float]) ->
|
|
241
|
+
val: Union[str, int, float]) -> bytes:
|
|
236
242
|
"""
|
|
237
243
|
Convert a value being sent to WriteSDO into binary.
|
|
238
244
|
|
|
@@ -245,41 +251,24 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
245
251
|
|
|
246
252
|
Returns:
|
|
247
253
|
--------
|
|
248
|
-
|
|
249
|
-
and the second item the value being set in binary.
|
|
254
|
+
The value being set in binary.
|
|
250
255
|
"""
|
|
251
|
-
|
|
256
|
+
sdo_length = sdo.object_length()
|
|
252
257
|
sdo_val = b''
|
|
253
|
-
if sdo.val_type
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
sdo_val = int.to_bytes(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
elif sdo.val_type
|
|
260
|
-
sdo.val_type is val_type.uint_t:
|
|
261
|
-
len = 2
|
|
262
|
-
sdo_val = int.to_bytes(int(val), len,
|
|
263
|
-
byteorder='little',
|
|
264
|
-
signed=False)
|
|
265
|
-
elif sdo.val_type is val_type.long_t or \
|
|
266
|
-
sdo.val_type is val_type.ulong_t:
|
|
267
|
-
len = 4
|
|
268
|
-
sdo_val = int.to_bytes(int(val), len,
|
|
269
|
-
byteorder='little',
|
|
270
|
-
signed=False)
|
|
271
|
-
elif sdo.val_type is val_type.single_t:
|
|
272
|
-
len = 2
|
|
273
|
-
sdo_val = struct.pack('<f', float(val))
|
|
274
|
-
elif sdo.val_type is val_type.double_t:
|
|
275
|
-
len = 4
|
|
258
|
+
if sdo.val_type in (val_type.short_t, val_type.ushort_t):
|
|
259
|
+
sdo_val = int(val).to_bytes(sdo_length, 'little', signed=False)
|
|
260
|
+
elif sdo.val_type in (val_type.int_t, val_type.uint_t):
|
|
261
|
+
sdo_val = int(val).to_bytes(sdo_length, 'little', signed=False)
|
|
262
|
+
elif sdo.val_type in (val_type.long_t, val_type.ulong_t):
|
|
263
|
+
sdo_val = int(val).to_bytes(sdo_length, 'little', signed=False)
|
|
264
|
+
elif sdo.val_type in (val_type.single_t, val_type.double_t):
|
|
276
265
|
sdo_val = struct.pack('<f', float(val))
|
|
277
266
|
elif sdo.val_type is val_type.string_t:
|
|
278
267
|
sdo_val = val.encode()
|
|
279
268
|
else:
|
|
280
269
|
msg = 'Unsupported val_type: ' + str(sdo)
|
|
281
270
|
raise ValueError(msg)
|
|
282
|
-
return
|
|
271
|
+
return sdo_val
|
|
283
272
|
|
|
284
273
|
def read_sdo(self, sdo: SdoObject,) -> Tuple:
|
|
285
274
|
"""
|
|
@@ -296,7 +285,7 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
296
285
|
a tuple whose first term is the CAN error and the second
|
|
297
286
|
term is the abort error.
|
|
298
287
|
"""
|
|
299
|
-
|
|
288
|
+
length_variant = win32.VARIANT(
|
|
300
289
|
pythoncom.VT_BYREF | pythoncom.VT_I4,
|
|
301
290
|
0)
|
|
302
291
|
value_variant = win32.VARIANT(
|
|
@@ -311,7 +300,7 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
311
300
|
can_error = self._mvu.ReadSDO(sdo.node,
|
|
312
301
|
sdo.index,
|
|
313
302
|
sdo.sub,
|
|
314
|
-
|
|
303
|
+
length_variant,
|
|
315
304
|
value_variant,
|
|
316
305
|
error_variant)
|
|
317
306
|
self.return_state = self._errors_to_str(can_error,
|
|
@@ -327,7 +316,9 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
327
316
|
msg += f'while reading ({str(sdo)})'
|
|
328
317
|
raise MultiPyVuError(msg)
|
|
329
318
|
else:
|
|
330
|
-
return_val = self._binary_to_value(sdo,
|
|
319
|
+
return_val = self._binary_to_value(sdo,
|
|
320
|
+
length_variant,
|
|
321
|
+
value_variant)
|
|
331
322
|
|
|
332
323
|
return return_val, self.return_state
|
|
333
324
|
|
|
@@ -348,13 +339,11 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
348
339
|
--------
|
|
349
340
|
string with the error from MultiVu
|
|
350
341
|
"""
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
pythoncom.VT_BYREF | pythoncom.VT_I4,
|
|
354
|
-
len)
|
|
342
|
+
binary_val = self._value_to_binary(sdo, val)
|
|
343
|
+
data_length = sdo.object_length()
|
|
355
344
|
value_variant = win32.VARIANT(
|
|
356
345
|
pythoncom.VT_BYREF | pythoncom.VT_VARIANT,
|
|
357
|
-
|
|
346
|
+
binary_val)
|
|
358
347
|
error_variant = win32.VARIANT(
|
|
359
348
|
pythoncom.VT_BYREF | pythoncom.VT_I4,
|
|
360
349
|
0)
|
|
@@ -363,7 +352,7 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
363
352
|
can_error = self._mvu.WriteSDO(sdo.node,
|
|
364
353
|
sdo.index,
|
|
365
354
|
sdo.sub,
|
|
366
|
-
|
|
355
|
+
data_length,
|
|
367
356
|
value_variant,
|
|
368
357
|
error_variant)
|
|
369
358
|
self.return_state = self._errors_to_str(can_error,
|
|
@@ -379,14 +368,20 @@ class CommandSdoImp(CommandSdoBase):
|
|
|
379
368
|
self.logger_client.debug(msg)
|
|
380
369
|
return self.return_state
|
|
381
370
|
|
|
382
|
-
def get_state_server(self,
|
|
371
|
+
def get_state_server(self,
|
|
372
|
+
value_variant,
|
|
373
|
+
state_variant,
|
|
374
|
+
params: str) -> Tuple:
|
|
383
375
|
"""
|
|
384
376
|
Returns a tuple of the SDO query result and the can_error number.
|
|
385
377
|
|
|
378
|
+
Note that the first two input parameters are unused, but included
|
|
379
|
+
because the other CommandXXX classes use them.
|
|
380
|
+
|
|
386
381
|
Parameters:
|
|
387
382
|
-----------
|
|
388
|
-
value_variant:
|
|
389
|
-
state_variant:
|
|
383
|
+
value_variant: (not used)
|
|
384
|
+
state_variant: (not used)
|
|
390
385
|
params: str
|
|
391
386
|
The string representation of an sdo_object
|
|
392
387
|
|
|
@@ -434,10 +429,13 @@ class CommandSdoSim(CommandSdoBase):
|
|
|
434
429
|
"""
|
|
435
430
|
Returns a tuple of the SDO query result and the can_error number.
|
|
436
431
|
|
|
432
|
+
Note that the first two input parameters are unused, but included
|
|
433
|
+
because the other CommandXXX classes use them.
|
|
434
|
+
|
|
437
435
|
Parameters:
|
|
438
436
|
-----------
|
|
439
|
-
value_variant:
|
|
440
|
-
state_variant:
|
|
437
|
+
value_variant: (not used)
|
|
438
|
+
state_variant: (not used)
|
|
441
439
|
params: str
|
|
442
440
|
The string representation of an SdoObject
|
|
443
441
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
__version__ = "3.1.
|
|
2
|
+
__version__ = "3.1.2"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
disable_existing_loggers: True
|
|
3
|
+
formatters:
|
|
4
|
+
show_name:
|
|
5
|
+
format: '%(name)s - %(message)s'
|
|
6
|
+
no_name:
|
|
7
|
+
format: '%(message)s'
|
|
8
|
+
debug:
|
|
9
|
+
format: '%(asctime)-27s %(name)-20s %(levelname)-8s %(message)s'
|
|
10
|
+
gui:
|
|
11
|
+
format: '%(asctime)s - %(message)s'
|
|
12
|
+
datefmt: '%m-%d %H:%M'
|
|
13
|
+
handlers:
|
|
14
|
+
console:
|
|
15
|
+
class: logging.StreamHandler
|
|
16
|
+
level: INFO
|
|
17
|
+
formatter: show_name
|
|
18
|
+
stream: ext://sys.stdout
|
|
19
|
+
file:
|
|
20
|
+
class: logging.handlers.RotatingFileHandler
|
|
21
|
+
level: DEBUG
|
|
22
|
+
formatter: debug
|
|
23
|
+
filename: debug
|
|
24
|
+
maxBytes: 4194304 # 2^22
|
|
25
|
+
backupCount: 5
|
|
26
|
+
loggers:
|
|
27
|
+
MultiVuServer:
|
|
28
|
+
level: DEBUG
|
|
29
|
+
handlers: [console, file]
|
|
30
|
+
text_widget: text_widget
|
|
31
|
+
propagate: False
|
|
32
|
+
MultiVuClient:
|
|
33
|
+
level: DEBUG
|
|
34
|
+
handlers: [console, file]
|
|
35
|
+
propagate: False
|
|
36
|
+
UnitTest:
|
|
37
|
+
level: DEBUG
|
|
38
|
+
handlers: [console, file]
|
|
39
|
+
propagate: False
|
|
40
|
+
root:
|
|
41
|
+
level: WARNING
|
|
42
|
+
handlers: [console]
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A few helpful scripts used in the MultiPyVu module
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from os import path
|
|
6
|
+
from sys import platform
|
|
7
|
+
import subprocess
|
|
8
|
+
import re
|
|
9
|
+
|
|
10
|
+
from MultiPyVu.MultiVuClient import Client
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def absolute_path(filename: str) -> str:
|
|
14
|
+
"""
|
|
15
|
+
Finds the absolute path of a file based on its location
|
|
16
|
+
relative to the gui module
|
|
17
|
+
|
|
18
|
+
Parameters:
|
|
19
|
+
-----------
|
|
20
|
+
filename: str
|
|
21
|
+
The file location based on its relative path from the gui module
|
|
22
|
+
"""
|
|
23
|
+
abs_path = path.abspath(
|
|
24
|
+
path.join(path.dirname(
|
|
25
|
+
__file__), './'))
|
|
26
|
+
return path.join(abs_path, filename)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_ip():
|
|
30
|
+
"""
|
|
31
|
+
The IP address for the computer
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
--------
|
|
35
|
+
String with the IP address
|
|
36
|
+
"""
|
|
37
|
+
ip_output_str = ''
|
|
38
|
+
search_str = r'([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})'
|
|
39
|
+
if platform == 'win32':
|
|
40
|
+
ip_addr_script = 'whats_my_ip_address.cmd'
|
|
41
|
+
ip_addr_script = absolute_path(ip_addr_script)
|
|
42
|
+
proc = subprocess.run([ip_addr_script],
|
|
43
|
+
capture_output=True,
|
|
44
|
+
text=True)
|
|
45
|
+
if proc.returncode != 0:
|
|
46
|
+
print(proc.stderr)
|
|
47
|
+
raise Exception(proc.stderr)
|
|
48
|
+
ip_result = re.findall(search_str, proc.stdout)
|
|
49
|
+
if len(ip_result) == 1:
|
|
50
|
+
ip_address = ip_result[0]
|
|
51
|
+
else:
|
|
52
|
+
# using this suggestion:
|
|
53
|
+
# https://apple.stackexchange.com/questions/20547/how-do-i-find-my-ip-address-from-the-command-line
|
|
54
|
+
ifconfig_proc = subprocess.Popen(["ifconfig"],
|
|
55
|
+
stdout=subprocess.PIPE,
|
|
56
|
+
text=True)
|
|
57
|
+
grep_proc = subprocess.Popen(["grep", "inet"],
|
|
58
|
+
stdin=ifconfig_proc.stdout,
|
|
59
|
+
stdout=subprocess.PIPE,
|
|
60
|
+
text=True)
|
|
61
|
+
ip_output_str, err = grep_proc.communicate()
|
|
62
|
+
if err is not None:
|
|
63
|
+
print(err)
|
|
64
|
+
raise Exception(grep_proc.stderr)
|
|
65
|
+
ip_result = re.findall(search_str, ip_output_str)
|
|
66
|
+
if '127.0.0.1' in ip_result:
|
|
67
|
+
ip_result.remove('127.0.0.1')
|
|
68
|
+
if len(ip_result) >= 1:
|
|
69
|
+
ip_address = ip_result[0]
|
|
70
|
+
return ip_address
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def run_status(ip: str, port: int):
|
|
74
|
+
"""
|
|
75
|
+
Queries the server for its status.
|
|
76
|
+
"""
|
|
77
|
+
ip_address = ip
|
|
78
|
+
if ip_address == '0.0.0.0':
|
|
79
|
+
ip_address = 'localhost'
|
|
80
|
+
|
|
81
|
+
client = Client(host=ip_address,
|
|
82
|
+
port=port)
|
|
83
|
+
response = client.get_server_status()
|
|
84
|
+
print(f'Server status: {response}')
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def is_running(ip: str, port: int):
|
|
88
|
+
"""
|
|
89
|
+
Queries the server to see if it is running
|
|
90
|
+
"""
|
|
91
|
+
ip_address = ip
|
|
92
|
+
if ip_address == '0.0.0.0':
|
|
93
|
+
ip_address = 'localhost'
|
|
94
|
+
|
|
95
|
+
client = Client(host=ip_address,
|
|
96
|
+
port=port)
|
|
97
|
+
response = client.is_server_running()
|
|
98
|
+
if response:
|
|
99
|
+
print(f'Server is running at {client.address}')
|
|
100
|
+
else:
|
|
101
|
+
print(f'Server not running at {client.address}')
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def force_quit(ip: str, port: int) -> str:
|
|
105
|
+
"""
|
|
106
|
+
Quits the server.
|
|
107
|
+
"""
|
|
108
|
+
ip_address = ip
|
|
109
|
+
if ip_address == '0.0.0.0':
|
|
110
|
+
ip_address = 'localhost'
|
|
111
|
+
|
|
112
|
+
client = Client(host=ip_address,
|
|
113
|
+
port=port)
|
|
114
|
+
response = client.force_quit_server()
|
|
115
|
+
if response:
|
|
116
|
+
return response
|
|
117
|
+
else:
|
|
118
|
+
return f'Sent quit command to {client.address}'
|
|
@@ -37,6 +37,17 @@ class SdoObject():
|
|
|
37
37
|
The string can be converted into an sdo_object by calling
|
|
38
38
|
.str_to_obj(string), which is a static method and returns
|
|
39
39
|
an sdo_object.
|
|
40
|
+
|
|
41
|
+
Parameters:
|
|
42
|
+
-----------
|
|
43
|
+
nodID: int
|
|
44
|
+
The node number
|
|
45
|
+
sdo_index: int
|
|
46
|
+
This should be represented in hex. For example, 0x1008.
|
|
47
|
+
sub_index: int
|
|
48
|
+
This should be represented in hex. For example, 0x0.
|
|
49
|
+
val_t: val_type
|
|
50
|
+
Specify the type.
|
|
40
51
|
"""
|
|
41
52
|
def __init__(self,
|
|
42
53
|
nodeID: int,
|
|
@@ -44,7 +55,7 @@ class SdoObject():
|
|
|
44
55
|
sub_index: int,
|
|
45
56
|
val_t: val_type):
|
|
46
57
|
if (nodeID > 63) or (nodeID < 0):
|
|
47
|
-
msg = f'Invalid
|
|
58
|
+
msg = f'Invalid nodeID: {nodeID}'
|
|
48
59
|
raise ValueError(msg)
|
|
49
60
|
if (sdo_index > 0xFFFF) or (sdo_index < 0):
|
|
50
61
|
msg = f'Invalid SDO index: {sdo_index}'
|
|
@@ -99,3 +110,28 @@ class SdoObject():
|
|
|
99
110
|
s = int(sub_index, 16)
|
|
100
111
|
v_t = val_type[t]
|
|
101
112
|
return SdoObject(n, i, s, v_t)
|
|
113
|
+
|
|
114
|
+
def object_length(self) -> int:
|
|
115
|
+
"""
|
|
116
|
+
Get the byte size
|
|
117
|
+
"""
|
|
118
|
+
if self.val_type is val_type.short_t:
|
|
119
|
+
return 1
|
|
120
|
+
elif self.val_type is val_type.int_t:
|
|
121
|
+
return 2
|
|
122
|
+
elif self.val_type is val_type.single_t:
|
|
123
|
+
return 2
|
|
124
|
+
elif self.val_type is val_type.string_t:
|
|
125
|
+
return 1
|
|
126
|
+
elif self.val_type is val_type.ushort_t:
|
|
127
|
+
return 1
|
|
128
|
+
elif self.val_type is val_type.uint_t:
|
|
129
|
+
return 2
|
|
130
|
+
elif self.val_type is val_type.double_t:
|
|
131
|
+
return 4
|
|
132
|
+
elif self.val_type is val_type.long_t:
|
|
133
|
+
return 4
|
|
134
|
+
elif self.val_type is val_type.ulong_t:
|
|
135
|
+
return 4
|
|
136
|
+
else:
|
|
137
|
+
raise ValueError('Unimplemented SDO type')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: MultiPyVu
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.2
|
|
4
4
|
Summary: Control MultiVu using Python
|
|
5
5
|
Author-email: Damon D Jackson <djackson@qdusa.com>
|
|
6
6
|
Maintainer-email: "Quantum Design, Inc." <apps@qdusa.com>
|
|
@@ -38,7 +38,6 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
38
38
|
Requires-Python: >=3.8
|
|
39
39
|
Description-Content-Type: text/markdown
|
|
40
40
|
License-File: LICENSE
|
|
41
|
-
Requires-Dist: typing
|
|
42
41
|
Requires-Dist: pandas
|
|
43
42
|
Requires-Dist: pywin32>=300; platform_system == "Windows"
|
|
44
43
|
Requires-Dist: pillow
|
|
@@ -436,17 +435,28 @@ client = mpv.Client(port=6000)
|
|
|
436
435
|
- A log file named QdMultiVu.log shows the traffic between the server and client which can also be useful during troubleshooting.
|
|
437
436
|
|
|
438
437
|
## Changelog<a class="anchor" id="changelog"></a>
|
|
438
|
+
**3.1.2**
|
|
439
|
+
- October 2024
|
|
440
|
+
- Fixed a bug which truncated numbers
|
|
441
|
+
|
|
442
|
+
**3.1.1**
|
|
443
|
+
- October 2024
|
|
444
|
+
- Updated the installer to include missing files.
|
|
445
|
+
|
|
439
446
|
**3.1.0**
|
|
440
447
|
- October 2024
|
|
441
448
|
- Log the version number when the Client connects to the Server.
|
|
442
449
|
- Check that the Server and Client are running the same version.
|
|
443
450
|
- Increase the number of backup logs to 5.
|
|
444
451
|
- Bugfix to allow Client to run on Linux or Mac systems.
|
|
445
|
-
- Corrected a bug that prevented the Server from recognizing PPMS and MPMS3 MultiVu flavors
|
|
446
452
|
- Limit server to hosting only one client at a time.
|
|
447
453
|
- Add the ability to call -quit, -is_running, -status, -get_ip from the command line using python -m MultiPyVu
|
|
448
454
|
- Miscellaneous bug fixes and refactoring.
|
|
449
455
|
|
|
456
|
+
**2.2.0**
|
|
457
|
+
- January 2024
|
|
458
|
+
- Corrected a bug that prevented the Server from recognizing PPMS and MPMS3 MultiVu flavors
|
|
459
|
+
|
|
450
460
|
**2.1.4**
|
|
451
461
|
- October 2023
|
|
452
462
|
- Import full module as MultiPyVu. Instead of loading the three sub-modules as:
|
|
@@ -28,6 +28,7 @@ src/MultiPyVu/exceptions.py
|
|
|
28
28
|
src/MultiPyVu/generate_sdo_objects.py
|
|
29
29
|
src/MultiPyVu/instrument.py
|
|
30
30
|
src/MultiPyVu/logging_config.py
|
|
31
|
+
src/MultiPyVu/logging_config.yaml
|
|
31
32
|
src/MultiPyVu/project_vars.py
|
|
32
33
|
src/MultiPyVu/sdo_object.py
|
|
33
34
|
src/MultiPyVu.egg-info/PKG-INFO
|
|
@@ -49,4 +50,5 @@ src/MultiPyVu/gui/ViewTk.py
|
|
|
49
50
|
src/MultiPyVu/gui/__init__.py
|
|
50
51
|
src/MultiPyVu/images/Q.png
|
|
51
52
|
src/MultiPyVu/images/QD_logo.jpg
|
|
53
|
+
src/MultiPyVu/scripts/helper_scripts.py
|
|
52
54
|
src/MultiPyVu/scripts/whats_my_ip_address.cmd
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|