Files
COPILOT/Docs/legacy-architecture/configuration.md
klas 40143734fc 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>
2026-02-12 14:57:38 +01:00

9.0 KiB
Raw Blame History

title, description
title description
Configuration 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)

{
    "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)

{
    "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*(?<CameraId>\\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

{
    "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:

graph TD
    subgraph "Wall (WallId: 1, Name: HDŘÚ TSK/DIC)"
        subgraph "Segment 1 (4 rows × 8 cols)"
            M1["Monitor #01<br/>2×2 span<br/>VM: 151,152,153,154"]
            M2["Monitor #02<br/>2×2 span<br/>VM: 155,156,157,158"]
            M3["Monitor #03"]
            M4["Monitor #04"]
            M5["Monitor #05<br/>...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:

{
    "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

{
    "SequencesConfig": {
        "Sequences": [
            {
                "Id": 1,
                "CategoryId": 1,
                "Name": "Test-A",
                "Interval": 1,
                "MediaChannels": [500100, 500101, 500102, 500103]
            }
        ]
    }
}

AppServer Configuration

{
    "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                         │               │
│  └────────────────────────────────────────┘               │
└───────────────────────────────────────────────────────────┘