Important Update:

- DataTreeCore:
  - Rename enum EDataType -> EJsonDataType
- DeviceCore:
  - Rename enum EMBDataType -> EDeviceDataType
  - Add method GetNextTypeDevice() method
  - Bug fix: Add Type Name: 0 -> "none"
  - Added permanent Event Channel to TDevice
  - Add param Type to TDevice
  - Removed UpdateInterval/Timeout params & methods from TDevice
  - Separated DeviceInit() method from Init()
  - Add param DeviceInit to force/avoid DeviceInit() in Init()
  - Renamed and restructured SetUpdate() & SetParamScan() methods to:
      SetParamAccess() & SetParamEvent()
  - Converted DestroyDevice() and DestroyDeviceParam() to inline methods
  - Moved methods GetCmdParam() and HandleCommand() from CModbusInterface
  - Renamed TDeviceParam field:
    UpdateInterval/Timeout -> EventInterval/Timeout
  - Renamed TDeviceParam field: Scan -> Read
  - Added TDeviceParam field: Write
This commit is contained in:
Charl Wentzel
2018-12-11 19:55:44 +02:00
parent 07f746db2a
commit 3f568364da
4 changed files with 393 additions and 123 deletions

View File

@@ -353,7 +353,7 @@ bool CDataMember::DeleteCh( const char * Path )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDataMember::SetValuePtr( EDataType pType, const char * pValue, int pLen ) bool CDataMember::SetValuePtr( EJsonDataType pType, const char * pValue, int pLen )
{ {
Clear(); Clear();
Type = pType; Type = pType;
@@ -367,7 +367,7 @@ bool CDataMember::SetValuePtr( EDataType pType, const char * pValue, int pLen )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDataMember::SetValue( EDataType pType, const char * pValue, int pLen ) bool CDataMember::SetValue( EJsonDataType pType, const char * pValue, int pLen )
{ {
// Clear & Update Type // Clear & Update Type
Clear(); Clear();
@@ -511,7 +511,7 @@ const char * CDataMember::GetChName( const char * Path )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
EDataType CDataMember::GetChType( const char * Path ) EJsonDataType CDataMember::GetChType( const char * Path )
{ {
CDataMember * Member; CDataMember * Member;

View File

@@ -16,7 +16,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
typedef enum { jtNull = 0, jtBool = 1, jtInt = 2, jtFloat = 3, jtString = 4, jtArray = 5, jtObject = 6 } EDataType; typedef enum { jtNull = 0, jtBool = 1, jtInt = 2, jtFloat = 3, jtString = 4, jtArray = 5, jtObject = 6 } EJsonDataType;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -25,7 +25,7 @@ class CDataMember
{ {
char * Name; char * Name;
unsigned short NameLen; unsigned short NameLen;
EDataType Type; EJsonDataType Type;
char * Value; char * Value;
unsigned short Len; unsigned short Len;
@@ -41,8 +41,8 @@ class CDataMember
CDataMember * CreateChild( const char * Name, const int Len = -1 ); CDataMember * CreateChild( const char * Name, const int Len = -1 );
// Set Member value // Set Member value
bool SetValue( EDataType Type, const char * Value = NULL, int Len = -1 ); bool SetValue( EJsonDataType Type, const char * Value = NULL, int Len = -1 );
bool SetValuePtr( EDataType pType, const char * pValue, int pLen = -1 ); bool SetValuePtr( EJsonDataType pType, const char * pValue, int pLen = -1 );
public: public:
CDataMember( const char * pName = NULL, const int pLen = -1 ); CDataMember( const char * pName = NULL, const int pLen = -1 );
@@ -57,8 +57,8 @@ public:
/* Check Type */ /* Check Type */
EDataType GetType() { return Type; }; EJsonDataType GetType() { return Type; };
EDataType GetChType( const char * Path ); EJsonDataType GetChType( const char * Path );
inline bool isNull() { return (Type == jtNull); }; inline bool isNull() { return (Type == jtNull); };
inline bool isBool() { return (Type == jtBool); }; inline bool isBool() { return (Type == jtBool); };

View File

@@ -36,6 +36,7 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo
// Standard channels // Standard channels
DeviceChannel = NULL; DeviceChannel = NULL;
CmdChannel = NULL; CmdChannel = NULL;
EventChannel = NULL;
// Polling // Polling
PollStep = 0; PollStep = 0;
@@ -48,11 +49,9 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo
PollRetry = 0; PollRetry = 0;
MaxRetries = 3; MaxRetries = 3;
// Update Timer
SetUpdate( 0 );
// Data Structures // Data Structures
Config = NULL; Config = NULL;
DeviceInit = true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -75,6 +74,14 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
if (!CFunctionCore::Init( FunctionConfig )) if (!CFunctionCore::Init( FunctionConfig ))
return false; return false;
// Add Channels
if (!(CmdChannel = GetChannel( "Command" )))
CmdChannel = AddChannel( "Command", true, true );
if (!(DeviceChannel = GetChannel( "Device" )))
DeviceChannel = AddChannel( "Device", true, true );
if (!(DeviceChannel = GetChannel( "Event" )))
DeviceChannel = AddChannel( "Event", true, true );
// Get configuration // Get configuration
if ((Config = FunctionConfig->GetChild( "Config", true )) && Config->isString()) { if ((Config = FunctionConfig->GetChild( "Config", true )) && Config->isString()) {
ConfigName = (char*)FunctionConfig->GetChStr( "Config" ); ConfigName = (char*)FunctionConfig->GetChStr( "Config" );
@@ -93,12 +100,85 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
IntVal2 = PollConfig->GetChInt( "MaxRetries", 3, true ); IntVal2 = PollConfig->GetChInt( "MaxRetries", 3, true );
SetReplyParam( IntVal1, IntVal2 ); SetReplyParam( IntVal1, IntVal2 );
IntVal1 = PollConfig->GetChInt( "UpdateInterval", 1000, true );
SetUpdate( IntVal1 );
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, TO:%d, Max:%d, Up:%d",
ProcessName, Name, PollInterval, ReplyTimeout, MaxRetries, UpdateInterval ); ProcessName, Name, PollInterval, ReplyTimeout, MaxRetries );
// Update Devices -- may want to do it from derived class intead
if (DeviceInit) {
InitDevices( FunctionConfig );
}
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::InitDevices( CDataMember * FunctionConfig )
{
CDataMember * DeviceData;
CDataMember * ParamData;
CDataMember * InitVal;
TDevice * Device;
TDeviceParam * Param;
EDeviceDataType DataType;
bool Read;
bool Write;
char * EventOut;
int EventInt;
// Add Devices
DeviceData = Config->GetChFirstChild( "Devices", true );
while (DeviceData)
{
// Add device
Device = AddDevice( DeviceData->GetName() );
Param = NULL;
// Add Parameters
ParamData = DeviceData->GetChFirstChild( "Parameters", true );
while (ParamData)
{
DataType = GetDataType((char*)ParamData->GetChStr( "Type", "Unsigned16", true ));
if (!(Param = AddDeviceParam( Device, ParamData->GetName(), DataType, 1 )))
continue;
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 );
// Read + Event Out
ParamData = ParamData->GetNextPeer();
}
DeviceData = DeviceData->GetNextPeer();
}
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -118,15 +198,6 @@ bool CDeviceCore::SetReplyParam( int pReplyTimeout, int pMaxRetries )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Generate events
bool CDeviceCore::SetUpdate( int pUpdateInterval )
{
UpdateInterval = pUpdateInterval;
SetStartTime( &UpdateTimeout );
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::DeviceOnline( TDevice * Device, bool Online ) bool CDeviceCore::DeviceOnline( TDevice * Device, bool Online )
{ {
// Validate // Validate
@@ -192,54 +263,43 @@ bool CDeviceCore::CheckReplyTimeout( int TimeoutPollStep )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TDevice * CDeviceCore::AddDevice( const char * DeviceName ) TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * Type )
{ {
// Get register or end of list
TDevice ** Device = &FirstDevice; TDevice ** Device = &FirstDevice;
if (!DeviceName || !*DeviceName) return NULL;
while (*Device && strcmp( DeviceName, (*Device)->Name )) while (*Device && strcmp( DeviceName, (*Device)->Name ))
Device = &((*Device)->Next); Device = &((*Device)->Next);
// Create if not found // Create if not found
if (!*Device) { if (!*Device)
// Create register {
*Device = (TDevice*)malloc( sizeof(TDevice) ); *Device = (TDevice*)malloc( sizeof(TDevice) );
memset( *Device, 0x0, sizeof(TDevice) ); memset( *Device, 0x0, sizeof(TDevice) );
// Set Name
(*Device)->Name = (char *)malloc( strlen( DeviceName )+1 ); (*Device)->Name = (char *)malloc( strlen( DeviceName )+1 );
strcpy( (*Device)->Name, DeviceName ); strcpy( (*Device)->Name, DeviceName );
if (Type && *Type) {
(*Device)->Type = (char *)malloc( strlen( Type )+1 );
strcpy( (*Device)->Type, Type );
}
} }
// Report creation // Report creation
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Device added - '%s'", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Device added - '%s' (%s)",
ProcessName, Name, DeviceName ); ProcessName, Name, DeviceName, (Type)? Type : "no type" );
return *Device; return *Device;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::DestroyDevice( const char * DeviceName )
{
TDevice ** Device = NULL;
// Find device
if (!(Device = GetDevicePtr(DeviceName)))
return false;
// Destroy Device
if (!DestroyDevice( Device ))
return false;
// Device destroyed
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::DestroyDevice( TDevice ** Device ) bool CDeviceCore::DestroyDevice( TDevice ** Device )
{ {
TDevice * NextDevice = NULL; TDevice * NextDevice = NULL;
// Validate param // Validate Device
if (!Device || !*Device) if (!Device || !*Device)
return false; return false;
@@ -249,13 +309,15 @@ bool CDeviceCore::DestroyDevice( TDevice ** Device )
// Destroy Device structure // Destroy Device structure
if ((*Device)->Name) if ((*Device)->Name)
free( (*Device)->Name ); free( (*Device)->Name );
if ((*Device)->Type)
free( (*Device)->Type );
// Destroy paramters // Destroy paramters
while ((*Device)->FirstParam) { while ((*Device)->FirstParam) {
DestroyDeviceParam( &((*Device)->FirstParam) ); DestroyDeviceParam( &((*Device)->FirstParam) );
} }
// Destory Device // Destroy Device
free( *Device ); free( *Device );
// Remove from list // Remove from list
@@ -266,7 +328,7 @@ bool CDeviceCore::DestroyDevice( TDevice ** Device )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * ParamName, EMBDataType DataType, int ParamLen ) TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * ParamName, EDeviceDataType DataType, int ParamLen )
{ {
// Get register or end of list // Get register or end of list
TDeviceParam ** Param = &Device->FirstParam; TDeviceParam ** Param = &Device->FirstParam;
@@ -375,23 +437,6 @@ TDeviceParam * CDeviceCore::AddDeviceParam( TDevice * Device, const char * Param
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::DestroyDeviceParam( TDevice * Device, const char * ParamName )
{
TDeviceParam ** Param = NULL;
// Find param
if (!(Param = GetDeviceParamPtr( Device, ParamName )))
return false;
// Destroy Param
if (!DestroyDeviceParam( Param ))
return false;
// Parameter destroyed
return true;
}
//---------------------------------------------------------------------------
bool CDeviceCore::DestroyDeviceParam( TDeviceParam ** Param ) bool CDeviceCore::DestroyDeviceParam( TDeviceParam ** Param )
{ {
TDeviceParam * NextParam = NULL; TDeviceParam * NextParam = NULL;
@@ -894,22 +939,27 @@ bool CDeviceCore::CompareParamString( const char * ParamValue, const int ParamLe
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::SetParamScan( TDeviceParam * Param, bool Scan, const char * ChannelName, long pUpdateInterval ) bool CDeviceCore::SetParamAccess( TDeviceParam * Param, bool Read, bool Write )
{ {
// Validate
if (!Param) if (!Param)
return false; return false;
// Set scan parameters Param->Read = Read;
Param->Scan = Scan; Param->Write = Write;
Param->EventChannel = GetChannel( ChannelName ); return true;
// Configure Update timer
if (pUpdateInterval) {
Param->UpdateInterval = pUpdateInterval;
SetStartTime( &(Param->UpdateTimeout) );
} }
//---------------------------------------------------------------------------
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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -923,10 +973,8 @@ bool CDeviceCore::TimedParamEvents()
Device = FirstDevice; Device = FirstDevice;
while (Device) while (Device)
{ {
// Loop through all scan parameters // Loop through all Read parameters
while ((Param = GetNextScanParam( Device, Param ))) while ((Param = GetNextReadParam( Device, Param ))) {
{
// Generate timed events
EventOutput( Param, false ); EventOutput( Param, false );
} }
Device = Device->Next; Device = Device->Next;
@@ -935,6 +983,197 @@ bool CDeviceCore::TimedParamEvents()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDeviceCore::GetCmdParam( const char * Start, char * Param, char ** NextParam )
{
char * NextDelimeter;
int ParamLen;
// Get length of param
if ((NextDelimeter = strchr( (char*)Start, ',' ))) {
ParamLen = NextDelimeter - Start;
*NextParam = NextDelimeter + 1;
}
else {
// remove \r\n if necessary
ParamLen = strlen( Start );
if (Start[ParamLen-1] == '\n')
ParamLen--;
if (Start[ParamLen-1] == '\r')
ParamLen--;
*NextParam = NULL;
}
// Copy param
strncpy( Param, Start, ParamLen );
Param[ParamLen] = 0;
return true;
}
//---------------------------------------------------------------------------
int CDeviceCore::HandleCommand( const char *ChannelName, const char * Data, const int MaxLen )
{
int Len;
char ParamName[50];
char * NextParam = NULL;
TDevice * Device = NULL;
TDeviceParam * Param = NULL;
char OutputStr[250];
// Show accepted input
Log->Output( LogLevel, dlHigh, loNormal, Data, MaxLen, "%s/%s: Channel '%s' - IN:",
ProcessName, Name, ChannelName );
// Get command command
GetCmdParam( Data, ParamName, &NextParam );
if (!strcasecmp( "get", ParamName ))
{
// Check for additional parameters
if (!NextParam) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing parameters for 'Get'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Get device name
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Device = GetDevice( ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Device: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
// Get parameter name
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Param = GetDeviceParam( Device, ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Param: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
// Check for additional parameters
if (NextParam) {
// Unused Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary parameters for 'Get'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Build reply
sprintf( OutputStr, "get,%s,", Param->Name );
Len = MaxLen - strlen(OutputStr);
// Insert value
if (!GetValue( (TDeviceParam*)Param, &OutputStr[ strlen(OutputStr) ], Len ))
return false;
// Send reply
strcat( OutputStr, "\n" );
Output( ChannelName, OutputStr, strlen(OutputStr) );
return true;
}
else if (!strcasecmp( "set", ParamName ))
{
// Check for additional parameters
if (!NextParam) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing parameters for 'Set'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Get Device name
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Device = GetDevice( ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Device: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
// Get parameter name
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Param = GetDeviceParam( Device, ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Param: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
// Get parameter value
GetCmdParam( NextParam, ParamName, &NextParam );
if (strlen(ParamName) == 0) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - No value parameter for 'Set'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Check for additional parameters
if (NextParam) {
// Unused Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary parameters for 'Get'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Set value
Len = MaxLen;
if (!SetValue( Param, ParamName, Len, true ))
return false;
// Build & send reply
sprintf( OutputStr, "set,%s,%s\n", Param->Name, ParamName );
Output( ChannelName, OutputStr );
return true;
}
else if (!strcasecmp( "status", ParamName ))
{
// Check for additional parameters
if (!NextParam) {
// No Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Missing parameters for 'Set'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Get Device name
GetCmdParam( NextParam, ParamName, &NextParam );
if (!(Device = GetDevice( ParamName ))) {
// Unknown Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unknown Device: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
// Check for additional parameters
if (NextParam) {
// Unused Parameters
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unnecessary parameters for 'Status'",
ProcessName, Name, ChannelName );
return MaxLen;
}
// Build & send reply
sprintf( OutputStr, "status,%s,%d\n", Device->Name, Device->Online );
Output( ChannelName, OutputStr );
return true;
}
else
{
// Unrecognised command
Log->Message( LogLevel, dlMedium, "%s/%s: Channel '%s' - Unrecognized command: '%s'",
ProcessName, Name, ChannelName, ParamName );
return MaxLen;
}
return MaxLen;
}
//---------------------------------------------------------------------------
// Generate Event output // Generate Event output
bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force ) bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force )
{ {
@@ -944,7 +1183,7 @@ bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force )
// Check Timer or force // Check Timer or force
if (Force || if (Force ||
(Param->UpdateInterval && Timeout( Param->UpdateTimeout, Param->UpdateInterval )) ) (Param->EventInterval && Timeout( Param->EventTimeout, Param->EventInterval )) )
{ {
// Post event // Post event
char Message[200]; char Message[200];
@@ -980,8 +1219,8 @@ bool CDeviceCore::EventOutput( TDeviceParam * Param, bool Force )
Output( Param->EventChannel, Message, strlen(Message) ); Output( Param->EventChannel, Message, strlen(Message) );
// Reset timer // Reset timer
if (Param->UpdateInterval) { if (Param->EventInterval) {
SetStartTime( &(Param->UpdateTimeout) ); SetStartTime( &(Param->EventTimeout) );
} }
} }
return true; return true;

View File

@@ -17,11 +17,11 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Enumerated types // Enumerated types
typedef enum { dtNone = 0, dtUnsigned16 = 1, dtSigned16 = 2, dtUnsigned32 = 3, dtSigned32 = 4, dtFloat32 = 5, dtString = 6 } EMBDataType; typedef enum { dtNone = 0, dtUnsigned16 = 1, dtSigned16 = 2, dtUnsigned32 = 3, dtSigned32 = 4, dtFloat32 = 5, dtString = 6 } EDeviceDataType;
// Constants // Constants
const char DataTypeCount = 6; const char DataTypeCount = 6;
const char DataTypeName[][20] = { "Unsigned16", "Signed16", "Unsigned32", "Signed32", "Float32", "String" }; const char DataTypeName[][20] = { "None", "Unsigned16", "Signed16", "Unsigned32", "Signed32", "Float32", "String" };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -31,32 +31,44 @@ typedef struct SDeviceParam TDeviceParam;
// Devices with are polled // Devices with are polled
struct SDevice { struct SDevice {
// Device definition
char * Name; char * Name;
char * Type;
// Device status
bool Online; bool Online;
// Device parameters
TDeviceParam * FirstParam; TDeviceParam * FirstParam;
// Device peer list
TDevice * Next; TDevice * Next;
}; };
// Data parameters of devices // Data parameters of devices
struct SDeviceParam { struct SDeviceParam {
// Parameter definition
char * Name; char * Name;
EMBDataType DataType; EDeviceDataType DataType;
bool Scan; // Polling/Event parameters
bool Read;
TChannel * EventChannel; TChannel * EventChannel;
long UpdateInterval; long EventInterval;
timeval UpdateTimeout; timeval EventTimeout;
// Last value received from device
void * Value; void * Value;
int Len; int Len;
bool Changed; bool Changed;
// Value to on device
bool Write;
void * SetValue; void * SetValue;
int SetLen; int SetLen;
bool SetChanged; bool SetChanged;
// Parameter peer list
TDeviceParam * Next; TDeviceParam * Next;
}; };
@@ -73,10 +85,7 @@ class CDeviceCore : public CFunctionCore
protected: protected:
// Configuration // Configuration
CDataMember * Config; CDataMember * Config;
bool DeviceInit;
// Update
int UpdateInterval;
timeval UpdateTimeout;
// Parameters // Parameters
TDevice * FirstDevice; TDevice * FirstDevice;
@@ -85,6 +94,7 @@ protected:
// Standard channels // Standard channels
TChannel * DeviceChannel; TChannel * DeviceChannel;
TChannel * CmdChannel; TChannel * CmdChannel;
TChannel * EventChannel;
// Poll // Poll
int PollStep; // Position in polling sequence int PollStep; // Position in polling sequence
@@ -115,8 +125,14 @@ protected:
Device = &((*Device)->Next); Device = &((*Device)->Next);
return Device; return Device;
} }
inline TDevice * GetNextOnlineDevice( TDevice * LastDevice ) { inline TDevice * GetNextTypeDevice( const char * Type, TDevice * PrevDevice = NULL ) {
TDevice * Device = LastDevice; TDevice * Device = (PrevDevice)? PrevDevice->Next : FirstDevice;
while (Device && ((!Type && Device->Type) || (Type && (!Device->Type || !strcasecmp( Type, Device->Type )))))
Device = Device->Next;
return Device;
}
inline TDevice * GetNextOnlineDevice( TDevice * PrevDevice = NULL ) {
TDevice * Device = (PrevDevice)? PrevDevice->Next : FirstDevice;
while (Device && !Device->Online) while (Device && !Device->Online)
Device = Device->Next; Device = Device->Next;
return Device; return Device;
@@ -126,24 +142,24 @@ protected:
bool DestroyDeviceParam( TDeviceParam ** Param ); bool DestroyDeviceParam( TDeviceParam ** Param );
// Find Params // Find Params
inline TDeviceParam * GetDeviceParam( TDevice * Device, const char * Name ) { inline TDeviceParam * GetDeviceParam( TDevice * Device, const char * pName ) {
if (!Device) return NULL; if (!Device || !pName) return NULL;
TDeviceParam * Param = Device->FirstParam; TDeviceParam * Param = Device->FirstParam;
while (Param && strcasecmp( Param->Name, Name )) while (Param && strcasecmp( Param->Name, pName ))
Param = Param->Next; Param = Param->Next;
return Param; return Param;
} }
inline TDeviceParam ** GetDeviceParamPtr( TDevice * Device, const char * Name ) { inline TDeviceParam ** GetDeviceParamPtr( TDevice * Device, const char * pName ) {
if (!Device) return NULL; if (!Device || !pName) return NULL;
TDeviceParam ** Param = &Device->FirstParam; TDeviceParam ** Param = &(Device->FirstParam);
while (*Param && strcasecmp( (*Param)->Name, Name )) while (*Param && strcasecmp( (*Param)->Name, pName ))
Param = &((*Param)->Next); Param = &((*Param)->Next);
return Param; return Param;
} }
inline TDeviceParam * GetNextScanParam( TDevice * Device, TDeviceParam * LastParam = NULL ) { inline TDeviceParam * GetNextReadParam( TDevice * Device, TDeviceParam * LastParam = NULL ) {
if (!Device) return NULL; if (!Device) return NULL;
TDeviceParam * Param = (LastParam)? LastParam->Next : Device->FirstParam; TDeviceParam * Param = (LastParam)? LastParam->Next : Device->FirstParam;
while (Param && (!Param->Scan)) while (Param && (!Param->Read))
Param = Param->Next; Param = Param->Next;
return Param; return Param;
} }
@@ -163,11 +179,11 @@ protected:
} }
// Tools // Tools
inline EMBDataType GetDataType( const char * TypeName ) { inline EDeviceDataType GetDataType( const char * TypeName ) {
int Type; int Type;
for (Type = 0; Type < DataTypeCount; Type++) for (Type = 0; Type < DataTypeCount; Type++)
if (!strcasecmp( TypeName, DataTypeName[Type])) break; if (!strcasecmp( TypeName, DataTypeName[Type])) break;
return (Type == DataTypeCount)? dtNone : (EMBDataType)Type; return (Type == DataTypeCount)? dtNone : (EDeviceDataType)Type;
} }
bool CompareParamString( const char * ParamValue, const int ParamLen, const char * Value, const int Len ); bool CompareParamString( const char * ParamValue, const int ParamLen, const char * Value, const int Len );
@@ -189,39 +205,54 @@ public:
virtual ~CDeviceCore(); virtual ~CDeviceCore();
// Configuration // Configuration
bool Init( CDataMember * FunctionConfig ); virtual bool Init( CDataMember * FunctionConfig );
virtual bool InitDevices( CDataMember * FunctionConfig );
// Generate events // Polling parameters
bool SetPollParam( int pPollInterval ); bool SetPollParam( int pPollInterval );
bool SetReplyParam( int pReplyTimeout, int pMaxRetries ); bool SetReplyParam( int pReplyTimeout, int pMaxRetries );
bool SetUpdate( int pUpdateInterval );
bool SetParamScan( TDeviceParam * Param, bool Scan, const char * ChannelName, long pUpdateInterval ); bool SetParamAccess( TDeviceParam * Param, bool Read, bool Write );
bool SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval );
// Manage Devices // Manage Devices
TDevice * AddDevice( const char * DeviceName ); TDevice * AddDevice( const char * DeviceName, const char * Type = NULL );
bool DestroyDevice( const char * DeviceName ); inline bool DestroyDevice( const char * DeviceName ) {
TDevice ** Device = GetDevicePtr(DeviceName);
return (Device)? DestroyDevice( Device ) : false;
}
// Manage Params // Manage Params
TDeviceParam * AddDeviceParam( TDevice * Device, const char * ParamName, EMBDataType DataType, int ParamLen = 1 ); TDeviceParam * AddDeviceParam( TDevice * Device, const char * ParamName, EDeviceDataType DataType, int ParamLen = 1 );
bool DestroyDeviceParam( TDevice * Device, const char * ParamName ); inline bool DestroyDeviceParam( TDevice * Device, const char * ParamName ) {
TDeviceParam ** Param = GetDeviceParamPtr( Device, ParamName );
return (Param)? DestroyDeviceParam( Param ) : false;
};
// Update/Init Param values // Update/Init Param values
bool UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Value, bool Init ); bool UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Value, bool Init );
bool UpdateSignedValue( TDeviceParam * Param, const int32_t Value, bool Init ); bool UpdateSignedValue( TDeviceParam * Param, const int32_t Value, bool Init );
bool UpdateFloatValue( TDeviceParam * Param, const float Value, bool Init ); bool UpdateFloatValue( TDeviceParam * Param, const float Value, bool Init );
bool UpdateStringValue( TDeviceParam * Param, const char * Value, const int Len, bool Init ); bool UpdateStringValue( TDeviceParam * Param, const char * Value, const int Len, bool Init );
bool UpdateStringValue( TDeviceParam * Param, const char * Value, bool Init ) inline bool UpdateStringValue( TDeviceParam * Param, const char * Value, bool Init ) {
{ return UpdateStringValue( Param, Value, strlen(Value), Init ); }; return UpdateStringValue( Param, Value, strlen(Value), Init );
};
// Change Param Update instruction // Change Param Update instruction
bool SetUnsignedValue( TDeviceParam * Param, const u_int32_t Value, bool Force ); bool SetUnsignedValue( TDeviceParam * Param, const u_int32_t Value, bool Force );
bool SetSignedValue( TDeviceParam * Param, const int32_t Value, bool Force ); bool SetSignedValue( TDeviceParam * Param, const int32_t Value, bool Force );
bool SetFloatValue( TDeviceParam * Param, const float Value, bool Force ); bool SetFloatValue( TDeviceParam * Param, const float Value, bool Force );
bool SetStringValue( TDeviceParam * Param, const char * Value, const int Len, bool Force ); bool SetStringValue( TDeviceParam * Param, const char * Value, const int Len, bool Force );
bool SetStringValue( TDeviceParam * Param, const char * Value, bool Force ) inline bool SetStringValue( TDeviceParam * Param, const char * Value, bool Force ) {
{ return SetStringValue( Param, Value, strlen(Value), Force ); }; return SetStringValue( Param, Value, strlen(Value), Force );
};
// Text Interfaces
// Handle Interface Commands
bool GetCmdParam( const char * Start, char * Param, char ** NextParam );
int HandleCommand( const char *ChannelName, const char * Data, const int MaxLen );
// Command Text Interfaces
bool SetValue( TDeviceParam * Param, const char * Value, const int Len, bool Force ); bool SetValue( TDeviceParam * Param, const char * Value, const int Len, bool Force );
bool GetValue( TDeviceParam * Param, char * Value, int &Len ); bool GetValue( TDeviceParam * Param, char * Value, int &Len );
}; };