blob: 743966b5750270b111e7cd9021f27156fca0f121 [file]
#include "tlbmc/sensors/virtual_sensor.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "g3/macros.h"
#include "sensor_instance_properties.pb.h"
#include "virtual_sensor_config.pb.h"
#include "tlbmc/expression/expression.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/sensor.h"
#include "tlbmc/sensors/sync_polling_sensor.h"
#include "tlbmc/time/time.h"
namespace milotic_tlbmc {
absl::StatusOr<std::shared_ptr<VirtualSensor>> VirtualSensor::Create(
const VirtualSensorConfig& config,
const std::shared_ptr<boost::asio::io_context>& io_context,
const absl::flat_hash_map<std::string, std::shared_ptr<Sensor>>&
sensors_map,
std::unique_ptr<Expression> expression,
std::optional<NotificationCb> on_batch_notify) {
SensorInstanceProperties mutable_instance_properties =
config.instance_properties();
// Populate default related item if not specified.
if (!config.instance_properties().has_related_item()) {
mutable_instance_properties.mutable_related_item()->set_type(
RESOURCE_TYPE_BOARD);
mutable_instance_properties.mutable_related_item()->set_id(
config.entity_common_config().board_config_key());
}
return std::make_shared<VirtualSensor>(
Token(), config.entity_common_config(), mutable_instance_properties,
sensors_map, std::move(expression), io_context, on_batch_notify);
}
VirtualSensor::VirtualSensor(
Token token, const EntityCommonConfig& entity_common_config,
const SensorInstanceProperties& sensor_instance_properties,
const absl::flat_hash_map<std::string, std::shared_ptr<Sensor>>&
sensors_map,
std::unique_ptr<Expression> expression,
const std::shared_ptr<boost::asio::io_context>& io_context,
std::optional<NotificationCb> on_batch_notify)
: SyncPollingSensor(CreateStaticAttributes(sensor_instance_properties,
/*hal_common_config=*/{},
entity_common_config),
sensor_instance_properties.thresholds(), io_context,
on_batch_notify),
sensors_map_(sensors_map),
expression_(std::move(expression)),
sensor_name_(sensor_instance_properties.name()) {}
absl::StatusOr<SensorValue> VirtualSensor::ReadSensorData() {
absl::flat_hash_map<std::string, double> sensor_readings_map;
for (const auto& [sensor_name, sensor] : sensors_map_) {
if (sensor == nullptr) {
return absl::InvalidArgumentError(
absl::StrCat("Sensor ", sensor_name, " is missing"));
}
const std::shared_ptr<const SensorValue> sensor_data =
sensor->GetSensorData();
if (sensor_data == nullptr) {
return absl::InvalidArgumentError(
absl::StrCat("Sensor data for sensor ", sensor_name, " is null"));
}
sensor_readings_map[sensor_name] = sensor_data->reading();
}
ECCLESIA_ASSIGN_OR_RETURN(double value,
expression_->Evaluate(sensor_readings_map));
SensorValue sensor_data;
*sensor_data.mutable_timestamp() = Now();
sensor_data.set_reading(value);
return sensor_data;
}
} // namespace milotic_tlbmc