diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2b565bf..60f5cfa 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,18 +2,21 @@ name: Python package
on: [ push ]
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11' ]
+ python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
diff --git a/examples/bt_api_example.py b/examples/bt_api_example.py
new file mode 100644
index 0000000..d169ede
--- /dev/null
+++ b/examples/bt_api_example.py
@@ -0,0 +1,38 @@
+import time
+
+from serial import Serial
+
+from pyshimmer import ShimmerBluetooth, DEFAULT_BAUDRATE, DataPacket
+
+
+def stream_cb(pkt: DataPacket) -> None:
+ print(f'Received new data packet: ')
+ for chan in pkt.channels:
+ print(f'channel: ' + str(chan))
+ print(f'value: ' + str(pkt[chan]))
+ print('')
+
+def main(args=None):
+ serial = Serial('/dev/rfcomm42', DEFAULT_BAUDRATE)
+ shim_dev = ShimmerBluetooth(serial)
+
+ shim_dev.initialize()
+
+ dev_name = shim_dev.get_device_name()
+ print(f'My name is: {dev_name}')
+
+ info = shim_dev.get_firmware_version()
+ print("- firmware: [" + str(info[0]) + "]")
+ print("- version: [" + str(info[1].major) + "." + str(info[1].minor) + "." + str(info[1].rel) + "]")
+
+ shim_dev.add_stream_callback(stream_cb)
+
+ shim_dev.start_streaming()
+ time.sleep(5.0)
+ shim_dev.stop_streaming()
+
+ shim_dev.shutdown()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/examples/dock_example.py b/examples/dock_example.py
new file mode 100644
index 0000000..49eef47
--- /dev/null
+++ b/examples/dock_example.py
@@ -0,0 +1,19 @@
+from serial import Serial
+
+from pyshimmer import ShimmerDock, DEFAULT_BAUDRATE, fmt_hex
+
+
+def main(args=None):
+ serial = Serial('/dev/ttyECGdev', DEFAULT_BAUDRATE)
+
+ print(f'Connecting docker')
+ shim_dock = ShimmerDock(serial)
+
+ mac = shim_dock.get_mac_address()
+ print(f'Device MAC: {fmt_hex(mac)}')
+
+ shim_dock.close()
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 4aa044e..4fb0fa7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,6 +15,31 @@
# along with this program. If not, see .
[build-system]
-requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4"]
+requires = ["setuptools >= 42", "wheel", "setuptools_scm >= 3.4"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "pyshimmer"
+authors = [{ name = "Lukas Magel" }]
+description = "API for Shimmer sensor devices"
+readme = "README.rst"
+license = { file = "LICENSE" }
+urls = { "Homepage" = "https://github.com/seemoo-lab/pyshimmer" }
+requires-python = ">= 3.7"
+dynamic = ["version"]
+dependencies = [
+ "pyserial>=3.4",
+ "numpy>=1.15",
+ "pandas>=1.1.5",
+]
+
+[project.optional-dependencies]
+test = [
+ "pytest",
+ "pytest-cov",
+]
+
+[tool.setuptools.packages.find]
+include = ["pyshimmer*"]
[tool.setuptools_scm]
diff --git a/pyshimmer/bluetooth/bt_api.py b/pyshimmer/bluetooth/bt_api.py
index 5b22afd..36033c2 100644
--- a/pyshimmer/bluetooth/bt_api.py
+++ b/pyshimmer/bluetooth/bt_api.py
@@ -24,7 +24,7 @@
GetFirmwareVersionCommand, InquiryCommand, StartStreamingCommand, StopStreamingCommand, DataPacket, \
GetEXGRegsCommand, SetEXGRegsCommand, StartLoggingCommand, StopLoggingCommand, GetExperimentIDCommand, \
SetExperimentIDCommand, GetDeviceNameCommand, SetDeviceNameCommand, DummyCommand, GetBatteryCommand, \
- SetSamplingRateCommand, SetSensorsCommand, SetStatusAckCommand
+ SetSamplingRateCommand, SetSensorsCommand, SetStatusAckCommand, AllCalibration, GetAllCalibrationCommand
from pyshimmer.bluetooth.bt_const import ACK_COMMAND_PROCESSED, DATA_PACKET, FULL_STATUS_RESPONSE, INSTREAM_CMD_RESPONSE
from pyshimmer.bluetooth.bt_serial import BluetoothSerial
from pyshimmer.dev.channels import ChDataTypeAssignment, ChannelDataType, EChannelType, ESensorGroup
@@ -475,6 +475,12 @@ def get_exg_register(self, chip_id: int) -> ExGRegister:
"""
return self._process_and_wait(GetEXGRegsCommand(chip_id))
+ def get_all_calibration(self) -> AllCalibration:
+ """Gets all calibration data from sensor
+ :return: An AllCalibration object that presents the calibration contents in an easily processable manner
+ """
+ return self._process_and_wait(GetAllCalibrationCommand())
+
def set_exg_register(self, chip_id: int, offset: int, data: bytes) -> None:
"""Configure part of the memory of the ExG registers
diff --git a/pyshimmer/bluetooth/bt_commands.py b/pyshimmer/bluetooth/bt_commands.py
index 7186e61..5813fa7 100644
--- a/pyshimmer/bluetooth/bt_commands.py
+++ b/pyshimmer/bluetooth/bt_commands.py
@@ -23,6 +23,7 @@
from pyshimmer.dev.base import dr2sr, sr2dr, sec2ticks, ticks2sec
from pyshimmer.dev.channels import ChannelDataType, EChannelType, ESensorGroup, serialize_sensorlist
from pyshimmer.dev.exg import ExGRegister
+from pyshimmer.dev.calibration import AllCalibration
from pyshimmer.dev.fw_version import get_firmware_type
from pyshimmer.util import bit_is_set, resp_code_to_bytes, calibrate_u12_adc_value, battery_voltage_to_percent
@@ -221,7 +222,7 @@ def send(self, ser: BluetoothSerial) -> None:
def receive(self, ser: BluetoothSerial) -> any:
batt = ser.read_response(self.get_response_code(), arg_format='BBB')
- # Calculation see:
+ # Calculation see:
# http://shimmersensing.com/wp-content/docs/support/documentation/LogAndStream_for_Shimmer3_Firmware_User_Manual_rev0.11a.pdf (Page 17)
# https://shimmersensing.com/wp-content/docs/support/documentation/Shimmer_User_Manual_rev3p.pdf (Page 53)
raw_values = batt[1] * 256 + batt[0]
@@ -337,11 +338,41 @@ def send(self, ser: BluetoothSerial) -> None:
ser.write_command(GET_FW_VERSION_COMMAND)
def receive(self, ser: BluetoothSerial) -> any:
- fw_type_bin, major, minor, rel = ser.read_response(FW_VERSION_RESPONSE, arg_format=' None:
+ ser.write_command(GET_ALL_CALIBRATION_COMMAND)
+
+ def receive(self, ser: BluetoothSerial) -> any:
+ ser.read_response(ALL_CALIBRATION_RESPONSE)
+ reg_data = ser.read(self._rlen)
+ return AllCalibration(reg_data)
+
+
class InquiryCommand(ResponseCommand):
"""Perform an inquiry to determine the sample rate, buffer size, and active data channels
@@ -360,7 +391,8 @@ def send(self, ser: BluetoothSerial) -> None:
ser.write_command(INQUIRY_COMMAND)
def receive(self, ser: BluetoothSerial) -> any:
- sr_val, _, n_ch, buf_size = ser.read_response(INQUIRY_RESPONSE, arg_format=' None:
- ser.write_command(GET_EXG_REGS_COMMAND, 'BBB', self._chip, self._offset, self._rlen)
+ ser.write_command(GET_EXG_REGS_COMMAND, 'BBB',
+ self._chip, self._offset, self._rlen)
def receive(self, ser: BluetoothSerial) -> any:
rlen = ser.read_response(EXG_REGS_RESPONSE, arg_format='B')
if not rlen == self._rlen:
- raise ValueError('Response does not contain required amount of bytes')
+ raise ValueError(
+ 'Response does not contain required amount of bytes')
reg_data = ser.read(rlen)
return ExGRegister(reg_data)
@@ -429,7 +463,8 @@ def __init__(self, chip_id: int, offset: int, data: bytes):
def send(self, ser: BluetoothSerial) -> None:
dlen = len(self._data)
- ser.write_command(SET_EXG_REGS_COMMAND, 'BBB', self._chip, self._offset, dlen)
+ ser.write_command(SET_EXG_REGS_COMMAND, 'BBB',
+ self._chip, self._offset, dlen)
ser.write(self._data)
diff --git a/pyshimmer/bluetooth/bt_const.py b/pyshimmer/bluetooth/bt_const.py
index d8e93c4..7df4809 100644
--- a/pyshimmer/bluetooth/bt_const.py
+++ b/pyshimmer/bluetooth/bt_const.py
@@ -84,6 +84,9 @@
ENABLE_STATUS_ACK_COMMAND = 0xA3
+GET_ALL_CALIBRATION_COMMAND = 0x2C
+ALL_CALIBRATION_RESPONSE = 0x2D
+
"""
The Bluetooth LogAndStream API assigns a numerical index to each channel type. This dictionary maps each index to the
corresponding channel type.
diff --git a/pyshimmer/dev/calibration.py b/pyshimmer/dev/calibration.py
new file mode 100644
index 0000000..74dee01
--- /dev/null
+++ b/pyshimmer/dev/calibration.py
@@ -0,0 +1,85 @@
+# pyshimmer - API for Shimmer sensor devices
+# Copyright (C) 2023 Lukas Magel, Manuel Fernandez-Carmona
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import struct
+from typing import List
+
+from pyshimmer.util import fmt_hex
+
+
+class AllCalibration:
+
+ def __init__(self, reg_bin: bytes):
+ self._num_bytes = 84
+ self._sensor_bytes = 21
+ self._num_sensors = 4
+
+ if len(reg_bin) < self._num_bytes:
+ raise ValueError(
+ f'All calibration data must have length {self._num_bytes}')
+
+ self._reg_bin = reg_bin
+
+ def __str__(self) -> str:
+ def print_sensor(sens_num: int) -> str:
+ return f'Sensor {sens_num + 1:2d}\n' + \
+ f'\tOffset bias: {self.get_offset_bias(sens_num)}\n' + \
+ f'\tSensitivity: {self.get_sensitivity(sens_num)}\n' + \
+ f'\tAlignment Matrix: {self.get_ali_mat(sens_num)}\n'
+
+ obj_str = f''
+ for i in range(0, self._num_sensors):
+ obj_str += print_sensor(i)
+
+ reg_bin_str = fmt_hex(self._reg_bin)
+ obj_str += f'Binary: {reg_bin_str}\n'
+
+ return obj_str
+
+ @property
+ def binary(self):
+ return self._reg_bin
+
+ def __eq__(self, other: "AllCalibration") -> bool:
+ return self._reg_bin == other._reg_bin
+
+ def _check_sens_num(self, sens_num: int) -> None:
+ if not 0 <= sens_num < (self._num_sensors):
+ raise ValueError(f'Sensor num must be 0 to {self._num_sensors-1}')
+
+ def get_offset_bias(self, sens_num: int) -> List[int]:
+ self._check_sens_num(sens_num)
+ start_offset = sens_num * self._sensor_bytes
+ end_offset = start_offset + 6
+ ans = list(struct.unpack(
+ '>hhh', self._reg_bin[start_offset:end_offset]))
+ return ans
+
+ def get_sensitivity(self, sens_num: int) -> List[int]:
+ self._check_sens_num(sens_num)
+ start_offset = sens_num * self._sensor_bytes + 6
+ end_offset = start_offset + 6
+ ans = list(struct.unpack(
+ '>hhh', self._reg_bin[start_offset:end_offset]))
+ return ans
+
+ def get_ali_mat(self, sens_num: int) -> List[int]:
+ self._check_sens_num(sens_num)
+ start_offset = sens_num * self._sensor_bytes + 12
+ end_offset = start_offset + 9
+ ans = list(struct.unpack(
+ '>bbbbbbbbb', self._reg_bin[start_offset:end_offset]))
+ return ans
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 962cd03..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,39 +0,0 @@
-# pyshimmer - API for Shimmer sensor devices
-# Copyright (C) 2020 Lukas Magel
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-[metadata]
-name = pyshimmer
-author = Lukas Magel
-license = GPL-3.0-or-later
-description = API for Shimmer sensor devices
-url = https://github.com/seemoo-lab/pyshimmer
-long_description = file: README.rst
-
-[options]
-packages = find:
-setup_requires = setuptools_scm
-install_requires =
- pyserial>=3.4
- numpy>=1.15
- pandas>=1.1.5
-
-[options.packages.find]
-include = pyshimmer*
-
-[options.extras_require]
-test =
- pytest
- pytest-cov
diff --git a/test/bluetooth/test_bt_commands.py b/test/bluetooth/test_bt_commands.py
index a9e1484..1b76393 100644
--- a/test/bluetooth/test_bt_commands.py
+++ b/test/bluetooth/test_bt_commands.py
@@ -21,7 +21,7 @@
GetFirmwareVersionCommand, InquiryCommand, StartStreamingCommand, StopStreamingCommand, StartLoggingCommand, \
StopLoggingCommand, GetEXGRegsCommand, SetEXGRegsCommand, GetExperimentIDCommand, SetExperimentIDCommand, \
GetDeviceNameCommand, SetDeviceNameCommand, DummyCommand, DataPacket, ResponseCommand, SetStatusAckCommand, \
- SetSensorsCommand, SetSamplingRateCommand
+ SetSensorsCommand, SetSamplingRateCommand, GetAllCalibrationCommand
from pyshimmer.bluetooth.bt_serial import BluetoothSerial
from pyshimmer.dev.channels import ChDataTypeAssignment, EChannelType, ESensorGroup
from pyshimmer.dev.fw_version import EFirmwareType
@@ -95,10 +95,12 @@ def test_set_sampling_rate_command(self):
def test_get_battery_state_command(self):
cmd = GetBatteryCommand(in_percent=True)
- self.assert_cmd(cmd, b'\x95', b'\x8a\x94', b'\x8a\x94\x30\x0b\x80', 100)
+ self.assert_cmd(cmd, b'\x95', b'\x8a\x94',
+ b'\x8a\x94\x30\x0b\x80', 100)
cmd = GetBatteryCommand(in_percent=False)
- self.assert_cmd(cmd, b'\x95', b'\x8a\x94', b'\x8a\x94\x2e\x0b\x80', 4.168246153846154)
+ self.assert_cmd(cmd, b'\x95', b'\x8a\x94',
+ b'\x8a\x94\x2e\x0b\x80', 4.168246153846154)
def test_set_sensors_command(self):
sensors = [
@@ -119,7 +121,8 @@ def test_set_config_time_command(self):
def test_get_rtc(self):
cmd = GetRealTimeClockCommand()
- r = self.assert_cmd(cmd, b'\x91', b'\x90', b'\x90\x1f\xb1\x93\x09\x00\x00\x00\x00')
+ r = self.assert_cmd(cmd, b'\x91', b'\x90',
+ b'\x90\x1f\xb1\x93\x09\x00\x00\x00\x00')
self.assertAlmostEqual(r, 4903.3837585)
def test_set_rtc(self):
@@ -129,11 +132,13 @@ def test_set_rtc(self):
def test_get_status_command(self):
cmd = GetStatusCommand()
expected_result = [True, False, True, False, False, True, False, False]
- self.assert_cmd(cmd, b'\x72', b'\x8a\x71', b'\x8a\x71\x25', expected_result)
+ self.assert_cmd(cmd, b'\x72', b'\x8a\x71',
+ b'\x8a\x71\x25', expected_result)
def test_get_firmware_version_command(self):
cmd = GetFirmwareVersionCommand()
- fw_type, major, minor, patch = self.assert_cmd(cmd, b'\x2e', b'\x2f', b'\x2f\x03\x00\x00\x00\x0b\x00')
+ fw_type, major, minor, patch = self.assert_cmd(
+ cmd, b'\x2e', b'\x2f', b'\x2f\x03\x00\x00\x00\x0b\x00')
self.assertEqual(fw_type, EFirmwareType.LogAndStream)
self.assertEqual(major, 0)
self.assertEqual(minor, 11)
@@ -141,7 +146,8 @@ def test_get_firmware_version_command(self):
def test_inquiry_command(self):
cmd = InquiryCommand()
- sr, buf_size, ctypes = self.assert_cmd(cmd, b'\x01', b'\x02', b'\x02\x40\x00\x01\xff\x01\x09\x01\x01\x12')
+ sr, buf_size, ctypes = self.assert_cmd(
+ cmd, b'\x01', b'\x02', b'\x02\x40\x00\x01\xff\x01\x09\x01\x01\x12')
self.assertEqual(sr, 512.0)
self.assertEqual(buf_size, 1)
@@ -165,7 +171,8 @@ def test_stop_logging_command(self):
def test_get_exg_register_command(self):
cmd = GetEXGRegsCommand(1)
- r = self.assert_cmd(cmd, b'\x63\x01\x00\x0a', b'\x62', b'\x62\x0a\x00\x80\x10\x00\x00\x00\x00\x00\x02\x01')
+ r = self.assert_cmd(cmd, b'\x63\x01\x00\x0a', b'\x62',
+ b'\x62\x0a\x00\x80\x10\x00\x00\x00\x00\x00\x02\x01')
self.assertEqual(r.binary, b'\x00\x80\x10\x00\x00\x00\x00\x00\x02\x01')
def test_get_exg_reg_fail(self):
@@ -175,6 +182,11 @@ def test_get_exg_reg_fail(self):
mock.test_put_read_data(b'\x62\x04\x01\x02\x03\x04')
self.assertRaises(ValueError, cmd.receive, serial)
+ def test_get_allcalibration_command(self):
+ cmd = GetAllCalibrationCommand()
+ r = self.assert_cmd(cmd, b'\x2c', b'\x2d', b'\x2d\x08\xcd\x08\xcd\x08\xcd\x00\x5c\x00\x5c\x00\x5c\x00\x9c\x00\x9c\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x19\x96\x19\x96\x19\x96\x00\x9c\x00\x9c\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x87\x06\x87\x06\x87\x00\x9c\x00\x64\x00\x00\x00\x00\x9c')
+ self.assertEqual(r.binary, b'\x08\xcd\x08\xcd\x08\xcd\x00\x5c\x00\x5c\x00\x5c\x00\x9c\x00\x9c\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x19\x96\x19\x96\x19\x96\x00\x9c\x00\x9c\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x87\x06\x87\x06\x87\x00\x9c\x00\x64\x00\x00\x00\x00\x9c')
+
def test_set_exg_register_command(self):
cmd = SetEXGRegsCommand(1, 0x02, b'\x10\x00')
self.assert_cmd(cmd, b'\x61\x01\x02\x02\x10\x00')
diff --git a/test/dev/test_device_calibration.py b/test/dev/test_device_calibration.py
new file mode 100644
index 0000000..c5cb507
--- /dev/null
+++ b/test/dev/test_device_calibration.py
@@ -0,0 +1,115 @@
+# pyshimmer - API for Shimmer sensor devices
+# Copyright (C) 2023 Lukas Magel, Manuel Fernandez-Carmona
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import random
+from unittest import TestCase
+from pyshimmer.dev.calibration import AllCalibration
+
+def randbytes(k: int) -> bytes:
+ population = list(range(256))
+ seq = random.choices(population, k=k)
+ return bytes(seq)
+
+class AllCalibrationTest(TestCase):
+
+ def test_equality_operator(self):
+ def do_assert(a: bytes, b: bytes, result: bool) -> None:
+ self.assertEqual(AllCalibration(a) == AllCalibration(b), result)
+
+ x = randbytes(84)
+ y = randbytes(84)
+
+ do_assert(x, y, False)
+ do_assert(x, x, True)
+ do_assert(y, y, True)
+
+ for i in range(len(x)):
+ y = bytearray(x)
+ y[i] = random.randrange(0, 256)
+ do_assert(x, y, False)
+
+ def setUp(self) -> None:
+ random.seed(0x42)
+
+ def test_allcalibration_fail(self):
+ self.assertRaises(ValueError, AllCalibration, bytes())
+
+ def test_allcalibration(self):
+ bin_reg1 = bytes([0x08, 0xcd, 0x08, 0xcd, 0x08, 0xcd, 0x00, 0x5c, 0x00, 0x5c,
+ 0x00, 0x5c, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x96, 0x19,
+ 0x96, 0x19, 0x96, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b,
+ 0x02, 0x9b, 0x02, 0x9b, 0x00, 0x9c, 0x00, 0x64, 0x00, 0x00,
+ 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9c, 0x00, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x9c])
+
+ bin_reg2 = bytes([0x08, 0xcd, 0x08, 0xcd, 0x08, 0xcd, 0x00, 0x5c, 0x00, 0x5c,
+ 0x00, 0x5c, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x96, 0x19,
+ 0x96, 0x19, 0x96, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9c, 0x00, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x9c])
+
+ allcalib1 = AllCalibration(bin_reg1)
+ allcalib2 = AllCalibration(bin_reg2)
+ self.assertEqual(allcalib1.get_offset_bias(0), [2253, 2253, 2253] )
+ self.assertEqual(allcalib1.get_sensitivity(0), [92, 92, 92] )
+ self.assertEqual(allcalib1.get_ali_mat(0), [0, -100, 0, -100, 0, 0, 0, 0, -100] )
+ self.assertEqual(allcalib1.get_offset_bias(1), [0, 0, 0] )
+ self.assertEqual(allcalib1.get_sensitivity(1), [6550, 6550, 6550] )
+ self.assertEqual(allcalib1.get_ali_mat(1), [0, -100, 0, -100, 0, 0, 0, 0, -100] )
+ self.assertEqual(allcalib1.get_offset_bias(2), [0, 0, 0] )
+ self.assertEqual(allcalib1.get_sensitivity(2), [667, 667, 667] )
+ self.assertEqual(allcalib1.get_ali_mat(2), [0, -100, 0, 100, 0, 0, 0, 0, -100] )
+ self.assertEqual(allcalib1.get_offset_bias(3), [0, 0, 0] )
+ self.assertEqual(allcalib1.get_sensitivity(3), [1671, 1671, 1671] )
+ self.assertEqual(allcalib1.get_ali_mat(3), [0, -100, 0, 100, 0, 0, 0, 0, -100] )
+
+ self.assertEqual(allcalib2.get_offset_bias(0), [2253, 2253, 2253])
+ self.assertEqual(allcalib2.get_sensitivity(0), [92, 92, 92])
+ self.assertEqual(allcalib2.get_ali_mat(0), [0, -100, 0, -100, 0, 0, 0, 0, -100])
+ self.assertEqual(allcalib2.get_offset_bias(1), [0, 0, 0])
+ self.assertEqual(allcalib2.get_sensitivity(1), [6550, 6550, 6550])
+ self.assertEqual(allcalib2.get_ali_mat(1), [0, -100, 0, -100, 0, 0, 0, 0, -100])
+ self.assertEqual(allcalib2.get_offset_bias(2), [0, 0, 0])
+ self.assertEqual(allcalib2.get_sensitivity(2), [0, 0, 0])
+ self.assertEqual(allcalib2.get_ali_mat(2), [0, 0, 0, 0, 0, 0, 0, 0, 0])
+ self.assertEqual(allcalib2.get_offset_bias(3), [0, 0, 0])
+ self.assertEqual(allcalib2.get_sensitivity(3), [1671, 1671, 1671])
+ self.assertEqual(allcalib2.get_ali_mat(3), [0, -100, 0, 100, 0, 0, 0, 0, -100])
+
+ def test_exg_register_print(self):
+ bin_reg = bytes([0x08, 0xcd, 0x08, 0xcd, 0x08, 0xcd, 0x00, 0x5c, 0x00, 0x5c,
+ 0x00, 0x5c, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x96, 0x19,
+ 0x96, 0x19, 0x96, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x87, 0x06, 0x87, 0x06, 0x87, 0x00, 0x9c, 0x00, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x9c])
+
+ allcalib = AllCalibration(bin_reg)
+
+ str_repr = str(allcalib)
+ self.assertTrue('Offset bias: [0, 0, 0]' in str_repr)
+ self.assertTrue('Sensitivity: [1671,' in str_repr)
+