lora.stats()
lora.wan_params()
lora.commission()
lora.join()
lora.send()
lora.recv()
lora.port_open()
lora.port_close()
lora.callback()
lora.duty_get()
lora.duty_set()
lora.duty_start()
lora.duty_stop()
lora.enable_rx_listening()
lora.disable_rx_listening()
Displays useful information about the current lora-WAN settings such as: enabled region, current working class, Device EUI DevEUI, Join EUI, current assigned DevAddr after the joined procedure, lora-wan operating version and the type of activation whether NONE, OTAA, or ABP
region
class
DevEUI
DevAddr
version
activation
NONE
OTAA
ABP
Example:
lora.stats() # outputs # - region : EU-868 # - class : class-A # - dev eui : 39 2C 39 D1 5D 3E 12 10 # - join eui : EA 68 DE 1C 4B E0 20 F4 # - dev addr : 01 88 DB B8 # - lorawan version : val: 16778240 ( 1.0.4.0 ) # - activation : OTAA
To change the current operating region and forces the device to be in class A, B or C
A
B
C
lora.wan_params(region = lora._region.REGION_EU868, lwclass = lora._class.CLASS_A) # sets the lora region to EU868 # sets the default working class to class A which is the default
To give the device its credentials, it takes the following arguments:
version=<version> to specify the end-device LoRa standard. It takes one of the following:
version=<version>
version=lora._version.VERSION_1_0_x
version=lora._version.VERSION_1_1_x
type=lora._commission.OTAA Device will be commissioned using OTAA procedure and the device shall perform the Join procedure before tx/rx with the network in this activation method, the following keys shall be provided along with:
type=lora._commission.OTAA
JoinEUI
AppKey
NwkKey
type=lora._commission.ABP The device will not perform the join procedure and it will send directly an UL message. The following parameters shall be provided:
type=lora._commission.ABP
AppSKey
NwkSKey
REMARK If the device is already joined the network, after this commissioning operation the device will not be considered joined and need to rejoin again using the new provided commissioning parameters
import lora import ubinascii # OTAA Version 1.0.x Example lora.commission( type = lora._commission.OTAA, version = lora._version.VERSION_1_0_X, DevEUI = ubinascii.unhexlify('0000000000000000'), JoinEUI = ubinascii.unhexlify('0000000000000000'), AppKey = ubinascii.unhexlify('00000000000000000000000000000000') ) # OTAA Version 1.1.x Example lora.commission( type = lora._commission.OTAA, version = lora._version.VERSION_1_1_X, DevEUI = ubinascii.unhexlify('0000000000000000'), JoinEUI = ubinascii.unhexlify('0000000000000000'), AppKey = ubinascii.unhexlify('00000000000000000000000000000000'), NwkKey = ubinascii.unhexlify('00000000000000000000000000000000') ) # ABP Version 1.0.x Example lora.commission( type = lora._commission.ABP, version = lora._version.VERSION_1_0_X, DevAddr = 0x00000000, DevEUI = ubinascii.unhexlify('0000000000000000'), AppSKey = ubinascii.unhexlify('00000000000000000000000000000000'), NwkSKey = ubinascii.unhexlify('00000000000000000000000000000000') ) # ABP Version 1.1.x Example lora.commission( type = lora._commission.ABP, version = lora._version.VERSION_1_1_X, DevAddr = 0x00000000, DevEUI = ubinascii.unhexlify('0000000000000000'), AppSKey = ubinascii.unhexlify('00000000000000000000000000000000'), NwkSKey = ubinascii.unhexlify('00000000000000000000000000000000') )
Mandator operation to let the device join the network and be able to TX/RX with the lora-WAN server
import lora import time # start join procedure lora.join() # wait until join while lora.is_joined() == False: time.sleep(2) pass
To plan an UL message. It takes the following parameters:
message
config
port
retries
timeout
no-timeout
sync
id
# send an asynchronous UL message, with id=0, and without confirmation, no retries # upon tx failure, and no specified timeout which means the message will be # scheduled for UL in its turn within the pending UL messages until the duty-cycle # tx operation fetches it and send it lora.send('ul tx message') # send a message like before message, but if timeout of 3 seconds passed, # drop the message and don't send it lora.send('ul tx message', timeout=3000) # repeat the transmission for upto 2 times, the full operation timeout including # the retries attempts is 20 seconds lora.send('ul tx message', timeout=20000, retries=2) # same as before message but wait for confirmation as well from the network server lora.send('ul tx message', timeout=20000, retries=2, confirm=True) # same as the previous message, but the caller will be blocked until timeout, # or message is successfully sent and acked lora.send('ul tx message', timeout=20000, retries=2, confirm=True, sync=True)
The received data will come in the callback only
LoRa WAN sends/receives data over what is called ports, valid application ports are from 1 to 223.
ports
1
223
A port must be opened first before sending and receiving data over it
# opening port 1 lora.port_open(1) # data can be tx/rx over port 1 lora.send('any', port=5) # ignored because port 5 is not opened lora.send('any', port=1) # will be planned successfully for UL # opening port 1 lora.port_open(5) # data can be tx/rx over port 5 lora.send('any', port=5) # now it will be planned successfully lora.port_close(1) # no tx/rx more over this port lora.port_close(5) # no tx/rx more over this port
It can set a user lever callback and it takes the following parameters:
any
def get_evt_str(evt): if evt != None: if evt == lora._event.EVENT_TX_DONE: return 'EVENT_TX_DONE' elif evt == lora._event.EVENT_TX_TIMEOUT: return 'EVENT_TX_TIMEOUT' elif evt == lora._event.EVENT_TX_FAILED: return 'EVENT_TX_FAILED' elif evt == lora._event.EVENT_TX_CONFIRM: return 'EVENT_TX_CONFIRM' elif evt == lora._event.EVENT_RX_DONE: return 'EVENT_RX_DONE' elif evt == lora._event.EVENT_RX_TIMEOUT: return 'EVENT_RX_TIMEOUT' elif evt == lora._event.EVENT_RX_FAIL: return 'EVENT_RX_FAIL' return '--UNKNOWN-EVENT--' def cb_on_any(event, evt_data): print('( cb_on_any )--> event: ' + get_evt_str(event)) if evt_data != None: print(evt_data) pass def cb_on_port_1(event, evt_data): print('( cb_on_port_1 )--> event: ' + get_evt_str(event)) if evt_data != None: print(evt_data) pass port_1_triggers = lora._event.EVENT_RX_DONE | lora._event.EVENT_TX_DONE lora_unittest.test_callback_set(handler=cb_on_port_1, trigger=port_1_triggers, port=1) lora_unittest.test_callback_set(handler=cb_on_any) lora_unittest.test_gen_all_callbacks()
The device is normally working in class-A and the device shall follow a duty-cycle to do UL/DL operation. This duty cycle should be regulated to respect the time-on-air for this device.
The available operation are duty_set(), duty_get(), duty_start(), duty_stop()
duty_set()
duty_get()
duty_start()
duty_stop()
lora.duty_set(15000) # sets the duty cycle timer to 15 seconds # which means that every 15 seconds the device will check # if TX pending and send it, and listen in the RX window # to any scheduled DL message for this device lora.duty_get() # retrieve the current duty cycle time lora.duty_start() # start duty cycle operation lora.duty_stop() # stop duty cycle operation
RX listening means that the device will send a dummy UL message in case no pending TX message is pending, so that the server will plan an RX window for this device and hence the device can receive any pending DL message
the default behaviour is that the RX listening is disabled
lora.enable_rx_listening() # enable listening lora.disable_rx_listening() # disable listening # the device will listen only when there is a real # planned UL TX message