# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [unreleased]

## [9.9.0] - 2026-08-18

### Added

- Report which webhook URLs are registered, so a registration that was dropped
  or overwritten can be detected. A banned webhook is still listed, so this
  proves a webhook is registered - not that anything reaches it
- Record when the last webhook payload arrived, including payloads the library
  cannot classify
- `Home.has_status` tells you up front whether a home can be polled, so the ones
  Netatmo refuses need never be called

### Changed

- A home Netatmo permanently refuses now fails in its own distinct way, so it
  can be dropped rather than retried forever. Existing error handling still
  catches it
- Errors now carry the status and error code Netatmo sent back, so one kind of
  failure can be told apart from another
- Error logs and messages now name the home they came from
- Webhooks are managed through Netatmo's new endpoints

### Fixed

- Error messages for HTTP 409 and 429 name the status instead of leaving a
  blank where it should be
- Webhook URLs are redacted in logs. They are secrets, and debug logs end up in
  bug reports
- Devices belonging to no known home are named in the log
- Stop searching every home for a device that already said which home it is in

## [9.8.0] - 2026-08-13

### Added

- Process Netatmo webhook payloads - merge state,
  surface events, and signal refresh needs

## [9.7.0] - 2026-08-11

### Added

- Parse VELUX ACTIVE indoor climate sensors (`NXS`), departure switches (`NXD`),
  and room climate data.
- Resolve a schedule name to a schedule of the home's active temperature control mode
- Track a schedule switch made outside the library, e.g. reported by a webhook

### Changed

- `Module.reachable` is now a read-only property that resolves `#`-suffixed
  sub-modules from their parent module. Use `Module.mark_unreachable()` instead
  of assigning to it.
- A module listed in `/homestatus` without a `reachable` key now reads as
  reachable rather than unknown. Weather stations, thermostat relays, cameras,
  smoke and CO detectors, VELUX gateways and the Legrand ecometer never report
  the key, so they previously resolved `None`. The Legrand ecometer in particular
  was forced unreachable outright and now reports as connected.

### Fixed

