Fixed bugs.
Began to implement Fan Control.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* GCFanProfile.h
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef GCFANPROFILE_H_
|
||||
#define GCFANPROFILE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class GCFanProfile {
|
||||
private:
|
||||
std::string name;
|
||||
|
||||
public:
|
||||
GCFanProfile(std::string name) : name(name) {}
|
||||
virtual ~GCFanProfile() {}
|
||||
|
||||
std::string getName() { return name; }
|
||||
public:
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* GCFANPROFILE_H_ */
|
||||
+84
-12
@@ -13,13 +13,21 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <thread>
|
||||
#include "fanprofile/DummyProfile.h"
|
||||
#include "fanprofile/Dummy2Profile.h"
|
||||
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
log4cpp::Category& GrowControl::logger = log4cpp::Category::getInstance("growcontrol");
|
||||
|
||||
GrowControl::GrowControl() {
|
||||
GrowControl::GrowControl() : lcd(*this) {
|
||||
fanProfiles.push_back(new DummyProfile());
|
||||
fanProfiles.push_back(new Dummy2Profile());
|
||||
fan1ActiveProfile = fanProfiles.at(0);
|
||||
}
|
||||
|
||||
GrowControl::~GrowControl() {
|
||||
@@ -107,8 +115,8 @@ void GrowControl::newDeviceCallback(TfConnection& conn, TfDevice& device) {
|
||||
&& device.getDeviceState() == TfDeviceState::AVAILABLE ) {
|
||||
io16Bricklet = (TfIO16Bricklet*)&device;
|
||||
io16Bricklet->connect();
|
||||
io16Bricklet->setPortConfiguration('a', 0x7F, 'o', false);
|
||||
io16Bricklet->setPort('a', 1);
|
||||
io16Bricklet->setPortConfiguration('a', fan1PinMask, 'o', false);
|
||||
setFan1Level(fan1Level);
|
||||
logger << log4cpp::Priority::INFO << "Added io16 device " << device.getDeviceName(true) << ".";
|
||||
}
|
||||
break;
|
||||
@@ -187,14 +195,16 @@ double GrowControl::getHum1() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int GrowControl::getFan1() {
|
||||
unsigned GrowControl::getFan1Level(bool force) {
|
||||
std::lock_guard<std::mutex> lock(controlMutex);
|
||||
int ret = 0;
|
||||
unsigned ret = 0;
|
||||
if (force) {
|
||||
return fan1Level;
|
||||
}
|
||||
if (hum1Bricklet != nullptr) {
|
||||
if (hum1Bricklet->getDeviceState() == TfDeviceState::CONNECTED) {
|
||||
try {
|
||||
// ToDo
|
||||
throw GCException("Fan not implemented yet.", GCErrorCode::NOT_INITIALIZED);
|
||||
ret = fan1Level;
|
||||
} catch (TfError &e) {
|
||||
std::ostringstream ss;
|
||||
ss << "unknown exception while getting fan1: " << e.what();
|
||||
@@ -210,6 +220,64 @@ int GrowControl::getFan1() {
|
||||
}
|
||||
|
||||
|
||||
bool GrowControl::isFan1Connected() {
|
||||
return (io16Bricklet != nullptr && io16Bricklet->getDeviceState() == TfDeviceState::CONNECTED);
|
||||
}
|
||||
|
||||
void GrowControl::setFan1Level(unsigned level) {
|
||||
if (level > fan1UpperLimit) {
|
||||
level = fan1UpperLimit;
|
||||
}
|
||||
if (level != fan1Level) {
|
||||
fan1Level = level;
|
||||
if (isFan1Connected()) {
|
||||
if (fan1Level <= 0) {
|
||||
io16Bricklet->setPort('a', fan1PinMask, false);
|
||||
} else {
|
||||
io16Bricklet->setPort('a', fan1PinMask, false);
|
||||
usleep(100000); // Wait for 100 ms (Just to be sure)
|
||||
io16Bricklet->setPort('a', 1 << (fan1Level - 1), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned GrowControl::getFan1UpperLimit() {
|
||||
return fan1UpperLimit;
|
||||
}
|
||||
|
||||
void GrowControl::setFan1UpperLimit(unsigned limit) {
|
||||
fan1UpperLimit = limit;
|
||||
if (fan1Level > fan1UpperLimit) {
|
||||
setFan1Level(fan1UpperLimit);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned GrowControl::getFan1Max() {
|
||||
return fan1Max;
|
||||
}
|
||||
|
||||
bool GrowControl::getFan1AutoMode() {
|
||||
return fan1AutoMode;
|
||||
}
|
||||
|
||||
void GrowControl::setFan1AutoMode(bool mode) {
|
||||
fan1AutoMode = mode;
|
||||
}
|
||||
|
||||
GCFanProfile* GrowControl::getFan1Profile() {
|
||||
return fan1ActiveProfile;
|
||||
}
|
||||
|
||||
void GrowControl::setFan1Profile(GCFanProfile* profile) {
|
||||
fan1ActiveProfile = profile;
|
||||
}
|
||||
|
||||
const std::vector<GCFanProfile*>& GrowControl::getFanProfiles() {
|
||||
return fanProfiles;
|
||||
}
|
||||
|
||||
|
||||
void GrowControl::shutdownController() {
|
||||
std::lock_guard<std::mutex> lock(controlMutex);
|
||||
mainLoopFlag = false;
|
||||
@@ -222,6 +290,7 @@ void GrowControl::mainLoop() {
|
||||
|
||||
// Fetch sensor values
|
||||
GCSensorsInfo sensorValues;
|
||||
sensorValues.timestamp = std::chrono::system_clock::now();
|
||||
try {
|
||||
sensorValues.temp1.value = getTemp1();
|
||||
sensorValues.temp1.valid = true;
|
||||
@@ -244,17 +313,20 @@ void GrowControl::mainLoop() {
|
||||
sensorValues.hum1.error = e;
|
||||
}
|
||||
try {
|
||||
sensorValues.fan1.value = getFan1();
|
||||
sensorValues.fan1.valid = true;
|
||||
sensorValues.fan1UpperLimit = getFan1UpperLimit();
|
||||
sensorValues.fan1AutoMode = getFan1AutoMode();
|
||||
sensorValues.fan1Profile = getFan1Profile();
|
||||
sensorValues.fan1Level.value = getFan1Level();
|
||||
sensorValues.fan1Level.valid = true;
|
||||
} catch (GCException &e) {
|
||||
sensorValues.fan1.valid = false;
|
||||
sensorValues.fan1.error = e;
|
||||
sensorValues.fan1Level.valid = false;
|
||||
sensorValues.fan1Level.error = e;
|
||||
}
|
||||
|
||||
lcd.controlMainLoopCallback(sensorValues);
|
||||
|
||||
if (mainLoopFlag) {
|
||||
sleep(sleepDuration);
|
||||
std::this_thread::sleep_until(sensorValues.timestamp + std::chrono::seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
-2
@@ -13,11 +13,16 @@
|
||||
#include <log4cpp/Category.hh>
|
||||
#include <mutex>
|
||||
#include "LCD.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
||||
using namespace tfcppsimple;
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class GCFanProfile;
|
||||
|
||||
|
||||
template<class T>
|
||||
struct CGSensorValue {
|
||||
@@ -27,10 +32,14 @@ struct CGSensorValue {
|
||||
};
|
||||
|
||||
struct GCSensorsInfo {
|
||||
std::chrono::system_clock::time_point timestamp;
|
||||
CGSensorValue<double> temp1;
|
||||
CGSensorValue<double> temp2;
|
||||
CGSensorValue<double> hum1;
|
||||
CGSensorValue<int> fan1;
|
||||
CGSensorValue<unsigned> fan1Level;
|
||||
int fan1UpperLimit;
|
||||
bool fan1AutoMode;
|
||||
GCFanProfile* fan1Profile;
|
||||
};
|
||||
|
||||
|
||||
@@ -52,6 +61,13 @@ private:
|
||||
unsigned int sleepDuration = 1;
|
||||
bool mainLoopFlag = true;
|
||||
|
||||
unsigned fan1Max = 7;
|
||||
unsigned fan1UpperLimit = 7;
|
||||
uint8_t fan1PinMask = 0x7F;
|
||||
bool fan1AutoMode = true;
|
||||
unsigned fan1Level = 0;
|
||||
GCFanProfile* fan1ActiveProfile = nullptr;
|
||||
std::vector<GCFanProfile*> fanProfiles;
|
||||
|
||||
|
||||
public:
|
||||
@@ -71,7 +87,18 @@ public:
|
||||
|
||||
double getHum1();
|
||||
|
||||
int getFan1();
|
||||
bool isFan1Connected();
|
||||
unsigned getFan1Level(bool force = false);
|
||||
void setFan1Level(unsigned level);
|
||||
unsigned getFan1UpperLimit();
|
||||
void setFan1UpperLimit(unsigned limit);
|
||||
unsigned getFan1Max();
|
||||
bool getFan1AutoMode();
|
||||
void setFan1AutoMode(bool mode);
|
||||
GCFanProfile* getFan1Profile();
|
||||
void setFan1Profile(GCFanProfile* profile);
|
||||
const std::vector<GCFanProfile*>& getFanProfiles();
|
||||
|
||||
|
||||
void shutdownController();
|
||||
};
|
||||
|
||||
+8
-4
@@ -17,6 +17,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <error.h>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
@@ -51,7 +52,7 @@ void IPCManager::workerThreadFunc(IPCManager* obj, int socket, std::thread* self
|
||||
logger << log4cpp::Priority::INFO << "ipc connection closed by peer.";
|
||||
loopFlag = false;
|
||||
} else if (rsize < 0) { // Error while receive
|
||||
logger << log4cpp::Priority::ERROR << "error during ipc recv.";
|
||||
logger << log4cpp::Priority::ERROR << "error during ipc recv: " << strerror(errno);
|
||||
loopFlag = false;
|
||||
} else {
|
||||
// Check if '\0' appears in command (our end-of-command)
|
||||
@@ -106,7 +107,7 @@ void IPCManager::init(GrowControl& growControl, std::string socketPath) {
|
||||
this->socketPath = socketPath;
|
||||
// Create Socket
|
||||
if ((socketFD = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||
logger << log4cpp::Priority::ERROR << "Could not create socket";
|
||||
logger << log4cpp::Priority::ERROR << "Could not create socket: " << strerror(errno);
|
||||
throw GCException("Could not create socket", GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
// Create address struct
|
||||
@@ -117,12 +118,12 @@ void IPCManager::init(GrowControl& growControl, std::string socketPath) {
|
||||
unlink(local.sun_path);
|
||||
// bind socket
|
||||
if (bind(socketFD, (struct sockaddr *)&local, sizeof(local)) == -1) {
|
||||
logger << log4cpp::Priority::ERROR << "Could not bind socket";
|
||||
logger << log4cpp::Priority::ERROR << "Could not bind socket: " << strerror(errno);
|
||||
throw GCException("Could not bind socket", GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
// mark as listen connection
|
||||
if (listen(socketFD, 5) == -1) {
|
||||
logger << log4cpp::Priority::ERROR << "Could not switch socket to accepting mode";
|
||||
logger << log4cpp::Priority::ERROR << "Could not switch socket to accepting mode: " << strerror(errno);
|
||||
throw GCException("Could not switch socket to accepting mode", GCErrorCode::OTHER_ERROR);
|
||||
}
|
||||
logger << log4cpp::Priority::INFO << "Successfully created new ipc socket " << socketPath << ".";
|
||||
@@ -138,6 +139,8 @@ IPCManager::~IPCManager() {
|
||||
|
||||
|
||||
void IPCManager::shutdown() {
|
||||
/* There's a deadlock somewhere
|
||||
|
||||
if (configFlag) {
|
||||
if (socketFD > 0) {
|
||||
close(socketFD);
|
||||
@@ -155,6 +158,7 @@ void IPCManager::shutdown() {
|
||||
}
|
||||
configFlag = false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ namespace growcontrol {
|
||||
|
||||
log4cpp::Category& LCD::logger = log4cpp::Category::getInstance("growcontrol");
|
||||
|
||||
LCD::LCD() : pageRoot(*this) {
|
||||
LCD::LCD(GrowControl& controller) : controller(controller), pageRoot(*this) {
|
||||
activePage = &pageRoot;
|
||||
for (int t = 0; t < 4; t++) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
|
||||
@@ -17,6 +17,7 @@ using namespace tfcppsimple;
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class GrowControl;
|
||||
struct GCSensorsInfo;
|
||||
|
||||
class LCD : public TfLCD20x4Listener, public TfDeviceStateListener {
|
||||
@@ -29,14 +30,15 @@ private:
|
||||
char lcdBuffer[4][21];
|
||||
bool lineFlags[4] = {false, false, false, false};
|
||||
int lcdLightCountdown = 0;
|
||||
int lcdLightMaxCountdown = 10;
|
||||
int lcdLightMaxCountdown = 30;
|
||||
bool lcdLightCountdownFlag = false;
|
||||
LCDPage* activePage = nullptr;
|
||||
|
||||
GrowControl& controller;
|
||||
MainPage pageRoot;
|
||||
|
||||
public:
|
||||
LCD();
|
||||
LCD(GrowControl& controller);
|
||||
virtual ~LCD();
|
||||
|
||||
void setTfObject(TfLCD20x4Bricklet& lcd);
|
||||
@@ -54,6 +56,8 @@ public:
|
||||
void resetLightCountdown();
|
||||
void setLight(bool light);
|
||||
|
||||
GrowControl& getGrowControl() { return controller; }
|
||||
|
||||
void controlMainLoopCallback(GCSensorsInfo& sensors);
|
||||
|
||||
bool isLCDConnected();
|
||||
|
||||
@@ -6,3 +6,4 @@ SRC_FILES += src/main.cpp \
|
||||
|
||||
include src/lcdpages/config.mk
|
||||
include src/third-party/config.mk
|
||||
include src/fanprofile/config.mk
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Dummy2Profile.cpp
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "Dummy2Profile.h"
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
Dummy2Profile::Dummy2Profile() : GCFanProfile("Dummy2") {
|
||||
}
|
||||
|
||||
Dummy2Profile::~Dummy2Profile() {
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Dummy2Profile.h
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef DUMMY2PROFILE_H_
|
||||
#define DUMMY2PROFILE_H_
|
||||
|
||||
#include "../GCFanProfile.h"
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class Dummy2Profile: public GCFanProfile {
|
||||
public:
|
||||
Dummy2Profile();
|
||||
virtual ~Dummy2Profile();
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* DUMMY2PROFILE_H_ */
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* DummyProfile.cpp
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "DummyProfile.h"
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
DummyProfile::DummyProfile() : GCFanProfile("Dummy") {
|
||||
}
|
||||
|
||||
DummyProfile::~DummyProfile() {
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* DummyProfile.h
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef DUMMYPROFILE_H_
|
||||
#define DUMMYPROFILE_H_
|
||||
|
||||
#include "../GCFanProfile.h"
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class DummyProfile: public GCFanProfile {
|
||||
public:
|
||||
DummyProfile();
|
||||
virtual ~DummyProfile();
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* DUMMYPROFILE_H_ */
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
SRC_FILES += src/fanprofile/DummyProfile.cpp \
|
||||
src/fanprofile/Dummy2Profile.cpp
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* FanLevelSettings.cpp
|
||||
*
|
||||
* Created on: 17.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "FanLevelSettings.h"
|
||||
#include "../LCD.h"
|
||||
#include "../GrowControl.h"
|
||||
#include "../GCException.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
FanLevelSettings::FanLevelSettings(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) {
|
||||
}
|
||||
|
||||
FanLevelSettings::~FanLevelSettings() {
|
||||
}
|
||||
|
||||
void FanLevelSettings::fillItemVector(unsigned upperLimit) {
|
||||
if (lastUpperLimit != upperLimit) {
|
||||
items.clear();
|
||||
items.push_back("Auto");
|
||||
items.push_back("Off");
|
||||
for (unsigned t = 1; t <= upperLimit; t++) {
|
||||
std::ostringstream ss;
|
||||
ss << t;
|
||||
items.push_back(ss.str());
|
||||
}
|
||||
lastUpperLimit = upperLimit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FanLevelSettings::reset() {
|
||||
itemsStart = 0;
|
||||
cursorPos = 0;
|
||||
}
|
||||
|
||||
void FanLevelSettings::refreshDisplay() {
|
||||
if (lcd.isLCDConnected()) {
|
||||
fillItemVector(lcd.getGrowControl().getFan1UpperLimit());
|
||||
int diff = (items.size()-1) - (itemsStart + cursorPos);
|
||||
if (diff < -3) {
|
||||
reset();
|
||||
} else if (diff < 0) {
|
||||
cursorPos += diff;
|
||||
}
|
||||
if (lcd.getGrowControl().getFan1AutoMode()) {
|
||||
activePos = 0;
|
||||
} else {
|
||||
activePos = lcd.getGrowControl().getFan1Level(true) + 1;
|
||||
}
|
||||
char buffer[21];
|
||||
lcd.writeLine(0, "Fan Level:");
|
||||
for (unsigned t = itemsStart; t < items.size() && t < itemsStart + 3; t++) {
|
||||
char cursor = ' ';
|
||||
if (t == itemsStart + cursorPos) {
|
||||
cursor = 0x7e;
|
||||
}
|
||||
char navhint = ' ';
|
||||
if (t == itemsStart && t >0 ) {
|
||||
navhint = '<';
|
||||
} else if (t == itemsStart + 2 && items.size() - itemsStart > 3) {
|
||||
navhint = '>';
|
||||
}
|
||||
char aPosHint1 = ' ';
|
||||
char aPosHint2 = ' ';
|
||||
if (t == activePos) {
|
||||
aPosHint1 = '*';
|
||||
aPosHint2 = '*';
|
||||
}
|
||||
snprintf(buffer, 21, "%c %c%c%.14s%c", navhint, cursor, aPosHint1, items.at(t).c_str(), aPosHint2);
|
||||
lcd.writeLine(t - itemsStart + 1, buffer);
|
||||
}
|
||||
try {
|
||||
lcd.writeLCDBuffer();
|
||||
} catch (GCException &e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FanLevelSettings::buttonStateCallback(uint8_t button, bool state) {
|
||||
if (state) {
|
||||
bool refresh = false;
|
||||
switch (button) {
|
||||
case 0: // enter
|
||||
{
|
||||
unsigned pos = itemsStart + cursorPos;
|
||||
if (pos != activePos) {
|
||||
if (pos == 0) {
|
||||
lcd.getGrowControl().setFan1AutoMode(true);
|
||||
} else {
|
||||
lcd.getGrowControl().setFan1AutoMode(false);
|
||||
lcd.getGrowControl().setFan1Level(pos-1);
|
||||
}
|
||||
}
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 1: // up
|
||||
if (cursorPos > 0) {
|
||||
cursorPos--;
|
||||
} else if (cursorPos == 0 && itemsStart > 0) {
|
||||
itemsStart--;
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case 2: // down
|
||||
if (cursorPos < 2) {
|
||||
cursorPos++;
|
||||
} else if (cursorPos == 2 && items.size() - itemsStart > 3) {
|
||||
itemsStart++;
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case 3: // cancel
|
||||
lcd.setActivePage(*parent, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (refresh) {
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FanLevelSettings::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) {
|
||||
}
|
||||
|
||||
void FanLevelSettings::controlMainLoopCallback(GCSensorsInfo& sensors) {
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* FanLevelSettings.h
|
||||
*
|
||||
* Created on: 17.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef FANLEVELSETTINGS_H_
|
||||
#define FANLEVELSETTINGS_H_
|
||||
|
||||
#include "../LCDPage.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class FanLevelSettings: public LCDPage {
|
||||
private:
|
||||
std::vector<std::string> items;
|
||||
unsigned itemsStart = 0;
|
||||
unsigned cursorPos = 0;
|
||||
unsigned lastUpperLimit = 0;
|
||||
unsigned activePos = 0;
|
||||
|
||||
void fillItemVector(unsigned upperLimit);
|
||||
|
||||
public:
|
||||
FanLevelSettings(LCD& lcd, LCDPage* parent);
|
||||
virtual ~FanLevelSettings();
|
||||
|
||||
virtual void reset();
|
||||
virtual void refreshDisplay();
|
||||
|
||||
virtual void buttonStateCallback(uint8_t button, bool state);
|
||||
virtual void stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate);
|
||||
virtual void controlMainLoopCallback(GCSensorsInfo& sensors);
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* FANLEVELSETTINGS_H_ */
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* FanProfileSettings.cpp
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "FanProfileSettings.h"
|
||||
#include "../GCFanProfile.h"
|
||||
#include "../LCD.h"
|
||||
#include "../GrowControl.h"
|
||||
#include "../GCException.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
FanProfileSettings::FanProfileSettings(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) {
|
||||
}
|
||||
|
||||
FanProfileSettings::~FanProfileSettings() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FanProfileSettings::reset() {
|
||||
itemsStart = 0;
|
||||
cursorPos = 0;
|
||||
}
|
||||
|
||||
void FanProfileSettings::refreshDisplay() {
|
||||
if (items.size() == 0) {
|
||||
items = lcd.getGrowControl().getFanProfiles();
|
||||
}
|
||||
if (lcd.isLCDConnected()) {
|
||||
auto activeProfile = lcd.getGrowControl().getFan1Profile();
|
||||
char buffer[21];
|
||||
lcd.writeLine(0, "Fan Profiles:");
|
||||
for (unsigned t = itemsStart; t < items.size() && t < itemsStart + 3; t++) {
|
||||
auto ai = items.at(t);
|
||||
char cursor = ' ';
|
||||
if (t == itemsStart + cursorPos) {
|
||||
cursor = 0x7e;
|
||||
}
|
||||
char navhint = ' ';
|
||||
if (t == itemsStart && t >0 ) {
|
||||
navhint = '<';
|
||||
} else if (t == itemsStart + 2 && items.size() - itemsStart > 3) {
|
||||
navhint = '>';
|
||||
}
|
||||
char aPosHint1 = ' ';
|
||||
char aPosHint2 = ' ';
|
||||
if (ai == activeProfile) {
|
||||
aPosHint1 = '*';
|
||||
aPosHint2 = '*';
|
||||
}
|
||||
snprintf(buffer, 21, "%c %c%c%.14s%c", navhint, cursor, aPosHint1, ai->getName().c_str(), aPosHint2);
|
||||
lcd.writeLine(t - itemsStart + 1, buffer);
|
||||
}
|
||||
try {
|
||||
lcd.writeLCDBuffer();
|
||||
} catch (GCException &e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FanProfileSettings::buttonStateCallback(uint8_t button, bool state) {
|
||||
if (state) {
|
||||
bool refresh = false;
|
||||
switch (button) {
|
||||
case 0: // enter
|
||||
{
|
||||
unsigned pos = itemsStart + cursorPos;
|
||||
auto pi = items.at(pos);
|
||||
if (lastActiveProfile != pi) {
|
||||
lcd.getGrowControl().setFan1Profile(pi);
|
||||
}
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 1: // up
|
||||
if (cursorPos > 0) {
|
||||
cursorPos--;
|
||||
} else if (cursorPos == 0 && itemsStart > 0) {
|
||||
itemsStart--;
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case 2: // down
|
||||
if (cursorPos < 2) {
|
||||
cursorPos++;
|
||||
} else if (cursorPos == 2 && items.size() - itemsStart > 3) {
|
||||
itemsStart++;
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case 3: // cancel
|
||||
lcd.setActivePage(*parent, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (refresh) {
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FanProfileSettings::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) {
|
||||
}
|
||||
|
||||
void FanProfileSettings::controlMainLoopCallback(GCSensorsInfo& sensors) {
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* FanProfileSettings.h
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef FANPROFILESETTINGS_H_
|
||||
#define FANPROFILESETTINGS_H_
|
||||
|
||||
#include "../LCDPage.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class GCFanProfile;
|
||||
|
||||
class FanProfileSettings: public LCDPage {
|
||||
public:
|
||||
std::vector<GCFanProfile*> items;
|
||||
unsigned itemsStart = 0;
|
||||
unsigned cursorPos = 0;
|
||||
GCFanProfile* lastActiveProfile = nullptr;
|
||||
|
||||
public:
|
||||
FanProfileSettings(LCD& lcd, LCDPage* parent);
|
||||
virtual ~FanProfileSettings();
|
||||
|
||||
virtual void reset();
|
||||
virtual void refreshDisplay();
|
||||
|
||||
virtual void buttonStateCallback(uint8_t button, bool state);
|
||||
virtual void stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate);
|
||||
virtual void controlMainLoopCallback(GCSensorsInfo& sensors);
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* FANPROFILESETTINGS_H_ */
|
||||
@@ -11,21 +11,41 @@
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
FanSettings::FanSettings(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) {
|
||||
FanSettings::FanSettings(LCD& lcd, LCDPage* parent)
|
||||
: LCDPage(lcd, parent), levelSettings(lcd, this)
|
||||
, upperLimitSettings(lcd, this), profileSettings(lcd, this) {
|
||||
items.push_back("Fan Level");
|
||||
items.push_back("Fan Profile");
|
||||
items.push_back("Upper Limit");
|
||||
items.push_back("Back");
|
||||
}
|
||||
|
||||
FanSettings::~FanSettings() {
|
||||
}
|
||||
|
||||
void FanSettings::reset() {
|
||||
itemsStart = 0;
|
||||
cursorPos = 0;
|
||||
}
|
||||
|
||||
void FanSettings::refreshDisplay() {
|
||||
if (lcd.isLCDConnected()) {
|
||||
|
||||
lcd.clearDisplay();
|
||||
char buffer[21];
|
||||
lcd.writeLine(0, "Fan Settings:");
|
||||
lcd.writeLine(1, " ToDo");
|
||||
for (unsigned t = itemsStart; t < items.size() && t < itemsStart + 3; t++) {
|
||||
char cursor = ' ';
|
||||
if (t == itemsStart + cursorPos) {
|
||||
cursor = 0x7e;
|
||||
}
|
||||
char navhint = ' ';
|
||||
if (t == itemsStart && t >0 ) {
|
||||
navhint = '<';
|
||||
} else if (t == itemsStart + 2 && items.size() - itemsStart > 3) {
|
||||
navhint = '>';
|
||||
}
|
||||
snprintf(buffer, 21, "%c %c%-17.17s", navhint, cursor, items.at(t).c_str());
|
||||
lcd.writeLine(t - itemsStart + 1, buffer);
|
||||
}
|
||||
try {
|
||||
lcd.writeLCDBuffer();
|
||||
} catch (GCException &e) {
|
||||
@@ -35,7 +55,53 @@ void FanSettings::refreshDisplay() {
|
||||
|
||||
void FanSettings::buttonStateCallback(uint8_t button, bool state) {
|
||||
if (state) {
|
||||
lcd.setActivePage(*parent);
|
||||
bool refresh = false;
|
||||
switch (button) {
|
||||
case 0: // enter
|
||||
switch (itemsStart + cursorPos) {
|
||||
case 0: // Fan Settings
|
||||
lcd.setActivePage(levelSettings, true);
|
||||
break;
|
||||
case 1: // Profiles
|
||||
lcd.setActivePage(profileSettings, true);
|
||||
break;
|
||||
case 2: // Upper Limit
|
||||
lcd.setActivePage(upperLimitSettings, true);
|
||||
break;
|
||||
case 3: // back
|
||||
lcd.setActivePage(*parent, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: // up
|
||||
if (cursorPos > 0) {
|
||||
cursorPos--;
|
||||
refresh = true;
|
||||
} else if (cursorPos == 0 && itemsStart > 0) {
|
||||
itemsStart--;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 2: // down
|
||||
if (cursorPos < 2 && cursorPos < items.size() - 1 ) {
|
||||
cursorPos++;
|
||||
refresh = true;
|
||||
} else if (cursorPos == 2 && items.size() - itemsStart > 3) {
|
||||
itemsStart++;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 3: // cancel
|
||||
lcd.setActivePage(*parent, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (refresh) {
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,23 @@
|
||||
#define FANSETTINGS_H_
|
||||
|
||||
#include "../LCDPage.h"
|
||||
#include "FanLevelSettings.h"
|
||||
#include "FanUpperLimitSettings.h"
|
||||
#include "FanProfileSettings.h"
|
||||
#include <string>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class FanSettings : public LCDPage {
|
||||
private:
|
||||
std::vector<std::string> items;
|
||||
unsigned itemsStart = 0;
|
||||
unsigned cursorPos = 0;
|
||||
|
||||
FanLevelSettings levelSettings;
|
||||
FanUpperLimitSettings upperLimitSettings;
|
||||
FanProfileSettings profileSettings;
|
||||
|
||||
public:
|
||||
FanSettings(LCD& lcd, LCDPage* parent);
|
||||
virtual ~FanSettings();
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* FanUpperLimitSettings.cpp
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#include "FanUpperLimitSettings.h"
|
||||
#include "../LCD.h"
|
||||
#include "../GrowControl.h"
|
||||
#include "../GCException.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
FanUpperLimitSettings::FanUpperLimitSettings(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) {
|
||||
}
|
||||
|
||||
FanUpperLimitSettings::~FanUpperLimitSettings() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FanUpperLimitSettings::reset() {
|
||||
itemsStart = 0;
|
||||
cursorPos = 0;
|
||||
}
|
||||
|
||||
void FanUpperLimitSettings::refreshDisplay() {
|
||||
if (items.size() == 0) {
|
||||
for (unsigned t = 1; t <= lcd.getGrowControl().getFan1Max(); t++) {
|
||||
std::ostringstream ss;
|
||||
ss << t;
|
||||
items.push_back(ss.str());
|
||||
}
|
||||
}
|
||||
if (lcd.isLCDConnected()) {
|
||||
activePos = lcd.getGrowControl().getFan1UpperLimit() - 1;
|
||||
char buffer[21];
|
||||
lcd.writeLine(0, "Fan Upper Limit:");
|
||||
for (unsigned t = itemsStart; t < items.size() && t < itemsStart + 3; t++) {
|
||||
char cursor = ' ';
|
||||
if (t == itemsStart + cursorPos) {
|
||||
cursor = 0x7e;
|
||||
}
|
||||
char navhint = ' ';
|
||||
if (t == itemsStart && t >0 ) {
|
||||
navhint = '<';
|
||||
} else if (t == itemsStart + 2 && items.size() - itemsStart > 3) {
|
||||
navhint = '>';
|
||||
}
|
||||
char aPosHint1 = ' ';
|
||||
char aPosHint2 = ' ';
|
||||
if (t == activePos) {
|
||||
aPosHint1 = '*';
|
||||
aPosHint2 = '*';
|
||||
}
|
||||
snprintf(buffer, 21, "%c %c%c%.14s%c", navhint, cursor, aPosHint1, items.at(t).c_str(), aPosHint2);
|
||||
lcd.writeLine(t - itemsStart + 1, buffer);
|
||||
}
|
||||
try {
|
||||
lcd.writeLCDBuffer();
|
||||
} catch (GCException &e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FanUpperLimitSettings::buttonStateCallback(uint8_t button, bool state) {
|
||||
if (state) {
|
||||
bool refresh = false;
|
||||
switch (button) {
|
||||
case 0: // enter
|
||||
{
|
||||
unsigned pos = itemsStart + cursorPos;
|
||||
if (pos != activePos) {
|
||||
lcd.getGrowControl().setFan1UpperLimit(pos+1);
|
||||
}
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 1: // up
|
||||
if (cursorPos > 0) {
|
||||
cursorPos--;
|
||||
} else if (cursorPos == 0 && itemsStart > 0) {
|
||||
itemsStart--;
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case 2: // down
|
||||
if (cursorPos < 2) {
|
||||
cursorPos++;
|
||||
} else if (cursorPos == 2 && items.size() - itemsStart > 3) {
|
||||
itemsStart++;
|
||||
}
|
||||
refresh = true;
|
||||
break;
|
||||
case 3: // cancel
|
||||
lcd.setActivePage(*parent, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (refresh) {
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FanUpperLimitSettings::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) {
|
||||
}
|
||||
|
||||
void FanUpperLimitSettings::controlMainLoopCallback(GCSensorsInfo& sensors) {
|
||||
}
|
||||
|
||||
} /* namespace growcontrol */
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* FanUpperLimitSettings.h
|
||||
*
|
||||
* Created on: 18.06.2014
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef FanUpperLimitSettings_H_
|
||||
#define FanUpperLimitSettings_H_
|
||||
|
||||
#include "../LCDPage.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
class FanUpperLimitSettings: public LCDPage {
|
||||
private:
|
||||
std::vector<std::string> items;
|
||||
unsigned itemsStart = 0;
|
||||
unsigned cursorPos = 0;
|
||||
unsigned lastUpperLimit = 0;
|
||||
unsigned activePos = 0;
|
||||
|
||||
public:
|
||||
FanUpperLimitSettings(LCD& lcd, LCDPage* parent);
|
||||
virtual ~FanUpperLimitSettings();
|
||||
|
||||
virtual void reset();
|
||||
virtual void refreshDisplay();
|
||||
|
||||
virtual void buttonStateCallback(uint8_t button, bool state);
|
||||
virtual void stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate);
|
||||
virtual void controlMainLoopCallback(GCSensorsInfo& sensors);
|
||||
};
|
||||
|
||||
} /* namespace growcontrol */
|
||||
|
||||
#endif /* FanUpperLimitSettings_H_ */
|
||||
+37
-18
@@ -7,7 +7,14 @@
|
||||
|
||||
#include "MainPage.h"
|
||||
#include "../GrowControl.h"
|
||||
#include "../GCFanProfile.h"
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
|
||||
namespace growcontrol {
|
||||
|
||||
@@ -71,9 +78,6 @@ void MainPage::controlMainLoopCallback(GCSensorsInfo& sensors) {
|
||||
snprintf(temp1, 21, "%4.2lf%cC", sensors.temp1.value, 0xdf);
|
||||
} else {
|
||||
switch (sensors.temp1.error.getErrorCode()) {
|
||||
case GCErrorCode::SENSOR_DISCONNECTED:
|
||||
snprintf(temp1, 21, "DISCON");
|
||||
break;
|
||||
default:
|
||||
snprintf(temp1, 21, " ERROR");
|
||||
break;
|
||||
@@ -84,9 +88,6 @@ void MainPage::controlMainLoopCallback(GCSensorsInfo& sensors) {
|
||||
snprintf(temp2, 21, "%4.2lf%cC", sensors.temp2.value, 0xdf);
|
||||
} else {
|
||||
switch (sensors.temp2.error.getErrorCode()) {
|
||||
case GCErrorCode::SENSOR_DISCONNECTED:
|
||||
snprintf(temp2, 21, "DISCON");
|
||||
break;
|
||||
default:
|
||||
snprintf(temp2, 21, " ERROR");
|
||||
break;
|
||||
@@ -97,33 +98,51 @@ void MainPage::controlMainLoopCallback(GCSensorsInfo& sensors) {
|
||||
snprintf(hum1, 21, "%4.1lf%% ", sensors.hum1.value);
|
||||
} else {
|
||||
switch (sensors.hum1.error.getErrorCode()) {
|
||||
case GCErrorCode::SENSOR_DISCONNECTED:
|
||||
snprintf(hum1, 21, "DISCON");
|
||||
break;
|
||||
default:
|
||||
snprintf(hum1, 21, "ERROR ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fan1
|
||||
if (sensors.fan1.valid) {
|
||||
snprintf(fan1, 21, "ToDo");
|
||||
if (sensors.fan1Level.valid) {
|
||||
std::ostringstream ss;
|
||||
if (sensors.fan1Level.value == 0) {
|
||||
ss << "off";
|
||||
} else {
|
||||
ss << sensors.fan1Level.value;
|
||||
}
|
||||
if (sensors.fan1AutoMode) {
|
||||
auto profile = lcd.getGrowControl().getFan1Profile();
|
||||
if (profile == nullptr) {
|
||||
ss << " (Auto?)";
|
||||
} else {
|
||||
ss << " (" << profile->getName() << ")";
|
||||
}
|
||||
} else {
|
||||
ss << " (Manual)";
|
||||
}
|
||||
std::string fanString = ss.str();
|
||||
snprintf(fan1, 21, fanString.c_str());
|
||||
} else {
|
||||
switch (sensors.fan1.error.getErrorCode()) {
|
||||
case GCErrorCode::SENSOR_DISCONNECTED:
|
||||
snprintf(fan1, 21, "DISCON");
|
||||
break;
|
||||
switch (sensors.fan1Level.error.getErrorCode()) {
|
||||
default:
|
||||
snprintf(fan1, 21, " ERROR");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// date
|
||||
std::chrono::system_clock::time_point test;
|
||||
auto time = std::chrono::system_clock::to_time_t(sensors.timestamp);
|
||||
auto ltime = std::localtime(&time);
|
||||
strftime(buffer[0], 20, " %d.%m.%y %H:%M:%S ", ltime );
|
||||
// line 0
|
||||
snprintf(buffer[1], 21, "T: %7.7s %7.7s ", temp1, temp2);
|
||||
// line 1
|
||||
snprintf(buffer[0], 21, "T: %7.7s %7.7s ", temp1, temp2);
|
||||
snprintf(buffer[1], 21, "T: %7.7s %7.7s ", temp1, temp2);
|
||||
// line 2
|
||||
snprintf(buffer[1], 21, "Humidity: %5.5s ", hum1);
|
||||
snprintf(buffer[2], 21, "Humidity: %5.5s ", hum1);
|
||||
// line 3
|
||||
snprintf(buffer[2], 21, "Fan: %-15.15s", fan1);
|
||||
snprintf(buffer[3], 21, "Fan: %-15.15s", fan1);
|
||||
|
||||
refreshDisplay();
|
||||
}
|
||||
|
||||
@@ -3,4 +3,7 @@ SRC_FILES += src/lcdpages/MainPage.cpp \
|
||||
src/lcdpages/MainMenu.cpp \
|
||||
src/lcdpages/AboutPage.cpp \
|
||||
src/lcdpages/FanSettings.cpp \
|
||||
src/lcdpages/PCSettings.cpp
|
||||
src/lcdpages/PCSettings.cpp \
|
||||
src/lcdpages/FanLevelSettings.cpp \
|
||||
src/lcdpages/FanUpperLimitSettings.cpp \
|
||||
src/lcdpages/FanProfileSettings.cpp
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ using namespace growcontrol;
|
||||
static log4cpp::Category& logger = log4cpp::Category::getInstance("growcontrol");
|
||||
|
||||
std::string pidFile = "/var/run/growcontrold.pid";
|
||||
std::string socketPath = "/var/run/growcontrol.socket";
|
||||
std::string socketPath = "/opt/growcontrol/growcontrold.socket";
|
||||
std::string log4cppConfig = "log4cpp.config";
|
||||
std::string host = "localhost";
|
||||
uint16_t port = 4223;
|
||||
|
||||
Reference in New Issue
Block a user