Important Update;

- ApplicationCore:
  - Minor log updates
- FunctionCore:
  - Initialise structs & object params in declaration
- DeviceCore:
  - Update logs with more consistent structure
  - Initialise structs & object params in declaration
  - Implemented DeviceType templates
    - Added Add/Get/Destroy methods
    - Load from config or separate template file
    - Build Devices/Params from template
  - Implemented ParamGroups
    - Added Add/Get/Destroy methods
    - Load with DeviceTypes
  - Added JSON parser to read separate template files
  - Bug fix: Getxxxx() methods
This commit is contained in:
Charl Wentzel
2018-12-13 09:17:39 +02:00
parent 90beb031af
commit dc76d99b58
5 changed files with 565 additions and 220 deletions

View File

@@ -29,15 +29,6 @@ extern CApplication * Application;
CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCore( pName, pType )
{
// Clear Parameters
FirstDevice = NULL;
ActiveDevice = NULL;
// Standard channels
DeviceChannel = NULL;
CmdChannel = NULL;
EventChannel = NULL;
// Polling
PollStep = 0;
PollInterval = 250;
@@ -50,8 +41,9 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo
MaxRetries = 3;
// Data Structures
Config = NULL;
DeviceInit = true;
ConfigTypes = new CDataMember();
JSONparse = new CJSONparse( ConfigTypes );
}
//---------------------------------------------------------------------------
@@ -60,6 +52,12 @@ CDeviceCore::~CDeviceCore()
// Destroy Params
while (FirstDevice)
DestroyDevice( &FirstDevice );
while (FirstDeviceType)
DestroyDevice( &FirstDeviceType );
if (JSONparse)
delete JSONparse;
if (ConfigTypes)
delete ConfigTypes;
}
//---------------------------------------------------------------------------
@@ -79,8 +77,8 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
CmdChannel = AddChannel( "Command", true, true );
if (!(DeviceChannel = GetChannel( "Device" )))
DeviceChannel = AddChannel( "Device", true, true );
if (!(DeviceChannel = GetChannel( "Event" )))
DeviceChannel = AddChannel( "Event", true, true );
if (!(EventChannel = GetChannel( "Event" )))
EventChannel = AddChannel( "Event", true, true );
// Get configuration
if ((Config = FunctionConfig->GetChild( "Config", true )) && Config->isString()) {
@@ -100,12 +98,12 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
IntVal2 = PollConfig->GetChInt( "MaxRetries", 3, true );
SetReplyParam( IntVal1, IntVal2 );
Log->Message( LogLevel, dlMedium, "%s/%s: Set Polling param - Int:%d, TO:%d, Max:%d, Up:%d",
Log->Message( LogLevel, dlMedium, "%s/%s: Set polling param - Int:%d, T/O:%d, Max:%d",
ProcessName, Name, PollInterval, ReplyTimeout, MaxRetries );
// Update Devices -- may want to do it from derived class intead
if (DeviceInit) {
InitDevices( FunctionConfig );
CDeviceCore::InitDevices( FunctionConfig );
}
return true;
@@ -114,11 +112,63 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
bool CDeviceCore::InitDevices( CDataMember * FunctionConfig )
{
CDataMember * DeviceData;
CDataMember * DeviceData = NULL;
TDevice * Device = NULL;
char * DeviceName = NULL;
char * DeviceType = NULL;
// Load Device Types
DeviceData = Config->GetChFirstChild( "DeviceTypes", true );
while (DeviceData)
{
DeviceName = (char*)DeviceData->GetName();
Device = AddDeviceType( DeviceName );
if (DeviceData->isString()) {
if (JSONparse->ReadFromFile( DeviceName, DeviceData->GetStr() )) { // Contains file reference
InitDeviceParams( Device, ConfigTypes->GetChild( DeviceName ) );
InitParamGroups( Device, ConfigTypes->GetChild( DeviceName ) );
JSONparse->WriteToFile( DeviceName, DeviceData->GetStr() );
}
else {
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Fail to load device type '%s' from file: '%s'",
ProcessName, Name, DeviceName, DeviceData->GetStr() );
}
}
else if (DeviceData->isObject()) {
InitDeviceParams( Device, DeviceData ); // Contains definition
InitParamGroups( Device, DeviceData );
}
else {
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device type config for '%s'",
ProcessName, Name, DeviceName );
}
DeviceData = DeviceData->GetNextPeer();
}
// Load Actual Devices
DeviceData = Config->GetChFirstChild( "Devices", true );
while (DeviceData)
{
DeviceName = (char*)DeviceData->GetName();
DeviceType = (char*)DeviceData->GetChStr( "Type" );
Device = AddDevice( DeviceName, DeviceType );
InitDeviceParams( Device, DeviceData );
InitParamGroups( Device, DeviceData );
DeviceData = DeviceData->GetNextPeer();
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig )
{
CDataMember * ParamData;
CDataMember * InitVal;
TDevice * Device;
TDeviceParam * Param;
TDeviceParam * Template;
EDeviceDataType DataType;
@@ -127,58 +177,105 @@ bool CDeviceCore::InitDevices( CDataMember * FunctionConfig )
char * EventOut;
int EventInt;
// Add Devices
DeviceData = Config->GetChFirstChild( "Devices", true );
while (DeviceData)
// Copy Template
Template = (Device->Template)? Device->Template->FirstParam : NULL;
while (Template) {
if ((Param = AddDeviceParam( Device, Template->Name, Template->DataType, Template->Len )))
{
// Add device
Device = AddDevice( DeviceData->GetName() );
Param = NULL;
SetParamAccess( Param, Template->Read, Template->Write );
SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval );
if ((Template->DataType == dtUnsigned16) || (Template->DataType == dtUnsigned32)) {
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)) {
UpdateSignedValue( Param, *((int16_t*)Template->Value), Template->Changed );
if (Template->SetChanged)
SetSignedValue( Param, *((int16_t*)Template->Value), true );
}
else if (Template->DataType == dtFloat32) {
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
ParamData = DeviceData->GetChFirstChild( "Parameters", true );
ParamData = DeviceConfig->GetChFirstChild( "Parameters", true );
while (ParamData)
{
DataType = GetDataType((char*)ParamData->GetChStr( "Type", "Unsigned16", true ));
if (!(Param = AddDeviceParam( Device, ParamData->GetName(), DataType, 1 )))
continue;
if ((Param = AddDeviceParam( Device, ParamData->GetName(), DataType, 1 )))
{
Read = ParamData->GetChBool( "Read", false, true );
Write = ParamData->GetChBool( "Write", false, true );
SetParamAccess( Param, Read, Write );
if ((InitVal = ParamData->GetChild( "InitValue", false ))) {
if (InitVal->isInt() && ((DataType == dtUnsigned16) || (DataType == dtUnsigned32))) {
UpdateUnsignedValue( Param, InitVal->GetInt(0), Read );
if (Write)
SetUnsignedValue( Param, InitVal->GetInt(0), true );
}
else if (InitVal->isInt() && ((DataType == dtSigned16) || (DataType == dtSigned32))) {
UpdateSignedValue( Param, InitVal->GetInt(0), Read );
if (Write)
SetSignedValue( Param, InitVal->GetInt(0), true );
}
else if (InitVal->isFloat() && (DataType == dtFloat32)) {
UpdateFloatValue( Param, InitVal->GetFloat(0), Read );
if (Write)
SetFloatValue( Param, InitVal->GetFloat(0), true );
}
else if (InitVal->isString() && (DataType == dtString)) {
UpdateStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), Read );
if (Write)
SetStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), true );
}
}
EventOut = (char*)ParamData->GetChStr( "EventChannel", NULL, false );
EventInt = ParamData->GetChInt( "EventInterval", 0, false );
SetParamEvent( Param, EventOut, EventInt );
if ((InitVal = ParamData->GetChild( "InitValue", false ))) {
if ((DataType == dtUnsigned16) || (DataType == dtUnsigned32)) {
UpdateUnsignedValue( Param, InitVal->GetInt(0), Read );
if (Write)
SetUnsignedValue( Param, InitVal->GetInt(0), true );
}
else if ((DataType == dtSigned16) || (DataType == dtSigned32)) {
UpdateSignedValue( Param, InitVal->GetInt(0), Read );
if (Write)
SetSignedValue( Param, InitVal->GetInt(0), true );
}
else if (DataType == dtFloat32) {
UpdateFloatValue( Param, InitVal->GetFloat(0), Read );
if (Write)
SetFloatValue( Param, InitVal->GetFloat(0), true );
}
else if (DataType == dtString) {
UpdateStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), Read );
if (Write)
SetStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), true );
}
}
}
// Read + Event Out
ParamData = ParamData->GetNextPeer();
}
DeviceData = DeviceData->GetNextPeer();
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::InitParamGroups( TDevice * Device, CDataMember * DeviceConfig )
{
CDataMember * GroupData;
CDataMember * ItemData;
TDeviceParamGroup * Group;
// Add Parameters
GroupData = DeviceConfig->GetChFirstChild( "ParamGroups", true );
while (GroupData)
{
if ((Group = AddParamGroup( Device, GroupData->GetName() )))
{
ItemData = GroupData->GetElement( 0 );
while (ItemData)
{
AddParamItem( Group, ItemData->GetStr() );
ItemData = ItemData->GetNextPeer();
}
}
GroupData = GroupData->GetNextPeer();
}
return true;
}
//---------------------------------------------------------------------------
@@ -210,7 +307,7 @@ bool CDeviceCore::DeviceOnline( TDevice * Device, bool Online )
// Log Event
Device->Online = Online;
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Device '%s' %s",
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Device '%s' %s",
ProcessName, Name, Device->Name, ((Online)? "online" : "offline") );
return true;
}
@@ -237,12 +334,12 @@ bool CDeviceCore::CheckReplyTimeout( int TimeoutPollStep )
// Handle No Reply / Retry
if (PollRetry < MaxRetries) {
// Log Event
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - %s timeout, retry [%d]",
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Device '%s' timeout, retry [%d]",
ProcessName, Name, DeviceChannel->Name, ActiveDevice->Name, PollRetry );
}
else {
// Log Event
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - %s timeout, max [%d]",
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Device '%s' timeout, max [%d]",
ProcessName, Name, DeviceChannel->Name, ActiveDevice->Name, PollRetry );
// Set Device Offline
@@ -263,18 +360,46 @@ bool CDeviceCore::CheckReplyTimeout( int TimeoutPollStep )
}
//---------------------------------------------------------------------------
TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName )
{
TDevice ** DeviceType = GetDeviceTypePtr( DeviceTypeName );
if (!DeviceType) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Could not add device type '%s'",
ProcessName, Name, ((DeviceTypeName)? DeviceTypeName : "[device type]") );
return NULL;
}
else if (*DeviceType) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Device type '%s' already exists",
ProcessName, Name, DeviceTypeName );
}
else {
*DeviceType = (TDevice*)calloc( 1, sizeof(TDevice) );
(*DeviceType)->Type = (char *)malloc( strlen( DeviceTypeName )+1 );
strcpy( (*DeviceType)->Type, DeviceTypeName );
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device type '%s'",
ProcessName, Name, DeviceTypeName );
}
return *DeviceType;
}
//---------------------------------------------------------------------------
TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * Type )
{
TDevice ** Device = &FirstDevice;
TDevice ** Device = GetDevicePtr( DeviceName );
if (!DeviceName || !*DeviceName) return NULL;
while (*Device && strcmp( DeviceName, (*Device)->Name ))
Device = &((*Device)->Next);
// Create if not found
if (!*Device)
{
if (!Device) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Could not add device '%s' (%s)", ProcessName, Name,
((DeviceName)? DeviceName : "[device]"), ((Type)? Type : "no type") );
return NULL;
}
else if (*Device) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Device type '%s' (%s) already exists", ProcessName, Name,
DeviceName, (((*Device)->Type)? (*Device)->Type : "no type") );
}
else {
*Device = (TDevice*)malloc( sizeof(TDevice) );
memset( *Device, 0x0, sizeof(TDevice) );
@@ -284,13 +409,13 @@ TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * Type )
if (Type && *Type) {
(*Device)->Type = (char *)malloc( strlen( Type )+1 );
strcpy( (*Device)->Type, Type );
}
(*Device)->Template = GetDeviceType( Type );
}
// Report creation
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Device added - '%s' (%s)",
ProcessName, Name, DeviceName, (Type)? Type : "no type" );
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device '%s' (%s%s)", ProcessName, Name,
DeviceName, ((Type)? Type : "no type"), (((*Device)->Template)? "*" : "") );
}
return *Device;
}
//---------------------------------------------------------------------------
@@ -330,13 +455,21 @@ bool CDeviceCore::DestroyDevice( TDevice ** Device )
TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * ParamName, EDeviceDataType DataType, int ParamLen )
{
// Get register or end of list
TDeviceParam ** Param = &Device->FirstParam;
while (*Param && strcmp( ParamName, (*Param)->Name ))
Param = &((*Param)->Next);
TDeviceParam ** Param = GetDeviceParamPtr( Device, ParamName );
// Create if not found
if (!*Param) {
if (!Param) {
// Invalid device/param
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Param '%s/%s' cannot be created", ProcessName, Name,
((!Device)? "[device]" : (Device->Name)? Device->Name : Device->Type),
((!ParamName)? "[param]" : ParamName));
return NULL;
}
else if (*Param) {
// Parameter already exists
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Param '%s/%s' already exists", ProcessName, Name,
((Device->Name)? Device->Name : Device->Type), ParamName, DataTypeName[DataType]);
}
else {
// Create register
*Param = (TDeviceParam*)malloc( sizeof(TDeviceParam) );
memset( *Param, 0x0, sizeof(TDeviceParam) );
@@ -345,6 +478,7 @@ TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * Param
(*Param)->Name = (char *)malloc( strlen( ParamName )+1 );
strcpy( (*Param)->Name, ParamName );
(*Param)->DataType = DataType;
(*Param)->Device = Device;
// Init values
switch (DataType)
@@ -424,15 +558,11 @@ TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * Param
default :
break;
}
}
// Mark as updated
(*Param)->Changed = true;
// Report creation
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Param added - '%s' (%s)",
ProcessName, Name, ParamName, DataTypeName[DataType] );
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added param '%s/%s' (%s)", ProcessName, Name,
((Device->Name)? Device->Name : Device->Type), ParamName, DataTypeName[DataType]);
}
return *Param;
}
//---------------------------------------------------------------------------
@@ -467,6 +597,152 @@ bool CDeviceCore::DestroyDeviceParam( TDeviceParam ** Param )
}
//---------------------------------------------------------------------------
TDeviceParamGroup * CDeviceCore::AddParamGroup( TDevice * Device, const char * GroupName )
{
TDeviceParamGroup ** ParamGroup = GetParamGroupPtr( GroupName );
if (!ParamGroup) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Could not add param group '%s'", ProcessName, Name,
((!Device)? "[device]" : (Device->Name)? Device->Name : Device->Type),
((GroupName)? GroupName : "[group]") );
return NULL;
}
else if (*ParamGroup) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Param group '%s/%s' already exists",
ProcessName, Name, ((Device->Name)? Device->Name : Device->Type), GroupName );
}
else {
*ParamGroup = (TDeviceParamGroup*)calloc( 1, sizeof(TDeviceParamGroup) );
(*ParamGroup)->Name = (char *)malloc( strlen( GroupName )+1 );
strcpy( (*ParamGroup)->Name, GroupName );
(*ParamGroup)->Device = Device;
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added param group '%s/%s'",
ProcessName, Name, ((Device->Name)? Device->Name : Device->Type), GroupName );
}
return *ParamGroup;
}
//---------------------------------------------------------------------------
bool CDeviceCore::DestroyParamGroup( TDeviceParamGroup ** ParamGroup )
{
TDeviceParamGroup * NextGroup = NULL;
// Validate ParamGroup
if (!ParamGroup || !*ParamGroup)
return false;
// Save reference to next Param Group
NextGroup = (*ParamGroup)->NextGroup;
// Destroy Param Group structure
if ((*ParamGroup)->Name)
free( (*ParamGroup)->Name );
// Destroy items
while ((*ParamGroup)->FirstParam) {
DestroyParamItem( &((*ParamGroup)->FirstParam) );
}
// Destroy ParamGroup
free( *ParamGroup );
// Remove from list
*ParamGroup = NextGroup;
// ParamGroup successfully destroyed
return true;
}
//---------------------------------------------------------------------------
TDeviceParamItem * CDeviceCore::AddParamItem( TDeviceParamGroup * Group, const char * ParamName )
{
TDeviceParamItem ** Item = GetParamItemPtr( Group, ParamName );
TDeviceParam * Param = NULL;
if (!Item) {
// Invalid group/param
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Param group item '%s/%s' cannot be created", ProcessName, Name,
((!Group)? "[group]" : Group->Name), ((!ParamName)? "[param]" : ParamName));
return NULL;
}
else if (*Item) {
// Item already exists
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Param Group item '%s/%s' already exists", ProcessName, Name,
Group->Name, ParamName );
}
else if (!(Param = GetDeviceParam( Group->Device, ParamName ))) {
// Parameter does not exist
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Param '%s/%s' does not exists - Cannot add to Param group '%s'", ProcessName, Name,
((Group->Device->Name)? Group->Device->Name : Group->Device->Type), ParamName, Group->Name );
}
else {
*Item = (TDeviceParamItem*)malloc( sizeof(TDeviceParamItem) );
memset( *Item, 0x0, sizeof(TDeviceParamItem) );
(*Item)->Param = Param;
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added param group item '%s/%s/%s'", ProcessName, Name,
((Group->Device->Name)? Group->Device->Name : Group->Device->Type), Group->Name, ParamName );
}
return *Item;
}
//---------------------------------------------------------------------------
bool CDeviceCore::DestroyParamItem( TDeviceParamItem ** Item )
{
TDeviceParamItem * NextParam = NULL;
if (!Item || !*Item)
return false;
NextParam = (*Item)->NextItem;
free( *Item );
*Item = NextParam;
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::SetParamAccess( TDeviceParam * Param, bool Read, bool Write )
{
if (!Param)
return false;
Param->Read = Read;
Param->Write = Write;
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlMedium, "%s/%s: Set param '%s/%s' access - R:%d, W:%d",
ProcessName, Name, DeviceName, Param->Name, Read, Write );
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval )
{
if (!Param)
return false;
Param->EventChannel = GetChannel( ChannelName );
if (pEventInterval) {
Param->EventInterval = pEventInterval;
SetStartTime( &(Param->EventTimeout) );
}
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlMedium, "%s/%s: Set param '%s/%s' event - Ch:'%s', Int:%d",
ProcessName, Name, DeviceName, Param->Name, ((ChannelName)? ChannelName : ""), pEventInterval );
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Value, bool Init )
{
bool Changed = false;
@@ -485,8 +761,11 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Mark change & log event
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %u", ProcessName, Name,
Param->Name, ((Init)? "initialised" : "changed"), *((u_int16_t*)Param->Value) );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - %u", ProcessName, Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, *((u_int16_t*)Param->Value) );
}
}
break;
@@ -498,8 +777,11 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Mark change & log event
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %u", ProcessName, Name,
Param->Name, ((Init)? "initialised" : "changed"), *((u_int32_t*)Param->Value) );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - %u", ProcessName, Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, *((u_int32_t*)Param->Value) );
}
}
break;
@@ -511,8 +793,11 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Mark change & log event
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %f", ProcessName, Name,
Param->Name, ((Init)? "initialised" : "changed"), *((float*)Param->Value) );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - %f", ProcessName, Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, *((float*)Param->Value) );
}
}
break;
@@ -523,7 +808,7 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val
// Generate Channel Event
if (Changed) {
Param->Changed = true;
EventOutput( Param, Changed );
if (Param->Device->Name) EventOutput( Param, Changed ); // Only send event of actual device, not type/template
}
return Changed;
}
@@ -547,8 +832,11 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value,
// Mark change & log event
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %d", ProcessName, Name,
Param->Name, ((Init)? "initialised" : "changed"), *((int16_t*)Param->Value) );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - %d", ProcessName, Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, *((int16_t*)Param->Value) );
}
}
break;
@@ -560,8 +848,11 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value,
// Mark change & log event
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %d", ProcessName, Name, Param->Name,
((Init)? "initialised" : "changed"), *((int32_t*)Param->Value) );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - %d", ProcessName, Name, Param->Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, *((int32_t*)Param->Value) );
}
}
break;
@@ -572,7 +863,7 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value,
// Generate Channel Event
if (Changed) {
Param->Changed = true;
EventOutput( Param, Changed );
if (Param->Device->Name) EventOutput( Param, Changed ); // Only send event of actual device, not type/template
}
return Changed;
}
@@ -596,8 +887,11 @@ bool CDeviceCore::UpdateFloatValue( TDeviceParam * Param, const float Value, boo
// Mark change & log event
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %f", ProcessName, Name,
Param->Name, ((Init)? "initialised" : "changed"), *((float*)Param->Value) );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - %f", ProcessName, Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, *((float*)Param->Value) );
}
}
break;
@@ -608,7 +902,7 @@ bool CDeviceCore::UpdateFloatValue( TDeviceParam * Param, const float Value, boo
// Generate Channel Event
if (Changed) {
Param->Changed = true;
EventOutput( Param, Changed );
if (Param->Device->Name) EventOutput( Param, Changed ); // Only send event of actual device, not type/template
}
return Changed;
}
@@ -642,8 +936,11 @@ bool CDeviceCore::UpdateStringValue( TDeviceParam * Param, const char * Value, c
// Mark Change
Changed = true;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: '%s' %s - %s", ProcessName, Name,
Param->Name, ((Init)? "initialised" : "changed"), (char*)Param->Value );
if (Log) {
char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type;
Log->Message( LogLevel, dlLow, "%s/%s: %s param '%s/%s' - '%s'", ProcessName, Name,
((Init)? "Init" : "Changed"), DeviceName, Param->Name, (char*)Param->Value );
}
}
break;
@@ -654,7 +951,7 @@ bool CDeviceCore::UpdateStringValue( TDeviceParam * Param, const char * Value, c
// Generate Channel Event
if (Changed) {
Param->Changed = true;
EventOutput( Param, Changed );
if (Param->Device->Name) EventOutput( Param, Changed ); // Only send event of actual device, not type/template
}
return Changed;
}
@@ -939,31 +1236,6 @@ bool CDeviceCore::CompareParamString( const char * ParamValue, const int ParamLe
}
//---------------------------------------------------------------------------
bool CDeviceCore::SetParamAccess( TDeviceParam * Param, bool Read, bool Write )
{
if (!Param)
return false;
Param->Read = Read;
Param->Write = Write;
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval )
{
if (!Param)
return false;
Param->EventChannel = GetChannel( ChannelName );
if (pEventInterval) {
Param->EventInterval = pEventInterval;
SetStartTime( &(Param->EventTimeout) );
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::TimedParamEvents()
{
TDevice * Device = NULL;
@@ -1031,7 +1303,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
// Check for additional parameters
if (!NextParam) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing parameters for 'Get'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing 'get' parameters",
ProcessName, Name, ChannelName );
return MaxLen;
}
@@ -1040,7 +1312,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Device = GetDevice( ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Device: '%s'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown 'get' Device: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
@@ -1049,7 +1321,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Param = GetDeviceParam( Device, ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Param: '%s'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown 'get' Param: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
@@ -1057,7 +1329,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
// Check for additional parameters
if (NextParam) {
// Unused Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary parameters for 'Get'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary 'get' parameters",
ProcessName, Name, ChannelName );
return MaxLen;
}
@@ -1080,7 +1352,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
// Check for additional parameters
if (!NextParam) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing parameters for 'Set'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing 'set' parameters",
ProcessName, Name, ChannelName );
return MaxLen;
}
@@ -1089,7 +1361,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Device = GetDevice( ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Device: '%s'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown 'set' Device: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
@@ -1098,7 +1370,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Param = GetDeviceParam( Device, ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Param: '%s'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown 'set' Param: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
@@ -1107,7 +1379,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
GetCmdParam( NextParam, ParamName, &NextParam );
if (strlen(ParamName) == 0) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - No value parameter for 'Set'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - No 'set' value parameter",
ProcessName, Name, ChannelName );
return MaxLen;
}
@@ -1115,7 +1387,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
// Check for additional parameters
if (NextParam) {
// Unused Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary parameters for 'Get'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary 'set' parameters",
ProcessName, Name, ChannelName );
return MaxLen;
}
@@ -1135,7 +1407,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
// Check for additional parameters
if (!NextParam) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing parameters for 'Set'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing 'status' parameters",
ProcessName, Name, ChannelName );
return MaxLen;
}
@@ -1144,7 +1416,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Device = GetDevice( ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Device: '%s'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown 'status' Device: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
@@ -1152,7 +1424,7 @@ int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, cons
// Check for additional parameters
if (NextParam) {
// Unused Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary parameters for 'Status'",
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary 'status' parameters",
ProcessName, Name, ChannelName );
return MaxLen;
}

