Skip to main content

Vendor System Integration Details

This document provides detailed integration specifications for each vendor system in CitadelMesh, including API details, authentication methods, data models, and operational considerations.

Schneider Electric Security Expert

Product: Enterprise access control and intrusion detection system Vendor: Schneider Electric (pelco.com/security-expert) Version Tested: 7.x

System Capabilities

  • Card-based access control (125 kHz, 13.56 MHz RFID)
  • Multi-door interlock and anti-passback
  • Video integration with Avigilon
  • Alarm monitoring and response
  • Cardholder management up to 100,000 users

API Integration

Base URL: https://<server-ip>/SecurityExpertAPI/v1/

Authentication: API Key + Basic Auth

headers = {
"X-API-Key": config.api_key,
"Authorization": f"Basic {base64_encode(username:password)}"
}

Event Subscription

# Subscribe to events via webhook
POST /events/subscribe
{
"callback_url": "https://citadel-edge.local/webhooks/security-expert",
"event_types": [
"access_granted",
"access_denied",
"door_forced",
"door_held",
"anti_passback_violation"
],
"filter": {
"door_ids": ["door.lobby.main", "door.server_room"]
}
}

Control Operations

# Lock door
POST /doors/{door_id}/lock
{}

# Unlock door temporarily
POST /doors/{door_id}/unlock
{
"duration_seconds": 300, # Max 900 (15 min)
"reason": "Security incident response"
}

# Get door status
GET /doors/{door_id}/status
Response: {
"door_id": "door.lobby.main",
"status": "locked",
"last_access": "2025-09-30T15:30:00Z",
"online": true
}

Safety Considerations

  • Emergency egress doors NEVER locked remotely
  • Unlock duration limited by fire code (typically 15 min max)
  • Audit all control commands
  • Network segmentation (separate VLAN from corporate)

Avigilon Control Center

Product: Video management and analytics platform Vendor: Avigilon (Motorola Solutions) Version Tested: 7.x/8.x

System Capabilities

  • H.264/H.265 video recording
  • AI-powered analytics (person/vehicle detection)
  • License plate recognition (LPR)
  • Appearance search
  • Unusual motion/activity detection

API Integration

Base URL: https://<server-ip>/api/v1/

Authentication: OAuth 2.0 + API credentials

# Get OAuth token
POST /auth/token
{
"grant_type": "client_credentials",
"client_id": config.client_id,
"client_secret": config.client_secret
}

headers = {
"Authorization": f"Bearer {access_token}"
}

Analytics Events

# Poll for analytics events
GET /analytics/events?since={timestamp}&types=person_detected,loitering

Response: {
"events": [
{
"event_id": "evt-001",
"type": "person_detected",
"camera_id": "cam-lobby-01",
"timestamp": "2025-09-30T15:30:00Z",
"confidence": 0.95,
"bounding_box": {"x": 100, "y": 200, "w": 50, "h": 150},
"attributes": {
"gender": "male",
"age_range": "30-40",
"clothing_color": "blue"
}
}
]
}

Video Streams

# Get RTSP stream URL
GET /cameras/{camera_id}/stream

Response: {
"rtsp_url": "rtsp://avigilon.local:554/stream1",
"resolution": "1920x1080",
"framerate": 30,
"codec": "h264"
}

# Create bookmark (snapshot with metadata)
POST /cameras/{camera_id}/bookmarks
{
"timestamp": "2025-09-30T15:30:00Z",
"label": "Security Incident 001",
"duration_seconds": 30
}

Privacy Controls

  • Edge-based video redaction (blur faces/license plates)
  • Role-based camera access (SPIFFE-scoped streams)
  • Retention policies enforced (90 days edge, configurable cloud)
  • PII minimization in analytics (no biometric storage)

EcoStruxure Building Operation

Product: Building management system (BMS) for HVAC, lighting, energy Vendor: Schneider Electric Version Tested: 2021/2022

System Capabilities

  • BACnet/IP native support
  • OPC UA server
  • Trend logging and analytics
  • Alarm management
  • Scheduler and calendar functions

API Integration

Base URL: https://<server-ip>/webstation/api/

Authentication: Username/Password + Session Token

# Login
POST /login
{
"username": config.username,
"password": config.password
}

Response: {
"session_token": "abc123...",
"expires_in": 3600
}

headers = {
"X-Session-Token": session_token
}

Reading Points

# Read single point
GET /points/{point_id}/presentValue

Response: {
"point_id": "hvac.zone1.temp",
"value": 72.5,
"unit": "F",
"quality": "good",
"timestamp": "2025-09-30T15:30:00Z"
}

# Batch read
POST /points/readBatch
{
"point_ids": [
"hvac.zone1.temp",
"hvac.zone1.setpoint",
"hvac.zone1.occupancy"
]
}

Writing Points

# Write setpoint (BACnet priority)
POST /points/{point_id}/write
{
"value": 72.0,
"priority": 8, # BACnet priority 1-16
"duration_minutes": 60 # Optional override duration
}

Response: {
"success": true,
"written_value": 72.0,
"timestamp": "2025-09-30T15:31:00Z"
}

