implement first stages of active mode communication
This commit is contained in:
@ -11,6 +11,7 @@ from owrx.bookmarks import Bookmarks
|
||||
from owrx.map import Map
|
||||
from owrx.locator import Locator
|
||||
from owrx.property import PropertyStack
|
||||
from owrx.modes import Modes
|
||||
from multiprocessing import Queue
|
||||
from queue import Full
|
||||
from js8py import Js8Frame
|
||||
@ -122,6 +123,9 @@ class OpenWebRxReceiverClient(Client):
|
||||
features = FeatureDetector().feature_availability()
|
||||
self.write_features(features)
|
||||
|
||||
modes = Modes.getModes()
|
||||
self.write_modes(modes)
|
||||
|
||||
CpuUsageThread.getSharedInstance().add_client(self)
|
||||
|
||||
def __sendProfiles(self):
|
||||
@ -345,6 +349,13 @@ class OpenWebRxReceiverClient(Client):
|
||||
"mode": frame.mode
|
||||
}})
|
||||
|
||||
def write_modes(self, modes):
|
||||
self.send({"type": "modes", "value": [{
|
||||
"modulation": m.modulation,
|
||||
"name": m.name,
|
||||
"requirements": m.requirements
|
||||
} for m in modes]})
|
||||
|
||||
|
||||
class MapConnection(Client):
|
||||
def __init__(self, conn):
|
||||
|
@ -1,5 +1,5 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from owrx.service import ServiceDetector
|
||||
from owrx.modes import Modes
|
||||
from owrx.config import Config
|
||||
|
||||
|
||||
@ -196,7 +196,7 @@ class MultiCheckboxInput(Input):
|
||||
class ServicesCheckboxInput(MultiCheckboxInput):
|
||||
def __init__(self, id, label, infotext=None):
|
||||
services = [
|
||||
Option(s, s.upper()) for s in ServiceDetector.getAvailableServices()
|
||||
Option(s.modulation, s.name) for s in Modes.getAvailableServices()
|
||||
]
|
||||
super().__init__(id, label, services, infotext)
|
||||
|
||||
|
43
owrx/modes.py
Normal file
43
owrx/modes.py
Normal file
@ -0,0 +1,43 @@
|
||||
from owrx.feature import FeatureDetector
|
||||
from functools import reduce
|
||||
|
||||
|
||||
class Mode(object):
|
||||
def __init__(self, modulation, name, requirements=None, service=False):
|
||||
self.modulation = modulation
|
||||
self.name = name
|
||||
self.requirements = requirements if requirements is not None else []
|
||||
self.service = service
|
||||
|
||||
def is_available(self):
|
||||
fd = FeatureDetector()
|
||||
return reduce(
|
||||
lambda a, b: a and b, [fd.is_available(r) for r in self.requirements], True
|
||||
)
|
||||
|
||||
def is_service(self):
|
||||
return self.service
|
||||
|
||||
|
||||
class Modes(object):
|
||||
mappings = [
|
||||
Mode("ft8", "FT8", ["wsjt-x"], True),
|
||||
Mode("ft4", "FT4", ["wsjt-x"], True),
|
||||
Mode("jt65", "JT65", ["wsjt-x"], True),
|
||||
Mode("jt9", "JT9", ["wsjt-x"], True),
|
||||
Mode("wspr", "WSPR", ["wsjt-x"], True),
|
||||
Mode("packet", "Packet", ["packet"], True),
|
||||
Mode("js8", "JS8Call", ["js8call"], True),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def getModes():
|
||||
return Modes.mappings
|
||||
|
||||
@staticmethod
|
||||
def getAvailableModes():
|
||||
return [m for m in Modes.getModes() if m.is_available()]
|
||||
|
||||
@staticmethod
|
||||
def getAvailableServices():
|
||||
return [m for m in Modes.getAvailableModes() if m.is_service()]
|
@ -8,12 +8,11 @@ from owrx.aprs import AprsParser
|
||||
from owrx.js8 import Js8Parser
|
||||
from owrx.config import Config
|
||||
from owrx.source.resampler import Resampler
|
||||
from owrx.feature import FeatureDetector
|
||||
from owrx.property import PropertyLayer
|
||||
from js8py import Js8Frame
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from .schedule import ServiceScheduler
|
||||
from functools import reduce
|
||||
from owrx.modes import Modes
|
||||
|
||||
import logging
|
||||
|
||||
@ -60,31 +59,6 @@ class Js8ServiceOutput(ServiceOutput):
|
||||
return t == "js8_demod"
|
||||
|
||||
|
||||
class ServiceDetector(object):
|
||||
requirements = {
|
||||
"ft8": ["wsjt-x"],
|
||||
"ft4": ["wsjt-x"],
|
||||
"jt65": ["wsjt-x"],
|
||||
"jt9": ["wsjt-x"],
|
||||
"wspr": ["wsjt-x"],
|
||||
"packet": ["packet"],
|
||||
"js8": ["js8call"],
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def getAvailableServices():
|
||||
# TODO this should be in a more central place (the frontend also needs this)
|
||||
fd = FeatureDetector()
|
||||
|
||||
return [
|
||||
name
|
||||
for name, requirements in ServiceDetector.requirements.items()
|
||||
if reduce(
|
||||
lambda a, b: a and b, [fd.is_available(r) for r in requirements], True
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class ServiceHandler(object):
|
||||
def __init__(self, source):
|
||||
self.lock = threading.Lock()
|
||||
@ -120,7 +94,7 @@ class ServiceHandler(object):
|
||||
|
||||
def isSupported(self, mode):
|
||||
configured = Config.get()["services_decoders"]
|
||||
available = ServiceDetector.getAvailableServices()
|
||||
available = [m.modulation for m in Modes.getAvailableServices()]
|
||||
return mode in configured and mode in available
|
||||
|
||||
def shutdown(self):
|
||||
|
Reference in New Issue
Block a user