Compare commits

...

19 Commits

Author SHA1 Message Date
Sergey Revyakin 3952aa9e69 grc_скрипты 3 days ago
Sergey Revyakin 45283cf7c9 удалил лишний дамп 3 days ago
Sergey Revyakin 74bb2d9ce2 добавил новые сервисы 3 days ago
Sergey Revyakin 280e576a38 добавил новые сервисы 3 days ago
Sergey Revyakin 931ac9052f поменял усиление 6 days ago
Sergey Revyakin 815daf4be3 sync 6 days ago
Sergey Revyakin 4b185700bd изменил накопление буфера 7 days ago
Sergey Revyakin 6cd8396a8d добавил fft и решение по топ бинам 7 days ago
Sergey Revyakin 8d866125ff убрал обратный ход 7 days ago
Sergey Revyakin 04899fbb0d добавил подсчет по линейности 2 weeks ago
Sergey Revyakin 9d3fc41c4b добавил логирование времени прихода пакета в буфер для дебага 2 weeks ago
Sergey Revyakin ce43f5f8ff . 2 weeks ago
Sergey Revyakin b8ab9b366d добавил блок телеметрии в datas_processing 2 weeks ago
Sergey Revyakin 40d7e9ecde добавил изменения с телеметрией 2 weeks ago
Sergey Revyakin b53f6022b2 подсчет типа dbfs 2 weeks ago
Sergey Revyakin 93072ea0fc сервер для телеметрии 2 weeks ago
Sergey Revyakin dd58c4eacd докер обертка для телеметрии 2 weeks ago
Sergey Revyakin 6911d8ab25 добавил подсчет по dbfs 3 weeks ago
Sergey Revyakin 3a936fac9c убрал неправильный старт sdr 3 weeks ago

3
.gitignore vendored

