quarchpy 2.2.9.dev3__py2.py3-none-any.whl → 2.2.9.dev5__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.
- quarchpy/__init__.py +1 -1
- quarchpy/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-310.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-310.pyc +0 -0
- quarchpy/_version.py +1 -1
- quarchpy/config_files/Cable_Modules/QTL1253-01 - Mini SAS Module Config v3.5 c1.3.qfg +196 -196
- quarchpy/config_files/Cable_Modules/QTL1253-01 - Mini SAS Module Config v4.000 c1.3.qfg +198 -198
- quarchpy/config_files/Cable_Modules/QTL1253-02 - Mini SAS Module Config v3.5 c1.3.qfg +196 -196
- quarchpy/config_files/Cable_Modules/QTL1253-02 - Mini SAS Module Config v4.000 c1.3.qfg +198 -198
- quarchpy/config_files/Cable_Modules/QTL1253-xx - Mini SAS Module Config v4.003 c1.6.qfg +197 -197
- quarchpy/config_files/Cable_Modules/QTL1271-xx - Ethernet Module Config v3.5 c1.2.qfg +188 -188
- quarchpy/config_files/Cable_Modules/QTL1271-xx - Ethernet Module Config v4.000 c1.2.qfg +190 -190
- quarchpy/config_files/Cable_Modules/QTL1271-xx - Ethernet Module Config v4.100 c1.3.qfg +189 -189
- quarchpy/config_files/Cable_Modules/QTL1292-xx - SFP+ Cable Pull Module Config v4.000 c1.1.qfg +154 -154
- quarchpy/config_files/Cable_Modules/QTL1309-04 - USB 3.0 Module Config v4.003 c1.2.qfg +187 -187
- quarchpy/config_files/Cable_Modules/QTL1309-xx - USB 3.0 Module Config v3.5 c1.1.qfg +187 -187
- quarchpy/config_files/Cable_Modules/QTL1309-xx - USB 3.0 Module Config v4.000 c1.1.qfg +188 -188
- quarchpy/config_files/Cable_Modules/QTL1366-xx - QSFP Cable Pull Module Config v4.000 c1.1.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL1383-xx - eSATAp Module Config v4.000 c1.3.qfg +190 -190
- quarchpy/config_files/Cable_Modules/QTL1521-02 - Mini SAS HD Module Config v4.000 c1.1.qfg +210 -210
- quarchpy/config_files/Cable_Modules/QTL1521-03 - Mini SAS HD Module Config v4.000 c1.1.qfg +210 -210
- quarchpy/config_files/Cable_Modules/QTL1521-05 - Mini SAS HD Module Config v4.005 c1.1.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL1521-05 - Mini SAS HD Module Config v4.007 c1.2.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL1521-xx - Mini SAS HD Module Config v4.003 c1.5.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL1663-xx - Quad QSFP Cable Pull Module Config v4.000 c1.1.qfg +308 -308
- quarchpy/config_files/Cable_Modules/QTL1675-05 - Mini SAS HD Module w Triggering Config v4.007 c1.3.qfg +211 -211
- quarchpy/config_files/Cable_Modules/QTL1675-xx - Mini SAS HD Module w Triggering Config v4.000 c1.1.qfg +210 -210
- quarchpy/config_files/Cable_Modules/QTL1917-xx - Dual SFP+ Cable Pull Module Config v4.000 c1.1.qfg +174 -174
- quarchpy/config_files/Cable_Modules/QTL1971-01 - USB TypeC Module Config v4.000 c1.1.qfg +203 -203
- quarchpy/config_files/Cable_Modules/QTL1971-02 - USB TypeC Module Config v4.000 c1.1.qfg +203 -203
- quarchpy/config_files/Cable_Modules/QTL2022-xx - RJ-45 Cable Module Config v4.104 c1.3.QFG +189 -189
- quarchpy/config_files/Cable_Modules/QTL2058-xx - External PCIe Module Config v4.001 c1.1.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL2138-01 - SFP28 Cable Pull Module Config v4.000 c1.1.qfg +154 -154
- quarchpy/config_files/Cable_Modules/QTL2146-01 - Gen4 OCuLink Cable Module Config v4.001 c1.1.qfg +212 -212
- quarchpy/config_files/Cable_Modules/QTL2162-01 - 24G mini SAS HD Cable Break Module Config v4.000 c1.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL2171-01 - QSFP28 Cable Module Config v4.000 c1.qfg +198 -198
- quarchpy/config_files/Cable_Modules/QTL2171-02 - QSFP28 Cable Module Config v4.000 c1.qfg +198 -198
- quarchpy/config_files/Cable_Modules/QTL2341-01 - Gen4 External PCIe Cable Module v4.000.qfg +209 -209
- quarchpy/config_files/Cable_Modules/QTL2602-xx - Multiprotocol Link Breaker.qfg +178 -178
- quarchpy/config_files/Cable_Modules/QTL2834-xx - -48V DC Breaker Module v5.000 c1.0.qfg +177 -177
- quarchpy/config_files/Card_Modules/QTL1069-xx - SBB 2.0 Module Config v3.5 c1.1.qfg +366 -366
- quarchpy/config_files/Card_Modules/QTL1630-01 - PCIe Card Module v4.000 c1.0.qfg +280 -280
- quarchpy/config_files/Card_Modules/QTL1630-02 - PCIe Card Module Config v4.004 c1.2.qfg +283 -283
- quarchpy/config_files/Card_Modules/QTL1630-02 - PCIe Card Module Config v4.005 c1.2.qfg +283 -283
- quarchpy/config_files/Card_Modules/QTL1630-02 - PCIe Card Module Config v4.100 c1.4.qfg +284 -284
- quarchpy/config_files/Card_Modules/QTL1630-04 - PCIe Card Module Config v4.001 c1.1.qfg +287 -287
- quarchpy/config_files/Card_Modules/QTL1630-04 - PCIe Card Module Config v4.004 c1.2.qfg +287 -287
- quarchpy/config_files/Card_Modules/QTL1688-01 - PCIe Card Module w Triggering Config v4.004 c1.2.qfg +284 -284
- quarchpy/config_files/Card_Modules/QTL1688-01 - PCIe Card Module w Triggering Config v4.006 c1.3.qfg +285 -285
- quarchpy/config_files/Card_Modules/QTL1688-03 - PCIe Card Module w Triggering Config v4.001 c1.1.qfg +286 -286
- quarchpy/config_files/Card_Modules/QTL1688-03 - PCIe Card Module w Triggering Config v4.004 c1.2.qfg +288 -288
- quarchpy/config_files/Card_Modules/QTL1688-04 - PCIe Card Module w Triggering Config v4.005 c1.5.qfg +288 -288
- quarchpy/config_files/Card_Modules/QTL1688-05 - PCIe Card Module w Triggering Config v4.005 c1.qfg +288 -288
- quarchpy/config_files/Card_Modules/QTL1848-01 - PCIe Lite Card Module Config v4.000.qfg +122 -122
- quarchpy/config_files/Card_Modules/QTL1848-02 - PCIe Lite Card Module Config v4.000.qfg +134 -134
- quarchpy/config_files/Card_Modules/QTL1919-01 - PCIe x8 Card Module Config v4.001 c1.4.qfg +247 -247
- quarchpy/config_files/Card_Modules/QTL1920-01 - PCIe x8 Card Module w Triggering Config v4.000 c1.3.qfg +247 -247
- quarchpy/config_files/Card_Modules/QTL2019-xx - M.2 Horizontal Card Module Config v4.002 c1.1.qfg +219 -219
- quarchpy/config_files/Card_Modules/QTL2034-xx - M.2 M-Key Vertical Module Config v4.001 c1.1.qfg +221 -221
- quarchpy/config_files/Card_Modules/QTL2067-xx - PCIe SFF Module Config v4.000 c1.1.qfg +248 -248
- quarchpy/config_files/Card_Modules/QTL2067-xx - Sanblaze 2 Drive Riser Card Config v4.006 c1.4.qfg +256 -256
- quarchpy/config_files/Card_Modules/QTL2067-xx - Sanblaze 2 Drive Riser Card Config v4.007 c1.4.qfg +256 -256
- quarchpy/config_files/Card_Modules/QTL2073-01 - GEN3 PCIe Lite Card Module Config v4.001.qfg +134 -134
- quarchpy/config_files/Card_Modules/QTL2073-01 - PCIe Lite Card Module Config v4.000.qfg +134 -134
- quarchpy/config_files/Card_Modules/QTL2074-01 - GEN3 PCIe HS Card Module v4.005 c1.4.qfg +287 -287
- quarchpy/config_files/Card_Modules/QTL2074-01 - PCIe Card Module Config CurrentLimit v4.004 c1.2.qfg +287 -287
- quarchpy/config_files/Card_Modules/QTL2087-xx - PCIe GEN4 Card Module w Triggering Config v4.001 c1.1.qfg +287 -287
- quarchpy/config_files/Card_Modules/QTL2087-xx - PCIe GEN4 Card Module w Triggering Config v4.001 c1.3.qfg +277 -277
- quarchpy/config_files/Card_Modules/QTL2087-xx - PCIe GEN4 Card Module w Triggering Config v5.000 c1.4.qfg +277 -277
- quarchpy/config_files/Card_Modules/QTL2094-01 - Sanblaze Dualport Riser Card Config v4.001 c1.1.qfg +223 -223
- quarchpy/config_files/Card_Modules/QTL2128-xx - PCIe GEN4 Card Module w Triggering Config v4.000 c1.1.qfg +287 -287
- quarchpy/config_files/Card_Modules/QTL2128-xx - PCIe GEN4 Card Module w Triggering Config v4.001 c1.4.qfg +277 -277
- quarchpy/config_files/Card_Modules/QTL2135-xx - PCIe GEN4 Card Module w Triggering Config - Inrush Limit v4.001 c1.4.qfg +277 -277
- quarchpy/config_files/Card_Modules/QTL2161-01 - EDSFF x8 Module Config v4.000 c1.1.qfg +210 -210
- quarchpy/config_files/Card_Modules/QTL2171-xx - EDSFF x8 Module w Triggering Config 4.001 c1.1.qfg +213 -213
- quarchpy/config_files/Card_Modules/QTL2203-01 - Sanblaze Dualport Rack Riser Card Config v4.000 c1.1.qfg +218 -218
- quarchpy/config_files/Card_Modules/QTL2203-01 - Sanblaze Dualport Rack Riser Card Config v4.005 c1.5.qfg +218 -218
- quarchpy/config_files/Card_Modules/QTL2272-01 - GEN4 EDSFF x8 Module Config v4.000 c1.1.qfg +211 -211
- quarchpy/config_files/Card_Modules/QTL2282-01 - Sanblaze Singleport Rack Riser Card Config v4.000 c1.1.qfg +212 -212
- quarchpy/config_files/Card_Modules/QTL2282-01 - Sanblaze Singleport Rack Riser Card Config v4.002 c1.2.qfg +212 -212
- quarchpy/config_files/Card_Modules/QTL2318-01 - SANBlaze U.2 Rack Riser Card Config v4.000 c1.1.qfg +218 -218
- quarchpy/config_files/Card_Modules/QTL2322-03 - GEN4 M.2 M-Key Vertical Breaker Module Config v5.001 c1.3.qfg +220 -220
- quarchpy/config_files/Card_Modules/QTL2322-xx - GEN4 M.2 M-Key Vertical Breaker Module Config v5.000 c1.1.qfg +208 -208
- quarchpy/config_files/Card_Modules/QTL2334-xx - Gen4 EDSFF x4 Card Module Config v4.000 c1.1.qfg +187 -187
- quarchpy/config_files/Card_Modules/QTL2351-xx - GEN4 EDSFF x4 Card Module +Triggering Config v4.000 c1.1.qfg +189 -189
- quarchpy/config_files/Card_Modules/QTL2351-xx - GEN4 EDSFF x4 Card Module +Triggering Config v4.001 c1.2.qfg +190 -190
- quarchpy/config_files/Card_Modules/QTL2357-xx - PCIe GEN5 Card Module Config v5.000 c1.1.qfg +282 -282
- quarchpy/config_files/Card_Modules/QTL2358-xx - PCIe GEN5 Card Module w Triggering Config v5.000 c1.1.qfg +283 -283
- quarchpy/config_files/Card_Modules/QTL2378-xx - SANBlaze U.3 Rack Riser Card Config v4.000 c1.1.qfg +215 -215
- quarchpy/config_files/Card_Modules/QTL2378-xx - SANBlaze U.3 Rack Riser Card Config v4.001 c1.2.qfg +217 -217
- quarchpy/config_files/Card_Modules/QTL2395-01 - GEN4 M.2 M-Key Vertical Breaker Module w Triggering Config v5.000 c1.1.qfg +208 -208
- quarchpy/config_files/Card_Modules/QTL2395-02 - GEN4 M.2 M-Key Vertical Breaker Module w Triggering Config v5.001 c1.3.qfg +220 -220
- quarchpy/config_files/Card_Modules/QTL2395-03 - GEN4 M.2 M-Key Vertical Breaker Module w Triggering Config v5.001 c1.3.qfg +220 -220
- quarchpy/config_files/Card_Modules/QTL2396-xx - PCIe GEN5 Card Module w inrush Config v5.000 c1.1.qfg +282 -282
- quarchpy/config_files/Card_Modules/QTL2403-xx - Gen4 PCIe Lite Module Config v4.000.qfg +135 -135
- quarchpy/config_files/Card_Modules/QTL2515-xx - PCIe GEN4 Card Module w Triggering - Inrush Limit Config v4.001 c1.3.qfg +277 -277
- quarchpy/config_files/Card_Modules/QTL2652-xx - Gen5 PCIe Lite Module Config v4.000.qfg +130 -130
- quarchpy/config_files/Card_Modules/QTL2652-xx - Gen5 PCIe Lite Module Config v4.003.qfg +137 -137
- quarchpy/config_files/Card_Modules/QTL2658-xx - Gen5 PCIe Lite Module w Inrush Config v4.000.qfg +130 -130
- quarchpy/config_files/Card_Modules/QTL2661-xx - GEN5 PCIe U.3 Breaker Config w Triggering v5.000 c1.1.qfg +229 -229
- quarchpy/config_files/Card_Modules/QTL2662-xx - GEN5 PCIe U.3 Breaker Config v5.000 c1.1.qfg +228 -228
- quarchpy/config_files/Card_Modules/QTL2686-xx - Gen5 EDSFF E3 x4 Breaker Config v5.000.qfg +230 -230
- quarchpy/config_files/Card_Modules/QTL2686-xx - Gen5 EDSFF E3 x4 Breaker Config v5.001 c1.2.qfg +233 -233
- quarchpy/config_files/Card_Modules/QTL2686-xx - Gen5 EDSFF E3 x4 Breaker v5.000 c1.1.qfg +230 -230
- quarchpy/config_files/Card_Modules/QTL2692-xx - Gen5 EDSFF E3 x4 Breaker +Triggering Config v5.000.qfg +230 -230
- quarchpy/config_files/Card_Modules/QTL2692-xx - Gen5 EDSFF E3 x4 Breaker w Triggering Config v5.001 c1.2.qfg +233 -233
- quarchpy/config_files/Card_Modules/QTL2692-xx - Gen5 EDSFF E3 x4 Breaker w Triggering v5.000 c1.1.qfg +230 -230
- quarchpy/config_files/Card_Modules/QTL2766-xx - GEN4 EDSFF E1 x8 Breaker Config v5.000.qfg +253 -253
- quarchpy/config_files/Card_Modules/QTL2767-xx - GEN4 EDSFF E3 x8 Breaker Config v5.000.qfg +253 -253
- quarchpy/config_files/Card_Modules/QTL2768-xx - GEN4 EDSFF E3 2T x8 Breaker Config v5.000.qfg +253 -253
- quarchpy/config_files/Card_Modules/QTL2776-xx - GEN4 EDSFF E1 x8 Breaker +Triggering Config v5.000.qfg +253 -253
- quarchpy/config_files/Card_Modules/QTL2777-xx - GEN4 EDSFF E3 x8 Breaker +Triggering Config v5.000.qfg +253 -253
- quarchpy/config_files/Card_Modules/QTL2778-xx - GEN4 EDSFF E3 2T x8 Breaker +Triggering Config v5.000.qfg +253 -253
- quarchpy/config_files/Card_Modules/QTL2798-xx - PCIe GEN5 Card Module w Triggering w Inrush Limit Config v5.000 c1.1.qfg +283 -283
- quarchpy/config_files/Card_Modules/QTL2804-xx - GEN5 MCIO x4 to U.2 Breaker Config v5.000 c1.1.qfg +234 -234
- quarchpy/config_files/Card_Modules/QTL2805-xx - GEN5 MCIO x4 to U.2 Breaker + Triggering Config v5.000 c1.1.qfg +234 -234
- quarchpy/config_files/Card_Modules/QTL2814-xx - GEN5 AIC to U.2 Breaker + Triggering Config v5.000 c1.1 .qfg +233 -233
- quarchpy/config_files/Card_Modules/QTL2892-xx - GEN5 EDSFF E1 x4 Breaker.qfg +233 -233
- quarchpy/config_files/Card_Modules/QTL2925-xx - GEN5 EDSFF E1 x4 Breaker +Triggering.qfg +233 -233
- quarchpy/config_files/Drive_Modules/QTL1177-xx - HS Module Config v3.5 c1.5.qfg +198 -198
- quarchpy/config_files/Drive_Modules/QTL1177-xx - HS Module Config v4.000 c1.5.qfg +200 -200
- quarchpy/config_files/Drive_Modules/QTL1177-xx - HS Module Config v4.006 c1.8.qfg +199 -199
- quarchpy/config_files/Drive_Modules/QTL1215-xx - Lite Module Config v3.50.qfg +118 -118
- quarchpy/config_files/Drive_Modules/QTL1215-xx - Lite Module Config v4.000.qfg +118 -118
- quarchpy/config_files/Drive_Modules/QTL1301-xx - HS Lite Module Config v3.50.qfg +129 -129
- quarchpy/config_files/Drive_Modules/QTL1301-xx - HS Lite Module Config v4.000.qfg +129 -129
- quarchpy/config_files/Drive_Modules/QTL1429-01 - EMC HS Lite Module Config v4.000.qfg +129 -129
- quarchpy/config_files/Drive_Modules/QTL1429-02 - EMC HS Lite Module Config v4.002.qfg +120 -120
- quarchpy/config_files/Drive_Modules/QTL1623-03 - 12G HS Lite Module Config v4.001.qfg +128 -128
- quarchpy/config_files/Drive_Modules/QTL1623-04 - 12G HS Lite Module Config v4.001.qfg +128 -128
- quarchpy/config_files/Drive_Modules/QTL1680-xx - SCA2 Lite Module Config v4.001.qfg +135 -135
- quarchpy/config_files/Drive_Modules/QTL1689-01 - 12G HS Module Config v4.001 c1.1.qfg +199 -199
- quarchpy/config_files/Drive_Modules/QTL1689-04 - 12G HS Module Config v4.002 c1.1.qfg +196 -196
- quarchpy/config_files/Drive_Modules/QTL1689-05 - 12G HS Module Config v4.002 c1.1.qfg +196 -196
- quarchpy/config_files/Drive_Modules/QTL1743-02 - PCIe SFF Module Config v4.003 c1.3.qfg +222 -222
- quarchpy/config_files/Drive_Modules/QTL1743-02 - PCIe SFF Module Config v4.006 c1.4.qfg +213 -213
- quarchpy/config_files/Drive_Modules/QTL1743-xx - PCIe SFF Module Config v4.000 c1.1.qfg +221 -221
- quarchpy/config_files/Drive_Modules/QTL1753-xx - 12G Lite Module Config v4.000.qfg +116 -116
- quarchpy/config_files/Drive_Modules/QTL1921-01 - EMC 12G HS Lite Module Config v4.000.qfg +120 -120
- quarchpy/config_files/Drive_Modules/QTL2207-01 - GEN 4 PCIe U.2 Drive Module.qfg +217 -217
- quarchpy/config_files/Drive_Modules/QTL2207-02 - GEN 4 PCIe U.2 Drive Module v5.000.qfg +220 -220
- quarchpy/config_files/Drive_Modules/QTL2207-03 - GEN 4 PCIe SFF HS Drive Module Triggering v5.001.qfg +221 -221
- quarchpy/config_files/Drive_Modules/QTL2207-xx - GEN 4 PCIe U.2 Drive Module v4.001.qfg +219 -219
- quarchpy/config_files/Drive_Modules/QTL2207-xx - GEN 4 PCIe U.2 Drive Module.qfg +219 -219
- quarchpy/config_files/Drive_Modules/QTL2245-01 - GEN 4 PCIe U.3 HS Drive Module v4.000.qfg +223 -223
- quarchpy/config_files/Drive_Modules/QTL2245-xx - GEN 4 PCIe U.3 HS Drive Module.qfg +229 -229
- quarchpy/config_files/Drive_Modules/QTL2266-01 - GEN 4 PCIe SFF HS Drive Module Triggering.qfg +219 -219
- quarchpy/config_files/Drive_Modules/QTL2266-02 - GEN 4 PCIe SFF HS Drive Module Triggering v4.002.qfg +220 -220
- quarchpy/config_files/Drive_Modules/QTL2266-03 - GEN 4 PCIe SFF HS Drive Module Triggering v5.001.qfg +221 -221
- quarchpy/config_files/Drive_Modules/QTL2266-XX - GEN 4 PCIe SFF HS Drive Module Triggering.qfg +219 -219
- quarchpy/config_files/Drive_Modules/QTL2270-01 - GEN 4 PCIe U.3 HS Drive Module Triggering v4.000.qfg +225 -225
- quarchpy/config_files/Drive_Modules/QTL2270-xx - GEN 4 PCIe U.3 HS Drive Module Triggering.qfg +230 -230
- quarchpy/config_files/Drive_Modules/QTL2542-02 - 24G SAS Drive Breaker Module v5.001.qfg +194 -194
- quarchpy/config_files/Drive_Modules/QTL2542-xx - 24G SAS Drive Breaker v5.000 c1.1.qfg +194 -194
- quarchpy/config_files/Drive_Modules/QTL2543-xx - 24G SAS Drive Breaker +Triggering v5.000 c1.1.qfg +195 -195
- quarchpy/config_files/Drive_Modules/QTL2602-xx - Multiprotocol Link Breaker.qfg +178 -178
- quarchpy/config_files/Drive_Modules/QTL2645-xx - Gen5 PCIe U.2 Drive Module v5.000.qfg +227 -227
- quarchpy/config_files/Drive_Modules/QTL2645-xx - Gen5 PCIe U.2 Drive Module v5.001.qfg +227 -227
- quarchpy/config_files/Drive_Modules/QTL2645-xx - Gen5 PCIe U.2 Drive Module v5.003.qfg +227 -227
- quarchpy/config_files/Drive_Modules/QTL2645-xx - Gen5 PCIe U.2 Drive Module v5.007.qfg +229 -229
- quarchpy/config_files/Drive_Modules/QTL2651-xx - Gen5 PCIe U.2 Drive Module + Triggering v5.000.qfg +228 -228
- quarchpy/config_files/Drive_Modules/QTL2651-xx - Gen5 PCIe U.2 Drive Module + Triggering v5.001.qfg +228 -228
- quarchpy/config_files/Drive_Modules/QTL2651-xx - Gen5 PCIe U.2 Drive Module + Triggering v5.003.qfg +228 -228
- quarchpy/config_files/Drive_Modules/QTL2651-xx - Gen5 PCIe U.2 Drive Module v5.007.qfg +230 -230
- quarchpy/config_files/Drive_Modules/QTL2661-xx - Gen5 U.3 Drive Module + Triggering v5.000.qfg +229 -229
- quarchpy/config_files/Drive_Modules/QTL2662-xx - Gen5 PCIe U.3 Drive Module v5.000.qfg +228 -228
- quarchpy/config_files/Drive_Modules/QTL2757-xx - Gen5 SFF Lite Breaker Module Config v4.000.qfg +140 -140
- quarchpy/config_files/Drive_Modules/QTL2804-xx - Gen5 MCIO to U.2 Breaker +Triggering v5.003.qfg +253 -253
- quarchpy/config_files/Drive_Modules/QTL2804-xx - Gen5 MCIO to U.2 Breaker v5.001.qfg +234 -234
- quarchpy/config_files/Drive_Modules/QTL2805-xx - Gen5 MCIO to U.2 Breaker +Triggering v5.001.qfg +234 -234
- quarchpy/config_files/Drive_Modules/QTL2805-xx - Gen5 MCIO to U.2 Breaker +Triggering v5.002.qfg +253 -253
- quarchpy/config_files/Drive_Modules/QTL2805-xx - Gen5 MCIO to U.2 Breaker +Triggering v5.003.qfg +253 -253
- quarchpy/config_files/Drive_Modules/QTL2813-xx - Gen5 AIC to U.2 Breaker v5.001 c1.2.qfg +230 -230
- quarchpy/config_files/Drive_Modules/QTL2813-xx - Gen5 AIC to U.2 Breaker with Triggering v5.002 c1.3.qfg +253 -253
- quarchpy/config_files/Drive_Modules/QTL2814-xx - Gen5 AIC to U.2 Breaker with Triggering v5.001 c1.2.qfg +230 -230
- quarchpy/config_files/Drive_Modules/QTL2814-xx - Gen5 AIC to U.2 Breaker with Triggering v5.002 c1.3.qfg +253 -253
- quarchpy/config_files/Drive_Modules/QTL2892-xx - Gen5 EDSFF E1 x4 Breaker v5.001.qfg +233 -233
- quarchpy/config_files/Drive_Modules/Standard Drive Module Config v3.5 c1.1.qfg +171 -171
- quarchpy/config_files/Power_Margining/HD/QTL1944-xx - HD Power Module v5.000.qfg +123 -123
- quarchpy/config_files/Power_Margining/HD/QTL1944-xx - HD Power Module v5.003.qfg +124 -124
- quarchpy/config_files/Power_Margining/HD/QTL1995-xx - x6 HD Power Module v5.002.qfg +122 -122
- quarchpy/config_files/Power_Margining/HD/QTL1995-xx - x6 HD Power Module v5.003.qfg +123 -123
- quarchpy/config_files/Power_Margining/HD/QTL1999-xx - Single HD Power Module v5.002.qfg +122 -122
- quarchpy/config_files/Power_Margining/HD/QTL1999-xx - Single HD Power Module v5.003.qfg +123 -123
- quarchpy/config_files/Power_Margining/HD/QTL1999-xx - Single HD Power Module v6.000.qfg +124 -124
- quarchpy/config_files/Power_Margining/PPM/QTL1455-02 - Power Margining Module v4.101.qfg +78 -78
- quarchpy/config_files/Power_Margining/PPM/QTL1455-02 - Power Margining Module v4.200.qfg +80 -80
- quarchpy/config_files/Power_Margining/PPM/QTL1455-02 - Power Margining Module v4.201.qfg +82 -82
- quarchpy/config_files/Power_Margining/PPM/QTL1455-02 - Test Power Margining Module v4.004.qfg +73 -73
- quarchpy/config_files/Power_Margining/PPM/QTL1658-01 - Power Margining Module w. Triggering v4.101.qfg +78 -78
- quarchpy/config_files/Power_Margining/PPM/QTL1658-01 - Power Margining Module w. Triggering v4.200.qfg +80 -80
- quarchpy/config_files/Power_Margining/PPM/QTL1658-01 - Power Margining Module w. Triggering v4.201.qfg +82 -82
- quarchpy/config_files/Power_Margining/PPM/QTL1727-01 - 3v3 Power Margining Module w. Triggering v4.105.qfg +78 -78
- quarchpy/config_files/Power_Margining/PPM/QTL1727-01 - 3v3 Power Margining Module w. Triggering v4.200.qfg +80 -80
- quarchpy/config_files/Power_Margining/PPM/QTL1727-01 - 3v3 Power Margining Module w. Triggering v4.201.qfg +82 -82
- quarchpy/config_files/Power_Margining/PPM/QTL1730-01 - 3v3 Power Margining Module v4.105.qfg +78 -78
- quarchpy/config_files/Power_Margining/PPM/QTL1730-01 - 3v3 Power Margining Module v4.200.qfg +80 -80
- quarchpy/config_files/Power_Margining/PPM/QTL1730-01 - 3v3 Power Margining Module v4.201.qfg +82 -82
- quarchpy/config_files/Power_Margining/XLC/QTL1824-01 - Power Margining Module V2 - Triggering v4.000.qfg +80 -80
- quarchpy/config_files/Power_Margining/XLC/QTL1824-01 - Power Margining Module V2 - Triggering v4.200.qfg +81 -81
- quarchpy/config_files/Power_Margining/XLC/QTL1824-01 - Power Margining Module V2 - Triggering v4.202.qfg +87 -87
- quarchpy/config_files/Power_Margining/XLC/QTL1824-01 - Power Margining Module V2 - Triggering v4.210.qfg +88 -88
- quarchpy/config_files/Power_Margining/XLC/QTL1824-01 - Power Margining Module V2 - Triggering v4.211.qfg +121 -121
- quarchpy/config_files/Power_Margining/XLC/QTL1824-03 - Power Margining Module V2 - Triggering v4.213.qfg +121 -121
- quarchpy/config_files/Power_Margining/XLC/QTL1847-01 - Power Margining Module V2 v4.213.qfg +121 -121
- quarchpy/config_files/Switch_Modules/QTL1390-xx - 4-8 SATA MUX Module Config v4.002.qfg +186 -186
- quarchpy/config_files/Switch_Modules/QTL1443-xx - 1-8 USB3 MUX Module Config v4.002.qfg +147 -147
- quarchpy/config_files/Switch_Modules/QTL1443-xx - 1-8 USB3 MUX Module Config v4.003.qfg +147 -147
- quarchpy/config_files/Switch_Modules/QTL1443-xx - 1-8 USB3 MUX Module Config v4.100.qfg +147 -147
- quarchpy/config_files/Switch_Modules/QTL1449-xx - 1-8 PCIe MUX Module Config v4.000.qfg +145 -145
- quarchpy/config_files/Switch_Modules/QTL1490-xx - SATA Keyed HS Module Config v4.003 c1.6.qfg +194 -194
- quarchpy/config_files/Switch_Modules/QTL1490-xx - SATA Keyed HS Module Config v4.006 c1.8.qfg +193 -193
- quarchpy/config_files/Switch_Modules/QTL1530-xx - 1-8 DP MUX Module Config v4.000.qfg +145 -145
- quarchpy/config_files/Switch_Modules/QTL1564-xx - 12 Port Mini SAS HD MUX Module Config v4.000.qfg +184 -184
- quarchpy/config_files/Switch_Modules/QTL1584-xx - 1-4 ExpressCard MUX Module Config v4.000.qfg +81 -81
- quarchpy/config_files/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-310.pyc +0 -0
- quarchpy/connection_specific/QPS/win-amd64/app.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/help.txt +17 -50
- quarchpy/connection_specific/QPS/win-amd64/qis/qis.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/QuarchCommon-2.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/usb4java-1.3.1.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps-command-reference.html +104 -112
- quarchpy/connection_specific/QPS/win-amd64/qps.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/JFXUtilities-1.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/QuarchCommon-2.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/scriptCommands.txt +4 -26
- quarchpy/connection_specific/QPS/win-amd64/whats-new.txt +12 -20
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_TCP.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-310.pyc +0 -0
- quarchpy/connection_specific/__pycache__/mDNS.cpython-310.pyc +0 -0
- quarchpy/connection_specific/connection_QIS.py +226 -171
- quarchpy/connection_specific/connection_QPS.py +0 -2
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/fix_permissions.cpython-310.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/bin/java +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/bin/jfr +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/bin/jrunscript +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/bin/jwebserver +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/bin/keytool +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/bin/rmiregistry +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/jaxp.properties +26 -46
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/logging.properties +2 -2
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/management/management.properties +5 -4
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/net.properties +3 -1
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/security/java.policy +46 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/security/java.security +59 -67
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.base/asm.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.base/cldr.md +98 -89
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.base/icu.md +470 -45
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.base/public_suffix.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.base/unicode.md +92 -258
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.desktop/freetype.md +7 -7
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.desktop/giflib.md +10 -6
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.smartcardio/pcsclite.md +4 -4
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xalan.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.crypto.cryptoki/pkcs11cryptotoken.md +10 -14
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/ADDITIONAL_LICENSE_INFO +37 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/ASSEMBLY_EXCEPTION +27 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/LICENSE +347 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/ADDITIONAL_LICENSE_INFO +37 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/ASSEMBLY_EXCEPTION +27 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/LICENSE +347 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.localedata/cldr.md +98 -89
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/classlist +224 -309
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/jexec +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/jfr/default.jfc +10 -36
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/jfr/profile.jfc +10 -35
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/jrt-fs.jar +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/jspawnhelper +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libawt.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libawt_headless.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libawt_xawt.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libdt_socket.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libextnet.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libfontmanager.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libfreetype.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libinstrument.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libj2gss.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libj2pcsc.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libj2pkcs11.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjaas.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjava.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjavajpeg.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjawt.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjdwp.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjimage.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjli.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjsig.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjsound.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libjsvml.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/liblcms.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libmanagement.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libmanagement_agent.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libmanagement_ext.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libmlib_image.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libnet.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libnio.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libprefs.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/librmi.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libsctp.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libsplashscreen.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libsyslookup.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libverify.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libzip.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/modules +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/psfontj2d.properties +1 -1
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/security/default.policy +235 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/security/public_suffix_list.dat +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/server/libjsig.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/server/libjvm.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/tzdb.dat +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/release +2 -2
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/bin/java +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/bin/jfr +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/bin/jrunscript +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/bin/jwebserver +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/bin/keytool +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/bin/rmiregistry +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/jaxp.properties +26 -46
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/logging.properties +2 -2
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/management/management.properties +5 -4
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/net.properties +3 -1
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/security/java.policy +46 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/security/java.security +59 -67
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.base/asm.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.base/cldr.md +98 -89
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.base/icu.md +470 -45
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.base/public_suffix.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.base/unicode.md +92 -258
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.desktop/freetype.md +7 -7
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.desktop/giflib.md +10 -6
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.smartcardio/pcsclite.md +4 -4
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xalan.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.crypto.cryptoki/pkcs11cryptotoken.md +10 -14
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/ADDITIONAL_LICENSE_INFO +37 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/ASSEMBLY_EXCEPTION +27 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/LICENSE +347 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/ADDITIONAL_LICENSE_INFO +37 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/ASSEMBLY_EXCEPTION +27 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/LICENSE +347 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/jdk.localedata/cldr.md +98 -89
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/classlist +223 -315
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/jfr/default.jfc +10 -36
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/jfr/profile.jfc +10 -35
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/jrt-fs.jar +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/jspawnhelper +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libawt.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libawt_lwawt.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libdt_socket.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libextnet.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libfontmanager.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libfreetype.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libinstrument.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libj2gss.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libj2pcsc.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libj2pkcs11.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjaas.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjava.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjavajpeg.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjawt.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjdwp.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjimage.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjli.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjsig.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libjsound.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/liblcms.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libmanagement.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libmanagement_agent.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libmanagement_ext.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libmlib_image.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libnet.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libnio.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libosx.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libosxapp.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libosxkrb5.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libosxsecurity.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libosxui.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libprefs.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/librmi.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libsplashscreen.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libsyslookup.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libverify.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/libzip.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/modules +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/psfontj2d.properties +1 -1
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/security/default.policy +235 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/security/public_suffix_list.dat +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/server/libjsig.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/server/libjvm.dylib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/shaders.metallib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/lib/tzdb.dat +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/release +2 -2
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-console-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-datetime-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-debug-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-errorhandling-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-file-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-file-l1-2-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-file-l2-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-handle-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-heap-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-interlocked-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-libraryloader-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-localization-l1-2-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-memory-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-namedpipe-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-processenvironment-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-processthreads-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-processthreads-l1-1-1.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-profile-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-rtlsupport-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-string-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-synch-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-synch-l1-2-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-sysinfo-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-timezone-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-core-util-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-conio-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-convert-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-environment-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-filesystem-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-heap-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-locale-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-math-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-multibyte-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-private-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-process-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-runtime-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-stdio-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-string-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-time-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/api-ms-win-crt-utility-l1-1-0.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/awt.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/dt_socket.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/extnet.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/fontmanager.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/freetype.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/instrument.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/j2gss.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/j2pcsc.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/j2pkcs11.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jaas.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jabswitch.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jaccessinspector.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jaccesswalker.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/java.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/java.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/javaaccessbridge.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/javajpeg.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/javaw.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jawt.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jdwp.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jfr.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jimage.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jli.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jrunscript.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jsound.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jsvml.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/jwebserver.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/keytool.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/kinit.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/klist.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/ktab.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/lcms.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/management.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/management_agent.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/management_ext.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/mlib_image.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/msvcp140.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/net.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/nio.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/prefs.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/rmi.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/rmiregistry.exe +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/server/jvm.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/splashscreen.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/sspi_bridge.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/syslookup.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/ucrtbase.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/vcruntime140.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/vcruntime140_1.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/verify.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/w2k_lsa_auth.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/windowsaccessbridge-64.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/bin/zip.dll +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/jaxp.properties +26 -46
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/logging.properties +2 -2
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/management/management.properties +5 -4
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/net.properties +3 -1
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/security/java.policy +46 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/security/java.security +59 -67
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.base/asm.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.base/cldr.md +98 -89
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.base/icu.md +470 -45
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.base/public_suffix.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.base/unicode.md +92 -258
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.desktop/freetype.md +7 -7
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.desktop/giflib.md +10 -6
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xalan.md +1 -1
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.crypto.cryptoki/pkcs11cryptotoken.md +10 -14
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/ADDITIONAL_LICENSE_INFO +1 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/ASSEMBLY_EXCEPTION +1 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler/LICENSE +1 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/ADDITIONAL_LICENSE_INFO +1 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/ASSEMBLY_EXCEPTION +1 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/jdk.internal.vm.compiler.management/LICENSE +1 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/classlist +222 -313
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/jawt.lib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/jfr/default.jfc +10 -36
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/jfr/profile.jfc +10 -35
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/jrt-fs.jar +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/jvm.lib +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/modules +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/psfontj2d.properties +1 -1
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/security/default.policy +251 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/security/public_suffix_list.dat +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/tzdb.dat +0 -0
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/lib/tzmappings +146 -1
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/release +2 -2
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialposix.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_linux.cpython-310.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_posix.cpython-310.pyc +0 -0
- quarchpy/connection_specific/usb_libs/usb1.py +2360 -2360
- quarchpy/debug/SystemTest.py +34 -7
- quarchpy/debug/__pycache__/SystemTest.cpython-310.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-310.pyc +0 -0
- quarchpy/debug/module_debug.py +25 -25
- quarchpy/debug/simple_terminal.py +23 -18
- quarchpy/device/__init__.py +4 -4
- quarchpy/device/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-310.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-310.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-310.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-310.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-310.pyc +0 -0
- quarchpy/device/device.py +1237 -441
- quarchpy/device/quarchArray.py +2 -2
- quarchpy/device/quarchPPM.py +9 -9
- quarchpy/device/scanDevices.py +1 -1
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-310.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-310.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-310.pyc +0 -0
- quarchpy/docs/CHANGES.rst +443 -443
- quarchpy/docs/Makefile +20 -20
- quarchpy/docs/_build/html/.buildinfo +4 -4
- quarchpy/docs/_build/html/CHANGES.html +660 -660
- quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +439 -439
- quarchpy/docs/_build/html/_sources/index.rst.txt +23 -23
- quarchpy/docs/_build/html/_sources/readme.rst.txt +41 -41
- quarchpy/docs/_build/html/_sources/source/modules.rst.txt +7 -7
- quarchpy/docs/_build/html/_sources/source/quarchpy.calibration.rst.txt +78 -78
- quarchpy/docs/_build/html/_sources/source/quarchpy.config_files.rst.txt +22 -22
- quarchpy/docs/_build/html/_sources/source/quarchpy.connection_specific.rst.txt +76 -76
- quarchpy/docs/_build/html/_sources/source/quarchpy.debug.rst.txt +38 -38
- quarchpy/docs/_build/html/_sources/source/quarchpy.device.rst.txt +54 -54
- quarchpy/docs/_build/html/_sources/source/quarchpy.disk_test.rst.txt +126 -126
- quarchpy/docs/_build/html/_sources/source/quarchpy.fio.rst.txt +30 -30
- quarchpy/docs/_build/html/_sources/source/quarchpy.iometer.rst.txt +22 -22
- quarchpy/docs/_build/html/_sources/source/quarchpy.qis.rst.txt +22 -22
- quarchpy/docs/_build/html/_sources/source/quarchpy.qps.rst.txt +22 -22
- quarchpy/docs/_build/html/_sources/source/quarchpy.rst.txt +50 -50
- quarchpy/docs/_build/html/_sources/source/quarchpy.user_interface.rst.txt +22 -22
- quarchpy/docs/_build/html/_sources/source/quarchpy.utilities.rst.txt +22 -22
- quarchpy/docs/_build/html/_static/alabaster.css +662 -662
- quarchpy/docs/_build/html/_static/basic.css +913 -913
- quarchpy/docs/_build/html/_static/custom.css +1 -1
- quarchpy/docs/_build/html/_static/doctools.js +149 -149
- quarchpy/docs/_build/html/_static/documentation_options.js +12 -12
- quarchpy/docs/_build/html/_static/jquery-3.4.1.js +10598 -10598
- quarchpy/docs/_build/html/_static/jquery.js +2 -2
- quarchpy/docs/_build/html/_static/language_data.js +192 -192
- quarchpy/docs/_build/html/_static/pygments.css +83 -83
- quarchpy/docs/_build/html/_static/searchtools.js +632 -632
- quarchpy/docs/_build/html/_static/sphinx_highlight.js +154 -154
- quarchpy/docs/_build/html/_static/underscore-1.3.1.js +999 -999
- quarchpy/docs/_build/html/_static/underscore.js +5 -5
- quarchpy/docs/_build/html/genindex.html +1626 -1626
- quarchpy/docs/_build/html/index.html +214 -214
- quarchpy/docs/_build/html/py-modindex.html +300 -300
- quarchpy/docs/_build/html/readme.html +137 -137
- quarchpy/docs/_build/html/search.html +123 -123
- quarchpy/docs/_build/html/source/changelog.html +739 -739
- quarchpy/docs/_build/html/source/licenses.html +181 -181
- quarchpy/docs/_build/html/source/modules.html +222 -222
- quarchpy/docs/_build/html/source/quarchpy.calibration.html +147 -147
- quarchpy/docs/_build/html/source/quarchpy.config_files.html +136 -136
- quarchpy/docs/_build/html/source/quarchpy.connection_specific.html +729 -729
- quarchpy/docs/_build/html/source/quarchpy.debug.html +251 -251
- quarchpy/docs/_build/html/source/quarchpy.device.html +1165 -1165
- quarchpy/docs/_build/html/source/quarchpy.disk_test.html +220 -220
- quarchpy/docs/_build/html/source/quarchpy.fio.html +218 -218
- quarchpy/docs/_build/html/source/quarchpy.html +715 -715
- quarchpy/docs/_build/html/source/quarchpy.iometer.html +271 -271
- quarchpy/docs/_build/html/source/quarchpy.qis.html +640 -640
- quarchpy/docs/_build/html/source/quarchpy.qps.html +186 -186
- quarchpy/docs/_build/html/source/quarchpy.user_interface.html +278 -278
- quarchpy/docs/_build/html/source/quarchpy.utilities.html +211 -211
- quarchpy/docs/_build/html/source/readme.html +147 -147
- quarchpy/docs/conf.py +56 -56
- quarchpy/docs/index.rst +23 -23
- quarchpy/docs/make.bat +35 -35
- quarchpy/docs/readme.rst +41 -41
- quarchpy/docs/source/modules.rst +7 -7
- quarchpy/docs/source/quarchpy.calibration.rst +78 -78
- quarchpy/docs/source/quarchpy.config_files.rst +22 -22
- quarchpy/docs/source/quarchpy.connection_specific.rst +76 -76
- quarchpy/docs/source/quarchpy.debug.rst +38 -38
- quarchpy/docs/source/quarchpy.device.rst +54 -54
- quarchpy/docs/source/quarchpy.disk_test.rst +126 -126
- quarchpy/docs/source/quarchpy.fio.rst +30 -30
- quarchpy/docs/source/quarchpy.iometer.rst +22 -22
- quarchpy/docs/source/quarchpy.qis.rst +22 -22
- quarchpy/docs/source/quarchpy.qps.rst +22 -22
- quarchpy/docs/source/quarchpy.rst +50 -50
- quarchpy/docs/source/quarchpy.user_interface.rst +22 -22
- quarchpy/docs/source/quarchpy.utilities.rst +22 -22
- quarchpy/fio/HIDEtest_performance_class.py +533 -533
- quarchpy/fio/__pycache__/FIO_interface.cpython-310.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/iometer/__pycache__/{gen_iometer_template.cpython-313.pyc → gen_iometer_template.cpython-310.pyc} +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-310.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-310.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-310.pyc +0 -0
- quarchpy/qis/qisFuncs.py +1 -1
- quarchpy/qps/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-310.pyc +0 -0
- quarchpy/user_interface/__pycache__/__init__.cpython-310.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-310.pyc +0 -0
- quarchpy/utilities/__pycache__/TestCenter.cpython-310.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-310.pyc +0 -0
- quarchpy/utilities/__pycache__/Version.cpython-310.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-310.pyc +0 -0
- {quarchpy-2.2.9.dev3.dist-info → quarchpy-2.2.9.dev5.dist-info}/METADATA +466 -466
- {quarchpy-2.2.9.dev3.dist-info → quarchpy-2.2.9.dev5.dist-info}/RECORD +655 -753
- {quarchpy-2.2.9.dev3.dist-info → quarchpy-2.2.9.dev5.dist-info}/WHEEL +1 -1
- quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-313.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-313.pyc +0 -0
- quarchpy/__pycache__/run.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-313.pyc +0 -0
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/Material-Icons-license.txt +0 -51
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/argparse4j-LICENSE.txt +0 -23
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/com.sun.istack-license.html +0 -59
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/commons-io-LICENSE-2.0.txt +0 -202
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/controlsfx-license.txt +0 -29
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/jakarta.activation-license.html +0 -59
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/jakarta.xml.bind-api-license.html +0 -59
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/netty-LICENSE.txt +0 -202
- quarchpy/connection_specific/QPS/win-amd64/3rdPartyLicenses/netty-NOTICE.txt +0 -239
- quarchpy/connection_specific/QPS/win-amd64/InstallType.dat +0 -1
- quarchpy/connection_specific/QPS/win-amd64/app.properties +0 -6
- quarchpy/connection_specific/QPS/win-amd64/license.txt +0 -1
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/com.sun.istack-license.html +0 -59
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/dorkbox-LICENSE.Apachev2 +0 -218
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/jSerialComm-LICENSE-APACHE-2.0 +0 -202
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/jSerialComm-LICENSE-LGPL-3.0 +0 -165
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/jakarta.activation-license.html +0 -59
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/jakarta.xml.bind-api-license.html +0 -59
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/javassist-License.html +0 -381
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/jmdns-LICENSE.txt +0 -202
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/jna-AL2.0 +0 -177
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/kotlin-stdlib-LICENSE-2.0.txt +0 -202
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/netty-LICENSE.txt +0 -202
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/netty-NOTICE.txt +0 -239
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/slf4j-LICENSE.txt +0 -24
- quarchpy/connection_specific/QPS/win-amd64/qis/3rdPartyLicenses/usb4java-LICENSE.md +0 -20
- quarchpy/connection_specific/QPS/win-amd64/qis/license.txt +0 -1
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/CInterface-2.5.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/TorridonCommon-1.3.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/commons-io-2.18.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/qutils-1.0.jar +0 -0
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_TCP.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_TCP.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-313.pyc +0 -0
- quarchpy/connection_specific/__pycache__/mDNS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/mDNS.cpython-313.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/fix_permissions.cpython-311.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/fix_permissions.cpython-313.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/conf/jaxp-strict.properties.template +0 -123
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/schema10part1.md +0 -51
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/schema10part2.md +0 -50
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xhtml10.md +0 -57
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xhtml10schema.md +0 -150
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xhtml11.md +0 -68
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xhtml11schema.md +0 -60
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xmlspec.md +0 -63
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/java.xml/xmlxsd.md +0 -43
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/legal/jdk.incubator.vector/sleef.md +0 -439
- quarchpy/connection_specific/jdk_j21_jres/lin_amd64_jdk_21_jre/lib/libsimdsort.so +0 -0
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/conf/jaxp-strict.properties.template +0 -123
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/schema10part1.md +0 -51
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/schema10part2.md +0 -50
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xhtml10.md +0 -57
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xhtml10schema.md +0 -150
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xhtml11.md +0 -68
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xhtml11schema.md +0 -60
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xmlspec.md +0 -63
- quarchpy/connection_specific/jdk_j21_jres/mac_amd64_jdk_21_jre/legal/java.xml/xmlxsd.md +0 -43
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/conf/jaxp-strict.properties.template +0 -123
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/schema10part1.md +0 -51
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/schema10part2.md +0 -50
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xhtml10.md +0 -57
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xhtml10schema.md +0 -150
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xhtml11.md +0 -68
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xhtml11schema.md +0 -60
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xmlspec.md +0 -63
- quarchpy/connection_specific/jdk_j21_jres/win_amd64_jdk_21_jre/legal/java.xml/xmlxsd.md +0 -43
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/win32.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-313.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-313.pyc +0 -0
- quarchpy/connection_specific/usb_libs/__pycache__/libusb1.cpython-311.pyc +0 -0
- quarchpy/connection_specific/usb_libs/__pycache__/usb1.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/SystemTest.cpython-313.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/module_debug.cpython-313.pyc +0 -0
- quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/simple_terminal.cpython-313.pyc +0 -0
- quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-313.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-313.pyc +0 -0
- quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-313.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-313.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-313.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-313.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-313.pyc +0 -0
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-313.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-313.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-313.pyc +0 -0
- quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/FIO_interface.cpython-313.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-313.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-313.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-313.pyc +0 -0
- quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-313.pyc +0 -0
- quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/__init__.cpython-313.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-313.pyc +0 -0
- quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TestCenter.cpython-313.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-313.pyc +0 -0
- quarchpy/utilities/__pycache__/Version.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/Version.cpython-313.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-313.pyc +0 -0
- /quarchpy/connection_specific/QPS/win-amd64/DeviceConfig/{QTL1995-02.xml → QTL1995-02.XML} +0 -0
- /quarchpy/connection_specific/QPS/win-amd64/DeviceConfig/{QTL1999-02.xml → QTL1999-02.XML} +0 -0
- /quarchpy/connection_specific/QPS/win-amd64/DeviceConfig/{QTL2312-01.xml → QTL2312-01.XML} +0 -0
- {quarchpy-2.2.9.dev3.dist-info → quarchpy-2.2.9.dev5.dist-info}/top_level.txt +0 -0
quarchpy/device/device.py
CHANGED
@@ -1,562 +1,1358 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import Optional, Tuple, Any, Union # Added for type hinting in docstrings
|
3
|
+
import logging
|
4
|
+
import os
|
5
5
|
import re
|
6
|
+
import sys
|
7
|
+
import time
|
6
8
|
|
7
|
-
|
9
|
+
from quarchpy.qps import isQpsRunning
|
10
|
+
from quarchpy.qis import isQisRunning
|
11
|
+
|
12
|
+
from quarchpy.connection import QISConnection, PYConnection, QPSConnection
|
13
|
+
# Check Python version and set timeout exception
|
8
14
|
if sys.version_info.major == 2:
|
9
|
-
# Python 2: Use socket.timeout
|
10
15
|
try:
|
11
16
|
import socket
|
17
|
+
|
12
18
|
timeout_exception = socket.timeout
|
13
19
|
except AttributeError as e:
|
14
20
|
timeout_exception = None
|
15
|
-
logging.error("Socket timeout
|
21
|
+
logging.error(f"Socket timeout unavailable: {e}")
|
16
22
|
else:
|
17
|
-
# Python 3: Use built-in TimeoutError
|
18
|
-
timeout_exception = TimeoutError
|
23
|
+
timeout_exception = TimeoutError # Python 3: Use built-in TimeoutError
|
19
24
|
|
25
|
+
# --- Main Device Class ---
|
20
26
|
class quarchDevice:
|
21
27
|
"""
|
22
|
-
Allows control over a Quarch device, over a wide range of underlying
|
23
|
-
used for control of all
|
24
|
-
|
28
|
+
Allows control over a Quarch device, over a wide range of underlying
|
29
|
+
connection methods. This is the core class used for control of all
|
30
|
+
Quarch products.
|
31
|
+
|
32
|
+
Attributes:
|
33
|
+
ConString (str): The potentially modified connection string used.
|
34
|
+
ConType (str): The specified connection type ('PY', 'QIS', 'QPS').
|
35
|
+
timeout (int): The communication timeout in seconds.
|
36
|
+
connectionObj (Optional[QISConnection, QPSConnection, PYConnection]): The underlying connection
|
37
|
+
object (e.g., PYConnection, QISConnection instance). None if connection failed or is closed.
|
38
|
+
ConCommsType (Optional[str]): The actual communication type determined
|
39
|
+
by the connection object (e.g., 'USB', 'TCP'). Set for PY type.
|
40
|
+
connectionName (Optional[str]): The target identifier determined by the
|
41
|
+
connection object (e.g., 'QTL1234-01-001', '192.168.1.100'). Set for PY type.
|
42
|
+
connectionTypeName (Optional[str]): Alias for ConCommsType. Set for PY type.
|
25
43
|
"""
|
26
44
|
|
27
|
-
def __init__(self, ConString, ConType="PY", timeout="5"):
|
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
|
-
|
45
|
+
def __init__(self, ConString: str, ConType: str = "PY", timeout: str = "5"):
|
46
|
+
"""
|
47
|
+
Initializes the quarchDevice, establishes the connection.
|
48
|
+
|
49
|
+
Performs initial parameter validation, determines the connection type,
|
50
|
+
delegates to specific helper methods to create the underlying connection
|
51
|
+
object (PYConnection, QISConnection, or QPSConnection), and verifies
|
52
|
+
the connection.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
ConString (str): The connection string (e.g., "USB:ID", "TCP:IP", "QIS:ID").
|
56
|
+
ConType (str, optional): The connection mode ('PY', 'QIS', 'QPS'). Defaults to "PY".
|
57
|
+
timeout (str, optional): Communication timeout in seconds. Defaults to "5".
|
58
|
+
|
59
|
+
Raises:
|
60
|
+
ValueError: If ConString format is invalid or timeout is not numeric.
|
61
|
+
ConnectionError: If establishing the connection fails.
|
62
|
+
TimeoutError: If verifying the device on QIS/QPS times out.
|
63
|
+
ImportError: If required underlying connection classes are missing.
|
64
|
+
"""
|
65
|
+
# --- Initial setup and validation ---
|
66
|
+
# Initialize all instance attributes first
|
67
|
+
self.ConType = ""
|
68
|
+
self.ConString = ""
|
69
|
+
self.connectionTypeName = None
|
70
|
+
self.connectionName = None
|
71
|
+
self.ConCommsType = None
|
72
|
+
self.connectionObj = None
|
73
|
+
self.timeout = 5 # Default int timeout
|
74
|
+
|
75
|
+
# Call helper to store and validate parameters
|
76
|
+
self._store_and_validate_params(ConString, ConType, timeout)
|
77
|
+
|
78
|
+
logging.debug(f"Initializing quarchDevice with ConString='{self.ConString}', ConType='{self.ConType}', Timeout='{self.timeout}'")
|
79
|
+
con_type_upper = self.ConType.upper()
|
80
|
+
|
81
|
+
# --- Delegate to specific initialization method ---
|
82
|
+
if con_type_upper == "PY":
|
83
|
+
self._initialize_py_connection()
|
84
|
+
elif con_type_upper.startswith("QIS"):
|
85
|
+
self._initialize_qis_connection()
|
86
|
+
elif con_type_upper.startswith("QPS"):
|
87
|
+
self._initialize_qps_connection()
|
88
|
+
else:
|
89
|
+
# Invalid ConType should have been caught by check_module_format
|
90
|
+
raise ValueError(f"Invalid connection type '{self.ConType}'.")
|
91
|
+
|
92
|
+
# --- Final connection verification ---
|
93
|
+
self._verify_connection_object()
|
94
|
+
logging.info(f"Connection successful: Type='{self.ConType}', Target='{getattr(self.connectionObj, 'ConnTarget', 'Unknown')}'")
|
95
|
+
|
96
|
+
# --- Private Helper Methods ---
|
97
|
+
|
98
|
+
def _store_and_validate_params(self, ConString: str, ConType: str, timeout: str):
|
99
|
+
"""
|
100
|
+
Stores initial parameters and performs basic validation.
|
101
|
+
|
102
|
+
Sets self.ConString (with lowercasing rule), self.ConType,
|
103
|
+
validates and sets self.timeout (as int), and calls
|
104
|
+
check_module_format to validate ConString format.
|
105
|
+
|
106
|
+
Args:
|
107
|
+
ConString (str): The raw connection string.
|
108
|
+
ConType (str): The raw connection type.
|
109
|
+
timeout (str): The raw timeout value.
|
110
|
+
|
111
|
+
Raises:
|
112
|
+
ValueError: If timeout is non-numeric or ConString format is invalid.
|
113
|
+
"""
|
63
114
|
self.ConString = ConString
|
115
|
+
# Lowercase unless serial
|
64
116
|
if "serial" not in ConString.lower():
|
65
117
|
self.ConString = ConString.lower()
|
66
|
-
self.ConType = ConType
|
118
|
+
self.ConType = ConType
|
119
|
+
self.connectionObj = None # Ensure it's reset here
|
120
|
+
self.timeout = int(timeout)
|
67
121
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
raise Exception("Invalid value for timeout, must be a numeric value")
|
122
|
+
# Use the globally defined check_module_format function
|
123
|
+
if not check_module_format(self.ConString):
|
124
|
+
raise ValueError(f"Module format is invalid for connection string: '{self.ConString}'")
|
72
125
|
|
73
|
-
|
74
|
-
|
126
|
+
def _initialize_py_connection(self):
|
127
|
+
"""
|
128
|
+
Initializes the connection using the PY (Pure Python) method.
|
75
129
|
|
76
|
-
|
77
|
-
|
78
|
-
|
130
|
+
Handles colon formatting, resolves target using get_connection_target if
|
131
|
+
applicable, creates the PYConnection object, stores connection details,
|
132
|
+
and verifies communication with a '*tst?' command.
|
79
133
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
self.ConString = self.ConString.replace('::', ':')
|
134
|
+
Sets:
|
135
|
+
self.connectionObj, self.ConCommsType, self.connectionName,
|
136
|
+
self.connectionTypeName, self.ConString (potentially updated).
|
84
137
|
|
85
|
-
|
86
|
-
|
87
|
-
|
138
|
+
Raises:
|
139
|
+
ConnectionError: If connection fails or device doesn't respond correctly.
|
140
|
+
ImportError: If PYConnection class is missing.
|
141
|
+
"""
|
142
|
+
logging.debug("Attempting PY connection...")
|
143
|
+
# Handle potential double colons
|
144
|
+
numb_colons = self.ConString.count(":")
|
145
|
+
if numb_colons == 2:
|
146
|
+
logging.debug("Replacing '::' with ':' in ConString for PY connection.")
|
147
|
+
self.ConString = self.ConString.replace('::', ':')
|
148
|
+
|
149
|
+
# Resolve target if needed
|
150
|
+
self._resolve_py_target()
|
88
151
|
|
89
|
-
|
152
|
+
# Create PYConnection object
|
153
|
+
try:
|
154
|
+
# Store PYConnection object
|
90
155
|
self.connectionObj = PYConnection(self.ConString)
|
91
|
-
|
156
|
+
# Store connection details from the object
|
157
|
+
self.ConCommsType = getattr(self.connectionObj, 'ConnTypeStr', None)
|
158
|
+
self.connectionName = getattr(self.connectionObj, 'ConnTarget', None)
|
159
|
+
self.connectionTypeName = self.ConCommsType # Alias
|
160
|
+
logging.debug(f"PY Connection details: Type='{self.connectionTypeName}', Target='{self.connectionName}'")
|
161
|
+
except Exception as e_pyconn:
|
162
|
+
logging.error(f"Failed to create PYConnection for '{self.ConString}': {e_pyconn}", exc_info=True)
|
163
|
+
raise ConnectionError(f"Failed to establish PY connection for '{self.ConString}'") from e_pyconn
|
164
|
+
|
165
|
+
# Verify communication with *tst?
|
166
|
+
self._test_py_connection()
|
167
|
+
|
168
|
+
def _resolve_py_target(self):
|
169
|
+
"""
|
170
|
+
Attempts to resolve ConString target if needed for PY connections.
|
92
171
|
|
93
|
-
|
94
|
-
|
95
|
-
|
172
|
+
If the ConString looks like a QTL identifier (contains 'qtl') but is
|
173
|
+
not explicitly USB, it calls the external `get_connection_target`
|
174
|
+
function to find the best actual connection string (e.g., a specific
|
175
|
+
COM port or IP address) and updates `self.ConString` if found.
|
96
176
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
177
|
+
Uses:
|
178
|
+
self.ConString
|
179
|
+
get_connection_target (imported function)
|
180
|
+
|
181
|
+
Modifies:
|
182
|
+
self.ConString (if target is resolved)
|
183
|
+
"""
|
184
|
+
# Check conditions: contains 'qtl', not 'usb', and helper function exists
|
185
|
+
if "qtl" in self.ConString.lower() and "usb" not in self.ConString.lower():
|
186
|
+
from quarchpy.device import get_connection_target
|
187
|
+
if get_connection_target is not None:
|
188
|
+
try:
|
189
|
+
logging.debug(f"Attempting to resolve connection target for '{self.ConString}'...")
|
190
|
+
resolved_con_string = get_connection_target(self.ConString)
|
191
|
+
if resolved_con_string and "Fail" not in resolved_con_string: # Check for failure string
|
192
|
+
logging.debug(f"Resolved '{self.ConString}' to '{resolved_con_string}'")
|
193
|
+
self.ConString = resolved_con_string # Update if successful
|
194
|
+
else:
|
195
|
+
logging.warning(f"get_connection_target failed or returned empty for '{self.ConString}'. Using original.")
|
196
|
+
except Exception as e_scan:
|
197
|
+
# Log error but continue with original ConString
|
198
|
+
logging.error(f"Error calling get_connection_target: {e_scan}. Using original ConString.")
|
106
199
|
else:
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
## QIS
|
111
|
-
# ConType may be QIS only or QIS:ip:port [:3] checks if the first 3 letters are QIS.
|
112
|
-
elif self.ConType[:3].upper() == "QIS":
|
113
|
-
try: # If host and port are specified.
|
114
|
-
QIS, host, port = self.ConType.split(':') # Extract QIS, host and port.
|
115
|
-
port = int(port) # QIS port should be an int.
|
116
|
-
except: # If host and port are not specified.
|
117
|
-
host = '127.0.0.1'
|
118
|
-
port = 9722
|
119
|
-
|
120
|
-
numb_colons = self.ConString.count(":")
|
121
|
-
if numb_colons == 1:
|
122
|
-
self.ConString = self.ConString.replace(':', '::')
|
123
|
-
# Creates the connection object.
|
124
|
-
self.connectionObj = QISConnection(self.ConString, host, port)
|
200
|
+
# Log if resolution needed but helper unavailable
|
201
|
+
logging.warning("get_connection_target function not available, cannot resolve connection string.")
|
125
202
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
timeout = time.time() + int(timeout) # now + n seconds
|
130
|
-
# check for device in list, has a timeout
|
131
|
-
while time.time() < timeout: # look for the connection string in qis $list details
|
132
|
-
|
133
|
-
# Check if it's a module's QTL number
|
134
|
-
if "qtl" not in self.ConString.lower():
|
135
|
-
|
136
|
-
# If not, check if it contains a valid IP address format
|
137
|
-
ip_address = re.search(r"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", self.ConString)
|
138
|
-
if not ip_address:
|
139
|
-
raise ValueError("ConString " + self.ConString + " does not contain a valid QTL number or IP address")
|
140
|
-
# Attempt to get QTL number from qis "$list details"
|
141
|
-
temp_str = _check_ip_in_qis_list(ip_address.group(), self.connectionObj.qis.get_list_details())
|
142
|
-
if temp_str:
|
143
|
-
# If found
|
144
|
-
self.ConString = temp_str
|
145
|
-
break
|
146
|
-
|
147
|
-
logging.debug("Did not find ip address in list details, attempt targetted qis scan")
|
148
|
-
|
149
|
-
# If it's not present in the list already, then try scanning for it via qis
|
150
|
-
# Scan is purposefully after initial check! 09/03/2023
|
151
|
-
# Valid response example "Located device: 192.168.1.3"
|
152
|
-
if "located" in str(self.connectionObj.qis.scanIP(self.ConString)).lower():
|
153
|
-
# Note - Qis takes a moment or 2 to add this newly located device to the $list 21/03/23
|
154
|
-
timeout += 20 # Extend the timeout as the drive was located
|
155
|
-
while time.time() < timeout:
|
156
|
-
# try find the QTL from ipaddress
|
157
|
-
temp_str = _check_ip_in_qis_list(ip_address.group(), self.connectionObj.qis.get_list_details())
|
158
|
-
if temp_str:
|
159
|
-
# If the item is found, break out of this loop
|
160
|
-
self.ConString = temp_str
|
161
|
-
break
|
162
|
-
time.sleep(1) # Slow down the poll
|
163
|
-
else:
|
164
|
-
# if it's not found, continue and allow program to timeout
|
165
|
-
continue
|
166
|
-
# Break out of both loops
|
167
|
-
break
|
168
|
-
|
169
|
-
elif str(self.ConString).lower() in str(list_str).lower():
|
170
|
-
# If we have QTL device, and it's in list, nothing more needs done.
|
171
|
-
break
|
172
|
-
else:
|
173
|
-
time.sleep(1)
|
174
|
-
list = self.connectionObj.qis.getDeviceList()
|
175
|
-
list_str = "".join(list).lower()
|
176
|
-
else: # If we didn't hit a 'break' condition in the above loop, then it timed out
|
177
|
-
raise timeout_exception("Could not find module " + self.ConString + " from Qis within specified time")
|
203
|
+
def _test_py_connection(self):
|
204
|
+
"""
|
205
|
+
Sends '*tst?' command to verify communication for PY connections.
|
178
206
|
|
179
|
-
|
207
|
+
Checks if the response contains "OK" or "FAIL".
|
208
|
+
Closes connection and raises ConnectionError
|
209
|
+
if the test fails or times out.
|
180
210
|
|
181
|
-
|
182
|
-
|
211
|
+
Raises:
|
212
|
+
ConnectionError: If the command fails or the response is invalid.
|
213
|
+
"""
|
214
|
+
try:
|
215
|
+
# Use snake_case internally
|
216
|
+
item = self.send_command("*tst?")
|
217
|
+
except Exception as e_tst:
|
218
|
+
logging.warning(f"Error sending *tst? during init: {e_tst}")
|
219
|
+
# Raise a more specific error indicating communication failure
|
220
|
+
raise ConnectionError("Module failed to respond to *tst? command during initialization.") from e_tst
|
221
|
+
|
222
|
+
# Check if response indicates basic communication success
|
223
|
+
response_ok = item is not None and ("OK" in item or "FAIL" in item)
|
224
|
+
if not response_ok:
|
225
|
+
logging.error(f"No valid module response to *tst? command! Received: '{item}'")
|
183
226
|
try:
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
if numb_colons == 1:
|
195
|
-
self.ConString = self.ConString.replace(':', '::')
|
227
|
+
self.close_connection()
|
228
|
+
except Exception as close_err:
|
229
|
+
logging.error(f"Error closing connection after *tst? failure: {close_err}")
|
230
|
+
# Raise error indicating failed test
|
231
|
+
raise ConnectionError(f"No valid module response to *tst? command! Received: '{item}'")
|
232
|
+
logging.debug("*tst? check successful.")
|
233
|
+
|
234
|
+
def _parse_server_details(self, default_port: int) -> Tuple[str, int]:
|
235
|
+
"""
|
236
|
+
Parses host and port from self.ConType for QIS/QPS connection types.
|
196
237
|
|
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
|
-
|
238
|
+
Expects self.ConType to be like "QIS" or "QIS:host:port".
|
239
|
+
Returns defaults ('127.0.0.1', default_port) if parsing fails or is not applicable.
|
240
|
+
|
241
|
+
Args:
|
242
|
+
default_port (int): The default port number for the server type (QIS/QPS).
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
tuple[str, int]: A tuple containing the host (str) and port (int).
|
246
|
+
"""
|
247
|
+
host = '127.0.0.1'
|
248
|
+
port = default_port
|
249
|
+
con_type_upper = self.ConType.upper()
|
250
|
+
# Determine prefix based on actual ConType start
|
251
|
+
prefix = "QIS" if con_type_upper.startswith("QIS") else "QPS" if con_type_upper.startswith("QPS") else None
|
252
|
+
|
253
|
+
if prefix:
|
254
|
+
try:
|
255
|
+
# Attempt to split ConType string like "QIS:host:port"
|
256
|
+
_, host_parsed, port_str = self.ConType.split(':')
|
257
|
+
port = int(port_str) # Convert port part to integer
|
258
|
+
host = host_parsed # Use parsed host
|
259
|
+
except ValueError:
|
260
|
+
# Handles cases where split fails (not 3 parts) or int conversion fails
|
261
|
+
# Only log warning if it looked like host/port were provided but were invalid
|
262
|
+
if con_type_upper != prefix:
|
263
|
+
logging.warning(f"Could not parse host/port from ConType '{self.ConType}', using defaults {host}:{port}.")
|
264
|
+
except Exception as e_parse:
|
265
|
+
# Catch any other unexpected parsing errors
|
266
|
+
logging.warning(f"Error parsing ConType '{self.ConType}': {e_parse}. Using defaults {host}:{port}.")
|
267
|
+
return host, port
|
268
|
+
|
269
|
+
def _prepare_server_con_string(self):
|
270
|
+
"""
|
271
|
+
Formats self.ConString by replacing single ':' with '::' if needed.
|
272
|
+
|
273
|
+
This is sometimes required for QIS/QPS connection libraries when only
|
274
|
+
one colon is present in the identifier part (e.g., "TCP:ID" becomes "TCP::ID").
|
275
|
+
|
276
|
+
Modifies:
|
277
|
+
self.ConString
|
278
|
+
"""
|
279
|
+
numb_colons = self.ConString.count(":")
|
280
|
+
# Apply replacement only if exactly one colon exists
|
281
|
+
if numb_colons == 1:
|
282
|
+
logging.debug(f"Replacing single colon ':' with '::' in ConString '{self.ConString}' for server connection.")
|
283
|
+
self.ConString = self.ConString.replace(':', '::')
|
284
|
+
|
285
|
+
def _verify_server_device(self, server_conn_obj: Any, server_type: str):
|
286
|
+
"""
|
287
|
+
Finds and verifies the target device on a QIS or QPS server.
|
288
|
+
|
289
|
+
Repeatedly checks the server's device list for the target device
|
290
|
+
(self.ConString), handling identification by QTL number or IP address.
|
291
|
+
If identified by IP, resolves it to the device's actual connection string
|
292
|
+
(e.g., "TYPE::QTL...") using _check_ip_in_qis_list. May trigger a
|
293
|
+
network scan via the server connection object's scanIP method if needed.
|
294
|
+
|
295
|
+
Args:
|
296
|
+
server_conn_obj (Any): The specific QIS/QPS connection object
|
297
|
+
(e.g., self.connectionObj.qis). Type hinted as Any
|
298
|
+
as the exact type depends on the imported library.
|
299
|
+
server_type (str): "QIS" or "QPS" for logging/error messages.
|
300
|
+
|
301
|
+
Returns:
|
302
|
+
bool: True if the device was successfully found and verified.
|
303
|
+
`self.ConString` may be updated as a side effect if resolved via IP.
|
304
|
+
|
305
|
+
Raises:
|
306
|
+
ValueError: If ConString is IP-based but contains no valid IP.
|
307
|
+
TimeoutError: If the device cannot be found/verified within self.timeout.
|
308
|
+
Exception: Propagates exceptions from server_conn_obj methods.
|
309
|
+
"""
|
310
|
+
# --- Initialization ---
|
311
|
+
logging.debug(f"Verifying device '{self.ConString}' on {server_type} server...")
|
312
|
+
found = False
|
313
|
+
connect_timeout = time.time() + self.timeout # Calculate deadline
|
314
|
+
|
315
|
+
# --- Main Verification Loop ---
|
316
|
+
while time.time() < connect_timeout:
|
317
|
+
# --- Get current list details ---
|
318
|
+
try:
|
319
|
+
list_details = server_conn_obj.get_list_details() # Assumes method exists
|
320
|
+
list_str_lower = "".join(list_details).lower()
|
321
|
+
except Exception as e_list:
|
322
|
+
logging.warning(f"Failed to refresh {server_type} list details during check: {e_list}")
|
323
|
+
if time.time() >= connect_timeout:
|
245
324
|
break
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
325
|
+
time.sleep(1) # Wait before retrying list fetch
|
326
|
+
continue # Skip rest of loop iteration
|
327
|
+
|
328
|
+
# --- Determine target type (IP or QTL) ---
|
329
|
+
target_lower = self.ConString.lower()
|
330
|
+
|
331
|
+
if "qtl" not in target_lower:
|
332
|
+
# --- Target is likely IP Address ---
|
333
|
+
ip_match = re.search(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", target_lower)
|
334
|
+
if not ip_match:
|
335
|
+
raise ValueError(f"ConString '{self.ConString}' has no QTL and no valid IP for {server_type}.")
|
336
|
+
target_ip = ip_match.group()
|
337
|
+
|
338
|
+
# Call helper to find by IP (handles list check, scan, re-check)
|
339
|
+
resolved_string = self._find_device_by_ip(server_conn_obj, server_type, list_details, target_ip)
|
340
|
+
if resolved_string:
|
341
|
+
# Side effect: self.ConString was updated in helper
|
342
|
+
found = True
|
343
|
+
break # Exit main loop
|
344
|
+
# If _find_device_by_ip returns None, IP wasn't found in this iteration/scan attempt
|
345
|
+
else:
|
346
|
+
# --- Target is QTL Number ---
|
347
|
+
if self._find_device_by_qtl(list_str_lower, target_lower):
|
348
|
+
found = True # Found via QTL
|
349
|
+
break # Exit main loop
|
350
|
+
|
351
|
+
# --- Not found yet, wait before next iteration ---
|
352
|
+
if time.time() >= connect_timeout:
|
353
|
+
break # Exit loop if timeout reached before sleeping
|
354
|
+
logging.debug(f"Target '{self.ConString}' not found in {server_type} list yet. Waiting 1s before retry...")
|
355
|
+
time.sleep(1)
|
356
|
+
|
357
|
+
# --- Loop Finished: Final Check ---
|
358
|
+
if not found:
|
359
|
+
logging.error(f"Timeout: Could not find/verify module '{self.ConString}' in {server_type} within {self.timeout}s.")
|
360
|
+
raise TimeoutError(f"Could not find module '{self.ConString}' in {server_type} within {self.timeout}s")
|
361
|
+
|
362
|
+
logging.info(f"Successfully verified device '{self.ConString}' in {server_type}.")
|
363
|
+
return True # Indicate success
|
364
|
+
|
365
|
+
def _find_device_by_ip(self, server_conn_obj, server_type, list_details, target_ip):
|
366
|
+
"""
|
367
|
+
Attempts to find the device via IP, potentially resolving it and scanning.
|
252
368
|
|
369
|
+
Checks the provided list, then optionally scans if not found and re-checks.
|
370
|
+
Updates self.ConString if resolved via IP lookup.
|
253
371
|
|
372
|
+
Args:
|
373
|
+
server_conn_obj: The specific QIS/QPS connection object (e.g., self.connectionObj.qis).
|
374
|
+
server_type (str): "QIS" or "QPS" for logging/error messages.
|
375
|
+
list_details (list): The current list details from the server.
|
376
|
+
target_ip (str): The IP address being searched for.
|
254
377
|
|
378
|
+
Returns:
|
379
|
+
str: The resolved ConString if found (and self.ConString is updated).
|
380
|
+
None: If not found via IP lookup or scan within this attempt.
|
255
381
|
|
382
|
+
Raises:
|
383
|
+
Exceptions from underlying scanIP or get_list_details calls.
|
384
|
+
"""
|
385
|
+
# 1. Check current list details for the IP
|
386
|
+
resolved_con_string = _check_ip_in_qis_list(target_ip, list_details)
|
387
|
+
if resolved_con_string:
|
388
|
+
logging.info(f"Resolved IP {target_ip} to '{resolved_con_string}' from {server_type} list.")
|
389
|
+
self.ConString = resolved_con_string # Update instance ConString
|
390
|
+
return resolved_con_string # Return resolved string
|
391
|
+
|
392
|
+
# 2. IP not in list, attempt network scan if possible
|
393
|
+
logging.debug(f"IP {target_ip} not in {server_type} list, attempting network scan...")
|
394
|
+
try:
|
395
|
+
scan_method = getattr(server_conn_obj, 'scanIP', None)
|
396
|
+
if not scan_method:
|
397
|
+
logging.warning(f"scanIP method not found on {server_type} connection object.")
|
398
|
+
return None # Cannot scan
|
399
|
+
|
400
|
+
scan_response = scan_method(target_ip) # Scan using the target IP
|
401
|
+
if "located" not in str(scan_response).lower():
|
402
|
+
logging.debug(f"{server_type} scan for {target_ip} did not locate the device.")
|
403
|
+
return None # Scan didn't find it
|
404
|
+
|
405
|
+
# 3. Scan located the device, now re-check the list after a delay
|
406
|
+
logging.info(f"{server_type} located {target_ip} via scan. Re-checking list after delay...")
|
407
|
+
# Use a shorter, fixed timeout for this re-check phase
|
408
|
+
scan_recheck_timeout = time.time() + 20 # Allow 20s for list update
|
409
|
+
time.sleep(2) # Initial pause
|
410
|
+
|
411
|
+
while time.time() < scan_recheck_timeout:
|
412
|
+
current_list_details = server_conn_obj.get_list_details() # Re-fetch
|
413
|
+
resolved_con_string = _check_ip_in_qis_list(target_ip, current_list_details)
|
414
|
+
if resolved_con_string:
|
415
|
+
logging.info(f"Resolved IP {target_ip} to '{resolved_con_string}' after scan.")
|
416
|
+
self.ConString = resolved_con_string # Update instance ConString
|
417
|
+
return resolved_con_string # Return resolved string
|
418
|
+
# If not found yet, wait before checking again
|
419
|
+
if time.time() >= scan_recheck_timeout:
|
420
|
+
break # Check timeout before sleep
|
421
|
+
logging.debug(f"IP {target_ip} still not resolved in {server_type} list post-scan, retrying...")
|
422
|
+
time.sleep(1)
|
423
|
+
|
424
|
+
# If loop finishes without finding, log it
|
425
|
+
logging.warning(f"Device at {target_ip} was located by scan but did not appear resolvable in {server_type} list within timeout.")
|
426
|
+
return None # Not found even after scan
|
427
|
+
|
428
|
+
except Exception as e_findIP:
|
429
|
+
# Log errors during the scan process but don't necessarily stop verification yet
|
430
|
+
logging.warning(f"Error during {server_type} scan/re-check for {target_ip}: {e_findIP}")
|
431
|
+
return None # Indicate IP search failed for this attempt
|
432
|
+
|
433
|
+
@staticmethod
|
434
|
+
def _find_device_by_qtl(list_str_lower, target_qtl_lower):
|
435
|
+
"""Checks if the target QTL identifier exists in the server list string."""
|
436
|
+
if target_qtl_lower in list_str_lower:
|
437
|
+
logging.debug(f"Found target QTL '{target_qtl_lower}' directly in server list.")
|
438
|
+
return True
|
439
|
+
return False
|
256
440
|
|
441
|
+
def _initialize_qis_connection(self):
|
442
|
+
"""
|
443
|
+
Initializes the connection using the QIS method.
|
257
444
|
|
258
|
-
|
259
|
-
|
260
|
-
|
445
|
+
Parses host/port, prepares connection string, creates QISConnection object,
|
446
|
+
verifies the device presence on the server using the common helper, and
|
447
|
+
sets the device as default on the QIS server.
|
448
|
+
|
449
|
+
Sets:
|
450
|
+
self.connectionObj, self.ConString.
|
451
|
+
|
452
|
+
Raises:
|
453
|
+
ConnectionError: If connection or verification fails.
|
454
|
+
TimeoutError: If verification times out.
|
455
|
+
ImportError: If QISConnection class is missing.
|
456
|
+
"""
|
457
|
+
logging.debug("Attempting QIS connection...")
|
458
|
+
host, port = self._parse_server_details(default_port=9722)
|
459
|
+
self._prepare_server_con_string()
|
460
|
+
|
461
|
+
# Create QISConnection object
|
462
|
+
try:
|
463
|
+
# Assumes QISConnection is imported
|
464
|
+
self.connectionObj = QISConnection(self.ConString, host, port)
|
465
|
+
logging.debug(f"QISConnection object created for '{self.ConString}' via {host}:{port}")
|
466
|
+
except Exception as e_qisconn:
|
467
|
+
logging.error(f"Failed to create QISConnection: {e_qisconn}", exc_info=True)
|
468
|
+
raise ConnectionError("Failed to establish QIS connection.") from e_qisconn
|
469
|
+
|
470
|
+
# Verify device presence on the QIS server
|
471
|
+
try:
|
472
|
+
# Pass the QIS-specific sub-object (self.connectionObj.qis) to the helper
|
473
|
+
self._verify_server_device(self.connectionObj.qis, "QIS")
|
474
|
+
except TimeoutError as e_timeout:
|
475
|
+
self.close_connection() # Close object if verification failed
|
476
|
+
raise e_timeout # Re-raise timeout
|
477
|
+
except Exception as e_qis_conn:
|
478
|
+
self.close_connection() # Close object if verification failed
|
479
|
+
raise ConnectionError(f"Failed QIS device verification: {e_qis_conn}") from e_qis_conn
|
480
|
+
|
481
|
+
# Set QIS default device
|
482
|
+
try:
|
483
|
+
set_default_cmd = f"$default {self.ConString}"
|
484
|
+
logging.debug(f"Setting QIS default device: {set_default_cmd}")
|
485
|
+
# Assumes sendAndReceiveCmd exists on QIS object
|
486
|
+
response = self.connectionObj.qis.sendAndReceiveCmd(cmd=set_default_cmd)
|
487
|
+
logging.debug(f"QIS set default response: {response}")
|
488
|
+
if "fail" in response.lower():
|
489
|
+
logging.warning(f"QIS command '$default {self.ConString}' failed.")
|
490
|
+
except Exception as e_def:
|
491
|
+
logging.warning(f"Error setting QIS default device: {e_def}")
|
492
|
+
|
493
|
+
def _initialize_qps_connection(self):
|
494
|
+
"""
|
495
|
+
Initializes the connection using the QPS method.
|
496
|
+
|
497
|
+
Parses host/port, prepares connection string, creates QPSConnection object,
|
498
|
+
and verifies the device presence on the server using the common helper.
|
499
|
+
|
500
|
+
Sets:
|
501
|
+
self.connectionObj, self.ConString (potentially updated).
|
502
|
+
|
503
|
+
Raises:
|
504
|
+
ConnectionError: If connection or verification fails.
|
505
|
+
TimeoutError: If verification times out.
|
506
|
+
ImportError: If QPSConnection class is missing.
|
507
|
+
"""
|
508
|
+
logging.debug("Attempting QPS connection...")
|
509
|
+
host, port = self._parse_server_details(default_port=9822) # type: ignore[misc] # Private call ok
|
510
|
+
self._prepare_server_con_string() # type: ignore[misc] # Private call ok
|
511
|
+
|
512
|
+
# Create QPSConnection object
|
513
|
+
try:
|
514
|
+
# Assumes QPSConnection is imported
|
515
|
+
self.connectionObj = QPSConnection(host, port)
|
516
|
+
logging.debug(f"QPSConnection object created via {host}:{port}")
|
517
|
+
except Exception as e_qpsconn:
|
518
|
+
logging.error(f"Failed to create QPSConnection: {e_qpsconn}", exc_info=True)
|
519
|
+
raise ConnectionError("Failed to establish QPS connection.") from e_qpsconn
|
520
|
+
|
521
|
+
# Verify device presence on the QPS server
|
522
|
+
try:
|
523
|
+
# Pass the QPS-specific sub-object (self.connectionObj.qps) to the helper
|
524
|
+
self._verify_server_device(self.connectionObj.qps, "QPS") # type: ignore[misc] # Private call ok
|
525
|
+
except TimeoutError as e_timeout:
|
526
|
+
self.close_connection() # Close object if verification failed
|
527
|
+
raise e_timeout # Re-raise timeout
|
528
|
+
except Exception as e_qps_conn:
|
529
|
+
self.close_connection() # Close object if verification failed
|
530
|
+
raise ConnectionError(f"Failed QPS device verification: {e_qps_conn}") from e_qps_conn
|
531
|
+
# QPS typically doesn't use/need a '$default' command
|
532
|
+
|
533
|
+
def _verify_connection_object(self):
|
534
|
+
"""
|
535
|
+
Performs final checks to ensure a valid connection object exists.
|
536
|
+
|
537
|
+
Raises:
|
538
|
+
ConnectionError: If self.connectionObj is None or lacks expected attributes.
|
539
|
+
"""
|
540
|
+
if not self.connectionObj:
|
541
|
+
# This should ideally be caught by specific init helpers, but acts as a final safeguard
|
542
|
+
raise ConnectionError("Connection object (self.connectionObj) was not successfully created by initializer.")
|
261
543
|
|
262
|
-
|
544
|
+
def __del__(self):
|
545
|
+
""" Ensures the connection is closed when the object is garbage collected. """
|
546
|
+
try:
|
547
|
+
# Close all connections
|
548
|
+
self.close_connection()
|
549
|
+
except Exception as e_close:
|
550
|
+
# Avoid errors during shutdown sequence
|
551
|
+
if logging and logging.error:
|
552
|
+
logging.error(f"Error during automatic connection close in destructor: {e_close}")
|
263
553
|
|
554
|
+
# --- Public Methods (Wrappers + snake_case) ---
|
264
555
|
|
265
|
-
#
|
266
|
-
|
267
|
-
|
268
|
-
|
556
|
+
# --- sendCommand ---
|
557
|
+
def send_command(self, command_string: str, is_response_expected: bool = True) -> str:
|
558
|
+
"""
|
559
|
+
Executes a text command on the connected device.
|
560
|
+
|
561
|
+
Sends the command string via the appropriate underlying connection object
|
562
|
+
(PY, QIS, or QPS) and returns the response. Handles QIS/QPS specific
|
563
|
+
formatting or command routing as needed.
|
564
|
+
|
565
|
+
Args:
|
566
|
+
command_string (str): The text command to send (e.g., "*IDN?").
|
567
|
+
is_response_expected (bool, optional): If False, the method may return
|
568
|
+
faster as it doesn't wait for/read a response. Defaults to True.
|
569
|
+
|
570
|
+
Returns:
|
571
|
+
str: The response string from the device. Returns an empty string if
|
572
|
+
no response was expected or received, or if the underlying connection
|
573
|
+
returned None.
|
574
|
+
|
575
|
+
Raises:
|
576
|
+
ConnectionError: If the device is not connected, or if communication fails.
|
577
|
+
TimeoutError: If the device response times out.
|
578
|
+
NotImplementedError: If the method is called for an unsupported ConType.
|
269
579
|
"""
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
580
|
+
logging.debug(f"{os.path.basename(__file__)}: {self.ConType[:3]} sending command: {command_string}")
|
581
|
+
|
582
|
+
if not hasattr(self, 'connectionObj') or not self.connectionObj:
|
583
|
+
raise ConnectionError("Connection object not available in send_command.")
|
584
|
+
|
585
|
+
con_type_upper = self.ConType.upper()
|
586
|
+
try:
|
587
|
+
if con_type_upper.startswith("QIS"):
|
588
|
+
# Use current ConString state (might have been updated)
|
589
|
+
current_con_string = self.ConString
|
590
|
+
numb_colons = current_con_string.count(":")
|
591
|
+
if numb_colons == 1:
|
592
|
+
current_con_string = current_con_string.replace(':', '::')
|
593
|
+
# Assumes QISConnection type for connectionObj
|
594
|
+
response = self.connectionObj.qis.sendCommand(command_string, device=current_con_string, expectedResponse=is_response_expected)
|
595
|
+
|
596
|
+
elif con_type_upper == "PY":
|
597
|
+
# Assumes PYConnection type for connectionObj
|
598
|
+
if hasattr(self.connectionObj, 'connection') and hasattr(self.connectionObj.connection, 'sendCommand'):
|
599
|
+
response = self.connectionObj.connection.sendCommand(command_string, expectedResponse=is_response_expected)
|
600
|
+
else:
|
601
|
+
raise AttributeError("PYConnection object missing expected structure.")
|
602
|
+
|
603
|
+
elif con_type_upper.startswith("QPS"):
|
604
|
+
# Assumes QPSConnection type for connectionObj
|
605
|
+
if command_string and command_string[0] != '$':
|
606
|
+
command_string = f"{self.ConString} {command_string}" # Prepend target ID
|
607
|
+
response = self.connectionObj.qps.sendCommand(command_string, is_response_expected)
|
608
|
+
else:
|
609
|
+
raise NotImplementedError(f"send_command not implemented for ConType {self.ConType}")
|
610
|
+
|
611
|
+
except timeout_exception: # Use platform specific timeout
|
612
|
+
logging.error(f"Timeout sending command: '{command_string}'")
|
613
|
+
raise TimeoutError(f"Timeout sending command: {command_string}")
|
614
|
+
except Exception as e_cmd_exception:
|
615
|
+
logging.error(f"Error sending command '{command_string}': {e_cmd_exception}", exc_info=True)
|
616
|
+
raise ConnectionError(f"Error sending command '{command_string}'") from e_cmd_exception
|
617
|
+
|
618
|
+
response_str = response if response is not None else "" # Ensure string
|
619
|
+
logging.debug(f"{os.path.basename(__file__)}: {self.ConType[:3]} received: {response_str[:100]}{'...' if len(response_str) > 100 else ''}")
|
620
|
+
return response_str
|
621
|
+
|
622
|
+
def sendCommand(self, CommandString: str, expectedResponse: bool = True) -> str:
|
623
|
+
"""
|
624
|
+
DEPRECATED - Use send_command instead.
|
625
|
+
|
626
|
+
Executes a text command on the connected device.
|
276
627
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
-------
|
281
|
-
command_response : str or None
|
628
|
+
Sends the command string via the appropriate underlying connection object
|
629
|
+
(PY, QIS, or QPS) and returns the response. Handles QIS/QPS specific
|
630
|
+
formatting or command routing as needed.
|
282
631
|
|
283
|
-
|
284
|
-
|
632
|
+
Args:
|
633
|
+
CommandString (str): The text command to send (e.g., "*IDN?").
|
634
|
+
expectedResponse (bool, optional): If False, the method may return
|
635
|
+
faster as it doesn't wait for/read a response. Defaults to True.
|
285
636
|
|
637
|
+
Returns:
|
638
|
+
str: The response string from the device. Returns an empty string if
|
639
|
+
no response was expected or received, or if the underlying connection
|
640
|
+
returned None.
|
641
|
+
|
642
|
+
Raises:
|
643
|
+
ConnectionError: If the device is not connected, or if communication fails.
|
644
|
+
TimeoutError: If the device response times out.
|
645
|
+
NotImplementedError: If the method is called for an unsupported ConType.
|
286
646
|
"""
|
647
|
+
return self.send_command(CommandString, expectedResponse)
|
287
648
|
|
288
|
-
|
289
|
-
|
649
|
+
# --- sendBinaryCommand ---
|
650
|
+
def send_binary_command(self, cmd: bytes) -> bytes:
|
651
|
+
"""
|
652
|
+
Sends a binary command and reads binary response (USB only).
|
290
653
|
|
291
|
-
|
654
|
+
This method is typically used for low-level or USB-specific communication.
|
655
|
+
It assumes a PY connection type with a specific underlying structure.
|
292
656
|
|
293
|
-
|
294
|
-
|
295
|
-
self.ConString = self.ConString.replace(':', '::')
|
657
|
+
Args:
|
658
|
+
cmd (bytes): The binary command sequence to send.
|
296
659
|
|
297
|
-
|
298
|
-
|
299
|
-
logging.debug(os.path.basename(__file__) + ": "+self.ConType[:3]+" received: " + response)
|
300
|
-
return response
|
660
|
+
Returns:
|
661
|
+
bytes: The binary data read back from the device.
|
301
662
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
663
|
+
Raises:
|
664
|
+
TypeError: If the connection type is not PY or the underlying
|
665
|
+
connection object structure is unexpected.
|
666
|
+
ConnectionError: If communication fails.
|
667
|
+
"""
|
668
|
+
# Check connection type and structure
|
669
|
+
if self.ConType.upper() != "PY" or \
|
670
|
+
not hasattr(self.connectionObj, 'connection') or \
|
671
|
+
not hasattr(self.connectionObj.connection, 'Connection') or \
|
672
|
+
not hasattr(self.connectionObj.connection.Connection, 'SendCommand') or \
|
673
|
+
not hasattr(self.connectionObj.connection.Connection, 'BulkRead'):
|
674
|
+
raise TypeError(f"send_binary_command requires a PY connection with a USB connection.")
|
675
|
+
|
676
|
+
logging.debug("Sending binary command...")
|
677
|
+
try:
|
678
|
+
self.connectionObj.connection.Connection.SendCommand(cmd)
|
679
|
+
response = self.connectionObj.connection.Connection.BulkRead()
|
680
|
+
except Exception as e_binary_exception:
|
681
|
+
logging.error(f"Error during binary command: {e_binary_exception}", exc_info=True)
|
682
|
+
raise ConnectionError("Failed to send/receive binary command.") from e_binary_exception
|
307
683
|
|
308
|
-
|
309
|
-
|
310
|
-
if CommandString[0] != '$':
|
311
|
-
CommandString = self.ConString + " " + CommandString
|
684
|
+
logging.debug("Received binary response.")
|
685
|
+
return response if response is not None else b"" # Ensure bytes return
|
312
686
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
687
|
+
def sendBinaryCommand(self, cmd: bytes) -> bytes:
|
688
|
+
"""
|
689
|
+
DEPRECATED - Use send_binary_command instead.
|
690
|
+
|
691
|
+
Sends a binary command and reads binary response (USB only).
|
317
692
|
|
693
|
+
This method is typically used for low-level or USB-specific communication.
|
694
|
+
It assumes a PY connection type with a specific underlying structure.
|
318
695
|
|
319
|
-
|
320
|
-
|
321
|
-
def sendBinaryCommand(self, cmd):
|
322
|
-
self.connectionObj.connection.Connection.SendCommand(cmd)
|
323
|
-
return self.connectionObj.connection.Connection.BulkRead()
|
696
|
+
Args:
|
697
|
+
cmd (bytes): The binary command sequence to send.
|
324
698
|
|
699
|
+
Returns:
|
700
|
+
bytes: The binary data read back from the device.
|
325
701
|
|
326
|
-
|
327
|
-
|
328
|
-
|
702
|
+
Raises:
|
703
|
+
TypeError: If the connection type is not PY or the underlying
|
704
|
+
connection object structure is unexpected.
|
705
|
+
ConnectionError: If communication fails.
|
329
706
|
"""
|
330
|
-
|
331
|
-
|
332
|
-
|
707
|
+
return self.send_binary_command(cmd)
|
708
|
+
|
709
|
+
# --- openConnection ---
|
710
|
+
def open_connection(self) -> Any:
|
333
711
|
"""
|
334
|
-
|
335
|
-
logging.debug("Attempting to open " + self.ConType[:3] + " connection")
|
712
|
+
Opens or re-opens the connection to the module.
|
336
713
|
|
337
|
-
|
338
|
-
|
714
|
+
Handles reopening logic based on the connection type (PY, QIS, QPS).
|
715
|
+
For PY, it recreates the connection object. For QIS/QPS, it calls
|
716
|
+
the underlying connect method.
|
339
717
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
718
|
+
Returns:
|
719
|
+
Any: For PY connections, returns the new PYConnection object.
|
720
|
+
For QIS/QPS, returns the result of the underlying connect call
|
721
|
+
(could be bool or other status). Returns True for successful QIS connect.
|
344
722
|
|
345
|
-
|
346
|
-
|
723
|
+
Raises:
|
724
|
+
AttributeError: If the connection object is missing expected methods (connect).
|
725
|
+
ConnectionError: If reopening the connection fails.
|
726
|
+
ValueError: If the connection type is not recognized.
|
727
|
+
"""
|
728
|
+
logging.debug(f"Attempting to open {self.ConType[:3]} connection")
|
729
|
+
con_type_upper = self.ConType.upper()
|
347
730
|
|
348
|
-
|
349
|
-
|
731
|
+
try:
|
732
|
+
if con_type_upper.startswith("QIS"):
|
733
|
+
if hasattr(self.connectionObj, 'qis') and hasattr(self.connectionObj.qis, 'connect'):
|
734
|
+
self.connectionObj.qis.connect()
|
735
|
+
logging.info("QIS connect called.")
|
736
|
+
return True # Assume success if no exception (original TODO noted lack of return check)
|
737
|
+
else:
|
738
|
+
raise AttributeError("QIS connection object or connect method not found.")
|
739
|
+
|
740
|
+
elif con_type_upper == "PY":
|
741
|
+
# Recreate PYConnection (original logic, potentially risky)
|
742
|
+
logging.warning("Recreating PYConnection in open_connection. Previous handles might linger.")
|
743
|
+
if self.connectionObj and hasattr(self.connectionObj, 'connection') and hasattr(self.connectionObj.connection, 'close'):
|
744
|
+
try:
|
745
|
+
self.connectionObj.connection.close() # Close old one first
|
746
|
+
except Exception as e_connection_exception:
|
747
|
+
logging.warning(f"Unable to close old PY Connection: {e_connection_exception}")
|
748
|
+
pass
|
749
|
+
# Recreate (assumes PYConnection is imported)
|
750
|
+
self.connectionObj = PYConnection(self.ConString)
|
751
|
+
logging.info(f"PY Connection recreated for {self.ConString}")
|
752
|
+
# Update internal details
|
753
|
+
self.ConCommsType = getattr(self.connectionObj, 'ConnTypeStr', None)
|
754
|
+
self.connectionName = getattr(self.connectionObj, 'ConnTarget', None)
|
755
|
+
self.connectionTypeName = self.ConCommsType
|
756
|
+
return self.connectionObj # Return new object
|
757
|
+
|
758
|
+
elif con_type_upper.startswith("QPS"):
|
759
|
+
if hasattr(self.connectionObj, 'qps') and hasattr(self.connectionObj.qps, 'connect'):
|
760
|
+
result = self.connectionObj.qps.connect(self.ConString)
|
761
|
+
logging.info(f"QPS connect called for {self.ConString}. Result: {result}")
|
762
|
+
return result
|
763
|
+
else:
|
764
|
+
raise AttributeError("QPS connection object or connect method not found.")
|
350
765
|
|
766
|
+
else:
|
767
|
+
raise ValueError("Connection type not recognised in open_connection")
|
768
|
+
|
769
|
+
except Exception as e_conn:
|
770
|
+
logging.error(f"Failed to open connection for {self.ConString} ({self.ConType}): {e_conn}", exc_info=True)
|
771
|
+
raise ConnectionError(f"Failed to open connection for {self.ConString}") from e_conn
|
772
|
+
|
773
|
+
def openConnection(self) -> Any:
|
774
|
+
"""
|
775
|
+
DEPRECATED - Use open_connection instead.
|
776
|
+
|
777
|
+
Opens or re-opens the connection to the module.
|
778
|
+
|
779
|
+
Handles reopening logic based on the connection type (PY, QIS, QPS).
|
780
|
+
For PY, it recreates the connection object. For QIS/QPS, it calls
|
781
|
+
the underlying connect method.
|
782
|
+
|
783
|
+
Returns:
|
784
|
+
Any: For PY connections, returns the new PYConnection object.
|
785
|
+
For QIS/QPS, returns the result of the underlying connect call
|
786
|
+
(could be bool or other status). Returns True for successful QIS connect.
|
351
787
|
|
352
|
-
|
353
|
-
|
788
|
+
Raises:
|
789
|
+
AttributeError: If the connection object is missing expected methods (connect).
|
790
|
+
ConnectionError: If reopening the connection fails.
|
791
|
+
ValueError: If the connection type is not recognized.
|
354
792
|
"""
|
355
|
-
|
356
|
-
|
793
|
+
return self.open_connection()
|
794
|
+
|
795
|
+
# --- closeConnection ---
|
796
|
+
def close_connection(self) -> str:
|
357
797
|
"""
|
358
|
-
|
359
|
-
logging.debug("Attempting to close " + self.ConType[:3] + " connection")
|
798
|
+
Closes the connection to the module.
|
360
799
|
|
361
|
-
|
362
|
-
|
363
|
-
self.connectionObj.qis.closeConnection(conString=self.ConString)
|
364
|
-
elif self.ConType == "PY":
|
365
|
-
self.connectionObj.connection.close()
|
800
|
+
Handles closing logic based on connection type (PY, QIS, QPS).
|
801
|
+
Clears the internal connection object reference upon successful close.
|
366
802
|
|
367
|
-
|
368
|
-
|
803
|
+
Returns:
|
804
|
+
str: "OK" on success, "FAIL" on failure or if no connection exists.
|
805
|
+
"""
|
806
|
+
# This method contains the original logic from closeConnection
|
807
|
+
logging.debug(f"Attempting to close {self.ConType[:3]} connection for {self.ConString}")
|
808
|
+
con_type_upper = self.ConType.upper()
|
809
|
+
closed_ok = False
|
810
|
+
conn_obj_to_close = self.connectionObj # Work with current object
|
369
811
|
|
370
|
-
|
812
|
+
if conn_obj_to_close is None:
|
813
|
+
logging.debug("No connection object exists to close.")
|
814
|
+
return "OK" # Nothing to do
|
371
815
|
|
816
|
+
try:
|
817
|
+
if con_type_upper.startswith("QIS"):
|
818
|
+
if hasattr(conn_obj_to_close, 'qis') and hasattr(conn_obj_to_close.qis, 'closeConnection'):
|
819
|
+
if isQisRunning():
|
820
|
+
conn_obj_to_close.qis.closeConnection(conString=self.ConString)
|
821
|
+
closed_ok = True
|
822
|
+
else:
|
823
|
+
logging.warning("QIS connection object or closeConnection method not found.")
|
372
824
|
|
373
|
-
|
374
|
-
|
825
|
+
elif con_type_upper == "PY":
|
826
|
+
if hasattr(conn_obj_to_close, 'connection') and hasattr(conn_obj_to_close.connection, 'close'):
|
827
|
+
conn_obj_to_close.connection.close()
|
828
|
+
closed_ok = True
|
829
|
+
else:
|
830
|
+
logging.warning("PY connection object structure invalid for close.")
|
831
|
+
|
832
|
+
elif con_type_upper.startswith("QPS"):
|
833
|
+
if hasattr(conn_obj_to_close, 'qps') and hasattr(conn_obj_to_close.qps, 'disconnect'):
|
834
|
+
if isQpsRunning():
|
835
|
+
conn_obj_to_close.qps.disconnect(self.ConString) # QPS uses disconnect
|
836
|
+
closed_ok = True
|
837
|
+
else:
|
838
|
+
logging.warning("QPS connection object or disconnect method not found.")
|
839
|
+
else:
|
840
|
+
logging.error(f"Cannot close unknown connection type: {self.ConType}")
|
841
|
+
|
842
|
+
if closed_ok:
|
843
|
+
logging.info(f"Connection closed for {self.ConString}")
|
844
|
+
self.connectionObj = None # Clear reference only if close succeeded
|
845
|
+
return "OK"
|
846
|
+
else:
|
847
|
+
logging.warning(f"Could not close connection for {self.ConString} - state uncertain.")
|
848
|
+
return "FAIL"
|
849
|
+
|
850
|
+
except Exception as e_close:
|
851
|
+
logging.error(f"Error during close_connection for {self.ConString}: {e_close}", exc_info=True)
|
852
|
+
# Do not clear self.connectionObj if close failed with exception
|
853
|
+
return "FAIL"
|
854
|
+
|
855
|
+
def closeConnection(self) -> str:
|
375
856
|
"""
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
Returns
|
386
|
-
-------
|
387
|
-
result : bool
|
388
|
-
|
389
|
-
True if the device was found and reconnected, false if it was not and we timed out
|
390
|
-
|
857
|
+
DEPRECATED - Use close_connection instead.
|
858
|
+
|
859
|
+
Closes the connection to the module.
|
860
|
+
|
861
|
+
Handles closing logic based on connection type (PY, QIS, QPS).
|
862
|
+
Clears the internal connection object reference upon successful close.
|
863
|
+
|
864
|
+
Returns:
|
865
|
+
str: "OK" on success, "FAIL" on failure or if no connection exists.
|
391
866
|
"""
|
867
|
+
return self.close_connection()
|
392
868
|
|
393
|
-
|
394
|
-
|
869
|
+
# --- resetDevice ---
|
870
|
+
def reset_device(self, timeout: int = 10) -> bool:
|
871
|
+
"""
|
872
|
+
Issues a reset command and attempts recovery.
|
395
873
|
|
396
|
-
|
874
|
+
Sends '*rst' to the device, handles connection type specifics (like
|
875
|
+
closing PY connection), then attempts to reconnect within the timeout period.
|
397
876
|
|
398
|
-
|
399
|
-
|
400
|
-
self.ConString = self.ConString.replace(':', '::')
|
877
|
+
Args:
|
878
|
+
timeout (int, optional): Seconds to wait for reconnection. Defaults to 10.
|
401
879
|
|
402
|
-
|
403
|
-
|
404
|
-
logging.debug(os.path.basename(__file__) + ": connecting back to " + retval)
|
880
|
+
Returns:
|
881
|
+
bool: True if reset and reconnection were successful, False otherwise.
|
405
882
|
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
883
|
+
Raises:
|
884
|
+
ConnectionError: If sending the reset command fails initially (and connection exists).
|
885
|
+
"""
|
886
|
+
logging.debug(f"{os.path.basename(__file__)}: sending command: *rst")
|
887
|
+
original_con_string = self.ConString # Store original target before potential modification
|
888
|
+
original_con_type = self.ConType # Store original type
|
889
|
+
con_type_upper = self.ConType.upper()
|
413
890
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
CommandString = self.ConString + " " + "*rst"
|
418
|
-
self.connectionObj.qps.sendCmdVerbose(CommandString, expectedResponse = False)
|
419
|
-
logging.debug(os.path.basename(__file__) + ": connecting back to " + retval)
|
891
|
+
if not hasattr(self, 'connectionObj') or not self.connectionObj:
|
892
|
+
logging.error("Cannot reset device, no connection object.")
|
893
|
+
return False
|
420
894
|
|
421
|
-
#
|
895
|
+
# --- Send Reset Command ---
|
896
|
+
try:
|
897
|
+
if con_type_upper.startswith("QIS"):
|
898
|
+
current_con_string = original_con_string
|
899
|
+
numb_colons = current_con_string.count(":")
|
900
|
+
if numb_colons == 1:
|
901
|
+
current_con_string = current_con_string.replace(':', '::')
|
902
|
+
self.connectionObj.qis.sendCmd(current_con_string, "*rst", expectedResponse=False)
|
903
|
+
elif con_type_upper == "PY":
|
904
|
+
self.connectionObj.connection.sendCommand("*rst", expectedResponse=False)
|
905
|
+
self.connectionObj.connection.close() # Close PY after reset
|
906
|
+
self.connectionObj = None # Clear potentially invalid object
|
907
|
+
elif con_type_upper.startswith("QPS"):
|
908
|
+
CommandString = f"{original_con_string} *rst"
|
909
|
+
self.connectionObj.qps.sendCmdVerbose(CommandString, expectedResponse=False)
|
910
|
+
else:
|
911
|
+
logging.error(f"Reset not supported for connection type {self.ConType}")
|
912
|
+
return False
|
913
|
+
logging.debug("*rst command sent successfully.")
|
422
914
|
|
423
|
-
|
915
|
+
except Exception as e_reset:
|
916
|
+
logging.error(f"Error sending *rst command: {e_reset}", exc_info=True)
|
917
|
+
# Attempt to close connection forcefully on error before recovery attempt?
|
918
|
+
try:
|
919
|
+
self.close_connection()
|
920
|
+
except Exception as e_close:
|
921
|
+
logging.warning(f"Unable to close current connection: {e_close}")
|
922
|
+
pass
|
923
|
+
# Return False as reset command itself failed
|
924
|
+
return False
|
925
|
+
|
926
|
+
# --- Recovery Attempt ---
|
927
|
+
logging.debug(f"Attempting to reconnect to {original_con_string} after reset...")
|
928
|
+
temp_device = None
|
424
929
|
startTime = time.time()
|
425
|
-
time.sleep(0.6)
|
426
|
-
|
930
|
+
time.sleep(0.6)
|
931
|
+
|
932
|
+
while temp_device is None:
|
933
|
+
# Check timeout
|
934
|
+
if (time.time() - startTime) > timeout:
|
935
|
+
logging.critical(f"Reconnection failed to {original_con_string} within {timeout}s timeout.")
|
936
|
+
self.connectionObj = None # Ensure connectionObj is None if recovery failed
|
937
|
+
return False
|
427
938
|
try:
|
428
|
-
#
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
939
|
+
# Calculate remaining timeout for the attempt
|
940
|
+
remaining_timeout = max(1, timeout - int(time.time() - startTime))
|
941
|
+
temp_device = get_quarch_device(original_con_string, ConType=original_con_type, timeout=str(remaining_timeout))
|
942
|
+
except Exception as recon_e:
|
943
|
+
logging.debug(f"Reconnect attempt failed: {recon_e}. Retrying...")
|
944
|
+
time.sleep(0.2)
|
945
|
+
|
946
|
+
# --- Recovery Successful ---
|
947
|
+
logging.info(f"Successfully reconnected to {original_con_string} after reset.")
|
948
|
+
# Replace the current connection object and potentially other details
|
949
|
+
self.connectionObj = temp_device.connectionObj
|
950
|
+
self.ConString = temp_device.ConString # Update ConString (might have changed if resolved)
|
951
|
+
self.ConType = temp_device.ConType # Update ConType (should likely be same?)
|
952
|
+
# Copy other relevant attributes if necessary
|
953
|
+
self.timeout = temp_device.timeout
|
954
|
+
if hasattr(temp_device, 'ConCommsType'):
|
955
|
+
self.ConCommsType = temp_device.ConCommsType
|
956
|
+
if hasattr(temp_device, 'connectionName'):
|
957
|
+
self.connectionName = temp_device.connectionName
|
958
|
+
if hasattr(temp_device, 'connectionTypeName'):
|
959
|
+
self.connectionTypeName = temp_device.connectionTypeName
|
960
|
+
|
961
|
+
time.sleep(1)
|
438
962
|
return True
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
if
|
476
|
-
|
963
|
+
|
964
|
+
def resetDevice(self, timeout: int = 10) -> bool:
|
965
|
+
"""
|
966
|
+
DEPRECATED - Use reset_device instead.
|
967
|
+
|
968
|
+
Issues a reset command and attempts recovery.
|
969
|
+
|
970
|
+
Sends '*rst' to the device, handles connection type specifics (like
|
971
|
+
closing PY connection), then attempts to reconnect within the timeout period.
|
972
|
+
|
973
|
+
Args:
|
974
|
+
timeout (int, optional): Seconds to wait for reconnection. Defaults to 10.
|
975
|
+
|
976
|
+
Returns:
|
977
|
+
bool: True if reset and reconnection were successful, False otherwise.
|
978
|
+
|
979
|
+
Raises:
|
980
|
+
ConnectionError: If sending the reset command fails initially (and connection exists).
|
981
|
+
"""
|
982
|
+
return self.reset_device(timeout)
|
983
|
+
|
984
|
+
# --- send_and_verify_command/sendAndVerifyCommand ---
|
985
|
+
def send_and_verify_command(self, command_string: str, expected_response: str = "OK", exception: bool = True) -> bool:
|
986
|
+
"""
|
987
|
+
Sends a command and verifies the response matches expected string.
|
988
|
+
|
989
|
+
A convenience wrapper around `send_command`.
|
990
|
+
|
991
|
+
Args:
|
992
|
+
command_string (str): The text command to send.
|
993
|
+
expected_response (str, optional): The exact string expected back from
|
994
|
+
the device. Defaults to "OK". Comparison is case-sensitive.
|
995
|
+
exception (bool, optional): If True, raises ValueError if the response
|
996
|
+
does not match. If False, returns False on mismatch. Defaults to True.
|
997
|
+
|
998
|
+
Returns:
|
999
|
+
bool: True if the response matched `expected_response`, False otherwise
|
1000
|
+
(only if `exception` is False).
|
1001
|
+
|
1002
|
+
Raises:
|
1003
|
+
ValueError: If the response does not match `expected_response` and
|
1004
|
+
`exception` is True.
|
1005
|
+
ConnectionError: If sending the command fails.
|
1006
|
+
TimeoutError: If the device times out responding.
|
1007
|
+
"""
|
1008
|
+
responseStr = self.send_command(command_string)
|
1009
|
+
|
1010
|
+
if responseStr != expected_response:
|
1011
|
+
error_msg = f"Command Sent: '{command_string}', Expected response: '{expected_response}', Response received: '{responseStr}'"
|
1012
|
+
logging.error(error_msg)
|
1013
|
+
if exception:
|
1014
|
+
raise ValueError(error_msg)
|
477
1015
|
else:
|
478
1016
|
return False
|
479
1017
|
else:
|
1018
|
+
logging.debug(f"Command '{command_string}' verified successfully (Response: '{expected_response}').")
|
480
1019
|
return True
|
481
1020
|
|
1021
|
+
def sendAndVerifyCommand(self, commandString: str, responseExpected: str = "OK", exception: bool = True) -> bool:
|
1022
|
+
"""
|
1023
|
+
DEPRECATED - Use send_and_verify_command instead.
|
1024
|
+
|
1025
|
+
Sends a command and verifies the response matches expected string.
|
1026
|
+
|
1027
|
+
A convenience wrapper around `send_command`.
|
1028
|
+
|
1029
|
+
Args:
|
1030
|
+
commandString (str): The text command to send.
|
1031
|
+
responseExpected (str, optional): The exact string expected back from
|
1032
|
+
the device. Defaults to "OK". Comparison is case-sensitive.
|
1033
|
+
exception (bool, optional): If True, raises ValueError if the response
|
1034
|
+
does not match. If False, returns False on mismatch. Defaults to True.
|
1035
|
+
|
1036
|
+
Returns:
|
1037
|
+
bool: True if the response matched `expected_response`, False otherwise
|
1038
|
+
(only if `exception` is False).
|
1039
|
+
|
1040
|
+
Raises:
|
1041
|
+
ValueError: If the response does not match `expected_response` and
|
1042
|
+
`exception` is True.
|
1043
|
+
ConnectionError: If sending the command fails.
|
1044
|
+
TimeoutError: If the device times out responding.
|
1045
|
+
"""
|
1046
|
+
return self.send_and_verify_command(commandString, responseExpected, exception)
|
1047
|
+
|
1048
|
+
# --- get_runtime/getRuntime ---
|
1049
|
+
def get_runtime(self, command: str = "conf:runtimes?") -> Optional[int]:
|
1050
|
+
"""
|
1051
|
+
Queries the device runtime and returns it as an integer in seconds.
|
482
1052
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
1053
|
+
Handles potential "FAIL" responses and non-numeric/non-'s' terminated responses.
|
1054
|
+
|
1055
|
+
Args:
|
1056
|
+
command (str, optional): The specific command to query runtime.
|
1057
|
+
Defaults to "conf:runtimes?". Can be overridden for different
|
1058
|
+
modules (e.g., PAM fixtures).
|
1059
|
+
|
1060
|
+
Returns:
|
1061
|
+
Optional[int]: The runtime in seconds if successfully parsed, otherwise None.
|
1062
|
+
"""
|
1063
|
+
runtime_str = self.send_command(command)
|
1064
|
+
|
1065
|
+
if runtime_str is None:
|
1066
|
+
logging.error(f"Received None response for runtime command: {command}")
|
1067
|
+
return None
|
1068
|
+
|
1069
|
+
# Use case-insensitive check for "fail"
|
1070
|
+
if "fail" in runtime_str.lower():
|
1071
|
+
logging.error(f"Runtime check failed (Command: {command}, Response: {runtime_str}), check FW/FPGA?")
|
1072
|
+
return None # Return None on failure
|
1073
|
+
|
1074
|
+
# Check if response ends with 's' and try conversion
|
1075
|
+
if isinstance(runtime_str, str) and runtime_str.endswith("s"):
|
1076
|
+
try:
|
1077
|
+
runtime_int = int(runtime_str[:-1])
|
1078
|
+
logging.debug(f"Runtime parsed as {runtime_int} seconds.")
|
1079
|
+
return runtime_int
|
1080
|
+
except ValueError:
|
1081
|
+
logging.error(f"Runtime response '{runtime_str}' not a valid int format.")
|
1082
|
+
return None
|
1083
|
+
except Exception as e_runtime:
|
1084
|
+
logging.error(f"Unexpected error parsing runtime '{runtime_str}': {e_runtime}", exc_info=True)
|
1085
|
+
return None
|
499
1086
|
else:
|
1087
|
+
# Log if format is unexpected
|
1088
|
+
logging.warning(f"Runtime response '{runtime_str}' did not end with 's' or was not string. Cannot parse as seconds.")
|
500
1089
|
return None
|
501
1090
|
|
1091
|
+
def getRuntime(self, command: str = "conf:runtimes?") -> Optional[int]:
|
1092
|
+
"""
|
1093
|
+
DEPRECATED - Use get_runtime instead.
|
1094
|
+
|
1095
|
+
Queries the device runtime and returns it as an integer in seconds.
|
1096
|
+
|
1097
|
+
Handles potential "FAIL" responses and non-numeric/non-'s' terminated responses.
|
1098
|
+
|
1099
|
+
Args:
|
1100
|
+
command (str, optional): The specific command to query runtime.
|
1101
|
+
Defaults to "conf:runtimes?". Can be overridden for different
|
1102
|
+
modules (e.g., PAM fixtures).
|
1103
|
+
|
1104
|
+
Returns:
|
1105
|
+
Optional[int]: The runtime in seconds if successfully parsed, otherwise None.
|
1106
|
+
"""
|
1107
|
+
return self.get_runtime(command)
|
1108
|
+
|
502
1109
|
|
503
|
-
|
1110
|
+
# --- Top-Level Function Definitions ---
|
1111
|
+
|
1112
|
+
def _check_ip_in_qis_list(ip_address: str, detailed_device_list: list) -> Optional[str]:
|
504
1113
|
"""
|
505
|
-
Checks if
|
506
|
-
|
507
|
-
|
1114
|
+
Checks if an IP address exists in a QIS/QPS device list detail output.
|
1115
|
+
|
1116
|
+
Parses the list provided by the server to find an entry matching the IP
|
1117
|
+
address (specifically for TCP entries) and returns the corresponding
|
1118
|
+
full connection string (e.g., "TCP::QTL...") if found.
|
1119
|
+
|
1120
|
+
Args:
|
1121
|
+
ip_address (str): The IP address to search for.
|
1122
|
+
detailed_device_list (list[str]): A list where each string is a line
|
1123
|
+
from the server's "$list details" or "$module list details" output.
|
1124
|
+
|
1125
|
+
Returns:
|
1126
|
+
Optional[str]: The resolved connection string (e.g., "TCP::QTL...") if a
|
1127
|
+
matching TCP entry is found, otherwise None.
|
508
1128
|
"""
|
509
|
-
#
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
#
|
515
|
-
|
516
|
-
|
517
|
-
#
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
1129
|
+
# This function's logic remains unchanged
|
1130
|
+
if not detailed_device_list:
|
1131
|
+
return None
|
1132
|
+
|
1133
|
+
for module_line in detailed_device_list:
|
1134
|
+
# Use regex to find IP pattern robustly
|
1135
|
+
ip_match = re.search(r"\bIP:(" + re.escape(ip_address) + r")\b", module_line) # Match exact IP
|
1136
|
+
if ip_match:
|
1137
|
+
# Found the IP, check if it's a TCP entry
|
1138
|
+
if "tcp" in module_line.lower():
|
1139
|
+
# Try to extract the "TYPE::ID" part using regex or split
|
1140
|
+
conn_str_match = re.search(r"^\s*\d+\)\s+([A-Z]+::\S+)", module_line) # Look for "N) TYPE::ID"
|
1141
|
+
if conn_str_match:
|
1142
|
+
logging.debug(f"Resolved IP {ip_address} using regex to: {conn_str_match.group(1)}")
|
1143
|
+
return conn_str_match.group(1)
|
1144
|
+
else:
|
1145
|
+
# Fallback to original split method if regex fails
|
1146
|
+
parts = module_line.split()
|
1147
|
+
if len(parts) > 1 and "::" in parts[1]:
|
1148
|
+
logging.debug(f"Resolved IP {ip_address} using split method to: {parts[1]}")
|
1149
|
+
return parts[1]
|
1150
|
+
else:
|
1151
|
+
logging.warning(f"Found IP {ip_address} in TCP line, but couldn't extract TYPE::ID: {module_line}")
|
1152
|
+
else:
|
1153
|
+
logging.debug(f"IP {ip_address} found but not a TCP entry: {module_line}")
|
1154
|
+
|
1155
|
+
# IP address not found in any relevant line
|
522
1156
|
return None
|
523
1157
|
|
524
1158
|
|
525
|
-
#
|
526
|
-
def
|
527
|
-
|
1159
|
+
# --- checkModuleFormat / check_module_format ---
|
1160
|
+
def check_module_format(ConString: str) -> bool:
|
1161
|
+
"""
|
1162
|
+
Checks the basic validity of a connection string format.
|
1163
|
+
|
1164
|
+
Verifies presence of ':', checks against allowed connection types,
|
1165
|
+
and validates the number of colons or sub-device format.
|
1166
|
+
|
1167
|
+
Args:
|
1168
|
+
ConString (str): The connection string to validate.
|
1169
|
+
|
1170
|
+
Returns:
|
1171
|
+
bool: True if the format seems valid, False otherwise.
|
528
1172
|
|
1173
|
+
Note:
|
1174
|
+
Uses a specific list of allowed connection types defined within.
|
1175
|
+
May recursively call itself to validate controller part of sub-device strings.
|
1176
|
+
"""
|
1177
|
+
if not ConString:
|
1178
|
+
return True # Allow empty
|
1179
|
+
if ':' not in ConString:
|
1180
|
+
logging.warning("check_module_format: Connection string missing ':'.")
|
1181
|
+
return False
|
1182
|
+
|
1183
|
+
ConnectionTypes = ["USB", "SERIAL", "TELNET", "REST", "TCP"]
|
529
1184
|
conTypeSpecified = ConString[:ConString.find(':')]
|
530
1185
|
|
531
1186
|
correctConType = False
|
532
1187
|
for value in ConnectionTypes:
|
533
1188
|
if value.lower() == conTypeSpecified.lower():
|
534
1189
|
correctConType = True
|
1190
|
+
break
|
535
1191
|
|
536
1192
|
if not correctConType:
|
537
|
-
logging.warning("Invalid connection type specified
|
538
|
-
logging.warning("Invalid connection string: "
|
1193
|
+
logging.warning(f"Invalid connection type specified ('{conTypeSpecified}'). Use one of {ConnectionTypes}")
|
1194
|
+
logging.warning(f"Invalid connection string: {ConString}")
|
539
1195
|
return False
|
540
1196
|
|
541
1197
|
numb_colons = ConString.count(":")
|
542
|
-
|
543
|
-
|
544
|
-
|
1198
|
+
|
1199
|
+
# Check sub-device format first
|
1200
|
+
if "<" in ConString and ">" in ConString:
|
1201
|
+
match = re.match(r"^[A-Z]+:[^<>:]+<\d+>$", ConString, re.IGNORECASE)
|
1202
|
+
if match:
|
1203
|
+
controller_part = ConString.split('<')[0]
|
1204
|
+
if check_module_format(controller_part): # Recursive call
|
1205
|
+
return True
|
1206
|
+
else:
|
1207
|
+
logging.warning(f"Invalid controller part '{controller_part}' in '{ConString}'")
|
1208
|
+
else:
|
1209
|
+
logging.warning(f"Invalid sub-device syntax: '{ConString}'")
|
1210
|
+
# If sub-device checks failed, return False
|
545
1211
|
return False
|
1212
|
+
else:
|
1213
|
+
# Not a sub-device, check original strict colon count (1 or 2)
|
1214
|
+
if numb_colons > 2 or numb_colons <= 0:
|
1215
|
+
logging.warning(f"Invalid number of colons ({numb_colons}) in module string (expected 1 or 2).")
|
1216
|
+
logging.warning(f"Invalid connection string: {ConString}")
|
1217
|
+
return False
|
546
1218
|
|
1219
|
+
# Passed basic checks
|
547
1220
|
return True
|
548
1221
|
|
549
1222
|
|
550
|
-
|
551
|
-
|
1223
|
+
# Original checkModuleFormat function, kept for compatibility, now calls snake_case version
|
1224
|
+
def checkModuleFormat(ConString: str) -> bool:
|
1225
|
+
"""
|
1226
|
+
DEPRECATED - Use check_module_format instead.
|
1227
|
+
|
1228
|
+
Checks the basic validity of a connection string format.
|
1229
|
+
|
1230
|
+
Verifies presence of ':', checks against allowed connection types,
|
1231
|
+
and validates the number of colons or sub-device format.
|
1232
|
+
|
1233
|
+
Args:
|
1234
|
+
ConString (str): The connection string to validate.
|
1235
|
+
|
1236
|
+
Returns:
|
1237
|
+
bool: True if the format seems valid, False otherwise.
|
1238
|
+
|
1239
|
+
Note:
|
1240
|
+
Uses a specific list of allowed connection types defined within.
|
1241
|
+
May recursively call itself to validate controller part of sub-device strings.
|
1242
|
+
"""
|
1243
|
+
return check_module_format(ConString)
|
1244
|
+
|
1245
|
+
|
1246
|
+
# --- getQuarchDevice / get_quarch_device ---
|
1247
|
+
def get_quarch_device(connectionTarget: str, ConType: str = "PY", timeout: str = "5") -> 'Union[quarchDevice, subDevice]':
|
1248
|
+
"""
|
1249
|
+
Creates and returns a quarchDevice or subDevice instance.
|
1250
|
+
|
1251
|
+
Parses the connectionTarget, determines if it's a standard device or a
|
1252
|
+
sub-device (e.g., "TYPE:ID<PORT>"), and instantiates the appropriate
|
1253
|
+
quarchDevice or subDevice object via the quarchArray class if needed.h
|
1254
|
+
|
1255
|
+
Args:
|
1256
|
+
connectionTarget (str): The connection string for the target device
|
1257
|
+
or sub-device.
|
1258
|
+
ConType (str, optional): The connection type hint ('PY', 'QIS', 'QPS', etc.)
|
1259
|
+
used when creating the base quarchDevice instance if not a sub-device.
|
1260
|
+
Defaults to "PY". Note: For sub-devices, the controller connection
|
1261
|
+
currently defaults to "PY" internally based on original logic.
|
1262
|
+
timeout (str, optional): The connection timeout in seconds as a string.
|
1263
|
+
Defaults to "5".
|
1264
|
+
|
1265
|
+
Returns:
|
1266
|
+
quarchDevice | subDevice | Any: An instance representing the connected device.
|
1267
|
+
Type hinted as Any because subDevice type might vary.
|
1268
|
+
|
1269
|
+
Raises:
|
1270
|
+
ImportError: If quarchArray components are needed but not found.
|
1271
|
+
ValueError: If the connectionTarget format is invalid.
|
1272
|
+
ConnectionError: If connecting to the device or controller fails.
|
1273
|
+
RuntimeError: For other unexpected errors during connection/instantiation.
|
1274
|
+
"""
|
1275
|
+
# Import quarchArray
|
552
1276
|
from .quarchArray import quarchArray
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
1277
|
+
|
1278
|
+
# Original check for sub-device format using __contains__
|
1279
|
+
if isinstance(connectionTarget, str) and connectionTarget.__contains__("<") and connectionTarget.__contains__(">"):
|
1280
|
+
logging.debug(f"Detected sub-device format for {connectionTarget}")
|
1281
|
+
myDevice = None # Ensure defined in this scope
|
1282
|
+
myArrayController = None # Ensure defined
|
1283
|
+
try:
|
1284
|
+
controller_target_str, portNumberPart = connectionTarget.split("<")
|
1285
|
+
portNumberStr = portNumberPart[:-1] # Remove '>'
|
1286
|
+
|
1287
|
+
# Validate port number
|
1288
|
+
if not portNumberStr.isdigit():
|
1289
|
+
raise ValueError(f"Invalid port number '{portNumberStr}' in sub-device string")
|
1290
|
+
portNumber = int(portNumberStr)
|
1291
|
+
|
1292
|
+
# Validate controller part using the wrapper function (internal call)
|
1293
|
+
if not check_module_format(controller_target_str):
|
1294
|
+
raise ValueError(f"Invalid controller part format: '{controller_target_str}'")
|
1295
|
+
|
1296
|
+
logging.debug(f"Connecting to controller '{controller_target_str}' first...")
|
1297
|
+
myDeviceBase = quarchDevice(controller_target_str, ConType="PY", timeout=timeout)
|
1298
|
+
|
1299
|
+
logging.debug("Wrapping controller device with quarchArray...")
|
1300
|
+
myArrayController = quarchArray(myDeviceBase)
|
1301
|
+
|
1302
|
+
logging.debug(f"Getting subDevice for port {portNumber}...")
|
1303
|
+
mySubDevice = myArrayController.getSubDevice(portNumber)
|
1304
|
+
|
1305
|
+
myDevice = mySubDevice # Return the subDevice instance
|
1306
|
+
logging.info(f"Successfully connected to sub-device: {connectionTarget}")
|
1307
|
+
except (ImportError, ValueError, ConnectionError, RuntimeError) as e_device_error:
|
1308
|
+
# Catch specific known errors and re-raise
|
1309
|
+
logging.error(f"Failed to get sub-device '{connectionTarget}': {e_device_error}", exc_info=True)
|
1310
|
+
raise # Re-raise the caught exception
|
1311
|
+
except Exception as e_device_error:
|
1312
|
+
# Catch any other unexpected errors
|
1313
|
+
logging.error(f"Unexpected error getting sub-device '{connectionTarget}': {e_device_error}", exc_info=True)
|
1314
|
+
# Wrap in RuntimeError
|
1315
|
+
raise RuntimeError(f"Unexpected error getting sub-device '{connectionTarget}'") from e_device_error
|
1316
|
+
|
560
1317
|
else:
|
1318
|
+
# Standard device connection
|
1319
|
+
logging.debug(f"Standard device connection for: {connectionTarget}")
|
1320
|
+
# Use passed ConType and timeout
|
561
1321
|
myDevice = quarchDevice(connectionTarget, ConType=ConType, timeout=timeout)
|
562
|
-
|
1322
|
+
logging.info(f"Successfully connected to standard device: {connectionTarget}")
|
1323
|
+
|
1324
|
+
return myDevice
|
1325
|
+
|
1326
|
+
|
1327
|
+
# Original getQuarchDevice function, kept for compatibility, now calls snake_case version
|
1328
|
+
def getQuarchDevice(connectionTarget: str, ConType: str = "PY", timeout: str = "5") -> 'Union[quarchDevice, subDevice]':
|
1329
|
+
"""
|
1330
|
+
DEPRECATED - Use get_quarch_device instead.
|
1331
|
+
|
1332
|
+
Creates and returns a quarchDevice or subDevice instance.
|
1333
|
+
|
1334
|
+
Parses the connectionTarget, determines if it's a standard device or a
|
1335
|
+
sub-device (e.g., "TYPE:ID<PORT>"), and instantiates the appropriate
|
1336
|
+
quarchDevice or subDevice object via the quarchArray class if needed.
|
1337
|
+
|
1338
|
+
Args:
|
1339
|
+
connectionTarget (str): The connection string for the target device
|
1340
|
+
or sub-device.
|
1341
|
+
ConType (str, optional): The connection type hint ('PY', 'QIS', 'QPS', etc.)
|
1342
|
+
used when creating the base quarchDevice instance if not a sub-device.
|
1343
|
+
Defaults to "PY". Note: For sub-devices, the controller connection
|
1344
|
+
currently defaults to "PY" internally based on original logic.
|
1345
|
+
timeout (str, optional): The connection timeout in seconds as a string.
|
1346
|
+
Defaults to "5".
|
1347
|
+
|
1348
|
+
Returns:
|
1349
|
+
quarchDevice | subDevice | Any: An instance representing the connected device.
|
1350
|
+
Type hinted as Any because subDevice type might vary.
|
1351
|
+
|
1352
|
+
Raises:
|
1353
|
+
ImportError: If quarchArray components are needed but not found.
|
1354
|
+
ValueError: If the connectionTarget format is invalid.
|
1355
|
+
ConnectionError: If connecting to the device or controller fails.
|
1356
|
+
RuntimeError: For other unexpected errors during connection/instantiation.
|
1357
|
+
"""
|
1358
|
+
return get_quarch_device(connectionTarget, ConType, timeout)
|