From 5d6df85ed657ce81cbedc6f45c9db31dec94fef5 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 8 Feb 2019 01:43:00 -0500 Subject: [PATCH] Fix custom commands Fix for custom commands with multiple inner tags Updated tests --- sucks/__init__.py | 41 ++++++++++++++++++++++++----------------- tests/test_commands.py | 14 ++++++++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/sucks/__init__.py b/sucks/__init__.py index b6cc953..fcd5f87 100644 --- a/sucks/__init__.py +++ b/sucks/__init__.py @@ -115,10 +115,10 @@ COMPONENT_FROM_ECOVACS = { } def str_to_bool(s): - if s == 'True': + if s == 'True' or s == True: return True - elif s == 'False': - return False + elif s == 'False' or s == False: + return False else: raise ValueError("Cannot covert {} to a bool".format(s)) @@ -661,6 +661,10 @@ class EcoVacsIOT(): def _wrap_command(self, cmd, recipient): + #Remove the td from ctl xml for RestAPI + payloadxml = cmd.to_xml() + payloadxml.attrib.pop("td") + return { 'auth': { 'realm': EcoVacsAPI.REALM, @@ -669,8 +673,9 @@ class EcoVacsIOT(): 'userid': self.uid, 'with': 'users', }, - "cmdName": cmd.name, - "payload": cmd.args_to_xml(), + "cmdName": cmd.name, + "payload": ET.tostring(payloadxml).decode(), + "payloadType": "x", "td": "q", "toId": recipient, @@ -997,31 +1002,33 @@ class VacBotCommand: def to_xml(self): ctl = ET.Element('ctl', {'td': self.name}) - for key, value in self.args.items(): + for key, value in self.args.items(): if type(value) is dict: inner = ET.Element(key, value) ctl.append(inner) + elif type(value) is list: + for item in value: + ixml = self.listobject_to_xml(key, item) + ctl.append(ixml) else: ctl.set(key, value) + return ctl - def args_to_xml(self): - ctl = ET.Element('ctl',{}) - for key, value in self.args.items(): - if type(value) is dict: - inner = ET.Element(key, value) - ctl.append(inner) - else: - ctl.set(key, value) - return ET.tostring(ctl).decode() - - def __str__(self, *args, **kwargs): return self.command_name() + " command" def command_name(self): return self.__class__.__name__.lower() + def listobject_to_xml(self, tag, conv_object): + rtnobject = ET.Element(tag) + if type(conv_object) is dict: + for key, value in conv_object.items(): + rtnobject.set(key, value) + else: + rtnobject.set(tag, conv_object) + return rtnobject class Clean(VacBotCommand): def __init__(self, mode='auto', speed='normal', iot=False, action='start',terminal=False, **kwargs): diff --git a/tests/test_commands.py b/tests/test_commands.py index a1f020e..c385e12 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -19,6 +19,20 @@ def test_custom_command_inner_tag(): b'') +def test_custom_command_multiple_inner_tag(): + # Ensure a custom-built command with multiple inner tags generates the expected XML payload + c = VacBotCommand('CustomCommand', {"customtag":[{"customvar":"customvalue1"},{"customvar":"customvalue2"}]}) + logging.info(ElementTree.tostring(c.to_xml())) + assert_equals(ElementTree.tostring(c.to_xml()), + b'') + +def test_custom_command_args_multiple_inner_tag(): + # Ensure a custom-built command with args and multiple inner tags generates the expected XML payload + c = VacBotCommand('CustomCommand', {"arg1":"value1","customtag":[{"customvar":"customvalue1"},{"customvar":"customvalue2"}]}) + assert_equals(ElementTree.tostring(c.to_xml()), + b'') + + def test_custom_command_noargs(): # Ensure a custom-built command with no args generates XML without an args element c = VacBotCommand('CustomCommand')