class Lora(Connection): """Putting sensor data onto the Enabling platform. USING LoRa""" def __init__(self, deviceAddress, applicationKey, networkKey): from network import LoRa import socket import binascii import struct self.deviceAddress = deviceAddress self.applicationKey = applicationKey self.networkKey = networkKey self.lora = LoRa(mode=LoRa.LORAWAN) dev_addr = struct.unpack(">l", binascii.unhexlify(deviceAddress.replace(' ','')))[0] nwk_swkey = binascii.unhexlify(networkKey.replace(' ','')) app_swkey = binascii.unhexlify(applicationKey.replace(' ','')) self.lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) self.s.setblocking(False) def pushSensorData(self, enCoSensor, debug = False, forceCreateChannel = False): try: self.s.send(bytes(enCoSensor.getLoRaPacket())) data = self.s.recv(64) if data: print(data) except AttributeError as err: print("Unable to send sensor over the loar network. Unable to convert to binary stream!") print (err)
class Startiot: def __init__(self): self.dev_eui = binascii.unhexlify("**REMOVED**") self.app_eui = binascii.unhexlify("**REMOVED**") self.app_key = binascii.unhexlify("**REMOVED**") self.lora = LoRa(mode=LoRa.LORAWAN) def connect(self, blocking = False, timeout = 0, function = None): self.lora.join(activation=LoRa.OTAA, auth=(self.dev_eui, self.app_eui, self.app_key), timeout=0) if timeout == 0: while not self.lora.has_joined(): if function == None: time.sleep(2.5) else: function() else: for x in range(timeout): if self.lora.has_joined(): break if function == None: time.sleep(2.5) else: function() if not self.lora.has_joined(): return False 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(blocking) return True def send(self, data): self.s.send(data) def recv(self, length): return self.s.recv(length)
# 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 # Now let's send some data... # create a LoRa socket
class LORA(object): 'Wrapper class for LoRa' def __init__(self, dr=2): # LoRa and socket instances # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) self.callback = None self.sockets = [] self.dr = dr # socket dr self.LED = None self.debug = False def connect(self, method, ports=1, callback=None, myLED=None, dr=None, debug=False): """ Connect device to LoRa. Set the socket and lora instances. myLED is led object, on resume use lora nvram """ self.callback = callback # call back routine on LoRa reply callback(port,response) self.debug = debug self.LED = myLED if myLED: myLED.heartbeat(False) self.restore sleep_ms(100) if self.lora.has_joined() or self.status: # resume LoRa OTAA or ABP self.getPorts(ports) return True if self.debug: print("No previous LoRa join. Try to join.") if (not type(method) is dict): raise ValueError("No activation method defined.") fnd = False try: if not method['OTAA'][0]: raise ValueError() fnd = True except: try: # OTAA from Config import dev_eui except: from machine import unique_id from ubinascii import hexlify dev_eui = 'AAAA' + hexlify(unique_id()) # use dflt try: from Config import app_eui, app_key method['OTAA'] = (dev_eui, app_eui, app_key) fnd = True except: pass if not fnd: try: if not method['ABP'][0]: raise ValueError() fnd = True except: # ABP try: from Config import dev_addr, nwk_swkey, app_swkey method['ABP'] = (dev_addr, nwk_swkey, app_swkey) fnd = True except: pass if not fnd: raise ValueError("No LoRa keys defined") if self.debug: print("LoRa keys load from Config") count = 0 if self.debug: print("Try to join LoRa/%s" % str(method.keys())) if 'OTAA' in method.keys(): # first OTAA from ubinascii import unhexlify # Join a network using OTAA (Over the Air Activation) next code looks strange dev_eui = method['OTAA'][0] dev_eui = unhexlify(dev_eui) app_eui = method['OTAA'][1] app_eui = unhexlify(app_eui) app_key = method['OTAA'][2] app_key = unhexlify(app_key) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=dr) # Wait until the module has joined the network if myLED: myLED.blink(4, 2.5, 0x04acf6) else: sleep_ms(10000) while not self.lora.has_joined(): if count > 15: break # machine.reset()? print("Wait for OTAA join: ", count) count += 1 if myLED: myLED.blink(2, 2.5, 0xff0000) else: sleep_ms(5000) if self.lora.has_joined(): count = 1 print("LoRa OTAA join.") else: count = 0 if not count: # if not ABP if not 'ABP' in method.keys(): print("No ABP TTN keys defined.") return False import struct from ubinascii import unhexlify # next code is strange. ABP method is not yet operational dev_addr = method['ABP'][0] dev_addr = unhexlify(dev_addr) dev_addr = struct.unpack('>l', dev_addr)[0] nwk_swkey = method['ABP'][1] nwk_swkey = unhexlify(nwk_swkey) app_swkey = method['ABP'][2] app_swkey = unhexlify(app_swkey) print("LoRa ABP join.") self.lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) self.getPorts(ports) if myLED: myLED.blink(2, 0.1, 0x009900) self.dump return True def getPorts(self, ports): # Create a LoRa sockets self.sockets = [] self.sockets.append(socket.socket(socket.AF_LORA, socket.SOCK_RAW)) # Set the LoRaWAN data rate self.sockets[0].setsockopt(socket.SOL_LORA, socket.SO_DR, self.dr) # Make the socket non-blocking self.sockets[0].setblocking(False) # Create a raw LoRa socket # default port 2 self.sockets.append(None) for nr in range(ports): self.sockets.append(socket.socket(socket.AF_LORA, socket.SOCK_RAW)) self.sockets[nr + 2].setblocking(False) if nr: self.sockets[nr + 2].bind(nr + 2) if self.debug: print("Installed LoRa port %d" % (nr + 2)) return True def send(self, data, port=2): """ Send data over the network. """ if (port < 2) or (port > len(self.sockets)): raise ValueError('Unknown LoRa port %d' % port) if not self.sockets[port]: raise OSError('No socket') rts = True try: self.sockets[port].send(data) if self.LED: self.LED.blink(2, 0.1, 0x0000ff) if self.debug: print("Sending data") # print(data) except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno) else: print("Lora ERROR: %s" % e) rts = False if self.LED: self.LED.off data = self.sockets[port].recv(64) if self.debug: print("Received data:", data) if self.callback and data: self.callback(port, data) sleep_ms(1000) self.dump # save status return rts @property def dump(self): from time import sleep_ms sleep_ms(2000) if self.debug: print("Save LoRa keys") return self.lora.nvram_save() @property def restore(self): self.lora.nvram_restore() if self.debug: print("Restore LoRa keys") return self.lora.stats().tx_counter @property def status(self): return self.lora.stats().tx_counter @property def clear(self): if self.debug: print("Clear LoRa keys") self.lora.nvram_erase()
#channel 9: 904100000 hz min_dr 0 max_dr 3 #channel 10: 904300000 hz min_dr 0 max_dr 3 #channel 11: 904500000 hz min_dr 0 max_dr 3 #channel 12: 904700000 hz min_dr 0 max_dr 3 #channel 13: 904900000 hz min_dr 0 max_dr 3 #channel 14: 905100000 hz min_dr 0 max_dr 3 #channel 15: 905300000 hz min_dr 0 max_dr 3 print('US channels set') time.sleep(1) print('Joining LoRa via OTAA') # join a network using ABP (Activation By Personalization) #lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # join a network using OTAA (Over the Air Activation) lora.join(activation=LoRa.OTAA, auth=(lorakeys._dev_eui, lorakeys._app_eui, lorakeys._app_key), timeout=0, dr=0) # wait until the module has joined the network while not lora.has_joined(): time.sleep(2.4) pycom.rgbled(0x7f7f00) #ylw time.sleep(0.1) pycom.rgbled(0x000000) #blk print('Not yet joined...') pass # 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) #from hpma115s0 import HPMA115S0
class LORA(object): 'Wrapper class for LoRa' # LoRa and socket instances lora = None s = None def connect(self, dev_eui, app_eui, app_key): """ Connect device to LoRa. Set the socket and lora instances. """ dev_eui = unhexlify(dev_eui) app_eui = unhexlify(app_eui) app_key = unhexlify(app_key) # Disable blue blinking and turn LED off LED.heartbeat(False) LED.off() # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode=LoRa.LORAWAN) # Join a network using OTAA (Over the Air Activation) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # Wait until the module has joined the network count = 0 while not self.lora.has_joined(): LED.blink(1, 2.5, 0xff0000) # print("Trying to join: " , count) count = count + 1 # Create a LoRa socket LED.blink(2, 0.1) 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) # print ("Joined! ", count) # print("Create LoRaWAN socket") # Create a raw LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setblocking(False) def send(self, data): """ Send data over the network. """ try: self.s.send(data) LED.blink(2, 0.1, 0x00ff00) print("Sending data:") print(data) except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno) LED.off() data = self.s.recv(64) print("Received data:", data) return data
# 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 if join_wait == 5: lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0, dr=config.LORA_NODE_DR) join_wait = 0 else: break # create a LoRa socket
Main operations: this is sample code for LoRaWAN on AU915 ''' lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AU915, device_class=LoRa.CLASS_C) # create an OTA authentication params dev_eui = binascii.unhexlify('0000000000000000') app_key = binascii.unhexlify( 'a926e5bb85271f2d') # not used leave empty loraserver.io nwk_key = binascii.unhexlify('a926e5bb85271f2da0440f2f4200afe3') prepare_channels(lora, 64, 5) # join a network using OTAA lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_key, nwk_key), timeout=0, dr=0) # DR is 2 in v1.1rb but 0 worked for ne # wait until the module has joined the network print('Over the air network activation ... ', end='') while not lora.has_joined(): time.sleep(2.5) print('.', end='') print('') for i in range(0, 8): fq = LORA_FREQUENCY + (i * 200000) lora.add_channel(i, frequency=fq, dr_min=0, dr_max=LORA_NODE_DR) print("AU915 Adding channel up %s %s" % (i, fq)) # create a LoRa socket
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( '70B3D57ED0019255') # these settings can be found from TTN #app_eui = ubinascii.unhexlify('70B3D57ED001C55E') dev_eui = ubinascii.unhexlify( '0058A97F44896904') # these settings can be found from TTN #dev_eui = ubinascii.unhexlify('006D2D7767E7BAFE') # these settings can be found from TTN app_key = ubinascii.unhexlify('AEAFACB81C594C7B7BE3466241CD38EF' ) # 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 self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) # make the socket non-blocking self.s.setblocking(False) self.lora.nvram_save() 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 change_txpower(self, power): self.lora.tx_power(power) 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) #lora=self.lora 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) self.s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False) def EnviarGateway(self, data): self.s.bind(3) self.s.send(data) time.sleep(10) 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) misg_crc = misg + " " + str(self.calculate_crc(misg)) msg = iv + cipher.encrypt(misg_crc) self.s.send(msg) self.s.setblocking(False) def reciveData(self, f, rtc): 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: crc_OK, msg = self.check_crc(original) if crc_OK: f = open('msgReceived_first.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") except Exception as e: print(e) return ("error") else: return ("error") 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 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 ApplyFormat_NeighboursTable(self, table, count): msg = b'' for i in range(len(table[0])): packet_power = ustruct.pack('b', int(table[1][i])) #signed char 1 byte packet_id = ustruct.pack('>Q', int(table[0][i], 16)) #long long: 8 bytes msg = msg + packet_id + packet_power #id=splitmsg[1].encode('utf-8') #id_aux=ustruct.pack('>Q',int(splitmsg[1],16)) #long long: 8 bytes msg = msg + ustruct.pack('H', count) return (msg) def neighbours_min(self, id, neighbours, neighbours_aux): 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 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) if (crc_new != crc_rcv): print(crc_new, crc_rcv, splitmsg) return (crc_new == crc_rcv, aux)
class PybytesConnection: def __init__(self, config, message_callback): self.__conf = config self.__host = config['server'] self.__ssl = config.get('ssl', False) self.__ssl_params = config.get('ssl_params', {}) self.__user_name = config['username'] self.__device_id = config['device_id'] self.__mqtt_download_topic = "d" + self.__device_id self.__mqtt_upload_topic = "u" + self.__device_id self.__connection = None self.__connection_status = constants.__CONNECTION_STATUS_DISCONNECTED self.__pybytes_protocol = PybytesProtocol(config, message_callback, pybytes_connection=self) 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)) else: print('Watchdog for WiFi and LTE was disabled, enable with "connection_watchdog": true in pybytes_config.json') # Establish a connection through WIFI before connecting to mqtt server def connect_wifi(self, reconnect=True, check_interval=0.5): self.__initialise_watchdog() if self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED: print("Error connect_wifi: Connection already exists. Disconnect First") 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']))] 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) available_nets = self.wlan.scan() 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] self.wlan.connect(net_to_use, (sec, pwd), timeout=10000) while not self.wlan.isconnected(): time.sleep(0.1) except Exception as e: if str(e) == "list index out of range": print("Please review Wifi SSID and password inside config") else: print("Error connecting using WIFI: %s" % e) self.wlan.deinit() return False self.__network_type = constants.__NETWORK_TYPE_WIFI print("WiFi connection established") self.__mqtt_check_interval = check_interval try: self.__connection = MQTTClient(self.__device_id, self.__host, self.__mqtt_download_topic, user=self.__user_name, password=self.__device_id, reconnect=reconnect, ssl=self.__ssl, ssl_params = self.__ssl_params) self.__connection.connect() self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_MQTT_WIFI self.__pybytes_protocol.start_MQTT(self, check_interval, constants.__NETWORK_TYPE_WIFI) 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)) 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, reconnect=True, check_interval=0.5): self.__initialise_watchdog() lte_cfg = self.__conf.get('lte') 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") return False try: from network import LTE time.sleep(3) print_debug(1, 'LTE init(carrier={}, cid={})'.format(lte_cfg.get('carrier'), lte_cfg.get('cid', 1))) self.lte = LTE(carrier=lte_cfg.get('carrier')) # instantiate the LTE object print_debug(1, 'LTE attach(band={}, apn={}, type={})'.format(lte_cfg.get('band'), lte_cfg.get('apn'), lte_cfg.get('type'))) self.lte.attach(band=lte_cfg.get('band'), apn=lte_cfg.get('apn'), type=lte_cfg.get('type')) # 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()') self.lte.connect() # start a data session and obtain an IP address 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 self.__mqtt_check_interval = check_interval try: self.__connection = MQTTClient(self.__device_id, self.__host, self.__mqtt_download_topic, user=self.__user_name, password=self.__device_id, reconnect=reconnect, ssl=self.__ssl, ssl_params = self.__ssl_params) self.__connection.connect() self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_MQTT_LTE self.__pybytes_protocol.start_MQTT(self, check_interval, constants.__NETWORK_TYPE_WIFI) 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)) else: print("MQTT ERROR! {}".format(ex)) return False except Exception as ex: print("Exception connect_lte: {}".format(ex)) return False else: print("Error... missing configuration!") return False # LORA def connect_lora_abp(self, lora_timeout, nanogateway): if (self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED): print("Error connect_lora_abp: Connection already exists. Disconnect First") return False try: from network import LoRa except Exception as ex: print("This device does not support LoRa connections: %s" % ex) return False self.lora = LoRa(mode=LoRa.LORAWAN) self.lora.nvram_restore() dev_addr = self.__conf['lora']['abp']['dev_addr'] nwk_swkey = self.__conf['lora']['abp']['nwk_skey'] app_swkey = self.__conf['lora']['abp']['app_skey'] timeout_ms = self.__conf.get('lora_timeout', lora_timeout) * 1000 dev_addr = struct.unpack(">l", binascii.unhexlify(dev_addr.replace(' ', '')))[0] nwk_swkey = binascii.unhexlify(nwk_swkey.replace(' ', '')) app_swkey = binascii.unhexlify(app_swkey.replace(' ', '')) try: print("Trying to join LoRa.ABP for %d seconds..." % 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) _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" % lora_timeout) return False def connect_lora_otta(self, lora_timeout, nanogateway): if (self.__connection_status != constants.__CONNECTION_STATUS_DISCONNECTED): print("Error connect_lora_otta: Connection already exists. Disconnect First") return False try: from network import LoRa except Exception as ex: print("This device does not support LoRa connections: %s" % ex) return False 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'] timeout_ms = self.__conf.get('lora_timeout',lora_timeout) * 1000 self.lora = LoRa(mode=LoRa.LORAWAN) 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: print("Trying to join LoRa.OTAA for %d seconds..." % 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) _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" % lora_timeout) 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): print("Error: Connection already exists. Disconnect First") pass try: from network import Sigfox except: 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 = Sigfox(mode=Sigfox.SIGFOX, rcz=sf_rcz) self.__sigfox_socket = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW) self.__sigfox_socket.setblocking(True) self.__sigfox_socket.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False) self.__network_type = constants.__NETWORK_TYPE_SIGFOX self.__connection_status = constants.__CONNECTION_STATUS_CONNECTED_SIGFOX 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): print_debug(1, 'self.__connection_status={} | self.__network_type={}'.format(self.__connection_status, self.__network_type)) if (self.__connection_status == constants.__CONNECTION_STATUS_DISCONNECTED): print("Already disconnected") pass if (constants.__CONNECTION_STATUS_CONNECTED_MQTT_WIFI <= self.__connection_status <= constants.__CONNECTION_STATUS_CONNECTED_MQTT_LTE): print_debug(1, 'MQTT over WIFI||LTE... disconnecting MQTT') try: self.__connection.disconnect() self.__connection_status = constants.__CONNECTION_STATUS_DISCONNECTED except Exception as e: print("Error disconnecting: {}".format(e)) if (self.__connection_status == constants.__CONNECTION_STATUS_CONNECTED_LORA): print_debug(1, 'Connected over LORA... closing socket and saving nvram') 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): 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): 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))) 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)
class LoRaHelper: def __init__(self, app_eui_hexstr, app_key_hexstr, debug_led=True, debug_output=True): self._debug = debug_output self._led = debug_led if self._led: pycom.heartbeat(False) pycom.rgbled(0x500000) self._app_eui = binascii.unhexlify(app_eui_hexstr) self._app_key = binascii.unhexlify(app_key_hexstr) self._air_time_base = 0 tmp = pycom.nvs_get('air') if tmp is not None: self._air_time_base = tmp self._air_time = self._air_time_base self._sock = None self._lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) if self._led: pycom.rgbled(0x500000) if self._debug: print('LoRaHelper (debug): LoRa MAC: ' + str(binascii.hexlify(self._lora.mac()))) print('LoRaHelper (debug): Joining network ...') self._lora.join(activation=LoRa.OTAA, auth=(self._app_eui, self._app_key), timeout=0) tmp_on = True while not self._lora.has_joined(): if self._debug: print('LoRaHelper (debug): Joining ...') time.sleep(1) tmp_on = not tmp_on if self._led: if tmp_on: pycom.rgbled(0x502000) else: pycom.rgbled(0x000000) if self._led: pycom.rgbled(0x505000) if self._debug: print('LoRaHelper (debug): LoRaWan network joined!') if self._debug: print('LoRaHelper (debug): Creating socket') self._sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self._sock.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) if self._led: pycom.rgbled(0x005000) if self._debug: print('LoRaHelper (debug): Creating socket') def mac(self): return binascii.hexlify(self._lora.mac()).upper().decode('utf-8') def has_joined(self): return self._lora.has_joined() def air_time(self): self._air_time = self._air_time_base + self._lora.stats().tx_time_on_air pycom.nvs_set('air', self._air_time) return self._air_time def send(self, data: bytes): if self._sock is None: self._sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self._sock.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) self._sock.setblocking(True) self._sock.send(data) self._sock.setblocking(False) self._air_time = self._air_time_base + self._lora.stats().tx_time_on_air pycom.nvs_set('air', self._air_time) def recv(self): if self._sock is None: self._sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self._sock.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) self._sock.setblocking(False) data = self._sock.recv(128) return data
# Initialize LoRa in LORAWAN mode. lora = LoRa(mode=LoRa.LORAWAN) # create an OTA authentication params dev_eui = binascii.unhexlify('007FFD9B1D113123'.replace(' ','')) app_eui = binascii.unhexlify('70B3D57EF0005B3B'.replace(' ','')) app_key = binascii.unhexlify('950942111D56A3812CAE94A0DD5048D9'.replace(' ','')) # 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)
class LoRaManager: """ """ def __init__(self, manager, settings): self.manager = manager self.settings = settings # LoRa settings. self.otaa_settings = self.settings.get('networking.lora.otaa') #self.generated_device_eui = binascii.hexlify(LoRa().mac()) def start(self): """ """ self.start_lora_join() def start_lora_join(self): """ """ from network import LoRa if self.otaa_settings['region'] == 'AS923': lora_region = LoRa.AS923 elif self.otaa_settings['region'] == 'AU915': lora_region = LoRa.AU915 elif self.otaa_settings['region'] == 'EU868': lora_region = LoRa.EU868 elif self.otaa_settings['region'] == 'US915': lora_region = LoRa.US915 lora_adr = self.otaa_settings['adr'] or False self.lora_socket = None self.lora = LoRa(mode=LoRa.LORAWAN, region=lora_region, adr=lora_adr) # restore LoRa state from NVRAM after waking up from DEEPSLEEP. Reset LoRa NVRAM and rejoin otherwise if machine.reset_cause() == machine.DEEPSLEEP_RESET: self.lora.nvram_restore() log.info( '[LoRa] LoRaWAN state restored from NVRAM after deep sleep') else: self.lora.nvram_erase() log.info('[LoRa] LoRaWAN state erased from NVRAM. Rejoin forced') # Create LoRaWAN OTAA connection to TTN. app_eui = binascii.unhexlify(self.otaa_settings['application_eui']) app_key = binascii.unhexlify(self.otaa_settings['application_key']) if not self.lora.has_joined(): log.info('[LoRa] joining the network...') if self.otaa_settings.get('device_eui') is None: self.lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) else: dev_eui = binascii.unhexlify(self.otaa_settings['device_eui']) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) def wait_for_lora_join(self, attempts): """ :param attempts: """ self.lora_joined = None for i in range(0, attempts): while not self.lora.has_joined(): log.info('[LoRa] Not joined yet...') time.sleep(2.5) self.lora_joined = self.lora.has_joined() if self.lora_joined: log.info('[LoRa] joined...') else: log.info('[LoRa] did not join in %s attempts', attempts) return self.lora_joined def create_lora_socket(self): """ """ # create a lora socket self.socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.socket.settimeout(6.0) self.lora_socket = True log.info('[LoRa] socket created') return self.lora_socket def lora_send(self, payload): """ :param payload: """ self.socket.setblocking(True) success = self.socket.send(payload) self.socket.setblocking(False) self.lora.nvram_save() return success def lora_receive(self): """ """ import binascii try: rx, port = self.socket.recvfrom(256) except socket.timeout: log.info('[LoRa] no packet received within receive window ') if rx: log.info('[LoRa] Received: {}, on port: {}'.format(rx, port)) return rx, port
def main(): print ("Main Execution") app_eui = binascii.unhexlify('00 00 00 00 00 00 00 00'.replace(' ','')) app_key = binascii.unhexlify('11 22 33 44 55 66 77 88 11 22 33 44 55 66 77 88'.replace(' ','')) pycom.heartbeat(False) lora = LoRa(mode=LoRa.LORAWAN) for i in range (0, 255): led = i<< 16| i <<8 | i pycom.rgbled(led) time.sleep(0.01) # join a network using OTAA (Over the Air Activation) lora.join(activation=LoRa.OTAA, auth=(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 yet joined...') pycom.rgbled(0) # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.bind(0x02); # set the LoRaWAN data rate s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False) print("apres setsock") # make the socket blocking # (waits for the data to be sent and for the 2 receive windows to expire) f = Frag(s, MTU=50, rule=rule_frag)#, f.send ("""To be, or not to be: that is the question: Whether ’tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles, And by opposing end them? To die: to sleep; No more; and by a sleep to say we end The heart-ache and the thousand natural shocks That flesh is heir to, ’tis a consummation Devoutly to be wish’d. To die, to sleep; To sleep: perchance to dream: ay, there’s the rub; For in that sleep of death what dreams may come When we have shuffled off this mortal coil, Must give us pause: there’s the respect That makes calamity of so long life; For who would bear the whips and scorns of time, The oppressor’s wrong, the proud man’s contumely, The pangs of despised love, the law’s delay, The insolence of office and the spurns That patient merit of the unworthy takes, When he himself might his quietus make With a bare bodkin? who would fardels bear, To grunt and sweat under a weary life, But that the dread of something after death, The undiscover’d country from whose bourn No traveller returns, puzzles the will And makes us rather bear those ills we have Than fly to others that we know not of? Thus conscience does make cowards of us all; And thus the native hue of resolution Is sicklied o’er with the pale cast of thought, And enterprises of great pith and moment With this regard their currents turn awry, And lose the name of action.–Soft you now! The fair Ophelia! Nymph, in thy orisons Be all my sins remember’d.""") f.sleep()
import pycom import machine import config print('Main start') # LoRa details keys obtained from KPN dev_addr = struct.unpack(">l", binascii.unhexlify(config.DEV_ADDR))[0] nwks_key = binascii.unhexlify(config.NWKS_KEY) apps_key = binascii.unhexlify(config.APPS_KEY) # Setup LoRa lora = LoRa(mode=LoRa.LORAWAN, adr=True) # join a network using ABP lora.join(activation=LoRa.ABP, auth=(dev_addr, nwks_key, apps_key), timeout=0) print("LoRa active: ", lora.has_joined()) # create a LoRa socket lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate lora_sock.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) lora_sock.setblocking(False) def ack(): for i in range(3): pycom.rgbled(0x00ff00) time.sleep_ms(100)
class LoRaManager: """ """ def __init__(self, manager, settings): self.manager = manager self.settings = settings # LoRa settings. self.otaa_settings = self.settings.get('networking.lora.otaa') #self.generated_device_eui = binascii.hexlify(LoRa().mac()) def start(self): """ """ self.start_lora_join() self.wait_for_lora_join(42) time.sleep(2.5) if self.lora_joined: self.create_lora_socket() else: log.error("[LoRa] Could not join network") def start_lora_join(self): """ """ from network import LoRa #pycom.rgbled(0x0f0000) # red #self.lora = LoRa(mode=LoRa.LORAWAN, region=self.otaa_settings['region']) self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) # restore LoRa state from NVRAM after waking up from DEEPSLEEP. Rejoin otherwise if machine.reset_cause() == machine.DEEPSLEEP_RESET: self.lora.nvram_restore() log.info( '[LoRA] LoRaWAN state restored from NVRAM after deep sleep') else: self.lora.nvram_erase() log.info( '[LoRA] LoRaWAN state erased from NVRAM to let the device join the network' ) # Create LoRaWAN OTAA connection to TTN. app_eui = binascii.unhexlify(self.otaa_settings['application_eui']) app_key = binascii.unhexlify(self.otaa_settings['application_key']) # Remark: For Pycom Nanogateway. # Set the 3 default channels to the same frequency (must be before sending the otaa join request) #self.lora.add_channel(0, frequency=self.otaa_settings['frequency'], dr_min=0, dr_max=5) #self.lora.add_channel(1, frequency=self.otaa_settings['frequency'], dr_min=0, dr_max=5) #self.lora.add_channel(2, frequency=self.otaa_settings['frequency'], dr_min=0, dr_max=5) if not self.lora.has_joined(): if self.otaa_settings.get('device_eui') is None: self.lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) else: dev_eui = binascii.unhexlify(self.otaa_settings['device_eui']) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) def wait_for_lora_join(self, attempts): """ :param attempts: """ self.lora_joined = None for i in range(0, attempts): while not self.lora.has_joined(): time.sleep(2.5) #pycom.rgbled(0x0f0f00) # yellow time.sleep(0.1) log.info('[LoRA] Not joined yet...') #pycom.rgbled(0x000000) # off self.lora_joined = self.lora.has_joined() if self.lora_joined: log.info('[LoRA] joined...') # TODO: move nvram_save() to after payload send call self.lora.nvram_save() else: log.info('[LoRa] did not join in %s attempts', attempts) #for i in range(3, 16): # self.lora.remove_channel(i) return self.lora_joined def create_lora_socket(self): """ """ # create a lora socket self.lora_socket = None self.socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate #self.socket.setsockopt(socket.SOL_LORA, socket.SO_DR, self.otaa_settings['datarate']) self.socket.setsockopt(socket.SOL_LORA, socket.SO_DR, self.otaa_settings['datarate']) # make the socket non-blocking self.socket.setblocking(False) self.lora_socket = True log.info('[LoRa] socket created') for i in range(0, 2): #pycom.rgbled(0x000f00) # green time.sleep(0.1) #pycom.rgbled(0x000000) # off time.sleep(4.0) return self.lora_socket def lora_send(self, payload): """ :param payload: """ success = self.socket.send(payload) for i in range(0, 2): #pycom.rgbled(0x00000f) # green time.sleep(0.1) #pycom.rgbled(0x000000) # off return success def lora_receive(self): """ """ rx, port = self.socket.recvfrom(256) if rx: #pycom.rgbled(0x000f00) # green log.info('[LoRa] Received: {}, on port: {}'.format(rx, port)) #pycom.rgbled(0x000f00) # green time.sleep(6) return rx, port
def start(my_ota_updater): from network import LoRa import socket import time import binascii import pycom # Turn the light red # blue pycom.heartbeat(False) pycom.rgbled(0x110000) # 0x000011 # Initialise LoRa in LORAWAN mode. lora = LoRa(mode=LoRa.LORAWAN) print("devEUI {}".format(binascii.hexlify(lora.mac()))) app_eui = binascii.unhexlify('00 00 00 00 00 00 00 00'.replace(' ', '')) app_key = binascii.unhexlify( '11 22 33 44 55 66 77 88 11 22 33 44 55 66 77 88'.replace(' ', '')) # join a network using OTAA (Over the Air Activation) lora.join(activation=LoRa.OTAA, auth=(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 yet joined...') # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) #s.bind(5) # set the LoRaWAN data rate s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False) timestamp = time.time() # setup for the data sending i2c = I2C(0, I2C.MASTER, baudrate=400000) print(i2c.scan()) bme = data_sensor.BME280(i2c=i2c) ob = 0 while True: # Turn the light green pycom.rgbled(0x001100) s.setblocking(True) s.settimeout(10) # reading data ar = bme.read_raw_temp() a = bme.read_temperature() br = bme.read_raw_pressure() b = bme.read_pressure() cr = bme.read_raw_humidity() c = bme.read_humidity() # print ("temp", ar, a, "° - hum", cr, c, "% - pres", br, # "pres", b, "hPa [delta", ob - br, "]" ) ob = br # for testing new code, remove try/except #message_to_send = "Temp : " + str(a) + "°C - Hum : " + str(c) + "%" # - Pres : " + str(b) + "hPa" message_to_send = { "temperature": str(a), "humidity": str(c), "pressure": str(b) } message_to_send = json.dumps(message_to_send) print(message_to_send) try: # send the data from the sensor s.send(message_to_send) except: print('timeout in sending') # Turn the light red pycom.rgbled(0x110000) try: data_received = s.recv(64) print(data_received) # Turn the light white pycom.rgbled(0x111111) except: print('nothing received') data_received = "" # Turn the light off pycom.rgbled(0x000000) # regularly check for a new update print("pre if") if data_received: data_received = str(data_received)[2:-1] print("data received : ", data_received, " type : ", type(data_received)) data_dict = json.loads(data_received) print(data_dict) if data_dict["version"] > VERSION: print("if before") my_ota_updater.check_for_update_to_install_during_next_reboot( WIFI_SSID, WIFI_PW) # turn wifi off print("if after") # s.setblocking(False) print("sleep") time.sleep(5)
print('line 31') # disable LED heartbeat (so we can control the LED) pycom.heartbeat(False) # set LED to red pycom.rgbled(0x7f0000) print('line 36') # lora config lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923) # access info app_eui = binascii.unhexlify('70B3D57ED0013D54') app_key = binascii.unhexlify('71CD15EFBCF23E05B70F94F19C5CEB66') print('line 42') # attempt join - continues attempts background lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=10000) # wait for a connection print('Waiting for network connection...') while not lora.has_joined(): pass # we're online, set LED to green and notify via print pycom.rgbled(0x007f00) print('Network joined!') # setup the socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) s.setblocking(False) s.bind(1)
def set_LoRa_WAN_ABP(): print("Setting up ABP...") lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
lora = LoRa(mode=LoRa.LORAWAN, public=True, adr=False) #Setting up channels for sub-band 2 for TTN for index in range(0, 8): lora.remove_channel(index) for index in range(16, 65): lora.remove_channel(index) for index in range(66, 72): lora.remove_channel(index) auth = (bytes([...]), bytes([...])) print("joining...") lora.join(activation=LoRa.OTAA, auth=auth, timeout=0) x = 0 # wait until the module has joined the network while (not lora.has_joined() and x < 10): time.sleep(2.5) print('Not yet joined...') x = x + 1 print(lora.has_joined()) if (lora.has_joined()): # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) lora.remove_channel(65) #drop the 500khz channel for index in range(0, 20):
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AS923, device_class=LoRa.CLASS_C, adr=False, tx_power=20) # create an OTA authentication params dev_eui = binascii.unhexlify('0000000000000000') app_key = binascii.unhexlify( 'a926e5bb85271f2d') # not used leave empty loraserver.io nwk_key = binascii.unhexlify('a926e5bb85271f2da0440f2f4200afe3') # join a network using OTAA lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_key, nwk_key), timeout=0, dr=2) # AS923 always joins at DR2 prepare_channels(lora, LORA_CHANNEL, LORA_NODE_DR) # wait until the module has joined the network print('Over the air network activation ... ', end='') while not lora.has_joined(): time.sleep(2.5) print('.', end='') print('') # create a LoRa socket lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate
# channel=7, antenna=WLAN.INT_ANT) # Display our device info & address print(sys_info) print(lora_mac) # join a network using OTAA sfdr = 5 sfdr_min = 0 # SF12 sfdr_max = 5 # SF7 pycom.rgbled(0x7f7f00) # yellow while not (lora.has_joined()): lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0, dr=sfdr) time.sleep(20) if not lora.has_joined() and sfdr != 0: sfdr -= 1 pycom.rgbled(0x007f00) # green s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate SF7=5 SF8=4 SF9=3 SF10=2 SF11=1 SF12=0 s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, True) # make the socket non-blocking s.setblocking(False) pycom.heartbeat(False)
device_class=LoRa.CLASS_C) wdt.init(timeout=300000) wdt.feed() if config.LORA_STATE_PERSIST: lora.nvram_restore() else: lora.nvram_erase() try: dev_addr = struct.unpack(">l", ubinascii.unhexlify(config.ABP_DEV_ADDR))[0] nwk_swkey = ubinascii.unhexlify(config.ABP_NWK_SWKEY) app_swkey = ubinascii.unhexlify(config.ABP_APP_SWKEY) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) print("Using ABP") except Exception: app_eui = ubinascii.unhexlify(config.OTAA_APP_EUI) app_key = ubinascii.unhexlify(config.OTAA_APP_KEY) f = open('deveui.txt', 'w') f.write(ubinascii.hexlify(lora.mac()).decode('ascii')) f.close() lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) print("Using OTAA") blink = True while not lora.has_joined(): blink = not blink pycom.rgbled(0xff0000 if blink else 0x000000) time.sleep(0.5)
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)
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) dev_addr = struct.unpack(">l", binascii.unhexlify('26011783'))[0] nwk_swkey = ubinascii.unhexlify('CFEFE657C90C2BFE2A6D9ECCEA4B1111') app_swkey = ubinascii.unhexlify('A4D90348A3A516CEB1288C54C54154B0') for i in range(3, 16): # remove all the non-default channels lora.remove_channel(i) lora.add_channel( index=0, frequency=868100000, dr_min=0, dr_max=5) # set the 3 default channels to the same frequency (868.1 MHz) 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) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey), timeout=0) # loRa join TTN s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # loRa socket s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) time.sleep(1) s.setblocking(False) pycom.heartbeat(False) # AVERAGE HUMIDITY time.sleep(2) humidity = 0 for n1 in range(3): #read values 3 times humidity = humidity + (100 - int(hum_val() / 40.95)) time.sleep(1)
import binascii from network import LoRa import config # initialize LORAWAN mode for EU region lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868) # print DevEUI of the device, use this when provisioning it in your network server print("DevEUI: " + binascii.hexlify(lora.mac()).decode('utf-8').upper()) # OTAA authentication parameters, replace these with your own print("Joining network using OTAA (Over the Air Activation)") lora.join(activation=LoRa.OTAA, auth=(config.app_eui, config.app_key), timeout=0) # wait until the module has joined the network while not lora.has_joined(): time.sleep(2.5) print('Not yet joined...') print("Joined network") # create socket to be used for LoRa communication s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # configure data rate s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
class Node: _thread = None def __init__(self): self.lora = None self.s = None self.py = Pysense() # 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.alarma = None # Alarma de toma de datos de aceleracion self.s_lock = _thread.allocate_lock() # Semaforo para envío #------------------------------------------------------------------------------# def connect(self, dev_eui, app_eui, app_key, dr=5): """ Connect device to LoRa. Set the socket and lora instances. """ # Disable blue blinking and turn LED off pycom.heartbeat(False) # 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) #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! ") print("Create LoRaWAN 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, dr) # selecting confirmed type of messages self.s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, True) # Make the socket non-blocking self.s.setblocking(False) #Crea la alarma tras la conexion self.alarma = Timer.Alarm( self.readsens, self.interval, periodic=True) #Alarma de toma de datos de aceleracion #------------------------------------------------------------------------------# def send(self, datalast, dataraw): """ Send data over the network. """ self.s_lock.acquire( ) # Espera a que el semáforo esté disponible (tiempo indefinido) try: data = datalast, dataraw self.s.send(str(data)) time.sleep(2) #Espera para posible recepción rx = self.s.recv(128) #Recepción de datos self.receive(rx=rx) 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 #------------------------------------------------------------------------------# def receive(self, rx=None): if rx == None: 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.interval = int.from_bytes( rx[1:], 'big') #Decodifica el valor del nuevo intervalo self.alarma.cancel() #Cancela la alarma self.alarma = Timer.Alarm( self.readsens, self.interval, periodic=True ) #Vuelve a crear una alarma para el nuevo intervalo elif rx[0] == 67: #Orden de Cancelación de Lecturas (ASCII hex C=0x43 dec 67) print('Cancela las lecturas') self.alarma.cancel() elif rx[0] == 82: #Orden de Cambio Data Rate (ASCII hex R=0x52 dec 87) dr = int.from_bytes( rx[1:], 'big') #Decodifica el valor del nuevo data Rate self.connect(dr=dr) else: pass #------------------------------------------------------------------------------# #Función de lectura de medidas. El Acelerometro ya ha sido inicializado al #crear la instancia de la clase def readsens(self, alarma): 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[2] > 1): print("Enviando datos") _thread.start_new_thread( self.send, (self.last, self.raw)) # Se crea un hilo para el envío de valores self._compare_update() self.battery = round(self.py.read_battery_voltage(), 2) if (self.battery < 3.3): 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
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(' ', '')) # 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...') # 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
lora.add_channel(index=8, frequency=904600000, dr_min=3, dr_max=3) #lora.init(mode, [region=LoRa.US915, frequency, tx_power, bandwidth=LoRa.BW_125KHZ, sf=7, preamble=8, coding_rate=LoRa.CODING_4_5, power_mode=LoRa.ALWAYS_ON, tx_iq=False, rx_iq=False, adr=False, public=True, tx_retries=2, device_class=LoRa.CLASS_A]) # create an OTAA authentication parameters, change them to the provided credentials app_eui = ubinascii.unhexlify('70B3D57ED00364C6') app_key = ubinascii.unhexlify('1F93D7158251630C1D0C784BF57D4B7B') #uncomment to use LoRaWAN application provided dev_eui dev_eui = ubinascii.unhexlify('70B3D5499C46BF34') #pycom.rgbled(0x000000) # join a network using OTAA (Over the Air Activation) #uncomment below to use LoRaWAN application provided dev_eui #lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) for i in range(3000): time.sleep_ms(1) lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key)) #lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key)) # wait until the module has joined the network #for i in range(5): """ count=0 while not lora.has_joined(): pycom.rgbled(0x0f000f) #time.sleep_ms(10) if count < 20000: count=count+1 #time.sleep_ms(10) #time.sleep_ms(1) else : #pycom.rgbled(0x0f000f) print('New join request')
#channel 9: 904100000 hz min_dr 0 max_dr 3 #channel 10: 904300000 hz min_dr 0 max_dr 3 #channel 11: 904500000 hz min_dr 0 max_dr 3 #channel 12: 904700000 hz min_dr 0 max_dr 3 #channel 13: 904900000 hz min_dr 0 max_dr 3 #channel 14: 905100000 hz min_dr 0 max_dr 3 #channel 15: 905300000 hz min_dr 0 max_dr 3 print('US channels set') time.sleep(1) print('restoring LoRa NVRAM') lora.nvram_restore() print('Joining LoRa via ABP') # 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) while (1): # make the socket blocking # (waits for the data to be sent and for the 2 receive windows to expire) s.setblocking(True) print("Sending data!") # s.send(bytes([bytestream[4], bytestream[5], bytestream[6],bytestream[7],tempstruct[0],tempstruct[1],rhstruct[0],rhstruct[1],dewstruct[0],dewstruct[1],presstruct[0],presstruct[1],broadlumstruct[0],broadlumstruct[1],IRlumstruct[0],IRlumstruct[1]]))#,relativehumid,dewpoint])) s.send(
class Startiot: def __init__(self): self.dev_eui = binascii.unhexlify("YOUR DEV_EUI") self.app_eui = binascii.unhexlify("YOUR APP_EUI") self.app_key = binascii.unhexlify("YOUR APP_KEY") self.lora = LoRa(mode=LoRa.LORAWAN) def connect(self, timeout=0, function=None, blocking=False): self.lora.nvram_restore() if not self.lora.has_joined(): # No saved connetion state pycom.rgbled(0x0f0000) self.lora.join(activation=LoRa.OTAA, auth=( self.dev_eui, self.app_eui, self.app_key), timeout=0) if timeout == 0: while not self.lora.has_joined(): if function == None: sleep(2.5) else: function() else: for x in range(timeout): if self.lora.has_joined(): break if function == None: sleep(2.5) else: function() if not self.lora.has_joined(): return False pycom.rgbled(0x000000) else: # Connection state restored pycom.rgbled(0x0000ff) pass self.lora.nvram_save() 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(blocking) pycom.rgbled(0x000000) return True def send(self, data): self.s.setblocking(True) self.s.send(data) def recv(self, length=64): self.s.setblocking(False) return self.s.recv(length)
class LoraController: def __init__(self, options, logger, eventLog, ledController): self.options = options self.logger = logger self.eventLog = eventLog self.led = ledController self.lora = LoRa(mode=LoRa.LORA, power_mode=LoRa.SLEEP) self.tx_runner = None # thread which sends events over lora self.lastJoin = 0 # when did we join the lora network self.isJoinLogged = False # did we log the initial LORA join self.lastEventId = 0 # last sent event id self.sendLock = _thread.allocate_lock() self.socketLock = _thread.allocate_lock() self.isAckingCounter = 0 self.noDownlinkCounter = 0 self.lastUplinkTime = 0 self.isAcking = False # logging def log(self, *text): self.logger.log("LORA", *text) # start lora connectivity def start(self): # setup lorawan self.lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868, device_class=LoRa.CLASS_A, tx_retries=3, adr=True, sf=12) self.lora.nvram_restore() self.lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT | LoRa.TX_FAILED_EVENT), handler=self.lora_callback) self.log('Lora DevEUI is', self.getDeviceEUI()) self.log('Lora AppEUI is', self.options['lora_app_eui']) if len(self.options['lora_app_eui']) != 16: self.log("ERROR", "Setting 'lora_app_eui' is invalid:", self.options['lora_app_eui']) return # issue join if self.options['lora_mode'] == "abp": self.join() elif self.lora.has_joined(): self.log("Lora network is already joined, re-joining anyway") else: self.join() def lora_callback(self, lora): events = lora.events() if events & LoRa.TX_FAILED_EVENT: self.log('Lora TX FAILED') # determines the LORA MAC address (string) def getDeviceEUI(self): return ubinascii.hexlify(self.lora.mac()).decode('ascii').upper() # joins the lora network via OTAA def joinOTAA(self): app_eui = ubinascii.unhexlify(self.options['lora_app_eui']) app_key = ubinascii.unhexlify(self.options['lora_app_key']) self.lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) self.log("Joining via OTAA") self.lastJoin = time.time() # joins the lora network via ABP def joinABP(self): net_key = ubinascii.unhexlify(self.options['lora_net_key']) app_key = ubinascii.unhexlify(self.options['lora_app_key']) # note: TTN seems to want the reverse bytes of this address device_address = ubinascii.unhexlify(self.options['lora_dev_adr']) self.lora.join(activation=LoRa.ABP, auth=(device_address, net_key, app_key)) self.log("Joining via ABP with device address", device_address) self.lastJoin = time.time() # joins the lora network via ABP or OTAA def join(self): if self.options['lora_mode'] == "abp": self.joinABP() else: self.joinOTAA() def hasJoined(self): return self.lora.has_joined() def stats(self): return self.lora.stats() def makePayload(self, event): payload = None command = event['Command'] idbytes = event['ID'].to_bytes(2, 'little') event_ts = event['Time'] try: if command == eventlog.CMD_TAG_DETECTED: # Tag with 4-Byte UID detected # <0x01> <Event ID 0..1> <Timestamp 0..3> <UID 0..3/6/9> timeBytes = event_ts.to_bytes(4, 'little') uid = event['Data'][0:10] # remove trailing 0x00 uid_size = 10 for i in range(uid_size - 1, 3, -1): if uid[i] != 0x00: break uid_size = uid_size - 1 uid = uid[:uid_size] payload = bytes([0x01]) + idbytes + timeBytes + uid uidText = ubinascii.hexlify(uid).decode() self.log("CMD 0x01 [NFC_DETECTED] SEQ#", event['ID'], ". uid =", uidText, ", ts =", event_ts) if command == eventlog.CMD_TIME_REQUEST2: # ask backend for current time (new) # <0x04> <ID 0..1> <Our Time 0..3> mytime = time.time().to_bytes(4, 'little') payload = bytes([command]) + idbytes + mytime self.log("CMD 0x04 [TIME_REQUEST] ID#", event['ID'], ". our_time =", time.time(), utime.gmtime(time.time())) if command == eventlog.CMD_TIME_CHANGED: # <0x05> <Event ID 0..1> <Our Time 0..3> <Old Time 0..3> mytime = event_ts.to_bytes(4, 'little') oldTime = event['Data'][0:4] payload = bytes([eventlog.CMD_TIME_CHANGED ]) + idbytes + mytime + oldTime self.log("CMD 0x05 [TIME_CHANGED] SEQ#", event['ID'], ". our_time =", event_ts, utime.gmtime(event_ts), ", old_time =", oldTime) except Exception as e: self.log("ERROR: Unable to prepare LORA payload:", e.args[0], e) return payload # attempts to send the given event def sendEvent(self, event): with self.sendLock: eventId = event['ID'] command = event['Command'] self.log("Preparing to send CMD =", command, ", SEQ_NO =", eventId) if self.lastEventId > 0 and eventId > self.lastEventId + 1: self.log("ERROR", "Event IDs are not in sequence - last:", self.lastEventId, ", current:", eventId) self.lastEventId = eventId # prepare lora payload for supported event log entries payload = self.makePayload(event) if payload == None: self.log( "WARN: Event payload is None and therefore ignored for lora transmission" ) return True # send payload return self.sendAndHandleResponse(payload) # sends the payload and handles the optional response def sendAndHandleResponse(self, payload): if not self.hasJoined(): self.log("ERROR", "Unable to send LORA payload because not joined") return False # send responseData = self.sendPayload(payload) if responseData == False: self.noDownlinkCounter = self.noDownlinkCounter + 1 return False # handle response if responseData != None and len(responseData) > 0: try: return True except Exception as e: self.log("ERROR: Unable to handle LORA payload: ", e.args[0], e) self.noDownlinkCounter = self.noDownlinkCounter + 1 else: self.noDownlinkCounter = self.noDownlinkCounter + 1 # the message has been sent return True def sendTimeRequest(self, clockSyncEvent, clockSyncRequests): clockSyncEvent['Command'] = eventlog.CMD_TIME_REQUEST2 payload = self.makePayload(clockSyncEvent) try: with self.sendLock: # send lora uplink responseData = self.sendPayload(payload, False) if responseData == False: return None except Exception as e: self.log("ERROR", "Unable to sync clock via LORA:", e.args[0], e) return None # send the specified payload def sendPayload(self, data, updateTime=True): try: with self.socketLock: self.log("> sending", len(data), "bytes:", binascii.hexlify(data)) responseData = None # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setblocking(False) try: """free_memory = gc.mem_free() allocated_memory = gc.mem_alloc() print("Free Memory: " + str(free_memory) + " -- Allocated Memory : " + str(allocated_memory))""" s.send(data) time.sleep(5) responseData = s.recv(64) except Exception as e: self.log("ERROR", "LORA Socket Exception", e) s.close() if responseData != None: responseLen = len(responseData) if responseLen > 0: self.log("< received", responseLen, "bytes:", binascii.hexlify(responseData)) else: self.log("< no downlink") # log if updateTime == True: self.lastUplinkTime = time.time() self.log(self.stats()) time.sleep_ms(10) # save frame counters self.lora.nvram_save() time.sleep_ms(5) return responseData except Exception as e: self.log("ERROR", "Unable to send payload", e.args[0], e) return False
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, 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'2222222222222222') #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'2222222222222222', isprimary=True) #set up service character chr1 = srv1.characteristic(uuid=b'2222222222222222', 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.start_scan(-1) #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 print(char.properties()) if (char.properties() & Bluetooth.PROP_READ): #print('char {} value = {}'.format(char.uuid(), char.read())) print('char {} value = {}'.format(char.uuid(), char.read())) #Use LoRa to send the data out s.send(char.read()) time.sleep(2) #write data to server #char.write(b'x0ff') #Yunwei conn.disconnect() print('connected?',conn.isconnected()) #break time.sleep(3) bluetooth_client.start_scan(-1) ''' #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) ''' except: print("Error while connecting or reading from the BLE device") #break time.sleep(1) #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) 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()
class LoRaNetwork: def __init__(self): # Turn off hearbeat LED pycom.heartbeat(False) # Initialize LoRaWAN radio self.lora = LoRa(mode=LoRa.LORAWAN) # Connect to sensors. #wlan = WLAN(mode=WLAN.STA) # Uncomment next line to disable wifi #wlan.deinit() # go for fixed IP settings (IP, Subnet, Gateway, DNS) # Set network keys app_eui = binascii.unhexlify('70B3D57EF0003F19') app_key = binascii.unhexlify('0EFCC322B67F7BC848E683AD0A27F64A') # Join the network self.lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) #pycom.rgbled(red) # Loop until joined while not self.lora.has_joined(): print('Not joined yet...') pycom.rgbled(off) time.sleep(0.1) #pycom.rgbled(red) pycom.rgbled(red) time.sleep(0.1) pycom.rgbled(green) time.sleep(0.1) pycom.rgbled(blue) time.sleep(0.1) pycom.rgbled(off) time.sleep(2) print('Joined') #pycom.rgbled(blue) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) self.s.setblocking(True) self.bytesarraytemp = bytearray(2) #sensor addr = 0x20 #or 32 self.chirp = Chirp(addr) def convertbytes(self, data): self.bytesarraytemp[0] = (data & 0xFF00) >> 8 self.bytesarraytemp[1] = (data & 0x00FF) return self.bytesarraytemp def senddata(self): while True: print("temp") print(self.chirp.temp()) count = self.s.send(tempVar + self.convertbytes(self.chirp.temp())) #print(count) print("moist") globalMoist = self.chirp.moist() print(globalMoist) count = self.s.send(moistVar + self.convertbytes(self.chirp.moist())) #print(count) print("light") print(self.chirp.light()) count = self.s.send(lightVar + self.convertbytes(self.chirp.light()))
# create an ABP authentication params dev_addr = struct.unpack(">l", binascii.unhexlify('26 01 14 7D'.replace(' ','')))[0] nwk_swkey = binascii.unhexlify('3C 74 F4 F4 0C AE A0 21 30 3B C2 42 84 FC F3 AF'.replace(' ','')) app_swkey = binascii.unhexlify('0F FA 70 72 CC 6F F6 9A 10 2A 0F 39 BE B0 88 0F'.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 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) for i in range (200): s.send(b'PKT #' + bytes([i])) time.sleep(4) rx, port = s.recvfrom(256) if rx: