Power cap fixes required for the 5.0 kernel

The OCC device driver changed in the 5.0 kernel which requires
2 user space changes when setting the OCC user power cap:

1) The file name to write to changed to powerX_cap_user, where
   X is some number.
2) The value changed to microWatts, from Watts.

This commit uses a regular expression to find the filename.  An
alternative method would have been to find the X value by finding
which powerX_label file contained the word 'system'.

Tested: Ran the ipmitool dcmi commands to set and activate the
        power cap.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I4f086b2d80944c3bd0ebc627e4df92935d27a5a3
diff --git a/powercap.cpp b/powercap.cpp
index 638d5fe..5466ccf 100644
--- a/powercap.cpp
+++ b/powercap.cpp
@@ -1,6 +1,7 @@
 #include <cassert>
 #include <phosphor-logging/log.hpp>
 #include <powercap.hpp>
+#include <regex>
 
 namespace open_power
 {
@@ -20,6 +21,7 @@
 constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
 
 using namespace phosphor::logging;
+namespace fs = std::filesystem;
 
 std::string PowerCap::getService(std::string path, std::string interface)
 {
@@ -108,6 +110,19 @@
     return sdbusplus::message::variant_ns::get<bool>(pcapEnabled);
 }
 
+std::string PowerCap::getPcapFilename(const fs::path& path)
+{
+    std::regex expr{"power\\d+_cap_user$"};
+    for (auto& file : fs::directory_iterator(path))
+    {
+        if (std::regex_search(file.path().string(), expr))
+        {
+            return file.path().filename();
+        }
+    }
+    return std::string{};
+}
+
 void PowerCap::writeOcc(uint32_t pcapValue)
 {
     // Create path out to master occ hwmon entry
@@ -122,9 +137,19 @@
     // Now set our path to this full path, including this hwmonXX directory
     fileName = std::make_unique<fs::path>(*fs::directory_iterator(*fileName));
     // Append on the hwmon string where we write the user power cap
-    *fileName /= "/caps1_user";
 
-    auto pcapString{std::to_string(pcapValue)};
+    auto baseName = getPcapFilename(*fileName);
+    if (baseName.empty())
+    {
+        log<level::ERR>("Could not find a power cap file to write to",
+                        entry("PATH=%s", *fileName->c_str()));
+        return;
+    }
+    *fileName /= baseName;
+
+    uint64_t microWatts = pcapValue * 1000000ull;
+
+    auto pcapString{std::to_string(microWatts)};
 
     log<level::INFO>("Writing pcap value to hwmon",
                      entry("PCAP_PATH=%s", fileName->c_str()),