Important Update:
- DeviceCore: - Allow different event output types: None, Simple or JSON - Add date & time to JSON events
This commit is contained in:
110
DeviceCore.cpp
110
DeviceCore.cpp
@@ -13,6 +13,7 @@
|
|||||||
// redA Libraries
|
// redA Libraries
|
||||||
#include "ApplicationCore.h"
|
#include "ApplicationCore.h"
|
||||||
#include "DeviceCore.h"
|
#include "DeviceCore.h"
|
||||||
|
#include "DateTimeCore.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo
|
|||||||
// Data Structures
|
// Data Structures
|
||||||
ConfigTypes = new CDataMember();
|
ConfigTypes = new CDataMember();
|
||||||
ValueTree = new CDataMember();
|
ValueTree = new CDataMember();
|
||||||
|
EventData = new CDataMember();
|
||||||
JSONparse = new CJSONparse();
|
JSONparse = new CJSONparse();
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -52,6 +54,8 @@ CDeviceCore::~CDeviceCore()
|
|||||||
delete ConfigTypes;
|
delete ConfigTypes;
|
||||||
if (ValueTree)
|
if (ValueTree)
|
||||||
delete ValueTree;
|
delete ValueTree;
|
||||||
|
if (EventData)
|
||||||
|
delete EventData;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -61,6 +65,7 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
|
|||||||
CDataMember * PollConfig = NULL;
|
CDataMember * PollConfig = NULL;
|
||||||
int IntVal1;
|
int IntVal1;
|
||||||
int IntVal2;
|
int IntVal2;
|
||||||
|
char * StrVal;
|
||||||
|
|
||||||
// Call Previous load config
|
// Call Previous load config
|
||||||
if (!CFunctionCore::Init( FunctionConfig ))
|
if (!CFunctionCore::Init( FunctionConfig ))
|
||||||
@@ -105,6 +110,13 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
|
|||||||
ProcessName, Name, PersistFile );
|
ProcessName, Name, PersistFile );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Event Output
|
||||||
|
StrVal = (char*)Config->GetChStr( "EventOutput", "None", true );
|
||||||
|
EventOutputType = GetEventType( StrVal );
|
||||||
|
|
||||||
|
Log->Message( LogLevel, dlMedium, "%s/%s: Event Output - Type:%s",
|
||||||
|
ProcessName, Name, EventTypeName[EventOutputType] );
|
||||||
|
|
||||||
// Update Devices -- may want to do it from derived class intead
|
// Update Devices -- may want to do it from derived class intead
|
||||||
if (DeviceInit) {
|
if (DeviceInit) {
|
||||||
InitDevices( FunctionConfig );
|
InitDevices( FunctionConfig );
|
||||||
@@ -1764,54 +1776,114 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * SourceRef,
|
|||||||
// Generate Event output
|
// Generate Event output
|
||||||
bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force )
|
bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force )
|
||||||
{
|
{
|
||||||
char Message[200];
|
int EventLen = EventMsgLen;
|
||||||
|
CDataMember * Path = NULL;
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
if (!Param || !(Param->EventChannel))
|
if (!Param || !(Param->EventChannel))
|
||||||
return false;
|
return false;
|
||||||
|
if (EventOutputType == et_None)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check Timer or force
|
// Check Timer or force
|
||||||
if (Force ||
|
if (Force ||
|
||||||
(Param->EventInterval && Timeout( Param->EventTimeout, Param->EventInterval )) )
|
(Param->EventInterval && Timeout( Param->EventTimeout, Param->EventInterval )) )
|
||||||
{
|
{
|
||||||
|
// Create message
|
||||||
// Post event
|
// Post event
|
||||||
switch (Param->DataType)
|
if (true) {
|
||||||
{
|
// JSON output
|
||||||
case dtBool :
|
EventData->Clear();
|
||||||
sprintf( Message, "%s: %u\n", Param->DataPath, *((bool*)Param->Value) );
|
EventData->SetChStr( "Type", "ParamEvent" );
|
||||||
|
EventData->SetChStr( "Time", GetDateTimeStr() );
|
||||||
|
|
||||||
|
Path = EventData->GetChild( "Path", true );
|
||||||
|
Path->SetArray();
|
||||||
|
bool NewMember = true;
|
||||||
|
char * Start = NULL;
|
||||||
|
char * Pos = Param->DataPath;
|
||||||
|
while (true) {
|
||||||
|
if (!*Pos || (*Pos == '/')) {
|
||||||
|
NewMember = true;
|
||||||
|
if (Start)
|
||||||
|
Path->SetChStr( "[]", Start, Pos-Start );
|
||||||
|
if (!*Pos)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (NewMember) {
|
||||||
|
NewMember = false;
|
||||||
|
Start = Pos;
|
||||||
|
}
|
||||||
|
Pos++;
|
||||||
|
}
|
||||||
|
EventData->SetChStr( "Device", Param->Device->Name );
|
||||||
|
EventData->SetChStr( "Param", Param->Name );
|
||||||
|
|
||||||
|
switch (Param->DataType) {
|
||||||
|
case dtBool : EventData->SetChBool( "Value", *((bool*)Param->Value) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtUnsigned16 :
|
case dtUnsigned16 : EventData->SetChBool( "Value", *((u_int16_t*)Param->Value) );
|
||||||
sprintf( Message, "%s: %u\n", Param->DataPath, *((u_int16_t*)Param->Value) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtUnsigned32_HL :
|
case dtUnsigned32_HL :
|
||||||
case dtUnsigned32_LH :
|
case dtUnsigned32_LH : EventData->SetChBool( "Value", *((u_int32_t*)Param->Value) );
|
||||||
sprintf( Message, "%s: %u\n", Param->DataPath, *((u_int32_t*)Param->Value) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtSigned16 :
|
case dtSigned16 : EventData->SetChBool( "Value", *((int16_t*)Param->Value) );
|
||||||
sprintf( Message, "%s: %d\n", Param->DataPath, *((int16_t*)Param->Value) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtSigned32_HL :
|
case dtSigned32_HL :
|
||||||
case dtSigned32_LH :
|
case dtSigned32_LH : EventData->SetChBool( "Value", *((int32_t*)Param->Value) );
|
||||||
sprintf( Message, "%s: %d\n", Param->DataPath, *((int32_t*)Param->Value) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtFloat32_L :
|
case dtFloat32_L :
|
||||||
case dtFloat32_B :
|
case dtFloat32_B : EventData->SetChBool( "Value", *((float*)Param->Value) );
|
||||||
sprintf( Message, "%s: %f\n", Param->DataPath, *((float*)Param->Value) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtString :
|
case dtString : EventData->SetChBool( "Value", (char*)Param->Value );
|
||||||
sprintf( Message, "%s: %s\n", Param->DataPath, (char*)Param->Value );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default : EventData->SetChNull( "Value" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Output( Param->EventChannel, NULL, true, Message, strlen(Message) );
|
JSONparse->SetBase( EventData );
|
||||||
|
JSONparse->WriteToString( NULL, EventMsg, EventLen, 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (Param->DataType)
|
||||||
|
{
|
||||||
|
case dtBool : sprintf( EventMsg, "%s: %u\n", Param->DataPath, *((bool*)Param->Value) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dtUnsigned16 : sprintf( EventMsg, "%s: %u\n", Param->DataPath, *((u_int16_t*)Param->Value) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dtUnsigned32_HL :
|
||||||
|
case dtUnsigned32_LH : sprintf( EventMsg, "%s: %u\n", Param->DataPath, *((u_int32_t*)Param->Value) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dtSigned16 : sprintf( EventMsg, "%s: %d\n", Param->DataPath, *((int16_t*)Param->Value) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dtSigned32_HL :
|
||||||
|
case dtSigned32_LH : sprintf( EventMsg, "%s: %d\n", Param->DataPath, *((int32_t*)Param->Value) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dtFloat32_L :
|
||||||
|
case dtFloat32_B : sprintf( EventMsg, "%s: %f\n", Param->DataPath, *((float*)Param->Value) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dtString : sprintf( EventMsg, "%s: %s\n", Param->DataPath, (char*)Param->Value );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default : sprintf( EventMsg, "%s:\n", Param->DataPath );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send event
|
||||||
|
Output( Param->EventChannel, NULL, true, EventMsg, strlen(EventMsg) );
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
if (Param->EventInterval) {
|
if (Param->EventInterval) {
|
||||||
|
|||||||
18
DeviceCore.h
18
DeviceCore.h
@@ -20,12 +20,14 @@
|
|||||||
// Enumerated types
|
// Enumerated types
|
||||||
typedef enum { dtNone = 0, dtBool = 1, dtUnsigned16 = 2, dtSigned16 = 3, dtUnsigned32_HL = 4, dtUnsigned32_LH = 5,
|
typedef enum { dtNone = 0, dtBool = 1, dtUnsigned16 = 2, dtSigned16 = 3, dtUnsigned32_HL = 4, dtUnsigned32_LH = 5,
|
||||||
dtSigned32_HL = 6, dtSigned32_LH = 7, dtFloat32_L = 8, dtFloat32_B = 9, dtString = 10 } EDeviceDataType;
|
dtSigned32_HL = 6, dtSigned32_LH = 7, dtFloat32_L = 8, dtFloat32_B = 9, dtString = 10 } EDeviceDataType;
|
||||||
|
|
||||||
// Constants
|
|
||||||
const char DataTypeCount = 10;
|
const char DataTypeCount = 10;
|
||||||
const char DataTypeName[][20] = { "None", "Boolean", "Unsigned16", "Signed16", "Unsigned32_HL", "Unsigned32_LH",
|
const char DataTypeName[][20] = { "None", "Boolean", "Unsigned16", "Signed16", "Unsigned32_HL", "Unsigned32_LH",
|
||||||
"Signed32_HL", "Signed32_LH", "Float32_L", "Float32_B", "String" };
|
"Signed32_HL", "Signed32_LH", "Float32_L", "Float32_B", "String" };
|
||||||
|
|
||||||
|
typedef enum { et_None = 0, et_Simple = 1, et_JSON = 2 } EEventType;
|
||||||
|
const char EventTypeCount = 3;
|
||||||
|
const char EventTypeName[][10] = { "None", "Simple", "JSON" };
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Structure prototypes
|
// Structure prototypes
|
||||||
@@ -152,6 +154,12 @@ protected:
|
|||||||
int PollRetry = 0; // No of polling retries that has timed out
|
int PollRetry = 0; // No of polling retries that has timed out
|
||||||
int MaxRetries = 3; // Max allowed retries
|
int MaxRetries = 3; // Max allowed retries
|
||||||
|
|
||||||
|
// Event output
|
||||||
|
EEventType EventOutputType = et_None;
|
||||||
|
CDataMember * EventData = NULL;
|
||||||
|
const int EventMsgLen = 1000;
|
||||||
|
char EventMsg[1000] = {0};
|
||||||
|
|
||||||
// Manage Devices
|
// Manage Devices
|
||||||
bool DestroyDevice( TDevice ** Device );
|
bool DestroyDevice( TDevice ** Device );
|
||||||
|
|
||||||
@@ -298,6 +306,12 @@ protected:
|
|||||||
if (!strcasecmp( TypeName, DataTypeName[Type])) break;
|
if (!strcasecmp( TypeName, DataTypeName[Type])) break;
|
||||||
return (Type == DataTypeCount)? dtNone : (EDeviceDataType)Type;
|
return (Type == DataTypeCount)? dtNone : (EDeviceDataType)Type;
|
||||||
}
|
}
|
||||||
|
inline EEventType GetEventType( const char * TypeName ) {
|
||||||
|
int Type;
|
||||||
|
for (Type = 0; Type < EventTypeCount; Type++)
|
||||||
|
if (!strcasecmp( TypeName, EventTypeName[Type])) break;
|
||||||
|
return (Type == EventTypeCount)? et_None : (EEventType)Type;
|
||||||
|
}
|
||||||
|
|
||||||
bool CompareParamString( const char * ParamValue, const int ParamLen, const char * Value, const int Len );
|
bool CompareParamString( const char * ParamValue, const int ParamLen, const char * Value, const int Len );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user