Select Git revision
-
Carl Philipp Klemm authoredCarl Philipp Klemm authored
test.cpp 6.10 KiB
#include <thread>
#include <readline/readline.h>
#include <readline/history.h>
#include "coincell.h"
#include "log.h"
#include "options.h"
#include "tokenize.h"
#include "vcpps.h"
#include "heaters.h"
#include "multiplexers.h"
#include "coincells.h"
#include "startupfailure.h"
void devicefailed(Vcpps& psu, int device, uint16_t serial, int code)
{
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";
}
bool preparePsu(Vcpps* psu, float voltage, float current)
{
Vcpps::Status status;
Log(Log::INFO, true, false)<<"Setting psu voltage to "<<voltage;
bool ret = psu->setVoltage(voltage);
if(!ret)
{
Log(Log::ERROR, true, false)<<"Unable to set psu voltage";
return false;
}
Log(Log::INFO, true, false)<<"Setting psu current to "<<current;
ret = psu->setCurrent(current);
if(!ret)
{
Log(Log::ERROR, true, false)<<"Unable to set psu current";
return false;
}
ret = psu->setEnabled(true);
if(!ret)
{
Log(Log::ERROR, true, false)<<"Unable to enable psu output";
return false;
}
Log(Log::INFO, true, false)<<"Waiting for psu to stablize";
std::this_thread::sleep_for(std::chrono::seconds(2));
ret = psu->getStatus(status);
ret = psu->getStatus(status);
if(!ret)
{
Log(Log::ERROR)<<"Unable to read psu state, abort";
psu->setEnabled(false);
return false;
}
else if(status.curent_limited)
{
Log(Log::ERROR)<<"Psu is overcurrent at "<<status.current<<" abort";
psu->setEnabled(false);
return false;
}
Log(Log::INFO, true, false)<<"PSU voltage: "<<status.voltage<<" current: "<<status.current
<<" is currently "<<(status.curent_limited ? "" : "not")<<" current limited";
return true;
}
void print_cmd_help(const std::string& line)
{
Log(Log::INFO, true, false)<<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, true, false)<<"Geting PSU";
Vcpps psu(config.psuPort);
psu.setEnabled(false);
Log(Log::INFO, true, false)<<"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::vector<std::unique_ptr<CoinCell>> coinCells = asign_coincells(config.cells, &heaters, &multiplexers);
bool ret = preparePsu(&psu, 10, 10);
if(!ret)
return 2;
while(true)
{
const char* linePtr = readline("> ");
if(!linePtr)
continue;
std::string line = std::string(linePtr);
if(line.empty())
continue;
std::vector<std::string> tokens = tokenize(line, ' ');
int coincellId = -1;
if(tokens.size() >= 2)
{
coincellId = std::stol(tokens[1]);
if(coincellId < 0 || coincellId > coinCells.size())
Log(Log::ERROR, true, false)<<"Invalid coin cell id: "<<tokens[1];
}
if(coincellId < 0 && 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, true, false)<<"unable to connect coin cell "<<coincellId;
else
Log(Log::ERROR, true, false)<<"connected coin cell "<<coincellId;
}
else if(tokens[0] == "disconnect" || tokens[0] == "d")
{
bool ret = coinCells[coincellId]->setConnected(false);
if(!ret)
Log(Log::ERROR, true, false)<<"unable to disconnect coin cell "<<coincellId;
else
Log(Log::ERROR, true, false)<<"disconnected coin cell "<<coincellId;
}
else if(tokens[0] == "set" || tokens[0] == "s")
{
if(tokens.size() < 3)
{
Log(Log::ERROR, true, false)<<"This command requires a temperature";
continue;
}
float temperature = std::stod(tokens[2]);
if(temperature < 10 || temperature > 100)
{
Log(Log::ERROR, true, false)<<"Temperature "<<tokens[2]<<" is invalid";
continue;
}
coinCells[coincellId]->setEnabled(true);
coinCells[coincellId]->setTemperature(temperature);
}
else if(tokens[0] == "get" || tokens[0] == "g")
{
float temperature;
if(coincellId < 0)
{
for(size_t i = 0; i < coinCells.size(); ++i)
{
std::unique_ptr<CoinCell>& cell = coinCells[i];
bool ret = cell->getTemperature(temperature);
if(!ret)
Log(Log::ERROR, true, false)<<"Cell "<<i<<" UNABLE TO READ";
else
Log(Log::INFO, true, false)<<"Cell "<<i<<" temperature: "<<temperature;
}
auto connected = multiplexers.getConnected();
for(size_t i = 0; i < connected.size(); ++i)
Log(Log::INFO, true, false)<<"multiplexer channel "<<i<<' '<<(connected[i] ? "connected" : "disconnected");
}
else
{
bool ret = coinCells[coincellId]->getTemperature(temperature);
if(!ret)
{
Log(Log::ERROR, true, false)<<"Cell "<<coincellId<<" UNABLE TO READ";
continue;
}
float setpoint;
ret = coinCells[coincellId]->getSetpoint(setpoint);
if(!ret)
{
Log(Log::ERROR, true, false)<<"Cell "<<coincellId<<" UNABLE TO READ";
continue;
}
bool enabled = coinCells[coincellId]->getEnabled();
Log(Log::ERROR, true, false)<<"Cell "<<coincellId<<':';
Log(Log::ERROR, true, false)<<"\ttemperature: "<<temperature<<"\n\tsetpoint: "<<setpoint;
Log(Log::ERROR, true, false)<<"\tenabled: "<<(enabled ? "true" : "false");
}
}
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, true, false)<<err.what();
return 1;
}
}