Add missing object functions to analog inputs and values (#568)

* ai.c: add possibility to set a custom object name

The Name_Set function is already declared in the header but not
implemented. With this implementation, one can set a custom object name
from a server application.

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>

* av.c: add possibility to set a custom object name

The Name_Set function is already declared in the header but not
implemented. With this implementation, one can set a custom object name
from a server application.

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>

* ai.c: implement function to set custom description

For now the hard-coded behaviour was to return the object name whenever
a client requested the value for the description.

Therefore implement the functions Description and Description_Set already
declared in the header and add a Description property to the data
structure used. We also need to properly implement PROP_DESCRIPTION in
the Read_Property function.

This way we can set and read a custom decsription from a server application
and send the appropriate response to a read-property request asking for
PROP_DESCRIPTION.

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>

* av.c: implement function to set custom description

For now the hard-coded behaviour was to return the object name whenever
a client requested the value for the description.

Therefore implement the functions Description and Description_Set already
declared in the header and add a Description property to the data
structure used. We also need to properly implement PROP_DESCRIPTION in
the Read_Property function.

This way we can set and read a custom decsription from a server application
and send the appropriate response to a read-property request asking for
PROP_DESCRIPTION.

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>

* ai.c: implement function to set custom units

Implement the object functions related to Units already declared in the
header.

By default Analog Inputs will have the Unit UNITS_PERCENT. Add
functionality to be able to set and read custom units from a server
application.

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>

* av.c: implement function to set custom units

Implement the object functions related to Units already declared in the
header.

By default Analog Values will have the Unit UNITS_NO_UNIT. Add
functionality to be able to set and read custom units from a server
application.

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>

---------

Signed-off-by: Sebastian Weyer <sebastian.weyer@smile.fr>
Co-authored-by: Sebastian Weyer <sebastian.weyer@smile.fr>
This commit is contained in:
Sebastian Weyer
2024-02-05 18:32:02 +01:00
committed by GitHub
parent f326b1347f
commit 46d686a8ab
4 changed files with 229 additions and 12 deletions
+118 -7
View File
@@ -97,6 +97,7 @@ void Analog_Input_Init(void)
AI_Descr[i].Prior_Value = 0.0f;
AI_Descr[i].COV_Increment = 1.0f;
AI_Descr[i].Changed = false;
AI_Descr[i].Object_Name = NULL;
#if defined(INTRINSIC_REPORTING)
AI_Descr[i].Event_State = EVENT_STATE_NORMAL;
/* notification class not connected */
@@ -209,17 +210,49 @@ void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
}
}
/**
* For a given object instance-number, return the name.
*
* Note: the object name must be unique within this device
*
* @param object_instance - object-instance number of the object
* @param object_name - object name/string pointer
*
* @return true/false
*/
bool Analog_Input_Object_Name(
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
unsigned int index;
static char text_string[32] = "";
bool status = false;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
sprintf(text_string, "ANALOG INPUT %lu", (unsigned long)index);
status = characterstring_init_ansi(object_name, text_string);
if (object_instance < MAX_ANALOG_INPUTS) {
if (AI_Descr[object_instance].Object_Name) {
status = characterstring_init_ansi(object_name, AI_Descr[object_instance].Object_Name);
} else {
snprintf(text_string, sizeof(text_string), "ANALOG INPUT %u",
object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
}
return status;
}
/**
* For a given object instance-number, sets the object-name
*
* @param object_instance - object-instance number of the object
* @param new_name - holds the object-name to be set
*
* @return true if object-name was set
*/
bool Analog_Input_Name_Set(uint32_t object_instance, char *new_name)
{
bool status = false;
if (object_instance < MAX_ANALOG_INPUTS) {
status = true;
AI_Descr[object_instance].Object_Name = new_name;
}
return status;
@@ -247,6 +280,40 @@ unsigned Analog_Input_Event_State(uint32_t object_instance)
return state;
}
/**
* @brief For a given object instance-number, returns the description
* @param object_instance - object-instance number of the object
* @return description text or NULL if not found
*/
char *Analog_Input_Description(uint32_t object_instance)
{
char *name = NULL;
if (object_instance < MAX_ANALOG_INPUTS) {
name = AI_Descr[object_instance].Description;
}
return name;
}
/**
* @brief For a given object instance-number, sets the description
* @param object_instance - object-instance number of the object
* @param new_name - holds the description to be set
* @return true if object-name was set
*/
bool Analog_Input_Description_Set(uint32_t object_instance, char *new_name)
{
bool status = false; /* return value */
if (object_instance < MAX_ANALOG_INPUTS && new_name) {
status = true;
AI_Descr[object_instance].Description = new_name;
}
return status;
}
bool Analog_Input_Change_Of_Value(uint32_t object_instance)
{
unsigned index = 0;
@@ -327,6 +394,44 @@ void Analog_Input_COV_Increment_Set(uint32_t object_instance, float value)
}
}
/**
* For a given object instance-number, returns the units property value
*
* @param object_instance - object-instance number of the object
*
* @return units property value
*/
uint16_t Analog_Input_Units(uint32_t object_instance)
{
uint16_t units = UNITS_NO_UNITS;
if (object_instance < MAX_ANALOG_INPUTS) {
units = AI_Descr[object_instance].Units;
}
return units;
}
/**
* For a given object instance-number, sets the units property value
*
* @param object_instance - object-instance number of the object
* @param units - units property value
*
* @return true if the units property value was set
*/
bool Analog_Input_Units_Set(uint32_t object_instance, uint16_t units)
{
bool status = false;
if (object_instance < MAX_ANALOG_INPUTS) {
AI_Descr[object_instance].Units = units;
status = true;
}
return status;
}
bool Analog_Input_Out_Of_Service(uint32_t object_instance)
{
unsigned index = 0;
@@ -396,12 +501,18 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
Analog_Input_Object_Name(rpdata->object_instance, &char_string);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Input_Description(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
+2
View File
@@ -52,6 +52,8 @@ extern "C" {
float Prior_Value;
float COV_Increment;
bool Changed;
char* Object_Name;
char* Description;
#if defined(INTRINSIC_REPORTING)
uint32_t Time_Delay;
uint32_t Notification_Class;
+107 -5
View File
@@ -104,6 +104,7 @@ void Analog_Value_Init(void)
AV_Descr[i].Prior_Value = 0.0f;
AV_Descr[i].COV_Increment = 1.0f;
AV_Descr[i].Changed = false;
AV_Descr[i].Object_Name = NULL;
#if defined(INTRINSIC_REPORTING)
AV_Descr[i].Event_State = EVENT_STATE_NORMAL;
/* notification class not connected */
@@ -280,13 +281,36 @@ float Analog_Value_Present_Value(uint32_t object_instance)
bool Analog_Value_Object_Name(
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
static char text_string[32] = "";
bool status = false;
if (object_instance < MAX_ANALOG_VALUES) {
sprintf(
text_string, "ANALOG VALUE %lu", (unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
if (AV_Descr[object_instance].Object_Name) {
status = characterstring_init_ansi(object_name, AV_Descr[object_instance].Object_Name);
} else {
snprintf(text_string, sizeof(text_string), "ANALOG VALUE %u",
object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
}
return status;
}
/**
* For a given object instance-number, sets the object-name
*
* @param object_instance - object-instance number of the object
* @param new_name - holds the object-name to be set
*
* @return true if object-name was set
*/
bool Analog_Value_Name_Set(uint32_t object_instance, char *new_name)
{
bool status = false;
if (object_instance < MAX_ANALOG_VALUES) {
status = true;
AV_Descr[object_instance].Object_Name = new_name;
}
return status;
@@ -314,6 +338,40 @@ unsigned Analog_Value_Event_State(uint32_t object_instance)
return state;
}
/**
* @brief For a given object instance-number, returns the description
* @param object_instance - object-instance number of the object
* @return description text or NULL if not found
*/
char *Analog_Value_Description(uint32_t object_instance)
{
char *name = NULL;
if (object_instance < MAX_ANALOG_VALUES) {
name = AV_Descr[object_instance].Description;
}
return name;
}
/**
* @brief For a given object instance-number, sets the description
* @param object_instance - object-instance number of the object
* @param new_name - holds the description to be set
* @return true if object-name was set
*/
bool Analog_Value_Description_Set(uint32_t object_instance, char *new_name)
{
bool status = false; /* return value */
if (object_instance < MAX_ANALOG_VALUES && new_name) {
status = true;
AV_Descr[object_instance].Description = new_name;
}
return status;
}
/**
* For a given object instance-number, determines if the COV flag
* has been triggered.
@@ -431,6 +489,44 @@ void Analog_Value_COV_Increment_Set(uint32_t object_instance, float value)
}
}
/**
* For a given object instance-number, returns the units property value
*
* @param object_instance - object-instance number of the object
*
* @return units property value
*/
uint16_t Analog_Value_Units(uint32_t object_instance)
{
uint16_t units = UNITS_NO_UNITS;
if (object_instance < MAX_ANALOG_VALUES) {
units = AV_Descr[object_instance].Units;
}
return units;
}
/**
* For a given object instance-number, sets the units property value
*
* @param object_instance - object-instance number of the object
* @param units - units property value
*
* @return true if the units property value was set
*/
bool Analog_Value_Units_Set(uint32_t object_instance, uint16_t units)
{
bool status = false;
if (object_instance < MAX_ANALOG_VALUES) {
AV_Descr[object_instance].Units = units;
status = true;
}
return status;
}
bool Analog_Value_Out_Of_Service(uint32_t object_instance)
{
unsigned index = 0;
@@ -506,7 +602,6 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
if (Analog_Value_Object_Name(
rpdata->object_instance, &char_string)) {
apdu_len =
@@ -514,6 +609,13 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
}
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Value_Description(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
+2
View File
@@ -52,6 +52,8 @@ extern "C" {
float Prior_Value;
float COV_Increment;
bool Changed;
char* Object_Name;
char* Description;
#if defined(INTRINSIC_REPORTING)
uint32_t Time_Delay;
uint32_t Notification_Class;