Skip to content

Version 2026.4.20 (2026-04-24)

What's Changed

Changed

  • Adopt the new openccu-data package (>=2026.4.1) as the source-of-truth for CCU translation and easymode metadata. Both ccu_translations.py and easymode_data.py now resolve their data files via importlib.resources from openccu_data.data (extract archives) and openccu_data.data.translation_custom (curated overrides), replacing the previous pkgutil.get_data lookups.

Removed

  • Drop the vendored aiohomematic/ccu_data/ tree (translation extract, easymode extract, and all translation_custom/*.json overrides) — these are now distributed by openccu-data.
  • Drop script/lint_translation_custom.py and the corresponding lint-translation-custom prek hook; the lint logic moved to openccu-data together with the custom override files.
  • Drop the ccu_data/* entries from package-data in pyproject.toml.

Migration

Downstream consumers do not need to change anything: the public API of ccu_translations and easymode_data is unchanged. New dependency openccu-data is pulled in transitively when upgrading. To regenerate the underlying CCU artifacts, work in the openccu-data repository and publish a new release; aiohomematic picks it up via its version constraint.

Version 2026.4.19 (2026-04-22)

What's Changed

Changed

  • Further linter tightening — second pass cross-referenced against the Home Assistant core project's pyproject.toml:
  • Ruff: added B009, B017, B024, B025, B035, B905, F541, SLF, and the RUF007, RUF008, RUF010, RUF016, RUF017, RUF019, RUF020, RUF021, RUF022, RUF023, RUF024, RUF026, RUF030, RUF032, RUF033, RUF034, RUF059, RUF101 rules. B905 now forces zip(..., strict=...), RUF008 catches mutable dataclass defaults, RUF024 catches mutable dict.fromkeys values, RUF022/RUF023 keep __all__ / __slots__ sorted alphabetically.
  • Ruff: added flake8-tidy-imports.banned-api entries for async_timeout, pytz, and tests, preventing production code from importing test modules.
  • Ruff: files that are intentionally coupled to private state of adjacent classes (model */field.py descriptors, compat.py's sys._is_gil_enabled, rpc_proxy.py extending xmlrpc.client, rpc_server.py reading aiohttp.web.TCPSite._server, and the connection_recovery duck-typed introspection paths) are exempted from SLF001 per-file, with the rationale documented in the config.
  • mypy: enabled the deprecated error code so calls into APIs annotated with typing_extensions.deprecated fail type-checking, and turned on strict_bytes to disallow implicit bytes / str mixing.
  • pylint: set fail-on = ["I"] so informational messages (useless-suppression, use-symbolic-message-instead) now fail the check instead of being silently informational. Added a tests per-file-ignore pair (redefined-outer-name, use-implicit-booleaness-not-comparison) matching the core config.
  • pytest: enabled asyncio_debug = true to surface scheduler hazards and un-awaited coroutines during the test run.
  • Reconcile RUF022 with the project's lint-all-exports convention: The project's custom lint-all-exports hook requires every public package __init__.py to keep grouped, header-commented __all__ lists (# GroupName then alphabetical within each group). Ruff's new RUF022 would sort the whole list alphabetically and break the groups, so RUF022 is disabled for aiohomematic/**/__init__.py (glob, so future packages are covered automatically) and for central/events/internal.py which follows the same style. RUF022 still enforces sorting on every other __all__ in the codebase.
  • Disable asyncio_debug for the RPC stress tests: asyncio_debug catches scheduler and awaitable hazards across the rest of the suite, but its slow-callback logging adds ~2× overhead — enough to break the hard-coded timing thresholds in TestStress::test_concurrent_events / test_sustained_load / test_multicall_batch_performance (those tests measure throughput, not correctness). A class-scoped autouse fixture toggles debug mode off for their duration and restores the previous setting afterwards.

Fixed

  • Dead branch in .github/scripts/analyze_issue.py::_analyze_logs: both arms of the len(matches) if isinstance(matches[0], str) else len(matches) ternary computed the same value (RUF034). Simplified to a single len(matches) call.

Version 2026.4.18 (2026-04-21)

What's Changed

Changed

  • Stricter linter configuration: tightened the project's quality gates.
  • Ruff: full S (flake8-bandit) suite activated, BLE (blind-except) and PTH (pathlib) added, mccabe.max-complexity lowered from 25 to 15. Per-file-ignores extended for tests, script/, .github/scripts/, and top-level examples so only library code is held to the strict bar.
  • mypy: enabled possibly-undefined and unused-awaitable error codes. explicit-override intentionally left off — enabling it surfaces ~890 missing @override decorators across protocol implementations and belongs in its own dedicated PR.
  • bandit: added 16 additional checks (B104–B107, B303/B304/B310/B311, B321/B324, B501–B505, B701). Tests excluded from bandit scope since fixture data is intentional; ruff's S rules guard production.
  • Migrate filesystem operations to pathlib: store/storage.py, support/file_ops.py, and model/device.py now use pathlib.Path throughout instead of os.path / glob — clearer semantics for glob / resolve / replace operations, no behavior change.
  • Narrow broad exception handlers where the type was obvious: ~25 except Exception: blocks in coordinators, client, model, and store replaced with concrete exception types (e.g. except (OSError, compat.JSONDecodeError) for storage I/O, except (ValueError, SyntaxError, MemoryError, TypeError) for JSON parsing, except AioHomematicException for project-level RPC calls). Intentionally broad catches — incident recording, recovery stages, decorator boundaries, calculated data points, service-boundary callbacks — now carry a # noqa: BLE001 with a specific reason documenting why narrowing would break the defensive contract.
  • Refactor complex functions for readability: extracted helpers in central/health.py::health_score (circuit / activity scoring), central/query_facade.py::get_parameters (skip / resolve helpers), client/json_rpc.py::get_all_system_variables (inclusion and record builders), model/schedule_models.py::validate_domain_constraints (per-domain validator dispatch table), model/week_profile.py::convert_raw_to_dict_schedule, and support/__init__.py::element_matches_key. Remaining complex functions (decorator factories, RPC fault translators, pydantic TypedDict serializers) keep a # noqa: C901 with a concrete reason.

Fixed

  • DelegatedProperty forward-reference type resolution: using a string form (DelegatedProperty["DeviceRegistry"](...)) in central/coordinators/device.py::device_registry caused mypy to resolve the attribute as Any, which silently masked no-any-return errors in devices, get_channel, get_device, get_virtual_remotes, and identify_channel. Importing DeviceRegistry directly and dropping the quotes restores strict return-type checking.
  • Path.mkdir vs. os.makedirs in tests: after the pathlib migration, tests/test_support.py::test_check_or_create_directory_sync still patched os.path.exists / os.makedirs and no longer intercepted calls. Updated to patch pathlib.Path.exists / pathlib.Path.mkdir.
  • __new__ return type in central/rpc_server.py: annotated with Self instead of the concrete class so the PYI034 contract holds.

Version 2026.4.17 (2026-04-20)

What's Changed

Added

  • Add device profile for HmIP-UDI-SMI55 (Universal Dimming Interface with motion sensor): Registered as IP dimmer on channel 7 (with secondary channels 8/9, state channel 6). Motion sensor parameters (MOTION, ILLUMINATION, CURRENT_ILLUMINATION, MOTION_DETECTION_ACTIVE, RESET_MOTION) from channel 4 are exposed via additional data points. Week profile support on channel 10 is included. Battery data (R03/AAA, quantity 2) added to operating voltage level calculation.
  • Add lint-translation-custom pre-commit hook: new script/lint_translation_custom.py validates every override key in aiohomematic/ccu_data/translation_custom/*.json against the extracted archive, the Parameter enum, and known channel-type prefixes. Keys that look like channel_prefix_parameter typos (where a pipe | was required) are reported as errors with a concrete fix suggestion; noop overrides whose value matches the extract are reported as warnings.

Fixed

  • HmIP-DLD parameter label "Summer deaktivieren" replaced with "Akustische Rückmeldung deaktivieren": the custom translation overrides for DISABLE_ACOUSTIC_CHANNELSTATE and HOLD_TIME were keyed as door_lock_disable_acoustic_channelstate and door_lock_hold_time. Lookups use channel_type|parameter with a pipe separator, so the keys never matched and the raw CCU firmware strings ("Summer deaktivieren", "Haltezeit beim Öffnen") were forwarded unchanged. The keys are now written as plain globals (disable_acoustic_channelstate, hold_time) so the overrides actually apply.

Version 2026.4.16 (2026-04-18)

What's Changed

Fixed

  • Fixed HmIP-DLD (and similar devices) silently rejecting schedule updates: DefaultWeekProfile.set_schedule unconditionally sent all WP_* schedule parameters (WP_CONDITION, WP_ASTRO_TYPE, WP_ASTRO_OFFSET, WP_LEVEL_2, WP_RAMP_TIME_BASE, WP_RAMP_TIME_FACTOR) to the device. Lock devices like HmIP-DLD only advertise a subset of ScheduleField in their MASTER paramset description — the CCU then silently rejected the entire putParamset call, leaving CONFIG_PENDING set forever. WeekProfile.supported_schedule_fields now introspects the MASTER paramset description and _filter_raw_schedule_by_supported_fields drops all unsupported NN_WP_* keys before put_paramset, so device schedule writes only send what the device actually accepts.
  • Validate schedule writes against paramset description: WeekProfile write paths (DefaultWeekProfile.set_schedule, ClimateWeekProfile.set_schedule, set_profile, copy_schedule_to) now pass check_against_pd=True to put_paramset, matching the existing behavior of set_weekday. Previously, unknown or unsupported WP_* parameters were forwarded to the CCU without validation, where they were silently rejected or caused opaque errors. The client now raises a clear ClientException listing the offending parameter before the request is sent.

Added

  • WeekProfile.supported_schedule_fields property (also exposed via WeekProfileDataPoint and the WeekProfileProtocol / WeekProfileDataPointProtocol protocols) returns the frozenset[ScheduleField] that the device advertises in its MASTER paramset description. Frontends can inspect this capability set (forwarded as supported_schedule_fields on the schedule entity attributes) to hide non-functional inputs for devices like HmIP-DLD.

Version 2026.4.15 (2026-04-18)

What's Changed

Fixed

  • Fixed LinkCoordinator.get_linkable_channels excluding non-CLIMATE channels: get_link_source_categories / get_link_target_categories only mapped CLIMATE roles to a DataPointCategory, so channels with LINK_SOURCE_ROLES / LINK_TARGET_ROLES such as REMOTE_CONTROL (HmIP-RCV-50), SWITCH, KEYMATIC, WINMATIC, LEVEL, WEATHER_*, WINDOW_SWITCH*, etc. produced empty category tuples and were filtered out as non-linkable. Added a _LINK_ROLE_TO_CATEGORY mapping so all known link roles produce a non-empty category. Fixes the homematicip-local-frontend "Add Direct Link" wizard not offering the HmIP-RCV-50 virtual remote (and other non-climate devices) as a target.
  • Downgrade log level for unsupported JSON-RPC methods from error to warning in AioJsonRpcAioHttpClient._check_supported_methods — missing optional methods do not indicate a failure and should not be reported as errors.
  • Log instead of silently swallowing BaseHomematicException in ConfigurationCoordinator.get_configurable_devices. Devices whose get_configurable_channels fails (e.g. due to a missing child description) were dropped from the panel device list without any trace. They are still skipped, but now emit a warning identifying interface, address, model, and the underlying exception, so the root cause can be diagnosed instead of hidden. A debug line also explains devices skipped because they have no configurable channels.
  • Fixed HmIP-RCV-50 (and similar devices) missing from the panel device list: DeviceDescriptionRegistry.get_device_with_channels iterated over every entry in the parent's CHILDREN array and called get_device_description for each. Some CCU firmwares (observed with OpenCCU and the virtual remote HmIP-RCV-50) emit an empty-string entry in CHILDREN, causing a DescriptionNotFoundException that propagated into ConfigurationCoordinator.get_configurable_devices and removed the whole device from the panel list. Empty entries are now skipped, consistent with the existing filter in Device.finalize_init (aiohomematic/model/device.py:354).

Version 2026.4.14 (2026-04-16)

What's Changed

Added

  • Extract MASTER paramset metadata from CCU WebUI dialog functions (parameter groups, ordering, option presets, conditional visibility)
  • Add ui_labels translation category for resolving JS translation keys from easymode metadata
  • Add get_ui_label_translation() to ccu_translations public API
  • Add MASTER_SENDER_TYPE constant and label_key field to ParameterGroupDef in easymode_data

Fixed

  • Fix duplicate conditional visibility entries in easymode extraction

Version 2026.4.13 (2026-04-15)

What's Changed

Fixed

  • Fixed schedule target channels for multi-config lock devices (HmIP-DLP, HmIP-DLD): The schedule UI incorrectly showed all channel groups (e.g. channels 0 and 12 for HmIP-DLP) as schedule targets, including the button lock which has no schedule. Now only channel groups from CDPs with an explicit schedule_channel_no are included in the target channel map.

Version 2026.4.12 (2026-04-15)

What's Changed

Added

  • Lock schedule support for HmIP-DLD and HmIP-DLP: Added week profile (schedule) support for door lock devices.

  • HmIP-DLD: schedule_channel_no=10, HmIP-DLP: schedule_channel_no=14

  • Door lock mode: 4 lock actions (lock + auto-relock end/start, unlock + auto-relock end, auto-relock end) encoded as lock_action field
  • User permission mode: Permission granted/not granted for ACCESS_RECEIVER channels 2-9, encoded as permission field
  • lock_mode field: Distinguishes between door_lock and user_permission modes, derived from target_channels
  • Domain validation: LOCK domain rejects level_2, ramp_time, and user-set duration; enforces mutual exclusivity of lock_action and permission based on lock_mode
  • Level range extended: SimpleScheduleEntry.level now allows 0.0-1.01 (1.01 is a special lock value for "Auto-Relock End")
  • New enums: LockAction, LockMode, LockPermission

Version 2026.4.11 (2026-04-14)

What's Changed

Added

  • Command retry mechanism for transient failures: Introduced CommandRetryHandler that automatically retries set_value and put_paramset operations on transient errors (network timeouts, device unreachability, DutyCycle exhaustion, transmission pending) with exponential backoff.

  • Retryable errors: TimeoutError, NoConnectionException, InternalBackendException, XML-RPC fault codes -1 (UNREACH), -8 (INSUFFICIENT_DUTYCYCLE), -9 (DEVICE_OUT_OF_RANGE), -10 (TRANSMISSION_PENDING).

  • Non-retryable errors: AuthFailure, ValidationException, UnsupportedException, CircuitBreakerOpenException, CommandSupersededError.
  • Special delays: DutyCycle exhaustion uses 40s delay (regeneration ~1%/36s), transmission pending uses 5s delay.
  • Connection recovery awareness: On NoConnectionException, waits for RecoveryCompletedEvent instead of blind retry. Recovery wait is interruptible by cancellation (via asyncio.wait with FIRST_COMPLETED).
  • Per-DataPoint supersede: New command on the same data point cancels any pending retry for that data point. Uses cooperative asyncio.Event-based cancellation — the retry loop checks a cancel event before each attempt and during each delay/recovery wait.
  • Interruptible delays: _interruptible_sleep() wakes immediately on cancellation instead of sleeping the full delay.
  • CRITICAL purge support: CRITICAL-priority commands (e.g., cover stop()) cancel all pending retries for the device via purge_addresses. Device address matching uses device_address: prefix to prevent false matches.
  • Idempotency-safe: DpAction and DpButton have _retryable = False by default (fire-and-forget, non-idempotent). Climate RF thermostat mode DpAction calls override with explicit retry=True (target-state semantics).
  • Configurable via TimeoutConfig: command_retry_max_attempts (default 3, 0 = disabled), command_retry_base_delay, command_retry_max_delay, command_retry_backoff_factor, command_retry_duty_cycle_delay, command_retry_transmission_pending_delay, command_retry_recovery_wait.
  • Per-call control: retry parameter on send_value(), set_value(), put_paramset() allows per-call enable/disable.
  • Metrics: CommandRetryMetrics tracks total retries, successful retries, exhausted retries, recovery waits, timeouts, and cancellations.

Changed

  • GenericDataPoint.send_value(): New retry: bool | None = None parameter. None uses the class default (_retryable), explicit True/False overrides.
  • InterfaceClient.set_value() / put_paramset(): New retry: bool = True parameter, passed through to CommandRetryHandler.execute_with_retry().
  • CallParameterCollector: Derives retry from collected data points' _retryable attributes, with explicit override support via send_value(retry=...).
  • Protocol updates: ValueOperationsProtocol.set_value() and ParamsetOperationsProtocol.put_paramset() include retry: bool = True.

Version 2026.4.10 (2026-04-12)

What's Changed

Added

  • Added ScheduleChannelSwitch data point: New per-channel switch data points for enabling/disabling schedule participation on non-climate devices. Each target channel gets its own ScheduleChannelSwitch instance, registered on the schedule channel with DataPointCategory.SCHEDULE_SWITCH. The switches derive their state from the WEEK_PROGRAM_CHANNEL_LOCKS bitmask and write via COMBINED_PARAMETER. They are auto-discovered by Home Assistant as standard switch entities, designed to be grouped in a schedule subdevice.

  • Added ScheduleChannelSwitchProtocol in interfaces/model.py with value, turn_on(), turn_off(), channel_key, and target_channel_info.

  • Added DataPointCategory.SCHEDULE_SWITCH mapped to DataPointType.SWITCH, included in the CATEGORIES tuple for HA entity discovery.

Version 2026.4.9 (2026-04-12)

What's Changed

Added

  • Added per-channel schedule enable/disable support for non-climate week profiles: The WeekProfileDataPoint now exposes a schedule_enabled property (returning a Mapping[str, bool] of per-channel enabled states) and a set_schedule_enabled() method with an optional channel_key parameter, allowing users to activate or deactivate the weekly program per target channel on devices that support WEEK_PROGRAM_CHANNEL_LOCKS. The state is derived from the bound WEEK_PROGRAM_CHANNEL_LOCKS generic data point and automatically syncs via event subscription.

  • Added new parameters: WEEK_PROGRAM_CHANNEL_LOCKS, WEEK_PROGRAM_TARGET_CHANNEL_LOCK, and WEEK_PROGRAM_TARGET_CHANNEL_LOCKS to the Parameter enum.

  • Added schedule helper functions: channel_key_to_bitmask() and parse_channel_locks() in schedule_models for converting between channel keys and bitmask values used by WEEK_PROGRAM_CHANNEL_LOCKS.

  • Added channel locks data loading on init: WeekProfileDataPoint now loads the WEEK_PROGRAM_CHANNEL_LOCKS value during load_data_point_value, and CustomDataPoint._init_data_point_values triggers week_profile_data_point.load_data_point_value to ensure the schedule enabled state is available after startup.

Fixed

  • Fixed visibility rules for WEEK_PROGRAM parameters: Removed the blanket WEEK_PROGRAM_ prefix pattern from IGNORED_PARAMETERS_START_PATTERN so that WEEK_PROGRAM_CHANNEL_LOCKS and related parameters are no longer hidden. WEEK_PROGRAM_POINTER is now explicitly listed in IGNORED_PARAMETERS to preserve its previous hidden behavior.

Version 2026.4.8 (2026-04-11)

What's Changed

Fixed

  • Fixed missing DURATION_UNIT/DURATION_VALUE in turn_off for lights with ramp_time: When turn_off(ramp_time=...) is called on lights with timer unit parameters (HmIP-BSL, HmIP-RGBW, HmIPW-WRC6, HmIP-DRG-DALI), DURATION_UNIT and DURATION_VALUE are now always included in the putParamset call, matching the behavior already implemented for turn_on. This prevents XMLRPCFault errors and optimistic rollbacks when turning off lights with a transition time.

Version 2026.4.7 (2026-04-10)

What's Changed

Fixed

  • Fixed missing DURATION_UNIT/DURATION_VALUE in putParamset for signal lights: Devices with timer unit parameters (HmIP-BSL, HmIP-RGBW, HmIPW-WRC6) now always include DURATION_UNIT and DURATION_VALUE in putParamset calls during turn_on. When no explicit on_time is set, the permanent marker (DV=31, DU=H) is sent as default, matching CCU expectations and preventing XMLRPCFault errors.

  • Fixed RAMP_TIME_TO_OFF usage for RGBW and DRG-DALI lights: The turn_off() method of CustomDpIpRGBWLight and CustomDpIpDrgDaliLight now correctly uses RAMP_TIME_TO_OFF_UNIT/RAMP_TIME_TO_OFF_VALUE instead of RAMP_TIME_UNIT/RAMP_TIME_VALUE when a ramp time is provided during turn-off, matching CCU WebUI behavior.

  • Fixed siren duration always sent on turn_on: CustomDpIpSiren.turn_on() now falls back to send_default() when no duration value is available, ensuring DURATION_UNIT/DURATION_VALUE are always included in the putParamset call, consistent with CCU WebUI behavior.

Added

  • Added has_unit property to CombinedDpTimerAction: Indicates whether the timer has a unit data point, used to determine if duration defaults should be included in putParamset calls.

  • Added CodeQL workflow with Python 3.14: Custom CodeQL analysis workflow using setup-python-dependencies: false and explicit Python 3.14 setup to avoid parse errors from new Python 3.14 syntax features.

Version 2026.4.6 (2026-04-09)

What's Changed

Added

  • Added determine_parameter to ValueOperationsProtocol: The client protocol interface now exposes determine_parameter, making it available through the protocol-based DI layer.

Version 2026.4.5 (2026-04-09)

What's Changed

Added

  • Added determine_parameter support: New determine_parameter method on BackendOperationsProtocol, BaseBackend, CcuBackend, and InterfaceClient that wraps the XML-RPC determineParameter call for auto-detecting parameter values on a channel.

Version 2026.4.4 (2026-04-08)

What's Changed

Added

  • Added channel name to configurable device channel data: The ConfigurableDeviceChannel dataclass now includes a channel_name field, exposing user-defined channel names in the configuration coordinator API for use in the configuration panel.

Version 2026.4.3 (2026-04-08)

What's Changed

Added

  • Added channel name to device link and linkable channel data: The DeviceLink dataclass now includes sender_channel_name and receiver_channel_name fields, and LinkableChannel includes channel_name. This exposes user-defined channel names in the link coordinator API for use in the configuration panel.

Docs

  • Documented schedule editing permissions for non-admin users: Added permissions sections to the Climate Schedule Card and Schedule Card documentation. Extended the Config Panel documentation with a new section explaining how to enable schedule editing for non-admin household members.

Version 2026.4.2 (2026-04-07)

What's Changed

Added

  • Added additional data points for HmIP-DLP (Door Lock Pro): Enabled additional entities from channels beyond the main lock (Ch12) and button lock (Ch0). New data points include door state (Ch3), permission state (Ch4-11), lock state reason (Ch12), auto relock state (Ch13), and sabotage sensors (Ch0). Added LOCK_STATE_REASON, AUTO_RELOCK_STATE, PERMISSION_STATE, SABOTAGE_ACCELERATION, SABOTAGE_BATTERY, SABOTAGE_MAGNETIC_FIELD, and SABOTAGE_VERTICAL to the Parameter enum. Added HmIP-DLP to UN_IGNORE_PARAMETERS_BY_DEVICE for ERROR_JAMMED.

  • Registered additional data points in multi-channel detection cache: When additional_data_points activates a generic data point on a channel outside the custom data point's own channel group, the parameter is now registered in the _address_parameter_cache of ParamsetDescriptionRegistry. This ensures is_in_multiple_channels() returns correct results for parameters that appear on multiple channels via additional_data_points. Added register_additional_parameter() to ParamsetDescriptionProviderProtocol and ParamsetDescriptionRegistry.

  • Synthesize missing parameter name translations from value entries: The CCU translation extraction script now derives parameter name translations from value-entry templates when no explicit parameter name entry exists in the stringtable. When all value entries for a parameter share the same leading template variable (e.g. ${stringTableAutoRelockState}: ${lblYes}), that variable is resolved as the parameter name. This adds ~89 previously missing parameter translations, including AUTO_RELOCK_STATE for HmIP-DLP.

Fixed

  • Fixed multi-channel postfix for data point names: The channel postfix (ch{no}) is now applied consistently when a parameter appears in multiple channels, regardless of whether the channel name contains an address separator. Previously, the postfix was only added when the channel name matched the address:channel_no pattern, causing missing disambiguation for channels with custom names.

  • Fixed spurious optimistic rollbacks for CUxD/CCU-Jack devices: Disabled optimistic updates for interfaces without RPC callback support (CUxD, CCU-Jack). These interfaces receive event confirmations via MQTT with unpredictable latency (often >30s for slow devices like FHT80b), causing the 30-second rollback timer to fire before the confirmation arrives. This led to incorrect value reversions and cascading write loops. The value now updates only when the MQTT confirmation arrives, regardless of latency. (#3103)

Version 2026.4.1 (2026-04-05)

What's Changed

Fixed

  • Fixed sysvar and device data points temporarily showing unknown after setting the same value: When send_variable() or send_value() was called with a value identical to the already confirmed value, the unconfirmed value was not populated (remained None) while the unconfirmed timestamp was updated. This caused _value to return None (shown as "unknown" in Home Assistant) until the next polling cycle confirmed the value (~20-30 seconds). The issue was more likely to occur with rapid value changes or when setting to 0. Fixed by always populating _unconfirmed_value regardless of whether the value changed. Fixes #3090.

  • Fixed device schedules appearing empty for cover and dimmer devices: The CCU reports level_2 values slightly above 1.0 (e.g. 1.01) for some cover devices like HmIP-BROLL. The Pydantic validation on SimpleScheduleEntry.level_2 (le=1.0) rejected these values, causing the entire schedule group to be silently skipped. Fixed by clamping level_2 to [0.0, 1.0] in convert_raw_group_to_simple_entry(), consistent with the existing level clamping. Fixes #3092.

Version 2026.4.0 (2026-04-03)

What's Changed

Fixed

  • Fixed forced-to-sensor data points not publishing events: Data points with force_to_sensor() (LEVEL on HmIP-eTRV and HmIP-HEATING) were publishing DataPointStateChangedEvent and DeviceRemovedEvent with the internal _unique_id attribute instead of the unique_id property (which includes the _sensor suffix). This caused a key mismatch in the EventBus — subscribers registered with the property value never received events. Also fixed cleanup_subscriptions() using the wrong key, which caused orphaned subscriptions (memory leak). Regression introduced in #3081.

Added

  • CLI tool documentation: New docs/developer/cli_tool.md documents the hmcli command-line tool with all commands, interactive mode, JSON output, shell completion, and common debugging use cases.

  • Restore procedures: Added restore section to docs/user/features/backup.md covering restore via Home Assistant and CCU WebUI, verification checklist, and failure recovery.

  • Consumer API documentation: Expanded docs/developer/consumer_api.md with sections for SubscriptionGroup pattern, DataPoint registration (register()/unregister()), type-safe queries (get_data_points_by_type()), event tiers (public vs internal), and command throttling.

  • Contributor guide: Added "Where to start" section to docs/contributor/contributing.md with contribution tiers by experience level. Added 3 missing lint scripts to docs/contributor/dev-environment.md (lint_event_tiers.py, lint_delegated_property.py, lint_rega_scripts.py).

  • Global abbreviations: Added TLS and EEPROM to docs/includes/abbreviations.md for automatic tooltip expansion.

  • German documentation (i18n): Added complete German translations for all 18 user-facing documentation pages (Phase 1 + Phase 2). Infrastructure uses mkdocs-static-i18n plugin with language switcher. German pages live under docs/de/ with identical structure. Translation workflow managed by script/translate_docs.py (status checking, hash tracking, scaffolding). Terminology consistency enforced via docs/de/glossary_terms.yml (~80 terms). English remains the source language; German translations are produced locally via Claude Code. Existing URLs unchanged (EN at /, DE at /de/).

Changed

  • CLAUDE.md: Updated version to 2026.4.0, replaced all subscription examples with EventBus pattern, added lint_event_tiers.py to scripts table, updated last-modified date.

  • README.md: Fixed 4 code bugs in Quick Start example (wrong parameter names, missing await, incorrect property name).

Improved

  • Instance name clarity: Added concrete example to docs/user/homeassistant_integration.md explaining why unique instance names matter with multiple HA instances.

  • Callback concept: Added explanation in integration docs of how CCU pushes events via XML-RPC callbacks and what breaks when the callback path fails.

  • Docker networking: Expanded Docker section in docs/faq.md with step-by-step options (host networking vs manual callback_host) and commands to find Docker host IP.

  • Stale API references removed: Updated 6 architecture and developer docs to replace removed subscribe_to_data_point_updated, custom_id, and get_data_point_by_custom_id references with current EventBus patterns.

Version 2026.3.23 (2026-03-31)

What's Changed

Breaking

  • Unified subscription architecture: DataPoint subscriptions now go through the EventBus instead of a separate mechanism. The following APIs have been removed:

  • CallbackDataPoint.subscribe_to_data_point_updated(handler, custom_id)

  • CallbackDataPoint.subscribe_to_device_removed(handler)
  • CallbackDataPoint.subscribe_to_internal_data_point_updated(handler)
  • CallbackDataPoint.custom_id property
  • DataPointStateChangedEvent.custom_id field
  • CentralUnit.get_data_point_by_custom_id()
  • DeviceQueryFacade.get_data_point_by_custom_id()

Consumers now subscribe directly via EventBus.subscribe(event_type=DataPointStateChangedEvent, event_key=dp.unique_id, handler=...) and use SubscriptionGroup for lifecycle management.

  • DataPoint registration separated from subscription: New register() / unregister() methods replace the implicit registration via subscribe_to_data_point_updated(custom_id=...). The is_registered property is now a simple boolean flag.

Added

  • Event tier enforcement: Internal events structurally separated into aiohomematic.central.events.internal. Public __all__ only exports public events. New lint script script/lint_event_tiers.py enforces that external consumers do not import internal events.

  • DeviceQueryFacade.get_data_points_by_type(): Type-safe data point lookup filtering by concrete class, eliminating cast() in consumer code.

  • Public API surface documentation: docs/reference/api/public_api.md defines stable import paths in three tiers for external consumers.

  • Session playback documentation: docs/contributor/testing/session_playback.md documents the test session recording and playback infrastructure.

  • Coordinator responsibility matrix: Added to docs/architecture.md with per-coordinator summaries and interaction matrix.

Changed

  • Event module structure: Internal event classes moved from bus.py to internal.py. All internal consumers import from aiohomematic.central.events.internal directly.

  • publish_data_point_updated_event(): Now publishes a single event instead of N events (one per registered custom_id). Signature simplified: data_point and custom_id parameters removed.

Version 2026.3.22 (2026-03-31)

What's Changed

Fixed

  • Fixed acknowledge for alarm messages: acknowledge_message.fn now distinguishes between service messages (ID_SERVICES) and alarm messages. Service messages still require OPERATION_WRITE on the trigger datapoint, while alarm messages are always acknowledged — matching the CCU WebUI behavior (alarmMessages.htm).

  • Fixed false channel identification for hub data points: Device.identify_channel used plain substring matching (str(ise_id) in text) for ISE ID lookups, causing false positives when short numeric IDs (e.g. 0, 10) appeared as suffixes in system variable names like SV_HKV_10. This could lead to incorrect name generation and missing entities in Home Assistant. The method now uses word-boundary matching, requiring the ID to be delimited by non-word characters.

Changed

  • Renamed rega_id to ise_id: Aligned internal naming with official Homematic terminology. The CCU-internal object identifier is called ise_id (not rega_id) in the Homematic ecosystem. This is a breaking API change affecting Device.ise_id, Channel.ise_id, and client methods like get_ise_id_by_address, rename_device(ise_id=...), rename_channel(ise_id=...), has_program_ids(ise_id=...).

Version 2026.3.21 (2026-03-30)

What's Changed

Fixed

  • Quittable flag based on trigger datapoint: get_service_messages.fn now checks OPERATION_WRITE on the trigger datapoint instead of the alarm object, matching the CCU WebUI behavior (serviceMessages.htm).

  • Acknowledge only writable messages: acknowledge_message.fn now refuses to acknowledge messages whose trigger datapoint lacks the OPERATION_WRITE bit, returning an error instead of silently acknowledging non-quittable messages.

Changed

  • Removed auto-enable of alarm/service SysVars: The system variables ${sysVarAlarmMessages} (ID 40) and ${sysVarServiceMessages} (ID 41) are no longer force-enabled and renamed. These are fully superseded by the dedicated HmAlarmMessagesSensor and HmServiceMessagesSensor hub data points.

  • Exposed message DPs on HubCoordinator: alarm_messages_dp and service_messages_dp are now accessible via HubCoordinator as DelegatedProperty for direct access from downstream consumers.

Version 2026.3.20 (2026-03-29)

What's Changed

Added

  • Message enrichment in aiohomematic: ServiceMessageData and AlarmMessageData now include pre-resolved fields (message_code, display_name, msg_type_name) so downstream consumers no longer need to extract parameter names from raw CCU message formats or map numeric types to text. Translations are provided via the existing i18n system (en/de).

  • ServiceMessageType enum extended: Added ALARM (3), UPDATE_PENDING (4), and COMMUNICATION (5) to cover all CCU service message types.

  • Additional information for message sensors: HmAlarmMessagesSensor and HmServiceMessagesSensor now expose each message as an individual extra state attribute (alarm_1, alarm_2, ... / message_1, message_2, ...) with human-readable display names, making them directly accessible in HA templates.

  • Dynamic i18n key detection: check_i18n_catalogs.py now recognizes f-string prefixes in i18n.tr() calls, preventing false unused-key warnings for dynamically constructed translation keys.

Fixed

  • DST-safe callback alive and connection checks: Replaced datetime.now() with time.monotonic() for all duration calculations in is_callback_alive(), is_connected(), and ConnectionHealth scoring. Wall-clock time jumps during DST transitions (or NTP corrections) caused false callback timeout detections (e.g. 3602s instead of 2s after a spring-forward). Monotonic timestamps are immune to clock adjustments. The LastEventTrackerProtocol gains a new get_last_event_monotonic_for_interface() method.

  • Alarm messages not returned: Fixed ReGa script get_alarm_messages.fn not returning active alarm messages. The script required a resolvable trigger data point (AlTriggerDP), but system alarms (e.g. WatchDog) use the sentinel value 65535 which has no backing object. Trigger information is now optional. Also replaced the asOncoming constant with numeric 1 for reliability across CCU firmware versions.

Version 2026.3.19 (2026-03-28)

What's Changed

Added

Cross-Project Platform Improvements

  • DataPointType enum: New DataPointType StrEnum providing a canonical data point type (SENSOR, SWITCH, CLIMATE, COVER, LIGHT, LOCK, etc.) for downstream consumers. Accessible via data_point.data_point_type property on all data point types. Eliminates isinstance checks and custom mapping logic in bridges and integrations.

  • CentralUnit async context manager: CentralUnit now supports async with for automatic start()/stop() lifecycle management, preventing resource leaks.

  • EventBus subscription groups: New SubscriptionGroup class and event_bus.create_subscription_group(name) factory method for collective subscription lifecycle management. Replaces error-prone manual unsubscribe callback tracking with group.subscribe() / group.unsubscribe_all().

  • Device name in events: DeviceTriggerEvent, DeviceLifecycleEvent, OptimisticRollbackEvent, and DataPointStateChangedEvent now carry human-readable device names (device_name / device_names fields), eliminating the need for downstream consumers to perform separate device registry lookups.

  • State transition callback API: New central.on_state_transition() method for registering handlers on specific CentralState transitions (e.g., DEGRADED → RUNNING). Supports wildcard from_state=None for any-source transitions.

  • Extended query facade: get_data_points() now accepts a data_point_type filter parameter. New get_devices() method with interface and available filters for device-level queries. New get_schedule_capable_devices() method returning ScheduleInfo objects for devices with week profile support.

OpenCCU API Extensions

  • System variable creation: New methods create_system_variable_bool(), create_system_variable_float(), and create_system_variable_enum() for creating system variables on the CCU backend. Exposed through JSON-RPC client, backend protocol, CcuBackend, InterfaceClient, and HubCoordinator.

  • Link info read/write: New methods get_link_info() and set_link_info() for reading and writing link metadata (name, description) between paired device channels. Exposed through JSON-RPC client, backend protocol, CcuBackend, InterfaceClient, and LinkCoordinator.

  • Service message suppression: New methods get_suppressed_service_messages() and suppress_service_message() for suppressing or unsuppressing service messages per channel. Exposed through JSON-RPC client, backend protocol, CcuBackend, InterfaceClient, and HubCoordinator.

Parameter Metadata

  • Conditional visibility metadata: SenderTypeMetadata now supports conditional_visibility (rules for showing/hiding parameters based on trigger values), parameter_groups (semantic grouping of related parameters), and cross_validation_rule_ids (references to applicable cross-parameter validation rules). Data is parsed from the easymode archive when available.

Version 2026.3.18 (2026-03-27)

What's Changed

Added

  • SysvarDpSwitch turn_on/turn_off: Added turn_on() and turn_off() methods to SysvarDpSwitch, enabling direct use as a HA SwitchEntity. Previously only the generic send_variable(value=...) was available. The methods use optimistic state updates via send_variable.

Version 2026.3.17 (2026-03-25)

What's Changed

Added

  • Service messages hub sensor: New HmServiceMessagesSensor exposes active CCU service messages (from ID_SERVICES) as a hub sensor in Home Assistant. The sensor value is the count of active messages; full message details are available via the messages attribute.

  • Alarm messages hub sensor: New HmAlarmMessagesSensor exposes active CCU alarm messages (from ID_SYSTEM_VARIABLES) as a hub sensor. These are user-created system alarms shown in the CCU WebUI under "Alarmmeldungen" — previously not available in aiohomematic at all.

  • Extended service message data: ServiceMessageData now includes last_timestamp, counter, rooms (tuple), functions (tuple), and quittable flag, matching the data shown in the CCU WebUI. Inactive channels are filtered out.

  • Alarm message data: New AlarmMessageData dataclass with alarm_id, name, description, device_name, timestamp, last_timestamp, counter, last_trigger, and rooms.

  • New ReGa script: get_alarm_messages.fn reads alarm messages from ID_SYSTEM_VARIABLES, filtered for active ALARMDP objects.

  • New device HmIP-DLP: Added support for the IP Door Lock Pro with lock control (channel 12) and button lock (channel 0). Includes battery data (4× AA).

  • Backend capability: alarm_messages flag added to BackendCapabilities (enabled for CCU backend only).

  • Acknowledge messages: New acknowledge_message() method on AioJsonRpcAioHttpClient allows quitting (receipting) service messages and alarm messages by their ReGa ID. Uses new acknowledge_message.fn ReGa script with AlReceipt() for both ID_SERVICES and ALARMDP objects.

Fixed

  • get_alarm_messages.fn: Fixed ReGa parse error caused by non-existent LastTriggerMessage() method. Replaced with trigger data point name via AlTriggerDP(). Added AlTriggerDP() > 0 filter to exclude system counting variables (${sysVarAlarmMessages}, ${sysVarPresence}) and user-created alarm-type sysvars without device triggers. Switched from compound && conditions to nested if statements to prevent ReGa error propagation.

  • get_alarm_messages.fn / get_service_messages.fn: Fixed device_name, rooms, and functions fields being empty or containing ReGa object IDs instead of actual names. Root cause: oTrigger.Channel() returns the channel ID (integer), not the object — added dom.GetObject(iChnId) to resolve the channel object before accessing Name(), ChnRoom(), and ChnFunction().

  • get_service_messages.fn: Removed ChnInactive() check that caused runtime errors on some channels, breaking the entire iteration and producing malformed JSON output ([,,,]).

Version 2026.3.16 (2026-03-24)

What's Changed

Improved

  • Consolidate CCU extracted data into gzip archives: Restructured the storage of CCU-sourced data from individual JSON files to gzip-compressed archives, reducing package size from ~11 MB to ~516 KB (95% reduction).

  • New directory aiohomematic/ccu_data/ replaces the previous scattered layout:

    • easymode_extract.json.gz — all easymode metadata (was 65 files + 2 in easymode_extract/, 10 MB → 140 KB)
    • translation_extract.json.gz — all extracted CCU translations (was 11 files in translations/ccu_extract/, 636 KB → 125 KB)
    • translation_custom/ — hand-maintained translation overrides (unchanged, editable JSON files)
  • Updated easymode_data.py and ccu_translations.py loaders to decompress from .json.gz archives via gzip.decompress() + pkgutil.get_data()
  • Updated extraction scripts (extract_ccu_easymodes.py, extract_ccu_translations.py) to output gzip archives directly
  • Removed aiohomematic/easymode_extract/, translations/ccu_extract/, and translations/ccu_custom/ directories

Version 2026.3.14 (2026-03-24)

What's Changed

Added

  • Add CCU easymode metadata extraction: New script script/extract_ccu_easymodes.py parses TCL easymode configuration files from the CCU WebUI and extracts structured metadata for 65 channel types, including easymode profiles, subsets, parameter ordering, and option preset references. Supports dual-source loading from local OCCU checkout and/or remote CCU instance.

  • Add easymode data loader API: New module aiohomematic/easymode_data.py provides thread-safe, lazily loaded access to extracted easymode metadata (channel metadata, option presets, cross-validation rules) via pkgutil.get_data().

  • Add 46 option preset definitions: Extracted preset sets (BLIND_LEVEL, DELAY, LENGTH_OF_STAY, DIM_ONLEVEL, RAMPTIME, LOGIC_COMBINATION, etc.) from options.tcl for use in configuration UI dropdowns.

  • Add cross-parameter validation: New validate_cross_parameters() function in parameter_tools.py checks constraints between related parameters (e.g. DIM_MAX_LEVEL >= DIM_MIN_LEVEL, COND_VALUE_HI >= COND_VALUE_LO). Integrated into ConfigurationCoordinator.put_paramset() to validate before RPC call.

  • Include easymode extract data in package: Updated pyproject.toml to include easymode_extract/*.json and easymode_extract/channel_metadata/*.json in the distributed package.

  • Extract easymode TCL inline option value translations: New parse_easymode_tcl_option_values() in script/extract_ccu_translations.py extracts param=index → translated label mappings from set options(N) patterns inside easymode TCL files, adding ~320 new parameter value translations per locale (EN/DE) for parameters like acoustic_alarm_signal, acoustic_alarm_timing, optical_alarm_signal, and many more.

  • Add use_fallback parameter to get_parameter_value_translation(): New optional use_fallback flag (default True) allows callers to skip the generic value-only fallback and restrict lookups to parameter-specific translations only.

Version 2026.3.13 (2026-03-22)

What's Changed

Improved

  • Extract 134 additional parameter translations from CCU firmware: Expanded the CCU translation extraction script to scan all easymode TCL files (not just *_master.tcl), resolving parameter-to-template-variable mappings from hmipChannelConfigDialogs.tcl and other HmIP configuration dialogs. Also broadened the template variable regex to match all camelCase variables (not just stringTable*/lbl* prefixes). PNAME labels now take priority over easymode TCL labels to preserve official localization quality.

Added

  • Add 85 custom parameter translations: Added German and English labels for parameters that have help text in the CCU firmware but no label (e.g. blocking_period, door_lock_hold_time, sensor_sensitivity_rain, mounting_orientation, ESI OBIS codes, soil moisture settings, and many more HmIP MASTER parameters).

Version 2026.3.12 (2026-03-22)

What's Changed

Fixed

  • Skip duplicate optimistic sends for identical values: When an automation triggers switch.turn_on twice in rapid succession (~100ms), the second send is now skipped if an optimistic value with the same target is already pending. Previously, the optimistic tracker incremented pending_sends to 2 while the CCU only confirmed once, causing a spurious rollback after 30s that set the switch to OFF despite the device being physically ON (#3049).

Improved

  • Hide BOOTED parameter by default: Added BOOTED to the default hidden parameters list in visibility rules.

Version 2026.3.11 (2026-03-21)

What's Changed

Added

  • Add resolve_channel_type for HmIP translation lookups: New function that resolves the effective channel type for translation lookups by appending _HMIP when HmIP-specific translations exist, matching the CCU WebUI behavior where HmIP devices may have different parameter semantics.

Version 2026.3.10 (2026-03-19)

What's Changed

Improved

  • Include hidden and device-level channels with MASTER paramset in configuration: Device-level entries, internal channels, and invisible channels were previously excluded from get_configurable_channels(). They are now included when they have a MASTER paramset (restricted to MASTER only), allowing configuration of device-wide settings that live on these channels.
  • Show read-only MASTER parameters in device configuration: The MASTER paramset filter in get_configurable_devices() previously required parameters to be writable. It now includes all visible, non-internal parameters regardless of write access, so read-only configuration values are also displayed.

Version 2026.3.9 (2026-03-19)

What's Changed

Fixed

  • Skip optimistic updates for action data points: Action data points (ACTION, ACTION_NUMBER, ACTION_SELECT, BUTTON) and parameters without event support never receive CCU event confirmations. The optimistic update timer would always expire after 30 seconds, causing spurious OPTIMISTIC_ROLLBACK timeout warnings in the log. This was particularly visible with the HmIP-MP3P LED channel (Repetitions, Ramp Time, Duration parameters).

Improved

  • TLS: Use certifi CA bundle when available: The TLS context now loads the certifi CA bundle in addition to the system default verify paths when the certifi package is installed. This ensures trusted certificates work out-of-the-box in environments like Home Assistant that ship certifi but may not have a complete system trust store.

Version 2026.3.8 (2026-03-13)

What's Changed

Fixed

  • Connection recovery heartbeat not starting after startup failure: The _on_central_state_changed handler compared the trigger string with exact match (== "no clients connected"), but central_unit.py emits "no clients connected (start() completed)". Changed to startswith for robust matching. Without this fix, the heartbeat timer never started after a startup failure (e.g., CCU rebooting after firmware update), leaving the central stuck in FAILED state with no automatic retry.

Version 2026.3.7 (2026-03-11)

What's Changed

Added

  • PayloadProtocol: New protocol interface guaranteeing config_payload, info_payload, and state_payload properties. Added to DeviceProtocol, ChannelProtocol, BaseDataPointProtocol, GenericHubDataPointProtocol, and CentralProtocol. Downstream consumers can now depend on the payload API through protocol interfaces. Defined in _payload_protocol.py (minimal module to avoid circular imports, following the _log_context_protocol.py pattern). PayloadMixin now explicitly inherits from PayloadProtocol.

Version 2026.3.6 (2026-03-11)

What's Changed

Added

  • Property alt_name support: All property decorators (config_property, state_property, info_property, hm_property) and DelegatedProperty now accept an optional alt_name parameter. When use_alt_names=True is passed to get_hm_property_by_kind(), the alternative name is used as dict key instead of the property name. This enables payload keys to differ from internal property names.
  • PayloadMixin (config_payload, state_payload, info_payload) now uses use_alt_names=True by default, so properties with alt_name automatically use the alternative key in payloads. Log context remains unaffected and continues to use the original property name.
  • Exact contract tests for payload key stability: Rewrote property decorator contract tests to use exact set equality via get_hm_property_by_kind() instead of subset checks. Tests now detect property additions, removals, Kind reclassifications, and alt_name changes for Device, Climate, and generic DataPoint classes. Added INFO key verification for generic data points.

Changed

  • Capabilities use config_property(cached=True): Reclassified capabilities properties in Climate, Cover, Garage, Light, Lock, and Siren from @info_property(cached=True) to @config_property(cached=True). Capabilities describe immutable device features determined at init, which aligns with Kind.CONFIG semantics.
  • Device payload alt_names: Added alt_name mappings to Device properties for Home Assistant-aligned payload keys: addressserial_number, model_descriptionmodel_id, firmwaresw_version, identifieridentifiers, roomsuggested_area.
  • Climate payload alt_names: Added alt_name mappings to climate properties: activityaction, modehvac_mode, modeshvac_modes, profilepreset_mode, profilespreset_modes.

Version 2026.3.5 (2026-03-10)

What's Changed

Added

  • Data point metadata: Introduced Quantity and ValueBehavior enums in const.py and a new data_point_metadata.py module that maps Homematic parameters to their semantic quantity (e.g., temperature, humidity, energy) and value behavior (instantaneous, cumulative, monotonic). The quantity and value_behavior properties are now available on BaseParameterDataPoint.
  • Cover capabilities: Introduced CoverCapabilities dataclass with static capability flags (position, tilt, stop, vent) for cover entities, consistent with the existing capabilities pattern used by Light, Climate, Lock, and Siren. Predefined capability sets: COVER_CAPABILITIES, BLIND_CAPABILITIES, GARAGE_CAPABILITIES. This replaces the need for isinstance() checks to determine cover features.
  • Cover device documentation: Added detailed documentation for cover device types, capabilities, and garage door specifics including discrete state mapping and position slider behavior.

Changed

  • Capabilities use info_property(cached=True): Replaced manual getattr/object.__setattr__ caching pattern in capabilities properties across Climate, Light, Lock, and Siren with the declarative @info_property(cached=True) decorator. The _capabilities slot has been renamed to _cached_capabilities accordingly.
  • Property decorator improvements: config_property and info_property now support a cached=True parameter for lazy-computed immutable values. Dataclass instances in log context are automatically converted to dicts.
  • Light property categorization: Reclassified brightness_pct, group_brightness, group_brightness_pct, and other light properties from plain @property to @state_property for proper state tracking.
  • Climate temperature bounds: min_temp and max_temp in BaseCustomDpClimate changed from @state_property to @config_property since temperature bounds are configuration values, not runtime state.
  • DelegatedProperty kind annotations: Added Kind.CONFIG/Kind.STATE annotations to ClimateWeekProfile.max_temp/min_temp and CustomDpTextDisplay.burst_limit_warning.

Version 2026.3.4 (2026-03-08)

What's Changed

Fixed

  • Health tracker central state sync: Added sync_central_state() to HealthTracker to synchronize the cached central state after _evaluate_central_state() completes. Previously, the CentralHealth object could hold a stale central state after start or system status events that did not trigger a client health update.

Version 2026.3.3 (2026-03-07)

What's Changed

Security

  • ReGa script injection prevention: Added _escape_rega_string() to escape backslashes and double quotes before interpolating values into ReGa script templates, preventing script injection via crafted system variable names, device addresses, or program IDs.
  • Device address validation: accept_device_in_inbox() now validates the device address format before passing it to ReGa script substitution.
  • Password field protection: CentralConfig.password now uses Field(repr=False, exclude=True) to prevent accidental exposure via repr(), str(), or model_dump().
  • Authorization header sanitization: Added pattern for Authorization: Basic headers to _SENSITIVE_PATTERNS in error message sanitization.
  • TLS disabled warning: JSON-RPC client now logs an info message when TLS is disabled, warning that credentials are transmitted in plain text.
  • Unknown interface_id logging: RPC callback server now logs a warning when receiving events for an unregistered interface_id.
  • ReGa script path traversal prevention: _get_script() and _post_script() now require RegaScript enum instead of arbitrary strings, preventing path traversal attacks via crafted script names.
  • Firmware URL scheme validation: download_firmware() now rejects URLs with non-HTTP(S) schemes, preventing the CCU from connecting to arbitrary protocols.
  • Restrictive temp file permissions: Storage temp files are now created with 0o600 permissions before being atomically replaced, preventing other users from reading cached data.
  • Path traversal protection in delete_file(): File paths resolved via glob are now validated to stay within the target directory using realpath() checks.
  • Documented DEFAULT_VERIFY_TLS=False: Added comment explaining that TLS verification is disabled by default due to self-signed certificates in typical home automation setups.
  • RPC background task limit: The XML-RPC callback server now enforces a maximum of 1000 concurrent background tasks (MAX_RPC_BACKGROUND_TASKS). Excess tasks are dropped with a warning, preventing memory exhaustion from event floods.
  • Cryptographic RNG for address anonymization: Replaced random.randint() and random.shuffle() with secrets.randbelow() and secrets.SystemRandom().shuffle() for device address anonymization in exports and session recordings.
  • Restrictive directory permissions: os.makedirs() calls in storage, device export, and file operations now use mode=0o700, ensuring only the owner can access storage directories.

Performance

  • EventBus pre-sorted handlers: Handlers are now inserted in priority order via bisect.insort during subscription, eliminating sorted() on every event publish.
  • Parallel device finalization: finalize_init() for new devices now runs concurrently via asyncio.gather(), reducing startup time.
  • Parallel client refresh: Polled interface data refreshes now run concurrently instead of sequentially.
  • Optimized custom_id lookup: get_data_point_by_custom_id() now iterates devices directly instead of materializing a full tuple first.
  • Parallel interface operations: Client creation (secondary), initialization, de-initialization, device discovery (start_direct), and firmware refresh now run concurrently across interfaces via asyncio.gather(), while operations within a single interface remain serial (CCU limitation).
  • Parallel async checks: remove_central_link() now runs _has_central_link() and _has_program_ids() concurrently instead of sequentially.
  • Pre-compiled description marker regex: Program and system variable description marker removal now uses a single pre-compiled regex pattern instead of iterating over all DescriptionMarker enum values with str.replace().
  • weakref.finalize for subscription cleanup: CustomDataPoint, CalculatedDataPoint, CombinedDataPoint, and ClimateWeekProfileDataPoint now use weakref.finalize() instead of __del__() for subscription cleanup, ensuring reliable garbage collection even with circular references.
  • slots=True for dataclasses: ValidationResult and ParamsetChange dataclasses now use slots=True to reduce per-instance memory overhead.
  • Optimized is_in_multi_channel_group(): Replaced list comprehension with sum() generator and early None return.

Version 2026.3.2 (2026-03-06)

What's Changed

Changed

  • Python 3.14 minimum: Dropped Python 3.13 support. Python 3.14 is now the minimum required version. All tool configurations (ruff, mypy, pylint) updated to target Python 3.14. -

Version 2026.3.1 (2026-03-05)

What's Changed

Added

  • DpActionNumber data points: New DpActionFloat and DpActionInteger generic data point types for write-only FLOAT/INTEGER parameters. These provide number entities in Home Assistant (with MIN/MAX validation) while remaining write-only at the protocol level. Previously, all write-only numeric parameters were mapped to DpAction (no HA entity). The resolver now maps write-only FLOAT to DpActionFloat and write-only INTEGER to DpActionInteger.
  • DpActionBoolean and DpActionString data points: New DpActionBoolean and DpActionString generic data point types for write-only BOOL/STRING parameters. These complete the DpAction hierarchy so that every CCU write-only parameter type has a type-safe handler. Previously, write-only BOOL and STRING parameters fell through to the generic DpAction fallback with Any value type. DpAction now only handles TYPE=ACTION parameters (triggers without type information).
  • Type-correct custom data point fields: Replaced DpAction with specific types in custom data points where pydevccu paramset data shows a concrete TYPE: MANU_MODE (TYPE=FLOAT) → DpActionFloat, CONTROL_MODE on HmIP (TYPE=INTEGER) → DpActionInteger, DISPLAY_DATA_COMMIT (TYPE=BOOL) → DpActionBoolean, DISPLAY_DATA_STRING/COMBINED_PARAMETER/LEVEL_COMBINED (TYPE=STRING) → DpActionString. DpAction remains only for genuine TYPE=ACTION parameters (AUTO_MODE, BOOST_MODE, COMFORT_MODE, LOWERING_MODE, STOP, OPEN).

Refactored

  • CombinedDataPoint for timer value+unit pairs: Introduced CombinedDataPoint base class and CombinedDpTimerAction concrete implementation in aiohomematic/model/combined/. This new data point type combines multiple underlying data points (e.g., timer value + unit) into a single writable entity with automatic unit conversion (seconds to S/M/H). Replaced the ephemeral TimerField/TimerAccessor pattern with the CombinedTimerField descriptor, which creates persistent CombinedDpTimerAction instances during custom data point initialization. For the IP Siren (HmIP-ASIR), the duration combined data point is exposed as a visible HA number entity (max=58,834,800 seconds) with automatic unit conversion, replacing the raw DURATION_VALUE number entity that had no unit context. Applied across all custom data points with timer parameters: lights, sirens, switches, and valves. Also removed TimerUnitMixin, OnOffActionMixin, TimerAccessor, and TimerField.
  • CombinedDpHsColor for hue+saturation pairs: New CombinedDpHsColor combined data point that encapsulates HUE + SATURATION into a single tuple[float, float] value with automatic saturation scaling (CCU 0.0–1.0 ↔ HA 0.0–100.0). Added CombinedHsColorField descriptor and generalized the combined field detection from timer-specific (COMBINED_TIMER_FIELD_MARKER) to generic (COMBINED_FIELD_MARKER + CombinedFieldProtocol). Simplified CustomDpIpRGBWLight and CustomDpIpDrgDaliLight by replacing identical boilerplate hs_color property and turn_on() conversion logic with delegation to the combined data point. Removed ParamType bound from CombinedDataPoint generic parameter to support non-ParamType value types.
  • Unified field visibility in profile configs: Merged 6 field dictionaries (3 pairs of hidden/visible) in ChannelGroupConfig into 3 dictionaries where each entry carries its own visibility via hidden()/visible() helper functions. fields, channel_fields, and fixed_channel_fields now accept FieldValue (either bare Parameter for default behavior, hidden(Parameter.X) for NO_CREATE, or visible(Parameter.X) for CDP_VISIBLE). Removed visible_fields, visible_channel_fields, and visible_fixed_channel_fields from both ChannelGroupConfig and RebasedChannelGroupConfig. Updated _init_data_points() and helper methods to use resolve_field_value() for per-entry visibility extraction. Removed dead ProfileKey.VISIBLE_FIELDS, ProfileKey.VISIBLE_REPEATABLE_FIELDS, and ProfileKey.REPEATABLE_FIELDS enum members.

Fixed

  • Scheduler busy-loop at 100% CPU during connection issues: When has_connection_issue was True, the scheduler entered a busy-loop because skipped jobs (all except _check_connection) never advanced their next_run, causing the sleep calculation to compute delay = 0.0. The sleep calculation now only considers jobs eligible to run in the current state, and skipped jobs advance their schedule to prevent a burst of simultaneous execution on recovery.

Version 2026.3.0 (2026-03-01)

What's Changed

Fixed

  • Device link encoding: Fix garbled UTF-8 characters in device link names and descriptions retrieved via XML-RPC. The CCU stores user-defined strings as UTF-8 but the XML-RPC transport decodes them as ISO-8859-1, causing multi-byte characters to be misinterpreted (e.g. üü). New fix_xml_rpc_encoding utility in support.text_utils reverses the double-encoding.

Version 2026.2.32 (2026-02-28)

What's Changed

Fixed

  • Non-climate schedule: allow empty target channels: Schedules without explicit target channels were incorrectly filtered as inactive because is_schedule_active() required both weekdays and target channels. The CCU handles default channel assignment when no explicit channels are configured, so the activity check now only requires at least one weekday. The SimpleScheduleEntry.target_channels field default was changed from min_length=1 to default_factory=list and the fallback in convert_raw_group_to_simple_entry() now returns an empty list instead of ["1_1"].

Version 2026.2.31 (2026-02-27)

What's Changed

Fixed

  • Install mode: Use interface-specific client instead of primary client for install mode buttons. Previously, activating install mode for one interface (e.g. HmIP-RF) could incorrectly target another interface (e.g. BidCos-RF). (#2990)

Version 2026.2.30 (2026-02-27)

What's Changed

Added

  • Device icons: Extract device model → icon filename mapping from CCU's DEVDB.tcl (525 entries). New get_device_icon() in ccu_translations and icon property on Device / DeviceIdentityProtocol expose the filename relative to img/devices/250/ for downstream consumers (e.g. Home Assistant).
  • Profile-specific parameter translations: Extract ~550 additional parameter translations from CCU easymode profile localization files (e.g. COLOR_TEMP, MAX_COLOR_TEMP, SWITCH_DIRECTION), merged with lowest priority into the existing parameters_{locale}.json output.

Version 2026.2.29 (2026-02-27)

What's Changed

Added

  • Parameter help texts: Extract and expose Markdown-formatted help texts for ~165 MASTER paramset parameters (e.g. BUTTON_LOCK, TEMPERATURE_OFFSET, VALVE_OFFSET) from the CCU WebUI. The HTML content is converted to Markdown, template variables are resolved, and the result is available via get_parameter_help() in ccu_translations and as a description property on BaseParameterDataPoint.

Version 2026.2.28 (2026-02-27)

What's Changed

Fixed

  • Fix spurious optimistic update rollbacks: apply_optimistic_value() was called before the is_state_change() check in the direct send path. When sending a value identical to the current state (e.g. turning off an already-off switch), the optimistic timer started but no RPC was sent to the CCU, making confirmation impossible. After 30 seconds the timer fired a spurious rollback with warning logs and OptimisticRollbackEvent. The state change check now runs first so optimistic tracking is only activated when an RPC call actually occurs.

Version 2026.2.27 (2026-02-26)

What's Changed

Fixed

  • Fix channel-specific translation lookup: The channel_type parameter in get_parameter_translation() and get_parameter_value_translation() was not lowercased before lookup, while all stored keys are lowercase. This caused channel-specific translations (e.g. maintenance|low_bat → "Batterie") to never match when the channel type came from device descriptions in uppercase (e.g. MAINTENANCE). Both functions now normalize channel_type to lowercase.

Docs

  • Document Week Profile sensor value: Added explanation of the Week Profile sensor's numeric value to the user documentation, describing how the count of active schedule entries is computed for climate and non-climate devices.

Version 2026.2.26 (2026-02-26)

What's Changed

Improved

  • Add option value translations from options.tcl: The extraction script now parses options.tcl to resolve translated labels for MASTER paramset dropdown parameters. This adds ~65 new entries per locale to parameter_values_*.json, covering POWERUP_JUMPTARGET, LOGIC_COMBINATION, FLOOR_HEATING_MODE, HEATING_MODE_SELECTION, MIOB_DIN_CONFIG, DALI_EFFECTS, and more. Parameters that previously showed raw VALUE_LIST values (e.g. ON_DELAY, LOGIC_OR) now display human-readable labels in the UI.

Version 2026.2.25 (2026-02-23)

What's Changed

Fixed

  • Use JSON-RPC for HmIP-RF install mode: The Java-based HMIPServer does not support the XML-RPC setInstallMode method — it throws IllegalArgumentException: argument type mismatch and returns an empty response. Install mode for HmIP-RF now uses the dedicated JSON-RPC methods Interface.setInstallModeHMIP and Interface.getInstallMode instead. BidCos-RF continues to use XML-RPC setInstallMode as before.
  • Fix BidCos-RF install mode with device address filter: The XML-RPC call for signature (3) setInstallMode(Boolean, Integer, String) incorrectly sent 4 arguments (on, time, mode, address) instead of the documented 3 arguments (on, time, address).
  • Improve empty XML-RPC response handling: Empty HTTP responses from the CCU (e.g. caused by server-side exceptions) are now caught as ExpatError with a specific warning log and raised as ClientException, instead of falling through to the generic exception handler.
  • Fix HmIP-HDM2 cover showing "unknown" state: Devices without tilt support (e.g. HmIP-HDM2 in plissee mode) sent LEVEL_2_STATUS = INVALID from the CCU, which poisoned the cover entity's is_status_valid check and caused Home Assistant to show "unknown" state despite position control working. CustomDpBlind now excludes LEVEL_2 from relevant data points when its value is None.

Version 2026.2.24 (2026-02-23)

What's Changed

Fixed

  • Handle empty XML-RPC responses for void CCU methods: The CCU's setInstallMode method returns an empty HTTP response body instead of a proper XML-RPC response. The XML parser failed with ExpatError: no element found. The proxy now detects empty responses (expat error code 3 at line 1, column 0) and treats them as successful void returns, preventing ClientException when activating install mode.

Version 2026.2.23 (2026-02-22)

What's Changed

Fixed

  • Clear deleted schedule entries on CCU: DefaultWeekProfile.convert_dict_to_raw_schedule now explicitly zeroes out WEEKDAY and TARGET_CHANNELS for unused groups (1-24) that are not in the schedule. This ensures that deleted schedule entries are properly deactivated on the CCU, since put_paramset only updates keys that are sent.

Version 2026.2.22 (2026-02-22)

What's Changed

Added

  • Schedule domain property for week profiles: Add schedule_domain property to WeekProfileDataPoint and WeekProfileDataPointProtocol that returns the DataPointCategory (switch, light, cover, valve) for non-climate schedule devices. This enables consumers like the Home Assistant Climate Schedule Card to distinguish schedule types and adapt their UI accordingly.

Version 2026.2.21 (2026-02-20)

What's Changed

Fixed

  • Documentation audit and corrections: Comprehensive review and update of ~20 documentation files to match the current implementation. Key fixes include: corrected class names (AsyncXmlRpcServer, AsyncRPCFunctions, AioJsonRpcAioHttpClient, CommandTracker), updated API signatures for metrics emission functions (emit_* now use key parameter instead of source/source_id/operation), fixed coordinator access patterns (central.state, central.hub_coordinator, central.client_coordinator, central.link), corrected event types (DataPointValueReceivedEvent), updated constant values (COMMAND_TRACKER_MAX_SIZE: 500, LAST_COMMAND_SEND_STORE_TIMEOUT: 60), fixed exception hierarchy (BaseHomematicException as base), and updated sequence diagrams with correct RecoveryStage enum values and EventBus subscription patterns.

Version 2026.2.20 (2026-02-19)

What's Changed

Added

  • LinkCoordinator for device direct link management: Add LinkCoordinator as a high-level facade for listing, creating, and removing direct links between device channels. Includes DeviceLink and LinkableChannel dataclasses for enriched link data with translated channel type labels, device metadata, and link direction. The coordinator provides linkable channel discovery with role-based filtering. Exposed via LinkFacadeProtocol and wired into CentralUnit as link property.

  • Dimmer last-level tracking: Add last_level property and set_last_level method to CustomDpDimmer for tracking the last non-default brightness level, enabling restore-to-previous-brightness workflows.

  • Channel link peer categories: Add link_peer_source_categories and link_peer_target_categories properties to ChannelGroupingProtocol for exposing link role categories per channel.

  • Configurable device listing: Add get_configurable_devices to ConfigurationCoordinator returning ConfigurableDevice dataclasses with resolved channel type labels, effective paramset keys (MASTER excluded when no writable visible parameters exist), and MaintenanceData from channel 0. Exposed via ConfigurationFacadeProtocol.

  • Paramset copy operation: Add copy_paramset to ConfigurationCoordinator for copying writable paramset values from a source channel to a target channel. Filters non-writable and missing parameters, returns CopyParamsetResult with copy/skip counts and old target values for change tracking.

Documentation

  • Architecture docs updated: Add ConfigurationCoordinator and LinkCoordinator to Mermaid component diagram, Central Protocols listing, and coordinator categorization (new "Facade coordinators" category). Update ChannelGroupingProtocol description with new link peer category properties.

  • CLAUDE.md updated: Update coordinator directory tree (7 → 9 files, add configuration.py and link.py). Add ConfigurationFacadeProtocol and LinkFacadeProtocol to Key Protocol Interfaces listing.

  • API reference updated: Add configuration and link properties to CentralUnit members list in docs/reference/api/central.md.


Version 2026.2.19 (2026-02-19)

What's Changed

Added

  • On-demand LINK paramset description fetching: Add get_paramset_description_on_demand to InterfaceClient and get_link_paramset_description to ConfigurationCoordinator for fetching LINK paramset descriptions directly from the backend when needed. LINK paramsets are not cached during device discovery, so this API enables direct link configuration without requiring a full device reload.

Version 2026.2.18 (2026-02-17)

What's Changed

Improved

  • Add translations for LINK paramset parameters: LINK paramset parameters use SHORT_/LONG_ prefixes (e.g. SHORT_ON_LEVEL, LONG_RAMPON_TIME). The translation lookup now strips these prefixes as fallback, matching the CCU WebUI behavior, and prepends the press-type label (e.g. "Tastendruck kurz" / "Button press short"). Added 138 custom parameter name translations and 1,150 custom enum value translations covering all LINK paramset parameters (time bases, time modes, action types, profile actions, condition types, jump targets, driving modes, control modes, and more).

Fixed

  • Fix delayed device creation failing on multi-interface devices: When a new HmIP device was paired, the CCU sends newDevices on multiple interfaces (e.g. HmIP-RF and VirtualDevices) with the same device address. _delayed_device_descriptions was keyed by device address only, causing the first add_new_devices_manually call to consume descriptions from all interfaces, while the second call found nothing and failed with No device description found. Fixed by making _delayed_device_descriptions interface-aware (keyed by {interface_id: {address: [descriptions]}}). Also fixed: DEVICES_DELAYED event now only reports addresses for the current interface, and missing addresses in a batch no longer abort the entire operation (continue instead of return).

Version 2026.2.17 (2026-02-16)

What's Changed

Fixed

  • Preserve channel postfix when translation suppresses parameter name: When a parameter translation resolves to an empty string ("") for a multi-channel data point, the channel disambiguation postfix (e.g. ch13) was lost because the truthiness check treated "" the same as None. Changed to an identity check (is not None) so that an empty translation correctly yields translated_name="ch13" instead of removing the name entirely.

Changed

  • example.py uses environment variables: Hardcoded CCU credentials replaced with os.environ lookups. A lightweight .env loader reads variables from the project-root .env file at startup.

Version 2026.2.16 (2026-02-16)

What's Changed

Improved

  • Translate custom data point postfix: When a custom data point provides a data_point_name_postfix (e.g. BUTTON_LOCK), it is now translated via get_parameter_translation — the same mechanism used for generic data points and events. The translated postfix populates translated_name and translated_full_name in DataPointNameData.

Version 2026.2.15 (2026-02-15)

What's Changed

Fixed

  • i18n: Allow multiple CentralUnit instances: set_locale() is now idempotent — calling it again with the same locale is a no-op. When called with a different locale, it logs a message and keeps the original. Previously, creating a second CentralUnit raised RuntimeError because set_locale() was strictly one-shot.

Version 2026.2.14 (2026-02-15)

What's Changed

Improved

  • Empty parameter translation suppresses parameter name: When a CCU parameter translation resolves to an empty string (""), the parameter name is now omitted from translated_name and translated_full_name in DataPointNameData. This allows translations to explicitly suppress redundant parameter names when the channel name already conveys the meaning. None (no translation found) still falls back to the original untranslated name as before.

Version 2026.2.13 (2026-02-15)

What's Changed

Improved

  • Extraction script: PNAME and easymode TCL parsing: Added two new extraction sources to extract_ccu_translations.py:

  • PNAME.txt files with direct parameter name → label mappings

  • Easymode TCL files (*_master.tcl) for parameter → template variable resolution via set param / ${stringTable...} patterns
  • Improved HTML entity decoding (", <, >)
  • Source merging refactored into _merge_sources() helper
  • Parameters: 841 → 1029 (+188), parameter values: 1256 → 1326 (+70), device models: 365 → 367 (+2)

  • Extraction script fixes: Fixed multiple bugs in extract_ccu_translations.py that caused ~215 parameter translations to be missed:

  • Added translate.lang.extension.js and translate.lang.js as extraction sources

  • Added MASTER_LANG device-specific translation files as additional source
  • Fixed comment regex that destroyed :// URLs inside string values
  • Fixed regex to target langJSON specifically (ignoring HMIdentifier blocks)
  • Added parsing of langJSON alias assignments after jQuery.extend blocks
  • Added handling of invalid JS escape sequences (\', \.) for JSON compatibility
  • Added channelDescription.js and deviceDescription.js to template resolution

  • Custom translation cleanup: Removed 17 redundant entries from ccu_custom/parameters_*.json and ccu_custom/parameter_values_*.json that are now correctly provided by the improved extraction. Added 67 channel-qualified override keys to ensure custom translations take precedence over extracted channel-specific translations.

  • Value-only translation fallback: get_parameter_value_translation now has a three-tier lookup: channel-specific → parameter-specific → value-only. The new value-only fallback builds an index of standalone enum values mapped to their shortest (most generic) translation, so shared values like true, false, or weekday names resolve even for unknown parameters.

  • Weekday translations: Added show_weekday value translations (Monday–Sunday) to ccu_custom/parameter_values_*.json (EN + DE).

  • Configurable channel filtering: get_configurable_channels now applies CCU-compatible filtering rules: channels must have the VISIBLE flag set and must not have the INTERNAL flag. WEEK_PROGRAM channels are excluded as they are handled by schedule cards.

Version 2026.2.12 (2026-02-13)

What's Changed

Improved

  • CCU translation loading via pkgutil: Replaced Path.read_text() with pkgutil.get_data() for loading CCU translation files. This avoids blocking file I/O detection in Home Assistant's event loop. Translations are now eagerly initialized at import time to prevent any later I/O on first use.

Version 2026.2.11 (2026-02-13)

What's Changed

Improved

  • Robust JSON parsing with stdlib fallback: When orjson fails to parse JSON from CCU Rega scripts (e.g., due to non-standard literals like NaN or Infinity), the parser now falls through to Python's stdlib json module which handles these edge cases gracefully.

  • Extended control character sanitization: The JSON sanitizer now also escapes the DEL character (U+007F) in string values, in addition to the existing U+0000–U+001F range.

  • Diagnostic logging for JSON parse errors: When a Rega script response fails to parse as JSON, the exact problematic character (Unicode codepoint), its position, and surrounding context are now logged at WARNING level to aid diagnosis.

Changed

  • CCU translation API: Renamed functions and properties for semantic accuracy:
  • get_device_model_label()get_device_model_description()
  • get_channel_type_label()get_channel_type_translation()
  • get_parameter_label()get_parameter_translation()
  • get_parameter_value_label()get_parameter_value_translation()
  • Device.labelDevice.model_description
  • Channel.labelChannel.type_translation
  • BaseParameterDataPoint.labelBaseParameterDataPoint.translation
  • BaseParameterDataPoint.value_labelsBaseParameterDataPoint.value_translations
  • CalculatedDataPoint.labelCalculatedDataPoint.translation

Version 2026.2.10 (2026-02-11)

What's Changed

Added

  • CCU translation extraction: New script (script/extract_ccu_translations.py) that extracts human-readable translations from the OpenCCU/RaspberryMatic WebUI for channel types, device models, parameter names, and parameter enum values. Supports local OCCU checkout (OCCU_PATH) and remote CCU fetch (CCU_URL). Resolves the two-level stringtable indirection, URL-decodes Latin-1 characters, and strips HTML from values.

  • CCU translations loader module: New module (aiohomematic/ccu_translations.py) providing typed lookup functions for CCU-sourced translations:

  • get_channel_type_label(): Channel type labels (e.g. BLIND -> "Jalousieaktor")

  • get_device_model_label(): Device model descriptions with sub_model fallback for abbreviated HmIP keys (e.g. PS, SMO, BSM)
  • get_parameter_label(): Parameter labels with channel-specific fallback
  • get_parameter_value_label(): Enum value labels with channel-specific fallback

All lookups are thread-safe (double-checked locking) and asyncio event loop safe (lazy initialization, then pure dict reads with zero I/O).

  • Generated translation files: 8 JSON files under aiohomematic/translations/ccu_extract/ (4 categories x 2 locales: de, en) with 2500+ translation entries total.

  • CCU translation custom override layer: New aiohomematic/translations/ccu_custom/ directory with identically-named JSON files (empty by default). Keys in ccu_custom/ override or supplement keys from ccu_extract/ at load time and survive re-extraction.

  • Labels for calculated data points: Calculated data points (dew point, enthalpy, frost point, etc.) now resolve human-readable labels via ccu_translations, matching the behavior of parameter-backed data points. Custom translations for all 10 calculated parameters are provided in ccu_custom/parameters_{de,en}.json.

Documentation

  • ADR-0024: Architecture Decision Record for CCU translation extraction (docs/adr/0024-ccu-translation-extraction.md)

Version 2026.2.9 (2026-02-11)

What's Changed

Added

  • parameter_tools module: New standalone module (aiohomematic/parameter_tools.py) providing pure-function utilities for working with ParameterData descriptions, independent of DataPoint instances:

  • ParameterHelper: Flag and operation checks (is_parameter_visible, is_parameter_writable, has_parameter_events), enum resolution (resolve_enum_value, resolve_enum_index), and step size calculation (get_parameter_step).

  • ParameterValidator: Value validation (validate_value, validate_paramset) and type coercion (coerce_value) against parameter descriptions without requiring a DataPoint instance.
  • ParamsetDiff: Type-aware comparison of two paramset snapshots (diff_paramset) with proper float equality handling.

  • ConfigurationCoordinator: New high-level facade (aiohomematic/central/coordinators/configuration.py) for device configuration operations, exposed as central.configuration. Provides:

  • get_paramset_description() / get_all_paramset_descriptions(): Read parameter definitions for a channel.

  • get_paramset() / put_paramset(): Read and write paramset values with optional built-in validation.
  • get_configurable_channels(): Discover configurable channels for a device.
  • get_parameter_data(): Look up a single parameter description.

  • ConfigurationFacadeProtocol: Protocol interface for the configuration facade, enabling dependency injection and testability for consumers.

Version 2026.2.8 (2026-02-09)

What's Changed

Refactored

  • Extract DeviceQueryFacade from CentralUnit (P1): Moved 12 query methods (get_data_points, get_events, get_generic_data_point, get_custom_data_point, get_data_point_by_custom_id, get_event, get_event_groups, get_readable_generic_data_points, get_state_paths, get_install_mode, get_un_ignore_candidates, get_parameters) into a new DeviceQueryFacade class (~348 LOC). CentralUnit retains one-line delegates for API compatibility.

  • Centralize circuit breaker management in BaseBackend: Circuit breakers are now collected and managed by the base backend class via a circuit_breakers tuple. all_circuit_breakers_closed, circuit_breaker, and reset_circuit_breakers are implemented once in BaseBackend, eliminating duplicate logic in CcuBackend, HomegearBackend, and JsonCcuBackend.

  • Replace hasattr introspection in ConnectionHealth.update_from_client: The method now accepts ClientConnectionProtocol instead of Any and reads client.state via the public API instead of reaching into _state_machine, _proxy._circuit_breaker, and _json_rpc_client._circuit_breaker.

  • Thread-safe RequestCoalescer: The check-and-register operation is now protected by an asyncio.Lock, making it safe under Python 3.13+ free-threading. The lock is released before awaiting the actual request to allow concurrent coalescing.

  • Extract OptimisticValueTracker from BaseParameterDataPoint: Consolidated 5 optimistic-update-related slots into a single pure state management class (aiohomematic/model/optimistic.py, ~136 LOC). Manages apply, confirm, and rollback lifecycle with burst support and automatic rollback timeouts — no event publishing, logging, or I/O.

  • Extract _DeviceAvailability and _DeviceFirmware from Device: Moved availability state management (UN_REACH, STICKY_UN_REACH, forced availability) and firmware version tracking / update operations into dedicated helper classes within device.py, reducing the main Device class complexity.

  • Split support.py into support/ package: The monolithic support.py module is now a package with three focused submodules:

  • address.py: Address parsing/validation with @lru_cache

  • file_ops.py: Async file system operations
  • mixins.py: LogContextMixin and PayloadMixin for structured logging

The package re-exports all public symbols, so external imports remain unchanged.

  • Rename proxy lifecycle methods on InterfaceClient: initialize_proxy()init_proxy(), deinitialize_proxy()deinit_proxy(), reinitialize_proxy()reinit_proxy().

Added

  • cleanup() method on CentralDataCache: Forces an expiration check on all interfaces, callable from scheduler or tests.

  • @runtime_checkable on client and model sub-protocols: Added to ClientStateMachineProtocol, ClientIdentityProtocol, ClientConnectionProtocol, ClientLifecycleProtocol, DeviceDiscoveryOperationsProtocol, ParamsetOperationsProtocol, ValueOperationsProtocol, LinkOperationsProtocol, FirmwareOperationsProtocol, SystemVariableOperationsProtocol, ProgramOperationsProtocol, BackupOperationsProtocol, and several channel/device sub-protocols.

  • _migrate_schema() hook re-enabled in BasePersistentCache.load() (P12): Schema version mismatches now attempt migration via _migrate_schema() before falling back to VERSION_MISMATCH. Default raises NotImplementedError so existing behaviour is preserved.

Documentation

  • Device class section comments (P8): Added 7 section markers (# -- 1. Metadata & Identity -- through # -- 7. Week Profile --) to organize the Device class body.

  • DataPoint hierarchy diagram (P9): Added class hierarchy documentation to data_point.py showing the 5-level parameter-backed chain and 2-level calculated chain.

  • Cache concurrency model (P10): Added Concurrency section to CentralDataCache, CommandTracker, PingPongTracker, and DeviceDetailsCache documenting the single-event-loop assumption and PEP 703 implications.

  • Lazy cache expiration (P11): Documented the intentional lazy expiration strategy and _is_initializing lifecycle in CentralDataCache.

  • Protocol selection guide (docs/architecture/protocol_selection_guide.md): Decision tree for choosing among 115 protocol interfaces by use case, with guidance on naming conventions and interface segregation principles.

Testing

  • Benchmark test suite (tests/benchmarks/): Performance baseline tests for CentralDataCache, CircuitBreaker, EventBus, and RequestCoalescer.

  • Error-path test suite (tests/test_error_paths.py, ~585 LOC): Comprehensive resilience tests covering RequestCoalescer burst scenarios, circuit breaker integration, cache expiration edge cases, and shutdown cleanup.


Version 2026.2.7 (2026-02-09)

What's Changed

Added

  • Paramset consistency checker: Automatically detects missing parameters on HmIP/HmIPW devices after firmware updates. The HmIPServer (crRFD) on the CCU sometimes fails to refresh its stored parameter data after a firmware update, creating a mismatch between getParamsetDescription() (schema) and getParamset() (actual values). The checker runs as a background task after device creation and reports inconsistencies via:
  • Home Assistant Repairs (as IntegrationIssue with type PARAMSET_INCONSISTENCY)
  • Log warnings with affected device addresses and missing parameters
  • Diagnostics data (via IncidentStore) A factory reset of the affected device on the CCU resolves the issue. See troubleshooting documentation and ADR-0023 for details. Based on Homematic forum discussion.

Changed

  • Rename _temporary_value to _unconfirmed_value: All internal references to _temporary_value, _temporary_refreshed_at, _temporary_modified_at, write_temporary_value, _reset_temporary_value, and related methods have been renamed to _unconfirmed_* / write_unconfirmed_value / _reset_unconfirmed_value. This clarifies the role of the second value tier in the three-tier resolution model (optimistic → unconfirmed → confirmed). Affected files: data_point.py, hub/data_point.py, interface_client.py, interfaces/model.py.

Fixed

  • XML-RPC server race condition on multi-hub startup: Fixed a race condition in AsyncXmlRpcServer.start() that caused "address in use" errors when multiple central units (e.g., two OpenCCU instances) started concurrently. The singleton server is now protected by an asyncio.Lock to ensure only one coroutine can bind to the port at a time. Also added proper cleanup of partial state if binding fails.

  • Optimistic rollback now clears unconfirmed value: _rollback_optimistic_value() now calls _reset_unconfirmed_value() before restoring the previous confirmed value. Previously, the unconfirmed value survived the rollback and would override the restored value through the timestamp comparison in _value, undermining the rollback entirely.

Documentation

  • Three-tier value resolution architecture doc: New docs/architecture/value_resolution.md describing the full value resolution mechanism (optimistic → unconfirmed → confirmed), including timing, scope, interaction between tiers, rollback behaviour, and the hub sysvar variant.

  • Updated ADR 0020: Added unconfirmed value tier to the value resolution description and documented that rollback clears the unconfirmed value.


Version 2026.2.6 (2026-02-06)

What's Changed

Added

  • WeekProfileDataPoint: Added device-level data points that serve as the central interface for schedule data — both for climate and non-climate devices. One data point per device exposes schedule metadata, target channel mappings, and delegates read/write operations to the underlying WeekProfile.

New classes and types:

  • WeekProfileDataPoint / ClimateWeekProfileDataPoint in aiohomematic.model.week_profile_data_point
  • WeekProfileDataPointProtocol / ClimateWeekProfileDataPointProtocol in aiohomematic.interfaces
  • ScheduleType StrEnum in aiohomematic.const (CLIMATE, DEFAULT)
  • TargetChannelInfo dataclass in aiohomematic.model.schedule_models

New device properties:

  • device.week_profile_data_point: Access the data point (or None)
  • device.channel_groups: Channel group configurations keyed by group number

Data point properties:

  • schedule_type: Returns ScheduleType.CLIMATE or ScheduleType.DEFAULT
  • schedule: Cached schedule as ScheduleDict
  • available_target_channels: Human-readable target channel mapping (non-climate only)
  • min_temp / max_temp: Temperature bounds (climate only)
  • value: Number of active schedule entries (state property)

Schedule operations (both types):

  • get_schedule(), set_schedule(), reload_schedule(), fire_schedule_updated()

Climate-specific operations (ClimateWeekProfileDataPoint):

  • get_schedule_profile(), set_schedule_profile()
  • get_schedule_weekday(), set_schedule_weekday()
  • copy_schedule(), copy_schedule_profile()
  • available_profiles, schedule_profile_nos

  • Automatic profile sync from device: ClimateWeekProfileDataPoint now binds the device's ACTIVE_PROFILE (IP) or WEEK_PROGRAM_POINTER (RF) generic data point. current_schedule_profile updates automatically when the thermostat switches profiles.

  • Climate CDP notification on schedule change: When schedule data changes (e.g., after CONFIG_PENDING=False reload), the linked Climate CDP is automatically notified via an internal subscription, causing the HA Climate Entity to update.

  • device_active_profile_index property: Returns the 1-based profile index from the device parameter (int | None). RF values are normalised from 0-based to 1-based.

Changed

  • Schedule access removed from climate CDPs (breaking change): All schedule methods and properties removed from BaseCustomDpClimate. Schedule operations are now exclusively available via device.week_profile_data_point. Removed: available_schedule_profiles, schedule, get_schedule(), set_schedule(), get_schedule_profile(), set_schedule_profile(), get_schedule_weekday(), set_schedule_weekday(), copy_schedule(), copy_schedule_profile().

  • Schedule access removed from non-climate CDPs: has_schedule, schedule, get_schedule(), and set_schedule() removed from CustomDataPoint base class and CustomDataPointProtocol.

  • Climate profile property renames (breaking change): On ClimateWeekProfileDataPointProtocol, active_profilecurrent_schedule_profile, active_schedulecurrent_profile_schedule, set_active_profile()set_current_schedule_profile(). This avoids a naming conflict with the device parameter ACTIVE_PROFILE. copy_schedule and copy_schedule_profile parameter renamed from target_climate_data_point to target_data_point.

  • Copy method refactoring: ClimateWeekProfile.copy_schedule renamed to copy_schedule_to and copy_profile renamed to copy_profile_to. Both now accept target_week_profile: ClimateWeekProfile instead of target_climate_data_point: BaseCustomDpClimate.

  • HA-Addon renamed to HA-App (breaking change): SystemInformation.is_ha_addon renamed to is_ha_app. The rega script get_backend_info.fn now returns is_ha_app instead of is_ha_addon in the JSON response.

Fixed

  • CommandThrottle busy-wait replaced with asyncio.Event: The background worker in CommandThrottle no longer polls with asyncio.sleep(0.1) (ASYNC110 violation). Uses asyncio.Event for efficient wake-on-enqueue, reducing idle CPU usage and improving command latency.

  • CallbackDataPoint ownership reset on unsubscribe: When the owning custom_id fully unsubscribes from a data point, _custom_id is now reset to None. This allows re-registration with a different custom_id (e.g. after an entity_id rename in Home Assistant), preventing AioHomematicException on resubscription.

Refactoring

  • DelegatedProperty expansion: Replaced 56 boilerplate @property methods with DelegatedProperty descriptors across 23 files (central, client, model, store layers). This reduces repetitive delegation code while preserving the same runtime behavior. Properties that are overridden in subclasses (category, state_uncertain) remain as @property methods.

Version 2026.2.5 (2026-02-05)

What's Changed

Fixed

  • i18n format specs: Fixed i18n.tr() silently dropping format specifiers like {interval:.3f} because all kwargs values were converted to str before format_map(). Float format specs require the original type. Placeholders with format specs now render correctly in log messages.

  • Optimistic mismatch false positives: Fixed false OPTIMISTIC_MISMATCH warnings when the CCU rounds float values (e.g., optimistic 0.3803… vs CCU-confirmed 0.38). Float values are now rounded to 2 decimal places before comparison.

  • Optimistic burst false rollbacks: Fixed false OptimisticRollbackEvent and logbook entries during rapid command bursts (e.g., dimming a light through multiple values). Intermediate CCU confirmations are now silently accepted; mismatch is only evaluated on the final confirmation when all pending sends have been acknowledged.

  • Optimistic mismatch no longer fires rollback events: VALUE_MISMATCH no longer publishes OptimisticRollbackEvent. When the CCU confirms a different value (e.g., clamping to minimum dimming level), the CCU value is silently accepted as authoritative. Rollback events are now only published for actual rollbacks (TIMEOUT, SEND_ERROR). This eliminates noisy logbook entries during normal CCU value corrections.


Version 2026.2.4 (2026-02-05)

What's Changed

Added

  • Optimistic updates: Added optimistic state updates for data points to provide instant UI feedback before CCU confirmation. Data points immediately update their state when send_value() is called, then rollback if the CCU rejects the value or times out. Configure rollback timeout via TimeoutConfig.optimistic_update_timeout (default: 30.0s).

New event: OptimisticRollbackEvent in aiohomematic.central.events

New properties on data points:

  • is_optimistic: Check if data point has pending optimistic value
  • optimistic_age: Get age of optimistic value in seconds

  • Command priority queue: Added three-tier priority system for command throttling to ensure security-critical commands bypass queues while bulk operations are deprioritized:

  • CRITICAL (priority 0): Security and access control commands (locks, sirens, alarms) bypass throttle entirely

  • HIGH (priority 1): Interactive user commands use normal throttle with high queue priority
  • LOW (priority 2): Burst detection automatically downgrades commands when burst thresholds are exceeded

New enum: CommandPriority in aiohomematic.client

CRITICAL priority is declared at the service-method level via @bind_collector(priority=CommandPriority.CRITICAL) on lock and siren service methods.

  • Command throttle: Added configurable per-interface rate limiting for outgoing device commands (set_value, put_paramset). The throttle enforces a minimum delay between consecutive commands on the same RF interface to ensure smooth operation and prevent packet loss during bulk operations. Configure via TimeoutConfig.command_throttle_interval (default: 0.0 = disabled).

New class: CommandThrottle in aiohomematic.client

  • CRITICAL queue purge: When a CRITICAL command arrives (e.g., cover STOP, lock, siren), all pending queued commands for the same channel group are automatically purged from the throttle queue. This prevents queued movement commands from restarting a cover after STOP. Purged commands are cancelled with CommandSupersededError and return an empty result to callers. Channel group scope is respected — STOP on group 1 does not affect group 2 on the same device.

New exception: CommandSupersededError in aiohomematic.exceptions

New method: CustomDataPoint.get_channel_group_addresses() — returns all channel addresses in the data point's channel group

New parameter: purge_addresses on set_value(), put_paramset(), and CommandThrottle.acquire()

Removed

  • CRITICAL_PRIORITY_PARAMETERS: Removed the frozenset from aiohomematic.const. CRITICAL priority is now declared exclusively via @bind_collector(priority=CommandPriority.CRITICAL) on service methods. The parameter-set-based detection was redundant since all lock/siren commands flow through decorated service methods.

  • Bulk operation context: Removed _is_bulk_operation_context() from BaseParameterDataPoint. The RequestContext bulk operation flag was never used by the HA integration, making it dead code. The command throttle's built-in burst detection provides automatic LOW priority downgrade without requiring explicit context flags.

Improved

  • Internationalization: Added German and English translations for 8 new log messages in command throttle and optimistic updates subsystems
  • Type safety: Fixed multiple mypy strict mode violations including Future/Task type parameters, call_later signatures, and protocol definitions
  • Code quality: Removed lazy imports in production code, fixed import violations in test files to use public API

Fixed

  • Syntax error: Fixed unterminated triple-quoted string in interfaces/central.py that prevented module compilation
  • Type annotations: Fixed missing config property in CentralInfoProtocol and ConfigProviderProtocol
  • Cover target levels: Fixed _target_level and _target_tilt_level properties to check for None before calling float(), preventing type errors
  • Event bus access: Fixed optimistic rollback event publishing to use _event_bus_provider.event_bus instead of non-existent _event_bus attribute
  • Optimistic updates in collector path: Fixed optimistic values interfering with is_state_change() checks in parent service methods. When using CallParameterCollector, optimistic values are now deferred until send_data() instead of being applied immediately in send_value(), preventing sibling data point reads from returning premature values

Version 2026.2.3 (2026-02-03)

What's Changed

Added

  • Domain-specific schedule validation: Added validation for schedule data based on device category (SWITCH, LIGHT, COVER, VALVE). The validation enforces that only appropriate fields are used for each device type:

  • SWITCH: Level must be binary (0.0 or 1.0), level_2 and ramp_time are forbidden

  • LIGHT: level_2 (slat position) is forbidden
  • COVER: ramp_time and duration are forbidden
  • VALVE: level_2 and ramp_time are forbidden

The validation is backward-compatible: when no domain context is provided (e.g., direct SimpleSchedule.model_validate() calls), all fields are accepted. Domain-specific validation is automatically applied when using DefaultWeekProfile.set_schedule().

New exports from schedule_models.py:

  • SCHEDULE_DOMAIN_CONTEXT_KEY: Context key for passing domain to Pydantic validators
  • SCHEDULE_DOMAINS: frozenset of categories that support schedules

Version 2026.2.2 (2026-02-03)

What's Changed

Fixed

  • JSON control character sanitization: Fixed JSONDecodeError when ReGa scripts (e.g., fetch_all_device_data.fn) return JSON containing unescaped control characters in device names or values. The _sanitize_json_control_chars function is now applied consistently to all JSON parsing from CCU responses, including script results in _post_script and nested JSON in _get_serial. The sanitization is now selective - it only escapes control characters within JSON string values, preserving structural whitespace (newlines between JSON objects, etc.) to avoid "unexpected content after document" errors.
  • CustomDataPoint schedule conversion: Fixed get_schedule() and set_schedule() methods in CustomDataPoint to correctly convert between ScheduleDict (string keys, dict values) and SimpleSchedule Pydantic model (integer keys, Pydantic values). The methods now:
  • Accept both ScheduleDict and SimpleSchedule as input to set_schedule()
  • Properly delegate to week_profile.get_schedule() to ensure ValidationException is raised for unsupported devices
  • Convert between formats correctly in both directions

Documentation

  • Week profile: Added comprehensive documentation for SimpleScheduleEntry fields in week_profile.md, including:
  • Complete field reference with types, ranges, and validation rules
  • Device-type-specific meanings for level field (switch, light, cover, valve)
  • Condition types (fixed_time, astro, fixed_if_before_astro, fixed_if_after_astro)
  • Duration and ramp_time format examples
  • Field summary table and complete usage examples
  • Week profile module docstring: Updated to reflect API changes from version 2026.2.1 (removed "simple" prefix from method names)

Version 2026.2.1 (2026-02-02)

What's Changed

Fixed

  • LINK paramset validation: Fixed put_paramset with check_against_pd=True for LINK paramsets. LINK paramsets are not cached during device initialization (by design), so validation is now automatically skipped for LINK calls to prevent "Parameter not found" errors. Fixes #2903.
  • ClimateWeekProfile type signature: Fixed incorrect type annotation in convert_dict_to_raw_schedule() - removed ClimateSchedule from union type since the method only accepts _ClimateScheduleDictInternal (13-slot format). The Pydantic model ClimateSchedule uses a different structure (simple format with base_temperature and periods).
  • Schedule Pydantic models JSON serialization: Added _JsonSerializableMixin to all schedule Pydantic models (ClimateSchedule, ClimateProfileSchedule, ClimateWeekdaySchedule, ClimateSchedulePeriod, SimpleSchedule, SimpleScheduleEntry) to support orjson/Home Assistant JSON serialization via __json__() method.

Breaking Changes

  • Climate schedule API unified to Pydantic models only: The old dual-format API (TypedDict + Pydantic) has been removed. All schedule methods now use Pydantic models exclusively.

Renamed methods in BaseCustomDpClimate:

  • simple_schedule property → schedule
  • get_schedule_simple_profile() → removed (use get_schedule_profile())
  • get_schedule_simple_schedule()get_schedule()
  • get_schedule_simple_weekday()get_schedule_weekday()
  • set_simple_schedule()set_schedule()
  • set_simple_schedule_profile()set_schedule_profile()
  • set_simple_schedule_weekday()set_schedule_weekday()

Removed types from const.py:

  • ScheduleSlotType enum
  • ScheduleSlot TypedDict
  • ClimateWeekdaySchedule type alias (now Pydantic model in schedule_models)
  • ClimateProfileSchedule type alias (now Pydantic model in schedule_models)
  • ClimateScheduleDict type alias (now ClimateSchedule Pydantic model)
  • CLIMATE_MAX_SCHEDULER_TIME, CLIMATE_MIN_SCHEDULER_TIME, CLIMATE_RELEVANT_SLOT_TYPES
  • CLIMATE_SCHEDULE_SLOT_IN_RANGE, CLIMATE_SCHEDULE_SLOT_RANGE, CLIMATE_SCHEDULE_TIME_RANGE

Migration: Replace old TypedDict imports with Pydantic models from aiohomematic.model.schedule_models.

Changed

  • ClimateWeekProfile: Simple schedule format now uses Pydantic models for automatic validation. The existing user-facing format remains unchanged (no breaking changes), but input validation is now more robust with clear error messages.
  • DefaultWeekProfile: Refactored schedule cache to use human-readable Pydantic models (SimpleSchedule, SimpleScheduleEntry) instead of complex dictionary format. The new format provides automatic validation, clear field names (e.g., weekdays, time, level, duration), and better developer experience.

Added

  • schedule_models: New Pydantic models for climate device schedules:
  • ClimateSchedulePeriod: Validates temperature periods with starttime, endtime, temperature
  • ClimateWeekdaySchedule: Validates daily schedules with base_temperature and periods
  • ClimateProfileSchedule: Validates weekly schedules (MONDAY-SUNDAY)
  • ClimateSchedule: Validates complete profiles (P1-P6)
  • schedule_models: Pydantic models for non-climate device schedules:
  • SimpleScheduleEntry: Validated schedule entry with weekdays, time, condition, target_channels, level, duration, ramp_time
  • SimpleSchedule: Container for multiple schedule entries keyed by group number (1-24)

Validation Improvements

Climate simple schedule validation now checks:

  • Time format (HH:MM, supports 24:00 for end-of-day)
  • Required fields (starttime, endtime, temperature)
  • Time sequence (start < end)
  • No overlapping periods
  • Valid weekdays (MONDAY-SUNDAY)
  • Valid profiles (P1-P6)

Technical

  • week_profile.py: Simplified implementation by using Pydantic models directly instead of manual conversion functions (~2300 lines removed)
  • Added Pydantic mypy plugin to pyproject.toml for improved type inference
  • Updated WeekProfileProtocol to accept any schedule type (removed dict[Any, Any] constraint)
  • Updated type annotations in Device, DeviceWeekProfileProtocol, and BaseCustomDataPoint
  • Added i18n keys for better error messages: exception.model.schedule.invalid_weekday, exception.model.schedule.invalid_profile

Version 2026.2.0 (2026-02-01)

What's Changed

Fixed

  • EventBus: Fix subscription leak for DeviceLifecycleEvent when stopping CentralUnit. The event type was missing from clear_external_subscriptions(), causing "LEAKED_SUBSCRIPTION" warnings during shutdown.

  • DeviceCoordinator: Fix devices not appearing after factory reset and re-pairing. When a device was reset and re-paired with the same address, channel descriptions (e.g., HEQ0128279:0, HEQ0128279:1) were not added to cache because only the parent device address was checked. Added _identify_missing_device_descriptions() to detect and cache missing channel descriptions.

Version 2026.1.57 (2026-01-31)

What's Changed

Added

  • JsonCcuBackend: Implemented get_device_details() method via JSON-RPC Device.listAllDetail. This enables proper device name and interface registration for CUxD/CCU-Jack backends, matching the functionality of CcuBackend.

Fixed

  • CUxD/CCU-Jack: Fix interface registration for CUxD/CCU-Jack devices. Devices were incorrectly assigned Interface.BIDCOS_RF (default) because JsonCcuBackend.get_device_details() returned None, causing get_data_points(interface=Interface.CUXD) to filter out all CUxD devices. Interface is now registered during _add_new_devices() when device descriptions are cached.

  • InterfaceClient: Fix fetch_device_details() to use interface from device data instead of client's interface. The legacy client used Interface(device["interface"]) but the new implementation incorrectly used self.interface, which would register all devices with the calling client's interface when Device.listAllDetail returns devices from multiple interfaces.

Version 2026.1.56 (2026-01-31)

What's Changed

Fixed

  • CUxD/CCU-Jack: Fix data not updating after startup for polled interfaces. The refresh_data_point_data() method was using hardcoded CallSource.HM_INIT which caused data points with ignore_on_initial_load to be skipped during periodic polling. Changed default to CallSource.MANUAL_OR_SCHEDULED so polling works correctly while preserving initialization behavior.

Version 2026.1.55 (2026-01-30)

What's Changed

Added

  • Documentation: Added comparison table of Homematic integrations in FAQ (Homematic, HomematicIP Cloud, Homematic(IP) Local)
  • Documentation: Added raw schedule operations documentation (get_schedule_profile, get_schedule_weekday, set_schedule_profile, set_schedule_weekday)
  • Documentation: Added comprehensive send_text_display action documentation with all parameters (icon, colors, alignment, sound, etc.)
  • Documentation: Added instructions for accessing optional settings in Home Assistant

Test Infrastructure

  • OpenCCU: Added comprehensive test fixtures for VirtualCCU with BackendMode.OPENCCU support
  • OpenCCU: Added pydevccu_openccu session-scoped fixture running JSON-RPC server in separate thread
  • OpenCCU: Added central_unit_openccu fixture with proper device lifecycle event handling
  • OpenCCU: Added test_backend_openccu.py with backend detection, programs, sysvars, rooms/functions, and backup tests
  • OpenCCU: Added test_central_pydev_openccu.py with full 397-device central unit tests

Fixed

  • OperatingVoltageLevel: Use user-configured LOW_BAT_LIMIT value instead of default for battery percentage calculation. This fixes incorrect battery readings when users have customized the low battery threshold (regression from #2281)
  • OperatingVoltageLevel: Return None instead of clamped value when voltage_max <= low_bat_limit (invalid configuration)
  • OperatingVoltageLevel: Ensure calculate_operating_voltage_level always returns float (0.0/100.0) instead of int (0/100)
  • Documentation: Corrected client architecture references across all docs - replaced non-existent ClientCCU/ClientJsonCCU/ClientHomegear classes with correct InterfaceClient + Backend Strategy pattern (CcuBackend, JsonCcuBackend, HomegearBackend)
  • Documentation: Fixed HeartbeatTimerFiredEvent key from interface_id to central_name in event reference
  • Documentation: Added missing RecoveryAttemptedEvent field documentation (max_attempts, stage_reached, success, error_message)
  • Documentation: Removed references to non-existent USE_INTERFACE_CLIENT feature flag in ADR 0013
  • Documentation: Fixed outdated file paths in CLAUDE.md (docstring docs moved to docs/contributor/coding/)
  • Documentation: Updated sequence diagram participant names to InterfaceClient
  • Documentation: Replaced non-existent Handler class hierarchy with correct Backend Strategy architecture in sequence diagrams
  • Documentation: Fixed action name typo homeassistant.update_device_firmware_datahomematicip_local.update_device_firmware_data
  • Documentation: Fixed copy_schedule and copy_schedule_profile examples (corrected source/target entity usage)
  • Documentation: Fixed broken links in troubleshooting docs (now point to Actions Reference)
  • Documentation: Fixed GitHub issues URL in optional settings

Version 2026.1.54 (2026-01-29)

What's Changed

Changed

  • Logging: Reduced log level for data point validation messages from WARNING to DEBUG (value range min/max, enum index/value validation)

Fixed

  • Documentation: Fixed MkDocs abbreviations format (*[...] instead of _[...])
  • Documentation: Added .prettierignore to prevent prettier from breaking abbreviations syntax

Removed

  • Documentation: Removed migration guides (obsolete after refactoring completion)
  • Documentation: Removed community templates page

Version 2026.1.53 (2026-01-29)

What's Changed

Added

  • Device Support: Added HmIP-WRC6-230 (Wall-mount Remote Control 6-button 230V) as fixed color light

  • MkDocs Documentation: Replaced Sphinx with MkDocs Material theme for GitHub Pages documentation

  • Added mkdocs.yml with full Material theme configuration

  • Added GitHub Actions workflow (.github/workflows/docs.yml) for automatic deployment on push to devel/master
  • Added custom styling (docs/stylesheets/extra.css) for tables, code blocks, and ADR formatting
  • Added abbreviation tooltips (docs/includes/abbreviations.md) for common terms (CCU, HmIP, RF, etc.)
  • Documentation available at https://sukramj.github.io/aiohomematic/

  • Home Assistant Integration Documentation: Added comprehensive user guide for the Homematic(IP) Local integration

  • docs/user/homeassistant_integration.md - Complete integration guide

  • docs/user/features/homeassistant_actions.md - Full actions reference with examples
  • docs/user/features/week_profile.md - Week profile/schedule management
  • docs/user/troubleshooting/troubleshooting_flowchart.md - Visual diagnosis flowcharts
  • docs/user/advanced/cuxd_ccu_jack.md - CUxD and CCU-Jack setup guide
  • docs/user/device_support.md - Device support overview

  • Developer Documentation

  • docs/developer/error_handling.md - Exception hierarchy and circuit breaker
  • docs/architecture/caching.md - Cache architecture documentation
  • docs/contributor/release_process.md - Release workflow

Changed

  • Documentation Structure: Reorganized docs/ directory for better navigation

  • docs/user/ - User documentation (features/, troubleshooting/, advanced/)

  • docs/developer/ - Library consumer documentation
  • docs/contributor/ - Code contribution documentation (coding/, testing/)
  • docs/architecture/ - Technical deep-dives (events/)
  • docs/reference/ - Reference material (glossary, common operations)

  • README.md: Simplified with links to GitHub Pages documentation

  • Unignore Documentation: Revised to UI-only configuration (no file-based config)
  • Pre-commit Config: Updated codespell excludes for new doc paths
  • GitHub Issue Templates: Updated all documentation links to use GitHub Pages URLs
  • GitHub Workflows: Updated close-insufficient-info workflow with GitHub Pages links
  • Abbreviations: Fixed format from _[...] to *[...] for proper MkDocs rendering

Removed

  • Sphinx Documentation: Removed unused Sphinx configuration and files

  • Removed docs/conf.py, docs/index.rst, docs/Makefile, docs/__init__.py

  • Removed docs/api/*.rst (5 files), docs/user/*.rst (4 files), docs/dev/*.rst (3 files)
  • Simplified requirements_docs.txt to MkDocs dependencies only

  • Device-Specific Documentation: Removed obsolete pages (replaced by derived binary sensors)

  • Removed docs/user/devices/ (hmip_srh_window_handle.md, hmip_swsd_smoke_detector.md)
  • Removed docs/user/ccu_scripts/ (rename_sysvar_marker.md)

Version 2026.1.52 (2026-01-28)

What's Changed

Added

  • Derived Binary Sensors: Implemented registry-based system for creating binary sensors derived from enum data points (ADR 0019)
  • Added DerivedBinarySensor calculated data point class
  • Added DerivedBinarySensorRegistry for declarative mapping definitions
  • Added DerivedBinarySensorMapping dataclass for mapping rules
  • New calculated parameters: INTRUSION_ALARM, SMOKE_ALARM, WINDOW_OPEN
  • Automatic creation of derived binary sensors during device initialization
  • HmIP-SRH, HM-Sec-RHS: Window handle sensor now provides additional WINDOW_OPEN binary sensor (ON when TILTED or OPEN)
  • HmIP-SWSD: Smoke detector now provides additional INTRUSION_ALARM and SMOKE_ALARM binary sensors (ON when alarm active)

Improvements

  • Enhanced Data Point Validity: Implemented comprehensive validation for data points including type checking, range validation, and proper None handling
  • Automatic STATUS Parameter Updates: STATUS parameters (e.g., LEVEL_STATUS) now automatically update the main parameter's validity state
  • Type-Specific Validation: Each parameter type (FLOAT, INTEGER, BOOL, ENUM, etc.) now has appropriate validation rules
  • None Value Semantics: Clarified when None is a valid value (ACTION types, optional parameters) vs invalid (numeric sensors)

Technical Details

  • Added has_valid_value_type and is_value_in_range properties to BaseParameterDataPoint
  • STATUS parameter events are now automatically subscribed and processed
  • Warning logs for out-of-range values received from CCU
  • Added _OPTIONAL_PARAMETERS frozenset (19 parameters) using Parameter enum values - excludes ACTION type parameters which are handled automatically
  • Added missing Parameter enum values: INHIBIT, INSTALL_TEST, ON_TIME_UNIT, ON_TIME_VALUE, PARTY_START_DAY, PARTY_START_TIME, PARTY_STOP_DAY, PARTY_STOP_TIME, PARTY_TEMPERATURE
  • Optional parameters include: color controls (COLOR, HUE, SATURATION, COLOR*TEMPERATURE, EFFECT), timing unit selectors (ON_TIME_UNIT, RAMP_TIME_UNIT, RAMP_TIME_TO_OFF_UNIT, DURATION_UNIT), party mode (PARTY**), and special features (LEVEL_2, INHIBIT, INSTALL_TEST)
  • Note: ACTION type parameters (*_VALUE like ON_TIME_VALUE, RAMP_TIME_VALUE) are automatically allowed to be None and don't need explicit listing

Version 2026.1.51 (2026-01-27)

What's Changed

Added

  • CUxD/CCU-Jack regression prevention contract tests: Added dedicated test_cuxd_ccu_jack_contract.py with 20 tests specifically designed to prevent regressions that have occurred during AI-assisted refactoring. Tests cover:

  • Interface classification (JSON-RPC vs XML-RPC constants)

  • Backend factory behavior (JsonCcuBackend creation)
  • Capability flags (ping_pong=False, rpc_callback=False)
  • Port configuration (HTTP 80 / HTTPS 443)
  • Enum value stability
  • Backend behavior (init_proxy/deinit_proxy are no-ops)

  • Comprehensive contract tests for stability guarantees: Added contract tests that define the stable API contract for aiohomematic. These tests ensure that changes to core infrastructure require explicit consideration and MAJOR version bumps:

  • test_capability_contract.py: Backend capabilities (CUxD, CCU-Jack, CCU, Homegear)

  • test_client_state_machine_contract.py: Client state machine transitions and properties
  • test_central_state_machine_contract.py: Central state machine transitions and properties
  • test_connection_recovery_contract.py: Connection recovery behavior (exponential backoff, max attempts, stage progression)
  • test_event_system_contract.py: Event types, required fields, and immutability
  • test_client_lifecycle_contract.py: Client lifecycle methods (init, deinit, reconnect, stop)
  • test_enum_constants_contract.py: Enum value stability (Interface, Backend, DataPointCategory, DeviceProfile, ParamsetKey, etc.)
  • test_configuration_contract.py: Configuration class stability (CentralConfig, InterfaceConfig, TimeoutConfig)
  • test_exception_hierarchy_contract.py: Exception hierarchy (BaseHomematicException and subclasses)
  • test_protocol_interfaces_contract.py: Protocol interface definitions (runtime checkable, required members)
  • test_hub_entities_contract.py: Hub entity classes (Program, Sysvar, Metrics, Inbox, Update)
  • test_subscription_api_contract.py: EventBus subscription API stability
  • test_backend_week_profile_contract.py: BackendOperationsProtocol (47 tests) and WeekProfileProtocol (7 tests) API stability
  • test_client_protocol_contract.py: ClientProtocol and all 18 sub-protocols (124 tests covering identity, connection, lifecycle, operations, and method signatures)
  • test_device_channel_protocol_contract.py: DeviceProtocol, ChannelProtocol and all sub-protocols (273 tests covering identity, channel access, state, operations, configuration, and providers)

  • @unique decorator for all Enums: Added @unique decorator to 70+ enum classes across 15+ files to prevent accidental duplicate enum values. Affected modules include const.py, climate.py, cover.py, light.py, lock.py, siren.py, mixins.py, events/types.py, events/integration.py, json_rpc.py, rpc_proxy.py, metrics/events.py, store/types.py, and property_decorators.py

Changed

  • TimeoutConfig converted to Pydantic: TimeoutConfig is now a Pydantic BaseModel with frozen=True for immutability. The API remains fully compatible with the previous NamedTuple implementation.

  • InterfaceConfig converted to Pydantic with CUxD validation: InterfaceConfig is now a Pydantic BaseModel with proper validation:

  • For standard interfaces (HmIP-RF, BidCos-RF, etc.): port must be > 0

  • For CUxD/CCU-Jack: port is automatically set to None (ignored, JSON-RPC uses HTTP/HTTPS)
  • interface_id and rpc_server are computed fields

  • CentralConfig converted to Pydantic: CentralConfig is now a Pydantic BaseModel with:

  • Automatic collection normalization (set/tuple → frozenset)

  • Computed private attributes for derived values (requires_xml_rpc_server, session_recorder_*)
  • Factory methods (for_ccu, for_homegear) preserved
  • All 30+ configuration fields with proper type hints and defaults

  • DeviceConfig/ExtendedDeviceConfig converted to Pydantic: DeviceConfig and ExtendedDeviceConfig in model/custom/registry.py are now Pydantic BaseModel classes with frozen=True for immutability

  • ProfileConfig classes converted to Pydantic: ChannelGroupConfig, ProfileConfig, and RebasedChannelGroupConfig in model/custom/profile.py are now Pydantic BaseModel classes with frozen=True

  • BackendCapabilities converted to Pydantic: BackendCapabilities in client/backends/capabilities.py is now a Pydantic BaseModel with frozen=True. Backend implementations now use model_copy(update={...}) instead of dataclasses.replace()

  • @override decorators added: Added @override decorator from typing module to explicitly mark overridden methods across the codebase for improved code clarity and type checking

  • Final annotations for constants: Added Final type annotations to key constants for improved type safety

Documentation

  • CLAUDE.md: CUxD/CCU-Jack special handling section: Added prominent "⚠️ CRITICAL: CUxD/CCU-Jack Special Handling" section at the top of CLAUDE.md to prevent AI-assisted refactoring regressions. Includes:
  • Comparison table (XML-RPC vs JSON-RPC differences)
  • Key constants to check before refactoring
  • Common regression patterns with ❌ WRONG / ✅ CORRECT examples
  • Refactoring checklist with pytest commands

See ADR-0018 for architectural context.

Fixed

  • Client reconnect now works from INITIALIZED state: Fixed an issue where clients stuck in INITIALIZED state (e.g., after a failed startup due to JSON parsing errors) couldn't be reconnected. The state machine didn't allow RECONNECTING as a valid transition from INITIALIZED. The fix transitions to DISCONNECTED first (which is the documented recovery path), then proceeds with reconnection. This enables automatic recovery when the initial connection was never established.

  • JSON parsing now handles unescaped control characters: Fixed JSONDecodeError: unexpected control character in string errors that occurred when device names or descriptions on the CCU contained unescaped control characters (newline, tab, carriage return, etc.). The Device.listAllDetail JSON-RPC response is now sanitized by escaping control characters (U+0000 to U+001F) to proper \uXXXX sequences before parsing. This allows the central unit to start successfully even when the CCU returns malformed JSON.


Version 2026.1.50 (2026-01-25)

What's Changed

Changed

  • Clean port handling for JSON-RPC-only interfaces: Refactored InterfaceConfig.port from int to int | None. XML-RPC interfaces (HmIP-RF, BidCos-RF, BidCos-Wired, VirtualDevices) require a valid port > 0, while JSON-RPC-only interfaces (CUxD, CCU-Jack) now correctly use None instead of the previous workaround value 0. This provides cleaner semantics and proper validation:
  • InterfaceConfig now enforces port validation based on interface type
  • CentralConfigBuilder.add_cuxd_interface() no longer passes port=0
  • TCP pre-flight checks correctly skip interfaces with port=None
  • Connection recovery checks simplified from port is None or port == 0 to port is None

Version 2026.1.49 (2026-01-25)

What's Changed

Fixed

  • Hub data not refreshed after connection recovery: Fixed an issue where hub data (System Update, Programs, Sysvars) was not refreshed after a successful reconnect. This caused the System Update DataPoint in Home Assistant to show stale information (e.g., "Update available" even after the CCU had completed the firmware update during the disconnect). The ConnectionRecoveryCoordinator now accepts a hub_data_fetcher parameter and calls fetch_system_update_data(), fetch_program_data(), and fetch_sysvar_data() after successful data load. This ensures that hub state is synchronized immediately after recovery instead of waiting up to 4 hours for the next scheduled refresh.

  • Recovery fails for individual clients when others exist: Fixed an issue where recovery for CUxD or CCU-Jack clients would fail with "Clients bereits erstellt" when other clients (HmIP-RF, BidCos-RF, etc.) were already created. The ConnectionRecoveryCoordinator._stage_reconnect() now calls _create_client(interface_config=...) directly for the specific failing interface instead of _create_clients() which requires no existing clients.

  • Client state machine blocks recovery from INITIALIZED state: Fixed an issue where clients stuck in INITIALIZED state (initialized but never connected) could not be recovered. The state machine now allows INITIALIZED → DISCONNECTED transitions, enabling deinit_proxy() to reset the client state for reconnection attempts. This was causing InvalidStateTransitionError: Invalid state transition from initialized to disconnected.

  • TCP check fails for JSON-RPC-only interfaces: Fixed an issue where CUxD and CCU-Jack client creation would always fail at startup because the TCP pre-flight check was attempted on port 0. These interfaces use JSON-RPC (via the central JSON port 443/80) and don't have individual XML-RPC ports. The TCP check is now skipped for interfaces with port=0.

Added

  • JSON-RPC port pre-flight check: Added a TCP pre-flight check for the JSON-RPC port (80/443) before creating any CCU clients. CCU uses JSON-RPC for hub operations (programs, sysvars, system updates, etc.) in addition to XML-RPC for device communication. This check happens once at startup and ensures the JSON-RPC service is available before attempting to create clients.

Version 2026.1.48 (2026-01-25)

What's Changed

Fixed

  • XML-RPC authentication headers not sent with TLS: Fixed a critical bug where HTTP Basic Authentication headers were not being sent when TLS was enabled. The custom timeout transport classes (_TimeoutTransport, _TimeoutSafeTransport) did not pass the headers parameter to the base class __init__(). When ServerProxy receives a pre-built transport, it does not add headers to it - headers must be passed directly to the transport constructor. This caused all XML-RPC calls to fail with ProtocolError: Unauthorized when CCU authentication was enabled. The fix passes the authentication headers directly to the transport classes.

Version 2026.1.47 (2026-01-25)

What's Changed

Fixed

  • Authentication check fails for non-admin users: Fixed a regression introduced in 2026.1.41 where users without ADMIN rights on the CCU would fail to connect via JSON-RPC. The _get_auth_enabled() method in json_rpc.py now catches AuthFailure exceptions in addition to InternalBackendException. When CCU.getAuthEnabled fails with "access denied (ADMIN needed 2)", this actually proves that authentication is enabled on the CCU (otherwise no permission check would occur). The method now correctly returns True in this case instead of propagating the exception.

Version 2026.1.46 (2026-01-24)

What's Changed

Added

  • HA-Addon detection: OpenCCU running as Home Assistant Add-on is now detected via HM_RUNNING_IN_HA or SUPERVISOR_TOKEN environment variables. The new is_ha_addon field in SystemInformation indicates whether the backend runs as an HA-Addon.

Changed

  • System update disabled for HA-Addons: The has_system_update property returns False for HA-Addons. The System Update entity is not created and the firmware_update_trigger capability is set to False, as updates are managed by the HA Supervisor.

Breaking Changes

  • System Update entity not created for HA-Addons: The System Update entity is no longer created when running as an HA-Addon. Existing orphaned entities can be manually deleted in Home Assistant.

Version 2026.1.45 (2026-01-23)

What's Changed

Added

  • Free-threaded Python 3.14t support: Added compatibility layer for Python 3.14 free-threaded builds (no GIL). The new compat module (aiohomematic/compat.py) provides:

  • is_free_threaded_build() and is_gil_enabled() detection functions

  • Conditional JSON backend: uses orjson on standard builds, falls back to stdlib json on free-threaded builds
  • dumps(), loads(), and JSONDecodeError with unified API across backends
  • Option flags (OPT_INDENT_2, OPT_NON_STR_KEYS, OPT_SORT_KEYS) compatible with both backends

  • CentralRegistry: New thread-safe registry (aiohomematic/central/registry.py) for CentralUnit instances using copy-on-read pattern. Safe for both GIL-enabled and free-threaded Python builds. Replaces the module-level CENTRAL_INSTANCES dict.

  • Python 3.14t in CI: Added free-threaded Python 3.14t to the test matrix in GitHub Actions workflow.

  • Package classifiers: Added new classifiers to pyproject.toml:

  • Programming Language :: Python :: Free Threading :: 2 - Beta

  • Natural Language :: English, Natural Language :: German
  • Environment :: No Input/Output (Daemon)
  • Topic :: Internet, Topic :: Software Development :: Libraries :: Python Modules

  • Tests: Added comprehensive test suites:

  • tests/test_compat.py: Tests for free-threading detection, JSON serialization, and round-trip behavior
  • tests/test_central_registry.py: Tests for CentralRegistry thread-safety and operations

Changed

  • orjson is now an optional dependency: orjson does not support free-threaded Python, so it has been moved to an optional extra. Install with pip install aiohomematic[fast] for faster JSON serialization on standard builds. The compat module automatically falls back to stdlib json when orjson is unavailable.

  • compat module functions use keyword-only arguments: dumps(*, obj, option) and loads(*, data) require keyword arguments for consistency with project coding standards.

  • Migrated JSON operations to compat module: All direct orjson usage replaced with compat.dumps() and compat.loads() in:

  • aiohomematic/central/rpc_server.py

  • aiohomematic/client/json_rpc.py
  • aiohomematic/model/device.py
  • aiohomematic/store/persistent/session.py
  • aiohomematic/store/storage.py
  • aiohomematic/support.py
  • aiohomematic/i18n.py

  • CENTRAL_INSTANCES replaced with CentralRegistry: The module-level CENTRAL_INSTANCES: dict[str, CentralUnit] has been replaced with a thread-safe CentralRegistry instance providing atomic operations.


Version 2026.1.44 (2026-01-22)

What's Changed

Added

  • SensorValueMixin: New mixin class in aiohomematic/model/mixins/sensor_value.py that consolidates duplicated value transformation logic between DpSensor (generic) and SysvarDpSensor (hub). Provides standardized handling for value list lookup, converter functions, and string length validation.

  • Priority 1 Unit Tests: Comprehensive unit tests for InterfaceClient, Coordinators, and Event System achieving 86%+ coverage:

  • test_central_event_types.py: Event type validation tests
  • test_central_event_bus.py: EventBus priority, batch publishing, and handler stats tests
  • test_interface_client_lifecycle.py: Client lifecycle and capability-gated operations tests
  • test_interface_client_backends.py: Backend-specific capability tests
  • test_central_client_coordinator.py: ClientCoordinator lifecycle and edge case tests
  • test_central_event_coordinator.py: Event routing tests

Fixed

  • Fixed test_package_init.py assertion to handle i18n fallback behavior when translation is not loaded during runpy.run_module context

Changed

  • Async RPC server is now the standard implementation: The async XML-RPC server (using aiohttp) is now the only RPC server implementation. The legacy thread-based XML-RPC server has been removed.
  • Removed OptionalSettings.ASYNC_RPC_SERVER feature flag (no longer needed)
  • Removed legacy thread-based XML-RPC server implementation
  • Removed RpcServerTaskSchedulerProtocol from aiohomematic/interfaces/central.py
  • Renamed async_rpc_server.py to rpc_server.py (consistent naming, no async_ prefix)
  • Updated CentralUnit to use the aiohttp-based server directly
  • InterfaceClient is now the only client implementation: The legacy client implementations (ClientCCU, ClientJsonCCU, ClientHomegear) and handler classes have been removed. InterfaceClient with the Backend Strategy Pattern is now the standard implementation.
  • Removed OptionalSettings.USE_INTERFACE_CLIENT feature flag (no longer needed)
  • Removed legacy client classes: ClientCCU, ClientJsonCCU, ClientHomegear
  • Removed handler classes: DeviceHandler, LinkHandler, FirmwareHandler, SystemVariableHandler, ProgramHandler, BackupHandler, MetadataHandler, BaseHandler
  • Removed aiohomematic/client/ccu.py and aiohomematic/client/handlers/ directory
  • Added aiohomematic/client/state_change.py for state change tracking utilities
  • Added aiohomematic/client/client_factory.py for ClientConfig class
  • ClientConfig is now imported from aiohomematic.client.client_factory instead of aiohomematic.client.ccu

Refactored

  • DeviceProfileRegistry data-driven registrations: Consolidated repetitive device registration calls into data-driven tuples with loops, reducing boilerplate code:
  • switch.py: 11 separate register() calls → single data tuple with loop (~56% reduction)
  • light.py: 17 RF/IP Dimmer registrations → two data tuples with loops (~43% reduction)

Removed

  • OptionalSettings.ASYNC_RPC_SERVER - async server is now the default
  • OptionalSettings.ENABLE_LINKED_ENTITY_CLIMATE_ACTIVITY - linked entity climate activity is now always enabled
  • Legacy thread-based XML-RPC server (replaced by aiohttp-based implementation)
  • RpcServerTaskSchedulerProtocol - only needed by removed sync server
  • tests/test_rpc_server_compatibility.py - compatibility tests no longer needed
  • OptionalSettings.USE_INTERFACE_CLIENT - InterfaceClient is now the default
  • Legacy client classes: ClientCCU, ClientJsonCCU, ClientHomegear
  • Handler classes in aiohomematic/client/handlers/
  • aiohomematic/client/ccu.py

Version 2026.1.43 (2026-01-21)

What's Changed

Added

  • Pydantic integration for RPC response validation: Introduced aiohomematic.schemas package with Pydantic models for validating and normalizing data from Homematic backends:
  • DeviceDescriptionModel: Validates device descriptions from listDevices(), newDevices() callbacks
  • ParameterDataModel: Validates parameter metadata from getParamsetDescription()
  • Normalization functions: normalize_device_description(), normalize_parameter_data(), normalize_paramset_description()
  • Validation occurs at all data ingestion points (RPC responses, cache loading)

Changed

  • Removed voluptuous dependency: Replaced voluptuous with Pydantic for data validation. The validator.py module now uses ValidationException instead of vol.Invalid. External consumers (e.g., Home Assistant integration) that used voluptuous-based validators (channel_no, wait_for, address, host) must implement their own validators.

Breaking Changes

  • Removed from aiohomematic.validator: channel_no, positive_int, wait_for, address, host (voluptuous schemas)
  • Removed from aiohomematic.validator: channel_address, device_address, hostname, ipv4_address, password, paramset_key (validator functions)

Version 2026.1.42 (2026-01-19)

What's Changed

Fixed

  • Device availability events for forced availability: Device.set_forced_availability() now publishes DeviceLifecycleEvent with event_type=AVAILABILITY_CHANGED when the device availability actually changes. Previously, only UNREACH/STICKY_UNREACH parameter changes triggered this event, meaning forced availability changes were not observable via the EventBus.

Version 2026.1.41 (2026-01-19)

What's Changed

Added

  • Startup resilience for authentication errors: Implemented defensive client initialization to prevent false re-authentication requests when CCU starts after Home Assistant. The new approach uses a 3-stage validation:
  • Stage 1: TCP Pre-Flight Check - Wait for port availability before attempting initialization
  • Stage 2: Client Creation & RPC Validation - Verify backend communication
  • Stage 3: Retry with Exponential Backoff - Retry transient authentication errors before failing
  • New TimeoutConfig parameters:
    • startup_max_init_attempts: Maximum initialization attempts during startup (default: 5)
    • startup_init_retry_delay: Initial delay between retry attempts (default: 3s)
    • startup_max_init_retry_delay: Maximum delay after backoff (default: 30s)
  • Reuses existing parameters: reconnect_tcp_check_timeout, reconnect_tcp_check_interval, reconnect_backoff_factor
  • Only triggers re-authentication if all retry attempts are exhausted

Fixed

  • Automatic reconnection after startup failures: Fixed connection recovery coordinator to properly handle startup failures where backend (CCU/pydevccu) was not available during Home Assistant startup. Previously, the integration would remain in FAILED state indefinitely. Now:
  • Heartbeat timer starts automatically when central transitions to FAILED state during startup
  • Recovery attempts run every 60 seconds (configurable via HEARTBEAT_RETRY_INTERVAL)
  • Two distinct recovery paths:
    • Startup failures (client never created): TCP check → Client creation → Data loading
    • Runtime failures (client exists): TCP check → RPC check → Warmup → Stability check → Reconnection → Data loading
  • Port resolution for TCP checks now falls back to interface configuration when client doesn't exist
  • Integration automatically reconnects within 60 seconds once backend becomes available

Version 2026.1.40 (2026-01-17)

What's Changed

Added

  • translation_key for data points: Added translation_key property to enable translations for data points that previously lacked this feature. Now all data point types provide a consistent translation_key:
  • GenericHubDataPointProtocol and CalculatedDataPointProtocol now require translation_key
  • BaseParameterDataPoint: Derived from parameter name (existing, e.g., set_point_temperature)
  • GenericHubDataPoint: Uses category value (e.g., hub_sensor, hub_button)
  • HmInboxSensor: "inbox"
  • HmUpdate: "system_update"
  • _BaseMetricsSensor: Derived from sensor name (e.g., system_health, connection_latency, last_event_age)
  • HmInterfaceConnectivitySensor: "interface_connectivity"
  • _BaseInstallModeDataPoint: "install_mode"
  • DpUpdate: "device_update"
  • CalculatedDataPoint: Derived from calculated parameter name

Changed

  • ChannelEventGroup as virtual data point: Refactored ChannelEventGroup from a helper class to a virtual data point bound to the Channel. Event groups are now created during Channel.finalize_init() for each DeviceTriggerEventType present in the channel. Key changes:
  • ChannelEventGroup now extends CallbackDataPoint and follows the standard subscription pattern
  • New subscribe_to_data_point_updated() method replaces subscribe_to_events()
  • New last_triggered_event property tracks which event fired
  • New device_trigger_event_type property identifies the event type of the group
  • Event groups are accessible via channel.event_groups dict keyed by DeviceTriggerEventType
  • A channel can have multiple event groups (one per DeviceTriggerEventType)
  • central.get_event_groups() now returns channel-bound instances (reused, not created on-the-fly)
  • Added subscribe_to_internal_data_point_updated to GenericEventProtocol
  • DataPointsCreatedEvent now sends ChannelEventGroupProtocol for EVENT category instead of tuple of events
  • Migration guide: docs/migrations/channel_event_group_migration_2026_01.md

Fixed

  • Legacy cache migration for climate schedules: Fixed ValidationException: Time 360 is invalid error that occurred when starting with aiohomematic 2026.1.39 if the paramset cache contained legacy schedule data. The issue was that old cached data stored endtime values as numeric strings (e.g., "360") instead of integers (360) or time strings ("06:00"). Added a new helper function _endtime_to_minutes() that handles all three formats, ensuring smooth migration without requiring cache deletion.

  • Coordinated cache clearing on version mismatch: Fixed an issue where only one cache (device or paramset descriptions) would be cleared when its schema version was incremented. Now when either DeviceDescriptionRegistry or ParamsetDescriptionRegistry detects a version mismatch, both caches are cleared together via CacheCoordinator.load_all(), which returns False to signal that both caches need to be rebuilt from CCU. Additionally, both registries now override clear() to also clear their internal index structures (_addresses, _device_descriptions, _address_parameter_cache), ensuring complete cache invalidation. This prevents scenarios where one cache's index data could remain in memory after clearing, causing incomplete rebuilds. Added new DataOperationResult.VERSION_MISMATCH enum value to signal version mismatches for coordinated handling.

  • Sound player soundfile default handling: Fixed CustomDpSoundPlayer.turn_on() to use the entity's current value or default as fallback when soundfile parameter is not explicitly provided, instead of always defaulting to "INTERNAL_SOUNDFILE". Also moved SOUNDFILE to visible_fields in IP_SOUND_PLAYER_CONFIG profile configuration.

  • Backend detection timeout support: Fixed TypeError: ServerProxy.__init__() got an unexpected keyword argument 'timeout' error in backend detection. The xmlrpc.client.ServerProxy class doesn't accept a timeout parameter directly. Introduced custom _TimeoutTransport and _TimeoutSafeTransport classes that properly set socket timeout on HTTP/HTTPS connections, fixing backend detection functionality.

Developer

  • Parallel test execution with pytest-xdist: Added pytest-xdist for parallel test execution, providing ~3.5x speedup (from ~180s to ~51s). CI workflow updated to use -n auto --dist loadscope. Session-scoped SessionPlayer fixtures now load ZIP files once per test session and share across all tests.

Version 2026.1.39 (2026-01-15)

What's Changed

Added

  • Paramset description patching system: Added a generic mechanism to patch incorrect paramset_descriptions returned by the CCU. Some devices return wrong parameter metadata (e.g., HM-CC-VG-1 with invalid MIN/MAX for SET_TEMPERATURE). The patching system:

  • Applies device-specific corrections during data ingestion (not on cache load)

  • Uses declarative patch definitions in aiohomematic/store/patches/
  • Matches patches by device_type, channel_no, paramset_key, and parameter
  • Automatically rebuilds cache when schema version changes (bumped to v3)

New modules:

  • ParamsetPatch: Dataclass defining a patch (device_type, channel_no, paramset_key, parameter, patches, reason)
  • ParamsetPatchMatcher: O(1) lookup matcher that applies patches to parameter data
  • PARAMSET_PATCHES: Registry of all defined patches

Initial patch:

  • HM-CC-VG-1 channel 1 SET_TEMPERATURE: Fixes MIN/MAX from incorrect CCU values to 4.5/30.5

Fixed

  • Paramset patching now works for channel paramsets: Fixed two issues that prevented patches from being applied to channel paramset descriptions:
  • Device type comparison is now case-insensitive (consistent with rest of codebase)
  • Channel paramsets now use PARENT_TYPE (root device type) for patch matching instead of channel TYPE

Version 2026.1.38 (2026-01-14)

What's Changed

Added

  • Configurable backend detection timeouts via TimeoutConfig: Backend detection timeouts are now centrally managed through TimeoutConfig instead of hardcoded constants. Added two new fields to TimeoutConfig:

  • backend_detection_request: float = 5.0 - Timeout for individual XML-RPC/JSON-RPC requests (1s in test mode)

  • backend_detection_total: float = 15.0 - Total timeout for the complete detection process (3s in test mode)

The detect_backend() function now accepts an optional timeout_config: TimeoutConfig | None parameter to override the timeout values from DetectionConfig. This allows for consistent timeout configuration across the application and automatic TEST_SPEEDUP support. Timeouts can be configured in three ways:

  1. Use defaults from DEFAULT_TIMEOUT_CONFIG
  2. Set explicitly in DetectionConfig(request_timeout=..., total_timeout=...)
  3. Pass a custom TimeoutConfig to detect_backend(timeout_config=...)

  4. Socket-level timeout for XML-RPC connections: Added timeout parameter to AioXmlRpcProxy.__init__() that sets socket-level timeouts for TCP connections. This prevents backend detection from hanging indefinitely when connecting to unreachable hosts. The request_timeout is now passed as socket timeout during detection, ensuring TCP connection attempts fail quickly (default: 5s) instead of relying on OS-default timeouts (60-120s). Normal RPC operations continue to use no socket timeout (backward compatible).

  5. Smart early abort on fatal connection errors: Backend detection now intelligently distinguishes between transient and fatal network errors. When encountering fatal errors (ETIMEDOUT, EHOSTUNREACH, ENETUNREACH, or TimeoutError), detection immediately aborts instead of trying all remaining ports. For transient errors (ECONNREFUSED - port closed but host reachable), detection continues to the next port. This reduces detection time on unreachable hosts from ~30s (6 ports × 5s) to ~5s (1 port × 5s), a 6× performance improvement.

  6. Service methods for manual configuration reload: Added Device.reload_device_config() and Channel.reload_channel_config() service methods (decorated with @inspector) for external/manual calls to force a reload of device/channel configuration data. These methods are intended for use cases where CONFIG_PENDING events are unreliable (classic BidCos devices) or when manual cache updates are needed. They internally call on_config_changed() which remains a callback method for internal system use. The methods reload paramset descriptions, link peers, and all master parameter values from the backend.

Typical use cases:

  • After changing master parameters on BidCos devices (CONFIG_PENDING unreliable)
  • Manual refresh of device/channel configuration
  • Forcing cache updates for debugging

Changed

  • Removed hardcoded detection timeout constants: Removed _DETECTION_TIMEOUT and _DETECTION_TOTAL_TIMEOUT constants from backend_detection.py. Default values are now provided by DEFAULT_TIMEOUT_CONFIG.backend_detection_request and DEFAULT_TIMEOUT_CONFIG.backend_detection_total.

Tests

  • New tests for timeout configuration: Added six new test cases in TestDetectBackendTimeout:
  • test_detect_backend_with_custom_timeout_config: Verifies that a custom TimeoutConfig is correctly used
  • test_detect_backend_timeout_config_overrides_detection_config: Verifies that timeout_config parameter overrides DetectionConfig timeouts
  • test_detect_backend_total_timeout_cancels_multiple_probes: Verifies that total_timeout cancels detection even when multiple ports remain to be probed, ensuring detection is always aborted within the timeout period
  • test_detect_backend_socket_timeout_on_unreachable_host: Verifies that socket-level timeout prevents hanging on unreachable hosts (marked as slow test)
  • test_detect_backend_aborts_on_host_unreachable: Verifies that detection aborts after the first fatal error (EHOSTUNREACH) instead of trying all 6 ports
  • test_detect_backend_tries_all_ports_on_connection_refused: Verifies that detection continues through all ports when encountering transient errors (ECONNREFUSED)

Documentation

  • Updated backend_detection.md: Added section explaining timeout configuration options and usage examples with custom TimeoutConfig.

Version 2026.1.37 (2026-01-13)

What's Changed

Added

  • Type conversion for read operations (convert_from_pd): Added optional convert_from_pd: bool = False parameter to get_paramset() and get_value() methods across all client implementations (InterfaceClient, ClientCCU, ClientJsonCCU, DeviceHandler). When enabled, values returned from the CCU are automatically converted to their correct types (INTEGER, FLOAT, BOOL, ENUM, STRING) based on the ParameterDescription. This mirrors the existing check_against_pd parameter for write operations but without MIN/MAX validation (backend already enforced bounds). New helper methods _convert_read_value() and _check_get_paramset() handle the conversion logic.

Changed

  • WeekProfile now uses automatic type conversion: Both ClimateWeekProfile and DefaultWeekProfile now call get_paramset() with convert_from_pd=True in their _get_raw_schedule() methods. This ensures ENDTIME values are returned as integers and TEMPERATURE values as floats directly from the client layer, eliminating the need for manual type handling in schedule parsing code. This is particularly important for HM-CC-VG-1 virtual heating groups where the CCU returns values as strings.

  • Renamed write conversion methods for consistency: Renamed _convert_value() to _convert_write_value() in InterfaceClient and DeviceHandler to clearly distinguish write operations from the new read conversion methods. The naming now follows a consistent pattern:

  • Read: _convert_read_value(), _check_get_paramset()

  • Write: _convert_write_value(), _check_put_paramset()

  • Simplified type handling in week_profile.py: Removed redundant string fallback code in ClimateWeekProfile.convert_raw_to_dict_schedule(). With convert_from_pd=True, ENDTIME values are now always integers from the client layer. Helper functions identify_base_temperature() and _validate_and_convert_weekday_to_simple() retain int/string dual support since they may receive raw CCU data directly.

Tests

  • New tests for convert_from_pd functionality: Added TestClientConvertFromPd test class with 4 tests covering the HM-CC-VG-1 string-to-int conversion scenario:
  • test_get_paramset_converts_string_to_int: Verifies ENDTIME "360" → 360 and TEMPERATURE "17.5" → 17.5
  • test_get_value_converts_string_to_int: Verifies single value conversion
  • test_convert_from_pd_preserves_correct_types: Verifies already-correct types remain unchanged
  • test_convert_from_pd_unknown_parameter_unchanged: Verifies unknown parameters pass through unchanged

Version 2026.1.36 (2026-01-13)

What's Changed

Fixed

  • Schedule validation error for HM-CC-VG-1 heating groups: Fixed ValidationException: Time 360 is invalid error when adding climate entities for virtual heating groups (HM-CC-VG-1). The CCU sometimes returns ENDTIME values as strings ("360") instead of integers (360) in the raw paramset. The convert_raw_to_dict_schedule() function in ClimateWeekProfile now handles both formats by checking if string values are numeric before conversion. This complements the fix in 2026.1.35 which addressed integer handling in identify_base_temperature().

Version 2026.1.35 (2026-01-13)

What's Changed

Fixed

  • Schedule validation error on device initialization: Fixed ValidationException: Time 360 is invalid error occurring when heating group devices (VirtualDevices interface) are initialized. The identify_base_temperature() function in week_profile.py incorrectly assumed all endtime values in the schedule cache are formatted strings ("06:00"), but during initial cache loading they can be raw integers (360 minutes) directly from the CCU. The function now handles both integer and string formats by checking the type before conversion. This fixes climate entity creation failures and recurring errors on Home Assistant startup. (Fixes #2797)

  • Type safety for ScheduleSlot: Updated ScheduleSlot TypedDict to correctly declare endtime: str | int instead of endtime: str. This reflects the actual behavior where the CCU always returns integers (minutes since midnight) while internal conversion may use string format. Fixes mypy type checking errors in week_profile.py.


Version 2026.1.34 (2026-01-13)

What's Changed

Fixed

  • CUxD/CCU-Jack unnecessary reconnects via MQTT: Fixed false positive connection loss detection for CUxD and CCU-Jack interfaces when used with Homematic(IP) Local MQTT bridge. These interfaces use JSON-RPC without ping/pong support and receive events via MQTT, causing callback_warn_interval checks to incorrectly trigger reconnects every ~4 minutes. Both is_callback_alive() and is_connected() now check ping_pong capability to skip callback timeout validation for MQTT-based interfaces.

  • Syntax error in device_ops.py: Fixed IndentationError in _validate_and_convert_value() method that prevented module import. Restored missing value conversion and MIN/MAX validation code block.

Changed

  • Schedule cache now uses pessimistic update strategy: Climate schedule cache (ClimateWeekProfile and DefaultWeekProfile) is no longer updated optimistically when calling set_schedule(), set_profile(), or set_weekday(). The cache is now updated only after receiving CONFIG_PENDING = False from the CCU via reload_and_cache_schedule(). This ensures the cache always reflects the actual CCU state, eliminating race conditions and inconsistencies. The cache remains essential for performance (avoiding RPC calls on reads) and event optimization (publishing events only when data changes). UI components like the Climate Schedule Card work seamlessly with this approach due to their built-in loading states and optimistic local updates.

  • Enhanced schedule temperature tests: Extended tests for set_simple_schedule_weekday and set_simple_schedule_profile to verify correct behavior when integer temperatures are provided. Tests now explicitly verify that integer-to-float conversion happens in _convert_value (inside put_paramset) based on paramset descriptions, rather than in week_profile.py. This ensures type conversion follows the established pattern where the client layer handles all type conversions based on CCU parameter definitions.

Documentation

  • CLAUDE.md - Schedule Cache Management: Added comprehensive section documenting the pessimistic schedule cache update strategy, including cache update flow diagram, implementation details, and integration guidelines for Home Assistant Climate Schedule Card. Includes timeline diagrams showing the ~0.5-2 second delay between set_schedule() calls and cache updates via CONFIG_PENDING.

  • CLAUDE.md - Homematic(IP) Local Integration: Added comprehensive section on "Integration with Homematic(IP) Local" explaining MQTT-based event flow for CUxD/CCU-Jack, capability-based callback health checks, and debugging guidance for MQTT integration issues.


Version 2026.1.33 (2026-01-12)

What's Changed

Fixed

  • LINK paramsets causing false "incomplete device data" issues: LINK paramsets are now excluded from paramset fetch operations and completeness checks. LINK paramsets are only relevant for device linking (direct associations) and are fetched dynamically when links are configured. Previously, failed LINK fetches (which occur when no links exist) caused devices to be incorrectly flagged as having incomplete data, triggering unnecessary repair issues in Home Assistant.

  • Empty paramset descriptions not being cached: Fixed issue where paramset descriptions that return an empty dict {} (valid response) were incorrectly treated as missing. HmIP base device addresses and some channel types return empty MASTER or VALUES paramsets which is valid behavior. The fix uses is not None check instead of truthy check in all paramset fetch code paths (get_paramset_descriptions, fetch_paramset_descriptions, and fetch_paramset_description), ensuring empty dicts are properly cached.

Changed

  • Skip LINK paramsets during device initialization: LINK paramset descriptions are no longer fetched during initial device creation or CONFIG_PENDING reload. This reduces startup time, eliminates spurious error messages for non-linked devices, and prevents false positive "incomplete device data" warnings. Link functionality remains fully supported - LINK paramsets are fetched on-demand when link operations are performed.

  • Improved log message clarity: Changed "devices" to "device/channel descriptions" in paramset fetch logging for accuracy, since the count includes both device and channel entries.


Version 2026.1.32 (2026-01-12)

What's Changed

Fixed

  • O(N²) performance issue during device creation: Fixed severe performance regression introduced in 2026.1.31 where DataFetchCompletedEvent was published after each individual device's paramset fetch, causing N cache saves for N devices. The event is now published once after the entire batch completes, reducing startup time from ~210 seconds to ~17 seconds for 397 devices (13x improvement).

  • put_paramset fails on HM-CC-VG-1: Fixed TypeError: '<' not supported between instances of 'int' and 'str' when calling put_paramset on HM-CC-VG-1. This device returns MIN/MAX values as strings instead of numbers in paramset descriptions. Now converts these values to the correct numeric type before comparison.

Changed

  • Enable schedule for HM-CC-VG-1

Version 2026.1.31 (2026-01-12)

What's Changed

Fixed

  • Schedule temperature values not updating on HM-TC-IT-WM-W-EU: Fixed issue where temperature values in simple weekly schedules were sent as integers to the CCU, causing them to be silently ignored. The CCU requires temperature parameters as floats. Added explicit float() conversions in convert_dict_to_raw_schedule(), _validate_and_convert_simple_to_weekday(), and _fillup_weekday_data() to ensure all temperature values are sent as floats regardless of user input type. This fixes schedule temperature updates for HM-TC-IT-WM-W-EU and other Homematic RF thermostats when using set_schedule_simple_weekday.

  • Event-based cache persistence for paramset descriptions: Implemented automatic cache persistence using DataFetchCompletedEvent to prevent race conditions where paramsets were fetched but not saved before shutdown. The CacheCoordinator now subscribes to data fetch completion events and automatically persists caches when changes are detected.

  • Paramset completeness validation before device creation: Added validation after paramset fetch operations to ensure all required paramsets are in cache before starting device creation. If paramsets are still missing after fetch attempts, creation of the new devices in this batch is aborted (existing devices remain unaffected), the partial cache is persisted for diagnostics, and an INCOMPLETE_DEVICE_DATA integration issue event is published to allow the Home Assistant integration to create a repair issue.

Changed

  • DataFetchCompletedEvent operation is now enum-based: Changed DataFetchCompletedEvent.operation from str to DataFetchOperation enum for type safety. Use DataFetchOperation.FETCH_PARAMSET_DESCRIPTIONS or DataFetchOperation.FETCH_DEVICE_DESCRIPTIONS instead of string literals.

  • Optimized cache save operations: Introduced save_if_changed() method that only writes to disk when has_unsaved_changes=True, avoiding unnecessary disk I/O during shutdown when event-based auto-save has already persisted changes.

  • Improved cache save logging: Added detailed debug logging for cache save operations showing content keys and sizes to aid in troubleshooting cache-related issues.

Added

  • Test for integer temperature conversion in schedules: Added test_rf_thermostat_simple_schedule_integer_temperature_conversion to verify that integer temperatures in YAML are correctly converted to floats before being sent to the CCU. This test ensures the fix for issue #2789 and prevents regression.

  • Integration issue for incomplete device data: Added new IntegrationIssueType.INCOMPLETE_DEVICE_DATA that is published via SystemStatusChangedEvent when devices cannot be created due to missing paramset descriptions after fetch attempts. The issue includes the affected device addresses and can be used by the Home Assistant integration to create repair issues alerting users to potential CCU data corruption or communication problems.

  • Schedule test for HM-TC-IT-WM-W-EU (#2785): Added test coverage for weekly program schedule operations on RF thermostats.


Version 2026.1.30 (2026-01-11)

What's Changed

Fixed

  • Device availability not reset after CCU restart: The state transition sequence during reconnect is reconnecting → disconnected → connecting → connected. The availability reset only triggered when old_state was in (DISCONNECTED, FAILED, RECONNECTING), but the final transition has old_state=CONNECTING. Added CONNECTING to the list of states that trigger availability reset.

  • Race condition in client state event processing: Events from the EventBus may be processed out of order (e.g., disconnected event processed after connected event). Now checks the current client state before marking devices unavailable, preventing incorrect availability changes when the client has already recovered.


Version 2026.1.29 (2026-01-11)

What's Changed

Fixed

  • Connectivity sensors not updating during CCU restart: Interface connectivity binary sensors now subscribe to ClientStateChangedEvent for immediate reactive updates instead of only updating during scheduled refresh cycles.

  • CuXD devices not created when paramset_descriptions missing: When device_descriptions were already cached but paramset_descriptions were missing (e.g., from a previous interrupted run), devices were skipped with "Nothing to add/update". Now properly detects missing paramset_descriptions by comparing expected PARAMSETS from device_description against cached paramsets, ensuring both caches stay synchronized.


Version 2026.1.28 (2026-01-10)

What's Changed

Breaking Changes

  • Comprehensive Capabilities Pattern Migration: All supports_* properties have been migrated to a unified Capabilities pattern.

  • Entity Capabilities (frozen dataclasses):

    • LightCapabilities: brightness, transition, color_temperature, hs_color, effects
    • SirenCapabilities: duration, lights, tones, soundfiles
    • LockCapabilities: open
    • ClimateCapabilities: profiles
  • Static capabilities now accessed via entity.capabilities.<name>:

    • light.supports_brightnesslight.capabilities.brightness
    • siren.supports_durationsiren.capabilities.duration
    • lock.supports_openlock.capabilities.open
    • climate.supports_profilesclimate.capabilities.profiles
  • Dynamic properties renamed to has_*:

    • light.supports_color_temperaturelight.has_color_temperature
    • light.supports_effectslight.has_effects
    • light.supports_hs_colorlight.has_hs_color
    • display.supports_iconsdisplay.has_icons
    • display.supports_soundsdisplay.has_sounds
    • device.supports_week_profiledevice.has_week_profile
    • data_point.supports_eventsdata_point.has_events
    • data_point.supports_scheduledata_point.has_schedule
    • central.supports_ping_pongcentral.has_ping_pong
  • BackendCapabilities: Removed supports_* prefix from all 19 fields:

    • capabilities.supports_ping_pongcapabilities.ping_pong
    • capabilities.supports_backupcapabilities.backup
    • (and all other fields)
  • Handler classes: All supports_*has_*:

    • handler.supports_linkinghandler.has_linking
    • handler.supports_programshandler.has_programs
    • (and all other handlers)
  • ClientConfig: All supports_*has_*:

    • config.supports_linkingconfig.has_linking
    • config.supports_ping_pongconfig.has_ping_pong

Added

  • Faster Connectivity Detection (#2767): Improved connection loss detection from ~240s to ~20s:

  • Added ping_timeout (10s) for ping/connectivity check operations

  • Added connectivity_error_threshold (1) - single failure marks interface as disconnected
  • Reduced callback_warn_interval from 10 minutes to 3 minutes
  • Immediate device unavailability marking when client state changes to DISCONNECTED/FAILED
  • Fixed system health score defaulting to 100% before connections established (now shows 0%)

  • Interface Connectivity Binary Sensors: New hub-level binary sensors showing per-interface connectivity status:

  • HmInterfaceConnectivitySensor class for each interface (HmIP-RF, BidCos-RF, etc.)

  • Shows ON when interface is connected and operational
  • Shows OFF when interface is disconnected, failed, or degraded
  • Always available (never shows unavailable since its purpose is to show connection state)
  • Refreshed automatically via scheduler at the same interval as metrics

  • New protocol: HubBinarySensorDataPointProtocol for hub-level binary sensor data points

  • New Capabilities Dataclasses in aiohomematic/model/custom/capabilities/:

  • LightCapabilities, SirenCapabilities, LockCapabilities, ClimateCapabilities

  • All use @dataclass(frozen=True, slots=True) for immutability and performance
  • Predefined constants for common capability sets

  • Comprehensive test coverage for ConnectionRecoveryCoordinator (90+ tests):

  • Unit tests for InterfaceRecoveryState dataclass (retry logic, exponential backoff, state transitions)
  • Tests for all recovery stages (TCP check, RPC check, stability check, reconnect, data load)
  • Tests for event handlers (_on_connection_lost, _on_circuit_breaker_tripped, _on_circuit_breaker_state_changed)
  • Tests for state machine transitions (RECOVERING, RUNNING, DEGRADED, FAILED)
  • Tests for heartbeat timer and incident recording
  • Tests for exception handling (CancelledError, generic exceptions)
  • Tests for edge cases (shutdown during recovery, max retries, JSON-RPC port fallback)

Version 2026.1.27 (2026-01-09)

What's Changed

Fixed

  • Fix recovery stuck in infinite retry loop after CCU restart (follow-up to GitHub #2757):
  • Reset XML-RPC proxy transport before RPC availability check during recovery. After CCU restart, the proxy's HTTP connection enters an inconsistent state (ResponseNotReady) which caused system.listMethods calls to fail silently
  • Fix proxy lookup to handle both direct client proxy (client._proxy) and backend proxy (client._backend._proxy) for InterfaceClient architecture
  • Add logging when RPC check fails during recovery for better debugging

Version 2026.1.25 (2026-01-09)

What's Changed

Fixed

  • Fix persistent ping_pong_mismatch repair issues after CCU restart (GitHub #2757):
  • Fix central state stuck at "recovering" after successful recovery by correcting the order of operations in ConnectionRecoveryCoordinator._start_recovery() - now removes interface from active_recoveries before checking transition state
  • Add immediate connection repair notification when recovery starts - emits SystemStatusChangedEvent(connection_state=(interface_id, False)) so users see feedback immediately instead of waiting for recovery to fail
  • Emit connection restored event when recovery succeeds to clear the repair notification

Version 2026.1.24 (2026-01-09)

What's Changed

Breaking Changes

  • Strongly typed events and IntegrationIssue: Multiple event classes now use typed enums instead of string comparisons. This prevents consumer errors from incorrect string matching and provides better IDE support:

  • IntegrationIssue:

    • issue.severity is now IntegrationIssueSeverity enum
    • New issue.issue_type field as IntegrationIssueType enum
    • issue.mismatch_count is now int | None
    • issue.mismatch_type is now PingPongMismatchType | None
  • ClientStateChangedEvent: old_state and new_state are now ClientState enum (previously str)

  • CentralStateChangedEvent: old_state and new_state are now CentralState enum (previously str)

  • DataRefreshTriggeredEvent / DataRefreshCompletedEvent: refresh_type is now DataRefreshType enum (previously str)

  • ProgramExecutedEvent: triggered_by is now ProgramTrigger enum (previously str)

  • See migration guide: docs/migrations/strongly_typed_events_2026_01.md

Added

  • New enums: DataRefreshType and ProgramTrigger for strongly typed event fields

Version 2026.1.23 (2026-01-09)

What's Changed

Fixed

  • Fix list_device() returning empty list treated as error: The init_proxy() method now correctly handles empty device lists from interfaces that don't support RPC callbacks. Previously, an empty device list was incorrectly treated as a connection failure because the code used a truthy check (if device_descriptions :=) instead of a None check. Now uses is not None to properly distinguish between "no devices" (success) and "list_devices failed" (failure).

Version 2026.1.22 (2026-01-09)

What's Changed

Fixed

  • Fix leaked EventBus subscriptions on central stop: Six internal subscription leaks have been fixed:

  • SysvarStateChangedEvent subscriptions in HubCoordinator were not being cleaned up (72 subscriptions per central)

  • HealthRecordedEvent subscription in ClientCoordinator was stored but never unsubscribed
  • DeviceRemovedEvent subscription in CacheCoordinator - the existing stop() method was not being called
  • DataPointValueReceivedEvent subscriptions in EventCoordinator were not being cleaned up
  • DataPointStatusReceivedEvent subscriptions in EventCoordinator were not being cleaned up
  • SystemStatusChangedEvent subscriptions in CentralUnit, InterfaceClient, and ClientCCU were not being cleaned up

The HubCoordinator and EventCoordinator now have clear() methods, CacheCoordinator.stop() is called during central shutdown, and client stop() methods now properly unsubscribe from system status events.

Added

  • New EventBus.clear_external_subscriptions() method: Clears subscriptions for event types that are subscribed to by external consumers (like Home Assistant integration). This includes DataPointStateChangedEvent, DeviceRemovedEvent, DeviceStateChangedEvent, FirmwareStateChangedEvent, and LinkPeerChangedEvent. The method is called during central shutdown as a fallback cleanup for external subscriptions that were not properly unsubscribed.

Version 2026.1.21 (2026-01-09)

What's Changed

Fixed

  • Fix state machine transition error on unload: Allow transition from FAILED to DISCONNECTED state. This fixes InvalidStateTransitionError when unloading the Home Assistant integration while a client is in failed state. Previously, deinit_proxy() could not cleanly shut down a failed client.

Version 2026.1.20 (2026-01-08)

What's Changed

Changed

  • Eliminate dynamic import in CentralConfig.create_central(): The circular import between config.py and central_unit.py has been resolved using Dependency Inversion with a new CentralConfigProtocol. This eliminates the Home Assistant warning: Detected blocking call to import_module with args ('aiohomematic.central.central_unit',).

  • Eliminate all remaining lazy imports: All noqa: PLC0415 markers have been removed from production code. Circular imports have been resolved through module restructuring:

  • Event types (Event, EventPriority, state change events) moved to central/events/types.py
  • LogContextProtocol moved to _log_context_protocol.py in root package
  • Handler utilities now imported at top-level
  • Metrics imports now at top-level in circuit_breaker.py

Added

  • New CentralConfigProtocol: A protocol interface in interfaces/central.py that defines the configuration contract, enabling CentralUnit to depend on the protocol rather than the concrete CentralConfig class.

  • New central/events/types.py module: Contains foundational event types to break circular import chains:

  • Event base class

  • EventPriority enum
  • CircuitBreakerStateChangedEvent, CircuitBreakerTrippedEvent
  • ClientStateChangedEvent, CentralStateChangedEvent, HealthRecordedEvent

  • New _log_context_protocol.py module: Minimal leaf module containing LogContextProtocol to avoid triggering package initialization chains.

Removed

  • CentralConfig.create_json_rpc_client() method removed: This method was moved inline into CentralUnit.json_rpc_client property. External consumers should not have been using this method as it required a CentralUnit instance as parameter.

Internal

  • CentralUnit.__init__ now accepts CentralConfigProtocol instead of CentralConfig
  • ConfigProviderProtocol.config now returns CentralConfigProtocol
  • ClientDependenciesProtocol.config now returns CentralConfigProtocol
  • Event consumer modules now import from central/events/types.py directly
  • property_decorators.py imports LogContextProtocol from root package module

Version 2026.1.19 (2026-01-08)

What's Changed

Breaking Changes

  • CentralConfig.create_central() is now async: Prevents "Detected blocking call" warnings in Home Assistant 2026.1.0+ by running all blocking I/O operations (os.path.exists, os.makedirs) in a thread pool executor.
# Before
central = config.create_central()

# After
central = await config.create_central()
  • CentralConfig.check_config() is now async: Configuration validation now runs in executor to avoid blocking.

  • check_config() function is now async: Module-level config validation function now returns Awaitable[list[str]].

  • check_or_create_directory() is now async: Directory creation utility now returns Awaitable[bool].

Version 2026.1.18 (2026-01-08)

What's Changed

Added

  • Add old_value and new_value fields to DataPointStateChangedEvent: External consumers can now track what changed without maintaining their own previous state. The fields are populated when values change and may be None during initial load or for non-value updates.

  • Add AvailabilityInfo dataclass: New unified view of device availability bundling reachability, battery, and signal information:

  • is_reachable: Device reachability status (inverse of UNREACH)

  • last_updated: Most recent data point modification time
  • battery_level: Battery percentage (0-100) from OperatingVoltageLevel or BATTERY_STATE
  • low_battery: LOW_BAT indicator
  • signal_strength: RSSI in dBm from RSSI_DEVICE
  • Helper properties: has_battery, has_signal_info

  • Add Device.availability property: Returns AvailabilityInfo providing a unified view of device connectivity and health status.

  • Add Consumer API documentation: New docs/consumer_api.md guide explaining the three API layers (HomematicAPI, CentralUnit, Protocols), event subscription patterns, and common operations for external consumers like Matter bridges.

Internal

  • Update DeviceAvailabilityProtocol: Added availability property to the protocol interface
  • Update CalculatedDataPointProtocol: Added missing value property to the protocol interface
  • Update CallbackDataPointProtocol: Added old_value and new_value parameters to publish_data_point_updated_event()
  • Remove unnecessary delayed imports: Moved store.types imports to top-level in 7 files and metrics/central.events imports in request_coalescer.py. These imports had # noqa: PLC0415 markers but no actual circular dependency. Remaining delayed imports in circuit_breaker.py are necessary due to genuine circular dependency chains.

Version 2026.1.17 (2026-01-07)

What's Changed

Internal

  • Extend DeviceDescription TypedDict to cover full API specification: Activated all optional fields from HM_XmlRpc_API.pdf V2.16 and HMIP_XmlRpc_API_Addendum.pdf V2.10

  • Added fields: PARENT_TYPE, RF_ADDRESS, INDEX, AES_ACTIVE, VERSION, FLAGS, DIRECTION, GROUP, TEAM, TEAM_TAG, TEAM_CHANNELS, ROAMING

  • Improved documentation: Grouped fields by category (Common, Firmware, Interface/Connectivity, Links, Device metadata, Groups/Teams)
  • Type safety: Full type coverage for all fields defined in API specification

  • Improve ParameterData validation and type safety:

  • VALUE_LIST: Changed from Iterable[Any] to Iterable[str] with validation ensuring all elements are converted to strings

  • SPECIAL: Documented actual usage pattern - API spec defines Array<Struct>, but CCU/pydevccu/Homegear return Mapping[str, Any] with special value IDs as keys (e.g., {"NOT_USED": 111600.0, "PERMANENT": 255})
  • Debug logging: All validation failures now logged at DEBUG level with context (address, parameter name, validation error) for easier troubleshooting and backend compatibility monitoring

  • Implement ADR 0015: Description Data Normalization and Validation: Establish comprehensive data normalization layer using voluptuous for device and parameter descriptions

  • Problem: Device descriptions and paramset descriptions were normalized at output points (e.g., listDevices() XML-RPC response), addressing symptoms rather than root causes. This violated DRY principle and created multiple validation points.
  • Solution: Normalize data at all ingestion points following "Parse, don't validate" pattern
  • Benefits: Single source of truth for data correctness, defense in depth with multiple validation points, cache efficiency through schema versioning, reduced complexity by eliminating output normalization

Bug Fixes

  • Fix Homegear device details fetching in InterfaceClient: The new InterfaceClient backend architecture was missing the get_device_details() implementation for Homegear
  • Fix excessive getValue calls during startup: Fixed a bug where the data cache was expiring during device creation, causing hundreds of unnecessary getValue RPC calls

Version 2026.1.16 (2026-01-06)

What's Changed

Bug Fixes

  • Fix VirtualDevices init() Timeout (#2731): Fixed a bug where VirtualDevices init() times out even though the CCU successfully processed the request

  • Root cause: The VirtualDevices service on some CCU backends (OpenCCU, RaspberryMatic) processes the init() request correctly, calls back listDevices/newDevices, but fails to send the init() response. This causes a 3-second timeout even though the initialization was successful.

  • Symptom: PROXY_INIT failed: NoConnectionException [OSError: timed out] for VirtualDevices while BidCos-RF and HmIP-RF work fine. The CCU does call back listDevices successfully, but init() still times out.

  • Fix: Added detection of successful callback during init() timeout. If init() times out but a listDevices callback was received (indicated by modified_at timestamp update), the init() is treated as successful.

  • Affected files:

    • aiohomematic/client/ccu.py: Added callback detection in init_proxy()
    • aiohomematic/client/interface_client.py: Added callback detection in init_proxy()
  • Impact: VirtualDevices (heating groups) should now initialize reliably on OpenCCU/RaspberryMatic systems

Version 2026.1.15 (2026-01-06)

What's Changed

Bug Fixes

  • Fix VirtualDevices Connection Failure (#2731): Fixed a critical bug where VirtualDevices connections would fail with a 3-second timeout

  • Root cause: The CCU's Java DeviceDescription.children field expects String[] (array), but some backends (notably VirtualDevices) send CHILDREN as an empty string or omit it, causing the CCU's XML-RPC parser to crash with IllegalArgumentException: Can not set String[] field to String

  • Fix: Added _normalize_device_description() function that ensures CHILDREN is always a list before sending to the CCU via listDevices callback

  • Affected files:

    • aiohomematic/central/rpc_server.py: Added normalization for legacy XML-RPC server
    • aiohomematic/central/async_rpc_server.py: Added normalization for async XML-RPC server
  • Impact: VirtualDevices (heating groups) should now connect reliably on OpenCCU/RaspberryMatic systems

Version 2026.1.14 (2026-01-06)

What's Changed

Breaking Changes

  • Remove Retry Logic for RPC Operations (#2731): Completely removed the @with_retry decorator and RetryStrategy class from the codebase

  • Rationale: The retry mechanism (added in 2025.12.8) conflicted with the CircuitBreaker pattern, causing cascading failures. Each retry counted as a separate failure toward the circuit breaker threshold. On slow backends like VirtualDevices on Pi4/OpenCCU, this caused the circuit breaker to trip during initialization.

  • What was removed:

    • aiohomematic/retry.py module (RetryStrategy, with_retry, is_retryable_exception)
    • @with_retry decorator from AioXmlRpcProxy, AioJsonRpcAioHttpClient, and HomematicAPI
    • RETRY_* constants from const.py
    • _RETRY_BYPASS_METHODS constant from rpc_proxy.py
  • Error handling preserved: The existing mechanisms are sufficient:

    • CircuitBreaker: Fast-fail on backend outage (per-proxy)
    • CentralConnectionState: Aggregate health tracking (central)
    • ClientStateMachine: Connection lifecycle (per-client)
    • ConnectionRecoveryCoordinator: Automatic reconnection (central)
  • Impact: Network errors now fail immediately instead of retrying. This provides more predictable behavior and prevents retry-induced failures. The ConnectionRecoveryCoordinator handles reconnection at the appropriate connection level.

  • ADR: See ADR 0014 for detailed rationale

Version 2026.1.13 (2026-01-06)

What's Changed

Improvements

  • Add TypedDict for Device Details: Introduced DeviceDetail and ChannelDetail TypedDicts for type-safe handling of JSON-RPC device details response

  • Provides static type checking via mypy

  • Better IDE autocomplete support
  • Documents the data structure in code

  • Rename Backend Methods for Consistency: Renamed backend methods to follow consistent naming convention

  • fetch_device_details()get_device_details() (returns data)
  • fetch_all_device_data()get_all_device_data() (returns data)
  • Convention: get_* in BackendOperationsProtocol returns data, fetch_* in ClientProtocol fetches AND caches

Bug Fixes

  • Fix InterfaceClient Not Loading Channel Names: The fetch_device_details() method in InterfaceClient was not processing the nested channels array from the JSON-RPC response, causing channel names to be missing when using InterfaceClient instead of the legacy client

Version 2026.1.12 (2026-01-06)

What's Changed

Bug Fixes

  • Fix Device Cache Not Reloading After Firmware Update: The updateDevice callback now properly handles both firmware updates (hint=0) and link partner changes (hint=1)

  • Root Cause: The updateDevice callback was a NO-OP that only logged the event. The hint parameter (which indicates the type of update) was completely ignored

  • Problem: After a firmware update that changed a device's channel structure (e.g., HmIP-BRC2 removing channel 3), the cached descriptions still contained the old channel structure, causing errors like "Non-existent Channel 3". Link partner changes were also not propagated to the device model
  • Fix:
    • When hint=0 (firmware update), the handler now:
    • Removes cached device and paramset descriptions for the device
    • Removes the Device object from the registry
    • Fetches fresh device descriptions from the CCU
    • Recreates the Device object with the new structure
    • When hint=1 (link partner change), the handler now:
    • Refreshes link peer information for all channels of the device
    • Triggers LinkPeerChangedEvent if link peers have changed
  • New Constant: Added UpdateDeviceHint enum with FIRMWARE=0 and LINKS=1 values
  • New Methods:

    • DeviceCoordinator.update_device(): Handles firmware update cache invalidation
    • DeviceCoordinator.refresh_device_link_peers(): Handles link partner refresh
  • Implement Device Replacement Handler: The replaceDevice callback now properly handles CCU device replacement

  • Use Case: When a broken device is replaced using the CCU's "Replace device" function, the CCU transfers configuration from the old to the new device and notifies listeners

  • Previous Behavior: Was a NO-OP that only logged the event
  • New Behavior:
    1. Removes the old device from registry and caches
    2. Fetches fresh device descriptions for the new device
    3. Creates the new Device object with all data points
  • New Method: DeviceCoordinator.replace_device()

  • Implement Re-Added Device Handler: The readdedDevice callback now properly handles device re-pairing

  • Use Case: When a known device is put into learn-mode while installation mode is active (re-pairing), device parameters may have changed

  • Previous Behavior: Was a NO-OP that only logged the event
  • New Behavior:
    1. Removes cached descriptions to force refresh
    2. Fetches fresh device descriptions from the CCU
    3. Recreates the Device object with updated parameters
  • New Method: DeviceCoordinator.readd_device()

  • Fix Hub Entities Not Created When Secondary Clients Fail (#2718): System variables, programs, and other hub entities are now created even when secondary clients (e.g., CUxD) fail to initialize

  • Root Cause: The fetch_program_data() and fetch_sysvar_data() methods checked central.available, which returns False if any client is unavailable

  • Symptom: When CUxD fails to connect, no programs or system variables appear in Home Assistant, showing "Entity no longer provided by integration"
  • Fix: Changed availability checks to use primary_client.available instead of central.available, since hub data is only fetched from the primary client (HmIP-RF/BidCoS-RF)
  • Affected files: aiohomematic/model/hub/hub.py, aiohomematic/central/scheduler.py

  • Fix Connection Recovery Port Detection for InterfaceClient: The _get_client_port() method now correctly retrieves the port for both client implementations

  • Root Cause: The method only checked client._config.interface_config.port (ClientCCU path), but InterfaceClient stores config directly in client._interface_config.port
  • Symptom: Warning logged: CONNECTION_RECOVERY: No port configured for <interface>, skipping TCP check
  • Fix: Added check for _interface_config attribute first (InterfaceClient), then falls back to _config.interface_config (ClientCCU)

Version 2026.1.11 (2026-01-05)

What's Changed

New Features

  • New InterfaceClient with Backend Strategy Pattern: Introduced a unified client implementation that replaces the three legacy clients (ClientCCU, ClientJsonCCU, ClientHomegear)

  • Architecture: Single InterfaceClient class delegates transport operations to backend strategies (CcuBackend, JsonCcuBackend, HomegearBackend)

  • Benefits: Cleaner separation of concerns, easier maintenance, consistent behavior across all backend types
  • Feature Flag: Enable via OptionalSettings.USE_INTERFACE_CLIENT or environment variable AIOHOMEMATIC_USE_INTERFACE_CLIENT=1
  • Status: Phase 2 complete - all business logic migrated, 24 comparison tests verify identical behavior to legacy clients
  • Documentation: See docs/adr/0013-implementation-status.md for implementation details

  • CI Tests Both Client Implementations: The CI pipeline now runs the full test suite (1640 tests) with both legacy client and InterfaceClient implementations

  • Test infrastructure updated to support InterfaceClient's __slots__ architecture
  • Coverage threshold temporarily lowered to 80% (will be restored to 85% after legacy client cleanup)

Bug Fixes

  • Fix VirtualDevices Init Timeout Causing Client Failure: The init() RPC method is now excluded from automatic retry logic

  • Root Cause: In version 2025.12.8, @with_retry was added to XML-RPC requests, causing init() failures to trigger 3 retry attempts before marking the client as FAILED

  • Problem: VirtualDevices interface on some CCUs doesn't respond to init() within the timeout, but sends the listDevices callback correctly. The retry mechanism amplified single timeouts into complete client failure
  • Fix: Added _RETRY_BYPASS_METHODS constant excluding init from retry logic. The client state machine handles init failures via its own reconnection logic
  • Impact: VirtualDevices (heating groups) connections are more resilient on slow-responding CCUs

  • Fix HmIP-MP3P LED Auto-Off After 10 Seconds: The sound player LED (light.turn_on) now stays on permanently by default instead of turning off after 10 seconds

  • Changed the default on_time from 10.0 to 0.0 (permanently on)

  • Previously, calling light.turn_on without explicit on_time would send DURATION_VALUE: 10, causing the LED to turn off after 10 seconds even though ON_TIME_LIST: PERMANENTLY_ON was also sent

  • Fix Device Availability Not Updating in Home Assistant: Entities on channels other than :0 now properly update their availability state when UN_REACH or STICKY_UN_REACH changes

  • Root Cause: When UN_REACH changed on channel :0, only publish_device_updated_event() was called. Entities subscribe to their own data point's subscribe_to_data_point_updated, not to device events

  • Problem: Entities on channels :1, :2, etc. never received notification of availability changes and continued showing cached "available" state
  • Fix: Now notifies all data points on the device via publish_data_point_updated_event() when availability changes, similar to set_forced_availability()

  • Fix InterfaceClient Ping-Pong Token Handling: The new InterfaceClient now correctly passes the ping-pong token through backend strategies

  • Token is now passed from InterfaceClient.ping() to the backend's ping() method
  • Ensures proper connection health monitoring with the new client implementation

Internal

  • Replace supports_* Methods with capabilities Object: Consolidated 10 boolean supports_* properties into a single ClientCapabilities dataclass

  • Before: client.supports_ping, client.supports_programs, client.supports_install_mode, etc.

  • After: client.capabilities.supports_ping, client.capabilities.supports_programs, etc.
  • Capabilities are determined once at client creation based on backend type
  • Removes ~300 lines of redundant property definitions across client classes
  • Both legacy clients and InterfaceClient now use the same capabilities system

  • InterfaceClient Feature Parity: Added missing methods to achieve full feature parity with legacy clients

  • Added is_callback_alive(), check_connection_availability(), execute_program(), set_system_variable(), get_system_variable(), and 8 other methods
  • InterfaceClient now implements all 45+ methods from the client protocol

Version 2026.1.10 (2026-01-04)

What's Changed

Bug Fixes

  • Fix CUxD/CCU-Jack Recovery for JSON-RPC-only Interfaces: Connection recovery now properly handles JSON-RPC-only interfaces (CUxD, CCU-Jack)
  • TCP Check: For interfaces without an XML-RPC port (port=0), the recovery now checks the JSON-RPC port (80/443) instead of failing immediately
  • RPC Availability Check: JSON-RPC-only interfaces now use check_connection_availability() (which calls Interface.isPresent via JSON-RPC) instead of attempting XML-RPC system.listMethods
  • Previously, CUxD recovery would always fail at the TCP check stage because _get_client_port returned None
  • This caused the central to enter FAILED state after max retries even when the CUxD service was available

Version 2026.1.9 (2026-01-04)

What's Changed

Bug Fixes

  • Backend Detection Validates Interface Availability: The backend detection now verifies that each interface process is actually running via is_present() check, not just installed

  • Previously, interfaces like CUxD would be reported as "available" even when the daemon wasn't running

  • This caused connection recovery loops and eventual "central failed" state when the integration tried to connect to non-running interfaces
  • Now only interfaces that pass the is_present() check are included in the detection result
  • Added warning logs when installed interfaces are not running

  • Fix CUxD/CCU-Jack JSON-RPC Method Overrides: ClientJsonCCU now properly uses JSON-RPC for all device operations

  • Fixed UnsupportedException errors for getParamsetDescription and related methods
  • Added missing method overrides: fetch_paramset_description, fetch_paramset_descriptions, get_paramset_descriptions, get_all_paramset_descriptions, get_all_device_descriptions, update_paramset_descriptions
  • These methods were previously delegating to the handler which used XML-RPC (not available for CUxD/CCU-Jack interfaces)

Improvements

  • Dynamic Version Detection in Issue Analyzer: The GitHub Issue Analyzer bot now fetches current integration versions dynamically from GitHub Releases instead of using outdated hardcoded values
  • Fixes incorrect "outdated version" warnings when users report issues with the latest version
  • Supports automatic version detection for stable and pre-release versions
  • No longer requires manual updates to the analyzer script when new versions are released
  • If version information cannot be retrieved, no version-related comments are made

Version 2026.1.8 (2026-01-03)

What's Changed

Improvements

  • Reduce RPC Error Log Noise: Expected RPC errors during initial data loading no longer clutter the logs

  • Added _XmlRpcFaultCode enum documenting all Homematic XML-RPC error codes (-1 to -10)

  • Expected errors (Unknown Parameter, UNREACH, Unknown Device, etc.) now recorded with WARNING severity
  • Incident Store always logs at DEBUG level - its purpose is recording, not active logging
  • Active logging remains at the source (log_boundary_error, @inspector decorator)
  • Eliminates duplicate logging between Incident Store and boundary error handlers

  • Increase Incident Store Capacity: Raised INCIDENT_STORE_MAX_PER_TYPE from 20 to 50 for better diagnostics


Version 2026.1.7 (2026-01-03)

What's Changed

Bug Fixes

  • Fix Runtime Device Addition: Fixed KeyError when adding new devices during runtime after cache was loaded
  • Root cause: ParamsetDescriptionRegistry lost its nested defaultdict structure after loading from JSON
  • When a new device was added, accessing non-existent keys raised KeyError instead of creating empty dicts
  • Error manifested as: UPDATE_CACHES_WITH_NEW_DEVICES failed: KeyError [device_address]
  • Fix rebuilds proper defaultdict structure in _process_loaded_content()
  • Added regression test for the scenario

Internal

  • Remove asyncio Fallbacks: Made task_scheduler a required parameter in core infrastructure classes

  • EventBus, CircuitBreaker, and Storage now require explicit TaskSchedulerProtocol injection

  • Removes runtime asyncio event loop fallback code that was only used in tests
  • Improves code clarity and ensures consistent dependency injection patterns
  • Test infrastructure updated with _NoOpTaskScheduler for synchronous tests

  • Remove Legacy Code: Removed regular_to_default_dict_hook from support.py

  • This function was used with json.loads(object_hook=...) before Storage Abstraction Layer
  • No longer needed since orjson doesn't support object_hook parameter

Version 2026.1.6 (2026-01-03)

What's Changed

Bug Fixes

  • Fix CuXD/CCU-Jack Device Control: ClientJsonCCU now properly overrides set_value and put_paramset to use JSON-RPC

  • Root cause: After handler refactoring (#2554), DeviceHandler used XML-RPC proxy for all value operations

  • ClientJsonCCU used NullRpcProxy which threw UnsupportedException for all RPC calls
  • CuXD and CCU-Jack devices could not be controlled (set_value failed silently)
  • Fix restores the JSON-RPC based value operations that worked in version 2025.11.7
  • Added tests to verify ClientJsonCCU uses JSON-RPC for set_value and put_paramset

  • Fix Sysvar-to-Device Association: System variables with device references are now correctly associated with their devices/channels

  • Root cause: After coordinator refactoring, hub initialization happened BEFORE device creation
  • identify_channel() found no channels because devices didn't exist yet during sysvar creation
  • Fix: Device creation now happens BEFORE hub initialization in start_clients()
  • Sysvars containing channel/device ise_ids are now properly linked to their devices in Home Assistant

New Features

  • Circuit Breaker Incident Recording: Circuit breaker state changes are now recorded as incidents

  • CIRCUIT_BREAKER_TRIPPED (ERROR): When circuit breaker opens due to excessive failures

  • CIRCUIT_BREAKER_RECOVERED (INFO): When circuit breaker recovers after successful test requests
  • Incidents include comprehensive context: failure/success counts, thresholds, timestamps, total requests

  • CONNECTION_LOST Incident Recording: Connection loss events are now recorded as incidents

  • CONNECTION_LOST (ERROR): When connection to backend is lost

  • Recorded by ConnectionRecoveryCoordinator when handling connection loss events
  • Context includes: reason, client state, circuit breaker state, recovery attempt count, active recoveries

  • CONNECTION_RESTORED Incident Recording: Connection restoration events are now recorded as incidents

  • CONNECTION_RESTORED (INFO): When connection to backend is successfully restored

  • Recorded by ConnectionRecoveryCoordinator after successful recovery completion
  • Context includes: total attempts, duration, stages completed, client state, circuit breaker state

  • RPC_ERROR Incident Recording: RPC call failures are now recorded as incidents

  • RPC_ERROR (ERROR): When an RPC call fails (SSL, OS, protocol, or general errors)

  • Recorded by both AioXmlRpcProxy (XML-RPC) and AioJsonRpcAioHttpClient (JSON-RPC)
  • Context includes: protocol, method, error type, sanitized error message, TLS status
  • Supports all error types: SSLError, OSError, XMLRPCFault, ProtocolError, JSONRPCError, etc.

  • CALLBACK_TIMEOUT Incident Recording: Callback timeout events are now recorded as incidents

  • CALLBACK_TIMEOUT (WARNING): When no callback is received from backend within configured interval

  • Recorded by ClientCCU when callback staleness is detected in is_callback_alive()
  • Context includes: seconds since last event, configured threshold, last event time, client/circuit breaker state

  • Per-Type Incident Storage: IncidentStore now uses per-IncidentType storage limits

  • Each incident type maintains its own history (max 20 per type, 7-day retention)
  • Prevents high-frequency incidents from crowding out rare but important events
  • Renamed max_incidents to max_per_type parameter

Version 2026.1.5 (2026-01-02)

What's Changed

  • Add IncidentStore for Persistent Diagnostic Incidents: New storage system for tracking and persisting diagnostic incidents

  • Introduces IncidentStore in aiohomematic/store/persistent/incident.py

  • Implements save-on-incident, load-on-demand persistence strategy
  • Stores incidents in {storage_path}/cache/{central_name}_hm_incidents.json
  • Automatic cleanup of old incidents (default: 7 days retention)
  • Incidents are deleted when integration is removed via cleanup_files()

  • PingPong Tracker Incident Recording: Connection health issues are now recorded as incidents

  • PING_PONG_MISMATCH_HIGH (ERROR): When pending PONG count exceeds threshold

  • PING_PONG_UNKNOWN_HIGH (WARNING): When unknown PONG count exceeds threshold
  • Incidents include context (counts, thresholds) and journal excerpts for debugging
  • Added IncidentRecorderProtocol for decoupled incident recording

  • PingPong Diagnostics Journal: Enhanced diagnostic capabilities for connection monitoring

  • PingPongJournal ring buffer tracks PING/PONG events with timestamps
  • RTT (round-trip time) statistics available via get_rtt_statistics()
  • Journal excerpts attached to incidents for post-mortem analysis

Bug Fixes

  • Fix KeyError for PARENT in Device Descriptions: Use .get() to safely access optional PARENT field

  • Some device descriptions may not include the PARENT key

  • Fixes KeyError: 'PARENT' during device discovery

  • Fix KeyError for CHILDREN in Device Descriptions: Use .get() to safely access optional CHILDREN field

  • Affected files: model/device.py, client/handlers/device_ops.py, store/persistent/device.py
  • Prevents KeyError: 'CHILDREN' for devices without channel children

Version 2026.1.4 (2026-01-02)

What's Changed

Bug Fixes

  • Fix PingPong Unknown Issue Not Cleared: Unknown PONG mismatch issues are now properly cleared when conditions normalize

  • Previously, when unknown PONGs exceeded the threshold (15), a repair issue was created but never removed

  • Now a reset event (mismatch_count=0) is published when the count drops below the threshold
  • Matches the existing behavior for pending PING mismatches

  • Fix OperatingVoltageLevel Shows Unknown After Restart (Issue #2674): Battery parameters now load from cache on startup

  • Previously, parameters with ignore_on_initial_load=True (e.g., OPERATING_VOLTAGE, LOW_BAT) would remain "Unknown" after HA restart until the device was triggered
  • Now these parameters load from the persistent data cache while still skipping RPC calls to avoid waking battery devices
  • Calculated data points like OperatingVoltageLevel now show their cached values immediately after restart

Version 2026.1.3 (2026-01-02)

What's Changed

Bug Fixes

  • Fix PingPong Race Condition: Register ping token in tracker before sending the ping request

  • Previously, the CCU could respond with PONG before the token was registered, causing false "unknown PONG" counts

  • Now the token is tracked before await proxy.ping(), eliminating the race condition

  • Fix Week Profile ScheduleCondition: Extended ScheduleCondition enum with all 8 valid values

  • Added: FIXED_IF_BEFORE_ASTRO, ASTRO_IF_BEFORE_FIXED, FIXED_IF_AFTER_ASTRO, ASTRO_IF_AFTER_FIXED, EARLIEST_OF_FIXED_AND_ASTRO, LATEST_OF_FIXED_AND_ASTRO

  • Fixes ValueError: 7 is not a valid ScheduleCondition on HmIP-BROLL blinds with astro-based schedules
  • Added graceful fallback for unknown enum values in AstroType, TimeBase, and ScheduleCondition

  • Fix ClientJsonCCU Handler Initialization: ClientJsonCCU (used for CCU-Jack) now properly initializes handlers

  • Root cause: init_client() only initialized handlers when supports_rpc_callback=True, but CCU-Jack uses JSON-RPC exclusively
  • Added NullRpcProxy class - a lightweight proxy placeholder that doesn't create XML-RPC connections
  • ClientJsonCCU.init_client() now uses NullRpcProxy to satisfy handler initialization without wasting resources
  • Fixes AttributeError: 'ClientJsonCCU' object has no attribute '_device_ops_handler'

Version 2026.1.2 (2026-01-01)

What's Changed

Refactoring

  • Async DNS Resolution: get_ip_addr() now uses async loop.getaddrinfo() instead of blocking socket.gethostbyname()

  • Eliminates need for executor thread pool for DNS lookups

  • Direct await instead of async_add_executor_job() wrapper

  • Removed Dead Code: Removed unused shrink_json_file() function from support.py


Version 2026.1.1 (2026-01-01)

What's Changed

New Features

  • RPC Server Metrics: New rpc_server section in metrics aggregation

  • Tracks incoming requests from CCU to the XML-RPC callback server

  • RpcServerMetrics dataclass with: total_requests, total_errors, active_tasks, avg_latency_ms, max_latency_ms
  • Computed properties: error_rate, success_rate
  • Available via MetricsAggregator.rpc_server and included in MetricsSnapshot

  • Generic Metrics Serialization: MetricsSnapshot.to_dict() method for JSON-serializable output

  • Automatically converts all fields and computed @property values

  • Handles datetime → ISO format, float → rounded to 2 decimals, nested dataclasses → recursive conversion
  • Eliminates manual field mapping in diagnostics code

  • Generic Health Serialization: CentralHealth.to_dict() and ConnectionHealth.to_dict() methods

  • Same generic conversion as metrics: fields, properties, datetime, Enum → name

  • Nested client_health dict with per-client status automatically converted
  • Simplifies diagnostics and monitoring integration

  • Data Points by Category: New ModelMetrics.data_points_by_category field

  • Counts all data points grouped by DataPointCategory (SWITCH, SENSOR, CLIMATE, etc.)

  • Includes device data points, program data points, and sysvar data points
  • Available via MetricsAggregator.model.data_points_by_category and in MetricsSnapshot
  • Replaces manual counting logic in diagnostics code

  • Complete Cache Metrics: Full cache statistics in CacheMetrics

  • New SizeOnlyStats for registries/trackers (size only, no hit/miss semantics)
  • CacheStats reserved for true caches with hit/miss/eviction tracking
  • Registries: device_descriptions, paramset_descriptions, visibility_registry (size only)
  • Trackers: ping_pong_tracker, command_tracker (size and evictions only)
  • True caches: data_cache (size, hits, misses, evictions)
  • New CacheProviderForMetricsProtocol for centralized cache access

Bug Fixes

  • Race Condition in Device Creation: Fixed race condition between newDevices callback and startup code

  • Root cause: Startup code called check_for_new_device_addresses() while callback was still populating cache

  • Device creation now happens inside semaphore in _add_new_devices() to ensure all descriptions are cached first
  • New check_and_create_devices_from_cache() method for atomic check-and-create with semaphore protection
  • Startup code now uses atomic method to prevent racing with callbacks

  • Resilient Device Creation: Device creation no longer crashes when channel descriptions are missing

  • New DescriptionNotFoundException for specific error handling
  • Device.__init__ gracefully skips channels with missing descriptions and logs a warning
  • Device remains functional with available channels

Refactoring

  • Semantic Class Naming: Renamed classes to better reflect their actual purpose
  • CommandCacheCommandTracker (tracks sent commands, no hit/miss semantics)
  • PingPongCachePingPongTracker (tracks connection health, not a cache)
  • DeviceDescriptionCacheDeviceDescriptionRegistry (authoritative store, not a cache)
  • ParamsetDescriptionCacheParamsetDescriptionRegistry (authoritative store, not a cache)
  • ParameterVisibilityCacheParameterVisibilityRegistry (defines rules, memoization is implementation detail)
  • last_value_send_cachelast_value_send_tracker property on clients
  • CacheName enum reduced to DATA only (the actual cache with hit/miss semantics)
  • New TrackerStatistics for tracker-specific stats (evictions only, no hits/misses)
  • Removed CacheStatistics from ParameterVisibilityRegistry (deterministic rules don't need hit/miss tracking)

Version 2026.1.0 (2026-01-01)

What's Changed

New Features

  • Async XML-RPC Server (Experimental): New asyncio-native XML-RPC server using aiohttp

  • Enable via OptionalSettings.ASYNC_RPC_SERVER in CentralConfig.optional_settings

  • Alternative to the thread-based XML-RPC server for receiving callbacks from Homematic backend
  • Full support for system.multicall (batched events from CCU)
  • Fire-and-forget pattern for event processing (immediate response to backend)
  • Graceful shutdown with background task cancellation and 5s timeout
  • Health-check endpoint (GET /health) returning JSON with server status, request/error counts, active tasks
  • Metrics integration: rpc_server.request, rpc_server.error, rpc_server.latency, rpc_server.active_tasks
  • Singleton pattern per (ip_addr, port) combination
  • Comprehensive test coverage: 48 tests (41 unit, 4 integration, 3 stress)
  • Performance validated: >1,000 req/s throughput, <500ms average multicall response
  • See ADR 0012 for design rationale and performance benchmarks

  • Storage Abstraction Layer: New unified storage system for all persistent data

  • StorageProtocol and StorageFactoryProtocol interfaces for DuckTyping compatibility

  • Storage class with orjson serialization, atomic writes, ZIP loading, version migrations, delayed/debounced saves
  • LocalStorageFactory as default implementation for standalone usage
  • Enables Home Assistant to substitute its native Store via factory pattern
  • All persistent caches (DeviceDescriptionCache, ParamsetDescriptionCache, SessionRecorder) refactored to use Storage
  • CentralConfig.storage_factory field for dependency injection
  • cleanup_files() method for deleting all storage files
  • Configurable storage options: raw_mode (no metadata wrapper), formatted (indented JSON), as_zip (ZIP compression)

  • Device Definition Export: Single ZIP file export for device definitions

  • _DefinitionExporter now creates {model}.zip containing subdirectories
  • device_descriptions/{model}.json and paramset_descriptions/{model}.json inside ZIP
  • Formatted JSON output with indentation for readability

Code Quality

  • BasePersistentCache: New base class replacing BasePersistentFile with cleaner separation of concerns

Version 2025.12.55 (2025-12-30)

What's Changed

New Features

  • Fixed Color Light API: Expose fixed color utilities as public API for Home Assistant integration
  • FixedColor enum (previously _FixedColor) - available color names (WHITE, RED, YELLOW, etc.)
  • FIXED_COLOR_TO_HS mapping (previously _FIXED_COLOR_SWITCHER) - converts fixed colors to HS values
  • hs_color_to_fixed_converter() function (previously _convert_color()) - converts HS color to nearest fixed color

Code Quality

  • Package Structure Refactoring: Improved maintainability by splitting large __init__.py files

  • client/__init__.py (1793 → 105 lines): Moved client classes to dedicated modules

    • client/ccu.py: ClientCCU, ClientJsonCCU, ClientHomegear, ClientConfig
    • client/config.py: InterfaceConfig
  • model/hub/__init__.py (803 → 123 lines): Moved Hub class to dedicated module
    • model/hub/hub.py: Hub, ProgramDpType, MetricsDpType
  • All public APIs remain unchanged (re-exported from __init__.py)
  • Fixed circular imports by using direct submodule imports in metrics/aggregator.py and client/rpc_proxy.py

  • Export Validation: New linter script for validating __all__ exports

  • script/lint_all_exports.py: Validates exports are imported, grouped, and sorted

  • Ensures consistency across all package __init__.py files

  • Import Standardization: Enforce consistent package import conventions across the codebase

  • External consumers (tests, aiohomematic_test_support) must import public symbols from package __init__.py facades, not directly from submodules
  • Example: from aiohomematic.interfaces import ChannelProtocol instead of from aiohomematic.interfaces.model import ChannelProtocol
  • Added callback_backend_system and callback_event decorators to aiohomematic.central public API
  • New pre-commit hook lint-package-imports enforces these conventions
  • New linter script script/lint_package_imports.py with --all flag for checking internal imports

Version 2025.12.54 (2025-12-29)

What's Changed

Bug Fixes

  • ConnectionRecoveryCoordinator: Fixed JSON-RPC authentication failures during connection recovery

  • Added clear_json_rpc_session() method to Client class

  • Session is now cleared at recovery start to force re-authentication
  • Prevents "access denied" errors when CCU restarts and invalidates existing sessions

  • HubCoordinator: Fixed inbox data not being fetched during initialization

  • init_hub() now calls fetch_inbox_data(scheduled=False) alongside program/sysvar data

  • This ensures the inbox sensor is created at startup and HA receives the HUB_REFRESHED event
  • Previously, inbox data was only fetched by the scheduler after sys_scan_interval

  • EventCoordinator: Fixed DEVICES_DELAYED event not being forwarded to integrations

  • Added DeviceLifecycleEventType.DELAYED to the enum
  • Added interface_id field to DeviceLifecycleEvent for repair issue context
  • Added handler in publish_system_event() to emit DeviceLifecycleEvent with DELAYED type
  • This restores the repair issue flow for delayed device creation (broken since event migration in 2025.12.27)

New Features

  • Unified Connection Recovery Coordinator: New event-driven coordinator handling all connection recovery
  • Located in aiohomematic/central/connection_recovery.py
  • Replaces SelfHealingCoordinator, RecoveryCoordinator, and BackgroundScheduler recovery logic
  • Event-Driven Architecture: Subscribes to ConnectionLostEvent and CircuitBreakerTrippedEvent
  • Staged Recovery Process: TCP check → RPC check → Warmup → Stability check → Reconnect → Data load
  • Retry Management: Exponential backoff with max 8 attempts, heartbeat retry in FAILED state
  • Parallel Recovery: Throttled parallel recovery with semaphore (max 2 concurrent)
  • New Recovery Events:
    • ConnectionLostEvent: Emitted when connection is lost
    • RecoveryStageChangedEvent: Tracks recovery stage transitions
    • RecoveryAttemptedEvent: Records each recovery attempt
    • RecoveryCompletedEvent: Emitted on successful recovery
    • RecoveryFailedEvent: Emitted when max retries reached
    • HeartbeatTimerFiredEvent: Triggers heartbeat retries in FAILED state
  • New Enum: RecoveryStage with 12 stages (IDLE, DETECTING, COOLDOWN, TCP_CHECKING, etc.)

Internal Changes

  • CentralUnit: Removed old RecoveryCoordinator, added new ConnectionRecoveryCoordinator
  • MetricsAggregator: Removed unused recovery_coordinator parameter
  • BackgroundScheduler: Refactored to detection-only architecture
  • _check_connection now only detects connection issues and emits ConnectionLostEvent
  • Removed _handle_staged_reconnection, _load_data_with_retry, and related recovery methods (~350 LOC)
  • Removed json_rpc_client_provider parameter (no longer needed)
  • All recovery logic now handled by ConnectionRecoveryCoordinator
  • Removed deprecated files:
  • aiohomematic/central/self_healing.py
  • aiohomematic/central/recovery.py
  • aiohomematic/metrics/service.py
  • Removed deprecated exports from aiohomematic.metrics: record_service_call, get_service_stats, clear_service_stats
  • BaseParameterDataPoint: Renamed previous_value to last_non_default_value with changed semantics
  • Now stores only meaningful (non-default) values instead of the immediate previous value
  • Enables "restore last brightness" feature for dimmers - stores last non-zero level
  • Hub data points (sysvar, metrics, inbox) use separate caching for refresh/modify detection
  • Event Naming Improvements: Renamed events for better clarity and self-documentation
  • BackendParameterEventRpcParameterReceivedEvent (raw parameter from RPC callback)
  • DataPointUpdatedEventDataPointValueReceivedEvent (data point value received from backend)
  • DataPointStatusUpdatedEventDataPointStatusReceivedEvent (status parameter received from backend)
  • DataPointUpdatedCallbackEventDataPointStateChangedEvent (callback for state changes)
  • SysvarUpdatedEventSysvarStateChangedEvent (system variable state changed)
  • DeviceUpdatedEventDeviceStateChangedEvent (device state changed)
  • FirmwareUpdatedEventFirmwareStateChangedEvent (firmware state changed)
  • ConnectionStageEventConnectionStageChangedEvent (connection stage changed)
  • ConnectionHealthEventConnectionHealthChangedEvent (connection health changed)
  • HealthRecordEventHealthRecordedEvent (health status recorded)
  • RecoveryAttemptEventRecoveryAttemptedEvent (recovery attempt completed)
  • SystemStatusEventSystemStatusChangedEvent (system status changed)

Version 2025.12.53 (2025-12-28)

What's Changed

New Features

  • Event-Driven System Events: New events for comprehensive system observability

  • Connection Stage Events: ConnectionStageChangedEvent tracks reconnection progress through 5 stages (LOST → TCP_AVAILABLE → RPC_AVAILABLE → WARMUP → ESTABLISHED)

  • Connection Health Events: ConnectionHealthChangedEvent reports interface health status changes
  • Cache Invalidation Events: CacheInvalidatedEvent with CacheType and CacheInvalidationReason enums
  • Circuit Breaker Events: CircuitBreakerStateChangedEvent and CircuitBreakerTrippedEvent for state transitions
  • State Machine Events: ClientStateChangedEvent and CentralStateChangedEvent for state transitions
  • Data Refresh Events: DataRefreshTriggeredEvent and DataRefreshCompletedEvent for scheduler refresh operations
  • Program Events: ProgramExecutedEvent when programs are executed
  • Request Coalescer Events: RequestCoalescedEvent when requests are coalesced
  • Health Record Events: HealthRecordedEvent emitted by CircuitBreaker for success/failure tracking
  • New Enums in const.py: ConnectionStage, CacheType, CacheInvalidationReason

  • Complete Event-Driven Metrics Architecture: Full migration to event-based metrics collection

  • New aiohomematic/metrics/ Module: Independent metrics module (moved from central/)

    • keys.py: Type-safe metric keys with MetricKey dataclass and MetricKeys factory
    • events.py: MetricEvent hierarchy (LatencyMetricEvent, CounterMetricEvent, GaugeMetricEvent, HealthMetricEvent)
    • observer.py: MetricsObserver for event-driven aggregation with query API
    • emitter.py: Emission utilities (emit_latency, emit_counter, emit_gauge, emit_health)
    • stats.py: Consolidated stats classes (CacheStats, LatencyStats, ServiceStats)
  • Type-Safe Metric Keys: New MetricKey dataclass with MetricKeys factory for all known metrics
    • Pattern: {component}.{metric}.{identifier} (e.g., ping_pong.rtt.hmip_rf)
    • Factory methods: MetricKeys.ping_pong_rtt(), cache_hit(), cache_miss(), client_health(), self_healing_*(), etc.
  • Component Migration to Emit-Only Pattern:
    • PingPongCache: Removed local _latency_stats, now emits via MetricKeys.ping_pong_rtt()
    • CentralDataCache: Removed local _stats, now emits via MetricKeys.cache_hit/miss()
    • CircuitBreaker: Emits counters via MetricKeys.circuit_success/failure/rejection()
    • @inspector: Emits latency/errors via MetricKeys.service_call/error() (no more global registry)
    • HealthTracker: Emits HealthMetricEvent via MetricKeys.client_health()
    • SelfHealingCoordinator: Emits counters via MetricKeys.self_healing_trip/recovery/refresh_success/refresh_failure()
  • MetricsAggregator Integration: Now queries MetricsObserver for latency and cache metrics
    • Latency: Aggregates from ping_pong.rtt.* pattern
    • Cache: Gets hit/miss counters from observer
  • EventMetrics.health_records: New counter tracking HealthRecordedEvent emissions from CircuitBreaker

  • SelfHealingCoordinator: New coordinator for automatic recovery based on circuit breaker events

  • Located in aiohomematic/central/self_healing.py

  • Subscribes to CircuitBreakerTrippedEvent and CircuitBreakerStateChangedEvent
  • Triggers data refresh when circuit breaker recovers (HALF_OPEN → CLOSED)
  • Emits SelfHealingTriggeredEvent and SelfHealingDataRefreshEvent for observability
  • New Metric Emissions: Emits counter metrics via emit_counter():

    • MetricKeys.self_healing_trip(): When circuit breaker trips
    • MetricKeys.self_healing_recovery(): When circuit breaker recovers
    • MetricKeys.self_healing_refresh_success(): When data refresh succeeds
    • MetricKeys.self_healing_refresh_failure(): When data refresh fails
  • Self-Healing Events: New events in aiohomematic/metrics/events.py

  • SelfHealingTriggeredEvent: Emitted when self-healing reacts to circuit breaker events (actions: "trip_logged", "recovery_initiated")

  • SelfHealingDataRefreshEvent: Emitted after data refresh completes with success/failure status
  • SELF_HEALING_EVENT_TYPES tuple for subscription convenience

  • EventDrivenMockServer: New test infrastructure for event-driven test orchestration

  • Located in aiohomematic_test_support/event_mock.py

  • Provides fluent API for configuring responses to events: mock_server.when(event_type=SomeEvent).then_call(handler=...)
  • Supports filtering with .matching(filter_fn=...) and one-shot responses with .once()
  • Supports chained event publishing with .then_publish(event_factory=...)
  • Tracks invocation counts for verification

  • Event-Driven Cache Invalidation: Decoupled device removal from cache management

  • DeviceRemovedEvent now includes device_address, interface_id, and channel_addresses for device-level removal

  • CacheCoordinator subscribes to DeviceRemovedEvent and invalidates caches automatically
  • DeviceCoordinator.remove_device() no longer calls CacheCoordinator.remove_device_from_caches() directly
  • Improved architecture: device lifecycle and cache management are now decoupled via EventBus

  • Event-Driven Test Verification Patterns: New test infrastructure demonstrating event-based testing

  • Located in tests/test_event_driven_verification.py
  • Section 3.1: Circuit breaker tests using events instead of internal state inspection
    • test_circuit_breaker_trips_emits_event: Verify trip via CircuitBreakerTrippedEvent
    • test_circuit_breaker_recovery_emits_state_change: Verify full recovery cycle via state change events
    • test_half_open_failure_reopens_circuit_via_events: Verify re-trip behavior via events
  • Section 3.2: Integration test patterns using events
    • test_event_sequence_verification: Verify event ordering with EventSequenceAssertion
    • test_data_refresh_events_integration: Verify refresh cycle via DataRefreshTriggeredEvent/DataRefreshCompletedEvent
    • test_no_events_assertion: Verify no events emitted using assert_no_event()
  • Section 3.3: Performance and timing tests using events
    • test_coalescing_effectiveness: Verify request coalescing via RequestCoalescedEvent
    • test_coalescing_with_different_keys: Verify no coalescing for different keys
    • test_coalescing_reports_correct_interface: Verify correct interface_id in events

Breaking Changes

  • CentralUnit.metrics now returns MetricsObserver (event-driven) instead of MetricsAggregator (polling-based)
  • Use central.metrics_aggregator for polling-based detailed diagnostics
  • Hub sensors parameter changed: Use metrics_observer= instead of metrics_aggregator=
  • Import paths changed: from aiohomematic.metrics import MetricsObserver, emit_latency, MetricKeys
  • CentralDataCache requires event_bus_provider: New mandatory parameter for event emission
  • CacheCoordinator requires event_bus_provider: New mandatory parameter passed to CentralDataCache
  • Removed PingPongCache.latency_stats: Use MetricsObserver instead
  • Removed CentralDataCache.stats: Use MetricsObserver counters instead (new .size property for entry count)
  • CircuitBreaker now accepts optional event_bus: New optional parameter for metric event emission
  • Service registry removed: record_service_call, get_service_stats, clear_service_stats (deprecated in 2025.12.53) removed; use MetricsObserver instead
  • ClientStateMachine now accepts optional event_bus: New optional parameter for ClientStateChangedEvent emission
  • RequestCoalescer now accepts optional event_bus and interface_id: New optional parameters for RequestCoalescedEvent emission
  • ClientCoordinator now requires event_bus_provider: New mandatory parameter for subscribing to HealthRecordedEvent
  • Removed HealthRecordCallbackProtocol: The callback-based health recording pattern is replaced by EventBus
  • Removed health_record_callback parameter: Removed from ClientConfig, ClientFactoryProtocol.create_client_instance(), BaseRpcProxy, AioXmlRpcProxy, and AioJsonRpcAioHttpClient
  • CircuitBreaker emits HealthRecordedEvent: Now publishes health status via EventBus instead of invoking a callback
  • Removed CentralStateMachine.on_state_change callback: Use EventBus subscription to CentralStateChangedEvent instead
  • Removed ClientStateMachine.on_state_change callback: Use EventBus subscription to ClientStateChangedEvent instead
  • Removed StateChangeCallbackProtocol: The callback protocol is no longer needed; use EventBus subscriptions
  • DeviceRemovedEvent signature changed: Now includes device_address, interface_id, channel_addresses with defaults for backward compatibility
  • CacheCoordinator now subscribes to DeviceRemovedEvent: Call cache_coordinator.stop() to unsubscribe on shutdown

Test Improvements

  • Migrate tests to use public API instead of internal state: Tests now use public properties and event-based verification
  • Circuit Breaker: Using event_capture fixture with CircuitBreakerStateChangedEvent and CircuitBreakerTrippedEvent
  • Request Coalescer: Using event_capture fixture with RequestCoalescedEvent for coalescing verification
  • Central Caches: Using event_capture fixture with CacheInvalidatedEvent for cache clear verification
  • Client Coordinator: Using has_clients, clients_started, primary_client properties
  • Event Coordinator: Using event_bus property and get_last_event_seen_for_interface() method
  • Background Scheduler: Using is_active, devices_created properties
  • Cover Models: Removed redundant _group_level checks where current_position verifies the same behavior

Version 2025.12.52 (2025-12-27)

What's Changed

Bug Fixes

  • Fix health score not reaching 100%: JSON-RPC client was using URL instead of interface_id for health tracking, causing last_successful_request to never be recorded. Now uses primary client's interface_id for proper health attribution.
  • Fix HealthMetrics.last_event_time always showing epoch: The last_event_time field was never populated in MetricsAggregator.health. Now correctly aggregates the most recent event time across all clients.
  • Fix connection latency always showing 0.0 ms: latency_tracker only tracked paramset description requests which rarely executed. Now uses ping/pong round-trip time for accurate latency measurement via PingPongCache.latency_stats.
  • Fix test mock returning _Method instead of CircuitBreakerMetrics: Added proper circuit_breaker property to _AioXmlRpcProxyFromSession mock to return real CircuitBreaker instance.

Version 2025.12.51 (2025-12-27)

What's Changed

New Features

  • Add metrics hub sensors for Home Assistant: Three new hub sensors exposing key system metrics
  • System Health (HmSystemHealthSensor): Overall system health score (0-100%)
  • Connection Latency (HmConnectionLatencySensor): Average RPC connection latency in ms
  • Last Event Age (HmLastEventAgeSensor): Seconds since last backend event
  • Sensors are accessible via hub.metrics_dps (returns MetricsDpType)
  • Automatically initialized during init_hub() and published via HUB_REFRESHED event
  • Scheduled refresh every 60 seconds (configurable via ScheduleTimerConfig.metrics_refresh_interval)

API Changes

  • Added MetricsProviderProtocol interface for accessing the MetricsAggregator
  • HubCoordinator now requires metrics_provider parameter
  • New Hub methods: create_metrics_dps(), fetch_metrics_data(), init_metrics(), publish_metrics_refreshed()

Version 2025.12.50 (2025-12-27)

What's Changed

Code Quality

  • Enforce keyword-only parameters for module-level functions: Extended lint_kwonly.py to enforce keyword-only parameters consistently across the codebase
  • Class methods: * must come after self/cls
  • Module-level functions: * must come before the first argument
  • Fixed 109+ function signatures to comply with the new rules
  • Added # kwonly: disable annotations for callbacks, decorators, and voluptuous validators where positional args are required

Version 2025.12.49 (2025-12-27)

What's Changed

New Features

  • Add MetricsAggregator for unified observability: New centralized metrics system providing a single access point for all runtime statistics
  • Access via CentralUnit.metrics property (DelegatedProperty pattern)
  • snapshot() method returns immutable MetricsSnapshot with all metrics at a point in time
  • 7 metric categories: RPC, Events, Cache, Health, Recovery, Model, Services

Metrics Categories

  • RPC Metrics (RpcMetrics):

  • success_rate, failure_rate, coalesce_rate, rejection_rate (percentages)

  • avg_latency_ms, max_latency_ms from RequestCoalescer
  • Aggregated from all clients' circuit breakers and coalescers

  • Event Metrics (EventMetrics):

  • events_published, handlers_executed, handler_errors

  • avg_handler_duration_ms, max_handler_duration_ms
  • Handler duration tracking via time.perf_counter() for high precision

  • Cache Metrics (CacheMetrics):

  • overall_hit_rate across all caches

  • total_entries count
  • Per-cache CacheStats: device_descriptions, paramset_descriptions, data_cache, command_cache, ping_pong_cache, visibility_cache

  • Health Metrics (HealthMetrics):

  • clients_total, clients_healthy, clients_unhealthy

  • availability_rate percentage
  • overall_health_score from CentralHealthTracker

  • Recovery Metrics (RecoveryMetrics):

  • attempts_total, successes, failures

  • success_rate percentage
  • Placeholder for future RecoveryCoordinator integration

  • Model Metrics (ModelMetrics):

  • devices_count, channels_count, data_points_count

  • hub_programs_count, hub_sysvars_count

  • Service Metrics (ServiceMetrics):

  • total_calls, total_errors, avg_duration_ms, max_duration_ms
  • by_method: Per-method breakdown with ServiceStats
  • Multi-Central isolation via global registry keyed by (central_name, method_name)
  • Integrated with @inspector(measure_performance=True) decorator

Internal

  • EventBus: Add HandlerStats dataclass and get_handler_stats() method for handler execution tracking
  • EventBus: Track handler duration, execution count, and error count in _safe_call_handler()
  • RequestCoalescer: Add LatencyStats dataclass with record() and reset() methods
  • RequestCoalescer: Track latency (min, max, avg, count, total) during request execution
  • CentralDataCache: Add CacheStats tracking (hits, misses, size) via stats property
  • DeviceHandler: Expose paramset_description_coalescer property for metrics access
  • @inspector decorator: Record service call metrics when measure_performance=True
  • Extracts central_name from context_obj._central_info.name
  • Records duration and error status to global registry
  • Thread-safe via threading.Lock
  • Documentation: Update architecture review with metrics implementation status

Tests

  • Add tests/test_metrics.py with 38 tests covering all metric dataclasses, service stats, and integration

Version 2025.12.48 (2025-12-26)

What's Changed

Bug Fixes

  • Fix HmIP-WRCD display not updating: Replace poorly documented COMBINED_PARAMETER with individual data point calls for reliable display updates
  • Fix HmIP-WRCD sound not playing: Sound parameters (INTERVAL, REPETITIONS) now correctly sent via put_paramset
  • Fix conversion error for empty numeric values: Handle empty strings from CCU for FLOAT/INTEGER parameters gracefully (e.g., LEVEL_2 for devices without slats)
  • Fix CustomDpCover.is_closed return type: Change from bool | None to bool (method always returns bool)
  • Fix cover/dimmer is_valid returning False after restart: Treat UNKNOWN status as valid for is_valid check (GitHub Issue #2630)
  • When CCU sends *_STATUS = UNKNOWN during startup, entities now correctly report valid state
  • Previously, is_valid returned False, causing Home Assistant to use stale cached values

Improvements

  • HmIP-WRCD: Rewrite send_text() to use individual data points instead of COMBINED_PARAMETER
  • Uses put_paramset with all display parameters for atomic updates
  • DISPLAY_DATA_COMMIT=True triggers the display update at the end
  • More reliable and easier to debug
  • HmIP-WRCD: Extend display_id range from 1-3 to 1-5 (device supports 5 display lines)
  • HmIP-WRCD: Add interval parameter to TextDisplayArgs for controlling sound tone intervals (1-15)
  • HmIP-WRCD: Expose burst_limit_warning property and log warning in send_text() when active
  • HmIP-WRCD: Support repeat=-1 for INFINITE_REPETITIONS
  • HmIP-MP3P: Change repetitions parameter from string to int for simpler API
  • 0 = no repetition, 1-14 = repetition count, -1 = infinite
  • Automatic conversion to device VALUE_LIST strings (REPETITIONS_XXX format)
  • HmIP-MP3P: Remove available_repetitions property (no longer needed with int-based API)

Internal

  • ProfileConfig: Add fixed_channel_fields / visible_fixed_channel_fields to ChannelGroupConfig
  • Allows defining fields with absolute channel numbers (not rebased relative to group_no)
  • Useful for device-wide parameters on channel 0
  • ProfileConfig: Rename repeating_fieldsfields, visible_repeating_fieldsvisible_fields for clarity
  • ProfileConfig: Rename RebasedChannelGroupRebasedChannelGroupConfig for consistency
  • ProfileConfig: Add comprehensive documentation for relative vs absolute channel numbers
  • IP_TEXT_DISPLAY: Add new fields to profile config (DISPLAY_DATA_COMMIT, DISPLAY_DATA_ID, DISPLAY_DATA_STRING, INTERVAL)
  • Visibility Rules: Un-ignore DISPLAY_DATA_COMMIT, DISPLAY_DATA_ID, DISPLAY_DATA_STRING, INTERVAL for HmIP-WRCD

Version 2025.12.47 (2025-12-25)

What's Changed

New Features

  • Add HmIP-MP3P (Combined signal generator) support: Implement sound player and LED control for combination signaling devices
  • Sound Player (CustomDpSoundPlayer in siren.py, channel 2):
    • Inherits from BaseCustomDpSiren for siren integration
    • play_sound() method with volume, soundfile, duration, repetitions, ramp time parameters
    • stop_sound() method to stop playback
    • _convert_soundfile_index() helper for integer-to-soundfile-name conversion (1-189)
    • Exposes available options via DelegatedProperty from ActionSelect VALUE_LISTs
  • LED Control (CustomDpSoundPlayerLed in light.py, channel 6):
    • Inherits from CustomDpDimmer for dimmer integration
    • set_led() method with color, brightness, on_time, duration, repetitions parameters
    • turn_off() method to turn off LED
    • Exposes available colors, on times, repetitions via DelegatedProperty
  • New DeviceProfile.IP_SOUND_PLAYER and DeviceProfile.IP_SOUND_PLAYER_LED profiles
  • Category-specific translation keys for validation messages

Version 2025.12.46 (2025-12-25)

What's Changed

New Features

  • Add HmIP-WRCD (Wall-mount Remote Control with Display) support: Implement CustomDpTextDisplay custom data point for devices with LCD displays
  • New DataPointCategory.TEXT_DISPLAY and DeviceProfile.IP_TEXT_DISPLAY
  • send_text() method to display text with configurable icon, colors, alignment, and optional sound
  • Expose display parameters as ActionSelects: DISPLAY_DATA_ICON, DISPLAY_DATA_BACKGROUND_COLOR, DISPLAY_DATA_TEXT_COLOR, DISPLAY_DATA_ALIGNMENT, ACOUSTIC_NOTIFICATION_SELECTION
  • Uses COMBINED_PARAMETER format for efficient multi-parameter updates

Version 2025.12.45 (2025-12-24)

What's Changed

Improvements

  • Restructure store package into organized sub-packages: Split monolithic cache files into focused modules

  • New store/persistent/ package: Base class, device cache, paramset cache, session recorder

  • New store/dynamic/ package: Command cache, device details, central data, ping-pong cache
  • New store/visibility/ package: Visibility rules, parser, and cache
  • New store/types.py: Shared type definitions (CachedCommand, PongTracker, type aliases)
  • New store/serialization.py: freeze_params/unfreeze_params utilities for session recording

  • Add typed cache entries for better type safety:

  • CachedCommand dataclass replaces tuple[Any, datetime] in CommandCache

  • PongTracker dataclass with tokens, seen_at, logged fields for PingPongCache
  • Type aliases: InterfaceParamsetMap, ChannelParamsetMap, ParamsetMap, ParameterMap

  • Reduce code duplication in PingPongCache:

  • Single _cleanup_tracker() method replaces duplicate _cleanup_pending_pongs() and _cleanup_unknown_pongs()

  • PongTracker.contains() method for token membership checks

  • Refactor ParameterVisibilityCache for improved clarity and maintainability: Major restructuring of the visibility module

  • Extract static visibility rules to new visibility_rules.py module (~300 lines of constants)

  • Add typed cache keys using NamedTuple (IgnoreCacheKey, UnIgnoreCacheKey) for better type safety
  • Add UnIgnoreEntry dataclass for parsed configuration entries
  • Replace nested defaultdict structures with dedicated ChannelParamsetRules and ModelRules classes
  • Refactor _get_un_ignore_line_details from 75+ lines of string splits to regex-based parse_un_ignore_line function with ParsedUnIgnoreLine result type
  • Add invalidate_all_caches() method for complete cache reset
  • Improve code organization with clear section separators and better method grouping

  • Enhance sort_class_members.py for property assignments: Improved handling of property-like class attributes

  • Support DelegatedProperty with ast.AnnAssign (annotated assignments like name: Final = DelegatedProperty[...]())

  • Sort _GenericProperty assignments to the end of classes (ensures referenced methods are already defined)
  • Added GENERIC_PROPERTY group constant for proper ordering

  • Add DP006 validation to lint-delegated-property: Reports when DelegatedProperty(cached=True) is used without the required _cached_{property_name} slot

Version 2025.12.44 (2025-12-23)

What's Changed

Improvements

  • Add Context Variables pattern for request tracking and tracing: Implement contextvars-based context propagation for async call chains

  • RequestContext dataclass with request ID, operation, device address, and timing

  • request_context context manager for scoped context setting
  • ContextualLoggerAdapter for automatic request ID prefixing in log messages
  • RequestContextFilter for structured logging with context fields
  • Span and span context manager for performance tracing with parent-child relationships
  • Automatic context propagation through async call chains
  • 42 tests covering all context functionality

  • Add DP004/DP005 validation to lint-delegated-property: The linter now validates property paths and cache slots

  • DP004 error: Reports when DelegatedProperty path references an attribute not defined in __slots__, __init__, class-level assignments, or @property

  • DP005 error: Reports when @hm_property(cached=True) is used on a slotted class without the required _cached_{property_name} slot
  • Enhanced AST visitor to detect DelegatedProperty in annotated assignments (e.g., name: Final = DelegatedProperty[...])
  • Enhanced AST visitor to detect @hm_property(cached=True) and similar decorators
  • Tracks class-level plain assignments (e.g., _enabled_default = True)
  • Validates path resolution and cache slots across class inheritance hierarchy

  • Replace IN_SERVICE_VAR with RequestContext: Unified service call tracking through the new context variables pattern

  • Removed standalone IN_SERVICE_VAR: ContextVar[bool] in favor of RequestContext

  • Added is_in_service() helper that checks for operation.startswith("service:")
  • @inspector decorator now creates RequestContext(operation="service:{func_name}") for service calls
  • @bind_collector decorator uses the same pattern for consistent context propagation
  • Breaking: IN_SERVICE_VAR is no longer exported from aiohomematic.context

  • Add CentralConfigBuilder for fluent configuration: Implement Builder Pattern for CentralConfig with step-by-step configuration and validation

  • CentralConfigBuilder class with fluent method chaining (.with_name(), .with_host(), .add_hmip_interface(), etc.)

  • Factory presets: CentralConfigBuilder.for_ccu() and CentralConfigBuilder.for_homegear()
  • Early validation via .validate() method returning list of ValidationError
  • Automatic interface port resolution based on TLS settings
  • 36 tests covering all builder functionality

  • Introduce singledispatch pattern for type converters: Added extensible type conversion using Python's functools.singledispatch

  • New to_homematic_value() converter: Python types → Homematic-compatible values (bool→int, float→rounded, datetime→ISO, timedelta→seconds, Enum→value, list/dict→recursive)

  • New from_homematic_value() converter: Homematic values → Python types with optional target_type hints
  • Refactored _get_text_value() in property_decorators.py to use singledispatch
  • Both converters are extensible via @converter.register(YourType)

  • Make data point protocols generic for improved type safety: Protocols now preserve generic type information for mypy

  • BaseParameterDataPointProtocol[ParameterT] - properties like default, max, min, previous_value, value now return ParameterT instead of Any

  • GenericDataPointProtocol[ParameterT] - extends base protocol with typed value handling
  • Added type aliases for heterogeneous collections: BaseParameterDataPointProtocolAny, GenericDataPointProtocolAny, GenericEventProtocolAny

  • Fix property decorators to preserve generic type information for mypy: The value property on data points now correctly infers types (e.g., DpSwitch.valuebool | None, DpSensor[float].valuefloat | None)

  • Changed BaseParameterDataPoint.value from @state_property decorator to explicit _GenericProperty construction with kind=Kind.STATE

  • Added __get__ overloads to _GenericProperty for proper type inference
  • Exported Kind and _GenericProperty from property_decorators.py
  • Subclasses override _get_value() method for custom value reading logic

  • Refactor CustomDataPoint to use DataPointField descriptor: Declarative field definitions replace imperative _init_data_point_fields()

  • DataPointField now uses keyword-only __init__ parameters

  • Eliminated _init_data_point_fields() method from CustomDataPoint base class
  • Applied DataPointField pattern to all custom data point classes (climate, cover, light, lock, siren, switch, valve)
  • Subclasses use _post_init() for additional initialization after field resolution

  • Add CalculatedDataPointField descriptor for calculated data points: Mirrors the DataPointField descriptor pattern from custom data points

  • New file aiohomematic/model/calculated/field.py with CalculatedDataPointField descriptor

  • Changed CalculatedDataPoint._data_points from list to dict for O(1) lookup by (parameter, paramset_key) key
  • Added _resolve_data_point() method for lazy data point resolution with subscription handling
  • Added fallback_parameters support for trying alternative parameters (e.g., TEMPERATUREACTUAL_TEMPERATURE)
  • Added use_device_fallback support for trying device address (channel 0) if not found on current channel
  • Refactored BaseClimateSensor, ApparentTemperature, and OperatingVoltageLevel to use declarative field descriptors

  • Optimize field descriptors: Removed unused _attr_name slot and __set_name__ method from DataPointField and CalculatedDataPointField

  • Require explicit cache slots for cached properties: Removed WeakKeyDictionary fallback from both @hm_property(cached=True) and DelegatedProperty(cached=True) in favor of explicit slot definitions

  • Both decorators now validate at class-definition time that _cached_{property_name} exists in __slots__

  • TypeError is raised immediately when class is defined if cache slot is missing (not at runtime)
  • Added cache slots to Channel (_cached_group_master, _cached_group_no, _cached_is_in_multi_group)
  • Added cache slot to CalculatedDataPoint (_cached_dpk)
  • DP005 linter rule validates cache slots exist (see lint-delegated-property changes above)
  • Breaking: Classes that previously relied on WeakKeyDictionary fallback must add explicit slots

  • Add DelegatedProperty descriptor: New descriptor for delegating property access to nested attribute paths

  • Supports kind (config/info/state/simple) for categorization via get_hm_property_by_kind()
  • Supports cached=True for per-instance caching of delegated values (requires explicit _cached_{name} slot)
  • Supports log_context=True for structured logging
  • Migrated 266 simple delegation properties across the codebase to use DelegatedProperty
  • Note: Cannot be used when subclasses override with @property due to mypy limitations

Version 2025.12.43 (2025-12-22)

What's Changed

Improvements

  • Make ACOUSTIC_ALARM_SELECTION and OPTICAL_ALARM_SELECTION visible: These siren parameters are now exposed as entities
  • Enhance siren.turn_on service: Now uses values from ACOUSTIC_ALARM_SELECTION and OPTICAL_ALARM_SELECTION entities as fallback when not provided in service call
  • DpActionSelect value setter uses write_value: Keeps history clean and fires update events when value is set

Version 2025.12.42 (2025-12-21)

What's Changed

New Features

  • Introduce DpActionSelect data point type: New category for write-only ENUM parameters with VALUE_LIST
  • Provides a value getter to read the current selection (unlike DpAction which is write-only)
  • Automatically created by factory for write-only parameters with VALUE_LIST
  • New category: DataPointCategory.ACTION_SELECT
  • Located in aiohomematic/model/generic/action_select.py

Bug Fixes

  • Fix custom data point type annotations: Verified all custom data point types against pydevccu paramset descriptions

  • cover.py: Changed _dp_section from DpSensor[str | None] to DpSensor[int | None] (SECTION is INTEGER 0-15, not STRING)

  • Update custom data points to use DpActionSelect: Parameters with VALUE_LIST now correctly use DpActionSelect instead of DpAction

  • siren.py: ACOUSTIC_ALARM_SELECTION, OPTICAL_ALARM_SELECTION, DURATION_UNIT, SMOKE_DETECTOR_COMMAND
  • lock.py: LOCK_TARGET_LEVEL
  • light.py: ON_TIME_UNIT, EFFECT, RAMP_TIME_TO_OFF_UNIT, RAMP_TIME_UNIT
  • cover.py: DOOR_COMMAND

Documentation

  • Fix documentation accuracy across all docs/*.md files: Updated stale references after recent refactoring
  • Fixed directory references: caches/store/
  • Fixed file references: xml_rpc_server.pyrpc_server.py, xml_rpc.pyrpc_proxy.py
  • Fixed class names: XmlRpcProxyAioXmlRpcProxy
  • Removed non-existent event types: BackendSystemEventData, HomematicEvent, InterfaceEvent, CentralStateChangedEvent, ClientStateChangedEvent
  • Added correct event types from event_bus.py and integration_events.py
  • Fixed method signatures in examples to use keyword-only arguments
  • Updated docs/unignore.md path reference
  • Updated docs/homematicip_local_api_usage.md event references
  • Add documentation maintenance instructions to CLAUDE.md: New section for verifying docs/*.md accuracy after refactoring

Version 2025.12.41 (2025-12-20)

What's Changed

Breaking Changes

  • Rename EventType to DeviceTriggerEventType: Clearer naming for device trigger events
  • EventTypeDeviceTriggerEventType in aiohomematic.const
  • Affects: DEVICE_ERROR, IMPULSE, KEYPRESS event types
  • Update imports: from aiohomematic.const import DeviceTriggerEventType

Bug Fixes

  • Fix update_status to accept integer values from backend: Backend sends integer indices for STATUS parameters
  • update_status now accepts both int (backend index) and str (enum value)
  • Integer indices are converted to strings using the cached VALUE_LIST from the status parameter's paramset description
  • This ensures correct mapping regardless of ParameterStatus enum order
  • DataPointStatusReceivedEvent.status_value type is int | str

Version 2025.12.40 (2025-12-20)

What's Changed

Bug Fixes

  • Change ParameterStatus from IntEnum to StrEnum: Align enum with actual HmIP parameter values
  • All *_STATUS ENUM parameters (LEVEL_STATUS, ACTUAL_TEMPERATURE_STATUS, etc.) use string-based VALUE_LISTs
  • Values: NORMAL, UNKNOWN, OVERFLOW, UNDERFLOW, ERROR, INVALID, UNUSED
  • DataPointStatusReceivedEvent.status_value type changed to str

Version 2025.12.38 (2025-12-20)

What's Changed

Bug Fixes

  • Fix ENUM parameter handling for HmIP devices: Properly detect and handle string-based ENUMs vs index-based ENUMs
  • Root cause: HM devices use integer MIN/MAX/DEFAULT for ENUMs (send as index), while HmIP devices use string MIN/MAX/DEFAULT (send as string value)
  • Added _enum_value_is_index detection based on isinstance(MIN, int) in BaseParameterDataPoint
  • Updated DpAction and DpSelect to send string values for HmIP devices
  • Affects all ENUM parameters on HmIP devices including:
    • Time units: RAMP_TIME_UNIT, DURATION_UNIT, ON_TIME_UNIT (now "S", "M", "H" instead of 0, 1, 2)
    • Lock commands: LOCK_TARGET_LEVEL (now "LOCKED", "UNLOCKED", "OPEN")
    • Garage commands: DOOR_COMMAND (now "OPEN", "CLOSE", "STOP", "PARTIAL_OPEN")
    • Siren alarms: ACOUSTIC_ALARM_SELECTION, OPTICAL_ALARM_SELECTION, SMOKE_DETECTOR_COMMAND
    • Light effects: COLOR, COLOR_BEHAVIOUR
  • Resolves issues with HmIP-RGBW, HmIP-LSC, HmIP-BSL, HmIP-DRG-DALI, HmIPW-WRC6, and other HmIP devices

Version 2025.12.37 (2025-12-19)

What's Changed

Improvements

  • Recovery now uses actual client failure reasons: RecoveryCoordinator now queries client state machines for actual failure reasons instead of using FailureReason.UNKNOWN for all degraded interfaces
  • XML-RPC server binding failure now includes failure reason: OSError during XML-RPC server startup now passes FailureReason.INTERNAL

Version 2025.12.36 (2025-12-19)

What's Changed

New Features

  • Add degraded_interfaces tracking for DEGRADED state: Show which interfaces are degraded and why
  • New degraded_interfaces property on CentralStateMachine: Mapping[str, FailureReason]
  • New degraded_interfaces field on SystemStatusChangedEvent for integration consumption
  • Updated transition_to() method with degraded_interfaces parameter
  • Log output now shows interface-specific failure reasons: [interfaces: HmIP-RF=network, BidCos-RF=auth]
  • Integration benefit: Home Assistant can now show detailed status per interface in DEGRADED state
  • See docs/migrations/failure_reason_migration_2025_12.md for usage examples

Improvements

  • Recovery max-retries now propagates failure info: When recovery fails after max retries, the FAILED transition now includes failure_reason and failure_interface_id

Version 2025.12.35 (2025-12-19)

What's Changed

Improvements

  • Complete FailureReason propagation from client to central: Fix failure reason not being propagated when client creation fails
  • ClientCoordinator now tracks last_failure_reason and last_failure_interface_id from failed client creation attempts
  • Central state machine now receives failure info when transitioning to FAILED state
  • Added ClientStateMachineProtocol for type-safe access to client state machine properties
  • Added state_machine property to ClientProtocol for accessing client state machine
  • Before: Log showed [reason=none] even for authentication failures
  • After: Log correctly shows [reason=auth] for authentication failures, [reason=network] for network issues, etc.
  • Updated migration documentation with full propagation path

Version 2025.12.34 (2025-12-19)

What's Changed

New Features

  • Add FailureReason support for state machines: Enable differentiation between failure types when Central or Client enters FAILED state
  • New FailureReason enum with values: NONE, AUTH, NETWORK, INTERNAL, TIMEOUT, CIRCUIT_BREAKER, UNKNOWN
  • Extended ClientStateMachine with failure_reason, failure_message properties
  • Extended CentralStateMachine with failure_reason, failure_message, failure_interface_id properties
  • Extended SystemStatusChangedEvent with failure_reason and failure_interface_id fields
  • New helper function exception_to_failure_reason() for mapping exceptions to failure reasons
  • Integration benefit: Home Assistant can now show specific error messages (e.g., "Check your credentials" for auth failures vs "Check network connection" for network errors)
  • See docs/migrations/failure_reason_migration_2025_12.md for migration guide

Version 2025.12.33 (2025-12-17)

What's Changed

Breaking Changes

  • Consolidate scheduler intervals in ScheduleTimerConfig: Centralized all scheduler-related intervals and timeouts
  • Introduced new ScheduleTimerConfig class (similar to TimeoutConfig)
  • Moved from CentralConfig:
    • periodic_refresh_interval (default: 15s)
    • sys_scan_interval (default: 30s)
  • Moved from TimeoutConfig:
    • connection_checker_interval (default: 15s)
  • Added to ScheduleTimerConfig:
    • device_firmware_check_interval (default: 6h)
    • device_firmware_delivering_check_interval (default: 1h)
    • device_firmware_updating_check_interval (default: 5m)
    • system_update_check_interval (default: 4h)
    • system_update_progress_check_interval (default: 30s)
    • system_update_progress_timeout (default: 30min)

Improvements

  • Refactor get_system_update_info.fn script: Simplified and optimized firmware update check script
  • Simplified version parsing using shell pipeline (grep | tr | cut)
  • Streamlined exit code handling (exit codes: 0 = no update, 1 = update available, >4 = error/script unavailable)
  • Simplified available version extraction from checkFirmwareUpdate.sh output
  • Removed complex validation logic while maintaining functionality
  • Co-Authored-By: @Baxxy13

Version 2025.12.32 (2025-12-16)

What's Changed

Breaking Changes

  • Refactor Simple Schedule Format: Complete overhaul of simple schedule data structures used by climate thermostats
  • Old format: Tuple-based (base_temperature, [periods]) with ScheduleSlotType enum keys
  • New format: TypedDict-based with lowercase string keys (e.g., "starttime", "endtime", "temperature")
  • Replaces:
    • CLIMATE_SIMPLE_WEEKDAY_DATASimpleWeekdaySchedule TypedDict
    • CLIMATE_SIMPLE_PROFILE_DICTSimpleProfileSchedule type alias
    • CLIMATE_SIMPLE_SCHEDULE_DICTSimpleScheduleDict type alias
  • New TypedDict class: SimpleSchedulePeriod for individual schedule periods
  • Benefits:
    • ✅ Full JSON serialization support (enables Home Assistant custom cards)
    • ✅ Better type safety with TypedDict
    • ✅ Cleaner, more intuitive API with string keys
    • ✅ Reduced memory overhead (no enum objects)
  • Migration required: See docs/migrations/simple_schedule_migration_2025_12.md for step-by-step guide
  • Updated method signatures:
    • ClimateWeekProfile.get_schedule_simple_weekday() returns SimpleWeekdaySchedule
    • ClimateWeekProfile.set_simple_weekday() accepts SimpleWeekdaySchedule
    • ClimateWeekProfile.get_schedule_simple_profile() returns SimpleProfileSchedule
    • CustomDpClimate.set_simple_schedule_weekday() accepts SimpleWeekdaySchedule

Improvements

  • Add ScheduleSlot TypedDict: Improve type safety for normal schedule format

  • New TypedDict class with endtime: str and temperature: float fields

  • Provides IDE autocomplete and better type checking for schedule slot access

  • Rename schedule type aliases: Consistent naming with Simple Schedule types

  • CLIMATE_WEEKDAY_DICTClimateWeekdaySchedule (now dict[int, ScheduleSlot])
  • CLIMATE_PROFILE_DICTClimateProfileSchedule
  • CLIMATE_SCHEDULE_DICTClimateScheduleDict
  • Breaking change: Downstream code using these type aliases must update imports

Documentation

  • Create comprehensive migration guide: docs/migrations/simple_schedule_migration_2025_12.md
  • Includes before/after code examples
  • Search-and-replace patterns for automated migration
  • JSON serialization examples
  • Detailed API change documentation

Version 2025.12.31 (2025-12-16)

What's Changed

Improvements (aiohomematic_test_support)

  • Fix patch cleanup in test factories: Patches created in FactoryWithClient.get_default_central() are now explicitly stored and stopped during cleanup instead of relying on patch.stopall(). Ensures proper resource cleanup and prevents patch state leakage between tests.
  • Improve exception handling in mock creation: Replace bare except Exception: pass with specific exception handling and debug logging in get_mock(). Now logs AttributeError and TypeError when methods cannot be copied to mock instances, improving debuggability.
  • Add cleanup methods to SessionPlayer: New class methods for session data management:
  • clear_all() - Clear all cached session data
  • clear_file(file_id) - Clear data for specific file ID
  • get_loaded_file_ids() - List currently loaded file IDs
  • get_memory_usage() - Return approximate memory usage of cached data
  • Extract ADDRESS_DEVICE_TRANSLATION to JSON: Device address-to-filename mappings (362 entries) now loaded from data/device_translation.json instead of hardcoded dict. Reduces maintenance burden and allows easy updates without code changes. Fallback to hardcoded dict maintained for backwards compatibility.

Documentation (aiohomematic_test_support)

  • Create detailed improvement analysis: docs/test_support_improvements.md - Comprehensive review of test support package identifying 10 issues and optimization opportunities with priority matrix
  • Create executable implementation plan: docs/test_support_implementation_plan.md - Step-by-step guide with exact file paths and code blocks for implementing high-priority fixes

Version 2025.12.30 (2025-12-16)

What's Changed

Breaking Changes

  • Rename Protocol classes to follow -Protocol suffix convention:
  • StateChangeCallbackStateChangeCallbackProtocol
  • HealthRecordCallbackHealthRecordCallbackProtocol
  • SyncEventHandlerSyncEventHandlerProtocol
  • AsyncEventHandlerAsyncEventHandlerProtocol
  • Refactor is_valid property on data points:
  • is_valid now combines temporal and status validity (is_refreshed and is_status_valid)
  • Previous is_valid behavior (temporal check only) moved to new is_refreshed property
  • Consumers relying on is_valid for temporal-only check should migrate to is_refreshed

New Features

  • Add STATUS parameter support for data points:
  • New ParameterStatus enum with values: NORMAL, UNKNOWN, OVERFLOW, UNDERFLOW, ERROR, INVALID, UNUSED
  • New DataPointStatusReceivedEvent for STATUS parameter events
  • BaseParameterDataPoint now automatically detects paired *_STATUS parameters (e.g., LEVEL_STATUS for LEVEL)
  • New properties on data points: status, status_dpk, status_parameter, has_status_parameter
  • New is_refreshed property: Returns if data point has received a value
  • New is_status_valid property: Returns if STATUS is NORMAL or no STATUS parameter exists
  • Updated is_valid property: Combined check (is_refreshed and is_status_valid)
  • STATUS events are automatically routed to the main parameter's data point
  • Callbacks are only triggered when status actually changes (not on refresh)
  • Add has_parameter() method to ParamsetDescriptionProviderProtocol and ParamsetDescriptionCache

Bug Fixes

  • Fix typo in enum name: CalulatedParameterCalculatedParameter

Improvements

  • Document intentional camelCase exceptions for RPC callbacks in CLAUDE.md
  • Improve type safety by replacing *args and **kwargs with TypedDict:
  • Create StateChangeArgs TypedDict with all entity-specific parameters (on/off, brightness, position, climate-specific, cover-specific)
  • Create SystemEventArgs TypedDict for flexible system event argument handling
  • Replace **kwargs: Any with **kwargs: Unpack[StateChangeArgs] in all is_state_change() methods across custom data point classes
  • Remove **kwargs from publish_data_point_updated_event() - now accepts no arguments for cleaner event handling
  • Replace climate callback **kwargs: Any with explicit custom_id: str | None = None parameter

Version 2025.12.29 (2025-12-15)

What's Changed

Bug Fixes

  • Fix event publication

Version 2025.12.28 (2025-12-14)

What's Changed

Bug Fixes

  • Fix central incorrectly transitioning to RUNNING during startup with empty client list: all() returns True for empty iterables, causing premature RUNNING state before clients are registered
  • Fix central incorrectly transitioning to DEGRADED when all clients are connected: Missing not all_connected check in start() method allowed transition to DEGRADED even when all clients were CONNECTED
  • Fix scheduler not starting when central is in DEGRADED state: Now starts when central is operational (RUNNING or DEGRADED)
  • Fix HealthTracker not tracking clients: Clients were never registered with the health tracker after creation, causing update_client_health() to be a no-op. Now clients are properly registered during start() and unregistered during stop()

Improvements

  • Enhance state transition logging:

  • DEGRADED state now shows which clients are not connected (e.g., "clients not connected: Otto-Dev-929-BidCos-RF")

  • Client state machine now includes reason in log messages (e.g., "proxy initialized", "connection check failed")
  • Important client transitions (CONNECTED, DISCONNECTED, FAILED) now log at INFO level
  • Scheduler waiting message now shows current state

  • Automatic health data updates:

  • Events received from backend now automatically update last_event_received in health tracker
  • RPC request success/failure automatically tracked via circuit breaker callbacks
  • Health tracker now provides accurate can_receive_events, consecutive_failures, last_successful_request, last_failed_request metrics

Version 2025.12.27 (2025-12-14)

What's Changed

Bug Fixes

  • Fix firmware data not updating after refresh: Device descriptions cache was not being updated for existing devices during refresh_firmware_data() calls (both ad-hoc service calls and periodic checks). The cache update was skipped because the code incorrectly returned early when no "new" devices were found, even though existing device descriptions needed updating.

Version 2025.12.26 (2025-12-14)

What's Changed

Breaking Changes

  • Replace 9 legacy events with 4 focused integration events:
  • Remove SystemEventTypeData - replaced by DeviceLifecycleEvent and DataPointsCreatedEvent
  • Remove CallbackStateChangedEvent - replaced by SystemStatusChangedEvent.callback_state
  • Remove CentralStateChangedEvent - replaced by SystemStatusChangedEvent.central_state
  • Remove ClientStateChangedEvent - replaced by SystemStatusChangedEvent.client_state
  • Remove ConnectionStateChangedEvent - replaced by SystemStatusChangedEvent.connection_state
  • Remove DeviceAvailabilityChangedEvent - replaced by DeviceLifecycleEvent.availability_changes
  • Remove FetchDataFailedEvent - replaced by SystemStatusChangedEvent.issues
  • Remove HomematicEvent - replaced by DeviceTriggerEvent
  • Remove PingPongMismatchEvent - replaced by SystemStatusChangedEvent.issues

New Features

  • Add SystemStatusChangedEvent - aggregated event for all infrastructure and lifecycle state changes
  • central_state: CentralState | None - central unit state changes
  • connection_state: tuple[str, bool] | None - connection state (interface_id, connected)
  • client_state: tuple[str, ClientState, ClientState] | None - client state (interface_id, old, new)
  • callback_state: tuple[str, bool] | None - callback server state (interface_id, alive)
  • issues: tuple[IntegrationIssue, ...] - issues for user notification
  • Add DeviceLifecycleEvent - aggregated event for device lifecycle and availability
  • event_type: DeviceLifecycleEventType - CREATED, UPDATED, REMOVED, AVAILABILITY_CHANGED
  • device_addresses: tuple[str, ...] - affected device addresses
  • availability_changes: tuple[tuple[str, bool], ...] - availability changes
  • includes_virtual_remotes: bool - whether virtual remotes are included
  • Add DataPointsCreatedEvent - event for new data points (entity discovery)
  • new_data_points: tuple[tuple[DataPointCategory, tuple[BaseDataPoint, ...]], ...]
  • Add DeviceTriggerEvent - event for device triggers (button press, sensor trigger)
  • interface_id: str - interface identifier
  • channel_address: str - device address (not channel address)
  • parameter: str - parameter name (e.g., PRESS_SHORT)
  • value: str | int | float | bool - event value
  • Add IntegrationIssue dataclass for user-facing issues with severity, issue_id, translation_key
  • Add DeviceLifecycleEventType enum with CREATED, UPDATED, REMOVED, AVAILABILITY_CHANGED values

Migration Guide

See docs/migrations/event_migration_2025_12.md for detailed migration instructions.

Version 2025.12.25 (2025-12-13)

What's Changed

Breaking Changes

  • Remove InterfaceEvent class and InterfaceEventType enum - replaced with typed events
  • Remove EventType.INTERFACE and EventType.DEVICE_AVAILABILITY enum values
  • Remove publish_interface_event method from CentralUnit and EventCoordinator
  • Remove InterfaceEventPublisher protocol from interfaces
  • Remove INTERFACE_EVENT_SCHEMA from schemas
  • Remove delegation methods from CentralUnit - use coordinators directly:
  • Remove get_device() - use central.device_coordinator.get_device() instead
  • Remove get_channel() - use central.device_coordinator.get_channel() instead
  • Remove get_virtual_remotes() - use central.device_coordinator.get_virtual_remotes() instead
  • Remove remove_device() - use await central.device_coordinator.remove_device() instead
  • Remove CentralUnitState enum - use CentralState instead:
  • Removed legacy _state attribute from CentralUnit - all state now managed by state machine
  • Removed central_state property - use state property instead (returns CentralState from state machine)
  • CentralUnitState.NEWCentralState.STARTING
  • CentralUnitState.INITIALIZINGCentralState.INITIALIZING
  • CentralUnitState.RUNNINGCentralState.RUNNING
  • CentralUnitState.STOPPEDCentralState.STOPPED
  • CentralUnitState.STOPPED_BY_ERRORCentralState.FAILED
  • CentralUnitState.STOPPING state removed (no intermediate stopping state)
  • Change BackgroundScheduler.__init__() signature - now requires firmware_data_refresher parameter
  • Change CentralUnitStateProvider.state property type from CentralUnitState to CentralState
  • Change CentralInfo protocol - renamed central_state property to state (returns CentralState)
  • Change CentralHealthProtocol - renamed central_state property to state (returns CentralState)
  • Change ClientDependencies protocol - renamed central_state property to state (returns CentralState)

New Features

  • Add FetchDataFailedEvent - typed event for data fetch failures (replaces InterfaceEventType.FETCH_DATA)
  • Add PingPongMismatchEvent - typed event for ping/pong mismatches with PingPongMismatchType enum (PENDING, UNKNOWN)
  • Add DeviceAvailabilityChangedEvent - typed event for device availability changes (replaces EventType.DEVICE_AVAILABILITY)
  • Add PingPongMismatchType enum with PENDING and UNKNOWN values

Enhancements

  • Consolidate state management in CentralUnit - state property now directly delegates to state machine
  • Separate FirmwareDataRefresher protocol from DeviceDataRefresher protocol for clearer separation of concerns
  • Implement FirmwareDataRefresher in DeviceCoordinator instead of CentralUnit
  • Direct coordinator access pattern improves code clarity and reduces unnecessary delegation
  • Unified protocol property naming - all protocols now use state instead of mixed central_state/state

  • Replace fixed cool-down with staged reconnection for faster recovery after CCU restart:

  • Stage 0: Initial cool-down (reconnect_initial_cooldown, default 10s)
  • Stage 1: Non-invasive TCP port check (no CCU load, bypasses firewall ICMP blocks)
  • Stage 2: First system.listMethods check (verify RPC is responding)
  • Stage 3: Warmup delay (reconnect_warmup_delay, default 10s)
  • Stage 4: Second system.listMethods check (confirm services stable)
  • Stage 5: Full reconnection with proxy recreation
  • New TimeoutConfig options:
  • reconnect_initial_cooldown: Initial wait before checks (default 10s)
  • reconnect_tcp_check_timeout: Max time for TCP checks (default 60s)
  • reconnect_tcp_check_interval: TCP check interval (default 5s)
  • reconnect_warmup_delay: Warmup delay after first RPC check (default 10s)

Version 2025.12.24 (2025-12-12)

What's Changed

Bug Fixes

  • Fix "ResponseNotReady" errors after CCU reconnection by recreating proxy objects with fresh HTTP transport after successful PROXY_INIT
  • Add configurable cool-down period (reconnect_cooldown_delay, default 60s) after connection loss - all communication including pings is suspended during cool-down to allow CCU time to fully restart

Version 2025.12.23 (2025-12-12)

What's Changed

Breaking Changes

  • New Central State Machine architecture for improved reconnection reliability
  • Introduces CentralState enum with states: STARTING, INITIALIZING, RUNNING, DEGRADED, RECOVERING, FAILED, STOPPED
  • Central is RUNNING only when ALL clients are CONNECTED
  • DEGRADED state when at least one client is not connected
  • FAILED state after max retries (8 attempts) with heartbeat retry every 60 seconds
  • New protocol interfaces: CentralStateMachineProtocol, CentralHealthProtocol, HealthTrackerProtocol

New Features

  • Add CentralStateMachine class for orchestrating overall system state (central/state_machine.py)
  • Add ConnectionHealth and CentralHealth classes for unified health tracking (central/health.py)
  • Add RecoveryCoordinator for coordinated client recovery with max retry tracking (central/recovery.py)
  • Add CentralStateChangedEvent to EventBus for monitoring state transitions
  • Add ClientStateChangedEvent to EventBus for monitoring client state changes
  • Add state property to ClientConnectionProtocol protocol for accessing current client state
  • Add health score calculation (0.0-1.0) based on state machine, circuit breakers, and activity
  • Add exponential backoff for recovery retries (5s base, up to 60s max)
  • Add multi-stage data load verification in recovery process
  • New test suite for central state machine architecture (33 tests)

Bug Fixes

  • Fix entities not marked unavailable after failed proxy initialization - devices now correctly show unavailable during CCU restart/recovery

Version 2025.12.22 (2025-12-12)

What's Changed

Enhancements

  • Improve CCU reconnection behavior with exponential backoff (2s initial, doubles up to 120s max)
  • Add configurable TimeoutConfig in CentralConfig for connection/reconnect timing settings

Bug Fixes

  • Fix data loading after partial reconnect - load data for available interfaces immediately instead of waiting for all
  • Fix premature data loading - verify both state machine and actual connection before loading; retry up to 8 times with circuit breaker reset between attempts
  • Fix client reconnect logic - use state machine check to prevent skipping reconnect when connection is lost
  • Fix state machine allowing recovery from FAILED state via reconnect attempts
  • Fix JSON-RPC session renewal after CCU restart - AuthFailure now triggers fresh login
  • Fix race condition in scheduler client iteration with snapshot

Version 2025.12.21 (2025-12-11)

What's Changed

Enhancements

  • Circuit breakers automatically reset after successful reconnect to allow immediate data refresh
  • Add reset_circuit_breakers() method to ClientConnectionProtocol protocol

Bug Fixes

  • Fix entities remaining unavailable after CCU reconnect - circuit breakers now reset automatically, allowing immediate data refresh instead of waiting for slow recovery

Version 2025.12.20 (2025-12-11)

What's Changed

Enhancements

  • Add BackupData dataclass with filename and content for backup downloads
  • Backup filename now includes hostname and CCU version (e.g., Otto-3.83.6.20251025-2025-12-10-1937.sbk)
  • create_backup_and_download() now returns BackupData | None instead of bytes | None
  • Add firmware update support for OpenCCU via checkFirmwareUpdate.sh
  • Add HmUpdate hub entity for system firmware updates (OpenCCU only)
  • Add get_system_update_info() method to check for available firmware updates
  • Add trigger_firmware_update() method to initiate firmware update with automatic reboot (runs with nohup)
  • Add SystemUpdateData dataclass with check_script_available field to verify script availability
  • Add progress tracking for hub firmware updates:
  • New in_progress property on HmUpdate to track update status
  • Automatic polling every 30 seconds during update to detect completion
  • Progress detection via firmware version change
  • 30-minute timeout with graceful cleanup
  • Events published on progress state changes for Home Assistant integration

Architecture

  • Migrate CentralConnectionState callbacks to unified EventBus pattern:
  • Add ConnectionStateChangedEvent for connection state changes (connected/disconnected)
  • Add EventBus.publish_sync() method for synchronous event publishing from non-async code
  • Rename StateChangeCallback to StateChangeCallbackProtocol and remove register_state_change_callback() method
  • Add event_bus property to ClientDependencies protocol
  • All connection state notifications now use the same EventBus as other events
  • EventBus now uses TaskScheduler (Looper) for proper task lifecycle management:
  • publish_sync() uses TaskScheduler when available for task tracking, shutdown handling, and exception logging
  • Falls back to raw asyncio when no TaskScheduler is provided (e.g., in tests)

Developer Tools

  • Enhance check_i18n_catalogs.py to detect unused translation keys:
  • Add detection of translation keys in strings.json that are not used in the codebase
  • Add --remove-unused flag to automatically remove unused keys from all catalog files
  • Unused keys are reported as warnings (non-blocking) to avoid disrupting commits
  • Current statistics: 185 total keys, 181 used (97.8%), 4 unused (2.2%)
  • Add comprehensive i18n management documentation at docs/i18n_management.md

Bug Fixes

  • Fix excessive ERROR logging during CCU restart/reconnect - connection errors now log ERROR only on first occurrence, DEBUG for subsequent failures (fixes inverted logic in CentralConnectionState.add_issue() usage)
  • Fix PING_PONG false alarm mismatch events during CCU restart - PINGs sent during downtime are no longer tracked when connection is known to be down, and cache is cleared on reconnect
  • Scheduler now pauses non-essential jobs during connection issues - only _check_connection continues to run during CCU downtime, preventing unnecessary RPC calls and log spam
  • Reduce INFO-level log noise during reconnection - circuit breaker successful recovery transitions (half_open → closed) now log at DEBUG level instead of INFO

Notes

  • Firmware update features are only available on OpenCCU systems where /bin/checkFirmwareUpdate.sh is present
  • Backup before firmware update should be done via create_backup_and_download() in Home Assistant before triggering the update

Version 2025.12.19 (2025-12-10)

What's Changed

Architecture

  • Add combined sub-protocol interfaces to reduce coupling:
  • Client Combined Protocols (3): ValueAndParamsetOperations, DeviceDiscoveryWithIdentityProtocol, DeviceDiscoveryAndMetadataProtocol
  • Device Combined Protocols (1): DeviceRemovalInfo
  • Components now depend on minimal protocol combinations instead of full composite protocols
  • Refactor components to use combined sub-protocols:
  • CacheCoordinator.remove_device_from_caches uses DeviceRemovalInfo instead of DeviceProtocol
  • DeviceCoordinator.refresh_device_descriptions_and_create_missing_devices uses DeviceDiscoveryWithIdentityProtocol
  • DeviceCoordinator._rename_new_device uses DeviceDiscoveryAndMetadataProtocol
  • CallParameterCollector uses ValueAndParamsetOperations instead of ClientProtocol
  • DeviceDetailsCache.remove_device uses DeviceRemovalInfo instead of DeviceProtocol
  • DeviceDescriptionCache.remove_device uses DeviceRemovalInfo instead of DeviceProtocol
  • ParamsetDescriptionCache.remove_device uses DeviceRemovalInfo instead of DeviceProtocol
  • Split ClientProtocol (85 members) into 14 focused sub-protocols following Interface Segregation Principle:
  • Core Protocols (4): ClientIdentityProtocol, ClientConnectionProtocol, ClientLifecycleProtocol, ClientCapabilitiesProtocol
  • Handler-Based Protocols (9): DeviceDiscoveryOperationsProtocol, ParamsetOperationsProtocol, ValueOperationsProtocol, LinkOperationsProtocol, FirmwareOperationsProtocol, SystemVariableOperationsProtocol, ProgramOperationsProtocol, BackupOperationsProtocol, MetadataOperationsProtocol
  • Support Protocol (1): ClientSupportProtocol (utility methods and caches)
  • Handler classes explicitly inherit their sub-protocols for compile-time type checking
  • Add CentralProtocol composite protocol combining 29 sub-protocols:
  • CentralUnit now inherits from CentralProtocol (+ PayloadMixin, LogContextMixin)
  • Provides single protocol for complete central unit access
  • Maintains ability to depend on specific sub-protocols for better decoupling
  • Add CircuitBreaker integration to JSON-RPC client (AioJsonRpcAioHttpClient):
  • Prevents retry-storms during backend outages for JSON-RPC calls
  • Consistent resilience pattern across both XML-RPC and JSON-RPC clients
  • Session management methods (login/logout/renew) bypass circuit breaker
  • Add RequestCoalescer for get_device_description in DeviceOperationsHandler:
  • Deduplicates concurrent requests for the same device address
  • Reduces backend load during device discovery
  • Add explicit protocol inheritance to coordinators:
  • EventCoordinator now inherits from EventBusProvider, EventPublisher, LastEventTrackerProtocol, InterfaceEventPublisher
  • HubCoordinator now inherits from HubDataFetcher, HubDataPointManager
  • Improves type safety and removes type: ignore comments

Documentation

  • Update architecture_analysis.md with comprehensive evaluation:
  • Accurate metrics: 43,218 LOC across 102 files, 63 protocol interfaces
  • Detailed module breakdown (central, client, model, interfaces, store)
  • New sections for CircuitBreaker, RequestCoalescer, and Handler patterns
  • Architecture maturity assessment with ratings
  • ADR reference table with all 8 decisions

Version 2025.12.18 (2025-12-10)

What's Changed

Architecture

  • Refactor ClientCCU into specialized handler classes (BackupHandler, DeviceOpsHandler, FirmwareHandler, LinkManagementHandler, MetadataHandler, ProgramsHandler, SysvarsHandler)
  • Add ClientStateMachine for managing client connection lifecycle with validated state transitions
  • Add ClientState enum for client connection states (CREATED, INITIALIZING, INITIALIZED, CONNECTING, CONNECTED, DISCONNECTED, RECONNECTING, STOPPING, STOPPED, FAILED)
  • Split DeviceProtocol (72 members) into 10 focused sub-protocols following Interface Segregation Principle:
  • DeviceIdentityProtocol, DeviceChannelAccessProtocol, DeviceAvailabilityProtocol, DeviceFirmwareProtocol
  • DeviceLinkManagementProtocol, DeviceGroupManagementProtocol, DeviceConfigurationProtocol
  • DeviceWeekProfileProtocol, DeviceProvidersProtocol, DeviceLifecycleProtocol
  • Split ChannelProtocol (39 members) into 6 focused sub-protocols:
  • ChannelIdentityProtocol, ChannelDataPointAccessProtocol, ChannelGroupingProtocol
  • ChannelMetadataProtocol, ChannelLinkManagementProtocol, ChannelLifecycleProtocol
  • Add EventPriority enum with four priority levels (CRITICAL, HIGH, NORMAL, LOW) for handler ordering
  • Add EventBatch context manager for efficient batch event publishing
  • Add publish_batch() method to EventBus for optimized bulk event publishing
  • Add CircuitBreaker for preventing retry-storms during backend outages:
  • Three-state machine (CLOSED → OPEN → HALF_OPEN → CLOSED)
  • Configurable failure threshold, recovery timeout, and success threshold
  • Integrated with CentralConnectionState for coordinated health tracking
  • Metrics tracking for failures, successes, and rejections
  • Add RequestCoalescer for efficient RPC call deduplication:
  • Merges identical concurrent requests into a single backend call
  • Particularly beneficial during device discovery (getParamsetDescription calls)
  • Includes metrics for monitoring coalesce rate effectiveness

Bug Fixes

  • Fix hub data points initialization by ensuring clients are connected before init_hub() is called
  • Fix mock property delegation to support dynamic property value updates in tests
  • Add __slots__ support to get_mock() in test support module

Documentation

  • Add comprehensive inline comments for complex algorithms across the codebase:
  • State machine valid transitions diagram and state descriptions
  • Event publishing batching and subscription reference counting
  • bind_collector decorator context variable pattern
  • Cache eviction strategies (LRU, TTL, lazy cleanup)
  • SessionRecorder nested dict structure and purge algorithm
  • freeze/unfreeze parameter transformation for cache keys
  • EventBus dual-key handler lookup and polymorphic handler detection
  • Device discovery set difference algorithm and PARENT address fallback
  • DeviceProfileRegistry hierarchical model matching (exact → prefix)
  • Add migration guide for protocol sub-protocols (docs/migrations/protocol_subprotocols_2025_12.md)
  • Refactor architecture.md: Move inline decisions to ADRs, reduce from ~450 to ~245 lines
  • Add ADR 0007: Device Slots Reduction via Composition (Rejected)
  • Add ADR 0008: TaskGroup Migration (Deferred)

Version 2025.12.17 (2025-12-09)

What's Changed

  • Fix return types

Version 2025.12.16 (2025-12-09)

What's Changed

Concurrency and Thread-Safety

  • Add asyncio.Lock for thread-safe task management in InstallModeDpSensor
  • Replace bool state flags with asyncio.Event in BackgroundScheduler for thread-safety
  • Fix list-modification-during-iteration bug in climate.py subscription cleanup
  • Add asyncio.Lock to DeviceRegistry for thread-safe device operations

Memory Leak Prevention

  • Add auto-cleanup of EventBus subscriptions when devices/data points are removed
  • Add clear_subscriptions_by_key() method to EventBus for key-based cleanup

Error Handling

  • Add exception logging for scheduler jobs, background tasks, and install mode loops

Architecture and Dependency Injection

  • Add RpcServerCentralProtocol and RpcServerTaskSchedulerProtocol protocols
  • Refactor RpcServer to use protocol interfaces instead of direct CentralUnit dependency
  • Introduce _CentralEntry container class for decoupled central/looper storage
  • Add HubFetchOperations base protocol for consolidated hub data fetching
  • Consolidate UnsubscribeCallback definition in type_aliases.py
  • Add ClientDependencies composite protocol for decoupled client architecture
  • Refactor ClientConfig and ClientCCU to use ClientDependencies instead of CentralUnit

Other changes

  • Add basic rega script linter to ensure support for session recorder
  • Add architecture analysis
  • Cleanup scripts for recorder
  • Improve backend detection

Version 2025.12.15 (2025-12-08)

What's Changed

  • Revert get_serial.fn &error removal

Version 2025.12.14 (2025-12-08)

What's Changed

  • Cleanup ReGa scripts
  • Eliminate CDPD dictionary format with pure ProfileConfig implementation
  • Refactor CCU backup

Version 2025.12.13 (2025-12-07)

What's Changed

  • Add is_service param to inspector
  • Add inspector to load_data_point_value
  • Mark service methods with external/internal scope usage
  • Add scan_aiohomematic_calls.py script to find external method calls

Version 2025.12.12 (2025-12-07)

What's Changed

  • Fix retry

Version 2025.12.11 (2025-12-07)

What's Changed

  • Cleanup of legacy code in custom entity definition

Version 2025.12.10 (2025-12-07)

What's Changed

  • Add DeviceProfileRegistry as central registry for device-to-profile mappings
  • Add type-safe DeviceConfig and ExtendedDeviceConfig dataclasses
  • Add ProfileConfig and ChannelGroupConfig dataclasses for profile definitions
  • Migrate all 117 device models to DeviceProfileRegistry
  • Remove legacy ALL_DEVICES and ALL_BLACKLISTED_DEVICES dictionaries
  • Remove make_* factory functions from entity modules
  • Simplify get_custom_configs() to use only DeviceProfileRegistry
  • Move schemas to schemas.py

Version 2025.12.9 (2025-12-06)

What's Changed

  • Add TimerUnitMixin for light timer unit conversion
  • Refactor valve.py to use StateChangeTimerMixin and GroupStateMixin
  • Refactor light.py to use TimerUnitMixin for IP light classes
  • Remove unused DirectionStateMixin from mixins.py
  • Update imports to use specific protocol submodules

Version 2025.12.8 (2025-12-06)

What's Changed

Architecture and Internals

  • Split interfaces.py into interfaces/ package for better maintainability
  • Add DataPointTypeResolver class for extensible data point type mapping
  • Add shared mixins for custom entities (model/custom/mixins.py)
  • Refactor switch.py to use StateChangeTimerMixin and GroupStateMixin
  • Refactor cover.py to use PositionMixin for position calculations
  • Refactor light.py to use StateChangeTimerMixin and BrightnessMixin

Reliability and Error Handling

  • Add login rate limiting with exponential backoff for JSON-RPC client
  • Add error message sanitization helpers (sanitize_error_message, RpcContext.fmt_sanitized)
  • Add retry module with RetryStrategy class for transient network errors
  • Improve CentralConnectionState
  • Add resource limits for internal collections

High-Level API (HomematicAPI)

  • Add HomematicAPI facade class with simplified high-level interface
  • Add CentralConfig.for_ccu() and CentralConfig.for_homegear() factory methods
  • Add async context manager support for HomematicAPI
  • Add @with_retry decorator to HomematicAPI operations for automatic retry

CLI Enhancements (hmcli)

  • Add subcommand-based CLI structure with device discovery commands
  • Add list-devices command to list all devices
  • Add list-channels <device> command to list channels of a device
  • Add list-parameters <channel> command to list parameters of a channel
  • Add device-info <address> command to show detailed device information
  • Add get and set subcommands for parameter operations
  • Add interactive subcommand for REPL mode with command history and tab completion
  • Add shell completion script generation for bash, zsh, and fish shells
  • Add --generate-completion <shell> option to generate completion scripts

Documentation

  • Add getting_started.md documentation with quick start examples
  • Add common_operations.md documenting top 15 most-used operations

Version 2025.12.7 (2025-12-05)

What's Changed

  • Add helper for config support

Version 2025.12.6 (2025-12-04)

What's Changed

  • Add ENERGY_COUNTER_FEED_IN
  • Fix backend detection
  • Fix install mode for HmIP
  • Improved delayed device handling
  • Refactor add_new_devices_manually to address names

Version 2025.12.5 (2025-12-03)

What's Changed

  • Add install mode virtual data points with countdown timer (HUB_BUTTON + HUB_SENSOR)
  • Support separate install mode data points per interface (HmIP-RF and BidCos-RF)
  • Add JSON-RPC methods for HmIP install mode (getInstallMode, setInstallModeHmIP)
  • Add init_install_mode, fetch_install_mode_data, publish_install_mode_refreshed to Hub/HubCoordinator/CentralUnit
  • Add mandatory interface parameter to get_install_mode/set_install_mode on CentralUnit
  • Extend ClientCoordinator.get_client to accept optional interface parameter
  • Add ClientProvider to Hub for multi-interface install mode support
  • Fix install mode data point creation to check for client availability per interface
  • Fix install mode unique_id generation to avoid duplicate prefix
  • Mark setInstallMode/setInstallModeHmIP as optional JSON-RPC methods

Version 2025.12.4 (2025-12-02)

What's Changed

  • Add rename for new devices

Version 2025.12.3 (2025-12-02)

What's Changed

  • Add create_backup_and_download to BackupProvider/CentralUnit
  • Add dedicated inbox devices code
  • Add rename_device / accept_device_in_inbox to Central/DeviceManagement
  • Refactor Client

Version 2025.12.2 (2025-12-01)

What's Changed

  • Add HubProtocol and WeekProfileProtocol to interfaces
  • Cleanup client api
  • Rename regaid to ise_id
  • Update documentation

Version 2025.12.1 (2025-12-01)

What's Changed

  • Migrate to Protocol based model

Version 2025.12.0 (2025-12-01)

What's Changed

  • Added get_install_mode() and set_install_mode() methods
  • Added rename_device and rename_channel methods
  • Method accept_device_in_inbox to accept new devices
  • New hub entity for device inbox (devices pending pairing)
  • New hub entity for system update status
  • New method create_backup() for creating CCU system backups
  • New method download_backup() for downloading backup files
  • New method download_firmware() for downloading firmware to CCU
  • New method get_service_messages to fetch CCU service messages
  • New method get_system_update_info for firmware update status
  • Extended SystemInformation with CCU type identification (CCU vs OpenCCU)
  • New CCUType enum for backend identification
  • New protocols for model data points for better decoupling
  • New script trigger_firmware_update.fn to trigger firmware updates
  • New script create_backup.fn to create system backups
  • New script get_backend_info.fn to retrieve backend information
  • Extended get_system_update_info.fn to support OpenCCU online version check

Version 2025.11.30 (2025-11-26)

What's Changed

  • Use AioXmlRpcProxy for backend detection

Version 2025.11.29 (2025-11-26)

What's Changed

  • Extend backend detection

Version 2025.11.28 (2025-11-26)

What's Changed

  • Avoid potential memory leaks
  • Clear in-memory caches on stop

Version 2025.11.27 (2025-11-25)

What's Changed

  • Add backend detection
  • Use CentralConnectionState in AioJsonRpcAioHttpClient

Version 2025.11.26 (2025-11-25)

What's Changed

  • Improve event processing

Version 2025.11.25 (2025-11-24)

What's Changed

  • Cleanup after event bus migration
  • Switch from legacy wrapper to event bus naming

Version 2025.11.24 (2025-11-24)

What's Changed

  • Add ClientFactoryProtocol for DI
  • Improve documentation

Version 2025.11.23 (2025-11-21)

What's Changed

  • Clean up event bus implementation and remove legacy code
  • Extend API to re-add support for mqtt client

Version 2025.11.22 (2025-11-20)

What's Changed

  • Add data_point_provider to DeviceCoordinator

Version 2025.11.21 (2025-11-20)

What's Changed

  • De-couple from central unit pt2
  • Improve typing in protocols/interfaces

Version 2025.11.20 (2025-11-19)

What's Changed

  • De-couple from central unit
  • Extract coordinators from central unit
  • Extract device registry from central
  • Extract scheduler from central
  • Refactor event handling to event bus
  • Rename writeable to writable

Version 2025.11.19 (2025-11-17)

What's Changed

  • Fix service naming

Version 2025.11.18 (2025-11-17)

What's Changed

  • Add more simple services and converters to week profile
  • Add base_temperature to CLIMATE_SIMPLE_WEEKDAY_DATA
  • Filter entries in validate_and_convert_weekday_to_simple
  • Refactor simple schedule

Version 2025.11.17 (2025-11-16)

What's Changed

  • Fix week profile filtering
  • Improve test coverage,
  • Reorganize test files

Version 2025.11.16 (2025-11-16)

What's Changed

  • Add schedule support to custom data point
  • Improve the test coverage of week_profile
  • Optimize climate get/set_schedule
  • Return filtered climate schedule data on get_schedule / Accept filtered data in climate set_schedule

Version 2025.11.15 (2025-11-13)

What's Changed

  • Move reload_and_cache_schedule to load_data_point_value

Version 2025.11.14 (2025-11-13)

What's Changed

  • Add input converter to climate scheduler setter

Version 2025.11.13 (2025-11-13)

What's Changed

  • Use schedule cache for climate get/set schedule operations

Version 2025.11.12 (2025-11-12)

What's Changed

  • Add climate schedule cache

Version 2025.11.11 (2025-11-09)

What's Changed

  • Add translations for log messages with level >= INFO or translation exclusions
  • Move strings.json to root

Version 2025.11.10 (2025-11-08)

What's Changed

  • Make exceptions translatable

Version 2025.11.9 (2025-11-07)

What's Changed

  • Do not normalize homematic event data

Version 2025.11.8 (2025-11-07)

What's Changed

  • Remove need for empty parentheses for bind_collector
  • Switch mypy to strict
  • Use Protocol for callback with parameters

Version 2025.11.7 (2025-11-05)

What's Changed

  • Handle early arrival of pong events

Version 2025.11.6 (2025-11-05)

What's Changed

  • Add code member sorter to pre-commit
  • Add post_init_data_point_fields
  • Make ping pong handling more robust
  • Move on_link_peer_changed and refresh_link_peer_activity_sources to BaseCustomDpClimate

Version 2025.11.5 (2025-11-04)

What's Changed

  • Remove link support for not linkable interfaces

Version 2025.11.4 (2025-11-04)

What's Changed

  • Fix issue with linked channels for climate activity
  • Store data_point_updated_callbacks by custom_id

Version 2025.11.3 (2025-11-03)

What's Changed

  • Add fallback to climate.activity to use linked channels, if own dps don't exist

Version 2025.11.2 (2025-11-02)

What's Changed

  • Add link peer channel to channel
  • Add link_peer channels to device

Version 2025.11.0 (2025-11-01)

What's Changed

  • Fix issue after reconnect
  • Use generic DP DpDummy instead of NoneTypeDataPoint replacement

Version 2025.10.26 (2025-10-30)

What's Changed

  • Run delete_file task in executor

Version 2025.10.25 (2025-10-30)

What's Changed

  • Handle ping after ping success

Version 2025.10.24 (2025-10-30)

What's Changed

  • Fix custom HmIP-WGTC definition
  • Test support: Improve central unit code/test coverage

Version 2025.10.22 (2025-10-26)

What's Changed

  • Refactor PingPongCache

Version 2025.10.21 (2025-10-26)

What's Changed

  • Add pong_mismatch_allowed to ping pong event
  • Revert: Improve call back alive check

Version 2025.10.20 (2025-10-26)

What's Changed

  • Test support: Improve code/test coverage
  • Improve call back alive check
  • Improve version creation for aiohomematic_test_support

Version 2025.10.18 (2025-10-24)

What's Changed

  • Test support: Search in secondary sessions if primary session has no results

Version 2025.10.17 (2025-10-23)

What's Changed

  • Test support: Remove ClientLocal

Version 2025.10.16 (2025-10-23)

What's Changed

  • Test support: Add option to start central in get_default_central (tests)

Version 2025.10.15 (2025-10-23)

What's Changed

  • Test support: Refactor tests to use central*client_factory_with****ccu_client

Version 2025.10.14 (2025-10-22)

What's Changed

  • Test support: Add separate deployment for aiohomematic_test_support
  • Test support: Refactor tests to use SessionPlayer instead of ClientLocal
  • Test support: Use recorded session for testing

Version 2025.10.10 (2025-10-19)

What's Changed

  • Add file_path to BasePersitentFile load
  • Add get_latest_response_by_params to session recorder
  • Add 'optional settings' config option
  • Remove individual ttl for session recorder entry
  • Rename filename to file_name
  • Use enum for internal custom ids

Version 2025.10.9 (2025-10-18)

What's Changed

  • Add session recorder
  • Ensure custom_ids are only used for external registrations
  • Fix rpc auth

Version 2025.10.8 (2025-10-14)

What's Changed

  • Add dew point spread and enthalpy to calculated sensors

Version 2025.10.7 (2025-10-13)

What's Changed

  • Fix issue with RPC-Server setup

Version 2025.10.6 (2025-10-13)

What's Changed

  • Add ELV-SH-PSMCI
  • Refactor rpc handling

Version 2025.10.5 (2025-10-10)

What's Changed

  • Fix issue with non existing PARENT in device description

Version 2025.10.4 (2025-10-07)

What's Changed

  • Add delayed device creation
  • Add source of device creation to callback
  • Improve test setup and cleanup
  • Minimize decorator overhead

Version 2025.10.3 (2025-10-06)

What's Changed

  • Add Keyword-only method linter (mypy-style)

Version 2025.10.2 (2025-10-05)

What's Changed

  • API cleanup: ensure that kw arguments are passed to the underlying function

Version 2025.10.1 (2025-10-01)

What's Changed

  • Add option to cover entities that the current default behaviour can be disabled:
  • The default behaviour is, that the primary cover entity of a group uses the level of the state channel and no its own level to display a correct level.
  • Only HM experts should disable this option, that like to control all three writeable channels of a cover group.

Version 2025.10.0 (2025-10-01)

What's Changed

  • Improve error message if service is not available
  • Make default_callback_port, storage_folder optional
  • Re-/Store last manual temperature of climate entity

Version 2025.9.8 (2025-09-29)

What's Changed

  • Add CuXD parameters CMD_RETL and CMD_RETS to ignore list, to avoid warnings when reading the value without an appropriate configuration.
  • CMD_RETL warning: use CUX28010xx:16.CMD_QUERY_RET=1 to activate CUX28010xx:16.CMD_RETL command!
  • CMD_RETS warning: use CUX28010xx:16.CMD_QUERY_RET=1 to activate CUX28010xx:16.CMD_RETS command!
  • Add them to unignore if you are able to handle the warnings.

Version 2025.9.7 (2025-09-28)

What's Changed

  • Fix device has_sub_devices pt2

  • Version 2025.9.6 (2025-09-28)

  • Fix device has_sub_devices

Version 2025.9.5 (2025-09-25)

What's Changed

  • Fix magic method issue with log_context in xml_rpc client

Version 2025.9.4 (2025-09-24)

What's Changed

Version 2025.9.3 (2025-09-14)

What's Changed

  • Remove test-only-relevant code from _get_attributes_by_decorator
  • Further decorator refactoring

Version 2025.9.2 (2025-09-12)

What's Changed

  • Refactor CDP OperatingVoltageLevel
  • Refactor event method handling
  • Refactor decorators
  • Add log_context to @*_property
  • Add overloads to @*_property
  • Add overloads to @inspector

Version 2025.9.1 (2025-09-06)

What's Changed

  • Document how device, channel and data point names are created (docs/naming.md)
  • Add worked examples to naming documentation
  • Use dedicated loggers for event and performance logging

Version 2025.8.10 (2025-08-29)

What's Changed

  • Improve documentation
  • Added docs/architecture.md describing high-level components (central, client, model, caches, support) and their interactions
  • Added data flow for XML-RPC/JSON-RPC, event handling, and data point updates
  • Added sequence diagrams for connect, device discovery, state change propagation
  • Add troubleshouting docs
  • Add customization for HmIP-LSC
  • Avoid deadlocks within locks (cover)
  • Detailing the central status
  • Improve boundary logging und exception handling
  • Improve decorators
  • Improve lock handling
  • Shield network I/O against cancellation
  • Validate custom datapoint definition on startup

Version 2025.8.9 (2025-08-23)

What's Changed

  • Add signature to model
  • Improve immutability
  • Improve readability of visibility cache

Version 2025.8.8 (2025-08-23)

What's Changed

  • Extend DataPointKey usage
  • Improve fetch_all_device_data

Version 2025.8.7 (2025-08-17)

What's Changed

  • Use room from channel 0 for device, if multiple set on channels
  • Use room from master channel, if multiple set on channel group

Version 2025.8.6 (2025-08-14)

What's Changed

  • Do not send additional parameter in kwargs for events
  • Fix unique_id_prefix usage
  • Rename hahomematic to aiohomematic

Version 2025.8.5 (2025-08-11

What's Changed

  • Improve module documentation
  • Small performance improvements

Version 2025.8.4 (2025-08-10)

What's Changed

  • Small performance improvements

Version 2025.8.3 (2025-08-07)

What's Changed

  • Fix refresh shortly

Version 2025.8.2 (2025-08-07)

What's Changed

  • Simplify should_fire_data_point_updated_callback for calculated data points

Version 2025.8.1 (2025-08-06)

What's Changed

  • Cleanup slots
  • Move timer support to BaseDataPoint

Version 2025.8.0 (2025-08-03)

What's Changed

  • Use slots

Version 2025.7.7 (2025-07-26)

What's Changed

  • Align exception naming

Version 2025.7.6 (2025-07-25)

What's Changed

  • Refactor argument extraction from exceptions

Version 2025.7.5 (2025-07-23)

What's Changed

  • Add customization for (Deleting of obsolete entities/device) might be required):
  • HmIP-SMO230

Version 2025.7.4 (2025-07-13)

What's Changed

  • Add customization for (Deleting of obsolete entities/device) might be required):
  • HmIP-WGT/HmIP-WGTC
  • Replace asyncio.iscoroutinefunction

Version 2025.7.3 (2025-07-13)

What's Changed

  • Improve: Fire updated events for calculated DPs when refreshed within a second

Version 2025.7.2 (2025-07-12)

What's Changed

  • Rename channel* to group* properties for cover, light and switch

Version 2025.7.1 (2025-07-12)

What's Changed

  • Fire updated events for calculated DPs when refreshed within a second

Version 2025.7.0 (2025-07-09)

What's Changed

  • Add default customization for ELV-SH-SW1-BAT (Deleting of obsolete entities might be required)
  • Enable OPERATING_VOLTAGE_LEVEL for HM-CC-RT-DN and HM-TC-IT-WM-W-EU

Version 2025.6.0 (2025-06-16)

What's Changed

  • Add batteries for ELV-SH-TACO
  • Add state channel to sub_device_channel mapping
  • Improve sub_device_channel identification

Version 2025.5.2 (2025-06-01)

What's Changed

  • Add operating voltage level to ELV-SH-WSM / HmIP-WSM
  • Enable ACTUAL_TEMPERATURE on maintenance channel

Version 2025.5.1 (2025-05-20)

What's Changed

  • Add CustomDP valve for ELV-SH-WSM / HmIP-WSM

Version 2025.5.0 (2025-05-19)

What's Changed

  • Fix performance measurement
  • Improve identify ip address
  • Wait with PING/PONG handling until interface is initialized

Version 2025.4.2 (2025-04-11)

What's Changed

  • Add button_lock to HmIP-DLD

Version 2025.4.1 (2025-04-07)

What's Changed

  • limit text values to 255 characters

Version 2025.4.0 (2025-04-03)

What's Changed

  • Create TLS context during module load

Version 2025.3.0 (2025-03-09)

What's Changed

  • Clear session on auth failure
  • Use enums for const parameter values

Version 2025.2.7 (2025-02-08)

What's Changed

Version 2025.2.6 (2025-02-08)

What's Changed

  • Add vapor concentration and dew point to all device channels that support temperature and humidity
  • Add HmIP-FCI1 and HmIP-FCI6 to batteries
  • Ensure load_data_point_value usage for initial load
  • Fix OperatingVoltageLevel attributes: low_bat_limit, low_bat_limit_default
  • Ignore parameters on initial load, if not already fetched by rega script (ERROR*, RSSI*, DUTY_CYCLE, DUTYCYCLE, LOW_BAT, LOWBAT, OPERATING_VOLTAGE)
  • Ignore model on initial load (HmIP-SWSD, HmIP-SWD)

Version 2025.2.5 (2025-02-05)

What's Changed

  • Use value instead of default for low_bat_limit

Version 2025.2.3 (2025-02-05)

What's Changed

  • Fix calculated climate sensor identification

Version 2025.2.2 (2025-02-05)

What's Changed

  • Catch get_metadata XMLRPC fault
  • Catch JSONDecodeError on load/save cache files
  • Ignore devices with unknown battery
  • Set battery to UNKNOWN for HmIP-PCBS-BAT
  • Sort battery list for correct wildcard search

Version 2025.2.1 (2025-02-02)

What's Changed

  • Add calculated data points for HM devices
  • Remove python 3.12 for github tests and pylint
  • Use py 3.13 for mypy and pylint

Version 2025.2.0 (2025-02-01)

What's Changed

  • Fix battery qty

Version 2025.1.22 (2025-01-31)

What's Changed

  • Add config option to define the hm_master_poll_after_send_intervals
  • Enable DEW_POINT calculation for internal thermostats
  • Use temporary values where push is not supported

Version 2025.1.21 (2025-01-30)

What's Changed

  • Improve connection error handling

Version 2025.1.20 (2025-01-30)

What's Changed

  • Fix index issue with WEEK_PROGRAM_POINTER
  • Use ParamsetKey enum in tests

Version 2025.1.19 (2025-01-29)

What's Changed

  • Don't read on unavailable devices
  • Enable schedule on hm thermostat
  • Poll master dp values 5s after send for bidcos devices
  • Rename paramset_key to paramset_key_or_link_address for put_paramset

Version 2025.1.18 (2025-01-28)

What's Changed

  • Add climate presets based on WEEK_PROGRAM_POINTER
  • Add WEEK_PROGRAM_POINTER for bidcos climate devices
  • Define schedule_channel_address for HM schedule usage
  • Fix usage of master dps for bidcos climate devices

Version 2025.1.17 (2025-01-26)

What's Changed

  • Catch math related value errors

Version 2025.1.16 (2025-01-26)

What's Changed

  • Limit calculated climate sensors to selected devices

Version 2025.1.15 (2025-01-25)

What's Changed

  • Add calculated data points: FrostPoint

Version 2025.1.14 (2025-01-25)

What's Changed

  • Add calculated data points: ApparentTemperature, DewPoint, VaporConcentration
  • Refactor OperatingVoltageLevel

Version 2025.1.13 (2025-01-24)

What's Changed

  • Fix OperatingVoltageLevel sensor value

Version 2025.1.12 (2025-01-24)

What's Changed

  • Add LOW_BAT_LIMIT
  • Add calculated data points: OperatingVoltageLevel
  • Refactor parameter_visibility

Version 2025.1.11 (2025-01-20)

What's Changed

  • Cleanup cache file clear
  • Delay start of scheduler until devices are created
  • Rename instance_name to central_name
  • Slugify cache file name

Version 2025.1.10 (2025-01-17)

What's Changed

  • Return regular dict from list_devices

Version 2025.1.9 (2025-01-15)

What's Changed

  • Load cached files as defaultdicts

Version 2025.1.8 (2025-01-15)

What's Changed

  • Improve defaultdict usage

Version 2025.1.7 (2025-01-14)

What's Changed

  • Fix KeyError on uninitialised dict pt2

Version 2025.1.6 (2025-01-14)

What's Changed

  • Fix KeyError on uninitialised dict

Version 2025.1.5 (2025-01-11)

What's Changed

  • Refactor create_* methods:
  • create_data_points_and_events
  • create_data_point_and_append_to_channel
  • create_event_and_append_to_channel
  • Speedup wildcard lookup

Version 2025.1.4 (2025-01-09)

What's Changed

  • Cleanup: Use defaultdict, improve naming
  • Rename decorator @inspector

Version 2025.1.3 (2025-01-08)

What's Changed

  • Fix issue with programs/sysvars on backend restart

Version 2025.1.2 (2025-01-06)

What's Changed

  • Add legacy name for hub entities
  • Cleanup hub entity name if channel exists
  • Identify channel of a system variable:
  • name ends with channel address
  • name contains channel/device id

Version 2025.1.1 (2025-01-05)

What's Changed

  • Consider heating value type when calculating hvac action

Version 2025.1.0 (2025-01-01)

What's Changed

  • Remove get-/set_install_mode

Version 2024.12.13 (2024-12-27)

What's Changed

  • Add program switch

Version 2024.12.12 (2024-12-23)

What's Changed

  • Ensure service and alarm messages are always displayed
  • Remove sv prefix from sysvar / p prefix from program

Version 2024.12.11 (2024-12-22)

What's Changed

  • Fix remove last sysvar/program
  • Remove unignore file import
  • Rename has_markers to enabled_default
  • Use NamedTuple for datapoint key

Version 2024.12.10 (2024-12-21)

What's Changed

  • Refactor scheduler
  • Reformat line length to 120

Version 2024.12.9 (2024-12-20)

What's Changed

  • Add periodic checks for device firmware updates
  • Refactor scheduler to use just one task
  • Rename marker for extended system variables from hahm to HAHM to better align with other markers

Version 2024.12.8 (2024-12-20)

What's Changed

  • Rename create methods
  • Revert mangled attribute name in json_rpc_client

Version 2024.12.7 (2024-12-18)

What's Changed

  • Extend element_matches_key search
  • Log debug if variable is too long
  • Remove default markers from description
  • Start json_rpc client only for ccu

Version 2024.12.6 (2024-12-18)

What's Changed

  • Support markers for sysvar/program selection
  • Remove danielperna84 from links after repository transfer to sukramj

Version 2024.12.5 (2024-12-15)

What's Changed

  • Limit number of concurrent mass operations to json api to 3 parallel executions

Version 2024.12.4 (2024-12-14)

What's Changed

  • Add missing encoding to unquote
  • Ensure default encoding is ISO-8859-1 where needed

Version 2024.12.3 (2024-12-14)

What's Changed

  • Add method cleanup_text_from_html_tags
  • Decode received sysvar/program descriptions
  • Replace special character replacement by simple UriEncode() method use by @jens-maus

Version 2024.12.2 (2024-12-10)

What's Changed

  • Use kelvin instead of mireds for color temp

Version 2024.12.1 (2024-12-10)

What's Changed

  • Catch orjson.JSONDecodeError on faulthy json script response

Version 2024.12.0 (2024-12-05)

What's Changed

  • Add description to sysvar and program
  • Add BidCos-Wired to list of primary interface candidates
  • Remove obsolete try/except in homegear client

Version 2024.11.11 (2024-11-25)

What's Changed

  • Enable central link management for HmIP-wired
  • Reset temporary values before write

Version 2024.11.10 (2024-11-24)

What's Changed

  • Add TIME_OF_OPERATION to smoke detector
  • Switch multiplier from int to float
  • Use more constants for cover and light

Version 2024.11.9 (2024-11-22)

What's Changed

  • Make sysvars eventable

Version 2024.11.8 (2024-11-21)

What's Changed

  • Add missing @service annotations
  • Add performance measurement to @service
  • Don't re-raise exception on internal services
  • Move @service
  • Remove @service from abstract methods

Version 2024.11.7 (2024-11-19)

What's Changed

  • Set state_uncertain on value write

Version 2024.11.6 (2024-11-19)

What's Changed

  • Cleanup data point

Version 2024.11.5 (2024-11-19)

What's Changed

  • Fix returned version of client
  • Improve store tmp value
  • Store temporary value for sysvar data points

Version 2024.11.4 (2024-11-19)

What's Changed

  • Add sysvar/program refresh to scheduler
  • Run periodic tasks with an individual interval
  • Store temporary value for polling client data points

Version 2024.11.3 (2024-11-18)

What's Changed

  • Add interface(id) to performance log message
  • Add interfaces_requiring_periodic_refresh to config
  • Add periodic data refresh to CentralUnitChecker for some interfaces
  • Add root path for virtual devices
  • Maintain data_cache by interface
  • Reduce MAX_CACHE_AGE to 10s

Version 2024.11.2 (2024-11-17)

What's Changed

  • Add get_data_point_path to central
  • Allow empty port for some interfaces
  • Do reconnect/reload only for affected interfaces
  • Ignore unknown interfaces
  • Remove clients for not available interfaces

Version 2024.11.1 (2024-11-14)

What's Changed

  • Add basic support for json clients
  • Add data_point_path event
  • Add getDeviceDescription, getParamsetDescription, listDevices, getValue, setValue, getParamset, putParamset to json_rpc
  • Add option to refresh data by interface
  • Add xml_rpc support flag to client
  • Extend DP_KEY with interface_id
  • Rename event to data_point_event

Version 2024.11.0 (2024-11-04)

What's Changed

  • Improve on_time usage

Version 2024.10.17 (2024-10-29)

What's Changed

  • Use enum for json/event keys
  • Fire interface event, if data could not be fetched with script from CCU

Version 2024.10.16 (2024-10-27)

What's Changed

  • Optimize MASTER data load

Version 2024.10.15 (2024-10-27)

What's Changed

  • Rename model to better distinguish from HA

Version 2024.10.14 (2024-10-26)

What's Changed

  • Use version from module

Version 2024.10.13 (2024-10-24)

What's Changed

  • Disable climate temperature validation when turning off

Version 2024.10.12 (2024-10-19)

What's Changed

  • Small tweaks to improve central link management

Version 2024.10.11 (2024-10-19)

What's Changed

  • Align method parameters with CCU
  • Use PRESS_SHORT for reportValueUsage
  • Check if channel has programs before deleting links

Version 2024.10.10 (2024-10-18)

What's Changed

  • Add create_central_links and remove_central_links to device and central

Version 2024.10.9 (2024-10-17)

What's Changed

  • Add central link methods to click event
  • Add reportValueUsage, addLink, removeLink and getLinks to client
  • Add version to code
  • Fix wrong channel assignment for HmIP-DRBLI4
  • Add operation_mode to channel

Version 2024.10.8 (2024-10-15)

What's Changed

  • Add services to copy climate schedules
  • Make validation for climate schedules optional

Version 2024.10.7 (2024-10-12)

What's Changed

  • Add MIN_MAX_VALUE_NOT_RELEVANT_FOR_MANU_MODE, OPTIMUM_START_STOP and TEMPERATURE_OFFSET to climate
  • Improve profile validation
  • Use regex to identify schedule profiles

Version 2024.10.6 (2024-10-11)

What's Changed

  • Export SIMPLE_PROFILE_DICT, SIMPLE_WEEKDAY_LIST

Version 2024.10.5 (2024-10-11)

What's Changed

  • Add simple climate schedule service to store profiles
  • Reuse existing dict types
  • Convert schedule time from minutes to hh:mm

Version 2024.10.4 (2024-10-09)

What's Changed

  • Add basic climate schedule services
  • Refactor constants
  • Rename climate enums and constants to better distinguish from HA

Version 2024.10.3 (2024-10-07)

What's Changed

  • Add missing import entries

Version 2024.10.2 (2024-10-07)

What's Changed

  • Simplify entity imports

Version 2024.10.1 (2024-10-04)

What's Changed

  • Fix rx_mode lazy_config
  • Make DEFAULT optional due to homegear support
  • Move context var to own module

Version 2024.10.0 (2024-10-03)

What's Changed

  • Add config option for max read workers
  • Disable collector for stop events
  • Improve logging when raising exception
  • Log exception at the most outer service
  • Make UPDATEABLE optional due to homegear support
  • Raise exception on set_value, put_paramset
  • Remove command queue

Version 2024.9.12 (2024-09-26)

What's Changed

  • Add config option for listen ip address and port

Version 2024.9.11 (2024-09-25)

What's Changed

  • Remove CED for ELV-SH-WUA / HmIP-WUA

Version 2024.9.10 (2024-09-22)

What's Changed

  • Add name to channel
  • Catch bind address errors of xml rpc server
  • Refactor get_events, get_new_entities
  • Remove unnecessary checks
  • Separate enable/disable sysvar and program scan
  • Use paramset_description from channel

Version 2024.9.9 (2024-09-21)

What's Changed

  • Use channel instead of channel_addresses

Version 2024.9.8 (2024-09-21)

What's Changed

  • Refactor device/entity to extract channel
  • Replace device_type by model
  • Shorten names

Version 2024.9.7 (2024-09-15)

What's Changed

  • Add bind_collector to all relevant methods with option to disable it
  • Identify bind_collector annotated methods
  • Mark externally accessed services with service_call if bind_collector is not appropriate

Version 2024.9.6 (2024-09-13)

What's Changed

  • Add missing PayloadMixin
  • Adjust payload and path
  • Rename value_property to state_property

Version 2024.9.5 (2024-09-03)

What's Changed

  • Improve device_description usage
  • Reduce number of required characters for an address identification

Version 2024.9.4 (2024-09-03)

What's Changed

  • Use validator for local schema

Version 2024.9.3 (2024-09-02)

What's Changed

  • Improve validation of channel address, device address, password and htmltag

Version 2024.9.2 (2024-09-02)

What's Changed

  • Allow str for get_paramset

Version 2024.9.1 (2024-09-02)

What's Changed

  • Improve paramset key check

Version 2024.9.0 (2024-09-01)

What's Changed

  • Add getLinkPeers XmlRPC method
  • Do not create update entities that are not updatable (manually remove obsolete update entities)
  • Only try device update refresh if device is updatable
  • Refactor update entity

Version 2024.8.15 (2024-08-29)

What's Changed

  • Add check for link paramsets
  • Avoid permanent cache save on remove device
  • Check rx_mode
  • Ensure only one load/save of cache file at time
  • Load all paramsets
  • Small definition fix for DALI
  • Use TypedDict for device_description
  • Use TypedDict for parameter_data

Version 2024.8.14 (2024-08-26)

What's Changed

  • Add paramset_key to entity_key
  • Switch typing of paramset_key from str to ParamsetKey
  • Mark only level as relevant entity for DALI

Version 2024.8.13 (2024-08-25)

What's Changed

  • Check/convert values of manual executed put_paramset/set_value

Version 2024.8.12 (2024-08-24)

What's Changed

  • Add additional validation on config parameters

Version 2024.8.11 (2024-08-21)

What's Changed

  • Make HEATING_COOLING visible for thermostats
  • Use only relevant IP for XmlRPC Server listening on

Version 2024.8.10 (2024-08-20)

What's Changed

  • Cleanup ParamsetDescriptionCache
  • Cleanup DeviceDescriptionCache

Version 2024.8.9 (2024-08-20)

What's Changed

  • Avoid excessive memory usage in cache

Version 2024.8.8 (2024-08-18)

What's Changed

  • Refactor folder handling

Version 2024.8.7 (2024-08-18)

What's Changed

  • Fix empty channel on get_parameters

Version 2024.8.6 (2024-08-18)

What's Changed

  • Fix get_parameters

Version 2024.8.5 (2024-08-17)

What's Changed

  • Add un_ignore_candidates to central

Version 2024.8.4 (2024-08-16)

What's Changed

  • Make load only relevant paramset descriptions configurable
  • Add UN_IGNORE_WILDCARD to get_parameters

Version 2024.8.3 (2024-08-15)

What's Changed

  • Ignore parameters on un ignore parameter list

Version 2024.8.2 (2024-08-15)

What's Changed

  • Add CED for ELV-SH-WUA / HmIP-WUA
  • Refactor get_parameters for unignore_candidates

Version 2024.8.1(2024-08-02)

What's Changed

  • Refactor entity path
  • Allow undefined generic entities besides CE

Version 2024.8.0 (2024-08-01)

What's Changed

  • Reduce data load, if only device description is updated

Version 2024.7.1 (2024-07-27)

What's Changed

  • Enable button lock for hm devices

Version 2024.7.0 (2024-07-26)

What's Changed

  • Rename last_updated -> modified_at
  • Rename last_refreshed -> refreshed_at
  • Add button lock CE
  • Add time units to HmIP-RGBW calls

Version 2024.5.6 (2024-05-31)

What's Changed

  • Catch TypeError on SysVar import

Version 2024.5.5 (2024-05-29)

What's Changed

  • Fix address for bidcos wired virtual device

Version 2024.5.4 (2024-05-23)

What's Changed

  • Enable CE visible entities by default

Version 2024.5.3 (2024-05-16)

What's Changed

  • Fix value assignment to lock enums
  • Set open tilt level back to 100%
  • Use PEP 695 typing

Version 2024.5.2 (2024-05-14)

What's Changed

  • Move command_queue handling from device to channel
  • Add level sensors to cover/blind
  • Allow changing level or tilt while blind is moving by @sleiner

Version 2024.5.1 (2024-05-06)

What's Changed

  • Improve callback register/unregister

Version 2024.5.0 (2024-05-01)

What's Changed

  • Make some items from value_property to property
  • Rename callbacks
  • Fix Homegear reconnect
  • Add COLOR_BEHAVIOUR to HmIP-BSL

Version 2024.4.12 (2024-04-24)

What's Changed

  • Fix missing param in unregister_entity_updated_callback
  • Set open tilt level to 50%

Version 2024.4.11 (2024-04-24)

What's Changed

  • Add command queue
  • Move open/close from IpBlind to Blind
  • Use central_client_factory fixture
  • Ensure central.stop() is called in tests

Version 2024.4.10 (2024-04-21)

What's Changed

  • Add wait_for_callback to collector
  • Wait for target value in wait_for_state_change_or_timeout

Version 2024.4.9 (2024-04-20)

What's Changed

  • Decompose combined parameter
  • Return affected entity keys for service calls
  • Add callback to unregister on register return
  • Add option to wait for set_value/put_paramset callback

Version 2024.4.8 (2024-04-13)

What's Changed

  • Make entity event async
  • Extract looper from central and reuse for json/xml_rpc
  • Move loop_check to async_support
  • Record last value send

Version 2024.4.7 (2024-04-13)

What's Changed

  • Rename loop_safe to loop_check
  • Reduce loop_check to minimum
  • Update ruff rules / requirements

Version 2024.4.6 (2024-04-10)

What's Changed

  • Remove unused callback from tests
  • Add loop_safe annotation
  • Remove entity_data_event_callback
  • Make backend_system_callback loop aware

Version 2024.4.5 (2024-04-09)

What's Changed

  • Align callback naming

Version 2024.4.4 (2024-04-09)

What's Changed

  • Unify entity update/refresh events

Version 2024.4.3 (2024-04-09)

What's Changed

  • Restructure check_connection
  • Make xml_rpc event async
  • Block central stop until tasks are finished

Version 2024.4.2 (2024-04-08)

What's Changed

  • Adjust cache max size
  • Update ruff rules

Version 2024.4.1 (2024-04-05)

What's Changed

  • Fix register refreshed entity
  • Refactor callback naming

Version 2024.4.0 (2024-04-02)

What's Changed

  • Remove support for python 3.11
  • Remove python 3.11 for github tests and pylint
  • Use py 3.12 for mypy and pylint
  • Use more list comprehension
  • Customize HmIP-DRG-DALI

Version 2024.3.1 (2024-03-12)

What's Changed

  • Add additional parameter to HBW-LC4-IN4-DR
  • Add check if init is running in the main thread

Version 2024.3.0 (2024-03-01)

What's Changed

  • Add HBW-LC4-IN4-DR

Version 2024.2.4 (2024-02-13)

What's Changed

  • Group entities to sub devices / base channels
  • Add mapping for fixed color channel
  • Refactor entity name data

Version 2024.2.3 (2024-02-12)

What's Changed

  • Rename func to make_ce_func
  • Add fixed mapping for HBW-LC-RGBWW-IN6-DR
  • Fix mapping of HmIP-HDM

Version 2024.2.2 (2024-02-11)

What's Changed

  • Add option to un ignore mechanism to ignore the automatic creation of custom entities by device type
  • Remove incomplete/wrong mapping for HBW-LC-RGBWW-IN6-DR
  • Fix mapping of HmIP-HDM

Version 2024.2.1 (2024-02-02)

What's Changed

  • Accept float as input for int numbers

Version 2024.2.0 (2024-02-01)

What's Changed

  • Ignore empty unignore line
  • All MASTER parameters must be unignored

Version 2024.1.11 (2024-01-31)

What's Changed

  • Remove deprecation warnings for py3.12
  • Fix/improve unignore search

Version 2024.1.10 (2024-01-28)

What's Changed

  • Remove old complex format for unignore

Version 2024.1.9 (2024-01-26)

What's Changed

  • Move product group identification to client
  • Add new pattern for unignore (parameter:paramset_key@device_type:channel_no)
  • Allow all as unignore parameter for device_type and channel_no

Version 2024.1.8 (2024-01-12)

What's Changed

  • Store old_value in entity model

Version 2024.1.7 (2024-01-12)

What's Changed

  • Reload master data after config pending event
  • Allow direct_call without cache wait time

Version 2024.1.6 (2024-01-11)

What's Changed

  • Fix unignore doc and improve unignore tests
  • Move unignore check to entity

Version 2024.1.5 (2024-01-09)

What's Changed

  • Remove effects from HmIP-RGBW when in PWM mode

Version 2024.1.4 (2024-01-07)

What's Changed

  • Fix relevant entities for HmIP-RGBW

Version 2024.1.3 (2024-01-07)

What's Changed

  • Add duration=111600 when ramp_time used for HmIP-RGBW

Version 2024.1.2 (2024-01-07)

What's Changed

  • Only consider relevant entities for HmIP-RGBW

Version 2024.1.1 (2024-01-05)

What's Changed

  • Allow ordered execution of collector paramsets
  • Add python 3.12 for github tests and pylint

Version 2024.1.0 (2024-01-03)

What's Changed

  • Add duration=0 when ramp_time used for HmIP-RGBW

Version 2023.12.4 (2023-12-19)

What's Changed

  • Add HB-LC-Bl1-Velux to cover

Version 2023.12.3 (2023-12-16)

What's Changed

  • Set attributes of dataclasses
  • Add another reason to ping pong mismatch

Version 2023.12.2 (2023-12-15)

What's Changed

  • Save all rooms to entity model

Version 2023.12.1 (2023-12-01)

What's Changed

  • Central name must not contain the identifier separator (@)

Version 2023.12.0 (2023-12-01)

What's Changed

  • Add support for away_mode and classic homematic thermostats
  • Collect config validation errors

Version 2023.11.4 (2023-11-22)

What's Changed

  • Don't send ts with ping pong if it should not be handled

Version 2023.11.3 (2023-11-21)

What's Changed

  • Clear ping pong cache on proxy init

Version 2023.11.2 (2023-11-21)

What's Changed

  • Refactor ping pong, remove semaphore

Version 2023.11.1 (2023-11-20)

What's Changed

  • Improve ping/pong mechanism. Fire event, if mismatch is 15 within 5 Minutes

Version 2023.11.0 (2023-11-01)

What's Changed

  • Use last_refreshed for validation check

Version 2023.10.14 (2023-10-29)

What's Changed

  • Cleanup cover
  • Replace last_updated by last_refreshed
  • Rename fire events
  • Switch formatting from black to ruff-format

Version 2023.10.13 (2023-10-28)

What's Changed

  • Fix service enable_away_mode_by_calendar
  • Add class method default_platform

Version 2023.10.12 (2023-10-15)

What's Changed

  • Ignore switch to sensor if un ignored
  • Update un ignore documentation

Version 2023.10.11 (2023-10-13)

What's Changed

  • Remove WrapperEntity

Version 2023.10.10 (2023-10-12)

What's Changed

  • Align method signatures
  • Remove get_update_entities

Version 2023.10.9 (2023-10-12)

What's Changed

  • Fix register_update_callback for update
  • Add filter options to device.get_entity*
  • Send relevant entities instead of devices in callback

Version 2023.10.8 (2023-10-11)

What's Changed

  • Register external sources with custom identifier
  • Remove subscribed_entity_unique_identifiers
  • Rename custom_identifier to custom_id
  • Rename unique_identifier to unique_id

Version 2023.10.7 (2023-10-10)

What's Changed

  • Adjust typing after move to more enums
  • Add measure_execution_time to writing methods
  • Fix send sysvar #1249
  • Add HmIPW-SCTHD

Version 2023.10.6 (2023-10-08)

What's Changed

  • Add faultCode and faultString to xmlrpc.client.Fault
  • Use Mapping/Set for readonly access
  • Use enum for CE fields
  • Use Parameter for ED

Version 2023.10.5 (2023-10-07)

What's Changed

  • Add started property to central
  • Rename:
  • value_list -> values
  • effect_list -> effects
  • Add more checks to get/set value from/tp values
  • Use more tuple instead of list
  • Cleanup code
  • Collect subscribed entities in central

Version 2023.10.4 (2023-10-03)

What's Changed

  • Cleanup exception handling
  • Reduce log output for InternalBackendException

Version 2023.10.3 (2023-10-03)

What's Changed

  • Small fix to re raise InternalBackendException

Version 2023.10.2 (2023-10-03)

What's Changed

  • Catch 'internal error' on _get_auth_enabled. Relevant for for CCU2 users

Version 2023.10.1 (2023-10-02)

What's Changed

  • Use enum for JsonRPC and XmlRPC methods
  • Get supported JsonRPC and XmlRPC methods and check against used methods

Version 2023.10.0 (2023-10-01)

What's Changed

  • Code cleanup
  • Remove Hm prefix from enums
  • Use enum for parameters
  • Use more existing constants

Version 2023.9.8 (2023-09-30)

What's Changed

  • Improve caching
  • Cleanup cache naming
  • Remove max_age from most method signatures
  • Simplify data cache
  • Rename some cache methods
  • Remove attr prefix

Version 2023.9.7 (2023-09-29)

What's Changed

  • Add check to BaseHomematicException
  • Reduce log level to 'warning' for get_all_device_data 'JSONDecodeError' exceptions
  • Update requirements

Version 2023.9.6 (2023-09-29)

What's Changed

  • Use freezegun for climate test
  • Update ReGa-Script fetch_all_device_data.fn by @Baxxy13
  • Parameterize call to fetch_all_device_data.fn
  • Simplify json rpc post code
  • Improve for ConnectionProblemIssuer json rpc
  • Improve handle_exception_log
  • Avoid repeated logs
  • Move get_system_information to json_rpc
  • Add str to client and central

Version 2023.9.5 (2023-09-23)

What's Changed

  • Cleanup light code
  • Use more enums for climate, cover, lock
  • Use TypedDict for light, siren args
  • Update requirements

Version 2023.9.4 (2023-09-21)

What's Changed

  • Use more assignment-expr
  • Make _LOGGER final

Version 2023.9.3 (2023-09-18)

What's Changed

  • Improve typing
  • Refactor get_paramset_description

Version 2023.9.2 (2023-09-17)

What's Changed

  • Cleanup logger
  • Refactor client and central modules
  • Move bind_collector to platforms.entity
  • Move config/value_property to platforms.decorators
  • Move measure_execution_time to decorators
  • Move definition exporter to device
  • Move HM_INTERFACE_EVENT_SCHEMA to central
  • Update requirements

Version 2023.9.1 (2023-09-06)

What's Changed

  • Re add channel 7 for HmIPW-WRC6
  • Reduce log level for exceptions in fetch_paramset_description
  • Filter SSLErrors by code

Version 2023.9.0 (2023-09-03)

What's Changed

  • Refactor cover api

Version 2023.8.14 (2023-08-30)

What's Changed

  • Reduce visibility of local constants
  • Convert StrEnum and IntEnum in proxy

Version 2023.8.13 (2023-08-28)

What's Changed

  • Fix measure_execution_time decorator for sync methods
  • Add async support to callback_system_event
  • Replace constants enums

Version 2023.8.12 (2023-08-27)

What's Changed

  • Remove unused const
  • Remove dead code
  • Optimize get readable entities for MASTER

Version 2023.8.11 (2023-08-25)

What's Changed

  • Always set color_behaviour for HmIPW-WRC6

Version 2023.8.10 (2023-08-25)

What's Changed

  • Extend HmIPW-WRC6 implementation

Version 2023.8.9 (2023-08-23)

What's Changed

  • Add decorator to measure function execution time
  • Extend HmIPW-WRC6 implementation

Version 2023.8.8 (2023-08-21)

What's Changed

  • Fix get_all_system_variables return value

Version 2023.8.7 (2023-08-21)

What's Changed

  • Add SSLError to XmlRpcProxy and JsonRpcAioHttpClient
  • Make integration more robust against json result failures

Version 2023.8.6 (2023-08-17)

What's Changed

  • Remove use_caches and load_un_ignore from central config
  • Remove obsolete comments
  • Align sslcontext creation with Home Assistant

Version 2023.8.5 (2023-08-16)

What's Changed

  • Improve testing:
  • Set client_session to None
  • Remove unnecessary async from create_central
  • Make start_direct a config option

Version 2023.8.4 (2023-08-14)

What's Changed

  • Improve testing:
  • Extract ClientLocal code from production code
  • Use own main package for ClientLocal
  • Patch permanent till teardown

Version 2023.8.3 (2023-08-12)

What's Changed

  • Update project setup
  • Restructure test helper
  • Add ping pong tests
  • Avoid multiple central starts

Version 2023.8.2 (2023-08-06)

What's Changed

  • Improve exception and log handling

Version 2023.8.1 (2023-08-04)

What's Changed

  • Prepare backend for HA issue usage

Version 2023.8.0 (2023-08-01)

What's Changed

  • Remove only the starting device name from entity name
  • Remove title from program and sysvar names

Version 2023.7.6 (2023-07-29)

What's Changed

  • Refactor Json error handling / logging
  • Use ping pong only for CCU
  • Add primary_client attribute to central_unit

Version 2023.7.5 (2023-07-26)

What's Changed

  • Add SystemInformation to client api
  • Send credentials on XmlRPC api only when authentication is enabled in CCU
  • Remove support for python 3.10
  • Add available_interfaces to SystemInformation

Version 2023.7.4 (2023-07-18)

What's Changed

  • Update requirements
  • Add identifier to device
  • Rename ENTITY_NO_CREATE to NO_CREATE
  • Extend Channel
  • Add channel related attributes to entity
  • Add kwargs to update_entity
  • Call update_entity for ENTITY_EVENTS
  • Ignore click events on plugs
  • Add manufacturer to device

Version 2023.7.3 (2023-07-13)

What's Changed

  • Fire interface event about ping/pong mismatch
  • Add message to fire_interface_event
  • Add schema for interface event

Version 2023.7.2 (2023-07-12)

What's Changed

  • Add new Events PRESS_LOCK and PRESS_UNLOCK for HmIP-WKP

Version 2023.7.1 (2023-07-11)

What's Changed

  • Log an error about the ping/pong count mismatch

Version 2023.7.0 (2023-07-07)

What's Changed

  • Project file maintenance
  • Replace isort with ruff
  • Move overlapping pylint rules to ruff, disable mypy overlap

Version 2023.6.1 (2023-06-23)

What's Changed

  • Fix tunable white support for hmIP-RGBW
  • Avoid creating entities that are not usable in selected device operation mode for hmIP-RGBW
  • Update requirements

Version 2023.6.0 (2023-06-01)

What's Changed

  • Update requirements
  • Do not create update entities for virtual remotes
  • Cleanup FIX_UNIT_BY_PARAM

Version 2023.5.2 (2023-05-14)

What's Changed

  • Improve update_device_firmware

Version 2023.5.1 (2023-05-11)

What's Changed

  • Refactor device description cache handling
  • Add device firmware update handling
  • Make interface an enum
  • Add product group to device

Version 2023.5.0 (2023-05-01)

What's Changed

  • Remove unsupported on_time / refactor HmIP-RGBW
  • Update requirements

Version 2023.4.5 (2023-04-28)

What's Changed

  • Fix division by zero for HmIP-RGBW
  • Remove color_temperature from RGBW

Version 2023.4.4 (2023-04-28)

What's Changed

  • Add missing channel for HmIP-RGBW

Version 2023.4.3 (2023-04-27)

What's Changed

  • Update requirements
  • Add HmIP-RGBW

Version 2023.4.2 (2023-04-24)

What's Changed

  • Update requirements
  • Fix cover (HDM2) no longer working

Version 2023.4.0 (2023-04-16)

What's Changed

  • Update requirements
  • Add log message to negative password check
  • Fix 'Cannot parse hex-string value'

Version 2023.3.1 (2023-03-17)

What's Changed

  • Add name to tasks
  • Improve typing
  • Move callback calls into exception block
  • Remove avoidable usage of deepcopy
  • Add dependabot
  • Update requirements
  • Drop pyupgrade, autoflake, flake8 in favor of ruff
  • Refactor cover, add set_combined_position
  • Add is_in_multiple_channels to base entity

Version 2023.3.0 (2023-03-01)

What's Changed

  • Update ruff, adjust module aliases
  • Fix spamming CCU logs with errors (#981)

Version 2023.2.11 (2023-02-24)

What's Changed

  • Update ruff, fix comments
  • Switch to orjson
  • Fix climate: compare set temperature to target temperature

Version 2023.2.10 (2023-02-23)

What's Changed

  • Use sets for central callbacks
  • Add get_all_entities for device

Version 2023.2.9 (2023-02-18)

What's Changed

  • Fix property types
  • Ensure modules for platforms are loaded
  • Use local dicts for device lists
  • Clear central data cache if identified as outdated
  • Avoid redundant cache loads within init phase
  • Extract value preparation from send_value
  • Differentiate between input and default parameter type
  • Fix asyncio-dangling-task (RUF006)
  • Add typed dict for light and siren

Version 2023.2.8 (2023-02-11)

What's Changed

  • Add project setup script
  • Add entity_data event
  • Add payload mixin
  • Cleanup module dependencies
  • Use cache decorators for some high-traffic methods
  • Allow that channel_no could be None
  • Add and use get_channel_address
  • Add HmIP-SWSD as siren
  • Raise CALLBACK_WARN_INTERVAL to 10 minutes

Version 2023.2.7 (2023-02-07)

What's Changed

  • Disable validation of state change for action and button
  • Check if entity is writable on send

Version 2023.2.6 (2023-02-07)

What's Changed

  • Add missing bind_collector
  • Add more Final typing
  • Add option to collector to disable put_paramset
  • Add on_time Mixin to temporary store on_time
  • Add pre-commit check
  • Basic linting for tests

Version 2023.2.5 (2023-02-05)

What's Changed

  • Fix GitHub build/publish
  • Add comments to parameter_visibility
  • Use put_paramset only when there is more than one parameter to sent
  • Use only one implementation for garage doors (HO/TM)
  • Avoid backend calls if value/state doesn't change
  • If an entity (e.g. switch) has only one parameter that represents its state, then a call to the backend will be made, if the parameter value sent is not identical to the current state.
  • If an entity (e.g. cover, climate, light) has multiple parameters that represent its state, then a call to the backend will be made, if one of these parameter values sent is not identical to its current state.
  • Not covered by this approach:
    • platforms: lock and siren.
    • services: stop_cover, stop_cover_tilt, enable_away_mode_*, disable_away_mode, set_on_time_value
    • system variables
  • Add virtual channels for HmIP cover/blind:
  • Channel no as examples from HmIP-BROLL. The implementation of the first actor channel (4) remains unchanged, which means that this channel (4) shows the correct cover position from sensor channel (3). The other actor channels (5+6) are generated as initially deactivated and only use the cover position from their own channel after activation.

Version 2023.2.1 (2023-02-01)

What's Changed

  • Separate check for parameter is un_ignored based on if it should be hidden or not

Version 2023.2.0 (2023-02-01)

What's Changed

  • Log validation exceptions in central
  • Add typing to decorators
  • Add tests for better code coverage

Version 2023.1.8 (2023-01-29)

What's Changed

  • Cleanup LOGGER messages
  • Cleanup code base with ruff
  • Ensure the signal handler gets called at most once by @mtdcr
  • Fix stop central, if another central is active on the same XmlRPC server
  • JsonRpcAioHttpClient: Allow empty password by @mtdcr
  • Remove VALVE_STATE from HmIPW-FALMOT-C12
  • Remove put_paramset from custom_entity
  • Remove set_value, put_paramset from central
  • Remove support for python 3.9
  • Remove to int converter for HmIP-SCTH230 CONCENTRATION
  • Replace old-style union syntax
  • Validate password with regex (warning only!)

Version 2023.1.7 (2023-01-24)

What's Changed

  • Aggregate calls to backend
  • Fix HmIP-MOD-TM: inverted direction

Version 2023.1.6 (2023-01-22)

What's Changed

  • Add a new custom entity type for windows drive
  • Return True if sending service calls succeed

Version 2023.1.5 (2023-01-20)

What's Changed

  • Add ExtendedConfig and use for additional_entities
  • Add ExtendedConfig to custom entities
  • Add LED_STATUS to HM-OU-LED16
  • Allow multiple CustomConfigs for a hm device
  • Cleanup test imports
  • Increase the line length to 99
  • Remove LOWBAT from HM-LC-Sw1-DR
  • Remove obsolete ED_ADDITIONAL_ENTITIES_BY_DEVICE_TYPE from entity_definition
  • Replace custom entity config data structure by CustomConfig
  • Sort lists in parameter_visibility.py

Version 2023.1.4 (2023-01-16)

What's Changed

  • Add helper, central tests
  • Add more tests and test based refactorings
  • Reduce backend calls and logging during lost connection
  • Remove obsolete parse_ccu_sys_var
  • Update color_conversion threshold by @guillempages

Version 2023.1.3 (2023-01-13)

What's Changed

  • Unify event parameters
  • Refactor entity.py for better event support
  • Fix wrong warning after set_system_variable
  • Add validation to event_data

Version 2023.1.2 (2023-01-10)

What's Changed

  • Remove OPERATING_VOLTAGE from HmIP-BROLL, HmIP-FROLL
  • Remove loop from test signature
  • Cleanup ignore/unignore handling and add tests

Version 2023.1.1 (2023-01-09)

What's Changed

  • No longer create ClientSession in json_rpc_client for tests
  • Add backend tests
  • Use mocked local client to check method_calls
  • Remove sleep after connection_checker stops
  • Remove LOWBAT from HM-LC-Sw1-Pl, HM-LC-Sw2-FM
  • Simplify entity de-/registration
  • Refactor add/delete device and add tests
  • Add un_ignore_list to test config
  • Allow unignore for DEVICE_ERROR_EVENTS

Version 2023.1.0 (2023-01-01)

What's Changed

  • API Cleanup
  • Allow to disable cache
  • Allow to disable un_ignore load
  • Add local client
  • Use local client in tests
  • Move event() code to central_unit
  • Move listDevices() code to central_unit

Version 2022.12.12 (2022-12-30)

What's Changed

  • Add un_ignore list to central config
  • Fix entity_definition schema
  • Rename cache_dict to persistent_cache
  • Reduce access to internal complex objects for custom_component

Version 2022.12.11 (2022-12-28)

What's Changed

  • Rename climate presets from 'Profile ' to 'week*program*'
  • Add support for python 3.11

Version 2022.12.10 (2022-12-27)

What's Changed

  • Make constant assignment final
  • Fix native device units

Version 2022.12.9 (2022-12-25)

What's Changed

  • Remove empty unit for numeric sysvars
  • Add enable_default to entity
  • Remove some warn level parameters from ignore list

Version 2022.12.8 (2022-12-22)

What's Changed

  • Reformat code / check with flake8
  • Refactor entity inheritance

Version 2022.12.7 (2022-12-21)

What's Changed

  • Send ERROR_* parameters as homematic.device_error event

Version 2022.12.6 (2022-12-20)

What's Changed

  • Add additional checks for custom entities
  • Code Cleanup

Version 2022.12.5 (2022-12-17)

What's Changed

  • Code Cleanup
  • Remove sub_type from model to simplify code
  • Remove obsolete methods
  • Refactor binary_sensor check
  • Convert value_list to tuple
  • Use tuple for immutable lists

Version 2022.12.4 (2022-12-13)

What's Changed

  • Fix disable away_mode in climate. Now goes back to the origin control_mode.

Version 2022.12.3 (2022-12-12)

What's Changed

  • Disable temperature validation for setting to off for HM heating group HM-CC-VG-1

Version 2022.12.2 (2022-12-09)

What's Changed

  • Add HM-LC-AO-SM as light
  • Remove hub from HmPlatform
  • Hub is no longer an entity

Version 2022.12.1 (2022-12-01)

What's Changed

  • Improve naming of modules
  • Add new platform for text sysvars

Version 2022.12.0 (2022-12-01)

What's Changed

  • Add transition to light turn_off
  • Remove min brightness of 10 for lights

Version 2022.11.2 (2022-11-13)

What's Changed

  • Generalize some collection helpers

Version 2022.11.1 (2022-11-03)

What's Changed

  • Rename protected attributes to _attr*
  • Code cleanup
  • Add option to wrap entities to a different platform
  • Wrap LEVEL of HmIP-TRV*, HmIP-HEATING to sensor

Version 2022.11.0 (2022-11-02)

What's Changed

  • Rename ATTR*HM*_ to HM_
  • Use generic property implementation

Version 2022.10.10 (2022-10-25)

What's Changed

  • Use min_temp if target_temp < min_temp
  • Remove event_loop from signatures
  • Refactor central_config, create xml_rpc server in central_unit

Version 2022.10.9 (2022-10-23)

What's Changed

  • Fix don't hide unignored parameters
  • Refactor refesh_entity_data. Allow restriction to paramset and cache age.

Version 2022.10.8 (2022-10-21)

What's Changed

  • Add semaphore to fetch sysvar and programs from backend

Version 2022.10.7 (2022-10-20)

What's Changed

  • Accept some existing prefix for sysvars and programs to avoid additional prefixing with Sv* / P*
  • accepted sysvar prefixes: V*, Sv*
  • accepted program prefixes: P*, Prg*
  • Read min/max temperature for climate devices
  • Min set temperature for thermostats is now 5.0 degree. 4.5. degree is only off

Version 2022.10.6 (2022-10-15)

What's Changed

  • Replace data_* by HmDataOperationResult
  • Use HmHvacMode HEAT instead of AUTO for simple thermostats
  • Add HUMIDITY and ACTUAL_TEMPERATURE to heating groups

Version 2022.10.5 (2022-10-11)

What's Changed

  • Set Hm Thermostat to manual mode before switching off

Version 2022.10.4 (2022-10-10)

What's Changed

  • Allow entity creation for some internal parameters

Version 2022.10.3 (2022-10-10)

What's Changed

  • Fix HM Blind/Cover custom entity types

Version 2022.10.2 (2022-10-08)

What's Changed

  • Make connection checker more resilient:
  • Reduce connection checker interval to 15s
  • Connection is not connected, if three consecutive checks fail.

Version 2022.10.1 (2022-10-05)

What's Changed

  • Ignore OPERATING_VOLTAGE for HmIP-PMFS
  • Add ALPHA-IP-RBG

Version 2022.10.0 (2022-10-01)

What's Changed

  • Rename hub event
  • Remove "Servicemeldungen" from sysvars. It's already included in the hub_entity (sensor.{instance_name})

Version 2022.9.1 (2022-09-20)

What's Changed

  • Improve XmlServer shutdown
  • Add name to threads and executors
  • Improve ThreadPoolExecutor shutdown

Version 2022.9.0 (2022-09-02)

What's Changed

  • Exclude value from event_data if None

Version 2022.8.15 (2022-08-27)

What's Changed

  • Fix select entity detection

Version 2022.8.14 (2022-08-23)

What's Changed

  • Exclude STRING sysvar from extended check

Version 2022.8.13 (2022-08-23)

What's Changed

  • Allow three states for a forced availability of a device

Version 2022.8.12 (2022-08-23)

What's Changed

  • Add device_type to device availability event
  • Code deduplication and small fixes

Version 2022.8.11 (2022-08-18)

What's Changed

  • Adjust logging (level and message)
  • Delete sysvar if type changes

Version 2022.8.10 (2022-08-16)

What's Changed

  • Improve readability of XmlRpc server
  • Remove module data

Version 2022.8.9 (2022-08-16)

What's Changed

  • Fix check if thread is started

Version 2022.8.8 (2022-08-16)

What's Changed

  • Remove unused local_ip from XmlRPCServer
  • Create all XmlRpc server by requested port(s)

Version 2022.8.7 (2022-08-12)

What's Changed

  • Fix hs_color for CeColorDimmer(HM-LC-RGBW-WM)

Version 2022.8.6 (2022-08-12)

What's Changed

  • Reduce api calls for light

Version 2022.8.5 (2022-08-11)

What's Changed

  • Add cache for rega script files

Version 2022.8.4 (2022-08-08)

What's Changed

  • Add platform as field and remove obsolete constructors
  • Reduce member

Version 2022.8.3 (2022-08-07)

What's Changed

  • Remove CHANNEL_OPERATION_MODE from cover ce
  • Refactor get_value/set_value
  • Remove domain from model
  • Rename unique_id to unique_identifier
  • Remove should_poll from model

Version 2022.8.2 (2022-08-02)

What's Changed

  • Remove obsolete methods
  • Remove obsolete device_address parameter
  • Rename sysvar to hub entity
  • Add program buttons

Version 2022.8.0 (2022-08-01)

What's Changed

  • Fix pylint, mypy issues due to newer versions
  • Remove properties of final members
  • Add types to Final
  • Init entity fields in init method
  • Remove device_info from model
  • Remove attributes from model

Version 2022.7.14 (2022-07-28)

What's Changed

  • Add HmIP-BS2 to custom entities
  • Remove force and add call_source for getValue

Version 2022.7.13 (2022-07-22)

What's Changed

  • Cleanup API
  • Limit init cache time usage
  • Avoid repetitive calls to CCU within max_age_seconds

Version 2022.7.12 (2022-07-21)

What's Changed

  • Add ELV-SH-BS2 to custom entities
  • Code Cleanup
  • Rearrange validity check
  • Cleanup entity code

Version 2022.7.11 (2022-07-19)

What's Changed

  • Raise interval for alive checks

Version 2022.7.10 (2022-07-19)

What's Changed

  • Use entities instead of values inside custom entities
  • Fix _check_connection for Homegear/CCU

Version 2022.7.9 (2022-07-17)

What's Changed

  • Remove state_uncertain from default attributes

Version 2022.7.8 (2022-07-13)

What's Changed

  • Fix entity update

Version 2022.7.7 (2022-07-12)

What's Changed

  • Fix naming of custom entity

Version 2022.7.6 (2022-07-12)

What's Changed

  • Fix last_state handling for custom entities

Version 2022.7.5 (2022-07-11)

What's Changed

  • Rename value_uncertain to state_uncertain
  • Add state_uncertain to custom entity

Version 2022.7.4 (2022-07-11)

What's Changed

  • Set value_uncertain to True if no data could be loaded from CCU

Version 2022.7.3 (2022-07-10)

What's Changed

  • Set default value for hub entity to None

Version 2022.7.2 (2022-07-10)

What's Changed

  • Align entity naming to HA entity name
  • Ensure entity value refresh after reconnect
  • Ignore further parameters by device

Version 2022.7.1 (2022-07-07)

What's Changed

  • Better distinguish between NO_CACHE_ENTRY and None

Version 2022.7.0 (2022-07-07)

What's Changed

  • Switch to calendar versioning

Version 1.9.4 (2022-07-03)

What's Changed

  • Load MASTER data on initial load

Version 1.9.3 (2022-07-02)

What's Changed

  • Fix export of device definitions

Version 1.9.2 (2022-07-01)

What's Changed

  • Use CHANNEL_OPERATION_MODE for devices with MULTI_MODE_INPUT_TRANSMITTER, KEY_TRANSCEIVER channels
  • Re-Add HmIPW-FIO6 to custom device handling

Version 1.9.1 (2022-06-29)

What's Changed

  • Remove HmIPW-FIO6 from custom device handling

Version 1.9.0 (2022-06-09)

What's Changed

  • Refactor entity name creation
  • Cleanup entity selection
  • Add button to virtual remote

Version 1.8.6 (2022-06-07)

What's Changed

  • Code cleanup

Version 1.8.5 (2022-06-06)

What's Changed

  • Remove sysvars if deleted from CCU
  • Add check for sysvar type in sensor
  • Remove unused sysvar attributes
  • Refactor HmEntityDefinition

Version 1.8.4 (2022-06-04)

What's Changed

  • Refactor all sysvar script
  • Use ext_marker script in combination with SysVar.getAll

Version 1.8.3 (2022-06-04)

What's Changed

  • Refactor sysvar creation eventing

Version 1.8.2 (2022-06-03)

What's Changed

  • Fix build

Version 1.8.1 (2022-06-03)

What's Changed

  • Use marker in sysvar description for extended sysvars

Version 1.8.0 (2022-06-02)

What's Changed

  • Enable additional sysvar entity types

Version 1.7.3 (2022-06-01)

What's Changed

  • Add more debug logging

Version 1.7.2 (2022-06-01)

What's Changed

  • Better differentiate between float and int for sysvars
  • Switch from # as unit placeholder for sysvars to ' '
  • Move sysvar length check to sensor

Version 1.7.1 (2022-05-31)

What's Changed

  • Rename parameter channel_address to address for put/get_paramset

Version 1.7.0 (2022-05-31)

What's Changed

  • Refactor system variables
  • Add more types for sysvar entities

Version 1.6.2 (2022-05-30)

What's Changed

  • Add more options for boolean conversions

Version 1.6.1 (2022-05-29)

What's Changed

  • Fix entity definition for HMIP-HEATING

Version 1.6.0 (2022-05-29)

What's Changed

  • Add impulse event
  • Add LEVEL and STATE to HmIP-Heating group to display hvac_action
  • Add device_type as model to attributes

Version 1.5.4 (2022-05-24)

What's Changed

  • Add function attribute only if set

Version 1.5.3 (2022-05-24)

What's Changed

  • Rename subsection to function

Version 1.5.2 (2022-05-24)

What's Changed

  • Add subsection to attributes
  • Use parser for internal sysvars

Version 1.5.0 (2022-05-23)

What's Changed

  • Add option to replace too technical parameter name by friendly parameter name
  • Ignore more parameters by device
  • Use dataclass for sysvars
  • Limit sysvar length to 255 chars due to HA limitations

Version 1.4.0 (2022-05-16)

What's Changed

  • Block parameters by device_type that should not create entities in HA
  • Fix remove instance on shutdown

Version 1.3.1 (2022-05-13)

What's Changed

  • Increase connection timeout(30s->60s) and reconnect interval(90s->120s) to better support slower hardware

Version 1.3.0 (2022-05-06)

What's Changed

  • Use unit for vars, if available
  • Remove special handling for pydevccu
  • Remove set boost mode to false, when preset is none for bidcos climate entities

Version 1.2.2 (2022-05-02)

What's Changed

  • Fix light channel for multi dimmer

Version 1.2.1 (2022-04-27)

What's Changed

  • Fix callback alive check
  • Reconnect clients based on outstanding xml callback events

Version 1.2.0 (2022-04-26)

What's Changed

  • Cleanup build

Version 1.1.5 (2022-04-25)

What's Changed

  • Reorg light attributes
  • Add on_time to light and switch

Version 1.1.4 (2022-04-21)

What's Changed

  • Use min as default if default is unset for parameter_data

Version 1.1.3 (2022-04-20)

What's Changed

  • Add CeColorDimmer
  • Fix interface_event

Version 1.1.2 (2022-04-12)

What's Changed

  • Add extra_params to _post_script
  • Add set_system_variable with string value
  • Disallow html tags in string system variable

Version 1.1.1 (2022-04-11)

What's Changed

  • Read # Version and serial in get_client

Version 1.1.0 (2022-04-09)

What's Changed

  • Add BATTERY_STATE to DEFAULT_ENTITIES
  • Migrate device_info to dataclass
  • Add rega script (provided by @baxxy13) to get serial from CCU
  • Add method to clean up cache dirs

Version 1.0.6 (2022-04-06)

What's Changed

  • Revert to XmlRPC getValue and getParamset for CCU

Version 1.0.5 (2022-04-05)

What's Changed

  • Limit hub_state to ccu only

Version 1.0.4 (2022-03-30)

What's Changed

  • Use max # Version of interfaces for backend version
  • Remove device as parameter from parameter_availability
  • Add XmlRPC.listDevice to Client
  • Add start_direct for starts without waiting for events (only for temporary usage)

Version 1.0.3 (2022-03-30)

What's Changed

  • Revert to XmlRPC get# Version for CCU

Version 1.0.2 (2022-03-29)

What's Changed

  • Revert to XmlRPC getParamsetDescription for CCU

Version 1.0.1 (2022-03-29)

What's Changed

  • Add central_id for uniqueness of heating groups, sysvars and hub

Version 1.0.0 (2022-03-28)

What's Changed

  • Simplify json usage
  • Move json methods to json client
  • Make json client independent from central config
  • Add get_serial to validate
  • Use serial for sysvar unique_ids
  • Rename domain for test and example from hahm to homematicip_local

Version 0.38.5 (2022-03-22)

What's Changed

  • Use interface_id for interface events
  • Add support for color temp dimmer

Version 0.38.4 (2022-03-21)

What's Changed

  • Fix interface name for BidCos-Wired

Version 0.38.3 (2022-03-20)

What's Changed

  • Add check for available API method to identify BidCos Wired
  • Cleanup backend identification

Version 0.38.2 (2022-03-20)

What's Changed

  • Catch SysVar parsing exceptions

Version 0.38.1 (2022-03-20)

What's Changed

  • Fix lock/unlock for HM-Sec-Key

Version 0.38.0 (2022-03-20)

What's Changed

  • Add central validation
  • Add jso_rpc.post_script

Version 0.37.7 (2022-03-18)

What's Changed

  • Add additional system_listMethods to avoid errors on CCU

Version 0.37.6 (2022-03-18)

What's Changed

  • Add JsonRPC.Session.logout before central stop to avoid warn logs at CCU.

Version 0.37.5 (2022-03-18)

What's Changed

  • Add api for available interfaces
  • Send event if interface is not available
  • Don't block available interfaces

Version 0.37.4 (2022-03-17)

What's Changed

  • Fix reload paramset
  • Fix value converter

Version 0.37.3 (2022-03-17)

What's Changed

  • Cleanup caching code

Version 0.37.2 (2022-03-17)

What's Changed

  • Use homematic script to fetch initial data for CCU/HM

Version 0.37.1 (2022-03-16)

What's Changed

  • Add semaphore(1) to improve cache usage (less api calls)

Version 0.37.0 (2022-03-15)

What's Changed

  • Avoid unnecessary prefetches
  • Fix JsonRPC Session handling
  • Rename NamesCache to DeviceDetailsCache
  • Move RoomCache to DeviceDetailsCache
  • Move hm value converter to helpers
  • Use JSON RPC for get_value, get_paramset, get_paramset_description
  • Use default for binary_sensor

Version 0.36.3 (2022-03-09)

What's Changed

  • Add hub property
  • Add check if callback is already registered
  • Use callback when hub is created

Version 0.36.2 (2022-03-06)

What's Changed

  • Fix cover device mapping

Version 0.36.1 (2022-03-06)

What's Changed

  • Small climate fix
  • Make more devices custom_entities

Version 0.36.0 (2022-02-24)

What's Changed

  • Remove HA constants
  • Use enums own constants

Version 0.35.3 (2022-02-23)

What's Changed

  • Move xmlrpc credentials to header

Version 0.35.2 (2022-02-22)

What's Changed

  • Remove password from Exceptions

Version 0.35.1 (2022-02-21)

What's Changed

  • Fix IpBlind
  • Fix parameter visibility

Version 0.35.0 (2022-02-19)

What's Changed

  • Fix usage of async_add_executor_job
  • Improve local_ip identification

Version 0.34.2 (2022-02-16)

What's Changed

  • Add is_locking/is_unlocking to lock

Version 0.34.1 (2022-02-16)

What's Changed

  • Fix siren definition

Version 0.34.0 (2022-02-15)

What's Changed

  • Use backported StrEnum
  • Sort constants to identify HA constants
  • Add new platform siren

Version 0.33.0 (2022-02-14)

What's Changed

  • Make parameter availability more robust
  • Add hvac_action to IP Thermostats
  • Add hvac_action to some HM Thermostats

Version 0.32.4 (2022-02-12)

What's Changed

  • add opening/closing to IPGarage

Version 0.32.3 (2022-02-12)

What's Changed

  • Add state to HmIP-MOD-HO
  • Use enum value for actions

Version 0.32.2 (2022-02-11)

What's Changed

  • Fix HmIP-MOD-HO

Version 0.32.1 (2022-02-11)

What's Changed

  • Update to pydevccu 0.1.3
  • Priotize detection of devices for custom entities (e.g. HmIP-PCBS2)
  • Add HmIPW-FIO6 as CE

Version 0.32.0 (2022-02-10)

What's Changed

  • Move create_devices to central
  • Move parameter visibility relevant data to own module

Version 0.31.2 (2022-02-08)

What's Changed

  • Add HmIP-HDM2 to cover
  • Fix unignore filename

Version 0.31.1 (2022-02-07)

What's Changed

  • Improve naming
  • Add multiplier to entity
  • Substitute device_type of HB devices for usage in custom_entities

Version 0.31.0 (2022-02-06)

What's Changed

  • Add missing return statement
  • Add last_update to every value_cache_entry
  • Rename init_entity_value to load_entity_value
  • move (un)ignore methods to device
  • Add support for unignore file
  • Make PROCESS a binary_sensor
  • Add DIRECTION & ACTIVITY_STATE to cover (is_opening, is_closing)

Version 0.30.1 (2022-02-04)

What's Changed

  • Start hub earlier

Version 0.30.0 (2022-02-03)

What's Changed

  • Add paramset to entity
  • Add CHANNEL_OPERATION_MODE for HmIP(W)-DRBL4
  • Fix DLD lock_state
  • Add is_jammed to locks

Version 0.29.2 (2022-02-02)

What's Changed

  • Add support for blacklisting a custom entity
  • Add HmIP-STH to climate custom entities

Version 0.29.1 (2022-02-02)

What's Changed

  • Check if interface callback is alive
  • Add class for HomeamaticIP Blinds

Version 0.29.0 (2022-02-01)

What's Changed

  • Make device availability dependent on the client
  • Fire event about interface availability

Version 0.28.7 (2022-01-30)

What's Changed

  • Add additional check to reconnect

Version 0.28.6 (2022-01-30)

What's Changed

  • Optimize get_value caching

Version 0.28.5 (2022-01-30)

What's Changed

  • Extend device cache to use get_value

Version 0.28.4 (2022-01-30)

What's Changed

  • Limit read proxy workers to 1

Version 0.28.3 (2022-01-29)

What's Changed

  • Rename RawDevicesCache to DeviceDescriptionCache

Version 0.28.2 (2022-01-29)

What's Changed

  • Make names cache non persistent
  • Bump pydevccu to 0.1.2

Version 0.28.1 (2022-01-28)

What's Changed

  • Update hub.py to match GenericEntity
  • Cleanup central API
  • Use dedicated proxy for mass read operations, to avoid blocking of connection checker

Version 0.28.0 (2022-01-27)

What's Changed

  • Try create client after init failure
  • Reduce CCU calls

Version 0.27.2 (2022-01-25)

What's Changed

  • Optimize data_load

Version 0.27.1 (2022-01-25)

What's Changed

  • Fix naming paramset -> paramset_description pt2
  • Optimize data_load by using get_paramset

Version 0.27.0 (2022-01-25)

What's Changed

  • Fix naming paramset -> paramset_description
  • Add get_value and get_paramset to central
  • Add hmcli.py as command line script

Version 0.26.0 (2022-01-22)

What's Changed

  • Make whitelist for parameter depend on the device_type/sub_type
  • Add additional params for HM-SEC-Win (DIRECTION, ERROR, WORKING, STATUS)
  • Add additional params for HM-SEC-Key (DIRECTION, ERROR)
  • Assign secondary channels for HM dimmers
  • Remove explicit wildcard in entity_definition

Version 0.25.0 (2022-01-19)

What's Changed

  • Remove SpecialEvents
  • Make UNREACH, STICKY_UNREACH, CONFIG_PENDING generic entities
  • init UNREACH ... on init
  • only poll sysvars when central is available

Version 0.24.4 (2022-01-18)

What's Changed

  • Improve logging
  • Generic schema for entities is name(str):channel(int), everything else is custom.

  • Fix sysvar unique_id

  • Slugify sysvar name
  • Kill executor on shutdown
  • Catch ValueError on conversion
  • Add more data to logging

Version 0.24.0-0.24.2 (2022-01-17)

What's Changed

  • Improve exception handling

Version 0.23.3 (2022-01-16)

What's Changed

  • Update fix_rssi according to doc

Version 0.23.1 (2022-01-16)

What's Changed

  • Add more logging to reconnect
  • Add doc link for RSSI fix

Version 0.23.0 (2022-01-16)

What's Changed

  • Make ["DRY", "RAIN"] sensor a binary_sensor
  • Add converter to sensor value
  • HmIP-SCTH230 CONCENTRATION to int
  • Fix RSSI
  • raise connection_checker interval to 60s
  • Add sleep interval(120s) to wait with reconnect after successful connection check

Version 0.22.2 (2022-01-15)

What's Changed

  • Rename hub extra_state_attributes to attributes

Version 0.22.1 (2022-01-15)

What's Changed

  • Add VALVE_STATE for hm climate
  • Add entity_type to attributes
  • Accept LOWBAT only on channel 0

Version 0.22.0 (2022-01-14)

What's Changed

  • Move client management to central
  • Add rooms
  • Move calls to create_devices and start_connection_checker

Version 0.21.2 (2022-01-13)

What's Changed

  • Add ERROR_LOCK form HmIP-DLD
  • Remove ALARM_EVENTS

Version 0.21.1 (2022-01-13)

What's Changed

  • Fix event identification and generation

Version 0.21.0 (2022-01-13)

What's Changed

  • Remove typecast for text, binary_sensor and number
  • Don't exclude Servicemeldungen from sysvars
  • Use Servicemeldungen sysvar for hub state
  • Add test for HM-CC-VG-1 (HM-Heatinggroup)
  • Remove additional typecasts for number

Version 0.20.0 (2022-01-12)

What's Changed

  • Add converter to BaseParameterEntity/GenericEntity
  • Fix number entities returning None when 0

Version 0.19.0 (2022-01-11)

What's Changed

  • Mark secondary channels name with a V → Vch

Version 0.18.1 (2022-01-10)

What's Changed

  • Reduce some log_level
  • Fix callback to notify un_reach

Version 0.18.0 (2022-01-09)

What's Changed

  • Add config option to specify storage directory
  • Move Exceptions to own module
  • Add binary_sensor platform for SVs
  • Add config check
  • Add hub_entities_by_platform
  • Remove option_enable_sensors_for_system_variables

Version 0.17.1 (2022-01-09)

What's Changed

  • Fix naming for multi channel custom entities

Version 0.17.0 (2022-01-09)

What's Changed

  • Refactor entity definition
  • improve naming
  • classify entities (primary, secondary, sensor, Generic, Event)
  • remove option_enable_virtual_channels from central
  • remove entity.create_in_ha. Replaced by HmEntityUsage

Version 0.16.2 (2022-01-08)

What's Changed

  • Fix enum str in entity definition

Version 0.16.1 (2022-01-08)

What's Changed

  • Use helper for device_name
  • Add logging to show usage of unique_id in name
  • Add HmIPW-WRC6 to custom entities
  • Add HmIP-SCTH230 to custom entities
  • Refactor entity definition
  • Remove unnecessary field names from additional entity definitions
  • Add additional entity definitions by device type

Version 0.16.0 (2022-01-08)

What's Changed

  • Return unique_id if name is not in cache
  • Remove no longer needed press_virtual_remote_key

Version 0.15.2 (2022-01-07)

What's Changed

  • Add devices to CustomEntity
  • HmIP-WGC
  • HmIP-WHS
  • Update to pydevccu 0.1.0

Version 0.15.1 (2022-01-07)

What's Changed

  • Identify virtual remote by device type
  • Fix Device Exporter / format output

Version 0.15.0 (2022-01-07)

What's Changed

  • Use actions instead of buttons for virtual remotes

Version 0.14.1 (2022-01-06)

What's Changed

  • Remove SVs from EXCLUDED_FROM_SENSOR

Version 0.14.0 (2022-01-06)

What's Changed

  • Switch some HM-LC-Bl1 to cover
  • Use decorators on central methods
  • Make decorators async aware
  • Don't exclude DutyCycle, needed for old rf-modules
  • Don't exclude Watchdog from SV sensor
  • Ignore mypy error

Version 0.13.3 (2022-01-05)

What's Changed

  • HM cover fix: check level for None
  • Only device_address is required for HA callback
  • Fix: max_temp issue for hm thermostats
  • Fix: hm const are str instead of int

Version 0.13.2 (2022-01-04)

What's Changed

  • Fix cover state
  • Move delete_devices from RPCFunctions to central
  • Move new_devices from RPCFunctions to central
  • Add method to delete a single device to central

Version 0.13.1 (2022-01-04)

What's Changed

  • Use generic climate profiles list

Version 0.13.0 (2022-01-04)

What's Changed

  • Remove dedicated json tls option
  • Fix unique_id for heating_groups
  • Use domain name as base folder name
  • Remove domain const from aiohomematic

Version 0.12.0 (2022-01-03)

What's Changed

  • Split number to integer and float

Version 0.11.2 (2022-01-02)

What's Changed

  • Precise entity definitions

Version 0.11.1 (2022-01-02)

What's Changed

  • Improve detection of multi channel devices

Version 0.11.0 (2022-01-02)

What's Changed

  • Add positional arguments
  • Add missing channel no
  • Set ED_PHY_CHANNEL min_length to 1
  • Add platform zu hub entities
  • Use entities in properties
  • Add transition to dimmer
  • Rename entity.state to entity.value
  • Remove channel no, if channel is the only_primary_channel

Version 0.10.0 (2021-12-31)

What's Changed

  • Make reset_motion, reset_presence a button
  • add check to device_name / Fixes

Version 0.9.1 (2021-12-30)

What's Changed

  • Load and clear caches async
  • Extend naming strategy to use device name if channel name is not customized

Version 0.9.0 (2021-12-30)

What's Changed

  • Add new helper for event_name
  • Add channel to click_event payload

Version 0.8.0 (2021-12-29)

What's Changed

  • Use base class for file cache
  • Rename primary_client to client
  • Add export for device definition

Version 0.7.0 (2021-12-28)

What's Changed

  • Remove deleted entities from device and central collections
  • use datetime for last_events
  • Climate IP: use calendar for duration away

Version 0.6.1 (2021-12-27)

What's Changed

  • Display profiles only when hvac_mode auto is enabled
  • Fix binary sensor state update for hmip 2-state sensors

Version 0.6.0 (2021-12-27)

What's Changed

  • Add climate methods for away mode
  • Fix HVAC_MODE_OFF for climate

Version 0.5.1 (2021-12-26)

What's Changed

  • Fix hm_light turn_off

Version 0.5.0 (2021-12-25)

What's Changed

  • Fix Select Entity
  • Remove internal device temperature (ACTUAL_TEMPERATURE CH0)
  • Support Cool Mode for IPThermostats
  • Display if AWAY_MODE is set on thermostat
  • Separate device_address and channel_address

Version 0.4.0 (2021-12-24)

What's Changed

  • Use datetime for last_updated (time_initialized)
  • Fix example
  • Add ACTUAL_TEMPERATURE as separate entity by @towo
  • Add HEATING_COOLING to IPThermostat and Group
  • Add ()HUMIDITY and ()TEMPERATURE as separate entities for Bidcos thermostats
  • use ACTIVE_PROFILE in climate presets

Version 0.3.1 (2021-12-23)

What's Changed

  • Make HmIP-BSM a switch (only dimable devices should be lights)

Version 0.3.0 (2021-12-23)

What's Changed

  • Cleanup API, device/entity
  • Add ACTIVE_PROFILE to IPThermostat

Version 0.2.0 (2021-12-22)

What's Changed

  • Cleanup API, reduce visibility
  • Add setValue to client

Version 0.1.2 (2021-12-21)

What's Changed

  • Rotate device identifier

Version 0.1.1 (2021-12-21)

What's Changed

  • Remove unnecessary async
  • Removed unused helper
  • Add interface_id to identifiers in device_info

Version 0.1.0 (2021-12-20)

What's Changed

  • Bump # Version to 0.1.0
  • Remove interface_id from get_entity_name and get_custom_entity_name
  • Add initial test
  • Add coverage config

Version 0.0.22 (2021-12-16)

What's Changed

  • Resolve names without interface
  • Fix device.entities for virtual remotes
  • Remove unused const
  • Cache model and primary_client

Version 0.0.21 (2021-12-15)

What's Changed

  • Fix number set_state
  • Update ignore list
  • Fix select entity

Version 0.0.20 (2021-12-14)

What's Changed

  • Move caches to classes

Version 0.0.19 (2021-12-12)

What's Changed

  • Add helper for address
  • Fixes for Hub init

Version 0.0.18 (2021-12-11)

What's Changed

  • Add type hints based on HA coding guidelines
  • Rename device_description to entity_definition
  • Send alarm event on value change
  • Rename impulse to special events
  • reduce event_callbacks

Version 0.0.17 (2021-12-05)

What's Changed

  • Remove variables that are covered by other sensors (CCU only)
  • Remove dummy from service message (HmIP-RF always sends 0001D3C98DD4B6:3 unreach)
  • Rename Bidcos thermostats to SimpleRfThermostat and RfThermostat
  • Use more Enums (like HA does): HmPlatform, HmEventType
  • Use assignment expressions
  • Add more type hints (fix most mypy errors)

Version 0.0.16 (2021-12-02)

What's Changed

  • Don't use default entities for climate groups (already included in device)

Version 0.0.15 (2021-12-01)

What's Changed

  • Fix: remove wildcard for HmIP-STHD
  • Add unit to hub entities

Version 0.0.14 (2021-11-30)

What's Changed

  • Add KeyMatic
  • Add HmIP-MOD-OC8
  • Add HmIP-PCBS, HmIP-PCBS2, HmIP-PCBS-BAT, HmIP-USBSM
  • Remove xmlrpc calls related to ccu system variables (not supported by api)
  • Update hub sensor excludes

Version 0.0.13 (2021-11-29)

What's Changed

  • Add HmIP-MOD-HO, HmIP-MOD-TM
  • Add sub_type to device/entity
  • Add PRESET_NONE to climate
  • Add level und state as additional entities for climate

Version 0.0.12 (2021-11-27)

What's Changed

  • Add more type converter
  • Move get_tls_context to helper
  • Update requirements
  • Cleanup constants
  • Use flags from parameter_data
  • Add wildcard start to exclude parameters that start with word
  • Fix channel assignment for dimmers
  • Fix entity name: add channel only if a parameter name exists is in multiple channels of the device.

Version 0.0.11 (2021-11-26)

What's Changed

  • Fix: cover open/close default values to float
  • Fix: add missing async/await
  • make get_primary_client public

Version 0.0.10 (2021-11-26)

What's Changed

  • Fix TLS handling

Version 0.0.9 (2021-11-25)

What's Changed

  • Don't start connection checker for pydevccu
  • Use a dummy hub for pydevccu
  • Convert min, max, default values (fix for cover)

Version 0.0.8 (2021-11-25)

What's Changed

  • Add button platform. This allows to use the virtual remotes of a ccu in automations.
  • Cleanup entity inheritance.

Version 0.0.7 (2021-11-23)

What's Changed

  • Switch to a non-permanent session for jsonrpc calls The json capabilities of a ccu are limited (3 parallel session!?!). So we no longer us a persisted session. (like pyhomematic)
  • Enable write-only params as HMAction(solves a problem with climate writing CONTROL_MODE)

Version 0.0.6 (2021-11-22)

What's Changed

  • Rename server to central_unit (after the extraction of the XMLRPC-Server server has not been a server anymore).
  • Rename json_rpc to json_rpc_client
  • Move json_rpc from client to central_unit to remove number of active sessions
  • Add hub with option to enable own system variables as sensors

Version 0.0.5 (2021-11-20)

What's Changed

  • Add method for virtual remote
  • Update entity availability based on connection status
  • Fix action_event for ha device trigger

Version 0.0.4 (2021-11-18)

What's Changed

  • Use one XMLRPC-Server for all backends

Version 0.0.3 (2021-11-16)

What's Changed

  • Reduce back to parameters with events
  • Rewrite climate-entity creation
  • Refactor to Async
  • Remove entity_id and replace by unique_id
  • Reorg Client/Server/Caches
  • Use One Server per backend (CCU/Homegear) with multiple clients/interfaces
  • Define device_description for custom_entities
  • Create custom_entities for climate, cover, light, lock and switch
  • Maintain ignored parameters
  • Add collection with wildcard parameters to ignore
  • Enable click, impulse and alarm events
  • Add connection checker

Version 0.0.2 (2021-04-20)

What's Changed

  • Use input_select for ENUM actors (Issue #8)
  • Added DEVICE_IN_BOOTLOADER and INSTALL_TEST to ignored parameters
  • Create switch for type ACTION for parameters with only write-flag
  • Create number for type FLOAT for parameters with only write-flag
  • Add exceptions to abort startup under certain conditions
  • Refactoring, introduce Device class
  • Allow to fetch single paramset on demand
  • Renew JSON-RPC sessions instead of logging in and out all the time

Version 0.0.1 (2021-04-08)

What's Changed

  • Initial testing release