You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

678 lines
25 KiB

1 year ago
  1. #include "disinfection_ctl_service.hpp"
  2. using namespace iflytop;
  3. using namespace std;
  4. /**
  5. * @brief
  6. *
  7. * :
  8. *
  9. *
  10. * 1s
  11. *
  12. * 1s
  13. *
  14. * 1s
  15. *
  16. *
  17. *
  18. * 1s
  19. *
  20. * 1s
  21. *
  22. *
  23. */
  24. // #define PRE_HEAT_TIME (2)
  25. // #define PRE_HEAT_TIME (5 * 60)
  26. #define DVALUE_COMPUTEPERIOD_TIME_S (10.0)
  27. #define MAX_VOLUME (5000)
  28. namespace iflytop {
  29. extern bool g_in_test;
  30. }
  31. DisinfectionCtrlService::DisinfectionCtrlService() {}
  32. void DisinfectionCtrlService::initialize() {
  33. GET_TO_SERVICE(m_zcanHost);
  34. GET_TO_SERVICE(m_deviceIoControlService);
  35. GET_TO_SERVICE(m_dbService);
  36. GET_TO_SERVICE(m_disinfectionLogsManager);
  37. m_deviceIoControlService->drainingPump_close();
  38. m_deviceIoControlService->replenishingFluidsPump_close();
  39. m_deviceIoControlService->sprayLiquidPump_close();
  40. m_deviceIoControlService->heartingPlate_setPower(false);
  41. m_deviceIoControlService->airBlower_setState(false);
  42. m_deviceIoControlService->airCompressor_setState(false);
  43. m_dvalueComputer.initialize();
  44. }
  45. static string getTime() {
  46. struct tm tm = {0};
  47. time_t t = time(nullptr);
  48. struct tm* tmp = localtime_r(&t, &tm);
  49. return fmt::format("{:0>4}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", tm.tm_year + 1900, //
  50. tm.tm_mon + 1, //
  51. tm.tm_mday, //
  52. tm.tm_hour, //
  53. tm.tm_min, tm.tm_sec);
  54. }
  55. string DisinfectionCtrlService::createDisinfectionID() {
  56. struct tm tm = {0};
  57. time_t t = time(nullptr);
  58. if (t == -1) {
  59. logger->error("time(nullptr) failed");
  60. exit(-1);
  61. }
  62. struct tm* tmp = localtime_r(&t, &tm);
  63. if (!tmp) {
  64. logger->error("localtime_r failed");
  65. exit(-1);
  66. }
  67. // tm = *utctime::tm_increment_hour(&tm, 8);
  68. // logger->info("trace sendmsg_startCapture {}:{}", __FILE__, __LINE__);
  69. return fmt::format("{:0>4}-{:0>2}{:0>2}-{:0>2}{:0>2}{:0>2}", tm.tm_year + 1900, //
  70. tm.tm_mon + 1, //
  71. tm.tm_mday, //
  72. tm.tm_hour, //
  73. tm.tm_min, tm.tm_sec);
  74. }
  75. static bool zfeq(float a, float b, float eps = 0.01) {
  76. if (fabs(a - b) < eps) {
  77. return true;
  78. }
  79. return false;
  80. }
  81. float DisinfectionCtrlService::getDisinfectionDValue(float ppm) { //
  82. return m_dvalueComputer.computeDValue(ppm);
  83. }
  84. float DisinfectionCtrlService::computeNowLogLevel(DisinfectionContext& context) {
  85. float dvalue = context.dvalue;
  86. if (dvalue > 0) {
  87. /**
  88. * @brief m_nowLoglevel
  89. */
  90. return context.m_nowLoglevel + DVALUE_COMPUTEPERIOD_TIME_S / (dvalue * 60);
  91. }
  92. return context.m_nowLoglevel;
  93. }
  94. void DisinfectionCtrlService::computeRemainTime(DisinfectionContext& context) {
  95. /**
  96. * @brief Dvalue
  97. */
  98. float dvalue = context.dvalue;
  99. if (dvalue > 0) {
  100. /**
  101. * @brief m_nowLoglevel
  102. */
  103. if (context.m_targetLoglevel >= context.m_nowLoglevel) {
  104. context.m_remaintime = (context.m_targetLoglevel - context.m_nowLoglevel) * (dvalue * 60);
  105. } else {
  106. context.m_remaintime = 0;
  107. }
  108. } else {
  109. //
  110. }
  111. logger->info("computeRemainTime minh2o2 {} dvalue {}", context.h2o2data.min_h2o2, dvalue);
  112. }
  113. void DisinfectionCtrlService::initContext(DisinfectionContext& context, //
  114. int loglevel, //
  115. float injection_pump_speed, //
  116. float stoped_gs, //
  117. float continued_gs, //
  118. float stoped_satur, //
  119. float continued_satur, //
  120. float stoped_humi, //
  121. float continued_humi //
  122. ) {
  123. context.m_disinfectionID = createDisinfectionID();
  124. context.pre_heat_time_s = m_dbService->getSettingVal("pre_heat_time_s");
  125. context.stoped_gs = stoped_gs;
  126. context.continued_gs = continued_gs;
  127. context.stoped_satur = stoped_satur;
  128. context.continued_satur = continued_satur;
  129. context.stoped_humi = stoped_humi;
  130. context.continued_humi = continued_humi;
  131. context.injection_pump_speed = injection_pump_speed;
  132. context.injection_pump_speed_changed = true;
  133. if (g_in_test) {
  134. logger->warn("in test mode, pre_heat_time_s = 5");
  135. context.pre_heat_time_s = 5;
  136. }
  137. logger->info("startDisinfection {} {}", m_context.m_targetLoglevel, m_context.m_disinfectionID);
  138. logger->info(" stoped_gs {}", context.stoped_gs);
  139. logger->info(" continued_gs {}", context.continued_gs);
  140. logger->info(" stoped_satur {}", context.stoped_satur);
  141. logger->info(" continued_satur {}", context.continued_satur);
  142. logger->info(" stoped_humi {}", context.stoped_humi);
  143. logger->info(" continued_humi {}", context.continued_humi);
  144. logger->info(" pre_heat_time_s {}", context.pre_heat_time_s);
  145. logger->info("");
  146. // m_remaintime = loglevel * 20 * 60; // 计算总的加热时间
  147. context.m_remaintime = context.pre_heat_time_s + loglevel * 90 * 60; // 计算总的加热时间
  148. m_disinfectionWorkState = 1;
  149. context.m_targetLoglevel = loglevel;
  150. context.m_nowLoglevel = 0;
  151. // m_context.m_preheatFlag = true;
  152. m_context.dvalue = 0;
  153. // m_context.stopedflag = false;
  154. m_context.m_state = kpreheat;
  155. m_context.m_starttp = zsteady_clock().now();
  156. m_zcanHost->warning_light_ctrl_c1002(1, 0, 0, 1, 0);
  157. m_deviceIoControlService->heartingPlate_setPower(true);
  158. context.csvlogger = m_disinfectionLogsManager->createNewLogger(context.m_disinfectionID);
  159. // zsteady_clock().elapsedTimeS(m_context.m_starttp), //
  160. // sensors[0].h2o2, sensors[0].temp, sensors[0].humid, sensors[0].saturation, //
  161. // sensors[1].h2o2, sensors[1].temp, sensors[1].humid, sensors[1].saturation, //
  162. // sensors[2].h2o2, sensors[2].temp, sensors[2].humid, sensors[2].saturation, //
  163. // m_context.dvalue, m_context.m_nowLoglevel, (int)m_context.m_targetLoglevel, //
  164. // ds->heatingStrip_getstate(), ds->airBlower_getstate(), ds->airCompressor_getstate(), ds->sprayLiquidPump_getRPM(), //
  165. // ds->getPressureSensorData(1), ds->getPressureSensorData(2), ds->getPressureSensorData(3), ds->getPressureSensorData(4), //
  166. // m_deviceIoControlService->getDisinfectantVolume_g(), //
  167. // m_context.m_remaintime
  168. context.csvlogger->write(
  169. "Date," //
  170. "Hydrogen peroxide volume(ppm),Temperature(C),Relative humidity(%RH),H2O H2O2 RS(%RS)," //
  171. // "h2o22,temp2,humi2,saturation2," //
  172. // "h2o23,temp3,humi3,saturation3," //
  173. "Dvalue,Loglevel,Targetloglevel," //
  174. "Heating,Blower,Compressor,Pump(g/min)," //
  175. "Disinfectant Volume(g)," //
  176. "Remaining time (s)\n" //
  177. );
  178. }
  179. static string formattimeS(int sec) {
  180. if (sec >= 0) {
  181. return fmt::format("{:0>2}:{:0>2}:{:0>2}", sec / 3600, sec % 3600 / 60, sec % 60);
  182. } else {
  183. return fmt::format("--:--:--");
  184. }
  185. }
  186. void DisinfectionCtrlService::dumpDisinfectionLogsToCSV(DisinfectionContext& context) {
  187. auto* sensors = &m_context.h2o2data.h2o2sensor_data[0];
  188. auto ds = m_deviceIoControlService;
  189. float dvalue = 0;
  190. if (m_context.dvalue <= 0) {
  191. dvalue = 0;
  192. } else {
  193. dvalue = m_context.dvalue;
  194. }
  195. int remaintime = getEstimatedRemainingTimeS();
  196. context.csvlogger->write(
  197. fmt::format("{}," //
  198. "{},{},{},{}," //
  199. // "{},{},{},{}," //
  200. // "{},{},{},{}," //
  201. "{},{},{}," //
  202. "{},{},{},{}," //
  203. // "{},{},{},{}," //
  204. "{}," //
  205. "{}\n" //
  206. ,
  207. getTime(), //
  208. sensors[0].h2o2, sensors[0].temp, sensors[0].humid, sensors[0].saturation, //
  209. // sensors[1].h2o2, sensors[1].temp, sensors[1].humid, sensors[1].saturation, //
  210. // sensors[2].h2o2, sensors[2].temp, sensors[2].humid, sensors[2].saturation, //
  211. (int32_t)dvalue, (int32_t)m_context.m_nowLoglevel, (int32_t)m_context.m_targetLoglevel, //
  212. ds->heatingStrip_getstate(), ds->airBlower_getstate(), ds->airCompressor_getstate(), ds->sprayLiquidPump_getGPM(), //
  213. m_deviceIoControlService->getDisinfectantVolume_g(), //
  214. formattimeS(remaintime)));
  215. }
  216. void DisinfectionCtrlService::finishDisinfection(DisinfectionContext& context) {
  217. context.m_remaintime = 0;
  218. logger->info("stop disinfection {}", context.m_disinfectionID);
  219. // sprayLiquidPump_close();
  220. m_deviceIoControlService->sprayLiquidPump_close();
  221. usleep(1000 * 1000);
  222. // airCompressor(false);
  223. m_deviceIoControlService->airCompressor_setState(false);
  224. usleep(1000 * 1000);
  225. // blower_setPower(false);
  226. m_deviceIoControlService->airBlower_setState(false);
  227. usleep(1000 * 1000);
  228. // heartingPlate_setPower(false);
  229. m_deviceIoControlService->heartingPlate_setPower(false);
  230. m_disinfectionWorkState = 3;
  231. m_zcanHost->warning_light_ctrl_c1002(1, 0, 0, 0, 0);
  232. context.csvlogger = nullptr;
  233. }
  234. void DisinfectionCtrlService::processPreheatState(DisinfectionContext& context) {
  235. int hasstarttime = zsteady_clock().elapsedTimeS(context.m_starttp);
  236. // logger->info("preheat {}", context.m_disinfectionID);
  237. if ((context.m_state == kpreheat && hasstarttime > m_context.pre_heat_time_s)) {
  238. logger->info("preheat finished {}", context.m_disinfectionID);
  239. // blower_setPower(true);
  240. m_deviceIoControlService->airBlower_setState(true);
  241. usleep(1000 * 1000);
  242. // airCompressor(true);
  243. m_deviceIoControlService->airCompressor_setState(true);
  244. usleep(1000 * 1000);
  245. // sprayLiquidPump_open();
  246. m_deviceIoControlService->sprayLiquidPump_open(context.injection_pump_speed);
  247. context.m_state = kdisinfection;
  248. // context.m_preheatFlag = false;
  249. // context.sprayLiquidFlag = true;
  250. } else {
  251. logger->info("{}: preheat {}", context.m_disinfectionID, m_context.pre_heat_time_s - hasstarttime);
  252. }
  253. }
  254. void DisinfectionCtrlService::dumpDisinfectionLogs(DisinfectionContext& context) {
  255. // float h2o2_g = m_deviceIoControlService->getDisinfectantVolume_g();
  256. auto* sensors = &m_context.h2o2data.h2o2sensor_data[0];
  257. auto ds = m_deviceIoControlService;
  258. logger->info(
  259. "T:{}," //
  260. "s1:({},{},{},{})," //
  261. "s2:({},{},{},{})," //
  262. "s3:({},{},{},{})," //
  263. "D:{},log:({}:{})," //
  264. "io:({},{},{},{})," //
  265. "p:({},{},{},{})," //
  266. "h2o2g:{}," //
  267. "rt:{}" //
  268. ,
  269. zsteady_clock().elapsedTimeS(m_context.m_starttp), //
  270. sensors[0].h2o2, sensors[0].temp, sensors[0].humid, sensors[0].saturation, //
  271. sensors[1].h2o2, sensors[1].temp, sensors[1].humid, sensors[1].saturation, //
  272. sensors[2].h2o2, sensors[2].temp, sensors[2].humid, sensors[2].saturation, //
  273. m_context.dvalue, m_context.m_nowLoglevel, (int)m_context.m_targetLoglevel, //
  274. ds->heatingStrip_getstate(), ds->airBlower_getstate(), ds->airCompressor_getstate(), ds->sprayLiquidPump_getRPM(), //
  275. ds->getPressureSensorData(1), ds->getPressureSensorData(2), ds->getPressureSensorData(3), ds->getPressureSensorData(4), //
  276. m_deviceIoControlService->getDisinfectantVolume_g(), //
  277. getEstimatedRemainingTimeS());
  278. }
  279. /**
  280. * @brief
  281. *
  282. */
  283. void DisinfectionCtrlService::processDisinfectionState(DisinfectionContext& context) {
  284. ZCHECK(context.m_state == kdisinfection || context.m_state == kdisinfection_take_a_break, "state error");
  285. /**
  286. * @brief
  287. */
  288. /**
  289. * @brief 湿
  290. */
  291. if (m_context.m_state == kdisinfection) {
  292. /**
  293. * @brief
  294. */
  295. float nowSatur = m_context.h2o2data.max_saturation;
  296. float nowh2o2 = m_context.h2o2data.max_h2o2;
  297. float humid = m_context.h2o2data.max_humid;
  298. if (m_context.injection_pump_speed_changed) {
  299. m_deviceIoControlService->sprayLiquidPump_open(context.injection_pump_speed);
  300. m_context.injection_pump_speed_changed = false;
  301. }
  302. // humid > m_context.stoped_satur
  303. if (nowSatur > m_context.stoped_satur || nowh2o2 > m_context.stoped_gs || humid > m_context.stoped_humi) {
  304. logger->info("stop sprayLiquid");
  305. m_deviceIoControlService->sprayLiquidPump_close();
  306. usleep(1000 * 1000);
  307. m_deviceIoControlService->airCompressor_setState(false);
  308. // m_context.sprayLiquidFlag = false;
  309. m_context.m_state = kdisinfection_take_a_break;
  310. }
  311. } else {
  312. float nowSatur = m_context.h2o2data.max_saturation;
  313. float nowh2o2 = m_context.h2o2data.max_h2o2;
  314. float humid = m_context.h2o2data.max_humid;
  315. // && humid < m_context.continued_satur
  316. if (nowSatur < m_context.continued_satur && nowh2o2 < m_context.continued_gs && humid < context.continued_humi) {
  317. logger->info("start sprayLiquid");
  318. m_deviceIoControlService->sprayLiquidPump_open(context.injection_pump_speed);
  319. usleep(1000 * 1000);
  320. m_deviceIoControlService->airCompressor_setState(true);
  321. m_context.m_state = kdisinfection;
  322. }
  323. }
  324. }
  325. void DisinfectionCtrlService::disinfectionLoop(bool& breakflag) {
  326. // logger->info("disinfection running {} {}s preheatFlag:{}", m_context.m_disinfectionID, m_context.m_remaintime, m_context.m_preheatFlag);
  327. m_context.m_remaintime--;
  328. bool forcelog = false;
  329. if (m_context.m_remaintime < 0) {
  330. m_context.m_remaintime = 0;
  331. }
  332. /**
  333. * @brief
  334. */
  335. m_deviceIoControlService->getAllSensorData(m_context.h2o2data);
  336. /**
  337. * @brief D值
  338. */
  339. m_context.dvalue = getDisinfectionDValue(m_context.h2o2data.min_h2o2);
  340. if (zsteady_clock().elapsedTimeS(m_context.m_lastComputeDvalueTp) > DVALUE_COMPUTEPERIOD_TIME_S) {
  341. m_context.m_lastComputeDvalueTp = zsteady_clock().now();
  342. //
  343. if (m_context.m_state == kdisinfection || m_context.m_state == kdisinfection_take_a_break) {
  344. m_context.m_nowLoglevel = computeNowLogLevel(m_context);
  345. computeRemainTime(m_context);
  346. }
  347. }
  348. if (m_context.m_state == kpreheat) {
  349. /**
  350. * @brief
  351. */
  352. processPreheatState(m_context);
  353. } else if (m_context.m_state == kdisinfection || m_context.m_state == kdisinfection_take_a_break) {
  354. /**
  355. * @brief
  356. */
  357. processDisinfectionState(m_context);
  358. //
  359. if (m_context.m_remaintime <= 0 && m_context.m_nowLoglevel > (m_context.m_targetLoglevel + 0.01)) {
  360. m_context.m_remaintime = 0;
  361. m_context.m_nowLoglevel = m_context.m_targetLoglevel + 0.01;
  362. logger->info("disinfection finished {},but waitting for h2o2 to safe", m_context.m_disinfectionID);
  363. m_deviceIoControlService->sprayLiquidPump_close();
  364. usleep(1000 * 1000);
  365. m_deviceIoControlService->airCompressor_setState(false);
  366. usleep(1000 * 1000);
  367. m_deviceIoControlService->heartingPlate_setPower(false);
  368. m_context.m_state = kwait_for_h2o2_down;
  369. forcelog = true;
  370. }
  371. } else if (m_context.m_state == kwait_for_h2o2_down) {
  372. /**
  373. * @brief h2o2浓度下降
  374. */
  375. logger->info("waitting for h2o2 concentration to safe value {}=>{}", m_context.h2o2data.min_h2o2, 1);
  376. if (m_context.h2o2data.min_h2o2 < 1) {
  377. logger->info("h2o2 concentration to safe value");
  378. breakflag = true;
  379. forcelog = true;
  380. m_context.m_state = kfinished;
  381. }
  382. } else {
  383. ZCHECK(false, "state error");
  384. }
  385. if (forcelog || zsteady_clock().elapsedTimeS(m_context.m_lastlogTp) > DVALUE_COMPUTEPERIOD_TIME_S) {
  386. m_context.m_lastlogTp = zsteady_clock().now();
  387. dumpDisinfectionLogs(m_context);
  388. dumpDisinfectionLogsToCSV(m_context);
  389. }
  390. }
  391. void DisinfectionCtrlService::changeDisinfectionParameter(int injection_pump_speed, //
  392. int stoped_gs, //
  393. int continued_gs, //
  394. int stoped_satur, //
  395. int continued_satur, //
  396. int stoped_humi, //
  397. int continued_humi) {
  398. lock_guard<recursive_mutex> lock(lock_);
  399. // logger->info("changeInjectionPumpSpeed {}=>{}", m_context.injection_pump_speed, speed);
  400. // m_context.injection_pump_speed = speed;
  401. m_context.injection_pump_speed = injection_pump_speed;
  402. m_context.stoped_gs = stoped_gs;
  403. m_context.continued_gs = continued_gs;
  404. m_context.stoped_satur = stoped_satur;
  405. m_context.continued_satur = continued_satur;
  406. m_context.stoped_humi = stoped_humi;
  407. m_context.continued_humi = continued_humi;
  408. m_context.injection_pump_speed_changed = true;
  409. logger->info("changeDisinfectionParameter {} {} {} {} {} {} {}", injection_pump_speed, stoped_gs, continued_gs, stoped_satur, continued_satur, stoped_humi,
  410. continued_humi);
  411. }
  412. void DisinfectionCtrlService::startDisinfection(int loglevel, //
  413. int injection_pump_speed, //
  414. int stoped_gs, //
  415. int continued_gs, //
  416. int stoped_satur, //
  417. int continued_satur, //
  418. int stoped_humi, //
  419. int continued_humi //
  420. ) {
  421. lock_guard<recursive_mutex> lock(lock_);
  422. /**
  423. * @TODO
  424. * 湿湿
  425. */
  426. if (m_disinfectionThread) {
  427. stopDisinfection();
  428. }
  429. initContext(m_context, loglevel, injection_pump_speed, stoped_gs, continued_gs, stoped_satur, continued_satur, stoped_humi, continued_humi);
  430. m_disinfectionThread.reset(new Thread("m_disinfectionThread", [this]() {
  431. ThisThread thisThread;
  432. while (!thisThread.getExitFlag()) {
  433. thisThread.sleepForMs(1000);
  434. bool breakflag = false;
  435. disinfectionLoop(breakflag);
  436. if (breakflag) {
  437. break;
  438. }
  439. }
  440. //
  441. finishDisinfection(m_context);
  442. }));
  443. //
  444. }
  445. int DisinfectionCtrlService::getDisinfectionWorkState() { return m_context.m_state; }
  446. void DisinfectionCtrlService::stopDisinfection() {
  447. lock_guard<recursive_mutex> lock(lock_);
  448. if (m_disinfectionThread) {
  449. m_disinfectionThread->join();
  450. m_disinfectionThread = nullptr;
  451. }
  452. m_context.m_state = kfinished;
  453. m_disinfectionWorkState = 0;
  454. }
  455. int32_t DisinfectionCtrlService::getEstimatedRemainingTimeS() {
  456. lock_guard<recursive_mutex> lock(lock_);
  457. if (m_context.m_state == kpreheat) {
  458. return getPreHeatRaminTimeS();
  459. } else if (m_context.m_state == kdisinfection || m_context.m_state == kdisinfection_take_a_break) {
  460. if (m_context.dvalue > 0) {
  461. return m_context.m_remaintime;
  462. } else {
  463. return -1;
  464. }
  465. } else {
  466. return 0;
  467. }
  468. }
  469. int32_t DisinfectionCtrlService::getPreHeatRaminTimeS() {
  470. lock_guard<recursive_mutex> lock(lock_);
  471. int32_t remaintime = 0;
  472. if (m_context.m_state == kpreheat) {
  473. remaintime = m_context.pre_heat_time_s - zsteady_clock().elapsedTimeS(m_context.m_starttp);
  474. if (remaintime < 0) {
  475. remaintime = 0;
  476. }
  477. return remaintime;
  478. } else {
  479. return 0;
  480. }
  481. }
  482. string DisinfectionCtrlService::getDisinfectionID() {
  483. lock_guard<recursive_mutex> lock(lock_);
  484. return m_context.m_disinfectionID;
  485. }
  486. bool DisinfectionCtrlService::isPreheatState() {
  487. lock_guard<recursive_mutex> lock(lock_);
  488. return m_context.m_state == kpreheat;
  489. }
  490. int DisinfectionCtrlService::getReplenishingFluidsWorkState() { return m_replenishingFluidsWorkState; }
  491. int DisinfectionCtrlService::getDrainingWorkState() { return m_drainingWorkState; }
  492. /*******************************************************************************
  493. * // 加液 *
  494. *******************************************************************************/
  495. /**
  496. * @brief
  497. *
  498. * @param stopatg
  499. */
  500. void DisinfectionCtrlService::startReplenishingFluids(int stopatg) {
  501. lock_guard<recursive_mutex> lock(lock_);
  502. if (m_disinfectionThread) {
  503. m_disinfectionThread->join();
  504. m_disinfectionThread = nullptr;
  505. }
  506. int32_t nowvolume = m_deviceIoControlService->getDisinfectantVolume_g();
  507. if (nowvolume > stopatg) {
  508. logger->warn("start Replenishing fail, nowvolume {} > stopatg {}", nowvolume, stopatg);
  509. return;
  510. }
  511. m_disinfectionThread.reset(new Thread("disinfectionThread", [this, stopatg]() {
  512. ThisThread thisThread;
  513. m_deviceIoControlService->replenishingFluidsPump_open();
  514. logger->info("startReplenishingFluids {}g", stopatg);
  515. while (!thisThread.getExitFlag()) {
  516. int32_t nowvolume = m_deviceIoControlService->getDisinfectantVolume_g();
  517. logger->info("replenishingFluids {}g", nowvolume);
  518. if (nowvolume > stopatg) {
  519. break;
  520. }
  521. if (nowvolume > MAX_VOLUME) {
  522. logger->warn("replenishingFluids reach full level {}g", nowvolume);
  523. break;
  524. }
  525. thisThread.sleepForMs(1000);
  526. }
  527. logger->info("stopReplenishingFluids");
  528. // replenishingFluidsPump_close();
  529. m_deviceIoControlService->replenishingFluidsPump_close();
  530. m_replenishingFluidsWorkState = 0;
  531. }));
  532. //
  533. m_replenishingFluidsWorkState = 1;
  534. logger->info("startReplenishingFluids ");
  535. }
  536. /**
  537. * @brief
  538. *
  539. */
  540. void DisinfectionCtrlService::stopReplenishingFluids() {
  541. lock_guard<recursive_mutex> lock(lock_);
  542. if (m_disinfectionThread) {
  543. m_disinfectionThread->join();
  544. m_disinfectionThread = nullptr;
  545. }
  546. logger->info("stopReplenishingFluids");
  547. // replenishingFluidsPump_close();
  548. m_deviceIoControlService->replenishingFluidsPump_close();
  549. m_replenishingFluidsWorkState = 0;
  550. }
  551. /*******************************************************************************
  552. * *
  553. *******************************************************************************/
  554. /**
  555. * @brief
  556. *
  557. */
  558. void DisinfectionCtrlService::startDraining() {
  559. lock_guard<recursive_mutex> lock(lock_);
  560. if (m_disinfectionThread) {
  561. m_disinfectionThread->join();
  562. m_disinfectionThread = nullptr;
  563. }
  564. m_disinfectionThread.reset(new Thread("disinfectionThread", [this]() {
  565. ThisThread thisThread;
  566. m_deviceIoControlService->drainingPump_open();
  567. logger->info("startDraining ");
  568. auto startdrainingtime = zsteady_clock().now();
  569. zsteady_tp volumeReachZeroTime;
  570. bool volumeReachZeroFlag = false;
  571. while (!thisThread.getExitFlag()) {
  572. int32_t nowvolume = m_deviceIoControlService->getDisinfectantVolume_g();
  573. logger->info("draining remain {} g", nowvolume);
  574. if (!volumeReachZeroFlag && nowvolume == 0) {
  575. volumeReachZeroTime = zsteady_clock().now();
  576. volumeReachZeroFlag = true;
  577. }
  578. if (volumeReachZeroFlag) {
  579. logger->info("stopDraining after {} s", 30 - zsteady_clock().elapsedTimeS(volumeReachZeroTime));
  580. if (zsteady_clock().elapsedTimeS(volumeReachZeroTime) > 30) {
  581. break;
  582. }
  583. }
  584. thisThread.sleepForMs(1000);
  585. }
  586. logger->info("stopDraining");
  587. // replenishingFluidsPump_close();
  588. m_deviceIoControlService->drainingPump_close();
  589. m_drainingWorkState = 0;
  590. }));
  591. logger->info("startDraining");
  592. // drainingPump_open();
  593. m_drainingWorkState = 1;
  594. }
  595. /**
  596. * @brief
  597. */
  598. void DisinfectionCtrlService::stopDraining() {
  599. lock_guard<recursive_mutex> lock(lock_);
  600. if (m_disinfectionThread) {
  601. m_disinfectionThread->join();
  602. m_disinfectionThread = nullptr;
  603. }
  604. logger->info("stopDraining");
  605. m_drainingWorkState = 0;
  606. // drainingPump_close();
  607. m_deviceIoControlService->drainingPump_close();
  608. }