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:
304
DeviceCore.cpp
304
DeviceCore.cpp
@@ -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,86 +128,121 @@ 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;
|
||||||
CDataMember * InitVal;
|
|
||||||
TDeviceParam * Param;
|
|
||||||
TDeviceParam * Template;
|
TDeviceParam * Template;
|
||||||
|
bool isType = (Device->Name)? false : true;
|
||||||
|
|
||||||
EDeviceDataType DataType;
|
// Copy Template Params
|
||||||
|
|
||||||
bool Read;
|
|
||||||
bool Write;
|
|
||||||
char * EventOut;
|
|
||||||
int EventInt;
|
|
||||||
|
|
||||||
// Copy Template
|
|
||||||
Template = (Device->Template)? Device->Template->FirstParam : NULL;
|
Template = (Device->Template)? Device->Template->FirstParam : NULL;
|
||||||
while (Template)
|
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 )))
|
if ((Param = AddDeviceParam( Device, Template->Name, Template->DataType, Template->Len )))
|
||||||
{
|
{
|
||||||
SetParamAccess( Param, Template->Read, Template->Write );
|
SetParamAccess( Param, Template->Read, Template->Write );
|
||||||
SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval );
|
|
||||||
|
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)) {
|
if ((Template->DataType == dtUnsigned16) || (Template->DataType == dtUnsigned32_HL) || (Template->DataType == dtUnsigned32_LH)) {
|
||||||
UpdateUnsignedValue( Param, *((u_int16_t*)Template->Value), Template->Changed );
|
UpdateUnsignedValue( Param, *((u_int16_t*)Template->Value), Template->Changed );
|
||||||
@@ -214,26 +264,93 @@ bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfi
|
|||||||
if (Template->SetChanged)
|
if (Template->SetChanged)
|
||||||
SetStringValue( Param, (char*)Template->Value, Template->Len, true );
|
SetStringValue( Param, (char*)Template->Value, Template->Len, true );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Template = Template->Next;
|
SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Parameters
|
if (DataPath) free( DataPath );
|
||||||
ParamData = DeviceConfig->GetChFirstChild( "Parameters", true );
|
return true;
|
||||||
while (ParamData)
|
}
|
||||||
{
|
//---------------------------------------------------------------------------
|
||||||
DataType = GetDataType((char*)ParamData->GetChStr( "Type", "Unsigned16", true ));
|
|
||||||
if ((Param = AddDeviceParam( Device, ParamData->GetName(), DataType, 1 )))
|
bool CDeviceCore::InitDeviceParam( TDevice * Device, CDataMember * ParamConfig,
|
||||||
{
|
const char * ParentName, const char * ParentPath, CDataMember * ParentNode )
|
||||||
Read = ParamData->GetChBool( "Read", false, true );
|
{
|
||||||
Write = ParamData->GetChBool( "Write", false, true );
|
char * NodeName;
|
||||||
|
char * FullName;
|
||||||
|
char * DataPath;
|
||||||
|
CDataMember * DataNode;
|
||||||
|
CDataMember * Children;
|
||||||
|
CDataMember * ChildConfig;
|
||||||
|
CDataMember * ChildMap;
|
||||||
|
|
||||||
|
CDataMember * InitVal;
|
||||||
|
TDeviceParam * Param;
|
||||||
|
|
||||||
|
EDeviceDataType DataType;
|
||||||
|
|
||||||
|
bool Read;
|
||||||
|
bool Write;
|
||||||
|
char * EventOut;
|
||||||
|
int EventInt;
|
||||||
|
|
||||||
|
// Create Node Name
|
||||||
|
NodeName = (char*)ParamConfig->GetName();
|
||||||
|
if (ParentName && *ParentName) {
|
||||||
|
FullName = (char*)malloc( strlen(ParentName) + strlen(NodeName) + 2 );
|
||||||
|
sprintf( FullName, "%s_%s", ParentName, NodeName );
|
||||||
|
} else {
|
||||||
|
FullName = strdup( NodeName );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Node Path
|
||||||
|
DataNode = (ParentNode)? ParentNode->GetChild( NodeName, true ) : NULL;
|
||||||
|
if (ParentPath && *ParentPath) {
|
||||||
|
DataPath = (char*)malloc( strlen(ParentPath) + strlen(NodeName) + 2 );
|
||||||
|
sprintf( DataPath, "%s/%s", ParentPath, NodeName );
|
||||||
|
} else {
|
||||||
|
DataPath = strdup( NodeName );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
@@ -411,6 +533,7 @@ TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName )
|
|||||||
*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) {
|
||||||
|
|||||||
18
DeviceCore.h
18
DeviceCore.h
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user