def bluetooth_scanner(): global ble_thread try: while True: try: tools.debug('BLE - Starting BLE scanner, RSSI: ' + str(int(globalVars.RSSI_NEAR_THRESHOLD,16) - 256) + " - RTC: " + str(int(utime.time())) + " - REFRESH: " + str(globalVars.MAX_REFRESH_TIME) + " - SCAN: " + str(int(globalVars.BLE_SCAN_PERIOD)) + " - SLEEP: " + str(int(globalVars.STANDBY_PERIOD)) + " - DEBUG: " + str(globalVars.debug_cc) ,'v') ble_thread = True bluetooth = Bluetooth() bluetooth.tx_power(Bluetooth.TX_PWR_SCAN, Bluetooth.TX_PWR_P9) bluetooth.start_scan(int(globalVars.BLE_SCAN_PERIOD)) while bluetooth.isscanning(): adv = bluetooth.get_adv() if adv: if 'WILOC_01' in str(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)): data_raw = str(ubinascii.hexlify(adv.data).decode('utf-8')) if globalVars.MAC_TYPE == "LORA": mac_proc = data_raw[34:50] # LoRa MAC elif globalVars.MAC_TYPE == "BLE": mac_proc = str(ubinascii.hexlify(adv.mac).decode('utf-8')) # MAC BLE tools.debug('Name: '+ str(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) +' MAC: '+ str(mac_proc)+ ' RSSI: ' + str(adv.rssi) + ' DT: '+ str(int(utime.time())) +' RAW: ' + data_raw,'vvv') if mac_proc not in globalVars.mac_scanned: tools.debug('Step 1 - New device detected: ' + str(mac_proc),'vv') globalVars.mac_scanned.append(mac_proc) if adv.rssi >= (int(globalVars.RSSI_NEAR_THRESHOLD,16) - 256): wilocMain.checkListType(str(mac_proc), globalVars.ALARM_LIST_TYPE) globalVars.scanned_frames.append(Device(addr=mac_proc,rssi=adv.rssi, raw=data_raw)) elif 'WIL_C01' in str(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)): data_raw = str(ubinascii.hexlify(adv.data).decode('utf-8')) mac_proc = str(ubinascii.hexlify(adv.mac).decode('utf-8')) # MAC BLE #tools.debug('BLE Name: '+ str(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) +' - BLE MAC: '+ str(mac_proc)+ ' - RSSI: ' + str(adv.rssi) + ' - DT: '+ str(int(utime.time())) +' - RAW: ' + data_raw,'vvv') if mac_proc not in globalVars.mac_scanned: tools.debug('Step 1 - BLE New device detected: ' + str(mac_proc),'vv') globalVars.mac_scanned.append(mac_proc) if adv.rssi >= (int(globalVars.RSSI_NEAR_THRESHOLD,16) - 256): wilocMain.checkListType(str(mac_proc), globalVars.ALARM_LIST_TYPE) globalVars.scanned_frames.append(Device(addr=mac_proc,rssi=adv.rssi, raw=data_raw)) tools.debug('BLE - Stopping BLE scanner ' + str(int(utime.time())),'v') tools.sleepWiloc(int(globalVars.STANDBY_PERIOD)) except BaseException as ee1: checkError("Error scanning Bluetooth",ee1) tools.sleepWiloc(int(globalVars.STANDBY_PERIOD)) except BaseException as e: checkError("Error thread Bluetooth", e) ble_thread = False finally: ble_thread = False _thread.start_new_thread(bluetooth_scanner,())
def getBluetoothNetworks(): bl_networks = {} tmp_mac = [] bl_index = 0 nb_scan = 0 bl = Bluetooth() while nb_scan < NB_SCAN_BL: print("scan : %d" % nb_scan) bl.start_scan(10) #Duration of scan to be define !!!! while bl.isscanning(): adv = bl.get_adv() if adv: if adv.mac not in tmp_mac: tmp_mac.append(adv.mac) bl_networks[str(bl_index)] = { "id": str(ubinascii.hexlify(adv.mac, ":"))[2:19], "rssi": str(adv.rssi) } print("NAME = %s -- MAC : %s -- RSSI = %d" % (bl.resolve_adv_data(adv.data, bl.ADV_NAME_CMPL), ubinascii.hexlify(adv.mac, ":"), adv.rssi)) bl_index += 1 nb_scan += 1 tmp_mac = [] utime.sleep(BL_DELAY_SCAN_SEC) print("getBluetoothNetworks - Done!") return bl_networks
def isOwnerNearby(self): ''' Logic here checks if a known BLE device is broadcasting nearby. If they are, return true. Else, return false ''' # TODO remove return False bt = Bluetooth() bt.start_scan(ConfigBluetooth.SCAN_ALLOW_TIME) # Scans for 10 seconds while bt.isscanning(): adv = bt.get_adv() if adv and binascii.hexlify(adv.mac) == ConfigBluetooth.MAC_ADDR: try: if self.debug: print("Owner device found: {} Mac addr {}".format( bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL), ConfigBluetooth.MAC_ADDR)) conn = bt.connect(adv.mac) time.sleep(0.05) conn.disconnect() bt.stop_scan() except Exception: bt.stop_scan() return True time.sleep(0.050) return False
def scanBluetooth(): bt = Bluetooth() bt.start_scan( -1) # Start scanning indefinitely until stop_scan() is called while True: adv = bt.get_adv() if adv: # try to get the complete name print("BT Name: {}".format( bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL))) # print out mac address of bluetooth device print("Mac addr: {}, {}".format(adv.mac, binascii.hexlify(adv.mac))) else: time.sleep(0.5) time.sleep(3)
def isBTDeviceNearby(): bt = Bluetooth() while True: print("Scanning for owner BT device nearby...") bt.start_scan(10) # Scans for 10 seconds while bt.isscanning(): adv = bt.get_adv() if adv and binascii.hexlify(adv.mac) == ConfigBluetooth.MAC_ADDR: try: print("Owner device found: {} Mac addr {}".format( bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL), ConfigBluetooth.MAC_ADDR)) conn = bt.connect(adv.mac) time.sleep(0.05) conn.disconnect() bt.stop_scan() except Exception as e: print("Exception {}".format(e)) bt.stop_scan() break else: time.sleep(0.050)
# org.bluetooth.characteristic.weight_measurement_WS_CHAR = (UUID(0x2A9D), FLAG_READ | FLAG_NOTIFY,) # org.bluetooth.service.environmental_sensing - ES _ES_INT = 0x181A from network import Bluetooth import time import struct print('Create BT') bluetooth = Bluetooth() print('Scanning...') bluetooth.start_scan(2) # start scanning with no timeout time.sleep(2.1) if not bluetooth.isscanning(): for adv in bluetooth.get_advertisements(): name = bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) if name == 'HEN': mac = adv.mac try: print('Connecting to HEN') conn = bluetooth.connect(adv.mac) time.sleep(0.05) services = conn.services() for service in services: time.sleep(0.050) #print('Service: ',service.uuid()) #print('Chars: ',service.characteristics()) uuid = service.uuid() if type(uuid) == bytes: #uuid_str = UUIDbytes2UUIDstring(uuid)
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)
import ubinascii import time from network import Bluetooth ######################################################## # Scan for bluetooth signals and retrieve data # ######################################################## ids = [] bluetooth = Bluetooth() bluetooth.start_scan(20) while bluetooth.isscanning(): adv = bluetooth.get_adv() if adv: mfg_data = bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA) if mfg_data: if (ubinascii.hexlify(mfg_data) == str.encode( "590002150112233445566778899aabbccddeeff0dd907baabb")): print("you have arrived", ubinascii.hexlify(mfg_data)) break else: if ubinascii.hexlify(mfg_data) not in ids: ids.append(ubinascii.hexlify(mfg_data)) print(ubinascii.hexlify(mfg_data), " strength ", adv.rssi)
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()
bt.start_scan(-1) intervalloEsposizione = 0 numeroDiMisureSingole = 0 #assumerà valori sempre maggiori se permane lo stato (es ESITO 0 o 1), se cambia viene riportata a 0 elementi tipoDiEsitoCorrente = 0 soglia = 5 #means che 10 secondi di intervallo minimo possono essere passati con MQTT ---> successivamente metteremo 30 (ossia un minuto) #def char_notify_callback(char): #char_value = (char.value()) #print("Got new char: {} value: {}".format(char.uuid(), char_value)) while True: print('Sono un while loopppp con esito di scan a ', bt.isscanning()) adv = bt.get_adv() if adv and bt.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) == 'BLDG Arduino Nano 33 BLE': while True: try: conn = bt.connect(adv.mac) services = conn.services() for service in services: time.sleep( 2 ) #attendo 2 sec per uniformarmi con i tempi di arduino #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() i = 0 #contatore ignorante per considerare le varie caratteristiche (prima contatore, poi ESITO ESPOSIZIONE)
from network import Bluetooth import binascii import time bt = Bluetooth() bt.set_advertisement(name="lopy1", manufacturer_data="lopy_v1") # scan until we can connect to any BLE device around bt.start_scan(-1) while True: adv = bt.get_adv() if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'lopy2': try: conn = bt.connect(adv.mac) services = conn.services() for service in services: time.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() break except: print("Error while connecting or reading from the BLE device")
m = 1 # number of observations ekf = ekf(n, m) # Set initial state n x 1 X matrix ekf.setX(0, -70) ekf.setX(1, 0) # Set initial covariance n x n P matrix ekf.setP(0, 0, 100) ekf.setP(1, 1, 100) # Setup bluetooth to scan bluetooth devices bt = Bluetooth() bt.stop_scan() bt.start_scan(-1) prev = utime.ticks_ms() while True: adv = bt.get_advertisements() if len(adv) > 0: for ad in adv: if bt.resolve_adv_data(ad.data, bt.ADV_NAME_CMPL) == 'RECO': if ubinascii.hexlify(ad.mac) == b'fd46b42dfe28': now = utime.ticks_ms() t = utime.ticks_diff(now, prev) / 1000 prev = now z = [ad.rssi] # Sensor observations ekf.step(z, update_eq, ekf, t) # EKF cycle x_filtered = ekf.getX() # Get filtered states print(x_filtered[0], ',', z[0])
# later version, with permitted additional terms. For more information # see the Pycom Licence v1.0 document supplied with this file, or # available at https://www.pycom.io/opensource/licensing # from network import Bluetooth import binascii import time bt = Bluetooth() bt.start_scan(-1) while True: adv = bt.get_adv() if adv: # try to get the complete name print(bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) # try to get the manufacturer data (Apple's iBeacon data is sent here) mfg_data = 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) print(binascii.hexlify(mfg_data)) if bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate': conn = bt.connect(adv.mac) services = conn.services() for service in services: time.sleep(0.050)
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!')
from network import Bluetooth import time bt = Bluetooth() bt.start_scan(-1) while True: adv = bt.get_adv() if adv # try to get the complete name print(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) # try to get the manufacturer data (Apple's iBeacon data is sent here) print(binascii.hexlify(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA))) if bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate': conn = bt.connect(adv.mac) services = conn.services() for service in services: time.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() break else:
def BlueToothFun(): ''' #Firstly,act as a server pycom.heartbeat(False) bluetooth = Bluetooth() #create a bluetooth object bluetooth.set_advertisement(name='LoPyServer2', service_uuid=b'1234567890123456') #id for this device deviceID = 222 #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 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 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) chr2 = srv2.characteristic(uuid=4567, value=0x1234) char2_read_counter = 0xF0 def char2_cb_handler(chr): global char2_read_counter char2_read_counter += 1 if char2_read_counter > 0xF1: return char2_read_counter char2_cb = chr2.callback(trigger=Bluetooth.CHAR_READ_EVENT, handler=char2_cb_handler)''' #Secondly, also act as client bt = Bluetooth() bt.start_scan(-1) counter = 0 while True: #Gets an named tuple with the advertisement data received during the scanning. #The structure is (mac, addr_type, adv_type, rssi, data) adv = bt.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 adv and bt.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) == 'LoPyServer1': 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 = bt.connect(adv.mac) #print('connected?',conn.isconnected()) services = conn.services() #print('This is service',services) #print(services) ''' for service in services: print('This is service uuid',service.uuid()) time.sleep(0.050) if type(service.uuid()) == bytes: print('if bytes:Reading chars from service = {}'.format(service.uuid())) else: print('if not bytes: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())) ''' #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()) + str(counter)) #Yunwei conn.disconnect() print('connected?', conn.isconnected()) #break time.sleep(1) bt.start_scan(-1) except: print("Error while connecting or reading from the BLE device") #break time.sleep(1) bt.start_scan(-1) print('Scan again')
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('260214B3'))[0] nwk_swkey = binascii.unhexlify('2C2139EEC68B264BF1F0EDCE183CE33F') app_swkey = binascii.unhexlify('C25FB9A263307BF86B659298D86D4A45') # 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, act as BLE client bt = Bluetooth() bt.start_scan(-1) counter = 0 while True: #Gets an named tuple with the advertisement data received during the scanning. #The structure is (mac, addr_type, adv_type, rssi, data) adv = bt.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 adv and bt.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) == 'LoPyServer1': 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 = bt.connect(adv.mac) #print('connected?',conn.isconnected()) services = conn.services() #print('This is service',services) #print(services) ''' for service in services: print('This is service uuid',service.uuid()) time.sleep(0.050) if type(service.uuid()) == bytes: print('if bytes:Reading chars from service = {}'.format(service.uuid())) else: print('if not bytes: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())) ''' #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()) + str(counter)) #Use LoRa to send the data out s.send(char.read()) time.sleep(4) #Yunwei conn.disconnect() print('connected?', conn.isconnected()) #break time.sleep(6) bt.start_scan(-1) except: print("Error while connecting or reading from the BLE device") #break time.sleep(1) bt.start_scan(-1) print('Scan again')
def checkId(): print("BEACON ID", beaconId) if beaconId != "": if str.encode(beaconId) in dangerAreas: del dangerAreas[str.encode(beaconId)] bluetooth = Bluetooth() bluetooth.start_scan(10) while bluetooth.isscanning(): adv = bluetooth.get_adv() if adv: # try to get the complete name #print(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) if (adv.rssi > -63): mfg_data = adv.mac #bluetooth.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) #print(ubinascii.hexlify(mfg_data)) tempIdValue = ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA)) time.sleep(2) print(tempIdValue) if (tempIdValue == str.encode(beaconId)): print("you have arrived", adv.rssi) break else: if ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth. ADV_MANUFACTURER_DATA)) in dangerAreas: p_out.value(1) #Vibrate the motor time.sleep(2) p_out.value(0) time.sleep(3) if (len(locations) > 0): if (dangerAreas[ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth. ADV_MANUFACTURER_DATA))] != locations[-1]): locations.append( dangerAreas[ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth. ADV_MANUFACTURER_DATA))]) print("location: ", locations[-1]) time.sleep(3) break else: locations.append( ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth. ADV_MANUFACTURER_DATA))) print("location: ", locations[-1]) time.sleep(3) break print("Location size ", len(locations)) print( "Data of danger device", ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA)), " strength ", adv.rssi) else: print( "Data of device", ubinascii.hexlify( bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA)), " strength ", adv.rssi) else: continue else: print("No beaconId")
import pycom import binascii import network from network import WLAN from machine import RTC bluetooth = Bluetooth() bluetooth.set_advertisement(name="lopy2", manufacturer_data="lopy_v2") bluetooth.start_scan( -1) #Change to 10 to have it searching for 10 sec instead if forever #bluetooth.stop_scan() adv = None bluetooth.advertise(True) while True: adv = bluetooth.get_adv() if adv and bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'lopy1': try: bluetooth.connect(adv.mac) print( bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_APPEARANCE)) print("Connected to device with addr = {}".format( binascii.hexlify(adv.mac))) #bluetooth.connect(adv.mac) pycom.heartbeat(False) for cycles in range(1): # stop after 1 cycles pycom.rgbled(0x000080) # blue time.sleep(0.5) pycom.rgbled(0x000000) # blue
class BLEScanner(object): """ BLE scanner for beacons and tags data packages """ def __init__(self, max_list_items=25): self._beacons = [] self._tags = [] self._max_list_items = max_list_items self._ble = None def start(self, timeout=-1): """ Start beacon scanning """ log.info('Start scanning for beacons and tags') if self._ble is None: self._ble = Bluetooth() self._ble.start_scan(timeout) while self._ble.isscanning(): self.beacon_data_collect() def stop(self): """ Stop BLE """ log.info('Stop scanning for beacons and tags') if self._ble: self._ble.stop_scan() #self._ble.deinit() #self._ble = None def set_max_list_items(self, max_list_items): """ Set the max list items to return""" self._max_list_items = max_list_items def reset(self): """ Reset the retrieved beacon/tag list during scanning """ log.info('Reset beacon/tag list') self._beacons[:] = [] self._tags[:] = [] @property def beacons(self): """ Return the beacons found """ res = list(self._beacons) # make a copy return res @property def tags(self): """ Return the tags found """ res = list(self._tags) # make a copy return res def beacon_data_collect(self): """ Collect the beacon data """ adv = self._ble.get_adv() if adv: if self._ble.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == "ITAG": binitag = binascii.hexlify(adv[0]) tag = binitag.decode('UTF-8') if tag not in self._tags: log.debug('Found tag [{}]', tag) self._tags.append(tag) else: # try to get the complete name only works with ibeacons data = self._ble.resolve_adv_data( adv.data, Bluetooth.ADV_MANUFACTURER_DATA) if data: # try to get the manufacturer data (Apple's iBeacon data is sent here) bindata = binascii.hexlify(data) beacon = bindata.decode('UTF-8') # Check if beacon is in list if beacon not in self._beacons: log.debug('Found beacon [{}]', beacon) self._beacons.append(beacon)
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
def BLEClientTest(): bluetooth_client = Bluetooth() bluetooth_client.start_scan(-1) adv = bluetooth_client.get_adv() server_name = bluetooth_client.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)
import ubinascii from network import Bluetooth bluetooth = Bluetooth() bluetooth.start_scan(20) while bluetooth.isscanning(): adv = bluetooth.get_adv() if adv: # try to get the complete name print(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)) mfg_data = bluetooth.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) print(ubinascii.hexlify(mfg_data))
# time.sleep(1) wdt.feed() from network import Bluetooth import time bt = Bluetooth() bt.start_scan(-1) print("getting BLE advert") isDataSent = False failureCount = 0 while isDataSent == False: adv = bt.get_adv() if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'gpy4gcam': print('found gpy4gcam') try: conn = bt.connect(adv.mac) services = conn.services() print('printing services...') for idx, service in enumerate(services): time.sleep(0.050) chars = service.characteristics() print('printing characteristics') for idx_,char in enumerate(chars): if (char.properties() & Bluetooth.PROP_READ): print('service = {:x}, char = {:x} value = {}'.format(service.uuid(),char.uuid(), char.read())) if char.uuid() == 0xaa2: print('0xaa2 found') char.write(b'x0f')
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")
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)) print("NameShort: "+str(bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_SHORT))) print("NameComplete: "+str(bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL))) mfg_data = 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) print("ManufacturerData: "+str(ubinascii.hexlify(mfg_data))) print("connecting to "+str(ubinascii.hexlify(adv.mac))) try: conn = bt.connect(adv.mac) t = "other" if conn: try: print("connected to "+str(ubinascii.hexlify(adv.mac))) services = conn.services() for service in services: if type(service.uuid()) == bytes:
from network import Bluetooth import machine import time from pytrack import Pytrack py = Pytrack() bt = Bluetooth() bt.start_scan(-1) count = 0 no_adv_count = 0 while True: adv = bt.get_adv() count += 1 if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'gpy': #if adv: print("{}: AVD FOUND and {}".format( count, bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL))) try: conn = bt.connect(adv.mac) services = conn.services() for service in services: time.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:
from network import Bluetooth import time bt = Bluetooth() bt.stop_scan() bt.start_scan(-1) while True: adv = bt.get_adv() print(adv) if adv: print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_NAME_CMPL)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_NAME_SHORT)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_FLAG)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_16SRV_PART)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_T16SRV_CMPL)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_32SRV_PART)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_32SRV_CMPL)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_128SRV_PART)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_128SRV_CMPL)) print('data %s' % bt.resolve_adv_data(adv.data, bt.ADV_TX_PWR)) time.sleep(4) if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate': conn = bt.connect(adv.mac) services = conn.services() for service in services: time.sleep(0.050) if type(service.uuid()) == bytes: print('Reading chars from service = {}'.format(service.uuid())) else:
MacAddressList = [] MacAddressL = [] whiteList = [b'c2516b8e459d', b'f00f695ff143', b'c538524c4d77'] mapDict = {whiteList[0]: 'Tag1', whiteList[1]: 'Tag2', whiteList[2]: 'Tag3'} bluetooth.start_scan(20) while True: #Retrieves mac adresses in the allocated time while bluetooth.isscanning(): adv = bluetooth.get_adv() #CHANGE KONTAKT TO THE ADV NAME OF THE BLE TAGS YOU ARE USING if adv and bluetooth.resolve_adv_data( adv.data, Bluetooth.ADV_NAME_CMPL) == 'Kontakt': print(ubinascii.hexlify(adv.mac)) MacAddressList.append(ubinascii.hexlify(adv.mac)) MacAddressList = [x for x in MacAddressList if x in whiteList] MacAddressList = list(set(MacAddressList)) MacAddressL = [mapDict.get(n, n) for n in MacAddressList] MacAddressString = ' '.join(map(str, MacAddressL)) data_out = json.dumps(MacAddressString) print("encoded" + data_out) data_in = data_out Mac_in = json.loads(data_in) print("decoded" + data_in) #pycom.rgbled(0x00FF00) time.sleep(1) if bluetooth.isscanning() == False: