From f3d5e43b39b30bb052a15e38cf973a93b63d6558 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Fri, 15 Sep 2017 22:20:07 +0200 Subject: [PATCH 1/4] Implement adding, deleting and updating the timer New commands are: * mirobo timer add --cron --command --params * mirobo timer delete * mirobo timer update [--on|--off] Although the vacuum accepts command and params, the added cron entry will be just 'start_clean' --- README.md | 16 ++++++++++ mirobo/vacuum.py | 19 +++++++----- mirobo/vacuum_cli.py | 70 ++++++++++++++++++++++++++++++++------------ 3 files changed, 79 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 6cc6ecd53..c83191774 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,22 @@ Timer #6, id 1488667697356 (ts: 2017-03-04 23:48:17.355999) At 08:48 on the 5th of March ``` +Adding a new timer +``` +$ mirobo timer add --cron '* * * * *' +``` + +Activating/deactivating an existing timer, +use `mirobo timer` to get the required id. +``` +$ mirobo timer update [--off|--on] +``` + +Deleting a timer +``` +$ mirobo timer delete +``` + ### Cleaning history ``` diff --git a/mirobo/vacuum.py b/mirobo/vacuum.py index 862dd7aa8..9e9d67c0f 100644 --- a/mirobo/vacuum.py +++ b/mirobo/vacuum.py @@ -139,13 +139,18 @@ def timer(self) -> List[Timer]: return timers - def set_timer(self, details): - # how to create timers/change values? - # ['ts', 'on'] to enable - raise NotImplementedError() - # return self.send( - # "set_timer", [["ts", ["cron_line", ["start_clean", ""]]]]) - # return self.send("upd_timer", ["ts", "on"]) + def add_timer(self, cron, command, parameters): + import time + ts = int(round(time.time() * 1000)) + return self.send("set_timer", [[str(ts), [cron, [command, parameters]]]]) + + def delete_timer(self, timer_id: int): + return self.send("del_timer", [str(timer_id)]) + + def update_timer(self, timer_id: int, mode): + if mode != "on" and mode != "off": + raise DeviceException("update_timer needs to be either 'on' or 'off") + return self.send("upd_timer", [str(timer_id), mode]) def dnd_status(self): """Returns do-not-disturb status.""" diff --git a/mirobo/vacuum_cli.py b/mirobo/vacuum_cli.py index 1665a7958..abd761320 100644 --- a/mirobo/vacuum_cli.py +++ b/mirobo/vacuum_cli.py @@ -294,27 +294,59 @@ def fanspeed(vac: mirobo.Vacuum, speed): click.echo("Current fan speed: %s" % vac.fan_speed()) -@cli.command() -@click.argument('timer', required=False, default=None) +@cli.group(invoke_without_command=True) @pass_dev -def timer(vac: mirobo.Vacuum, timer): - """Schedule vacuuming, times in GMT.""" - if timer: - raise NotImplementedError() - # vac.set_timer(x) - else: - timers = vac.timer() - for idx, timer in enumerate(timers): - color = "green" if timer.enabled else "yellow" - # Note ts == ID for changes - click.echo(click.style("Timer #%s, id %s (ts: %s)" % ( - idx, timer.id, timer.ts), bold=True, fg=color)) - print(" %s" % timer.cron) - min, hr, x, y, days = timer.cron.split(' ') - # hr is in gmt+8 (chinese time), TODO convert to local +@click.pass_context +def timer(ctx, vac: mirobo.Vacuum): + """List and modify existing timers.""" + if ctx.invoked_subcommand is not None: + return + timers = vac.timer() + for idx, timer in enumerate(timers): + color = "green" if timer.enabled else "yellow" + # Note ts == ID for changes + click.echo(click.style("Timer #%s, id %s (ts: %s)" % ( + idx, timer.id, timer.ts), bold=True, fg=color)) + print(" %s" % timer.cron) + min, hr, x, y, days = timer.cron.split(' ') + # hr is in gmt+8 (chinese time), TODO convert to local + if hr != '*': hr = (int(hr) - 8) % 24 - cron = "%s %s %s %s %s" % (min, hr, x, y, days) - click.echo(" %s" % pretty_cron.prettify_cron(cron)) + cron = "%s %s %s %s %s" % (min, hr, x, y, days) + click.echo(" %s" % pretty_cron.prettify_cron(cron)) + + +@timer.command() +@click.option('--cron') +@click.option('--command', default='', required=False) +@click.option('--params', default='', required=False) +@pass_dev +def add(vac: mirobo.Vacuum, cron, command, params): + """Schedule vacuuming..""" + click.echo(vac.add_timer(cron, command, params)) + + +@timer.command() +@click.argument('timer_id', type=int, required=True) +@pass_dev +def delete(vac: mirobo.Vacuum, timer_id): + """Delete existing schedule.""" + click.echo(vac.delete_timer(timer_id)) + + +@timer.command() +@click.argument('timer_id', type=int, required=True) +@click.option('--on', is_flag=True) +@click.option('--off', is_flag=True) +@pass_dev +def update(vac: mirobo.Vacuum, timer_id, on, off): + """Update (on or off) an existing scheduled.""" + if on and not off: + vac.update_timer(timer_id, "on") + elif off and not on: + vac.update_timer(timer_id, "off") + else: + click.echo("Only 'on' and 'off' are valid for timer") @cli.command() From 52c0c58b7a3039947e08e43ed9ef8a12e716b112 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Fri, 15 Sep 2017 22:39:08 +0200 Subject: [PATCH 2/4] make hound happy --- mirobo/vacuum.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mirobo/vacuum.py b/mirobo/vacuum.py index 9e9d67c0f..31969bb90 100644 --- a/mirobo/vacuum.py +++ b/mirobo/vacuum.py @@ -142,14 +142,16 @@ def timer(self) -> List[Timer]: def add_timer(self, cron, command, parameters): import time ts = int(round(time.time() * 1000)) - return self.send("set_timer", [[str(ts), [cron, [command, parameters]]]]) + return self.send("set_timer", [ + [str(ts), [cron, [command, parameters]]] + ]) def delete_timer(self, timer_id: int): return self.send("del_timer", [str(timer_id)]) def update_timer(self, timer_id: int, mode): if mode != "on" and mode != "off": - raise DeviceException("update_timer needs to be either 'on' or 'off") + raise DeviceException("'on' or 'off are only allowed") return self.send("upd_timer", [str(timer_id), mode]) def dnd_status(self): From 6398796318af37abdda8f4dd0e297cd424c0ac10 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sat, 16 Sep 2017 16:45:54 +0200 Subject: [PATCH 3/4] handle commentary from the pr --- mirobo/vacuum.py | 17 ++++++++++++----- mirobo/vacuum_cli.py | 28 +++++++++++++--------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/mirobo/vacuum.py b/mirobo/vacuum.py index 31969bb90..240f00d81 100644 --- a/mirobo/vacuum.py +++ b/mirobo/vacuum.py @@ -2,6 +2,7 @@ import math import time from typing import List +import enum from .vacuumcontainers import (VacuumStatus, ConsumableStatus, CleaningSummary, CleaningDetails, Timer) @@ -14,6 +15,10 @@ class VacuumException(DeviceException): pass +class TimerState(enum.Enum): + On = "on" + Off = "off" + class Vacuum(Device): """Main class representing the vacuum.""" @@ -139,7 +144,8 @@ def timer(self) -> List[Timer]: return timers - def add_timer(self, cron, command, parameters): + def add_timer(self, cron: str, command: str, parameters: str): + """Add a timer.""" import time ts = int(round(time.time() * 1000)) return self.send("set_timer", [ @@ -147,12 +153,13 @@ def add_timer(self, cron, command, parameters): ]) def delete_timer(self, timer_id: int): + """Delete a timer.""" return self.send("del_timer", [str(timer_id)]) - def update_timer(self, timer_id: int, mode): - if mode != "on" and mode != "off": - raise DeviceException("'on' or 'off are only allowed") - return self.send("upd_timer", [str(timer_id), mode]) + def update_timer(self, timer_id: int, mode: TimerState): + if mode != TimerState.On and mode != TimerState.Off: + raise DeviceException("Only 'On' or 'Off' are allowed") + return self.send("upd_timer", [str(timer_id), mode.value]) def dnd_status(self): """Returns do-not-disturb status.""" diff --git a/mirobo/vacuum_cli.py b/mirobo/vacuum_cli.py index abd761320..65c50aa36 100644 --- a/mirobo/vacuum_cli.py +++ b/mirobo/vacuum_cli.py @@ -302,16 +302,13 @@ def timer(ctx, vac: mirobo.Vacuum): if ctx.invoked_subcommand is not None: return timers = vac.timer() + click.echo("Timezone: %s\n" % vac.timezone()) for idx, timer in enumerate(timers): color = "green" if timer.enabled else "yellow" - # Note ts == ID for changes click.echo(click.style("Timer #%s, id %s (ts: %s)" % ( idx, timer.id, timer.ts), bold=True, fg=color)) - print(" %s" % timer.cron) + click.echo(" %s" % timer.cron) min, hr, x, y, days = timer.cron.split(' ') - # hr is in gmt+8 (chinese time), TODO convert to local - if hr != '*': - hr = (int(hr) - 8) % 24 cron = "%s %s %s %s %s" % (min, hr, x, y, days) click.echo(" %s" % pretty_cron.prettify_cron(cron)) @@ -322,7 +319,7 @@ def timer(ctx, vac: mirobo.Vacuum): @click.option('--params', default='', required=False) @pass_dev def add(vac: mirobo.Vacuum, cron, command, params): - """Schedule vacuuming..""" + """Add a timer.""" click.echo(vac.add_timer(cron, command, params)) @@ -330,21 +327,22 @@ def add(vac: mirobo.Vacuum, cron, command, params): @click.argument('timer_id', type=int, required=True) @pass_dev def delete(vac: mirobo.Vacuum, timer_id): - """Delete existing schedule.""" + """Delete a timer.""" click.echo(vac.delete_timer(timer_id)) @timer.command() @click.argument('timer_id', type=int, required=True) -@click.option('--on', is_flag=True) -@click.option('--off', is_flag=True) +@click.option('--enable', is_flag=True) +@click.option('--disable', is_flag=True) @pass_dev -def update(vac: mirobo.Vacuum, timer_id, on, off): - """Update (on or off) an existing scheduled.""" - if on and not off: - vac.update_timer(timer_id, "on") - elif off and not on: - vac.update_timer(timer_id, "off") +def update(vac: mirobo.Vacuum, timer_id, enable, disable): + """Enable/disable a timer.""" + from mirobo.vacuum import TimerState + if enable and not disable: + vac.update_timer(timer_id, TimerState.On) + elif disable and not enable: + vac.update_timer(timer_id, TimerState.Off) else: click.echo("Only 'on' and 'off' are valid for timer") From b63b5d65e872a1eaf5fda698b7bb839cde92c53d Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sat, 16 Sep 2017 17:43:18 +0200 Subject: [PATCH 4/4] be consistent about --enable and --disable --- README.md | 2 +- mirobo/vacuum_cli.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c83191774..2ef6e4a0e 100644 --- a/README.md +++ b/README.md @@ -215,7 +215,7 @@ $ mirobo timer add --cron '* * * * *' Activating/deactivating an existing timer, use `mirobo timer` to get the required id. ``` -$ mirobo timer update [--off|--on] +$ mirobo timer update [--enable|--disable] ``` Deleting a timer diff --git a/mirobo/vacuum_cli.py b/mirobo/vacuum_cli.py index 65c50aa36..87b52f5c3 100644 --- a/mirobo/vacuum_cli.py +++ b/mirobo/vacuum_cli.py @@ -344,7 +344,7 @@ def update(vac: mirobo.Vacuum, timer_id, enable, disable): elif disable and not enable: vac.update_timer(timer_id, TimerState.Off) else: - click.echo("Only 'on' and 'off' are valid for timer") + click.echo("You need to specify either --enable or --disable") @cli.command()