diff --git a/pyfritzhome/cli.py b/pyfritzhome/cli.py
index 05836a6..d3fa5f9 100644
--- a/pyfritzhome/cli.py
+++ b/pyfritzhome/cli.py
@@ -122,6 +122,7 @@ def thermostat_set_window_open(fritz, args):
"""Command that sets the thermostats window state."""
fritz.set_window_open(args.ain, args.timespan)
+
def thermostat_set_boost_mode(fritz, args):
"""Command that sets the thermostats into boost mode."""
fritz.set_boost_mode(args.ain, args.timespan)
@@ -292,9 +293,7 @@ def main(args=None):
subparser.set_defaults(func=thermostat_set_window_open)
# thermostat boost_mpde
- subparser = _sub_switch.add_parser(
- "set_boost_mode", help="activate the boost mode"
- )
+ subparser = _sub_switch.add_parser("set_boost_mode", help="activate the boost mode")
subparser.add_argument("ain", type=str, metavar="AIN", help="Actor Identification")
subparser.add_argument(
"timespan",
diff --git a/pyfritzhome/devicetypes/fritzhomedevicethermostat.py b/pyfritzhome/devicetypes/fritzhomedevicethermostat.py
index b98c70b..c05bb82 100644
--- a/pyfritzhome/devicetypes/fritzhomedevicethermostat.py
+++ b/pyfritzhome/devicetypes/fritzhomedevicethermostat.py
@@ -71,7 +71,9 @@ def _update_hkr_from_node(self, node):
self.battery_low = self.get_node_value_as_int_as_bool(
hkr_element, "batterylow"
)
- self.battery_level = int(self.get_node_value_as_int(hkr_element, "battery"))
+ self.battery_level = int(
+ self.get_node_value_as_int(hkr_element, "battery")
+ )
self.window_open = self.get_node_value_as_int_as_bool(
hkr_element, "windowopenactiv"
diff --git a/pyfritzhome/fritzhome.py b/pyfritzhome/fritzhome.py
index 2a5b076..d57420b 100644
--- a/pyfritzhome/fritzhome.py
+++ b/pyfritzhome/fritzhome.py
@@ -162,13 +162,14 @@ def get_prefixed_host(self):
else:
return "http://" + host
- def update_devices(self):
+ def update_devices(self, ignore_removed=True):
"""Update the device."""
_LOGGER.info("Updating Devices ...")
if self._devices is None:
self._devices = {}
- for element in self.get_device_elements():
+ device_elements = self.get_device_elements()
+ for element in device_elements:
if element.attrib["identifier"] in self._devices.keys():
_LOGGER.info(
"Updating already existing Device " + element.attrib["identifier"]
@@ -178,6 +179,15 @@ def update_devices(self):
_LOGGER.info("Adding new Device " + element.attrib["identifier"])
device = FritzhomeDevice(self, node=element)
self._devices[device.ain] = device
+
+ if not ignore_removed:
+ for identifier in list(self._devices.keys()):
+ if identifier not in [
+ element.attrib["identifier"] for element in device_elements
+ ]:
+ _LOGGER.info("Removing no more existing device " + identifier)
+ self._devices.pop(identifier)
+
return True
def _get_listinfo_elements(self, entity_type):
@@ -280,9 +290,7 @@ def set_boost_mode(self, ain, seconds):
"""Set the thermostate to boost mode."""
endtimestamp = int(time.time() + seconds)
- self._aha_request(
- "sethkrboost", ain=ain, param={"endtimestamp": endtimestamp}
- )
+ self._aha_request("sethkrboost", ain=ain, param={"endtimestamp": endtimestamp})
def get_comfort_temperature(self, ain):
"""Get the thermostate comfort temperature."""
@@ -407,13 +415,14 @@ def has_templates(self):
return False
return True
- def update_templates(self):
+ def update_templates(self, ignore_removed=True):
"""Update the template."""
_LOGGER.info("Updating Templates ...")
if self._templates is None:
self._templates = {}
- for element in self.get_template_elements():
+ template_elements = self.get_template_elements()
+ for element in template_elements:
if element.attrib["identifier"] in self._templates.keys():
_LOGGER.info(
"Updating already existing Template " + element.attrib["identifier"]
@@ -423,6 +432,15 @@ def update_templates(self):
_LOGGER.info("Adding new Template " + element.attrib["identifier"])
template = FritzhomeTemplate(self, node=element)
self._templates[template.ain] = template
+
+ if not ignore_removed:
+ for identifier in list(self._templates.keys()):
+ if identifier not in [
+ element.attrib["identifier"] for element in template_elements
+ ]:
+ _LOGGER.info("Removing no more existing template " + identifier)
+ self._templates.pop(identifier)
+
return True
def get_template_elements(self):
diff --git a/tests/responses/base/device_list_removed_device.xml b/tests/responses/base/device_list_removed_device.xml
new file mode 100644
index 0000000..b8cc771
--- /dev/null
+++ b/tests/responses/base/device_list_removed_device.xml
@@ -0,0 +1,67 @@
+
+
+
+ 1
+ Steckdose
+
+ 1
+ auto
+ 0
+ 0
+
+
+ 0
+ 707
+
+
+ 285
+ 0
+
+
+
+ 1
+ FRITZ!DECT Rep 100 #1
+
+ 288
+ 0
+
+
+
+ 1
+ Badezimmer
+
+ 205
+ -15
+
+
+ 41
+ 36
+ 36
+ 42
+ 0
+ 0
+ 0
+ 0
+
+ 1508342400
+ 42
+
+
+
+
+ 1
+ Gruppe
+
+ 1
+ auto
+
+
+
+
+ 0
+ 17
+
+
+
\ No newline at end of file
diff --git a/tests/responses/templates/template_list_removed_template.xml b/tests/responses/templates/template_list_removed_template.xml
new file mode 100644
index 0000000..b21814d
--- /dev/null
+++ b/tests/responses/templates/template_list_removed_template.xml
@@ -0,0 +1,85 @@
+
+
+
+ Base Data
+
+
+
+
+
+
+ One Device
+
+
+
+
+
+
+ Multiple Devices
+
+
+
+
+
+
+
+
+
+
+
+ Apply Heating Summer Mode (Heating off)
+
+
+
+
+
+
+ Apply Heating Target Temperature
+
+
+
+
+
+
+ Apply Heating Holiday Mode
+
+
+
+
+
+
+ Apply Heating Time Table
+
+
+
+
+
+
+ Apply Switch/Lamp/Actor manuel on/off Setting
+
+
+
+
+
+
+ Apply Switch/Lamp/Actor Automatic Time Table
+
+
+
+
+
+
+ Apply Lamp/Blind Level
+
+
+
+
+
+
+ Apply Lamp Color
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/test_fritzhome.py b/tests/test_fritzhome.py
index 4a8142d..7233870 100644
--- a/tests/test_fritzhome.py
+++ b/tests/test_fritzhome.py
@@ -234,9 +234,9 @@ def test_set_boost_mode(self):
self.fritz._request.assert_called_with(
"http://10.0.0.1/webservices/homeautoswitch.lua",
{
- "sid": None,
+ "sid": "0000001",
"ain": "1",
"switchcmd": "sethkrboost",
"endtimestamp": 1000 + 25,
},
- )
\ No newline at end of file
+ )
diff --git a/tests/test_fritzhomedevicebase.py b/tests/test_fritzhomedevicebase.py
index c489560..9d4960d 100644
--- a/tests/test_fritzhomedevicebase.py
+++ b/tests/test_fritzhomedevicebase.py
@@ -98,6 +98,20 @@ def test_get_device_present(self):
{"ain": "08761 0000434", "switchcmd": "getswitchpresent", "sid": "0000001"},
)
+ def test_device_removed(self):
+ self.mock.side_effect = [
+ Helper.response("base/device_list"),
+ Helper.response("base/device_list_removed_device"),
+ Helper.response("base/device_list_removed_device"),
+ ]
+
+ self.fritz.update_devices()
+ assert len(self.fritz.get_devices()) == 5
+ self.fritz.update_devices()
+ assert len(self.fritz.get_devices()) == 5
+ self.fritz.update_devices(ignore_removed=False)
+ assert len(self.fritz.get_devices()) == 4
+
def test_device_and_unit_id(self):
device = FritzhomeEntityBase()
diff --git a/tests/test_fritzhometemplate.py b/tests/test_fritzhometemplate.py
index 6795aa4..c4259f4 100644
--- a/tests/test_fritzhometemplate.py
+++ b/tests/test_fritzhometemplate.py
@@ -40,6 +40,20 @@ def test_template_init(self):
FritzhomeDeviceFeatures.TEMPERATURE,
]
+ def test_template_removed(self):
+ self.mock.side_effect = [
+ Helper.response("templates/template_list"),
+ Helper.response("templates/template_list_removed_template"),
+ Helper.response("templates/template_list_removed_template"),
+ ]
+
+ self.fritz.update_templates()
+ assert len(self.fritz.get_templates()) == 12
+ self.fritz.update_templates()
+ assert len(self.fritz.get_templates()) == 12
+ self.fritz.update_templates(ignore_removed=False)
+ assert len(self.fritz.get_templates()) == 11
+
def test_template_with_single_device(self):
template = self.fritz.get_template_by_ain("tmp0B32F7-1B0650234")