diff --git a/CHANGELOG.md b/CHANGELOG.md index dc6b6d31..03158298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ The git repositories are hosted at the following sites: ### Added +* Added API and optional properties to basic lighting output object example + for power and feedback value. (#1185) * Added properties to the Channel object write member value coercion minimal properties supported. (#1176) * Added Send_x_Address() API to ReadPropertyMultiple, WritePropertyMultiple, diff --git a/src/bacnet/basic/object/lo.c b/src/bacnet/basic/object/lo.c index b8556fac..ed727e55 100644 --- a/src/bacnet/basic/object/lo.c +++ b/src/bacnet/basic/object/lo.c @@ -33,7 +33,6 @@ struct object_data { float Present_Value; BACNET_LIGHTING_COMMAND_DATA Lighting_Command; BACNET_LIGHTING_COMMAND Last_Lighting_Command; - float Physical_Value; uint32_t Egress_Time_Seconds; uint32_t Default_Fade_Time; uint32_t Trim_Fade_Time; @@ -92,7 +91,7 @@ static const int32_t Properties_Required[] = { PROP_LAST_ON_VALUE, PROP_DEFAULT_ON_VALUE, #endif - -1 + -1, }; static const int32_t Properties_Optional[] = { /* unordered list of optional properties */ @@ -108,7 +107,10 @@ static const int32_t Properties_Optional[] = { PROP_LOW_END_TRIM, PROP_TRIM_FADE_TIME, #endif - -1 + PROP_FEEDBACK_VALUE, + PROP_POWER, + PROP_INSTANTANEOUS_POWER, + -1, }; static const int32_t Properties_Proprietary[] = { -1 }; @@ -2937,6 +2939,125 @@ bool Lighting_Output_Override_Color_Reference_Set( return status; } +/** + * @brief For a given object instance-number, gets the feedback value property + * @param object_instance - object-instance number of the object + * @return the feedback value of this object instance. + */ +float Lighting_Output_Feedback_Value(uint32_t object_instance) +{ + float value = 0.0; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + value = pObject->Feedback_Value; + } + + return value; +} + +/** + * @brief For a given object instance-number, sets the feedback value + * of the object. + * @param object_instance - object-instance number of the object + * @param value - holds the value to be set + * @return true if feedback value was set + */ +bool Lighting_Output_Feedback_Value_Set(uint32_t object_instance, float value) +{ + bool status = false; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + pObject->Feedback_Value = value; + status = true; + } + + return status; +} + +/** + * @brief For a given object instance-number, gets the power value property + * @param object_instance - object-instance number of the object + * @return the power value of this object instance. + */ +float Lighting_Output_Power(uint32_t object_instance) +{ + float value = 0.0; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + value = pObject->Power; + } + + return value; +} + +/** + * @brief For a given object instance-number, sets the power value + * of the object. + * @param object_instance - object-instance number of the object + * @param value - holds the value to be set + * @return true if power value was set + */ +bool Lighting_Output_Power_Set(uint32_t object_instance, float value) +{ + bool status = false; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + pObject->Power = value; + status = true; + } + + return status; +} + +/** + * @brief For a given object instance-number, gets the instantaneous power value + * property + * @param object_instance - object-instance number of the object + * @return the instantaneous power value of this object instance. + */ +float Lighting_Output_Instantaneous_Power(uint32_t object_instance) +{ + float value = 0.0; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + value = pObject->Instantaneous_Power; + } + + return value; +} + +/** + * @brief For a given object instance-number, sets the instantaneous power value + * of the object. + * @param object_instance - object-instance number of the object + * @param value - holds the instantaneous power value to be set + * @return true if instantaneous power value was set + */ +bool Lighting_Output_Instantaneous_Power_Set( + uint32_t object_instance, float value) +{ + bool status = false; + struct object_data *pObject; + + pObject = Keylist_Data(Object_List, object_instance); + if (pObject) { + pObject->Instantaneous_Power = value; + status = true; + } + + return status; +} + /** * ReadProperty handler for this object. For the given ReadProperty * data, the application_data is loaded or the error flags are set. @@ -3130,6 +3251,20 @@ int Lighting_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) apdu_len = encode_application_character_string(&apdu[0], &char_string); break; + case PROP_FEEDBACK_VALUE: + real_value = + Lighting_Output_Feedback_Value(rpdata->object_instance); + apdu_len = encode_application_real(&apdu[0], real_value); + break; + case PROP_POWER: + real_value = Lighting_Output_Power(rpdata->object_instance); + apdu_len = encode_application_real(&apdu[0], real_value); + break; + case PROP_INSTANTANEOUS_POWER: + real_value = + Lighting_Output_Instantaneous_Power(rpdata->object_instance); + apdu_len = encode_application_real(&apdu[0], real_value); + break; default: rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; @@ -3333,6 +3468,30 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) } } break; + case PROP_FEEDBACK_VALUE: + status = write_property_type_valid( + wp_data, &value, BACNET_APPLICATION_TAG_REAL); + if (status) { + status = Lighting_Output_Feedback_Value_Set( + wp_data->object_instance, value.type.Real); + } + break; + case PROP_POWER: + status = write_property_type_valid( + wp_data, &value, BACNET_APPLICATION_TAG_REAL); + if (status) { + status = Lighting_Output_Power_Set( + wp_data->object_instance, value.type.Real); + } + break; + case PROP_INSTANTANEOUS_POWER: + status = write_property_type_valid( + wp_data, &value, BACNET_APPLICATION_TAG_REAL); + if (status) { + status = Lighting_Output_Instantaneous_Power_Set( + wp_data->object_instance, value.type.Real); + } + break; default: if (property_lists_member( Properties_Required, Properties_Optional, @@ -3454,7 +3613,6 @@ uint32_t Lighting_Output_Create(uint32_t object_instance) pObject->Object_Name = NULL; pObject->Description = NULL; pObject->Present_Value = 0.0f; - pObject->Physical_Value = 0.0f; lighting_command_init(&pObject->Lighting_Command); pObject->Lighting_Command.Key = object_instance; pObject->Lighting_Command.Notification_Head.callback = @@ -3471,7 +3629,7 @@ uint32_t Lighting_Output_Create(uint32_t object_instance) pObject->Default_Ramp_Rate = 100.0; pObject->Default_Step_Increment = 1.0f; pObject->Transition = BACNET_LIGHTING_TRANSITION_FADE; - pObject->Feedback_Value = 0.0; + pObject->Feedback_Value = 0.0f; for (p = 0; p < BACNET_MAX_PRIORITY; p++) { pObject->Priority_Array[p] = 0.0f; BIT_CLEAR(pObject->Priority_Active_Bits, p); diff --git a/src/bacnet/basic/object/lo.h b/src/bacnet/basic/object/lo.h index 26edaf8e..a3208202 100644 --- a/src/bacnet/basic/object/lo.h +++ b/src/bacnet/basic/object/lo.h @@ -216,6 +216,22 @@ BACNET_STACK_EXPORT bool Lighting_Output_Override_Color_Reference_Set( uint32_t object_instance, const BACNET_OBJECT_ID *value); +BACNET_STACK_EXPORT +float Lighting_Output_Feedback_Value(uint32_t object_instance); +BACNET_STACK_EXPORT +bool Lighting_Output_Feedback_Value_Set(uint32_t object_instance, float value); + +BACNET_STACK_EXPORT +float Lighting_Output_Power(uint32_t object_instance); +BACNET_STACK_EXPORT +bool Lighting_Output_Power_Set(uint32_t object_instance, float value); + +BACNET_STACK_EXPORT +float Lighting_Output_Instantaneous_Power(uint32_t object_instance); +BACNET_STACK_EXPORT +bool Lighting_Output_Instantaneous_Power_Set( + uint32_t object_instance, float value); + BACNET_STACK_EXPORT void Lighting_Output_Timer(uint32_t object_instance, uint16_t milliseconds); diff --git a/test/bacnet/basic/object/lo/src/main.c b/test/bacnet/basic/object/lo/src/main.c index 8ec6e292..9b625a97 100644 --- a/test/bacnet/basic/object/lo/src/main.c +++ b/test/bacnet/basic/object/lo/src/main.c @@ -356,6 +356,8 @@ static void testLightingOutput(void) zassert_true( is_float_equal(test_real, real_value), "value=%f test_value=%f", real_value, test_real); + /* refresh */ + Lighting_Output_Lighting_Command_Refresh(instance); /* color-override */ status = Lighting_Output_Color_Override_Set(instance, true); zassert_true(status, NULL); @@ -394,7 +396,24 @@ static void testLightingOutput(void) test_real = Lighting_Output_Tracking_Value(instance); zassert_true(is_float_equal(test_real, real_value), NULL); zassert_true(is_float_equal(Test_Tracking_Value, real_value), NULL); - + /* feedback value */ + status = Lighting_Output_Feedback_Value_Set(instance, 55.5f); + zassert_true(status, NULL); + test_real = Lighting_Output_Feedback_Value(instance); + zassert_true(is_float_equal(test_real, 55.5f), NULL); + /* power*/ + status = Lighting_Output_Power_Set(instance, 12345.67f); + zassert_true(status, NULL); + test_real = Lighting_Output_Power(instance); + zassert_true(is_float_equal(test_real, 12345.67f), NULL); + /* instantenous power*/ + status = Lighting_Output_Instantaneous_Power_Set(instance, 76543.21f); + zassert_true(status, NULL); + test_real = Lighting_Output_Instantaneous_Power(instance); + zassert_true(is_float_equal(test_real, 76543.21f), NULL); + /* context get/set */ + Lighting_Output_Context_Set( + instance, Lighting_Output_Context_Get(instance)); /* out-of-bounds */ test_instance = Lighting_Output_Create(BACNET_MAX_INSTANCE + 1); zassert_equal(test_instance, BACNET_MAX_INSTANCE, NULL);