blob: 493fe32ad989630e5a2a95d7ae9ed07bdc15b0b8 [file] [log] [blame]
#include "trigger_factory.hpp"
#include "discrete_threshold.hpp"
#include "numeric_threshold.hpp"
#include "on_change_threshold.hpp"
#include "sensor.hpp"
#include "trigger.hpp"
#include "trigger_actions.hpp"
#include "utils/dbus_mapper.hpp"
#include "utils/transform.hpp"
namespace ts = utils::tstring;
TriggerFactory::TriggerFactory(
std::shared_ptr<sdbusplus::asio::connection> bus,
std::shared_ptr<sdbusplus::asio::object_server> objServer,
SensorCache& sensorCache, interfaces::ReportManager& reportManager) :
bus(std::move(bus)),
objServer(std::move(objServer)), sensorCache(sensorCache),
reportManager(reportManager)
{}
std::unique_ptr<interfaces::Trigger> TriggerFactory::make(
const std::string& id, const std::string& name,
const std::vector<std::string>& triggerActionsIn,
const std::vector<std::string>& reportIds,
interfaces::TriggerManager& triggerManager,
interfaces::JsonStorage& triggerStorage,
const LabeledTriggerThresholdParams& labeledThresholdParams,
const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
{
const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo);
std::vector<TriggerAction> triggerActions;
std::transform(triggerActionsIn.begin(), triggerActionsIn.end(),
std::back_inserter(triggerActions),
[](const auto& triggerActionStr) {
return toTriggerAction(triggerActionStr);
});
std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
if (isTriggerThresholdDiscrete(labeledThresholdParams))
{
const auto& labeledDiscreteThresholdParams =
std::get<std::vector<discrete::LabeledThresholdParam>>(
labeledThresholdParams);
for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams)
{
std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
std::string thresholdName =
labeledThresholdParam.at_label<ts::UserId>();
discrete::Severity severity =
labeledThresholdParam.at_label<ts::Severity>();
auto dwellTime =
Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>());
std::string thresholdValue =
labeledThresholdParam.at_label<ts::ThresholdValue>();
action::discrete::fillActions(actions, triggerActions, severity,
reportManager, reportIds);
thresholds.emplace_back(std::make_shared<DiscreteThreshold>(
bus->get_io_context(), sensors, sensorNames, std::move(actions),
Milliseconds(dwellTime), std::stod(thresholdValue),
thresholdName));
}
if (labeledDiscreteThresholdParams.empty())
{
std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
action::discrete::onChange::fillActions(actions, triggerActions,
reportManager, reportIds);
thresholds.emplace_back(std::make_shared<OnChangeThreshold>(
sensors, sensorNames, std::move(actions)));
}
}
else
{
const auto& labeledNumericThresholdParams =
std::get<std::vector<numeric::LabeledThresholdParam>>(
labeledThresholdParams);
for (const auto& labeledThresholdParam : labeledNumericThresholdParams)
{
std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
auto type = labeledThresholdParam.at_label<ts::Type>();
auto dwellTime =
Milliseconds(labeledThresholdParam.at_label<ts::DwellTime>());
auto direction = labeledThresholdParam.at_label<ts::Direction>();
auto thresholdValue =
double{labeledThresholdParam.at_label<ts::ThresholdValue>()};
action::numeric::fillActions(actions, triggerActions, type,
thresholdValue, reportManager,
reportIds);
thresholds.emplace_back(std::make_shared<NumericThreshold>(
bus->get_io_context(), sensors, sensorNames, std::move(actions),
dwellTime, direction, thresholdValue));
}
}
return std::make_unique<Trigger>(
bus->get_io_context(), objServer, id, name, triggerActionsIn, reportIds,
labeledSensorsInfo, labeledThresholdParams, std::move(thresholds),
triggerManager, triggerStorage);
}
std::pair<Sensors, std::vector<std::string>> TriggerFactory::getSensors(
const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
{
Sensors sensors;
std::vector<std::string> sensorNames;
for (const auto& labeledSensorInfo : labeledSensorsInfo)
{
const auto& service = labeledSensorInfo.at_label<ts::Service>();
const auto& sensorPath = labeledSensorInfo.at_label<ts::SensorPath>();
const auto& metadata = labeledSensorInfo.at_label<ts::Metadata>();
sensors.emplace_back(sensorCache.makeSensor<Sensor>(
service, sensorPath, metadata, bus->get_io_context(), bus));
if (metadata.empty())
{
sensorNames.emplace_back(sensorPath);
}
else
{
sensorNames.emplace_back(metadata);
}
}
return {sensors, sensorNames};
}
std::vector<LabeledSensorInfo>
TriggerFactory::getLabeledSensorsInfo(boost::asio::yield_context& yield,
const SensorsInfo& sensorsInfo) const
{
auto tree = utils::getSubTreeSensors(yield, bus);
return utils::transform(sensorsInfo, [&tree](const auto& item) {
const auto& [sensorPath, metadata] = item;
auto found = std::find_if(
tree.begin(), tree.end(),
[path = sensorPath](const auto& x) { return x.first == path; });
if (tree.end() != found)
{
const auto& [service, ifaces] = found->second.front();
return LabeledSensorInfo(service, sensorPath, metadata);
}
throw std::runtime_error("Not found");
});
}