Files
geutebruck/ACTION_MAPPING_STRUCTURE_GUIDE.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

7.1 KiB

Action Mapping Binary Structure - Complete Guide

Summary

Based on analysis of TestMKS_original.set vs TestMKS_added_mapping.set, this document explains how action mappings are stored and how to programmatically add thousands of them.

Binary Structure

Overall Format

MARKER SECTION:
├─ 'ules' (4 bytes) - Action mapping marker
├─ Length (4 bytes, little-endian) - Length of marker name/data section
└─ Marker Name/Data Section (variable length)
   ├─ Metadata bytes
   ├─ Properties (optional, multiple)
   │  └─ Each property: 01 <len> <.name> <value_marker> <value>
   └─ Additional metadata

ACTION SECTION (follows marker section):
├─ Action Entry 1
│  ├─ Entry number (01 for first, 02 for second, etc.)
│  ├─ Metadata: 05 00 00 00
│  ├─ Action data: 07 01 40 <len_u16_LE> <action_string>
│  └─ Additional metadata (varies)
├─ Action Entry 2
│  └─ (same structure)
└─ ...

NEXT MARKER:
└─ 05 'Rules' or next 'ules' marker

Example 1: Simple Mapping (No Parameters)

Hex Dump (offset 0x41433):

75 6C 65 73    - 'ules' marker
02 00 00 00    - Length: 2 bytes
00 01          - Marker data (2 bytes)

31 05 00 00 00 - Action entry #1 metadata
07 01 40       - Action marker
0B 00          - Length: 11 bytes (little-endian)
47 53 43 20 50 61 6E 4C 65 66 74  - "GSC PanLeft"
...

Example 2: Mapping with Parameters

Hex Dump (offset 0x3D90D):

75 6C 65 73    - 'ules' marker
40 00 00 00    - Length: 64 bytes
00 01          - Start of marker data

# Properties within marker data:
01             - Property marker
0B             - Name length: 11
2E 53 77 69 74 63 68 4D 6F 64 65  - ".SwitchMode"
00             - Value type: null

01             - Property marker
0C             - Name length: 12
2E 56 69 64 65 6F 4F 75 74 70 75 74  - ".VideoOutput"
00             - Value type: null

# Then actions follow...

Property Value Types

Marker Type Structure
0x01 Boolean 01 <value> where value is 00 or 01
0x04 Integer 04 <int32_LE> (4 bytes, little-endian)
0x00 Null Just 00
0x07 String 07 <len> <string_bytes>

Action Entry Format

Each action entry consists of:

<entry_number> - 01, 02, 03, etc. (sequential)
05 00 00 00    - Metadata (always this sequence)
07 01 40       - Action marker (always this sequence)
<length>       - 2 bytes, little-endian (length of action string)
<action_name>  - UTF-8 encoded action name
04 02 40 21 00 00 00 00 - Additional metadata
04 02 40 40 <4 bytes>    - More metadata (varies)

Key Findings

1. File Reorganization

When you add a mapping using GeViSoft GUI:

  • The entire .set file is reorganized
  • All offsets change
  • Mappings may be reordered
  • Net result: +1 mapping but many bytes change

This means you cannot simply append to the end of the file!

2. Insertion Strategy

To programmatically add mappings:

Option A: Parse → Modify → Rebuild

  1. Parse the entire .set file
  2. Add new mapping to internal structure
  3. Regenerate the entire file
  4. Write back to disk

Option B: Use GeViSoft API (if available)

  1. Use SetupClient API to modify configuration
  2. Let GeViSoft handle file format

Option C: Template-Based (recommended for bulk)

  1. Create template mappings in GUI
  2. Export configuration
  3. Use find/replace to duplicate with new IDs
  4. Import back

3. Complexity Factors

  • Offsets must be recalculated
  • File structure is tightly packed
  • No obvious "free space" to insert data
  • Dependencies between sections unknown
  • Checksum or validation may exist

Programmatic Approach

Step 1: Create Mapping Binary Data

def create_action_mapping(actions, parameters=None):
    """
    Generate binary data for an action mapping

    Args:
        actions: List of action strings
        parameters: Dict of parameter_name -> value (optional)

    Returns:
        bytes: Complete mapping binary data
    """
    import struct

    # Build marker name/data section
    marker_data = bytearray()
    marker_data.extend(b'\x00\x01')  # Base metadata

    # Add parameters if any
    if parameters:
        for name, value in parameters.items():
            # Property marker
            marker_data.append(0x01)
            # Name with leading dot
            name_with_dot = f".{name}"
            name_bytes = name_with_dot.encode('utf-8')
            marker_data.append(len(name_bytes))
            marker_data.extend(name_bytes)

            # Value
            if value is None:
                marker_data.append(0x00)
            elif isinstance(value, bool):
                marker_data.append(0x01)
                marker_data.append(0x01 if value else 0x00)
            elif isinstance(value, int):
                marker_data.append(0x04)
                marker_data.extend(struct.pack('<i', value))

    # Build complete marker section
    result = bytearray()
    result.extend(b'ules')  # Marker
    result.extend(struct.pack('<I', len(marker_data)))  # Length
    result.extend(marker_data)  # Data

    # Add actions
    for i, action in enumerate(actions, 1):
        # Entry number
        result.append(i)
        # Metadata
        result.extend(b'\x05\x00\x00\x00')
        # Action marker
        result.extend(b'\x07\x01\x40')
        # Action length and string
        action_bytes = action.encode('utf-8')
        result.extend(struct.pack('<H', len(action_bytes)))
        result.extend(action_bytes)
        # Additional metadata (simplified)
        result.extend(b'\x04\x02\x40\x21\x00\x00\x00\x00')
        result.extend(b'\x04\x02\x40\x40\x00\x10\x00\x00')

    return bytes(result)

Step 2: Insert into Configuration

The recommended approach is to:

  1. Read entire configuration using existing parser
  2. Add new mapping to internal structure
  3. Regenerate file using configuration writer

Practical Recommendations

For Adding Thousands of Mappings

Best Approach:

  1. Use C# SDK + Configuration API

    // Pseudo-code
    var config = parser.Parse(file);
    for (int i = 0; i < 1000; i++) {
        var mapping = new ActionMapping {
            Actions = new[] { $"Action_{i}" },
            Parameters = new Dictionary<string, object>()
        };
        config.AddMapping(mapping);
    }
    writer.Write(config, outputFile);
    
  2. Batch Process via GUI Templates

    • Create 1 mapping template in GUI
    • Export configuration as JSON/XML (if supported)
    • Programmatically duplicate + modify
    • Import back
  3. Direct Binary Manipulation (risky!)

    • Parse existing file completely
    • Understand all section dependencies
    • Insert mappings
    • Rebuild file with correct offsets

Next Steps

For your use case (adding thousands of mappings), I recommend:

  1. Extend C# Parser to support WRITING (currently read-only)
  2. Create AddActionMapping() method in ConfigurationService
  3. Batch add via gRPC/REST API
  4. Write back to .set file

Would you like me to:

  • Create C# writer for .set files
  • Build Python script for bulk mapping creation
  • Extend the gRPC API to support CREATE operations
  • Create a bulk import tool (CSV → action mappings)