-
Notifications
You must be signed in to change notification settings - Fork 4
plugin sdk state management
Plugins report their health and operational status to Config Tool using ModifyPluginState().
Plugin detects condition
↓
Calls ModifyPluginState()
↓
Plugin Host aggregates states
↓
Config Tool displays in role diagnostics
↓
Role RunningState updated (green/yellow/red)
Key concepts:
- Multiple state contexts can be active simultaneously
- States appear in Config Tool diagnostics
- Error states change role's RunningState to "Not Running" (red)
- Warning states change role's RunningState to "Warning" (yellow)
- States persist until cleared or plugin restarts
The PluginStateEntry class represents a single state condition:
public class PluginStateEntry
{
public PluginStateEntry(string context, string message);
// Properties (set after construction)
public string Context { get; set; }
public string Message { get; set; }
public string Details { get; set; }
public Exception Exception { get; set; }
public bool IsWarning { get; set; }
public bool IsError { get; set; }
}Constructor parameters:
-
context- Unique identifier for this state (e.g., "Connection", "Database"). Cannot be null or empty. -
message- User-friendly description of the state. Set to empty string to clear the context.
Properties (set after construction):
-
IsWarning- Indicates warning state (yellow) -
IsError- Indicates error state (red). When true,IsWarningis ignored. -
Exception- Optional exception details -
Details- Additional detailed message
Call ModifyPluginState() to report or update the plugin role's state:
protected override void OnPluginLoaded()
{
try
{
InitializeConnection();
ModifyPluginState(new PluginStateEntry("Connection", "Connected to external system"));
}
catch (Exception ex)
{
Logger.TraceError(ex, "Connection failed");
ModifyPluginState(new PluginStateEntry("Connection",
"Failed to connect to external system")
{
Exception = ex,
IsError = true
});
}
}Use ModifyEntityState() to report state for entities owned by your plugin. This allows individual entities created by your plugin to display their own diagnostics in Config Tool.
protected void ModifyEntityState(Guid entityId, PluginStateEntry state);
protected void ModifyEntityState(Guid entityId, PluginStateEntry state, bool isRunningStateSettable);Parameters:
-
entityId- The GUID of the entity to attach the state to -
state- The state entry to report -
isRunningStateSettable- When true (default), the entity'sRunningStateis updated based on the state entry. Set to false to report diagnostics without affecting the entity's running state.
Requirements:
- The entity must be owned by your plugin (
entity.OwnerRole == PluginGuid) - Or the entity must be the plugin role itself
private void UpdateDeviceStatus(Guid deviceEntityId, bool isOnline)
{
if (isOnline)
{
ModifyEntityState(deviceEntityId,
new PluginStateEntry("Status", "Online"));
}
else
{
ModifyEntityState(deviceEntityId,
new PluginStateEntry("Status", "Offline") { IsWarning = true });
}
}
private void ReportDeviceError(Guid deviceEntityId, Exception ex)
{
ModifyEntityState(deviceEntityId,
new PluginStateEntry("Status", "Communication error")
{
Exception = ex,
IsError = true
});
}Use isRunningStateSettable = false when you want to display diagnostic information without changing the entity's running state indicator:
// Report statistics without affecting the entity's green/yellow/red state
ModifyEntityState(deviceEntityId,
new PluginStateEntry("Statistics", $"Processed {count} events today"),
isRunningStateSettable: false);ModifyPluginState() is a convenience method that calls ModifyEntityState() with the plugin's own GUID:
// These are equivalent:
ModifyPluginState(new PluginStateEntry("Connection", "Connected"));
ModifyEntityState(PluginGuid, new PluginStateEntry("Connection", "Connected"));Indicates normal operation:
ModifyPluginState(new PluginStateEntry("Connection", "Connected"));
ModifyPluginState(new PluginStateEntry("Database", "Database operational"));
ModifyPluginState(new PluginStateEntry("Hardware", "All devices online"));Effect on role:
- Role shows green (Running) if no error/warning states
- State appears in diagnostics as informational
Indicates degraded operation:
ModifyPluginState(new PluginStateEntry("Connection",
"Intermittent connection issues") { IsWarning = true });
ModifyPluginState(new PluginStateEntry("Hardware",
"2 of 10 devices offline") { IsWarning = true });
ModifyPluginState(new PluginStateEntry("Performance",
"Query response time exceeds threshold") { IsWarning = true });Effect on role:
- Role shows yellow (Warning)
- State appears in diagnostics with warning icon
- Plugin continues to operate
When to use:
- Recoverable errors
- Degraded performance
- Partial failures
- Approaching limits
Indicates critical failure:
ModifyPluginState(new PluginStateEntry("Connection",
"Cannot connect to external system") { Exception = ex, IsError = true });
ModifyPluginState(new PluginStateEntry("Database",
"Database connection lost") { Exception = ex, IsError = true });
ModifyPluginState(new PluginStateEntry("License",
"License validation failed") { IsError = true });Effect on role:
- Role shows red (Not Running)
- State appears in diagnostics with error icon
- Plugin may be non-functional
When to use:
- Connection failures
- Database errors
- License/certificate issues
- Critical resource unavailable
Use different context strings for different subsystems:
// Multiple contexts can be active simultaneously
ModifyPluginState(new PluginStateEntry("Connection", "Connected"));
ModifyPluginState(new PluginStateEntry("Database", "Connected"));
ModifyPluginState(new PluginStateEntry("Hardware", "All devices online"));
ModifyPluginState(new PluginStateEntry("License", "Valid"));Common context names:
-
"Connection"- External system connectivity -
"Database"- Database status -
"Hardware"- Hardware device status -
"License"- Licensing status -
"Configuration"- Configuration validation -
"Performance"- Performance metrics -
"Startup"- Initialization status
Context best practices:
- Use descriptive, consistent names
- One context per subsystem
- Clear context scope
- Don't use too many contexts (5-10 max)
Clear a state by setting empty message:
// Report warning
ModifyPluginState(new PluginStateEntry("Connection",
"Slow response") { IsWarning = true });
// Later, when resolved
ModifyPluginState(new PluginStateEntry("Connection", string.Empty));When to clear:
- Condition resolved
- Subsystem recovered
- Error no longer applicable
Important
- Must use same context string to clear
- Empty message clears the state
- Cleared states don't appear in diagnostics
- All states cleared on plugin restart
Report progress during initialization:
protected override void OnPluginLoaded()
{
ModifyPluginState(new PluginStateEntry("Startup", "Initializing..."));
try
{
InitializeConnection();
ModifyPluginState(new PluginStateEntry("Startup", "Connection initialized"));
LoadConfiguration();
ModifyPluginState(new PluginStateEntry("Startup", "Configuration loaded"));
// Clear startup state when complete
ModifyPluginState(new PluginStateEntry("Startup", string.Empty));
// Report operational state
ModifyPluginState(new PluginStateEntry("Status", "Plugin ready"));
}
catch (Exception ex)
{
ModifyPluginState(new PluginStateEntry("Startup",
"Initialization failed") { Exception = ex, IsError = true });
}
}Update states as conditions change:
private void OnConnectionStateChanged(bool connected)
{
if (connected)
{
ModifyPluginState(new PluginStateEntry("Connection", "Connected"));
}
else
{
ModifyPluginState(new PluginStateEntry("Connection",
"Disconnected") { IsWarning = true });
// Attempt reconnection
Task.Run(() => AttemptReconnect());
}
}
private async Task AttemptReconnect()
{
for (int i = 0; i < 3; i++)
{
ModifyPluginState(new PluginStateEntry("Connection",
$"Reconnecting... (attempt {i + 1}/3)") { IsWarning = true });
if (await TryConnectAsync())
{
ModifyPluginState(new PluginStateEntry("Connection", "Reconnected"));
return;
}
await Task.Delay(TimeSpan.FromSeconds(5));
}
ModifyPluginState(new PluginStateEntry("Connection",
"Reconnection failed") { IsError = true });
}The Plugin Host aggregates all plugin states:
Aggregation rules:
- Any error state → Role shows red (Not Running)
- Any warning state (no errors) → Role shows yellow (Warning)
- All success/cleared states → Role shows green (Running)
Example:
// Plugin reports multiple states
ModifyPluginState(new PluginStateEntry("Connection", "Connected")); // Green
ModifyPluginState(new PluginStateEntry("Database", "Connected")); // Green
ModifyPluginState(new PluginStateEntry("Hardware",
"1 device offline") { IsWarning = true }); // Yellow
// Role overall state: Yellow (Warning) because of hardware warningPath: System → Roles → [Plugin Role] → Diagnostics
What's displayed:
- Role's aggregated RunningState (green/yellow/red icon)
- List of all active states by context
- State messages
- Timestamps
- Exception details (if provided)
States are NOT:
- Persisted in database
- Available through SDK queries
- Visible to end users (Config Tool only)
private void MonitorConnection()
{
if (IsConnected())
{
ModifyPluginState(new PluginStateEntry("Connection", "Connected"));
}
else if (IsConnecting())
{
ModifyPluginState(new PluginStateEntry("Connection",
"Connecting...") { IsWarning = true });
}
else
{
ModifyPluginState(new PluginStateEntry("Connection",
"Disconnected") { IsError = true });
}
}private void ValidateAndApplyConfiguration(PluginConfig config)
{
if (!ValidateConfiguration(config, out string error))
{
ModifyPluginState(new PluginStateEntry("Configuration",
$"Invalid configuration: {error}") { IsError = true });
return;
}
ModifyPluginState(new PluginStateEntry("Configuration", string.Empty));
ApplyConfiguration(config);
}private void MonitorPerformance()
{
var metrics = GetPerformanceMetrics();
if (metrics.AverageResponseTime > TimeSpan.FromSeconds(5))
{
ModifyPluginState(new PluginStateEntry("Performance",
$"Slow response time: {metrics.AverageResponseTime.TotalSeconds:F2}s")
{ IsWarning = true });
}
else
{
ModifyPluginState(new PluginStateEntry("Performance", string.Empty));
}
}- Plugin SDK Overview - Plugin architecture
- Plugin SDK Lifecycle - When to report states
- Plugin SDK Database - Database state reporting
- Logging - Complementary logging
-
Security Center SDK Developer Guide Overview of the SDK framework and how to build integrations with Security Center.
-
Platform SDK
- Platform SDK Overview Introduction to the Platform SDK and core concepts.
- SDK Certificates Details certificates, licensing, and connection validation.
- Entity Guide Explains the core entity model, inheritance, and how to work with entities.
- Entity Cache Guide Describes the engine's local entity cache and synchronization.
- SDK Transactions Covers batching operations for performance and consistency.
- ReportManager Querying entities and activity data from Security Center.
- Events and Actions Subscribing to events and handling actions.
- Logging with the Genetec SDK How to configure logging, diagnostics, and debug methods.
- Referencing SDK Assemblies Best practices for referencing assemblies and resolving them at runtime.
- SDK Compatibility Guide Understanding backward compatibility and versioning in the SDK.
-
Plugin SDK
- Plugin SDK Overview Introduction to plugin architecture and capabilities.
- Plugin SDK Certificates SDK certificate requirements for plugin roles.
- Plugin SDK Lifecycle Initialization and disposal patterns.
- Plugin SDK Threading Threading model, QueueUpdate, and async patterns.
- Plugin SDK Configuration Configuration storage and monitoring.
- Plugin SDK Restricted Configuration Secure credential storage and admin-only configuration.
- Plugin SDK Database Database integration and schema management.
- Plugin SDK Events Event subscription and handling.
- Plugin SDK Queries Query processing and response handling.
- Plugin SDK Request Manager Request/response communication with clients.
- Plugin SDK Entity Ownership Understanding plugin-owned entities, running state management, and ownership release.
- Plugin SDK Entity Mappings Using EntityMappings for plugin-specific configuration and external system integration.
- Plugin SDK State Management Reporting plugin health and diagnostics.
- Plugin SDK Server Management High availability and server failover.
- Custom Privileges Defining and enforcing custom privileges.
- Resolving Non-SDK Assemblies Handling third-party dependencies in plugins and workspace modules.
- Deploying Plugins Registering and deploying plugins and workspace modules.
-
- Macro SDK Developer Guide Complete guide to creating server-side automation scripts in Security Center using C#.
- Getting Started Setup, authentication, and basic configuration for the Web SDK.
- Referencing Entities Entity discovery, search capabilities, and parameter formats.
- Entity Operations CRUD operations, multi-value fields, and method execution.
- Partitions Managing partitions, entity membership, and user access control.
- Custom Fields Creating, reading, writing, and filtering custom entity fields.
- Custom Card Formats Managing custom credential card format definitions.
- Actions Control operations for doors, cameras, macros, and notifications.
- Events and Alarms Real-time event monitoring, alarm monitoring, and custom events.
- Incidents Incident management, creation, and attachment handling.
- Reports Activity reports, entity queries, and historical data retrieval.
- Performance Guide Optimization tips and best practices for efficient API usage.
- Reference Entity GUIDs, EntityType enumeration, and EventType enumeration.
- Under the Hood Technical architecture, query reflection, and SDK internals.
- Troubleshooting Common error resolution and debugging techniques.
- Media Gateway Guide Setup and configuration of the Media Gateway role for video streaming.
- Web Player Guide Complete guide to integrating GWP for live and playback video streaming.
- Web Player API Reference Full API documentation with interfaces, methods, properties, and events.
- Web Player Sample Application Comprehensive demo showcasing all GWP features with timeline and PTZ controls.
- Genetec Web Player Multiplexing Sample Multi-camera grid demo using a shared WebSocket connection.