View File

@@ -12,6 +12,7 @@
/* none */
// redA Libraries
#include "JSONparseCore.h"
#include "FunctionCore.h"
//---------------------------------------------------------------------------
@@ -28,48 +29,65 @@ const char DataTypeName[][20] = { "None", "Unsigned16", "Signed16", "Unsigned32"
// Structure prototypes
typedef struct SDevice TDevice;
typedef struct SDeviceParam TDeviceParam;
typedef struct SDeviceParamGroup TDeviceParamGroup;
typedef struct SDeviceParamItem TDeviceParamItem;
// Devices with are polled
struct SDevice {
// Device definition
char * Name;
char * Type;
char * Name = NULL;
char * Type = NULL;
TDevice * Template = NULL;
// Device status
bool Online;
bool Online = false;
// Device parameters
TDeviceParam * FirstParam;
TDeviceParam * FirstParam = NULL;
// Device peer list
TDevice * Next;
TDevice * Next = NULL;
};
// Data parameters of devices
struct SDeviceParam {
// Parameter definition
char * Name;
EDeviceDataType DataType;
char * Name = NULL;
EDeviceDataType DataType = dtNone;
TDevice * Device = Device;
// Last value (received from device)
void * Value = NULL;
int Len = 0;
bool Changed = false;
// Polling/Event parameters
bool Read;
TChannel * EventChannel;
long EventInterval;
bool Read = false;
TChannel * EventChannel = NULL;
long EventInterval = 0;
timeval EventTimeout;
// Last value received from device
void * Value;
int Len;
bool Changed;
// Value to on device
bool Write;
void * SetValue;
int SetLen;
bool SetChanged;
bool Write = false;
void * SetValue = NULL;
int SetLen = 0;
bool SetChanged = false;
// Parameter peer list
TDeviceParam * Next;
TDeviceParam * Next = NULL;
};
// Parameters groups - used where parameters are read/written as a groug
struct SDeviceParamGroup {
char * Name = NULL;
TDevice * Device = NULL;
TDeviceParamItem * FirstParam = NULL;
TDeviceParamGroup * NextGroup = NULL;
};
struct SDeviceParamItem {
TDeviceParam * Param = NULL;
TDeviceParamItem * NextItem = NULL;
};
//---------------------------------------------------------------------------
@@ -84,17 +102,22 @@ class CDeviceCore : public CFunctionCore
{
protected:
// Configuration
CDataMember * Config;
bool DeviceInit;
CDataMember * Config = NULL;
CDataMember * ConfigTypes = NULL;
CJSONparse * JSONparse = NULL;
bool DeviceInit = false;
// Parameters
TDevice * FirstDevice;
TDevice * ActiveDevice;
// Devices & Type
TDevice * FirstDeviceType = NULL;
TDevice * FirstDevice = NULL;
TDevice * ActiveDevice = NULL;
TDeviceParamGroup * FirstParamGroup = NULL;
// Standard channels
TChannel * DeviceChannel;
TChannel * CmdChannel;
TChannel * EventChannel;
TChannel * DeviceChannel = NULL;
TChannel * CmdChannel = NULL;
TChannel * EventChannel = NULL;
// Poll
int PollStep; // Position in polling sequence
@@ -112,14 +135,26 @@ protected:
// Manage Devices
bool DestroyDevice( TDevice ** Device );
// Find Device Types
inline TDevice * GetDeviceType( const char * TypeName ) {
TDevice ** DeviceType = GetDeviceTypePtr( TypeName );
return (DeviceType)? *DeviceType : NULL;
}
inline TDevice ** GetDeviceTypePtr( const char * TypeName ) {
if (!TypeName || !*TypeName) return NULL;
TDevice ** DeviceType = &FirstDeviceType;
while (*DeviceType && strcasecmp( (*DeviceType)->Type, TypeName ))
DeviceType = &((*DeviceType)->Next);
return DeviceType;
}
// Find Devices
inline TDevice * GetDevice( const char * Name ) {
TDevice * Device = FirstDevice;
while (Device && strcasecmp( Device->Name, Name ))
Device = Device->Next;
return Device;
TDevice ** Device = GetDevicePtr(Name);
return (Device)? *Device : NULL;
}
inline TDevice ** GetDevicePtr( const char * Name ) {
if (!Name || !*Name) return NULL;
TDevice ** Device = &FirstDevice;
while (*Device && strcasecmp( (*Device)->Name, Name ))
Device = &((*Device)->Next);
@@ -127,7 +162,7 @@ protected:
}
inline TDevice * GetNextTypeDevice( const char * Type, TDevice * PrevDevice = NULL ) {
TDevice * Device = (PrevDevice)? PrevDevice->Next : FirstDevice;
while (Device && ((!Type && Device->Type) || (Type && (!Device->Type || !strcasecmp( Type, Device->Type )))))
while (Device && ((!Type && Device->Type) || (Type && (!Device->Type || strcasecmp( Type, Device->Type )))))
Device = Device->Next;
return Device;
}
@@ -143,14 +178,11 @@ protected:
// Find Params
inline TDeviceParam * GetDeviceParam( TDevice * Device, const char * pName ) {
if (!Device || !pName) return NULL;
TDeviceParam * Param = Device->FirstParam;
while (Param && strcasecmp( Param->Name, pName ))
Param = Param->Next;
return Param;
TDeviceParam ** Param = GetDeviceParamPtr(Device, pName);
return (Param)? *Param : NULL;
}
inline TDeviceParam ** GetDeviceParamPtr( TDevice * Device, const char * pName ) {
if (!Device || !pName) return NULL;
if (!Device || !pName || !*pName) return NULL;
TDeviceParam ** Param = &(Device->FirstParam);
while (*Param && strcasecmp( (*Param)->Name, pName ))
Param = &((*Param)->Next);
@@ -178,6 +210,36 @@ protected:
return Param;
}
// Manage Param Groups
bool DestroyParamGroup( TDeviceParamGroup ** Group );
bool DestroyParamItem( TDeviceParamItem ** Item );
// Find Param Groups
inline TDeviceParamGroup * GetParamGroup( const char * GroupName ) {
TDeviceParamGroup ** Group = GetParamGroupPtr( GroupName );
return (Group)? *Group : NULL;
}
inline TDeviceParamGroup ** GetParamGroupPtr( const char * GroupName ) {
if (!GroupName || !*GroupName) return NULL;
TDeviceParamGroup ** Group = &FirstParamGroup;
while (*Group && strcasecmp( (*Group)->Name, GroupName ))
Group = &((*Group)->NextGroup);
return Group;
}
// Find Param Groups Items
inline TDeviceParamItem * GetParamItem( TDeviceParamGroup * Group, const char * ParamName ) {
TDeviceParamItem ** Item = GetParamItemPtr( Group, ParamName );
return (Item)? *Item : NULL;
}
inline TDeviceParamItem ** GetParamItemPtr( TDeviceParamGroup * Group, const char * ParamName ) {
if (!Group || !ParamName || !*ParamName) return NULL;
TDeviceParamItem ** Item = &Group->FirstParam;
while (*Item && strcasecmp( (*Item)->Param->Name, ParamName ))
Item = &((*Item)->NextItem);
return Item;
}
// Tools
inline EDeviceDataType GetDataType( const char * TypeName ) {
int Type;
@@ -207,6 +269,8 @@ public:
// Configuration
virtual bool Init( CDataMember * FunctionConfig );
virtual bool InitDevices( CDataMember * FunctionConfig );
virtual bool InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig );
virtual bool InitParamGroups( TDevice * Device, CDataMember * DeviceConfig );
// Polling parameters
bool SetPollParam( int pPollInterval );
@@ -215,6 +279,13 @@ public:
bool SetParamAccess( TDeviceParam * Param, bool Read, bool Write );
bool SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval );
// Manage Devices Types
TDevice * AddDeviceType( const char * DeviceTypeName );
inline bool DestroyDeviceType( const char * DeviceTypeName ) {
TDevice ** DeviceType = GetDeviceTypePtr(DeviceTypeName);
return (DeviceType)? DestroyDevice( DeviceType ) : false;
}
// Manage Devices
TDevice * AddDevice( const char * DeviceName, const char * Type = NULL );
inline bool DestroyDevice( const char * DeviceName ) {
@@ -229,6 +300,18 @@ public:
return (Param)? DestroyDeviceParam( Param ) : false;
};
// Manage Param Groups
TDeviceParamGroup * AddParamGroup( TDevice * Device, const char * GroupName );
inline bool DestroyParamGroup( const char * GroupName ) {
TDeviceParamGroup ** Group = GetParamGroupPtr( GroupName );
return (Group)? DestroyParamGroup( Group ) : false;
};
TDeviceParamItem * AddParamItem( TDeviceParamGroup * Group, const char * ParamName );
inline bool DestroyParamItem( TDeviceParamGroup * Group, const char * ParamName ) {
TDeviceParamItem ** Item = GetParamItemPtr( Group, ParamName );
return (Item)? DestroyParamItem( Item ) : false;
};
// Update/Init Param values
bool UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Value, bool Init );
bool UpdateSignedValue( TDeviceParam * Param, const int32_t Value, bool Init );

