detect fan type by matching against 'compatible'

Switches fan-type detection to key off well-known 'compatible' strings,
as documented
@ https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/hwmon/

Change was created in response to the comment:
"I'd much prefer we query compatible attribute through the
of_node symlink" as discussed with Andrew J. and Ed T. in the
gerrit review
@ https://gerrit.openbmc.org/c/openbmc/dbus-sensors/+/58458

Tested: confirmed fans appear in WebUI only when
valid 'compatible' strings are found

Change-Id: Ifae4abc64288e84023c045fc8b2c7a4f0d1b8498
Signed-off-by: Chris Sides <christopher.sides@hpe.com>
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 5042fb6..6dccee5 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -64,17 +64,35 @@
 
 FanTypes getFanType(const fs::path& parentPath)
 {
-    fs::path linkPath = parentPath / "device";
-    std::string canonical = fs::read_symlink(linkPath);
-    if (canonical.ends_with("pwm-tacho-controller") ||
-        canonical.ends_with("pwm_tach:tach"))
+    fs::path linkPath = parentPath / "of_node";
+    std::string canonical = fs::canonical(linkPath);
+
+    std::string compatiblePath = canonical + "/compatible";
+    std::ifstream compatibleStream(compatiblePath);
+
+    if (!compatibleStream.is_open())
     {
-        return FanTypes::aspeed;
+        std::cerr << "Error opening " << compatiblePath << "\n";
+        return FanTypes::i2c; // Should this throw an exception instead?
     }
-    if (canonical.ends_with("pwm-fan-controller"))
+
+    std::string compatibleString;
+    while (compatibleStream.peek() != EOF)
     {
-        return FanTypes::nuvoton;
+        std::getline(compatibleStream, compatibleString);
+        compatibleString.pop_back(); // trim EOL before comparisons
+
+        if (compatibleString == "aspeed,ast2400-pwm-tacho" ||
+            compatibleString == "aspeed,ast2500-pwm-tacho")
+        {
+            return FanTypes::aspeed;
+        }
+        if (compatibleString == "nuvoton,npcm750-pwm-fan")
+        {
+            return FanTypes::nuvoton;
+        }
     }
+
     // todo: will we need to support other types?
     return FanTypes::i2c;
 }