Skip to content

Commit

Permalink
Adapt to more strict communication API
Browse files Browse the repository at this point in the history
* Use device's timestamp + 1 second when sending messages
* Store message id between mirobo cli tool executions

Fixes #14, #21 and closes #15
  • Loading branch information
rytilahti committed Jul 6, 2017
1 parent 40556c9 commit f274bdf
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
27 changes: 23 additions & 4 deletions mirobo/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
@click.option('--ip', envvar="MIROBO_IP", required=False)
@click.option('--token', envvar="MIROBO_TOKEN", required=False)
@click.option('-d', '--debug', default=False, count=True)
@click.option('--id-file', type=click.File('r+', lazy=False), default='/tmp/python-mirobo.seq')
@click.pass_context
def cli(ctx, ip, token, debug):
def cli(ctx, ip, token, debug, id_file):
"""A tool to command Xiaomi Vacuum robot."""
if debug:
logging.basicConfig(level=logging.DEBUG)
Expand All @@ -37,14 +38,32 @@ def cli(ctx, ip, token, debug):
click.echo("You have to give ip and token!")
sys.exit(-1)

vac = mirobo.Vacuum(ip, token, debug)
start_id = 0
try:
start_id = int(id_file.read())
_LOGGER.debug("Read stored message id: %s" % start_id)
except ValueError:
pass

vac = mirobo.Vacuum(ip, token, start_id, debug)
_LOGGER.debug("Connecting to %s with token %s", ip, token)

ctx.obj = vac

if ctx.invoked_subcommand is None:
ctx.invoke(status)
cleanup(vac, id_file=id_file)


@cli.resultcallback()
@pass_dev
def cleanup(vac, **kwargs):
id_file = kwargs['id_file']
_LOGGER.debug("Writing %s to %s" % (vac.raw_id, id_file))

id_file.seek(0)
id_file.truncate()
id_file.write(str(vac.raw_id))

@cli.command()
def discover():
Expand Down Expand Up @@ -215,8 +234,8 @@ def cleaning_history(vac):
for e in vac.clean_details(id_):
color = "green" if e.complete else "yellow"
click.echo(click.style(
"Clean #%s: %s-%s (complete: %s, unknown: %s)" % (
idx, e.start, e.end, e.complete, e.unknown),
"Clean #%s: %s-%s (complete: %s, error: %s)" % (
idx, e.start, e.end, e.complete, e.error),
bold=True, fg=color))
click.echo(" Area cleaned: %s m²" % e.area)
click.echo(" Duration: (%s)" % e.duration)
Expand Down
22 changes: 18 additions & 4 deletions mirobo/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def __init__(self, ip, token, start_id=0, debug=0):
self.debug = debug

self._timeout = 5
self._device_ts = 0
self.__id = start_id
self._devtype = None
self._serial = None
Expand All @@ -29,6 +30,10 @@ def __enter__(self):
if m is not None:
self._devtype = m.header.value.devtype
self._serial = m.header.value.serial
self._device_ts = m.header.value.ts
_LOGGER.debug("Discovered %s %s with ts: %s" % (self._devtype,
self._serial,
self._device_ts))
else:
_LOGGER.error("Unable to discover a device at address %s", self.ip)

Expand Down Expand Up @@ -90,9 +95,10 @@ def send(self, command, parameters=None):
if parameters:
cmd["params"] = parameters

send_ts = self._device_ts + datetime.timedelta(seconds=1)
header = {'length': 0, 'unknown': 0x00000000,
'devtype': self._devtype, 'serial': self._serial,
'ts': datetime.datetime.utcnow()}
'ts': send_ts}

msg = {'data': {'value': cmd},
'header': {'value': header},
Expand All @@ -116,11 +122,15 @@ def send(self, command, parameters=None):
try:
data, addr = s.recvfrom(1024)
m = Message.parse(data, ctx)
self._device_ts = m.header.value.ts
if self.debug > 1:
_LOGGER.debug("recv: %s" % m)
_LOGGER.debug("%s:%s (ts: %s) << %s" % (self.ip, self.port,
m.header.value.ts,
m.data.value))

self.__id = m.data.value["id"]
_LOGGER.debug("%s:%s (ts: %s, id: %s) << %s" % (self.ip, self.port,
m.header.value.ts,
m.data.value["id"],
m.data.value))
return m.data.value["result"]
except OSError as ex:
_LOGGER.error("got error when receiving: %s", ex)
Expand All @@ -133,3 +143,7 @@ def _id(self):
if self.__id >= 9999:
self.__id = 0
return self.__id

@property
def raw_id(self):
return self.__id
2 changes: 1 addition & 1 deletion mirobo/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def _encode(self, obj, context):
return calendar.timegm(obj.timetuple())

def _decode(self, obj, context):
return datetime.datetime.fromtimestamp(obj)
return datetime.datetime.utcfromtimestamp(obj)


class EncryptionAdapter(Adapter):
Expand Down

0 comments on commit f274bdf

Please sign in to comment.