C++ Support Classes¶
A number of support classes exist within the common library that forms part of every Flir plugin.
Reading¶
The Reading class and the associated Datapoint and DatapointValue classes provide the mechanism within C++ classes to manipulated the reading asset data. The public part of the Reading class is currently defined as follows;
class Reading {
public:
Reading(const std::string& asset, Datapoint *value);
Reading(const std::string& asset, std::vector<Datapoint *> values);
Reading(const std::string& asset, std::vector<Datapoint *> values, const std::string& ts);
Reading(const Reading& orig);
~Reading();
void addDatapoint(Datapoint *value);
Datapoint *removeDatapoint(const std::string& name);
std::string toJSON(bool minimal = false) const;
std::string getDatapointsJSON() const;
// Return AssetName
const std::string& getAssetName() const { return m_asset; };
// Set AssetName
void setAssetName(std::string assetName) { m_asset = assetName; };
unsigned int getDatapointCount() { return m_values.size(); };
void removeAllDatapoints();
// Return Reading datapoints
const std::vector<Datapoint *> getReadingData() const { return m_values; };
// Return reference to Reading datapoints
std::vector<Datapoint *>& getReadingData() { return m_values; };
unsigned long getId() const { return m_id; };
unsigned long getTimestamp() const { return (unsigned long)m_timestamp.tv_sec; };
unsigned long getUserTimestamp() const { return (unsigned long)m_userTimestamp.tv_sec; };
void setId(unsigned long id) { m_id = id; };
void setTimestamp(unsigned long ts) { m_timestamp.tv_sec = (time_t)ts; };
void setTimestamp(struct timeval tm) { m_timestamp = tm; };
void setTimestamp(const std::string& timestamp);
void getTimestamp(struct timeval *tm) { *tm = m_timestamp; };
void setUserTimestamp(unsigned long uTs) { m_userTimestamp.tv_sec = (time_t)uTs; };
void setUserTimestamp(struct timeval tm) { m_userTimestamp = tm; };
void setUserTimestamp(const std::string& timestamp);
void getUserTimestamp(struct timeval *tm) { *tm = m_userTimestamp; };
typedef enum dateTimeFormat { FMT_DEFAULT, FMT_STANDARD, FMT_ISO8601 } readingTimeFormat;
// Return Reading asset time - ts time
const std::string getAssetDateTime(readingTimeFormat datetimeFmt = FMT_DEFAULT, bool addMs = true) const;
// Return Reading asset time - user_ts time
const std::string getAssetDateUserTime(readingTimeFormat datetimeFmt = FMT_DEFAULT, bool addMs = true) const;
}
The Reading class contains a number of items that are mapped to the JSON representation of data that is sent to the Flir storage service and are used by the various services and plugins within Flir.
Asset Name: The name of the asset. The asset name is set in the constructor of the reading and retrieved via the getAssetName() method.
Timestamp: The timestamp when the reading was first seen within Flir.
User Timestamp: The timestamp for the actual data in the reading. This may differ from the value of Timestamp if the device itself is able to supply a timestamp value.
Datapoints: The actual data of a reading stored in a Datapoint class.
The Datapoint class provides a name for each data point within a Reading and the tagged type data for the reading value. The public definition of the Datapoint class is as follows;
class Datapoint {
public:
/**
* Construct with a data point value
*/
Datapoint(const std::string& name, DatapointValue& value) : m_name(name), m_value(value);
~Datapoint();
/**
* Return asset reading data point as a JSON
* property that can be included within a JSON
* document.
*/
std::string toJSONProperty();
const std::string getName() const;
void setName(std::string name);
const DatapointValue getData() const;
DatapointValue& getData();
}
Closely associated with the Datapoint is the DatapointValue which uses a tagged union to store the values. The public definition of the DatapointValue is as follows;
class DatapointValue {
public:
/**
* Construct with a string
*/
DatapointValue(const std::string& value)
{
m_value.str = new std::string(value);
m_type = T_STRING;
};
/**
* Construct with an integer value
*/
DatapointValue(const long value)
{
m_value.i = value;
m_type = T_INTEGER;
};
/**
* Construct with a floating point value
*/
DatapointValue(const double value)
{
m_value.f = value;
m_type = T_FLOAT;
};
/**
* Construct with an array of floating point values
*/
DatapointValue(const std::vector<double>& values)
{
m_value.a = new std::vector<double>(values);
m_type = T_FLOAT_ARRAY;
};
/**
* Construct with an array of Datapoints
*/
DatapointValue(std::vector<Datapoint*>*& values, bool isDict)
{
m_value.dpa = values;
m_type = isDict? T_DP_DICT : T_DP_LIST;
}
/**
* Construct with an Image
*/
DatapointValue(const DPImage& value)
{
m_value.image = new DPImage(value);
m_type = T_IMAGE;
}
/**
* Construct with a DataBuffer
*/
DatapointValue(const DataBuffer& value)
{
m_value.dataBuffer = new DataBuffer(value);
m_type = T_DATABUFFER;
}
/**
* Construct with an Image Pointer, the
* image becomes owned by the datapointValue
*/
DatapointValue(DPImage *value)
{
m_value.image = value;
m_type = T_IMAGE;
}
/**
* Construct with a DataBuffer
*/
DatapointValue(DataBuffer *value)
{
m_value.dataBuffer = value;
m_type = T_DATABUFFER;
}
/**
* Construct with a 2 dimensional array of floating point values
*/
DatapointValue(const std::vector< std::vector<double> >& values)
{
m_value.a2d = new std::vector< std::vector<double> >();
for (auto row : values)
{
m_value.a2d->push_back(std::vector<double>(row));
}
m_type = T_2D_FLOAT_ARRAY;
};
/**
* Copy constructor
*/
DatapointValue(const DatapointValue& obj);
/**
* Assignment Operator
*/
DatapointValue& operator=(const DatapointValue& rhs);
/**
* Destructor
*/
~DatapointValue();
/**
* Set the value of a datapoint, this may
* also cause the type to be changed.
* @param value An integer value to set
*/
void setValue(long value)
{
m_value.i = value;
m_type = T_INTEGER;
}
/**
* Set the value of a datapoint, this may
* also cause the type to be changed.
* @param value A floating point value to set
*/
void setValue(double value)
{
m_value.f = value;
m_type = T_FLOAT;
}
/** Set the value of a datapoint to be an image
* @param value The image to set in the data point
*/
void setValue(const DPImage& value)
{
m_value.image = new DPImage(value);
m_type = T_IMAGE;
}
/**
* Return the value as a string
*/
std::string toString() const;
/**
* Return string value without trailing/leading quotes
*/
std::string toStringValue() const { return *m_value.str; };
/**
* Return long value
*/
long toInt() const { return m_value.i; };
/**
* Return double value
*/
double toDouble() const { return m_value.f; };
// Supported Data Tag Types
typedef enum DatapointTag
{
T_STRING,
T_INTEGER,
T_FLOAT,
T_FLOAT_ARRAY,
T_DP_DICT,
T_DP_LIST,
T_IMAGE,
T_DATABUFFER,
T_2D_FLOAT_ARRAY
} dataTagType;
/**
* Return the Tag type
*/
dataTagType getType() const
{
return m_type;
}
std::string getTypeStr() const
{
switch(m_type)
{
case T_STRING: return std::string("STRING");
case T_INTEGER: return std::string("INTEGER");
case T_FLOAT: return std::string("FLOAT");
case T_FLOAT_ARRAY: return std::string("FLOAT_ARRAY");
case T_DP_DICT: return std::string("DP_DICT");
case T_DP_LIST: return std::string("DP_LIST");
case T_IMAGE: return std::string("IMAGE");
case T_DATABUFFER: return std::string("DATABUFFER");
case T_2D_FLOAT_ARRAY: return std::string("2D_FLOAT_ARRAY");
default: return std::string("INVALID");
}
}
/**
* Return array of datapoints
*/
std::vector<Datapoint*>*& getDpVec()
{
return m_value.dpa;
}
/**
* Return array of float
*/
std::vector<double>*& getDpArr()
{
return m_value.a;
}
/**
* Return 2D array of float
*/
std::vector<std::vector<double> >*& getDp2DArr()
{
return m_value.a2d;
}
/**
* Return the Image
*/
DPImage *getImage()
{
return m_value.image;
}
/**
* Return the DataBuffer
*/
DataBuffer *getDataBuffer()
{
return m_value.dataBuffer;
}
};
The DatapointValue can store data in as a number of types
Type
C++ Representation
T_STRING
Pointer to std::string
T_INTEGER
long
T_FLOAT
double
T_FLOAT_ARRAY
Pointer to std::vector<double>
T_2D_FLOAT_ARRAY
Pointer to std::vector<std::vector<double>>
T_DP_DICT
Pointer to std::vector<Datapoint *>
T_DP_LIST
Pointer to std::vector<Datapoint *>
T_IMAGE
Pointer to DPImage
T_DATABUFFER
Pointer to DataBuffer
Configuration Category¶
The ConfigCategory class is a support class for managing configuration information within a plugin and is passed to the plugin entry points. The public definition of the class is as follows;
class ConfigCategory {
public:
enum ItemType {
UnknownType,
StringItem,
EnumerationItem,
JsonItem,
BoolItem,
NumberItem,
DoubleItem,
ScriptItem,
CategoryType,
CodeItem
};
ConfigCategory(const std::string& name, const std::string& json);
ConfigCategory() {};
ConfigCategory(const ConfigCategory& orig);
~ConfigCategory();
void addItem(const std::string& name, const std::string description,
const std::string& type, const std::string def,
const std::string& value);
void addItem(const std::string& name, const std::string description,
const std::string def, const std::string& value,
const std::vector<std::string> options);
void removeItems();
void removeItemsType(ItemType type);
void keepItemsType(ItemType type);
bool extractSubcategory(ConfigCategory &subCategories);
void setDescription(const std::string& description);
std::string getName() const;
std::string getDescription() const;
unsigned int getCount() const;
bool itemExists(const std::string& name) const;
bool setItemDisplayName(const std::string& name, const std::string& displayName);
std::string getValue(const std::string& name) const;
std::string getType(const std::string& name) const;
std::string getDescription(const std::string& name) const;
std::string getDefault(const std::string& name) const;
bool setDefault(const std::string& name, const std::string& value);
std::string getDisplayName(const std::string& name) const;
std::vector<std::string> getOptions(const std::string& name) const;
std::string getLength(const std::string& name) const;
std::string getMinimum(const std::string& name) const;
std::string getMaximum(const std::string& name) const;
bool isString(const std::string& name) const;
bool isEnumeration(const std::string& name) const;
bool isJSON(const std::string& name) const;
bool isBool(const std::string& name) const;
bool isNumber(const std::string& name) const;
bool isDouble(const std::string& name) const;
bool isDeprecated(const std::string& name) const;
std::string toJSON(const bool full=false) const;
std::string itemsToJSON(const bool full=false) const;
ConfigCategory& operator=(ConfigCategory const& rhs);
ConfigCategory& operator+=(ConfigCategory const& rhs);
void setItemsValueFromDefault();
void checkDefaultValuesOnly() const;
std::string itemToJSON(const std::string& itemName) const;
enum ItemAttribute { ORDER_ATTR, READONLY_ATTR, MANDATORY_ATTR, FILE_ATTR};
std::string getItemAttribute(const std::string& itemName,
ItemAttribute itemAttribute) const;
}
Although ConfigCategory is a complex class, only a few of the methods are commonly used within a plugin
itemExists: - used to test if an expected configuration item exists within the configuration category.
getValue: - return the value of a configuration item from within the configuration category
isBool: - tests if a configuration item is of boolean type
isNumber: - tests if a configuration item is a number
isDouble: - tests if a configuration item is valid to be represented as a double
isString: - tests if a configuration item is a string
Logger¶
The Logger class is used to write entries to the syslog system within Flir. A singleton Logger exists which can be obtained using the following code snippet;
Logger *logger = Logger::getLogger();
logger->error("An error has occurred within the plugin processing");
It is then possible to log messages at one of five different log levels; debug, info, warn, error or fatal. Messages may be logged using standard printf formatting strings. The public definition of the Logger class is as follows;
class Logger {
public:
Logger(const std::string& application);
~Logger();
static Logger *getLogger();
void debug(const std::string& msg, ...);
void printLongString(const std::string&);
void info(const std::string& msg, ...);
void warn(const std::string& msg, ...);
void error(const std::string& msg, ...);
void fatal(const std::string& msg, ...);
void setMinLevel(const std::string& level);
};
The various log levels should be used as follows;
debug: should be used to output messages that are relevant only to a programmer that is debugging the plugin.
info: should be used for information that is meaningful to the end users, but should not normally be logged.
warn: should be used for warning messages that will normally be logged but reflect a condition that does not prevent the plugin from operating.
error: should be used for conditions that cause a temporary failure in processing within the plugin.
fatal: should be used for conditions that cause the plugin to fail processing permanently, possibly requiring a restart of the microservice in order to resolve.