HeartRate.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import bluetooth
  2. FLAG_SRV_BSL = 0x01 # 感器位置服务
  3. FLAG_SRV_APPEND = 0x02 # 其他附加服务
  4. SENSOR_LOC_OTHER = 0X00
  5. SENSOR_LOC_CHEST = 0X01
  6. SENSOR_LOC_WRIST = 0X02
  7. SENSOR_LOC_FINGER = 0X03
  8. SENSOR_LOC_HAND = 0X04
  9. SENSOR_LOC_EAR_LOBE = 0X05
  10. SENSOR_LOC_FOOT = 0X06
  11. class Sender():
  12. hr_uuid = 0x180D
  13. hrm_uuid = 0x2A37
  14. bsl_uuid = 0x2A38 # body sensor location uuid
  15. hrm_handle = 20
  16. bsl_handle = 21
  17. sensor_locations = ["Other","Chest","Wrist","Finger","Hand","Ear Lobe","Foot"]
  18. def __init__(self):
  19. self._ble = bluetooth.BLE()
  20. self._ble.active(1)
  21. self._ble.config(gap_name = "HeartRate")
  22. self._ble.config(gap_uuid = bluetooth.UUID(0x180d))
  23. self._ble.irq(self._self_irq)
  24. self._callback = None
  25. # 激活
  26. def active(self,active_flag = None):
  27. return self._ble.active(active_flag)
  28. # 修改与查询参数
  29. def config(self,*param_name, **kv):
  30. try:
  31. self._ble._check_active()
  32. except:
  33. raise OSError
  34. # 查询参数
  35. if len(param_name) != 0:
  36. first_param = param_name[0]
  37. if first_param == "gap_name":
  38. return self._ble.config("gap_name")
  39. elif first_param == "sensor_location":
  40. return self.sensor_locations[int(self._ble.gatts_read(self.bsl_handle))]
  41. elif first_param == "hr":
  42. return int(self._ble.gatts_read(self.hrm_handle)[1])
  43. else:
  44. # TODO:未实现
  45. # return self._ble.config(first_param)
  46. pass
  47. # 修改参数
  48. if "gap_name" in kv:
  49. return self._ble.config(gap_name=kv["gap_name"])
  50. if "sensor_location" in kv:
  51. return self._ble.gatts_write(self.bsl_handle,kv["sensor_location"])
  52. if "hr" in kv:
  53. self.update_hr(kv["hr"])
  54. return 0
  55. # 注册服务
  56. def register_services(self,FLAG , services_append = None):
  57. HR_UUID = bluetooth.UUID(self.hr_uuid)
  58. HR_CHAR = (bluetooth.UUID(self.hrm_uuid), bluetooth.FLAG_NOTIFY,)
  59. if FLAG & FLAG_SRV_BSL != 0:
  60. BSL_CHAR = (bluetooth.UUID(self.bsl_uuid), bluetooth.FLAG_READ,)
  61. # BSL_CHAR = (bluetooth.UUID(self.bsl_uuid + 1), bluetooth.FLAG_READ,)
  62. HR_SERVICE = (HR_UUID, (HR_CHAR,BSL_CHAR),)
  63. else :
  64. HR_SERVICE = (HR_UUID, (HR_CHAR,),)
  65. services = [HR_SERVICE,]
  66. if FLAG & FLAG_SRV_APPEND != 0 and services_append != None:
  67. services_append = list(services_append)
  68. services += services_append
  69. return self._ble.gatts_register_services(tuple(services))
  70. # 广播
  71. def advertise(self, interval_us,adv_data=None,resp_data=None, connectable=True, adv_data_append=True):
  72. return self._ble.gap_advertise(interval_us,adv_data,resp_data, connectable,adv_data_append)
  73. # 设置回调函数
  74. def irq(self,func):
  75. self._callback = func
  76. # 默认回调函数
  77. def _self_irq(self,event_id,data):
  78. if event_id == 1: # 连接
  79. if self._callback == None:
  80. print(data)
  81. pass
  82. else :
  83. self._callback(event_id,data)
  84. elif event_id == 2: # 断开连接
  85. if self._callback == None: # 默认继续扫描
  86. print("adv again")
  87. self._ble.gap_advertise(6250)
  88. # self._ble.gap_advertise(6250,adv_data=bytearray("adv"),resp_data=bytes([0x12,0x34,0x56]))
  89. else :
  90. self._callback(event_id,data)
  91. elif event_id == 4: # 读请求
  92. if self._callback == None: # 默认可读
  93. return 0
  94. else :
  95. self._callback(event_id,data)
  96. elif event_id == 18: # 订阅通知
  97. if self._callback == None:
  98. pass
  99. else:
  100. self._callback(event_id,data)
  101. elif event_id == 27: # 连接参数更新
  102. if self._callback == None:
  103. print("_IRQ_CONNECTION_UPDATE")
  104. else:
  105. self._callback(event_id,data)
  106. else :
  107. self._callback(event_id,data)
  108. # 更新心率
  109. def update_hr(self,hr):
  110. # TODO: 首字节默认使用0X06, 暂未弄清楚其他数字含义
  111. return self._ble.gatts_write(self.hrm_handle,[0x06,hr],True)