"""A sensor for incoming calls using a USB modem that supports caller ID.""" import logging from basicmodem.basicmodem import BasicModem as bm import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( CONF_DEVICE, CONF_NAME, EVENT_HOMEASSISTANT_STOP, STATE_IDLE, ) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) DEFAULT_NAME = "Modem CallerID" ICON = "mdi:phone-classic" DEFAULT_DEVICE = "/dev/ttyACM0" STATE_RING = "ring" STATE_CALLERID = "callerid" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_DEVICE, default=DEFAULT_DEVICE): cv.string, } ) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up modem caller ID sensor platform.""" name = config.get(CONF_NAME) port = config.get(CONF_DEVICE) modem = bm(port) if modem.state == modem.STATE_FAILED: _LOGGER.error("Unable to initialize modem") return add_entities([ModemCalleridSensor(hass, name, port, modem)]) class ModemCalleridSensor(Entity): """Implementation of USB modem caller ID sensor.""" def __init__(self, hass, name, port, modem): """Initialize the sensor.""" self._attributes = {"cid_time": 0, "cid_number": "", "cid_name": ""} self._name = name self.port = port self.modem = modem self._state = STATE_IDLE modem.registercallback(self._incomingcallcallback) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self._stop_modem) def set_state(self, state): """Set the state.""" self._state = state def set_attributes(self, attributes): """Set the state attributes.""" self._attributes = attributes @property def should_poll(self): """No polling needed.""" return False @property def icon(self): """Return icon.""" return ICON @property def state(self): """Return the state of the device.""" return self._state @property def name(self): """Return the name of the sensor.""" return self._name @property def device_state_attributes(self): """Return the state attributes.""" return self._attributes def _stop_modem(self, event): """HA is shutting down, close modem port.""" if self.modem: self.modem.close() self.modem = None def _incomingcallcallback(self, newstate): """Handle new states.""" if newstate == self.modem.STATE_RING: if self.state == self.modem.STATE_IDLE: att = { "cid_time": self.modem.get_cidtime, "cid_number": "", "cid_name": "", } self.set_attributes(att) self._state = STATE_RING self.schedule_update_ha_state() elif newstate == self.modem.STATE_CALLERID: att = { "cid_time": self.modem.get_cidtime, "cid_number": self.modem.get_cidnumber, "cid_name": self.modem.get_cidname, } self.set_attributes(att) self._state = STATE_CALLERID self.schedule_update_ha_state() elif newstate == self.modem.STATE_IDLE: self._state = STATE_IDLE self.schedule_update_ha_state()