Add SMBPBI sensor
This sensor implementation polls readings from a virtual
eeprom i2c device. It can be used to read telemetry and
expose readings on dbus.
Entity Manager configs:
{
"Address": "0x1f",
"Bus": 1,
"ReadOffset": 288,
"Units": "DegreesC",
"Name": "Example_0_Temp_0",
"PollRate": 1.0,
"MinValue": -128,
"MaxValue": 127,
"Thresholds": [
{
"Direction": "greater than",
"Name": "upper non critical",
"Severity": 0,
"Value": 90.0
}
],
"ValueType": "UINT64",
"Type": "SmbpbiVirtualEeprom"
}
Change-Id: I13a5a82b583a31dd57feb7b3e6929e2a469d4b6d
Signed-off-by: Aushim Nagarkatti <anagarkatti@nvidia.com>
diff --git a/src/smbpbi/SmbpbiSensor.hpp b/src/smbpbi/SmbpbiSensor.hpp
new file mode 100644
index 0000000..c869ce3
--- /dev/null
+++ b/src/smbpbi/SmbpbiSensor.hpp
@@ -0,0 +1,89 @@
+/*
+ * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION &
+ * AFFILIATES. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+#include "Thresholds.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/random_access_file.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sensor.hpp>
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+constexpr std::array<size_t, 3> i2CReadLenValues = {4, 8, 8};
+
+enum class I2C_READ_LEN_INDEX
+{
+ FLOAT32,
+ FLOAT64,
+ UINT64
+};
+
+struct SmbpbiSensor : public Sensor
+{
+ SmbpbiSensor(
+ std::shared_ptr<sdbusplus::asio::connection>& conn,
+ boost::asio::io_context& io, const std::string& name,
+ const std::string& sensorConfiguration, const std::string& objType,
+ sdbusplus::asio::object_server& objectServer,
+ std::vector<thresholds::Threshold>&& thresholdData, uint8_t busId,
+ uint8_t addr, uint16_t offset, std::string& sensorUnits,
+ std::string& valueType, size_t pollTime, double minVal, double maxVal,
+ std::string& path);
+ ~SmbpbiSensor() override;
+
+ void checkThresholds() override;
+
+ size_t getPollRate() const
+ {
+ return pollRateSecond;
+ }
+ void read();
+ void init();
+
+ uint8_t busId;
+ uint8_t addr;
+ uint16_t offset;
+ std::string sensorUnits;
+ std::string sensorType;
+ std::string valueType;
+
+ private:
+ int i2cReadDataBytes(uint8_t* reading, int length);
+ int i2cReadDataBytesDouble(double& reading);
+ int i2cReadDataBytesUI64(uint64_t& reading);
+ int readRawEEPROMData(double& data);
+ int readFloat64EEPROMData(double& data);
+ static double convert2Temp(const uint8_t* rawData);
+ static double convert2Power(const uint8_t* rawData);
+ void waitReadCallback(const boost::system::error_code& ec);
+ sdbusplus::asio::object_server& objectServer;
+ boost::asio::random_access_file inputDev;
+ boost::asio::steady_timer waitTimer;
+ size_t pollRateSecond;
+};
+
+bool checkInvalidReading(uint8_t* reading, int length)
+{
+ // there is no value updated from HMC if reading data is all 0xff
+ uint8_t* ptr = reading;
+ for (int i = 0; i < length; i++, ptr++)
+ {
+ if (*ptr != 0xFF)
+ {
+ return false;
+ }
+ }
+ return true;
+}