Light Commands

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.

Example Response
{
  "status": "OK",
  "message": "Message sent successfully"
}
Example Request (JavaScript)
// 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.

Example Response
{
  "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"
    }
  ]
}
Example Request (JavaScript)
// 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.

Example Response
{
  "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"
    }
  ]
}
Example Request (JavaScript)
// 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.

Example Response
{
  "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"
    }
  ]
}
Example Request (JavaScript)
// 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 (JavaScript)
// 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();
*/