def commandLogger(self, context, board, writeType, characteristic, command, length): prev = len(self.full_history) super().commandLogger(context, board, writeType, characteristic, command, length) curr = len(self.full_history) if (prev != curr): if (command[0] == 0xb and command[1] == 0x82): if (command[2] == 0x00): response = to_string_buffer( [0x0b, 0x82, 0x04, 0xc1, 0x00, 0x20]) elif (command[2] == 0x01): response = to_string_buffer( [0x0b, 0x82, 0x04, 0xc1, 0x01, 0x20]) elif (command[2] == 0x02): response = to_string_buffer( [0x0b, 0x82, 0x04, 0xc1, 0x02, 0x20]) elif (command[2] == 0x03): response = to_string_buffer( [0x0b, 0x82, 0x04, 0xc1, 0x03, 0x20]) else: response = to_string_buffer([0x0b, 0x82]) if (response != None): self.schedule_response(response)
def test_double_response(self): tap = self.libmetawear.mbl_mw_acc_bosch_get_tap_data_signal(self.board) self.libmetawear.mbl_mw_datasignal_subscribe(tap, None, self.sensor_data_handler) self.notify_mw_char(to_string_buffer([0x03, 0x0e, 0x11])) self.assertEqual(self.data, BoschTap(type = 0x1, sign = 0x0)) self.notify_mw_char(to_string_buffer([0x03, 0x0e, 0x31])) self.assertEqual(self.data, BoschTap(type = 0x1, sign = 0x1))
def test_data_extraction(self): expected = [24.5, 24.625, 24.5, 24.375, 24.25, 24.375, 24.5, 24.25] values = [] def handle_sensor_data(context, data): data_ptr= cast(data.contents.value, POINTER(c_float)) values.append(data_ptr.contents.value) fn_wrapper = FnVoid_VoidP_DataP(handle_sensor_data) self.libmetawear.mbl_mw_datasignal_subscribe(self.processors[1], None, fn_wrapper) self.notify_mw_char(to_string_buffer([0x09, 0x03, 0x01, 0x04, 0x85, 0xa0, 0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc4, 0x00, 0xc3, 0x00])) self.notify_mw_char(to_string_buffer([0x09, 0x03, 0x01, 0x5e, 0x85, 0xa0, 0x00, 0xc2, 0x00, 0xc3, 0x00, 0xc4, 0x00, 0xc2, 0x00])) self.assertEqual(values, expected)
def commandLogger(self, context, board, writeType, characteristic, command, length): prev = len(self.full_history) TestMetaWearBase.commandLogger(self, context, board, writeType, characteristic, command, length) curr = len(self.full_history) if (prev != curr): response = None if (command[0] == 0x19 and command[1] == 0x8c): response = to_string_buffer([0x19, 0x8c, 0xf6, 0xff, 0x00, 0x00, 0x0a, 0x00, 0xe8, 0x03, 0x03, 0x00]) elif (command[0] == 0x19 and command[1] == 0x8d): response = to_string_buffer([0x19, 0x8d, 0x04, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00]) elif(command[0] == 0x19 and command[1] == 0x8e): response = to_string_buffer([0x19, 0x8e, 0x66, 0x00, 0x17, 0xfd, 0x8a, 0xfc, 0x7f, 0x03, 0x01, 0x00]) if (response != None): self.schedule_response(response)
def test_mac_address(self): signal = self.libmetawear.mbl_mw_settings_get_mac_data_signal(self.board) self.libmetawear.mbl_mw_datasignal_subscribe(signal, None, self.sensor_data_handler) self.notify_mw_char(to_string_buffer([ 0x11, 0x8b, 0x01, 0x07, 0x7b, 0x52, 0x8f, 0xc9, 0xe8 ])) self.assertEqual(self.data, "E8:C9:8F:52:7B:07")
def test_acc_hpf_data(self): expected = CartesianFloat(x= -0.00104, y= 0.0025, z= 0.0013) self.libmetawear.mbl_mw_datasignal_subscribe(self.processors[0], None, self.sensor_data_handler) self.notify_mw_char(to_string_buffer([0x09, 0x03, 0x00, 0xef, 0xff, 0x29, 0x00, 0x16, 0x00])) self.assertEqual(self.data_cartesian_float, expected)
def test_time_offset(self): expected = [10, 11, 8, 11, 10] offsets = [] prev_time = [] def handle_sensor_data(context, data): if len(prev_time) == 0: prev_time.append(data.contents.epoch) else: offsets.append(data.contents.epoch - prev_time[0]) prev_time[0] = data.contents.epoch fn_wrapper = FnVoid_VoidP_DataP(handle_sensor_data) self.libmetawear.mbl_mw_datasignal_subscribe(self.processors[0], None, fn_wrapper) responses = [ [0x09, 0x03, 0x00, 0xa6, 0x33, 0x0d, 0x00, 0xc1, 0x00, 0xb1, 0x24, 0x19, 0xcd], [0x09, 0x03, 0x00, 0xad, 0x33, 0x0d, 0x00, 0xd4, 0x00, 0x18, 0x25, 0xc0, 0xcc], [0x09, 0x03, 0x00, 0xb4, 0x33, 0x0d, 0x00, 0xc7, 0x00, 0x09, 0x25, 0xb2, 0xcc], [0x09, 0x03, 0x00, 0xba, 0x33, 0x0d, 0x00, 0xc5, 0x00, 0x17, 0x25, 0xbc, 0xcc], [0x09, 0x03, 0x00, 0xc1, 0x33, 0x0d, 0x00, 0xd4, 0x00, 0xe9, 0x24, 0xe4, 0xcc], [0x09, 0x03, 0x00, 0xc8, 0x33, 0x0d, 0x00, 0xaf, 0x00, 0xf7, 0x24, 0xe3, 0xcc] ] for r in responses: self.notify_mw_char(to_string_buffer(r)) self.assertEqual(offsets, expected)
def test_handle_overflow_state(self): expected = OverflowState(length = 0x0c94, assert_en = 0) self.libmetawear.mbl_mw_debug_read_stack_overflow_state(self.board, None, self.sensor_data_handler) self.notify_mw_char(to_string_buffer([0xfe, 0x89, 0x00, 0x94, 0x0c])) self.assertEqual(self.data, expected)
def test_time_offset(self): expected = [0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 133, 0, 0, 0] offsets = [] prev_time = [] def handle_sensor_data(context, data): if len(prev_time) == 0: prev_time.append(data.contents.epoch) else: offsets.append(data.contents.epoch - prev_time[0]) prev_time[0] = data.contents.epoch fn_wrapper = FnVoid_VoidP_DataP(handle_sensor_data) self.libmetawear.mbl_mw_datasignal_subscribe(self.processors[1], None, fn_wrapper) responses = [ [0x0b, 0x84, 0x1c, 0x84, 0xa0, 0x00, 0x01], [0x09, 0x03, 0x01, 0x04, 0x85, 0xa0, 0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc4, 0x00, 0xc3, 0x00], [0x09, 0x03, 0x01, 0x5e, 0x85, 0xa0, 0x00, 0xc2, 0x00, 0xc3, 0x00, 0xc4, 0x00, 0xc2, 0x00], [0x09, 0x03, 0x01, 0xb8, 0x85, 0xa0, 0x00, 0xc3, 0x00, 0xc4, 0x00, 0xc3, 0x00, 0xc3, 0x00], [0x09, 0x03, 0x01, 0x13, 0x86, 0xa0, 0x00, 0xc5, 0x00, 0xc3, 0x00, 0xc5, 0x00, 0xc2, 0x00] ] for r in responses: self.notify_mw_char(to_string_buffer(r)) self.assertEqual(offsets, expected)
def test_handle_schedule_queue_state(self): expected = [0x03, 0x02, 0x01, 0x00, 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x1e] self.libmetawear.mbl_mw_debug_read_schedule_queue_usage(self.board, None, self.sensor_data_handler) self.notify_mw_char(to_string_buffer([0xfe, 0x8a, 0x03, 0x02, 0x01, 0x00, 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x1e])) self.assertEqual(self.data, expected)
def test_teardown_serialize(self): state_buffer = to_string_buffer(self.expected_state) self.libmetawear.mbl_mw_metawearboard_deserialize( self.board, cast(state_buffer, POINTER(c_ubyte)), len(state_buffer.raw)) self.libmetawear.mbl_mw_metawearboard_initialize( self.board, None, self.initialized_fn) acc_signal = self.libmetawear.mbl_mw_acc_get_acceleration_data_signal( self.board) self.libmetawear.mbl_mw_datasignal_log(acc_signal, None, self.logger_created) self.events["log"].wait() self.libmetawear.mbl_mw_metawearboard_tear_down(self.board) state_array_size = c_uint(0) state_ptr = cast( self.libmetawear.mbl_mw_metawearboard_serialize( self.board, byref(state_array_size)), POINTER(c_ubyte * state_array_size.value)) python_array = [] for i in range(0, state_array_size.value): python_array.append(state_ptr.contents[i]) self.libmetawear.mbl_mw_memory_free(state_ptr) self.maxDiff = None self.assertEqual(python_array[0:271], self.expected_state[0:271])
def test_deserialize_motion_r_new_fw(self): firmware_state = [0x03, 0x03, 0x01] self.firmware_revision = create_string_buffer(b'1.3.3', 5) self.boardType = TestMetaWearBase.METAWEAR_MOTION_R_BOARD state_buffer = to_string_buffer( TestMetaWearBoardSerialize.motion_r_state) self.libmetawear.mbl_mw_metawearboard_deserialize( self.board, cast(state_buffer, POINTER(c_ubyte)), len(state_buffer.raw)) self.libmetawear.mbl_mw_metawearboard_initialize( self.board, None, self.initialized_fn) state_array_size = c_uint(0) state_ptr = cast( self.libmetawear.mbl_mw_metawearboard_serialize( self.board, byref(state_array_size)), POINTER(c_ubyte * state_array_size.value)) python_array = [] for i in range(0, state_array_size.value): python_array.append(state_ptr.contents[i]) self.libmetawear.mbl_mw_memory_free(state_ptr) self.assertEqual(python_array[1:4], firmware_state)
def commandLogger(self, context, board, writeType, characteristic, command, length): if (command[0] == 0xb and command[1] == 0x84): self.schedule_response( to_string_buffer([0x0b, 0x84, 0xa9, 0x72, 0x04, 0x00, 0x01])) else: super().commandLogger(context, board, writeType, characteristic, command, length)
def logger_ready(self, context, logger): cartesian_float_data= FnVoid_VoidP_DataP(self.float_data_handler) self.libmetawear.mbl_mw_logger_subscribe(logger, None, cartesian_float_data) self.libmetawear.mbl_mw_logging_download(self.board, 20, byref(self.download_handler)) for line in Bmi160GyroYAxis.log_responses: self.notify_mw_char(to_string_buffer(line)) self.events["log"].set()
def test_deserialize_motion_r(self): # just test that deserialization is successful state_buffer = to_string_buffer( TestMetaWearBoardSerialize.motion_r_state) self.libmetawear.mbl_mw_metawearboard_deserialize( self.board, cast(state_buffer, POINTER(c_ubyte)), len(state_buffer.raw)) self.assertTrue(True)
def commandLogger(self, context, board, writeType, characteristic, command, length): prev = len(self.full_history) TestMetaWearBase.commandLogger(self, context, board, writeType, characteristic, command, length) curr = len(self.full_history) if (prev != curr): response = None if (command[0] == 0x03 and command[1] == 0x83): response = to_string_buffer([0x03, 0x83, 40, 8]) elif (command[0] == 0x13 and command[1] == 0x83): response = to_string_buffer([0x13, 0x83, 40, 3]) elif (command[0] == 0x19 and command[1] == 0x82): response = to_string_buffer([0x19, 0x82, 0x1, 0xf]) elif (self.sync_logger and command[0] == 0xb and command[1] == 0x82): if (command[2] == 0x00): response = to_string_buffer( [0x0b, 0x82, 0x09, 0x03, 0x00, 0x60]) elif (command[2] == 0x01): response = to_string_buffer( [0x0b, 0x82, 0x09, 0x03, 0x00, 0x64]) elif (command[2] == 0x02): response = to_string_buffer( [0x0b, 0x82, 0x09, 0x03, 0x00, 0x68]) elif (command[2] == 0x03): response = to_string_buffer( [0x0b, 0x82, 0x09, 0x03, 0x00, 0x6c]) else: response = to_string_buffer([0x0b, 0x82]) elif (self.sync_dataproc and command[0] == 0x9 and command[1] == 0x82): if (command[2] == 0x00): response = to_string_buffer([ 0x09, 0x82, 0x19, 0x07, 0xff, 0xe0, 0x08, 0x17, 0x14, 0x00, 0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]) else: response = to_string_buffer([0x09, 0x82]) if (response != None): self.schedule_response(response)
def commandLogger(self, context, board, writeType, characteristic, command, length): prev = len(self.full_history) super().commandLogger(context, board, writeType, characteristic, command, length) curr = len(self.full_history) if (prev != curr): if (command[0] == 0x03 and command[1] == 0x83): response = to_string_buffer([0x03, 0x83, 40, 8]) elif (command[0] == 0x13 and command[1] == 0x83): response = to_string_buffer([0x13, 0x83, 40, 3]) elif (command[0] == 0x19 and command[1] == 0x82): response = to_string_buffer([0x19, 0x82, 0x1, 0xf]) else: response = None if (response != None): self.schedule_response(response)
def test_charge_status_signal(self): signal = self.libmetawear.mbl_mw_settings_get_charge_status_data_signal( self.board) self.libmetawear.mbl_mw_datasignal_subscribe(signal, None, self.sensor_data_handler) for value in [0x00, 0x01]: with self.subTest(state=value): self.notify_mw_char(to_string_buffer([0x11, 0x12, value])) self.assertEqual(self.data.value, value)
def test_handle_download(self): expected = [1.16088868, 1793.6878, 3545.5054] self.actual = [] self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[0], None, self.sensor_data_handler) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0x00, 0x3c, 0xe2, 0x01, 0x00, 0x93, 0x12, 0x00, 0x00, 0x00, 0x48, 0x32, 0x02, 0x00, 0x01, 0x1b, 0x70, 0x00 ])) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0x00, 0x53, 0x82, 0x02, 0x00, 0x16, 0x98, 0xdd, 0x00 ])) for a, b in zip(self.actual, expected): self.assertAlmostEqual(a, b, delta=0.001)
def setUp(self): self.boardType = TestMetaWearBase.METAWEAR_RPRO_BOARD self.board = self.libmetawear.mbl_mw_metawearboard_create( byref(self.btle_connection)) state_buffer = to_string_buffer(serializedstate.activity_with_buffer) self.libmetawear.mbl_mw_metawearboard_deserialize( self.board, cast(state_buffer, POINTER(c_ubyte)), len(state_buffer.raw)) self.libmetawear.mbl_mw_metawearboard_initialize( self.board, None, self.initialized_fn)
def test_handle_download(self): expected = CartesianFloat(x=0.060, y=0.077, z=0.991) self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[0], None, self.sensor_data_handler) self.notify_mw_char( to_string_buffer([ 11, 7, -96, -26, 66, 0, 0, -11, 0, 61, 1, -95, -26, 66, 0, 0, -35, 15, 0, 0 ])) self.assertEqual(self.data_cartesian_float, expected)
def setUp(self): self.boardType = TestMetaWearBase.METAWEAR_RPRO_BOARD self.firmware_revision = create_string_buffer(b'1.2.3', 5) self.board = self.libmetawear.mbl_mw_metawearboard_create( byref(self.btle_connection)) state_buffer = to_string_buffer(serializedstate.multi_comparator_state) self.libmetawear.mbl_mw_metawearboard_deserialize( self.board, cast(state_buffer, POINTER(c_ubyte)), len(state_buffer.raw)) self.libmetawear.mbl_mw_metawearboard_initialize( self.board, None, self.initialized_fn)
def test_no_modules(self): self.boardType = TestMetaWearBase.CUSTOM_BOARD self.custom_module_number = b'5' self.lookup_module_response = lambda x: to_string_buffer([x, 0x80]) self.libmetawear.mbl_mw_metawearboard_initialize( self.board, None, self.initialized_fn) self.init_event.wait() self.assertEqual(Const.STATUS_OK, self.init_status) # should not issue command to read current time self.assertNotEqual([0x0b, 0x84], self.command)
def test_count_extraction(self): expected = 492 actual = [] def data_handler(context, data): actual.append(cast(data.contents.extra, POINTER(c_uint)).contents.value) data_handler_fn = FnVoid_VoidP_DataP(data_handler) self.libmetawear.mbl_mw_datasignal_subscribe(self.processors[0], None, data_handler_fn) self.notify_mw_char(to_string_buffer([0x09, 0x03, 0x00, 0xec, 0x01, 0x00, 0x00, 0x01, 0x0b, 0x9a, 0x07, 0x40, 0x40])) self.assertEqual(actual[0], expected)
def test_handle_state_download(self): expected = 3521.868 self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[1], None, self.sensor_data_handler) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0xc1, 0xe9, 0x06, 0x02, 0x00, 0xe3, 0x1d, 0xdc, 0x00 ])) self.assertAlmostEqual(expected, self.data_float.value, delta=0.001)
def test_handle_download(self): self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[0], None, self.sensor_data_handler) self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[1], None, self.sensor_data_handler) expected = CartesianFloat(x=0.060, y=0.077, z=0.991) self.notify_mw_char( to_string_buffer([ 11, 7, 0x60, -26, 66, 0, 0, -11, 0, 61, 1, 0x62, -26, 66, 0, 0, -35, 15, 0, 0 ])) self.assertEqual(self.data_cartesian_float, expected) expected = CartesianFloat(x=224.192, y=170.823, z=147.012) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0x61, 0x38, 0xc2, 0x01, 0x00, 0xe6, 0x72, 0x8c, 0x57, 0x63, 0x38, 0xc2, 0x01, 0x00, 0x58, 0x4b, 0x00, 0x00 ])) self.assertEqual(self.data_cartesian_float, expected)
def test_handle_download(self): results = [] def fused_data_handler(context, data): values = cast(data.contents.value, POINTER(POINTER(Data) * 2)) self.sensorDataHandler(context, values.contents[0]) results.append(self.data) self.sensorDataHandler(context, values.contents[1]) results.append(self.data) fn_wrapper = FnVoid_VoidP_DataP(fused_data_handler) expected = [ CartesianFloat(x=-0.02307129, y=0.02008057, z=1.022278), CartesianFloat(x=0.2591463, y=0.4611281, z=0.04573171), CartesianFloat(x=-0.0123291, y=0.01885986, z=1.031372), CartesianFloat(x=0.3048781, y=0.4954268, z=0.1105183) ] self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[0], None, fn_wrapper) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0xc0, 0xac, 0x1b, 0x00, 0x00, 0x86, 0xfe, 0x49, 0x01, 0xc1, 0xac, 0x1b, 0x00, 0x00, 0x6d, 0x41, 0x44, 0x00 ])) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0xc2, 0xac, 0x1b, 0x00, 0x00, 0x79, 0x00, 0x0c, 0x00, 0xc0, 0xc8, 0x1b, 0x00, 0x00, 0x36, 0xff, 0x35, 0x01 ])) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0xc1, 0xc8, 0x1b, 0x00, 0x00, 0x02, 0x42, 0x50, 0x00, 0xc2, 0xc8, 0x1b, 0x00, 0x00, 0x82, 0x00, 0x1d, 0x00 ])) self.assertEqual(results, expected)
def test_handle_download(self): expected = [32.25, 0, 31.625, -25.0] self.actual = [] for x in range(0, 4): self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[x], None, self.sensor_data_handler) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0xa0, 0xbd, 0x25, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0xa3, 0xbd, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])) self.notify_mw_char( to_string_buffer([ 0x0b, 0x07, 0xa1, 0xbd, 0x25, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0xa2, 0xbd, 0x25, 0x00, 0x00, 0x38, 0xff, 0x00, 0x00 ])) for a, b in zip(self.actual, expected): self.assertAlmostEqual(a, b, delta=0.001)
def test_handle_response(self): tests= [ { 'expected': SensorOrientation.FACE_UP_LANDSCAPE_RIGHT, 'response': [0x03, 0x11, 0x07], 'name': 'fulr' }, { 'expected': SensorOrientation.FACE_UP_PORTRAIT_UPRIGHT, 'response': [0x03, 0x11, 0x01], 'name': 'fupu' }, { 'expected': SensorOrientation.FACE_UP_PORTRAIT_UPSIDE_DOWN, 'response': [0x03, 0x11, 0x03], 'name': 'fupd' }, { 'expected': SensorOrientation.FACE_UP_LANDSCAPE_LEFT, 'response': [0x03, 0x11, 0x05], 'name': 'full' }, { 'expected': SensorOrientation.FACE_DOWN_LANDSCAPE_RIGHT, 'response': [0x03, 0x11, 0x0f], 'name': 'fdlr' }, { 'expected': SensorOrientation.FACE_DOWN_LANDSCAPE_LEFT, 'response': [0x03, 0x11, 0x0d], 'name': 'fdll' }, { 'expected': SensorOrientation.FACE_DOWN_PORTRAIT_UPRIGHT, 'response': [0x03, 0x11, 0x09], 'name': 'fdpu' }, { 'expected': SensorOrientation.FACE_DOWN_PORTRAIT_UPSIDE_DOWN, 'response': [0x03, 0x11, 0x0b], 'name': 'fdpd' } ] for test in tests: with self.subTest(odr= test['name']): orientation = self.libmetawear.mbl_mw_acc_bosch_get_orientation_detection_data_signal(self.board) self.libmetawear.mbl_mw_datasignal_subscribe(orientation, None, self.sensor_data_handler) self.notify_mw_char(to_string_buffer(test['response'])) self.assertEqual(self.data_int32.value, test['expected'])
def test_handle_download(self): expected = [-0.053, -0.015] self.actual = [] self.libmetawear.mbl_mw_anonymous_datasignal_subscribe( self.result['signals'].contents[0], None, self.sensor_data_handler) self.notify_mw_char( to_string_buffer([ 11, 7, 64, 34, 223, 4, 0, 249, 255, 0, 0, 64, 61, 223, 4, 0, 254, 255, 0, 0 ])) for a, b in zip(self.actual, expected): self.assertAlmostEqual(a, b, delta=0.001)