Changeset 14518 for trunk/FACT++/src
- Timestamp:
- 10/24/12 12:35:52 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/pwrctrl.cc
r14516 r14518 1 1 #include <boost/bind.hpp> 2 2 3 #include <string> // std::string 4 #include <algorithm> // std::transform 5 #include <cctype> // std::tolower 3 #include <string> 6 4 7 5 #include <QtXml/QDomDocument> … … 18 16 #include "tools.h" 19 17 20 #include "Headers Lid.h"18 #include "HeadersPower.h" 21 19 22 20 namespace ba = boost::asio; … … 29 27 { 30 28 protected: 31 32 struct Status 33 { 34 bool fWaterFlowOk; 35 bool fWaterLevelOk; 36 37 bool fPwrBiasOn; 38 bool fPwr24VOn; 39 bool fPwrPumpOn; 40 bool fPwrDriveOn; 41 42 bool fDriveMainSwitchOn; 43 bool fDriveFeedbackOn; 44 45 Status() { } 46 47 bool Set(bool &rc, const QString &value) 48 { 49 rc = value.toInt(); 50 return true; 51 } 52 53 bool Set(const QDomNamedNodeMap &map) 54 { 55 if (!map.contains("id") || !map.contains("title")) 56 return false; 57 58 QString item = map.namedItem("id").nodeValue(); 59 QString value = map.namedItem("title").nodeValue(); 60 61 if (item==(QString("flow_meter"))) 62 return Set(fWaterFlowOk, value); 63 64 if (item==(QString("level"))) 65 return Set(fWaterLevelOk, value); 66 67 if (item==(QString("bias_power"))) 68 return Set(fPwrBiasOn, value); 69 70 if (item==(QString("power_24v"))) 71 return Set(fPwr24VOn, value); 72 73 if (item==(QString("pump"))) 74 return Set(fPwrPumpOn, value); 75 76 if (item==(QString("drive_power"))) 77 return Set(fPwrDriveOn, value); 78 79 if (item==(QString("drive_on"))) 80 return Set(fDriveMainSwitchOn, value); 81 82 if (item==(QString("drive_enable"))) 83 return Set(fDriveFeedbackOn, value); 84 85 return false; 86 } 87 88 void Print(ostream &out, const string &title, const bool &val, const string &t="enabled", const string &f="disabled") 89 { 90 out << setw(15) << (title+":"); 91 if (val) 92 out << kGreen << t << endl; 93 else 94 out << kRed << f << endl; 95 } 96 97 void Print(ostream &out) 98 { 99 Print(out, "Water flow", fWaterFlowOk, "ok", "low"); 100 Print(out, "Water level", fWaterLevelOk, "ok", "low"); 101 Print(out, "Power bias", fPwrBiasOn); 102 Print(out, "Power 24V", fPwr24VOn); 103 Print(out, "Power pump", fPwrPumpOn); 104 Print(out, "Power drive", fPwrDriveOn); 105 Print(out, "Drive main", fDriveMainSwitchOn, "on", "off"); 106 Print(out, "Drive feedback", fDriveFeedbackOn, "on", "off"); 107 } 108 109 }; 29 bool fIsValid; 110 30 111 31 private: … … 113 33 114 34 bool fIsVerbose; 35 bool fDebugRx; 115 36 116 37 string fSite; … … 123 44 Time fLastReport; 124 45 125 Status fStatus;126 127 virtual void Update(const Status &)46 Power::Status fStatus; 47 48 virtual void Update(const Power::Status &) 128 49 { 129 50 } … … 132 53 void ProcessAnswer() 133 54 { 134 if (f IsVerbose)55 if (fDebugRx) 135 56 { 136 57 Out() << "------------------------------------------------------" << endl; … … 139 60 } 140 61 141 /*142 fRdfData =143 "HTTP/1.1 200 OK\n"144 "Content-Type: text/html\n"145 "Connnection: close\r\n"146 "\r\n"147 "<!DOCTYPE HTML>\n"148 "<html><head>\n"149 "<meta http-equiv=\"refresh\" content=\"1 URL=index.html\"/>\n"150 "<title>FACT camera power interlock control</title>\n"151 "</head><body>\n"152 "<FORM NAME=\"Form\">"153 "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"D2off\" VALUE=\"Disable Pump\"/>--> FC_OFF HIGH for 0.5 seconds <br/>\n"154 "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"D2on\" VALUE=\"Enable Pump\" />--> FC_ON HIGH for 3.0 seconds <br/>\n"155 "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"toggle_x\" VALUE=\"Toggle X\" />--> ... well it toggles X <br/>\n"156 "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"toggle_y\" VALUE=\"Toggle Y\" />--> ... well it toggles Y <br/>\n"157 "FC_OK :2 is <font color=\"red\" size=\"20\"><span id=\"FC_OK\" value=\"0\">LOW </span></font><br />\n"158 "BP_ON :3 is <font color=\"red\" size=\"20\"><span id=\"BP_ON\" value=\"0\">LOW </span></font><br />\n"159 "IL_ON :14 is <font color=\"green\" size=\"20\"><span id=\"IL_ON\" value=\"1\">HIGH </span></font><br />\n"160 "FL_OK :15 is <font color=\"green\" size=\"20\"><span id=\"FL_OK\" value=\"1\">HIGH </span></font><br />\n"161 "FP_EN :16 is <font color=\"red\" size=\"20\"><span id=\"FP_EN\" value=\"0\">LOW </span></font><br />\n"162 "X_ON :17 is <font color=\"red\" size=\"20\"><span id=\"X_ON\" value=\"0\">LOW </span></font><br />\n"163 "Y_ON :18 is <font color=\"red\" size=\"20\"><span id=\"Y_ON\" value=\"0\">LOW </span></font><br />\n"164 "Z_OK :19 is <font color=\"red\" size=\"20\"><span id=\"Z_OK\" value=\"0\">LOW </span></font><br />\n"165 "</FORM>\n"166 "</body></html>\n";167 */168 169 62 const size_t p1 = fRdfData.find("\r\n\r\n"); 170 //const size_t p1 = fRdfData.find("\n\n");171 63 if (p1==string::npos) 172 64 { … … 187 79 } 188 80 81 if (fDebugRx) 82 Out() << "Parsed:\n-------\n" << doc.toString().toStdString() << endl; 83 84 const QDomNodeList imageElems = doc.elementsByTagName("span"); 85 86 for (unsigned int i=0; i<imageElems.length(); i++) 87 { 88 const QDomElement e = imageElems.item(i).toElement(); 89 90 const QDomNamedNodeMap att = e.attributes(); 91 92 if (fStatus.Set(att)) 93 fIsValid = true; 94 } 95 189 96 if (fIsVerbose) 190 {191 Out() << "Parsed:\n-------\n" << doc.toString().toStdString() << endl;192 Out() << "------------------------------------------------------" << endl;193 }194 195 const QDomNodeList imageElems = doc.elementsByTagName("span"); // "input"196 197 /*198 // elementById199 for (unsigned int i=0; i<imageElems.length(); i++)200 {201 QDomElement e = imageElems.item(i).toElement();202 Out() << "<" << e.tagName().toStdString() << " ";203 204 QDomNamedNodeMap att = e.attributes();205 206 for (int j=0; j<att.size(); j++)207 {208 Out() << att.item(j).nodeName().toStdString() << "=";209 Out() << att.item(j).nodeValue().toStdString() << " ";210 }211 Out() << "> " << e.text().toStdString() << endl;212 }*/213 214 for (unsigned int i=0; i<imageElems.length(); i++)215 {216 const QDomElement e = imageElems.item(i).toElement();217 218 const QDomNamedNodeMap att = e.attributes();219 220 fStatus.Set(att);221 }222 223 if (fIsVerbose)224 {225 97 fStatus.Print(Out()); 226 Out() << "------------------------------------------------------" << endl;227 }228 98 229 99 Update(fStatus); 230 100 231 101 fRdfData = ""; 232 233 /*234 if ((fLid1.status!="Open" && fLid1.status!="Closed" && fLid1.status!="Unknown") ||235 (fLid2.status!="Open" && fLid2.status!="Closed" && fLid2.status!="Unknown"))236 {237 Warn("Lid status unknown ("+fLid1.status+"/"+fLid2.status+")");238 PostClose(false);239 return;240 }*/241 102 242 103 fLastReport = Time(); … … 251 112 if (err==ba::error::eof) 252 113 { 253 ProcessAnswer(); 114 if (!fRdfData.empty()) 115 ProcessAnswer(); 254 116 return; 255 117 } … … 273 135 fRdfData += string(fArray.data(), bytes_received); 274 136 275 //cout << "." << flush;276 277 137 // Does the message contain a header? 278 138 const size_t p1 = fRdfData.find("\r\n\r\n"); … … 282 142 const size_t p2 = fRdfData.find("\r\n\r\n", p1+4); 283 143 if (p2!=string::npos) 284 {285 144 ProcessAnswer(); 286 }287 145 } 288 146 … … 369 227 public: 370 228 ConnectionInterlock(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()), 371 fIsV erbose(true), fLastReport(Time::none), fKeepAlive(ioservice)229 fIsValid(false), fIsVerbose(true), fDebugRx(false), fLastReport(Time::none), fKeepAlive(ioservice) 372 230 { 373 231 SetLogStream(&imp); … … 377 235 { 378 236 fIsVerbose = b; 237 } 238 239 void SetDebugRx(bool b) 240 { 241 fDebugRx = b; 379 242 Connection::SetVerbose(b); 380 243 } … … 393 256 { 394 257 fNextCommand = post; 395 //PostRequest("POST", post);396 258 } 397 259 … … 400 262 PostRequest("POST", fNextCommand); 401 263 fNextCommand = ""; 402 403 //fLid1.status = "";404 //fLid2.status = "";405 264 406 265 fKeepAlive.expires_from_now(boost::posix_time::seconds(fInterval)); … … 416 275 int GetState() const 417 276 { 418 using namespace Lid;277 using namespace Power::State; 419 278 420 279 // Timeout 421 280 if (fLastReport.IsValid() && fLastReport+boost::posix_time::seconds(fInterval*2)<Time()) 422 return State::kDisconnected; 281 return Power::State::kDisconnected; 282 283 // No dat areceived yet 284 if (!fIsValid) 285 return Power::State::kConnected; 423 286 424 287 /* 425 // Inconsistency 426 if (fLid1.status!=fLid2.status) 427 return State::kInconsistent; 428 429 // Unknown 430 if (fLid1.status=="Unknown") 431 return State::kUnknown; 432 433 // Closed 434 if (fLid1.status=="Closed") 435 return State::kClosed; 436 437 // Open 438 if (fLid1.status=="Open") 439 return State::kOpen; 440 */ 441 return State::kConnected; 288 bool fWaterFlowOk; 289 bool fWaterLevelOk; 290 bool fPwrBiasOn; 291 bool fPwr24VOn; 292 bool fPwrPumpOn; 293 bool fPwrDriveOn; 294 bool fDriveMainSwitchOn; 295 bool fDriveFeedbackOn; 296 */ 297 298 if (!fStatus.fWaterLevelOk || (fStatus.fPwrPumpOn && !fStatus.fWaterFlowOk)) 299 return kCoolingFailure; 300 301 const int rc = 302 (fStatus.fPwrBiasOn ? kBiasOn : 0) | 303 (fStatus.fPwrPumpOn ? kCameraOn : 0) | 304 (fStatus.fDriveFeedbackOn ? kDriveOn : 0); 305 306 return rc==0 ? kSystemOff : rc; 442 307 } 443 308 }; … … 452 317 { 453 318 private: 454 //DimDescribedService fDim;319 DimDescribedService fDim; 455 320 456 321 public: 457 322 ConnectionDimWeather(ba::io_service& ioservice, MessageImp &imp) : 458 ConnectionInterlock(ioservice, imp)/*, 459 fDim("PWR_CONTROL/DATA", "S:2;F:2;F:2", 460 "|status[bool]:Lid1/2 open or closed" 461 "|I[A]:Lid1/2 current" 462 "|P[dac]:Lid1/2 hall sensor position in averaged dac counts")*/ 463 { 464 } 465 466 void Update(const Status &status) 467 { 468 /* 469 struct DimData 470 { 471 int16_t status[2]; 472 float current[2]; 473 float position[2]; 474 475 DimData() { status[0] = status[1] = -1; } 476 477 } __attribute__((__packed__)); 478 479 DimData data; 480 481 if (l1.status=="Open") 482 data.status[0] = 1; 483 if (l1.status=="Closed") 484 data.status[0] = 0; 485 486 if (l2.status=="Open") 487 data.status[1] = 1; 488 if (l2.status=="Closed") 489 data.status[1] = 0; 490 491 data.current[0] = l1.current; 492 data.current[1] = l2.current; 493 494 data.position[0] = l1.position; 495 data.position[1] = l2.position; 496 497 fDim.Update(data);*/ 323 ConnectionInterlock(ioservice, imp), 324 fDim("PWR_CONTROL/DATA", "B:1;B:1;B:1;B:1;B:1;B:1;B:1;B:1", 325 "|water_lvl[bool]:Water level ok" 326 "|water_flow[bool]:Water flowing" 327 "|pwr_24V[bool]:24V power enabled" 328 "|pwr_pump[bool]:Pump power enabled" 329 "|pwr_bias[bool]:Bias power enabled" 330 "|pwr_drive[bool]:Drive power enabled (command value)" 331 "|main_drive[bool]:Drive manual main switch on" 332 "|feedback_drive[bool]:Drive power on (feedback value)") 333 { 334 } 335 336 void Update(const Power::Status &status) 337 { 338 fDim.setQuality(status.GetVal()); 339 fDim.Update(status); 498 340 } 499 341 }; … … 505 347 { 506 348 private: 507 S f Lid;349 S fPower; 508 350 Time fLastCommand; 509 351 … … 524 366 return T::kSM_FatalError; 525 367 526 f Lid.SetVerbose(evt.GetBool());368 fPower.SetVerbose(evt.GetBool()); 527 369 528 370 return T::GetCurrentState(); 529 371 } 530 372 373 int SetDebugRx(const EventImp &evt) 374 { 375 if (!CheckEventSize(evt.GetSize(), "SetDebugRx", 1)) 376 return T::kSM_FatalError; 377 378 fPower.SetDebugRx(evt.GetBool()); 379 380 return T::GetCurrentState(); 381 } 382 531 383 int Post(const EventImp &evt) 532 384 { 533 f Lid.Post(evt.GetText());385 fPower.Post(evt.GetText()); 534 386 return T::GetCurrentState(); 535 387 } 536 388 537 int Open() 538 { 389 int SetCameraPower(const EventImp &evt) 390 { 391 if (!CheckEventSize(evt.GetSize(), "SetCameraPower", 1)) 392 return T::kSM_FatalError; 393 539 394 fLastCommand = Time(); 540 fLid.Post("Button5="); 541 return Lid::State::kMoving; 542 } 543 int Close() 395 fPower.Post(evt.GetBool() ? "cam_on=" : "cam_off="); 396 return T::GetCurrentState(); 397 } 398 399 int ToggleDrive() 544 400 { 545 401 fLastCommand = Time(); 546 fLid.Post("Button6="); 547 return Lid::State::kMoving; 548 549 } 550 /* 551 int MoveMotor(const EventImp &evt, int mid) 552 { 553 if (!CheckEventSize(evt.GetSize(), "MoveMotor", 2)) 554 return T::kSM_FatalError; 555 556 if (evt.GetUShort()>0xfff) 557 { 558 ostringstream msg; 559 msg << "Position " << evt.GetUShort() << " for motor " << mid+1 << " out of range [0,1023]."; 560 T::Error(msg); 561 return T::GetCurrentState(); 562 } 563 564 fLid.MoveMotor(mid, evt.GetUShort()); 565 402 fPower.Post("dt="); 566 403 return T::GetCurrentState(); 567 }*/ 404 405 } 568 406 569 407 int Execute() … … 576 414 poll_one(); 577 415 578 const int rc = fLid.GetState(); 579 580 if (T::GetCurrentState()==Lid::State::kMoving && 581 (rc==Lid::State::kConnected || rc==Lid::State::kDisconnected) && 582 fLastCommand+boost::posix_time::seconds(6*fLid.GetInterval()) < Time()) 583 return Lid::State::kMoving; 584 585 return rc==Lid::State::kConnected ? T::GetCurrentState() : rc; 416 return fPower.GetState(); 586 417 } 587 418 … … 589 420 public: 590 421 StateMachinePowerControl(ostream &out=cout) : 591 T(out, " LID_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),592 f Lid(*this, *this)422 T(out, "PWR_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)), 423 fPower(*this, *this) 593 424 { 594 425 // ba::io_service::work is a kind of keep_alive for the loop. … … 600 431 601 432 // State names 602 T::AddStateName( Lid::State::kDisconnected, "NoConnection",433 T::AddStateName(Power::State::kDisconnected, "NoConnection", 603 434 "No connection to web-server could be established recently"); 604 435 605 T::AddStateName( Lid::State::kConnected, "Connected",436 T::AddStateName(Power::State::kConnected, "Connected", 606 437 "Connection established, but status still not known"); 607 438 608 T::AddStateName(Lid::State::kInconsistent, "Inconsistent", 609 "Both lids show different states"); 610 611 T::AddStateName(Lid::State::kUnknown, "Unknown", 612 "Arduino resports both lids in an unknown status"); 613 614 T::AddStateName(Lid::State::kClosed, "Closed", 615 "Both lids are closed"); 616 617 T::AddStateName(Lid::State::kOpen, "Open", 618 "Both lids are open"); 439 T::AddStateName(Power::State::kSystemOff, "PowerOff", 440 "Camera, Bias and Drive power off"); 441 442 T::AddStateName(Power::State::kBiasOn, "BiasOn", 443 "Camera and Drive power off, Bias on"); 444 445 T::AddStateName(Power::State::kDriveOn, "DriveOn", 446 "Camera and Bias power off, Drive on"); 447 448 T::AddStateName(Power::State::kCameraOn, "CameraOn", 449 "Drive and Bias power off, Camera on"); 450 451 T::AddStateName(Power::State::kDriveOn|Power::State::kCameraOn, "BiasOff", 452 "Camera and Drive power on, Bias off"); 453 454 T::AddStateName(Power::State::kBiasOn|Power::State::kCameraOn, "DriveOff", 455 "Camera and Bias power on, Drive off"); 456 457 T::AddStateName(Power::State::kDriveOn|Power::State::kBiasOn, "CameraOff", 458 "Drive and Bias power on, Camera off"); 459 460 T::AddStateName(Power::State::kDriveOn|Power::State::kBiasOn|Power::State::kCameraOn, "SystemOn", 461 "Camera, Bias and drive power on"); 619 462 620 463 … … 623 466 (bind(&StateMachinePowerControl::SetVerbosity, this, placeholders::_1)) 624 467 ("set verbosity state" 625 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data"); 626 627 T::AddEvent("OPEN", Lid::State::kInconsistent, Lid::State::kClosed) 628 (bind(&StateMachinePowerControl::Open, this)); 629 630 T::AddEvent("CLOSE", Lid::State::kInconsistent, Lid::State::kOpen) 631 (bind(&StateMachinePowerControl::Close, this)); 468 "|verbosity[bool]:disable or enable verbosity for interpreted data (yes/no)"); 469 470 T::AddEvent("SET_DEBUG_RX", "B") 471 (bind(&StateMachinePowerControl::SetDebugRx, this, placeholders::_1)) 472 ("set debux-rx state" 473 "|debug[bool]:dump received text and parsed text to console (yes/no)"); 474 475 T::AddEvent("CAMERA_POWER", "B") 476 (bind(&StateMachinePowerControl::SetCameraPower, this, placeholders::_1)); 477 478 T::AddEvent("TOGGLE_DRIVE") 479 (bind(&StateMachinePowerControl::ToggleDrive, this)); 632 480 633 481 T::AddEvent("POST", "C") … … 639 487 int EvalOptions(Configuration &conf) 640 488 { 641 fLid.SetVerbose(!conf.Get<bool>("quiet")); 642 fLid.SetInterval(conf.Get<uint16_t>("interval")); 643 fLid.SetDebugTx(conf.Get<bool>("debug-tx")); 644 fLid.SetSite(conf.Get<string>("url")); 645 fLid.SetEndpoint(conf.Get<string>("addr")); 646 fLid.StartConnect(); 489 fPower.SetVerbose(!conf.Get<bool>("quiet")); 490 fPower.SetInterval(conf.Get<uint16_t>("interval")); 491 fPower.SetDebugTx(conf.Get<bool>("debug-tx")); 492 fPower.SetDebugRx(conf.Get<bool>("debug-rx")); 493 fPower.SetSite(conf.Get<string>("url")); 494 fPower.SetEndpoint(conf.Get<string>("addr")); 495 fPower.StartConnect(); 647 496 648 497 return -1; … … 671 520 ("interval,i", var<uint16_t>(5), "Interval between two updates on the server in seconds") 672 521 ("debug-tx", po_bool(), "Enable debugging of ethernet transmission.") 522 ("debug-rx", po_bool(), "Enable debugging for received data.") 673 523 ; 674 524
Note:
See TracChangeset
for help on using the changeset viewer.