2019-02-13 20:21:14 +00:00
|
|
|
"""Support for Freebox devices (Freebox v6 and Freebox mini 4K)."""
|
2020-03-11 21:15:59 +00:00
|
|
|
from typing import Dict
|
2018-12-27 23:26:09 +00:00
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
from homeassistant.config_entries import ConfigEntry
|
2020-02-13 16:52:58 +00:00
|
|
|
from homeassistant.const import DATA_RATE_KILOBYTES_PER_SECOND
|
2020-06-30 19:55:46 +00:00
|
|
|
from homeassistant.core import callback
|
2020-03-11 21:15:59 +00:00
|
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
2018-12-27 23:26:09 +00:00
|
|
|
from homeassistant.helpers.entity import Entity
|
2020-03-11 21:15:59 +00:00
|
|
|
from homeassistant.helpers.typing import HomeAssistantType
|
2020-06-30 19:55:46 +00:00
|
|
|
import homeassistant.util.dt as dt_util
|
2020-03-11 21:15:59 +00:00
|
|
|
|
|
|
|
from .const import (
|
2020-06-30 19:55:46 +00:00
|
|
|
CALL_SENSORS,
|
2020-03-11 21:15:59 +00:00
|
|
|
CONNECTION_SENSORS,
|
|
|
|
DOMAIN,
|
|
|
|
SENSOR_DEVICE_CLASS,
|
|
|
|
SENSOR_ICON,
|
|
|
|
SENSOR_NAME,
|
|
|
|
SENSOR_UNIT,
|
|
|
|
TEMPERATURE_SENSOR_TEMPLATE,
|
|
|
|
)
|
|
|
|
from .router import FreeboxRouter
|
2019-03-21 05:56:46 +00:00
|
|
|
|
2018-12-27 23:26:09 +00:00
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
async def async_setup_entry(
|
|
|
|
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
|
|
|
|
) -> None:
|
2018-12-27 23:26:09 +00:00
|
|
|
"""Set up the sensors."""
|
2020-03-11 21:15:59 +00:00
|
|
|
router = hass.data[DOMAIN][entry.unique_id]
|
|
|
|
entities = []
|
|
|
|
|
|
|
|
for sensor_name in router.sensors_temperature:
|
|
|
|
entities.append(
|
|
|
|
FreeboxSensor(
|
|
|
|
router,
|
|
|
|
sensor_name,
|
|
|
|
{**TEMPERATURE_SENSOR_TEMPLATE, SENSOR_NAME: f"Freebox {sensor_name}"},
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
for sensor_key in CONNECTION_SENSORS:
|
|
|
|
entities.append(
|
|
|
|
FreeboxSensor(router, sensor_key, CONNECTION_SENSORS[sensor_key])
|
|
|
|
)
|
2018-12-27 23:26:09 +00:00
|
|
|
|
2020-06-30 19:55:46 +00:00
|
|
|
for sensor_key in CALL_SENSORS:
|
|
|
|
entities.append(FreeboxCallSensor(router, sensor_key, CALL_SENSORS[sensor_key]))
|
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
async_add_entities(entities, True)
|
2018-12-27 23:26:09 +00:00
|
|
|
|
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
class FreeboxSensor(Entity):
|
|
|
|
"""Representation of a Freebox sensor."""
|
2018-12-27 23:26:09 +00:00
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
def __init__(
|
|
|
|
self, router: FreeboxRouter, sensor_type: str, sensor: Dict[str, any]
|
|
|
|
) -> None:
|
|
|
|
"""Initialize a Freebox sensor."""
|
2018-12-27 23:26:09 +00:00
|
|
|
self._state = None
|
2020-03-11 21:15:59 +00:00
|
|
|
self._router = router
|
|
|
|
self._sensor_type = sensor_type
|
|
|
|
self._name = sensor[SENSOR_NAME]
|
|
|
|
self._unit = sensor[SENSOR_UNIT]
|
|
|
|
self._icon = sensor[SENSOR_ICON]
|
|
|
|
self._device_class = sensor[SENSOR_DEVICE_CLASS]
|
|
|
|
self._unique_id = f"{self._router.mac} {self._name}"
|
|
|
|
|
2020-06-30 19:55:46 +00:00
|
|
|
@callback
|
|
|
|
def async_update_state(self) -> None:
|
2020-03-11 21:15:59 +00:00
|
|
|
"""Update the Freebox sensor."""
|
|
|
|
state = self._router.sensors[self._sensor_type]
|
|
|
|
if self._unit == DATA_RATE_KILOBYTES_PER_SECOND:
|
|
|
|
self._state = round(state / 1000, 2)
|
|
|
|
else:
|
|
|
|
self._state = state
|
|
|
|
|
|
|
|
@property
|
|
|
|
def unique_id(self) -> str:
|
|
|
|
"""Return a unique ID."""
|
|
|
|
return self._unique_id
|
2018-12-27 23:26:09 +00:00
|
|
|
|
|
|
|
@property
|
2020-03-11 21:15:59 +00:00
|
|
|
def name(self) -> str:
|
|
|
|
"""Return the name."""
|
2018-12-27 23:26:09 +00:00
|
|
|
return self._name
|
|
|
|
|
2019-12-23 16:37:41 +00:00
|
|
|
@property
|
2020-03-11 21:15:59 +00:00
|
|
|
def state(self) -> str:
|
|
|
|
"""Return the state."""
|
|
|
|
return self._state
|
|
|
|
|
|
|
|
@property
|
|
|
|
def unit_of_measurement(self) -> str:
|
|
|
|
"""Return the unit."""
|
2019-12-23 16:37:41 +00:00
|
|
|
return self._unit
|
|
|
|
|
|
|
|
@property
|
2020-03-11 21:15:59 +00:00
|
|
|
def icon(self) -> str:
|
|
|
|
"""Return the icon."""
|
2019-12-23 16:37:41 +00:00
|
|
|
return self._icon
|
|
|
|
|
2018-12-27 23:26:09 +00:00
|
|
|
@property
|
2020-03-11 21:15:59 +00:00
|
|
|
def device_class(self) -> str:
|
|
|
|
"""Return the device_class."""
|
|
|
|
return self._device_class
|
2018-12-27 23:26:09 +00:00
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
@property
|
|
|
|
def device_info(self) -> Dict[str, any]:
|
|
|
|
"""Return the device information."""
|
|
|
|
return self._router.device_info
|
2018-12-27 23:26:09 +00:00
|
|
|
|
2020-03-11 21:15:59 +00:00
|
|
|
@property
|
|
|
|
def should_poll(self) -> bool:
|
|
|
|
"""No polling needed."""
|
|
|
|
return False
|
|
|
|
|
2020-06-30 19:55:46 +00:00
|
|
|
@callback
|
|
|
|
def async_on_demand_update(self):
|
2020-03-11 21:15:59 +00:00
|
|
|
"""Update state."""
|
2020-06-30 19:55:46 +00:00
|
|
|
self.async_update_state()
|
|
|
|
self.async_write_ha_state()
|
2020-03-11 21:15:59 +00:00
|
|
|
|
|
|
|
async def async_added_to_hass(self):
|
|
|
|
"""Register state update callback."""
|
2020-06-30 19:55:46 +00:00
|
|
|
self.async_update_state()
|
|
|
|
self.async_on_remove(
|
|
|
|
async_dispatcher_connect(
|
|
|
|
self.hass,
|
|
|
|
self._router.signal_sensor_update,
|
|
|
|
self.async_on_demand_update,
|
|
|
|
)
|
2020-03-11 21:15:59 +00:00
|
|
|
)
|
|
|
|
|
2020-06-30 19:55:46 +00:00
|
|
|
|
|
|
|
class FreeboxCallSensor(FreeboxSensor):
|
|
|
|
"""Representation of a Freebox call sensor."""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self, router: FreeboxRouter, sensor_type: str, sensor: Dict[str, any]
|
|
|
|
) -> None:
|
|
|
|
"""Initialize a Freebox call sensor."""
|
|
|
|
self._call_list_for_type = []
|
|
|
|
super().__init__(router, sensor_type, sensor)
|
|
|
|
|
|
|
|
@callback
|
|
|
|
def async_update_state(self) -> None:
|
|
|
|
"""Update the Freebox call sensor."""
|
|
|
|
self._call_list_for_type = []
|
2020-09-12 23:13:57 +00:00
|
|
|
if self._router.call_list:
|
|
|
|
for call in self._router.call_list:
|
|
|
|
if not call["new"]:
|
|
|
|
continue
|
|
|
|
if call["type"] == self._sensor_type:
|
|
|
|
self._call_list_for_type.append(call)
|
2020-06-30 19:55:46 +00:00
|
|
|
|
|
|
|
self._state = len(self._call_list_for_type)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def device_state_attributes(self) -> Dict[str, any]:
|
|
|
|
"""Return device specific state attributes."""
|
|
|
|
return {
|
|
|
|
dt_util.utc_from_timestamp(call["datetime"]).isoformat(): call["name"]
|
|
|
|
for call in self._call_list_for_type
|
|
|
|
}
|