Added heartrate alarm

This commit is contained in:
NateSchoolfield 2021-02-15 20:04:48 -08:00
parent bca9e148fa
commit c3bc050593
10 changed files with 831 additions and 10 deletions

8
.gitignore vendored
View File

@ -1,5 +1,6 @@
mac.txt mac*.txt
auth_key.txt auth_key*.txt
*.sh
*.pyc *.pyc
/__pycache__ /__pycache__
*.swp *.swp
@ -8,3 +9,6 @@ auth_key.txt
*.code-workspace *.code-workspace
/.vscode /.vscode
/data /data
datafilter.py
crymonitor.py

View File

@ -15,9 +15,10 @@ mac_filename = 'mac.txt'
maximize_graph = False maximize_graph = False
vibration_settings = { vibration_settings = {
'interval_minutes': 0.1, 'interval_minutes': 20,
'duration_seconds': 5, 'duration_seconds': 10,
'type': 'random' 'type': 'random',
'heartrate_alarm_pct': 17
} }
band = None band = None
@ -65,7 +66,7 @@ def average_data(tick_time):
sleepdata.average_raw_data(tick_time) sleepdata.average_raw_data(tick_time)
sleepdata.last_tick_time = time.time() sleepdata.last_tick_time = time.time()
def sleep_monitor_callback(data): def sleep_monitor_callback(data):
tick_time = time.time() tick_time = time.time()
@ -79,6 +80,9 @@ def sleep_monitor_callback(data):
average_data(tick_time) average_data(tick_time)
vibration.heartrate_increase_pct = sleepdata.analyze_heartrate(10)
print("HR increase percent: {}".format(vibration.heartrate_increase_pct))
def connect(): def connect():
global band global band
@ -113,7 +117,9 @@ def start_data_pull():
def start_vibration(): def start_vibration():
while True: while True:
try: try:
vibration.timed_vibration(vibration_settings) #vibration.timed_vibration(vibration_settings)
vibration.heartrate_alarm(vibration_settings)
except BTLEDisconnectError: except BTLEDisconnectError:
print("Vibration thread waiting for band reconnect...") print("Vibration thread waiting for band reconnect...")
time.sleep(1) time.sleep(1)

164
bluesleep.py.orig Executable file
View File

