"""Generic device for the HomematicIP Cloud component.""" import logging from typing import Optional from homematicip.aio.device import AsyncDevice from homematicip.aio.home import AsyncHome from homeassistant.components import homematicip_cloud from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) ATTR_MODEL_TYPE = 'model_type' # RSSI HAP -> Device ATTR_RSSI_DEVICE = 'rssi_device' # RSSI Device -> HAP ATTR_RSSI_PEER = 'rssi_peer' ATTR_SABOTAGE = 'sabotage' ATTR_GROUP_MEMBER_UNREACHABLE = 'group_member_unreachable' class HomematicipGenericDevice(Entity): """Representation of an HomematicIP generic device.""" def __init__(self, home: AsyncHome, device, post: Optional[str] = None) -> None: """Initialize the generic device.""" self._home = home self._device = device self.post = post _LOGGER.info("Setting up %s (%s)", self.name, self._device.modelType) @property def device_info(self): """Return device specific attributes.""" # Only physical devices should be HA devices. if isinstance(self._device, AsyncDevice): return { 'identifiers': { # Serial numbers of Homematic IP device (homematicip_cloud.DOMAIN, self._device.id) }, 'name': self._device.label, 'manufacturer': self._device.oem, 'model': self._device.modelType, 'sw_version': self._device.firmwareVersion, 'via_device': ( homematicip_cloud.DOMAIN, self._device.homeId), } return None async def async_added_to_hass(self): """Register callbacks.""" self._device.on_update(self._async_device_changed) def _async_device_changed(self, *args, **kwargs): """Handle device state changes.""" _LOGGER.debug("Event %s (%s)", self.name, self._device.modelType) self.async_schedule_update_ha_state() @property def name(self) -> str: """Return the name of the generic device.""" name = self._device.label if self._home.name is not None and self._home.name != '': name = "{} {}".format(self._home.name, name) if self.post is not None and self.post != '': name = "{} {}".format(name, self.post) return name @property def should_poll(self) -> bool: """No polling needed.""" return False @property def available(self) -> bool: """Device available.""" return not self._device.unreach @property def unique_id(self) -> str: """Return a unique ID.""" return "{}_{}".format(self.__class__.__name__, self._device.id) @property def icon(self) -> Optional[str]: """Return the icon.""" if hasattr(self._device, 'lowBat') and self._device.lowBat: return 'mdi:battery-outline' if hasattr(self._device, 'sabotage') and self._device.sabotage: return 'mdi:alert' return None @property def device_state_attributes(self): """Return the state attributes of the generic device.""" attr = {ATTR_MODEL_TYPE: self._device.modelType} if hasattr(self._device, 'sabotage') and self._device.sabotage: attr[ATTR_SABOTAGE] = self._device.sabotage if hasattr(self._device, 'rssiDeviceValue') and \ self._device.rssiDeviceValue: attr[ATTR_RSSI_DEVICE] = self._device.rssiDeviceValue if hasattr(self._device, 'rssiPeerValue') and \ self._device.rssiPeerValue: attr[ATTR_RSSI_PEER] = self._device.rssiPeerValue return attr