Add quality check for clock quality (LCQ)

This commit is contained in:
Kasper D. Fischer 2022-12-06 15:43:13 +01:00
parent d21fb0ca3b
commit cb3623e4a9
2 changed files with 51 additions and 7 deletions

View File

@ -1,10 +1,10 @@
# Parameters file for Surveillance Bot # Parameters file for Surveillance Bot
datapath: "/data/SDS/" # SC3 Datapath datapath: "/data/SDS/" # SC3 Datapath
networks: ["1Y", "HA"] networks: ["1Y", "HA"] # select networks, list or str
stations: "*" stations: "*" # select stations, list or str
locations: "*" locations: "*" # select locations, list or str
channels: ["EX1", "EX2", "EX3", "VEI"] # Specify SOH channels, currently supported EX[1-3] and VEI channels: ["EX1", "EX2", "EX3", "VEI", "LCQ"] # Specify SOH channels, currently supported EX[1-3], VEI, LCQ
channel_names: ["Temperature (°C)", "230V/12V Status (V)", "Router/Charger State (V)", "Logger Voltage (V)"] # names for plotting (optional) channel_names: ["Clock Quality (%)", "Temperature (°C)", "230V/12V Status (V)", "Router/Charger State (V)", "Logger Voltage (V)"] # names for plotting (optional)
stations_blacklist: ["TEST", "EREA"] stations_blacklist: ["TEST", "EREA"]
networks_blacklist: [] networks_blacklist: []
interval: 60 # Perform checks every x seconds interval: 60 # Perform checks every x seconds
@ -43,6 +43,8 @@ THRESHOLDS:
low_volt: 12 # min voltage for low voltage warning low_volt: 12 # min voltage for low voltage warning
high_volt: 14.8 # max voltage for over voltage warning high_volt: 14.8 # max voltage for over voltage warning
unclassified: 5 # min voltage samples not classified for warning unclassified: 5 # min voltage samples not classified for warning
clockquality_warn: 90 # clock quality ranges from 0 % to 100 % with 100 % being the best level
clockquality_fail: 70
# add links to html table with specified key as column and value as relative link, interpretable string parameters: # add links to html table with specified key as column and value as relative link, interpretable string parameters:
# nw (e.g. 1Y), st (e.g. GR01A), nwst_id (e.g. 1Y.GR01A) # nw (e.g. 1Y), st (e.g. GR01A), nwst_id (e.g. 1Y.GR01A)

View File

@ -61,7 +61,7 @@ def fancy_timestr(dt, thresh=600, modif='+'):
class SurveillanceBot(object): class SurveillanceBot(object):
def __init__(self, parameter_path, outpath_html=None): def __init__(self, parameter_path, outpath_html=None):
self.keys = ['last active', '230V', '12V', 'router', 'charger', 'voltage', 'temp', 'other'] self.keys = ['last active', '230V', '12V', 'router', 'charger', 'voltage', 'clock', 'temp', 'other']
self.parameter_path = parameter_path self.parameter_path = parameter_path
self.update_parameters() self.update_parameters()
self.starttime = UTCDateTime() self.starttime = UTCDateTime()
@ -668,6 +668,7 @@ class StationQC(object):
self.pb_temp_analysis() self.pb_temp_analysis()
self.pb_power_analysis() self.pb_power_analysis()
self.pb_rout_charge_analysis() self.pb_rout_charge_analysis()
self.clock_quality_analysis()
def return_print_analysis(self): def return_print_analysis(self):
items = [self.nwst_id] items = [self.nwst_id]
@ -696,6 +697,47 @@ class StationQC(object):
def get_last_occurrence(self, trace, indices): def get_last_occurrence(self, trace, indices):
return self.get_time(trace, indices[-1]) return self.get_time(trace, indices[-1])
def clock_quality_analysis(self, channel='LCQ'):
""" Analyse clock quality """
key = 'clock'
st = self.stream.select(channel=channel)
trace = self.get_trace(st, key)
if not trace: return
clockQuality = trace.data
clockQuality_warn_level = self.parameters.get('THRESHOLDS').get('clockquality_warn')
clockQuality_fail_level = self.parameters.get('THRESHOLDS').get('clockquality_fail')
if self.verbosity > 1:
self.print(40 * '-')
self.print('Performing Clock Quality check', flush=False)
clockQuality_warn = np.where(clockQuality < clockQuality_warn_level)[0]
clockQuality_fail = np.where(clockQuality < clockQuality_fail_level)[0]
if len(clockQuality_warn) == 0 and len(clockQuality_fail) == 0:
self.status_ok(key, detailed_message=f'ClockQuality={(clockQuality[-1])}')
return
n_qc_warn = 0
n_qc_fail = 0
warn_message = f'Trace {trace.get_id()}:'
if len(clockQuality_warn) > 0:
# try calculate number of warn peaks from gaps between indices
n_qc_warn = len(np.where(np.diff(clockQuality_warn) > 1)[0]) + 1
detailed_message = warn_message + f' {n_qc_warn}x Qlock Quality less then {clockQuality_warn_level}' \
+ self.get_last_occurrence_timestring(trace, clockQuality_warn)
self.warn(key, detailed_message=detailed_message, count=n_qc_warn,
last_occurrence=self.get_last_occurrence(trace, clockQuality_warn))
if len(clockQuality_fail) > 0:
# try calculate number of fail peaks from gaps between indices
n_qc_fail = len(np.where(np.diff(clockQuality_fail) > 1)[0]) + 1
detailed_message = warn_message + f' {n_qc_fail}x Qlock Quality less then {clockQuality_fail_level}V ' \
+ self.get_last_occurrence_timestring(trace, clockQuality_fail)
self.error(key, detailed_message=detailed_message, count=n_qc_fail,
last_occurrence=self.get_last_occurrence(trace, clockQuality_fail))
def voltage_analysis(self, channel='VEI'): def voltage_analysis(self, channel='VEI'):
""" Analyse voltage channel for over/undervoltage """ """ Analyse voltage channel for over/undervoltage """
key = 'voltage' key = 'voltage'