quarchpy 2.1.25__py2.py3-none-any.whl → 2.1.27__py2.py3-none-any.whl

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.
Files changed (29) hide show
  1. quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
  2. quarchpy/_version.py +1 -1
  3. quarchpy/_version.py.bak +1 -0
  4. quarchpy/connection_specific/QPS/qps.jar +0 -0
  5. quarchpy/connection_specific/__pycache__/mDNS.cpython-311.pyc +0 -0
  6. quarchpy/connection_specific/mDNS.py +20 -5
  7. quarchpy/connection_specific/mDNS.py.bak +141 -0
  8. quarchpy/debug/SystemTest.py +2 -6
  9. quarchpy/debug/SystemTest.py.bak +200 -0
  10. quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
  11. quarchpy/docs/CHANGES.rst +9 -0
  12. quarchpy/docs/_build/doctrees/CHANGES.doctree +0 -0
  13. quarchpy/docs/_build/doctrees/environment.pickle +0 -0
  14. quarchpy/docs/_build/doctrees/source/changelog.doctree +0 -0
  15. quarchpy/docs/_build/html/CHANGES.html +136 -123
  16. quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +9 -0
  17. quarchpy/docs/_build/html/index.html +64 -62
  18. quarchpy/docs/_build/html/searchindex.js +1 -1
  19. quarchpy/docs/_build/html/source/changelog.html +200 -185
  20. {quarchpy-2.1.25.dist-info → quarchpy-2.1.27.dist-info}/METADATA +11 -2
  21. {quarchpy-2.1.25.dist-info → quarchpy-2.1.27.dist-info}/RECORD +23 -26
  22. {quarchpy-2.1.25.dist-info → quarchpy-2.1.27.dist-info}/WHEEL +1 -1
  23. quarchpy/__pycache__/run.cpython-311.pyc +0 -0
  24. quarchpy/connection_specific/__pycache__/connection_Telnet.cpython-311.pyc +0 -0
  25. quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
  26. quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
  27. quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
  28. quarchpy/fio/__pycache__/fioDiskFinder.cpython-311.pyc +0 -0
  29. {quarchpy-2.1.25.dist-info → quarchpy-2.1.27.dist-info}/top_level.txt +0 -0
quarchpy/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.1.25"
1
+ __version__ = "2.1.27"
@@ -0,0 +1 @@
1
+ __version__ = "2.1.26"
Binary file
@@ -1,6 +1,6 @@
1
1
  import platform # For getting the operating system name
2
2
  import subprocess # For executing a shell command
3
-
3
+ import logging
4
4
  from zeroconf import Zeroconf
5
5
 
6
6
 
@@ -70,17 +70,27 @@ class MyListener:
70
70
  """
71
71
  Handle service addition event.
72
72
  """
73
+ logging.debug("Adding service: " +name)
73
74
  info = zc.get_service_info(type_, name)
75
+ # Log the service name
74
76
  if "Quarch:" in str(info):
75
77
  # decode the incoming properties from mdns
76
- decoded_properties = {key.decode('utf-8'): value.decode('utf-8') for key, value in info.properties.items()}
78
+ decoded_properties ={}
79
+ for key, value in info.properties.items():
80
+ decoded_properties[ key.decode('utf-8')]=value.decode('utf-8')
81
+ pass
82
+ #decoded_properties = {key.decode('utf-8'): value.decode('utf-8') for key, value in info.properties.items()}
77
83
  decoded_ip = ".".join(str(byte) for byte in info.addresses[0])
78
84
  self.get_instance().add_device(decoded_properties, decoded_ip)
79
85
 
86
+
87
+
88
+
80
89
  def add_device(self, properties_dict, ip_address):
81
90
  """
82
91
  Add a device to the found devices dictionary.
83
92
  """
93
+ logging.debug("Adding device: " +str(ip_address)+"\n"+str(properties_dict))
84
94
  qtl_num = "QTL" + properties_dict['86'] if '86' in properties_dict else None
