import sys, os, time import logging import struct from bluepy.btle import ( Peripheral, DefaultDelegate, ADDR_TYPE_RANDOM, ADDR_TYPE_PUBLIC, BTLEException, BTLEDisconnectError ) from datetime import datetime, timedelta from Crypto.Cipher import AES from datetime import datetime 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 class Delegate(DefaultDelegate): def __init__(self, device): DefaultDelegate.__init__(self) self.device = device self.pkg = 0 def handleNotification(self, hnd, data): if hnd == self.device._char_auth.getHandle(): if data[:3] == b'\x10\x01\x01': self.device._req_rdn() elif data[:3] == b'\x10\x01\x04': self.device.state = AUTH_STATES.KEY_SENDING_FAILED elif data[:3] == b'\x10\x02\x01': # 16 bytes random_nr = data[3:] self.device._send_enc_rdn(random_nr) elif data[:3] == b'\x10\x02\x04': self.device.state = AUTH_STATES.REQUEST_RN_ERROR elif data[:3] == b'\x10\x03\x01': self.device.state = AUTH_STATES.AUTH_OK else: self.device.state = AUTH_STATES.AUTH_FAILED elif hnd == self.device._char_heart_measure.getHandle(): self.device.queue.put((QUEUE_TYPES.HEART, data)) elif hnd == 0x38: 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) == 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 send_gyro_start(self): 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.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(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) def send_heart_measure_keepalive(self): self._char_heart_ctrl.write(b'\x16', True) def start_heart_and_gyro(self, callback): self.heart_measure_callback = callback self.gyro_raw_callback = callback self.send_gyro_start() self.send_heart_measure_start() heartbeat_time = time.time() while True: self.waitForNotifications(0.5) self._parse_queue() if (time.time() - heartbeat_time) >= 12: heartbeat_time = time.time() self.send_heart_measure_keepalive() self.send_gyro_start()