Overview
The AutoLight V3 REST API provides comprehensive HTTP endpoints for controlling and monitoring LED systems. The API is served by the APIServerManager on port 8000 via AsyncWebServer with FreeRTOS task-based execution.
Base URL : http://{device-ip}:8000/api/v1
Default IP (AP Mode) : 192.168.4.1
Default IP (mDNS) : als.local
Protocol : HTTP
Response Format : Plain text
Quick Start
cURL Examples
JavaScript Fetch
Python Requests
# Get current mode
curl http://192.168.4.1:8000/api/v1/data/get/mode
# Set mode to 5
curl "http://192.168.4.1:8000/api/v1/data/set/mode?value=5"
# Get device name
curl http://192.168.4.1:8000/api/v1/data/get/device/name
# Set delay to 100ms
curl "http://192.168.4.1:8000/api/v1/data/set/delay?value=100"
API Endpoints
GET /api/v1/data/get/device/name
Get the device name (SSID in AP mode) Response : Plain text stringExample :curl http://192.168.4.1:8000/api/v1/data/get/device/name
# Response: "AutoLight-A1B2"
Implementation : APIServerManager.cpp:238api_ . on ( "/api/v1/data/get/device/name" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
auto creds = ConfigManager :: getInstance (). getCredentials ();
request -> send ( 200 , "text/plain" , creds . ssid );
});
GET /api/v1/data/get/device/serial
Get the device serial number Response : Plain text stringExample :curl http://192.168.4.1:8000/api/v1/data/get/device/serial
# Response: "AL3-001234"
Implementation : APIServerManager.cpp:247api_ . on ( "/api/v1/data/get/device/serial" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
auto creds = ConfigManager :: getInstance (). getCredentials ();
request -> send ( 200 , "text/plain" , creds . serial );
});
GET /api/v1/data/get/device/ch
Get the device channel count Response : Plain text integer (1-64)Example :curl http://192.168.4.1:8000/api/v1/data/get/device/ch
# Response: "12"
Implementation : APIServerManager.cpp:243api_ . on ( "/api/v1/data/get/device/ch" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
request -> send ( 200 , "text/plain" , String ( config_ -> getChannel ()));
});
Device State
GET /api/v1/data/get/mode
Get the current LED sequence mode Response : Plain text integer (0-15)
0 - OFF
1 - Static ON
2-15 - LED sequences
Example :curl http://192.168.4.1:8000/api/v1/data/get/mode
# Response: "5"
Implementation : APIServerManager.cpp:267api_ . on ( "/api/v1/data/get/mode" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
request -> send ( 200 , "text/plain" , String ( led_ -> getSequenceIndex ()));
});
GET /api/v1/data/get/delay
Get the current timing delay in milliseconds Response : Plain text integer (30-300)Example :curl http://192.168.4.1:8000/api/v1/data/get/delay
# Response: "50"
Implementation : APIServerManager.cpp:283api_ . on ( "/api/v1/data/get/delay" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
request -> send ( 200 , "text/plain" , String ( led_ -> getDelayTime ()));
});
Device Control
GET /api/v1/data/set/mode
Set the LED sequence mode Parameters :
value (required) - Mode number (0-15)
Response : Plain text confirmationExample :curl "http://192.168.4.1:8000/api/v1/data/set/mode?value=7"
# Response: "Berhasil Set Mode : 7"
Implementation : APIServerManager.cpp:271api_ . on ( "/api/v1/data/set/mode" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
if ( request -> hasArg ( "value" )) {
String modeValue = request -> arg ( "value" );
int modeValueInt = modeValue . toInt ();
Serial . println ( "API Set Mode: " + String (modeValueInt));
led_ -> changeModeApp (modeValueInt);
request -> send ( 200 , "text/plain" , "Berhasil Set Mode : " + modeValue);
} else {
request -> send ( 400 , "text/plain" , "Parameter 'value' is missing" );
}
});
Validation :
Value must be 0-15
Invalid values default to mode 0 (OFF)
GET /api/v1/data/set/delay
Set the timing delay in milliseconds Parameters :
value (required) - Delay in milliseconds (30-300)
Response : Plain text confirmationExample :curl "http://192.168.4.1:8000/api/v1/data/set/delay?value=100"
# Response: "Berhasil Set delay : 100"
Implementation : APIServerManager.cpp:287api_ . on ( "/api/v1/data/set/delay" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
if ( request -> hasArg ( "value" )) {
String delayValue = request -> arg ( "value" );
led_ -> setInitDelay ( delayValue . toInt ());
request -> send ( 200 , "text/plain" , "Berhasil Set delay : " + delayValue);
} else {
request -> send ( 400 , "text/plain" , "Parameter 'value' is missing" );
}
});
Validation :
Recommended range: 30-300ms
Values below 30ms may cause timing issues
Values above 300ms create sluggish patterns
GET /api/v1/data/set/device/name
Set the device name (requires restart to take effect) Parameters :
value (required) - New device name (URL encoded)
Response : Plain text confirmationExample :curl "http://192.168.4.1:8000/api/v1/data/set/device/name?value=MyAutoLight"
# Response: "Berhasil Set device : MyAutoLight"
Implementation : APIServerManager.cpp:252api_ . on ( "/api/v1/data/set/device/name" , HTTP_GET, [ this ]( AsyncWebServerRequest * request ) {
if ( request -> hasArg ( "value" )) {
String deviceName = request -> arg ( "value" );
ConfigManager :: getInstance (). updateCredentials (deviceName, "" );
auto creds = ConfigManager :: getInstance (). getCredentials ();
credentials_ = creds;
request -> send ( 200 , "text/plain" , "Berhasil Set device : " + creds . ssid );
} else {
request -> send ( 400 , "text/plain" , "Parameter 'value' is missing" );
}
});
Device name changes are persisted to EEPROM but require a restart to take effect for WiFi AP SSID.
LED Sequence Modes
The mode parameter controls which LED sequence is active:
Mode Name Description 0 OFF Complete OFF state - all channels disabled 1 Static ON All channels continuously high 2 Blink All All channels blink simultaneously 3 Fill Center Fill from two points (center outward) 4 Fill Right Fill from right to left 5 Fill Ends Fill from both ends inward 6 Sequential Blink one LED at a time sequentially 7 Two LED Fill Blink two LEDs while filling 8 Snake Snake pattern with reverse 9 Random Random LED activation 10 Wave Wave propagation effect 11 Multi-Pattern Complex multi-pattern coordination 12 Matrix Advanced pattern matrix 13 Custom Blink Custom blink patterns 14 Advanced Advanced pattern combinations 15 All Sequences All sequences in rotation
API Server Configuration
WiFi Modes
The API server operates in two WiFi modes:
Access Point (AP)
Station (STA)
Default mode for standalone operation // Default AP configuration
WiFi . mode (WIFI_AP);
WiFi . softAP ( credentials_ . ssid , credentials_ . password );
Settings: Connects to existing WiFi network // STA mode configuration
WiFi . mode (WIFI_STA);
WiFi . begin ( credentials_ . ssid , credentials_ . password );
Settings:
SSID : Your network SSID
Password : Your network password
IP Address : DHCP assigned
Web Server : http://
API Server : http://:8000
mDNS : http://als.local
If STA connection fails after 30 seconds, automatically falls back to AP mode.
Server Initialization
The APIServerManager initializes two AsyncWebServer instances:
class APIServerManager {
private:
AsyncWebServer server_; // Port 80 - Static files from SD card
AsyncWebServer api_; // Port 8000 - REST API endpoints
public:
APIServerManager ( BaseChannel * led , BaseConfig * config )
: server_ ( 80 ), api_ ( 8000 ) {
// Constructor
}
};
Initialization sequence : APIServerManager.cpp:73-110
Load Credentials
initCredentials ();
auto creds = ConfigManager :: getInstance (). getCredentials ();
Initialize SD Card
initSDCard ();
if ( ! SD . begin ( 5 )) {
Serial . println ( "Card Mount Failed" );
}
Start WiFi
initWiFi ();
// Automatically handles AP or STA mode
Setup Routes
setupRoutes ();
// Register all API endpoints
Configure CORS
setDefaultHeaders ();
DefaultHeaders :: Instance (). addHeader ( "Access-Control-Allow-Origin" , "*" );
Start Servers
server_ . begin (); // Port 80
api_ . begin (); // Port 8000
Start mDNS
MDNS . begin ( "als" );
// Available at http://als.local
CORS Configuration
The API automatically enables CORS for cross-origin requests:
void APIServerManager :: setDefaultHeaders () {
DefaultHeaders :: Instance (). addHeader ( "Access-Control-Allow-Headers" , "content-type" );
DefaultHeaders :: Instance (). addHeader ( "Access-Control-Allow-Origin" , "*" );
}
This allows the web client to be hosted on a different domain while still communicating with the device API.
Error Handling
HTTP Status Codes
Code Meaning Example 200 Success Request completed successfully 400 Bad Request Missing required parameter 404 Not Found Invalid endpoint 500 Server Error Internal server error
Common Errors
Cause : Required value parameter not providedcurl http://192.168.4.1:8000/api/v1/data/set/mode
# Response: "Parameter 'value' is missing"
Solution : Include the value parametercurl "http://192.168.4.1:8000/api/v1/data/set/mode?value=5"
Cause : Device not reachable on networkTroubleshooting :
Verify device IP address
Check WiFi connection (AP or STA mode)
Ping the device: ping 192.168.4.1
Check firewall settings
Try mDNS: curl http://als.local:8000/api/v1/data/get/mode
Cause : Browser blocking cross-origin requestNote : CORS is automatically enabled on the server side. If you still see CORS errors:
Check browser console for specific error
Verify API server is running on port 8000
Use browser dev tools to inspect headers
Try direct API call with cURL to verify server
Integration Examples
Web Client Integration
React/TypeScript Example (from AutoLight Web Client):
// lib/api/device.ts
const baseURL = ` ${ protocol } :// ${ host } : ${ port } /api/v1`
export async function getDeviceMode () : Promise < number > {
try {
const response = await fetch ( ` ${ baseURL } /data/get/mode` )
if ( ! response . ok ) throw new Error ( 'Failed to get mode' )
return parseInt ( await response . text ())
} catch ( error ) {
console . error ( 'Error getting device mode:' , error )
throw error
}
}
export async function setDeviceMode ( mode : number ) : Promise < void > {
try {
const response = await fetch ( ` ${ baseURL } /data/set/mode?value= ${ mode } ` )
if ( ! response . ok ) throw new Error ( 'Failed to set mode' )
} catch ( error ) {
console . error ( 'Error setting device mode:' , error )
throw error
}
}
// Usage with React hook
function useLEDControl () {
const [ mode , setMode ] = useState ( 0 )
useEffect (() => {
// Poll device every 2 seconds
const interval = setInterval ( async () => {
const currentMode = await getDeviceMode ()
setMode ( currentMode )
}, 2000 )
return () => clearInterval ( interval )
}, [])
const updateMode = async ( newMode : number ) => {
await setDeviceMode ( newMode )
setMode ( newMode )
}
return { mode , updateMode }
}
Python Integration
import requests
import time
class AutoLightAPI :
def __init__ ( self , host = '192.168.4.1' , port = 8000 ):
self .base_url = f 'http:// { host } : { port } /api/v1'
def get_mode ( self ):
"""Get current LED mode"""
response = requests.get( f ' { self .base_url } /data/get/mode' )
return int (response.text)
def set_mode ( self , mode ):
"""Set LED mode (0-15)"""
if not 0 <= mode <= 15 :
raise ValueError ( 'Mode must be between 0 and 15' )
requests.get( f ' { self .base_url } /data/set/mode?value= { mode } ' )
def get_delay ( self ):
"""Get current timing delay in ms"""
response = requests.get( f ' { self .base_url } /data/get/delay' )
return int (response.text)
def set_delay ( self , delay ):
"""Set timing delay (30-300ms)"""
if not 30 <= delay <= 300 :
raise ValueError ( 'Delay must be between 30 and 300ms' )
requests.get( f ' { self .base_url } /data/set/delay?value= { delay } ' )
def get_device_info ( self ):
"""Get device information"""
name = requests.get( f ' { self .base_url } /data/get/device/name' ).text
serial = requests.get( f ' { self .base_url } /data/get/device/serial' ).text
channels = int (requests.get( f ' { self .base_url } /data/get/device/ch' ).text)
return {
'name' : name,
'serial' : serial,
'channels' : channels
}
# Usage example
api = AutoLightAPI( host = '192.168.4.1' )
# Get device info
info = api.get_device_info()
print ( f "Device: { info[ 'name' ] } " )
print ( f "Serial: { info[ 'serial' ] } " )
print ( f "Channels: { info[ 'channels' ] } " )
# Cycle through modes
for mode in range ( 2 , 16 ):
api.set_mode(mode)
time.sleep( 2 )
# Turn off
api.set_mode( 0 )
Arduino/ESP32 Client
#include <WiFi.h>
#include <HTTPClient.h>
class AutoLightClient {
private:
String baseURL;
HTTPClient http;
public:
AutoLightClient ( const char* host , int port = 8000 ) {
baseURL = String ( "http://" ) + host + ":" + String (port) + "/api/v1" ;
}
int getMode () {
String url = baseURL + "/data/get/mode" ;
http . begin (url);
int httpCode = http . GET ();
if (httpCode == 200 ) {
String payload = http . getString ();
return payload . toInt ();
}
return - 1 ;
}
bool setMode ( int mode ) {
String url = baseURL + "/data/set/mode?value=" + String (mode);
http . begin (url);
int httpCode = http . GET ();
return (httpCode == 200 );
}
int getDelay () {
String url = baseURL + "/data/get/delay" ;
http . begin (url);
int httpCode = http . GET ();
if (httpCode == 200 ) {
String payload = http . getString ();
return payload . toInt ();
}
return - 1 ;
}
bool setDelay ( int delayMs ) {
String url = baseURL + "/data/set/delay?value=" + String (delayMs);
http . begin (url);
int httpCode = http . GET ();
return (httpCode == 200 );
}
};
// Usage
AutoLightClient led ( "192.168.4.1" );
void setup () {
Serial . begin ( 115200 );
WiFi . begin ( "YourSSID" , "YourPassword" );
while ( WiFi . status () != WL_CONNECTED) {
delay ( 500 );
Serial . print ( "." );
}
// Get current mode
int mode = led . getMode ();
Serial . println ( "Current mode: " + String (mode));
// Set to mode 5
led . setMode ( 5 );
// Set delay to 100ms
led . setDelay ( 100 );
}
void loop () {
// Control logic
}
Rate Limiting
The API does not enforce rate limiting, but excessive requests may impact LED sequence execution. Recommended polling interval : 1-2 seconds for state monitoring
Concurrent Requests
AsyncWebServer handles concurrent requests efficiently:
Multiple clients can connect simultaneously
FreeRTOS task-based execution prevents blocking
Web server (port 80) and API (port 8000) run independently
Response Times
Typical response times:
Endpoint Average Response Time GET device info 5-15ms GET mode/delay 5-10ms SET mode/delay 10-20ms SET device name 50-100ms (EEPROM write)
Next Steps
Web Client Explore the Next.js web interface using this API
AutoLight V3 Learn about firmware architecture
Pattern Builder Create custom LED sequences
Back to Overview Return to AutoLight overview