def connect(self): """Connect to the Fritz!Box.""" _LOGGER.debug("Setting up socket connection") try: self.connection = FritzMonitor(address=self.host, port=self.port) kwargs = {"event_queue": self.connection.start()} Thread(target=self._process_events, kwargs=kwargs).start() except OSError as err: self.connection = None _LOGGER.error("Cannot connect to %s on port %s: %s", self.host, self.port, err)
def start_monitoring(config): try: # as a context manager FritzMonitor will shut down the monitor thread with FritzMonitor(address=config["fritz"]["address"]) as monitor: event_queue = monitor.start() process_events(config, monitor, event_queue) except (OSError, KeyboardInterrupt) as err: print(err)
class FritzBoxCallMonitor: """Event listener to monitor calls on the Fritz!Box.""" def __init__(self, host, port, sensor): """Initialize Fritz!Box monitor instance.""" self.host = host self.port = port self.connection = None self.stopped = ThreadingEvent() self._sensor = sensor def connect(self): """Connect to the Fritz!Box.""" _LOGGER.debug("Setting up socket connection") try: self.connection = FritzMonitor(address=self.host, port=self.port) kwargs = {"event_queue": self.connection.start()} Thread(target=self._process_events, kwargs=kwargs).start() except OSError as err: self.connection = None _LOGGER.error("Cannot connect to %s on port %s: %s", self.host, self.port, err) def _process_events(self, event_queue): """Listen to incoming or outgoing calls.""" _LOGGER.debug("Connection established, waiting for events") while not self.stopped.is_set(): try: event = event_queue.get(timeout=10) except queue.Empty: if not self.connection.is_alive and not self.stopped.is_set(): _LOGGER.error("Connection has abruptly ended") _LOGGER.debug("Empty event queue") continue else: _LOGGER.debug("Received event: %s", event) self._parse(event) sleep(1) def _parse(self, line): """Parse the call information and set the sensor states.""" line = line.split(";") df_in = "%d.%m.%y %H:%M:%S" df_out = "%Y-%m-%dT%H:%M:%S" isotime = datetime.strptime(line[0], df_in).strftime(df_out) if line[1] == FRITZ_STATE_RING: self._sensor.set_state(STATE_RINGING) att = { "type": "incoming", "from": line[3], "to": line[4], "device": line[5], "initiated": isotime, "from_name": self._sensor.number_to_name(line[3]), } self._sensor.set_attributes(att) elif line[1] == FRITZ_STATE_CALL: self._sensor.set_state(STATE_DIALING) att = { "type": "outgoing", "from": line[4], "to": line[5], "device": line[6], "initiated": isotime, "to_name": self._sensor.number_to_name(line[5]), } self._sensor.set_attributes(att) elif line[1] == FRITZ_STATE_CONNECT: self._sensor.set_state(STATE_TALKING) att = { "with": line[4], "device": line[3], "accepted": isotime, "with_name": self._sensor.number_to_name(line[4]), } self._sensor.set_attributes(att) elif line[1] == FRITZ_STATE_DISCONNECT: self._sensor.set_state(STATE_IDLE) att = {"duration": line[3], "closed": isotime} self._sensor.set_attributes(att) self._sensor.schedule_update_op_state()