diff --git a/sucks/__init__.py b/sucks/__init__.py
index f8b7c4e..2b32ba5 100644
--- a/sucks/__init__.py
+++ b/sucks/__init__.py
@@ -6,9 +6,11 @@ from collections import OrderedDict
from threading import Event
import threading
import sched
-
+import random
+import ssl
import requests
import stringcase
+
from sleekxmpp import ClientXMPP, Callback, MatchXPath
from sleekxmpp.xmlstream import ET
from sleekxmpp.exceptions import XMPPError
@@ -17,8 +19,6 @@ from paho.mqtt.client import Client as ClientMQTT
from paho.mqtt import publish as MQTTPublish
from paho.mqtt import subscribe as MQTTSubscribe
-import ssl
-
_LOGGER = logging.getLogger(__name__)
# These consts define all of the vocabulary used by this library when presenting various states and components.
@@ -856,7 +856,7 @@ class EcoVacsIOTMQ(ClientMQTT):
class EcoVacsXMPP(ClientXMPP):
def __init__(self, user, domain, resource, secret, continent, vacuum, server_address=None ):
- ClientXMPP.__init__(self, user + '@' + domain, '0/' + resource + '/' + secret)
+ ClientXMPP.__init__(self, "{}@{}/{}".format(user, domain,resource), '0/' + resource + '/' + secret) #Init with resource to bind it
self.user = user
self.domain = domain
self.resource = resource
@@ -922,12 +922,24 @@ class EcoVacsXMPP(ClientXMPP):
def _wrap_command(self, ctl, recipient):
q = self.make_iq_query(xmlns=u'com:ctl', ito=recipient, ifrom=self._my_address())
- q['type'] = 'set'
+ q['type'] = 'set'
+ if not "id" in ctl.attrib:
+ ctl.attrib["id"] = self.getReqID() #If no ctl id provided, add an id to the ctl. This was required for the ozmo930 and shouldn't hurt others
for child in q.xml:
if child.tag.endswith('query'):
child.append(ctl)
return q
+ def getReqID(self, customid="0"): #Generate a somewhat random string for request id, with minium 8 chars. Works similar to ecovacs app.
+ if customid != "0":
+ return "{}".format(customid) #return provided id as string
+ else:
+ rtnval = str(random.randint(1,50))
+ while len(str(rtnval)) <= 8:
+ rtnval = "{}{}".format(rtnval,random.randint(0,50))
+
+ return "{}".format(rtnval) #return as string
+
def _my_address(self):
if not self.vacuum['iotmq']:
return self.user + '@' + self.domain + '/' + self.boundjid.resource
@@ -995,10 +1007,8 @@ class VacBotCommand:
class Clean(VacBotCommand):
def __init__(self, mode='auto', speed='normal', iotmq=False, action='start',terminal=False, **kwargs):
if kwargs == {}:
- if not iotmq:
- super().__init__('Clean', {'clean': {'type': CLEAN_MODE_TO_ECOVACS[mode], 'speed': FAN_SPEED_TO_ECOVACS[speed]}})
- else:
- super().__init__('Clean', {'clean': {'type': CLEAN_MODE_TO_ECOVACS[mode], 'speed': FAN_SPEED_TO_ECOVACS[speed],'act': CLEAN_ACTION_TO_ECOVACS[action]}})
+ #Looks like action is needed for some bots, shouldn't affect older models
+ super().__init__('Clean', {'clean': {'type': CLEAN_MODE_TO_ECOVACS[mode], 'speed': FAN_SPEED_TO_ECOVACS[speed],'act': CLEAN_ACTION_TO_ECOVACS[action]}})
else:
initcmd = {'type': CLEAN_MODE_TO_ECOVACS[mode], 'speed': FAN_SPEED_TO_ECOVACS[speed]}
for kkey, kvalue in kwargs.items():
diff --git a/tests/test_commands.py b/tests/test_commands.py
index bbdd4a9..c40baf4 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -43,11 +43,11 @@ def test_custom_command_noargs():
def test_clean_command():
c = Clean()
assert_equals(ElementTree.tostring(c.to_xml()),
- b'') # protocol has attribs in other order
+ b'') # protocol has attribs in other order
c = Clean('edge', 'high')
assert_equals(ElementTree.tostring(c.to_xml()),
- b'') # protocol has attribs in other order
+ b'') # protocol has attribs in other order
c = Clean(iotmq=True)
assert_equals(ElementTree.tostring(c.to_xml()),
@@ -93,13 +93,13 @@ def test_spotarea_command():
def test_edge_command():
c = Edge()
assert_equals(ElementTree.tostring(c.to_xml()),
- b'') # protocol has attribs in other order
+ b'') # protocol has attribs in other order
def test_spot_command():
c = Spot()
assert_equals(ElementTree.tostring(c.to_xml()),
- b'') # protocol has attribs in other order
+ b'') # protocol has attribs in other order
def test_charge_command():
@@ -111,7 +111,7 @@ def test_charge_command():
def test_stop_command():
c = Stop()
assert_equals(ElementTree.tostring(c.to_xml()),
- b'')
+ b'')
def test_play_sound_command():
diff --git a/tests/test_ecovacs_xmpp.py b/tests/test_ecovacs_xmpp.py
index 1bd6b23..7f5331a 100644
--- a/tests/test_ecovacs_xmpp.py
+++ b/tests/test_ecovacs_xmpp.py
@@ -13,6 +13,20 @@ def test_wrap_command():
c = str(x._wrap_command(Clean().to_xml(), 'E0000000001234567890@126.ecorobot.net/atom'))
assert_true(search(r'from="20170101abcdefabcdefa@ecouser.net/abcdef12"', c))
assert_true(search(r'to="E0000000001234567890@126.ecorobot.net/atom"', c))
+ assert_true(search(r'td="Clean" id="',c)) #Check that an id was added to ctl
+
+ cwithid = Clean().to_xml()
+ cwithid.attrib["id"] = "12345678"
+ c = str(x._wrap_command(cwithid, 'E0000000001234567890@126.ecorobot.net/atom'))
+ assert_true(search(r'td="Clean" id="12345678',c)) #Check that customid was added to ctl
+
+def test_getReqID():
+ x = make_ecovacs_xmpp()
+ rid = x.getReqID("12345678")
+ assert_equals(rid, "12345678") #Check returned ID is the same as provided
+
+ rid2 = x.getReqID()
+ assert_true(len(rid2) >= 8) #Check returned random ID is at least 8 chars
def test_subscribe_to_ctls():
response = None