slm-open-api-package 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/PKG-INFO +2 -1
  2. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/pyproject.toml +2 -1
  3. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/pyproject.toml.orig +32 -31
  4. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/CPB_example.py +4 -2
  5. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/example_multi.py +3 -0
  6. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/fast_log_example.py +1 -0
  7. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/Leq.py +8 -8
  8. slm_open_api_package-0.2.2/src/slm_api/helpers/https_requests.py +69 -0
  9. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/measurment_handler.py +5 -6
  10. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/sequence_handler.py +3 -4
  11. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/stream_handler.py +4 -5
  12. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/stream_handlers.py +6 -7
  13. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/webxi_helper_functions.py +27 -16
  14. slm_open_api_package-0.2.2/src/slm_api/helpers/webxi_root.pem +24 -0
  15. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/README.md +0 -0
  16. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/__init__.py +0 -0
  17. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/enums/fast_log_intervals_enum.py +0 -0
  18. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/enums/sequence_id_enum.py +0 -0
  19. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/flac_example.py +0 -0
  20. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/FigureHandler.py +0 -0
  21. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/__init__.py +0 -0
  22. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/buffer.py +0 -0
  23. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/data_handler.py +0 -0
  24. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/fft.py +0 -0
  25. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/flac_stream_2_samples.py +0 -0
  26. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/tmpFileStateMachine.py +0 -0
  27. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/helpers/websocket_handler.py +0 -0
  28. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/mp3_example.py +0 -0
  29. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/screen_record_example.py +0 -0
  30. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/webxi/README.md +0 -0
  31. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/webxi/__init__.py +0 -0
  32. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/webxi/webxi-header.ksy +0 -0
  33. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/webxi/webxi-stream.ksy +0 -0
  34. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/webxi/webxi_header.py +0 -0
  35. {slm_open_api_package-0.2.0 → slm_open_api_package-0.2.2}/src/slm_api/webxi/webxi_stream.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: slm_open_api_package
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Add your description here
5
5
  Author: Sofus Vingaard
6
6
  Author-email: Sofus Vingaard <sofus.krebsvingaard@hbkworld.com>
@@ -14,6 +14,7 @@ Requires-Dist: pyqt5
14
14
  Requires-Dist: pyqt5-qt5<5.15.11
15
15
  Requires-Dist: miniaudio
16
16
  Requires-Dist: matplotlib>=3.11.1
17
+ Requires-Dist: cryptography>=50.0.1
17
18
  Requires-Python: >=3.12
18
19
  Description-Content-Type: text/markdown
19
20
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "slm_open_api_package"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -15,6 +15,7 @@ dependencies = [
15
15
  "PyQt5-Qt5<5.15.11",
16
16
  "miniaudio",
17
17
  "matplotlib>=3.11.1",
18
+ "cryptography>=50.0.1",
18
19
  ]
19
20
 
20
21
  [[project.authors]]
@@ -1,31 +1,32 @@
1
- [project]
2
- name = "slm_open_api_package"
3
- version = "0.2.0"
4
- description = "Add your description here"
5
- readme = "README.md"
6
- authors = [
7
- { name = "Sofus Vingaard", email = "sofus.krebsvingaard@hbkworld.com" }
8
- ]
9
- requires-python = ">=3.12"
10
- dependencies = [
11
- "requests",
12
- "numpy",
13
- "websockets",
14
- "kaitaistruct",
15
- "packaging",
16
- "pyqtgraph",
17
- "PyQt5",
18
- "PyQt5-Qt5<5.15.11",
19
- "miniaudio",
20
- "matplotlib>=3.11.1",
21
- ]
22
-
23
- [project.scripts]
24
- open-api-package = "slm_api:main"
25
-
26
- [tool.uv.build-backend]
27
- module-name = "slm_api"
28
-
29
- [build-system]
30
- requires = ["uv_build>=0.12.5,<0.13.0"]
31
- build-backend = "uv_build"
1
+ [project]
2
+ name = "slm_open_api_package"
3
+ version = "0.2.2"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Sofus Vingaard", email = "sofus.krebsvingaard@hbkworld.com" }
8
+ ]
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "requests",
12
+ "numpy",
13
+ "websockets",
14
+ "kaitaistruct",
15
+ "packaging",
16
+ "pyqtgraph",
17
+ "PyQt5",
18
+ "PyQt5-Qt5<5.15.11",
19
+ "miniaudio",
20
+ "matplotlib>=3.11.1",
21
+ "cryptography>=50.0.1",
22
+ ]
23
+
24
+ [project.scripts]
25
+ open-api-package = "slm_api:main"
26
+
27
+ [tool.uv.build-backend]
28
+ module-name = "slm_api"
29
+
30
+ [build-system]
31
+ requires = ["uv_build>=0.12.5,<0.13.0"]
32
+ build-backend = "uv_build"
@@ -10,7 +10,9 @@ from slm_api.helpers.data_handler import CsvDataHandler,PickleDataHandler,JsonDa
10
10
 
