Commit ab3b17e3 authored by Alessio Netti's avatar Alessio Netti
Browse files

Analytics: sink units

- Allowing users to define analyzers with inputs but no outputs
- In this case, a "sink" unit is created, which always refers to the
root of the sensor tree
- This is useful for control analyzers that tune system knobs but do
not actively produce sensor data
parent 8ea5658d
......@@ -67,4 +67,10 @@ void JobAggregatorConfigurator::analyzer(JobAggregatorAnalyzer& a, CFG_VAL confi
}
}
bool JobAggregatorConfigurator::unit(UnitTemplate<AggregatorSensorBase>& u) { return true; }
\ No newline at end of file
bool JobAggregatorConfigurator::unit(UnitTemplate<AggregatorSensorBase>& u) {
if(u.getOutputs().empty()) {
LOG(error) << _analyzerName << ": At least one output sensor per unit must be defined!";
return false;
}
return true;
}
\ No newline at end of file
......@@ -509,6 +509,9 @@ protected:
*/
virtual bool readUnits(Analyzer& an, std::vector<shared_ptr<SBase>>& protoInputs, std::vector<shared_ptr<SBase>>& protoOutputs, inputMode_t inputMode) {
vector <shared_ptr<UnitTemplate<SBase>>> *units = NULL;
if(protoOutputs.empty())
LOG(debug) << " No output specified, generating sink unit.";
try {
units = _unitGen.generateUnits(protoInputs, protoOutputs, inputMode, an.getMqttPart(), !an.getStreaming(), an.getRelaxed());
}
......
......@@ -183,17 +183,17 @@ public:
vector<shared_ptr<UnitTemplate<SBase>>> *generateUnits(vector<shared_ptr<SBase>>& inputs, vector<shared_ptr<SBase>>& outputs,
inputMode_t inputMode, string mqttPrefix="", bool ondemand=false, bool relaxed=false) {
// If no outputs are defined, no units can be instantiated
if((inputs.empty() && inputMode==SELECTIVE) || outputs.empty())
throw invalid_argument("UnitGenerator: Invalid inputs or outputs!");
// If no inputs are defined, no units can be instantiated
if(inputs.empty() && inputMode==SELECTIVE)
throw invalid_argument("UnitGenerator: Invalid inputs!");
// Output sensors must share the same unit pattern
if(!isConsistent(outputs))
if(!outputs.empty() && !isConsistent(outputs))
throw invalid_argument("UnitGenerator: Incoherent output levels!");
// We iterate over the outputs, and compute their depth level in the current sensor tree. From such depth level,
// the list of units is defined, consisting in all nodes in the sensor tree at the level of the outputs
int unitLevel = parseNodeLevelString(outputs[0]->getName());
int unitLevel = outputs.empty() ? -1 : parseNodeLevelString(outputs[0]->getName());
set<string>* units = NULL;
if(unitLevel > -1)
units = resolveNodeLevelString(outputs[0]->getName(), SensorNavigator::rootKey, false);
......@@ -250,16 +250,16 @@ public:
shared_ptr<UnitTemplate<SBase>> generateUnit(const string& u, vector<shared_ptr<SBase>>& inputs, vector<shared_ptr<SBase>>& outputs,
inputMode_t inputMode, string mqttPrefix="", bool relaxed=false) {
// If no outputs are defined, no units can be instantiated
if((inputs.size()==0 && inputMode==SELECTIVE) || outputs.size() == 0)
throw invalid_argument("UnitGenerator: Invalid inputs or outputs!");
// If no inputs are defined, no units can be instantiated
if(inputs.size()==0 && inputMode==SELECTIVE)
throw invalid_argument("UnitGenerator: Invalid inputs!");
// Output sensors must share the same unit pattern
if(!isConsistent(outputs))
if(!outputs.empty() && !isConsistent(outputs))
throw invalid_argument("UnitGenerator: Incoherent output levels!");
// The unit specified as input must belong to the domain of the outputs
if(!nodeBelongsToPattern(u, outputs[0]->getName()))
if(!nodeBelongsToPattern(u, outputs.empty() ? SensorNavigator::rootKey : outputs[0]->getName()))
throw domain_error("UnitGenerator: Node " + u + " does not belong to this unit domain!");
return _generateUnit(u, inputs, outputs, inputMode, mqttPrefix, relaxed);
......@@ -288,7 +288,7 @@ public:
vector<shared_ptr<SBase>>& outputs, vector<shared_ptr<SBase>>& subInputs, vector<shared_ptr<SBase>>& subOutputs,
inputMode_t inputMode, string mqttPrefix="", bool relaxed=false) {
// If no outputs are defined, no units can be instantiated
// If no inputs or outputs are defined, no units can be instantiated
if((subInputs.size()==0 && inputMode==SELECTIVE) || subOutputs.size()==0)
throw invalid_argument("HiUnitGenerator: Invalid inputs or outputs!");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment