def find_bluetooth_adapter(self, tty_port=None): if tty_port is None: tty_port = self.find_tty() if tty_port is None: raise ValueError('Bluetooth adapter not found!') self.bluetooth = BLE(tty_port)
def __init__(self, opc, name="ybb", rxbuf=1024): Consumer.__init__(self) self._ble = BLE() self._ble.active(True) self._ble.irq(self._irq) self._ble.config(gap_name = name[:16]) ((self._tx_handle, self._rx_handle),) = self._ble.gatts_register_services((_UART_SERVICE,)) # Increase the size of the rx buffer and enable append mode. self._ble.gatts_set_buffer(self._rx_handle, rxbuf, True) self._connections = {} self._rx_buffer = bytearray() self._opc = opc # Optionally add services=[_UART_UUID], but this is likely to make the payload too large. self._payload = advertising_payload(name=name[:16], appearance=_ADV_APPEARANCE_GENERIC_COMPUTER) self._advertise()
raise EventTimeoutError() def wait_for_event(irq, key, timeout_ms): start_time = time.ticks_ms() event_queue = _events[irq][key] while not event_queue: _maybe_raise_timeout(timeout_ms, start_time) machine.idle() return event_queue.popleft() _ble = BLE() gap_advertise = _ble.gap_advertise gatts_register_services = _ble.gatts_register_services gatts_read = _ble.gatts_read gatts_write = _ble.gatts_write gatts_set_buffer = _ble.gatts_set_buffer gap_disconnect = _ble.gap_disconnect def gap_scan(duration_ms, interval_us=None, window_us=None, timeout_ms=None): assert not (interval_us is None and window_us is not None), \ "Argument window_us has to be specified if interval_us is specified" start_time = time.ticks_ms()
class Myo(object): def __init__(self): self.bluetooth = None self.connection = None def connect(self, tty_port=None): self.safely_disconnect() self.find_bluetooth_adapter(tty_port) address = self.find_myo_device() connection_packet = self.bluetooth.connect(address) self.connection = multiord(connection_packet.payload)[-1] self.bluetooth.wait_event(3, 0) print('Connected.') is_fw_valid = self.valid_firmware_version() if is_fw_valid: device_name = self.read_attribute(0x03) print('Device name: %s' % device_name.payload[5:]) self.write_attribute(0x1d, b'\x01\x00') self.write_attribute(0x24, b'\x02\x00') self.initialize() else: raise ValueError('The firmware version must be v1.x or greater.') def find_bluetooth_adapter(self, tty_port=None): if tty_port is None: tty_port = self.find_tty() if tty_port is None: raise ValueError('Bluetooth adapter not found!') self.bluetooth = BLE(tty_port) def find_tty(self): for port in comports(): if re.search(r'PID=2458:0*1', port[2]): return port[0] return None def run(self, timeout=None): if self.connection is not None: self.bluetooth.receive_packet(timeout) else: raise ValueError('Myo device not paired.') def valid_firmware_version(self): firmware = self.read_attribute(0x17) _, _, _, _, major, minor, patch, build = unpack( 'BHBBHHHH', firmware.payload) print('Firmware version: %d.%d.%d.%d' % (major, minor, patch, build)) return major > 0 def add_listener(self, listener): if self.bluetooth is not None: self.bluetooth.add_listener(listener) else: print('Connect function must be called before adding a listener.') def vibrate(self, duration): cmd = b'\x03\x01' if duration == VibrationType.LONG: cmd = cmd + b'\x03' elif duration == VibrationType.MEDIUM: cmd = cmd + b'\x02' elif duration == VibrationType.SHORT: cmd = cmd + b'\x01' else: cmd = cmd + b'\x00' self.write_attribute(0x19, cmd) def initialize(self): self.write_attribute(0x28, b'\x01\x00') self.write_attribute(0x19, b'\x01\x03\x01\x01\x00') self.write_attribute(0x19, b'\x01\x03\x01\x01\x01') def find_myo_device(self): print('Find Myo device...') address = None self.bluetooth.start_scan() while True: packet = self.bluetooth.receive_packet() if packet.payload.endswith( b'\x06\x42\x48\x12\x4A\x7F\x2C\x48\x47\xB9\xDE\x04\xA9\x01\x00\x06\xD5' ): address = list(multiord(packet.payload[2:8])) break self.bluetooth.end_scan() return address def write_attribute(self, attribute, value): if self.connection is not None: self.bluetooth.write_attribute(self.connection, attribute, value) def read_attribute(self, attribute): if self.connection is not None: return self.bluetooth.read_attribute(self.connection, attribute) return None def safely_disconnect(self): if self.bluetooth is not None: self.bluetooth.end_scan() self.bluetooth.disconnect(0) self.bluetooth.disconnect(1) self.bluetooth.disconnect(2) self.disconnect() def disconnect(self): if self.connection is not None: self.bluetooth.disconnect(self.connection)
class BLEUART(Consumer): def __init__(self, opc, name="ybb", rxbuf=1024): Consumer.__init__(self) self._ble = BLE() self._ble.active(True) self._ble.irq(self._irq) self._ble.config(gap_name = name[:16]) ((self._tx_handle, self._rx_handle),) = self._ble.gatts_register_services((_UART_SERVICE,)) # Increase the size of the rx buffer and enable append mode. self._ble.gatts_set_buffer(self._rx_handle, rxbuf, True) self._connections = {} self._rx_buffer = bytearray() self._opc = opc # Optionally add services=[_UART_UUID], but this is likely to make the payload too large. self._payload = advertising_payload(name=name[:16], appearance=_ADV_APPEARANCE_GENERIC_COMPUTER) self._advertise() def _parse(self): try: bs = self.read() log.debug("Read data: %s", bs) d = bs.decode().strip() json = loads(d) if ENCRYPTED_INPUT: # 处理加密 st = Sec() json = st.dec_payload(json) if TOKEN not in json: return None, json return json[TOKEN], json except BaseException as e: log.debug("Invalid request: %s" , e) return None, None def send(self, r): try: if not self.is_authed(): log.debug("No authenticated central") return self.write(dumps(r)) except BaseException as e: log.debug("Send failed: %r" , e) def _handle(self): t, d = self._parse() tm = self._opc.tm_auth(t) if tm is not None: self.send(tm) elif not self._opc.auth(t): self.send(AUTH_ERR) else: self._set_auth() create_task(self._call(d)) def _set_auth(self): for conn_handle in self._connections: self._connections[conn_handle] = -1 def _irq(self, event, data): # Track connections so we can send notifications. if event == _IRQ_CENTRAL_CONNECT: conn_handle, _, _ = data self._connections[conn_handle] = 0 log.debug("New connection") elif event == _IRQ_CENTRAL_DISCONNECT: conn_handle, _, _ = data log.debug("Disconnected") if conn_handle in self._connections: del self._connections[conn_handle] # Start advertising again to allow a new connection. self._advertise() elif event == _IRQ_GATTS_WRITE: conn_handle, value_handle = data if conn_handle in self._connections and value_handle == self._rx_handle: self._rx_buffer += self._ble.gatts_read(self._rx_handle) self._handle() def any(self): return len(self._rx_buffer) def read(self, sz=None): if not sz: sz = len(self._rx_buffer) ret = self._rx_buffer[0:sz] self._rx_buffer = self._rx_buffer[sz:] return ret def write(self, data, authed = False): for conn_handle in self._connections: if not authed or self._connections[conn_handle] < 0: log.debug("Send data: %s", data) self._ble.gatts_notify(conn_handle, self._tx_handle, data) def close(self): for conn_handle in self._connections: self._ble.gap_disconnect(conn_handle) self._connections.clear() def disconnect(self, conn_handle): if conn_handle in self._connections: self._ble.gap_disconnect(conn_handle) def _advertise(self, interval_us=500000): self._ble.gap_advertise(interval_us, adv_data=self._payload) log.info("Advertised", ) def is_authed(self): for conn_handle in self._connections: if self._connections[conn_handle] < 0: return True return False def check_auth(self): for conn_handle in self._connections: if self._connections[conn_handle] >= 0: self._connections[conn_handle] = self._connections[conn_handle] + 1 if self._connections[conn_handle] > AUTH_FAILED_COUNT: log.info("Connect is not authenticated: %d, disconnected.", conn_handle) self.disconnect(conn_handle) async def _call(self, data): try: r = await self._opc.op_request(data, False) self.send(r) except BaseException as e: #NOSONAR msg = "Call failed %r" % e log.debug(msg) self.send(result(500, msg)) async def monitor(self): ''' 清理非法连接 ''' log.debug("BLE connection monitor") while True: try: sleep(1) self.check_auth() except: # NOSONAR # pylint: disable=W0702 pass async def consume(self, data: dict): if ENCRYPTED_OUTPUT: st = Sec() self.send(st.enc_paylaod(data)) else: self.send(data) sleep(0)
_IRQ_GATTC_SERVICE_RESULT = const(1 << 8) _IRQ_GATTC_CHARACTERISTIC_RESULT = const(1 << 9) _IRQ_GATTC_DESCRIPTOR_RESULT = const(1 << 10) _IRQ_GATTC_READ_RESULT = const(1 << 11) _IRQ_GATTC_WRITE_STATUS = const(1 << 12) _IRQ_GATTC_NOTIFY = const(1 << 13) _IRQ_GATTC_INDICATE = const(1 << 14) #Global functions for the timer time_after = time.time() time_before = time.time() timeCheck = False global conn_handle # create BLE variable bt = BLE() # set active to True initializing the bluetooth module bt.active(1) #adc for the battery level check adc = machine.ADC(Pin(32)) val = adc.read() # adding banner message to the device print("****************************************************") print("* SER 402 - Project 5 Trynkit *") print("* Micropython on ESP32 *") print("* Battery Voltage:" + str(val)) print("****************************************************")
def create_battery_service(): service = BatteryService(BLE()) service.register_services() service.start() return service