mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Implement support for SwitchBot Meter, MeterPlus, and Outdoor Meter (#115522)
* Implement support for SwitchBot MeterPlus Add temperature, humidity, and battery sensor entities for the MeterPlus device * Rename GH username * Update homeassistant/components/switchbot_cloud/coordinator.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Refactor to use EntityDescriptions Concat entity ID in SwitchBotCloudSensor init * Remove __future__ import * Make scan interval user configurable * Add support for Meter and Outdoor Meter * Revert "Make scan interval user configurable" This reverts commit e256c35bb71e598cf879e05e1df21dff8456b09d. * Remove device-specific default scan intervals * Update homeassistant/components/switchbot_cloud/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/switchbot_cloud/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/switchbot_cloud/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Fix ruff errors * Reorder manifest keys * Update CODEOWNERS * Add sensor.py to coveragerc --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
548eb35b79
commit
c3f95a4f7a
@ -1377,6 +1377,7 @@ omit =
|
|||||||
homeassistant/components/switchbot_cloud/climate.py
|
homeassistant/components/switchbot_cloud/climate.py
|
||||||
homeassistant/components/switchbot_cloud/coordinator.py
|
homeassistant/components/switchbot_cloud/coordinator.py
|
||||||
homeassistant/components/switchbot_cloud/entity.py
|
homeassistant/components/switchbot_cloud/entity.py
|
||||||
|
homeassistant/components/switchbot_cloud/sensor.py
|
||||||
homeassistant/components/switchbot_cloud/switch.py
|
homeassistant/components/switchbot_cloud/switch.py
|
||||||
homeassistant/components/switchmate/switch.py
|
homeassistant/components/switchmate/switch.py
|
||||||
homeassistant/components/syncthing/__init__.py
|
homeassistant/components/syncthing/__init__.py
|
||||||
|
@ -1365,8 +1365,8 @@ build.json @home-assistant/supervisor
|
|||||||
/tests/components/switchbee/ @jafar-atili
|
/tests/components/switchbee/ @jafar-atili
|
||||||
/homeassistant/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
/homeassistant/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
||||||
/tests/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
/tests/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
||||||
/homeassistant/components/switchbot_cloud/ @SeraphicRav
|
/homeassistant/components/switchbot_cloud/ @SeraphicRav @laurence-presland
|
||||||
/tests/components/switchbot_cloud/ @SeraphicRav
|
/tests/components/switchbot_cloud/ @SeraphicRav @laurence-presland
|
||||||
/homeassistant/components/switcher_kis/ @thecode
|
/homeassistant/components/switcher_kis/ @thecode
|
||||||
/tests/components/switcher_kis/ @thecode
|
/tests/components/switcher_kis/ @thecode
|
||||||
/homeassistant/components/switchmate/ @danielhiversen @qiz-li
|
/homeassistant/components/switchmate/ @danielhiversen @qiz-li
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
"""The SwitchBot via API integration."""
|
"""SwitchBot via API integration."""
|
||||||
|
|
||||||
from asyncio import gather
|
from asyncio import gather
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
@ -15,7 +15,7 @@ from .const import DOMAIN
|
|||||||
from .coordinator import SwitchBotCoordinator
|
from .coordinator import SwitchBotCoordinator
|
||||||
|
|
||||||
_LOGGER = getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SWITCH]
|
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR, Platform.SWITCH]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -24,6 +24,7 @@ class SwitchbotDevices:
|
|||||||
|
|
||||||
climates: list[Remote] = field(default_factory=list)
|
climates: list[Remote] = field(default_factory=list)
|
||||||
switches: list[Device | Remote] = field(default_factory=list)
|
switches: list[Device | Remote] = field(default_factory=list)
|
||||||
|
sensors: list[Device] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -72,6 +73,14 @@ def make_device_data(
|
|||||||
devices_data.switches.append(
|
devices_data.switches.append(
|
||||||
prepare_device(hass, api, device, coordinators_by_id)
|
prepare_device(hass, api, device, coordinators_by_id)
|
||||||
)
|
)
|
||||||
|
if isinstance(device, Device) and device.device_type in [
|
||||||
|
"Meter",
|
||||||
|
"MeterPlus",
|
||||||
|
"WoIOSensor",
|
||||||
|
]:
|
||||||
|
devices_data.sensors.append(
|
||||||
|
prepare_device(hass, api, device, coordinators_by_id)
|
||||||
|
)
|
||||||
return devices_data
|
return devices_data
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,4 +5,8 @@ from typing import Final
|
|||||||
|
|
||||||
DOMAIN: Final = "switchbot_cloud"
|
DOMAIN: Final = "switchbot_cloud"
|
||||||
ENTRY_TITLE = "SwitchBot Cloud"
|
ENTRY_TITLE = "SwitchBot Cloud"
|
||||||
SCAN_INTERVAL = timedelta(seconds=600)
|
DEFAULT_SCAN_INTERVAL = timedelta(seconds=600)
|
||||||
|
|
||||||
|
SENSOR_KIND_TEMPERATURE = "temperature"
|
||||||
|
SENSOR_KIND_HUMIDITY = "humidity"
|
||||||
|
SENSOR_KIND_BATTERY = "battery"
|
||||||
|
@ -9,7 +9,7 @@ from switchbot_api import CannotConnect, Device, Remote, SwitchBotAPI
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import DOMAIN, SCAN_INTERVAL
|
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
|
||||||
|
|
||||||
_LOGGER = getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
|
|
||||||
@ -21,7 +21,6 @@ class SwitchBotCoordinator(DataUpdateCoordinator[Status]):
|
|||||||
|
|
||||||
_api: SwitchBotAPI
|
_api: SwitchBotAPI
|
||||||
_device_id: str
|
_device_id: str
|
||||||
_should_poll = False
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass: HomeAssistant, api: SwitchBotAPI, device: Device | Remote
|
self, hass: HomeAssistant, api: SwitchBotAPI, device: Device | Remote
|
||||||
@ -31,7 +30,7 @@ class SwitchBotCoordinator(DataUpdateCoordinator[Status]):
|
|||||||
hass,
|
hass,
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=SCAN_INTERVAL,
|
update_interval=DEFAULT_SCAN_INTERVAL,
|
||||||
)
|
)
|
||||||
self._api = api
|
self._api = api
|
||||||
self._device_id = device.device_id
|
self._device_id = device.device_id
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
{
|
{
|
||||||
"domain": "switchbot_cloud",
|
"domain": "switchbot_cloud",
|
||||||
"name": "SwitchBot Cloud",
|
"name": "SwitchBot Cloud",
|
||||||
"codeowners": ["@SeraphicRav"],
|
"codeowners": ["@SeraphicRav", "@laurence-presland"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/switchbot_cloud",
|
"documentation": "https://www.home-assistant.io/integrations/switchbot_cloud",
|
||||||
|
"integration_type": "hub",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["switchbot-api"],
|
"loggers": ["switchbot-api"],
|
||||||
"requirements": ["switchbot-api==2.1.0"]
|
"requirements": ["switchbot-api==2.1.0"]
|
||||||
|
83
homeassistant/components/switchbot_cloud/sensor.py
Normal file
83
homeassistant/components/switchbot_cloud/sensor.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
"""Platform for sensor integration."""
|
||||||
|
|
||||||
|
from switchbot_api import Device, SwitchBotAPI
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import PERCENTAGE, UnitOfTemperature
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import SwitchbotCloudData
|
||||||
|
from .const import DOMAIN
|
||||||
|
from .coordinator import SwitchBotCoordinator
|
||||||
|
from .entity import SwitchBotCloudEntity
|
||||||
|
|
||||||
|
SENSOR_TYPE_TEMPERATURE = "temperature"
|
||||||
|
SENSOR_TYPE_HUMIDITY = "humidity"
|
||||||
|
SENSOR_TYPE_BATTERY = "battery"
|
||||||
|
|
||||||
|
METER_PLUS_SENSOR_DESCRIPTIONS = (
|
||||||
|
SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_TEMPERATURE,
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_HUMIDITY,
|
||||||
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_BATTERY,
|
||||||
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up SwitchBot Cloud entry."""
|
||||||
|
data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id]
|
||||||
|
|
||||||
|
async_add_entities(
|
||||||
|
SwitchBotCloudSensor(data.api, device, coordinator, description)
|
||||||
|
for device, coordinator in data.devices.sensors
|
||||||
|
for description in METER_PLUS_SENSOR_DESCRIPTIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SwitchBotCloudSensor(SwitchBotCloudEntity, SensorEntity):
|
||||||
|
"""Representation of a SwitchBot Cloud sensor entity."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
api: SwitchBotAPI,
|
||||||
|
device: Device,
|
||||||
|
coordinator: SwitchBotCoordinator,
|
||||||
|
description: SensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize SwitchBot Cloud sensor entity."""
|
||||||
|
super().__init__(api, device, coordinator)
|
||||||
|
self.entity_description = description
|
||||||
|
self._attr_unique_id = f"{device.device_id}_{description.key}"
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
"""Handle updated data from the coordinator."""
|
||||||
|
if not self.coordinator.data:
|
||||||
|
return
|
||||||
|
self._attr_native_value = self.coordinator.data.get(self.entity_description.key)
|
||||||
|
self.async_write_ha_state()
|
Loading…
x
Reference in New Issue
Block a user