Bug-fixes & persistent saving of important parameters
This commit is contained in:
@@ -31,6 +31,7 @@ distclean : clean
|
||||
install: bin/growcontrold
|
||||
mkdir -p /opt/growcontrol/bin
|
||||
mkdir -p /opt/growcontrol/log
|
||||
mkdir -p /opt/growcontrol/save
|
||||
cp bin/growcontrold /opt/growcontrol/bin
|
||||
cp -r config /opt/growcontrol
|
||||
|
||||
|
||||
+15
-2
@@ -12,16 +12,29 @@
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class GrowControl;
|
||||
struct GCSensorsInfo;
|
||||
|
||||
class GCFanProfile {
|
||||
private:
|
||||
long id;
|
||||
std::string name;
|
||||
GrowControl& controller;
|
||||
|
||||
public:
|
||||
GCFanProfile(std::string name) : name(name) {}
|
||||
GCFanProfile(GrowControl& controller, long id, std::string name) : id(id), name(name), controller(controller) {}
|
||||
virtual ~GCFanProfile() {}
|
||||
|
||||
std::string getName() { return name; }
|
||||
public:
|
||||
long getID() { return id; }
|
||||
|
||||
virtual void startCallback() = 0;
|
||||
virtual void stopCallback() = 0;
|
||||
virtual void pauseCallback() = 0;
|
||||
virtual void continueCallback() = 0;
|
||||
virtual void upperLimitChangedCallback(unsigned oldlimit, unsigned newlimit) = 0;
|
||||
virtual void mainLoopCallback(GCSensorsInfo& sensors) = 0;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
+129
-8
@@ -18,6 +18,7 @@
|
||||
#include <thread>
|
||||
#include "fanprofile/DummyProfile.h"
|
||||
#include "fanprofile/Dummy2Profile.h"
|
||||
#include "savefile.h"
|
||||
|
||||
|
||||
namespace growcontrol {
|
||||
@@ -25,16 +26,50 @@ namespace growcontrol {
|
||||
log4cpp::Category& GrowControl::logger = log4cpp::Category::getInstance("growcontrol");
|
||||
|
||||
GrowControl::GrowControl() : lcd(*this) {
|
||||
fanProfiles.push_back(new DummyProfile());
|
||||
fanProfiles.push_back(new Dummy2Profile());
|
||||
fanProfiles.push_back(new DummyProfile(*this));
|
||||
fanProfiles.push_back(new Dummy2Profile(*this));
|
||||
fan1ActiveProfile = fanProfiles.at(0);
|
||||
}
|
||||
|
||||
GrowControl::~GrowControl() {
|
||||
}
|
||||
|
||||
bool GrowControl::connect(std::string host , uint16_t port, bool retry) {
|
||||
bool GrowControl::connect(std::string workDir, std::string host , uint16_t port, bool retry) {
|
||||
tfConnection.addListener(*this);
|
||||
this->workDirString = workDir;
|
||||
std::ostringstream ss;
|
||||
ss << workDir << "/" << "save";
|
||||
saveDirString = ss.str();
|
||||
|
||||
try {
|
||||
fan1UpperLimit = saveFileRead<unsigned>(saveDirString, "fan1UpperLimit.save");
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
try {
|
||||
fan1AutoMode = saveFileRead<bool>(saveDirString, "fan1AutoMode.save");
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
if (!fan1AutoMode) {
|
||||
try {
|
||||
fan1Level = saveFileRead<unsigned>(saveDirString, "fan1Level.save");
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
}
|
||||
try {
|
||||
long pid = saveFileRead<long>(saveDirString, "fan1Profile.save");
|
||||
for (auto p : fanProfiles) {
|
||||
if (p->getID() == pid) {
|
||||
fan1ActiveProfile = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
|
||||
bool breakFlag = false;
|
||||
do {
|
||||
try {
|
||||
@@ -239,6 +274,13 @@ void GrowControl::setFan1Level(unsigned level) {
|
||||
io16Bricklet->setPort('a', 1 << (fan1Level - 1), true);
|
||||
}
|
||||
}
|
||||
if (!fan1AutoMode) {
|
||||
try {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1Level.save", fan1Level);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,9 +289,20 @@ unsigned GrowControl::getFan1UpperLimit() {
|
||||
}
|
||||
|
||||
void GrowControl::setFan1UpperLimit(unsigned limit) {
|
||||
fan1UpperLimit = limit;
|
||||
if (fan1Level > fan1UpperLimit) {
|
||||
setFan1Level(fan1UpperLimit);
|
||||
if (fan1UpperLimit != limit) {
|
||||
unsigned old = fan1UpperLimit;
|
||||
fan1UpperLimit = limit;
|
||||
if (fan1Level > fan1UpperLimit) {
|
||||
setFan1Level(fan1UpperLimit);
|
||||
}
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
fan1ActiveProfile->upperLimitChangedCallback(old, limit);
|
||||
}
|
||||
try {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1UpperLimit.save", fan1UpperLimit);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +315,21 @@ bool GrowControl::getFan1AutoMode() {
|
||||
}
|
||||
|
||||
void GrowControl::setFan1AutoMode(bool mode) {
|
||||
fan1AutoMode = mode;
|
||||
if (fan1AutoMode != mode) {
|
||||
fan1AutoMode = mode;
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
if (fan1AutoMode) {
|
||||
fan1ActiveProfile->continueCallback();
|
||||
} else {
|
||||
fan1ActiveProfile->pauseCallback();
|
||||
}
|
||||
}
|
||||
try {
|
||||
saveFileWrite<bool>(saveDirString, "fan1AutoMode.save", fan1AutoMode);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GCFanProfile* GrowControl::getFan1Profile() {
|
||||
@@ -270,7 +337,22 @@ GCFanProfile* GrowControl::getFan1Profile() {
|
||||
}
|
||||
|
||||
void GrowControl::setFan1Profile(GCFanProfile* profile) {
|
||||
fan1ActiveProfile = profile;
|
||||
if (fan1ActiveProfile != profile) {
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
fan1ActiveProfile->stopCallback();
|
||||
}
|
||||
fan1ActiveProfile = profile;
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
fan1ActiveProfile->startCallback();
|
||||
}
|
||||
try {
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1Profile.save", fan1ActiveProfile->getID());
|
||||
}
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<GCFanProfile*>& GrowControl::getFanProfiles() {
|
||||
@@ -286,6 +368,10 @@ void GrowControl::shutdownController() {
|
||||
|
||||
void GrowControl::mainLoop() {
|
||||
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
fan1ActiveProfile->startCallback();
|
||||
}
|
||||
|
||||
while (mainLoopFlag) {
|
||||
|
||||
// Fetch sensor values
|
||||
@@ -325,11 +411,46 @@ void GrowControl::mainLoop() {
|
||||
|
||||
lcd.controlMainLoopCallback(sensorValues);
|
||||
|
||||
if (fan1AutoMode && fan1ActiveProfile != nullptr) {
|
||||
fan1ActiveProfile->mainLoopCallback(sensorValues);
|
||||
}
|
||||
|
||||
if (mainLoopFlag) {
|
||||
std::this_thread::sleep_until(sensorValues.timestamp + std::chrono::seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1UpperLimit.save", fan1UpperLimit);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
try {
|
||||
saveFileWrite<bool>(saveDirString, "fan1AutoMode.save", fan1AutoMode);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
if (!fan1AutoMode) {
|
||||
try {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1Level.save", fan1Level);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1Level.save", 0);
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (fan1ActiveProfile != nullptr) {
|
||||
saveFileWrite<unsigned>(saveDirString, "fan1Profile.save", fan1ActiveProfile->getID());
|
||||
}
|
||||
} catch (GCException &e) {
|
||||
logger << log4cpp::Priority::INFO << e.what();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-2
@@ -37,7 +37,7 @@ struct GCSensorsInfo {
|
||||
CGSensorValue<double> temp2;
|
||||
CGSensorValue<double> hum1;
|
||||
CGSensorValue<unsigned> fan1Level;
|
||||
int fan1UpperLimit;
|
||||
unsigned fan1UpperLimit;
|
||||
bool fan1AutoMode;
|
||||
GCFanProfile* fan1Profile;
|
||||
};
|
||||
@@ -69,12 +69,15 @@ private:
|
||||
GCFanProfile* fan1ActiveProfile = nullptr;
|
||||
std::vector<GCFanProfile*> fanProfiles;
|
||||
|
||||
std::string workDirString;
|
||||
std::string saveDirString;
|
||||
|
||||
|
||||
public:
|
||||
GrowControl();
|
||||
virtual ~GrowControl();
|
||||
|
||||
bool connect(std::string host , uint16_t port, bool retry = true);
|
||||
bool connect(std::string workDir, std::string host , uint16_t port, bool retry = true);
|
||||
|
||||
void newDeviceCallback(TfConnection& conn, TfDevice& device);
|
||||
void shutdownCallback();
|
||||
@@ -101,6 +104,9 @@ public:
|
||||
|
||||
|
||||
void shutdownController();
|
||||
|
||||
const std::string getSaveDir() { return saveDirString; }
|
||||
const std::string getWorkDir() { return workDirString; }
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
@@ -9,10 +9,34 @@
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
Dummy2Profile::Dummy2Profile() : GCFanProfile("Dummy2") {
|
||||
Dummy2Profile::Dummy2Profile(GrowControl& controller) : GCFanProfile(controller, 2, "Dummy2") {
|
||||
}
|
||||
|
||||
Dummy2Profile::~Dummy2Profile() {
|
||||
}
|
||||
|
||||
void Dummy2Profile::startCallback() {
|
||||
|
||||
}
|
||||
|
||||
void Dummy2Profile::stopCallback() {
|
||||
|
||||
}
|
||||
|
||||
void Dummy2Profile::upperLimitChangedCallback(unsigned oldlimit, unsigned newlimit) {
|
||||
|
||||
}
|
||||
|
||||
void Dummy2Profile::mainLoopCallback(GCSensorsInfo& sensors) {
|
||||
|
||||
}
|
||||
|
||||
void Dummy2Profile::pauseCallback() {
|
||||
|
||||
}
|
||||
|
||||
void Dummy2Profile::continueCallback() {
|
||||
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
@@ -14,8 +14,15 @@ namespace growcontrol {
|
||||
|
||||
class Dummy2Profile: public GCFanProfile {
|
||||
public:
|
||||
Dummy2Profile();
|
||||
Dummy2Profile(GrowControl& controller);
|
||||
virtual ~Dummy2Profile();
|
||||
|
||||
virtual void startCallback();
|
||||
virtual void stopCallback();
|
||||
virtual void pauseCallback();
|
||||
virtual void continueCallback();
|
||||
virtual void upperLimitChangedCallback(unsigned oldlimit, unsigned newlimit);
|
||||
virtual void mainLoopCallback(GCSensorsInfo& sensors);
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
@@ -6,13 +6,41 @@
|
||||
*/
|
||||
|
||||
#include "DummyProfile.h"
|
||||
#include <log4cpp/Category.hh>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
DummyProfile::DummyProfile() : GCFanProfile("Dummy") {
|
||||
static log4cpp::Category& logger = log4cpp::Category::getInstance("growcontrol");
|
||||
|
||||
DummyProfile::DummyProfile(GrowControl& controller) : GCFanProfile(controller, 1, "Dummy") {
|
||||
}
|
||||
|
||||
DummyProfile::~DummyProfile() {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::~DummyProfile()";
|
||||
}
|
||||
|
||||
void DummyProfile::startCallback() {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::startCallback()";
|
||||
}
|
||||
|
||||
void DummyProfile::stopCallback() {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::stopCallback()";
|
||||
}
|
||||
|
||||
void DummyProfile::upperLimitChangedCallback(unsigned oldlimit, unsigned newlimit) {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::upperLimitChangedCallback(" << oldlimit << ", " << newlimit << ")";
|
||||
}
|
||||
|
||||
void DummyProfile::mainLoopCallback(GCSensorsInfo& sensors) {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::mainLoopCallback()";
|
||||
}
|
||||
|
||||
void DummyProfile::pauseCallback() {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::pauseCallback()";
|
||||
}
|
||||
|
||||
void DummyProfile::continueCallback() {
|
||||
logger << log4cpp::Priority::INFO << "DummyProfile::continueCallback()";
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
@@ -14,8 +14,15 @@ namespace growcontrol {
|
||||
|
||||
class DummyProfile: public GCFanProfile {
|
||||
public:
|
||||
DummyProfile();
|
||||
DummyProfile(GrowControl& controller);
|
||||
virtual ~DummyProfile();
|
||||
|
||||
virtual void startCallback();
|
||||
virtual void stopCallback();
|
||||
virtual void pauseCallback();
|
||||
virtual void continueCallback();
|
||||
virtual void upperLimitChangedCallback(unsigned oldlimit, unsigned newlimit);
|
||||
virtual void mainLoopCallback(GCSensorsInfo& sensors);
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
@@ -88,7 +88,7 @@ void FanProfileSettings::buttonStateCallback(uint8_t button, bool state) {
|
||||
refresh = true;
|
||||
break;
|
||||
case 2: // down
|
||||
if (cursorPos < 2) {
|
||||
if (cursorPos < 2 && cursorPos < items.size() - 1) {
|
||||
cursorPos++;
|
||||
} else if (cursorPos == 2 && items.size() - itemsStart > 3) {
|
||||
itemsStart++;
|
||||
|
||||
+14
-3
@@ -31,6 +31,7 @@ std::string pidFile = "/var/run/growcontrold.pid";
|
||||
std::string socketPath = "/opt/growcontrol/growcontrold.socket";
|
||||
std::string log4cppConfig = "log4cpp.config";
|
||||
std::string host = "localhost";
|
||||
std::string workDir = "/opt/growcontrol";
|
||||
uint16_t port = 4223;
|
||||
bool daemonMode = false;
|
||||
int pid_fd = 0;
|
||||
@@ -60,13 +61,14 @@ void signalHandler(int signum) {
|
||||
|
||||
|
||||
void printUsage(std::ostream& stream, std::string name) {
|
||||
stream << "Usage: " << name << " [-d] [-pid pid-file] [-s socket-path] [-l log4cpp-config] [-h host] [-p port]" << std::endl
|
||||
stream << "Usage: " << name << " [-d] [-pid pid-file] [-s socket-path] [-l log4cpp-config] [-h host] [-p port] [-w work-dir]" << std::endl
|
||||
<< "\t-d ... daemon mode" << std::endl
|
||||
<< "\t-pid ... pid-file" << std::endl
|
||||
<< "\t-s ... path of ipc socket" << std::endl
|
||||
<< "\t-l ... path to log4cpp config file" << std::endl
|
||||
<< "\t-h ... brickd address" << std::endl
|
||||
<< "\t-p ... brickd port" << std::endl;
|
||||
<< "\t-p ... brickd port" << std::endl
|
||||
<< "\t-w ... working directory" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +108,15 @@ int main(int argc, char **argv) {
|
||||
printUsage(std::cerr, argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
} else if (strcmp(argv[t], "-w") == 0) {
|
||||
if (t+1 < argc && argv[t+1][0] != '-') {
|
||||
t++;
|
||||
workDir = argv[t];
|
||||
} else {
|
||||
std::cerr << "Option -w is missing an argument." << std::endl << std::endl;
|
||||
printUsage(std::cerr, argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
} else if (strcmp(argv[t], "-h") == 0) {
|
||||
if (t+1 < argc && argv[t+1][0] != '-') {
|
||||
t++;
|
||||
@@ -156,7 +167,7 @@ int main(int argc, char **argv) {
|
||||
signal(SIGINT, signalHandler);
|
||||
signal(SIGHUP, signalHandler);
|
||||
|
||||
controller.connect(host, port);
|
||||
controller.connect(workDir, host, port);
|
||||
|
||||
if (!termSignalCaught) {
|
||||
sleep(2);
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* savefile.h
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SAVEFILE_H_
|
||||
#define SAVEFILE_H_
|
||||
|
||||
#include "GCException.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
|
||||
template<class T>
|
||||
void saveFileWrite(std::string file, T value) {
|
||||
std::ofstream fs(file, std::ios::out | std::ios::binary);
|
||||
fs << value;
|
||||
if (!fs) {
|
||||
std::ostringstream msg;
|
||||
msg << "Could not write to save file " << file;
|
||||
throw GCException(msg.str(), GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T saveFileRead(std::string file) {
|
||||
T ret;
|
||||
std::ifstream fs(file, std::ios::out | std::ios::binary);
|
||||
fs >> ret;
|
||||
if (!fs) {
|
||||
std::ostringstream msg;
|
||||
msg << "Could not read from save file " << file;
|
||||
throw GCException(msg.str(), GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void saveFileWrite(std::string base, std::string file, T value) {
|
||||
std::ostringstream ss;
|
||||
ss << base << "/" << file;
|
||||
std::ofstream fs(ss.str(), std::ios::out | std::ios::binary);
|
||||
fs << value;
|
||||
if (!fs) {
|
||||
std::ostringstream msg;
|
||||
msg << "Could not write to save file " << ss.str();
|
||||
throw GCException(msg.str(), GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T saveFileRead(std::string base, std::string file) {
|
||||
T ret;
|
||||
std::ostringstream ss;
|
||||
ss << base << "/" << file;
|
||||
std::ifstream fs(ss.str(), std::ios::out | std::ios::binary);
|
||||
fs >> ret;
|
||||
if (!fs) {
|
||||
std::ostringstream msg;
|
||||
msg << "Could not read from save file " << ss.str();
|
||||
throw GCException(msg.str(), GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* SAVEFILE_H_ */
|
||||
Reference in New Issue
Block a user