From 1f8555fc9aacfba1744856075eac20c857f9f8b2 Mon Sep 17 00:00:00 2001 From: NateSchoolfield Date: Fri, 5 Feb 2021 13:20:53 -0800 Subject: [PATCH] Decoded another mystery BLE packet --- bluesleep.py | 8 ++++-- constants.py | 2 ++ miband.py | 79 +++++++++++++++++++++++++++++++++++++++++----------- sleepdata.py | 58 ++++++++++++++++++++++++-------------- 4 files changed, 107 insertions(+), 40 deletions(-) diff --git a/bluesleep.py b/bluesleep.py index fb51f49..4661751 100755 --- a/bluesleep.py +++ b/bluesleep.py @@ -10,8 +10,10 @@ import sleepdata, vibrate auth_key_filename = 'auth_key.txt' mac_filename = 'mac.txt' +maximize_graph = False + vibration_settings = { - 'interval_minutes': 0.2, + 'interval_minutes': 45, 'duration_seconds': 5, 'type': 'random' } @@ -68,7 +70,7 @@ def sleep_monitor_callback(data): if not sleepdata.last_tick_time: sleepdata.last_tick_time = time.time() - if data[0] == "GYRO": + if data[0] == "GYRO_RAW": sleepdata.process_gyro_data(data[1], tick_time) elif data[0] == "HR": sleepdata.process_heartrate_data(data[1], tick_time) @@ -120,7 +122,7 @@ if __name__ == "__main__": connect() threading.Thread(target=start_data_pull).start() threading.Thread(target=start_vibration).start() - sleepdata.init_graph(maximize=True) + sleepdata.init_graph(maximize=maximize_graph, graph_displaytime_mins=5) diff --git a/constants.py b/constants.py index 7485dc7..3692015 100644 --- a/constants.py +++ b/constants.py @@ -88,3 +88,5 @@ class QUEUE_TYPES(object): HEART = 'heart' RAW_ACCEL = 'raw_accel' RAW_HEART = 'raw_heart' + RAW_GYRO = 'raw_gyro' + AVG_GYRO = 'avg_gyro' \ No newline at end of file diff --git a/miband.py b/miband.py index de4de31..fbc215d 100644 --- a/miband.py +++ b/miband.py @@ -1,7 +1,6 @@ import sys, os, time import logging import struct -import binascii from bytepatterns import miband4 as bytepattern @@ -50,14 +49,26 @@ class Delegate(DefaultDelegate): self.device.queue.put((QUEUE_TYPES.RAW_ACCEL, data)) elif len(data) == 16: self.device.queue.put((QUEUE_TYPES.RAW_HEART, data)) + else: + print("Unhandled data on handle 0x38: {}".format(data)) elif hnd == self.device._char_hz.getHandle(): if len(data) == 20 and struct.unpack('b', data[0:1])[0] == 1: self.device.queue.put((QUEUE_TYPES.RAW_ACCEL, data)) + elif len(data) == 11: + #print("Unknown data: {}".format(bytes.hex(data, " "))) + #print(struct.unpack('BBBBBBBBBB', data[1:])) + # Seems to be a counter of the time the gyro is enabled. + #print(struct.unpack(">x2L", data)) + #print(struct.unpack(" 1: - g_data = graph_data[data_type] # Re-referenced to short name + g_data = graph_data[data_type] data_periods = s_data['periods'] starting_index = max([(len(g_data['time']) - 1), 0]) @@ -209,13 +223,11 @@ def init_graph_data(): def graph_animation(i): - global graph_axes - global graph_data - plotflag = False - + if len(graph_data) == 0: init_graph_data() + flush_old_graph_data(graph_displaytime_minutes) update_graph_data() for data_type in graph_data: @@ -223,6 +235,7 @@ def graph_animation(i): graph_axes.clear() break + plotflag = False for data_type in sleep_data: s_data = sleep_data[data_type] g_data = graph_data[data_type] @@ -239,10 +252,13 @@ def graph_animation(i): plt.legend() -def init_graph(maximize=False): +def init_graph(graph_displaytime_mins=60, maximize=False): + global graph_displaytime_minutes + graph_displaytime_minutes = graph_displaytime_mins if maximize: figure_manager = plt.get_current_fig_manager() figure_manager.full_screen_toggle() + ani = animation.FuncAnimation(graph_figure, graph_animation, interval=1000) plt.show()