Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config flow to fritzbox_callmonitor #40736

Merged
Merged
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
5575a18
Initial commit
springstan Sep 1, 2020
5936727
Merge branch 'dev' of https://github.com/home-assistant/core into add…
springstan Sep 26, 2020
07fcf90
Add config flow to fritzbox call monitor
springstan Sep 28, 2020
d82b54d
Merge branch 'dev' of https://github.com/home-assistant/core into add…
springstan Sep 28, 2020
0613274
Omit fritzbox_callmonitor from test coverage for now
springstan Sep 28, 2020
3a5411f
Add yaml import to config entry
springstan Oct 3, 2020
7739d4c
Use reference strings in config flow
springstan Oct 4, 2020
985bb7f
Add guard clause for no prefixes
springstan Oct 12, 2020
27fb8cf
Make try catch more readable
springstan Oct 12, 2020
578bb92
Use inline for each loop to go through prefixes
springstan Oct 12, 2020
392c03b
Move I/O into init method
springstan Oct 12, 2020
a1c0e6c
Remove redundant description for config flow
springstan Oct 12, 2020
e24bfdf
Define fph inside of __init__
springstan Oct 12, 2020
f88f633
Select phonebook by its name instead of its id
springstan Oct 13, 2020
4dd63b8
Remove unused port attribute from FritzBoxPhonebook
springstan Oct 13, 2020
73e26a7
Remove phonebook_id attribute from sensor
springstan Oct 13, 2020
4370916
Rename id variable to not override builtin
springstan Oct 13, 2020
6eb8556
Fix unknown variable in sensor.py
springstan Oct 14, 2020
99a2bb1
Add OptionsFlow for prefixes
springstan Oct 17, 2020
418d968
Rename LOGGER to _LOGGER and create one for each file instead of for …
springstan Oct 17, 2020
a2a16e7
Only import what is necessary
springstan Oct 17, 2020
2da4038
Remove unnecessary partial import
springstan Oct 17, 2020
1465fb0
Add and use UNKOWN_NAME constant
springstan Oct 17, 2020
a91e17b
Store model name in sensor attribute
springstan Oct 19, 2020
2170e32
Remove unnecessary attributes from sensor
springstan Oct 19, 2020
987eee8
Call update_phonebook inside of init_phonebook
springstan Oct 19, 2020
d9162a0
Use serial number and phonebook id for unique id
springstan Oct 19, 2020
561c498
Clean up sensor attributes
springstan Oct 19, 2020
ed46725
Correct spelling mistake in strings.json
springstan Oct 19, 2020
1486293
Solve pylint error
springstan Oct 19, 2020
1e7e053
Test fritzbox_callmonitor files by removing it from coveragerc
springstan Oct 19, 2020
96eccc9
Raise ConfigEntryNotReady if unable to connect
springstan Oct 19, 2020
cc2c0b8
Merge branch 'dev' of https://github.com/home-assistant/core into add…
springstan Oct 19, 2020
41973ff
Remove unused name attribute from config flow
springstan Oct 19, 2020
4fda2ca
Fix yaml import to config entry
springstan Oct 20, 2020
8a0bed4
Implement async_added_to_hass and async_will_remove_from_hass for Fri…
springstan Oct 20, 2020
0d1c16a
Normalize naming of config_entry
springstan Oct 20, 2020
824688a
Use correct method for checking socket connection
springstan Oct 20, 2020
09b08fb
Add and use REGEX_NUMBER constant
springstan Oct 20, 2020
6d1f82f
Allow zero prefixes in OptionFlow via suggested_value and add prefix …
springstan Oct 21, 2020
d1d7423
Solve pylint errors
springstan Oct 21, 2020
00f2ff6
Make config flow easier to read
springstan Oct 21, 2020
7359e27
Set entity_id instead of name for created sensors
springstan Oct 21, 2020
9091cdb
Solve pylint error
springstan Oct 21, 2020
e96180c
Remove check for RESULT_SUCCESS since it is unnecessary
springstan Nov 5, 2020
092bc37
Only raise ConfigEntryNotReady if device is offline
springstan Nov 5, 2020
d583753
Resolve merge conflicts
springstan Nov 10, 2020
b9eda16
Only test coverage of config flow
springstan Nov 10, 2020
4177416
Move time related constants back to their previous place
springstan Nov 10, 2020
a418480
Merge branch 'dev' of https://github.com/home-assistant/core into add…
springstan Dec 6, 2020
5bc0b54
Merge branch 'dev' of https://github.com/home-assistant/core into add…
springstan Dec 7, 2020
6a387ca
Extract socket connection to library class FritzMonitor
springstan Dec 7, 2020
04b83cb
Add tests for config flow
springstan Dec 11, 2020
34efb6e
Add missing propertymock for two test cases
springstan Dec 11, 2020
9c2eb4d
Adjust test requirements to include all fritz integrations
springstan Dec 12, 2020
82702b2
Refactoring: renaming variables, extracting code into functions etc.
springstan Dec 12, 2020
fe519bc
Fix pylint error
springstan Dec 12, 2020
b3e8b3d
Remove logic for keeping name from yaml import, rely on renaming by u…
springstan Dec 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Extract socket connection to library class FritzMonitor
  • Loading branch information
