Interfaces and Commands
In addition to the built-in console page, Node-Camera can also be integrated into target systems by using its APIs. In the following interface descriptions, the IP address or mDNS hostname of Node-Camera is represented by ${host}
.
If Access Control is enabled in the system settings, please refer to Access Control.
HTTP Photo Interface
Use HTTP GET to obtain real-time photos from Node-Camera. Interface address:
http://${host}/still
The interface returns a JPEG photo captured by the camera. You can use a browser to test the photo interface.
HTTP Video Interface
Use HTTP GET to access the Node-Camera camera video stream. Unlike the photo interface, the video stream uses port 81
. Interface address:
http://${host}:81/stream
The interface returns a real-time MJPEG video stream with the MIME type multipart/x-mixed-replace
. You can use a browser to test the video interface.
The HTTP video interface only allows one connection at a time (exclusive). If a client is already streaming video, subsequent video requests will be ignored.
WebSocket Video Interface
When Stream Socket is enabled in the system settings, Node-Camera will provide a WebSocket video interface and stop the HTTP video interface. WebSocket interface address:
ws://${host}:81/stream
After the client establishes a WebSocket connection with Node-Camera, it can control the video stream transmission by sending the following commands (strings):
stream
- Start continuous video stream transmission.stop
- Stop video stream transmission.still
- Transmit one photo and then stop.
Each data packet (event.data) sent by the server contains a complete JPEG image (Blob).
The WebSocket video interface only allows one connection at a time (exclusive). If a client has already connected to the WebSocket video interface, subsequent connection requests will be ignored. When Stream Socket is enabled in the system settings, the Camera and Console pages will automatically connect to the video interface. Therefore, when accessing the WebSocket video interface through other (custom) methods, the Camera and Console pages should be closed.
Client Example:
<!DOCTYPE html>
<html>
<head>
<title>Stream-WebSocket</title>
</head>
<body>
<div>
<img id="image" src="">
</div>
<div>
<button id="stream">Stream</button>
<button id="stop">Stop</button>
<button id="still">Still</button>
</div>
</body>
<script>
const image = document.getElementById('image');
const stream = document.getElementById('stream');
const stop = document.getElementById('stop');
const still = document.getElementById('still');
const socketURL = 'ws://192.168.1.100:81/stream'; // Replace with actual address
let socket = null;
const connect = () => {
socket = new WebSocket(socketURL);
socket.addEventListener('open', e => {
// Send the token here if 'Access Control' is enabled
});
socket.addEventListener('close', e => {
setTimeout(connect, 1000);
});
socket.addEventListener('error', e => {
console.warn('WebSocket Connection Failed');
});
socket.addEventListener('message', e => {
if (e.data instanceof Blob) {
image.src = URL.createObjectURL(e.data);
}
});
}
const send = arg => {
if (socket?.readyState === WebSocket.OPEN) {
socket.send(arg);
console.log(arg);
}
else {
console.warn('WebSocket Not Connected');
}
}
stream.onclick = () => send('stream');
stop.onclick = () => send('stop');
still.onclick = () => send('still');
connect();
</script>
</html>
Commands
The commands of Node-Camera include LED switch, pan-tilt control, joystick control, capture trigger, timer switch, port read/write, PWM control, and PCA9685 driver.
Command Interface
Commands can be sent via HTTP GET or WebSocket. If UART CMD is enabled in the system settings, commands can also be sent through the serial port.
HTTP GET command interface:
http://${host}/cmd
The commands are sent as a URL parameter. For example,
http://${host}/cmd?flash=1
(turn on the LED).WebSocket command interface:
ws://${host}/socket/cmd
Commands are sent through the connected WebSocket. For example,
socket.send("flash=1")
(turn on the LED).UART command interface:
If UART CMD is enabled in the system settings, the data received by the serial port will be parsed and executed as commands. For example, if the RXD receives the string
flash=1
, the LED will turn on.
Command Definition
A command consists of a command name (command_name
) and optional command arguments (command_args
). Command format:
command_name[=command_args]
When a command returns a value (return_value
), the format is:
command:return_value
Where command
is the complete command that was received.
For example, the command to read the GPIO12 port get=12
returns get=12:1
, indicating that the GPIO12 port is at a high level.
The following describes each command by name:
flash - LED switch control. Parameter values:
0
- Off;1
- On. No return value.up - Pan-tilt servo moves upward, no parameters, no return value. The servo rotates continuously until the upper limit or a stop command is received.
down - Pan-tilt servo moves downward, no parameters, no return value. The servo rotates continuously until the lower limit or a stop command is received.
left - Pan-tilt servo moves to the left, no parameters, no return value. The servo rotates continuously until the lower limit or a stop command is received.
right - Pan-tilt servo moves to the right, no parameters, no return value. The servo rotates continuously until the upper limit or a stop command is received.
stop - Pan-tilt servo stops rotating, no parameters, no return value.
joy - Joystick control, no return value.
The joystick settings are configured in the Console system settings. The parameters are two comma-separated integers, defined according to the joystick mode (joy_mode). Command format:
joy=arg1,arg2
joy_mode =
1
- Dual-Wheels modearg1
- Left wheel PWM duty cycle, value range-1000
~1000
, negative value indicates reverse.arg2
- Right wheel PWM duty cycle, value range-1000
~1000
, negative value indicates reverse.
joy_mode =
2
- Steering & Drive modearg1
- Steering servo duty cycle, value range-1000
~1000
.-1000
is the lower limit of the steering angle,1000
is the upper limit, and0
indicates the middle angle.arg2
- Drive wheel PWM duty cycle, value range-1000
~1000
, negative value indicates reverse.
capture - Valid when Command Trigger is enabled in the system settings. Triggers a single photo capture, no parameters, no return value.
reset_seq - Resets the captured photo file's sequence number to
0
, no parameters, no return value.timing - Capture timer switch control. Parameter values:
0
- Off;1
- On. No return value.get - Reads the port level value, the parameter is the GPIO port number.
This command is effective for the gpio.input port set in Peripherals system settings. For example, to read the level of GPIO12:
get=12
This command returns the port level (
0
- Low;1
- High). If the GPIO12 port is at a high level, it returns:get=12:1
set - Sets the port to high level, the parameter is the GPIO port number.
This command is effective for the gpio.output port set in Peripherals system settings. For example, to set GPIO12 to high level:
set=12
clr - Sets the port to low level, the parameter is the GPIO port number.
This command is effective for the gpio.output port set in Peripherals system settings. For example, to set GPIO12 to low level:
clr=12
raw - Reads the analog port sample value, the parameter is the ADC1 GPIO port number.
This command is effective for the gpio.analog port set in the Peripherals system settings. For example, to read the sample value of the GPIO32 (ADC1_CH4) port:
raw=32
This command returns the sample value of the corresponding port. The system default ADC is 12 bits wide, and the return value range is
0
~4095
. For example, the sample return of the GPIO32 port:raw=32:2033
The recommended voltage range for analog ports is 150mV~2450mV.
vol - Reads the analog port voltage value, the parameter is the ADC1 GPIO port number.
This command is effective for the gpio.analog port set in the Peripherals system settings. Unlike the raw command, this command converts the sample value to the actual voltage value (mV) and returns it. For example, to read the voltage value of the GPIO32 (ADC1_CH4) port:
vol=32
The command returns the voltage value of the corresponding port, in mV. For example, the voltage return of the GPIO32 port (1830mV):
vol=32:1830
The recommended voltage range for analog ports is 150mV~2450mV.
bat - Reads the battery level, no parameters.
This command is effective after enabling and configuring Battery Monitor in the Features system settings. It is used to obtain the current battery level. The battery level is represented as a percentage value (50 means 50%), and
-1
is returned if the function is not enabled. For example, if the remaining battery is 60%, it returns:bat:60
pwm - Sets the pulse width (duty cycle) output of the PWM port defined by pwm in the Peripherals system settings. The parameters are the port number (gpio_num) and the duty cycle (duty), separated by commas. No return value. Command format:
pwm=gpio_num,duty
gpio_num
- GPIO port number.duty
- Pulse width (duty cycle), the value range is0
~4095
(12bits).
pca9685 - Sets the pulse width (duty cycle) output of the PWM module port defined by pca9685 in the Peripherals system settings. The parameters are the device ID (id), channel number (channel), and duty cycle (duty), separated by commas. No return value. Command format:
pca9685=id,channel,duty
id
- Specifies a PCA9685 device ID set in the Peripherals system settings.channel
- Channel number, the value range is0
~15
.duty
- Pulse width (duty cycle), the value range is0
~4095
(12bits).
Serial-WebSocket bridge
When UART Socket is enabled in the system settings, the Node-Camera serial port (UART0) will be mapped to the WebSocket address:
ws://${host}/socket/uart
When a client establishes a WebSocket connection with Node-Camera at this address, data sent by the client over WebSocket is passed through to the Node-Camera's serial output (TXD), and data received on the Node-Camera's serial input (RXD) is sent back to the client over WebSocket.
The Serial-WebSocket interface allows only one connection (exclusive) at a time. If a client has already connected to the Serial-WebSocket interface, subsequent connection requests will be ignored. When UART Socket is enabled, the Settings page will automatically connect to the Serial-WebSocket interface. Therefore, when accessing the Serial-WebSocket interface through other (custom) methods, the Settings page should be closed.
Client example:
<!DOCTYPE html>
<html>
<head>
<title>UART-WebSocket</title>
</head>
<body>
<div>RXD</div>
<div>
<textarea id="rxd" rows="8" cols="32"></textarea>
</div>
<div>TXD</div>
<div>
<input id="txd" type="text"><button id="send">Send</button>
</div>
</body>
<script>
const rxd = document.getElementById('rxd');
const txd = document.getElementById('txd');
const send = document.getElementById('send');
const socketURL = 'ws://192.168.1.100/socket/uart'; // Replace with actual address
let socket;
const connect = () => {
socket = new WebSocket(socketURL);
socket.addEventListener('open', e => {
// Send the token here if 'Access Control' is enabled
});
socket.addEventListener('close', e => {
setTimeout(connect, 1000);
});
socket.addEventListener('error', e => {
rxd.value = 'WebSocket Connection Failed';
});
socket.addEventListener('message', e => {
rxd.value += e.data;
});
}
send.onclick = () => {
if (txd.value === '') return;
if (socket?.readyState === WebSocket.OPEN) {
socket.send(txd.value);
}
else {
rxd.value = 'WebSocket Not Connected';
}
}
connect();
</script>
</html>
SD Card Interface
When SD card support is enabled in the system settings, the SD card interface can be accessed via HTTP GET.
Get the list of photos stored on the SD card:
http://${host}/sdcard?list
The interface returns a photo list in JSON format:
json[ ["file_name", "yyyy-mm-dd hh:mi:ss"], ... ]
Example of return:
json[ ["IMG_0000.JPG", "1980-01-01 00:00:30"], ["IMG_0001.JPG", "1980-01-01 00:00:40"], ["IMG_0002.JPG", "1980-01-01 00:00:50"] ]
Get a specified photo:
http://${host}/sdcard?image=${file_name}
Example:
http://${host}/sdcard?image=IMG_0000.JPG
Delete a specified photo:
http://${host}/sdcard?delete=${file_name}
Example:
http://${host}/sdcard?delete=IMG_0000.JPG
Access Control
Node-Camera implements access control based on the HTTP Cookie mechanism.
When Access Control is enabled in the system settings and a password is set, Node-Camera will check for a key-value pair named "token" in the request header’s Cookie for each valid HTTP request. If the token is missing or verification fails, the following rules will apply:
Accessing the system built-in pages will redirect to the password input page. After verification passes, it will return to the requested page.
Accessing the photo or video interface will return an Access Denied image.
Accessing the control interface will return HTTP status: 401 Unauthorized.
For WebSocket connections, after a successful connection, the client needs to send the token token=xxxxxx
first, otherwise the connection will be closed by the server.
When the access password is submitted via the password input page, the HTTP response header will include the Cookie token upon successful verification:
Set-Cookie: token=xxxxxx
The browser will automatically include the Cookie: token=xxxxxx
header in subsequent requests, granting normal access.
The Cookie mechanism is automatically supported by browsers. If accessing the interface programmatically, the above mechanism can be used to add the Cookie token to the HTTP request header:
Submit the access password (Access Code) using a HTTP POST method to the address:
http://${host}/code
Retrieve the token
token=xxxxxx
from the response header.Add the token as a Cookie item to the subsequent HTTP request header.
When using a WebSocket connection, send the token
token=xxxxxx
obtained from the POST request immediately after the connection is established.
Client example (Node.js):
/*
* Access Control - Get real-time photo from the camera and save it locally
*/
const http = require('http');
const fs = require('fs');
const hostIP = '192.168.1.100'; // Replace with actual IP
const accessCode = 'nodenode'; // Access password
const localFile = 'still.jpg'; // Local file name
// step 3. Get the camera photo using the token and save it
function saveStill(token) {
console.log(token);
let file = fs.createWriteStream(localFile);
http.get(
{
host: hostIP,
path: '/still',
headers: { 'Cookie': token } // Add Cookie token
},
response => {
response.pipe(file); // Save
console.log('Saved');
}
);
}
// step 2. Callback - Extract the token from the response headers and call saveStill(token)
function callback(response) {
console.log(response.statusCode);
console.log(JSON.stringify(response.headers));
let data = '';
response.on('data', chunk => data += chunk);
response.on('end', () => console.log(data));
const cookies = response.headers['set-cookie'];
if (cookies) {
cookies.forEach(ck => {
if (ck.indexOf('token=') == 0) saveStill(ck.split(';')[0]);
});
}
}
// step 1. Submit the access password (accessCode)
const req = http.request(
{
host: hostIP,
path: '/code',
method: 'POST',
headers: {
'Content-Type': 'text/plain',
'Content-Length': accessCode.length
}
},
callback);
req.write(accessCode); // POST
req.end();