control: Add zone increase & decrease timers
Add the increase and decrease timers to the JSON based zone objects to
handle target increase and decrease on their configured intervals.
Change-Id: I55f777b5f88b6fc05937c7acf91428e31c138b90
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/zone.cpp b/control/json/zone.cpp
index 6249194..be827cf 100644
--- a/control/json/zone.cpp
+++ b/control/json/zone.cpp
@@ -27,6 +27,7 @@
#include <sdeventplus/event.hpp>
#include <algorithm>
+#include <chrono>
#include <filesystem>
#include <fstream>
#include <iterator>
@@ -54,12 +55,15 @@
ConfigBase(jsonObj),
ThermalObject(bus, (fs::path{CONTROL_OBJPATH} /= getName()).c_str(), true),
_manager(mgr), _incDelay(0), _floor(0), _target(0), _incDelta(0),
- _decDelta(0), _requestTargetBase(0), _isActive(true)
+ _decDelta(0), _requestTargetBase(0), _isActive(true),
+ _incTimer(event, std::bind(&Zone::incTimerExpired, this)),
+ _decTimer(event, std::bind(&Zone::decTimerExpired, this))
{
// Increase delay is optional, defaults to 0
if (jsonObj.contains("increase_delay"))
{
- _incDelay = jsonObj["increase_delay"].get<uint64_t>();
+ _incDelay =
+ std::chrono::seconds(jsonObj["increase_delay"].get<uint64_t>());
}
setDefaultCeiling(jsonObj);
setDefaultFloor(jsonObj);
@@ -69,6 +73,9 @@
{
setInterfaces(jsonObj);
}
+
+ // Start timer for fan target decreases
+ _decTimer.restart(_decInterval);
}
void Zone::addFan(std::unique_ptr<Fan> fan)
@@ -133,11 +140,18 @@
requestTarget = _ceiling;
}
setTarget(requestTarget);
- // TODO // Restart timer countdown for fan speed increase
- // _incTimer.restartOnce(_incDelay);
+ // Restart timer countdown for fan target increase
+ _incTimer.restartOnce(_incDelay);
}
}
+void Zone::incTimerExpired()
+{
+ // Clear increase delta when timer expires allowing additional target
+ // increase requests or target decreases to occur
+ _incDelta = 0;
+}
+
void Zone::requestDecrease(uint64_t targetDelta)
{
// Only decrease the lowest target delta requested
@@ -147,6 +161,40 @@
}
}
+void Zone::decTimerExpired()
+{
+ // Check all entries are set to allow a decrease
+ auto pred = [](auto const& entry) { return entry.second; };
+ auto decAllowed = std::all_of(_decAllowed.begin(), _decAllowed.end(), pred);
+
+ // Only decrease targets when allowed, a requested decrease target delta
+ // exists, where no requested increases exist and the increase timer is not
+ // running (i.e. not in the middle of increasing)
+ if (decAllowed && _decDelta != 0 && _incDelta == 0 &&
+ !_incTimer.isEnabled())
+ {
+ auto requestTarget = getRequestTargetBase();
+ // Request target should not start above ceiling
+ if (requestTarget > _ceiling)
+ {
+ requestTarget = _ceiling;
+ }
+ // Target can not go below the defined floor
+ if ((requestTarget < _decDelta) || (requestTarget - _decDelta < _floor))
+ {
+ requestTarget = _floor;
+ }
+ else
+ {
+ requestTarget = requestTarget - _decDelta;
+ }
+ setTarget(requestTarget);
+ }
+ // Clear decrease delta when timer expires
+ _decDelta = 0;
+ // Decrease timer is restarted since its repeating
+}
+
void Zone::setPersisted(const std::string& intf, const std::string& prop)
{
if (std::find_if(_propsPersisted[intf].begin(), _propsPersisted[intf].end(),
@@ -226,7 +274,8 @@
entry("JSON=%s", jsonObj.dump().c_str()));
throw std::runtime_error("Missing required zone's decrease interval");
}
- _decInterval = jsonObj["decrease_interval"].get<uint64_t>();
+ _decInterval =
+ std::chrono::seconds(jsonObj["decrease_interval"].get<uint64_t>());
}
void Zone::setInterfaces(const json& jsonObj)