def initConnection(address): pycom.rgbled(0xffff00) pycom.heartbeat(False) bluetooth = Bluetooth() bluetooth.start_scan(-1) bluetooth.init() while True: print("starting bluetooth") global connection devices = bluetooth.get_advertisements() try: if devices is not None and len(devices) > 0: for device in devices: uuid = ubinascii.hexlify(device.mac) if (str(uuid) == address): print("foud the arduino") connection = bluetooth.connect(device.mac) print(device) bluetooth.stop_scan() global char char = getBleChar() pycom.rgbled(0x00ff00) return device except: print("arduino refused connection trying again") pycom.heartbeat(True) closeConnection() continue time.sleep(0.05) pycom.rgbled(0xff0000) return None
def main(): gc.enable() while True: WIFI() #Connect to WiFi set_rtc() #Set RTC time mqtt1() #Connect Heatcheck Client mqtt2() #Conenct BLE Client _thread.start_new_thread(heartbeat, ()) #Start HeartBeat loop print("Scanning... from: " + MAC) #Prints device MAC print(TOPIC) #Prints BLE data Topic global bt bt = Bluetooth() if CONFIG.get( 'btExt') == True: #If wnating to use external BLE antenna Pin('P12', mode=Pin.OUT)(True) bt.init(antenna=Bluetooth.EXT_ANT) print("Using Ext for Bt") bt.start_scan(-1) #Start Scanning for BLE data indefinitely _thread.start_new_thread(scan, ()) #Start BLE decode loop print("Scanning....") running_check() #Start wait loop, checks for incoming messages machine.reset() #Should never get this ppoint
def BLEAndLoRaFun(): ###### First, initialize as one LoRa node device ###### # initialize LoRa in LORAWAN mode. # Please pick the region that matches where you are using the device: # Asia = LoRa.AS923 # Australia = LoRa.AU915 # Europe = LoRa.EU868 # United States = LoRa.US915 lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915) # create an ABP authentication params dev_addr = struct.unpack(">l", binascii.unhexlify('26021A14'))[0] nwk_swkey = binascii.unhexlify('BB515D851353D2AB5ACCD112F0F2C597') app_swkey = binascii.unhexlify('B74092CB7C5A79CAD681C384ABF925D2') # remove all the channels for channel in range(0, 72): lora.remove_channel(channel) # set all channels to the same frequency (must be before sending the OTAA join request) for channel in range(0, 72): lora.add_channel(channel, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=3) # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3) # last parameter is 3 # make the socket non-blocking s.setblocking(False) ''' ###### 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: print("Client connected") pycom.rgbled(0x007f00) # green elif events & Bluetooth.CLIENT_DISCONNECTED: 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', value=5) #char1_read_counter = 0 def char1_cb_handler(chr): #global char1_read_counter #char1_read_counter += 1 global BLEConnectionCounter events = chr.events() if events & Bluetooth.CHAR_WRITE_EVENT: print("Write request with value = {}".format(chr.value())) else: #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 char1_cb = chr1.callback(trigger=Bluetooth.CHAR_WRITE_EVENT | Bluetooth.CHAR_READ_EVENT, handler=char1_cb_handler) ''' ###### Third, set up BLE client service ###### bluetooth_client = Bluetooth() #bluetooth_client.init(id=0, mode=Bluetooth.BLE, antenna=None) bluetooth_client.start_scan(10) #server_name1 = bluetooth_client.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) counter = 50 #while True: while counter > 0: print(counter) counter -= 1 #Gets an named tuple with the advertisement data received during the scanning. #The structure is (mac, addr_type, adv_type, rssi, data) adv = bluetooth_client.get_adv() #servermac = ''#save the serer mac #use resolve_adv_data to resolve the 31 bytes of the advertisement message #Here is problem: when disconnect from server, then adv will always be null... #if get a valid advertisement from one server if adv: server_name = bluetooth_client.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) #print(server_name) if checkValidServer(server_name): try: #Opens a BLE connection with the device specified by the mac_addr argument #This function blocks until the connection succeeds or fails. #print(adv.mac) #global servermac#change servermac to global #servermac = adv.mac #counter += 1 conn = bluetooth_client.connect(adv.mac) #print('connected?',conn.isconnected()) services = conn.services() #print('This is service',services) #print(services) #Yunwei - it seems that only when the type of uuid is bytes then could read the data from server for service in services: time.sleep(0.050) if type(service.uuid()) == bytes: chars = service.characteristics() for char in chars: #check if the character properties is PROP_READ properties = char.properties() print('char properties is ' + str(properties)) if (properties & Bluetooth.PROP_READ): print('char {} value = {}'.format( char.uuid(), char.read())) #Use LoRa to send the data out #s.send(char.read()) time.sleep(2) #10 & Bluetooth.PROP_WRITE #10&Bluetooth.PROP_READ if (properties & Bluetooth.PROP_WRITE): print('write to server!') char.write(b'x02') time.sleep(2) #Yunwei conn.disconnect() #bluetooth_client.deinit() bluetooth_client.stop_scan() time.sleep(3) bluetooth_client.deinit() print('deinit') time.sleep(3) bluetooth_client.init() #if(bluetooth_client.isscanning()): # bluetooth_client.stop_scan() #bluetooth_client.deinit() bluetooth_client.start_scan(10) print('connected?', conn.isconnected()) #break time.sleep(3) gc.collect() #if it's still scan, then need to stop scan first #bluetooth_client.start_scan(-1) ''' if(bluetooth_client.isscanning()): bluetooth_client.stop_scan() #then scan again bluetooth_client.start_scan(-1) ''' except: print( "Error while connecting or reading from the BLE device" ) #break time.sleep(1) if (bluetooth_client.isscanning()): bluetooth_client.stop_scan() bluetooth_client.deinit() time.sleep(1) bluetooth_client.deinit() time.sleep(1) #init again bluetooth_client.init(id=0, mode=Bluetooth.BLE, antenna=None) bluetooth_client.start_scan(10) else: bluetooth_client.deinit() time.sleep(1) bluetooth_client.init() time.sleep(1) bluetooth_client.start_scan(10) print('Scan again') else: print('adv is None!') time.sleep(3) ''' time.sleep(3) #if it's still scan, then need to stop scan first if(bluetooth_client.isscanning()): bluetooth_client.stop_scan() #then scan again bluetooth_client.start_scan(-1) ''' #bluetooth_client.stop_scan() bluetooth_client.stop_scan() bluetooth_client.deinit() print('out of loop!')
class RuuviTag: def __init__(self, whitelist=None, antenna=None): self._whitelist = whitelist self._blacklist = [] self.bluetooth = Bluetooth() self.bluetooth.init(antenna=antenna) def __repr__(self): return "{}(whitelist={!r}, blacklist={!r})".format( type(self).__name__, self._whitelist, self._blacklist) @property def blacklist(self): return self._blacklist @blacklist.setter def blacklist(self, value): self._blacklist = value def get_tag(self, mac, adv): data = self.get_data(adv) if data is None: self._blacklist.append(mac) return None data = self.decode_data(*data) # Select namedtuple for URL or RAW format if data[0] in [2, 4]: tag = RuuviTagURL else: tag = RuuviTagRAW if data[0] == 3: # Fill missing measurements from RAW 1 # format with None data = data + (None, ) * 3 return tag(mac.decode("utf-8"), adv.rssi, *data) def get_data(self, adv): # raw1 and raw2 format data = self.get_data_format_raw(adv) if data is not None: return data # deprecated url format data = self.get_data_format_2and4(adv) if data is not None: return (2, data) @staticmethod def get_data_format_2and4(adv): """ Test if device data is in data format 2 or 4. Returns measurement data or None if not in format 2 or 4. """ try: data = adv.data.decode("utf-8") index = data.find("ruu.vi/#") if index > -1: return data[(index + 8):] else: index = data.find("r/") if index > -1: return data[(index + 2):] return None except Exception: return None def get_data_format_raw(self, adv): """Test if device data is in raw format 3 (RAWv1) or 5 (RAWv2). Returns decoded measurements from the manufacturer data or None if not in format RAWv1, RAWv2 or no data can be extracetd from the device. The Bluetooth device is necessary to get the manufacturer data. """ raw_data_formats = [3, 5] try: data = self.bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA) except TypeError: return None if data is None: return None # Only RuuviTags if data[:2] != b"\x99\x04": return None # Only data format 3 and 5 (raw) if data[2] not in raw_data_formats: return None return (data[2], data) def decode_data(self, data_format, data): if data_format in (2, 4): return decode_data_format_2and4(data) elif data_format == 3: return decode_data_format_3(data) elif data_format == 5: return decode_data_format_5(data)
def BLEClient(): #Description: check if the BLE server is set up by another LoPy #Note: for convention reason, the LoPy server name will be "LoPyServer"+device_id def checkValidServer(server_name): if (server_name == None): return False else: #check if server_name contains "LoPyServer" if (re.match('LoPyServer*', server_name)): return True else: return False global rec_msg ###### Third, set up BLE client service ###### bluetooth_client = Bluetooth() bluetooth_client.start_scan(10) #server_name1 = bluetooth_client.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) counter = 50 #while True: while counter > 0: #Gets an named tuple with the advertisement data received during the scanning. #The structure is (mac, addr_type, adv_type, rssi, data) adv = bluetooth_client.get_adv() #servermac = ''#save the serer mac #use resolve_adv_data to resolve the 31 bytes of the advertisement message #Here is problem: when disconnect from server, then adv will always be null... #if get a valid advertisement from one server if adv: server_name = bluetooth_client.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) #print(server_name) if checkValidServer(server_name): try: #Opens a BLE connection with the device specified by the mac_addr argument #This function blocks until the connection succeeds or fails. #print(adv.mac) #global servermac#change servermac to global #servermac = adv.mac #counter += 1 conn = bluetooth_client.connect(adv.mac) #print('connected?',conn.isconnected()) services = conn.services() #print('This is service',services) #print(services) #Yunwei - it seems that only when the type of uuid is bytes then could read the data from server for service in services: time.sleep(0.050) if type(service.uuid()) == bytes: chars = service.characteristics() for char in chars: #check if the character properties is PROP_READ if (char.properties() & Bluetooth.PROP_READ): print('char {} value = {}'.format( char.uuid(), char.read())) #create lora msg rec_msg = str(char.read()) counter -= 1 #Use LoRa to send the data out #s.send(char.read()) time.sleep(5) #Yunwei conn.disconnect() print('connected?', conn.isconnected()) #break time.sleep(3) gc.collect() bluetooth_client.start_scan(10) except: print( "Error while connecting or reading from the BLE device" ) #break time.sleep(1) if (bluetooth_client.isscanning()): bluetooth_client.stop_scan() bluetooth_client.deinit() time.sleep(1) bluetooth_client.init() time.sleep(1) #init again #bluetooth_client.init(id=0, mode=Bluetooth.BLE, antenna=None) bluetooth_client.start_scan(10) else: bluetooth_client.deinit() time.sleep(1) bluetooth_client.init() time.sleep(1) bluetooth_client.start_scan(10) bluetooth_client.stop_scan() bluetooth_client.deinit()
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 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)
from network import Bluetooth import time import ubinascii import binascii import struct bt = Bluetooth() bt.start_scan(-1) bt.init() # This is important for it to work! Put on front fo bt.start? def acc_recieve_array(): #x_acc_char.value(b) pass tilt = 0 i = 0 T = [] data_1 = 0 initialWait = 0 while True: #time.sleep(3) #Every 3 seconds adv = bt.get_adv() if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'LoPy': conn = bt.connect(adv.mac) services = conn.services() while True: for service in services: chars = service.characteristics() for char in chars:
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