class LoRa
This class provides a driver for the LoRa network processor in the LoPy. Below is an example demonstrating LoRaWAN Activation by Personalisation usage:
from network import LoRa
import socket
import binascii
import struct
# Initialize LoRa in LORAWAN mode.
lora = LoRa(mode=LoRa.LORAWAN)
# create an ABP authentication params
dev_addr = struct.unpack(">l", binascii.unhexlify('00 00 00 05'.replace(' ','')))[0]
nwk_swkey = binascii.unhexlify('2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C'.replace(' ',''))
app_swkey = binascii.unhexlify('2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C'.replace(' ',''))
# 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, 5)
# make the socket non-blocking
s.setblocking(False)
# send some data
s.send(bytes([0x01, 0x02, 0x03]))
# get any data received...
data = s.recv(64)
print(data)
Please ensure that there is an antenna connected to your device before sending/receiving LoRa messages as inproper use (e.g. without an antenna), may damage the device.
Additional Examples
For various other complete LoRa examples, check here for additional examples.
Constructors
Create and configure a LoRa object. See init for params of configuration.
lora = LoRa(mode=LoRa.LORAWAN)
Methods
This method is used to set the LoRa subsystem configuration and to specific raw LoRa or LoRaWAN.
The arguments are:
modecan be eitherLoRa.LORA orLoRa.LORAWAN .frequencyaccepts values between 863000000 and 870000000 in the 868 band, or between 902000000 and 928000000 in the 915 band.tx_poweris the transmit power in dBm. It accepts between 2 and 14 for the 868 band, and between 5 and 20 in the 915 band.bandwidthis the channel bandwidth in KHz. In the 868 band the accepted values areLoRa.BW_125KHZ andLoRa.BW_250KHZ . In the 915 band the accepted values areLoRa.BW_125KHZ andLoRa.BW_500KHZ .sfsets the desired spreading factor. Accepts values between 7 and 12.preambleconfigures the number of pre-amble symbols. The default value is 8.coding_ratecan take the following values:LoRa.CODING_4_5 ,LoRa.CODING_4_6 ,LoRa.CODING_4_7 orLoRa.CODING_4_8 .power_modecan be eitherLoRa.ALWAYS_ON ,LoRa.TX_ONLY orLoRa.SLEEP . InALWAYS_ON mode, the radio is always listening for incoming - packets whenever a transmission is not taking place. InTX_ONLY the radio goes to sleep as soon as the transmission completes. InSLEEP mode the radio is sent to sleep permanently and won’t accept any commands until the power mode is changed.tx_iqenables TX IQ inversion.rx_iqenables RX IQ inversion.adrenables Adaptive Data Rate.publicselects between the public and private sync word.tx_retriessets the number of TX retries inLoRa.LORAWAN mode.device_classsets the LoRaWAN device class. Can be eitherLoRa.CLASS_A orLoRa.CLASS_C .
In adr, public, tx_retries and device_class are used. All the other params will be ignored as they are handled by the LoRaWAN stack directly. On the other hand, in adr, tx_retries and device_class are ignored since they are only relevant to the LoRaWAN stack.
For example, you can do:
# initialize in raw LoRa mode
lora.init(mode=LoRa.LORA, tx_power=14, sf=12)
or:
# initialize in LoRaWAN mode
lora.init(mode=LoRa.LORAWAN)
Join a LoRaWAN network. The parameters are:
activation: can be eitherLoRa.OTAA orLoRa.ABP .auth: is a tuple with the authentication data.
In the case of app_eui, app_key). Example:
from network import LoRa
import socket
import time
import binascii
# Initialize LoRa in LORAWAN mode.
lora = LoRa(mode=LoRa.LORAWAN)
# create an OTAA authentication parameters
app_eui = binascii.unhexlify('AD A4 DA E3 AC 12 67 6B'.replace(' ',''))
app_key = binascii.unhexlify('11 B0 28 2A 18 9B 75 B0 B4 D2 D8 C7 FA 38 54 8B'.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...')
In the case of dev_addr, nwk_swkey, app_swkey). Example:
from network import LoRa
import socket
import binascii
import struct
# Initialize LoRa in LORAWAN mode.
lora = LoRa(mode=LoRa.LORAWAN)
# create an ABP authentication params
dev_addr = struct.unpack(">l", binascii.unhexlify('00 00 00 05'.replace(' ','')))[0]
nwk_swkey = binascii.unhexlify('2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C'.replace(' ',''))
app_swkey = binascii.unhexlify('2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C'.replace(' ',''))
# join a network using ABP (Activation By Personalization)
lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
Get or set the bandwidth in raw LoRa mode (
# get raw LoRa Bandwidth
lora.bandwidth()
# set raw LoRa Bandwidth
lora.bandwidth(LoRa.BW_125KHZ)
Get or set the frequency in raw LoRa mode (
# get raw LoRa Frequency
lora.frequency()
# set raw LoRa Frequency
lora.frequency(868000000)
lora.coding_rate([coding_rate])
Get or set the coding rate in raw LoRa mode (LoRa.LORA). The allowed values are:
# get raw LoRa Coding Rate
lora.coding_rate()
# set raw LoRa Coding Rate
lora.coding_rate(LoRa.CODING_4_5)
Get or set the number of preamble symbols in raw LoRa mode (
# get raw LoRa preamble symbols
lora.preamble()
# set raw LoRa preamble symbols
lora.preamble(LoRa.CODING_4_5)
Get or set the spreading factor value in raw LoRa mode (
# get raw LoRa spread factor value
lora.sf()
# set raw LoRa spread factor value
lora.sf(7)
Get or set the power mode in raw LoRa mode (
Return a named tuple with useful information from the last received LoRa or LoRaWAN packet. The named tuple has the following form:
(rx_timestamp, rssi, snr, sftx, sfrx, tx_trials)
Example:
lora.stats()
Where:
rx_timestampis an internal timestamp of the last received packet with microseconds precision.rssiholds the received signal strength in dBm.snrcontains the signal to noise ratio id dB.sfrxtells the data rate (in the case of LORAWAN mode) or the spreading factor (in the case of LORA mode) of the last packet received.sftxtells the data rate (in the case of LORAWAN mode) or the spreading factor (in the case of LORA mode) of the last packet transmitted.tx_trialsis the number of tx attempts of the last transmitted packet (only relevant for LORAWAN confirmed packets).
Returns True if a LoRaWAN network has been joined. False otherwise.:
Add a LoRaWAN channel on the specified index. If there’s already a channel with that index it will be replaced with the new one.
The arguments are:
index: Index of the channel to add. Accepts values between 0 and 15 for EU and between 0 and 71 for US.frequency: Centre frequency in Hz of the channel.dr_min: Minimum data rate of the channel (0-7).dr_max: Maximum data rate of the channel (0-7).
Examples:
lora.add_channel(index=0, frequency=868000000, dr_min=5, dr_max=6)
Removes the channel from the specified index. On the 868MHz band the channels 0 to 2 cannot be removed, they can only be replaced by other channels using the lora.add_channel method. A way to remove all channels except for one is to add the same channel, 3 times on indexes 0, 1 and 2. An example can be seen below:
lora.remove_channel()
On the 915MHz band there are no restrictions around this.
Returns a byte object with the 8-Byte MAC address of the LoRa radio.
Specify a callback handler for the LoRa radio. The trigger types are
The ack is received. If the ack is not received tx_retries configured have been performed.
An example of how this callback functions can be seen the in method
This method is used to check for radio activity on the current LoRa channel, and if the rssi of the measured activity is lower than the rssi_threshold given, the return value will be True, otherwise False. Example:
lora.ischannel_free(-100)
Set the battery level value that will be sent when the LoRaWAN MAC command that retrieves the battery level is received. This command is sent by the network and handled automatically by the LoRaWAN stack. Value should be in percentage, from 0 to 100. Values larger than 100 will be clipped:
lora.set_battery_level(75)
This method returns a value with bits sets (if any) indicating the events that have triggered the callback. Please note that by calling this function the internal events registry is cleared automatically, therefore calling it immediately for a second time will most likely return a value of 0.
Example:
def lora_cb(lora):
events = lora.events()
if events & LoRa.RX_PACKET_EVENT:
print('Lora packet received')
if events & LoRa.TX_PACKET_EVENT:
print('Lora packet sent')
lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=lora_cb)
Constants
Working with LoRa and LoRaWAN Sockets
LoRa sockets are created in the following way:
import socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
And they must be created after initialising the LoRa network card.
LoRa sockets support the following standard methods from the socket module:
Usage:
s.close()
Usage:
s.bind(1)
The
Usage:
s.send(bytes([1, 2, 3]))
or:
s.send('Hello')
Usage:
s.recv(128)
Set the value of the given socket option. The needed symbolic constants are defined in the socket module (SO_* etc.). In the case of LoRa the values are always integers. Examples:
# configuring the data rate
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
# selecting non-confirmed type of messages
s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False)
# selecting confirmed type of messages
s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, True)
Socket options are only applicable when the LoRa radio is used in
Sets the socket timeout value in seconds. Accepts floating point values.
Usage:
s.settimeout(5.5)
Usage:
s.setblocking(True)