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

258 lines
7.1 KiB
Markdown

# 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
```python
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**
```csharp
// 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)