1 #include <boost/array.hpp> 5 #include <QtXml/QDomDocument> 21 namespace ba = boost::asio;
22 namespace bs = boost::system;
23 namespace dummy = ba::placeholders;
58 Out() <<
"------------------------------------------------------" << endl;
59 Out() << fRdfData << endl;
60 Out() <<
"------------------------------------------------------" << endl;
63 const size_t p1 = fRdfData.find(
"\r\n\r\n");
66 Warn(
"HTTP header not found.");
71 fRdfData.erase(0, p1+4);
72 fRdfData.insert(0,
"<?xml version=\"1.0\"?>\n");
75 if (!doc.setContent(QString(fRdfData.c_str()),
false))
77 Warn(
"Parsing of html failed.");
83 Out() <<
"Parsed:\n-------\n" << doc.toString().toStdString() << endl;
85 const QDomNodeList imageElems = doc.elementsByTagName(
"span");
87 for (
unsigned int i=0;
i<imageElems.length();
i++)
89 const QDomElement e = imageElems.item(
i).toElement();
91 const QDomNamedNodeMap att = e.attributes();
104 fLastReport =
Time();
108 void HandleRead(
const boost::system::error_code& err,
size_t bytes_received)
111 if (bytes_received==0 || err)
113 if (err==ba::error::eof)
115 if (!fRdfData.empty())
122 if (err && err!=ba::error::eof &&
123 err!=ba::error::basic_errors::not_connected &&
124 err!=ba::error::basic_errors::operation_aborted)
127 str <<
"Reading from " << URL() <<
": " << err.message() <<
" (" << err <<
")";
130 PostClose(err!=ba::error::basic_errors::operation_aborted);
136 fRdfData += string(fArray.data(), bytes_received);
139 const size_t p1 = fRdfData.find(
"\r\n\r\n");
140 if (p1!=string::npos)
143 const size_t p2 = fRdfData.find(
"\r\n\r\n", p1+4);
144 if (p2!=string::npos)
158 dummy::error, dummy::bytes_transferred));
166 if (error && error!=ba::error::basic_errors::operation_aborted)
169 str <<
"Write timeout of " << URL() <<
": " << error.message() <<
" (" << error <<
")";
188 if (fKeepAlive.expires_at() > ba::deadline_timer::traits_type::now())
208 fIsValid(false), fIsVerbose(true), fDebugRx(false), fLastReport(
Time::none), fKeepAlive(ioservice)
241 string cmd =
"GET " + fSite;
243 if (!fNextCommand.empty())
244 cmd +=
"?" + fNextCommand;
246 cmd +=
" HTTP/1.1\r\n";
253 fKeepAlive.expires_from_now(boost::posix_time::seconds(fInterval));
255 this, dummy::error));
266 if (!fLastReport.
IsValid() ||
Time()>fLastReport+boost::posix_time::seconds(fInterval*3))
310 fDim(
"PWR_CONTROL/DATA",
"C:1;C:1;C:1;C:1;C:1;C:1;C:1;C:1",
311 "|water_lvl[bool]:Water level ok" 312 "|water_flow[bool]:Water flowing" 313 "|pwr_24V[bool]:24V power enabled" 314 "|pwr_pump[bool]:Pump power enabled" 315 "|pwr_bias[bool]:Bias power enabled" 316 "|pwr_drive[bool]:Drive power enabled (command value)" 317 "|main_drive[bool]:Drive manual main switch on" 318 "|feedback_drive[bool]:Drive power on (feedback value)")
331 template <
class T,
class S>
344 msg << name <<
" - Received event has " << has <<
" bytes, but expected " << size <<
".";
351 if (!CheckEventSize(evt.
GetSize(),
"SetVerbosity", 1))
352 return T::kSM_FatalError;
354 fPower.SetVerbose(evt.
GetBool());
356 return T::GetCurrentState();
361 if (!CheckEventSize(evt.
GetSize(),
"SetDebugRx", 1))
362 return T::kSM_FatalError;
364 fPower.SetDebugRx(evt.
GetBool());
366 return T::GetCurrentState();
372 return T::GetCurrentState();
377 if (!CheckEventSize(evt.
GetSize(),
"SetCameraPower", 1))
378 return T::kSM_FatalError;
380 fLastCommand =
Time();
381 fPower.Post(evt.
GetBool() ?
"cam_on=Camera+ON" :
"cam_off=Camera+OFF");
382 return T::GetCurrentState();
387 fLastCommand =
Time();
388 fPower.Post(
"dt=Drive+ON%2FOFF");
389 return T::GetCurrentState();
395 const int rc = fPower.GetState();
398 T::Error(
"Power control unit reported cooling failure.");
400 return fPower.GetState();
410 "No connection to web-server could be established recently");
413 "Connection established, but status still not known");
416 "Camera, Bias and Drive power off");
419 "Camera and Drive power off, Bias on");
422 "Camera and Bias power off, Drive on");
425 "Drive and Bias power off, Camera on");
428 "Camera and Drive power on, Bias off");
431 "Camera and Bias power on, Drive off");
434 "Drive and Bias power on, Camera off");
437 "Camera, Bias and drive power on");
440 "The cooling unit has failed, the interlock has switched off");
443 T::AddEvent(
"SET_VERBOSE",
"B:1")
445 (
"Set verbosity state" 446 "|verbosity[bool]:disable or enable verbosity for interpreted data (yes/no)");
448 T::AddEvent(
"SET_DEBUG_RX",
"B:1")
450 (
"Set debux-rx state" 451 "|debug[bool]:dump received text and parsed text to console (yes/no)");
453 T::AddEvent(
"CAMERA_POWER",
"B:1")
455 (
"Switch camera power" 456 "|power[bool]:Switch camera power 'on' or 'off'");
458 T::AddEvent(
"TOGGLE_DRIVE")
460 (
"Toggle drive power");
462 T::AddEvent(
"POST",
"C")
464 (
"set verbosity state" 465 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
470 fPower.SetVerbose(!conf.
Get<
bool>(
"quiet"));
471 fPower.SetInterval(conf.
Get<uint16_t>(
"interval"));
472 fPower.SetDebugTx(conf.
Get<
bool>(
"debug-tx"));
473 fPower.SetDebugRx(conf.
Get<
bool>(
"debug-rx"));
474 fPower.SetSite(conf.
Get<
string>(
"url"));
475 fPower.SetEndpoint(conf.
Get<
string>(
"addr"));
476 fPower.StartConnect();
487 template<
class T,
class S,
class R>
490 return Main::execute<T, StateMachinePowerControl<S, R>>(conf);
495 po::options_description control(
"Interlock control");
496 control.add_options()
497 (
"no-dim,d",
po_switch(),
"Disable dim services")
498 (
"addr,a", var<string>(
""),
"Network address of the lid controling Arduino including port")
499 (
"url,u", var<string>(
""),
"File name and path to load")
500 (
"quiet,q",
po_bool(
true),
"Disable printing contents of all received messages (except dynamic data) in clear text.")
501 (
"interval,i", var<uint16_t>(5),
"Interval between two updates on the server in seconds")
502 (
"debug-tx",
po_bool(),
"Enable debugging of ethernet transmission.")
503 (
"debug-rx",
po_bool(),
"Enable debugging for received data.")
521 "The pwrctrl is an interface to the interlock hardware.\n" 523 "The default is that the program is started without user intercation. " 524 "All actions are supposed to arrive as DimCommands. Using the -c " 525 "option, a local shell can be initialized. With h or help a short " 526 "help message about the usuage can be brought to the screen.\n" 528 "Usage: pwrctrl [-c type] [OPTIONS]\n" 529 " or: pwrctrl [OPTIONS]\n";
555 int main(
int argc,
const char* argv[])
566 if (!conf.
Has(
"console"))
568 if (conf.
Get<
bool>(
"no-dim"))
569 return RunShell<LocalStream, StateMachine, ConnectionInterlock>(conf);
571 return RunShell<LocalStream, StateMachineDim, ConnectionDimWeather>(conf);
574 if (conf.
Get<
bool>(
"no-dim"))
576 if (conf.
Get<
int>(
"console")==0)
577 return RunShell<LocalShell, StateMachine, ConnectionInterlock>(conf);
579 return RunShell<LocalConsole, StateMachine, ConnectionInterlock>(conf);
583 if (conf.
Get<
int>(
"console")==0)
584 return RunShell<LocalShell, StateMachineDim, ConnectionDimWeather>(conf);
586 return RunShell<LocalConsole, StateMachineDim, ConnectionDimWeather>(conf);
StateMachinePowerControl(ostream &out=cout)
int Post(const EventImp &evt)
void Print(std::ostream &out, const char *title, const bool &val, const char *t="enabled", const char *f="disabled")
int RunShell(Configuration &conf)
A general base-class describing events issues in a state machine.
const char * GetText() const
void Post(const string &post)
void SetupConfiguration(Configuration &conf)
void setQuality(int quality)
The base implementation of a distributed messaging system.
Adds some functionality to boost::posix_time::ptime for our needs.
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
void HandleRequest(const bs::error_code &error)
po::typed_value< bool > * po_switch()
int main(int argc, const char *argv[])
int SetCameraPower(const EventImp &evt)
void HandleRead(const boost::system::error_code &err, size_t bytes_received)
bool CheckEventSize(size_t has, const char *name, size_t size)
bool Has(const std::string &var)
ConnectionInterlock(ba::io_service &ioservice, MessageImp &imp)
void AddOptions(const po::options_description &opt, bool visible=true)
void SetupConfiguration(Configuration &conf)
void SetSite(const string &site)
void Update(const Power::Status &status)
void SetVerbose(bool b=true)
Commandline parsing, resource file parsing and database access.
boost::asio::streambuf fBuffer
bool Set(bool &rc, const QString &value)
boost::array< char, 4096 > fArray
int EvalOptions(Configuration &conf)
po::typed_value< bool > * po_bool(bool def=false)
void SetInterval(uint16_t i)
static const uint16_t kMaxAddr
int SetVerbosity(const EventImp &evt)
boost::asio::deadline_timer fKeepAlive
int SetDebugRx(const EventImp &evt)
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
void ConnectionEstablished()
ConnectionDimWeather(ba::io_service &ioservice, MessageImp &imp)
virtual void Update(const Power::Status &)
virtual size_t GetSize() const