Skip to content
Snippets Groups Projects
Commit 8baf362d authored by Carl Philipp Klemm's avatar Carl Philipp Klemm
Browse files

Add cmdline application for testing

parent eeaed446
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,7 @@ find_package(OpenSSL REQUIRED)
pkg_check_modules(MULTIPLEXER REQUIRED eismuliplexer)
pkg_check_modules(COINCELLHELL REQUIRED libcoincellhell)
pkg_check_modules(EISGEN REQUIRED libeisgenerator)
pkg_check_modules(READLINE readline)
if(WIN32)
set(COINCELLHELL_LIBRARIES -lws2_32 -L/home/philipp/programing/kiss/coincellhell/libcoincellhell/build-w64/ -l:libcoincellhell.dll.a)
......@@ -34,6 +35,7 @@ set(SRC_FILES
multiplexers.cpp
heater.cpp
coincell.cpp
coincells.cpp
biocontrol.cpp
tokenize.cpp
expirament.cpp
......@@ -47,3 +49,27 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${MULTIPLEXER_INCLUDE_DIRS}
${SERIALPORT_INCLUDE_DIRS} ${COINCELLHELL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS} ${EISGEN_LIBRARIES_INCLUDE_DIRS})
target_compile_definitions(${PROJECT_NAME} PUBLIC SMTP_OPENSSL)
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
if(READLINE_FOUND)
message("Readline found, will build testing application")
set(SRC_FILES_TEST
test.cpp
log.cpp
multiplexers.cpp
smtp/smtp.c
smtp/SMTPMail.cpp
biocontrol.cpp
vcpps.cpp
heater.cpp
coincell.cpp
coincells.cpp
tokenize.cpp
randomgen.cpp)
add_executable(${PROJECT_NAME}_test ${SRC_FILES_TEST})
target_link_libraries(${PROJECT_NAME}_test ${READLINE_LIBRARIES} ${MULTIPLEXER_LIBRARIES} ${SERIALPORT_LIBRARIES}
${COINCELLHELL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EISGEN_LIBRARIES})
target_include_directories(${PROJECT_NAME}_test PUBLIC ${READLINE_INCLUDE_DIRS} ${MULTIPLEXER_INCLUDE_DIRS}
${SERIALPORT_INCLUDE_DIRS} ${COINCELLHELL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS} ${EISGEN_LIBRARIES_INCLUDE_DIRS})
target_compile_definitions(${PROJECT_NAME}_test PUBLIC SMTP_OPENSSL)
endif(READLINE_FOUND)
#include "coincells.h"
#include "log.h"
std::vector<std::unique_ptr<CoinCell>> asign_coincells(std::vector<uint16_t> cellids, Heaters* heaters, Multiplexers* multiplexers)
{
CoinCell cell(heaters, multiplexers, 0, {3});
std::vector<std::unique_ptr<CoinCell>> coinCells;
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 0, std::vector<int>({3, 10})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 1, std::vector<int>({2, 9})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 2, std::vector<int>({1, 8})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 3, std::vector<int>({0, 7})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 4, std::vector<int>({6, 13})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 5, std::vector<int>({5, 12})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 6, std::vector<int>({4, 11})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 8, std::vector<int>({24, 17})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 9, std::vector<int>({23, 16})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 10, std::vector<int>({22, 15})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 11, std::vector<int>({21, 14})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 12, std::vector<int>({27, 20})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 13, std::vector<int>({26, 19})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 14, std::vector<int>({25, 18})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 16, std::vector<int>({31})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 17, std::vector<int>({30})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 18, std::vector<int>({29})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 19, std::vector<int>({28})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 20, std::vector<int>({34})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 21, std::vector<int>({33})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 22, std::vector<int>({32})));
if(!cellids.empty())
{
for(ssize_t i = coinCells.size()-1; i >= 0; --i)
{
auto search = std::find(cellids.begin(), cellids.end(), i);
if(search == cellids.end())
coinCells.erase(coinCells.begin()+i);
}
}
Log(Log::INFO)<<"Connections:";
for(std::unique_ptr<CoinCell>& cell : coinCells)
{
int heater = cell->getHeaterId();
const std::vector<int>& muliplexerchs = cell->getMulitplexerChannels();
std::pair<int, int> heaterAddr = heaters->getAddress(heater);
Log(Log::INFO, false)<<"CoincellHell "<<heaterAddr.first<<" unit "<<heaterAddr.second<<" is connected to: ";
for(int id : muliplexerchs)
{
std::pair<int, channel_t> addr = multiplexers->getAddress(id);
Log(Log::INFO, false, false)<<" Mulitplexer "<<addr.first<<" channel "<<Multiplexers::chToString(addr.second)<<", ";
}
Log(Log::INFO, false)<<'\n';
}
return coinCells;
}
#pragma once
#include "coincell.h"
#include "multiplexers.h"
#include "heaters.h"
std::vector<std::unique_ptr<CoinCell>> asign_coincells(std::vector<uint16_t> cellids, Heaters* heaters, Multiplexers* multiplexers);
......@@ -19,6 +19,7 @@
#include "log.h"
#include "smtp/smtp.h"
#include <cassert>
Log::Log()
{
......@@ -77,6 +78,9 @@ std::string Log::getLabel(Level level)
case ERROR:
label = "ERROR";
break;
case NEVER:
assert(false);
break;
}
return label;
}
......
......@@ -34,7 +34,8 @@ public:
DEBUG,
INFO,
WARN,
ERROR
ERROR,
NEVER
};
private:
......
......@@ -13,8 +13,10 @@
#include <sys/stat.h>
#include <fstream>
#include "biocontrol.h"
#include "coincell.h"
#include "coincells.h"
#include "log.h"
#include "heaters.h"
#include "multiplexers.h"
......@@ -171,65 +173,6 @@ bool listSerialPorts()
return true;
}
std::vector<std::unique_ptr<CoinCell>> asign_coincells(std::vector<uint16_t> cellids, Heaters* heaters, Multiplexers* multiplexers)
{
CoinCell cell(heaters, multiplexers, 0, {3});
std::vector<std::unique_ptr<CoinCell>> coinCells;
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 0, std::vector<int>({3, 10})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 1, std::vector<int>({2, 9})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 2, std::vector<int>({1, 8})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 3, std::vector<int>({0, 7})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 4, std::vector<int>({6, 13})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 5, std::vector<int>({5, 12})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 6, std::vector<int>({4, 11})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 8, std::vector<int>({24, 17})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 9, std::vector<int>({23, 16})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 10, std::vector<int>({22, 15})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 11, std::vector<int>({21, 14})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 12, std::vector<int>({27, 20})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 13, std::vector<int>({26, 19})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 14, std::vector<int>({25, 18})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 16, std::vector<int>({31})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 17, std::vector<int>({30})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 18, std::vector<int>({29})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 19, std::vector<int>({28})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 20, std::vector<int>({34})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 21, std::vector<int>({33})));
coinCells.push_back(std::make_unique<CoinCell>(heaters, multiplexers, 22, std::vector<int>({32})));
if(!cellids.empty())
{
for(ssize_t i = coinCells.size()-1; i >= 0; --i)
{
auto search = std::find(cellids.begin(), cellids.end(), i);
if(search == cellids.end())
coinCells.erase(coinCells.begin()+i);
}
}
Log(Log::INFO)<<"Connections:";
for(std::unique_ptr<CoinCell>& cell : coinCells)
{
int heater = cell->getHeaterId();
const std::vector<int>& muliplexerchs = cell->getMulitplexerChannels();
std::pair<int, int> heaterAddr = heaters->getAddress(heater);
Log(Log::INFO, false)<<"CoincellHell "<<heaterAddr.first<<" unit "<<heaterAddr.second<<" is connected to: ";
for(int id : muliplexerchs)
{
std::pair<int, channel_t> addr = multiplexers->getAddress(id);
Log(Log::INFO, false, false)<<" Mulitplexer "<<addr.first<<" channel "<<Multiplexers::chToString(addr.second)<<", ";
}
Log(Log::INFO, false)<<'\n';
}
return coinCells;
}
int main(int argc, char** argv)
{
umask(0);
......
#include <thread>
#include <readline/readline.h>
#include <readline/history.h>
#include "coincell.h"
#include "log.h"
#include "options.h"
static void logThread()
{
static int a = 42;
#include "tokenize.h"
#include "vcpps.h"
#include "heaters.h"
#include "multiplexers.h"
#include "coincells.h"
#include "startupfailure.h"
while(true)
void devicefailed(Vcpps& psu, int device, uint16_t serial, int code)
{
Log(Log::INFO)<<"DEBUG"<<' '<<++a;
std::this_thread::sleep_for(std::chrono::microseconds(10));
std::stringstream ss;
Log(Log::WARN)<<"Heater device "<<device<<" with serial number "<<serial<<" has "
<<(code == Heaters::ERR_RECOVERED ? "recovered" : "failed")<<" with code "<<code;
}
void heaterfailed(int heater, int device)
{
Log(Log::WARN)<<"Heater "<<heater<<" on device "<<device<<" has failed";
}
static void logThreadTwo()
bool preparePsu(Vcpps* psu, float voltage, float current)
{
Vcpps::Status status;
Log(Log::INFO)<<"Setting psu voltage to "<<voltage;
bool ret = psu->setVoltage(voltage);
if(!ret)
{
Log(Log::ERROR)<<"Unable to set psu voltage";
return false;
}
Log(Log::INFO)<<"Setting psu current to "<<current;
ret = psu->setCurrent(current);
if(!ret)
{
static unsigned int a = 0;
Log(Log::ERROR)<<"Unable to set psu current";
return false;
}
ret = psu->setEnabled(true);
if(!ret)
{
Log(Log::ERROR)<<"Unable to enable psu output";
return false;
}
Log(Log::INFO)<<"Waiting for psu to stablize";
std::this_thread::sleep_for(std::chrono::seconds(2));
while(true)
ret = psu->getStatus(status);
if(!ret || status.curent_limited)
{
a+=2;
Log(Log::INFO)<<"DEBUG 2"<<' '<<a;
std::this_thread::sleep_for(std::chrono::microseconds(1));
Log(Log::ERROR)<<"Psu is overcurrent, abort";
psu->setEnabled(false);
return false;
}
Log(Log::INFO)<<"PSU voltage: "<<status.voltage<<" current: "<<status.current
<<" is currently "<<(status.curent_limited ? "" : "not")<<" current limited";
return true;
}
int main()
void print_cmd_help(const std::string& line)
{
Log(Log::INFO)<<line<<" is not a valid command. Valid commands: connect (c), disconnect (d), set (s), get (g), clear."<<
"all commands except clear require a number containing the id of the coincell after the command";
}
int main(int argc, char** argv)
{
Log::level = Log::INFO;
Log::sendmailLevel = Log::NEVER;
Log::headers = false;
Config config;
argp_parse(&argp, argc, argv, 0, 0, &config);
try
{
Log(Log::INFO)<<"Geting PSU";
Vcpps psu(config.psuPort);
psu.setEnabled(false);
Log(Log::INFO)<<"Starting thread";
Log(Log::INFO)<<"Aquireing heaters and multiplexers";
Heaters heaters(config.heaterSerials,
[&psu](int device, uint16_t serial, int code){devicefailed(psu, device, serial, code);},
&heaterfailed);
Multiplexers multiplexers(config.multiplexerSerials);
std::thread threadA(logThread);
std::thread threadB(logThreadTwo);
std::vector<std::unique_ptr<CoinCell>> coinCells = asign_coincells(config.cells, &heaters, &multiplexers);
bool ret = preparePsu(&psu, 10, 10);
if(!ret)
return 2;
while(true)
{
Log(Log::INFO)<<"MAIN"<<" Thread";
std::this_thread::sleep_for(std::chrono::microseconds(1));
std::string line = std::string(readline("> "));
if(line.empty())
continue;
std::vector<std::string> tokens = tokenize(line, ' ');
int coincellId = 0;
if(tokens.size() < 2 && tokens[0] != "clear")
{
print_cmd_help(line);
continue;
}
else if(tokens[0] != "clear" && tokens[0] != "get" && tokens.size() >= 2)
{
coincellId = std::stol(tokens[1]);
if(coincellId < 0 || coincellId > coinCells.size())
Log(Log::ERROR)<<"Invalid coin cell id: "<<tokens[1];
}
else if(tokens.size() < 2 && tokens[0] != "clear" && tokens[0] != "get")
{
print_cmd_help(line);
}
if(tokens[0] == "connect" || tokens[0] == "c")
{
bool ret = coinCells[coincellId]->setConnected(true);
if(!ret)
Log(Log::ERROR)<<"unable to connect coin cell "<<coincellId;
else
Log(Log::ERROR)<<"connected coin cell "<<coincellId;
}
else if(tokens[0] == "disconnect" || tokens[0] == "d")
{
bool ret = coinCells[coincellId]->setConnected(false);
if(!ret)
Log(Log::ERROR)<<"unable to disconnect coin cell "<<coincellId;
else
Log(Log::ERROR)<<"disconnected coin cell "<<coincellId;
}
else if(tokens[0] == "set" || tokens[0] == "s")
{
if(tokens.size() < 3)
{
Log(Log::ERROR)<<"This command requires a temperature";
continue;
}
float temperature = std::stod(tokens[2]);
if(temperature < 10 || temperature > 100)
{
Log(Log::ERROR)<<"Temperature "<<tokens[2]<<" is invalid";
continue;
}
coinCells[coincellId]->setEnabled(true);
coinCells[coincellId]->setTemperature(temperature);
}
else if(tokens[0] == "get" || tokens[0] == "g")
{
for(size_t i = 0; i < coinCells.size(); ++i)
{
std::unique_ptr<CoinCell>& cell = coinCells[i];
float temperature;
bool ret = cell->getTemperature(temperature);
if(!ret)
Log(Log::ERROR)<<"Cell "<<i<<" UNABLE TO READ";
else
Log(Log::INFO)<<"Cell "<<i<<" temperature "<<temperature;
}
auto connected = multiplexers.getConnected();
for(size_t i = 0; i < connected.size(); ++i)
Log(Log::INFO)<<"multiplexer channel "<<i<<' '<<(connected[i] ? "connected" : "disconnected");
}
else if(tokens[0] == "clear")
{
multiplexers.disconnectAll();
for(std::unique_ptr<CoinCell>& cell :coinCells)
cell->setEnabled(false);
}
add_history(line.c_str());
}
}
catch(const startup_failure& err)
{
Log(Log::ERROR)<<err.what();
return 1;
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment