Metadata-Version: 2.4 Name: pyliebherrhomeapi Version: 0.4.1 Summary: Python library for Liebherr Home API Author-email: Mario Mett License: MIT Project-URL: Homepage, https://github.com/mettolen/pyliebherrhomeapi Project-URL: Repository, https://github.com/mettolen/pyliebherrhomeapi Project-URL: Issues, https://github.com/mettolen/pyliebherrhomeapi/issues Keywords: liebherr,home-automation,api Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: Topic :: Home Automation Requires-Python: >=3.12 Description-Content-Type: text/markdown License-File: LICENSE Requires-Dist: aiohttp>=3.9.0 Provides-Extra: dev Requires-Dist: pytest>=7.0; extra == "dev" Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev" Requires-Dist: pytest-cov>=4.0; extra == "dev" Requires-Dist: pytest-timeout>=2.1.0; extra == "dev" Requires-Dist: ruff>=0.1.0; extra == "dev" Requires-Dist: mypy>=1.0; extra == "dev" Requires-Dist: build>=1.0.0; extra == "dev" Requires-Dist: twine>=4.0.0; extra == "dev" Dynamic: license-file # pyliebherrhomeapi [![CI](https://github.com/mettolen/pyliebherrhomeapi/actions/workflows/ci.yml/badge.svg)](https://github.com/mettolen/pyliebherrhomeapi/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/mettolen/pyliebherrhomeapi/branch/main/graph/badge.svg)](https://codecov.io/gh/mettolen/pyliebherrhomeapi) [![PyPI version](https://badge.fury.io/py/pyliebherrhomeapi.svg)](https://badge.fury.io/py/pyliebherrhomeapi) [![PyPI Downloads](https://img.shields.io/pypi/dm/pyliebherrhomeapi.svg)](https://pypi.org/project/pyliebherrhomeapi/) [![Python versions](https://img.shields.io/pypi/pyversions/pyliebherrhomeapi.svg)](https://pypi.org/project/pyliebherrhomeapi/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Python library for the [Liebherr SmartDevice Home API](https://developer.liebherr.com/apis/smartdevice-homeapi/). --- This library is used by the [Liebherr](https://www.home-assistant.io/integrations/liebherr) Home Assistant integration. Dynamic Regex Badge Dynamic Regex Badge Static Badge ## Features - ๐Ÿ”Œ **Async/await support** using asyncio with comprehensive error handling - ๐ŸŒก๏ธ **Temperature control** for all zones in your Liebherr appliances - โ„๏ธ **SuperFrost/SuperCool** control for quick cooling/freezing - ๐ŸŽ‰ **Special modes** (Party Mode, Night Mode, Presentation Light) - ๐ŸงŠ **Ice maker control** with Max Ice support - ๐Ÿ’ง **HydroBreeze and BioFreshPlus** mode management - ๐Ÿšช **Auto door** control for supported appliances - ๐Ÿ“ฑ **Device management** - list and query all connected appliances - ๐Ÿ›ก๏ธ **Type hints** for better IDE support and development experience - โœ… **Input validation** with proper error handling - ๐Ÿ“Š **Comprehensive data models** for all control types - ๐Ÿ“ **Configurable logging** with privacy-focused debug output - ๐Ÿงช **100% test coverage** ensuring reliability and code quality ## Requirements - Python 3.12+ (matches the typed codebase and test matrix) - Asyncio environment with `aiohttp` (installed automatically) - Network access to `https://home-api.smartdevice.liebherr.com` ## Installation - From PyPI (when published): ```bash pip install pyliebherrhomeapi ``` - From source (current repository): ```bash pip install . ``` ## Prerequisites Before using this library, you need: 1. **Connect your appliance**: Connect your Liebherr appliance via the [SmartDevice app](https://smartdevice.onelink.me/OrY5/8neax8lp) to your home WiFi network - [Download the SmartDevice app](https://smartdevice.onelink.me/OrY5/8neax8lp) - [Instructions for connecting your appliance](https://go.liebherr.com/cb2ct1) 2. **Get your API Key** (via the SmartDevice app): - Go to **Settings** in the SmartDevice app - Select **"Beta features"** - Activate the **HomeAPI** - Copy the API Key (โš ๏ธ **Important**: The API key can only be copied once. Once you leave the screen, it cannot be copied again. If you forget your key, you'll need to create a new one via the app) 3. **Connected appliances only**: Only appliances that are connected to the internet via the SmartDevice app can be accessed through the HomeAPI. Appliances that are only registered but not connected will not appear ## Quick Start ```python import asyncio from pyliebherrhomeapi import ( LiebherrClient, TemperatureUnit, IceMakerMode, ) async def main(): # Create client with your API key async with LiebherrClient(api_key="your-api-key-here") as client: # Get all devices (only connected devices are returned) devices = await client.get_devices() print(f"Found {len(devices)} device(s)") for device in devices: # device_id is the serial number of the appliance print(f"Device: {device.nickname} ({device.device_id})") print(f" Type: {device.device_type}") print(f" Model: {device.device_name}") # Get all controls for this device controls = await client.get_controls(device.device_id) print(f" Controls: {len(controls)}") if __name__ == "__main__": asyncio.run(main()) ``` ## Important Notes ### Device Zones - Each device has at least one zone (cooling zone, freezing zone, etc.) - **Zone numbering**: The top zone is zone 0, zone numbers ascend from top to bottom - Zone controls (like temperature, SuperFrost, SuperCool) always require a `zone_id` - Base controls (like Party Mode, Night Mode) apply to the whole device and don't need a zone ### Polling Recommendations โš ๏ธ **Beta Version Notice**: The API currently doesn't push updates, so endpoints need to be polled regularly. **Recommended polling intervals:** - **Controls**: Poll every 30 seconds using `/v1/devices/{deviceId}/controls` to get all states in one call - **Device list**: Poll manually only when appliances are added/removed or nicknames change - **Rate limits**: Be mindful of API call limits. Avoid too many calls at once as there are restrictions for security and performance ### Control Types **Base Controls** (apply to entire device, no `zone_id` needed): - Party Mode - Night Mode **Zone Controls** (require `zone_id`, even if device has only one zone): - Temperature - SuperFrost - SuperCool - Ice Maker - HydroBreeze - BioFreshPlus - Auto Door ## Usage Examples ### Temperature Control ```python from pyliebherrhomeapi import LiebherrClient, TemperatureUnit async with LiebherrClient(api_key="your-api-key") as client: # Set temperature for zone 0 (top zone) to 4ยฐC await client.set_temperature( device_id="12.345.678.9", zone_id=0, # Zone 0 is the top zone target=4, unit=TemperatureUnit.CELSIUS ) # Get temperature control info controls = await client.get_control( device_id="12.345.678.9", control_name="temperature", zone_id=0 ) ``` ### SuperCool and SuperFrost ```python # Enable SuperCool for zone 0 await client.set_super_cool( device_id="12.345.678.9", zone_id=0, value=True ) # Enable SuperFrost for zone 1 await client.set_super_frost( device_id="12.345.678.9", zone_id=1, value=True ) ``` ### Special Modes ```python # Enable Party Mode await client.set_party_mode( device_id="12.345.678.9", value=True ) # Enable Night Mode await client.set_night_mode( device_id="12.345.678.9", value=True ) # Set presentation light intensity (0-5) await client.set_presentation_light( device_id="12.345.678.9", target=3 ) ``` ### Ice Maker Control ```python from pyliebherrhomeapi import IceMakerMode # Turn on ice maker await client.set_ice_maker( device_id="12.345.678.9", zone_id=0, mode=IceMakerMode.ON ) # Enable Max Ice mode await client.set_ice_maker( device_id="12.345.678.9", zone_id=0, mode=IceMakerMode.MAX_ICE ) ``` ### HydroBreeze Control ```python from pyliebherrhomeapi import HydroBreezeMode # Set HydroBreeze to medium await client.set_hydro_breeze( device_id="12.345.678.9", zone_id=0, mode=HydroBreezeMode.MEDIUM ) ``` ### BioFreshPlus Control ```python from pyliebherrhomeapi import BioFreshPlusMode # Set BioFreshPlus mode await client.set_bio_fresh_plus( device_id="12.345.678.9", zone_id=0, mode=BioFreshPlusMode.ZERO_ZERO ) ``` ### Auto Door Control ```python # Open the door await client.trigger_auto_door( device_id="12.345.678.9", zone_id=0, value=True # True to open, False to close ) ``` ### Query Device Controls ```python # Get all controls (recommended for polling - gets all states in one call) all_controls = await client.get_controls(device_id="12.345.678.9") # Get specific control by name temp_controls = await client.get_control( device_id="12.345.678.9", control_name="temperature" ) # Get control for specific zone zone_temp = await client.get_control( device_id="12.345.678.9", control_name="temperature", zone_id=0 # Top zone ) ``` ### Efficient Polling Pattern ```python import asyncio from pyliebherrhomeapi import LiebherrClient async def poll_device_state(client: LiebherrClient, device_id: str): """Poll device state every 30 seconds (recommended interval).""" while True: try: # Get all controls in a single API call device_state = await client.get_device_state(device_id) # Process the controls for control in device_state.controls: print(f"{control.name}: {control}") # Wait 30 seconds before next poll (recommended by Liebherr) await asyncio.sleep(30) except Exception as e: print(f"Error polling device: {e}") await asyncio.sleep(30) async def main(): async with LiebherrClient(api_key="your-api-key") as client: devices = await client.get_devices() if devices: await poll_device_state(client, devices[0].device_id) ``` ## Logging The library uses Python's standard `logging` module for diagnostics. By default, it uses a `NullHandler`, so no logs are emitted unless you configure logging in your application. ### Enable Debug Logging ```python import logging # Enable debug logging for the library logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Or configure just for pyliebherrhomeapi logger = logging.getLogger('pyliebherrhomeapi') logger.setLevel(logging.DEBUG) handler = logging.StreamHandler() handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) logger.addHandler(handler) ``` ### Log Levels - **DEBUG**: Detailed information about API requests, responses, and session lifecycle - **INFO**: General information about operations (currently not used) - **WARNING**: HTTP errors and connection issues - **ERROR**: Severe errors like server failures ### Privacy Device IDs are automatically masked in debug logs (showing only last 4 characters) to protect sensitive information. ## Error Handling ```python from pyliebherrhomeapi import ( LiebherrClient, LiebherrAuthenticationError, LiebherrBadRequestError, LiebherrNotFoundError, LiebherrPreconditionFailedError, LiebherrUnsupportedError, LiebherrConnectionError, LiebherrTimeoutError, ) async with LiebherrClient(api_key="your-api-key") as client: try: await client.set_temperature( device_id="12.345.678.9", zone_id=0, target=4 ) except LiebherrAuthenticationError: print("Invalid API key") except LiebherrBadRequestError as e: print(f"Invalid request: {e}") except LiebherrNotFoundError: print("Device not reachable") except LiebherrPreconditionFailedError: print("Device not onboarded to your household") except LiebherrUnsupportedError: print("Feature not supported on this device") except (LiebherrConnectionError, LiebherrTimeoutError) as e: print(f"Connection error: {e}") ``` ## Development ### Setup ```bash # Clone the repository git clone https://github.com/mettolen/pyliebherrhomeapi.git cd pyliebherrhomeapi # Install development dependencies pip install -e ".[dev]" ``` ### Testing ```bash # Run tests pytest # Run tests with coverage pytest --cov=pyliebherrhomeapi --cov-report=html ``` ### Code Quality ```bash # Format code ruff format . # Lint code ruff check . # Type checking mypy src ``` ## API Documentation For detailed API documentation, visit: - [SmartDevice HomeAPI Overview](https://developer.liebherr.com/apis/smartdevice-homeapi/) - [Swagger UI Documentation](https://developer.liebherr.com/apis/smartdevice-homeapi/swagger-ui/) - [Release Notes](https://developer.liebherr.com/apis/smartdevice-homeapi/releasenotes/) **API Base URL**: `https://home-api.smartdevice.liebherr.com` ## Implementation Notes This client library is generated based on the official `openapi.json` specification downloaded from the Liebherr Developer Portal, which reflects the latest API state. When Liebherr updates their API and releases a new version of the OpenAPI specification, this client library will be updated accordingly to maintain compatibility and support new features. ## License MIT License - see [LICENSE](LICENSE) file for details. ## Contributing Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.