diff --git a/src/bacnet/basic/object/lo.c b/src/bacnet/basic/object/lo.c index 45da3cc0..713a6ea7 100644 --- a/src/bacnet/basic/object/lo.c +++ b/src/bacnet/basic/object/lo.c @@ -2394,7 +2394,7 @@ uint32_t Lighting_Output_Create(uint32_t object_instance) pObject->Physical_Value = 0.0f; lighting_command_init(&pObject->Lighting_Command); pObject->Lighting_Command.Key = object_instance; - pObject->Lighting_Command.Tracking_Value_Callback = + pObject->Lighting_Command.Notification_Head.callback = Lighting_Output_Tracking_Value_Callback; pObject->Last_Lighting_Command.operation = BACNET_LIGHTS_NONE; pObject->Last_Lighting_Command.use_target_level = false; diff --git a/src/bacnet/basic/sys/lighting_command.c b/src/bacnet/basic/sys/lighting_command.c index 17d8e02d..51d75a91 100644 --- a/src/bacnet/basic/sys/lighting_command.c +++ b/src/bacnet/basic/sys/lighting_command.c @@ -15,6 +15,50 @@ /* me! */ #include "lighting_command.h" +/** + * @brief call the lighting command tracking value callbacks + * @param data - dimmer data + * @param old_value - value prior to write + * @param value - value of the write + */ +static void lighting_command_tracking_value_handler( + struct bacnet_lighting_command_data *data, float old_value, float value) +{ + struct lighting_command_notification *head; + + head = &data->Notification_Head; + do { + if (head->callback) { + head->callback(data->Key, old_value, value); + } + head = head->next; + } while (head); +} + +/** + * @brief Add a Lighting Command notification callback + * @param cb - notification callback to be added + */ +void lighting_command_notification_add( + struct bacnet_lighting_command_data *data, + struct lighting_command_notification *notification) +{ + struct lighting_command_notification *head; + + head = &data->Notification_Head; + do { + if (head->next == notification) { + /* already here! */ + break; + } else if (!head->next) { + /* first available free node */ + head->next = notification; + break; + } + head = head->next; + } while (head); +} + /** * @brief Callback for tracking value updates * @param data - dimmer data @@ -24,27 +68,20 @@ static void lighting_command_tracking_value_notify( struct bacnet_lighting_command_data *data, float old_value, float value) { - if (data->Tracking_Value_Callback) { - if (!data->Out_Of_Service) { - /* 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, data->High_Trim_Value)) { - value = data->High_Trim_Value; - } else if (isless(value, data->Low_Trim_Value)) { - value = data->Low_Trim_Value; - } - data->Tracking_Value_Callback(data->Key, old_value, value); - } else { - debug_printf( - "Lighting-Command[%lu]-Out-of-Service\n", - (unsigned long)data->Key); + if (!data->Out_Of_Service) { + /* 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, data->High_Trim_Value)) { + value = data->High_Trim_Value; + } else if (isless(value, data->Low_Trim_Value)) { + value = data->Low_Trim_Value; } + lighting_command_tracking_value_handler(data, old_value, value); } else { debug_printf( - "Lighting-Command[%lu]-Tracking-Value=%f\n", - (unsigned long)data->Key, (double)value); + "Lighting-Command[%lu]-Out-of-Service\n", (unsigned long)data->Key); } } @@ -643,5 +680,6 @@ void lighting_command_init(struct bacnet_lighting_command_data *data) data->Blink.Interval = 0; data->Blink.Duration = 0; data->Blink.State = false; - data->Tracking_Value_Callback = NULL; + data->Notification_Head.next = NULL; + data->Notification_Head.callback = NULL; } diff --git a/src/bacnet/basic/sys/lighting_command.h b/src/bacnet/basic/sys/lighting_command.h index bafae623..946ce061 100644 --- a/src/bacnet/basic/sys/lighting_command.h +++ b/src/bacnet/basic/sys/lighting_command.h @@ -19,6 +19,11 @@ */ typedef void (*lighting_command_tracking_value_callback)( uint32_t key, float old_value, float value); +struct lighting_command_notification; +struct lighting_command_notification { + struct lighting_command_notification *next; + lighting_command_tracking_value_callback callback; +}; typedef struct bacnet_lighting_command_warn_data { /* warn */ @@ -51,7 +56,7 @@ typedef struct bacnet_lighting_command_data { bool Out_Of_Service : 1; /* key used with callback */ uint32_t Key; - lighting_command_tracking_value_callback Tracking_Value_Callback; + struct lighting_command_notification Notification_Head; } BACNET_LIGHTING_COMMAND_DATA; #ifdef __cplusplus @@ -83,6 +88,10 @@ BACNET_STACK_EXPORT void lighting_command_none(struct bacnet_lighting_command_data *data); BACNET_STACK_EXPORT void lighting_command_init(struct bacnet_lighting_command_data *data); +BACNET_STACK_EXPORT +void lighting_command_notification_add( + struct bacnet_lighting_command_data *data, + struct lighting_command_notification *notification); #ifdef __cplusplus } diff --git a/test/bacnet/basic/sys/lighting_command/src/main.c b/test/bacnet/basic/sys/lighting_command/src/main.c index aba82c15..24371ea4 100644 --- a/test/bacnet/basic/sys/lighting_command/src/main.c +++ b/test/bacnet/basic/sys/lighting_command/src/main.c @@ -133,7 +133,7 @@ static void test_lighting_command_command_unit(void) float target_step = 1.0f; lighting_command_init(&data); - data.Tracking_Value_Callback = dimmer_tracking_value; + data.Notification_Head.callback = dimmer_tracking_value; lighting_command_stop(&data); lighting_command_timer(&data, milliseconds); zassert_true(data.In_Progress == BACNET_LIGHTING_IDLE, NULL);