11
11
 
12
12
  host, ip = webxi_helper.set_host_ip(__file__)
13
- sequence_names = ["CPBLAeq"]
13
+ sequence_names = ["LAeq"]
14
+ cpb_sequence_names = ["CPBLAeq"]
15
+
14
16
 
15
17
  sequenceID= SequenceIdEnums.CPBLAeq.value
16
18
 
@@ -60,7 +62,7 @@ if __name__ == "__main__":
60
62
  streamer = WebXiStreamHandler(host, ip,
61
63
  sequenceID=sequenceID,
62
64
  cpb=True,
63
- sequenceNames=sequence_names,
65
+ sequenceNames=cpb_sequence_names,
64
66
  saving_path=r"./saved_data/test_file",
65
67
  saving="json")
66
68
  # streamer.setDataHandler(JsonDataHandler(r"C:\Users\SKREBSVINGAA\csv_test\csv_test.txt"))
@@ -20,6 +20,9 @@ from slm_api.helpers import websocket_handler as webSocket # Async functions
20
20
  from slm_api.helpers import webxi_helper_functions as webxi_helper
21
21
  from slm_api.helpers import stream_handlers as sh
22
22
  from slm_api.helpers.data_handler import DataHandler
23
+ from slm_api.helpers.https_requests import UseHttps
24
+
25
+ UseHttps(use_https=False)
23
26
 
24
27
  host, ip = webxi_helper.set_host_ip(__file__)
25
28
 
@@ -150,6 +150,7 @@ class PrintDataHandler(DataHandler):
150
150
 
151
151
 
152
152
  if __name__ == "__main__":
153
+
153
154
  try:
