| #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 |