| #ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_ |
| #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_ |
| |
| #include <array> |
| #include <cstddef> |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <string_view> |
| #include <tuple> |
| #include <vector> |
| |
| #include "absl/base/thread_annotations.h" |
| #include "absl/status/statusor.h" |
| #include "boost/asio.hpp" //NOLINT: boost::asio is commonly used in BMC |
| #include "boost/circular_buffer.hpp" //NOLINT: boost is commonly used in BMC |
| #include "entity_common_config.pb.h" |
| #include "i2c_common_config.pb.h" |
| #include "psu_sensor_config.pb.h" |
| #include "reading_range_config.pb.h" |
| #include "reading_transform_config.pb.h" |
| #include "threshold_config.pb.h" |
| #include "tlbmc/hal/sysfs/i2c.h" |
| #include "sensor.pb.h" |
| #include "tlbmc/sensors/i2c_hwmon_based_sensor.h" |
| #include "tlbmc/sensors/sensor.h" |
| |
| namespace milotic_tlbmc { |
| |
| constexpr std::string_view kLabelSuffix = "_label"; |
| |
| /* |
| The following is the framework for adding different types of PSU sensors. |
| To add a new sensor type please do the following: |
| 1. Add the new sensor type to the PsuSensorType enum below |
| 2. Add the new sensor type to the kDefaultPsuSensorProperties array in |
| psu_sensor.cc. |
| 3. Add the new sensor file suffix to the kPsuSensorFileSuffixes array below |
| 4. Add the new sensor label prefix to the kPsuSensorFilePrefixes array below |
| |
| Example: |
| The peak power input file is found with a file that has the suffix |
| "_input_highest". In the EM config file, we attach the prefix "highest" to the |
| label to expose that sensor. |
| */ |
| |
| enum class PsuSensorFileType : uint8_t { |
| kDefault = 0, // This is the default [sensor]_input file. |
| kHighestPower, // Power sensors have a special file for highest power: |
| // [power]_input_highest. |
| kUnknown, // Non-standard sensor file. |
| }; |
| |
| constexpr std::array<std::string_view, |
| static_cast<size_t>(PsuSensorFileType::kUnknown)> |
| kPsuSensorFileSuffixes = {"_input", "_input_highest"}; |
| |
| constexpr std::array<std::string_view, |
| static_cast<size_t>(PsuSensorFileType::kUnknown)> |
| kPsuSensorLabelPrefixes = {"", "highest"}; |
| |
| struct PsuSensorFileInfo { |
| std::string file_prefix; |
| PsuSensorFileType file_type; |
| }; |
| |
| class PsuSensor : public I2cHwmonBasedSensor { |
| private: |
| class Token; |
| |
| public: |
| struct ReadingProperties { |
| std::string_view label_type_name; |
| double max_reading; |
| double min_reading; |
| double scale; |
| double offset; |
| SensorUnit sensor_unit; |
| |
| bool operator==(const ReadingProperties& other) const { |
| return std::tie(max_reading, min_reading, scale, offset, sensor_unit) == |
| std::tie(other.max_reading, other.min_reading, other.scale, |
| other.offset, sensor_unit); |
| } |
| }; |
| // Load the device if not already loaded and returns a list of sensors that |
| // can be used to read the temperature from the device. Note: |
| // 1. The `io_context` must run only on a single thread. |
| static absl::StatusOr<std::vector<std::shared_ptr<Sensor>>> Create( |
| const PsuSensorConfig& config, |
| const std::shared_ptr<boost::asio::io_context>& io_context, |
| const I2cSysfs& i2c_sysfs, |
| std::optional<NotificationCb> on_batch_notify = std::nullopt); |
| |
| PsuSensor(Token token, PsuSensorType sensor_type, SensorUnit sensor_unit, |
| const std::string& input_dev_path, const std::string& sensor_name, |
| const I2cCommonConfig& i2c_common_config, |
| const ThresholdConfigs& threshold_configs, |
| const ReadingRangeConfigs& reading_range_configs, |
| const ReadingTransformConfig& reading_transform_config, |
| const EntityCommonConfig& entity_common_config, |
| const std::shared_ptr<boost::asio::io_context>& io_context, |
| std::optional<NotificationCb> on_batch_notify); |
| |
| ~PsuSensor() override = default; |
| |
| void HandleRefreshResult(const boost::system::error_code& error, |
| size_t bytes_read) override |
| ABSL_LOCKS_EXCLUDED(sensor_data_mutex_); |
| |
| protected: |
| PsuSensor() = default; |
| |
| // Returns the driver name for the given sensor type. |
| static absl::StatusOr<std::string_view> GetDriverName( |
| PsuSensorType sensor_type); |
| |
| // Given the config and the properties of the sensor, returns the reading |
| // range configs. |
| static absl::StatusOr<ReadingRangeConfigs> GetReadingRangeConfigs( |
| const ReadingRangeConfigs& configs, const ReadingProperties& properties); |
| |
| // Given a label with digits (e.g., "vout1"), returns the default reading |
| // properties of the sensor. |
| static absl::StatusOr<ReadingProperties> GetPsuSensorProperties( |
| std::string_view label); |
| |
| // Given an label, returns the unit of the sensor. |
| static absl::StatusOr<SensorUnit> GetSensorUnit(std::string_view label); |
| |
| static std::string ApplyLabelModifications(std::string_view label, |
| PsuSensorFileType file_type); |
| |
| static absl::StatusOr<std::string> ParseLabelFile( |
| const boost::filesystem::path& hwmon_path, std::string_view file_prefix); |
| |
| // Given a sensor name, performs the transformation to append sensor unit and |
| // create a unique name for the sensor. |
| static std::string GetPsuSensorKey(std::string_view name, |
| const PsuSensorConfig& config, |
| PsuSensor::ReadingProperties properties); |
| |
| // Get the contents of the label of the sensor. |
| static std::string GetLabel(const boost::filesystem::path& hwmon_path, |
| std::string_view file_prefix, |
| PsuSensorFileType file_type); |
| |
| static PsuSensorFileInfo GetPsuSensorFileInfo(std::string_view input_file); |
| |
| private: |
| class Token { |
| private: |
| explicit Token() = default; |
| friend PsuSensor; |
| }; |
| |
| const PsuSensorType sensor_type_ = PSU_SENSOR_TYPE0_UNKNOWN; |
| const std::string sensor_name_; |
| const std::string board_config_name_; |
| }; |
| |
| } // namespace milotic_tlbmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_ |