blob: 09b55f918d53a0b94dafd61c0bd957534681e266 [file] [log] [blame]
Matt Spinlerd7abf362018-01-18 12:40:02 -06001#pragma once
2
3#include <deque>
4#include <tuple>
5#include <vector>
6
7namespace witherspoon
8{
9namespace power
10{
11namespace history
12{
13
14static constexpr auto recIDPos = 0;
15static constexpr auto recTimePos = 1;
16static constexpr auto recAvgPos = 2;
17static constexpr auto recMaxPos = 3;
18using Record = std::tuple<size_t, int64_t, int64_t, int64_t>;
19
20/**
21 * @class RecordManager
22 *
23 * This class manages the records for the input power history of
24 * a power supply.
25 *
26 * The history is the average and maximum power values across 30s
27 * intervals. Every 30s, a new record will be available from the
28 * PS. This class takes that raw PS data and converts it into
29 * something useable by D-Bus. It ensures the readings are always
30 * sorted newest to oldest, and prunes out the oldest entries when
31 * necessary. If there is a problem with the ordering IDs coming
32 * from the PS, it will clear out the old records and start over.
33 */
34class RecordManager
35{
36 public:
37
38 static constexpr auto LAST_SEQUENCE_ID = 0xFF;
39
40 using DBusRecord = std::tuple<uint64_t, int64_t>;
41 using DBusRecordList = std::vector<DBusRecord>;
42
43 RecordManager() = delete;
44 ~RecordManager() = default;
45 RecordManager(const RecordManager&) = default;
46 RecordManager& operator=(const RecordManager&) = default;
47 RecordManager(RecordManager&&) = default;
48 RecordManager& operator=(RecordManager&&) = default;
49
50 /**
51 * @brief Constructor
52 *
53 * @param[in] maxRec - the maximum number of history
54 * records to keep at a time
55 */
56 RecordManager(size_t maxRec) :
57 RecordManager(maxRec, LAST_SEQUENCE_ID)
58 {
59 }
60
61 /**
62 * @brief Constructor
63 *
64 * @param[in] maxRec - the maximum number of history
65 * records to keep at a time
66 * @param[in] lastSequenceID - the last sequence ID the power supply
67 * will use before starting over
68 */
69 RecordManager(size_t maxRec, size_t lastSequenceID) :
70 maxRecords(maxRec),
71 lastSequenceID(lastSequenceID)
72 {
73 }
74
75 /**
Matt Spinlere710d182018-01-18 13:06:17 -060076 * @brief Converts a Linear Format power number to an integer
77 *
78 * The PMBus spec describes a 2 byte Linear Format
79 * number that is composed of an exponent and mantissa
80 * in two's complement notation.
81 *
82 * Value = Mantissa * 2**Exponent
83 *
84 * @return int64_t the converted value
85 */
86 static int64_t linearToInteger(uint16_t data);
87
88 /**
Matt Spinlerd7abf362018-01-18 12:40:02 -060089 * @brief Returns the number of records
90 *
91 * @return size_t - the number of records
92 *
93 */
94 inline size_t getNumRecords() const
95 {
96 return records.size();
97 }
98
99 /**
100 * @brief Deletes all records
101 */
102 inline void clear()
103 {
104 records.clear();
105 }
106
107 private:
108
109 /**
110 * @brief The maximum number of entries to keep in the history.
111 *
112 * When a new record is added, the oldest one will be removed.
113 */
114 const size_t maxRecords;
115
116 /**
117 * @brief The last ID the power supply returns before rolling over
118 * back to the first ID of 0.
119 */
120 const size_t lastSequenceID;
121
122 /**
123 * @brief The list of timestamp/average/maximum records.
124 * Newer records are added to the front, and older ones
125 * removed from the back.
126 */
127 std::deque<Record> records;
128};
129
130}
131}
132}