- Report the actually selected schedule after a schedule switch
- Reachability of `#`-suffixed sub-modules now resolves from the parent module,
  so Legrand NLIS double switches are no longer reported unreachable
  ([home-assistant/core#178403](https://github.com/home-assistant/core/issues/178403))
- An absent `reachable` key in a `/homestatus` payload now preserves the
  previous value instead of meaning "unreachable"
- A bridge that does not report `reachable` no longer overwrites its bridged
  children, and the rooms those children are in, with its own payload. Rooms
  missing from `/homestatus` kept the bridge's readings permanently — an outdoor
  room would report the indoor weather station's CO2 and humidity
- `errors[]` naming a bridge whose bridged children sit in rooms absent from
  `/homesdata` no longer raises `KeyError` out of `async_update_status`
- A cycle in a bridge's `modules_bridged` no longer raises `RecursionError` from
  `Module.mark_unreachable()`
- A bridged module that is declared in `/homesdata` but never listed in
  `/homestatus` no longer stays unreachable for good after a single outage of its
  bridge. Nothing ever describes such a module, so the mark it inherited could not
  be lifted by any later payload

## [9.6.0] - 2026-07-28

### Added

- Filter homes via an optional `disabled_homes_ids` denylist on `AsyncAccount`.
  Full inventory stays available as `all_home_names`.

### Deprecated

- `AsyncAccount.all_homes_id` — use `all_home_names` instead

## [9.5.0] - 2026-07-21

### Added

- Retry on Netatmo 429 concurrency errors with exponential backoff, honoring the
  `Retry-After` header (#547)
- Parse additional module attributes (`last_seen`, `setup_date`,
  `offload_meters`, per-module `error_code`)
- Parse OpenTherm boiler diagnostics on OTH modules (`boiler_control`,
  `boiler_error`, `dhw_control`, `boiler_status`)
- Parse room `type` and `therm_relay` from `/homesdata`
- Parse the `/homesdata` user block (`country`, `pending_user_consent`, unit
  preferences)
- Parse `electricity` / `electricity_production` and `event` schedule payloads
- Surface home geolocation (`altitude`, `coordinates`, `country`, `timezone`) on
  `Home`

### Changed

- Replace the room setpoint-mode/pilot-wire "invert" dicts with clearer named
  helpers

### Fixed

- Exclude `doortag_category` from the `NACamDoorTag` feature set (#500)
- Populate `AsyncAccount.user` email from `/homesdata`, kept out of `raw_data`
- Read bridged-children ids from both `module_bridged` and `modules_bridged`
  spellings (#603)
- Registering a module discovered via `/homestatus` no longer wipes home fields
  or known modules
- Alias legacy `/homesdata` module types (`NBD`, `NADoorTag`) to their canonical
  classes
- Handle the `auto` temperature control mode; unknown modes degrade to `None`
  instead of raising (#176631)

## [9.4.0]

### Added

- Support for WebRTC live stream for Netatmo Indoor Camera Advance (NPC)

### Changed

- bump dependencies and tooling

## [9.4.0]

### Added

- Support for WebRTC live stream for Netatmo Indoor Camera Advance (NPC)

### Changed

- bump dependencies and tooling

## [9.3.0]

### Added

- Support for VELUX ACTIVE gateways (`NXG`) and covers (`NXO`)
- New category concept for NACamDoorTag modules
- Support for siren control for NOC (Smart Outdoor Camera)

### Fixed

- Correct typo in device_types for cooking

## [9.2.3]

### Fixed

- Update github action

## [9.2.2]

### Changed

- Improved type hints and annotations using pyrefly
- Added ruff check to tox configuration
- Deprecated Python 3.11 support
- Replace black by ruff format
- Use astral uv actions in github actions
- Update dev dependencies and tooling
- Test uv build for test.pypi

### Fixed

- Fixed mypy typing errors
- Add missing 'electricity_production' schedule type to ScheduleType

### Removed

- Removed unused development packages (pytest-mock)

## [9.2.1]

### Added

- Added SPDX license identifier [PEP 639](https://peps.python.org/pep-0639/).

### Fixed

- Removed upper bound for Python version constraint.

## [9.2.0]

### Changed

- Improved schedule handling
- Updated dev container configuration

## [9.1.0]

### Added

- Support for 3rd party zigbee roller blinds
- Support for Netatmo Indoor Camera Advance (NPC)
- Fixtures for multiple modules (NLL, NLV, NLLV, NLJ, NLIS, NLPT, NLPD, NLPO)
- Added conventional-pre-commit hook for commit-msg stage

### Changed

- Updated device type descriptions to better reflect their functionality
- Removed some unnecessary mixins from Legrand device classes
- Create RemoteControlMixin for easier device representation
- Replaced setup-cfg-fmt with pyprojectsort pre-commit hook
- Improved error handling in extract_raw_data for empty homes
- Refactored test file handling to use anyio.open_file()
- Updated pre-commit hooks to latest versions
- Updated project metadata in pyproject.toml

### Fixed

- Handling of cooling/heating control mode
- Fixed async tests to avoid blocking file access
- Fixed detection of missing homes in API responses
- Fixed async mock configuration in tests
- Fixed error handling for throttling errors
- Fixed exception class names to end with "Error" suffix
- Fixed handling of empty homes data
- Fixed test file handling to use anyio
- Fixed coverage report configuration in tox.ini
- Fixed type casting in async_update_measures method for Energy module
- Fixed error handling for missing parameters in fake_post_request
- Fixed handling of unknown device types
- Fixed handling of place data and historical data in NetatmoBase class
- Fixed handling of station ids in fix_id function
- Fixed handling of zone_id type in async_set_schedule_temperatures method
- Fixed handling of angle for display in module.py
- Fixed handling of device type and boiler status in Room class
- Fixed handling of missing parameters in test functions
- Fixed handling of file paths for fixtures
- Fixed handling of deprecated assert_called method
- Fixed handling of test cases for NLP, NLF, and NLIS Legrand modules
- Fixed handling of test cases for different weather modules
- Fixed handling of mypy configuration in tox.ini

## [9.0.0]

### Added

- Support for Pilot Wire ("fil pilote" support)
- AC Auto schedule

### Changed

- Replaced pipenv with uv and updated readme

### Removed

- Python 3.10 support

### Fixed

- Propper handling of climate schedules in heating or cooling
- Fix HVAC related setpoint evaluation
- devcontainer

## [8.1.0]

### Added

- Expose camera person status
- Add NLE support
- Add proper energy support
- Add cooler support
- Add BNS support

## [8.0.3]

### Added

- Add NLLF centralized ventilation controller

### Fixed

- Add BNSC switch capability

## [8.0.2]

### Fixed

- Duplicates in entity names (https://github.com/home-assistant/core/issues/88792)
- Add shutter capabilities to BNAB, BNAS and BNMS (https://github.com/home-assistant/core/issues/106392)

## [8.0.1]

### Added

- NLFE Legrand dimmer switch evolution

## [8.0.0]

### Added

- Bticino IP scopes
- Bticino dimmable light (BNLD)
- Start and end times to room class

### Changed

- Add power data to NLPD entities

### Removed

- deprecated code

## [7.6.0]

### Added

- Opening category for NACamDoorTag
- Schedule modification
- Bticino MyHome Server 1 scopes
- NLPD - Drivia dry contact
- BTicino module stubs (functionality will come later)
- support for Legrand garage door opener (NLJ)
- support for BTicino intelligent light (BNIL)

### Removed

- Support for Python 3.8 and 3.9

### Fixed

- Update functionality for NLP, NLC, NLT and NLG

## [7.5.0]

### Added

- Add NLAS - wireless batteryless scene switch device type
- Add BNEU, EBU, NLDD, NLAO, NLLF, NLUO, NLUP, Z3L, NLTS, NLUF

### Fixed

- Update Legrand and BTicino devices
- Fix broken temperature setter when OTM is in the setup

## [7.4.0]

### Added

- Add NLUF device stub
- Add TPSRS Somfy shutters

### Changed

- Update test fixture data to be in line with HA tests

### Fixed

- Handle unknown device types and log
- Fix misc device types and add stubs for unknown

## [7.3.0]

### Added

- Add Legrand NLUI device class

### Changed

- Minor code clean ups

### Fixed

- Handle invalid ip addressed from the API more gracefully
- Let weather station devices register home even if home does not exist
- Catch ContentTypeError error and handle more graceful
- Fix key error when battery hits very_low
- Response handling issues

## [7.2.0]

### Added

- Add NLPO Legrand contactor
- Add NLD Legrand Double On/Off dimmer remote
- Add NLFE Legrand On-Off dimmer switch
- Add BTicino device support for BNCX, BNDL, BNSL

## [7.1.1]

### Fixed

- Fix Netatmo radiator valves (NRV) set termpature

## [7.1.0] - 2022-10-03

### Added

- Adds Legrand NLIS double switches
- Adds Legrand NLPT relay/teleruptor

### Fixed

- Use dimmer type for Legrand NLF dimmers

## [7.0.1] - 2022-06-05

### Deprecated

- The following modules are deprecated and will be removed in pyatmo 8.0.0
  - camera
  - home_coach
  - public_data
  - thermostat
  - weather_station

## [7.0.0] - 2022-06-05

### Added

- Adds support for Netatmo modulating thermostat
- Adds support for Netatmo doorbell
- Adds support for shutters, lights, energy meters and switches
- Adds support for 3rd party devices from different Legrand brands such as BTicinio, Bubendorff, Smarther, CX3
- Fetch favorite weather sensors
- Add support for third-party Netatmo devices (see `base_url` and `user_prefix` parameters)

### Changed

- Replace freezegun with time-machine

### Deprecated

- The following modules are deprecated and will be removed in pyatmo 8.0.0
  - camera
  - home_coach
  - public_data
  - thermostat
  - weather_station

### Removed

-

### Fixed

- Use async fixture decorators

### Security

-

## [6.2.4] - 2022-01-31

### Fixed

- Crash when home does not contain valid devices

## [6.2.2] - 2021-12-29

### Fixed

- Use ID if schedule name is missing

## [6.2.1] - 2021-12-18

### Fixed

- Catch when no body is contained in the response

## [6.2.0] - 2021-11-19

### Added

- Add support for python3.20
- Introduce climate module #156

### Changed

- Use assignment expressions

## [6.1.0] - 2021-10-03

### Added

- Provide a VS Code devcontainer

### Changed

- Provide separate method for image retrival
- Minor f-string conversions

## [6.0.0] - 2021-09-10

### Changed

- Ensure camera name is not None
- Split persons by home
- BREAKING: Require home_id for person related methods
- version is now managed by setuptools scm

## [5.2.3] - 2021-07-22

### Fixed

- Ignore if API omits unimportant attributes in response

## [5.2.2] - 2021-07-21

### Fixed

- Ignore if API omits unimportant attributes in response

## [5.2.1] - 2021-07-10

### Added

- Distribute type information

### Changed

- Update type annotations

## [5.2.0] - 2021-06-30

### Changed

- [BREAKING] Fix parameter order of set person home/away methods
- Refactor camera person detection checks

## [5.1.0] - 2021-06-14

### Fixed

- Handle error when camera is not reachable more graceful
- Update selfcheck to use the new update methods
- Fix false positive errors when no climate devices are registered

### Security

- Upgrade aiohttp to 3.7.4 or later to fix vulnerability

## [4.2.3] - 2021-05-17

### Fixed

- Extraction of climate schedules was looking for the wrong attribute (Backported from [5.0.1])

## [5.0.1] - 2021-05-09

### Fixed

- Extraction of climate schedules was looking for the wrong attribute

## [5.0.0] - 2021-04-26

### Added

- Async support

### Changed

- [BREAKING] Data retrival extracted into separate update method

## [4.2.2] - 2021-01-20

### Fixed

- Fix error when camera does not return a local url

## [4.2.1] - 2020-12-03

### Changed

- Improve CI & deployment

## [4.2.0] - 2020-11-02

### Changed

- Improve CI & deployment

### Fixed

- Set station name if not contained in the backend data

### Removed

- Remove min and max from weather station

## [4.1.0] - 2020-10-07

### Fixed

- Fix crash when station name is not contained in the backend data

[9.9.0]: https://github.com/jabesq-org/pyatmo/compare/v9.8.0...v9.9.0
[9.8.0]: https://github.com/jabesq-org/pyatmo/compare/v9.7.0...v9.8.0
[9.7.0]: https://github.com/jabesq-org/pyatmo/compare/v9.6.0...v9.7.0
[9.6.0]: https://github.com/jabesq-org/pyatmo/compare/v9.5.0...v9.6.0
[9.5.0]: https://github.com/jabesq-org/pyatmo/compare/v9.4.0...v9.5.0
[9.4.0]: https://github.com/jabesq-org/pyatmo/compare/v9.3.0...v9.4.0
[9.3.0]: https://github.com/jabesq-org/pyatmo/compare/v9.2.3...v9.3.0
[9.2.3]: https://github.com/jabesq-org/pyatmo/compare/v9.2.2...v9.2.3
[9.2.2]: https://github.com/jabesq-org/pyatmo/compare/v9.2.1...v9.2.2
[9.2.1]: https://github.com/jabesq-org/pyatmo/compare/v9.2.0...v9.2.1
[9.2.0]: https://github.com/jabesq-org/pyatmo/compare/v9.1.0...v9.2.0
[9.1.0]: https://github.com/jabesq-org/pyatmo/compare/v9.0.0...v9.1.0
[9.0.0]: https://github.com/jabesq-org/pyatmo/compare/v8.1.0...v9.0.0
[8.1.0]: https://github.com/jabesq-org/pyatmo/compare/v8.0.3...v8.1.0
[8.0.3]: https://github.com/jabesq-org/pyatmo/compare/v8.0.2...v8.0.3
[8.0.2]: https://github.com/jabesq-org/pyatmo/compare/v8.0.1...v8.0.2
[8.0.1]: https://github.com/jabesq-org/pyatmo/compare/v8.0.0...v8.0.1
[8.0.0]: https://github.com/jabesq-org/pyatmo/compare/v7.6.0...v8.0.0
[7.6.0]: https://github.com/jabesq-org/pyatmo/compare/v7.5.0...v7.6.0
[7.5.0]: https://github.com/jabesq-org/pyatmo/compare/v7.4.0...v7.5.0
[7.4.0]: https://github.com/jabesq-org/pyatmo/compare/v7.3.0...v7.4.0
[7.3.0]: https://github.com/jabesq-org/pyatmo/compare/v7.2.0...v7.3.0
[7.2.0]: https://github.com/jabesq-org/pyatmo/compare/v7.1.1...v7.2.0
[7.1.1]: https://github.com/jabesq-org/pyatmo/compare/v7.1.0...v7.1.1
[7.1.0]: https://github.com/jabesq-org/pyatmo/compare/v7.0.1...v7.1.0
[7.0.1]: https://github.com/jabesq-org/pyatmo/compare/v7.0.0...v7.0.1
[7.0.0]: https://github.com/jabesq-org/pyatmo/compare/v6.2.4...v7.0.0
[6.2.4]: https://github.com/jabesq-org/pyatmo/compare/v6.2.2...v6.2.4
[6.2.2]: https://github.com/jabesq-org/pyatmo/compare/v6.2.1...v6.2.2
[6.2.1]: https://github.com/jabesq-org/pyatmo/compare/v6.2.0...v6.2.1
[6.2.0]: https://github.com/jabesq-org/pyatmo/compare/v6.1.0...v6.2.0
[6.1.0]: https://github.com/jabesq-org/pyatmo/compare/v6.0.0...v6.1.0
[6.0.0]: https://github.com/jabesq-org/pyatmo/compare/v5.2.3...v6.0.0
[5.2.3]: https://github.com/jabesq-org/pyatmo/compare/v5.2.2...v5.2.3
[5.2.2]: https://github.com/jabesq-org/pyatmo/compare/v5.2.1...v5.2.2
[5.2.1]: https://github.com/jabesq-org/pyatmo/compare/v5.2.0...v5.2.1
[5.2.0]: https://github.com/jabesq-org/pyatmo/compare/v5.1.0...v5.2.0
[5.1.0]: https://github.com/jabesq-org/pyatmo/compare/v5.0.1...v5.1.0
[5.0.1]: https://github.com/jabesq-org/pyatmo/compare/v5.0.0...v5.0.1
[5.0.0]: https://github.com/jabesq-org/pyatmo/compare/v4.2.2...v5.0.0
[4.2.3]: https://github.com/jabesq-org/pyatmo/compare/v4.2.2...v4.2.3
[4.2.2]: https://github.com/jabesq-org/pyatmo/compare/v4.2.1...v4.2.2
[4.2.1]: https://github.com/jabesq-org/pyatmo/compare/v4.2.0...v4.2.1
[4.2.0]: https://github.com/jabesq-org/pyatmo/compare/v4.1.0...v4.2.0
[4.1.0]: https://github.com/jabesq-org/pyatmo/compare/v4.0.0...v4.1.0
[4.0.0]: https://github.com/jabesq-org/pyatmo/compare/v3.3.1...v4.0.0
[3.3.1]: https://github.com/jabesq-org/pyatmo/releases/tag/v3.3.1
