| #include "tlbmc/store/store_hft_adapter.h" |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/log/log.h" |
| #include "absl/memory/memory.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/match.h" |
| #include "absl/strings/str_join.h" |
| #include "absl/strings/str_split.h" |
| #include "absl/strings/substitute.h" |
| #include "absl/time/time.h" |
| #include "g3/macros.h" |
| #include "identifier.pb.h" |
| #include "payload.pb.h" |
| #include "sensor_identifier.pb.h" |
| #include "sensor_payload.pb.h" |
| #include "subscription_params.pb.h" |
| #include "tlbmc/collector/collector.h" |
| #include "topology_config.pb.h" |
| #include "sensor.pb.h" |
| #include "tlbmc/sensors/sensor.h" |
| #include "tlbmc/store/store.h" |
| #include "tlbmc/time/time.h" |
| |
| namespace milotic_tlbmc { |
| |
| namespace { |
| |
| std::vector<milotic_hft::Identifier> GetSensorIdentifiers(const Store* store) { |
| std::vector<milotic_hft::Identifier> identifiers; |
| for (const std::shared_ptr<const Sensor>& sensor : store->GetAllSensors()) { |
| milotic_hft::Identifier identifier; |
| identifier.mutable_sensor_identifier()->set_name(sensor->GetKey()); |
| identifiers.push_back(identifier); |
| } |
| return identifiers; |
| } |
| |
| absl::Status ConfigureSensors(Store* store, int sampling_interval_ms, |
| const milotic_hft::Identifier& identifier) { |
| return store->ConfigureCollection( |
| {.sampling_interval_ms = sampling_interval_ms, |
| .key = identifier.sensor_identifier().name()}, |
| Collector::Type::kSensor); |
| } |
| |
| absl::StatusOr<milotic_hft::Payload> CollectSensorData( |
| const milotic_hft::SensorIdentifier& sensor_identifier, Store* store, |
| absl::Time start_time) { |
| milotic_hft::Payload payload; |
| milotic_hft::HighFrequencySensorsReadingsBatch* batch = |
| payload.mutable_high_frequency_sensors_readings_batch(); |
| std::shared_ptr<const Sensor> sensor = |
| store->GetSensorBySensorKey(sensor_identifier.name()); |
| if (sensor == nullptr) { |
| return absl::NotFoundError( |
| absl::Substitute("Sensor $0 not found", sensor_identifier.name())); |
| } |
| milotic_hft::HighFrequencySensorsReadings* sensors = |
| batch->add_high_frequency_sensors(); |
| milotic_hft::SensorIdentifier* sensor_identifier_from_readings = |
| sensors->mutable_sensor_identifier(); |
| const SensorAttributesStatic& static_attributes = |
| sensor->GetSensorAttributesStatic(); |
| |
| // Get devpath for the sensor. |
| // 1. Get config name from static attributes. |
| // 2. Get topology node from config name. |
| // 3. Get devpath from topology node. |
| ECCLESIA_ASSIGN_OR_RETURN( |
| const TopologyConfigNode* topology_node, |
| store->GetFruTopology( |
| static_attributes.entity_common_config().board_config_name())); |
| |
| // Replace the local root identifier with /phys when exporting the devpath. |
| const std::string& devpath = topology_node->location_context().devpath(); |
| if (!absl::StartsWith(devpath, "/phys")) { |
| std::vector<std::string> devpath_parts = absl::StrSplit(devpath, '/'); |
| if (devpath_parts.size() < 2) { |
| return absl::InternalError( |
| absl::Substitute("Invalid devpath: $0", devpath)); |
| } |
| devpath_parts[1] = "phys"; |
| sensor_identifier_from_readings->set_devpath( |
| absl::StrJoin(devpath_parts, "/")); |
| } else { |
| sensor_identifier_from_readings->set_devpath(devpath); |
| } |
| sensor_identifier_from_readings->set_name(sensor->GetKey()); |
| sensor_identifier_from_readings->set_source(milotic_hft::SENSOR_SOURCE_BMC); |
| sensor_identifier_from_readings->set_units( |
| ConvertToHftUnit(static_attributes.unit())); |
| for (const auto& sensor_data : |
| sensor->GetSensorDataHistorySince(start_time)) { |
| milotic_hft::HighFrequencySensorReading* reading = |
| sensors->add_timestamped_readings(); |
| reading->set_float_reading(static_cast<float>(sensor_data->reading())); |
| reading->set_timestamp_ns( |
| absl::ToUnixNanos(DecodeGoogleApiProto(sensor_data->timestamp()))); |
| } |
| return payload; |
| } |
| |
| } // namespace |
| |
| milotic_hft::SensorUnits ConvertToHftUnit(SensorUnit unit) { |
| switch (unit) { |
| case UNIT_DEGREE_CELSIUS: |
| return milotic_hft::SENSOR_UNIT_DEGREES; |
| case UNIT_WATT: |
| return milotic_hft::SENSOR_UNIT_WATTS; |
| case UNIT_AMPERE: |
| return milotic_hft::SENSOR_UNIT_AMPS; |
| case UNIT_VOLT: |
| return milotic_hft::SENSOR_UNIT_VOLTS; |
| case UNIT_REVOLUTION_PER_MINUTE: |
| return milotic_hft::SENSOR_UNIT_RPM; |
| case UNIT_PERCENT: |
| return milotic_hft::SENSOR_UNIT_PERCENT; |
| default: |
| return milotic_hft::SENSOR_UNIT_UNSPECIFIED; |
| } |
| } |
| |
| absl::StatusOr<std::unique_ptr<StoreHftAdapter>> StoreHftAdapter::Create( |
| Store* store) { |
| return absl::WrapUnique(new StoreHftAdapter(store)); |
| } |
| |
| absl::Status StoreHftAdapter::ConfigureSamplingInterval( |
| const milotic_hft::Identifier& identifier, int sampling_interval_ms) { |
| LOG(WARNING) << "Configure called for identifier: " << identifier; |
| switch (identifier.identifier_case()) { |
| case milotic_hft::Identifier::kSensorIdentifier: |
| ECCLESIA_RETURN_IF_ERROR( |
| ConfigureSensors(store_, sampling_interval_ms, identifier)); |
| break; |
| // Add support for other telemetry types. |
| default: |
| return absl::InvalidArgumentError(absl::Substitute( |
| "Identifier $0 is not supported", identifier.identifier_case())); |
| } |
| return absl::OkStatus(); |
| } |
| |
| absl::Status StoreHftAdapter::ResetSamplingIntervalToDefault( |
| const milotic_hft::Identifier& identifier) { |
| switch (identifier.identifier_case()) { |
| case milotic_hft::Identifier::kSensorIdentifier: |
| return store_->ConfigureCollection( |
| {.sampling_interval_ms = 0, // Setting 0 resets to default value. |
| .key = identifier.sensor_identifier().name()}, |
| Collector::Type::kSensor); |
| // Add support for other telemetry types. |
| default: |
| return absl::InvalidArgumentError(absl::Substitute( |
| "Identifier $0 is not supported", identifier.identifier_case())); |
| } |
| } |
| |
| absl::StatusOr<milotic_hft::Payload> StoreHftAdapter::Collect( |
| const milotic_hft::Identifier& identifier, absl::Time start_time) const { |
| switch (identifier.identifier_case()) { |
| case milotic_hft::Identifier::kSensorIdentifier: |
| return CollectSensorData(identifier.sensor_identifier(), store_, |
| start_time); |
| // Add support for other telemetry types. |
| default: |
| return absl::InvalidArgumentError("Identifier is not supported"); |
| } |
| } |
| |
| absl::StatusOr<std::vector<milotic_hft::Identifier>> |
| StoreHftAdapter::GetIdentifiersForResourceType( |
| const milotic_hft::SubscriptionPolicy::ResourceType& resource_type) const { |
| switch (resource_type) { |
| case milotic_hft::SubscriptionPolicy::RESOURCE_TYPE_SENSOR: |
| return GetSensorIdentifiers(store_); |
| default: |
| return absl::InvalidArgumentError("Resource type is not supported"); |
| } |
| } |
| |
| absl::Status StoreHftAdapter::ConfigureBatchSize( |
| const milotic_hft::Identifier& identifier, int max_batch_size) { |
| switch (identifier.identifier_case()) { |
| case milotic_hft::Identifier::kSensorIdentifier: |
| return store_->ConfigureCollection( |
| {.max_batch_size = max_batch_size, |
| .key = identifier.sensor_identifier().name()}, |
| Collector::Type::kSensor); |
| // Add support for other telemetry types. |
| default: |
| return absl::InvalidArgumentError(absl::Substitute( |
| "Identifier $0 is not supported", identifier.identifier_case())); |
| } |
| } |
| |
| absl::Status StoreHftAdapter::ResetBatchSizeToDefault( |
| const milotic_hft::Identifier& identifier) { |
| switch (identifier.identifier_case()) { |
| case milotic_hft::Identifier::kSensorIdentifier: |
| return store_->ConfigureCollection( |
| {.max_batch_size = 0, // Setting 0 resets to default value. |
| .key = identifier.sensor_identifier().name()}, |
| Collector::Type::kSensor); |
| // Add support for other telemetry types. |
| default: |
| return absl::InvalidArgumentError(absl::Substitute( |
| "Identifier $0 is not supported", identifier.identifier_case())); |
| } |
| } |
| |
| } // namespace milotic_tlbmc |