diff --git a/bluesleep.py b/bluesleep.py index c37f520..020e296 100755 --- a/bluesleep.py +++ b/bluesleep.py @@ -332,11 +332,36 @@ def start_data_pull(): while True: try: - band.start_heart_and_gyro(callback=sleep_monitor_callback) + band.start_heart_and_gyro(sensitivity=1, callback=sleep_monitor_callback) except BTLEDisconnectError: band.gyro_started_flag = False connect() +def vibrate_pattern(duration): + print("Sending vibration...") + duration_start = time.time() + pulse_pattern = [[30, 0.01], [60, 0.01], [90, 0.01], [120, 0.01], [150, 0.01], [180, 0.01]] + + while True: + if (time.time() - duration_start) >= duration: + print ("Stopping vibration") + band.vibrate(0) + break + else: + for pattern in pulse_pattern: + if (time.time() - duration_start) >= duration: + break + vibrate_ms = pattern[0] + vibro_delay = pattern[1] + band.vibrate(vibrate_ms) + time.sleep(vibro_delay) + +def vibrate_rolling(): + for x in range(10): + for x in range(20, 40, 1): + band.vibrate(x) + for x in range(40, 20, -1): + band.vibrate(x) if __name__ == "__main__": connect() diff --git a/miband.py b/miband.py index 15c2cec..581d72f 100644 --- a/miband.py +++ b/miband.py @@ -1,6 +1,7 @@ import sys, os, time import logging import struct +import binascii from bluepy.btle import ( Peripheral, DefaultDelegate, @@ -15,14 +16,8 @@ from constants import ( UUIDS, AUTH_STATES, ALERT_TYPES, QUEUE_TYPES, MUSICSTATE ) -try: - from Queue import Queue, Empty -except ImportError: - from queue import Queue, Empty -try: - xrange -except NameError: - xrange = range +from queue import Queue, Empty + class Delegate(DefaultDelegate): @@ -33,17 +28,16 @@ class Delegate(DefaultDelegate): def handleNotification(self, hnd, data): if hnd == self.device._char_auth.getHandle(): - if data[:3] == b'\x10\x01\x01': + if data[:3] == bytepattern.fetch_begin: self.device._req_rdn() - elif data[:3] == b'\x10\x01\x04': + elif data[:3] == bytepattern.fetch_error: self.device.state = AUTH_STATES.KEY_SENDING_FAILED - elif data[:3] == b'\x10\x02\x01': - # 16 bytes + elif data[:3] == bytepattern.fetch_continue: random_nr = data[3:] self.device._send_enc_rdn(random_nr) - elif data[:3] == b'\x10\x02\x04': + elif data[:3] == bytepattern.fetch_complete: self.device.state = AUTH_STATES.REQUEST_RN_ERROR - elif data[:3] == b'\x10\x03\x01': + elif data[:3] == bytepattern.auth_ok: self.device.state = AUTH_STATES.AUTH_OK else: self.device.state = AUTH_STATES.AUTH_FAILED @@ -54,49 +48,6 @@ 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)) - # The fetch characteristic controls the communication with the activity characteristic. - elif hnd == self.device._char_fetch.getHandle(): - if data[:3] == b'\x10\x01\x01': - # get timestamp from what date the data actually is received - year = struct.unpack(" self.device.end_timestamp - timedelta(minutes=1): - print("Finished fetching") - return - print("Trigger more communication") - time.sleep(1) - t = self.device.last_timestamp + timedelta(minutes=1) - self.device.start_get_previews_data(t) - - elif data[:3] == b'\x10\x02\x04': - print("No more activity fetch possible") - return - else: - print("Unexpected data on handle " + str(hnd) + ": " + str(data)) - return - elif hnd == self.device._char_activity.getHandle(): - if len(data) % 4 == 1: - self.pkg += 1 - i = 1 - while i < len(data): - index = int(self.pkg) * 4 + (i - 1) / 4 - timestamp = self.device.first_timestamp + timedelta(minutes=index) - self.device.last_timestamp = timestamp - category = struct.unpack("= duration: - print ("Stopping vibration") - self._char_alert.write(b'\x00\x00\x00\x00\x00\x00', withResponse=False) - break - else: - if ((time.time() - pulse_time)*1000) >= vibro_current_value: - pulse_time = time.time() - self._char_alert.write(b'\xff' + (vibro_current_value).to_bytes(1, 'big') + b'\x00\x00\x00\x01', withResponse=False) - vibro_current_value += 1 - print (vibro_current_value) - if vibro_current_value > 255: - vibro_current_value = vibro_start_value + def vibrate(self, ms): + vibration_scaler = 0.75 + ms = min([round(ms / vibration_scaler), 255]) + sent_value = int(ms / 2) + vibration_duration = ms / 1000 + self._char_alert.write(bytepattern.vibration(sent_value), withResponse=False) + time.sleep(vibration_duration) - def send_gyro_start(self): + def send_gyro_start(self, sensitivity): if not self.gyro_started_flag: self._log.info("Starting gyro...") - self.writeCharacteristic(self._sensor_handle, self.start_bytes, withResponse=True) - self.writeCharacteristic(self._steps_handle, self.start_bytes, withResponse=True) - self.writeCharacteristic(self._hz_handle, self.start_bytes, withResponse=True) + self.writeCharacteristic(self._sensor_handle, bytepattern.start, withResponse=True) + self.writeCharacteristic(self._steps_handle, bytepattern.start, withResponse=True) + self.writeCharacteristic(self._hz_handle, bytepattern.start, withResponse=True) self.gyro_started_flag = True - self._char_sensor.write(b'\x01' + bytes([self.gyro_sensitivity]) + b'\x19', withResponse=False) - self.writeCharacteristic(self._sensor_handle, self.stop_bytes, withResponse=True) + self._char_sensor.write(bytepattern.gyro_start(sensitivity), withResponse=False) + self.writeCharacteristic(self._sensor_handle, bytepattern.stop, withResponse=True) self._char_sensor.write(b'\x02', withResponse=False) def send_heart_measure_start(self): self._log.info("Starting heart measure...") - # stop heart monitor continues & manual - self._char_heart_ctrl.write(b'\x15\x02\x00', True) - self._char_heart_ctrl.write(b'\x15\x01\x00', True) - # enable heart monitor notifications - self.writeCharacteristic(self._heart_measure_handle, self.start_bytes, withResponse=True) - # start heart monitor continues - self._char_heart_ctrl.write(b'\x15\x01\x01', True) + self._char_heart_ctrl.write(bytepattern.stop_heart_measure_manual, True) + self._char_heart_ctrl.write(bytepattern.stop_heart_measure_continues, True) + self.writeCharacteristic(self._heart_measure_handle, bytepattern.start, withResponse=True) + self._char_heart_ctrl.write(bytepattern.start_heart_measure_continues, True) def send_heart_measure_keepalive(self): - self._char_heart_ctrl.write(b'\x16', True) + self._char_heart_ctrl.write(bytepattern.heart_measure_keepalive, True) - def start_heart_and_gyro(self, callback): + def start_heart_and_gyro(self, sensitivity, callback): self.heart_measure_callback = callback self.gyro_raw_callback = callback - self.send_gyro_start() + self.send_gyro_start(sensitivity) self.send_heart_measure_start() heartbeat_time = time.time() @@ -323,4 +278,4 @@ class miband(Peripheral): if (time.time() - heartbeat_time) >= 12: heartbeat_time = time.time() self.send_heart_measure_keepalive() - self.send_gyro_start() \ No newline at end of file + self.send_gyro_start(sensitivity) \ No newline at end of file diff --git a/sleepdata.py b/sleepdata.py index 7ae03b9..7a42b7a 100644 --- a/sleepdata.py +++ b/sleepdata.py @@ -1,4 +1,24 @@ -class SleepData(): +class Sleep_Data(object): def __init__(self): print("init") + + sleep_data = { + 'heartrate': { + 'value_name': 'bpm', + 'periods': [2, 5, 10, 15], + 'raw_data': [], + 'averaged_data': [], + }, + 'movement':{ + 'value_name': 'movement', + 'periods': [10, 30, 60], + 'raw_data': [], + 'averaged_data': [], + 'workspace': { + 'gyro_last_x' : 0, + 'gyro_last_y' : 0, + 'gyro_last_z' : 0 + } + } + } \ No newline at end of file