Support for intervals in seconds on alarm add/set

This commit is contained in:
Fabio Manganiello 2020-02-22 16:18:56 +01:00
parent f8f3d2e310
commit 0643b7fade
2 changed files with 18 additions and 8 deletions

View file

@ -57,8 +57,12 @@ class Alarm:
try:
cron = croniter.croniter(self.when, now)
return cron.get_next()
except croniter.CroniterBadCronError:
except (AttributeError, croniter.CroniterBadCronError):
try:
timestamp = datetime.datetime.fromisoformat(self.when).timestamp()
except (TypeError, ValueError):
timestamp = (datetime.datetime.now() + datetime.timedelta(seconds=int(self.when))).timestamp()
return timestamp if timestamp >= now else None
def is_enabled(self):
@ -223,8 +227,13 @@ class AlarmBackend(Backend):
def add_alarm(self, when: str, actions: list, name: Optional[str] = None, audio_file: Optional[str] = None,
enabled: bool = True) -> Alarm:
alarm = Alarm(when=when, actions=actions, name=name, enabled=enabled, audio_file=audio_file)
assert alarm.name not in self.alarms, 'Alarm {} already exists'.format(alarm.name)
alarm = Alarm(when=when, actions=actions, name=name, enabled=enabled, audio_file=audio_file,
audio_plugin=self.audio_plugin)
if alarm.name in self.alarms:
self.logger.info('Overwriting existing alarm {}'.format(alarm.name))
self.alarms[alarm.name].stop()
self.alarms[alarm.name] = alarm
self.alarms[alarm.name].start()
return self.alarms[alarm.name]

View file

@ -20,22 +20,23 @@ class AlarmPlugin(Plugin):
return get_backend('alarm')
@action
def add(self, when: str, actions: list, name: Optional[str] = None, audio_file: Optional[str] = None,
enabled: bool = True) -> str:
def add(self, when: str, actions: Optional[list] = None, name: Optional[str] = None,
audio_file: Optional[str] = None, enabled: bool = True) -> str:
"""
Add a new alarm. NOTE: alarms that aren't configured in the :class:`platypush.backend.alarm.AlarmBackend`
will only run in the current session. If you want an alarm to be permanently stored, you should configure
it in the alarm backend configuration. You may want to add an alarm dynamically if it's a one-time alarm instead
:param when: When the alarm should be executed. It can be either a cron expression (for recurrent alarms), or
a datetime string in ISO format (for one-shot alarms/timers).
a datetime string in ISO format (for one-shot alarms/timers), or an integer representing the number of
seconds before the alarm goes on (e.g. 300 for 5 minutes).
:param actions: List of actions to be executed.
:param name: Alarm name.
:param audio_file: Path of the audio file to be played.
:param enabled: Whether the new alarm should be enabled (default: True).
:return: The alarm name.
"""
alarm = self._get_backend().add_alarm(when=when, audio_file=audio_file, actions=actions,
alarm = self._get_backend().add_alarm(when=when, audio_file=audio_file, actions=actions or [],
name=name, enabled=enabled)
return alarm.name