@ -183,4 +183,5 @@ cython_debug/
#.idea/ #.idea/
*.png *.png
/logs/*.log /logs/*.log
runtime/

@ -148,19 +148,7 @@ docker compose -f deploy/docker/docker-compose.yml down
``` ```
### Все SDR-сервисы (systemd) ### Все SDR-сервисы (systemd)
Запуск всех SDR unitов:
```bash
sudo systemctl start dronedetector-sdr-433.service
sudo systemctl start dronedetector-sdr-750.service
sudo systemctl start dronedetector-sdr-868.service
sudo systemctl start dronedetector-sdr-3300.service
sudo systemctl start dronedetector-sdr-4500.service
sudo systemctl start dronedetector-sdr-5200.service
sudo systemctl start dronedetector-sdr-5800.service
sudo systemctl start dronedetector-sdr-915.service
sudo systemctl start dronedetector-sdr-1200.service
sudo systemctl start dronedetector-sdr-2400.service
```
```bash ```bash
sudo systemctl status dronedetector-sdr-433.service sudo systemctl status dronedetector-sdr-433.service
sudo systemctl status dronedetector-sdr-750.service sudo systemctl status dronedetector-sdr-750.service
@ -176,38 +164,26 @@ sudo systemctl status dronedetector-sdr-2400.service
```bash ```bash
sudo systemctl stop dronedetector-sdr-433.service sudo systemctl stop dronedetector-sdr-433.service
sudo systemctl stop dronedetector-sdr-750.service sudo systemctl stop dronedetector-sdr-750.service
sudo systemctl stop dronedetector-sdr-868.service
sudo systemctl stop dronedetector-sdr-3300.service sudo systemctl stop dronedetector-sdr-3300.service
sudo systemctl stop dronedetector-sdr-4500.service sudo systemctl stop dronedetector-sdr-4500.service
sudo systemctl stop dronedetector-sdr-5200.service sudo systemctl stop dronedetector-sdr-5200.service
sudo systemctl stop dronedetector-sdr-5800.service sudo systemctl stop dronedetector-sdr-5800.service
sudo systemctl stop dronedetector-sdr-915.service
sudo systemctl stop dronedetector-sdr-1200.service sudo systemctl stop dronedetector-sdr-1200.service
sudo systemctl stop dronedetector-sdr-2400.service sudo systemctl stop dronedetector-sdr-2400.service
sudo systemctl stop dronedetector-sdr-1500.service
sudo systemctl stop dronedetector-sdr-868.service
sudo systemctl stop dronedetector-sdr-868-915.service
``` ```
Альтернатива одной командой:
```bash
for u in dronedetector-sdr-{433,750,868,3300,4500,5200,5800,915,1200,2400}.service; do
sudo systemctl start "$u"
done
```
Проверка статуса всех SDR unitов: Проверка статуса всех SDR unitов:
```bash ```bash
sudo systemctl status dronedetector-sdr-*.service --no-pager sudo systemctl status dronedetector-sdr-*.service --no-pager
``` ```
### Полный ручной старт всего контура
```bash
docker compose -f deploy/docker/docker-compose.yml up -d
for u in dronedetector-sdr-{433,750,868,3300,4500,5200,5800,915,1200,2400}.service; do
sudo systemctl start "$u"
done
```
### Просмотр логов SDR ### Просмотр логов SDR
``` bash ``` bash
# 50 последних # 50 последних

@ -70,7 +70,7 @@ def validate_env(source: str, schema: Dict[str, Callable[[str], Any]]) -> Dict[s
def resolve_hackrf_index(serial_env_key: str, source: str) -> str: def resolve_hackrf_index(serial_env_key: str, source: str) -> str:
"""Resolve HackRF index from expected serial in env.""" """Resolve HackRF osmosdr selector from expected serial in env."""
serial = validate_env(source, {serial_env_key: as_str})[serial_env_key] serial = validate_env(source, {serial_env_key: as_str})[serial_env_key]
try: try:
@ -96,4 +96,4 @@ def resolve_hackrf_index(serial_env_key: str, source: str) -> str:
f"[{source}] serial {serial!r} not found among connected HackRF devices: {serials}" f"[{source}] serial {serial!r} not found among connected HackRF devices: {serials}"
) )
return str(serials.index(serial)) return serial

@ -0,0 +1,3 @@
SHARED_VECTOR_LEN = 4096
SHARED_868_ADDR = 'tcp://127.0.0.1:35068'
SHARED_915_ADDR = 'tcp://127.0.0.1:35069'

@ -0,0 +1,18 @@
# syntax=docker/dockerfile:1.7
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONPATH=/app
WORKDIR /app
COPY deploy/requirements/telemetry_server.txt /tmp/requirements.txt
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --upgrade pip && \
pip install -r /tmp/requirements.txt
COPY . /app
EXPOSE 5020
CMD ["python3", "-m", "telemetry.telemetry_server"]

@ -9,6 +9,7 @@ services:
- ../../.env - ../../.env
environment: environment:
- PYTHONPATH=/app - PYTHONPATH=/app
- JAMMER_STATE_FILE=/app/runtime/jammer_active.flag
working_dir: /app working_dir: /app
command: ["python3", "-m", "src.server_to_master"] command: ["python3", "-m", "src.server_to_master"]
restart: unless-stopped restart: unless-stopped
@ -16,6 +17,7 @@ services:
- "5010:5010" - "5010:5010"
volumes: volumes:
- ../../.env:/app/.env:ro - ../../.env:/app/.env:ro
- ../../runtime:/app/runtime
networks: networks:
- dronedetector-net - dronedetector-net
@ -48,6 +50,29 @@ services:
networks: networks:
- dronedetector-net - dronedetector-net
dronedetector-telemetry-server:
container_name: dronedetector-telemetry-server
image: dronedetector-telemetry-server:latest
build:
context: ../..
dockerfile: deploy/docker/Dockerfile.telemetry_server
env_file:
- ../../.env
environment:
- PYTHONPATH=/app
working_dir: /app
command: ["python3", "-m", "telemetry.telemetry_server"]
restart: unless-stopped
ports:
- "5020:5020"
volumes:
- ../../.env:/app/.env:ro
- ../../telemetry:/app/telemetry
- ../../common:/app/common
networks:
- dronedetector-net
networks: networks:
dronedetector-net: dronedetector-net:
name: dronedetector-net name: dronedetector-net

@ -0,0 +1,3 @@
fastapi==0.115.6
uvicorn[standard]==0.32.1
python-dotenv==1.0.1

@ -0,0 +1,19 @@
[Unit]
Description=DroneDetector SDR Scanner 1500 MHz
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=__RUN_USER__
Group=__RUN_GROUP__
WorkingDirectory=__PROJECT_ROOT__
EnvironmentFile=__PROJECT_ROOT__/.env
Environment=PYTHONPATH=__PROJECT_ROOT__
ExecStartPre=/usr/local/bin/dronedetector-precheck-sdr.sh
ExecStart=__PROJECT_ROOT__/.venv-sdr/bin/python src/main_1500.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target

@ -0,0 +1,19 @@
[Unit]
Description=DroneDetector SDR Router 868/915 Shared HackRF
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=__RUN_USER__
Group=__RUN_GROUP__
WorkingDirectory=__PROJECT_ROOT__
EnvironmentFile=__PROJECT_ROOT__/.env
Environment=PYTHONPATH=__PROJECT_ROOT__
ExecStartPre=/usr/local/bin/dronedetector-precheck-sdr.sh
ExecStart=__PROJECT_ROOT__/.venv-sdr/bin/python src/main_868_915_router.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target

@ -1,7 +1,8 @@
[Unit] [Unit]
Description=DroneDetector SDR Scanner 868 MHz Description=DroneDetector SDR Scanner 868 MHz
After=network-online.target After=network-online.target dronedetector-sdr-868-915.service
Wants=network-online.target Wants=network-online.target
Requires=dronedetector-sdr-868-915.service
[Service] [Service]
Type=simple Type=simple

@ -1,7 +1,8 @@
[Unit] [Unit]
Description=DroneDetector SDR Scanner 915 MHz Description=DroneDetector SDR Scanner 915 MHz
After=network-online.target After=network-online.target dronedetector-sdr-868-915.service
Wants=network-online.target Wants=network-online.target
Requires=dronedetector-sdr-868-915.service
[Service] [Service]
Type=simple Type=simple

@ -10,7 +10,9 @@ RUN_GROUP="$(id -gn "${RUN_USER}")"
SDR_UNITS=( SDR_UNITS=(
dronedetector-sdr-433.service dronedetector-sdr-433.service
dronedetector-sdr-750.service dronedetector-sdr-750.service
dronedetector-sdr-868-915.service
dronedetector-sdr-868.service dronedetector-sdr-868.service
dronedetector-sdr-1500.service
dronedetector-sdr-3300.service dronedetector-sdr-3300.service
dronedetector-sdr-4500.service dronedetector-sdr-4500.service
dronedetector-sdr-5200.service dronedetector-sdr-5200.service

@ -1,115 +1,119 @@
from common.runtime import load_root_env, validate_env, as_float, as_int, as_str
from common.runtime import load_root_env, validate_env, as_float, as_int, as_str import json
import numpy as np import os
import requests
import os import numpy as np
import sys import requests
import json
import time
load_root_env(__file__) load_root_env(__file__)
validate_env("orange_scripts/compose_send_data_915.py", { validate_env('orange_scripts/compose_send_data_915.py', {
"POROG_915": as_float, 'POROG_915': as_float,
"SERVER_IP_1": as_str, 'SERVER_IP_1': as_str,
"SERVER_PORT_1": as_int, 'SERVER_PORT_1': as_int,
}) })
porog = float(os.getenv('POROG_915'))
server_ip_1 = os.getenv('SERVER_IP_1') porog = float(os.getenv('POROG_915'))
server_port_1 = os.getenv('SERVER_PORT_1') server_ip_1 = os.getenv('SERVER_IP_1')
server_ip_2 = os.getenv('SERVER_IP_2') server_port_1 = os.getenv('SERVER_PORT_1')
server_port_2 = os.getenv('SERVER_PORT_2') server_ip_2 = os.getenv('SERVER_IP_2')
PARAMS = {'split_size': 400_000, 'point_amount': 100_000} server_port_2 = os.getenv('SERVER_PORT_2')
PARAMS['show_amount'] = 0.8 * PARAMS['point_amount'] PARAMS = {'split_size': 400_000, 'point_amount': 100_000}
token = 0 PARAMS['show_amount'] = int(0.8 * PARAMS['point_amount'])
channel = 1 token = 0
flag = 0 channel = 1
flag = 0
##############################
# HYPERPARAMETERS f_base = 0.91e9
############################## f_step = 20e6
f_base = 0.91e9 f_roof = 0.98e9
f_step = 20e6
f_roof = 0.98e9 f = f_base
############################## EOCF = 0
# Variables signal_arr = np.array([], dtype=np.complex64)
##############################
f = f_base
EOCF = 0 class NumpyArrayEncoder(json.JSONEncoder):
signal_arr = [] def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
class NumpyArrayEncoder(json.JSONEncoder): if isinstance(obj, np.ndarray):
def default(self, obj): return obj.tolist()
if isinstance(obj, np.integer): return super().default(obj)
return int(obj)
elif isinstance(obj, np.ndarray):
return obj.tolist() def send_data(sig):
else: try:
return super(NumpyArrayEncoder, self).default(obj) global token
print('#' * 10)
print('\nОтправка пакета ' + str(token + 1))
def send_data(sig): data_to_send = {
try: 'freq': 915,
global token 'channel': int(channel),
print('#' * 10) 'token': int(token + 1),
print('\nОтправка пакета ' + str(token+1)) 'data_real': np.asarray(np.array(sig, dtype=np.complex64).real, dtype=np.float32),
data_to_send = { 'data_imag': np.asarray(np.array(sig, dtype=np.complex64).imag, dtype=np.float32),
"freq": 915, }
"channel": int(channel), mod_data_to_send = json.dumps(data_to_send, cls=NumpyArrayEncoder)
"token": int(token+1), response = requests.post(
"data_real": np.asarray(np.array(sig, dtype=np.complex64).real, dtype=np.float32), 'http://{0}:{1}/receive_data'.format(server_ip_1, server_port_1),
"data_imag": np.asarray(np.array(sig, dtype=np.complex64).imag, dtype=np.float32) json=mod_data_to_send,
} )
mod_data_to_send = json.dumps(data_to_send, cls=NumpyArrayEncoder) if response.status_code == 200:
response = requests.post("http://{0}:{1}/receive_data".format(server_ip_1, server_port_1), json=mod_data_to_send) token += 1
if response.status_code == 200: print(response.text)
token += 1 print('#' * 10)
print(response.text) else:
print('#' * 10) print('Ошибка при отправке данных: ', response.status_code)
else: print('#' * 10)
print("Ошибка при отправке данных: ", response.status_code) except Exception as exc:
print('#' * 10) print(str(exc))
except Exception as exc:
print(str(exc))
def median(sig):
global flag
def median(sig): samples = np.asarray(np.abs(np.array(sig, dtype=np.complex64)), dtype=np.float32)
global flag med = abs(float(np.median(sorted(samples)[int(PARAMS['show_amount']):])))
median = abs(float(np.median(sorted(np.asarray(np.abs(np.array(sig, dtype=np.complex64)), dtype=np.float32))[int(PARAMS['show_amount']):]))) flag = 0 if porog > med else 1
flag = 0 if porog > median else 1 print(channel, med, flag)
print(channel, median, flag)
def advance_freq():
def work(lvl): global channel
global flag global f
global channel
global f_base next_freq = f + f_step
global f_step if next_freq >= f_roof:
global f_roof f = f_base
global f channel = 1
global EOCF return f, True
global signal_arr
f = next_freq
y = np.array(lvl).ravel() channel += 1
signal_arr = np.concatenate((signal_arr, y), axis=None) return f, False
if f >= f_roof:
f = f_base def work(lvl):
signal_arr = [] global flag
channel = 1 global f
return f, EOCF global EOCF
else: global signal_arr
if flag == 0 and len(signal_arr) >= PARAMS['point_amount']:
median(signal_arr[:PARAMS['point_amount']]) y = np.asarray(lvl, dtype=np.complex64).ravel()
signal_arr = [] signal_arr = np.concatenate((signal_arr, y), axis=None)
if flag == 0:
f += f_step if flag == 0 and len(signal_arr) >= PARAMS['point_amount']:
channel += 1 median(signal_arr[:PARAMS['point_amount']])
if len(signal_arr) >= PARAMS['split_size']: signal_arr = np.array([], dtype=np.complex64)
send_data(signal_arr[:PARAMS['split_size']]) if flag == 0:
flag = 0 f, _ = advance_freq()
signal_arr = [] return f, EOCF
channel += 1
f += f_step if len(signal_arr) >= PARAMS['split_size']:
return f, EOCF send_data(signal_arr[:PARAMS['split_size']])
flag = 0
signal_arr = np.array([], dtype=np.complex64)
f, _ = advance_freq()
return f, EOCF
return f, EOCF

@ -10,11 +10,10 @@ import os
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('HACKID_1200', 'orange_scripts/main_1200.py') return resolve_hackrf_index('HACKID_1200', 'orange_scripts/main_1200.py')
serial_number = os.getenv('HACKID_1200') serial_number = os.getenv('HACKID_1200')
pos = None pos = None
output = [] output = []

@ -10,11 +10,10 @@ import os
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('HACKID_2400', 'orange_scripts/main_2400.py') return resolve_hackrf_index('HACKID_2400', 'orange_scripts/main_2400.py')
serial_number = os.getenv('HACKID_2400') serial_number = os.getenv('HACKID_2400')
pos = None pos = None
output = [] output = []

@ -1,173 +1,92 @@
from gnuradio import blocks, gr from gnuradio import blocks, gr, zeromq
import sys import signal
import signal import sys
import compose_send_data_915 as my_freq import threading
import osmosdr import time
import time
import threading import compose_send_data_915 as my_freq
import subprocess
import os from common.runtime import load_root_env
from common.runtime import load_root_env, resolve_hackrf_index from common.shared_stream_addrs import SHARED_915_ADDR, SHARED_VECTOR_LEN
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): class get_center_freq(gr.top_block):
return resolve_hackrf_index('HACKID_915', 'orange_scripts/main_915.py') def __init__(self):
serial_number = os.getenv('HACKID_915') gr.top_block.__init__(self, 'get_center_freq')
pos = None
output = [] self.prob_freq = 0
try: self.poll_rate = 10000
command = 'lsusb -v -d 1d50:6089 | grep iSerial' self.vector_len = SHARED_VECTOR_LEN
output.append(subprocess.check_output(command, shell=True, text=True)) self.center_freq = 0
except subprocess.CalledProcessError as e: self.shared_addr = SHARED_915_ADDR
print(f"Команда завершилась с кодом возврата {e.returncode}") self._stop_polling = threading.Event()
print(e) self._prob_freq_thread = None
print(output)
output_lines = output[0].strip().split('\n') self.probSigVec = blocks.probe_signal_vc(self.vector_len)
print(output_lines) self.shared_source_0 = zeromq.pull_source(
serial_numbers = [line.split()[-1] for line in output_lines] gr.sizeof_gr_complex,
print(serial_numbers) self.vector_len,
for i, number in enumerate(serial_numbers): self.shared_addr,
if number == serial_number: 100,
id = i False,
break -1,
if id is not None: False,
print('HackId is: {0}'.format(id)) )
return str(id) self.connect((self.shared_source_0, 0), (self.probSigVec, 0))
else:
print('Такого хака нет!') def start_polling(self):
if self._prob_freq_thread is not None:
return
class get_center_freq(gr.top_block):
def _prob_freq_probe():
def __init__(self): while not self._stop_polling.is_set():
gr.top_block.__init__(self, "get_center_freq") self.set_prob_freq(self.probSigVec.level())
time.sleep(1.0 / self.poll_rate)
##################################################
# Variables self._prob_freq_thread = threading.Thread(target=_prob_freq_probe, daemon=True)
################################################## self._prob_freq_thread.start()
self.prob_freq = prob_freq = 0
self.top_peaks_amount = top_peaks_amount = 20 def get_prob_freq(self):
self.samp_rate = samp_rate = 20e6 return self.prob_freq
self.poll_rate = poll_rate = 10000
self.num_points = num_points = 8192 def set_prob_freq(self, prob_freq):
self.flag = flag = 1 self.prob_freq = prob_freq
self.decimation = decimation = 1 self.center_freq = my_freq.work(self.prob_freq)[0]
self.center_freq = center_freq = my_freq.work(prob_freq)[0]
def get_center_freq(self):
################################################## return self.center_freq
# Blocks
################################################## def set_center_freq(self, center_freq):
self.probSigVec = blocks.probe_signal_vc(4096) self.center_freq = center_freq
self.rtlsdr_source_0 = osmosdr.source(
args="numchan=" + str(1) + " " + 'hackrf=' + get_hack_id() def close(self):
) self._stop_polling.set()
self.rtlsdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t()) self.stop()
self.rtlsdr_source_0.set_sample_rate(samp_rate) self.wait()
self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(16, 0) def main(top_block_cls=get_center_freq, options=None):
self.rtlsdr_source_0.set_if_gain(16, 0) time.sleep(3)
self.rtlsdr_source_0.set_bb_gain(0, 0) tb = top_block_cls()
self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) def sig_handler(sig=None, frame=None):
self.rtlsdr_source_0.set_min_output_buffer(4096) tb.close()
sys.exit(0)
def _prob_freq_probe():
while True: signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
val = self.probSigVec.level()
try: tb.start()
self.set_prob_freq(val) tb.start_polling()
except AttributeError: try:
pass print('shared_pull_addr:', SHARED_915_ADDR)
time.sleep(1.0 / (poll_rate)) except EOFError:
_prob_freq_thread = threading.Thread(target=_prob_freq_probe) pass
_prob_freq_thread.daemon = True tb.wait()
_prob_freq_thread.start()
self.blocks_stream_to_vector_1 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, 4096) if __name__ == '__main__':
main()
##################################################
# Connections
##################################################
self.connect((self.blocks_stream_to_vector_1, 0), (self.probSigVec, 0))
self.connect((self.rtlsdr_source_0, 0), (self.blocks_stream_to_vector_1, 0))
def get_prob_freq(self):
return self.prob_freq
def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq)[0])
def get_top_peaks_amount(self):
return self.top_peaks_amount
def set_top_peaks_amount(self, top_peaks_amount):
self.top_peaks_amount = top_peaks_amount
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
def get_poll_rate(self):
return self.poll_rate
def set_poll_rate(self, poll_rate):
self.poll_rate = poll_rate
def get_num_points(self):
return self.num_points
def set_num_points(self, num_points):
self.num_points = num_points
def get_flag(self):
return self.flag
def set_flag(self, flag):
self.flag = flag
def get_decimation(self):
return self.decimation
def set_decimation(self, decimation):
self.decimation = decimation
def get_center_freq(self):
return self.center_freq
def set_center_freq(self, center_freq):
self.center_freq = center_freq
self.rtlsdr_source_0.set_center_freq(self.center_freq, 0)
def main(top_block_cls=get_center_freq, options=None):
time.sleep(3)
tb = top_block_cls()
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
try:
input('Press Enter to quit: ')
except EOFError:
pass
tb.wait()
if __name__ == '__main__':
main()

BIN
out.iq

Binary file not shown.

@ -7,7 +7,9 @@ COMPOSE_FILE="${PROJECT_ROOT}/deploy/docker/docker-compose.yml"
SDR_UNITS=( SDR_UNITS=(
dronedetector-sdr-433.service dronedetector-sdr-433.service
dronedetector-sdr-750.service dronedetector-sdr-750.service
dronedetector-sdr-868-915.service
dronedetector-sdr-868.service dronedetector-sdr-868.service
dronedetector-sdr-1500.service
dronedetector-sdr-3300.service dronedetector-sdr-3300.service
dronedetector-sdr-4500.service dronedetector-sdr-4500.service
dronedetector-sdr-5200.service dronedetector-sdr-5200.service

@ -0,0 +1,686 @@
options:
parameters:
author: ''
catch_exceptions: 'True'
category: '[GRC Hier Blocks]'
cmake_opt: ''
comment: ''
copyright: ''
description: ''
gen_cmake: 'On'
gen_linking: dynamic
generate_options: qt_gui
hier_block_src_path: '.:'
id: band_scanner
max_nouts: '0'
output_language: python
placement: (0,0)
qt_qss_theme: ''
realtime_scheduling: ''
run: 'True'
run_command: '{python} -u {filename}'
run_options: prompt
sizing_mode: fixed
thread_safe_setters: ''
title: band_scanner
window_size: (1000,1000)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [8, 8]
rotation: 0
state: enabled
blocks:
- name: freq
id: variable
parameters:
comment: ''
value: py_module.work(func_probe, min_f, max_f, step_f)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [368, 16.0]
rotation: 0
state: true
- name: func_probe
id: variable_function_probe
parameters:
block_id: vec_probe
comment: ''
function_args: ''
function_name: level
poll_rate: '0.05'
value: '0'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [1120, 272.0]
rotation: 0
state: true
- name: max_f
id: variable
parameters:
comment: ''
value: 3.0e9
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [536, 16.0]
rotation: 0
state: true
- name: min_f
id: variable
parameters:
comment: ''
value: 0.4e9
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [448, 16.0]
rotation: 0
state: true
- name: samp_rate
id: variable
parameters:
comment: ''
value: 20e6
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [184, 12]
rotation: 0
state: enabled
- name: step_f
id: variable
parameters:
comment: ''
value: 5e6
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [616, 16.0]
rotation: 0
state: true
- name: analog_const_source_x_0
id: analog_const_source_x
parameters:
affinity: ''
alias: ''
comment: ''
const: freq
maxoutbuf: '0'
minoutbuf: '0'
type: float
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [792, 48.0]
rotation: 0
state: disabled
- name: osmosdr_source_0
id: osmosdr_source
parameters:
affinity: ''
alias: ''
ant0: ''
ant1: ''
ant10: ''
ant11: ''
ant12: ''
ant13: ''
ant14: ''
ant15: ''
ant16: ''
ant17: ''
ant18: ''
ant19: ''
ant2: ''
ant20: ''
ant21: ''
ant22: ''
ant23: ''
ant24: ''
ant25: ''
ant26: ''
ant27: ''
ant28: ''
ant29: ''
ant3: ''
ant30: ''
ant31: ''
ant4: ''
ant5: ''
ant6: ''
ant7: ''
ant8: ''
ant9: ''
args: hackrf=0
bb_gain0: '0'
bb_gain1: '20'
bb_gain10: '20'
bb_gain11: '20'
bb_gain12: '20'
bb_gain13: '20'
bb_gain14: '20'
bb_gain15: '20'
bb_gain16: '20'
bb_gain17: '20'
bb_gain18: '20'
bb_gain19: '20'
bb_gain2: '20'
bb_gain20: '20'
bb_gain21: '20'
bb_gain22: '20'
bb_gain23: '20'
bb_gain24: '20'
bb_gain25: '20'
bb_gain26: '20'
bb_gain27: '20'
bb_gain28: '20'
bb_gain29: '20'
bb_gain3: '20'
bb_gain30: '20'
bb_gain31: '20'
bb_gain4: '20'
bb_gain5: '20'
bb_gain6: '20'
bb_gain7: '20'
bb_gain8: '20'
bb_gain9: '20'
bw0: '0'
bw1: '0'
bw10: '0'
bw11: '0'
bw12: '0'
bw13: '0'
bw14: '0'
bw15: '0'
bw16: '0'
bw17: '0'
bw18: '0'
bw19: '0'
bw2: '0'
bw20: '0'
bw21: '0'
bw22: '0'
bw23: '0'
bw24: '0'
bw25: '0'
bw26: '0'
bw27: '0'
bw28: '0'
bw29: '0'
bw3: '0'
bw30: '0'
bw31: '0'
bw4: '0'
bw5: '0'
bw6: '0'
bw7: '0'
bw8: '0'
bw9: '0'
clock_source0: ''
clock_source1: ''
clock_source2: ''
clock_source3: ''
clock_source4: ''
clock_source5: ''
clock_source6: ''
clock_source7: ''
comment: ''
corr0: '0'
corr1: '0'
corr10: '0'
corr11: '0'
corr12: '0'
corr13: '0'
corr14: '0'
corr15: '0'
corr16: '0'
corr17: '0'
corr18: '0'
corr19: '0'
corr2: '0'
corr20: '0'
corr21: '0'
corr22: '0'
corr23: '0'
corr24: '0'
corr25: '0'
corr26: '0'
corr27: '0'
corr28: '0'
corr29: '0'
corr3: '0'
corr30: '0'
corr31: '0'
corr4: '0'
corr5: '0'
corr6: '0'
corr7: '0'
corr8: '0'
corr9: '0'
dc_offset_mode0: '0'
dc_offset_mode1: '0'
dc_offset_mode10: '0'
dc_offset_mode11: '0'
dc_offset_mode12: '0'
dc_offset_mode13: '0'
dc_offset_mode14: '0'
dc_offset_mode15: '0'
dc_offset_mode16: '0'
dc_offset_mode17: '0'
dc_offset_mode18: '0'
dc_offset_mode19: '0'
dc_offset_mode2: '0'
dc_offset_mode20: '0'
dc_offset_mode21: '0'
dc_offset_mode22: '0'
dc_offset_mode23: '0'
dc_offset_mode24: '0'
dc_offset_mode25: '0'
dc_offset_mode26: '0'
dc_offset_mode27: '0'
dc_offset_mode28: '0'
dc_offset_mode29: '0'
dc_offset_mode3: '0'
dc_offset_mode30: '0'
dc_offset_mode31: '0'
dc_offset_mode4: '0'
dc_offset_mode5: '0'
dc_offset_mode6: '0'
dc_offset_mode7: '0'
dc_offset_mode8: '0'
dc_offset_mode9: '0'
freq0: freq
freq1: 100e6
freq10: 100e6
freq11: 100e6
freq12: 100e6
freq13: 100e6
freq14: 100e6
freq15: 100e6
freq16: 100e6
freq17: 100e6
freq18: 100e6
freq19: 100e6
freq2: 100e6
freq20: 100e6
freq21: 100e6
freq22: 100e6
freq23: 100e6
freq24: 100e6
freq25: 100e6
freq26: 100e6
freq27: 100e6
freq28: 100e6
freq29: 100e6
freq3: 100e6
freq30: 100e6
freq31: 100e6
freq4: 100e6
freq5: 100e6
freq6: 100e6
freq7: 100e6
freq8: 100e6
freq9: 100e6
gain0: '100'
gain1: '10'
gain10: '10'
gain11: '10'
gain12: '10'
gain13: '10'
gain14: '10'
gain15: '10'
gain16: '10'
gain17: '10'
gain18: '10'
gain19: '10'
gain2: '10'
gain20: '10'
gain21: '10'
gain22: '10'
gain23: '10'
gain24: '10'
gain25: '10'
gain26: '10'
gain27: '10'
gain28: '10'
gain29: '10'
gain3: '10'
gain30: '10'
gain31: '10'
gain4: '10'
gain5: '10'
gain6: '10'
gain7: '10'
gain8: '10'
gain9: '10'
gain_mode0: 'False'
gain_mode1: 'False'
gain_mode10: 'False'
gain_mode11: 'False'
gain_mode12: 'False'
gain_mode13: 'False'
gain_mode14: 'False'
gain_mode15: 'False'
gain_mode16: 'False'
gain_mode17: 'False'
gain_mode18: 'False'
gain_mode19: 'False'
gain_mode2: 'False'
gain_mode20: 'False'
gain_mode21: 'False'
gain_mode22: 'False'
gain_mode23: 'False'
gain_mode24: 'False'
gain_mode25: 'False'
gain_mode26: 'False'
gain_mode27: 'False'
gain_mode28: 'False'
gain_mode29: 'False'
gain_mode3: 'False'
gain_mode30: 'False'
gain_mode31: 'False'
gain_mode4: 'False'
gain_mode5: 'False'
gain_mode6: 'False'
gain_mode7: 'False'
gain_mode8: 'False'
gain_mode9: 'False'
if_gain0: '100'
if_gain1: '20'
if_gain10: '20'
if_gain11: '20'
if_gain12: '20'
if_gain13: '20'
if_gain14: '20'
if_gain15: '20'
if_gain16: '20'
if_gain17: '20'
if_gain18: '20'
if_gain19: '20'
if_gain2: '20'
if_gain20: '20'
if_gain21: '20'
if_gain22: '20'
if_gain23: '20'
if_gain24: '20'
if_gain25: '20'
if_gain26: '20'
if_gain27: '20'
if_gain28: '20'
if_gain29: '20'
if_gain3: '20'
if_gain30: '20'
if_gain31: '20'
if_gain4: '20'
if_gain5: '20'
if_gain6: '20'
if_gain7: '20'
if_gain8: '20'
if_gain9: '20'
iq_balance_mode0: '0'
iq_balance_mode1: '0'
iq_balance_mode10: '0'
iq_balance_mode11: '0'
iq_balance_mode12: '0'
iq_balance_mode13: '0'
iq_balance_mode14: '0'
iq_balance_mode15: '0'
iq_balance_mode16: '0'
iq_balance_mode17: '0'
iq_balance_mode18: '0'
iq_balance_mode19: '0'
iq_balance_mode2: '0'
iq_balance_mode20: '0'
iq_balance_mode21: '0'
iq_balance_mode22: '0'
iq_balance_mode23: '0'
iq_balance_mode24: '0'
iq_balance_mode25: '0'
iq_balance_mode26: '0'
iq_balance_mode27: '0'
iq_balance_mode28: '0'
iq_balance_mode29: '0'
iq_balance_mode3: '0'
iq_balance_mode30: '0'
iq_balance_mode31: '0'
iq_balance_mode4: '0'
iq_balance_mode5: '0'
iq_balance_mode6: '0'
iq_balance_mode7: '0'
iq_balance_mode8: '0'
iq_balance_mode9: '0'
maxoutbuf: '0'
minoutbuf: '0'
nchan: '1'
num_mboards: '1'
sample_rate: samp_rate
sync: sync
time_source0: ''
time_source1: ''
time_source2: ''
time_source3: ''
time_source4: ''
time_source5: ''
time_source6: ''
time_source7: ''
type: fc32
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [448, 220.0]
rotation: 0
state: true
- name: py_module
id: epy_module
parameters:
alias: ''
comment: ''
source_code: "# this module will be imported in the into your flowgraph\r\n\r\n\
import numpy\r\nimport os\r\nimport time \r\n\r\nf = 0\r\n\r\ndef work(lvl,\
\ min_f, max_f, step_f):\r\n global f\r\n if f < min_f:\r\n f =\
\ min_f\r\n f += step_f\r\n if f > max_f:\r\n f = min_f\r\n \
\ print('ffffffffffffffffff: {0}'.format(f)) \r\n return f\r\n "
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [1128, 392.0]
rotation: 0
state: true
- name: qtgui_number_sink_0
id: qtgui_number_sink
parameters:
affinity: ''
alias: ''
autoscale: 'False'
avg: '0'
color1: ("black", "black")
color10: ("black", "black")
color2: ("black", "black")
color3: ("black", "black")
color4: ("black", "black")
color5: ("black", "black")
color6: ("black", "black")
color7: ("black", "black")
color8: ("black", "black")
color9: ("black", "black")
comment: ''
factor1: '1'
factor10: '1'
factor2: '1'
factor3: '1'
factor4: '1'
factor5: '1'
factor6: '1'
factor7: '1'
factor8: '1'
factor9: '1'
graph_type: qtgui.NUM_GRAPH_NONE
gui_hint: ''
label1: ''
label10: ''
label2: ''
label3: ''
label4: ''
label5: ''
label6: ''
label7: ''
label8: ''
label9: ''
max: 0.95e9
min: 0.85e9
name: '""'
nconnections: '1'
type: float
unit1: ''
unit10: ''
unit2: ''
unit3: ''
unit4: ''
unit5: ''
unit6: ''
unit7: ''
unit8: ''
unit9: ''
update_time: '0.01'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [992, 24.0]
rotation: 0
state: disabled
- name: qtgui_time_sink_x_0
id: qtgui_time_sink_x
parameters:
affinity: ''
alias: ''
alpha1: '1.0'
alpha10: '1.0'
alpha2: '1.0'
alpha3: '1.0'
alpha4: '1.0'
alpha5: '1.0'
alpha6: '1.0'
alpha7: '1.0'
alpha8: '1.0'
alpha9: '1.0'
autoscale: 'False'
axislabels: 'True'
color1: blue
color10: dark blue
color2: red
color3: green
color4: black
color5: cyan
color6: magenta
color7: yellow
color8: dark red
color9: dark green
comment: ''
ctrlpanel: 'False'
entags: 'True'
grid: 'False'
gui_hint: ''
label1: Signal 1
label10: Signal 10
label2: Signal 2
label3: Signal 3
label4: Signal 4
label5: Signal 5
label6: Signal 6
label7: Signal 7
label8: Signal 8
label9: Signal 9
legend: 'True'
marker1: '-1'
marker10: '-1'
marker2: '-1'
marker3: '-1'
marker4: '-1'
marker5: '-1'
marker6: '-1'
marker7: '-1'
marker8: '-1'
marker9: '-1'
name: freq
nconnections: '1'
size: '1000000'
srate: samp_rate
stemplot: 'False'
style1: '1'
style10: '1'
style2: '1'
style3: '1'
style4: '1'
style5: '1'
style6: '1'
style7: '1'
style8: '1'
style9: '1'
tr_chan: '0'
tr_delay: '0'
tr_level: '0.0'
tr_mode: qtgui.TRIG_MODE_FREE
tr_slope: qtgui.TRIG_SLOPE_POS
tr_tag: '""'
type: complex
update_time: '0.10'
width1: '1'
width10: '1'
width2: '1'
width3: '1'
width4: '1'
width5: '1'
width6: '1'
width7: '1'
width8: '1'
width9: '1'
ylabel: Amplitude
ymax: '1'
ymin: '-1'
yunit: '""'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [928, 272.0]
rotation: 0
state: enabled
- name: vec_probe
id: blocks_probe_signal_vx
parameters:
affinity: ''
alias: ''
comment: ''
type: complex
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [936, 384.0]
rotation: 0
state: true
connections:
- [analog_const_source_x_0, '0', qtgui_number_sink_0, '0']
- [osmosdr_source_0, '0', qtgui_time_sink_x_0, '0']
- [osmosdr_source_0, '0', vec_probe, '0']
metadata:
file_format: 1
grc_version: 3.10.7.0

@ -0,0 +1,642 @@
options:
parameters:
author: ''
catch_exceptions: 'True'
category: '[GRC Hier Blocks]'
cmake_opt: ''
comment: ''
copyright: ''
description: ''
gen_cmake: 'On'
gen_linking: dynamic
generate_options: qt_gui
hier_block_src_path: '.:'
id: data_saver
max_nouts: '0'
output_language: python
placement: (0,0)
qt_qss_theme: ''
realtime_scheduling: ''
run: 'True'
run_command: '{python} -u {filename}'
run_options: prompt
sizing_mode: fixed
thread_safe_setters: ''
title: data_saver
window_size: ''
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [8, 8]
rotation: 0
state: enabled
blocks:
- name: freq
id: variable
parameters:
comment: ''
value: 1.160e9
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [56, 307]
rotation: 0
state: true
- name: samp_rate
id: variable
parameters:
comment: ''
value: 20e6
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [56, 212]
rotation: 0
state: enabled
- name: epy_block_0
id: epy_block
parameters:
Delay: '0.1'
FileTag: '''DJI_3'''
SaveDir: '''D:/Dataset/1160'''
SplitSize: '400000'
_source_code: "\"\"\"\nEmbedded Python Blocks:\n\nEach time this file is saved,\
\ GRC will instantiate the first class it finds\nto get ports and parameters\
\ of your block. The arguments to __init__ will\nbe the parameters. All of\
\ them are required to have default values!\n\"\"\"\n\nimport numpy as np\n\
from gnuradio import gr\nimport os\nimport time\nimport matplotlib.pyplot as\
\ plt\nimport sys\nimport gc\n\nclass Simsi_Sink(gr.sync_block): # other base\
\ classes are basic_block, decim_block, interp_block\n \"\"\"Embedded Python\
\ Block example - a simple multiply const\"\"\"\n\n def __init__(self, SaveDir=\"\
./signal\", FileTag=\"fragment_\", SplitSize=1000000, Delay=2): # only default\
\ arguments here\n \"\"\"arguments to this function show up as parameters\
\ in GRC\"\"\"\n gr.sync_block.__init__(\n self,\n \
\ name='Simsi_Sink', # will show up in GRC\n in_sig=[np.complex64],\n\
\ out_sig=None#[np.complex64]\n )\n self.Delay = Delay\n\
\ self.FileTag = FileTag\n self.SplitSize = SplitSize\n \
\ \n self.SaveDir = SaveDir\n if not os.path.exists(self.SaveDir)\
\ and self.SaveDir == \"./signal\":\n os.mkdir(\"signal\")\n \
\ \n self.it = 0\n self.Signal = np.array([], dtype=np.float32)\n\
\ self.data_dir = SaveDir\n\n self.last_file_path = self.data_dir\
\ + \"/\" + self.FileTag + str(self.it)\n self.last_fd = open(self.last_file_path,\
\ \"wb\")\n self.last_file_len = 0\n\n\n self.reading_in_progress_file_path\
\ = self.data_dir + \"/reading_in_progress\"\n self.reading_in_progress_file_fd\
\ = open(self.reading_in_progress_file_path, \"wb\")\n\n print(self.Signal)\n\
\ print(self.data_dir)\n # if an attribute with the same name\
\ as a parameter is found,\n # a callback is registered (properties work,\
\ too).\n\n def work(self, input_items, output_items):\n \"\"\"example:\
\ multiply with constant\"\"\"\n length = len(input_items[0])\n \
\ self.last_file_len += length\n\n if self.last_file_len > self.SplitSize:\n\
\ print(\"Saving file: \" + str(self.last_file_path))\n \
\ length = length - (self.last_file_len - self.SplitSize)\n self.last_fd.write(input_items[0][0:length].copy())\n\
\ self.it += 1\n self.last_file_len = 0\n self.last_file_path\
\ = self.data_dir + '/' + self.FileTag + str(self.it)\n self.last_fd.close()\n\
\ self.reading_in_progress_file_fd.close()\n os.remove(self.reading_in_progress_file_path)\n\
\ time.sleep(self.Delay)\n self.reading_in_progress_file_fd\
\ = open(self.reading_in_progress_file_path, \"wb\")\n self.last_fd\
\ = open(self.last_file_path, \"wb\")\n \n else:\n \
\ self.last_fd.write(input_items[0].copy())\n\n\n return len(input_items[0])\n"
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
states:
_io_cache: ('Simsi_Sink', 'Simsi_Sink', [('SaveDir', "'./signal'"), ('FileTag',
"'fragment_'"), ('SplitSize', '1000000'), ('Delay', '2')], [('0', 'complex',
1)], [], 'Embedded Python Block example - a simple multiply const', ['Delay',
'FileTag', 'SaveDir', 'SplitSize'])
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [728, 336.0]
rotation: 0
state: enabled
- name: osmosdr_source_1
id: osmosdr_source
parameters:
affinity: ''
alias: ''
ant0: ''
ant1: ''
ant10: ''
ant11: ''
ant12: ''
ant13: ''
ant14: ''
ant15: ''
ant16: ''
ant17: ''
ant18: ''
ant19: ''
ant2: ''
ant20: ''
ant21: ''
ant22: ''
ant23: ''
ant24: ''
ant25: ''
ant26: ''
ant27: ''
ant28: ''
ant29: ''
ant3: ''
ant30: ''
ant31: ''
ant4: ''
ant5: ''
ant6: ''
ant7: ''
ant8: ''
ant9: ''
args: hackrf=0
bb_gain0: '36'
bb_gain1: '20'
bb_gain10: '20'
bb_gain11: '20'
bb_gain12: '20'
bb_gain13: '20'
bb_gain14: '20'
bb_gain15: '20'
bb_gain16: '20'
bb_gain17: '20'
bb_gain18: '20'
bb_gain19: '20'
bb_gain2: '20'
bb_gain20: '20'
bb_gain21: '20'
bb_gain22: '20'
bb_gain23: '20'
bb_gain24: '20'
bb_gain25: '20'
bb_gain26: '20'
bb_gain27: '20'
bb_gain28: '20'
bb_gain29: '20'
bb_gain3: '20'
bb_gain30: '20'
bb_gain31: '20'
bb_gain4: '20'
bb_gain5: '20'
bb_gain6: '20'
bb_gain7: '20'
bb_gain8: '20'
bb_gain9: '20'
bw0: '0'
bw1: '0'
bw10: '0'
bw11: '0'
bw12: '0'
bw13: '0'
bw14: '0'
bw15: '0'
bw16: '0'
bw17: '0'
bw18: '0'
bw19: '0'
bw2: '0'
bw20: '0'
bw21: '0'
bw22: '0'
bw23: '0'
bw24: '0'
bw25: '0'
bw26: '0'
bw27: '0'
bw28: '0'
bw29: '0'
bw3: '0'
bw30: '0'
bw31: '0'
bw4: '0'
bw5: '0'
bw6: '0'
bw7: '0'
bw8: '0'
bw9: '0'
clock_source0: ''
clock_source1: ''
clock_source2: ''
clock_source3: ''
clock_source4: ''
clock_source5: ''
clock_source6: ''
clock_source7: ''
comment: ''
corr0: '0'
corr1: '0'
corr10: '0'
corr11: '0'
corr12: '0'
corr13: '0'
corr14: '0'
corr15: '0'
corr16: '0'
corr17: '0'
corr18: '0'
corr19: '0'
corr2: '0'
corr20: '0'
corr21: '0'
corr22: '0'
corr23: '0'
corr24: '0'
corr25: '0'
corr26: '0'
corr27: '0'
corr28: '0'
corr29: '0'
corr3: '0'
corr30: '0'
corr31: '0'
corr4: '0'
corr5: '0'
corr6: '0'
corr7: '0'
corr8: '0'
corr9: '0'
dc_offset_mode0: '0'
dc_offset_mode1: '0'
dc_offset_mode10: '0'
dc_offset_mode11: '0'
dc_offset_mode12: '0'
dc_offset_mode13: '0'
dc_offset_mode14: '0'
dc_offset_mode15: '0'
dc_offset_mode16: '0'
dc_offset_mode17: '0'
dc_offset_mode18: '0'
dc_offset_mode19: '0'
dc_offset_mode2: '0'
dc_offset_mode20: '0'
dc_offset_mode21: '0'
dc_offset_mode22: '0'
dc_offset_mode23: '0'
dc_offset_mode24: '0'
dc_offset_mode25: '0'
dc_offset_mode26: '0'
dc_offset_mode27: '0'
dc_offset_mode28: '0'
dc_offset_mode29: '0'
dc_offset_mode3: '0'
dc_offset_mode30: '0'
dc_offset_mode31: '0'
dc_offset_mode4: '0'
dc_offset_mode5: '0'
dc_offset_mode6: '0'
dc_offset_mode7: '0'
dc_offset_mode8: '0'
dc_offset_mode9: '0'
freq0: freq
freq1: 100e6
freq10: 100e6
freq11: 100e6
freq12: 100e6
freq13: 100e6
freq14: 100e6
freq15: 100e6
freq16: 100e6
freq17: 100e6
freq18: 100e6
freq19: 100e6
freq2: 100e6
freq20: 100e6
freq21: 100e6
freq22: 100e6
freq23: 100e6
freq24: 100e6
freq25: 100e6
freq26: 100e6
freq27: 100e6
freq28: 100e6
freq29: 100e6
freq3: 100e6
freq30: 100e6
freq31: 100e6
freq4: 100e6
freq5: 100e6
freq6: 100e6
freq7: 100e6
freq8: 100e6
freq9: 100e6
gain0: '12'
gain1: '10'
gain10: '10'
gain11: '10'
gain12: '10'
gain13: '10'
gain14: '10'
gain15: '10'
gain16: '10'
gain17: '10'
gain18: '10'
gain19: '10'
gain2: '10'
gain20: '10'
gain21: '10'
gain22: '10'
gain23: '10'
gain24: '10'
gain25: '10'
gain26: '10'
gain27: '10'
gain28: '10'
gain29: '10'
gain3: '10'
gain30: '10'
gain31: '10'
gain4: '10'
gain5: '10'
gain6: '10'
gain7: '10'
gain8: '10'
gain9: '10'
gain_mode0: 'False'
gain_mode1: 'False'
gain_mode10: 'False'
gain_mode11: 'False'
gain_mode12: 'False'
gain_mode13: 'False'
gain_mode14: 'False'
gain_mode15: 'False'
gain_mode16: 'False'
gain_mode17: 'False'
gain_mode18: 'False'
gain_mode19: 'False'
gain_mode2: 'False'
gain_mode20: 'False'
gain_mode21: 'False'
gain_mode22: 'False'
gain_mode23: 'False'
gain_mode24: 'False'
gain_mode25: 'False'
gain_mode26: 'False'
gain_mode27: 'False'
gain_mode28: 'False'
gain_mode29: 'False'
gain_mode3: 'False'
gain_mode30: 'False'
gain_mode31: 'False'
gain_mode4: 'False'
gain_mode5: 'False'
gain_mode6: 'False'
gain_mode7: 'False'
gain_mode8: 'False'
gain_mode9: 'False'
if_gain0: '30'
if_gain1: '20'
if_gain10: '20'
if_gain11: '20'
if_gain12: '20'
if_gain13: '20'
if_gain14: '20'
if_gain15: '20'
if_gain16: '20'
if_gain17: '20'
if_gain18: '20'
if_gain19: '20'
if_gain2: '20'
if_gain20: '20'
if_gain21: '20'
if_gain22: '20'
if_gain23: '20'
if_gain24: '20'
if_gain25: '20'
if_gain26: '20'
if_gain27: '20'
if_gain28: '20'
if_gain29: '20'
if_gain3: '20'
if_gain30: '20'
if_gain31: '20'
if_gain4: '20'
if_gain5: '20'
if_gain6: '20'
if_gain7: '20'
if_gain8: '20'
if_gain9: '20'
iq_balance_mode0: '0'
iq_balance_mode1: '0'
iq_balance_mode10: '0'
iq_balance_mode11: '0'
iq_balance_mode12: '0'
iq_balance_mode13: '0'
iq_balance_mode14: '0'
iq_balance_mode15: '0'
iq_balance_mode16: '0'
iq_balance_mode17: '0'
iq_balance_mode18: '0'
iq_balance_mode19: '0'
iq_balance_mode2: '0'
iq_balance_mode20: '0'
iq_balance_mode21: '0'
iq_balance_mode22: '0'
iq_balance_mode23: '0'
iq_balance_mode24: '0'
iq_balance_mode25: '0'
iq_balance_mode26: '0'
iq_balance_mode27: '0'
iq_balance_mode28: '0'
iq_balance_mode29: '0'
iq_balance_mode3: '0'
iq_balance_mode30: '0'
iq_balance_mode31: '0'
iq_balance_mode4: '0'
iq_balance_mode5: '0'
iq_balance_mode6: '0'
iq_balance_mode7: '0'
iq_balance_mode8: '0'
iq_balance_mode9: '0'
maxoutbuf: '0'
minoutbuf: '0'
nchan: '1'
num_mboards: '1'
sample_rate: samp_rate
sync: sync
time_source0: ''
time_source1: ''
time_source2: ''
time_source3: ''
time_source4: ''
time_source5: ''
time_source6: ''
time_source7: ''
type: fc32
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [244, 164]
rotation: 0
state: true
- name: qtgui_time_sink_x_0_1
id: qtgui_time_sink_x
parameters:
affinity: ''
alias: ''
alpha1: '1.0'
alpha10: '1.0'
alpha2: '1.0'
alpha3: '1.0'
alpha4: '1.0'
alpha5: '1.0'
alpha6: '1.0'
alpha7: '1.0'
alpha8: '1.0'
alpha9: '1.0'
autoscale: 'False'
axislabels: 'True'
color1: blue
color10: dark blue
color2: red
color3: green
color4: black
color5: cyan
color6: magenta
color7: yellow
color8: dark red
color9: dark green
comment: ''
ctrlpanel: 'False'
entags: 'True'
grid: 'False'
gui_hint: ''
label1: ''
label10: ''
label2: ''
label3: ''
label4: ''
label5: ''
label6: ''
label7: ''
label8: ''
label9: ''
legend: 'True'
marker1: '-1'
marker10: '-1'
marker2: '-1'
marker3: '-1'
marker4: '-1'
marker5: '-1'
marker6: '-1'
marker7: '-1'
marker8: '-1'
marker9: '-1'
name: '""'
nconnections: '1'
size: '1000000'
srate: samp_rate
stemplot: 'False'
style1: '1'
style10: '1'
style2: '1'
style3: '1'
style4: '1'
style5: '1'
style6: '1'
style7: '1'
style8: '1'
style9: '1'
tr_chan: '0'
tr_delay: '0'
tr_level: '0.0'
tr_mode: qtgui.TRIG_MODE_FREE
tr_slope: qtgui.TRIG_SLOPE_POS
tr_tag: '""'
type: complex
update_time: '0.01'
width1: '1'
width10: '1'
width2: '1'
width3: '1'
width4: '1'
width5: '1'
width6: '1'
width7: '1'
width8: '1'
width9: '1'
ylabel: Amplitude
ymax: '2'
ymin: '-2'
yunit: '""'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [720, 92.0]
rotation: 0
state: enabled
- name: qtgui_waterfall_sink_x_0
id: qtgui_waterfall_sink_x
parameters:
affinity: ''
alias: ''
alpha1: '1.0'
alpha10: '1.0'
alpha2: '1.0'
alpha3: '1.0'
alpha4: '1.0'
alpha5: '1.0'
alpha6: '1.0'
alpha7: '1.0'
alpha8: '1.0'
alpha9: '1.0'
axislabels: 'True'
bw: samp_rate
color1: '0'
color10: '0'
color2: '0'
color3: '0'
color4: '0'
color5: '0'
color6: '0'
color7: '0'
color8: '0'
color9: '0'
comment: ''
fc: freq
fftsize: '32768'
freqhalf: 'True'
grid: 'False'
gui_hint: ''
int_max: '10'
int_min: '-140'
label1: ''
label10: ''
label2: ''
label3: ''
label4: ''
label5: ''
label6: ''
label7: ''
label8: ''
label9: ''
legend: 'True'
maxoutbuf: '0'
minoutbuf: '0'
name: '""'
nconnections: '1'
showports: 'False'
type: complex
update_time: '0.10'
wintype: window.WIN_HAMMING
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [1040, 172.0]
rotation: 0
state: enabled
connections:
- [osmosdr_source_1, '0', epy_block_0, '0']
- [osmosdr_source_1, '0', qtgui_time_sink_x_0_1, '0']
- [osmosdr_source_1, '0', qtgui_waterfall_sink_x_0, '0']
metadata:
file_format: 1
grc_version: 3.10.9.2

@ -0,0 +1,683 @@
options:
parameters:
author: ''
catch_exceptions: 'True'
category: '[GRC Hier Blocks]'
cmake_opt: ''
comment: ''
copyright: ''
description: ''
gen_cmake: 'On'
gen_linking: dynamic
generate_options: no_gui
hier_block_src_path: '.:'
id: fft_detector
max_nouts: '0'
output_language: python
placement: (0,0)
qt_qss_theme: ''
realtime_scheduling: ''
run: 'True'
run_command: '{python} -u {filename}'
run_options: prompt
sizing_mode: fixed
thread_safe_setters: ''
title: fft_detector
window_size: (1000,1000)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [8, 8]
rotation: 0
state: enabled
blocks:
- name: filter1
id: variable
parameters:
comment: ''
value: firdes.low_pass (1, samp_rate, 500e3, 300e3, window.WIN_BLACKMAN_HARRIS)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [464, 16.0]
rotation: 0
state: true
- name: filter2
id: variable
parameters:
comment: ''
value: firdes.low_pass(1,samp_rate, 5e3, 3e3, window.WIN_HANN)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [696, 16.0]
rotation: 0
state: true
- name: freq
id: variable
parameters:
comment: ''
value: py_module.work(func_probe)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [368, 16.0]
rotation: 0
state: true
- name: func_probe
id: variable_function_probe
parameters:
block_id: vec_probe
comment: ''
function_args: ''
function_name: level
poll_rate: '100'
value: '0'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [1312, 128.0]
rotation: 0
state: enabled
- name: max_f
id: variable
parameters:
comment: ''
value: 2.46e9
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [536, 16.0]
rotation: 0
state: disabled
- name: min_f
id: variable
parameters:
comment: ''
value: 2.4e9
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [456, 16.0]
rotation: 0
state: disabled
- name: samp_rate
id: variable
parameters:
comment: ''
value: 20e6
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [184, 12]
rotation: 0
state: enabled
- name: blocks_complex_to_mag_squared_0
id: blocks_complex_to_mag_squared
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
vlen: '2048'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [840, 120.0]
rotation: 0
state: true
- name: blocks_integrate_xx_0
id: blocks_integrate_xx
parameters:
affinity: ''
alias: ''
comment: ''
decim: '10'
maxoutbuf: '0'
minoutbuf: '0'
type: float
vlen: '2048'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [840, 192.0]
rotation: 0
state: true
- name: blocks_keep_one_in_n_0
id: blocks_keep_one_in_n
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
n: '1'
type: complex
vlen: '2048'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [368, 272.0]
rotation: 0
state: true
- name: blocks_nlog10_ff_0
id: blocks_nlog10_ff
parameters:
affinity: ''
alias: ''
comment: ''
k: '-100'
maxoutbuf: '0'
minoutbuf: '0'
n: '10'
vlen: '2048'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [840, 280.0]
rotation: 0
state: true
- name: blocks_stream_to_vector_0_0
id: blocks_stream_to_vector
parameters:
affinity: ''
alias: ''
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
num_items: '2048'
type: complex
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [368, 216.0]
rotation: 0
state: true
- name: dc_blocker_xx_0
id: dc_blocker_xx
parameters:
affinity: ''
alias: ''
comment: ''
length: '1024'
long_form: 'True'
maxoutbuf: '0'
minoutbuf: '0'
type: cc
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [368, 136.0]
rotation: 0
state: true
- name: fft_vxx_0
id: fft_vxx
parameters:
affinity: ''
alias: ''
comment: ''
fft_size: '2048'
forward: 'True'
maxoutbuf: '0'
minoutbuf: '0'
nthreads: '1'
shift: 'True'
type: complex
window: window.blackmanharris(2048)
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [576, 192.0]
rotation: 0
state: true
- name: osmosdr_source_0
id: osmosdr_source
parameters:
affinity: ''
alias: ''
ant0: ''
ant1: ''
ant10: ''
ant11: ''
ant12: ''
ant13: ''
ant14: ''
ant15: ''
ant16: ''
ant17: ''
ant18: ''
ant19: ''
ant2: ''
ant20: ''
ant21: ''
ant22: ''
ant23: ''
ant24: ''
ant25: ''
ant26: ''
ant27: ''
ant28: ''
ant29: ''
ant3: ''
ant30: ''
ant31: ''
ant4: ''
ant5: ''
ant6: ''
ant7: ''
ant8: ''
ant9: ''
args: hackrf=0
bb_gain0: '0'
bb_gain1: '20'
bb_gain10: '20'
bb_gain11: '20'
bb_gain12: '20'
bb_gain13: '20'
bb_gain14: '20'
bb_gain15: '20'
bb_gain16: '20'
bb_gain17: '20'
bb_gain18: '20'
bb_gain19: '20'
bb_gain2: '20'
bb_gain20: '20'
bb_gain21: '20'
bb_gain22: '20'
bb_gain23: '20'
bb_gain24: '20'
bb_gain25: '20'
bb_gain26: '20'
bb_gain27: '20'
bb_gain28: '20'
bb_gain29: '20'
bb_gain3: '20'
bb_gain30: '20'
bb_gain31: '20'
bb_gain4: '20'
bb_gain5: '20'
bb_gain6: '20'
bb_gain7: '20'
bb_gain8: '20'
bb_gain9: '20'
bw0: 20e6
bw1: '0'
bw10: '0'
bw11: '0'
bw12: '0'
bw13: '0'
bw14: '0'
bw15: '0'
bw16: '0'
bw17: '0'
bw18: '0'
bw19: '0'
bw2: '0'
bw20: '0'
bw21: '0'
bw22: '0'
bw23: '0'
bw24: '0'
bw25: '0'
bw26: '0'
bw27: '0'
bw28: '0'
bw29: '0'
bw3: '0'
bw30: '0'
bw31: '0'
bw4: '0'
bw5: '0'
bw6: '0'
bw7: '0'
bw8: '0'
bw9: '0'
clock_source0: ''
clock_source1: ''
clock_source2: ''
clock_source3: ''
clock_source4: ''
clock_source5: ''
clock_source6: ''
clock_source7: ''
comment: ''
corr0: '0'
corr1: '0'
corr10: '0'
corr11: '0'
corr12: '0'
corr13: '0'
corr14: '0'
corr15: '0'
corr16: '0'
corr17: '0'
corr18: '0'
corr19: '0'
corr2: '0'
corr20: '0'
corr21: '0'
corr22: '0'
corr23: '0'
corr24: '0'
corr25: '0'
corr26: '0'
corr27: '0'
corr28: '0'
corr29: '0'
corr3: '0'
corr30: '0'
corr31: '0'
corr4: '0'
corr5: '0'
corr6: '0'
corr7: '0'
corr8: '0'
corr9: '0'
dc_offset_mode0: '0'
dc_offset_mode1: '0'
dc_offset_mode10: '0'
dc_offset_mode11: '0'
dc_offset_mode12: '0'
dc_offset_mode13: '0'
dc_offset_mode14: '0'
dc_offset_mode15: '0'
dc_offset_mode16: '0'
dc_offset_mode17: '0'
dc_offset_mode18: '0'
dc_offset_mode19: '0'
dc_offset_mode2: '0'
dc_offset_mode20: '0'
dc_offset_mode21: '0'
dc_offset_mode22: '0'
dc_offset_mode23: '0'
dc_offset_mode24: '0'
dc_offset_mode25: '0'
dc_offset_mode26: '0'
dc_offset_mode27: '0'
dc_offset_mode28: '0'
dc_offset_mode29: '0'
dc_offset_mode3: '0'
dc_offset_mode30: '0'
dc_offset_mode31: '0'
dc_offset_mode4: '0'
dc_offset_mode5: '0'
dc_offset_mode6: '0'
dc_offset_mode7: '0'
dc_offset_mode8: '0'
dc_offset_mode9: '0'
freq0: freq
freq1: 100e6
freq10: 100e6
freq11: 100e6
freq12: 100e6
freq13: 100e6
freq14: 100e6
freq15: 100e6
freq16: 100e6
freq17: 100e6
freq18: 100e6
freq19: 100e6
freq2: 100e6
freq20: 100e6
freq21: 100e6
freq22: 100e6
freq23: 100e6
freq24: 100e6
freq25: 100e6
freq26: 100e6
freq27: 100e6
freq28: 100e6
freq29: 100e6
freq3: 100e6
freq30: 100e6
freq31: 100e6
freq4: 100e6
freq5: 100e6
freq6: 100e6
freq7: 100e6
freq8: 100e6
freq9: 100e6
gain0: '100'
gain1: '10'
gain10: '10'
gain11: '10'
gain12: '10'
gain13: '10'
gain14: '10'
gain15: '10'
gain16: '10'
gain17: '10'
gain18: '10'
gain19: '10'
gain2: '10'
gain20: '10'
gain21: '10'
gain22: '10'
gain23: '10'
gain24: '10'
gain25: '10'
gain26: '10'
gain27: '10'
gain28: '10'
gain29: '10'
gain3: '10'
gain30: '10'
gain31: '10'
gain4: '10'
gain5: '10'
gain6: '10'
gain7: '10'
gain8: '10'
gain9: '10'
gain_mode0: 'False'
gain_mode1: 'False'
gain_mode10: 'False'
gain_mode11: 'False'
gain_mode12: 'False'
gain_mode13: 'False'
gain_mode14: 'False'
gain_mode15: 'False'
gain_mode16: 'False'
gain_mode17: 'False'
gain_mode18: 'False'
gain_mode19: 'False'
gain_mode2: 'False'
gain_mode20: 'False'
gain_mode21: 'False'
gain_mode22: 'False'
gain_mode23: 'False'
gain_mode24: 'False'
gain_mode25: 'False'
gain_mode26: 'False'
gain_mode27: 'False'
gain_mode28: 'False'
gain_mode29: 'False'
gain_mode3: 'False'
gain_mode30: 'False'
gain_mode31: 'False'
gain_mode4: 'False'
gain_mode5: 'False'
gain_mode6: 'False'
gain_mode7: 'False'
gain_mode8: 'False'
gain_mode9: 'False'
if_gain0: '100'
if_gain1: '20'
if_gain10: '20'
if_gain11: '20'
if_gain12: '20'
if_gain13: '20'
if_gain14: '20'
if_gain15: '20'
if_gain16: '20'
if_gain17: '20'
if_gain18: '20'
if_gain19: '20'
if_gain2: '20'
if_gain20: '20'
if_gain21: '20'
if_gain22: '20'
if_gain23: '20'
if_gain24: '20'
if_gain25: '20'
if_gain26: '20'
if_gain27: '20'
if_gain28: '20'
if_gain29: '20'
if_gain3: '20'
if_gain30: '20'
if_gain31: '20'
if_gain4: '20'
if_gain5: '20'
if_gain6: '20'
if_gain7: '20'
if_gain8: '20'
if_gain9: '20'
iq_balance_mode0: '0'
iq_balance_mode1: '0'
iq_balance_mode10: '0'
iq_balance_mode11: '0'
iq_balance_mode12: '0'
iq_balance_mode13: '0'
iq_balance_mode14: '0'
iq_balance_mode15: '0'
iq_balance_mode16: '0'
iq_balance_mode17: '0'
iq_balance_mode18: '0'
iq_balance_mode19: '0'
iq_balance_mode2: '0'
iq_balance_mode20: '0'
iq_balance_mode21: '0'
iq_balance_mode22: '0'
iq_balance_mode23: '0'
iq_balance_mode24: '0'
iq_balance_mode25: '0'
iq_balance_mode26: '0'
iq_balance_mode27: '0'
iq_balance_mode28: '0'
iq_balance_mode29: '0'
iq_balance_mode3: '0'
iq_balance_mode30: '0'
iq_balance_mode31: '0'
iq_balance_mode4: '0'
iq_balance_mode5: '0'
iq_balance_mode6: '0'
iq_balance_mode7: '0'
iq_balance_mode8: '0'
iq_balance_mode9: '0'
maxoutbuf: '2048'
minoutbuf: '2048'
nchan: '1'
num_mboards: '1'
sample_rate: samp_rate
sync: sync
time_source0: ''
time_source1: ''
time_source2: ''
time_source3: ''
time_source4: ''
time_source5: ''
time_source6: ''
time_source7: ''
type: fc32
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [80, 132.0]
rotation: 0
state: true
- name: py_module
id: epy_module
parameters:
alias: ''
comment: ''
source_code: "# this module will be imported in the into your flowgraph\r\n\r\n\
import numpy as np\r\nimport os\r\nimport time \r\n\r\nimport matplotlib.pyplot\
\ as plt\r\nimport math\r\n\r\n\r\n##################################\r\n# frequency\
\ change params\r\n##################################\r\n\r\nmin_f = 0.400e9\
\ # 2.38e9\r\nmax_f = 0.500e9 # 2.52e9\r\nstep_f = 1e6 # 10e6\r\nf = min_f +\
\ step_f / 2\r\n\r\n\r\n##################################\r\n# spectrum\r\n\
##################################\r\n\r\nbins = 2048\r\nsavepath = 'C:/Users/ftlen/Work/GNU\
\ Radio/fft_detector/pics/433/'\r\n#savepath = 'C:/Users/ftlen/\u0420\u0430\u0431\
\u043E\u0447\u0438\u0439 \u0441\u0442\u043E\u043B/\u043D\u0438\u043A\u0438\u0442\
\u0430/'\r\n#filetag = '433_transmitter_denis_teleskop_'\r\nfiletag = '433_noise_office_teleskop_'\r\
\n\r\nfileit = 1\r\nsplit_size = 1_000_000\r\nmax_its = 10\r\nmax_iter = 0\r\
\n\r\nlast_spectrum_arr = np.array([])\r\nsignal_arr = np.array([])\r\n\r\n\
def set_spec_arr_zero(): \r\n global bins, min_f, max_f, step_f\r\n arr\
\ = np.array([-100] * int(((max_f - min_f) / step_f - 1) * bins), dtype=np.float32)\r\
\n return arr\r\n\r\nlast_spectrum_arr = set_spec_arr_zero()\r\n\r\n\r\n\
def moving_average(x, w=50):\r\n return np.convolve(x, np.ones(w), 'valid')\
\ / w\r\n##################################\r\n# main\r\n##################################\r\
\n\r\ndef work(lvl):\r\n global f, min_f, max_f, step_f\r\n global last_spectrum_arr,\
\ bins\r\n global savepath, filetag, fileit\r\n global signal_arr, split_size\r\
\n global max_its, max_iter\r\n #print('wrk')\r\n if f >= max_f - step_f:\r\
\n f = min_f + step_f / 2\r\n #print('!', last_spectrum_arr.shape)\r\
\n last_spectrum_arr = moving_average(last_spectrum_arr)\r\n plt.ylim(-100,\
\ -50)\r\n plt.xlim(min_f, max_f)\r\n x = np.linspace(min_f, max_f,\
\ len(last_spectrum_arr))\r\n plt.plot(x, last_spectrum_arr)\r\n \
\ plt.savefig(savepath + filetag + str(fileit))\r\n fileit += 1\r\n\
\ plt.close()\r\n last_spectrum_arr = set_spec_arr_zero()\r\n\
\ return f\r\n\r\n y = np.array(lvl).ravel()\r\n if len(y) == 2048:\r\
\n arr = y # / np.linalg.norm(y)\r\n\r\n x1 = int((f-min_f)/step_f\
\ * bins - bins/2)\r\n x2 = int((f-min_f)/step_f * bins + bins/2)\r\n\
\r\n override_arr = last_spectrum_arr[x1:x2]\r\n\r\n #override_arr\
\ = np.maximum(arr, override_arr)\r\n override_arr = np.mean( np.array([\
\ arr, override_arr ]), axis=0 )\r\n\r\n last_spectrum_arr[x1:x2] = override_arr\r\
\n\r\n if max_iter == max_its:\r\n f += step_f\r\n \
\ max_iter = 0\r\n else:\r\n max_iter += 1\r\n return\
\ f\r\n "
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [1312, 232.0]
rotation: 0
state: enabled
- name: vec_probe
id: blocks_probe_signal_vx
parameters:
affinity: ''
alias: ''
comment: ''
type: float
vlen: '2048'
states:
bus_sink: false
bus_source: false
bus_structure: null
coordinate: [1096, 192.0]
rotation: 0
state: enabled
connections:
- [blocks_complex_to_mag_squared_0, '0', blocks_integrate_xx_0, '0']
- [blocks_integrate_xx_0, '0', blocks_nlog10_ff_0, '0']
- [blocks_keep_one_in_n_0, '0', fft_vxx_0, '0']
- [blocks_nlog10_ff_0, '0', vec_probe, '0']
- [blocks_stream_to_vector_0_0, '0', blocks_keep_one_in_n_0, '0']
- [dc_blocker_xx_0, '0', blocks_stream_to_vector_0_0, '0']
- [fft_vxx_0, '0', blocks_complex_to_mag_squared_0, '0']
- [osmosdr_source_0, '0', dc_blocker_xx_0, '0']
metadata:
file_format: 1
grc_version: 3.10.7.0

File diff suppressed because it is too large Load Diff

@ -1,170 +1,258 @@
import statistics import os
import statistics
# Более лучшая версия кода есть в FRScanner from datetime import datetime
class DataBuffer: # Более лучшая версия кода есть в FRScanner
"""
Класс с реализацией циклического буффера.
class DataBuffer:
Атрибуты: """
current_column: Указатель на текущий столбец буфера, который обновляем. Класс с реализацией циклического буффера.
thinning_counter: Прореживающий множитель на текующей итерации.
current_counter: Указатель на количество чтений между последним обновлением столбца и предыдущим атрибутом. Атрибуты:
num_of_thinning_iter: Прореживающий множитель. Раз в это количечество раз будет обнволяться столбец буфера. current_column: Указатель на текущий столбец буфера, который обновляем.
line_size: Количество строк буфера = количеству каналов. thinning_counter: Прореживающий множитель на текующей итерации.
columns_size: Количество столбцов = фиксированное число. current_counter: Указатель на количество чтений между последним обновлением столбца и предыдущим атрибутом.
multiply_factor: Процентный показатель превышения сигналом уровня шума. ex m_p = 1.1 => триггер, если num_of_thinning_iter: Прореживающий множитель. Раз в это количество раз будет обновляться столбец буфера.
сигнал превышает шум на 10%. line_size: Количество строк буфера = количеству каналов.
num_for_alarm: Количество раз, превышающих шум, при которых триггеримся = фиксированное число. columns_size: Количество столбцов = фиксированное число.
is_init: Флаг инициализации буфера. = True, если инициализирован. multiply_factor: Процентный показатель превышения сигналом уровня шума (legacy).
buffer: Массив для буфера. num_for_alarm: Количество раз, превышающих шум, при которых триггеримся.
buffer_medians: Массив для медиан столбцов букера. is_init: Флаг инициализации буфера.
buffer_alarms: Массив для количества тревог по столбца буфера. buffer: Массив для буфера.
""" buffer_medians: Массив медиан по каналам.
buffer_mads: Массив MAD по каналам.
def __init__(self, columns_size, num_of_thinning_iter, num_of_channels, multiply_factor, num_for_alarm): buffer_alarms: Массив для количества тревог по каналам.
""" """
Инициализируем класс.
def __init__(self, columns_size, num_of_thinning_iter, num_of_channels, multiply_factor, num_for_alarm, freq_tag=None):
:param columns_size: self.current_column = 0
:param num_of_thinning_iter: self.thinning_counter = 1
:param num_of_channels: self.current_counter = 1
:param multiply_factor: self.num_of_thinning_iter = num_of_thinning_iter
:param num_for_alarm: self.line_size = num_of_channels
""" self.columns_size = columns_size
self.current_column = 0 self.multiply_factor = multiply_factor
self.thinning_counter = 1 self.num_for_alarm = num_for_alarm
self.current_counter = 1 self.is_init = False
self.num_of_thinning_iter = num_of_thinning_iter
self.line_size = num_of_channels self.buffer = [[0 for _ in range(self.columns_size)] for _ in range(self.line_size)]
self.columns_size = columns_size self.buffer_timestamps = [[None for _ in range(self.columns_size)] for _ in range(self.line_size)]
self.multiply_factor = multiply_factor self.buffer_medians = [0.0] * self.line_size
self.num_for_alarm = num_for_alarm self.buffer_mads = [0.0] * self.line_size
self.is_init = False self.buffer_alarms = [0] * self.line_size
self.buffer = [[0 for _ in range(self.columns_size)] for _ in range(self.line_size)] self.last_alarm_channels = []
self.buffer_medians = [0] * self.line_size self.episode_history = [[0.0 for _ in range(self.num_of_thinning_iter)] for _ in range(self.line_size)]
self.buffer_alarms = [0] * self.line_size self.episode_history_timestamps = [[None for _ in range(self.num_of_thinning_iter)] for _ in range(self.line_size)]
def get_buffer(self): self.freq_tag = '' if freq_tag is None else str(freq_tag)
return self.buffer suffix = f'_{self.freq_tag}' if self.freq_tag else ''
def get_medians(self): self.mad_k_on = float(os.getenv('mad_k_on' + suffix, os.getenv('mad_k_on', 5.0)))
return self.buffer_medians self.mad_eps = float(os.getenv('mad_eps' + suffix, os.getenv('mad_eps', 0.05)))
self.dbfs_linear_offset_db = float(
def get_alarms(self): os.getenv('dbfs_linear_offset_db' + suffix, os.getenv('dbfs_linear_offset_db', 0.0))
return self.buffer_alarms )
self.dbfs_linear_abs_median_scale = float(
def check_init(self): os.getenv('dbfs_linear_abs_median_scale' + suffix, os.getenv('dbfs_linear_abs_median_scale', 0.0))
return self.is_init )
def print(self): def get_buffer(self):
print('buffer is: ') return self.buffer
for i in range(self.line_size):
print(self.buffer[i], end=' ') def get_timestamps(self):
print() return self.buffer_timestamps
def medians(self): def get_medians(self):
""" return self.buffer_medians
Вычислить медиану по строке буфера.
:return: None def get_mads(self):
""" return self.buffer_mads
if self.check_init():
for i in range(self.line_size): def get_alarms(self):
self.buffer_medians[i] = statistics.median(self.buffer[i]) return self.buffer_alarms
# print('medians is: ', self.buffer_medians)
# return self.buffer_medians def get_last_alarm_channels(self):
return list(self.last_alarm_channels)
def alarms_fill_zeros(self):
self.buffer_alarms = [0] * self.line_size def check_init(self):
def update(self, data): return self.is_init
"""
Обновление буфера. def print(self):
Если номер текущего чтения совпадает с количеством прореживающего множителя на текущем обновлении буфера, то print('buffer is: ')
1. Обновляем буфер. for i in range(self.line_size):
2. Двигаем курсор на след столбец. Если был последний столбец, то двигаем курсор в начало. print(self.buffer[i], end=' ')
3. Берем медианы по буферу, если он уже проиницализирован. print()
4. Сбрасываем счетчик текущих чтений.
5. Если был последний столбец (и мы уже переключились на первый), то @staticmethod
Если прореживающий множитель на текующей итерации был единица, то мы иницилизировались def _calc_mad(values, median):
До тех пор, пока множитель на итерации меньше фиксированного, увеличиваем в два раза. deviations = [abs(v - median) for v in values]
В противном случае - увеличиваем номер чтения. return statistics.median(deviations)
:param data: Массив с метриками сигнала по каналам.
:return: None @staticmethod
""" def _format_ts(timestamp):
if timestamp is None:
# TODO: Добавить время релаксации - если система затриггерилась, то перестать обновлять буфер на N чтений, return 'None'
# где N задается в .env-template. Сейчас есть бага, что буфер перестает обновляться только когда система try:
# триггерится. Между тем, когда приходит аларм и num_for_alarm, когда сигнал алармовский, но система еще не return datetime.fromtimestamp(float(timestamp)).isoformat(sep=' ', timespec='milliseconds')
# триггерится, буфер продолжает обновляться. В таких условиях буфер может набрать в себя алармовских сигналов except Exception:
# и повысить пороги. Пример такой ситуации: дрон висит на 1км, система его видит, но сигнал превышает порог раз return str(timestamp)
# через раз и аларм срабатывает не всегда. В таких условиях наберется высокий сигнал, повысятся пороги и когда
# дрон начнет движение вперед, он будет заметен на более низкой дистанции, чем обычно, так как пороги повышены. @staticmethod
def _mean_timestamp(timestamps):
if self.current_counter == self.thinning_counter: filtered = [float(ts) for ts in timestamps if ts is not None]
for i in range(self.line_size): if not filtered:
self.buffer[i][self.current_column] = data[i] return None
self.current_column = (self.current_column + 1) % self.columns_size return sum(filtered) / len(filtered)
#print('Столбец {0} обновлен. Перешли к столбцу {1}: '.format(self.current_column - 1, self.current_column))
self.medians() def medians(self):
self.current_counter = 1 """
if self.current_column == 0: Вычислить медиану и MAD по строкам буфера.
if self.thinning_counter == 1: :return: None
self.is_init = True """
self.medians() if self.check_init():
print('Начальная калибровка завершена.') for i in range(self.line_size):
if self.thinning_counter < self.num_of_thinning_iter: med = float(statistics.median(self.buffer[i]))
self.thinning_counter *= 2 self.buffer_medians[i] = med
# print('thinning counter обновлен: ', self.thinning_counter) self.buffer_mads[i] = float(self._calc_mad(self.buffer[i], med))
else: def get_linear_term(self, median_value):
self.current_counter += 1 median_value = float(median_value)
# print('curr counter обновлен: ', self.current_counter) return self.dbfs_linear_offset_db + self.dbfs_linear_abs_median_scale * abs(median_value)
def check_alarm(self, data): def get_threshold(self, channel_idx):
""" """
Проверка триггера системы. Получить динамический порог в dB для канала:
Если значение по каналу превышает медиану (порог) шума на какой-то процент, то инкремент буфер аларма по каналу. threshold = median + linear_term(median) + mad_k_on * MAD.
Превышение num_for_alarm подряд - триггер. Если после n превышений, где n<num_for_alarm приходит сигнал не До завершения инициализации возвращает None.
первышающий порог, то сбрасываем буфер алармов. """
:param data: if not self.check_init():
:return: Да/нет. return None
"""
if self.check_init(): baseline = float(self.buffer_medians[channel_idx])
ratios=[] mad_eff = max(float(self.buffer_mads[channel_idx]), self.mad_eps)
print("="*50) linear_term = self.get_linear_term(baseline)
for i in range(len(data)): return baseline + linear_term + self.mad_k_on * mad_eff
exceeding = data[i] > self.multiply_factor * self.buffer_medians[i]
ratios.append(data[i]/self.buffer_medians[i]) def get_thresholds(self):
if exceeding: if not self.check_init():
self.buffer_alarms[i] += 1 return [None] * self.line_size
# print('Инкремент буффер алармов по каналу {0}, текущее число по этому каналу: {1}'.format(i,self.buffer_alarms[i])) return [self.get_threshold(i) for i in range(self.line_size)]
else:
self.buffer_alarms[i] = 0 def log_threshold_update(self, updated_column):
# print('Обнулили буффер алармов по каналу {0}, текущее число по этому каналу: {1}'.format(i,self.buffer_alarms[i])) if not self.check_init():
return
if self.buffer_alarms[i] >= self.num_for_alarm:
# print('Сработала тревога по каналу {0}, текущее число по этому каналу: {1}'.format(i,self.buffer_alarms[i])) now_str = datetime.now().isoformat(sep=' ', timespec='milliseconds')
self.buffer_alarms = [0] * self.line_size freq_tag = self.freq_tag or 'unknown'
print("Отношения:", [f"{r:.3f}" for r in ratios]) print(f'[threshold-update][{freq_tag}] now={now_str} updated_column={updated_column}')
print("!"*50) for i in range(self.line_size):
return True baseline = float(self.buffer_medians[i])
print("Отношения:", [f"{r:.3f}" for r in ratios]) mad = float(self.buffer_mads[i])
print("="*50) mad_eff = max(mad, self.mad_eps)
linear_term = self.get_linear_term(baseline)
threshold = self.get_threshold(i)
return False packet_times = [self._format_ts(ts) for ts in self.buffer_timestamps[i]]
print(
def check_single_alarm(self, median, cur_channel): f' ch={i} median={baseline:.6f} '
""" f'linear_term={linear_term:.6f} '
Проверка, является ли текущая медиана по каналу превышающей порог. f'mad={mad:.6f} mad_eff={mad_eff:.6f} '
:param median: меди (хар-ка) по каналу. f'mad_term={self.mad_k_on * mad_eff:.6f} '
:param cur_channel: индекс канала внутри частоты. f'threshold={threshold:.6f} '
:return: Да/нет. f'packet_times={packet_times}'
""" )
if self.check_init():
exceeding = median > self.multiply_factor * self.buffer_medians[cur_channel] def alarms_fill_zeros(self):
print(median/self.buffer_medians[cur_channel]) self.buffer_alarms = [0] * self.line_size
if exceeding: self.last_alarm_channels = []
return True
else: def update(self, data, packet_timestamps=None):
return False """
Обновление буфера.
Если номер текущего чтения совпадает с количеством прореживающего множителя на текущем обновлении буфера, то
1. Обновляем буфер.
2. Двигаем курсор на след столбец. Если был последний столбец, то двигаем курсор в начало.
3. Берем медианы по буферу, если он уже проиницализирован.
4. Сбрасываем счетчик текущих чтений.
5. Если был последний столбец (и мы уже переключились на первый), то
Если прореживающий множитель на текующей итерации был единица, то мы иницилизировались.
До тех пор, пока множитель на итерации меньше фиксированного, увеличиваем в два раза.
В противном случае - увеличиваем номер чтения.
:param data: Массив с метриками сигнала по каналам.
:param packet_timestamps: Времена пакетов SDR для каждой метрики канала.
:return: None
"""
if packet_timestamps is None:
packet_timestamps = [None] * self.line_size
if len(packet_timestamps) != self.line_size:
raise ValueError('packet_timestamps length must match number of channels')
sample_idx = self.current_counter - 1
for i in range(self.line_size):
self.episode_history[i][sample_idx] = float(data[i])
self.episode_history_timestamps[i][sample_idx] = packet_timestamps[i]
if self.current_counter == self.thinning_counter:
updated_column = self.current_column
for i in range(self.line_size):
samples = self.episode_history[i][:self.thinning_counter]
timestamps = self.episode_history_timestamps[i][:self.thinning_counter]
self.buffer[i][self.current_column] = float(sum(samples) / len(samples))
self.buffer_timestamps[i][self.current_column] = self._mean_timestamp(timestamps)
self.current_column = (self.current_column + 1) % self.columns_size
self.medians()
if self.check_init():
self.log_threshold_update(updated_column)
for i in range(self.line_size):
for j in range(self.thinning_counter):
self.episode_history[i][j] = 0.0
self.episode_history_timestamps[i][j] = None
self.current_counter = 1
if self.current_column == 0:
if self.thinning_counter == 1:
self.is_init = True
self.medians()
print('Начальная калибровка завершена.')
self.log_threshold_update(updated_column)
if self.thinning_counter < self.num_of_thinning_iter:
self.thinning_counter *= 2
else:
self.current_counter += 1
def check_alarm(self, data):
"""
Проверка триггера системы по dBFS во времени.
Один порог на канал, набор тревоги и сброс счетчиков как в main.
"""
if self.check_init():
self.last_alarm_channels = []
for i in range(len(data)):
current = data[i]
threshold = self.get_threshold(i)
exceeding = current >= threshold
if exceeding:
self.buffer_alarms[i] += 1
else:
self.buffer_alarms[i] = 0
if self.buffer_alarms[i] >= self.num_for_alarm:
self.last_alarm_channels = [i]
self.buffer_alarms = [0] * self.line_size
return True
return False
def check_single_alarm(self, median, cur_channel):
"""
Проверка, является ли текущая метрика по каналу превышающей порог.
:param median: текущая метрика в dBFS.
:param cur_channel: индекс канала внутри частоты.
:return: Да/нет.
"""
if self.check_init():
threshold = self.get_threshold(cur_channel)
return median >= threshold
return False

@ -1,168 +1,89 @@
import os from core.data_buffer import DataBuffer
from core.data_buffer import DataBuffer
class MultiChannel:
def get_centre_freq(freq): def __init__(self, steps, bases, roofs):
""" self.steps = steps
Получить название частоты по ее диапазону. self.bases = bases
:param freq: Частота, которую обрабатываем. self.roofs = roofs
:return: Название частоты. self.cur_channel = self.bases[0]
""" self.cur_roof = self.roofs[0]
c_freq = 0 self.cur_step = self.steps[0]
if 5.46e9 <= freq <= 6.0e9: self.num_chs = []
c_freq = 5800 self.init_freq = False
if 5.0e9 <= freq <= 5.4e9: self.DB = []
c_freq = 5200
if 4.5e9 <= freq <= 4.7e9: def init_f(self):
c_freq = 4500 self.init_freq = True
if 3.3e9 <= freq <= 3.5e9: return self.bases[0]
c_freq = 3300
if 2.4e9 <= freq <= 2.5e9: def get_cur_channel(self):
c_freq = 2400 return self.cur_channel
if 1e9 <= freq <= 1.36e9:
c_freq = 1200 @staticmethod
if 0.9e9 <= freq <= 0.960e9: def _range_finished(channel, roof, step):
c_freq = 915 if step < 0:
if 0.830e9 <= freq <= 0.890e9: return channel <= roof
c_freq = 868 return channel >= roof
if 0.700e9 <= freq <= 0.780e9:
c_freq = 750 def change_channel(self):
if 0.380e9 <= freq <= 0.500e9: if not self.init_freq:
c_freq = 433 return self.init_f()
return str(c_freq)
current_idx = self.roofs.index(self.cur_roof)
if self._range_finished(self.cur_channel, self.cur_roof, self.cur_step):
class MultiChannel: next_idx = (current_idx + 1) % len(self.bases)
""" self.cur_channel = self.bases[next_idx]
Класс с реализацией переключателя каналов. Присутствует поддержка нескольких частот, а поэтому self.cur_roof = self.roofs[next_idx]
Атрибуты: self.cur_step = self.steps[next_idx]
steps: Массив шагов для разных частот. Ex. steps = [-20e6, -5e6, -3e6], i-ый элемент соответствует i-ой else:
частоте для обработке, типа 1.2, 915 и 868. self.cur_channel += self.cur_step
bases: Массив верхних границ диапазонов рассматриваемых частот. Ex bases = [1.36e9, 0.93e9, 0.87e9] для return self.get_cur_channel()
1.2, 915 и 868.
roofs: То же самое, только нижних границ. Ex roofs = [1e9, 0.9e9, 0.85e9] def get_num_chs(self, idx_freq):
cur_channel: Указатель на текущий канал, который обрабатываем. if (idx_freq + 1) > len(self.num_chs):
cur_roof: Указатель на нижнюю границу текущей обрабатываемой частоты. tmp = self.bases[idx_freq]
cur_step: Указатель на шаг текущей обрабатываемой частоты. roof = self.roofs[idx_freq]
num_chs: Массив из каналов по обрабатываемым частотам. Вычисляется автоматически исходя из границ и шага. step = self.steps[idx_freq]
init_freq: Чекер на инициализацию частоты перед началом работы скрипта. Нужен из-за особенности counter = 0
работы графов GNURadio и функции work в embedded Python блоке. if step == 0:
DB: Список из циклических буферов для соответствующих чатсот. raise ValueError('step must not be zero')
""" if step < 0:
while tmp >= roof:
def __init__(self, steps, bases, roofs): counter += 1
""" tmp += step
Инициализация класса. else:
:param steps: Список с шагами для соответствующих частот. while tmp <= roof:
:param bases: Список верхних границ диапазонов частот, с которыми работаем. counter += 1
:param roofs: Список нижних границ --//--. tmp += step
""" self.num_chs.append(counter)
return counter
self.steps = steps return self.num_chs[idx_freq]
self.bases = bases
self.roofs = roofs def check_f(self, freq):
self.cur_channel = self.bases[0] for i in range(len(self.bases)):
self.cur_roof = self.roofs[0] low = min(self.roofs[i], self.bases[i])
self.cur_step = self.steps[0] high = max(self.roofs[i], self.bases[i])
self.num_chs = [] if low <= freq <= high:
self.init_freq = False return self.get_num_chs(i), self.DB[i]
self.DB = [] return None, None
def init_f(self): def fill_DB(self, buffer_columns_size, num_of_thinning_iter, multiply_factor, num_for_alarm, freq_tag=None):
""" self.DB = []
Инициализация начальной частоты, с которой начинаем обработку. for i in range(len(self.bases)):
:return: Верхняя граница первой частоты из набора частот. num_chs = self.get_num_chs(i)
""" self.DB.append(
self.init_freq = True DataBuffer(
return self.bases[0] buffer_columns_size,
num_of_thinning_iter,
def get_cur_channel(self): num_chs,
""" multiply_factor,
Получить текущий обрабатываемый канал. num_for_alarm,
:return: Канал обработки. freq_tag=freq_tag,
""" )
return self.cur_channel )
def change_channel(self): def db_alarms_zeros(self, circle_buffer):
""" for i in range(len(self.DB)):
Функция смены канала. Идет от верхней границы диапазона частоты к нижней с шагом step. Если дошли до нижней if self.DB[i] != circle_buffer:
границы, то переключаемся на следующую частоту посредством переноса курсора текущего канала на верхнюю границу self.DB[i].alarms_fill_zeros()
новой частоты и указатель нижней границы также двигаем на следующую позицию. Если частота для обработки одна, то
указатель текущего канала возвращается в начало - верхней границы этой же частоты. Указатель нижней границы не
изменяется.
:return: Канал после смены.
"""
if not self.init_freq:
return self.init_f()
if self.cur_channel <= self.cur_roof:
if self.cur_roof == self.roofs[-1]:
self.cur_channel = self.bases[0]
self.cur_roof = self.roofs[0]
self.cur_step = self.steps[0]
else:
next_roofs = self.roofs.index(self.cur_roof) + 1
self.cur_channel = self.bases[next_roofs]
self.cur_roof = self.roofs[next_roofs]
self.cur_step = self.steps[next_roofs]
else:
self.cur_channel += self.cur_step
# print('Канал частоты изменен на ', self.cur_channel / 1000000)
return self.get_cur_channel()
def get_num_chs(self, idx_freq):
"""
Вычисляет количество каналов на частоте исходя из верхнего, нижнего диапазонов и шага.
:param idx_freq: id частоты внутри класса. Т.е. в данный момент обрабатывается несколько частот, то id =
индексу верхней границы в bases для данной частоты, или нижней границы в roofs или шагу в steps.
В примерах из описания атрибутов индекс частоты 915 будет равен единице (т.к. идет вторым элементом в списках).
:return: Количество каналов.
"""
if (idx_freq + 1) > len(self.num_chs):
tmp = self.bases[idx_freq]
counter = 0
while tmp >= self.roofs[idx_freq]:
counter += 1
tmp += self.steps[idx_freq]
self.num_chs.append(counter)
return counter
else:
return self.num_chs[idx_freq]
def check_f(self, freq):
"""
Проверить наличие частоты в классе. Если да, то вернуть количество каналов и циклический буфер этой частоты.
:param freq: Частота.
:return: Количество каналов, циклический буфер выбранной частоты ИЛИ none.
"""
for i in range(len(self.bases)):
if self.roofs[i] <= freq <= self.bases[i]:
return self.get_num_chs(i), self.DB[i]
else:
return None, None
def fill_DB(self):
"""
Инициализировать циклические буферы для всех частот в отдельный список.
:return: N0nE.
"""
for i in range(len(self.bases)):
freq = get_centre_freq(self.bases[i])
buffer_columns_size = int(os.getenv('buffer_columns_size_' + str(freq)))
num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_' + str(freq)))
multiply_factor = float(os.getenv('multiply_factor_' + str(freq)))
num_for_alarm = int(os.getenv('num_for_alarm_' + str(freq)))
num_chs = self.get_num_chs(i)
self.DB.append(
DataBuffer(buffer_columns_size, num_of_thinning_iter, num_chs, multiply_factor, num_for_alarm))
def db_alarms_zeros(self, circle_buffer):
"""
При отработке системы зануляет алармы во всех буферах, кроме текущего, т.к. в текущем уже занулилось.
:param circle_buffer: Циклический буфер текущей обрабатываемой частоты.
:return: None.
"""
for i in range(len(self.DB)):
if self.DB[i] != circle_buffer:
self.DB[i].alarms_fill_zeros()

@ -1,107 +1,165 @@
import os import os
import numpy as np import math
from typing import Union import time
from common.runtime import load_root_env import numpy as np
from typing import Union
from common.runtime import load_root_env
load_root_env(__file__) load_root_env(__file__)
def get_signal_length(freq): def get_signal_length(freq):
length = int(os.getenv('signal_length_' + str(freq))) length = int(os.getenv('signal_length_' + str(freq)))
return length return length
class Signal: class Signal:
""" """
Класс сбора и предобработки сигнала. Класс сбора и предобработки сигнала.
Атрибуты: Атрибуты:
length: Длина сигнала. length: Длина сигнала.
signal: Массив, в который собираем сигнал. signal: Массив, в который собираем сигнал.
""" """
def __init__(self, conv_method='average'): def __init__(self, conv_method='average'):
self.conv_method = conv_method self.conv_method = conv_method
self.signal = [] self.signal = []
self.signal_abs = [] self.signal_abs = []
self.last_packet_ts = None
def get_signal(self): self.metric_mode = os.getenv('signal_metric_mode', 'fft_top_bins').strip().lower()
""" self.fft_top_bins = max(1, int(os.getenv('signal_fft_top_bins', '2048')))
Возвращает собранный сигнал. self.fft_window = os.getenv('signal_fft_window', 'hann').strip().lower()
:return: Массив с сигналом.
""" def get_signal(self):
return self.signal, self.signal_abs """
Возвращает собранный сигнал.
def clear(self) -> None: :return: Массив с сигналом.
""" """
Очистить массив с сигналом после предобработки? return self.signal, self.signal_abs
:return: None
""" def get_last_packet_ts(self):
self.signal = [] return self.last_packet_ts
self.signal_abs = []
def clear(self) -> None:
def signal_preprocessing(self, length) -> float: """
""" Очистить массив с сигналом после предобработки?
Предобработка сигнала. :return: None
"""
:return: Число типа float - "характеристика сигнала". self.signal = []
""" self.signal_abs = []
signal = np.array([self.signal.real[0:length], self.signal.imag[0:length]], dtype=np.float32) self.last_packet_ts = None
signal_abs = np.linalg.norm(signal, axis=0) # Поэлементный модуль комплексного числа. shape.result
# (1, self.length) def _build_window(self, size: int) -> np.ndarray:
if self.conv_method == 'max': if self.fft_window in {'', 'none', 'rect', 'rectangular'}:
result = np.max(signal_abs) return np.ones(size, dtype=np.float32)
else: if self.fft_window == 'hann':
result = np.median(signal_abs) return np.hanning(size).astype(np.float32, copy=False)
self.signal = signal raise ValueError(f'unsupported fft window: {self.fft_window}')
self.signal_abs = signal_abs
return result def _compute_iq_power(self, samples: np.ndarray, signal_abs: np.ndarray) -> float:
if self.conv_method == 'max':
def fill_signal(self, lvl, length) -> Union[int, float]: return float(np.max(signal_abs * signal_abs))
"""
Сбор сигнала в соответствующий массив. Если уже собран, то предобработка. if self.metric_mode in {'fft', 'fft_top_bins', 'top_bins'}:
:param lvl: Массив, без ограничения общности, с неизвестной длиной, содержащий сигнал. window = self._build_window(samples.size)
:param length: windowed = samples.astype(np.complex64, copy=False) * window
:return: 0 - если еще нет нужного количества сигнала, "характеристика" иначе. spectrum = np.fft.fft(windowed)
""" power_bins = (np.abs(spectrum) ** 2).astype(np.float32, copy=False)
if len(self.signal) <= length: power_bins /= max(float(np.sum(window * window)), 1.0)
y = np.array(lvl).ravel()
self.signal = np.concatenate((self.signal, y), axis=None) bins_to_keep = min(self.fft_top_bins, power_bins.size)
return 0 top_bins = np.partition(power_bins, power_bins.size - bins_to_keep)[-bins_to_keep:]
else: return float(np.mean(top_bins))
preproc_signal = self.signal_preprocessing(length)
#self.clear() return float(np.mean(signal_abs * signal_abs))
return preproc_signal
def signal_preprocessing(self, length) -> float:
"""
class SignalsArray: Предобработка сигнала.
"""
Класс для сохранения медиан сигналов на частотах. :return: Число типа float - "характеристика сигнала".
Атрибуты: """
sig_array: Список для сохранения медиан. samples = np.asarray(self.signal).ravel()[0:length]
counter: Индикатор наполненности массива. if samples.size == 0:
""" return 0.0
def __init__(self):
self.sig_array = [] # Основной режим: считаем dBFS из IQ-вектора.
self.counter = 0 if np.iscomplexobj(samples):
i = samples.real.astype(np.float32, copy=False)
def fill_sig_arr(self, metrica, num_chs=3): q = samples.imag.astype(np.float32, copy=False)
""" signal = np.array([i, q], dtype=np.float32)
Аппендим характеристику сигнала (метрику) в массив длиной num_chs. signal_abs = np.sqrt(i * i + q * q).astype(np.float32, copy=False)
:param metrica: Характеристика сигнала (метрика).
:param num_chs: Количество каналов на частоте. power = self._compute_iq_power(samples, signal_abs)
:return: Индекс канала внутри частоты и массив с характеристиками, если заполнен, иначе - пустой.
""" result = 10.0 * math.log10(max(power, 1e-20))
if num_chs: self.signal = signal
if self.counter < num_chs: self.signal_abs = signal_abs
self.sig_array.append(metrica) return result
self.counter += 1
if self.counter == num_chs: # Fallback: если на вход уже подали скалярную метрику, агрегируем как есть.
arr = self.sig_array scalar_samples = samples.astype(np.float32, copy=False)
self.sig_array = [] if self.conv_method == 'max':
self.counter = 0 result = float(np.max(scalar_samples))
return num_chs - 1, arr else:
else: result = float(np.median(scalar_samples))
return self.counter - 1, []
else: self.signal = scalar_samples
return 0, [] self.signal_abs = np.abs(scalar_samples)
return result
def fill_signal(self, lvl, length) -> Union[int, float]:
"""
Сбор сигнала в соответствующий массив. Если уже собран, то предобработка.
:param lvl: Массив, без ограничения общности, с неизвестной длиной, содержащий сигнал.
:param length:
:return: 0 - если еще нет нужного количества сигнала, "характеристика" иначе.
"""
if len(self.signal) <= length:
y = np.array(lvl).ravel()
self.signal = np.concatenate((self.signal, y), axis=None)
return 0
else:
self.last_packet_ts = time.time()
preproc_signal = self.signal_preprocessing(length)
return preproc_signal
class SignalsArray:
"""
Класс для сохранения медиан сигналов на частотах.
Атрибуты:
sig_array: Список для сохранения медиан.
counter: Индикатор наполненности массива.
"""
def __init__(self):
self.sig_array = []
self.sig_ts_array = []
self.counter = 0
def fill_sig_arr(self, metrica, packet_ts=None, num_chs=3):
"""
Аппендим характеристику сигнала (метрику) в массив длиной num_chs.
:param metrica: Характеристика сигнала (метрика).
:param packet_ts: Время завершения набора пакета с SDR для текущей метрики.
:param num_chs: Количество каналов на частоте.
:return: Индекс канала внутри частоты и массив с характеристиками, если заполнен, иначе - пустой.
"""
if num_chs:
if self.counter < num_chs:
self.sig_array.append(metrica)
self.sig_ts_array.append(packet_ts)
self.counter += 1
if self.counter == num_chs:
arr = self.sig_array
arr_ts = self.sig_ts_array
self.sig_array = []
self.sig_ts_array = []
self.counter = 0
return num_chs - 1, arr, arr_ts
else:
return self.counter - 1, [], []
else:
return 0, [], []

@ -0,0 +1,150 @@
import os
import datetime
import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from utils.jammer_state_flag import is_jammer_active
from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__)
debug_flag = as_bool(os.getenv('debug_flag', '0'))
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
module_name = os.getenv('module_name')
elems_to_save = os.getenv('elems_to_save')
file_types_to_save = os.getenv('file_types_to_save')
localhost = os.getenv('lochost')
localport = os.getenv('locport')
f_step = [*map(float, os.getenv('f_step_1500').split())]
f_bases = [*map(float, os.getenv('f_bases_1500').split())]
f_roofs = [*map(float, os.getenv('f_roofs_1500').split())]
signal_length = int(os.getenv('signal_length_1500'))
buffer_columns_size = int(os.getenv('buffer_columns_size_1500'))
num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_1500'))
multiply_factor = float(os.getenv('multiply_factor_1500'))
num_for_alarm = int(os.getenv('num_for_alarm_1500'))
c_freq = os.getenv('c_freq_1500', '1500')
path_to_save_medians = os.getenv('path_to_save_medians')
path_to_save_alarms = os.getenv('path_to_save_alarms')
smb_host = os.getenv('smb_host')
smb_port = os.getenv('smb_port')
smb_user = os.getenv('smb_user')
smb_pass = os.getenv('smb_pass')
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name')
remote_pc_name = os.getenv('remote_pc_name')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint')
telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
telemetry_port = os.getenv('telemetry_port', '5020')
telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
elems_to_save = elems_to_save.split(',')
file_types_to_save = file_types_to_save.split(',')
tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
multi_channel = MultiChannel(f_step, f_bases, f_roofs)
f = multi_channel.init_f()
multi_channel.fill_DB(
buffer_columns_size,
num_of_thinning_iter,
multiply_factor,
num_for_alarm,
c_freq,
)
if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
conn.connect(smb_host, 139)
filelist = conn.listPath(shared_folder, '/')
print(filelist)
def work(lvl):
f = multi_channel.get_cur_channel()
freq = c_freq
median = tmp_signal.fill_signal(lvl, signal_length)
packet_ts = tmp_signal.get_last_packet_ts()
if median:
try:
num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians())
alarm = circle_buffer.check_alarm(sigs_array)
if alarm:
print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer)
elif not is_jammer_active():
circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if telemetry_enabled:
try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
dbfs_current = float(sigs_array[max_idx])
dbfs_threshold = circle_buffer.get_threshold(max_idx)
channel_thresholds = circle_buffer.get_thresholds()
alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
send_telemetry(
data={
'freq': str(freq),
'ts': time.time(),
'dbfs_current': dbfs_current,
'dbfs_threshold': dbfs_threshold,
'alarm': bool(alarm),
'channel_idx': int(max_idx),
'channels_total': int(len(sigs_array)),
'channel_values': [float(v) for v in sigs_array],
'channel_thresholds': channel_thresholds,
'alarm_channels': alarm_channels,
},
host=telemetry_host,
port=telemetry_port,
endpoint=telemetry_endpoint,
timeout_sec=telemetry_timeout_sec,
)
except Exception as exc:
if debug_flag:
print(f'telemetry send failed: {exc}')
if send_to_module_flag:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
print(cur_channel, single_alarm)
if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e:
print(f'Ошибка: {e}')
else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print('.', end='')
tmp_signal.clear()
return f

@ -1,28 +1,14 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, {
"send_to_module_flag": as_bool,
"save_data_flag": as_bool,
"elems_to_save": as_str,
"file_types_to_save": as_str,
"lochost": as_str,
"locport": as_str,
"freq_endpoint": as_str,
"path_to_save_medians": as_str,
"path_to_save_alarms": as_str,
"module_name": as_str,
f"f_step_{freq_suffix}": as_str,
f"f_bases_{freq_suffix}": as_str,
f"f_roofs_{freq_suffix}": as_str,
})
debug_flag = as_bool(os.getenv('debug_flag', '0')) debug_flag = as_bool(os.getenv('debug_flag', '0'))
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
@ -35,6 +21,12 @@ localport = os.getenv('locport')
f_step = [*map(float, os.getenv('f_step_3300').split())] f_step = [*map(float, os.getenv('f_step_3300').split())]
f_bases = [*map(float, os.getenv('f_bases_3300').split())] f_bases = [*map(float, os.getenv('f_bases_3300').split())]
f_roofs = [*map(float, os.getenv('f_roofs_3300').split())] f_roofs = [*map(float, os.getenv('f_roofs_3300').split())]
signal_length = int(os.getenv('signal_length_3300'))
buffer_columns_size = int(os.getenv('buffer_columns_size_3300'))
num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_3300'))
multiply_factor = float(os.getenv('multiply_factor_3300'))
num_for_alarm = int(os.getenv('num_for_alarm_3300'))
c_freq = os.getenv('c_freq_3300', '3300')
path_to_save_medians = os.getenv('path_to_save_medians') path_to_save_medians = os.getenv('path_to_save_medians')
path_to_save_alarms = os.getenv('path_to_save_alarms') path_to_save_alarms = os.getenv('path_to_save_alarms')
smb_host = os.getenv('smb_host') smb_host = os.getenv('smb_host')
@ -46,6 +38,11 @@ the_pc_name = os.getenv('the_pc_name')
remote_pc_name = os.getenv('remote_pc_name') remote_pc_name = os.getenv('remote_pc_name')
smb_domain = os.getenv('smb_domain') smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') freq_endpoint = os.getenv('freq_endpoint')
telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
telemetry_port = os.getenv('telemetry_port', '5020')
telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
elems_to_save = elems_to_save.split(',') elems_to_save = elems_to_save.split(',')
file_types_to_save = file_types_to_save.split(',') file_types_to_save = file_types_to_save.split(',')
@ -54,7 +51,13 @@ tmp_signal = Signal()
tmp_sigs_array = SignalsArray() tmp_sigs_array = SignalsArray()
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multi_channel = MultiChannel(f_step, f_bases, f_roofs)
f = multi_channel.init_f() f = multi_channel.init_f()
multi_channel.fill_DB() multi_channel.fill_DB(
buffer_columns_size,
num_of_thinning_iter,
multiply_factor,
num_for_alarm,
c_freq,
)
if debug_flag: if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
@ -64,16 +67,15 @@ if debug_flag:
def work(lvl): def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq)
median = tmp_signal.fill_signal(lvl, signal_length) median = tmp_signal.fill_signal(lvl, signal_length)
packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
try: try:
num_chs, circle_buffer = multi_channel.check_f(f) num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array: if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array)) print('Значения на {0}: {1}'.format(freq, sigs_array))
@ -83,19 +85,47 @@ def work(lvl):
if alarm: if alarm:
print('----ALARM---- ', freq) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer) multi_channel.db_alarms_zeros(circle_buffer)
else: elif not is_jammer_active():
circle_buffer.update(sigs_array) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if telemetry_enabled:
try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
dbfs_current = float(sigs_array[max_idx])
dbfs_threshold = circle_buffer.get_threshold(max_idx)
channel_thresholds = circle_buffer.get_thresholds()
alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
send_telemetry(
data={
'freq': str(freq),
'ts': time.time(),
'dbfs_current': dbfs_current,
'dbfs_threshold': dbfs_threshold,
'alarm': bool(alarm),
'channel_idx': int(max_idx),
'channels_total': int(len(sigs_array)),
'channel_values': [float(v) for v in sigs_array],
'channel_thresholds': channel_thresholds,
'alarm_channels': alarm_channels,
},
host=telemetry_host,
port=telemetry_port,
endpoint=telemetry_endpoint,
timeout_sec=telemetry_timeout_sec,
)
except Exception as exc:
if debug_flag:
print(f'telemetry send failed: {exc}')
if send_to_module_flag: if send_to_module_flag:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag: if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
list(range(num_chs)))
if circle_buffer.check_init(): if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
circle_buffer.get_medians())
if debug_flag: if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
@ -106,14 +136,14 @@ def work(lvl):
try: try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e: except Exception as e:
print(f"Ошибка: {e}") print(f'Ошибка: {e}')
else: else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel() f = multi_channel.change_channel()
except Exception as e: except Exception as e:
print(str(e)) print(str(e))
print(".", end='') print('.', end='')
tmp_signal.clear() tmp_signal.clear()

@ -1,120 +1,150 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, { debug_flag = as_bool(os.getenv('debug_flag', '0'))
"send_to_module_flag": as_bool, send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
"save_data_flag": as_bool, save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
"elems_to_save": as_str, module_name = os.getenv('module_name')
"file_types_to_save": as_str, elems_to_save = os.getenv('elems_to_save')
"lochost": as_str, file_types_to_save = os.getenv('file_types_to_save')
"locport": as_str, localhost = os.getenv('lochost')
"freq_endpoint": as_str, localport = os.getenv('locport')
"path_to_save_medians": as_str, f_step = [*map(float, os.getenv('f_step_433').split())]
"path_to_save_alarms": as_str, f_bases = [*map(float, os.getenv('f_bases_433').split())]
"module_name": as_str, f_roofs = [*map(float, os.getenv('f_roofs_433').split())]
f"f_step_{freq_suffix}": as_str, signal_length = int(os.getenv('signal_length_433'))
f"f_bases_{freq_suffix}": as_str, buffer_columns_size = int(os.getenv('buffer_columns_size_433'))
f"f_roofs_{freq_suffix}": as_str, num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_433'))
}) multiply_factor = float(os.getenv('multiply_factor_433'))
num_for_alarm = int(os.getenv('num_for_alarm_433'))
debug_flag = as_bool(os.getenv('debug_flag', '0')) c_freq = os.getenv('c_freq_433', '433')
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) path_to_save_medians = os.getenv('path_to_save_medians')
save_data_flag = as_bool(os.getenv('save_data_flag', '0')) path_to_save_alarms = os.getenv('path_to_save_alarms')
module_name = os.getenv('module_name') smb_host = os.getenv('smb_host')
elems_to_save = os.getenv('elems_to_save') smb_port = os.getenv('smb_port')
file_types_to_save = os.getenv('file_types_to_save') smb_user = os.getenv('smb_user')
localhost = os.getenv('lochost') smb_pass = os.getenv('smb_pass')
localport = os.getenv('locport') shared_folder = os.getenv('shared_folder')
f_step = [*map(float, os.getenv('f_step_433').split())] the_pc_name = os.getenv('the_pc_name')
f_bases = [*map(float, os.getenv('f_bases_433').split())] remote_pc_name = os.getenv('remote_pc_name')
f_roofs = [*map(float, os.getenv('f_roofs_433').split())] smb_domain = os.getenv('smb_domain')
path_to_save_medians = os.getenv('path_to_save_medians') freq_endpoint = os.getenv('freq_endpoint')
path_to_save_alarms = os.getenv('path_to_save_alarms') telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
smb_host = os.getenv('smb_host') telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
smb_port = os.getenv('smb_port') telemetry_port = os.getenv('telemetry_port', '5020')
smb_user = os.getenv('smb_user') telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
smb_pass = os.getenv('smb_pass') telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name') elems_to_save = elems_to_save.split(',')
remote_pc_name = os.getenv('remote_pc_name') file_types_to_save = file_types_to_save.split(',')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
elems_to_save = elems_to_save.split(',') multi_channel = MultiChannel(f_step, f_bases, f_roofs)
file_types_to_save = file_types_to_save.split(',') f = multi_channel.init_f()
multi_channel.fill_DB(
tmp_signal = Signal() buffer_columns_size,
tmp_sigs_array = SignalsArray() num_of_thinning_iter,
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multiply_factor,
f = multi_channel.init_f() num_for_alarm,
multi_channel.fill_DB() c_freq,
)
if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) if debug_flag:
conn.connect(smb_host, 139) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
filelist = conn.listPath(shared_folder, '/') conn.connect(smb_host, 139)
print(filelist) filelist = conn.listPath(shared_folder, '/')
print(filelist)
def work(lvl):
def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq) median = tmp_signal.fill_signal(lvl, signal_length)
median = tmp_signal.fill_signal(lvl, signal_length) packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
try: try:
num_chs, circle_buffer = multi_channel.check_f(f) num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array: if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array)) print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians()) print('Пороги: ', circle_buffer.get_medians())
alarm = circle_buffer.check_alarm(sigs_array) alarm = circle_buffer.check_alarm(sigs_array)
if alarm: if alarm:
print('----ALARM---- ', freq) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer) multi_channel.db_alarms_zeros(circle_buffer)
else: elif not is_jammer_active():
circle_buffer.update(sigs_array) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if send_to_module_flag: if telemetry_enabled:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
if save_data_flag: dbfs_current = float(sigs_array[max_idx])
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: dbfs_threshold = circle_buffer.get_threshold(max_idx)
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), channel_thresholds = circle_buffer.get_thresholds()
list(range(num_chs))) alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, send_telemetry(
circle_buffer.get_medians()) data={
'freq': str(freq),
if debug_flag: 'ts': time.time(),
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) 'dbfs_current': dbfs_current,
print(cur_channel, single_alarm) 'dbfs_threshold': dbfs_threshold,
if single_alarm: 'alarm': bool(alarm),
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal()) 'channel_idx': int(max_idx),
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?') 'channels_total': int(len(sigs_array)),
try: 'channel_values': [float(v) for v in sigs_array],
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) 'channel_thresholds': channel_thresholds,
except Exception as e: 'alarm_channels': alarm_channels,
print(f"Ошибка: {e}") },
else: host=telemetry_host,
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') port=telemetry_port,
endpoint=telemetry_endpoint,
f = multi_channel.change_channel() timeout_sec=telemetry_timeout_sec,
except Exception as e: )
print(str(e)) except Exception as exc:
print(".", end='') if debug_flag:
print(f'telemetry send failed: {exc}')
tmp_signal.clear()
if send_to_module_flag:
return f send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
print(cur_channel, single_alarm)
if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e:
print(f'Ошибка: {e}')
else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print('.', end='')
tmp_signal.clear()
return f

@ -1,28 +1,14 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, {
"send_to_module_flag": as_bool,
"save_data_flag": as_bool,
"elems_to_save": as_str,
"file_types_to_save": as_str,
"lochost": as_str,
"locport": as_str,
"freq_endpoint": as_str,
"path_to_save_medians": as_str,
"path_to_save_alarms": as_str,
"module_name": as_str,
f"f_step_{freq_suffix}": as_str,
f"f_bases_{freq_suffix}": as_str,
f"f_roofs_{freq_suffix}": as_str,
})
debug_flag = as_bool(os.getenv('debug_flag', '0')) debug_flag = as_bool(os.getenv('debug_flag', '0'))
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
@ -35,6 +21,12 @@ localport = os.getenv('locport')
f_step = [*map(float, os.getenv('f_step_4500').split())] f_step = [*map(float, os.getenv('f_step_4500').split())]
f_bases = [*map(float, os.getenv('f_bases_4500').split())] f_bases = [*map(float, os.getenv('f_bases_4500').split())]
f_roofs = [*map(float, os.getenv('f_roofs_4500').split())] f_roofs = [*map(float, os.getenv('f_roofs_4500').split())]
signal_length = int(os.getenv('signal_length_4500'))
buffer_columns_size = int(os.getenv('buffer_columns_size_4500'))
num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_4500'))
multiply_factor = float(os.getenv('multiply_factor_4500'))
num_for_alarm = int(os.getenv('num_for_alarm_4500'))
c_freq = os.getenv('c_freq_4500', '4500')
path_to_save_medians = os.getenv('path_to_save_medians') path_to_save_medians = os.getenv('path_to_save_medians')
path_to_save_alarms = os.getenv('path_to_save_alarms') path_to_save_alarms = os.getenv('path_to_save_alarms')
smb_host = os.getenv('smb_host') smb_host = os.getenv('smb_host')
@ -46,6 +38,11 @@ the_pc_name = os.getenv('the_pc_name')
remote_pc_name = os.getenv('remote_pc_name') remote_pc_name = os.getenv('remote_pc_name')
smb_domain = os.getenv('smb_domain') smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') freq_endpoint = os.getenv('freq_endpoint')
telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
telemetry_port = os.getenv('telemetry_port', '5020')
telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
elems_to_save = elems_to_save.split(',') elems_to_save = elems_to_save.split(',')
file_types_to_save = file_types_to_save.split(',') file_types_to_save = file_types_to_save.split(',')
@ -54,7 +51,13 @@ tmp_signal = Signal()
tmp_sigs_array = SignalsArray() tmp_sigs_array = SignalsArray()
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multi_channel = MultiChannel(f_step, f_bases, f_roofs)
f = multi_channel.init_f() f = multi_channel.init_f()
multi_channel.fill_DB() multi_channel.fill_DB(
buffer_columns_size,
num_of_thinning_iter,
multiply_factor,
num_for_alarm,
c_freq,
)
if debug_flag: if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
@ -64,16 +67,15 @@ if debug_flag:
def work(lvl): def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq)
median = tmp_signal.fill_signal(lvl, signal_length) median = tmp_signal.fill_signal(lvl, signal_length)
packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
try: try:
num_chs, circle_buffer = multi_channel.check_f(f) num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array: if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array)) print('Значения на {0}: {1}'.format(freq, sigs_array))
@ -83,19 +85,47 @@ def work(lvl):
if alarm: if alarm:
print('----ALARM---- ', freq) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer) multi_channel.db_alarms_zeros(circle_buffer)
else: elif not is_jammer_active():
circle_buffer.update(sigs_array) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if telemetry_enabled:
try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
dbfs_current = float(sigs_array[max_idx])
dbfs_threshold = circle_buffer.get_threshold(max_idx)
channel_thresholds = circle_buffer.get_thresholds()
alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
send_telemetry(
data={
'freq': str(freq),
'ts': time.time(),
'dbfs_current': dbfs_current,
'dbfs_threshold': dbfs_threshold,
'alarm': bool(alarm),
'channel_idx': int(max_idx),
'channels_total': int(len(sigs_array)),
'channel_values': [float(v) for v in sigs_array],
'channel_thresholds': channel_thresholds,
'alarm_channels': alarm_channels,
},
host=telemetry_host,
port=telemetry_port,
endpoint=telemetry_endpoint,
timeout_sec=telemetry_timeout_sec,
)
except Exception as exc:
if debug_flag:
print(f'telemetry send failed: {exc}')
if send_to_module_flag: if send_to_module_flag:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag: if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
list(range(num_chs)))
if circle_buffer.check_init(): if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
circle_buffer.get_medians())
if debug_flag: if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
@ -106,14 +136,14 @@ def work(lvl):
try: try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e: except Exception as e:
print(f"Ошибка: {e}") print(f'Ошибка: {e}')
else: else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel() f = multi_channel.change_channel()
except Exception as e: except Exception as e:
print(str(e)) print(str(e))
print(".", end='') print('.', end='')
tmp_signal.clear() tmp_signal.clear()

@ -1,120 +1,150 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, { debug_flag = as_bool(os.getenv('debug_flag', '0'))
"send_to_module_flag": as_bool, send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
"save_data_flag": as_bool, save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
"elems_to_save": as_str, module_name = os.getenv('module_name')
"file_types_to_save": as_str, elems_to_save = os.getenv('elems_to_save')
"lochost": as_str, file_types_to_save = os.getenv('file_types_to_save')
"locport": as_str, localhost = os.getenv('lochost')
"freq_endpoint": as_str, localport = os.getenv('locport')
"path_to_save_medians": as_str, f_step = [*map(float, os.getenv('f_step_5200').split())]
"path_to_save_alarms": as_str, f_bases = [*map(float, os.getenv('f_bases_5200').split())]
"module_name": as_str, f_roofs = [*map(float, os.getenv('f_roofs_5200').split())]
f"f_step_{freq_suffix}": as_str, signal_length = int(os.getenv('signal_length_5200'))
f"f_bases_{freq_suffix}": as_str, buffer_columns_size = int(os.getenv('buffer_columns_size_5200'))
f"f_roofs_{freq_suffix}": as_str, num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_5200'))
}) multiply_factor = float(os.getenv('multiply_factor_5200'))
num_for_alarm = int(os.getenv('num_for_alarm_5200'))
debug_flag = as_bool(os.getenv('debug_flag', '0')) c_freq = os.getenv('c_freq_5200', '5200')
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) path_to_save_medians = os.getenv('path_to_save_medians')
save_data_flag = as_bool(os.getenv('save_data_flag', '0')) path_to_save_alarms = os.getenv('path_to_save_alarms')
module_name = os.getenv('module_name') smb_host = os.getenv('smb_host')
elems_to_save = os.getenv('elems_to_save') smb_port = os.getenv('smb_port')
file_types_to_save = os.getenv('file_types_to_save') smb_user = os.getenv('smb_user')
localhost = os.getenv('lochost') smb_pass = os.getenv('smb_pass')
localport = os.getenv('locport') shared_folder = os.getenv('shared_folder')
f_step = [*map(float, os.getenv('f_step_5200').split())] the_pc_name = os.getenv('the_pc_name')
f_bases = [*map(float, os.getenv('f_bases_5200').split())] remote_pc_name = os.getenv('remote_pc_name')
f_roofs = [*map(float, os.getenv('f_roofs_5200').split())] smb_domain = os.getenv('smb_domain')
path_to_save_medians = os.getenv('path_to_save_medians') freq_endpoint = os.getenv('freq_endpoint')
path_to_save_alarms = os.getenv('path_to_save_alarms') telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
smb_host = os.getenv('smb_host') telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
smb_port = os.getenv('smb_port') telemetry_port = os.getenv('telemetry_port', '5020')
smb_user = os.getenv('smb_user') telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
smb_pass = os.getenv('smb_pass') telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name') elems_to_save = elems_to_save.split(',')
remote_pc_name = os.getenv('remote_pc_name') file_types_to_save = file_types_to_save.split(',')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
elems_to_save = elems_to_save.split(',') multi_channel = MultiChannel(f_step, f_bases, f_roofs)
file_types_to_save = file_types_to_save.split(',') f = multi_channel.init_f()
multi_channel.fill_DB(
tmp_signal = Signal() buffer_columns_size,
tmp_sigs_array = SignalsArray() num_of_thinning_iter,
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multiply_factor,
f = multi_channel.init_f() num_for_alarm,
multi_channel.fill_DB() c_freq,
)
if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) if debug_flag:
conn.connect(smb_host, 139) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
filelist = conn.listPath(shared_folder, '/') conn.connect(smb_host, 139)
print(filelist) filelist = conn.listPath(shared_folder, '/')
print(filelist)
def work(lvl):
def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq) median = tmp_signal.fill_signal(lvl, signal_length)
median = tmp_signal.fill_signal(lvl, signal_length) packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
try: try:
num_chs, circle_buffer = multi_channel.check_f(f) num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array: if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array)) print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians()) print('Пороги: ', circle_buffer.get_medians())
alarm = circle_buffer.check_alarm(sigs_array) alarm = circle_buffer.check_alarm(sigs_array)
if alarm: if alarm:
print('----ALARM---- ', freq) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer) multi_channel.db_alarms_zeros(circle_buffer)
else: elif not is_jammer_active():
circle_buffer.update(sigs_array) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if send_to_module_flag: if telemetry_enabled:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
if save_data_flag: dbfs_current = float(sigs_array[max_idx])
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: dbfs_threshold = circle_buffer.get_threshold(max_idx)
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), channel_thresholds = circle_buffer.get_thresholds()
list(range(num_chs))) alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, send_telemetry(
circle_buffer.get_medians()) data={
'freq': str(freq),
if debug_flag: 'ts': time.time(),
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) 'dbfs_current': dbfs_current,
print(cur_channel, single_alarm) 'dbfs_threshold': dbfs_threshold,
if single_alarm: 'alarm': bool(alarm),
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal()) 'channel_idx': int(max_idx),
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?') 'channels_total': int(len(sigs_array)),
try: 'channel_values': [float(v) for v in sigs_array],
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) 'channel_thresholds': channel_thresholds,
except Exception as e: 'alarm_channels': alarm_channels,
print(f"Ошибка: {e}") },
else: host=telemetry_host,
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') port=telemetry_port,
endpoint=telemetry_endpoint,
f = multi_channel.change_channel() timeout_sec=telemetry_timeout_sec,
except Exception as e: )
print(str(e)) except Exception as exc:
print(".", end='') if debug_flag:
print(f'telemetry send failed: {exc}')
tmp_signal.clear()
if send_to_module_flag:
return f send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
print(cur_channel, single_alarm)
if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e:
print(f'Ошибка: {e}')
else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print('.', end='')
tmp_signal.clear()
return f

@ -1,120 +1,150 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, { debug_flag = as_bool(os.getenv('debug_flag', '0'))
"send_to_module_flag": as_bool, send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
"save_data_flag": as_bool, save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
"elems_to_save": as_str, module_name = os.getenv('module_name')
"file_types_to_save": as_str, elems_to_save = os.getenv('elems_to_save')
"lochost": as_str, file_types_to_save = os.getenv('file_types_to_save')
"locport": as_str, localhost = os.getenv('lochost')
"freq_endpoint": as_str, localport = os.getenv('locport')
"path_to_save_medians": as_str, f_step = [*map(float, os.getenv('f_step_5800').split())]
"path_to_save_alarms": as_str, f_bases = [*map(float, os.getenv('f_bases_5800').split())]
"module_name": as_str, f_roofs = [*map(float, os.getenv('f_roofs_5800').split())]
f"f_step_{freq_suffix}": as_str, signal_length = int(os.getenv('signal_length_5800'))
f"f_bases_{freq_suffix}": as_str, buffer_columns_size = int(os.getenv('buffer_columns_size_5800'))
f"f_roofs_{freq_suffix}": as_str, num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_5800'))
}) multiply_factor = float(os.getenv('multiply_factor_5800'))
num_for_alarm = int(os.getenv('num_for_alarm_5800'))
debug_flag = as_bool(os.getenv('debug_flag', '0')) c_freq = os.getenv('c_freq_5800', '5800')
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) path_to_save_medians = os.getenv('path_to_save_medians')
save_data_flag = as_bool(os.getenv('save_data_flag', '0')) path_to_save_alarms = os.getenv('path_to_save_alarms')
module_name = os.getenv('module_name') smb_host = os.getenv('smb_host')
elems_to_save = os.getenv('elems_to_save') smb_port = os.getenv('smb_port')
file_types_to_save = os.getenv('file_types_to_save') smb_user = os.getenv('smb_user')
localhost = os.getenv('lochost') smb_pass = os.getenv('smb_pass')
localport = os.getenv('locport') shared_folder = os.getenv('shared_folder')
f_step = [*map(float, os.getenv('f_step_5800').split())] the_pc_name = os.getenv('the_pc_name')
f_bases = [*map(float, os.getenv('f_bases_5800').split())] remote_pc_name = os.getenv('remote_pc_name')
f_roofs = [*map(float, os.getenv('f_roofs_5800').split())] smb_domain = os.getenv('smb_domain')
path_to_save_medians = os.getenv('path_to_save_medians') freq_endpoint = os.getenv('freq_endpoint')
path_to_save_alarms = os.getenv('path_to_save_alarms') telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
smb_host = os.getenv('smb_host') telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
smb_port = os.getenv('smb_port') telemetry_port = os.getenv('telemetry_port', '5020')
smb_user = os.getenv('smb_user') telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
smb_pass = os.getenv('smb_pass') telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name') elems_to_save = elems_to_save.split(',')
remote_pc_name = os.getenv('remote_pc_name') file_types_to_save = file_types_to_save.split(',')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
elems_to_save = elems_to_save.split(',') multi_channel = MultiChannel(f_step, f_bases, f_roofs)
file_types_to_save = file_types_to_save.split(',') f = multi_channel.init_f()
multi_channel.fill_DB(
tmp_signal = Signal() buffer_columns_size,
tmp_sigs_array = SignalsArray() num_of_thinning_iter,
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multiply_factor,
f = multi_channel.init_f() num_for_alarm,
multi_channel.fill_DB() c_freq,
)
if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) if debug_flag:
conn.connect(smb_host, 139) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
filelist = conn.listPath(shared_folder, '/') conn.connect(smb_host, 139)
print(filelist) filelist = conn.listPath(shared_folder, '/')
print(filelist)
def work(lvl):
def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq) median = tmp_signal.fill_signal(lvl, signal_length)
median = tmp_signal.fill_signal(lvl, signal_length) packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
try: try:
num_chs, circle_buffer = multi_channel.check_f(f) num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array: if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array)) print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians()) print('Пороги: ', circle_buffer.get_medians())
alarm = circle_buffer.check_alarm(sigs_array) alarm = circle_buffer.check_alarm(sigs_array)
if alarm: if alarm:
print('----ALARM---- ', freq) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer) multi_channel.db_alarms_zeros(circle_buffer)
else: elif not is_jammer_active():
circle_buffer.update(sigs_array) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if send_to_module_flag: if telemetry_enabled:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
if save_data_flag: dbfs_current = float(sigs_array[max_idx])
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: dbfs_threshold = circle_buffer.get_threshold(max_idx)
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), channel_thresholds = circle_buffer.get_thresholds()
list(range(num_chs))) alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, send_telemetry(
circle_buffer.get_medians()) data={
'freq': str(freq),
if debug_flag: 'ts': time.time(),
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) 'dbfs_current': dbfs_current,
print(cur_channel, single_alarm) 'dbfs_threshold': dbfs_threshold,
if single_alarm: 'alarm': bool(alarm),
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal()) 'channel_idx': int(max_idx),
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?') 'channels_total': int(len(sigs_array)),
try: 'channel_values': [float(v) for v in sigs_array],
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) 'channel_thresholds': channel_thresholds,
except Exception as e: 'alarm_channels': alarm_channels,
print(f"Ошибка: {e}") },
else: host=telemetry_host,
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') port=telemetry_port,
endpoint=telemetry_endpoint,
f = multi_channel.change_channel() timeout_sec=telemetry_timeout_sec,
except Exception as e: )
print(str(e)) except Exception as exc:
print(".", end='') if debug_flag:
print(f'telemetry send failed: {exc}')
tmp_signal.clear()
if send_to_module_flag:
return f send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
print(cur_channel, single_alarm)
if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e:
print(f'Ошибка: {e}')
else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print('.', end='')
tmp_signal.clear()
return f

@ -1,123 +1,150 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, { debug_flag = as_bool(os.getenv('debug_flag', '0'))
"send_to_module_flag": as_bool, send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
"save_data_flag": as_bool, save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
"elems_to_save": as_str, module_name = os.getenv('module_name')
"file_types_to_save": as_str, elems_to_save = os.getenv('elems_to_save')
"lochost": as_str, file_types_to_save = os.getenv('file_types_to_save')
"locport": as_str, localhost = os.getenv('lochost')
"freq_endpoint": as_str, localport = os.getenv('locport')
"path_to_save_medians": as_str, f_step = [*map(float, os.getenv('f_step_750').split())]
"path_to_save_alarms": as_str, f_bases = [*map(float, os.getenv('f_bases_750').split())]
"module_name": as_str, f_roofs = [*map(float, os.getenv('f_roofs_750').split())]
f"f_step_{freq_suffix}": as_str, signal_length = int(os.getenv('signal_length_750'))
f"f_bases_{freq_suffix}": as_str, buffer_columns_size = int(os.getenv('buffer_columns_size_750'))
f"f_roofs_{freq_suffix}": as_str, num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_750'))
}) multiply_factor = float(os.getenv('multiply_factor_750'))
num_for_alarm = int(os.getenv('num_for_alarm_750'))
debug_flag = as_bool(os.getenv('debug_flag', '0')) c_freq = os.getenv('c_freq_750', '750')
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) path_to_save_medians = os.getenv('path_to_save_medians')
save_data_flag = as_bool(os.getenv('save_data_flag', '0')) path_to_save_alarms = os.getenv('path_to_save_alarms')
module_name = os.getenv('module_name') smb_host = os.getenv('smb_host')
elems_to_save = os.getenv('elems_to_save') smb_port = os.getenv('smb_port')
file_types_to_save = os.getenv('file_types_to_save') smb_user = os.getenv('smb_user')
localhost = os.getenv('lochost') smb_pass = os.getenv('smb_pass')
localport = os.getenv('locport') shared_folder = os.getenv('shared_folder')
f_step = [*map(float, os.getenv('f_step_750').split())] the_pc_name = os.getenv('the_pc_name')
f_bases = [*map(float, os.getenv('f_bases_750').split())] remote_pc_name = os.getenv('remote_pc_name')
f_roofs = [*map(float, os.getenv('f_roofs_750').split())] smb_domain = os.getenv('smb_domain')
path_to_save_medians = os.getenv('path_to_save_medians') freq_endpoint = os.getenv('freq_endpoint')
path_to_save_alarms = os.getenv('path_to_save_alarms') telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
smb_host = os.getenv('smb_host') telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
smb_port = os.getenv('smb_port') telemetry_port = os.getenv('telemetry_port', '5020')
smb_user = os.getenv('smb_user') telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
smb_pass = os.getenv('smb_pass') telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name') elems_to_save = elems_to_save.split(',')
remote_pc_name = os.getenv('remote_pc_name') file_types_to_save = file_types_to_save.split(',')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
elems_to_save = elems_to_save.split(',') multi_channel = MultiChannel(f_step, f_bases, f_roofs)
file_types_to_save = file_types_to_save.split(',') f = multi_channel.init_f()
multi_channel.fill_DB(
tmp_signal = Signal() buffer_columns_size,
tmp_sigs_array = SignalsArray() num_of_thinning_iter,
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multiply_factor,
f = multi_channel.init_f() num_for_alarm,
multi_channel.fill_DB() c_freq,
)
if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) if debug_flag:
conn.connect(smb_host, 139) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
filelist = conn.listPath(shared_folder, '/') conn.connect(smb_host, 139)
print(filelist) filelist = conn.listPath(shared_folder, '/')
print(filelist)
def work(lvl):
def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq) median = tmp_signal.fill_signal(lvl, signal_length)
median = tmp_signal.fill_signal(lvl, signal_length) packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
print(1) try:
try: num_chs, circle_buffer = multi_channel.check_f(f)
num_chs, circle_buffer = multi_channel.check_f(f) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
print(num_chs, circle_buffer)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) if sigs_array:
print(3) print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians())
if sigs_array: alarm = circle_buffer.check_alarm(sigs_array)
print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians()) if alarm:
alarm = circle_buffer.check_alarm(sigs_array) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer)
if alarm: elif not is_jammer_active():
print('----ALARM---- ', freq) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
multi_channel.db_alarms_zeros(circle_buffer)
else: if telemetry_enabled:
circle_buffer.update(sigs_array) try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
if send_to_module_flag: dbfs_current = float(sigs_array[max_idx])
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) dbfs_threshold = circle_buffer.get_threshold(max_idx)
channel_thresholds = circle_buffer.get_thresholds()
if save_data_flag: alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), send_telemetry(
list(range(num_chs))) data={
if circle_buffer.check_init(): 'freq': str(freq),
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, 'ts': time.time(),
circle_buffer.get_medians()) 'dbfs_current': dbfs_current,
'dbfs_threshold': dbfs_threshold,
if debug_flag: 'alarm': bool(alarm),
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) 'channel_idx': int(max_idx),
print(cur_channel, single_alarm) 'channels_total': int(len(sigs_array)),
if single_alarm: 'channel_values': [float(v) for v in sigs_array],
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal()) 'channel_thresholds': channel_thresholds,
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?') 'alarm_channels': alarm_channels,
try: },
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) host=telemetry_host,
except Exception as e: port=telemetry_port,
print(f"Ошибка: {e}") endpoint=telemetry_endpoint,
else: timeout_sec=telemetry_timeout_sec,
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') )
except Exception as exc:
f = multi_channel.change_channel() if debug_flag:
except Exception as e: print(f'telemetry send failed: {exc}')
print(str(e))
print(".", end='') if send_to_module_flag:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
tmp_signal.clear()
if save_data_flag:
return f if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
print(cur_channel, single_alarm)
if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e:
print(f'Ошибка: {e}')
else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print('.', end='')
tmp_signal.clear()
return f

@ -1,120 +1,150 @@
import os import os
import datetime import datetime
from common.runtime import load_root_env, validate_env, as_bool, as_str import time
from common.runtime import load_root_env, as_bool
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from utils.datas_processing import pack_elems, agregator, send_data, send_telemetry, save_data, remote_save_data
from core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from utils.jammer_state_flag import is_jammer_active
from core.multichannelswitcher import MultiChannel, get_centre_freq from core.sig_n_medi_collect import Signal, SignalsArray
from core.multichannelswitcher import MultiChannel
load_root_env(__file__) load_root_env(__file__)
freq_suffix = os.path.splitext(os.path.basename(__file__))[0].split("_")[-1]
validate_env(__file__, { debug_flag = as_bool(os.getenv('debug_flag', '0'))
"send_to_module_flag": as_bool, send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0'))
"save_data_flag": as_bool, save_data_flag = as_bool(os.getenv('save_data_flag', '0'))
"elems_to_save": as_str, module_name = os.getenv('module_name')
"file_types_to_save": as_str, elems_to_save = os.getenv('elems_to_save')
"lochost": as_str, file_types_to_save = os.getenv('file_types_to_save')
"locport": as_str, localhost = os.getenv('lochost')
"freq_endpoint": as_str, localport = os.getenv('locport')
"path_to_save_medians": as_str, f_step = [*map(float, os.getenv('f_step_868').split())]
"path_to_save_alarms": as_str, f_bases = [*map(float, os.getenv('f_bases_868').split())]
"module_name": as_str, f_roofs = [*map(float, os.getenv('f_roofs_868').split())]
f"f_step_{freq_suffix}": as_str, signal_length = int(os.getenv('signal_length_868'))
f"f_bases_{freq_suffix}": as_str, buffer_columns_size = int(os.getenv('buffer_columns_size_868'))
f"f_roofs_{freq_suffix}": as_str, num_of_thinning_iter = int(os.getenv('num_of_thinning_iter_868'))
}) multiply_factor = float(os.getenv('multiply_factor_868'))
num_for_alarm = int(os.getenv('num_for_alarm_868'))
debug_flag = as_bool(os.getenv('debug_flag', '0')) c_freq = os.getenv('c_freq_868', '868')
send_to_module_flag = as_bool(os.getenv('send_to_module_flag', '0')) path_to_save_medians = os.getenv('path_to_save_medians')
save_data_flag = as_bool(os.getenv('save_data_flag', '0')) path_to_save_alarms = os.getenv('path_to_save_alarms')
module_name = os.getenv('module_name') smb_host = os.getenv('smb_host')
elems_to_save = os.getenv('elems_to_save') smb_port = os.getenv('smb_port')
file_types_to_save = os.getenv('file_types_to_save') smb_user = os.getenv('smb_user')
localhost = os.getenv('lochost') smb_pass = os.getenv('smb_pass')
localport = os.getenv('locport') shared_folder = os.getenv('shared_folder')
f_step = [*map(float, os.getenv('f_step_868').split())] the_pc_name = os.getenv('the_pc_name')
f_bases = [*map(float, os.getenv('f_bases_868').split())] remote_pc_name = os.getenv('remote_pc_name')
f_roofs = [*map(float, os.getenv('f_roofs_868').split())] smb_domain = os.getenv('smb_domain')
path_to_save_medians = os.getenv('path_to_save_medians') freq_endpoint = os.getenv('freq_endpoint')
path_to_save_alarms = os.getenv('path_to_save_alarms') telemetry_enabled = as_bool(os.getenv('telemetry_enabled', '1'))
smb_host = os.getenv('smb_host') telemetry_host = os.getenv('telemetry_host', '127.0.0.1')
smb_port = os.getenv('smb_port') telemetry_port = os.getenv('telemetry_port', '5020')
smb_user = os.getenv('smb_user') telemetry_endpoint = os.getenv('telemetry_endpoint', 'telemetry')
smb_pass = os.getenv('smb_pass') telemetry_timeout_sec = float(os.getenv('telemetry_timeout_sec', '0.30'))
shared_folder = os.getenv('shared_folder')
the_pc_name = os.getenv('the_pc_name') elems_to_save = elems_to_save.split(',')
remote_pc_name = os.getenv('remote_pc_name') file_types_to_save = file_types_to_save.split(',')
smb_domain = os.getenv('smb_domain')
freq_endpoint = os.getenv('freq_endpoint') tmp_signal = Signal()
tmp_sigs_array = SignalsArray()
elems_to_save = elems_to_save.split(',') multi_channel = MultiChannel(f_step, f_bases, f_roofs)
file_types_to_save = file_types_to_save.split(',') f = multi_channel.init_f()
multi_channel.fill_DB(
tmp_signal = Signal() buffer_columns_size,
tmp_sigs_array = SignalsArray() num_of_thinning_iter,
multi_channel = MultiChannel(f_step, f_bases, f_roofs) multiply_factor,
f = multi_channel.init_f() num_for_alarm,
multi_channel.fill_DB() c_freq,
)
if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) if debug_flag:
conn.connect(smb_host, 139) conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
filelist = conn.listPath(shared_folder, '/') conn.connect(smb_host, 139)
print(filelist) filelist = conn.listPath(shared_folder, '/')
print(filelist)
def work(lvl):
def work(lvl):
f = multi_channel.get_cur_channel() f = multi_channel.get_cur_channel()
freq = get_centre_freq(f) freq = c_freq
signal_length = get_signal_length(freq) median = tmp_signal.fill_signal(lvl, signal_length)
median = tmp_signal.fill_signal(lvl, signal_length) packet_ts = tmp_signal.get_last_packet_ts()
if median: if median:
try: try:
num_chs, circle_buffer = multi_channel.check_f(f) num_chs, circle_buffer = multi_channel.check_f(f)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs) cur_channel, sigs_array, sigs_ts_array = tmp_sigs_array.fill_sig_arr(median, packet_ts=packet_ts, num_chs=num_chs)
if sigs_array: if sigs_array:
print('Значения на {0}: {1}'.format(freq, sigs_array)) print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians()) print('Пороги: ', circle_buffer.get_medians())
alarm = circle_buffer.check_alarm(sigs_array) alarm = circle_buffer.check_alarm(sigs_array)
if alarm: if alarm:
print('----ALARM---- ', freq) print('----ALARM---- ', freq)
multi_channel.db_alarms_zeros(circle_buffer) multi_channel.db_alarms_zeros(circle_buffer)
else: elif not is_jammer_active():
circle_buffer.update(sigs_array) circle_buffer.update(sigs_array, packet_timestamps=sigs_ts_array)
if send_to_module_flag: if telemetry_enabled:
send_data(agregator(freq, alarm), localhost, localport, freq_endpoint) try:
max_idx = max(range(len(sigs_array)), key=lambda idx: sigs_array[idx])
if save_data_flag: dbfs_current = float(sigs_array[max_idx])
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: dbfs_threshold = circle_buffer.get_threshold(max_idx)
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), channel_thresholds = circle_buffer.get_thresholds()
list(range(num_chs))) alarm_channels = circle_buffer.get_last_alarm_channels() if alarm else []
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, send_telemetry(
circle_buffer.get_medians()) data={
'freq': str(freq),
if debug_flag: 'ts': time.time(),
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) 'dbfs_current': dbfs_current,
print(cur_channel, single_alarm) 'dbfs_threshold': dbfs_threshold,
if single_alarm: 'alarm': bool(alarm),
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal()) 'channel_idx': int(max_idx),
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?') 'channels_total': int(len(sigs_array)),
try: 'channel_values': [float(v) for v in sigs_array],
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) 'channel_thresholds': channel_thresholds,
except Exception as e: 'alarm_channels': alarm_channels,
print(f"Ошибка: {e}") },
else: host=telemetry_host,
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') port=telemetry_port,
endpoint=telemetry_endpoint,
f = multi_channel.change_channel() timeout_sec=telemetry_timeout_sec,
except Exception as e: )
print(str(e)) except Exception as exc:
print(".", end='') if debug_flag:
print(f'telemetry send failed: {exc}')
tmp_signal.clear()
if send_to_module_flag:
return f send_data(agregator(freq, alarm), localhost, localport, freq_endpoint)
if save_data_flag:
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), list(range(num_chs)))
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, circle_buffer.get_medians())
if debug_flag:
single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
print(cur_channel, single_alarm)
if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, tmp_signal.get_signal())
print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
try:
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
except Exception as e:
print(f'Ошибка: {e}')
else:
print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print('.', end='')
tmp_signal.clear()
return f

@ -0,0 +1,104 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gnuradio import blocks
from gnuradio import gr
import signal
import sys
import threading
import time
import osmosdr
import embedded_1500 as my_freq
from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__)
def get_hack_id():
return resolve_hackrf_index('hack_1500', 'src/main_1500.py')
class get_center_freq(gr.top_block):
def __init__(self):
gr.top_block.__init__(self, 'get_center_freq')
self.prob_freq = 0
self.samp_rate = 20e6
self.poll_rate = 10000
self.vector_len = 4096
self.center_freq = my_freq.work(self.prob_freq)
self._prob_freq_thread = None
self.probSigVec = blocks.probe_signal_vc(self.vector_len)
self.rtlsdr_source_0 = osmosdr.source(
args='numchan=' + str(1) + ' ' + 'hackrf=' + get_hack_id()
)
self.rtlsdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t())
self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
self.rtlsdr_source_0.set_center_freq(self.center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(24, 0)
self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(100, 0)
self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(self.vector_len)
self.blocks_stream_to_vector_1 = blocks.stream_to_vector(gr.sizeof_gr_complex * 1, self.vector_len)
self.connect((self.blocks_stream_to_vector_1, 0), (self.probSigVec, 0))
self.connect((self.rtlsdr_source_0, 0), (self.blocks_stream_to_vector_1, 0))
def _prob_freq_probe():
while True:
val = self.probSigVec.level()
try:
self.set_prob_freq(val)
except AttributeError:
pass
time.sleep(1.0 / self.poll_rate)
self._prob_freq_thread = threading.Thread(target=_prob_freq_probe, daemon=True)
self._prob_freq_thread.start()
def get_prob_freq(self):
return self.prob_freq
def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq))
def get_center_freq(self):
return self.center_freq
def set_center_freq(self, center_freq):
self.center_freq = center_freq
self.rtlsdr_source_0.set_center_freq(self.center_freq, 0)
def main(top_block_cls=get_center_freq, options=None):
tb = top_block_cls()
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
try:
print('СЕРВИСНАЯ ИНФОРМАЦИЯ: ')
print('debug_flag: ', my_freq.debug_flag)
print('save_data_flag: ', my_freq.save_data_flag)
print('send_to_module_flag: ', my_freq.send_to_module_flag)
except EOFError:
pass
tb.wait()
if __name__ == '__main__':
main()

@ -18,12 +18,12 @@ import time
import threading import threading
import subprocess import subprocess
import os import os
import numpy as np
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('hack_3300', 'src/main_3300.py') return resolve_hackrf_index('hack_3300', 'src/main_3300.py')
serial_number = os.getenv('hack_3300') serial_number = os.getenv('hack_3300')
@ -83,6 +83,14 @@ class get_center_freq(gr.top_block):
self.flag = flag = 1 self.flag = flag = 1
self.decimation = decimation = 1 self.decimation = decimation = 1
self.center_freq = center_freq = my_freq.work(prob_freq) self.center_freq = center_freq = my_freq.work(prob_freq)
self.read_pipe_settle_sec = float(os.getenv('read_pipe_settle_sec_hf', '0.003'))
self.read_pipe_windows_per_update = max(1, int(os.getenv('read_pipe_windows_per_update_hf', '3')) )
self.read_pipe_vec_len = 4096
self.read_pipe_window_sec = self.read_pipe_vec_len / self.samp_rate
self.read_pipe_poll_sec = float(os.getenv('read_pipe_poll_sec_hf', str(self.read_pipe_window_sec)))
self.read_pipe_poll_sec = max(self.read_pipe_window_sec, self.read_pipe_poll_sec)
self.read_pipe_next_at = time.monotonic()
self.read_pipe_settle_until = 0.0
################################################## ##################################################
# Blocks # Blocks
@ -95,21 +103,42 @@ class get_center_freq(gr.top_block):
self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_sample_rate(samp_rate)
self.rtlsdr_source_0.set_center_freq(center_freq, 0) self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(100, 0) self.rtlsdr_source_0.set_gain(24, 0)
self.rtlsdr_source_0.set_if_gain(100, 0) self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(0, 0) self.rtlsdr_source_0.set_bb_gain(100, 0)
self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096) self.rtlsdr_source_0.set_min_output_buffer(4096)
def _prob_freq_probe(): def _prob_freq_probe():
while True: while True:
now = time.monotonic()
if now < self.read_pipe_settle_until:
time.sleep(min(self.read_pipe_poll_sec, self.read_pipe_settle_until - now))
continue
windows = []
for i in range(self.read_pipe_windows_per_update):
windows.append(np.array(self.probSigVec.level()).ravel())
if i + 1 < self.read_pipe_windows_per_update:
time.sleep(self.read_pipe_window_sec)
if len(windows) == 1:
val = windows[0]
else:
val = np.concatenate(windows, axis=None)
val = self.probSigVec.level()
try: try:
self.set_prob_freq(val) self.set_prob_freq(val)
except AttributeError: except AttributeError:
pass pass
time.sleep(1.0 / (poll_rate))
self.read_pipe_next_at += self.read_pipe_poll_sec
sleep_for = self.read_pipe_next_at - time.monotonic()
if sleep_for > 0:
time.sleep(sleep_for)
else:
self.read_pipe_next_at = time.monotonic()
_prob_freq_thread = threading.Thread(target=_prob_freq_probe) _prob_freq_thread = threading.Thread(target=_prob_freq_probe)
_prob_freq_thread.daemon = True _prob_freq_thread.daemon = True
_prob_freq_thread.start() _prob_freq_thread.start()
@ -129,7 +158,12 @@ class get_center_freq(gr.top_block):
def set_prob_freq(self, prob_freq): def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq)) next_center = my_freq.work(self.prob_freq)
if next_center is None:
return
if next_center != self.center_freq:
self.set_center_freq(next_center)
self.read_pipe_settle_until = time.monotonic() + self.read_pipe_settle_sec
def get_top_peaks_amount(self): def get_top_peaks_amount(self):
return self.top_peaks_amount return self.top_peaks_amount

@ -21,11 +21,10 @@ import os
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('hack_433', 'src/main_433.py') return resolve_hackrf_index('hack_433', 'src/main_433.py')
serial_number = os.getenv('hack_433') serial_number = os.getenv('hack_433')
pos = None pos = None
output = [] output = []
@ -95,9 +94,9 @@ class get_center_freq(gr.top_block):
self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_sample_rate(samp_rate)
self.rtlsdr_source_0.set_center_freq(center_freq, 0) self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(10, 0) self.rtlsdr_source_0.set_gain(24, 0)
self.rtlsdr_source_0.set_if_gain(100, 0) self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(0, 0) self.rtlsdr_source_0.set_bb_gain(100, 0)
self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096) self.rtlsdr_source_0.set_min_output_buffer(4096)

@ -18,12 +18,12 @@ import time
import threading import threading
import subprocess import subprocess
import os import os
import numpy as np
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('hack_4500', 'src/main_4500.py') return resolve_hackrf_index('hack_4500', 'src/main_4500.py')
serial_number = os.getenv('hack_4500') serial_number = os.getenv('hack_4500')
@ -83,6 +83,14 @@ class get_center_freq(gr.top_block):
self.flag = flag = 1 self.flag = flag = 1
self.decimation = decimation = 1 self.decimation = decimation = 1
self.center_freq = center_freq = my_freq.work(prob_freq) self.center_freq = center_freq = my_freq.work(prob_freq)
self.read_pipe_settle_sec = float(os.getenv('read_pipe_settle_sec_hf', '0.003'))
self.read_pipe_windows_per_update = max(1, int(os.getenv('read_pipe_windows_per_update_hf', '3')) )
self.read_pipe_vec_len = 4096
self.read_pipe_window_sec = self.read_pipe_vec_len / self.samp_rate
self.read_pipe_poll_sec = float(os.getenv('read_pipe_poll_sec_hf', str(self.read_pipe_window_sec)))
self.read_pipe_poll_sec = max(self.read_pipe_window_sec, self.read_pipe_poll_sec)
self.read_pipe_next_at = time.monotonic()
self.read_pipe_settle_until = 0.0
################################################## ##################################################
# Blocks # Blocks
@ -95,21 +103,42 @@ class get_center_freq(gr.top_block):
self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_sample_rate(samp_rate)
self.rtlsdr_source_0.set_center_freq(center_freq, 0) self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(100, 0) self.rtlsdr_source_0.set_gain(24, 0)
self.rtlsdr_source_0.set_if_gain(100, 0) self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(0, 0) self.rtlsdr_source_0.set_bb_gain(100, 0)
self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096) self.rtlsdr_source_0.set_min_output_buffer(4096)
def _prob_freq_probe(): def _prob_freq_probe():
while True: while True:
now = time.monotonic()
if now < self.read_pipe_settle_until:
time.sleep(min(self.read_pipe_poll_sec, self.read_pipe_settle_until - now))
continue
windows = []
for i in range(self.read_pipe_windows_per_update):
windows.append(np.array(self.probSigVec.level()).ravel())
if i + 1 < self.read_pipe_windows_per_update:
time.sleep(self.read_pipe_window_sec)
if len(windows) == 1:
val = windows[0]
else:
val = np.concatenate(windows, axis=None)
val = self.probSigVec.level()
try: try:
self.set_prob_freq(val) self.set_prob_freq(val)
except AttributeError: except AttributeError:
pass pass
time.sleep(1.0 / (poll_rate))
self.read_pipe_next_at += self.read_pipe_poll_sec
sleep_for = self.read_pipe_next_at - time.monotonic()
if sleep_for > 0:
time.sleep(sleep_for)
else:
self.read_pipe_next_at = time.monotonic()
_prob_freq_thread = threading.Thread(target=_prob_freq_probe) _prob_freq_thread = threading.Thread(target=_prob_freq_probe)
_prob_freq_thread.daemon = True _prob_freq_thread.daemon = True
_prob_freq_thread.start() _prob_freq_thread.start()
@ -129,7 +158,12 @@ class get_center_freq(gr.top_block):
def set_prob_freq(self, prob_freq): def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq)) next_center = my_freq.work(self.prob_freq)
if next_center is None:
return
if next_center != self.center_freq:
self.set_center_freq(next_center)
self.read_pipe_settle_until = time.monotonic() + self.read_pipe_settle_sec
def get_top_peaks_amount(self): def get_top_peaks_amount(self):
return self.top_peaks_amount return self.top_peaks_amount

@ -18,14 +18,13 @@ import time
import threading import threading
import subprocess import subprocess
import os import os
import numpy as np
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('hack_5200', 'src/main_5200.py') return resolve_hackrf_index('hack_5200', 'src/main_5200.py')
serial_number = os.getenv('hack_5200') serial_number = os.getenv('hack_5200')
pos = None pos = None
output = [] output = []
@ -83,6 +82,14 @@ class get_center_freq(gr.top_block):
self.flag = flag = 1 self.flag = flag = 1
self.decimation = decimation = 1 self.decimation = decimation = 1
self.center_freq = center_freq = my_freq.work(prob_freq) self.center_freq = center_freq = my_freq.work(prob_freq)
self.read_pipe_settle_sec = float(os.getenv('read_pipe_settle_sec_hf', '0.003'))
self.read_pipe_windows_per_update = max(1, int(os.getenv('read_pipe_windows_per_update_hf', '3')) )
self.read_pipe_vec_len = 4096
self.read_pipe_window_sec = self.read_pipe_vec_len / self.samp_rate
self.read_pipe_poll_sec = float(os.getenv('read_pipe_poll_sec_hf', str(self.read_pipe_window_sec)))
self.read_pipe_poll_sec = max(self.read_pipe_window_sec, self.read_pipe_poll_sec)
self.read_pipe_next_at = time.monotonic()
self.read_pipe_settle_until = 0.0
################################################## ##################################################
# Blocks # Blocks
@ -96,20 +103,41 @@ class get_center_freq(gr.top_block):
self.rtlsdr_source_0.set_center_freq(center_freq, 0) self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(100, 0) self.rtlsdr_source_0.set_gain(100, 0)
self.rtlsdr_source_0.set_if_gain(100, 0) self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(0, 0) self.rtlsdr_source_0.set_bb_gain(24, 0)
self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096) self.rtlsdr_source_0.set_min_output_buffer(4096)
def _prob_freq_probe(): def _prob_freq_probe():
while True: while True:
now = time.monotonic()
if now < self.read_pipe_settle_until:
time.sleep(min(self.read_pipe_poll_sec, self.read_pipe_settle_until - now))
continue
windows = []
for i in range(self.read_pipe_windows_per_update):
windows.append(np.array(self.probSigVec.level()).ravel())
if i + 1 < self.read_pipe_windows_per_update:
time.sleep(self.read_pipe_window_sec)
if len(windows) == 1:
val = windows[0]
else:
val = np.concatenate(windows, axis=None)
val = self.probSigVec.level()
try: try:
self.set_prob_freq(val) self.set_prob_freq(val)
except AttributeError: except AttributeError:
pass pass
time.sleep(1.0 / (poll_rate))
self.read_pipe_next_at += self.read_pipe_poll_sec
sleep_for = self.read_pipe_next_at - time.monotonic()
if sleep_for > 0:
time.sleep(sleep_for)
else:
self.read_pipe_next_at = time.monotonic()
_prob_freq_thread = threading.Thread(target=_prob_freq_probe) _prob_freq_thread = threading.Thread(target=_prob_freq_probe)
_prob_freq_thread.daemon = True _prob_freq_thread.daemon = True
_prob_freq_thread.start() _prob_freq_thread.start()
@ -129,7 +157,12 @@ class get_center_freq(gr.top_block):
def set_prob_freq(self, prob_freq): def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq)) next_center = my_freq.work(self.prob_freq)
if next_center is None:
return
if next_center != self.center_freq:
self.set_center_freq(next_center)
self.read_pipe_settle_until = time.monotonic() + self.read_pipe_settle_sec
def get_top_peaks_amount(self): def get_top_peaks_amount(self):
return self.top_peaks_amount return self.top_peaks_amount

@ -18,14 +18,14 @@ import time
import threading import threading
import subprocess import subprocess
import os import os
import numpy as np
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('hack_5800', 'src/main_5800.py') return resolve_hackrf_index('hack_5800', 'src/main_5800.py')
serial_number = os.getenv('hack_5800') serial_number = os.getenv('hack_5800')
pos = None pos = None
output = [] output = []
@ -83,6 +83,14 @@ class get_center_freq(gr.top_block):
self.flag = flag = 1 self.flag = flag = 1
self.decimation = decimation = 1 self.decimation = decimation = 1
self.center_freq = center_freq = my_freq.work(prob_freq) self.center_freq = center_freq = my_freq.work(prob_freq)
self.read_pipe_settle_sec = float(os.getenv('read_pipe_settle_sec_hf', '0.003'))
self.read_pipe_windows_per_update = max(1, int(os.getenv('read_pipe_windows_per_update_hf', '3')) )
self.read_pipe_vec_len = 4096
self.read_pipe_window_sec = self.read_pipe_vec_len / self.samp_rate
self.read_pipe_poll_sec = float(os.getenv('read_pipe_poll_sec_hf', str(self.read_pipe_window_sec)))
self.read_pipe_poll_sec = max(self.read_pipe_window_sec, self.read_pipe_poll_sec)
self.read_pipe_next_at = time.monotonic()
self.read_pipe_settle_until = 0.0
################################################## ##################################################
# Blocks # Blocks
@ -95,21 +103,42 @@ class get_center_freq(gr.top_block):
self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_sample_rate(samp_rate)
self.rtlsdr_source_0.set_center_freq(center_freq, 0) self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(5, 0) self.rtlsdr_source_0.set_gain(24, 0)
self.rtlsdr_source_0.set_if_gain(100, 0) self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(100, 0) self.rtlsdr_source_0.set_bb_gain(100, 0)
self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096) self.rtlsdr_source_0.set_min_output_buffer(4096)
def _prob_freq_probe(): def _prob_freq_probe():
while True: while True:
now = time.monotonic()
if now < self.read_pipe_settle_until:
time.sleep(min(self.read_pipe_poll_sec, self.read_pipe_settle_until - now))
continue
windows = []
for i in range(self.read_pipe_windows_per_update):
windows.append(np.array(self.probSigVec.level()).ravel())
if i + 1 < self.read_pipe_windows_per_update:
time.sleep(self.read_pipe_window_sec)
if len(windows) == 1:
val = windows[0]
else:
val = np.concatenate(windows, axis=None)
val = self.probSigVec.level()
try: try:
self.set_prob_freq(val) self.set_prob_freq(val)
except AttributeError: except AttributeError:
pass pass
time.sleep(1.0 / (poll_rate))
self.read_pipe_next_at += self.read_pipe_poll_sec
sleep_for = self.read_pipe_next_at - time.monotonic()
if sleep_for > 0:
time.sleep(sleep_for)
else:
self.read_pipe_next_at = time.monotonic()
_prob_freq_thread = threading.Thread(target=_prob_freq_probe) _prob_freq_thread = threading.Thread(target=_prob_freq_probe)
_prob_freq_thread.daemon = True _prob_freq_thread.daemon = True
_prob_freq_thread.start() _prob_freq_thread.start()
@ -129,7 +158,12 @@ class get_center_freq(gr.top_block):
def set_prob_freq(self, prob_freq): def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq)) next_center = my_freq.work(self.prob_freq)
if next_center is None:
return
if next_center != self.center_freq:
self.set_center_freq(next_center)
self.read_pipe_settle_until = time.monotonic() + self.read_pipe_settle_sec
def get_top_peaks_amount(self): def get_top_peaks_amount(self):
return self.top_peaks_amount return self.top_peaks_amount

@ -21,11 +21,10 @@ import os
from common.runtime import load_root_env, resolve_hackrf_index from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): def get_hack_id():
return resolve_hackrf_index('hack_750', 'src/main_750.py') return resolve_hackrf_index('hack_750', 'src/main_750.py')
serial_number = os.getenv('hack_750') serial_number = os.getenv('hack_750')
pos = None pos = None
output = [] output = []
@ -95,9 +94,9 @@ class get_center_freq(gr.top_block):
self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_sample_rate(samp_rate)
self.rtlsdr_source_0.set_center_freq(center_freq, 0) self.rtlsdr_source_0.set_center_freq(center_freq, 0)
self.rtlsdr_source_0.set_freq_corr(0, 0) self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_gain(100, 0) self.rtlsdr_source_0.set_gain(24, 0)
self.rtlsdr_source_0.set_if_gain(100, 0) self.rtlsdr_source_0.set_if_gain(24, 0)
self.rtlsdr_source_0.set_bb_gain(0, 0) self.rtlsdr_source_0.set_bb_gain(100, 0)
self.rtlsdr_source_0.set_antenna('', 0) self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_bandwidth(0, 0) self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096) self.rtlsdr_source_0.set_min_output_buffer(4096)

@ -1,208 +1,99 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# from gnuradio import blocks
# SPDX-License-Identifier: GPL-3.0 from gnuradio import gr
# from gnuradio import zeromq
# GNU Radio Python Flow Graph import signal
# Title: get_center_freq import sys
# GNU Radio version: 3.8.1.0 import threading
import time
from gnuradio import blocks
from gnuradio import gr import embedded_868 as my_freq
import sys
import signal from common.runtime import load_root_env
import embedded_868 as my_freq # embedded python module from common.shared_stream_addrs import SHARED_868_ADDR, SHARED_VECTOR_LEN
import osmosdr
import time
import threading
import subprocess
import os
from common.runtime import load_root_env, resolve_hackrf_index
load_root_env(__file__) load_root_env(__file__)
def get_hack_id(): class get_center_freq(gr.top_block):
return resolve_hackrf_index('hack_868', 'src/main_868.py') def __init__(self):
serial_number = os.getenv('hack_868') gr.top_block.__init__(self, 'get_center_freq')
pos = None
output = [] self.prob_freq = 0
try: self.poll_rate = 10000
# command = '/home/orangepi/hackrf/host/build/hackrf-tools/src/hackrf_info' self.vector_len = SHARED_VECTOR_LEN
command = 'lsusb -v -d 1d50:6089 | grep iSerial' self.center_freq = 0
output.append(subprocess.check_output(command, shell=True, text=True)) self.shared_addr = SHARED_868_ADDR
self._stop_polling = threading.Event()
# indexes = [line.split(":")[1].strip() for line in output_lines if "Index" in line] self._prob_freq_thread = None
# serial_numbers = [line.split(":")[1].strip() for line in output_lines if "Serial number" in line]
# print(indexes) self.probSigVec = blocks.probe_signal_vc(self.vector_len)
# print(serial_numbers) self.shared_source_0 = zeromq.pull_source(
# for i, number in enumerate(serial_numbers): gr.sizeof_gr_complex,
# if number == serial_number: self.vector_len,
# pos = i self.shared_addr,
# break 100,
# if pos is not None: False,
# id = indexes[pos] -1,
# else: False,
# print('Такого хака нет!') )
except subprocess.CalledProcessError as e: self.connect((self.shared_source_0, 0), (self.probSigVec, 0))
print(f"Команда завершилась с кодом возврата {e.returncode}")
print(e) def start_polling(self):
print(output) if self._prob_freq_thread is not None:
output_lines = output[0].strip().split('\n') return
print(output_lines)
serial_numbers = [line.split()[-1] for line in output_lines] def _prob_freq_probe():
print(serial_numbers) while not self._stop_polling.is_set():
for i, number in enumerate(serial_numbers): self.set_prob_freq(self.probSigVec.level())
if number == serial_number: time.sleep(1.0 / self.poll_rate)
id = i
break self._prob_freq_thread = threading.Thread(target=_prob_freq_probe, daemon=True)
if id is not None: self._prob_freq_thread.start()
print('HackId is: {0}'.format(id))
return str(id) def get_prob_freq(self):
else: return self.prob_freq
print('Такого хака нет!')
def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq
self.center_freq = my_freq.work(self.prob_freq)
class get_center_freq(gr.top_block): def get_center_freq(self):
return self.center_freq
def __init__(self):
gr.top_block.__init__(self, "get_center_freq") def set_center_freq(self, center_freq):
self.center_freq = center_freq
##################################################
# Variables def close(self):
################################################## self._stop_polling.set()
self.prob_freq = prob_freq = 0 self.stop()
self.top_peaks_amount = top_peaks_amount = 20 self.wait()
self.samp_rate = samp_rate = 20e6
self.poll_rate = poll_rate = 10000
self.num_points = num_points = 8192 def main(top_block_cls=get_center_freq, options=None):
self.flag = flag = 1 tb = top_block_cls()
self.decimation = decimation = 1
self.center_freq = center_freq = my_freq.work(prob_freq) def sig_handler(sig=None, frame=None):
tb.close()
################################################## sys.exit(0)
# Blocks
################################################## signal.signal(signal.SIGINT, sig_handler)
self.probSigVec = blocks.probe_signal_vc(4096) signal.signal(signal.SIGTERM, sig_handler)
self.rtlsdr_source_0 = osmosdr.source(
args="numchan=" + str(1) + " " + 'hackrf=' + get_hack_id() tb.start()
) tb.start_polling()
self.rtlsdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t()) try:
self.rtlsdr_source_0.set_sample_rate(samp_rate) print('shared_pull_addr:', SHARED_868_ADDR)
self.rtlsdr_source_0.set_center_freq(center_freq, 0) print('debug_flag:', my_freq.debug_flag)
self.rtlsdr_source_0.set_freq_corr(0, 0) print('save_data_flag:', my_freq.save_data_flag)
self.rtlsdr_source_0.set_gain(100, 0) print('send_to_module_flag:', my_freq.send_to_module_flag)
self.rtlsdr_source_0.set_if_gain(100, 0) except EOFError:
self.rtlsdr_source_0.set_bb_gain(0, 0) pass
self.rtlsdr_source_0.set_antenna('', 0) tb.wait()
self.rtlsdr_source_0.set_bandwidth(0, 0)
self.rtlsdr_source_0.set_min_output_buffer(4096)
def _prob_freq_probe(): if __name__ == '__main__':
while True: main()
val = self.probSigVec.level()
try:
self.set_prob_freq(val)
except AttributeError:
pass
time.sleep(1.0 / (poll_rate))
_prob_freq_thread = threading.Thread(target=_prob_freq_probe)
_prob_freq_thread.daemon = True
_prob_freq_thread.start()
self.blocks_stream_to_vector_1 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, 4096)
##################################################
# Connections
##################################################
self.connect((self.blocks_stream_to_vector_1, 0), (self.probSigVec, 0))
self.connect((self.rtlsdr_source_0, 0), (self.blocks_stream_to_vector_1, 0))
def get_prob_freq(self):
return self.prob_freq
def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq
self.set_center_freq(my_freq.work(self.prob_freq))
def get_top_peaks_amount(self):
return self.top_peaks_amount
def set_top_peaks_amount(self, top_peaks_amount):
self.top_peaks_amount = top_peaks_amount
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
def get_poll_rate(self):
return self.poll_rate
def set_poll_rate(self, poll_rate):
self.poll_rate = poll_rate
def get_num_points(self):
return self.num_points
def set_num_points(self, num_points):
self.num_points = num_points
def get_flag(self):
return self.flag
def set_flag(self, flag):
self.flag = flag
def get_decimation(self):
return self.decimation
def set_decimation(self, decimation):
self.decimation = decimation
def get_center_freq(self):
return self.center_freq
def set_center_freq(self, center_freq):
self.center_freq = center_freq
self.rtlsdr_source_0.set_center_freq(self.center_freq, 0)
def main(top_block_cls=get_center_freq, options=None):
#for k in range(0, 3):
# light_diods_on_boot()
tb = top_block_cls()
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
try:
print('СЕРВИСНАЯ ИНФОРМАЦИЯ: ')
print('debug_flag: ', my_freq.debug_flag)
print('save_data_flag: ', my_freq.save_data_flag)
print('send_to_module_flag: ', my_freq.send_to_module_flag)
#print('multiply_factor: ', float(os.getenv('multiply_factor_' + '1200')))
#print('multiply_factor: ', float(os.getenv('multiply_factor_' + '715')))
except EOFError:
pass
#tb.stop()
tb.wait()
if __name__ == '__main__':
main()

@ -0,0 +1,122 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gnuradio import blocks
from gnuradio import gr
import signal
import sys
import threading
import time
import osmosdr
from common.runtime import load_root_env, resolve_hackrf_index
from common.shared_stream_addrs import SHARED_VECTOR_LEN
from shared_router_868_915 import SharedRouter868915
load_root_env(__file__)
def get_hack_id():
return resolve_hackrf_index('hack_868', 'src/main_868_915_router.py')
class get_center_freq(gr.top_block):
def __init__(self):
gr.top_block.__init__(self, 'get_center_freq')
self.prob_freq = 0
self.poll_rate = 10000
self.vector_len = SHARED_VECTOR_LEN
self.router = SharedRouter868915()
self.active_lane = self.router.get_active_name()
self.center_freq = self.router.get_start_freq()
self._stop_polling = threading.Event()
self._prob_freq_thread = None
self.probSigVec = blocks.probe_signal_vc(self.vector_len)
self.rtlsdr_source_0 = osmosdr.source(
args='numchan=' + str(1) + ' ' + 'hackrf=' + get_hack_id()
)
self.rtlsdr_source_0.set_time_unknown_pps(osmosdr.time_spec_t())
self.rtlsdr_source_0.set_freq_corr(0, 0)
self.rtlsdr_source_0.set_antenna('', 0)
self.rtlsdr_source_0.set_min_output_buffer(self.vector_len)
self.apply_active_frontend()
self.rtlsdr_source_0.set_center_freq(self.center_freq, 0)
self.blocks_stream_to_vector_1 = blocks.stream_to_vector(gr.sizeof_gr_complex * 1, self.vector_len)
self.connect((self.rtlsdr_source_0, 0), (self.blocks_stream_to_vector_1, 0))
self.connect((self.blocks_stream_to_vector_1, 0), (self.probSigVec, 0))
def start_polling(self):
if self._prob_freq_thread is not None:
return
def _prob_freq_probe():
while not self._stop_polling.is_set():
self.set_prob_freq(self.probSigVec.level())
time.sleep(1.0 / self.poll_rate)
self._prob_freq_thread = threading.Thread(target=_prob_freq_probe, daemon=True)
self._prob_freq_thread.start()
def apply_active_frontend(self):
frontend = self.router.get_active_frontend()
self.rtlsdr_source_0.set_sample_rate(frontend['sample_rate'])
self.rtlsdr_source_0.set_gain(frontend['gain'], 0)
self.rtlsdr_source_0.set_if_gain(frontend['if_gain'], 0)
self.rtlsdr_source_0.set_bb_gain(frontend['bb_gain'], 0)
self.rtlsdr_source_0.set_bandwidth(frontend['bandwidth'], 0)
def get_prob_freq(self):
return self.prob_freq
def set_prob_freq(self, prob_freq):
self.prob_freq = prob_freq
next_center, lane_switched = self.router.route_vector(self.prob_freq)
if lane_switched:
self.active_lane = self.router.get_active_name()
self.apply_active_frontend()
if next_center != self.center_freq:
self.set_center_freq(next_center)
def get_center_freq(self):
return self.center_freq
def set_center_freq(self, center_freq):
self.center_freq = center_freq
self.rtlsdr_source_0.set_center_freq(self.center_freq, 0)
def close(self):
self._stop_polling.set()
try:
self.router.close()
finally:
self.stop()
self.wait()
def main(top_block_cls=get_center_freq, options=None):
tb = top_block_cls()
def sig_handler(sig=None, frame=None):
tb.close()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
tb.start_polling()
try:
print('shared_router_active_lane:', tb.router.get_active_name())
print('shared_router_start_freq:', tb.get_center_freq())
except EOFError:
pass
tb.wait()
if __name__ == '__main__':
main()

@ -14,6 +14,7 @@ from fastapi import FastAPI
from common.runtime import load_root_env, validate_env, as_bool, as_float, as_int, as_str from common.runtime import load_root_env, validate_env, as_bool, as_float, as_int, as_str
from datetime import datetime, timedelta from datetime import datetime, timedelta
import logging import logging
from src.utils.jammer_state_flag import set_jammer_active
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
@ -416,6 +417,7 @@ async def jammer_active():
freqs_alarm = {freq: 0 for freq in freqs} freqs_alarm = {freq: 0 for freq in freqs}
jammer_event = True jammer_event = True
set_jammer_active(True)
print('АКТИВИРУЕМ ПОДАВИТЕЛЬ ААААААААААААААААААААААААААААААААААААААААААААААА!!!!') print('АКТИВИРУЕМ ПОДАВИТЕЛЬ ААААААААААААААААААААААААААААААААААААААААААААААА!!!!')
print('-' * 20) print('-' * 20)
@ -438,6 +440,7 @@ async def jammer_deactive():
global sending_data_task global sending_data_task
alarm = False alarm = False
jammer_event = False jammer_event = False
set_jammer_active(False)
sending_data_task = asyncio.create_task(sending_data()) sending_data_task = asyncio.create_task(sending_data())
print('ОТКЛЮАЕМ ПОДАВИТЕЛЬ ААААААААААААААААААААААААААААААААААААААААААААААААА!!!!') print('ОТКЛЮАЕМ ПОДАВИТЕЛЬ ААААААААААААААААААААААААААААААААААААААААААААААААА!!!!')
@ -496,6 +499,7 @@ async def jam_server():
await jammer_deactive() await jammer_deactive()
except Exception as e: except Exception as e:
jam_server_connect = None jam_server_connect = None
set_jammer_active(False)
if jammer_event: if jammer_event:
await jammer_deactive() await jammer_deactive()
@ -508,6 +512,7 @@ async def startup_event():
""" """
global sending_data_task global sending_data_task
set_jammer_active(False)
asyncio.create_task(jam_server()) asyncio.create_task(jam_server())
sending_data_task = asyncio.create_task(sending_data()) sending_data_task = asyncio.create_task(sending_data())

@ -0,0 +1,173 @@
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

@ -1,108 +1,116 @@
import os import os
import datetime import datetime
from smb.SMBConnection import SMBConnection from smb.SMBConnection import SMBConnection
from dotenv import load_dotenv from dotenv import load_dotenv
from DroneScanner.utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data from DroneScanner.utils.datas_processing import pack_elems, agregator, send_data, save_data, remote_save_data
from DroneScanner.core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length from DroneScanner.core.sig_n_medi_collect import Signal, SignalsArray, get_signal_length
from DroneScanner.core.multichannelswitcher import MultiChannel, get_centre_freq from DroneScanner.core.multichannelswitcher import MultiChannel, get_centre_freq
dotenv_path = os.path.join(os.path.dirname(__file__), '../../.env') dotenv_path = os.path.join(os.path.dirname(__file__), '../../.env')
if os.path.exists(dotenv_path): if os.path.exists(dotenv_path):
load_dotenv(dotenv_path) load_dotenv(dotenv_path)
debug_flag = bool(os.getenv('debug_flag')) debug_flag = bool(os.getenv('debug_flag'))
send_to_module_flag = bool(os.getenv('send_to_module_flag')) send_to_module_flag = bool(os.getenv('send_to_module_flag'))
save_data_flag = bool(os.getenv('save_data_flag')) save_data_flag = bool(os.getenv('save_data_flag'))
module_name = os.getenv('module_name') module_name = os.getenv('module_name')
elems_to_save = os.getenv('elems_to_save') elems_to_save = os.getenv('elems_to_save')
file_types_to_save = os.getenv('file_types_to_save') file_types_to_save = os.getenv('file_types_to_save')
localhost = os.getenv('lochost') localhost = os.getenv('lochost')
localport = os.getenv('locport') localport = os.getenv('locport')
f_step = [*map(float, os.getenv('f_step_1200').split())] f_step = [*map(float, os.getenv('f_step_1200').split())]
f_bases = [*map(float, os.getenv('f_bases_1200').split())] f_bases = [*map(float, os.getenv('f_bases_1200').split())]
f_roofs = [*map(float, os.getenv('f_roofs_1200').split())] f_roofs = [*map(float, os.getenv('f_roofs_1200').split())]
path_to_save_medians = os.getenv('path_to_save_medians')
path_to_save_alarms = os.getenv('path_to_save_alarms') c_freq = as_str(os.getenv(f'c_freq_{freq_suffix}', freq_suffix))path_to_save_medians = os.getenv('path_to_save_medians')
smb_host = os.getenv('smb_host') path_to_save_alarms = os.getenv('path_to_save_alarms')
smb_port = os.getenv('smb_port') smb_host = os.getenv('smb_host')
smb_user = os.getenv('smb_user') smb_port = os.getenv('smb_port')
smb_pass = os.getenv('smb_pass') smb_user = os.getenv('smb_user')
shared_folder = os.getenv('shared_folder') smb_pass = os.getenv('smb_pass')
the_pc_name = os.getenv('the_pc_name') shared_folder = os.getenv('shared_folder')
remote_pc_name = os.getenv('remote_pc_name') the_pc_name = os.getenv('the_pc_name')
smb_domain = os.getenv('smb_domain') remote_pc_name = os.getenv('remote_pc_name')
smb_domain = os.getenv('smb_domain')
elems_to_save = elems_to_save.split(',')
file_types_to_save = file_types_to_save.split(',') elems_to_save = elems_to_save.split(',')
file_types_to_save = file_types_to_save.split(',')
tmp_signal = Signal()
tmp_sigs_array = SignalsArray() tmp_signal = Signal()
multi_channel = MultiChannel(f_step, f_bases, f_roofs) tmp_sigs_array = SignalsArray()
f = multi_channel.init_f() multi_channel = MultiChannel(
multi_channel.fill_DB() f_step,
f_bases,
if debug_flag: f_roofs,
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True) config_tags=[freq_suffix] * len(f_step),
conn.connect(smb_host, 139) report_freqs=[c_freq] * len(f_step),
filelist = conn.listPath(shared_folder, '/') )
print(filelist) f = multi_channel.init_f()
multi_channel.fill_DB()
def work(lvl): if debug_flag:
conn = SMBConnection(smb_user, smb_pass, the_pc_name, remote_pc_name, use_ntlm_v2=True)
f = multi_channel.get_cur_channel() conn.connect(smb_host, 139)
freq = get_centre_freq(f) filelist = conn.listPath(shared_folder, '/')
signal_length = get_signal_length(freq) print(filelist)
median, signal, abs_signal = tmp_signal.fill_sig(lvl, signal_length)
if median != -1: def work(lvl):
try:
num_chs, circle_buffer = multi_channel.check_f(f) f = multi_channel.get_cur_channel()
config_tag = multi_channel.get_config_tag(f)
#print(f, freq, num_chs, signal_length) freq = multi_channel.get_report_freq(f)
#print(median) signal_length = get_signal_length(config_tag)
median, signal, abs_signal = tmp_signal.fill_sig(lvl, signal_length)
cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs)
if median != -1:
if sigs_array: try:
print('Значения на {0}: {1}'.format(freq, sigs_array)) num_chs, circle_buffer = multi_channel.check_f(f)
print('Пороги: ', circle_buffer.get_medians())
alarm = circle_buffer.check_alarm(sigs_array) #print(f, freq, num_chs, signal_length)
#print(median)
if alarm:
print('----ALARM---- ', freq) cur_channel, sigs_array = tmp_sigs_array.fill_sig_arr(median, num_chs)
multi_channel.db_alarms_zeros(circle_buffer)
else: if sigs_array:
circle_buffer.update(sigs_array) print('Значения на {0}: {1}'.format(freq, sigs_array))
print('Пороги: ', circle_buffer.get_medians())
if send_to_module_flag: alarm = circle_buffer.check_alarm(sigs_array)
send_data(agregator(freq, alarm), localhost, localport)
if alarm:
if save_data_flag: print('----ALARM---- ', freq)
if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0: multi_channel.db_alarms_zeros(circle_buffer)
save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)), else:
list(range(num_chs))) circle_buffer.update(sigs_array)
if circle_buffer.check_init():
save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array, if send_to_module_flag:
circle_buffer.get_medians()) send_data(agregator(freq, alarm), localhost, localport)
# print(circle_buffer.get_buffer())
# print(circle_buffer.get_medians()) if save_data_flag:
# print(circle_buffer.get_alarms()) if not circle_buffer.check_init() and circle_buffer.current_column - 1 == 0:
if debug_flag: save_data(path_to_save_medians, freq, 'DateTime', 'ALARM', 'max signal', list(range(num_chs)),
single_alarm = circle_buffer.check_single_alarm(median, cur_channel) list(range(num_chs)))
print(cur_channel, single_alarm) if circle_buffer.check_init():
if single_alarm: save_data(path_to_save_medians, freq, datetime.datetime.now(), alarm, max(sigs_array), sigs_array,
data = pack_elems(elems_to_save, file_types_to_save, signal, abs_signal) circle_buffer.get_medians())
#print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?') # print(circle_buffer.get_buffer())
try: # print(circle_buffer.get_medians())
remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms) # print(circle_buffer.get_alarms())
except Exception as e: if debug_flag:
print(f"Ошибка: {e}") single_alarm = circle_buffer.check_single_alarm(median, cur_channel)
#else: print(cur_channel, single_alarm)
#print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!') if single_alarm:
data = pack_elems(elems_to_save, file_types_to_save, signal, abs_signal)
f = multi_channel.change_channel() #print('SAVE CURRENT SIGNAL SROCHNO TI MENYA SLISHISH?!?!?!?')
except Exception as e: try:
print(str(e)) remote_save_data(conn, data, module_name, freq, shared_folder, path_to_save_alarms)
print(".", end='') except Exception as e:
return f print(f"Ошибка: {e}")
#else:
#print('VSE OKI DOKI SIGNAL SOKHRANYAT NE NUZHNO!!!')
f = multi_channel.change_channel()
except Exception as e:
print(str(e))
print(".", end='')
return f

@ -1,149 +1,183 @@
import os import os
import io import io
import csv import csv
import itertools import time
import requests import itertools
import numpy as np import requests
from datetime import datetime import numpy as np
from datetime import datetime
def pack_elems(names, file_types, *elems):
if len(names) != len(file_types) or len(names) != len(elems): _telemetry_error_last_ts = 0.0
raise ValueError('Длин массивов имен и типов файлов и не совпадает с количество элементов для сохранения')
return {name: {'file_type': file_type, 'elem': elem} for name, file_type, elem in zip(names, file_types, elems)}
def pack_elems(names, file_types, *elems):
if len(names) != len(file_types) or len(names) != len(elems):
def agregator(freq, alarm): raise ValueError('Длин массивов имен и типов файлов и не совпадает с количество элементов для сохранения')
if alarm: return {name: {'file_type': file_type, 'elem': elem} for name, file_type, elem in zip(names, file_types, elems)}
amplitude = 9
else:
amplitude = 0 def agregator(freq, alarm):
if alarm:
data = {"freq": freq, amplitude = 9
"amplitude": amplitude else:
} amplitude = 0
return data
data = {"freq": freq,
"amplitude": amplitude
def send_data(data, localhost, localport, endpoint): }
""" return data
Отправка данных по POST на модуль сервер.
:param data: Данные для отправки.
:param localhost: Хост модуль сервера. def send_data(data, localhost, localport, endpoint):
:param localport: Порт модуль сервера. """
""" Отправка данных по POST на модуль сервер.
:param data: Данные для отправки.
def _post(port): :param localhost: Хост модуль сервера.
url = "http://{0}:{1}/{2}".format(localhost, port, endpoint) :param localport: Порт модуль сервера.
return requests.post(url, json=data), url """
try: def _post(port):
response, url = _post(localport) url = "http://{0}:{1}/{2}".format(localhost, port, endpoint)
if response.status_code == 200: return requests.post(url, json=data), url
print("Данные успешно отправлены и приняты!", url)
return try:
response, url = _post(localport)
# Частый кейс: порт 5000 занят локальным registry (DroneDetectPCSoft). if response.status_code == 200:
# Пробуем порт модуля сервера из env (например, 5010). print("Данные успешно отправлены и приняты!", url)
fallback_port = os.getenv('GENERAL_SERVER_PORT') return
if response.status_code == 404 and fallback_port and str(localport) != str(fallback_port):
response_fb, url_fb = _post(fallback_port) # Частый кейс: порт 5000 занят локальным registry (DroneDetectPCSoft).
if response_fb.status_code == 200: # Пробуем порт модуля сервера из env (например, 5010).
#print("Данные успешно отправлены и приняты!", url_fb) fallback_port = os.getenv('GENERAL_SERVER_PORT')
return if response.status_code == 404 and fallback_port and str(localport) != str(fallback_port):
print("Ошибка при отправке данных:", response_fb.status_code, url_fb) response_fb, url_fb = _post(fallback_port)
return if response_fb.status_code == 200:
return
print("Ошибка при отправке данных:", response.status_code, url) print("Ошибка при отправке данных:", response_fb.status_code, url_fb)
except Exception as e: return
print(str(e))
print("Ошибка при отправке данных:", response.status_code, url)
except Exception as e:
def save_data(path_to_save, freq, *args): print(str(e))
"""
Сохранение данных в csv файл. Используется для сохранения метрик и медиан сигнала на каналах с датой и временем
- для анализа. def send_telemetry(data, host, port, endpoint='telemetry', timeout_sec=0.30):
:param path_to_save: Путь для сохранения. """
:param freq: Обрабатываемая частота. Best-effort отправка телеметрии на отдельный telemetry-server.
:param args: Что сохраняем в файл. Ошибки намеренно не пробрасываются, чтобы не влиять на основной детект/аларм поток.
""" """
global _telemetry_error_last_ts
try:
if not os.path.exists(path_to_save): host = '' if host is None else str(host).strip()
print('Folder was created.') port = '' if port is None else str(port).strip()
os.makedirs(path_to_save) endpoint = str(endpoint or 'telemetry').strip().lstrip('/')
with open(path_to_save + 'data_' + str(freq) + '.csv', 'a', newline='') as f: if not host or not port:
writer = csv.writer(f) return
args2 = itertools.chain(*(arg if isinstance(arg, list) else [arg] for arg in args))
writer.writerow(args2) try:
print('Write csv.') url = f"http://{host}:{port}/{endpoint}"
response = requests.post(url, json=data, timeout=float(timeout_sec))
except Exception as e: if response.status_code == 200:
print(str(e)) return
now = time.time()
def prepare_folders_paths(path): if now - _telemetry_error_last_ts >= 10.0:
folders = path.split('/') print(f"telemetry http error: {response.status_code} {url}")
folders.pop() _telemetry_error_last_ts = now
folders = [elem + '/' for elem in folders] except Exception as exc:
print(folders) now = time.time()
cur_path = '' if now - _telemetry_error_last_ts >= 10.0:
print(cur_path) print(f"telemetry send failed: {exc}")
return folders, cur_path _telemetry_error_last_ts = now
def remote_save_data(conn, data, module_name, freq, share_folder, path_to_save): def save_data(path_to_save, freq, *args):
""" """
Сохранение данных (сигнала) в файл на удаленный диск. Сохранение данных в csv файл. Используется для сохранения метрик и медиан сигнала на каналах с датой и временем
:param conn: - для анализа.
:param data: :param path_to_save: Путь для сохранения.
:param module_name: :param freq: Обрабатываемая частота.
:param freq: :param args: Что сохраняем в файл.
:param share_folder: """
:param path_to_save:
:return: try:
""" if not os.path.exists(path_to_save):
# cur_datetime = datetime.now().strftime('%d_%m_%Y_%H_%M_%S') print('Folder was created.')
# file_name = f'alarm_{module_name}_{freq}_{cur_datetime}.npy' os.makedirs(path_to_save)
# path = f"{path_to_save_medians}{module_name}/{str(freq)}/"
# path_to_file = f"{path}{file_name}" with open(path_to_save + 'data_' + str(freq) + '.csv', 'a', newline='') as f:
# print(path_to_file) writer = csv.writer(f)
# args2 = itertools.chain(*(arg if isinstance(arg, list) else [arg] for arg in args))
# folders, cur_path = prepare_folders_paths(path) writer.writerow(args2)
# print('Write csv.')
# buffer = io.BytesIO()
# np.save(buffer, data) except Exception as e:
# buffer.seek(0) print(str(e))
#
# for i in range(len(folders)):
# cur_path = cur_path + folders[i] def prepare_folders_paths(path):
# try: folders = path.split('/')
# conn.listPath(share_folder, cur_path) folders.pop()
# except Exception: folders = [elem + '/' for elem in folders]
# conn.createDirectory(share_folder, cur_path) print(folders)
# cur_path = ''
# conn.storeFile(share_folder, path_to_file, buffer) print(cur_path)
for name, values in data.items(): return folders, cur_path
elem_name = name
file_type = values['file_type']
elem_data = values['elem'] def remote_save_data(conn, data, module_name, freq, share_folder, path_to_save):
print(elem_data.shape) """
buffer = io.BytesIO() Сохранение данных (сигнала) в файл на удаленный диск.
np.save(buffer, elem_data) :param conn:
buffer.seek(0) :param data:
:param module_name:
cur_datetime = datetime.now().strftime('%d_%m_%Y_%H_%M_%S') :param freq:
file_name = f'alarm_{elem_name}_{module_name}_{freq}_{cur_datetime}.{file_type}' :param share_folder:
path = f"{path_to_save}{module_name}/{str(freq)}/{elem_name}/" :param path_to_save:
path_to_file = f"{path}{file_name}" :return:
folders, cur_path = prepare_folders_paths(path) """
# cur_datetime = datetime.now().strftime('%d_%m_%Y_%H_%M_%S')
for i in range(len(folders)): # file_name = f'alarm_{module_name}_{freq}_{cur_datetime}.npy'
cur_path = cur_path + folders[i] # path = f"{path_to_save_medians}{module_name}/{str(freq)}/"
try: # path_to_file = f"{path}{file_name}"
conn.listPath(share_folder, cur_path) # print(path_to_file)
except Exception: #
conn.createDirectory(share_folder, cur_path) # folders, cur_path = prepare_folders_paths(path)
#
conn.storeFile(share_folder, path_to_file, buffer) # buffer = io.BytesIO()
# np.save(buffer, data)
# buffer.seek(0)
#
# for i in range(len(folders)):
# cur_path = cur_path + folders[i]
# try:
# conn.listPath(share_folder, cur_path)
# except Exception:
# conn.createDirectory(share_folder, cur_path)
#
# conn.storeFile(share_folder, path_to_file, buffer)
for name, values in data.items():
elem_name = name
file_type = values['file_type']
elem_data = values['elem']
print(elem_data.shape)
buffer = io.BytesIO()
np.save(buffer, elem_data)
buffer.seek(0)
cur_datetime = datetime.now().strftime('%d_%m_%Y_%H_%M_%S')
file_name = f'alarm_{elem_name}_{module_name}_{freq}_{cur_datetime}.{file_type}'
path = f"{path_to_save}{module_name}/{str(freq)}/{elem_name}/"
path_to_file = f"{path}{file_name}"
folders, cur_path = prepare_folders_paths(path)
for i in range(len(folders)):
cur_path = cur_path + folders[i]
try:
conn.listPath(share_folder, cur_path)
except Exception:
conn.createDirectory(share_folder, cur_path)
conn.storeFile(share_folder, path_to_file, buffer)

@ -0,0 +1,47 @@
import os
import time
from pathlib import Path
_DEFAULT_FLAG_PATH = Path(__file__).resolve().parents[2] / "runtime" / "jammer_active.flag"
_FLAG_PATH = Path(os.getenv("JAMMER_STATE_FILE", str(_DEFAULT_FLAG_PATH)))
_CACHE_TTL_SEC = float(os.getenv("JAMMER_STATE_CACHE_TTL_SEC", "0.25"))
_STALE_SEC = float(os.getenv("JAMMER_STATE_STALE_SEC", "5.0"))
_cached_value = False
_cached_checked_monotonic = 0.0
def _read_uncached() -> bool:
try:
stat = _FLAG_PATH.stat()
if time.time() - stat.st_mtime > _STALE_SEC:
return False
return _FLAG_PATH.read_text(encoding="ascii").strip() == "1"
except OSError:
return False
def is_jammer_active() -> bool:
global _cached_value
global _cached_checked_monotonic
now = time.monotonic()
if now - _cached_checked_monotonic < _CACHE_TTL_SEC:
return _cached_value
_cached_value = _read_uncached()
_cached_checked_monotonic = now
return _cached_value
def set_jammer_active(active: bool) -> None:
global _cached_value
global _cached_checked_monotonic
_FLAG_PATH.parent.mkdir(parents=True, exist_ok=True)
tmp_path = _FLAG_PATH.with_name(f"{_FLAG_PATH.name}.{os.getpid()}.tmp")
tmp_path.write_text("1" if active else "0", encoding="ascii")
os.replace(tmp_path, _FLAG_PATH)
_cached_value = bool(active)
_cached_checked_monotonic = time.monotonic()

@ -0,0 +1 @@
# telemetry package

@ -0,0 +1,465 @@
import asyncio
import os
import time
from collections import defaultdict, deque
from typing import Any, Deque, Dict, List, Optional
from fastapi import FastAPI, Query, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from pydantic import BaseModel, Field
from common.runtime import load_root_env
load_root_env(__file__)
TELEMETRY_BIND_HOST = os.getenv('telemetry_bind_host', os.getenv('lochost', '0.0.0.0'))
TELEMETRY_BIND_PORT = int(os.getenv('telemetry_bind_port', os.getenv('telemetry_port', '5020')))
TELEMETRY_HISTORY_SEC = int(float(os.getenv('telemetry_history_sec', '900')))
TELEMETRY_MAX_POINTS_PER_FREQ = int(os.getenv('telemetry_max_points_per_freq', '5000'))
def _new_buffer() -> Deque[Dict[str, Any]]:
return deque(maxlen=TELEMETRY_MAX_POINTS_PER_FREQ)
app = FastAPI(title='DroneDetector Telemetry Server')
_buffers: Dict[str, Deque[Dict[str, Any]]] = defaultdict(_new_buffer)
_ws_clients: List[WebSocket] = []
_state_lock = asyncio.Lock()
class TelemetryPoint(BaseModel):
freq: str
ts: float = Field(default_factory=lambda: time.time())
dbfs_current: float
dbfs_threshold: Optional[float] = None
alarm: bool = False
channel_idx: int = 0
channels_total: int = 1
channel_values: Optional[List[float]] = None
channel_thresholds: Optional[List[Optional[float]]] = None
alarm_channels: Optional[List[int]] = None
def _prune_freq_locked(freq: str, now_ts: float) -> None:
cutoff = now_ts - TELEMETRY_HISTORY_SEC
buf = _buffers[freq]
while buf and float(buf[0].get('ts', 0.0)) < cutoff:
buf.popleft()
def _copy_series_locked(seconds: int, freq: Optional[str] = None) -> Dict[str, List[Dict[str, Any]]]:
now_ts = time.time()
cutoff = now_ts - seconds
if freq is not None:
data = [point for point in _buffers.get(freq, []) if float(point.get('ts', 0.0)) >= cutoff]
return {freq: data}
series: Dict[str, List[Dict[str, Any]]] = {}
for key, buf in _buffers.items():
series[key] = [point for point in buf if float(point.get('ts', 0.0)) >= cutoff]
return series
async def _broadcast(message: Dict[str, Any]) -> None:
dead: List[WebSocket] = []
for ws in list(_ws_clients):
try:
await ws.send_json(message)
except Exception:
dead.append(ws)
if dead:
async with _state_lock:
for ws in dead:
if ws in _ws_clients:
_ws_clients.remove(ws)
@app.post('/telemetry')
async def ingest_telemetry(point: TelemetryPoint):
payload = point.model_dump()
freq = str(payload['freq'])
now_ts = time.time()
async with _state_lock:
_buffers[freq].append(payload)
_prune_freq_locked(freq, now_ts)
await _broadcast({'type': 'point', 'data': payload})
return {'ok': True}
@app.get('/telemetry/history')
async def telemetry_history(
freq: Optional[str] = Query(default=None),
seconds: int = Query(default=300, ge=10, le=86400),
):
seconds = min(seconds, TELEMETRY_HISTORY_SEC)
async with _state_lock:
series = _copy_series_locked(seconds=seconds, freq=freq)
return {'seconds': seconds, 'series': series}
@app.websocket('/telemetry/ws')
async def telemetry_ws(websocket: WebSocket):
await websocket.accept()
async with _state_lock:
_ws_clients.append(websocket)
snapshot = _copy_series_locked(seconds=min(300, TELEMETRY_HISTORY_SEC), freq=None)
await websocket.send_json({'type': 'snapshot', 'data': snapshot})
try:
while True:
# Keepalive channel from browser; content is ignored.
await websocket.receive_text()
except WebSocketDisconnect:
pass
finally:
async with _state_lock:
if websocket in _ws_clients:
_ws_clients.remove(websocket)
MONITOR_HTML = """
<!doctype html>
<html>
<head>
<meta charset=\"utf-8\" />
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />
<title>DroneDetector Telemetry</title>
<script src=\"https://cdn.plot.ly/plotly-2.35.2.min.js\"></script>
<style>
:root {
--bg: #f6f8fb;
--card: #ffffff;
--line: #d9dde5;
--text: #1c232e;
--green: #12b76a;
--red: #ef4444;
--muted: #5b6574;
}
body { margin: 0; background: var(--bg); color: var(--text); font-family: system-ui, -apple-system, Segoe UI, sans-serif; }
.wrap { max-width: 1800px; margin: 0 auto; padding: 14px; }
.head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.meta { font-size: 13px; color: var(--muted); }
.grid { display: flex; flex-direction: column; gap: 10px; }
.card { width: 100%; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 8px 8px 8px; }
.title-row { display: flex; justify-content: space-between; align-items: center; margin: 4px 8px; }
.title { font-size: 20px; font-weight: 700; }
.ctrl { display: flex; align-items: center; gap: 6px; }
.ctrl label { font-size: 12px; color: var(--muted); }
.ctrl select { border: 1px solid var(--line); border-radius: 6px; padding: 2px 6px; }
.plot { height: 260px; width: 100%; }
.events-title { font-size: 12px; color: var(--muted); margin: 2px 8px 4px; }
.events { max-height: 110px; overflow-y: auto; border-top: 1px dashed var(--line); margin: 0 8px; padding-top: 4px; }
.ev { display: flex; justify-content: space-between; font-size: 12px; line-height: 1.4; color: var(--text); }
.ev-t { color: var(--muted); }
.ev-empty { color: var(--muted); font-size: 12px; }
</style>
</head>
<body>
<div class=\"wrap\">
<div class=\"head\">
<div>
<h2 style=\"margin:0;\">DroneDetector Telemetry Monitor</h2>
<div class=\"meta\">Green: dBFS current, Red: channel threshold, Red dots: alarm points</div>
</div>
<div class=\"meta\" id=\"status\">connecting...</div>
</div>
<div class=\"grid\" id=\"plots\"></div>
</div>
<script>
const windowSec = 300;
const state = {}; // freq -> points[]
const selectedChannel = {}; // freq -> 'max' | channel index as string
function numericSortFreq(a, b) {
return Number(a) - Number(b);
}
function formatTime(ts) {
return new Date(Number(ts) * 1000).toLocaleTimeString('ru-RU', {hour12: false});
}
function getChannelCount(freq) {
const pts = state[freq] || [];
let maxCount = 1;
for (const p of pts) {
if (Number.isFinite(Number(p.channels_total))) {
maxCount = Math.max(maxCount, Number(p.channels_total));
}
if (Array.isArray(p.channel_values)) {
maxCount = Math.max(maxCount, p.channel_values.length);
}
}
return maxCount;
}
function ensurePlot(freq) {
if (document.getElementById(`plot-${freq}`)) return;
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<div class=\"title-row\">
<div class=\"title\">${freq} MHz</div>
<div class=\"ctrl\">
<label for=\"chan-${freq}\">channel</label>
<select id=\"chan-${freq}\"></select>
</div>
</div>
<div class=\"plot\" id=\"plot-${freq}\"></div>
<div class=\"events-title\">Alarms (time -> channel)</div>
<div class=\"events\" id=\"events-${freq}\"></div>
`;
document.getElementById('plots').appendChild(card);
selectedChannel[freq] = 'max';
const sel = document.getElementById(`chan-${freq}`);
sel.addEventListener('change', () => {
selectedChannel[freq] = sel.value;
render(freq);
});
}
function updateChannelSelector(freq) {
const sel = document.getElementById(`chan-${freq}`);
if (!sel) return;
const prev = selectedChannel[freq] ?? 'max';
const count = getChannelCount(freq);
const opts = ['max'];
for (let i = 0; i < count; i += 1) opts.push(String(i));
sel.innerHTML = '';
for (const v of opts) {
const option = document.createElement('option');
option.value = v;
option.textContent = v === 'max' ? 'max' : `ch ${v}`;
sel.appendChild(option);
}
selectedChannel[freq] = opts.includes(prev) ? prev : 'max';
sel.value = selectedChannel[freq];
}
function trimPoints(freq) {
const arr = state[freq] || [];
const cutoff = Date.now() / 1000 - windowSec;
state[freq] = arr.filter(p => Number(p.ts) >= cutoff);
}
function getPointValueForSelection(point, selection) {
if (selection === 'max') {
return {
y: point.dbfs_current ?? null,
threshold: point.dbfs_threshold ?? null,
};
}
const idx = Number(selection);
if (!Number.isInteger(idx)) {
return {y: null, threshold: null};
}
const y = Array.isArray(point.channel_values) && idx < point.channel_values.length
? point.channel_values[idx]
: null;
const threshold = Array.isArray(point.channel_thresholds) && idx < point.channel_thresholds.length
? point.channel_thresholds[idx]
: null;
return {y, threshold};
}
function isAlarmForSelection(point, selection) {
if (point.alarm !== true) return false;
if (selection === 'max') return true;
const idx = Number(selection);
if (!Number.isInteger(idx)) return false;
if (Array.isArray(point.alarm_channels) && point.alarm_channels.length > 0) {
return point.alarm_channels.includes(idx);
}
return Number(point.channel_idx) === idx;
}
function renderAlarmEvents(freq, pts) {
const el = document.getElementById(`events-${freq}`);
if (!el) return;
const alarmPts = pts.filter(p => p.alarm === true);
if (alarmPts.length === 0) {
el.innerHTML = '<div class=\"ev-empty\">no alarms</div>';
return;
}
const rows = alarmPts.slice(-20).reverse().map((p) => {
const channels = Array.isArray(p.alarm_channels) && p.alarm_channels.length > 0
? p.alarm_channels.join(',')
: String(p.channel_idx ?? '-');
return `<div class=\"ev\"><span class=\"ev-t\">${formatTime(p.ts)}</span><span>ch ${channels}</span></div>`;
});
el.innerHTML = rows.join('');
}
function render(freq) {
ensurePlot(freq);
trimPoints(freq);
updateChannelSelector(freq);
const pts = state[freq] || [];
const sel = selectedChannel[freq] ?? 'max';
const x = [];
const y = [];
const thr = [];
const alarmX = [];
const alarmY = [];
for (const p of pts) {
const metric = getPointValueForSelection(p, sel);
if (metric.y === null || metric.y === undefined) {
continue;
}
const ts = new Date(Number(p.ts) * 1000);
x.push(ts);
y.push(metric.y);
thr.push(metric.threshold);
if (isAlarmForSelection(p, sel)) {
alarmX.push(ts);
alarmY.push(metric.y);
}
}
const labelSuffix = sel === 'max' ? 'max' : `ch ${sel}`;
const traces = [
{
x,
y,
mode: 'lines',
name: `dBFS (${labelSuffix})`,
line: {color: '#12b76a', width: 2},
},
{
x,
y: thr,
mode: 'lines',
name: `Threshold (${labelSuffix})`,
line: {color: '#ef4444', width: 2, dash: 'dash'},
},
{
x: alarmX,
y: alarmY,
mode: 'markers',
name: 'Alarm',
marker: {color: '#ef4444', size: 6, symbol: 'circle'},
},
];
Plotly.react(`plot-${freq}`, traces, {
margin: {l: 40, r: 12, t: 12, b: 32},
showlegend: true,
legend: {orientation: 'h', y: 1.16},
xaxis: {
title: 'time',
tickformat: '%H:%M:%S',
hoverformat: '%H:%M:%S',
range: [new Date(Date.now() - windowSec * 1000), new Date()],
},
yaxis: {title: 'dBFS'},
}, {displayModeBar: false, responsive: true});
renderAlarmEvents(freq, pts);
}
function renderAll() {
const freqs = Object.keys(state).sort(numericSortFreq);
freqs.forEach(render);
}
async function loadInitial() {
const res = await fetch(`/telemetry/history?seconds=${windowSec}`);
const payload = await res.json();
const series = payload.series || {};
for (const [freq, points] of Object.entries(series)) {
state[freq] = points;
}
renderAll();
}
function connectWs() {
const proto = location.protocol === 'https:' ? 'wss' : 'ws';
const ws = new WebSocket(`${proto}://${location.host}/telemetry/ws`);
ws.onopen = () => {
document.getElementById('status').textContent = 'ws connected';
setInterval(() => {
if (ws.readyState === 1) ws.send('ping');
}, 20000);
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'snapshot' && msg.data) {
for (const [freq, points] of Object.entries(msg.data)) {
state[freq] = points;
}
renderAll();
return;
}
if (msg.type !== 'point') return;
const p = msg.data;
const freq = String(p.freq);
if (!state[freq]) state[freq] = [];
state[freq].push(p);
render(freq);
};
ws.onclose = () => {
document.getElementById('status').textContent = 'ws disconnected, retrying...';
setTimeout(connectWs, 1500);
};
ws.onerror = () => {
document.getElementById('status').textContent = 'ws error';
};
}
setInterval(() => {
renderAll();
}, 1000);
loadInitial().then(connectWs).catch((e) => {
document.getElementById('status').textContent = `init error: ${e}`;
connectWs();
});
</script>
</body>
</html>
"""
@app.get('/', response_class=HTMLResponse)
@app.get('/monitor', response_class=HTMLResponse)
async def monitor_page():
return HTMLResponse(content=MONITOR_HTML)
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host=TELEMETRY_BIND_HOST, port=TELEMETRY_BIND_PORT)
Loading…
Cancel
Save