Light Commands
Table of Contents
Overview
The Light Commands API allows you to send commands to light devices in the RCAMS system. These commands control the color and behavior of the lights, providing visual emergency notifications throughout school facilities. You can send commands to individual lights, groups of lights, all lights in a school, or all lights across an entire district. This section details the API endpoints for sending commands to lights at various levels of the organizational hierarchy.
Note: All light command endpoints require basic authentication. The user must have appropriate permissions for the requested operations.
Light Command API Endpoints
| Target | Endpoint |
|---|---|
| Individual Light | /lightcommands.php |
| Group of Lights | /lightcommandsgroup.php or /groupcommands.php |
| School-wide Lights | /lightcommandsclient.php |
| District-wide Lights | /lightcommandsdistrict.php |
Light Command Types
The RCAMS system supports various command types that can be sent to light devices. Each command corresponds to a specific emergency protocol and causes the light to display a specific color.
Light Command Messages
| Command | Color | Protocol | Description |
|---|---|---|---|
MODE:0 |
Off | Off/Normal | Turn off the light |
MODE:1 |
Red | Lockdown | High-level emergency requiring lockdown |
MODE:2 |
Blue | Secure | Secure the building/area |
MODE:3 |
White | Team Assist | Request for assistance from response team |
MODE:4 |
Green | Evacuate | Emergency evacuation required |
MODE:5 |
Orange | Shelter | Take shelter in place |
MODE:6 |
Purple | Hold | Hold in current location |
Warning: Exercise caution when sending commands, especially to multiple lights. These commands are designed for emergency situations and may trigger responses from staff and students.
Send Command to Individual Light
Sends a command to a single light device.
POST/lightcommands.php
Sends a command to a single light device identified by its MAC address.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
light_mac |
String | Yes | MAC address of the light to control |
message |
String | Yes | Command message to send (e.g., MODE:1) |
Response
Returns confirmation that the message was sent successfully.
{
"status": "OK",
"message": "Message sent successfully"
}
// Set up the request
const jsonData = JSON.stringify({
light_mac: '1B3C1A3F7D1B',
message: 'MODE:1' // Red/Lockdown
});
// Make the API call
fetch('https://rcamsapi.spheronomics.com/api/v2/lightcommands.php', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('your_api_username:your_api_password') // Replace with actual credentials
},
body: jsonData
})
.then(response => response.json())
.then(data => {
if (data.status === 'OK') {
console.log('Command sent successfully');
} else {
console.error('Error:', data.message);
}
})
.catch(error => console.error('Error:', error));
Send Command to Group
Sends a command to all lights in a group.
POST/lightcommandsgroup.php or /groupcommands.php
Sends a command to all lights assigned to a specific group.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
group_id |
String | Yes | ID of the group to send the command to |
message |
String | Yes | Command message to send (e.g., MODE:1) |
Response
Returns confirmation that the command was executed for the group, along with individual results for each light in the group.
{
"status": "OK",
"message": "Light group command executed",
"results": [
{
"status": "OK",
"message": "message published",
"light_mac": "JCBD2G5D2EA2D"
},
{
"status": "false",
"message": "light_missed_params",
"light_mac": "1B2C3D4F4B5E"
},
{
"status": "OK",
"message": "message published",
"light_mac": "1F2C3D2A4C5D"
},
{
"status": "false",
"message": "Failed to connect to MQTT broker.",
"light_mac": "8145CEBD724"
}
]
}
// Set up the request
const jsonData = JSON.stringify({
group_id: '1',
message: 'MODE:2' // Blue/Secure
});
// Make the API call
fetch('https://rcamsapi.spheronomics.com/api/v2/groupcommands.php', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('your_api_username:your_api_password') // Replace with actual credentials
},
body: jsonData
})
.then(response => response.json())
.then(data => {
if (data.status === 'OK') {
console.log('Group command executed');
console.log('Results for individual lights:', data.results);
// Count successful and failed commands
const successful = data.results.filter(result => result.status === 'OK').length;
const failed = data.results.filter(result => result.status !== 'OK').length;
console.log(`Command summary: ${successful} successful, ${failed} failed`);
} else {
console.error('Error:', data.message);
}
})
.catch(error => console.error('Error:', error));
Send Command to School
Sends a command to all lights in a school.
POST/lightcommandsclient.php
Sends a command to all lights across all groups within a specific school.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
school_id |
String | Yes | ID of the school to send the command to |
message |
String | Yes | Command message to send (e.g., MODE:1) |
Response
Returns confirmation that the command was executed for the school, along with individual results for each light in the school.
{
"status": "OK",
"message": "Lights school command executed",
"results": [
{
"status": "OK",
"message": "message published",
"light_mac": "1B2C3D4F3B3E"
},
{
"status": "OK",
"message": "message published",
"light_mac": "JCBD2G5D2EA2D"
},
{
"status": "false",
"message": "light_missed_params",
"light_mac": "1B2C3D4F4B5E"
},
{
"status": "OK",
"message": "message published",
"light_mac": "1F2C3D2A4C5D"
},
{
"status": "false",
"message": "Failed to connect to MQTT broker.",
"light_mac": "8145CEBD724"
}
]
}
// Set up the request
const jsonData = JSON.stringify({
school_id: '1',
message: 'MODE:4' // Green/Evacuate
});
// Make the API call
fetch('https://rcamsapi.spheronomics.com/api/v2/lightcommandsclient.php', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('your_api_username:your_api_password') // Replace with actual credentials
},
body: jsonData
})
.then(response => response.json())
.then(data => {
if (data.status === 'OK') {
console.log('School command executed');
console.log('Results for individual lights:', data.results);
// Count successful and failed commands
const successful = data.results.filter(result => result.status === 'OK').length;
const failed = data.results.filter(result => result.status !== 'OK').length;
console.log(`Command summary: ${successful} successful, ${failed} failed`);
} else {
console.error('Error:', data.message);
}
})
.catch(error => console.error('Error:', error));
Send Command to District
Sends a command to all lights in a district.
Warning: This command affects all schools, groups, and lights in an entire district. Use this functionality with extreme caution and only in genuine emergency situations that affect the entire district.
POST/lightcommandsdistrict.php
Sends a command to all lights across all schools and groups within a specific district.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
district_id |
String | Yes | ID of the district to send the command to |
message |
String | Yes | Command message to send (e.g., MODE:1) |
Response
Returns confirmation that the command was executed for the district, along with individual results for each light in the district, organized by school.
{
"status": "OK",
"message": "Lights school command executed",
"results": [
{
"school_name": "Washington Elementary",
"light_mac": "AABBCCDDEEFF",
"status": "OK",
"message": "message published"
},
{
"school_name": "Washington Elementary",
"light_mac": "112233445566",
"status": "OK",
"message": "message published"
},
{
"school_name": "Lincoln High School",
"light_mac": "AABBCCDDEE77",
"status": "OK",
"message": "message published"
}
]
}
// Set up the request
const jsonData = JSON.stringify({
district_id: '1',
message: 'MODE:0' // Off/Normal
});
// Make the API call
fetch('https://rcamsapi.spheronomics.com/api/v2/lightcommandsdistrict.php', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('your_api_username:your_api_password') // Replace with actual credentials
},
body: jsonData
})
.then(response => response.json())
.then(data => {
if (data.status === 'OK') {
console.log('District command executed');
console.log('Results for individual lights:', data.results);
// Process results by school
const schoolResults = {};
data.results.forEach(result => {
if (!schoolResults[result.school_name]) {
schoolResults[result.school_name] = {
total: 0,
successful: 0,
failed: 0
};
}
schoolResults[result.school_name].total++;
if (result.status === 'OK') {
schoolResults[result.school_name].successful++;
} else {
schoolResults[result.school_name].failed++;
}
});
console.log('Command summary by school:', schoolResults);
} else {
console.error('Error:', data.message);
}
})
.catch(error => console.error('Error:', error));
Code Examples
Emergency Command System Example
The following example demonstrates a comprehensive emergency command system that provides functions for sending commands at all levels of the organizational hierarchy.
// Emergency Command System for RCAMS
class EmergencyCommandSystem {
constructor(apiUsername, apiPassword) {
this.apiUsername = apiUsername;
this.apiPassword = apiPassword;
this.baseUrl = 'https://rcamsapi.spheronomics.com/api/v1';
}
// Helper method for making API requests
async makeRequest(endpoint, params) {
// Create form data from params
const json = {};
for (const [key, value] of Object.entries(params)) {
json[key] = value;
}
const jsonString = JSON.stringify(json);
try {
const response = await fetch(`${this.baseUrl}/${endpoint}`, {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa(`${this.apiUsername}:${this.apiPassword}`)
},
body: jsonString
});
return await response.json();
} catch (error) {
console.error(`API request to ${endpoint} failed:`, error);
throw error;
}
}
// Login
async login(username, password) {
const response = await this.makeRequest('login.php', {
user: username,
pass: password
});
if (response.status === 'OK') {
console.log('Login successful.');
return true;
} else {
console.error('Login failed:', response.message);
return false;
}
}
// Logout
async logout() {
if (!this.status) {
console.error('Not logged in.');
return false;
}
const response = await this.makeRequest('logout.php', {
});
if (response.status === 'ok') {
console.log('Logout successful.');
return true;
} else {
console.error('Logout failed:', response.message);
return false;
}
}
// Check if logged in
isLoggedIn() {
return this.status !== 'OK';
}
// Command methods
async sendLightCommand(lightMac, command) {
if (!this.isLoggedIn()) {
throw new Error('Not logged in. Call login() first.');
}
return await this.makeRequest('lightcommands.php', {
light_mac: lightMac,
message: command
});
}
async sendGroupCommand(groupId, command) {
if (!this.isLoggedIn()) {
throw new Error('Not logged in. Call login() first.');
}
return await this.makeRequest('groupcommands.php', {
group_id: groupId,
message: command
});
}
async sendSchoolCommand(schoolId, command) {
if (!this.isLoggedIn()) {
throw new Error('Not logged in. Call login() first.');
}
return await this.makeRequest('lightcommandsclient.php', {
school_id: schoolId,
message: command
});
}
async sendDistrictCommand(districtId, command) {
if (!this.isLoggedIn()) {
throw new Error('Not logged in. Call login() first.');
}
return await this.makeRequest('lightcommandsdistrict.php', {
district_id: districtId,
message: command
});
}
// Command helper methods for specific emergency protocols
async sendLockdown(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:1');
}
async sendSecure(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:2');
}
async sendTeamAssist(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:3');
}
async sendEvacuate(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:4');
}
async sendShelter(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:5');
}
async sendHold(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:6');
}
async sendAllClear(target, targetId) {
return await this.sendCommand(target, targetId, 'MODE:0');
}
// Generic command dispatcher
async sendCommand(target, targetId, command) {
switch (target.toLowerCase()) {
case 'light':
return await this.sendLightCommand(targetId, command);
case 'group':
return await this.sendGroupCommand(targetId, command);
case 'school':
return await this.sendSchoolCommand(targetId, command);
case 'district':
return await this.sendDistrictCommand(targetId, command);
default:
throw new Error(`Invalid target type: ${target}. Must be 'light', 'group', 'school', or 'district'.`);
}
}
}
// Example usage:
/*
async function emergencyDrill() {
// Initialize the system with API credentials
const ecs = new EmergencyCommandSystem('your_api_username', 'your_api_password');
try {
// Login
const loginSuccess = await ecs.login('your_email@example.com', 'your_secure_password');
if (!loginSuccess) return;
// Example: Run a lockdown drill for a specific school
console.log('Starting lockdown drill...');
const schoolId = '1';
// Step 1: Send lockdown command to the school
const lockdownResult = await ecs.sendLockdown('school', schoolId);
console.log('Lockdown command result:', lockdownResult);
// Wait 2 minutes
console.log('Waiting 2 minutes...');
await new Promise(resolve => setTimeout(resolve, 120000));
// Step 2: Send all-clear command to end the drill
console.log('Ending drill with all-clear command...');
const allClearResult = await ecs.sendAllClear('school', schoolId);
console.log('All-clear command result:', allClearResult);
// Logout
await ecs.logout();
console.log('Drill completed successfully.');
} catch (error) {
console.error('Error during emergency drill:', error);
}
}
// Run the drill (commented out for safety)
// emergencyDrill();
*/