@ -0,0 +1,164 @@
#!/usr/bin/env python3
import time, re, threading
from bluepy.btle import BTLEDisconnectError
from miband import miband
import sleepdata
from vibrate import Vibrate
auth_key_filename = 'auth_key.txt'
mac_filename = 'mac.txt'
maximize_graph = False
vibration_settings = {
<<<<<<< Updated upstream
<<<<<<< Updated upstream
<<<<<<< Updated upstream
'interval_minutes': 0.1,
'duration_seconds': 5,
'type': 'random'
=======
=======
>>>>>>> Stashed changes
'interval_minutes': 20,
'duration_seconds': 10,
'type': 'random',
'heartrate_alarm_pct': 17
<<<<<<< Updated upstream
>>>>>>> Stashed changes
=======
>>>>>>> Stashed changes
||||||| constructed merge base
'interval_minutes': 45,
'duration_seconds': 5,
'type': 'random'
=======
'interval_minutes': 20,
'duration_seconds': 10,
'type': 'random',
'heartrate_alarm_pct': 17
>>>>>>> Stashed changes
}
band = None
#-------------------------------------------------------------------------#
class regex_patterns():
mac_regex_pattern = re.compile(r'([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})')
authkey_regex_pattern = re.compile(r'([0-9a-fA-F]){32}')
def get_mac_address(filename):
try:
with open(filename, "r") as f:
hwaddr_search = re.search(regex_patterns.mac_regex_pattern, f.read().strip())
if hwaddr_search:
MAC_ADDR = hwaddr_search[0]
else:
print ("No valid MAC address found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("MAC file not found: {}".format(filename))
exit(1)
return MAC_ADDR
def get_auth_key(filename):
try:
with open(filename, "r") as f:
key_search = re.search(regex_patterns.authkey_regex_pattern, f.read().strip())
if key_search:
AUTH_KEY = bytes.fromhex(key_search[0])
else:
print ("No valid auth key found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("Auth key file not found: {}".format(filename))
exit(1)
return AUTH_KEY
def average_data(tick_time):
if (tick_time - sleepdata.last_tick_time) >= sleepdata.tick_seconds:
sleepdata.average_raw_data(tick_time)
sleepdata.last_tick_time = time.time()
def sleep_monitor_callback(data):
tick_time = time.time()
if not sleepdata.last_tick_time:
sleepdata.last_tick_time = time.time()
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)
average_data(tick_time)
vibration.heartrate_increase_pct = sleepdata.analyze_heartrate(10)
print("HR increase percent: {}".format(vibration.heartrate_increase_pct))
def connect():
global band
success = False
timeout = 3
msg = 'Connection to the band failed. Trying again in {} seconds'
MAC_ADDR = get_mac_address(mac_filename)
AUTH_KEY = get_auth_key(auth_key_filename)
while not success:
try:
band = miband(MAC_ADDR, AUTH_KEY, debug=True)
success = band.initialize()
except BTLEDisconnectError:
print(msg.format(timeout))
time.sleep(timeout)
except KeyboardInterrupt:
print("\nExit.")
exit()
def start_data_pull():
while True:
try:
band.start_heart_and_gyro(sensitivity=1, callback=sleep_monitor_callback)
except BTLEDisconnectError:
band.gyro_started_flag = False
connect()
def start_vibration():
while True:
try:
#vibration.timed_vibration(vibration_settings)
vibration.heartrate_alarm(vibration_settings)
except BTLEDisconnectError:
print("Vibration thread waiting for band reconnect...")
time.sleep(1)
if __name__ == "__main__":
connect()
vibration = Vibrate(band)
threading.Thread(target=start_data_pull).start()
threading.Thread(target=start_vibration).start()
sleepdata.init_graph(maximize=maximize_graph, graph_displaytime_mins=5)
#import simpleaudio as sa
# comfort_wav = 'comfort.wav'
# wave_obj = sa.WaveObject.from_wave_file(comfort_wav)
# comfort_delay = 30
# comfort_lasttime = time.time()

153
bluesleep_BACKUP_570995.py Executable file
View File

@ -0,0 +1,153 @@
#!/usr/bin/env python3
import time, re, threading
from bluepy.btle import BTLEDisconnectError
from miband import miband
import sleepdata
from vibrate import Vibrate
auth_key_filename = 'auth_key.txt'
mac_filename = 'mac.txt'
maximize_graph = False
vibration_settings = {
<<<<<<< Updated upstream
<<<<<<< Updated upstream
'interval_minutes': 0.1,
'duration_seconds': 5,
'type': 'random'
=======
=======
>>>>>>> Stashed changes
'interval_minutes': 20,
'duration_seconds': 10,
'type': 'random',
'heartrate_alarm_pct': 17
<<<<<<< Updated upstream
>>>>>>> Stashed changes
=======
>>>>>>> Stashed changes
}
band = None
#-------------------------------------------------------------------------#
class regex_patterns():
mac_regex_pattern = re.compile(r'([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})')
authkey_regex_pattern = re.compile(r'([0-9a-fA-F]){32}')
def get_mac_address(filename):
try:
with open(filename, "r") as f:
hwaddr_search = re.search(regex_patterns.mac_regex_pattern, f.read().strip())
if hwaddr_search:
MAC_ADDR = hwaddr_search[0]
else:
print ("No valid MAC address found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("MAC file not found: {}".format(filename))
exit(1)
return MAC_ADDR
def get_auth_key(filename):
try:
with open(filename, "r") as f:
key_search = re.search(regex_patterns.authkey_regex_pattern, f.read().strip())
if key_search:
AUTH_KEY = bytes.fromhex(key_search[0])
else:
print ("No valid auth key found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("Auth key file not found: {}".format(filename))
exit(1)
return AUTH_KEY
def average_data(tick_time):
if (tick_time - sleepdata.last_tick_time) >= sleepdata.tick_seconds:
sleepdata.average_raw_data(tick_time)
sleepdata.last_tick_time = time.time()
def sleep_monitor_callback(data):
tick_time = time.time()
if not sleepdata.last_tick_time:
sleepdata.last_tick_time = time.time()
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)
average_data(tick_time)
vibration.heartrate_increase_pct = sleepdata.analyze_heartrate(10)
print("HR increase percent: {}".format(vibration.heartrate_increase_pct))
def connect():
global band
success = False
timeout = 3
msg = 'Connection to the band failed. Trying again in {} seconds'
MAC_ADDR = get_mac_address(mac_filename)
AUTH_KEY = get_auth_key(auth_key_filename)
while not success:
try:
band = miband(MAC_ADDR, AUTH_KEY, debug=True)
success = band.initialize()
except BTLEDisconnectError:
print(msg.format(timeout))
time.sleep(timeout)
except KeyboardInterrupt:
print("\nExit.")
exit()
def start_data_pull():
while True:
try:
band.start_heart_and_gyro(sensitivity=1, callback=sleep_monitor_callback)
except BTLEDisconnectError:
band.gyro_started_flag = False
connect()
def start_vibration():
while True:
try:
#vibration.timed_vibration(vibration_settings)
vibration.heartrate_alarm(vibration_settings)
except BTLEDisconnectError:
print("Vibration thread waiting for band reconnect...")
time.sleep(1)
if __name__ == "__main__":
connect()
vibration = Vibrate(band)
threading.Thread(target=start_data_pull).start()
threading.Thread(target=start_vibration).start()
sleepdata.init_graph(maximize=maximize_graph, graph_displaytime_mins=5)
#import simpleaudio as sa
# comfort_wav = 'comfort.wav'
# wave_obj = sa.WaveObject.from_wave_file(comfort_wav)
# comfort_delay = 30
# comfort_lasttime = time.time()

135
bluesleep_BASE_570995.py Normal file
View File

@ -0,0 +1,135 @@
#!/usr/bin/env python3
import time, re, threading
from bluepy.btle import BTLEDisconnectError
from miband import miband
import sleepdata
from vibrate import Vibrate
auth_key_filename = 'auth_key.txt'
mac_filename = 'mac.txt'
maximize_graph = False
vibration_settings = {
'interval_minutes': 45,
'duration_seconds': 5,
'type': 'random'
}
band = None
#-------------------------------------------------------------------------#
class regex_patterns():
mac_regex_pattern = re.compile(r'([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})')
authkey_regex_pattern = re.compile(r'([0-9a-fA-F]){32}')
def get_mac_address(filename):
try:
with open(filename, "r") as f:
hwaddr_search = re.search(regex_patterns.mac_regex_pattern, f.read().strip())
if hwaddr_search:
MAC_ADDR = hwaddr_search[0]
else:
print ("No valid MAC address found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("MAC file not found: {}".format(filename))
exit(1)
return MAC_ADDR
def get_auth_key(filename):
try:
with open(filename, "r") as f:
key_search = re.search(regex_patterns.authkey_regex_pattern, f.read().strip())
if key_search:
AUTH_KEY = bytes.fromhex(key_search[0])
else:
print ("No valid auth key found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("Auth key file not found: {}".format(filename))
exit(1)
return AUTH_KEY
def average_data(tick_time):
if (tick_time - sleepdata.last_tick_time) >= sleepdata.tick_seconds:
sleepdata.average_raw_data(tick_time)
sleepdata.last_tick_time = time.time()
def sleep_monitor_callback(data):
tick_time = time.time()
if not sleepdata.last_tick_time:
sleepdata.last_tick_time = time.time()
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)
average_data(tick_time)
def connect():
global band
success = False
timeout = 3
msg = 'Connection to the band failed. Trying again in {} seconds'
MAC_ADDR = get_mac_address(mac_filename)
AUTH_KEY = get_auth_key(auth_key_filename)
while not success:
try:
band = miband(MAC_ADDR, AUTH_KEY, debug=True)
success = band.initialize()
except BTLEDisconnectError:
print(msg.format(timeout))
time.sleep(timeout)
except KeyboardInterrupt:
print("\nExit.")
exit()
def start_data_pull():
while True:
try:
band.start_heart_and_gyro(sensitivity=1, callback=sleep_monitor_callback)
except BTLEDisconnectError:
band.gyro_started_flag = False
connect()
def start_vibration():
while True:
try:
vibration.timed_vibration(vibration_settings)
except BTLEDisconnectError:
print("Vibration thread waiting for band reconnect...")
time.sleep(1)
if __name__ == "__main__":
connect()
vibration = Vibrate(band)
threading.Thread(target=start_data_pull).start()
threading.Thread(target=start_vibration).start()
sleepdata.init_graph(maximize=maximize_graph, graph_displaytime_mins=5)
#import simpleaudio as sa
# comfort_wav = 'comfort.wav'
# wave_obj = sa.WaveObject.from_wave_file(comfort_wav)
# comfort_delay = 30
# comfort_lasttime = time.time()

147
bluesleep_LOCAL_570995.py Normal file
View File

@ -0,0 +1,147 @@
#!/usr/bin/env python3
import time, re, threading
from bluepy.btle import BTLEDisconnectError
from miband import miband
import sleepdata
from vibrate import Vibrate
auth_key_filename = 'auth_key.txt'
mac_filename = 'mac.txt'
maximize_graph = False
vibration_settings = {
<<<<<<< Updated upstream
'interval_minutes': 0.1,
'duration_seconds': 5,
'type': 'random'
=======
'interval_minutes': 20,
'duration_seconds': 10,
'type': 'random',
'heartrate_alarm_pct': 17
>>>>>>> Stashed changes
}
band = None
#-------------------------------------------------------------------------#
class regex_patterns():
mac_regex_pattern = re.compile(r'([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})')
authkey_regex_pattern = re.compile(r'([0-9a-fA-F]){32}')
def get_mac_address(filename):
try:
with open(filename, "r") as f:
hwaddr_search = re.search(regex_patterns.mac_regex_pattern, f.read().strip())
if hwaddr_search:
MAC_ADDR = hwaddr_search[0]
else:
print ("No valid MAC address found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("MAC file not found: {}".format(filename))
exit(1)
return MAC_ADDR
def get_auth_key(filename):
try:
with open(filename, "r") as f:
key_search = re.search(regex_patterns.authkey_regex_pattern, f.read().strip())
if key_search:
AUTH_KEY = bytes.fromhex(key_search[0])
else:
print ("No valid auth key found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("Auth key file not found: {}".format(filename))
exit(1)
return AUTH_KEY
def average_data(tick_time):
if (tick_time - sleepdata.last_tick_time) >= sleepdata.tick_seconds:
sleepdata.average_raw_data(tick_time)
sleepdata.last_tick_time = time.time()
def sleep_monitor_callback(data):
tick_time = time.time()
if not sleepdata.last_tick_time:
sleepdata.last_tick_time = time.time()
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)
average_data(tick_time)
vibration.heartrate_increase_pct = sleepdata.analyze_heartrate(10)
print("HR increase percent: {}".format(vibration.heartrate_increase_pct))
def connect():
global band
success = False
timeout = 3
msg = 'Connection to the band failed. Trying again in {} seconds'
MAC_ADDR = get_mac_address(mac_filename)
AUTH_KEY = get_auth_key(auth_key_filename)
while not success:
try:
band = miband(MAC_ADDR, AUTH_KEY, debug=True)
success = band.initialize()
except BTLEDisconnectError:
print(msg.format(timeout))
time.sleep(timeout)
except KeyboardInterrupt:
print("\nExit.")
exit()
def start_data_pull():
while True:
try:
band.start_heart_and_gyro(sensitivity=1, callback=sleep_monitor_callback)
except BTLEDisconnectError:
band.gyro_started_flag = False
connect()
def start_vibration():
while True:
try:
#vibration.timed_vibration(vibration_settings)
vibration.heartrate_alarm(vibration_settings)
except BTLEDisconnectError:
print("Vibration thread waiting for band reconnect...")
time.sleep(1)
if __name__ == "__main__":
connect()
vibration = Vibrate(band)
threading.Thread(target=start_data_pull).start()
threading.Thread(target=start_vibration).start()
sleepdata.init_graph(maximize=maximize_graph, graph_displaytime_mins=5)
#import simpleaudio as sa
# comfort_wav = 'comfort.wav'
# wave_obj = sa.WaveObject.from_wave_file(comfort_wav)
# comfort_delay = 30
# comfort_lasttime = time.time()

141
bluesleep_REMOTE_570995.py Normal file
View File

@ -0,0 +1,141 @@
#!/usr/bin/env python3
import time, re, threading
from bluepy.btle import BTLEDisconnectError
from miband import miband
import sleepdata
from vibrate import Vibrate
auth_key_filename = 'auth_key.txt'
mac_filename = 'mac.txt'
maximize_graph = False
vibration_settings = {
'interval_minutes': 20,
'duration_seconds': 10,
'type': 'random',
'heartrate_alarm_pct': 17
}
band = None
#-------------------------------------------------------------------------#
class regex_patterns():
mac_regex_pattern = re.compile(r'([0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5})')
authkey_regex_pattern = re.compile(r'([0-9a-fA-F]){32}')
def get_mac_address(filename):
try:
with open(filename, "r") as f:
hwaddr_search = re.search(regex_patterns.mac_regex_pattern, f.read().strip())
if hwaddr_search:
MAC_ADDR = hwaddr_search[0]
else:
print ("No valid MAC address found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("MAC file not found: {}".format(filename))
exit(1)
return MAC_ADDR
def get_auth_key(filename):
try:
with open(filename, "r") as f:
key_search = re.search(regex_patterns.authkey_regex_pattern, f.read().strip())
if key_search:
AUTH_KEY = bytes.fromhex(key_search[0])
else:
print ("No valid auth key found in {}".format(filename))
exit(1)
except FileNotFoundError:
print ("Auth key file not found: {}".format(filename))
exit(1)
return AUTH_KEY
def average_data(tick_time):
if (tick_time - sleepdata.last_tick_time) >= sleepdata.tick_seconds:
sleepdata.average_raw_data(tick_time)
sleepdata.last_tick_time = time.time()
def sleep_monitor_callback(data):
tick_time = time.time()
if not sleepdata.last_tick_time:
sleepdata.last_tick_time = time.time()
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)
average_data(tick_time)
vibration.heartrate_increase_pct = sleepdata.analyze_heartrate(10)
print("HR increase percent: {}".format(vibration.heartrate_increase_pct))
def connect():
global band
success = False
timeout = 3
msg = 'Connection to the band failed. Trying again in {} seconds'
MAC_ADDR = get_mac_address(mac_filename)
AUTH_KEY = get_auth_key(auth_key_filename)
while not success:
try:
band = miband(MAC_ADDR, AUTH_KEY, debug=True)
success = band.initialize()
except BTLEDisconnectError:
print(msg.format(timeout))
time.sleep(timeout)
except KeyboardInterrupt:
print("\nExit.")
exit()
def start_data_pull():
while True:
try:
band.start_heart_and_gyro(sensitivity=1, callback=sleep_monitor_callback)
except BTLEDisconnectError:
band.gyro_started_flag = False
connect()
def start_vibration():
while True:
try:
#vibration.timed_vibration(vibration_settings)
vibration.heartrate_alarm(vibration_settings)
except BTLEDisconnectError:
print("Vibration thread waiting for band reconnect...")
time.sleep(1)
if __name__ == "__main__":
connect()
vibration = Vibrate(band)
threading.Thread(target=start_data_pull).start()
threading.Thread(target=start_vibration).start()
sleepdata.init_graph(maximize=maximize_graph, graph_displaytime_mins=5)
#import simpleaudio as sa
# comfort_wav = 'comfort.wav'
# wave_obj = sa.WaveObject.from_wave_file(comfort_wav)
# comfort_delay = 30
# comfort_lasttime = time.time()

View File

@ -231,7 +231,7 @@ class miband(Peripheral):
def _parse_heart_measure(self, bytes): def _parse_heart_measure(self, bytes):
res = struct.unpack('bb', bytes)[1] res = struct.unpack('bb', bytes)[1]
return_tuple = ["HR", res] return_tuple = ["HR", res]
print("BPM: {}".format(res)) #print("BPM: {}".format(res))
return return_tuple return return_tuple
@ -301,6 +301,16 @@ class miband(Peripheral):
self.waitForNotifications(wait) self.waitForNotifications(wait)
# def send_gyro_start(self, sensitivity):
# if not self.gyro_started_flag:
# self._log.info("Starting gyro...")
# self.write_req(self._sensor_handle, BYTEPATTERNS.start)
# self.write_req(self._steps_handle, BYTEPATTERNS.start)
# self.write_req(self._hz_handle, BYTEPATTERNS.start)
# self.gyro_started_flag = True
# self.write_cmd(self._char_sensor, BYTEPATTERNS.gyro_start(sensitivity))
# self.write_req(self._sensor_handle, BYTEPATTERNS.stop)
# self.write_cmd(self._char_sensor, b'\x02')
def send_gyro_start(self, sensitivity): def send_gyro_start(self, sensitivity):
if not self.gyro_started_flag: if not self.gyro_started_flag:
self._log.info("Starting gyro...") self._log.info("Starting gyro...")
@ -309,9 +319,10 @@ class miband(Peripheral):
self.write_req(self._hz_handle, BYTEPATTERNS.start) self.write_req(self._hz_handle, BYTEPATTERNS.start)
self.gyro_started_flag = True self.gyro_started_flag = True
self.write_cmd(self._char_sensor, BYTEPATTERNS.gyro_start(sensitivity)) self.write_cmd(self._char_sensor, BYTEPATTERNS.gyro_start(sensitivity))
self.write_cmd(self._char_sensor, bytes.fromhex("010100000019"))
self.write_req(self._sensor_handle, BYTEPATTERNS.stop) self.write_req(self._sensor_handle, BYTEPATTERNS.stop)
self.write_cmd(self._char_sensor, b'\x02') self.write_cmd(self._char_sensor, b'\x02')
self.write_cmd(self._char_sensor, b'\x03')
def send_heart_measure_start(self): def send_heart_measure_start(self):
self._log.info("Starting heart measure...") self._log.info("Starting heart measure...")

View File

@ -12,6 +12,7 @@ sleep_data = {
'periods': [2, 5, 10, 15], 'periods': [2, 5, 10, 15],
'raw_data': [], 'raw_data': [],
'averaged_data': [], 'averaged_data': [],
'last_hr': []
}, },
'movement':{ 'movement':{
'value_name': 'movement', 'value_name': 'movement',
@ -173,6 +174,7 @@ def process_gyro_data(gyro_data, tick_time):
def process_heartrate_data(heartrate_data, tick_time): def process_heartrate_data(heartrate_data, tick_time):
last_heartrate_count = 20
print("BPM: " + str(heartrate_data)) print("BPM: " + str(heartrate_data))
if heartrate_data > 0: if heartrate_data > 0:
value_name = sleep_data['heartrate']['value_name'] value_name = sleep_data['heartrate']['value_name']
@ -181,6 +183,21 @@ def process_heartrate_data(heartrate_data, tick_time):
value_name: heartrate_data value_name: heartrate_data
} ) } )
if len(sleep_data['heartrate']['last_hr']) > last_heartrate_count:
sleep_data['heartrate']['last_hr'].pop(0)
sleep_data['heartrate']['last_hr'].append(heartrate_data)
def analyze_heartrate(hr_count):
# Finds the pct change between the lowest HR in the last $hr_count samples and the current HR
pct_heartrate_increase = 0
if len(sleep_data['heartrate']['last_hr']) >= hr_count:
last_heartrate_list = sleep_data['heartrate']['last_hr'][-hr_count:]
last_heartrate_min = min(last_heartrate_list)
current_heartrate = last_heartrate_list[-1]
pct_heartrate_increase = int((current_heartrate - last_heartrate_min)/last_heartrate_min*100)
return pct_heartrate_increase
def zero_to_nan(value): def zero_to_nan(value):
if value == 0: if value == 0:

View File

@ -12,6 +12,8 @@ import logging
class Vibrate(): class Vibrate():
vibrate_band = None vibrate_band = None
vibration_log = None vibration_log = None
heartrate_increase_pct = 0
def __init__(self, band): def __init__(self, band):
self.vibrate_band = band self.vibrate_band = band
@ -22,12 +24,53 @@ class Vibrate():
self.vibration_log = logging.getLogger(__name__) self.vibration_log = logging.getLogger(__name__)
self.vibration_log.setLevel(vibration_log_level) self.vibration_log.setLevel(vibration_log_level)
def heartrate_alarm(self, settings):
interval_minutes = settings['interval_minutes']
duration_seconds = settings['duration_seconds']
type = settings['type']
heartrate_alarm_pct = settings['heartrate_alarm_pct']
tick_time = time.time()
buzz_delay = interval_minutes * 60
buzz_timer = tick_time - buzz_delay
self.vibration_log.info("Starting heartrate alarm timer, alarming at {} percent for {} seconds with a {} minute interval".format(
heartrate_alarm_pct,
duration_seconds,
interval_minutes))
if type not in ['random', 'pattern', 'rolling', 'continuous']:
self.vibration_log.warn("Invalid or no vibration type specified: {}".format(type))
self.vibration_log.warn("Must be one of these: random, pattern, rolling, continuous")
return
while True:
elapsed_time = tick_time - buzz_timer
if elapsed_time >= buzz_delay and self.heartrate_increase_pct >= heartrate_alarm_pct:
self.vibration_log.info("Heartrate alarm triggered at {} percent, buzzing".format(self.heartrate_increase_pct))
if type == 'random':
self.vibrate_random(duration_seconds)
elif type == 'pattern':
self.vibrate_pattern(duration_seconds)
elif type == 'rolling':
self.vibrate_rolling(duration_seconds)
elif type == 'continuous':
self.vibrate_continuous(duration_seconds)
buzz_timer = tick_time
elif not elapsed_time >= buzz_delay and self.heartrate_increase_pct >= heartrate_alarm_pct:
self.vibration_log.info("Heartrate alarm threshold reached ({} percent) but timout not expired".format(self.heartrate_increase_pct))
else:
tick_time = time.time()
time.sleep(0.5)
def timed_vibration(self, settings): def timed_vibration(self, settings):
interval_minutes = settings['interval_minutes'] interval_minutes = settings['interval_minutes']
duration_seconds = settings['duration_seconds'] duration_seconds = settings['duration_seconds']
type = settings['type'] type = settings['type']
buzz_timer = time.time() buzz_timer = time.time()
tick_time = time.time() tick_time = time.time()
buzz_delay = interval_minutes * 60 buzz_delay = interval_minutes * 60