forked from platypush/platypush
[#340] Better state management for alarms.
- Added `AlarmEnabledEvent` and `AlarmDisabledEvent`. - Added `snooze_interval` configurable both at plugin level and alarm level.
This commit is contained in:
parent
34e2a59285
commit
f27e7bb7e2
4 changed files with 54 additions and 9 deletions
|
@ -4,43 +4,54 @@ from platypush.message.event import Event
|
||||||
|
|
||||||
|
|
||||||
class AlarmEvent(Event):
|
class AlarmEvent(Event):
|
||||||
def __init__(self, name: Optional[str] = None, *args, **kwargs):
|
"""
|
||||||
|
Base class for alarm events.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, name: Optional[str] = None, **kwargs):
|
||||||
super().__init__(*args, name=name, **kwargs)
|
super().__init__(*args, name=name, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class AlarmEnabledEvent(AlarmEvent):
|
||||||
|
"""
|
||||||
|
Triggered when an alarm is enabled.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class AlarmDisabledEvent(AlarmEvent):
|
||||||
|
"""
|
||||||
|
Triggered when an alarm is disabled.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class AlarmStartedEvent(AlarmEvent):
|
class AlarmStartedEvent(AlarmEvent):
|
||||||
"""
|
"""
|
||||||
Triggered when an alarm starts.
|
Triggered when an alarm starts.
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AlarmEndedEvent(AlarmEvent):
|
class AlarmEndedEvent(AlarmEvent):
|
||||||
"""
|
"""
|
||||||
Triggered when an alarm stops.
|
Triggered when an alarm stops.
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AlarmDismissedEvent(AlarmEndedEvent):
|
class AlarmDismissedEvent(AlarmEndedEvent):
|
||||||
"""
|
"""
|
||||||
Triggered when an alarm is dismissed.
|
Triggered when an alarm is dismissed.
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AlarmSnoozedEvent(AlarmEvent):
|
class AlarmSnoozedEvent(AlarmEvent):
|
||||||
"""
|
"""
|
||||||
Triggered when an alarm is snoozed.
|
Triggered when an alarm is snoozed.
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AlarmTimeoutEvent(AlarmEndedEvent):
|
class AlarmTimeoutEvent(AlarmEndedEvent):
|
||||||
"""
|
"""
|
||||||
Triggered when an alarm times out.
|
Triggered when an alarm times out.
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -79,6 +79,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
alarms: Optional[Union[list, Dict[str, Any]]] = None,
|
alarms: Optional[Union[list, Dict[str, Any]]] = None,
|
||||||
media_plugin: Optional[str] = None,
|
media_plugin: Optional[str] = None,
|
||||||
poll_interval: Optional[float] = 5.0,
|
poll_interval: Optional[float] = 5.0,
|
||||||
|
snooze_interval: float = 300.0,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -90,8 +91,11 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
``media.gstreamer`` etc. If not specified, the first available
|
``media.gstreamer`` etc. If not specified, the first available
|
||||||
configured local media plugin will be used. This only applies to
|
configured local media plugin will be used. This only applies to
|
||||||
alarms that are configured to play an audio resource.
|
alarms that are configured to play an audio resource.
|
||||||
|
:param poll_interval: Poll interval in seconds (default: 5).
|
||||||
|
:param snooze_interval: Default snooze interval in seconds (default: 300).
|
||||||
"""
|
"""
|
||||||
super().__init__(poll_interval=poll_interval, **kwargs)
|
super().__init__(poll_interval=poll_interval, **kwargs)
|
||||||
|
self.snooze_interval = snooze_interval
|
||||||
self._db_lock = RLock()
|
self._db_lock = RLock()
|
||||||
alarms = alarms or []
|
alarms = alarms or []
|
||||||
if isinstance(alarms, dict):
|
if isinstance(alarms, dict):
|
||||||
|
@ -160,7 +164,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
self.alarms[name] = Alarm.from_db(
|
self.alarms[name] = Alarm.from_db(
|
||||||
alarm,
|
alarm,
|
||||||
stop_event=self._should_stop,
|
stop_event=self._should_stop,
|
||||||
media_plugin=self.media_plugin,
|
media_plugin=alarm.media_plugin or self.media_plugin,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _sync_alarms(self):
|
def _sync_alarms(self):
|
||||||
|
@ -240,6 +244,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
audio_file: Optional[str] = None,
|
audio_file: Optional[str] = None,
|
||||||
audio_volume: Optional[Union[int, float]] = None,
|
audio_volume: Optional[Union[int, float]] = None,
|
||||||
enabled: bool = True,
|
enabled: bool = True,
|
||||||
|
snooze_interval: Optional[float] = None,
|
||||||
) -> Alarm:
|
) -> Alarm:
|
||||||
alarm = Alarm(
|
alarm = Alarm(
|
||||||
when=when,
|
when=when,
|
||||||
|
@ -249,6 +254,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
media=media or audio_file,
|
media=media or audio_file,
|
||||||
media_plugin=self.media_plugin,
|
media_plugin=self.media_plugin,
|
||||||
audio_volume=audio_volume,
|
audio_volume=audio_volume,
|
||||||
|
snooze_interval=snooze_interval or self.snooze_interval,
|
||||||
stop_event=self._should_stop,
|
stop_event=self._should_stop,
|
||||||
on_change=self._on_alarm_update,
|
on_change=self._on_alarm_update,
|
||||||
)
|
)
|
||||||
|
@ -281,6 +287,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
self.logger.info('No alarm is running')
|
self.logger.info('No alarm is running')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
interval = interval or alarm.snooze_interval or self.snooze_interval
|
||||||
alarm.snooze(interval=interval)
|
alarm.snooze(interval=interval)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -293,6 +300,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
audio_file: Optional[str] = None,
|
audio_file: Optional[str] = None,
|
||||||
audio_volume: Optional[Union[int, float]] = None,
|
audio_volume: Optional[Union[int, float]] = None,
|
||||||
enabled: bool = True,
|
enabled: bool = True,
|
||||||
|
snooze_interval: Optional[float] = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Add a new alarm.
|
Add a new alarm.
|
||||||
|
@ -307,6 +315,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
:param media: Path of the audio file to be played.
|
:param media: Path of the audio file to be played.
|
||||||
:param audio_volume: Volume of the audio.
|
:param audio_volume: Volume of the audio.
|
||||||
:param enabled: Whether the new alarm should be enabled (default: True).
|
:param enabled: Whether the new alarm should be enabled (default: True).
|
||||||
|
:param snooze_interval: Snooze seconds before playing the alarm again.
|
||||||
:return: The newly created alarm.
|
:return: The newly created alarm.
|
||||||
"""
|
"""
|
||||||
if audio_file:
|
if audio_file:
|
||||||
|
@ -322,6 +331,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
name=name,
|
name=name,
|
||||||
enabled=enabled,
|
enabled=enabled,
|
||||||
audio_volume=audio_volume,
|
audio_volume=audio_volume,
|
||||||
|
snooze_interval=snooze_interval,
|
||||||
).to_dict()
|
).to_dict()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -343,6 +353,19 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
"""
|
"""
|
||||||
self._disable(name)
|
self._disable(name)
|
||||||
|
|
||||||
|
@action
|
||||||
|
def set_enabled(self, name: str, enabled: bool):
|
||||||
|
"""
|
||||||
|
Enable/disable an alarm.
|
||||||
|
|
||||||
|
:param name: Alarm name.
|
||||||
|
:param enabled: Whether the alarm should be enabled.
|
||||||
|
"""
|
||||||
|
if enabled:
|
||||||
|
self._enable(name)
|
||||||
|
else:
|
||||||
|
self._disable(name)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def dismiss(self):
|
def dismiss(self):
|
||||||
"""
|
"""
|
||||||
|
@ -351,7 +374,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
self._dismiss()
|
self._dismiss()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def snooze(self, interval: Optional[float] = 300.0):
|
def snooze(self, interval: Optional[float] = None):
|
||||||
"""
|
"""
|
||||||
Snooze the alarm that is currently running for the specified number of seconds.
|
Snooze the alarm that is currently running for the specified number of seconds.
|
||||||
The alarm will stop and resume again later.
|
The alarm will stop and resume again later.
|
||||||
|
|
|
@ -12,9 +12,11 @@ from platypush.context import get_bus, get_plugin
|
||||||
from platypush.entities.alarm import Alarm as AlarmDb
|
from platypush.entities.alarm import Alarm as AlarmDb
|
||||||
from platypush.message.request import Request
|
from platypush.message.request import Request
|
||||||
from platypush.message.event.alarm import (
|
from platypush.message.event.alarm import (
|
||||||
AlarmStartedEvent,
|
AlarmDisabledEvent,
|
||||||
AlarmDismissedEvent,
|
AlarmDismissedEvent,
|
||||||
|
AlarmEnabledEvent,
|
||||||
AlarmSnoozedEvent,
|
AlarmSnoozedEvent,
|
||||||
|
AlarmStartedEvent,
|
||||||
)
|
)
|
||||||
from platypush.plugins.media import MediaPlugin, PlayerState
|
from platypush.plugins.media import MediaPlugin, PlayerState
|
||||||
from platypush.procedure import Procedure
|
from platypush.procedure import Procedure
|
||||||
|
@ -145,7 +147,13 @@ class Alarm:
|
||||||
self.set_enabled(True)
|
self.set_enabled(True)
|
||||||
|
|
||||||
def set_enabled(self, enabled: bool):
|
def set_enabled(self, enabled: bool):
|
||||||
|
if enabled == self._enabled:
|
||||||
|
return
|
||||||
|
|
||||||
self._enabled = enabled
|
self._enabled = enabled
|
||||||
|
evt_type = AlarmEnabledEvent if enabled else AlarmDisabledEvent
|
||||||
|
get_bus().post(evt_type(name=self.name))
|
||||||
|
self._on_change()
|
||||||
|
|
||||||
def dismiss(self):
|
def dismiss(self):
|
||||||
self.state = AlarmState.DISMISSED
|
self.state = AlarmState.DISMISSED
|
||||||
|
@ -232,6 +240,7 @@ class Alarm:
|
||||||
sleep_time = self._runtime_snooze_interval
|
sleep_time = self._runtime_snooze_interval
|
||||||
else:
|
else:
|
||||||
self.state = AlarmState.WAITING
|
self.state = AlarmState.WAITING
|
||||||
|
self._on_change()
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
manifest:
|
manifest:
|
||||||
events:
|
events:
|
||||||
|
- platypush.message.event.alarm.AlarmDisabledEvent
|
||||||
- platypush.message.event.alarm.AlarmDismissedEvent
|
- platypush.message.event.alarm.AlarmDismissedEvent
|
||||||
|
- platypush.message.event.alarm.AlarmEnabledEvent
|
||||||
- platypush.message.event.alarm.AlarmSnoozedEvent
|
- platypush.message.event.alarm.AlarmSnoozedEvent
|
||||||
- platypush.message.event.alarm.AlarmStartedEvent
|
- platypush.message.event.alarm.AlarmStartedEvent
|
||||||
- platypush.message.event.alarm.AlarmTimeoutEvent
|
- platypush.message.event.alarm.AlarmTimeoutEvent
|
||||||
|
|
Loading…
Reference in a new issue