Feature/add bacnet binary lighting object (#522)
* Added Binary Lighting Output object example. * Changed piface example app to support binary-lighting-output object type and blink warn * Changed example device object to not create objects when device object-table is overridden * Fixed unit testing for device object
This commit is contained in:
@@ -188,6 +188,8 @@ add_library(${PROJECT_NAME}
|
|||||||
src/bacnet/basic/object/bacfile.h
|
src/bacnet/basic/object/bacfile.h
|
||||||
src/bacnet/basic/object/bi.c
|
src/bacnet/basic/object/bi.c
|
||||||
src/bacnet/basic/object/bi.h
|
src/bacnet/basic/object/bi.h
|
||||||
|
src/bacnet/basic/object/blo.c
|
||||||
|
src/bacnet/basic/object/blo.h
|
||||||
src/bacnet/basic/object/bo.c
|
src/bacnet/basic/object/bo.c
|
||||||
src/bacnet/basic/object/bo.h
|
src/bacnet/basic/object/bo.h
|
||||||
src/bacnet/basic/object/bv.c
|
src/bacnet/basic/object/bv.c
|
||||||
|
|||||||
+1
-4
@@ -118,9 +118,6 @@ static void Init_Service_Handlers(void)
|
|||||||
/* handle communication so we can shutup when asked */
|
/* handle communication so we can shutup when asked */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||||
handler_device_communication_control);
|
handler_device_communication_control);
|
||||||
/* handle the data coming back from private requests */
|
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
|
|
||||||
handler_unconfirmed_private_transfer);
|
|
||||||
/* configure the cyclic timers */
|
/* configure the cyclic timers */
|
||||||
mstimer_set(&BACnet_Task_Timer, 1000UL);
|
mstimer_set(&BACnet_Task_Timer, 1000UL);
|
||||||
mstimer_set(&BACnet_TSM_Timer, 50UL);
|
mstimer_set(&BACnet_TSM_Timer, 50UL);
|
||||||
@@ -297,7 +294,7 @@ static void bacnet_output_init(void)
|
|||||||
Channel_Reference_List_Member_Element_Set(
|
Channel_Reference_List_Member_Element_Set(
|
||||||
light_channel_instance, 1 + i, &member);
|
light_channel_instance, 1 + i, &member);
|
||||||
|
|
||||||
object_instance++;
|
object_instance = 1 + i;
|
||||||
}
|
}
|
||||||
Color_Write_Present_Value_Callback_Set(Color_Write_Value_Handler);
|
Color_Write_Present_Value_Callback_Set(Color_Write_Value_Handler);
|
||||||
Color_Temperature_Write_Present_Value_Callback_Set(
|
Color_Temperature_Write_Present_Value_Callback_Set(
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ BACNET_OBJECT_SRC := \
|
|||||||
$(BACNET_OBJECT_DIR)/ao.c \
|
$(BACNET_OBJECT_DIR)/ao.c \
|
||||||
$(BACNET_OBJECT_DIR)/av.c \
|
$(BACNET_OBJECT_DIR)/av.c \
|
||||||
$(BACNET_OBJECT_DIR)/bi.c \
|
$(BACNET_OBJECT_DIR)/bi.c \
|
||||||
|
$(BACNET_OBJECT_DIR)/blo.c \
|
||||||
$(BACNET_OBJECT_DIR)/bo.c \
|
$(BACNET_OBJECT_DIR)/bo.c \
|
||||||
$(BACNET_OBJECT_DIR)/bv.c \
|
$(BACNET_OBJECT_DIR)/bv.c \
|
||||||
$(BACNET_OBJECT_DIR)/channel.c \
|
$(BACNET_OBJECT_DIR)/channel.c \
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ SRC = main.c \
|
|||||||
device.c \
|
device.c \
|
||||||
$(BACNET_OBJECT_DIR)/netport.c \
|
$(BACNET_OBJECT_DIR)/netport.c \
|
||||||
$(BACNET_OBJECT_DIR)/bi.c \
|
$(BACNET_OBJECT_DIR)/bi.c \
|
||||||
|
$(BACNET_OBJECT_DIR)/blo.c \
|
||||||
$(BACNET_OBJECT_DIR)/bo.c
|
$(BACNET_OBJECT_DIR)/bo.c
|
||||||
|
|
||||||
CFLAGS += -DMAX_TSM_TRANSACTIONS=1
|
CFLAGS += -DMAX_TSM_TRANSACTIONS=1
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
/* include the OS specific */
|
/* include the OS specific */
|
||||||
#include "bacnet/basic/object/device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bacnet/basic/object/bi.h"
|
#include "bacnet/basic/object/bi.h"
|
||||||
|
#include "bacnet/basic/object/blo.h"
|
||||||
#include "bacnet/basic/object/bo.h"
|
#include "bacnet/basic/object/bo.h"
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||||
#include "bacnet/basic/object/netport.h"
|
#include "bacnet/basic/object/netport.h"
|
||||||
@@ -88,6 +89,18 @@ static object_functions_t My_Object_Table[] = {
|
|||||||
Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */,
|
Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */,
|
||||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||||
|
{ OBJECT_BINARY_LIGHTING_OUTPUT, Binary_Lighting_Output_Init,
|
||||||
|
Binary_Lighting_Output_Count, Binary_Lighting_Output_Index_To_Instance,
|
||||||
|
Binary_Lighting_Output_Valid_Instance,
|
||||||
|
Binary_Lighting_Output_Object_Name,
|
||||||
|
Binary_Lighting_Output_Read_Property,
|
||||||
|
Binary_Lighting_Output_Write_Property,
|
||||||
|
Binary_Lighting_Output_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 */,
|
||||||
|
Binary_Lighting_Output_Create, Binary_Lighting_Output_Delete,
|
||||||
|
Binary_Lighting_Output_Timer },
|
||||||
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
|
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
|
||||||
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
||||||
Binary_Output_Object_Name, Binary_Output_Read_Property,
|
Binary_Output_Object_Name, Binary_Output_Read_Property,
|
||||||
@@ -1979,3 +1992,30 @@ bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
|
|||||||
|
|
||||||
return status;
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+150
-67
@@ -1,33 +1,17 @@
|
|||||||
/**************************************************************************
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief
|
||||||
|
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||||
|
* @date January 2023
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
*/
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "bacnet/config.h"
|
#include "bacnet/config.h"
|
||||||
#include "bacnet/basic/binding/address.h"
|
#include "bacnet/basic/binding/address.h"
|
||||||
@@ -39,40 +23,117 @@
|
|||||||
#include "bacnet/npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "bacnet/apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "bacnet/iam.h"
|
#include "bacnet/iam.h"
|
||||||
#include "bacnet/basic/tsm/tsm.h"
|
|
||||||
#include "bacnet/basic/object/device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bacnet/basic/object/bacfile.h"
|
#include "bacnet/basic/object/bacfile.h"
|
||||||
#include "bacnet/datalink/datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "bacnet/dcc.h"
|
#include "bacnet/dcc.h"
|
||||||
#include "bacnet/getevent.h"
|
#include "bacnet/getevent.h"
|
||||||
#include "bacport.h"
|
#include "bacport.h"
|
||||||
#include "bacnet/basic/tsm/tsm.h"
|
#include "bacnet/basic/sys/mstimer.h"
|
||||||
#include "bacnet/basic/tsm/tsm.h"
|
#include "bacnet/basic/tsm/tsm.h"
|
||||||
#include "bacnet/version.h"
|
#include "bacnet/version.h"
|
||||||
/* include the device object */
|
/* include the device object */
|
||||||
#include "bacnet/basic/object/device.h"
|
#include "bacnet/basic/object/device.h"
|
||||||
#include "bacnet/basic/object/bi.h"
|
#include "bacnet/basic/object/bi.h"
|
||||||
|
#include "bacnet/basic/object/blo.h"
|
||||||
#include "bacnet/basic/object/bo.h"
|
#include "bacnet/basic/object/bo.h"
|
||||||
#include "pifacedigital.h"
|
#include "pifacedigital.h"
|
||||||
|
|
||||||
/** @file server/main.c Example server application using the BACnet Stack. */
|
/** @file server/main.c Example server application using the BACnet Stack. */
|
||||||
|
|
||||||
/* (Doxygen note: The next two lines pull all the following Javadoc
|
/* number of binary outputs on the PiFace card */
|
||||||
* into the ServerDemo module.) */
|
#define PIFACE_OUTPUTS_MAX 8
|
||||||
/** @addtogroup ServerDemo */
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/** Buffer used for receiving */
|
/** Buffer used for receiving */
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
/* current version of the BACnet stack */
|
/* current version of the BACnet stack */
|
||||||
static const char *BACnet_Version = BACNET_VERSION_TEXT;
|
static const char *BACnet_Version = BACNET_VERSION_TEXT;
|
||||||
|
/* task timer for various BACnet timeouts */
|
||||||
|
static struct mstimer BACnet_Task_Timer;
|
||||||
|
/* task timer for TSM timeouts */
|
||||||
|
static struct mstimer BACnet_TSM_Timer;
|
||||||
|
/* task timer for address binding timeouts */
|
||||||
|
static struct mstimer BACnet_Address_Timer;
|
||||||
|
/* task timer for object functionality */
|
||||||
|
static struct mstimer BACnet_Object_Timer;
|
||||||
|
/* track the state of of the output */
|
||||||
|
static bool PiFace_Output_State[PIFACE_OUTPUTS_MAX];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief output write value request
|
||||||
|
* @param index - 0..N index of the output
|
||||||
|
* @param value - value of the write ON or OFF
|
||||||
|
*/
|
||||||
|
static void piface_write_output(int index, BACNET_BINARY_LIGHTING_PV value)
|
||||||
|
{
|
||||||
|
if (index < PIFACE_OUTPUTS_MAX) {
|
||||||
|
if (value == BINARY_LIGHTING_PV_OFF) {
|
||||||
|
pifacedigital_digital_write(index, 0);
|
||||||
|
PiFace_Output_State[index] = false;
|
||||||
|
printf("OUTPUT[%u]=OFF\n", index);
|
||||||
|
} else if (value == BINARY_LIGHTING_PV_ON) {
|
||||||
|
pifacedigital_digital_write(index, 1);
|
||||||
|
PiFace_Output_State[index] = true;
|
||||||
|
printf("OUTPUT[%u]=ON\n", index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback for write value request
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
* @param old_value - value prior to write
|
||||||
|
* @param value - value of the write
|
||||||
|
*/
|
||||||
|
static void Binary_Lighting_Output_Write_Value_Handler(uint32_t object_instance,
|
||||||
|
BACNET_BINARY_LIGHTING_PV old_value,
|
||||||
|
BACNET_BINARY_LIGHTING_PV value)
|
||||||
|
{
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
index = Binary_Lighting_Output_Instance_To_Index(object_instance);
|
||||||
|
if (index < PIFACE_OUTPUTS_MAX) {
|
||||||
|
printf("BLO-WRITE: OUTPUT[%u]=%d present=%d feedback=%d target=%d\n",
|
||||||
|
index, (int)value,
|
||||||
|
(int)Binary_Lighting_Output_Present_Value(object_instance),
|
||||||
|
(int)old_value,
|
||||||
|
(int)Binary_Lighting_Output_Lighting_Command_Target_Value(
|
||||||
|
object_instance));
|
||||||
|
piface_write_output(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback for blink warning notification
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
*/
|
||||||
|
static void Binary_Lighting_Output_Blink_Warn_Handler(uint32_t object_instance)
|
||||||
|
{
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
index = Binary_Lighting_Output_Instance_To_Index(object_instance);
|
||||||
|
if (index < PIFACE_OUTPUTS_MAX) {
|
||||||
|
/* blink is just toggle on/off every one second */
|
||||||
|
if (PiFace_Output_State[index]) {
|
||||||
|
printf("BLO-BLINK: OUTPUT[%u]=%d\n", index,
|
||||||
|
BINARY_LIGHTING_PV_OFF);
|
||||||
|
piface_write_output(index, BINARY_LIGHTING_PV_OFF);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"BLO-BLINK: OUTPUT[%u]=%d\n", index, BINARY_LIGHTING_PV_ON);
|
||||||
|
piface_write_output(index, BINARY_LIGHTING_PV_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Initialize the handlers we will utilize.
|
/** Initialize the handlers we will utilize.
|
||||||
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
|
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
|
||||||
*/
|
*/
|
||||||
static void Init_Service_Handlers(void)
|
static void Init_Service_Handlers(void)
|
||||||
{
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint32_t object_instance;
|
||||||
|
|
||||||
Device_Init(NULL);
|
Device_Init(NULL);
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
/* we need to handle who-is to support dynamic device binding */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
@@ -107,9 +168,21 @@ static void Init_Service_Handlers(void)
|
|||||||
/* handle communication so we can shutup when asked */
|
/* handle communication so we can shutup when asked */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||||
handler_device_communication_control);
|
handler_device_communication_control);
|
||||||
/* handle the data coming back from private requests */
|
/* configure the cyclic timers */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
|
mstimer_set(&BACnet_Task_Timer, 1000UL);
|
||||||
handler_unconfirmed_private_transfer);
|
mstimer_set(&BACnet_TSM_Timer, 50UL);
|
||||||
|
mstimer_set(&BACnet_Address_Timer, 60UL * 1000UL);
|
||||||
|
mstimer_set(&BACnet_Object_Timer, 1000UL);
|
||||||
|
/* create some objects */
|
||||||
|
for (i = 0; i < PIFACE_OUTPUTS_MAX; i++) {
|
||||||
|
object_instance = 1 + i;
|
||||||
|
Binary_Lighting_Output_Create(object_instance);
|
||||||
|
Binary_Output_Create(object_instance);
|
||||||
|
}
|
||||||
|
Binary_Lighting_Output_Write_Value_Callback_Set(
|
||||||
|
Binary_Lighting_Output_Write_Value_Handler);
|
||||||
|
Binary_Lighting_Output_Blink_Warn_Callback_Set(
|
||||||
|
Binary_Lighting_Output_Blink_Warn_Handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void piface_init(void)
|
static void piface_init(void)
|
||||||
@@ -159,6 +232,7 @@ static void piface_task(void)
|
|||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
|
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
|
||||||
bool pin_status = false;
|
bool pin_status = false;
|
||||||
|
uint32_t object_instance;
|
||||||
|
|
||||||
for (i = 0; i < MAX_BINARY_INPUTS; i++) {
|
for (i = 0; i < MAX_BINARY_INPUTS; i++) {
|
||||||
if (!Binary_Input_Out_Of_Service(i)) {
|
if (!Binary_Input_Out_Of_Service(i)) {
|
||||||
@@ -181,13 +255,24 @@ static void piface_task(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < MAX_BINARY_OUTPUTS; i++) {
|
for (i = 0; i < PIFACE_OUTPUTS_MAX; i++) {
|
||||||
if (!Binary_Output_Out_Of_Service(i)) {
|
object_instance = Binary_Output_Index_To_Instance(i);
|
||||||
present_value = Binary_Output_Present_Value(i);
|
if (Binary_Output_Valid_Instance(object_instance)) {
|
||||||
if (present_value == BINARY_INACTIVE) {
|
if (!Binary_Output_Out_Of_Service(object_instance)) {
|
||||||
pifacedigital_digital_write(i, 0);
|
present_value = Binary_Output_Present_Value(object_instance);
|
||||||
} else {
|
if (present_value == BINARY_INACTIVE) {
|
||||||
pifacedigital_digital_write(i, 1);
|
if (PiFace_Output_State[i]) {
|
||||||
|
printf("BO-WRITE: OUTPUT[%u]=%d\n", i,
|
||||||
|
BINARY_LIGHTING_PV_OFF);
|
||||||
|
piface_write_output(i, BINARY_LIGHTING_PV_OFF);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!PiFace_Output_State[i]) {
|
||||||
|
printf("BO-WRITE: OUTPUT[%u]=%d\n", i,
|
||||||
|
BINARY_LIGHTING_PV_OFF);
|
||||||
|
piface_write_output(i, BINARY_LIGHTING_PV_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,12 +294,9 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
BACNET_ADDRESS src = { 0 }; /* address where message came from */
|
BACNET_ADDRESS src = { 0 }; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 1; /* milliseconds */
|
unsigned timeout_ms = 1; /* milliseconds */
|
||||||
time_t last_seconds = 0;
|
unsigned long seconds = 0;
|
||||||
time_t current_seconds = 0;
|
unsigned long milliseconds;
|
||||||
uint32_t elapsed_seconds = 0;
|
|
||||||
uint32_t elapsed_milliseconds = 0;
|
|
||||||
uint32_t address_binding_tmr = 0;
|
|
||||||
|
|
||||||
/* allow the device ID to be set */
|
/* allow the device ID to be set */
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -233,41 +315,42 @@ int main(int argc, char *argv[])
|
|||||||
atexit(datalink_cleanup);
|
atexit(datalink_cleanup);
|
||||||
piface_init();
|
piface_init();
|
||||||
atexit(piface_cleanup);
|
atexit(piface_cleanup);
|
||||||
/* configure the timeout values */
|
|
||||||
last_seconds = time(NULL);
|
|
||||||
/* broadcast an I-Am on startup */
|
/* broadcast an I-Am on startup */
|
||||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||||
/* loop forever */
|
/* loop forever */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* input */
|
/* input */
|
||||||
current_seconds = time(NULL);
|
|
||||||
|
|
||||||
/* returns 0 bytes on timeout */
|
/* returns 0 bytes on timeout */
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout_ms);
|
||||||
|
|
||||||
/* process */
|
/* process */
|
||||||
if (pdu_len) {
|
if (pdu_len) {
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
}
|
}
|
||||||
/* at least one second has passed */
|
if (mstimer_expired(&BACnet_Task_Timer)) {
|
||||||
elapsed_seconds = (uint32_t)(current_seconds - last_seconds);
|
mstimer_reset(&BACnet_Task_Timer);
|
||||||
if (elapsed_seconds) {
|
/* 1 second tasks */
|
||||||
last_seconds = current_seconds;
|
dcc_timer_seconds(1);
|
||||||
dcc_timer_seconds(elapsed_seconds);
|
datalink_maintenance_timer(1);
|
||||||
datalink_maintenance_timer(elapsed_seconds);
|
dlenv_maintenance_timer(1);
|
||||||
dlenv_maintenance_timer(elapsed_seconds);
|
handler_cov_timer_seconds(1);
|
||||||
elapsed_milliseconds = elapsed_seconds * 1000;
|
}
|
||||||
handler_cov_timer_seconds(elapsed_seconds);
|
if (mstimer_expired(&BACnet_TSM_Timer)) {
|
||||||
tsm_timer_milliseconds(elapsed_milliseconds);
|
mstimer_reset(&BACnet_TSM_Timer);
|
||||||
|
tsm_timer_milliseconds(mstimer_interval(&BACnet_TSM_Timer));
|
||||||
}
|
}
|
||||||
handler_cov_task();
|
handler_cov_task();
|
||||||
/* scan cache address */
|
if (mstimer_expired(&BACnet_Address_Timer)) {
|
||||||
address_binding_tmr += elapsed_seconds;
|
mstimer_reset(&BACnet_Address_Timer);
|
||||||
if (address_binding_tmr >= 60) {
|
/* address cache */
|
||||||
address_cache_timer(address_binding_tmr);
|
seconds = mstimer_interval(&BACnet_Address_Timer) / 1000;
|
||||||
address_binding_tmr = 0;
|
address_cache_timer(seconds);
|
||||||
}
|
}
|
||||||
/* output/input */
|
/* output/input */
|
||||||
|
if (mstimer_expired(&BACnet_Object_Timer)) {
|
||||||
|
mstimer_reset(&BACnet_Object_Timer);
|
||||||
|
milliseconds = mstimer_interval(&BACnet_Object_Timer);
|
||||||
|
Device_Timer(milliseconds);
|
||||||
|
}
|
||||||
piface_task();
|
piface_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ SRC = main.c \
|
|||||||
$(BACNET_OBJECT_DIR)/av.c \
|
$(BACNET_OBJECT_DIR)/av.c \
|
||||||
$(BACNET_OBJECT_DIR)/bi.c \
|
$(BACNET_OBJECT_DIR)/bi.c \
|
||||||
$(BACNET_OBJECT_DIR)/bo.c \
|
$(BACNET_OBJECT_DIR)/bo.c \
|
||||||
|
$(BACNET_OBJECT_DIR)/blo.c \
|
||||||
$(BACNET_OBJECT_DIR)/bv.c \
|
$(BACNET_OBJECT_DIR)/bv.c \
|
||||||
$(BACNET_OBJECT_DIR)/channel.c \
|
$(BACNET_OBJECT_DIR)/channel.c \
|
||||||
$(BACNET_OBJECT_DIR)/color_object.c \
|
$(BACNET_OBJECT_DIR)/color_object.c \
|
||||||
|
|||||||
+17
-7
@@ -2206,13 +2206,23 @@ int bacapp_snprintf_value(
|
|||||||
break;
|
break;
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
case PROP_RELINQUISH_DEFAULT:
|
case PROP_RELINQUISH_DEFAULT:
|
||||||
if (object_type < OBJECT_PROPRIETARY_MIN) {
|
switch (object_type) {
|
||||||
ret_val = snprintf(str, str_len, "%s",
|
case OBJECT_BINARY_INPUT:
|
||||||
bactext_binary_present_value_name(
|
case OBJECT_BINARY_OUTPUT:
|
||||||
value->type.Enumerated));
|
case OBJECT_BINARY_VALUE:
|
||||||
} else {
|
ret_val = snprintf(str, str_len, "%s",
|
||||||
ret_val = snprintf(str, str_len, "%lu",
|
bactext_binary_present_value_name(
|
||||||
(unsigned long)value->type.Enumerated);
|
value->type.Enumerated));
|
||||||
|
break;
|
||||||
|
case OBJECT_BINARY_LIGHTING_OUTPUT:
|
||||||
|
ret_val = snprintf(str, str_len, "%s",
|
||||||
|
bactext_binary_lighting_pv_name(
|
||||||
|
value->type.Enumerated));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret_val = snprintf(str, str_len, "%lu",
|
||||||
|
(unsigned long)value->type.Enumerated);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_RELIABILITY:
|
case PROP_RELIABILITY:
|
||||||
|
|||||||
@@ -1079,7 +1079,7 @@ typedef enum {
|
|||||||
PROP_STATE_EXAMPLE_TWO = 257
|
PROP_STATE_EXAMPLE_TWO = 257
|
||||||
} BACNET_PROPERTY_STATES;
|
} BACNET_PROPERTY_STATES;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum BACnetReliability {
|
||||||
RELIABILITY_NO_FAULT_DETECTED = 0,
|
RELIABILITY_NO_FAULT_DETECTED = 0,
|
||||||
RELIABILITY_NO_SENSOR = 1,
|
RELIABILITY_NO_SENSOR = 1,
|
||||||
RELIABILITY_OVER_RANGE = 2,
|
RELIABILITY_OVER_RANGE = 2,
|
||||||
@@ -2106,6 +2106,7 @@ typedef enum BACnetBinaryLightingPV {
|
|||||||
BINARY_LIGHTING_PV_WARN_OFF = 3,
|
BINARY_LIGHTING_PV_WARN_OFF = 3,
|
||||||
BINARY_LIGHTING_PV_WARN_RELINQUISH = 4,
|
BINARY_LIGHTING_PV_WARN_RELINQUISH = 4,
|
||||||
BINARY_LIGHTING_PV_STOP = 5,
|
BINARY_LIGHTING_PV_STOP = 5,
|
||||||
|
BINARY_LIGHTING_PV_MAX = 6,
|
||||||
/* -- Enumerated values 0-63 are reserved for definition by ASHRAE.
|
/* -- Enumerated values 0-63 are reserved for definition by ASHRAE.
|
||||||
-- Enumerated values 64-255 may be used by others
|
-- Enumerated values 64-255 may be used by others
|
||||||
-- subject to the procedures and constraints described in Clause 23. */
|
-- subject to the procedures and constraints described in Clause 23. */
|
||||||
|
|||||||
+30
-1
@@ -1750,12 +1750,41 @@ const char *bactext_lighting_operation_name(unsigned index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bactext_bactext_lighting_operation_strtol(const char *search_name, unsigned *found_index)
|
bool bactext_lighting_operation_strtol(const char *search_name, unsigned *found_index)
|
||||||
{
|
{
|
||||||
return bactext_strtol_index(
|
return bactext_strtol_index(
|
||||||
bacnet_lighting_operation_names, search_name, found_index);
|
bacnet_lighting_operation_names, search_name, found_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INDTEXT_DATA bacnet_binary_lighting_pv_names[] = {
|
||||||
|
{ BINARY_LIGHTING_PV_OFF, "off" },
|
||||||
|
{ BINARY_LIGHTING_PV_ON, "on" },
|
||||||
|
{ BINARY_LIGHTING_PV_WARN, "warn" },
|
||||||
|
{ BINARY_LIGHTING_PV_WARN_OFF, "warn-off" },
|
||||||
|
{ BINARY_LIGHTING_PV_WARN_RELINQUISH, "warn-relinquish" },
|
||||||
|
{ BINARY_LIGHTING_PV_STOP, "stop" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *bactext_binary_lighting_pv_name(unsigned index)
|
||||||
|
{
|
||||||
|
if (index < BINARY_LIGHTING_PV_PROPRIETARY_MIN) {
|
||||||
|
return indtext_by_index_default(
|
||||||
|
bacnet_binary_lighting_pv_names, index, ASHRAE_Reserved_String);
|
||||||
|
} else if (index <= BINARY_LIGHTING_PV_PROPRIETARY_MAX) {
|
||||||
|
return Vendor_Proprietary_String;
|
||||||
|
} else {
|
||||||
|
return "Invalid BACnetBinaryLightingPV";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bactext_binary_lighting_pv_names_strtol(const char *search_name,
|
||||||
|
unsigned *found_index)
|
||||||
|
{
|
||||||
|
return bactext_strtol_index(
|
||||||
|
bacnet_binary_lighting_pv_names, search_name, found_index);
|
||||||
|
}
|
||||||
|
|
||||||
INDTEXT_DATA bacnet_color_operation_names[] = { { BACNET_COLOR_OPERATION_NONE,
|
INDTEXT_DATA bacnet_color_operation_names[] = { { BACNET_COLOR_OPERATION_NONE,
|
||||||
"none" },
|
"none" },
|
||||||
{ BACNET_COLOR_OPERATION_FADE_TO_COLOR, "fade-to-color" },
|
{ BACNET_COLOR_OPERATION_FADE_TO_COLOR, "fade-to-color" },
|
||||||
|
|||||||
+10
-1
@@ -201,7 +201,16 @@ extern "C" {
|
|||||||
unsigned index);
|
unsigned index);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool bactext_bactext_lighting_operation_strtol(
|
bool bactext_lighting_operation_strtol(
|
||||||
|
const char *search_name,
|
||||||
|
unsigned *found_index);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
const char *bactext_binary_lighting_pv_name(
|
||||||
|
unsigned index);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool bactext_binary_lighting_pv_names_strtol(
|
||||||
const char *search_name,
|
const char *search_name,
|
||||||
unsigned *found_index);
|
unsigned *found_index);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,161 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author Steve Karg
|
||||||
|
* @date 2023
|
||||||
|
* @brief Binary Lighting Output object
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
#ifndef BINARY_LIGHTING_OUTPUT_H
|
||||||
|
#define BINARY_LIGHTING_OUTPUT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "bacnet/bacnet_stack_exports.h"
|
||||||
|
#include "bacnet/bacdef.h"
|
||||||
|
#include "bacnet/bacerror.h"
|
||||||
|
#include "bacnet/rp.h"
|
||||||
|
#include "bacnet/wp.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback for write value request
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
* @param old_value - value prior to write
|
||||||
|
* @param value - value of the write
|
||||||
|
*/
|
||||||
|
typedef void (*binary_lighting_output_write_value_callback)(
|
||||||
|
uint32_t object_instance,
|
||||||
|
BACNET_BINARY_LIGHTING_PV old_value,
|
||||||
|
BACNET_BINARY_LIGHTING_PV value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback for blink warning notification
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
*/
|
||||||
|
typedef void (*binary_lighting_output_blink_warn_callback)(
|
||||||
|
uint32_t object_instance);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Property_Lists(
|
||||||
|
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Valid_Instance(uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
unsigned Binary_Lighting_Output_Count(void);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
uint32_t Binary_Lighting_Output_Index_To_Instance(unsigned index);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
unsigned Binary_Lighting_Output_Instance_To_Index(uint32_t instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Object_Instance_Add(uint32_t instance);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
BACNET_BINARY_LIGHTING_PV Binary_Lighting_Output_Present_Value(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
unsigned Binary_Lighting_Output_Present_Value_Priority(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Present_Value_Set(uint32_t object_instance,
|
||||||
|
BACNET_BINARY_LIGHTING_PV value,
|
||||||
|
unsigned priority);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Present_Value_Relinquish(
|
||||||
|
uint32_t object_instance, unsigned priority);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
BACNET_BINARY_LIGHTING_PV Binary_Lighting_Output_Relinquish_Default(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Relinquish_Default_Set(
|
||||||
|
uint32_t object_instance, BACNET_BINARY_LIGHTING_PV value);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
BACNET_RELIABILITY Binary_Lighting_Output_Reliability(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Reliability_Set(
|
||||||
|
uint32_t object_instance, BACNET_RELIABILITY value);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Object_Name(
|
||||||
|
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Name_Set(uint32_t object_instance, char *new_name);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
char *Binary_Lighting_Output_Description(uint32_t instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Description_Set(uint32_t instance, char *new_name);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Out_Of_Service(uint32_t instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Out_Of_Service_Set(
|
||||||
|
uint32_t instance, bool oos_flag);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
BACNET_BINARY_LIGHTING_PV Binary_Lighting_Output_Lighting_Command_Target_Value(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
unsigned Binary_Lighting_Output_Lighting_Command_Target_Priority(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Lighting_Command_Set(
|
||||||
|
uint32_t object_instance, BACNET_BINARY_LIGHTING_PV value, unsigned priority);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
BACNET_BINARY_LIGHTING_PV Binary_Lighting_Output_Feedback_Value(
|
||||||
|
uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Feedback_Value_Set(
|
||||||
|
uint32_t object_instance, BACNET_BINARY_LIGHTING_PV value);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Blink_Warn_Enable(uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Blink_Warn_Enable_Set(
|
||||||
|
uint32_t object_instance, bool enable);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
uint32_t Binary_Lighting_Output_Egress_Time(uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Egress_Time_Set(
|
||||||
|
uint32_t object_instance, uint32_t seconds);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Egress_Active(uint32_t object_instance);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Timer(
|
||||||
|
uint32_t object_instance, uint16_t milliseconds);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Write_Value_Callback_Set(
|
||||||
|
binary_lighting_output_write_value_callback cb);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Blink_Warn_Callback_Set(
|
||||||
|
binary_lighting_output_blink_warn_callback cb);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
uint32_t Binary_Lighting_Output_Create(uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Delete(uint32_t object_instance);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Cleanup(void);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void Binary_Lighting_Output_Init(void);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int Binary_Lighting_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool Binary_Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#endif
|
||||||
@@ -51,6 +51,9 @@
|
|||||||
#include "bacnet/basic/object/ao.h"
|
#include "bacnet/basic/object/ao.h"
|
||||||
#include "bacnet/basic/object/av.h"
|
#include "bacnet/basic/object/av.h"
|
||||||
#include "bacnet/basic/object/bi.h"
|
#include "bacnet/basic/object/bi.h"
|
||||||
|
#if (BACNET_PROTOCOL_REVISION >= 16)
|
||||||
|
#include "bacnet/basic/object/blo.h"
|
||||||
|
#endif
|
||||||
#include "bacnet/basic/object/bo.h"
|
#include "bacnet/basic/object/bo.h"
|
||||||
#include "bacnet/basic/object/bv.h"
|
#include "bacnet/basic/object/bv.h"
|
||||||
#include "bacnet/basic/object/channel.h"
|
#include "bacnet/basic/object/channel.h"
|
||||||
@@ -267,6 +270,20 @@ static object_functions_t My_Object_Table[] = {
|
|||||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||||
Channel_Create, Channel_Delete, NULL /* Timer */ },
|
Channel_Create, Channel_Delete, NULL /* Timer */ },
|
||||||
#endif
|
#endif
|
||||||
|
#if (BACNET_PROTOCOL_REVISION >= 16)
|
||||||
|
{ OBJECT_BINARY_LIGHTING_OUTPUT, Binary_Lighting_Output_Init,
|
||||||
|
Binary_Lighting_Output_Count, Binary_Lighting_Output_Index_To_Instance,
|
||||||
|
Binary_Lighting_Output_Valid_Instance,
|
||||||
|
Binary_Lighting_Output_Object_Name,
|
||||||
|
Binary_Lighting_Output_Read_Property,
|
||||||
|
Binary_Lighting_Output_Write_Property,
|
||||||
|
Binary_Lighting_Output_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 */,
|
||||||
|
Binary_Lighting_Output_Create, Binary_Lighting_Output_Delete,
|
||||||
|
Binary_Lighting_Output_Timer },
|
||||||
|
#endif
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 24)
|
#if (BACNET_PROTOCOL_REVISION >= 24)
|
||||||
{ OBJECT_COLOR, Color_Init, Color_Count, Color_Index_To_Instance,
|
{ OBJECT_COLOR, Color_Init, Color_Count, Color_Index_To_Instance,
|
||||||
Color_Valid_Instance, Color_Object_Name, Color_Read_Property,
|
Color_Valid_Instance, Color_Object_Name, Color_Read_Property,
|
||||||
@@ -2201,12 +2218,14 @@ void Device_Init(object_functions_t *object_table)
|
|||||||
pObject++;
|
pObject++;
|
||||||
}
|
}
|
||||||
/* create some dynamically created objects as examples */
|
/* create some dynamically created objects as examples */
|
||||||
pObject = Object_Table;
|
if (!object_table) {
|
||||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
pObject = Object_Table;
|
||||||
if (pObject->Object_Create) {
|
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
||||||
pObject->Object_Create(BACNET_MAX_INSTANCE);
|
if (pObject->Object_Create) {
|
||||||
|
pObject->Object_Create(BACNET_MAX_INSTANCE);
|
||||||
|
}
|
||||||
|
pObject++;
|
||||||
}
|
}
|
||||||
pObject++;
|
|
||||||
}
|
}
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||||
Channel_Write_Property_Internal_Callback_Set(Device_Write_Property);
|
Channel_Write_Property_Internal_Callback_Set(Device_Write_Property);
|
||||||
|
|||||||
@@ -48,10 +48,6 @@
|
|||||||
/* me! */
|
/* me! */
|
||||||
#include "bacnet/basic/object/lo.h"
|
#include "bacnet/basic/object/lo.h"
|
||||||
|
|
||||||
#ifndef MAX_LIGHTING_OUTPUTS
|
|
||||||
#define MAX_LIGHTING_OUTPUTS 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct object_data {
|
struct object_data {
|
||||||
float Present_Value;
|
float Present_Value;
|
||||||
float Tracking_Value;
|
float Tracking_Value;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#define KEYLIST_H
|
#define KEYLIST_H
|
||||||
|
|
||||||
#include "bacnet/bacnet_stack_exports.h"
|
#include "bacnet/bacnet_stack_exports.h"
|
||||||
#include "key.h"
|
#include "bacnet/basic/sys/key.h"
|
||||||
|
|
||||||
/* This is a key sorted linked list data library that */
|
/* This is a key sorted linked list data library that */
|
||||||
/* uses a key or index to access the data. */
|
/* uses a key or index to access the data. */
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ list(APPEND testdirs
|
|||||||
bacnet/basic/object/av
|
bacnet/basic/object/av
|
||||||
bacnet/basic/object/bacfile
|
bacnet/basic/object/bacfile
|
||||||
bacnet/basic/object/bi
|
bacnet/basic/object/bi
|
||||||
|
bacnet/basic/object/blo
|
||||||
bacnet/basic/object/bo
|
bacnet/basic/object/bo
|
||||||
bacnet/basic/object/bv
|
bacnet/basic/object/bv
|
||||||
bacnet/basic/object/channel
|
bacnet/basic/object/channel
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
||||||
|
|
||||||
|
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||||
|
project(test_${basename}
|
||||||
|
VERSION 1.0.0
|
||||||
|
LANGUAGES C)
|
||||||
|
|
||||||
|
|
||||||
|
string(REGEX REPLACE
|
||||||
|
"/test/bacnet/[a-zA-Z_/-]*$"
|
||||||
|
"/src"
|
||||||
|
SRC_DIR
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
string(REGEX REPLACE
|
||||||
|
"/test/bacnet/[a-zA-Z_/-]*$"
|
||||||
|
"/test"
|
||||||
|
TST_DIR
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
set(ZTST_DIR "${TST_DIR}/ztest/src")
|
||||||
|
|
||||||
|
add_compile_definitions(
|
||||||
|
BIG_ENDIAN=0
|
||||||
|
CONFIG_ZTEST=1
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${SRC_DIR}
|
||||||
|
${TST_DIR}/ztest/include
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME}
|
||||||
|
# File(s) under test
|
||||||
|
${SRC_DIR}/bacnet/basic/object/blo.c
|
||||||
|
# Support files and stubs (pathname alphabetical)
|
||||||
|
${SRC_DIR}/bacnet/bacaddr.c
|
||||||
|
${SRC_DIR}/bacnet/bacapp.c
|
||||||
|
${SRC_DIR}/bacnet/bacdcode.c
|
||||||
|
${SRC_DIR}/bacnet/bacdest.c
|
||||||
|
${SRC_DIR}/bacnet/bacdevobjpropref.c
|
||||||
|
${SRC_DIR}/bacnet/bacerror.c
|
||||||
|
${SRC_DIR}/bacnet/bacint.c
|
||||||
|
${SRC_DIR}/bacnet/bacreal.c
|
||||||
|
${SRC_DIR}/bacnet/bacstr.c
|
||||||
|
${SRC_DIR}/bacnet/bactext.c
|
||||||
|
${SRC_DIR}/bacnet/basic/sys/bigend.c
|
||||||
|
${SRC_DIR}/bacnet/basic/sys/days.c
|
||||||
|
${SRC_DIR}/bacnet/basic/sys/keylist.c
|
||||||
|
${SRC_DIR}/bacnet/basic/sys/linear.c
|
||||||
|
${SRC_DIR}/bacnet/datetime.c
|
||||||
|
${SRC_DIR}/bacnet/indtext.c
|
||||||
|
${SRC_DIR}/bacnet/hostnport.c
|
||||||
|
${SRC_DIR}/bacnet/lighting.c
|
||||||
|
${SRC_DIR}/bacnet/timestamp.c
|
||||||
|
${SRC_DIR}/bacnet/wp.c
|
||||||
|
${SRC_DIR}/bacnet/weeklyschedule.c
|
||||||
|
${SRC_DIR}/bacnet/bactimevalue.c
|
||||||
|
${SRC_DIR}/bacnet/dailyschedule.c
|
||||||
|
# Test and test library files
|
||||||
|
./src/main.c
|
||||||
|
../mock/device_mock.c
|
||||||
|
${ZTST_DIR}/ztest_mock.c
|
||||||
|
${ZTST_DIR}/ztest.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
m)
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Unit test for object
|
||||||
|
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||||
|
* @date September 2023
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
#include <zephyr/ztest.h>
|
||||||
|
#include <bacnet/bactext.h>
|
||||||
|
#include <bacnet/basic/object/blo.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup bacnet_tests
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
|
ZTEST(lo_tests, testBinaryLightingOutput)
|
||||||
|
#else
|
||||||
|
static void testBinaryLightingOutput(void)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
uint8_t apdu[MAX_APDU] = { 0 };
|
||||||
|
int len = 0, test_len = 0;
|
||||||
|
BACNET_READ_PROPERTY_DATA rpdata;
|
||||||
|
BACNET_APPLICATION_DATA_VALUE value = { 0 };
|
||||||
|
const int *pRequired = NULL;
|
||||||
|
const int *pOptional = NULL;
|
||||||
|
const int *pProprietary = NULL;
|
||||||
|
const uint32_t instance = 123;
|
||||||
|
BACNET_WRITE_PROPERTY_DATA wpdata = { 0 };
|
||||||
|
bool status = false;
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
Binary_Lighting_Output_Init();
|
||||||
|
Binary_Lighting_Output_Create(instance);
|
||||||
|
status = Binary_Lighting_Output_Valid_Instance(instance);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
index = Binary_Lighting_Output_Instance_To_Index(instance);
|
||||||
|
zassert_equal(index, 0, NULL);
|
||||||
|
|
||||||
|
rpdata.application_data = &apdu[0];
|
||||||
|
rpdata.application_data_len = sizeof(apdu);
|
||||||
|
rpdata.object_type = OBJECT_BINARY_LIGHTING_OUTPUT;
|
||||||
|
rpdata.object_instance = instance;
|
||||||
|
rpdata.array_index = BACNET_ARRAY_ALL;
|
||||||
|
|
||||||
|
Binary_Lighting_Output_Property_Lists(
|
||||||
|
&pRequired, &pOptional, &pProprietary);
|
||||||
|
while ((*pRequired) >= 0) {
|
||||||
|
rpdata.object_property = *pRequired;
|
||||||
|
rpdata.array_index = BACNET_ARRAY_ALL;
|
||||||
|
len = Binary_Lighting_Output_Read_Property(&rpdata);
|
||||||
|
zassert_not_equal(len, BACNET_STATUS_ERROR,
|
||||||
|
"property '%s': failed to ReadProperty!\n",
|
||||||
|
bactext_property_name(rpdata.object_property));
|
||||||
|
if (len >= 0) {
|
||||||
|
test_len = bacapp_decode_known_property(rpdata.application_data,
|
||||||
|
len, &value, rpdata.object_type, rpdata.object_property);
|
||||||
|
if (rpdata.object_property != PROP_PRIORITY_ARRAY) {
|
||||||
|
zassert_equal(len, test_len,
|
||||||
|
"property '%s': failed to decode!\n",
|
||||||
|
bactext_property_name(rpdata.object_property));
|
||||||
|
}
|
||||||
|
/* check WriteProperty properties */
|
||||||
|
wpdata.object_type = rpdata.object_type;
|
||||||
|
wpdata.object_instance = rpdata.object_instance;
|
||||||
|
wpdata.object_property = rpdata.object_property;
|
||||||
|
wpdata.array_index = rpdata.array_index;
|
||||||
|
memcpy(&wpdata.application_data, rpdata.application_data, MAX_APDU);
|
||||||
|
wpdata.application_data_len = len;
|
||||||
|
wpdata.error_code = ERROR_CODE_SUCCESS;
|
||||||
|
status = Binary_Lighting_Output_Write_Property(&wpdata);
|
||||||
|
if (!status) {
|
||||||
|
/* verify WriteProperty property is known */
|
||||||
|
zassert_not_equal(wpdata.error_code,
|
||||||
|
ERROR_CODE_UNKNOWN_PROPERTY,
|
||||||
|
"property '%s': WriteProperty Unknown!\n",
|
||||||
|
bactext_property_name(rpdata.object_property));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pRequired++;
|
||||||
|
}
|
||||||
|
while ((*pOptional) != -1) {
|
||||||
|
rpdata.object_property = *pOptional;
|
||||||
|
rpdata.array_index = BACNET_ARRAY_ALL;
|
||||||
|
len = Binary_Lighting_Output_Read_Property(&rpdata);
|
||||||
|
zassert_not_equal(len, BACNET_STATUS_ERROR,
|
||||||
|
"property '%s': failed to ReadProperty!\n",
|
||||||
|
bactext_property_name(rpdata.object_property));
|
||||||
|
if (len > 0) {
|
||||||
|
test_len = bacapp_decode_application_data(rpdata.application_data,
|
||||||
|
(uint8_t)rpdata.application_data_len, &value);
|
||||||
|
zassert_equal(len, test_len, "property '%s': failed to decode!\n",
|
||||||
|
bactext_property_name(rpdata.object_property));
|
||||||
|
/* check WriteProperty properties */
|
||||||
|
wpdata.object_type = rpdata.object_type;
|
||||||
|
wpdata.object_instance = rpdata.object_instance;
|
||||||
|
wpdata.object_property = rpdata.object_property;
|
||||||
|
wpdata.array_index = rpdata.array_index;
|
||||||
|
memcpy(&wpdata.application_data, rpdata.application_data, MAX_APDU);
|
||||||
|
wpdata.application_data_len = len;
|
||||||
|
wpdata.error_code = ERROR_CODE_SUCCESS;
|
||||||
|
status = Binary_Lighting_Output_Write_Property(&wpdata);
|
||||||
|
if (!status) {
|
||||||
|
/* verify WriteProperty property is known */
|
||||||
|
zassert_not_equal(wpdata.error_code,
|
||||||
|
ERROR_CODE_UNKNOWN_PROPERTY,
|
||||||
|
"property '%s': WriteProperty Unknown!\n",
|
||||||
|
bactext_property_name(rpdata.object_property));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pOptional++;
|
||||||
|
}
|
||||||
|
/* check for unsupported property - use ALL */
|
||||||
|
rpdata.object_property = PROP_ALL;
|
||||||
|
len = Binary_Lighting_Output_Read_Property(&rpdata);
|
||||||
|
zassert_equal(len, BACNET_STATUS_ERROR, NULL);
|
||||||
|
status = Binary_Lighting_Output_Write_Property(&wpdata);
|
||||||
|
zassert_false(status, NULL);
|
||||||
|
/* check the delete function */
|
||||||
|
status = Binary_Lighting_Output_Delete(instance);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
uint32_t object_instance;
|
||||||
|
BACNET_BINARY_LIGHTING_PV old_pv;
|
||||||
|
BACNET_BINARY_LIGHTING_PV pv;
|
||||||
|
uint32_t count;
|
||||||
|
} BLO_Value;
|
||||||
|
static void Binary_Lighting_Output_Write_Value_Handler(uint32_t object_instance,
|
||||||
|
BACNET_BINARY_LIGHTING_PV old_value,
|
||||||
|
BACNET_BINARY_LIGHTING_PV value)
|
||||||
|
{
|
||||||
|
BLO_Value.object_instance = object_instance;
|
||||||
|
BLO_Value.old_pv = old_value;
|
||||||
|
BLO_Value.pv = value;
|
||||||
|
BLO_Value.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
uint32_t object_instance;
|
||||||
|
uint32_t count;
|
||||||
|
} BLO_Blink;
|
||||||
|
static void Binary_Lighting_Output_Blink_Warn_Handler(uint32_t object_instance)
|
||||||
|
{
|
||||||
|
BLO_Blink.object_instance = object_instance;
|
||||||
|
BLO_Blink.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
|
ZTEST(lo_tests, testBinaryLightingOutputBlink)
|
||||||
|
#else
|
||||||
|
static void testBinaryLightingOutputBlink(void)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const uint32_t object_instance = 123;
|
||||||
|
bool status = false;
|
||||||
|
uint16_t milliseconds, milliseconds_elapsed;
|
||||||
|
BACNET_BINARY_LIGHTING_PV pv, test_pv, expect_pv;
|
||||||
|
unsigned test_priority;
|
||||||
|
BACNET_WRITE_PROPERTY_DATA wpdata = { 0 };
|
||||||
|
BACNET_APPLICATION_DATA_VALUE value = { 0 };
|
||||||
|
|
||||||
|
Binary_Lighting_Output_Init();
|
||||||
|
Binary_Lighting_Output_Create(object_instance);
|
||||||
|
status = Binary_Lighting_Output_Valid_Instance(object_instance);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
Binary_Lighting_Output_Write_Value_Callback_Set(
|
||||||
|
Binary_Lighting_Output_Write_Value_Handler);
|
||||||
|
Binary_Lighting_Output_Blink_Warn_Callback_Set(
|
||||||
|
Binary_Lighting_Output_Blink_Warn_Handler);
|
||||||
|
/* check the blink warning engine at defaults */
|
||||||
|
milliseconds_elapsed = 100;
|
||||||
|
expect_pv = BINARY_LIGHTING_PV_OFF;
|
||||||
|
Binary_Lighting_Output_Timer(object_instance, milliseconds_elapsed);
|
||||||
|
zassert_equal(BLO_Blink.count, 0, "count=%u", BLO_Blink.count);
|
||||||
|
zassert_equal(BLO_Value.count, 0, "count=%u", BLO_Value.count);
|
||||||
|
zassert_equal(BLO_Value.pv, expect_pv, "value=%u", BLO_Value.pv);
|
||||||
|
|
||||||
|
/* check WriteProperty properties */
|
||||||
|
wpdata.object_type = OBJECT_BINARY_LIGHTING_OUTPUT;
|
||||||
|
wpdata.object_instance = object_instance;
|
||||||
|
wpdata.object_property = PROP_PRESENT_VALUE;
|
||||||
|
wpdata.priority = BACNET_MAX_PRIORITY;
|
||||||
|
wpdata.array_index = BACNET_ARRAY_ALL;
|
||||||
|
wpdata.error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
wpdata.error_code = ERROR_CODE_SUCCESS;
|
||||||
|
/* ON */
|
||||||
|
pv = BINARY_LIGHTING_PV_ON;
|
||||||
|
expect_pv = BINARY_LIGHTING_PV_ON;
|
||||||
|
wpdata.application_data_len =
|
||||||
|
encode_application_enumerated(wpdata.application_data, pv);
|
||||||
|
status = Binary_Lighting_Output_Write_Property(&wpdata);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
milliseconds = 2000;
|
||||||
|
milliseconds_elapsed = 100;
|
||||||
|
while (milliseconds) {
|
||||||
|
Binary_Lighting_Output_Timer(object_instance, milliseconds_elapsed);
|
||||||
|
test_pv = Binary_Lighting_Output_Present_Value(object_instance);
|
||||||
|
zassert_equal(expect_pv, test_pv, NULL);
|
||||||
|
test_priority =
|
||||||
|
Binary_Lighting_Output_Present_Value_Priority(object_instance);
|
||||||
|
zassert_equal(wpdata.priority, test_priority,
|
||||||
|
"priority=%u test_priority=%u", wpdata.priority, test_priority);
|
||||||
|
zassert_equal(BLO_Blink.count, 0, NULL);
|
||||||
|
zassert_equal(BLO_Value.count, 1, "count=%u", BLO_Value.count);
|
||||||
|
zassert_equal(BLO_Value.pv, expect_pv, NULL);
|
||||||
|
milliseconds -= milliseconds_elapsed;
|
||||||
|
}
|
||||||
|
/* OFF */
|
||||||
|
pv = BINARY_LIGHTING_PV_OFF;
|
||||||
|
expect_pv = BINARY_LIGHTING_PV_OFF;
|
||||||
|
wpdata.application_data_len =
|
||||||
|
encode_application_enumerated(wpdata.application_data, pv);
|
||||||
|
status = Binary_Lighting_Output_Write_Property(&wpdata);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
milliseconds = 2000;
|
||||||
|
milliseconds_elapsed = 100;
|
||||||
|
while (milliseconds) {
|
||||||
|
Binary_Lighting_Output_Timer(object_instance, milliseconds_elapsed);
|
||||||
|
test_pv = Binary_Lighting_Output_Present_Value(object_instance);
|
||||||
|
zassert_equal(expect_pv, test_pv, NULL);
|
||||||
|
test_priority =
|
||||||
|
Binary_Lighting_Output_Present_Value_Priority(object_instance);
|
||||||
|
zassert_equal(wpdata.priority, test_priority,
|
||||||
|
"priority=%u test_priority=%u", wpdata.priority, test_priority);
|
||||||
|
zassert_equal(BLO_Blink.count, 0, NULL);
|
||||||
|
zassert_equal(BLO_Value.count, 2, "count=%u", BLO_Value.count);
|
||||||
|
zassert_equal(BLO_Value.pv, expect_pv, NULL);
|
||||||
|
milliseconds -= milliseconds_elapsed;
|
||||||
|
}
|
||||||
|
/* WARN - already off */
|
||||||
|
pv = BINARY_LIGHTING_PV_WARN;
|
||||||
|
expect_pv = BINARY_LIGHTING_PV_OFF;
|
||||||
|
wpdata.application_data_len =
|
||||||
|
encode_application_enumerated(wpdata.application_data, pv);
|
||||||
|
status = Binary_Lighting_Output_Write_Property(&wpdata);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
milliseconds = 2000;
|
||||||
|
milliseconds_elapsed = 100;
|
||||||
|
while (milliseconds) {
|
||||||
|
Binary_Lighting_Output_Timer(object_instance, milliseconds_elapsed);
|
||||||
|
test_pv = Binary_Lighting_Output_Present_Value(object_instance);
|
||||||
|
zassert_equal(expect_pv, test_pv, "pv=%u", test_pv);
|
||||||
|
test_priority =
|
||||||
|
Binary_Lighting_Output_Present_Value_Priority(object_instance);
|
||||||
|
zassert_equal(wpdata.priority, test_priority,
|
||||||
|
"priority=%u test_priority=%u", wpdata.priority, test_priority);
|
||||||
|
zassert_equal(BLO_Blink.count, 0, NULL);
|
||||||
|
zassert_equal(BLO_Value.count, 2, "count=%u", BLO_Value.count);
|
||||||
|
zassert_equal(BLO_Value.pv, expect_pv, NULL);
|
||||||
|
milliseconds -= milliseconds_elapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
|
ZTEST_SUITE(blo_tests, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
#else
|
||||||
|
void test_main(void)
|
||||||
|
{
|
||||||
|
ztest_test_suite(blo_tests, ztest_unit_test(testBinaryLightingOutput),
|
||||||
|
ztest_unit_test(testBinaryLightingOutputBlink));
|
||||||
|
|
||||||
|
ztest_run_test_suite(blo_tests);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -52,6 +52,7 @@ add_executable(${PROJECT_NAME}
|
|||||||
${SRC_DIR}/bacnet/basic/object/ao.c
|
${SRC_DIR}/bacnet/basic/object/ao.c
|
||||||
${SRC_DIR}/bacnet/basic/object/av.c
|
${SRC_DIR}/bacnet/basic/object/av.c
|
||||||
${SRC_DIR}/bacnet/basic/object/bi.c
|
${SRC_DIR}/bacnet/basic/object/bi.c
|
||||||
|
${SRC_DIR}/bacnet/basic/object/blo.c
|
||||||
${SRC_DIR}/bacnet/basic/object/bo.c
|
${SRC_DIR}/bacnet/basic/object/bo.c
|
||||||
${SRC_DIR}/bacnet/basic/object/bv.c
|
${SRC_DIR}/bacnet/basic/object/bv.c
|
||||||
${SRC_DIR}/bacnet/basic/object/channel.c
|
${SRC_DIR}/bacnet/basic/object/channel.c
|
||||||
|
|||||||
Reference in New Issue
Block a user