7424b43bdd
- Introduced new enum value `kShortDiagnosticBit` to `GatewayModbusGeneratedKind`. - Enhanced `GatewayModbusPoint` and `GatewayModbusPointBinding` structures to include diagnostic snapshot, boolean key, and device type. - Added new diagnostic bit specifications and updated the corresponding arrays for generated discrete inputs and holding registers. - Implemented `addGeneratedDiagnosticPoint` function to handle the creation of diagnostic points. - Updated `rebuildMap` method to include generated diagnostic points during the map rebuilding process. Co-authored-by: Copilot <copilot@github.com>
639 lines
26 KiB
C
639 lines
26 KiB
C
#include "gateway_bacnet_stack_port.h"
|
|
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
#include "bacnet/apdu.h"
|
|
#include "bacnet/basic/binding/address.h"
|
|
#include "bacnet/basic/object/ai.h"
|
|
#include "bacnet/basic/object/ao.h"
|
|
#include "bacnet/basic/object/av.h"
|
|
#include "bacnet/basic/object/bi.h"
|
|
#include "bacnet/basic/object/bo.h"
|
|
#include "bacnet/basic/object/bv.h"
|
|
#include "bacnet/basic/object/device.h"
|
|
#include "bacnet/basic/object/ms-input.h"
|
|
#include "bacnet/basic/object/mso.h"
|
|
#include "bacnet/basic/object/msv.h"
|
|
#include "bacnet/basic/service/h_apdu.h"
|
|
#include "bacnet/basic/services.h"
|
|
#include "bacnet/basic/tsm/tsm.h"
|
|
#include "bacnet/bacdef.h"
|
|
#include "bacnet/npdu.h"
|
|
#include "bip.h"
|
|
|
|
static gateway_bacnet_stack_write_callback_t Write_Callback;
|
|
static void* Write_Callback_Context;
|
|
static uint8_t Rx_Buffer[BIP_MPDU_MAX];
|
|
static const char Multistate_Value_States[] =
|
|
"State 1\0"
|
|
"State 2\0"
|
|
"State 3\0"
|
|
"State 4\0"
|
|
"State 5\0"
|
|
"State 6\0"
|
|
"State 7\0"
|
|
"State 8\0"
|
|
"State 9\0"
|
|
"State 10\0"
|
|
"State 11\0"
|
|
"State 12\0"
|
|
"State 13\0"
|
|
"State 14\0"
|
|
"State 15\0"
|
|
"State 16\0";
|
|
|
|
static bool clear_analog_value_objects(void)
|
|
{
|
|
unsigned count = Analog_Value_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Analog_Value_Delete(Analog_Value_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_analog_output_objects(void)
|
|
{
|
|
unsigned count = Analog_Output_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Analog_Output_Delete(Analog_Output_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_binary_value_objects(void)
|
|
{
|
|
unsigned count = Binary_Value_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Binary_Value_Delete(Binary_Value_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_binary_output_objects(void)
|
|
{
|
|
unsigned count = Binary_Output_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Binary_Output_Delete(Binary_Output_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_multistate_value_objects(void)
|
|
{
|
|
unsigned count = Multistate_Value_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Multistate_Value_Delete(Multistate_Value_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_analog_input_objects(void)
|
|
{
|
|
unsigned count = Analog_Input_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Analog_Input_Delete(Analog_Input_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_binary_input_objects(void)
|
|
{
|
|
unsigned count = Binary_Input_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Binary_Input_Delete(Binary_Input_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_multistate_input_objects(void)
|
|
{
|
|
unsigned count = Multistate_Input_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Multistate_Input_Delete(Multistate_Input_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool clear_multistate_output_objects(void)
|
|
{
|
|
unsigned count = Multistate_Output_Count();
|
|
while (count > 0) {
|
|
count--;
|
|
Multistate_Output_Delete(Multistate_Output_Index_To_Instance(count));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void set_analog_value_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Analog_Value_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Analog_Value_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_analog_output_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Analog_Output_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Analog_Output_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_binary_value_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Binary_Value_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Binary_Value_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_binary_output_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Binary_Output_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Binary_Output_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_multistate_value_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Multistate_Value_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Multistate_Value_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_analog_input_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Analog_Input_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Analog_Input_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_binary_input_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Binary_Input_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Binary_Input_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_multistate_input_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Multistate_Input_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Multistate_Input_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void set_multistate_output_state(
|
|
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
|
|
{
|
|
Multistate_Output_Out_Of_Service_Set(object_instance, out_of_service);
|
|
Multistate_Output_Reliability_Set(object_instance, reliability);
|
|
}
|
|
|
|
static void notify_write_real(
|
|
gateway_bacnet_object_kind_t object_kind, uint32_t object_instance, double value)
|
|
{
|
|
if (Write_Callback) {
|
|
gateway_bacnet_write_value_t write_value = {
|
|
.kind = GW_BACNET_WRITE_VALUE_REAL,
|
|
.real_value = value,
|
|
.boolean_value = false,
|
|
.unsigned_value = 0,
|
|
};
|
|
Write_Callback(object_kind, object_instance, &write_value, Write_Callback_Context);
|
|
}
|
|
}
|
|
|
|
static void notify_write_boolean(
|
|
gateway_bacnet_object_kind_t object_kind, uint32_t object_instance, bool value)
|
|
{
|
|
if (Write_Callback) {
|
|
gateway_bacnet_write_value_t write_value = {
|
|
.kind = GW_BACNET_WRITE_VALUE_BOOLEAN,
|
|
.real_value = 0.0,
|
|
.boolean_value = value,
|
|
.unsigned_value = 0,
|
|
};
|
|
Write_Callback(object_kind, object_instance, &write_value, Write_Callback_Context);
|
|
}
|
|
}
|
|
|
|
static void notify_write_unsigned(
|
|
gateway_bacnet_object_kind_t object_kind, uint32_t object_instance, uint32_t value)
|
|
{
|
|
if (Write_Callback) {
|
|
gateway_bacnet_write_value_t write_value = {
|
|
.kind = GW_BACNET_WRITE_VALUE_UNSIGNED,
|
|
.real_value = 0.0,
|
|
.boolean_value = false,
|
|
.unsigned_value = value,
|
|
};
|
|
Write_Callback(object_kind, object_instance, &write_value, Write_Callback_Context);
|
|
}
|
|
}
|
|
|
|
static void analog_value_write(uint32_t object_instance, float old_value, float value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_real(GW_BACNET_OBJECT_ANALOG_VALUE, object_instance, value);
|
|
}
|
|
|
|
static void analog_output_write(uint32_t object_instance, float old_value, float value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_real(GW_BACNET_OBJECT_ANALOG_OUTPUT, object_instance, value);
|
|
}
|
|
|
|
static void binary_value_write(
|
|
uint32_t object_instance, BACNET_BINARY_PV old_value, BACNET_BINARY_PV value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_boolean(GW_BACNET_OBJECT_BINARY_VALUE, object_instance, value == BINARY_ACTIVE);
|
|
}
|
|
|
|
static void binary_output_write(
|
|
uint32_t object_instance, BACNET_BINARY_PV old_value, BACNET_BINARY_PV value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_boolean(GW_BACNET_OBJECT_BINARY_OUTPUT, object_instance, value == BINARY_ACTIVE);
|
|
}
|
|
|
|
static void multistate_value_write(uint32_t object_instance, uint32_t old_value, uint32_t value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_unsigned(GW_BACNET_OBJECT_MULTI_STATE_VALUE, object_instance, value);
|
|
}
|
|
|
|
static void binary_input_write(
|
|
uint32_t object_instance, BACNET_BINARY_PV old_value, BACNET_BINARY_PV value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_boolean(GW_BACNET_OBJECT_BINARY_INPUT, object_instance, value == BINARY_ACTIVE);
|
|
}
|
|
|
|
static void multistate_input_write(uint32_t object_instance, uint32_t old_value, uint32_t value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_unsigned(GW_BACNET_OBJECT_MULTI_STATE_INPUT, object_instance, value);
|
|
}
|
|
|
|
static void multistate_output_write(uint32_t object_instance, uint32_t old_value, uint32_t value)
|
|
{
|
|
(void)old_value;
|
|
notify_write_unsigned(GW_BACNET_OBJECT_MULTI_STATE_OUTPUT, object_instance, value);
|
|
}
|
|
|
|
static object_functions_t Object_Table[] = {
|
|
{ OBJECT_DEVICE, NULL, Device_Count, Device_Index_To_Instance,
|
|
Device_Valid_Object_Instance_Number, Device_Object_Name, Device_Read_Property_Local,
|
|
Device_Write_Property_Local, Device_Property_Lists, DeviceGetRRInfo, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, Device_Writable_Property_List },
|
|
{ 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, Analog_Value_Write_Property, Analog_Value_Property_Lists,
|
|
NULL, NULL, Analog_Value_Encode_Value_List, Analog_Value_Change_Of_Value,
|
|
Analog_Value_Change_Of_Value_Clear, NULL, NULL, NULL, Analog_Value_Create,
|
|
Analog_Value_Delete, NULL, Analog_Value_Writable_Property_List },
|
|
{ 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, Analog_Output_Write_Property, Analog_Output_Property_Lists,
|
|
NULL, NULL, Analog_Output_Encode_Value_List, Analog_Output_Change_Of_Value,
|
|
Analog_Output_Change_Of_Value_Clear, NULL, NULL, NULL, Analog_Output_Create,
|
|
Analog_Output_Delete, NULL, Analog_Output_Writable_Property_List },
|
|
{ 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, Binary_Value_Write_Property, Binary_Value_Property_Lists,
|
|
NULL, NULL, Binary_Value_Encode_Value_List, Binary_Value_Change_Of_Value,
|
|
Binary_Value_Change_Of_Value_Clear, NULL, NULL, NULL, Binary_Value_Create,
|
|
Binary_Value_Delete, NULL, Binary_Value_Writable_Property_List },
|
|
{ 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, Binary_Output_Write_Property, Binary_Output_Property_Lists,
|
|
NULL, NULL, Binary_Output_Encode_Value_List, Binary_Output_Change_Of_Value,
|
|
Binary_Output_Change_Of_Value_Clear, NULL, NULL, NULL, Binary_Output_Create,
|
|
Binary_Output_Delete, NULL, Binary_Output_Writable_Property_List },
|
|
{ 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,
|
|
Multistate_Value_Write_Property, Multistate_Value_Property_Lists, NULL, NULL,
|
|
Multistate_Value_Encode_Value_List, Multistate_Value_Change_Of_Value,
|
|
Multistate_Value_Change_Of_Value_Clear, NULL, NULL, NULL, Multistate_Value_Create,
|
|
Multistate_Value_Delete, NULL, Multistate_Value_Writable_Property_List },
|
|
{ OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
|
|
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, Analog_Input_Object_Name,
|
|
Analog_Input_Read_Property, Analog_Input_Write_Property, Analog_Input_Property_Lists,
|
|
NULL, NULL, Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value,
|
|
Analog_Input_Change_Of_Value_Clear, NULL, NULL, NULL, Analog_Input_Create,
|
|
Analog_Input_Delete, NULL, Analog_Input_Writable_Property_List },
|
|
{ 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, Binary_Input_Write_Property, Binary_Input_Property_Lists,
|
|
NULL, NULL, Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value,
|
|
Binary_Input_Change_Of_Value_Clear, NULL, NULL, NULL, Binary_Input_Create,
|
|
Binary_Input_Delete, NULL, Binary_Input_Writable_Property_List },
|
|
{ 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,
|
|
Multistate_Input_Write_Property, Multistate_Input_Property_Lists, NULL, NULL,
|
|
Multistate_Input_Encode_Value_List, Multistate_Input_Change_Of_Value,
|
|
Multistate_Input_Change_Of_Value_Clear, NULL, NULL, NULL, Multistate_Input_Create,
|
|
Multistate_Input_Delete, NULL, Multistate_Input_Writable_Property_List },
|
|
{ OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init, Multistate_Output_Count,
|
|
Multistate_Output_Index_To_Instance, Multistate_Output_Valid_Instance,
|
|
Multistate_Output_Object_Name, Multistate_Output_Read_Property,
|
|
Multistate_Output_Write_Property, Multistate_Output_Property_Lists, NULL, NULL,
|
|
Multistate_Output_Encode_Value_List, Multistate_Output_Change_Of_Value,
|
|
Multistate_Output_Change_Of_Value_Clear, NULL, NULL, NULL, Multistate_Output_Create,
|
|
Multistate_Output_Delete, NULL, Multistate_Output_Writable_Property_List },
|
|
{ MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
};
|
|
|
|
bool gateway_bacnet_stack_start(
|
|
uint32_t device_instance,
|
|
const char* device_name,
|
|
uint16_t udp_port,
|
|
gateway_bacnet_stack_write_callback_t write_callback,
|
|
void* callback_context)
|
|
{
|
|
if (!device_name || device_name[0] == '\0') {
|
|
device_name = "DALI Gateway";
|
|
}
|
|
if (udp_port == 0) {
|
|
udp_port = 47808;
|
|
}
|
|
|
|
Write_Callback = write_callback;
|
|
Write_Callback_Context = callback_context;
|
|
|
|
address_init();
|
|
Device_Set_Object_Instance_Number(device_instance);
|
|
Device_Init(Object_Table);
|
|
Device_Object_Name_ANSI_Init(device_name);
|
|
Device_Set_Vendor_Name("TonyCloud", strlen("TonyCloud"));
|
|
Device_Set_Vendor_Identifier(260);
|
|
Device_Set_Model_Name("DALI Gateway", strlen("DALI Gateway"));
|
|
Device_Set_Description("DALI BACnet/IP bridge", strlen("DALI BACnet/IP bridge"));
|
|
|
|
Analog_Value_Write_Present_Value_Callback_Set(analog_value_write);
|
|
Analog_Output_Write_Present_Value_Callback_Set(analog_output_write);
|
|
Binary_Value_Write_Present_Value_Callback_Set(binary_value_write);
|
|
Binary_Output_Write_Present_Value_Callback_Set(binary_output_write);
|
|
Multistate_Value_Write_Present_Value_Callback_Set(multistate_value_write);
|
|
Binary_Input_Write_Present_Value_Callback_Set(binary_input_write);
|
|
Multistate_Input_Write_Present_Value_Callback_Set(multistate_input_write);
|
|
Multistate_Output_Write_Present_Value_Callback_Set(multistate_output_write);
|
|
|
|
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
|
apdu_set_confirmed_handler(
|
|
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
|
apdu_set_confirmed_handler(
|
|
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control);
|
|
|
|
return bip_init(udp_port);
|
|
}
|
|
|
|
void gateway_bacnet_stack_cleanup(void)
|
|
{
|
|
bip_cleanup();
|
|
Write_Callback = NULL;
|
|
Write_Callback_Context = NULL;
|
|
}
|
|
|
|
bool gateway_bacnet_stack_upsert_object(
|
|
gateway_bacnet_object_kind_t object_kind,
|
|
uint32_t object_instance,
|
|
const char* object_name,
|
|
const char* description,
|
|
bool out_of_service,
|
|
uint32_t reliability)
|
|
{
|
|
if (!object_name || object_name[0] == '\0') {
|
|
object_name = "DALI BACnet Object";
|
|
}
|
|
if (!description) {
|
|
description = "";
|
|
}
|
|
|
|
BACNET_RELIABILITY object_reliability = (BACNET_RELIABILITY)reliability;
|
|
|
|
switch (object_kind) {
|
|
case GW_BACNET_OBJECT_ANALOG_VALUE:
|
|
if (!Analog_Value_Valid_Instance(object_instance)) {
|
|
Analog_Value_Create(object_instance);
|
|
}
|
|
Analog_Value_Name_Set(object_instance, object_name);
|
|
Analog_Value_Description_Set(object_instance, description);
|
|
Analog_Value_Units_Set(object_instance, UNITS_PERCENT);
|
|
Analog_Value_Present_Value_Set(object_instance, 0.0f, BACNET_NO_PRIORITY);
|
|
set_analog_value_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
|
|
if (!Analog_Output_Valid_Instance(object_instance)) {
|
|
Analog_Output_Create(object_instance);
|
|
}
|
|
Analog_Output_Name_Set(object_instance, object_name);
|
|
Analog_Output_Description_Set(object_instance, description);
|
|
Analog_Output_Units_Set(object_instance, UNITS_PERCENT);
|
|
Analog_Output_Present_Value_Set(object_instance, 0.0f, BACNET_MAX_PRIORITY);
|
|
set_analog_output_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_VALUE:
|
|
if (!Binary_Value_Valid_Instance(object_instance)) {
|
|
Binary_Value_Create(object_instance);
|
|
}
|
|
Binary_Value_Name_Set(object_instance, object_name);
|
|
Binary_Value_Description_Set(object_instance, description);
|
|
Binary_Value_Write_Enable(object_instance);
|
|
Binary_Value_Present_Value_Set(object_instance, BINARY_INACTIVE);
|
|
set_binary_value_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_OUTPUT:
|
|
if (!Binary_Output_Valid_Instance(object_instance)) {
|
|
Binary_Output_Create(object_instance);
|
|
}
|
|
Binary_Output_Name_Set(object_instance, object_name);
|
|
Binary_Output_Description_Set(object_instance, description);
|
|
Binary_Output_Present_Value_Set(object_instance, BINARY_INACTIVE, BACNET_MAX_PRIORITY);
|
|
set_binary_output_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
|
|
if (!Multistate_Value_Valid_Instance(object_instance)) {
|
|
Multistate_Value_Create(object_instance);
|
|
}
|
|
Multistate_Value_Name_Set(object_instance, object_name);
|
|
Multistate_Value_Description_Set(object_instance, description);
|
|
Multistate_Value_State_Text_List_Set(object_instance, Multistate_Value_States);
|
|
Multistate_Value_Write_Enable(object_instance);
|
|
Multistate_Value_Present_Value_Set(object_instance, 1);
|
|
set_multistate_value_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_ANALOG_INPUT:
|
|
if (!Analog_Input_Valid_Instance(object_instance)) {
|
|
Analog_Input_Create(object_instance);
|
|
}
|
|
Analog_Input_Name_Set(object_instance, object_name);
|
|
Analog_Input_Description_Set(object_instance, description);
|
|
Analog_Input_Units_Set(object_instance, UNITS_PERCENT);
|
|
Analog_Input_Present_Value_Set(object_instance, 0.0f);
|
|
set_analog_input_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_INPUT:
|
|
if (!Binary_Input_Valid_Instance(object_instance)) {
|
|
Binary_Input_Create(object_instance);
|
|
}
|
|
Binary_Input_Name_Set(object_instance, object_name);
|
|
Binary_Input_Description_Set(object_instance, description);
|
|
Binary_Input_Present_Value_Set(object_instance, BINARY_INACTIVE);
|
|
set_binary_input_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
|
|
if (!Multistate_Input_Valid_Instance(object_instance)) {
|
|
Multistate_Input_Create(object_instance);
|
|
}
|
|
Multistate_Input_Name_Set(object_instance, object_name);
|
|
Multistate_Input_Description_Set(object_instance, description);
|
|
Multistate_Input_State_Text_List_Set(object_instance, Multistate_Value_States);
|
|
Multistate_Input_Present_Value_Set(object_instance, 1);
|
|
set_multistate_input_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
|
|
if (!Multistate_Output_Valid_Instance(object_instance)) {
|
|
Multistate_Output_Create(object_instance);
|
|
}
|
|
Multistate_Output_Name_Set(object_instance, object_name);
|
|
Multistate_Output_Description_Set(object_instance, description);
|
|
Multistate_Output_State_Text_List_Set(object_instance, Multistate_Value_States);
|
|
Multistate_Output_Present_Value_Set(object_instance, 1, BACNET_MAX_PRIORITY);
|
|
set_multistate_output_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool gateway_bacnet_stack_set_object_state(
|
|
gateway_bacnet_object_kind_t object_kind,
|
|
uint32_t object_instance,
|
|
bool out_of_service,
|
|
uint32_t reliability)
|
|
{
|
|
BACNET_RELIABILITY object_reliability = (BACNET_RELIABILITY)reliability;
|
|
|
|
switch (object_kind) {
|
|
case GW_BACNET_OBJECT_ANALOG_VALUE:
|
|
set_analog_value_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
|
|
set_analog_output_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_VALUE:
|
|
set_binary_value_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_OUTPUT:
|
|
set_binary_output_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
|
|
set_multistate_value_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_ANALOG_INPUT:
|
|
set_analog_input_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_INPUT:
|
|
set_binary_input_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
|
|
set_multistate_input_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
|
|
set_multistate_output_state(object_instance, out_of_service, object_reliability);
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool gateway_bacnet_stack_set_present_value(
|
|
gateway_bacnet_object_kind_t object_kind,
|
|
uint32_t object_instance,
|
|
const gateway_bacnet_write_value_t* value)
|
|
{
|
|
if (!value) {
|
|
return false;
|
|
}
|
|
|
|
switch (object_kind) {
|
|
case GW_BACNET_OBJECT_ANALOG_VALUE:
|
|
return Analog_Value_Present_Value_Set(
|
|
object_instance, (float)value->real_value, BACNET_NO_PRIORITY);
|
|
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
|
|
return Analog_Output_Present_Value_Set(
|
|
object_instance, (float)value->real_value, BACNET_MAX_PRIORITY);
|
|
case GW_BACNET_OBJECT_ANALOG_INPUT:
|
|
Analog_Input_Present_Value_Set(object_instance, (float)value->real_value);
|
|
return true;
|
|
case GW_BACNET_OBJECT_BINARY_VALUE:
|
|
return Binary_Value_Present_Value_Set(
|
|
object_instance, value->boolean_value ? BINARY_ACTIVE : BINARY_INACTIVE);
|
|
case GW_BACNET_OBJECT_BINARY_OUTPUT:
|
|
return Binary_Output_Present_Value_Set(
|
|
object_instance, value->boolean_value ? BINARY_ACTIVE : BINARY_INACTIVE,
|
|
BACNET_MAX_PRIORITY);
|
|
case GW_BACNET_OBJECT_BINARY_INPUT:
|
|
return Binary_Input_Present_Value_Set(
|
|
object_instance, value->boolean_value ? BINARY_ACTIVE : BINARY_INACTIVE);
|
|
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
|
|
return Multistate_Value_Present_Value_Set(
|
|
object_instance, value->unsigned_value == 0 ? 1 : value->unsigned_value);
|
|
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
|
|
return Multistate_Output_Present_Value_Set(
|
|
object_instance, value->unsigned_value == 0 ? 1 : value->unsigned_value,
|
|
BACNET_MAX_PRIORITY);
|
|
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
|
|
return Multistate_Input_Present_Value_Set(
|
|
object_instance, value->unsigned_value == 0 ? 1 : value->unsigned_value);
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool gateway_bacnet_stack_clear_objects(void)
|
|
{
|
|
return clear_analog_value_objects() &&
|
|
clear_analog_output_objects() &&
|
|
clear_analog_input_objects() &&
|
|
clear_binary_value_objects() &&
|
|
clear_binary_output_objects() &&
|
|
clear_binary_input_objects() &&
|
|
clear_multistate_value_objects() &&
|
|
clear_multistate_input_objects() &&
|
|
clear_multistate_output_objects();
|
|
}
|
|
|
|
void gateway_bacnet_stack_send_i_am(void)
|
|
{
|
|
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
|
}
|
|
|
|
void gateway_bacnet_stack_poll(uint16_t elapsed_ms)
|
|
{
|
|
BACNET_ADDRESS src = { 0 };
|
|
uint16_t pdu_len = bip_receive(&src, Rx_Buffer, sizeof(Rx_Buffer), 0);
|
|
if (pdu_len > 0) {
|
|
npdu_handler(&src, Rx_Buffer, pdu_len);
|
|
}
|
|
if (elapsed_ms > 0) {
|
|
tsm_timer_milliseconds(elapsed_ms);
|
|
Device_Timer(elapsed_ms);
|
|
}
|
|
} |