blob: 6bb10d7598cdf1c76c00393d02f262bbb125c2c3 [file] [log] [blame]
#include "tlbmc/sensors/nic_sensor.h"
#include <chrono> // NOLINT: chrono is commonly used in BMC
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "tlbmc/hal/nic_veeprom/interface.h"
#include "tlbmc/sensors/sensor.h"
namespace milotic_tlbmc {
absl::StatusOr<std::shared_ptr<NicSensor>> NicSensor::Create(
const std::string& sensor_name,
nic_veeprom::NicTelemetryName telemetry_name, SensorUnit sensor_unit,
const EntityCommonConfig& entity_common_config,
const ThresholdConfigs& threshold_configs,
const ReadingRangeConfigs& reading_range_configs,
const std::shared_ptr<boost::asio::io_context>& io_context,
const nic_veeprom::Accessor& accessor,
std::optional<NotificationCb> on_batch_notify) {
return std::make_shared<NicSensor>(Token(), sensor_name, telemetry_name,
sensor_unit, entity_common_config,
threshold_configs, reading_range_configs,
io_context, accessor, on_batch_notify);
}
NicSensor::NicSensor(Token token, const std::string& sensor_name,
nic_veeprom::NicTelemetryName telemetry_name,
SensorUnit sensor_unit,
const EntityCommonConfig& entity_common_config,
const ThresholdConfigs& threshold_configs,
const ReadingRangeConfigs& reading_range_configs,
const std::shared_ptr<boost::asio::io_context>& io_context,
const nic_veeprom::Accessor& accessor,
std::optional<NotificationCb> on_batch_notify)
: Sensor(CreateStaticAttributes(sensor_name, sensor_unit,
/*i2c_common_config=*/{},
entity_common_config, reading_range_configs,
/*reading_transform_config=*/{}),
threshold_configs, on_batch_notify),
telemetry_name_(telemetry_name),
sensor_unit_(sensor_unit),
io_context_(io_context),
accessor_(accessor) {}
void NicSensor::RefreshOnceAsync(
absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
callback) {
std::weak_ptr<NicSensor> self = shared_from_this();
boost::asio::post(*io_context_, [self(std::move(self)),
callback(std::move(callback))]() mutable {
std::shared_ptr<NicSensor> sensor = self.lock();
if (!sensor) {
LOG(WARNING) << "Sensor is destroyed; cancel the refresh.";
return;
}
std::chrono::steady_clock::time_point last_refresh_start_time =
sensor->GetLastRefreshStartTime();
if (last_refresh_start_time !=
std::chrono::steady_clock::time_point::min()) {
sensor->UpdateSoftwarePollingStartMetrics(
std::chrono::steady_clock::now() - last_refresh_start_time);
}
sensor->SetLastRefreshStartTime(std::chrono::steady_clock::now());
// Get the sensor value
absl::StatusOr<const std::shared_ptr<const SensorValue>> sensor_value =
sensor->GetSensorValue();
if (!sensor_value.ok()) {
State state;
state.set_status(STATUS_STALE);
state.set_status_message(
absl::StrCat("Failed to read sensor value with error: ",
sensor_value.status().message()));
sensor->UpdateState(std::move(state));
if (callback) {
callback(sensor->GetSensorData());
}
} else {
sensor->StoreSensorData(*sensor_value);
State state;
state.set_status(STATUS_READY);
sensor->UpdateState(std::move(state));
if (callback) {
callback(sensor->GetSensorData());
}
}
std::chrono::steady_clock::time_point last_refresh_end_time =
sensor->GetLastRefreshEndTime();
if (last_refresh_end_time != std::chrono::steady_clock::time_point::min()) {
sensor->UpdateSoftwarePollingEndMetrics(std::chrono::steady_clock::now() -
last_refresh_end_time);
}
sensor->SetLastRefreshEndTime(std::chrono::steady_clock::now());
});
}
} // namespace milotic_tlbmc