--- title: "Configuration" description: "JSON configuration files, monitor wall topology, and function button mapping" --- # Configuration System ## Configuration Files All configuration is stored as JSON files, managed centrally on the AppServer and synced to each keyboard. ### appsettings.json (Main) ```json { "UseSoftwareRendering": true, "AppServerConfiguration": { "Uri": "https://copilot.test.d6.colsys.cz", "Timeout": "00:00:01.5" }, "ReconnectionConfiguration": { "ReconnectionPeriod": "00:00:02" }, "ViewerStates": { "AppServerConnectionTimeout": "00:00:05" } } ``` | Setting | Value | Purpose | |---------|-------|---------| | `UseSoftwareRendering` | `true` | Forces WPF software rendering (no GPU) for LattePanda | | `AppServerConfiguration.Uri` | HTTPS URL | Central AppServer for coordination | | `AppServerConfiguration.Timeout` | 1.5s | HTTP request timeout | | `ReconnectionPeriod` | 2s | Auto-reconnect interval to camera servers | | `AppServerConnectionTimeout` | 5s | SignalR connection timeout | ### appsettings-copilot.json (Per-Keyboard) ```json { "CopilotConfig": { "WallId": 2, "CameraLockOptions": { "Priority": "Low", "Timeout": "00:05:00" }, "CameraNumberOptions": { "MaxLength": 6, "Prefixes": ["500", "501", "502"], "CancelEditTimeout": "00:05" }, "ViewerStateThrottleInterval": "00:00:00.150", "CentralServer": { "IpAddress": "192.168.102.186", "UserName": "sysadmin", "Password": "masterkey" }, "AllowPrepositionsInterval": { "Min": 10, "Max": 99 }, "PlaybackOptions": { "Allowed": true, "Speeds": [1, 2, 5, 15, 30, 100, 250] }, "AlarmHistoryOptions": { "CameraIdExtractionRegex": "^\\D*(?\\d{6})\\D*$", "DefaultSearchInterval": "30.00:00:00" } } } ``` | Setting | Purpose | |---------|---------| | `WallId` | Which monitor wall this keyboard controls | | `CameraLockOptions.Priority` | PTZ lock priority (`Low` / `High`) | | `CameraLockOptions.Timeout` | Lock auto-expiration (5 min) | | `CameraNumberOptions.MaxLength` | Max digits for camera number (6) | | `CameraNumberOptions.Prefixes` | Auto-prefixes for camera numbers | | `CancelEditTimeout` | Auto-cancel camera number entry (5 sec) | | `ViewerStateThrottleInterval` | Debounce viewer state updates (150ms) | | `PlaybackOptions.Speeds` | Shuttle playback speeds (1x to 250x) | | `AllowPrepositionsInterval` | Valid preposition range (10-99) | ### appsettings-camera-servers.json ```json { "CameraServerConfig": { "CameraServers": [ { "IpAddress": "192.168.102.20", "UserName": "sysadmin", "Password": "masterkey", "CameraServerType": "GCore" }, { "IpAddress": "192.168.102.186", "UserName": "sysadmin", "Password": "masterkey", "CameraServerType": "GeviScope" } ] } } ``` Supported server types: `GeViScope`, `GCore`, `GeViSoft` ### appsettings-monitor-wall.json (Topology) Defines the physical monitor wall layout: ```mermaid graph TD subgraph "Wall (WallId: 1, Name: HDŘÚ TSK/DIC)" subgraph "Segment 1 (4 rows × 8 cols)" M1["Monitor #01
2×2 span
VM: 151,152,153,154"] M2["Monitor #02
2×2 span
VM: 155,156,157,158"] M3["Monitor #03"] M4["Monitor #04"] M5["Monitor #05
...etc"] end end ``` Hierarchy: ``` Wall └── Segment (grid: RowCount × ColumnCount) └── Monitor (physical screen, positioned at Row/Col with RowSpan/ColSpan) └── VirtualMonitor (individual video feed, positioned within monitor grid) ``` A single physical monitor can display multiple virtual monitors (e.g., 2×2 quad view). Each VirtualMonitor has a unique `VirtualMonitorId` that maps to a `ViewerId` in the camera server. ### appsettings-function-buttons.json Maps F1-F7 and Home keys to actions per wall: ```json { "FunctionButtonsConfig": { "FunctionButtons": [ { "WallId": 1, "Buttons": [ { "Button": "F1", "Actions": [ { "ViewerId": 1001, "ActionType": "CrossSwitch", "SourceId": 501111 }, { "ViewerId": 1002, "ActionType": "CrossSwitch", "SourceId": 502345 } ] }, { "Button": "F4", "Actions": [ { "ViewerId": 1001, "ActionType": "SequenceStart", "SourceId": 258 } ] } ] } ] } } ``` Action types: `CrossSwitch` (switch camera to viewer), `SequenceStart` (start camera cycling) ### appsettings-sequences.json ```json { "SequencesConfig": { "Sequences": [ { "Id": 1, "CategoryId": 1, "Name": "Test-A", "Interval": 1, "MediaChannels": [500100, 500101, 500102, 500103] } ] } } ``` ## AppServer Configuration ```json { "ConnectionStrings": { "SqliteConnection": "Data Source=copilot.db" }, "CameaApiClient": { "Uri": "http://localhost:8081", "Timeout": "00:00:01.5", "TimeZone": "Central Europe Standard Time" }, "LockExpirationConfig": { "LockExpirationTimeout": "00:05:00", "NotificationBeforeExpiration": "00:01:00" }, "Kestrel": { "Endpoints": { "Https": { "Url": "https://*:443", "Certificate": { "Subject": "copilot.test.d6.colsys.cz", "Store": "Root", "Location": "LocalMachine" } } } } } ``` ## Network Topology ``` ┌───────────────────────────────────────────────────────────┐ │ 192.168.102.0/24 Network │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ GeViScope Server │ │ G-Core Server │ │ │ │ 192.168.102.186 │ │ 192.168.102.20 │ │ │ │ sysadmin/master │ │ sysadmin/master │ │ │ └────────┬─────────┘ └────────┬────────┘ │ │ │ TCP (native SDK) │ TCP (native SDK) │ │ │ │ │ │ ┌────────┴──────────────────────┴────────┐ │ │ │ Keyboard SBC │ │ │ │ (LattePanda Sigma) │ │ │ │ Copilot.App.exe (WPF) │ │ │ └────────┬───────────────────────────────┘ │ │ │ HTTPS/WSS (SignalR) │ │ │ │ │ ┌────────┴───────────────────────────────┐ │ │ │ AppServer │ │ │ │ copilot.test.d6.colsys.cz:443 │ │ │ │ Copilot.AppServer.exe │ │ │ │ + SQLite DB + Camea API (:8081) │ │ │ └────────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────────┐ │ │ │ Elasticsearch (logging) │ │ │ │ localhost:9200 │ │ │ └────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────┘ ```