slm-open-api-package 0.2.2__tar.gz → 0.2.4__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 (38) hide show
  1. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/PKG-INFO +1 -1
  2. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/pyproject.toml +1 -1
  3. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/pyproject.toml.orig +1 -1
  4. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/example_multi.py +1 -1
  5. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/flac_example.py +0 -1
  6. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/https_requests.py +10 -0
  7. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/measurment_handler.py +1 -0
  8. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/stream_handler.py +7 -2
  9. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/stream_handlers.py +47 -2
  10. slm_open_api_package-0.2.4/src/slm_api/helpers/websocket_handler.py +12 -0
  11. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/webxi_helper_functions.py +5 -1
  12. slm_open_api_package-0.2.4/src/slm_api/multi_device_flac.py +155 -0
  13. slm_open_api_package-0.2.4/src/slm_api/multi_instrument_example.py +75 -0
  14. slm_open_api_package-0.2.2/src/slm_api/helpers/websocket_handler.py +0 -8
  15. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/README.md +0 -0
  16. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/CPB_example.py +0 -0
  17. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/__init__.py +0 -0
  18. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/enums/fast_log_intervals_enum.py +0 -0
  19. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/enums/sequence_id_enum.py +0 -0
  20. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/fast_log_example.py +0 -0
  21. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/FigureHandler.py +0 -0
  22. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/Leq.py +0 -0
  23. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/__init__.py +0 -0
  24. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/buffer.py +0 -0
  25. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/data_handler.py +0 -0
  26. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/fft.py +0 -0
  27. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/flac_stream_2_samples.py +0 -0
  28. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/sequence_handler.py +0 -0
  29. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/tmpFileStateMachine.py +0 -0
  30. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/helpers/webxi_root.pem +0 -0
  31. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/mp3_example.py +0 -0
  32. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/screen_record_example.py +0 -0
  33. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/webxi/README.md +0 -0
  34. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/webxi/__init__.py +0 -0
  35. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/webxi/webxi-header.ksy +0 -0
  36. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/webxi/webxi-stream.ksy +0 -0
  37. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/src/slm_api/webxi/webxi_header.py +0 -0
  38. {slm_open_api_package-0.2.2 → slm_open_api_package-0.2.4}/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.2
3
+ Version: 0.2.4
4
4
  Summary: Add your description here
5
5
  Author: Sofus Vingaard
6
6
  Author-email: Sofus Vingaard <sofus.krebsvingaard@hbkworld.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "slm_open_api_package"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "slm_open_api_package"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -22,7 +22,7 @@ from slm_api.helpers import stream_handlers as sh
22
22
  from slm_api.helpers.data_handler import DataHandler
23
23
  from slm_api.helpers.https_requests import UseHttps
24
24
 
25
- UseHttps(use_https=False)
25
+ # UseHttps(use_https=False)
26
26
 
27
27
  host, ip = webxi_helper.set_host_ip(__file__)
28
28
 
@@ -151,7 +151,6 @@ class figureHandler(FigureHandler):
151
151
 
152
152
  def on_close():
153
153
  streamer.stopStream()
154
- meas.stop_measurement()
155
154
 
156
155
  if __name__ == "__main__":
157
156
  # streamer = streamHandler()
@@ -18,6 +18,14 @@ class WebxiAdapter(HTTPAdapter):
18
18
  kwargs["assert_hostname"] = False # urllib3 does its own SAN check independent of ssl_context.check_hostname
19
19
  return super().init_poolmanager(*args, **kwargs)
20
20
 
21
+ def build_ssl_context():
22
+ """SSLContext trusting only webxi_root.pem, with hostname checking disabled."""
23
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
24
+ ctx.load_verify_locations(cafile=str(_CERT_FILE))
25
+ ctx.check_hostname = False
26
+ ctx.verify_mode = ssl.CERT_REQUIRED
27
+ return ctx
28
+
21
29
 
22
30
  _session = requests.Session()
23
31
  if _CERT_FILE.is_file():
@@ -26,6 +34,8 @@ if _CERT_FILE.is_file():
26
34
  class UseHttps:
