diff --git a/owrx/connection.py b/owrx/connection.py index 6ed86c5..fb2a148 100644 --- a/owrx/connection.py +++ b/owrx/connection.py @@ -230,6 +230,11 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient): self.write_log_message('SDR device "{0}" was disabled, selecting new device'.format(self.sdr.getName())) self.setSdr() + def onShutdown(self): + logger.warning('SDR device "%s" is shutting down, selecting new device', self.sdr.getName()) + self.write_log_message('SDR device "{0}" is shutting down, selecting new device'.format(self.sdr.getName())) + self.setSdr() + def getClientClass(self) -> SdrClientClass: return SdrClientClass.USER diff --git a/owrx/dsp.py b/owrx/dsp.py index 84bc22e..647d28c 100644 --- a/owrx/dsp.py +++ b/owrx/dsp.py @@ -214,3 +214,6 @@ class DspManager(csdr.output, SdrSourceEventClient): def onFail(self): logger.debug("received onFail(), shutting down DspSource") self.dsp.stop() + + def onShutdown(self): + self.dsp.stop() diff --git a/owrx/fft.py b/owrx/fft.py index cfef176..2c8ba15 100644 --- a/owrx/fft.py +++ b/owrx/fft.py @@ -84,3 +84,6 @@ class SpectrumThread(csdr.output, SdrSourceEventClient): def onFail(self): self.dsp.stop() + + def onShutdown(self): + self.dsp.stop() diff --git a/owrx/sdr.py b/owrx/sdr.py index ceed661..9933dda 100644 --- a/owrx/sdr.py +++ b/owrx/sdr.py @@ -27,7 +27,7 @@ class MappedSdrSources(PropertyDelegator): if self.isDeviceValid(value) and key not in self: self._addSource(key, value) elif not self.isDeviceValid(value) and key in self: - self._removeSource(key) + del self[key] def _addSource(self, key, value): if self.isDeviceValid(value): @@ -38,13 +38,6 @@ class MappedSdrSources(PropertyDelegator): value["profiles"].wire(updateMethod) ] - def _removeSource(self, key): - if key in self: - self[key].stop() - for sub in self.subscriptions[key]: - sub.cancel() - del self.subscriptions[key] - def isDeviceValid(self, device): return self._hasProfiles(device) and self._sdrTypeAvailable(device) @@ -75,15 +68,23 @@ class MappedSdrSources(PropertyDelegator): cls = getattr(module, className) return cls(id, props) + def _removeSource(self, key, source): + source.shutdown() + for sub in self.subscriptions[key]: + sub.cancel() + del self.subscriptions[key] + def __setitem__(self, key, value): - if key in self: - self._removeSource(key) + source = self[key] if key in self else None super().__setitem__(key, value) + if source is not None: + self._removeSource(key, source) def __delitem__(self, key): - if key in self: - self._removeSource(key) + source = self[key] if key in self else None super().__delitem__(key) + if source is not None: + self._removeSource(key, source) class SdrService(object): diff --git a/owrx/service/__init__.py b/owrx/service/__init__.py index 5072fd5..cf76e38 100644 --- a/owrx/service/__init__.py +++ b/owrx/service/__init__.py @@ -122,6 +122,10 @@ class ServiceHandler(SdrSourceEventClient): logger.debug("sdr source failed; stopping services.") self.stopServices() + def onShutdown(self): + logger.debug("sdr source is shutting down; shutting down service handler, too.") + self.shutdown() + def onEnable(self): self._scheduleServiceStartup() diff --git a/owrx/service/schedule.py b/owrx/service/schedule.py index 4d136b3..bd6ec23 100644 --- a/owrx/service/schedule.py +++ b/owrx/service/schedule.py @@ -258,6 +258,9 @@ class ServiceScheduler(SdrSourceEventClient): def onFail(self): self.shutdown() + def onShutdown(self): + self.shutdown() + def onDisable(self): self.cancelTimer() diff --git a/owrx/source/__init__.py b/owrx/source/__init__.py index 6ac69d4..af96f27 100644 --- a/owrx/source/__init__.py +++ b/owrx/source/__init__.py @@ -56,6 +56,9 @@ class SdrSourceEventClient(object): def onFail(self): pass + def onShutdown(self): + pass + def onDisable(self): pass @@ -349,6 +352,11 @@ class SdrSource(ABC): if self.monitor: self.monitor.join() + def shutdown(self): + self.stop() + for c in self.clients.copy(): + c.onShutdown() + def getClients(self, *args): if not args: return self.clients