def init(callback): bt = Bluetooth() bt.set_advertisement(name='LoPy', service_uuid=b'1234567890123456') bt.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=callback) bt.advertise(True)
def run(self): bluetooth = Bluetooth() bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456') bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.conn_cb) bluetooth.advertise(True) #Create a new service on the internal GATT server. Returns a object of type BluetoothServerService. srv1 = bluetooth.service( uuid=self.uuid2bytes('00001819-0000-1000-8000-00805f9b34fb'), isprimary=True) #Creates a new characteristic on the service. Returns an object of the class GATTSCharacteristic self.char1 = srv1.characteristic( uuid=self.uuid2bytes('00002a67-0000-1000-8000-00805f9b34fb'), properties=Bluetooth.PROP_BROADCAST | Bluetooth.PROP_INDICATE, value=1) #Creates a callback that will be executed when any of the triggers occurs char1_cb = self.char1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.char1_cb_handler)
def gatt_connect(): global ble ble = Bluetooth() ble.set_advertisement(name='SiPy') ble.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=con_cb) ble.advertise(True)
class PyBluetooth: def __init__(self, name, serviceUUID): self._bt = Bluetooth() self.setAdvertisement(name=name, serviceUUID=serviceUUID) self._bt.callback(trigger=Bluetooth.CLIENT_CONNECTED, handler=self.onClientConnect, arg=self) self._bt.callback(trigger=Bluetooth.CLIENT_DISCONNECTED, handler=self.onClientConnect, arg=self) self._services = {} def __del__(self): self._bt.disconnect_client() def addService(self, uuid, characteristicNumber=0, isPrimary=False): self._services[uuid] = self._bt.service(self.formatUUID(uuid), nbr_chars=characteristicNumber, isprimary=True) return self._services[uuid] def getService(self, uuid): return self._services[uuid] def setAdvertisement(self, name, manufacturerData=None, serviceData=None, serviceUUID=None): self._name = name if serviceUUID != None: serviceUUID = self.formatUUID(serviceUUID) self._bt.set_advertisement(name=name, manufacturer_data=manufacturerData, service_data=serviceData, service_uuid=serviceUUID) def startAdvertisement(self): self._bt.advertise(True) def stopAdvertisement(self): self._bt.advertise(False) def formatUUID(self, uuid): uuid = uuid.encode().replace(b'-', b'') tmp = binascii.unhexlify(uuid) return bytes(reversed(tmp)) def onClientConnect(self): events = self._bt.events() print("[" + self._name + "]: Client connected") pycom.heartbeat(False) pycom.rgbled(0x110011) def onClientDisconnect(self): print("[" + self._name + "]: Client disconnected") pycom.heartbeat(True)
def BLEServer(): ###### Second, set up BLE server service ###### pycom.heartbeat(False) bluetooth = Bluetooth() #create a bluetooth object bluetooth.set_advertisement(name='LoPyServer' + str(globalvar.device_id), service_uuid=b'3333333333333333') #using callback conn_cb to check client's connection ##Function: conn_cb(callback for bluetooth object events checking) ##Description:check there is any client connected to the service def conn_cb(bt_o): events = bt_o.events( ) #using events to check if there is any client connected to the service if events & Bluetooth.CLIENT_CONNECTED: #2 print("Client connected") pycom.rgbled(0x007f00) # green elif events & Bluetooth.CLIENT_DISCONNECTED: #4 bt_o.disconnect_client() print("Client disconnected") pycom.rgbled(0x7f0000) # red time.sleep(3) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) bluetooth.advertise(True) #set up BLE service srv1 = bluetooth.service(uuid=b'3333333333333333', isprimary=True) #set up service character chr1 = srv1.characteristic(uuid=b'3333333333333333', properties=Bluetooth.PROP_READ | Bluetooth.PROP_WRITE, value=5) #char1_read_counter = 0 def char1_cb_handler(chr): #global char1_read_counter #char1_read_counter += 1 global BLEConnectionCounter events = chr.events() print('events is ' + str(events)) if events & Bluetooth.CHAR_WRITE_EVENT: #16 print("Write request with value = {}".format(chr.value())) elif events & Bluetooth.CHAR_READ_EVENT: #8 #modify here to send its device_id to other clients BLEConnectionCounter += 1 return str(globalvar.device_id) + ' ' + str(BLEConnectionCounter) #using the callback to send the data to other clients chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler)
def BlueToothFun(): global deviceID global connectionCounter #Also act as a server pycom.heartbeat(False) bluetooth = Bluetooth() #create a bluetooth object bluetooth.set_advertisement(name='LoPyServer1', service_uuid=b'1234567890123456') #using callback conn_cb to check client's connection ##Function: conn_cb(callback for bluetooth object events checking) ##Description:check there is any client connected to the service def conn_cb(bt_o): events = bt_o.events( ) #using events to check if there is any client connected to the service if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") pycom.rgbled(0x007f00) # green elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") pycom.rgbled(0x7f0000) # red bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) # bluetooth.advertise(True) srv1 = bluetooth.service(uuid=b'1234567890123456', isprimary=True) chr1 = srv1.characteristic(uuid=b'ab34567890123456', value=5) #char1_read_counter = 0 def char1_cb_handler(chr): #global char1_read_counter #char1_read_counter += 1 global connectionCounter events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("Write request with value = {}".format(chr.value())) else: #modify here to send message to other clients #connectionCounter += 1 return str(deviceID) #using the callback to send the data to other clients char1_cb = chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler) '''srv2 = bluetooth.service(uuid=1234, isprimary=True)
class BLEGATTS: def __init__(self): self.bt_inst = None self.advert_name = None self.connect_callback = None self.is_connected = False self.services = { } def _connection_handler(self, bt): events = bt.events() if events & Bluetooth.CLIENT_CONNECTED: self.is_connected = True if self.connect_callback: self.connect_callback(self.is_connected) elif events & Bluetooth.CLIENT_DISCONNECTED: self.is_connected = False if self.connect_callback: self.connect_callback(self.is_connected) def init(self, advert_name, connect_callback = None): self.bt_inst = Bluetooth(id=0,antenna=Bluetooth.INT_ANT) self.advert_name = advert_name self.connect_callback = connect_callback self.bt_inst.set_advertisement(name=self.advert_name, manufacturer_data=None, service_data=None, service_uuid=None) self.bt_inst.callback(trigger=Bluetooth.CLIENT_CONNECTED|Bluetooth.CLIENT_DISCONNECTED, handler=self._connection_handler) def advertise(self, toggle=True): self.bt_inst.advertise(toggle) def disconnect(self): if self.is_connected: self.bt_inst.disconnect_client() def deinit(self): #TODO: stop services self.disconnect() self.bt_inst.deinit() def addService(self, service_name, uuid): self.services[service_name] = BLEGATTSService(self.bt_inst, uuid) return self.services[service_name] def getService(self, service_name): return service_name in self.services and self.services[service_name] or None def setCharValue(self, svc_name, char_name, value): if self.is_connected and svc_name in self.services and char_name in self.services[svc_name].characteristics: #print ('%s:%s=%s' % (svc_name,char_name,str(value))) self.services[svc_name].characteristics[char_name].setValue(value)
def __init__(self, mesh_mac): self.status = { 'connected' : False } bluetooth = Bluetooth(modem_sleep=False) bluetooth.set_advertisement(name='PyGo (mac:' + str(mesh_mac) + ')', service_uuid=0xec00) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.conn_cb) bluetooth.advertise(True) srv_rx = bluetooth.service(uuid=0xec00, isprimary=True) self.chr_rx = srv_rx.characteristic(uuid=0xec0e, value=0) srv_tx = bluetooth.service(uuid=0xed00, isprimary=True) self.chr_tx = srv_tx.characteristic(uuid=0xed0e, value=0) self.unpacker = None
def connect(self): bluetooth = Bluetooth() bluetooth.set_advertisement(name='Blynk') def conn_cb(bt): events = bt.events() if events & Bluetooth.CLIENT_CONNECTED: self.bout = b'' print("Client connected") elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") BlynkProtocol.disconnect(self) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) nus = bluetooth.service( uuid=unhex('6E400001-B5A3-F393-E0A9-E50E24DCCA9E'), isprimary=True, nbr_chars=2) self.rx = nus.characteristic( uuid=unhex('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), properties=Bluetooth.PROP_WRITE | Bluetooth.PROP_WRITE_NR, value='') self.tx = nus.characteristic( uuid=unhex('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), properties=Bluetooth.PROP_READ | Bluetooth.PROP_NOTIFY, value='') bluetooth.advertise(True) def rx_cb(chr): data = chr.value() print('>', data) self.process(bytes(data)) def tx_subsc(chr): print("Client subscribed", chr) BlynkProtocol.connect(self, login=False) self.tx.callback(trigger=Bluetooth.CHAR_SUBSCRIBE_EVENT, handler=tx_subsc) self.rx.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=rx_cb)
def _init(self): self.status = {'connected': False} bluetooth = Bluetooth(modem_sleep=False) adv_name = self.ble_name bluetooth.set_advertisement(name=adv_name, service_uuid=0xec00) print("BLE name:", adv_name) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.conn_cb) bluetooth.advertise(True) srv_rx = bluetooth.service(uuid=0xec00, isprimary=True) self.chr_rx = srv_rx.characteristic(uuid=0xec0e, value=0) srv_tx = bluetooth.service(uuid=0xed00, isprimary=True) self.chr_tx = srv_tx.characteristic(uuid=0xed0e, value=0) self.unpacker = None
class Blues: # Initialization method. def __init__(self): print('Advertising Bluetooth...') self.mBluetooth = Bluetooth() self.mEvents = self.mBluetooth.events() # self.mBluetooth.init([id=0, mode=Bluetooth.BLE, antenna=Bluetooth.INT_ANT, modem_sleep=False, pin=None, privacy=True, secure_connections=True, mtu=200]) self.mBluetooth.set_advertisement( name='FiPy', service_uuid=2) self.mBluetooth.callback(trigger=self.mBluetooth.CLIENT_CONNECTED | self.mBluetooth.CLIENT_DISCONNECTED, handler=self.Connection) self.mBluetooth.advertise(True) # Create Service & Characteristic self.CreateServChar() self.mCharacteristic.callback( trigger=self.mBluetooth.CHAR_WRITE_EVENT | self.mBluetooth.CHAR_READ_EVENT, handler=self.CharCallback) # Connection method: Used as callback function to detect a BLE connection. def Connection(self, zResponse): self.mEvents = zResponse.events() if self.mEvents & self.mBluetooth.CLIENT_CONNECTED: print("Client connected") elif self.mEvents & self.mBluetooth.CLIENT_DISCONNECTED: print("Client disconnected") def CreateServChar(self): # Create service and characteristic self.mService = self.mBluetooth.service( uuid=3, isprimary=True) self.mCharacteristic = self.mService.characteristic( uuid=31, properties=self.mBluetooth.PROP_WRITE | self.mBluetooth.PROP_READ, value=6) def CharCallback(self, chr, zResponse): self.mEvents, value = zResponse if self.mEvents & self.mBluetooth.CHAR_READ_EVENT: print("Read from Char = {}".format(value)) if self.mEvents & self.mBluetooth.CHAR_WRITE_EVENT: print("Written to Char = {}".format(value))
def startSending(dataList: list, callback, shouldClear): global data global call global bluetooth global clear clear = shouldClear call = callback pycom.rgbled(0x70000ff) data = dataList print("data" + str(data)) bluetooth = Bluetooth() bluetooth.set_advertisement(name='Loy', service_uuid=b'1234567890123456') bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) bluetooth.advertise(True) srv1 = bluetooth.service(uuid=b'serviceA90123456', isprimary=True) srv2 = bluetooth.service(uuid=b'serviceB90123456', isprimary=True) srv3 = bluetooth.service(uuid=b'serviceC90123456', isprimary=True) srv4 = bluetooth.service(uuid=b'serviceD90123456', isprimary=True) chr1 = srv1.characteristic(uuid=b'temp567890123456', value="") chr2 = srv2.characteristic(uuid=b'light67890123456', value="") chr3 = srv3.characteristic(uuid=b'time567890123456', value="") chr4 = srv4.characteristic(uuid=b'id34567890123456', value="") chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler) chr2.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char2_cb_handler) chr3.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char3_cb_handler) chr4.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char4_cb_handler)
class BLEScanner: def __init__(self, buffer_size): """Store buffer in given storage.""" self.beaconlist = [] self.beacontime = [] self.beaconrssi = [] self.beaconevents = [] self.beaconcount = [] self.timelastdata = time.time() self.eventBuffer = RingBuffer(buffer_size) self.bluetooth = Bluetooth() def new_adv_event(self, event): global beaconlist, beaconevents, timelastdata if event.events() == Bluetooth.NEW_ADV_EVENT: anydata = True while anydata: adv = self.bluetooth.get_adv() if adv != None: timelastdata = time.time() devid = binascii.hexlify(adv[0]).decode('utf-8') rssi = str(adv[3] * -1) if devid not in self.beaconlist: print('new device found {} @ {}'.format( devid, timelastdata)) self.beaconlist.append(devid) self.beacontime.append(timelastdata) self.beaconrssi.append(rssi) self.beaconcount.append(0) #if len(beaconevents) > 20: # beaconevents.pop(0) #beaconevents.append([timelastdata, devid, rssi]) self.eventBuffer.add([timelastdata, devid, rssi, 0]) else: #find index in array of this beacon and check the timelastdata #update beaconrssi #decide if stuff shoudl be pushed again i = self.beaconlist.index(devid) if self.timelastdata > (self.beacontime[i] + 300): #update it self.beacontime[i] = timelastdata self.beaconrssi[i] = rssi rx_count = self.beaconcount[i] self.beaconcount[i] = self.beaconcount[i] + 1 #if len(beaconevents) > 20: # beaconevents.pop(0) #beaconevents.append([timelastdata, devid, rssi]) self.eventBuffer.add( [timelastdata, devid, rssi, rx_count]) #print('Updated index {}'.format(i)) else: anydata = False def start_scan(self): print('Starting BLE scan') #bluetooth = self.bluetooth.callback(trigger=Bluetooth.NEW_ADV_EVENT, handler=self.new_adv_event) self.bluetooth.init() self.bluetooth.start_scan(-1)
class Comdev(object): def __init__(self): if bt_enabled: self.ble = Bluetooth() self.chr1 = None self.ble.set_advertisement(name="jitback", service_uuid=POSITION_SERVICE) self.ble.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.__cb_ble_conn) self.promote(BT_PROMOTE) if wifi_enable and wifi_config: # TODO wifi staffs and get configuration to set_advertisement pass if lora_enabled: # TODO wifi staffs and get configuration to set_advertisement pass def __cb_ble_conn(self, bt): """ Callback for connection """ e = bt.events() if e & Bluetooth.CLIENT_CONNECTED: print("connected") self.ble.advertise(False) elif e & Bluetooth.CLIENT_DISCONNECTED: print("disconnected") self.promote(BT_PROMOTE) def characteristic_cb(self, characteristic): events = characteristic.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("Write request with value = {} for {}".format( characteristic.value(), characteristic.uuid())) elif events & Bluetooth.CHAR_READ_EVENT: print("Bluetooth.CHAR_READ_EVENT") def promote(self, device_id=0): if device_id == BT_PROMOTE: self.ble.advertise(True) srv1 = self.ble.service(uuid=POSITION_SERVICE, isprimary=True) self.chr1 = srv1.characteristic(uuid=ACC_BACK_MEASUREMENT, value=1) self.chr2 = srv1.characteristic(uuid=GYR_BACK_MEASUREMENT, value=2) self.chr3 = srv1.characteristic(uuid=MAG_BACK_MEASUREMENT, value=3) self.chr1.callback(Bluetooth.CHAR_READ_EVENT, handler=self.characteristic_cb) self.chr2.callback(Bluetooth.CHAR_READ_EVENT, handler=self.characteristic_cb) self.chr3.callback(Bluetooth.CHAR_READ_EVENT, handler=self.characteristic_cb) else: pass def set_value(self, characteristic, data): if characteristic is None: return elif characteristic == ACC_BACK_MEASUREMENT: self.chr1.value(value=data) elif characteristic == GYR_BACK_MEASUREMENT: self.chr2.value(value=data) elif characteristic == MAG_BACK_MEASUREMENT: self.chr3.value(value=data)
class BluetoothApi: """Many examples integrated from https://microchipdeveloper.com/wireless:ble-gatt-data-organization https://development.pycom.io/firmwareapi/pycom/network/bluetooth/ https://github.com/sandeepmistry/arduino-BLEPeripheral https://github.com/kriswiner/nRF52832DevBoard/blob/master/BMP280_nRF52.ino https://forum.pycom.io/topic/2826/how-to-send-data-to-characteristic-over-ble/17 """ def __init__(self): self.bt = None def start(self): """ """ print('Starting Bluetooth') self.bt = Bluetooth() # Default #self.bt.init(id=0, mode=Bluetooth.BLE, antenna=Bluetooth.INT_ANT, modem_sleep=True) #self.bt.init(id=0, antenna=Bluetooth.INT_ANT, modem_sleep=False) self.bt.init(modem_sleep=False) return print('Entering main loop') while True: print('--- loop ---') adv = self.bt.get_adv() print('adv:', adv) # Give the system some breath. print('machine.idle()') machine.idle() utime.sleep(10.0) continue def scan(self, duration): """ :param duration: """ duration = int(duration) print('Starting Bluetooth scan for {} seconds'.format(duration)) self.bt.start_scan(duration) while self.bt.isscanning(): #print('is-scanning') adv = self.bt.get_adv() if adv: # try to get the complete name name_short = self.bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_SHORT) name_complete = self.bt.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) print('names:', name_short, name_complete) service_data = self.bt.resolve_adv_data( adv.data, Bluetooth.ADV_SERVICE_DATA) print('service_data:', service_data) mfg_data = self.bt.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA) if mfg_data: # try to get the manufacturer data (Apple's iBeacon data is sent here) data = ubinascii.hexlify(mfg_data) print('data:', data) print('Bluetooth scanning stopped') def find_heart_rate(self): """ """ adv = self.bt.get_adv() if adv and self.bt.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate': try: conn = self.bt.connect(adv.mac, timeout=5000) services = conn.services() for service in services: utime.sleep(0.050) if type(service.uuid()) == bytes: print('Reading chars from service = {}'.format( service.uuid())) else: print('Reading chars from service = %x' % service.uuid()) chars = service.characteristics() for char in chars: if (char.properties() & Bluetooth.PROP_READ): print('char {} value = {}'.format( char.uuid(), char.read())) conn.disconnect() except: print("Error while connecting or reading from the BLE device") else: utime.sleep(0.050) utime.sleep(10.0) def advertise(self): """https://development.pycom.io/firmwareapi/pycom/network/bluetooth/""" device_name = get_device_name() print('Advertising device {}'.format(device_name)) # TODO: Get from settings self.bt.set_advertisement(name=device_name, service_uuid=b'1234567890123456') def conn_cb(bt_o): """ :param bt_o: """ print("Callback happened") # Returns flags and clear internal registry events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected:", events) elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") self.bt.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) self.bt.advertise(True) def start_service(self): """https://development.pycom.io/firmwareapi/pycom/network/bluetooth/gattsservice/ https://development.pycom.io/firmwareapi/pycom/network/bluetooth/gattscharacteristic/ https://www.bluetooth.com/specifications/gatt/characteristics/ https://docs.python.org/3/library/struct.html The format field determines how a single value contained in the Characteristic Value is formatted. The information contained on this page is referenced in Bluetooth® Core Specification Volume 3, Part G, Section 3.3.3.5.2. https://www.bluetooth.com/specifications/assigned-numbers/format-types/ """ print('Starting service') # A. Battery Service # UUID: 180F # Abstract: The Battery Service exposes the state of a battery within a device # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.service.battery_service.xml battery = self.bt.service(uuid=0x180F, isprimary=True, nbr_chars=1, start=True) # Battery Level # UUID: 2A19 # Abstract: The current charge level of a battery. # 100% represents fully charged while 0% represents fully discharged # Format: uint8 # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.battery_level.xml battery_level = battery.characteristic(uuid=0x2A19, value=78) # B. Environmental Sensing Service (ESS) # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.service.environmental_sensing.xml # https://www.bluetooth.com/specifications/assigned-numbers/environmental-sensing-service-characteristics/ # https://github.com/sandeepmistry/arduino-BLEPeripheral/issues/215 # https://github.com/sandeepmistry/arduino-nRF5/issues/248 environment = self.bt.service(uuid=0x181A, isprimary=True, nbr_chars=5, start=True) # Temperature # UUID: 2A6E # InformativeText: Unit is in degrees Celsius with a resolution of 0.01 degrees Celsius # Format: sint16 # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature.xml # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature_measurement.xml # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.temperature_type.xml # https://github.com/ARMmbed/ble/blob/master/ble/services/HealthThermometerService.h # https://github.com/ARMmbed/ble/blob/master/ble/services/EnvironmentalService.h # Temperature Celsius # UUID: 2A1F # Format: sint16 # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature_celsius.xml self.temp = 42.42 temperature = environment.characteristic(uuid=0x2A1F) def temp_getter(chr): """ :param chr: """ print('Getting characteristic:', chr) value = sint16(self.temp * 10) print('Value:', value) self.temp += 1 return value print('Adding characteristic callback') temperature_callback = temperature.callback( trigger=Bluetooth.CHAR_READ_EVENT, handler=temp_getter) # Temperature Measurement # UUID: 2A1C # Format: Variable length structure # Value Format: FLOAT (IEEE-11073 32-bit FLOAT) # Abstract: The Temperature Measurement characteristic is a variable length structure # containing a Flags field, a Temperature Measurement Value field and, based upon the # contents of the Flags field, optionally a Time Stamp field and/or a Temperature Type field. # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature_measurement.xml print('Adding Temperature Measurement') temperature_measurement = environment.characteristic( uuid=0x2A1C, value=encode_temperature_2a1c(42.428423)) # Scientific Temperature # UUID: 2A3C # Format: float64 (IEEE-754 64-bit floating point) # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.scientific_temperature_celsius.xml # http://forum.espruino.com/conversations/306536/ # https://stackoverflow.com/questions/36655172/how-to-read-a-ble-characteristic-float-in-swift # For the 'f', 'd' and 'e' conversion codes, the packed representation uses the IEEE 754 # binary32, binary64 or binary16 format (for 'f', 'd' or 'e' respectively), regardless of # the floating-point format used by the platform. # https://docs.python.org/3/library/struct.html #print('Adding Scientific Measurement') #temperature_sci = environment.characteristic(uuid=0x2A3C, value=float64(42.42)) # Humidity # UUID: 2A6F # InformativeText: Unit is in percent with a resolution of 0.01 percent # Format: uint16 # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.humidity.xml humidity1 = environment.characteristic(uuid=0x2A6F, value=uint16(86.86 * 100)) humidity2 = environment.characteristic(uuid=0x2A6F, value=uint16(50.55 * 100)) # Pressure # UUID: 2A6D # InformativeText: Unit is in pascals with a resolution of 0.1 Pa # Format: uint32 # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.pressure.xml # Weight # UUID: 2A98 # InformativeText: Unit is in kilograms with a resolution of 0.005 # Format: uint16 # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.weight.xml # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.weight_measurement.xml # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.weight_scale_feature.xml # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.weight.xml # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.weight_measurement.xml # https://github.com/oesmith/gatt-xml/blob/master/org.bluetooth.characteristic.weight_scale_feature.xml weight = environment.characteristic(uuid=0x2A98, value=uint16(25.44 * 2 * 100)) # GPS # https://forum.pycom.io/topic/5012/can-only-see-value-of-first-gatt-characteristic """ lan = bt.service(0x1819, nbr_chars=3) # 0.001 precision lan.characteristic(uuid=0x2AAE, value=int(gps.lat * 1000)) lan.characteristic(uuid=0x2AAF, value=int(gps.lon * 1000)) lan.characteristic(uuid=0x2AB3, value=int(gps.alt * 1000)) """ # Generic Access # UUID: 1800 # Abstract: The generic_access service contains generic information # about the device. All available Characteristics are readonly. # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.generic_access.xml # Generic Attribute Service # UUID: 1801 # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.generic_attribute.xml # String Characteristic # UUID: 2A3D # A generic UTF8 string which may be used in Services requiring strings. # https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.string.xml srv1 = self.bt.service(uuid=BluetoothUuid.to_bytes_le( '15ECCA29-0B6E-40B3-9181-BE9509B53200'), isprimary=True, nbr_chars=2, start=True) #generic_attribute = self.bt.service(uuid=0x1800, isprimary=True, nbr_chars=2, start=True) #wifi_ssid = generic_attribute.characteristic(uuid=0x2A3D, properties=Bluetooth.PROP_BROADCAST | Bluetooth.PROP_INDICATE | Bluetooth.PROP_NOTIFY | Bluetooth.PROP_READ | Bluetooth.PROP_WRITE, value="default") #wifi_ssid = generic_attribute.characteristic(uuid=0x2A3D, properties=Bluetooth.PROP_NOTIFY | Bluetooth.PROP_READ | Bluetooth.PROP_WRITE, value="default") wifi_ssid = srv1.characteristic(uuid=0x2A3D) #wifi_password = generic_attribute.characteristic(uuid=0x2A3D, properties=Bluetooth.PROP_READ | Bluetooth.PROP_WRITE) #print('wifi_ssid:', wifi_ssid, dir(wifi_ssid)) #cfg = wifi_ssid.config() #print('cfg:', cfg) #wifi_ssid.config(name='hallodri') print('wifi_ssid:', wifi_ssid) print('wifi_ssid:', dir(wifi_ssid)) def wifi_callback(characteristic): """ :param characteristic: """ print('Characteristic callback:', characteristic) #print('attr_obj:', characteristic.attr_obj) events = characteristic.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("Write request with value = {}".format( characteristic.value())) else: pass value = characteristic.value() print('Reading characteristic:', value) print('Adding characteristic callback') wifi_ssid_callback = wifi_ssid.callback( trigger=Bluetooth.CHAR_READ_EVENT | Bluetooth.CHAR_WRITE_EVENT, handler=wifi_callback) #wifi_password_callback = wifi_password.callback(trigger=Bluetooth.CHAR_READ_EVENT | Bluetooth.CHAR_WRITE_EVENT, handler=wifi_callback) #print('instance:', wifi_ssid.instance()) # Characteristic User Description # UUID: 0x2901,0x2902 print(wifi_ssid_callback) print(dir(wifi_ssid_callback)) srv1.characteristic(uuid=0x2901, value="hello world 1")
class ConfigureBluetooth: def __init__(self, data, main): self.data = data self.main = main self.mode = 0 self.pycom = main.pycom self.nodeName = None self.connectionFailed = False self.bluetoothConnected = False self.srv1 = None self.chr1 = None self.srv2 = None self.chr2 = None self.chr3 = None self.bluetooth = None self.char1_cb = None self.char2_cb = None self.service_uuid = 0x2A6D self.service_uuid2 = 0x2A6F self.characteristic_uuid = 0x2A6E self.characteristic_uuid2 = 0x2B6E self.state = 'start' self.unlocked = False # 1: self.pin_reverb, # 2: self.pin_efx1, # 3: self.pin_efx2, # 4: self.pin_minus, # 5: self.pin_plus, # 6: self.pin_variation1, # 7: self.pin_variation2, # 8: self.pin_variation3, # 9: self.pin_transpose, # 10: self.pin_sound_epiano, # 11: self.pin_sound_piano, # 12: self.pin_sound_organ # 13: self.pin_reserve ## start() gets called by main.py in initialisation phase ## returns when main state can be started def start(self): self.setBluetoothAdvertisement(self.mode) return True def setBluetoothAdvertisement(self, mode): if mode == 0: print("Bluetooth Basic activated") self.nodeName = self.data.get('name') print("Advertising on bluetooth with:") print(self.nodeName) self.bluetooth = Bluetooth() self.bluetooth.init() ## service_uuid is dummy, is there an existing profile we should use? self.bluetooth.set_advertisement(name=self.nodeName, service_uuid=self.service_uuid) self.bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.conn_cb) self.bluetooth.advertise(True) ## Below is dummy code, only for testing purposes, services and characteristics should become classes self.srv1 = self.bluetooth.service(uuid=self.service_uuid, isprimary=True) self.chr1 = self.srv1.characteristic(uuid=self.characteristic_uuid, value=b'123') self.char1_cb = self.chr1.callback( trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.unlock_handler) self.srv1.start() self.srv2 = self.bluetooth.service(uuid=self.service_uuid2, isprimary=True) self.chr2 = self.srv2.characteristic( uuid=self.characteristic_uuid2, value=b'chr2') self.chr3 = self.srv2.characteristic( uuid=self.characteristic_uuid2, value=b'chr3') self.char2_cb = self.chr2.callback( trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.interface_handler) self.srv2.start() self.main.start_main_state() def conn_cb(self, bt_o): events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") self.bluetoothConnected = True elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") self.stop_config_state() def unlock_handler(self, chr): events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("Client has written to UNLOCK characteristic") # if written correct passphrase: if (chr.value() == b'0123'): self.start_config_state() self.unlocked = True else: print('wrong password') print("Write request with value = {}".format(chr.value())) if events & Bluetooth.CHAR_READ_EVENT: print("Client has read characteristic") def toggle_method(self, param1, param2): # quickly turn on then off = toggle self.main.toggle_switch(self.main.pin_array[int(param1) - 1]) print('Toggled ' + str(self.main.pin_array[int(param1) - 1])) def loop_through_options(self): # loop through indexes self.main.currentIndex += 1 print(self.main.options) if self.main.currentIndex > len(self.main.options) - 1: self.main.currentIndex = 0 print(self.main.currentIndex) # # toggle (on-off sequence) and switch (on or off) self.main.sequence_method(self.main.options[self.main.currentIndex]) def switch_method(self, param1, param2=0): # switch on or off (controlled by param2) if int(param2) == 1: self.main.switch_on(self.main.pin_array[int(param1) - 1]) print('Switched ON ' + str(self.main.pin_array[int(param1) - 1])) else: self.main.switch_off(self.main.pin_array[int(param1) - 1]) print('Switched OFF ' + str(self.main.pin_array[int(param1) - 1])) def sequence_method(self, param1, param2=0): # toggle a sequence of buttons # e.g. "11-1-2-3-6" self.toggleList = param1.split("-") # API: "2,1-2-3,0" print(self.toggleList) for x in self.toggleList: print(x) self.main.toggle_switch(self.main.pin_array[int(x) - 1]) time.sleep(0.1) def toggle_setting(self, param1, param2): # toggle a sequence of buttons depending on param1 setting int self.toggleList = [1, 2, 3] print(self.toggleList) for x in self.toggleList: print(x) self.main.toggle_switch(self.main.pin_array[int(x) - 1]) time.sleep(0.1) def transpose_up(self): # tranpose up # switch 9 to ON (1) # toggle 5 (plus) self.switch_method(9, 1) time.sleep(0.1) self.main.toggle_switch(self.main.pin_array[5 - 1]) time.sleep(0.1) self.switch_method(9, 0) def transpose_down(self): # tranpose down # switch 9 to ON (1) # toggle 4 (minus) self.switch_method(9, 1) time.sleep(0.1) self.main.toggle_switch(self.main.pin_array[4 - 1]) time.sleep(0.1) self.switch_method(9, 0) def octave_up(self): # octave up, could be triggered with e.g. PuckJS as BLE client self.main.toggle_switch(self.main.pin_array[5 - 1]) def octave_down(self): # octave down self.main.toggle_switch(self.main.pin_array[4 - 1]) def interface_handler(self, chr): events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("Client has written to characteristic") if self.unlocked: print("Write request with value = {}".format(chr.value())) a = str(chr.value()) a = a[2:-1].split(",") print(a) # e.g. STRING="0,00ff00,1" # i.e. LED function (0), color, mode (blink / constant / etc.) options = { 0: self.toggle_method, 1: self.switch_method, 2: self.sequence_method, 3: self.toggle_setting, 4: self.transpose_up, 5: self.transpose_down, 6: self.octave_up, 7: self.octave_down, 8: self.loop_through_options } try: if int(a[0]) == 8 or int(a[0]) == 7 or int( a[0]) == 6 or int(a[0]) == 5 or int(a[0]) == 4: options(int(a[0]))() else: options[int(a[0])](a[1], a[2]) except: print('Error') # self.chr2.value(b'Error') # give response back: # self.chr2.value(bytearray(a)) print('OK') self.chr2.value(b'OK') if events & Bluetooth.CHAR_READ_EVENT: print("Client has read characteristic") def start_config_state(self): self.mode = 1 self.state = 'start_config_state' self.pycom.rgbled(0x0000ff) self.chr1.value(b'Welcome') def stop_config_state(self): self.state = 'stop_config_state' self.unlocked = False self.pycom.rgbled(0xff0000) self.bluetoothConnected = False self.mode = 0
class BLE(): # This class initializes the BLE mode in the fipy and also checks # if the BLE mode param is on or not def __init__(self, name, uuid): self.ble = Bluetooth() self.ble.set_advertisement(name=name, service_uuid=uuid) self.setup() def connect_cb(self, bt_o): # callback for connection print('enter connect_cb\n') events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") self.string = "" def setup(self): # sets up all the services and characteristics print("Enter Setup\n") self.ble.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.connect_cb) self.ble.advertise(True) # main service switches config_service = self.ble.service(uuid=0xfff0, isprimary=True, nbr_chars=1) # main service self.message = config_service.characteristic(uuid=0xfff0, value=0) # nvram declarations self.string = "" pycom.nvs_set('id', 0) pycom.nvs_set('mode', 0) pycom.nvs_set('wifi', 0) pycom.nvs_set('mqtt', 0) pycom.nvs_set('lora', 0) pycom.nvs_set('ssid', 0) pycom.nvs_set('pass', 0) pycom.nvs_set('server', 0) pycom.nvs_set('port', 0) pycom.nvs_set('appSkey', 0) pycom.nvs_set('nwkSkey', 0) pycom.nvs_set('temp_sensor', 0) pycom.nvs_set('temp_f', 0) pycom.nvs_set('accl_sensor', 0) pycom.nvs_set('accl_f', 0) pycom.nvs_set('alt_sensor', 0) pycom.nvs_set('alt_f', 0) pycom.nvs_set('light_sensor', 0) pycom.nvs_set('light_f', 0) # callbacks to deploy_handler which will use the switch_dict to switch between chars msg_cb = self.message.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.msg_handler) # restart details callback) print("waiting for callback") def msg_handler(self,chr): print("Entered msg_handler\n") # handles write and read requests from the client print(chr.value()) events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: msg = chr.value().decode('utf-8') self.string += msg print("string is" + self.string) if msg[len(msg)-2:] == '>e': self.list = [] self.list = self.string[:len(self.string)-2].split(";") msg_list = msg[1:len(msg)-2].split(";") print(self.list) self.execute(self.list) return # device should reset after this elif events & Bluetooth.CHAR_READ_EVENT: NvsStore('deveui', binascii.hexlify(LoRa().mac()).decode('utf-8')) return binascii.hexlify(LoRa().mac()).decode('utf-8') def execute(self, msg_list): for x in range(len(msg_list)): if msg_list[x] == '': msg_list[x] = '0' print(msg_list) print("count" + str(len(msg_list))) if len(msg_list) == 15: NvsStore('id', msg_list[0]) if msg_list[2] == "1": NvsStore('wifi', msg_list[2]) NvsStore('ssid', msg_list[5]) NvsStore('pass', msg_list[6]) else: pycom.nvs_set('wifi', 0) if msg_list[3] == "1": NvsStore('mqtt', msg_list[3]) NvsStore('server', msg_list[7]) NvsStore('port', msg_list[8]) else: pycom.nvs_set('mqtt', 0) if msg_list[4] == "1": NvsStore('lora', msg_list[4]) NvsStore('appskey', msg_list[9]) NvsStore('nwkskey', msg_list[10]) else: pycom.nvs_set('mqtt', 0) if msg_list[11] != 0: NvsStore('temp_sensor', '1') NvsStore('temp_f', msg_list[11]) else: pycom.nvs_set('temp_sensor', 0) if msg_list[12] != 0: NvsStore('alt_sensor', '1') NvsStore('alt_f', msg_list[12]) else: pycom.nvs_set('alt_sensor', 0) if msg_list[13] != 0: NvsStore('accl_sensor', '1') NvsStore('accl_f', msg_list[13]) else: pycom.nvs_set('accl_sensor', 0) if msg_list[14] != 0: NvsStore('light_sensor', '1') NvsStore('light_f', msg_list[14]) else: pycom.nvs_set('light_sensor', 0) if int(msg_list[2]) + int(msg_list[4]) == 0: print("YAS") NvsStore('mode', 0) NvsStore('mode', msg_list[1]) pycom.rgbled(0xffffff) time.sleep(2) pycom.rgbled(0x000000) print("ENTERING DEPLOY MODE IN 5 seconds") time.sleep(5) machine.reset() else: print("INCORRECT DATA STREAM") self.string = ""
class BLE(): # This class initializes the BLE mode in the fipy and also checks # if the BLE mode param is on or not def __init__(self, name, uuid): self.ble = Bluetooth() self.ble.set_advertisement(name=name, service_uuid=uuid) self.setup() def connect_cb(self, bt_o): # callback for connection print('enter connect_cb\n') events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") def setup(self): # sets up all the services and characteristics print("Enter Setup\n") self.ble.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.connect_cb) self.ble.advertise(True) # main service switches boot_service = self.ble.service(uuid=0xfff0, isprimary=True, nbr_chars=5) wifi_service = self.ble.service(uuid=0xfff1, isprimary=True, nbr_chars=2) mqtt_service = self.ble.service(uuid=0xfff2, isprimary=True, nbr_chars=2) lora_service = self.ble.service(uuid=0xfff3, isprimary=True, nbr_chars=3) restart_service = self.ble.service(uuid=0xfff4, isprimary=True, nbr_chars=1) #lte_service = self.ble.service(uuid=0xfff3, isprimary=True, nbr_chars=1) misc_service = self.ble.service(uuid=0xfff5, isprimary=True, nbr_chars=4) # characteristic / service declarations self.id_f = boot_service.characteristic(uuid=0x01, value=0) pycom.nvs_set('id', 0) self.mode_f = boot_service.characteristic(uuid=0x02, value=0) pycom.nvs_set('mode', 0) # generic services to be added to boot service self.wifi_f = boot_service.characteristic(uuid=0x03, value=0) pycom.nvs_set('wifi', 0) self.mqtt_f = boot_service.characteristic(uuid=0x04, value=0) pycom.nvs_set('mqtt', 0) self.lora_f = boot_service.characteristic(uuid=0x05, value=0) pycom.nvs_set('lora', 0) #self.lte_f = boot_service.characteristic(uuid=0x2002, value=0) #pycom.nvs_set('lte', 0) # restart declaration self.restart_f = restart_service.characteristic(uuid=0x01, value=0) # wifi_service chars self.wifi_ssid = wifi_service.characteristic(uuid=0x01, value=0) self.wifi_pass = wifi_service.characteristic(uuid=0x02, value=0) # mqtt_service chars self.mqtt_server = mqtt_service.characteristic(uuid=0x03, value=0) self.mqtt_port = mqtt_service.characteristic(uuid=0x04, value=0) # lora_service chars self.lora_deveui = lora_service.characteristic(uuid=0x01, value=0) self.lora_appSkey = lora_service.characteristic(uuid=0x02, value=0) self.lora_nwkSkey = lora_service.characteristic(uuid=0x03, value=0) # sensor_service chars -> light, pressure, humidity, temperature, altitude self.temp_sensor = misc_service.characteristic(uuid=0x01, value=0) self.alt_sensor = misc_service.characteristic(uuid=0x03, value=0) self.accl_sensor = misc_service.characteristic(uuid=0x05, value=0) self.light_sensor = misc_service.characteristic(uuid=0x07, value=0) # callbacks to deploy_handler which will use the switch_dict to switch between chars id_f_cb = self.id_f.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.deploy_handler) mode_f_cb = self.mode_f.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.deploy_handler) wifi_f_cb = self.wifi_f.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.deploy_handler) mqtt_f_cb = self.mqtt_f.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.deploy_handler) lora_f_cb = self.lora_f.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.deploy_handler) #lte_f_cb = self.lte_f.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.deploy_handler) # restart details callback restart_f_cb = self.restart_f.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.restart_handler) # wifi details callback wifi_cb1 = self.wifi_ssid.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.wifi_handler) wifi_cb2 = self.wifi_pass.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.wifi_handler) print("Enter callback mqtt\n") # mqtt details callback mqtt_cb1 = self.mqtt_server.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.mqtt_handler) mqtt_cb2 = self.mqtt_port.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.mqtt_handler) # lora details callback lora_cb1 = self.lora_deveui.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=self.lora_handler) lora_cb2 = self.lora_appSkey.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.lora_handler) lora_cb3 = self.lora_nwkSkey.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.lora_handler) # sensor details callback temp_sensor_cb = self.temp_sensor.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.sensor_handler) alt_sensor_cb = self.alt_sensor.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.sensor_handler) accl_sensor_cb = self.accl_sensor.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.sensor_handler) light_sensor_cb = self.light_sensor.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.sensor_handler) print("setup done/n") def deploy_handler(self, chr): print("Entered Deploy Handler\n") # handles write and read requests from the client events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: val = chr.value().decode('utf-8') print(val[0]) print(val) if val[0] == '0': self.id_f.value(val[1:]) NvsStore('id', val[1:]) if val[0] == '1': self.mode_f.value(val[1]) NvsStore('mode', val[1]) elif val[0] == '2': self.wifi_f.value(val[1]) NvsStore('wifi', val[1]) elif val[0] == '3': self.mqtt_f.value(val[1]) NvsStore('mqtt', val[1]) elif val[0] == '4': self.lora_f.value(val[1]) NvsStore('lora', val[1]) else: pass elif events & Bluetooth.CHAR_READ_EVENT: return "REJECTED" def wifi_handler(self, chr): print("Wifi Handler\n") # handles writing the wifi ssid and password events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: val = chr.value().decode("utf-8") print(val) if val[0] == '0': self.wifi_ssid.value(val[1:]) x = val[1:] NvsStore('ssid', x) print(NvsExtract('ssid').retval()) elif val[0] == '1': self.wifi_pass.value(val[1:]) NvsStore('pass', val[1:]) print(NvsExtract('pass').retval()) elif events & Bluetooth.CHAR_READ_EVENT: try: print("Connected to ssid: " + x) except NameError: print("not declared yet") print("exit") def lora_handler(self, chr): # handles writing the lora deveui, appSkey and nwkSkey events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: val = chr.value().decode('utf-8') if val[0] == '0': NvsStore('deveui', binascii.hexlify(LoRa().mac()).decode('utf-8')) elif val[0] == '1': self.lora_appSkey.value(val[1:]) NvsStore('appSkey', val[1:]) elif val[0] == '2': self.lora_nwkSkey.value(val[1:]) NvsStore('nwkSkey', val[1:]) elif events & Bluetooth.CHAR_READ_EVENT: return binascii.hexlify(LoRa().mac()).decode('utf-8') def restart_handler(self, chr): events = chr.events() print("restart handler\n") if events & Bluetooth.CHAR_WRITE_EVENT: val = chr.value().decode("utf-8") if val == b'1': machine.reset( ) # hard reset resets hardware and software except firmware loaded else: print("Breach") def mqtt_handler(self, chr): print("MQTT handler") events = chr.events() val = chr.value().decode("utf-8") if events & Bluetooth.CHAR_WRITE_EVENT: if val[0] == '0': self.wifi_ssid.value(val[1:]) NvsStore('server', val[1:]) elif val[0] == '1': self.wifi_pass.value(val[1:]) NvsStore('port', val[1:]) elif events & Bluetooth.CHAR_READ_EVENT: print("Connected to server: " + str(self.mqtt_server.value())) def sensor_handler(self, chr): print("Sensor handler") events = chr.events() val = chr.value().decode("utf-8") if events & Bluetooth.CHAR_WRITE_EVENT: if val[0] == '0': self.temp_sensor.value(val[1]) NvsStore('tempsensor', val[1]) NvsStore('temp_f', val[2:]) elif val[0] == '1': self.alt_sensor.value(val[1]) NvsStore('altsensor', val[1]) NvsStore('alt_f', val[2:]) elif val[0] == '2': self.accl_sensor.value(val[1]) NvsStore('acclsensor', val[1]) NvsStore('accl_f', val[2:]) elif val[0] == '3': self.light_sensor.value(val[1]) NvsStore('lightsensor', val[1]) NvsStore('light_f', val[2:]) else: pass # for now
class BluetoothServer: # pylint: disable=C1001,R0903,R0902 """ BluetoothServer Advertises bluetooth services, handles connection and clients """ def __init__( self, # pylint: disable=W0102,R0913,R0914 device_id='', bluetooth_ids={}, client_ids=set(), on_client_paired=None, on_client_unpaired=None, get_next_data_item=None, get_next_event_item=None, clear_event=None): # Read bluetooth IDs: self.__device_id = device_id self.__bt_id = bluetooth_ids.get('bt_id') self.__bt_setup_svc_id = bluetooth_ids.get('bt_setup_svc_id') self.__bt_pair_svc_id = bluetooth_ids.get('bt_pair_svc_id') self.__bt_unpair_svc_id = bluetooth_ids.get('bt_unpair_svc_id') self.__bt_data_svc_id = bluetooth_ids.get('bt_data_svc_id') self.__bt_event_svc_id = bluetooth_ids.get('bt_event_svc_id') self.__bt_event_notif_svc_id = bluetooth_ids.get( 'bt_event_notif_svc_id') self.__bt_event_clear_svc_id = bluetooth_ids.get( 'bt_event_clear_svc_id') self.__bt_setup_char_id = bluetooth_ids.get('bt_setup_char_id') self.__bt_pair_char_id = bluetooth_ids.get('bt_pair_char_id') self.__bt_unpair_char_id = bluetooth_ids.get('bt_unpair_char_id') self.__bt_data_char_id = bluetooth_ids.get('bt_data_char_id') self.__bt_event_char_id = bluetooth_ids.get('bt_event_char_id') self.__bt_event_notif_char_id = bluetooth_ids.get( 'bt_event_notif_char_id') self.__bt_event_clear_char_id = bluetooth_ids.get( 'bt_event_clear_char_id') self.__on_client_paired = on_client_paired self.__on_client_unpaired = on_client_unpaired self.__get_next_data_item = get_next_data_item self.__get_next_event_item = get_next_event_item self.__clear_event = clear_event # Save currently paired clients self.client_ids = client_ids # Setup bluetooth & configure advertisement. self.bluetooth = Bluetooth() self.bluetooth.set_advertisement( name=BT_ADV_PREFIX + self.__device_id, service_uuid=uuid2bytes(self.__bt_id), manufacturer_data=BT_MANUFACTURER_NAME, service_data=BT_DEVICE_VERSION) # Create services: setup_service = self.bluetooth.service(uuid=uuid2bytes( self.__bt_setup_svc_id), isprimary=True) pair_service = self.bluetooth.service(uuid=uuid2bytes( self.__bt_pair_svc_id), isprimary=True) unpair_service = self.bluetooth.service(uuid=uuid2bytes( self.__bt_unpair_svc_id), isprimary=True) data_service = self.bluetooth.service(uuid=uuid2bytes( self.__bt_data_svc_id), isprimary=True) event_service = self.bluetooth.service(uuid=uuid2bytes( self.__bt_event_svc_id), isprimary=True, nbr_chars=2) event_notif_service = self.bluetooth.service(uuid=uuid2bytes( self.__bt_event_notif_svc_id), isprimary=True) # event_clear_service = self.bluetooth.service( # uuid=uuid2bytes(self.__bt_event_clear_svc_id), # isprimary=True) # Create characteristics for services: self.__setup_char = setup_service.characteristic( uuid=uuid2bytes(self.__bt_setup_char_id), properties=Bluetooth.PROP_WRITE, value=None) self.__pair_char = pair_service.characteristic( uuid=uuid2bytes(self.__bt_pair_char_id), properties=Bluetooth.PROP_WRITE, value=None) self.__unpair_char = unpair_service.characteristic( uuid=uuid2bytes(self.__bt_unpair_char_id), properties=Bluetooth.PROP_WRITE, value=None) self.__data_char = data_service.characteristic( uuid=uuid2bytes(self.__bt_data_char_id), properties=Bluetooth.PROP_READ, value=None) self.__event_char = event_service.characteristic( uuid=uuid2bytes(self.__bt_event_char_id), properties=Bluetooth.PROP_READ, # pylint: disable=C0301 value=None) self.__event_notif_char = event_notif_service.characteristic( uuid=uuid2bytes(self.__bt_event_notif_char_id), properties=Bluetooth.PROP_NOTIFY | Bluetooth.PROP_INDICATE, value=None) self.__event_clear_char = event_service.characteristic( uuid=uuid2bytes(self.__bt_event_clear_char_id), properties=Bluetooth.PROP_WRITE, value=None) # Add callbacks: self.bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.__on_connection_status_changed) self.__setup_char.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.__on_setup_write, arg=None) self.__pair_char.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.__on_pair_write, arg=None) self.__unpair_char.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.__on_unpair_write, arg=None) self.__data_char.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=self.__on_data_read, arg=None) self.__event_char.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=self.__on_event_read, arg=None) self.__event_clear_char.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.__on_event_clear, arg=None) # Start advertising: self.bluetooth.advertise(True) def update_client_ids(self, client_ids): """ set_client_ids Update the client_ids """ self.client_ids = client_ids def __on_connection_status_changed(self, bt_o): events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: self.__on_client_connected(bt_o) elif events & Bluetooth.CLIENT_DISCONNECTED: self.__on_client_disconnected(bt_o) def __on_client_connected(self, bt_o): # pylint: disable=R0201 adv = bt_o.get_adv() print('Client connected: ', adv) def __on_client_disconnected(self, bt_o): # pylint: disable=R0201 adv = bt_o.get_adv() print('Client disconnected: ', adv) def __on_setup_write(self, ch): # pylint: disable=R0201,C0103 """ __on_setup_write Setup device """ data = ch.value().decode() print("setup_write: ", data) if TIME_SETUP_PREFIX in data: time_vals = data.replace(TIME_SETUP_PREFIX, "", 1) time_vals = [int(x) for x in time_vals.split(",")] set_current_time((time_vals[0], time_vals[1], time_vals[2], time_vals[3], time_vals[4], time_vals[5])) print("Current timestamp: ", current_timestamp()) def __on_pair_write(self, ch): # pylint: disable=C0103 """ __on_pair_write Triggered from the pair-write characteristic. Expected data is the unique "client id" from the app. """ client_id = ch.value().decode() self.__on_client_paired(client_id) print("pair_write: ", client_id) def __on_unpair_write(self, ch): # pylint: disable=C0103 client_id = ch.value().decode() self.__on_client_unpaired(client_id) print("unpair_write: ", client_id) def __on_data_read(self, ch): # pylint: disable=C0103 """ __on_data_read Triggered from the data characteristic. """ data = self.__get_next_data_item() ch.value(data) print("data_read: ", data) def __on_event_read(self, ch): # pylint: disable=C0103 """ __on_event_read Triggered from the event characteristic. """ data = self.__get_next_event_item() ch.value(data) print("event_read: ", data) def __on_event_clear(self, ch): # pylint: disable=C0103 """ __on_event_clear Triggered from event_clear characteristic """ data = ch.value().decode() if EVENT_CLEAR_PREFIX in data: e_id = data.replace(EVENT_CLEAR_PREFIX, "", 1) self.__clear_event(e_id) def send_event_notification(self, event): """ send_event_notification """ print("Notifying client of event: ", event.event_id) self.__event_notif_char.value("new_event=" + event.event_id)
chr1.value( currentAngle) # update the value that is displayed over Bluetooth print("Set new angle: ", currentAngle) # Function to caculate the pwm value for the angle given. def setServoPwn(angle): servo.duty_cycle( ((angle / 180) * 0.05) + 0.05) # calculate the right value for PWM based on the angle given bluetooth = Bluetooth() # Get a bluetooth instance bluetooth.set_advertisement(name='FyPi') # Set the name bluetooth.callback( trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) # set up the callbacks for connect and disconnect events bluetooth.advertise(True) # advertise the device print("Started BLE") srv1 = bluetooth.service( uuid=0x1815, isprimary=True ) # set up the service to display the current angle of the servo chr1 = srv1.characteristic( uuid=0x2763, value=currentAngle) # set up the characteristic to get the server angle char1_cb = chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=char1_cb_handler ) # set up the callback when writen to characteristic
def BLEServer(): bluetooth = Bluetooth() #create a bluetooth object bluetooth.set_advertisement(name=settings['deviceid'], service_uuid=settings['filipsblue_service']) #using callback conn_cb to check client's connection ##Function: conn_cb(callback for bluetooth object events checking) ##Description:check there is any client connected to the service def conn_cb(bt_o): events = bt_o.events( ) #using events to check if there is any client connected to the service global isConnected if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") isConnected = True pycom.rgbled(0x007f00) # green elif events & Bluetooth.CLIENT_DISCONNECTED: bt_o.disconnect_client( ) # in this way other client will have the chance to connect? print("Client disconnected") isConnected = False pycom.rgbled(0x7f0000) # red time.sleep(3) bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) bluetooth.advertise(True) print("Started BLE advertising") ########################### # BLE Ambient Sensor Service ########################### ambient_sensor_service = bluetooth.service( uuid=settings['ambient_sensor_service'], isprimary=True, nbr_chars=2 ) # nbr_chars indicates the number of characteristics of this service #set up service characteristic ambient_sensor_chr = ambient_sensor_service.characteristic( uuid=settings['ambient_sensor_chr'], properties=Bluetooth.PROP_NOTIFY, value='NA') ambient_sensor_sample_interval_chr = ambient_sensor_service.characteristic( uuid=settings['ambient_sensor_sample_interval_chr'], properties=Bluetooth.PROP_WRITE, value='NA') def ambient_sensor_sample_interval_cb_handler(chr): events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("ambient_sensor_sample_interval_cb_handler : Raw value: {}". format(chr.value())) try: sample_interval = float(chr.value()) ambient_sensor.set_sample_interval(sample_interval) print("Updated ambient sampling rate: {}".format( sample_interval)) except: print( "ambient_sensor_sample_interval_cb_handler : Invalid value. Expected type float." ) pass ambient_sensor_sample_interval_chr.callback( trigger=Bluetooth.CHAR_WRITE_EVENT, handler=ambient_sensor_sample_interval_cb_handler) ambient_sensor_service.start() def ble_ambient_sensor_callback(lux_sample): print("Should we notify? : " + str(isConnected)) # Can take an integer, a string or a bytes object. Can only be called if there clients are connected? # Should trigger notification if a client has registered for notifications if isConnected: try: ambient_sensor_chr.value( str(lux_sample)) # Send the notification over BLE print("Emitted lux value: " + str(lux_sample)) except: # Some error happened during notification. # Most likely no client is connected to receive notifications. # Disconnect bluetooth communication. bluetooth.disconnect_client() ambient_sensor = AmbientSensor( callback_on_emit=ble_ambient_sensor_callback) _thread.start_new_thread(ambient_sensor.start_sampling, ()) # Start sampling the ambient sensor ########################### # BLE Light Source Service ########################### light_source_service = bluetooth.service( uuid=settings['light_source_service'], isprimary=True) #set up service characteristic light_source_chr = light_source_service.characteristic( uuid=settings['light_source_chr'], properties=Bluetooth.PROP_WRITE, value='\xff\xff\xff') def light_source_chr_cb_handler(chr): events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: colorsArray = chr.value() try: print("light_source_chr_cb_handler : Raw value: {}".format( chr.value())) red = colorsArray[0] green = colorsArray[1] blue = colorsArray[2] print("Set LED with value = {} {} {}".format(red, green, blue)) set_LED_rgb(red, green, blue) except: print( "light_source_chr_cb_handler : Invalid value. Expected byte array of length 3." ) pass light_source_chr.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=light_source_chr_cb_handler) light_source_service.start()
def bt_cb(bt): print("bt disconnected") while True: print("loop") adv = bt.get_adv() if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'test': try: bt.stop_scan() conn = bt.connect(adv.mac) print("connected to My iPhone") bt.callback(Bluetooth.CLIENT_DISCONNECTED, bt_cb) services = conn.services() for service in services: print('service UUID = {}'.format(service.uuid() if isinstance( service.uuid(), bytes) else hex(service.uuid()))) if service.uuid() == 0x1111: chars = service.characteristics() for char in chars: time.sleep(0.050) char.callback(trigger=Bluetooth.CHAR_NOTIFY_EVENT, handler=char_cb) print('char {} value = {}'.format( hex(char.uuid()), char.read())) break except: print("erreur")
class BLEUart: def __init__(self): self.status = {'connected': False} self.rx_data = [] def begin(self, name): self._ble = Bluetooth() # Some apps require the service uuid to be part of the advertising packet for the device to show up # as Uart capable, like the Bluefruit Connect app self._ble.set_advertisement( name=name, service_uuid=unhex('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')) #self._ble.set_advertisement(name=name) self._ble.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=self.conn_callback) self._ble.advertise(True) nus = self._ble.service( uuid=unhex('6E400001-B5A3-F393-E0A9-E50E24DCCA9E'), isprimary=True, nbr_chars=2) self.rx = nus.characteristic( uuid=unhex('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), #properties=Bluetooth.PROP_WRITE | Bluetooth.PROP_WRITE_NR, properties=Bluetooth.PROP_WRITE_NR, value='') self.tx = nus.characteristic( uuid=unhex('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), #properties=Bluetooth.PROP_READ | Bluetooth.PROP_NOTIFY, properties=Bluetooth.PROP_NOTIFY, value='') self.tx.callback(trigger=Bluetooth.CHAR_SUBSCRIBE_EVENT, handler=self.tx_subsc_callback) self.rx.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=self.rx_callback) def end(self): self.status['connected'] = False self.rx_data = [] self._ble.disconnect_client() self._ble.deinit() def conn_callback(self, bt): events = bt.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") self.status['connected'] = True elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") self.status['connected'] = False self.rx_data = [] def rx_callback(self, chr, msg): data = chr.value() #print('BLE data received') strdata = str(data, 'utf-8') #print('> ', strdata) self.rx_data.append(strdata) def tx_subsc_callback(self, chr, msg): print("Client subscribed", chr.value()) def write(self, msg): if self.status['connected'] == True: while len(msg): data = msg[:20] msg = msg[20:] print('BLE data send:') print('<', data) self.tx.value(data) self.tx.value('\r\n') def available_data(self): return (True if (len(self.rx_data) > 0) else False) def get_data(self): if self.available_data(): data = self.rx_data[0] del self.rx_data[0] return data else: return 0
bluetooth = Bluetooth() wlan = network.WLAN(mode=network.WLAN.STA) lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868) s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setblocking(False) def conn_cb (bt_o): events = bt_o.events() if events & Bluetooth.CLIENT_CONNECTED: print("Client connected") elif events & Bluetooth.CLIENT_DISCONNECTED: print("Client disconnected") bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) #BLE bluetooth.deinit() wlan.deinit() lora.power_mode(LoRa.SLEEP) bluetooth = Bluetooth() pycom.heartbeat(False) pycom.rgbled(0x000077) print('sending BT') bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890abcdef') bluetooth.advertise(True)
Periods[mac] += [[t, t, adv.rssi]] else: # seeing mac for the first time Adv[mac] = adv Periods[mac] = [[t, t, adv.rssi]] if debug: print_adv(adv) else: print('X', end='') print("init") bt = Bluetooth() # antenna=Bluetooth.EXT_ANT) bt.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED | Bluetooth.CHAR_READ_EVENT | Bluetooth.CHAR_WRITE_EVENT | Bluetooth.NEW_ADV_EVENT | Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED | Bluetooth.CHAR_NOTIFY_EVENT, handler=bt_event_cb) time.sleep(1) scan_timeout_s = 2 # how long do we scan. if you want to trace then it should be long! track_timeout_s = 10 # after how long do we total_adv_ct = 0 last_adv_time = None try: print("start_scan") bt.start_scan(scan_timeout_s) except Exception as e: print("cannot start_scan", e) print("stop_scan") bt.stop_scan()