Files
geutebruck/geutebruck-api/docs/ACTION_MAPPING_IMPLEMENTATION.md
Administrator 14893e62a5 feat: Geutebruck GeViScope/GeViSoft Action Mapping System - MVP
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>
2025-12-31 18:10:54 +01:00

13 KiB

Action Mapping Implementation Guide

Overview

This document describes the GeViSoft action mapping implementation, which provides automated response capabilities for the Geutebruck surveillance system. Action mappings allow you to trigger one or more actions based on an input action (e.g., route a camera to a monitor when motion is detected).

Architecture

Components

┌─────────────────────────────────────────────────────────────┐
│                     Python FastAPI                           │
│  ┌─────────────┐  ┌──────────────┐  ┌──────────────────┐   │
│  │  Router     │→ │  Service     │→ │  Database Model  │   │
│  │ (REST API)  │  │  (Business)  │  │  (PostgreSQL)    │   │
│  └─────────────┘  └──────────────┘  └──────────────────┘   │
│         ↓                                                     │
└─────────┼─────────────────────────────────────────────────────┘
          │ gRPC
          ↓
┌─────────────────────────────────────────────────────────────┐
│              C# SDK Bridge (gRPC Server)                     │
│  ┌────────────────────┐    ┌──────────────────────────┐    │
│  │ ActionMapping      │ →  │  GeViDatabaseWrapper     │    │
│  │ Handler            │    │  (GeViSoft Connection)   │    │
│  └────────────────────┘    └──────────────────────────┘    │
│                                      ↓                       │
└──────────────────────────────────────┼───────────────────────┘
                                       │ SDK
                                       ↓
                            ┌──────────────────────┐
                            │  GeViServer          │
                            │  (GeViSoft)          │
                            └──────────────────────┘

Data Flow

  1. Create/Update: REST API → Database → SDK Bridge → GeViServer
  2. Execute: GeViServer Event → SDK Bridge Callback → Execute Output Actions
  3. List/Query: REST API → Database

Implementation Details

Backend (C# SDK Bridge)

Files Created/Modified

  1. Configuration

    • appsettings.json - Added GeViSoft connection settings
    • Program.cs - Dual connection (GeViScope + GeViSoft)
  2. SDK Layer

    • SDK/ActionMappingHandler.cs - Core action mapping logic
    • In-memory storage for MVP (database sync in production)
    • Input action detection and output action execution
  3. gRPC Service

    • Services/ActionMappingService.cs - gRPC service implementation
    • Protos/actionmapping.proto - Protocol buffer definitions
  4. Connection Management

    • Separate GeViDatabaseWrapper instances for GeViScope and GeViSoft
    • Non-fatal GeViSoft connection (video ops work without it)

Key Classes

ActionMappingHandler (SDK/ActionMappingHandler.cs):

public class ActionMappingHandler
{
    public async Task<List<ActionMappingConfig>> EnumerateActionMappingsAsync(bool enabledOnly = false)
    public async Task<ActionMappingConfig> CreateActionMappingAsync(...)
    public async Task<ActionMappingConfig?> UpdateActionMappingAsync(...)
    public async Task<bool> DeleteActionMappingAsync(string id)
    public async Task<bool> ExecuteActionMappingAsync(string inputAction)
}

ActionMappingConfig (Data Model):

public class ActionMappingConfig
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string InputAction { get; set; }
    public List<string> OutputActions { get; set; }
    public bool Enabled { get; set; }
    public int ExecutionCount { get; set; }
    public DateTime? LastExecuted { get; set; }
}

Frontend (Python FastAPI)

