diff --git a/examples/main.py b/examples/main.py
index 963bcc6b233562022328cdd957b1f955df4f00ef..f0656324d61a8b473b172b4b88dd043996115811 100644
--- a/examples/main.py
+++ b/examples/main.py
@@ -2,7 +2,7 @@ import logging
import sys
import os
-sys.path.append('../src')
+sys.path.append('./src')
from PySide6.QtWidgets import QApplication
from rich.logging import RichHandler
diff --git a/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py b/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py
index dfad80f216eb4822ec681df3616467047821ca05..4b7c50a74836bc124f1bf80a7ed142b183a45419 100644
--- a/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py
+++ b/src/CaptDeviceControl/controller/BaseAD2CaptDevice.py
@@ -1,5 +1,6 @@
import logging
import os
+import sys
import time
from abc import abstractmethod
from collections import deque
@@ -8,8 +9,7 @@ from PySide6.QtCore import QObject, QThreadPool
from numpy import ndarray
from rich.logging import RichHandler
-from CaptDeviceControl.controller.mp_AD2Capture.AD2StateMPSetter import AD2State
-from CaptDeviceControl.controller.mp_AD2Capture.MPDeviceControl import mp_capture
+
from CaptDeviceControl.model.AD2CaptDeviceModel import AD2CaptDeviceModel, AD2CaptDeviceSignals
from CaptDeviceControl.model.AD2Constants import AD2Constants
from multiprocessing import Process, Queue, Value, Lock
@@ -224,56 +224,11 @@ class BaseAD2CaptDevice(QObject):
#time.sleep(0.1)
self.logger.info("Status data consume thread ended")
- def _set_ad2state_from_process(self, ad2state: AD2State):
- # print(ad2state.__dict__)
- self.model.pid = ad2state.pid
-
- self.model.dwf_version = ad2state.dwf_version
-
- self.model.connected = ad2state.connected
- self.model.device_name = ad2state.device_name
- self.model.device_serial_number = ad2state.device_serial_number
- self.model.device_index = ad2state.device_index
-
- if ad2state.acquisition_state == AD2Constants.CapturingState.RUNNING():
- self.logger.info("[START ACQ] Started acquisition")
- self.model.capturing_finished = False
- self.model.start_recording = True
- self.model.stop_recording = False
- elif ad2state.acquisition_state == AD2Constants.CapturingState.STOPPED():
- if self.model.start_recording:
- self.model.capturing_finished = True
- self.logger.info(f"[STOP ACQ] Finished acquisition {self.model.capturing_finished}.")
- # Emit a signal, that the Capturing has finished
- self.model.start_recording = False
- self.model.stop_recording = True
- self.model.device_capturing_state = ad2state.acquisition_state
-
- self.model.sample_rate = ad2state.sample_rate
- self.model.selected_ain_channel = ad2state.selected_ain_channel
-
- self.model.ain_channels = ad2state.ain_channels
- self.model.ain_buffer_size = ad2state.ain_buffer_size
- self.model.ain_bits = ad2state.ain_bits
- self.model.ain_device_state = ad2state.ain_device_state
-
- self.model.recording_time = ad2state.recording_time
-
# ==================================================================================================================
# Destructor
# ==================================================================================================================
- def stop_process(self):
- #self.end_process_flag.value = True
-
- time_start = time.time()
- #while self.proc.is_alive():
- # time.sleep(0.1)
- self.logger.warning(f"AD2 process exited after {time.time()-time_start}s")
- self.kill_thread = True
-
- def __del__(self):
- self.logger.info("Exiting AD2 controller")
- self.stop_process()
- self.logger.warning("AD2 controller exited")
+ def exit(self):
+ self.mpcaptdevicecontrol.safe_exit()
+
\ No newline at end of file
diff --git a/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py b/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py
deleted file mode 100644
index f1f0827cdfc2f5fe380b01e0fe847fe6cb281604..0000000000000000000000000000000000000000
--- a/src/CaptDeviceControl/controller/mp_AD2Capture/AD2StateMPSetter.py
+++ /dev/null
@@ -1,297 +0,0 @@
-from ctypes import c_int, c_byte
-
-from CaptDeviceControl.model.AD2Constants import AD2Constants
-
-class AD2State:
- def __init__(self):
- # Multiprocessing Information
- self._pid = None
- self._ppid = None
-
- # WaveForms Runtime (DWF) Information
- self._dwf_version: str = "Unknown"
-
- # Device information
- self._connected: bool = False
- self._device_name: str = "Unknown"
- self._serial_number: str = "Unknown"
- self._device_index: int = -1
-
- # Acquisition Settings
- self._sample_rate: int = -1
- self._selected_ain_channel: int = -1
-
- # Analog In Information
- self._ain_channels: list = []
- self._ain_buffer_size: int = -1
- self._ain_bits: int = -1
- self._ain_device_state: c_byte = c_byte()
-
- # Analog Out Information
- self._aout_channels: list = []
-
- # Acquired Signal Information
- self._acquisition_state: int = AD2Constants.CapturingState.STOPPED()
-
- self._time_capture_started: float = -1 # The time the capturing has started
- self._time_capture_ended: float = -1 # The time the capturing has ended
- self._recording_time: float = -1
-
- self._samples_captured: int = 0
- self._samples_lost: int = -1
- self._samples_corrupted: int = -1
-
- # Device Status
- self._device_ready: bool = False
- self._device_capturing = False
-
-
- def reinit(self, fields: dict):
- for k, v in fields.items():
- setattr(self, k, v)
-
- # =========== Multiprocessing Information
- @property
- def pid(self):
- return self._pid
-
- @property
- def ppid(self):
- return self._ppid
-
- # =========== WaveForms Runtime (DWF) Information
- @property
- def dwf_version(self):
- return self._dwf_version
-
- # =========== Device Information
- @property
- def connected(self):
- return self._connected
-
- @property
- def device_name(self):
- return self._device_name
-
- @property
- def device_serial_number(self):
- return self._serial_number
-
- @property
- def device_index(self):
- return self._device_index
-
- # ========== Acquisition Settings
- @property
- def sample_rate(self):
- return self._sample_rate
-
- @property
- def selected_ain_channel(self):
- return self._selected_ain_channel
-
- # =========== Analog In Information
- @property
- def ain_channels(self):
- return self._ain_channels
-
- @property
- def ain_buffer_size(self):
- return self._ain_buffer_size
-
- @property
- def ain_bits(self):
- return self._ain_bits
-
- @property
- def ain_device_state(self):
- return self._ain_device_state
-
- # =========== Analog Out Information
- @property
- def aout_channels(self):
- return self._aout_channels
-
- # =========== Acquired Signal Information
- @property
- def acquisition_state(self):
- return self._acquisition_state
-
- @property
- def time_capture_started(self) -> float:
- """The time the capturing has started"""
- return self._time_capture_started
-
- @property
- def time_capture_ended(self) -> float:
- """The time the capturing has ended"""
- return self._time_capture_ended
-
- @property
- def recording_time(self):
- return self._recording_time
-
- @property
- def samples_captured(self):
- return self._samples_captured
-
- @property
- def samples_lost(self):
- return self._samples_lost
-
- @property
- def samples_corrupted(self):
- return self._samples_corrupted
-
- # =========== Device Status
- @property
- def device_ready(self):
- return self._device_ready
-
- @property
- def device_capturing(self):
- return self._device_capturing
-
-
-class AD2StateMPSetter(AD2State):
-
- def __init__(self, state_queue):
- super().__init__()
- self._state_queue = state_queue
-
- # =========== Multiprocessing Information
- @AD2State.pid.setter
- def pid(self, value):
- self._pid = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.ppid.setter
- def ppid(self, value):
- self._ppid = value
- self._state_queue.put(self.to_simple_class())
-
- # =========== WaveForms Runtime (DWF) Information
- @AD2State.dwf_version.setter
- def dwf_version(self, value):
-
- self._dwf_version = value
- self._state_queue.put(self.to_simple_class())
-
- # =========== Device Information
- @AD2State.connected.setter
- def connected(self, value):
- self._connected = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.device_name.setter
- def device_name(self, value):
- self._device_name = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.device_serial_number.setter
- def device_serial_number(self, value):
- self._serial_number = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.device_index.setter
- def device_index(self, value):
- self._device_index = value
- self._state_queue.put(self.to_simple_class())
-
- # ========== Acquisition Settings
- @AD2State.sample_rate.setter
- def sample_rate(self, value):
- self._sample_rate = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.selected_ain_channel.setter
- def selected_ain_channel(self, value):
- self._selected_ain_channel = value
- self._state_queue.put(self.to_simple_class())
-
- # =========== Analog In Information
- @AD2State.ain_channels.setter
- def ain_channels(self, value):
- self._ain_channels = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.ain_buffer_size.setter
- def ain_buffer_size(self, value):
- self._ain_buffer_size = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.ain_bits.setter
- def ain_bits(self, value):
- self._ain_bits = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.ain_device_state.setter
- def ain_device_state(self, value):
- self._ain_device_state = value
- self._state_queue.put(self.to_simple_class())
-
- # =========== Analog Out Information
- @AD2State.aout_channels.setter
- def aout_channels(self, value):
- self._aout_channels = value
- self._state_queue.put(self.to_simple_class())
-
- # =========== Acquired Signal Information
- @AD2State.acquisition_state.setter
- def acquisition_state(self, value):
- self._acquisition_state = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.time_capture_ended.setter
- def time_capture_started(self, value: float):
- """The time the capturing has started"""
- self._time_capture_started = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.time_capture_ended.setter
- def time_capture_ended(self, value: float):
- self._time_capture_ended = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.recording_time.setter
- def recording_time(self, value):
- self._recording_time = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.samples_captured.setter
- def samples_captured(self, value):
- self._samples_captured = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.samples_lost.setter
- def samples_lost(self, value):
- self._samples_lost = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.samples_corrupted.setter
- def samples_corrupted(self, value):
- self._samples_corrupted = value
- self._state_queue.put(self.to_simple_class())
-
- # =========== Device Status
- @AD2State.device_ready.setter
- def device_ready(self, value):
- self._device_ready = value
- self._state_queue.put(self.to_simple_class())
-
- @AD2State.device_capturing.setter
- def device_capturing(self, value):
- self._device_capturing = value
- self._state_queue.put(self.to_simple_class())
-
- def to_simple_class(self) -> AD2State:
- exclude = ["_state_queue"]
- ad2state = AD2State()
- to_dict = {}
- for item, value in self.__dict__.items():
- if item in exclude:
- continue
- else:
- to_dict[item] = value
- ad2state.reinit(to_dict)
- return ad2state
diff --git a/src/CaptDeviceControl/controller/mp_AD2Capture/MPCaptDeviceControl.py b/src/CaptDeviceControl/controller/mp_AD2Capture/MPCaptDeviceControl.py
index 5b73a813bf1cdb3f0fb0847cac6d007ec6e8ab63..62ff7ea32df0b4a881b12ad663811ae0362d3ba7 100644
--- a/src/CaptDeviceControl/controller/mp_AD2Capture/MPCaptDeviceControl.py
+++ b/src/CaptDeviceControl/controller/mp_AD2Capture/MPCaptDeviceControl.py
@@ -4,8 +4,8 @@ import cmp
from PySide6.QtCore import Signal
from CaptDeviceControl.controller.mp_AD2Capture.MPCaptDevice import MPCaptDevice
-from model.AD2CaptDeviceModel import AD2CaptDeviceSignals, AD2CaptDeviceModel
-from model.AD2Constants import AD2Constants
+from CaptDeviceControl.model.AD2CaptDeviceModel import AD2CaptDeviceSignals, AD2CaptDeviceModel
+from CaptDeviceControl.model.AD2Constants import AD2Constants
class MPCaptDeviceControl(cmp.CProcessControl):
diff --git a/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py b/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py
deleted file mode 100644
index e6692352a63dd679fd140a890b982315c9211b2d..0000000000000000000000000000000000000000
--- a/src/CaptDeviceControl/controller/mp_AD2Capture/MPDeviceControl.py
+++ /dev/null
@@ -1,336 +0,0 @@
-"""
-File for methods that run the multiporcessing capture.
-Here we can init the device capturing and stream the data using ques.
-(c) Christoph Schmidt, 2023
-christoph.schmidt@tugraz.at
-"""
-
-import os
-import random
-import sys
-import time
-from ctypes import c_int, byref, c_double, cdll, create_string_buffer, c_int32, CDLL
-
-from CaptDeviceControl.controller.mp_AD2Capture.AD2StateMPSetter import AD2StateMPSetter
-from CaptDeviceControl.model.AD2Constants import AD2Constants
-from CaptDeviceControl.constants.dwfconstants import acqmodeRecord, DwfStateConfig, DwfStatePrefill, DwfStateArmed, enumfilterType, \
- enumfilterUSB, enumfilterDemo
-
-
-# ======================================================================================================================
-# Process logging function
-# ======================================================================================================================
-def _mp_log_debug(msg, prefix="AD2 Thread"):
- print(f"DBG | [{prefix}/{os.getpid()}]: {msg}")
-
-
-def _mp_log_error(msg, prefix="AD2 Thread"):
- print(f"ERR | [{prefix}/{os.getpid()}]: {msg}")
-
-
-def _mp_log_info(msg, prefix="AD2 Thread"):
- print(f"INF | [{prefix}/{os.getpid()}]: {msg}")
-
-
-def _mp_log_warning(msg, prefix="AD2 Thread"):
- print(f"WARN | [{prefix}/{os.getpid()}]: {msg}")
-
-
-# ======================================================================================================================
-# Process Main function, used for capturing and streaming data
-# ======================================================================================================================
-def mp_capture(stream_data_queue, capture_data_queue, state_queue,
- start_capture, end_process,
- device_id, channel, sample_rate):
- """
- Captures data from the device and puts it into a queue.
- :param capture_data_queue:
- :param state_queue:
- :param start_capture:
- :param end_process:
- :param device_id:
- :param sample_rate:
- :param stream_data_queue: Queue to put the data into.
- :param channel: Channel to capture data from.
- :return: None
- """
-
- time_capture_started = 0
- capturing_notified = False
-
- ad2_state = AD2StateMPSetter(state_queue)
- ad2_state.pid = os.getpid()
- ad2_state.ppid = os.getppid()
- # Print pid and ppid
- _mp_log_info(f"Starting capture thread, pid={ad2_state.pid}, ppid={ad2_state.ppid}")
-
- ad2_state.selected_ain_channel = channel
- ad2_state.sample_rate = sample_rate
- ad2_state.device_index = device_id
- _mp_log_debug(f"Setting up device {ad2_state.device_index} with "
- f"channel {ad2_state.selected_ain_channel} and "
- f"acquisition rate {ad2_state.sample_rate} Hz")
-
- dwf, hdwf = _mp_open_device(device_id, ad2_state)
-
- # acquisition_state = c_byte()
-
- cAvailable = c_int()
- cLost = c_int()
- cCorrupted = c_int()
-
- # FDwfAnalogInStatus(HDWF hdwf, BOOL fReadData, DwfState* psts)
- _t_setup_aquisition(dwf, hdwf, ad2_state)
- _t_setup_sine_wave(dwf, hdwf, ad2_state)
-
- _mp_log_info("Configuring acquisition. Starting oscilloscope.")
- # FDwfAnalogInConfigure(HDWF hdwf, int fReconfigure, int fStart)
- # Configures the instrument and start or stop the acquisition. To reset the Auto trigger timeout, set
- # fReconfigure to TRUE.
- # hdwf – Interface handle.
- # fReconfigure – Configure the device.
- # fStart – Start the acquisition.
- dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1))
-
- _mp_log_info("Device configured. Starting acquisition.")
-
- cSamples = 0
- ad2_state.device_ready = True
- capture_samples = 0
- print(end_process.value)
- while end_process.value == int(False):
- # Checks the state of the acquisition. To read the data from the device, set fReadData to TRUE. For
- # single acquisition mode, the data will be read only when the acquisition is finished
- dwf.FDwfAnalogInStatus(hdwf, c_int(1),
- byref(ad2_state.ain_device_state)) # Variable to receive the acquisition state
-
- if cSamples == 0 and (
- ad2_state.ain_device_state == DwfStateConfig or
- ad2_state.ain_device_state == DwfStatePrefill or
- ad2_state.ain_device_state == DwfStateArmed):
- _mp_log_info("Device in idle state. Waiting for acquisition to start.")
- continue # Acquisition not yet started.
-
- dwf.FDwfAnalogInStatusRecord(hdwf,
- byref(cAvailable),
- byref(cLost),
- byref(cCorrupted))
- cSamples += cLost.value
-
- if cLost.value:
- ad2_state.samples_lost += cLost.value
- if cCorrupted.value:
- ad2_state.samples_corrupted += cCorrupted.value
-
- # self.dwf.FDwfAnalogInStatusSamplesValid(self.hdwf, byref(self.cValid))
- if cAvailable.value == 0:
- continue
- else:
- # print(f"Available: {cAvailable.value}")
- # if cSamples + cAvailable.value > self.ad2capt_model.n_samples:
- # cAvailable = c_int(self.ad2capt_model.n_samples - cSamples)
- rgdSamples = (c_double * cAvailable.value)()
-
- dwf.FDwfAnalogInStatusData(hdwf, c_int(ad2_state.selected_ain_channel), byref(rgdSamples),
- cAvailable) # get channel data
- # Print how many samples are available
- status = {"available": cAvailable.value, 'captured': 0, 'lost': cLost.value,
- 'corrupted': cCorrupted.value, "time": time.time()}
- #print(status)
- time.sleep(random.random())
- #print(len(rgdSamples))
- stream_data_queue.put(
- ([(float(s)) for s in rgdSamples], status)
- )
-
- if start_capture.value == 1:
- if not capturing_notified:
- time_capture_started = time.time()
- capture_samples = 0
- _mp_log_info("Starting command recieved. Acquisition started.")
- ad2_state.acquisition_state = AD2Constants.CapturingState.RUNNING()
- capturing_notified = True
- capture_samples = capture_samples + len(rgdSamples)
- status = {
- "available": cAvailable.value,
- "captured": capture_samples,
- "lost": cLost.value,
- "corrupted": cCorrupted.value,
- "recording_time": time.time() - time_capture_started}
- capture_data_queue.put(([float(s) for s in rgdSamples], status))
- # capture_data_queue.put([float(s) for s in rgdSamples])
- elif start_capture.value == 0:
- if capturing_notified:
- ad2_state.acquisition_state = AD2Constants.CapturingState.STOPPED()
- time_capture_stopped = time.time()
- time_captured = time_capture_stopped - time_capture_started
- ad2_state.recording_time = time_captured
- _mp_log_info(f"Acquisition stopped after {time_captured} seconds. Captured {capture_samples} "
- f"samples. Resulting in a time of {capture_samples / ad2_state.sample_rate} s.")
- status = {
- "available": cAvailable.value,
- "captured": capture_samples,
- "lost": cLost.value,
- "corrupted": cCorrupted.value,
- "recording_time": time.time() - time_capture_started}
- capture_data_queue.put(([float(s) for s in rgdSamples], status))
-
- capturing_notified = False
- cSamples += cAvailable.value
-
- _mp_close_device(dwf, hdwf, channel, ad2_state)
-
-
-def _mp_update_device_information(dwf, hdwf, ad2_state: AD2StateMPSetter):
- in_channel = c_int()
- out_channel = c_int()
- buffer_size = c_int()
- # Get the Analog In Channels and Buffer Size
- dwf.FDwfAnalogInChannelCount(hdwf, byref(in_channel))
- ad2_state.ain_channels = list(range(0, int(in_channel.value)))
- dwf.FDwfAnalogInBufferSizeInfo(hdwf, 0, byref(buffer_size))
-
- # Get the Analog Out Channels and Buffer Size
- ad2_state.analog_analog_in_buffer_size = int(buffer_size.value)
- dwf.FDwfAnalogOutCount(hdwf, byref(out_channel))
- ad2_state.aout_channels = list(range(0, int(out_channel.value)))
-
- # # Select the first Analog In Channel
- # ad2_state.selected_channel = ad2_state.list_of_analog_in_channels[0]
-
-
-def _mp_get_dwf_information(dwf, ad2_state: AD2StateMPSetter):
- _mp_log_debug(f"Getting DWF version information...")
- version = create_string_buffer(16)
- dwf.FDwfGetVersion(version)
- ad2_state.dwf_version = version.value.decode("utf-8")
- _mp_log_debug(f"DWF Version: {ad2_state.dwf_version}")
-
-# ======================================================================================================================
-# Setup the device
-# ======================================================================================================================
-def _t_setup_sine_wave(dwf, hdwf, ad2_state: AD2StateMPSetter):
- _mp_log_debug("Generating AM sine wave...")
- dwf.FDwfAnalogOutNodeEnableSet(hdwf, c_int(0), c_int(0), c_int(1)) # carrier
- dwf.FDwfAnalogOutNodeFunctionSet(hdwf, c_int(0), c_int(0), c_int(1)) # sine
- dwf.FDwfAnalogOutNodeFrequencySet(hdwf, c_int(0), c_int(0), c_double(0.1))
- dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, c_int(0), c_int(0), c_double(1))
- # dwf.FDwfAnalogOutNodeOffsetSet(hdwf, c_int(0), c_int(0), c_double(0.5))
- # dwf.FDwfAnalogOutNodeEnableSet(hdwf, c_int(0), c_int(2), c_int(1)) # AM
- # dwf.FDwfAnalogOutNodeFunctionSet(hdwf, c_int(0), c_int(2), c_int(3)) # triangle
- # dwf.FDwfAnalogOutNodeFrequencySet(hdwf, c_int(0), c_int(2), c_double(0.1))
- # dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, c_int(0), c_int(2), c_double(50))
- dwf.FDwfAnalogOutConfigure(hdwf, c_int(0), c_int(1))
- _mp_log_debug("Sine wave on output channel 0 configured.")
-
-
-def _t_setup_aquisition(dwf, hdwf, ad2_state: AD2StateMPSetter):
- dwf.FDwfAnalogInStatus(hdwf, c_int(1),
- byref(ad2_state.ain_device_state)) # Variable to receive the acquisition state
- _mp_log_info(f"[Task] Setup for acquisition on channel"
- f" {ad2_state.selected_ain_channel} with rate {ad2_state.sample_rate} Hz.")
- dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(ad2_state.selected_ain_channel), c_int(1))
- dwf.FDwfAnalogInChannelRangeSet(hdwf, c_int(ad2_state.selected_ain_channel), c_double(5))
- dwf.FDwfAnalogInAcquisitionModeSet(hdwf, acqmodeRecord)
- dwf.FDwfAnalogInFrequencySet(hdwf, c_double(ad2_state.sample_rate))
- dwf.FDwfAnalogInRecordLengthSet(hdwf, 0) # -1 infinite record length
-
- # Variable to receive the acquisition state
- dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(ad2_state.ain_device_state))
- _mp_log_info(f"[Task] Wait 2 seconds for the offset to stabilize.")
- # wait at least 2 seconds for the offset to stabilize
- time.sleep(2)
- _mp_log_info(f"[Task] Setup for acquisition done.")
-
-
-def _mp_discover_connected_devices(dwf):
- _mp_log_info(f"Discovering connected devices...")
- num_of_connected_devices = 0
-
- devicename = create_string_buffer(64)
- serialnum = create_string_buffer(16)
-
- for iDevice in enumerate_devices(dwf, show_demo_devices=True):
- dwf.FDwfEnumDeviceName(c_int(iDevice), devicename)
- dwf.FDwfEnumSN(c_int(iDevice), serialnum)
- connected_devices.append({
- 'type': type,
- 'device_id': int(iDevice),
- 'device_name': str(devicename.value.decode('UTF-8')),
- 'serial_number': str(serialnum.value.decode('UTF-8'))
- })
- #_mp_log_debug(f"Found {type} device: {devicename.value.decode('UTF-8')} ({serialnum.value.decode('UTF-8')})")
- # print(connected_devices)
- # print(f"Discoverd {len(self.model.connected_devices)} devices.")
- return connected_devices
-
-def enumerate_devices(dwf: CDLL, show_demo_devices=False) -> list:
- """
- Enumerates all connected devices. Function is used to discover all connected, compatible devices.
- Builds an internal list of detected devices filtered by the enumfilter parameter. It must be called
- before using other FDwfEnum functions because they obtain information about enumerated devices
- from this list identified by the device index.
- :param show_demo_devices: Specify if demo devices should be shown.
- :return: A list from 0 to n devices.
- """
- if show_demo_devices:
- enum_filter = c_int32(enumfilterType.value | enumfilterUSB.value | enumfilterDemo.value)
- else:
- enum_filter = c_int32(enumfilterType.value | enumfilterUSB.value)
-
- cDevice = c_int()
- dwf.FDwfEnum(enum_filter, byref(cDevice))
- return list(range(0, cDevice.value))
-
-def _mp_open_device(ad2_state: AD2StateMPSetter):
- """
- Opens the device and returns the handle.
- :return: Device handle.
- """
- _mp_log_debug(f"Importing dwf library for {sys.platform}...")
- if sys.platform.startswith("win"):
- dwf = cdll.dwf
- elif sys.platform.startswith("darwin"):
- dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
- else:
- dwf = cdll.LoadLibrary("libdwf.so")
- hdwf = c_int()
-
- _mp_get_dwf_information(dwf, ad2_state)
- # This is needed, otherwise, the device is not found.
- _mp_discover_connected_devices(dwf)
-
- # Opens the device specified by idxDevice. The device handle is returned in hdwf. If idxDevice is -1, the
- # first available device is opened.
- _mp_log_info(f"[Task] Opening device #{ad2_state.device_index}...")
- dwf.FDwfDeviceOpen(c_int(ad2_state.device_index), byref(hdwf))
-
- devicename = create_string_buffer(64)
- serialnum = create_string_buffer(16)
-
- dwf.FDwfEnumDeviceName(c_int(ad2_state.device_index), devicename)
- dwf.FDwfEnumSN(c_int(ad2_state.device_index), serialnum)
-
- ad2_state.device_name = str(devicename.value.decode("utf-8"))
- ad2_state.device_serial_number = str(serialnum.value.decode("utf-8")).replace("SN:", "")
- # open device
-
- if hdwf.value == 0:
- szerr = create_string_buffer(512)
- dwf.FDwfGetLastErrorMsg(szerr)
- _mp_log_error(f"Failed to open device: {szerr.value}")
- ad2_state.connected = False
- raise Exception(f"Failed to open device: {szerr.value}")
- else:
- _mp_log_info(f"Device opened: {ad2_state.device_name} ({ad2_state.device_serial_number})")
- ad2_state.connected = True
-
- return dwf, hdwf
-
-
-def _mp_close_device(dwf, hdwf, channel, ad2_state: AD2StateMPSetter):
- dwf.FDwfAnalogOutReset(hdwf, c_int(channel))
- _mp_log_info(f"[Task] Closing device...")
- dwf.FDwfDeviceClose(hdwf)
- ad2_state.connected = False
- _mp_log_info(f"[Task] Device closed.")
diff --git a/src/CaptDeviceControl/view/AD2CaptDeviceView.py b/src/CaptDeviceControl/view/AD2CaptDeviceView.py
index 46dfb253a481d39da5173f7426e7223bc78aa557..4246c8d339b5a29ee845b219ff920b263e9be2e2 100644
--- a/src/CaptDeviceControl/view/AD2CaptDeviceView.py
+++ b/src/CaptDeviceControl/view/AD2CaptDeviceView.py
@@ -481,3 +481,9 @@ class ControlWindow(QMainWindow):
else:
item = QStandardItem(str(data))
parent.appendRow(item)
+
+ def closeEvent(self, args):
+ print("Destroyed")
+ self.controller.exit()
+ self.destroyed.emit()
+
\ No newline at end of file