bugfix: change lighting command update notifications to use scaled physical values using min/max actual value. (#1315)
This commit is contained in:
@@ -16,12 +16,142 @@
|
||||
#include "lighting_command.h"
|
||||
|
||||
/**
|
||||
* @brief call the lighting command tracking value callbacks
|
||||
* @param data - dimmer data structure
|
||||
* @param old_value - value prior to write
|
||||
* @param value - value of the write
|
||||
* @brief compare two floating point values to 3 decimal places
|
||||
*
|
||||
* @param x1 - first comparison value
|
||||
* @param x2 - second comparison value
|
||||
* @return true if the value is the same to 3 decimal points
|
||||
*/
|
||||
static void lighting_command_tracking_value_notify(
|
||||
static bool is_float_equal(float x1, float x2)
|
||||
{
|
||||
return fabs(x1 - x2) < 0.001;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clamp the value within the normalized range
|
||||
* @details The normalized output level is specified as the
|
||||
* linearized percentage (0..100%) of the possible light output range
|
||||
* with 0.0% being off, 1.0% being dimmest, and 100.0% being brightest.
|
||||
* @param value [in] value to clamp within the normalized range
|
||||
* @return value clamped within the normalized range of 0.0% to 100.0%
|
||||
*/
|
||||
float lighting_command_normalized_range_clamp(float value)
|
||||
{
|
||||
float physical_value;
|
||||
|
||||
/* clamp value within physical values, if non-zero */
|
||||
if (isless(value, 1.0f)) {
|
||||
/* jump target to OFF */
|
||||
physical_value = 0.0f;
|
||||
} else if (isgreater(value, 100.0f)) {
|
||||
physical_value = 100.0f;
|
||||
} else {
|
||||
physical_value = value;
|
||||
}
|
||||
|
||||
return physical_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clamp the value within the normal ON range
|
||||
* @details The normal ON output level is specified as the linearized
|
||||
* percentage (1..100%) of the possible light output range with 1.0% being
|
||||
* dimmest, and 100.0% being brightest.
|
||||
* @param value [in] value to clamp within the normalized ON range
|
||||
* @return value clamped within the normalized ON range of 1.0% to 100.0%
|
||||
*/
|
||||
float lighting_command_normalized_on_range_clamp(float value)
|
||||
{
|
||||
float normalized_on_value;
|
||||
|
||||
/* clamp value within 1.0 and 100.0 values */
|
||||
if (isless(value, 1.0f)) {
|
||||
normalized_on_value = 1.0f;
|
||||
} else if (isgreater(value, 100.0f)) {
|
||||
normalized_on_value = 100.0f;
|
||||
} else {
|
||||
normalized_on_value = value;
|
||||
}
|
||||
|
||||
return normalized_on_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adjust Min/Max Actual Value Range
|
||||
* @details Min_Actual_Value property, of type Real, shall specify
|
||||
* the physical output level that corresponds to a Present_Value of 1.0%.
|
||||
* Changing Min_Actual_Value to a value greater than Max_Actual_Value
|
||||
* shall force Max_Actual_Value to become equal to Min_Actual_Value.
|
||||
* Min_Actual_Value shall always be a positive number in the
|
||||
* range 1.0% to 100.0%.
|
||||
*
|
||||
* Max_Actual_Value property, of type Real, shall specify the physical
|
||||
* output level that corresponds to a Present_Value of 100.0%.
|
||||
* Changing Max_Actual_Value to a value less than Min_Actual_Value
|
||||
* shall force Min_Actual_Value to become equal to Max_Actual_Value.
|
||||
* Max_Actual_Value shall always be a positive number in the range
|
||||
* 1.0% to 100.0%.
|
||||
*/
|
||||
static void lighting_command_min_max_value_range_adjust(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
float swap_value, min_value, max_value;
|
||||
|
||||
min_value =
|
||||
lighting_command_normalized_on_range_clamp(data->Min_Actual_Value);
|
||||
max_value =
|
||||
lighting_command_normalized_on_range_clamp(data->Max_Actual_Value);
|
||||
if (isgreater(min_value, max_value)) {
|
||||
/* swap the configured high and low actual values if they are inverse */
|
||||
swap_value = min_value;
|
||||
min_value = max_value;
|
||||
max_value = swap_value;
|
||||
}
|
||||
data->Min_Actual_Value = min_value;
|
||||
data->Max_Actual_Value = max_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate the Feedback_Value property value
|
||||
*
|
||||
* This property, of type Real, shall indicate the actual value
|
||||
* of the physical lighting output within the normalized range.
|
||||
* If the actual value of the physical lighting output in the
|
||||
* non-normalized range is not off but is less than the
|
||||
* Min_Actual_Value, then Feedback_Value shall be set to 1.0%.
|
||||
* If the actual value in the non-normalized range is greater than
|
||||
* Max_Actual_Value, then Feedback_Value shall be set to 100.0%.
|
||||
* @param data - dimmer data structure
|
||||
* @return calculated feedback-value
|
||||
*/
|
||||
float lighting_command_normalized_to_physical_value(
|
||||
float min_value, float max_value, float normalized_value)
|
||||
{
|
||||
float physical_value, x1, x2, x3, y1, y3;
|
||||
|
||||
if (isless(normalized_value, 1.0f)) {
|
||||
physical_value = 0.0f;
|
||||
} else if (isgreater(normalized_value, 100.0f)) {
|
||||
physical_value = max_value;
|
||||
} else {
|
||||
x1 = 1.0f;
|
||||
x2 = normalized_value;
|
||||
x3 = 100.0f;
|
||||
y1 = min_value;
|
||||
y3 = max_value;
|
||||
physical_value = linear_interpolate(x1, x2, x3, y1, y3);
|
||||
}
|
||||
|
||||
return physical_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief call the lighting command notification callbacks
|
||||
* @param data - dimmer data structure
|
||||
* @param old_value - physical value prior to write
|
||||
* @param value - physical value of the write
|
||||
*/
|
||||
static void lighting_command_notify(
|
||||
struct bacnet_lighting_command_data *data, float old_value, float value)
|
||||
{
|
||||
struct lighting_command_notification *head;
|
||||
@@ -175,32 +305,6 @@ float lighting_command_step_increment_clamp(float step_increment)
|
||||
return step_increment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clamp the value within the physical min/max range
|
||||
* @details The physical output level, or non-normalized range,
|
||||
* is specified as the linearized percentage (0..100%)
|
||||
* of the possible light output range with 0.0% being off,
|
||||
* 1.0% being dimmest, and 100.0% being brightest.
|
||||
* @param value [in] value to clamp within the physical min/max range
|
||||
* @return value clamped within the physical min/max range of 0.0% to 100.0%
|
||||
*/
|
||||
float lighting_command_physical_range_clamp(float value)
|
||||
{
|
||||
float physical_value;
|
||||
|
||||
/* clamp value within physical values, if non-zero */
|
||||
if (isless(value, 1.0f)) {
|
||||
/* jump target to OFF */
|
||||
physical_value = 0.0f;
|
||||
} else if (isgreater(value, 100.0f)) {
|
||||
physical_value = 100.0f;
|
||||
} else {
|
||||
physical_value = value;
|
||||
}
|
||||
|
||||
return physical_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate the target value for a step down command
|
||||
* @param tracking_value [in] current tracking value
|
||||
@@ -305,36 +409,23 @@ static float lighting_command_operating_range_clamp_fade_nolock(
|
||||
float value,
|
||||
uint16_t milliseconds)
|
||||
{
|
||||
float high_trim, low_trim, swap_value;
|
||||
|
||||
if (data) {
|
||||
/* clamp range within physical limits */
|
||||
high_trim =
|
||||
lighting_command_physical_range_clamp(data->High_Trim_Value);
|
||||
low_trim = lighting_command_physical_range_clamp(data->Low_Trim_Value);
|
||||
/* valid range check for high and low trim values */
|
||||
if (isgreater(low_trim, high_trim)) {
|
||||
/* swap the trims if they are inverse */
|
||||
swap_value = low_trim;
|
||||
low_trim = high_trim;
|
||||
high_trim = swap_value;
|
||||
}
|
||||
/* clamp value within trim values, if non-zero */
|
||||
if (isless(value, 1.0f)) {
|
||||
/* jump target to OFF if below normalized min */
|
||||
value = 0.0f;
|
||||
} else if (isgreater(value, high_trim)) {
|
||||
} else if (isgreater(value, data->High_Trim_Value)) {
|
||||
value = lighting_command_trim_fade(
|
||||
data, value, high_trim, milliseconds);
|
||||
data, value, data->High_Trim_Value, milliseconds);
|
||||
data->In_Progress = BACNET_LIGHTING_TRIM_ACTIVE;
|
||||
} else if (isless(value, low_trim)) {
|
||||
value =
|
||||
lighting_command_trim_fade(data, value, low_trim, milliseconds);
|
||||
} else if (isless(value, data->Low_Trim_Value)) {
|
||||
value = lighting_command_trim_fade(
|
||||
data, value, data->Low_Trim_Value, milliseconds);
|
||||
data->In_Progress = BACNET_LIGHTING_TRIM_ACTIVE;
|
||||
}
|
||||
} else {
|
||||
/* no data, so just clamp value within physical limits */
|
||||
value = lighting_command_physical_range_clamp(value);
|
||||
value = lighting_command_normalized_range_clamp(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@@ -358,195 +449,6 @@ float lighting_command_operating_range_clamp_fade(
|
||||
return clamped_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clamp the value within the operating range between low and high
|
||||
* end trim values immediately.
|
||||
* @details The Operating Range is a subset of the Normalized Range,
|
||||
* that represents the range of acceptable values for control of the object.
|
||||
* The Operating Range is defined by the High_End_Trim and Low_End_Trim
|
||||
* property values. When values are written outside of the Operating Range,
|
||||
* the Tracking_Value will reflect the actual, clamped normalized light
|
||||
* output while the Present_Value will reflect the original target value.
|
||||
* @param data - dimmer data structure
|
||||
* @param value the value that will be subject to clamping
|
||||
* @return value clamped within the operating range defined by the High_End_Trim
|
||||
* and Low_End_Trim property values
|
||||
*/
|
||||
static float lighting_command_operating_range_clamp_nolock(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
return lighting_command_operating_range_clamp_fade_nolock(data, value, 0);
|
||||
}
|
||||
|
||||
float lighting_command_operating_range_clamp(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
float clamped_value;
|
||||
|
||||
if (!data) {
|
||||
return value;
|
||||
}
|
||||
lighting_command_lock(data);
|
||||
clamped_value = lighting_command_operating_range_clamp_nolock(data, value);
|
||||
lighting_command_unlock(data);
|
||||
|
||||
return clamped_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine if the values are both within the normalized OFF range
|
||||
* @details The physical output level, or non-normalized range,
|
||||
* is specified as the linearized percentage (0..100%)
|
||||
* of the possible light output range with 0.0% being off,
|
||||
* 1.0% being dimmest, and 100.0% being brightest.
|
||||
* The actual range represents the subset of physical output levels
|
||||
* defined by Min_Actual_Value and Max_Actual_Value
|
||||
* (or 1.0 to 100.0% if these properties are not present).
|
||||
* The normalized range is always 0.0 to 100.0% where
|
||||
* 1.0% = bottom of the actual range and 100.0% = top of the actual range.
|
||||
* @param data - dimmer data structure
|
||||
* @param value1 [in] value to check if it is within the normalized OFF range
|
||||
* @param value2 [in] value to check if it is within the normalized OFF range
|
||||
* @return true if both values are within the normalized OFF range, false
|
||||
* otherwise
|
||||
*/
|
||||
static bool lighting_command_is_normalized_off_to_off_nolock(
|
||||
struct bacnet_lighting_command_data *data, float value1, float value2)
|
||||
{
|
||||
float min_value, max_value;
|
||||
|
||||
/* check normalized range within physical limits */
|
||||
max_value = lighting_command_physical_range_clamp(data->Max_Actual_Value);
|
||||
min_value = lighting_command_physical_range_clamp(data->Min_Actual_Value);
|
||||
if (isgreater(min_value, max_value)) {
|
||||
/* the high and low configured actual values are swapped */
|
||||
min_value = max_value;
|
||||
}
|
||||
if (isless(value1, min_value) && isless(value2, min_value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clamp the value within the normalized ON range 1% to 100%.
|
||||
* @details The physical output level, or non-normalized range,
|
||||
* is specified as the linearized percentage (0..100%)
|
||||
* of the possible light output range with 0.0% being off,
|
||||
* 1.0% being dimmest, and 100.0% being brightest.
|
||||
* The actual range represents the subset of physical output levels
|
||||
* defined by Min_Actual_Value and Max_Actual_Value
|
||||
* (or 1.0 to 100.0% if these properties are not present).
|
||||
* The normalized range is always 0.0 to 100.0% where
|
||||
* 1.0% = bottom of the actual range and 100.0% = top of the actual range.
|
||||
* @param data - dimmer data structure
|
||||
* @param value [in] value to normalize
|
||||
* @return normalized value within the range defined by Min_Actual_Value
|
||||
* and Max_Actual_Value
|
||||
*/
|
||||
static float lighting_command_normalized_on_range_clamp_nolock(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
float min_value, max_value, swap_value;
|
||||
|
||||
/* clamp range within physical limits */
|
||||
max_value = lighting_command_physical_range_clamp(data->Max_Actual_Value);
|
||||
min_value = lighting_command_physical_range_clamp(data->Min_Actual_Value);
|
||||
if (isgreater(min_value, max_value)) {
|
||||
/* swap the configured high and low actual values if they are inverse */
|
||||
swap_value = min_value;
|
||||
min_value = max_value;
|
||||
max_value = swap_value;
|
||||
}
|
||||
/* clamp value within actual min/max values */
|
||||
if (isgreater(value, max_value)) {
|
||||
value = max_value;
|
||||
} else if (isless(value, min_value)) {
|
||||
value = min_value;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float lighting_command_normalized_on_range_clamp(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
float clamped_value;
|
||||
|
||||
if (!data) {
|
||||
return value;
|
||||
}
|
||||
lighting_command_lock(data);
|
||||
clamped_value =
|
||||
lighting_command_normalized_on_range_clamp_nolock(data, value);
|
||||
lighting_command_unlock(data);
|
||||
|
||||
return clamped_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Normalize the value to the min/max range
|
||||
* @details The physical output level, or non-normalized range,
|
||||
* is specified as the linearized percentage (0..100%)
|
||||
* of the possible light output range with 0.0% being off,
|
||||
* 1.0% being dimmest, and 100.0% being brightest.
|
||||
* The actual range represents the subset of physical output levels
|
||||
* defined by Min_Actual_Value and Max_Actual_Value
|
||||
* (or 1.0 to 100.0% if these properties are not present).
|
||||
* The normalized range is always 0.0 to 100.0% where
|
||||
* 1.0% = bottom of the actual range and 100.0% = top of the actual range.
|
||||
* @param data - dimmer data structure
|
||||
* @param value [in] value to normalize
|
||||
* @return normalized value within the range defined by
|
||||
* 0.0%, Min_Actual_Value, and Max_Actual_Value
|
||||
*/
|
||||
static float lighting_command_normalized_range_clamp_nolock(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
float normalized_value;
|
||||
float min_value, max_value, swap_value;
|
||||
|
||||
/* clamp range within physical limits */
|
||||
max_value = lighting_command_physical_range_clamp(data->Max_Actual_Value);
|
||||
min_value = lighting_command_physical_range_clamp(data->Min_Actual_Value);
|
||||
/* valid range check for high and low trim values */
|
||||
if (isgreater(min_value, max_value)) {
|
||||
/* swap the trims if they are inverse */
|
||||
swap_value = min_value;
|
||||
min_value = max_value;
|
||||
max_value = swap_value;
|
||||
}
|
||||
/* clamp value within normalized values, if non-zero */
|
||||
if (isless(value, 1.0f)) {
|
||||
/* jump target to OFF if below normalized min */
|
||||
normalized_value = 0.0f;
|
||||
} else if (isgreater(value, max_value)) {
|
||||
normalized_value = max_value;
|
||||
} else if (isless(value, min_value)) {
|
||||
normalized_value = min_value;
|
||||
} else {
|
||||
normalized_value = value;
|
||||
}
|
||||
|
||||
return normalized_value;
|
||||
}
|
||||
|
||||
float lighting_command_normalized_range_clamp(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
float clamped_value;
|
||||
|
||||
if (!data) {
|
||||
return value;
|
||||
}
|
||||
lighting_command_lock(data);
|
||||
clamped_value = lighting_command_normalized_range_clamp_nolock(data, value);
|
||||
lighting_command_unlock(data);
|
||||
|
||||
return clamped_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback for tracking value updates
|
||||
* @param data - dimmer data structure
|
||||
@@ -555,16 +457,25 @@ float lighting_command_normalized_range_clamp(
|
||||
* @param milliseconds - number of milliseconds elapsed
|
||||
*/
|
||||
static void lighting_command_tracking_value_event(
|
||||
struct bacnet_lighting_command_data *data, float old_value, float value)
|
||||
struct bacnet_lighting_command_data *data,
|
||||
float old_value,
|
||||
float tracking_value)
|
||||
{
|
||||
float physical_value, old_physical_value;
|
||||
|
||||
lighting_command_min_max_value_range_adjust(data);
|
||||
physical_value = lighting_command_normalized_to_physical_value(
|
||||
data->Min_Actual_Value, data->Max_Actual_Value, tracking_value);
|
||||
old_physical_value = lighting_command_normalized_to_physical_value(
|
||||
data->Min_Actual_Value, data->Max_Actual_Value, old_value);
|
||||
if (data->Overridden) {
|
||||
lighting_command_tracking_value_notify(data, old_value, value);
|
||||
lighting_command_notify(data, old_physical_value, physical_value);
|
||||
if (data->Overridden_Momentary) {
|
||||
data->Overridden = false;
|
||||
}
|
||||
} else if (!data->Out_Of_Service) {
|
||||
data->Overridden_Momentary = false;
|
||||
lighting_command_tracking_value_notify(data, old_value, value);
|
||||
lighting_command_notify(data, old_physical_value, physical_value);
|
||||
} else {
|
||||
debug_printf(
|
||||
"Lighting-Command[%lu]-Out-of-Service\n", (unsigned long)data->Key);
|
||||
@@ -586,18 +497,17 @@ static void lighting_command_fade_handler(
|
||||
float target_value;
|
||||
|
||||
old_value = data->Tracking_Value;
|
||||
if (lighting_command_is_normalized_off_to_off_nolock(
|
||||
data, old_value, data->Target_Level)) {
|
||||
if (isless(old_value, 1.0f) && isless(data->Target_Level, 1.0f)) {
|
||||
/* check for OFF to OFF transition */
|
||||
data->Tracking_Value = 0.0f;
|
||||
data->In_Progress = BACNET_LIGHTING_IDLE;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
} else {
|
||||
/* clamp Target value within the Normalized ON Range */
|
||||
target_value = lighting_command_normalized_on_range_clamp_nolock(
|
||||
data, data->Target_Level);
|
||||
target_value =
|
||||
lighting_command_normalized_on_range_clamp(data->Target_Level);
|
||||
if ((milliseconds >= data->Fade_Time) ||
|
||||
(!islessgreater(data->Tracking_Value, target_value))) {
|
||||
(is_float_equal(data->Tracking_Value, target_value))) {
|
||||
/* stop fading */
|
||||
if (isless(data->Target_Level, 1.0f)) {
|
||||
/* jump target to OFF if below normalized min */
|
||||
@@ -609,12 +519,12 @@ static void lighting_command_fade_handler(
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
data->Fade_Time = 0;
|
||||
} else {
|
||||
/* fading */
|
||||
/* fading in the normalized ON range */
|
||||
x1 = 0.0f;
|
||||
x2 = (float)milliseconds;
|
||||
x3 = (float)data->Fade_Time;
|
||||
if (isless(old_value, data->Min_Actual_Value)) {
|
||||
y1 = data->Min_Actual_Value;
|
||||
if (isless(old_value, 1.0f)) {
|
||||
y1 = 1.0f;
|
||||
} else {
|
||||
y1 = old_value;
|
||||
}
|
||||
@@ -642,8 +552,7 @@ static void lighting_command_fade_handler(
|
||||
* at a particular percent per second defined by ramp-rate.
|
||||
* While the ramp operation is executing, In_Progress shall be set
|
||||
* to RAMP_ACTIVE, and Tracking_Value shall be updated to reflect the current
|
||||
* progress of the ramp. <target-level> shall be clamped to
|
||||
* Min_Actual_Value and Max_Actual_Value.
|
||||
* progress of the ramp.
|
||||
*
|
||||
* @param data - dimmer data structure
|
||||
* @param milliseconds - number of milliseconds elapsed
|
||||
@@ -655,17 +564,16 @@ static void lighting_command_ramp_handler(
|
||||
operating_value;
|
||||
|
||||
old_value = data->Tracking_Value;
|
||||
if (lighting_command_is_normalized_off_to_off_nolock(
|
||||
data, old_value, data->Target_Level)) {
|
||||
if (isless(old_value, 1.0f) && isless(data->Target_Level, 1.0f)) {
|
||||
/* check for OFF to OFF transition */
|
||||
data->Tracking_Value = 0.0f;
|
||||
data->In_Progress = BACNET_LIGHTING_IDLE;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
} else {
|
||||
/* clamp Target value within the Normalized ON Range */
|
||||
target_value = lighting_command_normalized_on_range_clamp_nolock(
|
||||
data, data->Target_Level);
|
||||
if (!islessgreater(data->Tracking_Value, target_value)) {
|
||||
target_value =
|
||||
lighting_command_normalized_on_range_clamp(data->Target_Level);
|
||||
if (is_float_equal(data->Tracking_Value, target_value)) {
|
||||
/* stop ramping */
|
||||
if (isless(data->Target_Level, 1.0f)) {
|
||||
/* jump target to OFF if below normalized min */
|
||||
@@ -706,9 +614,7 @@ static void lighting_command_ramp_handler(
|
||||
step_value = target_value;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
}
|
||||
/* clamp target within min/max, if needed */
|
||||
step_value = lighting_command_normalized_on_range_clamp_nolock(
|
||||
data, step_value);
|
||||
step_value = lighting_command_normalized_on_range_clamp(step_value);
|
||||
if (data->Lighting_Operation == BACNET_LIGHTS_STOP) {
|
||||
if (isless(data->Target_Level, 1.0f)) {
|
||||
/* jump target to OFF if below normalized min */
|
||||
@@ -736,31 +642,26 @@ static void lighting_command_ramp_handler(
|
||||
* Updates the object tracking value while stepping
|
||||
*
|
||||
* Commands the dimmer to a value equal to the Tracking_Value
|
||||
* plus the step-increment. The resulting sum shall be clamped to
|
||||
* Min_Actual_Value and Max_Actual_Value
|
||||
* plus the step-increment. If the result of the addition is
|
||||
* greater than 100.0%, the value shall be set to 100.0%.
|
||||
*
|
||||
* @param data [in] dimmer data
|
||||
*/
|
||||
static void
|
||||
lighting_command_step_up_handler(struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
float old_value, target_value, operating_value;
|
||||
float old_value, target_value;
|
||||
|
||||
old_value = data->Tracking_Value;
|
||||
if (isgreaterequal(old_value, data->Min_Actual_Value)) {
|
||||
/* inhibit ON if the value is already OFF */
|
||||
if (isgreaterequal(old_value, 1.0f)) {
|
||||
/* inhibit ON if the value is currently OFF */
|
||||
target_value = lighting_command_step_up_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
/* clamp Tracking value within the Normalized ON Range */
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
data->Tracking_Value =
|
||||
lighting_command_normalized_on_range_clamp_nolock(
|
||||
data, target_value);
|
||||
lighting_command_normalized_on_range_clamp(target_value);
|
||||
data->In_Progress = BACNET_LIGHTING_IDLE;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
operating_value = lighting_command_operating_range_clamp_nolock(
|
||||
data, data->Tracking_Value);
|
||||
data->Tracking_Value = operating_value;
|
||||
/* notify */
|
||||
lighting_command_tracking_value_event(
|
||||
data, old_value, data->Tracking_Value);
|
||||
@@ -771,8 +672,7 @@ lighting_command_step_up_handler(struct bacnet_lighting_command_data *data)
|
||||
* Updates the object tracking value while stepping
|
||||
*
|
||||
* Commands the dimmer to a value equal to the Tracking_Value
|
||||
* plus the step-increment. The resulting sum shall be clamped to
|
||||
* Min_Actual_Value and Max_Actual_Value
|
||||
* plus the step-increment.
|
||||
*
|
||||
* @param data [in] dimmer data
|
||||
*/
|
||||
@@ -784,14 +684,13 @@ lighting_command_step_down_handler(struct bacnet_lighting_command_data *data)
|
||||
old_value = data->Tracking_Value;
|
||||
target_value = lighting_command_step_down_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
/* clamp Tracking value within the Normalized ON Range */
|
||||
data->Tracking_Value =
|
||||
lighting_command_normalized_on_range_clamp_nolock(data, target_value);
|
||||
lighting_command_normalized_on_range_clamp(target_value);
|
||||
data->In_Progress = BACNET_LIGHTING_IDLE;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
operating_value = lighting_command_operating_range_clamp_nolock(
|
||||
data, data->Tracking_Value);
|
||||
operating_value =
|
||||
lighting_command_normalized_range_clamp(data->Tracking_Value);
|
||||
data->Tracking_Value = operating_value;
|
||||
/* notify */
|
||||
lighting_command_tracking_value_event(
|
||||
@@ -802,27 +701,32 @@ lighting_command_step_down_handler(struct bacnet_lighting_command_data *data)
|
||||
* Updates the object tracking value while stepping
|
||||
*
|
||||
* Commands the dimmer to a value equal to the Tracking_Value
|
||||
* plus the step-increment. The resulting sum shall be clamped to
|
||||
* Min_Actual_Value and Max_Actual_Value
|
||||
* plus the step-increment.
|
||||
* If the result of the addition is greater than 100.0%,
|
||||
* the value shall be set to 100.0%.
|
||||
* When the Tracking_Value is 0.0%, 1.0% is written
|
||||
* to the specified slot in the priority array.
|
||||
*
|
||||
* @param data [in] dimmer data
|
||||
*/
|
||||
static void
|
||||
lighting_command_step_on_handler(struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
float old_value, target_value, operating_value;
|
||||
float old_value, target_value;
|
||||
|
||||
old_value = data->Tracking_Value;
|
||||
target_value = lighting_command_step_up_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
data->Tracking_Value =
|
||||
lighting_command_normalized_range_clamp_nolock(data, target_value);
|
||||
if (isless(data->Tracking_Value, 1.0f)) {
|
||||
/* step is ignored when starting at OFF */
|
||||
data->Tracking_Value = 1.0f;
|
||||
} else {
|
||||
target_value = lighting_command_step_up_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
/* clamp Tracking value inclusively within the Normalized Range */
|
||||
data->Tracking_Value =
|
||||
lighting_command_normalized_range_clamp(target_value);
|
||||
}
|
||||
data->In_Progress = BACNET_LIGHTING_IDLE;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
operating_value = lighting_command_operating_range_clamp_nolock(
|
||||
data, data->Tracking_Value);
|
||||
data->Tracking_Value = operating_value;
|
||||
/* notify */
|
||||
lighting_command_tracking_value_event(
|
||||
data, old_value, data->Tracking_Value);
|
||||
@@ -831,28 +735,28 @@ lighting_command_step_on_handler(struct bacnet_lighting_command_data *data)
|
||||
/**
|
||||
* Updates the object tracking value while stepping
|
||||
*
|
||||
* Commands the dimmer to a value equal to the Tracking_Value
|
||||
* plus the step-increment. The resulting sum shall be clamped to
|
||||
* Min_Actual_Value and Max_Actual_Value
|
||||
* Commands Present_Value to a value equal to the Tracking_Value
|
||||
* minus the step-increment at the specified priority.
|
||||
* The step-down operation is implemented by writing
|
||||
* the Tracking_Value minus step-increment to the specified
|
||||
* slot in the priority array.
|
||||
* If the result of the subtraction is less than 1.0%,
|
||||
* 0.0% is written to the specified slot in the priority array.
|
||||
*
|
||||
* @param data [in] dimmer data
|
||||
*/
|
||||
static void
|
||||
lighting_command_step_off_handler(struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
float old_value, target_value, operating_value;
|
||||
float old_value, target_value;
|
||||
|
||||
old_value = data->Tracking_Value;
|
||||
target_value = lighting_command_step_down_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
data->Tracking_Value =
|
||||
lighting_command_normalized_range_clamp_nolock(data, target_value);
|
||||
lighting_command_normalized_range_clamp(target_value);
|
||||
data->In_Progress = BACNET_LIGHTING_IDLE;
|
||||
data->Lighting_Operation = BACNET_LIGHTS_STOP;
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
operating_value = lighting_command_operating_range_clamp_nolock(
|
||||
data, data->Tracking_Value);
|
||||
data->Tracking_Value = operating_value;
|
||||
/* notify */
|
||||
lighting_command_tracking_value_event(
|
||||
data, old_value, data->Tracking_Value);
|
||||
@@ -936,11 +840,8 @@ static void lighting_command_blink_handler(
|
||||
}
|
||||
}
|
||||
}
|
||||
target_value =
|
||||
lighting_command_normalized_range_clamp_nolock(data, target_value);
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
operating_value =
|
||||
lighting_command_operating_range_clamp_nolock(data, target_value);
|
||||
operating_value = lighting_command_normalized_range_clamp(target_value);
|
||||
/* note: The blink-warn notifications shall not be reflected
|
||||
in the tracking value. */
|
||||
if (data->In_Progress == BACNET_LIGHTING_IDLE) {
|
||||
@@ -959,7 +860,7 @@ static void lighting_command_override_nolock(
|
||||
float old_value;
|
||||
|
||||
old_value = data->Tracking_Value;
|
||||
data->Tracking_Value = lighting_command_physical_range_clamp(value);
|
||||
data->Tracking_Value = lighting_command_normalized_range_clamp(value);
|
||||
lighting_command_tracking_value_event(
|
||||
data, old_value, data->Tracking_Value);
|
||||
}
|
||||
@@ -1003,7 +904,7 @@ void lighting_command_override_set(
|
||||
void lighting_command_override_clear(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
float old_value, normalized_value, operating_value;
|
||||
float old_value;
|
||||
|
||||
if (!data) {
|
||||
return;
|
||||
@@ -1013,13 +914,9 @@ void lighting_command_override_clear(
|
||||
data->Overridden_Momentary = false;
|
||||
old_value = data->Tracking_Value;
|
||||
/* clamp Tracking value within the Normalized Range */
|
||||
normalized_value =
|
||||
lighting_command_normalized_range_clamp_nolock(data, value);
|
||||
/* clamp Tracking value inclusively within the Operating Range */
|
||||
operating_value =
|
||||
lighting_command_operating_range_clamp_nolock(data, normalized_value);
|
||||
data->Tracking_Value = operating_value;
|
||||
lighting_command_tracking_value_event(data, old_value, operating_value);
|
||||
data->Tracking_Value = lighting_command_normalized_range_clamp(value);
|
||||
lighting_command_tracking_value_event(
|
||||
data, old_value, data->Tracking_Value);
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
@@ -1190,7 +1087,7 @@ void lighting_command_step(
|
||||
/* configure the lighting operation */
|
||||
if (((operation == BACNET_LIGHTS_STEP_UP) ||
|
||||
(operation == BACNET_LIGHTS_STEP_DOWN)) &&
|
||||
(!islessgreater(data->Tracking_Value, 0.0))) {
|
||||
(is_float_equal(data->Tracking_Value, 0.0))) {
|
||||
/* If the starting level of Tracking_Value is 0.0%,
|
||||
then this operation is ignored. */
|
||||
goto done;
|
||||
@@ -1202,23 +1099,19 @@ void lighting_command_step(
|
||||
if (operation == BACNET_LIGHTS_STEP_UP) {
|
||||
target_value = lighting_command_step_up_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
target_value = lighting_command_normalized_on_range_clamp_nolock(
|
||||
data, target_value);
|
||||
target_value = lighting_command_normalized_on_range_clamp(target_value);
|
||||
} else if (operation == BACNET_LIGHTS_STEP_DOWN) {
|
||||
target_value = lighting_command_step_down_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
target_value = lighting_command_normalized_on_range_clamp_nolock(
|
||||
data, target_value);
|
||||
target_value = lighting_command_normalized_on_range_clamp(target_value);
|
||||
} else if (operation == BACNET_LIGHTS_STEP_ON) {
|
||||
target_value = lighting_command_step_up_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
target_value =
|
||||
lighting_command_normalized_range_clamp_nolock(data, target_value);
|
||||
target_value = lighting_command_normalized_range_clamp(target_value);
|
||||
} else if (operation == BACNET_LIGHTS_STEP_OFF) {
|
||||
target_value = lighting_command_step_down_target_value(
|
||||
data->Tracking_Value, data->Step_Increment);
|
||||
target_value =
|
||||
lighting_command_normalized_range_clamp_nolock(data, target_value);
|
||||
target_value = lighting_command_normalized_range_clamp(target_value);
|
||||
} else {
|
||||
goto done;
|
||||
}
|
||||
@@ -1431,24 +1324,43 @@ void lighting_command_toggle_default(
|
||||
/**
|
||||
* @brief Configure the lighting command to apply low or high trim
|
||||
* @param data [in] dimmer data
|
||||
* @param high_end_trim [in] BACnet lighting high end trim
|
||||
* @param low_end_trim [in] BACnet lighting low end trim
|
||||
* @param trim_fade_time [in] BACnet lighting trim fade time
|
||||
*/
|
||||
void lighting_command_trim_set(
|
||||
struct bacnet_lighting_command_data *data,
|
||||
float High_End_Trim,
|
||||
float Low_End_Trim,
|
||||
uint32_t Trim_Fade_Time)
|
||||
float high_end_trim,
|
||||
float low_end_trim,
|
||||
uint32_t trim_fade_time)
|
||||
{
|
||||
float swap_value, high_trim, low_trim;
|
||||
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
lighting_command_lock(data);
|
||||
/* apply high and low trim */
|
||||
data->High_Trim_Value = High_End_Trim;
|
||||
data->Low_Trim_Value = Low_End_Trim;
|
||||
data->Trim_Fade_Time = Trim_Fade_Time;
|
||||
/* clamp range within normalized limits */
|
||||
high_trim = lighting_command_normalized_on_range_clamp(high_end_trim);
|
||||
low_trim = lighting_command_normalized_on_range_clamp(low_end_trim);
|
||||
/* valid range check for high and low trim values */
|
||||
if (isgreater(low_trim, high_trim)) {
|
||||
/* swap the trims if they are inverse */
|
||||
swap_value = low_trim;
|
||||
low_trim = high_trim;
|
||||
high_trim = swap_value;
|
||||
}
|
||||
data->High_Trim_Value = high_trim;
|
||||
data->Low_Trim_Value = low_trim;
|
||||
data->Trim_Fade_Time = trim_fade_time;
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command key
|
||||
* @param data [in] dimmer data
|
||||
* @param key [in] BACnet lighting key
|
||||
*/
|
||||
void lighting_command_key_set(
|
||||
struct bacnet_lighting_command_data *data, uint32_t key)
|
||||
{
|
||||
@@ -1460,6 +1372,11 @@ void lighting_command_key_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command tracking value callback
|
||||
* @param data [in] dimmer data
|
||||
* @param cb [in] BACnet lighting tracking value callback
|
||||
*/
|
||||
void lighting_command_tracking_value_callback_set(
|
||||
struct bacnet_lighting_command_data *data,
|
||||
lighting_command_tracking_value_callback cb)
|
||||
@@ -1472,6 +1389,11 @@ void lighting_command_tracking_value_callback_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command in progress
|
||||
* @param data [in] dimmer data
|
||||
* @return BACNET_LIGHTING_IN_PROGRESS - lighting command in progress
|
||||
*/
|
||||
BACNET_LIGHTING_IN_PROGRESS
|
||||
lighting_command_in_progress_get(struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1487,6 +1409,11 @@ lighting_command_in_progress_get(struct bacnet_lighting_command_data *data)
|
||||
return in_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command in progress
|
||||
* @param data [in] dimmer data
|
||||
* @param in_progress [in] BACnet lighting in progress
|
||||
*/
|
||||
void lighting_command_in_progress_set(
|
||||
struct bacnet_lighting_command_data *data,
|
||||
BACNET_LIGHTING_IN_PROGRESS in_progress)
|
||||
@@ -1499,6 +1426,11 @@ void lighting_command_in_progress_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command tracking value
|
||||
* @param data [in] dimmer data
|
||||
* @return float - lighting command tracking value
|
||||
*/
|
||||
float lighting_command_tracking_value_get(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1514,6 +1446,11 @@ float lighting_command_tracking_value_get(
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command tracking value
|
||||
* @param data [in] dimmer data
|
||||
* @param value [in] BACnet lighting tracking value
|
||||
*/
|
||||
void lighting_command_tracking_value_set(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
@@ -1541,6 +1478,11 @@ void lighting_command_blink_warn_feature_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the lighting command blink egress is active
|
||||
* @param data [in] dimmer data
|
||||
* @return bool - true if the lighting command blink egress is active
|
||||
*/
|
||||
bool lighting_command_blink_egress_active(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1556,6 +1498,11 @@ bool lighting_command_blink_egress_active(
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command out of service
|
||||
* @param data [in] dimmer data
|
||||
* @return bool - true if the lighting command is out of service
|
||||
*/
|
||||
bool lighting_command_out_of_service_get(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1571,6 +1518,11 @@ bool lighting_command_out_of_service_get(
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command out of service
|
||||
* @param data [in] dimmer data
|
||||
* @param value [in] BACnet lighting out of service
|
||||
*/
|
||||
void lighting_command_out_of_service_set(
|
||||
struct bacnet_lighting_command_data *data, bool value)
|
||||
{
|
||||
@@ -1582,6 +1534,11 @@ void lighting_command_out_of_service_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command last on value
|
||||
* @param data [in] dimmer data
|
||||
* @return float - lighting command last on value
|
||||
*/
|
||||
float lighting_command_last_on_value_get(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1597,6 +1554,11 @@ float lighting_command_last_on_value_get(
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command last on value
|
||||
* @param data [in] dimmer data
|
||||
* @param value [in] BACnet lighting last on value
|
||||
*/
|
||||
void lighting_command_last_on_value_set(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
@@ -1608,6 +1570,11 @@ void lighting_command_last_on_value_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command default on value
|
||||
* @param data [in] dimmer data
|
||||
* @return float - lighting command default on value
|
||||
*/
|
||||
float lighting_command_default_on_value_get(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1623,6 +1590,11 @@ float lighting_command_default_on_value_get(
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lighting command default on value
|
||||
* @param data [in] dimmer data
|
||||
* @param value [in] BACnet lighting default on value
|
||||
*/
|
||||
void lighting_command_default_on_value_set(
|
||||
struct bacnet_lighting_command_data *data, float value)
|
||||
{
|
||||
@@ -1634,6 +1606,11 @@ void lighting_command_default_on_value_set(
|
||||
lighting_command_unlock(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command overridden status
|
||||
* @param data [in] dimmer data
|
||||
* @return bool - true if the lighting command is overridden
|
||||
*/
|
||||
bool lighting_command_overridden_status(
|
||||
struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
@@ -1649,6 +1626,27 @@ bool lighting_command_overridden_status(
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the lighting command feedback value
|
||||
* @param data [in] dimmer data
|
||||
* @return float - lighting command feedback value
|
||||
*/
|
||||
float lighting_command_feedback_value(struct bacnet_lighting_command_data *data)
|
||||
{
|
||||
float feedback_value;
|
||||
|
||||
if (!data) {
|
||||
return 0.0f;
|
||||
}
|
||||
lighting_command_lock(data);
|
||||
lighting_command_min_max_value_range_adjust(data);
|
||||
feedback_value = lighting_command_normalized_to_physical_value(
|
||||
data->Min_Actual_Value, data->Max_Actual_Value, data->Tracking_Value);
|
||||
lighting_command_unlock(data);
|
||||
|
||||
return feedback_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine if fade, ramp, or warn command is currently executing
|
||||
* @param pObject [in] object to apply the trim values to
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
#include "bacnet/bacdef.h"
|
||||
|
||||
/**
|
||||
* @brief Callback for tracking value updates
|
||||
* @brief Callback for lighting command notifications
|
||||
* @param key - key used to link to specific light
|
||||
* @param old_value - value prior to write
|
||||
* @param value - value of the write
|
||||
* @param old_value - physical value prior to write
|
||||
* @param value - physical value of the write
|
||||
*/
|
||||
typedef void (*lighting_command_tracking_value_callback)(
|
||||
uint32_t key, float old_value, float value);
|
||||
@@ -165,22 +165,23 @@ BACNET_STACK_EXPORT
|
||||
float lighting_command_ramp_rate_clamp(float ramp_rate);
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_step_increment_clamp(float step_increment);
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_operating_range_clamp(
|
||||
struct bacnet_lighting_command_data *data, float value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_operating_range_clamp_fade(
|
||||
struct bacnet_lighting_command_data *data,
|
||||
float value,
|
||||
uint16_t milliseconds);
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_normalized_range_clamp(
|
||||
struct bacnet_lighting_command_data *data, float value);
|
||||
float lighting_command_normalized_range_clamp(float value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_normalized_on_range_clamp(
|
||||
struct bacnet_lighting_command_data *data, float value);
|
||||
float lighting_command_normalized_on_range_clamp(float value);
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_physical_range_clamp(float value);
|
||||
float lighting_command_normalized_to_physical_value(
|
||||
float min_value, float max_value, float normalized_value);
|
||||
BACNET_STACK_EXPORT
|
||||
float lighting_command_feedback_value(
|
||||
struct bacnet_lighting_command_data *data);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void lighting_command_trim_set(
|
||||
|
||||
@@ -235,15 +235,23 @@ static void test_lighting_command_unit(void)
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
zassert_true(data.In_Progress == BACNET_LIGHTING_IDLE, NULL);
|
||||
|
||||
/* normalized range clamp testing */
|
||||
/* normalized range scaling to physical values */
|
||||
data.Max_Actual_Value = 95.0f;
|
||||
data.Min_Actual_Value = 5.0f;
|
||||
target_level = lighting_command_normalized_range_clamp(&data, 0.1f);
|
||||
target_level = lighting_command_normalized_to_physical_value(
|
||||
data.Min_Actual_Value, data.Max_Actual_Value, 0.1f);
|
||||
zassert_true(is_float_equal(target_level, 0.0f), NULL);
|
||||
target_level = lighting_command_normalized_range_clamp(&data, 100.0f);
|
||||
target_level = lighting_command_normalized_to_physical_value(
|
||||
data.Min_Actual_Value, data.Max_Actual_Value, 100.1f);
|
||||
zassert_true(is_float_equal(target_level, data.Max_Actual_Value), NULL);
|
||||
target_level = lighting_command_normalized_range_clamp(&data, 1.0f);
|
||||
zassert_true(is_float_equal(target_level, data.Min_Actual_Value), NULL);
|
||||
target_level = lighting_command_normalized_to_physical_value(
|
||||
data.Min_Actual_Value, data.Max_Actual_Value, 50.0f);
|
||||
zassert_true(
|
||||
islessequal(target_level, data.Max_Actual_Value), "physical-value=%.2f",
|
||||
target_level);
|
||||
zassert_true(
|
||||
isgreaterequal(target_level, data.Min_Actual_Value),
|
||||
"physical-value=%.2f", target_level);
|
||||
data.Max_Actual_Value = 100.0f;
|
||||
data.Min_Actual_Value = 1.0f;
|
||||
|
||||
@@ -306,8 +314,8 @@ static void test_lighting_command_unit(void)
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
zassert_true(data.In_Progress == BACNET_LIGHTING_IDLE, NULL);
|
||||
zassert_true(is_float_equal(Tracking_Value, target_level), NULL);
|
||||
data.Low_Trim_Value = data.Min_Actual_Value;
|
||||
zassert_true(is_float_equal(data.Last_On_Value, 1.0f), NULL);
|
||||
data.Low_Trim_Value = 1.0f;
|
||||
/* high trim */
|
||||
data.High_Trim_Value = 90.0f;
|
||||
target_level = 100.0f;
|
||||
@@ -317,8 +325,8 @@ static void test_lighting_command_unit(void)
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
zassert_true(data.In_Progress == BACNET_LIGHTING_TRIM_ACTIVE, NULL);
|
||||
zassert_true(is_float_equal(Tracking_Value, data.High_Trim_Value), NULL);
|
||||
data.High_Trim_Value = data.Max_Actual_Value;
|
||||
zassert_true(is_float_equal(data.Last_On_Value, target_level), NULL);
|
||||
data.High_Trim_Value = 100.0f;
|
||||
/* trim fade time */
|
||||
target_level = 80.0f;
|
||||
milliseconds = 10;
|
||||
@@ -408,21 +416,21 @@ static void test_lighting_command_unit(void)
|
||||
zassert_true(is_float_equal(target_step, 100.0f), NULL);
|
||||
|
||||
/* physical range clamping */
|
||||
target_level = lighting_command_physical_range_clamp(0.0f);
|
||||
target_level = lighting_command_normalized_range_clamp(0.0f);
|
||||
zassert_true(is_float_equal(target_level, 0.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(0.5f);
|
||||
target_level = lighting_command_normalized_range_clamp(0.5f);
|
||||
zassert_true(is_float_equal(target_level, 0.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(0.9f);
|
||||
target_level = lighting_command_normalized_range_clamp(0.9f);
|
||||
zassert_true(is_float_equal(target_level, 0.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(1.0f);
|
||||
target_level = lighting_command_normalized_range_clamp(1.0f);
|
||||
zassert_true(is_float_equal(target_level, 1.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(50.0f);
|
||||
target_level = lighting_command_normalized_range_clamp(50.0f);
|
||||
zassert_true(is_float_equal(target_level, 50.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(100.0f);
|
||||
target_level = lighting_command_normalized_range_clamp(100.0f);
|
||||
zassert_true(is_float_equal(target_level, 100.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(100.1f);
|
||||
target_level = lighting_command_normalized_range_clamp(100.1f);
|
||||
zassert_true(is_float_equal(target_level, 100.0f), NULL);
|
||||
target_level = lighting_command_physical_range_clamp(150.0f);
|
||||
target_level = lighting_command_normalized_range_clamp(150.0f);
|
||||
zassert_true(is_float_equal(target_level, 100.0f), NULL);
|
||||
|
||||
/* step UP - inhibit ON */
|
||||
@@ -483,7 +491,7 @@ static void test_lighting_command_unit(void)
|
||||
is_float_equal(data.Last_On_Value, data.Max_Actual_Value), NULL);
|
||||
/* step DOWN, not off */
|
||||
target_step = 1.0f;
|
||||
target_level = data.Min_Actual_Value + target_step;
|
||||
target_level = 1.0f + target_step;
|
||||
milliseconds = 10;
|
||||
lighting_command_fade_to(&data, target_level, 0);
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
@@ -492,18 +500,17 @@ static void test_lighting_command_unit(void)
|
||||
lighting_command_step(&data, BACNET_LIGHTS_STEP_DOWN, target_step);
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
zassert_true(data.In_Progress == BACNET_LIGHTING_IDLE, NULL);
|
||||
zassert_true(is_float_equal(Tracking_Value, data.Min_Actual_Value), NULL);
|
||||
zassert_true(
|
||||
is_float_equal(data.Last_On_Value, data.Min_Actual_Value), NULL);
|
||||
/* clamp to min */
|
||||
zassert_true(is_float_equal(Tracking_Value, 1.0f), NULL);
|
||||
zassert_true(is_float_equal(data.Last_On_Value, 1.0f), NULL);
|
||||
/* clamp to min normal */
|
||||
target_step = 100.0f;
|
||||
lighting_command_step(&data, BACNET_LIGHTS_STEP_DOWN, target_step);
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
zassert_true(data.In_Progress == BACNET_LIGHTING_IDLE, NULL);
|
||||
zassert_true(is_float_equal(Tracking_Value, data.Min_Actual_Value), NULL);
|
||||
zassert_true(is_float_equal(Tracking_Value, 1.0f), NULL);
|
||||
/* step DOWN and off */
|
||||
target_step = 100.0f;
|
||||
target_level = data.Min_Actual_Value;
|
||||
target_level = 1.0f;
|
||||
milliseconds = 10;
|
||||
lighting_command_fade_to(&data, target_level, 0);
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
@@ -513,8 +520,7 @@ static void test_lighting_command_unit(void)
|
||||
lighting_command_timer(&data, milliseconds);
|
||||
zassert_true(data.In_Progress == BACNET_LIGHTING_IDLE, NULL);
|
||||
zassert_true(is_float_equal(Tracking_Value, 0.0f), NULL);
|
||||
zassert_true(
|
||||
is_float_equal(data.Last_On_Value, data.Min_Actual_Value), NULL);
|
||||
zassert_true(is_float_equal(data.Last_On_Value, 1.0f), NULL);
|
||||
/* blink warn - immediate off */
|
||||
data.Blink.Interval = 0;
|
||||
data.Blink.Duration = 0;
|
||||
@@ -574,8 +580,8 @@ static void test_lighting_command_unit(void)
|
||||
data.In_Progress == BACNET_LIGHTING_RAMP_ACTIVE,
|
||||
"In_Progress=%d", data.In_Progress);
|
||||
zassert_true(
|
||||
isgreater(data.Tracking_Value, data.Min_Actual_Value),
|
||||
"Tracking_Value=%f", Tracking_Value);
|
||||
isgreater(data.Tracking_Value, 1.0f), "Tracking_Value=%f",
|
||||
Tracking_Value);
|
||||
zassert_true(
|
||||
isless(data.Tracking_Value, data.Max_Actual_Value),
|
||||
"Tracking_Value=%f", Tracking_Value);
|
||||
@@ -583,7 +589,7 @@ static void test_lighting_command_unit(void)
|
||||
} while (data.Lighting_Operation != BACNET_LIGHTS_STOP);
|
||||
|
||||
/* slower ramp down */
|
||||
target_level = data.Min_Actual_Value;
|
||||
target_level = 1.0f;
|
||||
milliseconds = 33;
|
||||
ramp_rate = 0.1f;
|
||||
do {
|
||||
@@ -594,15 +600,14 @@ static void test_lighting_command_unit(void)
|
||||
data.In_Progress == BACNET_LIGHTING_RAMP_ACTIVE,
|
||||
"In_Progress=%d", data.In_Progress);
|
||||
zassert_true(
|
||||
isgreater(data.Tracking_Value, data.Min_Actual_Value),
|
||||
"Tracking_Value=%f", Tracking_Value);
|
||||
isgreater(data.Tracking_Value, 1.0f), "Tracking_Value=%f",
|
||||
Tracking_Value);
|
||||
zassert_true(
|
||||
isless(data.Tracking_Value, data.Max_Actual_Value),
|
||||
"Tracking_Value=%f", Tracking_Value);
|
||||
}
|
||||
} while (data.Lighting_Operation != BACNET_LIGHTS_STOP);
|
||||
zassert_true(
|
||||
is_float_equal(data.Last_On_Value, data.Min_Actual_Value), NULL);
|
||||
zassert_true(is_float_equal(data.Last_On_Value, 1.0f), NULL);
|
||||
/* large elapsed timer - ramp up */
|
||||
target_level = data.Max_Actual_Value;
|
||||
milliseconds = 2000;
|
||||
@@ -615,8 +620,8 @@ static void test_lighting_command_unit(void)
|
||||
data.In_Progress == BACNET_LIGHTING_RAMP_ACTIVE,
|
||||
"In_Progress=%d", data.In_Progress);
|
||||
zassert_true(
|
||||
isgreater(data.Tracking_Value, data.Min_Actual_Value),
|
||||
"Tracking_Value=%f", Tracking_Value);
|
||||
isgreater(data.Tracking_Value, 1.0f), "Tracking_Value=%f",
|
||||
Tracking_Value);
|
||||
zassert_true(
|
||||
isless(data.Tracking_Value, data.Max_Actual_Value),
|
||||
"Tracking_Value=%f", Tracking_Value);
|
||||
|
||||
Reference in New Issue
Block a user