[update] re-read data daily, add daily overlap, add value -1 for voltage lower 1V (e.g. pbox not connected)

This commit is contained in:
Marcel Paffrath 2022-11-14 22:31:22 +01:00
parent 04371f92c5
commit cd6b40688b
3 changed files with 52 additions and 27 deletions

View File

@ -7,7 +7,7 @@ channels: ['EX1', 'EX2', 'EX3', 'VEI'] # Specify SOH channels, currently supp
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
timespan: 7 # Check data of the recent x days timespan: 3 # Check data of the recent x days
verbosity: 0 verbosity: 0
reread_parameters: True # reread parameters file (change parameters on runtime, not for itself/GUI refresh/datapath) reread_parameters: True # reread parameters file (change parameters on runtime, not for itself/GUI refresh/datapath)
track_changes: True # tracks all changes since GUI startup by text highlighting (GUI only) track_changes: True # tracks all changes since GUI startup by text highlighting (GUI only)
@ -17,6 +17,7 @@ html_figures: True # Create html figure directory and links
POWBOX: POWBOX:
pb_ok: 1 # Voltage for PowBox OK pb_ok: 1 # Voltage for PowBox OK
pb_SOH2: # PowBox channel 2 voltage translations pb_SOH2: # PowBox channel 2 voltage translations
-1: {"230V": "PBox under 1V", "12V": "PBox under 1V"}
1: {"230V": 'OK', "12V": "OK"} 1: {"230V": 'OK', "12V": "OK"}
2: {"230V": "OFF", "12V": "OK"} 2: {"230V": "OFF", "12V": "OK"}
3: {"230V": "OK", "12V": "overvoltage"} 3: {"230V": "OK", "12V": "overvoltage"}
@ -24,6 +25,7 @@ POWBOX:
4.5: {"230V": "OFF", "12V": "overvoltage"} 4.5: {"230V": "OFF", "12V": "overvoltage"}
5: {"230V": "OFF", "12V": "undervoltage"} 5: {"230V": "OFF", "12V": "undervoltage"}
pb_SOH3: # PowBox channel 3 voltage translations pb_SOH3: # PowBox channel 3 voltage translations
-1: {"router": "PBox under 1V", "charger": "PBox under 1V"}
1: {"router": "OK", "charger": "OK"} 1: {"router": "OK", "charger": "OK"}
2: {"router": "OK", "charger": "0 < resets < 3"} 2: {"router": "OK", "charger": "0 < resets < 3"}
2.5: {"router": "OK", "charger": "locked"} 2.5: {"router": "OK", "charger": "locked"}

View File

@ -6,6 +6,7 @@ ulimit -s 8192
#$ -cwd #$ -cwd
#$ -pe smp 1 #$ -pe smp 1
#$ -N survBot_bg #$ -N survBot_bg
#$ -l os=*stretch
source /opt/anaconda3/etc/profile.d/conda.sh source /opt/anaconda3/etc/profile.d/conda.sh
conda activate py37 conda activate py37
@ -15,4 +16,4 @@ export MKL_NUM_THREADS=1
export NUMEXPR_NUM_THREADS=1 export NUMEXPR_NUM_THREADS=1
export OMP_NUM_THREADS=1 export OMP_NUM_THREADS=1
python survBot.py -html '/home/marcel/public_html/' python survBot.py -html '/data/www/~marcel/'

View File

