Compare commits

...

1564 Commits

Author SHA1 Message Date
Daniel Hjelseth Høyer a9b984d705 tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-16 16:47:20 +01:00
Daniel Hjelseth Høyer 886c0578e7 tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 16:18:46 +01:00
Daniel Hjelseth Høyer 02e579c5ae tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 15:38:27 +01:00
Daniel Hjelseth Høyer d47f3ca1d8 tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 15:27:07 +01:00
Daniel Hjelseth Høyer 02e5f2c234 tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 15:18:07 +01:00
Daniel Hjelseth Høyer e42195bfed tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 14:39:42 +01:00
Daniel Hjelseth Høyer b2944a6d66 tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 13:55:08 +01:00
Daniel Hjelseth Høyer 03d15fb70c tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 13:46:40 +01:00
Daniel Hjelseth Høyer 01d57ddcf1 tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 13:34:15 +01:00
Daniel Hjelseth Høyer cfc85cfd29 clean up
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 12:37:13 +01:00
Daniel Hjelseth Høyer ca2dc20709 Refactor Tibber
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-15 03:22:39 +01:00
Denis Shulyaka 3840f7a767 Bump openai to 2.21.0 (#163032) 2026-02-14 20:08:45 -05:00
Jordan Harvey af2d2a857a Add bedtime end time entity Nintendo parental controls (#160927) 2026-02-14 22:51:20 +01:00
jameson_uk 31970255a2 Add air quality monitor sensors to Alexa Devices (#162095)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-02-14 22:29:11 +01:00
Daniel Hjelseth Høyer f30397a11a Update homevolt quality scale (#163022)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-14 22:05:03 +01:00
Denis Shulyaka cbcfc43c5a Add reauthentication to Anthropic (#163019) 2026-02-14 21:53:25 +01:00
mettolen acaa2aeeee Add switch entities to Liebherr integration (#162688) 2026-02-14 21:41:06 +01:00
Denis Shulyaka c67c19413b Improve Anthropic coverage (#163011) 2026-02-14 21:33:53 +01:00
Paul Tarjan 8840d2f0ef Add entity descriptions to Hikvision binary sensors (#160875)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-14 21:32:39 +01:00
Daniel Hjelseth Høyer 82fb3c35dc Add zeroconf support to Homevolt (#162897)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-14 21:24:16 +01:00
Franck Nijhof 4d0d5d6817 CI security hardening actions/checkout to not persist-credentials (#162991) 2026-02-14 21:11:43 +01:00
Denis Shulyaka 12584482a2 Add data descriptions for Anthropic data flow (#162961) 2026-02-14 22:34:33 +03:00
Denis Shulyaka b47dd2f923 Enable strict typing check for Anthropic (#163013) 2026-02-14 19:04:29 +00:00
Ludovic BOUÉ 3d354da104 Added ppm support for the ozone device class in sensor (#162996) 2026-02-14 19:57:16 +01:00
wollew 89e900dca1 add switch platform for Velux on/off switches (#163002) 2026-02-14 15:36:51 +01:00
Patrick Vorgers 675884ad78 S3 backup - Improved buffer handling (#162955) 2026-02-14 15:26:08 +01:00
Franck Nijhof efb6cdc17e Fix failing sftp_storage test (#163000) 2026-02-14 08:12:06 -06:00
Jan Bouwhuis aca7fe530c Fix lingering test_waiting_for_client_not_loaded test (#162994) 2026-02-14 13:55:12 +01:00
Simone Chemelli 10fa02a36c Small test cleanup for Fritz (#162993) 2026-02-14 13:41:26 +01:00
jameson_uk 5344a874b0 fix: info skill reference (#162823) 2026-02-14 13:34:59 +01:00
Glenn de Haan ad2fe0d4d0 Add HDFury CEC and 5v switches (#162988) 2026-02-14 13:20:24 +01:00
Ludovic BOUÉ 9c275acca9 Add Matter TVOC level entity (#162964)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-14 12:50:08 +01:00
Martin Hjelmare 225ecedc95 Fix Z-Wave climate set preset (#162728) 2026-02-14 12:45:36 +01:00
Artur Pragacz f246c90073 Move DATA_MP_ENTITIES in Onkyo (#162674) 2026-02-14 12:35:40 +01:00
Denis Shulyaka 5bf7e83e76 Anthropic: Increase max iterations for AI Task (#162954) 2026-02-14 12:33:12 +01:00
Christian Lackas 3b3f4066c3 Fix HomematicIP entity recovery after access point cloud reconnect (#162575) 2026-02-14 12:23:16 +01:00
Glenn de Haan 30e484c292 Improve quality scale to platinum HDFury integration (#162985) 2026-02-14 12:17:32 +01:00
wollew 137377b50a Refactor Velux cover class (#162984) 2026-02-14 12:16:14 +01:00
Franck Nijhof 96b98c9cb9 Remove YAML anchors / expand GitHub CI workflows (#162987) 2026-02-14 12:01:29 +01:00
MoonDevLT 7d3601aa6f Replace the manufacturer name of lunatone (#162854) 2026-02-14 11:52:39 +01:00
Anders Ödlund 2ef7f6b317 Z-Wave lock service action modernization (#162967)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 10:33:23 +01:00
Matthias Alphart 7c8b181e6d Update knx-frontend to 2026.2.13.222258 (#162963) 2026-02-14 10:10:50 +01:00
Thomas Rupprecht b5147d8afa Improve SpaceAPI Manifest (#160805) 2026-02-14 09:55:55 +01:00
hanwg dc4bc6feea Set default file transfer timeouts for Telegram bot (#162978) 2026-02-14 09:36:25 +01:00
Thomas Rupprecht 4cea3b4aac Improve types and code in SpaceAPI (#162970) 2026-02-14 09:26:25 +01:00
Brett Adams d633a69e07 Bump python-tesla-fleet-api to v1.4.3 (#162977)
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-14 09:25:20 +01:00
AlCalzone 3e8e95f95e Handle Z-Wave values (re-)added at runtime (#162921) 2026-02-13 23:46:59 +01:00
Michael Hansen 6d66df9346 Bump intents to 2026.2.13 (#162959) 2026-02-13 23:29:55 +01:00
TheJulianJES ed15a01a6a Fix home-assistant-intents breaking nightly builds (#162957)
Co-authored-by: Robert Resch <robert@resch.dev>
2026-02-13 23:28:36 +01:00
Glenn de Haan 462d958b7e Bump hdfury to 1.5.0 (#162944) 2026-02-13 21:42:22 +01:00
Robin Lintermann d888579cbd Bump pysmarlaapi to 1.0.1 and compatibility changes (#162911) 2026-02-13 21:41:05 +01:00
Erik Montnemery e16a8ed20e Don't mock out filesystem operations in backup tests (#162877) 2026-02-13 21:39:34 +01:00
YogevBokobza b11a75d438 Add Switcher heater support (#162588)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2026-02-13 22:32:55 +02:00
Glenn de Haan 95df5b9ec9 Fix incorrect type HDFury select platform (#162948) 2026-02-13 20:50:26 +01:00
epenet a301a9c4b6 Always include homeassistant translations in tests (#162850) 2026-02-13 20:17:48 +01:00
Thomas55555 e80bb871e4 Bump ruff to 0.15.1 (#162903) 2026-02-13 19:43:37 +01:00
epenet ff4ff98e54 Parametrize yeelight test_device_types test (#161838) 2026-02-13 19:43:07 +01:00
wollew 88c6cb3877 add OnOffLight without brightness control to velux integration (#162835) 2026-02-13 19:42:44 +01:00
Michael 6b3a7e4cd6 Fix handling when FRITZ!Box reboots in FRITZ!Smarthome (#162676) 2026-02-13 19:41:03 +01:00
Michael 36ff7506a0 Fix handling when FRITZ!Box reboots in FRITZ!Box Tools (#162679) 2026-02-13 19:40:51 +01:00
Allen Porter a0af35f2dc Improve MCP SSE fallback error handling (#162655) 2026-02-13 19:39:34 +01:00
Josef Zweck c15da19b84 Log remaining token duration in onedrive (#162933) 2026-02-13 19:38:44 +01:00
Damien Sorel 23e88a24f0 Add remove item intent for todo component (#152922) 2026-02-13 19:38:22 +01:00
Robert Resch 815c708d19 Block redirect to localhost (#162941) 2026-02-13 19:31:35 +01:00
Paulus Schoutsen f9f2f39a3c OpenAI: Increase max iterations for AI Task (#162599) 2026-02-13 13:16:26 -05:00
Erik Montnemery 490514c274 Add fixture to give tests their own unique copy of testing_config (#162938) 2026-02-13 18:07:18 +01:00
Kamil Breguła 7da339b59c Add quality scale for GIOS (#155603)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2026-02-13 18:01:44 +01:00
Josef Zweck 1bb31892c2 Add integration for onedrive for business (#155709)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-13 07:01:52 -08:00
epenet 267caf2365 Use APPLICATION_CREDENTIALS_DOMAIN constant in tests (#162932) 2026-02-13 15:47:38 +01:00
Petro31 4e71a38e31 Ensure numeric template sensors only use numbers in _attr_native_state (#162878)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2026-02-13 14:14:28 +01:00
Petro31 d3d916566a Make template lock code error consistent between state based and trigger based template entities (#162923) 2026-02-13 14:13:58 +01:00
epenet fd3258a6d3 Use constants for update_entity calls in tests (#162920) 2026-02-13 13:54:40 +01:00
Sammy [Andrei Marinache] d1aadb5842 Add Miele TQ1000WP tumble dryer programs and program phases (#162871)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Åke Strandberg <ake@strandberg.eu>
2026-02-13 13:53:12 +01:00
epenet d984411911 Raise on missing supported color modes (#162717) 2026-02-13 13:39:48 +01:00
Robin Lintermann 8ed0a4cf29 Specifiy number of parallel updates in Smarla (#162914) 2026-02-13 13:24:24 +01:00
Simone Chemelli 9a407b8668 Optimize coordinator data type for UptimeRobot (#162912) 2026-02-13 13:23:59 +01:00
Robin Lintermann 72aa9d8a6a Improve smarla typing in tests (#162163) 2026-02-13 13:19:27 +01:00
Kevin Stillhammer dc1c52622e Fix google_travel_time get_travel_times config_entry_id description (#162910)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-13 13:18:55 +01:00
peteS-UK 44d5ecc926 Replace repeated patches in config_flow_test with fixtures for Squeezebox (#153032) 2026-02-13 12:00:24 +01:00
Simone Chemelli 54b0393ebe Cleanup code for UptimeRobot (#162905) 2026-02-13 11:53:04 +01:00
epenet 54141ffd3f Drop yardian custom translation overrides in tests (#162904) 2026-02-13 10:57:17 +01:00
David Bonnes 92b823068c Move evohome service registration to services.py (#162902) 2026-02-13 10:25:03 +01:00
Norbert Rittel d4a6377ab3 Fix capitalization of "Immich" and "MIME type" (#162900) 2026-02-13 10:00:39 +01:00
epenet 80d07c42ac Move evohome hasskey to const module (#162899) 2026-02-13 08:25:43 +00:00
puddly 077eeafa69 Bump ZHA to 0.0.90 (#162894) 2026-02-13 08:40:26 +01:00
dependabot[bot] b6ff8c94b1 Bump docker/build-push-action from 6.19.1 to 6.19.2 (#162896)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-13 08:39:53 +01:00
Michael 6a1581f2bf Immich reached platinum 🏆 (#162891) 2026-02-13 07:45:56 +01:00
johanzander 2dc0d32a29 Implement automatic migration for Growatt Server DEFAULT_PLANT_ID entries (#159972) 2026-02-13 01:56:50 +01:00
Niracler 036696f4cd Add energy sensor platform to sunricher_dali (#161415)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-13 01:55:16 +01:00
Michael 89f5b33a5e Cache get api calls in FRITZ!Box tools (#160246)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2026-02-13 01:54:33 +01:00
Matthias Alphart fc52885c21 Support KNX time server configuration from UI (#161854) 2026-02-13 01:52:38 +01:00
Ville Skyttä ffa8fc583d Recorder total_increasing warning clarifications (#157453) 2026-02-13 01:47:51 +01:00
Samuel Xiao f18fa07019 Switchbot Cloud: Add new supported device Ai Art Frame (#160754)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-13 01:47:03 +01:00
Alex Merkel ce704dd5f7 Add play/pause ability & media info to LG soundbars integration (#161184)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-13 01:39:05 +01:00
Patrick Vorgers d930755f92 IDrive e2 backup provider (#144910)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-12 15:49:03 -08:00
epenet 196c6d9839 Do not unregister adguard services (#158308)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-13 00:40:30 +01:00
David Rapan cce5358901 Re-implement Cloudflare using coordinator (#156817)
Signed-off-by: David Rapan <david@rapan.cz>
2026-02-13 00:33:48 +01:00
Heindrich Paul df7c3d787d Only show trains for configured time if configured in nederlandse_spoorwegen (#159261) 2026-02-13 00:29:20 +01:00
Manu a6287731f7 Increase test coverage in Xbox integration (#162876) 2026-02-12 15:14:07 -08:00
karwosts 1667b3f16b Add annual statistics aggregation (#160857) 2026-02-13 00:11:07 +01:00
Noah Husby 2aa9d22350 Add room correction setting to Cambridge Audio (#162743)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-02-12 23:10:13 +00:00
Matthias Alphart 3bcb303ef1 Support KNX number entity configuration from UI (#161269) 2026-02-13 00:06:53 +01:00
Manu e6de37cc69 Use service helper to retrieve config entry in Duck DNS integration (#162879) 2026-02-12 23:00:23 +00:00
Jon d10f5cc9ea Expose power and energy sensors for vera metered switches (#161028) 2026-02-12 23:56:35 +01:00
Erwin Douna 4921f05189 Disable mobile devices in tado (#160881)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 23:56:01 +01:00
Brett Adams 877ad391f0 Add config flow to Splunk (#160478)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Erwin Douna <e.douna@gmail.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 23:27:49 +01:00
n-6 8a5594b9e4 Added Ambient Weather station sensors for AQIN monitor. (#161082)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 23:27:25 +01:00
Josef Zweck a0623d1f97 Add IQS to openai_conversation (#161051)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Matthias Alphart <farmio@alphart.net>
Co-authored-by: Erwin Douna <e.douna@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 23:26:27 +01:00
Michael c8f8ef887a Add reconfigure flow to immich (#162892) 2026-02-12 23:25:51 +01:00
Eduardo Tsen 40ec6d3793 Add switch controls for dishwashers in SmartThings (#160266)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 22:57:54 +01:00
Matthias Alphart 0a79d84f9a KNX Expose: Add support for sending value periodically (#160883) 2026-02-12 22:51:40 +01:00
Przemko92 7a7e60ce75 Add number to Compit (#162165)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-12 22:49:34 +01:00
Kurt Chrisford 6bfaf6b188 Add action exception handling to Actron Air (#160579)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 22:46:53 +01:00
Kinachi249 34a445545c Cync - allow updating multiple attributes in one command (#159574)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 22:46:30 +01:00
epenet 3c854a7679 Improve type hints in utility_meter (#160993) 2026-02-12 22:46:13 +01:00
Florent Fourcot b7b6c1a72e Add more Melcloud sensors (#160770)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 22:39:21 +01:00
Michael fdf02cf657 Add missing exception translations in immich (#162889) 2026-02-12 22:32:22 +01:00
Kevin Stillhammer acf739df81 add services to google_travel_time (#160740)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 22:31:36 +01:00
Tom Matheussen 4801dcaded Add parent device for Satel Integra (#160933)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 22:29:59 +01:00
Daniel Hjelseth Høyer 11af0a2d04 Add reauthentication flow to Homevolt (#162868)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-12 22:27:30 +01:00
Michel Nederlof 40b30b94a2 Adjust discovery interval in govee-light-local (#160914)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 21:56:23 +01:00
Daniel Hjelseth Høyer 902d3f45a2 Add diagnostics to Homevolt (#162873)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-12 21:56:12 +01:00
ryanjones-gentex bf887fbc71 Add reauth flow to HomeLink integration (#158454)
Co-authored-by: Nicholas Aelick <niaexa@syntronic.com>
2026-02-12 21:51:26 +01:00
Michael e5ede7deea Categorize all immich sensor entities as diagnostic (#162887) 2026-02-12 21:36:45 +01:00
Erwin Douna 8b674a44a1 Melcloud move ConfigEntry declaration (#160890)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 21:32:54 +01:00
Joost Lekkerkerker e145963d48 Remove unused snapshots for Homevolt (#162885) 2026-02-12 21:32:41 +01:00
Simone Chemelli 1bca0ba5f8 Update UptimeRobot to API v3 (#153508) 2026-02-12 21:28:11 +01:00
Anders Ödlund 38531033a1 Catch AccessoryDisconnectedError in homekit pairing (#162466)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 20:51:09 +01:00
Xitee 9f1b6a12a5 Filter out transient zero values from qBittorrent alltime stats (#162821)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:45:42 +01:00
Daniel Hjelseth Høyer 876589f0cd Fix keys for Homevolt (#162874)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-02-12 18:42:50 +01:00
Przemko92 bd09ac9030 Add water heater support for Compit (#162021)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 18:39:02 +01:00
wollew 6d143c1ce2 add quality scale to manifest of velux integration (#162869) 2026-02-12 18:38:49 +01:00
Artur Pragacz f4ceb22d73 Add analytics platform to mobile_app (#162736) 2026-02-12 17:09:40 +01:00
Manu 5839191c37 Move entity service registration to async_setup in ntfy integration (#162833) 2026-02-12 16:42:15 +01:00
Manu 29feccb190 Improve tests in Bring! integration (#162853)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-12 16:41:08 +01:00
epenet a017417849 Use service helper to extract habitica config entry (#162795)
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
2026-02-12 16:39:03 +01:00
Aron List 72a7d708b0 Expose ActuatorEnabled attr of matter DoorLock (#162598) 2026-02-12 16:03:30 +01:00
epenet 47be13e6bf Improve error validation in service tests (#162851) 2026-02-12 06:34:31 -08:00
ElCruncharino 7d583be8e1 Add timeout to B2 metadata downloads to prevent backup hang (#162562) 2026-02-12 06:26:50 -08:00
Manu ccb3b35694 Use https for media player cover images in Xbox integration (#162859) 2026-02-12 05:59:28 -08:00
Steve Easley 48893d4daa Add JVC Projector switch platform (#161899)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-12 14:21:34 +01:00
Yoshi Walsh 0388e5dd7f Bump pydaikin to 2.17.2 (#162846) 2026-02-12 14:18:46 +01:00
Marc Hörsken 7a68903318 Bump pywmspro to 0.3.3 (#162832) 2026-02-12 14:18:19 +01:00
Anders Ödlund 64766100fe Add get_lock_usercode service to zwave_js integration (#162057)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 13:44:33 +01:00
Abílio Costa 0576dd91b7 Validate core_files.yaml base_platforms completeness (#162826) 2026-02-12 11:59:19 +00:00
Jon Seager f4440e992f Bump pytouchlinesl to 0.6.0 (#162856) 2026-02-12 12:42:36 +01:00
Daniel Hjelseth Høyer ea83b5a892 Add Homevolt battery integration (#160416)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-12 12:39:58 +01:00
Vicx d148952c99 Bump slixmpp to 1.13.2 (#162837) 2026-02-12 11:48:48 +01:00
epenet ed9a810908 Fix unavailable status in Tuya (#162709) 2026-02-12 11:46:40 +01:00
Peter Kolbus 6960cd6853 Bump pyweatherflowudp to 1.5.0 (#162841)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-12 11:43:01 +01:00
dependabot[bot] 5bd86ba600 Bump docker/build-push-action from 6.18.0 to 6.19.1 (#162844)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-12 10:05:36 +01:00
LG-ThinQ-Integration 70bc49479d Add vacuum's activity table to LG ThinQ (#162616)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2026-02-12 10:02:29 +01:00
wh1t3f1r3 81e0c105d6 Fix Venstar integration crash when thermostat is unreachable (#162524) 2026-02-12 09:54:11 +01:00
Peter Kolbus 527e2aec1f Improve weatherflow type hints (#162843) 2026-02-12 09:07:30 +01:00
epenet cd6661260c Use service helper to extract bring config entry (#162790) 2026-02-12 00:05:18 -05:00
epenet efa522cc73 Use service helper to extract bosch alarm config entry (#162789) 2026-02-12 00:04:50 -05:00
Artur Pragacz f9bd1b3d30 Rename registry imports in intent helper (#162765)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 00:04:29 -05:00
staticdev 4cfdb14714 Fix devcontainer defaultFormatter blocks (#162750) 2026-02-12 00:02:27 -05:00
epenet 6fb802e6b9 Use service helper to extract transmission config entry (#162814) 2026-02-11 23:58:35 -05:00
Christian Lackas 9b30fecb0c Fix absolute humidity sensor on HmIP-WGT glass thermostats (#162455) 2026-02-11 23:42:37 +01:00
Roman Lytvyn e77acc1002 Add WATER_LEVEL sensor to homekit_controller (#161900) 2026-02-11 23:38:46 +01:00
cdnninja 07e8b780a2 Add DHCP Discovery to vesync (#162259)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-11 23:27:35 +01:00
Denis Shulyaka e060395786 Anthropic Structured Outputs support (#162515) 2026-02-11 23:25:46 +01:00
Denis Shulyaka 661b14dec5 Deprecate OpenAI actions (#162211) 2026-02-11 23:17:15 +01:00
Christian Lackas b8e63b7ef6 Use direct DHW status for ViCare water heater state (#162591) 2026-02-11 23:07:56 +01:00
Abílio Costa fd78e35a86 Align number unit converters with sensor (#162662) 2026-02-11 23:07:04 +01:00
Mick Vleeshouwer db55dfe3c7 Improve device information in Overkiz (#162419) 2026-02-11 22:39:34 +01:00
Joost Lekkerkerker bda3121f98 Add snapshot tests to waterfurnace sensors (#162594) 2026-02-11 22:28:41 +01:00
dontinelli fd4981f3e2 Split up coordinators in solarlog (#161169)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-11 22:23:32 +01:00
Manu ae1bedd94a Add uptime ratio and avg. response time sensors to Uptime Kuma (#162785) 2026-02-11 22:09:21 +01:00
hanwg 90b67f90fa Handle config entry not loaded for Telegram bot (#161951)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-11 22:05:21 +01:00
cdnninja 9c821fb5f5 Mark log unavailable as complete for vesync (#162464) 2026-02-11 22:03:12 +01:00
Graham Crockford 1f9691ace1 Add charge state to Victron BLE (#162593)
Co-authored-by: Graham Crockford <badgerwithagun@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-11 21:59:56 +01:00
Paulus Schoutsen 5331cd99c6 Google Gen AI: Increase max iterations for AI Task (#162600)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-11 21:55:37 +01:00
Denis Shulyaka 1c3f24c78f Add TTS support for OpenAI (#162468)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-11 21:37:49 +01:00
Kamil Breguła e179e74df3 Support dual cook oven in Smartthing (#156561)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:27:40 +01:00
wollew 98602bd311 Bump pyvlx to 0.2.29 (#162829) 2026-02-11 21:10:44 +01:00
Jeef 5f01124c74 Bump typedmonarchmoney to 0.7.0 (#162686) 2026-02-11 19:44:08 +00:00
Brett Adams 4b5368be8e Complete config-entry-unloading quality check in Teslemetry (#161956)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-11 20:31:30 +01:00
Brett Adams 6379014f13 Use chained comparison in Teslemetry update platform (#161950)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-11 20:07:04 +01:00
Joost Lekkerkerker aa640020be Bump pySmartThings to 3.5.2 (#162809)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-02-11 20:02:28 +01:00
Simone Chemelli 92f4e600d1 Fix alarm refresh warning for Comelit SimpleHome (#162710) 2026-02-11 19:36:57 +01:00
Andreas Jakl 25a6b6fa65 Add switch platform to nrgkick integration for enabling or pausing car charging (#162563)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-11 19:36:36 +01:00
Manu 3cbe1295f9 Bump pythonkuma to 0.4.1 (#162773) 2026-02-11 19:35:12 +01:00
Erwin Douna 72581fb2b1 Add endpoint system df information (#160134) 2026-02-11 19:28:49 +01:00
Erwin Douna 97c89590e0 Portainer fix multiple environments & containers (#153674) 2026-02-11 19:21:36 +01:00
epenet b6ba86f3c1 Use service helper to extract onedrive config entry (#162803) 2026-02-11 10:16:55 -08:00
epenet cedc291872 Use service helper to extract tado config entry (#162812) 2026-02-11 10:15:38 -08:00
epenet 1d30486f82 Use service helper to extract velbus config entry (#162813) 2026-02-11 10:15:19 -08:00
Christopher Fenner 9f1b4c9035 Improve EnOcean config flow (#162751) 2026-02-11 19:14:45 +01:00
Christian Lackas 80ebb34ad1 Add smoke detector extended properties to homematicip_cloud (#161629)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-11 18:56:39 +01:00
hanwg e0e11fd99d Fix bug in edit_message_media action for Telegram bot (#162762) 2026-02-11 17:55:14 +01:00
Artur Pragacz 578a933f30 Move entity name helper to module-level function (#162766) 2026-02-11 17:54:53 +01:00
Christian Lackas 57493a1f69 Add ELV-SH-SB8 Status Board switch support to homematicip_cloud (#161668) 2026-02-11 17:43:51 +01:00
Simone Chemelli 3a4100fa94 Fix image platform state for Vodafone Station (#162747)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-11 17:39:51 +01:00
theobld-ww 0c1af1d613 Add switch entities to Watts Vision + (#162699)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-11 17:39:17 +01:00
starkillerOG 4e46431798 Add additional Reolink PTZ buttons (#162793) 2026-02-11 17:29:24 +01:00
starkillerOG bec66f49a2 Add Reolink PTZ patrol status (#162796) 2026-02-11 17:29:05 +01:00
epenet 4019768fa1 Use service helper to extract easyenergy config entry (#162791) 2026-02-11 17:24:57 +01:00
epenet 25d902fd3e Use service helper to extract google_photos config entry (#162792) 2026-02-11 17:24:44 +01:00
epenet 30f006538d Use service helper to extract google_sheets config entry (#162794) 2026-02-11 17:24:26 +01:00
epenet 15b1fee42d Use service helper to extract mastodon config entry (#162798) 2026-02-11 17:24:05 +01:00
epenet d69b816459 Use service helper to extract mealie config entry (#162800) 2026-02-11 17:19:03 +01:00
epenet bf79721e97 Use service helper to extract ohme config entry (#162801) 2026-02-11 17:18:25 +01:00
torben-iometer 66a0b44284 Fix missing values in battery_level in iometer (#162781) 2026-02-11 17:17:55 +01:00
Andy 8693294ea6 Add support for Nanoleaf Essentials / Replace aionanoleaf through aionanoleaf2 (#157295)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-11 17:06:40 +01:00
epenet 14ac7927f1 Use service helper to extract seventeentrack config entry (#162807) 2026-02-11 16:08:40 +01:00
Willem-Jan van Rootselaar b4674473d7 Fix BSBLAN water heater mapping and add on/off (#160256) 2026-02-11 16:06:26 +01:00
epenet f01ece1d3d Move TadoConfigEntry declaration (#162811) 2026-02-11 16:01:31 +01:00
epenet 08160a41a6 Use service helper to extract swiss public transport config entry (#162810) 2026-02-11 15:59:50 +01:00
epenet e617698770 Use service helper to extract stookwijzer config entry (#162808) 2026-02-11 15:59:36 +01:00
epenet ee31bdf18b Use service helper to extract radarr config entry (#162805) 2026-02-11 15:41:02 +01:00
epenet 305b911c0d Use service helper to extract overseerr config entry (#162804) 2026-02-11 15:36:34 +01:00
epenet 842abf78d2 Use service helper to extract risco config entry (#162806) 2026-02-11 15:35:27 +01:00
Willem-Jan van Rootselaar 134e8d1c1b Bump python-bsblan to version 4.2.0 (#162786) 2026-02-11 15:31:06 +01:00
epenet 733e90f747 Use service helper to extract immich config entry (#162797) 2026-02-11 15:02:32 +01:00
Artur Pragacz 6c92f7a864 Add integration type to mobile_app (#157719) 2026-02-11 14:48:10 +01:00
epenet f69b5b6e8f Use service helper to extract amberelectric config entry (#162788) 2026-02-11 13:49:29 +01:00
Willem-Jan van Rootselaar 59e53ee7b7 Add HVAC action support for BSBLAN climate entity (#156828)
Co-authored-by: Erwin Douna <e.douna@gmail.com>
2026-02-11 13:27:18 +01:00
epenet 62e1b0118c Add service helper to get config entry (#162068) 2026-02-11 13:20:37 +01:00
Guido Schmitz b7e9066b9d Add quality scale for devolo Home Control (#147483) 2026-02-11 12:17:02 +01:00
Erik Montnemery 2d6532b8ee Fix deadlock in ReloadServiceHelper (#162775) 2026-02-11 12:14:23 +01:00
Kamil Breguła ebd1f1b00f Add pagination support for AWS S3 (#162578)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 11:27:33 +01:00
jameson_uk 95a1ceb080 feat: add info skills to alexa devices (#162097) 2026-02-11 11:23:07 +01:00
dvdinth 3f9e7d1dba Add IntelliClima integration and tests (#157363)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-11 11:18:26 +01:00
epenet eab80f78d9 Raise on missing color mode (#162715) 2026-02-11 11:12:52 +01:00
Robert Resch aa9fdd56ec Bump cryptography to 46.0.5 (#162783) 2026-02-11 11:09:54 +01:00
epenet c727261f67 Move matter fixture list to a constant (#162776) 2026-02-11 10:47:09 +01:00
jameson_uk 703c62aa74 Bump aioamazondevices to 12.0.0 (#162778) 2026-02-11 10:21:11 +01:00
Tomás Correia 6e1f90228b fix to cloudflare r2 setup screen info (#162677) 2026-02-10 23:43:59 +01:00
LeoXie 3be089d2a5 Add Matter CO alarm state (#162627)
Co-authored-by: Ludovic BOUÉ <lboue@users.noreply.github.com>
2026-02-10 23:43:32 +01:00
Noah Husby 692d3d35cc Bump aiostreammagic to 2.12.1 (#162744) 2026-02-10 23:26:20 +01:00
starkillerOG c52cb8362e Bump reolink-aio to 0.19.0 (#162672) 2026-02-10 23:24:55 +01:00
Boaz Cahlon 93ac215ab4 Add integration for Hegel Music Systems amplifiers (#153867)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-10 22:56:48 +01:00
Michael f9eb86b50a Improve recognizability of Wi-Fi qr code in FRITZ!Box Tools (#162752) 2026-02-10 21:55:20 +00:00
Christian Lackas a7f9992a4e Bump homematicip to 2.6.0 (#162702)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-02-10 21:52:09 +00:00
Andreas Jakl 13fde0d135 Bump nrgkick-api to 1.7.1 (#162738) 2026-02-10 19:26:51 +01:00
tronikos 5105c6c50f Add last_changed and last_updated for the Opower statistics (#159101) 2026-02-10 17:08:58 +00:00
Josef Zweck af152ebe50 Bump onedrive-personal-sdk to 0.1.2 (#162689) 2026-02-10 08:52:29 -08:00
Manu dea4452e42 Set device entry type and integration type to service in Portainer integration (#162732) 2026-02-10 08:51:03 -08:00
Maikel Punie af07631d83 migrate velbus config entries (#162565) 2026-02-10 16:14:00 +01:00
theobld-ww d2ca00ca53 Refactor Watts Vision+ to generic device, in preparation for switch support (#162721)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-10 16:08:30 +01:00
Jeef bb2f7bdfc4 Bump intellifire4py to 4.3.1 (#162659) 2026-02-10 14:21:58 +00:00
epenet b1379d9153 Fix flaky lunatone test (#162727) 2026-02-10 15:18:59 +01:00
Anrijs ea4b286659 Bump aranet lib version to 2.6.0 (#162656)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2026-02-10 16:03:16 +02:00
Norbert Rittel 2d00cb9a29 Improve descriptions of xiaomi_miio.vacuum_clean_segment action (#162698) 2026-02-10 05:47:46 -08:00
Christian Lackas 2ef1a20ae4 Add @lackas as code owner for homematicip_cloud (#162696) 2026-02-10 05:47:11 -08:00
Joost Lekkerkerker 95defddfff Add edenhaus as devcontainer codeowner (#162707) 2026-02-10 05:46:41 -08:00
J. Nick Koston 009bdd91cc Bump aioesphomeapi to 44.0.0 (#162712) 2026-02-10 14:21:56 +01:00
Manu 63bbead41e Add support for attachments from media sources in ntfy notifications (#152329)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-10 13:47:16 +01:00
MoonDevLT 2c9a96b62a Add config entry diagnostics to lunatone (#162406)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-10 13:18:23 +01:00
Brett Adams ace7fad62a Add exception translations to Teslemetry (#162141)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-10 12:22:59 +01:00
Brett Adams 3c73cc8bad Use icon translations for Teslemetry battery percent entities (#162140)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 12:15:30 +01:00
Petro31 83c41c265d Update template update to new template entity framework (#162561) 2026-02-10 11:39:29 +01:00
epenet c8bc5618dc Raise error when light reports invalid supported color modes (#162644) 2026-02-10 11:30:14 +01:00
Brandon Rothweiler 60d770f265 Bump py-aosmith to 1.0.17 (#162685) 2026-02-10 11:17:19 +01:00
joel-bourquard 6f4b9dcad7 Miele: Added support for Plate #5 on Miele KM 7699 (#162503) 2026-02-10 09:34:24 +01:00
ElCruncharino 1bba31f7af Fix AsyncIteratorReader blocking after stream exhaustion (#161731) 2026-02-10 09:21:52 +01:00
Ludovic BOUÉ 4705e584b0 Sort Matter fixture files list (#162693) 2026-02-10 07:41:50 +01:00
Ludovic BOUÉ 80bbe5df6a Add smoke detector test to Matter binary sensor tests (#162638) 2026-02-09 10:36:34 -08:00
Artur Pragacz 88c4d88e06 Simplify subscribe feature websocket in labs (#162646) 2026-02-09 17:05:43 +01:00
dependabot[bot] 718f459026 Bump actions/ai-inference from 2.0.5 to 2.0.6 (#162609)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-09 16:58:05 +01:00
XHyperDEVX 5c3ddcff3e Make “Reasoning Summary” configurable in OpenAI (#157557)
Co-authored-by: cto-new[bot] <140088366+cto-new[bot]@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-09 16:29:27 +01:00
Ludovic BOUÉ 08acececb2 Add local temperature calibration for all Matter thermostats (#161724)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2026-02-09 16:09:25 +01:00
epenet 27d6ae2881 Adjust openrgb default color mode handling (#162650) 2026-02-09 16:00:44 +01:00
Brett Adams 5c4d9f4ca4 Fix Tesla Fleet partner registration to use all regions (#162525)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 15:33:05 +01:00
MarkGodwin 9ece327881 Limit actions on omada controller to one at a time (#162499) 2026-02-09 14:42:37 +01:00
cdnninja 1b0ef3f358 Add drying mode switch to vesync (#161905)
Co-authored-by: Dave T <17680170+davet2001@users.noreply.github.com>
2026-02-09 14:30:25 +01:00
Petro31 a5eca0614a Update template weather platform to new template entity framework (#162569) 2026-02-09 14:26:19 +01:00
Aaron Godfrey 7b2509fadb Increase max tasks retrieved per page to prevent timeout (#162587) 2026-02-09 14:19:40 +01:00
epenet f6e0bc28f4 Raise error when light reports an invalid color_mode (#162620) 2026-02-09 14:18:37 +01:00
Petro31 e87056408e Update template light to new entity framework (#162445) 2026-02-09 14:14:58 +01:00
Petro31 c945f32989 Update template fan platform to the new entity framework (#162328) 2026-02-09 14:13:23 +01:00
Ludovic BOUÉ 8d37917d8b Rename Matter Heiman smoke detector fixture file (#162632) 2026-02-09 14:05:13 +01:00
Artur Pragacz 68cc2dff53 Add subscribe preview feature helper to labs (#161778) 2026-02-09 14:03:02 +01:00
Andrea Turri 45babbca92 Add new Miele mappings (#162544) 2026-02-09 13:53:47 +01:00
Nick Beeuwsaert b56dcfb7e9 Add sensor state class to eufylife_ble (#162607) 2026-02-09 13:49:58 +01:00
Leonardo Merza a56114d84a Add slow mode option for SwitchBot curtains (#155272)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-09 13:30:14 +01:00
Allen Porter de8a26c5b0 Bump grpc to 1.78.0 (#162520) 2026-02-09 13:20:55 +01:00
epenet 48f39524c4 Fix matter light color_mode (#162637) 2026-02-09 13:20:37 +01:00
Aidan Timson 2b4ef312c3 Add translation for MFA code (#162635) 2026-02-09 13:16:18 +01:00
epenet b4d175b811 Adjust esphome light test (#162633) 2026-02-09 12:48:14 +01:00
epenet 7ff6c2a421 Add missing features in tplink light tests (#162631) 2026-02-09 12:47:56 +01:00
dependabot[bot] cf0a438f32 Bump j178/prek-action from 1.1.0 to 1.1.1 (#162610)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-09 11:02:04 +01:00
epenet 9e1bfa3564 Cleanup mired light test (#162622) 2026-02-09 09:55:58 +01:00
Petro31 3c266183e1 Add new template entity framework to event platform (#162228) 2026-02-09 07:54:40 +01:00
epenet 5c5f5d064a Remove legacy fallback in light color_mode property (#162276) 2026-02-09 07:54:07 +01:00
Michael fc18ec4588 Bump aioimmich to 0.12.0 (#162573)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-08 23:51:24 +01:00
Thomas55555 3fd2fa27e7 Bump aioautomower to 2.7.3 (#162583)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-08 23:49:36 +01:00
Andres Ruiz cf637f8c2f Update waterfurnace integration to use Coordinator, instead of its own thread. (#161494)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-08 23:39:23 +01:00
Joost Lekkerkerker 228fca9f0c Pin setuptools to 81.0.0 (#162589)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-08 23:10:25 +01:00
tan-lawrence c5ce8998e2 Deprecate unknown fan mode in coolmaster (#161737)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-08 23:05:14 +01:00
Petro31 a4204bf11e Update template lock platform to new template entity framework (#162493) 2026-02-08 23:03:55 +01:00
mettolen 3e44d15fc1 Add diagnostics to Liebherr integration (#162360)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-08 22:52:56 +01:00
Norbert Rittel 4f07d8688c Sentence-case "speech-to-text" in google_cloud (#162534) 2026-02-08 22:50:12 +01:00
Petro31 89fda1a4ae update template number platform to new template entity framework (#162540) 2026-02-08 22:42:11 +01:00
Andres Ruiz f678e7ef34 Add additional sensors for waterfurnace integration (#162581) 2026-02-08 22:38:21 +01:00
Petro31 24e8208deb Update template select platform to new template entity framework (#162543) 2026-02-08 22:27:49 +01:00
Petro31 3c66a1b35d Update template vacuum platform to new template entity framework (#162564) 2026-02-08 22:27:21 +01:00
Petro31 5a2299e8b6 Update template switch platform to new template entity framework (#162556) 2026-02-08 22:25:38 +01:00
Noah Husby 8087953b90 Bump aiostreammagic to 2.12.0 (#162570) 2026-02-08 21:53:29 +01:00
Thomas55555 77a15b44c9 Increase polling in Husqvarna Automower (#162582) 2026-02-08 21:50:42 +01:00
hanwg 2177b494b9 Fix config flow bug for Telegram bot (#162555) 2026-02-08 21:32:51 +01:00
Peter Grauvogel 10497c2bf4 Fix Green Planet Energy price unit conversion (#162511) 2026-02-08 21:07:32 +01:00
Petro31 e7fd744941 Update template sensor platform to new template entity framework (#162554) 2026-02-08 21:01:31 +01:00
Elias Wernicke b9bfbc9e98 Validate conversation_command in start timer intent (#149915)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2026-02-08 19:56:07 +01:00
Robert Svensson ba6f1343cc Add regression testing to Axis OUI support list (#162508) 2026-02-08 19:19:09 +01:00
Jaap Pieroen 0d07d4bc69 Bump essent-dynamic-pricing to 0.3.1 (#160958)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-08 10:03:20 +01:00
Norbert Rittel 94931a21fb Sentence-case "text-to-speech" and "speech-to-text" in elevenlabs (#162533) 2026-02-08 09:16:27 +01:00
Norbert Rittel ce295605ad Sentence-case "text-to-speech" and "speech-to-text" (#162532) 2026-02-08 09:11:58 +01:00
Denis Shulyaka 9e371fd083 Use hass httpx client for Anthropic (#162518) 2026-02-08 06:51:11 +01:00
Denis Shulyaka 9fa5a843cb Fix JSON serialization of datetime objects in Google Generative AI tool results (#162495) 2026-02-07 22:13:57 +01:00
Denis Shulyaka 8b5fb407e5 Fix JSON serialization of time objects in Open Router tool results (#162505) 2026-02-07 22:11:18 +01:00
Denis Shulyaka 8ef1e25f8c Fix JSON serialization of time objects in Ollama tool results (#162502)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-07 21:15:13 +01:00
Denis Shulyaka ce3dd2b6db Fix JSON serialization of time objects in OpenAI tool results (#162490) 2026-02-07 21:13:38 +01:00
Denis Shulyaka a98010d0c1 Fix JSON serialization of time objects in Cloud conversation tool results (#162506) 2026-02-07 21:08:39 +01:00
Shay Levy a915a69886 Add coverage for Shelly init (#162497) 2026-02-07 19:46:28 +02:00
cdnninja bb4ffd8c6e Add vesync Data Types (#162461) 2026-02-07 15:54:07 +00:00
epenet 403710354b Use shorthand attributes in tasmota lights (#162290) 2026-02-07 11:59:37 +01:00
Markus 9b3743a8bc Update snapcast to 2.3.7 (#162452) 2026-02-07 09:42:17 +01:00
rrooggiieerr 9642ff63ca Remove duplicate call of format_mac() (#162469) 2026-02-07 09:17:45 +01:00
Brett Adams 5a1862431e Fix device_class of backup reserve sensor in teslemetry (#162458) 2026-02-07 08:26:12 +01:00
Brett Adams efed2b75a5 Fix device_class of backup reserve sensor in Tessie (#162459) 2026-02-07 08:25:48 +01:00
epenet 5a87a8805e Add hassfest check for action-setup IQS (#162084)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-06 22:26:18 +01:00
Jonathan 8c48084b3f Fix device_class of backup reserve sensor (#161178) 2026-02-06 21:36:53 +01:00
arstom 60fd442ed7 Add ebusd sensors for Vaillant 700 (#161180)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-02-06 21:30:33 +01:00
epenet 1d6c5a283e Fix redundant off preset in Tuya climate (#161040) 2026-02-06 20:58:22 +01:00
Thomas55555 a53f876e09 Bump ruff to 0.15.0 (#162356)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-06 19:39:32 +01:00
jameson_uk 88d894212b dep: bump aioamazondevices to 11.1.3 (#162437) 2026-02-06 19:37:34 +01:00
Artur Pragacz f2d4319366 Make bad entity ID detection more lenient (#162425) 2026-02-06 15:58:27 +01:00
epenet 3eb8d64381 Fix invalid yardian snaphots (#162422) 2026-02-06 15:52:58 +01:00
epenet 818ce549d9 Remove duplicate class field in incomfort (#162420) 2026-02-06 15:16:20 +01:00
epenet db7800d170 Simplify (in-)equality checks (#162416) 2026-02-06 15:11:22 +01:00
epenet bc1c24efb1 Improve (r)split performance (#162418) 2026-02-06 15:10:30 +01:00
David Recordon 5ad632c34a Add Fan mode support to Control4 integration (#159980) 2026-02-06 14:11:18 +01:00
Sab44 65f95e5c4b Bump librehardwaremonitor-api to version 1.9.1 (#162409) 2026-02-06 14:04:21 +01:00
Joost Lekkerkerker bb406594d1 Remove double unit of measurement for yardian (#162412) 2026-02-06 14:03:57 +01:00
epenet b7a7b7bc63 Cleanup unnecessary brackets for except statements (a-h) (#162404) 2026-02-06 13:48:56 +01:00
epenet 1c59d846e3 Cleanup unnecessary brackets for except statements (core) (#162410) 2026-02-06 13:45:59 +01:00
Joost Lekkerkerker 3b40bb7d28 Remove entity id overwrite for ambient station (#162403) 2026-02-06 13:39:51 +01:00
epenet a171e17097 Cleanup unnecessary brackets for except statements (q-z) (#162408) 2026-02-06 13:31:56 +01:00
epenet c881d96d2f Cleanup unnecessary brackets for except statements (i-p) (#162405) 2026-02-06 13:23:25 +01:00
Luo Chen f1a99a2d65 Fix unicode escaping in MCP server tool response (#162319)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-06 13:11:28 +01:00
mettolen d02adabe5d Add Start session action to Saunum integration (#162177) 2026-02-06 12:47:50 +01:00
Mark Jansen 286730165d Simplify sun condition schema by re-using an existing type (#161894)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-02-06 12:27:16 +01:00
epenet 95a58252cf Reformat lambda (tests) (#162383) 2026-02-06 12:24:58 +01:00
epenet bf6643643b Reformat lambda (core) (#162382) 2026-02-06 12:24:48 +01:00
epenet 8d780d6712 Reformat lambda (t-z) (#162381) 2026-02-06 12:24:37 +01:00
epenet 576c7227c6 Reformat lambda (m-s) (#162379) 2026-02-06 12:24:19 +01:00
epenet 915d375f0a Reformat lambda (a-l) (#162377) 2026-02-06 12:24:12 +01:00
Petro31 e9487a81a7 Update template image platform to new entity framework (#162343) 2026-02-06 12:20:11 +01:00
Andres Ruiz 0a2fe01b66 Add device_info to waterfurnace sensors (#162080)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-06 12:17:27 +01:00
Peter Grauvogel 9de9bde7d8 Add timestamp sensors for highest and lowest price times (#161639) 2026-02-06 12:04:39 +01:00
epenet fbc91d3d3d Remove str from sensor state class (#161686) 2026-02-06 12:01:23 +01:00
Abílio Costa 47672614df Remove external url from config for local_only users (#161891) 2026-02-06 12:00:07 +01:00
Denis Shulyaka 8c01c4a155 Add gpt-image-1.5 model support (#162208) 2026-02-06 11:57:00 +01:00
Aaron Godfrey 5dc7f8bfe3 Fix conversion of data for todo.* actions (#162366) 2026-02-06 11:52:01 +01:00
epenet cc01d15d74 Use StrEnum in eq3btsmart (#162387) 2026-02-06 11:51:00 +01:00
epenet 5c980e8d97 Cleanup ternary if expressions (#162394) 2026-02-06 11:50:47 +01:00
epenet c01e3beb2e Use StrEnum in stt (#162389) 2026-02-06 11:50:35 +01:00
Jan Bouwhuis a5b16e3694 Remove parentheses for except statements where it is not needed in mqtt integration (#162398) 2026-02-06 11:49:42 +01:00
epenet 866cd52ada Cleanup default None value from dict.get (#162396) 2026-02-06 11:49:02 +01:00
John O'Nolan 2d308aaa20 Add Ghost integration (#162041)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-06 11:47:53 +01:00
epenet 0456eb54ee Use StrEnum in unifiprotect (#162390) 2026-02-06 11:42:34 +01:00
epenet ce6fced6a4 Use StrEnum in intent helper (#162391) 2026-02-06 11:41:58 +01:00
epenet fc56f52c74 Use StrEnum in modbus (#162388) 2026-02-06 11:41:29 +01:00
dependabot[bot] f7e65eeece Bump github/codeql-action from 4.32.1 to 4.32.2 (#162369)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-06 11:33:24 +01:00
epenet 8c94de4a9c Use StrEnum in easyenergy (#162386) 2026-02-06 12:15:42 +02:00
epenet 46971c1c82 Use StrEnum in cloud (#162385) 2026-02-06 12:15:09 +02:00
epenet fb5c3c7eb6 Use StrEnum in uptimerobot tests (#162392) 2026-02-06 12:14:28 +02:00
Anders Ödlund ea42237444 Add dismiss protection to config flows (#162270)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-02-06 10:59:37 +01:00
Matt Zimmerman 2a76c2678e Add missing config flow strings to SmartTub (#162375)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 08:53:00 +01:00
Manu 72b6e5fabe Add remote action exceptions to Xbox (#162347) 2026-02-06 08:27:31 +01:00
Jordan Harvey f739fc1f55 Update pynintendoparental requirement to version 2.3.2.1 (#162362) 2026-02-06 08:26:51 +01:00
Denis Shulyaka aecfca5020 Add Claude Opus 4.6 support (#162365) 2026-02-06 08:25:53 +01:00
Matt Zimmerman f024ae442f Add PARALLEL_UPDATES to SmartTub platform files (#162373)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 08:21:33 +01:00
Matt Zimmerman 07a9aad4a4 Bump python-smarttub to 0.0.47 (#162367)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 08:14:42 +01:00
Denis Shulyaka 22ab58077e Bump anthropic to 0.78.0 (#162349) 2026-02-05 22:15:16 +01:00
epenet 4b666688c9 Adjust color mode handling in esphome lights (#162294) 2026-02-05 21:04:21 +01:00
Shay Levy d118332366 Fix Shelly Linkedgo Thermostat status update (#162339) 2026-02-05 20:52:21 +01:00
Michael Potthoff 9f32e0da14 Add type option "first_available" to sensor group in group component (#155525) 2026-02-05 20:26:45 +01:00
Andre Lengwenus 1cef223a06 Bump pypck to 0.9.10 (#162333) 2026-02-05 20:14:04 +01:00
epenet 29da1233f3 Fix missing color_mode attribute in mqtt light (#162311)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-05 18:22:57 +01:00
Arie Catsman a5b3d22058 Bump pyenphase to 2.4.5 (#162324) 2026-02-05 17:42:45 +01:00
jameson_uk d37e958a0b Add config entry tests to alexa_devices (#162295) 2026-02-05 13:07:14 +00:00
epenet 0498ac7364 Migrate supported_color_modes to shorthand attribute in zwave_js lights (#162296) 2026-02-05 13:56:20 +01:00
epenet 67bdeb9945 Adjust unknown color mode handling in ZHA lights (#162292) 2026-02-05 12:30:06 +01:00
Oliver a227307387 Add support for media_stop command for denonavr receivers (#162236) 2026-02-05 12:17:25 +01:00
Oliver 0e0309cabf Add mapping for stopped state to denonavr media player (#162283) 2026-02-05 12:15:14 +01:00
epenet fd2dfc83c6 Use shorthand attributes in zwave_js lights (#162293) 2026-02-05 12:05:08 +01:00
epenet 9e736891c4 Use shorthand attributes in demo lights (#162282) 2026-02-05 12:02:41 +01:00
Oliver fbabf0dcb8 Bump denonavr to 1.3.2 (#162271) 2026-02-05 11:59:10 +01:00
Tomás Correia 7128791152 Fix multipart upload to use consistent part sizes for R2/S3 (#162278) 2026-02-05 11:54:02 +01:00
epenet 94456b5bc3 Improve type hints in tradfri lights (#162287) 2026-02-05 11:51:34 +01:00
epenet 2105c6b177 Improve type hints in switchbot lights (#162286) 2026-02-05 11:46:50 +01:00
Robin Lintermann 34156f79e8 Bump pysmarlaapi to 0.13.0 (#162277) 2026-02-05 11:45:29 +01:00
epenet bb1a2530f5 Improve type hints in nanoleaf lights (#162284) 2026-02-05 11:44:54 +01:00
epenet 06613746f9 Remove unnecessary shorthand attribute init in template (#162279) 2026-02-05 11:41:57 +01:00
epenet 98ca948afe Improve type hints in abode lights (#162281) 2026-02-05 11:35:43 +01:00
Krisjanis Lejejs fa58fe5f4e Bump hass-nabucasa from 1.12.0 to 1.13.0 (#162274) 2026-02-05 11:03:44 +01:00
Petro31 46f230c487 Clean up unused cover constants (#162225) 2026-02-05 10:46:36 +01:00
epenet 13a987aba3 Cleanup deprecated SUPPORT_ light constants (#162210) 2026-02-05 10:32:32 +01:00
cdnninja 9cef323581 Update Vesync quality-scale to Bronze (#162260) 2026-02-05 09:44:47 +01:00
epenet 7ea7576188 Cleanup legacy support for extracting color modes from light supported features (#162265) 2026-02-05 09:33:22 +01:00
Franck Nijhof f8abbfd42b Merge branch 'master' into dev 2026-02-05 08:17:24 +00:00
Erik Montnemery 5cd1821bc9 Update redgtech snapshots (#162267) 2026-02-05 09:13:13 +01:00
Norbert Rittel 2ef7f26ffb Improve description of camera.play_stream action (#162264) 2026-02-05 09:07:10 +01:00
Jonathan Sady do Nascimento 184bea49e2 Add redgtech integration (#136947)
Co-authored-by: luan-nvg <luannnvg@gmail.com>
2026-02-05 09:04:14 +01:00
David Bonnes c853fb2068 Bump evohome-async to 1.1.3 (#162232) 2026-02-05 08:25:30 +01:00
mettolen 79e0a93e48 Upgrade Liebherr integration to Silver (#162178) 2026-02-04 22:24:53 +01:00
Andres Ruiz 3867c1d7d1 Extract waterfurnace sensor names for translation (#162025)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-04 21:48:23 +01:00
Thomas55555 b9b6b050cc Bump google_air_quality_api to 3.0.1 (#162233) 2026-02-04 21:46:07 +01:00
Muhammad Hamza Khan d960736b3d Improve typing in syncthing (#162193)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-04 21:43:13 +01:00
Franck Nijhof 3e8923f105 2026.2.0 (#162224) 2026-02-04 20:35:11 +01:00
Franck Nijhof 17cca3e69d Bump version to 2026.2.0 2026-02-04 18:53:49 +00:00
Franck Nijhof 12714c489f Bump version to 2026.2.0b5 2026-02-04 18:45:36 +00:00
Robert Resch f788d61b4a Revert "Bump intents (#162205)" (#162226) 2026-02-04 18:36:12 +00:00
Simone Chemelli 5c726af00b Fix logic and tests for Alexa Devices utils module (#162223) 2026-02-04 18:36:10 +00:00
Joost Lekkerkerker d1d207fbb2 Add guard for Apple TV text focus state (#162207) 2026-02-04 18:36:09 +00:00
David Bonnes 6c7f8df7f7 Fix evohome not updating scheduled setpoints in state attrs (#162043) 2026-02-04 18:36:07 +00:00
Kevin Stillhammer 6f8c9b1504 Bump fressnapftracker to 0.2.2 (#161913) 2026-02-04 18:36:06 +00:00
Kevin Stillhammer 4f9aedbc84 Filter out invalid trackers in fressnapf_tracker (#161670) 2026-02-04 18:36:04 +00:00
Joost Lekkerkerker afa0f572ce Add guard for Apple TV text focus state (#162207) 2026-02-04 19:34:53 +01:00
Simone Chemelli a6a1b9ddbd Fix logic and tests for Alexa Devices utils module (#162223) 2026-02-04 19:31:57 +01:00
Robert Resch c1f5b4593f Revert "Bump intents (#162205)" (#162226) 2026-02-04 19:30:05 +01:00
Kevin Stillhammer f1de4dc1cc Filter out invalid trackers in fressnapf_tracker (#161670) 2026-02-04 17:43:24 +01:00
David Bonnes 4ae0d9a9c6 Fix evohome not updating scheduled setpoints in state attrs (#162043) 2026-02-04 17:37:41 +01:00
David Girón fcd0b579cf Compress container image with zstd (#160665)
Co-authored-by: Robert Resch <robert@resch.dev>
2026-02-04 17:28:07 +01:00
Franck Nijhof 52fb0343e4 Bump version to 2026.2.0b4 2026-02-04 16:14:23 +00:00
Bram Kragten 1050b4580a Update frontend to 20260128.6 (#162214) 2026-02-04 16:10:08 +00:00
Åke Strandberg 344c42172e Add missing codes for Miele coffe systems (#162206) 2026-02-04 16:10:06 +00:00
Michael Hansen 93cc0fd7f1 Bump intents (#162205) 2026-02-04 16:10:05 +00:00
andreimoraru 05fe636b55 Bump yt-dlp to 2026.02.04 (#162204)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-04 16:10:03 +00:00
Marc Mueller f22467d099 Pin auth0-python to <5.0 (#162203) 2026-02-04 16:10:01 +00:00
TheJulianJES 4bc3899b32 Bump ZHA to 0.0.89 (#162195) 2026-02-04 16:10:00 +00:00
Oliver fc4d6bf5f1 Bump denonavr to 1.3.1 (#162183) 2026-02-04 16:09:58 +00:00
johanzander 8ed0672a8f Bump growattServer to 1.9.0 (#162179)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:09:57 +00:00
Norbert Rittel 282e347a1b Clarify action descriptions in media_player (#162172) 2026-02-04 16:09:55 +00:00
Erik Montnemery 1bfb02b440 Bump python-otbr-api to 2.8.0 (#162167) 2026-02-04 16:09:54 +00:00
Przemko92 71b03bd9ae Bump compit-inext-api to 0.8.0 (#162166) 2026-02-04 16:09:52 +00:00
Przemko92 cbd69822eb Update compit-inext-api to 0.7.0 (#162020) 2026-02-04 16:09:51 +00:00
Denis Shulyaka db900f4dd2 Anthropic repair deprecated models (#162162)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-04 16:00:14 +00:00
Jonathan Bangert a707e695bc Bump bleak-esphome to 3.6.0 (#162028) 2026-02-04 16:00:12 +00:00
Liquidmasl 4feceac205 Jellyfin native client controls (#161982) 2026-02-04 16:00:11 +00:00
Petro31 10c20faaca Fix template weather humidity (#161945) 2026-02-04 16:00:09 +00:00
Robert Svensson abcd512401 Add missing OUI to Axis integration, discovery would abort with unsup… (#161943) 2026-02-04 16:00:07 +00:00
Bram Kragten dee7a237ee Update frontend to 20260128.6 (#162214) 2026-02-04 16:58:12 +01:00
Åke Strandberg 3975eba12c Add missing codes for Miele coffe systems (#162206) 2026-02-04 15:06:35 +01:00
epenet ade91ebdab Cleanup deprecated COLOR_MODE light constants (#162197) 2026-02-04 15:00:12 +01:00
Norbert Rittel 1bf194dd0f Clarify action descriptions in media_player (#162172) 2026-02-04 14:58:40 +01:00
Manu 2eca8db8aa Add action exceptions to Xbox integration (#162198) 2026-02-04 14:56:52 +01:00
Robert Svensson 78415bc1ff Add missing OUI to Axis integration, discovery would abort with unsup… (#161943) 2026-02-04 14:43:04 +01:00
Denis Shulyaka e2469bcd0f Anthropic repair deprecated models (#162162)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-04 14:40:31 +01:00
Michael Hansen 54d64b7da2 Bump intents (#162205) 2026-02-04 14:25:28 +01:00
Erik Montnemery d548f3d12f Bump python-otbr-api to 2.8.0 (#162167) 2026-02-04 14:23:02 +01:00
epenet 668995da73 Fix incorrect exception in telegram_bot (#162191) 2026-02-04 13:32:29 +01:00
epenet 9eeae8eac6 Improve typing in telegram_bot (#162190) 2026-02-04 12:15:23 +00:00
andreimoraru 7e7056aa94 Bump yt-dlp to 2026.02.04 (#162204)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-04 12:07:40 +00:00
epenet b633b8d271 Fix test_before_setup IQS check (#162187)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-04 12:41:59 +01:00
Marc Mueller 45c7b9ccb8 Pin auth0-python to <5.0 (#162203) 2026-02-04 12:19:49 +01:00
dependabot[bot] 3ad1a57dfc Bump github/codeql-action from 4.32.0 to 4.32.1 (#162118)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-04 10:40:44 +01:00
Brandon Rothweiler 3cbe236a36 Bump py-aosmith to 1.0.16 (#162160) 2026-02-04 10:40:09 +01:00
Przemko92 39816c1e8a Bump compit-inext-api to 0.8.0 (#162166) 2026-02-04 10:39:12 +01:00
johanzander 5587dd43b9 Bump growattServer to 1.9.0 (#162179)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 10:38:18 +01:00
Jonathan Bangert 715d1e4eb8 Bump bleak-esphome to 3.6.0 (#162028) 2026-02-04 10:34:30 +01:00
Oliver af172fb70d Bump denonavr to 1.3.1 (#162183) 2026-02-04 10:33:44 +01:00
TheJulianJES 8c8bc104eb Bump ZHA to 0.0.89 (#162195) 2026-02-04 10:27:23 +01:00
Liquidmasl 51b20fb5db Adjust radarr constants and strings (#162159) 2026-02-04 10:16:47 +01:00
Kamil Breguła 445ba26667 Enable check for duplicate exception handlers (#162169)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-02-04 10:14:46 +01:00
epenet 886448f4ba Cleanup deprecated mired handling in light platform (#161777) 2026-02-04 09:52:53 +01:00
Petro31 ede4341ef3 Fix template weather humidity (#161945) 2026-02-04 08:02:09 +01:00
Liquidmasl fe363f32ec Jellyfin native client controls (#161982) 2026-02-03 20:18:59 +01:00
Kamil Breguła 31562e7571 Remove duplicated exception handler in overkiz (#162171)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2026-02-03 20:16:06 +01:00
Kamil Breguła 0bdb51e4ca Remove duplicated exception handler in systemmonitor (#162170)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
2026-02-03 20:14:37 +01:00
epenet 67a5d7ac21 Move neato service registration (#162146) 2026-02-03 20:05:12 +01:00
epenet 5e7f06c476 Move sharkiq service registration (#162147) 2026-02-03 19:52:54 +01:00
epenet 9a69852296 Move xiaomi_miio service registration (#162148) 2026-02-03 19:48:39 +01:00
Bram Kragten fdf8edf474 Bump version to 2026.2.0b3 2026-02-03 18:03:54 +01:00
Bram Kragten 47e1a98bee Update frontend to 20260128.5 (#162156) 2026-02-03 18:03:04 +01:00
Joost Lekkerkerker 2d8572b943 Add Heatit virtual brand (#162155) 2026-02-03 18:03:02 +01:00
Joost Lekkerkerker 660cfdbd50 Add Heiman virtual brand (#162152) 2026-02-03 18:03:00 +01:00
Steven Travers 4208595da6 Modify Analytics text on feature labs (#162151) 2026-02-03 18:02:59 +01:00
Paul Bottein b6b2d2fc6f Update title and description of YAML dashboard repair (#162138) 2026-02-03 18:02:58 +01:00
victorigualada 6c4c632848 Handle chat log attachments in Cloud integration (#162121) 2026-02-03 18:02:57 +01:00
Shay Levy 78cf62176f Fix Shelly xpercent sensor state_class (#162107) 2026-02-03 18:02:56 +01:00
Denis Shulyaka df971c7a42 Anthropic: Switch default model to Haiku 4.5 (#162093) 2026-02-03 18:02:55 +01:00
mezz64 1fcabb7f2d Bump pyhik to 0.4.2 (#162092)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-03 18:02:53 +01:00
Åke Strandberg 9fb60c9ea2 Update Senz temperature sensor (#162016) 2026-02-03 18:02:52 +01:00
J. Diego Rodríguez Royo 9c11a4646f Remove coffee machine's hot water sensor's state class at Home Connect (#161246) 2026-02-03 17:58:47 +01:00
jameson_uk b036a78776 Remove invalid notification sensors for Alexa devices (#160422)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2026-02-03 17:58:45 +01:00
Kamil Breguła 60bb3cb704 Handle missing battery stats in systemmonitor (#158287)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-03 17:58:43 +01:00
Bram Kragten a722925b8e Update frontend to 20260128.5 (#162156) 2026-02-03 17:57:15 +01:00
Joost Lekkerkerker 419c5de50e Add Heiman virtual brand (#162152) 2026-02-03 17:20:25 +01:00
Joost Lekkerkerker 37faed565e Add Heatit virtual brand (#162155) 2026-02-03 17:19:50 +01:00
Paul Bottein 622953e61f Update title and description of YAML dashboard repair (#162138) 2026-02-03 17:09:23 +01:00
Steven Travers 17926c3f6a Modify Analytics text on feature labs (#162151) 2026-02-03 16:09:34 +01:00
victorigualada 48d85170c2 Handle chat log attachments in Cloud integration (#162121) 2026-02-03 15:54:56 +01:00
epenet 08d179c520 Move ecovacs service registration (#162145) 2026-02-03 15:50:17 +01:00
hanwg 5752387da8 Add entity_id parameter for Telegram bot actions (#159745)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-02-03 15:34:39 +01:00
Sebastiaan Speck 1ebde65f03 Add sound horn and flash lights buttons to Renault (#161976)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-03 15:18:55 +01:00
Denis Shulyaka 89f536e332 Anthropic: Switch default model to Haiku 4.5 (#162093) 2026-02-03 14:12:21 +01:00
Shay Levy 8784329333 Fix Shelly xpercent sensor state_class (#162107) 2026-02-03 14:11:55 +01:00
Marc Mueller d73538722d Use Generator and AsyncGenerator for contextmanager typing (#162144) 2026-02-03 13:52:33 +01:00
Brett Adams d49d3f0a2f Mark test-coverage as done for Teslemetry quality scale (#161958)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-03 12:57:14 +01:00
Blaine Cook 8466dd4c2b Add temperature sensor to Huum integration (#161405)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-03 12:38:39 +01:00
Brett Adams 6bb1e688c6 Mark reconfiguration-flow as done for Teslemetry (#162139)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 12:37:24 +01:00
epenet 9bc1c4c4f3 Simplify reolink method arguments (#162137) 2026-02-03 12:23:33 +01:00
jameson_uk a554cb8211 Remove invalid notification sensors for Alexa devices (#160422)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2026-02-03 11:48:57 +01:00
Liquidmasl 145d38403e Add get_queue and get_movies service calls to Radarr (#160753)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-03 11:30:30 +01:00
Erwin Douna 10d4af5674 Use asyncio.gather pattern in portainer (#160888) 2026-02-03 11:23:34 +01:00
Brett Adams ed3b4d2de3 Fix oauth debug log bug in Teslemetry (#161652) 2026-02-03 11:16:45 +01:00
epenet e66d324877 Move openhome service registration (#162127) 2026-02-03 11:15:53 +01:00
epenet f7f18627a2 Move squeezebox service registration (#162132) 2026-02-03 11:15:28 +01:00
epenet d18630020f Move songpal service registration (#162131) 2026-02-03 11:15:05 +01:00
epenet a715ec318c Move snapcast service registration (#162130) 2026-02-03 11:14:39 +01:00
epenet 0ef5a77dc9 Move roon service registration (#162129) 2026-02-03 11:14:06 +01:00
epenet b43abf83b8 Move roku service registration (#162128) 2026-02-03 11:13:19 +01:00
epenet 84d28db3a7 Move linkplay service registration (#162126) 2026-02-03 11:12:32 +01:00
epenet 74d99fa0be Move denonavr service registration (#162123) 2026-02-03 11:12:04 +01:00
epenet 3ff0320ed8 Move vizio service registration (#162133) 2026-02-03 11:11:19 +01:00
epenet 16cb9e9785 Move kodi service registration (#162125) 2026-02-03 11:10:41 +01:00
epenet d92279dfcb Move epson service registration (#162124) 2026-02-03 11:10:10 +01:00
Kamil Breguła 4b9d28d0e5 Handle missing battery stats in systemmonitor (#158287)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-02-03 10:54:31 +01:00
Wendelin e6a60dfe50 Add option to use frontend PR artifact to frontend integration (#161291)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2026-02-03 10:23:25 +01:00
Tom d219056e9d Add target_humidity_step attribute to climate (#160418) 2026-02-03 09:34:31 +02:00
epenet 6ff6b099b5 Move bring service registration (#162077) 2026-02-03 07:42:03 +01:00
Brett Adams c5b9699098 Add model_id and sw_version to Teslemetry device info (#161959)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:58:02 +01:00
mettolen 6937bfdf67 Add number entity to Liebherr integration (#162011) 2026-02-02 21:48:39 +01:00
epenet 39ee3fcfaa Move bond service registration (#162075) 2026-02-02 21:47:30 +01:00
J. Diego Rodríguez Royo 16cdfd05a0 Remove coffee machine's hot water sensor's state class at Home Connect (#161246) 2026-02-02 21:30:43 +01:00
mezz64 f49d4787be Bump pyhik to 0.4.2 (#162092)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-02-02 21:22:42 +01:00
epenet 2076700dc4 Move rainbird service registration (#162089) 2026-02-02 21:02:57 +01:00
Åke Strandberg 76c135913e Update Senz temperature sensor (#162016) 2026-02-02 20:10:46 +01:00
epenet c3534d5445 Mark tts method type hints as mandatory (#161235) 2026-02-02 19:49:55 +01:00
epenet fc60b16d65 Mark device_tracker method type hints as mandatory (#161232) 2026-02-02 19:49:26 +01:00
epenet 0443c93f77 Move webostv service registration (#162091) 2026-02-02 20:48:21 +02:00
Bram Kragten 0e770958ac Bump version to 2026.2.0b2 2026-02-02 19:12:33 +01:00
Bram Kragten 2a54c71b6c Update frontend to 20260128.4 (#162096) 2026-02-02 19:11:59 +01:00
Steven Travers 50463291ab Add learn more data for Analytics in labs (#162094) 2026-02-02 19:11:59 +01:00
Andrea Turri 43cc34042a Fix Miele dishwasher PowerDisk filling level sensor not showing up (#162048) 2026-02-02 19:11:58 +01:00
Jan Bouwhuis a02244ccda Bump incomfort-client to 0.6.12 (#162037) 2026-02-02 19:11:57 +01:00
Adrián Moreno a739619121 Bump pymeteoclimatic to 0.1.1 (#162029) 2026-02-02 19:11:56 +01:00
Åke Strandberg 5db97a5f1c Improved error checking during startup of SENZ (#162026) 2026-02-02 19:11:54 +01:00
Josef Zweck 804ba9c9cc Remove file description dependency in onedrive (#162012) 2026-02-02 19:11:53 +01:00
Filip Bårdsnes Tomren 5ecbcea946 Update ical requirement version to 12.1.3 (#162010) 2026-02-02 19:11:52 +01:00
hanwg 11be2b6289 Fix parse_mode for Telegram bot actions (#162006) 2026-02-02 19:11:51 +01:00
cdnninja eefae0307b Add integration type of hub to vesync (#162004) 2026-02-02 19:11:50 +01:00
Matthias Alphart d397ee28ea Fix KNX fan unique_id for switch-only fans (#162002) 2026-02-02 19:11:49 +01:00
starkillerOG 02c821128e Bump reolink-aio to 0.18.2 (#161998) 2026-02-02 19:11:48 +01:00
Shay Levy 71dc15d45f Fix Shelly CoIoT repair issue (#161973)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-02 19:11:47 +01:00
Raphael Hehl 1078387b22 Bump uiprotect to version 10.1.0 (#161967)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-02-02 19:11:46 +01:00
tronikos 35fab27d15 Bump opower to 0.17.0 (#161962) 2026-02-02 19:11:45 +01:00
Yuxin Wang 915dc7a908 Mark datetime sensors as unknown when parsing fails (#161952) 2026-02-02 19:11:44 +01:00
mvn23 e5a9738983 Fix OpenTherm Gateway button availability (#161933) 2026-02-02 19:11:43 +01:00
mvn23 2ff73219a2 Bump pyotgw to 2.2.3 (#161928) 2026-02-02 19:11:42 +01:00
epenet 5dc1270ed1 Fix mired warning in template light (#161923) 2026-02-02 19:11:41 +01:00
J. Diego Rodríguez Royo 9e95ad5a85 Restore the Home Connect program option entities (#156401)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-02-02 19:11:40 +01:00
Bram Kragten f97cf0e446 Update frontend to 20260128.4 (#162096) 2026-02-02 19:03:38 +01:00
epenet bd4fa0d5c2 Move reolink service registration (#162085) 2026-02-02 19:02:09 +01:00
Steven Travers f60d367184 Add learn more data for Analytics in labs (#162094) 2026-02-02 17:22:01 +01:00
epenet 6e231f2ec5 Move husqvarna_automower service registration (#162087) 2026-02-02 17:08:41 +01:00
epenet 13ba2d2e47 Move litterrobot service registration (#162088) 2026-02-02 17:08:07 +01:00
epenet ba4a163e24 Move roborock service registration (#162090) 2026-02-02 17:07:44 +01:00
epenet b7db8684db Move elgato service registration (#162086) 2026-02-02 17:05:48 +01:00
Ludovic BOUÉ a7595dc468 Rename Matter Inovelli VTM31-SN fixture (#162076) 2026-02-02 15:49:11 +01:00
epenet d2c8c3565b Move blink service registration (#162078) 2026-02-02 14:49:05 +01:00
Ludovic BOUÉ 422d1031f4 Rename Matter Mock air purifier fixture file (#161937) 2026-02-02 14:43:27 +01:00
Viktor Andersson c9a79cf100 Update Electricity Maps translations (#162074)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-02-02 13:54:07 +01:00
epenet c42d47a619 Rename service registration function in growatt_server (#162073) 2026-02-02 13:32:33 +01:00
Ludovic BOUÉ a26f871d32 Rename Matter Mock devices (#161949) 2026-02-02 12:59:32 +01:00
Gage Benne d481c1bcc5 Improve accuracy of blood glucose conversion factor (#161644) 2026-02-02 12:19:16 +01:00
dependabot[bot] 379e3596b4 Bump dawidd6/action-download-artifact from 12 to 14 (#162058)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-02 10:55:15 +01:00
Jan Bouwhuis 423a7cdbba Bump incomfort-client to 0.6.12 (#162037) 2026-02-02 10:10:11 +01:00
Henning Kerstan 841fa48186 Replace hass.data[DATA_ENOCEAN] by config_entry.runtime_data (#161997) 2026-02-02 09:50:49 +01:00
Andres Ruiz 61e35157e3 Bump waterfurnace to 1.5.1 (#162042) 2026-02-02 08:59:53 +01:00
epenet 87f655f56d Move alarmdecoder service registration (#162063) 2026-02-02 08:59:47 +01:00
epenet 692b8d0722 Move agent_dvr service registration (#162062) 2026-02-02 08:59:35 +01:00
Luke Lashley 5f9f623c3f Bump python-roborock to 4.12.0 (#162054) 2026-02-01 20:28:35 -08:00
Przemko92 e595b6cd90 Update compit-inext-api to 0.7.0 (#162020) 2026-02-02 02:28:36 +01:00
Andrea Turri a748eebf3e Fix Miele dishwasher PowerDisk filling level sensor not showing up (#162048) 2026-02-02 02:18:02 +01:00
Adrián Moreno 6bdd544867 Bump pymeteoclimatic to 0.1.1 (#162029) 2026-02-02 00:44:29 +01:00
Luke Lashley 705eadf8ce Add the ability to select region for Roborock (#160898) 2026-02-01 11:50:34 -08:00
Josef Zweck b7c6e4eafc Remove file description dependency in onedrive (#162012) 2026-02-01 19:43:56 +01:00
Åke Strandberg f4aba286fe Improved error checking during startup of SENZ (#162026) 2026-02-01 19:42:27 +01:00
Yuxin Wang 5fa4f6de11 Mark datetime sensors as unknown when parsing fails (#161952) 2026-02-01 17:41:01 +01:00
Justus db1f045c42 bump iometer to v0.4.0 (#162027) 2026-02-01 17:32:03 +01:00
Erwin Douna eaba4817bd Optimize attribute lookup in DSMR Reader (#161994) 2026-02-01 15:26:00 +01:00
Erwin Douna 96cb2247df Remove unneeded NotImplementedError in Volvlo entity (#161990) 2026-02-01 15:25:23 +01:00
Matthias Alphart 99fa7a1f52 Fix KNX fan unique_id for switch-only fans (#162002) 2026-02-01 12:53:19 +01:00
Filip Bårdsnes Tomren e0ba928296 Update ical requirement version to 12.1.3 (#162010) 2026-02-01 12:43:34 +01:00
Tomasz 16fd5e8f1f Move initial_color to CalendarEntityDescription (#161831)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-02-01 11:01:05 +00:00
Brett Adams 201e95a417 Complete config-flow-test-coverage quality in Teslemetry (#161955)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 10:54:35 +01:00
dafal dc01592991 Bthome encryption downgrade (#159646)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
2026-02-01 09:40:47 +02:00
hanwg c5fb2bd566 Fix parse_mode for Telegram bot actions (#162006) 2026-02-01 08:37:23 +01:00
cdnninja d03d996155 Add integration type of hub to vesync (#162004) 2026-02-01 08:33:04 +01:00
starkillerOG 9618412a44 Bump reolink-aio to 0.18.2 (#161998) 2026-02-01 07:49:55 +01:00
Erwin Douna 967e97661f Add reauth to Proxmox (#161944) 2026-01-31 22:42:33 +01:00
Erwin Douna b757312fe0 Remove unused variables in SMA (#161989) 2026-01-31 20:40:28 +01:00
Erwin Douna 2ed8ec0bdf Add reconfigure to Proxmox (#161941)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-31 20:21:55 +01:00
epenet 97f6e3741a Fix mired warning in template light (#161923) 2026-01-31 17:30:41 +01:00
Colin c2d3244d26 openevse: Turn on strict typing (#161957)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-31 16:56:17 +01:00
Shay Levy eafeba792d Fix Shelly CoIoT repair issue (#161973)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-31 16:33:31 +02:00
Norbert Rittel c9318b6fbf Clarify action description for input_button helper (#161963) 2026-01-31 15:16:36 +01:00
epenet 99be382abf Remove outdated device registry cleanup in generic_hygrostat (#161859) 2026-01-31 15:15:19 +01:00
epenet 7cfcfca210 Remove outdated device registry cleanup in generic_thermostat (#161861) 2026-01-31 15:14:57 +01:00
epenet f29daccb19 Remove outdated device registry cleanup in history_stats (#161862) 2026-01-31 15:14:42 +01:00
epenet be869fce6c Remove outdated device registry cleanup in mold_indicator (#161864) 2026-01-31 15:14:26 +01:00
epenet 7bb0414a39 Remove outdated device registry cleanup in statistics (#161865) 2026-01-31 15:14:09 +01:00
epenet 3f8807d063 Remove outdated device registry cleanup in threshold (#161866) 2026-01-31 15:13:54 +01:00
mettolen 67642e6246 Add reauthentication flow to Liebherr integration (#161902)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-31 15:12:52 +01:00
mvn23 0d215597f3 Fix OpenTherm Gateway button availability (#161933) 2026-01-31 15:06:21 +01:00
mvn23 f41bd2b582 Bump pyotgw to 2.2.3 (#161928) 2026-01-31 15:03:56 +01:00
Norbert Rittel 5c9ec1911b Clarify action descriptions for input_boolean (#161924) 2026-01-31 15:03:08 +01:00
J. Diego Rodríguez Royo 1a0b7fe984 Restore the Home Connect program option entities (#156401)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-31 12:32:18 +01:00
Erwin Douna 26ee25d7bb Pattern fix for Proxmox config flow (#161946) 2026-01-31 11:41:41 +01:00
Norbert Rittel aabf52d3cf Rename "service" to "action", use common state for "High" (#161940) 2026-01-31 11:40:55 +01:00
Erwin Douna 99fcb46a7e Add parallel updates to Portainer (#161947) 2026-01-31 11:40:25 +01:00
Raphael Hehl 6580c5e5bf Bump uiprotect to version 10.1.0 (#161967)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-01-31 11:39:20 +01:00
tronikos 63e7d4dc08 Bump opower to 0.17.0 (#161962) 2026-01-31 11:38:43 +01:00
Sid cc6900d846 Bump eheimdigital to 1.6.0 (#161961) 2026-01-31 11:38:14 +01:00
Brett Adams ca2ad22884 Rename drive inverter unavailable state in Teslemetry (#161960)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:36:12 +01:00
Armin Ghofrani 40944f0f2d Enable prompt caching for Anthropic conversation integration (#158957)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:32:47 +03:00
uptimeZERO_ 91a3e488b1 Bump media source upload limit from 10mb to 20mb (#161436) 2026-01-30 13:07:37 +01:00
Magnus Øverli 9a1f517e6e Convert flexit_bacnet fireplace mode to climate preset- Rename 'Boost… (#155760)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-30 12:59:10 +01:00
Franck Nijhof 9a5d4610f7 Bump version to 2026.2.0b1 2026-01-30 11:45:08 +00:00
Paul Bottein 41c524fce4 Update frontend to 20260128.3 (#161918) 2026-01-30 11:44:54 +00:00
David Recordon 5f9fa95554 Fix Control4 HVAC state-to-action mapping (#161916) 2026-01-30 11:44:51 +00:00
Simone Chemelli 6950be8ea9 Handle hostname resolution for Shelly repair issue (#161914) 2026-01-30 11:44:47 +00:00
puddly c5a8bf64d0 Bump ZHA to 0.0.88 (#161904) 2026-01-30 11:44:44 +00:00
hanwg a2b9a6e9df Update translations for Telegram bot (#161903) 2026-01-30 11:44:43 +00:00
Marc Mueller a0c567f0da Update fritzconnection to 1.15.1 (#161887) 2026-01-30 11:44:40 +00:00
Bram Kragten c7feafdde6 Update frontend to 20260128.2 (#161881) 2026-01-30 11:44:38 +00:00
Björn Dalfors e1e74b0aeb Bump nibe to 2.22.0 (#161873) 2026-01-30 11:44:36 +00:00
Sebastiaan Speck 673411ef97 Bump renault-api to 0.5.3 (#161857) 2026-01-30 11:44:34 +00:00
epenet f7e5af7cb1 Fix incorrect entity_description class in radarr (#161856) 2026-01-30 11:44:32 +00:00
Norbert Rittel 0ee56ce708 Fix action descriptions of alarm_control_panel (#161852) 2026-01-30 11:44:30 +00:00
Manu f93a176398 Fix string in Namecheap DynamicDNS integration (#161821) 2026-01-30 11:44:28 +00:00
Paul Bottein cd2394bc12 Allow lovelace path for dashboard in yaml and fix yaml dashboard migration (#161816) 2026-01-30 11:44:26 +00:00
Michael Hansen 5c20b8eaff Bump intents to 2026.1.28 (#161813) 2026-01-30 11:44:25 +00:00
Aaron Godfrey 4bd499d3a6 Update todoist-api-python to 3.1.0 (#161811)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-30 11:44:23 +00:00
Jan Bouwhuis 8a53b94c5a Fix use of ambiguous units for reactive power and energy (#161810) 2026-01-30 11:44:20 +00:00
victorigualada d5aff326e3 Use OpenAI schema dataclasses for cloud stream responses (#161663) 2026-01-30 11:44:18 +00:00
Gage Benne 22f66abbe7 Bump pydexcom to 0.5.1 (#161549) 2026-01-30 11:44:16 +00:00
Mattia Monga f635228b1f Make viaggiatreno work by fixing some critical bugs (#160093)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-30 11:44:14 +00:00
Artur Pragacz 4c708c143d Fix validation of actions config in intent_script (#158266) 2026-01-30 11:44:12 +00:00
Simone Chemelli c82c614bb9 Handle hostname resolution for Shelly repair issue (#161914) 2026-01-30 12:26:48 +01:00
Norbert Rittel 20914dce67 Improve action descriptions of camera (#161876) 2026-01-30 12:08:49 +01:00
Paul Bottein 5fc407d2f3 Update frontend to 20260128.3 (#161918) 2026-01-30 11:51:53 +01:00
Marc Mueller c7444d38a1 Remove pydantic v1 mypy plugin (#161901) 2026-01-30 11:19:06 +01:00
puddly 81f6136bda Bump ZHA to 0.0.88 (#161904) 2026-01-30 11:18:38 +01:00
Steve Easley 862d0ea49e Bump JVC Projector dependency to 2.0.1 (#161898) 2026-01-30 11:17:14 +01:00
hanwg f2fdfed241 Update translations for Telegram bot (#161903) 2026-01-30 11:13:46 +01:00
David Recordon 15640049cb Fix Control4 HVAC state-to-action mapping (#161916) 2026-01-30 10:59:39 +01:00
dependabot[bot] 5c163434f8 Bump actions/cache from 5.0.2 to 5.0.3 (#161906)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-30 10:47:02 +01:00
Sebastiaan Speck e54c2ea55e Ensure Renault buttons are supported by the vehicle (#161893)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-30 09:58:50 +01:00
Kevin Stillhammer 1ec42693ab Bump fressnapftracker to 0.2.2 (#161913) 2026-01-30 09:32:13 +01:00
epenet 672864ae4f Remove outdated device registry cleanup in trend (#161867) 2026-01-30 08:07:53 +01:00
Artur Pragacz e54d7e42cb Add subscription pattern for conversation intents (#158456) 2026-01-30 07:19:57 +01:00
Jan Bouwhuis 5d63fce015 Re-add Claude code to devcontainer via native install script (#161807) 2026-01-29 23:35:59 -05:00
Paul Bottein 190fe10eed Allow lovelace path for dashboard in yaml and fix yaml dashboard migration (#161816) 2026-01-29 17:19:37 -05:00
Bram Kragten ef410c1e2a Update frontend to 20260128.2 (#161881) 2026-01-29 23:02:59 +01:00
Artur Pragacz 5a712398e7 Fix validation of actions config in intent_script (#158266) 2026-01-29 22:12:46 +01:00
Thomas55555 b1be3fe0da Introduce common string for data description of verify_ssl (#160703) 2026-01-29 20:27:37 +00:00
Brett Adams 97a7ab011b Add quality scale to Teslemetry (#159589) 2026-01-29 20:23:09 +00:00
SamareshSingh 694a3050b9 Add device_class inheritance to min_max sensor (#157602)
Signed-off-by: Samaresh Sahoo <ssamaresh01@gmail.com>
Co-authored-by: Samaresh Kumar Singh <ssam18@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-29 21:15:41 +01:00
Erwin Douna 8164e65188 Fix small typo in Portainer strings (#161889) 2026-01-29 20:58:07 +01:00
Marc Mueller 9af0d1eed4 Update fritzconnection to 1.15.1 (#161887) 2026-01-29 20:57:52 +01:00
Jan Bouwhuis 72e6ca55ba Fix use of ambiguous units for reactive power and energy (#161810) 2026-01-29 20:34:09 +01:00
Jeremiah Paige 0fb62a7e97 Add wsdot code-owner (#160807) 2026-01-29 19:52:41 +01:00
Erwin Douna 930eb70a8b Add prune images service to Portainer (#161009)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-29 19:39:17 +01:00
Norbert Rittel 462104fa68 Clarify action descriptions for input numbers (#161847) 2026-01-29 18:43:26 +01:00
mettolen d0c77d8a7e Delete unused Liebherr snapshot (#161879) 2026-01-29 17:38:56 +01:00
Björn Dalfors 606780b20f Bump nibe to 2.22.0 (#161873) 2026-01-29 17:06:38 +01:00
Tucker Kern 8f465cf2ca Remove deprecated Snapcast group entities and custom grouping services (#160945) 2026-01-29 16:44:50 +01:00
epenet 4e29476dd9 Cleanup deprecated YAML import from datadog (#161870) 2026-01-29 15:33:14 +01:00
epenet b4328083be Fix incorrect entity_description class in radarr (#161856) 2026-01-29 15:09:06 +01:00
epenet 72ba59f559 Remove outdated device registry cleanup in utility_meter (#161868) 2026-01-29 15:01:41 +01:00
epenet 826168b601 Remove outdated device registry cleanup in integration (#161863) 2026-01-29 15:01:22 +01:00
Sebastiaan Speck 66f181992c Bump renault-api to 0.5.3 (#161857) 2026-01-29 14:02:22 +01:00
epenet 336ef4c37b Remove outdated device registry cleanup in derivative (#161858) 2026-01-29 13:55:49 +01:00
mettolen 72e7bf7f9c Add new Liebherr integration (#161197)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-29 13:49:09 +01:00
Gage Benne acbdbc9be7 Bump pydexcom to 0.5.1 (#161549) 2026-01-29 12:47:05 +01:00
Steve Easley 3551382f8d Add additional JVC Projector entities (#161134) 2026-01-29 12:45:19 +01:00
Mattia Monga 95014d7e6d Make viaggiatreno work by fixing some critical bugs (#160093)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-29 12:41:47 +01:00
Retha Runolfsson dfe1990484 Add service for switchbot keypad vision (#160659)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-29 12:23:38 +01:00
epenet 15ff5d0f74 Modernize tasmota light tests (#161830) 2026-01-29 12:05:03 +01:00
epenet 1407f61a9c Modernize abode light tests (#161829) 2026-01-29 12:01:32 +01:00
epenet 6107b794d6 Modernize hue light tests (#161828) 2026-01-29 12:01:07 +01:00
epenet 7ab8ceab7e Modernize zha light tests (#161826) 2026-01-29 12:00:52 +01:00
epenet a4db6a9ebc Modernize template light tests (#161833) 2026-01-29 11:59:55 +01:00
Colin 12a2650b6b Add quality scale to openesve (#161651) 2026-01-29 11:55:54 +01:00
Markus Jacobsen 23da7ecedd Bump mozart_api to 5.3.1.108.2 (#161846) 2026-01-29 11:54:11 +01:00
wollew 8d9e7b0b26 Do not use base class of pyvlx in velux light platform (#161837) 2026-01-29 11:52:22 +01:00
epenet 9664047345 Modernize homekit_controller light tests (#161844) 2026-01-29 11:51:59 +01:00
epenet 804fbf9cef Modernize govee_light_local light tests (#161845) 2026-01-29 11:51:22 +01:00
epenet e10fe074c9 Cleanup deprecated color_temp support in lifx (#161848) 2026-01-29 11:50:53 +01:00
Norbert Rittel 7b0e21da74 Fix action descriptions of alarm_control_panel (#161852) 2026-01-29 11:50:22 +01:00
epenet 29e142cf1e Modernize matter light tests (#161850) 2026-01-29 11:49:51 +01:00
epenet 6b765ebabb Modernize tradfri light tests (#161849) 2026-01-29 11:49:18 +01:00
epenet 899aa62697 Modernize knx light tests (#161851) 2026-01-29 11:42:18 +01:00
dependabot[bot] a11efba405 Bump docker/login-action from 3.6.0 to 3.7.0 (#161825) 2026-01-29 07:43:41 +01:00
Manu 78280dfc5a Fix string in Namecheap DynamicDNS integration (#161821) 2026-01-29 03:10:09 +01:00
Glenn de Haan 4220bab08a Improve quality scale to gold HDFury integration (#161800) 2026-01-29 00:25:00 +01:00
Marc Mueller f7dcf8de15 Switch back to mypy 1.19.1 (#161817) 2026-01-29 00:12:46 +01:00
Aaron Godfrey 7e32b50fee Update todoist-api-python to 3.1.0 (#161811)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-29 00:00:53 +01:00
Robert Resch c875b75272 Use Python 3.14 as default one (#161426)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-01-28 23:48:27 +01:00
John Hillery 7368b9ca1d Add sensor for energy remaining to tessie integration (#161796) 2026-01-28 23:41:29 +01:00
Michael Jones 493e8c1a22 Append ID to flood monitoring station name in EAFM (#161794) 2026-01-28 22:18:35 +00:00
Michael Hansen 1b16b24550 Bump intents to 2026.1.28 (#161813) 2026-01-28 23:14:36 +01:00
Franck Nijhof 7637300632 Bump version to 2026.3.0dev0 (#161809) 2026-01-28 23:12:34 +01:00
Franck Nijhof 3369459d41 Bump version to 2026.2.0b0 2026-01-28 20:00:19 +00:00
victorigualada bdbce57217 Use OpenAI schema dataclasses for cloud stream responses (#161663) 2026-01-28 20:59:03 +01:00
Jan Čermák 8536472fe9 Rename add-ons to apps in hassio integration (#161801)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-28 20:46:34 +01:00
Erwin Douna ad4fda7bb4 Analytics refactor to apps (#161784)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-28 20:13:04 +01:00
Brett Adams 36e1b86952 Add missing data description string in Tesla Fleet (#161201)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2026-01-28 20:12:01 +01:00
Raphael Hehl 0c9834e4ca Exclude AI Port from camera entities and RTSP issues (#161188)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-01-28 19:54:15 +01:00
epenet 360af74519 Improve min/max kelvin handling in hue_ble (#161782) 2026-01-28 19:53:57 +01:00
epenet d099ac457d Improve use of SensorEntityDescription in solax (#161687) 2026-01-28 19:50:18 +01:00
Joakim Plate fc330ce165 Let nibe library autodetect word swap on config (#161786) 2026-01-28 19:42:36 +01:00
Chris b52dd5fc05 Add number platform to openevse (#161726)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-28 19:40:36 +01:00
Tom Matheussen b517ce132f Don't attempt to verify ignored Doorbird devices during discovery (#161776) 2026-01-28 19:40:02 +01:00
puddly acec35846c Bump ZHA to 0.0.87 (#161733) 2026-01-28 19:39:13 +01:00
Manu af661898c2 Rename add-on to app in common strings (#161790) 2026-01-28 19:08:51 +01:00
Manu e2f5a4849c Rename add-on to app in MQTT discovery flow (#161711)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-28 18:52:26 +01:00
Manu 399b7f6223 Rename add-on to app in Wyoming discovery flow (#161721) 2026-01-28 18:51:31 +01:00
Bram Kragten 782f7af332 Update frontend to 20260128.1 (#161795) 2026-01-28 18:50:03 +01:00
Przemko92 66af6565bf Add select for compit integration (#152778)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-28 17:35:15 +00:00
Matthias Alphart 8a00aa8550 Update knx-frontend to 2026.1.28.162006 (#161798) 2026-01-28 18:28:24 +01:00
Jan Čermák b07adc03d2 Add services using "apps" instead of "addons" to hassio integration (#161689)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-28 18:08:52 +01:00
Bram Kragten a978e3c199 Remove developer tools panel, add redirects (#161789)
Co-authored-by: Robert Resch <robert@resch.dev>
2026-01-28 17:55:30 +01:00
prana-dev-official bb3c977448 Prana integration (#156599)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-28 17:22:19 +01:00
Petar Petrov 8057de408e Add non standard power sensor support (#160432)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-28 17:20:50 +01:00
Manu 0be4ee71e7 Rename add-on to app in Z-Wave JS discovery flow (#161774) 2026-01-28 16:31:22 +01:00
Amit Finkelstein 7ff5f14748 Bump pysiaalarm to 3.2.2 (#161788) 2026-01-28 16:23:01 +01:00
hanwg d5e58c817d Add API server endpoint to options for Telegram bot (#161580) 2026-01-28 16:16:32 +01:00
Manu 8a08016fb9 Rename add-on to app in Reolink issue description (#161787)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-28 15:47:25 +01:00
Luke Lashley d45ddd3762 Add the ability to set Cleaning mode and mop mode for Q7 Vacs (#161725)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-28 15:34:41 +01:00
epenet 0e98e8c893 Cleanup deprecated vacuum battery support from mqtt (#161745) 2026-01-28 15:24:56 +01:00
Petro31 84a09bec0e Make template weather consistent with itself and other platforms (#159607) 2026-01-28 15:04:03 +01:00
Petro31 6fd27ec7ec Update template cover to new framework (#161481) 2026-01-28 15:03:45 +01:00
epenet 91e2a318a5 Improve mqtt light tests (#161780) 2026-01-28 15:01:34 +01:00
Manu 1221c5bcad Rename add-on to app in SABnzbd config flow (#161783) 2026-01-28 14:59:38 +01:00
Manu 8e3befc301 Rename add-on to app in OTBR issue description (#161781) 2026-01-28 14:42:11 +01:00
epenet 2df62385f1 Remove str from light color mode (#161755) 2026-01-28 14:37:53 +01:00
Tomás Correia 9f3b13dfa1 Add Cloudflare R2 integration (#152825)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-28 14:34:58 +01:00
Sab44 9c27e1233e Pass aiohttp websession to librehardwaremonitor-api (#161741) 2026-01-28 14:20:59 +01:00
Joost Lekkerkerker 825da95550 Remove bluesound sleep timer service (#161120) 2026-01-28 14:07:16 +01:00
Andrew Jackson 18bda2dbbe Remove Mastodon extra field attributes (#161659) 2026-01-28 14:05:56 +01:00
epenet 630a9b4896 Cleanup deprecated usb alias (#161748) 2026-01-28 14:04:23 +01:00
epenet e6399d2bfe Cleanup deprecated ssdp aliases (#161747) 2026-01-28 14:03:32 +01:00
Artur Pragacz 4bae0d15ec Rename group attribute in Insteon (#161703)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 13:58:12 +01:00
Artur Pragacz 760a75d1f1 Rename group attribute in LimitlessLED (#161701)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 13:57:49 +01:00
epenet c08912fc78 Improve sunricher_dali light shorthand attributes (#161765) 2026-01-28 12:36:03 +00:00
epenet 316d804336 Improve cync light type hints (#161768) 2026-01-28 12:34:49 +00:00
epenet d3658a52dd Improve upb light type hints (#161763) 2026-01-28 12:33:55 +00:00
epenet b3e42a1f07 Improve tasmota light type hints (#161762) 2026-01-28 12:33:19 +00:00
epenet dee07b25a2 Improve decora_wifi light type hints (#161759) 2026-01-28 12:32:11 +00:00
epenet f460bf36fe Improve homekit_controller light type hints (#161773) 2026-01-28 12:31:25 +00:00
Artur Pragacz 020d122799 Enable snapshot analytics as labs feature (#160068)
Co-authored-by: Steven Travers <steven.travers20@gmail.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-28 13:24:38 +01:00
epenet 699b4b12da Improve demo light type hints (#161770) 2026-01-28 13:17:02 +01:00
epenet 3ec96f21d1 Cleanup deprecated get access in Lovelace data (#161749) 2026-01-28 13:03:27 +01:00
epenet c6c5970864 Cleanup deprecated water_heater alias (#161751) 2026-01-28 13:00:55 +01:00
epenet 570146c4a6 Cleanup deprecated vacuum state constants (#161750) 2026-01-28 12:56:09 +01:00
epenet 75b7f80f6c Cleanup deprecated zeroconf aliases (#161746) 2026-01-28 12:52:40 +01:00
epenet 1c1a99e5ae Improve elgato light type hints (#161771) 2026-01-28 12:51:29 +01:00
epenet 0203f6e6f1 Improve hue light type hints (#161766) 2026-01-28 12:50:57 +01:00
epenet 66612f97ec Improve govee_light_local light type hints (#161772) 2026-01-28 12:50:22 +01:00
epenet 6d215c284c Improve zwave_js light type hints (#161775) 2026-01-28 12:50:13 +01:00
Artur Pragacz 8e9e406341 Fix labs description url check in hassfest (#161730) 2026-01-28 12:47:13 +01:00
MoonDevLT b6772c4104 Bump lunatone-rest-api-client to 0.6.3 (#161764) 2026-01-28 12:39:05 +01:00
epenet d6a830da1a Improve deconz light type hints (#161769) 2026-01-28 12:37:13 +01:00
epenet 2f7a895e28 Cleanup deprecated dt util function (#161752) 2026-01-28 11:54:15 +01:00
Abílio Costa 5cb5b0eb45 Handle wait_for_trigger service actions when extracting references (#161706)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2026-01-28 10:37:39 +00:00
epenet 33ae951030 Improve shelly light type hints (#161761) 2026-01-28 11:24:21 +01:00
epenet 1cb56216ba Improve crownstone light type hints (#161758) 2026-01-28 11:23:53 +01:00
epenet 6409574ecf Improve flux_led light type hints (#161760) 2026-01-28 11:20:57 +01:00
dependabot[bot] a94d39e493 Bump j178/prek-action from 1.0.12 to 1.1.0 (#161736)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-28 11:16:10 +01:00
epenet fec008c589 Improve abode light type hints (#161756) 2026-01-28 11:14:29 +01:00
Robert Resch 358e58ea85 Bump deebot-client to 17.1.0 (#161727) 2026-01-28 09:36:00 +01:00
epenet e8bbc9598f Cleanup deprecated dhcp alias (#161742) 2026-01-28 09:29:46 +01:00
Luke Lashley 49e0c8e0bd Add binary sensors for water boxes for Roborock docks (#161732) 2026-01-28 07:07:10 +01:00
dependabot[bot] 0623da8aa9 Bump actions/attest-build-provenance from 3.1.0 to 3.2.0 (#161653)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-27 23:03:05 +01:00
Manu 8356524cf2 Rename add-on to app in Music Assistant discovery flow (#161720)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2026-01-27 22:58:41 +01:00
starkillerOG 420123f1ff Bump reolink-aio to 0.18.1 (#161714) 2026-01-27 22:58:18 +01:00
Michael 3ea3d88889 Make FRITZ!Box Tools tests more reliable (#161719) 2026-01-27 16:57:28 -05:00
Manu f88876a3c7 Add reauth flow to Namecheap DynamicDNS integration (#161674) 2026-01-27 21:50:02 +01:00
Manu de834f9988 Rename add-on to app in Mealie discovery flow (#161704) 2026-01-27 21:48:52 +01:00
Manu 83ace00e14 Rename add-on to app in motionEye discovery flow (#161707) 2026-01-27 21:48:38 +01:00
Manu 1f163dfcbd Rename add-on to app in AdGuard discovery flow (#161696) 2026-01-27 21:47:52 +01:00
Manu 057d24a227 Rename add-on to app in pyLoad (#161693) 2026-01-27 21:47:37 +01:00
Manu 9418217d38 Rename add-on to app in VLC telnet discovery flow (#161710)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-27 21:47:15 +01:00
marph91 181f89446f Add the myStrom WiFi Motion Sensor (#156880)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-27 21:34:33 +01:00
Andreas Jakl 37b4bfc9fc Add NRGkick integration and tests (#159995)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-27 21:33:12 +01:00
Colin b84022f88b openevse: Switch to using websockets and push instead of polling (#160758) 2026-01-27 21:15:18 +01:00
Colin a88ceada60 openevse: Change translation to max_current to Current Limit (#161713) 2026-01-27 21:13:22 +01:00
Thomas Rupprecht f72a70a549 [esphome] add missing mapping of state class MEASUREMENT_ANGLE (#161464) 2026-01-28 09:13:02 +13:00
Joshua Monta 70e84526cc Uhoo integration (#158887)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-27 21:08:41 +01:00
Tomasz 1bb4c9d213 Add support for initial color in Google Calendar (#161671) 2026-01-27 20:00:40 +00:00
Artur Pragacz 0b96aa8871 Rename group attribute in PlayStation Network (#161702)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:49:57 +00:00
Chris 8645ef60ec Fix unit of measurement on openevse energy sensors (#161705) 2026-01-27 20:46:39 +01:00
Manu a2e4980364 Add clear/delete actions to ntfy integration (#161388)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-27 20:04:30 +01:00
Manu 39ff57ecd2 Rename add-on to app in DeConz discovery flow (#161699) 2026-01-27 19:42:58 +01:00
Artur Pragacz f3025daa1f Rename group attribute in deCONZ (#161700)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:41:34 +01:00
Paul Tarjan 364ecc191e Deprecate implicit Wake-On-LAN in Samsung TV integration (#158740)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-27 19:36:43 +01:00
Douwe eaa1798443 Add water heater support to ESPHome (#159201)
Co-authored-by: Ludovic BOUÉ <lboue@users.noreply.github.com>
Co-authored-by: Ludovic BOUÉ <ludovic.boue@gmail.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-01-27 08:30:58 -10:00
Simone Chemelli 11f713209d Create CoIoT setting repair issue for Shelly gen 1 devices (#160056) 2026-01-27 20:16:19 +02:00
AlCalzone d96bc1b32e Clarify what is being discovered by the Z-Wave integration (#161626) 2026-01-27 13:15:02 -05:00
Glenn de Haan 1022f422c8 Add HDFury CEC switches (#161391) 2026-01-27 19:13:43 +01:00
Artur Pragacz 3e21ac02fc Rename group attribute in Hue (#161698)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:10:41 +01:00
Manu f2a17a0aca Rename add-on to app in Uptime Kuma (#161692) 2026-01-27 13:09:37 -05:00
Jan Čermák 0593bca476 Fix mocking of Yellow hardware probing in hassio tests (#161695) 2026-01-27 19:09:27 +01:00
DeerMaximum c361185efb Add silver quality scale for NINA (#161122) 2026-01-27 19:05:25 +01:00
Glenn de Haan 9882fe0eda Add HDFury reconfiguration (#161690) 2026-01-27 18:50:37 +01:00
mezz64 bbb5ab448e Bump pyhik to 0.4.1 (#161465) 2026-01-27 17:33:22 +01:00
Ståle Storø Hauknes 9c07550f40 Add connectivity mode diagnostics sensor for Airthings BLE (#161261)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-27 17:31:23 +01:00
Joost Lekkerkerker 36b9234f26 Don't translate URLs (#154224)
Co-authored-by: jbouwh <jan@jbsoft.nl>
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2026-01-27 17:30:15 +01:00
cdnninja 2dc1981932 VeSync Multiple Config Entries (#160114)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-27 17:28:02 +01:00
Simone Chemelli fda817cb1d Fix deflection switch state for Fritz (#161669) 2026-01-27 17:18:08 +01:00
Joost Lekkerkerker 8ccc9e407e Add integration_type device to sensirion_ble (#161539) 2026-01-27 17:11:37 +01:00
Joost Lekkerkerker bf07a79e3a Add SmartThings device info from device identification (#161688) 2026-01-27 17:02:10 +01:00
epenet 6fd2d74539 Improve type hints in control4 media player (#161234) 2026-01-27 17:01:47 +01:00
Paul Bottein 8a91e07b97 Migrate default Lovelace panel to dashboard system (#158265)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-01-27 15:55:22 +00:00
Christian Lackas c53b2d63d7 Bump homematicip to 2.5.0 (#161365) 2026-01-27 15:54:43 +00:00
Thomas55555 a8b7e1b5d9 Use dataclass in Google Air Quality (#160638) 2026-01-27 16:54:07 +01:00
Muhammad Hamza Khan 9d90e3c7ce Support for stateChanged parameter for each folder from syncthing (#160376) 2026-01-27 16:53:44 +01:00
Craig Andrews 187aa52d92 Use default time zone for boot time (#161605) 2026-01-27 16:49:35 +01:00
Paulo Ruberto 0e08a6a69c Implement Roborock dock cleaning fluid status (#161098) 2026-01-27 16:45:17 +01:00
Jan Čermák be88a1f14a Add app selector as replacement for addon selector (#161684) 2026-01-27 17:35:34 +02:00
David Recordon 3794b4e1a1 Improve Control4 connection error logging (#159979)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-27 16:28:32 +01:00
Michael Davie 46cc30e1f5 Clear cache when radar type is changed via service (#161601)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 16:25:46 +01:00
Paul Bottein c261d39f99 And env instructions for AI agents (#161665) 2026-01-27 16:24:08 +01:00
cdnninja f7bc7d3911 Bump pyvesync to 3.4.1 (#160573)
Co-authored-by: Joe Trabulsy <jtrabulsy@gmail.com>
2026-01-27 16:18:37 +01:00
epenet d880d305f4 Improve diagnostics docstring (#161683) 2026-01-27 16:06:55 +01:00
Colin 19fe9c0f5e Add more sensors to openevse (#160904)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-27 15:47:30 +01:00
Renat Sibgatulin 03eddfa142 Update air-Q refrigerant sensors (#161483) 2026-01-27 15:38:09 +01:00
Luke Lashley d6a3189651 Bump python-roborock to 4.8.0 (#161680) 2026-01-27 15:36:51 +01:00
epenet 71f17f2cf1 Fix Tuya device registry cleanup (#161268) 2026-01-27 15:23:08 +01:00
epenet 6e2092b784 Bump freebox-api to 1.3.0 (#161677) 2026-01-27 15:22:03 +01:00
epenet 499fd131b0 Use HassKey in abode (#161675) 2026-01-27 15:21:42 +01:00
epenet 9493240e9f Bump meteofrance-api to 1.5.0 (#161676) 2026-01-27 15:20:51 +01:00
Michael ed70cacaa6 Improve typing in models and entity module in FRITZ!Box tools (#161635) 2026-01-27 13:19:13 +01:00
Åke Strandberg 197e5203eb Update code translations for Miele microwave/Oven combo (#161657) 2026-01-27 11:34:18 +01:00
Simone Chemelli 1f8a98609c Improve test coverage for switch in Fritz (#161630) 2026-01-27 10:48:51 +01:00
AlCalzone 69ee3a15b6 Display Z-Wave home IDs as hexadecimal (#161624) 2026-01-27 09:58:36 +01:00
Tomasz b13c2e3018 Add initial_color property to CalendarEntity (#145606)
Co-authored-by: Allen Porter <allen.porter@gmail.com>
2026-01-27 10:52:07 +02:00
Erik Montnemery 27b8274d3e Add media_player conditions (#161384) 2026-01-27 09:32:42 +01:00
J. Nick Koston cc6c506995 Bump bleak to 2.1.1 (#161650)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-27 09:05:53 +01:00
dependabot[bot] 216bfeaa4a Bump github/codeql-action from 4.31.11 to 4.32.0 (#161654)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-27 08:30:41 +01:00
cdnninja 0781ac8450 Add Missing None return type in Vesync (#161597) 2026-01-27 08:25:43 +01:00
Erik Montnemery 5ec6a40ceb Add humidifier conditions (#161022) 2026-01-27 08:23:55 +01:00
Michael ec7a1fa266 Move the state based icons to icon translations for device trackers in FRITZ!Box tools (#161636) 2026-01-27 08:23:23 +01:00
J. Nick Koston 729e530a6f Bump bleak-esphome to 3.5.0 (#161649) 2026-01-27 08:20:55 +01:00
Erik Montnemery c85c96a70e Add person conditions (#161385) 2026-01-27 08:18:39 +01:00
Erik Montnemery ff1898c334 Add vacuum cleaner conditions (#161386) 2026-01-27 08:18:12 +01:00
Erik Montnemery 68b4ad722d Add climate conditions (#161020)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-27 07:53:31 +01:00
Erik Montnemery 3c1bf41e5a Add lawn_mower conditions (#161382) 2026-01-27 07:52:46 +01:00
Josef Zweck 9a03005d87 Fix config flow abort for oauth integrations when no implementation exception (#161631) 2026-01-27 07:19:03 +01:00
epenet 7e2878ec83 Bump influxdb-client to 1.50.0 (#161476) 2026-01-27 07:13:09 +01:00
Artur Pragacz c6064f40d2 Use same code path for friendly name as for entity ID (#161250) 2026-01-27 00:13:53 +01:00
Simone Chemelli af5fe8e053 Add switch platform to Vodafone Station (#160419) 2026-01-26 21:11:28 +01:00
Niracler 0ad692238f Add binary sensor platform to sunricher_dali (#161463)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 21:10:44 +01:00
wollew f220c0b8fe Put Velux integration on quality scale (#161500) 2026-01-26 21:10:01 +01:00
tan-lawrence c33c834f5a Add back support for coolmaster speeds that don't have a direct HA equivalent (#160825) 2026-01-26 20:07:22 +00:00
wollew 0cf224fcb0 bump pyvlx to 0.2.28 (#161495) 2026-01-26 21:03:33 +01:00
Artem Sheremet e50558c8fe Add extra enum value for cottons_hygiene (#161230) 2026-01-26 21:02:45 +01:00
Paul Tarjan 99b43e74ea Fix Hikvision NVR channel naming and device hierarchy (#160866)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Paul Tarjan <ptarjan@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 21:01:06 +01:00
Josef Zweck f4f25b3f96 Always require diff for dependency bumps (#161633) 2026-01-26 20:51:30 +01:00
Vallabh Mahajan e3c04d6a6b Add support for ecobee attisRetail model (#161515)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 20:47:35 +01:00
Stan 015df950f2 Fix removal of stale Tailscale devices (#161084)
Co-authored-by: Stan Cope <976785+scopey@users.noreply.github.com>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-01-26 19:17:07 +00:00
Ziv 980c9bd9a0 added test to see that URL for module has not changed (#161628) 2026-01-26 14:10:38 -05:00
Peter Grauvogel b91abea97e New integration featuring the green planet energy prices API for tariff with dynamic prices (#150010)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-26 19:59:36 +01:00
Maciej Bieniek 6bb222bfc3 Bump aiotractive to 1.0.0 (#161470) 2026-01-26 19:58:49 +01:00
Sab44 9ece2217eb Add basic auth support to Libre Hardware Monitor (#160248) 2026-01-26 19:50:16 +01:00
epenet d1fac72fe0 Bump aioguardian to 2026.01.1 (#161471)
Co-authored-by: Aaron Bach <bachya1208@gmail.com>
2026-01-26 08:20:32 -10:00
Renat Sibgatulin adb728baa1 Add Mold index support for air-q (#161439) 2026-01-26 19:15:20 +01:00
Przemko92 e36432beed Update compit-inext-api to 0.6.0 (#161528) 2026-01-26 19:13:52 +01:00
JP-Ellis 2830221820 Allow control on missing izone thermometer (#155826)
Signed-off-by: JP-Ellis <josh@jpellis.me>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 18:34:56 +01:00
Josef Zweck 4e0cbccc11 Fix mastodon snapshots (#161627) 2026-01-26 17:35:37 +01:00
mettolen b341ae886b Upgrade Airobot integration to platinum (#161532)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 17:25:17 +01:00
Erik Montnemery 9913e1397e Add lock conditions (#161383) 2026-01-26 16:28:37 +01:00
Erik Montnemery b1a048901f Add switch conditions (#160950)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-26 16:13:19 +01:00
Manu 20c0c5f655 Add more sensors to Mastodon integration (#160835) 2026-01-26 15:42:20 +01:00
Andres Ruiz 9fb1612dac Migrate waterfurnace to config flow (#159908)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 15:05:43 +01:00
Manu 6d064dfca0 Set quality scale of Duck DNS to platinum 🏆️ (#158043)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-26 15:02:48 +01:00
Ziv 8ee49bb2d3 Fix module URL format in dynalite panel (#161625) 2026-01-26 14:37:26 +01:00
Denis Shulyaka 2343ff3454 Bump openai to 2.15.0 (#161533) 2026-01-26 14:30:58 +01:00
Marc Mueller 6224afc5d9 Update orjson to 3.11.5 (#161569) 2026-01-26 14:30:38 +01:00
Network-Buzzard 422dcb442d Update bus and train API URLs to use live data (#161374) 2026-01-26 14:01:31 +01:00
cdnninja 29fa9278a2 Typevar T for vesync strict typing (#161595)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-26 12:58:45 +01:00
Artur Pragacz e478045ce2 Move vacuum constants to const.py (#161620) 2026-01-26 12:50:00 +01:00
cdnninja 0103c563d1 Switch to product_type instead of is_instance for vesync (#161594) 2026-01-26 12:38:14 +01:00
Mick Vleeshouwer a265527ea7 Bump pyOverkiz to 1.20.0 in Overkiz (#161622) 2026-01-26 12:36:27 +01:00
Simone Chemelli bb45b23ba9 Small cleanup in sensors test for system monitor (#161616) 2026-01-26 12:30:17 +01:00
Simone Chemelli f8797ef06a Add 100% coverage to binary_sensor for Fritz (#161592) 2026-01-26 10:38:45 +01:00
Christopher Fenner 253d0f0bf0 add inverter sensors for ViCare integration (#161608) 2026-01-26 10:17:05 +01:00
Mick Vleeshouwer 65a621e0b9 Add debug logging for connection failures in Overkiz (#161614)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-26 10:14:06 +01:00
Joakim Plate 8727be4241 Consider missing togrill device okey to log real errors (#161544) 2026-01-26 10:00:47 +01:00
Michael Davie 21e1ca7203 Bump env-canada to 0.12.4 (#161542)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-26 09:41:08 +01:00
starkillerOG 7c6a2d796a Add Reolink pet chime ringtone select entity (#161575) 2026-01-26 09:05:55 +01:00
Luke Lashley 8cac2f9af2 Bump Python-Roborock to 4.7.2 (#161409) 2026-01-26 09:01:41 +01:00
Joost Lekkerkerker c0d265375a Add Decora Wifi to Leviton brand (#161441)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2026-01-26 09:00:31 +01:00
Erwin Douna 98b7ffcbdd Portainer refactor availability (#161589) 2026-01-26 08:59:25 +01:00
Christopher Fenner b18a8791ef add wifi sensor for ViCare devices (#161537) 2026-01-26 08:43:56 +01:00
J. Nick Koston b71add0769 Bump bleak-esphome to 3.4.1 (#161560) 2026-01-26 08:36:27 +01:00
Maikel Punie 2ee7155764 Bump valbuasio to 2026.1.4 (#161270) 2026-01-26 08:35:12 +01:00
Michael c5e1787e3b Fix reliability of internet access switches in FRITZ!Box Tools (#161593) 2026-01-26 08:34:56 +01:00
Retha Runolfsson 1bf9d72f7e Bump PySwitchbot to 1.0.0 (#161612) 2026-01-26 08:33:54 +01:00
Robert Resch 19333a8056 Bump go2rtc to 1.9.14 (#161559) 2026-01-26 08:32:17 +01:00
dependabot[bot] 664e97194a Bump github/codeql-action from 4.31.10 to 4.31.11 (#161609)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:04:19 +01:00
Tor André Roland afb5330cfe Support SSID with spaces in Adax-integration (#161596) 2026-01-26 07:03:34 +01:00
Tom 42c816d2d4 Bump airOS to v0.6.3 (#161591) 2026-01-25 22:11:23 +01:00
Christopher Fenner ba0f3485ba Bump PyViCare to 2.56.0 (#161563) 2026-01-25 21:38:19 +01:00
Barry vd. Heuvel a42caebf3e Update wefabricate/wh-python to 2026.1.25 for Weheat integration (#161573) 2026-01-25 20:57:26 +01:00
Jules Dejaeghere fad66d13f3 Bump irm-kmi-api to 1.1.1 to fix wind bug (#161578) 2026-01-25 20:56:53 +01:00
Michael 431d311193 Bump pyfritzhome to 0.6.19 (#161565) 2026-01-25 19:27:22 +01:00
Simone Chemelli 9fa3f8cfac Add 100% coverage to init for Fritz (#161583) 2026-01-25 19:26:42 +01:00
Will Moss 121e1f3b71 Improved error handling for oauth2 configuration in ondilo_ico integration (#161588) 2026-01-25 19:25:55 +01:00
Joao-Sousa-71 471f5602b2 Fix system monitor integration FileNotFoundError (#159534)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
2026-01-25 19:24:24 +01:00
Franck Nijhof fb7481dc05 Merge branch 'master' into dev 2026-01-25 16:54:27 +00:00
cdnninja 0ed458d4a3 Add Device Type to Vesync Test Fixtures (#161585) 2026-01-25 17:52:54 +01:00
Marc Mueller 51a3bd6bea Replace deprecated mcp function call (#161577) 2026-01-25 07:25:59 -08:00
Marc Mueller ecf5adefa8 Update types packages (#161579) 2026-01-25 16:12:15 +01:00
Jan Bouwhuis db3e568248 Fix code dev container not building (#161519) 2026-01-25 16:11:24 +01:00
Petro31 15d6463f09 Fix TriggerEntity's _handle_rendered_results for loop exiting early (#161485) 2026-01-25 13:24:28 +01:00
AJ Jordan 30951f2573 Clarify Steam ID format doc string (#161556) 2026-01-25 11:21:33 +01:00
J. Nick Koston 8f88c3d4ea Bump aioesphomeapi to 43.14.0 (#161550) 2026-01-24 23:52:02 -10:00
Muhammad Hamza Khan f38a0c5e6d Updating aiosyncthing to latest version (#161536) 2026-01-25 09:44:07 +01:00
Joakim Plate 48fff588c9 Update togrill to 0.8.1 (#161541) 2026-01-25 09:05:41 +01:00
Allen Porter 6112fa59f3 Update Anthropic config flow to filter out invalid LLM APIs (#161551) 2026-01-24 23:11:09 -08:00
Allen Porter 78e2581528 Update Google Gemini config flow to filter out invalid LLM APIs (#161552) 2026-01-24 23:11:04 -08:00
Allen Porter e41757ae2b Update OpenAI config flow to filter out invalid LLM APIs (#161553) 2026-01-24 23:10:59 -08:00
Allen Porter 1b83c7705f Update openrouter config flow to filter out invalid LLM APIs (#161554) 2026-01-24 23:10:43 -08:00
Glenn de Haan 7bc5717357 Add HDFury discovery (#161523) 2026-01-25 07:10:40 +01:00
Allen Porter 6aaec5c159 Add support for HTTP Streamable to MCP integration (#161547)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-25 01:03:55 -05:00
Allen Porter aca0232e71 Bump mcp to 1.26.0 (#161545) 2026-01-24 20:55:23 -05:00
Manu 73bfe308b7 Add link to emoji reference in ntfy (#161524) 2026-01-24 20:41:43 +01:00
Joakim Sørensen d68ac745d4 Show installed packages in cloud support package (#161516) 2026-01-24 08:20:39 -05:00
Maciej Bieniek 103097b74f Remove Tractive sensors that are no longer supported by the Tractive API (#160089) 2026-01-24 09:34:53 +01:00
cdnninja 3facfa3359 Align Vesync Humidifier Refresh with other platforms (#161507) 2026-01-24 08:10:58 +01:00
mettolen e852001943 Pump pyairobotrest to 0.3.0 (#161511) 2026-01-24 08:10:29 +01:00
Marc Mueller 374d7478f6 Remove macos install scripts (#161506) 2026-01-23 21:09:52 -05:00
Erik Montnemery 6c1b44aae2 Improve docstrings in condition tests (#161431) 2026-01-23 15:28:41 -05:00
Robert Resch 99827a86b4 Remove next Python version warning/repair (#161427) 2026-01-23 15:27:59 -05:00
karwosts 846b139e05 Hassfest: Don't allow placeholders in state translations (#161447) 2026-01-23 15:26:40 -05:00
Artur Pragacz d66c7bf38b Fix LLM test to use string values for device attributes (#161490) 2026-01-23 15:24:43 -05:00
Paulus Schoutsen e77a60df3a Split out integration skill from CLAUDE.md (#161413)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-23 15:22:18 -05:00
Franck Nijhof 8ad35e1bff 2026.1.3 (#161497) 2026-01-23 21:05:58 +01:00
Franck Nijhof 7ce4667856 Update wiz snapshots 2026-01-23 19:16:11 +00:00
epenet 3637124881 Add selenium to FORBIDDEN_PACKAGE_EXCEPTIONS (#161216) 2026-01-23 18:44:46 +00:00
Franck Nijhof 7e3b9e1d0f Bump version to 2026.1.3 2026-01-23 17:57:17 +00:00
tronikos 0867807ba6 Bump opower to 0.16.5 (#161450) 2026-01-23 17:54:49 +00:00
Erik Montnemery 44ca65b1e1 Revert deprecation of server_host for container installations (#161443)
Co-authored-by: Robert Resch <robert@resch.dev>
2026-01-23 17:54:48 +00:00
Artur Pragacz fda3a63e82 Bump music-assistant-client to 1.3.3 (#161438) 2026-01-23 17:54:47 +00:00
Tom Harris db2fd77c8b Bump Insteon panel to 0.6.1 (#161411) 2026-01-23 17:54:46 +00:00
Raphael Hehl 2f49dedc63 Bump uiprotect to 10.0.1 (#161397)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-01-23 17:54:45 +00:00
Robert Resch 594cd572de Migrate config entries to string unique id (#161370) 2026-01-23 17:54:44 +00:00
Raphael Hehl 865d2e4b6e Bump uiprotect to 10.0.0 (#161350) 2026-01-23 17:54:43 +00:00
Josef Zweck 59319f56bf Bump onedrive-personal-sdk to 0.1.1 (#161337) 2026-01-23 17:54:41 +00:00
Jacob 9eb398a953 Fix icons for 'moving' state (#161194) 2026-01-23 17:54:40 +00:00
Raphael Hehl 2cb9bbf949 Fix detection of multiple smart object types in single event (#161189)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-23 17:54:39 +00:00
tronikos 22ff086dc1 Bump opower to 0.16.4 (#161153) 2026-01-23 17:54:38 +00:00
Tero Paloheimo 6a42de1e21 Bump xiaomi-ble to 1.4.3 (#161132) 2026-01-23 17:20:43 +00:00
Artur Pragacz 4ac42ea39f Fix color temperature attributes in wiz (#161125) 2026-01-23 17:20:42 +00:00
Ludovic BOUÉ 9016c5d51d Adjust battery voltage sensor display precision for Matter devices (#161088)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-23 17:20:40 +00:00
Josef Zweck fcb4ed6cef Bump onedrive-personal-sdk to 0.1.0 (#160976) 2026-01-23 17:20:39 +00:00
Allan Lewis 368a411f01 Update list of supported locations for London Air (#160884) 2026-01-23 17:20:37 +00:00
Raphael Hehl e6772307ba Bump uiprotect to 8.1.1 (#160816) 2026-01-23 17:20:35 +00:00
Artur Pragacz 6b386bbc8f Add pre announce URL to Music Assistant (#161448) 2026-01-23 15:37:13 +01:00
epenet 8983d06d05 Move advantage_air service registration (#161487) 2026-01-23 15:22:40 +01:00
epenet 12e9241f71 Move bang_olufsen service registration (#161484)
Co-authored-by: Markus Jacobsen <markusjacobsen@hotmail.com>
2026-01-23 14:33:35 +01:00
torben-iometer 1e1445f393 round data for battery level to avoid small fluctuations (#161475) 2026-01-23 13:45:07 +01:00
Joost Lekkerkerker 1b08b578a8 Add integration_type service to rachio (#161301) 2026-01-23 13:09:09 +01:00
Joost Lekkerkerker e469e50f76 Add integration_type hub to rainforest_eagle (#161304) 2026-01-23 13:08:38 +01:00
Fredrik Mårtensson 9046ae1602 Add Tuya pet feeder entities (#161440)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-23 11:38:32 +01:00
Manu f1bf2625e6 Add note to config flow about token invalidation in PlayStation Network integration (#161459) 2026-01-23 11:12:33 +01:00
Robert Resch 1451af72ff Bump uv to 0.9.26 (#161458) 2026-01-23 10:46:16 +01:00
dependabot[bot] 26311e9480 Bump actions/checkout from 6.0.1 to 6.0.2 (#161467)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-23 09:59:04 +01:00
abelyliu c208b06c6a Add delta report type support for Tuya sensors (#160285)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-23 07:58:32 +01:00
Thomas55555 be373a76a7 Use device_class for NO in Google Air Quality (#161449) 2026-01-23 07:46:49 +01:00
Manu 5721c6c168 Bump python-xbox to 0.1.3 (#161453) 2026-01-23 06:39:55 +01:00
tronikos 0843cd761f Bump opower to 0.16.5 (#161450) 2026-01-22 22:57:14 +01:00
Erik Montnemery ff43003ce3 Add device_tracker conditions (#161381) 2026-01-22 21:38:10 +00:00
Michael Toscano 8e0f905aca Apple tv new feature keyboard binary sensor (#152397)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2026-01-22 18:40:43 +01:00
Erik Montnemery 2b730069d7 Revert deprecation of server_host for container installations (#161443)
Co-authored-by: Robert Resch <robert@resch.dev>
2026-01-22 18:38:23 +01:00
Artur Pragacz 4d87627091 Bump music-assistant-client to 1.3.3 (#161438) 2026-01-22 18:12:06 +01:00
epenet d9eff759dc Fix hassfest requirement check (#161435) 2026-01-22 18:01:09 +01:00
Robert Resch 9c3ffda4d2 Remove setting enable_cleanup_closed as it's not required anymore (#161430) 2026-01-22 16:49:23 +01:00
Paul Tarjan fa30ed1dd8 Add error handling for NVR event fetching in Hikvision integration (#160251)
Co-authored-by: Paul Tarjan <ptarjan@users.noreply.github.com>
2026-01-22 14:37:47 +01:00
Paul Tarjan 947ed121dc Create base entity class for Hikvision integration (#161175)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-22 14:36:27 +01:00
Petro31 9448f52d4a Update binary_sensor template platform to use new template framework (#159650)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-22 14:11:49 +01:00
Tom Harris 54be76f0ab Bump Insteon panel to 0.6.1 (#161411) 2026-01-22 13:48:42 +01:00
Jeremiah 32cd649fe4 Bump xiaomi-ble to 1.6.0 (#161421)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-01-22 12:50:37 +01:00
dependabot[bot] 69dc711466 Bump actions/setup-python from 6.1.0 to 6.2.0 (#161417) 2026-01-22 12:07:18 +01:00
Thomas55555 78212245dd Add ppb as a valid UOM for sensor/number NO device class (#161379) 2026-01-22 11:34:29 +01:00
Joost Lekkerkerker 5bbc39bd88 Add integration_type device to screenlogic (#161324) 2026-01-22 07:56:26 +01:00
Robert Resch 6b14eb7ad1 Migrate config entries to string unique id (#161370) 2026-01-21 23:36:21 -05:00
J. Nick Koston 83a53dea94 Fix SSL context mutation by httpx/httpcore with ALPN protocol bucketing (#161330) 2026-01-21 16:53:38 -10:00
Joost Lekkerkerker 4fb89e68a7 Add integration_type hub to sanix (#161322) 2026-01-21 23:18:32 +01:00
Glenn de Haan 5202ddf095 Bump hdfury to 1.4.2 (#161401) 2026-01-21 23:06:06 +01:00
Marc Mueller f7d7a4502e Update ruff to 0.14.13 (#161399) 2026-01-21 22:43:26 +01:00
Petro31 c7417d77b5 Update template select test framework (#161389) 2026-01-21 22:31:00 +01:00
Petro31 22018f1f80 Update template number tests to new framework (#161395) 2026-01-21 22:30:13 +01:00
Raphael Hehl 22c6704d81 Fix detection of multiple smart object types in single event (#161189)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-21 22:22:34 +01:00
Raphael Hehl 0552934b3c Bump uiprotect to 10.0.1 (#161397)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-01-21 22:20:33 +01:00
Joost Lekkerkerker bbe1d28e88 Refactor GitHub tests to patch the library instead (#160568) 2026-01-21 22:09:56 +01:00
Robert Resch b700a27c8f Enable apple tv on Python 3.14 (#161396) 2026-01-21 21:56:51 +01:00
Joost Lekkerkerker 0566a668a9 Add translation for add entry to RDW (#161329) 2026-01-21 21:28:27 +01:00
Marc Mueller 94f636bc2d Update pyatv to 0.17.0 (#161394) 2026-01-21 21:22:26 +01:00
Manu a6e7546142 Add support for sequence ID to publish action in ntfy integration (#161342) 2026-01-21 17:41:46 +00:00
Thomas55555 493319894b Use device_class for O3 in Google Air Quality (#161380) 2026-01-21 17:34:46 +01:00
Erik Montnemery 987396722b Adjust entity condition strings (#161055) 2026-01-21 16:56:47 +01:00
epenet 4f52b0363d Reorder unit conversion classes alphabetically (#161364) 2026-01-21 15:53:43 +00:00
Daniel Hjelseth Høyer 52e18ed6f6 Simplify tibber config (#160903) 2026-01-21 15:42:25 +01:00
Abílio Costa 4180175fd3 Improve automation variable name (#161340) 2026-01-21 14:27:18 +00:00
Maciej Bieniek e39ee8cae7 Bump imgw_pib to 2.0.1 (#161376) 2026-01-21 15:26:29 +01:00
epenet c214193087 Reorder recorder constants alphabetically (#161363) 2026-01-21 14:07:24 +01:00
Paulus Schoutsen 2d84847be5 Migrate apps added to sidebar to use new app panel (#161265)
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
2026-01-21 14:59:13 +02:00
Joost Lekkerkerker 0d69fd4535 Add integration_type hub to rainbird (#161303) 2026-01-21 13:42:24 +01:00
Joost Lekkerkerker 56f556864c Add integration_type hub to sensibo (#161326) 2026-01-21 13:41:18 +01:00
Manu c1b03dc553 Bump aiontfy to 0.7.0 (#161341) 2026-01-21 13:40:56 +01:00
epenet 07e76578e6 Add translation for add entry to Renault (#161361) 2026-01-21 13:40:25 +01:00
Manu bc45fd4e45 Add translation for add entry to Habitica integration (#161372) 2026-01-21 13:39:56 +01:00
Abílio Costa 0ea03f549c Support target conditions in script relation extraction (#161338) 2026-01-21 12:01:15 +00:00
Robert Resch 0ee46dbf5d Replace deprecated test-results-action action with codecov-action (#159202) 2026-01-21 12:33:32 +01:00
Thomas55555 e12f394f8e Bump google-air-quality-api to 3.0.0 (#161347) 2026-01-21 08:49:20 +01:00
Thomas55555 b40046264d Add ppb as a valid UOM for sensor/number Ozone device class (#159328)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-21 08:32:23 +01:00
Thomas55555 22afa1d248 Use device_class for NO2 in Google Air Quality (#161359) 2026-01-21 07:51:35 +01:00
Josef Zweck 8920ffbcdb Add translation for add entry to onedrive (#161336) 2026-01-21 07:06:22 +01:00
Thomas55555 a447c1b42e Use SO2 device_class in Google Air Quality (#161349) 2026-01-21 06:55:02 +01:00
Raphael Hehl 50211f75ed Bump uiprotect to 10.0.0 (#161350) 2026-01-21 00:59:46 +01:00
Thomas55555 27117c9d17 Add ppb as a valid UOM for sensor/number NO2 device class (#159426)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-01-20 22:35:11 +00:00
Scott K Logan 7c4cdd57b6 Set integration_type for rainforest_raven to 'hub' (#161343) 2026-01-20 21:46:47 +01:00
Josef Zweck 6af5698645 Bump onedrive-personal-sdk to 0.1.1 (#161337) 2026-01-20 20:14:58 +00:00
Erik Montnemery 75db2cde40 Improve light brightness triggers (#161233) 2026-01-20 20:14:15 +00:00
stegm 329dd05434 Bump pykoplenti to 1.5.0 (#161305) 2026-01-20 21:12:49 +01:00
Joost Lekkerkerker 53c53d03e0 Add integration_type hub to rituals_perfume_genie (#161312) 2026-01-20 21:10:11 +01:00
Joost Lekkerkerker 360b394d03 Add integration_type hub to rfxtrx (#161311) 2026-01-20 21:09:09 +01:00
Joost Lekkerkerker a663d55632 Add integration_type device to renson (#161310) 2026-01-20 21:07:50 +01:00
Joost Lekkerkerker 3fd266a513 Add integration_type hub to rehlko (#161309) 2026-01-20 21:07:21 +01:00
Joost Lekkerkerker 442c1d6242 Add integration_type hub to refoss (#161308) 2026-01-20 21:06:51 +01:00
Joost Lekkerkerker 0e2aae02f6 Add integration_type device to rapt_ble (#161307) 2026-01-20 21:04:45 +01:00
Joost Lekkerkerker 3227a6e49f Add integration_type device to rainforest_raven (#161306) 2026-01-20 21:04:10 +01:00
Joost Lekkerkerker 9d0cfb628b Add integration_type device to radiotherm (#161302) 2026-01-20 21:00:50 +01:00
Joost Lekkerkerker 4578fe0260 Add integration_type device to rabbitair (#161300) 2026-01-20 20:55:41 +01:00
Joost Lekkerkerker 0d92708108 Add integration_type device to qnap_qsw (#161299) 2026-01-20 20:54:58 +01:00
Joost Lekkerkerker cceb50071b Add integration_type device to ruuvitag_ble (#161319) 2026-01-20 20:53:14 +01:00
Joost Lekkerkerker 62f296c9dd Add integration_type device to ruuvi_gateway (#161318) 2026-01-20 20:52:32 +01:00
Joost Lekkerkerker ea1f280494 Add integration_type hub to russound_rio (#161317) 2026-01-20 20:48:32 +01:00
Joost Lekkerkerker 67108a2fc8 Add integration_type service to rova (#161316) 2026-01-20 20:47:36 +01:00
Joost Lekkerkerker 1ccbd5124e Add integration_type hub to roon (#161315) 2026-01-20 20:47:07 +01:00
Joost Lekkerkerker 818af90a7b Add integration_type device to roomba (#161314) 2026-01-20 20:45:35 +01:00
Joost Lekkerkerker 23bc78fa25 Add integration_type device to romy (#161313) 2026-01-20 20:44:38 +01:00
Josef Zweck 0b1cc7638f Enable smart chunk size in onedrive (#161170) 2026-01-20 20:41:48 +01:00
Joost Lekkerkerker c291a2fbc1 Add translation for add entry to NYT Games (#161327) 2026-01-20 20:35:50 +01:00
Joost Lekkerkerker 7379a4ff4b Add integration_type hub to sense (#161325) 2026-01-20 20:33:18 +01:00
Joost Lekkerkerker ddcf5cb749 Add integration_type hub to schlage (#161323) 2026-01-20 20:29:23 +01:00
Joost Lekkerkerker 4b10a542b0 Add integration_type hub to rympro (#161320) 2026-01-20 20:27:35 +01:00
Joost Lekkerkerker beea9fa74b Add integration_type service to sabnzbd (#161321) 2026-01-20 20:20:54 +01:00
Joost Lekkerkerker ce8fd16456 Add translation for add entry to Twitch (#161332) 2026-01-20 20:11:20 +01:00
Joost Lekkerkerker 2172d15489 Add translation for add entry to SmartThings (#161331) 2026-01-20 20:10:47 +01:00
Joost Lekkerkerker 0cfa0ed670 Add translation for add entry to Withings (#161333) 2026-01-20 20:07:54 +01:00
Joost Lekkerkerker f6839913d8 Add translation for add entry to Youtube (#161334) 2026-01-20 20:07:33 +01:00
Manu 8fa01497ee Add translation for add entry to Xbox integration (#161296) 2026-01-20 19:14:49 +01:00
Abílio Costa e077c65a77 Support target conditions in automation relation extraction (#161016) 2026-01-20 17:34:21 +00:00
Manu 7c49656fa8 Add translation for add entry to PlayStation Network integration (#161298) 2026-01-20 18:29:23 +01:00
Erik Montnemery 1730479c8d Remove reference of removed stub_blueprint_populate fixture from siren tests (#161294) 2026-01-20 16:16:22 +01:00
Thomas55555 bc28c8fd3c Add ppb as a valid uom for sensor/number CO device class (#159554) 2026-01-20 16:07:24 +01:00
Erik Montnemery c3616fd5df Add siren conditions (#161021) 2026-01-20 16:05:21 +01:00
epenet 6b97f2ac06 Use shorthand attributes in wyoming TTS (#161286) 2026-01-20 15:59:49 +01:00
Erik Montnemery deefcbcbe4 Remove stub_blueprint_populate test fixture (#161288) 2026-01-20 15:46:06 +01:00
Samuel Xiao e84aeb9f99 Switchbot Cloud: Add new supported Lock (#161276) 2026-01-20 15:27:27 +01:00
epenet ade3d8a657 Pass timestamps to Tuya wrapper skip_update (#161271) 2026-01-20 15:24:49 +01:00
Krisjanis Lejejs a65d9032ff Bump hass-nabucasa from 1.10.0 to 1.11.0 (#161283) 2026-01-20 14:50:00 +01:00
Martin Hjelmare b950a4eaf4 Fix nobo_hub options flow unload mocking (#161287) 2026-01-20 14:49:46 +01:00
Joost Lekkerkerker 3fe91751f5 Make add entry translatable (#159901) 2026-01-20 14:25:33 +01:00
Erwin Douna 6ee58b96ca Bump pyfirefly to 0.1.12 (#161278) 2026-01-20 13:51:09 +01:00
Erik Montnemery d1404e7905 Simplify logic in condition tests (#161239) 2026-01-20 10:39:47 +01:00
Paulus Schoutsen 7c34191813 Use new app panel instead of ingress page (#161264)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-20 10:54:56 +02:00
PolarBearEs 7540d04779 Remove duplicated MQTT_ORIGIN_INFO_SCHEMA in schemas.py (#161263) 2026-01-20 08:41:40 +01:00
mettolen d828130670 Bump pysaunum to 0.3.0 (#161255) 2026-01-20 08:31:48 +01:00
Adalberto Garcia Garces 2ec6c08bd7 Add 18 new Tuya device fixtures (#161225) 2026-01-20 07:33:59 +01:00
Thomas55555 48852bab7a Add ppb as a valid UOM for sensor/number SO2 device class (#159431) 2026-01-19 23:32:45 +00:00
Andres Ruiz 7d370f4513 Bump waterfurnace to 1.4.0 (#161244) 2026-01-19 20:33:29 +01:00
Aleksandr Oleinikov 9d97791faf Change default model for Ollama to qwen3:4b-instruct (#161202)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-19 12:56:18 -05:00
Norbert Rittel 4fe8982b68 Clarify description of lawn_mower.docked trigger (#161238) 2026-01-19 17:48:40 +00:00
Krisjanis Lejejs 8248ade211 Bump hass-nabucasa from 1.9.0 to 1.10.0 (#161226) 2026-01-19 15:02:09 +01:00
Brett Adams 572c0e393c Add reconfigure flow in Teslemetry (#160969)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:58:14 +01:00
Colin d25f2bab9a Increase test coverage in openevse (#160971)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-19 14:44:05 +01:00
Dave Morra 916812dd58 Add trigger for vacuum returning to dock (#158143)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-19 13:34:35 +01:00
Marc Mueller cea84aa3c8 Fix pytest usefixtures mark in proxmoxve tests (#161177) 2026-01-19 13:06:15 +01:00
Paulus Schoutsen af83fa809a Add app panel (#157554)
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
2026-01-19 13:08:00 +02:00
epenet 8c997cb6a9 Add selenium to FORBIDDEN_PACKAGE_EXCEPTIONS (#161216) 2026-01-19 10:47:00 +01:00
Jacob 4ccb6e4c8b Fix icons for 'moving' state (#161194) 2026-01-19 10:37:19 +01:00
epenet 37a45b1a92 Use shorthand attributes in qwikswitch sensor/binary_sensor (#161209) 2026-01-19 10:26:21 +01:00
dependabot[bot] ac84211702 Bump actions/ai-inference from 2.0.4 to 2.0.5 (#161206)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-19 10:25:42 +01:00
dependabot[bot] c209ddbb24 Bump actions/cache from 5.0.1 to 5.0.2 (#161207)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-19 10:18:59 +01:00
epenet 66ab50c737 Fix incorrect device class in wirelesstag binary_sensor (#161215) 2026-01-19 10:14:36 +01:00
Artur Pragacz 46074b0f9c Fix color temperature attributes in wiz (#161125) 2026-01-19 09:35:36 +01:00
Przemko92 56d8913159 Bump compit-inext-api to 0.4.2 (#161162) 2026-01-19 09:33:55 +01:00
epenet c1bbfec203 Use HassKey in wirelesstag (#161211) 2026-01-19 08:32:39 +01:00
epenet 290c2fd5b6 Use shorthand attributes in w800rf32 binary_sensor (#161210) 2026-01-19 08:32:12 +01:00
Tim Laing e472180fb2 Bump pyicloud to 2.3.0 (#161164) 2026-01-18 17:36:50 +01:00
David(Xiaobin) Lin a1ced9a259 Bump xiaomi-ble to 1.5.0 (#161154) 2026-01-18 17:34:51 +01:00
Daniel Hjelseth Høyer 80a700f668 Add more Tibber sensors (#161079)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-01-18 13:44:42 +01:00
mettolen 54fc963297 Add configurable sauna types to Saunum integration (#159782) 2026-01-18 13:43:11 +01:00
Joost Lekkerkerker 59776adeb3 Remove deprecated Homee entity (#161121) 2026-01-18 13:42:03 +01:00
Marc Mueller af53daa43c Fix vicare DeprecationWarnings (#161161) 2026-01-18 13:40:56 +01:00
tronikos 65123609ea Bump opower to 0.16.4 (#161153) 2026-01-18 10:12:43 +01:00
Manu 847adcf977 Add tests for media player actions in Xbox integration (#161156) 2026-01-18 10:09:05 +01:00
Daniel Hjelseth Høyer f0dc66cb53 Update Tibber library 0.35.0 (#161139) 2026-01-18 06:43:56 +01:00
Ivan Lopez Hernandez 54275a0ee4 Update Gemini SDK Version (#161137) 2026-01-17 15:21:22 -05:00
Manu 964f36bc50 Assume muted state in Xbox integration (#161118) 2026-01-17 21:05:53 +01:00
Erwin Douna e83cbc3fc5 Proxmox set integration type (#161141) 2026-01-17 20:59:40 +01:00
Tero Paloheimo e26d90d82b Bump xiaomi-ble to 1.4.3 (#161132) 2026-01-17 18:33:29 +01:00
Artur Pragacz da52482365 Add labs to core files (#161126) 2026-01-17 17:01:59 +01:00
Maciej Bieniek 6ba16ee9e9 Create cable unplugged entity only for Shelly Flood Gen4 (#161053) 2026-01-17 16:58:23 +01:00
Glenn de Haan fa29d8180f Improve quality scale to silver HDFury integration (#161077) 2026-01-17 16:57:25 +01:00
Zach Deibert 5d43efb22d Add support for Minecraft Server Java Edition 1.4 - 1.6 (#161035)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-17 16:14:17 +01:00
mettolen 3539c4bcec Update Saunum integration to platinum quality (#160824)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-17 15:44:45 +01:00
Allan Lewis 3e3ec4616c Update list of supported locations for London Air (#160884) 2026-01-17 15:44:34 +01:00
Steve Easley 907861effd Bump pyjvcprojector to 2.0.0 (#160739)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-17 15:44:29 +01:00
Zach Deibert 862a2bc95c Update mcstatus to 12.1.0 (#161124) 2026-01-17 15:41:47 +01:00
DeerMaximum 60f498c1fa Use configuration constants in NINA tests (#161119) 2026-01-17 14:22:32 +01:00
mettolen bb3617ac08 Add switch entitles to Airobot integration (#161090) 2026-01-17 13:17:22 +01:00
Niracler 48d1bd13fa Add sensor platform support to sunricher_dali integration (#159579) 2026-01-17 13:16:43 +01:00
Josef Zweck 8555bc9da0 Add reauthentication to openai_conversation (#161044)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-17 13:13:58 +01:00
epenet 9260394883 Mark preset_mode type hints as compulsory in climate/fan platforms (#161043) 2026-01-17 13:09:18 +01:00
DeerMaximum 8503637a80 Patch the NINA library instead of the HTTP requests (#161074) 2026-01-17 13:00:40 +01:00
Erwin Douna c993cd9bee Add Config Flow for ProxmoxVE (#142432)
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-17 12:59:58 +01:00
epenet 171013c0d0 Improve type hints in nx584 (#161065) 2026-01-17 12:56:31 +01:00
Evan Graham c8a7aa359e Add gpt-4.1-mini and gpt-4.1-nano to unsupported extended cache retention list (#161097) 2026-01-17 12:16:25 +01:00
Ludovic BOUÉ 88d8951657 Adjust battery voltage sensor display precision for Matter devices (#161088)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-17 11:55:44 +01:00
epenet b66ab3cf92 Improve type hints in ness_alarm (#161064) 2026-01-17 11:43:14 +01:00
epenet 253b32abd6 Use HassKey in qwikswitch (#161066) 2026-01-17 00:33:30 +01:00
Ludovic BOUÉ cc20072c86 Fix Matter Window covering config status entity name (#160960) 2026-01-17 00:25:48 +01:00
Franck Nijhof ae17b620f6 2026.1.2 (#161085) 2026-01-16 22:38:22 +01:00
Álvaro Fernández Rojas c5b72ac286 Update aioairzone to v1.0.5 (#160688) 2026-01-16 20:41:42 +00:00
Franck Nijhof 5f6dce5503 Bump version to 2026.1.2 2026-01-16 19:52:58 +00:00
Bram Kragten 6dd8692bb8 Update frontend to 20260107.2 (#161061) 2026-01-16 19:52:06 +00:00
Andrew Jackson 16f4849e88 Bump aiomealie to 1.2.0 (#161058) 2026-01-16 19:52:05 +00:00
Robert Resch 04809e47f1 Require admin for blueprint ws commands (#161008) 2026-01-16 19:52:03 +00:00
Matthias Alphart 691cf67f68 Update knx-frontend to 2026.1.15.112308 (#161004) 2026-01-16 19:52:02 +00:00
AlCalzone c2e1646473 Clean up unnecessary Z-Wave "device config changed" repairs (#161000) 2026-01-16 19:52:00 +00:00
Josef Zweck 9ac5560c41 Add descriptions to openai_conversation (#160979)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-16 19:51:59 +00:00
Niracler 68cbdcf3c9 Bump PySrDaliGateway from 0.18.0 to 0.19.3 (#160972)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-16 19:51:57 +00:00
tronikos 6474a1bf63 Bump opower to 0.16.3 (#160961) 2026-01-16 19:51:56 +00:00
Jaap Pieroen 572092d362 Decrease Essent update interval to 1 hour (#160959) 2026-01-16 19:51:54 +00:00
Arie Catsman 01ea5a1634 Bump pyenphase from 2.4.2 to 2.4.3 (#160912) 2026-01-16 19:51:52 +00:00
Marc Mueller b202c8b43e Update PyNaCl to 1.6.2 (#160909) 2026-01-16 19:51:51 +00:00
Robert Resch 79fd98753a Add support for packaging version >= 26 on the version bump script (#160858) 2026-01-16 19:51:49 +00:00
Kevin Stillhammer 447da083c0 accept leading zeros in sms_code for fressnapf_tracker (#160834) 2026-01-16 19:51:48 +00:00
tronikos 0643b36ed5 Bump opower to 0.16.2 (#160822) 2026-01-16 19:51:46 +00:00
Michael Hansen 4ee3ac16af Revert back to microVAD (#160821) 2026-01-16 19:51:44 +00:00
Álvaro Fernández Rojas 6824f38c68 Fix Airzone Q-Adapt select entities (#160695)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2026-01-16 19:51:42 +00:00
Bram Kragten f86db56d48 Update frontend to 20260107.2 (#161061) 2026-01-16 16:44:08 +01:00
Manu 3e2ebb8ebb Fix entity description in Mastodon (#161068) 2026-01-16 16:38:00 +01:00
Artur Pragacz 6e7b206788 Add update preview feature to labs (#160989) 2026-01-16 15:18:06 +01:00
Manu cee007b0b0 Add binary sensor platform to Mastodon (#161056) 2026-01-16 14:31:42 +01:00
Erwin Douna bd24c27bc9 SMA add selector strings/translation (#161060) 2026-01-16 13:56:15 +01:00
Andrew Jackson 49bd26da86 Bump aiomealie to 1.2.0 (#161058) 2026-01-16 13:37:22 +01:00
AlCalzone 49c42b9ad0 Clean up unnecessary Z-Wave "device config changed" repairs (#161000) 2026-01-16 12:51:42 +01:00
Josef Zweck 411491dc45 Type OpenAI config entry consistently (#161052) 2026-01-16 11:19:51 +01:00
Erik Montnemery 47383a499e Remove useless @pytest.mark.asyncio decorators from tests (#161050) 2026-01-16 10:19:23 +01:00
Erwin Douna f9aa307cb2 SMA add reconfigure flow (#160743)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-16 10:16:34 +01:00
epenet 7c6a31861e Improve type hints in egardia (#161048) 2026-01-16 10:08:24 +01:00
Robert Resch b2b25ca28c Revert "Add SmartThings media-player audio notifications" (#161049) 2026-01-16 10:06:30 +01:00
epenet ad9efab16a Improve type hints in concord232 (#161045) 2026-01-16 09:46:53 +01:00
Matthias Alphart e967d33911 Update knx-frontend to 2026.1.15.112308 (#161004) 2026-01-16 09:37:09 +01:00
epenet 86bacdbdde Use shorthand attributes in oasa_telematics (#160990) 2026-01-16 09:34:51 +01:00
Robert Resch 644a40674d Make shebang matcher stricter (#160986) 2026-01-16 09:21:19 +01:00
Raphael Hehl 2cf813758e Add per-camera ring volume control for UniFi Protect chimes (#161031)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-01-16 08:29:35 +01:00
DeerMaximum ad47eccf5f Bump pynina to 1.0.2 (#161013) 2026-01-16 08:24:58 +01:00
epenet 581b554a66 Improve type hints in digital_ocean (#161006) 2026-01-16 08:23:13 +01:00
epenet e4def9eb03 Improve type hints in envisalink (#161005) 2026-01-16 08:22:15 +01:00
epenet 5f2d17faf6 Improve type hints in homematic (#161002) 2026-01-16 08:21:30 +01:00
TheJulianJES e17565c069 Add Resideo X2S Smart Thermostat diagnostics to Matter fixture (#161037) 2026-01-16 08:20:42 +01:00
Erik Montnemery b856e04825 Add assist_satellite conditions (#161019) 2026-01-16 07:39:59 +01:00
epenet 67e676df4f Fix duplicate HVACMode in Tuya climate (#160918) 2026-01-15 22:12:24 +01:00
Erik Montnemery e2e7485e30 Remove unused test fixture from light condition tests (#160925) 2026-01-15 22:03:18 +01:00
Erik Montnemery 043a0b5aa6 Add alarm_control_panel conditions (#160975) 2026-01-15 20:17:02 +01:00
Jaap Pieroen 457af066c8 Decrease Essent update interval to 1 hour (#160959) 2026-01-15 19:42:18 +01:00
Robert Resch 3040fa3412 Require admin for blueprint ws commands (#161008) 2026-01-15 16:46:55 +01:00
epenet 1293e7ed70 Improve type hints in mfi (#160985) 2026-01-15 10:51:32 +01:00
Josef Zweck 3e81cea99f Add descriptions to openai_conversation (#160979)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-15 10:40:52 +01:00
Josef Zweck 4ce2dae701 Bump onedrive-personal-sdk to 0.1.0 (#160976) 2026-01-15 10:39:22 +01:00
epenet a14a8c4e43 Mark last_reset and state_class type hints as compulsory in sensor platform (#160982) 2026-01-15 10:38:34 +01:00
epenet 89e734d2de Improve type hints in ebusd (#160984) 2026-01-15 10:30:58 +01:00
Brett Adams 26c81f29e9 Teslemetry: Add OAuth error handling guards (#160968)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-15 10:28:11 +01:00
Niracler ce82e88919 Bump PySrDaliGateway from 0.18.0 to 0.19.3 (#160972)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-15 09:44:39 +01:00
Erik Montnemery 60316a1232 Deduplicate light condition descriptions (#160977) 2026-01-15 09:14:28 +01:00
Erik Montnemery aca4d3c5e6 Fix stale and misleading docstrings in alarm_control_panel.trigger (#160978) 2026-01-15 09:08:24 +01:00
epenet 9a93096e4b Move utility_meter service definitions (#160980) 2026-01-15 09:06:18 +01:00
tronikos 3b68aa0776 Bump opower to 0.16.3 (#160961) 2026-01-15 08:29:01 +01:00
Erik Montnemery 6ca60f0260 Update sunricher_dali test snapshots (#160973) 2026-01-15 08:26:46 +01:00
Erwin Douna fc281b2fae Firefly III fix background task (#160935) 2026-01-14 21:24:44 +01:00
Abílio Costa 3b111287d5 Remove entity performance optimization section from copilot-instructions (#160944) 2026-01-14 19:36:52 +00:00
Marc Mueller 00f42efc7e Update PyNaCl to 1.6.2 (#160909) 2026-01-14 18:21:09 +01:00
Erik Montnemery 9b9f94414b Add shared helper to assert conditions are hidden behind labs flag (#160941) 2026-01-14 16:53:17 +00:00
Erik Montnemery f01653633d Add shared enable_experimental_triggers_conditions test fixture (#160937) 2026-01-14 16:01:06 +00:00
Erik Montnemery 1ace3e248f Add create_target_condition test helper (#160936) 2026-01-14 16:19:41 +01:00
epenet d9bde85b58 Mark device_class type hints as compulsory in binary_sensor platform (#160934) 2026-01-14 16:18:04 +01:00
Joost Lekkerkerker 766a50abd7 Translate Hikvision NVR channel device name (#160862) 2026-01-14 16:16:26 +01:00
Niracler 9e6073099c Add button platform to sunricher_dali (#160908) 2026-01-14 16:02:25 +01:00
Erik Montnemery 892618d2ff Add fan conditions (#160832)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2026-01-14 15:50:22 +01:00
epenet 79c4164e03 Mark device_class type hints as compulsory in various platforms (#160929) 2026-01-14 15:47:17 +01:00
epenet 77dd4189b1 Mark device_class type hints as compulsory in sensor platform (#160931) 2026-01-14 15:46:40 +01:00
karwosts 4dbab23ada Duration selector for timer.change (#160645) 2026-01-14 15:45:32 +01:00
Erik Montnemery ce7f1a6f6a Adjust docstring in entity registry (#160926) 2026-01-14 15:14:46 +01:00
Erik Montnemery 6fc28298aa Update matter test snapshots (#160924) 2026-01-14 14:53:02 +01:00
Artur Pragacz 0130919128 Improve entity id generation (#160302) 2026-01-14 14:34:52 +01:00
Erik Montnemery 200627a695 Simplify light condition tests (#160910) 2026-01-14 14:15:51 +01:00
epenet 82926f8e9d Mark send_message type hints as compulsory in notify (#160850) 2026-01-14 13:01:33 +01:00
Arie Catsman 07fc81361b Bump pyenphase from 2.4.2 to 2.4.3 (#160912) 2026-01-14 12:57:05 +01:00
Martin Hjelmare bd8aed8e63 Bump zwave-js-server-python to 0.68.0 (#160911) 2026-01-14 12:55:48 +01:00
Martin Hjelmare 2c1693d50a Fix Generate requirements task (#160916) 2026-01-14 12:54:15 +01:00
Marek Tyburec 6e60b70691 Add SmartThings media-player audio notifications (#153287) 2026-01-14 12:50:27 +01:00
Erik Montnemery ac889feb75 Minor optimization of light conditions (#160915) 2026-01-14 11:49:56 +00:00
Erik Montnemery a902f3bb00 Improve comments in trigger and condition test helpers (#160830) 2026-01-14 11:42:32 +00:00
Erwin Douna fcb0c9500b Firefly III expand asyncio.gather usage (#160913) 2026-01-14 12:19:02 +01:00
Abílio Costa f049fbdf77 Add calendar event_started/event_ended triggers (#159659) 2026-01-14 11:12:17 +00:00
dependabot[bot] 20102cd83f Bump j178/prek-action from 1.0.11 to 1.0.12 (#160902)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-14 10:28:11 +01:00
Erik Montnemery 6d6324dae5 Fix some reversed asserts in sensor group tests (#160905) 2026-01-14 09:43:26 +01:00
Erik Montnemery 2ee5410a6c Remove set of _attr_extra_state_attributes in sensor group (#160846)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-14 09:21:54 +01:00
Erik Montnemery 56f02a41ca Adjust sensor group behavior (#152167) 2026-01-14 08:23:34 +01:00
Erwin Douna d43102de1b Bump pyportainer 1.0.23 (#160878) 2026-01-14 07:09:35 +01:00
Ludovic BOUÉ 2bcd02b296 Add MatterOutdoorTemperature attribute to Matter binary sensor discovery schema only if OutdoorTemperature exists (#160879) 2026-01-14 06:58:55 +01:00
Brett Adams ad11c72488 Add retry logic to Teslemetry coordinators (#160756)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 01:36:43 +01:00
Manu ddfa6f83c3 Refactor Namecheap DNS update logic to use a coordinator (#160863) 2026-01-14 01:34:27 +01:00
epenet 85baf7a41d Improve type hints in mobile_app notify (#160853)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2026-01-14 01:26:10 +01:00
epenet bf4d5a0bab Improve type hints in telegram notify (#160855) 2026-01-14 01:26:00 +01:00
Erwin Douna 16527ba707 Melcloud small config flow refactor (#160892) 2026-01-14 01:15:36 +01:00
Brett Adams 0612ea4ee8 Bump tesla-fleet-api to 1.4.2 (#159616)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-14 01:14:58 +01:00
Ville Skyttä 9e842152f7 Upgrade prettier-plugin-sort to 4.2.0 (#160894) 2026-01-14 01:13:16 +01:00
Erwin Douna 63e79c3639 Firefly III add asyncio.gather pattern (#160886) 2026-01-14 01:12:44 +01:00
Erwin Douna d0e4a7fa75 Melcloud Pythonic refactor init (#160891) 2026-01-14 00:38:41 +01:00
Glenn de Haan 815976b9a4 Add HDFury sensor platform (#160628) 2026-01-14 00:35:48 +01:00
scheric 86a5cc5edb Add keep_alive to generic_thermostat config flow (#156641)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-01-13 23:20:40 +00:00
Björn Ebbinghaus 3ebc08c5ec Prefer explicit DeviceClass over hint in entity_id in homekit (#152507)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2026-01-13 23:00:58 +00:00
Paul Bottein 1bcbebb00c Use config entity category for Matter door lock operating mode (#160507) 2026-01-13 23:46:54 +01:00
Jan Bouwhuis 2895225552 Improve test coverage on mobile app legacy notify service action (#160869) 2026-01-13 22:39:01 +01:00
Erwin Douna f4f772ea31 Bump pyfirefly 0.1.11 (#160877) 2026-01-13 22:37:32 +01:00
Manu 66f60e6757 Add reconfigure flow to Namecheap integration (#160870) 2026-01-13 19:47:50 +00:00
Lukas 72d299f088 Mark pooldose as strictly typed (#160779)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-13 19:40:52 +00:00
Thomas55555 9c66561381 Make pollutants dynamic in Google Air Quality (#160747) 2026-01-13 19:28:41 +00:00
Erik Montnemery e762f839fa Improve sensor group tests (#160854) 2026-01-13 20:16:06 +01:00
Joost Lekkerkerker 0c9d97c89f Unmark integrations with a config flow as legacy (#160861) 2026-01-13 19:59:39 +01:00
Robert Resch fb3ee34c81 Bump prek to 0.2.28 (#160864) 2026-01-13 18:59:07 +01:00
Daniel Hjelseth Høyer cb99400128 Add Tibber binary sensors (#160365)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-13 18:56:14 +01:00
divers33 58ef925a07 Refactor MELCloud integration to use DataUpdateCoordinator (#160131)
Co-authored-by: divers33 <divers33@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-13 18:52:37 +01:00
Paul Tarjan 41bbfb8725 Add camera platform support to Hikvision integration (#160252)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-13 18:38:18 +01:00
Manu ed226e31b1 Remove defusedxml dependency from Namecheap DynamicDNS integration (#160656) 2026-01-13 18:16:50 +01:00
Robert Resch e900bb9770 Add support for packaging version >= 26 on the version bump script (#160858) 2026-01-13 18:14:46 +01:00
Matthias Alphart d173d25072 Refactor KNX expose entity class (#160705) 2026-01-13 17:25:46 +01:00
Colin 0959896984 openevse: Use a data update coordinator (#160757)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-13 17:04:56 +01:00
epenet 4a3ae454b8 Improve type hints in pushsafer notify (#160851) 2026-01-13 16:46:01 +01:00
Joost Lekkerkerker f2cf6b69bf Use extended entity descriptions in openevse (#160611) 2026-01-13 16:44:29 +01:00
epenet 176f847ebb Split Tuya climate wrappers (#160839) 2026-01-13 16:38:40 +01:00
epenet 277419aafb Fix logging in mycroft notify (#160852) 2026-01-13 16:28:17 +01:00
Willem-Jan van Rootselaar d2b8d165d7 Optimize BSB-Lan integration startup (#160784) 2026-01-13 16:07:33 +01:00
Jamin bf74e67700 Bump voip-utils to 0.3.5 (#160848) 2026-01-13 16:03:55 +01:00
Chris 5c3b85a37a Add authentication to config flow in openevse (#160521)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-13 16:03:40 +01:00
Manu 8543f3f989 Add config flow to Namecheap DynamicDNS integration (#160841) 2026-01-13 15:46:15 +01:00
Sebastian YEPES 52a8a66a91 Bump qingping-ble to 1.1.0 (#160815) 2026-01-13 15:35:50 +01:00
dependabot[bot] 002a931e70 Bump github/codeql-action from 4.31.9 to 4.31.10 (#160829)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 15:33:27 +01:00
Daniel Hjelseth Høyer 0667bfc81d Remove old migration for Tibber (#160845) 2026-01-13 15:31:28 +01:00
Michael Hansen 329b2c840d Revert back to microVAD (#160821) 2026-01-13 08:09:17 -06:00
Robert Resch ea7e94bcc1 Replace pre-commit by prek (#160427) 2026-01-13 15:09:02 +01:00
nasWebio cc30add73a Add climate platform to NASweb integration (#141583)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2026-01-13 14:55:12 +01:00
Simone Chemelli 21cfb9a0e5 Add guest Wi-Fi QR code for Vodafone Station (#160307)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-13 13:57:59 +01:00
Erik Montnemery 143eadd887 Remove progress_step date entry flow decorator (#160844) 2026-01-13 13:52:57 +01:00
Erik Montnemery 855da1d070 Adjust light condition test (#160831) 2026-01-13 10:58:34 +01:00
AlCalzone d5be76d7e6 Make integration scaffolding a bit more newbie-friendly (#160837) 2026-01-13 10:39:49 +01:00
Matthias Alphart 5f396332df Update xknx to 3.14.0 (#160813) 2026-01-13 10:22:49 +01:00
Kevin Stillhammer 56e638e170 accept leading zeros in sms_code for fressnapf_tracker (#160834) 2026-01-13 10:18:15 +01:00
Norbert Rittel 52b90c7706 Make light conditions consistent with triggers and actions (#160477) 2026-01-13 09:45:31 +01:00
Erik Montnemery a6221d16b6 Add helper for creating entity condition tests (#160425) 2026-01-13 08:25:41 +01:00
tronikos 51701cab7c Bump opower to 0.16.2 (#160822) 2026-01-12 19:20:06 -08:00
Raphael Hehl 010e1f2d0d Bump uiprotect to 8.1.1 (#160816) 2026-01-12 23:06:50 +01:00
Jonathan de Jong 66909fc9ca Support HVAC mode in set temperature calls in Mill (#155416)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-12 21:46:20 +01:00
Lukas 90a28c95c8 Bump python-pooldose to 0.8.2 (#160800) 2026-01-12 20:20:33 +01:00
Erik Montnemery 83f2c53e8c Disable pyright type checking in VS Code (#160528) 2026-01-12 20:19:19 +01:00
Ludovic BOUÉ 514b6e243c Rename Matter Eve Thermostat Fixture to eve_thermo_v4 (#160796) 2026-01-12 20:16:13 +01:00
Krisjanis Lejejs 742230c7be Bump hass-nabucasa from 1.8.0 to 1.9.0 (#160788) 2026-01-12 19:50:48 +01:00
Ludovic BOUÉ acb6b1444e Add fixture for Matter Eve Thermo 20ECD1701 (v5) with detailed attributes (#160795) 2026-01-12 18:52:18 +01:00
Erwin Douna f358b2231a Add match case in perform action (#160150) 2026-01-12 18:25:51 +01:00
Joakim Sørensen fd24cffa6b Block untill done while setting up cloud in tests (#160780) 2026-01-12 17:32:06 +01:00
Yuxin Wang 0b5d6ee538 Add TIMESTAMP device classes to corresponding sensors in APCUPSD (#160577) 2026-01-12 17:10:25 +01:00
DeerMaximum d125bb88d1 Use load_json_object_fixture in tests for NINA (#160690)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-12 17:09:18 +01:00
Ludovic BOUÉ 2ab51f582a Add Matter occupied setback for thermostats (#155439) 2026-01-12 16:47:43 +01:00
epenet f9b32811b2 Move typed ConfigEntry to coordinator module in point (#160786) 2026-01-12 16:34:38 +01:00
seppwabala 41a423e140 Add support for eds0065 in onewire (#160094)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-12 16:21:00 +01:00
Xiangxuan Qu f717867657 Pass config_entry explicitly to Point coordinator (#160578) 2026-01-12 15:55:41 +01:00
J. Nick Koston ab202a03db Handle deleted issue during repair flow translation check (#160698) 2026-01-12 15:52:36 +01:00
Álvaro Fernández Rojas 46a3e5e5b5 Fix Airzone Q-Adapt select entities (#160695)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2026-01-12 15:48:07 +01:00
Krisjanis Lejejs 0163a4d289 Bump hass-nabucasa from 1.7.0 to 1.8.0 (#160775) 2026-01-12 15:46:49 +01:00
Willem-Jan van Rootselaar 6c1bf31a3c Bump python-bsblan to version 4.1.0 (#160676) 2026-01-12 15:44:03 +01:00
Michael a434760a80 Complete entity name and icon translations in FRITZ!Box Tools (#160746)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-12 15:43:28 +01:00
Jevgeni Kiski 798990fadc Bump vallox-websocket-api to 6.0.0 (#160742) 2026-01-12 15:30:17 +01:00
Glenn de Haan b3d9d92e4a Add HDFury diagnostics (#160641) 2026-01-12 15:08:19 +01:00
Lukas 1082a9ca69 Pooldose: Sync with docs update (#160190) 2026-01-12 14:41:46 +01:00
Joost Lekkerkerker c247f56658 Fix fitbit icon (#160750) 2026-01-12 11:08:59 +01:00
Paul Tarjan e7f71781f1 Fix Hikvision NVR binary sensors not being detected (#160254)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 11:04:30 +01:00
Josef Zweck c4b2c5e621 Fix missing key for brew by weight in lamarzocco (#160722) 2026-01-12 11:03:36 +01:00
Thomas55555 7779609a76 Add more pollutants to Google Air Quality (#160738) 2026-01-12 11:02:18 +01:00
Duco Sebel 7b9a5f897c Bump python-homewizard-energy to 10.0.1 (#160736) 2026-01-12 10:59:55 +01:00
epenet 6eccbfc1cf Fix Requirement parsing in RequirementsManager (#160485) 2026-01-12 10:55:39 +01:00
Artur Pragacz 0da518e951 Fix scrape sensor device name (#160765) 2026-01-12 10:53:25 +01:00
Bram Kragten e5851b7920 Update frontend to 20260107.1 (#160644) 2026-01-12 10:51:49 +01:00
Artur Pragacz 1b9364e8b5 Assign device_entry earlier in entity platform (#160767) 2026-01-12 10:49:01 +01:00
Carter Green 8460d4f5e2 Yolink diagnostic sensors (#160749) 2026-01-12 10:33:49 +01:00
Artur Pragacz 8fd35cd70d Rename registry imports in entity platform (#160766) 2026-01-12 10:27:03 +01:00
MarkGodwin 88be115699 Bump tplink_omada quality scale to bronze (#160762) 2026-01-12 09:52:46 +01:00
J. Nick Koston 7f4063f91e Bump aiodns to 4.0.0 (#160707) 2026-01-11 07:31:31 -10:00
mattreim 080ba46885 Add model id RODRET wireless dimmer (#160636) 2026-01-11 18:22:19 +01:00
Brett Adams 2cb028ee79 Catch any migration failures in Teslemetry (#160549) 2026-01-11 16:46:30 +01:00
mettolen 72655dbf0b Pump pysaunum to 0.2.0 (#160668) 2026-01-11 16:14:45 +01:00
Erwin Douna 153278221d Bump pytado 0.18.16 (#160724) 2026-01-11 13:24:22 +01:00
Daniel Hjelseth Høyer 4942ce7e86 Better handling of ratelimiting from Tibber (#160599)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-01-11 11:40:27 +01:00
hanwg 98e918cd8a Improve polling error messages for Telegram bot (#160675) 2026-01-11 06:54:50 +01:00
J. Nick Koston 1efc87bfef Bump easyenergy to 2.2.0 (#160709) 2026-01-10 18:54:50 -10:00
Simon Delberghe b4360ccbd9 Move condition to prioritize preset mode (eco/comfort...) instead of program name in Overkiz (#160189) 2026-01-10 23:58:19 +01:00
Ernst Klamer ce234d69a7 Revert bthome-ble back to 3.16.0 to fix missing data (#160694) 2026-01-10 09:47:30 -10:00
Álvaro Fernández Rojas b2a198e230 Update aioairzone to v1.0.5 (#160688) 2026-01-10 20:43:10 +01:00
Michael Hansen 538009d2df Bump pysilero-vad to 3.2.0 (#160691) 2026-01-10 13:35:46 -06:00
Clifford Roche 99329851a2 Bump greeclimate to 2.1.1 (#160683) 2026-01-10 19:51:04 +01:00
DeerMaximum f8ec395e96 Use snapshots for binary sensor tests in Nina (#160532) 2026-01-10 17:47:29 +01:00
mettolen 98fe189edf Add recalibrate CO2 button to Airobot (#160679) 2026-01-10 17:37:14 +01:00
Samuel Xiao 7b413e3fd3 Bumb switchbot api to v2.10.0 (#160657) 2026-01-10 13:01:55 +01:00
Paul Tarjan 00ca5473d4 Bump pyhik to 0.4.0 (#160654) 2026-01-10 08:04:29 +01:00
Martin Hjelmare 33c808713e Fix Z-Wave creating notification binary sensor for idle state (#160604) 2026-01-10 02:43:13 +01:00
Sid c97437fbf3 Add the professionel5e filter series to eheimdigital (#155550) 2026-01-09 21:24:01 +01:00
Jordan Harvey ad8f14fec1 Bump pynintendoparental to 2.3.2 (#160626)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-01-09 20:09:31 +01:00
karwosts 7df586eff1 Use duration selector for timer service (#160391) 2026-01-09 20:07:32 +01:00
Manu f6fa95d2f7 Rename Namecheap FreeDNS to Dynamic DNS (#160625) 2026-01-09 19:37:03 +01:00
Tero Paloheimo 23a8300012 Add Ruuvi IAQS to Ruuvi BLE (#160529) 2026-01-09 19:04:30 +01:00
Glenn de Haan 694d67d2d5 Add HDFury switch platform (#160620) 2026-01-09 18:08:37 +01:00
mettolen a26c910db7 Add number entities to Saunum integration (#160444) 2026-01-09 18:04:49 +01:00
mettolen ac9d04624b Update Airobot integration to gold quality tier (#160525) 2026-01-09 18:02:27 +01:00
James a0ec7bde33 Introduce better types in Yardian coordinator (#152641)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-09 17:55:08 +01:00
Vasily G. 5f7dc49215 Spotify: user Liked Songs collection playable (#160452)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-09 17:48:39 +01:00
LG-ThinQ-Integration f79eef150e Add humidifier entity for humidifier and dehumidifier to LG ThinQ (#152593)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2026-01-09 17:41:20 +01:00
Arie Catsman 1733599442 Change device class to energy_storage for some enphase_envoy battery entities (#160603) 2026-01-09 16:48:00 +01:00
Thomas55555 3bde4f606b Bump google-air-quality-api to 2.1.2 (#160561) 2026-01-09 16:40:38 +01:00
Christopher Fenner afb635125c Bump PyViCare to 2.55.1 (#156875) 2026-01-09 16:39:31 +01:00
James 876d54ad4d Yardian: Add sensors (#153020)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-09 16:31:29 +01:00
Tom Matheussen c20cd8fb94 Add missing segment speed icons for WLED (#160597) 2026-01-09 15:42:23 +01:00
Colin e15b2ec0cb openevse: Add device_info and unique_id to sensors (#160543)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-09 15:02:07 +01:00
azerty9971 1829452ef1 Change Tuya covers to prefer set_position instead of instruction_wrapper (#160526) 2026-01-09 14:31:31 +01:00
Dan Čermák 9d8dc9ec06 Fix JSON serialization of time objects in anthropic tool results (#160459)
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2026-01-09 12:06:36 +01:00
Bram Kragten 72a3523193 Fix trigger selectors (#160519) 2026-01-09 11:43:33 +01:00
Maciej Bieniek 7c3541e983 Fix AttributeError for missing/incomplete health data in Tractive (#160553) 2026-01-09 10:55:33 +01:00
Michael 8246fc78fa Fix for older Fritzbox models which do not support smarthome triggers (#160555) 2026-01-09 10:52:44 +01:00
tronikos 78dd3aee10 Bump opower to 0.16.1 (#160588) 2026-01-09 10:51:39 +01:00
Brett Adams c22e578aca Fix config flow bug in Tesla Fleet (#160591) 2026-01-09 10:41:33 +01:00
Brett Adams 1021c1959e Fix Climate signal in Teslemetry (#160571) 2026-01-09 10:41:18 +01:00
Brett Adams d3161d8e92 Fix translation of unknown response in Teslemetry & Tesla Fleet (#160506) 2026-01-09 10:16:00 +01:00
Johann Kellerman fc468b56c8 Bump pysma to 1.1.0 (#160583) 2026-01-09 10:14:15 +01:00
Markus Jacobsen ea48dc3c58 Add battery charging binary sensor to Bang & Olufsen (#160527)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-09 09:59:20 +01:00
cdnninja 11dde08d79 Correct vesync missing return type (#160580) 2026-01-09 08:09:31 +01:00
epenet 5e43708a40 Skip Tuya update if it is not relevent (#160407) 2026-01-09 07:01:43 +01:00
osohotwateriot 1ac2280266 Change nettleie to grid fee in english strings (#160516) 2026-01-08 23:11:42 +00:00
puddly 6b1ad8d2d1 Bump serialx to v0.6.2 (#160545) 2026-01-08 23:10:29 +00:00
Michael Hansen c1741237f4 Bump pysilero-vad to 3.1.0 (#160554) 2026-01-08 23:09:18 +00:00
LG-ThinQ-Integration 8ecacd6490 Add target_humidity_step attribute to humidifier (#156906)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2026-01-08 23:06:31 +00:00
Glenn de Haan 188ab3930c Add HDFury button platform (#160548) 2026-01-08 22:14:23 +01:00
Michael Hansen a8dba53185 Revert "Update voluptuous and voluptuous-openapi" (#160530) 2026-01-08 10:25:46 -06:00
Erwin Douna a2ef0c9a75 Portainer add prune unused images (#160137)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-08 17:05:45 +01:00
Jan Bouwhuis 5a1fe17580 Bump Intergas Incomfort-client to v0.6.11 (#160520) 2026-01-08 16:44:21 +01:00
ElCruncharino 34388f52a6 Add asyncio-level timeout to Backblaze B2 uploads (#160468) 2026-01-08 16:39:47 +01:00
DeerMaximum fc2199fcf7 Add bronze quality scale for NINA (#155191) 2026-01-08 15:53:43 +01:00
DeerMaximum 2236f8cd07 Fix typo in NINA config flow (#160523) 2026-01-08 15:44:50 +01:00
Klaas Schoute 8d376027bf Add support for gas meter in Powerfox integration (#158196)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-08 14:53:00 +01:00
JHSL 47e91bc2ec Add dishwasher program Dishcare.Dishwasher.Program.IntensiveFixedZone (#160463) 2026-01-08 14:45:44 +01:00
Zoltán Farkasdi 33d1cdd0ac Refactor netatmo binary sensors (#160352) 2026-01-08 13:24:05 +01:00
Brett Adams f46de054ba Add missing data_description translations to Tessie (#160511)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 13:02:36 +01:00
Brett Adams 741aa714dd Add missing PARALLEL_UPDATES to Tesla Fleet (#160510) 2026-01-08 12:40:38 +01:00
osohotwateriot 5fac7d4ffb Add Nettleie optimization option (#160494) 2026-01-08 12:24:00 +01:00
Glenn de Haan 341c441e61 Add HDFury integration (#159996) 2026-01-08 12:21:04 +01:00
wollew a1edf0a77c fix rain sensor for some rare velux windows (#160504) 2026-01-08 12:19:40 +01:00
Erik Montnemery dd84b52c7b Bump python-otbr-api to 2.7.1 (#160496) 2026-01-08 12:10:39 +01:00
Etienne C. 43ced677e5 Get the polling state of a sensor from a template (#159900) 2026-01-08 12:03:45 +01:00
Ville Skyttä 7a696935ed Add icons for Nord Pool highest and lowest price sensors (#159729) 2026-01-08 11:27:17 +01:00
Deyan Petrov be3be360a7 Make Tuya binary sensor consider only updated properties (#160404)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2026-01-08 09:47:27 +01:00
Mick Vleeshouwer 092ebaaeb1 Bump pyOverkiz to 1.19.4 (#160457) 2026-01-08 08:41:30 +01:00
Retha Runolfsson e8025317ed Bump PySwitchbot to 0.76.0 (#160470) 2026-01-08 08:39:23 +01:00
wollew 39b025dfea catch and wrap exceptions when doing pyvlx actions in velux entities (#160430)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-08 00:06:26 +01:00
DeerMaximum 1b436a8808 Use async_configure in NINA to set flow data in tests (#160435)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-07 23:48:42 +01:00
Markus Jacobsen a7440e3756 Add battery support to Bang & Olufsen (#159994) 2026-01-07 23:40:22 +01:00
wollew 2c7852f94b remove workaround for recognition of closed velux windows (#160433) 2026-01-07 23:39:37 +01:00
Maikel Punie bd4653f830 Update velbus quality scale rules for docs (#160200) 2026-01-07 23:32:45 +01:00
Tero Paloheimo c0b2847a87 Update ruuvitag-ble to 0.4.0 (#160441) 2026-01-07 23:32:03 +01:00
J. Diego Rodríguez Royo 8853f6698b Add steam mode and hot air gentle programs to Home Connect (#160445) 2026-01-07 23:10:20 +01:00
Artem Draft b1a3ad6ac3 Improve Bravia TV logging messages (#160394) 2026-01-07 23:09:46 +01:00
Arie Catsman dafa2e69e2 Optimize enphase_envoy code for on_phase use (#160448) 2026-01-07 23:09:00 +01:00
Chris 2c6d6f8ab4 Add unique_id to openevse user flow and import flow (#160436)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-07 23:06:25 +01:00
J. Diego Rodríguez Royo 10d32b7f23 Bump aiohomeconnect to version 0.28.0 (#160438) 2026-01-07 20:44:36 +01:00
TheJulianJES e4dc4e0ced Bump ZHA to 0.0.84 (#160440) 2026-01-07 19:57:09 +01:00
Maikel Punie 6f9794f235 Add icon translations for velbus (#160439) 2026-01-07 19:26:47 +01:00
Paul Bottein b8cff13737 Fix hvac_mode validation in climate.hvac_mode_changed trigger (#160364) 2026-01-07 17:44:03 +01:00
Bram Kragten 7777714cc0 Update frontend to 20260107.0 (#160434) 2026-01-07 17:34:23 +01:00
Chris f15d5cdf2a Add zeroconf discovery to openevse (#160318)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-07 16:42:32 +01:00
DeerMaximum 6181f4e7de NINA Use MockConfigEntry to setup integration in test (#160324) 2026-01-07 16:33:06 +01:00
Robert Resch 80df3b5b80 Bump deebot-client to 17.0.1 (#160428) 2026-01-07 16:07:11 +01:00
Simone Chemelli 6e32a2aa18 Bump aiovodafone to 3.1.1 (#160429) 2026-01-07 15:34:46 +01:00
Abílio Costa 3b575fe3e3 Support target triggers in automation relation extraction (#160369) 2026-01-07 15:15:44 +01:00
Joost Lekkerkerker 229400de98 Make Watts depend on the cloud integration (#160424) 2026-01-07 15:07:24 +01:00
Norbert Rittel e963adfdf0 Fix capitalization in openevse data_description string (#160423) 2026-01-07 14:53:19 +01:00
Simone Chemelli fd7bbc68c6 Bump aioshelly to 13.23.1 (#160420) 2026-01-07 14:49:18 +01:00
Robert Resch 9281ab018c Constraint aiomqtt>=2.5.0 to fix blocking call (#160410)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-07 14:21:49 +01:00
Andres Ruiz 80baf86e23 Add codeowners and integration_type for waterfurnace (#160397) 2026-01-07 13:12:58 +01:00
Simone Chemelli db497b23fe Small cleanup for Vodafone Station tests (#160415) 2026-01-07 12:50:12 +01:00
cdnninja a2fb8f5a72 Add Vesync Air Fryer Sensors (#160170)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-07 12:41:34 +01:00
hanwg 6953bd4599 Fix schema validation error in Telegram (#160367) 2026-01-07 12:27:17 +01:00
Xiangxuan Qu 225be65f71 Fix IndexError in Israel Rail sensor when no departures available (#160351)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-07 12:22:39 +01:00
momala454 7b0463f763 Add additional lens modes 4 to 10 to JVC projector remote (#159657)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-07 12:22:19 +01:00
Luke Lashley 4d305b657a Bump python-roborock to 4.2.1 (#160398) 2026-01-07 11:23:40 +01:00
Paul Tarjan d5a553c8c7 Fix Ring integration log flooding for accounts without subscription (#158012)
Co-authored-by: Robert Resch <robert@resch.dev>
2026-01-07 11:14:05 +01:00
Ivan Dlugos 9169b68254 Bump sentry-sdk to 2.48.0 (#159415)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-07 11:05:38 +01:00
Colin fde9bd95d5 Replace openevse backend library (#160325) 2026-01-07 10:25:15 +01:00
Marc Mueller e4db8ff86e Update guppy3 to 3.1.6 (#160356) 2026-01-07 10:11:01 +01:00
Erik Montnemery a084e51345 Add test helpers for numerical state triggers (#160308)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2026-01-07 08:53:35 +01:00
Luke Lashley 00381e6dfd Remove q7 total cleaning time for Roborock (#160399) 2026-01-06 20:27:09 -08:00
Michael Hansen b6d493696a Bump intents to 2026.1.6 (#160389) 2026-01-06 17:11:54 -06:00
Artem Draft 5f0500c3cd Add SSL support in Bravia TV (#160373)
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
2026-01-06 23:59:47 +01:00
dontinelli c61a63cc6f Bump solarlog_cli to 0.7.0 (#160382) 2026-01-06 23:59:16 +01:00
Raphael Hehl 5445a4f40f Bump uiprotect to 8.0.0 (#160384)
Co-authored-by: RaHehl <rahehl@users.noreply.github.com>
2026-01-06 23:57:19 +01:00
Daniel Hjelseth Høyer 2888cacc3f Bump pyTibber to 0.34.1 (#160380)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2026-01-06 23:56:26 +01:00
TheJulianJES 16f3e6d2c9 Bump ZHA to 0.0.83 (#160342) 2026-01-06 12:11:40 -05:00
Bram Kragten 7a872970fa Update frontend to 20251229.1 (#160372) 2026-01-06 17:53:56 +01:00
Bram Kragten 4f5ca986ce Fix number or entity choose schema (#160358) 2026-01-06 17:23:24 +01:00
Artem Draft b58e058da5 Bump pybravia to 0.4.1 (#160368) 2026-01-06 16:42:58 +01:00
epenet badebe0c7f Refactor Tuya event platform to use DeviceWrapper (#160366) 2026-01-06 16:09:13 +01:00
mettolen 7817ec1a52 Update Saunum integration to gold quality tier (#159783) 2026-01-06 16:07:28 +01:00
epenet c773998946 Remove default in Tuya DeviceWrapper options (#160303) 2026-01-06 13:06:53 +01:00
Mika 2bc9397103 Fix missing state class to solaredge (#160336) 2026-01-06 12:36:49 +01:00
Daniel Hjelseth Høyer 685534b17c Add more Tibber sensors (#160354) 2026-01-06 11:18:35 +01:00
tronikos c740f44bfa Bump opower to 0.16.0 (#160348) 2026-01-06 10:25:43 +01:00
mettolen ce471d0222 Add button entity to Airobot integration (#160169) 2026-01-06 08:57:24 +01:00
Manu 53ed344fe0 Add action exceptions to Duck DNS (#160331) 2026-01-06 08:38:22 +01:00
Manu 5f8f3c961a Remove stale devices in Xbox integration (#160337) 2026-01-06 08:27:42 +01:00
Aidan Timson 9d0c5530f2 Bump systembridgeconnector to 5.3.1 (#160326) 2026-01-06 08:09:25 +01:00
abelyliu d114fe4fbd Add report_type to Tuya diagnostic (#160311) 2026-01-06 07:37:48 +01:00
Daniel Hjelseth Høyer f03d44d5b5 Bump pyTibber to 0.34.0 (#160333) 2026-01-06 00:55:28 +01:00
Frédéric 35f4464d4a Add Resideo X2S Smart Thermostat to Matter fan-only mode list (#160260) 2026-01-06 00:24:20 +01:00
DeerMaximum fc2530e979 Use a fixture in NINA to mock async_setup_entry (#160323) 2026-01-05 21:51:10 +01:00
Manu 354fafda1a Refactor Xbox coordinators (#160174) 2026-01-05 21:31:57 +01:00
Sid 5b0dab479d Bump eheimdigital to 1.5.0 (#160312) 2026-01-05 21:30:05 +01:00
Daniel Hjelseth Høyer 1e1f414849 Fix unit for Tibber sensor (#160319) 2026-01-05 21:27:00 +01:00
Xidorn Quan 7c81df6c5c Fix rain count sensors' state class of Ecowitt (#158204) 2026-01-05 21:02:21 +01:00
J. Nick Koston 95d7c42e6a Require service_uuid and service_data_uuid to match hue ble (#160321) 2026-01-05 19:47:31 +01:00
Joakim Sørensen 19fd80035e Add connection check before registering cloudhook URL (#160284) 2026-01-05 09:35:49 -05:00
Martin Hjelmare 8e30787ae6 Test hassfest translations gen_strings_schema (#159464) 2026-01-05 15:27:03 +01:00
epenet 7133da928f Add max_value/min_value/value_step to Tuya DeviceWrapper (#160300) 2026-01-05 14:56:17 +01:00
Colin 3f9a41d393 Add openevse config flow (#158968)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-05 14:49:36 +01:00
epenet f4caf36204 Use generic DeviceWrapper in Tuya cover (#160301) 2026-01-05 14:45:13 +01:00
Bram Kragten 079866e384 Fix humidifier trigger turned on icon (#160297) 2026-01-05 13:45:31 +01:00
epenet dce0db78aa Use generic DeviceWrapper in Tuya sensor (#160299) 2026-01-05 13:45:08 +01:00
epenet fffc18d28b Use generic DeviceWrapper in more Tuya platforms (#160298) 2026-01-05 13:44:45 +01:00
cdnninja c7cbcbc32d Refactor entity unavailable handling in VeSync (#160274) 2026-01-05 13:17:35 +01:00
Samuel Xiao aebcdd6e7a Switchbot Cloud: Add new supported light (#160282) 2026-01-05 13:12:02 +01:00
Paul Tarjan 3be92510f8 Fix Tesla update showing scheduled updates as installing (#158681) 2026-01-05 12:42:58 +01:00
Matrix 4d8448e82a Bump yolink api to 0.6.1 (#160293) 2026-01-05 12:37:26 +01:00
Daniel Hjelseth Høyer 625bc467d4 Move Tibber to OAuth (#156690)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-05 12:36:41 +01:00
Steven Looman 47573b7f6a Bump async-upnp-client to 0.46.2 (#160188) 2026-01-05 12:33:40 +01:00
epenet 7c95c92525 Make Tuya DeviceWrapper a generic class (#159349) 2026-01-05 12:22:48 +01:00
dotlambda 1aed46e39e Bump google-genai to 1.56.0 (#160210) 2026-01-05 12:21:02 +01:00
epenet 6659166df0 Move Tuya vacuum entity logic to wrapper class (#159255) 2026-01-05 12:20:25 +01:00
Erik Montnemery 1e6b0ba9ec Allow passing trigger options to parametrize_trigger_states (#160119) 2026-01-05 10:44:31 +01:00
abelyliu 1f23098638 Bump tuya-device-sharing-sdk to 0.2.8 (#160288) 2026-01-05 10:28:13 +01:00
epenet 98ee0421b7 Fix Tuya light color data wrapper (#160280) 2026-01-05 10:27:57 +01:00
cdnninja 6aaa57f660 Set PARALLEL_UPDATES in VeSync (#160272) 2026-01-05 09:18:16 +01:00
Andres Ruiz fad817853f Add state_class to waterfurnace sensors (#160277) 2026-01-05 09:17:41 +01:00
Michael 7ef7d3f570 Add entered and left home person triggers (#159320)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2026-01-05 09:09:59 +01:00
Thomas55555 14bca5a052 Make verify_ssl configurable in remote calendar (#160216) 2026-01-04 15:32:38 -08:00
Vincent Courcelle 18769730f0 Bump python-roborock to 4.2.0 (#160184) 2026-01-05 00:26:50 +01:00
Sab44 de6d117d9a Bump librehardwaremonitor-api to version 1.8.4 (#160249) 2026-01-04 21:35:28 +01:00
J. Nick Koston d2deef968a Ensure Brotli >= 1.2.0 (#160229) 2026-01-04 08:08:42 -10:00
Mick Vleeshouwer 6cae1821fb Fix execution history matching to ignore subsystem suffix in diagnostics in Overkiz (#160218) 2026-01-04 11:38:30 +01:00
Jan-Philipp Benecke 8d8046d233 Bump aiowebdav2 to 0.5.0 (#160233) 2026-01-04 11:37:41 +01:00
Samuel Xiao d7a9a980d0 Switchbot Cloud: Fixed Robot Vacuum Cleaner S20 had two device_model name (#160230) 2026-01-04 11:36:24 +01:00
J. Nick Koston ff8ad0c9ba Bump aioesphomeapi to 43.10.1 (#160227) 2026-01-03 17:40:15 -10:00
J. Nick Koston 27728cdca8 Bump aiohttp 3.13.3 (#160206) 2026-01-03 16:46:27 -10:00
Erwin Douna f1eaf78923 Portainer polish ephemeral container ID (#160186) 2026-01-03 21:32:07 +01:00
Willem-Jan van Rootselaar 667b1db594 Bump python-bsblan dependency to version 3.1.6 (#160202) 2026-01-03 21:30:26 +01:00
Josef Zweck d6cad546e1 Remove referral link from fish_audio (#160193) 2026-01-03 17:12:53 +01:00
Tom 4c8ffa2158 Bump airOS to v0.6.1 adding LiteAP AC support (#160194) 2026-01-03 13:52:08 +01:00
Lukas 933fae9ade Pooldose document exempts (#160166) 2026-01-03 08:59:07 +01:00
Erwin Douna b6dd9db76e Portainer add state sensor (#160156) 2026-01-03 08:51:58 +01:00
Manu 11487d6856 Set integration type service in Duck DNS (#160172) 2026-01-03 08:51:18 +01:00
Manu 920e938d84 Add discovery for default hostnames to PlayStation Network (#160173) 2026-01-03 08:44:17 +01:00
Kevin Stillhammer afc256622a raise proper service exceptions in fressnapf_tracker (#159707)
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-01-02 19:53:16 +01:00
Erwin Douna bfef048a7c Bump pyportainer 1.0.22 (#160140) 2026-01-02 18:37:14 +01:00
Maikel Punie bfc8111728 Bump velbus to silver integration scale (#160147) 2026-01-02 18:36:04 +01:00
Maikel Punie ebd6ae7e80 Velbus mark entities unavailable when connection is terminated (#160143) 2026-01-02 17:43:33 +01:00
MarkGodwin dd98a85300 Refactor TP-Link Omada config flow tests (#159950)
Co-authored-by: Joostlek <joostlek@outlook.com>
2026-01-02 17:41:04 +01:00
Brett Adams 6568a19ce6 Handle export options when enrolled to VPP in Teslemetry (#157665) 2026-01-02 16:52:03 +01:00
wollew 83c1e8d5b5 bump pyvlx version to 0.2.27 (#160139) 2026-01-02 16:49:09 +01:00
Simone Chemelli c5a06657a3 Remove low level call for Shelly climate (#160065) 2026-01-02 16:47:39 +01:00
Maciej Bieniek 25e54990d2 Bump nextdns to version 5.0.0 (#160138) 2026-01-02 16:33:27 +01:00
Nikoheld 3b2a7ba561 bump nibe to 2.21.0 (#160135) 2026-01-02 16:06:43 +01:00
Åke Strandberg 8f8f896675 Add filling level sensors to miele (#157858) 2026-01-02 15:57:15 +01:00
Willem-Jan van Rootselaar 9539a612a6 Add time synchronization feature to BSB-Lan integration (#156600) 2026-01-02 15:54:37 +01:00
Erwin Douna d6751eb63f Bump pyportainer 1.0.21 (#160130) 2026-01-02 15:06:46 +01:00
Pete Sage b462038126 Use long service timeout for Sonos Unjoin (#160110) 2026-01-02 14:18:56 +01:00
cdnninja ce06446376 Add pm1 and pm10 to vesync (#160072)
Co-authored-by: Josef Zweck <josef@zweck.dev>
2026-01-02 14:15:52 +01:00
Erik Montnemery 8de22e0134 Await writes in shopping_list action handlers (#157420) 2026-01-02 13:41:41 +01:00
mettolen fbd08d4e42 Bump pyairobotrest to 0.2.0 (#160125) 2026-01-02 12:29:29 +01:00
Zoltán Farkasdi 32e0be4535 netatmo: test_camera webhook testing parametrize and light split (#159772) 2026-01-02 11:00:17 +01:00
Maikel Punie 0423639833 Bump velbusaio to 2026.1.1 (#160116) 2026-01-02 09:16:27 +01:00
Jan Bouwhuis 1244d8aa33 Fix reolink brightness scaling (#160106) 2026-01-01 21:56:35 +01:00
Pete Sage 38c37ab33c Improve Sonos wait to unjoin timeout (#160011) 2026-01-01 20:21:25 +01:00
Willem-Jan van Rootselaar 1636eab2e8 Add schema validation for set_hot_water_schedule service (#159990) 2026-01-01 20:16:54 +01:00
Miguel Camba 737a5811a9 Update voluptuous and voluptuous-openapi (#160073) 2026-01-01 20:07:06 +01:00
Austin Mroczek 5f2da20319 Bump total_connect_client to 2025.12.2 (#160075) 2026-01-01 20:02:56 +01:00
Michael Hansen 2aed4fb8e9 Bump intents to 2026.1.1 (#160099) 2026-01-01 19:58:37 +01:00
Lukas 2b10dc4545 Add reconfiguration flow to pooldose (#159978)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2026-01-01 17:20:33 +01:00
Maikel Punie b5d22a63bb Velbus quality docs updates (#160092) 2026-01-01 17:02:30 +01:00
Maikel Punie e8e19f47cd Velbus Exception translations (#159627)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-01 16:51:39 +01:00
Maikel Punie 97e6643cd7 Bump velbusaio to 2026.1.0 (#160087) 2026-01-01 16:50:28 +01:00
Ben Wolstencroft ee4bb0eef5 Add support for health_overview API endpoint to Tractive integration (#157960)
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
2026-01-01 13:06:24 +01:00
Maikel Punie f82bb8f0b8 Use brightness scale in velbus light (#160041) 2026-01-01 13:03:52 +01:00
cdnninja 79b368cfc3 add description to string vesync (#160003) 2025-12-31 22:20:50 +01:00
cdnninja 6da4a006f2 Add Auto Off Switch to VeSync (#160070) 2025-12-31 22:17:33 +01:00
Allen Porter e5f3ccb38d Improve roborock test accuracy/robustness (#160021) 2025-12-31 16:32:53 +01:00
tronikos 560b91b93b Filter out duplicate voices without language code in Google Cloud (#160046) 2025-12-31 16:30:53 +01:00
Pete Sage edd9f50562 bump soco to 0.30.14 for Sonos (#160050) 2025-12-31 16:25:55 +01:00
Paul Tarjan a4b2e84b03 Fix Hikvision thread safety issue when calling async_write_ha_state (#160027) 2025-12-31 15:52:41 +01:00
rlippmann 9da07c2058 remove domain and service slots from Service object (#160039) 2025-12-31 13:34:02 +01:00
Simone Chemelli 8de6785182 Bump aioamazondevices to 11.0.2 (#160016)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-12-31 12:31:32 +01:00
Anders Melchiorsen 77f6fa8116 Bump eternalegypt to 0.0.18 (#160006) 2025-12-31 10:57:58 +01:00
Anders Melchiorsen 6b6f338e7e Fix netgear_lte unloading (#160008) 2025-12-31 10:53:24 +01:00
David Knowles aa995fb590 Use WATER device_class for Hydrawise sensors (#160018) 2025-12-31 10:47:48 +01:00
Anders Melchiorsen f0fee87b9e Move async_setup_services to async_setup for netgear_lte (#160007) 2025-12-31 10:43:59 +01:00
Erwin Douna 56ab3bf59b Bump pyfirefly 0.1.10 (#160028) 2025-12-31 09:04:40 +01:00
Luke Lashley 24e2720924 Don't prefer cache for Roborock device fetching (#160022) 2025-12-30 13:21:54 -08:00
Erwin Douna bacc2f00af Bump portainer 1.0.19 (#160014) 2025-12-30 21:13:24 +01:00
Manu 6de2d6810b Convert store image URLs to https in Xbox media resolver (#160015) 2025-12-30 21:10:51 +01:00
Allen Porter de07833d92 Update roborock binary sensor tests with snapshots (#159981) 2025-12-30 19:36:32 +01:00
Matthias Alphart b4eff231c3 Update knx-frontend to 2025.12.30.151231 (#159999) 2025-12-30 18:49:02 +01:00
Luke Lashley 98fea46eea Add support for vacuum entity for Roborock Q7 (#159966) 2025-12-30 07:26:18 -08:00
divers33 18e8821891 Add podcast favorites support to Sonos media browser (#159961)
Co-authored-by: divers33 <divers33@users.noreply.github.com>
2025-12-30 15:14:53 +01:00
Sab44 cc2377d44d Bump librehardwaremonitor-api to version 1.7.2 (#159987) 2025-12-30 12:18:50 +01:00
doomsniper09 8370c6abfb Accept integer coordinates in has_location helper (#159835)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2025-12-30 12:06:23 +01:00
Panda-NZ 2d1a672de5 Add ambient temperature sensor to ToGrill (#159798) 2025-12-30 09:44:23 +01:00
Ernst Klamer 75ea42a834 bump xiaomi-ble to 1.4.1 (#159954) 2025-12-30 00:12:45 +01:00
Lukas 45491e17cd Pooldose Diagnostics (#159965) 2025-12-29 23:03:13 +01:00
Stefan H. b994f03391 Migrate traccar_server to use entry.runtime_data (#156065)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-29 22:16:01 +01:00
Kamil Breguła 473cb59013 Add translation of exceptions in met (#155765)
Co-authored-by: mik-laj <12058428+mik-laj@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-29 22:12:40 +01:00
J. Nick Koston 9302926d99 Bump aioesphomeapi to 43.9.1 (#159960) 2025-12-29 11:09:37 -10:00
Branden Cash d92516b7c9 Implement reconfigure config flow in SRP energy (#151542)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-29 21:52:25 +01:00
Luke Lashley 5b561213d3 Bump Python-Roborock to 4.1.0 (#159963) 2025-12-29 21:52:13 +01:00
Erwin Douna 0a16bd4919 Portainer fix stopped container for stats (#159964) 2025-12-29 21:51:46 +01:00
Michael f74a6e2625 Record current Feedreader integration quality scale and set to silver (#143179)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-29 21:36:23 +01:00
Joost Lekkerkerker ecc271409a Small cleanup in Feedreader (#159962) 2025-12-29 21:31:25 +01:00
Michael 1f63bc3231 Record current Synology DSM integration quality scale (#141245)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-12-29 21:24:18 +01:00
Joost Lekkerkerker 78adeb837e Inject session in Switchbot cloud (#159942) 2025-12-29 21:18:34 +01:00
Joost Lekkerkerker bfacf462bf Add integration_type service to nuheat (#159845) 2025-12-29 21:12:23 +01:00
Joost Lekkerkerker 771d40dbf6 Add integration_type hub to permobil (#159872) 2025-12-29 21:12:05 +01:00
Joost Lekkerkerker 8e441242ad Add integration_type hub to pooldose (#159880) 2025-12-29 21:11:46 +01:00
Joost Lekkerkerker b8a4237ab1 Add integration_type hub to poolsense (#159881) 2025-12-29 21:11:17 +01:00
Joost Lekkerkerker e92af1ee76 Add integration_type device to ps4 (#159892) 2025-12-29 21:10:52 +01:00
Matthias Alphart e561c1cebb Fix KNX translation references (#159959) 2025-12-29 20:50:53 +01:00
Franck Nijhof d77f82f8e8 Bump version to 2026.2.0dev0 (#159956) 2025-12-29 20:38:24 +01:00
Joost Lekkerkerker fcc3598d7f Add integration_type device to netgear (#159816) 2025-12-29 21:14:58 +02:00
4259 changed files with 195437 additions and 56815 deletions
+784
View File
@@ -0,0 +1,784 @@
---
name: Home Assistant Integration knowledge
description: Everything you need to know to build, test and review Home Assistant Integrations. If you're looking at an integration, you must use this as your primary reference.
---
### File Locations
- **Integration code**: `./homeassistant/components/<integration_domain>/`
- **Integration tests**: `./tests/components/<integration_domain>/`
## Integration Templates
### Standard Integration Structure
```
homeassistant/components/my_integration/
├── __init__.py # Entry point with async_setup_entry
├── manifest.json # Integration metadata and dependencies
├── const.py # Domain and constants
├── config_flow.py # UI configuration flow
├── coordinator.py # Data update coordinator (if needed)
├── entity.py # Base entity class (if shared patterns)
├── sensor.py # Sensor platform
├── strings.json # User-facing text and translations
├── services.yaml # Service definitions (if applicable)
└── quality_scale.yaml # Quality scale rule status
```
An integration can have platforms as needed (e.g., `sensor.py`, `switch.py`, etc.). The following platforms have extra guidelines:
- **Diagnostics**: [`platform-diagnostics.md`](platform-diagnostics.md) for diagnostic data collection
- **Repairs**: [`platform-repairs.md`](platform-repairs.md) for user-actionable repair issues
### Minimal Integration Checklist
- [ ] `manifest.json` with required fields (domain, name, codeowners, etc.)
- [ ] `__init__.py` with `async_setup_entry` and `async_unload_entry`
- [ ] `config_flow.py` with UI configuration support
- [ ] `const.py` with `DOMAIN` constant
- [ ] `strings.json` with at least config flow text
- [ ] Platform files (`sensor.py`, etc.) as needed
- [ ] `quality_scale.yaml` with rule status tracking
## Integration Quality Scale
Home Assistant uses an Integration Quality Scale to ensure code quality and consistency. The quality level determines which rules apply:
### Quality Scale Levels
- **Bronze**: Basic requirements (ALL Bronze rules are mandatory)
- **Silver**: Enhanced functionality
- **Gold**: Advanced features
- **Platinum**: Highest quality standards
### Quality Scale Progression
- **Bronze → Silver**: Add entity unavailability, parallel updates, auth flows
- **Silver → Gold**: Add device management, diagnostics, translations
- **Gold → Platinum**: Add strict typing, async dependencies, websession injection
### How Rules Apply
1. **Check `manifest.json`**: Look for `"quality_scale"` key to determine integration level
2. **Bronze Rules**: Always required for any integration with quality scale
3. **Higher Tier Rules**: Only apply if integration targets that tier or higher
4. **Rule Status**: Check `quality_scale.yaml` in integration folder for:
- `done`: Rule implemented
- `exempt`: Rule doesn't apply (with reason in comment)
- `todo`: Rule needs implementation
### Example `quality_scale.yaml` Structure
```yaml
rules:
# Bronze (mandatory)
config-flow: done
entity-unique-id: done
action-setup:
status: exempt
comment: Integration does not register custom actions.
# Silver (if targeting Silver+)
entity-unavailable: done
parallel-updates: done
# Gold (if targeting Gold+)
devices: done
diagnostics: done
# Platinum (if targeting Platinum)
strict-typing: done
```
**When Reviewing/Creating Code**: Always check the integration's quality scale level and exemption status before applying rules.
## Code Organization
### Core Locations
- Shared constants: `homeassistant/const.py` (use these instead of hardcoding)
- Integration structure:
- `homeassistant/components/{domain}/const.py` - Constants
- `homeassistant/components/{domain}/models.py` - Data models
- `homeassistant/components/{domain}/coordinator.py` - Update coordinator
- `homeassistant/components/{domain}/config_flow.py` - Configuration flow
- `homeassistant/components/{domain}/{platform}.py` - Platform implementations
### Common Modules
- **coordinator.py**: Centralize data fetching logic
```python
class MyCoordinator(DataUpdateCoordinator[MyData]):
def __init__(self, hass: HomeAssistant, client: MyClient, config_entry: ConfigEntry) -> None:
super().__init__(
hass,
logger=LOGGER,
name=DOMAIN,
update_interval=timedelta(minutes=1),
config_entry=config_entry, # ✅ Pass config_entry - it's accepted and recommended
)
```
- **entity.py**: Base entity definitions to reduce duplication
```python
class MyEntity(CoordinatorEntity[MyCoordinator]):
_attr_has_entity_name = True
```
### Runtime Data Storage
- **Use ConfigEntry.runtime_data**: Store non-persistent runtime data
```python
type MyIntegrationConfigEntry = ConfigEntry[MyClient]
async def async_setup_entry(hass: HomeAssistant, entry: MyIntegrationConfigEntry) -> bool:
client = MyClient(entry.data[CONF_HOST])
entry.runtime_data = client
```
### Manifest Requirements
- **Required Fields**: `domain`, `name`, `codeowners`, `integration_type`, `documentation`, `requirements`
- **Integration Types**: `device`, `hub`, `service`, `system`, `helper`
- **IoT Class**: Always specify connectivity method (e.g., `cloud_polling`, `local_polling`, `local_push`)
- **Discovery Methods**: Add when applicable: `zeroconf`, `dhcp`, `bluetooth`, `ssdp`, `usb`
- **Dependencies**: Include platform dependencies (e.g., `application_credentials`, `bluetooth_adapters`)
### Config Flow Patterns
- **Version Control**: Always set `VERSION = 1` and `MINOR_VERSION = 1`
- **Unique ID Management**:
```python
await self.async_set_unique_id(device_unique_id)
self._abort_if_unique_id_configured()
```
- **Error Handling**: Define errors in `strings.json` under `config.error`
- **Step Methods**: Use standard naming (`async_step_user`, `async_step_discovery`, etc.)
### Integration Ownership
- **manifest.json**: Add GitHub usernames to `codeowners`:
```json
{
"domain": "my_integration",
"name": "My Integration",
"codeowners": ["@me"]
}
```
### Async Dependencies (Platinum)
- **Requirement**: All dependencies must use asyncio
- Ensures efficient task handling without thread context switching
### WebSession Injection (Platinum)
- **Pass WebSession**: Support passing web sessions to dependencies
```python
async def async_setup_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool:
"""Set up integration from config entry."""
client = MyClient(entry.data[CONF_HOST], async_get_clientsession(hass))
```
- For cookies: Use `async_create_clientsession` (aiohttp) or `create_async_httpx_client` (httpx)
### Data Update Coordinator
- **Standard Pattern**: Use for efficient data management
```python
class MyCoordinator(DataUpdateCoordinator):
def __init__(self, hass: HomeAssistant, client: MyClient, config_entry: ConfigEntry) -> None:
super().__init__(
hass,
logger=LOGGER,
name=DOMAIN,
update_interval=timedelta(minutes=5),
config_entry=config_entry, # ✅ Pass config_entry - it's accepted and recommended
)
self.client = client
async def _async_update_data(self):
try:
return await self.client.fetch_data()
except ApiError as err:
raise UpdateFailed(f"API communication error: {err}")
```
- **Error Types**: Use `UpdateFailed` for API errors, `ConfigEntryAuthFailed` for auth issues
- **Config Entry**: Always pass `config_entry` parameter to coordinator - it's accepted and recommended
## Integration Guidelines
### Configuration Flow
- **UI Setup Required**: All integrations must support configuration via UI
- **Manifest**: Set `"config_flow": true` in `manifest.json`
- **Data Storage**:
- Connection-critical config: Store in `ConfigEntry.data`
- Non-critical settings: Store in `ConfigEntry.options`
- **Validation**: Always validate user input before creating entries
- **Config Entry Naming**:
- ❌ Do NOT allow users to set config entry names in config flows
- Names are automatically generated or can be customized later in UI
- ✅ Exception: Helper integrations MAY allow custom names in config flow
- **Connection Testing**: Test device/service connection during config flow:
```python
try:
await client.get_data()
except MyException:
errors["base"] = "cannot_connect"
```
- **Duplicate Prevention**: Prevent duplicate configurations:
```python
# Using unique ID
await self.async_set_unique_id(identifier)
self._abort_if_unique_id_configured()
# Using unique data
self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]})
```
### Reauthentication Support
- **Required Method**: Implement `async_step_reauth` in config flow
- **Credential Updates**: Allow users to update credentials without re-adding
- **Validation**: Verify account matches existing unique ID:
```python
await self.async_set_unique_id(user_id)
self._abort_if_unique_id_mismatch(reason="wrong_account")
return self.async_update_reload_and_abort(
self._get_reauth_entry(),
data_updates={CONF_API_TOKEN: user_input[CONF_API_TOKEN]}
)
```
### Reconfiguration Flow
- **Purpose**: Allow configuration updates without removing device
- **Implementation**: Add `async_step_reconfigure` method
- **Validation**: Prevent changing underlying account with `_abort_if_unique_id_mismatch`
### Device Discovery
- **Manifest Configuration**: Add discovery method (zeroconf, dhcp, etc.)
```json
{
"zeroconf": ["_mydevice._tcp.local."]
}
```
- **Discovery Handler**: Implement appropriate `async_step_*` method:
```python
async def async_step_zeroconf(self, discovery_info):
"""Handle zeroconf discovery."""
await self.async_set_unique_id(discovery_info.properties["serialno"])
self._abort_if_unique_id_configured(updates={CONF_HOST: discovery_info.host})
```
- **Network Updates**: Use discovery to update dynamic IP addresses
### Network Discovery Implementation
- **Zeroconf/mDNS**: Use async instances
```python
aiozc = await zeroconf.async_get_async_instance(hass)
```
- **SSDP Discovery**: Register callbacks with cleanup
```python
entry.async_on_unload(
ssdp.async_register_callback(
hass, _async_discovered_device,
{"st": "urn:schemas-upnp-org:device:ZonePlayer:1"}
)
)
```
### Bluetooth Integration
- **Manifest Dependencies**: Add `bluetooth_adapters` to dependencies
- **Connectable**: Set `"connectable": true` for connection-required devices
- **Scanner Usage**: Always use shared scanner instance
```python
scanner = bluetooth.async_get_scanner()
entry.async_on_unload(
bluetooth.async_register_callback(
hass, _async_discovered_device,
{"service_uuid": "example_uuid"},
bluetooth.BluetoothScanningMode.ACTIVE
)
)
```
- **Connection Handling**: Never reuse `BleakClient` instances, use 10+ second timeouts
### Setup Validation
- **Test Before Setup**: Verify integration can be set up in `async_setup_entry`
- **Exception Handling**:
- `ConfigEntryNotReady`: Device offline or temporary failure
- `ConfigEntryAuthFailed`: Authentication issues
- `ConfigEntryError`: Unresolvable setup problems
### Config Entry Unloading
- **Required**: Implement `async_unload_entry` for runtime removal/reload
- **Platform Unloading**: Use `hass.config_entries.async_unload_platforms`
- **Cleanup**: Register callbacks with `entry.async_on_unload`:
```python
async def async_unload_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
entry.runtime_data.listener() # Clean up resources
return unload_ok
```
### Service Actions
- **Registration**: Register all service actions in `async_setup`, NOT in `async_setup_entry`
- **Validation**: Check config entry existence and loaded state:
```python
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
async def service_action(call: ServiceCall) -> ServiceResponse:
if not (entry := hass.config_entries.async_get_entry(call.data[ATTR_CONFIG_ENTRY_ID])):
raise ServiceValidationError("Entry not found")
if entry.state is not ConfigEntryState.LOADED:
raise ServiceValidationError("Entry not loaded")
```
- **Exception Handling**: Raise appropriate exceptions:
```python
# For invalid input
if end_date < start_date:
raise ServiceValidationError("End date must be after start date")
# For service errors
try:
await client.set_schedule(start_date, end_date)
except MyConnectionError as err:
raise HomeAssistantError("Could not connect to the schedule") from err
```
### Service Registration Patterns
- **Entity Services**: Register on platform setup
```python
platform.async_register_entity_service(
"my_entity_service",
{vol.Required("parameter"): cv.string},
"handle_service_method"
)
```
- **Service Schema**: Always validate input
```python
SERVICE_SCHEMA = vol.Schema({
vol.Required("entity_id"): cv.entity_ids,
vol.Required("parameter"): cv.string,
vol.Optional("timeout", default=30): cv.positive_int,
})
```
- **Services File**: Create `services.yaml` with descriptions and field definitions
### Polling
- Use update coordinator pattern when possible
- **Polling intervals are NOT user-configurable**: Never add scan_interval, update_interval, or polling frequency options to config flows or config entries
- **Integration determines intervals**: Set `update_interval` programmatically based on integration logic, not user input
- **Minimum Intervals**:
- Local network: 5 seconds
- Cloud services: 60 seconds
- **Parallel Updates**: Specify number of concurrent updates:
```python
PARALLEL_UPDATES = 1 # Serialize updates to prevent overwhelming device
# OR
PARALLEL_UPDATES = 0 # Unlimited (for coordinator-based or read-only)
```
## Entity Development
### Unique IDs
- **Required**: Every entity must have a unique ID for registry tracking
- Must be unique per platform (not per integration)
- Don't include integration domain or platform in ID
- **Implementation**:
```python
class MySensor(SensorEntity):
def __init__(self, device_id: str) -> None:
self._attr_unique_id = f"{device_id}_temperature"
```
**Acceptable ID Sources**:
- Device serial numbers
- MAC addresses (formatted using `format_mac` from device registry)
- Physical identifiers (printed/EEPROM)
- Config entry ID as last resort: `f"{entry.entry_id}-battery"`
**Never Use**:
- IP addresses, hostnames, URLs
- Device names
- Email addresses, usernames
### Entity Descriptions
- **Lambda/Anonymous Functions**: Often used in EntityDescription for value transformation
- **Multiline Lambdas**: When lambdas exceed line length, wrap in parentheses for readability
- **Bad pattern**:
```python
SensorEntityDescription(
key="temperature",
name="Temperature",
value_fn=lambda data: round(data["temp_value"] * 1.8 + 32, 1) if data.get("temp_value") is not None else None, # ❌ Too long
)
```
- **Good pattern**:
```python
SensorEntityDescription(
key="temperature",
name="Temperature",
value_fn=lambda data: ( # ✅ Parenthesis on same line as lambda
round(data["temp_value"] * 1.8 + 32, 1)
if data.get("temp_value") is not None
else None
),
)
```
### Entity Naming
- **Use has_entity_name**: Set `_attr_has_entity_name = True`
- **For specific fields**:
```python
class MySensor(SensorEntity):
_attr_has_entity_name = True
def __init__(self, device: Device, field: str) -> None:
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device.id)},
name=device.name,
)
self._attr_name = field # e.g., "temperature", "humidity"
```
- **For device itself**: Set `_attr_name = None`
### Event Lifecycle Management
- **Subscribe in `async_added_to_hass`**:
```python
async def async_added_to_hass(self) -> None:
"""Subscribe to events."""
self.async_on_remove(
self.client.events.subscribe("my_event", self._handle_event)
)
```
- **Unsubscribe in `async_will_remove_from_hass`** if not using `async_on_remove`
- Never subscribe in `__init__` or other methods
### State Handling
- Unknown values: Use `None` (not "unknown" or "unavailable")
- Availability: Implement `available()` property instead of using "unavailable" state
### Entity Availability
- **Mark Unavailable**: When data cannot be fetched from device/service
- **Coordinator Pattern**:
```python
@property
def available(self) -> bool:
"""Return if entity is available."""
return super().available and self.identifier in self.coordinator.data
```
- **Direct Update Pattern**:
```python
async def async_update(self) -> None:
"""Update entity."""
try:
data = await self.client.get_data()
except MyException:
self._attr_available = False
else:
self._attr_available = True
self._attr_native_value = data.value
```
### Extra State Attributes
- All attribute keys must always be present
- Unknown values: Use `None`
- Provide descriptive attributes
## Device Management
### Device Registry
- **Create Devices**: Group related entities under devices
- **Device Info**: Provide comprehensive metadata:
```python
_attr_device_info = DeviceInfo(
connections={(CONNECTION_NETWORK_MAC, device.mac)},
identifiers={(DOMAIN, device.id)},
name=device.name,
manufacturer="My Company",
model="My Sensor",
sw_version=device.version,
)
```
- For services: Add `entry_type=DeviceEntryType.SERVICE`
### Dynamic Device Addition
- **Auto-detect New Devices**: After initial setup
- **Implementation Pattern**:
```python
def _check_device() -> None:
current_devices = set(coordinator.data)
new_devices = current_devices - known_devices
if new_devices:
known_devices.update(new_devices)
async_add_entities([MySensor(coordinator, device_id) for device_id in new_devices])
entry.async_on_unload(coordinator.async_add_listener(_check_device))
```
### Stale Device Removal
- **Auto-remove**: When devices disappear from hub/account
- **Device Registry Update**:
```python
device_registry.async_update_device(
device_id=device.id,
remove_config_entry_id=self.config_entry.entry_id,
)
```
- **Manual Deletion**: Implement `async_remove_config_entry_device` when needed
### Entity Categories
- **Required**: Assign appropriate category to entities
- **Implementation**: Set `_attr_entity_category`
```python
class MySensor(SensorEntity):
_attr_entity_category = EntityCategory.DIAGNOSTIC
```
- Categories include: `DIAGNOSTIC` for system/technical information
### Device Classes
- **Use When Available**: Set appropriate device class for entity type
```python
class MyTemperatureSensor(SensorEntity):
_attr_device_class = SensorDeviceClass.TEMPERATURE
```
- Provides context for: unit conversion, voice control, UI representation
### Disabled by Default
- **Disable Noisy/Less Popular Entities**: Reduce resource usage
```python
class MySignalStrengthSensor(SensorEntity):
_attr_entity_registry_enabled_default = False
```
- Target: frequently changing states, technical diagnostics
### Entity Translations
- **Required with has_entity_name**: Support international users
- **Implementation**:
```python
class MySensor(SensorEntity):
_attr_has_entity_name = True
_attr_translation_key = "phase_voltage"
```
- Create `strings.json` with translations:
```json
{
"entity": {
"sensor": {
"phase_voltage": {
"name": "Phase voltage"
}
}
}
}
```
### Exception Translations (Gold)
- **Translatable Errors**: Use translation keys for user-facing exceptions
- **Implementation**:
```python
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="end_date_before_start_date",
)
```
- Add to `strings.json`:
```json
{
"exceptions": {
"end_date_before_start_date": {
"message": "The end date cannot be before the start date."
}
}
}
```
### Icon Translations (Gold)
- **Dynamic Icons**: Support state and range-based icon selection
- **State-based Icons**:
```json
{
"entity": {
"sensor": {
"tree_pollen": {
"default": "mdi:tree",
"state": {
"high": "mdi:tree-outline"
}
}
}
}
}
```
- **Range-based Icons** (for numeric values):
```json
{
"entity": {
"sensor": {
"battery_level": {
"default": "mdi:battery-unknown",
"range": {
"0": "mdi:battery-outline",
"90": "mdi:battery-90",
"100": "mdi:battery"
}
}
}
}
}
```
## Testing Requirements
- **Location**: `tests/components/{domain}/`
- **Coverage Requirement**: Above 95% test coverage for all modules
- **Best Practices**:
- Use pytest fixtures from `tests.common`
- Mock all external dependencies
- Use snapshots for complex data structures
- Follow existing test patterns
### Config Flow Testing
- **100% Coverage Required**: All config flow paths must be tested
- **Test Scenarios**:
- All flow initiation methods (user, discovery, import)
- Successful configuration paths
- Error recovery scenarios
- Prevention of duplicate entries
- Flow completion after errors
### Testing
- **Integration-specific tests** (recommended):
```bash
pytest ./tests/components/<integration_domain> \
--cov=homeassistant.components.<integration_domain> \
--cov-report term-missing \
--durations-min=1 \
--durations=0 \
--numprocesses=auto
```
### Testing Best Practices
- **Never access `hass.data` directly** - Use fixtures and proper integration setup instead
- **Use snapshot testing** - For verifying entity states and attributes
- **Test through integration setup** - Don't test entities in isolation
- **Mock external APIs** - Use fixtures with realistic JSON data
- **Verify registries** - Ensure entities are properly registered with devices
### Config Flow Testing Template
```python
async def test_user_flow_success(hass, mock_api):
"""Test successful user flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
# Test form submission
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=TEST_USER_INPUT
)
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == "My Device"
assert result["data"] == TEST_USER_INPUT
async def test_flow_connection_error(hass, mock_api_error):
"""Test connection error handling."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=TEST_USER_INPUT
)
assert result["type"] == FlowResultType.FORM
assert result["errors"] == {"base": "cannot_connect"}
```
### Entity Testing Patterns
```python
@pytest.fixture
def platforms() -> list[Platform]:
"""Overridden fixture to specify platforms to test."""
return [Platform.SENSOR] # Or another specific platform as needed.
@pytest.mark.usefixtures("entity_registry_enabled_by_default", "init_integration")
async def test_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
device_registry: dr.DeviceRegistry,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the sensor entities."""
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
# Ensure entities are correctly assigned to device
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, "device_unique_id")}
)
assert device_entry
entity_entries = er.async_entries_for_config_entry(
entity_registry, mock_config_entry.entry_id
)
for entity_entry in entity_entries:
assert entity_entry.device_id == device_entry.id
```
### Mock Patterns
```python
# Modern integration fixture setup
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Return the default mocked config entry."""
return MockConfigEntry(
title="My Integration",
domain=DOMAIN,
data={CONF_HOST: "127.0.0.1", CONF_API_KEY: "test_key"},
unique_id="device_unique_id",
)
@pytest.fixture
def mock_device_api() -> Generator[MagicMock]:
"""Return a mocked device API."""
with patch("homeassistant.components.my_integration.MyDeviceAPI", autospec=True) as api_mock:
api = api_mock.return_value
api.get_data.return_value = MyDeviceData.from_json(
load_fixture("device_data.json", DOMAIN)
)
yield api
@pytest.fixture
def platforms() -> list[Platform]:
"""Fixture to specify platforms to test."""
return PLATFORMS
@pytest.fixture
async def init_integration(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_device_api: MagicMock,
platforms: list[Platform],
) -> MockConfigEntry:
"""Set up the integration for testing."""
mock_config_entry.add_to_hass(hass)
with patch("homeassistant.components.my_integration.PLATFORMS", platforms):
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
return mock_config_entry
```
## Debugging & Troubleshooting
### Common Issues & Solutions
- **Integration won't load**: Check `manifest.json` syntax and required fields
- **Entities not appearing**: Verify `unique_id` and `has_entity_name` implementation
- **Config flow errors**: Check `strings.json` entries and error handling
- **Discovery not working**: Verify manifest discovery configuration and callbacks
- **Tests failing**: Check mock setup and async context
### Debug Logging Setup
```python
# Enable debug logging in tests
caplog.set_level(logging.DEBUG, logger="my_integration")
# In integration code - use proper logging
_LOGGER = logging.getLogger(__name__)
_LOGGER.debug("Processing data: %s", data) # Use lazy logging
```
### Validation Commands
```bash
# Check specific integration
python -m script.hassfest --integration-path homeassistant/components/my_integration
# Validate quality scale
# Check quality_scale.yaml against current rules
# Run integration tests with coverage
pytest ./tests/components/my_integration \
--cov=homeassistant.components.my_integration \
--cov-report term-missing
```
@@ -0,0 +1,19 @@
# Integration Diagnostics
Platform exists as `homeassistant/components/<domain>/diagnostics.py`.
- **Required**: Implement diagnostic data collection
- **Implementation**:
```python
TO_REDACT = [CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE]
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: MyConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
return {
"entry_data": async_redact_data(entry.data, TO_REDACT),
"data": entry.runtime_data.data,
}
```
- **Security**: Never expose passwords, tokens, or sensitive coordinates
@@ -0,0 +1,55 @@
# Repairs platform
Platform exists as `homeassistant/components/<domain>/repairs.py`.
- **Actionable Issues Required**: All repair issues must be actionable for end users
- **Issue Content Requirements**:
- Clearly explain what is happening
- Provide specific steps users need to take to resolve the issue
- Use friendly, helpful language
- Include relevant context (device names, error details, etc.)
- **Implementation**:
```python
ir.async_create_issue(
hass,
DOMAIN,
"outdated_version",
is_fixable=False,
issue_domain=DOMAIN,
severity=ir.IssueSeverity.ERROR,
translation_key="outdated_version",
)
```
- **Translation Strings Requirements**: Must contain user-actionable text in `strings.json`:
```json
{
"issues": {
"outdated_version": {
"title": "Device firmware is outdated",
"description": "Your device firmware version {current_version} is below the minimum required version {min_version}. To fix this issue: 1) Open the manufacturer's mobile app, 2) Navigate to device settings, 3) Select 'Update Firmware', 4) Wait for the update to complete, then 5) Restart Home Assistant."
}
}
}
```
- **String Content Must Include**:
- What the problem is
- Why it matters
- Exact steps to resolve (numbered list when multiple steps)
- What to expect after following the steps
- **Avoid Vague Instructions**: Don't just say "update firmware" - provide specific steps
- **Severity Guidelines**:
- `CRITICAL`: Reserved for extreme scenarios only
- `ERROR`: Requires immediate user attention
- `WARNING`: Indicates future potential breakage
- **Additional Attributes**:
```python
ir.async_create_issue(
hass, DOMAIN, "issue_id",
breaks_in_ha_version="2024.1.0",
is_fixable=True,
is_persistent=True,
severity=ir.IssueSeverity.ERROR,
translation_key="issue_description",
)
```
- Only create issues for problems users can potentially resolve
+3 -1
View File
@@ -22,6 +22,7 @@ base_platforms: &base_platforms
- homeassistant/components/calendar/** - homeassistant/components/calendar/**
- homeassistant/components/camera/** - homeassistant/components/camera/**
- homeassistant/components/climate/** - homeassistant/components/climate/**
- homeassistant/components/conversation/**
- homeassistant/components/cover/** - homeassistant/components/cover/**
- homeassistant/components/date/** - homeassistant/components/date/**
- homeassistant/components/datetime/** - homeassistant/components/datetime/**
@@ -53,6 +54,7 @@ base_platforms: &base_platforms
- homeassistant/components/update/** - homeassistant/components/update/**
- homeassistant/components/vacuum/** - homeassistant/components/vacuum/**
- homeassistant/components/valve/** - homeassistant/components/valve/**
- homeassistant/components/wake_word/**
- homeassistant/components/water_heater/** - homeassistant/components/water_heater/**
- homeassistant/components/weather/** - homeassistant/components/weather/**
@@ -70,7 +72,6 @@ components: &components
- homeassistant/components/cloud/** - homeassistant/components/cloud/**
- homeassistant/components/config/** - homeassistant/components/config/**
- homeassistant/components/configurator/** - homeassistant/components/configurator/**
- homeassistant/components/conversation/**
- homeassistant/components/demo/** - homeassistant/components/demo/**
- homeassistant/components/device_automation/** - homeassistant/components/device_automation/**
- homeassistant/components/dhcp/** - homeassistant/components/dhcp/**
@@ -91,6 +92,7 @@ components: &components
- homeassistant/components/input_number/** - homeassistant/components/input_number/**
- homeassistant/components/input_select/** - homeassistant/components/input_select/**
- homeassistant/components/input_text/** - homeassistant/components/input_text/**
- homeassistant/components/labs/**
- homeassistant/components/logbook/** - homeassistant/components/logbook/**
- homeassistant/components/logger/** - homeassistant/components/logger/**
- homeassistant/components/lovelace/** - homeassistant/components/lovelace/**
+9 -5
View File
@@ -8,9 +8,6 @@
"PYTHONASYNCIODEBUG": "1" "PYTHONASYNCIODEBUG": "1"
}, },
"features": { "features": {
// Node feature required for Claude Code until fixed https://github.com/anthropics/devcontainer-features/issues/28
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
"ghcr.io/devcontainers/features/github-cli:1": {} "ghcr.io/devcontainers/features/github-cli:1": {}
}, },
// Port 5683 udp is used by Shelly integration // Port 5683 udp is used by Shelly integration
@@ -40,7 +37,8 @@
"python.terminal.activateEnvInCurrentTerminal": true, "python.terminal.activateEnvInCurrentTerminal": true,
"python.testing.pytestArgs": ["--no-cov"], "python.testing.pytestArgs": ["--no-cov"],
"pylint.importStrategy": "fromEnvironment", "pylint.importStrategy": "fromEnvironment",
"python.analysis.typeCheckingMode": "basic", // Pyright type checking is not compatible with mypy which Home Assistant uses for type checking
"python.analysis.typeCheckingMode": "off",
"editor.formatOnPaste": false, "editor.formatOnPaste": false,
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.formatOnType": true, "editor.formatOnType": true,
@@ -62,7 +60,13 @@
"[python]": { "[python]": {
"editor.defaultFormatter": "charliermarsh.ruff" "editor.defaultFormatter": "charliermarsh.ruff"
}, },
"[json][jsonc][yaml]": { "[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"json.schemas": [ "json.schemas": [
+1 -1
View File
@@ -80,7 +80,7 @@ If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running: `python3 -m script.hassfest`. Updated and included derived files by running: `python3 -m script.hassfest`.
- [ ] New or updated dependencies have been added to `requirements_all.txt`. - [ ] New or updated dependencies have been added to `requirements_all.txt`.
Updated by running `python3 -m script.gen_requirements_all`. Updated by running `python3 -m script.gen_requirements_all`.
- [ ] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description. - [ ] For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.
<!-- <!--
This project is very active and we have a high turnover of pull requests. This project is very active and we have a high turnover of pull requests.
File diff suppressed because it is too large Load Diff
+41 -26
View File
@@ -10,12 +10,12 @@ on:
env: env:
BUILD_TYPE: core BUILD_TYPE: core
DEFAULT_PYTHON: "3.13" DEFAULT_PYTHON: "3.14.2"
PIP_TIMEOUT: 60 PIP_TIMEOUT: 60
UV_HTTP_TIMEOUT: 60 UV_HTTP_TIMEOUT: 60
UV_SYSTEM_PYTHON: "true" UV_SYSTEM_PYTHON: "true"
# Base image version from https://github.com/home-assistant/docker # Base image version from https://github.com/home-assistant/docker
BASE_IMAGE_VERSION: "2025.12.0" BASE_IMAGE_VERSION: "2026.01.0"
ARCHITECTURES: '["amd64", "aarch64"]' ARCHITECTURES: '["amd64", "aarch64"]'
jobs: jobs:
@@ -30,10 +30,12 @@ jobs:
architectures: ${{ env.ARCHITECTURES }} architectures: ${{ env.ARCHITECTURES }}
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@@ -96,11 +98,13 @@ jobs:
os: ubuntu-24.04-arm os: ubuntu-24.04-arm
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Download nightly wheels of frontend - name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev' if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 uses: dawidd6/action-download-artifact@5c98f0b039f36ef966fdb7dfa9779262785ecb05 # v14
with: with:
github_token: ${{secrets.GITHUB_TOKEN}} github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend repo: home-assistant/frontend
@@ -111,7 +115,7 @@ jobs:
- name: Download nightly wheels of intents - name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev' if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 uses: dawidd6/action-download-artifact@5c98f0b039f36ef966fdb7dfa9779262785ecb05 # v14
with: with:
github_token: ${{secrets.GITHUB_TOKEN}} github_token: ${{secrets.GITHUB_TOKEN}}
repo: OHF-Voice/intents-package repo: OHF-Voice/intents-package
@@ -122,7 +126,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev' if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@@ -165,7 +169,7 @@ jobs:
sed -i "s|home-assistant-intents==.*|home-assistant-intents==${BASH_REMATCH[1]}|" \ sed -i "s|home-assistant-intents==.*|home-assistant-intents==${BASH_REMATCH[1]}|" \
homeassistant/package_constraints.txt homeassistant/package_constraints.txt
sed -i "s|home-assistant-intents==.*||" requirements_all.txt sed -i "s|home-assistant-intents==.*||" requirements_all.txt requirements.txt
fi fi
- name: Download translations - name: Download translations
@@ -184,14 +188,13 @@ jobs:
echo "${{ github.sha }};${{ github.ref }};${{ github.event_name }};${{ github.actor }}" > rootfs/OFFICIAL_IMAGE echo "${{ github.sha }};${{ github.ref }};${{ github.event_name }};${{ github.actor }}" > rootfs/OFFICIAL_IMAGE
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- &install_cosign - name: Install Cosign
name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
with: with:
cosign-release: "v2.5.3" cosign-release: "v2.5.3"
@@ -225,7 +228,7 @@ jobs:
- name: Build base image - name: Build base image
id: build id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
@@ -235,6 +238,7 @@ jobs:
build-args: | build-args: |
BUILD_FROM=${{ steps.vars.outputs.base_image }} BUILD_FROM=${{ steps.vars.outputs.base_image }}
tags: ghcr.io/home-assistant/${{ matrix.arch }}-homeassistant:${{ needs.init.outputs.version }} tags: ghcr.io/home-assistant/${{ matrix.arch }}-homeassistant:${{ needs.init.outputs.version }}
outputs: type=image,push=true,compression=zstd,compression-level=9,force-compression=true,oci-mediatypes=true
labels: | labels: |
io.hass.arch=${{ matrix.arch }} io.hass.arch=${{ matrix.arch }}
io.hass.version=${{ needs.init.outputs.version }} io.hass.version=${{ needs.init.outputs.version }}
@@ -273,7 +277,9 @@ jobs:
- green - green
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set build additional args - name: Set build additional args
run: | run: |
@@ -287,7 +293,7 @@ jobs:
fi fi
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
@@ -311,7 +317,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Initialize git - name: Initialize git
uses: home-assistant/actions/helpers/git-init@master uses: home-assistant/actions/helpers/git-init@master
@@ -354,17 +362,20 @@ jobs:
matrix: matrix:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"] registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps: steps:
- *install_cosign - name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
with:
cosign-release: "v2.5.3"
- name: Login to DockerHub - name: Login to DockerHub
if: matrix.registry == 'docker.io/homeassistant' if: matrix.registry == 'docker.io/homeassistant'
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
@@ -474,10 +485,12 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true' if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@@ -519,17 +532,19 @@ jobs:
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }} HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image - name: Build Docker image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with: with:
context: . # So action will not pull the repository again context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile file: ./script/hassfest/docker/Dockerfile
@@ -542,7 +557,7 @@ jobs:
- name: Push Docker image - name: Push Docker image
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true' if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
id: push id: push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with: with:
context: . # So action will not pull the repository again context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile file: ./script/hassfest/docker/Dockerfile
@@ -551,7 +566,7 @@ jobs:
- name: Generate artifact attestation - name: Generate artifact attestation
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true' if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
uses: actions/attest-build-provenance@00014ed6ed5efc5b1ab7f7f34a39eb55d41aa4f8 # v3.1.0 uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0
with: with:
subject-name: ${{ env.HASSFEST_IMAGE_NAME }} subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }} subject-digest: ${{ steps.push.outputs.digest }}
+475 -318
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -21,14 +21,16 @@ jobs:
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 uses: github/codeql-action/init@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with: with:
languages: python languages: python
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 uses: github/codeql-action/analyze@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with: with:
category: "/language:python" category: "/language:python"
@@ -231,7 +231,7 @@ jobs:
- name: Detect duplicates using AI - name: Detect duplicates using AI
id: ai_detection id: ai_detection
if: steps.extract.outputs.should_continue == 'true' && steps.fetch_similar.outputs.has_similar == 'true' if: steps.extract.outputs.should_continue == 'true' && steps.fetch_similar.outputs.has_similar == 'true'
uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 uses: actions/ai-inference@a380166897b5408b8fb7dddd148142794cb5624a # v2.0.6
with: with:
model: openai/gpt-4o model: openai/gpt-4o
system-prompt: | system-prompt: |
@@ -57,7 +57,7 @@ jobs:
- name: Detect language using AI - name: Detect language using AI
id: ai_language_detection id: ai_language_detection
if: steps.detect_language.outputs.should_continue == 'true' if: steps.detect_language.outputs.should_continue == 'true'
uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 uses: actions/ai-inference@a380166897b5408b8fb7dddd148142794cb5624a # v2.0.6
with: with:
model: openai/gpt-4o-mini model: openai/gpt-4o-mini
system-prompt: | system-prompt: |
@@ -4,7 +4,7 @@
"owner": "check-executables-have-shebangs", "owner": "check-executables-have-shebangs",
"pattern": [ "pattern": [
{ {
"regexp": "^(.+):\\s(.+)$", "regexp": "^(.+):\\s(marked executable but has no \\(or invalid\\) shebang!.*)$",
"file": 1, "file": 1,
"message": 2 "message": 2
} }
+5 -3
View File
@@ -10,7 +10,7 @@ on:
- "**strings.json" - "**strings.json"
env: env:
DEFAULT_PYTHON: "3.13" DEFAULT_PYTHON: "3.14.2"
jobs: jobs:
upload: upload:
@@ -19,10 +19,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
+41 -23
View File
@@ -17,7 +17,7 @@ on:
- "script/gen_requirements_all.py" - "script/gen_requirements_all.py"
env: env:
DEFAULT_PYTHON: "3.13" DEFAULT_PYTHON: "3.14.2"
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref_name}} group: ${{ github.workflow }}-${{ github.ref_name}}
@@ -29,13 +29,14 @@ jobs:
if: github.repository_owner == 'home-assistant' if: github.repository_owner == 'home-assistant'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- &checkout - name: Checkout the repository
name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with:
persist-credentials: false
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python id: python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true check-latest: true
@@ -74,7 +75,7 @@ jobs:
) > .env_file ) > .env_file
- name: Upload env_file - name: Upload env_file
uses: &actions-upload-artifact actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with: with:
name: env_file name: env_file
path: ./.env_file path: ./.env_file
@@ -82,7 +83,7 @@ jobs:
overwrite: true overwrite: true
- name: Upload requirements_diff - name: Upload requirements_diff
uses: *actions-upload-artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with: with:
name: requirements_diff name: requirements_diff
path: ./requirements_diff.txt path: ./requirements_diff.txt
@@ -94,7 +95,7 @@ jobs:
python -m script.gen_requirements_all ci python -m script.gen_requirements_all ci
- name: Upload requirements_all_wheels - name: Upload requirements_all_wheels
uses: *actions-upload-artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with: with:
name: requirements_all_wheels name: requirements_all_wheels
path: ./requirements_all_wheels_*.txt path: ./requirements_all_wheels_*.txt
@@ -106,7 +107,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: &matrix-build matrix:
abi: ["cp313", "cp314"] abi: ["cp313", "cp314"]
arch: ["amd64", "aarch64"] arch: ["amd64", "aarch64"]
include: include:
@@ -115,17 +116,18 @@ jobs:
- arch: aarch64 - arch: aarch64
os: ubuntu-24.04-arm os: ubuntu-24.04-arm
steps: steps:
- *checkout - name: Checkout the repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- &download-env-file - name: Download env_file
name: Download env_file uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
uses: &actions-download-artifact actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with: with:
name: env_file name: env_file
- &download-requirements-diff - name: Download requirements_diff
name: Download requirements_diff uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
uses: *actions-download-artifact
with: with:
name: requirements_diff name: requirements_diff
@@ -136,7 +138,7 @@ jobs:
sed -i "/uv/d" requirements_diff.txt sed -i "/uv/d" requirements_diff.txt
- name: Build wheels - name: Build wheels
uses: &home-assistant-wheels home-assistant/wheels@e5742a69d69f0e274e2689c998900c7d19652c21 # 2025.12.0 uses: home-assistant/wheels@e5742a69d69f0e274e2689c998900c7d19652c21 # 2025.12.0
with: with:
abi: ${{ matrix.abi }} abi: ${{ matrix.abi }}
tag: musllinux_1_2 tag: musllinux_1_2
@@ -156,16 +158,32 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: *matrix-build matrix:
abi: ["cp313", "cp314"]
arch: ["amd64", "aarch64"]
include:
- arch: amd64
os: ubuntu-latest
- arch: aarch64
os: ubuntu-24.04-arm
steps: steps:
- *checkout - name: Checkout the repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- *download-env-file - name: Download env_file
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: env_file
- *download-requirements-diff - name: Download requirements_diff
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: requirements_diff
- name: Download requirements_all_wheels - name: Download requirements_all_wheels
uses: *actions-download-artifact uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with: with:
name: requirements_all_wheels name: requirements_all_wheels
@@ -178,7 +196,7 @@ jobs:
sed -i "/uv/d" requirements_diff.txt sed -i "/uv/d" requirements_diff.txt
- name: Build wheels - name: Build wheels
uses: *home-assistant-wheels uses: home-assistant/wheels@e5742a69d69f0e274e2689c998900c7d19652c21 # 2025.12.0
with: with:
abi: ${{ matrix.abi }} abi: ${{ matrix.abi }}
tag: musllinux_1_2 tag: musllinux_1_2
+3 -3
View File
@@ -1,6 +1,6 @@
repos: repos:
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.0 rev: v0.15.1
hooks: hooks:
- id: ruff-check - id: ruff-check
args: args:
@@ -39,14 +39,14 @@ repos:
- id: prettier - id: prettier
additional_dependencies: additional_dependencies:
- prettier@3.6.2 - prettier@3.6.2
- prettier-plugin-sort-json@4.1.1 - prettier-plugin-sort-json@4.2.0
- repo: https://github.com/cdce8p/python-typing-update - repo: https://github.com/cdce8p/python-typing-update
rev: v0.6.0 rev: v0.6.0
hooks: hooks:
# Run `python-typing-update` hook manually from time to time # Run `python-typing-update` hook manually from time to time
# to update python typing syntax. # to update python typing syntax.
# Will require manual work, before submitting changes! # Will require manual work, before submitting changes!
# pre-commit run --hook-stage manual python-typing-update --all-files # prek run --hook-stage manual python-typing-update --all-files
- id: python-typing-update - id: python-typing-update
stages: [manual] stages: [manual]
args: args:
+1 -1
View File
@@ -1 +1 @@
3.13 3.14
+11 -1
View File
@@ -53,6 +53,7 @@ homeassistant.components.air_quality.*
homeassistant.components.airgradient.* homeassistant.components.airgradient.*
homeassistant.components.airly.* homeassistant.components.airly.*
homeassistant.components.airnow.* homeassistant.components.airnow.*
homeassistant.components.airobot.*
homeassistant.components.airos.* homeassistant.components.airos.*
homeassistant.components.airq.* homeassistant.components.airq.*
homeassistant.components.airthings.* homeassistant.components.airthings.*
@@ -83,6 +84,7 @@ homeassistant.components.androidtv_remote.*
homeassistant.components.anel_pwrctrl.* homeassistant.components.anel_pwrctrl.*
homeassistant.components.anova.* homeassistant.components.anova.*
homeassistant.components.anthemav.* homeassistant.components.anthemav.*
homeassistant.components.anthropic.*
homeassistant.components.apache_kafka.* homeassistant.components.apache_kafka.*
homeassistant.components.apcupsd.* homeassistant.components.apcupsd.*
homeassistant.components.api.* homeassistant.components.api.*
@@ -220,6 +222,7 @@ homeassistant.components.generic_hygrostat.*
homeassistant.components.generic_thermostat.* homeassistant.components.generic_thermostat.*
homeassistant.components.geo_location.* homeassistant.components.geo_location.*
homeassistant.components.geocaching.* homeassistant.components.geocaching.*
homeassistant.components.ghost.*
homeassistant.components.gios.* homeassistant.components.gios.*
homeassistant.components.github.* homeassistant.components.github.*
homeassistant.components.glances.* homeassistant.components.glances.*
@@ -240,6 +243,7 @@ homeassistant.components.guardian.*
homeassistant.components.habitica.* homeassistant.components.habitica.*
homeassistant.components.hardkernel.* homeassistant.components.hardkernel.*
homeassistant.components.hardware.* homeassistant.components.hardware.*
homeassistant.components.hdfury.*
homeassistant.components.heos.* homeassistant.components.heos.*
homeassistant.components.here_travel_time.* homeassistant.components.here_travel_time.*
homeassistant.components.history.* homeassistant.components.history.*
@@ -285,6 +289,7 @@ homeassistant.components.input_button.*
homeassistant.components.input_select.* homeassistant.components.input_select.*
homeassistant.components.input_text.* homeassistant.components.input_text.*
homeassistant.components.integration.* homeassistant.components.integration.*
homeassistant.components.intelliclima.*
homeassistant.components.intent.* homeassistant.components.intent.*
homeassistant.components.intent_script.* homeassistant.components.intent_script.*
homeassistant.components.ios.* homeassistant.components.ios.*
@@ -361,7 +366,6 @@ homeassistant.components.my.*
homeassistant.components.mysensors.* homeassistant.components.mysensors.*
homeassistant.components.myuplink.* homeassistant.components.myuplink.*
homeassistant.components.nam.* homeassistant.components.nam.*
homeassistant.components.nanoleaf.*
homeassistant.components.nasweb.* homeassistant.components.nasweb.*
homeassistant.components.neato.* homeassistant.components.neato.*
homeassistant.components.nest.* homeassistant.components.nest.*
@@ -375,6 +379,7 @@ homeassistant.components.no_ip.*
homeassistant.components.nordpool.* homeassistant.components.nordpool.*
homeassistant.components.notify.* homeassistant.components.notify.*
homeassistant.components.notion.* homeassistant.components.notion.*
homeassistant.components.nrgkick.*
homeassistant.components.ntfy.* homeassistant.components.ntfy.*
homeassistant.components.number.* homeassistant.components.number.*
homeassistant.components.nut.* homeassistant.components.nut.*
@@ -382,11 +387,13 @@ homeassistant.components.ohme.*
homeassistant.components.onboarding.* homeassistant.components.onboarding.*
homeassistant.components.oncue.* homeassistant.components.oncue.*
homeassistant.components.onedrive.* homeassistant.components.onedrive.*
homeassistant.components.onedrive_for_business.*
homeassistant.components.onewire.* homeassistant.components.onewire.*
homeassistant.components.onkyo.* homeassistant.components.onkyo.*
homeassistant.components.open_meteo.* homeassistant.components.open_meteo.*
homeassistant.components.open_router.* homeassistant.components.open_router.*
homeassistant.components.openai_conversation.* homeassistant.components.openai_conversation.*
homeassistant.components.openevse.*
homeassistant.components.openexchangerates.* homeassistant.components.openexchangerates.*
homeassistant.components.opensky.* homeassistant.components.opensky.*
homeassistant.components.openuv.* homeassistant.components.openuv.*
@@ -407,6 +414,7 @@ homeassistant.components.person.*
homeassistant.components.pi_hole.* homeassistant.components.pi_hole.*
homeassistant.components.ping.* homeassistant.components.ping.*
homeassistant.components.plugwise.* homeassistant.components.plugwise.*
homeassistant.components.pooldose.*
homeassistant.components.portainer.* homeassistant.components.portainer.*
homeassistant.components.powerfox.* homeassistant.components.powerfox.*
homeassistant.components.powerwall.* homeassistant.components.powerwall.*
@@ -431,6 +439,7 @@ homeassistant.components.raspberry_pi.*
homeassistant.components.rdw.* homeassistant.components.rdw.*
homeassistant.components.recollect_waste.* homeassistant.components.recollect_waste.*
homeassistant.components.recorder.* homeassistant.components.recorder.*
homeassistant.components.redgtech.*
homeassistant.components.remember_the_milk.* homeassistant.components.remember_the_milk.*
homeassistant.components.remote.* homeassistant.components.remote.*
homeassistant.components.remote_calendar.* homeassistant.components.remote_calendar.*
@@ -454,6 +463,7 @@ homeassistant.components.russound_rio.*
homeassistant.components.ruuvi_gateway.* homeassistant.components.ruuvi_gateway.*
homeassistant.components.ruuvitag_ble.* homeassistant.components.ruuvitag_ble.*
homeassistant.components.samsungtv.* homeassistant.components.samsungtv.*
homeassistant.components.saunum.*
homeassistant.components.scene.* homeassistant.components.scene.*
homeassistant.components.schedule.* homeassistant.components.schedule.*
homeassistant.components.schlage.* homeassistant.components.schlage.*
+2 -2
View File
@@ -7,8 +7,8 @@
"python.testing.pytestEnabled": false, "python.testing.pytestEnabled": false,
// https://code.visualstudio.com/docs/python/linting#_general-settings // https://code.visualstudio.com/docs/python/linting#_general-settings
"pylint.importStrategy": "fromEnvironment", "pylint.importStrategy": "fromEnvironment",
// Pyright is too pedantic for Home Assistant // Pyright type checking is not compatible with mypy which Home Assistant uses for type checking
"python.analysis.typeCheckingMode": "basic", "python.analysis.typeCheckingMode": "off",
"[python]": { "[python]": {
"editor.defaultFormatter": "charliermarsh.ruff", "editor.defaultFormatter": "charliermarsh.ruff",
}, },
+4 -4
View File
@@ -45,7 +45,7 @@
{ {
"label": "Ruff", "label": "Ruff",
"type": "shell", "type": "shell",
"command": "pre-commit run ruff-check --all-files", "command": "prek run ruff-check --all-files",
"group": { "group": {
"kind": "test", "kind": "test",
"isDefault": true "isDefault": true
@@ -57,9 +57,9 @@
"problemMatcher": [] "problemMatcher": []
}, },
{ {
"label": "Pre-commit", "label": "Prek",
"type": "shell", "type": "shell",
"command": "pre-commit run --show-diff-on-failure", "command": "prek run --show-diff-on-failure",
"group": { "group": {
"kind": "test", "kind": "test",
"isDefault": true "isDefault": true
@@ -120,7 +120,7 @@
{ {
"label": "Generate Requirements", "label": "Generate Requirements",
"type": "shell", "type": "shell",
"command": "./script/gen_requirements_all.py", "command": "${command:python.interpreterPath} -m script.gen_requirements_all",
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
-1
View File
@@ -1 +0,0 @@
.github/copilot-instructions.md
+328
View File
@@ -0,0 +1,328 @@
# GitHub Copilot & Claude Code Instructions
This repository contains the core of Home Assistant, a Python 3 based home automation application.
## Code Review Guidelines
**When reviewing code, do NOT comment on:**
- **Missing imports** - We use static analysis tooling to catch that
- **Code formatting** - We have ruff as a formatting tool that will catch those if needed (unless specifically instructed otherwise in these instructions)
**Git commit practices during review:**
- **Do NOT amend, squash, or rebase commits after review has started** - Reviewers need to see what changed since their last review
## Python Requirements
- **Compatibility**: Python 3.13+
- **Language Features**: Use the newest features when possible:
- Pattern matching
- Type hints
- f-strings (preferred over `%` or `.format()`)
- Dataclasses
- Walrus operator
### Strict Typing (Platinum)
- **Comprehensive Type Hints**: Add type hints to all functions, methods, and variables
- **Custom Config Entry Types**: When using runtime_data:
```python
type MyIntegrationConfigEntry = ConfigEntry[MyClient]
```
- **Library Requirements**: Include `py.typed` file for PEP-561 compliance
## Code Quality Standards
- **Formatting**: Ruff
- **Linting**: PyLint and Ruff
- **Type Checking**: MyPy
- **Lint/Type/Format Fixes**: Always prefer addressing the underlying issue (e.g., import the typed source, update shared stubs, align with Ruff expectations, or correct formatting at the source) before disabling a rule, adding `# type: ignore`, or skipping a formatter. Treat suppressions and `noqa` comments as a last resort once no compliant fix exists
- **Testing**: pytest with plain functions and fixtures
- **Language**: American English for all code, comments, and documentation (use sentence case, including titles)
### Writing Style Guidelines
- **Tone**: Friendly and informative
- **Perspective**: Use second-person ("you" and "your") for user-facing messages
- **Inclusivity**: Use objective, non-discriminatory language
- **Clarity**: Write for non-native English speakers
- **Formatting in Messages**:
- Use backticks for: file paths, filenames, variable names, field entries
- Use sentence case for titles and messages (capitalize only the first word and proper nouns)
- Avoid abbreviations when possible
### Documentation Standards
- **File Headers**: Short and concise
```python
"""Integration for Peblar EV chargers."""
```
- **Method/Function Docstrings**: Required for all
```python
async def async_setup_entry(hass: HomeAssistant, entry: PeblarConfigEntry) -> bool:
"""Set up Peblar from a config entry."""
```
- **Comment Style**:
- Use clear, descriptive comments
- Explain the "why" not just the "what"
- Keep code block lines under 80 characters when possible
- Use progressive disclosure (simple explanation first, complex details later)
## Async Programming
- All external I/O operations must be async
- **Best Practices**:
- Avoid sleeping in loops
- Avoid awaiting in loops - use `gather` instead
- No blocking calls
- Group executor jobs when possible - switching between event loop and executor is expensive
### Blocking Operations
- **Use Executor**: For blocking I/O operations
```python
result = await hass.async_add_executor_job(blocking_function, args)
```
- **Never Block Event Loop**: Avoid file operations, `time.sleep()`, blocking HTTP calls
- **Replace with Async**: Use `asyncio.sleep()` instead of `time.sleep()`
### Thread Safety
- **@callback Decorator**: For event loop safe functions
```python
@callback
def async_update_callback(self, event):
"""Safe to run in event loop."""
self.async_write_ha_state()
```
- **Sync APIs from Threads**: Use sync versions when calling from non-event loop threads
- **Registry Changes**: Must be done in event loop thread
### Error Handling
- **Exception Types**: Choose most specific exception available
- `ServiceValidationError`: User input errors (preferred over `ValueError`)
- `HomeAssistantError`: Device communication failures
- `ConfigEntryNotReady`: Temporary setup issues (device offline)
- `ConfigEntryAuthFailed`: Authentication problems
- `ConfigEntryError`: Permanent setup issues
- **Try/Catch Best Practices**:
- Only wrap code that can throw exceptions
- Keep try blocks minimal - process data after the try/catch
- **Avoid bare exceptions** except in specific cases:
- ❌ Generally not allowed: `except:` or `except Exception:`
- ✅ Allowed in config flows to ensure robustness
- ✅ Allowed in functions/methods that run in background tasks
- Bad pattern:
```python
try:
data = await device.get_data() # Can throw
# ❌ Don't process data inside try block
processed = data.get("value", 0) * 100
self._attr_native_value = processed
except DeviceError:
_LOGGER.error("Failed to get data")
```
- Good pattern:
```python
try:
data = await device.get_data() # Can throw
except DeviceError:
_LOGGER.error("Failed to get data")
return
# ✅ Process data outside try block
processed = data.get("value", 0) * 100
self._attr_native_value = processed
```
- **Bare Exception Usage**:
```python
# ❌ Not allowed in regular code
try:
data = await device.get_data()
except Exception: # Too broad
_LOGGER.error("Failed")
# ✅ Allowed in config flow for robustness
async def async_step_user(self, user_input=None):
try:
await self._test_connection(user_input)
except Exception: # Allowed here
errors["base"] = "unknown"
# ✅ Allowed in background tasks
async def _background_refresh():
try:
await coordinator.async_refresh()
except Exception: # Allowed in task
_LOGGER.exception("Unexpected error in background task")
```
- **Setup Failure Patterns**:
```python
try:
await device.async_setup()
except (asyncio.TimeoutError, TimeoutException) as ex:
raise ConfigEntryNotReady(f"Timeout connecting to {device.host}") from ex
except AuthFailed as ex:
raise ConfigEntryAuthFailed(f"Credentials expired for {device.name}") from ex
```
### Logging
- **Format Guidelines**:
- No periods at end of messages
- No integration names/domains (added automatically)
- No sensitive data (keys, tokens, passwords)
- Use debug level for non-user-facing messages
- **Use Lazy Logging**:
```python
_LOGGER.debug("This is a log message with %s", variable)
```
### Unavailability Logging
- **Log Once**: When device/service becomes unavailable (info level)
- **Log Recovery**: When device/service comes back online
- **Implementation Pattern**:
```python
_unavailable_logged: bool = False
if not self._unavailable_logged:
_LOGGER.info("The sensor is unavailable: %s", ex)
self._unavailable_logged = True
# On recovery:
if self._unavailable_logged:
_LOGGER.info("The sensor is back online")
self._unavailable_logged = False
```
## Development Commands
### Environment
- **Local development (non-container)**: Activate the project venv before running commands: `source .venv/bin/activate`
- **Dev container**: No activation needed, the environment is pre-configured
### Code Quality & Linting
- **Run all linters on all files**: `prek run --all-files`
- **Run linters on staged files only**: `prek run`
- **PyLint on everything** (slow): `pylint homeassistant`
- **PyLint on specific folder**: `pylint homeassistant/components/my_integration`
- **MyPy type checking (whole project)**: `mypy homeassistant/`
- **MyPy on specific integration**: `mypy homeassistant/components/my_integration`
### Testing
- **Quick test of changed files**: `pytest --timeout=10 --picked`
- **Update test snapshots**: Add `--snapshot-update` to pytest command
- ⚠️ Omit test results after using `--snapshot-update`
- Always run tests again without the flag to verify snapshots
- **Full test suite** (AVOID - very slow): `pytest ./tests`
### Dependencies & Requirements
- **Update generated files after dependency changes**: `python -m script.gen_requirements_all`
- **Install all Python requirements**:
```bash
uv pip install -r requirements_all.txt -r requirements.txt -r requirements_test.txt
```
- **Install test requirements only**:
```bash
uv pip install -r requirements_test_all.txt -r requirements.txt
```
### Translations
- **Update translations after strings.json changes**:
```bash
python -m script.translations develop --all
```
### Project Validation
- **Run hassfest** (checks project structure and updates generated files):
```bash
python -m script.hassfest
```
## Common Anti-Patterns & Best Practices
### ❌ **Avoid These Patterns**
```python
# Blocking operations in event loop
data = requests.get(url) # ❌ Blocks event loop
time.sleep(5) # ❌ Blocks event loop
# Reusing BleakClient instances
self.client = BleakClient(address)
await self.client.connect()
# Later...
await self.client.connect() # ❌ Don't reuse
# Hardcoded strings in code
self._attr_name = "Temperature Sensor" # ❌ Not translatable
# Missing error handling
data = await self.api.get_data() # ❌ No exception handling
# Storing sensitive data in diagnostics
return {"api_key": entry.data[CONF_API_KEY]} # ❌ Exposes secrets
# Accessing hass.data directly in tests
coordinator = hass.data[DOMAIN][entry.entry_id] # ❌ Don't access hass.data
# User-configurable polling intervals
# In config flow
vol.Optional("scan_interval", default=60): cv.positive_int # ❌ Not allowed
# In coordinator
update_interval = timedelta(minutes=entry.data.get("scan_interval", 1)) # ❌ Not allowed
# User-configurable config entry names (non-helper integrations)
vol.Optional("name", default="My Device"): cv.string # ❌ Not allowed in regular integrations
# Too much code in try block
try:
response = await client.get_data() # Can throw
# ❌ Data processing should be outside try block
temperature = response["temperature"] / 10
humidity = response["humidity"]
self._attr_native_value = temperature
except ClientError:
_LOGGER.error("Failed to fetch data")
# Bare exceptions in regular code
try:
value = await sensor.read_value()
except Exception: # ❌ Too broad - catch specific exceptions
_LOGGER.error("Failed to read sensor")
```
### ✅ **Use These Patterns Instead**
```python
# Async operations with executor
data = await hass.async_add_executor_job(requests.get, url)
await asyncio.sleep(5) # ✅ Non-blocking
# Fresh BleakClient instances
client = BleakClient(address) # ✅ New instance each time
await client.connect()
# Translatable entity names
_attr_translation_key = "temperature_sensor" # ✅ Translatable
# Proper error handling
try:
data = await self.api.get_data()
except ApiException as err:
raise UpdateFailed(f"API error: {err}") from err
# Redacted diagnostics data
return async_redact_data(data, {"api_key", "password"}) # ✅ Safe
# Test through proper integration setup and fixtures
@pytest.fixture
async def init_integration(hass, mock_config_entry, mock_api):
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id) # ✅ Proper setup
# Integration-determined polling intervals (not user-configurable)
SCAN_INTERVAL = timedelta(minutes=5) # ✅ Common pattern: constant in const.py
class MyCoordinator(DataUpdateCoordinator[MyData]):
def __init__(self, hass: HomeAssistant, client: MyClient, config_entry: ConfigEntry) -> None:
# ✅ Integration determines interval based on device capabilities, connection type, etc.
interval = timedelta(minutes=1) if client.is_local else SCAN_INTERVAL
super().__init__(
hass,
logger=LOGGER,
name=DOMAIN,
update_interval=interval,
config_entry=config_entry, # ✅ Pass config_entry - it's accepted and recommended
)
```
+1 -1
View File
@@ -1 +1 @@
.github/copilot-instructions.md AGENTS.md
Generated
+46 -8
View File
@@ -15,7 +15,7 @@
.yamllint @home-assistant/core .yamllint @home-assistant/core
pyproject.toml @home-assistant/core pyproject.toml @home-assistant/core
requirements_test.txt @home-assistant/core requirements_test.txt @home-assistant/core
/.devcontainer/ @home-assistant/core /.devcontainer/ @home-assistant/core @edenhaus
/.github/ @home-assistant/core /.github/ @home-assistant/core
/.vscode/ @home-assistant/core /.vscode/ @home-assistant/core
/homeassistant/*.py @home-assistant/core /homeassistant/*.py @home-assistant/core
@@ -288,6 +288,8 @@ build.json @home-assistant/supervisor
/tests/components/cloud/ @home-assistant/cloud /tests/components/cloud/ @home-assistant/cloud
/homeassistant/components/cloudflare/ @ludeeus @ctalkington /homeassistant/components/cloudflare/ @ludeeus @ctalkington
/tests/components/cloudflare/ @ludeeus @ctalkington /tests/components/cloudflare/ @ludeeus @ctalkington
/homeassistant/components/cloudflare_r2/ @corrreia
/tests/components/cloudflare_r2/ @corrreia
/homeassistant/components/co2signal/ @jpbede @VIKTORVAV99 /homeassistant/components/co2signal/ @jpbede @VIKTORVAV99
/tests/components/co2signal/ @jpbede @VIKTORVAV99 /tests/components/co2signal/ @jpbede @VIKTORVAV99
/homeassistant/components/coinbase/ @tombrien /homeassistant/components/coinbase/ @tombrien
@@ -593,6 +595,8 @@ build.json @home-assistant/supervisor
/tests/components/geonetnz_quakes/ @exxamalte /tests/components/geonetnz_quakes/ @exxamalte
/homeassistant/components/geonetnz_volcano/ @exxamalte /homeassistant/components/geonetnz_volcano/ @exxamalte
/tests/components/geonetnz_volcano/ @exxamalte /tests/components/geonetnz_volcano/ @exxamalte
/homeassistant/components/ghost/ @johnonolan
/tests/components/ghost/ @johnonolan
/homeassistant/components/gios/ @bieniu /homeassistant/components/gios/ @bieniu
/tests/components/gios/ @bieniu /tests/components/gios/ @bieniu
/homeassistant/components/github/ @timmo001 @ludeeus /homeassistant/components/github/ @timmo001 @ludeeus
@@ -641,6 +645,8 @@ build.json @home-assistant/supervisor
/tests/components/gpsd/ @fabaff @jrieger /tests/components/gpsd/ @fabaff @jrieger
/homeassistant/components/gree/ @cmroche /homeassistant/components/gree/ @cmroche
/tests/components/gree/ @cmroche /tests/components/gree/ @cmroche
/homeassistant/components/green_planet_energy/ @petschni
/tests/components/green_planet_energy/ @petschni
/homeassistant/components/greeneye_monitor/ @jkeljo /homeassistant/components/greeneye_monitor/ @jkeljo
/tests/components/greeneye_monitor/ @jkeljo /tests/components/greeneye_monitor/ @jkeljo
/homeassistant/components/group/ @home-assistant/core /homeassistant/components/group/ @home-assistant/core
@@ -661,9 +667,13 @@ build.json @home-assistant/supervisor
/tests/components/harmony/ @ehendrix23 @bdraco @mkeesey @Aohzan /tests/components/harmony/ @ehendrix23 @bdraco @mkeesey @Aohzan
/homeassistant/components/hassio/ @home-assistant/supervisor /homeassistant/components/hassio/ @home-assistant/supervisor
/tests/components/hassio/ @home-assistant/supervisor /tests/components/hassio/ @home-assistant/supervisor
/homeassistant/components/hdfury/ @glenndehaan
/tests/components/hdfury/ @glenndehaan
/homeassistant/components/hdmi_cec/ @inytar /homeassistant/components/hdmi_cec/ @inytar
/tests/components/hdmi_cec/ @inytar /tests/components/hdmi_cec/ @inytar
/homeassistant/components/heatmiser/ @andylockran /homeassistant/components/heatmiser/ @andylockran
/homeassistant/components/hegel/ @boazca
/tests/components/hegel/ @boazca
/homeassistant/components/heos/ @andrewsayre /homeassistant/components/heos/ @andrewsayre
/tests/components/heos/ @andrewsayre /tests/components/heos/ @andrewsayre
/homeassistant/components/here_travel_time/ @eifinger /homeassistant/components/here_travel_time/ @eifinger
@@ -707,8 +717,10 @@ build.json @home-assistant/supervisor
/tests/components/homekit_controller/ @Jc2k @bdraco /tests/components/homekit_controller/ @Jc2k @bdraco
/homeassistant/components/homematic/ @pvizeli /homeassistant/components/homematic/ @pvizeli
/tests/components/homematic/ @pvizeli /tests/components/homematic/ @pvizeli
/homeassistant/components/homematicip_cloud/ @hahn-th /homeassistant/components/homematicip_cloud/ @hahn-th @lackas
/tests/components/homematicip_cloud/ @hahn-th /tests/components/homematicip_cloud/ @hahn-th @lackas
/homeassistant/components/homevolt/ @danielhiversen
/tests/components/homevolt/ @danielhiversen
/homeassistant/components/homewizard/ @DCSBL /homeassistant/components/homewizard/ @DCSBL
/tests/components/homewizard/ @DCSBL /tests/components/homewizard/ @DCSBL
/homeassistant/components/honeywell/ @rdfurman @mkmer /homeassistant/components/honeywell/ @rdfurman @mkmer
@@ -750,6 +762,8 @@ build.json @home-assistant/supervisor
/tests/components/icloud/ @Quentame @nzapponi /tests/components/icloud/ @Quentame @nzapponi
/homeassistant/components/idasen_desk/ @abmantis /homeassistant/components/idasen_desk/ @abmantis
/tests/components/idasen_desk/ @abmantis /tests/components/idasen_desk/ @abmantis
/homeassistant/components/idrive_e2/ @patrickvorgers
/tests/components/idrive_e2/ @patrickvorgers
/homeassistant/components/igloohome/ @keithle888 /homeassistant/components/igloohome/ @keithle888
/tests/components/igloohome/ @keithle888 /tests/components/igloohome/ @keithle888
/homeassistant/components/ign_sismologia/ @exxamalte /homeassistant/components/ign_sismologia/ @exxamalte
@@ -794,6 +808,8 @@ build.json @home-assistant/supervisor
/tests/components/insteon/ @teharris1 /tests/components/insteon/ @teharris1
/homeassistant/components/integration/ @dgomes /homeassistant/components/integration/ @dgomes
/tests/components/integration/ @dgomes /tests/components/integration/ @dgomes
/homeassistant/components/intelliclima/ @dvdinth
/tests/components/intelliclima/ @dvdinth
/homeassistant/components/intellifire/ @jeeftor /homeassistant/components/intellifire/ @jeeftor
/tests/components/intellifire/ @jeeftor /tests/components/intellifire/ @jeeftor
/homeassistant/components/intent/ @home-assistant/core @synesthesiam @arturpragacz /homeassistant/components/intent/ @home-assistant/core @synesthesiam @arturpragacz
@@ -915,6 +931,8 @@ build.json @home-assistant/supervisor
/tests/components/libre_hardware_monitor/ @Sab44 /tests/components/libre_hardware_monitor/ @Sab44
/homeassistant/components/lidarr/ @tkdrob /homeassistant/components/lidarr/ @tkdrob
/tests/components/lidarr/ @tkdrob /tests/components/lidarr/ @tkdrob
/homeassistant/components/liebherr/ @mettolen
/tests/components/liebherr/ @mettolen
/homeassistant/components/lifx/ @Djelibeybi /homeassistant/components/lifx/ @Djelibeybi
/tests/components/lifx/ @Djelibeybi /tests/components/lifx/ @Djelibeybi
/homeassistant/components/light/ @home-assistant/core /homeassistant/components/light/ @home-assistant/core
@@ -1015,8 +1033,8 @@ build.json @home-assistant/supervisor
/tests/components/mill/ @danielhiversen /tests/components/mill/ @danielhiversen
/homeassistant/components/min_max/ @gjohansson-ST /homeassistant/components/min_max/ @gjohansson-ST
/tests/components/min_max/ @gjohansson-ST /tests/components/min_max/ @gjohansson-ST
/homeassistant/components/minecraft_server/ @elmurato /homeassistant/components/minecraft_server/ @elmurato @zachdeibert
/tests/components/minecraft_server/ @elmurato /tests/components/minecraft_server/ @elmurato @zachdeibert
/homeassistant/components/minio/ @tkislan /homeassistant/components/minio/ @tkislan
/tests/components/minio/ @tkislan /tests/components/minio/ @tkislan
/homeassistant/components/moat/ @bdraco /homeassistant/components/moat/ @bdraco
@@ -1066,8 +1084,10 @@ build.json @home-assistant/supervisor
/tests/components/myuplink/ @pajzo @astrandb /tests/components/myuplink/ @pajzo @astrandb
/homeassistant/components/nam/ @bieniu /homeassistant/components/nam/ @bieniu
/tests/components/nam/ @bieniu /tests/components/nam/ @bieniu
/homeassistant/components/nanoleaf/ @milanmeu @joostlek /homeassistant/components/namecheapdns/ @tr4nt0r
/tests/components/nanoleaf/ @milanmeu @joostlek /tests/components/namecheapdns/ @tr4nt0r
/homeassistant/components/nanoleaf/ @milanmeu @joostlek @loebi-ch @JaspervRijbroek @jonathanrobichaud4
/tests/components/nanoleaf/ @milanmeu @joostlek @loebi-ch @JaspervRijbroek @jonathanrobichaud4
/homeassistant/components/nasweb/ @nasWebio /homeassistant/components/nasweb/ @nasWebio
/tests/components/nasweb/ @nasWebio /tests/components/nasweb/ @nasWebio
/homeassistant/components/nederlandse_spoorwegen/ @YarmoM @heindrichpaul /homeassistant/components/nederlandse_spoorwegen/ @YarmoM @heindrichpaul
@@ -1120,6 +1140,8 @@ build.json @home-assistant/supervisor
/tests/components/notify_events/ @matrozov @papajojo /tests/components/notify_events/ @matrozov @papajojo
/homeassistant/components/notion/ @bachya /homeassistant/components/notion/ @bachya
/tests/components/notion/ @bachya /tests/components/notion/ @bachya
/homeassistant/components/nrgkick/ @andijakl
/tests/components/nrgkick/ @andijakl
/homeassistant/components/nsw_fuel_station/ @nickw444 /homeassistant/components/nsw_fuel_station/ @nickw444
/tests/components/nsw_fuel_station/ @nickw444 /tests/components/nsw_fuel_station/ @nickw444
/homeassistant/components/nsw_rural_fire_service_feed/ @exxamalte /homeassistant/components/nsw_rural_fire_service_feed/ @exxamalte
@@ -1158,6 +1180,8 @@ build.json @home-assistant/supervisor
/tests/components/ondilo_ico/ @JeromeHXP /tests/components/ondilo_ico/ @JeromeHXP
/homeassistant/components/onedrive/ @zweckj /homeassistant/components/onedrive/ @zweckj
/tests/components/onedrive/ @zweckj /tests/components/onedrive/ @zweckj
/homeassistant/components/onedrive_for_business/ @zweckj
/tests/components/onedrive_for_business/ @zweckj
/homeassistant/components/onewire/ @garbled1 @epenet /homeassistant/components/onewire/ @garbled1 @epenet
/tests/components/onewire/ @garbled1 @epenet /tests/components/onewire/ @garbled1 @epenet
/homeassistant/components/onkyo/ @arturpragacz @eclair4151 /homeassistant/components/onkyo/ @arturpragacz @eclair4151
@@ -1170,6 +1194,8 @@ build.json @home-assistant/supervisor
/tests/components/open_router/ @joostlek /tests/components/open_router/ @joostlek
/homeassistant/components/openerz/ @misialq /homeassistant/components/openerz/ @misialq
/tests/components/openerz/ @misialq /tests/components/openerz/ @misialq
/homeassistant/components/openevse/ @c00w @firstof9
/tests/components/openevse/ @c00w @firstof9
/homeassistant/components/openexchangerates/ @MartinHjelmare /homeassistant/components/openexchangerates/ @MartinHjelmare
/tests/components/openexchangerates/ @MartinHjelmare /tests/components/openexchangerates/ @MartinHjelmare
/homeassistant/components/opengarage/ @danielhiversen /homeassistant/components/opengarage/ @danielhiversen
@@ -1253,6 +1279,8 @@ build.json @home-assistant/supervisor
/tests/components/powerfox/ @klaasnicolaas /tests/components/powerfox/ @klaasnicolaas
/homeassistant/components/powerwall/ @bdraco @jrester @daniel-simpson /homeassistant/components/powerwall/ @bdraco @jrester @daniel-simpson
/tests/components/powerwall/ @bdraco @jrester @daniel-simpson /tests/components/powerwall/ @bdraco @jrester @daniel-simpson
/homeassistant/components/prana/ @prana-dev-official
/tests/components/prana/ @prana-dev-official
/homeassistant/components/private_ble_device/ @Jc2k /homeassistant/components/private_ble_device/ @Jc2k
/tests/components/private_ble_device/ @Jc2k /tests/components/private_ble_device/ @Jc2k
/homeassistant/components/probe_plus/ @pantherale0 /homeassistant/components/probe_plus/ @pantherale0
@@ -1267,7 +1295,8 @@ build.json @home-assistant/supervisor
/tests/components/prosegur/ @dgomes /tests/components/prosegur/ @dgomes
/homeassistant/components/proximity/ @mib1185 /homeassistant/components/proximity/ @mib1185
/tests/components/proximity/ @mib1185 /tests/components/proximity/ @mib1185
/homeassistant/components/proxmoxve/ @jhollowe @Corbeno /homeassistant/components/proxmoxve/ @jhollowe @Corbeno @erwindouna
/tests/components/proxmoxve/ @jhollowe @Corbeno @erwindouna
/homeassistant/components/ps4/ @ktnrg45 /homeassistant/components/ps4/ @ktnrg45
/tests/components/ps4/ @ktnrg45 /tests/components/ps4/ @ktnrg45
/homeassistant/components/pterodactyl/ @elmurato /homeassistant/components/pterodactyl/ @elmurato
@@ -1338,6 +1367,8 @@ build.json @home-assistant/supervisor
/tests/components/recorder/ @home-assistant/core /tests/components/recorder/ @home-assistant/core
/homeassistant/components/recovery_mode/ @home-assistant/core /homeassistant/components/recovery_mode/ @home-assistant/core
/tests/components/recovery_mode/ @home-assistant/core /tests/components/recovery_mode/ @home-assistant/core
/homeassistant/components/redgtech/ @jonhsady @luan-nvg
/tests/components/redgtech/ @jonhsady @luan-nvg
/homeassistant/components/refoss/ @ashionky /homeassistant/components/refoss/ @ashionky
/tests/components/refoss/ @ashionky /tests/components/refoss/ @ashionky
/homeassistant/components/rehlko/ @bdraco @peterager /homeassistant/components/rehlko/ @bdraco @peterager
@@ -1544,6 +1575,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/speedtestdotnet/ @rohankapoorcom @engrbm87 /homeassistant/components/speedtestdotnet/ @rohankapoorcom @engrbm87
/tests/components/speedtestdotnet/ @rohankapoorcom @engrbm87 /tests/components/speedtestdotnet/ @rohankapoorcom @engrbm87
/homeassistant/components/splunk/ @Bre77 /homeassistant/components/splunk/ @Bre77
/tests/components/splunk/ @Bre77
/homeassistant/components/spotify/ @frenck @joostlek /homeassistant/components/spotify/ @frenck @joostlek
/tests/components/spotify/ @frenck @joostlek /tests/components/spotify/ @frenck @joostlek
/homeassistant/components/sql/ @gjohansson-ST @dougiteixeira /homeassistant/components/sql/ @gjohansson-ST @dougiteixeira
@@ -1715,6 +1747,8 @@ build.json @home-assistant/supervisor
/tests/components/twinkly/ @dr1rrb @Robbie1221 @Olen /tests/components/twinkly/ @dr1rrb @Robbie1221 @Olen
/homeassistant/components/twitch/ @joostlek /homeassistant/components/twitch/ @joostlek
/tests/components/twitch/ @joostlek /tests/components/twitch/ @joostlek
/homeassistant/components/uhoo/ @getuhoo @joshsmonta
/tests/components/uhoo/ @getuhoo @joshsmonta
/homeassistant/components/ukraine_alarm/ @PaulAnnekov /homeassistant/components/ukraine_alarm/ @PaulAnnekov
/tests/components/ukraine_alarm/ @PaulAnnekov /tests/components/ukraine_alarm/ @PaulAnnekov
/homeassistant/components/unifi/ @Kane610 /homeassistant/components/unifi/ @Kane610
@@ -1801,6 +1835,8 @@ build.json @home-assistant/supervisor
/tests/components/waqi/ @joostlek /tests/components/waqi/ @joostlek
/homeassistant/components/water_heater/ @home-assistant/core /homeassistant/components/water_heater/ @home-assistant/core
/tests/components/water_heater/ @home-assistant/core /tests/components/water_heater/ @home-assistant/core
/homeassistant/components/waterfurnace/ @sdague @masterkoppa
/tests/components/waterfurnace/ @sdague @masterkoppa
/homeassistant/components/watergate/ @adam-the-hero /homeassistant/components/watergate/ @adam-the-hero
/tests/components/watergate/ @adam-the-hero /tests/components/watergate/ @adam-the-hero
/homeassistant/components/watson_tts/ @rutkai /homeassistant/components/watson_tts/ @rutkai
@@ -1859,6 +1895,8 @@ build.json @home-assistant/supervisor
/tests/components/worldclock/ @fabaff /tests/components/worldclock/ @fabaff
/homeassistant/components/ws66i/ @ssaenger /homeassistant/components/ws66i/ @ssaenger
/tests/components/ws66i/ @ssaenger /tests/components/ws66i/ @ssaenger
/homeassistant/components/wsdot/ @ucodery
/tests/components/wsdot/ @ucodery
/homeassistant/components/wyoming/ @synesthesiam /homeassistant/components/wyoming/ @synesthesiam
/tests/components/wyoming/ @synesthesiam /tests/components/wyoming/ @synesthesiam
/homeassistant/components/xbox/ @hunterjm @tr4nt0r /homeassistant/components/xbox/ @hunterjm @tr4nt0r
Generated
+2 -2
View File
@@ -24,13 +24,13 @@ ENV \
COPY rootfs / COPY rootfs /
# Add go2rtc binary # Add go2rtc binary
COPY --from=ghcr.io/alexxit/go2rtc@sha256:f394f6329f5389a4c9a7fc54b09fdec9621bbb78bf7a672b973440bbdfb02241 /usr/local/bin/go2rtc /bin/go2rtc COPY --from=ghcr.io/alexxit/go2rtc@sha256:675c318b23c06fd862a61d262240c9a63436b4050d177ffc68a32710d9e05bae /usr/local/bin/go2rtc /bin/go2rtc
RUN \ RUN \
# Verify go2rtc can be executed # Verify go2rtc can be executed
go2rtc --version \ go2rtc --version \
# Install uv # Install uv
&& pip3 install uv==0.9.17 && pip3 install uv==0.9.26
WORKDIR /usr/src WORKDIR /usr/src
+3
View File
@@ -52,6 +52,9 @@ RUN --mount=type=bind,source=requirements.txt,target=requirements.txt \
--mount=type=bind,source=requirements_test_pre_commit.txt,target=requirements_test_pre_commit.txt \ --mount=type=bind,source=requirements_test_pre_commit.txt,target=requirements_test_pre_commit.txt \
uv pip install -r requirements.txt -r requirements_test.txt uv pip install -r requirements.txt -r requirements_test.txt
# Claude Code native install
RUN curl -fsSL https://claude.ai/install.sh | bash
WORKDIR /workspaces WORKDIR /workspaces
# Set the default shell to bash instead of sh # Set the default shell to bash instead of sh
-34
View File
@@ -67,8 +67,6 @@ from .const import (
BASE_PLATFORMS, BASE_PLATFORMS,
FORMAT_DATETIME, FORMAT_DATETIME,
KEY_DATA_LOGGING as DATA_LOGGING, KEY_DATA_LOGGING as DATA_LOGGING,
REQUIRED_NEXT_PYTHON_HA_RELEASE,
REQUIRED_NEXT_PYTHON_VER,
SIGNAL_BOOTSTRAP_INTEGRATIONS, SIGNAL_BOOTSTRAP_INTEGRATIONS,
) )
from .core_config import async_process_ha_core_config from .core_config import async_process_ha_core_config
@@ -516,38 +514,6 @@ async def async_from_config_dict(
stop = monotonic() stop = monotonic()
_LOGGER.info("Home Assistant initialized in %.2fs", stop - start) _LOGGER.info("Home Assistant initialized in %.2fs", stop - start)
if (
REQUIRED_NEXT_PYTHON_HA_RELEASE
and sys.version_info[:3] < REQUIRED_NEXT_PYTHON_VER
):
current_python_version = ".".join(str(x) for x in sys.version_info[:3])
required_python_version = ".".join(str(x) for x in REQUIRED_NEXT_PYTHON_VER[:2])
_LOGGER.warning(
(
"Support for the running Python version %s is deprecated and "
"will be removed in Home Assistant %s; "
"Please upgrade Python to %s"
),
current_python_version,
REQUIRED_NEXT_PYTHON_HA_RELEASE,
required_python_version,
)
issue_registry.async_create_issue(
hass,
core.DOMAIN,
f"python_version_{required_python_version}",
is_fixable=False,
severity=issue_registry.IssueSeverity.WARNING,
breaks_in_ha_version=REQUIRED_NEXT_PYTHON_HA_RELEASE,
translation_key="python_version",
translation_placeholders={
"current_python_version": current_python_version,
"required_python_version": required_python_version,
"breaks_in_ha_version": REQUIRED_NEXT_PYTHON_HA_RELEASE,
},
)
return hass return hass
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "cloudflare",
"name": "Cloudflare",
"integrations": ["cloudflare", "cloudflare_r2"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "heatit",
"name": "Heatit",
"iot_standards": ["zwave"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "heiman",
"name": "Heiman",
"iot_standards": ["matter", "zigbee"]
}
+1
View File
@@ -1,5 +1,6 @@
{ {
"domain": "leviton", "domain": "leviton",
"name": "Leviton", "name": "Leviton",
"integrations": ["decora_wifi"],
"iot_standards": ["zwave"] "iot_standards": ["zwave"]
} }
+1
View File
@@ -13,6 +13,7 @@
"microsoft", "microsoft",
"msteams", "msteams",
"onedrive", "onedrive",
"onedrive_for_business",
"xbox" "xbox"
] ]
} }
+14 -13
View File
@@ -30,7 +30,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from .const import CONF_POLLING, DOMAIN, LOGGER from .const import CONF_POLLING, DOMAIN, DOMAIN_DATA, LOGGER
from .services import async_setup_services from .services import async_setup_services
ATTR_DEVICE_NAME = "device_name" ATTR_DEVICE_NAME = "device_name"
@@ -99,7 +99,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except (AbodeException, ConnectTimeout, HTTPError) as ex: except (AbodeException, ConnectTimeout, HTTPError) as ex:
raise ConfigEntryNotReady(f"Unable to connect to Abode: {ex}") from ex raise ConfigEntryNotReady(f"Unable to connect to Abode: {ex}") from ex
hass.data[DOMAIN] = AbodeSystem(abode, polling) hass.data[DOMAIN_DATA] = AbodeSystem(abode, polling)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@@ -113,11 +113,12 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry.""" """Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
await hass.async_add_executor_job(hass.data[DOMAIN].abode.events.stop) await hass.async_add_executor_job(hass.data[DOMAIN_DATA].abode.events.stop)
await hass.async_add_executor_job(hass.data[DOMAIN].abode.logout) await hass.async_add_executor_job(hass.data[DOMAIN_DATA].abode.logout)
hass.data[DOMAIN].logout_listener() if logout_listener := hass.data[DOMAIN_DATA].logout_listener:
hass.data.pop(DOMAIN) logout_listener()
hass.data.pop(DOMAIN_DATA)
return unload_ok return unload_ok
@@ -127,16 +128,16 @@ async def setup_hass_events(hass: HomeAssistant) -> None:
def logout(event: Event) -> None: def logout(event: Event) -> None:
"""Logout of Abode.""" """Logout of Abode."""
if not hass.data[DOMAIN].polling: if not hass.data[DOMAIN_DATA].polling:
hass.data[DOMAIN].abode.events.stop() hass.data[DOMAIN_DATA].abode.events.stop()
hass.data[DOMAIN].abode.logout() hass.data[DOMAIN_DATA].abode.logout()
LOGGER.info("Logged out of Abode") LOGGER.info("Logged out of Abode")
if not hass.data[DOMAIN].polling: if not hass.data[DOMAIN_DATA].polling:
await hass.async_add_executor_job(hass.data[DOMAIN].abode.events.start) await hass.async_add_executor_job(hass.data[DOMAIN_DATA].abode.events.start)
hass.data[DOMAIN].logout_listener = hass.bus.async_listen_once( hass.data[DOMAIN_DATA].logout_listener = hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, logout EVENT_HOMEASSISTANT_STOP, logout
) )
@@ -178,6 +179,6 @@ def setup_abode_events(hass: HomeAssistant) -> None:
] ]
for event in events: for event in events:
hass.data[DOMAIN].abode.events.add_event_callback( hass.data[DOMAIN_DATA].abode.events.add_event_callback(
event, partial(event_callback, event) event, partial(event_callback, event)
) )
@@ -13,8 +13,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AbodeSystem from .const import DOMAIN_DATA
from .const import DOMAIN
from .entity import AbodeDevice from .entity import AbodeDevice
@@ -24,7 +23,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode alarm control panel device.""" """Set up Abode alarm control panel device."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
async_add_entities( async_add_entities(
[AbodeAlarm(data, await hass.async_add_executor_job(data.abode.get_alarm))] [AbodeAlarm(data, await hass.async_add_executor_job(data.abode.get_alarm))]
) )
@@ -15,8 +15,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.util.enum import try_parse_enum from homeassistant.util.enum import try_parse_enum
from . import AbodeSystem from .const import DOMAIN_DATA
from .const import DOMAIN
from .entity import AbodeDevice from .entity import AbodeDevice
@@ -26,7 +25,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode binary sensor devices.""" """Set up Abode binary sensor devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
device_types = [ device_types = [
"connectivity", "connectivity",
+2 -2
View File
@@ -19,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.util import Throttle from homeassistant.util import Throttle
from . import AbodeSystem from . import AbodeSystem
from .const import DOMAIN, LOGGER from .const import DOMAIN_DATA, LOGGER
from .entity import AbodeDevice from .entity import AbodeDevice
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
@@ -31,7 +31,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode camera devices.""" """Set up Abode camera devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
async_add_entities( async_add_entities(
AbodeCamera(data, device, timeline.CAPTURE_IMAGE) AbodeCamera(data, device, timeline.CAPTURE_IMAGE)
@@ -64,7 +64,7 @@ class AbodeFlowHandler(ConfigFlow, domain=DOMAIN):
else: else:
errors = {"base": "cannot_connect"} errors = {"base": "cannot_connect"}
except (ConnectTimeout, HTTPError): except ConnectTimeout, HTTPError:
errors = {"base": "cannot_connect"} errors = {"base": "cannot_connect"}
if errors: if errors:
+9
View File
@@ -1,10 +1,19 @@
"""Constants for the Abode Security System component.""" """Constants for the Abode Security System component."""
from __future__ import annotations
import logging import logging
from typing import TYPE_CHECKING
from homeassistant.util.hass_dict import HassKey
if TYPE_CHECKING:
from . import AbodeSystem
LOGGER = logging.getLogger(__package__) LOGGER = logging.getLogger(__package__)
DOMAIN = "abode" DOMAIN = "abode"
DOMAIN_DATA: HassKey[AbodeSystem] = HassKey(DOMAIN)
ATTRIBUTION = "Data provided by goabode.com" ATTRIBUTION = "Data provided by goabode.com"
CONF_POLLING = "polling" CONF_POLLING = "polling"
+2 -3
View File
@@ -9,8 +9,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AbodeSystem from .const import DOMAIN_DATA
from .const import DOMAIN
from .entity import AbodeDevice from .entity import AbodeDevice
@@ -20,7 +19,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode cover devices.""" """Set up Abode cover devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
async_add_entities( async_add_entities(
AbodeCover(data, device) AbodeCover(data, device)
+2 -2
View File
@@ -7,7 +7,7 @@ from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from . import AbodeSystem from . import AbodeSystem
from .const import ATTRIBUTION, DOMAIN from .const import ATTRIBUTION, DOMAIN, DOMAIN_DATA
class AbodeEntity(Entity): class AbodeEntity(Entity):
@@ -29,7 +29,7 @@ class AbodeEntity(Entity):
self._update_connection_status, self._update_connection_status,
) )
self.hass.data[DOMAIN].entity_ids.add(self.entity_id) self.hass.data[DOMAIN_DATA].entity_ids.add(self.entity_id)
async def async_will_remove_from_hass(self) -> None: async def async_will_remove_from_hass(self) -> None:
"""Unsubscribe from Abode connection status updates.""" """Unsubscribe from Abode connection status updates."""
+4 -5
View File
@@ -20,8 +20,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AbodeSystem from .const import DOMAIN_DATA
from .const import DOMAIN
from .entity import AbodeDevice from .entity import AbodeDevice
@@ -31,7 +30,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode light devices.""" """Set up Abode light devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
async_add_entities( async_add_entities(
AbodeLight(data, device) AbodeLight(data, device)
@@ -100,7 +99,7 @@ class AbodeLight(AbodeDevice, LightEntity):
return _hs return _hs
@property @property
def color_mode(self) -> str | None: def color_mode(self) -> ColorMode:
"""Return the color mode of the light.""" """Return the color mode of the light."""
if self._device.is_dimmable and self._device.is_color_capable: if self._device.is_dimmable and self._device.is_color_capable:
if self.hs_color is not None: if self.hs_color is not None:
@@ -111,7 +110,7 @@ class AbodeLight(AbodeDevice, LightEntity):
return ColorMode.ONOFF return ColorMode.ONOFF
@property @property
def supported_color_modes(self) -> set[str] | None: def supported_color_modes(self) -> set[ColorMode]:
"""Flag supported color modes.""" """Flag supported color modes."""
if self._device.is_dimmable and self._device.is_color_capable: if self._device.is_dimmable and self._device.is_color_capable:
return {ColorMode.COLOR_TEMP, ColorMode.HS} return {ColorMode.COLOR_TEMP, ColorMode.HS}
+2 -3
View File
@@ -9,8 +9,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AbodeSystem from .const import DOMAIN_DATA
from .const import DOMAIN
from .entity import AbodeDevice from .entity import AbodeDevice
@@ -20,7 +19,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode lock devices.""" """Set up Abode lock devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
async_add_entities( async_add_entities(
AbodeLock(data, device) AbodeLock(data, device)
+2 -2
View File
@@ -19,7 +19,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AbodeSystem from . import AbodeSystem
from .const import DOMAIN from .const import DOMAIN_DATA
from .entity import AbodeDevice from .entity import AbodeDevice
ABODE_TEMPERATURE_UNIT_HA_UNIT = { ABODE_TEMPERATURE_UNIT_HA_UNIT = {
@@ -66,7 +66,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode sensor devices.""" """Set up Abode sensor devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
async_add_entities( async_add_entities(
AbodeSensor(data, device, description) AbodeSensor(data, device, description)
+4 -4
View File
@@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.dispatcher import dispatcher_send
from .const import DOMAIN, LOGGER from .const import DOMAIN, DOMAIN_DATA, LOGGER
SERVICE_SETTINGS = "change_setting" SERVICE_SETTINGS = "change_setting"
SERVICE_CAPTURE_IMAGE = "capture_image" SERVICE_CAPTURE_IMAGE = "capture_image"
@@ -35,7 +35,7 @@ def _change_setting(call: ServiceCall) -> None:
value = call.data[ATTR_VALUE] value = call.data[ATTR_VALUE]
try: try:
call.hass.data[DOMAIN].abode.set_setting(setting, value) call.hass.data[DOMAIN_DATA].abode.set_setting(setting, value)
except AbodeException as ex: except AbodeException as ex:
LOGGER.warning(ex) LOGGER.warning(ex)
@@ -46,7 +46,7 @@ def _capture_image(call: ServiceCall) -> None:
target_entities = [ target_entities = [
entity_id entity_id
for entity_id in call.hass.data[DOMAIN].entity_ids for entity_id in call.hass.data[DOMAIN_DATA].entity_ids
if entity_id in entity_ids if entity_id in entity_ids
] ]
@@ -61,7 +61,7 @@ def _trigger_automation(call: ServiceCall) -> None:
target_entities = [ target_entities = [
entity_id entity_id
for entity_id in call.hass.data[DOMAIN].entity_ids for entity_id in call.hass.data[DOMAIN_DATA].entity_ids
if entity_id in entity_ids if entity_id in entity_ids
] ]
+2 -3
View File
@@ -12,8 +12,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AbodeSystem from .const import DOMAIN_DATA
from .const import DOMAIN
from .entity import AbodeAutomation, AbodeDevice from .entity import AbodeAutomation, AbodeDevice
DEVICE_TYPES = ["switch", "valve"] DEVICE_TYPES = ["switch", "valve"]
@@ -25,7 +24,7 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Abode switch devices.""" """Set up Abode switch devices."""
data: AbodeSystem = hass.data[DOMAIN] data = hass.data[DOMAIN_DATA]
entities: list[SwitchEntity] = [ entities: list[SwitchEntity] = [
AbodeSwitch(data, device) AbodeSwitch(data, device)
@@ -43,7 +43,7 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
longitude=user_input[CONF_LONGITUDE], longitude=user_input[CONF_LONGITUDE],
) )
await accuweather.async_get_location() await accuweather.async_get_location()
except (ApiError, ClientConnectorError, TimeoutError, ClientError): except ApiError, ClientConnectorError, TimeoutError, ClientError:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
except InvalidApiKeyError: except InvalidApiKeyError:
errors[CONF_API_KEY] = "invalid_api_key" errors[CONF_API_KEY] = "invalid_api_key"
@@ -104,7 +104,7 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
longitude=self._longitude, longitude=self._longitude,
) )
await accuweather.async_get_location() await accuweather.async_get_location()
except (ApiError, ClientConnectorError, TimeoutError, ClientError): except ApiError, ClientConnectorError, TimeoutError, ClientError:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
except InvalidApiKeyError: except InvalidApiKeyError:
errors["base"] = "invalid_api_key" errors["base"] = "invalid_api_key"
@@ -18,7 +18,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import ActronAirConfigEntry, ActronAirSystemCoordinator from .coordinator import ActronAirConfigEntry, ActronAirSystemCoordinator
from .entity import ActronAirAcEntity, ActronAirZoneEntity from .entity import ActronAirAcEntity, ActronAirZoneEntity, handle_actron_api_errors
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@@ -136,16 +136,19 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
"""Return the target temperature.""" """Return the target temperature."""
return self._status.user_aircon_settings.temperature_setpoint_cool_c return self._status.user_aircon_settings.temperature_setpoint_cool_c
@handle_actron_api_errors
async def async_set_fan_mode(self, fan_mode: str) -> None: async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set a new fan mode.""" """Set a new fan mode."""
api_fan_mode = FAN_MODE_MAPPING_HA_TO_ACTRONAIR.get(fan_mode) api_fan_mode = FAN_MODE_MAPPING_HA_TO_ACTRONAIR.get(fan_mode)
await self._status.user_aircon_settings.set_fan_mode(api_fan_mode) await self._status.user_aircon_settings.set_fan_mode(api_fan_mode)
@handle_actron_api_errors
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the HVAC mode.""" """Set the HVAC mode."""
ac_mode = HVAC_MODE_MAPPING_HA_TO_ACTRONAIR.get(hvac_mode) ac_mode = HVAC_MODE_MAPPING_HA_TO_ACTRONAIR.get(hvac_mode)
await self._status.ac_system.set_system_mode(ac_mode) await self._status.ac_system.set_system_mode(ac_mode)
@handle_actron_api_errors
async def async_set_temperature(self, **kwargs: Any) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the temperature.""" """Set the temperature."""
temp = kwargs.get(ATTR_TEMPERATURE) temp = kwargs.get(ATTR_TEMPERATURE)
@@ -209,11 +212,13 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
"""Return the target temperature.""" """Return the target temperature."""
return self._zone.temperature_setpoint_cool_c return self._zone.temperature_setpoint_cool_c
@handle_actron_api_errors
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the HVAC mode.""" """Set the HVAC mode."""
is_enabled = hvac_mode != HVACMode.OFF is_enabled = hvac_mode != HVACMode.OFF
await self._zone.enable(is_enabled) await self._zone.enable(is_enabled)
@handle_actron_api_errors
async def async_set_temperature(self, **kwargs: Any) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the temperature.""" """Set the temperature."""
await self._zone.set_temperature(temperature=kwargs.get(ATTR_TEMPERATURE)) await self._zone.set_temperature(temperature=kwargs.get(ATTR_TEMPERATURE))
+26 -1
View File
@@ -1,7 +1,12 @@
"""Base entity classes for Actron Air integration.""" """Base entity classes for Actron Air integration."""
from actron_neo_api import ActronAirZone from collections.abc import Callable, Coroutine
from functools import wraps
from typing import Any, Concatenate
from actron_neo_api import ActronAirAPIError, ActronAirZone
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -9,6 +14,26 @@ from .const import DOMAIN
from .coordinator import ActronAirSystemCoordinator from .coordinator import ActronAirSystemCoordinator
def handle_actron_api_errors[_EntityT: ActronAirEntity, **_P](
func: Callable[Concatenate[_EntityT, _P], Coroutine[Any, Any, Any]],
) -> Callable[Concatenate[_EntityT, _P], Coroutine[Any, Any, None]]:
"""Decorate Actron Air API calls to handle ActronAirAPIError exceptions."""
@wraps(func)
async def wrapper(self: _EntityT, *args: _P.args, **kwargs: _P.kwargs) -> None:
"""Wrap API calls with exception handling."""
try:
await func(self, *args, **kwargs)
except ActronAirAPIError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="api_error",
translation_placeholders={"error": str(err)},
) from err
return wrapper
class ActronAirEntity(CoordinatorEntity[ActronAirSystemCoordinator]): class ActronAirEntity(CoordinatorEntity[ActronAirSystemCoordinator]):
"""Base class for Actron Air entities.""" """Base class for Actron Air entities."""
@@ -26,7 +26,7 @@ rules:
unique-config-entry: done unique-config-entry: done
# Silver # Silver
action-exceptions: todo action-exceptions: done
config-entry-unloading: done config-entry-unloading: done
docs-configuration-parameters: docs-configuration-parameters:
status: exempt status: exempt
@@ -49,6 +49,9 @@
} }
}, },
"exceptions": { "exceptions": {
"api_error": {
"message": "Failed to communicate with Actron Air device: {error}"
},
"auth_error": { "auth_error": {
"message": "Authentication failed, please reauthenticate" "message": "Authentication failed, please reauthenticate"
}, },
+27 -13
View File
@@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import ActronAirConfigEntry, ActronAirSystemCoordinator from .coordinator import ActronAirConfigEntry, ActronAirSystemCoordinator
from .entity import ActronAirAcEntity from .entity import ActronAirAcEntity, handle_actron_api_errors
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@@ -29,30 +29,42 @@ SWITCHES: tuple[ActronAirSwitchEntityDescription, ...] = (
key="away_mode", key="away_mode",
translation_key="away_mode", translation_key="away_mode",
is_on_fn=lambda coordinator: coordinator.data.user_aircon_settings.away_mode, is_on_fn=lambda coordinator: coordinator.data.user_aircon_settings.away_mode,
set_fn=lambda coordinator, set_fn=lambda coordinator, enabled: (
enabled: coordinator.data.user_aircon_settings.set_away_mode(enabled), coordinator.data.user_aircon_settings.set_away_mode(enabled)
),
), ),
ActronAirSwitchEntityDescription( ActronAirSwitchEntityDescription(
key="continuous_fan", key="continuous_fan",
translation_key="continuous_fan", translation_key="continuous_fan",
is_on_fn=lambda coordinator: coordinator.data.user_aircon_settings.continuous_fan_enabled, is_on_fn=lambda coordinator: (
set_fn=lambda coordinator, coordinator.data.user_aircon_settings.continuous_fan_enabled
enabled: coordinator.data.user_aircon_settings.set_continuous_mode(enabled), ),
set_fn=lambda coordinator, enabled: (
coordinator.data.user_aircon_settings.set_continuous_mode(enabled)
),
), ),
ActronAirSwitchEntityDescription( ActronAirSwitchEntityDescription(
key="quiet_mode", key="quiet_mode",
translation_key="quiet_mode", translation_key="quiet_mode",
is_on_fn=lambda coordinator: coordinator.data.user_aircon_settings.quiet_mode_enabled, is_on_fn=lambda coordinator: (
set_fn=lambda coordinator, coordinator.data.user_aircon_settings.quiet_mode_enabled
enabled: coordinator.data.user_aircon_settings.set_quiet_mode(enabled), ),
set_fn=lambda coordinator, enabled: (
coordinator.data.user_aircon_settings.set_quiet_mode(enabled)
),
), ),
ActronAirSwitchEntityDescription( ActronAirSwitchEntityDescription(
key="turbo_mode", key="turbo_mode",
translation_key="turbo_mode", translation_key="turbo_mode",
is_on_fn=lambda coordinator: coordinator.data.user_aircon_settings.turbo_enabled, is_on_fn=lambda coordinator: (
set_fn=lambda coordinator, coordinator.data.user_aircon_settings.turbo_enabled
enabled: coordinator.data.user_aircon_settings.set_turbo_mode(enabled), ),
is_supported_fn=lambda coordinator: coordinator.data.user_aircon_settings.turbo_supported, set_fn=lambda coordinator, enabled: (
coordinator.data.user_aircon_settings.set_turbo_mode(enabled)
),
is_supported_fn=lambda coordinator: (
coordinator.data.user_aircon_settings.turbo_supported
),
), ),
) )
@@ -93,10 +105,12 @@ class ActronAirSwitch(ActronAirAcEntity, SwitchEntity):
"""Return true if the switch is on.""" """Return true if the switch is on."""
return self.entity_description.is_on_fn(self.coordinator) return self.entity_description.is_on_fn(self.coordinator)
@handle_actron_api_errors
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on.""" """Turn the switch on."""
await self.entity_description.set_fn(self.coordinator, True) await self.entity_description.set_fn(self.coordinator, True)
@handle_actron_api_errors
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off.""" """Turn the switch off."""
await self.entity_description.set_fn(self.coordinator, False) await self.entity_description.set_fn(self.coordinator, False)
+1 -1
View File
@@ -87,7 +87,7 @@ class AdaxConfigFlow(ConfigFlow, domain=DOMAIN):
data_schema=data_schema, data_schema=data_schema,
) )
wifi_ssid = user_input[WIFI_SSID].replace(" ", "") wifi_ssid = user_input[WIFI_SSID]
wifi_pswd = user_input[WIFI_PSWD].replace(" ", "") wifi_pswd = user_input[WIFI_PSWD].replace(" ", "")
configurator = adax_local.AdaxConfig(wifi_ssid, wifi_pswd) configurator = adax_local.AdaxConfig(wifi_ssid, wifi_pswd)
+67 -49
View File
@@ -20,9 +20,10 @@ from homeassistant.const import (
Platform, Platform,
) )
from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady, ServiceValidationError
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.typing import ConfigType
from .const import ( from .const import (
CONF_FORCE, CONF_FORCE,
@@ -45,6 +46,7 @@ SERVICE_REFRESH_SCHEMA = vol.Schema(
{vol.Optional(CONF_FORCE, default=False): cv.boolean} {vol.Optional(CONF_FORCE, default=False): cv.boolean}
) )
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.UPDATE] PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.UPDATE]
type AdGuardConfigEntry = ConfigEntry[AdGuardData] type AdGuardConfigEntry = ConfigEntry[AdGuardData]
@@ -57,6 +59,69 @@ class AdGuardData:
version: str version: str
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the component."""
def _get_adguard_instances(hass: HomeAssistant) -> list[AdGuardHome]:
"""Get the AdGuardHome instances."""
entries: list[AdGuardConfigEntry] = hass.config_entries.async_loaded_entries(
DOMAIN
)
if not entries:
raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="config_entry_not_loaded"
)
return [entry.runtime_data.client for entry in entries]
async def add_url(call: ServiceCall) -> None:
"""Service call to add a new filter subscription to AdGuard Home."""
for adguard in _get_adguard_instances(call.hass):
await adguard.filtering.add_url(
allowlist=False, name=call.data[CONF_NAME], url=call.data[CONF_URL]
)
async def remove_url(call: ServiceCall) -> None:
"""Service call to remove a filter subscription from AdGuard Home."""
for adguard in _get_adguard_instances(call.hass):
await adguard.filtering.remove_url(allowlist=False, url=call.data[CONF_URL])
async def enable_url(call: ServiceCall) -> None:
"""Service call to enable a filter subscription in AdGuard Home."""
for adguard in _get_adguard_instances(call.hass):
await adguard.filtering.enable_url(allowlist=False, url=call.data[CONF_URL])
async def disable_url(call: ServiceCall) -> None:
"""Service call to disable a filter subscription in AdGuard Home."""
for adguard in _get_adguard_instances(call.hass):
await adguard.filtering.disable_url(
allowlist=False, url=call.data[CONF_URL]
)
async def refresh(call: ServiceCall) -> None:
"""Service call to refresh the filter subscriptions in AdGuard Home."""
for adguard in _get_adguard_instances(call.hass):
await adguard.filtering.refresh(
allowlist=False, force=call.data[CONF_FORCE]
)
hass.services.async_register(
DOMAIN, SERVICE_ADD_URL, add_url, schema=SERVICE_ADD_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_REMOVE_URL, remove_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_ENABLE_URL, enable_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_DISABLE_URL, disable_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_REFRESH, refresh, schema=SERVICE_REFRESH_SCHEMA
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> bool:
"""Set up AdGuard Home from a config entry.""" """Set up AdGuard Home from a config entry."""
session = async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL]) session = async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL])
@@ -79,56 +144,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> b
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
async def add_url(call: ServiceCall) -> None:
"""Service call to add a new filter subscription to AdGuard Home."""
await adguard.filtering.add_url(
allowlist=False, name=call.data[CONF_NAME], url=call.data[CONF_URL]
)
async def remove_url(call: ServiceCall) -> None:
"""Service call to remove a filter subscription from AdGuard Home."""
await adguard.filtering.remove_url(allowlist=False, url=call.data[CONF_URL])
async def enable_url(call: ServiceCall) -> None:
"""Service call to enable a filter subscription in AdGuard Home."""
await adguard.filtering.enable_url(allowlist=False, url=call.data[CONF_URL])
async def disable_url(call: ServiceCall) -> None:
"""Service call to disable a filter subscription in AdGuard Home."""
await adguard.filtering.disable_url(allowlist=False, url=call.data[CONF_URL])
async def refresh(call: ServiceCall) -> None:
"""Service call to refresh the filter subscriptions in AdGuard Home."""
await adguard.filtering.refresh(allowlist=False, force=call.data[CONF_FORCE])
hass.services.async_register(
DOMAIN, SERVICE_ADD_URL, add_url, schema=SERVICE_ADD_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_REMOVE_URL, remove_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_ENABLE_URL, enable_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_DISABLE_URL, disable_url, schema=SERVICE_URL_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_REFRESH, refresh, schema=SERVICE_REFRESH_SCHEMA
)
return True return True
async def async_unload_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: AdGuardConfigEntry) -> bool:
"""Unload AdGuard Home config entry.""" """Unload AdGuard Home config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if not hass.config_entries.async_loaded_entries(DOMAIN):
# This is the last loaded instance of AdGuard, deregister any services
hass.services.async_remove(DOMAIN, SERVICE_ADD_URL)
hass.services.async_remove(DOMAIN, SERVICE_REMOVE_URL)
hass.services.async_remove(DOMAIN, SERVICE_ENABLE_URL)
hass.services.async_remove(DOMAIN, SERVICE_DISABLE_URL)
hass.services.async_remove(DOMAIN, SERVICE_REFRESH)
return unload_ok
@@ -107,7 +107,7 @@ class AdGuardHomeFlowHandler(ConfigFlow, domain=DOMAIN):
async def async_step_hassio( async def async_step_hassio(
self, discovery_info: HassioServiceInfo self, discovery_info: HassioServiceInfo
) -> ConfigFlowResult: ) -> ConfigFlowResult:
"""Prepare configuration for a Hass.io AdGuard Home add-on. """Prepare configuration for a Hass.io AdGuard Home app.
This flow is triggered by the discovery component. This flow is triggered by the discovery component.
""" """
+1 -1
View File
@@ -52,7 +52,7 @@ class AdGuardHomeEntity(Entity):
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return device information about this AdGuard Home instance.""" """Return device information about this AdGuard Home instance."""
if self._entry.source == SOURCE_HASSIO: if self._entry.source == SOURCE_HASSIO:
config_url = "homeassistant://hassio/ingress/a0d7b954_adguard" config_url = "homeassistant://app/a0d7b954_adguard"
elif self.adguard.tls: elif self.adguard.tls:
config_url = f"https://{self.adguard.host}:{self.adguard.port}" config_url = f"https://{self.adguard.host}:{self.adguard.port}"
else: else:
@@ -9,8 +9,8 @@
}, },
"step": { "step": {
"hassio_confirm": { "hassio_confirm": {
"description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the add-on: {addon}?", "description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the app: {addon}?",
"title": "AdGuard Home via Home Assistant add-on" "title": "AdGuard Home via Home Assistant app"
}, },
"user": { "user": {
"data": { "data": {
@@ -76,6 +76,11 @@
} }
} }
}, },
"exceptions": {
"config_entry_not_loaded": {
"message": "Config entry not loaded."
}
},
"services": { "services": {
"add_url": { "add_url": {
"description": "Adds a new filter subscription to AdGuard Home.", "description": "Adds a new filter subscription to AdGuard Home.",
@@ -8,12 +8,15 @@ from advantage_air import ApiError, advantage_air
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import ADVANTAGE_AIR_RETRY from .const import ADVANTAGE_AIR_RETRY, DOMAIN
from .models import AdvantageAirData from .models import AdvantageAirData
from .services import async_setup_services
type AdvantageAirDataConfigEntry = ConfigEntry[AdvantageAirData] type AdvantageAirDataConfigEntry = ConfigEntry[AdvantageAirData]
@@ -32,6 +35,14 @@ PLATFORMS = [
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
REQUEST_REFRESH_DELAY = 0.5 REQUEST_REFRESH_DELAY = 0.5
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the component."""
async_setup_services(hass)
return True
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: AdvantageAirDataConfigEntry hass: HomeAssistant, entry: AdvantageAirDataConfigEntry
@@ -5,8 +5,6 @@ from __future__ import annotations
from decimal import Decimal from decimal import Decimal
from typing import Any from typing import Any
import voluptuous as vol
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
SensorEntity, SensorEntity,
@@ -14,7 +12,6 @@ from homeassistant.components.sensor import (
) )
from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AdvantageAirDataConfigEntry from . import AdvantageAirDataConfigEntry
@@ -24,7 +21,6 @@ from .models import AdvantageAirData
ADVANTAGE_AIR_SET_COUNTDOWN_VALUE = "minutes" ADVANTAGE_AIR_SET_COUNTDOWN_VALUE = "minutes"
ADVANTAGE_AIR_SET_COUNTDOWN_UNIT = "min" ADVANTAGE_AIR_SET_COUNTDOWN_UNIT = "min"
ADVANTAGE_AIR_SERVICE_SET_TIME_TO = "set_time_to"
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@@ -53,13 +49,6 @@ async def async_setup_entry(
entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key)) entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key))
async_add_entities(entities) async_add_entities(entities)
platform = entity_platform.async_get_current_platform()
platform.async_register_entity_service(
ADVANTAGE_AIR_SERVICE_SET_TIME_TO,
{vol.Required("minutes"): cv.positive_int},
"set_time_to",
)
class AdvantageAirTimeTo(AdvantageAirAcEntity, SensorEntity): class AdvantageAirTimeTo(AdvantageAirAcEntity, SensorEntity):
"""Representation of Advantage Air timer control.""" """Representation of Advantage Air timer control."""
@@ -0,0 +1,27 @@
"""Services for Advantage Air integration."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, service
from .const import DOMAIN
ADVANTAGE_AIR_SERVICE_SET_TIME_TO = "set_time_to"
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Home Assistant services."""
service.async_register_platform_entity_service(
hass,
DOMAIN,
ADVANTAGE_AIR_SERVICE_SET_TIME_TO,
entity_domain=SENSOR_DOMAIN,
schema={vol.Required("minutes"): cv.positive_int},
func="set_time_to",
)
+11 -1
View File
@@ -7,10 +7,12 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform from homeassistant.const import Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN, SERVER_URL from .const import DOMAIN, SERVER_URL
from .services import async_setup_services
ATTRIBUTION = "ispyconnect.com" ATTRIBUTION = "ispyconnect.com"
DEFAULT_BRAND = "Agent DVR by ispyconnect.com" DEFAULT_BRAND = "Agent DVR by ispyconnect.com"
@@ -19,6 +21,14 @@ PLATFORMS = [Platform.ALARM_CONTROL_PANEL, Platform.CAMERA]
AgentDVRConfigEntry = ConfigEntry[Agent] AgentDVRConfigEntry = ConfigEntry[Agent]
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the component."""
async_setup_services(hass)
return True
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, config_entry: AgentDVRConfigEntry hass: HomeAssistant, config_entry: AgentDVRConfigEntry
+1 -22
View File
@@ -9,10 +9,7 @@ from homeassistant.components.camera import CameraEntityFeature
from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import ( from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
AddConfigEntryEntitiesCallback,
async_get_current_platform,
)
from . import AgentDVRConfigEntry from . import AgentDVRConfigEntry
from .const import ATTRIBUTION, CAMERA_SCAN_INTERVAL_SECS, DOMAIN from .const import ATTRIBUTION, CAMERA_SCAN_INTERVAL_SECS, DOMAIN
@@ -21,20 +18,6 @@ SCAN_INTERVAL = timedelta(seconds=CAMERA_SCAN_INTERVAL_SECS)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
_DEV_EN_ALT = "enable_alerts"
_DEV_DS_ALT = "disable_alerts"
_DEV_EN_REC = "start_recording"
_DEV_DS_REC = "stop_recording"
_DEV_SNAP = "snapshot"
CAMERA_SERVICES = {
_DEV_EN_ALT: "async_enable_alerts",
_DEV_DS_ALT: "async_disable_alerts",
_DEV_EN_REC: "async_start_recording",
_DEV_DS_REC: "async_stop_recording",
_DEV_SNAP: "async_snapshot",
}
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
@@ -57,10 +40,6 @@ async def async_setup_entry(
async_add_entities(cameras) async_add_entities(cameras)
platform = async_get_current_platform()
for service, method in CAMERA_SERVICES.items():
platform.async_register_entity_service(service, None, method)
class AgentCamera(MjpegCamera): class AgentCamera(MjpegCamera):
"""Representation of an Agent Device Stream.""" """Representation of an Agent Device Stream."""
@@ -0,0 +1,38 @@
"""Services for Agent DVR."""
from __future__ import annotations
from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import service
from .const import DOMAIN
_DEV_EN_ALT = "enable_alerts"
_DEV_DS_ALT = "disable_alerts"
_DEV_EN_REC = "start_recording"
_DEV_DS_REC = "stop_recording"
_DEV_SNAP = "snapshot"
CAMERA_SERVICES = {
_DEV_EN_ALT: "async_enable_alerts",
_DEV_DS_ALT: "async_disable_alerts",
_DEV_EN_REC: "async_start_recording",
_DEV_DS_REC: "async_stop_recording",
_DEV_SNAP: "async_snapshot",
}
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Home Assistant services."""
for service_name, method in CAMERA_SERVICES.items():
service.async_register_platform_entity_service(
hass,
DOMAIN,
service_name,
entity_domain=CAMERA_DOMAIN,
schema=None,
func=method,
)
@@ -133,8 +133,9 @@ CONTROL_ENTITIES: tuple[AirGradientSelectEntityDescription, ...] = (
value_fn=lambda config: _get_value( value_fn=lambda config: _get_value(
config.co2_automatic_baseline_calibration_days, ABC_DAYS config.co2_automatic_baseline_calibration_days, ABC_DAYS
), ),
set_value_fn=lambda client, set_value_fn=lambda client, value: (
value: client.set_co2_automatic_baseline_calibration(int(value)), client.set_co2_automatic_baseline_calibration(int(value))
),
), ),
) )
+7 -1
View File
@@ -7,7 +7,13 @@ from homeassistant.core import HomeAssistant
from .coordinator import AirobotConfigEntry, AirobotDataUpdateCoordinator from .coordinator import AirobotConfigEntry, AirobotDataUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.NUMBER, Platform.SENSOR] PLATFORMS: list[Platform] = [
Platform.BUTTON,
Platform.CLIMATE,
Platform.NUMBER,
Platform.SENSOR,
Platform.SWITCH,
]
async def async_setup_entry(hass: HomeAssistant, entry: AirobotConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: AirobotConfigEntry) -> bool:
@@ -0,0 +1,96 @@
"""Button platform for Airobot integration."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
from pyairobotrest.exceptions import (
AirobotConnectionError,
AirobotError,
AirobotTimeoutError,
)
from homeassistant.components.button import (
ButtonDeviceClass,
ButtonEntity,
ButtonEntityDescription,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN
from .coordinator import AirobotConfigEntry, AirobotDataUpdateCoordinator
from .entity import AirobotEntity
PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class AirobotButtonEntityDescription(ButtonEntityDescription):
"""Describes Airobot button entity."""
press_fn: Callable[[AirobotDataUpdateCoordinator], Coroutine[Any, Any, None]]
BUTTON_TYPES: tuple[AirobotButtonEntityDescription, ...] = (
AirobotButtonEntityDescription(
key="restart",
device_class=ButtonDeviceClass.RESTART,
entity_category=EntityCategory.CONFIG,
press_fn=lambda coordinator: coordinator.client.reboot_thermostat(),
),
AirobotButtonEntityDescription(
key="recalibrate_co2",
translation_key="recalibrate_co2",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
press_fn=lambda coordinator: coordinator.client.recalibrate_co2_sensor(),
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirobotConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Airobot button entities."""
coordinator = entry.runtime_data
async_add_entities(
AirobotButton(coordinator, description) for description in BUTTON_TYPES
)
class AirobotButton(AirobotEntity, ButtonEntity):
"""Representation of an Airobot button."""
entity_description: AirobotButtonEntityDescription
def __init__(
self,
coordinator: AirobotDataUpdateCoordinator,
description: AirobotButtonEntityDescription,
) -> None:
"""Initialize the button."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.data.status.device_id}_{description.key}"
async def async_press(self) -> None:
"""Handle the button press."""
try:
await self.entity_description.press_fn(self.coordinator)
except AirobotConnectionError, AirobotTimeoutError:
# Connection errors during reboot are expected as device restarts
pass
except AirobotError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="button_press_failed",
translation_placeholders={"button": self.entity_description.key},
) from err
@@ -29,6 +29,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AirobotConfigEntry from . import AirobotConfigEntry
from .const import DOMAIN from .const import DOMAIN
from .coordinator import AirobotDataUpdateCoordinator
from .entity import AirobotEntity from .entity import AirobotEntity
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1
@@ -63,6 +64,11 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
_attr_min_temp = SETPOINT_TEMP_MIN _attr_min_temp = SETPOINT_TEMP_MIN
_attr_max_temp = SETPOINT_TEMP_MAX _attr_max_temp = SETPOINT_TEMP_MAX
def __init__(self, coordinator: AirobotDataUpdateCoordinator) -> None:
"""Initialize the climate entity."""
super().__init__(coordinator)
self._attr_unique_id = coordinator.data.status.device_id
@property @property
def _status(self) -> ThermostatStatus: def _status(self) -> ThermostatStatus:
"""Get status from coordinator data.""" """Get status from coordinator data."""
@@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
import asyncio
from collections.abc import Mapping from collections.abc import Mapping
from dataclasses import dataclass from dataclasses import dataclass
import logging import logging
@@ -60,11 +61,17 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> DeviceInf
try: try:
# Try to fetch data to validate connection and authentication # Try to fetch data to validate connection and authentication
status = await client.get_statuses() status, settings = await asyncio.gather(
settings = await client.get_settings() client.get_statuses(), client.get_settings()
)
except AirobotAuthError as err: except AirobotAuthError as err:
raise InvalidAuth from err raise InvalidAuth from err
except (AirobotConnectionError, AirobotTimeoutError, AirobotError) as err: except (
AirobotConnectionError,
AirobotTimeoutError,
AirobotError,
TimeoutError,
) as err:
raise CannotConnect from err raise CannotConnect from err
# Use device name or device ID as title # Use device name or device ID as title
@@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
@@ -52,8 +53,10 @@ class AirobotDataUpdateCoordinator(DataUpdateCoordinator[AirobotData]):
async def _async_update_data(self) -> AirobotData: async def _async_update_data(self) -> AirobotData:
"""Fetch data from API endpoint.""" """Fetch data from API endpoint."""
try: try:
status = await self.client.get_statuses() status, settings = await asyncio.gather(
settings = await self.client.get_settings() self.client.get_statuses(),
self.client.get_settings(),
)
except AirobotAuthError as err: except AirobotAuthError as err:
raise ConfigEntryAuthFailed( raise ConfigEntryAuthFailed(
translation_domain=DOMAIN, translation_domain=DOMAIN,
+2 -4
View File
@@ -24,8 +24,6 @@ class AirobotEntity(CoordinatorEntity[AirobotDataUpdateCoordinator]):
status = coordinator.data.status status = coordinator.data.status
settings = coordinator.data.settings settings = coordinator.data.settings
self._attr_unique_id = status.device_id
connections = set() connections = set()
if (mac := coordinator.config_entry.data.get(CONF_MAC)) is not None: if (mac := coordinator.config_entry.data.get(CONF_MAC)) is not None:
connections.add((CONNECTION_NETWORK_MAC, mac)) connections.add((CONNECTION_NETWORK_MAC, mac))
@@ -37,6 +35,6 @@ class AirobotEntity(CoordinatorEntity[AirobotDataUpdateCoordinator]):
manufacturer="Airobot", manufacturer="Airobot",
model="Thermostat", model="Thermostat",
model_id="TE1", model_id="TE1",
sw_version=str(status.fw_version), sw_version=status.fw_version_string,
hw_version=str(status.hw_version), hw_version=status.hw_version_string,
) )
@@ -1,9 +1,22 @@
{ {
"entity": { "entity": {
"button": {
"recalibrate_co2": {
"default": "mdi:molecule-co2"
}
},
"number": { "number": {
"hysteresis_band": { "hysteresis_band": {
"default": "mdi:delta" "default": "mdi:delta"
} }
},
"switch": {
"actuator_exercise_disabled": {
"default": "mdi:valve"
},
"child_lock": {
"default": "mdi:lock"
}
} }
} }
} }
@@ -12,6 +12,6 @@
"integration_type": "device", "integration_type": "device",
"iot_class": "local_polling", "iot_class": "local_polling",
"loggers": ["pyairobotrest"], "loggers": ["pyairobotrest"],
"quality_scale": "silver", "quality_scale": "platinum",
"requirements": ["pyairobotrest==0.2.0"] "requirements": ["pyairobotrest==0.3.0"]
} }
@@ -43,7 +43,7 @@ rules:
discovery-update-info: done discovery-update-info: done
discovery: done discovery: done
docs-data-update: done docs-data-update: done
docs-examples: todo docs-examples: done
docs-known-limitations: done docs-known-limitations: done
docs-supported-devices: done docs-supported-devices: done
docs-supported-functions: done docs-supported-functions: done
@@ -69,4 +69,4 @@ rules:
# Platinum # Platinum
async-dependency: done async-dependency: done
inject-websession: done inject-websession: done
strict-typing: todo strict-typing: done
+3 -1
View File
@@ -28,6 +28,7 @@ from homeassistant.util.dt import utcnow
from homeassistant.util.variance import ignore_variance from homeassistant.util.variance import ignore_variance
from . import AirobotConfigEntry from . import AirobotConfigEntry
from .coordinator import AirobotDataUpdateCoordinator
from .entity import AirobotEntity from .entity import AirobotEntity
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@@ -53,6 +54,7 @@ SENSOR_TYPES: tuple[AirobotSensorEntityDescription, ...] = (
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1,
value_fn=lambda status: status.temp_air, value_fn=lambda status: status.temp_air,
), ),
AirobotSensorEntityDescription( AirobotSensorEntityDescription(
@@ -136,7 +138,7 @@ class AirobotSensor(AirobotEntity, SensorEntity):
def __init__( def __init__(
self, self,
coordinator, coordinator: AirobotDataUpdateCoordinator,
description: AirobotSensorEntityDescription, description: AirobotSensorEntityDescription,
) -> None: ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
@@ -59,6 +59,11 @@
} }
}, },
"entity": { "entity": {
"button": {
"recalibrate_co2": {
"name": "Recalibrate CO2 sensor"
}
},
"number": { "number": {
"hysteresis_band": { "hysteresis_band": {
"name": "Hysteresis band" "name": "Hysteresis band"
@@ -80,12 +85,23 @@
"heating_uptime": { "heating_uptime": {
"name": "Heating uptime" "name": "Heating uptime"
} }
},
"switch": {
"actuator_exercise_disabled": {
"name": "Actuator exercise disabled"
},
"child_lock": {
"name": "Child lock"
}
} }
}, },
"exceptions": { "exceptions": {
"authentication_failed": { "authentication_failed": {
"message": "Authentication failed, please reauthenticate." "message": "Authentication failed, please reauthenticate."
}, },
"button_press_failed": {
"message": "Failed to press {button} button."
},
"connection_failed": { "connection_failed": {
"message": "Failed to communicate with device." "message": "Failed to communicate with device."
}, },
@@ -97,6 +113,12 @@
}, },
"set_value_failed": { "set_value_failed": {
"message": "Failed to set value: {error}" "message": "Failed to set value: {error}"
},
"switch_turn_off_failed": {
"message": "Failed to turn off {switch}."
},
"switch_turn_on_failed": {
"message": "Failed to turn on {switch}."
} }
} }
} }
+118
View File
@@ -0,0 +1,118 @@
"""Switch platform for Airobot thermostat."""
from __future__ import annotations
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
from pyairobotrest.exceptions import AirobotError
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import AirobotConfigEntry
from .const import DOMAIN
from .coordinator import AirobotDataUpdateCoordinator
from .entity import AirobotEntity
PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class AirobotSwitchEntityDescription(SwitchEntityDescription):
"""Describes Airobot switch entity."""
is_on_fn: Callable[[AirobotDataUpdateCoordinator], bool]
turn_on_fn: Callable[[AirobotDataUpdateCoordinator], Coroutine[Any, Any, None]]
turn_off_fn: Callable[[AirobotDataUpdateCoordinator], Coroutine[Any, Any, None]]
SWITCH_TYPES: tuple[AirobotSwitchEntityDescription, ...] = (
AirobotSwitchEntityDescription(
key="child_lock",
translation_key="child_lock",
entity_category=EntityCategory.CONFIG,
is_on_fn=lambda coordinator: (
coordinator.data.settings.setting_flags.childlock_enabled
),
turn_on_fn=lambda coordinator: coordinator.client.set_child_lock(True),
turn_off_fn=lambda coordinator: coordinator.client.set_child_lock(False),
),
AirobotSwitchEntityDescription(
key="actuator_exercise_disabled",
translation_key="actuator_exercise_disabled",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
is_on_fn=lambda coordinator: (
coordinator.data.settings.setting_flags.actuator_exercise_disabled
),
turn_on_fn=lambda coordinator: coordinator.client.toggle_actuator_exercise(
True
),
turn_off_fn=lambda coordinator: coordinator.client.toggle_actuator_exercise(
False
),
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirobotConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Airobot switch entities."""
coordinator = entry.runtime_data
async_add_entities(
AirobotSwitch(coordinator, description) for description in SWITCH_TYPES
)
class AirobotSwitch(AirobotEntity, SwitchEntity):
"""Representation of an Airobot switch."""
entity_description: AirobotSwitchEntityDescription
def __init__(
self,
coordinator: AirobotDataUpdateCoordinator,
description: AirobotSwitchEntityDescription,
) -> None:
"""Initialize the switch."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{coordinator.data.status.device_id}_{description.key}"
@property
def is_on(self) -> bool:
"""Return true if the switch is on."""
return self.entity_description.is_on_fn(self.coordinator)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
try:
await self.entity_description.turn_on_fn(self.coordinator)
except AirobotError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="switch_turn_on_failed",
translation_placeholders={"switch": self.entity_description.key},
) from err
await self.coordinator.async_request_refresh()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
try:
await self.entity_description.turn_off_fn(self.coordinator)
except AirobotError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="switch_turn_off_failed",
translation_placeholders={"switch": self.entity_description.key},
) from err
await self.coordinator.async_request_refresh()
@@ -114,7 +114,7 @@ class AirOSConfigFlow(ConfigFlow, domain=DOMAIN):
AirOSDeviceConnectionError, AirOSDeviceConnectionError,
): ):
self.errors["base"] = "cannot_connect" self.errors["base"] = "cannot_connect"
except (AirOSConnectionAuthenticationError, AirOSDataMissingError): except AirOSConnectionAuthenticationError, AirOSDataMissingError:
self.errors["base"] = "invalid_auth" self.errors["base"] = "invalid_auth"
except AirOSKeyDataMissingError: except AirOSKeyDataMissingError:
self.errors["base"] = "key_data_missing" self.errors["base"] = "key_data_missing"
+1 -1
View File
@@ -7,5 +7,5 @@
"integration_type": "device", "integration_type": "device",
"iot_class": "local_polling", "iot_class": "local_polling",
"quality_scale": "silver", "quality_scale": "silver",
"requirements": ["airos==0.6.0"] "requirements": ["airos==0.6.3"]
} }
+12
View File
@@ -4,12 +4,24 @@
"health_index": { "health_index": {
"default": "mdi:heart-pulse" "default": "mdi:heart-pulse"
}, },
"mold": {
"default": "mdi:water-check"
},
"oxygen": { "oxygen": {
"default": "mdi:leaf" "default": "mdi:leaf"
}, },
"performance_index": { "performance_index": {
"default": "mdi:head-check" "default": "mdi:head-check"
}, },
"r32": {
"default": "mdi:hvac"
},
"r454b": {
"default": "mdi:hvac"
},
"r454c": {
"default": "mdi:hvac"
},
"radon": { "radon": {
"default": "mdi:radioactive" "default": "mdi:radioactive"
}, },
+25 -4
View File
@@ -219,6 +219,13 @@ SENSOR_TYPES: list[AirQEntityDescription] = [
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value=lambda data: data.get("ch4_MIPEX"), value=lambda data: data.get("ch4_MIPEX"),
), ),
AirQEntityDescription(
key="mold",
translation_key="mold",
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value=lambda data: data.get("mold"),
),
AirQEntityDescription( AirQEntityDescription(
key="n2o", key="n2o",
device_class=SensorDeviceClass.NITROUS_OXIDE, device_class=SensorDeviceClass.NITROUS_OXIDE,
@@ -319,11 +326,25 @@ SENSOR_TYPES: list[AirQEntityDescription] = [
value=lambda data: data.get("c3h8_MIPEX"), value=lambda data: data.get("c3h8_MIPEX"),
), ),
AirQEntityDescription( AirQEntityDescription(
key="refigerant", key="r32",
translation_key="refigerant", translation_key="r32",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value=lambda data: data.get("refigerant"), value=lambda data: data.get("r32"),
),
AirQEntityDescription(
key="r454b",
translation_key="r454b",
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value=lambda data: data.get("r454b"),
),
AirQEntityDescription(
key="r454c",
translation_key="r454c",
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value=lambda data: data.get("r454c"),
), ),
AirQEntityDescription( AirQEntityDescription(
key="sih4", key="sih4",
+12 -3
View File
@@ -101,6 +101,9 @@
"methanethiol": { "methanethiol": {
"name": "Methanethiol" "name": "Methanethiol"
}, },
"mold": {
"name": "Mold index"
},
"noise": { "noise": {
"name": "Noise" "name": "Noise"
}, },
@@ -116,12 +119,18 @@
"propane": { "propane": {
"name": "Propane" "name": "Propane"
}, },
"r32": {
"name": "Refrigerant R-32"
},
"r454b": {
"name": "Refrigerant R-454B"
},
"r454c": {
"name": "Refrigerant R-454C"
},
"radon": { "radon": {
"name": "Radon" "name": "Radon"
}, },
"refigerant": {
"name": "Refrigerant"
},
"relative_pressure": { "relative_pressure": {
"name": "Relative pressure" "name": "Relative pressure"
}, },
@@ -1,6 +1,14 @@
{ {
"entity": { "entity": {
"sensor": { "sensor": {
"connectivity_mode": {
"default": "mdi:bluetooth-off",
"state": {
"bluetooth": "mdi:bluetooth",
"not_configured": "mdi:alert-circle",
"smartlink": "mdi:hub"
}
},
"radon_1day_avg": { "radon_1day_avg": {
"default": "mdi:radioactive" "default": "mdi:radioactive"
}, },
@@ -5,7 +5,7 @@ from __future__ import annotations
import dataclasses import dataclasses
import logging import logging
from airthings_ble import AirthingsDevice from airthings_ble import AirthingsConnectivityMode, AirthingsDevice
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@@ -41,6 +41,12 @@ from .coordinator import AirthingsBLEConfigEntry, AirthingsBLEDataUpdateCoordina
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONNECTIVITY_MODE_MAP = {
AirthingsConnectivityMode.BLE.value: "bluetooth",
AirthingsConnectivityMode.SMARTLINK.value: "smartlink",
AirthingsConnectivityMode.NOT_CONFIGURED.value: "not_configured",
}
SENSORS_MAPPING_TEMPLATE: dict[str, SensorEntityDescription] = { SENSORS_MAPPING_TEMPLATE: dict[str, SensorEntityDescription] = {
"radon_1day_avg": SensorEntityDescription( "radon_1day_avg": SensorEntityDescription(
key="radon_1day_avg", key="radon_1day_avg",
@@ -129,6 +135,14 @@ SENSORS_MAPPING_TEMPLATE: dict[str, SensorEntityDescription] = {
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0, suggested_display_precision=0,
), ),
"connectivity_mode": SensorEntityDescription(
key="connectivity_mode",
translation_key="connectivity_mode",
device_class=SensorDeviceClass.ENUM,
options=list(CONNECTIVITY_MODE_MAP.values()),
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
),
} }
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@@ -256,4 +270,12 @@ class AirthingsSensor(
@property @property
def native_value(self) -> StateType: def native_value(self) -> StateType:
"""Return the value reported by the sensor.""" """Return the value reported by the sensor."""
return self.coordinator.data.sensors[self.entity_description.key] value = self.coordinator.data.sensors[self.entity_description.key]
# Map connectivity mode to enum values
if self.entity_description.key == "connectivity_mode":
if not isinstance(value, str):
return None
return CONNECTIVITY_MODE_MAP.get(value)
return value
@@ -30,6 +30,14 @@
"ambient_noise": { "ambient_noise": {
"name": "Ambient noise" "name": "Ambient noise"
}, },
"connectivity_mode": {
"name": "Connectivity mode",
"state": {
"bluetooth": "Bluetooth",
"not_configured": "Not configured",
"smartlink": "SmartLink"
}
},
"illuminance": { "illuminance": {
"name": "[%key:component::sensor::entity_component::illuminance::name%]" "name": "[%key:component::sensor::entity_component::illuminance::name%]"
}, },
@@ -130,7 +130,7 @@ class AirVisualFlowHandler(ConfigFlow, domain=DOMAIN):
try: try:
await coro await coro
except (InvalidKeyError, KeyExpiredError, UnauthorizedError): except InvalidKeyError, KeyExpiredError, UnauthorizedError:
errors[CONF_API_KEY] = "invalid_api_key" errors[CONF_API_KEY] = "invalid_api_key"
except NotFoundError: except NotFoundError:
errors[CONF_CITY] = "location_not_found" errors[CONF_CITY] = "location_not_found"
@@ -85,6 +85,22 @@ class AirzoneSystemEntity(AirzoneEntity):
value = system[key] value = system[key]
return value return value
async def _async_update_sys_params(self, params: dict[str, Any]) -> None:
"""Send system parameters to API."""
_params = {
API_SYSTEM_ID: self.system_id,
**params,
}
_LOGGER.debug("update_sys_params=%s", _params)
try:
await self.coordinator.airzone.set_sys_parameters(_params)
except AirzoneError as error:
raise HomeAssistantError(
f"Failed to set system {self.entity_id}: {error}"
) from error
self.coordinator.async_set_updated_data(self.coordinator.airzone.data())
class AirzoneHotWaterEntity(AirzoneEntity): class AirzoneHotWaterEntity(AirzoneEntity):
"""Define an Airzone Hot Water entity.""" """Define an Airzone Hot Water entity."""
@@ -12,5 +12,5 @@
"integration_type": "hub", "integration_type": "hub",
"iot_class": "local_polling", "iot_class": "local_polling",
"loggers": ["aioairzone"], "loggers": ["aioairzone"],
"requirements": ["aioairzone==1.0.4"] "requirements": ["aioairzone==1.0.5"]
} }
+73 -14
View File
@@ -20,6 +20,7 @@ from aioairzone.const import (
AZD_MODES, AZD_MODES,
AZD_Q_ADAPT, AZD_Q_ADAPT,
AZD_SLEEP, AZD_SLEEP,
AZD_SYSTEMS,
AZD_ZONES, AZD_ZONES,
) )
@@ -30,7 +31,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator from .coordinator import AirzoneConfigEntry, AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity from .entity import AirzoneEntity, AirzoneSystemEntity, AirzoneZoneEntity
@dataclass(frozen=True, kw_only=True) @dataclass(frozen=True, kw_only=True)
@@ -85,14 +86,7 @@ def main_zone_options(
return [k for k, v in options.items() if v in modes] return [k for k, v in options.items() if v in modes]
MAIN_ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = ( SYSTEM_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription(
api_param=API_MODE,
key=AZD_MODE,
options_dict=MODE_DICT,
options_fn=main_zone_options,
translation_key="modes",
),
AirzoneSelectDescription( AirzoneSelectDescription(
api_param=API_Q_ADAPT, api_param=API_Q_ADAPT,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
@@ -104,6 +98,17 @@ MAIN_ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
) )
MAIN_ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription(
api_param=API_MODE,
key=AZD_MODE,
options_dict=MODE_DICT,
options_fn=main_zone_options,
translation_key="modes",
),
)
ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = ( ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription( AirzoneSelectDescription(
api_param=API_COLD_ANGLE, api_param=API_COLD_ANGLE,
@@ -140,16 +145,37 @@ async def async_setup_entry(
"""Add Airzone select from a config_entry.""" """Add Airzone select from a config_entry."""
coordinator = entry.runtime_data coordinator = entry.runtime_data
added_systems: set[str] = set()
added_zones: set[str] = set() added_zones: set[str] = set()
def _async_entity_listener() -> None: def _async_entity_listener() -> None:
"""Handle additions of select.""" """Handle additions of select."""
entities: list[AirzoneBaseSelect] = []
systems_data = coordinator.data.get(AZD_SYSTEMS, {})
received_systems = set(systems_data)
new_systems = received_systems - added_systems
if new_systems:
entities.extend(
AirzoneSystemSelect(
coordinator,
description,
entry,
system_id,
systems_data.get(system_id),
)
for system_id in new_systems
for description in SYSTEM_SELECT_TYPES
if description.key in systems_data.get(system_id)
)
added_systems.update(new_systems)
zones_data = coordinator.data.get(AZD_ZONES, {}) zones_data = coordinator.data.get(AZD_ZONES, {})
received_zones = set(zones_data) received_zones = set(zones_data)
new_zones = received_zones - added_zones new_zones = received_zones - added_zones
if new_zones: if new_zones:
entities: list[AirzoneZoneSelect] = [ entities.extend(
AirzoneZoneSelect( AirzoneZoneSelect(
coordinator, coordinator,
description, description,
@@ -161,8 +187,8 @@ async def async_setup_entry(
for description in MAIN_ZONE_SELECT_TYPES for description in MAIN_ZONE_SELECT_TYPES
if description.key in zones_data.get(system_zone_id) if description.key in zones_data.get(system_zone_id)
and zones_data.get(system_zone_id).get(AZD_MASTER) is True and zones_data.get(system_zone_id).get(AZD_MASTER) is True
] )
entities += [ entities.extend(
AirzoneZoneSelect( AirzoneZoneSelect(
coordinator, coordinator,
description, description,
@@ -173,10 +199,11 @@ async def async_setup_entry(
for system_zone_id in new_zones for system_zone_id in new_zones
for description in ZONE_SELECT_TYPES for description in ZONE_SELECT_TYPES
if description.key in zones_data.get(system_zone_id) if description.key in zones_data.get(system_zone_id)
] )
async_add_entities(entities)
added_zones.update(new_zones) added_zones.update(new_zones)
async_add_entities(entities)
entry.async_on_unload(coordinator.async_add_listener(_async_entity_listener)) entry.async_on_unload(coordinator.async_add_listener(_async_entity_listener))
_async_entity_listener() _async_entity_listener()
@@ -203,6 +230,38 @@ class AirzoneBaseSelect(AirzoneEntity, SelectEntity):
self._attr_current_option = self._get_current_option() self._attr_current_option = self._get_current_option()
class AirzoneSystemSelect(AirzoneSystemEntity, AirzoneBaseSelect):
"""Define an Airzone System select."""
def __init__(
self,
coordinator: AirzoneUpdateCoordinator,
description: AirzoneSelectDescription,
entry: ConfigEntry,
system_id: str,
system_data: dict[str, Any],
) -> None:
"""Initialize."""
super().__init__(coordinator, entry, system_data)
self._attr_unique_id = f"{self._attr_unique_id}_{system_id}_{description.key}"
self.entity_description = description
self._attr_options = self.entity_description.options_fn(
system_data, description.options_dict
)
self.values_dict = {v: k for k, v in description.options_dict.items()}
self._async_update_attrs()
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
param = self.entity_description.api_param
value = self.entity_description.options_dict[option]
await self._async_update_sys_params({param: value})
class AirzoneZoneSelect(AirzoneZoneEntity, AirzoneBaseSelect): class AirzoneZoneSelect(AirzoneZoneEntity, AirzoneBaseSelect):
"""Define an Airzone Zone select.""" """Define an Airzone Zone select."""
@@ -100,7 +100,7 @@ class AirZoneCloudConfigFlow(ConfigFlow, domain=DOMAIN):
try: try:
await self.airzone.login() await self.airzone.login()
except (AirzoneCloudError, LoginError): except AirzoneCloudError, LoginError:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
else: else:
return await self.async_step_inst_pick() return await self.async_step_inst_pick()
@@ -9,6 +9,7 @@
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]", "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
"oauth_error": "[%key:common::config_flow::abort::oauth2_error%]", "oauth_error": "[%key:common::config_flow::abort::oauth2_error%]",
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]", "oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
"oauth_implementation_unavailable": "[%key:common::config_flow::abort::oauth2_implementation_unavailable%]",
"oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]", "oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]",
"oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]", "oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
@@ -0,0 +1,93 @@
"""Provides conditions for alarm control panels."""
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.condition import (
Condition,
EntityStateConditionBase,
make_entity_state_condition,
)
from homeassistant.helpers.entity import get_supported_features
from .const import DOMAIN, AlarmControlPanelEntityFeature, AlarmControlPanelState
def supports_feature(hass: HomeAssistant, entity_id: str, features: int) -> bool:
"""Test if an entity supports the specified features."""
try:
return bool(get_supported_features(hass, entity_id) & features)
except HomeAssistantError:
return False
class EntityStateRequiredFeaturesCondition(EntityStateConditionBase):
"""State condition."""
_required_features: int
def entity_filter(self, entities: set[str]) -> set[str]:
"""Filter entities of this domain with the required features."""
entities = super().entity_filter(entities)
return {
entity_id
for entity_id in entities
if supports_feature(self._hass, entity_id, self._required_features)
}
def make_entity_state_required_features_condition(
domain: str, to_state: str, required_features: int
) -> type[EntityStateRequiredFeaturesCondition]:
"""Create an entity state condition class with required feature filtering."""
class CustomCondition(EntityStateRequiredFeaturesCondition):
"""Condition for entity state changes."""
_domain = domain
_states = {to_state}
_required_features = required_features
return CustomCondition
CONDITIONS: dict[str, type[Condition]] = {
"is_armed": make_entity_state_condition(
DOMAIN,
{
AlarmControlPanelState.ARMED_AWAY,
AlarmControlPanelState.ARMED_CUSTOM_BYPASS,
AlarmControlPanelState.ARMED_HOME,
AlarmControlPanelState.ARMED_NIGHT,
AlarmControlPanelState.ARMED_VACATION,
},
),
"is_armed_away": make_entity_state_required_features_condition(
DOMAIN,
AlarmControlPanelState.ARMED_AWAY,
AlarmControlPanelEntityFeature.ARM_AWAY,
),
"is_armed_home": make_entity_state_required_features_condition(
DOMAIN,
AlarmControlPanelState.ARMED_HOME,
AlarmControlPanelEntityFeature.ARM_HOME,
),
"is_armed_night": make_entity_state_required_features_condition(
DOMAIN,
AlarmControlPanelState.ARMED_NIGHT,
AlarmControlPanelEntityFeature.ARM_NIGHT,
),
"is_armed_vacation": make_entity_state_required_features_condition(
DOMAIN,
AlarmControlPanelState.ARMED_VACATION,
AlarmControlPanelEntityFeature.ARM_VACATION,
),
"is_disarmed": make_entity_state_condition(DOMAIN, AlarmControlPanelState.DISARMED),
"is_triggered": make_entity_state_condition(
DOMAIN, AlarmControlPanelState.TRIGGERED
),
}
async def async_get_conditions(hass: HomeAssistant) -> dict[str, type[Condition]]:
"""Return the alarm control panel conditions."""
return CONDITIONS
@@ -0,0 +1,52 @@
.condition_common: &condition_common
target:
entity:
domain: alarm_control_panel
fields: &condition_common_fields
behavior:
required: true
default: any
selector:
select:
translation_key: condition_behavior
options:
- all
- any
is_armed: *condition_common
is_armed_away:
fields: *condition_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_AWAY
is_armed_home:
fields: *condition_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_HOME
is_armed_night:
fields: *condition_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_NIGHT
is_armed_vacation:
fields: *condition_common_fields
target:
entity:
domain: alarm_control_panel
supported_features:
- alarm_control_panel.AlarmControlPanelEntityFeature.ARM_VACATION
is_disarmed: *condition_common
is_triggered: *condition_common
@@ -1,4 +1,27 @@
{ {
"conditions": {
"is_armed": {
"condition": "mdi:shield"
},
"is_armed_away": {
"condition": "mdi:shield-lock"
},
"is_armed_home": {
"condition": "mdi:shield-home"
},
"is_armed_night": {
"condition": "mdi:shield-moon"
},
"is_armed_vacation": {
"condition": "mdi:shield-airplane"
},
"is_disarmed": {
"condition": "mdi:shield-off"
},
"is_triggered": {
"condition": "mdi:bell-ring"
}
},
"entity_component": { "entity_component": {
"_": { "_": {
"default": "mdi:shield", "default": "mdi:shield",
@@ -1,8 +1,82 @@
{ {
"common": { "common": {
"condition_behavior_description": "How the state should match on the targeted alarms.",
"condition_behavior_name": "Behavior",
"trigger_behavior_description": "The behavior of the targeted alarms to trigger on.", "trigger_behavior_description": "The behavior of the targeted alarms to trigger on.",
"trigger_behavior_name": "Behavior" "trigger_behavior_name": "Behavior"
}, },
"conditions": {
"is_armed": {
"description": "Tests if one or more alarms are armed.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is armed"
},
"is_armed_away": {
"description": "Tests if one or more alarms are armed in away mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is armed away"
},
"is_armed_home": {
"description": "Tests if one or more alarms are armed in home mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is armed home"
},
"is_armed_night": {
"description": "Tests if one or more alarms are armed in night mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is armed night"
},
"is_armed_vacation": {
"description": "Tests if one or more alarms are armed in vacation mode.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is armed vacation"
},
"is_disarmed": {
"description": "Tests if one or more alarms are disarmed.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is disarmed"
},
"is_triggered": {
"description": "Tests if one or more alarms are triggered.",
"fields": {
"behavior": {
"description": "[%key:component::alarm_control_panel::common::condition_behavior_description%]",
"name": "[%key:component::alarm_control_panel::common::condition_behavior_name%]"
}
},
"name": "Alarm is triggered"
}
},
"device_automation": { "device_automation": {
"action_type": { "action_type": {
"arm_away": "Arm {entity_name} away", "arm_away": "Arm {entity_name} away",
@@ -76,6 +150,12 @@
} }
}, },
"selector": { "selector": {
"condition_behavior": {
"options": {
"all": "All",
"any": "Any"
}
},
"trigger_behavior": { "trigger_behavior": {
"options": { "options": {
"any": "Any", "any": "Any",
@@ -86,7 +166,7 @@
}, },
"services": { "services": {
"alarm_arm_away": { "alarm_arm_away": {
"description": "Arms the alarm in the away mode.", "description": "Arms an alarm in the away mode.",
"fields": { "fields": {
"code": { "code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]", "description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
@@ -96,7 +176,7 @@
"name": "Arm away" "name": "Arm away"
}, },
"alarm_arm_custom_bypass": { "alarm_arm_custom_bypass": {
"description": "Arms the alarm while allowing to bypass a custom area.", "description": "Arms an alarm while allowing to bypass a custom area.",
"fields": { "fields": {
"code": { "code": {
"description": "Code to arm the alarm.", "description": "Code to arm the alarm.",
@@ -106,7 +186,7 @@
"name": "Arm with custom bypass" "name": "Arm with custom bypass"
}, },
"alarm_arm_home": { "alarm_arm_home": {
"description": "Arms the alarm in the home mode.", "description": "Arms an alarm in the home mode.",
"fields": { "fields": {
"code": { "code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]", "description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
@@ -116,7 +196,7 @@
"name": "Arm home" "name": "Arm home"
}, },
"alarm_arm_night": { "alarm_arm_night": {
"description": "Arms the alarm in the night mode.", "description": "Arms an alarm in the night mode.",
"fields": { "fields": {
"code": { "code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]", "description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
@@ -126,7 +206,7 @@
"name": "Arm night" "name": "Arm night"
}, },
"alarm_arm_vacation": { "alarm_arm_vacation": {
"description": "Arms the alarm in the vacation mode.", "description": "Arms an alarm in the vacation mode.",
"fields": { "fields": {
"code": { "code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]", "description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
@@ -136,7 +216,7 @@
"name": "Arm vacation" "name": "Arm vacation"
}, },
"alarm_disarm": { "alarm_disarm": {
"description": "Disarms the alarm.", "description": "Disarms an alarm.",
"fields": { "fields": {
"code": { "code": {
"description": "Code to disarm the alarm.", "description": "Code to disarm the alarm.",
@@ -146,7 +226,7 @@
"name": "Disarm" "name": "Disarm"
}, },
"alarm_trigger": { "alarm_trigger": {
"description": "Triggers the alarm manually.", "description": "Triggers an alarm manually.",
"fields": { "fields": {
"code": { "code": {
"description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]", "description": "[%key:component::alarm_control_panel::services::alarm_arm_custom_bypass::fields::code::description%]",
@@ -14,7 +14,7 @@ from .const import DOMAIN, AlarmControlPanelEntityFeature, AlarmControlPanelStat
def supports_feature(hass: HomeAssistant, entity_id: str, features: int) -> bool: def supports_feature(hass: HomeAssistant, entity_id: str, features: int) -> bool:
"""Get the device class of an entity or UNDEFINED if not found.""" """Test if an entity supports the specified features."""
try: try:
return bool(get_supported_features(hass, entity_id) & features) return bool(get_supported_features(hass, entity_id) & features)
except HomeAssistantError: except HomeAssistantError:
@@ -39,7 +39,7 @@ class EntityStateTriggerRequiredFeatures(EntityTargetStateTriggerBase):
def make_entity_state_trigger_required_features( def make_entity_state_trigger_required_features(
domain: str, to_state: str, required_features: int domain: str, to_state: str, required_features: int
) -> type[EntityTargetStateTriggerBase]: ) -> type[EntityTargetStateTriggerBase]:
"""Create an entity state trigger class.""" """Create an entity state trigger class with required feature filtering."""
class CustomTrigger(EntityStateTriggerRequiredFeatures): class CustomTrigger(EntityStateTriggerRequiredFeatures):
"""Trigger for entity state changes.""" """Trigger for entity state changes."""
@@ -18,12 +18,15 @@ from homeassistant.const import (
Platform, Platform,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.typing import ConfigType
from .const import ( from .const import (
CONF_DEVICE_BAUD, CONF_DEVICE_BAUD,
CONF_DEVICE_PATH, CONF_DEVICE_PATH,
DOMAIN,
PROTOCOL_SERIAL, PROTOCOL_SERIAL,
PROTOCOL_SOCKET, PROTOCOL_SOCKET,
SIGNAL_PANEL_MESSAGE, SIGNAL_PANEL_MESSAGE,
@@ -32,9 +35,11 @@ from .const import (
SIGNAL_ZONE_FAULT, SIGNAL_ZONE_FAULT,
SIGNAL_ZONE_RESTORE, SIGNAL_ZONE_RESTORE,
) )
from .services import async_setup_services
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
PLATFORMS = [ PLATFORMS = [
Platform.ALARM_CONTROL_PANEL, Platform.ALARM_CONTROL_PANEL,
Platform.BINARY_SENSOR, Platform.BINARY_SENSOR,
@@ -54,6 +59,12 @@ class AlarmDecoderData:
restart: bool restart: bool
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the component."""
async_setup_services(hass)
return True
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: AlarmDecoderConfigEntry hass: HomeAssistant, entry: AlarmDecoderConfigEntry
) -> bool: ) -> bool:
@@ -2,17 +2,13 @@
from __future__ import annotations from __future__ import annotations
import voluptuous as vol
from homeassistant.components.alarm_control_panel import ( from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity, AlarmControlPanelEntity,
AlarmControlPanelEntityFeature, AlarmControlPanelEntityFeature,
AlarmControlPanelState, AlarmControlPanelState,
CodeFormat, CodeFormat,
) )
from homeassistant.const import ATTR_CODE
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -27,11 +23,6 @@ from .const import (
) )
from .entity import AlarmDecoderEntity from .entity import AlarmDecoderEntity
SERVICE_ALARM_TOGGLE_CHIME = "alarm_toggle_chime"
SERVICE_ALARM_KEYPRESS = "alarm_keypress"
ATTR_KEYPRESS = "keypress"
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
@@ -50,23 +41,6 @@ async def async_setup_entry(
) )
async_add_entities([entity]) async_add_entities([entity])
platform = entity_platform.async_get_current_platform()
platform.async_register_entity_service(
SERVICE_ALARM_TOGGLE_CHIME,
{
vol.Required(ATTR_CODE): cv.string,
},
"alarm_toggle_chime",
)
platform.async_register_entity_service(
SERVICE_ALARM_KEYPRESS,
{
vol.Required(ATTR_KEYPRESS): cv.string,
},
"alarm_keypress",
)
class AlarmDecoderAlarmPanel(AlarmDecoderEntity, AlarmControlPanelEntity): class AlarmDecoderAlarmPanel(AlarmDecoderEntity, AlarmControlPanelEntity):
"""Representation of an AlarmDecoder-based alarm panel.""" """Representation of an AlarmDecoder-based alarm panel."""
@@ -0,0 +1,46 @@
"""Support for AlarmDecoder-based alarm control panels (Honeywell/DSC)."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.alarm_control_panel import (
DOMAIN as ALARM_CONTROL_PANEL_DOMAIN,
)
from homeassistant.const import ATTR_CODE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, service
from .const import DOMAIN
SERVICE_ALARM_TOGGLE_CHIME = "alarm_toggle_chime"
SERVICE_ALARM_KEYPRESS = "alarm_keypress"
ATTR_KEYPRESS = "keypress"
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Home Assistant services."""
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_ALARM_TOGGLE_CHIME,
entity_domain=ALARM_CONTROL_PANEL_DOMAIN,
schema={
vol.Required(ATTR_CODE): cv.string,
},
func="alarm_toggle_chime",
)
service.async_register_platform_entity_service(
hass,
DOMAIN,
SERVICE_ALARM_KEYPRESS,
entity_domain=ALARM_CONTROL_PANEL_DOMAIN,
schema={
vol.Required(ATTR_KEYPRESS): cv.string,
},
func="alarm_keypress",
)
+1 -1
View File
@@ -123,7 +123,7 @@ class Auth:
allow_redirects=True, allow_redirects=True,
) )
except (TimeoutError, aiohttp.ClientError): except TimeoutError, aiohttp.ClientError:
_LOGGER.error("Timeout calling LWA to get auth token") _LOGGER.error("Timeout calling LWA to get auth token")
return None return None
@@ -358,7 +358,7 @@ async def async_send_changereport_message(
""" """
try: try:
token = await config.async_get_access_token() token = await config.async_get_access_token()
except (RequireRelink, NoTokenAvailable): except RequireRelink, NoTokenAvailable:
await config.set_authorized(False) await config.set_authorized(False)
_LOGGER.error( _LOGGER.error(
"Error when sending ChangeReport to Alexa, could not get access token" "Error when sending ChangeReport to Alexa, could not get access token"
@@ -392,7 +392,7 @@ async def async_send_changereport_message(
allow_redirects=True, allow_redirects=True,
) )
except (TimeoutError, aiohttp.ClientError): except TimeoutError, aiohttp.ClientError:
_LOGGER.error("Timeout sending report to Alexa for %s", alexa_entity.entity_id) _LOGGER.error("Timeout sending report to Alexa for %s", alexa_entity.entity_id)
return return
@@ -549,7 +549,7 @@ async def async_send_doorbell_event_message(
allow_redirects=True, allow_redirects=True,
) )
except (TimeoutError, aiohttp.ClientError): except TimeoutError, aiohttp.ClientError:
_LOGGER.error("Timeout sending report to Alexa for %s", alexa_entity.entity_id) _LOGGER.error("Timeout sending report to Alexa for %s", alexa_entity.entity_id)
return return
@@ -29,3 +29,24 @@ COUNTRY_DOMAINS = {
CATEGORY_SENSORS = "sensors" CATEGORY_SENSORS = "sensors"
CATEGORY_NOTIFICATIONS = "notifications" CATEGORY_NOTIFICATIONS = "notifications"
# Map service translation keys to Alexa API
INFO_SKILLS_MAPPING = {
"calendar_today": "Alexa.Calendar.PlayToday",
"calendar_tomorrow": "Alexa.Calendar.PlayTomorrow",
"calendar_next": "Alexa.Calendar.PlayNext",
"date": "Alexa.Date.Play",
"time": "Alexa.Time.Play",
"national_news": "Alexa.News.NationalNews",
"flash_briefing": "Alexa.FlashBriefing.Play",
"traffic": "Alexa.Traffic.Play",
"weather": "Alexa.Weather.Play",
"cleanup": "Alexa.CleanUp.Play",
"good_morning": "Alexa.GoodMorning.Play",
"sing_song": "Alexa.SingASong.Play",
"fun_fact": "Alexa.FunFact.Play",
"tell_joke": "Alexa.Joke.Play",
"tell_story": "Alexa.TellStory.Play",
"im_home": "Alexa.ImHome.Play",
"goodnight": "Alexa.GoodNight.Play",
}

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