1 #pragma once
2 
3 #include "sensor.hpp"
4 
5 #include <sdbusplus/bus.hpp>
6 #include <sdbusplus/server.hpp>
7 #include <xyz/openbmc_project/Sensor/Value/server.hpp>
8 
9 #include <memory>
10 #include <mutex>
11 #include <type_traits>
12 
13 template <typename... T>
14 using ServerObject = typename sdbusplus::server::object_t<T...>;
15 
16 using ValueInterface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
17 using ValueObject = ServerObject<ValueInterface>;
18 
19 namespace pid_control
20 {
21 
22 class ValueHelper : public ValueInterface
23 {
24   public:
operator ()() const25     auto operator()() const
26     {
27         return value();
28     }
29 };
30 
31 constexpr bool usingDouble =
32     std::is_same_v<std::result_of_t<ValueHelper()>, double>;
33 using ValueType = std::conditional_t<usingDouble, double, int64_t>;
34 
35 /*
36  * HostSensor object is a Sensor derivative that also implements a ValueObject,
37  * which comes from the dbus as an object that implements Sensor.Value.
38  */
39 class HostSensor : public Sensor, public ValueObject
40 {
41   public:
42     static std::unique_ptr<Sensor> createTemp(const std::string& name,
43                                               int64_t timeout,
44                                               sdbusplus::bus_t& bus,
45                                               const char* objPath, bool defer);
46 
HostSensor(const std::string & name,int64_t timeout,sdbusplus::bus_t & bus,const char * objPath,bool defer)47     HostSensor(const std::string& name, int64_t timeout, sdbusplus::bus_t& bus,
48                const char* objPath, bool defer) :
49         Sensor(name, timeout),
50         ValueObject(bus, objPath,
51                     defer ? ValueObject::action::defer_emit
52                           : ValueObject::action::emit_object_added)
53     {}
54 
55     ValueType value(ValueType value) override;
56 
57     ReadReturn read(void) override;
58     void write(double value) override;
59     bool getFailed(void) override;
60 
61   private:
62     /*
63      * _lock will be used to make sure _updated & _value are updated
64      * together.
65      */
66     std::mutex _lock;
67     std::chrono::high_resolution_clock::time_point _updated;
68     double _value = 0;
69 };
70 
71 } // namespace pid_control
72