Skip to content

Commit

Permalink
adds testmode and improves log messages for compatible versions
Browse files Browse the repository at this point in the history
  • Loading branch information
bb-Ricardo committed Dec 21, 2022
1 parent 5c73dbb commit d7eed65
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 20 deletions.
12 changes: 7 additions & 5 deletions fritzinfluxdb/classes/fritzbox/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,17 +521,19 @@ def query_service_data(self, service):
if self.discovery_done is True and service.should_be_requested() is False:
return

service_and_version_name = f"{service.name} " \
f"(Fritz!OS {service.os_min_versions} - {service.os_max_versions or 'latest'})"
if self.discovery_done is False:
if service.os_version_match(self.config.fw_version) is False:
log.debug(f"FritzOS version {self.config.fw_version} not compatible with "
f"supported versions for {service.name}: "
f"supported versions for '{service.name}': "
f"{service.os_min_versions} - {service.os_max_versions or 'latest'}")
service.available = False
return

if service.link_type is not None and self.config.link_type != service.link_type:
log.warning(f"Service '{service.name}' not applicable for this "
f"FritzBox Model Link type '{self.config.link_type}'")
log.warning(f"Service '{service_and_version_name}' not applicable for this "
f"FritzBox Model Link type '{self.config.link_type}'")
service.available = False
return

Expand All @@ -550,11 +552,11 @@ def query_service_data(self, service):
message_handler(message_text)

if self.discovery_done is False:
log.info(f"{self.name} service '{service.name}' will be disabled.")
log.info(f"{self.name} service '{service_and_version_name}' will be disabled.")
service.available = False
return

log.debug(f"Request {self.name} service '{service.name}' returned successfully")
log.debug(f"Request {self.name} service '{service_and_version_name}' returned successfully")

# set time stamp of this query
service.set_last_query_now()
Expand Down
91 changes: 76 additions & 15 deletions fritzinfluxdb/classes/fritzbox/service_definitions/homeauto.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
"""

import xmltodict
import random
from datetime import datetime

from fritzinfluxdb.common import grab
from fritzinfluxdb.common import grab, in_test_mode
from fritzinfluxdb.classes.fritzbox.service_handler import FritzBoxLuaURLPath
from fritzinfluxdb.classes.fritzbox.service_definitions import lua_services

Expand Down Expand Up @@ -75,6 +77,10 @@
"1024": "SUOTA-Update"
}

test_data = None
test_file_location = "test/homeauto_sample.xml"
test_start_ts = datetime.now().timestamp()


def avm_temp_map(value, input_min, input_max, output_min, output_max):
"""
Expand All @@ -93,6 +99,47 @@ def avm_temp_map(value, input_min, input_max, output_min, output_max):
return float((int_value-input_min)/(input_max-input_min)*(output_max-output_min)+output_min)


def get_ha_temperature(data):

if in_test_mode():
return random.randrange(220, 250) / 10

return float((int(grab(data, "temperature.celsius")) + int(grab(data, "temperature.offset")))/10)


def get_ha_powermeter_power(data):

if in_test_mode():
return random.randrange(300_000, 500_000) / 1000

return float(int(grab(data, "powermeter.power")) / 1000)


def get_ha_powermeter_energy(data):

energy = grab(data, "powermeter.energy")
if in_test_mode():
return float(energy) + float(datetime.now().timestamp() - test_start_ts)

return energy


def get_ha_powermeter_voltage(data):

if in_test_mode():
return random.randrange(225_000, 234_000) / 1000

return float(int(grab(data, "powermeter.voltage")) / 1000)


def get_ha_switch_state(data):

if in_test_mode():
return int((datetime.now().timestamp() - test_start_ts) / 1000) % 2

return "0"+grab(data, "switch.state", fallback="0")


def decode_function_bitmask(bitmask: int):

return_values = list()
Expand All @@ -114,13 +161,13 @@ def reformat_homeauto_device_list(data):

device_list = data.get("devicelist")

devices_by_id = {x.get("@id"): x for x in device_list.get("device")}
devices_by_id = {x.get("@id"): x for x in device_list.get("device", [])}

