Initial commit: COPILOT D6 Flutter keyboard controller
Flutter web app replacing legacy WPF CCTV surveillance keyboard controller. Includes wall overview, section view with monitor grid, camera input, PTZ control, alarm/lock/sequence BLoCs, and legacy-matching UI styling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
190
Docs/legacy-architecture/appserver.md
Normal file
190
Docs/legacy-architecture/appserver.md
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
title: "AppServer"
|
||||
description: "ASP.NET Core coordination server - SignalR hub, REST API, database, admin UI"
|
||||
---
|
||||
|
||||
# AppServer (Copilot.AppServer)
|
||||
|
||||
The AppServer is a centralized coordination service that runs as an ASP.NET Core application (Windows Service capable). It does NOT handle video — only coordination between keyboards.
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Copilot.AppServer.exe"
|
||||
subgraph "SignalR Hub"
|
||||
CamLock["Camera Lock<br/>Management"]
|
||||
SeqMgr["Sequence<br/>Scheduler"]
|
||||
CfgSync["Configuration<br/>Sync"]
|
||||
ViewState["Viewer State<br/>Broadcasting"]
|
||||
AlarmQ["Alarm Query<br/>Proxy"]
|
||||
end
|
||||
|
||||
subgraph "REST API (v1)"
|
||||
Updates["GET /api/v1/updates/{name}<br/>Auto-update manifest"]
|
||||
CfgAPI["Configuration endpoints"]
|
||||
end
|
||||
|
||||
subgraph "Blazor Admin UI"
|
||||
AdminWWW["Web-based admin panel<br/>Configuration management"]
|
||||
end
|
||||
|
||||
subgraph "Database"
|
||||
SQLite["SQLite (copilot.db)<br/>• Camera locks<br/>• Lock history<br/>• Alarm cache"]
|
||||
end
|
||||
|
||||
subgraph "External Integrations"
|
||||
CameaClient["Camea API Client<br/>http://localhost:8081<br/>Alarm data source"]
|
||||
end
|
||||
end
|
||||
|
||||
K1["Keyboard 1"] -->|WSS| CamLock
|
||||
K2["Keyboard 2"] -->|WSS| SeqMgr
|
||||
K3["Keyboard 3"] -->|WSS| CfgSync
|
||||
CamLock --> SQLite
|
||||
AlarmQ --> CameaClient
|
||||
AdminWWW --> CfgSync
|
||||
```
|
||||
|
||||
## SignalR Hub Interface
|
||||
|
||||
The hub exposes methods grouped by function:
|
||||
|
||||
### Camera Locks
|
||||
```
|
||||
TryLockCamera(cameraId, copilotName, priority) → CameraLockResult
|
||||
UnlockCamera(cameraId, copilotName)
|
||||
RequestCameraLock(cameraId, copilotName, priority)
|
||||
CameraLockConfirmTakeOver(cameraId, copilotName, confirm)
|
||||
ResetCameraLockExpiration(cameraId, copilotName)
|
||||
GetLockedCameraIds(copilotName) → IEnumerable<int>
|
||||
```
|
||||
|
||||
### Camera Lock Notifications (Server → Client)
|
||||
```
|
||||
CameraLockNotify(notification) where notification has:
|
||||
- NotificationType: Acquired | TakenOver | ConfirmTakeOver | Confirmed | Rejected | ExpireSoon | Unlocked
|
||||
- CameraId: int
|
||||
- CopilotName: string
|
||||
```
|
||||
|
||||
### Sequences
|
||||
```
|
||||
Start(viewerId, sequenceId)
|
||||
Stop(viewerId)
|
||||
GetSequences(categoryId) → IEnumerable<SequenceMessage>
|
||||
GetSequenceCategories() → IEnumerable<SequenceCategoryMessage>
|
||||
GetRunningSequences() → IEnumerable<ViewerSequenceState>
|
||||
```
|
||||
|
||||
### Sequence Notifications (Server → Client)
|
||||
```
|
||||
ViewerSequenceStateChanged(ViewerSequenceState)
|
||||
```
|
||||
|
||||
### Configuration
|
||||
```
|
||||
GetConfigurationFile(filename) → ConfigurationFile
|
||||
```
|
||||
|
||||
### Configuration Notifications (Server → Client)
|
||||
```
|
||||
ConfigurationFileChanged(ConfigurationFile)
|
||||
```
|
||||
|
||||
### Alarms
|
||||
```
|
||||
GetCamerasWithAlarms() → HashSet<int>
|
||||
GetAlarmsForCamera(cameraId, from, to) → IReadOnlyList<CameraAlarm>
|
||||
```
|
||||
|
||||
## Database Schema (SQLite)
|
||||
|
||||
Managed via Entity Framework Core with code-first migrations:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CameraLock {
|
||||
int CameraId PK
|
||||
string OwnerName
|
||||
string Priority
|
||||
datetime ExpiresAt
|
||||
datetime CreatedAt
|
||||
}
|
||||
|
||||
CameraLockHistory {
|
||||
int Id PK
|
||||
int CameraId
|
||||
string OwnerName
|
||||
string Action
|
||||
datetime Timestamp
|
||||
}
|
||||
|
||||
AlarmCache {
|
||||
int Id PK
|
||||
int CameraId
|
||||
int AlarmTypeId
|
||||
string Name
|
||||
datetime StartTime
|
||||
datetime EndTime
|
||||
}
|
||||
```
|
||||
|
||||
## Lock Expiration System
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
Lock["Lock Created<br/>(ExpiresAt = now + 5min)"] --> Timer["Expiration Timer"]
|
||||
Timer -->|"T+4min<br/>(1min before expiry)"| Warn["Send ExpireSoon<br/>notification"]
|
||||
Warn --> Reset{"PTZ Action?"}
|
||||
Reset -->|Yes| ExtendLock["Reset ExpiresAt = now + 5min"]
|
||||
ExtendLock --> Timer
|
||||
Reset -->|No timeout| Expire["Send Unlocked<br/>notification"]
|
||||
Expire --> Remove["Remove lock from DB"]
|
||||
```
|
||||
|
||||
## Auto-Update System
|
||||
|
||||
The AppServer serves firmware and application updates:
|
||||
|
||||
```
|
||||
GET /api/v1/updates/{copilotName}
|
||||
→ Returns JSON array of available updates:
|
||||
[
|
||||
{
|
||||
"Version": "1.0.706",
|
||||
"Url": "https://copilot.test.d6.colsys.cz/updates/Copilot-1.0.706.zip",
|
||||
"Changelog": "https://...",
|
||||
"Mandatory": { "Value": true, "MinVersion": "1.0.700" },
|
||||
"CheckSum": { "Value": "abc123...", "HashingAlgorithm": "SHA256" }
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
The WPF app uses `AutoUpdater.NET` to check on startup and apply updates.
|
||||
|
||||
## Deployment
|
||||
|
||||
```
|
||||
Copilot.AppServer.exe
|
||||
├── appsettings.json (main config)
|
||||
├── configs/
|
||||
│ ├── appsettings-copilot.json
|
||||
│ ├── appsettings-camera-servers.json
|
||||
│ ├── appsettings-monitor-wall.json
|
||||
│ ├── appsettings-function-buttons.json
|
||||
│ ├── appsettings-prepositions.json
|
||||
│ ├── appsettings-sequences.json
|
||||
│ └── appsettings-sequence-categories.json
|
||||
├── copilot.db (SQLite database)
|
||||
├── wwwroot/ (Blazor admin UI assets)
|
||||
├── logs/
|
||||
│ ├── copilot-appserver-YYYYMMDD.log
|
||||
│ └── buffer/ (Elasticsearch buffer)
|
||||
└── web.config (IIS hosting, if used)
|
||||
```
|
||||
|
||||
Runs as:
|
||||
- Windows Service (`Microsoft.Extensions.Hosting.WindowsServices`)
|
||||
- Or standalone Kestrel server on HTTPS port 443
|
||||
- Uses machine certificate store for TLS
|
||||
Reference in New Issue
Block a user