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>
84 lines
3.0 KiB
Python
84 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Analyze the structure of action mappings in the .set file to understand input/output and parameters"""
|
|
import sys
|
|
import struct
|
|
|
|
# Read the GeViSoft configuration file directly
|
|
config_file = r"C:\GEVISOFT\setup_config_20251212_122429.dat"
|
|
|
|
try:
|
|
with open(config_file, "rb") as f:
|
|
data = f.read()
|
|
|
|
print(f"Read {len(data)} bytes from {config_file}")
|
|
|
|
# Look for "ules" marker at offset 253894 (first action mapping)
|
|
offset = 253894
|
|
|
|
print(f"\nAnalyzing action mapping at offset {offset}")
|
|
print("=" * 80)
|
|
|
|
# Print 1000 bytes from this offset with analysis
|
|
window_start = offset - 100
|
|
window_end = offset + 900
|
|
|
|
for i in range(window_start, window_end, 16):
|
|
# Hex bytes
|
|
hex_line = ' '.join(f'{data[i+j]:02X}' if i+j < len(data) else ' ' for j in range(16))
|
|
|
|
# ASCII representation
|
|
ascii_line = ''
|
|
for j in range(16):
|
|
if i+j < len(data):
|
|
b = data[i+j]
|
|
ascii_line += chr(b) if 32 <= b < 127 else '.'
|
|
else:
|
|
ascii_line += ' '
|
|
|
|
# Annotations for key patterns
|
|
annotation = ''
|
|
if i == offset:
|
|
annotation = ' <-- MARKER START (ules)'
|
|
elif data[i:i+2] == b'\x07\x01' and i > offset:
|
|
annotation = ' <-- STRING marker'
|
|
elif data[i:i+3] == b'\x07\x01\x40' and i > offset:
|
|
annotation = ' <-- ACTION marker'
|
|
elif data[i] == 0x01 and i > offset:
|
|
annotation = ' <-- BOOLEAN'
|
|
elif data[i] == 0x04 and i > offset:
|
|
annotation = ' <-- INTEGER'
|
|
elif data[i] == 0x05 and i > offset:
|
|
annotation = ' <-- MARKER'
|
|
|
|
print(f"{i:08X}: {hex_line:<48} | {ascii_line}{annotation}")
|
|
|
|
# Look for patterns that might indicate parameters
|
|
print("\n" + "=" * 80)
|
|
print("Looking for parameter patterns around actions...")
|
|
print("=" * 80)
|
|
|
|
# Search for "VideoInput" string
|
|
search_terms = [b"VideoInput", b"G-core", b"alias", b"CrossSwitch"]
|
|
for term in search_terms:
|
|
pos = data.find(term, offset, offset + 1000)
|
|
if pos != -1:
|
|
print(f"\nFound '{term.decode()}' at offset {pos} ({pos - offset} bytes from marker)")
|
|
# Show context
|
|
start = max(0, pos - 30)
|
|
end = min(len(data), pos + 100)
|
|
context = data[start:end]
|
|
|
|
# Hex dump of context
|
|
for i in range(0, len(context), 16):
|
|
actual_offset = start + i
|
|
hex_bytes = ' '.join(f'{b:02X}' for b in context[i:i+16])
|
|
ascii_chars = ''.join(chr(b) if 32 <= b < 127 else '.' for b in context[i:i+16])
|
|
marker = ' <--' if actual_offset == pos else ''
|
|
print(f" {actual_offset:08X}: {hex_bytes:<48} | {ascii_chars}{marker}")
|
|
|
|
except FileNotFoundError:
|
|
print(f"Error: Could not find file {config_file}")
|
|
print("Please make sure the GeViSoft configuration file exists.")
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|