LUA API Guide
For FATBOX G3 (version 2.2)
LUA interpreter version: 5.1.5
Revision log:
V2.2
>add support for Zigbee (via usb port)
>add support for multi serial port (G3 extended ports version)
>add support for timeout in serial port & sms send/receive functions V2.1
>add support for CANbus (CAN2.0A & 2.0B)
V2.0
>add support for GPS (standalone mode, non-assist)
>add support for serial port handle hex/bin data
>add support for standard Modbus master (Modbus/RTU & Modbus/TCP)
>add support for special Modbus protocol using 32-bits registers
Contents
Introduction to LUA
LUA is a powerful scripting language used in many embedded devices worldwide.
Read up more on python at www.lua.org
The LUA script interpreter is embedded into the Linux/OpenWRT operating system of the FATBOX G3.
With LUA script running, user can execute customized functions to
-
- Monitor digital input to create alarms/alerts.
-
- Manage the sending & receiving of SMS messages.
-
- Save events/data to a file in flash memory.
-
- Handle Serial RS232/485 communications with serial devices.
-
- Handle TCP/UDP communications with host or client.
First LUA Program/ Importing to the FATBOX G3
1. Open a notepad.
2. Enter the following
require "G3"
green_tick_led=53
while true do:
switch_led(green_tick_led,1)
sleep(0.2)
switch_led(green_tick_led,0)
sleep(0.2)
end
3. Save the file as ‘user.lua’ to a USB drive with label ‘FATBOX’.
Then create a folder ‘/user’ and put the file inside this folder.
Confirm the file properties is type .lua and not .txt or .text.
4. Connect the USB drive to the FATBOX G3’s USB port.
5. Login via web browser using default ETH0 port IP 192.168.1.1
6. Click ‘Download to FATBOX’ under the LUA Script Management.
7. Click ‘Execute user.lua Script’ to run the script.
8. The blinking LED on the FATBOX G3 confirms the script running
Cellular Module Functions
Reboot G3 router
reboot()
soft reboot the G3 router
Example:
require "G3"
if read_IN() then
reboot()
end
Cellular status check
cellular_status()
returns 0 if not connected to cellular network
returns 1 if connected to cellular network
Example:
require "G3"
if cellular_status() then
print ("3G OK")
end
Check cellular signal strength
check_signal(timeout_sec)
returns 0 when there is no +CSQ signal received
returns +CSQ:[n] number between 0 and 31 indicating the signal strength level
Example:
require “G3”
while true do
csq=check_signal(10) #timeout=10sec
print(csq)
ifcsq~=0 then
rssi=tonumber(string.match(csq, "%d+"))
print(rssi)
else rssi=0 end
sleep(1)
end
Cellular turn ON/OFF
cellular_off()
cellular_on()
switch on or off the cellular module.
Example:
require "G3"
if read_IN() then
cellular_on()
else:
cellular_off()
end
Pause LUA Program
sleep(x)
sleep for x seconds
Example:
require "G3"
sleep(0.5)
sleep(3)
Ping function
ping(host,interface)
returns 0 if ping failed
returns 1 if ping success
host=valid ip address or domain name eg “8.8.8.8” or “www.lua.org”
interface=”eth0”,”eth1” or omitted for default route
Example
require "G3"
ping100=ping(“192.168.1.100”,”eth0”)
ping200=ping(“10.1.1.200”,”eth1”)
pingdnsserver=ping(“8.8.8.8”)
pingdomain=ping(“www.microsoft.com”)
I/O Functions

