def setup_ble(): bt = Bluetooth() if C.BLE_ENABLED: bt.set_advertisement(name="LoPy") bt.advertise(True) else: bt.deinit()
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)
class bluetooth: def __init__(self): self.bluetooth = Bluetooth() self.bluetooth.set_advertisement(name=ble_device_name, manufacturer_data=manufacturer_data, service_data=None, service_uuid=private_UUID) self.bluetooth.advertise(True) #service_acc self.service_acc = self.bluetooth.service(uuid=service_acc_UUID, isprimary=True, nbr_chars=3, start=True) self.character_acc_x = self.service_acc.characteristic( uuid=character_acc_x_UUID, properties=None, value=33) self.character_acc_y = self.service_acc.characteristic( uuid=character_acc_y_UUID, properties=None, value=34) self.character_acc_z = self.service_acc.characteristic( uuid=character_acc_z_UUID, properties=None, value=35) def updateValue(self, accelerate=None, gps=None): if (accelerate != None): float_bytes = struct.pack('f', accelerate[0]) #print(float_bytes) print(accelerate[0], accelerate[1], accelerate[2]) total_bytes = b'' total_bytes = struct.pack('<f', accelerate[0]) + struct.pack( '<f', accelerate[1]) + struct.pack( '<f', accelerate[2]) + struct.pack( '<f', gps[0]) + struct.pack('<f', gps[1]) self.character_acc_x.value(total_bytes) self.character_acc_y.value(total_bytes) self.character_acc_z.value(total_bytes)
class ble: def __init__(self): self.bluetooth = Bluetooth() self.bluetooth.set_advertisement(name=ble_device_name, manufacturer_data=manufacturer_data, service_data=None, service_uuid=private_UUID) self.bluetooth.advertise(True) #service self.service_acc = self.bluetooth.service(uuid=service_acc_UUID, isprimary=True, nbr_chars=3, start=True) self.character_acc_x = self.service_acc.characteristic( uuid=character_acc_x_UUID, properties=None, value=33) self.character_acc_y = self.service_acc.characteristic( uuid=character_acc_y_UUID, properties=None, value=34) self.character_acc_z = self.service_acc.characteristic( uuid=character_acc_z_UUID, properties=None, value=35) def updateValue(self, accelerate=None): if (accelerate != None): self.character_acc_x.value(accelerate[0]) self.character_acc_y.value(accelerate[1]) self.character_acc_z.value(accelerate[2])
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 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)
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)
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)
def bt_check(self): av = AV() av.blue() bluetooth = Bluetooth() bluetooth.set_advertisement(name=BLE_DEVICE_NAME, manufacturer_data=BLE_DEVICE_NAME, service_uuid=0001) bluetooth.advertise(True) srv1 = bluetooth.service(uuid=0001, isprimary=True) chr1 = srv1.characteristic(uuid=0002, value=5) if self.config["state"] == 0: lock_state = 0 else: lock_state = 1 def char1_cb_handler(chr): if chr.value() == bytes(BLE_SECRET_KEY, "utf-8"): if self.config["state"] == 0: self.lock() av.locked() return 'good' else: self.unlock() av.unlocked() return 'good' srv2 = bluetooth.service(uuid=0003, isprimary=True) chr2 = srv2.characteristic(uuid=0004, value=lock_state) char1_cb = chr2.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=char1_cb_handler) time.sleep(20) av.off() bluetooth.advertise(False)
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) time.sleep(8) #micro bluetooth.deinit() wlan.deinit() lora.power_mode(LoRa.SLEEP) pycom.rgbled(0x000000) h = 0 for i in range (300000): h = h+1; #WIFI
from LIS2HH12 import LIS2HH12 from SI7006A20 import SI7006A20 from LTR329ALS01 import LTR329ALS01 from MPL3115A2 import MPL3115A2,ALTITUDE,PRESSURE from secrets import WIFISSID, WIFIPASS wdt = machine.WDT(timeout=300000) py = Pysense() mp = MPL3115A2(py,mode=ALTITUDE) # Returns height in meters. Mode may also be set to PRESSURE, returning a value in Pascals si = SI7006A20(py) lt = LTR329ALS01(py) li = LIS2HH12(py) bt = Bluetooth() bt.set_advertisement(name="pycom") bt.advertise(True) while True: wdt.feed() bt.start_scan(10) while bt.isscanning(): time.sleep_ms(100) advs = bt.get_advertisements() devices = set() devicetypes = dict() for adv in advs: if adv.mac in devices: continue devices.add(adv.mac) print("MAC: "+str(ubinascii.hexlify(adv.mac))) print("RSSI: "+str(adv.rssi))
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)
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 pwm = PWM(0, frequency=50) # make a pwm provider servo = pwm.channel(0, pin='P23',
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") 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 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 = ""
global Irrigation_Delay_Sec_Off Irrigation_Delay_Sec_Off = int(chr2.value()) # watering time in seconds global Irrigation_Delay_Count Irrigation_Delay_Count = 0 global Solenoid_Status Solenoid_Status = True f = open(FileName, 'w') # overwrite data f.write(str(Irrigation_Delay_Sec_On) + "_" + str(Irrigation_Delay_Sec_Off)) f.close() # Setup BLE advertisement BLE_Obj = Bluetooth() BLE_Obj.set_advertisement(name='Greenhouse', service_uuid=b'1234567890123456') BLE_Obj.advertise(True) #define BLE GATT servcies and charateristics srv1 = BLE_Obj.service( uuid=0x100, isprimary=True ) # define two services because Pycom does not support multiple characteristics srv2 = BLE_Obj.service( uuid=0x200, isprimary=True) # frontend code and documentation is incomplete chr1 = srv1.characteristic(uuid=0x101, value=Irrigation_Delay_Sec_On) chr2 = srv2.characteristic(uuid=0x201, value=Irrigation_Delay_Sec_Off) # Define callbacks for BLE events chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=Delay_On_BLE_Callback) chr2.callback(trigger=Bluetooth.CHAR_WRITE_EVENT,
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 SwarmBluetooth(Body.SwarmBody, Network.SwarmNetwork): def __init__(self): #Body.SwarmBody.__init__(self) #Network.SwarmNetwork.__init__(self) self.bluetooth = Bluetooth() self.Collision_Timer = 0 self.Tile_Transmit_Timer = 2 self.bl_threshold = -35 self.RepulsionTime = 2000 pass #Transmits Information about a Tile that a robot is traversing #We don't actually need to send temperature information in this message as other bots need not know def Start_Transmit_Tile_Update(self, RX, RY, Luminosity, Time_Steps): #This statment may be not good, current unsure #self.bluetooth.stopscan(); print("Tile Transmit Update" + str(RX) + "/" + str(RY)) #Sets the advertisment that we want, the method work up to 99, uses 01, 10 if RX < 10: RXM = "0" + str(RX) else: RXM = str(RX) if RY < 10: RYM = "0" + str(RY) else: RYM = str(RY) ss = RXM + RYM + str(Luminosity) #print(ss); self.bluetooth.set_advertisement(name="a_mp", manufacturer_data="l", service_data=ss) self.bluetooth.advertise(True) #Sets teh timer for how long we should transmit self.Tile_Transmit_Timer = 200 return -1 def test_transmit(self): self.bluetooth.set_advertisement(name="a", manufacturer_data="l", service_data="99999") self.bluetooth.advertise(True) #Broadcasts the selection of a tile as a robots destination def Broadcast_Tile_Selection(self, Target_Destination, State): RX = Target_Destination[0] RY = Target_Destination[1] print("Broadcasting Tile Selection" + str(RX) + "/" + str(RY)) #Sets the advertisment that we want, the method work up to 99, uses 01, 10 if RX < 10: RXM = "0" + str(RX) else: RXM = str(RX) if RY < 10: RYM = "0" + str(RY) else: RYM = str(RY) mes = RXM + RYM + str(State) self.bluetooth.set_advertisement(name="a_tg", manufacturer_data="l", service_data=mes) self.bluetooth.advertise(True) self.Tile_Transmit_Timer = 50 return -1 #Handles Transmission and Listening Decisions For a given cycle #Needs to be run each cycle def Handle_Bluetooth_Behaviour(self, Swarmbehv_obj, print_boolean): if self.Collision_Timer > 0: self.Collision_Timer -= 1 #Transmit if transmission timer is active #print(str(self.Tile_Transmit_Timer)); if self.Tile_Transmit_Timer > 1: self.Tile_Transmit_Timer -= 1 #self.bluetooth.stopscan(); #print("Decrementing") #If stopping transmission elif self.Tile_Transmit_Timer == 1: self.bluetooth.advertise(False) self.Tile_Transmit_Timer -= 1 #Start Scanning if self.bluetooth.isscanning() == False: self.bluetooth.start_scan(-1) #print("Starting A Scan") #If not transmitting else: #If we are scanning for bluetooth transmissions if self.bluetooth.isscanning(): #print("Scanning"); #Continue to do it adv = self.bluetooth.get_adv() if adv: # try to get the complete name if print_boolean == True: pass #print(self.bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) name = self.bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) mfg_data = self.bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA) adv_mes = self.bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_SERVICE_DATA) if print_boolean == True: pass #print(adv_mes); if adv_mes: if print_boolean == True: print("MES!") if mfg_data: if print_boolean == True: pass #print(ubinascii.hexlify(mfg_data)) if adv_mes and name: bl_strength = adv[3] #If the strength is past the bl_threshold if bl_strength > self.bl_threshold: #We start our collision reverse movement if self.Collision_Timer == 0: self.Collision_Timer = self.RepulsionTime #Ths code wll be req n future #Unless we are alreay in one, then we cancel it and restart normal movement #else: #self.Collision_Timer = 0; if print_boolean == True: pass #print(ubinascii.hexlify(adv_mes)) #print(adv_mes) #If meesage is an intent update if name == "a_tg": #if print_boolean == True: #print("target recieved!" + str(bl_strength)) #do it hexd = ubinascii.hexlify(adv_mes) mx = (int(adv_mes[0]) - 48) * 10 + ( int(adv_mes[1]) - 48) my = (int(adv_mes[2]) - 48) * 10 + ( int(adv_mes[3]) - 48) state = int(adv_mes[4]) - 48 if print_boolean == True: print(mx) print(my) print(state) #If all of them are integers if isinstance(mx, int) and isinstance( my, int) and isinstance(state, int): Swarmbehv_obj.Map_Assignement[mx][my] = state if print_boolean == True: #Swarmbehv_obj.Display_Map(Swarmbehv_obj.Map_Light); pass elif name == "a_mp": if print_boolean == True: print("mapping recieved !") #If message is a tile update #Get coords of square cx = (int(adv_mes[0]) - 48) * 10 + ( int(adv_mes[1]) - 48) cy = (int(adv_mes[2]) - 48) * 10 + ( int(adv_mes[3]) - 48) #create temp string lumin_s = 0 for i in range(4, len(adv_mes)): lumin_s += (10**(len(adv_mes) - i - 1)) * (int(adv_mes[i]) - 48) #make temp float lumin_s = float(lumin_s) if print_boolean == True: print(cx) print(cy) print(lumin_s) #If cx and cy are integers if isinstance(cx, int) and isinstance( cy, int) and cx > 0 and cy > 0: Swarmbehv_obj.Map_Light[cx][cy] = lumin_s Swarmbehv_obj.Map_Bounty[cx][cy] = 0 #Swarmbehv_obj.Area_Matrix[cx][cy] = 1; #print(Swarmbehv_obj.Area_Matrix); if print_boolean == True: Swarmbehv_obj.Display_Map( Swarmbehv_obj.Map_Light) #Charge Request Message elif name == "a_cr": if print_boolean == True: print("Charge Request Recieved !") hexd = ubinascii.hexlify(adv_mes) mx = (int(adv_mes[0]) - 48) * 10 + ( int(adv_mes[1]) - 48) my = (int(adv_mes[2]) - 48) * 10 + ( int(adv_mes[3]) - 48) #t_ID = 0; #for i in range(4,len(adv_mes)): #t_ID += (10**(len(adv_mes)-i-1))*(int(adv_mes[i])-48); Swarmbehv_obj.Charge_Flag = True #Swarmbehv_obj.classharge_ID = t_ID; Swarmbehv_obj.Charge_X = mx Swarmbehv_obj.Charge_Y = my #If it is not then goto square and transmit intent #Charge accepted message elif name == "a_ch": print("Charge Ticket Accepeted Elsewhere !") Swarmbehv_obj.Charge_Flag = False #Used to run handle bluetooth behaviour on a thread def Handle_Bluetooth_Behaviour_Continuous(self, Swarmbehv_obj, print_boolean): while True: self.Handle_Bluetooth_Behaviour(Swarmbehv_obj, print_boolean) #Sends a global call for itself to be charged def Call_For_Charge(self, Swarmbehv_obj, Current_X, Current_Y): RX = 0 RY = 0 RY = Current_Y #Check the Tile 2 to the left if Current_X - 2 > 0: RX = Current_X - 2 elif Current_X + 2 < math.floor( Swarmbehv_obj.Arena_X_Mm / Swarmbehv_obj.Arena_Grid_Size_X): RX = Current_X - 2 else: pass RX = Current_X #Somthing in Y required here ? #Check the Tile 2 to the right #Use whichever is not out of the Area_Matrix #RX = Target_Destination[0]; #RY = Target_Destination[1]; print("Broadcasting Call For Charge" + str(RX) + "/" + str(RY)) #Sets the advertisment that we want, the method work up to 99, uses 01, 10 if RX < 10: RXM = "0" + str(RX) else: RXM = str(RX) if RY < 10: RYM = "0" + str(RY) else: RYM = str(RY) mes = RXM + RYM #str(ubinascii.hexlify(machine.unique_id())); self.bluetooth.set_advertisement(name="a_cr", manufacturer_data="l", service_data=mes) self.bluetooth.advertise(True) self.Tile_Transmit_Timer = 50 return -1 #Tells other robots to forget if a robot of an ID has been charged def Call_Charge_Handled(self): #Simplyt broadcasts nothing with the correct name mes = "cH" self.bluetooth.set_advertisement(name="a_ch", manufacturer_data="l", service_data=mes) self.Tile_Transmit_Timer = 50
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)
# print('Read request on char 2') # # def char21_cb_handler(chr, data): # # The value is not used in this callback as the WRITE events are not processed. # events, value = data # if events & Bluetooth.CHAR_READ_EVENT: # print('Read request on char 21') # # bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456') bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb) # bluetooth.callback(trigger=Bluetooth.CHAR_NOTIFY_EVENT, handler=conn_notify_cb) bluetooth.advertise(False) # srv1 = bluetooth.service(uuid=b'1234567890123456', isprimary=True) chr1 = srv1.characteristic(uuid=b'ab34567890123456', properties=Bluetooth.PROP_READ, value=0) char1_cb = chr1.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler) # # srv2 = bluetooth.service(uuid=1234, nbr_chars=2 ,isprimary=True) # chr2 = srv2.characteristic(uuid=4567, value=0x1234) # char2_cb = chr2.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=char2_cb_handler) # chr21 = srv2.characteristic(uuid=4568, value=0x4321) # char21_cb = chr2.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=char21_cb_handler)
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()
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