mirror of
https://github.com/home-assistant/core.git
synced 2025-12-15 04:18:53 +00:00
Compare commits
99 Commits
input_bool
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b41bb09a7 | ||
|
|
e58fc6976d | ||
|
|
9def627a57 | ||
|
|
9b56759c1e | ||
|
|
c3f743cafd | ||
|
|
160c495ddc | ||
|
|
9a1cd8545d | ||
|
|
fa81e6cd04 | ||
|
|
746f4ef1e2 | ||
|
|
0149de6ba6 | ||
|
|
1df2f18e0a | ||
|
|
5800824893 | ||
|
|
aac07b6b4b | ||
|
|
2448ce1970 | ||
|
|
7b40e3b8a7 | ||
|
|
29d06cfcc9 | ||
|
|
365d168ddd | ||
|
|
234191336e | ||
|
|
ba57b72658 | ||
|
|
bb08b315b8 | ||
|
|
50621df244 | ||
|
|
2db7b5c99f | ||
|
|
78af3acf35 | ||
|
|
b72f04d44e | ||
|
|
35f287e330 | ||
|
|
0a55f83b46 | ||
|
|
5030d0ba90 | ||
|
|
f582f06ee4 | ||
|
|
662bada5d8 | ||
|
|
3ca338dd25 | ||
|
|
9337a0e71b | ||
|
|
ccbb00197d | ||
|
|
0f59c17e61 | ||
|
|
6253ade3e2 | ||
|
|
e5890378a1 | ||
|
|
b8ab0bcadf | ||
|
|
19cb827577 | ||
|
|
03676d7e5a | ||
|
|
13f3b49b96 | ||
|
|
90c8c56a06 | ||
|
|
afb9e18a7d | ||
|
|
2c2934065f | ||
|
|
0bead67df9 | ||
|
|
2895849203 | ||
|
|
b2400708ac | ||
|
|
0bed9c20b3 | ||
|
|
d3fb7a7b87 | ||
|
|
60dcca4143 | ||
|
|
01f498f239 | ||
|
|
15055b8e8e | ||
|
|
6826619e12 | ||
|
|
b50a8e04a8 | ||
|
|
c6c67c5357 | ||
|
|
c82803d1e2 | ||
|
|
732b30f181 | ||
|
|
0e2e57a657 | ||
|
|
f00b0080a9 | ||
|
|
ad970c1234 | ||
|
|
02ec56bffa | ||
|
|
8388c290bf | ||
|
|
576ee99faf | ||
|
|
8a3534c345 | ||
|
|
e1e91c5568 | ||
|
|
1e09bddb1d | ||
|
|
90e4340595 | ||
|
|
120b17349c | ||
|
|
8a26961304 | ||
|
|
407b675080 | ||
|
|
274844271b | ||
|
|
f11e4e7bda | ||
|
|
96f8c39c6f | ||
|
|
77b79fef8d | ||
|
|
a0d2f285f3 | ||
|
|
3aef05d1ec | ||
|
|
510e391ee4 | ||
|
|
54adfdd694 | ||
|
|
d45f920b4a | ||
|
|
3080ef9a4a | ||
|
|
51cebb52f3 | ||
|
|
7b0d4c47b7 | ||
|
|
a660ab3f97 | ||
|
|
dd8fc16788 | ||
|
|
2b0fab0468 | ||
|
|
3bb88ed433 | ||
|
|
984385cd98 | ||
|
|
09de108676 | ||
|
|
ebc7581718 | ||
|
|
e55162812d | ||
|
|
aa6ccaa024 | ||
|
|
e1b009a6de | ||
|
|
91ddc525b0 | ||
|
|
d7d7954ac2 | ||
|
|
e87c260df7 | ||
|
|
5185c6cd68 | ||
|
|
7599c918e2 | ||
|
|
fa7e22ec91 | ||
|
|
606519e51b | ||
|
|
8e39e010f7 | ||
|
|
dc01cf49a0 |
8
CODEOWNERS
generated
8
CODEOWNERS
generated
@@ -220,8 +220,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/bizkaibus/ @UgaitzEtxebarria
|
||||
/homeassistant/components/blebox/ @bbx-a @swistakm
|
||||
/tests/components/blebox/ @bbx-a @swistakm
|
||||
/homeassistant/components/blink/ @fronzbot @mkmer
|
||||
/tests/components/blink/ @fronzbot @mkmer
|
||||
/homeassistant/components/blink/ @fronzbot
|
||||
/tests/components/blink/ @fronzbot
|
||||
/homeassistant/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
|
||||
/tests/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
|
||||
/homeassistant/components/bluemaestro/ @bdraco
|
||||
@@ -308,8 +308,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/config/ @home-assistant/core
|
||||
/homeassistant/components/configurator/ @home-assistant/core
|
||||
/tests/components/configurator/ @home-assistant/core
|
||||
/homeassistant/components/control4/ @lawtancool
|
||||
/tests/components/control4/ @lawtancool
|
||||
/homeassistant/components/control4/ @lawtancool @davidrecordon
|
||||
/tests/components/control4/ @lawtancool @davidrecordon
|
||||
/homeassistant/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
|
||||
/tests/components/conversation/ @home-assistant/core @synesthesiam @arturpragacz
|
||||
/homeassistant/components/cookidoo/ @miaucl
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@Bre77"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/advantage_air",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["advantage_air"],
|
||||
"requirements": ["advantage-air==0.4.4"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@Noltari"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/aemet",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aemet_opendata"],
|
||||
"requirements": ["AEMET-OpenData==0.6.4"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": [],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/aftership",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["pyaftership==21.11.0"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@ispysoftware"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/agent_dvr",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["agent"],
|
||||
"requirements": ["agent-py==0.0.24"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@asymworks"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/airnow",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyairnow"],
|
||||
"requirements": ["pyairnow==1.3.1"]
|
||||
|
||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from pyairobotrest.models import ThermostatStatus
|
||||
|
||||
@@ -23,6 +24,8 @@ from homeassistant.const import (
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.util.dt import utcnow
|
||||
from homeassistant.util.variance import ignore_variance
|
||||
|
||||
from . import AirobotConfigEntry
|
||||
from .entity import AirobotEntity
|
||||
@@ -34,10 +37,15 @@ PARALLEL_UPDATES = 0
|
||||
class AirobotSensorEntityDescription(SensorEntityDescription):
|
||||
"""Describes Airobot sensor entity."""
|
||||
|
||||
value_fn: Callable[[ThermostatStatus], StateType]
|
||||
value_fn: Callable[[ThermostatStatus], StateType | datetime]
|
||||
supported_fn: Callable[[ThermostatStatus], bool] = lambda _: True
|
||||
|
||||
|
||||
uptime_to_stable_datetime = ignore_variance(
|
||||
lambda value: utcnow().replace(microsecond=0) - timedelta(seconds=value),
|
||||
timedelta(minutes=2),
|
||||
)
|
||||
|
||||
SENSOR_TYPES: tuple[AirobotSensorEntityDescription, ...] = (
|
||||
AirobotSensorEntityDescription(
|
||||
key="air_temperature",
|
||||
@@ -96,6 +104,14 @@ SENSOR_TYPES: tuple[AirobotSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda status: status.errors,
|
||||
),
|
||||
AirobotSensorEntityDescription(
|
||||
key="device_uptime",
|
||||
translation_key="device_uptime",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda status: uptime_to_stable_datetime(status.device_uptime),
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -129,6 +145,6 @@ class AirobotSensor(AirobotEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{coordinator.data.status.device_id}_{description.key}"
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
def native_value(self) -> StateType | datetime:
|
||||
"""Return the state of the sensor."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.status)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/airthings",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["airthings"],
|
||||
"requirements": ["airthings-cloud==0.2.0"]
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["airthings-ble==1.2.0"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@samsinnamon"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/airtouch4",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["airtouch4pyapi"],
|
||||
"requirements": ["airtouch4pyapi==1.0.5"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@danzel"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/airtouch5",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["airtouch5py"],
|
||||
"requirements": ["airtouch5py==0.3.0"]
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/airzone",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["aioairzone"],
|
||||
"requirements": ["aioairzone==1.0.4"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@Noltari"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/airzone_cloud",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["aioairzone_cloud"],
|
||||
"requirements": ["aioairzone-cloud==0.7.2"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@madpilot"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/amberelectric",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["amberelectric"],
|
||||
"requirements": ["amberelectric==2.0.12"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@engrbm87"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/android_ip_webcam",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["pydroid-ipcam==3.0.0"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@pantherale0"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/anglian_water",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyanglianwater"],
|
||||
"quality_scale": "bronze",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@Lash-L"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/anova",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["anova_wifi"],
|
||||
"requirements": ["anova-wifi==0.17.0"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@hyralex"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/anthemav",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["anthemav"],
|
||||
"requirements": ["anthemav==1.4.1"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@bdr99"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/aosmith",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["py-aosmith==1.0.15"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@elupus"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/arcam_fmj",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["arcam"],
|
||||
"requirements": ["arcam-fmj==1.8.2"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@ikalnyi"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/arve",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["asyncarve==0.1.1"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@milanmeu"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/aseko_pool_live",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aioaseko"],
|
||||
"requirements": ["aioaseko==1.0.0"]
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["aioasuswrt", "asusrouter", "asyncssh"],
|
||||
"requirements": ["aioasuswrt==1.5.2", "asusrouter==1.21.3"]
|
||||
"requirements": ["aioasuswrt==1.5.4", "asusrouter==1.21.3"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@MatsNL"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/atag",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pyatag"],
|
||||
"requirements": ["pyatag==0.3.5.3"]
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/august",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["pubnub", "yalexs"],
|
||||
"requirements": ["yalexs==9.2.0", "yalexs-ble==3.2.2"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@djtimca"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/aurora",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["auroranoaa"],
|
||||
"requirements": ["auroranoaa==0.0.5"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@nickw444", "@Bre77"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/aussie_broadband",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aussiebb"],
|
||||
"requirements": ["pyaussiebb==0.1.5"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@kaareseras"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/azure_data_explorer",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["azure"],
|
||||
"requirements": ["azure-kusto-ingest==4.5.1", "azure-kusto-data[aio]==4.5.1"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@timmo001"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/azure_devops",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aioazuredevops"],
|
||||
"requirements": ["aioazuredevops==2.2.2"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@eavanvalkenburg"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/azure_event_hub",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["azure"],
|
||||
"requirements": ["azure-eventhub==5.11.1"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@bdraco", "@jfroy"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/baf",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"requirements": ["aiobafi6==0.9.0"],
|
||||
"zeroconf": [
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/balboa",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pybalboa"],
|
||||
"requirements": ["pybalboa==1.1.3"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@bbx-a", "@swistakm"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/blebox",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["blebox_uniapi"],
|
||||
"requirements": ["blebox-uniapi==2.5.0"],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "blink",
|
||||
"name": "Blink",
|
||||
"codeowners": ["@fronzbot", "@mkmer"],
|
||||
"codeowners": ["@fronzbot"],
|
||||
"config_flow": true,
|
||||
"dhcp": [
|
||||
{
|
||||
@@ -18,7 +18,8 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/blink",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["blinkpy"],
|
||||
"requirements": ["blinkpy==0.25.1"]
|
||||
"requirements": ["blinkpy==0.25.2"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@gleeuwen", "@NickKoepr", "@jtodorova23"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/blue_current",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["bluecurrent_api"],
|
||||
"requirements": ["bluecurrent-api==1.3.2"]
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/bluemaestro",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"requirements": ["bluemaestro-ble==0.4.1"]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"codeowners": ["@thrawnarn", "@LouisChrist"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/bluesound",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["pyblu==2.0.5"],
|
||||
"zeroconf": [
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@gerard33", "@rikroe"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["bimmer_connected"],
|
||||
"requirements": ["bimmer-connected[china]==0.17.3"]
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/bond",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["bond_async"],
|
||||
"requirements": ["bond-async==0.2.1"],
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"codeowners": ["@tschamm"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/bosch_shc",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["boschshcpy"],
|
||||
"requirements": ["boschshcpy==0.2.107"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@gjohansson-ST"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/brottsplatskartan",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["brottsplatskartan"],
|
||||
"requirements": ["brottsplatskartan==1.0.5"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@eavanvalkenburg"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/brunt",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["brunt"],
|
||||
"requirements": ["brunt==1.2.0"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@mjj4791", "@ties", "@Robbie1221"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/buienradar",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["buienradar", "vincenty"],
|
||||
"requirements": ["buienradar==1.0.6"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": [],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/caldav",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["caldav", "vobject"],
|
||||
"requirements": ["caldav==2.1.0", "icalendar==6.3.1", "vobject==0.9.9"]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["ffmpeg"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/canary",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["canary"],
|
||||
"requirements": ["py-canary==0.5.4"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@ocalvo"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/ccm15",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["py_ccm15==0.1.2"]
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
"codeowners": ["@jjlawren"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/cert_expiry",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@ludeeus", "@ctalkington"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/cloudflare",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["pycfdns"],
|
||||
"requirements": ["pycfdns==3.0.0"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@tombrien"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/coinbase",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["coinbase"],
|
||||
"requirements": ["coinbase-advanced-py==1.2.2"]
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"domain": "control4",
|
||||
"name": "Control4",
|
||||
"codeowners": ["@lawtancool"],
|
||||
"codeowners": ["@lawtancool", "@davidrecordon"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/control4",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pyControl4"],
|
||||
"requirements": ["pyControl4==1.5.0"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@fredrike"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/daikin",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pydaikin"],
|
||||
"requirements": ["pydaikin==2.17.1"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": [],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/datadog",
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["datadog"],
|
||||
"quality_scale": "legacy",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@gagebenne"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/dexcom",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pydexcom"],
|
||||
"requirements": ["pydexcom==0.2.3"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@gjohansson-ST"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/dnsip",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["aiodns==3.6.0"]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["http", "repairs"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/doorbird",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["doorbirdpy"],
|
||||
"requirements": ["DoorBirdPy==3.0.11"],
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["mqtt"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/drop_connect",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"mqtt": ["drop_connect/discovery/#"],
|
||||
"requirements": ["dropmqttapi==1.0.3"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@sarahseidman"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/droplet",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["pydroplet==2.3.4"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": [],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/dunehd",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pdunehd"],
|
||||
"requirements": ["pdunehd==1.3.2"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@cereal2nd"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/duotecno",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pyduotecno", "pyduotecno-node", "pyduotecno-unit"],
|
||||
"requirements": ["pyDuotecno==2024.10.1"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@Jc2k"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/eafm",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aioeafm"],
|
||||
"requirements": ["aioeafm==0.1.2"]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"homekit": {
|
||||
"models": ["EB", "ecobee*"]
|
||||
},
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyecobee"],
|
||||
"requirements": ["python-ecobee-api==0.3.2"],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@pjanuario"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/ecoforest",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pyecoforest"],
|
||||
"requirements": ["pyecoforest==0.4.0"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@w1ll1am23"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/econet",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["paho_mqtt", "pyeconet"],
|
||||
"requirements": ["pyeconet==0.1.28"]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["application_credentials", "http"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/ekeybionyx",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["ekey-bionyxpy==1.0.0"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@jafar-atili"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/electrasmart",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["pyElectra==1.2.4"]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["recorder"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/elvia",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["elvia==0.1.0"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@gwww", "@michaeldavie"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["env_canada"],
|
||||
"requirements": ["env-canada==0.12.1"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@erwindouna"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/firefly_iii",
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_polling",
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["pyfirefly==0.1.8"]
|
||||
|
||||
@@ -42,11 +42,11 @@
|
||||
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
|
||||
},
|
||||
"data_description": {
|
||||
"api_key": "The API key for authenticating with Firefly",
|
||||
"api_key": "The API key for authenticating with Firefly III",
|
||||
"url": "[%key:common::config_flow::data::url%]",
|
||||
"verify_ssl": "Verify the SSL certificate of the Firefly instance"
|
||||
"verify_ssl": "Verify the SSL certificate of the Firefly III instance"
|
||||
},
|
||||
"description": "You can create an API key in the Firefly UI. Go to **Options > Profile** and select the **OAuth** tab. Create a new personal access token and copy it (it will only display once)."
|
||||
"description": "You can create an API key in the Firefly III UI. Go to **Options > Profile** and select the **OAuth** tab. Create a new personal access token and copy it (it will only display once)."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -84,13 +84,13 @@
|
||||
},
|
||||
"exceptions": {
|
||||
"cannot_connect": {
|
||||
"message": "An error occurred while trying to connect to the Firefly instance: {error}"
|
||||
"message": "An error occurred while trying to connect to the Firefly III instance: {error}"
|
||||
},
|
||||
"invalid_auth": {
|
||||
"message": "An error occurred while trying to authenticate: {error}"
|
||||
},
|
||||
"timeout_connect": {
|
||||
"message": "A timeout occurred while trying to connect to the Firefly instance: {error}"
|
||||
"message": "A timeout occurred while trying to connect to the Firefly III instance: {error}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["application_credentials", "http"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/fitbit",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["fitbit", "fitbit_web_api"],
|
||||
"requirements": ["fitbit==0.3.1", "fitbit-web-api==2.13.5"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@stefano055415"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/freedompro",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyfreedompro"],
|
||||
"requirements": ["pyfreedompro==1.1.0"]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pyfritzhome"],
|
||||
"requirements": ["pyfritzhome==0.6.17"],
|
||||
"requirements": ["pyfritzhome==0.6.18"],
|
||||
"ssdp": [
|
||||
{
|
||||
"st": "urn:schemas-upnp-org:device:fritzbox:1"
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
"codeowners": ["@wlcrs"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/frontier_silicon",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["afsapi==0.2.7"],
|
||||
"ssdp": [{ "st": "urn:schemas-frontier-silicon-com:undok:fsapi:1" }]
|
||||
"ssdp": [
|
||||
{
|
||||
"st": "urn:schemas-frontier-silicon-com:undok:fsapi:1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@crevetor"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/fujitsu_fglair",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["ayla-iot-unofficial==1.4.7"]
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/fully_kiosk",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"mqtt": ["fully/deviceInfo/+"],
|
||||
"quality_scale": "bronze",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@klaasnicolaas"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/garages_amsterdam",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["odp-amsterdam==6.1.2"]
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/gardena_bluetooth",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["bleak", "bleak_esphome", "gardena_bluetooth"],
|
||||
"requirements": ["gardena-bluetooth==1.6.0"]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["application_credentials"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/geocaching",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["geocachingapi==0.3.0"]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@timmo001", "@ludeeus"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/github",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aiogithubapi"],
|
||||
"requirements": ["aiogithubapi==24.6.0"]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"codeowners": ["@engrbm87"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/glances",
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["glances_api"],
|
||||
"requirements": ["glances-api==0.8.0"]
|
||||
|
||||
@@ -908,12 +908,21 @@ class StartStopTrait(_Trait):
|
||||
}
|
||||
|
||||
if domain in COVER_VALVE_DOMAINS:
|
||||
assumed_state_or_set_position = bool(
|
||||
(
|
||||
self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
& COVER_VALVE_SET_POSITION_FEATURE[domain]
|
||||
)
|
||||
or self.state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
)
|
||||
|
||||
return {
|
||||
"isRunning": state
|
||||
in (
|
||||
COVER_VALVE_STATES[domain]["closing"],
|
||||
COVER_VALVE_STATES[domain]["opening"],
|
||||
)
|
||||
or assumed_state_or_set_position
|
||||
}
|
||||
|
||||
raise NotImplementedError(f"Unsupported domain {domain}")
|
||||
@@ -975,11 +984,23 @@ class StartStopTrait(_Trait):
|
||||
"""Execute a StartStop command."""
|
||||
domain = self.state.domain
|
||||
if command == COMMAND_START_STOP:
|
||||
assumed_state_or_set_position = bool(
|
||||
(
|
||||
self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
& COVER_VALVE_SET_POSITION_FEATURE[domain]
|
||||
)
|
||||
or self.state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
)
|
||||
|
||||
if params["start"] is False:
|
||||
if self.state.state in (
|
||||
COVER_VALVE_STATES[domain]["closing"],
|
||||
COVER_VALVE_STATES[domain]["opening"],
|
||||
) or self.state.attributes.get(ATTR_ASSUMED_STATE):
|
||||
if (
|
||||
self.state.state
|
||||
in (
|
||||
COVER_VALVE_STATES[domain]["closing"],
|
||||
COVER_VALVE_STATES[domain]["opening"],
|
||||
)
|
||||
or assumed_state_or_set_position
|
||||
):
|
||||
await self.hass.services.async_call(
|
||||
domain,
|
||||
SERVICE_STOP_COVER_VALVE[domain],
|
||||
@@ -992,7 +1013,14 @@ class StartStopTrait(_Trait):
|
||||
ERR_ALREADY_STOPPED,
|
||||
f"{FRIENDLY_DOMAIN[domain]} is already stopped",
|
||||
)
|
||||
else:
|
||||
elif (
|
||||
self.state.state
|
||||
in (
|
||||
COVER_VALVE_STATES[domain]["open"],
|
||||
COVER_VALVE_STATES[domain]["closed"],
|
||||
)
|
||||
or assumed_state_or_set_position
|
||||
):
|
||||
await self.hass.services.async_call(
|
||||
domain,
|
||||
SERVICE_TOGGLE_COVER_VALVE[domain],
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"bbw_dose": {
|
||||
"default": "mdi:weight-gram"
|
||||
},
|
||||
"coffee_temp": {
|
||||
"default": "mdi:thermometer-water"
|
||||
},
|
||||
@@ -51,6 +54,14 @@
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"bbw_dose_mode": {
|
||||
"default": "mdi:all-inclusive-box",
|
||||
"state": {
|
||||
"continuous": "mdi:all-inclusive-box",
|
||||
"dose1": "mdi:numeric-1-box",
|
||||
"dose2": "mdi:numeric-2-box"
|
||||
}
|
||||
},
|
||||
"prebrew_infusion_select": {
|
||||
"default": "mdi:water-pump-off",
|
||||
"state": {
|
||||
|
||||
@@ -5,9 +5,14 @@ from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
from pylamarzocco import LaMarzoccoMachine
|
||||
from pylamarzocco.const import ModelName, PreExtractionMode, WidgetType
|
||||
from pylamarzocco.const import DoseMode, ModelName, PreExtractionMode, WidgetType
|
||||
from pylamarzocco.exceptions import RequestNotSuccessful
|
||||
from pylamarzocco.models import CoffeeBoiler, PreBrewing, SteamBoilerTemperature
|
||||
from pylamarzocco.models import (
|
||||
BrewByWeightDoses,
|
||||
CoffeeBoiler,
|
||||
PreBrewing,
|
||||
SteamBoilerTemperature,
|
||||
)
|
||||
|
||||
from homeassistant.components.number import (
|
||||
NumberDeviceClass,
|
||||
@@ -18,6 +23,7 @@ from homeassistant.const import (
|
||||
PRECISION_TENTHS,
|
||||
PRECISION_WHOLE,
|
||||
EntityCategory,
|
||||
UnitOfMass,
|
||||
UnitOfTemperature,
|
||||
UnitOfTime,
|
||||
)
|
||||
@@ -219,6 +225,72 @@ ENTITIES: tuple[LaMarzoccoNumberEntityDescription, ...] = (
|
||||
)
|
||||
),
|
||||
),
|
||||
LaMarzoccoNumberEntityDescription(
|
||||
key="bbw_dose_1",
|
||||
translation_key="bbw_dose",
|
||||
translation_placeholders={"dose": "Dose 1"},
|
||||
device_class=NumberDeviceClass.WEIGHT,
|
||||
native_unit_of_measurement=UnitOfMass.GRAMS,
|
||||
native_step=PRECISION_TENTHS,
|
||||
native_min_value=5,
|
||||
native_max_value=100,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
set_value_fn=(
|
||||
lambda machine, value: machine.set_brew_by_weight_dose(
|
||||
dose=DoseMode.DOSE_1,
|
||||
value=value,
|
||||
)
|
||||
),
|
||||
native_value_fn=(
|
||||
lambda machine: cast(
|
||||
BrewByWeightDoses,
|
||||
machine.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES],
|
||||
).doses.dose_1.dose
|
||||
),
|
||||
available_fn=lambda coordinator: (
|
||||
cast(
|
||||
BrewByWeightDoses,
|
||||
coordinator.device.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES],
|
||||
).scale_connected
|
||||
),
|
||||
supported_fn=(
|
||||
lambda coordinator: coordinator.device.dashboard.model_name
|
||||
in (ModelName.LINEA_MINI, ModelName.LINEA_MINI_R)
|
||||
),
|
||||
),
|
||||
LaMarzoccoNumberEntityDescription(
|
||||
key="bbw_dose_2",
|
||||
translation_key="bbw_dose",
|
||||
translation_placeholders={"dose": "Dose 2"},
|
||||
device_class=NumberDeviceClass.WEIGHT,
|
||||
native_unit_of_measurement=UnitOfMass.GRAMS,
|
||||
native_step=PRECISION_TENTHS,
|
||||
native_min_value=5,
|
||||
native_max_value=100,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
set_value_fn=(
|
||||
lambda machine, value: machine.set_brew_by_weight_dose(
|
||||
dose=DoseMode.DOSE_2,
|
||||
value=value,
|
||||
)
|
||||
),
|
||||
native_value_fn=(
|
||||
lambda machine: cast(
|
||||
BrewByWeightDoses,
|
||||
machine.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES],
|
||||
).doses.dose_2.dose
|
||||
),
|
||||
available_fn=lambda coordinator: (
|
||||
cast(
|
||||
BrewByWeightDoses,
|
||||
coordinator.device.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES],
|
||||
).scale_connected
|
||||
),
|
||||
supported_fn=(
|
||||
lambda coordinator: coordinator.device.dashboard.model_name
|
||||
in (ModelName.LINEA_MINI, ModelName.LINEA_MINI_R)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
from pylamarzocco.const import (
|
||||
DoseMode,
|
||||
ModelName,
|
||||
PreExtractionMode,
|
||||
SmartStandByType,
|
||||
@@ -13,7 +14,7 @@ from pylamarzocco.const import (
|
||||
)
|
||||
from pylamarzocco.devices import LaMarzoccoMachine
|
||||
from pylamarzocco.exceptions import RequestNotSuccessful
|
||||
from pylamarzocco.models import PreBrewing, SteamBoilerLevel
|
||||
from pylamarzocco.models import BrewByWeightDoses, PreBrewing, SteamBoilerLevel
|
||||
|
||||
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||
from homeassistant.const import EntityCategory
|
||||
@@ -50,6 +51,14 @@ STANDBY_MODE_HA_TO_LM = {
|
||||
|
||||
STANDBY_MODE_LM_TO_HA = {value: key for key, value in STANDBY_MODE_HA_TO_LM.items()}
|
||||
|
||||
DOSE_MODE_HA_TO_LM = {
|
||||
"continuous": DoseMode.CONTINUOUS,
|
||||
"dose1": DoseMode.DOSE_1,
|
||||
"dose2": DoseMode.DOSE_2,
|
||||
}
|
||||
|
||||
DOSE_MODE_LM_TO_HA = {value: key for key, value in DOSE_MODE_HA_TO_LM.items()}
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class LaMarzoccoSelectEntityDescription(
|
||||
@@ -117,6 +126,31 @@ ENTITIES: tuple[LaMarzoccoSelectEntityDescription, ...] = (
|
||||
machine.schedule.smart_wake_up_sleep.smart_stand_by_after
|
||||
],
|
||||
),
|
||||
LaMarzoccoSelectEntityDescription(
|
||||
key="bbw_dose_mode",
|
||||
translation_key="bbw_dose_mode",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
options=["continuous", "dose1", "dose2"],
|
||||
select_option_fn=lambda machine, option: machine.set_brew_by_weight_dose_mode(
|
||||
mode=DOSE_MODE_HA_TO_LM[option]
|
||||
),
|
||||
current_option_fn=lambda machine: DOSE_MODE_LM_TO_HA[
|
||||
cast(
|
||||
BrewByWeightDoses,
|
||||
machine.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES],
|
||||
).mode
|
||||
],
|
||||
available_fn=lambda coordinator: (
|
||||
cast(
|
||||
BrewByWeightDoses,
|
||||
coordinator.device.dashboard.config[WidgetType.CM_BREW_BY_WEIGHT_DOSES],
|
||||
).scale_connected
|
||||
),
|
||||
supported_fn=(
|
||||
lambda coordinator: coordinator.device.dashboard.model_name
|
||||
in (ModelName.LINEA_MINI, ModelName.LINEA_MINI_R)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -87,6 +87,9 @@
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"bbw_dose": {
|
||||
"name": "Brew by weight {dose}"
|
||||
},
|
||||
"coffee_temp": {
|
||||
"name": "Coffee target temperature"
|
||||
},
|
||||
@@ -107,6 +110,14 @@
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"bbw_dose_mode": {
|
||||
"name": "Brew by weight dose mode",
|
||||
"state": {
|
||||
"continuous": "Continuous",
|
||||
"dose1": "Dose 1",
|
||||
"dose2": "Dose 2"
|
||||
}
|
||||
},
|
||||
"prebrew_infusion_select": {
|
||||
"name": "Prebrew/-infusion mode",
|
||||
"state": {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"""Support for LCN climate control."""
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Iterable
|
||||
from datetime import timedelta
|
||||
from functools import partial
|
||||
@@ -172,14 +171,14 @@ class LcnClimate(LcnEntity, ClimateEntity):
|
||||
async def async_update(self) -> None:
|
||||
"""Update the state of the entity."""
|
||||
self._attr_available = any(
|
||||
await asyncio.gather(
|
||||
self.device_connection.request_status_variable(
|
||||
[
|
||||
await self.device_connection.request_status_variable(
|
||||
self.variable, SCAN_INTERVAL.seconds
|
||||
),
|
||||
self.device_connection.request_status_variable(
|
||||
await self.device_connection.request_status_variable(
|
||||
self.setpoint, SCAN_INTERVAL.seconds
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
def input_received(self, input_obj: InputType) -> None:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"""Support for LCN covers."""
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Coroutine, Iterable
|
||||
from datetime import timedelta
|
||||
from functools import partial
|
||||
@@ -134,14 +133,14 @@ class LcnOutputsCover(LcnEntity, CoverEntity):
|
||||
"""Update the state of the entity."""
|
||||
if not self.device_connection.is_group:
|
||||
self._attr_available = any(
|
||||
await asyncio.gather(
|
||||
self.device_connection.request_status_output(
|
||||
[
|
||||
await self.device_connection.request_status_output(
|
||||
pypck.lcn_defs.OutputPort["OUTPUTUP"], SCAN_INTERVAL.seconds
|
||||
),
|
||||
self.device_connection.request_status_output(
|
||||
await self.device_connection.request_status_output(
|
||||
pypck.lcn_defs.OutputPort["OUTPUTDOWN"], SCAN_INTERVAL.seconds
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
def input_received(self, input_obj: InputType) -> None:
|
||||
@@ -274,7 +273,7 @@ class LcnRelayCover(LcnEntity, CoverEntity):
|
||||
self.motor, self.positioning_mode, SCAN_INTERVAL.seconds
|
||||
)
|
||||
)
|
||||
self._attr_available = any(await asyncio.gather(*coros))
|
||||
self._attr_available = any([await coro for coro in coros])
|
||||
|
||||
def input_received(self, input_obj: InputType) -> None:
|
||||
"""Set cover states when LCN input object (command) is received."""
|
||||
|
||||
@@ -15,6 +15,13 @@ from .entity import MealieEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
SUPPORTED_MEALPLAN_ENTRY_TYPES = [
|
||||
MealplanEntryType.BREAKFAST,
|
||||
MealplanEntryType.DINNER,
|
||||
MealplanEntryType.LUNCH,
|
||||
MealplanEntryType.SIDE,
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
@@ -26,7 +33,7 @@ async def async_setup_entry(
|
||||
|
||||
async_add_entities(
|
||||
MealieMealplanCalendarEntity(coordinator, entry_type)
|
||||
for entry_type in MealplanEntryType
|
||||
for entry_type in SUPPORTED_MEALPLAN_ENTRY_TYPES
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_polling",
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["aiomealie==1.1.0"]
|
||||
"requirements": ["aiomealie==1.1.1"]
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ class MoldIndicator(SensorEntity):
|
||||
|
||||
# Return an error if the sensor change its state to Unknown.
|
||||
if state.state in (STATE_UNKNOWN, STATE_UNAVAILABLE):
|
||||
_LOGGER.error(
|
||||
_LOGGER.debug(
|
||||
"Unable to parse temperature sensor %s with state: %s",
|
||||
state.entity_id,
|
||||
state.state,
|
||||
@@ -352,7 +352,7 @@ class MoldIndicator(SensorEntity):
|
||||
|
||||
# Return an error if the sensor change its state to Unknown.
|
||||
if state.state in (STATE_UNKNOWN, STATE_UNAVAILABLE):
|
||||
_LOGGER.error(
|
||||
_LOGGER.debug(
|
||||
"Unable to parse humidity sensor %s, state: %s",
|
||||
state.entity_id,
|
||||
state.state,
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_push",
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["python-overseerr==0.7.1"]
|
||||
"requirements": ["python-overseerr==0.8.0"]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from plugwise.constants import GwEntityData
|
||||
from plugwise import GwEntityData
|
||||
|
||||
from homeassistant.const import ATTR_NAME, ATTR_VIA_DEVICE, CONF_HOST
|
||||
from homeassistant.helpers.device_registry import (
|
||||
@@ -30,37 +30,43 @@ class PlugwiseEntity(CoordinatorEntity[PlugwiseDataUpdateCoordinator]):
|
||||
super().__init__(coordinator)
|
||||
self._dev_id = device_id
|
||||
|
||||
configuration_url: str | None = None
|
||||
if entry := self.coordinator.config_entry:
|
||||
configuration_url = f"http://{entry.data[CONF_HOST]}"
|
||||
api = coordinator.api
|
||||
gateway_id = api.gateway_id
|
||||
entry = coordinator.config_entry
|
||||
|
||||
data = coordinator.data[device_id]
|
||||
# Link configuration-URL for the gateway device
|
||||
configuration_url = (
|
||||
f"http://{entry.data[CONF_HOST]}"
|
||||
if device_id == gateway_id and entry
|
||||
else None
|
||||
)
|
||||
|
||||
# Build connections set
|
||||
connections = set()
|
||||
if mac := data.get("mac_address"):
|
||||
if mac := self.device.get("mac_address"):
|
||||
connections.add((CONNECTION_NETWORK_MAC, mac))
|
||||
if mac := data.get("zigbee_mac_address"):
|
||||
connections.add((CONNECTION_ZIGBEE, mac))
|
||||
if zigbee_mac := self.device.get("zigbee_mac_address"):
|
||||
connections.add((CONNECTION_ZIGBEE, zigbee_mac))
|
||||
|
||||
# Set base device info
|
||||
self._attr_device_info = DeviceInfo(
|
||||
configuration_url=configuration_url,
|
||||
identifiers={(DOMAIN, device_id)},
|
||||
connections=connections,
|
||||
manufacturer=data.get("vendor"),
|
||||
model=data.get("model"),
|
||||
model_id=data.get("model_id"),
|
||||
name=coordinator.api.smile.name,
|
||||
sw_version=data.get("firmware"),
|
||||
hw_version=data.get("hardware"),
|
||||
manufacturer=self.device.get("vendor"),
|
||||
model=self.device.get("model"),
|
||||
model_id=self.device.get("model_id"),
|
||||
name=api.smile.name,
|
||||
sw_version=self.device.get("firmware"),
|
||||
hw_version=self.device.get("hardware"),
|
||||
)
|
||||
|
||||
if device_id != coordinator.api.gateway_id:
|
||||
# Add extra info if not the gateway device
|
||||
if device_id != gateway_id:
|
||||
self._attr_device_info.update(
|
||||
{
|
||||
ATTR_NAME: data.get(ATTR_NAME),
|
||||
ATTR_VIA_DEVICE: (
|
||||
DOMAIN,
|
||||
str(self.coordinator.api.gateway_id),
|
||||
),
|
||||
ATTR_NAME: self.device.get(ATTR_NAME),
|
||||
ATTR_VIA_DEVICE: (DOMAIN, gateway_id),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ SELECT_TYPES = (
|
||||
PlugwiseSelectEntityDescription(
|
||||
key=SELECT_SCHEDULE,
|
||||
translation_key=SELECT_SCHEDULE,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
options_key="available_schedules",
|
||||
),
|
||||
PlugwiseSelectEntityDescription(
|
||||
|
||||
@@ -18,6 +18,7 @@ from roborock.data import UserData
|
||||
from roborock.devices.device import RoborockDevice
|
||||
from roborock.devices.device_manager import UserParams, create_device_manager
|
||||
from roborock.map.map_parser import MapParserConfig
|
||||
from roborock.mqtt.session import MqttSessionUnauthorized
|
||||
|
||||
from homeassistant.const import CONF_USERNAME, EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import Event, HomeAssistant
|
||||
@@ -92,6 +93,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) ->
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="no_user_agreement",
|
||||
) from err
|
||||
except MqttSessionUnauthorized as err:
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="mqtt_unauthorized",
|
||||
) from err
|
||||
except RoborockException as err:
|
||||
_LOGGER.debug("Failed to get Roborock home data: %s", err)
|
||||
raise ConfigEntryNotReady(
|
||||
|
||||
@@ -43,6 +43,12 @@ from .models import DeviceState
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=30)
|
||||
|
||||
# Roborock devices have a known issue where they go offline for a short period
|
||||
# around 3AM local time for ~1 minute and reset both the local connection
|
||||
# and MQTT connection. To avoid log spam, we will avoid reporting failures refreshing
|
||||
# data until this duration has passed.
|
||||
MIN_UNAVAILABLE_DURATION = timedelta(minutes=2)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -102,6 +108,9 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
# Keep track of last attempt to refresh maps/rooms to know when to try again.
|
||||
self._last_home_update_attempt: datetime
|
||||
self.last_home_update: datetime | None = None
|
||||
# Tracks the last successful update to control when we report failure
|
||||
# to the base class. This is reset on successful data update.
|
||||
self._last_update_success_time: datetime | None = None
|
||||
|
||||
@cached_property
|
||||
def dock_device_info(self) -> DeviceInfo:
|
||||
@@ -169,7 +178,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
self.last_home_update = dt_util.utcnow()
|
||||
|
||||
async def _verify_api(self) -> None:
|
||||
"""Verify that the api is reachable. If it is not, switch clients."""
|
||||
"""Verify that the api is reachable."""
|
||||
if self._device.is_connected:
|
||||
if self._device.is_local_connected:
|
||||
async_delete_issue(
|
||||
@@ -217,26 +226,27 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
try:
|
||||
# Update device props and standard api information
|
||||
await self._update_device_prop()
|
||||
except UpdateFailed:
|
||||
if self._should_suppress_update_failure():
|
||||
_LOGGER.debug(
|
||||
"Suppressing update failure until unavailable duration passed"
|
||||
)
|
||||
return self.data
|
||||
raise
|
||||
|
||||
# If the vacuum is currently cleaning and it has been IMAGE_CACHE_INTERVAL
|
||||
# since the last map update, you can update the map.
|
||||
new_status = self.properties_api.status
|
||||
if (
|
||||
new_status.in_cleaning
|
||||
and (dt_util.utcnow() - self._last_home_update_attempt)
|
||||
> IMAGE_CACHE_INTERVAL
|
||||
) or self.last_update_state != new_status.state_name:
|
||||
self._last_home_update_attempt = dt_util.utcnow()
|
||||
try:
|
||||
await self.update_map()
|
||||
except HomeAssistantError as err:
|
||||
_LOGGER.debug("Failed to update map: %s", err)
|
||||
except RoborockException as ex:
|
||||
_LOGGER.debug("Failed to update data: %s", ex)
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_data_fail",
|
||||
) from ex
|
||||
# If the vacuum is currently cleaning and it has been IMAGE_CACHE_INTERVAL
|
||||
# since the last map update, you can update the map.
|
||||
new_status = self.properties_api.status
|
||||
if (
|
||||
new_status.in_cleaning
|
||||
and (dt_util.utcnow() - self._last_home_update_attempt)
|
||||
> IMAGE_CACHE_INTERVAL
|
||||
) or self.last_update_state != new_status.state_name:
|
||||
self._last_home_update_attempt = dt_util.utcnow()
|
||||
try:
|
||||
await self.update_map()
|
||||
except HomeAssistantError as err:
|
||||
_LOGGER.debug("Failed to update map: %s", err)
|
||||
|
||||
if self.properties_api.status.in_cleaning:
|
||||
if self._device.is_local_connected:
|
||||
@@ -248,6 +258,8 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
else:
|
||||
self.update_interval = V1_CLOUD_NOT_CLEANING_INTERVAL
|
||||
self.last_update_state = self.properties_api.status.state_name
|
||||
self._last_update_success_time = dt_util.utcnow()
|
||||
_LOGGER.debug("Data update successful %s", self._last_update_success_time)
|
||||
return DeviceState(
|
||||
status=self.properties_api.status,
|
||||
dnd_timer=self.properties_api.dnd,
|
||||
@@ -255,6 +267,23 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
clean_summary=self.properties_api.clean_summary,
|
||||
)
|
||||
|
||||
def _should_suppress_update_failure(self) -> bool:
|
||||
"""Determine if we should suppress update failure reporting.
|
||||
|
||||
We suppress reporting update failures until a minimum duration has
|
||||
passed since the last successful update. This is used to avoid reporting
|
||||
the device as unavailable for short periods, a known issue.
|
||||
|
||||
The intent is to apply to routine background state refreshes and not
|
||||
other failures such as the first update or map updates.
|
||||
"""
|
||||
if self._last_update_success_time is None:
|
||||
# Never had a successful update, do not suppress
|
||||
return False
|
||||
failure_duration = dt_util.utcnow() - self._last_update_success_time
|
||||
_LOGGER.debug("Update failure duration: %s", failure_duration)
|
||||
return failure_duration < MIN_UNAVAILABLE_DURATION
|
||||
|
||||
async def get_routines(self) -> list[HomeDataScene]:
|
||||
"""Get routines."""
|
||||
try:
|
||||
|
||||
@@ -426,6 +426,9 @@
|
||||
"map_failure": {
|
||||
"message": "Something went wrong creating the map"
|
||||
},
|
||||
"mqtt_unauthorized": {
|
||||
"message": "Roborock MQTT servers rejected the connection due to rate limiting or invalid credentials. You may either attempt to reauthenticate or wait and reload the integration."
|
||||
},
|
||||
"no_coordinators": {
|
||||
"message": "No devices were able to successfully setup"
|
||||
},
|
||||
|
||||
@@ -416,8 +416,8 @@ def warn_dip(
|
||||
_LOGGER.warning(
|
||||
(
|
||||
"Entity %s %shas state class total_increasing, but its state is not"
|
||||
" strictly increasing. Triggered by state %s (%s) with last_updated set"
|
||||
" to %s. Please %s"
|
||||
" strictly increasing. Triggered by state %s (previous state: %s) with"
|
||||
" last_updated set to %s. Please %s"
|
||||
),
|
||||
entity_id,
|
||||
f"from integration {domain} " if domain else "",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"""Tesla Fleet integration."""
|
||||
|
||||
import asyncio
|
||||
from typing import Final
|
||||
|
||||
from aiohttp.client_exceptions import ClientResponseError
|
||||
@@ -83,29 +82,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslaFleetConfigEntry) -
|
||||
region: str = token["ou_code"].lower()
|
||||
|
||||
oauth_session = OAuth2Session(hass, entry, implementation)
|
||||
refresh_lock = asyncio.Lock()
|
||||
|
||||
async def _refresh_token() -> str:
|
||||
async with refresh_lock:
|
||||
try:
|
||||
await oauth_session.async_ensure_token_valid()
|
||||
except ClientResponseError as e:
|
||||
if e.status == 401:
|
||||
raise ConfigEntryAuthFailed from e
|
||||
raise ConfigEntryNotReady from e
|
||||
token: str = oauth_session.token[CONF_ACCESS_TOKEN]
|
||||
return token
|
||||
async def _get_access_token() -> str:
|
||||
try:
|
||||
await oauth_session.async_ensure_token_valid()
|
||||
except ClientResponseError as e:
|
||||
if e.status == 401:
|
||||
raise ConfigEntryAuthFailed from e
|
||||
raise ConfigEntryNotReady from e
|
||||
token: str = oauth_session.token[CONF_ACCESS_TOKEN]
|
||||
return token
|
||||
|
||||
# Create API connection
|
||||
tesla = TeslaFleetApi(
|
||||
session=session,
|
||||
access_token=access_token,
|
||||
access_token=_get_access_token,
|
||||
region=region,
|
||||
charging_scope=False,
|
||||
partner_scope=False,
|
||||
energy_scope=Scope.ENERGY_DEVICE_DATA in scopes,
|
||||
vehicle_scope=Scope.VEHICLE_DEVICE_DATA in scopes,
|
||||
refresh_hook=_refresh_token,
|
||||
)
|
||||
try:
|
||||
products = (await tesla.products())["response"]
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["tesla-fleet-api"],
|
||||
"requirements": ["tesla-fleet-api==1.2.5"]
|
||||
"requirements": ["tesla-fleet-api==1.3.0"]
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["tesla-fleet-api"],
|
||||
"requirements": ["tesla-fleet-api==1.2.5", "teslemetry-stream==0.7.10"]
|
||||
"requirements": ["tesla-fleet-api==1.3.0", "teslemetry-stream==0.7.10"]
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user