# Phase 0: Infrastructure Implementation Plan **Status:** In Progress **Duration:** Week 1-2 **Goal:** Finalize bridges, add event subscriptions, test direct commands, document configurations --- ## Current State Assessment ### Bridge Readiness | Bridge | Port | Status | PLC Events | ViewerConnectLive | PTZ | Playback | |--------|------|--------|------------|-------------------|-----|----------| | GeViScope | 7720 | ✅ Ready | ✅ | ✅ | ✅ | ✅ | | G-Core | 7721 | ✅ Ready | ✅ | ✅ | ✅ | ✅ | | GeViServer | 7710 | ⚠️ Minimal | ⚠️ Events only | ❌ | ❌ | ❌ | **Decision:** GeViServer Bridge remains minimal per design ("Minimal GeViSoft usage"). --- ## Phase 0 Tasks ### Task 1: Event Notification Forwarding ✅ COMPLETED **Priority:** HIGH **Effort:** 4-6 hours **Status:** Done (2026-02-03) The bridges have PLC subscriptions but notifications are only logged. For the new architecture, events must be forwarded to the Flutter app. **Sub-tasks:** 1. [x] Add WebSocket endpoint to GeViScope Bridge for event streaming (`ws://localhost:7720/ws/events`) 2. [x] Add WebSocket endpoint to G-Core Bridge for event streaming (`ws://localhost:7721/ws/events`) 3. [x] Define event message format (JSON) 4. [x] Forward these events: - `ViewerConnected(Viewer, Channel, PlayMode)` - `ViewerCleared(Viewer)` - `ViewerSelectionChanged(Viewer, Channel, PlayMode)` - `EventStarted(EventID, TypeID, ForeignKey)` - `EventStopped(EventID, TypeID)` - `VCAlarmQueueNotification(Viewer, Notification, AlarmID, TypeID)` - `DigitalInput(Contact, State)` - `ConnectionLost` (bonus) **Event Message Format:** ```json { "timestamp": "2026-02-03T10:30:00.123Z", "server": "GeViScope-01", "action": "ViewerConnected", "params": { "Viewer": 5, "Channel": 101, "PlayMode": 11 } } ``` --- ### Task 2: Alarm Query Endpoints ✅ COMPLETED (Event-Based) **Priority:** HIGH **Effort:** 3-4 hours **Status:** Done (2026-02-03) Add alarm query capability to bridges (critical for "never miss alarms" requirement). **Finding:** GeViScope/G-Core SDKs don't have direct alarm query APIs like GeViSoft. They use event-based tracking. **Implementation:** - [x] Research GeViScope SDK - uses EventStarted/EventStopped notifications (no query API) - [x] Research G-Core SDK - uses EventStarted/EventStopped notifications (no query API) - [x] Implement `GET /alarms/active` - returns alarms tracked from events - [x] Implement `GET /alarms` - returns all tracked alarms (active + stopped) - [x] Track alarm state from EventStarted/EventStopped notifications **Important:** For complete alarm state on startup (before any events received), the Flutter app should query GeViServer bridge which has `GeViSQ_GetFirstAlarm/GetNextAlarm` methods. --- ### Task 3: Monitor State Query ✅ COMPLETED (Event-Based) **Priority:** MEDIUM **Effort:** 2-3 hours **Status:** Done (2026-02-03) Add ability to query current monitor state on startup. **Finding:** GeViScope/G-Core SDKs use ViewerConnected/ViewerCleared events for state changes. GetFirstVideoOutput is GeViSoft SDK only. **Implementation:** - [x] Research GeViScope SDK - uses ViewerConnected/ViewerCleared/ViewerSelectionChanged events - [x] Research G-Core SDK - same event-based approach - [x] Implement `GET /monitors` - returns all monitored states tracked from events - [x] Implement `GET /monitors/{viewerId}` - returns specific monitor state - [x] Track monitor state from ViewerConnected/ViewerCleared events **Important:** For complete monitor state on startup (before any events received), the Flutter app should either: 1. Trigger a ViewerConnectLive to each known monitor (will fire ViewerConnected event) 2. Query GeViServer bridge if GeViSoft integration is acceptable --- ### Task 4: Server Configuration Documentation ✅ COMPLETED **Priority:** MEDIUM **Effort:** 2-3 hours **Status:** Done (2026-02-03) Document server configurations for deployment. **Sub-tasks:** 1. [x] Create `servers.json` template with all server definitions 2. [x] Document camera ID ranges per server 3. [x] Document monitor ID mappings 4. [x] Create `crossswitch-rules.json` template 5. [x] Create `keyboards.json` template **Files Created:** - `C:\DEV\COPILOT_D6\config\servers.json.template` - `C:\DEV\COPILOT_D6\config\crossswitch-rules.json.template` - `C:\DEV\COPILOT_D6\config\keyboards.json.template` --- ### Task 5: Bridge Health Checks ✅ COMPLETED **Priority:** MEDIUM **Effort:** 1-2 hours **Status:** Done (2026-02-03) Enhance health check endpoints for production monitoring. **Sub-tasks:** 1. [x] Add detailed status to `/status` endpoint: - `is_connected` (bool) - `address` (server address) - `connection_duration_sec` - `event_count` (since connection) - `websocket_clients` (connected WS clients) - `plc_active` (bool) 2. [x] Add `/health` endpoint for load balancer probes 3. [ ] Add connection auto-reconnect logic (deferred to Phase 1) --- ### Task 6: Integration Testing ⬜ IN PROGRESS **Priority:** HIGH **Effort:** 4-6 hours Test bridges against actual servers. **Sub-tasks:** 1. [ ] Test GeViScope Bridge against real GeViScope server - [ ] Connection/disconnection - [ ] ViewerConnectLive - [ ] PTZ control - [ ] Event reception via WebSocket 2. [ ] Test G-Core Bridge against real G-Core server - [ ] Same tests as above 3. [x] Create test scripts (HTTP files) - `C:\DEV\COPILOT_D6\tests\test-geviscope.http` - `C:\DEV\COPILOT_D6\tests\test-gcore.http` 4. [ ] Document any SDK issues found --- ### Task 7: Logging Standardization ⬜ **Priority:** LOW **Effort:** 2 hours Standardize logging format for Kibana integration. **Sub-tasks:** 1. [ ] Configure Serilog with JSON formatter 2. [ ] Add structured logging fields: - keyboard_id - server_id - command - duration_ms - success 3. [ ] Configure log rotation 4. [ ] Test log output format --- ## File Structure After Phase 0 ``` C:\DEV\COPILOT_D6\ ├── docs\ │ ├── NEW_SYSTEM_DESIGN_SUMMARY.md │ ├── IMPLEMENTATION_QUICK_REFERENCE.md │ └── plans\ │ └── PHASE_0_INFRASTRUCTURE.md ├── config\ │ ├── servers.json.template ✅ Created │ ├── crossswitch-rules.json.template ✅ Created │ └── keyboards.json.template ✅ Created └── tests\ ├── test-geviscope.http ✅ Created └── test-gcore.http ✅ Created Bridges (existing, enhanced): ├── C:\DEV\COPILOT\geviscope-bridge\ ✅ WebSocket added └── C:\DEV\COPILOT\gcore-bridge\ ✅ WebSocket added ``` --- ## Success Criteria - [x] Events are streamed via WebSocket from both bridges - [x] Alarm state can be queried on demand (event-based tracking + `/alarms/active` endpoint) - [x] Monitor state can be queried on demand (event-based tracking + `/monitors` endpoint) - [x] Configuration templates are documented - [ ] All bridge endpoints tested against real servers - [ ] Logging format matches ELK requirements (Task 7 - pending, low priority) --- ## Dependencies - Access to GeViScope server for testing - Access to G-Core server for testing - GeViScope SDK documentation (chunk files available) - G-Core SDK documentation (chunk files available) --- ## Next Phase After Phase 0, proceed to **Phase 1: Flutter Keyboard Core** - Keyboard layout UI - Direct command execution - Server routing logic - State notification subscription