Files Created

  1. Database Models

    • models/action_mapping.py - SQLAlchemy models
      • ActionMapping - Main table
      • ActionMappingExecution - Execution log for audit
  2. Schemas

    • schemas/action_mapping.py - Pydantic models
      • ActionMappingCreate - Request for creating
      • ActionMappingUpdate - Request for updating
      • ActionMappingResponse - Response model
      • ActionMappingListResponse - List response
  3. Service Layer

    • services/action_mapping_service.py - Business logic
      • Database CRUD operations
      • SDK Bridge synchronization (TODO)
  4. API Routes

    • routers/action_mappings.py - REST endpoints
      • GET /api/v1/action-mappings - List all
      • GET /api/v1/action-mappings/{id} - Get one
      • POST /api/v1/action-mappings - Create
      • PUT /api/v1/action-mappings/{id} - Update
      • DELETE /api/v1/action-mappings/{id} - Delete
  5. Migrations

    • migrations/versions/20251210_action_mappings.py - Database schema

Database Schema

action_mappings table:

CREATE TABLE action_mappings (
    id UUID PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    input_action VARCHAR(500) NOT NULL,
    output_actions VARCHAR[] NOT NULL,
    geviscope_instance_scope VARCHAR(50),
    enabled BOOLEAN NOT NULL DEFAULT true,
    execution_count INTEGER NOT NULL DEFAULT 0,
    last_executed TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE NOT NULL,
    updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
    created_by UUID NOT NULL,
    metadata_json JSONB
);

CREATE INDEX ix_action_mappings_input_action ON action_mappings(input_action);
CREATE INDEX ix_action_mappings_enabled ON action_mappings(enabled);
CREATE INDEX ix_action_mappings_instance_scope ON action_mappings(geviscope_instance_scope);

action_mapping_executions table:

CREATE TABLE action_mapping_executions (
    id UUID PRIMARY KEY,
    mapping_id UUID NOT NULL,
    input_action VARCHAR(500) NOT NULL,
    output_actions_executed VARCHAR[] NOT NULL,
    success BOOLEAN NOT NULL,
    error_message TEXT,
    executed_at TIMESTAMP WITH TIME ZONE NOT NULL,
    duration_ms INTEGER,
    context_json JSONB
);

CREATE INDEX ix_action_mapping_executions_mapping_id ON action_mapping_executions(mapping_id);
CREATE INDEX ix_action_mapping_executions_executed_at ON action_mapping_executions(executed_at);

API Usage Examples

Create Action Mapping

curl -X POST http://localhost:8000/api/v1/action-mappings \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Motion Detection Alert",
    "description": "Route camera to monitor when motion detected",
    "input_action": "VMD_Start(101038)",
    "output_actions": [
      "CrossSwitch(101038, 1, 0)",
      "SendMail(security@example.com, Motion Detected)"
    ],
    "enabled": true
  }'

List Action Mappings

curl -X GET "http://localhost:8000/api/v1/action-mappings?enabled_only=true" \
  -H "Authorization: Bearer $TOKEN"

Update Action Mapping

curl -X PUT http://localhost:8000/api/v1/action-mappings/{id} \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": false,
    "description": "Temporarily disabled"
  }'

Delete Action Mapping

curl -X DELETE http://localhost:8000/api/v1/action-mappings/{id} \
  -H "Authorization: Bearer $TOKEN"

Common Use Cases

1. Motion Detection → Camera Routing

Scenario: When motion is detected on a camera, route it to monitor 1

{
  "name": "VMD Auto-Route",
  "input_action": "VMD_Start(101038)",
  "output_actions": ["CrossSwitch(101038, 1, 0)"]
}

2. Door Contact → Alarm Response

Scenario: When door contact opens, flash beacon and send email

{
  "name": "Door Open Alert",
  "input_action": "InputContact(3, false)",
  "output_actions": [
    "AlternateContact(2, 1000, 500)",
    "SendMail(security@example.com, Door Opened)"
  ]
}

3. Alarm → Multi-Action Response

Scenario: When alarm triggers, route cameras, activate outputs, send notifications

