added BaseChecker for defining the Checker API, added Checker parent class for the collecting/analysis logic, adjusted PVChecker and ValueChecker to make use of the former
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
|
||||
from .pvchecker import PVChecker
|
||||
from .valuechecker import ValueChecker
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class BaseChecker(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def get_ready(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def is_happy(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
from abc import abstractmethod
|
||||
from time import sleep
|
||||
|
||||
from .basechecker import BaseChecker
|
||||
from .utils import within, within_fraction, fraction_to_percentage
|
||||
|
||||
|
||||
class Checker(BaseChecker):
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, vmin, vmax, wait_time, required_fraction):
|
||||
self.vmin = vmin
|
||||
self.vmax = vmax
|
||||
self.wait_time = wait_time
|
||||
self.required_fraction = required_fraction
|
||||
|
||||
self.data = []
|
||||
|
||||
|
||||
def check(self):
|
||||
val = self.current()
|
||||
return within(val, self.vmin, self.vmax)
|
||||
|
||||
@abstractmethod
|
||||
def current(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def sleep(self):
|
||||
sleep(self.wait_time)
|
||||
|
||||
|
||||
def clear_and_start_counting(self):
|
||||
self.clear()
|
||||
self.start_counting()
|
||||
|
||||
def clear(self):
|
||||
self.data.clear()
|
||||
|
||||
|
||||
@abstractmethod
|
||||
def start_counting(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def stop_counting_and_analyze(self):
|
||||
self.stop_counting()
|
||||
self.analyze()
|
||||
|
||||
@abstractmethod
|
||||
def stop_counting(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def analyze(self):
|
||||
vmin = self.vmin
|
||||
vmax = self.vmax
|
||||
required_fraction = self.required_fraction
|
||||
|
||||
fraction = within_fraction(self.data, vmin, vmax)
|
||||
result = (fraction >= required_fraction)
|
||||
|
||||
status = "happy" if result else "unhappy"
|
||||
percentage = fraction_to_percentage(fraction)
|
||||
required_percentage = fraction_to_percentage(required_fraction)
|
||||
|
||||
msg = "Checker {}: {}% within limits [{}, {}), required was {}%.".format(status, percentage, vmin, vmax, required_percentage)
|
||||
print(msg)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_ready(self):
|
||||
time_start = time()
|
||||
checker_ever_unhappy = False
|
||||
|
||||
while not self.long_check():
|
||||
checker_ever_unhappy = True
|
||||
delta_t = time() - time_start
|
||||
print(f"Checker is unhappy, waiting for OK conditions since {delta_t:5.1f} seconds.")
|
||||
|
||||
if checker_ever_unhappy:
|
||||
delta_t = time() - time_start
|
||||
print(f"Checker was unhappy, waited for {delta_t:5.1f} seconds.")
|
||||
|
||||
self.clear_and_start_counting()
|
||||
|
||||
|
||||
def is_happy(self):
|
||||
return self.stop_counting_and_analyze()
|
||||
|
||||
|
||||
def long_check(self):
|
||||
self.clear_and_start_counting()
|
||||
self.sleep()
|
||||
state = self.stop_counting_and_analyze()
|
||||
return state
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from epics import PV
|
||||
from time import sleep
|
||||
|
||||
from .utils import within, within_fraction, fraction_to_percentage
|
||||
from .checker import Checker
|
||||
|
||||
|
||||
class PVChecker:
|
||||
class PVChecker(Checker):
|
||||
|
||||
def __init__(self, channel, vmin, vmax, wait_time, required_fraction):
|
||||
self.channel = channel
|
||||
@@ -17,24 +16,9 @@ class PVChecker:
|
||||
self.data = []
|
||||
|
||||
|
||||
def check(self):
|
||||
val = self.current()
|
||||
return within(val, self.vmin, self.vmax)
|
||||
|
||||
def current(self):
|
||||
return self.pv.get()
|
||||
|
||||
def sleep(self):
|
||||
sleep(self.wait_time)
|
||||
|
||||
|
||||
def clear_and_start_counting(self):
|
||||
self.clear()
|
||||
self.start_counting()
|
||||
|
||||
def clear(self):
|
||||
self.data.clear()
|
||||
|
||||
|
||||
def start_counting(self):
|
||||
def collect(value=None, **kwargs):
|
||||
@@ -44,57 +28,8 @@ class PVChecker:
|
||||
self.pv.add_callback(callback=collect)
|
||||
|
||||
|
||||
def stop_counting_and_analyze(self):
|
||||
self.stop_counting()
|
||||
self.analyze()
|
||||
|
||||
def stop_counting(self):
|
||||
self.pv.clear_callbacks()
|
||||
|
||||
|
||||
def analyze(self):
|
||||
vmin = self.vmin
|
||||
vmax = self.vmax
|
||||
required_fraction = self.required_fraction
|
||||
|
||||
fraction = within_fraction(self.data, vmin, vmax)
|
||||
result = (fraction >= required_fraction)
|
||||
|
||||
status = "happy" if result else "unhappy"
|
||||
percentage = fraction_to_percentage(fraction)
|
||||
required_percentage = fraction_to_percentage(required_fraction)
|
||||
|
||||
msg = "Checker {}: {}% within limits [{}, {}), required was {}%.".format(status, percentage, vmin, vmax, required_percentage)
|
||||
print(msg)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_ready(self):
|
||||
time_start = time()
|
||||
checker_ever_unhappy = False
|
||||
|
||||
while not self.long_check():
|
||||
checker_ever_unhappy = True
|
||||
delta_t = time() - time_start
|
||||
print(f"Checker is unhappy, waiting for OK conditions since {delta_t:5.1f} seconds.")
|
||||
|
||||
if checker_ever_unhappy:
|
||||
delta_t = time() - time_start
|
||||
print(f"Checker was unhappy, waited for {delta_t:5.1f} seconds.")
|
||||
|
||||
self.clear_and_start_counting()
|
||||
|
||||
|
||||
def is_happy(self):
|
||||
return self.stop_counting_and_analyze()
|
||||
|
||||
|
||||
def long_check(self):
|
||||
self.clear_and_start_counting()
|
||||
self.sleep()
|
||||
state = self.stop_counting_and_analyze()
|
||||
return state
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
from time import sleep
|
||||
|
||||
from .utils import within, within_fraction, fraction_to_percentage
|
||||
|
||||
from .checker import Checker
|
||||
from slic.runners import LoopRunner
|
||||
|
||||
|
||||
class ValueChecker:
|
||||
class ValueChecker(Checker):
|
||||
|
||||
def __init__(self, get_value, vmin, vmax, wait_time, required_fraction):
|
||||
self.get_value = get_value
|
||||
@@ -18,24 +15,9 @@ class ValueChecker:
|
||||
self.runner = None
|
||||
|
||||
|
||||
def check(self):
|
||||
val = self.current()
|
||||
return within(val, self.vmin, self.vmax)
|
||||
|
||||
def current(self):
|
||||
return self.get_value()
|
||||
|
||||
def sleep(self):
|
||||
sleep(self.wait_time)
|
||||
|
||||
|
||||
def clear_and_start_counting(self):
|
||||
self.clear()
|
||||
self.start_counting()
|
||||
|
||||
def clear(self):
|
||||
self.data.clear()
|
||||
|
||||
|
||||
def start_counting(self):
|
||||
if self.runner:
|
||||
@@ -48,10 +30,6 @@ class ValueChecker:
|
||||
self.runner = LoopRunner(collect, self.wait_time)
|
||||
|
||||
|
||||
def stop_counting_and_analyze(self):
|
||||
self.stop_counting()
|
||||
self.analyze()
|
||||
|
||||
def stop_counting(self):
|
||||
if not self.runner:
|
||||
return # can only stop something, if we started it
|
||||
@@ -60,49 +38,4 @@ class ValueChecker:
|
||||
self.runner = None
|
||||
|
||||
|
||||
def analyze(self):
|
||||
vmin = self.vmin
|
||||
vmax = self.vmax
|
||||
required_fraction = self.required_fraction
|
||||
|
||||
fraction = within_fraction(self.data, vmin, vmax)
|
||||
result = (fraction >= required_fraction)
|
||||
|
||||
status = "happy" if result else "unhappy"
|
||||
percentage = fraction_to_percentage(fraction)
|
||||
required_percentage = fraction_to_percentage(required_fraction)
|
||||
|
||||
msg = "Checker {}: {}% within limits [{}, {}), required was {}%.".format(status, percentage, vmin, vmax, required_percentage)
|
||||
print(msg)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_ready(self):
|
||||
time_start = time()
|
||||
checker_ever_unhappy = False
|
||||
|
||||
while not self.long_check():
|
||||
checker_ever_unhappy = True
|
||||
delta_t = time() - time_start
|
||||
print(f"Checker is unhappy, waiting for OK conditions since {delta_t:5.1f} seconds.")
|
||||
|
||||
if checker_ever_unhappy:
|
||||
delta_t = time() - time_start
|
||||
print(f"Checker was unhappy, waited for {delta_t:5.1f} seconds.")
|
||||
|
||||
self.clear_and_start_counting()
|
||||
|
||||
|
||||
def is_happy(self):
|
||||
return self.stop_counting_and_analyze()
|
||||
|
||||
|
||||
def long_check(self):
|
||||
self.clear_and_start_counting()
|
||||
self.sleep()
|
||||
state = self.stop_counting_and_analyze()
|
||||
return state
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user