154
155
  streamer = WebXiStreamHandler(host,
155
156
  ip,
@@ -1,19 +1,19 @@
1
1
  import numpy as np
2
- import requests
2
+ from . import https_requests
3
3
 
4
4
 
5
5
  def SLM_Setup_LAeq(host):
6
6
  # Enable logging mode
7
- requests.put(host + "/webxi/Applications/SLM/Setup/ControlLoggingMode", json=1)
7
+ https_requests.put(host, "/webxi/Applications/SLM/Setup/ControlLoggingMode", json=1)
8
8
  # Set the device in free runnign mode
9
- requests.put(host + "/webxi/Applications/SLM/Setup/ControlMeasurementTimeControl", json=0)
9
+ https_requests.put(host, "/webxi/Applications/SLM/Setup/ControlMeasurementTimeControl", json=0)
10
10
  # Enable A weight frequency broad band weighting, but first clear the other once to be sure
11
- requests.put(host + "/webxi/Applications/SLM/Setup/BBFreqWeightB", json=False)
12
- requests.put(host + "/webxi/Applications/SLM/Setup/BBFreqWeightC", json=False)
13
- requests.put(host + "/webxi/Applications/SLM/Setup/BBFreqWeightZ", json=False)
14
- requests.put(host + "/webxi/Applications/SLM/Setup/BBFreqWeightA", json=True)
11
+ https_requests.put(host, "/webxi/Applications/SLM/Setup/BBFreqWeightB", json=False)
12
+ https_requests.put(host, "/webxi/Applications/SLM/Setup/BBFreqWeightC", json=False)
13
+ https_requests.put(host, "/webxi/Applications/SLM/Setup/BBFreqWeightZ", json=False)
14
+ https_requests.put(host, "/webxi/Applications/SLM/Setup/BBFreqWeightA", json=True)
15
15
  # Enable LAeq mode on the device
16
- requests.put(host + "/webxi/applications/slm/setup/BBLAeq", json=True)
16
+ https_requests.put(host, "/webxi/applications/slm/setup/BBLAeq", json=True)
17
17
 
18
18
  class MovingLeq:
19
19
  """Class to create a moving Leq object.\n
@@ -0,0 +1,69 @@
1
+ import ssl
2
+ import requests
3
+ from pathlib import Path
4
+ from requests.adapters import HTTPAdapter
5
+
6
+ _CERT_FILE = Path(__file__).resolve().parent / "webxi_root.pem"
7
+
8
+
9
+ class WebxiAdapter(HTTPAdapter):
10
+ """Trusts only webxi_root.pem; skips hostname check since device certs are per-serial, not per-IP."""
11
+
12
+ def init_poolmanager(self, *args, **kwargs):
13
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
14
+ ctx.load_verify_locations(cafile=str(_CERT_FILE))
15
+ ctx.check_hostname = False
16
+ ctx.verify_mode = ssl.CERT_REQUIRED
17
+ kwargs["ssl_context"] = ctx
18
+ kwargs["assert_hostname"] = False # urllib3 does its own SAN check independent of ssl_context.check_hostname
19
+ return super().init_poolmanager(*args, **kwargs)
20
+
21
+
22
+ _session = requests.Session()
23
+ if _CERT_FILE.is_file():
24
+ _session.mount("https://", WebxiAdapter())
25
+
26
+ class UseHttps:
27
+ use_https = True # class attribute: shared, module-wide default
28
+
29
+ def __init__(self, use_https=None):
30
+ if use_https is not None:
31
+ UseHttps.use_https = use_https
32
+
33
+ def request(self, method, host, endpoint, **kwargs):
34
+ """Send a request to the SLM. HTTPS calls are verified against webxi_root.pem via WebxiAdapter."""
35
+ if UseHttps.use_https:
36
+ if host.startswith("http://"):
37
+ stripped_host = host.removeprefix("http://")
38
+ url = f"https://{stripped_host}{endpoint}"
39
+ elif host.startswith("https://"):
40
+ url = host + endpoint
41
+ else:
42
+ url = f"https://{host}{endpoint}"
43
+ else:
44
+ stripped_host = host.removeprefix("https://").removeprefix("http://")
45
+ url = f"http://{stripped_host}{endpoint}"
46
+
47
+ kwargs.setdefault("timeout", 10)
48
+ kwargs.setdefault("verify", str(_CERT_FILE))
49
+
50
+ # print(f"[https_requests] {method} {url}")
51
+ response = _session.request(method, url, **kwargs)
52
+ response.raise_for_status()
53
+ return response
54
+
55
+
56
+ def get(host, endpoint, **kwargs):
57
+ return UseHttps().request("GET", host, endpoint, **kwargs)
58
+
59
+
60
+ def put(host, endpoint, **kwargs):
61
+ return UseHttps().request("PUT", host, endpoint, **kwargs)
62
+
63
+
64
+ def post(host, endpoint, **kwargs):
65
+ return UseHttps().request("POST", host, endpoint, **kwargs)
66
+
67
+
68
+ def delete(host, endpoint, **kwargs):
69
+ return UseHttps().request("DELETE", host, endpoint, **kwargs)
@@ -1,20 +1,19 @@
1
- import requests
2
- from requests.auth import HTTPDigestAuth
1
+ from . import https_requests
3
2
 
4
3
  def start_pause_measurement(hostID,start):
5
4
  """This function starts or pause a measurement.
6
5
  If trying to start a measurement and the device is already running
7
6
  will this function do nothing, same for pause."""
8
- response = requests.get(hostID + "/webxi/Applications/SLM/State")
7
+ response = https_requests.get(hostID, "/webxi/Applications/SLM/State")
9
8
  print(response.json())
10
9
  if start and response.json() != "Running":
11
- response = requests.put(hostID + "/WebXi/Applications/SLM?Action=StartPause")
10
+ response = https_requests.put(hostID, "/WebXi/Applications/SLM?Action=StartPause")
12
11
  assert(response.status_code == 200)
13
12
  elif not start and response.json() == "Running":
14
- response = requests.put(hostID + "/WebXi/Applications/SLM?Action=StartPause")
13
+ response = https_requests.put(hostID, "/WebXi/Applications/SLM?Action=StartPause")
15
14
  assert(response.status_code == 200)
16
15
 
17
16
  def stop_measurement(hostID):
18
17
  """Stop a measurement on the device"""
19
- response = requests.put(hostID + "/WebXi/Applications/SLM?Action=Stop")
18
+ response = https_requests.put(hostID, "/WebXi/Applications/SLM?Action=Stop")
20
19
  assert(response.status_code == 200)
@@ -1,5 +1,4 @@
1
- import requests
2
- from requests.auth import HTTPDigestAuth
1
+ from . import https_requests
3
2
 
4
3
  def find_sequence(sequenceId, sequences):
5
4
  """Iterations through the different sequences on the device to find the wanted one"""
@@ -27,13 +26,13 @@ def find_sequence_by_name(sequenceName, sequences):
27
26
  return test
28
27
 
29
28
  def getSequenceID(host, sequenceName):
30
- sequences = requests.get(host + "/webxi/sequences?recursive").json()
29
+ sequences = https_requests.get(host, "/webxi/sequences?recursive").json()
31
30
  return find_sequence_by_name(sequenceName, sequences)
32
31
 
33
32
 
34
33
  def get_sequence(hostID,ID):
35
34
  """This function checks if the ID exists"""
36
- response = requests.get(hostID + "/webxi/sequences?recursive")
35
+ response = https_requests.get(hostID, "/webxi/sequences?recursive")
37
36
  sequences = response.json()
38
37
  sequence = find_sequence(ID, sequences)
39
38
  if sequence == None:
@@ -1,5 +1,4 @@
1
- import requests
2
- from requests.auth import HTTPDigestAuth
1
+ from . import https_requests
3
2
  import asyncio
4
3
  from . import websocket_handler
5
4
  from . import measurment_handler
@@ -16,7 +15,7 @@ def setup_stream(host,ip,sequenceID,StreamName):
16
15
  "MessageTypes": ["SequenceData"],
17
16
  "Name": StreamName
18
17
  }
19
- response = requests.post(host + "/WebXi/Streams", json = body)
18
+ response = https_requests.post(host, "/WebXi/Streams", json = body)
20
19
  print(response)
21
20
  if not (response.status_code == 201):
22
21
  print(response.text)
@@ -25,7 +24,7 @@ def setup_stream(host,ip,sequenceID,StreamName):
25
24
 
26
25
  def get_stream_ID(host, streamName):
27
26
  """This function shows how to find the ID of a specific stream with specific name"""
28
- streams = requests.get(host + "/WebXi/Streams?recursive").json()
27
+ streams = https_requests.get(host, "/WebXi/Streams?recursive").json()
29
28
  # The keys are the stream IDs and are not renumbered when a stream is deleted
30
29
  matches = [int(ID) for ID, subtree in streams.items() if subtree["Name"] == streamName]
31
30
  return max(matches) if matches else None
@@ -34,7 +33,7 @@ def delete_stream(host, streamName):
34
33
  """Look up a stream by name and delete it, cleaning up the device resources used"""
35
34
  streamID = get_stream_ID(host, streamName)
36
35
  if streamID is not None:
37
- response = requests.delete(host + "/WebXi/Streams/" + str(streamID), timeout=10)
36
+ response = https_requests.delete(host, "/WebXi/Streams/" + str(streamID), timeout=10)
38
37
  response.raise_for_status()
39
38
 
40
39
  def data_type_conv(data_type, value, vector_length):
@@ -2,7 +2,7 @@
2
2
  cases (single Leq sequence, CPB, multiple sequences, FLAC/mp3 audio). The mode
3
3
  is picked with boolean flags (cpb, multi, flac, mp3) instead of subclassing."""
4
4
 
5
- import requests
5
+ from . import https_requests
6
6
  import time
7
7
  import re
8
8
  from datetime import datetime
@@ -48,7 +48,7 @@ def _webxi_time_to_epoch(header_time):
48
48
 
49
49
  def _get_fast_logging_interval_s(host):
50
50
  """Read the configured broadband fast-logging interval and return it in seconds."""
51
- enum = requests.get(f"{host}/WebXi/Applications/SLM/Setup/ControlBBFastLoggingInterval").json()
51
+ enum = https_requests.get(host, "/WebXi/Applications/SLM/Setup/ControlBBFastLoggingInterval").json()
52
52
  if enum not in _FAST_LOGGING_INTERVAL_MS:
53
53
  raise ValueError(f"Unexpected ControlBBFastLoggingInterval value: {enum!r}")
54
54
  return _FAST_LOGGING_INTERVAL_MS[enum] / 1000.0
@@ -58,14 +58,14 @@ def _set_fast_logging_interval(host, enum_value):
58
58
  """Configure the device's broadband fast-logging interval from an enum index (0-10)."""
59
59
  if enum_value not in _FAST_LOGGING_INTERVAL_MS:
60
60
  raise ValueError(f"Invalid ControlBBFastLoggingInterval enum: {enum_value!r}, must be one of {sorted(_FAST_LOGGING_INTERVAL_MS)}")
61
- response = requests.put(f"{host}/WebXi/Applications/SLM/Setup/ControlBBFastLoggingInterval", json=enum_value)
61
+ response = https_requests.put(host, "/WebXi/Applications/SLM/Setup/ControlBBFastLoggingInterval", json=enum_value)
62
62
  response.raise_for_status()
63
63
 
64
64
 
65
65
  def _get_slm_utc_offset_seconds(host):
66
66
  """Read the SLM's own configured time zone offset from UTC, in seconds.
67
67
  The device reports it as a string like 'GMT+02:00'."""
68
- response = requests.get(f"{host}/WebXi/Applications/SLM/Outputs/TimeZone")
68
+ response = https_requests.get(host, "/WebXi/Applications/SLM/Outputs/TimeZone")
69
69
  response.raise_for_status()
70
70
  value = str(response.json()).strip()
71
71
  match = re.search(r"([+-])(\d{2}):?(\d{2})", value)
@@ -181,7 +181,7 @@ class WebXiStreamHandler(stream.StreamHandler):
181
181
 
182
182
  def get_calibration_factor(self):
183
183
  # Calculate calibration factor from the microphone sensitivity
184
- response = requests.get(f"{self.host}/WebXi/Applications/SLM/Outputs/Sensitivity")
184
+ response = https_requests.get(self.host, "/WebXi/Applications/SLM/Outputs/Sensitivity")
185
185
  assert response.status_code == 200
186
186
  mic_sens = float(response.text) # V/Pa
187
187
  max_lvl = 20 * np.log10((self.max_input / mic_sens) / 20e-6) # dB SPL re 20 uPa
@@ -190,7 +190,7 @@ class WebXiStreamHandler(stream.StreamHandler):
190
190
  def streamInit(self):
191
191
  if self.mp3 or self.flac:
192
192
  quality_setting = "AudioRecordingListenQuality" if self.mp3 else "AudioRecordingAnalysisQuality"
193
- response = requests.put(f"{self.host}/WebXi/Applications/SLM/setup/{quality_setting}", json=1)
193
+ response = https_requests.put(self.host, f"/WebXi/Applications/SLM/setup/{quality_setting}", json=1)
194
194
  assert response.status_code == 200
195
195
  self.get_calibration_factor()
196
196
  self.ID, self.sequence = seq.get_sequence(self.host, self.sequenceID)
@@ -226,7 +226,6 @@ class WebXiStreamHandler(stream.StreamHandler):
226
226
  elif self.screen_record:
227
227
  self.ID, self.sequence = seq.get_sequence(self.host, seq.getSequenceID(self.host, "ScreenImage"))
228
228
  else:
229
- SLM_Setup_LAeq(self.host)
230
229
  self.ID, self.sequence = seq.get_sequence(self.host, self.sequenceID)
231
230
  self.data_type = self.sequence["DataType"]
232
231
  self.leq_mov = MovingLeq(self.leq_window_sec, storedata=True)
@@ -1,9 +1,9 @@
1
1
  import requests
2
2
  from pathlib import Path
3
+ from slm_api.helpers.https_requests import get, put
3
4
 
4
5
  # Reuse one connection to the device instead of opening a new TCP connection per
5
6
  # request — some devices take multiple seconds to accept a brand-new connection.
6
- _session = requests.Session()
7
7
 
8
8
  # Functions to turn on/off BB freq weights and sequences. These are used in the examples to make sure the wanted sequences are enabled on the SLM.
9
9
  def turn_off_bb_freq_weight(host):
@@ -13,31 +13,42 @@ def turn_off_bb_freq_weight(host):
13
13
  "/webxi/Applications/SLM/Setup/BBFreqWeightA",
14
14
  "/webxi/Applications/SLM/Setup/BBFreqWeightC",
15
15
  ):
16
- response = _session.put(host + endpoint, json=False, timeout=10)
17
- response.raise_for_status()
16
+ put(host , endpoint, json=False, timeout=10)
18
17
 
19
- def turn_on_bb_freq_weight(host, weights):
20
- for weight in weights:
21
- _session.put(host + f"/webxi/Applications/SLM/Setup/BBFreqWeight{weight}", json=True)
18
+ def turn_on_bb_freq_weight(host, weights, fast=False):
19
+ weights = [weights] if isinstance(weights, str) else weights
20
+ if not fast:
21
+ for weight in weights:
22
+ put(host , f"/webxi/Applications/SLM/Setup/BBFreqWeight{weight}", json=True)
23
+ else:
24
+ for weight in weights:
25
+ put(host , f"/webxi/Applications/SLM/Setup/FastBBFreqWeight{weight}", json=True)
22
26
 
23
- def turn_on_bb_leq(host, weights):
24
- for weight in weights:
25
- _session.put(host + f"/webxi/Applications/SLM/Setup/BB{weight}", json=True)
27
+ def turn_on_bb_leq(host, weights, fast=False):
28
+ weights = [weights] if isinstance(weights, str) else weights
29
+ if not fast:
30
+ for weight in weights:
31
+ put(host, f"/webxi/Applications/SLM/Setup/BB{weight}", json=True)
32
+ else:
33
+ for weight in weights:
34
+ put(host, f"/webxi/Applications/SLM/Setup/FastBB{weight}", json=True)
26
35
 