85
95
  # Check if module contains REST connection
86
96
  if '84' in properties_dict:
@@ -110,11 +120,16 @@ class MyListener:
110
120
  Get the found devices and perform ping check.
111
121
  """
112
122
  temp_dict = self.get_instance().found_devices
123
+ remove_device = False
113
124
  for key, value in list(temp_dict.items()):
114
- result = ping(key[key.index(":") + 1:])
115
- if not result or self.get_instance().target_conn not in key.lower():
125
+ can_ping = ping(key[key.index(":") + 1:])
126
+ if can_ping is False:
127
+ remove_device=True # Remove the device if it can't be pinged
128
+ elif self.get_instance().target_conn not in key.lower() and self.get_instance().target_conn.lower() != "all":
129
+ remove_device = True # or if its of the wrong connection type.
130
+ if remove_device is True:
116
131
  del self.get_instance().found_devices[key]
117
- print(str(self.get_instance().found_devices))
132
+ logging.debug("Returning found devices "+str(self.get_instance().found_devices))
118
133
  return self.get_instance().found_devices
119
134
 
120
135
  def get_zeroconf(self):
@@ -0,0 +1,141 @@
1
+ import platform # For getting the operating system name
2
+ import subprocess # For executing a shell command
3
+ import logging
4
+ from zeroconf import Zeroconf
5
+
6
+
7
+ def ping(host):
8
+ """
9
+ Returns True if host (str) responds to a ping request.
10
+ """
11
+ # Option for the number of packets as a function of
12
+ param = '-n' if platform.system().lower() == 'windows' else '-c'
13
+
14
+ # Building the command. Ex: "ping -c 1 google.com"
15
+ command = ['ping', param, '1', host]
16
+
17
+ # Execute the ping command and capture the output and return code
18
+ result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
19
+
20
+ # Check the return code and output to determine the result
21
+ if result.returncode == 0 and ("destination host unreachable" not in str(result.stdout).lower()):
22
+ return True # Ping successful
23
+ else:
24
+ return False # Ping failed
25
+
26
+
27
+ class MyListener:
28
+ """
29
+ MyListener class to handle service updates, removals, and additions in Zeroconf
30
+ """
31
+
32
+ _instance = None
33
+
34
+ @classmethod
35
+ def get_instance(cls):
36
+ """
37
+ Get an instance of MyListener class. If none exists, create one.
38
+ """
39
+ if cls._instance is None:
40
+ cls._instance = MyListener()
41
+ return cls._instance
42
+
43
+ def __init__(self):
44
+ """
45
+ Initialize MyListener instance.
46
+ """
47
+ self.found_devices = {}
48
+ self.mdns_service_running = False
49
+ self.zeroconf = None
50
+ self.target_conn = None
51
+
52
+ def update_service(self, zc, type_, name):
53
+ """
54
+ Handle service update event.
55
+ """
56
+ info = zc.get_service_info(type_, name)
57
+ if "Quarch:" in str(info):
58
+ # decode the incoming properties from mdns
59
+ decoded_properties = {key.decode('utf-8'): value.decode('utf-8') for key, value in info.properties.items()}
60
+ decoded_ip = ".".join(str(byte) for byte in info.addresses[0])
61
+ self.get_instance().add_device(decoded_properties, decoded_ip)
62
+
63
+ def remove_service(self, zc, type_, name):
64
+ """
65
+ Handle service removal event.
66
+ """
67
+ return None
68
+
69
+ def add_service(self, zc, type_, name):
70
+ """
71
+ Handle service addition event.
72
+ """
73
+ logging.warning("Adding service: " +name)
74
+ info = zc.get_service_info(type_, name)
75
+ # Log the service name
76
+ if "Quarch:" in str(info):
77
+ # decode the incoming properties from mdns
78
+ decoded_properties ={}
79
+ for key, value in info.properties.items():
80
+ decoded_properties[ key.decode('utf-8')]=value.decode('utf-8')
81
+ pass
82
+ #decoded_properties = {key.decode('utf-8'): value.decode('utf-8') for key, value in info.properties.items()}
83
+ decoded_ip = ".".join(str(byte) for byte in info.addresses[0])
84
+ self.get_instance().add_device(decoded_properties, decoded_ip)
85
+
86
+
87
+
88
+
89
+ def add_device(self, properties_dict, ip_address):
90
+ """
91
+ Add a device to the found devices dictionary.
92
+ """
93
+ logging.warning("Adding device: " +str(ip_address)+"\n"+str(properties_dict))
94
+ qtl_num = "QTL" + properties_dict['86'] if '86' in properties_dict else None
95
+ # Check if module contains REST connection
96
+ if '84' in properties_dict:
97
+ # Check the user specified connection type
98
+ if self.get_instance().target_conn == "all" or self.get_instance().target_conn == "rest":
99
+ if properties_dict['84'] == '80':
100
+ # print("Rest connection exists for device: " + qtl_num)
101
+ # Updates the found devices dict
102
+ self.get_instance().update_device_dict(device_dict={"REST:" + ip_address: qtl_num})
103
+ # Check if module contains TCP connection
104
+ if '85' in properties_dict:
105
+ # Check the user specified connection type
106
+ if self.get_instance().target_conn == "all" or self.get_instance().target_conn == "tcp":
107
+ if properties_dict['85'] == "9760":
108
+ # print("TCP connection exists for device: " + qtl_num)
109
+ # Updates the found devices dict
110
+ self.get_instance().update_device_dict(device_dict={"TCP:" + ip_address: qtl_num})
111
+
112
+ def update_device_dict(self, device_dict):
113
+ """
114
+ Update the found devices dictionary.
115
+ """
116
+ self.get_instance().found_devices.update(device_dict)
117
+
118
+ def get_found_devices(self):
119
+ """
120
+ Get the found devices and perform ping check.
121
+ """
122
+ temp_dict = self.get_instance().found_devices
123
+ remove_device = False
124
+ for key, value in list(temp_dict.items()):
125
+ can_ping = ping(key[key.index(":") + 1:])
126
+ if can_ping is False:
127
+ remove_device=True # Remove the device if it can't be pinged
128
+ elif self.get_instance().target_conn not in key.lower() and self.get_instance().target_conn.lower() != "all":
129
+ remove_device = True # or if its of the wrong connection type.
130
+ if remove_device is True:
131
+ del self.get_instance().found_devices[key]
132
+ logging.warning("Returning found devices "+str(self.get_instance().found_devices))
133
+ return self.get_instance().found_devices
134
+
135
+ def get_zeroconf(self):
136
+ """
137
+ Get the Zeroconf instance. If none exists, create one.
138
+ """
139
+ if self.get_instance().zeroconf is None:
140
+ self.get_instance().zeroconf = Zeroconf()
141
+ return self.get_instance().zeroconf
@@ -1,5 +1,5 @@
1
- # from quarchpy import *
2
- # from quarchpy.device import *
1
+ from quarchpy import *
2
+ from quarchpy.device import *
3
3
  try:
4
4
  from importlib.metadata import distribution
5
5
  except:
@@ -7,11 +7,7 @@ except:
7
7
  from importlib_metadata import distribution
8
8
  except Exception as e:
9
9
  print("Failed to import distribution from importlib_metadata")
10
- try:
11
10
 
12
- from importlib_metadata import distribution
13
- except:
14
- print("here")
15
11
  import os
16
12
  import platform
17
13
  import sys
@@ -0,0 +1,200 @@
1
+ from quarchpy import *
2
+ from quarchpy.device import *
3
+ try:
4
+ from importlib.metadata import distribution
5
+ except:
6
+ try:
7
+ from importlib_metadata import distribution
8
+ except Exception as e:
9
+ print("Failed to import distribution from importlib_metadata")
10
+
11
+ import os
12
+ import platform
13
+ import sys
14
+ import subprocess
15
+ from quarchpy._version import __version__
16
+
17
+ def test_communication():
18
+ print("")
19
+ print("DEVICE COMMUNICATION TEST")
20
+ print("-------------------------")
21
+ print("")
22
+ deviceList = scanDevices('all', favouriteOnly=False)
23
+ print("Devices visible:\r\n" + str(deviceList))
24
+ print("")
25
+ moduleStr = userSelectDevice(deviceList, nice=True, additionalOptions=["Rescan", "Quit", "All Conn Types"])
26
+ if moduleStr == "quit":
27
+ print("User selected quit")
28
+ return 0
29
+ print("Selected module is: " + moduleStr)
30
+ # Create a device using the module connection string
31
+ myDevice = getQuarchDevice(moduleStr)
32
+ QuarchSimpleIdentify(myDevice)
33
+ # Close the module before exiting the script
34
+ myDevice.closeConnection()
35
+
36
+ def test_system_info():
37
+ print("")
38
+ print("SYSTEM INFORMATION")
39
+ print("------------------")
40
+ print("OS Name: " + os.name)
41
+ print("Platform System: " + platform.system())
42
+ print("Platform: " + platform.platform())
43
+
44
+ if "nt" in os.name:
45
+ print("Platform Architecture: " + platform.architecture()[0])
46
+ else:
47
+ print(str(bytes(subprocess.check_output(['cat', '/etc/os-release'], stderr=subprocess.STDOUT)).decode()))
48
+ print("Platform Release: " + platform.release())
49
+
50
+ try:
51
+ print("Quarchpy Version: " + get_quarchpy_version())
52
+ except:
53
+ print("Unable to detect Quarchpy version")
54
+ try:
55
+ print("Quarchpy info Location: " + str(distribution("quarchpy")._path))
56
+ except Exception as e:
57
+ print(e)
58
+ print("Unable to detect Quarchpy location")
59
+ try:
60
+ print("Python Version: " + sys.version)
61
+ except:
62
+ print("Unable to detect Python version")
63
+ try:
64
+ print("QIS version number: " + get_QIS_version())
65
+ except:
66
+ print("Unable to detect QIS version")
67
+ try:
68
+ javaVersion = bytes(subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)).decode()
69
+ print("Java Version: " + str(javaVersion))
70
+ except:
71
+ print("Unable to detect java version"
72
+ "If Java is not installed then QIS and QPS will NOT run")
73
+ try:
74
+ javaLocation = get_java_location()
75
+ print("Java Location: " + str(javaLocation))
76
+ except:
77
+ print("Unable to detect java location"
78
+ "If Java is not installed then QIS and QPS will NOT run")
79
+
80
+ # Scan for all quarch devices on the system
81
+
82
+ def QuarchSimpleIdentify(device1):
83
+ """
84
+ Prints basic identification test data on the specified module, compatible with all Quarch devices
85
+
86
+ Parameters
87
+ ----------
88
+ device1: quarchDevice
89
+ Open connection to a quarch device
90
+
91
+ """
92
+ # Print the module name
93
+ print("MODULE IDENTIFY TEST")
94
+ print("--------------------")
95
+ print("")
96
+ print("Module Name: "),
97
+ print(device1.sendCommand("hello?"))
98
+ print("")
99
+ # Print the module identify and version information
100
+ print("Module Identity Information: ")
101
+ print(device1.sendCommand("*idn?"))
102
+
103
+ def get_QIS_version():
104
+ """
105
+ Returns the version of QIS. This is the version of QIS currenty running on the local system if one exists.
106
+ Otherwise the local version within quarchpy will be exectued and its version returned.
107
+
108
+ Returns
109
+ -------
110
+ version: str
111
+ String representation of the QIS version number
112
+
113
+ """
114
+
115
+ qis_version = ""
116
+ my_close_qis = False
117
+ if isQisRunning() == False:
118
+ my_close_qis = True
119
+ startLocalQis(headless=True)
120
+
121
+ myQis = qisInterface()
122
+ qis_version = myQis.sendAndReceiveCmd(cmd="$version")
123
+ if "No Target Device Specified" in qis_version:
124
+ qis_version = myQis.sendAndReceiveCmd(cmd="$help").split("\r\n")[0]
125
+ if my_close_qis:
126
+ myQis.sendAndReceiveCmd(cmd = "$shutdown")
127
+ return qis_version
128
+
129
+ def get_java_location():
130
+ """
131
+ Returns the location of java.
132
+
133
+ Returns
134
+ -------
135
+ location: str
136
+ String representation of the java location.
137
+ """
138
+ if "windows" in platform.platform().lower():
139
+ location = bytes(subprocess.check_output(['where', 'java'], stderr=subprocess.STDOUT)).decode()
140
+ elif "linux" in platform.platform().lower():
141
+ location = bytes(subprocess.check_output(['whereis', 'java'], stderr=subprocess.STDOUT)).decode()
142
+ else:
143
+ location = "Unable to detect OS to check java version."
144
+ return location
145
+
146
+ def get_quarchpy_version():
147
+ try:
148
+ return __version__
149
+ except:
150
+ return "Unknown"
151
+
152
+ def fix_usb():
153
+ content_to_write = "SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"16d0\", MODE=\"0666\"" \
154
+ "SUBSYSTEM==\"usb_device\", ATTRS{idVendor}==\"16d0\", MODE=\"0666\""
155
+
156
+ if "centos" in str(platform.platform()).lower():
157
+ content_to_write = "SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"16d0\", MODE=\"0666\", GROUP=*\n " \
158
+ "SUBSYSTEM==\"usb_device\", ATTRS{idVendor}==\"16d0\", MODE=\"0666\", GROUP=*"
159
+
160
+ destination = "/etc/udev/rules.d/20-quarchmodules.rules"
161
+
162
+ f = open("/etc/udev/rules.d/20-quarchmodules.rules", "w")
163
+ f.write(content_to_write)
164
+ f.close()
165
+
166
+ os.system("udevadm control --reload")
167
+ os.system("udevadm trigger")
168
+
169
+ print("USB rule added to file : /etc/udev/rules.d/20-quarchmodules.rules")
170
+
171
+
172
+ def main (args=None):
173
+ """
174
+ Main function to allow the system test to be called direct from the command line
175
+ """
176
+ bool_test_system_info = True
177
+ bool_test_communication = True
178
+ bool_fixusb=False
179
+ if args is not None and len(args)>0:
180
+ for arg in args:
181
+ if "--fixusb" in str(arg).lower():
182
+ bool_fixusb=True
183
+ # todo: Should we still be running the debug info stuff after this?
184
+ if "--skipsysteminfo" in str(arg).lower():
185
+ bool_test_system_info=False
186
+ if "--skipcommstest" in str(arg).lower():
187
+ bool_test_communication=False
188
+
189
+ if bool_fixusb:
190
+ fix_usb()
191
+ if bool_test_system_info:
192
+ test_system_info()
193
+ if bool_test_communication:
194
+ test_communication()
195
+
196
+
197
+ if __name__ == "__main__":
198
+ main([])
199
+ #main(["--skipSystemInfo","--skipCommsTest"])
200
+ #main(["--fixusb"])
quarchpy/docs/CHANGES.rst CHANGED
@@ -13,6 +13,15 @@ Quarchpy
13
13
  Change Log
14
14
  ----------
15
15
 
16
+ 2.1.27
17
+ ------
18
+ - new QPS 1.41 same QIS 1.43
19
+ - mDNS scanning improvelemts
20
+
21
+ 2.1.26
22
+ ------
23
+ - minor bugfix
24
+
16
25
  2.1.25
17
26
  ------
18
27
  - New QPS 1.40 and Qis 1.43