def send_LORA(value): # Initialize LoRa in LORAWAN mode. lora = LoRa(mode=LoRa.LORAWAN) # create an ABP authentication params dev_addr = struct.unpack(">l", binascii.unhexlify(config.DEV_ADDR.replace(' ','')))[0] nwk_swkey = binascii.unhexlify(config.NWK_SWKEY.replace(' ','')) app_swkey = binascii.unhexlify(config.APP_SWKEY.replace(' ','')) # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # remove all the non-default channels for i in range(3, 16): lora.remove_channel(i) # set the 3 default channels to the same frequency lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # 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, 5) # make the socket blocking s.setblocking(False) s.send(bytes(value))
def lora(): lora = LoRa(mode=LoRa.LORAWAN) dev_addr = struct.unpack(">l", binascii.unhexlify('26011DA5'.replace( ' ', '')))[0] #Device Address nwk_swkey = binascii.unhexlify('9E8262DC2B9787CA600C5CF46F25CC55'.replace( ' ', '')) # Network Session Key app_swkey = binascii.unhexlify('77F84AF9B49326ACE2E1F0CB18A79FB0'.replace( ' ', '')) # App Session Key for channel in range(3, 16): lora.remove_channel(channel) # set the channels frequency lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) for i in range(3, 16): lora.remove_channel(i) s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) s.setblocking(False) return s
def initialize_lorawan_link(self): #print(ubinascii.hexlify(network.LoRa().mac())) # Initialise 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.AU915, adr=False) self.myLora = lora # create an ABP authentication params dev_addr = struct.unpack(">l", ubinascii.unhexlify('260211EE'))[0] nwk_swkey = ubinascii.unhexlify('AB189EFE29DCF9F9830F3A564DC1844E') app_swkey = ubinascii.unhexlify('A55931ACC412DE51171CEDA45BE6B319') #for channel in range(0, 72): # lora.add_channel(channel, frequency=916800000, dr_min=0, dr_max=5) #lora.add_channel(0, frequency=923300000, dr_min=0, dr_max=5) for i in range(8, 72): lora.remove_channel(i) start = 916800000 f_inc = 200000 curr = start for i in range(8): #print(curr) lora.add_channel(index=i, frequency=curr, dr_min=0, dr_max=5) curr += f_inc #lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=self.lora_cb) # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) #print(lora.has_joined()) # wait until the module has joined the network while not lora.has_joined(): time.sleep(2.5) print('Not yet joined...') #print("Has joined!!!!!") # 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, self.data_rate) s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False) return s
def init(): global s # 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.EU868) # create an OTA authentication params # dev_eui = binascii.unhexlify('30AEA4FFFE505654') dev_eui = binascii.unhexlify('3AAEA4FFFE505654') app_eui = binascii.unhexlify('70B3D57ED000BDA0') # app_key = binascii.unhexlify('6D08E6C2C4237B3A1D223404713DF335') app_key = binascii.unhexlify('705DFC1AF37D90FB858F510EAFAAAE14') # set the 3 default channels to the same frequency (must be before sending the OTAA join request) lora.add_channel(0, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) lora.add_channel(1, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) lora.add_channel(2, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) # join a network using OTAA lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=config.LORA_NODE_DR) # wait until the module has joined the network while not lora.has_joined(): time.sleep(2.5) print('Not joined yet...') print('Joined') # remove all the non-default channels for i in range(3, 16): lora.remove_channel(i) # 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, config.LORA_NODE_DR) # make the socket blocking s.setblocking(False)
def send(self): t0 = time.time() print("LoRaWAN start") lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) # set the 3 default channels to the same frequency (must be before sending the OTAA join request) lora.add_channel(0, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) lora.add_channel(1, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) lora.add_channel(2, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) # join a network using OTAA lora.join(activation=LoRa.OTAA, auth=(self.dev_eui, self.app_eui, self.app_key), timeout=0, dr=config.LORA_NODE_DR) # wait until the module has joined the network while not lora.has_joined(): time.sleep(2.5) print('Not joined yet...', time.localtime()) # remove all the non-default channels for i in range(3, 16): lora.remove_channel(i) # 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, config.LORA_NODE_DR) # make the socket non-blocking s.setblocking(False) pkt = b'PKT #' + bytes([i]) print('Sending:', pkt) s.send(pkt) print("LoRaWAN done in ", time.time() - t0, " seconds")
def connect(): global _lora pycom.rgbled(0x7f0000) #red _lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) # Remove all the non-default channels for i in range(3, 16): _lora.remove_channel(i) print('Removed default channels') time.sleep(1) # Set EU ISM 868 channel plan for TTN Europe _lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) _lora.add_channel(1, frequency=868300000, dr_min=0, dr_max=5) _lora.add_channel(2, frequency=868500000, dr_min=0, dr_max=5) _lora.add_channel(3, frequency=867100000, dr_min=0, dr_max=5) _lora.add_channel(4, frequency=867300000, dr_min=0, dr_max=5) _lora.add_channel(5, frequency=867500000, dr_min=0, dr_max=5) _lora.add_channel(6, frequency=867700000, dr_min=0, dr_max=5) _lora.add_channel(7, frequency=867900000, dr_min=0, dr_max=5) print('EU channels set') time.sleep(1) #Join TTN Network via OTAA _lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=0) # wait until the module has joined the network print('Trying to join TTN Network...') while not _lora.has_joined(): pycom.rgbled(0x7f7f00) #yellow time.sleep(5) print('...') pass print('Network joined') pycom.rgbled(0x009999) #teal
def setupLora(): utime.sleep_ms(5) #thethingsnetwork parameters dev_addr = struct.unpack(">l", binascii.unhexlify(config.dev_addr))[0] nwk_swkey = binascii.unhexlify(config.nwk_swkey) app_swkey = binascii.unhexlify(config.app_swkey) #initialize LoRa in LORAWAN mode for Australia AU915 lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AU915) # remove all the non-default channels and leave channels 8-15 and 65 for index in range(0, 8): lora.remove_channel(index) # remove 0-7 for index in range(16, 65): lora.remove_channel(index) # remove 16-64 for index in range(66, 72): lora.remove_channel(index) # remove 66-71 # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # create a LoRa socke s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # make the socket non-blocking s.setblocking(False) #print("LoRa connexion set up") utime.sleep_ms(5) return s
def setup_node(): lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915) # create an ABP authentication params dev_addr = struct.unpack(">l", binascii.unhexlify('260210B3'.replace(' ', '')))[0] nwk_swkey = binascii.unhexlify('EC6368A1D013E22B7B4BAF96645DCF48'.replace( ' ', '')) app_swkey = binascii.unhexlify('5A60972B94850CA94141ED76FAC0DEDD'.replace( ' ', '')) # 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=4) # 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, config.LORA_NODE_DR) # make the socket blocking s.setblocking(False) return s
class Comunication: def __init__(self): self.key = b'encriptaincendis' self.node_list = "" pass # Initialize LoRa in LORAWAN mode. def JoinLoraWan(self): self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) # create an OTA authentication params app_eui = ubinascii.unhexlify('70B3D57ED001C55E') dev_eui = ubinascii.unhexlify( '006D2D7767E7BAFE') # these settings can be found from TTN #app_eui = ubinascii.unhexlify('70B3D57ED0019255') # these settings can be found from TTN app_key = ubinascii.unhexlify('0A05862CEA15FC56C047FC03FBDF34DB' ) # these settings can be found from TTN # set the 3 default channels to the same frequency (must be before sending the OTAA join request) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # join a network using OTAA self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # wait until the module has joined the network while not self.lora.has_joined(): time.sleep(2.5) print('Not joined yet...') # remove all the non-default channels for i in range(3, 16): self.lora.remove_channel(i) # create a LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate. DR5 means 5470 bits/s ans max payload=230 self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) # make the socket non-blocking self.s.setblocking(False) time.sleep(5) def start_LoraRaw(self): self.lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setblocking(False) #Aquesta instrucció igual sobra time.sleep(5) lora = self.lora #return(lora) def change_txpower(self, power): self.lora.tx_power(power) def savestate(self): self.lora.nvram_save() def Switch_to_LoraRaw(self): self.lora.nvram_save() self.lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setblocking(False) #Aquesta instrucció igual sobra time.sleep(5) def Switch_to_LoraWan(self): self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) self.lora.nvram_restore() time.sleep(2.5) #Si no es reinicia el socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) self.s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False) def EnviarGateway(self, data): self.s.bind(2) self.s.send(data) time.sleep(10) def sendData(self, msg, rtc, f): if "Hay" not in msg: f = open('msg_sent_final.txt', 'a') f.write("{}/{}/{} {}:{}:{} msg {} stats {}\n".format( rtc.now()[2], rtc.now()[1], rtc.now()[0], rtc.now()[3], rtc.now()[4], rtc.now()[5], msg, self.lora.stats())) f.close() self.s.setblocking(True) iv = crypto.getrandbits( 128) # hardware generated random IV (never reuse it) cipher = AES(self.key, AES.MODE_CFB, iv) misg_crc = msg + " " + str(self.calculate_crc(msg)) msg = iv + cipher.encrypt(misg_crc) self.s.send(msg) #print("missatge amb crc", msg) self.s.setblocking(False) #print(msg) #print(len(msg)) #time.sleep(5) def reciveData(self, rtc, f): self.s.setblocking(False) msg = self.s.recv(128) #Get any data recieved #If there's any data, decrypt if (len(msg) > 0): try: #print("encriptat: ",msg) cipher = AES(self.key, AES.MODE_CFB, msg[:16]) # on the decryption side original = cipher.decrypt(msg[16:]) print("original ", original) if "Config" in original or "stop" in original or "Discover" in original or "Hello" in original or "Info" in original or "Token" in original or "Alarm" in original or "Hay" in original: crc_OK, msg = self.check_crc(original) if crc_OK: if "Hay" not in msg: f = open('msg_received_final.txt', 'a') f.write( "{}/{}/{} {}:{}:{} msg {} stats {}\n".format( rtc.now()[2], rtc.now()[1], rtc.now()[0], rtc.now()[3], rtc.now()[4], rtc.now()[5], msg, self.lora.stats())) f.close() return (msg) else: print("CRC not OK") return ("error") else: return ("error") print("Keyword not in msg") except: return ("error") print("Exception") else: return ("error") print("Empty msg") def update_neighbours(self, pow, id_n, neighbours): if id_n in neighbours[0]: if pow < neighbours[1][neighbours[0].index(id_n)]: neighbours[1][neighbours[0].index(id_n)] = pow else: neighbours[0].append(id_n) neighbours[1].append(pow) #print("I have a friend ") print(neighbours) return neighbours def neighbours_min(self, neighbours, neighbours_aux, id): for id in neighbours[0]: if id in neighbours_aux[0]: neighbours[1][neighbours[0].index(id)] = min( neighbours[1][neighbours[0].index(id)], neighbours_aux[1][neighbours_aux[0].index(id)]) print(neighbours) return (neighbours) def ApplyFormat(self, splitmsg): packet_dust = ustruct.pack('H', int(splitmsg[3])) #Unsigned short 2 bytes packet_tempC = ustruct.pack('H', int(splitmsg[4])) packet_Tht = ustruct.pack('H', int(splitmsg[5])) packet_Hht = ustruct.pack( 'B', round(int(splitmsg[6]) * 100)) #Form 0 to 1 -> 0% to 100% #Unsigned char 1 byte packet_tbmp = ustruct.pack('H', int(splitmsg[7])) packet_val = ustruct.pack('H', int(splitmsg[8])) packet_dhi = ustruct.pack('B', int(splitmsg[9])) #+packet_TCam=ustruct.pack('f',int(splitmsg[10])) #id=splitmsg[1].encode('utf-8') id_aux = ustruct.pack('>Q', int(splitmsg[1], 16)) #long long: 8 bytes return (packet_dust + packet_tempC + packet_Tht + packet_Hht + packet_tbmp + packet_val + packet_dhi + id_aux) #+packet_TCam) def calculate_crc(self, msg): """ Compute CRC """ if type(msg) == bytes: msg = bytes.decode(msg) crc = 0 data = bin(int(binascii.hexlify(msg), 16)) data = str.encode(data) for i in range(len(data)): byte = data[i] for b in range(8): fb_bit = (crc ^ byte) & 0x01 if fb_bit == 0x01: crc = crc ^ 0x18 crc = (crc >> 1) & 0x7f if fb_bit == 0x01: crc = crc | 0x80 byte = byte >> 1 return crc def check_crc(self, msg): """ Check if CRC received is correct """ if type(msg) == bytes: msg = bytes.decode(msg) splitmsg = msg.split() crc_rcv = int(splitmsg[-1]) aux = " ".join(splitmsg[:-1]) #Not including the CRC received crc_new = self.calculate_crc(aux) return (crc_new == crc_rcv, aux) def get_node_list(self, list): self.node_list = list
def initialize_lora(name): print("first connection") lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915, tx_power=20, bandwidth=LoRa.BW_500KHZ, sf=7, frequency=903900000) #remove all channels gateway doesn't use for channel in range(16, 72): lora.remove_channel(channel) for channel in range(0, 7): lora.remove_channel(channel) #create an OTAA authentication parameters for no ring lopy if name == 1: dev_eui = ubinascii.unhexlify( '70B3D549952757BF') # these settings can be found from TTN app_eui = ubinascii.unhexlify('70B3D57ED0028A4F') app_key = ubinascii.unhexlify('88397B010F71D34BEDF77DA003C3A54C') elif name == NO_RING: dev_eui = ubinascii.unhexlify( '70B3D54990435DFE') # these settings can be found from TTN app_eui = ubinascii.unhexlify('70B3D57ED0028A4F') app_key = ubinascii.unhexlify('CE46C01958A612D102F0D106AB415862') else: dev_eui = ubinascii.unhexlify( '70B3D54990435DFE') # these settings can be found from TTN app_eui = ubinascii.unhexlify('70B3D57ED0028A4F') app_key = ubinascii.unhexlify('CE46C01958A612D102F0D106AB415862') if not lora.has_joined(): lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) pycom.rgbled(green) time.sleep(2.5) handshk_time = Timer.Chrono() handshk_time.start() # wait until the module has joined the network while not lora.has_joined(): pycom.rgbled(off) time.sleep(0.1) pycom.rgbled(red) time.sleep(2.4) print('Not yet joined...') lora.nvram_save() handshk_time.stop() print("Total handshake time: {0}".format(handshk_time.read())) print('Joined!') pycom.rgbled(blue) # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) #set to confirmed type of messages # set the LoRaWAN data rate s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3) # make the socket blocking # (waits for the data to be sent and for the 2 receive windows to expire) s.setblocking(True) # send some data s.send(make_payload()) # make the socket non-blocking s.setblocking(False) # get any data received (if any...) data = s.recvfrom(128) print("received message: {0}".format(data)) return
class Node: def __init__(self, data_rate, py): self.lora = None # Instancia de Lora (sin inicializar) self.s = None # Instancia Socket (sin inicializar) self.dr = data_rate # Data Rate (defecto 5) self.py = py # Instancia de Pysense self.acc = LIS2HH12(self.py) # Instancia del Acelerometro self.last = [0, 0, 0] # Último valor leído de aceleracion self.raw = [0, 0, 0] # Valor leído actual de aceleracion self.busy = 0 # Value has passed limit self.interval = 10 # Intervalo de toma de datos self.battery = None # Valor de la tensión de batería self.s_lock = _thread.allocate_lock() # Semaforo para envío #------------------------------------------------------------------------------# def connect(self, dev_eui, app_eui, app_key): """ Connect device to LoRa. Set the socket and lora instances. """ # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode=LoRa.LORAWAN, device_class=LoRa.CLASS_A) # Set the 3 default channels to the same frequency (must be before # sending the OTAA join request) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # Join a network using OTAA (Over the Air Activation) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=5) #login for TheThingsNetwork see here: #https://www.thethingsnetwork.org/forum/t/lopy-otaa-example/4471 # Wait until the module has joined the network while not self.lora.has_joined(): print("Trying to join LoraWAN with OTAA") time.sleep(2.5) print("LoraWAN joined! ") #Handler de Recepción #self.lora.callback(trigger=(LoRa.RX_PACKET_EVENT),handler=self.lora_cb) # save the LoRaWAN connection state self.lora.nvram_save() #------------------------------------------------------------------------------# def send(self, data): """ Send data over the network. """ self.s_lock.acquire( ) # Espera a que el semáforo esté disponible (tiempo indefinido) if py.get_wake_reason( ) == WAKE_REASON_ACCELEROMETER: #Si despierta tras deepsleep # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode=LoRa.LORAWAN, adr=True, device_class=LoRa.CLASS_A) # restore the LoRaWAN connection state try: self.lora.nvram_restore() except OSError: print("Error: LoRa Configuration could not be restored") self.connect( binascii.unhexlify('006A76B0778AEDA7'), binascii.unhexlify('70B3D57ED0009ABB'), binascii.unhexlify('08D62712D816F1C28B7E6EA39E711209')) print("LoRa Connection Parameters Recovered") for i in range(3, 16): self.lora.remove_channel(i) # Set the 3 default channels to the same frequency # (must be before sending the OTAA join request) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # Create a LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) print("Created LoRaWAN socket") # Make the socket non-blocking self.s.setblocking(True) try: self.s.send(data) self.s.setblocking(False) #Espera para posible recepción rx = bytes(self.s.recv(128)) #Recepción de datos self.receive(rx=rx) self.lora.nvram_save() except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno) self.s_lock.release() #Libera el semáforo _thread.exit() #Cierra el hilo #------------------------------------------------------------------------------# #Función de recpeción de datos.Es activada tras la ventana de recepción #posterior al envío. def receive(self, rx=None): if len(rx) == 0: #No hay mensaje de recepción pass else: if rx[0] == 82: #Orden de Cambio Data Rate (ASCII hex R=0x52 dec 87) print("Cambiando Data Rate %d" % (int.from_bytes(rx[1:], 'big'))) self.dr = int.from_bytes( rx[1:], 'big') #Decodifica el valor del nuevo data Rate pycom.nvs_set('data_rate', self.data_rate) #Lo guarda en NVRAM else: pass #------------------------------------------------------------------------------# #Función de lectura de medidas. Los sensores ya han sido inicializados al #crear la instancia de la clase Node def readsens(self): self.raw = self.acc.acceleration( ) # Devuelve tuple con aceleracion en tres ejes (G) print("Aceleracion-> X:%fG Y:%fG Z:%fG" % (self.raw[0], self.raw[1], self.raw[2])) #Cálculos #if (self.raw[0] > 2.1) or (self.raw[1] > 2.1) or (self.raw[2] > 2.1): # print("Enviando datos") # XR=int(self.raw[0]*10000).to_bytes(2,'little') # YR=int(self.raw[1]*10000).to_bytes(2,'little') # ZR=int(self.raw[2]*10000).to_bytes(2,'little') # XL=int(self.last[0]*10000).to_bytes(2,'little') # YL=int(self.last[1]*10000).to_bytes(2,'little') # ZL=int(self.last[2]*10000).to_bytes(2,'little') # data = XR+YR+ZR+XL+YL+ZL # _thread.start_new_thread(self.send,data) # Se crea un hilo para el envío de valores self._compare_update() alarmaPub = Timer.Alarm(self.readsens(), 10, periodic=False) #if (self.raw[0] < 1.5) and (self.raw[1] < 1.5) and (self.raw[2] < 1.5): # alarmaPub.cancel(); # n.py.setup_int_wake_up(rising=True,falling=False) #Activa la interrupcion para el boton DEBUG # print('Activada Interrupccion de Actividad') # n.acc.enable_activity_interrupt(1500,100) #Threshold= 1,5G, Min Time = 100ms # print("Going to Sleep") # n.py.setup_sleep(300) # n.py.go_to_sleep() #self.battery = round(self.py.read_battery_voltage(),2) #print("Battery: %f",%(self.battery)) #if (self.battery < 3.4): # print("Batería Crítica") # _thread.start_new_thread(self.send,("Batería"," Crítica")) # Se crea un hilo para el envío de alarma de batería #------------------------------------------------------------------------------# def _compare_update(self): if self.raw is not self.last: self.last = self.raw else: pass
class Comunication: def __init__(self): self.key = b'encriptaincendis' pass # Initialize LoRa in LORAWAN mode. def JoinLoraWan(self): self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) # create an OTA authentication params app_eui = ubinascii.unhexlify('70B3D57ED001C55E') dev_eui = ubinascii.unhexlify( '006D2D7767E7BAFE') # these settings can be found from TTN #app_eui = ubinascii.unhexlify('70B3D57ED0019255') # these settings can be found from TTN app_key = ubinascii.unhexlify('0A05862CEA15FC56C047FC03FBDF34DB' ) # these settings can be found from TTN # set the 3 default channels to the same frequency (must be before sending the OTAA join request) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # join a network using OTAA self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # wait until the module has joined the network while not self.lora.has_joined(): time.sleep(5) print('Not joined yet...') # remove all the non-default channels for i in range(3, 16): self.lora.remove_channel(i) # create a LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) # make the socket non-blocking self.s.setblocking(False) time.sleep(5) """ Your own code can be written below! """ def start_LoraRaw(self): self.lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setblocking(False) #Aquesta instrucció igual sobra #time.sleep(5) lora = self.lora #return(lora) def savestate(self): self.lora.nvram_save() # def restorestate(self): # self.lora.nvram_restore() def Switch_to_LoraRaw(self): self.lora.nvram_save() self.lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setblocking(False) #Aquesta instrucció igual sobra time.sleep(5) def Switch_to_LoraWan(self): self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) self.lora.nvram_restore() time.sleep(5) #Si no es reinicia el socket el missatge 3 no s'envia self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) def EnviarGateway(self, data): self.s.send(data) time.sleep(5) def RebreGateway(self): data, port = self.s.recvfrom(256) print(data) def sendData(self, misg): self.s.setblocking(True) iv = crypto.getrandbits( 128) # hardware generated random IV (never reuse it) cipher = AES(self.key, AES.MODE_CFB, iv) msg = iv + cipher.encrypt(misg) self.s.send(msg) self.s.setblocking(False) #print(msg) #print(len(msg)) time.sleep(5) def reciveData(self): self.s.setblocking(False) msg = self.s.recv(128) #Get any data recieved #If there's any data, decrypt if len(msg) > 0: print("encriptat: ", msg) cipher = AES(self.key, AES.MODE_CFB, msg[:16]) # on the decryption side original = cipher.decrypt(msg[16:]) print("original ", original) return (original) else: return
class PybytesConnection: def __init__(self, config, message_callback): if config is not None: self.__conf = config try: self.__host = pycom.nvs_get('pybytes_server') except: self.__host = config.get('server') self.__ssl = config.get('ssl', False) self.__ssl_params = config.get('ssl_params', {}) self.__user_name = config.get('username') self.__device_id = config.get('device_id') self.__mqtt_download_topic = "d" + self.__device_id self.__mqtt_upload_topic = "u" + self.__device_id self.__pybytes_protocol = PybytesProtocol( config, message_callback, pybytes_connection=self ) self.__connection = None self.__connection_status = constants.__CONNECTION_STATUS_DISCONNECTED self.__lora_socket = None self.lora = None self.lora_lock = _thread.allocate_lock() self.__sigfox_socket = None self.lte = None self.wlan = None self.__network_type = None self.__wifi_lte_watchdog = None def lte_ping_routine(self, delay): while True: self.send_ping_message() time.sleep(delay) def print_pretty_response(self, rsp): lines = rsp.split('\r\n') for line in lines: if line: if line not in ['OK']: print(line) def __initialise_watchdog(self): if self.__conf.get('connection_watchdog', True): self.__wifi_lte_watchdog = WDT( timeout=constants.__WDT_TIMEOUT_MILLISECONDS ) print('Initialized watchdog for WiFi and LTE connection with timeout {} ms'.format(constants.__WDT_TIMEOUT_MILLISECONDS)) # noqa else: print('Watchdog for WiFi and LTE was disabled, enable with "connection_watchdog": true in pybytes_config.json') # noqa # Establish a connection through WIFI before connecting to mqtt server def connect_wifi(self, reconnect=True, check_interval=0.5, timeout=120): self.__initialise_watchdog() if self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED: # noqa print("Error connect_wifi: Connection already exists. Disconnect First") # noqa return False try: from network import WLAN antenna = self.__conf.get('wlan_antenna', WLAN.INT_ANT) known_nets = [((self.__conf['wifi']['ssid'], self.__conf['wifi']['password']))] # noqa if antenna == WLAN.EXT_ANT: print("WARNING! Using external WiFi antenna.") '''to connect it to an existing network, the WiFi class must be configured as a station''' self.wlan = WLAN(mode=WLAN.STA, antenna=antenna) attempt = 0 print_debug(3, 'WLAN connected? {}'.format(self.wlan.isconnected())) while not self.wlan.isconnected() and attempt < 3: attempt += 1 print_debug(3, "Wifi connection attempt: {}".format(attempt)) print_debug(3, 'WLAN connected? {}'.format(self.wlan.isconnected())) available_nets = None while available_nets is None: try: available_nets = self.wlan.scan() for x in available_nets: print_debug(5, x) time.sleep(1) except: pass nets = frozenset([e.ssid for e in available_nets]) known_nets_names = frozenset([e[0]for e in known_nets]) net_to_use = list(nets & known_nets_names) try: net_to_use = net_to_use[0] pwd = dict(known_nets)[net_to_use] sec = [e.sec for e in available_nets if e.ssid == net_to_use][0] # noqa print_debug(99, "Connecting with {} and {}".format(net_to_use, pwd)) if sec == 0: self.wlan.connect(net_to_use, timeout=10000) else: self.wlan.connect(net_to_use, (sec, pwd), timeout=10000) start_time = time.time() while not self.wlan.isconnected(): if time.time() - start_time > timeout: raise TimeoutError('Timeout trying to connect via WiFi') time.sleep(0.1) except Exception as e: if str(e) == "list index out of range" and attempt == 3: print("Please review Wifi SSID and password inside config") self.wlan.deinit() return False elif attempt == 3: print("Error connecting using WIFI: %s" % e) return False self.__network_type = constants.__NETWORK_TYPE_WIFI print("WiFi connection established") try: self.__connection = MQTTClient( self.__device_id, self.__host, self.__mqtt_download_topic, self.__pybytes_protocol, user=self.__user_name, password=self.__device_id ) self.__connection.connect() self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_MQTT_WIFI # noqa self.__pybytes_protocol.start_MQTT( self, constants.__NETWORK_TYPE_WIFI ) return True except Exception as ex: if '{}'.format(ex) == '4': print('MQTT ERROR! Bad credentials when connecting to server: "{}"'.format(self.__host)) # noqa else: print("MQTT ERROR! {}".format(ex)) return False except Exception as ex: print("Exception connect_wifi: {}".format(ex)) return False # Establish a connection through LTE before connecting to mqtt server def connect_lte(self, activation_info=False, start_mqtt=True): if activation_info: lte_cfg = activation_info else: lte_cfg = self.__conf.get('lte') self.__initialise_watchdog() if lte_cfg is not None: if (os.uname()[0] not in ['FiPy', 'GPy']): print("You need a device with FiPy or GPy firmware to connect via LTE") # noqa return False try: from network import LTE time.sleep(3) if lte_cfg.get('carrier', 'standard') == 'standard': carrier = None else: carrier = lte_cfg.get('carrier') print_debug(1, 'LTE init(carrier={}, cid={})'.format(carrier, lte_cfg.get('cid', 1))) # noqa # instantiate the LTE object self.lte = LTE(carrier=carrier, cid=lte_cfg.get('cid', 1)) try: lte_type = lte_cfg.get('type') if len(lte_cfg.get('type')) > 0 else None except: lte_type = None try: lte_apn = lte_cfg.get('apn') if len(lte_cfg.get('type')) > 0 else None except: lte_apn = None try: lte_band = int(lte_cfg.get('band')) except: lte_band = None print_debug( 1, 'LTE attach(band={}, apn={}, type={})'.format( lte_band, lte_apn, lte_type ) ) self.lte.attach(band=lte_band, apn=lte_apn, type=lte_type) # noqa # attach the cellular modem to a base station while not self.lte.isattached(): time.sleep(0.25) time.sleep(1) print_debug(1, 'LTE connect()') # start a data session and obtain an IP address self.lte.connect() print_debug(1, 'LTE is_connected()') while not self.lte.isconnected(): time.sleep(0.25) print("LTE connection established") self.__network_type = constants.__NETWORK_TYPE_LTE if start_mqtt: try: self.__connection = MQTTClient( self.__device_id, self.__host, self.__mqtt_download_topic, self.__pybytes_protocol, user=self.__user_name, password=self.__device_id ) self.__connection.connect() self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_MQTT_LTE # noqa self.__pybytes_protocol.start_MQTT( self, constants.__NETWORK_TYPE_LTE ) print("Connected to MQTT {}".format(self.__host)) return True except Exception as ex: if '{}'.format(ex) == '4': print('MQTT ERROR! Bad credentials when connecting to server: "{}"'.format(self.__host)) # noqa else: print("MQTT ERROR! {}".format(ex)) return False except Exception as ex: print("Exception connect_lte: {}".format(ex)) sys.print_exception(ex) return False else: print("Error... missing configuration!") return False # LORA def connect_lora_abp(self, lora_timeout, nanogateway): print_debug(1,'Attempting to connect via LoRa') if (self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED): # noqa print("Error connect_lora_abp: Connection already exists. Disconnect First") # noqa return False try: from network import LoRa except Exception as ex: print("This device does not support LoRa connections: %s" % ex) return False lora_class = self.__conf.get('lora', {}).get('class', 0) if self.__conf.get('lora', {}).get('region') is not None: self.lora = LoRa(mode=LoRa.LORAWAN, region=self.__conf.get('lora').get('region'), device_class=lora_class) else: self.lora = LoRa(mode=LoRa.LORAWAN, device_class=lora_class) self.lora.nvram_restore() try: dev_addr = self.__conf['lora']['abp']['dev_addr'] nwk_swkey = self.__conf['lora']['abp']['nwk_skey'] app_swkey = self.__conf['lora']['abp']['app_skey'] except Exception as ex: print("Invalid LoRaWAN ABP configuration!") print_debug(1, ex) return False timeout_ms = self.__conf.get('lora_timeout', lora_timeout) * 1000 dev_addr = struct.unpack(">l", binascii.unhexlify(dev_addr.replace(' ', '')))[0] # noqa nwk_swkey = binascii.unhexlify(nwk_swkey.replace(' ', '')) app_swkey = binascii.unhexlify(app_swkey.replace(' ', '')) try: print("Trying to join LoRa.ABP for %d seconds..." % self.__conf.get('lora_timeout', lora_timeout)) self.lora.join( activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey), timeout=timeout_ms ) # if you want, uncomment this code, but timeout must be 0 # while not self.lora.has_joined(): # print("Joining...") # time.sleep(5) self.__open_lora_socket(nanogateway) # print_debug(5, 'Stack size: {}'.format(self.__thread_stack_size)) # _thread.stack_size(self.__thread_stack_size) # _thread.start_new_thread(self.__check_lora_messages, ()) return True except Exception as e: message = str(e) if message == 'timed out': print("LoRa connection timeout: %d seconds" % self.__conf.get('lora_timeout', lora_timeout)) else: print_debug(3, 'Exception in LoRa connect: {}'.format(e)) return False def connect_lora_otaa(self, lora_timeout, nanogateway): print_debug(1,'Attempting to connect via LoRa') if (self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED): # noqa print("Error connect_lora_otaa: Connection already exists. Disconnect First") # noqa return False try: from network import LoRa except Exception as ex: print("This device does not support LoRa connections: %s" % ex) return False try: dev_eui = self.__conf['lora']['otaa']['app_device_eui'] app_eui = self.__conf['lora']['otaa']['app_eui'] app_key = self.__conf['lora']['otaa']['app_key'] except Exception as ex: print("Invalid LoRaWAN OTAA configuration!") print_debug(1, ex) return False timeout_ms = self.__conf.get('lora_timeout', lora_timeout) * 1000 lora_class = self.__conf.get('lora', {}).get('class', 0) if self.__conf.get('lora', {}).get('region') is not None: self.lora = LoRa(mode=LoRa.LORAWAN, region=self.__conf.get('lora', {}).get('region'), device_class=lora_class) else: self.lora = LoRa(mode=LoRa.LORAWAN, device_class=lora_class) self.lora.nvram_restore() dev_eui = binascii.unhexlify(dev_eui.replace(' ', '')) app_eui = binascii.unhexlify(app_eui.replace(' ', '')) app_key = binascii.unhexlify(app_key.replace(' ', '')) try: if not self.lora.has_joined(): print("Trying to join LoRa.OTAA for %d seconds..." % self.__conf.get('lora_timeout', lora_timeout)) self.lora.join( activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=timeout_ms ) # if you want, uncomment this code, but timeout must be 0 # while not self.lora.has_joined(): # print("Joining...") # time.sleep(5) self.__open_lora_socket(nanogateway) # print_debug(5, 'Stack size: {}'.format(self.__thread_stack_size)) # _thread.stack_size(self.__thread_stack_size) # _thread.start_new_thread(self.__check_lora_messages, ()) return True except Exception as e: message = str(e) if message == 'timed out': print("LoRa connection timeout: %d seconds" % self.__conf.get('lora_timeout', lora_timeout)) else: print_debug(3, 'Exception in LoRa connect: {}'.format(e)) return False def __open_lora_socket(self, nanogateway): if (nanogateway): for i in range(3, 16): self.lora.remove_channel(i) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) print("Setting up LoRa socket...") self.__lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.__lora_socket.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_LORA self.__pybytes_protocol.start_Lora(self) print("Connected using LoRa") # SIGFOX def connect_sigfox(self): if (self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED): # noqa print("Error: Connection already exists. Disconnect First") pass try: from network import Sigfox except Exception: print("This device does not support Sigfox connections") return sigfox_config = self.__conf.get('sigfox', {}) if sigfox_config is None or sigfox_config.get('RCZ') is None: print(constants.__SIGFOX_WARNING) try: sf_rcz = int(sigfox_config.get('RCZ', 1)) - 1 if sf_rcz >= 0 and sf_rcz <= 3: Sigfox(mode=Sigfox.SIGFOX, rcz=sf_rcz) self.__sigfox_socket = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW) # noqa self.__sigfox_socket.setblocking(True) self.__sigfox_socket.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False) # noqa self.__network_type = constants.__NETWORK_TYPE_SIGFOX self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_SIGFOX # noqa self.__pybytes_protocol.start_Sigfox(self) print( "Connected using Sigfox. Only upload stream is supported" ) return True else: print('Invalid Sigfox RCZ specified in config!') return False except Exception as e: print('Exception in connect_sigfox: {}'.format(e)) return False # COMMON def disconnect(self, keep_wifi=False, force=False): if self.__wifi_lte_watchdog is not None: self.__wifi_lte_watchdog = WDT(timeout=constants.__WDT_MAX_TIMEOUT_MILLISECONDS) print('Watchdog timeout has been increased to {} ms'.format(constants.__WDT_MAX_TIMEOUT_MILLISECONDS)) # noqa print_debug( 1, 'self.__connection_status={} | self.__network_type={}'.format( self.__connection_status, self.__network_type ) ) if (self.__connection_status == constants.__CONNECTION_STATUS_DISCONNECTED): # noqa print_debug(3, "Already disconnected") if (constants.__CONNECTION_STATUS_CONNECTED_MQTT_WIFI <= self.__connection_status <= constants.__CONNECTION_STATUS_CONNECTED_MQTT_LTE): # noqa print_debug(1, 'MQTT over WIFI||LTE... disconnecting MQTT') try: self.__connection.disconnect(force=force) self.__connection_status = constants.__CONNECTION_STATUS_DISCONNECTED # noqa except Exception as e: print("Error disconnecting: {}".format(e)) if (self.__connection_status == constants.__CONNECTION_STATUS_CONNECTED_LORA): # noqa print_debug(1, 'Connected over LORA... closing socket and saving nvram') # noqa try: self.__lora_socket.close() self.lora.nvram_save() except Exception as e: print("Error disconnecting: {}".format(e)) if (self.__connection_status == constants.__CONNECTION_STATUS_CONNECTED_SIGFOX): # noqa print_debug(1, 'Connected over SIGFOX... closing socket') try: self.__sigfox_socket.close() except Exception as e: print("Error disconnecting: {}".format(e)) if (self.__network_type == constants.__NETWORK_TYPE_WIFI and not keep_wifi): print_debug(1, 'Connected over WIFI... disconnecting') try: self.wlan.deinit() except Exception as e: print("Error disconnecting: {}".format(e)) if (self.__network_type == constants.__NETWORK_TYPE_LTE): print_debug(1, 'Connected over LTE... disconnecting') try: lte_cfg = self.__conf.get('lte') print_debug(1, 'lte.deinit(reset={})'.format(lte_cfg.get('reset', False))) # noqa self.lte.deinit(reset=lte_cfg.get('reset', False)) except Exception as e: print("Error disconnecting: {}".format(e)) self.__network_type = None self.__connection_status = constants.__CONNECTION_STATUS_DISCONNECTED def is_connected(self): return not (self.__connection_status == constants.__CONNECTION_STATUS_DISCONNECTED) # noqa # Added for convention with other connectivity classes def isconnected(self): return not (self.__connection_status == constants.__CONNECTION_STATUS_DISCONNECTED) # noqa
class Node: def __init__(self,sleep_time,data_rate,pysense): self.lora = None # Instancia de Lora (sin inicializar) self.s = None # Instancia Socket (sin inicializar) self.sleep_time = sleep_time # Intervalo de inactividad self.dr = data_rate # Data Rate (defecto 5) self.py = pysense # Instancia de Pysense self.lt = LTR329ALS01(self.py) # Instancia Sensor de Luminosidad self.mp = MPL3115A2(self.py,mode=PRESSURE) # Instancia Sensor de Presión self.si = SI7006A20(self.py) # Instancia Sensor de Humedad y tempertura #------------------------------------------------------------------------------# def connect(self,dev_eui,app_eui, app_key): """ Connect device to LoRa. Set the socket and lora instances. """ # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode = LoRa.LORAWAN,device_class=LoRa.CLASS_A,region=LoRa.EU868) # Set the 3 default channels to the same frequency (must be before # sending the OTAA join request) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # Join a network using OTAA (Over the Air Activation) self.lora.join(activation = LoRa.OTAA, auth = (dev_eui,app_eui, app_key), timeout = 0, dr=self.dr) #login for TheThingsNetwork see here: #https://www.thethingsnetwork.org/forum/t/lopy-otaa-example/4471 # Wait until the module has joined the network while not self.lora.has_joined(): print("Trying to join LoraWAN with OTAA") time.sleep(2.5) print ("LoraWAN joined! ") # save the LoRaWAN connection state self.lora.nvram_save() #------------------------------------------------------------------------------# def send(self,data): """ Send data over the network. """ if py.get_wake_reason() == WAKE_REASON_TIMER: #Si despierta tras deepsleep # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode = LoRa.LORAWAN,adr=True,device_class=LoRa.CLASS_A,region=LoRa.EU868) # restore the LoRaWAN connection state try: self.lora.nvram_restore() except OSError: print("Error: LoRa Configuration could not be restored") self.connect(dev_eui,app_eui,app_key) print("LoRa Connection Parameters Recovered") # remove all the non-default channels for i in range(3, 16): self.lora.remove_channel(i) # Set the 3 default channels to the same frequency # (must be before sending the OTAA join request) self.lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # Create a LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) print("Created LoRaWAN socket") # Make the socket blocking self.s.setblocking(True) #Necesario para gurdar el contador de mensajes try: self.s.send(data) #Envio de datos self.s.setblocking(False) # make the socket non-blocking (necesario para no dejar colgado el dispositivo) rx = bytes(self.s.recv(128)) # (because if there's no data received it will block forever...) self.receive(rx=rx) self.lora.nvram_save() print('Lora Config Saved!') except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno) pass #------------------------------------------------------------------------------# #Función de recepción de datos.Es activada tras la ventana de recepción #posterior al envío. def receive(self,rx=None): if len(rx) == 0: #No hay mensaje de recepción print('No incoming message') pass else: if rx[0] == 73: #Orden de Cambio de intervalo (ASCII hex I=0x49 dec 73) print("Recibido cambio de intervalo %d" %(int.from_bytes(rx[1:],'big'))) self.sleep_time = int.from_bytes(rx[1:],'big') #Decodifica el valor del nuevo intervalo pycom.nvs_set('sleep_time',self.sleep_time) #Lo guarda en NVRAM elif rx[0] == 82: #Orden de Cambio Data Rate (ASCII hex R=0x52 dec 87) print("Cambiando Data Rate %d" %(int.from_bytes(rx[1:],'big'))) self.dr = int.from_bytes(rx[1:],'big') #Decodifica el valor del nuevo data Rate pycom.nvs_set('data_rate',self.data_rate) #Lo guarda en NVRAM elif rx[0] == 79: #4Fh ota = WiFiOTA('MBP_JuanMa','MBP_JuanMa',"54.154.225.138",8000) #Amazon Web Services Server print("Updating via OTA...") print('- ' * 20) ota.connect() ota.update() else: pass #------------------------------------------------------------------------------# #Función de lectura de medidas. Los sensores ya han sido inicializados al #crear la instancia de la clase Node def readsens(self): pressure = (int(self.mp.pressure())-90000).to_bytes(2,'little') #Segundo Elemento Lista: Presión (entero) humidity = int(round(self.si.humidity(),2)*100).to_bytes(2,'little') #Tercer Elemento Lista: Humedad (dos decimales) temperature = int(round(self.si.temperature(),2)*100).to_bytes(2,'little') #Cuarto Elemento Lista: Temperatura (dos decimales) battery = int(round(self.py.read_battery_voltage(),4)*10000-33000).to_bytes(2,'little') #Quinto Elemento Lista: Voltaje (cuatro decimales) light = int(self.lt.light()[0]).to_bytes(2,'little') #Primer Elemento Lista: Luminosidad (entero) reading = light+pressure+humidity+temperature+battery #Union de tipos bytes return reading
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 LoraNet: def __init__(self, frequency, dr, region, device_class=LoRa.CLASS_C, activation=LoRa.OTAA, auth=None): self.frequency = frequency self.dr = dr self.region = region self.device_class = device_class self.activation = activation self.auth = auth self.sock = None self._exit = False self.s_lock = _thread.allocate_lock() self.lora = LoRa(mode=LoRa.LORAWAN, region=self.region, device_class=self.device_class) self._msg_queue = [] self.q_lock = _thread.allocate_lock() self._process_ota_msg = None def stop(self): self._exit = True def init(self, process_msg_callback): self._process_ota_msg = process_msg_callback def receive_callback(self, lora): events = lora.events() if events & LoRa.RX_PACKET_EVENT: rx, port = self.sock.recvfrom(256) if rx: if '$OTA' in rx: print("OTA msg received: {}".format(rx)) self._process_ota_msg(rx.decode()) else: self.q_lock.acquire() self._msg_queue.append(rx) self.q_lock.release() def connect(self): if self.activation != LoRa.OTAA and self.activation != LoRa.ABP: raise ValueError("Invalid Lora activation method") if len(self.auth) < 3: raise ValueError("Invalid authentication parameters") self.lora.callback(trigger=LoRa.RX_PACKET_EVENT, handler=self.receive_callback) # set the 3 default channels to the same frequency self.lora.add_channel(0, frequency=self.frequency, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=self.frequency, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=self.frequency, dr_min=0, dr_max=5) # remove all the non-default channels for i in range(3, 16): self.lora.remove_channel(i) # authenticate with abp or ota if self.activation == LoRa.OTAA: self._authenticate_otaa(self.auth) else: self._authenticate_abp(self.auth) # create socket to server self._create_socket() def _authenticate_otaa(self, auth_params): # create an OTAA authentication params self.dev_eui = binascii.unhexlify(auth_params[0]) self.app_eui = binascii.unhexlify(auth_params[1]) self.app_key = binascii.unhexlify(auth_params[2]) self.lora.join(activation=LoRa.OTAA, auth=(self.dev_eui, self.app_eui, self.app_key), timeout=0, dr=self.dr) while not self.lora.has_joined(): time.sleep(2.5) print('Not joined yet...') def has_joined(self): return self.lora.has_joined() def _authenticate_abp(self, auth_params): # create an ABP authentication params self.dev_addr = struct.unpack(">l", binascii.unhexlify(auth_params[0]))[0] self.nwk_swkey = binascii.unhexlify(auth_params[1]) self.app_swkey = binascii.unhexlify(auth_params[2]) self.lora.join(activation=LoRa.ABP, auth=(self.dev_addr, self.nwk_swkey, self.app_swkey)) def _create_socket(self): # create a LoRa socket self.sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate self.sock.setsockopt(socket.SOL_LORA, socket.SO_DR, self.dr) # make the socket non blocking self.sock.setblocking(False) time.sleep(2) def send(self, packet): with self.s_lock: self.sock.send(packet) def receive(self, bufsize): with self.q_lock: if len(self._msg_queue) > 0: return self._msg_queue.pop(0) return '' def get_dev_eui(self): return binascii.hexlify(self.lora.mac()).decode('ascii') def change_to_multicast_mode(self, mcAuth): print('Start listening for firmware updates ...........') if self.device_class != LoRa.CLASS_C: self.lora = LoRa(mode=LoRa.LORAWAN, region=self.region, device_class=LoRa.CLASS_C) self.connect() mcAddr = struct.unpack(">l", binascii.unhexlify(mcAuth[0]))[0] mcNwkKey = binascii.unhexlify(mcAuth[1]) mcAppKey = binascii.unhexlify(mcAuth[2]) self.lora.join_multicast_group(mcAddr, mcNwkKey, mcAppKey)
import struct import ujson # Colors off = 0x000000 red = 0xff0000 green = 0x00ff00 blue = 0x0000ff yellow = 0xffff00 # Initialize LoRa in LORAWAN mode. lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AU915, public=True) # Set up KotahiNet channels # leave channels 8-15 and 65 for index in range(0, 8): lora.remove_channel(index) # remove 0-7 for index in range(16, 65): lora.remove_channel(index) # remove 16-64 for index in range(66, 72): lora.remove_channel(index) # remove 66-71 # Turn off hearbeat LED pycom.heartbeat(False) # create an ABP authentication params dev_addr = struct.unpack(">l", binascii.unhexlify('26 00 2C 58'.replace(' ', '')))[0] nwk_swkey = binascii.unhexlify( '37 70 5E 6D F5 04 8F 2F 42 87 E5 3F 09 78 A9 11'.replace(' ', '')) app_swkey = binascii.unhexlify( 'A1 13 D6 0F 1A 9C 08 9F E6 94 D6 83 76 9F 8B DE'.replace(' ', ''))
class LoRaMQ: def __init__(self, config): self.lora = LoRa(mode=LoRa.LORAWAN) # set the 3 default channels to the same frequency (must be before sending the OTAA join request) self.lora.add_channel(0, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) self.lora.add_channel(1, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) self.lora.add_channel(2, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5) # join a network using OTAA self.lora.join(activation=LoRa.OTAA, auth=(binascii.unhexlify(config.DEV_EUI), binascii.unhexlify(config.APP_EUI), binascii.unhexlify(config.APP_KEY)), timeout=0, dr=config.LORA_NODE_DR) # wait until the module has joined the network while not self.lora.has_joined(): time.sleep(2.5) print('Not joined yet...') # remove all the non-default channels for i in range(3, 16): self.lora.remove_channel(i) # create a LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, config.LORA_NODE_DR) # make the socket non-blocking self.s.setblocking(False) time.sleep(5.0) self.send_mutex = _thread.allocate_lock() self.send_queue = [] self.recv_mutex = _thread.allocate_lock() self.recv_queue = [] self.callback = None self.lora.callback(LoRa.RX_PACKET_EVENT, self._recv) def _recv(self, data): rx, port = s.recvfrom(256) self.recv_mutex.acquire() self.recv_queue.append((port, rx)) self.recv_mutex.release() if self.callback: _thread.start_new_thread(self.callback, tuple()) def send(self, data): self.send_mutex.acquire() self.send_queue.append(data) self.send_mutex.release() def receive(self): self.recv_mutex.acquire() if not len(self.recv_queue): return False data = self.recv_queue.pop(0) self.recv_mutex.release() return data def rq_length(self): self.recv_mutex.acquire() size = len(self.recv_queue) self.recv_mutex.release() return size def attach_callback(self, callback): self.callback = callback def _loop(self): while True: #acquire a lock on the send message queue self.send_mutex.acquire() #get the message from the front of the queue if len(self.send_queue): data = self.send_queue.pop(0) else: data = None self.send_mutex.release() if data: #acquire a lock on the channel self.recv_mutex.acquire() #send the data self.s.send(data) #release the channel lock self.recv_mutex.release() #LoRa protocol only allows sending and recieving every 5 seconds #so to avoid protocol errors from the transciever sleep the thread #for 5 seconds time.sleep(5) def start(self): _thread.start_new_thread(self._loop, tuple())
import binascii import struct import time import config # initialize LoRa in LORAWAN mode. lora = LoRa(mode=LoRa.LORAWAN) # create an OTA authentication params dev_eui = binascii.unhexlify('AA BB CC DD EE FF 77 78'.replace(' ','')) app_eui = binascii.unhexlify('70 B3 D5 7E F0 00 3B FD'.replace(' ','')) app_key = binascii.unhexlify('36 AB 76 25 FE 77 0B 68 81 68 3B 49 53 00 FF D6'.replace(' ','')) # 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 OTAA lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=config.LORA_NODE_DR) # wait until the module has joined the network join_wait = 0 while True: time.sleep(2.5) if not lora.has_joined(): print('Not joined yet...') join_wait += 1
class NanoGateway: """ Nano gateway class, set up by default for use with TTN, but can be configured for any other network supporting the Semtech Packet Forwarder. Only required configuration is wifi_ssid and wifi_password which are used for connecting to the Internet. """ def __init__(self, id, frequency, datarate, ssid, password, server, port, ntp_server='pool.ntp.org', ntp_period=3600): self.id = id self.server = server self.port = port self.frequency = frequency self.datarate = datarate self.ssid = ssid self.password = password self.ntp_server = ntp_server self.ntp_period = ntp_period self.server_ip = None self.rxnb = 0 self.rxok = 0 self.rxfw = 0 self.dwnb = 0 self.txnb = 0 self.sf = self._dr_to_sf(self.datarate) self.bw = self._dr_to_bw(self.datarate) self.stat_alarm = None self.pull_alarm = None self.uplink_alarm = None self.wlan = None self.sock = None self.udp_stop = False self.udp_lock = _thread.allocate_lock() self.lora = None self.lora_sock = None self.rtc = machine.RTC() def start(self): """ Starts the LoRaWAN nano gateway. """ self._log('Starting LoRaWAN nano gateway with id: {}', self.id) # setup WiFi as a station and connect self.wlan = WLAN(mode=WLAN.STA) self._connect_to_wifi() # get a time sync self._log('Syncing time with {} ...', self.ntp_server) self.rtc.ntp_sync(self.ntp_server, update_period=self.ntp_period) while not self.rtc.synced(): utime.sleep_ms(50) self._log("RTC NTP sync complete") # get the server IP and create an UDP socket self.server_ip = usocket.getaddrinfo(self.server, self.port)[0][-1] self._log('Opening UDP socket to {} ({}) port {}...', self.server, self.server_ip[0], self.server_ip[1]) self.sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM, usocket.IPPROTO_UDP) self.sock.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1) self.sock.setblocking(False) # push the first time immediatelly self._push_data(self._make_stat_packet()) # create the alarms self.stat_alarm = Timer.Alarm(handler=lambda t: self._push_data(self._make_stat_packet()), s=60, periodic=True) self.pull_alarm = Timer.Alarm(handler=lambda u: self._pull_data(), s=25, periodic=True) # start the UDP receive thread self.udp_stop = False _thread.start_new_thread(self._udp_thread, ()) # initialize the LoRa radio in LORA mode self._log('Setting up the LoRa radio at {} Mhz using {}', self._freq_to_float(self.frequency), self.datarate) self.lora = LoRa( mode=LoRa.LORA, region=LoRa.AU915, frequency=self.frequency, bandwidth=self.bw, sf=self.sf, preamble=8, coding_rate=LoRa.CODING_4_5, tx_iq=True ) # remove all the channels for channel in range(0, 72): self.lora.remove_channel(channel) self.lora.add_channel(8, frequency=self.frequency, dr_min=0, dr_max=3) # create a raw LoRa socket self.lora_sock = usocket.socket(usocket.AF_LORA, usocket.SOCK_RAW) self.lora_sock.setblocking(False) self.lora_tx_done = False self.lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=self._lora_cb) self._log('LoRaWAN nano gateway online') def stop(self): """ Stops the LoRaWAN nano gateway. """ self._log('Stopping...') # send the LoRa radio to sleep self.lora.callback(trigger=None, handler=None) self.lora.power_mode(LoRa.SLEEP) # stop the NTP sync self.rtc.ntp_sync(None) # cancel all the alarms self.stat_alarm.cancel() self.pull_alarm.cancel() # signal the UDP thread to stop self.udp_stop = True while self.udp_stop: utime.sleep_ms(50) # disable WLAN self.wlan.disconnect() self.wlan.deinit() def _connect_to_wifi(self): self.wlan.connect(self.ssid, auth=(None, self.password)) while not self.wlan.isconnected(): utime.sleep_ms(50) self._log('WiFi connected to: {}', self.ssid) def _dr_to_sf(self, dr): sf = dr[2:4] if sf[1] not in '0123456789': sf = sf[:1] return int(sf) def _dr_to_bw(self, dr): bw = dr[-5:] if bw == 'BW125': return LoRa.BW_125KHZ elif bw == 'BW250': return LoRa.BW_250KHZ else: return LoRa.BW_500KHZ def _sf_bw_to_dr(self, sf, bw): dr = 'SF' + str(sf) if bw == LoRa.BW_125KHZ: return dr + 'BW125' elif bw == LoRa.BW_250KHZ: return dr + 'BW250' else: return dr + 'BW500' def _lora_cb(self, lora): """ LoRa radio events callback handler. """ events = lora.events() if events & LoRa.RX_PACKET_EVENT: self.rxnb += 1 self.rxok += 1 rx_data = self.lora_sock.recv(256) stats = lora.stats() packet = self._make_node_packet(rx_data, self.rtc.now(), stats.rx_timestamp, stats.sfrx, self.bw, stats.rssi, stats.snr) self._push_data(packet) self._log('Received packet: {}', packet) self.rxfw += 1 if events & LoRa.TX_PACKET_EVENT: self.txnb += 1 lora.init( mode=LoRa.LORA, frequency=self.frequency, bandwidth=self.bw, sf=self.sf, preamble=8, coding_rate=LoRa.CODING_4_5, tx_iq=True ) def _freq_to_float(self, frequency): """ MicroPython has some inprecision when doing large float division. To counter this, this method first does integer division until we reach the decimal breaking point. This doesn't completely elimate the issue in all cases, but it does help for a number of commonly used frequencies. """ divider = 6 while divider > 0 and frequency % 10 == 0: frequency = frequency // 10 divider -= 1 if divider > 0: frequency = frequency / (10 ** divider) return frequency def _make_stat_packet(self): now = self.rtc.now() STAT_PK["stat"]["time"] = "%d-%02d-%02d %02d:%02d:%02d GMT" % (now[0], now[1], now[2], now[3], now[4], now[5]) STAT_PK["stat"]["rxnb"] = self.rxnb STAT_PK["stat"]["rxok"] = self.rxok STAT_PK["stat"]["rxfw"] = self.rxfw STAT_PK["stat"]["dwnb"] = self.dwnb STAT_PK["stat"]["txnb"] = self.txnb return ujson.dumps(STAT_PK) def _make_node_packet(self, rx_data, rx_time, tmst, sf, bw, rssi, snr): RX_PK["rxpk"][0]["time"] = "%d-%02d-%02dT%02d:%02d:%02d.%dZ" % (rx_time[0], rx_time[1], rx_time[2], rx_time[3], rx_time[4], rx_time[5], rx_time[6]) RX_PK["rxpk"][0]["tmst"] = tmst RX_PK["rxpk"][0]["freq"] = self._freq_to_float(self.frequency) RX_PK["rxpk"][0]["datr"] = self._sf_bw_to_dr(sf, bw) RX_PK["rxpk"][0]["rssi"] = rssi RX_PK["rxpk"][0]["lsnr"] = snr RX_PK["rxpk"][0]["data"] = ubinascii.b2a_base64(rx_data)[:-1] RX_PK["rxpk"][0]["size"] = len(rx_data) return ujson.dumps(RX_PK) def _push_data(self, data): token = uos.urandom(2) packet = bytes([PROTOCOL_VERSION]) + token + bytes([PUSH_DATA]) + ubinascii.unhexlify(self.id) + data with self.udp_lock: try: self.sock.sendto(packet, self.server_ip) except Exception as ex: self._log('Failed to push uplink packet to server: {}', ex) def _pull_data(self): token = uos.urandom(2) packet = bytes([PROTOCOL_VERSION]) + token + bytes([PULL_DATA]) + ubinascii.unhexlify(self.id) with self.udp_lock: try: self.sock.sendto(packet, self.server_ip) except Exception as ex: self._log('Failed to pull downlink packets from server: {}', ex) def _ack_pull_rsp(self, token, error): TX_ACK_PK["txpk_ack"]["error"] = error resp = ujson.dumps(TX_ACK_PK) packet = bytes([PROTOCOL_VERSION]) + token + bytes([PULL_ACK]) + ubinascii.unhexlify(self.id) + resp with self.udp_lock: try: self.sock.sendto(packet, self.server_ip) except Exception as ex: self._log('PULL RSP ACK exception: {}', ex) def _send_down_link(self, data, tmst, datarate, frequency): """ Transmits a downlink message over LoRa. """ self.lora.init( mode=LoRa.LORA, frequency=frequency, bandwidth=self._dr_to_bw(datarate), sf=self._dr_to_sf(datarate), preamble=8, coding_rate=LoRa.CODING_4_5, tx_iq=True ) while utime.ticks_cpu() < tmst: pass self.lora_sock.send(data) self._log( 'Sent downlink packet scheduled on {:.3f}, at {:.3f} Mhz using {}: {}', tmst / 1000000, self._freq_to_float(frequency), datarate, data ) def _udp_thread(self): """ UDP thread, reads data from the server and handles it. """ while not self.udp_stop: try: data, src = self.sock.recvfrom(1024) _token = data[1:3] _type = data[3] if _type == PUSH_ACK: self._log("Push ack") elif _type == PULL_ACK: self._log("Pull ack") elif _type == PULL_RESP: self.dwnb += 1 ack_error = TX_ERR_NONE tx_pk = ujson.loads(data[4:]) tmst = tx_pk["txpk"]["tmst"] t_us = tmst - utime.ticks_cpu() - 15000 if t_us < 0: t_us += 0xFFFFFFFF if t_us < 20000000: self.uplink_alarm = Timer.Alarm( handler=lambda x: self._send_down_link( ubinascii.a2b_base64(tx_pk["txpk"]["data"]), tx_pk["txpk"]["tmst"] - 50, tx_pk["txpk"]["datr"], int(tx_pk["txpk"]["freq"] * 1000) * 1000 ), us=t_us ) else: ack_error = TX_ERR_TOO_LATE self._log('Downlink timestamp error!, t_us: {}', t_us) self._ack_pull_rsp(_token, ack_error) self._log("Pull rsp") except usocket.timeout: pass except OSError as ex: if ex.errno != errno.EAGAIN: self._log('UDP recv OSError Exception: {}', ex) except Exception as ex: self._log('UDP recv Exception: {}', ex) # wait before trying to receive again utime.sleep_ms(UDP_THREAD_CYCLE_MS) # we are to close the socket self.sock.close() self.udp_stop = False self._log('UDP thread stopped') def _log(self, message, *args): """ Outputs a log message to stdout. """ print('[{:>10.3f}] {}'.format( utime.ticks_ms() / 1000, str(message).format(*args) ))
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')
# set the 3 default channels to the same frequency (must be before sending the OTAA join request) lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # join a network using OTAA lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # wait until the module has joined the network while not lora.has_joined(): time.sleep(2.5) print('Not joined yet...') # remove all the non-default channels for i in range(3, 16): lora.remove_channel(i) # 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, 5) # make the socket blocking s.setblocking(False) time.sleep(5.0) for i in range (200): s.send(b'PKT #' + bytes([i])) print('STA node sending packet ...')
# 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('2601147D'))[0] nwk_swkey = binascii.unhexlify('3C74F4F40CAEA021303BC24284FCF3AF') app_swkey = binascii.unhexlify('0FFA7072CC6FF69A102A0F39BEB0880F') # 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
lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # wait until the module has joined the network while not lora.has_joined(): pycom.rgbled(0x140000) time.sleep(2.5) pycom.rgbled(0x000000) time.sleep(1.0) print('Not yet joined...') print('OTAA joined') pycom.rgbled(0x001400) # to have only one channel: for index in range(0, 16): lora.remove_channel(index) lora.add_channel(index=0, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(index=1, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(index=2, frequency=868100000, dr_min=0, dr_max=5) # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate: # DR | SF # 5 | 7 # 4 | 8 # 3 | 9 # 2 | 10 # 1 | 11
import config # Initialize LoRa in LORAWAN mode. lora = LoRa(mode=LoRa.LORAWAN) # create an ABP authentication params dev_addr = struct.unpack(">l", binascii.unhexlify(config.DEV_ADDR.replace(' ','')))[0] nwk_swkey = binascii.unhexlify(config.NWK_SWKEY.replace(' ','')) app_swkey = binascii.unhexlify(config.APP_SWKEY.replace(' ','')) # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # remove all the non-default channels for i in range(3, 16): lora.remove_channel(i) # set the 3 default channels to the same frequency lora.add_channel(0, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(1, frequency=868100000, dr_min=0, dr_max=5) lora.add_channel(2, frequency=868100000, dr_min=0, dr_max=5) # 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, 5) # make the socket blocking s.setblocking(False)
class LoRaWANNode: def __init__(self, app_eui, app_key, frequency=868100000, dr=5): '''setup LoRaWAN for the European 868 MHz region with OTAA''' self.dr = dr self.frequency = frequency self.app_eui = ubinascii.unhexlify(app_eui) self.app_key = ubinascii.unhexlify(app_key) self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) self.socket = None self.setup() @property def has_joined(self): return self.lora.has_joined() def default_channels(self): ''' Remove all non-default channels and set the 3 default channels to the same frequency (must be before ending the OTAA join request) ''' for i in range(3, 16): self.lora.remove_channel(i) self.lora.add_channel(0, frequency=self.frequency, dr_min=0, dr_max=self.dr) self.lora.add_channel(1, frequency=self.frequency, dr_min=0, dr_max=self.dr) self.lora.add_channel(2, frequency=self.frequency, dr_min=0, dr_max=self.dr) def setup(self): '''Try to restore from nvram or join the network with otaa''' self.default_channels() self.lora.nvram_restore() if not self.has_joined: self.join() else: self.open_socket() def join(self, timeout=10): try: timeout = timeout * 1000 self.lora.join(activation=LoRa.OTAA, auth=(self.app_eui, self.app_key), timeout=timeout, dr=self.dr) if self.has_joined: self.lora.nvram_save() self.open_socket() except TimeoutError: pass def open_socket(self, timeout=6): self.socket = usocket.socket(usocket.AF_LORA, usocket.SOCK_RAW) self.socket.setsockopt(usocket.SOL_LORA, usocket.SO_DR, self.dr) self.socket.settimeout(timeout) def reset(self): self.socket.close() self.lora.nvram_erase() self.join() def send(self, data): '''Send out data as bytes''' if self.has_joined: if isinstance(data, (float, str, int)): data = bytes([data]) self.socket.send(data) utime.sleep(2) self.lora.nvram_save()