27
36
 
28
37
  def turn_off_CPB_freq_weight(host):
29
- _session.put(host + "/webxi/Applications/SLM/Setup/CPBFreqWeightB", json=False)
30
- _session.put(host + "/webxi/Applications/SLM/Setup/CPBFreqWeightZ", json=False)
31
- _session.put(host + "/webxi/Applications/SLM/Setup/CPBFreqWeightA", json=False)
32
- _session.put(host + "/webxi/Applications/SLM/Setup/CPBFreqWeightC", json=False)
38
+ put(host , "/webxi/Applications/SLM/Setup/CPBFreqWeightB", json=False)
39
+ put(host , "/webxi/Applications/SLM/Setup/CPBFreqWeightZ", json=False)
40
+ put(host , "/webxi/Applications/SLM/Setup/CPBFreqWeightA", json=False)
41
+ put(host , "/webxi/Applications/SLM/Setup/CPBFreqWeightC", json=False)
33
42
 
34
43
  def turn_on_CPB_freq_weight(host, weights):
44
+ weights = [weights] if isinstance(weights, str) else weights
35
45
  for weight in weights:
36
- _session.put(host + f"/webxi/Applications/SLM/Setup/CPBFreqWeight{weight}", json=True)
46
+ put(host , f"/webxi/Applications/SLM/Setup/CPBFreqWeight{weight}", json=True)
37
47
 