@ -57,6 +57,7 @@ class SurveillanceBot(object):
self.update_parameters() self.update_parameters()
self.starttime = UTCDateTime() self.starttime = UTCDateTime()
self.plot_hour = self.starttime.hour self.plot_hour = self.starttime.hour
self.current_day = self.starttime.julday
self.outpath_html = outpath_html self.outpath_html = outpath_html
self.filenames = [] self.filenames = []
self.filenames_read = [] self.filenames_read = []
@ -120,18 +121,35 @@ class SurveillanceBot(object):
self.filenames += list(self.cl._get_filenames(network, station, location, channel, self.filenames += list(self.cl._get_filenames(network, station, location, channel,
starttime=t1, endtime=time_now)) starttime=t1, endtime=time_now))
def read_data(self): def read_data(self, re_read_at_hour=1, daily_overlap=2):
'''
read data method reads new data into self.stream
:param re_read_at_hour: update archive at specified hour each day (hours up to 24)
:param daily_overlap: re-read data of previous day until specified hour (hours up to 24)
'''
self.data = {} self.data = {}
# re-read all data every new day
curr_time = UTCDateTime()
current_day = curr_time.julday
current_hour = curr_time.hour
yesterday = (curr_time - 24. * 3600.).julday
if re_read_at_hour is not False and current_day != self.current_day and current_hour == re_read_at_hour:
self.filenames_read = []
self.dataStream = Stream()
self.current_day = current_day
# add all data to current stream # add all data to current stream
for filename in self.filenames: for filename in self.filenames:
if filename in self.filenames_read: if filename in self.filenames_read:
continue continue
try: try:
st_new = read(filename) st_new = read(filename)
julday = UTCDateTime().julday # add file to read filenames to prevent re-reading in case it is not the current day (or end of
# add file to read filenames to prevent re-reading in case it is not the current dayfile # previous day)
if not filename.endswith(str(julday)): if not filename.endswith(f'{current_day:03}') and not (
filename.endswith(f'{yesterday:03}') and current_hour <= daily_overlap):
self.filenames_read.append(filename) self.filenames_read.append(filename)
except Exception as e: except Exception as e:
print(f'Could not read file {filename}:', e) print(f'Could not read file {filename}:', e)
@ -389,8 +407,7 @@ class StationQC(object):
def status_ok(self, key, message=None, status_message='OK'): def status_ok(self, key, message=None, status_message='OK'):
self.status_dict[key] = status_message self.status_dict[key] = status_message
if message: self.detailed_status_dict[key] = message
self.detailed_status_dict[key] = message
def warn(self, key, detailed_message, status_message='WARN'): def warn(self, key, detailed_message, status_message='WARN'):
# update detailed status if already existing # update detailed status if already existing
@ -544,13 +561,15 @@ class StationQC(object):
keys = ['230V', '12V'] keys = ['230V', '12V']
st = self.stream.select(channel=channel) st = self.stream.select(channel=channel)
trace = self.get_trace(st, keys) trace = self.get_trace(st, keys)
if not trace: return if not trace:
return
voltage = trace.data * 1e-6 voltage = trace.data * 1e-6
if self.verbosity > 1: if self.verbosity > 1:
self.print(40 * '-') self.print(40 * '-')
self.print('Performing PowBox 12V/230V check (EX2)', flush=False) self.print('Performing PowBox 12V/230V check (EX2)', flush=False)
voltage_check, voltage_dict, last_val = self.pb_voltage_ok(trace, voltage, pb_dict_key, channel=channel, voltage_check, voltage_dict, last_val = self.pb_voltage_ok(trace, voltage, pb_dict_key, channel=channel)
warn_keys=keys)
if voltage_check: if voltage_check:
for key in keys: for key in keys:
self.status_ok(key) self.status_ok(key)
@ -565,14 +584,15 @@ class StationQC(object):
pb_thresh = self.parameters.get('THRESHOLDS').get('pb_1v') pb_thresh = self.parameters.get('THRESHOLDS').get('pb_1v')
st = self.stream.select(channel=channel) st = self.stream.select(channel=channel)
trace = self.get_trace(st, keys) trace = self.get_trace(st, keys)
if not trace: return if not trace:
return
voltage = trace.data * 1e-6 voltage = trace.data * 1e-6
if self.verbosity > 1: if self.verbosity > 1:
self.print(40 * '-') self.print(40 * '-')
self.print('Performing PowBox Router/Charger check (EX3)', flush=False) self.print('Performing PowBox Router/Charger check (EX3)', flush=False)
voltage_check, voltage_dict, last_val = self.pb_voltage_ok(trace, voltage, pb_dict_key, channel=channel, voltage_check, voltage_dict, last_val = self.pb_voltage_ok(trace, voltage, pb_dict_key, channel=channel)
warn_keys=keys)
if voltage_check: if voltage_check:
for key in keys: for key in keys:
self.status_ok(key) self.status_ok(key)
@ -617,7 +637,7 @@ class StationQC(object):
return return
return trace return trace
def pb_voltage_ok(self, trace, voltage, pb_dict_key, warn_keys, channel=None): def pb_voltage_ok(self, trace, voltage, pb_dict_key, channel=None):
""" """
Checks if voltage level is ok everywhere and returns True. If it is not okay it returns a dictionary Checks if voltage level is ok everywhere and returns True. If it is not okay it returns a dictionary
with each voltage value associated to the different steps specified in POWBOX > pb_steps. Also raises with each voltage value associated to the different steps specified in POWBOX > pb_steps. Also raises
@ -634,20 +654,10 @@ class StationQC(object):
# check if voltage is over or under OK-level (1V), if not return True # check if voltage is over or under OK-level (1V), if not return True
over = np.where(voltage > pb_ok + pb_thresh)[0] over = np.where(voltage > pb_ok + pb_thresh)[0]
under = np.where(voltage < pb_ok - pb_thresh)[0] under = np.where(voltage < pb_ok - pb_thresh)[0]
if len(over) == 0 and len(under) == 0: if len(over) == 0 and len(under) == 0:
return True, {}, last_voltage return True, {}, last_voltage
# Warn in case of voltage under OK-level (1V)
if len(under) > 0:
# try calculate number of occurences from gaps between indices
n_occurrences = len(np.where(np.diff(under) > 1)[0]) + 1
self.warn(key='other',
detailed_message=f'Trace {trace.get_id()}: '
f'Voltage below {pb_ok}V in {len(under)} samples, {n_occurrences} time(s). '
f'Mean voltage: {np.mean(voltage):.2}'
+ self.get_last_occurrence_timestring(trace, under),
status_message='under 1V ({})'.format(n_occurrences))
# Get voltage levels for classification # Get voltage levels for classification
voltage_dict = {} voltage_dict = {}
classified_indices = np.array([]) classified_indices = np.array([])
@ -658,13 +668,25 @@ class StationQC(object):
voltage_dict[volt] = indices voltage_dict[volt] = indices
classified_indices = np.append(classified_indices, indices) classified_indices = np.append(classified_indices, indices)
# Warn in case of voltage under OK-level (1V)
if len(under) > 0:
# try calculate number of occurences from gaps between indices
n_occurrences = len(np.where(np.diff(under) > 1)[0]) + 1
voltage_dict[-1] = under
self.warn(key='other',
detailed_message=f'Trace {trace.get_id()}: '
f'Voltage below {pb_ok}V in {len(under)} samples, {n_occurrences} time(s). '
f'Mean voltage: {np.mean(voltage):.2}'
+ self.get_last_occurrence_timestring(trace, under),
status_message='under 1V ({})'.format(n_occurrences))
# classify last voltage values # classify last voltage values
for volt in voltage_levels: for volt in voltage_levels:
if (last_voltage < volt + pb_thresh) and (last_voltage > volt - pb_thresh): if (last_voltage < volt + pb_thresh) and (last_voltage > volt - pb_thresh):
last_val = volt last_val = volt
break break
else: else:
last_val = np.nan last_val = round(last_voltage, 2)
# in case not all voltage values could be classified # in case not all voltage values could be classified
if not len(classified_indices) == len(voltage): if not len(classified_indices) == len(voltage):