Read position of DIP switch
read_dip(pos)
returns the DIP switch position for program selection/user feature activation.
Example:
require "G3"
if read_dip(2) then
print (“dip switch #2 read position down!”)
else:
print (“dip switch #2 read position up!”)
end
Read digital input
read_IN()
returns 0 when IN is open circuit.
returns 1 when IN is shorted to GND terminal.
Example:
require "G3"
if read_IN() then
print (“IN terminal shorted to GND!”)
else:
print (“IN terminal is open”)
end
Trigger LED output
switch_led(n,level)
switch on or off the on-board LEDs
Example:
require "G3"
while true do
switch_led(53,1)
sleep(0.2)
switch_led(53,0)
sleep(0.2)
end
Blink LED output
blink_led(n, time)
blinks the on-board LEDs for a specific time period
Example:
require "G3"
while true do
blink_led(53,0.2)
sleep(0.2)
blink_led(54,0.2)
sleep(0.2)
blink_led(51,0.2)
sleep(0.2)
blink_led(52,0.2)
end


SMS Functions
Initialize cellular module for SMS text/pdu
init_modem(mode)
mode= “sms” or “pdu”
Example:
require "G3"
init_modem(“sms”) #for sending SMS in text mode.
init_modem(“pdu”) #for sending SMS in pdu mode.
Sending SMS as normal text
sms_send(number,message,timeout_sec)
number= mobile number in international format
message= standard text limited to 160 characters (GSM 7-bit alphabet)
Example:
require "G3"
init_modem(“sms”)
number=”+6xxxxxxxxxxx”
message=”ALARM!!! Battery voltage low.”
while true do
sleep(10)
print (“DIGITAL IN = ”..read_IN())
if (read_IN()==1) then
print (“External IN triggered. ALARM sent!”)
sms_send(number,message,10) #timeout=10sec
end
end
Reading SMS as normal text
sms_read(timeout_sec)
returns 0 when there is no sms received
returns the sms message when sms is received
Example:
require "G3"
init_modem(“sms”)
repeat
sleep(10)
print (“Waiting for incoming sms...”)
msg=sms_read(60) #timeout=60sec
until msg ~=0
print (msg)
Sending SMS in PDU mode
pdu_send(length, pdu, timeout_sec)
length = Total length in octets (8bits eg. FF) excluding SMSC data.
pdu = The actual PDU data in hex form.
Example:
length = "20"
#20 >Length (decimal) of PDU data in octets (exclude SMSC info)
pdu = "0011000B911689674523F10008FF0677ED6D88606F"
#00 >SMSC, zero means use SMSC stored in phone/SIM
#11 >SMS-SUBMIT
#00 >TP-Message-Reference
#0B >Length of phone number (11)
#91 >International format for phone number
#1689674523F1 >phone number=61987654321
#00 >TP-PID
#08 >TP-DCS Data Coding Scheme 00=ASCII 04=Binary 08=UCS2(Unicode)
#FF >TP-Validity-Period
#06 >TP-User-Data-Length
#77ED6D88606F >sms message in Chinese for "Short Message"
require "G3"
init_modem(“pdu”)
while true do
sleep(10)
print ("DIGITAL IN= "..read_IN())
if (read_IN()==1) then
print "External IN triggered. PDU data sent!"
pdu_send(length,pdu,10) #timeout=10sec
end
end
Reading SMS in PDU mode
pdu_read(timeout_sec)
returns 0 when there is no PDU message received
returns the PDU message when received
Example:
require "G3"
init_modem(“pdu”)
repeat
sleep(5)
msg=pdu_read(10) #timeout=10sec
until msg ~= 0
print (msg)
Serial Port Functions
Open/close serial RS232/485
serial_open(port,baud_rate,data_bits,stop_bits,parity)
opens the serial port with defined port number, baud rate, data bits, stop bits and parity.
serial_close(port)
close the serial port with defined port number
serial_raw(port)
set serial port with defined port number to raw mode
baud_rate = 2400, 4800, 9600, 19200, 38400, 57600, 115200
data_bits = 7, 8
stop_bits = 1, 2
parity = ‘N’, ‘E’, ‘O’ (i.e. None, Even, Odd parity)
Note* : RS232 or RS485 type setup via G3 web configure.
Note**: Only available on G3 model with extended serial and usb port.
Note^ : CONSOLE is the Linux system console and not available for programming access.
Sending serial RS232/485
serial_send(port,message,timeout_sec)
Send a message in ASCII code
Example:
require "G3"
serial_open(1,115200,8,1,’NONE’) #opens port1 @115200baudrate, 8databit, 1stopbit, no parity
message="SEND MESSAGE FROM LUA\r\n"
serial_send(1,message,10) #send message via port1 with timeout=10sec
print ("send="..message)
serial_close(1) #close port1
Send a message in HEX/BIN value.
Example:
require "G3"
serial_raw(1) #set port1 to raw mode
serial_open(1,115200,8,1,’NONE’) #opens port1 @115200baudrate, 8databit, 1stopbit, no parity
hexdata=string.char[0x01,0x04,0x1A,0x2B,0x3F]
serial_send(1,hexdata,10) #send hexdata via port1 with timeout=10sec
serial_close(1) #close port1
Reading serial RS232/485
serial_read(port,end_char,timeout_sec)
end_char = return when receive the end of message character
returns None when there is no serial data received
returns serial data upon receiving end_char or upon timeout
Example (ASCII code):
require "G3"
serial_open(1,115200, 8,1,’NONE’) #opens port1 @115200baudrate, 8databit, 1stopbit, no parity
end_char="\n" #return on receiving newline char
rxstr=serial_read(1,end_char,10) #read port1, returns only upon end_char or timeout=10sec
print("serial read data = "..rxstr)
serial_close(1) #close port1
Example (HEX/BIN code):
require "G3"
serial_open(1,115200, 8,1,’NONE’) #opens port1 @115200baudrate, 8databit, 1stopbit, no parity
end_char=string.char(0x00) #return on receiving char value 0x00
rxstr=serial_read(1,end_char,10) #read port1, returns only upon end_char or timeout=10sec
byte2 = string.byte(rxstr,2) #convert non-printable char to numerical char
byte3 = string.byte(rxstr,3)
print(byte2, byte3)
serial_close(1) #close port1
serial_receive(port,length,timeout_sec)
length = serial input buffer maximum size
returns nil when there is no serial data received
returns serial data upon input buffer full or upon timeout
Example (ASCII code):
import G3
G3.serial_open(1,115200, 8,1,’N’) #opens port1 @115200baudrate, 8databit, 1stopbit, no parity
length=10 #input buffer max size
rxstr=G3.serial_receive(1,length,10) #read port1, returns only upon input buffer full or timeout=10sec
print “serial receive data = “, rxstr
G3.serial_close(1) #close port1
Example (HEX/BIN code):
import G3
G3.serial_open(1,115200, 8,1,’N’) #opens port1 @115200baudrate, 8databit, 1stopbit, no parity
length=10 #input buffer max size
rxstr=G3.serial_receive(1,length,10) #read port1, returns only upon input buffer full or timeout=10sec
byte3 = ord(rxstr[3]) #convert non-printable char to char value
byte4 = ord(rxstr[4])
print “serial receive data = ”, byte3, byte4
serial_close(1) #close port1

Modbus Master Functions
Initialize Modbus master module
init_mbm()
Function to load modbus library into memory.
This must be executed once before any Modbus function call.
Open new connection context to Modbus slave
L1=mbm.open(“rtu”, baudrate, parity, data, stop, timeout)
returns a valid context L1 (>=0)
“rtu”
= Modbus/RTU device via SERIAL port RS232/RS485
baudrate
= serial baudrate of RTU device (1200,2400,4800,9600,19200,38400,57600,115200)
parity
= serial parity of RTU device (“N”,“E”,”O”)
data
= serial data bit of RTU device (7,8)
stop
= serial stop bit of RTU device (1,2)
timeout
= response timeout (seconds)
L1=mbm.open(“tcp”, ip_address, ip_port, timeout)
returns a valid context L1 (>=0)
“tcp”
= Modbus/TCP device via ETH port ETH0/ETH1
ip_address
= IP address of Modbus device (eg “192.168.1.100”)
ip_port
= IP port of Modbus device (default 502)
timeout
= response timeout (seconds)
Connect using connection context to Modbus slave
mbm.connect(L1)
L1 = a valid connection context (>=0) from mbm.open() function
returns 0 if connection successful
returns -1 if connection failed/timeout
Read Boolean status from Modbus slave
FC=01 for read discrete coils
data_8bitTable, status = mbm.fc1(L1, node, coil_address, coil_count, timeout)
FC=02 for read discrete inputs
data_8bitTable, status = mbm.fc2(L1, node, input_address, input_count, timeout)
Write Boolean state to Modbus slave
FC=05 for write single discrete coil
status = mbm.fc5(L1, node, coil_address, coil_state, timeout)
FC=15 for write multiple coils
status = mbm.fc15(L1, node, coil_address, coil_count, timeout, data_8bitTable)
Read data registers from Modbus slave
FC=03 for read holding registers (40,001 in old Modicon convention)
data_16bitTable, status = mbm.fc3(L1, node, reg_address, reg_count, timeout)
data_32bitTable, status = mbm.fc3_32bit(L1, node, reg_address, reg_count, timeout)
FC=04 for read input registers (30,001 in old Modicon convention)
data_16bitTable, status = mbm.fc4(L1, node, reg_address, reg_count, timeout)
data_32bitTable, status = mbm.fc4_32bit(L1, node, reg_address, reg_count, timeout)
Write data registers to Modbus slave
FC=06 for write single register
status = mbm.fc6(L1, node, reg_address, data_16bit, timeout)
status = mbm.fc6_32bit(L1, node, reg_address, data_32bit, timeout)
FC=16 for write multiple registers
status = mbm.fc16(L1, node, reg_address, reg_count, timeout, data_16bitTable)
status = mbm.fc16_32bit(L1, node, reg_address, reg_count, timeout, data_32bitTable)
xxx_address
=address of first coil/input/register to be read/write
xxx_count
=number of coils/inputs/registers to be read/write
coilstate
=integer with value 0 or 1
data_16bit
=16bit unsigned integer
data_32bit
=32bit unsigned integer
data_8bitTable
=array of 8bit unsigned integer elements
data_16bitTable
=array of 16bit unsigned integer elements
data_32bitTable
=array of 32bit unsigned integer elements
L1
=a valid connection context for the Modbus device
node
=Modbus/RTU slave address
=Modbus/TCP node=1
timeout
=response timeout (seconds)
status
=returns 1 for read/write success
Turn on/off the debug messages
mbm.debug(L1,0) turn off debug message in console
mbm.debug(L1,1) turn on debug message in console
Disconnect the Modbus context
mbm.disconnect(L1)
Close the Modbus connection context L1.
Close the Modbus context
mbm.close(L1)
Close and free the Modbus connection context L1.
Example:
require “G3”
init_mbm()
ip_addr=”192.168.1.100”;ip_port=502;timeout1=10
L1 = mbm.open(“tcp”,ip_addr,ip_port,timeout1)
baud=115200;parity=”N”;data=8;stop=1;timeout2=5
L2 = mbm.open(“rtu”,baud,parity,data,stop,timeout2)
status1 = mbm.connect(L1)
status2 = mbm.connect(L2)
mbm.debug(L1,1)
mbm.debug(L2,1)
if status1==0 then
node1=1;reg_addr1=100;reg_cnt1=8
data_16bitTable1,stat1 = mbm.fc3(L1,node1,reg_addr1,reg_cnt1,timeout1)
end
if stat1==1 then
print(“mbm.fc3 test read register confirmed\r\n”)
i=0
while (i<reg_cnt1) do
i=i+1
print(data_16bitTable1[i]..”\r\n”)
end
end
if status2==0 then
node2=0xC8;reg_addr2=0x1F;reg_cnt2=0x0A
data_16bitTable2={0x111A,0x222B,0x333C,0x444D,0x555E,0x666F,0x7770,0x8881,0x9992,0x0003}
stat2 = mbm.fc16(L1,node2,reg_addr2,reg_cnt2,timeout2,data_16bitTable2)
end
if stat2==1 then
print(“mbm.fc16 test write register confirmed\r\n”)
end
mbm.disconnect(L1)
mbm.disconnect(L2)
mbm.close(L1)
mbm.close(L2)
CANBus Functions
Initialize the on-board CANbus interface (specs: CAN 2.0A/B)
can_open(baud_rate)
baud_rate = your target CANbus system baud rate eg 50000,100000,125000,250000,500000 or 1000000
Maximum CAN baudrate supported by G3 is 1Mbps.
This must be executed once before any CANbus function call.
Sending CANbus messages
can_send(canid,extended,data_send)
canid
=000-7FF (3 hex chars for CAN 2.0A (standard))
=00000000-1FFFFFFF (8 hex chars for CAN 2.0B (extended))
extended
=0 (11-bit message ID for CAN 2.0A (standard))
=1 (29-bit message ID for CAN 2.0B (extended))
data_send
=ASCII hex chars of value 1-byte (eg 1A) to 8-bytes (eg 1A2B3C4D5E6F7A8B)
Option to separate by ‘.’ , e.g. 11.22.33.44.55.66.77.88
Receiving CANbus messages
data_receive = can_receive(canid,canmask,timeout)
returns 0 when no validated CANbus message received on timeout
canid
=000-7FF (3 hex chars for CAN 2.0A (standard))
=00000000-1FFFFFFF (8 hex chars for CAN 2.0B (extended))
canmask
=000-7FF (bit value 0 mask out message)
=00000000-1FFFFFFF (bit value 0 mask out message)
timeout
=receive timeout (seconds)
Mask usage example:
canid=0x5A0, canmask=0x7FF
canid & canmask = 0x5A0
Above mask will receive message with ID 0x5A0
canid=0x280, canmask=0x280
canid & canmask = 0x280
Above mask will receive message with ID 0x280 to 0x28F.
Close the CANbus interface
can_close()
Close the CANbus interface.
Example:
require "G3"
can_open(125000) #baud rate=125000bps
sleep(0.1)
id1=”280” #canid=0x280
extended1=0 #standard mode
data1=”AABBCC” #data=0xAA,0xBB,0xCC
can_send(id1,extended1,data1)
id2="1F177678" #canid=0x1F177678
extended2=1 #extended mode
data2="11.22.33.44.55.66.77.88" #data=0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88
can_send(id2,extended2,data2)
canid={}
canmask={}
canid[1]="111";canid[2]="222";canid[3]="333";canid[4]="444";canid[5]="555" canmask[1]="7FF";canmask[2]="7FF";canmask[3]="7FF";canmask[4]="7FF";canmask[5]="7FF";
timeout=10 --seconds
while (read_IN()==1) do
can_data=can_receive(canid, canmask, timeout)
print (can_data)
end
can_close()
ZigBee Functions
zigbee_status()
returns 1 if zigbee port found
returns 0 if zigbee port not found
zigbee_open(speed)
opens the zigbee port
speed = 19200 (for Telegesis ETRX357 Zigbee adapter)
zigbee_close()
close the zigbee port
data_receive=zigbee_read(timeout_sec)
returns 0 when no Zigbee message received
timeout_sec =receive timeout (seconds)
Zigbee report attributes message comprise of ZCL header and attributes report.
Typical ZCL reporting :
RX:D55A,0104,02,0A,0702,0D:<18><F3><0A><0A><E1><21><A5><5C><43><E1><21><85><13>
Note that the attributes report with <xx> denotes the raw data value received. Eg <18>=0x18
Function zigbee_read() will convert the raw data value to ascii code. Eg <18> will be reported as “18”
RX:D55A,0104,02,0A,0702,0D:18F30A0AE121A55C43E1218513
Example:
require "G3"
if zigbee_status() then
zigbee_open(19200)
while True:
data_receive=zigbee_read(10) #timeout=10sec
until data_receive ~= 0):
print (data_receive)
zigbee_close()
else:
print (“zigbee port not found”)
end
GPS Functions
This function is using the GPS capability built into the cellular module.
The external GPS antenna (non-active type) is an optional item.
gps_start(interval)
interval = GPS positioning time interval (1-1800 seconds)
function initialize the GPS to standalone mode (non-assist) and start positioning.
gps_stop()
stops the GPS positioning routine in the wireless module
gps_read(timeout)
returns 0 when there is no gps position reported
returns a valid gps position report on every interval time after position lock-in success
timeout =receive timeout (seconds)
Example:
require "G3"
interval=10
gps_start(interval)
while (read_IN()==1) do #eg connect INPUT to engine ignition switch
sleep(1)
gps=gps_read(10) #timeout=10sec
print(gps)
end
gps_stop()
LUA Script Debug via SSH or Console (extended port version)
You can connect via SSH or CONSOLE to edit/run scripts and view debug information.
Just enable SSH (need reboot) and connect via SSH as ‘root’ and using same password as web login.
When connected, you can run your Python scripts as below example.
Eg. /# lua /user/user.lua
Note that the LUA samples are located in the folder /scripts.
Eg. /# lua /scripts/python/chkdip.lua
Setup Requirement for Specific Applications
Setup G3 router for SMS reboot application
For LUA application making use of SMS to reboot, it is recommended to disable the ‘Signal LEDs’ as shown below.
Setup G3 router for SMS online/offline application
For LUA application making use of SMS to trigger ppp online/offline, it is recommended to
-
- Disable the ‘Signal LEDs’ as shown above.
-
- Disable the ‘Reboot on Ping Failure’ as shown below.
-
- Disable the ‘Reboot on 3G Data Failure’ as shown below.