38
48
  def turn_on_cpb_leq(host, weights):
49
+ weights = [weights] if isinstance(weights, str) else weights
39
50
  for weight in weights:
40
- _session.put(host + f"/webxi/Applications/SLM/Setup/CPB{weight}", json=True)
51
+ put(host , f"/webxi/Applications/SLM/Setup/{weight}", json=True)
41
52
 
42
53
 
43
54
  def _find_ip_file(caller_file=None):
@@ -46,7 +57,7 @@ def _find_ip_file(caller_file=None):
46
57
  for directory in (start, *start.parents):
47
58
  if (directory / "slm_ip").is_file():
48
59
  return directory / "slm_ip"
49
- if (directory / "pyproject.toml").is_file() or (directory / ".git").exists():
60
+ if (directory / "pyproject.toml").is_file() or (directory / ".git").exists() or (directory / "requirements.txt").is_file():
50
61
  return directory / "slm_ip"
51
62
  return start / "slm_ip"
52
63
 
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEBTCCAu2gAwIBAgIJAPJZCza59BhGMA0GCSqGSIb3DQEBCwUAMIGYMQswCQYD
3
+ VQQGEwJVSzEPMA0GA1UECAwGU3VycmV5MQ4wDAYDVQQHDAVFZ2hhbTEVMBMGA1UE
4
+ CgwMU3BlY3RyaXMgcGxjMRgwFgYDVQQLDA9JbnN0cnVtZW50YXRpb24xDzANBgNV
5
+ BAMMBndlYi14aTEmMCQGCSqGSIb3DQEJARYXQ2Fyc3Rlbi5IYW5zZW5AYmtzdi5j
6
+ b20wHhcNMTgxMjE5MTQ1MzM4WhcNNDgxMjExMTQ1MzM4WjCBmDELMAkGA1UEBhMC
7
+ VUsxDzANBgNVBAgMBlN1cnJleTEOMAwGA1UEBwwFRWdoYW0xFTATBgNVBAoMDFNw
8
+ ZWN0cmlzIHBsYzEYMBYGA1UECwwPSW5zdHJ1bWVudGF0aW9uMQ8wDQYDVQQDDAZ3
9
+ ZWIteGkxJjAkBgkqhkiG9w0BCQEWF0NhcnN0ZW4uSGFuc2VuQGJrc3YuY29tMIIB
10
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwBbiEL0V2VF7gVzRPb45pkJ/
11
+ Uip84zS6MWgyCUWUuqYLSlpoLkfbsVPK7JUPUfUlhw4KjYFd7M6jra98hkqPaap8
12
+ ybeCmu3o6m4zfP0cbQD3QCEjPDNVy8fLP08D1mF3C3ksoIhGgv/0OdIC5/mJ0CEB
13
+ RBnr4xk8Sy7wa4TEOkH1eRtOvYQyKDGEBWcuWJER5fKhBn5ZdKta1ts78ELMy/8i
14
+ MXXtKbPxR9ZMPuqQmeYkcT9CEDVMSYoCV4Yov7Edi6JZNp6U6hqYx8UxHtl7ljTt
15
+ aOnICI+ACcvYWKgsBZcdl4ZQ0VUTDa3FD2zUI63Sx5U2/th1ChZoRjApx0BwpwID
16
+ AQABo1AwTjAdBgNVHQ4EFgQUMpXkaVWWnTSjYLF8UHwCvWRxMyowHwYDVR0jBBgw
17
+ FoAUMpXkaVWWnTSjYLF8UHwCvWRxMyowDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
18
+ AQsFAAOCAQEAKcbCeH+WzWiXo5xWemVz/YLq3X/QJKB4UQgbyuXWItOjMvXGP0gi
19
+ owEY8s4y/YPGhl0R3lHFz2yLHRX0Vc+LzAB/8ob0Q0nKNttqnE3ofgZhpzUcGxVI
20
+ Yb2CpvHHdU4TXDYdLT4pkCb6+8pqlnOyRBBlJNvO5gKMSSvxcStVLp+2CwPhtex3
21
+ u43FzdRvC3kp0MmW1PCZgm5LqVh1IEx2TBiy9/7W5IAoSIh0bE+fGWi7NfcgZsv1
22
+ 2ZmKe/6p2vbHbarBTiOgD3GISr47+yhjN8Qd4eYPRLswZDHwkEDTW+TUvCmgbAfa
23
+ 3WCwBk4+GVXcGL/yIEWaSAIZbgAq03JsYA==
24
+ -----END CERTIFICATE-----