diff --git a/owrx/connection.py b/owrx/connection.py index ce7b795..fe5ac17 100644 --- a/owrx/connection.py +++ b/owrx/connection.py @@ -161,8 +161,9 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient): modes = Modes.getModes() self.write_modes(modes) + self.configSubs.append(SdrService.getActiveSources().wire(self._onSdrDeviceChanges)) + self.configSubs.append(SdrService.getAvailableProfiles().wire(self._sendProfiles)) self._sendProfiles() - SdrService.getActiveSources().wire(self._onSdrDeviceChanges) CpuUsageThread.getSharedInstance().add_client(self) @@ -240,17 +241,12 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient): return SdrClientClass.USER def _onSdrDeviceChanges(self, changes): - self._sendProfiles() # restart the client if an sdr has become available if self.sdr is None and any(s is not PropertyDeleted for s in changes.values()): self.setSdr() - def _sendProfiles(self): - profiles = [ - {"name": s.getName() + " " + p["name"], "id": sid + "|" + pid} - for (sid, s) in SdrService.getActiveSources().items() - for (pid, p) in s.getProfiles().items() - ] + def _sendProfiles(self, *args): + profiles = [{"id": pid, "name": name} for pid, name in SdrService.getAvailableProfiles().items()] self.write_profiles(profiles) def handleTextMessage(self, conn, message): diff --git a/owrx/sdr.py b/owrx/sdr.py index 9a177d4..e17856d 100644 --- a/owrx/sdr.py +++ b/owrx/sdr.py @@ -145,9 +145,47 @@ class ActiveSdrSources(PropertyReadOnly): del self._layer[key] +class AvailableProfiles(PropertyReadOnly): + def __init__(self, pm: PropertyManager): + self.subscriptions = {} + self._layer = PropertyLayer() + super().__init__(self._layer) + for key, value in pm.items(): + self._addSource(key, value) + pm.wire(self.handleSdrDeviceChange) + + def handleSdrDeviceChange(self, changes): + for key, value in changes.items(): + if value is PropertyDeleted: + self._removeSource(key) + else: + self._addSource(key, value) + + def handleProfileChange(self, source_id, source: SdrSource, changes): + for key, value in changes.items(): + if value is PropertyDeleted: + del self._layer["{}|{}".format(source_id, key)] + else: + self._layer["{}|{}".format(source_id, key)] = "{} {}".format(source.getName(), value["name"]) + + def _addSource(self, key, source: SdrSource): + for pid, p in source.getProfiles().items(): + self._layer["{}|{}".format(key, pid)] = "{} {}".format(source.getName(), p["name"]) + self.subscriptions[key] = source.getProfiles().wire(partial(self.handleProfileChange, key, source)) + + def _removeSource(self, key): + for profile_id in list(self._layer.keys()): + if profile_id.startswith("{}|".format(key)): + del self._layer[profile_id] + if key in self.subscriptions: + self.subscriptions[key].cancel() + del self.subscriptions[key] + + class SdrService(object): sources = None activeSources = None + availableProfiles = None @staticmethod def getFirstSource(): @@ -177,3 +215,9 @@ class SdrService(object): if SdrService.activeSources is None: SdrService.activeSources = ActiveSdrSources(SdrService.getAllSources()) return SdrService.activeSources + + @staticmethod + def getAvailableProfiles(): + if SdrService.availableProfiles is None: + SdrService.availableProfiles = AvailableProfiles(SdrService.getActiveSources()) + return SdrService.availableProfiles