Major Update:

- JSONparseCore:
  - Add initialisations values for class params
  - Add method AddBase() to dynamically change DataTree
  - Added Error messages
- DeviceCore:
  - Implement ValueTree (JSON tree)
    - Node are added as devices & params are created/added
    - Nodes (and path) are referenced on devices & params
    - Node values are updated as device params are updated
  - Added Persistence File (not yet complete)
  - Updated InitDevices() & InitDeviceParams()
    - Split into smaller methods: CopyTemplateParam() & InitDeviceParam()
    - Load Device definition or Parameter maps from files
    - Allow loading of nested parameter map files
    - Load Parameter as JSON tree, generate names/path dynamically
This commit is contained in:
Charl Wentzel
2019-01-09 10:56:38 +02:00
parent 3e40f7a86d
commit 3472f506b6
4 changed files with 321 additions and 126 deletions

View File

@@ -44,7 +44,8 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo
// Data Structures // Data Structures
DeviceInit = true; DeviceInit = true;
ConfigTypes = new CDataMember(); ConfigTypes = new CDataMember();
JSONparse = new CJSONparse( ConfigTypes ); ValueTree = new CDataMember();
JSONparse = new CJSONparse();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -59,11 +60,14 @@ CDeviceCore::~CDeviceCore()
delete JSONparse; delete JSONparse;
if (ConfigTypes) if (ConfigTypes)
delete ConfigTypes; delete ConfigTypes;
if (ValueTree)
delete ValueTree;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::Init( CDataMember * FunctionConfig ) bool CDeviceCore::Init( CDataMember * FunctionConfig )
{ {
char * PersistFile = NULL;
char * ConfigName = NULL; char * ConfigName = NULL;
CDataMember * PollConfig = NULL; CDataMember * PollConfig = NULL;
int IntVal1; int IntVal1;
@@ -102,9 +106,20 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
Log->Message( LogLevel, dlMedium, "%s/%s: Set polling param - Int:%d, T/O:%d, Max:%d", Log->Message( LogLevel, dlMedium, "%s/%s: Set polling param - Int:%d, T/O:%d, Max:%d",
ProcessName, Name, PollInterval, ReplyTimeout, MaxRetries ); ProcessName, Name, PollInterval, ReplyTimeout, MaxRetries );
// Load Value Tree from persistence file
if ((PersistFile = (char*)Config->GetChStr( "PersistFile", NULL, true ))) {
JSONparse->SetBase( ValueTree );
JSONparse->ReadFromFile( NULL, PersistFile );
Log->Message( LogLevel, dlMedium, "%s/%s: Persistence File '%s' loaded",
ProcessName, Name, PersistFile );
}
// 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) {
CDeviceCore::InitDevices( FunctionConfig ); InitDevices( FunctionConfig );
//JSONparse->SetBase( ValueTree );
//JSONparse->WriteToScreen( NULL, 2 );
} }
return true; return true;
@@ -113,70 +128,164 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
bool CDeviceCore::InitDevices( CDataMember * FunctionConfig ) bool CDeviceCore::InitDevices( CDataMember * FunctionConfig )
{ {
CDataMember * DeviceData = NULL; CDataMember * DeviceConfig = NULL;
TDevice * Device = NULL; TDevice * Device = NULL;
char * Definition = NULL;
char * DeviceName = NULL; char * DeviceName = NULL;
int DeviceID = 0; int DeviceID = 0;
char * DeviceAddr = NULL; char * DeviceAddr = NULL;
char * DeviceType = NULL; char * DeviceType = NULL;
char * DataPath = NULL;
// Load Device Types // Load Device Types
DeviceData = Config->GetChFirstChild( "DeviceTypes", true ); DeviceConfig = Config->GetChFirstChild( "DeviceTypes", true );
while (DeviceData) while (DeviceConfig)
{ {
DeviceType = (char*)DeviceData->GetName(); DeviceType = (char*)DeviceConfig->GetName();
Device = AddDeviceType( DeviceType ); if (!DeviceConfig->isObject()) {
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device type config for '%s'",
ProcessName, Name, DeviceType );
DeviceConfig = DeviceConfig->GetNextPeer();
continue;
}
DataPath = (char*)DeviceConfig->GetChStr( "DataPath", NULL );
Device = AddDeviceType( DeviceType, DataPath );
if (Device) { if (Device) {
if (DeviceData->isString()) { if ((Definition = (char*)DeviceConfig->GetChStr( "Definition", NULL, false ))) {
if (JSONparse->ReadFromFile( DeviceType, DeviceData->GetStr() )) { // Contains file reference JSONparse->SetBase( ConfigTypes );
InitDeviceParams( Device, ConfigTypes->GetChild( DeviceType ) ); if (JSONparse->ReadFromFile( DeviceType, Definition )) { // Contains file reference
InitDeviceParams( Device, ConfigTypes->GetChild( DeviceType ), NULL );
InitParamGroups( Device, ConfigTypes->GetChild( DeviceType ) ); InitParamGroups( Device, ConfigTypes->GetChild( DeviceType ) );
JSONparse->WriteToFile( DeviceType, DeviceData->GetStr() );
JSONparse->SetBase( ConfigTypes );
JSONparse->WriteToFile( DeviceType, Definition );
} }
else { else {
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Fail to load device type '%s' from file: '%s'", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Fail to load device type '%s' from file: '%s'",
ProcessName, Name, DeviceType, DeviceData->GetStr() ); ProcessName, Name, DeviceType, DeviceConfig->GetStr() );
} }
} }
else if (DeviceData->isObject()) {
InitDeviceParams( Device, DeviceData ); // Contains definition
InitParamGroups( Device, DeviceData );
}
else { else {
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device type config for '%s'", InitDeviceParams( Device, DeviceConfig, NULL ); // Contains definition
ProcessName, Name, DeviceType ); InitParamGroups( Device, DeviceConfig );
} }
} }
DeviceData = DeviceData->GetNextPeer(); DeviceConfig = DeviceConfig->GetNextPeer();
} }
// Load Actual Devices // Load Actual Devices
DeviceData = Config->GetChFirstChild( "Devices", true ); DeviceConfig = Config->GetChFirstChild( "Devices", true );
while (DeviceData) while (DeviceConfig)
{ {
DeviceName = (char*)DeviceData->GetName(); DeviceName = (char*)DeviceConfig->GetName();
DeviceID = DeviceData->GetChInt( "ID", 0 ); if (!DeviceConfig->isObject()) {
DeviceAddr = (char*)DeviceData->GetChStr( "Address", NULL ); if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device config for '%s'",
DeviceType = (char*)DeviceData->GetChStr( "Type", NULL ); ProcessName, Name, DeviceName );
Device = AddDevice( DeviceName, DeviceType, DeviceID, DeviceAddr ); DeviceConfig = DeviceConfig->GetNextPeer();
continue;
}
DeviceID = DeviceConfig->GetChInt( "ID", 0 );
DeviceAddr = (char*)DeviceConfig->GetChStr( "Address", NULL );
DeviceType = (char*)DeviceConfig->GetChStr( "Type", NULL );
DataPath = (char*)DeviceConfig->GetChStr( "DataPath", NULL );
Device = AddDevice( DeviceName, DeviceType, DeviceID, DeviceAddr, DataPath );
if (Device) { if (Device) {
InitDeviceParams( Device, DeviceData ); InitDeviceParams( Device, DeviceConfig, Device->DataNode );
InitParamGroups( Device, DeviceData ); InitParamGroups( Device, DeviceConfig );
} }
DeviceData = DeviceData->GetNextPeer(); DeviceConfig = DeviceConfig->GetNextPeer();
} }
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig ) bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig, CDataMember * ParentNode )
{ {
CDataMember * ParamData; CDataMember * ParamConfig;
TDeviceParam * Template;
bool isType = (Device->Name)? false : true;
// Copy Template Params
Template = (Device->Template)? Device->Template->FirstParam : NULL;
while (Template) {
CopyTemplateParam( Device, Template, ParentNode );
Template = Template->Next;
}
// Read Device Params
ParamConfig = DeviceConfig->GetChFirstChild( "Parameters", true );
while (ParamConfig) {
InitDeviceParam( Device, ParamConfig, NULL, ((isType)? NULL : Device->DataPath), ParentNode );
ParamConfig = ParamConfig->GetNextPeer();
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::CopyTemplateParam( TDevice * Device, TDeviceParam * Template, CDataMember * ParentNode )
{
TDeviceParam * Param = NULL;
CDataMember * DataNode = NULL;
char * DataPath = NULL;
if ((Param = AddDeviceParam( Device, Template->Name, Template->DataType, Template->Len )))
{
SetParamAccess( Param, Template->Read, Template->Write );
if (Template->DataPath) {
DataPath = (char*)malloc( strlen(Device->DataPath) + strlen(Template->DataPath) + 2);
sprintf( DataPath, "%s/%s", Device->DataPath, Template->DataPath );
DataNode = (Device->DataNode)? Device->DataNode->GetChild( Template->DataPath, true ) : NULL;
SetDataPath( Param, DataPath, DataNode );
}
if ((Template->DataType == dtUnsigned16) || (Template->DataType == dtUnsigned32_HL) || (Template->DataType == dtUnsigned32_LH)) {
UpdateUnsignedValue( Param, *((u_int16_t*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetUnsignedValue( Param, *((u_int16_t*)Template->Value), true );
}
else if ((Template->DataType == dtSigned16) || (Template->DataType == dtSigned32_HL) || (Template->DataType == dtSigned32_LH)) {
UpdateSignedValue( Param, *((int16_t*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetSignedValue( Param, *((int16_t*)Template->Value), true );
}
else if ((Template->DataType == dtFloat32_L) || (Template->DataType == dtFloat32_B)) {
UpdateFloatValue( Param, *((float*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetFloatValue( Param, *((float*)Template->Value), true );
}
else if (Template->DataType == dtString) {
UpdateStringValue( Param, (char*)Template->Value, Template->Len, Template->Changed );
if (Template->SetChanged)
SetStringValue( Param, (char*)Template->Value, Template->Len, true );
}
SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval );
}
if (DataPath) free( DataPath );
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::InitDeviceParam( TDevice * Device, CDataMember * ParamConfig,
const char * ParentName, const char * ParentPath, CDataMember * ParentNode )
{
char * NodeName;
char * FullName;
char * DataPath;
CDataMember * DataNode;
CDataMember * Children;
CDataMember * ChildConfig;
CDataMember * ChildMap;
CDataMember * InitVal; CDataMember * InitVal;
TDeviceParam * Param; TDeviceParam * Param;
TDeviceParam * Template;
EDeviceDataType DataType; EDeviceDataType DataType;
@@ -185,55 +294,63 @@ bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfi
char * EventOut; char * EventOut;
int EventInt; int EventInt;
// Copy Template // Create Node Name
Template = (Device->Template)? Device->Template->FirstParam : NULL; NodeName = (char*)ParamConfig->GetName();
while (Template) if (ParentName && *ParentName) {
{ FullName = (char*)malloc( strlen(ParentName) + strlen(NodeName) + 2 );
if ((Param = AddDeviceParam( Device, Template->Name, Template->DataType, Template->Len ))) sprintf( FullName, "%s_%s", ParentName, NodeName );
{ } else {
SetParamAccess( Param, Template->Read, Template->Write ); FullName = strdup( NodeName );
SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval );
if ((Template->DataType == dtUnsigned16) || (Template->DataType == dtUnsigned32_HL) || (Template->DataType == dtUnsigned32_LH)) {
UpdateUnsignedValue( Param, *((u_int16_t*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetUnsignedValue( Param, *((u_int16_t*)Template->Value), true );
}
else if ((Template->DataType == dtSigned16) || (Template->DataType == dtSigned32_HL) || (Template->DataType == dtSigned32_LH)) {
UpdateSignedValue( Param, *((int16_t*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetSignedValue( Param, *((int16_t*)Template->Value), true );
}
else if ((Template->DataType == dtFloat32_L) || (Template->DataType == dtFloat32_B)) {
UpdateFloatValue( Param, *((float*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetFloatValue( Param, *((float*)Template->Value), true );
}
else if (Template->DataType == dtString) {
UpdateStringValue( Param, (char*)Template->Value, Template->Len, Template->Changed );
if (Template->SetChanged)
SetStringValue( Param, (char*)Template->Value, Template->Len, true );
}
}
Template = Template->Next;
} }
// Add Parameters // Create Node Path
ParamData = DeviceConfig->GetChFirstChild( "Parameters", true ); DataNode = (ParentNode)? ParentNode->GetChild( NodeName, true ) : NULL;
while (ParamData) if (ParentPath && *ParentPath) {
{ DataPath = (char*)malloc( strlen(ParentPath) + strlen(NodeName) + 2 );
DataType = GetDataType((char*)ParamData->GetChStr( "Type", "Unsigned16", true )); sprintf( DataPath, "%s/%s", ParentPath, NodeName );
if ((Param = AddDeviceParam( Device, ParamData->GetName(), DataType, 1 ))) } else {
{ DataPath = strdup( NodeName );
Read = ParamData->GetChBool( "Read", false, true ); }
Write = ParamData->GetChBool( "Write", false, true );
if ((Children = ParamConfig->GetChild( "Children", false ))) {
// Data Branch
if (Children->isString()) {
// Load from file
ChildMap = new CDataMember();
JSONparse->SetBase( ChildMap );
if (!JSONparse->ReadFromFile( NULL, Children->GetStr() )) {
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Fail to load parameters from file: '%s'",
ProcessName, Name, Children->GetStr() );
}
else {
ChildConfig = ChildMap->GetFirstChild();
while (ChildConfig) {
InitDeviceParam( Device, ChildConfig, FullName, DataPath, DataNode );
ChildConfig = ChildConfig->GetNextPeer();
}
}
delete ChildMap;
}
else {
// Load children
ChildConfig = Children->GetFirstChild();
while (ChildConfig) {
InitDeviceParam( Device, ChildConfig, FullName, DataPath, DataNode );
}
}
}
else {
// Data Leaf
DataType = GetDataType((char*)ParamConfig->GetChStr( "Type", "Unsigned16", true ));
if ((Param = AddDeviceParam( Device, FullName, DataType, 1 ))) {
// Leaf
Read = ParamConfig->GetChBool( "Read", false, true );
Write = ParamConfig->GetChBool( "Write", false, true );
SetParamAccess( Param, Read, Write ); SetParamAccess( Param, Read, Write );
EventOut = (char*)ParamData->GetChStr( "EventChannel", NULL, false ); SetDataPath( Param, DataPath, DataNode );
EventInt = ParamData->GetChInt( "EventInterval", 0, false );
SetParamEvent( Param, EventOut, EventInt );
if ((InitVal = ParamData->GetChild( "InitValue", false ))) { if ((InitVal = ParamConfig->GetChild( "InitValue", false ))) {
if ((DataType == dtUnsigned16) || (DataType == dtUnsigned32_HL) || (DataType == dtUnsigned32_LH)) { if ((DataType == dtUnsigned16) || (DataType == dtUnsigned32_HL) || (DataType == dtUnsigned32_LH)) {
UpdateUnsignedValue( Param, InitVal->GetInt(0), Read ); UpdateUnsignedValue( Param, InitVal->GetInt(0), Read );
if (Write) if (Write)
@@ -255,10 +372,15 @@ bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfi
SetStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), true ); SetStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), true );
} }
} }
EventOut = (char*)ParamConfig->GetChStr( "EventChannel", NULL, false );
EventInt = ParamConfig->GetChInt( "EventInterval", 0, false );
SetParamEvent( Param, EventOut, EventInt );
} }
// Read + Event Out
ParamData = ParamData->GetNextPeer();
} }
if (FullName) free( FullName );
if (DataPath) free( DataPath );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -394,7 +516,7 @@ bool CDeviceCore::CheckReplyTimeout()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName ) TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName, const char * DataPath )
{ {
TDevice ** DeviceType = GetDeviceTypePtr( DeviceTypeName ); TDevice ** DeviceType = GetDeviceTypePtr( DeviceTypeName );
@@ -410,7 +532,8 @@ TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName )
else { else {
*DeviceType = new TDevice; *DeviceType = new TDevice;
(*DeviceType)->Type = strdup( DeviceTypeName ); (*DeviceType)->Type = strdup( DeviceTypeName );
(*DeviceType)->DataPath = strdup( DataPath );
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device type '%s'", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device type '%s'",
ProcessName, Name, DeviceTypeName ); ProcessName, Name, DeviceTypeName );
@@ -419,7 +542,8 @@ TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * DeviceType, const int DeviceID, const char * DeviceAddress ) TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * DeviceType,
const int DeviceID, const char * DeviceAddress, const char * DataPath )
{ {
TDevice ** Device = &FirstDevice; TDevice ** Device = &FirstDevice;
@@ -463,6 +587,18 @@ TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * DeviceTy
if (DeviceType && *DeviceType) { if (DeviceType && *DeviceType) {
(*Device)->Type = strdup( DeviceType ); (*Device)->Type = strdup( DeviceType );
(*Device)->Template = GetDeviceType( DeviceType ); (*Device)->Template = GetDeviceType( DeviceType );
if (DataPath && *DataPath) {
(*Device)->DataPath = strdup( DataPath );
(*Device)->DataNode = ValueTree->GetChild( (*Device)->DataPath, true );
}
else if ((*Device)->Template && (*Device)->Template->DataPath) {
// Use Template path as prefix, then add device ID or address
int PathLen = strlen((*Device)->Template->DataPath) + strlen(DeviceName) + 1;
(*Device)->DataPath = (char*)malloc(PathLen +1);
sprintf( (*Device)->DataPath, "%s/%s", (*Device)->Template->DataPath, DeviceName );
(*Device)->DataNode = ValueTree->GetChild( (*Device)->DataPath, true );
}
} }
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device '%s' - Tp:'%s'%s, ID:%d, Addr:'%s'", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device '%s' - Tp:'%s'%s, ID:%d, Addr:'%s'",
@@ -491,6 +627,8 @@ bool CDeviceCore::DestroyDevice( TDevice ** Device )
free( (*Device)->Address ); free( (*Device)->Address );
if ((*Device)->Type) if ((*Device)->Type)
free( (*Device)->Type ); free( (*Device)->Type );
if ((*Device)->DataPath)
free( (*Device)->DataPath );
// Destroy parameters & groups // Destroy parameters & groups
while ((*Device)->FirstParam) { while ((*Device)->FirstParam) {
@@ -647,6 +785,8 @@ bool CDeviceCore::DestroyDeviceParam( TDeviceParam ** Param )
free( (*Param)->Value ); free( (*Param)->Value );
if ((*Param)->SetValue) if ((*Param)->SetValue)
free( (*Param)->SetValue ); free( (*Param)->SetValue );
if ((*Param)->DataPath)
free( (*Param)->DataPath );
// Destroy Param // Destroy Param
delete *Param; delete *Param;
@@ -772,6 +912,23 @@ bool CDeviceCore::DestroyParamItem( TDeviceParamItem ** Item )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::SetDataPath( TDeviceParam * Param, const char * DataPath, CDataMember * DataNode )
{
if (!Param)
return false;
Param->DataPath = strdup( DataPath );
Param->DataNode = DataNode;
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlMedium, "%s/%s: Set param '%s/%s' data ref - P:%s, N:%s",
ProcessName, Name, DeviceName, Param->Name, DataPath, ((DataNode)? DataNode->GetName() : "(none)") );
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::SetParamAccess( TDeviceParam * Param, bool Read, bool Write ) bool CDeviceCore::SetParamAccess( TDeviceParam * Param, bool Read, bool Write )
{ {
if (!Param) if (!Param)
@@ -825,6 +982,9 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Set new value & mark change // Set new value & mark change
*((u_int16_t*)Param->Value) = Value; *((u_int16_t*)Param->Value) = Value;
if (Param->DataNode)
Param->DataNode->SetInt( *((u_int16_t*)Param->Value) );
// Mark change & log event // Mark change & log event
Changed = true; Changed = true;
if (Log) { if (Log) {
@@ -842,6 +1002,9 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Set new value & mark change // Set new value & mark change
*((u_int32_t*)Param->Value) = Value; *((u_int32_t*)Param->Value) = Value;
if (Param->DataNode)
Param->DataNode->SetInt( *((u_int32_t*)Param->Value) );
// Mark change & log event // Mark change & log event
Changed = true; Changed = true;
if (Log) { if (Log) {
@@ -860,6 +1023,9 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Set new value & mark change // Set new value & mark change
*((u_int32_t*)Param->Value) = Value; *((u_int32_t*)Param->Value) = Value;
if (Param->DataNode)
Param->DataNode->SetInt( *((u_int32_t*)Param->Value) );
// Mark change & log event // Mark change & log event
Changed = true; Changed = true;
if (Log) { if (Log) {
@@ -899,6 +1065,9 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value,
// Set new value & mark change // Set new value & mark change
*((int16_t*)Param->Value) = Value; *((int16_t*)Param->Value) = Value;
if (Param->DataNode)
Param->DataNode->SetInt( *((int16_t*)Param->Value) );
// Mark change & log event // Mark change & log event
Changed = true; Changed = true;
if (Log) { if (Log) {
@@ -916,6 +1085,9 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value,
// Set new value & mark change // Set new value & mark change
*((int32_t*)Param->Value) = Value; *((int32_t*)Param->Value) = Value;
if (Param->DataNode)
Param->DataNode->SetInt( *((int32_t*)Param->Value) );
// Mark change & log event // Mark change & log event
Changed = true; Changed = true;
if (Log) { if (Log) {
@@ -956,6 +1128,9 @@ bool CDeviceCore::UpdateFloatValue( TDeviceParam * Param, const float Value, boo
// Set new value & mark change // Set new value & mark change
*((float*)Param->Value) = Value; *((float*)Param->Value) = Value;
if (Param->DataNode)
Param->DataNode->SetFloat( *((float*)Param->Value) );
// Mark change & log event // Mark change & log event
Changed = true; Changed = true;
if (Log) { if (Log) {
@@ -1005,6 +1180,9 @@ bool CDeviceCore::UpdateStringValue( TDeviceParam * Param, const char * Value, c
memset( &((char*)Param->Value)[Len], 0x0, (Param->Len - Len + 1) ); // Add null teriminate memset( &((char*)Param->Value)[Len], 0x0, (Param->Len - Len + 1) ); // Add null teriminate
} }
if (Param->DataNode)
Param->DataNode->SetStr( (char*)Param->Value );
// Mark Change // Mark Change
Changed = true; Changed = true;
if (Log) { if (Log) {

View File

@@ -42,6 +42,8 @@ struct SDevice {
char * Name = NULL; char * Name = NULL;
int ID = 0; int ID = 0;
char * Address = NULL; char * Address = NULL;
char * DataPath = NULL;
CDataMember * DataNode = NULL;
// Device Type // Device Type
char * Type = NULL; char * Type = NULL;
@@ -65,6 +67,10 @@ struct SDeviceParam {
EDeviceDataType DataType = dtNone; EDeviceDataType DataType = dtNone;
TDevice * Device = Device; TDevice * Device = Device;
// Data Path
char * DataPath = NULL;
CDataMember * DataNode = NULL;
// Last value (received from device) // Last value (received from device)
void * Value = NULL; void * Value = NULL;
int Len = 0; int Len = 0;
@@ -117,6 +123,7 @@ protected:
// Configuration // Configuration
CDataMember * Config = NULL; CDataMember * Config = NULL;
CDataMember * ConfigTypes = NULL; CDataMember * ConfigTypes = NULL;
CDataMember * ValueTree = NULL;
CJSONparse * JSONparse = NULL; CJSONparse * JSONparse = NULL;
bool DeviceInit = false; bool DeviceInit = false;
@@ -306,25 +313,30 @@ public:
// Configuration // Configuration
virtual bool Init( CDataMember * FunctionConfig ); virtual bool Init( CDataMember * FunctionConfig );
virtual bool InitDevices( CDataMember * FunctionConfig ); virtual bool InitDevices( CDataMember * FunctionConfig );
virtual bool InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig ); virtual bool InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig, CDataMember * ParentNode );
virtual bool CopyTemplateParam( TDevice * Device, TDeviceParam * Template, CDataMember * ParentNode );
virtual bool InitDeviceParam( TDevice * Device, CDataMember * ParamConfig,
const char * ParentName, const char * ParentPath, CDataMember * ParentNode );
virtual bool InitParamGroups( TDevice * Device, CDataMember * DeviceConfig ); virtual bool InitParamGroups( TDevice * Device, CDataMember * DeviceConfig );
// Polling parameters // Polling parameters
bool SetPollParam( int pPollInterval ); bool SetPollParam( int pPollInterval );
bool SetReplyParam( int pReplyTimeout, int pMaxRetries ); bool SetReplyParam( int pReplyTimeout, int pMaxRetries );
bool SetDataPath( TDeviceParam * Param, const char * DataPath, CDataMember * DataNode );
bool SetParamAccess( TDeviceParam * Param, bool Read, bool Write ); bool SetParamAccess( TDeviceParam * Param, bool Read, bool Write );
bool SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval ); bool SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval );
// Manage Devices Types // Manage Devices Types
TDevice * AddDeviceType( const char * DeviceTypeName ); TDevice * AddDeviceType( const char * DeviceTypeName, const char * DataPath );
inline bool DestroyDeviceType( const char * DeviceTypeName ) { inline bool DestroyDeviceType( const char * DeviceTypeName ) {
TDevice ** DeviceType = GetDeviceTypePtr(DeviceTypeName); TDevice ** DeviceType = GetDeviceTypePtr(DeviceTypeName);
return (DeviceType)? DestroyDevice( DeviceType ) : false; return (DeviceType)? DestroyDevice( DeviceType ) : false;
} }
// Manage Devices // Manage Devices
TDevice * AddDevice( const char * DeviceName, const char * Type = NULL, const int ID = 0, const char * Address = NULL ); TDevice * AddDevice( const char * DeviceName, const char * Type = NULL,
const int ID = 0, const char * Address = NULL, const char * DataPath = NULL );
inline bool DestroyDevice( const char * DeviceName ) { inline bool DestroyDevice( const char * DeviceName ) {
TDevice ** Device = GetDevicePtrByName(DeviceName); TDevice ** Device = GetDevicePtrByName(DeviceName);
return (Device)? DestroyDevice( Device ) : false; return (Device)? DestroyDevice( Device ) : false;

View File

@@ -15,31 +15,16 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CJSONparse::CJSONparse()
{
SetBase( NULL );
}
//---------------------------------------------------------------------------
CJSONparse::CJSONparse( CDataMember * pDataTree ) CJSONparse::CJSONparse( CDataMember * pDataTree )
{ {
// Object tree if (!SetBase( pDataTree ))
DataTree = pDataTree; DataTree = NULL;
// File Operation
InputHandle = -1;
OutputHandle = -1;
Buffer = NULL;
// Parsing operation
BufPos = NULL;
Mark = NULL;
LineNo = 0;
CharNo = 0;
RefillBuffer = false;
// Printing operation
Spacer[0] = 0;
SpacerLen = 0;
// Error reporting
Error = false;
ErrorText[0] = 0;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -52,6 +37,18 @@ CJSONparse::~CJSONparse()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CJSONparse::SetBase( CDataMember * Object )
{
// Validate
if (Object && !Object->isObject() && !Object->isNull())
return false;
// Set
DataTree = Object;
return true;
}
//---------------------------------------------------------------------------
bool CJSONparse::WriteToScreen( const char * BasePath, const int Indent ) bool CJSONparse::WriteToScreen( const char * BasePath, const int Indent )
{ {
// Print to screen // Print to screen
@@ -124,6 +121,8 @@ bool CJSONparse::WriteToHandle( const char * BasePath, const int Handle, const i
// Validate // Validate
if (!DataTree) { if (!DataTree) {
Error = true;
sprintf( ErrorText, "No Data Tree set" );
return false; return false;
} }
@@ -187,11 +186,6 @@ bool CJSONparse::ReadFromFile( const char * BasePath, const char * FilePath )
int Handle = -1; int Handle = -1;
bool result = false; bool result = false;
// Validate
if (!DataTree) {
return false;
}
// Clear Error // Clear Error
Error = false; Error = false;
@@ -283,7 +277,14 @@ bool CJSONparse::ReadFromBuffer( const char * BasePath )
CDataMember * BaseMember = NULL; CDataMember * BaseMember = NULL;
// Validate // Validate
if (!DataTree || !Buffer) { if (!DataTree) {
Error = true;
sprintf( ErrorText, "No Data Tree set" );
return false;
}
if (!Buffer) {
Error = true;
sprintf( ErrorText, "No Data Buffer defined" );
return false; return false;
} }

View File

@@ -21,28 +21,28 @@
class CJSONparse class CJSONparse
{ {
private: private:
CDataMember * DataTree; CDataMember * DataTree = NULL;
// File operation // File operation
int InputHandle; int InputHandle = -1;
int OutputHandle; int OutputHandle = -1;
CShiftBuffer * Buffer; CShiftBuffer * Buffer = NULL;
// Parsing operation // Parsing operation
char * BufPos; char * BufPos = NULL;
char * Mark; char * Mark = NULL;
int LineNo; int LineNo = 0;
int CharNo; int CharNo = 0;
bool RefillBuffer; bool RefillBuffer = false;
// Printing Operation // Printing Operation
char Spacer[100]; char Spacer[100] = "";
int SpacerLen; int SpacerLen = 0;
// Error // Error
bool Error; bool Error = false;
char ErrorText[100]; char ErrorText[100] = "";
// Parsing functions // Parsing functions
void SkipWhiteSpace(); void SkipWhiteSpace();
@@ -57,9 +57,13 @@ private:
bool PrintArray( CDataMember * Object, const int Indent ); bool PrintArray( CDataMember * Object, const int Indent );
public: public:
CJSONparse();
CJSONparse( CDataMember * pDataTree ); CJSONparse( CDataMember * pDataTree );
~CJSONparse(); ~CJSONparse();
// Tree
bool SetBase( CDataMember * Object );
// Buffer operation // Buffer operation
bool CreateBuffer( int pBufLen ); bool CreateBuffer( int pBufLen );
bool FillBuffer(); bool FillBuffer();