Important Update:

- DeviceCore:
  - Allow different event output types: None, Simple or JSON
  - Add date & time to JSON events
This commit is contained in:
Charl Wentzel
2019-07-15 17:29:45 +02:00
parent 91a7707fef
commit df371d4f10
2 changed files with 118 additions and 32 deletions

View File

@@ -13,6 +13,7 @@
// redA Libraries
#include "ApplicationCore.h"
#include "DeviceCore.h"
#include "DateTimeCore.h"
//---------------------------------------------------------------------------
@@ -35,6 +36,7 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo
// Data Structures
ConfigTypes = new CDataMember();
ValueTree = new CDataMember();
EventData = new CDataMember();
JSONparse = new CJSONparse();
}
//---------------------------------------------------------------------------
@@ -52,6 +54,8 @@ CDeviceCore::~CDeviceCore()
delete ConfigTypes;
if (ValueTree)
delete ValueTree;
if (EventData)
delete EventData;
}
//---------------------------------------------------------------------------
@@ -61,6 +65,7 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
CDataMember * PollConfig = NULL;
int IntVal1;
int IntVal2;
char * StrVal;
// Call Previous load config
if (!CFunctionCore::Init( FunctionConfig ))
@@ -105,6 +110,13 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
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
if (DeviceInit) {
InitDevices( FunctionConfig );
@@ -1764,54 +1776,114 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * SourceRef,
// Generate Event output
bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force )
{
char Message[200];
int EventLen = EventMsgLen;
CDataMember * Path = NULL;
// Validate
if (!Param || !(Param->EventChannel))
return false;
if (EventOutputType == et_None)
return false;
// Check Timer or force
if (Force ||
(Param->EventInterval && Timeout( Param->EventTimeout, Param->EventInterval )) )
{
// Create message
// Post event
switch (Param->DataType)
{
case dtBool :
sprintf( Message, "%s: %u\n", Param->DataPath, *((bool*)Param->Value) );
if (true) {
// JSON output
EventData->Clear();
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;
case dtUnsigned16 :
sprintf( Message, "%s: %u\n", Param->DataPath, *((u_int16_t*)Param->Value) );
case dtUnsigned16 : EventData->SetChBool( "Value", *((u_int16_t*)Param->Value) );
break;
case dtUnsigned32_HL :
case dtUnsigned32_LH :
sprintf( Message, "%s: %u\n", Param->DataPath, *((u_int32_t*)Param->Value) );
case dtUnsigned32_LH : EventData->SetChBool( "Value", *((u_int32_t*)Param->Value) );
break;
case dtSigned16 :
sprintf( Message, "%s: %d\n", Param->DataPath, *((int16_t*)Param->Value) );
case dtSigned16 : EventData->SetChBool( "Value", *((int16_t*)Param->Value) );
break;
case dtSigned32_HL :
case dtSigned32_LH :
sprintf( Message, "%s: %d\n", Param->DataPath, *((int32_t*)Param->Value) );
case dtSigned32_LH : EventData->SetChBool( "Value", *((int32_t*)Param->Value) );
break;
case dtFloat32_L :
case dtFloat32_B :
sprintf( Message, "%s: %f\n", Param->DataPath, *((float*)Param->Value) );
case dtFloat32_B : EventData->SetChBool( "Value", *((float*)Param->Value) );
break;
case dtString :
sprintf( Message, "%s: %s\n", Param->DataPath, (char*)Param->Value );
case dtString : EventData->SetChBool( "Value", (char*)Param->Value );
break;
default :
default : EventData->SetChNull( "Value" );
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
if (Param->EventInterval) {

View File

@@ -20,12 +20,14 @@
// Enumerated types
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;
// Constants
const char DataTypeCount = 10;
const char DataTypeName[][20] = { "None", "Boolean", "Unsigned16", "Signed16", "Unsigned32_HL", "Unsigned32_LH",
"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
@@ -152,6 +154,12 @@ protected:
int PollRetry = 0; // No of polling retries that has timed out
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
bool DestroyDevice( TDevice ** Device );
@@ -298,6 +306,12 @@ protected:
if (!strcasecmp( TypeName, DataTypeName[Type])) break;
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 );