You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.3 KiB
Python
174 lines
5.3 KiB
Python
import os
|
|
|
|
import numpy as np
|
|
import zmq
|
|
|
|
from common.runtime import load_root_env
|
|
from common.shared_stream_addrs import SHARED_868_ADDR, SHARED_915_ADDR
|
|
from core.multichannelswitcher import MultiChannel
|
|
from core.sig_n_medi_collect import Signal
|
|
|
|
|
|
load_root_env(__file__)
|
|
|
|
|
|
class Scheduler868:
|
|
def __init__(self):
|
|
self.signal_length = int(os.getenv('signal_length_868'))
|
|
self.multi_channel = MultiChannel(
|
|
[*map(float, os.getenv('f_step_868').split())],
|
|
[*map(float, os.getenv('f_bases_868').split())],
|
|
[*map(float, os.getenv('f_roofs_868').split())],
|
|
)
|
|
self.base_freq = float(self.multi_channel.init_f())
|
|
self.signal = Signal()
|
|
|
|
def get_current_freq(self):
|
|
return float(self.multi_channel.get_cur_channel())
|
|
|
|
def process(self, lvl):
|
|
current_before = self.get_current_freq()
|
|
metric = self.signal.fill_signal(lvl, self.signal_length)
|
|
if metric == 0:
|
|
return current_before, False
|
|
|
|
next_freq = float(self.multi_channel.change_channel())
|
|
self.signal.clear()
|
|
lane_complete = next_freq == self.base_freq and current_before != self.base_freq
|
|
return next_freq, lane_complete
|
|
|
|
|
|
class Scheduler915:
|
|
def __init__(self):
|
|
self.porog = float(os.getenv('POROG_915'))
|
|
self.point_amount = 100_000
|
|
self.split_size = 400_000
|
|
self.show_amount = int(0.8 * self.point_amount)
|
|
self.f_base = 0.91e9
|
|
self.f_step = 20e6
|
|
self.f_roof = 0.98e9
|
|
self.f = self.f_base
|
|
self.channel = 1
|
|
self.flag = 0
|
|
self.signal_arr = np.array([], dtype=np.complex64)
|
|
|
|
def get_current_freq(self):
|
|
return float(self.f)
|
|
|
|
def _median(self, sig):
|
|
samples = np.asarray(np.abs(np.array(sig, dtype=np.complex64)), dtype=np.float32)
|
|
sorted_samples = sorted(samples)
|
|
median = abs(float(np.median(sorted_samples[self.show_amount:])))
|
|
self.flag = 0 if self.porog > median else 1
|
|
|
|
def _advance(self):
|
|
next_freq = self.f + self.f_step
|
|
if next_freq >= self.f_roof:
|
|
self.f = self.f_base
|
|
self.channel = 1
|
|
return float(self.f), True
|
|
|
|
self.f = next_freq
|
|
self.channel += 1
|
|
return float(self.f), False
|
|
|
|
def process(self, lvl):
|
|
y = np.asarray(lvl, dtype=np.complex64).ravel()
|
|
self.signal_arr = np.concatenate((self.signal_arr, y), axis=None)
|
|
|
|
if self.flag == 0 and len(self.signal_arr) >= self.point_amount:
|
|
self._median(self.signal_arr[:self.point_amount])
|
|
self.signal_arr = np.array([], dtype=np.complex64)
|
|
if self.flag == 0:
|
|
return self._advance()
|
|
|
|
if len(self.signal_arr) >= self.split_size:
|
|
self.flag = 0
|
|
self.signal_arr = np.array([], dtype=np.complex64)
|
|
return self._advance()
|
|
|
|
return float(self.f), False
|
|
|
|
|
|
class SharedRouter868915:
|
|
def __init__(self):
|
|
self.frontends = {
|
|
'868': {
|
|
'sample_rate': 20e6,
|
|
'gain': 24,
|
|
'if_gain': 24,
|
|
'bb_gain': 100,
|
|
'bandwidth': 0,
|
|
},
|
|
'915': {
|
|
'sample_rate': 20e6,
|
|
'gain': 16,
|
|
'if_gain': 16,
|
|
'bb_gain': 0,
|
|
'bandwidth': 0,
|
|
},
|
|
}
|
|
self.schedulers = {
|
|
'868': Scheduler868(),
|
|
'915': Scheduler915(),
|
|
}
|
|
self.context = zmq.Context.instance()
|
|
self.sockets = {
|
|
'868': self._make_socket(SHARED_868_ADDR),
|
|
'915': self._make_socket(SHARED_915_ADDR),
|
|
}
|
|
self.active_name = '868'
|
|
self.switch_counter = 0
|
|
|
|
def _make_socket(self, addr):
|
|
sock = self.context.socket(zmq.PUSH)
|
|
sock.setsockopt(zmq.SNDHWM, 64)
|
|
sock.setsockopt(zmq.LINGER, 0)
|
|
sock.setsockopt(zmq.IMMEDIATE, 1)
|
|
sock.bind(addr)
|
|
return sock
|
|
|
|
def close(self):
|
|
for sock in self.sockets.values():
|
|
try:
|
|
sock.close(0)
|
|
except Exception:
|
|
pass
|
|
|
|
def get_active_name(self):
|
|
return self.active_name
|
|
|
|
def get_active_freq(self):
|
|
return self.schedulers[self.active_name].get_current_freq()
|
|
|
|
def get_active_frontend(self):
|
|
return dict(self.frontends[self.active_name])
|
|
|
|
def get_start_freq(self):
|
|
return self.get_active_freq()
|
|
|
|
def route_vector(self, lvl):
|
|
vector = np.asarray(lvl, dtype=np.complex64).ravel()
|
|
active_name = self.active_name
|
|
|
|
try:
|
|
self.sockets[active_name].send(vector.tobytes(), zmq.NOBLOCK)
|
|
except zmq.Again:
|
|
pass
|
|
|
|
next_freq, lane_complete = self.schedulers[active_name].process(vector)
|
|
lane_switched = False
|
|
|
|
if lane_complete:
|
|
previous = self.active_name
|
|
self.active_name = '915' if self.active_name == '868' else '868'
|
|
next_freq = self.get_active_freq()
|
|
self.switch_counter += 1
|
|
lane_switched = True
|
|
print(
|
|
f'[shared-router-868-915] switch#{self.switch_counter}: '
|
|
f'{previous} -> {self.active_name}, tune={next_freq}'
|
|
)
|
|
|
|
return float(next_freq), lane_switched
|