Skip to content

Commit

Permalink
Add binary sensor to Netatmo (home-assistant#115119)
Browse files Browse the repository at this point in the history
* Add binary sensor to Netatmo

* Update homeassistant/components/netatmo/binary_sensor.py

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>

* Sigh

* Fix

* Fix

* Fix

---------

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>
  • Loading branch information
joostlek and jpbede committed Apr 11, 2024
1 parent d9b74fd commit 4224234
Show file tree
Hide file tree
Showing 6 changed files with 680 additions and 33 deletions.
60 changes: 60 additions & 0 deletions homeassistant/components/netatmo/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Support for Netatmo binary sensors."""

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import NETATMO_CREATE_WEATHER_SENSOR
from .data_handler import NetatmoDevice
from .entity import NetatmoWeatherModuleEntity

BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = (
BinarySensorEntityDescription(
key="reachable",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
),
)


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up Netatmo binary sensors based on a config entry."""

@callback
def _create_weather_binary_sensor_entity(netatmo_device: NetatmoDevice) -> None:
async_add_entities(
NetatmoWeatherBinarySensor(netatmo_device, description)
for description in BINARY_SENSOR_TYPES
if description.key in netatmo_device.device.features
)

entry.async_on_unload(
async_dispatcher_connect(
hass, NETATMO_CREATE_WEATHER_SENSOR, _create_weather_binary_sensor_entity
)
)


class NetatmoWeatherBinarySensor(NetatmoWeatherModuleEntity, BinarySensorEntity):
"""Implementation of a Netatmo binary sensor."""

def __init__(
self, device: NetatmoDevice, description: BinarySensorEntityDescription
) -> None:
"""Initialize a Netatmo binary sensor."""
super().__init__(device)
self.entity_description = description
self._attr_unique_id = f"{self.device.entity_id}-{description.key}"

@callback
def async_update_callback(self) -> None:
"""Update the entity's state."""
self._attr_is_on = self.device.reachable
self.async_write_ha_state()
1 change: 1 addition & 0 deletions homeassistant/components/netatmo/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
DEFAULT_ATTRIBUTION = f"Data provided by {MANUFACTURER}"

PLATFORMS = [
Platform.BINARY_SENSOR,
Platform.CAMERA,
Platform.CLIMATE,
Platform.COVER,
Expand Down
42 changes: 40 additions & 2 deletions homeassistant/components/netatmo/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
from __future__ import annotations

from abc import abstractmethod
from typing import Any
from typing import Any, cast

from pyatmo import DeviceType, Home, Module, Room
from pyatmo.modules.base_class import NetatmoBase
from pyatmo.modules.base_class import NetatmoBase, Place
from pyatmo.modules.device_types import DEVICE_DESCRIPTION_MAP

from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE
from homeassistant.core import callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity

from .const import (
CONF_URL_ENERGY,
CONF_URL_WEATHER,
DATA_DEVICE_IDS,
DEFAULT_ATTRIBUTION,
DOMAIN,
Expand Down Expand Up @@ -166,3 +168,39 @@ def __init__(self, device: NetatmoDevice) -> None:
def device_type(self) -> DeviceType:
"""Return the device type."""
return self.device.device_type


class NetatmoWeatherModuleEntity(NetatmoModuleEntity):
"""Netatmo weather module entity base class."""

_attr_configuration_url = CONF_URL_WEATHER

def __init__(self, device: NetatmoDevice) -> None:
"""Set up a Netatmo weather module entity."""
super().__init__(device)
category = getattr(self.device.device_category, "name")
self._publishers.extend(
[
{
"name": category,
SIGNAL_NAME: category,
},
]
)

if hasattr(self.device, "place"):
place = cast(Place, getattr(self.device, "place"))
if hasattr(place, "location") and place.location is not None:
self._attr_extra_state_attributes.update(
{
ATTR_LATITUDE: place.location.latitude,
ATTR_LONGITUDE: place.location.longitude,
}
)

@property
def device_type(self) -> DeviceType:
"""Return the Netatmo device type."""
if "." not in self.device.device_type:
return super().device_type
return DeviceType(self.device.device_type.partition(".")[2])
38 changes: 7 additions & 31 deletions homeassistant/components/netatmo/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from typing import Any, cast

import pyatmo
from pyatmo import DeviceType
from pyatmo.modules import PublicWeatherArea

from homeassistant.components.sensor import (
Expand Down Expand Up @@ -48,7 +47,6 @@
from .const import (
CONF_URL_ENERGY,
CONF_URL_PUBLIC_WEATHER,
CONF_URL_WEATHER,
CONF_WEATHER_AREAS,
DATA_HANDLER,
DOMAIN,
Expand All @@ -59,7 +57,12 @@
SIGNAL_NAME,
)
from .data_handler import HOME, PUBLIC, NetatmoDataHandler, NetatmoDevice, NetatmoRoom
from .entity import NetatmoBaseEntity, NetatmoModuleEntity, NetatmoRoomEntity
from .entity import (
NetatmoBaseEntity,
NetatmoModuleEntity,
NetatmoRoomEntity,
NetatmoWeatherModuleEntity,
)
from .helper import NetatmoArea

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -491,11 +494,10 @@ async def add_public_entities(update: bool = True) -> None:
await add_public_entities(False)


class NetatmoWeatherSensor(NetatmoModuleEntity, SensorEntity):
class NetatmoWeatherSensor(NetatmoWeatherModuleEntity, SensorEntity):
"""Implementation of a Netatmo weather/home coach sensor."""

entity_description: NetatmoSensorEntityDescription
_attr_configuration_url = CONF_URL_WEATHER

def __init__(
self,
Expand All @@ -506,34 +508,8 @@ def __init__(
super().__init__(netatmo_device)
self.entity_description = description
self._attr_translation_key = description.netatmo_name
category = getattr(self.device.device_category, "name")
self._publishers.extend(
[
{
"name": category,
SIGNAL_NAME: category,
},
]
)
self._attr_unique_id = f"{self.device.entity_id}-{description.key}"

if hasattr(self.device, "place"):
place = cast(pyatmo.modules.base_class.Place, getattr(self.device, "place"))
if hasattr(place, "location") and place.location is not None:
self._attr_extra_state_attributes.update(
{
ATTR_LATITUDE: place.location.latitude,
ATTR_LONGITUDE: place.location.longitude,
}
)

@property
def device_type(self) -> DeviceType:
"""Return the Netatmo device type."""
if "." not in self.device.device_type:
return super().device_type
return DeviceType(self.device.device_type.partition(".")[2])

@property
def available(self) -> bool:
"""Return True if entity is available."""
Expand Down
Loading

0 comments on commit 4224234

Please sign in to comment.