Feature/raspberry pi blinkt color objects (#503)

* fixed BACnetXYcolor and BACnetColorCommand encode and decoding and improved unit test coverage. Refactored BACnetXYcolor to/from ascii into lighting module.

* added to the color, color temperature, and lighting output objects a fade/ramp/step engine.  Added color and color command coercion into the channel object and enabled color temperature object coercion.  Added CreateObject and DeleteObject service handling to the color, color temperature, lighting output, and channel objects.

* added blinkt demo app for Raspberry Pi [WIP]

* updated gitignore to simplify handling of apps folder contents

* fixed piface demo build

* added RaspiOS to pipeline for piface and blinkt! demo builds

* added device object timer function for child object types into example Device object.  Refactored device object to increment database revision for create or delete object services.   Refactored example app/server to use mstimer library and device child object timers.

---------

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2023-09-28 10:50:32 -05:00
committed by GitHub
parent b0749572f6
commit da2dc9841a
64 changed files with 8012 additions and 1637 deletions
+63 -31
View File
@@ -99,7 +99,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
#if (BACNET_PROTOCOL_REVISION >= 17)
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
@@ -108,7 +108,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
#endif
{ OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
@@ -118,7 +118,7 @@ static object_functions_t My_Object_Table[] = {
Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value,
Analog_Input_Change_Of_Value_Clear, Analog_Input_Intrinsic_Reporting,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
{ OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count,
Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance,
Analog_Output_Object_Name, Analog_Output_Read_Property,
@@ -126,7 +126,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
Analog_Output_Create, Analog_Output_Delete},
Analog_Output_Create, Analog_Output_Delete, NULL /* Timer */},
{ OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
Analog_Value_Object_Name, Analog_Value_Read_Property,
@@ -135,7 +135,7 @@ static object_functions_t My_Object_Table[] = {
Analog_Value_Encode_Value_List, Analog_Value_Change_Of_Value,
Analog_Value_Change_Of_Value_Clear, Analog_Value_Intrinsic_Reporting,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
Binary_Input_Object_Name, Binary_Input_Read_Property,
@@ -144,7 +144,7 @@ static object_functions_t My_Object_Table[] = {
Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value,
Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
Binary_Output_Object_Name, Binary_Output_Read_Property,
@@ -152,7 +152,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
Binary_Output_Create, Binary_Output_Delete},
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */},
{ OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count,
Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance,
Binary_Value_Object_Name, Binary_Value_Read_Property,
@@ -160,7 +160,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_CHARACTERSTRING_VALUE, CharacterString_Value_Init,
CharacterString_Value_Count, CharacterString_Value_Index_To_Instance,
CharacterString_Value_Valid_Instance, CharacterString_Value_Object_Name,
@@ -172,14 +172,14 @@ static object_functions_t My_Object_Table[] = {
CharacterString_Value_Change_Of_Value_Clear,
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_COMMAND, Command_Init, Command_Count, Command_Index_To_Instance,
Command_Valid_Instance, Command_Object_Name, Command_Read_Property,
Command_Write_Property, Command_Property_Lists,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_INTEGER_VALUE, Integer_Value_Init, Integer_Value_Count,
Integer_Value_Index_To_Instance, Integer_Value_Valid_Instance,
Integer_Value_Object_Name, Integer_Value_Read_Property,
@@ -187,7 +187,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
#if defined(INTRINSIC_REPORTING)
{ OBJECT_NOTIFICATION_CLASS, Notification_Class_Init,
Notification_Class_Count, Notification_Class_Index_To_Instance,
@@ -198,7 +198,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
Notification_Class_Add_List_Element,
Notification_Class_Remove_List_Element,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
#endif
{ OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init, Life_Safety_Point_Count,
Life_Safety_Point_Index_To_Instance, Life_Safety_Point_Valid_Instance,
@@ -207,7 +207,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
{ OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count,
Load_Control_Index_To_Instance, Load_Control_Valid_Instance,
Load_Control_Object_Name, Load_Control_Read_Property,
@@ -215,7 +215,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
{ OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, Multistate_Input_Count,
Multistate_Input_Index_To_Instance, Multistate_Input_Valid_Instance,
Multistate_Input_Object_Name, Multistate_Input_Read_Property,
@@ -223,7 +223,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
{ OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init,
Multistate_Output_Count, Multistate_Output_Index_To_Instance,
Multistate_Output_Valid_Instance, Multistate_Output_Object_Name,
@@ -232,7 +232,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
Multistate_Output_Create, Multistate_Output_Delete},
Multistate_Output_Create, Multistate_Output_Delete, NULL /* Timer */},
{ OBJECT_MULTI_STATE_VALUE, Multistate_Value_Init, Multistate_Value_Count,
Multistate_Value_Index_To_Instance, Multistate_Value_Valid_Instance,
Multistate_Value_Object_Name, Multistate_Value_Read_Property,
@@ -241,7 +241,7 @@ static object_functions_t My_Object_Table[] = {
Multistate_Value_Encode_Value_List, Multistate_Value_Change_Of_Value,
Multistate_Value_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
{ OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count,
Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance,
Trend_Log_Object_Name, Trend_Log_Read_Property,
@@ -249,7 +249,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
#if (BACNET_PROTOCOL_REVISION >= 14)
{ OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count,
Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance,
@@ -258,14 +258,14 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
Lighting_Output_Create, Lighting_Output_Delete, Lighting_Output_Timer},
{ OBJECT_CHANNEL, Channel_Init, Channel_Count, Channel_Index_To_Instance,
Channel_Valid_Instance, Channel_Object_Name, Channel_Read_Property,
Channel_Write_Property, Channel_Property_Lists,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
Channel_Create, Channel_Delete, NULL /* Timer */ },
#endif
#if (BACNET_PROTOCOL_REVISION >= 24)
{ OBJECT_COLOR, Color_Init, Color_Count, Color_Index_To_Instance,
@@ -274,7 +274,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
Color_Create, Color_Delete},
Color_Create, Color_Delete, Color_Timer},
{ 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,
@@ -282,7 +282,8 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
Color_Temperature_Create, Color_Temperature_Delete},
Color_Temperature_Create, Color_Temperature_Delete,
Color_Temperature_Timer},
#endif
#if defined(BACFILE)
{ OBJECT_FILE, bacfile_init, bacfile_count, bacfile_index_to_instance,
@@ -291,7 +292,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
bacfile_create, bacfile_delete},
bacfile_create, bacfile_delete, NULL /* Timer */},
#endif
{ OBJECT_OCTETSTRING_VALUE, OctetString_Value_Init, OctetString_Value_Count,
OctetString_Value_Index_To_Instance, OctetString_Value_Valid_Instance,
@@ -300,7 +301,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_POSITIVE_INTEGER_VALUE, PositiveInteger_Value_Init,
PositiveInteger_Value_Count, PositiveInteger_Value_Index_To_Instance,
PositiveInteger_Value_Valid_Instance, PositiveInteger_Value_Object_Name,
@@ -310,7 +311,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_SCHEDULE, Schedule_Init, Schedule_Count,
Schedule_Index_To_Instance, Schedule_Valid_Instance,
Schedule_Object_Name, Schedule_Read_Property, Schedule_Write_Property,
@@ -318,7 +319,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
{ OBJECT_ACCUMULATOR, Accumulator_Init, Accumulator_Count,
Accumulator_Index_To_Instance, Accumulator_Valid_Instance,
Accumulator_Object_Name, Accumulator_Read_Property,
@@ -326,7 +327,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
NULL /* Object_Name */, NULL /* Read_Property */,
@@ -334,7 +335,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
NULL /* Create */, NULL /* Delete */ },
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
};
/** Glue function to let the Device object, when called by a handler,
@@ -545,7 +546,7 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
bool status = false;
/* From 16.4.1.1.2 Password
This optional parameter shall be a CharacterString of up to
This optional parameter shall be a CharacterString of up to
20 characters. For those devices that require the password as a
protection, the service request shall be denied if the parameter
is absent or if the password is incorrect. For those devices that
@@ -554,7 +555,7 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
rd_data->error_class = ERROR_CLASS_SERVICES;
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
} else if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
/* Note: you could use a mix of state and password to
/* Note: you could use a mix of state and password to
accomplish multiple things before restarting */
switch (rd_data->state) {
case BACNET_REINIT_COLDSTART:
@@ -1976,6 +1977,7 @@ bool Device_Create_Object(
} else {
/* required by ACK */
data->object_instance = object_instance;
Device_Inc_Database_Revision();
status = true;
}
}
@@ -2013,7 +2015,9 @@ bool Device_Delete_Object(
pObject->Object_Valid_Instance(data->object_instance)) {
/* The object being deleted must already exist */
status = pObject->Object_Delete(data->object_instance);
if (!status) {
if (status) {
Device_Inc_Database_Revision();
} else {
/* The object exists but cannot be deleted. */
data->error_class = ERROR_CLASS_OBJECT;
data->error_code = ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED;
@@ -2154,6 +2158,34 @@ bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
return status;
}
/**
* @brief Updates all the object timers with elapsed milliseconds
* @param milliseconds - number of milliseconds elapsed
*/
void Device_Timer(
uint16_t milliseconds)
{
struct object_functions *pObject;
unsigned count = 0;
uint32_t instance;
pObject = Object_Table;
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if (pObject->Object_Count) {
count = pObject->Object_Count();
}
while (count) {
count--;
if ((pObject->Object_Timer) &&
(pObject->Object_Index_To_Instance)) {
instance = pObject->Object_Index_To_Instance(count);
pObject->Object_Timer(instance, milliseconds);
}
}
pObject++;
}
}
#ifdef BAC_ROUTING
/****************************************************************************
************* BACnet Routing Functionality (Optional) **********************