activate more scheduler and service settings
This commit is contained in:
parent
0231d98ab8
commit
4e7f02fc2c
@ -9,7 +9,7 @@ from owrx.js8 import Js8Parser
|
|||||||
from owrx.config.core import CoreConfig
|
from owrx.config.core import CoreConfig
|
||||||
from owrx.config import Config
|
from owrx.config import Config
|
||||||
from owrx.source.resampler import Resampler
|
from owrx.source.resampler import Resampler
|
||||||
from owrx.property import PropertyLayer
|
from owrx.property import PropertyLayer, PropertyDeleted
|
||||||
from js8py import Js8Frame
|
from js8py import Js8Frame
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
from .schedule import ServiceScheduler
|
from .schedule import ServiceScheduler
|
||||||
@ -66,13 +66,42 @@ class ServiceHandler(SdrSourceEventClient):
|
|||||||
self.services = []
|
self.services = []
|
||||||
self.source = source
|
self.source = source
|
||||||
self.startupTimer = None
|
self.startupTimer = None
|
||||||
self.scheduler = None
|
self.activitySub = None
|
||||||
|
self.running = False
|
||||||
|
props = self.source.getProps()
|
||||||
|
self.enabledSub = props.wireProperty("services", self._receiveEvent)
|
||||||
|
# need to call _start() manually if property is not set since the default is True, but the initial call is only
|
||||||
|
# made if the property is present
|
||||||
|
if "services" not in props:
|
||||||
|
self._start()
|
||||||
|
|
||||||
|
def _receiveEvent(self, state):
|
||||||
|
# deletion means fall back to default, which is True
|
||||||
|
if state is PropertyDeleted:
|
||||||
|
state = True
|
||||||
|
if self.running == state:
|
||||||
|
return
|
||||||
|
if state:
|
||||||
|
self._start()
|
||||||
|
else:
|
||||||
|
self._stop()
|
||||||
|
|
||||||
|
def _start(self):
|
||||||
|
self.running = True
|
||||||
self.source.addClient(self)
|
self.source.addClient(self)
|
||||||
props = self.source.getProps()
|
props = self.source.getProps()
|
||||||
self.subscriptions = [props.filter("center_freq", "samp_rate").wire(self.onFrequencyChange)]
|
self.activitySub = props.filter("center_freq", "samp_rate").wire(self.onFrequencyChange)
|
||||||
if self.source.isAvailable():
|
if self.source.isAvailable():
|
||||||
self.scheduleServiceStartup()
|
self.scheduleServiceStartup()
|
||||||
self.scheduler = ServiceScheduler(self.source)
|
|
||||||
|
def _stop(self):
|
||||||
|
if self.activitySub is not None:
|
||||||
|
self.activitySub.cancel()
|
||||||
|
self.activitySub = None
|
||||||
|
self._cancelStartupTimer()
|
||||||
|
self.source.removeClient(self)
|
||||||
|
self.stopServices()
|
||||||
|
self.running = False
|
||||||
|
|
||||||
def getClientClass(self) -> SdrClientClass:
|
def getClientClass(self) -> SdrClientClass:
|
||||||
return SdrClientClass.INACTIVE
|
return SdrClientClass.INACTIVE
|
||||||
@ -86,8 +115,6 @@ class ServiceHandler(SdrSourceEventClient):
|
|||||||
elif state is SdrSourceState.FAILED:
|
elif state is SdrSourceState.FAILED:
|
||||||
logger.debug("sdr source failed; stopping services.")
|
logger.debug("sdr source failed; stopping services.")
|
||||||
self.stopServices()
|
self.stopServices()
|
||||||
if self.scheduler:
|
|
||||||
self.scheduler.shutdown()
|
|
||||||
|
|
||||||
def onBusyStateChange(self, state: SdrBusyState):
|
def onBusyStateChange(self, state: SdrBusyState):
|
||||||
pass
|
pass
|
||||||
@ -98,12 +125,10 @@ class ServiceHandler(SdrSourceEventClient):
|
|||||||
return mode in configured and mode in available
|
return mode in configured and mode in available
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
while self.subscriptions:
|
self._stop()
|
||||||
self.subscriptions.pop().cancel()
|
if self.enabledSub is not None:
|
||||||
self.stopServices()
|
self.enabledSub.cancel()
|
||||||
self.source.removeClient(self)
|
self.enabledSub = None
|
||||||
if self.scheduler:
|
|
||||||
self.scheduler.shutdown()
|
|
||||||
|
|
||||||
def stopServices(self):
|
def stopServices(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
@ -119,9 +144,13 @@ class ServiceHandler(SdrSourceEventClient):
|
|||||||
return
|
return
|
||||||
self.scheduleServiceStartup()
|
self.scheduleServiceStartup()
|
||||||
|
|
||||||
def scheduleServiceStartup(self):
|
def _cancelStartupTimer(self):
|
||||||
if self.startupTimer:
|
if self.startupTimer:
|
||||||
self.startupTimer.cancel()
|
self.startupTimer.cancel()
|
||||||
|
self.startupTimer = None
|
||||||
|
|
||||||
|
def scheduleServiceStartup(self):
|
||||||
|
self._cancelStartupTimer()
|
||||||
self.startupTimer = threading.Timer(10, self.updateServices)
|
self.startupTimer = threading.Timer(10, self.updateServices)
|
||||||
self.startupTimer.start()
|
self.startupTimer.start()
|
||||||
|
|
||||||
@ -281,23 +310,27 @@ class Js8Handler(object):
|
|||||||
|
|
||||||
class Services(object):
|
class Services(object):
|
||||||
handlers = []
|
handlers = []
|
||||||
|
schedulers = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start():
|
def start():
|
||||||
config = Config.get()
|
config = Config.get()
|
||||||
config.wireProperty("services_enabled", Services._receiveEvent)
|
config.wireProperty("services_enabled", Services._receiveEvent)
|
||||||
|
for source in SdrService.getSources().values():
|
||||||
|
Services.schedulers.append(ServiceScheduler(source))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _receiveEvent(state):
|
def _receiveEvent(state):
|
||||||
if state:
|
if state:
|
||||||
for source in SdrService.getSources().values():
|
for source in SdrService.getSources().values():
|
||||||
props = source.getProps()
|
Services.handlers.append(ServiceHandler(source))
|
||||||
if "services" not in props or props["services"] is not False:
|
|
||||||
Services.handlers.append(ServiceHandler(source))
|
|
||||||
else:
|
else:
|
||||||
Services.stop()
|
while Services.handlers:
|
||||||
|
Services.handlers.pop().shutdown()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def stop():
|
def stop():
|
||||||
while Services.handlers:
|
while Services.handlers:
|
||||||
Services.handlers.pop().shutdown()
|
Services.handlers.pop().shutdown()
|
||||||
|
while Services.schedulers:
|
||||||
|
Services.schedulers.pop().shutdown()
|
||||||
|
@ -209,10 +209,13 @@ class ServiceScheduler(SdrSourceEventClient):
|
|||||||
def __init__(self, source):
|
def __init__(self, source):
|
||||||
self.source = source
|
self.source = source
|
||||||
self.selectionTimer = None
|
self.selectionTimer = None
|
||||||
|
self.currentProfile = None
|
||||||
|
self.source.addClient(self)
|
||||||
self.schedule = None
|
self.schedule = None
|
||||||
props = self.source.getProps()
|
props = self.source.getProps()
|
||||||
props.filter("center_freq", "samp_rate").wire(self.onFrequencyChange)
|
self.subscriptions = []
|
||||||
props.wireProperty("scheduler", self.parseSchedule)
|
self.subscriptions.append(props.filter("center_freq", "samp_rate").wire(self.onFrequencyChange))
|
||||||
|
self.subscriptions.append(props.wireProperty("scheduler", self.parseSchedule))
|
||||||
# wireProperty calls parseSchedule with the initial value
|
# wireProperty calls parseSchedule with the initial value
|
||||||
# self.parseSchedule()
|
# self.parseSchedule()
|
||||||
|
|
||||||
@ -222,6 +225,8 @@ class ServiceScheduler(SdrSourceEventClient):
|
|||||||
self.scheduleSelection()
|
self.scheduleSelection()
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
|
while self.subscriptions:
|
||||||
|
self.subscriptions.pop().cancel()
|
||||||
self.cancelTimer()
|
self.cancelTimer()
|
||||||
self.source.removeClient(self)
|
self.source.removeClient(self)
|
||||||
|
|
||||||
@ -241,13 +246,16 @@ class ServiceScheduler(SdrSourceEventClient):
|
|||||||
self.selectionTimer.cancel()
|
self.selectionTimer.cancel()
|
||||||
|
|
||||||
def getClientClass(self) -> SdrClientClass:
|
def getClientClass(self) -> SdrClientClass:
|
||||||
return SdrClientClass.BACKGROUND
|
if self.currentProfile is None:
|
||||||
|
return SdrClientClass.INACTIVE
|
||||||
|
else:
|
||||||
|
return SdrClientClass.BACKGROUND
|
||||||
|
|
||||||
def onStateChange(self, state: SdrSourceState):
|
def onStateChange(self, state: SdrSourceState):
|
||||||
if state is SdrSourceState.STOPPING:
|
if state is SdrSourceState.STOPPING:
|
||||||
self.scheduleSelection()
|
self.scheduleSelection()
|
||||||
elif state is SdrSourceState.FAILED:
|
elif state is SdrSourceState.FAILED:
|
||||||
self.cancelTimer()
|
self.shutdown()
|
||||||
|
|
||||||
def onBusyStateChange(self, state: SdrBusyState):
|
def onBusyStateChange(self, state: SdrBusyState):
|
||||||
if state is SdrBusyState.IDLE:
|
if state is SdrBusyState.IDLE:
|
||||||
@ -262,17 +270,15 @@ class ServiceScheduler(SdrSourceEventClient):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if self.schedule is None:
|
if self.schedule is None:
|
||||||
logger.debug("no active schedule. releasing source...")
|
self.currentProfile = None
|
||||||
self.source.removeClient(self)
|
logger.debug("no active schedule, scheduler standing by for external events.")
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.debug("source seems to be idle, selecting profile for background services")
|
logger.debug("source seems to be idle, selecting profile for background services")
|
||||||
entry = self.schedule.getCurrentEntry()
|
self.currentProfile = entry = self.schedule.getCurrentEntry()
|
||||||
|
|
||||||
if entry is None:
|
if entry is None:
|
||||||
logger.debug("schedule did not return a current profile. releasing source...")
|
logger.debug("schedule did not return a current profile. checking next (future) entry...")
|
||||||
self.source.removeClient(self)
|
|
||||||
logger.debug("checking next (future) entry...")
|
|
||||||
nextEntry = self.schedule.getNextEntry()
|
nextEntry = self.schedule.getNextEntry()
|
||||||
if nextEntry is not None:
|
if nextEntry is not None:
|
||||||
self.scheduleSelection(nextEntry.getNextActivation())
|
self.scheduleSelection(nextEntry.getNextActivation())
|
||||||
@ -280,7 +286,6 @@ class ServiceScheduler(SdrSourceEventClient):
|
|||||||
logger.debug("no next entry available, scheduler standing by for external events.")
|
logger.debug("no next entry available, scheduler standing by for external events.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.source.addClient(self)
|
|
||||||
logger.debug("selected profile %s until %s", entry.getProfile(), entry.getScheduledEnd())
|
logger.debug("selected profile %s until %s", entry.getProfile(), entry.getScheduledEnd())
|
||||||
self.scheduleSelection(entry.getScheduledEnd())
|
self.scheduleSelection(entry.getScheduledEnd())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user