Compare commits

..

81 Commits

Author SHA1 Message Date
Paulus Schoutsen aabd681d7e 2022.10.1 (#79751) 2022-10-06 15:08:25 -04:00
Paulus Schoutsen 570270b9ea Bumped version to 2022.10.1 2022-10-06 14:13:51 -04:00
Bram Kragten aacae6b9bf Update frontend to 20221006.0 (#79745) 2022-10-06 14:13:46 -04:00
Erik Montnemery 35a69cb253 Correct how unit used for statistics is determined (#79725) 2022-10-06 14:13:46 -04:00
Matthew Simpson 998d13499c Bump btsmarthub_devicelist to 0.2.3 (#79705)
* Bump btsmarthub_devicelist

This PR bumps the btsmarthub_devicelist version to correct an issue
experienced by a recent firmware upgrade to the SmartHub2.

* Bump btsmarthub_devicelist to 0.2.3

This version bump fixes an issue where BT SmartHub2 devices cannot be
correctly autodetected. The current workaround is to specifiy it
manually, which isn't great UX (and did previously work until a recent
firmware upgrade).

I've also taken the opportunity to reassign ownership of the component
to myself as @jxwolstenholme no longer has a SmartHub so cannot do
manual testing and also has no need to use the component anymore.
2022-10-06 14:13:45 -04:00
J. Nick Koston 3bd4d66b2e Fix bluetooth diagnostics on macos (#79680)
* Fix bluetooth diagnostics on macos

The pyobjc objects cannot be pickled which cases dataclasses
asdict to raise an exception when trying to do the deepcopy

We now implement our own as_dict to avoid this problem

* add cover
2022-10-06 14:13:44 -04:00
puddly 5f37742197 ZHA radio migration: reset the old adapter (#79663) 2022-10-06 14:13:44 -04:00
Erik Montnemery 92afbf01e7 Simplify long term statistics by always supporting unit conversion (#79557) 2022-10-06 14:13:43 -04:00
Franck Nijhof eb003f34f0 2022.10.0 (#79659) 2022-10-05 20:13:12 +02:00
Erik Montnemery 9f7f13ac87 Don't normalize units of long term statistics (#79320)
* Don't normalize units of long term statistics

* Update statistics.py
2022-10-05 19:10:11 +02:00
Franck Nijhof 7a1757a61f Bumped version to 2022.10.0 2022-10-05 18:05:12 +02:00
Bram Kragten 9938642800 Update frontend to 20221005.0 (#79656) 2022-10-05 18:04:35 +02:00
Erik Montnemery 7e57933164 Normalize to kWh when handling WS energy/fossil_energy_consumption (#79649)
* Normalize to kWh when handling WS energy/fossil_energy_consumption

* Improve test
2022-10-05 18:04:29 +02:00
Jafar Atili 20db8138d9 Enhanced switchbee device naming (#79641) 2022-10-05 18:03:08 +02:00
Erik Montnemery 146520b437 Fix search throwing on templated services (#79637) 2022-10-05 11:58:12 +02:00
kpine 20c61af5b7 Allow picking multiple entity targets for zwave_js.refresh_value service (#79634)
Allow selection of multiple entities for zwave_js.refresh_value service
2022-10-05 11:58:09 +02:00
puddly e26f3de80b Bump ZHA dependencies (#79623) 2022-10-05 11:58:06 +02:00
Robert Svensson b4cb70cdeb Bump UniFi dependency to v37 (#79617) 2022-10-05 11:58:03 +02:00
Mike Degatano 895facdf72 Supervisor update entity auto update from api (#79611)
* Supervisor update entity auto update from api

* Update api mocks in tests
2022-10-05 11:58:00 +02:00
Mike Degatano ed7c93240c Handle state is None in InfluxDB (#79609) 2022-10-05 11:57:56 +02:00
J. Nick Koston 2c34190d82 Bump dbus-fast to 1.24.0 (#79608) 2022-10-05 11:57:50 +02:00
Jafar Atili 98567b6f26 Add supported brands for switchbee (#79595) 2022-10-05 11:57:45 +02:00
Tobias Sauerwein 9302071527 Netatmo add supported brands (#79563) 2022-10-05 11:57:39 +02:00
Paulus Schoutsen af5f5542d2 Bumped version to 2022.10.0b6 2022-10-04 11:52:10 -04:00
Bram Kragten f08fab9d7e Update frontend to 20221004.0 (#79602) 2022-10-04 11:52:02 -04:00
Paulus Schoutsen 1efa374c4e Add a couple more brands (#79600) 2022-10-04 11:52:02 -04:00
Franck Nijhof 723d415966 Set system & entity integration types (#79593) 2022-10-04 11:52:00 -04:00
epenet 09f1039f32 Add docstring to US volume constants (#79582)
* Add docstring to US volume constants

* A blank line separation
2022-10-04 11:52:00 -04:00
Franck Nijhof 9ca179ddcb Collect all brands (#79579) 2022-10-04 11:51:59 -04:00
kpine 310dbe90a1 Set zwave_js climate entity target temp attributes based on current mode (#79575)
* Report temperature correctly

* DRY

* Add test assertions

* Don't catch TypeError (revert)
2022-10-04 11:51:58 -04:00
J. Nick Koston 39be6ecd00 Bump dbus-fast to 1.23.0 (#79570) 2022-10-04 11:51:58 -04:00
Hans Oischinger 5957c6a185 Address late review of ViCare (#79458)
Runn blocking I/O of button entity creation in async_add_executor_job
2022-10-04 11:51:57 -04:00
Raman Gupta 04a2a041c3 Bump zwave_js lib to 0.43.0 and fix multi-file firmware updates (#79342) 2022-10-04 11:51:57 -04:00
Paulus Schoutsen 7cfba93d50 Bumped version to 2022.10.0b5 2022-10-03 21:19:03 -04:00
puddly e13c6a5264 Bump ZHA dependencies (#79565)
Bump all ZHA dependencies
2022-10-03 21:18:58 -04:00
Tobias Sauerwein 572d15050f Netatmo bump pyatmo to 7.1.0 (#79562)
Bump pyatmo to 7.1.0
2022-10-03 21:18:57 -04:00
Nathan Spencer dd243e18e6 Remove repairs issue per PR review request (#79561) 2022-10-03 21:18:57 -04:00
J. Nick Koston b1883609cf Remove call to deprecated bleak register_detection_callback (#79558) 2022-10-03 21:18:56 -04:00
Erik Montnemery 85c131ed43 Fix preserving long term statistics when entity_id is changed (#79556) 2022-10-03 21:18:55 -04:00
Bram Kragten a9f2119932 Update frontend to 20221003.0 (#79551) 2022-10-03 21:18:55 -04:00
Maikel Punie d32ab6ff8f Bump velbusaio to 2022.10.2 (#79537) 2022-10-03 21:18:54 -04:00
J. Nick Koston d77afb0a79 Bump dbus-fast to 1.22.0 (#79527)
Performance improvements
https://github.com/Bluetooth-Devices/dbus-fast/compare/v1.21.17...v1.22.0
2022-10-03 21:18:53 -04:00
epenet 736991af35 Align temperature conversion with other converters (#79521)
* Align temperature conversion with other converters

* Add comments and docstring

* Align tests
2022-10-03 21:18:53 -04:00
Maikel Punie e513c4fafc Bumb velbusaio to 2022.10.1 (#79471) 2022-10-03 21:18:52 -04:00
Ben Randall b519bf5332 Improve device_automation trigger validation (#75044)
* improve device_automation trigger validation

Validates the trigger configuration against the device_trigger schema before trying to access any of the properties in order to provide better error messages.
Updates the error message to include an explicit indication that the error is coming from a trigger configuration.  The inner error message from the validator can be accessed by viewing the stack trace.
Add test case for trigger missing domain.

Make action and condition validation consistent with trigger.  This is not strictly necessary, but should be helpful for certain use cases that bypass some of the outer validation.

Removed redundant schema elements from humidifier device_trigger.

**Blueprint with missing `domain`**
```
2022-07-12 06:02:18.351 ERROR (MainThread) [homeassistant.setup] Error during setup of component automation
Traceback (most recent call last):
  File "/workspaces/core/homeassistant/setup.py", line 235, in _async_setup_component
    result = await task
  File "/workspaces/core/homeassistant/components/automation/__init__.py", line 241, in async_setup
    if not await _async_process_config(hass, config, component):
  File "/workspaces/core/homeassistant/components/automation/__init__.py", line 648, in _async_process_config
    await async_validate_config_item(hass, raw_config),
  File "/workspaces/core/homeassistant/components/automation/config.py", line 74, in async_validate_config_item
    config[CONF_TRIGGER] = await async_validate_trigger_config(
  File "/workspaces/core/homeassistant/helpers/trigger.py", line 59, in async_validate_trigger_config
    conf = await platform.async_validate_trigger_config(hass, conf)
  File "/workspaces/core/homeassistant/components/device_automation/trigger.py", line 67, in async_validate_trigger_config
    hass, config[CONF_DOMAIN], DeviceAutomationType.TRIGGER
KeyError: 'domain'
```

**Blueprint with missing `property` (specific to zwave_js event schema)**
```
2022-07-12 06:09:54.206 ERROR (MainThread) [homeassistant.components.automation] Blueprint Missing Property generated invalid automation with inputs OrderedDict([('control_switch', '498be56d796836a67406e9ad373d23db')]): required key not provided @ data['property']. Got None
```

**Blueprint with missing `domain`**
```
2022-07-12 06:12:16.080 ERROR (MainThread) [homeassistant.components.automation] Blueprint Missing Domain generated invalid automation with inputs OrderedDict([('control_switch', '498be56d796836a67406e9ad373d23db')]): invalid trigger configuration: required key not provided @ data['domain']. Got <homeassistant.components.blueprint.models.BlueprintInputs object at 0x7f581e097820>
```

**Blueprint with missing `property` (specific to zwave_js event schema)**
```
2022-07-12 06:12:16.680 ERROR (MainThread) [homeassistant.components.automation] Blueprint Missing Property generated invalid automation with inputs OrderedDict([('control_switch', '498be56d796836a67406e9ad373d23db')]): invalid trigger configuration: required key not provided @ data['property']. Got <homeassistant.components.blueprint.models.BlueprintInputs object at 0x7f581c0dc9d0>
```

* Revert humifidier TRIGGER_SCHEMA change.
2022-10-03 21:18:51 -04:00
Allen Porter 8f44c11677 Add option to set a stun server for RTSPtoWebRTC (#72574) 2022-10-03 21:18:50 -04:00
Paulus Schoutsen 3abd0877f7 Bumped version to 2022.10.0b4 2022-10-02 21:25:55 -04:00
Jesse Hills 68aa0856c3 Bump aioesphomeapi to 11.1.0 (#79515) 2022-10-02 21:25:34 -04:00
J. Nick Koston ad1ed811e8 Bump bluetooth dependencies (#79514) 2022-10-02 21:25:33 -04:00
Michael 8c84efa842 Remove deprecated update binary sensor from Synology DSM (#79509) 2022-10-02 21:25:32 -04:00
Michael 12fc7f29d5 Set Synology DSM update entity to unavailable in case no data from api gathered (#79508) 2022-10-02 21:25:32 -04:00
Bram Kragten cc8267fb13 Update frontend to 20221002.0 (#79491) 2022-10-02 21:25:31 -04:00
Robert Svensson bcd9510733 Fix missing string message in UniFi (#79487) 2022-10-02 21:25:30 -04:00
TheJulianJES 43891f0baa Fix empty default ZHA configuration (#79475)
* Also add 0 as a default for transition in const.py

This is the same default transition (none) that is used in ZHA's light.py

* Send default values for unconfigured options in ZHA's configuration API

* Remove options that match defaults values before saving
2022-10-02 21:25:30 -04:00
IceBotYT 70010c0115 Fix LaCrosse View not updating (#79474) 2022-10-02 21:25:29 -04:00
David F. Mulcahey c32e4d34f6 Remove unnecessary config entity from ZHA (#79472) 2022-10-02 21:25:28 -04:00
J. Nick Koston f8f3d96a74 Bump dbus-fast to 1.20.0 (#79465) 2022-10-02 21:25:28 -04:00
zbeky 412ef9d126 Add EVOLVEO Heat M30v2 TRV (#79462) 2022-10-02 21:25:27 -04:00
Hung Nguyen 9bb75bb726 Skip parsing Flume sensors without location (#79456) 2022-10-02 21:25:26 -04:00
Allen Porter 321da50a7e Update nest climate to avoid duplicate set mode commands (#79445) 2022-10-02 21:25:26 -04:00
Erik Montnemery e410e298c4 Remove state_unit_of_measurement from metadata DB table (#79370)
* Remove state_unit_of_measurement from metadata DB table

* Adjust test
2022-10-02 21:25:25 -04:00
Nyro d41d09aa7e Fix overkiz entity name (#79229) 2022-10-02 21:25:24 -04:00
Paulus Schoutsen 590d47aad0 Bumped version to 2022.10.0b3 2022-10-01 21:28:46 -04:00
J. Nick Koston 6c7060e0e2 Bump ibeacon-ble to 0.7.3 (#79443) 2022-10-01 21:28:40 -04:00
J. Nick Koston 2fed773b93 Bump bluetooth-adapters to 0.5.3 (#79442) 2022-10-01 21:28:39 -04:00
J. Nick Koston 71e320fc96 Bump dbus-fast to 1.18.0 (#79440)
Changelog: https://github.com/Bluetooth-Devices/dbus-fast/compare/v1.17.0...v1.18.0
2022-10-01 21:28:39 -04:00
Tobias Sauerwein de90358f2a Fix Netatmo scope issue with HA cloud (#79437)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2022-10-01 21:28:38 -04:00
Michael 2703bbc630 Fix checking of upgrade API availability during setup of Synology DSM integration (#79435) 2022-10-01 21:28:37 -04:00
Matrix a3833a408b Fix mqtt reconnect fail when token expired (#79428)
* fix mqtt reconnect fail when token expired

* suggest change
2022-10-01 21:28:37 -04:00
Hans Oischinger 933b84050e vicare: Don't create unsupportedd button entites (#79425)
Button entities should only be offered when the datapoint exists on
the API.
2022-10-01 21:28:36 -04:00
Shay Levy 046c3b4dd1 Bump aiowebostv to 0.2.1 (#79423) 2022-10-01 21:28:35 -04:00
Mick Vleeshouwer 7e8905758b Fix low speed cover in Overkiz integration (#79416)
Fix low speed cover
2022-10-01 21:28:35 -04:00
Shay Levy 97f5670fdc Fix unifiprotect test failing CI (#79406) 2022-10-01 21:28:34 -04:00
Maciej Bieniek b3c43b981a Do not use AQI device class for CAQI sensor in Airly integration (#79402) 2022-10-01 21:28:33 -04:00
uvjustin ebb213eb14 Fix onvif snapshot fallback (#79394)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2022-10-01 21:28:33 -04:00
J. Nick Koston a0ba102492 Ensure bluetooth disconnect callback fires if esphome config entry is reloaded (#79389) 2022-10-01 21:28:32 -04:00
J. Nick Koston be036914a6 Improve robustness of linking homekit yaml to config entries (#79386) 2022-10-01 21:28:31 -04:00
G Johansson ecb934ee6a Fix _attr_name issue in Yale Smart Alarm (#79378)
Fix name issue
2022-10-01 21:28:31 -04:00
J. Nick Koston 783f514df3 Enable delete device support for iBeacon (#79339) 2022-10-01 21:28:30 -04:00
kingy444 2e2d8d1367 Powerview bump aiopvapi to 2.0.2 (#79274) 2022-10-01 21:28:29 -04:00
Allen Porter 1836dc4a3b Address Google Sheets PR feedback (#78889) 2022-10-01 21:28:29 -04:00
253 changed files with 3257 additions and 3195 deletions
+1 -1
View File
@@ -162,7 +162,7 @@ build.json @home-assistant/supervisor
/tests/components/brunt/ @eavanvalkenburg
/homeassistant/components/bsblan/ @liudger
/tests/components/bsblan/ @liudger
/homeassistant/components/bt_smarthub/ @jxwolstenholme
/homeassistant/components/bt_smarthub/ @typhoon2099
/homeassistant/components/bthome/ @Ernst79
/tests/components/bthome/ @Ernst79
/homeassistant/components/buienradar/ @mjj4791 @ties @Robbie1221
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "amazon",
"name": "Amazon",
"integrations": ["alexa", "amazon_polly", "aws", "route53"]
}
+4 -3
View File
@@ -2,10 +2,11 @@
"domain": "apple",
"name": "Apple",
"integrations": [
"icloud",
"ibeacon",
"apple_tv",
"homekit_controller",
"homekit",
"homekit_controller"
"ibeacon",
"icloud",
"itunes"
]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "aruba",
"name": "Aruba",
"integrations": ["aruba", "cppm_tracker"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "asterisk",
"name": "Asterisk",
"integrations": ["asterisk_cdr", "asterisk_mbox"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "august",
"name": "August Home",
"integrations": ["august", "yalexs_ble"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "cisco",
"name": "Cisco",
"integrations": ["cisco_ios", "cisco_mobility_express", "cisco_webex_teams"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "clicksend",
"name": "ClickSend",
"integrations": ["clicksend", "clicksend_tts"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "devolo",
"name": "devolo",
"integrations": ["devolo_home_control", "devolo_home_network"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "dlna",
"name": "DLNA",
"integrations": ["dlna_dmr", "dlna_dms"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "elgato",
"name": "Elgato",
"integrations": ["avea", "elgato"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "emoncms",
"name": "emoncms",
"integrations": ["emoncms", "emoncms_history"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "epson",
"name": "Epson",
"integrations": ["epson", "epsonworkforce"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "eq3",
"name": "eQ-3",
"integrations": ["eq3btsmart", "maxcube"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "ffmpeg",
"name": "FFmpeg",
"integrations": ["ffmpeg", "ffmpeg_motion", "ffmpeg_noise"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "geonet",
"name": "GeoNet",
"integrations": ["geonetnz_quakes", "geonetnz_volcano"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "globalcache",
"name": "Global Caché",
"integrations": ["gc100", "itach"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "hikvision",
"name": "Hikvision",
"integrations": ["hikvision", "hikvisioncam"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "homematic",
"name": "Homematic",
"integrations": ["homematic", "homematicip_cloud"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "honeywell",
"name": "Honeywell",
"integrations": ["lyric", "evohome", "honeywell"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "ibm",
"name": "IBM",
"integrations": ["watson_iot", "watson_tts"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "inovelli",
"name": "Inovelli",
"iot_standards": ["zigbee", "zwave"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "jasco",
"name": "Jasco",
"iot_standards": ["zwave"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "lg",
"name": "LG",
"integrations": ["lg_netcast", "lg_soundbar", "webostv"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "logitech",
"name": "Logitech",
"integrations": ["harmony", "ue_smart_radio", "squeezebox"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "lutron",
"name": "Lutron",
"integrations": ["lutron", "lutron_caseta", "homeworks"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "melnor",
"name": "Melnor",
"integrations": ["melnor", "raincloud"]
}
+16
View File
@@ -0,0 +1,16 @@
{
"domain": "microsoft",
"name": "Microsoft",
"integrations": [
"azure_devops",
"azure_event_hub",
"azure_service_bus",
"microsoft_face_detect",
"microsoft_face_identify",
"microsoft_face",
"microsoft",
"msteams",
"xbox",
"xbox_live"
]
}
+12
View File
@@ -0,0 +1,12 @@
{
"domain": "mqtt",
"name": "MQTT",
"integrations": [
"manual_mqtt",
"mqtt",
"mqtt_eventstream",
"mqtt_json",
"mqtt_room",
"mqtt_statestream"
]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "netgear",
"name": "NETGEAR",
"integrations": ["netgear", "netgear_lte"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "openwrt",
"name": "OpenWrt",
"integrations": ["luci", "ubus"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "panasonic",
"name": "Panasonic",
"integrations": ["panasonic_bluray", "panasonic_viera"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "philips",
"name": "Philips",
"integrations": ["dynalite", "hue", "philips_js"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "qnap",
"name": "QNAP",
"integrations": ["qnap", "qnap_qsw"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "raspberry_pi",
"name": "Raspberry Pi",
"integrations": ["rpi_camera", "rpi_power", "remote_rpi_gpio"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "russound",
"name": "Russound",
"integrations": ["russound_rio", "russound_rnet"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "samsung",
"name": "Samsung",
"integrations": ["familyhub", "samsungtv", "syncthru"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "solaredge",
"name": "SolarEdge",
"integrations": ["solaredge", "solaredge_local"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "sony",
"name": "Sony",
"integrations": ["braviatv", "ps4", "sony_projector", "songpal"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "synology",
"name": "Synology",
"integrations": ["synology_chat", "synology_dsm", "synology_srm"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "telegram",
"name": "Telegram",
"integrations": ["telegram", "telegram_bot"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "telldus",
"name": "Telldus",
"integrations": ["tellduslive", "tellstick"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "tesla",
"name": "Tesla",
"integrations": ["powerwall", "tesla_wall_connector"]
}
+9
View File
@@ -0,0 +1,9 @@
{
"domain": "trafikverket",
"name": "Trafikverket",
"integrations": [
"trafikverket_ferry",
"trafikverket_train",
"trafikverket_weatherstation"
]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "twilio",
"name": "Twilio",
"integrations": ["twilio", "twilio_call", "twilio_sms"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "u_tec",
"name": "U-tec",
"iot_standards": ["zwave"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "vlc",
"name": "VideoLAN",
"integrations": ["vlc", "vlc_telnet"]
}
+11
View File
@@ -0,0 +1,11 @@
{
"domain": "xiaomi",
"name": "Xiaomi",
"integrations": [
"xiaomi_aqara",
"xiaomi_ble",
"xiaomi_miio",
"xiaomi_tv",
"xiaomi"
]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "yale",
"name": "Yale",
"integrations": ["august", "yale_smart_alarm", "yalexs_ble"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "yandex",
"name": "Yandex",
"integrations": ["yandex_transport", "yandextts"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "yeelight",
"name": "Yeelight",
"integrations": ["yeelight", "yeelightsunflower"]
}
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "zooz",
"name": "Zooz",
"iot_standards": ["zwave"]
}
+1 -1
View File
@@ -68,7 +68,7 @@ class AirlySensorEntityDescription(SensorEntityDescription):
SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
AirlySensorEntityDescription(
key=ATTR_API_CAQI,
device_class=SensorDeviceClass.AQI,
icon="mdi:air-filter",
name=ATTR_API_CAQI,
native_unit_of_measurement="CAQI",
),
@@ -3,5 +3,6 @@
"name": "Alarm Control Panel",
"documentation": "https://www.home-assistant.io/integrations/alarm_control_panel",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
+3 -1
View File
@@ -819,7 +819,9 @@ def temperature_from_object(hass, temp_obj, interval=False):
# convert to Celsius if absolute temperature
temp -= 273.15
return TemperatureConverter.convert(temp, from_unit, to_unit, interval=interval)
if interval:
return TemperatureConverter.convert_interval(temp, from_unit, to_unit)
return TemperatureConverter.convert(temp, from_unit, to_unit)
@HANDLERS.register(("Alexa.ThermostatController", "SetTargetTemperature"))
+2 -1
View File
@@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/api",
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -5,5 +5,6 @@
"documentation": "https://www.home-assistant.io/integrations/application_credentials",
"dependencies": ["auth", "websocket_api"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
+2 -1
View File
@@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/auth",
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -5,5 +5,6 @@
"dependencies": ["blueprint", "trace"],
"after_dependencies": ["device_automation", "webhook"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -6,5 +6,6 @@
"codeowners": ["@home-assistant/core"],
"requirements": ["securetar==2022.2.0"],
"iot_class": "calculated",
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -3,5 +3,6 @@
"name": "Binary Sensor",
"documentation": "https://www.home-assistant.io/integrations/binary_sensor",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -3,5 +3,6 @@
"name": "Blueprint",
"documentation": "https://www.home-assistant.io/integrations/blueprint",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -55,7 +55,7 @@ from .models import (
HaBluetoothConnector,
ProcessAdvertisementCallback,
)
from .scanner import HaScanner, ScannerStartError, create_bleak_scanner
from .scanner import HaScanner, ScannerStartError
from .util import adapter_human_name, adapter_unique_name, async_default_adapter
if TYPE_CHECKING:
@@ -400,13 +400,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
passive = entry.options.get(CONF_PASSIVE)
mode = BluetoothScanningMode.PASSIVE if passive else BluetoothScanningMode.ACTIVE
scanner = HaScanner(hass, mode, adapter, address)
try:
bleak_scanner = create_bleak_scanner(mode, adapter)
scanner.async_setup()
except RuntimeError as err:
raise ConfigEntryNotReady(
f"{adapter_human_name(adapter, address)}: {err}"
) from err
scanner = HaScanner(hass, bleak_scanner, adapter, address)
info_callback = async_get_advertisement_callback(hass)
entry.async_on_unload(scanner.async_register_callback(info_callback))
try:
@@ -3,7 +3,6 @@ from __future__ import annotations
import asyncio
from collections.abc import Callable, Iterable
from dataclasses import asdict
from datetime import datetime, timedelta
import itertools
import logging
@@ -185,11 +184,11 @@ class BluetoothManager:
"adapters": self._adapters,
"scanners": scanner_diagnostics,
"connectable_history": [
asdict(service_info)
service_info.as_dict()
for service_info in self._connectable_history.values()
],
"history": [
asdict(service_info) for service_info in self._history.values()
service_info.as_dict() for service_info in self._history.values()
],
}
@@ -8,9 +8,9 @@
"requirements": [
"bleak==0.18.1",
"bleak-retry-connector==2.1.3",
"bluetooth-adapters==0.5.2",
"bluetooth-adapters==0.6.0",
"bluetooth-auto-recovery==0.3.3",
"dbus-fast==1.17.0"
"dbus-fast==1.24.0"
],
"codeowners": ["@bdraco"],
"config_flow": true,
@@ -53,6 +53,25 @@ class BluetoothServiceInfoBleak(BluetoothServiceInfo):
connectable: bool
time: float
def as_dict(self) -> dict[str, Any]:
"""Return as dict.
The dataclass asdict method is not used because
it will try to deepcopy pyobjc data which will fail.
"""
return {
"name": self.name,
"address": self.address,
"rssi": self.rssi,
"manufacturer_data": self.manufacturer_data,
"service_data": self.service_data,
"service_uuids": self.service_uuids,
"source": self.source,
"advertisement": self.advertisement,
"connectable": self.connectable,
"time": self.time,
}
class BluetoothScanningMode(Enum):
"""The mode of scanning for bluetooth devices."""
+17 -7
View File
@@ -16,7 +16,7 @@ from bleak.assigned_numbers import AdvertisementDataType
from bleak.backends.bluezdbus.advertisement_monitor import OrPattern
from bleak.backends.bluezdbus.scanner import BlueZScannerArgs
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from bleak.backends.scanner import AdvertisementData, AdvertisementDataCallback
from bleak_retry_connector import get_device_by_adapter
from dbus_fast import InvalidMessageError
@@ -86,11 +86,14 @@ class ScannerStartError(HomeAssistantError):
def create_bleak_scanner(
scanning_mode: BluetoothScanningMode, adapter: str | None
detection_callback: AdvertisementDataCallback,
scanning_mode: BluetoothScanningMode,
adapter: str | None,
) -> bleak.BleakScanner:
"""Create a Bleak scanner."""
scanner_kwargs: dict[str, Any] = {
"scanning_mode": SCANNING_MODE_TO_BLEAK[scanning_mode]
"detection_callback": detection_callback,
"scanning_mode": SCANNING_MODE_TO_BLEAK[scanning_mode],
}
if platform.system() == "Linux":
# Only Linux supports multiple adapters
@@ -117,16 +120,18 @@ class HaScanner(BaseHaScanner):
over ethernet, usb over ethernet, etc.
"""
scanner: bleak.BleakScanner
def __init__(
self,
hass: HomeAssistant,
scanner: bleak.BleakScanner,
mode: BluetoothScanningMode,
adapter: str,
address: str,
) -> None:
"""Init bluetooth discovery."""
self.hass = hass
self.scanner = scanner
self.mode = mode
self.adapter = adapter
self._start_stop_lock = asyncio.Lock()
self._cancel_watchdog: CALLBACK_TYPE | None = None
@@ -141,6 +146,13 @@ class HaScanner(BaseHaScanner):
"""Return a list of discovered devices."""
return self.scanner.discovered_devices
@hass_callback
def async_setup(self) -> None:
"""Set up the scanner."""
self.scanner = create_bleak_scanner(
self._async_detection_callback, self.mode, self.adapter
)
async def async_get_device_by_address(self, address: str) -> BLEDevice | None:
"""Get a device by address."""
if platform.system() == "Linux":
@@ -218,8 +230,6 @@ class HaScanner(BaseHaScanner):
async def async_start(self) -> None:
"""Start bluetooth scanner."""
self.scanner.register_detection_callback(self._async_detection_callback)
async with self._start_stop_lock:
await self._async_start()
@@ -2,8 +2,8 @@
"domain": "bt_smarthub",
"name": "BT Smart Hub",
"documentation": "https://www.home-assistant.io/integrations/bt_smarthub",
"requirements": ["btsmarthub_devicelist==0.2.2"],
"codeowners": ["@jxwolstenholme"],
"requirements": ["btsmarthub_devicelist==0.2.3"],
"codeowners": ["@typhoon2099"],
"iot_class": "local_polling",
"loggers": ["btsmarthub_devicelist"]
}
@@ -3,5 +3,6 @@
"name": "Button",
"documentation": "https://www.home-assistant.io/integrations/button",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/calendar",
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -6,5 +6,6 @@
"requirements": ["PyTurboJPEG==1.6.7"],
"after_dependencies": ["media_player"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -3,5 +3,6 @@
"name": "Climate",
"documentation": "https://www.home-assistant.io/integrations/climate",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/config",
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -3,5 +3,6 @@
"name": "Configurator",
"documentation": "https://www.home-assistant.io/integrations/configurator",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -5,5 +5,6 @@
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal",
"iot_class": "local_push"
"iot_class": "local_push",
"integration_type": "system"
}
+2 -1
View File
@@ -3,5 +3,6 @@
"name": "Cover",
"documentation": "https://www.home-assistant.io/integrations/cover",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -41,5 +41,6 @@
"zone"
],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -295,7 +295,6 @@ async def _insert_statistics(hass: HomeAssistant) -> None:
metadata: StatisticMetaData = {
"source": DOMAIN,
"name": "Outdoor temperature",
"state_unit_of_measurement": TEMP_CELSIUS,
"statistic_id": f"{DOMAIN}:temperature_outdoor",
"unit_of_measurement": TEMP_CELSIUS,
"has_mean": True,
@@ -309,7 +308,6 @@ async def _insert_statistics(hass: HomeAssistant) -> None:
metadata = {
"source": DOMAIN,
"name": "Energy consumption 1",
"state_unit_of_measurement": ENERGY_KILO_WATT_HOUR,
"statistic_id": f"{DOMAIN}:energy_consumption_kwh",
"unit_of_measurement": ENERGY_KILO_WATT_HOUR,
"has_mean": False,
@@ -322,7 +320,6 @@ async def _insert_statistics(hass: HomeAssistant) -> None:
metadata = {
"source": DOMAIN,
"name": "Energy consumption 2",
"state_unit_of_measurement": ENERGY_MEGA_WATT_HOUR,
"statistic_id": f"{DOMAIN}:energy_consumption_mwh",
"unit_of_measurement": ENERGY_MEGA_WATT_HOUR,
"has_mean": False,
@@ -337,7 +334,6 @@ async def _insert_statistics(hass: HomeAssistant) -> None:
metadata = {
"source": DOMAIN,
"name": "Gas consumption 1",
"state_unit_of_measurement": VOLUME_CUBIC_METERS,
"statistic_id": f"{DOMAIN}:gas_consumption_m3",
"unit_of_measurement": VOLUME_CUBIC_METERS,
"has_mean": False,
@@ -352,7 +348,6 @@ async def _insert_statistics(hass: HomeAssistant) -> None:
metadata = {
"source": DOMAIN,
"name": "Gas consumption 2",
"state_unit_of_measurement": VOLUME_CUBIC_FEET,
"statistic_id": f"{DOMAIN}:gas_consumption_ft3",
"unit_of_measurement": VOLUME_CUBIC_FEET,
"has_mean": False,
@@ -7,6 +7,7 @@ import voluptuous as vol
from homeassistant.const import CONF_DOMAIN
from homeassistant.core import Context, HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.typing import ConfigType
from . import DeviceAutomationType, async_get_device_automation_platform
@@ -51,14 +52,15 @@ async def async_validate_action_config(
) -> ConfigType:
"""Validate config."""
try:
config = cv.DEVICE_ACTION_SCHEMA(config)
platform = await async_get_device_automation_platform(
hass, config[CONF_DOMAIN], DeviceAutomationType.ACTION
)
if hasattr(platform, "async_validate_action_config"):
return await platform.async_validate_action_config(hass, config)
return cast(ConfigType, platform.ACTION_SCHEMA(config))
except InvalidDeviceAutomationConfig as err:
raise vol.Invalid(str(err) or "Invalid action configuration") from err
except (vol.Invalid, InvalidDeviceAutomationConfig) as err:
raise vol.Invalid("invalid action configuration: " + str(err)) from err
async def async_call_action_from_config(
@@ -58,8 +58,8 @@ async def async_validate_condition_config(
if hasattr(platform, "async_validate_condition_config"):
return await platform.async_validate_condition_config(hass, config)
return cast(ConfigType, platform.CONDITION_SCHEMA(config))
except InvalidDeviceAutomationConfig as err:
raise vol.Invalid(str(err) or "Invalid condition configuration") from err
except (vol.Invalid, InvalidDeviceAutomationConfig) as err:
raise vol.Invalid("invalid condition configuration: " + str(err)) from err
async def async_condition_from_config(
@@ -3,5 +3,6 @@
"name": "Device Automation",
"documentation": "https://www.home-assistant.io/integrations/device_automation",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -58,14 +58,15 @@ async def async_validate_trigger_config(
) -> ConfigType:
"""Validate config."""
try:
config = TRIGGER_SCHEMA(config)
platform = await async_get_device_automation_platform(
hass, config[CONF_DOMAIN], DeviceAutomationType.TRIGGER
)
if not hasattr(platform, "async_validate_trigger_config"):
return cast(ConfigType, platform.TRIGGER_SCHEMA(config))
return await platform.async_validate_trigger_config(hass, config)
except InvalidDeviceAutomationConfig as err:
raise vol.Invalid(str(err) or "Invalid trigger configuration") from err
except (vol.Invalid, InvalidDeviceAutomationConfig) as err:
raise InvalidDeviceAutomationConfig("invalid trigger configuration") from err
async def async_attach_trigger(
@@ -5,5 +5,6 @@
"dependencies": ["zone"],
"after_dependencies": [],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
+2 -1
View File
@@ -6,5 +6,6 @@
"codeowners": ["@bdraco"],
"quality_scale": "internal",
"iot_class": "local_push",
"loggers": ["aiodiscover", "dnspython", "pyroute2", "scapy"]
"loggers": ["aiodiscover", "dnspython", "pyroute2", "scapy"],
"integration_type": "system"
}
@@ -5,5 +5,6 @@
"documentation": "https://www.home-assistant.io/integrations/diagnostics",
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -6,5 +6,6 @@
"after_dependencies": ["zeroconf"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal",
"loggers": ["netdisco"]
"loggers": ["netdisco"],
"integration_type": "system"
}
@@ -5,5 +5,6 @@
"codeowners": ["@home-assistant/core"],
"iot_class": "calculated",
"dependencies": ["websocket_api", "history", "recorder"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -13,6 +13,7 @@ from typing import Any, cast
import voluptuous as vol
from homeassistant.components import recorder, websocket_api
from homeassistant.const import ENERGY_KILO_WATT_HOUR
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.integration_platform import (
async_process_integration_platforms,
@@ -268,6 +269,7 @@ async def ws_get_fossil_energy_consumption(
statistic_ids,
"hour",
True,
{"energy": ENERGY_KILO_WATT_HOUR},
)
def _combine_sum_statistics(
@@ -15,10 +15,9 @@ from bleak.backends.device import BLEDevice
from bleak.backends.service import BleakGATTServiceCollection
from bleak.exc import BleakError
from homeassistant.core import CALLBACK_TYPE, async_get_hass, callback as hass_callback
from homeassistant.core import CALLBACK_TYPE, async_get_hass
from ..domain_data import DomainData
from ..entry_data import RuntimeEntryData
from .characteristic import BleakGATTCharacteristicESPHome
from .descriptor import BleakGATTDescriptorESPHome
from .service import BleakGATTServiceESPHome
@@ -85,7 +84,9 @@ class ESPHomeClient(BaseBleakClient):
assert self._ble_device.details is not None
self._source = self._ble_device.details["source"]
self.domain_data = DomainData.get(async_get_hass())
self._client = self._async_get_entry_data().client
config_entry = self.domain_data.get_by_unique_id(self._source)
self.entry_data = self.domain_data.get_entry_data(config_entry)
self._client = self.entry_data.client
self._is_connected = False
self._mtu: int | None = None
self._cancel_connection_state: CALLBACK_TYPE | None = None
@@ -108,12 +109,6 @@ class ESPHomeClient(BaseBleakClient):
)
self._cancel_connection_state = None
@hass_callback
def _async_get_entry_data(self) -> RuntimeEntryData:
"""Get the entry data."""
config_entry = self.domain_data.get_by_unique_id(self._source)
return self.domain_data.get_entry_data(config_entry)
def _async_ble_device_disconnected(self) -> None:
"""Handle the BLE device disconnecting from the ESP."""
_LOGGER.debug("%s: BLE device disconnected", self._source)
@@ -125,8 +120,7 @@ class ESPHomeClient(BaseBleakClient):
def _async_esp_disconnected(self) -> None:
"""Handle the esp32 client disconnecting from hass."""
_LOGGER.debug("%s: ESP device disconnected", self._source)
entry_data = self._async_get_entry_data()
entry_data.disconnect_callbacks.remove(self._async_esp_disconnected)
self.entry_data.disconnect_callbacks.remove(self._async_esp_disconnected)
self._async_ble_device_disconnected()
def _async_call_bleak_disconnected_callback(self) -> None:
@@ -179,8 +173,7 @@ class ESPHomeClient(BaseBleakClient):
connected_future.set_exception(BleakError("Disconnected"))
return
entry_data = self._async_get_entry_data()
entry_data.disconnect_callbacks.append(self._async_esp_disconnected)
self.entry_data.disconnect_callbacks.append(self._async_esp_disconnected)
connected_future.set_result(connected)
timeout = kwargs.get("timeout", self._timeout)
@@ -203,14 +196,13 @@ class ESPHomeClient(BaseBleakClient):
async def _wait_for_free_connection_slot(self, timeout: float) -> None:
"""Wait for a free connection slot."""
entry_data = self._async_get_entry_data()
if entry_data.ble_connections_free:
if self.entry_data.ble_connections_free:
return
_LOGGER.debug(
"%s: Out of connection slots, waiting for a free one", self._source
)
async with async_timeout.timeout(timeout):
await entry_data.wait_for_ble_connections_free()
await self.entry_data.wait_for_ble_connections_free()
@property
def is_connected(self) -> bool:
@@ -3,7 +3,7 @@
"name": "ESPHome",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/esphome",
"requirements": ["aioesphomeapi==11.0.0"],
"requirements": ["aioesphomeapi==11.1.0"],
"zeroconf": ["_esphomelib._tcp.local."],
"dhcp": [{ "registered_devices": true }],
"codeowners": ["@OttoWinter", "@jesserockz"],
+2 -1
View File
@@ -3,5 +3,6 @@
"name": "Fan",
"documentation": "https://www.home-assistant.io/integrations/fan",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -4,5 +4,6 @@
"documentation": "https://www.home-assistant.io/integrations/file_upload",
"dependencies": ["http"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
+4 -1
View File
@@ -40,7 +40,10 @@ async def async_setup_entry(
flume_entity_list = []
for device in flume_devices.device_list:
if device[KEY_DEVICE_TYPE] != FLUME_TYPE_SENSOR:
if (
device[KEY_DEVICE_TYPE] != FLUME_TYPE_SENSOR
or KEY_DEVICE_LOCATION not in device
):
continue
device_id = device[KEY_DEVICE_ID]
@@ -2,7 +2,7 @@
"domain": "frontend",
"name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": ["home-assistant-frontend==20220929.0"],
"requirements": ["home-assistant-frontend==20221006.0"],
"dependencies": [
"api",
"auth",
@@ -19,5 +19,6 @@
"websocket_api"
],
"codeowners": ["@home-assistant/frontend"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}
@@ -3,5 +3,6 @@
"name": "Geolocation",
"documentation": "https://www.home-assistant.io/integrations/geo_location",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "entity"
}
@@ -2,7 +2,6 @@
from __future__ import annotations
from datetime import datetime
from typing import cast
import aiohttp
from google.auth.exceptions import RefreshError
@@ -105,12 +104,13 @@ async def async_setup_service(hass: HomeAssistant) -> None:
async def append_to_sheet(call: ServiceCall) -> None:
"""Append new line of data to a Google Sheets document."""
entry = cast(
ConfigEntry,
hass.config_entries.async_get_entry(call.data[DATA_CONFIG_ENTRY]),
entry: ConfigEntry | None = hass.config_entries.async_get_entry(
call.data[DATA_CONFIG_ENTRY]
)
session: OAuth2Session = hass.data[DOMAIN][entry.entry_id]
if not entry:
raise ValueError(f"Invalid config entry: {call.data[DATA_CONFIG_ENTRY]}")
if not (session := hass.data[DOMAIN].get(entry.entry_id)):
raise ValueError(f"Config entry not loaded: {call.data[DATA_CONFIG_ENTRY]}")
await session.async_ensure_token_valid()
await hass.async_add_executor_job(_append_to_sheet, call, entry)
@@ -8,7 +8,7 @@ from typing import Any
from google.oauth2.credentials import Credentials
from gspread import Client, GSpreadException
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_TOKEN
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import config_entry_oauth2_flow
@@ -25,6 +25,8 @@ class OAuth2FlowHandler(
DOMAIN = DOMAIN
reauth_entry: ConfigEntry | None = None
@property
def logger(self) -> logging.Logger:
"""Return logger."""
@@ -42,6 +44,9 @@ class OAuth2FlowHandler(
async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult:
"""Perform reauth upon an API authentication error."""
self.reauth_entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
)
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
@@ -52,40 +57,27 @@ class OAuth2FlowHandler(
return self.async_show_form(step_id="reauth_confirm")
return await self.async_step_user()
def _async_reauth_entry(self) -> ConfigEntry | None:
"""Return existing entry for reauth."""
if self.source != SOURCE_REAUTH or not (
entry_id := self.context.get("entry_id")
):
return None
return next(
(
entry
for entry in self._async_current_entries()
if entry.entry_id == entry_id
),
None,
)
async def async_oauth_create_entry(self, data: dict[str, Any]) -> FlowResult:
"""Create an entry for the flow, or update existing entry."""
service = Client(Credentials(data[CONF_TOKEN][CONF_ACCESS_TOKEN]))
if entry := self._async_reauth_entry():
if self.reauth_entry:
_LOGGER.debug("service.open_by_key")
try:
await self.hass.async_add_executor_job(
service.open_by_key,
entry.unique_id,
self.reauth_entry.unique_id,
)
except GSpreadException as err:
_LOGGER.error(
"Could not find spreadsheet '%s': %s", entry.unique_id, str(err)
"Could not find spreadsheet '%s': %s",
self.reauth_entry.unique_id,
str(err),
)
return self.async_abort(reason="open_spreadsheet_failure")
self.hass.config_entries.async_update_entry(entry, data=data)
await self.hass.config_entries.async_reload(entry.entry_id)
self.hass.config_entries.async_update_entry(self.reauth_entry, data=data)
await self.hass.config_entries.async_reload(self.reauth_entry.entry_id)
return self.async_abort(reason="reauth_successful")
try:
@@ -97,6 +89,7 @@ class OAuth2FlowHandler(
return self.async_abort(reason="create_spreadsheet_failure")
await self.async_set_unique_id(doc.id)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=DEFAULT_NAME, data=data, description_placeholders={"url": doc.url}
)
@@ -10,6 +10,10 @@
},
"auth": {
"title": "Link Google Account"
},
"reauth_confirm": {
"title": "[%key:common::config_flow::title::reauth%]",
"description": "The Google Sheets integration needs to re-authenticate your account"
}
},
"abort": {
@@ -5,5 +5,6 @@
"documentation": "https://www.home-assistant.io/integrations/hardware",
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal",
"requirements": ["psutil-home-assistant==0.0.1"]
"requirements": ["psutil-home-assistant==0.0.1"],
"integration_type": "system"
}
@@ -6,5 +6,6 @@
"after_dependencies": ["panel_custom"],
"codeowners": ["@home-assistant/supervisor"],
"iot_class": "local_polling",
"quality_scale": "internal"
"quality_scale": "internal",
"integration_type": "system"
}

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