View File

@@ -34,21 +34,11 @@ CFunctionCore::CFunctionCore( const char * pName, const char * pType ) : Type( p
Name = (char*)malloc( strlen(pName)+1 );
strcpy( Name, pName );
}
else {
Name = NULL;
}
// Channels
FirstChannel = NULL;
// Logging
Log = Application->Log;
LogLevel = dlNone;
LogOutput = loNormal;
// Stored output
StoredOutput = NULL;
StoredOutputLen = 0;
}
//---------------------------------------------------------------------------

View File

@@ -27,24 +27,24 @@ class CFunctionCore;
struct SChannel
{
char * Name;
char * Name = NULL;
TChannelLink * FirstInput;
TChannelLink * FirstOutput;
TChannelLink * FirstInput = NULL;
TChannelLink * FirstOutput = NULL;
bool InputEnabled;
bool OutputEnabled;
bool InputEnabled = NULL;
bool OutputEnabled = NULL;
TChannel * Next;
TChannel * Next = NULL;
};
//---------------------------------------------------------------------------
struct SChannelLink
{
CFunctionCore * Function;
char * Name;
CFunctionCore * Function = NULL;
char * Name = NULL;
SChannelLink * Next;
SChannelLink * Next = NULL;
};
//---------------------------------------------------------------------------
@@ -58,20 +58,20 @@ class CFunctionCore
{
protected:
// Function Definition
const char * Type;
char * Name;
const char * Type = NULL;
char * Name = NULL;
// Channels
TChannel * FirstChannel;
TChannel * FirstChannel = NULL;
// Logging
CLogCore * Log;
EDebugLevel LogLevel;
int LogOutput;
CLogCore * Log = NULL;
EDebugLevel LogLevel = dlNone;
int LogOutput = loNone;
// Stored Output
char * StoredOutput;
int StoredOutputLen;
char * StoredOutput = NULL;
int StoredOutputLen = 0;
// Manage Channel
inline TChannel * GetChannel( const char * pName ) {