Appearance
Control Device
Send control commands to a device (object) identified by its partial UID. This endpoint allows you to send raw data commands to devices and optionally wait for their responses.
Request
http
POST /api/control-deviceAuthentication Required: Must include JWT token in Authorization header.
Required Scope: device_control
Special Scope: If the user has the omit_mpass scope, the operation can proceed without requiring the master password.
Content-Type: application/json
Request Body
json
{
"partial_uid": "ABCDEF123456",
"request_id": "req-123",
"data": "...device control message...",
"cloud_access_code": "123456",
"response_required": true
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
partial_uid | string | Yes | Partial UID of the target device (hex format) |
request_id | string | No | Optional identifier for tracking this request |
data | string | Yes | Command data to send to device (hex format) |
cloud_access_code | string | No | Cloud access code for the device |
response_required | boolean | No | Whether to wait for device response (default: false) |
Request Examples
Send Command Without Response
bash
curl -X POST "http://your-server-ip:port/api/control-device" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"partial_uid": "ABC123",
"data": "...device control message..."
}'Send Command and Wait for Response
bash
curl -X POST "http://your-server-ip:port/api/control-device" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"partial_uid": "ABC123",
"request_id": "status-check-001",
"data": "...device control message...",
"response_required": true
}'Response
Success (200 OK)
Command Sent Successfully (with response):
json
{
"partial_uid": "ABCDEF123456",
"request_id": "req-123",
"uid": "AABBCCDDEEFF",
"data": ["...device response data...", "...additional response data..."],
"hw_id": "01",
"oid": "1234567890"
}Command Sent Successfully (no response required):
json
{
"partial_uid": "ABCDEF123456",
"request_id": "req-123",
"uid": "AABBCCDDEEFF",
"hw_id": "01",
"oid": "1234567890"
}Error:
json
{
"partial_uid": "ABCDEF123456",
"request_id": "req-123",
"uid": "AABBCCDDEEFF",
"error": "See error table below for possible values",
"hw_id": "01",
"oid": "1234567890"
}Response Fields
| Field | Type | Description |
|---|---|---|
partial_uid | string | The queried partial UID |
request_id | string | Request identifier (if provided) |
uid | string | Full unique identifier of the device |
data | array | Array of response data packets from device (hex format). Only present when response_required is true and device responds |
error | string | Error message if command failed or device reported an error (optional) |
hw_id | string | Hardware identifier (optional) |
oid | string | Object identifier (optional) |
Error Responses
HTTP Error Responses
400 Bad Request (Plain Text)
Invalid request401 Unauthorized (Plain Text)
NOT_LOGGED_IN403 Forbidden (Plain Text)
FORBIDDEN405 Method Not Allowed (Plain Text)
Method Not AllowedJSON Response with Errors
Even when the HTTP status is 200 OK, the response may contain an error field indicating issues with the request or device communication:
Error Response Example:
json
{
"partial_uid": "ABCDEF123456",
"request_id": "req-123",
"uid": "AABBCCDDEEFF",
"error": "NO_RESPONSE",
"hw_id": "01",
"oid": "1234567890"
}Possible Error Field Values
| Error Code | Occurs only when response_required is true | Description |
|---|---|---|
FIELD_UID_IS_MISSING | No | Required partial_uid field is missing from request |
INVALID_DATA | No | Command data format is invalid (not valid hex) |
BAD_DATA | No | Command data is malformed or corrupted |
NO_OBJECT | No | Device with specified partial UID not found |
NO_CONNECTION | No | Device is not connected or unreachable |
MPASS_IS_INCORRECT | No | Incorrect cloud access code provided |
NO_RESPONSE | Yes | Device did not respond within timeout period (10 seconds) |
INVALID_PACKET_NUMBER | Yes | Device response contained invalid packet number |
INVALID_PACKET_COUNT | Yes | Device response contained invalid packet count |
Command Reference
Device control commands are documented in the Control Command Reference page.
Usage Examples
Basic Device Control
javascript
async function sendDeviceCommand(partialUid, commandData, waitForResponse = false) {
try {
const response = await fetch('/api/control-device', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
partial_uid: partialUid,
data: commandData,
response_required: waitForResponse,
request_id: `cmd-${Date.now()}`
})
});
if (!response.ok) {
const error = await response.text();
throw new Error(`HTTP ${response.status}: ${error}`);
}
const result = await response.json();
if (waitForResponse && result.data) {
console.log(`Device ${partialUid} responded with:`, result.data);
} else {
console.log(`Command sent to device ${partialUid}`);
}
return result;
} catch (error) {
console.error('Device control failed:', error);
throw error;
}
}Device Status Check
javascript
async function checkDeviceStatus(partialUid) {
// Send status query command (example hex data)
const statusCommand = "010203"; // Replace with actual status command
try {
const result = await sendDeviceCommand(partialUid, statusCommand, true);
if (result.data && result.data.length > 0) {
// Parse device response
const statusData = result.data[0];
console.log(`Device ${partialUid} status: ${statusData}`);
return parseDeviceStatus(statusData);
}
throw new Error('No status data received');
} catch (error) {
console.error(`Failed to get status for device ${partialUid}:`, error);
throw error;
}
}
function parseDeviceStatus(hexData) {
// Example status parsing - replace with actual parsing logic
return {
battery: parseInt(hexData.substr(0, 2), 16),
signal: parseInt(hexData.substr(2, 2), 16),
mode: parseInt(hexData.substr(4, 2), 16)
};
}Batch Device Control
javascript
class DeviceController {
constructor(token) {
this.token = token;
this.pendingCommands = new Map();
}
async sendCommand(partialUid, data, options = {}) {
const requestId = options.requestId || `cmd-${Date.now()}-${Math.random()}`;
const command = {
partial_uid: partialUid,
data: data,
request_id: requestId,
response_required: options.waitForResponse || false,
cloud_access_code: options.cloudAccessCode
};
try {
const response = await fetch('/api/control-device', {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(command)
});
if (!response.ok) {
throw new Error(await response.text());
}
return await response.json();
} catch (error) {
console.error(`Command failed for device ${partialUid}:`, error);
throw error;
}
}
async sendToMultipleDevices(devices, commandData) {
const results = [];
for (const device of devices) {
try {
const result = await this.sendCommand(device.partial_uid, commandData);
results.push({
device: device.partial_uid,
status: 'success',
result: result
});
} catch (error) {
results.push({
device: device.partial_uid,
status: 'error',
error: error.message
});
}
}
return results;
}
}
// Usage
const controller = new DeviceController(authToken);
// Send command to single device
await controller.sendCommand('ABC123', '010203', {
waitForResponse: true,
requestId: 'status-check'
});
// Send same command to multiple devices
const devices = [
{ partial_uid: 'ABC123' },
{ partial_uid: 'DEF456' },
{ partial_uid: 'GHI789' }
];
const results = await controller.sendToMultipleDevices(devices, '040506');Command Queue Management
javascript
class CommandQueue {
constructor(maxConcurrent = 5) {
this.queue = [];
this.running = new Set();
this.maxConcurrent = maxConcurrent;
}
async addCommand(partialUid, data, options = {}) {
return new Promise((resolve, reject) => {
this.queue.push({
partialUid,
data,
options,
resolve,
reject
});
this.processQueue();
});
}
async processQueue() {
if (this.running.size >= this.maxConcurrent || this.queue.length === 0) {
return;
}
const command = this.queue.shift();
const commandPromise = this.executeCommand(command);
this.running.add(commandPromise);
try {
const result = await commandPromise;
command.resolve(result);
} catch (error) {
command.reject(error);
} finally {
this.running.delete(commandPromise);
this.processQueue(); // Process next command
}
}
async executeCommand(command) {
return sendDeviceCommand(
command.partialUid,
command.data,
command.options.waitForResponse
);
}
}
// Usage
const commandQueue = new CommandQueue(3); // Max 3 concurrent commands
// Queue multiple commands
commandQueue.addCommand('ABC123', '010203');
commandQueue.addCommand('DEF456', '040506');
commandQueue.addCommand('GHI789', '070809');Data Format Guidelines
Hex String Format
- Use uppercase or lowercase hex characters (A-F, 0-9)
- No spaces, hyphens, or other separators
- Examples:
01020304,ABCDEF123456,FF00AA55
Command Structure
Commands should follow your device's protocol specification:
[HEADER][COMMAND][DATA][CHECKSUM]Example command breakdown:
01- Header02- Command type0304- Data payloadAB- Checksum
Response Parsing
Device responses are returned as hex strings in an array:
json
{
"data": ["010203ABCDEF", "040506789012"]
}Each array element represents a separate response packet from the device.
Security Considerations
Scope Requirements
- device_control: Required for all device control operations
- omit_mpass: Special scope that bypasses master password requirements
Master Password
- Some operations may require master password verification
- Users with
omit_mpassscope can bypass this requirement - Implement additional security checks in your application if needed
Command Validation
- Validate hex data format before sending
- Implement command whitelisting for security
- Log all device control operations for audit trails
Timeout and Reliability
Response Timeout
- Device response timeout is 10 seconds
- Commands without
response_requiredreturn immediately after sending - Consider device communication latency in your application
Retry Logic
javascript
async function sendCommandWithRetry(partialUid, data, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await sendDeviceCommand(partialUid, data, true);
} catch (error) {
if (attempt === maxRetries) throw error;
console.log(`Command attempt ${attempt} failed, retrying...`);
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}Important Notes
- Scope Required: Users must have the
device_controlscope - Hex Format: All data must be in valid hexadecimal format
- Response Timeout: 10 seconds maximum wait time for device responses
- Multiple Packets: Device may respond with multiple data packets
- Request Tracking: Use
request_idfor operation tracking and logging - Error Formats: Mix of JSON and plain text error responses
- Master Password: May be required unless user has
omit_mpassscope