# Release override (relinquish)
POST /points/{point_id}/relinquish
{
"priority": 8
}

OPC UA Alternative

from opcua import Client

client = Client("opc.tcp://ebo-server:4840")
client.set_user("username")
client.set_password("password")
client.connect()

# Browse nodes
root = client.get_root_node()
zones = root.get_child(["Objects", "HVAC", "Zones"])

# Read value
temp_node = client.get_node("ns=2;s=HVAC.Zone1.Temperature")
temp_value = temp_node.get_value()

# Write value
setpoint_node = client.get_node("ns=2;s=HVAC.Zone1.Setpoint")
setpoint_node.set_value(72.0)

Safety Policies

Temperature bounds enforced by OPA:

  • Comfort range: 65-78°F
  • Night setback: 60-78°F
  • Data center: 68-75°F
  • Rate limiting: 5 changes/hour per zone

Home Assistant

Product: Open-source home automation platform Vendor: Open Source (home-assistant.io) Version Tested: 2024.x

Integration Method

WebSocket API for real-time events + REST API for control

WebSocket Connection

import websockets
import json

async def connect_ha():
uri = "ws://homeassistant.local:8123/api/websocket"
async with websockets.connect(uri) as websocket:
# Authenticate
auth_msg = {
"type": "auth",
"access_token": config.long_lived_token
}
await websocket.send(json.dumps(auth_msg))

# Subscribe to state changes
subscribe_msg = {
"id": 1,
"type": "subscribe_events",
"event_type": "state_changed"
}
await websocket.send(json.dumps(subscribe_msg))

# Receive events
while True:
message = await websocket.recv()
event = json.loads(message)
await process_ha_event(event)

Control Services

# Activate scene
POST /api/services/scene/turn_on
{
"entity_id": "scene.meeting_mode"
}

# Control light
POST /api/services/light/turn_on
{
"entity_id": "light.conference_room_a",
"brightness": 200, # 0-255
"color_temp": 370 # Mireds
}

# Get entity state
GET /api/states/{entity_id}

Response: {
"entity_id": "light.conference_room_a",
"state": "on",
"attributes": {
"brightness": 200,
"color_temp": 370,
"friendly_name": "Conference Room A Lights"
},
"last_changed": "2025-09-30T15:30:00Z"
}

Schneider PowerLogic PME

Product: Power monitoring and energy management Vendor: Schneider Electric Version Tested: 9.x

Integration Methods

  1. REST API: Real-time metrics
  2. SQL Database Export: Historical trends (read-only)

REST API

# Get current power
GET /api/metrics/power/realtime?meter_id={meter_id}

Response: {
"meter_id": "meter.main",
"timestamp": "2025-09-30T15:30:00Z",
"active_power_kw": 245.3,
"reactive_power_kvar": 32.1,
"apparent_power_kva": 247.4,
"power_factor": 0.99,
"frequency_hz": 60.0
}

# Query energy consumption
GET /api/energy/consumption?meter_id={meter_id}&start={start}&end={end}&interval=15min

Response: {
"data_points": [
{"timestamp": "2025-09-30T15:00:00Z", "kwh": 61.2},
{"timestamp": "2025-09-30T15:15:00Z", "kwh": 62.1},
...
],
"total_kwh": 1234.5
}

Use Cases in CitadelMesh

  • Demand Limiting: Monitor approach to demand limit, trigger HVAC setback
  • Demand Response: Detect DR events, coordinate load shedding
  • Energy KPIs: Real-time dashboards, baseline vs actual
  • Power Quality: Detect voltage sags, harmonics, PF issues

Bosch Fire & Intrusion

Product: Fire alarm and intrusion detection panels Vendor: Bosch Security Systems Version Tested: Various (site-specific)

IMPORTANT: Read-Only Integration

NO CONTROL COMMANDS PERMITTED per Authority Having Jurisdiction (AHJ) requirements.

Integration Method

Syslog + OPC UA (read-only monitoring)

Syslog Events

# Syslog format (RFC 5424)
&lt;134&gt;1 2025-09-30T15:30:00Z bosch-panel - - - - Fire alarm activated: Zone 3

# Parse to CloudEvent
event = CloudEvent(
type="citadel.incidents.fire.alarm",
source="spiffe://citadel.mesh/adapter/bosch",
subject="fire_panel.zone_3",
data={
"severity": "critical",
"zone": 3,
"alarm_type": "smoke_detector",
"timestamp": "2025-09-30T15:30:00Z"
}
)

OPC UA Monitoring

# Connect to Bosch fire panel OPC UA server (read-only)
client = Client("opc.tcp://bosch-panel:4840")
client.connect()

# Monitor alarm states (read-only)
zone_states = client.get_node("ns=2;s=FirePanel.Zones")
for zone in zone_states.get_children():
state = zone.get_value()
if state == "ALARM":
# Publish incident CloudEvent
await publish_fire_alarm_event(zone.get_browse_name())

Safety & Compliance

  • Network Segmentation: Separate VLAN, firewall rules
  • Read-Only: No write operations ever
  • Audit: Log all data access
  • AHJ Compliance: Documented compliance with fire code
  • Alerting Only: Forward to Ops Agent for human response

See Also