Add test MQTTPing
Add test MQTTPing & Fix tests
This commit is contained in:
@@ -15,3 +15,5 @@ cover/
|
|||||||
|
|
||||||
# Ignore sucks.egg-info
|
# Ignore sucks.egg-info
|
||||||
sucks.egg-info/
|
sucks.egg-info/
|
||||||
|
.noseids
|
||||||
|
nosetests.xml
|
||||||
|
|||||||
+21
-11
@@ -379,6 +379,11 @@ class VacBot():
|
|||||||
self.lifespanEvents = EventEmitter()
|
self.lifespanEvents = EventEmitter()
|
||||||
self.errorEvents = EventEmitter()
|
self.errorEvents = EventEmitter()
|
||||||
|
|
||||||
|
#Set none for clients to start
|
||||||
|
self.mqtt = None
|
||||||
|
self.iot = None
|
||||||
|
self.xmpp = None
|
||||||
|
|
||||||
if vacuum['iot']:
|
if vacuum['iot']:
|
||||||
self.iot = EcoVacsIOT(user, domain, resource, secret, continent, vacuum)
|
self.iot = EcoVacsIOT(user, domain, resource, secret, continent, vacuum)
|
||||||
self.iot.subscribe_to_ctls(self._handle_ctl)
|
self.iot.subscribe_to_ctls(self._handle_ctl)
|
||||||
@@ -481,6 +486,7 @@ class VacBot():
|
|||||||
if event['ret'] == 'fail' and event['errno'] == '8': #Already charging
|
if event['ret'] == 'fail' and event['errno'] == '8': #Already charging
|
||||||
status = 'slot_charging'
|
status = 'slot_charging'
|
||||||
else:
|
else:
|
||||||
|
status = 'idle' #Fall back to Idle status
|
||||||
_LOGGER.error("Unknown charging status '" + event['errno'] + "'") #Log this so we can identify more errors
|
_LOGGER.error("Unknown charging status '" + event['errno'] + "'") #Log this so we can identify more errors
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -515,6 +521,14 @@ class VacBot():
|
|||||||
try:
|
try:
|
||||||
if not self.vacuum['iot']:
|
if not self.vacuum['iot']:
|
||||||
self.xmpp.send_ping(self._vacuum_address())
|
self.xmpp.send_ping(self._vacuum_address())
|
||||||
|
elif self.vacuum['iot']:
|
||||||
|
if not self.mqtt.send_ping():
|
||||||
|
raise RuntimeError()
|
||||||
|
|
||||||
|
#self.xmpp.send_ping(EcoVacsAPI.REALM) #IOT vacuums are using the realm instead
|
||||||
|
#Some devices may utilize this, but it appears to
|
||||||
|
# just be an oversight in the app communidcations. IOT should probably be using MQTT pings (which are automatic when connected)
|
||||||
|
|
||||||
|
|
||||||
except XMPPError as err:
|
except XMPPError as err:
|
||||||
_LOGGER.warning("Ping did not reach VacBot. Will retry.")
|
_LOGGER.warning("Ping did not reach VacBot. Will retry.")
|
||||||
@@ -525,17 +539,8 @@ class VacBot():
|
|||||||
self.vacuum_status = 'offline'
|
self.vacuum_status = 'offline'
|
||||||
self.statusEvents.notify(self.vacuum_status)
|
self.statusEvents.notify(self.vacuum_status)
|
||||||
|
|
||||||
try:
|
except RuntimeError as err:
|
||||||
if self.vacuum['iot']:
|
|
||||||
self.mqtt.send_ping()
|
|
||||||
#self.xmpp.send_ping(EcoVacsAPI.REALM) #IOT vacuums are using the realm instead
|
|
||||||
#Some devices may utilize this, but it appears to
|
|
||||||
# just be an oversight in the app communidcations. IOT should probably be using MQTT pings (which are automatic when connected)
|
|
||||||
|
|
||||||
except MQTTException as err:
|
|
||||||
_LOGGER.warning("Ping did not reach VacBot. Will retry.")
|
_LOGGER.warning("Ping did not reach VacBot. Will retry.")
|
||||||
_LOGGER.debug("*** Error type: " + err.etype)
|
|
||||||
_LOGGER.debug("*** Error condition: " + err.condition)
|
|
||||||
self._failed_pings += 1
|
self._failed_pings += 1
|
||||||
if self._failed_pings >= 4:
|
if self._failed_pings >= 4:
|
||||||
self.vacuum_status = 'offline'
|
self.vacuum_status = 'offline'
|
||||||
@@ -807,8 +812,13 @@ class EcoVacsMQTT(ClientMQTT):
|
|||||||
rc = self._send_simple_command(MQTTPublish.paho.PINGREQ)
|
rc = self._send_simple_command(MQTTPublish.paho.PINGREQ)
|
||||||
if rc == MQTTPublish.paho.MQTT_ERR_SUCCESS:
|
if rc == MQTTPublish.paho.MQTT_ERR_SUCCESS:
|
||||||
_LOGGER.debug("*** MQTT ping acknowledged ***")
|
_LOGGER.debug("*** MQTT ping acknowledged ***")
|
||||||
|
print(rc)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(rc)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
return rc
|
|
||||||
|
|
||||||
def connect_and_wait_until_ready(self):
|
def connect_and_wait_until_ready(self):
|
||||||
|
|
||||||
|
|||||||
+55
-3
@@ -4,6 +4,8 @@ from sucks import *
|
|||||||
|
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
from sleekxmpp.exceptions import XMPPError
|
from sleekxmpp.exceptions import XMPPError
|
||||||
|
from paho.mqtt.client import MQTT_ERR_UNKNOWN as MQTTError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_handle_clean_report():
|
def test_handle_clean_report():
|
||||||
@@ -46,6 +48,9 @@ def test_handle_charge_state():
|
|||||||
v._handle_ctl({'event': 'charge_state', 'ret': 'fail', 'errno': '8'}) #Seen in IOT when already charging
|
v._handle_ctl({'event': 'charge_state', 'ret': 'fail', 'errno': '8'}) #Seen in IOT when already charging
|
||||||
assert_equals('charging', v.charge_status)
|
assert_equals('charging', v.charge_status)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'charge_state', 'ret': 'fail', 'errno': '5'}) #Seen in IOT randomly - not sure what this is yet
|
||||||
|
assert_equals('idle', v.charge_status)
|
||||||
|
|
||||||
v._handle_ctl({'event': 'charge_state', 'type': 'a_type_not_supported_by_sucks'})
|
v._handle_ctl({'event': 'charge_state', 'type': 'a_type_not_supported_by_sucks'})
|
||||||
assert_equals('a_type_not_supported_by_sucks', v.charge_status)
|
assert_equals('a_type_not_supported_by_sucks', v.charge_status)
|
||||||
|
|
||||||
@@ -135,8 +140,8 @@ def test_is_charging():
|
|||||||
assert_false(v.is_charging)
|
assert_false(v.is_charging)
|
||||||
|
|
||||||
def test_send_ping_no_monitor():
|
def test_send_ping_no_monitor():
|
||||||
|
#Test XMPP Ping
|
||||||
v = a_vacbot()
|
v = a_vacbot()
|
||||||
|
|
||||||
mock = v.xmpp.send_ping = Mock()
|
mock = v.xmpp.send_ping = Mock()
|
||||||
v.send_ping()
|
v.send_ping()
|
||||||
|
|
||||||
@@ -154,8 +159,28 @@ def test_send_ping_no_monitor():
|
|||||||
v.send_ping()
|
v.send_ping()
|
||||||
assert_equals(None, v.vacuum_status)
|
assert_equals(None, v.vacuum_status)
|
||||||
|
|
||||||
|
#Test MQTT Ping
|
||||||
|
v = a_vacbot(iot=True)
|
||||||
|
mock = v.mqtt.send_ping = Mock()
|
||||||
|
v.send_ping()
|
||||||
|
|
||||||
|
# On four failed pings, vacuum state gets set to 'offline'
|
||||||
|
mock.return_value = False
|
||||||
|
v.send_ping()
|
||||||
|
v.send_ping()
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals(None, v.vacuum_status)
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals('offline', v.vacuum_status)
|
||||||
|
|
||||||
|
# On a successful ping after the offline state, state gets reset to None, indicating that it is unknown
|
||||||
|
mock.return_value = True
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals(None, v.vacuum_status)
|
||||||
|
|
||||||
|
|
||||||
def test_send_ping_with_monitor():
|
def test_send_ping_with_monitor():
|
||||||
|
#Test XMPP Ping
|
||||||
v = a_vacbot(monitor=True)
|
v = a_vacbot(monitor=True)
|
||||||
|
|
||||||
ping_mock = v.xmpp.send_ping = Mock()
|
ping_mock = v.xmpp.send_ping = Mock()
|
||||||
@@ -182,6 +207,33 @@ def test_send_ping_with_monitor():
|
|||||||
v.send_ping()
|
v.send_ping()
|
||||||
assert_equals(1, request_statuses_mock.call_count)
|
assert_equals(1, request_statuses_mock.call_count)
|
||||||
|
|
||||||
|
#Test MQTT Ping
|
||||||
|
v = a_vacbot(iot=True, monitor=True)
|
||||||
|
|
||||||
|
ping_mock = v.mqtt.send_ping = Mock()
|
||||||
|
request_statuses_mock = v.request_all_statuses = Mock()
|
||||||
|
|
||||||
|
# First ping should try to fetch statuses
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals(1, request_statuses_mock.call_count)
|
||||||
|
|
||||||
|
# Nothing blowing up is success
|
||||||
|
|
||||||
|
# On four failed pings, vacuum state gets set to 'offline'
|
||||||
|
ping_mock.return_value = False
|
||||||
|
v.send_ping()
|
||||||
|
v.send_ping()
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals(None, v.vacuum_status)
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals('offline', v.vacuum_status)
|
||||||
|
|
||||||
|
# On a successful ping after the offline state, a request for initial statuses is made
|
||||||
|
ping_mock.return_value = True
|
||||||
|
request_statuses_mock.reset_mock()
|
||||||
|
v.send_ping()
|
||||||
|
assert_equals(1, request_statuses_mock.call_count)
|
||||||
|
|
||||||
|
|
||||||
def test_status_event_subscription():
|
def test_status_event_subscription():
|
||||||
v = a_vacbot()
|
v = a_vacbot()
|
||||||
@@ -283,8 +335,8 @@ def test_model_variation():
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def a_vacbot(bot=None, monitor=False):
|
def a_vacbot(bot=None, iot=False, monitor=False):
|
||||||
if bot is None:
|
if bot is None:
|
||||||
bot = {"did": "E0000000001234567890", "class": "126", "nick": "bob", "iot": False}
|
bot = {"did": "E0000000001234567890", "class": "126", "nick": "bob", "iot": iot}
|
||||||
return VacBot('20170101abcdefabcdefa', 'ecouser.net', 'abcdef12', 'A1b2C3d4efghijklmNOPQrstuvwxyz12',
|
return VacBot('20170101abcdefabcdefa', 'ecouser.net', 'abcdef12', 'A1b2C3d4efghijklmNOPQrstuvwxyz12',
|
||||||
bot, 'na', monitor=monitor)
|
bot, 'na', monitor=monitor)
|
||||||
|
|||||||
Reference in New Issue
Block a user