Invoke `SetManualPwm` in fan PWM writing

Google-Bug-Id:555225021,555226212
PiperOrigin-RevId: 975206054
Change-Id: I9a44075ebb6a8781b175d9909b26c2a3f1d7ca9b
diff --git a/tlbmc/sensors/fan_pwm.cc b/tlbmc/sensors/fan_pwm.cc
index ca940b9..3746f49 100644
--- a/tlbmc/sensors/fan_pwm.cc
+++ b/tlbmc/sensors/fan_pwm.cc
@@ -69,7 +69,8 @@
     const FanPwmConfig& config, const FanController& fan_controller,
     const std::shared_ptr<boost::asio::io_context>& io_context,
     const HwmonSysfs& hwmon_sysfs,
-    std::optional<NotificationCb> on_batch_notify) {
+    std::optional<NotificationCb> on_batch_notify,
+    std::optional<SetManualPwmCb> set_manual_pwm) {
   DLOG(INFO) << "Creating fan PWM for device: " << absl::StrCat(config);
   const HalCommonConfig& hal_common_config = config.hal_common_config();
   if (!fan_controller.ControllerHasSensor(hal_common_config)) {
@@ -109,7 +110,7 @@
     std::shared_ptr<FanPwm> fan_pwm = std::make_shared<FanPwm>(
         Token(), config.type(), "", config.hal_common_config(),
         mutable_instance_properties, config.entity_common_config(), io_context,
-        on_batch_notify, hwmon_sysfs);
+        on_batch_notify, hwmon_sysfs, std::move(set_manual_pwm));
     State state;
     // If the sensor is not detected, we set its creation as pending otherwise
     // set it to failed.
@@ -128,7 +129,8 @@
   return std::make_shared<FanPwm>(
       Token(), config.type(), it->second.pwm.string(),
       config.hal_common_config(), mutable_instance_properties,
-      config.entity_common_config(), io_context, on_batch_notify, hwmon_sysfs);
+      config.entity_common_config(), io_context, on_batch_notify, hwmon_sysfs,
+      std::move(set_manual_pwm));
 }
 
 void FanPwm::HandleRefreshResult(const boost::system::error_code& error,
@@ -180,6 +182,9 @@
   if (!file_out.good()) {
     return absl::InternalError(absl::StrCat("Error writing to ", pwm_path));
   }
+  if (set_manual_pwm_.has_value() && *set_manual_pwm_ != nullptr) {
+    (*set_manual_pwm_)(GetKey(), value.reading());
+  }
   // Deliberately no StoreSensorData here: the history buffer must hold only
   // readings observed by the poll (HandleRefreshResult). Subscription batch
   // sizing assumes the poll is the sole producer, so a commanded-value sample
@@ -194,13 +199,15 @@
                const EntityCommonConfig& entity_common_config,
                const std::shared_ptr<boost::asio::io_context>& io_context,
                std::optional<NotificationCb> on_batch_notify,
-               const HwmonSysfs& hwmon_sysfs)
+               const HwmonSysfs& hwmon_sysfs,
+               std::optional<SetManualPwmCb> set_manual_pwm)
     : IXcHwmonBasedSensor(
           input_dev_path, io_context,
           CreateStaticAttributes(sensor_instance_properties, hal_common_config,
                                  entity_common_config),
           sensor_instance_properties.thresholds(), on_batch_notify,
           hwmon_sysfs),
-      sensor_type_(sensor_type) {}
+      sensor_type_(sensor_type),
+      set_manual_pwm_(std::move(set_manual_pwm)) {}
 
 }  // namespace milotic_tlbmc
diff --git a/tlbmc/sensors/fan_pwm.h b/tlbmc/sensors/fan_pwm.h
index e1cde84..e0754e6 100644
--- a/tlbmc/sensors/fan_pwm.h
+++ b/tlbmc/sensors/fan_pwm.h
@@ -2,6 +2,7 @@
 #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_FAN_PWM_H_
 
 #include <cstddef>
+#include <functional>
 #include <memory>
 #include <optional>
 #include <string>
@@ -10,6 +11,7 @@
 #include "absl/base/thread_annotations.h"
 #include "absl/status/status.h"
 #include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
 #include "absl/synchronization/mutex.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
@@ -31,6 +33,8 @@
   class Token;
 
  public:
+  using SetManualPwmCb = std::function<void(absl::string_view, double)>;
+
   // Enables the PWM if not already enabled and returns a sensor that can be
   // used to read the PWM from the device.
   // Note:
@@ -39,7 +43,8 @@
       const FanPwmConfig& config, const FanController& fan_controller,
       const std::shared_ptr<boost::asio::io_context>& io_context,
       const HwmonSysfs& hwmon_sysfs,
-      std::optional<NotificationCb> on_batch_notify = std::nullopt);
+      std::optional<NotificationCb> on_batch_notify = std::nullopt,
+      std::optional<SetManualPwmCb> set_manual_pwm = std::nullopt);
 
   static absl::Status EnablePwm(const boost::filesystem::path& pwm_enable_path);
 
@@ -49,7 +54,8 @@
          const EntityCommonConfig& entity_common_config,
          const std::shared_ptr<boost::asio::io_context>& io_context,
          std::optional<NotificationCb> on_batch_notify,
-         const HwmonSysfs& hwmon_sysfs);
+         const HwmonSysfs& hwmon_sysfs,
+         std::optional<SetManualPwmCb> set_manual_pwm = std::nullopt);
 
   ~FanPwm() override = default;
 
@@ -70,6 +76,7 @@
   };
 
   const FanPwmType sensor_type_ = PWM_SENSOR_TYPE_UNKNOWN;
+  const std::optional<SetManualPwmCb> set_manual_pwm_ = std::nullopt;
 };
 
 }  // namespace milotic_tlbmc