- changes for last day
This commit is contained in:
parent
61cecc52dd
commit
9d2ba8c998
|
|
@ -4,14 +4,6 @@
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
|
||||||
"name": "Example: answerer",
|
|
||||||
"type": "python",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "example_answer.py",
|
|
||||||
"console": "integratedTerminal",
|
|
||||||
"args": [""]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "rabbitmq: utils_mcon",
|
"name": "rabbitmq: utils_mcon",
|
||||||
"type": "python",
|
"type": "python",
|
||||||
|
|
|
||||||
101
src/agent_gsm.py
101
src/agent_gsm.py
|
|
@ -1,15 +1,11 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import json
|
|
||||||
import subprocess
|
|
||||||
import time
|
import time
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import shlex
|
|
||||||
import select
|
|
||||||
import uuid
|
import uuid
|
||||||
|
import json
|
||||||
import utils_qualtest
|
import utils_qualtest
|
||||||
import utils_sevana
|
import utils_sevana
|
||||||
import utils_mcon
|
import utils_mcon
|
||||||
|
|
@ -18,17 +14,13 @@ import utils
|
||||||
import utils_cache
|
import utils_cache
|
||||||
|
|
||||||
from bt_controller import Bluetoothctl
|
from bt_controller import Bluetoothctl
|
||||||
import bt_call_controller
|
|
||||||
import bt_signal
|
import bt_signal
|
||||||
from bt_signal import SignalBoundaries
|
from bt_signal import SignalBoundaries
|
||||||
|
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import shutil
|
|
||||||
import signal
|
import signal
|
||||||
import yaml
|
import yaml
|
||||||
import pathlib
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
# Name of intermediary file with audio recorded from the GSM phone
|
# Name of intermediary file with audio recorded from the GSM phone
|
||||||
RECORD_FILE = "/dev/shm/qualtest_recorded.wav"
|
RECORD_FILE = "/dev/shm/qualtest_recorded.wav"
|
||||||
|
|
@ -109,10 +101,43 @@ def detect_degraded_signal(file_test: Path, file_reference: Path) -> SignalBound
|
||||||
def detect_reference_signal(file_reference: Path) -> SignalBoundaries:
|
def detect_reference_signal(file_reference: Path) -> SignalBoundaries:
|
||||||
# Run silence eraser on reference file as well
|
# Run silence eraser on reference file as well
|
||||||
result = bt_signal.find_reference_signal(file_reference)
|
result = bt_signal.find_reference_signal(file_reference)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def upload_results():
|
||||||
|
probe_list = CACHE.get_probe_list()
|
||||||
|
for t in probe_list:
|
||||||
|
# Path to .json report
|
||||||
|
path_report = t[0]
|
||||||
|
|
||||||
|
# Path to audio
|
||||||
|
path_audio = t[1]
|
||||||
|
|
||||||
|
with open(path_report, 'rt') as f:
|
||||||
|
report = json.loads(f.read())
|
||||||
|
|
||||||
|
upload_id, success = BackendServer.upload_report(report, cache=None)
|
||||||
|
if success:
|
||||||
|
utils.log(f'Report {upload_id} is uploaded ok.')
|
||||||
|
|
||||||
|
# Rename files to make sync audio filename with reported ones
|
||||||
|
path_report_fixed = CACHE.dir / f'{upload_id}.json'
|
||||||
|
path_report = path_report.rename(path_report_fixed)
|
||||||
|
|
||||||
|
path_audio_fixed = CACHE.dir / f'{upload_id}.wav'
|
||||||
|
path_audio = path_audio.rename(path_audio_fixed)
|
||||||
|
|
||||||
|
# Upload recorded audio
|
||||||
|
upload_result = BackendServer.upload_audio(upload_id, path_audio)
|
||||||
|
if upload_result:
|
||||||
|
utils.log('Recorded audio {upload_id}.wav is uploaded ok.')
|
||||||
|
os.remove(path_report)
|
||||||
|
os.remove(path_audio)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
def run_analyze(file_test: str, file_reference: str, number: str) -> bool:
|
def run_analyze(file_test: str, file_reference: str, number: str) -> bool:
|
||||||
global CALL_COUNTER
|
global CALL_COUNTER
|
||||||
|
|
||||||
|
|
@ -183,8 +208,8 @@ def run_analyze(file_test: str, file_reference: str, number: str) -> bool:
|
||||||
r['task_name'] = CURRENT_TASK
|
r['task_name'] = CURRENT_TASK
|
||||||
|
|
||||||
# Upload report
|
# Upload report
|
||||||
upload_id, success = BackendServer.upload_report(r)
|
upload_id, success = BackendServer.upload_report(r, cache=CACHE)
|
||||||
if upload_id != None and success:
|
if success:
|
||||||
utils.log('Report is uploaded ok.')
|
utils.log('Report is uploaded ok.')
|
||||||
|
|
||||||
# Upload recorded audio
|
# Upload recorded audio
|
||||||
|
|
@ -195,8 +220,9 @@ def run_analyze(file_test: str, file_reference: str, number: str) -> bool:
|
||||||
result = True
|
result = True
|
||||||
else:
|
else:
|
||||||
utils.log_error('Recorded audio is not uploaded.')
|
utils.log_error('Recorded audio is not uploaded.')
|
||||||
|
CACHE.add_recorded_audio(file_test, probe_id=upload_id)
|
||||||
else:
|
else:
|
||||||
utils.log_error('Failed to upload report.')
|
CACHE.add_recorded_audio(file_test, probe_id=upload_id)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.log_error(e)
|
utils.log_error(e)
|
||||||
|
|
@ -276,9 +302,17 @@ def run_caller_task(t):
|
||||||
if LOADED_AUDIO.exists():
|
if LOADED_AUDIO.exists():
|
||||||
os.remove(LOADED_AUDIO)
|
os.remove(LOADED_AUDIO)
|
||||||
|
|
||||||
if not BackendServer.load_audio(t["audio_id"], LOADED_AUDIO):
|
audio_id = t["audio_id"]
|
||||||
utils.log_error('No audio is available, exiting.')
|
if not BackendServer.load_audio(audio_id, LOADED_AUDIO):
|
||||||
sys.exit(EXIT_ERROR)
|
utils.log_error(f'Failed to load reference audio with ID {audio_id}.')
|
||||||
|
if CACHE.get_reference_audio(audio_id, LOADED_AUDIO):
|
||||||
|
utils.log(f' Found in cache.')
|
||||||
|
else:
|
||||||
|
utils.log(f' Failed to find the audio in cache.')
|
||||||
|
raise RuntimeError(f'Reference audio (ID: {audio_id}) is not available.')
|
||||||
|
else:
|
||||||
|
# Cache loaded audio
|
||||||
|
CACHE.add_reference_audio(audio_id, LOADED_AUDIO)
|
||||||
|
|
||||||
# Use loaded audio as reference
|
# Use loaded audio as reference
|
||||||
REFERENCE_AUDIO = str(LOADED_AUDIO)
|
REFERENCE_AUDIO = str(LOADED_AUDIO)
|
||||||
|
|
@ -310,19 +344,25 @@ def run_probe():
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Get task list update
|
# Get task list update
|
||||||
tasks = BackendServer.load_tasks()
|
new_tasks = BackendServer.load_tasks()
|
||||||
if tasks is None:
|
if new_tasks is None:
|
||||||
# Check in cache
|
# Check in cache
|
||||||
tasks = CACHE.get_tasks(BackendServer.phone.name)
|
utils.log('Checking for task list in cache...')
|
||||||
|
new_tasks = CACHE.get_tasks(BackendServer.phone.name)
|
||||||
|
|
||||||
# Did we fetch anything ?
|
# Did we fetch anything ?
|
||||||
if tasks:
|
if new_tasks:
|
||||||
|
utils.log(f' Task list found in cache.')
|
||||||
# Merge with existing ones. Some tasks can be removed, some can be add.
|
# Merge with existing ones. Some tasks can be removed, some can be add.
|
||||||
changed = TASK_LIST.merge_with(tasks)
|
changed = TASK_LIST.merge_with(incoming_tasklist = new_tasks)
|
||||||
CACHE.put_tasks(changed)
|
CACHE.put_tasks(name=BackendServer.phone.name, tasks=TASK_LIST)
|
||||||
else:
|
else:
|
||||||
utils.log_verbose(f"No task list assigned, exiting.")
|
utils.log(' Task isn\'t found in cache.')
|
||||||
sys.exit(EXIT_ERROR)
|
raise RuntimeError(f'No task list found, exiting.')
|
||||||
|
|
||||||
|
if len(TASK_LIST.tasks) == 0:
|
||||||
|
utils.log(f'Task list is empty, exiting from running loop')
|
||||||
|
return
|
||||||
|
|
||||||
# Sort tasks by triggering time
|
# Sort tasks by triggering time
|
||||||
TASK_LIST.schedule()
|
TASK_LIST.schedule()
|
||||||
|
|
@ -450,7 +490,7 @@ if 'bluetooth_mac' in config['audio']:
|
||||||
utils.verbose_logging = config['log']['verbose']
|
utils.verbose_logging = config['log']['verbose']
|
||||||
|
|
||||||
if config['log']['path']:
|
if config['log']['path']:
|
||||||
utils.open_log_file(config['log']['path'], 'wt')
|
utils.open_log_file(config['log']['path'], 'at')
|
||||||
|
|
||||||
# Use native ALSA utilities on RPi
|
# Use native ALSA utilities on RPi
|
||||||
if utils.is_raspberrypi():
|
if utils.is_raspberrypi():
|
||||||
|
|
@ -462,6 +502,7 @@ if 'ALSA' in config['audio']:
|
||||||
utils_mcon.USE_ALSA_AUDIO = True
|
utils_mcon.USE_ALSA_AUDIO = True
|
||||||
|
|
||||||
|
|
||||||
|
if 'adb' in config['log']:
|
||||||
if config['log']['adb']:
|
if config['log']['adb']:
|
||||||
utils_mcon.VERBOSE_ADB = True
|
utils_mcon.VERBOSE_ADB = True
|
||||||
utils.log('Enabled adb logcat output')
|
utils.log('Enabled adb logcat output')
|
||||||
|
|
@ -470,14 +511,13 @@ if config['log']['adb']:
|
||||||
if 'cache_dir' in config:
|
if 'cache_dir' in config:
|
||||||
DIR_CACHE = Path(config['cache_dir'])
|
DIR_CACHE = Path(config['cache_dir'])
|
||||||
if not DIR_CACHE.is_absolute():
|
if not DIR_CACHE.is_absolute():
|
||||||
DIR_CACHE = DIR_THIS / config['cache_dir']
|
DIR_CACHE = DIR_THIS.parent / config['cache_dir']
|
||||||
|
|
||||||
CACHE = utils_cache.InfoCache(dir=DIR_CACHE)
|
CACHE = utils_cache.InfoCache(dir=DIR_CACHE)
|
||||||
|
|
||||||
|
|
||||||
# Update path to pvqa/aqua-wb
|
# Update path to pvqa/aqua-wb
|
||||||
utils_sevana.find_binaries(DIR_PROJECT / 'bin')
|
utils_sevana.find_binaries(DIR_PROJECT / 'bin')
|
||||||
utils.log('Analyzer binaries are found')
|
|
||||||
|
|
||||||
# Load latest licenses & configs - this requires utils_sevana.find_binaries() to be called before
|
# Load latest licenses & configs - this requires utils_sevana.find_binaries() to be called before
|
||||||
utils_sevana.load_config_and_licenses(config['backend'])
|
utils_sevana.load_config_and_licenses(config['backend'])
|
||||||
|
|
@ -510,11 +550,16 @@ with open(QUALTEST_PID, "w") as f:
|
||||||
try:
|
try:
|
||||||
# Load information about phone
|
# Load information about phone
|
||||||
utils.log(f'Loading information about the node {BackendServer.instance} from {BackendServer.address}')
|
utils.log(f'Loading information about the node {BackendServer.instance} from {BackendServer.address}')
|
||||||
BackendServer.preload(CACHE.dir)
|
BackendServer.preload(CACHE)
|
||||||
if BackendServer.phone is None:
|
if BackendServer.phone is None:
|
||||||
utils.log_error(f'Failed to obtain information about {BackendServer.instance}. Exiting.')
|
utils.log_error(f'Failed to obtain information about {BackendServer.instance}. Exiting.')
|
||||||
exit(EXIT_ERROR)
|
exit(EXIT_ERROR)
|
||||||
|
|
||||||
|
# Cache information
|
||||||
|
CACHE.put_phone(BackendServer.phone)
|
||||||
|
|
||||||
|
# Upload results which were remaining in cache
|
||||||
|
upload_results()
|
||||||
|
|
||||||
if 'answerer' in BackendServer.phone.role:
|
if 'answerer' in BackendServer.phone.role:
|
||||||
# Check if task name is specified
|
# Check if task name is specified
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class Phone(Observable):
|
||||||
model_serial = properties['Serial']
|
model_serial = properties['Serial']
|
||||||
modem_online = properties['Online']
|
modem_online = properties['Online']
|
||||||
|
|
||||||
print(f'Found modem: {path} name: {modem_name} serial: {model_serial} online: {modem_online}')
|
utils.log(f'Found modem: {path} name: {modem_name} serial: {model_serial} online: {modem_online}')
|
||||||
if modem_online == 1:
|
if modem_online == 1:
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ class Phone(Observable):
|
||||||
self.modems = self.manager.GetModems()
|
self.modems = self.manager.GetModems()
|
||||||
|
|
||||||
# Wait for online modem
|
# Wait for online modem
|
||||||
utils.log('Waiting for BT modem (phone must be paired and connected before)...')
|
utils.log('Waiting for BT modem (phone must be paired and connected before) with timeout 10 seconds...')
|
||||||
self.modem = self.wait_for_online_modem(timeout_seconds=10) # 10 seconds timeout
|
self.modem = self.wait_for_online_modem(timeout_seconds=10) # 10 seconds timeout
|
||||||
|
|
||||||
if self.modem is None:
|
if self.modem is None:
|
||||||
|
|
@ -151,13 +151,11 @@ class Phone(Observable):
|
||||||
|
|
||||||
|
|
||||||
def set_call_add(self, object, properties):
|
def set_call_add(self, object, properties):
|
||||||
# print('Call add')
|
|
||||||
self.notifyObservers(object, EVENT_CALL_ADD)
|
self.notifyObservers(object, EVENT_CALL_ADD)
|
||||||
self.call_in_progress = True
|
self.call_in_progress = True
|
||||||
|
|
||||||
|
|
||||||
def set_call_ended(self, object):
|
def set_call_ended(self, object):
|
||||||
# print('Call removed')
|
|
||||||
self.notifyObservers(object, EVENT_CALL_REMOVE)
|
self.notifyObservers(object, EVENT_CALL_REMOVE)
|
||||||
self.call_in_progress = False
|
self.call_in_progress = False
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import sys
|
||||||
import yaml
|
import yaml
|
||||||
import subprocess
|
import subprocess
|
||||||
import utils_bt_audio
|
import utils_bt_audio
|
||||||
|
import utils
|
||||||
from bt_controller import Bluetoothctl
|
from bt_controller import Bluetoothctl
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
@ -25,13 +26,13 @@ if __name__ == '__main__':
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
# Connect to phone
|
# Connect to phone
|
||||||
print(f'Connecting to {bt_mac} ...')
|
utils.log(f'Connecting to {bt_mac} ...')
|
||||||
bt_ctl = Bluetoothctl()
|
bt_ctl = Bluetoothctl()
|
||||||
status = bt_ctl.connect(bt_mac)
|
status = bt_ctl.connect(bt_mac)
|
||||||
if status:
|
if status:
|
||||||
print(f'Connected ok.')
|
utils.log(f' Connected ok.')
|
||||||
else:
|
else:
|
||||||
print(f'Not connected, sorry.')
|
utils.log_error(f' Not connected, sorry.')
|
||||||
else:
|
else:
|
||||||
print('BT config not found.')
|
utils.log_error('BT config not found.')
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,13 @@ def close_log_file():
|
||||||
|
|
||||||
|
|
||||||
def get_current_time_str():
|
def get_current_time_str():
|
||||||
return str(datetime.datetime.now())
|
s = str(datetime.datetime.now())
|
||||||
|
s = s[:-3]
|
||||||
|
return s
|
||||||
|
|
||||||
def get_log_line(message: str) -> str:
|
def get_log_line(message: str) -> str:
|
||||||
current_time = get_current_time_str()
|
|
||||||
pid = os.getpid()
|
pid = os.getpid()
|
||||||
line = f'{current_time} : {pid} : {message}'
|
line = f'{get_current_time_str()} : {pid} : {message}'
|
||||||
|
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,10 @@ def start_PA() -> bool:
|
||||||
utils.log('Attempt to load module-bluetooth-discover...')
|
utils.log('Attempt to load module-bluetooth-discover...')
|
||||||
retcode = os.system('pacmd load-module module-bluetooth-discover')
|
retcode = os.system('pacmd load-module module-bluetooth-discover')
|
||||||
if retcode != 0:
|
if retcode != 0:
|
||||||
utils.log(f'Failed to load module-bluetooth-discover, exit code: {retcode}')
|
utils.log_error(f' Failed to load module-bluetooth-discover, exit code: {retcode}')
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print('...success.')
|
utils.log(' Load success.')
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class InfoCache:
|
||||||
if not self.is_active():
|
if not self.is_active():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
p = self.dir / f'audio_{probe_id}.wav'
|
p = self.dir / f'{probe_id}.wav'
|
||||||
|
|
||||||
shutil.copy(src_path, p)
|
shutil.copy(src_path, p)
|
||||||
return p
|
return p
|
||||||
|
|
@ -66,6 +66,29 @@ class InfoCache:
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_uuid(self, value):
|
||||||
|
try:
|
||||||
|
uuid.UUID(str(value))
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Returns list of tuples (path_to_probe.json, path_to_audio.wav)
|
||||||
|
def get_probe_list(self) -> list[Path]:
|
||||||
|
r = []
|
||||||
|
lst = os.listdir(self.dir)
|
||||||
|
for n in lst:
|
||||||
|
p = self.dir / n
|
||||||
|
if self.is_valid_uuid(p.stem) and n.endswith('.json'):
|
||||||
|
# Probe found
|
||||||
|
p_audio = p.with_suffix('.wav')
|
||||||
|
if p_audio.exists():
|
||||||
|
r.append(p, p.with_suffix('.wav'))
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
# Caches phone information
|
||||||
def put_phone(self, phone: Phone):
|
def put_phone(self, phone: Phone):
|
||||||
if self.is_active():
|
if self.is_active():
|
||||||
with open(self.dir / f'phone_{phone.name}.json', 'wt') as f:
|
with open(self.dir / f'phone_{phone.name}.json', 'wt') as f:
|
||||||
|
|
@ -78,7 +101,7 @@ class InfoCache:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
with open(p, 'rt') as f:
|
with open(p, 'rt') as f:
|
||||||
return Phone.make(f.read())
|
return Phone.make(json.loads(f.read()))
|
||||||
|
|
||||||
def put_tasks(self, name: str, tasks: TaskList):
|
def put_tasks(self, name: str, tasks: TaskList):
|
||||||
p = self.dir / f'tasks_{name}.json'
|
p = self.dir / f'tasks_{name}.json'
|
||||||
|
|
@ -88,7 +111,13 @@ class InfoCache:
|
||||||
|
|
||||||
def get_tasks(self, name: str) -> TaskList:
|
def get_tasks(self, name: str) -> TaskList:
|
||||||
p = self.dir / f'tasks_{name}.json'
|
p = self.dir / f'tasks_{name}.json'
|
||||||
# ToDo
|
try:
|
||||||
|
with open(p, 'rt') as f:
|
||||||
|
r = TaskList()
|
||||||
|
r.tasks = json.loads(f.read())
|
||||||
|
return r
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def add_report(self, report: dict) -> str:
|
def add_report(self, report: dict) -> str:
|
||||||
|
|
|
||||||
|
|
@ -165,9 +165,9 @@ def gsm_make_call(target: str):
|
||||||
|
|
||||||
# End current GSM call
|
# End current GSM call
|
||||||
def gsm_stop_call():
|
def gsm_stop_call():
|
||||||
os.system(f"{ADB} shell input keyevent 6")
|
# os.system(f"{ADB} shell input keyevent 6")
|
||||||
utils.log_verbose('GSM call stop keyevent is sent.')
|
# utils.log_verbose('GSM call stop keyevent is sent.')
|
||||||
|
pass
|
||||||
|
|
||||||
def gsm_send_digit(digit: str):
|
def gsm_send_digit(digit: str):
|
||||||
os.system(f"{ADB} shell input KEYCODE_{digit}")
|
os.system(f"{ADB} shell input KEYCODE_{digit}")
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ class QualtestBackend:
|
||||||
return self.__phone
|
return self.__phone
|
||||||
|
|
||||||
|
|
||||||
def preload(self, cache_dir: Path):
|
def preload(self, cache: InfoCache):
|
||||||
self.__phone = self.load_phone(cache_dir)
|
self.__phone = self.load_phone(cache)
|
||||||
|
|
||||||
|
|
||||||
def upload_report(self, report, cache: InfoCache) -> (str, bool):
|
def upload_report(self, report, cache: InfoCache) -> (str, bool):
|
||||||
|
|
@ -78,15 +78,18 @@ class QualtestBackend:
|
||||||
r = requests.post(url=url, json=report, timeout=utils.NETWORK_TIMEOUT)
|
r = requests.post(url=url, json=report, timeout=utils.NETWORK_TIMEOUT)
|
||||||
utils.log_verbose(f"Upload report finished. Response (probe ID): {r.content}")
|
utils.log_verbose(f"Upload report finished. Response (probe ID): {r.content}")
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise RuntimeError(f'Server returned code {r.status_code} and content {r.content}')
|
raise RuntimeError(f'Server returned code {r.status_code}')
|
||||||
|
|
||||||
result = (r.content.decode().strip(), True)
|
result = (r.content.decode().strip(), True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.log_error(f"Upload report to {self.address} finished with error.", err=e)
|
utils.log_error(f"Upload report to {self.address} finished with error.", err=e)
|
||||||
|
|
||||||
# Backup probe result
|
# Backup probe result
|
||||||
|
if cache is not None:
|
||||||
probe_id = cache.add_report(report)
|
probe_id = cache.add_report(report)
|
||||||
|
utils.log(f' {probe_id}.json report is put to cache.')
|
||||||
result = (probe_id, False)
|
result = (probe_id, False)
|
||||||
|
else:
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
@ -128,8 +131,7 @@ class QualtestBackend:
|
||||||
# Get response from server
|
# Get response from server
|
||||||
response = urllib.request.urlopen(url, timeout=utils.NETWORK_TIMEOUT)
|
response = urllib.request.urlopen(url, timeout=utils.NETWORK_TIMEOUT)
|
||||||
if response.getcode() != 200:
|
if response.getcode() != 200:
|
||||||
utils.log_error("Failed to get task list. Error code: %s" % response.getcode())
|
raise RuntimeError(f'Failed to get task list. Error code: {response.getcode()}')
|
||||||
return None
|
|
||||||
|
|
||||||
result = TaskList()
|
result = TaskList()
|
||||||
response_content = response.read().decode()
|
response_content = response.read().decode()
|
||||||
|
|
@ -137,7 +139,7 @@ class QualtestBackend:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
utils.log_error("Exception when fetching task list: {0}".format(err))
|
utils.log_error(f'Error when fetching task list from backend: {str(err)}')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -154,12 +156,13 @@ class QualtestBackend:
|
||||||
try:
|
try:
|
||||||
response = urllib.request.urlopen(url, timeout=utils.NETWORK_TIMEOUT)
|
response = urllib.request.urlopen(url, timeout=utils.NETWORK_TIMEOUT)
|
||||||
if response.getcode() != 200:
|
if response.getcode() != 200:
|
||||||
raise RuntimeError(f'Failed to load phone definition. Error code: {response.getcode()}')
|
raise RuntimeError(f'Failed to load phone definition from server. Error code: {response.getcode()}')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.log_error(f'Problem when loading the phone definition from backend. Error: {str(e)}')
|
utils.log_error(f'Problem when loading the phone definition from backend. Error: {str(e)}')
|
||||||
r = cache.get_phone(self.instance)
|
r = cache.get_phone(self.instance)
|
||||||
if r is None:
|
if r is None:
|
||||||
raise RuntimeError(f'No cached phone definition.')
|
raise RuntimeError(f'No cached phone definition.')
|
||||||
|
utils.log(f' Found phone definition in cache.')
|
||||||
return r
|
return r
|
||||||
|
|
||||||
# Get possible list of phones
|
# Get possible list of phones
|
||||||
|
|
@ -201,7 +204,7 @@ class QualtestBackend:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
utils.log_error(f"Exception when fetching task list: {str(err)}")
|
utils.log_error(f"Exception loading phone information: {str(err)}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,13 @@ def load_file(url: str, output_path: str):
|
||||||
|
|
||||||
|
|
||||||
def load_config_and_licenses(server: str):
|
def load_config_and_licenses(server: str):
|
||||||
|
# ToDo: validate licenses before. If they are ok - skip their update
|
||||||
|
try:
|
||||||
load_file(utils.join_host_and_path(server, '/deploy/pvqa.cfg'), PVQA_CFG_PATH)
|
load_file(utils.join_host_and_path(server, '/deploy/pvqa.cfg'), PVQA_CFG_PATH)
|
||||||
load_file(utils.join_host_and_path(server, '/deploy/pvqa.lic'), PVQA_LIC_PATH)
|
load_file(utils.join_host_and_path(server, '/deploy/pvqa.lic'), PVQA_LIC_PATH)
|
||||||
load_file(utils.join_host_and_path(server, '/deploy/aqua-wb.lic'), AQUA_LIC_PATH)
|
load_file(utils.join_host_and_path(server, '/deploy/aqua-wb.lic'), AQUA_LIC_PATH)
|
||||||
|
except Exception as e:
|
||||||
|
utils.log_error(f'Failed to fetch new licenses and config. Skipping it.')
|
||||||
|
|
||||||
def find_binaries(bin_directory: Path, license_server: str = None):
|
def find_binaries(bin_directory: Path, license_server: str = None):
|
||||||
# Update path to pvqa/aqua-wb
|
# Update path to pvqa/aqua-wb
|
||||||
|
|
@ -95,26 +98,26 @@ def find_binaries(bin_directory: Path, license_server: str = None):
|
||||||
SILER_PATH = bin_directory / platform_prefix / SILER_PATH
|
SILER_PATH = bin_directory / platform_prefix / SILER_PATH
|
||||||
SPEECH_DETECTOR_PATH = bin_directory / platform_prefix / SPEECH_DETECTOR_PATH
|
SPEECH_DETECTOR_PATH = bin_directory / platform_prefix / SPEECH_DETECTOR_PATH
|
||||||
|
|
||||||
print(f'Looking for binaries/licenses/configs at {bin_directory}...', end=' ')
|
utils.log(f'Looking for binaries/licenses/configs at {bin_directory}...')
|
||||||
|
|
||||||
# Check if binaries exist
|
# Check if binaries exist
|
||||||
if not PVQA_PATH.exists():
|
if not PVQA_PATH.exists():
|
||||||
print(f'Failed to find pvqa binary at {PVQA_PATH}. Exiting.')
|
utils.log_error(f'Failed to find pvqa binary at {PVQA_PATH}. Exiting.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not PVQA_CFG_PATH.exists():
|
if not PVQA_CFG_PATH.exists():
|
||||||
PVQA_CFG_PATH = Path(utils.get_script_path()) / 'pvqa.cfg'
|
PVQA_CFG_PATH = Path(utils.get_script_path()) / 'pvqa.cfg'
|
||||||
|
|
||||||
if not PVQA_CFG_PATH.exists():
|
if not PVQA_CFG_PATH.exists():
|
||||||
print(f'Failed to find pvqa config. Exiting.')
|
utils.log_error(f'Failed to find pvqa config. Exiting.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not AQUA_PATH.exists():
|
if not AQUA_PATH.exists():
|
||||||
print(f'Failed to find aqua-wb binary. Exiting.')
|
utils.log_error(f'Failed to find aqua-wb binary. Exiting.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not SILER_PATH.exists():
|
if not SILER_PATH.exists():
|
||||||
print(f'Failed to find silence_eraser binary. Exiting.')
|
utils.log_error(f'Failed to find silence_eraser binary. Exiting.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if license_server is not None:
|
if license_server is not None:
|
||||||
|
|
@ -125,16 +128,16 @@ def find_binaries(bin_directory: Path, license_server: str = None):
|
||||||
if not PVQA_LIC_PATH.exists():
|
if not PVQA_LIC_PATH.exists():
|
||||||
PVQA_LIC_PATH = Path(utils.get_script_path()) / 'pvqa.lic'
|
PVQA_LIC_PATH = Path(utils.get_script_path()) / 'pvqa.lic'
|
||||||
if not PVQA_LIC_PATH.exists():
|
if not PVQA_LIC_PATH.exists():
|
||||||
print(f'Failed to find pvqa license. Exiting.')
|
utils.log_error(f'Failed to find pvqa license. Exiting.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not AQUA_LIC_PATH.exists():
|
if not AQUA_LIC_PATH.exists():
|
||||||
AQUA_LIC_PATH = Path(utils.get_script_path()) / 'aqua-wb.lic'
|
AQUA_LIC_PATH = Path(utils.get_script_path()) / 'aqua-wb.lic'
|
||||||
if not AQUA_LIC_PATH.exists():
|
if not AQUA_LIC_PATH.exists():
|
||||||
print(f'Failed to find AQuA license. Exiting.')
|
utils.log_error(f'Failed to find AQuA license. Exiting.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print(f'Found all analyzers.')
|
utils.log(f' Found all analyzers.')
|
||||||
|
|
||||||
|
|
||||||
def speech_detector(test_path: str):
|
def speech_detector(test_path: str):
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
import utils
|
import utils
|
||||||
|
import json
|
||||||
from crontab import CronTab
|
from crontab import CronTab
|
||||||
|
|
||||||
start_system_time = time.time()
|
start_system_time = time.time()
|
||||||
|
|
@ -52,6 +52,10 @@ class Phone:
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def dump(self) -> str:
|
||||||
|
return json.dumps(self.to_dict(), indent=4)
|
||||||
|
|
||||||
|
|
||||||
class TaskList:
|
class TaskList:
|
||||||
tasks: list = []
|
tasks: list = []
|
||||||
|
|
||||||
|
|
@ -62,14 +66,14 @@ class TaskList:
|
||||||
# Merges incoming task list to existing one
|
# Merges incoming task list to existing one
|
||||||
# It preserves existing schedules
|
# It preserves existing schedules
|
||||||
# New items are NOT scheduled automatically
|
# New items are NOT scheduled automatically
|
||||||
def merge_with(self, tasklist) -> bool:
|
def merge_with(self, incoming_tasklist) -> bool:
|
||||||
changed = False
|
changed = False
|
||||||
if tasklist.tasks is None:
|
if incoming_tasklist.tasks is None:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Iterate all tasks, see if task with the same name exists already
|
# Iterate all tasks, see if task with the same name exists already
|
||||||
# Copy all keys, but keep existing ones
|
# Copy all keys, but keep existing ones
|
||||||
for new_task in tasklist.tasks:
|
for new_task in incoming_tasklist.tasks:
|
||||||
# Find if this task exists already
|
# Find if this task exists already
|
||||||
existing_task = self.find_task_by_name(new_task["name"])
|
existing_task = self.find_task_by_name(new_task["name"])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue