Commit Graph

44 Commits (fe010289b4687b4b45dd51ffe43b045a85dca3c1)

Author SHA1 Message Date
Renat Sibgatulin 4adf1992e1
Bump aioairq to 0.4.3 (#130963) 2024-11-19 20:13:33 +01:00
Renat Sibgatulin be5d6425dc
Add options flow to the airq integration (#109337)
* Add support for options to airq integration

Expose to the user the following configuration:
1. A choice between fetching from the device either:
    a. the averaged (previous and the new default behaviour) or
    b. noisy momentary sensor reading
2. A toggle to clip (spuriously) negative sensor values (default
    functionality, previously unexposed)

To those ends:
- Introduce an `OptionsFlowHandler` alongside with a listener
  `AirQCoordinator.async_set_options`
- Introduce constants to handle represent options
- Add tests and strings

* Drop OptionsFlowHandler in favour of SchemaOptionsFlowHandler

Modify `AirQCoordinator.__init__` to accommodate the change in option
handling, and drop `async_set_options` which slipped through the
previous commit.

* Ruff formatting
2024-05-15 09:13:26 +02:00
Marc Mueller 1c65aacde5
Use runtime_data for airq (#116620) 2024-05-02 20:58:37 +02:00
Marc Mueller ff3a801936
Add empty line after module docstring [a-d] (#112697) 2024-03-08 14:51:32 +01:00
Joost Lekkerkerker 900112b1e8
Remove entity description mixin in AirQ (#112377) 2024-03-05 18:30:42 +01:00
Erik Montnemery 6fe28d3764
Migrate integrations a-d to generic flowhandler (#111861) 2024-02-29 20:07:14 +01:00
Joost Lekkerkerker 5a1d447730
Add icon translations to AirQ (#108402) 2024-01-19 20:06:06 +01:00
Marc Mueller c5c132e1d4
Enable strict typing for airq (#106813) 2024-01-01 20:33:38 +01:00
Renat Sibgatulin 1031e416be
Remove IP / mDNS validation in airq integration setup (#106326)
Original design relied on aioairq.AirQ.__init__ checking if the input
was a valid IP address or an mDNS of a very specific structure,
and raising an InvalidInput otherwise.
Now, aioairq==0.3.2 removes said check completely following a user's
request to allow arbitrary host name and DNS entries.
In the config flow, "cannot_connect" covers the cases of misspelled
inputs now, which previously were covered by a dedicated "invalid_input"
2023-12-27 09:56:13 +01:00
Erik Montnemery 0c2485bc03
Freeze integration entity descriptions (#105984)
Co-authored-by: J. Nick Koston <nick@koston.org>
2023-12-18 16:28:13 -10:00
Renat Sibgatulin 68722ce662
Bump aioairq to 0.3.1 (#104659) 2023-11-29 08:43:48 +01:00
Erik Montnemery 045c327928
Move DeviceInfo from entity to device registry (#98149)
* Move DeviceInfo from entity to device registry

* Update integrations
2023-08-10 22:04:26 -04:00
Joost Lekkerkerker 04dc85b754
Use device class for AirQ entities (#95037) 2023-06-22 11:56:44 +02:00
Joost Lekkerkerker 18d0fe994d
Add entity translations for AirQ (#94280) 2023-06-20 22:19:17 +02:00
Renat Sibgatulin 8dbcbd156a
Add new sensors to airq (#90413)
Support for the sensors introduced in air-Q firmware v1.82.0
2023-03-29 11:33:27 +02:00
Renat Sibgatulin e27d3c9523
Improve airq handling of DeviceInfo (#90232)
* Reduce data sharing between ConfigFlow and DataUpdateCoordinator

Instead of fetching device information from the device once in
`ConfigFlow` and then piping it through in `ConfigEntry.data`,
only use as much as needed in `ConfigFlow.async_step_user`, then fetch
again in `AirQCoordinator._async_update_data` if a key is missing.

Additionally, factor `AirQCoordinator` out into a sumbodule.

Add a simple test for `AirQCoordinator.device_info` update.

Positive side effect: `AirQCoordinator.device_info` is
updated explicitly, instead of dumping the entire content of (a fully
compatible) `TypedDict`, retrieved from `aioairq`.

* Remove tests ill-suited to this PR

`test_config_flow.test_duplicate_error` slipped through by mistake,
while `test_coordinator.test_fetch_device_info_on_first_update` may need
a more thoroughly suite of accompanying tests

* Ignore airq/coordinator.py

...newly separated from airq/__init__.py, that's already in this list

* Reorder files alphabetically
2023-03-28 08:18:47 +02:00
Renat Sibgatulin 452e1d341d
Remove invalid device class in air-Q integration (#89329)
Remove device_class from sensors using inconsistent units
2023-03-08 10:00:40 +01:00
Erik Montnemery 601ac3d9a9
Drop unnecessary copy from entitydescription.name to _attr_name (#88251) 2023-02-16 13:54:32 +01:00
Erik Montnemery 231aad7a68
Sort manifests 1 (#87022) 2023-02-08 20:29:44 +01:00
Franck Nijhof 939eef3b28
Remove translations from Core (#87543)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2023-02-06 15:06:43 +01:00
GitHub Action 3f992ed31d [ci skip] Translation update 2023-02-04 00:23:44 +00:00
GitHub Action e1483ff746 [ci skip] Translation update 2023-01-21 00:24:12 +00:00
GitHub Action d1ecc418bb [ci skip] Translation update 2023-01-19 00:25:04 +00:00
GitHub Action b81453cb6b [ci skip] Translation update 2023-01-16 00:24:22 +00:00
GitHub Action 77f9548e51 [ci skip] Translation update 2023-01-15 00:25:52 +00:00
Franck Nijhof b0cee0bc46
String formatting and max line length - Part 1 (#84390)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2022-12-22 10:12:50 +01:00
GitHub Action f25017313a [ci skip] Translation update 2022-12-09 00:24:29 +00:00
epenet 5d71afef85
Use SoundPressure unit and device class in airq (#83581) 2022-12-08 20:56:18 +01:00
GitHub Action 03154e1d83 [ci skip] Translation update 2022-12-03 00:21:50 +00:00
GitHub Action 797dc51bc5 [ci skip] Translation update 2022-11-26 00:22:30 +00:00
GitHub Action f3b3193f7a [ci skip] Translation update 2022-11-25 00:24:19 +00:00
GitHub Action eaf6d43508 [ci skip] Translation update 2022-11-23 00:26:26 +00:00
GitHub Action 0be2a3f182 [ci skip] Translation update 2022-11-22 00:26:32 +00:00
GitHub Action 3bea04e387 [ci skip] Translation update 2022-11-21 00:26:41 +00:00
GitHub Action fe5246fb6f [ci skip] Translation update 2022-11-19 00:26:11 +00:00
GitHub Action 5119005a8d [ci skip] Translation update 2022-11-18 00:29:16 +00:00
GitHub Action 83a6012f80 [ci skip] Translation update 2022-11-15 00:26:42 +00:00
GitHub Action dcf68d768e [ci skip] Translation update 2022-11-09 00:27:20 +00:00
GitHub Action 785cf0e29c [ci skip] Translation update 2022-11-08 00:26:39 +00:00
GitHub Action e2788f8321 [ci skip] Translation update 2022-11-07 00:26:17 +00:00
GitHub Action fc472eb040 [ci skip] Translation update 2022-11-06 00:27:15 +00:00
GitHub Action 0311063c44 [ci skip] Translation update 2022-11-05 00:28:23 +00:00
GitHub Action c7fc51cfa5 [ci skip] Translation update 2022-11-04 00:29:52 +00:00
Renat Sibgatulin dd5baa6e48
Add air-Q integration (air quality sensors) (#76999)
* Added initial files for air-Q integration

* Allow FIXME comments in pylint (temporary)

Also reintroduce --ignore-missing-annotations=y

* Set up air-q entry to connect to aioairq's API (initial attempt)

Also add necessary constants

* Implement a class for sensors and its update logic

Very early stage, WIP

* Zeroconf and authentication are working

* Complete the bare-bone minimal working version

Specifically, make AirQSensor update its values.

* Handle invalid authentication gracefully

* Handle ClientConnectionError gracefully

* Add field hint for the login form

The key in the schema, which defines the form in
`ConfigFlow.async_show_form` is looked up in both `airq/strings/json`
and `airq/translations/en.json`. I am still not 100% sure how this
lookup is performed. WIP

* Minor cleanups

* Extend sensor list to all supported by SensorDeviceClass

Also manage warming up sensors

* aioairq is published to PyPI and mentioned in requirements

* Reordered constants and list content alphabetically

As required by style guides. Also turned SENSOR_TYPES to a list

* Updated file docstrings for a dev unfamiliar w/homeassistant like myself

* Adding a bit of logging for the integration setup process

* Expose scan interval & smoothing flag

Also streamline test_authentication in config_flow.

* Fix a type annotation mistake

* Use as many constants from homeassistant.const as possible

My only concern is using CONST_IP_ADDRESS = "ip_address" for smth which
stands for both IP address and mDNS...

* Temporarily rollback ConfigFlow.async_step_configure and use defaults

TODO: implement OptionFlowHandler instead

* Define custom Coordinator, w subset of airq config

The latter is then accessed from entity / sensor constructors to define
correct DeviceInfo

* Provide translations to de & fr + minor changes to en

* Provide translations to ru + a minor en changes

* Make translation a little more helpful and polite

* Fix devicename and entry title

* Remove stale commented out code

* Test config_flow

At this point two helper functions which interact with the external
library are not tested

* Clean up unrelated and meant as temporary changes

* Clean up unnecessary comments meant for internal use

* Move fetching config to a dedicated async coordinator method

As opposed to it being a potentially poorly justified step in
async_setup_entry

* Remove zeroconf support since it is not yet ready

* Remove translations other than en

* Remove unnecessary comments, manifest.json entries, and constants

* Improve exception handling

- `_LOGGER` uses `debug` and not `error` levels.
- Drop `ClientConnect` and catch `aiohttop.ClientConnectError` directly
- Drop `Exception` as it is not expected from `aioairq` (remove the
  corresponding test too)

* Drop strings for obsolete errors and steps

Specifically, `unknown` error isn't caught any more. `configure` step
has also been removed.

* Refactor en.json to be consistent with strings.json

* Move target_route from a coordinator argument to a constant

At this point a user cannot configure the target_route route, thus it
does not make sense to expose it half-heartedly in
`AirQCoordinator.__init__`, since it cannot be accessed.

* Fix an async call in `AirQCoordinator.async_setup_entry`

* Refactor underlying aioairq API

- Use `homeassistant.helpers.aiohttp.async_get_clientsession` and pass a
  single persistent session to `aioariq.AirQ.__init__`
- `aioairq.AirQ.fetch_device_info` now returns a `DeviceInfo` object heavily
  inspired and almost compatible with `homeassistant.helpers.entity.DeviceInfo`.
  Make heavier use of this object and define a single `DeviceInfo` in the
  `AirQCoordinator` (instead of recreating the same object for each sensor
  of the device in `sensor.AirQSensor`)
- Drop two helper functions in `config_flow.py` and operate on `aioariq.AirQ`
  methods directly

* Fix the version of aioairq

* Add 15 more sensors + icons

* Remove cnt* & TypPS, change units of health & performance

* Add 12 more sensors

* Add a missing icon

* Gracefully handle device not being available on setup

If the device and the host are not on the same WiFi,
ServerTimeoutError is raised, which is caught by
ClientConnectionError.
If the device is powered off, ClientConnectionError is expected.
In both cases, ConfigEntryNotReady is raised, as prescribed by the docs.
Newer version of aioairq times-out far quicker than the default 5 mins.

* Rename two sensors

* Validate provided IP address / mDNS

aioairq now raises InvalidInput if provided IP / mDNS does not seem
valid. Handle this exception correctly

* Apply suggestions from code review

Clean up the comments and rename the logger

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Artem Draft <Drafteed@users.noreply.github.com>

* Only fetch device info during the first refresh

- Fetched info is stored in AirQCoordinator.device_info.
- In `AirQSensor.native_value` only multiply by the factor if
  the sensor reading is not None
- Fix the tests for ConfigFlow for aioairq==0.2.3. Specifically
  make the dummy data pass the new validation step upstream
  + add a test which fails it

* Drop custom device classes for now

* Apply suggestions from code review

Co-authored-by: Artem Draft <Drafteed@users.noreply.github.com>

* Only fetch device info during ConfigFlow.async_step_user

Store the result obtained by `airq.fetch_device_info` it in
`config_entry.data`. Pass the entire config entry to `AirQCoordinator`
and build the entire `homeassistant.helpers.entity.DeviceInfo` in the
`AirQCoordinator.__init__`. This makes
`AirQCoordinator._async_fetch_device_info` and overloaded
`AirQCoordinator._async_config_entry_first_refresh` obsolete.

Bump aioairq version.

Turn update_interval from `AirQCoordinator.__init__` argument into a
contestant.

* Custom entity description exposing a hook to modify sensor value

Use a `AirQEntityDescription` with a callable `value_fn` which allows to
change the sensor value retrieved from the device. Note that the
callable does not handle data retrieval itself (even from
`coordinator.data`). Instead it is purely a hook to transform obtained
value.

* Avoid duplicated use of unique_id

Device info is fetched  during the `ConfigFlow.async_user_step`.
`unique_id` is taken from the device info and is **not** stored
in `config_entry.data`. Subsequently `config_entry.unique_id` is
used instead.

* Drop unnecessary try-except

Co-authored-by: Artem Draft <Drafteed@users.noreply.github.com>

* Clarify the use of value_transform_fn

* Refactor the use of lambdas in AirQEntityDescription

Now it is the job of the callable under `value` to get the sensor
reading from the coordinator's data. Factoring this functionality into a
callback decouples  the key of the description from the key of dict,
returned by the API, so `AirQEntityDescription` no longer requires its key
to be set to smth clearly internal (e.g. `nh3_MR100`).

* Use a callback to update native_value

Since all `native_value`s are updated synchronously, it can as well be
done in a callback for better state consistency (right?)

* Revert the description keys to match data keys

Must match given the current way of identifying available sensors. On a
broader scale, they must match to be able to relate the descriptions to
sensors, unless a separate lookup table is maintained.

* Reduce number of loops when adding sensors

Filtering warming up sensors and non-sensor keys can be combined with
adding entities.

* Remove obsolete imports

* Update integrations.json

* Add integration_type

Integration supports multiple devices => hub

Co-authored-by: dl2080 <daniel.lehmann@runbox.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Artem Draft <Drafteed@users.noreply.github.com>
Co-authored-by: Daniel Lehmann <43613560+dl2080@users.noreply.github.com>
Co-authored-by: Martin Selbmann <job@martin-selbmann.de>
2022-11-03 23:13:57 +01:00