27
35
  use_https = True # class attribute: shared, module-wide default
28
36
 
37
+
38
+
29
39
  def __init__(self, use_https=None):
30
40
  if use_https is not None:
31
41
  UseHttps.use_https = use_https
@@ -17,3 +17,4 @@ def stop_measurement(hostID):
17
17
  """Stop a measurement on the device"""
18
18
  response = https_requests.put(hostID, "/WebXi/Applications/SLM?Action=Stop")
19
19
  assert(response.status_code == 200)
20
+
@@ -20,8 +20,12 @@ def setup_stream(host,ip,sequenceID,StreamName):
20
20
  if not (response.status_code == 201):
21
21
  print(response.text)
22
22
  raise Exception("Cannot start stream, could be bacause of to many streams open on the device")
23
- return 'ws://' + ip + response.json()["URI"][0]
24
-
23
+ https = https_requests.UseHttps.use_https
24
+ if https:
25
+ return 'wss://' + ip + response.json()["URI"][0]
26
+ else:
27
+ return 'ws://' + ip + response.json()["URI"][0]
28
+
25
29
  def get_stream_ID(host, streamName):
26
30
  """This function shows how to find the ID of a specific stream with specific name"""
27
31
  streams = https_requests.get(host, "/WebXi/Streams?recursive").json()
@@ -75,6 +79,7 @@ class StreamHandler:
75
79
  self._stop_event = asyncio.Event()
76
80
  self.loop = asyncio.get_running_loop()
77
81
  task = self.loop.create_task(websocket_handler.next_async_websocket(self.uri, self.msg_func))
82
+ task.add_done_callback(lambda t: t.exception() and print(f"[{self.streamName}] Stream task failed: {t.exception()!r}"))
78
83
  await self._stop_event.wait()
79
84
  task.cancel()
80
85
  measurment_handler.stop_measurement(self.host)
@@ -9,6 +9,7 @@ from datetime import datetime
9
9
  from timeit import default_timer as timer
10
10
  import numpy as np
11
11
  import miniaudio
12
+ import threading
12
13
 
13
14
  from . import sequence_handler as seq
14
15
  from . import stream_handler as stream
@@ -109,6 +110,44 @@ class _TimeStamps:
109
110
  self._time_buffer = np.append(self._time_buffer[1:], new_value)
110
111
  return self.lastTime
111
112
 
113
+ def start_all_synced(streams):
114
+ """For handlers constructed with multi_device=True: open each device's stream/websocket,
115
+ then trigger start_pause_measurement on all of them at (nearly) the same instant."""
116
+ for s in streams:
117
+ s.uri = stream.setup_stream(s.host, s.ip, s.stream_ids, s.streamName)
118
+ threading.Thread(target=s.startStream, daemon=True).start()
119
+
120
+ barrier = threading.Barrier(len(streams))
121
+
122
+ def _start_one(s):
123
+ barrier.wait()
124
+ https_requests.put(s.host, "/WebXi/Applications/SLM?Action=StartPause")
125
+
126
+ start_threads = [threading.Thread(target=_start_one, args=(s,)) for s in streams]
127
+ for t in start_threads:
128
+ t.start()
129
+ for t in start_threads:
130
+ t.join()
131
+
132
+
133
+ def stop_all(streams):
134
+ """Tear down every stream: stop all measurements at (nearly) the same instant
135
+ via a barrier (mirroring start_all_synced), then delete each device-side stream resource."""
136
+ barrier = threading.Barrier(len(streams))
137
+
138
+ def _stop_one(s):
139
+ barrier.wait()
140
+ meas.stop_measurement(s.host)
141
+
142
+ stop_threads = [threading.Thread(target=_stop_one, args=(s,)) for s in streams]
143
+ for t in stop_threads:
144
+ t.start()
145
+ for t in stop_threads:
146
+ t.join()
147
+
148
+ for s in streams:
149
+ stream.delete_stream(s.host, s.streamName)
150
+
112
151
 
113
152
  class WebXiStreamHandler(stream.StreamHandler):
