py-neuromodulation 0.0.2__py3-none-any.whl → 0.0.3__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.
- docs/build/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
- docs/build/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +233 -0
- docs/build/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/build/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
- docs/build/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/build/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
- docs/build/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +68 -0
- docs/build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +239 -0
- docs/build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +97 -0
- docs/build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +192 -0
- docs/build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/source/_build/html/_downloads/09df217f95985497f45d69e2d4bdc5b1/plot_2_example_add_feature.py +76 -0
- docs/source/_build/html/_downloads/0d0d0a76e8f648d5d3cbc47da6351932/plot_real_time_demo.py +97 -0
- docs/source/_build/html/_downloads/3b4900a2b2818ff30362215b76f7d5eb/plot_1_example_BIDS.py +240 -0
- docs/source/_build/html/_downloads/5d73cadc59a8805c47e3b84063afc157/plot_example_BIDS.py +233 -0
- docs/source/_build/html/_downloads/7660317fa5a6bfbd12fcca9961457fc4/plot_example_rmap_computing.py +63 -0
- docs/source/_build/html/_downloads/7e92dd2e6cc86b239d14cafad972ae4f/plot_3_example_sharpwave_analysis.py +219 -0
- docs/source/_build/html/_downloads/839e5b319379f7fd9e867deb00fd797f/plot_example_gridPointProjection.py +210 -0
- docs/source/_build/html/_downloads/ae8be19afe5e559f011fc9b138968ba0/plot_first_demo.py +192 -0
- docs/source/_build/html/_downloads/b8b06cacc17969d3725a0b6f1d7741c5/plot_example_sharpwave_analysis.py +219 -0
- docs/source/_build/html/_downloads/c2db0bf2b334d541b00662b991682256/plot_6_real_time_demo.py +121 -0
- docs/source/_build/html/_downloads/c31a86c0b68cb4167d968091ace8080d/plot_example_add_feature.py +68 -0
- docs/source/_build/html/_downloads/ce3914826f782cbd1ea8fd024eaf0ac3/plot_5_example_rmap_computing.py +64 -0
- docs/source/_build/html/_downloads/da36848a41e6a3235d91fb7cfb6d59b4/plot_0_first_demo.py +189 -0
- docs/source/_build/html/_downloads/eaa4305c75b19a1e2eea941f742a6331/plot_4_example_gridPointProjection.py +210 -0
- docs/source/auto_examples/plot_0_first_demo.py +189 -0
- docs/source/auto_examples/plot_1_example_BIDS.py +240 -0
- docs/source/auto_examples/plot_2_example_add_feature.py +76 -0
- docs/source/auto_examples/plot_3_example_sharpwave_analysis.py +219 -0
- docs/source/auto_examples/plot_4_example_gridPointProjection.py +210 -0
- docs/source/auto_examples/plot_5_example_rmap_computing.py +64 -0
- docs/source/auto_examples/plot_6_real_time_demo.py +121 -0
- docs/source/conf.py +105 -0
- examples/plot_0_first_demo.py +189 -0
- examples/plot_1_example_BIDS.py +240 -0
- examples/plot_2_example_add_feature.py +76 -0
- examples/plot_3_example_sharpwave_analysis.py +219 -0
- examples/plot_4_example_gridPointProjection.py +210 -0
- examples/plot_5_example_rmap_computing.py +64 -0
- examples/plot_6_real_time_demo.py +121 -0
- packages/realtime_decoding/build/lib/realtime_decoding/__init__.py +4 -0
- packages/realtime_decoding/build/lib/realtime_decoding/decoder.py +104 -0
- packages/realtime_decoding/build/lib/realtime_decoding/features.py +163 -0
- packages/realtime_decoding/build/lib/realtime_decoding/helpers.py +15 -0
- packages/realtime_decoding/build/lib/realtime_decoding/run_decoding.py +345 -0
- packages/realtime_decoding/build/lib/realtime_decoding/trainer.py +54 -0
- packages/tmsi/build/lib/TMSiFileFormats/__init__.py +37 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/__init__.py +36 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/lsl_stream_writer.py +200 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_file_writer.py +496 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/poly5_to_edf_converter.py +236 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_formats/xdf_file_writer.py +977 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/__init__.py +35 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/edf_reader.py +116 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/poly5reader.py +294 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_readers/xdf_reader.py +229 -0
- packages/tmsi/build/lib/TMSiFileFormats/file_writer.py +102 -0
- packages/tmsi/build/lib/TMSiPlotters/__init__.py +2 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/__init__.py +39 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/_plotter_gui.py +234 -0
- packages/tmsi/build/lib/TMSiPlotters/gui/plotting_gui.py +440 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/__init__.py +44 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/hd_emg_plotter.py +446 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/impedance_plotter.py +589 -0
- packages/tmsi/build/lib/TMSiPlotters/plotters/signal_plotter.py +1326 -0
- packages/tmsi/build/lib/TMSiSDK/__init__.py +54 -0
- packages/tmsi/build/lib/TMSiSDK/device.py +588 -0
- packages/tmsi/build/lib/TMSiSDK/devices/__init__.py +34 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/TMSi_Device_API.py +1764 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/__init__.py +34 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_device.py +1366 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/saga_types.py +520 -0
- packages/tmsi/build/lib/TMSiSDK/devices/saga/xml_saga_config.py +165 -0
- packages/tmsi/build/lib/TMSiSDK/error.py +95 -0
- packages/tmsi/build/lib/TMSiSDK/sample_data.py +63 -0
- packages/tmsi/build/lib/TMSiSDK/sample_data_server.py +99 -0
- packages/tmsi/build/lib/TMSiSDK/settings.py +45 -0
- packages/tmsi/build/lib/TMSiSDK/tmsi_device.py +111 -0
- packages/tmsi/build/lib/__init__.py +4 -0
- packages/tmsi/build/lib/apex_sdk/__init__.py +34 -0
- packages/tmsi/build/lib/apex_sdk/device/__init__.py +41 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API.py +1009 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_enums.py +239 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_API_structures.py +668 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_device.py +1611 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_dongle.py +38 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_event_reader.py +57 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_channel.py +44 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_config.py +150 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_const.py +36 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_impedance_channel.py +48 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/apex_info.py +108 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/apex_structures/dongle_info.py +39 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/download_measurement.py +77 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/eeg_measurement.py +150 -0
- packages/tmsi/build/lib/apex_sdk/device/devices/apex/measurements/impedance_measurement.py +129 -0
- packages/tmsi/build/lib/apex_sdk/device/threads/conversion_thread.py +59 -0
- packages/tmsi/build/lib/apex_sdk/device/threads/sampling_thread.py +57 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_channel.py +83 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device.py +201 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_device_enums.py +103 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_dongle.py +43 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_event_reader.py +50 -0
- packages/tmsi/build/lib/apex_sdk/device/tmsi_measurement.py +118 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/__init__.py +33 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/event_data.py +44 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data.py +50 -0
- packages/tmsi/build/lib/apex_sdk/sample_data_server/sample_data_server.py +136 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_errors/error.py +126 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_sdk.py +113 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/apex/apex_structure_generator.py +134 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/decorators.py +60 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/logger_filter.py +42 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/singleton.py +42 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/support_functions.py +72 -0
- packages/tmsi/build/lib/apex_sdk/tmsi_utilities/tmsi_logger.py +98 -0
- py_neuromodulation/{helper.py → _write_example_dataset_helper.py} +1 -1
- py_neuromodulation/nm_EpochStream.py +2 -3
- py_neuromodulation/nm_IO.py +43 -70
- py_neuromodulation/nm_RMAP.py +308 -11
- py_neuromodulation/nm_analysis.py +1 -1
- py_neuromodulation/nm_artifacts.py +25 -0
- py_neuromodulation/nm_bispectra.py +64 -29
- py_neuromodulation/nm_bursts.py +44 -30
- py_neuromodulation/nm_coherence.py +2 -1
- py_neuromodulation/nm_features.py +4 -2
- py_neuromodulation/nm_filter.py +63 -32
- py_neuromodulation/nm_filter_preprocessing.py +91 -0
- py_neuromodulation/nm_fooof.py +47 -29
- py_neuromodulation/nm_mne_connectivity.py +1 -1
- py_neuromodulation/nm_normalization.py +50 -74
- py_neuromodulation/nm_oscillatory.py +151 -31
- py_neuromodulation/nm_plots.py +13 -10
- py_neuromodulation/nm_rereference.py +10 -8
- py_neuromodulation/nm_run_analysis.py +28 -13
- py_neuromodulation/nm_sharpwaves.py +103 -136
- py_neuromodulation/nm_stats.py +44 -30
- py_neuromodulation/nm_stream_abc.py +18 -10
- py_neuromodulation/nm_stream_offline.py +181 -40
- py_neuromodulation/utils/_logging.py +24 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/METADATA +182 -142
- py_neuromodulation-0.0.3.dist-info/RECORD +188 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/WHEEL +2 -1
- py_neuromodulation-0.0.3.dist-info/top_level.txt +5 -0
- tests/__init__.py +0 -0
- tests/conftest.py +117 -0
- tests/test_all_examples.py +10 -0
- tests/test_all_features.py +63 -0
- tests/test_bispectra.py +70 -0
- tests/test_bursts.py +105 -0
- tests/test_feature_sampling_rates.py +143 -0
- tests/test_fooof.py +16 -0
- tests/test_initalization_offline_stream.py +41 -0
- tests/test_multiprocessing.py +58 -0
- tests/test_nan_values.py +29 -0
- tests/test_nm_filter.py +95 -0
- tests/test_nm_resample.py +63 -0
- tests/test_normalization_settings.py +146 -0
- tests/test_notch_filter.py +31 -0
- tests/test_osc_features.py +424 -0
- tests/test_preprocessing_filter.py +151 -0
- tests/test_rereference.py +171 -0
- tests/test_sampling.py +57 -0
- tests/test_settings_change_after_init.py +76 -0
- tests/test_sharpwave.py +165 -0
- tests/test_target_channel_add.py +100 -0
- tests/test_timing.py +80 -0
- py_neuromodulation/data/README +0 -6
- py_neuromodulation/data/dataset_description.json +0 -8
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/MOV_aligned_features_ch_ECOG_RIGHT_0_all.png +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/all_feature_plt.pdf +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_FEATURES.csv +0 -182
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_LM_ML_RES.p +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SETTINGS.json +0 -273
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_SIDECAR.json +0 -6
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_decoding_performance.png +0 -0
- py_neuromodulation/data/derivatives/sub-testsub_ses-EphysMedOff_task-gripforce_run-0/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_nm_channels.csv +0 -11
- py_neuromodulation/data/participants.json +0 -32
- py_neuromodulation/data/participants.tsv +0 -2
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_coordsystem.json +0 -5
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_space-mni_electrodes.tsv +0 -11
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_channels.tsv +0 -11
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.eeg +0 -0
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.json +0 -18
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vhdr +0 -35
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/ieeg/sub-testsub_ses-EphysMedOff_task-gripforce_run-0_ieeg.vmrk +0 -13
- py_neuromodulation/data/sub-testsub/ses-EphysMedOff/sub-testsub_ses-EphysMedOff_scans.tsv +0 -2
- py_neuromodulation/grid_cortex.tsv +0 -40
- py_neuromodulation/grid_subcortex.tsv +0 -1429
- py_neuromodulation/nm_settings.json +0 -290
- py_neuromodulation/plots/STN_surf.mat +0 -0
- py_neuromodulation/plots/Vertices.mat +0 -0
- py_neuromodulation/plots/faces.mat +0 -0
- py_neuromodulation/plots/grid.mat +0 -0
- py_neuromodulation/py_neuromodulation.egg-info/PKG-INFO +0 -104
- py_neuromodulation/py_neuromodulation.egg-info/dependency_links.txt +0 -1
- py_neuromodulation/py_neuromodulation.egg-info/requires.txt +0 -26
- py_neuromodulation/py_neuromodulation.egg-info/top_level.txt +0 -1
- py_neuromodulation-0.0.2.dist-info/RECORD +0 -73
- /py_neuromodulation/{py_neuromodulation.egg-info/SOURCES.txt → utils/__init__.py} +0 -0
- {py_neuromodulation-0.0.2.dist-info → py_neuromodulation-0.0.3.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,1611 @@
|
|
|
1
|
+
"""
|
|
2
|
+
(c) 2022 Twente Medical Systems International B.V., Oldenzaal The Netherlands
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
|
|
16
|
+
####### # # ##### #
|
|
17
|
+
# ## ## #
|
|
18
|
+
# # # # # # #
|
|
19
|
+
# # # # ##### #
|
|
20
|
+
# # # # #
|
|
21
|
+
# # # # #
|
|
22
|
+
# # # ##### #
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @file apex_device.py
|
|
26
|
+
* @brief
|
|
27
|
+
* APEX Device object.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
import datetime
|
|
34
|
+
import os
|
|
35
|
+
import time
|
|
36
|
+
|
|
37
|
+
from ....tmsi_errors.error import TMSiError, TMSiErrorCode
|
|
38
|
+
from ....tmsi_utilities.decorators import LogPerformances
|
|
39
|
+
|
|
40
|
+
from ...tmsi_device import TMSiDevice
|
|
41
|
+
from ...tmsi_device_enums import *
|
|
42
|
+
|
|
43
|
+
from .apex_structures.apex_const import ApexConst
|
|
44
|
+
from .apex_structures.apex_info import ApexInfo
|
|
45
|
+
from .apex_structures.apex_config import ApexConfig
|
|
46
|
+
from .apex_structures.dongle_info import DongleInfo
|
|
47
|
+
from .apex_structures.apex_channel import ApexChannel
|
|
48
|
+
from .apex_structures.apex_impedance_channel import ApexImpedanceChannel
|
|
49
|
+
from .apex_API_structures import *
|
|
50
|
+
from .apex_API_enums import *
|
|
51
|
+
from .apex_dongle import ApexDongle
|
|
52
|
+
|
|
53
|
+
if "TMSi_ENV" in os.environ and os.environ["TMSi_ENV"] == "MOCKED":
|
|
54
|
+
from .apex_API_mock import *
|
|
55
|
+
elif "TMSi_ENV" in os.environ and os.environ["TMSi_ENV"] == "MOCKED24":
|
|
56
|
+
from .apex_API_mock_24 import *
|
|
57
|
+
else:
|
|
58
|
+
from .apex_API import *
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ApexDevice(TMSiDevice):
|
|
62
|
+
"""A class to represent and handle the Apex"""
|
|
63
|
+
|
|
64
|
+
__apex_sdk = None
|
|
65
|
+
__MAX_NUM_DEVICES = 10
|
|
66
|
+
__MAX_NUM_DONGLES = 2
|
|
67
|
+
__device_info_list = []
|
|
68
|
+
__dongle_info_list = []
|
|
69
|
+
__DEVICE_TYPE = "APEX"
|
|
70
|
+
|
|
71
|
+
@LogPerformances
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
serial_number,
|
|
75
|
+
dr_interface: DeviceInterfaceType,
|
|
76
|
+
pairing_status=PairingStatus.no_pairing_needed,
|
|
77
|
+
dongle_serial_number=0,
|
|
78
|
+
idx=-1,
|
|
79
|
+
):
|
|
80
|
+
"""Initialize the Device.
|
|
81
|
+
|
|
82
|
+
:param dr_serial_number: Serial number of the device.
|
|
83
|
+
:type dr_serial_number: int
|
|
84
|
+
:param dr_interface: Interface to use to communicate with the device.
|
|
85
|
+
:type dr_interface: DeviceInterfaceType
|
|
86
|
+
:param dongle_serial_number: Serial number of the dongle, default to 0.
|
|
87
|
+
:type dongle_serial_number: int
|
|
88
|
+
:param idx: Device index, defaults to -1.
|
|
89
|
+
:type idx: int, optional
|
|
90
|
+
"""
|
|
91
|
+
self.__device_handle = DeviceHandle(0)
|
|
92
|
+
self.__info = ApexInfo(
|
|
93
|
+
id=idx,
|
|
94
|
+
serial_number=serial_number,
|
|
95
|
+
dr_interface=dr_interface,
|
|
96
|
+
dongle_serial_number=dongle_serial_number,
|
|
97
|
+
pairing_status=pairing_status,
|
|
98
|
+
)
|
|
99
|
+
self.__config = ApexConfig()
|
|
100
|
+
|
|
101
|
+
@LogPerformances
|
|
102
|
+
def close(self):
|
|
103
|
+
"""Closes the connection to the device.
|
|
104
|
+
|
|
105
|
+
:raises TMSiError: TMSiErrorCode.device_error if impossible to close.
|
|
106
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
107
|
+
"""
|
|
108
|
+
if self.__info.get_state() != DeviceState.disconnected:
|
|
109
|
+
self.__last_error_code = TMSiCloseInterface(self.__device_handle)
|
|
110
|
+
self.__info.set_state(DeviceState.disconnected)
|
|
111
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
112
|
+
return
|
|
113
|
+
else:
|
|
114
|
+
raise TMSiError(
|
|
115
|
+
TMSiErrorCode.device_error, self.__last_error_code
|
|
116
|
+
)
|
|
117
|
+
else:
|
|
118
|
+
raise TMSiError(TMSiErrorCode.device_not_connected)
|
|
119
|
+
|
|
120
|
+
@LogPerformances
|
|
121
|
+
def discover(dr_interface: DeviceInterfaceType, num_retries: int = 3):
|
|
122
|
+
"""Discovers available devices.
|
|
123
|
+
|
|
124
|
+
:param dr_interface: Device interface to be searched.
|
|
125
|
+
:type dr_interface: DeviceInterfaceType
|
|
126
|
+
:param num_retries: Number of retries, optional
|
|
127
|
+
:type num_reties: int
|
|
128
|
+
"""
|
|
129
|
+
if not ApexDllAvailable:
|
|
130
|
+
TMSiLogger().warning("APEX DLL not available.")
|
|
131
|
+
raise TMSiError(error_code=TMSiErrorCode.missing_dll)
|
|
132
|
+
if ApexDllLocked:
|
|
133
|
+
TMSiLogger().warning("APEX DLL already in use.")
|
|
134
|
+
raise TMSiError(error_code=TMSiErrorCode.already_in_use_dll)
|
|
135
|
+
ApexDevice.get_sdk() # if sdk already available, nothing happens, otherwise initialize
|
|
136
|
+
for i in range(ApexDevice.__MAX_NUM_DEVICES):
|
|
137
|
+
if (
|
|
138
|
+
ApexDevice.__device_info_list[i].get_dr_interface()
|
|
139
|
+
== dr_interface
|
|
140
|
+
):
|
|
141
|
+
ApexDevice.__device_info_list[i] = ApexInfo()
|
|
142
|
+
|
|
143
|
+
for i in range(ApexDevice.__MAX_NUM_DONGLES):
|
|
144
|
+
ApexDevice.__dongle_info_list[i] = DongleInfo()
|
|
145
|
+
|
|
146
|
+
device_list = (TMSiDevList * ApexDevice.__MAX_NUM_DEVICES)()
|
|
147
|
+
dongle_list = (TMSiDongleList * ApexDevice.__MAX_NUM_DONGLES)()
|
|
148
|
+
num_found_devices = (c_uint)(0)
|
|
149
|
+
num_found_dongles = (c_uint)(0)
|
|
150
|
+
|
|
151
|
+
ret = TMSiGetDongleList(
|
|
152
|
+
pointer(dongle_list),
|
|
153
|
+
ApexDevice.__MAX_NUM_DONGLES,
|
|
154
|
+
pointer(num_found_dongles),
|
|
155
|
+
)
|
|
156
|
+
if ret == TMSiDeviceRetVal.TMSiStatusOK:
|
|
157
|
+
for i in range(ApexDevice.__MAX_NUM_DONGLES):
|
|
158
|
+
if i < num_found_dongles.value:
|
|
159
|
+
ApexDevice.__dongle_info_list[i].TMSiDongleID = dongle_list[
|
|
160
|
+
i
|
|
161
|
+
].TMSiDongleID
|
|
162
|
+
ApexDevice.__dongle_info_list[i].SerialNumber = dongle_list[
|
|
163
|
+
i
|
|
164
|
+
].SerialNumber
|
|
165
|
+
else:
|
|
166
|
+
break
|
|
167
|
+
|
|
168
|
+
for i in range(ApexDevice.__MAX_NUM_DEVICES):
|
|
169
|
+
device_list[i].TMSiDeviceID = ApexConst.TMSI_DEVICE_ID_NONE
|
|
170
|
+
|
|
171
|
+
while num_retries > 0:
|
|
172
|
+
ret = TMSiGetDeviceList(
|
|
173
|
+
pointer(device_list),
|
|
174
|
+
ApexDevice.__MAX_NUM_DEVICES,
|
|
175
|
+
dr_interface.value,
|
|
176
|
+
pointer(num_found_devices),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
if ret == TMSiDeviceRetVal.TMSiStatusOK:
|
|
180
|
+
# Devices are found, update the local device list with the found result
|
|
181
|
+
for i in range(ApexDevice.__MAX_NUM_DEVICES):
|
|
182
|
+
if (
|
|
183
|
+
device_list[i].TMSiDeviceID
|
|
184
|
+
!= ApexConst.TMSI_DEVICE_ID_NONE
|
|
185
|
+
):
|
|
186
|
+
for ii in range(ApexDevice.__MAX_NUM_DEVICES):
|
|
187
|
+
if (
|
|
188
|
+
ApexDevice.__device_info_list[ii].get_id()
|
|
189
|
+
== ApexConst.TMSI_DEVICE_ID_NONE
|
|
190
|
+
):
|
|
191
|
+
ApexDevice.__device_info_list[ii].set_id(
|
|
192
|
+
device_list[i].TMSiDeviceID
|
|
193
|
+
)
|
|
194
|
+
ApexDevice.__device_info_list[
|
|
195
|
+
ii
|
|
196
|
+
].set_dr_interface(dr_interface)
|
|
197
|
+
ApexDevice.__device_info_list[
|
|
198
|
+
ii
|
|
199
|
+
].set_dr_serial_number(
|
|
200
|
+
device_list[i].SerialNumberDataRecorder
|
|
201
|
+
)
|
|
202
|
+
ApexDevice.__device_info_list[
|
|
203
|
+
ii
|
|
204
|
+
].set_dongle_serial_number(
|
|
205
|
+
device_list[i].SerialNumberDongle
|
|
206
|
+
)
|
|
207
|
+
ApexDevice.__device_info_list[
|
|
208
|
+
ii
|
|
209
|
+
].set_pairing_status(
|
|
210
|
+
device_list[i].PairingStatus
|
|
211
|
+
)
|
|
212
|
+
ApexDevice.__device_info_list[ii].set_state(
|
|
213
|
+
DeviceState.disconnected
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
num_retries = 0
|
|
217
|
+
break
|
|
218
|
+
num_retries -= 1
|
|
219
|
+
else:
|
|
220
|
+
num_retries -= 1
|
|
221
|
+
TMSiLogger().warning(
|
|
222
|
+
"Trying to open connection to device. Number of retries left: "
|
|
223
|
+
+ str(num_retries)
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
@LogPerformances
|
|
227
|
+
def download_file_from_device(self, file_id: int, filename: str = None):
|
|
228
|
+
"""Creates a data stream to download the file from the device.
|
|
229
|
+
|
|
230
|
+
:param file_id: id of the file to download.
|
|
231
|
+
:type file_id: int
|
|
232
|
+
:param verbosity: if True, writes information about the download stream, defaults to True.
|
|
233
|
+
:type verbosity: bool, optional
|
|
234
|
+
:param filename: filename where to write the impedance report (if available), defaults to None
|
|
235
|
+
:type filename: str, optional
|
|
236
|
+
:raises TMSiError: TMSiErrorCode.file_writer_error if impedance report download fails.
|
|
237
|
+
:raises TMSiError: TMSiErrorCode.device_error if the file download fails.
|
|
238
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if already sampling.
|
|
239
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
240
|
+
"""
|
|
241
|
+
header, metadata = self.get_device_card_file_info(file_id)
|
|
242
|
+
n_of_samples = metadata.NumberOfSamples
|
|
243
|
+
self.start_download_file(file_id, filename, n_of_samples)
|
|
244
|
+
|
|
245
|
+
while True:
|
|
246
|
+
percentage = self.__measurement.get_download_percentage()
|
|
247
|
+
if percentage >= 100:
|
|
248
|
+
break
|
|
249
|
+
if self.__measurement.is_timeout():
|
|
250
|
+
break
|
|
251
|
+
time.sleep(0.1)
|
|
252
|
+
|
|
253
|
+
self.stop_download_file()
|
|
254
|
+
|
|
255
|
+
@LogPerformances
|
|
256
|
+
def export_configuration(self, filename: str):
|
|
257
|
+
"""Exports the current configuration to an xml file.
|
|
258
|
+
|
|
259
|
+
:param filename: name of the file where to export configuration.
|
|
260
|
+
:type filename: str
|
|
261
|
+
:raises TMSiError: TMSiErrorCode.file_writer_error if export configuration fails.
|
|
262
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
263
|
+
"""
|
|
264
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
265
|
+
if self.__config.export_to_xml(filename):
|
|
266
|
+
return
|
|
267
|
+
else:
|
|
268
|
+
raise TMSiError(error_code=TMSiErrorCode.file_writer_error)
|
|
269
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
270
|
+
|
|
271
|
+
@LogPerformances
|
|
272
|
+
def import_configuration(self, filename: str):
|
|
273
|
+
"""Imports the file configuration to the device.
|
|
274
|
+
|
|
275
|
+
:param filename: name of the file where to export configuration.
|
|
276
|
+
:type filename: str
|
|
277
|
+
:raises TMSiError: TMSiErrorCode.general_error if import configuration fails.
|
|
278
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
279
|
+
"""
|
|
280
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
281
|
+
if self.__config.import_from_xml(filename):
|
|
282
|
+
self.__set_device_channel_config(
|
|
283
|
+
[
|
|
284
|
+
ch.get_channel_name()
|
|
285
|
+
for ch in self.__config.get_channels()
|
|
286
|
+
],
|
|
287
|
+
[i for i in range(len(self.__config.get_channels()))],
|
|
288
|
+
)
|
|
289
|
+
self.__set_device_reference_config(
|
|
290
|
+
[ch.is_reference() for ch in self.__config.get_channels()],
|
|
291
|
+
[i for i in range(len(self.__config.get_channels()))],
|
|
292
|
+
)
|
|
293
|
+
self.__set_device_sampling_config(
|
|
294
|
+
frequency=TMSiBaseSampleRate(
|
|
295
|
+
self.__config.get_sample_rate()
|
|
296
|
+
),
|
|
297
|
+
impedance_limit=self.__config.get_impedance_limit(),
|
|
298
|
+
live_impedance=TMSiLiveImpedance(
|
|
299
|
+
self.__config.get_live_impedance()
|
|
300
|
+
),
|
|
301
|
+
)
|
|
302
|
+
self.__load_config_from_device()
|
|
303
|
+
return
|
|
304
|
+
else:
|
|
305
|
+
raise TMSiError(error_code=TMSiErrorCode.general_error)
|
|
306
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
307
|
+
|
|
308
|
+
@LogPerformances
|
|
309
|
+
def get_card_recording_config(self) -> TMSiDevCardRecCfg:
|
|
310
|
+
"""Gets configuration for card recording.
|
|
311
|
+
|
|
312
|
+
:raises TMSiError: TMSiErrorCode.device_error if get configuration fails.
|
|
313
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
314
|
+
:return: Configuration of the card recording.
|
|
315
|
+
:rtype: TMSiDevCardRecCfg
|
|
316
|
+
"""
|
|
317
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
318
|
+
return self.__get_device_card_recording_config()
|
|
319
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
320
|
+
|
|
321
|
+
@LogPerformances
|
|
322
|
+
def get_card_status(self) -> TMSiDevCardStatus:
|
|
323
|
+
"""Gets card status.
|
|
324
|
+
|
|
325
|
+
:raises TMSiError: TMSiErrorCode.device_error if get card status fails.
|
|
326
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
327
|
+
:return: Configuration of the card recording.
|
|
328
|
+
:rtype: TMSiDevCardStatus
|
|
329
|
+
"""
|
|
330
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
331
|
+
return self.__get_device_card_status()
|
|
332
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
333
|
+
|
|
334
|
+
@LogPerformances
|
|
335
|
+
def get_device_active_channels(self):
|
|
336
|
+
"""Gets the list of active channels.
|
|
337
|
+
|
|
338
|
+
:raises TMSiError: TMSiErrorCode.device_error if get channels from the device fails.
|
|
339
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
340
|
+
:return: The list of channels
|
|
341
|
+
:rtype: list[ApexChannel]
|
|
342
|
+
"""
|
|
343
|
+
return self.get_device_channels()
|
|
344
|
+
|
|
345
|
+
@LogPerformances
|
|
346
|
+
def get_device_card_file_info(
|
|
347
|
+
self, file_id: int
|
|
348
|
+
) -> tuple[TMSiFileMetadataHeader, TMSiDevCardFileDetails]:
|
|
349
|
+
"""Gets the information of the file on the device's card.
|
|
350
|
+
|
|
351
|
+
:param file_id: Id of the file to be investigated.
|
|
352
|
+
:type file_id: int
|
|
353
|
+
:raises TMSiError: TMSiErrorCode.device_error if get card info fails.
|
|
354
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
355
|
+
:return: A tuple with file metadata and file details.
|
|
356
|
+
:rtype: tuple[TMSiFileMetadataHeader, TMSiDevCardFileDetails]
|
|
357
|
+
"""
|
|
358
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
359
|
+
metadata, _ = self.__get_device_card_file_metadata(file_id)
|
|
360
|
+
header = self.__get_device_card_file_metadata_header(file_id)
|
|
361
|
+
return (header, metadata)
|
|
362
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
363
|
+
|
|
364
|
+
@LogPerformances
|
|
365
|
+
def get_device_card_file_list(self) -> list[TMSiDevCardFileInfo]:
|
|
366
|
+
"""Gets the list of files available on the device's card.
|
|
367
|
+
|
|
368
|
+
:raises TMSiError: TMSiErrorCode.device_error if get card file list fails.
|
|
369
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
370
|
+
:return: A list of file info.
|
|
371
|
+
:rtype: list[TMSiDevCardFileInfo]
|
|
372
|
+
"""
|
|
373
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
374
|
+
return self.__get_device_card_file_list()
|
|
375
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
376
|
+
|
|
377
|
+
@LogPerformances
|
|
378
|
+
def get_device_channels(self) -> list[ApexChannel]:
|
|
379
|
+
"""Gets the list of channels.
|
|
380
|
+
|
|
381
|
+
:raises TMSiError: TMSiErrorCode.device_error if get channels from the device fails.
|
|
382
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
383
|
+
:return: The list of channels
|
|
384
|
+
:rtype: list[ApexChannel]
|
|
385
|
+
"""
|
|
386
|
+
if self.__info.get_state() == DeviceState.sampling:
|
|
387
|
+
return self.__config.get_channels()
|
|
388
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
389
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
390
|
+
(
|
|
391
|
+
device_channel_metadata,
|
|
392
|
+
device_cycling_state_metadata,
|
|
393
|
+
) = self.__get_device_sample_metadata()
|
|
394
|
+
(
|
|
395
|
+
device_channel_name_list,
|
|
396
|
+
device_channel_alt_name_list,
|
|
397
|
+
) = self.__get_device_channel_config()
|
|
398
|
+
device_reference_config = self.__get_device_reference_config()
|
|
399
|
+
channels = []
|
|
400
|
+
for i in range(self.get_num_channels()):
|
|
401
|
+
channel = ApexChannel()
|
|
402
|
+
channel.set_device_channel_information(device_channel_metadata[i])
|
|
403
|
+
channel.set_device_channel_names(
|
|
404
|
+
device_channel_name_list[i].ChanName.decode("windows-1252"),
|
|
405
|
+
device_channel_alt_name_list[i].AltChanName.decode(
|
|
406
|
+
"windows-1252"
|
|
407
|
+
),
|
|
408
|
+
)
|
|
409
|
+
if i < len(device_reference_config):
|
|
410
|
+
channel.set_device_reference(
|
|
411
|
+
device_reference_config[i].ChanRefStatus
|
|
412
|
+
)
|
|
413
|
+
else:
|
|
414
|
+
channel.set_device_reference(None)
|
|
415
|
+
channels.append(channel)
|
|
416
|
+
self.__config.set_channels(channels)
|
|
417
|
+
self.__get_device_impedance_metadata()
|
|
418
|
+
return self.__config.get_channels()
|
|
419
|
+
|
|
420
|
+
@LogPerformances
|
|
421
|
+
def get_device_data(
|
|
422
|
+
self,
|
|
423
|
+
POINTER_received_data_array: pointer,
|
|
424
|
+
buffer_size: int,
|
|
425
|
+
POINTER_num_of_sets: pointer,
|
|
426
|
+
POINTER_data_type: pointer,
|
|
427
|
+
) -> TMSiDeviceRetVal:
|
|
428
|
+
"""Gets data from the device during sampling.
|
|
429
|
+
|
|
430
|
+
:param POINTER_received_data_array: array that will contain the received data.
|
|
431
|
+
:type POINTER_received_data_array: pointer(array[c_float])
|
|
432
|
+
:param buffer_size: maximum size of the buffer.
|
|
433
|
+
:type buffer_size: int
|
|
434
|
+
:param POINTER_num_of_sets: number of sets of data received.
|
|
435
|
+
:type POINTER_num_of_sets: pointer(c_uint)
|
|
436
|
+
:param POINTER_data_type: type of data received.
|
|
437
|
+
:type POINTER_data_type: pointer(c_int)
|
|
438
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if device is notin samplin modeg
|
|
439
|
+
:return: return value of the call
|
|
440
|
+
:rtype: TMSiDeviceRetVal
|
|
441
|
+
"""
|
|
442
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
443
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
444
|
+
return TMSiGetDeviceData(
|
|
445
|
+
self.__device_handle,
|
|
446
|
+
POINTER_received_data_array,
|
|
447
|
+
buffer_size,
|
|
448
|
+
POINTER_num_of_sets,
|
|
449
|
+
POINTER_data_type,
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
@LogPerformances
|
|
453
|
+
def get_device_handle_value(self) -> int:
|
|
454
|
+
"""Returns the value of the device handle.
|
|
455
|
+
|
|
456
|
+
:return: Device handle.
|
|
457
|
+
:rtype: int
|
|
458
|
+
"""
|
|
459
|
+
return self.__device_handle.value
|
|
460
|
+
|
|
461
|
+
@LogPerformances
|
|
462
|
+
def get_device_impedance_channels(self) -> list[ApexImpedanceChannel]:
|
|
463
|
+
"""Gets the list of impedance channels.
|
|
464
|
+
|
|
465
|
+
:raises TMSiError: TMSiErrorCode.device_error if get channels from the device fails.
|
|
466
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
467
|
+
:return: The list of channels
|
|
468
|
+
:rtype: list[ApexChannel]
|
|
469
|
+
"""
|
|
470
|
+
self.get_device_channels()
|
|
471
|
+
return self.__config.get_impedance_channels()
|
|
472
|
+
|
|
473
|
+
@LogPerformances
|
|
474
|
+
def get_device_impedance_data(
|
|
475
|
+
self,
|
|
476
|
+
POINTER_received_data_array: pointer,
|
|
477
|
+
buffer_size: int,
|
|
478
|
+
POINTER_num_of_sets: pointer,
|
|
479
|
+
) -> TMSiDeviceRetVal:
|
|
480
|
+
"""Gets impedance data from the device during sampling.
|
|
481
|
+
|
|
482
|
+
:param POINTER_received_data_array: array that will contain the received data.
|
|
483
|
+
:type POINTER_received_data_array: pointer(array[TMSiImpedanceSample])
|
|
484
|
+
:param buffer_size: maximum size of the buffer.
|
|
485
|
+
:type buffer_size: int
|
|
486
|
+
:param POINTER_num_of_sets: number of sets of data received.
|
|
487
|
+
:type POINTER_num_of_sets: pointer
|
|
488
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if device is notin samplin modeg
|
|
489
|
+
:return: return value of the call
|
|
490
|
+
:rtype: TMSiDeviceRetVal
|
|
491
|
+
"""
|
|
492
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
493
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
494
|
+
return TMSiGetDeviceImpedanceData(
|
|
495
|
+
self.__device_handle,
|
|
496
|
+
POINTER_received_data_array,
|
|
497
|
+
buffer_size,
|
|
498
|
+
POINTER_num_of_sets,
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
@LogPerformances
|
|
502
|
+
def get_device_info_report(self) -> TMSiDevInfoReport:
|
|
503
|
+
"""Gets the report with device information.
|
|
504
|
+
|
|
505
|
+
:raises TMSiError: TMSiErrorCode.device_error if get device info from the device fails.
|
|
506
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
507
|
+
:return: the device info report.
|
|
508
|
+
:rtype: TMSiDevInfoReport
|
|
509
|
+
"""
|
|
510
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
511
|
+
device_info_report = self.__get_device_info_report()
|
|
512
|
+
self.__info.set_device_info_report(device_info_report)
|
|
513
|
+
return device_info_report
|
|
514
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
515
|
+
|
|
516
|
+
@LogPerformances
|
|
517
|
+
def get_device_interface_status(
|
|
518
|
+
self, interface=DeviceInterfaceType.bluetooth
|
|
519
|
+
) -> TMSiInterfaceStatus:
|
|
520
|
+
"""Gets the device interface status.
|
|
521
|
+
|
|
522
|
+
:param interface: interface to check, defaults to DeviceInterfaceType.bluetooth
|
|
523
|
+
:type interface: DeviceInterfaceType, optional
|
|
524
|
+
:raises TMSiError: TMSiErrorCode.device_error if get device interface status from the device fails.
|
|
525
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
526
|
+
:return: interface status of the device.
|
|
527
|
+
:rtype: TMSiInterfaceStatus
|
|
528
|
+
"""
|
|
529
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
530
|
+
device_interface_status = self.__get_device_interface_status(
|
|
531
|
+
interface
|
|
532
|
+
)
|
|
533
|
+
return device_interface_status
|
|
534
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
535
|
+
|
|
536
|
+
@LogPerformances
|
|
537
|
+
def get_device_list(
|
|
538
|
+
dr_interface: DeviceInterfaceType,
|
|
539
|
+
) -> list["ApexDevice"]:
|
|
540
|
+
"""Gets the list of available devices.
|
|
541
|
+
|
|
542
|
+
:param dr_interface: interface to check.
|
|
543
|
+
:type dr_interface: DeviceInterfaceType
|
|
544
|
+
:return: a list of available devices on the requested interface.
|
|
545
|
+
:rtype: list[ApexDevice]
|
|
546
|
+
"""
|
|
547
|
+
device_list = []
|
|
548
|
+
for idx in range(ApexDevice.__MAX_NUM_DEVICES):
|
|
549
|
+
if (
|
|
550
|
+
ApexDevice.__device_info_list[idx].get_id()
|
|
551
|
+
!= ApexConst.TMSI_DEVICE_ID_NONE
|
|
552
|
+
and ApexDevice.__device_info_list[idx].get_dr_interface()
|
|
553
|
+
== dr_interface
|
|
554
|
+
):
|
|
555
|
+
device_list.append(
|
|
556
|
+
ApexDevice(
|
|
557
|
+
dongle_serial_number=ApexDevice.__device_info_list[
|
|
558
|
+
idx
|
|
559
|
+
].get_dongle_serial_number(),
|
|
560
|
+
serial_number=ApexDevice.__device_info_list[
|
|
561
|
+
idx
|
|
562
|
+
].get_dr_serial_number(),
|
|
563
|
+
dr_interface=dr_interface,
|
|
564
|
+
idx=ApexDevice.__device_info_list[idx].get_id(),
|
|
565
|
+
pairing_status=ApexDevice.__device_info_list[
|
|
566
|
+
idx
|
|
567
|
+
].get_pairing_status(),
|
|
568
|
+
)
|
|
569
|
+
)
|
|
570
|
+
return device_list
|
|
571
|
+
|
|
572
|
+
@LogPerformances
|
|
573
|
+
def get_device_power_status(self) -> TMSiDevPowerStatus:
|
|
574
|
+
"""Returns the power status of the device
|
|
575
|
+
|
|
576
|
+
:raises TMSiError: TMSiErrorCode.device_error if get device power status from the device fails.
|
|
577
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
578
|
+
:return: device power status.
|
|
579
|
+
:rtype: TMSiDevPowerStatus
|
|
580
|
+
"""
|
|
581
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
582
|
+
return self.__get_device_power_status()
|
|
583
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
584
|
+
|
|
585
|
+
@LogPerformances
|
|
586
|
+
def get_device_sampling_config(self) -> TMSiDevSamplingCfg:
|
|
587
|
+
"""Gets the sampling configuration of the device.
|
|
588
|
+
|
|
589
|
+
:raises TMSiError: TMSiErrorCode.device_error if get device sampling configuration from the device fails.
|
|
590
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
591
|
+
:return: device sampling configuration
|
|
592
|
+
:rtype: TMSiDevSamplingCfg
|
|
593
|
+
"""
|
|
594
|
+
if self.__info.get_state() == DeviceState.connected:
|
|
595
|
+
device_sampling_config = self.__get_device_sampling_config()
|
|
596
|
+
self.__config.set_device_sampling_config(device_sampling_config)
|
|
597
|
+
return device_sampling_config
|
|
598
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
599
|
+
|
|
600
|
+
@LogPerformances
|
|
601
|
+
def get_device_sampling_frequency(self):
|
|
602
|
+
"""Gets the sampling frequency."""
|
|
603
|
+
return self.__config.get_sampling_frequency()
|
|
604
|
+
|
|
605
|
+
@LogPerformances
|
|
606
|
+
def get_device_serial_number(self) -> int:
|
|
607
|
+
"""Gets the serial number of the device.
|
|
608
|
+
|
|
609
|
+
:return: serial number of the device.
|
|
610
|
+
:rtype: int
|
|
611
|
+
"""
|
|
612
|
+
return self.__info.get_dr_serial_number()
|
|
613
|
+
|
|
614
|
+
@LogPerformances
|
|
615
|
+
def get_device_state(self) -> DeviceState:
|
|
616
|
+
"""Gets the state of the device.
|
|
617
|
+
|
|
618
|
+
:return: the device state.
|
|
619
|
+
:rtype: DeviceState
|
|
620
|
+
"""
|
|
621
|
+
return self.__info.get_state()
|
|
622
|
+
|
|
623
|
+
@LogPerformances
|
|
624
|
+
def get_device_time(self) -> datetime.datetime:
|
|
625
|
+
"""Gets the time on the device.
|
|
626
|
+
|
|
627
|
+
:raises TMSiError: TMSiErrorCode.device_error if get time from the device fails.
|
|
628
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
629
|
+
:return: returns the datetime on the device.
|
|
630
|
+
:rtype: datetime.datetime
|
|
631
|
+
"""
|
|
632
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
633
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
634
|
+
return self.__get_device_rtc()
|
|
635
|
+
|
|
636
|
+
@LogPerformances
|
|
637
|
+
def get_device_type(self) -> str:
|
|
638
|
+
"""Returns the device type.
|
|
639
|
+
|
|
640
|
+
:return: the device type.
|
|
641
|
+
:rtype: str
|
|
642
|
+
"""
|
|
643
|
+
return ApexDevice.__DEVICE_TYPE
|
|
644
|
+
|
|
645
|
+
@LogPerformances
|
|
646
|
+
def get_dongle_list() -> list[ApexDongle]:
|
|
647
|
+
"""Returns the list of available dongles.
|
|
648
|
+
|
|
649
|
+
:return: list of available dongles.
|
|
650
|
+
:rtype: list[ApexDongle]
|
|
651
|
+
"""
|
|
652
|
+
dongle_list = []
|
|
653
|
+
for idx in range(ApexDevice.__MAX_NUM_DONGLES):
|
|
654
|
+
if (
|
|
655
|
+
ApexDevice.__dongle_info_list[idx].TMSiDongleID
|
|
656
|
+
!= ApexConst.TMSI_DONGLE_ID_NONE
|
|
657
|
+
):
|
|
658
|
+
dongle_list.append(
|
|
659
|
+
ApexDongle(
|
|
660
|
+
ApexDevice.__dongle_info_list[idx].TMSiDongleID,
|
|
661
|
+
ApexDevice.__dongle_info_list[idx].SerialNumber,
|
|
662
|
+
)
|
|
663
|
+
)
|
|
664
|
+
return dongle_list
|
|
665
|
+
|
|
666
|
+
@LogPerformances
|
|
667
|
+
def get_dongle_serial_number(self) -> int:
|
|
668
|
+
"""Gets the serial number of the dongle.
|
|
669
|
+
|
|
670
|
+
:return: serial number of the device.
|
|
671
|
+
:rtype: int
|
|
672
|
+
"""
|
|
673
|
+
return self.__info.get_dongle_serial_number()
|
|
674
|
+
|
|
675
|
+
@LogPerformances
|
|
676
|
+
def get_downloaded_percentage(self) -> int:
|
|
677
|
+
"""Gets the percentage of file downloaded.
|
|
678
|
+
|
|
679
|
+
:return: percentage of file downloaded.
|
|
680
|
+
:rtype: int
|
|
681
|
+
"""
|
|
682
|
+
return self.__measurement.get_download_percentage()
|
|
683
|
+
|
|
684
|
+
@LogPerformances
|
|
685
|
+
def get_driver_version() -> tuple[str, str]:
|
|
686
|
+
"""Gets the version of the DLL and USB drivers.
|
|
687
|
+
|
|
688
|
+
:raises TMSiError: TMSiErrorCode.device_error if it fails.
|
|
689
|
+
:return: tuple(dll_version, usb_version)
|
|
690
|
+
:rtype: tuple(str, str)
|
|
691
|
+
"""
|
|
692
|
+
version = TMSiDeviceDriverVersionInfo()
|
|
693
|
+
__last_error = TMSiGetDeviceDriverVersionInfo(pointer(version))
|
|
694
|
+
if __last_error != TMSiDeviceRetVal.TMSiStatusOK:
|
|
695
|
+
raise TMSiError(
|
|
696
|
+
error_code=TMSiErrorCode.device_error,
|
|
697
|
+
dll_error_code=__last_error,
|
|
698
|
+
)
|
|
699
|
+
return version
|
|
700
|
+
|
|
701
|
+
@LogPerformances
|
|
702
|
+
def get_dr_interface(self) -> DeviceInterfaceType:
|
|
703
|
+
"""Returns the interface of the device.
|
|
704
|
+
|
|
705
|
+
:return: the interface of the device.
|
|
706
|
+
:rtype: DeviceInterfaceType
|
|
707
|
+
"""
|
|
708
|
+
return self.__info.get_dr_interface()
|
|
709
|
+
|
|
710
|
+
@LogPerformances
|
|
711
|
+
def get_event(POINTER_event):
|
|
712
|
+
"""Gets the last event available
|
|
713
|
+
|
|
714
|
+
:param POINTER_event: _description_
|
|
715
|
+
:type POINTER_event: _type_
|
|
716
|
+
:return: _description_
|
|
717
|
+
:rtype: _type_
|
|
718
|
+
"""
|
|
719
|
+
__last_error = TMSiGetEvent(POINTER_event)
|
|
720
|
+
if __last_error != TMSiDeviceRetVal.TMSiStatusOK:
|
|
721
|
+
raise TMSiError(
|
|
722
|
+
error_code=TMSiErrorCode.device_error,
|
|
723
|
+
dll_error_code=__last_error,
|
|
724
|
+
)
|
|
725
|
+
|
|
726
|
+
@LogPerformances
|
|
727
|
+
def get_event_buffer(POINTER_num_found_events):
|
|
728
|
+
"""Gets the available events in the buffer
|
|
729
|
+
|
|
730
|
+
:return: TMSiDeviceRetVal.TMSiStatusOK
|
|
731
|
+
:rtype: TMSiDeviceRetVal
|
|
732
|
+
"""
|
|
733
|
+
return TMSiGetEventBuffered(POINTER_num_found_events)
|
|
734
|
+
|
|
735
|
+
@LogPerformances
|
|
736
|
+
def get_id(self) -> int:
|
|
737
|
+
"""Gets the device id.
|
|
738
|
+
|
|
739
|
+
:return: the device id.
|
|
740
|
+
:rtype: int
|
|
741
|
+
"""
|
|
742
|
+
return self.__info.get_id()
|
|
743
|
+
|
|
744
|
+
@LogPerformances
|
|
745
|
+
def get_live_impedance(self) -> bool:
|
|
746
|
+
"""Returns if live impedance is enabled.
|
|
747
|
+
|
|
748
|
+
:return: True if enabled, False if disabled.
|
|
749
|
+
:rtype: bool
|
|
750
|
+
"""
|
|
751
|
+
return self.__config.get_live_impedance()
|
|
752
|
+
|
|
753
|
+
@LogPerformances
|
|
754
|
+
def get_num_channels(self) -> int:
|
|
755
|
+
"""Returns the number of channels of the device.
|
|
756
|
+
|
|
757
|
+
:return: number of channels of the device.
|
|
758
|
+
:rtype: int
|
|
759
|
+
"""
|
|
760
|
+
return self.__info.get_num_channels()
|
|
761
|
+
|
|
762
|
+
@LogPerformances
|
|
763
|
+
def get_num_impedance_channels(self) -> int:
|
|
764
|
+
"""Returns the number of impedance channels of the device.
|
|
765
|
+
|
|
766
|
+
:return: number of impedance channels of the device.
|
|
767
|
+
:rtype: int
|
|
768
|
+
"""
|
|
769
|
+
return self.__info.get_num_impedance_channels()
|
|
770
|
+
|
|
771
|
+
@LogPerformances
|
|
772
|
+
def get_sdk() -> CDLL:
|
|
773
|
+
"""Gets the handle of the communication library
|
|
774
|
+
|
|
775
|
+
:return: the handle of the communication library.
|
|
776
|
+
:rtype: CDLL
|
|
777
|
+
"""
|
|
778
|
+
if ApexDevice.__apex_sdk is None:
|
|
779
|
+
ApexDevice.__initialize()
|
|
780
|
+
return ApexDevice.__apex_sdk
|
|
781
|
+
|
|
782
|
+
@LogPerformances
|
|
783
|
+
def open(self, dongle_id=ApexConst.TMSI_DONGLE_ID_NONE):
|
|
784
|
+
"""Opens the connection with the device.
|
|
785
|
+
|
|
786
|
+
:param dongle_id: Id of the dongle to use for the connection. Defaults to ApexConst.TMSI_DONGLE_ID_NONE
|
|
787
|
+
:type dongle_id: int, optional
|
|
788
|
+
:raises TMSiError: TMSiErrorCode.device_error if get time from the device fails.
|
|
789
|
+
:raises TMSiError: TMSiErrorCode.no_devices_found if device not found.
|
|
790
|
+
"""
|
|
791
|
+
self.__info.set_dongle_id(dongle_id)
|
|
792
|
+
if self.__info.get_id() != ApexConst.TMSI_DEVICE_ID_NONE:
|
|
793
|
+
self.__last_error_code = TMSiOpenInterface(
|
|
794
|
+
pointer(self.__device_handle),
|
|
795
|
+
dongle_id,
|
|
796
|
+
self.__info.get_id(),
|
|
797
|
+
self.__info.get_dr_interface().value,
|
|
798
|
+
)
|
|
799
|
+
if (
|
|
800
|
+
self.__last_error_code
|
|
801
|
+
== TMSiDeviceRetVal.TMSiStatusDrInterfaceAlreadyOpen
|
|
802
|
+
):
|
|
803
|
+
# The found device is available but in it's open-state: Close and re-open the connection
|
|
804
|
+
self.__last_error_code = TMSiCloseInterface(
|
|
805
|
+
self.__device_handle, self.__info.get_dr_interface().value
|
|
806
|
+
)
|
|
807
|
+
self.__last_error_code = TMSiOpenInterface(
|
|
808
|
+
pointer(self.__device_handle),
|
|
809
|
+
dongle_id,
|
|
810
|
+
self.__info.get_id(),
|
|
811
|
+
self.__info.get_dr_interface().value,
|
|
812
|
+
)
|
|
813
|
+
|
|
814
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
815
|
+
# The device is opened succesfully. Update the device information.
|
|
816
|
+
self.__info.set_state(DeviceState.connected)
|
|
817
|
+
|
|
818
|
+
# Read the device's configuration
|
|
819
|
+
self.__load_config_from_device()
|
|
820
|
+
|
|
821
|
+
else:
|
|
822
|
+
raise TMSiError(
|
|
823
|
+
error_code=TMSiErrorCode.device_error,
|
|
824
|
+
dll_error_code=self.__last_error_code,
|
|
825
|
+
)
|
|
826
|
+
else:
|
|
827
|
+
raise TMSiError(error_code=TMSiErrorCode.no_devices_found)
|
|
828
|
+
|
|
829
|
+
@LogPerformances
|
|
830
|
+
def pair_device(dongle_id: int, device_id: int) -> TMSiDeviceRetVal:
|
|
831
|
+
"""Pairs the device with the dongle
|
|
832
|
+
|
|
833
|
+
:param dongle_id: Id of the dongle
|
|
834
|
+
:type dongle_id: int
|
|
835
|
+
:param device_id: Id of the device
|
|
836
|
+
:type device_id: int
|
|
837
|
+
:return: return value of the call
|
|
838
|
+
:rtype: TMSiDeviceRetVal
|
|
839
|
+
"""
|
|
840
|
+
ret = TMSiPairDevice(dongle_id, device_id)
|
|
841
|
+
if ret == TMSiDeviceRetVal.TMSiStatusDllCommandInProgress:
|
|
842
|
+
TMSiLogger().info("Pairing ongoing")
|
|
843
|
+
elif ret == TMSiDeviceRetVal.TMSiStatusDllDeviceAlreadyPaired:
|
|
844
|
+
TMSiLogger().warning("Device already paired")
|
|
845
|
+
else:
|
|
846
|
+
TMSiLogger().warning("Pairing process failed")
|
|
847
|
+
return ret
|
|
848
|
+
|
|
849
|
+
@LogPerformances
|
|
850
|
+
def reset_device_card(self):
|
|
851
|
+
"""Resets the memory card of the device.
|
|
852
|
+
|
|
853
|
+
:raises TMSiError: TMSiErrorCode.device_error if reset card fails.
|
|
854
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
855
|
+
"""
|
|
856
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
857
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
858
|
+
self.__reset_device_card()
|
|
859
|
+
|
|
860
|
+
@LogPerformances
|
|
861
|
+
def reset_device_data_buffer(self):
|
|
862
|
+
"""Resets the incoming buffer.
|
|
863
|
+
|
|
864
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if device is notin samplin modeg
|
|
865
|
+
:raises TMSiError: TMSiErrorCode.device_error if reset fails
|
|
866
|
+
"""
|
|
867
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
868
|
+
raise TMSiError(TMSiErrorCode.api_invalid_command)
|
|
869
|
+
self.__last_error_code = TMSiResetDeviceDataBuffer(self.__device_handle)
|
|
870
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
871
|
+
return
|
|
872
|
+
else:
|
|
873
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
874
|
+
|
|
875
|
+
@LogPerformances
|
|
876
|
+
def reset_device_event_buffer():
|
|
877
|
+
"""Resets the incoming event buffer.
|
|
878
|
+
|
|
879
|
+
:raises TMSiError: TMSiErrorCode.device_error if reset fails
|
|
880
|
+
"""
|
|
881
|
+
__last_error_code = TMSiResetEventBuffer()
|
|
882
|
+
if __last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
883
|
+
return
|
|
884
|
+
else:
|
|
885
|
+
raise TMSiError(TMSiErrorCode.device_error, __last_error_code)
|
|
886
|
+
|
|
887
|
+
@LogPerformances
|
|
888
|
+
def reset_to_factory_default(self):
|
|
889
|
+
"""Resets the device to default configuration.
|
|
890
|
+
|
|
891
|
+
:raises TMSiError: TMSiErrorCode.device_error if reset fails.
|
|
892
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
893
|
+
"""
|
|
894
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
895
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
896
|
+
self.__set_device_factory_default()
|
|
897
|
+
self.__load_config_from_device()
|
|
898
|
+
|
|
899
|
+
@LogPerformances
|
|
900
|
+
def set_card_recording_config(
|
|
901
|
+
self, config: TMSiDevCardRecCfg
|
|
902
|
+
) -> TMSiDevCardRecCfg:
|
|
903
|
+
"""Sets the configuration for recording on card.
|
|
904
|
+
|
|
905
|
+
:param config: configuration to be set.
|
|
906
|
+
:type config: TMSiDevCardRecCfg
|
|
907
|
+
:raises TMSiError: TMSiErrorCode.device_error if set configuration fails.
|
|
908
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
909
|
+
:return: the new available configuration for recording on card.
|
|
910
|
+
:rtype: TMSiDevCardRecCfg
|
|
911
|
+
"""
|
|
912
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
913
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
914
|
+
self.__set_device_card_recording_config(config)
|
|
915
|
+
return self.__get_device_card_recording_config()
|
|
916
|
+
|
|
917
|
+
@LogPerformances
|
|
918
|
+
def set_device_channel_names(
|
|
919
|
+
self, names: list[str], indices: list[int]
|
|
920
|
+
) -> list[ApexChannel]:
|
|
921
|
+
"""Sets the device channel names
|
|
922
|
+
|
|
923
|
+
:param names: names to be set.
|
|
924
|
+
:type names: list[str]
|
|
925
|
+
:param indices: index of the channels to edit.
|
|
926
|
+
:type indices: list[int]
|
|
927
|
+
:raises TMSiError: TMSiErrorCode.device_error if set names fails.
|
|
928
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
929
|
+
:raises TypeError: if names is not only strings
|
|
930
|
+
:raises TypeError: if indices is not only integers.
|
|
931
|
+
:return: list of new channels.
|
|
932
|
+
:rtype: list[ApexChannel]
|
|
933
|
+
"""
|
|
934
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
935
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
936
|
+
for name in names:
|
|
937
|
+
if not isinstance(name, str):
|
|
938
|
+
raise TypeError("names must be strings")
|
|
939
|
+
for index in indices:
|
|
940
|
+
if not isinstance(index, int):
|
|
941
|
+
raise TypeError("indices must be integers")
|
|
942
|
+
self.__set_device_channel_config(names, indices)
|
|
943
|
+
return self.get_device_channels()
|
|
944
|
+
|
|
945
|
+
@LogPerformances
|
|
946
|
+
def set_device_download_file_request(
|
|
947
|
+
self, file_request: TMSiDevSetCardFileReq
|
|
948
|
+
):
|
|
949
|
+
"""Sets the download file request to start or stop the download stream.
|
|
950
|
+
|
|
951
|
+
:param file_request: file request to start or stop.
|
|
952
|
+
:type file_request: TMSiDevSetCardFileReq
|
|
953
|
+
:raises TMSiError: TMSiErrorCode.device_error if set impedance request fails.
|
|
954
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if device is not in sampling mode.
|
|
955
|
+
"""
|
|
956
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
957
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
958
|
+
self.__last_error_code = TMSiSetDeviceCardFileRequest(
|
|
959
|
+
self.__device_handle, pointer(file_request)
|
|
960
|
+
)
|
|
961
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
962
|
+
return
|
|
963
|
+
else:
|
|
964
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
965
|
+
|
|
966
|
+
@LogPerformances
|
|
967
|
+
def set_device_impedance_request(
|
|
968
|
+
self, measurement_request: TMSiDevImpedanceRequest
|
|
969
|
+
):
|
|
970
|
+
"""Sets the impedance request to start or stop the acquisition.
|
|
971
|
+
|
|
972
|
+
:param measurement_request: measurement request to start or stop.
|
|
973
|
+
:type measurement_request: TMSiSetDeviceImpedanceRequest
|
|
974
|
+
:raises TMSiError: TMSiErrorCode.device_error if set impedance request fails.
|
|
975
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if device is not in sampling mode.
|
|
976
|
+
"""
|
|
977
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
978
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
979
|
+
self.__last_error_code = TMSiSetDeviceImpedanceRequest(
|
|
980
|
+
self.__device_handle, pointer(measurement_request)
|
|
981
|
+
)
|
|
982
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
983
|
+
return
|
|
984
|
+
else:
|
|
985
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
986
|
+
|
|
987
|
+
@LogPerformances
|
|
988
|
+
def set_device_interface(
|
|
989
|
+
self,
|
|
990
|
+
device_interface=DeviceInterfaceType.bluetooth,
|
|
991
|
+
control=TMSiControl.ControlEnabled,
|
|
992
|
+
) -> TMSiDevCardStatus:
|
|
993
|
+
"""Set the device interface.
|
|
994
|
+
|
|
995
|
+
:param device_interface: the interface to set, defaults to DeviceInterfaceType.bluetooth
|
|
996
|
+
:type device_interface: DeviceInterfaceType, optional
|
|
997
|
+
:param control: enable or disable interface, defaults to TMSiControl.ControlEnabled
|
|
998
|
+
:type control: TMSiControl, optional
|
|
999
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1000
|
+
:return: the new status of the device interface.
|
|
1001
|
+
:rtype: TMSiDevCardStatus
|
|
1002
|
+
"""
|
|
1003
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
1004
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
1005
|
+
self.__set_device_interface_config(
|
|
1006
|
+
device_interface=device_interface, control=control
|
|
1007
|
+
)
|
|
1008
|
+
return self.get_device_interface_status(device_interface)
|
|
1009
|
+
|
|
1010
|
+
@LogPerformances
|
|
1011
|
+
def set_device_references(
|
|
1012
|
+
self, list_references: list[int], list_indices: list[int]
|
|
1013
|
+
):
|
|
1014
|
+
"""Sets the channels to be used as reference.
|
|
1015
|
+
|
|
1016
|
+
:param list_references: list of reference values.
|
|
1017
|
+
:type list_references: list[int]
|
|
1018
|
+
:param list_indices: list of indices to be edited.
|
|
1019
|
+
:type list_indices: list[int]
|
|
1020
|
+
:raises TMSiError: TMSiErrorCode.device_error if set references fails.
|
|
1021
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1022
|
+
:raises TypeError: if references is not only integers
|
|
1023
|
+
:raises TypeError: if indices is not only integers.
|
|
1024
|
+
:return: list of new channels.
|
|
1025
|
+
:rtype: list[ApexChannel]
|
|
1026
|
+
"""
|
|
1027
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
1028
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
1029
|
+
for index in list_indices:
|
|
1030
|
+
if not isinstance(index, int):
|
|
1031
|
+
raise TypeError("indices must be integers")
|
|
1032
|
+
for reference in list_references:
|
|
1033
|
+
if not isinstance(reference, int):
|
|
1034
|
+
raise TypeError("references must be integers")
|
|
1035
|
+
self.__set_device_reference_config(
|
|
1036
|
+
list_references=list_references, list_indices=list_indices
|
|
1037
|
+
)
|
|
1038
|
+
return self.get_device_channels()
|
|
1039
|
+
|
|
1040
|
+
@LogPerformances
|
|
1041
|
+
def set_device_sampling_config(
|
|
1042
|
+
self,
|
|
1043
|
+
sampling_frequency=TMSiBaseSampleRate.Decimal,
|
|
1044
|
+
live_impedance=TMSiLiveImpedance.On,
|
|
1045
|
+
impedance_limit=0,
|
|
1046
|
+
) -> TMSiDevSamplingCfg:
|
|
1047
|
+
"""Sets the sampling configuration of the device.
|
|
1048
|
+
|
|
1049
|
+
:param sampling_frequency: sample rate to set, defaults to TMSiBaseSampleRate.Decimal
|
|
1050
|
+
:type sampling_frequency: TMSiBaseSampleRate, optional
|
|
1051
|
+
:param live_impedance: enable or disable live impedance, defaults to TMSiLiveImpedance.On
|
|
1052
|
+
:type live_impedance: TMSiLiveImpedance, optional
|
|
1053
|
+
:param impedance_limit: kOhms value of the impedance limit, defaults to 0
|
|
1054
|
+
:type impedance_limit: int, optional
|
|
1055
|
+
:raises TMSiError: TMSiErrorCode.device_error if set sampling configuration fails.
|
|
1056
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1057
|
+
:return: the new sampling configuration
|
|
1058
|
+
:rtype: TMSiDevSamplingCfg
|
|
1059
|
+
"""
|
|
1060
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
1061
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
1062
|
+
self.__set_device_sampling_config(
|
|
1063
|
+
frequency=sampling_frequency,
|
|
1064
|
+
live_impedance=live_impedance,
|
|
1065
|
+
impedance_limit=impedance_limit,
|
|
1066
|
+
)
|
|
1067
|
+
return self.get_device_sampling_config()
|
|
1068
|
+
|
|
1069
|
+
@LogPerformances
|
|
1070
|
+
def set_device_sampling_request(
|
|
1071
|
+
self, measurement_request: TMSiDevSampleRequest
|
|
1072
|
+
):
|
|
1073
|
+
"""Sets the sampling request to start or stop the acquisition.
|
|
1074
|
+
|
|
1075
|
+
:param measurement_request: measurement request to configure the acquisition.
|
|
1076
|
+
:type measurement_request: TMSiDevSampleRequest
|
|
1077
|
+
:raises TMSiError: TMSiErrorCode.device_error if set sampling request fails.
|
|
1078
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if device is not in sampling mode.
|
|
1079
|
+
"""
|
|
1080
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
1081
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
1082
|
+
self.__last_error_code = TMSiSetDeviceSamplingRequest(
|
|
1083
|
+
self.__device_handle, pointer(measurement_request)
|
|
1084
|
+
)
|
|
1085
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1086
|
+
return
|
|
1087
|
+
else:
|
|
1088
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1089
|
+
|
|
1090
|
+
@LogPerformances
|
|
1091
|
+
def set_device_time(self, datetime: datetime.datetime):
|
|
1092
|
+
"""Sets the datetime of the device.
|
|
1093
|
+
|
|
1094
|
+
:param datetime: datetime to set on the device.
|
|
1095
|
+
:type datetime: datetime.datetime
|
|
1096
|
+
:raises TMSiError: TMSiErrorCode.device_error if set time fails.
|
|
1097
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1098
|
+
"""
|
|
1099
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
1100
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
1101
|
+
self.__set_device_rtc(datetime)
|
|
1102
|
+
|
|
1103
|
+
@LogPerformances
|
|
1104
|
+
def start_download_file(
|
|
1105
|
+
self, file_id: int, filename: str = None, n_of_samples: int = None
|
|
1106
|
+
):
|
|
1107
|
+
"""Starts the download of the file requested.
|
|
1108
|
+
|
|
1109
|
+
:param file_id: id of the file to download.
|
|
1110
|
+
:type file_id: int
|
|
1111
|
+
:param filename: filename where to write the impedance report (if available), defaults to None
|
|
1112
|
+
:type filename: str, optional
|
|
1113
|
+
:raises TMSiError: TMSiErrorCode.file_writer_error if impedance report download fails.
|
|
1114
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if already sampling.
|
|
1115
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1116
|
+
"""
|
|
1117
|
+
if self.__info.get_state() == DeviceState.sampling:
|
|
1118
|
+
raise TMSiError(TMSiErrorCode.api_invalid_command)
|
|
1119
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
1120
|
+
raise TMSiError(TMSiErrorCode.device_not_connected)
|
|
1121
|
+
if filename is not None:
|
|
1122
|
+
self.__download_impedance_report(file_id, filename)
|
|
1123
|
+
self.__measurement = MeasurementType.APEX_DOWNLOAD(
|
|
1124
|
+
self, file_id, n_of_samples
|
|
1125
|
+
)
|
|
1126
|
+
self.__info.set_state(DeviceState.sampling)
|
|
1127
|
+
self.__measurement.start()
|
|
1128
|
+
|
|
1129
|
+
@LogPerformances
|
|
1130
|
+
def start_measurement(
|
|
1131
|
+
self, measurement_type: MeasurementType, thread_refresh=None
|
|
1132
|
+
):
|
|
1133
|
+
"""Starts the measurement requested.
|
|
1134
|
+
|
|
1135
|
+
:param measurement_type: measurement to start
|
|
1136
|
+
:type measurement_type: MeasurementType
|
|
1137
|
+
:param thread_refresh: refresh time for sampling and conversion threads, defaults to None.
|
|
1138
|
+
:type thread_refresh: float, optional.
|
|
1139
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if already sampling.
|
|
1140
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1141
|
+
"""
|
|
1142
|
+
if self.__info.get_state() == DeviceState.sampling:
|
|
1143
|
+
raise TMSiError(TMSiErrorCode.api_invalid_command)
|
|
1144
|
+
if self.__info.get_state() != DeviceState.connected:
|
|
1145
|
+
raise TMSiError(error_code=TMSiErrorCode.device_not_connected)
|
|
1146
|
+
self.__measurement = measurement_type(self)
|
|
1147
|
+
if thread_refresh is not None:
|
|
1148
|
+
self.__measurement.set_sampling_pause(thread_refresh)
|
|
1149
|
+
self.__measurement.set_conversion_pause(thread_refresh)
|
|
1150
|
+
self.__info.set_state(DeviceState.sampling)
|
|
1151
|
+
self.__measurement.start()
|
|
1152
|
+
|
|
1153
|
+
@LogPerformances
|
|
1154
|
+
def stop_download_file(self):
|
|
1155
|
+
"""Stops the download of the file.
|
|
1156
|
+
|
|
1157
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if not sampling.
|
|
1158
|
+
"""
|
|
1159
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
1160
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
1161
|
+
self.__measurement.stop()
|
|
1162
|
+
self.__info.set_state(DeviceState.connected)
|
|
1163
|
+
|
|
1164
|
+
@LogPerformances
|
|
1165
|
+
def stop_measurement(self):
|
|
1166
|
+
"""Stops the measurement requested.
|
|
1167
|
+
|
|
1168
|
+
:param file_id: id of the file to download.
|
|
1169
|
+
:type file_id: int
|
|
1170
|
+
:raises TMSiError: TMSiErrorCode.api_invalid_command if already sampling.
|
|
1171
|
+
:raises TMSiError: TMSiErrorCode.device_not_connected if not connected.
|
|
1172
|
+
"""
|
|
1173
|
+
if self.__info.get_state() != DeviceState.sampling:
|
|
1174
|
+
raise TMSiError(error_code=TMSiErrorCode.api_invalid_command)
|
|
1175
|
+
self.__measurement.stop()
|
|
1176
|
+
self.__info.set_state(DeviceState.connected)
|
|
1177
|
+
|
|
1178
|
+
@LogPerformances
|
|
1179
|
+
def __initialize():
|
|
1180
|
+
try:
|
|
1181
|
+
ApexDevice.__apex_sdk = ApexSDK
|
|
1182
|
+
for i in range(ApexDevice.__MAX_NUM_DEVICES):
|
|
1183
|
+
ApexDevice.__device_info_list.append(ApexInfo())
|
|
1184
|
+
for i in range(ApexDevice.__MAX_NUM_DONGLES):
|
|
1185
|
+
ApexDevice.__dongle_info_list.append(DongleInfo())
|
|
1186
|
+
except:
|
|
1187
|
+
ApexDevice.__apex_sdk = None
|
|
1188
|
+
raise TMSiError(error_code=TMSiErrorCode.api_no_driver)
|
|
1189
|
+
|
|
1190
|
+
@LogPerformances
|
|
1191
|
+
def __download_impedance_report(self, file_id, filename):
|
|
1192
|
+
(
|
|
1193
|
+
card_file_details,
|
|
1194
|
+
impedance_report_list,
|
|
1195
|
+
) = self.__get_device_card_file_metadata(file_id)
|
|
1196
|
+
try:
|
|
1197
|
+
with open("{}.txt".format(filename), "w") as f:
|
|
1198
|
+
f.write("{}\n\n".format(card_file_details.RecFileName.decode()))
|
|
1199
|
+
f.write("Idx\t\tName\t\tRe\t\t\tIm\n")
|
|
1200
|
+
f.write(
|
|
1201
|
+
"\n".join(
|
|
1202
|
+
[
|
|
1203
|
+
"{}\t\t{}\t\t{} kOhm\t\t{} nF".format(
|
|
1204
|
+
i.ChanIdx,
|
|
1205
|
+
i.ChanName.decode(),
|
|
1206
|
+
i.ImpedanceRe,
|
|
1207
|
+
i.ImpedanceIm,
|
|
1208
|
+
)
|
|
1209
|
+
for i in impedance_report_list
|
|
1210
|
+
]
|
|
1211
|
+
)
|
|
1212
|
+
)
|
|
1213
|
+
except Exception as e:
|
|
1214
|
+
raise TMSiError(TMSiErrorCode.file_writer_error)
|
|
1215
|
+
|
|
1216
|
+
@LogPerformances
|
|
1217
|
+
def __get_device_card_file_list(self):
|
|
1218
|
+
file_list = (2000 * TMSiDevCardFileInfo)()
|
|
1219
|
+
file_number = (c_uint)(0)
|
|
1220
|
+
self.__last_error_code = TMSiGetDeviceCardFileList(
|
|
1221
|
+
self.__device_handle,
|
|
1222
|
+
pointer(file_list),
|
|
1223
|
+
len(file_list),
|
|
1224
|
+
pointer(file_number),
|
|
1225
|
+
)
|
|
1226
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1227
|
+
return_list = []
|
|
1228
|
+
for i in range(file_number.value):
|
|
1229
|
+
return_list.append(file_list[i])
|
|
1230
|
+
return return_list
|
|
1231
|
+
else:
|
|
1232
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1233
|
+
|
|
1234
|
+
@LogPerformances
|
|
1235
|
+
def __get_device_card_file_metadata(self, file_id):
|
|
1236
|
+
RecFileID = file_id
|
|
1237
|
+
DevCardFileDetails = TMSiDevCardFileDetails()
|
|
1238
|
+
ChannelMetadataList = (self.get_num_channels() * TMSiChannelMetadata)()
|
|
1239
|
+
ChannelMetadataListLen = self.get_num_channels()
|
|
1240
|
+
RetChannelMetadataListLen = (c_uint)(0)
|
|
1241
|
+
CyclingStateMetadataList = (
|
|
1242
|
+
self.get_num_channels() * TMSiCyclingStateMetadata
|
|
1243
|
+
)()
|
|
1244
|
+
CyclingStateMetadataListLen = self.get_num_channels()
|
|
1245
|
+
RetCyclingStatMetadataListLen = (c_uint)(0)
|
|
1246
|
+
ImpReportMetadata = TMSiDevImpReportMetadata()
|
|
1247
|
+
ImpedanceReportList = (self.get_num_channels() * TMSiDevImpReport)()
|
|
1248
|
+
ImpedanceReportListLen = self.get_num_channels()
|
|
1249
|
+
RetImpedanceReportListLen = (c_uint)(0)
|
|
1250
|
+
self.__last_error_code = TMSiGetDeviceCardFileMetadata(
|
|
1251
|
+
self.__device_handle,
|
|
1252
|
+
RecFileID,
|
|
1253
|
+
pointer(DevCardFileDetails),
|
|
1254
|
+
pointer(ChannelMetadataList),
|
|
1255
|
+
ChannelMetadataListLen,
|
|
1256
|
+
pointer(RetChannelMetadataListLen),
|
|
1257
|
+
pointer(CyclingStateMetadataList),
|
|
1258
|
+
CyclingStateMetadataListLen,
|
|
1259
|
+
pointer(RetCyclingStatMetadataListLen),
|
|
1260
|
+
pointer(ImpReportMetadata),
|
|
1261
|
+
pointer(ImpedanceReportList),
|
|
1262
|
+
ImpedanceReportListLen,
|
|
1263
|
+
pointer(RetImpedanceReportListLen),
|
|
1264
|
+
)
|
|
1265
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1266
|
+
return (
|
|
1267
|
+
DevCardFileDetails,
|
|
1268
|
+
ImpedanceReportList[0 : RetImpedanceReportListLen.value],
|
|
1269
|
+
)
|
|
1270
|
+
else:
|
|
1271
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1272
|
+
|
|
1273
|
+
@LogPerformances
|
|
1274
|
+
def __get_device_card_file_metadata_header(self, file_id):
|
|
1275
|
+
metadata = TMSiFileMetadataHeader()
|
|
1276
|
+
self.__last_error_code = TMSiGetDeviceCardFileMetadataHeader(
|
|
1277
|
+
self.__device_handle, file_id, pointer(metadata)
|
|
1278
|
+
)
|
|
1279
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1280
|
+
return metadata
|
|
1281
|
+
else:
|
|
1282
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1283
|
+
|
|
1284
|
+
@LogPerformances
|
|
1285
|
+
def __get_device_card_recording_config(self):
|
|
1286
|
+
config = TMSiDevCardRecCfg()
|
|
1287
|
+
self.__last_error_code = TMSiGetDeviceCardRecordingConfig(
|
|
1288
|
+
self.__device_handle, pointer(config)
|
|
1289
|
+
)
|
|
1290
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1291
|
+
return config
|
|
1292
|
+
else:
|
|
1293
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1294
|
+
|
|
1295
|
+
@LogPerformances
|
|
1296
|
+
def __get_device_card_status(self):
|
|
1297
|
+
card_status = TMSiDevCardStatus()
|
|
1298
|
+
self.__last_error_code = TMSiGetDeviceCardStatus(
|
|
1299
|
+
self.__device_handle, pointer(card_status)
|
|
1300
|
+
)
|
|
1301
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1302
|
+
return card_status
|
|
1303
|
+
else:
|
|
1304
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1305
|
+
|
|
1306
|
+
@LogPerformances
|
|
1307
|
+
def __get_device_channel_config(self):
|
|
1308
|
+
device_channel_alt_name_list = (
|
|
1309
|
+
TMSiDevAltChName * self.get_num_channels()
|
|
1310
|
+
)()
|
|
1311
|
+
device_channel_name_list = (TMSiDevChName * self.get_num_channels())()
|
|
1312
|
+
num_returned_items = (c_uint)(0)
|
|
1313
|
+
self.__last_error_code = TMSiGetDeviceChannelConfig(
|
|
1314
|
+
self.__device_handle,
|
|
1315
|
+
pointer(device_channel_name_list),
|
|
1316
|
+
pointer(device_channel_alt_name_list),
|
|
1317
|
+
self.get_num_channels(),
|
|
1318
|
+
pointer(num_returned_items),
|
|
1319
|
+
)
|
|
1320
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1321
|
+
return device_channel_name_list, device_channel_alt_name_list
|
|
1322
|
+
else:
|
|
1323
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1324
|
+
|
|
1325
|
+
@LogPerformances
|
|
1326
|
+
def __get_device_impedance_metadata(self):
|
|
1327
|
+
num_returned_items = (c_uint)(0)
|
|
1328
|
+
device_impedance_metadata_list = (
|
|
1329
|
+
TMSiImpedanceMetadata * self.get_num_impedance_channels()
|
|
1330
|
+
)()
|
|
1331
|
+
TMSiGetDeviceImpedanceMetadata(
|
|
1332
|
+
self.__device_handle,
|
|
1333
|
+
pointer(device_impedance_metadata_list),
|
|
1334
|
+
self.get_num_impedance_channels(),
|
|
1335
|
+
pointer(num_returned_items),
|
|
1336
|
+
)
|
|
1337
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1338
|
+
impedance_metadata_list = []
|
|
1339
|
+
impedance_channels = []
|
|
1340
|
+
for i in range(num_returned_items.value):
|
|
1341
|
+
impedance_metadata_list.append(
|
|
1342
|
+
device_impedance_metadata_list[i]
|
|
1343
|
+
)
|
|
1344
|
+
impedance_channels.append(
|
|
1345
|
+
ApexImpedanceChannel(device_impedance_metadata_list[i])
|
|
1346
|
+
)
|
|
1347
|
+
self.__config.set_impedance_channels(impedance_channels)
|
|
1348
|
+
return impedance_metadata_list
|
|
1349
|
+
else:
|
|
1350
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1351
|
+
|
|
1352
|
+
@LogPerformances
|
|
1353
|
+
def __get_device_info_report(self):
|
|
1354
|
+
device_info_report = TMSiDevInfoReport()
|
|
1355
|
+
self.__last_error_code = TMSiGetDeviceInfo(
|
|
1356
|
+
self.__device_handle, pointer(device_info_report)
|
|
1357
|
+
)
|
|
1358
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1359
|
+
return device_info_report
|
|
1360
|
+
else:
|
|
1361
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1362
|
+
|
|
1363
|
+
@LogPerformances
|
|
1364
|
+
def __get_device_interface_status(self, interface):
|
|
1365
|
+
interface_status = TMSiInterfaceStatus()
|
|
1366
|
+
self.__last_error_code = TMSiGetDeviceInterfaceStatus(
|
|
1367
|
+
self.__device_handle, interface.value, pointer(interface_status)
|
|
1368
|
+
)
|
|
1369
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1370
|
+
return interface_status
|
|
1371
|
+
else:
|
|
1372
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1373
|
+
|
|
1374
|
+
@LogPerformances
|
|
1375
|
+
def __get_device_power_status(self):
|
|
1376
|
+
power_status = TMSiDevPowerStatus()
|
|
1377
|
+
self.__last_error_code = TMSiGetDevicePowerStatus(
|
|
1378
|
+
self.__device_handle, pointer(power_status)
|
|
1379
|
+
)
|
|
1380
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1381
|
+
return power_status
|
|
1382
|
+
else:
|
|
1383
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1384
|
+
|
|
1385
|
+
@LogPerformances
|
|
1386
|
+
def __get_device_reference_config(self):
|
|
1387
|
+
device_channel_reference_list = (
|
|
1388
|
+
TMSiDevChanRef * self.get_num_channels()
|
|
1389
|
+
)()
|
|
1390
|
+
len_channel_reference_list = (c_uint)(0)
|
|
1391
|
+
self.__last_error_code = TMSiGetDeviceReferenceConfig(
|
|
1392
|
+
self.__device_handle,
|
|
1393
|
+
pointer(device_channel_reference_list),
|
|
1394
|
+
self.get_num_channels(),
|
|
1395
|
+
pointer(len_channel_reference_list),
|
|
1396
|
+
)
|
|
1397
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1398
|
+
device_channel_reference_list_to_return = (
|
|
1399
|
+
TMSiDevChanRef * len_channel_reference_list.value
|
|
1400
|
+
)()
|
|
1401
|
+
for i in range(len_channel_reference_list.value):
|
|
1402
|
+
device_channel_reference_list_to_return[
|
|
1403
|
+
i
|
|
1404
|
+
] = device_channel_reference_list[i]
|
|
1405
|
+
return device_channel_reference_list_to_return
|
|
1406
|
+
else:
|
|
1407
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1408
|
+
|
|
1409
|
+
@LogPerformances
|
|
1410
|
+
def __get_device_rtc(self):
|
|
1411
|
+
dev_time = TMSiTime()
|
|
1412
|
+
self.__last_error_code = TMSiGetDeviceRTC(
|
|
1413
|
+
self.__device_handle, pointer(dev_time)
|
|
1414
|
+
)
|
|
1415
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1416
|
+
return datetime.datetime(
|
|
1417
|
+
dev_time.Year + 1900,
|
|
1418
|
+
dev_time.Month + 1,
|
|
1419
|
+
dev_time.DayOfMonth,
|
|
1420
|
+
dev_time.Hours,
|
|
1421
|
+
dev_time.Minutes,
|
|
1422
|
+
dev_time.Seconds,
|
|
1423
|
+
)
|
|
1424
|
+
else:
|
|
1425
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1426
|
+
|
|
1427
|
+
@LogPerformances
|
|
1428
|
+
def __get_device_sample_metadata_header(self):
|
|
1429
|
+
device_sampling_metadata_header = TMSiSampleMetadataHeader()
|
|
1430
|
+
self.__last_error_code = TMSiGetDeviceSampleMetadataHeader(
|
|
1431
|
+
self.__device_handle,
|
|
1432
|
+
self.__info.get_dr_interface().value,
|
|
1433
|
+
pointer(device_sampling_metadata_header),
|
|
1434
|
+
)
|
|
1435
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1436
|
+
return device_sampling_metadata_header
|
|
1437
|
+
else:
|
|
1438
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1439
|
+
|
|
1440
|
+
@LogPerformances
|
|
1441
|
+
def __get_device_sample_metadata(self):
|
|
1442
|
+
device_channel_metadata = (
|
|
1443
|
+
TMSiChannelMetadata * self.get_num_channels()
|
|
1444
|
+
)()
|
|
1445
|
+
device_cycling_state_metadata = (
|
|
1446
|
+
TMSiCyclingStateMetadata * self.get_num_channels()
|
|
1447
|
+
)()
|
|
1448
|
+
num_returned_channels = (c_uint)(0)
|
|
1449
|
+
num_returned_cycling_states = (c_uint)(0)
|
|
1450
|
+
TMSiGetDeviceSampleMetadata(
|
|
1451
|
+
self.__device_handle,
|
|
1452
|
+
self.__info.get_dr_interface().value,
|
|
1453
|
+
pointer(device_channel_metadata),
|
|
1454
|
+
self.get_num_channels(),
|
|
1455
|
+
pointer(num_returned_channels),
|
|
1456
|
+
pointer(device_cycling_state_metadata),
|
|
1457
|
+
self.get_num_channels(),
|
|
1458
|
+
pointer(num_returned_cycling_states),
|
|
1459
|
+
)
|
|
1460
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1461
|
+
return_channels = []
|
|
1462
|
+
return_cycling_states = []
|
|
1463
|
+
for i in range(num_returned_channels.value):
|
|
1464
|
+
return_channels.append(device_channel_metadata[i])
|
|
1465
|
+
for i in range(num_returned_cycling_states.value):
|
|
1466
|
+
return_cycling_states.append(device_cycling_state_metadata[i])
|
|
1467
|
+
return return_channels, return_cycling_states
|
|
1468
|
+
else:
|
|
1469
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1470
|
+
|
|
1471
|
+
@LogPerformances
|
|
1472
|
+
def __get_device_sampling_config(self):
|
|
1473
|
+
device_sampling_config = TMSiDevSamplingCfg()
|
|
1474
|
+
self.__last_error_code = TMSiGetDeviceSamplingConfig(
|
|
1475
|
+
self.__device_handle, pointer(device_sampling_config)
|
|
1476
|
+
)
|
|
1477
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1478
|
+
return device_sampling_config
|
|
1479
|
+
else:
|
|
1480
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1481
|
+
|
|
1482
|
+
@LogPerformances
|
|
1483
|
+
def __load_config_from_device(self):
|
|
1484
|
+
self.get_device_info_report()
|
|
1485
|
+
self.get_device_sampling_config()
|
|
1486
|
+
device_sampling_metadata_header = (
|
|
1487
|
+
self.__get_device_sample_metadata_header()
|
|
1488
|
+
)
|
|
1489
|
+
self.__config.set_sampling_frequency(
|
|
1490
|
+
device_sampling_metadata_header.BaseFS
|
|
1491
|
+
)
|
|
1492
|
+
self.get_device_channels()
|
|
1493
|
+
|
|
1494
|
+
@LogPerformances
|
|
1495
|
+
def __reset_device_card(self):
|
|
1496
|
+
self.__last_error_code = TMSiResetDeviceCard(self.__device_handle)
|
|
1497
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1498
|
+
return
|
|
1499
|
+
else:
|
|
1500
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1501
|
+
|
|
1502
|
+
@LogPerformances
|
|
1503
|
+
def __set_device_factory_default(self):
|
|
1504
|
+
self.__last_error_code = TMSiSetDeviceFactoryDefaults(
|
|
1505
|
+
self.__device_handle
|
|
1506
|
+
)
|
|
1507
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1508
|
+
return
|
|
1509
|
+
else:
|
|
1510
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1511
|
+
|
|
1512
|
+
@LogPerformances
|
|
1513
|
+
def __set_device_card_recording_config(self, config):
|
|
1514
|
+
self.__last_error_code = TMSiSetDeviceCardRecordingConfig(
|
|
1515
|
+
self.__device_handle, pointer(config)
|
|
1516
|
+
)
|
|
1517
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1518
|
+
return
|
|
1519
|
+
else:
|
|
1520
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1521
|
+
|
|
1522
|
+
@LogPerformances
|
|
1523
|
+
def __set_device_channel_config(self, list_names, list_indices):
|
|
1524
|
+
_, device_channel_alt_name_list = self.__get_device_channel_config()
|
|
1525
|
+
num_channels = len(list_indices)
|
|
1526
|
+
if len(list_indices) > 0:
|
|
1527
|
+
for i in range(num_channels):
|
|
1528
|
+
converted_str = bytearray(ApexStringLengths.AltChanName.value)
|
|
1529
|
+
for character in range(len(list_names[i])):
|
|
1530
|
+
converted_str[character] = ord(list_names[i][character])
|
|
1531
|
+
device_channel_alt_name_list[
|
|
1532
|
+
list_indices[i]
|
|
1533
|
+
].AltChanName = bytes(converted_str)
|
|
1534
|
+
self.__last_error_code = TMSiSetDeviceChannelConfig(
|
|
1535
|
+
self.__device_handle,
|
|
1536
|
+
device_channel_alt_name_list,
|
|
1537
|
+
len(device_channel_alt_name_list),
|
|
1538
|
+
)
|
|
1539
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1540
|
+
return
|
|
1541
|
+
else:
|
|
1542
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1543
|
+
|
|
1544
|
+
@LogPerformances
|
|
1545
|
+
def __set_device_interface_config(
|
|
1546
|
+
self,
|
|
1547
|
+
device_interface=DeviceInterfaceType.bluetooth,
|
|
1548
|
+
control=TMSiControl.ControlEnabled,
|
|
1549
|
+
):
|
|
1550
|
+
self.__last_error_code = TMSiSetDeviceInterfaceConfig(
|
|
1551
|
+
self.__device_handle, device_interface.value, control.value
|
|
1552
|
+
)
|
|
1553
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1554
|
+
return
|
|
1555
|
+
else:
|
|
1556
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1557
|
+
|
|
1558
|
+
@LogPerformances
|
|
1559
|
+
def __set_device_reference_config(self, list_references, list_indices):
|
|
1560
|
+
device_channel_reference_list = self.__get_device_reference_config()
|
|
1561
|
+
if len(list_indices) > 0:
|
|
1562
|
+
for i in range(len(list_indices)):
|
|
1563
|
+
if list_indices[i] < len(device_channel_reference_list):
|
|
1564
|
+
device_channel_reference_list[
|
|
1565
|
+
list_indices[i]
|
|
1566
|
+
].ChanRefStatus = list_references[i]
|
|
1567
|
+
self.__last_error_code = TMSiSetDeviceReferenceConfig(
|
|
1568
|
+
self.__device_handle,
|
|
1569
|
+
pointer(device_channel_reference_list),
|
|
1570
|
+
len(device_channel_reference_list),
|
|
1571
|
+
)
|
|
1572
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1573
|
+
return
|
|
1574
|
+
else:
|
|
1575
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1576
|
+
|
|
1577
|
+
@LogPerformances
|
|
1578
|
+
def __set_device_rtc(self, dt):
|
|
1579
|
+
dev_time = TMSiTime()
|
|
1580
|
+
dev_time.Year = dt.year - 1900
|
|
1581
|
+
dev_time.Month = dt.month - 1
|
|
1582
|
+
dev_time.DayOfMonth = dt.day
|
|
1583
|
+
dev_time.Hours = dt.hour
|
|
1584
|
+
dev_time.Minutes = dt.minute
|
|
1585
|
+
dev_time.Seconds = dt.second
|
|
1586
|
+
self.__last_error_code = TMSiSetDeviceRTC(
|
|
1587
|
+
self.__device_handle, pointer(dev_time)
|
|
1588
|
+
)
|
|
1589
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1590
|
+
return
|
|
1591
|
+
else:
|
|
1592
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|
|
1593
|
+
|
|
1594
|
+
@LogPerformances
|
|
1595
|
+
def __set_device_sampling_config(
|
|
1596
|
+
self,
|
|
1597
|
+
frequency=TMSiBaseSampleRate.Binary,
|
|
1598
|
+
live_impedance=TMSiLiveImpedance.On,
|
|
1599
|
+
impedance_limit=0,
|
|
1600
|
+
):
|
|
1601
|
+
device_sampling_config = TMSiDevSamplingCfg()
|
|
1602
|
+
device_sampling_config.BaseSampleRate = frequency.value
|
|
1603
|
+
device_sampling_config.ImpedanceLimit = impedance_limit
|
|
1604
|
+
device_sampling_config.LiveImpedance = live_impedance.value
|
|
1605
|
+
self.__last_error_code = TMSiSetDeviceSamplingConfig(
|
|
1606
|
+
self.__device_handle, pointer(device_sampling_config)
|
|
1607
|
+
)
|
|
1608
|
+
if self.__last_error_code == TMSiDeviceRetVal.TMSiStatusOK:
|
|
1609
|
+
return
|
|
1610
|
+
else:
|
|
1611
|
+
raise TMSiError(TMSiErrorCode.device_error, self.__last_error_code)
|