Merge pull request #43 from OverloadUT/cleanup-and-bool-properties
Const and logging cleanup, addition of is_cleaning and is_charging
This commit is contained in:
+98
-62
@@ -11,58 +11,86 @@ from sleekxmpp import ClientXMPP, Callback, MatchXPath
|
|||||||
from sleekxmpp.xmlstream import ET
|
from sleekxmpp.xmlstream import ET
|
||||||
from sleekxmpp.exceptions import XMPPError
|
from sleekxmpp.exceptions import XMPPError
|
||||||
|
|
||||||
# These consts convert to and from Sucks's consts (which closely match what the UI and manuals use)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# These consts define all of the vocabulary used by this library when presenting various states and components.
|
||||||
|
# Applications implementing this library should import these rather than hard-code the strings, for future-proofing.
|
||||||
|
|
||||||
|
CLEAN_MODE_AUTO = 'auto'
|
||||||
|
CLEAN_MODE_EDGE = 'edge'
|
||||||
|
CLEAN_MODE_SPOT = 'spot'
|
||||||
|
CLEAN_MODE_SINGLE_ROOM = 'single_room'
|
||||||
|
CLEAN_MODE_STOP = 'stop'
|
||||||
|
|
||||||
|
FAN_SPEED_NORMAL = 'normal'
|
||||||
|
FAN_SPEED_HIGH = 'high'
|
||||||
|
|
||||||
|
CHARGE_MODE_RETURN = 'return'
|
||||||
|
CHARGE_MODE_RETURNING = 'returning'
|
||||||
|
CHARGE_MODE_CHARGING = 'charging'
|
||||||
|
CHARGE_MODE_IDLE = 'idle'
|
||||||
|
|
||||||
|
COMPONENT_SIDE_BRUSH = 'side_brush'
|
||||||
|
COMPONENT_MAIN_BRUSH = 'main_brush'
|
||||||
|
COMPONENT_FILTER = 'filter'
|
||||||
|
|
||||||
|
VACUUM_STATUS_OFFLINE = 'offline'
|
||||||
|
|
||||||
|
CLEANING_STATES = {CLEAN_MODE_AUTO, CLEAN_MODE_EDGE, CLEAN_MODE_SPOT, CLEAN_MODE_SINGLE_ROOM}
|
||||||
|
CHARGING_STATES = {CHARGE_MODE_CHARGING}
|
||||||
|
|
||||||
|
# These dictionaries convert to and from Sucks's consts (which closely match what the UI and manuals use)
|
||||||
# to and from what the Ecovacs API uses (which are sometimes very oddly named and have random capitalization.)
|
# to and from what the Ecovacs API uses (which are sometimes very oddly named and have random capitalization.)
|
||||||
CLEAN_MODE_TO_ECOVACS = {
|
CLEAN_MODE_TO_ECOVACS = {
|
||||||
'auto': 'auto',
|
CLEAN_MODE_AUTO: 'auto',
|
||||||
'edge': 'border',
|
CLEAN_MODE_EDGE: 'border',
|
||||||
'spot': 'spot',
|
CLEAN_MODE_SPOT: 'spot',
|
||||||
'single_room': 'singleroom',
|
CLEAN_MODE_SINGLE_ROOM: 'singleroom',
|
||||||
'stop': 'stop'
|
CLEAN_MODE_STOP: 'stop'
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEAN_MODE_FROM_ECOVACS = {
|
CLEAN_MODE_FROM_ECOVACS = {
|
||||||
'auto': 'auto',
|
'auto': CLEAN_MODE_AUTO,
|
||||||
'border': 'edge',
|
'border': CLEAN_MODE_EDGE,
|
||||||
'spot': 'spot',
|
'spot': CLEAN_MODE_SPOT,
|
||||||
'singleroom': 'single_room',
|
'singleroom': CLEAN_MODE_SINGLE_ROOM,
|
||||||
'stop': 'stop',
|
'stop': CLEAN_MODE_STOP,
|
||||||
'going': 'returning'
|
'going': CHARGE_MODE_RETURNING
|
||||||
}
|
}
|
||||||
|
|
||||||
FAN_SPEED_TO_ECOVACS = {
|
FAN_SPEED_TO_ECOVACS = {
|
||||||
'normal': 'standard',
|
FAN_SPEED_NORMAL: 'standard',
|
||||||
'high': 'strong'
|
FAN_SPEED_HIGH: 'strong'
|
||||||
}
|
}
|
||||||
|
|
||||||
FAN_SPEED_FROM_ECOVACS = {
|
FAN_SPEED_FROM_ECOVACS = {
|
||||||
'standard': 'normal',
|
'standard': FAN_SPEED_NORMAL,
|
||||||
'strong': 'high'
|
'strong': FAN_SPEED_HIGH
|
||||||
}
|
}
|
||||||
|
|
||||||
CHARGE_MODE_TO_ECOVACS = {
|
CHARGE_MODE_TO_ECOVACS = {
|
||||||
'return': 'go',
|
CHARGE_MODE_RETURN: 'go',
|
||||||
'returning': 'Going',
|
CHARGE_MODE_RETURNING: 'Going',
|
||||||
'charging': 'SlotCharging',
|
CHARGE_MODE_CHARGING: 'SlotCharging',
|
||||||
'idle': 'Idle'
|
CHARGE_MODE_IDLE: 'Idle'
|
||||||
}
|
}
|
||||||
|
|
||||||
CHARGE_MODE_FROM_ECOVACS = {
|
CHARGE_MODE_FROM_ECOVACS = {
|
||||||
'going': 'returning',
|
'going': CHARGE_MODE_RETURNING,
|
||||||
'slot_charging': 'charging',
|
'slot_charging': CHARGE_MODE_CHARGING,
|
||||||
'idle': 'idle'
|
'idle': CHARGE_MODE_IDLE
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPONENT_TO_ECOVACS = {
|
COMPONENT_TO_ECOVACS = {
|
||||||
'main_brush': 'Brush',
|
COMPONENT_MAIN_BRUSH: 'Brush',
|
||||||
'side_brush': 'SideBrush',
|
COMPONENT_SIDE_BRUSH: 'SideBrush',
|
||||||
'filter': 'DustCaseHeap'
|
COMPONENT_FILTER: 'DustCaseHeap'
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPONENT_FROM_ECOVACS = {
|
COMPONENT_FROM_ECOVACS = {
|
||||||
'brush': 'main_brush',
|
'brush': COMPONENT_MAIN_BRUSH,
|
||||||
'side_brush': 'side_brush',
|
'side_brush': COMPONENT_SIDE_BRUSH,
|
||||||
'dust_case_heap': 'filter'
|
'dust_case_heap': COMPONENT_FILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
class EcoVacsAPI:
|
class EcoVacsAPI:
|
||||||
@@ -83,7 +111,7 @@ class EcoVacsAPI:
|
|||||||
'channel': 'c_googleplay',
|
'channel': 'c_googleplay',
|
||||||
'deviceType': '1'
|
'deviceType': '1'
|
||||||
}
|
}
|
||||||
logging.debug("Setting up EcoVacsAPI")
|
_LOGGER.debug("Setting up EcoVacsAPI")
|
||||||
self.resource = device_id[0:8]
|
self.resource = device_id[0:8]
|
||||||
self.country = country
|
self.country = country
|
||||||
self.continent = continent
|
self.continent = continent
|
||||||
@@ -96,7 +124,7 @@ class EcoVacsAPI:
|
|||||||
('uid', self.uid),
|
('uid', self.uid),
|
||||||
('accessToken', self.login_access_token))['authCode']
|
('accessToken', self.login_access_token))['authCode']
|
||||||
self.user_access_token = self.__call_login_by_it_token()['token']
|
self.user_access_token = self.__call_login_by_it_token()['token']
|
||||||
logging.debug("EcoVacsAPI connection complete")
|
_LOGGER.debug("EcoVacsAPI connection complete")
|
||||||
|
|
||||||
def __sign(self, params):
|
def __sign(self, params):
|
||||||
result = params.copy()
|
result = params.copy()
|
||||||
@@ -113,34 +141,34 @@ class EcoVacsAPI:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def __call_main_api(self, function, *args):
|
def __call_main_api(self, function, *args):
|
||||||
logging.debug("calling main api {} with {}".format(function, args))
|
_LOGGER.debug("calling main api {} with {}".format(function, args))
|
||||||
params = OrderedDict(args)
|
params = OrderedDict(args)
|
||||||
params['requestId'] = self.md5(time.time())
|
params['requestId'] = self.md5(time.time())
|
||||||
url = (EcoVacsAPI.MAIN_URL_FORMAT + "/" + function).format(**self.meta)
|
url = (EcoVacsAPI.MAIN_URL_FORMAT + "/" + function).format(**self.meta)
|
||||||
api_response = requests.get(url, self.__sign(params))
|
api_response = requests.get(url, self.__sign(params))
|
||||||
json = api_response.json()
|
json = api_response.json()
|
||||||
logging.debug("got {}".format(json))
|
_LOGGER.debug("got {}".format(json))
|
||||||
if json['code'] == '0000':
|
if json['code'] == '0000':
|
||||||
return json['data']
|
return json['data']
|
||||||
elif json['code'] == '1005':
|
elif json['code'] == '1005':
|
||||||
logging.warning("incorrect email or password")
|
_LOGGER.warning("incorrect email or password")
|
||||||
raise ValueError("incorrect email or password")
|
raise ValueError("incorrect email or password")
|
||||||
else:
|
else:
|
||||||
logging.error("call to {} failed with {}".format(function, json))
|
_LOGGER.error("call to {} failed with {}".format(function, json))
|
||||||
raise RuntimeError("failure code {} ({}) for call {} and parameters {}".format(
|
raise RuntimeError("failure code {} ({}) for call {} and parameters {}".format(
|
||||||
json['code'], json['msg'], function, args))
|
json['code'], json['msg'], function, args))
|
||||||
|
|
||||||
def __call_user_api(self, function, args):
|
def __call_user_api(self, function, args):
|
||||||
logging.debug("calling user api {} with {}".format(function, args))
|
_LOGGER.debug("calling user api {} with {}".format(function, args))
|
||||||
params = {'todo': function}
|
params = {'todo': function}
|
||||||
params.update(args)
|
params.update(args)
|
||||||
response = requests.post(EcoVacsAPI.USER_URL_FORMAT.format(continent=self.continent), json=params)
|
response = requests.post(EcoVacsAPI.USER_URL_FORMAT.format(continent=self.continent), json=params)
|
||||||
json = response.json()
|
json = response.json()
|
||||||
logging.debug("got {}".format(json))
|
_LOGGER.debug("got {}".format(json))
|
||||||
if json['result'] == 'ok':
|
if json['result'] == 'ok':
|
||||||
return json
|
return json
|
||||||
else:
|
else:
|
||||||
logging.error("call to {} failed with {}".format(function, json))
|
_LOGGER.error("call to {} failed with {}".format(function, json))
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"failure {} ({}) for call {} and parameters {}".format(json['error'], json['errno'], function, params))
|
"failure {} ({}) for call {} and parameters {}".format(json['error'], json['errno'], function, params))
|
||||||
|
|
||||||
@@ -259,14 +287,14 @@ class VacBot():
|
|||||||
def _handle_error(self, event):
|
def _handle_error(self, event):
|
||||||
error = event['error']
|
error = event['error']
|
||||||
self.errorEvents.notify(error)
|
self.errorEvents.notify(error)
|
||||||
logging.debug("*** error = " + error)
|
_LOGGER.debug("*** error = " + error)
|
||||||
|
|
||||||
def _handle_life_span(self, event):
|
def _handle_life_span(self, event):
|
||||||
type = event['type']
|
type = event['type']
|
||||||
try:
|
try:
|
||||||
type = COMPONENT_FROM_ECOVACS[type]
|
type = COMPONENT_FROM_ECOVACS[type]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.warning("Unknown component type: '" + type + "'")
|
_LOGGER.warning("Unknown component type: '" + type + "'")
|
||||||
|
|
||||||
total = float(event['total'])
|
total = float(event['total'])
|
||||||
val = float(event['val'])
|
val = float(event['val'])
|
||||||
@@ -275,14 +303,14 @@ class VacBot():
|
|||||||
|
|
||||||
lifespan_event = {'type': type, 'lifespan': lifespan}
|
lifespan_event = {'type': type, 'lifespan': lifespan}
|
||||||
self.lifespanEvents.notify(lifespan_event)
|
self.lifespanEvents.notify(lifespan_event)
|
||||||
logging.debug("*** life_span " + type + " = " + str(lifespan))
|
_LOGGER.debug("*** life_span " + type + " = " + str(lifespan))
|
||||||
|
|
||||||
def _handle_clean_report(self, event):
|
def _handle_clean_report(self, event):
|
||||||
type = event['type']
|
type = event['type']
|
||||||
try:
|
try:
|
||||||
type = CLEAN_MODE_FROM_ECOVACS[type]
|
type = CLEAN_MODE_FROM_ECOVACS[type]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.warning("Unknown cleaning status '" + type + "'")
|
_LOGGER.warning("Unknown cleaning status '" + type + "'")
|
||||||
self.clean_status = type
|
self.clean_status = type
|
||||||
self.vacuum_status = type
|
self.vacuum_status = type
|
||||||
fan = event.get('speed', None)
|
fan = event.get('speed', None)
|
||||||
@@ -290,29 +318,29 @@ class VacBot():
|
|||||||
try:
|
try:
|
||||||
fan = FAN_SPEED_FROM_ECOVACS[fan]
|
fan = FAN_SPEED_FROM_ECOVACS[fan]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.warning("Unknown fan speed: '" + fan + "'")
|
_LOGGER.warning("Unknown fan speed: '" + fan + "'")
|
||||||
self.fan_speed = fan
|
self.fan_speed = fan
|
||||||
self.statusEvents.notify(self.vacuum_status)
|
self.statusEvents.notify(self.vacuum_status)
|
||||||
if self.fan_speed:
|
if self.fan_speed:
|
||||||
logging.debug("*** clean_status = " + self.clean_status + " fan_speed = " + self.fan_speed)
|
_LOGGER.debug("*** clean_status = " + self.clean_status + " fan_speed = " + self.fan_speed)
|
||||||
else:
|
else:
|
||||||
logging.debug("*** clean_status = " + self.clean_status + " fan_speed = None")
|
_LOGGER.debug("*** clean_status = " + self.clean_status + " fan_speed = None")
|
||||||
|
|
||||||
def _handle_battery_info(self, iq):
|
def _handle_battery_info(self, iq):
|
||||||
try:
|
try:
|
||||||
self.battery_status = float(iq['power']) / 100
|
self.battery_status = float(iq['power']) / 100
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logging.warning("couldn't parse battery status " + ET.tostring(iq))
|
_LOGGER.warning("couldn't parse battery status " + ET.tostring(iq))
|
||||||
else:
|
else:
|
||||||
self.batteryEvents.notify(self.battery_status)
|
self.batteryEvents.notify(self.battery_status)
|
||||||
logging.debug("*** battery_status = {:.0%}".format(self.battery_status))
|
_LOGGER.debug("*** battery_status = {:.0%}".format(self.battery_status))
|
||||||
|
|
||||||
def _handle_charge_state(self, event):
|
def _handle_charge_state(self, event):
|
||||||
status = event['type']
|
status = event['type']
|
||||||
try:
|
try:
|
||||||
status = CHARGE_MODE_FROM_ECOVACS[status]
|
status = CHARGE_MODE_FROM_ECOVACS[status]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.warning("Unknown charging status '" + status + "'")
|
_LOGGER.warning("Unknown charging status '" + status + "'")
|
||||||
|
|
||||||
self.charge_status = status
|
self.charge_status = status
|
||||||
if status != 'idle' or self.vacuum_status == 'charging':
|
if status != 'idle' or self.vacuum_status == 'charging':
|
||||||
@@ -321,18 +349,26 @@ class VacBot():
|
|||||||
# of what the vacuum is currently up to.
|
# of what the vacuum is currently up to.
|
||||||
self.vacuum_status = status
|
self.vacuum_status = status
|
||||||
self.statusEvents.notify(self.vacuum_status)
|
self.statusEvents.notify(self.vacuum_status)
|
||||||
logging.debug("*** charge_status = " + self.charge_status)
|
_LOGGER.debug("*** charge_status = " + self.charge_status)
|
||||||
|
|
||||||
def _vacuum_address(self):
|
def _vacuum_address(self):
|
||||||
return self.vacuum['did'] + '@' + self.vacuum['class'] + '.ecorobot.net/atom'
|
return self.vacuum['did'] + '@' + self.vacuum['class'] + '.ecorobot.net/atom'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_charging(self) -> bool:
|
||||||
|
return self.vacuum_status in CHARGING_STATES
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_cleaning(self) -> bool:
|
||||||
|
return self.vacuum_status in CLEANING_STATES
|
||||||
|
|
||||||
def send_ping(self):
|
def send_ping(self):
|
||||||
try:
|
try:
|
||||||
self.xmpp.send_ping(self._vacuum_address())
|
self.xmpp.send_ping(self._vacuum_address())
|
||||||
except XMPPError as err:
|
except XMPPError as err:
|
||||||
logging.warning("Ping did not reach VacBot. Will retry.")
|
_LOGGER.warning("Ping did not reach VacBot. Will retry.")
|
||||||
logging.debug("*** Error type: " + err.etype)
|
_LOGGER.debug("*** Error type: " + err.etype)
|
||||||
logging.debug("*** Error condition: " + err.condition)
|
_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'
|
||||||
@@ -355,9 +391,9 @@ class VacBot():
|
|||||||
self.run(GetLifeSpan('side_brush'))
|
self.run(GetLifeSpan('side_brush'))
|
||||||
self.run(GetLifeSpan('filter'))
|
self.run(GetLifeSpan('filter'))
|
||||||
except XMPPError as err:
|
except XMPPError as err:
|
||||||
logging.warning("Component refresh requests failed to reach VacBot. Will try again later.")
|
_LOGGER.warning("Component refresh requests failed to reach VacBot. Will try again later.")
|
||||||
logging.debug("*** Error type: " + err.etype)
|
_LOGGER.debug("*** Error type: " + err.etype)
|
||||||
logging.debug("*** Error condition: " + err.condition)
|
_LOGGER.debug("*** Error condition: " + err.condition)
|
||||||
|
|
||||||
def request_all_statuses(self):
|
def request_all_statuses(self):
|
||||||
try:
|
try:
|
||||||
@@ -365,9 +401,9 @@ class VacBot():
|
|||||||
self.run(GetChargeState())
|
self.run(GetChargeState())
|
||||||
self.run(GetBatteryState())
|
self.run(GetBatteryState())
|
||||||
except XMPPError as err:
|
except XMPPError as err:
|
||||||
logging.warning("Initial status requests failed to reach VacBot. Will try again on next ping.")
|
_LOGGER.warning("Initial status requests failed to reach VacBot. Will try again on next ping.")
|
||||||
logging.debug("*** Error type: " + err.etype)
|
_LOGGER.debug("*** Error type: " + err.etype)
|
||||||
logging.debug("*** Error condition: " + err.condition)
|
_LOGGER.debug("*** Error condition: " + err.condition)
|
||||||
else:
|
else:
|
||||||
self.refresh_components()
|
self.refresh_components()
|
||||||
|
|
||||||
@@ -402,8 +438,8 @@ class EcoVacsXMPP(ClientXMPP):
|
|||||||
self.ready_flag.wait()
|
self.ready_flag.wait()
|
||||||
|
|
||||||
def session_start(self, event):
|
def session_start(self, event):
|
||||||
logging.debug("----------------- starting session ----------------")
|
_LOGGER.debug("----------------- starting session ----------------")
|
||||||
logging.debug("event = {}".format(event))
|
_LOGGER.debug("event = {}".format(event))
|
||||||
self.register_handler(Callback("general",
|
self.register_handler(Callback("general",
|
||||||
MatchXPath('{jabber:client}iq/{com:ctl}query/{com:ctl}'),
|
MatchXPath('{jabber:client}iq/{com:ctl}query/{com:ctl}'),
|
||||||
self._handle_ctl))
|
self._handle_ctl))
|
||||||
@@ -440,7 +476,7 @@ class EcoVacsXMPP(ClientXMPP):
|
|||||||
|
|
||||||
def send_command(self, xml, recipient):
|
def send_command(self, xml, recipient):
|
||||||
c = self._wrap_command(xml, recipient)
|
c = self._wrap_command(xml, recipient)
|
||||||
logging.debug('Sending command {0}'.format(c))
|
_LOGGER.debug('Sending command {0}'.format(c))
|
||||||
c.send()
|
c.send()
|
||||||
|
|
||||||
def _wrap_command(self, ctl, recipient):
|
def _wrap_command(self, ctl, recipient):
|
||||||
@@ -457,7 +493,7 @@ class EcoVacsXMPP(ClientXMPP):
|
|||||||
def send_ping(self, to):
|
def send_ping(self, to):
|
||||||
q = self.make_iq_get(ito=to, ifrom=self._my_address())
|
q = self.make_iq_get(ito=to, ifrom=self._my_address())
|
||||||
q.xml.append(ET.Element('ping', {'xmlns': 'urn:xmpp:ping'}))
|
q.xml.append(ET.Element('ping', {'xmlns': 'urn:xmpp:ping'}))
|
||||||
logging.debug("*** sending ping ***")
|
_LOGGER.debug("*** sending ping ***")
|
||||||
q.send()
|
q.send()
|
||||||
|
|
||||||
def connect_and_wait_until_ready(self):
|
def connect_and_wait_until_ready(self):
|
||||||
|
|||||||
+8
-6
@@ -10,6 +10,8 @@ from pycountry_convert import country_alpha2_to_continent_code
|
|||||||
|
|
||||||
from sucks import *
|
from sucks import *
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FrequencyParamType(click.ParamType):
|
class FrequencyParamType(click.ParamType):
|
||||||
name = 'frequency'
|
name = 'frequency'
|
||||||
@@ -66,11 +68,11 @@ class StatusWait(BotWait):
|
|||||||
def wait(self, bot):
|
def wait(self, bot):
|
||||||
if not hasattr(bot, self.wait_on):
|
if not hasattr(bot, self.wait_on):
|
||||||
raise ValueError("object " + bot + " does not have method " + self.wait_on)
|
raise ValueError("object " + bot + " does not have method " + self.wait_on)
|
||||||
logging.debug("waiting on " + self.wait_on + " for value " + self.wait_for)
|
_LOGGER.debug("waiting on " + self.wait_on + " for value " + self.wait_for)
|
||||||
|
|
||||||
while getattr(bot, self.wait_on) != self.wait_for:
|
while getattr(bot, self.wait_on) != self.wait_for:
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
logging.debug("wait complete; " + self.wait_on + " is now " + self.wait_for)
|
_LOGGER.debug("wait complete; " + self.wait_on + " is now " + self.wait_for)
|
||||||
|
|
||||||
|
|
||||||
class CliAction:
|
class CliAction:
|
||||||
@@ -122,15 +124,15 @@ def should_run(frequency):
|
|||||||
return True
|
return True
|
||||||
n = random.random()
|
n = random.random()
|
||||||
result = n <= frequency
|
result = n <= frequency
|
||||||
logging.debug("tossing coin: {:0.3f} <= {:0.3f}: {}".format(n, frequency, result))
|
_LOGGER.debug("tossing coin: {:0.3f} <= {:0.3f}: {}".format(n, frequency, result))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@click.group(chain=True)
|
@click.group(chain=True)
|
||||||
@click.option('--debug/--no-debug', default=False)
|
@click.option('--debug/--no-debug', default=False)
|
||||||
def cli(debug):
|
def cli(debug):
|
||||||
level = logging.DEBUG if debug else logging.ERROR
|
logging.basicConfig(format='%(name)-10s %(levelname)-8s %(message)s')
|
||||||
logging.basicConfig(level=level, format='%(levelname)-8s %(message)s')
|
_LOGGER.parent.setLevel(logging.DEBUG if debug else logging.ERROR)
|
||||||
|
|
||||||
|
|
||||||
@cli.command(help='logs in with specified email; run this first')
|
@cli.command(help='logs in with specified email; run this first')
|
||||||
@@ -202,7 +204,7 @@ def run(actions, debug):
|
|||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
logging.debug("will run {}".format(actions))
|
_LOGGER.debug("will run {}".format(actions))
|
||||||
|
|
||||||
if actions:
|
if actions:
|
||||||
config = read_config()
|
config = read_config()
|
||||||
|
|||||||
@@ -95,6 +95,40 @@ def test_lifespan_reports():
|
|||||||
v._handle_ctl({'event': 'life_span', 'type': 'a_weird_component', 'total': '100', 'val': '87'})
|
v._handle_ctl({'event': 'life_span', 'type': 'a_weird_component', 'total': '100', 'val': '87'})
|
||||||
assert_equals({'side_brush': 0, 'main_brush': 0.005, 'a_weird_component': 0.87}, v.components)
|
assert_equals({'side_brush': 0, 'main_brush': 0.005, 'a_weird_component': 0.87}, v.components)
|
||||||
|
|
||||||
|
def test_is_cleaning():
|
||||||
|
v = a_vacbot()
|
||||||
|
|
||||||
|
assert_false(v.is_cleaning)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'clean_report', 'type': 'auto', 'speed': 'strong'})
|
||||||
|
assert_true(v.is_cleaning)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'clean_report', 'type': 'stop'})
|
||||||
|
assert_false(v.is_cleaning)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'clean_report', 'type': 'edge', 'speed': 'normal'})
|
||||||
|
assert_true(v.is_cleaning)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'charge_state', 'type': 'going'})
|
||||||
|
assert_false(v.is_cleaning)
|
||||||
|
|
||||||
|
def test_is_charging():
|
||||||
|
v = a_vacbot()
|
||||||
|
|
||||||
|
assert_false(v.is_charging)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'clean_report', 'type': 'auto', 'speed': 'strong'})
|
||||||
|
assert_false(v.is_charging)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'charge_state', 'type': 'going'})
|
||||||
|
assert_false(v.is_charging)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'charge_state', 'type': 'slot_charging'})
|
||||||
|
assert_true(v.is_charging)
|
||||||
|
|
||||||
|
v._handle_ctl({'event': 'clean_report', 'type': 'edge', 'speed': 'normal'})
|
||||||
|
assert_false(v.is_charging)
|
||||||
|
|
||||||
def test_send_ping_no_monitor():
|
def test_send_ping_no_monitor():
|
||||||
v = a_vacbot()
|
v = a_vacbot()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user