Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial submittion of a reusable hysteresis function. #222

Closed
wants to merge 9 commits into from
38 changes: 38 additions & 0 deletions Core/automation/lib/python/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,41 @@ def validate_uid(uid):
uid = "{}_{}".format("jython", uid)
uid = re.sub(r"__+", "_", uid)
return uid

def hysteresis(target, value, low=0, high=0):
"""
Checks if the value is below, above or between the hysteresis gap defined
by the target-low <= value <= target+high. The function accepts Python
primitives, QuantityTypes, DecimalTypes, or PercentTypes or any combination
of the four types. When using QuantityTypes, the default units of the Units
of Measure is used.

Arguments:
- target: The target value that defines the setpoint for the comparison.
- value: The value to determine where it is in the hysteresis.
- low: Value subtracted from target to define the lower bounds of the
hysteresis gap. Defaults to 0.
- high: Value added to target to define the upper bounds of the
hystersis gap. Defaults to 0

Returns:
- 1 if value is >= target+high
- 0 if the value is between target-low and target+high or if low and
high are both zero and value == target
- (-1) if value is <= target-low
"""
target, value, low, high = [x.floatValue()
if isinstance(x, (scope.QuantityType,
scope.DecimalType,
scope.PercentType))
else x
for x in [target, value, low, high]]

if value == target or target - low < value < target + high:
rval = 0
elif value <= (target - low):
rval = -1
else:
rval = 1

return rval
42 changes: 42 additions & 0 deletions Tests/automation/lib/python/tests/core/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Hysteresis test
from core.util import hysteresis
from core.log import logging, LOG_PREFIX

log = logging.getLogger("{}.TEST.util".format(LOG_PREFIX))
try:
assert hysteresis(30, 30, 1, 1) == 0
assert hysteresis(30, 29, 1, 1) == -1
assert hysteresis(30, 31, 1, 1) == 1
assert hysteresis(30, 30) == 0
assert hysteresis(30, 31) == 1
assert hysteresis(30, 29) == -1
assert hysteresis(QuantityType(u"30 %"),
QuantityType(u"29 %"),
low=QuantityType(u"1 %")) == -1
assert hysteresis(QuantityType(u"30 %"), QuantityType(u"29 %"), 1, 1) == -1
assert hysteresis(QuantityType(u"30 %"),
QuantityType(u"31 %"),
high=QuantityType(u"1 %")) == 1
assert hysteresis(DecimalType(30),
DecimalType(29),
low=DecimalType(1)) == -1
assert hysteresis(DecimalType(30), DecimalType(29), 1, 1) == -1
assert hysteresis(DecimalType(30),
DecimalType(31),
high=DecimalType(1)) == 1
assert hysteresis(PercentType(30),
PercentType(29),
low=PercentType(1)) == -1
assert hysteresis(PercentType(30), PercentType(29), 1, 1) == -1
assert hysteresis(PercentType(30),
PercentType(31),
high=PercentType(1)) == 1
assert hysteresis(QuantityType(u"30 %"),
DecimalType(29),
PercentType(1), 1) == -1

except AssertionError:
import traceback
log.error("Exception: {}".format(traceback.format_exc()))
else:
log.info("hysteresis tests passed!")