{
  "name": "Intrusion Alarm Response",
  "input_action": "AlarmStart(1)",
  "output_actions": [
    "CrossSwitch(5, 1, 0)",
    "CrossSwitch(6, 2, 0)",
    "OpenContact(10)",
    "SendMail(security@example.com, ALARM: Intrusion Detected)",
    "StartRecording(5)",
    "StartRecording(6)"
  ]
}

Testing

Diagnostic Tools

  1. SDK Bridge Diagnostic (DiagnoseActionMapping.exe):

    cd C:\DEV\COPILOT\geutebruck-api\src\sdk-bridge\DiagnoseActionMapping
    dotnet run -- localhost sysadmin password
    
  2. Python API Test (test_action_mappings.py):

    cd C:\DEV\COPILOT\geutebruck-api
    python tools/test_action_mappings.py --url http://localhost:8000
    

Manual Testing

  1. Start SDK Bridge:

    cd C:\DEV\COPILOT\geutebruck-api\src\sdk-bridge\GeViScopeBridge
    dotnet run
    
  2. Run Database Migrations:

    cd C:\DEV\COPILOT\geutebruck-api\src\api
    alembic upgrade head
    
  3. Start API Server:

    cd C:\DEV\COPILOT\geutebruck-api\src\api
    python main.py
    
  4. Access Swagger UI:

Security Considerations

Authentication

  • Viewer Role: Can list and view action mappings (read-only)
  • Operator Role: Can list and view (no create/edit/delete)
  • Administrator Role: Full CRUD permissions

Validation

  • Input action format validated
  • At least one output action required
  • Maximum length constraints on all fields
  • SQL injection prevention via parameterized queries

Audit Trail

All action mapping operations logged:

  • Who created/updated/deleted
  • When operation occurred
  • IP address of requester
  • Full change history

Limitations & Future Enhancements

Current MVP Limitations

  1. In-Memory Storage: SDK Bridge stores mappings in memory, not GeViServer config
  2. No Callback Registration: Input actions not automatically detected (would require event monitoring)
  3. No GeViSet Integration: Cannot import/export from GeViSet application
  4. No Pattern Matching: Input actions must match exactly (no wildcards)

Planned Enhancements

  1. Direct GeViServer Integration:

    • Store mappings in GeViServer configuration database
    • Use SetupClient API for configuration management
    • Sync with GeViSet application
  2. Event Callback System:

    • Register SDK callbacks for input action detection
    • Automatic execution of output actions
    • Real-time processing
  3. Advanced Features:

    • Action patterns with wildcards (e.g., VMD_Start(*))
    • Conditional logic (if/then/else)
    • Time-based enabling/disabling
    • Action chaining and dependencies
  4. Monitoring & Analytics:

    • Real-time execution dashboard
    • Performance metrics
    • Failure rate tracking
    • Execution history visualization

Troubleshooting

Connection Issues

Problem: SDK Bridge cannot connect to GeViSoft

Solutions:

  1. Check GeViServer is running
  2. Verify connection settings in appsettings.json
  3. Check firewall rules
  4. Review SDK Bridge logs: logs/sdk-bridge-*.log

Database Issues

Problem: Migration fails or table not found

Solutions:

  1. Run migrations: alembic upgrade head
  2. Check database connection in config.py
  3. Verify PostgreSQL is running
  4. Check migration logs

API Errors

Problem: 403 Forbidden when creating action mapping

Solutions:

  1. Ensure user has Administrator role
  2. Check JWT token is valid
  3. Verify authentication middleware is working

Problem: 500 Internal Server Error

Solutions:

  1. Check API logs: logs/api-*.log
  2. Verify SDK Bridge is running
  3. Check database connectivity
  4. Review error details in response

References

Support

For issues or questions:

  1. Check this documentation
  2. Review SDK Bridge logs
  3. Test with diagnostic tools
  4. Check GeViSoft SDK documentation
  5. Contact Geutebruck support for SDK-specific issues