forked from platypush/platypush
[alarm] Added dismiss_interval
configuration.
This commit is contained in:
parent
250858fe99
commit
52fd64a162
5 changed files with 110 additions and 20 deletions
|
@ -138,8 +138,8 @@
|
||||||
<br />
|
<br />
|
||||||
<span class="subtext">
|
<span class="subtext">
|
||||||
<span class="text">
|
<span class="text">
|
||||||
How long the interval should be paused after being triggered and
|
How long the alarm should be paused after being triggered and
|
||||||
snoozed.
|
manually snoozed.
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -150,6 +150,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row item">
|
||||||
|
<div class="name">
|
||||||
|
<label>
|
||||||
|
<i class="icon fas fa-xmark" />
|
||||||
|
Dismiss timeout
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<span class="subtext">
|
||||||
|
<span class="text">
|
||||||
|
How long the alarm should run before being automatically dismissed.
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="value">
|
||||||
|
<TimeInterval :value="editForm.dismiss_interval"
|
||||||
|
@input="editForm.dismiss_interval = $event" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row item">
|
<div class="row item">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<label>
|
<label>
|
||||||
|
@ -247,6 +267,7 @@ export default {
|
||||||
'media_plugin',
|
'media_plugin',
|
||||||
'name',
|
'name',
|
||||||
'snooze_interval',
|
'snooze_interval',
|
||||||
|
'dismiss_interval',
|
||||||
'when',
|
'when',
|
||||||
].forEach(key => {
|
].forEach(key => {
|
||||||
if (this.editForm[key] !== this.value[key])
|
if (this.editForm[key] !== this.value[key])
|
||||||
|
@ -258,6 +279,17 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
actionsToArgs(actions) {
|
||||||
|
return actions?.map(action => {
|
||||||
|
if (action.name) {
|
||||||
|
action.action = action.name
|
||||||
|
delete action.name
|
||||||
|
}
|
||||||
|
|
||||||
|
return action
|
||||||
|
}) ?? []
|
||||||
|
},
|
||||||
|
|
||||||
onWhenInput(value, type) {
|
onWhenInput(value, type) {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return
|
return
|
||||||
|
@ -302,7 +334,8 @@ export default {
|
||||||
media_plugin: this.editForm.media_plugin,
|
media_plugin: this.editForm.media_plugin,
|
||||||
audio_volume: this.editForm.audio_volume,
|
audio_volume: this.editForm.audio_volume,
|
||||||
snooze_interval: this.editForm.snooze_interval,
|
snooze_interval: this.editForm.snooze_interval,
|
||||||
actions: this.editForm.actions,
|
dismiss_interval: this.editForm.dismiss_interval,
|
||||||
|
actions: this.actionsToArgs(this.editForm.actions),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
action = 'alarm.edit'
|
action = 'alarm.edit'
|
||||||
|
@ -311,6 +344,9 @@ export default {
|
||||||
...this.changes,
|
...this.changes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.changes.actions)
|
||||||
|
args.actions = this.actionsToArgs(this.changes.actions)
|
||||||
|
|
||||||
if (this.changes.name != null) {
|
if (this.changes.name != null) {
|
||||||
args.name = this.value.name
|
args.name = this.value.name
|
||||||
args.new_name = this.changes.name
|
args.new_name = this.changes.name
|
||||||
|
|
|
@ -26,6 +26,7 @@ if not is_defined('alarm'):
|
||||||
media_plugin = Column(String, nullable=True)
|
media_plugin = Column(String, nullable=True)
|
||||||
audio_volume = Column(Integer, nullable=True)
|
audio_volume = Column(Integer, nullable=True)
|
||||||
snooze_interval = Column(Integer, nullable=True)
|
snooze_interval = Column(Integer, nullable=True)
|
||||||
|
dismiss_interval = Column(Integer, nullable=True)
|
||||||
actions = Column(JSON, nullable=True)
|
actions = Column(JSON, nullable=True)
|
||||||
static = Column(Boolean, nullable=False, default=False)
|
static = Column(Boolean, nullable=False, default=False)
|
||||||
condition_type = Column(String, nullable=False)
|
condition_type = Column(String, nullable=False)
|
||||||
|
|
|
@ -77,14 +77,15 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
alarms: Optional[Union[list, Dict[str, Any]]] = None,
|
alarms: Optional[Union[List[dict], Dict[str, dict]]] = None,
|
||||||
media_plugin: Optional[str] = None,
|
media_plugin: Optional[str] = None,
|
||||||
poll_interval: Optional[float] = 5.0,
|
poll_interval: Optional[float] = 2.0,
|
||||||
snooze_interval: float = 300.0,
|
snooze_interval: float = 300.0,
|
||||||
|
dismiss_interval: float = 300.0,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
:param alarms: List or name->value dict with the configured alarms. Example:
|
:param alarms: List or name->value dict with the configured alarms.
|
||||||
:param media_plugin: Media plugin (instance of
|
:param media_plugin: Media plugin (instance of
|
||||||
:class:`platypush.plugins.media.MediaPlugin`) that will be used to
|
:class:`platypush.plugins.media.MediaPlugin`) that will be used to
|
||||||
play the alarm audio. It needs to be a supported local media
|
play the alarm audio. It needs to be a supported local media
|
||||||
|
@ -92,11 +93,18 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
``media.gstreamer``, ``sound``, etc. If not specified, the first
|
``media.gstreamer``, ``sound``, etc. If not specified, the first
|
||||||
available configured local media plugin will be used. This only
|
available configured local media plugin will be used. This only
|
||||||
applies to alarms that are configured to play an audio resource.
|
applies to alarms that are configured to play an audio resource.
|
||||||
:param poll_interval: Poll interval in seconds (default: 5).
|
:param poll_interval: (Internal) poll interval, in seconds (default: 2).
|
||||||
:param snooze_interval: Default snooze interval in seconds (default: 300).
|
:param snooze_interval: Default snooze interval in seconds. This
|
||||||
|
specifies how long to wait between alarm runs when an alarm is
|
||||||
|
dismissed (default: 300).
|
||||||
|
:param dismiss_interval: Default dismiss interval in seconds. This
|
||||||
|
specifies how long an alarm should run without being manually
|
||||||
|
snoozed/dismissed before being automatically dismissed (default:
|
||||||
|
300).
|
||||||
"""
|
"""
|
||||||
super().__init__(poll_interval=poll_interval, **kwargs)
|
super().__init__(poll_interval=poll_interval, **kwargs)
|
||||||
self.snooze_interval = snooze_interval
|
self.snooze_interval = snooze_interval
|
||||||
|
self.dismiss_interval = dismiss_interval
|
||||||
self._db_lock = RLock()
|
self._db_lock = RLock()
|
||||||
alarms = alarms or []
|
alarms = alarms or []
|
||||||
if isinstance(alarms, dict):
|
if isinstance(alarms, dict):
|
||||||
|
@ -259,6 +267,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
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,
|
snooze_interval: Optional[float] = None,
|
||||||
|
dismiss_interval: Optional[float] = None,
|
||||||
) -> Alarm:
|
) -> Alarm:
|
||||||
alarm = Alarm(
|
alarm = Alarm(
|
||||||
when=when,
|
when=when,
|
||||||
|
@ -269,6 +278,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
media_plugin=media_plugin or self.media_plugin,
|
media_plugin=media_plugin or self.media_plugin,
|
||||||
audio_volume=audio_volume,
|
audio_volume=audio_volume,
|
||||||
snooze_interval=snooze_interval or self.snooze_interval,
|
snooze_interval=snooze_interval or self.snooze_interval,
|
||||||
|
dismiss_interval=dismiss_interval or self.dismiss_interval,
|
||||||
stop_event=self._should_stop,
|
stop_event=self._should_stop,
|
||||||
on_change=self._on_alarm_update,
|
on_change=self._on_alarm_update,
|
||||||
)
|
)
|
||||||
|
@ -316,6 +326,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
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,
|
snooze_interval: Optional[float] = None,
|
||||||
|
dismiss_interval: Optional[float] = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Add a new alarm.
|
Add a new alarm.
|
||||||
|
@ -332,6 +343,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
: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.
|
:param snooze_interval: Snooze seconds before playing the alarm again.
|
||||||
|
:param dismiss_interval: Dismiss seconds before stopping the alarm.
|
||||||
:return: The newly created alarm.
|
:return: The newly created alarm.
|
||||||
"""
|
"""
|
||||||
if audio_file:
|
if audio_file:
|
||||||
|
@ -349,6 +361,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
enabled=enabled,
|
enabled=enabled,
|
||||||
audio_volume=audio_volume,
|
audio_volume=audio_volume,
|
||||||
snooze_interval=snooze_interval,
|
snooze_interval=snooze_interval,
|
||||||
|
dismiss_interval=dismiss_interval,
|
||||||
).to_dict()
|
).to_dict()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -363,6 +376,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
audio_volume: Optional[Union[int, float]] = None,
|
audio_volume: Optional[Union[int, float]] = None,
|
||||||
enabled: Optional[bool] = None,
|
enabled: Optional[bool] = None,
|
||||||
snooze_interval: Optional[float] = None,
|
snooze_interval: Optional[float] = None,
|
||||||
|
dismiss_interval: Optional[float] = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Edit an existing alarm.
|
Edit an existing alarm.
|
||||||
|
@ -383,6 +397,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
:param audio_volume: Volume of the audio.
|
:param audio_volume: Volume of the audio.
|
||||||
:param enabled: Whether the new alarm should be enabled.
|
:param enabled: Whether the new alarm should be enabled.
|
||||||
:param snooze_interval: Snooze seconds before playing the alarm again.
|
:param snooze_interval: Snooze seconds before playing the alarm again.
|
||||||
|
:param dismiss_interval: Dismiss seconds before stopping the alarm.
|
||||||
:return: The modified alarm.
|
:return: The modified alarm.
|
||||||
"""
|
"""
|
||||||
alarm = self._get_alarm(name)
|
alarm = self._get_alarm(name)
|
||||||
|
@ -410,6 +425,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
if audio_volume is not None
|
if audio_volume is not None
|
||||||
else alarm.audio_volume,
|
else alarm.audio_volume,
|
||||||
snooze_interval=snooze_interval or alarm.snooze_interval,
|
snooze_interval=snooze_interval or alarm.snooze_interval,
|
||||||
|
dismiss_interval=dismiss_interval or alarm.dismiss_interval,
|
||||||
).to_dict()
|
).to_dict()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -419,15 +435,25 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
|
|
||||||
:param name: Alarm name.
|
:param name: Alarm name.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
alarm = self._get_alarm(name)
|
alarm = self._get_alarm(name)
|
||||||
|
except AssertionError:
|
||||||
|
self.logger.warning('Alarm %s does not exist', name)
|
||||||
|
return
|
||||||
|
|
||||||
assert not alarm.static, (
|
assert not alarm.static, (
|
||||||
f'Alarm {name} is statically defined in the configuration, '
|
f'Alarm {name} is statically defined in the configuration, '
|
||||||
'cannot overwrite it programmatically'
|
'cannot overwrite it programmatically'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
alarm.stop()
|
||||||
|
|
||||||
with self._db.get_session() as session:
|
with self._db.get_session() as session:
|
||||||
db_alarm = session.query(DbAlarm).filter_by(name=name).first()
|
db_alarm = session.query(DbAlarm).filter_by(name=name).first()
|
||||||
assert db_alarm, f'Alarm {name} does not exist'
|
if not db_alarm:
|
||||||
|
self.logger.warning('Alarm %s does not exist', name)
|
||||||
|
return
|
||||||
|
|
||||||
self._clear_alarm(db_alarm, session)
|
self._clear_alarm(db_alarm, session)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -507,6 +533,7 @@ class AlarmPlugin(RunnablePlugin, EntityManager):
|
||||||
"media_plugin": "media.vlc",
|
"media_plugin": "media.vlc",
|
||||||
"audio_volume": 10,
|
"audio_volume": 10,
|
||||||
"snooze_interval": 300,
|
"snooze_interval": 300,
|
||||||
|
"dismiss_interval": 300,
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"action": "tts.say",
|
"action": "tts.say",
|
||||||
|
|
|
@ -61,7 +61,8 @@ class Alarm:
|
||||||
media_plugin: Optional[str] = None,
|
media_plugin: Optional[str] = None,
|
||||||
audio_volume: Optional[Union[int, float]] = None,
|
audio_volume: Optional[Union[int, float]] = None,
|
||||||
snooze_interval: float = 300,
|
snooze_interval: float = 300,
|
||||||
poll_interval: float = 5,
|
dismiss_interval: float = 300,
|
||||||
|
poll_interval: float = 2,
|
||||||
enabled: bool = True,
|
enabled: bool = True,
|
||||||
static: bool = False,
|
static: bool = False,
|
||||||
stop_event: Optional[threading.Event] = None,
|
stop_event: Optional[threading.Event] = None,
|
||||||
|
@ -75,6 +76,7 @@ class Alarm:
|
||||||
self.media_plugin = media_plugin
|
self.media_plugin = media_plugin
|
||||||
self.audio_volume = audio_volume
|
self.audio_volume = audio_volume
|
||||||
self.snooze_interval = snooze_interval
|
self.snooze_interval = snooze_interval
|
||||||
|
self.dismiss_interval = dismiss_interval
|
||||||
self.state = AlarmState.UNKNOWN
|
self.state = AlarmState.UNKNOWN
|
||||||
self.timer: Optional[threading.Timer] = None
|
self.timer: Optional[threading.Timer] = None
|
||||||
self.static = static
|
self.static = static
|
||||||
|
@ -91,6 +93,7 @@ class Alarm:
|
||||||
self.stop_event = stop_event or threading.Event()
|
self.stop_event = stop_event or threading.Event()
|
||||||
self.poll_interval = poll_interval
|
self.poll_interval = poll_interval
|
||||||
self.on_change = on_change
|
self.on_change = on_change
|
||||||
|
self._dismiss_timer: Optional[threading.Timer] = None
|
||||||
|
|
||||||
def _on_change(self):
|
def _on_change(self):
|
||||||
if self.on_change:
|
if self.on_change:
|
||||||
|
@ -209,6 +212,7 @@ class Alarm:
|
||||||
def dismiss(self):
|
def dismiss(self):
|
||||||
self.state = AlarmState.DISMISSED
|
self.state = AlarmState.DISMISSED
|
||||||
self.stop_audio()
|
self.stop_audio()
|
||||||
|
self._clear_dismiss_timer()
|
||||||
get_bus().post(AlarmDismissedEvent(name=self.name))
|
get_bus().post(AlarmDismissedEvent(name=self.name))
|
||||||
self._on_change()
|
self._on_change()
|
||||||
|
|
||||||
|
@ -216,6 +220,7 @@ class Alarm:
|
||||||
self._runtime_snooze_interval = interval or self.snooze_interval
|
self._runtime_snooze_interval = interval or self.snooze_interval
|
||||||
self.state = AlarmState.SNOOZED
|
self.state = AlarmState.SNOOZED
|
||||||
self.stop_audio()
|
self.stop_audio()
|
||||||
|
self._clear_dismiss_timer()
|
||||||
get_bus().post(
|
get_bus().post(
|
||||||
AlarmSnoozedEvent(name=self.name, interval=self._runtime_snooze_interval)
|
AlarmSnoozedEvent(name=self.name, interval=self._runtime_snooze_interval)
|
||||||
)
|
)
|
||||||
|
@ -230,19 +235,27 @@ class Alarm:
|
||||||
return
|
return
|
||||||
|
|
||||||
interval = next_run - time.time()
|
interval = next_run - time.time()
|
||||||
|
self.state = AlarmState.WAITING
|
||||||
self.timer = threading.Timer(interval, self.alarm_callback)
|
self.timer = threading.Timer(interval, self.alarm_callback)
|
||||||
self.timer.start()
|
self.timer.start()
|
||||||
self.state = AlarmState.WAITING
|
self._clear_dismiss_timer()
|
||||||
self._on_change()
|
self._on_change()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.state = AlarmState.SHUTDOWN
|
self.state = AlarmState.SHUTDOWN
|
||||||
|
self.stop_audio()
|
||||||
|
|
||||||
if self.timer:
|
if self.timer:
|
||||||
self.timer.cancel()
|
self.timer.cancel()
|
||||||
self.timer = None
|
self.timer = None
|
||||||
|
|
||||||
self._on_change()
|
self._on_change()
|
||||||
|
|
||||||
|
def _clear_dismiss_timer(self):
|
||||||
|
if self._dismiss_timer:
|
||||||
|
self._dismiss_timer.cancel()
|
||||||
|
self._dismiss_timer = None
|
||||||
|
|
||||||
def _get_media_plugin(self) -> MediaPlugin:
|
def _get_media_plugin(self) -> MediaPlugin:
|
||||||
plugin = get_plugin(self.media_plugin)
|
plugin = get_plugin(self.media_plugin)
|
||||||
assert plugin and isinstance(plugin, MediaPlugin), (
|
assert plugin and isinstance(plugin, MediaPlugin), (
|
||||||
|
@ -265,9 +278,11 @@ class Alarm:
|
||||||
def stop_audio(self):
|
def stop_audio(self):
|
||||||
self._get_media_plugin().stop()
|
self._get_media_plugin().stop()
|
||||||
|
|
||||||
def alarm_callback(self):
|
def _on_start(self):
|
||||||
while not self.should_stop():
|
if self.state != AlarmState.RUNNING:
|
||||||
if self.is_enabled():
|
self._dismiss_timer = threading.Timer(self.dismiss_interval, self.dismiss)
|
||||||
|
self._dismiss_timer.start()
|
||||||
|
|
||||||
self.state = AlarmState.RUNNING
|
self.state = AlarmState.RUNNING
|
||||||
get_bus().post(AlarmStartedEvent(name=self.name))
|
get_bus().post(AlarmStartedEvent(name=self.name))
|
||||||
self._on_change()
|
self._on_change()
|
||||||
|
@ -275,6 +290,11 @@ class Alarm:
|
||||||
self.play_audio()
|
self.play_audio()
|
||||||
|
|
||||||
self.actions.execute()
|
self.actions.execute()
|
||||||
|
|
||||||
|
def alarm_callback(self):
|
||||||
|
while not self.should_stop():
|
||||||
|
if self.is_enabled():
|
||||||
|
self._on_start()
|
||||||
elif self.state != AlarmState.WAITING:
|
elif self.state != AlarmState.WAITING:
|
||||||
self.state = AlarmState.WAITING
|
self.state = AlarmState.WAITING
|
||||||
self._on_change()
|
self._on_change()
|
||||||
|
@ -339,6 +359,7 @@ class Alarm:
|
||||||
'media_plugin': self.media_plugin,
|
'media_plugin': self.media_plugin,
|
||||||
'audio_volume': self.audio_volume,
|
'audio_volume': self.audio_volume,
|
||||||
'snooze_interval': self.snooze_interval,
|
'snooze_interval': self.snooze_interval,
|
||||||
|
'dismiss_interval': self.dismiss_interval,
|
||||||
'actions': self.actions.requests,
|
'actions': self.actions.requests,
|
||||||
'static': self.static,
|
'static': self.static,
|
||||||
'condition_type': self.condition_type.value,
|
'condition_type': self.condition_type.value,
|
||||||
|
@ -354,6 +375,7 @@ class Alarm:
|
||||||
audio_volume=alarm.audio_volume, # type: ignore
|
audio_volume=alarm.audio_volume, # type: ignore
|
||||||
actions=alarm.actions, # type: ignore
|
actions=alarm.actions, # type: ignore
|
||||||
snooze_interval=alarm.snooze_interval, # type: ignore
|
snooze_interval=alarm.snooze_interval, # type: ignore
|
||||||
|
dismiss_interval=alarm.dismiss_interval, # type: ignore
|
||||||
enabled=bool(alarm.enabled),
|
enabled=bool(alarm.enabled),
|
||||||
static=bool(alarm.static),
|
static=bool(alarm.static),
|
||||||
state=getattr(AlarmState, str(alarm.state)),
|
state=getattr(AlarmState, str(alarm.state)),
|
||||||
|
@ -375,6 +397,7 @@ class Alarm:
|
||||||
for req in self.actions.requests
|
for req in self.actions.requests
|
||||||
],
|
],
|
||||||
snooze_interval=self.snooze_interval,
|
snooze_interval=self.snooze_interval,
|
||||||
|
dismiss_interval=self.dismiss_interval,
|
||||||
enabled=self.is_enabled(),
|
enabled=self.is_enabled(),
|
||||||
static=self.static,
|
static=self.static,
|
||||||
condition_type=self.condition_type.value,
|
condition_type=self.condition_type.value,
|
||||||
|
|
|
@ -238,7 +238,10 @@ class MediaVlcPlugin(MediaPlugin):
|
||||||
def quit(self, *_, **__):
|
def quit(self, *_, **__):
|
||||||
"""Quit the player (same as `stop`)"""
|
"""Quit the player (same as `stop`)"""
|
||||||
with self._stop_lock:
|
with self._stop_lock:
|
||||||
assert self._player, 'No vlc instance is running'
|
if not self._player:
|
||||||
|
self.logger.warning('No vlc instance is running')
|
||||||
|
return self.status()
|
||||||
|
|
||||||
self._player.stop()
|
self._player.stop()
|
||||||
self._on_stop_event.wait(timeout=5)
|
self._on_stop_event.wait(timeout=5)
|
||||||
self._reset_state()
|
self._reset_state()
|
||||||
|
|
Loading…
Reference in a new issue