add profile enabled switch

This commit is contained in:
Jakob Ketterl 2023-05-23 19:31:23 +02:00
parent 18473e6964
commit 37cd8f9d7e
3 changed files with 47 additions and 13 deletions

View file

@ -402,9 +402,10 @@ class PropertyCarousel(PropertyDelegator):
self.layers[key] = value
def removeLayer(self, key):
if key in self.layers and self.layers[key] is self.pm:
self.switch()
need_switch = key in self.layers and self.layers[key] is self.pm
del self.layers[key]
if need_switch:
self.switch()
def switch(self, key=None):
before = self.pm

View file

@ -1,5 +1,5 @@
from owrx.config import Config
from owrx.source import SdrSourceEventClient
from owrx.source import SdrSourceEventClient, ProfileIsActiveFilter
from owrx.feature import FeatureDetector, UnknownFeatureException
from owrx.active.list import ActiveListTransformation, ActiveListFilter, ActiveListListener, ActiveList, ActiveListChange
@ -22,6 +22,7 @@ class ProfileNameMapper(ActiveListTransformation):
def unmonitor(self, profile):
self.subscriptions[id(profile)].cancel()
del self.subscriptions[id(profile)]
class ProfileMapper(ActiveListTransformation):
@ -36,6 +37,7 @@ class ProfileMapper(ActiveListTransformation):
def unmonitor(self, source):
self.subscriptions[id(source)].cancel()
del self.subscriptions[id(source)]
class ProfileChangeListener(ActiveListListener):
@ -49,16 +51,24 @@ class ProfileChangeListener(ActiveListListener):
class HasProfilesFilter(ActiveListFilter):
def __init__(self):
self.monitors = {}
self.profiles = {}
def predicate(self, device) -> bool:
return "profiles" in device and device["profiles"] and len(device["profiles"]) > 0
if "profiles" not in device:
return False
if id(device) not in self.profiles:
self.profiles[id(device)] = device["profiles"].filter(ProfileIsActiveFilter())
return len(self.profiles[id(device)]) > 0
def monitor(self, device, callback: callable):
self.monitors[id(device)] = monitor = ProfileChangeListener(callback)
device["profiles"].addListener(monitor)
if id(device) not in self.profiles:
self.profiles[id(device)] = device["profiles"].filter(ProfileIsActiveFilter())
self.profiles[id(device)].addListener(monitor)
def unmonitor(self, device):
device["profiles"].removeListener(self.monitors[id(device)])
self.profiles[id(device)].removeListener(self.monitors[id(device)])
del self.monitors[id(device)]
class SourceIsEnabledListener(SdrSourceEventClient):

View file

@ -12,6 +12,7 @@ from owrx.command import CommandMapper
from owrx.socket import getAvailablePort
from owrx.property import PropertyStack, PropertyLayer, PropertyFilter, PropertyCarousel, PropertyDeleted
from owrx.property.filter import ByLambda
from owrx.active.list import ActiveListFilter
from owrx.active.list import ActiveList, ActiveListListener, ActiveListChange, ActiveListIndexAdded, ActiveListIndexDeleted, ActiveListIndexUpdated
from owrx.form.input import Input, TextInput, NumberInput, CheckboxInput, ModesInput, ExponentialInput
from owrx.form.input.converter import OptionalConverter
@ -98,12 +99,14 @@ class SdrProfileCarousel(PropertyCarousel):
if "profiles" not in props:
return
for profile in props["profiles"]:
profiles = props["profiles"].filter(ProfileIsActiveFilter())
for profile in profiles:
self.addProfile(profile)
# activate first available profile
self.switch()
props["profiles"].addListener(SdrProfileCarouselListener(self))
profiles.addListener(SdrProfileCarouselListener(self))
def addProfile(self, profile):
profile_id = profile["id"]
@ -123,6 +126,21 @@ class SdrProfileCarousel(PropertyCarousel):
return super()._getDefaultLayer()
class ProfileIsActiveFilter(ActiveListFilter):
def __init__(self):
self.subscriptions = {}
def predicate(self, profile) -> bool:
return "enabled" not in profile or profile["enabled"]
def monitor(self, profile, callback: callable):
self.subscriptions[id(profile)] = profile.filter("enabled").wire(lambda _: callback())
def unmonitor(self, profile):
self.subscriptions[id(profile)].cancel()
del self.subscriptions[id(profile)]
class SdrSource(ABC):
def __init__(self, props):
self.id = props["id"] if "id" in props else None
@ -260,7 +278,7 @@ class SdrSource(ABC):
return self.getProfile(self.props["profile_id"])
def getProfiles(self):
return self.props["profiles"]
return self.props["profiles"].filter(ProfileIsActiveFilter())
def getProfile(self, profile_id):
try:
@ -599,20 +617,25 @@ class SdrDeviceDescription(object):
def getDeviceInputs(self) -> List[Input]:
keys = self.getDeviceMandatoryKeys() + self.getDeviceOptionalKeys()
return [TextInput("name", "Device name", validator=RequiredValidator())] + [
return [
TextInput("name", "Device name", validator=RequiredValidator()),
CheckboxInput("enabled", "Enable this device", converter=OptionalConverter(defaultFormValue=True)),
] + [
i for i in self.getInputs() if i.id in keys
]
def getProfileInputs(self) -> List[Input]:
keys = self.getProfileMandatoryKeys() + self.getProfileOptionalKeys()
return [TextInput("name", "Profile name", validator=RequiredValidator())] + [
return [
TextInput("name", "Profile name", validator=RequiredValidator()),
CheckboxInput("enabled", "Enable this profile", converter=OptionalConverter(defaultFormValue=True)),
] + [
i for i in self.getInputs() if i.id in keys
]
def getInputs(self) -> List[Input]:
return [
SdrDeviceTypeDisplay("type", "Device type"),
CheckboxInput("enabled", "Enable this device", converter=OptionalConverter(defaultFormValue=True)),
GainInput("rf_gain", "Device gain", self.hasAgc()),
NumberInput(
"ppm",
@ -671,7 +694,7 @@ class SdrDeviceDescription(object):
return keys
def getProfileMandatoryKeys(self):
return ["name", "center_freq", "samp_rate", "start_freq", "start_mod"]
return ["name", "enabled", "center_freq", "samp_rate", "start_freq", "start_mod"]
def getProfileOptionalKeys(self):
return [