Python 3 Lite
Introduction
The Python 3 Lite Router App provides a lightweight Python 3 runtime optimized for Advantech routers with limited resources or where minimal footprint is critical. Once installed, Python enables:
- Automation of router management tasks.
- Custom data collection and analysis directly at the edge.
- Log parsing, basic device monitoring, and straightforward automation scripts.
Compared to the full Python 3 Router App, this version has a reduced feature set:
| Feature | Python 3 Lite | Python 3 |
|---|---|---|
| Python version | 3.x | 3.x |
pip package installer | — | ✓ |
venv virtual environments | — | ✓ |
hashlib | Pure-Python | Native (faster) |
| UNICODE support | Limited | Full |
| Resource usage | Lower | Higher |
The Python 3 Lite Router App is best suited for simple scripting tasks where minimal system impact and resource usage are paramount. For complex development work, pip-managed dependencies, or isolated virtual environments, use the full Python 3 Router App instead.
Installation
Prerequisites
Before installing, ensure:
- Sufficient storage space: Even the lightweight Python runtime requires storage. Check available disk space on the Router Apps page of the router's web interface.
Installation Procedure
To install the Python 3 Lite Router App, follow the instructions in the Configuration Manual, section Customization → Router Apps.
Verifying the Installation
Once installed, verify Python is available and working correctly:
- Access the router's command-line interface (CLI).
- Check the installed Python version:
python3 --versionThis should output the installed version, for example Python 3.x.y.
- Test importing a standard module:
python3 -c "import hashlib; print(hashlib)"If these commands execute without error, Python is ready to use.
Using Python
Interactive Python Shell
The Python interactive shell (REPL — Read-Eval-Print Loop) lets you type Python code directly and see immediate results. It is useful for testing code snippets or exploring Python features.
- Log in to the router's CLI.
- Start the Python interpreter:
python3The Python prompt (>>>) appears.
- Enter Python commands:
>>> print("Hello from Advantech Router!")
Hello from Advantech Router!
>>> a = 10
>>> b = 20
>>> print(a + b)
30
>>> import os
>>> os.uname()- To exit, type:
>>> exit()Or press Ctrl-D.
Executing Python Scripts
For more complex tasks, write Python code into .py files and execute them as scripts.
Creating or transferring scripts:
- Using
vi: Create or edit scripts directly on the router. Refer to the BusyBox vi tutorial for guidance. - Transferring via
scp: Write scripts on your development computer and transfer them to the router:
scp myscript.py admin@ROUTER_IP_ADDRESS:/tmp/Note that /tmp is a RAM disk — its contents are cleared on reboot.
Running a script:
- Add a shebang line at the top of the script:
#!/usr/bin/python3
print("This is my Python script.")- Make the script executable:
chmod +x /path/to/your/myscript.py- Run the script:
python3 /path/to/your/myscript.pyPassing Command-Line Arguments
Command-line arguments are accessible within the script via the sys.argv list. Example myscript_args.py:
#!/usr/bin/python3
import sys
print(f"Script name: {sys.argv[0]}")
if len(sys.argv) > 1:
print(f"First argument: {sys.argv[1]}")
if len(sys.argv) > 2:
print(f"Second argument: {sys.argv[2]}")Run with arguments:
python3 myscript_args.py arg1 "another argument"Output:
Script name: myscript_args.py
First argument: arg1
Second argument: another argumentStandard Library Modules
The following standard library modules are particularly useful for router scripting. All of these are available in the Python 3 Lite Router App:
| Module | Description |
|---|---|
os | Operating system interaction: file system operations, environment variables, os.system(). |
subprocess | Running external shell commands with full control over input/output streams. Recommended over os.system(). |
sys | System parameters and functions: command-line arguments (sys.argv), exit codes (sys.exit()). |
re | Regular expressions for text pattern matching and manipulation, useful for parsing log files. |
datetime | Date and time handling, for example timestamping log entries. |
socket | Low-level network operations. |
json | Parsing and generating JSON data, common in APIs and configurations. |
Tips
The Python 3 Lite Router App does not include pip, so third-party libraries cannot be installed from PyPI. Only the Python standard library and pure-Python libraries bundled alongside your scripts are available. For pip support, use the full Python 3 Router App.
Development Notes
Developing Python scripts for Advantech routers requires consideration of their specific operating environment, which is typically based on BusyBox with inherent resource constraints. These constraints are especially relevant when using the Python 3 Lite Router App.
BusyBox environment: BusyBox provides a compact set of Unix utilities with fewer options and sometimes slightly different behavior compared to full GNU equivalents. Scripts calling external commands should account for these differences.
Subprocess for command execution: Python's
subprocessmodule is strongly recommended overos.system()for running external shell commands. It provides better control over input/output streams and error handling.On-router text editing: The primary text editor available directly on the router is
vi. A BusyBox vi tutorial is available online.File system and volatility: The
/tmpdirectory is a RAM disk (tmpfs) — its contents are cleared on reboot. For persistent storage, use/opt,/mnt/user, or an attached USB drive, depending on the router model and configuration.Permissions: Python scripts require execute permissions (
chmod +x script.py) to run directly. Privileged operations may require root access.Resource constraints: Resource constraints are particularly important with the Lite version. Write efficient, lean code. Avoid memory-intensive operations and load only the modules you actually need.
No
pip— managing third-party libraries manually: Sincepipis not available, any third-party library your script depends on must be a pure-Python package that you bundle manually alongside your script, or you must copy the library files directly to the router. When possible, rely only on the standard library.Router SDK module (
um): For interacting with router-specific hardware — such as GPIOs, cellular signal strength, device temperature, expansion port configurations, or generating content for the router's web interface — Advantech provides theumPython module as part of the Advantech SDK. Refer to the SDK documentation for your target platform for details.
Script Examples
The following examples demonstrate practical use cases for Python on an Advantech router. All scripts rely only on the standard library and run on both the Python 3 Lite and full Python 3 Router Apps.
Gathering System Information
This script displays basic system information: uptime, memory usage, disk space, and hostname. Save the code below into a file named system_info.py.
#!/usr/bin/python3
import subprocess
print("Gathering Basic System Information...\n")
print("--- System Uptime ---")
try:
with open("/proc/uptime", "r") as f:
uptime_seconds = float(f.readline().split()[0])
days = int(uptime_seconds // (24 * 3600))
uptime_seconds %= (24 * 3600)
hours = int(uptime_seconds // 3600)
uptime_seconds %= 3600
minutes = int(uptime_seconds // 60)
seconds = int(uptime_seconds % 60)
print(f"System has been up for: {days} days, {hours} hours, {minutes} minutes, {seconds} seconds.")
except Exception as e:
print(f"Could not get uptime: {e}")
print()
print("--- Memory Usage ---")
try:
result = subprocess.run("free", shell=True, capture_output=True, text=True, check=True)
print(result.stdout.strip())
print("(Output is typically in kilobytes)")
except Exception as e:
print(f"Could not get memory usage: {e}")
print()
print("--- Disk Space ---")
try:
result = subprocess.run("df -k", shell=True, capture_output=True, text=True, check=True)
print(result.stdout.strip())
print("(Output is in 1K-blocks/kilobytes)")
except Exception as e:
print(f"Could not get disk space: {e}")
print()
print("--- Hostname ---")
try:
with open("/proc/sys/kernel/hostname", "r") as f:
hostname = f.read().strip()
print(hostname)
except Exception as e:
print(f"Could not get hostname: {e}")
print()The script reads uptime directly from /proc/uptime and the hostname from /proc/sys/kernel/hostname. Memory usage and disk space are retrieved by running free and df -k via subprocess. Each section uses a try...except block to handle errors gracefully.
Example output:
Gathering Basic System Information...
--- System Uptime ---
System has been up for: 0 days, 1 hours, 10 minutes, 34 seconds.
--- Memory Usage ---
total used free shared buff/cache available
Mem: 503840 38604 448744 184 16492 456496
Swap: 0 0 0
(Output is typically in kilobytes)
--- Disk Space ---
Filesystem 1024-blocks Used Available Use% Mounted on
/dev/root 64512 23544 40968 36% /
devtmpfs 251408 0 251408 0% /dev
none 251920 0 251920 0% /tmp
none 50384 184 50200 0% /var
/dev/mtdblock7 131072 19812 111260 15% /opt
/dev/mtdblock8 128 36 92 28% /var/data
(Output is in 1K-blocks/kilobytes)
--- Hostname ---
RouterBasic Network Reachability Test
This script pings a list of IP addresses to check their reachability. Save the code below into a file named network_test.py.
#!/usr/bin/python3
import subprocess
import sys
def ping_host(host_ip, count=1):
"""Pings a host and returns True if reachable, False otherwise."""
command = ["ping", "-c", str(count), "-W", "1", host_ip]
try:
process = subprocess.Popen(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
process.communicate()
return process.returncode == 0
except FileNotFoundError:
print(f"Error: 'ping' command not found.", file=sys.stderr)
return False
except Exception as e:
print(f"Error pinging {host_ip}: {e}", file=sys.stderr)
return False
if __name__ == "__main__":
hosts_to_check = ["8.8.8.8", "1.1.1.1", "192.168.1.254"]
if len(sys.argv) > 1:
hosts_to_check = sys.argv[1:]
print("--- Network Reachability Test ---")
for host in hosts_to_check:
print(f"Pinging {host}... ", end="")
if ping_host(host):
print("Reachable")
else:
print("Unreachable")The ping_host() function runs ping via subprocess.Popen, suppressing its output and checking only the return code (0 = reachable). The -W 1 flag sets a one-second timeout per packet, which is important for the BusyBox ping implementation. The default target list (8.8.8.8, 1.1.1.1, 192.168.1.254) can be overridden by passing IP addresses as command-line arguments.
Example output:
--- Network Reachability Test ---
Pinging 8.8.8.8... Reachable
Pinging 1.1.1.1... Reachable
Pinging 192.168.1.254... UnreachableSimple Log File Monitoring
This script monitors a log file and reports new lines matching specified keywords. Save the code below into a file named log_monitoring.py.
Caution
Continuously reading large log files can impact performance. This example is illustrative. For production use, consider more optimized log monitoring techniques or a more efficient file-tailing mechanism.
#!/usr/bin/python3
import sys
import re
import time
def monitor_log(log_file_path, keywords, interval_seconds=5):
"""Monitors a log file for lines containing specified keywords."""
print(f"Monitoring {log_file_path} for keywords: {keywords}")
print(f"Checking every {interval_seconds} seconds. Press Ctrl+C to stop.")
patterns = [re.compile(keyword, re.IGNORECASE) for keyword in keywords]
try:
last_lines_seen = set()
while True:
current_lines = set()
try:
with open(log_file_path, 'r') as f:
for line_number, line in enumerate(f, 1):
line = line.strip()
current_lines.add(line)
if line in last_lines_seen:
continue
for pattern in patterns:
if pattern.search(line):
print(f"[MATCH] Line {line_number}: {line}")
break
except FileNotFoundError:
print(f"Error: Log file '{log_file_path}' not found.", file=sys.stderr)
return
except Exception as e:
print(f"Error reading log file: {e}", file=sys.stderr)
last_lines_seen.update(current_lines)
time.sleep(interval_seconds)
except KeyboardInterrupt:
print("\nLog monitoring stopped.")
if __name__ == "__main__":
log_file = "/var/log/messages"
search_keywords = ["error", "warn", "dhcp"]
if len(sys.argv) > 1:
log_file = sys.argv[1]
if len(sys.argv) > 2:
search_keywords = sys.argv[2:]
try:
with open(log_file, 'r') as f:
pass
except Exception as e:
print(f"Cannot access log file {log_file}: {e}", file=sys.stderr)
sys.exit(1)
monitor_log(log_file, search_keywords)The script polls the log file every 5 seconds, compiles the keywords as case-insensitive regular expressions, and prints any new matching lines. Previously seen lines are tracked in a set to avoid duplicate reporting. The default log file (/var/log/messages) and keywords (error, warn, dhcp) can be overridden via command-line arguments. Press Ctrl-C to stop monitoring.
Example output:
Monitoring /var/log/messages for keywords: ['error', 'warn', 'dhcp']
Checking every 5 seconds. Press Ctrl+C to stop.
[MATCH] Line 15: 2025-05-22 12:34:43 [info] dhcpd: Wrote 0 leases to leases file.
[MATCH] Line 21: 2025-05-22 12:34:48 [warning] totd[1431]: Disabling rescanning of network interfaces
^C
Log monitoring stopped.