adafruit / Adafruit_CircuitPython_BluefruitConnect

This module helps you to communicate with the Adafruit Bluefruit Connect app or use its protocols
MIT License
17 stars 16 forks source link

Bluefruit Connect helper library for CircuitPython #1

Closed dhalbert closed 5 years ago

dhalbert commented 5 years ago

Creates and parses BluefruitConnect app packets. Currently has no dependencies on other BLE libraries, but is meant to be used in conjunction with them.

Some notes for reviewers:

Packet is an abstract superclass that includes common or default code for packet construction and parsing. _XYZPacket is an abstract subclass of Packet and includes common code for packet types that provide x, y, and z data fields.

Examples of concrete classes include ButtonPacket, ColorPacket, and GyroPacket. Each packet class is in a separate file, so that only those packet classes that are needed will need to be imported. When a concrete packet class is imported, it automatically registers itself with the Packet superclass, which adds the type code (!B, !C, etc.) to a lookup table held in a class variable in Packet. So only those classes that are imported will be known to the parent class and be parseable. This will save code space.

Parsing is done by the class methods Packet.from_bytes(a_buf) or Packet.from_stream(a_stream). Packet.from_stream() reads as many bytes as necessary from the stream to assemble a full packet. Both methods then parse the packet and instantiate one of the registered concrete subclasses.

This partial example will illustrate:

from adafruit_ble.uart import UARTService

from adafruit_bluefruit_connect.packet import Packet
# Only the packet classes that are imported will be known to Packet.
from adafruit_bluefruit_connect.color_packet import ColorPacket
from adafruit_bluefruit_connect.button_packet import ButtonPacket

# UARTService is from adafruit_ble.uart
uart_service = UARTService()

advertising_now = False
while True:

    if not uart_service.connected:
        if not advertising_now:
            uart_service.start_advertising()
            advertising_now = True
        continue

    # Connected, so no longer advertising
    advertising_now = False

    packet = Packet.from_stream(uart_service)
    if isinstance(packet, ColorPacket):
        # change some NeoPixels
    elif isinstance(packet, ButtonPacket):
        if packet.pressed:
            if packet.button == '5':
               # do something
            elif packet.button == '6':
               # do something else

This is adapted from examples/crickit_controller_test.py (which actually works).