Bug-fixes & persistent saving of important parameters

This commit is contained in:
hg
2014-06-19 00:40:58 +02:00
parent 6c5ea5a39f
commit 4c24d7a834
11 changed files with 314 additions and 20 deletions
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+25 -1
View File
@@ -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 */
+8 -1
View File
@@ -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 */
+29 -1
View File
@@ -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 */
+8 -1
View File
@@ -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 */
+1 -1
View File
@@ -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
View File
@@ -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);
+76
View File
@@ -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_ */