114
153
  """Configurable WebXi stream handler.
@@ -138,7 +177,7 @@ class WebXiStreamHandler(stream.StreamHandler):
138
177
 
139
178
  def __init__(self, host, ip, sequenceID=None, sequenceNames=None,
140
179
  streamName="Stream", cpb=False, multi=False, flac=False, mp3=False, fast_logging=False,
141
- time=False, screen_record=False, leq_window_sec=10, windowSize=None, fast_logging_interval=None,
180
+ time=False, screen_record=False, multi_device=False,leq_window_sec=10, windowSize=None, fast_logging_interval=None,
142
181
  saving=None, saving_path=None):
143
182
  super().__init__(streamName)
144
183
  self.host = host
@@ -149,6 +188,7 @@ class WebXiStreamHandler(stream.StreamHandler):
149
188
  self.multi = multi
150
189
  self.flac = flac
151
190
  self.mp3 = mp3
191
+ self.multi_device = multi_device
152
192
  self.fast_logging = fast_logging
153
193
  self.time = time
154
194
  self.screen_record = screen_record
@@ -231,6 +271,11 @@ class WebXiStreamHandler(stream.StreamHandler):
231
271
  self.leq_mov = MovingLeq(self.leq_window_sec, storedata=True)
232
272
 
233
273
  stream_ids = list(self.ID) if isinstance(self.ID, list) else [self.ID]
274
+ self.stream_ids = stream_ids # saved for start_all_synced() when multi_device=True
275
+ if self.multi_device:
276
+ return
277
+
278
+ return
234
279
  if self.time:
235
280
  utc_offset_seconds = _get_slm_utc_offset_seconds(self.host)
236
281
  self._time_stamps = _TimeStamps(self.windowSize or (self.leq_window_sec * 10 + 1), utc_offset_seconds)
@@ -287,7 +332,7 @@ class WebXiStreamHandler(stream.StreamHandler):
287
332
  value = package.content.sequence_blocks[0].values
288
333
  self.CPB_values = np.array(stream.data_type_conv(self.sequence["DataType"], value, self.sequence["VectorLength"])) / 100
289
334
  if self.data_handler:
290
- self.data_handler.handle(timestamp=self._time_prefix(), values=self.CPB_values)
335
+ self.data_handler.handle(timestamp=self._time_prefix(), value=self.CPB_values)
291
336
 
292
337
  def calcFreqBands(self):
293
338
  """Only meaningful when cpb=True."""
@@ -0,0 +1,12 @@
1
+ import websockets
2
+ import asyncio
3
+ from . import https_requests
4
+
5
+ async def next_async_websocket(uri, packetHandler):
6
+ ssl_context = https_requests.build_ssl_context() if uri.startswith("wss://") else None
7
+ async with websockets.connect(uri, ping_interval=None, ssl=ssl_context) as websocket:
8
+ async for message in websocket:
9
+ try:
10
+ packetHandler(message)
11
+ except Exception as exc:
12
+ print(f"Error handling message from {uri}: {exc!r}")
@@ -7,13 +7,17 @@ from slm_api.helpers.https_requests import get, put
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):
10
+
10
11
  for endpoint in (
11
12
  "/webxi/Applications/SLM/Setup/BBFreqWeightB",
12
13
  "/webxi/Applications/SLM/Setup/BBFreqWeightZ",
13
14
  "/webxi/Applications/SLM/Setup/BBFreqWeightA",
14
15
  "/webxi/Applications/SLM/Setup/BBFreqWeightC",
15
16
  ):
16
- put(host , endpoint, json=False, timeout=10)
17
+ try:
18
+ put(host , endpoint, json=False, timeout=10)
19
+ except requests.exceptions.HTTPError as exc:
20
+ print(f"Skipping {endpoint}: {exc}")
17
21
 
18
22
  def turn_on_bb_freq_weight(host, weights, fast=False):
19
23
  weights = [weights] if isinstance(weights, str) else weights
@@ -0,0 +1,155 @@
1
+ """
2
+ Multi-device FLAC/mp3 audio streaming
3
+ --------------------------------------
4
+ Streams FLAC- (or mp3-)encoded audio from several devices at once and plots
5
+ each device's waveform + spectrum, same as flac_example.py/mp3_example.py's
6
+ figureHandler, stacked in one window (one time/freq row pair per device).
7
+
8
+ Note: WebXiStreamHandler._msg_func_audio also appends decoded samples to the
9
+ module-level `DataBuffer` (helpers/buffer.py), which is a single shared buffer.
10
+ With multiple devices, samples from all of them interleave in that shared
11
+ buffer, so it isn't usable for per-device plotting here - each device instead
12
+ gets its own `buffer` instance (BufferDataHandler below).
13
+ """
14
+
15
+ import sys
16
+ import time
17
+
18
+ import numpy as np
19
+ import pyqtgraph as pg
20
+ from PyQt5 import QtWidgets
21
+
22
+ from slm_api.helpers.buffer import buffer as Buffer
23
+ from slm_api.helpers.fft import dBfft
24
+ from slm_api.helpers.stream_handlers import WebXiStreamHandler, start_all_synced, stop_all
25
+ from slm_api.helpers.data_handler import DataHandler
26
+ from slm_api.enums.sequence_id_enum import SequenceIdEnums
27
+
28
+ USE_MP3 = True # False = FLAC (SequenceIdEnums.FLACSignal), True = mp3 (SequenceIdEnums.MP3Signal)
29
+ SEQUENCE_ID = SequenceIdEnums.MP3Signal.value if USE_MP3 else SequenceIdEnums.FLACSignal.value
30
+ SAMPLE_RATE = 32e3 if USE_MP3 else 2 ** 16 # matches mp3_example.py / flac_example.py dBfft() calls
31
+
32
+ CHUNK_TO_SHOW = 2 ** 15
33
+
34
+
35
+ class BufferDataHandler(DataHandler):
36
+ """Per-device handler: appends decoded samples into its own buffer instead
37
+ of the shared DataBuffer singleton, so devices don't mix samples together."""
38
+
39
+ def __init__(self):
40
+ self.buffer = Buffer(2 ** 16)
41
+
42
+ def handle(self, samples, **data):
43
+ self.buffer.append(samples)
44
+
45
+
46
+ class MultiDeviceFigureHandler:
47
+ """One time-domain + spectrum plot pair per device, stacked in one window."""
48
+
49
+ def __init__(self, labels_and_handlers):
50
+ self.labels_and_handlers = labels_and_handlers
51
+ self.fft_hamming = np.hamming(CHUNK_TO_SHOW)
52
+ self.axis = np.flip(np.arange(CHUNK_TO_SHOW) * -1 / CHUNK_TO_SHOW)
53
+ self.old = [0] * len(labels_and_handlers)
54
+ self.oldold = [0] * len(labels_and_handlers)
55
+ self.i = 0
56
+
57
+ self.app = QtWidgets.QApplication(sys.argv)
58
+ self.win = pg.GraphicsLayoutWidget(title="Multi-device streaming")
59
+ self.win.setBackground('w')
60
+ self.win.resize(1000, 300 * len(labels_and_handlers))
61
+ label_style = {'color': '#000', 'font-size': '13pt'}
62
+
63
+ self.plots_time, self.plots_freq, self.curves_time, self.curves_freq = [], [], [], []
64
+ freq = np.arange(CHUNK_TO_SHOW // 2 + 1) / (float(CHUNK_TO_SHOW) / SAMPLE_RATE)
65
+ for label, _ in labels_and_handlers:
66
+ plot_time = self.win.addPlot(title=label)
67
+ curve_time = plot_time.plot(self.axis, np.zeros(CHUNK_TO_SHOW))
68
+ curve_time.setPen(color='b', width=2, autoDownsample=True, clipToView=True)
69
+ plot_time.showGrid(x=True, y=True)
70
+ plot_time.setXRange(np.min(self.axis), np.max(self.axis))
71
+ plot_time.setYRange(-2, 2)
72
+ plot_time.getAxis('left').setLabel('Pressure', units='Pa', **label_style)
73
+ plot_time.getAxis('bottom').setLabel('Time', units='s', **label_style)
74
+ self.win.nextRow()
75
+
76
+ plot_freq = self.win.addPlot()
77
+ curve_freq = plot_freq.plot(freq, np.zeros(len(freq)))
78
+ curve_freq.setPen(color='b', width=2, autoDownsample=True, clipToView=True)
79
+ plot_freq.setXRange(0, np.max(freq))
80
+ plot_freq.setYRange(-20, 130)
81
+ plot_freq.getAxis('bottom').enableAutoSIPrefix(enable=False)
82
+ plot_freq.setLogMode(x=True, y=False)
83
+ plot_freq.showGrid(x=True, y=True)
84
+ plot_freq.getAxis('left').setLabel('dB SPL re 20 µPa', **label_style)
85
+ plot_freq.getAxis('bottom').setLabel('Frequency', units='Hz', **label_style)
86
+ self.win.nextRow()
87
+
88
+ self.plots_time.append(plot_time)
89
+ self.plots_freq.append(plot_freq)
90
+ self.curves_time.append(curve_time)
91
+ self.curves_freq.append(curve_freq)
92
+
93
+ self.win.show()
94
+ self.timer = pg.QtCore.QTimer()
95
+ self.timer.timeout.connect(self.update)
96
+ self.timer.start(int(0.1 * 1000))
97
+
98
+ def update(self):
99
+ # Recomputing dBfft (32768-sample FFT) for every device on every 100ms
100
+ # tick can hold the GIL long enough to stall the decode threads (seen as
101
+ # audio decode's own "TotalTime" warnings), so only do it every 5th tick.
102
+ if self.i % 5 != 0:
103
+ self.i += 1
104
+ return
105
+ for idx, (label, handler) in enumerate(self.labels_and_handlers):
106
+ signal = handler.buffer.getPart(CHUNK_TO_SHOW)
107
+ x = np.linspace(np.min(self.axis), np.max(self.axis), len(signal))
108
+ freq, s_dbfs = dBfft(signal, SAMPLE_RATE, self.fft_hamming, ref=20e-6) # Reference = 20µPa
109
+ avg = s_dbfs / 3 + self.old[idx] / 3 + self.oldold[idx] / 3
110
+ self.curves_time[idx].setData(x, signal)
111
+ self.curves_freq[idx].setData(freq, avg)
112
+ self.oldold[idx] = self.old[idx]
113
+ self.old[idx] = s_dbfs
114
+ min_Pa = np.round(min(signal), 2)
115
+ max_Pa = np.round(max(signal), 2)
116
+ fft_peak = np.round(max(avg), 2)
117
+ fft_min = np.round(min(avg), 2)
118
+ peak_freq = freq[np.argmax(avg)]
119
+ if min_Pa != max_Pa:
120
+ self.plots_time[idx].setYRange(min_Pa * 1.2, max_Pa * 1.2)
121
+ if not np.isinf(fft_peak):
122
+ self.plots_freq[idx].setYRange(fft_min, fft_peak * 1.2)
123
+ print(f"{label} Min: {min_Pa} Pa, Max: {max_Pa} Pa, Peak: {fft_peak} dB SPL, Peak freq: {peak_freq} Hz")
124
+ self.i += 1
125
+
126
+ def run(self):
127
+ QtWidgets.QApplication.instance().exec_()
128
+
129
+
130
+ if __name__ == "__main__":
131
+ devices = [
132
+ ("http://192.168.1.183", "192.168.1.183"),
133
+ ("http://192.168.1.216", "192.168.1.216"),
134
+ ("http://192.168.1.191", "192.168.1.191"),
135
+
136
+ ]
137
+
138
+ streams = [
139
+ WebXiStreamHandler(
140
+ host=dev_host, ip=dev_ip, sequenceID=SEQUENCE_ID,
141
+ streamName=f"Stream_{dev_ip}", multi_device=True,
142
+ mp3=USE_MP3, flac=not USE_MP3,
143
+ )
144
+ for dev_host, dev_ip in devices
145
+ ]
146
+ handlers = [BufferDataHandler() for _ in streams]
147
+ for s, h in zip(streams, handlers):
148
+ s.setDataHandler(h)
149
+
150
+ fig = MultiDeviceFigureHandler([(s.ip, h) for s, h in zip(streams, handlers)])
151
+ fig.app.aboutToQuit.connect(lambda: stop_all(streams))
152
+
153
+ time.sleep(1)
154
+ start_all_synced(streams)
155
+ fig.run()
@@ -0,0 +1,75 @@
1
+ """
2
+ 18. Stream FastLAF (Sequence 115)
3
+ -----------------------------------
4
+ Streams the FastLAF (LAeq) broadband Leq value from sequence 115
5
+ and pretty-prints each received value to the terminal.
6
+
7
+ Sequence 115 properties:
8
+ Name: FastLAF
9
+ LocalName: LAeq
10
+ FunctionType: BroadbandLeq
11
+ DataType: Int16
12
+ Scale: 0.01
13
+ Weighting: A
14
+ AveragingMode: Linear
15
+ Unit: dB re 20uPa
16
+ """
17
+
18
+
19
+
20
+ import time
21
+ import threading
22
+ from slm_api.helpers.stream_handlers import WebXiStreamHandler, start_all_synced, stop_all
23
+ from slm_api.helpers.data_handler import DataHandler
24
+ from slm_api.enums.sequence_id_enum import SequenceIdEnums
25
+ from slm_api.enums.fast_log_intervals_enum import FastLogInterval
26
+ from slm_api.helpers import webxi_helper_functions as webxi_helper
27
+
28
+
29
+ FAST_LOGGING_INTERVAL_MS = FastLogInterval.interval_1000ms.value
30
+ SEQUENCE_ID = SequenceIdEnums.LAeq.value
31
+ SEQUENCE_NAME = SequenceIdEnums.LAeq.name
32
+
33
+
34
+ class PrintDataHandler(DataHandler):
35
+ def __init__(self, label):
36
+ self.label = label
37
+
38
+ def handle(self, value, **data):
39
+ print(f"{self.label} {SEQUENCE_NAME}: {value}")
40
+
41
+
42
+ if __name__ == "__main__":
43
+ devices = [
44
+ ("http://192.168.1.183", "192.168.1.183"),
45
+ ("http://192.168.1.216", "192.168.1.216"),
46
+ ("http://192.168.1.191", "192.168.1.191")
47
+ ]
48
+
49
+ # for dev_host, dev_ip in devices:
50
+ # # webxi_helper.turn_off_CPB_freq_weight(dev_host)
51
+ # # webxi_helper.turn_on_CPB_freq_weight(dev_host, "A")
52
+ # # webxi_helper.turn_on_cpb_leq(dev_host, SEQUENCE_NAME)
53
+ # webxi_helper.turn_off_bb_freq_weight(dev_host)
54
+ # webxi_helper.turn_on_bb_freq_weight(dev_host, "A")
55
+ # webxi_helper.turn_on_bb_leq(dev_host, 'LAF')
56
+
57
+ streams = [
58
+ WebXiStreamHandler(
59
+ host=dev_host, ip=dev_ip, sequenceID=SEQUENCE_ID,
60
+ streamName=f"Stream_{dev_ip}", multi_device=True
61
+ )
62
+ for dev_host, dev_ip in devices
63
+ ]
64
+ for s in streams:
65
+ s.setDataHandler(PrintDataHandler(s.ip))
66
+
67
+ time.sleep(1)
68
+ start_all_synced(streams)
69
+
70
+ try:
71
+ while True:
72
+ time.sleep(1)
73
+ except KeyboardInterrupt:
74
+ stop_all(streams)
75
+ print("\nStreams stopped by user.")
@@ -1,8 +0,0 @@
1
- import websockets
2
- import asyncio
3
-
4
- async def next_async_websocket(uri, packetHandler):
5
- """Function which awaits response from the websocket and calls the packetHandler"""
6
- async with websockets.connect(uri, ping_interval = None) as websocket:
7
- async for message in websocket:
8
- packetHandler(message)