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>
This commit is contained in:
295
GEVISET_PARSER_README.md
Normal file
295
GEVISET_PARSER_README.md
Normal file
@@ -0,0 +1,295 @@
|
||||
# GeViSet Configuration File Parser
|
||||
|
||||
A portable Python parser and generator for Geutebruck GeViSet `.set` configuration files.
|
||||
|
||||
## Features
|
||||
|
||||
- **Parse** `.set` binary configuration files to JSON format
|
||||
- **Generate** `.set` files from JSON configuration
|
||||
- **Cross-platform**: Works on Windows, Linux, and macOS
|
||||
- **Pure Python**: No external dependencies except Python 3.6+
|
||||
|
||||
## Binary Format Specification
|
||||
|
||||
The GeViSet `.set` file format is a proprietary binary format with the following structure:
|
||||
|
||||
### Type Markers
|
||||
- `0x00` - Section/Container
|
||||
- `0x01` - Boolean (1 byte: 0x00 or 0x01)
|
||||
- `0x02` - 64-bit integer (8 bytes, little-endian)
|
||||
- `0x04` - 32-bit integer (4 bytes, little-endian)
|
||||
- `0x07` - Property name (1-byte length prefix)
|
||||
- `0x08` - String value (2-byte length prefix)
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
[Section]
|
||||
0x00 - Section marker
|
||||
[1-byte length] - Name length
|
||||
[name bytes] - Section name (UTF-8)
|
||||
[4-byte int32] - Metadata value
|
||||
[1-byte] - Metadata flags
|
||||
[Properties/Subsections...]
|
||||
0x00 0x00 0x00... - End marker
|
||||
|
||||
[Property]
|
||||
0x07 - Property name marker
|
||||
[1-byte length] - Name length
|
||||
[name bytes] - Property name (UTF-8)
|
||||
[type marker] - Value type (0x01, 0x02, 0x04, or 0x08)
|
||||
[value bytes] - Value data
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
No installation required! Just copy `geviset_parser.py` to your system.
|
||||
|
||||
```bash
|
||||
# Download or copy the file
|
||||
cp geviset_parser.py /usr/local/bin/
|
||||
chmod +x /usr/local/bin/geviset_parser.py
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Command Line
|
||||
|
||||
#### Parse .set file to JSON
|
||||
```bash
|
||||
python3 geviset_parser.py config.set output.json
|
||||
```
|
||||
|
||||
#### Generate .set file from JSON
|
||||
```bash
|
||||
python3 geviset_parser.py config.json output.set
|
||||
```
|
||||
|
||||
### Python API
|
||||
|
||||
#### Parse a configuration file
|
||||
```python
|
||||
from geviset_parser import GeViSetParser
|
||||
|
||||
parser = GeViSetParser()
|
||||
config = parser.parse_file("GeViSoft.set")
|
||||
|
||||
# Access configuration
|
||||
print(config.keys()) # Top-level sections
|
||||
print(config['Users']['SysAdmin']['Password'])
|
||||
```
|
||||
|
||||
#### Modify and save configuration
|
||||
```python
|
||||
from geviset_parser import GeViSetParser, GeViSetGenerator
|
||||
from collections import OrderedDict
|
||||
|
||||
# Load existing configuration
|
||||
parser = GeViSetParser()
|
||||
config = parser.parse_file("GeViSoft.set")
|
||||
|
||||
# Modify user password (example - you'd need to hash it properly)
|
||||
if 'Users' in config and 'aa' in config['Users']:
|
||||
config['Users']['aa']['Password'] = 'new_hashed_password'
|
||||
|
||||
# Save modified configuration
|
||||
generator = GeViSetGenerator()
|
||||
generator.generate_file(config, "GeViSoft_modified.set")
|
||||
```
|
||||
|
||||
#### Create new configuration from scratch
|
||||
```python
|
||||
from geviset_parser import GeViSetGenerator
|
||||
from collections import OrderedDict
|
||||
|
||||
config = OrderedDict()
|
||||
config['MySection'] = OrderedDict()
|
||||
config['MySection']['_metadata'] = {'value': 0, 'flags': 0}
|
||||
config['MySection']['Enabled'] = True
|
||||
config['MySection']['Port'] = 8080
|
||||
config['MySection']['ServerName'] = 'localhost'
|
||||
|
||||
generator = GeViSetGenerator()
|
||||
generator.generate_file(config, "custom_config.set")
|
||||
```
|
||||
|
||||
## JSON Format
|
||||
|
||||
When exported to JSON, the configuration maintains an OrderedDict structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"GeViSoft Parameters": {
|
||||
"_metadata": {
|
||||
"value": 20,
|
||||
"flags": 0
|
||||
},
|
||||
"Alarms": {
|
||||
"_metadata": {
|
||||
"value": 0,
|
||||
"flags": 0
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"_metadata": {
|
||||
"value": 0,
|
||||
"flags": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"_metadata": {
|
||||
"value": 6,
|
||||
"flags": 7
|
||||
},
|
||||
"SysAdmin": {
|
||||
"_metadata": {
|
||||
"value": 0,
|
||||
"flags": 7
|
||||
},
|
||||
"Checksum": "340e1f3d767e056d5e9502c56fc9d73b",
|
||||
"Configured": true,
|
||||
"Description": "System Administrator",
|
||||
"Password": "abe6db4c9f5484fae8d79f2e868a673c"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Metadata
|
||||
|
||||
Each section includes a `_metadata` dictionary with:
|
||||
- `value`: 32-bit integer (purpose varies by section)
|
||||
- `flags`: 8-bit flags byte
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Extract User Passwords
|
||||
```python
|
||||
parser = GeViSetParser()
|
||||
config = parser.parse_file("GeViSoft.set")
|
||||
|
||||
if 'Users' in config:
|
||||
for user_name, user_data in config['Users'].items():
|
||||
if user_name != '_metadata' and isinstance(user_data, dict):
|
||||
password_hash = user_data.get('Password', '')
|
||||
print(f"User: {user_name}, Password Hash: {password_hash}")
|
||||
```
|
||||
|
||||
### Change Server Settings
|
||||
```python
|
||||
parser = GeViSetParser()
|
||||
config = parser.parse_file("GeViSoft.set")
|
||||
|
||||
# Modify GETAS TCP settings
|
||||
if 'GeViSoft Parameters' in config:
|
||||
getas = config['GeViSoft Parameters'].get('GETAS', {})
|
||||
getas['TCPEnabled'] = True
|
||||
getas['TCPPort'] = 7777
|
||||
getas['MaxTCPConnections'] = 10
|
||||
|
||||
# Save
|
||||
generator = GeViSetGenerator()
|
||||
generator.generate_file(config, "GeViSoft_modified.set")
|
||||
```
|
||||
|
||||
### Export Configuration for Backup
|
||||
```bash
|
||||
# Convert to JSON for version control
|
||||
python3 geviset_parser.py GeViSoft.set backup.json
|
||||
|
||||
# Edit in text editor
|
||||
vi backup.json
|
||||
|
||||
# Convert back to .set
|
||||
python3 geviset_parser.py backup.json GeViSoft_restored.set
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Password Hashing
|
||||
|
||||
The GeViSet format stores password hashes, not plaintext passwords. The exact hashing algorithm used by GeViSet is proprietary. When modifying user passwords:
|
||||
|
||||
1. **Do NOT** store plaintext passwords
|
||||
2. Use the same hashing algorithm as GeViSet (may require reverse engineering)
|
||||
3. Consider using the official GeViSet tool for password changes
|
||||
|
||||
### Checksums
|
||||
|
||||
Some sections include checksum fields (32-character hex strings that appear to be MD5 hashes). These may be used for integrity verification. When modifying configuration:
|
||||
|
||||
1. Preserve checksums if possible
|
||||
2. Or recalculate them based on the section content (algorithm TBD)
|
||||
3. Test modified configurations thoroughly before deployment
|
||||
|
||||
## Limitations
|
||||
|
||||
- Checksum/hash algorithms are not yet fully reverse-engineered
|
||||
- Some metadata field meanings are unknown
|
||||
- Binary format may vary between GeViSet versions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Parse Errors
|
||||
|
||||
If you encounter parse errors:
|
||||
|
||||
1. **Check file integrity**: Ensure the .set file isn't corrupted
|
||||
2. **Verify format version**: This parser was developed for GeViSet 7.x
|
||||
3. **Enable debug output**: Check warnings during parsing
|
||||
|
||||
### Generated Files Don't Work
|
||||
|
||||
If generated .set files don't load in GeViSet:
|
||||
|
||||
1. **Preserve metadata**: Ensure `_metadata` fields are maintained
|
||||
2. **Check checksums**: Some checksums may need recalculation
|
||||
3. **Verify structure**: Compare with original file structure
|
||||
|
||||
### Stack Overflow / Recursion Errors
|
||||
|
||||
If you hit recursion limits with very deeply nested configurations:
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.setrecursionlimit(5000) # Increase from default 1000
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Parse a sample file
|
||||
python3 geviset_parser.py sample.set sample.json
|
||||
|
||||
# Generate it back
|
||||
python3 geviset_parser.py sample.json sample_regenerated.set
|
||||
|
||||
# Compare
|
||||
diff <(xxd sample.set) <(xxd sample_regenerated.set)
|
||||
```
|
||||
|
||||
### Contributing
|
||||
|
||||
To contribute improvements:
|
||||
|
||||
1. Document any new type markers or structures discovered
|
||||
2. Add test cases for edge cases
|
||||
3. Update this README with new findings
|
||||
|
||||
## License
|
||||
|
||||
This parser was reverse-engineered for interoperability purposes. Use responsibly and in accordance with your GeViSet license agreement.
|
||||
|
||||
## Related Projects
|
||||
|
||||
- **geutebruck-api**: RESTful API for GeViScope/GeViSoft surveillance systems
|
||||
- See `C:\DEV\COPILOT\CLAUDE.md` for SDK documentation
|
||||
|
||||
## Author
|
||||
|
||||
Created during analysis of Geutebruck GeViSet configuration format.
|
||||
|
||||
For questions or issues, refer to the main project documentation.
|
||||
Reference in New Issue
Block a user