springstan committed Dec 7, 2020
commit 6a387cae07aaddda74843f93ef74695d856c01a8
59 changes: 22 additions & 37 deletions homeassistant/components/fritzbox_callmonitor/sensor.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
"""Sensor to monitor incoming/outgoing phone calls on a Fritz!Box router."""
from datetime import datetime, timedelta
import logging
from socket import (
AF_INET,
SO_KEEPALIVE,
SOCK_STREAM,
SOL_SOCKET,
socket,
timeout as SocketTimeout,
)
import queue
from threading import Event as ThreadingEvent, Thread
from time import sleep

from fritzconnection.core.fritzmonitor import FritzMonitor
import voluptuous as vol

from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN, PLATFORM_SCHEMA
Expand Down Expand Up @@ -55,7 +49,6 @@

_LOGGER = logging.getLogger(__name__)

RECONNECT_INTERVAL = 60
SCAN_INTERVAL = timedelta(hours=3)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
Expand Down Expand Up @@ -150,9 +143,12 @@ async def async_will_remove_from_hass(self):
self._monitor
and self._monitor.stopped
and not self._monitor.stopped.is_set()
and self._monitor.connection
and self._monitor.connection.is_alive
):
_LOGGER.debug("Stopping monitor for: %s", self.entity_id)
self._monitor.stopped.set()
self._monitor.connection.stop()
_LOGGER.debug("Stopped monitor for: %s", self.entity_id)

def set_state(self, state):
"""Set the state."""
Expand Down Expand Up @@ -219,48 +215,37 @@ def __init__(self, host, port, sensor):
"""Initialize Fritz!Box monitor instance."""
self.host = host
self.port = port
self.sock = None
self._sensor = sensor
self.connection = None
self.stopped = ThreadingEvent()
self._sensor = sensor

def connect(self):
"""Connect to the Fritz!Box."""
_LOGGER.debug("Setting up socket...")
self.sock = socket(AF_INET, SOCK_STREAM)
self.sock.settimeout(10)
self.sock.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1)
_LOGGER.debug("Setting up socket connection")
try:
self.sock.connect((self.host, self.port))
Thread(target=self._listen).start()
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.sock = None
self.connection = None
_LOGGER.error(
"Cannot connect to %s on port %s: %s", self.host, self.port, err
)

def _listen(self):
def _process_events(self, event_queue):
"""Listen to incoming or outgoing calls."""
_LOGGER.debug("Connection established, waiting for response...")
_LOGGER.debug("Connection established, waiting for events")
while not self.stopped.is_set():
try:
response = self.sock.recv(2048)
except SocketTimeout:
# if no response after 10 seconds, just recv again
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
response = str(response, "utf-8")
_LOGGER.debug("Received %s", response)

if not response:
# if the response is empty, the connection has been lost.
# try to reconnect
_LOGGER.warning("Connection lost, reconnecting...")
self.sock = None
while self.sock is None:
self.connect()
sleep(RECONNECT_INTERVAL)
else:
line = response.split("\n", 1)[0]
self._parse(line)
_LOGGER.debug("Received event: %s", event)
self._parse(event)
sleep(1)

def _parse(self, line):
Expand Down