From ae0b6fdcd003a45b1d36818609551b851f30c547 Mon Sep 17 00:00:00 2001 From: matzman Date: Mon, 16 Jun 2014 11:22:51 +0200 Subject: [PATCH] Initial commit. --- .cproject | 107 ++++++++++++++ .hgignore | 4 + .project | 28 ++++ .settings/language.settings.xml | 15 ++ Makefile | 29 ++++ Makefile.local | 29 ++++ src/GCException.h | 37 +++++ src/GrowControl.cpp | 251 ++++++++++++++++++++++++++++++++ src/GrowControl.h | 79 ++++++++++ src/IPCManager.cpp | 156 ++++++++++++++++++++ src/IPCManager.h | 47 ++++++ src/LCD.cpp | 182 +++++++++++++++++++++++ src/LCD.h | 65 +++++++++ src/LCDPage.h | 39 +++++ src/config.mk | 7 + src/lcdpages/AboutPage.cpp | 52 +++++++ src/lcdpages/AboutPage.h | 31 ++++ src/lcdpages/FanSettings.cpp | 48 ++++++ src/lcdpages/FanSettings.h | 31 ++++ src/lcdpages/MainMenu.cpp | 113 ++++++++++++++ src/lcdpages/MainMenu.h | 44 ++++++ src/lcdpages/MainPage.cpp | 133 +++++++++++++++++ src/lcdpages/MainPage.h | 35 +++++ src/lcdpages/PCSettings.cpp | 49 +++++++ src/lcdpages/PCSettings.h | 31 ++++ src/lcdpages/config.mk | 6 + src/main.cpp | 37 +++++ 27 files changed, 1685 insertions(+) create mode 100644 .cproject create mode 100644 .hgignore create mode 100644 .project create mode 100644 .settings/language.settings.xml create mode 100644 Makefile create mode 100644 Makefile.local create mode 100644 src/GCException.h create mode 100644 src/GrowControl.cpp create mode 100644 src/GrowControl.h create mode 100644 src/IPCManager.cpp create mode 100644 src/IPCManager.h create mode 100644 src/LCD.cpp create mode 100644 src/LCD.h create mode 100644 src/LCDPage.h create mode 100644 src/config.mk create mode 100644 src/lcdpages/AboutPage.cpp create mode 100644 src/lcdpages/AboutPage.h create mode 100644 src/lcdpages/FanSettings.cpp create mode 100644 src/lcdpages/FanSettings.h create mode 100644 src/lcdpages/MainMenu.cpp create mode 100644 src/lcdpages/MainMenu.h create mode 100644 src/lcdpages/MainPage.cpp create mode 100644 src/lcdpages/MainPage.h create mode 100644 src/lcdpages/PCSettings.cpp create mode 100644 src/lcdpages/PCSettings.h create mode 100644 src/lcdpages/config.mk create mode 100644 src/main.cpp diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..aa0ec40 --- /dev/null +++ b/.cproject @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + make + + all + true + true + true + + + make + + clean + true + true + true + + + + + + + + + + + + + + diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..97fe582 --- /dev/null +++ b/.hgignore @@ -0,0 +1,4 @@ +syntax: regexp + +^bin/ +^build/ diff --git a/.project b/.project new file mode 100644 index 0000000..edb08c1 --- /dev/null +++ b/.project @@ -0,0 +1,28 @@ + + + growcontrold + + + TinkerforgeCPPsimple + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..c0a722d --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fb7e899 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ + +include Makefile.local + +SRC_FILES = + +include src/config.mk + +OBJS = $(SRC_FILES:src/%.cpp=build/%.o) + +all : bin/growcontrold + +bin : + mkdir -p bin + +build : + mkdir -p build + +bin/growcontrold : bin $(OBJS) + $(CXX) $(LD_FLAGS) $(OBJS) $(LD_LIBS) -o $@ + +$(OBJS) : build/%.o : src/%.cpp + mkdir -p $(dir $@) + $(CXX) $(CXX_FLAGS) $(CXX_INCL) -c $< -o $@ + +clean : + rm -rf build + +distclean : clean + rm -rf bin diff --git a/Makefile.local b/Makefile.local new file mode 100644 index 0000000..5aeb27c --- /dev/null +++ b/Makefile.local @@ -0,0 +1,29 @@ + + + +CXX_FLAGS = -O0 -g3 -Wall -std=c++11 +CXX_INCL = -I ../TinkerforgeCPPsimple/include -I ../TinkerforgeCPPsimple/third-party/tinkerforge/include -I ../TinkerforgeCPPsimple/third-party/log4cpp/include -I /usr/include + +LD_FLAGS = -pthread +LD_LIBS = -L ../TinkerforgeCPPsimple/lib -ltfcppsimple -ltinkerforge -llog4cpp + + +GCC_HOME = +GCC_PREFIX = + +GCC = ${GCC_PREFIX}-gcc +CXX = ${GCC_PREFIX}-g++ +CPP = ${GCC_PREFIX}-cpp +AR = ${GCC_PREFIX}-ar +OBJDUMP = ${GCC_PREFIX}-objdump +RANLIB = ${GCC_PREFIX}-ranlib +SIZE = ${GCC_PREFIX}-size + +#GCC = ${GCC_HOME}/bin/${GCC_PREFIX}-gcc +#CXX = ${GCC_HOME}/bin/${GCC_PREFIX}-g++ +#CPP = ${GCC_HOME}/bin/${GCC_PREFIX}-cpp +#AR = ${GCC_HOME}/bin/${GCC_PREFIX}-ar +#OBJDUMP = ${GCC_HOME}/bin/${GCC_PREFIX}-objdump +#RANLIB = ${GCC_HOME}/bin/${GCC_PREFIX}-ranlib +#SIZE = ${GCC_HOME}/bin/${GCC_PREFIX}-size + diff --git a/src/GCException.h b/src/GCException.h new file mode 100644 index 0000000..7bfab71 --- /dev/null +++ b/src/GCException.h @@ -0,0 +1,37 @@ +/* + * GCException.h + * + * Created on: 14.06.2014 + * Author: matzman + */ + +#ifndef GCEXCEPTION_H_ +#define GCEXCEPTION_H_ + +#include + +enum class GCErrorCode : int { + NO_ERROR, + NO_SENSOR, + SENSOR_DISCONNECTED, + UNKNOWN_TFERROR, + NOT_INITIALIZED, + OTHER_ERROR +}; + +class GCException : public std::runtime_error { +protected: + GCErrorCode errorCode; + +public: + GCException() + : std::runtime_error(""), errorCode(GCErrorCode::NO_ERROR) {} + GCException(std::string msg, GCErrorCode errorCode) + : std::runtime_error(msg), errorCode(errorCode) {} + virtual ~GCException() {} + + GCErrorCode getErrorCode() { return errorCode; } +}; + + +#endif /* GCEXCEPTION_H_ */ diff --git a/src/GrowControl.cpp b/src/GrowControl.cpp new file mode 100644 index 0000000..763ff5d --- /dev/null +++ b/src/GrowControl.cpp @@ -0,0 +1,251 @@ +/* + * GrowControl.cpp + * + * Created on: 14.06.2014 + * Author: matzman + */ + +#include "GrowControl.h" +#include +#include +#include +#include + +namespace growcontrol { + +log4cpp::Category& GrowControl::logger = log4cpp::Category::getInstance("growcontrol"); + +GrowControl::GrowControl() { +} + +GrowControl::~GrowControl() { +} + +bool GrowControl::connect(std::string host , uint16_t port, bool retry) { + tfConnection.addListener(*this); + bool breakFlag = false; + do { + try { + tfConnection.connect(host, port); + breakFlag = true; + } catch (TfError &e) { + logger << log4cpp::Priority::ERROR << "Error while connecting to brickd: " << e.what(); + } + if (!breakFlag) { + logger << log4cpp::Priority::ERROR << "Waiting for 3 sec before retrying."; + sleep(3); + } else { + logger << log4cpp::Priority::INFO << "Successfully connected to brickd (" + << tfConnection.getHost() << ":" << tfConnection.getPort() << ")."; + } + } while (retry && !breakFlag); + return breakFlag; +} + +void GrowControl::newDeviceCallback(TfConnection& conn, TfDevice& device) { + std::lock_guard lock(controlMutex); + switch (device.getDeviceIdentifier()) { + case TfDeviceIdentifier::MASTER: + if ( (rootBrick == nullptr || rootBrick->getDeviceState() != TfDeviceState::CONNECTED) + && device.getDeviceState() == TfDeviceState::AVAILABLE && device.getParent() == nullptr ) { + rootBrick = (TfMasterBrick*)&device; + rootBrick->connect(); + logger << log4cpp::Priority::INFO << "Added root device " << device.getDeviceName(true) << "."; + } + break; + case TfDeviceIdentifier::TEMPERATURE: + { + int prioT1 = 10000; + int prioT2 = 10000; + int prioNew = 10000; + if (temp1Bricklet != nullptr && temp1Bricklet->getDeviceState() == TfDeviceState::CONNECTED) { + char pPos = ((char)temp1Bricklet->getParent()->getPosition()) - ((char)TfDevicePosition::BRICK0); + char pos = ((char)temp1Bricklet->getPosition()) - ((char)TfDevicePosition::BRICKLET0); + prioT1 = (pPos * 5 + pos); + } + if (temp2Bricklet != nullptr && temp2Bricklet->getDeviceState() == TfDeviceState::CONNECTED) { + char pPos = ((char)temp2Bricklet->getParent()->getPosition()) - ((char)TfDevicePosition::BRICK0); + char pos = ((char)temp2Bricklet->getPosition()) - ((char)TfDevicePosition::BRICKLET0); + prioT2 = (pPos * 5 + pos); + } + if (device.getDeviceState() == TfDeviceState::AVAILABLE) { + char pPos = ((char)device.getParent()->getPosition()) - ((char)TfDevicePosition::BRICK0); + char pos = ((char)device.getPosition()) - ((char)TfDevicePosition::BRICKLET0); + prioNew = (pPos * 5 + pos); + } + if (prioNew < 10000) { // new device is alive + if (prioNew < prioT1) { // new device has lower priority than current temp1 + if (prioT1 < 10000) { // current temp1 is alive and is moved to temp2 + temp2Bricklet = temp1Bricklet; + logger << log4cpp::Priority::INFO << "Moving temp1 to temp2."; + } + temp1Bricklet = (TfTemperatureBricklet*)&device; + temp1Bricklet->connect(); + logger << log4cpp::Priority::INFO << "Added temp1 device" << device.getDeviceName(true) << "."; + } else if (prioNew < prioT2) { // new device has lower priority than current temp2 + temp2Bricklet = (TfTemperatureBricklet*)&device; + temp2Bricklet->connect(); + logger << log4cpp::Priority::INFO << "Added temp2 device " << device.getDeviceName(true) << "."; + } + } + break; + } + case TfDeviceIdentifier::HUMIDITY: + if ( (hum1Bricklet == nullptr || hum1Bricklet->getDeviceState() != TfDeviceState::CONNECTED) + && device.getDeviceState() == TfDeviceState::AVAILABLE ) { + hum1Bricklet = (TfHumidityBricklet*)&device; + hum1Bricklet->connect(); + logger << log4cpp::Priority::INFO << "Added hum1 device " << device.getDeviceName(true) << "."; + } + break; + case TfDeviceIdentifier::IO16: + if ( (io16Bricklet == nullptr || io16Bricklet->getDeviceState() != TfDeviceState::CONNECTED) + && device.getDeviceState() == TfDeviceState::AVAILABLE ) { + io16Bricklet = (TfIO16Bricklet*)&device; + io16Bricklet->connect(); + logger << log4cpp::Priority::INFO << "Added io16 device " << device.getDeviceName(true) << "."; + } + break; + case TfDeviceIdentifier::LCD20x4: + lcd.setTfObject((TfLCD20x4Bricklet&)device); + break; + default: + break; + } +} + +void GrowControl::shutdownCallback() { + std::lock_guard lock(controlMutex); +} + +double GrowControl::getTemp1() { + std::lock_guard lock(controlMutex); + double ret = 0; + if (temp1Bricklet != nullptr) { + if (temp1Bricklet->getDeviceState() == TfDeviceState::CONNECTED) { + try { + ret = ((double)temp1Bricklet->getTemperature())/100.0; + } catch (TfError &e) { + std::ostringstream ss; + ss << "unknown exception while getting temp1: " << e.what(); + throw GCException(ss.str(), GCErrorCode::UNKNOWN_TFERROR); + } + } else { + throw GCException("temp1 sensor not connected.", GCErrorCode::SENSOR_DISCONNECTED); + } + } else { + throw GCException("No temp1 sensor present.", GCErrorCode::NO_SENSOR); + } + return ret; +} + +double GrowControl::getTemp2() { + std::lock_guard lock(controlMutex); + double ret = 0; + if (temp2Bricklet != nullptr) { + if (temp2Bricklet->getDeviceState() == TfDeviceState::CONNECTED) { + try { + ret = ((double)temp2Bricklet->getTemperature())/100.0; + } catch (TfError &e) { + std::ostringstream ss; + ss << "unknown exception while getting temp2: " << e.what(); + throw GCException(ss.str(), GCErrorCode::UNKNOWN_TFERROR); + } + } else { + throw GCException("temp2 sensor not connected.", GCErrorCode::SENSOR_DISCONNECTED); + } + } else { + throw GCException("No temp2 sensor present.", GCErrorCode::NO_SENSOR); + } + return ret; +} + +double GrowControl::getHum1() { + std::lock_guard lock(controlMutex); + double ret = 0; + if (hum1Bricklet != nullptr) { + if (hum1Bricklet->getDeviceState() == TfDeviceState::CONNECTED) { + try { + ret = ((double)hum1Bricklet->getHumidity())/10.0; + } catch (TfError &e) { + std::ostringstream ss; + ss << "unknown exception while getting hum1: " << e.what(); + throw GCException(ss.str(), GCErrorCode::UNKNOWN_TFERROR); + } + } else { + throw GCException("hum1 sensor not connected.", GCErrorCode::SENSOR_DISCONNECTED); + } + } else { + throw GCException("No hum1 sensor present.", GCErrorCode::NO_SENSOR); + } + return ret; +} + +int GrowControl::getFan1() { + std::lock_guard lock(controlMutex); + int ret = 0; + if (hum1Bricklet != nullptr) { + if (hum1Bricklet->getDeviceState() == TfDeviceState::CONNECTED) { + try { + // ToDo + throw GCException("Fan not implemented yet.", GCErrorCode::NOT_INITIALIZED); + } catch (TfError &e) { + std::ostringstream ss; + ss << "unknown exception while getting fan1: " << e.what(); + throw GCException(ss.str(), GCErrorCode::UNKNOWN_TFERROR); + } + } else { + throw GCException("fan1 not connected.", GCErrorCode::SENSOR_DISCONNECTED); + } + } else { + throw GCException("No fan1 present.", GCErrorCode::NO_SENSOR); + } + return ret; +} + + +void GrowControl::mainLoop() { + + while (mainLoopFlag) { + + // Fetch sensor values + GCSensorsInfo sensorValues; + try { + sensorValues.temp1.value = getTemp1(); + sensorValues.temp1.valid = true; + } catch (GCException &e) { + sensorValues.temp1.valid = false; + sensorValues.temp1.error = e; + } + try { + sensorValues.temp2.value = getTemp2(); + sensorValues.temp2.valid = true; + } catch (GCException &e) { + sensorValues.temp2.valid = false; + sensorValues.temp2.error = e; + } + try { + sensorValues.hum1.value = getHum1(); + sensorValues.hum1.valid = true; + } catch (GCException &e) { + sensorValues.hum1.valid = false; + sensorValues.hum1.error = e; + } + try { + sensorValues.fan1.value = getFan1(); + sensorValues.fan1.valid = true; + } catch (GCException &e) { + sensorValues.fan1.valid = false; + sensorValues.fan1.error = e; + } + + lcd.controlMainLoopCallback(sensorValues); + + sleep(sleepDuration); + } + +} + + + +} /* namespace growcontrol */ diff --git a/src/GrowControl.h b/src/GrowControl.h new file mode 100644 index 0000000..23fad8a --- /dev/null +++ b/src/GrowControl.h @@ -0,0 +1,79 @@ +/* + * GrowControl.h + * + * Created on: 14.06.2014 + * Author: matzman + */ + +#ifndef GROWCONTROL_H_ +#define GROWCONTROL_H_ + +#include +#include "GCException.h" +#include +#include +#include "LCD.h" + +using namespace tfcppsimple; + +namespace growcontrol { + + +template +struct CGSensorValue { + T value; + bool valid = false; + GCException error; +}; + +struct GCSensorsInfo { + CGSensorValue temp1; + CGSensorValue temp2; + CGSensorValue hum1; + CGSensorValue fan1; +}; + + +class GrowControl : public TfConnectionListener { +private: + + static log4cpp::Category& logger; + + LCD lcd; + + TfConnection tfConnection; + TfMasterBrick* rootBrick = nullptr; + TfTemperatureBricklet* temp1Bricklet = nullptr; + TfTemperatureBricklet* temp2Bricklet = nullptr; + TfHumidityBricklet* hum1Bricklet = nullptr; + TfIO16Bricklet* io16Bricklet = nullptr; + + std::mutex controlMutex; + unsigned int sleepDuration = 1; + bool mainLoopFlag = true; + + + +public: + GrowControl(); + virtual ~GrowControl(); + + bool connect(std::string host , uint16_t port, bool retry = true); + + void newDeviceCallback(TfConnection& conn, TfDevice& device); + void shutdownCallback(); + + void mainLoop(); + + double getTemp1(); + + double getTemp2(); + + double getHum1(); + + int getFan1(); +}; + +} /* namespace growcontrol */ + +#endif /* GROWCONTROL_H_ */ diff --git a/src/IPCManager.cpp b/src/IPCManager.cpp new file mode 100644 index 0000000..41d0a24 --- /dev/null +++ b/src/IPCManager.cpp @@ -0,0 +1,156 @@ +/* + * IPCManager.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "IPCManager.h" +#include "GCException.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace growcontrol { + +log4cpp::Category& IPCManager::logger = log4cpp::Category::getInstance("growcontrol.ipc"); + +void IPCManager::listenerThreadFunc(IPCManager* obj) { + logger << log4cpp::Priority::INFO << "Starting ipc listener."; + while(obj->listenerThreadFlag) { + int cSocketFD; + // accept connection + if ((cSocketFD = accept(obj->socketFD, nullptr, nullptr)) == -1) { + perror("Error while trying to accept incoming connection"); + logger << log4cpp::Priority::ERROR << "Error while trying to accept incoming connection"; + } else { + logger << log4cpp::Priority::INFO << "Successfully accepted new ipc connection."; + // Now we create a new thread that handles the established connection + std::thread* handleThread = new std::thread(workerThreadFunc, obj, cSocketFD, handleThread); + obj->workerThreads.insert(handleThread); + } + } +} + +void IPCManager::workerThreadFunc(IPCManager* obj, int socket, std::thread* self) { + // To something + bool loopFlag = true; + while (loopFlag) { + char buffer[100]; + std::string response; + // Receive command + int rsize = recv(socket, buffer, sizeof(buffer), 0); + if (rsize == 0) { // Connection closed + 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."; + loopFlag = false; + } else { + // Check if '\0' appears in command (our end-of-command) + int msglen = strnlen(buffer, sizeof(buffer)); + if (msglen <= 0 || msglen >= (int)sizeof(buffer)) { + logger << log4cpp::Priority::ERROR << "received faulty ipc data."; + loopFlag = false; + } else { + // Parse command + std::istringstream commandStream(buffer); + std::string firstPart; + std::getline(commandStream, firstPart, ' '); + std::transform(firstPart.begin(), firstPart.end(), firstPart.begin(), ::toupper); + if (firstPart.compare("GETVAL") == 0) { // get value command (several arguments) + std::vector args; + for (std::string arg; std::getline(commandStream, arg, ' '); ) { + args.push_back(arg); + } + if (args.size() == 0) { + response = "ERROR NO_ARGS"; + } else { + response = obj->handleGetValCommand(args); + } + } else if (firstPart.compare("SET") == 0) { // set command + response = "ERROR TODO"; + } else { + logger << log4cpp::Priority::ERROR << "Received unknown ipc command: " << buffer << "."; + response = "ERROR UNKNOWN_COMMAND"; + } + if (!response.empty()) { + int ssize = send(socket, response.c_str(), response.size() + 1 , 0); + if (ssize <= 0) { + logger << log4cpp::Priority::ERROR << "error while sending ipc response: " << response << "."; + loopFlag = false; + } + } + + } + } + } + // Cleanup resources + close(socket); + obj->workerThreads.erase(self); +} + + +IPCManager::IPCManager() {} + +void IPCManager::init(GrowControl& growControl, std::string socketPath) { + this->growControl = &growControl; + this->socketPath = socketPath; + // Create Socket + if ((socketFD = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + logger << log4cpp::Priority::ERROR << "Could not create socket"; + throw GCException("Could not create socket", GCErrorCode::OTHER_ERROR); + } + // Create address struct + struct sockaddr_un local; + local.sun_family = AF_UNIX; + strncpy(local.sun_path, socketPath.c_str(), sizeof(local.sun_path)); + // Unlink the socket path (remove possible remains?) + unlink(local.sun_path); + // bind socket + if (bind(socketFD, (struct sockaddr *)&local, sizeof(local)) == -1) { + logger << log4cpp::Priority::ERROR << "Could not bind socket"; + 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"; + throw GCException("Could not switch socket to accepting mode", GCErrorCode::OTHER_ERROR); + } + logger << log4cpp::Priority::INFO << "Successfully created new ipc socket " << socketPath << "."; + listenerThreadFlag = true; + listenerThread = new std::thread(listenerThreadFunc, this); +} + +IPCManager::~IPCManager() { + if (socketFD > 0) { + close(socketFD); + unlink(socketPath.c_str()); + } + if (listenerThread != nullptr) { + listenerThreadFlag = false; + listenerThread->join(); + delete listenerThread; + } + std::set workers(workerThreads); + for (auto w : workers) { + w->join(); + delete w; + } + +} + + +std::string IPCManager::handleGetValCommand(std::vector args) { + return "ERROR TODO"; +} + + +} /* namespace growcontrol */ diff --git a/src/IPCManager.h b/src/IPCManager.h new file mode 100644 index 0000000..13081e5 --- /dev/null +++ b/src/IPCManager.h @@ -0,0 +1,47 @@ +/* + * IPCManager.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef IPCMANAGER_H_ +#define IPCMANAGER_H_ + +#include +#include +#include +#include + +namespace growcontrol { + +class GrowControl; + +class IPCManager { +private: + static log4cpp::Category& logger; + + GrowControl* growControl = nullptr; + + std::string socketPath; + int socketFD = -1; + std::thread* listenerThread = nullptr; + bool listenerThreadFlag = false; + std::set workerThreads; + +public: + IPCManager(); + virtual ~IPCManager(); + + void init(GrowControl& growControl, std::string socketPath); + + static void listenerThreadFunc(IPCManager* obj); + + static void workerThreadFunc(IPCManager* obj, int socket, std::thread* self); + + std::string handleGetValCommand(std::vector args); +}; + +} /* namespace growcontrol */ + +#endif /* IPCMANAGER_H_ */ diff --git a/src/LCD.cpp b/src/LCD.cpp new file mode 100644 index 0000000..67d28a9 --- /dev/null +++ b/src/LCD.cpp @@ -0,0 +1,182 @@ +/* + * LCD.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "LCD.h" +#include "GCException.h" + +namespace growcontrol { + +log4cpp::Category& LCD::logger = log4cpp::Category::getInstance("growcontrol"); + +LCD::LCD() : pageRoot(*this) { + activePage = &pageRoot; + for (int t = 0; t < 4; t++) { + for (int i = 0; i < 20; i++) { + lcdBuffer[t][i] = ' '; + } + } + lcdBuffer[0][20] = '\0'; + lcdBuffer[1][20] = '\0'; + lcdBuffer[2][20] = '\0'; + lcdBuffer[3][20] = '\0'; +} + +LCD::~LCD() { +} + +bool LCD::isLCDConnected() { + return (lcdBricklet != nullptr && lcdBricklet->getDeviceState() == TfDeviceState::CONNECTED); +} + +void LCD::startLightCountdown() { + if (!lcdLightCountdownFlag) { + lcdLightCountdown = lcdLightMaxCountdown; + lcdLightCountdownFlag = true; + } +} + +void LCD::stopLightCountdown() { + lcdLightCountdownFlag = false; +} + +void LCD::resetLightCountdown() { + lcdLightCountdown = lcdLightMaxCountdown; +} + +void LCD::setLight(bool light) { + if (!light) { + stopLightCountdown(); + activePage = &pageRoot; + activePage->refreshDisplay(); + lcdLightCountdown = -1; + if (lcdBricklet != nullptr && lcdBricklet->getDeviceState() == TfDeviceState::CONNECTED) { + lcdBricklet->setBacklight(false); + } + } else { + startLightCountdown(); + if (lcdBricklet != nullptr && lcdBricklet->getDeviceState() == TfDeviceState::CONNECTED) { + lcdBricklet->setBacklight(true); + } + } +} + +void LCD::setTfObject(TfLCD20x4Bricklet& lcd) { + if ( (lcdBricklet == nullptr || lcdBricklet->getDeviceState() != TfDeviceState::CONNECTED) + && lcd.getDeviceState() == TfDeviceState::AVAILABLE ) { + if (lcdBricklet != nullptr) { + lcdBricklet->removeLcdListener(*this); + } + lcdBricklet = &lcd; + lcdBricklet->addLcdListener(*this); + lcdBricklet->connect(); + setLight(true); + lcdBricklet->setCursor(false, false); + lcdBricklet->clearDisplay(); + if (activePage != nullptr) { + activePage->refreshDisplay(); + } + logger << log4cpp::Priority::INFO << "Added lcd device " << lcd.getDeviceName(true) << "."; + } +} + +void LCD::buttonStateCallback(TfLCD20x4Bricklet& lcd, uint8_t button, bool state) { + if (lcdLightCountdown < 0) { + if (state) { + setLight(true); + } + } else if (&lcd == lcdBricklet && activePage != nullptr) { + resetLightCountdown(); + activePage->buttonStateCallback(button, state); + } +} + + +void LCD::writeLine(int line, std::string txt) { + std::lock_guard lock(lcdMutex); + snprintf(lcdBuffer[line], 21, "%-20.20s", txt.c_str()); + lineFlags[line] = true; +} + + +int LCD::writeLCDBuffer() { + std::lock_guard lock(lcdMutex); + int written = 0; + if (lcdBricklet != nullptr) { + if (lcdBricklet->getDeviceState() == TfDeviceState::CONNECTED) { + try { + for (int t = 0; t < 4; t++) { + if (lineFlags[t] == true) { + lcdBricklet->writeLine(t, 0, lcdBuffer[t]); + lineFlags[t] = false; + written++; + } + } + } catch (TfError &e) { + std::ostringstream ss; + ss << "unknown exception while writing lcd: " << e.what(); + throw GCException(ss.str(), GCErrorCode::UNKNOWN_TFERROR); + } + } else { + throw GCException("lcd not connected.", GCErrorCode::SENSOR_DISCONNECTED); + } + } else { + throw GCException("No lcd present.", GCErrorCode::NO_SENSOR); + } + return written; +} + +void LCD::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) { + if (newstate == TfDeviceState::CONNECTED) { + clearDisplay(); + activePage->refreshDisplay(); + } + if (&device == lcdBricklet && activePage != nullptr) { + activePage->stateChangeCallback(device, oldstate, newstate); + } +} + + +void LCD::setActivePage(LCDPage& page, bool reset) { + activePage = &page; + if (reset) { + page.reset(); + } + clearDisplay(); + page.refreshDisplay(); +} + +void LCD::controlMainLoopCallback(GCSensorsInfo& sensors) { + if (activePage != nullptr) { + activePage->controlMainLoopCallback(sensors); + } + if (lcdLightCountdownFlag && lcdLightCountdown > 0) { + lcdLightCountdown--; + } else if (lcdLightCountdownFlag && lcdLightCountdown == 0) { + setLight(false); + } +} + +void LCD::clearDisplay() { + for (int t = 0; t < 4; t++) { + for (int i = 0; i < 20; i++) { + lcdBuffer[t][i] = ' '; + } + } + lcdBuffer[0][20] = '\0'; + lcdBuffer[1][20] = '\0'; + lcdBuffer[2][20] = '\0'; + lcdBuffer[3][20] = '\0'; + if (isLCDConnected()) { + try { + lcdBricklet->clearDisplay(); + } catch (TfError &e) { + } + } +} + + +} /* namespace growcontrol */ diff --git a/src/LCD.h b/src/LCD.h new file mode 100644 index 0000000..d8b03ce --- /dev/null +++ b/src/LCD.h @@ -0,0 +1,65 @@ +/* + * LCD.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef LCD_H_ +#define LCD_H_ + +#include "TfCPPsimple.h" +#include "lcdpages/MainPage.h" +#include + + +using namespace tfcppsimple; + +namespace growcontrol { + +struct GCSensorsInfo; + +class LCD : public TfLCD20x4Listener, public TfDeviceStateListener { +private: + static log4cpp::Category& logger; + + TfLCD20x4Bricklet* lcdBricklet = nullptr; + + std::mutex lcdMutex; + char lcdBuffer[4][21]; + bool lineFlags[4] = {false, false, false, false}; + int lcdLightCountdown = 0; + int lcdLightMaxCountdown = 10; + bool lcdLightCountdownFlag = false; + LCDPage* activePage = nullptr; + + MainPage pageRoot; + +public: + LCD(); + virtual ~LCD(); + + void setTfObject(TfLCD20x4Bricklet& lcd); + + void buttonStateCallback(TfLCD20x4Bricklet& lcd, uint8_t button, bool state); + void stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate); + + void writeLine(int line, std::string txt); + int writeLCDBuffer(); + void clearDisplay(); + + void setActivePage(LCDPage& page, bool reset = false); + void startLightCountdown(); + void stopLightCountdown(); + void resetLightCountdown(); + void setLight(bool light); + + void controlMainLoopCallback(GCSensorsInfo& sensors); + + bool isLCDConnected(); + +}; + +} /* namespace growcontrol */ + +#endif /* LCD_H_ */ diff --git a/src/LCDPage.h b/src/LCDPage.h new file mode 100644 index 0000000..d205677 --- /dev/null +++ b/src/LCDPage.h @@ -0,0 +1,39 @@ +/* + * LCDPage.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef LCDPAGE_H_ +#define LCDPAGE_H_ + +#include "TfCPPsimple.h" + +using namespace tfcppsimple; + +namespace growcontrol { + +class LCD; +struct GCSensorsInfo; + +class LCDPage { +protected: + LCD& lcd; + LCDPage* parent; + +public: + LCDPage(LCD& lcd, LCDPage* parent = nullptr) : lcd(lcd), parent(parent) {} + virtual ~LCDPage() {} + + virtual void reset() = 0; + virtual void refreshDisplay() = 0; + + virtual void buttonStateCallback(uint8_t button, bool state) = 0; + virtual void stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) = 0; + virtual void controlMainLoopCallback(GCSensorsInfo& sensors) = 0; +}; + +} /* namespace growcontrol */ + +#endif /* LCDPAGE_H_ */ diff --git a/src/config.mk b/src/config.mk new file mode 100644 index 0000000..d2791ed --- /dev/null +++ b/src/config.mk @@ -0,0 +1,7 @@ + +SRC_FILES += src/main.cpp \ + src/GrowControl.cpp \ + src/LCD.cpp \ + src/IPCManager.cpp + +include src/lcdpages/config.mk diff --git a/src/lcdpages/AboutPage.cpp b/src/lcdpages/AboutPage.cpp new file mode 100644 index 0000000..0e2a6a5 --- /dev/null +++ b/src/lcdpages/AboutPage.cpp @@ -0,0 +1,52 @@ +/* + * AboutPage.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "AboutPage.h" +#include "../LCD.h" +#include "../GCException.h" + +namespace growcontrol { + +AboutPage::AboutPage(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) { +} + +AboutPage::~AboutPage() { +} + + + + + +void AboutPage::reset() { +} + +void AboutPage::refreshDisplay() { + if (lcd.isLCDConnected()) { + + lcd.clearDisplay(); + lcd.writeLine(1, " GrowControl v1.0"); + lcd.writeLine(2, " by Matzman, 2014"); + try { + lcd.writeLCDBuffer(); + } catch (GCException &e) { + } + } +} + +void AboutPage::buttonStateCallback(uint8_t button, bool state) { + if (state) { + lcd.setActivePage(*parent); + } +} + +void AboutPage::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) { +} + +void AboutPage::controlMainLoopCallback(GCSensorsInfo& sensors) { +} + +} /* namespace growcontrol */ diff --git a/src/lcdpages/AboutPage.h b/src/lcdpages/AboutPage.h new file mode 100644 index 0000000..9997194 --- /dev/null +++ b/src/lcdpages/AboutPage.h @@ -0,0 +1,31 @@ +/* + * AboutPage.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef ABOUTPAGE_H_ +#define ABOUTPAGE_H_ + +#include "../LCDPage.h" +#include + +namespace growcontrol { + +class AboutPage: public LCDPage { +public: + AboutPage(LCD& lcd, LCDPage* parent); + virtual ~AboutPage(); + + 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 /* ABOUTPAGE_H_ */ diff --git a/src/lcdpages/FanSettings.cpp b/src/lcdpages/FanSettings.cpp new file mode 100644 index 0000000..e524d9f --- /dev/null +++ b/src/lcdpages/FanSettings.cpp @@ -0,0 +1,48 @@ +/* + * FanSettings.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "FanSettings.h" +#include "../LCD.h" +#include "../GCException.h" + +namespace growcontrol { + +FanSettings::FanSettings(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) { +} + +FanSettings::~FanSettings() { +} + +void FanSettings::reset() { +} + +void FanSettings::refreshDisplay() { + if (lcd.isLCDConnected()) { + + lcd.clearDisplay(); + lcd.writeLine(0, "Fan Settings:"); + lcd.writeLine(1, " ToDo"); + try { + lcd.writeLCDBuffer(); + } catch (GCException &e) { + } + } +} + +void FanSettings::buttonStateCallback(uint8_t button, bool state) { + if (state) { + lcd.setActivePage(*parent); + } +} + +void FanSettings::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) { +} + +void FanSettings::controlMainLoopCallback(GCSensorsInfo& sensors) { +} + +} /* namespace growcontrol */ diff --git a/src/lcdpages/FanSettings.h b/src/lcdpages/FanSettings.h new file mode 100644 index 0000000..aee1dcc --- /dev/null +++ b/src/lcdpages/FanSettings.h @@ -0,0 +1,31 @@ +/* + * FanSettings.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef FANSETTINGS_H_ +#define FANSETTINGS_H_ + +#include "../LCDPage.h" +#include + +namespace growcontrol { + +class FanSettings : public LCDPage { +public: + FanSettings(LCD& lcd, LCDPage* parent); + virtual ~FanSettings(); + + 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 /* FANSETTINGS_H_ */ diff --git a/src/lcdpages/MainMenu.cpp b/src/lcdpages/MainMenu.cpp new file mode 100644 index 0000000..25388f7 --- /dev/null +++ b/src/lcdpages/MainMenu.cpp @@ -0,0 +1,113 @@ +/* + * MainMenu.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "MainMenu.h" +#include "../LCD.h" +#include "../GCException.h" + +namespace growcontrol { + +MainMenu::MainMenu(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent), + aboutPage(lcd, this), fanSettings(lcd, this), pcSettings(lcd, this) { + items.push_back("Fan Settings"); + items.push_back("PC Control"); + items.push_back("About"); + items.push_back("Back"); +} + +MainMenu::~MainMenu() { +} + + + +void MainMenu::reset() { + itemsStart = 0; + cursorPos = 0; +} + +void MainMenu::refreshDisplay() { + if (lcd.isLCDConnected()) { + char buffer[21]; + lcd.writeLine(0, "Main Menu:"); + 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) { + } + } +} + +void MainMenu::buttonStateCallback(uint8_t button, bool state) { + if (state) { + bool refresh = false; + switch (button) { + case 0: // enter + switch (itemsStart + cursorPos) { + case 0: // Fan Settings + lcd.setActivePage(fanSettings, true); + break; + case 1: // PC Settings + lcd.setActivePage(pcSettings, true); + break; + case 2: // About + lcd.setActivePage(aboutPage, true); + break; + case 3: // back + lcd.setActivePage(*parent, true); + break; + default: + break; + } + 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 MainMenu::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) { +} + +void MainMenu::controlMainLoopCallback(GCSensorsInfo& sensors) { +} + +} /* namespace growcontrol */ diff --git a/src/lcdpages/MainMenu.h b/src/lcdpages/MainMenu.h new file mode 100644 index 0000000..872f792 --- /dev/null +++ b/src/lcdpages/MainMenu.h @@ -0,0 +1,44 @@ +/* + * MainMenu.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef MAINMENU_H_ +#define MAINMENU_H_ + +#include "../LCDPage.h" +#include "AboutPage.h" +#include "FanSettings.h" +#include "PCSettings.h" +#include +#include + +namespace growcontrol { + +class MainMenu: public LCDPage { +private: + std::vector items; + unsigned itemsStart = 0; + unsigned cursorPos = 0; + + AboutPage aboutPage; + FanSettings fanSettings; + PCSettings pcSettings; + +public: + MainMenu(LCD& lcd, LCDPage* parent); + virtual ~MainMenu(); + + 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 /* MAINMENU_H_ */ diff --git a/src/lcdpages/MainPage.cpp b/src/lcdpages/MainPage.cpp new file mode 100644 index 0000000..3b36b69 --- /dev/null +++ b/src/lcdpages/MainPage.cpp @@ -0,0 +1,133 @@ +/* + * MainPage.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "MainPage.h" +#include "../GrowControl.h" +#include + +namespace growcontrol { + +MainPage::MainPage(LCD& lcd) : LCDPage(lcd), menu(lcd, this) { + for (int t = 0; t < 4; t++) { + for (int i = 0; i < 20; i++) { + buffer[t][i] = ' '; + } + } + buffer[0][20] = '\0'; + buffer[1][20] = '\0'; + buffer[2][20] = '\0'; + buffer[3][20] = '\0'; + snprintf(buffer[1], 21, "%-20.20s", " GrowControl"); + snprintf(buffer[2], 21, "%-20.20s", " loading ..."); +} + +MainPage::~MainPage() { +} + + + +void MainPage::reset() { + +} + +void MainPage::refreshDisplay(){ + if (lcd.isLCDConnected()) { + lcd.writeLine(0, buffer[0]); + lcd.writeLine(1, buffer[1]); + lcd.writeLine(2, buffer[2]); + lcd.writeLine(3, buffer[3]); + try { + lcd.writeLCDBuffer(); + } catch (GCException &e) { + //std::ostringstream ss; + //ss << "unknown exception while writing lcd: " << e.what(); + } + } +} + +void MainPage::buttonStateCallback(uint8_t button, bool state) { + if (button == 3 && state) { + lcd.setLight(false); + } else if (button == 0 && state) { + lcd.setActivePage(menu, true); + } +} + +void MainPage::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) { +} + +void MainPage::controlMainLoopCallback(GCSensorsInfo& sensors) { + if (lcd.isLCDConnected()) { + char temp1[21]; + char temp2[21]; + char hum1[21]; + char fan1[21]; + // temp1 + if (sensors.temp1.valid) { + 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; + } + } + // temp2 + if (sensors.temp2.valid) { + 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; + } + } + // hum1 + if (sensors.hum1.valid) { + 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"); + } else { + switch (sensors.fan1.error.getErrorCode()) { + case GCErrorCode::SENSOR_DISCONNECTED: + snprintf(fan1, 21, "DISCON"); + break; + default: + snprintf(fan1, 21, " ERROR"); + break; + } + } + // line 1 + snprintf(buffer[0], 21, "T: %7.7s %7.7s ", temp1, temp2); + // line 2 + snprintf(buffer[1], 21, "Humidity: %5.5s ", hum1); + // line 3 + snprintf(buffer[2], 21, "Fan: %-15.15s", fan1); + + refreshDisplay(); + } +} + + +} /* namespace growcontrol */ diff --git a/src/lcdpages/MainPage.h b/src/lcdpages/MainPage.h new file mode 100644 index 0000000..2f149e1 --- /dev/null +++ b/src/lcdpages/MainPage.h @@ -0,0 +1,35 @@ +/* + * MainPage.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef MAINPAGE_H_ +#define MAINPAGE_H_ + +#include "../LCDPage.h" +#include "MainMenu.h" + +namespace growcontrol { + +class MainPage: public LCDPage { +private: + char buffer[4][21]; + MainMenu menu; + +public: + MainPage(LCD& lcd); + virtual ~MainPage(); + + 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 /* MAINPAGE_H_ */ diff --git a/src/lcdpages/PCSettings.cpp b/src/lcdpages/PCSettings.cpp new file mode 100644 index 0000000..b0f9d9f --- /dev/null +++ b/src/lcdpages/PCSettings.cpp @@ -0,0 +1,49 @@ +/* + * PCSettings.cpp + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#include "PCSettings.h" +#include "../LCD.h" +#include "../GCException.h" + +namespace growcontrol { + +PCSettings::PCSettings(LCD& lcd, LCDPage* parent) : LCDPage(lcd, parent) { +} + +PCSettings::~PCSettings() { + // TODO Auto-generated destructor stub +} + +void PCSettings::reset() { +} + +void PCSettings::refreshDisplay() { + if (lcd.isLCDConnected()) { + + lcd.clearDisplay(); + lcd.writeLine(0, "PC Control:"); + lcd.writeLine(1, " ToDo"); + try { + lcd.writeLCDBuffer(); + } catch (GCException &e) { + } + } +} + +void PCSettings::buttonStateCallback(uint8_t button, bool state) { + if (state) { + lcd.setActivePage(*parent); + } +} + +void PCSettings::stateChangeCallback(TfDevice& device, TfDeviceState oldstate, TfDeviceState newstate) { +} + +void PCSettings::controlMainLoopCallback(GCSensorsInfo& sensors) { +} + +} /* namespace growcontrol */ diff --git a/src/lcdpages/PCSettings.h b/src/lcdpages/PCSettings.h new file mode 100644 index 0000000..6cfc9d6 --- /dev/null +++ b/src/lcdpages/PCSettings.h @@ -0,0 +1,31 @@ +/* + * PCSettings.h + * + * Created on: 15.06.2014 + * Author: matzman + */ + +#ifndef PCSETTINGS_H_ +#define PCSETTINGS_H_ + +#include "../LCDPage.h" +#include + +namespace growcontrol { + +class PCSettings: public LCDPage { +public: + PCSettings(LCD& lcd, LCDPage* parent); + virtual ~PCSettings(); + + 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 /* PCSETTINGS_H_ */ diff --git a/src/lcdpages/config.mk b/src/lcdpages/config.mk new file mode 100644 index 0000000..ee96f3f --- /dev/null +++ b/src/lcdpages/config.mk @@ -0,0 +1,6 @@ + +SRC_FILES += src/lcdpages/MainPage.cpp \ + src/lcdpages/MainMenu.cpp \ + src/lcdpages/AboutPage.cpp \ + src/lcdpages/FanSettings.cpp \ + src/lcdpages/PCSettings.cpp diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..05c1aa3 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,37 @@ +/* + * main.cpp + * + * Created on: 10.06.2014 + * Author: matzman + */ + +#include +#include "GrowControl.h" +#include "IPCManager.h" +#include +#include +#include +#include + +using namespace tfcppsimple; +using namespace growcontrol; + + +#define HOST "localhost" +#define PORT 4223 + +GrowControl controller; +IPCManager ipcManager; + + +int main(int argc, char **argv) { + TfUtils::configureLog4CPP("log4cpp.config"); + controller.connect(HOST, PORT); + sleep(2); + try { + ipcManager.init(controller, "/tmp/growcontrol.socket"); + } catch (GCException &e) { + } + controller.mainLoop(); + +}