diff --git a/README.md b/README.md index 7e649fc..6ed31f0 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,10 @@ This client uses an undocumented local HTTP API. It provides live readings for p 1. Create PooldoseClient ├── Connect to Device │ ├── Fetch Device Info (Debug Config) + │ ├── Load mapping JSON (based on model_id + fw_code) │ ├── WiFi Station Info (optional) │ ├── Access Point Info (optional) │ └── Network Info - └── Load mapping JSON (based on model_id + fw_code) 2. Get Static Values └── Device information and configuration @@ -55,13 +55,16 @@ This client uses an undocumented local HTTP API. It provides live readings for p └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ ▼ - │ ┌─────────────────┐ - │ │ API Endpoints │ - │ │ • get_debug │ - │ │ • get_wifi │ - │ │ • get_values │ - │ │ • set_value │ - │ └─────────────────┘ + │ ┌───────────────────────┐ + │ │ API Endpoints │ + │ │ • get_debug_config │ + │ │ • get_wifi_station │ + │ │ • get_access_point │ + │ │ • get_network_info │ + │ │ • get_values_raw │ + │ │ • get_device_language │ + │ │ • set_value │ + │ └───────────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ @@ -159,7 +162,10 @@ pip install python-pooldose ## Command Line Usage -After installation, you can use python-pooldose directly from the command line: +After installation, you can use python-pooldose directly from the command line. + +> **Note:** `--host` and `--mock` are mutually exclusive — you must specify exactly one. +> `--analyze` and `--analyze-all` require `--host` (they cannot be used in mock mode). ### Connect to Real Device @@ -178,6 +184,9 @@ pooldose --host 192.168.1.100 --analyze # Show all widgets including hidden ones pooldose --host 192.168.1.100 --analyze-all + +# Show version +pooldose --version ``` ### Mock Mode with JSON Files @@ -203,6 +212,9 @@ python -m pooldose --mock data.json # Show help python -m pooldose --help + +# Show version +python -m pooldose --version ``` ## Device Analysis for Unsupported Devices @@ -372,8 +384,12 @@ async def simple_test(): # Load data file json_file = Path("path/to/your/data.json") - # Create mock client - client = MockPooldoseClient(json_file_path=json_file) + # Create mock client (model_id and fw_code are required) + client = MockPooldoseClient( + json_file_path=json_file, + model_id="PDPR1H1HAW100", + fw_code="539187" + ) # Connect (loads mapping data) status = await client.connect() @@ -410,7 +426,7 @@ You can use the mock client with custom JSON files via the command line: pooldose --mock path/to/your/data.json -# Use mock client with model and firmware code (Beispiel mit Fantasiewerten) +# Use mock client with model and firmware code (example with fictional values) pooldose --mock path/to/your/data.json --model-id PDZZ1H1HATEST1V1 --fw-code 654321 # Or as Python module @@ -446,6 +462,8 @@ The JSON file must have the following structure: ```python client = MockPooldoseClient( json_file_path="path/to/data.json", + model_id="PDPR1H1HAW100", + fw_code="539187", timeout=30, # Ignored (compatibility) include_sensitive_data=True # Include WiFi keys etc. ) @@ -494,7 +512,7 @@ The following sample JSON files are available in the repository: ```python def test_temperature_reading(): - client = MockPooldoseClient("sample_data.json") + client = MockPooldoseClient("sample_data.json", model_id="PDPR1H1HAW100", fw_code="539187") asyncio.run(client.connect()) status, values = asyncio.run(client.instant_values()) @@ -506,7 +524,7 @@ def test_temperature_reading(): ```python # Analyze all sensor values -client = MockPooldoseClient("production_data.json") +client = MockPooldoseClient("production_data.json", model_id="PDPR1H1HAW100", fw_code="539187") await client.connect() status, data = await client.instant_values_structured() @@ -522,7 +540,7 @@ for sensor_name, sensor_data in sensors.items(): ```python async def test_full_integration(): - client = MockPooldoseClient("integration_sample_data.json") + client = MockPooldoseClient("integration_sample_data.json", model_id="PDPR1H1HAW100", fw_code="539187") # Test connection assert await client.connect() == RequestStatus.SUCCESS @@ -787,18 +805,21 @@ Mapping Discovery Process: #### Constructor ```python -PooldoseClient(host, timeout=30, include_sensitive_data=False, include_mac_lookup=False, use_ssl=False, port=None, ssl_verify=True) +PooldoseClient(host, timeout=30, *, websession=None, include_sensitive_data=False, include_mac_lookup=False, use_ssl=False, port=None, ssl_verify=True, debug_payload=False, retry_delay=0.1) ``` **Parameters:** - `host` (str): The hostname or IP address of the device - `timeout` (int): Request timeout in seconds (default: 30) +- `websession` (Optional[aiohttp.ClientSession]): Optional external ClientSession for HTTP requests. If provided, will be used for all API calls (mainly for Home Assistant integration) (default: None) - `include_sensitive_data` (bool): Whether to include sensitive data like WiFi passwords (default: False) - `include_mac_lookup` (bool): Whether to include MAC lookup via ARP (default: False) - `use_ssl` (bool): Whether to use HTTPS instead of HTTP (default: False) - `port` (Optional[int]): Custom port for connections. Defaults to 80 for HTTP, 443 for HTTPS (default: None) - `ssl_verify` (bool): Whether to verify SSL certificates when using HTTPS (default: True) +- `debug_payload` (bool): If True, log and store payloads sent to device for debugging (default: False) +- `retry_delay` (float): Delay in seconds between consecutive API requests during connect. Prevents overwhelming the embedded device (default: 0.1) #### Methods @@ -807,6 +828,9 @@ PooldoseClient(host, timeout=30, include_sensitive_data=False, include_mac_looku - `async instant_values()` → `tuple[RequestStatus, InstantValues | None]` - Get current sensor readings and device state - `async instant_values_structured()` → `tuple[RequestStatus, dict[str, Any]]` - Get structured data organized by type - `check_apiversion_supported()` → `tuple[RequestStatus, dict]` - Check API version compatibility +- `async set_switch(key, value)` → `bool` - Set a mapped switch value (convenience wrapper) +- `async set_number(key, value)` → `bool` - Set a mapped numeric value (convenience wrapper) +- `async set_select(key, value)` → `bool` - Set a mapped select option (convenience wrapper) #### Properties @@ -890,7 +914,7 @@ This client has been tested with: | SEKO POOLDOSE pH+ORP CF Group Wi-Fi | PDPR1H1HAW102 | 539187 | Alias for PDPR1H1HAW100 mapping | | SEKO PoolDose pH | PDPH1H1HAW100 | 539176 | pH-only device | | VÁGNER POOL VA DOS BASIC | PDHC1H1HAR1V0 | 539224 | | -| VÁGNER POOL VA DOS EXACT | PDHC1H1HAR1V1 | 539224 | Alias for PDHC1H1HAR1V0 mapping | +| VÁGNER POOL VA DOS EXACT | PDHC1H1HAR1V1 | 539224 | Alias for PDPR1H1HAR1V0 mapping | Other SEKO or VÁGNER POOL models may work but are untested. The client uses JSON mapping files to adapt to different device models and firmware versions (see e.g. `src/pooldose/mappings/model_PDPR1H1HAW100_FW539187.json`).