Common
General Functions
This category contains functions that are used for all devices.
| API Name | Brief Description |
|---|---|
| api.ledControl(state, timeout, period, offState, pattern, Ts, patternTimeout) | Turns ON or OFF the on board LED. |
| api.delayms(ms,mode) | Pauses the execution for ms milliseconds. |
| api.randInt(min, max) | Generates random number within given range. |
| api.getUniqueNumber() | Generates unique number. |
| api.getBatteryVoltage() | Returns the current voltage level of the battery in mV. |
| api.getTick(clock, reset) | Returns current number of milliseconds since startup. |
| api.dumpArray(str,opt) | Prints contents of variable as hexadecimal string (dumps array into console). |
| api.float() | Performs operation with given floating point data. Multiple variants. See below. |
| api.setVar() | Saves a persistent variable value. Multiple variants. See below. |
| api.getVar() | Returns persistent variable value. Multiple variants. See below. |
| api.wakeUpAt(day, hour, minute, second, resetOnFail) | Schedules the next wake up event of the device to provided day of month, hour, minute and second. |
| api.wakeUpIn(day, hour, minute, second, resetOnFail, milisecond) | Schedules the next wake up event of the device after specified time interval. |
| api.getTimeDate(timezoneShift) | Returns current date and time set on this device. |
| api.setTimeDate() | Set date and time on this device, or calculate the difference and synchronize the date and time. Multiple variants. See below. |
| api.voltageSourceState() | Controls voltage source. Multiple variants. See below. |
| api.stdin() | Reads stdin (standard input) data or control button (get status, wait for button). Multiple variants. See below. |
| api.stdout(out, size, offset) | Writes to stdout (standard output) without adding line termination. |
| api.bsprintf(binData, format, offset, endian) | Formats binary stream data according to various format specifiers, including support for characters, integers, short and long integers, floats, and doubles. |
| api.setVerbosity() | Controls the number of messages printed to the serial line. Multiple variants. See below. |
| api.exec() | Executes a system command or Lua fragment. Multiple variants. See below. |
| api.table() | Interface to create and manipulate memory-efficient tables and maps. Multiple variants. See below. |
| api.aes(operation, data, iv, key) | Encrypts or decrypts provided payload using a key and IV with AES-CTR. |
api.ledControl(state, timeout, period, offState, pattern, Ts, patternTimeout)
api.ledControl(1) --turn on the LED
Controls the device’s blue LED. Supports solid on/off, duty-cycled blinking via (timeout, period), and custom patterns with optional timeouts.
Arguments
- state (integer): Applied immediately every call.
1for ON.0for OFF.
Optional
- timeout (integer, optional, default:
-1): The amount of time, that LED turns on for in miliseconds. After said amount, LED turns off. - period (integer, optional, default:
-1): Length of one full cycle when using simple blinking. On each cycle edge, the LED turns tostate(typically ON) and stays ON fortimeoutbefore turning OFF for the remainder of the period.-1disables simple blinking. - offState (integer, optional, default:
-2): What value the driver treats as “off.” Only updates if you pass a value other than-2. - pattern (string or
nil, optional, default:nil): Pattern to play; overrides and clears current simple blinking (period/timeout). Passnil(or omit) to stop any running pattern. - Ts (integer, optional, default:
50): Tick duration for pattern stepping (each pattern character lastsTsunits). - patternTimeout (integer, optional, default:
-1): Total time to run the pattern before stopping pattern stepping.-1disables pattern timeout.
Simple blinking (duty cycle)
When period >= 0 (and no pattern is active), the LED cycles as follows:
- Every time the period elapses, the driver reloads both timers and sets the LED to the
statevalue (LEDblue(ledOnState)). - The
timeoutthen counts down. When it reaches zero, the LED is forced to off (LEDblue(ledOffState)). - The LED remains off until the next period edge, when step 1 repeats.
This means the effective duty cycle is approximately:
duty = timeout / period (same time base).
All counters are decremented by the LED tick; in many builds this is one millisecond, but treat these as driver ticks unless specified.
Pattern mode
Providing a pattern cancels any existing pattern and clears simple blinking/timeout. The LED is then driven by the pattern engine. Each pattern character lasts Ts ticks.
Supported characters (from the driver):
H— Force LED on (LEDblue(1))L— Force LED off (LEDblue(0))ZorF— High‑impedance / special off (LEDblue(-1))0..9— PWM-like brightness levels in tenths (0–9). Digits use the simple blinking engine under the hood with a fixed base period of 10 ticks and an ON‑time equal to the digit value in ticks. Concretely: the driver setsperiod = 10,timeout = digit, starts from OFF, and lets the period/timeout logic generate a duty cycle ≈digit/10.
Additional details:
- The pattern wraps when it reaches the end.
- If
patternTimeoutis set (not-1), a running total increases byTsafter each character step. When it reaches or exceedspatternTimeout, the pattern engine stops stepping (internal timers are zeroed and the position resets). The LED remains in whichever state the last step left it in until anotherapi.ledControl(...)call changes it.
Behavior & precedence
stateis applied immediately every call.- If
patternis provided: previous pattern is freed; simpleperiod&timeoutare cleared; pattern controls the LED. Digits within the pattern temporarily enable the duty‑cycle engine withperiod=10andtimeout=digitto emulate brightness. - If
patternis not provided and a pattern was running, that pattern is stopped and simple blinking is cleared. - If
period >= 0(and no pattern), the duty‑cycle behavior runs usingtimeoutandperiodas described above. offStateonly updates when a value other than-2is passed.
All time values (
timeout,period,Ts,patternTimeout) are measured in the driver’s tick unit; many targets wire this to milliseconds.
Example
api.ledControl(1) -- LED is turned on, needs to be turned off, else it shines indefinitely
api.ledControl(0) -- LED is turned off
api.ledControl(1,500) -- LED blinks once for half a second
led(1,0,0,0,"L123456789H987654321LLLLL", 50) -- LED Blinking on lower intensity
api.ledControl(1, 0, 0, 0, "H9L1", 50, 3000) -- LED Blinking on lower intensity for three seconds, than stays on on lower intensity
api.delayms(ms, mode)
api.delayms(1000) -- Delay one second
Pauses execution of code for a specified number of milliseconds.
Arguments
- ms (integer): Number of milliseconds to delay (0 to 2,147,483,647).
Optional
- mode (integer, optional): Use sleep for longer intervals:
1: Sleep if interval is longer than 10 ms.2: Sleep for the defined milliseconds.
Example
-- Delay one second
api.delayms(1000)
--------------------------------
-- Turn on blue LED, wait 1 second, then turn off
api.ledControl(1)
api.delayms(1000)
api.ledControl(0)
--------------------------------
-- Sleep for one second, then continue
api.delayms(1000, 2)
api.randInt(min, max)
api.randInt(5, 20) -- Generates a random number between 5 and 20
Generates and returns a random number within a specified range.
Note: LoRaWAN devices generate this number via a module, whereas other device use pseudorandom generation – this has in practicality little impact. You may also use native Lua function math.random(min, max) for the same purpose.
Arguments
- min (integer): Start of the range (0 to 2,147,483,647).
- max (integer): End of the range (0 to 2,147,483,647).
Return
- number (integer): Random number within the specified range.
Example
-- Generates a random number between curLow and curHigh variables
ran = api.randInt(curLow, curHigh)
api.getUniqueNumber()
api.getUniqueNumber() -- Get a unique number
Generates and returns a unique number (int32).
Info: Increments a uint32_t variable by one each time the function is called and returns its value (0 to 2^32).
Return
- num (integer): Unique number (0 to 2^32).
Example
-- Get a unique number
num = api.getUniqueNumber()
api.getBatteryVoltage()
api.getBatteryVoltage() -- Return battery voltage value in mV
Returns the current battery voltage level in millivolts (mV).
Return
- voltage (integer): Battery voltage level in mV.
Example
-- Get battery voltage value in mV
mv = api.getBatteryVoltage()
--------------------------------
-- Function that prints all the information upon booting, includes battery voltage
function bootMessage (joinMethod, rxTimeout, port)
local sysinfo = ex("_sysinfo")
model = sysinfo["model"]["name"]
sn = sysinfo["SN"]
fwma = sysinfo["ver"]["major"]
fwmi = sysinfo["ver"]["minor"]
fwbf = sysinfo["ver"]["bugfix"]
local battVol = api.getBatteryVoltage()
local cpuTemp = ex("_cpu_temp")
local bootMsg = model .. b(0) .. pp("<i", sn) .. b(fwma) .. b(fwmi) .. b(fwbf) .. ver .. pp("<i", battVol) .. b(cpuTemp)
local msgPrint = "Model: " .. model .. ", Serial number: " .. sn .. ", FW version: " .. fwma .. "." .. fwmi .. "." .. fwbf .. ", Script version: " .. ver .. ", Battery voltage: " .. battVol .. " mV, CPU temperature: " .. cpuTemp .. " C"
print(msgPrint)
api.getTick(clock, reset)
api.getTick() -- Read uptime in ms
Returns the current uptime tick.
clockselects the source and units.- Values are masked to 31 bits (
& 0x7FFFFFFF) to stay positive in Lua. - Default is an RTC-derived tick that keeps counting in sleep.
In most builds,
clock = 3returns two values: seconds and milliseconds. In specialSPEEDUP_256xbuilds,clock = 3returns a single millisecond tick (same masking rules as other single-value variants).
Arguments
Optional
- clock (integer, optional):
3: Use SysTick; returns seconds, milliseconds (two values; see note above forSPEEDUP_256x).2: Use RTC-derived tick; returns seconds.1: Use RTC-derived tick; returns milliseconds (default).0: Use SysTick; returns milliseconds.
- reset (integer, optional; applies to
clock = 0andclock = 3):1: Reset the SysTick base (internally setsuwTick = 1).0: Do not reset (default).
Return
- For
clock = 1or0: tick (integer, milliseconds; masked to 31 bits). - For
clock = 2: tick (integer, seconds; masked to 31 bits). - For
clock = 3:- seconds, milliseconds (two integers; each masked to 31 bits), or
- tick (single integer, milliseconds; masked) if built with
SPEEDUP_256x.
Example
-- Default: RTC-based milliseconds (masked to 31 bits)
local ms = api.getTick()
--------------------------------
-- RTC-based seconds
local s = api.getTick(2)
--------------------------------
-- SysTick milliseconds
local ms_systick = api.getTick(0)
--------------------------------
-- SysTick seconds + milliseconds (two returns in normal builds)
local seconds, millis = api.getTick(3)
--------------------------------
-- Reset SysTick base, then read ms
api.getTick(0, 1)
local ms_after_reset = api.getTick(0)
--------------------------------
-- Reset SysTick base, then read split seconds/ms (normal builds)
api.getTick(3, 1)
local sec2, ms2 = api.getTick(3)
--------------------------------
-- Onwake function using getTick to make sure time is correct
function onWake()
print("Periodic wake up - send a ping, that we are alive")
processInputs()
api.setVar(1, api.getTick()) -- update also the timestamp
end
api.dumpArray(str, opt)
api.dumpArray("123ef") -- Print as hex
Prints the contents of a variable as a hexadecimal string (dumps array into console).
Arguments
- str (string): Variable to print.
Optional
- opt (string, optional): Defines the type of print:
"normal": Default printing method."raw": Prints only raw values."return": Returns the hex string.
Example
-- Print string "123ef" as hexadecimal
api.dumpArray("123ef")
-- Output: 00 : 31 32 33 65 66
--------------------------------
-- Print string "123ef" as hexadecimal raw
api.dumpArray("123ef", "raw")
-- Output: 31 32 33 65 66
--------------------------------
-- Return string "123ef" as hexadecimal string
ret = api.dumpArray("123ef", "return")
--------------------------------
-- Example of how a detected error may be turned into HEX before sending via LoRaWAN
txbuf = txbuf .. pack.pack("<I2", directState, detectedError)
api.dumpArray(txbuf)
acked = api.loraSend(useAcking, 6000, txbuf, port)
api.float()
Performs operation with given floating point data. Note that float operations are disabled by default. In order to use these, please request a custom version of firmware.
| API Name | Brief Description |
|---|---|
| api.float("add", form, arg1, arg2) | Performs addition of arg1 and arg2 with given floating point data. Only available if allowed by the firmware. |
| api.float("sub", form, arg1, arg2) | Performs subtraction of arg2 from arg1 with given floating point data. Only available if allowed by the firmware. |
| api.float("mul", form, arg1, arg2) | Performs multiplication of arg1 and arg2 with given floating point data. Only available if allowed by the firmware. |
| api.float("div", form, arg1, arg2) | Performs division of arg1 by arg2 with given floating point data. Only available if allowed by the firmware. |
| api.float("coerce", form, arg1) | Performs coercion of arg1 with given floating point data (unary operation). Only available if allowed by the firmware. |
| api.float("convert", form, arg1) | Performs conversion of integer to float for arg1 with given floating point data (unary operation). Only available if allowed by the firmware. |
api.float("add", form, arg1, arg2)
api.float("add", "SSS", "12.8", "1000.0") -- add
Performs addition of arg1 and arg2 with given floating-point data.
Warning: Only available if allowed by the firmware.
Arguments
-
"add" (string, command): command for addition.
❗command - the argument needs to have this exact form❗ -
form (string): Two or three characters specifying input/output data format:
"B": Binary."S": String."I": Integer."N": Little endian integer.- First position: Format for
arg1. - Second position: Format for
arg2or return data. - Optional
"N": Coerces and returns little endian integer.
-
arg1 (string): First operation argument, formatted as specified.
-
arg2 (string): Second operation argument, formatted as specified.
Return
- result (string or integer): Result of the operation, either 4-byte little/big endian IEEE 754 float, string float representation, or integer value.
Example
-- Add two string float representations
ret = api.float("add", "SSS", "12.8", "1000.0")
print(ret)
-- Output: 1012.8000
api.float("sub", form, arg1, arg2)
api.float("sub", "SSS", "1000.0", "12.8") -- subtract
Performs subtraction of arg2 from arg1 with given floating-point data.
Warning: Only available if allowed by the firmware.
Arguments
-
"sub" (string, command): command for subtraction.
❗command - the argument needs to have this exact form❗ -
form (string): Two or three characters specifying input/output data format:
"B": Binary."S": String."I": Integer."N": Little endian integer.- First position: Format for
arg1. - Second position: Format for
arg2or return data. - Optional
"N": Coerces and returns little endian integer.
-
arg1 (string): First operation argument, formatted as specified.
-
arg2 (string): Second operation argument, formatted as specified.
Return
- result (string or integer): Result of the operation, either 4-byte little/big endian IEEE 754 float, string float representation, or integer value.
Example
-- Subtract two string float representations
ret = api.float("sub", "SSS", "1000.0", "12.8")
print(ret)
-- Output: 987.2000
api.float("mul", form, arg1, arg2)
api.float("mul", "SSS", "12.8", "1000.0") -- multiply
Performs multiplication of arg1 and arg2 with given floating-point data.
Warning: Only available if allowed by the firmware.
Arguments
-
"mul" (string, command): Command for multiplication.
❗command - the argument needs to have this exact form❗ -
form (string): Two or three characters specifying input/output data format:
"B": Binary."S": String."I": Integer."N": Little endian integer.- First position: Format for
arg1. - Second position: Format for
arg2or return data. - Optional
"N": Coerces and returns little endian integer.
-
arg1 (string): First operation argument, formatted as specified.
-
arg2 (string): Second operation argument, formatted as specified.
Return
- result (string or integer): Result of the operation, either 4-byte little/big endian IEEE 754 float, string float representation, or integer value.
Example
-- Multiply IEEE 754 float with a floating-point constant and return coerced value
ret = api.float("mul", "SSN", "12.8", "1000.0")
print(ret)
-- Output: 12800
--------------------------------
ret = api.float("mul", "SSS", "12.8", "1000.0")
print(ret)
-- Output: 12800.0000
--------------------------------
-- Hexadecimal interpretation of 12.8 is 0x414CCCCD (IEEE 754)
x = string.char(0xCD, 0xCC, 0x4C, 0x41)
ret = api.float("mul", "BSS", x, "1000.0")
print(ret)
-- Output: 12800.0000
api.float("div", form, arg1, arg2)
api.float("div", "SSS", "12800.0", "1000.0") -- divide
Performs division of arg1 by arg2 with given floating-point data.
Warning: Only available if allowed by the firmware.
Arguments
-
"div" (string, command): Command for division.
❗command - the argument needs to have this exact form❗ -
form (string): Two or three characters specifying input/output data format:
"B": Binary."S": String."I": Integer."N": Little endian integer.- First position: Format for
arg1. - Second position: Format for
arg2or return data. - Optional
"N": Coerces and returns little endian integer.
-
arg1 (string): First operation argument, formatted as specified.
-
arg2 (string): Second operation argument, formatted as specified.
Return
- result (string or integer): Result of the operation, either 4-byte little/big endian IEEE 754 float, string float representation, or integer value.
Example
-- Divide two string float representations
ret = api.float("div", "SSS", "12800.0", "1000.0")
print(ret)
-- Output: 12.8000
api.float("coerce", form, arg1)
api.float("coerce", "SS", "12.8") -- coerce to float
Performs coercion of arg1 with given floating-point data (unary operation).
Warning: Only available if allowed by the firmware.
Arguments
-
"coerce" (string, command): Command for coercion.
❗command - the argument needs to have this exact form❗ -
form (string): Two or three characters specifying input/output data format:
"B": Binary."S": String."I": Integer."N": Little endian integer.- First position: Format for
arg1. - Second position: Format for return data.
- Optional
"N": Coerces and returns little endian integer.
-
arg1 (string): Operation argument, formatted as specified.
Return
- result (string or integer): Result of the operation, either 4-byte little/big endian IEEE 754 float, string float representation, or integer value.
Example
-- Coerce a string float representation
ret = api.float("coerce", "SS", "12.8")
print(ret)
-- Output: 12.8000
api.float("convert", form, arg1)
api.float("convert", "NB>", 125) -- int to IEEE754 bytes
Performs conversion of integer to float for arg1 with given floating-point data (unary operation).
Warning: Only available if allowed by the firmware.
Arguments
-
"convert" (string, command)
❗command - the argument needs to have this exact form❗ -
form (string): Two or three characters specifying input/output data format:
"B": Binary."S": String."I": Integer."N": Little endian integer.- First position: Format for
arg1. - Second position: Format for return data.
- Optional
"N": Coerces and returns little endian integer.
-
arg1 (string): Operation argument, formatted as specified.
Return
- result (string or integer): Result of the operation, either 4-byte little/big endian IEEE 754 float, string float representation, or integer value.
Example
-- Convert integer to IEEE 754 float
y = string.char(0xCD, 0xCC, 0x4C, 0x42)
ret = api.float("convert", "IB", y)
api.dumpArray(ret)
-- Output: 9A 99 84 4E
--------------------------------
y = 125
ret = api.float("convert", "NB>", y)
api.dumpArray(ret)
-- Output: 42 FA 00 00
api.setVar()
| API Name | Description |
|---|---|
| api.setVar(index, value, bool) | Stores an integer value (0 to 2147483647) at the specified index (0-15 for RAM, 16-47 for HEE, 48-1071 for EEPROM), with optional bitwise negation at the next address. |
| api.setVar(index, mode, value) | Stores a string array buffer at the specified index (0-15 for RAM, 16-47 for HEE, 48-1071 for EEPROM) using the specified memory mode ("bytes" supported). |
api.setVar(index, value, bool)
api.setVar(1000, 3424) -- store number
Stores an integer value (0 to 2,147,483,647) at the specified index (0-15 for RAM, 16-47 for HEE, 48-1071 for EEPROM), with optional bitwise negation at the next address.
Info: Can be used between different wake-up iterations.
Arguments
- index (integer): Index of the variable to write:
0to15: RAM variables (lost on reset).16to47: High Endurance EEPROM (HEE) variables (6.4M writes).48to1071: EEPROM variables (100k writes).
- value (integer): Value to store (0 to 2,147,483,647).
Optional
- bool (boolean, optional): Stores bitwise negation of the value at the next address.
Example
-- Set persistent variable at index 1000 to 3424
api.setVar(1000, 3424)
-- get and format S0 inputs
function getS0Data()
s01 = api.S0readCounter(1)
print("S0-1: "..tostring(s01))
s02 = api.S0readCounter(2)
print("S0-2: "..tostring(s02))
-- read old values
s01_l = api.getVar(16)
s02_l = api.getVar(17)
s01_ll = api.getVar(20)
s02_ll = api.getVar(21)
-- update old values
api.setVar(16, s01)
api.setVar(17, s02)
api.setVar(20, s01_l)
api.setVar(21, s02_l)
api.setVar(index, mode, value)
api.setVar(30, "bytes", "Hello") -- store bytes
Stores a string array buffer at the specified index (0-15 for RAM, 16-47 for HEE, 48-1071 for EEPROM) using the specified memory mode ("bytes" supported).
Info: Can be used between different wake-up iterations.
Arguments
- index (integer): Index of the variable to write:
0to15: RAM variables (lost on reset).16to47: High Endurance EEPROM (HEE) variables (6.4M writes).48to1071: EEPROM variables (100k writes).
- mode (string): Explicit memory mode, currently supports
"bytes". - value (string): String array buffer to write.
Example
-- Store a string in EEPROM
myVariable = "This is some string to store to eeprom"
api.setVar(29, #myVariable) -- Save the length
api.setVar(30, "bytes", myVariable) -- Consumes ceil(#myVariable / 4) 32-bit indexes
--------------------------------
-- Stores a default list of primary addresses
api.setVar(32, "bytes", defaultListOfPrimaryAddresses)
api.setVar(30, #defaultListOfPrimaryAddresses, true)
listOfPrimaryAddresses = defaultListOfPrimaryAddresses
api.getVar()
Schedules the next wake up event of the device to provided day of month, hour, minute and second.
| API Name | Brief Description |
|---|---|
| api.getVar(index, default) | Returns an integer value from the specified index (0-15 for RAM, 16-47 for HEE, 48-1071 for EEPROM), returning the default value if the stored value matches the bitwise negation of the next address. |
| api.getVar(index, mode, length) | Returns a string array buffer of specified length from the index (0-15 for RAM, 16-47 for HEE, 48-1071 for EEPROM) using the specified memory mode ("bytes" supported). |