Compare commits

..

923 Commits

Author SHA1 Message Date
Ludovic BOUÉ 72ababf5c2 Modifies the async_set_temperature method to execute logic synchronously in the event loop, to avoid thread safety violations with legacy synchronous implementations. 2025-11-22 21:04:02 +00:00
Ludovic BOUÉ e100d8c53e Improve target temperature management by executing the adjustment method in an executor to avoid blocking the event loop. 2025-11-22 20:40:10 +00:00
Ludovic BOUÉ a678bed3b2 Execute the temperature definition directly in the event loop to ensure thread safety. 2025-11-22 18:18:50 +00:00
Ludovic BOUÉ ff8a4463ab Add unit_of_measurement for temperature fields 2025-11-22 18:50:15 +01:00
Ludovic BOUÉ 4d1aa15ddf Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 18:48:59 +01:00
Ludovic BOUÉ d91e7f060c Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 18:48:37 +01:00
Ludovic BOUÉ 20c99ecf04 Added support for the target temperature range in the temperature control service 2025-11-22 17:03:36 +00:00
Ludovic BOUÉ 6a711ee423 Reorder the name and description fields 2025-11-22 16:57:48 +00:00
Ludovic BOUÉ fc9e131297 Fix JSON formatting in strings.json 2025-11-22 17:43:32 +01:00
Ludovic BOUÉ abafd20a3a Merge branch 'dev' into gj-20250705-02 2025-11-22 17:41:15 +01:00
Jan Bouwhuis 1106f4f0e2 Fix typo in mqtt text subentry translations and improve advanced settings translations (#157052) 2025-11-22 15:40:36 +01:00
Andre Lengwenus f73e92a34a Mark entity unavailable if data can't be fetched (#156928) 2025-11-22 15:36:47 +01:00
hanwg 74ad5066e2 Fix Telegram bot bug where messages are sent to wrong recipient (#156978) 2025-11-22 15:25:35 +01:00
David Rapan 4202a665af Refactor Shelly climate to reuse RPC key split (#157002) 2025-11-22 15:20:31 +01:00
David Rapan c9ddbe39ce Refactor Shelly button to reuse RPC key split (#156990) 2025-11-22 15:20:02 +01:00
Ville Skyttä 8a2e8d2c61 Add internal util.snakecase, use instead of stringcase (#156775)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 15:19:15 +01:00
epenet ca2e8bfb56 Add support for tuya doorbell events (#156540)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-22 15:17:37 +01:00
epenet c0772f3957 Log warning for incorrect Tuya enum values (#156541) 2025-11-22 15:04:01 +01:00
epenet 0b96da3b24 Add more fixtures for Tuya tests (#156855) 2025-11-22 15:03:19 +01:00
Franck Nijhof 4c07b2b290 Remove template engine dependency in EmonCMS (#157045) 2025-11-22 14:48:44 +01:00
Paulus Schoutsen f699d95ea0 Do not require admin for instance URLs (#157012) 2025-11-22 13:09:38 +01:00
Artur Pragacz f6b9a0eb29 Ensure backwards compatibility for new-style configs in old triggers and conditions (#156446) 2025-11-22 12:37:48 +01:00
epenet 71c665ed49 Fix fallback to local system unit in Tuya climate (#156999) 2025-11-22 10:24:03 +01:00
Thomas D 85a1afb174 Add lock reduced guard button to Volvo integration (#157004) 2025-11-22 10:05:01 +01:00
Manu 9668a68c28 Bump python-xbox to v0.1.2 (#157030) 2025-11-22 00:09:42 +01:00
J. Nick Koston a06aa8edfe Bump inkbird-ble to 1.1.1 (#157016) 2025-11-21 15:08:03 -08:00
Kurt Chrisford 4e30a5d930 Add support for actron air que air conditioners (#156675) 2025-11-21 23:59:02 +01:00
Manu 696550a7f2 Add diagnostics platform to Xbox integration (#156662) 2025-11-21 23:56:07 +01:00
Raphael Hehl c064d23a99 Bump uiprotect to version 7.26.0 (#157022) 2025-11-21 23:54:50 +01:00
Lukas ac7b063c2c Add binary_sensor platform to pooldose integration (#156894) 2025-11-21 23:50:30 +01:00
J. Nick Koston e0778c8e2e Add security options to disable AP and BLE RPC after Shelly WiFi provisioning (#156970) 2025-11-21 14:27:26 -08:00
David Rapan 2ba5a96d5b Refactor Shelly binary sensor name removal (#157023)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-21 23:41:19 +02:00
Manu 13c9fb6e37 Remove Domino's Pizza integration (#156879) 2025-11-21 19:47:04 +01:00
Robert Resch 102bb1f694 Remove deprecated archs (#156414) 2025-11-21 19:17:41 +01:00
Franck Nijhof e5b2d44e8e Extract area template functions into an areas Jinja2 extension (#156629) 2025-11-21 17:56:16 +01:00
epenet 4d4ad900b1 Add Tuya climate tests for US unit_system (#156989) 2025-11-21 17:20:03 +01:00
Joost Lekkerkerker acc136af19 Add entities for Smartthings flexwash (#156997) 2025-11-21 16:58:50 +01:00
Abílio Costa 0f12a40eb2 Fix typing in websocket_api test (#156964) 2025-11-21 16:29:19 +01:00
Joost Lekkerkerker bf124daf72 Add SmartThings dustfilter threshold (#153909) 2025-11-21 16:28:35 +01:00
Josef Zweck 1682ced5cc Bump pylamarzocco to 2.2.0 (#156667) 2025-11-21 16:26:38 +01:00
averybiteydinosaur 80b316bc70 Bump version of python_awair to 0.2.5 (#155798)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-21 16:25:18 +01:00
karwosts 00d2340d4b Fix usage_prediction incorrectly accessing target fields (#156937) 2025-11-21 15:56:58 +01:00
Timothy 514a329580 Rework CloudhookURL setup for mobile app (#156940) 2025-11-21 15:23:23 +01:00
Petro31 f2b8bb01bf Modernize template cover (#156475) 2025-11-21 15:20:30 +01:00
Manu 30153ab059 Fix spelling mistake in IronOS integration (#156996) 2025-11-21 15:19:33 +01:00
Bram Kragten 2957b15ede Update frontend to 20251105.1 (#156992) 2025-11-21 15:18:23 +01:00
Glenn Vandeuren (aka Iondependent) 12ace95f3e Improve error handling in Niko Home Control config flow (#154565)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-21 14:34:59 +01:00
Joost Lekkerkerker babe19767d Add diagnostic support to WAQI (#156811) 2025-11-21 14:20:47 +01:00
Robert Resch d01843e1ab Use unix socket for HA managed go2rtc instance (#156968) 2025-11-21 14:19:03 +01:00
Joost Lekkerkerker 9964cb512a Throttle Decora wifi updates (#156994) 2025-11-21 14:16:03 +01:00
Joost Lekkerkerker ae38214b7c Bump pySmartThings to 3.3.4 (#156830) 2025-11-21 14:10:38 +01:00
Kamil Breguła 9812286801 Add fixtures for Samsung oven and dishwasher (#156655)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-21 13:53:10 +01:00
J. Nick Koston 32a40e5919 Bump PySwichBot to 0.74.0 (#156986) 2025-11-21 13:22:55 +01:00
Kamil Breguła 97de944a14 Add Washer Water Temperature to SmartThings (#156980)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-21 13:19:08 +01:00
Artur Pragacz c9bd87f4b3 Classify identify button as diagnostic in Matter (#156943) 2025-11-21 13:17:26 +01:00
Neal ac46568996 Add tests to concord232 component (#156070)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-21 13:13:08 +01:00
J. Nick Koston 7c1b8ee02c Bump aioshelly to 13.20.0 (#156988) 2025-11-21 06:11:03 -06:00
dependabot[bot] aa6901265d Bump actions/checkout from 5.0.1 to 6.0.0 (#156973)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-21 12:56:33 +01:00
epenet b76e9ad1c0 Migrate Tuya light (color_data) to use wrapper class (#156816) 2025-11-21 13:05:12 +02:00
epenet edb8007c65 Migrate Tuya climate (temperature) to use wrapper class (#156977) 2025-11-21 13:03:58 +02:00
epenet 956a29411f Migrate Tuya fan (oscillate) to use wrapper class (#156946) 2025-11-21 11:56:24 +01:00
Brett Adams 1a2361050b Add update platform to Tesla Fleet (#156908) 2025-11-21 11:54:20 +01:00
Jan Bouwhuis 0c9e92f6f9 Add MQTT text subentry support (#156686) 2025-11-21 11:46:19 +01:00
epenet bfdff46859 Migrate Tuya fan (speed) to use wrapper class (#156976) 2025-11-21 11:45:42 +01:00
epenet 9a22808499 Migrate Tuya fan (direction) to use wrapper class (#156944) 2025-11-21 11:44:16 +01:00
epenet 88b373af41 Migrate Tuya climate (swing) to use wrapper class (#156938) 2025-11-21 11:41:01 +01:00
epenet dea2f37e8f Migrate Tuya cover (state) to use wrapper class (#156941) 2025-11-21 11:38:05 +01:00
David Rapan 30cce68e0b Update Shelly's quality scale to platinum 🏆️ (#156982) 2025-11-21 12:36:58 +02:00
Shay Levy 985eff972a Mark Shelly entity translations as done (#155683) 2025-11-21 12:10:46 +02:00
David Rapan 31ca332158 Increase Shelly code coverage for Gen1 EM3 (#156752)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-21 11:02:53 +01:00
David Rapan bf76c1601d Align Shelly event naming paradigm (#156774)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-21 09:15:26 +01:00
J. Nick Koston e572f8d48f Fix Shelly Bluetooth discovery for Gen3/Gen4 devices without advertised names (#156883) 2025-11-20 15:11:17 -06:00
Franck Nijhof 482b5d49a3 Introduce Home Assistant Labs (#156840) 2025-11-20 21:22:37 +01:00
Robert Resch 126fd217e7 Bump go2rtc to 1.9.12 and go2rtc-client to 0.3.0 (#156948) 2025-11-20 19:41:40 +01:00
Manu 0327b0e1ec Fix next alarm sensor showing wrong time in Sleep as Android (#156939) 2025-11-20 18:56:58 +01:00
epenet 3d5a7b4813 Migrate Tuya vacuum (pause) to use wrapper class (#156947) 2025-11-20 18:55:03 +01:00
epenet e0bb30f63b Migrate Tuya fan (switch) to use wrapper class (#156936) 2025-11-20 15:04:36 +01:00
epenet e5ae58c5df Migrate Tuya cover (open/close/stop) to use wrapper class (#156726) 2025-11-20 15:24:58 +02:00
epenet 13e4bb4b93 Migrate Tuya climate (hvac_mode/presets) to use wrapper class (#156933) 2025-11-20 14:23:28 +01:00
epenet d5fd27d2a2 Add tests for Tuya climate actions (#156935) 2025-11-20 15:23:04 +02:00
bestycame 0a034b9984 Add Hanna integration (#147085)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Olivier d'Otreppe <odotreppe@abbove.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-20 14:20:14 +01:00
epenet 6a8106c0eb Add tests for Tuya fan actions (#156919) 2025-11-20 14:25:05 +02:00
epenet 2cacfc7413 Migrate Tuya fan (preset) to use wrapper class (#156922) 2025-11-20 13:19:37 +01:00
epenet 388ab5c16c Migrate Tuya climate (fan_mode) to use wrapper class (#156721) 2025-11-20 13:02:33 +01:00
epenet 81ea6f8c25 Migrate Tuya vacuum (status) to use wrapper class (#156744) 2025-11-20 14:01:18 +02:00
Joost Lekkerkerker 4f885994b7 Remove deprecation for SmartThings binary sensor (#156924) 2025-11-20 11:53:50 +01:00
Hessel 25e2c9ee80 Cache token info in Wallbox (#154147)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-20 11:12:11 +01:00
epenet 12c04f5571 Use pytest.parametrize in Tuya siren/switch/valve tests (#156920) 2025-11-20 10:46:57 +01:00
epenet 3ad1c6a47a Use pytest.parametrize in Tuya cover tests (#156921) 2025-11-20 11:38:14 +02:00
Åke Strandberg e7e13ecc74 Refactor miele program id codes part 3(3) (#144196)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-20 09:59:28 +01:00
J. Nick Koston 991b8d2040 Bump aioshelly to 13.19.0 (#156902) 2025-11-19 17:52:55 -06:00
J. Nick Koston 43fadbf6b4 Bump aioshelly to 13.18.0 (#156887) 2025-11-19 19:00:10 +02:00
Maciej Bieniek ca79d37135 Use native_value property instead of _attr_native_value in the Brother integration (#156878) 2025-11-19 16:06:11 +01:00
Paul Bottein df8ef15535 Add reorder floors and areas websocket command (#156802)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-19 09:58:07 -05:00
Maciej Bieniek 249c1530d0 Address comments for Brother tests (#156877) 2025-11-19 15:06:27 +01:00
Maciej Bieniek 081b769abc Use Brother printer model as model_id (#156876) 2025-11-19 14:44:22 +01:00
Josef Zweck b8b101d747 Lamarzocco fix websocket reconnect issue (#156786)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-11-19 13:06:29 +01:00
Sebastian Schneider a19be192e0 Bump aiounifi to 88 (#156867) 2025-11-19 13:04:20 +01:00
Josef Zweck 92da82a200 Bump onedrive-personal-sdk to 0.0.17 (#156865) 2025-11-19 13:03:37 +01:00
Paul Bottein 820ba1dfba Add system-level frontend data storage (#155945) 2025-11-19 06:59:34 -05:00
Ludovic BOUÉ 63c8962f09 Add Matter mock lock fixture (#156862) 2025-11-19 12:50:58 +01:00
dependabot[bot] c1a6996549 Bump github/codeql-action from 4.31.3 to 4.31.4 (#156850)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 12:46:32 +01:00
epenet 05253841af Auto-generate fixture list in Tuya tests (#156858) 2025-11-19 12:38:11 +01:00
Heindrich Paul f2ef0503a0 Adding new sensors to the cat litter box (#156054)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-19 12:32:54 +01:00
puddly 938da38fc3 Bump universal-silabs-flasher to 0.1.2 (#156849) 2025-11-19 10:46:56 +01:00
Niracler 9311a87bf5 Refactor Sunricher DALI integration to use direct device callbacks (#155315) 2025-11-19 09:47:45 +01:00
Louis b45294ded3 unifi: Add wired client link speed sensor and related tests (#155086)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Robert Svensson <Kane610@users.noreply.github.com>
2025-11-19 09:26:26 +01:00
Andre Lengwenus 82d3190016 Bump pypck to 0.9.5 (#156847) 2025-11-19 06:52:29 +01:00
omrishiv d8cbcc1977 Bump pylutron-caseta to 0.26.0 (#156825)
Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com>
2025-11-18 23:01:34 +01:00
Raj Laud 4b69543515 Add support for Victron bluetooth low energy devices (#148043)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-18 21:12:48 +01:00
Thomas55555 97ef4a35b9 Bump aioautomower to 2.7.1 (#156826) 2025-11-18 20:32:47 +01:00
Dan Raper f782c78650 Bump ohmepy and remove advanced_settings_coordinator (#156764) 2025-11-18 19:52:17 +01:00
Abílio Costa 139ed34c74 Properly mock integrations' file_path (#156813) 2025-11-18 18:42:35 +01:00
Andre Lengwenus 7f14d013ac Strict typing for lcn integration (#156800) 2025-11-18 18:26:24 +01:00
Artur Pragacz 963e27dda4 Send snapshot analytics for device database in dev (#155717) 2025-11-18 16:15:27 +00:00
Yuxin Wang b8e3d57fea Deprecate useless sensors in APCUPSD integration (#151525) 2025-11-18 17:09:38 +01:00
Heindrich Paul 0de2a16d0f Add binary sensor support and refactor NS sensor integration (#154589)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-18 16:29:09 +01:00
David Rapan c8c2413a09 Fix Shelly sleeping sensor with channel name (#156708)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-18 16:28:21 +01:00
Fredrik Mårtensson 291331f878 Fix is_matching in samsungtv config flow (#156594)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-18 16:12:21 +01:00
David a13cdbdf3d Add new Tuya dehumidifier test fixture (#156799)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-18 16:07:37 +01:00
epenet 1bf713f279 Set kw_only in Tuya TypeInformation (#156804)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-18 15:58:46 +01:00
Heindrich Paul 10c8ee417b Refactor Nederlandse Spoorwegen integration (#154616)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Erwin Douna <e.douna@gmail.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-18 15:53:49 +01:00
Jamin b23134f4f1 Reset state on error during VOIP announcement (#156384) 2025-11-18 15:36:41 +01:00
Joost Lekkerkerker f45a6f806b Add Cosori virtual integration (#156792) 2025-11-18 13:38:32 +01:00
Ludovic BOUÉ d3857a00d5 Rename Matter thermostat fixture (#156795) 2025-11-18 13:25:08 +01:00
Copilot 8c9b90a9f9 Fix hvv_departures to pass config_entry explicitly to DataUpdateCoordinator (#156794)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: joostlek <7083755+joostlek@users.noreply.github.com>
2025-11-18 12:32:55 +01:00
Timothy 4eedc88935 Store Mobile app pending updates when enabling back an entity (#156026)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-18 12:26:13 +01:00
Abílio Costa 343ea1b82d Return target in trigger description command (#156766)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-11-18 12:16:28 +01:00
Lukas 36e13653d2 New virtual integration Vagner Pool supported by pooldose (#156678)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-18 11:46:46 +01:00
dependabot[bot] 80444b2165 Bump actions/checkout from 5.0.0 to 5.0.1 (#156780)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 11:43:52 +01:00
epenet 262f06dd2b Migrate Tuya light (color_temp) to use wrapper class (#156743)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-18 11:43:32 +01:00
epenet bd87119c2e Fix blocking call in cync (#156782) 2025-11-18 11:41:54 +01:00
Andre Lengwenus 0dfa037aa8 Refactor device classes for LCN (#156791) 2025-11-18 11:39:23 +01:00
Artur Pragacz c32a471573 Register music assistant services in async setup (#155963) 2025-11-18 11:38:58 +01:00
valexi7 97b7e51171 Add fixture for Tuya Wifi Knob Thermostat wk_t94pit6zjbask9qo (#156781)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-18 08:34:21 +01:00
David Rapan 433712b407 Add Shelly binary sensor translation (#154116)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-17 22:39:14 +02:00
Luca Angemi 5d87e0f429 Make Google sheets datetime column optional (#155861)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-11-17 19:48:17 +00:00
tronikos acb087f1e5 Mark Google Assistant SDK as gold (#148077) 2025-11-17 17:37:41 +01:00
Andre Lengwenus 10c12623bf Switch LCN integration to local polling (#152601) 2025-11-17 15:50:26 +01:00
stegm 2fe20553b3 Add new settings option to kostal plenticore (#153162) 2025-11-17 15:45:50 +01:00
Tom Matheussen b431bb197a Sync quality scale tracking with codebase (#156440) 2025-11-17 15:41:30 +01:00
Manu eb9d625926 Fix return type annotations and enable strict typing in Xbox integration (#156746) 2025-11-17 14:38:02 +01:00
PaulCavill 3a69534b09 Bump pyiCloud to 2.2.0 (#156485) 2025-11-17 14:32:01 +01:00
Erik Montnemery 8f2cedcb73 Run hassfest if conditions.yaml or triggers.yaml is changed (#156738) 2025-11-17 12:26:50 +01:00
epenet 3658953ff3 Migrate Tuya light (brightness) to use wrapper class (#156735) 2025-11-17 11:58:16 +01:00
dotlambda 0be5893e37 sonos requires defusedxml (#156718) 2025-11-17 08:21:55 +01:00
Allen Porter c87e38c4cf Add Nest config flow data_description fields to fix quality scale item (#156713) 2025-11-17 08:13:15 +01:00
Allen Porter 4874610ad6 Bump google-nest-sdm to 9.0.1 (#156707) 2025-11-16 23:13:40 +01:00
Michael 9180282fc6 Add update entity to AdGUard Home (#156682)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-16 22:52:38 +01:00
J. Nick Koston 118f30f32e Bump dbus to 3.0.0 (#156704) 2025-11-16 22:34:31 +01:00
Bouwe Westerdijk bd10da126f Revisit diagnostic-category assignments for Plugwise (#156279) 2025-11-16 21:29:24 +01:00
starkillerOG b73a7928ca Enable Reolink RTSP and ONVIF port when supported (#156700) 2025-11-16 21:24:25 +01:00
Jan Bouwhuis 3e20c2ea93 Fix missing description placeholders in MQTT subentry flow (#156684) 2025-11-16 21:21:22 +01:00
andreipoenaru 60130d3d68 Add support for encoded URLs to RESTful Command (#154957)
Co-authored-by: Jan-Philipp Benecke <jan-philipp@bnck.me>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-16 21:04:18 +01:00
Denis Shulyaka c45ede2e5d Bump anthropic to 0.73.0 (#156692) 2025-11-16 21:02:55 +01:00
J. Nick Koston e167061f53 Bump dbus-fast to 2.46.4 (#156703) 2025-11-16 20:52:05 +01:00
Kamil Breguła 5560fb6c9e Refactor tests in GIOS (#155756)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-16 20:21:46 +01:00
J. Nick Koston 9808b6c961 Bump dbus-fast to 2.46.1 (#156695) 2025-11-16 19:34:29 +01:00
J. Nick Koston e8cfde579e Bump dbus-fast to 2.46.0 (#156693) 2025-11-16 09:46:53 -06:00
J. Nick Koston f695fb4d51 Bump dbus-fast to 2.45.1 (#156691) 2025-11-16 09:12:44 -06:00
Jan Bouwhuis a0e0549d90 Fix missing temperature_delta device class translations (#156685) 2025-11-16 15:00:51 +01:00
epenet ba034c6c8c Add alarm_state to Tuya siren alarm (#151221) 2025-11-16 12:26:33 +01:00
Åke Strandberg 008bb85c59 Mock arguments in senz tests (#156677) 2025-11-16 12:25:28 +01:00
Michael cf1c1294d3 Bump adguardhome to 0.8.1 (#156679) 2025-11-16 12:16:17 +01:00
Åke Strandberg 11d5d314cc Fix type hints in miele tests (#156657) 2025-11-16 12:12:45 +01:00
Joost Lekkerkerker 6f0de3071a Add fixture for dual washing machine to SmartThings (#156646) 2025-11-16 11:43:25 +01:00
mettolen 87d2597292 Add diagnostics to Saunum integration (#156623) 2025-11-16 11:40:49 +01:00
Manu 437bc04fe8 Remove Live-TV support from Xbox integration (#156669) 2025-11-16 11:30:04 +01:00
Åke Strandberg 67a0d6a187 Mock arguments to ClientResponseError() in miele tests (#156676) 2025-11-16 10:03:32 +01:00
Lukas abb52bca81 Add more sensors to Pooldose (#156002)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-15 23:02:27 +01:00
J. Nick Koston d2d6889278 Bump thermopro-ble to 1.1.2 (#156652) 2025-11-15 14:10:59 -06:00
David Rapan bdca592219 Add Shelly event translation (#156162)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-15 20:52:13 +02:00
Michael 5c0c7b9ec3 Bump adguardhome to 0.8.0 (#156651) 2025-11-15 16:26:05 +01:00
TheDK 9717599fb9 Use SensorDeviceClass.PRESSURE in Withings (#156648)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-15 16:08:34 +01:00
MarkGodwin 4d7de2f814 Bump tplink-omada-api to 1.5.3 (#156645) 2025-11-15 15:39:56 +01:00
epenet 779590ce1c Migrate Tuya climate (humidity) to use wrapper class (#156575) 2025-11-15 15:05:52 +01:00
epenet f3a185ff9c Migrate Tuya cover to use wrapper class (#156558)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-15 15:04:54 +01:00
epenet 5a5a106984 Migrate Tuya humidifier to use wrapper class (#156572)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-15 15:03:30 +01:00
epenet 796b421d99 Migrate Tuya vacuum to use wrapper class (#156569) 2025-11-15 15:02:49 +01:00
epenet 0c03e8dbe9 Migrate Tuya light (color_mode) to use wrapper class (#156582) 2025-11-15 15:02:40 +01:00
epenet 47cf4e3ffe Ensure Tuya scale and step are integers (#156555) 2025-11-15 14:30:44 +02:00
epenet 0ea0fc151d Use parametrize in tuya climate tests (#156577) 2025-11-15 14:28:57 +02:00
Åke Strandberg b7e5afec9f Fix typing in miele tests (#156637) 2025-11-15 12:19:34 +01:00
cdnninja 7a2bb67e82 Refactor vesync test (#156625) 2025-11-15 09:24:48 +01:00
Manu e0612bec07 Bump pythonkuma to v0.3.2 (#156626) 2025-11-15 03:43:16 +01:00
Denis Shulyaka a06f4b6776 Anthropic model selection from list (#156261) 2025-11-14 21:16:52 -05:00
Denis Shulyaka 275670a526 Add support for gpt-5.1 (#156612) 2025-11-14 18:39:05 -05:00
Robert Resch d0d62526dd Bump async-upnp-client to 0.46.0 (#156622) 2025-11-14 18:30:18 -05:00
Franck Nijhof aefdf412b0 Extract device template functions into a devices Jinja2 extension (#156619) 2025-11-15 00:23:38 +01:00
Manu 56ab6b2512 Prevent sensor updates caused by fluctuating “last seen” timestamps in Xbox integration (#156419) 2025-11-14 22:07:13 +01:00
mettolen d1dea85cf5 Add Saunum integration (#155099)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-14 19:55:55 +01:00
wollew 84b0d39763 clean up velux test fixtures (#156554) 2025-11-14 19:53:17 +01:00
tronikos 3aff225bc3 Add Google Weather integration (#147015)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-14 19:46:56 +01:00
Ludovic BOUÉ 04458e01be Fix spelling of 'Auto-relock time' in Matter integration strings (#156607) 2025-11-14 19:10:57 +01:00
Thomas55555 ae51cfb8c0 Fix model_id in Husqvarna Automower (#156608) 2025-11-14 19:10:16 +01:00
Simone Chemelli c116a9c037 Add debounce to Alexa Devices coordinator (#156609) 2025-11-14 19:09:19 +01:00
Allen Porter fb58758684 Add completed timestamp support in Google tasks (#156564) 2025-11-14 12:07:23 -05:00
Franck Nijhof 25fbcbc68c Extract floor template functions into a floors Jinja2 extension (#156589)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 12:06:55 -05:00
Denis Shulyaka a670286b45 Bump openai to 2.8.0 (#156602) 2025-11-14 12:06:21 -05:00
ElectricSteve 52ba55b17f Bump youtubeaio to 2.1.0 (#156595) 2025-11-14 16:01:00 +01:00
epenet ff0fc98c36 Fix sfr_box entry reload (#156593) 2025-11-14 15:03:43 +01:00
David Rapan 9f78a2263d Move Shelly sensor get_entity_translation_attributes to utils (#156590)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-14 15:44:48 +02:00
Kamil Breguła 9b4696a80b Add quality_scale to mvglive manifest (#155474) 2025-11-14 13:20:10 +01:00
wollew 70fe8cae39 Fix velux scenes (naming and unique ids) (#156436) 2025-11-14 13:18:08 +01:00
wollew 95eb45ab08 cleanup registered callbacks before removing velux config entry (#156525) 2025-11-14 13:06:45 +01:00
Erwin Douna 84f8e57141 Add retry_after to UpdateFailed in update coordinator (#153550)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 12:19:02 +01:00
Franck Nijhof f484b6df0d Extract label template functions into a label Jinja2 extension (#156439)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 11:04:31 +01:00
J. Diego Rodríguez Royo 34c1d45ee0 Ensure that Home Connect program update value event is a string when updating options (#156416)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-14 10:51:52 +01:00
epenet 09a105d9ad Migrate Tuya light (switch) to use wrapper class (#156580) 2025-11-14 10:33:58 +01:00
epenet 6bd1787d0a Improve parametrize in tuya light tests (#156581) 2025-11-14 10:19:48 +01:00
David Rapan 37040f5064 Add Shelly switch translation (#156146)
Signed-off-by: David Rapan <david@rapan.cz>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-14 11:16:04 +02:00
puddly 531397ec07 Avoid firing discovery events when flows immediately create a config entry (#155753) 2025-11-14 09:40:46 +01:00
epenet d6cc0f81de Remove pointless super.async_added_to_hass in Tuya climate (#156573) 2025-11-14 09:31:03 +01:00
TheJulianJES f8ef8a466a Bump ZHA to 0.0.79 (#156571) 2025-11-14 09:30:38 +01:00
Åke Strandberg 713015e26a Improve logging of failing miele action commands (#156275) 2025-11-14 09:10:24 +01:00
Åke Strandberg f9c1e81c5e Improve error handling and add tests to senz climate (#156544) 2025-11-14 09:06:56 +01:00
Joost Lekkerkerker 0549d113e6 Bump python-open-router to 0.3.3 (#156563) 2025-11-14 08:48:47 +01:00
dependabot[bot] 0d842978ec Bump github/codeql-action from 4.31.2 to 4.31.3 (#156565) 2025-11-13 23:05:52 -08:00
Nojus 55476ef6ea Remove arbitrary forecast limit for meteo_lt (#155877) 2025-11-14 00:14:48 +01:00
starkillerOG 0e130d8fdd Bump reolink-aio to 0.16.5 (#156553) 2025-11-14 00:12:03 +01:00
slickm0nty 20bcb84956 Set suggested display precision in modbus integration (#155467) 2025-11-13 22:47:40 +00:00
jlanchares bbb1d57081 Goodwe port502ftp support with PORT stored on config data. (#148628)
Co-authored-by: starkillerOG <starkiller.og@gmail.com>
2025-11-13 21:12:47 +01:00
hanwg 121406569b Upgrade Telegram bot quality scale to Silver (#155352) 2025-11-13 21:08:35 +01:00
Joost Lekkerkerker 4866c775ce Fix CI (#156549) 2025-11-13 21:08:08 +01:00
Willem-Jan van Rootselaar 7c5ab12270 Update bsblan to python-bsblan version 3.1.1 (#156536)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-13 20:44:12 +01:00
Erik Montnemery 099edfac20 Fix flux_led tests opening sockets (#156458) 2025-11-13 20:39:56 +01:00
epenet aa31df0fd5 Migrate Tuya camera to use wrapper class (#156542) 2025-11-13 20:38:44 +01:00
Bram Kragten 13fbeb6cdb Add support for trigger and condition category icons (#156533) 2025-11-13 14:36:34 -05:00
karwosts 8d557447df Add completed timestamp to TodoItem (#156547)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-11-13 14:35:33 -05:00
Joakim Sørensen e6e3f2455f Add discovery_service_actions configuration option (#156537) 2025-11-13 14:35:22 -05:00
epenet c9c518ee84 Improve IntegerTypeData scaling in Tuya (#156507) 2025-11-13 20:29:07 +01:00
Magnus 214731e964 Component asuswrt: Type check is redundant for this value (#154535) 2025-11-13 20:24:24 +01:00
Jan Čermák c4b09c9a0a Update Home Assistant base image to 2025.11.0 (#156517) 2025-11-13 20:01:22 +01:00
epenet f5b5b2fb70 Remove unused/absent property from Tuya (#156508) 2025-11-13 19:32:08 +01:00
Manu bb3cdd382b Add media_content_id to media player in Xbox integration (#156519) 2025-11-13 19:25:43 +01:00
starkillerOG 8d09b5c273 Relax Reolink update interval and timeout for big installs (#156509) 2025-11-13 19:25:03 +01:00
epenet d92fa7fa72 Move more logic from entity to wrapper in Tuya alarm (#156450) 2025-11-13 18:37:47 +01:00
Åke Strandberg 0c45b7f615 Add reconfiguration flow to senz (#156539) 2025-11-13 16:49:16 +01:00
Alexandre CUER bfa1116115 Add quality scale to Emoncms (#149727)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-13 16:10:29 +01:00
Arie Catsman 4984237987 Add alternative ct meter source to enphase_envoy diagnostics (#154468) 2025-11-13 15:37:36 +01:00
Joost Lekkerkerker 3839573151 Bump pySmartThings to 3.3.3 (#156528) 2025-11-13 15:31:03 +01:00
Åke Strandberg e02dc53df3 Add reauthentication flow and tests to senz (#156534) 2025-11-13 15:28:45 +01:00
Arie Catsman bedae1e12c Optimize Enphase_Envoy CT sensor entity code (#153859) 2025-11-13 14:59:24 +01:00
epenet b4eb73be98 Improve tests for Tuya alarm control panel (#156481) 2025-11-13 14:44:38 +01:00
wollew 0ac3f776fa set shorthand atrributes for supported_features in velux cover (#156524) 2025-11-13 14:18:20 +01:00
Petar Petrov 8e8a4fff11 Extract grid, gas, and water source validation into separate functions (#156515) 2025-11-13 13:28:25 +01:00
Åke Strandberg 579ffcc64d Add unique_id to senz config_entry (#156472) 2025-11-13 12:26:33 +01:00
Foscam-wangzhengyu 81943fb31d URL-encode the RTSP URL in the Foscam integration (#156488)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-13 12:23:28 +01:00
Petro31 70dd0bf12e Modernize template alarm control panel (#156476) 2025-11-13 12:21:03 +01:00
Tom Matheussen c2d462c1e7 Refactor Satel Integra platforms to use shared base entity (#156499) 2025-11-13 12:20:32 +01:00
epenet 49e050cc60 Redact more DP codes in tuya diagnostics (#156497) 2025-11-13 12:18:43 +01:00
Josef Zweck f6d829a2f3 Bump pylamarzocco to 2.1.3 (#156501) 2025-11-13 11:54:15 +01:00
Aarni Koskela e44e3b6f25 Rename RuuviTag BLE to Ruuvi BLE (#156504) 2025-11-13 11:36:50 +01:00
Christopher Fenner af603661c0 Fix spelling in ViCare integration (#156500) 2025-11-13 10:54:55 +01:00
puddly 35c6113777 Add firmware flashing debug loggers to hardware integrations (#156480)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-13 09:25:00 +01:00
TheJulianJES 3c2f729ddc Fix Z-Wave generating name before setting entity description (#156494) 2025-11-13 08:18:22 +01:00
Erik Montnemery 0d63cb765f Fix lg_netcast tests opening sockets (#156459)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 07:44:56 +01:00
TheJulianJES 3cb414511b Migrate Z-Wave event entity to new discovery schema (#156320) 2025-11-13 07:22:37 +01:00
karwosts f55c36d42d Update ical to 11.1.0 (#156487) 2025-11-12 20:24:04 -08:00
Erik Montnemery 26bb301cc0 Fix lifx tests opening sockets (#156460) 2025-11-12 21:51:54 +02:00
Erik Montnemery 4159e483ee Fix wiz tests opening sockets (#156468) 2025-11-12 20:11:15 +01:00
Erik Montnemery 7eb6f7cc07 Fix romy tests opening sockets (#156466) 2025-11-12 20:10:46 +01:00
epenet a7d01b0b03 Use json_loads_object in tuya models (#156455) 2025-11-12 20:08:28 +01:00
epenet 1e5cfddf83 Use json_loads_object in Tuya light (#156452) 2025-11-12 19:34:17 +01:00
epenet 006fc5b10a Remove JSON parsing from tuya diagnostics (#156451) 2025-11-12 19:32:40 +01:00
Erik Montnemery 35a4b685b3 Fix steamist tests opening sockets (#156467) 2025-11-12 12:01:21 -06:00
Janez Urevc b166818ef4 Bump tesla-wall-connector to 1.1.0 (#156438) 2025-11-12 17:45:08 +01:00
Erik Montnemery 34cd9f11d0 Fix onkyo tests opening sockets (#156461) 2025-11-12 17:32:58 +01:00
Erik Montnemery 0711d62085 Change collation to utf8mb4_bin for MySQL and MariaDB databases (#156297)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-12 16:54:58 +01:00
J. Diego Rodríguez Royo f70aeafb5f Bump aiohomeconnect to version 0.23.1 (#156454) 2025-11-12 15:59:20 +01:00
MoonDevLT e2279b3589 Bump lunatone-rest-api-client to 0.5.7 (#156356) 2025-11-12 14:44:52 +01:00
Christopher Fenner 87b68e99ec Add compressor, condensor and evaporator sensors in ViCare integration (#156411) 2025-11-12 14:42:26 +01:00
Manu b6c8b787e8 Add device storage sensor entities to Xbox (#155657) 2025-11-12 13:53:42 +01:00
Franck Nijhof 78f26edc29 Extend base jinja2 extension with limited template errors (#156431) 2025-11-12 13:52:15 +01:00
ehendrix23 5e6a72de90 Bump pyecobee to 0.3.2 (#156421)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-12 13:40:08 +01:00
Erik Montnemery dcc559f8b6 Fix progress step bugs (#155923) 2025-11-12 13:14:53 +01:00
Manu eda49cced0 Code quality improvements for Xbox integration (#156395) 2025-11-12 14:09:53 +02:00
Josef Zweck 14e41ab119 Fix lamarzocco update status (#156442) 2025-11-12 13:10:23 +02:00
Timothy 46151456d8 Make sure to clean register callbacks when mobile_app reloads (#156028) 2025-11-12 12:03:05 +01:00
cdnninja 39773a022a Bump pyvesync to 3.2.2 (#156423)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-11-12 11:59:45 +01:00
Christopher Fenner 5f49a6450f Add air quality sensors in ViCare integration (#156417) 2025-11-12 11:45:04 +01:00
Christopher Fenner dc8425c580 Add icon for pm4 sensor (#156432) 2025-11-12 11:38:33 +01:00
Josef Zweck 910bd371e4 Remove wsproto from exceptions (#156434) 2025-11-12 11:16:36 +01:00
Tom Matheussen 802a225e11 Clean alarm control panel platform for Satel Integra (#156357) 2025-11-12 11:09:48 +01:00
Josef Zweck 84f66fa689 Fix aussie-broadband tests (#156441) 2025-11-12 10:54:23 +01:00
wollew 0b7e88d0e0 add parallel_updates for button entity (#156437) 2025-11-12 11:49:32 +02:00
puddly 1fcaf95df5 Bump universal-silabs-flasher to v0.1.0 (#156291)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-12 10:44:33 +01:00
Erik Montnemery 6c7434531f Fix tado tests opening sockets (#156386) 2025-11-12 10:08:15 +01:00
Åke Strandberg 5ec1c2b68b Use runtime_data in Senz (#156408) 2025-11-12 10:06:45 +01:00
Christopher Fenner d8636d8346 Bump PyViCare to 2.55.0 (#156426) 2025-11-12 09:57:49 +01:00
Brett Adams 434763c74d Fix update progress in Teslemetry (#156422) 2025-11-12 09:55:09 +01:00
Petar Petrov 8cd2c1b43b Add power configuration to Energy dashboard (#153809)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 09:21:33 +01:00
Daniel Hjelseth Høyer 44711787a4 Update pyMill to 0.14.1 (#156396) 2025-11-12 09:15:59 +01:00
TheJulianJES 98fd0ee683 Exempt wsproto from license check (#156418) 2025-11-12 08:45:11 +01:00
Joost Lekkerkerker 303e4ce961 Add mac address to Velux device (#156376) 2025-11-12 09:45:02 +02:00
Paul Bottein 76f29298cd Add home panel (#156269) 2025-11-12 09:09:39 +02:00
Will Moss 17f5d0a69f Use common string for the remaining oauth2 error messages (#156407) 2025-11-12 04:43:12 +01:00
johanzander 90561de438 Refactor Growatt Server integration tests (#156413)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-12 00:32:25 +01:00
Will Moss aedd48c298 Improved error handling for oauth2 configuration in toon integration (#156218) 2025-11-11 22:38:46 +01:00
Will Moss febbb85532 Improved error handling for oauth2 configuration in netatmo integration (#156207) 2025-11-11 22:37:56 +01:00
Franck Nijhof af67a35b75 Extend base jinja2 extension with hass requirement and tests (#156403) 2025-11-11 22:34:08 +01:00
Will Moss dd34d458f5 Improved error handling for oauth2 configuration in tesla_fleet integration (#156219) 2025-11-11 22:33:20 +01:00
Will Moss 603d4bcf87 Improved error handling for oauth2 configuration in weheat integration (#156217) 2025-11-11 22:23:56 +01:00
Erik Montnemery 2dadc1f2b3 Fix iskra tests opening sockets (#156374) 2025-11-11 21:18:14 +01:00
epenet 936151fae5 Use dpcode_wrapper in tuya sensor platform (#156277) 2025-11-11 21:16:41 +01:00
wollew 9760eb7f2b Deprecate velux reboot action (#155549)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 20:23:07 +01:00
Erik Montnemery 7851bed00c Fix zimi tests opening sockets (#156382) 2025-11-11 11:48:30 -06:00
wollew 6aba0b20c6 Add Velux initial quality scale assessment (#154615) 2025-11-11 18:46:24 +01:00
Åke Strandberg cadfed2348 Add diagnostics to SENZ (#156383) 2025-11-11 18:19:37 +01:00
Åke Strandberg 44e2fa6996 Improve handling of OAuth2 implementation unavailable in SENZ (#156381) 2025-11-11 17:42:19 +01:00
Andrew Jackson d0ff617e17 Transmission Service validation and fixes (#155554) 2025-11-11 17:29:42 +01:00
wollew 8e499569a4 Add reboot button to velux gateway device (#155547)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 17:10:20 +01:00
Åke Strandberg 5e0ebddd6f Add temperature sensor to SENZ integration (#156181) 2025-11-11 16:33:49 +01:00
Artur Pragacz c0f61f6c2b Improve code quality of music assistant config flow (#156263) 2025-11-11 16:06:54 +01:00
Manu df60de38b0 Add In party sensor to Xbox integration (#155967) 2025-11-11 16:05:38 +01:00
Manu cb086bb8e9 Refactor media source platform in Xbox integration (#155925) 2025-11-11 15:01:53 +01:00
Erik Montnemery ee2e9dc7d6 Fix homewizard tests opening sockets (#156370) 2025-11-11 15:00:18 +01:00
TheJulianJES 85cd3c68b7 Remove redundant Z-Wave binary sensor entity_description arg (#156323) 2025-11-11 15:00:07 +01:00
Erik Montnemery 1b0b6e63f2 Fix squeezebox tests opening sockets (#156373) 2025-11-11 15:50:56 +02:00
Erik Montnemery 12fc79e8d3 Fix google_generative_ai_conversation tests opening sockets (#156371) 2025-11-11 14:33:36 +01:00
Ludovic BOUÉ ca2e7b9509 Add Matter Eve Shutter device with corresponding fixtures and snapshots (#156296) 2025-11-11 14:07:08 +01:00
Teemu R. 8e8becc43e tplink: handle repeated, unknown thermostat modes gracefully (#156310) 2025-11-11 14:06:29 +01:00
Paul Annekov dcec6c3dc8 Forbid to choose state in Ukraine Alarm integration (#156183) 2025-11-11 14:05:14 +01:00
Retha Runolfsson c0e59c4508 Add support for switchbot s20 (#156368) 2025-11-11 13:55:50 +01:00
Erik Montnemery cd379aadbf Use pytest.mark.freeze_time in sensibo tests (#156348) 2025-11-11 13:52:19 +01:00
antoniocifu ccdd54b187 Fix support for Hyperion 2.1.1 (#156343)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 13:18:35 +01:00
Marc Mueller 3f22dbaa2e Update pytest to 9.0.0 (#156365) 2025-11-11 13:18:09 +01:00
Retha Runolfsson c18dc0a9ab Add support for Switchbot Smart thermostat radiator (#155123) 2025-11-11 13:12:39 +01:00
Erik Montnemery f0e4296d93 Use pytest.mark.freeze_time in sensor tests (#156349) 2025-11-11 13:05:52 +01:00
Erik Montnemery b3750109c6 Use pytest.mark.freeze_time in playstation_network tests (#156347) 2025-11-11 13:05:38 +01:00
Erik Montnemery 93025c9845 Use pytest.mark.freeze_time in pglab tests (#156346) 2025-11-11 13:05:17 +01:00
Erik Montnemery df348644b1 Use pytest.mark.freeze_time in openai_conversation tests (#156345) 2025-11-11 13:05:02 +01:00
Erik Montnemery 8749b0d750 Use pytest.mark.freeze_time in smhi tests (#156352) 2025-11-11 13:02:21 +01:00
Erik Montnemery a6a1519c06 Use pytest.mark.freeze_time in snoo tests (#156353) 2025-11-11 13:02:01 +01:00
Erik Montnemery 3068e19843 Use pytest.mark.freeze_time in telegram_bot tests (#156354) 2025-11-11 13:01:34 +01:00
Erik Montnemery 55feb1e735 Use pytest.mark.freeze_time in tomorrowio tests (#156355) 2025-11-11 13:01:29 +01:00
Erik Montnemery bb7dc69131 Use pytest.mark.freeze_time in yale_smart_alarm tests (#156359) 2025-11-11 12:06:22 +01:00
Erik Montnemery aa9003a524 Use pytest.mark.freeze_time in wake_word tests (#156360) 2025-11-11 12:06:12 +01:00
Erik Montnemery 4e9da5249d Use pytest.mark.freeze_time in utility_meter tests (#156361) 2025-11-11 12:05:58 +01:00
Erik Montnemery f502739df2 Use pytest.mark.freeze_time in zha tests (#156358) 2025-11-11 12:04:59 +01:00
Erik Montnemery 0f2ff29378 Use pytest.mark.freeze_time in sleep_as_android tests (#156351) 2025-11-11 12:04:40 +01:00
Erik Montnemery 2921e7ed3c Use pytest.mark.freeze_time in plaato tests (#156362) 2025-11-11 12:04:31 +01:00
Christopher Fenner 25d44e8d37 Enhance compressor phase with state translations in ViCare integration (#156238) 2025-11-11 11:20:27 +01:00
Will Moss 0a480a26a3 Remove import of config_entry_oauth2_flow in scaffold in favor of direct imports (#156302) 2025-11-11 11:17:31 +01:00
Khole d5da64dd8d Bump pyhive to 1.0.7 (#156309) 2025-11-11 11:16:11 +01:00
wollew 92adcd8635 add the velux KLF 200 gateway as device (#155434)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-11 11:13:18 +01:00
Joost Lekkerkerker ee0c4b15c2 Make certain fields required for subentry flows (#156251) 2025-11-11 09:42:51 +01:00
Erik Montnemery 507f54198e Use pytest.mark.freeze_time in habitica tests (#156332) 2025-11-11 09:37:17 +01:00
epenet 0ed342b433 Use dpcode_wrapper in tuya alarm control panel platform (#156306) 2025-11-11 09:36:09 +01:00
cdnninja 363c86faf3 Add remove entity to vesync (#156213) 2025-11-11 09:35:19 +01:00
dependabot[bot] 095a7ad060 Bump actions/dependency-review-action from 4.8.1 to 4.8.2 (#156322)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 09:34:38 +01:00
Åke Strandberg ab5981bbbd Use common string for OAuth2 implementation error in myuplink (#156338) 2025-11-11 09:33:59 +01:00
Erik Montnemery ac2fb53dfd Fix typo in recorder statistics_meta table manager (#156326) 2025-11-11 09:33:30 +01:00
Erik Montnemery 02ff5de1ff Use pytest.mark.freeze_time in ntfy tests (#156336) 2025-11-11 09:33:21 +01:00
Erik Montnemery 5cd5d480d9 Check collation of statistics_meta DB table (#156327) 2025-11-11 09:31:43 +01:00
Erik Montnemery a3c7d772fc Use pytest.mark.freeze_time in conversation tests (#156329) 2025-11-11 09:29:46 +01:00
micha91 fe0c69dba7 Update aiomusiccast to 0.15 (#156325) 2025-11-11 09:26:16 +01:00
Artur Pragacz e5365234c3 Add myself as codeowner to music assistant (#156324) 2025-11-11 09:24:09 +01:00
Erik Montnemery 1531175bd3 Use pytest.mark.freeze_time in google tests (#156330) 2025-11-11 09:22:48 +01:00
Erik Montnemery 62add59ff4 Use pytest.mark.freeze_time in google_generative_ai_conversation tests (#156331) 2025-11-11 09:21:52 +01:00
Erik Montnemery d8daca657b Use pytest.mark.freeze_time in intellifire tests (#156333) 2025-11-11 10:17:58 +02:00
Erik Montnemery 1891da46ea Use pytest.mark.freeze_time in knx tests (#156335) 2025-11-11 08:52:39 +01:00
Marc Mueller 22ae894745 Update pytest-asyncio to 1.3.0 (#156315) 2025-11-10 22:07:02 -08:00
Will Moss 160810c69d Move oauth2_implementation_unavailable string to top level (#156299) 2025-11-11 06:58:24 +01:00
epenet 2ae23b920a Use dpcode_wrapper in tuya siren platform (#156284) 2025-11-10 23:06:14 +01:00
Artur Pragacz a7edfb082f Move config intents to manager (#154903) 2025-11-10 16:04:25 -06:00
Ludovic BOUÉ 3ac203b05f Add Matter Aqara W100 fixture (#156305)
- Adds JSON fixture file containing Matter node data for the Aqara W100 sensor
- Updates test configuration to include the new fixture in parametrized tests
- Adds snapshot test data for sensor and button entities created by this device
2025-11-10 21:58:18 +01:00
Jan Bouwhuis 7c3eb19fc4 Fix issues() template method returns non active issues (#156274) 2025-11-10 21:56:57 +01:00
kingy444 70c6fac743 Move hunterdouglas_powerview data class to upstream library (#156228)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-11-10 14:49:00 -06:00
Åke Strandberg e19d7250d5 Adjust user-facing string for miele (#156280) 2025-11-10 20:42:42 +01:00
Maikel Punie a850d5dba7 Bump velbusaio to 2025.11.0 (#156293) 2025-11-10 21:25:00 +02:00
Erik Montnemery 0cf0f10654 Correct migration to recorder schema 51 (#156267)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-10 20:14:25 +01:00
Ludovic BOUÉ 8429f154ca Fix status checks in Matter binary sensors (#156276)
This PR fixes bitmap bit checking logic in Matter binary sensors by replacing equality comparisons with bitwise AND operations. The changes correct how the integration checks if specific bits are set in bitmap fields.

Key changes:

Changed equality checks (==) to bitwise AND operations (&) for checking bitmap bits
Wrapped bitwise operations with bool() to ensure boolean return values
Applied fixes consistently across PumpStatus, DishwasherAlarm, and RefrigeratorAlarm bitmaps
2025-11-10 19:45:17 +01:00
Assaf Inbal 7b4f5ad362 Ituran: Don't cache properties (#156281) 2025-11-10 19:24:58 +02:00
David Rapan 583b439557 Add Shelly number translation (#156156)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-10 19:15:16 +02:00
Michael Hansen 05922de102 Always chunk Wyoming TTS audio (#156079) 2025-11-10 10:40:45 -05:00
Khole 7675a44b90 Hive: Remove Alarm Support (#156184) 2025-11-10 16:32:38 +01:00
Simone Chemelli 1e4d645683 Fix config flow reconfigure for Comelit (#156193) 2025-11-10 16:28:47 +01:00
Glenn Vandeuren (aka Iondependent) b5ae04605a Add climate platform for niko_home_control (#138087)
Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: VandeurenGlenn <8685280+VandeurenGlenn@users.noreply.github.com>
2025-11-10 16:27:59 +01:00
Manu 2240d6b94c Enable trophy sensors also for friends in PlayStation Network integration (#156106) 2025-11-10 16:18:15 +01:00
Foscam-wangzhengyu d1536ee636 Foscam Integration with Legacy Model Compatibility (#156226)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-10 16:14:57 +01:00
J. Nick Koston 8a926add7a Bump PySwitchbot to 0.73.0 (#156266) 2025-11-10 10:10:23 -05:00
J. Nick Koston 31f769900a Bump aiopvapi to 3.3.0 (#156268) 2025-11-10 10:06:58 -05:00
cdnninja 33ad777664 Add temp sensor to vesync humidifers (#155637)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-10 16:03:16 +01:00
Bouwe Westerdijk 59a4e4a337 Add Plugwise Adam zone profile select (#156262) 2025-11-10 16:00:26 +01:00
Andre Lengwenus 66a39933b0 Remove translations for non-existing service (#156265) 2025-11-10 15:53:00 +01:00
Heindrich Paul ad395e3bba Add delay clean time support to Tuya integration for cat litter boxes (#156053) 2025-11-10 15:48:00 +01:00
hanwg cfc6f2c229 Remove yaml in tests for Telegram polling bot (#156257) 2025-11-10 15:30:06 +01:00
Andrew Jackson 63aa41c766 Bump aiomealie to 1.1.0, adding recipe rating (#156256) 2025-11-10 15:28:45 +01:00
Tom Matheussen 037e0e93d3 Cleanup binary sensor platform for Satel Integra (#155915)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-11-10 15:13:49 +01:00
epenet db8b5865b3 Improve Tuya event tests (#156259) 2025-11-10 15:03:23 +01:00
epenet bd2ccc6672 Add tests for tuya button (#156252) 2025-11-10 14:54:51 +01:00
Joost Lekkerkerker bb63d40cdf Bump pySmartThings to 3.3.2 (#156250) 2025-11-10 14:53:29 +01:00
Ludovic BOUÉ 65285b8885 Fix Matter ValveFault attribute handling (#156258)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-10 14:45:13 +01:00
Denis Shulyaka 326b8f2b4f Add AI task for Anthropic (#156221) 2025-11-10 14:01:28 +01:00
Heindrich Paul 9f3df52fcc Added light support to cat litter boxes (#156051) 2025-11-10 13:57:54 +01:00
wollew 875838c277 adjust naming of velux light entities according to guidelines (#155850) 2025-11-10 13:55:17 +01:00
epenet adaafd1fda Use dpcode_wrapper in tuya binary sensor platform (#156247)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-10 13:54:09 +01:00
Heindrich Paul 50c5efddaa Add buttons for cat litter box devices (#156050) 2025-11-10 13:50:40 +01:00
epenet c4be054161 Adjust Tuya DPCodeBooleanWrapper inheritance (#156255) 2025-11-10 13:39:09 +01:00
Bouwe Westerdijk 61186356f3 Refresh test-fixtures for Plugwise (#156253) 2025-11-10 13:35:24 +01:00
Will Moss 9d60a19440 Improved error handling for oauth2 configuration in volvo integration (#156215) 2025-11-10 13:17:48 +01:00
epenet 108c212855 Use dpcode_wrapper in tuya button platform (#156237) 2025-11-10 12:58:42 +01:00
Erik Montnemery ae8db81c4e Use pytest.mark.freeze_time in ambient_network tests (#156241) 2025-11-10 12:50:43 +01:00
dotvav 51c970d1d0 Bump pypalazzetti lib from 0.1.19 to 0.1.20 (#156249) 2025-11-10 12:49:40 +01:00
Erik Montnemery d2d47cb607 Use pytest.mark.freeze_time in config_entries tests (#156239) 2025-11-10 12:12:26 +01:00
hahn-th b7a5447c8b Bump homematicip to 2.4.0 (#156235) 2025-11-10 12:04:38 +01:00
Erik Montnemery 2f80780f75 Use pytest.mark.freeze_time in bring tests (#156243) 2025-11-10 12:02:57 +01:00
Tom Matheussen 053ec2598f Cleanup switch platform for Satel Integra (#155987) 2025-11-10 12:00:27 +01:00
Erik Montnemery 85bed4ca77 Use pytest.mark.freeze_time in ai_task tests (#156240) 2025-11-10 12:07:08 +02:00
Erik Montnemery d0d268ffdc Use pytest.mark.freeze_time in cert_expiry tests (#156245) 2025-11-10 12:06:10 +02:00
Erik Montnemery a709fa5f6c Use pytest.mark.freeze_time in bmw_connected_drive tests (#156242) 2025-11-10 12:05:25 +02:00
Erik Montnemery 0c99638129 Use pytest.mark.freeze_time in caldav tests (#156244) 2025-11-10 12:04:42 +02:00
epenet 8a03ab2f64 Add async dpcode update wrapper to Tuya (#156230) 2025-11-10 10:09:22 +01:00
Heindrich Paul d2ad5b43f2 Added switches to cat litter box (#156055) 2025-11-10 09:12:14 +01:00
epenet 4fae49158c Add wrapper class for integer values in Tuya models (#156039)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-10 08:20:18 +01:00
Artur Pragacz 36268ffb73 Remove capability_attributes from CalculatedState (#151672) 2025-11-10 08:06:02 +01:00
Will Moss 1bd70454e1 Improved error handling for oauth2 configuration in onedrive integration (#156216) 2025-11-10 06:21:17 +01:00
OzGav dbc53b99c1 Music Assistant: Fix strings.json (#156188)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-11-10 05:34:35 +01:00
Michael 9ec3aee8aa Fix Climate state reproduction when target temperature is None (#156220) 2025-11-09 23:29:46 +01:00
Denis Shulyaka 8d50754056 Update OpenAI suggested prompt to not include citations (#154292)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-11-09 22:06:43 +01:00
Will Moss 6ee71dae35 Improved error handling for oauth2 configuration in smartthings integration (#156203) 2025-11-09 21:52:25 +01:00
Will Moss 9605921857 Improved error handling for oauth2 configuration in twitch integration (#156214) 2025-11-09 21:51:48 +01:00
Simone Chemelli 6f06eb5ecc Code optimization for Comelit (#156194) 2025-11-09 21:51:23 +01:00
Will Moss 4ca620e450 Improved error handling for oauth2 configuration in withings integration (#156206) 2025-11-09 21:50:47 +01:00
Will Moss 69c5668b13 Improved error handling for oauth2 configuration in point integration (#156202) 2025-11-09 21:49:57 +01:00
Will Moss 17fc1c5dbc Improved error handling for oauth2 configuration in youtube integration (#156205) 2025-11-09 21:48:43 +01:00
Will Moss 6cfe6ed543 Improved error handling for oauth2 configuration in spotify integration (#156201) 2025-11-09 21:47:28 +01:00
G Johansson b9fb4469d8 Remove deprecated start of flow no link to config entry (#155956)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-09 20:16:56 +01:00
Manu f53c581845 Inject httpx.AsyncClient session in Xbox integration (#156172) 2025-11-09 19:28:11 +01:00
Ville Skyttä a39710f9bc huawei_lte sensor improvements (#155693) 2025-11-09 19:26:48 +01:00
Manu 47734f54e8 Bump python-xbox to v0.1.1 (#156208) 2025-11-09 19:20:14 +01:00
cdnninja 52b3636e52 Bump pyvesync to 3.2.1 (#156195) 2025-11-09 19:06:01 +01:00
Will Moss 7aced2522a Use error introduced in #154579 in yolink integration (#156092) 2025-11-09 17:44:44 +01:00
Paul Bottein 5b2d43dffb Set climate, light and security panel not visible by default (#155973) 2025-11-09 16:01:03 +01:00
starkillerOG b4d6a44c21 Fix set_absolute_position angle (#156185) 2025-11-09 14:54:49 +01:00
Norbert Rittel adf8644cc3 Add missing hyphen to "device-specific" in onewire (#156187) 2025-11-09 14:47:26 +01:00
Khole acb6dc9a4f Hive fix via_device warning (#156173) 2025-11-09 13:13:32 +01:00
Matthias Alphart 463796fb4a Update xknx to 3.10.1 (#156177) 2025-11-09 13:08:48 +01:00
Khole c74a298b5b Hive Fix build dependancy requirement (#156171) 2025-11-09 10:31:11 +01:00
Ville Skyttä fb30535730 Make huawei_lte button and select names translatable (#155058) 2025-11-09 09:55:51 +01:00
Erwin Douna 7249a3c846 Portainer refactor sensor defaults (#155543) 2025-11-09 09:52:27 +01:00
dotlambda 21fce10742 Update caldav to 2.1.0 (#156166) 2025-11-09 09:46:40 +01:00
G Johansson ea04c6d88f Fix double reloading in esphome (#155142) 2025-11-09 09:45:09 +01:00
steinmn ce6127d87a Adax: Use TextSelectorType.PASSWORD for wifi-password to ensure it's treated as a password (#154852) 2025-11-09 09:44:06 +01:00
CubeZ2mDeveloper 646b1e36bf zwave_js: Add USB discovery for SONOFF Z-Wave 800 Dongle Plus (ZG23) (#155542)
Co-authored-by: WangWenyu <329577273@qq.com>
2025-11-09 09:41:34 +01:00
epenet 3eac379a13 Reorder TypeInformation classes in Tuya models (#156134) 2025-11-09 09:16:59 +01:00
Abílio Costa 88b6754c73 Fix MFA Notify setup flow schema (#156158) 2025-11-09 09:13:13 +01:00
Sören e0aa850d18 Update to version 1.6.1 of avea library (#156043) 2025-11-09 09:03:44 +01:00
Manu 4a85837f2e Raise on ImplementationUnavailableError in Xbox integration (#156168) 2025-11-09 08:56:16 +01:00
Denis Shulyaka 9002116572 Separate steps for Anthropic subentry flow (#155010)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-09 00:01:57 -05:00
David Rapan 7517569ea4 Add Shelly button translation (#156153)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-09 01:36:09 +02:00
Maciej Bieniek cd86c78750 Control modes for Shelly Cury (#155665)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-09 00:01:56 +01:00
Maciej Bieniek a0da295143 Add buttons to control the screen of the Shelly Wall Display (#156052)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-08 23:48:19 +01:00
Jan Rieger fd6ca8b081 Bump aio-ownet to 0.0.5 (#156157) 2025-11-08 22:08:13 +00:00
Will Moss 3dea0a917e Use error introduced in #154579 in august integration (#156096) 2025-11-08 14:46:12 -06:00
Will Moss a94c333754 Use error introduced in #154579 in yale integration (#156095) 2025-11-08 14:45:13 -06:00
J. Nick Koston 7fd482e3d6 Bump aioesphomeapi to 42.7.0 (#156138) 2025-11-08 14:29:37 -06:00
J. Nick Koston 162c1f1f31 Bump dbus-fast to 2.45.0 (#156137) 2025-11-08 14:29:25 -06:00
Åke Strandberg f8affb2b6a Add temperature sensor to Adax heaters (#156120) 2025-11-08 18:02:31 +01:00
J. Diego Rodríguez Royo 738863ad38 Use ConfigFlowContext at Home Connect config flow tests (#156132) 2025-11-08 07:36:08 -08:00
Allen Porter 59b3e65618 Bump python-roborock to 3.7.1 (#156129) 2025-11-08 15:57:02 +01:00
Maciej Bieniek 3840e50868 Bump aioshelly to version 13.17.0 (#156125) 2025-11-08 16:52:22 +02:00
karwosts 79339aefed Fix sequence block copy-paste (#155206) 2025-11-08 15:50:07 +01:00
epenet df3a4c5916 Migrate tuya event platform to use DPCodeWrapper (#156127) 2025-11-08 15:44:42 +01:00
Richard Kroegel 2e21ae0da7 Fix manifest URL requirement install check (#155664) 2025-11-08 15:42:44 +01:00
Stephan Martin 6992bfeef9 Add global radiation sensor to Zamg component (#155767) 2025-11-08 15:32:59 +01:00
Amit Finkelstein 625d7e2e44 Address review comments in Supervisor integrattion (#155928) 2025-11-08 15:31:02 +01:00
Will Moss 5af9082dc6 Use error introduced in #154579 in miele integration (#156093)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Åke Strandberg <ake@strandberg.eu>
2025-11-08 15:24:49 +01:00
Glenn Waters 902d89b29e ElkM1: Fix for using wrong variable to represent connected state. (#155177) 2025-11-08 15:18:49 +01:00
Åke Strandberg dfb0ea4202 Implement myuplink OAuth2 ImplementationUnavailableError (#155872) 2025-11-08 15:16:58 +01:00
Erik Montnemery 890894b3ae Fix octoprint tests opening sockets (#155901) 2025-11-08 15:15:25 +01:00
konddda dd95921eda Add missing power and current sensors for shelly topac ev charger. (#156099)
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
2025-11-08 15:12:41 +01:00
Maciej Bieniek 9479a88393 Fix device class and unit for Shelly rainfall sensor (#156124) 2025-11-08 15:11:56 +01:00
J. Diego Rodríguez Royo 3519611d8e Handle ImplementationUnavailableError at Home Connect (#156105) 2025-11-08 15:10:30 +01:00
Bouwe Westerdijk 1f04e0e655 Add string-constants to Plugwise - part 1 (#156042) 2025-11-08 15:09:38 +01:00
David Rapan 074c1ff775 Add Shelly update translation (#156062)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-08 15:08:11 +01:00
Ville Skyttä 0e28e6a323 huawei_lte test typing improvements (#156071) 2025-11-08 14:53:11 +01:00
Roy van Manen 9f01e0f6ea Add support for ENTRY_EXIT_2 zone type (#156031) 2025-11-08 14:39:08 +01:00
cdnninja 805a03dfd2 update methods to non deprecated methods in vesync (#155887) 2025-11-08 14:31:50 +01:00
karwosts 99bf3a6c6a Update error message for internal quality scale (#155938) 2025-11-08 14:30:41 +01:00
Maciej Bieniek 45ea8125d3 Fix sensor name translations for Shelly (#156118) 2025-11-08 14:29:43 +01:00
Mick Vleeshouwer a606511a7e Fix regression in Atlantic Electrical Heater with Adjustable Setpoint in Overkiz (#154783) 2025-11-08 13:56:17 +01:00
Heindrich Paul b5f215960f Add fixture for Poopy Nano 2 device in Tuya tests (#156048)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-08 11:30:01 +01:00
asafhas dc8ddc0dcc Add Tuya Video Doorbell fixture (#156103)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-08 10:22:51 +01:00
Manu c84c098d2c Change icon of spring effect in OpenRGB integration (#156098) 2025-11-08 09:38:41 +01:00
Andre Lengwenus f5a4071a81 Remove unused deprecation strings (#156097) 2025-11-08 09:35:34 +01:00
epenet ac5316e3ac Remove duplicate code in tuya find_dpcode (#156019) 2025-11-08 08:17:09 +01:00
Paul Bottein 2a2599de88 Add sidebar default visible flag to panels (#155506) 2025-11-07 22:40:59 -05:00
Markus Jacobsen aac25fa480 Bump mozart-api to 5.1.0.247.1 (#156067) 2025-11-08 00:02:13 +00:00
TheJulianJES 999acc4273 Log HomeAssistantErrors in ZHA config flow (#156075) 2025-11-07 23:57:42 +00:00
Manu 5dcf3d8419 Bump pynecil to v4.2.1 (#156064) 2025-11-07 23:54:45 +00:00
Nick Kuiper 9c14853e73 Update bluecurrent-api to 1.3.2 (#156049) 2025-11-07 23:49:18 +00:00
Michael 5659122f1d Add current user rights to diagnostics data of FRITZ!Box Tools (#156083) 2025-11-08 00:23:42 +01:00
Erwin Douna 3671222d7b Bump pyportainter 1.0.14 (#156072) 2025-11-08 01:19:00 +02:00
TheJulianJES bfd2883a4b Fix comment typo in ZHA config flow tests (#156078) 2025-11-08 01:16:15 +02:00
Marc Mueller 67156d159f Truncate password before sending it to bcrypt (#155950) 2025-11-07 21:26:32 +01:00
puddly 45c0891c3b Remove @progress_step decorator from ZHA and Hardware integration (#155867)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-07 21:26:05 +01:00
Michael Hansen 0694372c61 Bump intents to 2025.11.7 (#156063) 2025-11-07 13:21:28 -06:00
Jan-Philipp Benecke 2bbf4ebc9e Make BTHome sensor entities translatable (#156060) 2025-11-07 20:48:18 +02:00
Jan-Philipp Benecke 818b7bb33f Prevent overriding default values when restoring descriptions in passive bluetooth update processor (#156044) 2025-11-07 18:09:03 +01:00
David Rapan a265ecfade Add Shelly sensor translation (#154106)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-07 18:09:41 +02:00
epenet d52749c71a Add wrapper class for boolean values in Tuya models (#155905) 2025-11-07 16:16:14 +01:00
Guido Schmitz 5eb5b93c0e Allow devolo Home Control remote gateways to be offline (#152486)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-11-07 15:00:48 +00:00
epenet 7c6a39ec91 Add wrapper class for enum values in Tuya models (#155847) 2025-11-07 15:23:36 +01:00
Abílio Costa 57c3a5c349 Move imports to top level in websocket_api commands (#156004) 2025-11-07 14:10:19 +00:00
Erik Montnemery 07c4c58ce4 Deprecate http.server_host option and raise issue if used (#155849)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-11-07 14:51:07 +01:00
David Rapan 6a07b468a3 Add SQL services test for rollback on error (#155607)
Co-authored-by: J. Diego Rodríguez Royo <jdrr1998@hotmail.com>
2025-11-07 13:21:33 +01:00
epenet d63fdf7d35 Rename service registration method in amberelectric (#156032) 2025-11-07 13:20:15 +01:00
Joost Lekkerkerker d6eaa9fd7a Explode dataclasses in Alexa devices diagnostics (#155994) 2025-11-07 13:19:49 +01:00
epenet b7c4c28592 Rename service registration method in file (#156033) 2025-11-07 13:19:06 +01:00
epenet 042a0f7986 Rename service registration method in mastodon (#156036) 2025-11-07 13:17:36 +01:00
Foscam-wangzhengyu 5cc9e014b2 Fix the exception caused by the missing Foscam integration key (#156022) 2025-11-07 13:14:07 +01:00
epenet 94e30485c4 Rename service registration method in stookwijzer (#156034) 2025-11-07 13:07:30 +01:00
Ståle Storø Hauknes c9e76ae5d4 Improve scan interval for Airthings Corentium Home 2 (#155694)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-07 12:17:09 +01:00
Bouwe Westerdijk 568ed2f0f6 Add support for Plugwise Anna P1 (#155916) 2025-11-07 11:19:50 +01:00
G Johansson 5237dc073a Remove deprecated config entry handling in OptionsFlow (#155958) 2025-11-07 09:59:06 +01:00
Franck Nijhof a09f754b48 Merge branch 'master' into dev 2025-11-07 08:36:26 +00:00
Josef Zweck 64ad03ca60 Bump onedrive-personal-sdk to 0.0.16 (#156021) 2025-11-07 09:34:39 +01:00
johanzander b79b443a28 Fix Growatt integration authentication error for legacy config entries (#155993)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-07 09:15:24 +01:00
epenet 02148de9e2 Bump tuya-device-sharing-sdk to 0.2.5 (#156014) 2025-11-07 09:06:07 +01:00
Simone Chemelli d5bd93ebda Bump aioamazondevices to 8.0.1 (#155989) 2025-11-07 00:04:08 +01:00
Jan-Philipp Benecke 76bbd94f5d Make BTHome binary sensor names translatable (#155940) 2025-11-07 00:59:14 +02:00
G Johansson b5546b4ab9 Clean up homeassistant.const from deprecations (#155985) 2025-11-06 22:26:40 +01:00
tronikos dca9389735 Handle empty fields in SolarEdge config flow (#155978) 2025-11-06 12:51:07 -08:00
tronikos d3bebd94aa Fix SolarEdge unload failing when there are no sensors (#155979) 2025-11-06 12:50:45 -08:00
Mick Vleeshouwer 53c807bd5a Add additional sensor descriptions for Overkiz (#155869) 2025-11-06 21:10:58 +01:00
Erik Montnemery dffbdf15f2 Fix libre_hardware_monitor tests opening sockets (#155897) 2025-11-06 21:09:20 +01:00
Erik Montnemery e09c35c177 Fix wled tests opening sockets (#155903) 2025-11-06 21:08:06 +01:00
Åke Strandberg 0342d295e1 Fix for corrupt restored state in miele consumption sensors (#155966) 2025-11-06 21:05:41 +01:00
Charlie Rusbridger eb9849c411 Fix wrong BrowseError module in Kode (#155971) 2025-11-06 19:18:07 +00:00
Joshua Peisach (ItzSwirlz) 93d48fae9d noaa_tides: define constants (#155949) 2025-11-06 19:13:37 +00:00
Matthias Alphart d90a7b2345 Fix KNX Climate humidity DPT (#155942) 2025-11-06 19:09:51 +00:00
G Johansson c2f6a364b8 Remove deprecated constant for volt ampere reactive (#155955) 2025-11-06 18:59:11 +00:00
G Johansson bbadd92ffb Remove deprecated square meters constant (#155954) 2025-11-06 18:58:46 +00:00
Tom Monck JR 6a7de24a04 Fix args passed to check_config script (#155885) 2025-11-06 19:27:53 +02:00
G Johansson 67ccdd36fb Allow template in query in sql (#150287) 2025-11-06 17:11:46 +01:00
Andrea Turri 2ddf55a60d Miele time sensors 3/3 - Add absolute time sensors (#146055)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-06 17:09:19 +01:00
TheJulianJES 57e7bc81d4 Bump ZHA to 0.0.78 (#155937) 2025-11-06 16:30:24 +01:00
Erik Montnemery 777f09598f Fix waze_travel_time tests opening sockets (#155902) 2025-11-06 16:09:29 +01:00
G Johansson 81a9ef1df0 Fix spelling in smhi strings (#155951) 2025-11-06 15:54:30 +01:00
Erik Montnemery d063bc87a1 Fix nam tests opening sockets (#155898) 2025-11-06 15:02:03 +01:00
epenet 5fce08de65 Remove getattr in Tuya find_dpcode function (#155941) 2025-11-06 14:51:35 +01:00
epenet c0db966afd Move find_dpcode function out of Tuya entity (#155934) 2025-11-06 13:43:07 +01:00
G Johansson 9288995cad Add fans and battery sensor to systemmonitor (#151066) 2025-11-06 13:08:44 +01:00
Erik Montnemery 4d2abb4f65 Fix ezviz tests opening sockets (#155896) 2025-11-06 12:10:33 +01:00
Artur Pragacz 60014b6530 Rename misspelled service python files (#155909) 2025-11-06 09:59:45 +01:00
Erik Montnemery 3b57cab6b4 Revert "Allow opening sockets in logbook tests" (#155899) 2025-11-06 09:20:28 +01:00
Erik Montnemery 967467664b Disable automatic start of HTTP server in tests (#155857) 2025-11-06 08:37:04 +01:00
alexqzd b87b5cffd8 SmartThings: Expose the entity to control the AC unit beep (#151546) 2025-11-06 07:55:51 +01:00
Artur Pragacz bb44987af1 Clear dynamic encryption key in ESPHome on remove (#155858) 2025-11-06 02:11:32 +01:00
Christopher Fenner 8d3ef2b224 Add icons for presets in ViCare ventilation entity (#155845) 2025-11-05 20:57:02 +01:00
wollew 5e409295f9 velux: add one more missing data_description (#155854) 2025-11-05 20:56:19 +01:00
Franck Nijhof 0b91a92554 Bump version to 2025.11.0 2025-11-05 19:22:08 +00:00
Franck Nijhof 7855df92c8 2025.11 (#155440) 2025-11-05 11:20:38 -08:00
J. Nick Koston 530c189f9c Add Bluetooth WiFi provisioning for Shelly (#155822) 2025-11-05 13:20:24 -06:00
Franck Nijhof 11309f89f0 Bump version to 2025.11.0b6 2025-11-05 18:38:57 +00:00
Paulus Schoutsen 396a987035 Rename DALI Center to Sunricher DALI (#155865)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-05 18:29:29 +00:00
puddly b7696bfb20 Allow hardware integrations to specify TX power for ZHA (#155855)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-05 18:29:27 +00:00
Bram Kragten 5cfbe2cf71 Update frontend to 20251105.0 (#155853) 2025-11-05 18:29:26 +00:00
Erik Montnemery 4e255286af Create issue to warn against using http.server_host in supervised installs (#155837) 2025-11-05 18:29:25 +00:00
giuseppeg88 f05fef9588 Add bad code attempt event to manual alarm control panel (#146315)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-05 18:15:27 +00:00
Paulus Schoutsen a257b5c54c Rename DALI Center to Sunricher DALI (#155865)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-05 19:15:07 +01:00
puddly 5b9f7372fc Allow hardware integrations to specify TX power for ZHA (#155855)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-11-05 19:13:54 +01:00
puddly a4c0a9b3a5 Revert "Fix progress step recursion (#153906)" (#155866) 2025-11-05 18:46:39 +01:00
Bram Kragten 7d65b4c941 Update frontend to 20251105.0 (#155853) 2025-11-05 16:32:06 +01:00
Martin Hjelmare abd0ee7bce Fix progress step recursion (#153906) 2025-11-05 15:48:35 +01:00
Will Moss 9e3eb20a04 Fix account link no internet on startup (#154579)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-11-05 15:23:20 +01:00
Erik Montnemery 6dc655c3b4 Allow opening sockets in logbook tests (#155840) 2025-11-05 14:58:21 +01:00
Maciej Bieniek 9f595a94fb Check if the Brother printer serial number matches (#155842) 2025-11-05 14:15:46 +01:00
Lukas 5dc215a143 Bump python-pooldose to 0.7.8 (#155307)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-11-05 13:04:49 +00:00
starkillerOG 306b78ba5f Bring Reolink test coverage back to 100% (#155839) 2025-11-05 12:22:44 +01:00
Erik Montnemery bccb646a07 Create issue to warn against using http.server_host in supervised installs (#155837) 2025-11-05 12:13:56 +01:00
Christopher Fenner 4a5dc8cdd6 Add labels to selector in AndroidTV config flow (#155660) 2025-11-05 12:05:58 +01:00
Franck Nijhof 53a96af844 Bump version to 2025.11.0b5 2025-11-05 10:38:26 +00:00
Erik Montnemery accb705d8b Fix ESPHome config entry unload (#155830) 2025-11-05 10:29:40 +00:00
Foscam-wangzhengyu 1793abce4f Bump libpyfoscamcgi to 0.0.9 (#155824) 2025-11-05 10:29:38 +00:00
Nathan Spencer 8bfed0b60c Bump pylitterbot to 2025.0.0 (#155821) 2025-11-05 10:29:37 +00:00
steinmn 016c1de2ef Set LG Thinq energy sensor state_class as total_increasing (#155816) 2025-11-05 10:29:35 +00:00
G Johansson c270f31365 Bump holidays to 0.84 (#155802) 2025-11-05 10:29:34 +00:00
puddly f9e06acfc7 Add progress to ZHA migration steps (#155764)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-05 10:29:32 +00:00
Bouwe Westerdijk 901558b293 Bugfix: implement RestoreState and bump backend for Plugwise climate (#155126) 2025-11-05 10:29:31 +00:00
Erik Montnemery 52a751507a Revert "Deprecate http.server_host option and raise issue if used" (#155834) 2025-11-05 11:26:14 +01:00
wollew 533b9f969d velux: add missing data_descriptions in config flow (#155832) 2025-11-05 11:25:07 +01:00
G Johansson 5de7928bc0 Fix sentence casing in smhi (#155831) 2025-11-05 11:24:52 +01:00
epenet aad9b07f86 Simplify tuya sensor code (#155835) 2025-11-05 11:24:06 +01:00
Tom Matheussen 3e2c401253 Allow multiple config entries for Satel Integra (#155833) 2025-11-05 11:21:56 +01:00
Bouwe Westerdijk 762e63d042 Bugfix: implement RestoreState and bump backend for Plugwise climate (#155126) 2025-11-05 11:18:15 +01:00
Aarni Koskela c09cf36345 Bump ruuvitag-ble to 0.3.0 (#155720) 2025-11-05 11:14:31 +01:00
puddly ec6d40a51c Add progress to ZHA migration steps (#155764)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-11-05 11:10:10 +01:00
Erik Montnemery 47c2c61626 Deprecate http.server_host option and raise issue if used (#155828) 2025-11-05 11:08:49 +01:00
Erik Montnemery 73c941f6c5 Fix ESPHome config entry unload (#155830) 2025-11-05 10:32:29 +01:00
epenet 685edb5f76 Add Tuya test fixtures for cz category (#155827) 2025-11-05 09:54:27 +01:00
G Johansson 5987b6dcb9 Improve code formatting in System monitor (#155800) 2025-11-04 22:09:04 -08:00
Oliver Gründel cb029e0bb0 Remove state class for rolling window in ecowitt (#155812) 2025-11-04 22:06:15 -08:00
steinmn 553ec35947 Set LG Thinq energy sensor state_class as total_increasing (#155816) 2025-11-04 22:01:38 -08:00
G Johansson f93940bfa9 Revert "Make influxdb batch settings configurable" (#155808) 2025-11-04 22:00:02 -08:00
Foscam-wangzhengyu 486f93eb28 Bump libpyfoscamcgi to 0.0.9 (#155824) 2025-11-04 21:58:24 -08:00
cdnninja 462db36fef add update platform to vesync (#154915) 2025-11-04 21:40:35 -08:00
Nathan Spencer 485f7f45e8 Bump pylitterbot to 2025.0.0 (#155821) 2025-11-04 18:03:24 -08:00
G Johansson a446d8a98c Add fire sensors to smhi (#153224) 2025-11-04 17:37:32 -08:00
J. Nick Koston b4a31fc578 Bump aioshelly to 13.16.0 (#155813) 2025-11-04 22:20:00 +01:00
G Johansson 22321c22cc Bump holidays to 0.84 (#155802) 2025-11-04 22:18:02 +01:00
Bram Kragten 926627b49c Bump version to 2025.11.0b4 2025-11-04 20:38:30 +01:00
Bram Kragten a8eeba9c5f Update frontend to 20251104.0 (#155799) 2025-11-04 20:38:02 +01:00
Paul Bottein e4591c27c0 Rename safety panel to security panel (#155795) 2025-11-04 20:38:01 +01:00
starkillerOG 40dedec602 Bump reolink-aio to 0.16.4 (#155776) 2025-11-04 20:38:00 +01:00
Matt Zimmerman 3a65b5ca70 Update python-smarttub to 0.0.45 (#155768) 2025-11-04 20:37:59 +01:00
puddly dbeb82861f Bump ZHA to 0.0.77 (#155766) 2025-11-04 20:37:58 +01:00
Brett Adams e43c35ab2d Bump Tesla Fleet API to v1.2.5 (#155763) 2025-11-04 20:37:57 +01:00
karwosts b4c4fdefe3 Fix Ambient Weather incorrect state classes (#155751) 2025-11-04 20:37:56 +01:00
Fredrik Mårtensson 965dd7c557 Catch exception from libsoundtouch if device not available (#155749)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-11-04 20:37:55 +01:00
TheJulianJES 9a921f2c8e Fix ZBT-2 Thread to Zigbee migration discovery failing (#155735) 2025-11-04 20:37:54 +01:00
cdnninja aaae3244a8 Correct Vesync Humidifier Mode (#155638) 2025-11-04 20:37:53 +01:00
TheJulianJES 40ff100900 Add ZHA migration retry steps for unplugged adapters (#155537) 2025-11-04 20:37:52 +01:00
tronikos 1b62b2309f Remove Enmax Energy virtual integration (#155475) 2025-11-04 20:37:51 +01:00
puddly 9d57251aea Fix non-unique ZHA serial port paths and migrate USB integration to always list unique paths (#155019) 2025-11-04 20:37:50 +01:00
TheJulianJES 4419c236e2 Add ZHA migration retry steps for unplugged adapters (#155537) 2025-11-04 20:34:51 +01:00
Maciej Bieniek 1731a2534c Implement base entity class for Brother integration (#155714)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-04 20:28:52 +01:00
Bram Kragten ec0edf47b1 Update frontend to 20251104.0 (#155799) 2025-11-04 14:08:34 -05:00
Tom Matheussen 57c69738e3 Migrate Satel Integra entities unique_id to use config flow entry_id (#154187) 2025-11-04 20:03:08 +01:00
Robert Resch fb1f258b2b Readd deprecated archs to build wheels (#155792) 2025-11-04 19:30:19 +01:00
puddly d419dd0c05 Fix non-unique ZHA serial port paths and migrate USB integration to always list unique paths (#155019) 2025-11-04 11:42:56 -05:00
Paul Bottein 65960aa3f7 Rename safety panel to security panel (#155795) 2025-11-04 17:23:39 +01:00
Marc Mueller a25afe2834 Fix hassio test RuntimeWarning (#155787) 2025-11-04 17:15:20 +01:00
Marc Mueller 4cdfa3bddb Add mkdocs and sphinx to forbidden packages (#155781) 2025-11-04 17:08:33 +01:00
Erwin Douna 9e7bef9fa7 Bump pyportainer 1.0.13 (#155783) 2025-11-04 16:38:27 +01:00
Marc Mueller 68a1b1f91f Fix hassio tests (#155791) 2025-11-04 16:09:47 +01:00
ekutner 1659ca532d Add retry and error logging if communication with the CoolMaster device fails (#148699) 2025-11-04 14:57:32 +01:00
OzGav 8ea16daae4 Correctly map repeat mode in Music Assistant (#155777) 2025-11-04 14:07:15 +01:00
OzGav 5bd89acf9a Use typed config entry in Music Assistant (#155778) 2025-11-04 14:05:44 +01:00
starkillerOG 2b8db74be4 Bump reolink-aio to 0.16.4 (#155776) 2025-11-04 14:03:44 +01:00
krahabb d7f9a7114d Deprecate TemperatureConverter.convert_interval (#155689)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-11-04 13:40:41 +01:00
Marc Mueller f7a59eb86e Sort hassio strings (#155784) 2025-11-04 13:34:57 +01:00
Manu 37eef965ad Add friend count sensor to Xbox integration (#155761) 2025-11-04 11:27:48 +01:00
Amit Finkelstein b706430e66 Add binary sensor for HassOS share mount status (#149197) 2025-11-04 11:14:10 +01:00
Fredrik Mårtensson 5012aa5cb0 Catch exception from libsoundtouch if device not available (#155749)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-11-04 10:24:38 +01:00
karwosts 1c5f7adf4e Fix Ambient Weather incorrect state classes (#155751) 2025-11-04 09:35:08 +01:00
Manu ff364e3913 Add support for multiple entries to Xbox integration (#155771) 2025-11-04 09:00:40 +01:00
jgaalen 0e2a4605ff Make influxdb batch settings configurable (#134758)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-04 08:33:21 +01:00
cdnninja ca5b9ce0d3 Correct Vesync Humidifier Mode (#155638) 2025-11-03 22:44:19 -08:00
Brett Adams 953196ec21 Bump Tesla Fleet API to v1.2.5 (#155763) 2025-11-03 22:15:34 -08:00
Kamil Breguła b5be3d5ac3 Use data_description in config_flow for WLED (#155572)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-03 22:07:15 -08:00
puddly 5d9e8287d3 Bump ZHA to 0.0.77 (#155766) 2025-11-03 21:40:15 -08:00
Matt Zimmerman dc291708ae Update python-smarttub to 0.0.45 (#155768) 2025-11-03 21:39:54 -08:00
Paulus Schoutsen 257e82fe4e Add multiple selection to media selector (#154350) 2025-11-04 01:44:31 +01:00
starkillerOG ab6d4d645e Add Reolink audio noise reduction number entity (#155757)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-11-03 22:41:56 +00:00
starkillerOG 58ebd84326 Add Reolink exposure mode select entity (#155759) 2025-11-03 23:17:52 +01:00
J. Nick Koston 76b24dafed Bump aioesphomeapi to 42.6.0 (#155728) 2025-11-03 22:04:05 +00:00
Kamil Breguła 431f563ff6 Add translation of exceptions in WLED (#155570)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-03 22:59:08 +01:00
starkillerOG e308e610c6 Add Reolink PIR interval number entity (#155758) 2025-11-03 21:53:07 +00:00
Christopher Fenner 5e77cbd185 Add integration_type to Vicare manifest (#155726) 2025-11-03 22:50:41 +01:00
tronikos 2dbc7ff4b7 Remove Enmax Energy virtual integration (#155475) 2025-11-03 22:48:58 +01:00
Kamil Breguła 49a6c5776d Fix typing of ConfigEntry in WLED (#155571)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-03 22:01:42 +01:00
TheJulianJES 98f6001c9c Fix ZBT-2 Thread to Zigbee migration discovery failing (#155735) 2025-11-03 20:02:13 +00:00
Bram Kragten f877614e7f Bump version to 2025.11.0b3 2025-11-03 20:46:58 +01:00
Mike Degatano 170e1e87c7 Disable deprecated addon repair (#155739) 2025-11-03 20:46:03 +01:00
Michael Hansen e1feba5c86 Use character code in language matching (voice) (#155738) 2025-11-03 20:46:02 +01:00
Bram Kragten 9bf52b7966 Update frontend to 20251103.0 (#155734) 2025-11-03 20:46:02 +01:00
Simone Chemelli 3bc61a3564 Bump aioamazondevices to 6.5.6 (#155723) 2025-11-03 20:46:01 +01:00
Bram Kragten ce38a93177 Update frontend to 20251103.0 (#155734) 2025-11-03 20:45:08 +01:00
Mike Degatano 92fbf468f2 Disable deprecated addon repair (#155739) 2025-11-03 13:08:30 -05:00
Michael Hansen e09ec4a6f3 Use character code in language matching (voice) (#155738) 2025-11-03 13:07:38 -05:00
Jan Bouwhuis db63e0c829 Add RSSI signal strength sensor to incomfort boiler (#155688)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-11-03 18:03:46 +01:00
starkillerOG 8ed88d4a58 Add Reolink restart button for IPC cams (#155710) 2025-11-03 16:57:38 +01:00
dependabot[bot] d098ada777 Bump github/codeql-action from 4.31.0 to 4.31.2 (#155538)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-03 16:52:53 +01:00
Ілля Піскурьов 1add999c5a Add separate scale and offset for current temperature for modbus climates (#150985)
Co-authored-by: jan iversen <jancasacondor@gmail.com>
Co-authored-by: Claudio Ruggeri - CR-Tech <41435902+crug80@users.noreply.github.com>
Co-authored-by: crug80 <claudio@cr-tech.it>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-03 16:51:41 +01:00
Artur Pragacz fad217837f Accept more templates in service fields (#150239) 2025-11-03 16:40:42 +01:00
Simone Chemelli 983af1af7b Bump aioamazondevices to 6.5.6 (#155723) 2025-11-03 15:59:39 +01:00
Manu bcf2c4e9b6 Migrate library xbox-webapi to python-xbox in Xbox integration (#155536) 2025-11-03 13:51:40 +01:00
WardZhou c72f2fd546 Add Matter CurrentSensitivityLevel for Heiman and Aqara Occupancy/PIR (#155715) 2025-11-03 13:47:12 +01:00
Kamil Breguła f54864a476 Set PARALLEL_UPDATES for WLED (#155573)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-03 12:32:43 +01:00
Christopher Fenner fe1ff456c6 Add labels to selector in Brother config flow (#155659)
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
2025-11-03 11:22:00 +01:00
Sander Jochems ec25ead5ac Add outside temperature sensor to MELCloud Air-to-Air devices (#150722) 2025-11-03 08:52:56 +01:00
nasWebio e8277cb67c Add alarm control panel platform to NASweb integration (#141582)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-11-03 08:07:53 +01:00
Bram Kragten d2ba94e1bf Bump version to 2025.11.0b2 2025-11-03 08:04:32 +01:00
Joost Lekkerkerker 9a4ed82399 Bump python-open-router to 0.3.2 (#155700) 2025-11-03 08:04:12 +01:00
cdnninja b5136d01aa fix vesync mist level value (#155697) 2025-11-03 08:04:11 +01:00
starkillerOG d3e05090ea Bump reolink_aio to 0.16.3 (#155692) 2025-11-03 08:04:10 +01:00
Michael 7e75ca7af9 Revert "Remove neato integration (#154902)" (#155685) 2025-11-03 08:04:10 +01:00
Matthias Alphart 6616b5775f Fix KNX climate loading min/max temp from UI config (#155682) 2025-11-03 08:04:09 +01:00
Robert Resch 69b82d4c59 Bump deebot-client to 16.3.0 (#155681) 2025-11-03 08:04:08 +01:00
Bram Kragten 6b9709677a Fix device tracker name & icon for Volvo integration (#155667) 2025-11-03 08:03:00 +01:00
Paulus Schoutsen da0fb37a20 Fix hassfest brand domain validation (#155701) 2025-11-02 22:58:34 -08:00
Robert Resch a4e9c82c84 Bump deebot-client to 16.2.0 (#155642) 2025-11-03 07:57:45 +01:00
cdnninja de86bedb80 vesync don't assume fan speed target (#155617) 2025-11-03 07:57:44 +01:00
Matthias Alphart 9111c6df90 Update knx-frontend to 2025.10.31.195356 (#155569) 2025-11-03 07:57:43 +01:00
Jordan Harvey 751f6bddb1 Update pynintendoparental to version 1.1.3 (#155568) 2025-11-03 07:57:42 +01:00
Josef Zweck c9a61de0a1 Bump onedrive-personal-sdk to 0.0.15 (#155540) 2025-11-03 07:57:41 +01:00
Sid 01fb46d903 Bump eheimdigital to 1.4.0 (#155539) 2025-11-03 07:57:41 +01:00
cdnninja d26f61c9fe Bump pyvesync to 3.1.4 (#155533) 2025-11-03 07:57:39 +01:00
Robert Resch a47a144312 Bump uv to 0.9.6 (#155521) 2025-11-03 07:57:38 +01:00
Erwin Douna 69cf4f99d1 Portainer refactor CONF_VERIFY_SSL (#155520) 2025-11-03 07:57:37 +01:00
Shay Levy e6c757c187 Fix Shelly irrigation zone ID retrieval with Sleepy devices (#155514) 2025-11-03 07:57:36 +01:00
hanwg a36b0e2f3f Fix event entity state update for Telegram bot (#155510) 2025-11-03 07:57:35 +01:00
Jakob Schlyter 1a7c6cd96c Update regions and voices used by Amazon Polly (#155501) 2025-11-03 07:57:34 +01:00
tronikos ba3e538402 Bump opower to 0.15.9 (#155473) 2025-11-03 07:57:33 +01:00
Mike Degatano b2cd08aa65 Addon progress reporting follow-up from feedback (#155464) 2025-11-03 07:57:33 +01:00
karwosts 06dcd25a16 Hassfest check for invalid localization placeholders (#155216) 2025-11-03 07:57:32 +01:00
Maciej Bieniek 28675eee33 Finish Brother config flow tests by aborting or creating entry (#155663) 2025-11-03 07:50:56 +01:00
Robert Resch 84561cbc41 Use select entity for Ecovacs station auto empty settings (#155679) 2025-11-02 21:38:21 -08:00
Erwin Douna 4e48c881aa Portainer add resource usage of containers (#155113)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 21:37:04 -08:00
Joost Lekkerkerker af8cd0414b Bump python-open-router to 0.3.2 (#155700) 2025-11-02 16:53:50 -08:00
Paulus Schoutsen f54076da29 Split Yale brand (#155686)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 19:43:46 -05:00
Matthias Alphart 1d0eb97592 Fix KNX climate loading min/max temp from UI config (#155682) 2025-11-02 16:35:44 -08:00
Robert Resch 57f1c268ef Bump deebot-client to 16.3.0 (#155681) 2025-11-02 16:28:02 -08:00
Jakob Schlyter 01402e4f96 Update regions and voices used by Amazon Polly (#155501) 2025-11-02 16:27:50 -08:00
hanwg 6137a643d8 Fix event entity state update for Telegram bot (#155510) 2025-11-02 16:04:57 -08:00
Michael 1badfe3aff Revert "Remove neato integration (#154902)" (#155685) 2025-11-02 15:58:47 -08:00
starkillerOG a549104fe1 Bump reolink_aio to 0.16.3 (#155692) 2025-11-02 15:41:08 -08:00
cdnninja 2aab2ddc55 fix vesync mist level value (#155697) 2025-11-02 15:40:01 -08:00
Åke Strandberg 42e01362a5 Bump pymiele dependency to v0.6.0 (#155698) 2025-11-02 15:08:25 -08:00
Ludovic BOUÉ c3cf24ba25 Add Aqara Presence Multi-Sensor FP300 in Matter tests (#155646) 2025-11-02 20:24:10 +01:00
Ludovic BOUÉ 7809fb6a9b Add Ecovacs Deebot to Matter fixtures (#155587) 2025-11-02 20:23:35 +01:00
David Rapan 144fc2a443 Refactor SQL's data conversion (#155598) 2025-11-02 18:49:18 +01:00
Thomas D c67e005b2c Use command error message for lock in Volvo integration (#155677) 2025-11-02 18:41:00 +01:00
Maciej Bieniek 1c6913eec2 Add full device tests for new Shelly models (#155669) 2025-11-02 18:26:19 +02:00
Aarni Koskela fb5c4a1375 Improve Ruuvi Air support (#155678) 2025-11-02 10:16:44 -06:00
Thomas D 60b8392478 Fix device tracker name & icon for Volvo integration (#155667) 2025-11-02 14:57:17 +01:00
Thomas D 7145fb96dd Add lock platform to Volvo integration (#154168) 2025-11-02 14:46:04 +01:00
Maciej Bieniek 37d94aca6d Set PARALLEL_UPDATES to 0 for Brother sesnors (#155662) 2025-11-02 13:25:45 +01:00
Christian Kemper 9b697edfca Support for deactivating oneTimeCharge (#155592)
Signed-off-by: Christian Kemper <dev@bestof5.de>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-11-02 10:50:56 +01:00
Jordan Harvey 22e30be946 Update pynintendoparental to version 1.1.3 (#155568) 2025-11-02 06:28:21 +01:00
Robert Resch bc9d35b85f Bump deebot-client to 16.2.0 (#155642) 2025-11-01 22:13:29 -07:00
Diogo Gomes 4dfb6e4983 Bump cronsim to 2.7 (#155648) 2025-11-02 00:25:35 +01:00
Kamil Breguła 09d78ab5ad Use data_description in config_flow for GIOS (#155605)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 00:16:09 +01:00
Manu b2ebdb7ef0 Add friend location to Xbox integration (#155645) 2025-11-01 20:18:51 +01:00
cdnninja 83d6a30b2e Add Child Lock Switch to Vesync (#155643) 2025-11-01 20:18:32 +01:00
J. Nick Koston 19dee6d22a Allow configuring ignored Probe Plus devices (#155635) 2025-11-01 11:43:50 -05:00
J. Nick Koston afd27630fb Allow configuring ignored Kuler Sky devices (#155634) 2025-11-01 11:40:06 -05:00
J. Nick Koston cad1f1da1d Allow configuring ignored Elk-M1 devices (#155631) 2025-11-01 18:33:48 +02:00
J. Nick Koston cd62bd86fd Allow configuring ignored Steamist devices (#155630) 2025-11-01 18:33:22 +02:00
J. Nick Koston 79c3bc9eca Allow ignored snooz devices to be set up from the user flow (#155629) 2025-11-01 18:32:59 +02:00
J. Nick Koston 10439eea4b Allow ignored sensorpro devices to be set up from the user flow (#155628) 2025-11-01 18:21:12 +02:00
J. Nick Koston 75cc866e72 Allow ignored sensirion_ble devices to be set up from the user flow (#155626) 2025-11-01 18:15:23 +02:00
J. Nick Koston 8b2ca6c571 Allow ignored ruuvitag_ble devices to be set up from the user flow (#155625) 2025-11-01 18:14:11 +02:00
cdnninja 52db73e8e3 vesync don't assume fan speed target (#155617) 2025-11-01 18:10:08 +02:00
J. Nick Koston 79d15ec91c Allow ignored moat devices to be set up from the user flow (#155624) 2025-11-01 18:07:09 +02:00
J. Nick Koston 5af91df2b9 Allow ignored melnor devices to be set up from the user flow (#155623) 2025-11-01 18:05:32 +02:00
J. Nick Koston 89a85c3d8c Allow ignored medcom_ble devices to be set up from the user flow (#155622) 2025-11-01 18:04:05 +02:00
J. Nick Koston e44c6391b1 Allow ignored led_ble devices to be set up from the user flow (#155620) 2025-11-01 17:58:47 +02:00
J. Nick Koston 99d3234855 Allow ignored leaone devices to be set up from the user flow (#155619) 2025-11-01 17:56:04 +02:00
J. Nick Koston 32cc5123f5 Allow ignored ld2410_ble devices to be set up from the user flow (#155618) 2025-11-01 17:54:01 +02:00
J. Nick Koston 93415175bb Allow ignored bluemaestro devices to be set up from the user flow (#155613) 2025-11-01 17:53:16 +02:00
J. Nick Koston f04bb69dbc Allow ignored keymitt_ble devices to be set up from the user flow (#155616) 2025-11-01 17:51:52 +02:00
J. Nick Koston 9f8c9940bd Allow ignored bluemaestro devices to be set up from the user flow (#155611) 2025-11-01 17:51:16 +02:00
J. Nick Koston 496f527dff Allow ignored kegtron devices to be set up from the user flow (#155614) 2025-11-01 17:50:46 +02:00
Kamil Breguła 385e6f58a8 Set PARALLEL_UPDATES in GIOS (#155604)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2025-11-01 16:25:59 +01:00
Manu c8c37ad628 Remove unused code in Xbox integration (#155575) 2025-11-01 12:20:19 +01:00
David Rapan cc57732e24 Rename Starlink Last boot time to Last restart (#155596) 2025-11-01 12:19:05 +01:00
David Rapan 6011df8952 Refactor Starlink sensor construction (#155591)
Signed-off-by: David Rapan <david@rapan.cz>
2025-11-01 12:33:29 +02:00
Matthias Alphart 08e494aba5 Update knx-frontend to 2025.10.31.195356 (#155569) 2025-11-01 11:16:25 +02:00
Manu 77c428e4c7 Add @tr4nt0r as code owner to Xbox integration (#155582) 2025-11-01 11:14:37 +02:00
Manu c22a2b93fa Bump PSNAWP to 3.0.1 (#155579) 2025-10-31 22:23:32 -07:00
Andrew Jackson 7f84363bf4 Transmission create a common base entity (#155213) 2025-10-31 18:16:35 +01:00
Josef Zweck 0980c3a270 Bump onedrive-personal-sdk to 0.0.15 (#155540) 2025-10-31 16:58:31 +00:00
karwosts 7cec3aa27c Hassfest check for invalid localization placeholders (#155216) 2025-10-31 14:43:11 +01:00
Teemu R. 1ddb39f6d0 Use TEMPERATURE_DELTA for tplink temperature offset (#155239)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2025-10-31 14:19:28 +01:00
Erwin Douna 10d2e38315 Firefly add reconfigure flow (#155530) 2025-10-31 13:42:30 +01:00
Erwin Douna 5299690cb7 Portainer expand reconfigure check (#155544) 2025-10-31 12:05:48 +01:00
Sid 98c1dca7a8 Bump eheimdigital to 1.4.0 (#155539) 2025-10-31 08:59:34 +01:00
cdnninja 54c022d58a Bump pyvesync to 3.1.4 (#155533) 2025-10-31 08:20:02 +01:00
Mike Degatano 77d40ddc7d Addon progress reporting follow-up from feedback (#155464) 2025-10-31 08:17:09 +01:00
Aronne Brivio 092841ca5e Add auto empty sensor to Ecovacs (#155489)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-31 02:24:03 +01:00
Aronne Brivio 70238a613d Add border spin switch to Ecovacs (#155512) 2025-10-31 02:18:39 +01:00
Shay Levy 5b8d373527 Fix Shelly irrigation zone ID retrieval with Sleepy devices (#155514) 2025-10-31 01:05:14 +02:00
Andrew Jackson 4e3664b26f Move Transmission services into separate module (#155490)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-31 00:20:37 +02:00
Robert Resch 76f5cc368b Bump uv to 0.9.6 (#155521) 2025-10-30 23:11:45 +01:00
tronikos 2f4cd21a14 Bump opower to 0.15.9 (#155473) 2025-10-30 21:53:41 +00:00
J. Nick Koston d369aa761a Bump aioesphomeapi to 42.5.0 (#155481) 2025-10-30 21:52:49 +00:00
Erwin Douna d795806e3d Portainer refactor CONF_VERIFY_SSL (#155520) 2025-10-30 20:27:39 +01:00
Bram Kragten fd36782bae Bump version to 2025.11.0b1 2025-10-30 20:12:15 +01:00
Bram Kragten ed4573db57 Update frontend to 20251029.1 (#155513) 2025-10-30 20:11:55 +01:00
Erwin Douna 78373a6483 Firefly fix config flow (#155503) 2025-10-30 20:11:54 +01:00
Sab44 8455c35bec Bump librehardwaremonitor-api to 1.5.0 (#155492) 2025-10-30 20:11:53 +01:00
Kinachi249 00887a2f3f Bump PyCync to 0.4.3 (#155477) 2025-10-30 20:11:52 +01:00
Erwin Douna f1ca7543fa Bump pyportainer 1.0.12 (#155468) 2025-10-30 20:11:51 +01:00
Abílio Costa bb72b24ba9 Mock async_setup_entry in BMW Connected Drive config flow test (#155446) 2025-10-30 20:11:50 +01:00
Andrea Turri 322a27d992 Miele RestoreSensor: restore native value rather than stringified state (#152750)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2025-10-30 20:11:49 +01:00
hanwg a3b516110b Deprecate legacy Telegram notify service (#150720)
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: abmantis <amfcalt@gmail.com>
2025-10-30 20:11:48 +01:00
Bram Kragten d45a80ed06 Update frontend to 20251029.1 (#155513) 2025-10-30 19:49:37 +01:00
Erwin Douna 09b46d22af Firefly fix config flow (#155503) 2025-10-30 19:06:04 +01:00
Artur Pragacz b157afac13 Remove templates from schemas for service fields validation (#150063) 2025-10-30 18:46:43 +01:00
Jordan Harvey edaf5c8167 Add serial number for Nintendo Switch devices (#155500) 2025-10-30 14:42:51 +02:00
Robert Resch 1d6c9e3d94 Don't update the versions for deprecated archs (#155497) 2025-10-30 13:41:30 +01:00
Sab44 ddbc96206f Bump librehardwaremonitor-api to 1.5.0 (#155492) 2025-10-30 13:24:14 +01:00
Robert Resch cee5f4e275 Remove lirc integration (#155457) 2025-10-30 12:57:12 +01:00
Robert Resch 03a1ffc59b Remove keyboard integration (#155456) 2025-10-30 12:42:25 +01:00
Robert Resch 6e921a0192 Remove cups integration (#155448) 2025-10-30 11:27:42 +00:00
Brynley McDonald 99eb48c27f Remove Flick Electric integration (#155469) 2025-10-30 11:23:37 +01:00
Robert Resch 06dbfe52d0 Remove building images for deprecated architectures (#155447) 2025-10-30 10:33:43 +01:00
Kinachi249 b516de119c Bump PyCync to 0.4.3 (#155477) 2025-10-30 09:24:26 +01:00
ElCruncharino dcb2087f4b Add backblaze b2 backup integration (#149627)
Co-authored-by: Hugo van Rijswijk <git@hugovr.nl>
Co-authored-by: ElCruncharino <ElCruncharino@users.noreply.github.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-10-30 08:42:02 +01:00
Manu 7de94f3632 Set Xbox logo as icon for media player (#155459) 2025-10-30 08:40:07 +01:00
Erwin Douna 909e2304c1 Bump pyportainer 1.0.12 (#155468) 2025-10-30 08:39:26 +01:00
Aarni Koskela ae0b854314 Fix Ridwell strings.json (#155483) 2025-10-30 08:18:39 +01:00
Andrea Turri 6a6054afee Miele RestoreSensor: restore native value rather than stringified state (#152750)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2025-10-30 07:53:54 +01:00
kylehakala 3377e90b81 Show rotating category name in event summary if pickup is scheduled in ridwell (#152529) 2025-10-29 19:25:39 -06:00
Robert Resch 342c7f6510 Remove gstreamer integration (#155455) 2025-10-29 23:57:07 +01:00
Michael 982fba167a Add PARALLEL_UPDATES to fritzbox platforms (#155437) 2025-10-29 22:36:17 +00:00
Geoffrey 8026e64d7c Update codeowners for VegeHub integration (#155442)
Co-authored-by: GhoweVege <85890024+GhoweVege@users.noreply.github.com>
2025-10-29 22:34:09 +00:00
Robert Resch ebbfd5a6c7 Remove decora integration (#155449) 2025-10-29 22:30:23 +00:00
Robert Resch 356077541c Remove dlib face integrations (#155450) 2025-10-29 22:26:53 +00:00
Robert Resch 0b9a22b089 Remove eddystone temperature integration (#155452) 2025-10-29 22:25:45 +00:00
Robert Resch cce6f60b70 Remove snips integration (#155461) 2025-10-29 22:22:30 +00:00
Robert Resch d57dc5d0cd Remove pandora integration (#155458) 2025-10-29 22:22:01 +00:00
Robert Resch 6088f5eef5 Remove sms integration (#155460)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 22:21:02 +00:00
Robert Resch 5c96b11479 Remove tensorflow integration (#155462) 2025-10-29 22:18:30 +00:00
G Johansson afda849f3e Bump pynordpool to 0.3.2 (#155453) 2025-10-29 22:30:11 +01:00
Abílio Costa f2f769b34a Mock async_setup_entry in BMW Connected Drive config flow test (#155446) 2025-10-29 20:48:25 +01:00
Ludovic BOUÉ 45558f3087 Fix haojai brand name in Matter fixtures (#155443) 2025-10-29 20:47:30 +01:00
Bram Kragten c10b643af9 Bump version to 2025.12.0.dev0 (#155441) 2025-10-29 20:12:20 +01:00
hanwg 569dd2d6b7 Deprecate legacy Telegram notify service (#150720)
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: abmantis <amfcalt@gmail.com>
2025-10-29 18:40:27 +00:00
Bram Kragten 95ac5c0183 Bump version to 2025.11.0b0 2025-10-29 18:53:20 +01:00
Joakim Sørensen 40995b6d32 Bump hass-nabucasa from 1.4.0 to 1.5.1 (#155424)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-29 18:37:58 +01:00
Geoffrey f64c029bd1 Update library version for VegeHub integration (#155360)
Co-authored-by: GhoweVege <85890024+GhoweVege@users.noreply.github.com>
2025-10-29 18:30:53 +01:00
torben-iometer a050c0cd05 Add configuration_url to iometer (#155429)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-10-29 17:59:05 +01:00
Jordan Harvey 0c121468e0 Validate devices connected to Nintendo Parental Controls accounts (#154873)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-10-29 17:58:53 +01:00
Bram Kragten af277651f8 Update frontend to 20251029.0 (#155432) 2025-10-29 17:42:14 +01:00
Michael Hansen ca90826478 Use satellite area in fuzzy matcher (#155347)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-29 16:27:22 +01:00
Artur Pragacz dd4789af4e Fix translation references to unverified translations (#155314)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-10-29 16:20:59 +01:00
puddly ca49b6e7e2 Bump universal-silabs-flasher to 0.0.37 (#155421)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-29 16:09:05 +01:00
TheJulianJES fdbe293483 Hide HA Connect Zigbee adapters in Z-Wave serial port selector (#154923)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-10-29 16:05:27 +01:00
Joakim Sørensen aa67b46f6f Ensure api_server is defined in dev (#155422)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-29 16:02:05 +01:00
Shay Levy 9f21a97d39 Update IQS for Switcher integration to silver (#155425) 2025-10-29 14:42:24 +00:00
puddly 49158fad48 Fix ZBT and Yellow switch unit tests (#155426) 2025-10-29 15:33:20 +01:00
Jordan Harvey dff8e5221b Use API token authentiation in traccar_server (#155297) 2025-10-29 15:10:47 +01:00
epenet dbfa0aa22c Add missing data_description to sfr_box (#155420) 2025-10-29 16:05:51 +02:00
Shay Levy ec4464d65f Mark Switcher removal instructions as done (#155414) 2025-10-29 15:04:55 +01:00
epenet 6c8dffd521 Add base entity to sfr_box (#155418) 2025-10-29 14:55:32 +01:00
Heindrich Paul 09763012fc Add reconfigure flow to nederlandse_spoorwegen (#155412)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-10-29 14:46:08 +01:00
puddly aa5b970102 Beta firmware update switch for Connect integrations (#155370) 2025-10-29 14:45:56 +01:00
Robert Resch 80912045d7 Clear caplog in Ecovacs tests (#155404) 2025-10-29 14:33:43 +01:00
Jan-Philipp Benecke dbda31f6d5 Attach Ping device tracker to Ping device (#155399) 2025-10-29 14:31:51 +01:00
Retha Runolfsson 24219dd8f7 Bump pySwitchbot to 0.72.1 (#155415) 2025-10-29 14:22:02 +01:00
adam-the-hero 77d0cf1573 Update Watergate dependency to 2025.1.0 (#155393)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-10-29 14:21:19 +01:00
Artur Pragacz 1ea534e400 Remove legacy platform support from translations (#155178) 2025-10-29 14:16:57 +01:00
epenet a6ba8fa69c Add support for translation_placeholders in zha (#155254) 2025-10-29 14:08:04 +01:00
Michael a6c1ce86d8 Remove neato integration (#154902) 2025-10-29 14:05:59 +01:00
puddly fbb07e16cb Auto refresh hardware integration firmware update entities on setup (#154562) 2025-10-29 13:33:34 +01:00
Shay Levy 1387308f48 Update Switcher actions exceptions (#155296) 2025-10-29 14:32:10 +02:00
epenet 48d371eddb Use runtime_data in sfr_box (#155410) 2025-10-29 13:30:32 +01:00
Simone Chemelli c45c11574c Add next alarm/reminder/timer sensors to Alexa Devices (#153576) 2025-10-29 13:11:25 +01:00
Ståle Storø Hauknes 14eb103338 Bump Airthings BLE to 1.2.0 (#155386) 2025-10-29 12:40:00 +01:00
Manu 2bdb258a39 Add image platform to Xbox integration (#155369)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-10-29 12:31:55 +01:00
Simone Chemelli 5b323526b6 Bump aioamazondevices to 6.5.5 (#155408) 2025-10-29 12:31:30 +01:00
TheJulianJES 9d434c9403 Bump ZHA to 0.0.75 (#155389) 2025-10-29 11:17:19 +00:00
epenet e4103137ef Add sensors for Tuya cat toilet (#155245) 2025-10-29 11:50:38 +01:00
Jan-Philipp Benecke d9d4cc9004 Use a config entry migration instead of migrating in async_setup in Ping (#155403)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-29 11:19:23 +01:00
Ludovic BOUÉ 67baa2c737 Add Matter Aqara Floor Heating Thermostat W500 fixture (#155396) 2025-10-29 10:41:21 +01:00
Erwin Douna f9c504fcde Bump pyportainer 1.0.11 (#155394) 2025-10-29 10:39:45 +01:00
wollew 4b25d04326 Refactor Velux integration to use runtime_data (#155207) 2025-10-29 08:42:02 +01:00
J. Nick Koston 4e3eb44e69 Bump aioesphomeapi to 42.4.0 (#155383) 2025-10-29 09:37:38 +02:00
Jan-Philipp Benecke 6c84d25024 Fix device identifiers in ping and add migration (#155343) 2025-10-29 08:31:18 +01:00
Shay Levy c4dc4135e1 Add translation for Shelly Fifth button (#155377) 2025-10-29 08:30:24 +01:00
Michelle "MishManners®™" Duke 78bbdf108b Spelling error found in strings.json for Rainmachine (#155381) 2025-10-29 08:28:14 +01:00
Oliver 47397fd736 Update denonavr to 1.2.0 (#155385) 2025-10-29 08:27:37 +01:00
J. Nick Koston 2b62d2d636 Fix flakey ecovacs tests (#155387) 2025-10-29 08:26:27 +01:00
Petro31 350f99baab Remove indents and decrease long string in template config file (#155340) 2025-10-29 07:54:59 +01:00
J. Nick Koston 1245385371 Bump aiohttp to 3.13.2 (#155372) 2025-10-28 19:09:27 -05:00
eliasubz c86852eb21 Move URL out of xiaomi_miio strings.json (#155357)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-10-28 16:59:23 -07:00
Thomas55555 ad635d2eff Bump aioautomower to 2.7.0 (#155363) 2025-10-28 16:07:10 -07:00
G Johansson cf0e2b85dd Bump psutil to 7.1.2 (#155368) 2025-10-28 16:07:00 -07:00
Michael Hansen b9e7f1c628 Bump intents and fix for api change (#155374) 2025-10-28 16:06:33 -07:00
Erwin Douna 079d65acea Portainer add reconfigure flow (#155289) 2025-10-28 16:03:24 -07:00
Jordan Harvey 162737a473 Add actions for Nintendo Parental Controls (#154886) 2025-10-28 15:59:15 -07:00
Manu d074c5b7c8 Fix browse media in Xbox integration (#155376) 2025-10-29 00:37:42 +02:00
Mike Degatano d6ae0c142e Refactor diagnostics, create backup and green/yellow settings from handler (#154098)
Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-10-28 21:46:06 +01:00
Willem-Jan van Rootselaar 58182a344d Reduce API calls in BSBlan (#152704)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-10-28 13:43:45 -07:00
Kira 1a1f3d6b4e Handle new Blink login flow (#154632)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-10-28 13:43:32 -07:00
RvV1979 71589d212f Add "Intelligent" program to Home Connect (#155243) 2025-10-28 13:10:24 -07:00
Abílio Costa 9364a40fd2 Bump fastdotcom to 0.0.6 (#155354) 2025-10-28 21:08:19 +01:00
Oliver Gründel 7ead8f9154 Change rain count state_class to 'Total' (ecowitt) (#155358) 2025-10-28 21:07:31 +01:00
Erwin Douna 09ac47b35f Portainer add dynamic devices (#155304)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-28 20:57:28 +01:00
Joris Pelgröm 404393d6fe Bump letpot to 0.6.3 (#155356) 2025-10-28 19:18:27 +00:00
Joakim Sørensen de5a26830d Add api_server option to cloud (#155337)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-28 19:56:30 +01:00
epenet c0b0ce0c16 Bump sfrbox-api to 0.1.0 (#155349) 2025-10-28 20:49:23 +02:00
Andrew Jackson 88e27d9017 Add integration type, descriptions and selector options to Transmission strings (#155201)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-28 18:48:33 +00:00
Erwin Douna a37ba6dba4 Portainer remove unnecessary patch (#155317) 2025-10-28 18:39:08 +00:00
Manu f38c0d510e Add new sensor and attributes to Xbox integration (#155098) 2025-10-28 18:00:45 +01:00
Andrew Jackson be9fa9a606 Fix Transmission Action Add Torrent (#155350) 2025-10-28 17:44:32 +01:00
epenet 2bc6e728a3 Log exception details in sfr_box config flow (#155351) 2025-10-28 17:42:40 +01:00
J. Nick Koston 4e4a0d1e28 Bump bluetooth-data-tools to 1.28.4 (#155342) 2025-10-28 17:24:27 +01:00
Robert Resch c860aa1531 Show diff on pre-commit CI jobs (#155345)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-10-28 16:45:11 +01:00
Robert Resch 39c73cbbbd Fix CI by sorting telegram_bot files (#155346) 2025-10-28 10:40:39 -05:00
hanwg ca7332f597 Add event entity for Telegram bot (#154383) 2025-10-28 15:18:26 +01:00
Artur Pragacz eafedeb12a Add more information to music assistant get_queue (#155242) 2025-10-28 15:16:01 +01:00
Luca Angemi ce93de7fc6 Add google sheet get service (#150133)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-10-28 14:21:51 +01:00
steinmn 03f339b3a3 Fix Translation error in Home Connect "Add application credentials"-step (#155233) 2025-10-28 14:13:55 +01:00
Allen Porter 6cfeeea1ba Bump python-roborock to 3.7.0 (#155336) 2025-10-28 14:09:11 +01:00
Robert Resch ccbdaabe74 Add some Ecovacs lifespans entities (#155238) 2025-10-28 13:22:40 +01:00
puddly dd22c78d11 Migrate ZHA config entries to derive unique_id from the Zigbee EPID (#154489) 2025-10-28 13:11:42 +01:00
WardZhou 1a732accdd Add support for Thread Integration to Display Icons for IKEA TBRs (#155299) 2025-10-28 13:01:58 +01:00
Erwin Douna 59d663ee6e Add integration type to DSMR Reader (#155325) 2025-10-28 12:44:38 +01:00
Erwin Douna 2442a96c27 Portainer add integration type (#155324) 2025-10-28 12:44:06 +01:00
Erwin Douna f69de99501 Add integration type to tado (#155327) 2025-10-28 12:43:23 +01:00
Brett Adams 8ce9238f7a Handle cpd_enabled error in Tessie (#155322) 2025-10-28 12:42:53 +01:00
OzGav 2fe697486d Fix volume level of Music Assistant group players (#155259)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-10-28 12:41:35 +01:00
Erwin Douna 0bd25dc254 Add integration type to downloader (#155328) 2025-10-28 12:40:46 +01:00
Erwin Douna ed6af953af Add integration type to melcloud (#155330) 2025-10-28 12:39:04 +01:00
Erwin Douna 84f65c3f77 Add integration type to fastdotcom (#155329) 2025-10-28 12:37:41 +01:00
Erwin Douna 77c024fcdd SMA add integration type (#155323) 2025-10-28 12:44:38 +02:00
Shay Levy 27570138e7 Fix Switcher ConfigEntry typing (#155320) 2025-10-28 10:34:51 +01:00
Robert Resch 96f84b2b99 Sort homeassistant json files (#155285) 2025-10-28 10:33:10 +01:00
Sab44 28bee6d1aa Fix unique IDs and migrate v1 entries (#155319) 2025-10-28 10:07:37 +01:00
Mike Degatano c9d68ddd5c Add progress reporting for addon and core update entities (#153268)
Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-10-28 08:54:02 +01:00
Fredrik Erlandsson ac6dddc895 Daikin improve config flow dialog message (#155202)
Co-authored-by: Dave T <17680170+davet2001@users.noreply.github.com>
2025-10-28 00:02:15 -07:00
Samuel Xiao f7e5dc7637 Add Presence Sensor support to Switchbot Cloud (#155309) 2025-10-28 07:33:21 +01:00
Michael Hansen 1a5f431485 Bump hassil to 3.3.0 (#155301) 2025-10-28 05:46:04 +01:00
Erwin Douna faa04755e2 Portainer bugfix add button platform (#155305) 2025-10-27 21:53:10 +00:00
Åke Strandberg 76584161a6 Bump pymiele to v0.5.6 (#155266)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-10-27 21:45:28 +00:00
Shay Levy 103b121868 Enhance Switcher config flow tests (#155292) 2025-10-27 20:22:29 +01:00
epenet 76a6b3cea6 Do not exclude "repr" from motionblinds snapshots (#155271) 2025-10-27 20:41:05 +02:00
Michael Hansen 87e7fe6e37 Add custom (external) wake words (#152919) 2025-10-27 11:15:56 -07:00
G Johansson c782489973 Fix Nord Pool sensor resolution for next/previous price (#155119) 2025-10-27 17:32:27 +00:00
Åke Strandberg c9dbc1458c Set icon for myuplink DM sensor (#155274) 2025-10-27 18:17:28 +01:00
Robert Resch d4a33611f0 Bump prettier to 3.6.2 (#155281) 2025-10-27 18:16:13 +01:00
mkmer f028b7ab6e Bump AIOSomecomfort to 0.0.35 (#155265) 2025-10-27 18:13:33 +01:00
J. Diego Rodríguez Royo 86a9df761a Bump aiohomeconnect to version 0.23.0 (#155269) 2025-10-27 18:10:28 +01:00
G Johansson d5c244395c Fix reproduce state 2025-08-03 10:31:23 +00:00
G Johansson eeaa7dfb4d Add to demo 2025-08-03 10:31:23 +00:00
G Johansson 6c64615e0f Add tests 2025-08-03 10:31:23 +00:00
G Johansson 7379de033f Add target temp range to water_heater 2025-08-03 10:31:23 +00:00
3038 changed files with 195351 additions and 90972 deletions
+9 -51
View File
@@ -27,7 +27,7 @@ jobs:
publish: ${{ steps.version.outputs.publish }}
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
fetch-depth: 0
@@ -90,7 +90,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
@@ -162,18 +162,6 @@ jobs:
sed -i "s|home-assistant-intents==.*||" requirements_all.txt
fi
- name: Adjustments for armhf
if: matrix.arch == 'armhf'
run: |
# Pandas has issues building on armhf, it is expected they
# will drop the platform in the near future (they consider it
# "flimsy" on 386). The following packages depend on pandas,
# so we comment them out.
sed -i "s|env-canada|# env-canada|g" requirements_all.txt
sed -i "s|noaa-coops|# noaa-coops|g" requirements_all.txt
sed -i "s|pyezviz|# pyezviz|g" requirements_all.txt
sed -i "s|pykrakenapi|# pykrakenapi|g" requirements_all.txt
- name: Download translations
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
@@ -226,24 +214,16 @@ jobs:
- odroid-c4
- odroid-m1
- odroid-n2
- odroid-xu
- qemuarm
- qemuarm-64
- qemux86
- qemux86-64
- raspberrypi
- raspberrypi2
- raspberrypi3
- raspberrypi3-64
- raspberrypi4
- raspberrypi4-64
- raspberrypi5-64
- tinker
- yellow
- green
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set build additional args
run: |
@@ -281,7 +261,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
@@ -297,6 +277,7 @@ jobs:
key-description: "Home Assistant Core"
version: ${{ needs.init.outputs.version }}
channel: ${{ needs.init.outputs.channel }}
exclude-list: '["odroid-xu","qemuarm","qemux86","raspberrypi","raspberrypi2","raspberrypi3","raspberrypi4","tinker"]'
- name: Update version file (stable -> beta)
if: needs.init.outputs.channel == 'stable'
@@ -306,6 +287,7 @@ jobs:
key-description: "Home Assistant Core"
version: ${{ needs.init.outputs.version }}
channel: beta
exclude-list: '["odroid-xu","qemuarm","qemux86","raspberrypi","raspberrypi2","raspberrypi3","raspberrypi4","tinker"]'
publish_container:
name: Publish meta container for ${{ matrix.registry }}
@@ -323,7 +305,7 @@ jobs:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
@@ -357,27 +339,12 @@ jobs:
docker manifest create "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \
"${registry}/i386-homeassistant:${tag_r}" \
"${registry}/armhf-homeassistant:${tag_r}" \
"${registry}/armv7-homeassistant:${tag_r}" \
"${registry}/aarch64-homeassistant:${tag_r}"
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/amd64-homeassistant:${tag_r}" \
--os linux --arch amd64
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/i386-homeassistant:${tag_r}" \
--os linux --arch 386
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/armhf-homeassistant:${tag_r}" \
--os linux --arch arm --variant=v6
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/armv7-homeassistant:${tag_r}" \
--os linux --arch arm --variant=v7
docker manifest annotate "${registry}/home-assistant:${tag_l}" \
"${registry}/aarch64-homeassistant:${tag_r}" \
--os linux --arch arm64 --variant=v8
@@ -405,23 +372,14 @@ jobs:
# Pull images from github container registry and verify signature
docker pull "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/i386-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/armhf-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/armv7-homeassistant:${{ needs.init.outputs.version }}"
docker pull "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/amd64-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/i386-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/armhf-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/armv7-homeassistant:${{ needs.init.outputs.version }}"
validate_image "ghcr.io/home-assistant/aarch64-homeassistant:${{ needs.init.outputs.version }}"
if [[ "${{ matrix.registry }}" == "docker.io/homeassistant" ]]; then
# Upload images to dockerhub
push_dockerhub "amd64-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "i386-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "armhf-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "armv7-homeassistant" "${{ needs.init.outputs.version }}"
push_dockerhub "aarch64-homeassistant" "${{ needs.init.outputs.version }}"
fi
@@ -456,7 +414,7 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
@@ -501,7 +459,7 @@ jobs:
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+9 -13
View File
@@ -37,10 +37,10 @@ on:
type: boolean
env:
CACHE_VERSION: 1
CACHE_VERSION: 2
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2025.11"
HA_SHORT_VERSION: "2025.12"
DEFAULT_PYTHON: "3.13"
ALL_PYTHON_VERSIONS: "['3.13', '3.14']"
# 10.3 is the oldest supported version
@@ -99,7 +99,7 @@ jobs:
steps:
- &checkout
name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: |
@@ -364,13 +364,13 @@ jobs:
- name: Run check-json
run: |
. venv/bin/activate
pre-commit run --hook-stage manual check-json --all-files
pre-commit run --hook-stage manual check-json --all-files --show-diff-on-failure
- name: Run prettier (fully)
if: needs.info.outputs.test_full_suite == 'true'
run: |
. venv/bin/activate
pre-commit run --hook-stage manual prettier --all-files
pre-commit run --hook-stage manual prettier --all-files --show-diff-on-failure
- name: Run prettier (partially)
if: needs.info.outputs.test_full_suite == 'false'
@@ -378,7 +378,7 @@ jobs:
run: |
. venv/bin/activate
shopt -s globstar
pre-commit run --hook-stage manual prettier --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*}
pre-commit run --hook-stage manual prettier --show-diff-on-failure --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*}
- name: Register check executables problem matcher
run: |
@@ -386,7 +386,7 @@ jobs:
- name: Run executables check
run: |
. venv/bin/activate
pre-commit run --hook-stage manual check-executables-have-shebangs --all-files
pre-commit run --hook-stage manual check-executables-have-shebangs --all-files --show-diff-on-failure
- name: Register codespell problem matcher
run: |
@@ -502,7 +502,6 @@ jobs:
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libgammu-dev \
libswresample-dev \
libswscale-dev \
libudev-dev
@@ -623,7 +622,7 @@ jobs:
steps:
- *checkout
- name: Dependency review
uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4.8.1
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
with:
license-check: false # We use our own license audit checks
@@ -801,8 +800,7 @@ jobs:
-o Dir::State::Lists=${{ env.APT_LIST_CACHE_DIR }} \
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev
libturbojpeg
- *checkout
- *setup-python-default
- *cache-restore-python-default
@@ -853,7 +851,6 @@ jobs:
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev \
libxml2-utils
- *checkout
- *setup-python-matrix
@@ -1233,7 +1230,6 @@ jobs:
bluez \
ffmpeg \
libturbojpeg \
libgammu-dev \
libxml2-utils
- *checkout
- *setup-python-matrix
+3 -3
View File
@@ -21,14 +21,14 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Initialize CodeQL
uses: github/codeql-action/init@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v4.31.0
uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v4.31.0
uses: github/codeql-action/analyze@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
with:
category: "/language:python"
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
+3 -39
View File
@@ -33,7 +33,7 @@ jobs:
steps:
- &checkout
name: Checkout the repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
@@ -77,20 +77,8 @@ jobs:
# Use C-Extension for SQLAlchemy
echo "REQUIRE_SQLALCHEMY_CEXT=1"
# Add additional pip wheel build constraints
echo "PIP_CONSTRAINT=build_constraints.txt"
) > .env_file
- name: Write pip wheel build constraints
run: |
(
# ninja 1.11.1.2 + 1.11.1.3 seem to be broken on at least armhf
# this caused the numpy builds to fail
# https://github.com/scikit-build/ninja-python-distributions/issues/274
echo "ninja==1.11.1.1"
) > build_constraints.txt
- name: Upload env_file
uses: &actions-upload-artifact actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
@@ -99,13 +87,6 @@ jobs:
include-hidden-files: true
overwrite: true
- name: Upload build_constraints
uses: *actions-upload-artifact
with:
name: build_constraints
path: ./build_constraints.txt
overwrite: true
- name: Upload requirements_diff
uses: *actions-upload-artifact
with:
@@ -138,13 +119,6 @@ jobs:
- os: ubuntu-latest
- arch: aarch64
os: ubuntu-24.04-arm
exclude:
- abi: cp314
arch: armv7
- abi: cp314
arch: armhf
- abi: cp314
arch: i386
steps:
- *checkout
@@ -154,12 +128,6 @@ jobs:
with:
name: env_file
- &download-build-constraints
name: Download build_constraints
uses: *actions-download-artifact
with:
name: build_constraints
- &download-requirements-diff
name: Download requirements_diff
uses: *actions-download-artifact
@@ -199,7 +167,7 @@ jobs:
- *checkout
- *download-env-file
- *download-build-constraints
- *download-requirements-diff
- name: Download requirements_all_wheels
@@ -209,10 +177,6 @@ jobs:
- name: Adjust build env
run: |
if [ "${{ matrix.arch }}" = "i386" ]; then
echo "NPY_DISABLE_SVML=1" >> .env_file
fi
# Do not pin numpy in wheels building
sed -i "/numpy/d" homeassistant/package_constraints.txt
# Don't build wheels for uv as uv requires a greater version of rust as currently available on alpine
@@ -228,7 +192,7 @@ jobs:
arch: ${{ matrix.arch }}
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-ng-dev"
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-ng-dev"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
+6 -3
View File
@@ -33,10 +33,13 @@ repos:
rev: v1.37.1
hooks:
- id: yamllint
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.3
- repo: https://github.com/rbubley/mirrors-prettier
rev: v3.6.2
hooks:
- id: prettier
additional_dependencies:
- prettier@3.6.2
- prettier-plugin-sort-json@4.1.1
- repo: https://github.com/cdce8p/python-typing-update
rev: v0.6.0
hooks:
@@ -84,7 +87,7 @@ repos:
pass_filenames: false
language: script
types: [text]
files: ^(homeassistant/.+/(icons|manifest|strings)\.json|homeassistant/.+/(quality_scale)\.yaml|homeassistant/brands/.*\.json|homeassistant/.+/services\.yaml|script/hassfest/(?!metadata|mypy_config).+\.py|requirements.+\.txt)$
files: ^(homeassistant/.+/(icons|manifest|strings)\.json|homeassistant/.+/(conditions|quality_scale|services|triggers)\.yaml|homeassistant/brands/.*\.json|script/hassfest/(?!metadata|mypy_config).+\.py|requirements.+\.txt)$
- id: hassfest-metadata
name: hassfest-metadata
entry: script/run-in-env.sh python3 -m script.hassfest -p metadata,docker
+24
View File
@@ -0,0 +1,24 @@
/** @type {import("prettier").Config} */
module.exports = {
overrides: [
{
files: "./homeassistant/**/*.json",
options: {
plugins: [require.resolve("prettier-plugin-sort-json")],
jsonRecursiveSort: true,
jsonSortOrder: JSON.stringify({ [/.*/]: "numeric" }),
},
},
{
files: ["manifest.json", "./**/brands/*.json"],
options: {
// domain and name should stay at the top
jsonSortOrder: JSON.stringify({
domain: null,
name: null,
[/.*/]: "numeric",
}),
},
},
],
};
+3 -1
View File
@@ -107,6 +107,7 @@ homeassistant.components.automation.*
homeassistant.components.awair.*
homeassistant.components.axis.*
homeassistant.components.azure_storage.*
homeassistant.components.backblaze_b2.*
homeassistant.components.backup.*
homeassistant.components.baf.*
homeassistant.components.bang_olufsen.*
@@ -230,6 +231,7 @@ homeassistant.components.google_cloud.*
homeassistant.components.google_drive.*
homeassistant.components.google_photos.*
homeassistant.components.google_sheets.*
homeassistant.components.google_weather.*
homeassistant.components.govee_ble.*
homeassistant.components.gpsd.*
homeassistant.components.greeneye_monitor.*
@@ -395,7 +397,6 @@ homeassistant.components.otbr.*
homeassistant.components.overkiz.*
homeassistant.components.overseerr.*
homeassistant.components.p1_monitor.*
homeassistant.components.pandora.*
homeassistant.components.panel_custom.*
homeassistant.components.paperless_ngx.*
homeassistant.components.peblar.*
@@ -578,6 +579,7 @@ homeassistant.components.wiz.*
homeassistant.components.wled.*
homeassistant.components.workday.*
homeassistant.components.worldclock.*
homeassistant.components.xbox.*
homeassistant.components.xiaomi_ble.*
homeassistant.components.yale_smart_alarm.*
homeassistant.components.yalexs_ble.*
+5 -5
View File
@@ -10,16 +10,16 @@
// Pyright is too pedantic for Home Assistant
"python.analysis.typeCheckingMode": "basic",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
"editor.defaultFormatter": "charliermarsh.ruff",
},
"[json][jsonc][yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
},
"json.schemas": [
{
"fileMatch": ["homeassistant/components/*/manifest.json"],
// This value differs between working with devcontainer and locally, therefore this value should NOT be in sync!
"url": "./script/json_schemas/manifest_schema.json"
}
]
"url": "./script/json_schemas/manifest_schema.json",
},
],
}
Generated
+20 -14
View File
@@ -196,6 +196,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/azure_service_bus/ @hfurubotten
/homeassistant/components/azure_storage/ @zweckj
/tests/components/azure_storage/ @zweckj
/homeassistant/components/backblaze_b2/ @hugo-vrijswijk @ElCruncharino
/tests/components/backblaze_b2/ @hugo-vrijswijk @ElCruncharino
/homeassistant/components/backup/ @home-assistant/core
/tests/components/backup/ @home-assistant/core
/homeassistant/components/baf/ @bdraco @jfroy
@@ -316,8 +318,6 @@ build.json @home-assistant/supervisor
/tests/components/cpuspeed/ @fabaff
/homeassistant/components/crownstone/ @Crownstone @RicArch97
/tests/components/crownstone/ @Crownstone @RicArch97
/homeassistant/components/cups/ @fabaff
/tests/components/cups/ @fabaff
/homeassistant/components/cync/ @Kinachi249
/tests/components/cync/ @Kinachi249
/homeassistant/components/daikin/ @fredrike
@@ -510,8 +510,6 @@ build.json @home-assistant/supervisor
/tests/components/fjaraskupan/ @elupus
/homeassistant/components/flexit_bacnet/ @lellky @piotrbulinski
/tests/components/flexit_bacnet/ @lellky @piotrbulinski
/homeassistant/components/flick_electric/ @ZephireNZ
/tests/components/flick_electric/ @ZephireNZ
/homeassistant/components/flipr/ @cnico
/tests/components/flipr/ @cnico
/homeassistant/components/flo/ @dmulcahey
@@ -609,6 +607,8 @@ build.json @home-assistant/supervisor
/tests/components/google_tasks/ @allenporter
/homeassistant/components/google_travel_time/ @eifinger
/tests/components/google_travel_time/ @eifinger
/homeassistant/components/google_weather/ @tronikos
/tests/components/google_weather/ @tronikos
/homeassistant/components/govee_ble/ @bdraco
/tests/components/govee_ble/ @bdraco
/homeassistant/components/govee_light_local/ @Galorhallen
@@ -627,6 +627,8 @@ build.json @home-assistant/supervisor
/tests/components/guardian/ @bachya
/homeassistant/components/habitica/ @tr4nt0r
/tests/components/habitica/ @tr4nt0r
/homeassistant/components/hanna/ @bestycame
/tests/components/hanna/ @bestycame
/homeassistant/components/hardkernel/ @home-assistant/core
/tests/components/hardkernel/ @home-assistant/core
/homeassistant/components/hardware/ @home-assistant/core
@@ -846,6 +848,8 @@ build.json @home-assistant/supervisor
/tests/components/kraken/ @eifinger
/homeassistant/components/kulersky/ @emlove
/tests/components/kulersky/ @emlove
/homeassistant/components/labs/ @home-assistant/core
/tests/components/labs/ @home-assistant/core
/homeassistant/components/lacrosse_view/ @IceBotYT
/tests/components/lacrosse_view/ @IceBotYT
/homeassistant/components/lamarzocco/ @zweckj
@@ -1019,8 +1023,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/msteams/ @peroyvind
/homeassistant/components/mullvad/ @meichthys
/tests/components/mullvad/ @meichthys
/homeassistant/components/music_assistant/ @music-assistant
/tests/components/music_assistant/ @music-assistant
/homeassistant/components/music_assistant/ @music-assistant @arturpragacz
/tests/components/music_assistant/ @music-assistant @arturpragacz
/homeassistant/components/mutesync/ @currentoor
/tests/components/mutesync/ @currentoor
/homeassistant/components/my/ @home-assistant/core
@@ -1376,6 +1380,8 @@ build.json @home-assistant/supervisor
/tests/components/sanix/ @tomaszsluszniak
/homeassistant/components/satel_integra/ @Tommatheussen
/tests/components/satel_integra/ @Tommatheussen
/homeassistant/components/saunum/ @mettolen
/tests/components/saunum/ @mettolen
/homeassistant/components/scene/ @home-assistant/core
/tests/components/scene/ @home-assistant/core
/homeassistant/components/schedule/ @home-assistant/core
@@ -1479,8 +1485,6 @@ build.json @home-assistant/supervisor
/tests/components/smhi/ @gjohansson-ST
/homeassistant/components/smlight/ @tl-sl
/tests/components/smlight/ @tl-sl
/homeassistant/components/sms/ @ocalvo
/tests/components/sms/ @ocalvo
/homeassistant/components/snapcast/ @luar123
/tests/components/snapcast/ @luar123
/homeassistant/components/snmp/ @nmaggioni
@@ -1543,8 +1547,8 @@ build.json @home-assistant/supervisor
/tests/components/suez_water/ @ooii @jb101010-2
/homeassistant/components/sun/ @home-assistant/core
/tests/components/sun/ @home-assistant/core
/homeassistant/components/sunricher_dali_center/ @niracler
/tests/components/sunricher_dali_center/ @niracler
/homeassistant/components/sunricher_dali/ @niracler
/tests/components/sunricher_dali/ @niracler
/homeassistant/components/supla/ @mwegrzynek
/homeassistant/components/surepetcare/ @benleb @danielhiversen
/tests/components/surepetcare/ @benleb @danielhiversen
@@ -1721,8 +1725,8 @@ build.json @home-assistant/supervisor
/tests/components/vallox/ @andre-richter @slovdahl @viiru- @yozik04
/homeassistant/components/valve/ @home-assistant/core
/tests/components/valve/ @home-assistant/core
/homeassistant/components/vegehub/ @ghowevege
/tests/components/vegehub/ @ghowevege
/homeassistant/components/vegehub/ @thulrus
/tests/components/vegehub/ @thulrus
/homeassistant/components/velbus/ @Cereal2nd @brefra
/tests/components/velbus/ @Cereal2nd @brefra
/homeassistant/components/velux/ @Julius2342 @DeerMaximum @pawlizio @wollew
@@ -1736,6 +1740,8 @@ build.json @home-assistant/supervisor
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja @iprak @sapuseven
/homeassistant/components/vicare/ @CFenner
/tests/components/vicare/ @CFenner
/homeassistant/components/victron_ble/ @rajlaud
/tests/components/victron_ble/ @rajlaud
/homeassistant/components/victron_remote_monitoring/ @AndyTempel
/tests/components/victron_remote_monitoring/ @AndyTempel
/homeassistant/components/vilfo/ @ManneW
@@ -1821,8 +1827,8 @@ build.json @home-assistant/supervisor
/tests/components/ws66i/ @ssaenger
/homeassistant/components/wyoming/ @synesthesiam
/tests/components/wyoming/ @synesthesiam
/homeassistant/components/xbox/ @hunterjm
/tests/components/xbox/ @hunterjm
/homeassistant/components/xbox/ @hunterjm @tr4nt0r
/tests/components/xbox/ @hunterjm @tr4nt0r
/homeassistant/components/xiaomi_aqara/ @danielhiversen @syssi
/tests/components/xiaomi_aqara/ @danielhiversen @syssi
/homeassistant/components/xiaomi_ble/ @Jc2k @Ernst79
Generated
+2 -4
View File
@@ -21,17 +21,15 @@ ARG BUILD_ARCH
RUN \
case "${BUILD_ARCH}" in \
"aarch64") go2rtc_suffix='arm64' ;; \
"armhf") go2rtc_suffix='armv6' ;; \
"armv7") go2rtc_suffix='arm' ;; \
*) go2rtc_suffix=${BUILD_ARCH} ;; \
esac \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.11/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.12/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& chmod +x /bin/go2rtc \
# Verify go2rtc can be executed
&& go2rtc --version
# Install uv
RUN pip3 install uv==0.9.5
RUN pip3 install uv==0.9.6
WORKDIR /usr/src
-1
View File
@@ -13,7 +13,6 @@ RUN \
libavcodec-dev \
libavdevice-dev \
libavutil-dev \
libgammu-dev \
libswscale-dev \
libswresample-dev \
libavfilter-dev \
+2 -5
View File
@@ -1,10 +1,7 @@
image: ghcr.io/home-assistant/{arch}-homeassistant
build_from:
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2025.10.1
armhf: ghcr.io/home-assistant/armhf-homeassistant-base:2025.10.1
armv7: ghcr.io/home-assistant/armv7-homeassistant-base:2025.10.1
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2025.10.1
i386: ghcr.io/home-assistant/i386-homeassistant-base:2025.10.1
aarch64: ghcr.io/home-assistant/aarch64-homeassistant-base:2025.11.0
amd64: ghcr.io/home-assistant/amd64-homeassistant-base:2025.11.0
cosign:
base_identity: https://github.com/home-assistant/docker/.*
identity: https://github.com/home-assistant/core/.*
+7 -7
View File
@@ -6,7 +6,6 @@ Sending HOTP through notify service
from __future__ import annotations
import asyncio
from collections import OrderedDict
import logging
from typing import Any, cast
@@ -304,14 +303,15 @@ class NotifySetupFlow(SetupFlow[NotifyAuthModule]):
if not self._available_notify_services:
return self.async_abort(reason="no_available_service")
schema: dict[str, Any] = OrderedDict()
schema["notify_service"] = vol.In(self._available_notify_services)
schema["target"] = vol.Optional(str)
return self.async_show_form(
step_id="init", data_schema=vol.Schema(schema), errors=errors
schema = vol.Schema(
{
vol.Required("notify_service"): vol.In(self._available_notify_services),
vol.Optional("target"): str,
}
)
return self.async_show_form(step_id="init", data_schema=schema, errors=errors)
async def async_step_setup(
self, user_input: dict[str, str] | None = None
) -> FlowResult:
@@ -179,12 +179,18 @@ class Data:
user_hash = base64.b64decode(found["password"])
# bcrypt.checkpw is timing-safe
if not bcrypt.checkpw(password.encode(), user_hash):
# With bcrypt 5.0 passing a password longer than 72 bytes raises a ValueError.
# Previously the password was silently truncated.
# https://github.com/pyca/bcrypt/pull/1000
if not bcrypt.checkpw(password.encode()[:72], user_hash):
raise InvalidAuth
def hash_password(self, password: str, for_storage: bool = False) -> bytes:
"""Encode a password."""
hashed: bytes = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# With bcrypt 5.0 passing a password longer than 72 bytes raises a ValueError.
# Previously the password was silently truncated.
# https://github.com/pyca/bcrypt/pull/1000
hashed: bytes = bcrypt.hashpw(password.encode()[:72], bcrypt.gensalt(rounds=12))
if for_storage:
hashed = base64.b64encode(hashed)
+3
View File
@@ -176,6 +176,8 @@ FRONTEND_INTEGRATIONS = {
STAGE_0_INTEGRATIONS = (
# Load logging and http deps as soon as possible
("logging, http deps", LOGGING_AND_HTTP_DEPS_INTEGRATIONS, None),
# Setup labs for preview features
("labs", {"labs"}, STAGE_0_SUBSTAGE_TIMEOUT),
# Setup frontend
("frontend", FRONTEND_INTEGRATIONS, None),
# Setup recorder
@@ -212,6 +214,7 @@ DEFAULT_INTEGRATIONS = {
"backup",
"frontend",
"hardware",
"labs",
"logger",
"network",
"system_health",
+1
View File
@@ -15,6 +15,7 @@
"google_tasks",
"google_translate",
"google_travel_time",
"google_weather",
"google_wifi",
"google",
"nest",
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "victron",
"name": "Victron",
"integrations": ["victron_ble", "victron_remote_monitoring"]
}
+2 -8
View File
@@ -1,11 +1,5 @@
{
"domain": "yale",
"name": "Yale",
"integrations": [
"august",
"yale_smart_alarm",
"yalexs_ble",
"yale_home",
"yale"
]
"name": "Yale (non-US/Canada)",
"integrations": ["yale", "yalexs_ble", "yale_smart_alarm"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "yale_august",
"name": "Yale August (US/Canada)",
"integrations": ["august", "august_ble"]
}
+41 -41
View File
@@ -1,70 +1,70 @@
{
"config": {
"step": {
"user": {
"title": "Fill in your Abode login information",
"data": {
"username": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
}
},
"mfa": {
"title": "Enter your MFA code for Abode",
"data": {
"mfa_code": "MFA code (6-digits)"
}
},
"reauth_confirm": {
"title": "[%key:component::abode::config::step::user::title%]",
"data": {
"username": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
}
}
},
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_mfa_code": "Invalid MFA code"
},
"abort": {
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"invalid_mfa_code": "Invalid MFA code"
},
"step": {
"mfa": {
"data": {
"mfa_code": "MFA code (6-digits)"
},
"title": "Enter your MFA code for Abode"
},
"reauth_confirm": {
"data": {
"password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::email%]"
},
"title": "[%key:component::abode::config::step::user::title%]"
},
"user": {
"data": {
"password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::email%]"
},
"title": "Fill in your Abode login information"
}
}
},
"services": {
"capture_image": {
"name": "Capture image",
"description": "Requests a new image capture from a camera device.",
"fields": {
"entity_id": {
"name": "Entity",
"description": "Entity ID of the camera to request an image from."
"description": "Entity ID of the camera to request an image from.",
"name": "Entity"
}
}
},
"name": "Capture image"
},
"change_setting": {
"name": "Change setting",
"description": "Changes an Abode system setting.",
"fields": {
"setting": {
"name": "Setting",
"description": "Setting to change."
"description": "Setting to change.",
"name": "Setting"
},
"value": {
"name": "Value",
"description": "Value of the setting."
"description": "Value of the setting.",
"name": "Value"
}
}
},
"name": "Change setting"
},
"trigger_automation": {
"name": "Trigger automation",
"description": "Triggers an Abode automation.",
"fields": {
"entity_id": {
"name": "Entity",
"description": "Entity ID of the automation to trigger."
"description": "Entity ID of the automation to trigger.",
"name": "Entity"
}
}
},
"name": "Trigger automation"
}
}
}
+5 -5
View File
@@ -4,20 +4,20 @@
"timer_running": {
"default": "mdi:timer",
"state": {
"on": "mdi:timer-play",
"off": "mdi:timer-off"
"off": "mdi:timer-off",
"on": "mdi:timer-play"
}
}
},
"button": {
"tare": {
"default": "mdi:scale-balance"
},
"reset_timer": {
"default": "mdi:timer-refresh"
},
"start_stop": {
"default": "mdi:timer-play"
},
"tare": {
"default": "mdi:scale-balance"
}
}
}
+6 -6
View File
@@ -1,6 +1,5 @@
{
"config": {
"flow_title": "{name}",
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
@@ -10,18 +9,19 @@
"device_not_found": "Device could not be found.",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"flow_title": "{name}",
"step": {
"bluetooth_confirm": {
"description": "[%key:component::bluetooth::config::step::bluetooth_confirm::description%]"
},
"user": {
"description": "[%key:component::bluetooth::config::step::user::description%]",
"data": {
"address": "[%key:common::config_flow::data::device%]"
},
"data_description": {
"address": "Select Acaia scale you want to set up"
}
},
"description": "[%key:component::bluetooth::config::step::user::description%]"
}
}
},
@@ -32,14 +32,14 @@
}
},
"button": {
"tare": {
"name": "Tare"
},
"reset_timer": {
"name": "Reset timer"
},
"start_stop": {
"name": "Start/stop timer"
},
"tare": {
"name": "Tare"
}
}
}
@@ -1,25 +1,8 @@
{
"config": {
"step": {
"user": {
"data": {
"name": "[%key:common::config_flow::data::name%]",
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]"
},
"data_description": {
"api_key": "API key generated in the AccuWeather APIs portal."
}
},
"reauth_confirm": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]"
},
"data_description": {
"api_key": "[%key:component::accuweather::config::step::user::data_description::api_key%]"
}
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"create_entry": {
"default": "Some sensors are not enabled by default. You can enable them in the entity registry after the integration configuration."
@@ -29,9 +12,26 @@
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"requests_exceeded": "The allowed number of requests to the AccuWeather API has been exceeded. You have to wait or change the API key."
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
"step": {
"reauth_confirm": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]"
},
"data_description": {
"api_key": "[%key:component::accuweather::config::step::user::data_description::api_key%]"
}
},
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]",
"name": "[%key:common::config_flow::data::name%]"
},
"data_description": {
"api_key": "API key generated in the AccuWeather APIs portal."
}
}
}
},
"entity": {
@@ -120,9 +120,9 @@
"pressure_tendency": {
"name": "Pressure tendency",
"state": {
"steady": "Steady",
"falling": "Falling",
"rising": "Rising",
"falling": "Falling"
"steady": "Steady"
},
"state_attributes": {
"options": {
@@ -227,9 +227,6 @@
"wet_bulb_temperature": {
"name": "Wet bulb temperature"
},
"wind_speed": {
"name": "[%key:component::weather::entity_component::_::state_attributes::wind_speed::name%]"
},
"wind_chill_temperature": {
"name": "Wind chill temperature"
},
@@ -242,6 +239,9 @@
"wind_gust_speed_night": {
"name": "Wind gust speed night {forecast_day}"
},
"wind_speed": {
"name": "[%key:component::weather::entity_component::_::state_attributes::wind_speed::name%]"
},
"wind_speed_day": {
"name": "Wind speed day {forecast_day}"
},
+8 -8
View File
@@ -1,15 +1,15 @@
{
"config": {
"step": {
"user": {
"title": "Pick a hub to add",
"data": {
"id": "Host ID"
}
}
},
"abort": {
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
},
"step": {
"user": {
"data": {
"id": "Host ID"
},
"title": "Pick a hub to add"
}
}
}
}
@@ -1,10 +1,10 @@
"""The Actron Air integration."""
from actron_neo_api import (
ActronAirNeoACSystem,
ActronNeoAPI,
ActronNeoAPIError,
ActronNeoAuthError,
ActronAirACSystem,
ActronAirAPI,
ActronAirAPIError,
ActronAirAuthError,
)
from homeassistant.const import CONF_API_TOKEN, Platform
@@ -23,16 +23,16 @@ PLATFORM = [Platform.CLIMATE]
async def async_setup_entry(hass: HomeAssistant, entry: ActronAirConfigEntry) -> bool:
"""Set up Actron Air integration from a config entry."""
api = ActronNeoAPI(refresh_token=entry.data[CONF_API_TOKEN])
systems: list[ActronAirNeoACSystem] = []
api = ActronAirAPI(refresh_token=entry.data[CONF_API_TOKEN])
systems: list[ActronAirACSystem] = []
try:
systems = await api.get_ac_systems()
await api.update_status()
except ActronNeoAuthError:
except ActronAirAuthError:
_LOGGER.error("Authentication error while setting up Actron Air integration")
raise
except ActronNeoAPIError as err:
except ActronAirAPIError as err:
_LOGGER.error("API error while setting up Actron Air integration: %s", err)
raise
@@ -2,7 +2,7 @@
from typing import Any
from actron_neo_api import ActronAirNeoStatus, ActronAirNeoZone
from actron_neo_api import ActronAirStatus, ActronAirZone
from homeassistant.components.climate import (
FAN_AUTO,
@@ -132,7 +132,7 @@ class ActronSystemClimate(BaseClimateEntity):
return self._status.max_temp
@property
def _status(self) -> ActronAirNeoStatus:
def _status(self) -> ActronAirStatus:
"""Get the current status from the coordinator."""
return self.coordinator.data
@@ -194,7 +194,7 @@ class ActronZoneClimate(BaseClimateEntity):
def __init__(
self,
coordinator: ActronAirSystemCoordinator,
zone: ActronAirNeoZone,
zone: ActronAirZone,
) -> None:
"""Initialize an Actron Air unit."""
super().__init__(coordinator, zone.title)
@@ -221,7 +221,7 @@ class ActronZoneClimate(BaseClimateEntity):
return self._zone.max_temp
@property
def _zone(self) -> ActronAirNeoZone:
def _zone(self) -> ActronAirZone:
"""Get the current zone data from the coordinator."""
status = self.coordinator.data
return status.zones[self._zone_id]
@@ -3,7 +3,7 @@
import asyncio
from typing import Any
from actron_neo_api import ActronNeoAPI, ActronNeoAuthError
from actron_neo_api import ActronAirAPI, ActronAirAuthError
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_API_TOKEN
@@ -17,7 +17,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
def __init__(self) -> None:
"""Initialize the config flow."""
self._api: ActronNeoAPI | None = None
self._api: ActronAirAPI | None = None
self._device_code: str | None = None
self._user_code: str = ""
self._verification_uri: str = ""
@@ -30,10 +30,10 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle the initial step."""
if self._api is None:
_LOGGER.debug("Initiating device authorization")
self._api = ActronNeoAPI()
self._api = ActronAirAPI()
try:
device_code_response = await self._api.request_device_code()
except ActronNeoAuthError as err:
except ActronAirAuthError as err:
_LOGGER.error("OAuth2 flow failed: %s", err)
return self.async_abort(reason="oauth2_error")
@@ -50,7 +50,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
try:
await self._api.poll_for_token(self._device_code)
_LOGGER.debug("Authorization successful")
except ActronNeoAuthError as ex:
except ActronAirAuthError as ex:
_LOGGER.exception("Error while waiting for device authorization")
raise CannotConnect from ex
@@ -89,7 +89,7 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
try:
user_data = await self._api.get_user_info()
except ActronNeoAuthError as err:
except ActronAirAuthError as err:
_LOGGER.error("Error getting user info: %s", err)
return self.async_abort(reason="oauth2_error")
@@ -5,7 +5,7 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
from actron_neo_api import ActronAirNeoACSystem, ActronAirNeoStatus, ActronNeoAPI
from actron_neo_api import ActronAirACSystem, ActronAirAPI, ActronAirStatus
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@@ -23,7 +23,7 @@ ERROR_UNKNOWN = "unknown_error"
class ActronAirRuntimeData:
"""Runtime data for the Actron Air integration."""
api: ActronNeoAPI
api: ActronAirAPI
system_coordinators: dict[str, ActronAirSystemCoordinator]
@@ -33,15 +33,15 @@ AUTH_ERROR_THRESHOLD = 3
SCAN_INTERVAL = timedelta(seconds=30)
class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirNeoACSystem]):
class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirACSystem]):
"""System coordinator for Actron Air integration."""
def __init__(
self,
hass: HomeAssistant,
entry: ActronAirConfigEntry,
api: ActronNeoAPI,
system: ActronAirNeoACSystem,
api: ActronAirAPI,
system: ActronAirACSystem,
) -> None:
"""Initialize the coordinator."""
super().__init__(
@@ -57,7 +57,7 @@ class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirNeoACSystem]):
self.status = self.api.state_manager.get_status(self.serial_number)
self.last_seen = dt_util.utcnow()
async def _async_update_data(self) -> ActronAirNeoStatus:
async def _async_update_data(self) -> ActronAirStatus:
"""Fetch updates and merge incremental changes into the full state."""
await self.api.update_status()
self.status = self.api.state_manager.get_status(self.serial_number)
@@ -12,5 +12,5 @@
"documentation": "https://www.home-assistant.io/integrations/actron_air",
"iot_class": "cloud_polling",
"quality_scale": "bronze",
"requirements": ["actron-neo-api==0.1.84"]
"requirements": ["actron-neo-api==0.1.87"]
}
@@ -1,29 +1,29 @@
{
"config": {
"step": {
"user": {
"title": "Actron Air OAuth2 Authorization"
},
"timeout": {
"title": "Authorization timeout",
"description": "The authorization process timed out. Please try again.",
"data": {}
},
"connection_error": {
"title": "Connection error",
"description": "Failed to connect to Actron Air. Please check your internet connection and try again.",
"data": {}
}
},
"progress": {
"wait_for_authorization": "To authenticate, open the following URL and login at Actron Air:\n{verification_uri}\nIf the code is not automatically copied, paste the following code to authorize the integration:\n\n```{user_code}```\n\n\nThe login attempt will time out after {expires_minutes} minutes."
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
"oauth2_error": "Failed to start OAuth2 flow"
},
"error": {
"oauth2_error": "Failed to start OAuth2 flow. Please try again later."
},
"abort": {
"oauth2_error": "Failed to start OAuth2 flow",
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
"progress": {
"wait_for_authorization": "To authenticate, open the following URL and login at Actron Air:\n{verification_uri}\nIf the code is not automatically copied, paste the following code to authorize the integration:\n\n```{user_code}```\n\n\nThe login attempt will time out after {expires_minutes} minutes."
},
"step": {
"connection_error": {
"data": {},
"description": "Failed to connect to Actron Air. Please check your internet connection and try again.",
"title": "Connection error"
},
"timeout": {
"data": {},
"description": "The authorization process timed out. Please try again.",
"title": "Authorization timeout"
},
"user": {
"title": "Actron Air OAuth2 Authorization"
}
}
}
}
+14 -1
View File
@@ -17,6 +17,11 @@ from homeassistant.const import (
CONF_UNIQUE_ID,
)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.selector import (
TextSelector,
TextSelectorConfig,
TextSelectorType,
)
from .const import (
ACCOUNT_ID,
@@ -66,7 +71,15 @@ class AdaxConfigFlow(ConfigFlow, domain=DOMAIN):
) -> ConfigFlowResult:
"""Handle the local step."""
data_schema = vol.Schema(
{vol.Required(WIFI_SSID): str, vol.Required(WIFI_PSWD): str}
{
vol.Required(WIFI_SSID): str,
vol.Required(WIFI_PSWD): TextSelector(
TextSelectorConfig(
type=TextSelectorType.PASSWORD,
autocomplete="current-password",
),
),
}
)
if user_input is None:
return self.async_show_form(
+53 -17
View File
@@ -2,14 +2,16 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import cast
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import UnitOfEnergy
from homeassistant.const import UnitOfEnergy, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -20,44 +22,74 @@ from .const import CONNECTION_TYPE, DOMAIN, LOCAL
from .coordinator import AdaxCloudCoordinator
@dataclass(kw_only=True, frozen=True)
class AdaxSensorDescription(SensorEntityDescription):
"""Describes Adax sensor entity."""
data_key: str
SENSORS: tuple[AdaxSensorDescription, ...] = (
AdaxSensorDescription(
key="temperature",
data_key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1,
),
AdaxSensorDescription(
key="energy",
data_key="energyWh",
device_class=SensorDeviceClass.ENERGY,
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=3,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AdaxConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Adax energy sensors with config flow."""
"""Set up the Adax sensors with config flow."""
if entry.data.get(CONNECTION_TYPE) != LOCAL:
cloud_coordinator = cast(AdaxCloudCoordinator, entry.runtime_data)
# Create individual energy sensors for each device
async_add_entities(
AdaxEnergySensor(cloud_coordinator, device_id)
for device_id in cloud_coordinator.data
[
AdaxSensor(cloud_coordinator, entity_description, device_id)
for device_id in cloud_coordinator.data
for entity_description in SENSORS
]
)
class AdaxEnergySensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
"""Representation of an Adax energy sensor."""
class AdaxSensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
"""Representation of an Adax sensor."""
entity_description: AdaxSensorDescription
_attr_has_entity_name = True
_attr_translation_key = "energy"
_attr_device_class = SensorDeviceClass.ENERGY
_attr_native_unit_of_measurement = UnitOfEnergy.WATT_HOUR
_attr_suggested_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
_attr_state_class = SensorStateClass.TOTAL_INCREASING
_attr_suggested_display_precision = 3
def __init__(
self,
coordinator: AdaxCloudCoordinator,
entity_description: AdaxSensorDescription,
device_id: str,
) -> None:
"""Initialize the energy sensor."""
"""Initialize the sensor."""
super().__init__(coordinator)
self.entity_description = entity_description
self._device_id = device_id
room = coordinator.data[device_id]
self._attr_unique_id = f"{room['homeId']}_{device_id}_energy"
self._attr_unique_id = (
f"{room['homeId']}_{device_id}_{self.entity_description.key}"
)
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device_id)},
name=room["name"],
@@ -68,10 +100,14 @@ class AdaxEnergySensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
def available(self) -> bool:
"""Return True if entity is available."""
return (
super().available and "energyWh" in self.coordinator.data[self._device_id]
super().available
and self.entity_description.data_key
in self.coordinator.data[self._device_id]
)
@property
def native_value(self) -> int:
def native_value(self) -> int | float | None:
"""Return the native value of the sensor."""
return int(self.coordinator.data[self._device_id]["energyWh"])
return self.coordinator.data[self._device_id].get(
self.entity_description.data_key
)
+24 -24
View File
@@ -1,34 +1,34 @@
{
"config": {
"step": {
"user": {
"data": {
"connection_type": "Select connection type"
},
"description": "Select connection type. Local requires heaters with Bluetooth"
},
"local": {
"data": {
"wifi_ssid": "Wi-Fi SSID",
"wifi_pswd": "Wi-Fi password"
},
"description": "Reset the heater by pressing + and OK until display shows 'Reset'. Then press and hold OK button on the heater until the blue LED starts blinking before pressing Submit. Configuring heater might take some minutes."
},
"cloud": {
"data": {
"account_id": "Account ID",
"password": "[%key:common::config_flow::data::password%]"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"heater_not_available": "Heater not available. Try to reset the heater by pressing + and OK for some seconds.",
"heater_not_found": "Heater not found. Try to move the heater closer to Home Assistant computer.",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"step": {
"cloud": {
"data": {
"account_id": "Account ID",
"password": "[%key:common::config_flow::data::password%]"
}
},
"local": {
"data": {
"wifi_pswd": "Wi-Fi password",
"wifi_ssid": "Wi-Fi SSID"
},
"description": "Reset the heater by pressing + and OK until display shows 'Reset'. Then press and hold OK button on the heater until the blue LED starts blinking before pressing Submit. Configuring heater might take some minutes."
},
"user": {
"data": {
"connection_type": "Select connection type"
},
"description": "Select connection type. Local requires heaters with Bluetooth"
}
}
}
}
+1 -1
View File
@@ -45,7 +45,7 @@ SERVICE_REFRESH_SCHEMA = vol.Schema(
{vol.Optional(CONF_FORCE, default=False): cv.boolean}
)
PLATFORMS = [Platform.SENSOR, Platform.SWITCH]
PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.UPDATE]
type AdGuardConfigEntry = ConfigEntry[AdGuardData]
+20 -20
View File
@@ -1,6 +1,9 @@
{
"entity": {
"sensor": {
"average_processing_speed": {
"default": "mdi:speedometer"
},
"dns_queries": {
"default": "mdi:magnify"
},
@@ -13,21 +16,18 @@
"parental_control_blocked": {
"default": "mdi:human-male-girl"
},
"rules_count": {
"default": "mdi:counter"
},
"safe_browsing_blocked": {
"default": "mdi:shield-half-full"
},
"safe_searches_enforced": {
"default": "mdi:shield-search"
},
"average_processing_speed": {
"default": "mdi:speedometer"
},
"rules_count": {
"default": "mdi:counter"
}
},
"switch": {
"protection": {
"filtering": {
"default": "mdi:shield-check",
"state": {
"off": "mdi:shield-off"
@@ -39,7 +39,13 @@
"off": "mdi:shield-off"
}
},
"safe_search": {
"protection": {
"default": "mdi:shield-check",
"state": {
"off": "mdi:shield-off"
}
},
"query_log": {
"default": "mdi:shield-check",
"state": {
"off": "mdi:shield-off"
@@ -51,13 +57,7 @@
"off": "mdi:shield-off"
}
},
"filtering": {
"default": "mdi:shield-check",
"state": {
"off": "mdi:shield-off"
}
},
"query_log": {
"safe_search": {
"default": "mdi:shield-check",
"state": {
"off": "mdi:shield-off"
@@ -69,17 +69,17 @@
"add_url": {
"service": "mdi:link-plus"
},
"remove_url": {
"service": "mdi:link-off"
"disable_url": {
"service": "mdi:link-variant-off"
},
"enable_url": {
"service": "mdi:link-variant"
},
"disable_url": {
"service": "mdi:link-variant-off"
},
"refresh": {
"service": "mdi:refresh"
},
"remove_url": {
"service": "mdi:link-off"
}
}
}
@@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "local_polling",
"loggers": ["adguardhome"],
"requirements": ["adguardhome==0.7.0"]
"requirements": ["adguardhome==0.8.1"]
}
+71 -71
View File
@@ -1,35 +1,38 @@
{
"config": {
"step": {
"user": {
"description": "Set up your AdGuard Home instance to allow monitoring and control.",
"data": {
"host": "[%key:common::config_flow::data::host%]",
"password": "[%key:common::config_flow::data::password%]",
"port": "[%key:common::config_flow::data::port%]",
"username": "[%key:common::config_flow::data::username%]",
"ssl": "[%key:common::config_flow::data::ssl%]",
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
},
"data_description": {
"host": "The hostname or IP address of the device running your AdGuard Home."
}
},
"hassio_confirm": {
"title": "AdGuard Home via Home Assistant add-on",
"description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the add-on: {addon}?"
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
"existing_instance_updated": "Updated existing configuration."
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"existing_instance_updated": "Updated existing configuration.",
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
"step": {
"hassio_confirm": {
"description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the add-on: {addon}?",
"title": "AdGuard Home via Home Assistant add-on"
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"password": "[%key:common::config_flow::data::password%]",
"port": "[%key:common::config_flow::data::port%]",
"ssl": "[%key:common::config_flow::data::ssl%]",
"username": "[%key:common::config_flow::data::username%]",
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
},
"data_description": {
"host": "The hostname or IP address of the device running your AdGuard Home."
},
"description": "Set up your AdGuard Home instance to allow monitoring and control."
}
}
},
"entity": {
"sensor": {
"average_processing_speed": {
"name": "Average processing speed"
},
"dns_queries": {
"name": "DNS queries"
},
@@ -42,94 +45,91 @@
"parental_control_blocked": {
"name": "Parental control blocked"
},
"rules_count": {
"name": "Rules count"
},
"safe_browsing_blocked": {
"name": "Safe browsing blocked"
},
"safe_searches_enforced": {
"name": "Safe searches enforced"
},
"average_processing_speed": {
"name": "Average processing speed"
},
"rules_count": {
"name": "Rules count"
}
},
"switch": {
"protection": {
"name": "Protection"
"filtering": {
"name": "Filtering"
},
"parental": {
"name": "Parental control"
},
"safe_search": {
"name": "Safe search"
"protection": {
"name": "Protection"
},
"query_log": {
"name": "Query log"
},
"safe_browsing": {
"name": "Safe browsing"
},
"filtering": {
"name": "Filtering"
},
"query_log": {
"name": "Query log"
"safe_search": {
"name": "Safe search"
}
}
},
"services": {
"add_url": {
"name": "Add URL",
"description": "Adds a new filter subscription to AdGuard Home.",
"fields": {
"name": {
"name": "[%key:common::config_flow::data::name%]",
"description": "The name of the filter subscription."
"description": "The name of the filter subscription.",
"name": "[%key:common::config_flow::data::name%]"
},
"url": {
"name": "[%key:common::config_flow::data::url%]",
"description": "The filter URL to subscribe to, containing the filter rules."
"description": "The filter URL to subscribe to, containing the filter rules.",
"name": "[%key:common::config_flow::data::url%]"
}
}
},
"remove_url": {
"name": "Remove URL",
"description": "Removes a filter subscription from AdGuard Home.",
"fields": {
"url": {
"name": "[%key:common::config_flow::data::url%]",
"description": "The filter subscription URL to remove."
}
}
},
"enable_url": {
"name": "Enable URL",
"description": "Enables a filter subscription in AdGuard Home.",
"fields": {
"url": {
"name": "[%key:common::config_flow::data::url%]",
"description": "The filter subscription URL to enable."
}
}
},
"name": "Add URL"
},
"disable_url": {
"name": "Disable URL",
"description": "Disables a filter subscription in AdGuard Home.",
"fields": {
"url": {
"name": "[%key:common::config_flow::data::url%]",
"description": "The filter subscription URL to disable."
"description": "The filter subscription URL to disable.",
"name": "[%key:common::config_flow::data::url%]"
}
}
},
"name": "Disable URL"
},
"enable_url": {
"description": "Enables a filter subscription in AdGuard Home.",
"fields": {
"url": {
"description": "The filter subscription URL to enable.",
"name": "[%key:common::config_flow::data::url%]"
}
},
"name": "Enable URL"
},
"refresh": {
"name": "Refresh",
"description": "Refreshes all filter subscriptions in AdGuard Home.",
"fields": {
"force": {
"name": "Force",
"description": "Force update (bypasses AdGuard Home throttling), omit for a regular refresh."
"description": "Force update (bypasses AdGuard Home throttling), omit for a regular refresh.",
"name": "Force"
}
}
},
"name": "Refresh"
},
"remove_url": {
"description": "Removes a filter subscription from AdGuard Home.",
"fields": {
"url": {
"description": "The filter subscription URL to remove.",
"name": "[%key:common::config_flow::data::url%]"
}
},
"name": "Remove URL"
}
}
}
@@ -0,0 +1,71 @@
"""AdGuard Home Update platform."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
from adguardhome import AdGuardHomeError
from homeassistant.components.update import UpdateEntity, UpdateEntityFeature
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AdGuardConfigEntry, AdGuardData
from .const import DOMAIN
from .entity import AdGuardHomeEntity
SCAN_INTERVAL = timedelta(seconds=300)
PARALLEL_UPDATES = 1
async def async_setup_entry(
hass: HomeAssistant,
entry: AdGuardConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up AdGuard Home update entity based on a config entry."""
data = entry.runtime_data
if (await data.client.update.update_available()).disabled:
return
async_add_entities([AdGuardHomeUpdate(data, entry)], True)
class AdGuardHomeUpdate(AdGuardHomeEntity, UpdateEntity):
"""Defines an AdGuard Home update."""
_attr_supported_features = UpdateEntityFeature.INSTALL
_attr_name = None
def __init__(
self,
data: AdGuardData,
entry: AdGuardConfigEntry,
) -> None:
"""Initialize AdGuard Home update."""
super().__init__(data, entry)
self._attr_unique_id = "_".join(
[DOMAIN, self.adguard.host, str(self.adguard.port), "update"]
)
async def _adguard_update(self) -> None:
"""Update AdGuard Home entity."""
value = await self.adguard.update.update_available()
self._attr_installed_version = self.data.version
self._attr_latest_version = value.new_version
self._attr_release_summary = value.announcement
self._attr_release_url = value.announcement_url
async def async_install(
self, version: str | None, backup: bool, **kwargs: Any
) -> None:
"""Install latest update."""
try:
await self.adguard.update.begin_update()
except AdGuardHomeError as err:
raise HomeAssistantError(f"Failed to install update: {err}") from err
self.hass.config_entries.async_schedule_reload(self._entry.entry_id)
+10 -10
View File
@@ -1,22 +1,22 @@
{
"services": {
"write_data_by_name": {
"name": "Write data by name",
"description": "Write a value to the connected ADS device.",
"fields": {
"adsvar": {
"name": "ADS variable",
"description": "The name of the variable to write to."
},
"adstype": {
"name": "ADS type",
"description": "The data type of the variable to write to."
"description": "The data type of the variable to write to.",
"name": "ADS type"
},
"adsvar": {
"description": "The name of the variable to write to.",
"name": "ADS variable"
},
"value": {
"name": "Value",
"description": "The value to write to the variable."
"description": "The value to write to the variable.",
"name": "Value"
}
}
},
"name": "Write data by name"
}
}
}
@@ -1,11 +1,11 @@
{
"config": {
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"step": {
"user": {
"data": {
@@ -19,14 +19,14 @@
},
"services": {
"set_time_to": {
"name": "Set time to",
"description": "Controls timers to turn the system on or off after a set number of minutes.",
"fields": {
"minutes": {
"name": "Minutes",
"description": "Minutes until action."
"description": "Minutes until action.",
"name": "Minutes"
}
}
},
"name": "Set time to"
}
}
}
+42 -42
View File
@@ -1,57 +1,57 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"step": {
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"services": {
"add_tracking": {
"name": "Add tracking",
"description": "Adds a new tracking number to Aftership.",
"fields": {
"tracking_number": {
"name": "Tracking number",
"description": "Tracking number for the new tracking."
},
"title": {
"name": "Title",
"description": "A custom title for the new tracking."
},
"slug": {
"name": "Slug",
"description": "Slug (carrier) of the new tracking."
}
}
},
"remove_tracking": {
"name": "Remove tracking",
"description": "Removes a tracking number from Aftership.",
"fields": {
"tracking_number": {
"name": "[%key:component::aftership::services::add_tracking::fields::tracking_number::name%]",
"description": "Tracking number of the tracking to remove."
},
"slug": {
"name": "[%key:component::aftership::services::add_tracking::fields::slug::name%]",
"description": "Slug (carrier) of the tracking to remove."
}
}
}
},
"issues": {
"deprecated_yaml_import_issue_cannot_connect": {
"title": "The {integration_title} YAML configuration import failed",
"description": "Configuring {integration_title} using YAML is being removed but there was a connection error importing your YAML configuration.\n\nEnsure connection to {integration_title} works and restart Home Assistant to try again or remove the {integration_title} YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
"description": "Configuring {integration_title} using YAML is being removed but there was a connection error importing your YAML configuration.\n\nEnsure connection to {integration_title} works and restart Home Assistant to try again or remove the {integration_title} YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually.",
"title": "The {integration_title} YAML configuration import failed"
}
},
"services": {
"add_tracking": {
"description": "Adds a new tracking number to Aftership.",
"fields": {
"slug": {
"description": "Slug (carrier) of the new tracking.",
"name": "Slug"
},
"title": {
"description": "A custom title for the new tracking.",
"name": "Title"
},
"tracking_number": {
"description": "Tracking number for the new tracking.",
"name": "Tracking number"
}
},
"name": "Add tracking"
},
"remove_tracking": {
"description": "Removes a tracking number from Aftership.",
"fields": {
"slug": {
"description": "Slug (carrier) of the tracking to remove.",
"name": "[%key:component::aftership::services::add_tracking::fields::slug::name%]"
},
"tracking_number": {
"description": "Tracking number of the tracking to remove.",
"name": "[%key:component::aftership::services::add_tracking::fields::tracking_number::name%]"
}
},
"name": "Remove tracking"
}
}
}
@@ -1,19 +1,19 @@
{
"services": {
"disable_alerts": {
"service": "mdi:bell-off"
},
"enable_alerts": {
"service": "mdi:bell-alert"
},
"snapshot": {
"service": "mdi:camera"
},
"start_recording": {
"service": "mdi:record-rec"
},
"stop_recording": {
"service": "mdi:stop"
},
"enable_alerts": {
"service": "mdi:bell-alert"
},
"disable_alerts": {
"service": "mdi:bell-off"
},
"snapshot": {
"service": "mdi:camera"
}
}
}
+27 -27
View File
@@ -1,45 +1,45 @@
{
"config": {
"step": {
"user": {
"title": "Set up Agent DVR",
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]"
},
"data_description": {
"host": "The IP address of the Agent DVR server."
}
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]"
},
"data_description": {
"host": "The IP address of the Agent DVR server."
},
"title": "Set up Agent DVR"
}
}
},
"services": {
"start_recording": {
"name": "Start recording",
"description": "Enables continuous recording."
},
"stop_recording": {
"name": "Stop recording",
"description": "Disables continuous recording."
"disable_alerts": {
"description": "Disables alerts.",
"name": "Disable alerts"
},
"enable_alerts": {
"name": "Enable alerts",
"description": "Enables alerts."
},
"disable_alerts": {
"name": "Disable alerts",
"description": "Disables alerts."
"description": "Enables alerts.",
"name": "Enable alerts"
},
"snapshot": {
"name": "Snapshot",
"description": "Takes a photo."
"description": "Takes a photo.",
"name": "Snapshot"
},
"start_recording": {
"description": "Enables continuous recording.",
"name": "Start recording"
},
"stop_recording": {
"description": "Disables continuous recording.",
"name": "Stop recording"
}
}
}
@@ -30,6 +30,7 @@ generate_data:
media:
accept:
- "*"
multiple: true
generate_image:
fields:
task_name:
@@ -57,3 +58,4 @@ generate_image:
media:
accept:
- "*"
multiple: true
+30 -30
View File
@@ -1,52 +1,52 @@
{
"services": {
"generate_data": {
"name": "Generate data",
"description": "Uses AI to run a task that generates data.",
"fields": {
"task_name": {
"name": "Task name",
"description": "Name of the task."
},
"instructions": {
"name": "Instructions",
"description": "Instructions on what needs to be done."
"attachments": {
"description": "List of files to attach for multi-modal AI analysis.",
"name": "Attachments"
},
"entity_id": {
"name": "Entity ID",
"description": "Entity ID to run the task on. If not provided, the preferred entity will be used."
"description": "Entity ID to run the task on. If not provided, the preferred entity will be used.",
"name": "Entity ID"
},
"instructions": {
"description": "Instructions on what needs to be done.",
"name": "Instructions"
},
"structure": {
"name": "Structured output",
"description": "When set, the AI Task will output fields with this in structure. The structure is a dictionary where the keys are the field names and the values contain a 'description', a 'selector', and an optional 'required' field."
"description": "When set, the AI Task will output fields with this in structure. The structure is a dictionary where the keys are the field names and the values contain a 'description', a 'selector', and an optional 'required' field.",
"name": "Structured output"
},
"attachments": {
"name": "Attachments",
"description": "List of files to attach for multi-modal AI analysis."
"task_name": {
"description": "Name of the task.",
"name": "Task name"
}
}
},
"name": "Generate data"
},
"generate_image": {
"name": "Generate image",
"description": "Uses AI to generate image.",
"fields": {
"task_name": {
"name": "Task name",
"description": "Name of the task."
},
"instructions": {
"name": "Instructions",
"description": "Instructions that explains the image to be generated."
"attachments": {
"description": "List of files to attach for using as references.",
"name": "Attachments"
},
"entity_id": {
"name": "Entity ID",
"description": "Entity ID to run the task on."
"description": "Entity ID to run the task on.",
"name": "Entity ID"
},
"attachments": {
"name": "Attachments",
"description": "List of files to attach for using as references."
"instructions": {
"description": "Instructions that explains the image to be generated.",
"name": "Instructions"
},
"task_name": {
"description": "Name of the task.",
"name": "Task name"
}
}
},
"name": "Generate image"
}
}
}
+19 -19
View File
@@ -9,14 +9,17 @@
}
},
"number": {
"led_bar_brightness": {
"display_brightness": {
"default": "mdi:brightness-percent"
},
"display_brightness": {
"led_bar_brightness": {
"default": "mdi:brightness-percent"
}
},
"select": {
"co2_automatic_baseline_calibration": {
"default": "mdi:molecule-co2"
},
"configuration_control": {
"default": "mdi:cloud-cog"
},
@@ -31,23 +34,11 @@
},
"voc_index_learning_time_offset": {
"default": "mdi:clock-outline"
},
"co2_automatic_baseline_calibration": {
"default": "mdi:molecule-co2"
}
},
"sensor": {
"total_volatile_organic_component_index": {
"default": "mdi:molecule"
},
"nitrogen_index": {
"default": "mdi:molecule"
},
"pm003_count": {
"default": "mdi:blur"
},
"led_bar_brightness": {
"default": "mdi:brightness-percent"
"co2_automatic_baseline_calibration": {
"default": "mdi:molecule-co2"
},
"display_brightness": {
"default": "mdi:brightness-percent"
@@ -55,17 +46,26 @@
"display_temperature_unit": {
"default": "mdi:thermometer-lines"
},
"led_bar_brightness": {
"default": "mdi:brightness-percent"
},
"led_bar_mode": {
"default": "mdi:led-strip"
},
"nitrogen_index": {
"default": "mdi:molecule"
},
"nox_index_learning_time_offset": {
"default": "mdi:clock-outline"
},
"pm003_count": {
"default": "mdi:blur"
},
"total_volatile_organic_component_index": {
"default": "mdi:molecule"
},
"voc_index_learning_time_offset": {
"default": "mdi:clock-outline"
},
"co2_automatic_baseline_calibration": {
"default": "mdi:molecule-co2"
}
},
"switch": {
@@ -1,19 +1,5 @@
{
"config": {
"flow_title": "{model}",
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]"
},
"data_description": {
"host": "The hostname or IP address of the Airgradient device."
}
},
"discovery_confirm": {
"description": "Do you want to set up {model}?"
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
@@ -24,6 +10,20 @@
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"flow_title": "{model}",
"step": {
"discovery_confirm": {
"description": "Do you want to set up {model}?"
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]"
},
"data_description": {
"host": "The hostname or IP address of the Airgradient device."
}
}
}
},
"entity": {
@@ -36,14 +36,25 @@
}
},
"number": {
"led_bar_brightness": {
"name": "LED bar brightness"
},
"display_brightness": {
"name": "Display brightness"
},
"led_bar_brightness": {
"name": "LED bar brightness"
}
},
"select": {
"co2_automatic_baseline_calibration": {
"name": "CO2 automatic baseline duration",
"state": {
"0": "[%key:common::state::off%]",
"1": "1 day",
"8": "8 days",
"30": "30 days",
"90": "90 days",
"180": "180 days"
}
},
"configuration_control": {
"name": "Configuration source",
"state": {
@@ -51,13 +62,6 @@
"local": "Local"
}
},
"display_temperature_unit": {
"name": "Display temperature unit",
"state": {
"c": "Celsius",
"f": "Fahrenheit"
}
},
"display_pm_standard": {
"name": "Display PM standard",
"state": {
@@ -65,11 +69,18 @@
"us_aqi": "US AQI"
}
},
"display_temperature_unit": {
"name": "Display temperature unit",
"state": {
"c": "Celsius",
"f": "Fahrenheit"
}
},
"led_bar_mode": {
"name": "LED bar mode",
"state": {
"off": "[%key:common::state::off%]",
"co2": "[%key:component::sensor::entity_component::carbon_dioxide::name%]",
"off": "[%key:common::state::off%]",
"pm": "Particulate matter"
}
},
@@ -92,37 +103,14 @@
"360": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::360%]",
"720": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::state::720%]"
}
},
"co2_automatic_baseline_calibration": {
"name": "CO2 automatic baseline duration",
"state": {
"1": "1 day",
"8": "8 days",
"30": "30 days",
"90": "90 days",
"180": "180 days",
"0": "[%key:common::state::off%]"
}
}
},
"sensor": {
"total_volatile_organic_component_index": {
"name": "VOC index"
"co2_automatic_baseline_calibration_days": {
"name": "Carbon dioxide automatic baseline calibration"
},
"nitrogen_index": {
"name": "NOx index"
},
"pm003_count": {
"name": "PM0.3"
},
"raw_total_volatile_organic_component": {
"name": "Raw VOC"
},
"raw_nitrogen": {
"name": "Raw NOx"
},
"raw_pm02": {
"name": "Raw PM2.5"
"display_brightness": {
"name": "[%key:component::airgradient::entity::number::display_brightness::name%]"
},
"display_pm_standard": {
"name": "[%key:component::airgradient::entity::select::display_pm_standard::name%]",
@@ -131,26 +119,6 @@
"us_aqi": "[%key:component::airgradient::entity::select::display_pm_standard::state::us_aqi%]"
}
},
"co2_automatic_baseline_calibration_days": {
"name": "Carbon dioxide automatic baseline calibration"
},
"nox_learning_offset": {
"name": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::name%]"
},
"tvoc_learning_offset": {
"name": "[%key:component::airgradient::entity::select::voc_index_learning_time_offset::name%]"
},
"led_bar_mode": {
"name": "[%key:component::airgradient::entity::select::led_bar_mode::name%]",
"state": {
"off": "[%key:common::state::off%]",
"co2": "[%key:component::sensor::entity_component::carbon_dioxide::name%]",
"pm": "[%key:component::airgradient::entity::select::led_bar_mode::state::pm%]"
}
},
"led_bar_brightness": {
"name": "[%key:component::airgradient::entity::number::led_bar_brightness::name%]"
},
"display_temperature_unit": {
"name": "[%key:component::airgradient::entity::select::display_temperature_unit::name%]",
"state": {
@@ -158,8 +126,40 @@
"f": "[%key:component::airgradient::entity::select::display_temperature_unit::state::f%]"
}
},
"display_brightness": {
"name": "[%key:component::airgradient::entity::number::display_brightness::name%]"
"led_bar_brightness": {
"name": "[%key:component::airgradient::entity::number::led_bar_brightness::name%]"
},
"led_bar_mode": {
"name": "[%key:component::airgradient::entity::select::led_bar_mode::name%]",
"state": {
"co2": "[%key:component::sensor::entity_component::carbon_dioxide::name%]",
"off": "[%key:common::state::off%]",
"pm": "[%key:component::airgradient::entity::select::led_bar_mode::state::pm%]"
}
},
"nitrogen_index": {
"name": "NOx index"
},
"nox_learning_offset": {
"name": "[%key:component::airgradient::entity::select::nox_index_learning_time_offset::name%]"
},
"pm003_count": {
"name": "PM0.3"
},
"raw_nitrogen": {
"name": "Raw NOx"
},
"raw_pm02": {
"name": "Raw PM2.5"
},
"raw_total_volatile_organic_component": {
"name": "Raw VOC"
},
"total_volatile_organic_component_index": {
"name": "VOC index"
},
"tvoc_learning_offset": {
"name": "[%key:component::airgradient::entity::select::voc_index_learning_time_offset::name%]"
}
},
"switch": {
+25 -25
View File
@@ -1,30 +1,23 @@
{
"config": {
"step": {
"user": {
"description": "To generate API key go to {developer_registration_url}",
"data": {
"name": "[%key:common::config_flow::data::name%]",
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]"
}
}
},
"error": {
"wrong_location": "No Airly measuring stations in this area.",
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
"wrong_location": "[%key:component::airly::config::error::wrong_location%]"
}
},
"system_health": {
"info": {
"can_reach_server": "Reach Airly server",
"requests_remaining": "Remaining allowed requests",
"requests_per_day": "Allowed requests per day"
},
"error": {
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"wrong_location": "No Airly measuring stations in this area."
},
"step": {
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]",
"name": "[%key:common::config_flow::data::name%]"
},
"description": "To generate API key go to {developer_registration_url}"
}
}
},
"entity": {
@@ -38,11 +31,18 @@
}
},
"exceptions": {
"update_error": {
"message": "An error occurred while retrieving data from the Airly API for {entry}: {error}"
},
"no_station": {
"message": "An error occurred while retrieving data from the Airly API for {entry}: no measuring stations in this area"
},
"update_error": {
"message": "An error occurred while retrieving data from the Airly API for {entry}: {error}"
}
},
"system_health": {
"info": {
"can_reach_server": "Reach Airly server",
"requests_per_day": "Allowed requests per day",
"requests_remaining": "Remaining allowed requests"
}
}
}
+3 -3
View File
@@ -4,15 +4,15 @@
"aqi": {
"default": "mdi:blur"
},
"o3": {
"default": "mdi:blur"
},
"pm10": {
"default": "mdi:blur"
},
"pm25": {
"default": "mdi:blur"
},
"o3": {
"default": "mdi:blur"
},
"station": {
"default": "mdi:blur"
}
+18 -18
View File
@@ -1,15 +1,7 @@
{
"config": {
"step": {
"user": {
"description": "To generate API key go to {api_key_url}",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]",
"radius": "Station radius (miles; optional)"
}
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
@@ -17,16 +9,15 @@
"invalid_location": "No results found for that location, try changing the location or station radius.",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"options": {
"step": {
"init": {
"user": {
"data": {
"radius": "Station radius (miles)"
}
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]",
"radius": "Station radius (miles; optional)"
},
"description": "To generate API key go to {api_key_url}"
}
}
},
@@ -43,5 +34,14 @@
}
}
}
},
"options": {
"step": {
"init": {
"data": {
"radius": "Station radius (miles)"
}
}
}
}
}
+51 -51
View File
@@ -1,5 +1,17 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"unique_id_mismatch": "Re-authentication should be used for the same device not a new one"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"key_data_missing": "Expected data not returned from the device, check the documentation for supported devices",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"flow_title": "Ubiquiti airOS device",
"step": {
"reauth_confirm": {
@@ -19,7 +31,6 @@
},
"sections": {
"advanced_settings": {
"name": "[%key:component::airos::config::step::user::sections::advanced_settings::name%]",
"data": {
"ssl": "[%key:component::airos::config::step::user::sections::advanced_settings::data::ssl%]",
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
@@ -27,24 +38,24 @@
"data_description": {
"ssl": "[%key:component::airos::config::step::user::sections::advanced_settings::data_description::ssl%]",
"verify_ssl": "[%key:component::airos::config::step::user::sections::advanced_settings::data_description::verify_ssl%]"
}
},
"name": "[%key:component::airos::config::step::user::sections::advanced_settings::name%]"
}
}
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]"
"password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::username%]"
},
"data_description": {
"host": "IP address or hostname of the airOS device",
"username": "Administrator username for the airOS device, normally 'ubnt'",
"password": "Password configured through the UISP app or web interface"
"password": "Password configured through the UISP app or web interface",
"username": "Administrator username for the airOS device, normally 'ubnt'"
},
"sections": {
"advanced_settings": {
"name": "Advanced settings",
"data": {
"ssl": "Use HTTPS",
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
@@ -52,28 +63,17 @@
"data_description": {
"ssl": "Whether the connection should be encrypted (required for most devices)",
"verify_ssl": "Whether the certificate should be verified when using HTTPS. This should be off for self-signed certificates"
}
},
"name": "Advanced settings"
}
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"key_data_missing": "Expected data not returned from the device, check the documentation for supported devices",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"unique_id_mismatch": "Re-authentication should be used for the same device not a new one"
}
},
"entity": {
"binary_sensor": {
"port_forwarding": {
"name": "Port forwarding"
"dhcp6_server": {
"name": "DHCPv6 server"
},
"dhcp_client": {
"name": "DHCP client"
@@ -81,8 +81,8 @@
"dhcp_server": {
"name": "DHCP server"
},
"dhcp6_server": {
"name": "DHCPv6 server"
"port_forwarding": {
"name": "Port forwarding"
},
"pppoe": {
"name": "PPPoE link"
@@ -99,20 +99,27 @@
"router": "Router"
}
},
"wireless_frequency": {
"name": "Wireless frequency"
},
"wireless_essid": {
"name": "Wireless SSID"
"host_uptime": {
"name": "Uptime"
},
"wireless_antenna_gain": {
"name": "Antenna gain"
},
"wireless_throughput_tx": {
"name": "Throughput transmit (actual)"
"wireless_distance": {
"name": "Wireless distance"
},
"wireless_throughput_rx": {
"name": "Throughput receive (actual)"
"wireless_essid": {
"name": "Wireless SSID"
},
"wireless_frequency": {
"name": "Wireless frequency"
},
"wireless_mode": {
"name": "Wireless mode",
"state": {
"point_to_multipoint": "Point-to-multipoint",
"point_to_point": "Point-to-point"
}
},
"wireless_polling_dl_capacity": {
"name": "Download capacity"
@@ -123,12 +130,6 @@
"wireless_remote_hostname": {
"name": "Remote hostname"
},
"host_uptime": {
"name": "Uptime"
},
"wireless_distance": {
"name": "Wireless distance"
},
"wireless_role": {
"name": "Wireless role",
"state": {
@@ -136,27 +137,26 @@
"station": "Station"
}
},
"wireless_mode": {
"name": "Wireless mode",
"state": {
"point_to_point": "Point-to-point",
"point_to_multipoint": "Point-to-multipoint"
}
"wireless_throughput_rx": {
"name": "Throughput receive (actual)"
},
"wireless_throughput_tx": {
"name": "Throughput transmit (actual)"
}
}
},
"exceptions": {
"invalid_auth": {
"message": "[%key:common::config_flow::error::invalid_auth%]"
},
"cannot_connect": {
"message": "[%key:common::config_flow::error::cannot_connect%]"
},
"key_data_missing": {
"message": "Key data not returned from device"
},
"error_data_missing": {
"message": "Data incomplete or missing"
},
"invalid_auth": {
"message": "[%key:common::config_flow::error::invalid_auth%]"
},
"key_data_missing": {
"message": "Key data not returned from device"
}
}
}
+61 -61
View File
@@ -1,36 +1,21 @@
{
"config": {
"step": {
"user": {
"title": "Identify the device",
"description": "Provide the IP address or mDNS of the device and its password",
"data": {
"ip_address": "[%key:common::config_flow::data::ip%]",
"password": "[%key:common::config_flow::data::password%]"
}
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"invalid_input": "[%key:common::config_flow::error::invalid_host%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"options": {
"step": {
"init": {
"title": "Configure air-Q integration",
"user": {
"data": {
"return_average": "Show values averaged by the device",
"clip_negatives": "Clip negative values"
"ip_address": "[%key:common::config_flow::data::ip%]",
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"return_average": "air-Q allows to poll both the noisy sensor readings as well as the values averaged on the device (default)",
"clip_negatives": "For baseline calibration purposes, certain sensor values may briefly become negative. The default behavior is to clip such values to 0"
}
"description": "Provide the IP address or mDNS of the device and its password",
"title": "Identify the device"
}
}
},
@@ -53,8 +38,11 @@
"bromine": {
"name": "Bromine"
},
"methanethiol": {
"name": "Methanethiol"
"carbon_disulfide": {
"name": "Carbon disulfide"
},
"carbon_monoxide": {
"name": "[%key:component::sensor::entity_component::carbon_monoxide::name%]"
},
"chlorine": {
"name": "Chlorine"
@@ -62,12 +50,6 @@
"chlorine_dioxide": {
"name": "Chlorine dioxide"
},
"carbon_disulfide": {
"name": "Carbon disulfide"
},
"carbon_monoxide": {
"name": "[%key:component::sensor::entity_component::carbon_monoxide::name%]"
},
"dew_point": {
"name": "Dew point"
},
@@ -77,36 +59,51 @@
"ethylene": {
"name": "Ethylene"
},
"formaldehyde": {
"name": "Formaldehyde"
},
"fluorine": {
"name": "Fluorine"
},
"hydrogen_sulfide": {
"name": "Hydrogen sulfide"
"formaldehyde": {
"name": "Formaldehyde"
},
"health_index": {
"name": "Health index"
},
"hydrochloric_acid": {
"name": "Hydrochloric acid"
},
"hydrogen": {
"name": "Hydrogen"
},
"hydrogen_cyanide": {
"name": "Hydrogen cyanide"
},
"hydrogen_fluoride": {
"name": "Hydrogen fluoride"
},
"health_index": {
"name": "Health index"
},
"hydrogen": {
"name": "Hydrogen"
},
"hydrogen_peroxide": {
"name": "Hydrogen peroxide"
},
"hydrogen_phosphide": {
"name": "Hydrogen phosphide"
},
"hydrogen_sulfide": {
"name": "Hydrogen sulfide"
},
"industrial_volatile_organic_compounds": {
"name": "VOCs (industrial)"
},
"maximum_noise": {
"name": "Noise (maximum)"
},
"methane": {
"name": "Methane"
},
"methanethiol": {
"name": "Methanethiol"
},
"noise": {
"name": "Noise"
},
"organic_acid": {
"name": "Organic acid"
},
@@ -116,36 +113,39 @@
"performance_index": {
"name": "Performance index"
},
"hydrogen_phosphide": {
"name": "Hydrogen phosphide"
},
"relative_pressure": {
"name": "Relative pressure"
},
"propane": {
"name": "Propane"
},
"refigerant": {
"name": "Refrigerant"
},
"silicon_hydride": {
"name": "Silicon hydride"
},
"noise": {
"name": "Noise"
},
"maximum_noise": {
"name": "Noise (maximum)"
},
"radon": {
"name": "Radon"
},
"industrial_volatile_organic_compounds": {
"name": "VOCs (industrial)"
"refigerant": {
"name": "Refrigerant"
},
"relative_pressure": {
"name": "Relative pressure"
},
"silicon_hydride": {
"name": "Silicon hydride"
},
"virus_index": {
"name": "Virus index"
}
}
},
"options": {
"step": {
"init": {
"data": {
"clip_negatives": "Clip negative values",
"return_average": "Show values averaged by the device"
},
"data_description": {
"clip_negatives": "For baseline calibration purposes, certain sensor values may briefly become negative. The default behavior is to clip such values to 0",
"return_average": "air-Q allows to poll both the noisy sensor readings as well as the values averaged on the device (default)"
},
"title": "Configure air-Q integration"
}
}
}
}
+14 -14
View File
@@ -1,5 +1,13 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"user": {
"data": {
@@ -8,29 +16,21 @@
},
"description": "Log in at {url} to find your credentials"
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
}
},
"entity": {
"sensor": {
"radon": {
"name": "Radon"
},
"light": {
"name": "Light"
},
"virus_risk": {
"name": "Virus Risk"
},
"mold": {
"name": "Mold"
},
"radon": {
"name": "Radon"
},
"virus_risk": {
"name": "Virus Risk"
}
}
}
@@ -23,7 +23,7 @@ from homeassistant.components.bluetooth import (
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_ADDRESS
from .const import DOMAIN, MFCT_ID
from .const import DEVICE_MODEL, DOMAIN, MFCT_ID
_LOGGER = logging.getLogger(__name__)
@@ -128,15 +128,15 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm discovery."""
assert self._discovered_device is not None
if user_input is not None:
if (
self._discovered_device is not None
and self._discovered_device.device.firmware.need_firmware_upgrade
):
if self._discovered_device.device.firmware.need_firmware_upgrade:
return self.async_abort(reason="firmware_upgrade_required")
return self.async_create_entry(
title=self.context["title_placeholders"]["name"], data={}
title=self.context["title_placeholders"]["name"],
data={DEVICE_MODEL: self._discovered_device.device.model.value},
)
self._set_confirm_only()
@@ -164,7 +164,10 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
self._discovered_device = discovery
return self.async_create_entry(title=discovery.name, data={})
return self.async_create_entry(
title=discovery.name,
data={DEVICE_MODEL: discovery.device.model.value},
)
current_addresses = self._async_current_ids(include_ignore=False)
devices: list[BluetoothServiceInfoBleak] = []
@@ -1,11 +1,16 @@
"""Constants for Airthings BLE."""
from airthings_ble import AirthingsDeviceType
DOMAIN = "airthings_ble"
MFCT_ID = 820
VOLUME_BECQUEREL = "Bq/m³"
VOLUME_PICOCURIE = "pCi/L"
DEVICE_MODEL = "device_model"
DEFAULT_SCAN_INTERVAL = 300
DEVICE_SPECIFIC_SCAN_INTERVAL = {AirthingsDeviceType.CORENTIUM_HOME_2.value: 1800}
MAX_RETRIES_AFTER_STARTUP = 5
@@ -16,7 +16,12 @@ from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util.unit_system import METRIC_SYSTEM
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
from .const import (
DEFAULT_SCAN_INTERVAL,
DEVICE_MODEL,
DEVICE_SPECIFIC_SCAN_INTERVAL,
DOMAIN,
)
_LOGGER = logging.getLogger(__name__)
@@ -34,12 +39,18 @@ class AirthingsBLEDataUpdateCoordinator(DataUpdateCoordinator[AirthingsDevice]):
self.airthings = AirthingsBluetoothDeviceData(
_LOGGER, hass.config.units is METRIC_SYSTEM
)
device_model = entry.data.get(DEVICE_MODEL)
interval = DEVICE_SPECIFIC_SCAN_INTERVAL.get(
device_model, DEFAULT_SCAN_INTERVAL
)
super().__init__(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL),
update_interval=timedelta(seconds=interval),
)
async def _async_setup(self) -> None:
@@ -58,11 +69,29 @@ class AirthingsBLEDataUpdateCoordinator(DataUpdateCoordinator[AirthingsDevice]):
)
self.ble_device = ble_device
if DEVICE_MODEL not in self.config_entry.data:
_LOGGER.debug("Fetching device info for migration")
try:
data = await self.airthings.update_device(self.ble_device)
except Exception as err:
raise UpdateFailed(
f"Unable to fetch data for migration: {err}"
) from err
self.hass.config_entries.async_update_entry(
self.config_entry,
data={**self.config_entry.data, DEVICE_MODEL: data.model.value},
)
self.update_interval = timedelta(
seconds=DEVICE_SPECIFIC_SCAN_INTERVAL.get(
data.model.value, DEFAULT_SCAN_INTERVAL
)
)
async def _async_update_data(self) -> AirthingsDevice:
"""Get data from Airthings BLE."""
try:
data = await self.airthings.update_device(self.ble_device)
except Exception as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
return data
@@ -4,10 +4,10 @@
"radon_1day_avg": {
"default": "mdi:radioactive"
},
"radon_longterm_avg": {
"radon_1day_level": {
"default": "mdi:radioactive"
},
"radon_1day_level": {
"radon_longterm_avg": {
"default": "mdi:radioactive"
},
"radon_longterm_level": {
@@ -28,5 +28,5 @@
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
"iot_class": "local_polling",
"requirements": ["airthings-ble==1.1.1"]
"requirements": ["airthings-ble==1.2.0"]
}
@@ -1,49 +1,49 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"firmware_upgrade_required": "Your device requires a firmware upgrade. Please use the Airthings app (Android/iOS) to upgrade it.",
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
"unknown": "[%key:common::config_flow::error::unknown%]",
"unsupported_device": "Unsupported device"
},
"flow_title": "{name}",
"step": {
"bluetooth_confirm": {
"description": "[%key:component::bluetooth::config::step::bluetooth_confirm::description%]"
},
"user": {
"description": "[%key:component::bluetooth::config::step::user::description%]",
"data": {
"address": "[%key:common::config_flow::data::device%]"
},
"data_description": {
"address": "The Airthings devices discovered via Bluetooth."
}
},
"bluetooth_confirm": {
"description": "[%key:component::bluetooth::config::step::bluetooth_confirm::description%]"
},
"description": "[%key:component::bluetooth::config::step::user::description%]"
}
},
"abort": {
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"firmware_upgrade_required": "Your device requires a firmware upgrade. Please use the Airthings app (Android/iOS) to upgrade it.",
"unsupported_device": "Unsupported device",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"entity": {
"sensor": {
"radon_1day_avg": {
"name": "Radon 1-day average"
},
"radon_longterm_avg": {
"name": "Radon longterm average"
},
"radon_1day_level": {
"name": "Radon 1-day level"
},
"radon_longterm_level": {
"name": "Radon longterm level"
"ambient_noise": {
"name": "Ambient noise"
},
"illuminance": {
"name": "[%key:component::sensor::entity_component::illuminance::name%]"
},
"ambient_noise": {
"name": "Ambient noise"
"radon_1day_avg": {
"name": "Radon 1-day average"
},
"radon_1day_level": {
"name": "Radon 1-day level"
},
"radon_longterm_avg": {
"name": "Radon longterm average"
},
"radon_longterm_level": {
"name": "Radon longterm level"
}
}
}
@@ -9,13 +9,13 @@
},
"step": {
"user": {
"title": "Set up your AirTouch 4 connection details.",
"data": {
"host": "[%key:common::config_flow::data::host%]"
},
"data_description": {
"host": "The hostname or IP address of your AirTouch controller."
}
},
"title": "Set up your AirTouch 4 connection details."
}
}
}
@@ -1,18 +1,18 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"entity": {
@@ -21,8 +21,8 @@
"state_attributes": {
"fan_mode": {
"state": {
"turbo": "Turbo",
"intelligent_auto": "Intelligent Auto"
"intelligent_auto": "Intelligent Auto",
"turbo": "Turbo"
}
}
}
@@ -1,11 +1,11 @@
{
"entity": {
"sensor": {
"pollutant_level": {
"default": "mdi:gauge"
},
"pollutant_label": {
"default": "mdi:chemical-weapon"
},
"pollutant_level": {
"default": "mdi:gauge"
}
}
}
+36 -36
View File
@@ -1,54 +1,44 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"location_not_found": "Location not found",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"geography_by_coords": {
"title": "Configure a geography",
"description": "Use the AirVisual cloud API to monitor a latitude/longitude.",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]"
}
},
"description": "Use the AirVisual cloud API to monitor a latitude/longitude.",
"title": "Configure a geography"
},
"geography_by_name": {
"title": "[%key:component::airvisual::config::step::geography_by_coords::title%]",
"description": "Use the AirVisual cloud API to monitor a city/state/country.",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"city": "City",
"state": "State",
"country": "[%key:common::config_flow::data::country%]"
}
"country": "[%key:common::config_flow::data::country%]",
"state": "State"
},
"description": "Use the AirVisual cloud API to monitor a city/state/country.",
"title": "[%key:component::airvisual::config::step::geography_by_coords::title%]"
},
"reauth_confirm": {
"title": "Re-authenticate AirVisual",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]"
}
},
"title": "Re-authenticate AirVisual"
},
"user": {
"title": "Configure AirVisual",
"description": "Pick what type of AirVisual data you want to monitor."
}
},
"error": {
"unknown": "[%key:common::config_flow::error::unknown%]",
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]",
"location_not_found": "Location not found",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"options": {
"step": {
"init": {
"title": "[%key:component::airvisual::config::step::user::title%]",
"data": {
"show_on_map": "Show monitored geography on the map"
}
"description": "Pick what type of AirVisual data you want to monitor.",
"title": "Configure AirVisual"
}
}
},
@@ -67,19 +57,29 @@
"pollutant_level": {
"state": {
"good": "Good",
"hazardous": "Hazardous",
"moderate": "Moderate",
"unhealthy": "Unhealthy",
"unhealthy_sensitive": "Unhealthy for sensitive groups",
"very_unhealthy": "Very unhealthy",
"hazardous": "Hazardous"
"very_unhealthy": "Very unhealthy"
}
}
}
},
"issues": {
"airvisual_pro_migration": {
"title": "{ip_address} is now part of the AirVisual Pro integration",
"description": "AirVisual Pro units are now their own Home Assistant integration (as opposed to be included with the original AirVisual integration that uses the AirVisual cloud API). The Pro device located at `{ip_address}` has automatically been migrated.\n\nAs part of that migration, the Pro's device ID has changed from `{old_device_id}` to `{new_device_id}`. Please update these automations to use the new device ID: {device_automations_string}."
"description": "AirVisual Pro units are now their own Home Assistant integration (as opposed to be included with the original AirVisual integration that uses the AirVisual cloud API). The Pro device located at `{ip_address}` has automatically been migrated.\n\nAs part of that migration, the Pro's device ID has changed from `{old_device_id}` to `{new_device_id}`. Please update these automations to use the new device ID: {device_automations_string}.",
"title": "{ip_address} is now part of the AirVisual Pro integration"
}
},
"options": {
"step": {
"init": {
"data": {
"show_on_map": "Show monitored geography on the map"
},
"title": "[%key:component::airvisual::config::step::user::title%]"
}
}
}
}
@@ -1,40 +1,40 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"reauth_confirm": {
"description": "[%key:component::airvisual_pro::config::step::user::description%]",
"data": {
"password": "[%key:common::config_flow::data::password%]"
}
},
"description": "[%key:component::airvisual_pro::config::step::user::description%]"
},
"user": {
"description": "The password can be retrieved from the AirVisual Pro's UI.",
"data": {
"ip_address": "[%key:common::config_flow::data::host%]",
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"ip_address": "The hostname or IP address of your AirVisual Pro device."
}
},
"description": "The password can be retrieved from the AirVisual Pro's UI."
}
},
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"entity": {
"sensor": {
"pm01": {
"name": "PM0.1"
},
"outdoor_air_quality_index": {
"name": "Outdoor air quality index"
},
"pm01": {
"name": "PM0.1"
}
}
}
+13 -13
View File
@@ -10,15 +10,15 @@
"step": {
"discovered_connection": {
"data": {
"id": "[%key:component::airzone::config::step::user::data::id%]",
"host": "[%key:common::config_flow::data::host%]",
"id": "[%key:component::airzone::config::step::user::data::id%]",
"port": "[%key:common::config_flow::data::port%]"
}
},
"user": {
"data": {
"id": "System ID",
"host": "[%key:common::config_flow::data::host%]",
"id": "System ID",
"port": "[%key:common::config_flow::data::port%]"
}
}
@@ -37,19 +37,19 @@
"grille_angles": {
"name": "Cold angle",
"state": {
"90deg": "90°",
"50deg": "50°",
"40deg": "40°",
"45deg": "45°",
"40deg": "40°"
"50deg": "50°",
"90deg": "90°"
}
},
"heat_angles": {
"name": "Heat angle",
"state": {
"90deg": "[%key:component::airzone::entity::select::grille_angles::state::90deg%]",
"50deg": "[%key:component::airzone::entity::select::grille_angles::state::50deg%]",
"40deg": "[%key:component::airzone::entity::select::grille_angles::state::40deg%]",
"45deg": "[%key:component::airzone::entity::select::grille_angles::state::45deg%]",
"40deg": "[%key:component::airzone::entity::select::grille_angles::state::40deg%]"
"50deg": "[%key:component::airzone::entity::select::grille_angles::state::50deg%]",
"90deg": "[%key:component::airzone::entity::select::grille_angles::state::90deg%]"
}
},
"modes": {
@@ -66,20 +66,20 @@
"q_adapt": {
"name": "Q-Adapt",
"state": {
"standard": "Standard",
"maximum": "Maximum",
"minimum": "Minimum",
"power": "Power",
"silence": "Silence",
"minimum": "Minimum",
"maximum": "Maximum"
"standard": "Standard"
}
},
"sleep_times": {
"name": "Sleep",
"state": {
"off": "[%key:common::state::off%]",
"30m": "30 minutes",
"60m": "60 minutes",
"90m": "90 minutes"
"90m": "90 minutes",
"off": "[%key:common::state::off%]"
}
}
},
@@ -10,8 +10,8 @@
"user": {
"data": {
"id": "Installation",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]"
"password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::username%]"
}
}
}
@@ -32,9 +32,9 @@
"air_quality": {
"name": "Air Quality mode",
"state": {
"auto": "[%key:common::state::auto%]",
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]",
"auto": "[%key:common::state::auto%]"
"on": "[%key:common::state::on%]"
}
},
"modes": {
@@ -1,34 +1,34 @@
{
"config": {
"step": {
"pick_implementation": {
"title": "[%key:common::config_flow::title::oauth2_pick_implementation%]"
},
"reauth_confirm": {
"title": "[%key:common::config_flow::title::reauth%]",
"description": "Aladdin Connect needs to re-authenticate your account"
},
"oauth_discovery": {
"description": "Home Assistant has found an Aladdin Connect device on your network. Press **Submit** to continue setting up Aladdin Connect."
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]",
"cloud_not_enabled": "Please make sure you run Home Assistant with `{default_config}` enabled in your configuration.yaml.",
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
"oauth_error": "[%key:common::config_flow::abort::oauth2_error%]",
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
"oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]",
"oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]",
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
"authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]",
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
"user_rejected_authorize": "[%key:common::config_flow::abort::oauth2_user_rejected_authorize%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"wrong_account": "You are authenticated with a different account than the one set up. Please authenticate with the configured account.",
"cloud_not_enabled": "Please make sure you run Home Assistant with `{default_config}` enabled in your configuration.yaml."
"user_rejected_authorize": "[%key:common::config_flow::abort::oauth2_user_rejected_authorize%]",
"wrong_account": "You are authenticated with a different account than the one set up. Please authenticate with the configured account."
},
"create_entry": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"
},
"step": {
"oauth_discovery": {
"description": "Home Assistant has found an Aladdin Connect device on your network. Press **Submit** to continue setting up Aladdin Connect."
},
"pick_implementation": {
"title": "[%key:common::config_flow::title::oauth2_pick_implementation%]"
},
"reauth_confirm": {
"description": "Aladdin Connect needs to re-authenticate your account",
"title": "[%key:common::config_flow::title::reauth%]"
}
}
}
}
@@ -18,23 +18,23 @@
"alarm_arm_away": {
"service": "mdi:shield-lock"
},
"alarm_arm_custom_bypass": {
"service": "mdi:security"
},
"alarm_arm_home": {
"service": "mdi:shield-home"
},
"alarm_arm_night": {
"service": "mdi:shield-moon"
},
"alarm_arm_custom_bypass": {
"service": "mdi:security"
"alarm_arm_vacation": {
"service": "mdi:shield-airplane"
},
"alarm_disarm": {
"service": "mdi:shield-off"
},
"alarm_trigger": {
"service": "mdi:bell-ring"
},
"alarm_arm_vacation": {
"service": "mdi:shield-airplane"
}
}
}
@@ -1,5 +1,4 @@
{
"title": "Alarm control panel",
"device_automation": {
"action_type": {
"arm_away": "Arm {entity_name} away",
@@ -10,24 +9,24 @@
"trigger": "Trigger {entity_name}"
},
"condition_type": {
"is_triggered": "{entity_name} is triggered",
"is_disarmed": "{entity_name} is disarmed",
"is_armed_home": "{entity_name} is armed home",
"is_armed_away": "{entity_name} is armed away",
"is_armed_home": "{entity_name} is armed home",
"is_armed_night": "{entity_name} is armed night",
"is_armed_vacation": "{entity_name} is armed vacation"
"is_armed_vacation": "{entity_name} is armed vacation",
"is_disarmed": "{entity_name} is disarmed",
"is_triggered": "{entity_name} is triggered"
},
"extra_fields": {
"code": "Code",
"for": "[%key:common::device_automation::extra_fields::for%]"
},
"trigger_type": {
"triggered": "{entity_name} triggered",
"disarmed": "{entity_name} disarmed",
"armed_home": "{entity_name} armed home",
"armed_away": "{entity_name} armed away",
"armed_home": "{entity_name} armed home",
"armed_night": "{entity_name} armed night",
"armed_vacation": "{entity_name} armed vacation"
"armed_vacation": "{entity_name} armed vacation",
"disarmed": "{entity_name} disarmed",
"triggered": "{entity_name} triggered"
}
},
"entity_component": {
@@ -35,106 +34,34 @@
"name": "[%key:component::alarm_control_panel::title%]",
"state": {
"armed": "Armed",
"disarmed": "Disarmed",
"armed_home": "Armed home",
"armed_away": "Armed away",
"armed_custom_bypass": "Armed custom bypass",
"armed_home": "Armed home",
"armed_night": "Armed night",
"armed_vacation": "Armed vacation",
"armed_custom_bypass": "Armed custom bypass",
"pending": "Pending",
"arming": "Arming",
"disarmed": "Disarmed",
"disarming": "Disarming",
"pending": "Pending",
"triggered": "Triggered"
},
"state_attributes": {
"code_format": {
"name": "Code format",
"state": {
"text": "Text",
"number": "Number"
}
},
"changed_by": {
"name": "Changed by"
},
"code_arm_required": {
"name": "Code for arming",
"state": {
"true": "Required",
"false": "Not required"
"false": "Not required",
"true": "Required"
}
},
"code_format": {
"name": "Code format",
"state": {
"number": "Number",
"text": "Text"
}
}
}
}
},
"services": {
"alarm_disarm": {
"name": "Disarm",
"description": "Disarms the alarm.",
"fields": {
"code": {
"name": "Code",
"description": "Code to disarm the alarm."
}
}
},
"alarm_arm_custom_bypass": {
"name": "Arm with custom bypass",
"description": "Arms the alarm while allowing to bypass a custom area.",
"fields": {
"code": {
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]",
"description": "Code to arm the alarm."
}
}
},
"alarm_arm_home": {
"name": "Arm home",
"description": "Arms the alarm in the home mode.",
"fields": {
"code": {
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]",
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]"
}
}
},
"alarm_arm_away": {
"name": "Arm away",
"description": "Arms the alarm in the away mode.",
"fields": {
"code": {
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]",
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]"
}
}
},
"alarm_arm_night": {
"name": "Arm night",
"description": "Arms the alarm in the night mode.",
"fields": {
"code": {
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]",
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]"
}
}
},
"alarm_arm_vacation": {
"name": "Arm vacation",
"description": "Arms the alarm in the vacation mode.",
"fields": {
"code": {
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]",
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]"
}
}
},
"alarm_trigger": {
"name": "Trigger",
"description": "Triggers the alarm manually.",
"fields": {
"code": {
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]",
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]"
}
}
}
@@ -143,5 +70,78 @@
"code_arm_required": {
"message": "Arming requires a code but none was given for {entity_id}."
}
}
},
"services": {
"alarm_arm_away": {
"description": "Arms the alarm in the away mode.",
"fields": {
"code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]"
}
},
"name": "Arm away"
},
"alarm_arm_custom_bypass": {
"description": "Arms the alarm while allowing to bypass a custom area.",
"fields": {
"code": {
"description": "Code to arm the alarm.",
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]"
}
},
"name": "Arm with custom bypass"
},
"alarm_arm_home": {
"description": "Arms the alarm in the home mode.",
"fields": {
"code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]"
}
},
"name": "Arm home"
},
"alarm_arm_night": {
"description": "Arms the alarm in the night mode.",
"fields": {
"code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]"
}
},
"name": "Arm night"
},
"alarm_arm_vacation": {
"description": "Arms the alarm in the vacation mode.",
"fields": {
"code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]"
}
},
"name": "Arm vacation"
},
"alarm_disarm": {
"description": "Disarms the alarm.",
"fields": {
"code": {
"description": "Code to disarm the alarm.",
"name": "Code"
}
},
"name": "Disarm"
},
"alarm_trigger": {
"description": "Triggers the alarm manually.",
"fields": {
"code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
"name": "[%key:component::alarm_control_panel::services::alarm_disarm::fields::code::name%]"
}
},
"name": "Trigger"
}
},
"title": "Alarm control panel"
}
@@ -1,101 +1,101 @@
{
"config": {
"step": {
"user": {
"title": "Choose AlarmDecoder protocol",
"data": {
"protocol": "Protocol"
}
},
"protocol": {
"title": "Configure connection settings",
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]",
"device_baudrate": "Device baud rate",
"device_path": "Device path"
},
"data_description": {
"host": "The hostname or IP address of the AlarmDecoder device that is connected to your alarm panel.",
"port": "The port on which AlarmDecoder is accessible (for example, 10000)"
}
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"create_entry": {
"default": "Successfully connected to AlarmDecoder."
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"create_entry": {
"default": "Successfully connected to AlarmDecoder."
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
"step": {
"protocol": {
"data": {
"device_baudrate": "Device baud rate",
"device_path": "Device path",
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]"
},
"data_description": {
"host": "The hostname or IP address of the AlarmDecoder device that is connected to your alarm panel.",
"port": "The port on which AlarmDecoder is accessible (for example, 10000)"
},
"title": "Configure connection settings"
},
"user": {
"data": {
"protocol": "Protocol"
},
"title": "Choose AlarmDecoder protocol"
}
}
},
"options": {
"error": {
"int": "The field below must be an integer.",
"loop_range": "'RF loop' must be an integer between 1 and 4.",
"loop_rfid": "'RF loop' cannot be used without 'RF serial'.",
"relay_inclusive": "'Relay address' and 'Relay channel' are codependent and must be included together."
},
"step": {
"arm_settings": {
"data": {
"alt_night_mode": "Alternative night mode",
"auto_bypass": "Auto-bypass on arm",
"code_arm_required": "Code required for arming"
},
"title": "[%key:component::alarmdecoder::options::step::init::title%]"
},
"init": {
"title": "Configure AlarmDecoder",
"description": "What would you like to edit?",
"data": {
"edit_selection": "Edit"
}
},
"arm_settings": {
"title": "[%key:component::alarmdecoder::options::step::init::title%]",
"data": {
"auto_bypass": "Auto-bypass on arm",
"code_arm_required": "Code required for arming",
"alt_night_mode": "Alternative night mode"
}
},
"zone_select": {
"title": "[%key:component::alarmdecoder::options::step::init::title%]",
"description": "Enter the zone number you'd like to to add, edit, or remove.",
"data": {
"zone_number": "Zone number"
}
},
"description": "What would you like to edit?",
"title": "Configure AlarmDecoder"
},
"zone_details": {
"title": "[%key:component::alarmdecoder::options::step::init::title%]",
"description": "Enter details for zone {zone_number}. To delete zone {zone_number}, leave 'Zone name' blank.",
"data": {
"zone_name": "Zone name",
"zone_type": "Zone type",
"zone_rfid": "RF serial",
"zone_loop": "RF loop",
"zone_name": "Zone name",
"zone_relayaddr": "Relay address",
"zone_relaychan": "Relay channel"
}
"zone_relaychan": "Relay channel",
"zone_rfid": "RF serial",
"zone_type": "Zone type"
},
"description": "Enter details for zone {zone_number}. To delete zone {zone_number}, leave 'Zone name' blank.",
"title": "[%key:component::alarmdecoder::options::step::init::title%]"
},
"zone_select": {
"data": {
"zone_number": "Zone number"
},
"description": "Enter the zone number you'd like to to add, edit, or remove.",
"title": "[%key:component::alarmdecoder::options::step::init::title%]"
}
},
"error": {
"relay_inclusive": "'Relay address' and 'Relay channel' are codependent and must be included together.",
"int": "The field below must be an integer.",
"loop_rfid": "'RF loop' cannot be used without 'RF serial'.",
"loop_range": "'RF loop' must be an integer between 1 and 4."
}
},
"services": {
"alarm_keypress": {
"name": "Key press",
"description": "Sends custom keypresses to the alarm.",
"fields": {
"keypress": {
"name": "[%key:component::alarmdecoder::services::alarm_keypress::name%]",
"description": "String to send to the alarm panel."
"description": "String to send to the alarm panel.",
"name": "[%key:component::alarmdecoder::services::alarm_keypress::name%]"
}
}
},
"name": "Key press"
},
"alarm_toggle_chime": {
"name": "Toggle chime",
"description": "Sends the alarm the toggle chime command.",
"fields": {
"code": {
"name": "Code",
"description": "Code to toggle the alarm control panel chime with."
"description": "Code to toggle the alarm control panel chime with.",
"name": "Code"
}
}
},
"name": "Toggle chime"
}
}
}
+8 -8
View File
@@ -1,5 +1,4 @@
{
"title": "Alert",
"entity_component": {
"_": {
"name": "[%key:component::alert::title%]",
@@ -12,16 +11,17 @@
},
"services": {
"toggle": {
"name": "[%key:common::action::toggle%]",
"description": "Toggles alert's notifications."
"description": "Toggles alert's notifications.",
"name": "[%key:common::action::toggle%]"
},
"turn_off": {
"name": "[%key:common::action::turn_off%]",
"description": "Silences alert's notifications."
"description": "Silences alert's notifications.",
"name": "[%key:common::action::turn_off%]"
},
"turn_on": {
"name": "[%key:common::action::turn_on%]",
"description": "Resets alert's notifications."
"description": "Resets alert's notifications.",
"name": "[%key:common::action::turn_on%]"
}
}
},
"title": "Alert"
}
+5 -2
View File
@@ -58,7 +58,10 @@ from homeassistant.const import (
from homeassistant.helpers import network
from homeassistant.util import color as color_util, dt as dt_util
from homeassistant.util.decorator import Registry
from homeassistant.util.unit_conversion import TemperatureConverter
from homeassistant.util.unit_conversion import (
TemperatureConverter,
TemperatureDeltaConverter,
)
from .config import AbstractConfig
from .const import (
@@ -844,7 +847,7 @@ def temperature_from_object(
temp -= 273.15
if interval:
return TemperatureConverter.convert_interval(temp, from_unit, to_unit)
return TemperatureDeltaConverter.convert(temp, from_unit, to_unit)
return TemperatureConverter.convert(temp, from_unit, to_unit)
@@ -6,8 +6,8 @@ from collections.abc import Callable
from dataclasses import dataclass
from typing import Final
from aioamazondevices.api import AmazonDevice
from aioamazondevices.const import SENSOR_STATE_OFF
from aioamazondevices.const.metadata import SENSOR_STATE_OFF
from aioamazondevices.structures import AmazonDevice
from homeassistant.components.binary_sensor import (
DOMAIN as BINARY_SENSOR_DOMAIN,
@@ -26,3 +26,6 @@ COUNTRY_DOMAINS = {
"us": DEFAULT_DOMAIN,
"za": "co.za",
}
CATEGORY_SENSORS = "sensors"
CATEGORY_NOTIFICATIONS = "notifications"
@@ -2,12 +2,13 @@
from datetime import timedelta
from aioamazondevices.api import AmazonDevice, AmazonEchoApi
from aioamazondevices.api import AmazonEchoApi
from aioamazondevices.exceptions import (
CannotAuthenticate,
CannotConnect,
CannotRetrieveData,
)
from aioamazondevices.structures import AmazonDevice
from aiohttp import ClientSession
from homeassistant.config_entries import ConfigEntry
@@ -15,6 +16,7 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import _LOGGER, CONF_LOGIN_DATA, DOMAIN
@@ -42,6 +44,9 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
name=entry.title,
config_entry=entry,
update_interval=timedelta(seconds=SCAN_INTERVAL),
request_refresh_debouncer=Debouncer(
hass, _LOGGER, cooldown=30, immediate=False
),
)
self.api = AmazonEchoApi(
session,
@@ -2,9 +2,10 @@
from __future__ import annotations
from dataclasses import asdict
from typing import Any
from aioamazondevices.api import AmazonDevice
from aioamazondevices.structures import AmazonDevice
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
@@ -60,5 +61,5 @@ def build_device_data(device: AmazonDevice) -> dict[str, Any]:
"online": device.online,
"serial number": device.serial_number,
"software version": device.software_version,
"sensors": device.sensors,
"sensors": {key: asdict(sensor) for key, sensor in device.sensors.items()},
}
@@ -1,7 +1,7 @@
"""Defines a base Alexa Devices entity."""
from aioamazondevices.api import AmazonDevice
from aioamazondevices.const import SPEAKER_GROUP_MODEL
from aioamazondevices.const.devices import SPEAKER_GROUP_MODEL
from aioamazondevices.structures import AmazonDevice
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription
@@ -8,5 +8,5 @@
"iot_class": "cloud_polling",
"loggers": ["aioamazondevices"],
"quality_scale": "platinum",
"requirements": ["aioamazondevices==6.4.6"]
"requirements": ["aioamazondevices==8.0.1"]
}
@@ -6,8 +6,9 @@ from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any, Final
from aioamazondevices.api import AmazonDevice, AmazonEchoApi
from aioamazondevices.const import SPEAKER_GROUP_FAMILY
from aioamazondevices.api import AmazonEchoApi
from aioamazondevices.const.devices import SPEAKER_GROUP_FAMILY
from aioamazondevices.structures import AmazonDevice
from homeassistant.components.notify import NotifyEntity, NotifyEntityDescription
from homeassistant.core import HomeAssistant
@@ -4,9 +4,15 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from typing import Final
from aioamazondevices.api import AmazonDevice
from aioamazondevices.const.schedules import (
NOTIFICATION_ALARM,
NOTIFICATION_REMINDER,
NOTIFICATION_TIMER,
)
from aioamazondevices.structures import AmazonDevice
from homeassistant.components.sensor import (
SensorDeviceClass,
@@ -19,6 +25,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from .const import CATEGORY_NOTIFICATIONS, CATEGORY_SENSORS
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
@@ -36,6 +43,20 @@ class AmazonSensorEntityDescription(SensorEntityDescription):
and (sensor := device.sensors.get(key)) is not None
and sensor.error is False
)
category: str = CATEGORY_SENSORS
@dataclass(frozen=True, kw_only=True)
class AmazonNotificationEntityDescription(SensorEntityDescription):
"""Amazon Devices notification entity description."""
native_unit_of_measurement_fn: Callable[[AmazonDevice, str], str] | None = None
is_available_fn: Callable[[AmazonDevice, str], bool] = lambda device, key: (
device.online
and (notification := device.notifications.get(key)) is not None
and notification.next_occurrence is not None
)
category: str = CATEGORY_NOTIFICATIONS
SENSORS: Final = (
@@ -56,6 +77,23 @@ SENSORS: Final = (
state_class=SensorStateClass.MEASUREMENT,
),
)
NOTIFICATIONS: Final = (
AmazonNotificationEntityDescription(
key=NOTIFICATION_ALARM,
translation_key="alarm",
device_class=SensorDeviceClass.TIMESTAMP,
),
AmazonNotificationEntityDescription(
key=NOTIFICATION_REMINDER,
translation_key="reminder",
device_class=SensorDeviceClass.TIMESTAMP,
),
AmazonNotificationEntityDescription(
key=NOTIFICATION_TIMER,
translation_key="timer",
device_class=SensorDeviceClass.TIMESTAMP,
),
)
async def async_setup_entry(
@@ -74,12 +112,18 @@ async def async_setup_entry(
new_devices = current_devices - known_devices
if new_devices:
known_devices.update(new_devices)
async_add_entities(
sensors_list = [
AmazonSensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in SENSORS
for serial_num in new_devices
if coordinator.data[serial_num].sensors.get(sensor_desc.key) is not None
)
]
notifications_list = [
AmazonSensorEntity(coordinator, serial_num, notification_desc)
for notification_desc in NOTIFICATIONS
for serial_num in new_devices
]
async_add_entities(sensors_list + notifications_list)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
@@ -88,7 +132,9 @@ async def async_setup_entry(
class AmazonSensorEntity(AmazonEntity, SensorEntity):
"""Sensor device."""
entity_description: AmazonSensorEntityDescription
entity_description: (
AmazonSensorEntityDescription | AmazonNotificationEntityDescription
)
@property
def native_unit_of_measurement(self) -> str | None:
@@ -101,9 +147,13 @@ class AmazonSensorEntity(AmazonEntity, SensorEntity):
return super().native_unit_of_measurement
@property
def native_value(self) -> StateType:
def native_value(self) -> StateType | datetime:
"""Return the state of the sensor."""
return self.device.sensors[self.entity_description.key].value
# Sensors
if self.entity_description.category == CATEGORY_SENSORS:
return self.device.sensors[self.entity_description.key].value
# Notifications
return self.device.notifications[self.entity_description.key].next_occurrence
@property
def available(self) -> bool:
@@ -1,6 +1,6 @@
"""Support for services."""
from aioamazondevices.sounds import SOUNDS_LIST
from aioamazondevices.const.sounds import SOUNDS_LIST
import voluptuous as vol
from homeassistant.config_entries import ConfigEntryState
@@ -1,47 +1,12 @@
{
"common": {
"data_code": "One-time password (OTP code)",
"data_description_username": "The email address of your Amazon account.",
"data_description_password": "The password of your Amazon account.",
"data_description_code": "The one-time password to log in to your account. Currently, only tokens from OTP applications are supported.",
"data_description_password": "The password of your Amazon account.",
"data_description_username": "The email address of your Amazon account.",
"device_id_description": "The ID of the device to send the command to."
},
"config": {
"flow_title": "{username}",
"step": {
"user": {
"data": {
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]",
"code": "[%key:component::alexa_devices::common::data_code%]"
},
"data_description": {
"username": "[%key:component::alexa_devices::common::data_description_username%]",
"password": "[%key:component::alexa_devices::common::data_description_password%]",
"code": "[%key:component::alexa_devices::common::data_description_code%]"
}
},
"reauth_confirm": {
"data": {
"password": "[%key:common::config_flow::data::password%]",
"code": "[%key:component::alexa_devices::common::data_code%]"
},
"data_description": {
"password": "[%key:component::alexa_devices::common::data_description_password%]",
"code": "[%key:component::alexa_devices::common::data_description_code%]"
}
},
"reconfigure": {
"data": {
"password": "[%key:common::config_flow::data::password%]",
"code": "[%key:component::alexa_devices::common::data_code%]"
},
"data_description": {
"password": "[%key:component::alexa_devices::common::data_description_password%]",
"code": "[%key:component::alexa_devices::common::data_description_code%]"
}
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
@@ -55,15 +20,61 @@
"cannot_retrieve_data": "Unable to retrieve data from Amazon. Please try again later.",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"flow_title": "{username}",
"step": {
"reauth_confirm": {
"data": {
"code": "[%key:component::alexa_devices::common::data_code%]",
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"code": "[%key:component::alexa_devices::common::data_description_code%]",
"password": "[%key:component::alexa_devices::common::data_description_password%]"
}
},
"reconfigure": {
"data": {
"code": "[%key:component::alexa_devices::common::data_code%]",
"password": "[%key:common::config_flow::data::password%]"
},
"data_description": {
"code": "[%key:component::alexa_devices::common::data_description_code%]",
"password": "[%key:component::alexa_devices::common::data_description_password%]"
}
},
"user": {
"data": {
"code": "[%key:component::alexa_devices::common::data_code%]",
"password": "[%key:common::config_flow::data::password%]",
"username": "[%key:common::config_flow::data::username%]"
},
"data_description": {
"code": "[%key:component::alexa_devices::common::data_description_code%]",
"password": "[%key:component::alexa_devices::common::data_description_password%]",
"username": "[%key:component::alexa_devices::common::data_description_username%]"
}
}
}
},
"entity": {
"notify": {
"speak": {
"name": "Speak"
},
"announce": {
"name": "Announce"
},
"speak": {
"name": "Speak"
}
},
"sensor": {
"alarm": {
"name": "Next alarm"
},
"reminder": {
"name": "Next reminder"
},
"timer": {
"name": "Next timer"
}
},
"switch": {
@@ -72,34 +83,24 @@
}
}
},
"services": {
"send_sound": {
"name": "Send sound",
"description": "Sends a sound to a device",
"fields": {
"device_id": {
"name": "Device",
"description": "[%key:component::alexa_devices::common::device_id_description%]"
},
"sound": {
"name": "Alexa Skill sound file",
"description": "The sound file to play."
}
}
"exceptions": {
"cannot_connect_with_error": {
"message": "Error connecting: {error}"
},
"send_text_command": {
"name": "Send text command",
"description": "Sends a text command to a device",
"fields": {
"text_command": {
"name": "Alexa text command",
"description": "The text command to send."
},
"device_id": {
"name": "Device",
"description": "[%key:component::alexa_devices::common::device_id_description%]"
}
}
"cannot_retrieve_data_with_error": {
"message": "Error retrieving data: {error}"
},
"device_serial_number_missing": {
"message": "Device serial number missing: {device_id}"
},
"entry_not_loaded": {
"message": "Entry not loaded: {entry}"
},
"invalid_device_id": {
"message": "Invalid device ID specified: {device_id}"
},
"invalid_sound_value": {
"message": "Invalid sound {sound} specified"
}
},
"selector": {
@@ -149,24 +150,34 @@
}
}
},
"exceptions": {
"cannot_connect_with_error": {
"message": "Error connecting: {error}"
"services": {
"send_sound": {
"description": "Sends a sound to a device",
"fields": {
"device_id": {
"description": "[%key:component::alexa_devices::common::device_id_description%]",
"name": "Device"
},
"sound": {
"description": "The sound file to play.",
"name": "Alexa Skill sound file"
}
},
"name": "Send sound"
},
"cannot_retrieve_data_with_error": {
"message": "Error retrieving data: {error}"
},
"device_serial_number_missing": {
"message": "Device serial number missing: {device_id}"
},
"invalid_device_id": {
"message": "Invalid device ID specified: {device_id}"
},
"invalid_sound_value": {
"message": "Invalid sound {sound} specified"
},
"entry_not_loaded": {
"message": "Entry not loaded: {entry}"
"send_text_command": {
"description": "Sends a text command to a device",
"fields": {
"device_id": {
"description": "[%key:component::alexa_devices::common::device_id_description%]",
"name": "Device"
},
"text_command": {
"description": "The text command to send.",
"name": "Alexa text command"
}
},
"name": "Send text command"
}
}
}
@@ -6,7 +6,7 @@ from collections.abc import Callable
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Final
from aioamazondevices.api import AmazonDevice
from aioamazondevices.structures import AmazonDevice
from homeassistant.components.switch import (
DOMAIN as SWITCH_DOMAIN,
@@ -4,7 +4,7 @@ from collections.abc import Awaitable, Callable, Coroutine
from functools import wraps
from typing import Any, Concatenate
from aioamazondevices.const import SPEAKER_GROUP_FAMILY
from aioamazondevices.const.devices import SPEAKER_GROUP_FAMILY
from aioamazondevices.exceptions import CannotConnect, CannotRetrieveData
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
+18 -18
View File
@@ -1,5 +1,12 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
},
"error": {
"no_device_found": "[%key:common::config_flow::error::cannot_connect%]"
},
"flow_title": "{name}",
"step": {
"discovery_confirm": {
@@ -14,37 +21,30 @@
},
"description": "Fill in Altruist IP address or hostname in your local network"
}
},
"abort": {
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"no_device_found": "[%key:common::config_flow::error::cannot_connect%]"
}
},
"entity": {
"sensor": {
"co2": {
"name": "{sensor_name} CO2"
},
"humidity": {
"name": "{sensor_name} humidity"
},
"pressure": {
"name": "{sensor_name} pressure"
},
"temperature": {
"name": "{sensor_name} temperature"
},
"noise_max": {
"name": "Maximum noise"
},
"noise_avg": {
"name": "Average noise"
},
"co2": {
"name": "{sensor_name} CO2"
"noise_max": {
"name": "Maximum noise"
},
"pressure": {
"name": "{sensor_name} pressure"
},
"radiation": {
"name": "Radiation level"
},
"temperature": {
"name": "{sensor_name} temperature"
}
}
}
@@ -9,14 +9,14 @@ from homeassistant.helpers import config_validation as cv
from .const import CONF_SITE_ID, DOMAIN, PLATFORMS
from .coordinator import AmberConfigEntry, AmberUpdateCoordinator
from .services import setup_services
from .services import async_setup_services
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Amber component."""
setup_services(hass)
async_setup_services(hass)
return True
@@ -1,19 +1,5 @@
{
"entity": {
"sensor": {
"general": {
"default": "mdi:transmission-tower"
},
"controlled_load": {
"default": "mdi:clock-outline"
},
"feed_in": {
"default": "mdi:solar-power"
},
"renewables": {
"default": "mdi:solar-power"
}
},
"binary_sensor": {
"demand_window": {
"default": "mdi:meter-electric",
@@ -21,6 +7,20 @@
"off": "mdi:meter-electric-outline"
}
}
},
"sensor": {
"controlled_load": {
"default": "mdi:clock-outline"
},
"feed_in": {
"default": "mdi:solar-power"
},
"general": {
"default": "mdi:transmission-tower"
},
"renewables": {
"default": "mdi:solar-power"
}
}
},
"services": {
@@ -10,6 +10,7 @@ from homeassistant.core import (
ServiceCall,
ServiceResponse,
SupportsResponse,
callback,
)
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers.selector import ConfigEntrySelector
@@ -102,7 +103,8 @@ def get_forecasts(channel_type: str, data: dict) -> list[JsonValueType]:
return results
def setup_services(hass: HomeAssistant) -> None:
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Set up the services for the Amber integration."""
async def handle_get_forecasts(call: ServiceCall) -> ServiceResponse:
@@ -22,40 +22,40 @@
}
}
},
"services": {
"get_forecasts": {
"name": "Get price forecasts",
"description": "Retrieves price forecasts from Amber Electric for a site.",
"fields": {
"config_entry_id": {
"description": "The config entry of the site to get forecasts for.",
"name": "Config entry"
},
"channel_type": {
"name": "Channel type",
"description": "The channel to get forecasts for."
}
}
}
},
"exceptions": {
"channel_not_found": {
"message": "There is no {channel_type} channel at this site."
},
"integration_not_found": {
"message": "Config entry \"{target}\" not found in registry."
},
"not_loaded": {
"message": "{target} is not loaded."
},
"channel_not_found": {
"message": "There is no {channel_type} channel at this site."
}
},
"selector": {
"channel_type": {
"options": {
"general": "General",
"controlled_load": "Controlled load",
"feed_in": "Feed-in"
"feed_in": "Feed-in",
"general": "General"
}
}
},
"services": {
"get_forecasts": {
"description": "Retrieves price forecasts from Amber Electric for a site.",
"fields": {
"channel_type": {
"description": "The channel to get forecasts for.",
"name": "Channel type"
},
"config_entry_id": {
"description": "The config entry of the site to get forecasts for.",
"name": "Config entry"
}
},
"name": "Get price forecasts"
}
}
}
@@ -4,15 +4,15 @@
"last_rain": {
"default": "mdi:water"
},
"lightning_distance": {
"default": "mdi:lightning-bolt"
},
"lightning_strikes_per_day": {
"default": "mdi:lightning-bolt"
},
"lightning_strikes_per_hour": {
"default": "mdi:lightning-bolt"
},
"lightning_distance": {
"default": "mdi:lightning-bolt"
},
"wind_direction": {
"default": "mdi:compass-outline"
}
@@ -106,7 +106,7 @@ SENSOR_DESCRIPTIONS = (
translation_key="daily_rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2,
),
SensorEntityDescription(
@@ -150,7 +150,7 @@ SENSOR_DESCRIPTIONS = (
key=TYPE_LIGHTNING_PER_DAY,
translation_key="lightning_strikes_per_day",
native_unit_of_measurement="strikes",
state_class=SensorStateClass.TOTAL,
state_class=SensorStateClass.TOTAL_INCREASING,
entity_registry_enabled_default=False,
),
SensorEntityDescription(
@@ -182,7 +182,7 @@ SENSOR_DESCRIPTIONS = (
translation_key="monthly_rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2,
entity_registry_enabled_default=False,
),
@@ -229,7 +229,7 @@ SENSOR_DESCRIPTIONS = (
translation_key="weekly_rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2,
entity_registry_enabled_default=False,
),
@@ -262,7 +262,7 @@ SENSOR_DESCRIPTIONS = (
translation_key="yearly_rain",
native_unit_of_measurement=UnitOfPrecipitationDepth.INCHES,
device_class=SensorDeviceClass.PRECIPITATION,
state_class=SensorStateClass.TOTAL,
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2,
entity_registry_enabled_default=False,
),
@@ -1,42 +1,30 @@
{
"config": {
"step": {
"user": {
"title": "Select region",
"description": "Choose the region you want to survey in order to locate Ambient personal weather stations."
},
"station": {
"title": "Select station",
"description": "Select the weather station you want to add to Home Assistant.",
"data": {
"station": "Station"
}
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"no_stations_found": "Did not find any stations in the selected region."
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
"step": {
"station": {
"data": {
"station": "Station"
},
"description": "Select the weather station you want to add to Home Assistant.",
"title": "Select station"
},
"user": {
"description": "Choose the region you want to survey in order to locate Ambient personal weather stations.",
"title": "Select region"
}
}
},
"entity": {
"sensor": {
"pm25_24h_average": {
"name": "PM2.5 (24 hour average)"
},
"pm25_aqi": {
"name": "PM2.5 AQI"
},
"pm25_aqi_24h_average": {
"name": "PM2.5 AQI (24 hour average)"
},
"absolute_pressure": {
"name": "Absolute pressure"
},
"relative_pressure": {
"name": "Relative pressure"
},
"daily_rain": {
"name": "Daily rain"
},
@@ -52,21 +40,33 @@
"last_rain": {
"name": "Last rain"
},
"lightning_distance": {
"name": "Lightning distance"
},
"lightning_strikes_per_day": {
"name": "Lightning strikes per day"
},
"lightning_strikes_per_hour": {
"name": "Lightning strikes per hour"
},
"lightning_distance": {
"name": "Lightning distance"
},
"max_daily_gust": {
"name": "Max daily gust"
},
"monthly_rain": {
"name": "Monthly rain"
},
"pm25_24h_average": {
"name": "PM2.5 (24 hour average)"
},
"pm25_aqi": {
"name": "PM2.5 AQI"
},
"pm25_aqi_24h_average": {
"name": "PM2.5 AQI (24 hour average)"
},
"relative_pressure": {
"name": "Relative pressure"
},
"uv_index": {
"name": "UV index"
},
@@ -1,20 +1,20 @@
{
"config": {
"step": {
"user": {
"title": "Fill in your information",
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"app_key": "Application Key"
}
}
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
},
"error": {
"invalid_key": "[%key:common::config_flow::error::invalid_api_key%]",
"no_devices": "No devices found in account"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
"step": {
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"app_key": "Application Key"
},
"title": "Fill in your information"
}
}
},
"entity": {
@@ -22,6 +22,9 @@
"battery_1": {
"name": "Battery 1"
},
"battery_10": {
"name": "Battery 10"
},
"battery_2": {
"name": "Battery 2"
},
@@ -46,59 +49,11 @@
"battery_9": {
"name": "Battery 9"
},
"battery_10": {
"name": "Battery 10"
},
"interior_battery": {
"name": "Interior battery"
},
"leak_detector_battery_1": {
"name": "Leak detector battery 1"
},
"leak_detector_battery_2": {
"name": "Leak detector battery 2"
},
"leak_detector_battery_3": {
"name": "Leak detector battery 3"
},
"leak_detector_battery_4": {
"name": "Leak detector battery 4"
},
"soil_monitor_battery_1": {
"name": "Soil monitor battery 1"
},
"soil_monitor_battery_2": {
"name": "Soil monitor battery 2"
},
"soil_monitor_battery_3": {
"name": "Soil monitor battery 3"
},
"soil_monitor_battery_4": {
"name": "Soil monitor battery 4"
},
"soil_monitor_battery_5": {
"name": "Soil monitor battery 5"
},
"soil_monitor_battery_6": {
"name": "Soil monitor battery 6"
},
"soil_monitor_battery_7": {
"name": "Soil monitor battery 7"
},
"soil_monitor_battery_8": {
"name": "Soil monitor battery 8"
},
"soil_monitor_battery_9": {
"name": "Soil monitor battery 9"
},
"soil_monitor_battery_10": {
"name": "Soil monitor battery 10"
},
"co2_battery": {
"name": "Carbon dioxide battery"
},
"lightning_detector_battery": {
"name": "Lightning detector battery"
"interior_battery": {
"name": "Interior battery"
},
"leak_detector_1": {
"name": "Leak detector 1"
@@ -112,15 +67,33 @@
"leak_detector_4": {
"name": "Leak detector 4"
},
"pm25_indoor_battery": {
"name": "PM25 indoor battery"
"leak_detector_battery_1": {
"name": "Leak detector battery 1"
},
"leak_detector_battery_2": {
"name": "Leak detector battery 2"
},
"leak_detector_battery_3": {
"name": "Leak detector battery 3"
},
"leak_detector_battery_4": {
"name": "Leak detector battery 4"
},
"lightning_detector_battery": {
"name": "Lightning detector battery"
},
"pm25_battery": {
"name": "PM25 battery"
},
"pm25_indoor_battery": {
"name": "PM25 indoor battery"
},
"relay_1": {
"name": "Relay 1"
},
"relay_10": {
"name": "Relay 10"
},
"relay_2": {
"name": "Relay 2"
},
@@ -145,32 +118,44 @@
"relay_9": {
"name": "Relay 9"
},
"relay_10": {
"name": "Relay 10"
"soil_monitor_battery_1": {
"name": "Soil monitor battery 1"
},
"soil_monitor_battery_10": {
"name": "Soil monitor battery 10"
},
"soil_monitor_battery_2": {
"name": "Soil monitor battery 2"
},
"soil_monitor_battery_3": {
"name": "Soil monitor battery 3"
},
"soil_monitor_battery_4": {
"name": "Soil monitor battery 4"
},
"soil_monitor_battery_5": {
"name": "Soil monitor battery 5"
},
"soil_monitor_battery_6": {
"name": "Soil monitor battery 6"
},
"soil_monitor_battery_7": {
"name": "Soil monitor battery 7"
},
"soil_monitor_battery_8": {
"name": "Soil monitor battery 8"
},
"soil_monitor_battery_9": {
"name": "Soil monitor battery 9"
}
},
"sensor": {
"24_hour_rain": {
"name": "Rain 24 hours"
},
"pm25_aqi": {
"name": "PM2.5 AQI"
},
"pm25_aqi_24h_average": {
"name": "PM2.5 AQI 24 hour average"
},
"pm25_indoor_aqi": {
"name": "PM2.5 indoor AQI"
},
"pm25_indoor_aqi_24h_average": {
"name": "PM2.5 indoor AQI"
},
"absolute_pressure": {
"name": "Absolute pressure"
},
"relative_pressure": {
"name": "Relative pressure"
},
"daily_rain": {
"name": "Daily rain"
},
@@ -186,6 +171,9 @@
"humidity_1": {
"name": "Humidity 1"
},
"humidity_10": {
"name": "Humidity 10"
},
"humidity_2": {
"name": "Humidity 2"
},
@@ -210,14 +198,11 @@
"humidity_9": {
"name": "Humidity 9"
},
"humidity_10": {
"name": "Humidity 10"
},
"humidity_indoor": {
"name": "Humidity indoor"
},
"last_rain": {
"name": "Last rain"
"inside_temperature": {
"name": "Inside temperature"
},
"last_lightning_strike": {
"name": "Last Lightning strike"
@@ -225,6 +210,12 @@
"last_lightning_strike_distance": {
"name": "Last Lightning strike distance"
},
"last_rain": {
"name": "Last rain"
},
"lifetime_rain": {
"name": "Lifetime rain"
},
"lightning_strikes_per_day": {
"name": "Lightning strikes per day"
},
@@ -240,15 +231,33 @@
"pm25_24h_average": {
"name": "PM2.5 24 hour average"
},
"pm25_aqi": {
"name": "PM2.5 AQI"
},
"pm25_aqi_24h_average": {
"name": "PM2.5 AQI 24 hour average"
},
"pm25_indoor": {
"name": "PM2.5 indoor"
},
"pm25_indoor_24h_average": {
"name": "PM2.5 indoor 24 hour average"
},
"pm25_indoor_aqi": {
"name": "PM2.5 indoor AQI"
},
"pm25_indoor_aqi_24h_average": {
"name": "PM2.5 indoor AQI"
},
"relative_pressure": {
"name": "Relative pressure"
},
"soil_humidity_1": {
"name": "Soil humidity 1"
},
"soil_humidity_10": {
"name": "Soil humidity 10"
},
"soil_humidity_2": {
"name": "Soil humidity 2"
},
@@ -273,12 +282,12 @@
"soil_humidity_9": {
"name": "Soil humidity 9"
},
"soil_humidity_10": {
"name": "Soil humidity 10"
},
"soil_temperature_1": {
"name": "Soil temperature 1"
},
"soil_temperature_10": {
"name": "Soil temperature 10"
},
"soil_temperature_2": {
"name": "Soil temperature 2"
},
@@ -303,12 +312,12 @@
"soil_temperature_9": {
"name": "Soil temperature 9"
},
"soil_temperature_10": {
"name": "Soil temperature 10"
},
"temperature_1": {
"name": "Temperature 1"
},
"temperature_10": {
"name": "Temperature 10"
},
"temperature_2": {
"name": "Temperature 2"
},
@@ -333,21 +342,18 @@
"temperature_9": {
"name": "Temperature 9"
},
"temperature_10": {
"name": "Temperature 10"
},
"inside_temperature": {
"name": "Inside temperature"
},
"lifetime_rain": {
"name": "Lifetime rain"
},
"uv_index": {
"name": "UV index"
},
"weekly_rain": {
"name": "Weekly rain"
},
"wind_average_10m": {
"name": "Wind average 10 minutes"
},
"wind_average_2m": {
"name": "Wind average 2 minutes"
},
"wind_direction": {
"name": "Wind direction"
},
@@ -357,17 +363,11 @@
"wind_direction_average_2m": {
"name": "Wind direction average 2 minutes"
},
"wind_gust_direction": {
"name": "Wind gust direction"
},
"wind_gust": {
"name": "Wind gust"
},
"wind_average_10m": {
"name": "Wind average 10 minutes"
},
"wind_average_2m": {
"name": "Wind average 2 minutes"
"wind_gust_direction": {
"name": "Wind gust direction"
},
"yearly_rain": {
"name": "Yearly rain"
+10 -10
View File
@@ -1,7 +1,10 @@
{
"services": {
"enable_recording": {
"service": "mdi:record-rec"
"disable_audio": {
"service": "mdi:volume-off"
},
"disable_motion_recording": {
"service": "mdi:motion-sensor-off"
},
"disable_recording": {
"service": "mdi:stop"
@@ -9,18 +12,18 @@
"enable_audio": {
"service": "mdi:volume-high"
},
"disable_audio": {
"service": "mdi:volume-off"
},
"enable_motion_recording": {
"service": "mdi:motion-sensor"
},
"disable_motion_recording": {
"service": "mdi:motion-sensor-off"
"enable_recording": {
"service": "mdi:record-rec"
},
"goto_preset": {
"service": "mdi:pan"
},
"ptz_control": {
"service": "mdi:pan"
},
"set_color_bw": {
"service": "mdi:palette"
},
@@ -29,9 +32,6 @@
},
"stop_tour": {
"service": "mdi:panorama-outline"
},
"ptz_control": {
"service": "mdi:pan"
}
}
}
+96 -96
View File
@@ -1,130 +1,130 @@
{
"services": {
"enable_recording": {
"name": "Enable recording",
"description": "Enables continuous recording to camera storage.",
"fields": {
"entity_id": {
"name": "Entity",
"description": "Name(s) of the cameras, or 'all' for all cameras."
}
}
},
"disable_recording": {
"name": "Disable recording",
"description": "Disables continuous recording to camera storage.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
}
}
},
"enable_audio": {
"name": "Enable audio",
"description": "Enables audio stream.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
}
}
},
"disable_audio": {
"name": "Disable audio",
"description": "Disables audio stream.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
}
},
"enable_motion_recording": {
"name": "Enable motion recording",
"description": "Enables recording a clip to camera storage when motion is detected.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
}
}
},
"name": "Disable audio"
},
"disable_motion_recording": {
"name": "Disable motion recording",
"description": "Disables recording a clip to camera storage when motion is detected.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
}
},
"name": "Disable motion recording"
},
"disable_recording": {
"description": "Disables continuous recording to camera storage.",
"fields": {
"entity_id": {
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
},
"name": "Disable recording"
},
"enable_audio": {
"description": "Enables audio stream.",
"fields": {
"entity_id": {
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
},
"name": "Enable audio"
},
"enable_motion_recording": {
"description": "Enables recording a clip to camera storage when motion is detected.",
"fields": {
"entity_id": {
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
},
"name": "Enable motion recording"
},
"enable_recording": {
"description": "Enables continuous recording to camera storage.",
"fields": {
"entity_id": {
"description": "Name(s) of the cameras, or 'all' for all cameras.",
"name": "Entity"
}
},
"name": "Enable recording"
},
"goto_preset": {
"name": "Go to preset",
"description": "Moves camera to PTZ preset.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
},
"preset": {
"name": "Preset",
"description": "Preset number."
"description": "Preset number.",
"name": "Preset"
}
}
},
"set_color_bw": {
"name": "Set color",
"description": "Sets camera color mode.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
},
"color_bw": {
"name": "Color",
"description": "Color mode."
}
}
},
"start_tour": {
"name": "Start tour",
"description": "Starts camera's PTZ tour function.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
}
}
},
"stop_tour": {
"name": "Stop tour",
"description": "Stops camera's PTZ tour function.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
}
}
},
"name": "Go to preset"
},
"ptz_control": {
"name": "PTZ control",
"description": "Moves (pan/tilt) and/or zoom a PTZ camera.",
"fields": {
"entity_id": {
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]",
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]"
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
},
"movement": {
"name": "Movement",
"description": "Direction to move the camera."
"description": "Direction to move the camera.",
"name": "Movement"
},
"travel_time": {
"name": "Travel time",
"description": "Travel time in fractional seconds: from 0 to 1."
"description": "Travel time in fractional seconds: from 0 to 1.",
"name": "Travel time"
}
}
},
"name": "PTZ control"
},
"set_color_bw": {
"description": "Sets camera color mode.",
"fields": {
"color_bw": {
"description": "Color mode.",
"name": "Color"
},
"entity_id": {
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
},
"name": "Set color"
},
"start_tour": {
"description": "Starts camera's PTZ tour function.",
"fields": {
"entity_id": {
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
},
"name": "Start tour"
},
"stop_tour": {
"description": "Stops camera's PTZ tour function.",
"fields": {
"entity_id": {
"description": "[%key:component::amcrest::services::enable_recording::fields::entity_id::description%]",
"name": "[%key:component::amcrest::services::enable_recording::fields::entity_id::name%]"
}
},
"name": "Stop tour"
}
}
}
+5 -25
View File
@@ -6,9 +6,8 @@ import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
from homeassistant.core import Event, HassJob, HomeAssistant, callback
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import async_call_later, async_track_time_interval
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.hass_dict import HassKey
@@ -20,7 +19,7 @@ from .analytics import (
EntityAnalyticsModifications,
async_devices_payload,
)
from .const import ATTR_ONBOARDED, ATTR_PREFERENCES, DOMAIN, INTERVAL, PREFERENCE_SCHEMA
from .const import ATTR_ONBOARDED, ATTR_PREFERENCES, DOMAIN, PREFERENCE_SCHEMA
from .http import AnalyticsDevicesView
__all__ = [
@@ -43,28 +42,9 @@ async def async_setup(hass: HomeAssistant, _: ConfigType) -> bool:
# Load stored data
await analytics.load()
@callback
def start_schedule(_event: Event) -> None:
async def start_schedule(_event: Event) -> None:
"""Start the send schedule after the started event."""
# Wait 15 min after started
async_call_later(
hass,
900,
HassJob(
analytics.send_analytics,
name="analytics schedule",
cancel_on_shutdown=True,
),
)
# Send every day
async_track_time_interval(
hass,
analytics.send_analytics,
INTERVAL,
name="analytics daily",
cancel_on_shutdown=True,
)
await analytics.async_schedule()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, start_schedule)
@@ -111,7 +91,7 @@ async def websocket_analytics_preferences(
analytics = hass.data[DATA_COMPONENT]
await analytics.save_preferences(preferences)
await analytics.send_analytics()
await analytics.async_schedule()
connection.send_result(
msg["id"],
+225 -17
View File
@@ -7,6 +7,8 @@ from asyncio import timeout
from collections.abc import Awaitable, Callable, Iterable, Mapping
from dataclasses import asdict as dataclass_asdict, dataclass, field
from datetime import datetime
import random
import time
from typing import Any, Protocol
import uuid
@@ -31,10 +33,18 @@ from homeassistant.const import (
BASE_PLATFORMS,
__version__ as HA_VERSION,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.core import (
CALLBACK_TYPE,
HassJob,
HomeAssistant,
ReleaseChannel,
callback,
get_release_channel,
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.event import async_call_later, async_track_time_interval
from homeassistant.helpers.hassio import is_hassio
from homeassistant.helpers.singleton import singleton
from homeassistant.helpers.storage import Store
@@ -51,6 +61,7 @@ from homeassistant.setup import async_get_loaded_integrations
from .const import (
ANALYTICS_ENDPOINT_URL,
ANALYTICS_ENDPOINT_URL_DEV,
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
ATTR_ADDON_COUNT,
ATTR_ADDONS,
ATTR_ARCH,
@@ -71,6 +82,7 @@ from .const import (
ATTR_PROTECTED,
ATTR_RECORDER,
ATTR_SLUG,
ATTR_SNAPSHOTS,
ATTR_STATE_COUNT,
ATTR_STATISTICS,
ATTR_SUPERVISOR,
@@ -80,8 +92,10 @@ from .const import (
ATTR_UUID,
ATTR_VERSION,
DOMAIN,
INTERVAL,
LOGGER,
PREFERENCE_SCHEMA,
SNAPSHOT_VERSION,
STORAGE_KEY,
STORAGE_VERSION,
)
@@ -194,13 +208,18 @@ def gen_uuid() -> str:
return uuid.uuid4().hex
RELEASE_CHANNEL = get_release_channel()
@dataclass
class AnalyticsData:
"""Analytics data."""
onboarded: bool
preferences: dict[str, bool]
uuid: str | None
uuid: str | None = None
submission_identifier: str | None = None
snapshot_submission_time: float | None = None
@classmethod
def from_dict(cls, data: dict[str, Any]) -> AnalyticsData:
@@ -209,6 +228,8 @@ class AnalyticsData:
data["onboarded"],
data["preferences"],
data["uuid"],
data.get("submission_identifier"),
data.get("snapshot_submission_time"),
)
@@ -219,8 +240,10 @@ class Analytics:
"""Initialize the Analytics class."""
self.hass: HomeAssistant = hass
self.session = async_get_clientsession(hass)
self._data = AnalyticsData(False, {}, None)
self._data = AnalyticsData(False, {})
self._store = Store[dict[str, Any]](hass, STORAGE_VERSION, STORAGE_KEY)
self._basic_scheduled: CALLBACK_TYPE | None = None
self._snapshot_scheduled: CALLBACK_TYPE | None = None
@property
def preferences(self) -> dict:
@@ -228,6 +251,7 @@ class Analytics:
preferences = self._data.preferences
return {
ATTR_BASE: preferences.get(ATTR_BASE, False),
ATTR_SNAPSHOTS: preferences.get(ATTR_SNAPSHOTS, False),
ATTR_DIAGNOSTICS: preferences.get(ATTR_DIAGNOSTICS, False),
ATTR_USAGE: preferences.get(ATTR_USAGE, False),
ATTR_STATISTICS: preferences.get(ATTR_STATISTICS, False),
@@ -244,9 +268,9 @@ class Analytics:
return self._data.uuid
@property
def endpoint(self) -> str:
def endpoint_basic(self) -> str:
"""Return the endpoint that will receive the payload."""
if HA_VERSION.endswith("0.dev0"):
if RELEASE_CHANNEL is ReleaseChannel.DEV:
# dev installations will contact the dev analytics environment
return ANALYTICS_ENDPOINT_URL_DEV
return ANALYTICS_ENDPOINT_URL
@@ -277,13 +301,17 @@ class Analytics:
):
self._data.preferences[ATTR_DIAGNOSTICS] = False
async def _save(self) -> None:
"""Save data."""
await self._store.async_save(dataclass_asdict(self._data))
async def save_preferences(self, preferences: dict) -> None:
"""Save preferences."""
preferences = PREFERENCE_SCHEMA(preferences)
self._data.preferences.update(preferences)
self._data.onboarded = True
await self._store.async_save(dataclass_asdict(self._data))
await self._save()
if self.supervisor:
await hassio.async_update_diagnostics(
@@ -292,17 +320,16 @@ class Analytics:
async def send_analytics(self, _: datetime | None = None) -> None:
"""Send analytics."""
if not self.onboarded or not self.preferences.get(ATTR_BASE, False):
return
hass = self.hass
supervisor_info = None
operating_system_info: dict[str, Any] = {}
if not self.onboarded or not self.preferences.get(ATTR_BASE, False):
LOGGER.debug("Nothing to submit")
return
if self._data.uuid is None:
self._data.uuid = gen_uuid()
await self._store.async_save(dataclass_asdict(self._data))
await self._save()
if self.supervisor:
supervisor_info = hassio.get_supervisor_info(hass)
@@ -436,7 +463,7 @@ class Analytics:
try:
async with timeout(30):
response = await self.session.post(self.endpoint, json=payload)
response = await self.session.post(self.endpoint_basic, json=payload)
if response.status == 200:
LOGGER.info(
(
@@ -449,7 +476,7 @@ class Analytics:
LOGGER.warning(
"Sending analytics failed with statuscode %s from %s",
response.status,
self.endpoint,
self.endpoint_basic,
)
except TimeoutError:
LOGGER.error("Timeout sending analytics to %s", ANALYTICS_ENDPOINT_URL)
@@ -489,6 +516,182 @@ class Analytics:
if entry.source != SOURCE_IGNORE and entry.disabled_by is None
)
async def send_snapshot(self, _: datetime | None = None) -> None:
"""Send a snapshot."""
if not self.onboarded or not self.preferences.get(ATTR_SNAPSHOTS, False):
return
payload = await _async_snapshot_payload(self.hass)
headers = {
"Content-Type": "application/json",
"User-Agent": f"home-assistant/{HA_VERSION}",
}
if self._data.submission_identifier is not None:
headers["X-Device-Database-Submission-Identifier"] = (
self._data.submission_identifier
)
try:
async with timeout(30):
response = await self.session.post(
ANALYTICS_SNAPSHOT_ENDPOINT_URL, json=payload, headers=headers
)
if response.status == 200: # OK
response_data = await response.json()
new_identifier = response_data.get("submission_identifier")
if (
new_identifier is not None
and new_identifier != self._data.submission_identifier
):
self._data.submission_identifier = new_identifier
await self._save()
LOGGER.info(
"Submitted snapshot analytics to Home Assistant servers"
)
elif response.status == 400: # Bad Request
response_data = await response.json()
error_kind = response_data.get("kind", "unknown")
error_message = response_data.get("message", "Unknown error")
if error_kind == "invalid-submission-identifier":
# Clear the invalid identifier and retry on next cycle
LOGGER.warning(
"Invalid submission identifier to %s, clearing: %s",
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
error_message,
)
self._data.submission_identifier = None
await self._save()
else:
LOGGER.warning(
"Malformed snapshot analytics submission (%s) to %s: %s",
error_kind,
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
error_message,
)
elif response.status == 503: # Service Unavailable
response_text = await response.text()
LOGGER.warning(
"Snapshot analytics service %s unavailable: %s",
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
response_text,
)
else:
LOGGER.warning(
"Unexpected status code %s when submitting snapshot analytics to %s",
response.status,
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
)
except TimeoutError:
LOGGER.error(
"Timeout sending snapshot analytics to %s",
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
)
except aiohttp.ClientError as err:
LOGGER.error(
"Error sending snapshot analytics to %s: %r",
ANALYTICS_SNAPSHOT_ENDPOINT_URL,
err,
)
async def async_schedule(self) -> None:
"""Schedule analytics."""
if not self.onboarded:
LOGGER.debug("Analytics not scheduled")
if self._basic_scheduled is not None:
self._basic_scheduled()
self._basic_scheduled = None
if self._snapshot_scheduled:
self._snapshot_scheduled()
self._snapshot_scheduled = None
return
if not self.preferences.get(ATTR_BASE, False):
LOGGER.debug("Basic analytics not scheduled")
if self._basic_scheduled is not None:
self._basic_scheduled()
self._basic_scheduled = None
elif self._basic_scheduled is None:
# Wait 15 min after started for basic analytics
self._basic_scheduled = async_call_later(
self.hass,
900,
HassJob(
self._async_schedule_basic,
name="basic analytics schedule",
cancel_on_shutdown=True,
),
)
if not self.preferences.get(ATTR_SNAPSHOTS, False) or RELEASE_CHANNEL not in (
ReleaseChannel.DEV,
ReleaseChannel.NIGHTLY,
):
LOGGER.debug("Snapshot analytics not scheduled")
if self._snapshot_scheduled:
self._snapshot_scheduled()
self._snapshot_scheduled = None
elif self._snapshot_scheduled is None:
snapshot_submission_time = self._data.snapshot_submission_time
if snapshot_submission_time is None:
# Randomize the submission time within the 24 hours
snapshot_submission_time = random.uniform(0, 86400)
self._data.snapshot_submission_time = snapshot_submission_time
await self._save()
LOGGER.debug(
"Initialized snapshot submission time to %s",
snapshot_submission_time,
)
# Calculate delay until next submission
current_time = time.time()
delay = (snapshot_submission_time - current_time) % 86400
self._snapshot_scheduled = async_call_later(
self.hass,
delay,
HassJob(
self._async_schedule_snapshots,
name="snapshot analytics schedule",
cancel_on_shutdown=True,
),
)
async def _async_schedule_basic(self, _: datetime | None = None) -> None:
"""Schedule basic analytics."""
await self.send_analytics()
# Send basic analytics every day
self._basic_scheduled = async_track_time_interval(
self.hass,
self.send_analytics,
INTERVAL,
name="basic analytics daily",
cancel_on_shutdown=True,
)
async def _async_schedule_snapshots(self, _: datetime | None = None) -> None:
"""Schedule snapshot analytics."""
await self.send_snapshot()
# Send snapshot analytics every day
self._snapshot_scheduled = async_track_time_interval(
self.hass,
self.send_snapshot,
INTERVAL,
name="snapshot analytics daily",
cancel_on_shutdown=True,
)
def _domains_from_yaml_config(yaml_configuration: dict[str, Any]) -> set[str]:
"""Extract domains from the YAML configuration."""
@@ -505,8 +708,8 @@ DEFAULT_DEVICE_ANALYTICS_CONFIG = DeviceAnalyticsModifications()
DEFAULT_ENTITY_ANALYTICS_CONFIG = EntityAnalyticsModifications()
async def async_devices_payload(hass: HomeAssistant) -> dict: # noqa: C901
"""Return detailed information about entities and devices."""
async def _async_snapshot_payload(hass: HomeAssistant) -> dict: # noqa: C901
"""Return detailed information about entities and devices for a snapshot."""
dev_reg = dr.async_get(hass)
ent_reg = er.async_get(hass)
@@ -711,8 +914,13 @@ async def async_devices_payload(hass: HomeAssistant) -> dict: # noqa: C901
entities_info.append(entity_info)
return integrations_info
async def async_devices_payload(hass: HomeAssistant) -> dict:
"""Return detailed information about entities and devices for a direct download."""
return {
"version": "home-assistant:1",
"version": f"home-assistant:{SNAPSHOT_VERSION}",
"home_assistant": HA_VERSION,
"integrations": integrations_info,
"integrations": await _async_snapshot_payload(hass),
}
@@ -7,6 +7,8 @@ import voluptuous as vol
ANALYTICS_ENDPOINT_URL = "https://analytics-api.home-assistant.io/v1"
ANALYTICS_ENDPOINT_URL_DEV = "https://analytics-api-dev.home-assistant.io/v1"
SNAPSHOT_VERSION = "1"
ANALYTICS_SNAPSHOT_ENDPOINT_URL = f"https://device-database.eco-dev-aws.openhomefoundation.com/api/v1/snapshot/{SNAPSHOT_VERSION}"
DOMAIN = "analytics"
INTERVAL = timedelta(days=1)
STORAGE_KEY = "core.analytics"
@@ -38,6 +40,7 @@ ATTR_PREFERENCES = "preferences"
ATTR_PROTECTED = "protected"
ATTR_RECORDER = "recorder"
ATTR_SLUG = "slug"
ATTR_SNAPSHOTS = "snapshots"
ATTR_STATE_COUNT = "state_count"
ATTR_STATISTICS = "statistics"
ATTR_SUPERVISOR = "supervisor"
@@ -51,6 +54,7 @@ ATTR_VERSION = "version"
PREFERENCE_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_BASE): bool,
vol.Optional(ATTR_SNAPSHOTS): bool,
vol.Optional(ATTR_DIAGNOSTICS): bool,
vol.Optional(ATTR_STATISTICS): bool,
vol.Optional(ATTR_USAGE): bool,
@@ -1,47 +1,25 @@
{
"config": {
"step": {
"user": {
"data": {
"tracked_addons": "Add-ons",
"tracked_integrations": "Integrations",
"tracked_custom_integrations": "Custom integrations"
},
"data_description": {
"tracked_addons": "Select the add-ons you want to track",
"tracked_integrations": "Select the integrations you want to track",
"tracked_custom_integrations": "Select the custom integrations you want to track"
}
}
},
"abort": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"error": {
"no_integrations_selected": "You must select at least one integration to track"
}
},
"options": {
},
"step": {
"init": {
"user": {
"data": {
"tracked_addons": "[%key:component::analytics_insights::config::step::user::data::tracked_addons%]",
"tracked_integrations": "[%key:component::analytics_insights::config::step::user::data::tracked_integrations%]",
"tracked_custom_integrations": "[%key:component::analytics_insights::config::step::user::data::tracked_custom_integrations%]"
"tracked_addons": "Add-ons",
"tracked_custom_integrations": "Custom integrations",
"tracked_integrations": "Integrations"
},
"data_description": {
"tracked_addons": "[%key:component::analytics_insights::config::step::user::data_description::tracked_addons%]",
"tracked_integrations": "[%key:component::analytics_insights::config::step::user::data_description::tracked_integrations%]",
"tracked_custom_integrations": "[%key:component::analytics_insights::config::step::user::data_description::tracked_custom_integrations%]"
"tracked_addons": "Select the add-ons you want to track",
"tracked_custom_integrations": "Select the custom integrations you want to track",
"tracked_integrations": "Select the integrations you want to track"
}
}
},
"abort": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"error": {
"no_integrations_selected": "[%key:component::analytics_insights::config::error::no_integrations_selected%]"
}
},
"entity": {
@@ -56,5 +34,27 @@
"name": "Total reported integrations"
}
}
},
"options": {
"abort": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
},
"error": {
"no_integrations_selected": "[%key:component::analytics_insights::config::error::no_integrations_selected%]"
},
"step": {
"init": {
"data": {
"tracked_addons": "[%key:component::analytics_insights::config::step::user::data::tracked_addons%]",
"tracked_custom_integrations": "[%key:component::analytics_insights::config::step::user::data::tracked_custom_integrations%]",
"tracked_integrations": "[%key:component::analytics_insights::config::step::user::data::tracked_integrations%]"
},
"data_description": {
"tracked_addons": "[%key:component::analytics_insights::config::step::user::data_description::tracked_addons%]",
"tracked_custom_integrations": "[%key:component::analytics_insights::config::step::user::data_description::tracked_custom_integrations%]",
"tracked_integrations": "[%key:component::analytics_insights::config::step::user::data_description::tracked_integrations%]"
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More