Skip to content

Commit

Permalink
used new FritzHomeAutomation object
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Massmann <cm@vianetz.com>
  • Loading branch information
ma4nn committed Dec 14, 2023
1 parent 49401bf commit 1d4ff22
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 48 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fritzconnection>=1.3.0
fritzconnection>=1.12.0
requests
lxml
6 changes: 3 additions & 3 deletions src/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from unittest.mock import patch,MagicMock
from unittest.mock import patch
import pytest
from test_response_mock import ResponseMock
from test_fritzconnection_mock import FritzConnectionMock
Expand All @@ -7,12 +7,12 @@


@pytest.fixture(autouse=True)
def fixture_version(request): # request param is fixture
def fixture_version(request): # request param is fixture
with patch('requests.request', side_effect=ResponseMock) as mock_requests:
mock_requests.side_effect.version = request.param if hasattr(request, "param") else None
yield


@pytest.fixture(autouse=True)
def connection(request):
return FritzConnectionMock(version = request.param if hasattr(request, "param") else None)
return FritzConnectionMock(version=request.param if hasattr(request, "param") else None)
59 changes: 25 additions & 34 deletions src/fritzbox_smart_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,42 @@
@see https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/x_homeauto.pdf
"""

from fritzconnection import FritzConnection
from fritzconnection.lib.fritzhomeauto import FritzHomeAutomation
from fritzbox_config import FritzboxConfig
from fritzbox_munin_plugin_interface import MuninPluginInterface,main_handler


class FritzboxSmartHome(MuninPluginInterface):
__connection = None

def __init__(self, fritzbox_connection: FritzConnection):
def __init__(self, fritzbox_connection: FritzHomeAutomation):
self.__connection = fritzbox_connection

def __retrieve_smart_home(self) -> []:
smart_home_data = []

for i in range(0, 20):
data = self.__connection.call_action('X_AVM-DE_Homeauto1', 'GetGenericDeviceInfos', arguments={'NewIndex': i})
smart_home_data.append(data)

return smart_home_data

def print_stats(self):
smart_home_data = self.__retrieve_smart_home()
smart_home_data = self.__connection.get_device_information_list()

print("multigraph temperatures")
for data in smart_home_data:
if 'NewTemperatureIsValid' in data and data['NewTemperatureIsValid'] == 'VALID':
print (f"t{data['NewDeviceId']}.value {float(data['NewTemperatureCelsius']) / 10}")
print(f"t{data['NewDeviceId']}.value {float(data['NewTemperatureCelsius']) / 10}")
print("multigraph energy")
for data in smart_home_data:
if 'NewMultimeterIsValid' in data and data['NewMultimeterIsValid'] == 'VALID':
print (f"e{data['NewDeviceId']}.value {data['NewMultimeterEnergy']}")
print(f"e{data['NewDeviceId']}.value {data['NewMultimeterEnergy']}")
print("multigraph powers")
for data in smart_home_data:
if 'NewMultimeterIsValid' in data and data['NewMultimeterIsValid'] == 'VALID':
print (f"p{data['NewDeviceId']}.value {float(data['NewMultimeterPower']) / 100}")
print(f"p{data['NewDeviceId']}.value {float(data['NewMultimeterPower']) / 100}")
print("multigraph states")
for data in smart_home_data:
if 'NewSwitchIsValid' in data and data['NewSwitchIsValid'] == 'VALID':
state = 1
if 'NewSwitchState' in data and data['NewSwitchState'] == 'OFF':
state = 0
print (f"s{data['NewDeviceId']}.value {state}")
print(f"s{data['NewDeviceId']}.value {state}")

def print_config(self):
smart_home_data = self.__retrieve_smart_home()
smart_home_data = self.__connection.get_device_information_list()
print("multigraph temperatures")
print("graph_title Smart Home temperature")
print("graph_vlabel degrees Celsius")
Expand All @@ -58,10 +49,10 @@ def print_config(self):

for data in smart_home_data:
if 'NewTemperatureIsValid' in data and data['NewTemperatureIsValid'] == 'VALID':
print (f"t{data['NewDeviceId']}.label {data['NewDeviceName']}")
print (f"t{data['NewDeviceId']}.type GAUGE")
print (f"t{data['NewDeviceId']}.graph LINE")
print (f"t{data['NewDeviceId']}.info Temperature [{data['NewProductName']}], Offset: {float(data['NewTemperatureOffset']) / 10}°C")
print(f"t{data['NewDeviceId']}.label {data['NewDeviceName']}")
print(f"t{data['NewDeviceId']}.type GAUGE")
print(f"t{data['NewDeviceId']}.graph LINE")
print(f"t{data['NewDeviceId']}.info Temperature [{data['NewProductName']}], Offset: {float(data['NewTemperatureOffset']) / 10}°C")

print("multigraph energy")
print("graph_title Smart Home energy consumption")
Expand All @@ -71,10 +62,10 @@ def print_config(self):
print("graph_period hour")
for data in smart_home_data:
if 'NewMultimeterIsValid' in data and data['NewMultimeterIsValid'] == 'VALID':
print (f"e{data['NewDeviceId']}.label {data['NewDeviceName']}")
print (f"e{data['NewDeviceId']}.type DERIVE")
print (f"e{data['NewDeviceId']}.graph LINE")
print (f"e{data['NewDeviceId']}.info Energy consumption (Wh) [{data['NewProductName']}]")
print(f"e{data['NewDeviceId']}.label {data['NewDeviceName']}")
print(f"e{data['NewDeviceId']}.type DERIVE")
print(f"e{data['NewDeviceId']}.graph LINE")
print(f"e{data['NewDeviceId']}.info Energy consumption (Wh) [{data['NewProductName']}]")

print("multigraph powers")
print("graph_title Smart Home powers")
Expand All @@ -83,10 +74,10 @@ def print_config(self):
print("graph_scale no")
for data in smart_home_data:
if 'NewMultimeterIsValid' in data and data['NewMultimeterIsValid'] == 'VALID':
print (f"p{data['NewDeviceId']}.label {data['NewDeviceName']}")
print (f"p{data['NewDeviceId']}.type GAUGE")
print (f"p{data['NewDeviceId']}.graph LINE")
print (f"p{data['NewDeviceId']}.info Power (W) [{data['NewProductName']}]")
print(f"p{data['NewDeviceId']}.label {data['NewDeviceName']}")
print(f"p{data['NewDeviceId']}.type GAUGE")
print(f"p{data['NewDeviceId']}.graph LINE")
print(f"p{data['NewDeviceId']}.info Power (W) [{data['NewProductName']}]")

print("multigraph states")
print("graph_title Smart Home switch states")
Expand All @@ -95,12 +86,12 @@ def print_config(self):
print("graph_scale no")
for data in smart_home_data:
if 'NewSwitchIsValid' in data and data['NewSwitchIsValid'] == 'VALID':
print (f"s{data['NewDeviceId']}.label {data['NewDeviceName']}")
print (f"s{data['NewDeviceId']}.type GAUGE")
print (f"s{data['NewDeviceId']}.graph LINE")
print (f"s{data['NewDeviceId']}.info Switch state [{data['NewProductName']}]")
print(f"s{data['NewDeviceId']}.label {data['NewDeviceName']}")
print(f"s{data['NewDeviceId']}.type GAUGE")
print(f"s{data['NewDeviceId']}.graph LINE")
print(f"s{data['NewDeviceId']}.info Switch state [{data['NewProductName']}]")


if __name__ == '__main__':
config = FritzboxConfig()
main_handler(FritzboxSmartHome(FritzConnection(address=config.server, user=config.user, password=config.password, use_tls=config.use_tls)))
main_handler(FritzboxSmartHome(FritzHomeAutomation(address=config.server, user=config.user, password=config.password, use_tls=config.use_tls)))
25 changes: 19 additions & 6 deletions src/test_fritzbox_smart_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

@pytest.mark.parametrize("connection", ["7590-7.57"], indirect=True)
class TestFritzboxSmartHome:
def test_config(self, connection: MagicMock, capsys): # pylint: disable=unused-argument
smart_home = FritzboxSmartHome(connection)
smart_home.print_config()
def test_config(self, connection: MagicMock, capsys): # pylint: disable=unused-argument
sut = FritzboxSmartHome(connection)
sut.print_config()

assert capsys.readouterr().out == """multigraph temperatures
graph_title Smart Home temperature
Expand Down Expand Up @@ -53,9 +53,9 @@ def test_config(self, connection: MagicMock, capsys): # pylint: disable=unused-a
s16.info Switch state [FRITZ!DECT 210]
"""

def test_smart_home(self, connection: MagicMock, capsys): # pylint: disable=unused-argument
uptime = FritzboxSmartHome(connection)
uptime.print_stats()
def test_smart_home(self, connection: MagicMock, capsys): # pylint: disable=unused-argument
sut = FritzboxSmartHome(connection)
sut.print_stats()

assert capsys.readouterr().out == """multigraph temperatures
t16.value 7.0
Expand All @@ -65,4 +65,17 @@ def test_smart_home(self, connection: MagicMock, capsys): # pylint: disable=unus
p16.value 0.0
multigraph states
s16.value 0
"""

def test_smart_home_empty_devices(self, capsys): # pylint: disable=unused-argument
connection = MagicMock()
connection.get_device_information_list.return_value = {}

sut = FritzboxSmartHome(connection)
sut.print_stats()

assert capsys.readouterr().out == """multigraph temperatures
multigraph energy
multigraph powers
multigraph states
"""
10 changes: 6 additions & 4 deletions src/test_fritzconnection_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ class FritzConnectionMock: # pylint: disable=too-few-public-methods
def __init__(self, version):
self.version = version


def call_action(self, *args, **kwargs) -> {}:
index = 0
if 'arguments' in kwargs and 'NewIndex' in kwargs['arguments']:
index = kwargs['arguments']['NewIndex']

json_object = self.get_device_information_list()

return json_object[index] if len(json_object) > index else {}

def get_device_information_list(self, *args, **kwargs) -> {}:
file_name = 'smart_home_devices.json'
file_dir = f"{os.path.dirname(__file__)}/fixtures/fritzbox{self.version}"
with open(file_dir + "/" + file_name, "r", encoding="utf-8") as file:
json_object = json.load(file)

return json_object[index] if len(json_object) > index else {}
return json.load(file)

0 comments on commit 1d4ff22

Please sign in to comment.