regulators: Create DBusSensors class

Create the DBusSensors class.  This is a concrete implementation of the
Sensors abstract base class.  This class manages all the voltage
regulator sensors in the system.

Also add a lastUpdateTime data member to the DBusSensor class.  This
data member is set whenever the sensor is updated.  This enables the
DBusSensors class to detect sensors that were not updated during the
current monitoring cycle.

Sensors that were not updated during the current monitoring cycle are
deleted.  These sensors were likely produced by a hardware device that
was removed or replaced with a different version.

Tested:
* Ran through entire monitoring cycle multiple times
* Tested that lastUpdateTime is set correctly when a sensor is modified
  * Sensor value updated
  * Sensor disabled
  * Sensor put in error state
* Tested where new sensor was created
* Tested where existing sensor was updated
* Tested where all sensors disabled
* Tested where all sensors for a rail put in error state
* Tested where sensors removed due to not being updated this cycle
* Tested where D-Bus exception occurs when trying to create a sensor
* See complete test plan at
  https://gist.github.com/smccarney/69efb813c0005571aee687f67e489278

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: Ib1fc399f100188cc048ac3ab5892117b74f844e9
diff --git a/phosphor-regulators/src/dbus_sensors.hpp b/phosphor-regulators/src/dbus_sensors.hpp
new file mode 100644
index 0000000..4ffa70b
--- /dev/null
+++ b/phosphor-regulators/src/dbus_sensors.hpp
@@ -0,0 +1,130 @@
+/**
+ * Copyright © 2021 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "dbus_sensor.hpp"
+#include "sensors.hpp"
+#include "services.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/manager.hpp>
+
+#include <chrono>
+#include <map>
+#include <memory>
+#include <string>
+
+namespace phosphor::power::regulators
+{
+
+/**
+ * @class DBusSensors
+ *
+ * Implementation of the Sensors interface using D-Bus.
+ */
+class DBusSensors : public Sensors
+{
+  public:
+    // Specify which compiler-generated methods we want
+    DBusSensors() = delete;
+    DBusSensors(const DBusSensors&) = delete;
+    DBusSensors(DBusSensors&&) = delete;
+    DBusSensors& operator=(const DBusSensors&) = delete;
+    DBusSensors& operator=(DBusSensors&&) = delete;
+    virtual ~DBusSensors() = default;
+
+    /**
+     * Constructor.
+     *
+     * @param bus D-Bus bus object
+     */
+    explicit DBusSensors(sdbusplus::bus::bus& bus) :
+        bus{bus}, manager{bus, sensorsObjectPath}
+    {
+    }
+
+    /** @copydoc Sensors::enable() */
+    virtual void enable(Services& services) override;
+
+    /** @copydoc Sensors::endCycle() */
+    virtual void endCycle(Services& services) override;
+
+    /** @copydoc Sensors::endRail() */
+    virtual void endRail(bool errorOccurred, Services& services) override;
+
+    /** @copydoc Sensors::disable() */
+    virtual void disable(Services& services) override;
+
+    /** @copydoc Sensors::setValue() */
+    virtual void setValue(SensorType type, double value,
+                          Services& services) override;
+
+    /** @copydoc Sensors::startCycle() */
+    virtual void startCycle(Services& services) override;
+
+    /** @copydoc Sensors::startRail() */
+    virtual void startRail(const std::string& rail,
+                           const std::string& deviceInventoryPath,
+                           const std::string& chassisInventoryPath,
+                           Services& services) override;
+
+  private:
+    /**
+     * D-Bus bus object.
+     */
+    sdbusplus::bus::bus& bus;
+
+    /**
+     * D-Bus object manager.
+     *
+     * Causes this application to implement the
+     * org.freedesktop.DBus.ObjectManager interface.
+     */
+    sdbusplus::server::manager_t manager;
+
+    /**
+     * Map from sensor names to DBusSensor objects.
+     */
+    std::map<std::string, std::unique_ptr<DBusSensor>> sensors{};
+
+    /**
+     * Time that current monitoring cycle started.
+     */
+    std::chrono::system_clock::time_point cycleStartTime{};
+
+    /**
+     * Current voltage rail.
+     *
+     * This is set by startRail().
+     */
+    std::string rail{};
+
+    /**
+     * Current device inventory path.
+     *
+     * This is set by startRail().
+     */
+    std::string deviceInventoryPath{};
+
+    /**
+     * Current chassis inventory path.
+     *
+     * This is set by startRail().
+     */
+    std::string chassisInventoryPath{};
+};
+
+} // namespace phosphor::power::regulators