hun_fun_device_id = 0 # these need to be skipped and only scraped for the @fwversion
hun_fun_unit_id = 13 # these ones are kept

new_device_list = list()
for device in device_list.get("device"):
for device in device_list.get("device", []):

device_functions = decode_function_bitmask(device.get("@functionbitmask"))

Expand Down Expand Up @@ -152,9 +199,29 @@ def reformat_homeauto_device_list(data):
def prepare_response_data(response):
"""
handler to prepare returned data for parsing
Parameters
----------
response: requests.response
the FritzBox request response
Return
------
dict: xml response parsed to dict
"""

return reformat_homeauto_device_list(xmltodict.parse(response.content, force_list=('device',)))
global test_data

if in_test_mode():
if test_data is None:
with open(test_file_location) as f:
test_data = f.read()

content = test_data
else:
content = response.content

return reformat_homeauto_device_list(xmltodict.parse(content, force_list=('device',)))


lua_services.append(
Expand Down Expand Up @@ -260,9 +327,7 @@ def prepare_response_data(response):
# data struct type: dict
"type": float,
"tags_function": lambda data: {"name": data.get("name")},
"value_function": lambda data: (
float((int(grab(data, "temperature.celsius")) + int(grab(data, "temperature.offset")))/10)
),
"value_function": get_ha_temperature,
"exclude_filter_function": lambda data: (
grab(data, "temperature.celsius") is None or grab(data, "temperature.offset") is None
)
Expand Down Expand Up @@ -306,9 +371,7 @@ def prepare_response_data(response):
# data struct type: dict
"type": float,
"tags_function": lambda data: {"name": data.get("name")},
"value_function": lambda data: (
float(int(grab(data, "powermeter.power")) / 1000)
),
"value_function": get_ha_powermeter_power,
"exclude_filter_function": lambda data: grab(data, "powermeter.power") is None
},
"exclude_filter_function": lambda data: "device" not in data.get("devicelist").keys()
Expand All @@ -320,7 +383,7 @@ def prepare_response_data(response):
# data struct type: dict
"type": float,
"tags_function": lambda data: {"name": data.get("name")},
"value_function": lambda data: grab(data, "powermeter.energy"),
"value_function": get_ha_powermeter_energy,
"exclude_filter_function": lambda data: grab(data, "powermeter.energy") is None
},
"exclude_filter_function": lambda data: "device" not in data.get("devicelist").keys()
Expand All @@ -332,9 +395,7 @@ def prepare_response_data(response):
# data struct type: dict
"type": float,
"tags_function": lambda data: {"name": data.get("name")},
"value_function": lambda data: (
float(int(grab(data, "powermeter.voltage")) / 1000)
),
"value_function": get_ha_powermeter_voltage,
"exclude_filter_function": lambda data: grab(data, "powermeter.voltage") is None
},
"exclude_filter_function": lambda data: "device" not in data.get("devicelist").keys()
Expand All @@ -348,7 +409,7 @@ def prepare_response_data(response):
# data struct type: dict
"type": int,
"tags_function": lambda data: {"name": data.get("name")},
"value_function": lambda data: "0"+grab(data, "switch.state", fallback="0"),
"value_function": get_ha_switch_state,
"exclude_filter_function": lambda data: "switch" not in data.keys()
},
"exclude_filter_function": lambda data: "device" not in data.get("devicelist").keys()
Expand Down
17 changes: 17 additions & 0 deletions fritzinfluxdb/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
# repository or visit: <https://opensource.org/licenses/MIT>.

import sys
import os

test_mode_state = False
test_env_var_read = False


def do_error_exit(log_text):
Expand Down Expand Up @@ -103,3 +107,16 @@ def traverse(r_structure, r_path):
return traverse(data, separator.join(r_path.split(separator)[1:]))

return traverse(structure, path)


def in_test_mode():

global test_env_var_read, test_mode_state

if test_env_var_read is False:
test_mode_state = True if os.environ.get("TESTMODE") else False
test_env_var_read = True
if test_mode_state is True:
print("Running in TESTMODE")

return test_mode_state

0 comments on commit d7eed65

Please sign in to comment.