This MVP release provides a complete full-stack solution for managing action mappings in Geutebruck's GeViScope and GeViSoft video surveillance systems. ## Features ### Flutter Web Application (Port 8081) - Modern, responsive UI for managing action mappings - Action picker dialog with full parameter configuration - Support for both GSC (GeViScope) and G-Core server actions - Consistent UI for input and output actions with edit/delete capabilities - Real-time action mapping creation, editing, and deletion - Server categorization (GSC: prefix for GeViScope, G-Core: prefix for G-Core servers) ### FastAPI REST Backend (Port 8000) - RESTful API for action mapping CRUD operations - Action template service with comprehensive action catalog (247 actions) - Server management (G-Core and GeViScope servers) - Configuration tree reading and writing - JWT authentication with role-based access control - PostgreSQL database integration ### C# SDK Bridge (gRPC, Port 50051) - Native integration with GeViSoft SDK (GeViProcAPINET_4_0.dll) - Action mapping creation with correct binary format - Support for GSC and G-Core action types - Proper Camera parameter inclusion in action strings (fixes CrossSwitch bug) - Action ID lookup table with server-specific action IDs - Configuration reading/writing via SetupClient ## Bug Fixes - **CrossSwitch Bug**: GSC and G-Core actions now correctly display camera/PTZ head parameters in GeViSet - Action strings now include Camera parameter: `@ PanLeft (Comment: "", Camera: 101028)` - Proper filter flags and VideoInput=0 for action mappings - Correct action ID assignment (4198 for GSC, 9294 for G-Core PanLeft) ## Technical Stack - **Frontend**: Flutter Web, Dart, Dio HTTP client - **Backend**: Python FastAPI, PostgreSQL, Redis - **SDK Bridge**: C# .NET 8.0, gRPC, GeViSoft SDK - **Authentication**: JWT tokens - **Configuration**: GeViSoft .set files (binary format) ## Credentials - GeViSoft/GeViScope: username=sysadmin, password=masterkey - Default admin: username=admin, password=admin123 ## Deployment All services run on localhost: - Flutter Web: http://localhost:8081 - FastAPI: http://localhost:8000 - SDK Bridge gRPC: localhost:50051 - GeViServer: localhost (default port) Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.3 KiB
SDK Alarm Query Approach
Discovery Summary
After extracting and analyzing the GeViSoft .NET SDK API documentation (2403 HTML files from CHM), I found the correct approach to read action mappings from the live GeViSoft instance.
Key Finding
SetupClient functions are NOT exposed in the .NET SDK. The SDK documentation explicitly states:
"The SetupClient functions are used by GeViSet to change the server setup. They are usually not of interest for SDK developers."
Instead, the SDK provides State Query actions to read alarm configurations.
The Solution: State Queries
Action mappings in GeViSoft are stored as Alarms. We can query them using these state query actions:
Available Query Actions
| Action | Description (German → English) | Purpose |
|---|---|---|
GeViSQ_GetFirstAlarm |
Liefert die Information zu dem ersten Alarm | Get first alarm information |
GeViSQ_GetNextAlarm |
Liefert die Information zu dem naechsten Alarm | Get next alarm information |
GeViSQ_GetAlarms |
Liefert die Information zum bestimmten Alarm | Get specific alarm by ID |
GeViSQ_GetAlarmsByName |
Liefert die Information zum bestimmten Alarm | Get specific alarm by name |
GeViDBQ_CreateAlarmQuery |
Startet eine Abfrage ueber die Alarmtabelle | Start query over alarm table |
How to Enumerate All Alarms
// 1. Create query for first alarm
var query = new GeViSQ_GetFirstAlarm(
initActiveOnly: false, // false = all alarms (not just active)
initEnabledOnly: false // false = both enabled and disabled
);
// 2. Send query to GeViServer
await geviDatabase.SendMessageAsync(query);
// 3. Register callback to receive answer
geviDatabase.OnNewGeViSA_FirstAlarm += HandleFirstAlarmAnswer;
// 4. Iterate through remaining alarms
geviDatabase.OnNewGeViSA_NextAlarm += HandleNextAlarmAnswer;
// In handlers, send GeViSQ_GetNextAlarm to get subsequent alarms
Implementation Plan
Phase 1: Alarm Query Service (C# SDK Bridge)
Create AlarmQueryService.cs:
public class AlarmQueryService
{
private readonly GeViDatabaseWrapper _database;
private readonly List<AlarmInfo> _alarmCache = new();
public async Task<List<AlarmInfo>> GetAllAlarmsAsync()
{
_alarmCache.Clear();
// Send first alarm query
var query = new GeViSQ_GetFirstAlarm(false, false);
await _database.SendMessageAsync(query);
// Wait for answers (with timeout)
// Answers arrive via callbacks
return _alarmCache;
}
private void HandleFirstAlarmAnswer(GeViSA_FirstAlarmEventArgs e)
{
// Parse alarm data
var alarm = ParseAlarmData(e);
_alarmCache.Add(alarm);
// Request next alarm
var nextQuery = new GeViSQ_GetNextAlarm();
_database.SendMessageAsync(nextQuery);
}
private void HandleNextAlarmAnswer(GeViSA_NextAlarmEventArgs e)
{
if (e.HasMoreAlarms)
{
var alarm = ParseAlarmData(e);
_alarmCache.Add(alarm);
// Request next
var nextQuery = new GeViSQ_GetNextAlarm();
_database.SendMessageAsync(nextQuery);
}
}
}
Phase 2: Identify Action Mapping Alarms
Not all alarms are action mappings. Need to filter by:
- Alarm type/category
- Input action field presence
- Output actions field presence
Example alarm structure (from GeViDB.mdb):
ID: 12345
Name: "Motion Detection Auto-Route"
Type: "Action Mapping" (or similar type ID)
InputAction: "VMD_Start(101038)"
OutputActions: ["CrossSwitch(101038, 1, 0)"]
Enabled: true
Phase 3: Update ActionMappingHandler
Modify ActionMappingHandler.cs:
public class ActionMappingHandler
{
private readonly AlarmQueryService _alarmQuery;
public async Task<List<ActionMappingConfig>> GetAllActionMappingsAsync()
{
// Query all alarms from GeViServer
var allAlarms = await _alarmQuery.GetAllAlarmsAsync();
// Filter to only action mapping type alarms
var actionMappings = allAlarms
.Where(IsActionMapping)
.Select(MapToActionMappingConfig)
.ToList();
return actionMappings;
}
private bool IsActionMapping(AlarmInfo alarm)
{
// Filter logic:
// - Has input action
// - Has output actions
// - Type indicates it's an action mapping
return !string.IsNullOrEmpty(alarm.InputAction) &&
alarm.OutputActions?.Any() == true;
}
}
Phase 4: Callback Registration
Need to investigate:
- What answer types are returned by these queries
- How to register callbacks for alarm answers
- What fields are available in the answer objects
Next Steps
- Find alarm answer event types - Search for
GeViSA_FirstAlarm,GeViSA_NextAlarmevent args - Understand alarm data structure - What fields are available?
- Test query execution - Send a GetFirstAlarm query and inspect the response
- Implement full enumeration - Iterate through all alarms
- Filter for action mappings - Identify which alarms are action mappings
- Map to gRPC model - Convert alarm data to ActionMappingConfig
Advantages of This Approach
✅ Uses official SDK API (not direct database access) ✅ Reads LIVE data from GeViServer (not stale database copy) ✅ Same data that GeViSet would see ✅ Respects GeViServer's locking and transaction handling ✅ Can receive real-time updates via alarm events
Questions to Resolve
- Answer event types: What are the exact event arg types for alarm query answers?
- Alarm fields: What properties are available on alarm answer objects?
- Action mapping identification: How to distinguish action mapping alarms from other alarm types?
- Write operations: How to create/update/delete alarms (action mappings)?
- Real-time updates: Can we subscribe to alarm change notifications?
Documentation Files
Extracted CHM documentation location:
C:\DEV\COPILOT\geutebruck-api\docs\chm-extracted\
Key files:
class_g_e_u_t_e_b_r_u_e_c_k_1_1_ge_vi_soft_s_d_k_n_e_t_1_1_actions_wrapper_1_1_ge_vi_database-members.html- All GeViDatabase methodsclass_g_e_u_t_e_b_r_u_e_c_k_1_1_ge_vi_soft_s_d_k_n_e_t_1_1_actions_wrapper_1_1_state_queries_1_1_ge_vi_s_q___get_first_alarm.html- GetFirstAlarm documentation