Feature/color objects color command (#302)
* added BACnetColorCommand and BACnetxyColor encoding and unit testing * Added Color object and unit testing. * Added Color Temperature object and Unit test * Fix BVLC unit test warning. * add port Makefile for extra types * added RGB to and from CIE xy utility in sys folder, and add unit tests. * added cmake-win32 target * Change RP and RPM to use known property decoder. Add color object RP and RPM decoding and printing Fix RPM print for new reserved range above 4194303 Change default protocol-revision to 24 for Color object * Integrate Color and Color Temperature objects into demo apps Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
@@ -0,0 +1,917 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date June 2022
|
||||
* @brief Color objects, customize for your use
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
* The Color object is an object with a present-value that
|
||||
* uses an x,y color single precision floating point data type.
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright (C) 2022 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/bactext.h"
|
||||
#include "bacnet/cov.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/abort.h"
|
||||
#include "bacnet/lighting.h"
|
||||
#include "bacnet/reject.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* me! */
|
||||
#include "color_object.h"
|
||||
|
||||
struct object_data {
|
||||
bool Changed : 1;
|
||||
bool Write_Enabled : 1;
|
||||
BACNET_XY_COLOR Present_Value;
|
||||
BACNET_XY_COLOR Tracking_Value;
|
||||
BACNET_COLOR_COMMAND Color_Command;
|
||||
BACNET_COLOR_OPERATION_IN_PROGRESS In_Progress;
|
||||
BACNET_XY_COLOR Default_Color;
|
||||
uint32_t Default_Fade_Time;
|
||||
BACNET_COLOR_TRANSITION Transition;
|
||||
const char *Object_Name;
|
||||
const char *Description;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
/* callback for present value writes */
|
||||
static color_write_present_value_callback Color_Write_Present_Value_Callback;
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Color_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_TRACKING_VALUE,
|
||||
PROP_COLOR_COMMAND, PROP_IN_PROGRESS, PROP_DEFAULT_COLOR,
|
||||
PROP_DEFAULT_FADE_TIME, -1 };
|
||||
|
||||
static const int Color_Properties_Optional[] = { PROP_DESCRIPTION,
|
||||
PROP_TRANSITION, -1 };
|
||||
|
||||
static const int Color_Properties_Proprietary[] = { -1 };
|
||||
|
||||
/**
|
||||
* Returns the list of required, optional, and proprietary properties.
|
||||
* Used by ReadPropertyMultiple service.
|
||||
*
|
||||
* @param pRequired - pointer to list of int terminated by -1, of
|
||||
* BACnet required properties for this object.
|
||||
* @param pOptional - pointer to list of int terminated by -1, of
|
||||
* BACnet optkional properties for this object.
|
||||
* @param pProprietary - pointer to list of int terminated by -1, of
|
||||
* BACnet proprietary properties for this object.
|
||||
*/
|
||||
void Color_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||
{
|
||||
if (pRequired) {
|
||||
*pRequired = Color_Properties_Required;
|
||||
}
|
||||
if (pOptional) {
|
||||
*pOptional = Color_Properties_Optional;
|
||||
}
|
||||
if (pProprietary) {
|
||||
*pProprietary = Color_Properties_Proprietary;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a given Color instance is valid
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
*
|
||||
* @return true if the instance is valid, and false if not
|
||||
*/
|
||||
bool Color_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the number of Color objects
|
||||
*
|
||||
* @return Number of Color objects
|
||||
*/
|
||||
unsigned Color_Count(void)
|
||||
{
|
||||
return Keylist_Count(Object_List);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the object instance-number for a given 0..N index
|
||||
* of Color objects where N is Color_Count().
|
||||
*
|
||||
* @param index - 0..N where N is Color_Count()
|
||||
*
|
||||
* @return object instance-number for the given index
|
||||
*/
|
||||
uint32_t Color_Index_To_Instance(unsigned index)
|
||||
{
|
||||
return Keylist_Key(Object_List, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, determines a 0..N index
|
||||
* of Color objects where N is Color_Count().
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
*
|
||||
* @return index for the given instance-number, or Color_Count()
|
||||
* if not valid.
|
||||
*/
|
||||
unsigned Color_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
return Keylist_Index(Object_List, object_instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, determines the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
*
|
||||
* @return present-value of the object
|
||||
*/
|
||||
bool Color_Present_Value(uint32_t object_instance, BACNET_XY_COLOR *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
xy_color_copy(value, &pObject->Present_Value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - floating point Color
|
||||
*
|
||||
* @return true if values are within range and present-value is set.
|
||||
*/
|
||||
bool Color_Present_Value_Set(uint32_t object_instance, BACNET_XY_COLOR *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
xy_color_copy(&pObject->Present_Value, value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - floating point Color
|
||||
* @param priority - priority-array index value 1..16
|
||||
* @param error_class - the BACnet error class
|
||||
* @param error_code - BACnet Error code
|
||||
*
|
||||
* @return true if values are within range and present-value is set.
|
||||
*/
|
||||
static bool Color_Present_Value_Write(uint32_t object_instance,
|
||||
BACNET_XY_COLOR *value,
|
||||
uint8_t priority,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
BACNET_XY_COLOR old_value = { 0.0, 0.0 };
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
(void)priority;
|
||||
if (pObject->Write_Enabled) {
|
||||
xy_color_copy(&old_value, &pObject->Present_Value);
|
||||
xy_color_copy(&pObject->Present_Value, value);
|
||||
if (Color_Write_Present_Value_Callback) {
|
||||
Color_Write_Present_Value_Callback(
|
||||
object_instance, &old_value, value);
|
||||
}
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_OBJECT;
|
||||
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, determines the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
*
|
||||
* @return present-value of the object
|
||||
*/
|
||||
bool Color_Tracking_Value(uint32_t object_instance, BACNET_XY_COLOR *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
xy_color_copy(value, &pObject->Tracking_Value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - floating point Color
|
||||
*
|
||||
* @return true if values are within range and present-value is set.
|
||||
*/
|
||||
bool Color_Tracking_Value_Set(uint32_t object_instance, BACNET_XY_COLOR *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
xy_color_copy(&pObject->Tracking_Value, value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, gets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - color command data
|
||||
* @return true if the property value is copied
|
||||
*/
|
||||
bool Color_Command(uint32_t object_instance, BACNET_COLOR_COMMAND *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject && value) {
|
||||
color_command_copy(value, &pObject->Color_Command);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - color command data
|
||||
* @return true if values are within range and value is set.
|
||||
*/
|
||||
bool Color_Command_Set(uint32_t object_instance, BACNET_COLOR_COMMAND *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject && value) {
|
||||
color_command_copy(&pObject->Color_Command, value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, gets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @return property value
|
||||
*/
|
||||
BACNET_COLOR_OPERATION_IN_PROGRESS Color_In_Progress(uint32_t object_instance)
|
||||
{
|
||||
BACNET_COLOR_OPERATION_IN_PROGRESS value =
|
||||
BACNET_COLOR_OPERATION_IN_PROGRESS_MAX;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
value = pObject->In_Progress;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - BACNET_COLOR_OPERATION_IN_PROGRESS
|
||||
* @return true if values are within range and value is set.
|
||||
*/
|
||||
bool Color_In_Progress_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_OPERATION_IN_PROGRESS value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
if (value < BACNET_COLOR_OPERATION_IN_PROGRESS_MAX) {
|
||||
pObject->In_Progress = value;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, determines the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
*
|
||||
* @return present-value of the object
|
||||
*/
|
||||
bool Color_Default_Color(uint32_t object_instance, BACNET_XY_COLOR *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
xy_color_copy(value, &pObject->Default_Color);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the present-value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - floating point Color
|
||||
*
|
||||
* @return true if values are within range and present-value is set.
|
||||
*/
|
||||
bool Color_Default_Color_Set(uint32_t object_instance, BACNET_XY_COLOR *value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
xy_color_copy(&pObject->Default_Color, value);
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, gets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @return property value
|
||||
*/
|
||||
uint32_t Color_Default_Fade_Time(uint32_t object_instance)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
value = pObject->Default_Fade_Time;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - BACNET_COLOR_OPERATION_IN_PROGRESS
|
||||
* @return true if values are within range and value is set.
|
||||
*/
|
||||
bool Color_Default_Fade_Time_Set(uint32_t object_instance, uint32_t value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
if ((value == 0) ||
|
||||
((value >= BACNET_COLOR_FADE_TIME_MIN) &&
|
||||
(value <= BACNET_COLOR_FADE_TIME_MAX))) {
|
||||
pObject->Default_Fade_Time = value;
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, gets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @return property value
|
||||
*/
|
||||
BACNET_COLOR_TRANSITION Color_Transition(uint32_t object_instance)
|
||||
{
|
||||
BACNET_COLOR_TRANSITION value = BACNET_COLOR_OPERATION_IN_PROGRESS_MAX;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
value = pObject->Transition;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the property value
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - BACNET_COLOR_TRANSITION
|
||||
* @return true if values are within range and value is set.
|
||||
*/
|
||||
bool Color_Transition_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_TRANSITION value)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
if (value < BACNET_COLOR_TRANSITION_MAX) {
|
||||
pObject->Transition = value;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, loads the object-name into
|
||||
* a characterstring. Note that the object name must be unique
|
||||
* within this device.
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param object_name - holds the object-name retrieved
|
||||
*
|
||||
* @return true if object-name was retrieved
|
||||
*/
|
||||
bool Color_Object_Name(
|
||||
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject;
|
||||
char name_text[16] = "COLOR-4194303";
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
if (pObject->Object_Name) {
|
||||
status =
|
||||
characterstring_init_ansi(object_name, pObject->Object_Name);
|
||||
} else {
|
||||
snprintf(name_text, sizeof(name_text), "COLOR-%u", object_instance);
|
||||
status = characterstring_init_ansi(object_name, name_text);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the object-name
|
||||
* Note that the object name must be unique within this device.
|
||||
*
|
||||
* @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 Color_Name_Set(uint32_t object_instance, char *new_name)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
BACNET_CHARACTER_STRING object_name;
|
||||
BACNET_OBJECT_TYPE found_type = 0;
|
||||
uint32_t found_instance = 0;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject && new_name) {
|
||||
/* All the object names in a device must be unique */
|
||||
characterstring_init_ansi(&object_name, new_name);
|
||||
if (Device_Valid_Object_Name(
|
||||
&object_name, &found_type, &found_instance)) {
|
||||
if ((found_type == OBJECT_COLOR) &&
|
||||
(found_instance == object_instance)) {
|
||||
/* writing same name to same object */
|
||||
status = true;
|
||||
} else {
|
||||
/* duplicate name! */
|
||||
status = false;
|
||||
}
|
||||
} else {
|
||||
status = true;
|
||||
pObject->Object_Name = new_name;
|
||||
Device_Inc_Database_Revision();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 *Color_Description(uint32_t object_instance)
|
||||
{
|
||||
char *name = NULL;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
if (pObject->Description) {
|
||||
name = (char *)pObject->Description;
|
||||
} else {
|
||||
name = "";
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Color_Description_Set(uint32_t object_instance, char *new_name)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject && new_name) {
|
||||
status = true;
|
||||
pObject->Description = new_name;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ReadProperty handler for this object. For the given ReadProperty
|
||||
* data, the application_data is loaded or the error flags are set.
|
||||
*
|
||||
* @param rpdata - BACNET_READ_PROPERTY_DATA data, including
|
||||
* requested data and space for the reply, or error response.
|
||||
*
|
||||
* @return number of APDU bytes in the response, or
|
||||
* BACNET_STATUS_ERROR on error.
|
||||
*/
|
||||
int Color_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
uint8_t *apdu = NULL;
|
||||
BACNET_XY_COLOR color_value = { 0.0, 0.0 };
|
||||
BACNET_COLOR_COMMAND color_command = { 0 };
|
||||
|
||||
if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
|
||||
(rpdata->application_data_len == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], rpdata->object_type, rpdata->object_instance);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
Color_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], rpdata->object_type);
|
||||
break;
|
||||
case PROP_PRESENT_VALUE:
|
||||
if (Color_Present_Value(rpdata->object_instance, &color_value)) {
|
||||
apdu_len = xy_color_encode(apdu, &color_value);
|
||||
}
|
||||
break;
|
||||
case PROP_TRACKING_VALUE:
|
||||
if (Color_Tracking_Value(rpdata->object_instance, &color_value)) {
|
||||
apdu_len = xy_color_encode(apdu, &color_value);
|
||||
}
|
||||
break;
|
||||
case PROP_COLOR_COMMAND:
|
||||
if (Color_Command(rpdata->object_instance, &color_command)) {
|
||||
apdu_len = color_command_encode(apdu, &color_command);
|
||||
}
|
||||
break;
|
||||
case PROP_IN_PROGRESS:
|
||||
apdu_len = encode_application_enumerated(
|
||||
apdu, Color_In_Progress(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_DEFAULT_COLOR:
|
||||
if (Color_Default_Color(rpdata->object_instance, &color_value)) {
|
||||
apdu_len = xy_color_encode(apdu, &color_value);
|
||||
}
|
||||
break;
|
||||
case PROP_DEFAULT_FADE_TIME:
|
||||
apdu_len = encode_application_unsigned(
|
||||
apdu, Color_Default_Fade_Time(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_TRANSITION:
|
||||
apdu_len = encode_application_enumerated(
|
||||
apdu, Color_Transition(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(
|
||||
&char_string, Color_Description(rpdata->object_instance));
|
||||
apdu_len = encode_application_character_string(apdu, &char_string);
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
break;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((apdu_len >= 0) && (rpdata->object_property != PROP_PRIORITY_ARRAY) &&
|
||||
(rpdata->object_property != PROP_EVENT_TIME_STAMPS) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* WriteProperty handler for this object. For the given WriteProperty
|
||||
* data, the application_data is loaded or the error flags are set.
|
||||
*
|
||||
* @param wp_data - BACNET_WRITE_PROPERTY_DATA data, including
|
||||
* requested data and space for the reply, or error response.
|
||||
*
|
||||
* @return false if an error is loaded, true if no errors
|
||||
*/
|
||||
bool Color_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
|
||||
/* decode the some of the request */
|
||||
len = bacapp_decode_application_data(
|
||||
wp_data->application_data, wp_data->application_data_len, &value);
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
if ((wp_data->object_property != PROP_PRIORITY_ARRAY) &&
|
||||
(wp_data->object_property != PROP_EVENT_TIME_STAMPS) &&
|
||||
(wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
/* only array properties can have array options */
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
case PROP_PRESENT_VALUE:
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_REAL);
|
||||
if (status) {
|
||||
status = Color_Present_Value_Write(wp_data->object_instance,
|
||||
&value.type.XY_Color, wp_data->priority,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
case PROP_OBJECT_TYPE:
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a callback used when present-value is written from BACnet
|
||||
* @param cb - callback used to provide indications
|
||||
*/
|
||||
void Color_Write_Present_Value_Callback_Set(
|
||||
color_write_present_value_callback cb)
|
||||
{
|
||||
Color_Write_Present_Value_Callback = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines a object write-enabled flag state
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @return write-enabled status flag
|
||||
*/
|
||||
bool Color_Write_Enabled(uint32_t object_instance)
|
||||
{
|
||||
bool value = false;
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
value = pObject->Write_Enabled;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For a given object instance-number, sets the write-enabled flag
|
||||
* @param object_instance - object-instance number of the object
|
||||
*/
|
||||
void Color_Write_Enable(uint32_t object_instance)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
pObject->Write_Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For a given object instance-number, clears the write-enabled flag
|
||||
* @param object_instance - object-instance number of the object
|
||||
*/
|
||||
void Color_Write_Disable(uint32_t object_instance)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
pObject->Write_Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Color object
|
||||
* @param object_instance - object-instance number of the object
|
||||
*/
|
||||
bool Color_Create(uint32_t object_instance)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject = NULL;
|
||||
int index = 0;
|
||||
|
||||
pObject = Keylist_Data(Object_List, object_instance);
|
||||
if (!pObject) {
|
||||
pObject = calloc(1, sizeof(struct object_data));
|
||||
if (pObject) {
|
||||
pObject->Object_Name = NULL;
|
||||
pObject->Present_Value.x_coordinate = 0.0;
|
||||
pObject->Present_Value.y_coordinate = 0.0;
|
||||
pObject->Tracking_Value.x_coordinate = 0.0;
|
||||
pObject->Tracking_Value.y_coordinate = 0.0;
|
||||
pObject->Color_Command.operation = BACNET_COLOR_OPERATION_NONE;
|
||||
pObject->In_Progress = BACNET_COLOR_OPERATION_IN_PROGRESS_IDLE;
|
||||
pObject->Default_Color.x_coordinate = 1.0;
|
||||
pObject->Default_Color.y_coordinate = 1.0;
|
||||
pObject->Default_Fade_Time = 0;
|
||||
pObject->Transition = BACNET_COLOR_TRANSITION_NONE;
|
||||
pObject->Changed = false;
|
||||
pObject->Write_Enabled = false;
|
||||
/* add to list */
|
||||
index = Keylist_Data_Add(Object_List, object_instance, pObject);
|
||||
if (index >= 0) {
|
||||
status = true;
|
||||
Device_Inc_Database_Revision();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an Color object
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @return true if the object is deleted
|
||||
*/
|
||||
bool Color_Delete(uint32_t object_instance)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_data *pObject = NULL;
|
||||
|
||||
pObject = Keylist_Data_Delete(Object_List, object_instance);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
status = true;
|
||||
Device_Inc_Database_Revision();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all the Colors and their data
|
||||
*/
|
||||
void Color_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
Device_Inc_Database_Revision();
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Color object data
|
||||
*/
|
||||
void Color_Init(void)
|
||||
{
|
||||
Object_List = Keylist_Create();
|
||||
if (Object_List) {
|
||||
atexit(Color_Cleanup);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date June 2022
|
||||
* @brief Color object, customize for your use
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
* The Color object is an object with a present-value that
|
||||
* uses an x,y color single precision floating point data type.
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright (C) 2022 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef BACNET_COLOR_OBJECT_H
|
||||
#define BACNET_COLOR_OBJECT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacnet/bacnet_stack_exports.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
/**
|
||||
* @brief Callback for gateway write present value request
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param old_value - BACnetXYColor value prior to write
|
||||
* @param value - BACnetXYColor value of the write
|
||||
*/
|
||||
typedef void (*color_write_present_value_callback)(uint32_t object_instance,
|
||||
BACNET_XY_COLOR *old_value,
|
||||
BACNET_XY_COLOR *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Valid_Instance(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
unsigned Color_Count(void);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Index_To_Instance(unsigned index);
|
||||
BACNET_STACK_EXPORT
|
||||
unsigned Color_Instance_To_Index(uint32_t object_instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Object_Name(
|
||||
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Name_Set(uint32_t object_instance, char *new_name);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int Color_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Present_Value_Set(uint32_t object_instance, BACNET_XY_COLOR *value);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Present_Value(uint32_t object_instance, BACNET_XY_COLOR *value);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Write_Present_Value_Callback_Set(
|
||||
color_write_present_value_callback cb);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Tracking_Value_Set(uint32_t object_instance, BACNET_XY_COLOR *value);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Tracking_Value(uint32_t object_instance, BACNET_XY_COLOR *value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Command(uint32_t object_instance, BACNET_COLOR_COMMAND *value);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Command_Set(uint32_t object_instance, BACNET_COLOR_COMMAND *value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Default_Color_Set(uint32_t object_instance, BACNET_XY_COLOR *value);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Default_Color(uint32_t object_instance, BACNET_XY_COLOR *value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Default_Fade_Time(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Default_Fade_Time_Set(uint32_t object_instance, uint32_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
BACNET_COLOR_OPERATION_IN_PROGRESS Color_In_Progress(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_In_Progress_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_OPERATION_IN_PROGRESS value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
BACNET_COLOR_TRANSITION Color_Transition(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Transition_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_TRANSITION value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
char *Color_Description(uint32_t instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Description_Set(uint32_t instance, char *new_name);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Write_Enabled(uint32_t instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Write_Enable(uint32_t instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Write_Disable(uint32_t instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Create(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Delete(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Cleanup(void);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date July 2022
|
||||
* @brief Color Temperature object, customize for your use
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
* The Color Temperature object is an object with a present-value that
|
||||
* uses an Color Temperature INTEGER type
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright (C) 2022 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef BACNET_COLOR_TEMPERATURE_H
|
||||
#define BACNET_COLOR_TEMPERATURE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacnet/bacnet_stack_exports.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
/**
|
||||
* @brief Callback for gateway write present value request
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param old_value - 32-bit value prior to write
|
||||
* @param value - 32-bit value of the write
|
||||
*/
|
||||
typedef void (*color_temperature_write_present_value_callback)(
|
||||
uint32_t object_instance, uint32_t old_value, uint32_t value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Temperature_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Valid_Instance(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
unsigned Color_Temperature_Count(void);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Index_To_Instance(unsigned index);
|
||||
BACNET_STACK_EXPORT
|
||||
unsigned Color_Temperature_Instance_To_Index(uint32_t object_instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Object_Name(
|
||||
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Name_Set(uint32_t object_instance, char *new_name);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int Color_Temperature_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Present_Value_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Present_Value(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Temperature_Write_Present_Value_Callback_Set(
|
||||
color_temperature_write_present_value_callback cb);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Tracking_Value_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Tracking_Value(uint32_t object_instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Min_Pres_Value(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Min_Pres_Value_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Max_Pres_Value(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Max_Pres_Value_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Command(
|
||||
uint32_t object_instance, BACNET_COLOR_COMMAND *value);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Command_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_COMMAND *value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Default_Color_Temperature_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Default_Color_Temperature(uint32_t object_instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Default_Fade_Time(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Default_Fade_Time_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Default_Ramp_Rate(
|
||||
uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Default_Ramp_Rate_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Color_Temperature_Default_Step_Increment(
|
||||
uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Default_Step_Increment_Set(
|
||||
uint32_t object_instance, uint32_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
BACNET_COLOR_OPERATION_IN_PROGRESS Color_Temperature_In_Progress(
|
||||
uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_In_Progress_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_OPERATION_IN_PROGRESS value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
BACNET_COLOR_TRANSITION Color_Temperature_Transition(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Transition_Set(
|
||||
uint32_t object_instance, BACNET_COLOR_TRANSITION value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
char *Color_Temperature_Description(uint32_t instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Description_Set(uint32_t instance, char *new_name);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Write_Enabled(uint32_t instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Temperature_Write_Enable(uint32_t instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Temperature_Write_Disable(uint32_t instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Create(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Color_Temperature_Delete(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Temperature_Cleanup(void);
|
||||
BACNET_STACK_EXPORT
|
||||
void Color_Temperature_Init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
@@ -75,6 +75,10 @@
|
||||
#if defined(BACFILE)
|
||||
#include "bacnet/basic/object/bacfile.h"
|
||||
#endif /* defined(BACFILE) */
|
||||
#if (BACNET_PROTOCOL_REVISION >= 24)
|
||||
#include "bacnet/basic/object/color_object.h"
|
||||
#include "bacnet/basic/object/color_temperature.h"
|
||||
#endif
|
||||
|
||||
/* local forward (semi-private) and external prototypes */
|
||||
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
|
||||
@@ -223,6 +227,20 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ },
|
||||
#endif
|
||||
#if (BACNET_PROTOCOL_REVISION >= 24)
|
||||
{ OBJECT_COLOR, Color_Init, Color_Count,
|
||||
Color_Index_To_Instance, Color_Valid_Instance,
|
||||
Color_Object_Name, Color_Read_Property,
|
||||
Color_Write_Property, Color_Property_Lists,
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ },
|
||||
{ OBJECT_COLOR_TEMPERATURE, Color_Temperature_Init, Color_Temperature_Count,
|
||||
Color_Temperature_Index_To_Instance, Color_Temperature_Valid_Instance,
|
||||
Color_Temperature_Object_Name, Color_Temperature_Read_Property,
|
||||
Color_Temperature_Write_Property, Color_Temperature_Property_Lists,
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ },
|
||||
#endif
|
||||
#if defined(BACFILE)
|
||||
{ OBJECT_FILE, bacfile_init, bacfile_count, bacfile_index_to_instance,
|
||||
bacfile_valid_instance, bacfile_object_name, bacfile_read_property,
|
||||
@@ -1312,6 +1330,91 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/** Looks up the common Object and Property, and encodes its Value in an
|
||||
* APDU. Sets the error class and code if request is not appropriate.
|
||||
* @param pObject - object table
|
||||
* @param rpdata [in,out] Structure with the requested Object & Property info
|
||||
* on entry, and APDU message on return.
|
||||
* @return The length of the APDU on success, else BACNET_STATUS_ERROR
|
||||
*/
|
||||
static int Read_Property_Common(
|
||||
struct object_functions *pObject, BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = BACNET_STATUS_ERROR;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
uint8_t *apdu = NULL;
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
struct special_property_list_t property_list;
|
||||
#endif
|
||||
|
||||
if ((rpdata->application_data == NULL) ||
|
||||
(rpdata->application_data_len == 0)) {
|
||||
return 0;
|
||||
}
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
/* only array properties can have array options */
|
||||
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
} else {
|
||||
/* Device Object exception: requested instance
|
||||
may not match our instance if a wildcard */
|
||||
if (rpdata->object_type == OBJECT_DEVICE) {
|
||||
rpdata->object_instance = Object_Instance_Number;
|
||||
}
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], rpdata->object_type, rpdata->object_instance);
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
/* only array properties can have array options */
|
||||
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
} else {
|
||||
characterstring_init_ansi(&char_string, "");
|
||||
if (pObject->Object_Name) {
|
||||
(void)pObject->Object_Name(
|
||||
rpdata->object_instance, &char_string);
|
||||
}
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
/* only array properties can have array options */
|
||||
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
} else {
|
||||
apdu_len = encode_application_enumerated(
|
||||
&apdu[0], rpdata->object_type);
|
||||
}
|
||||
break;
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
case PROP_PROPERTY_LIST:
|
||||
Device_Objects_Property_List(
|
||||
rpdata->object_type, rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(rpdata,
|
||||
property_list.Required.pList, property_list.Optional.pList,
|
||||
property_list.Proprietary.pList);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (pObject->Object_Read_Property) {
|
||||
apdu_len = pObject->Object_Read_Property(rpdata);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/** Looks up the requested Object and Property, and encodes its Value in an
|
||||
* APDU.
|
||||
* @ingroup ObjIntf
|
||||
@@ -1325,9 +1428,6 @@ int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
{
|
||||
int apdu_len = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
struct special_property_list_t property_list;
|
||||
#endif
|
||||
|
||||
/* initialize the default return values */
|
||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
||||
@@ -1336,22 +1436,14 @@ int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
if (pObject != NULL) {
|
||||
if (pObject->Object_Valid_Instance &&
|
||||
pObject->Object_Valid_Instance(rpdata->object_instance)) {
|
||||
if (pObject->Object_Read_Property) {
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
if ((int)rpdata->object_property == PROP_PROPERTY_LIST) {
|
||||
Device_Objects_Property_List(rpdata->object_type,
|
||||
rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(rpdata,
|
||||
property_list.Required.pList,
|
||||
property_list.Optional.pList,
|
||||
property_list.Proprietary.pList);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
apdu_len = pObject->Object_Read_Property(rpdata);
|
||||
}
|
||||
}
|
||||
apdu_len = Read_Property_Common(pObject, rpdata);
|
||||
} else {
|
||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
}
|
||||
} else {
|
||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
@@ -1816,6 +1908,9 @@ void Device_Init(object_functions_t *object_table)
|
||||
}
|
||||
pObject++;
|
||||
}
|
||||
#if (BACNET_PROTOCOL_REVISION >= 24)
|
||||
Color_Create(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
|
||||
|
||||
Reference in New Issue
Block a user