Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

sort.cpp

Blame
  • 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;
    	}
    
    }