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.

409 lines
15 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "main_control_service.hpp"
  2. #include "configs/project_setting.hpp"
  3. #include "iflytop/components/zcanreceiver/zcanreceiverhost.hpp"
  4. #include "iflytop/core/components/stringutils.hpp"
  5. #include "iflytop/core/core.hpp"
  6. #include "version.hpp"
  7. using namespace iflytop;
  8. using namespace core;
  9. using namespace std;
  10. using namespace nlohmann;
  11. #define BIND
  12. static void getJsonValFromJson(json j, int& val) {
  13. if (j.is_string()) {
  14. string valstr = j;
  15. val = atoi(valstr.c_str());
  16. } else if (j.is_number()) {
  17. val = j;
  18. } else {
  19. throw std::runtime_error("getJsonValFromJson(int) error");
  20. }
  21. }
  22. template <typename T>
  23. static T jsonGet(json j) {
  24. T val;
  25. getJsonValFromJson(j, val);
  26. return val;
  27. }
  28. void MainControlService::initialize() {
  29. GET_TO_SERVICE(m_zconfig);
  30. // m_dbService.reset(new DBService());
  31. // m_dbService->initialize();
  32. BUILD_AND_REG_SERRVICE(DBService);
  33. GET_SERVICE(DBService)->initialize();
  34. GET_TO_SERVICE(m_dbService);
  35. /**
  36. * @brief
  37. */
  38. BUILD_AND_REG_SERRVICE(DeviceStateService);
  39. GET_SERVICE(DeviceStateService)->initialize();
  40. GET_TO_SERVICE(m_deviceStateService);
  41. BUILD_AND_REG_SERRVICE(ZCanHost);
  42. GET_SERVICE(ZCanHost)->initialize(m_zconfig->get_iflytopSubDeviceCanIFName(), m_zconfig->get_iflytopSubDeviceCanBitrate(), false);
  43. GET_TO_SERVICE(m_zcanhost);
  44. BUILD_AND_REG_SERRVICE(DisinfectionLogsManager);
  45. GET_SERVICE(DisinfectionLogsManager)->initialize();
  46. GET_TO_SERVICE(m_disinfectionLogsManager);
  47. BUILD_AND_REG_SERRVICE(DeviceIoControlService);
  48. GET_SERVICE(DeviceIoControlService)->initialize();
  49. GET_TO_SERVICE(m_deviceIoControlService);
  50. m_deviceIoControlService->startScan();
  51. /**
  52. * @brief Get the to service object
  53. */
  54. m_disinfectionCtrlService.reset(new DisinfectionCtrlService());
  55. m_disinfectionCtrlService->initialize();
  56. m_restfulServer.reset(new RestfulServer());
  57. m_restfulServer->regAPI("/hello_world", RESTFUL_SERVER_BIND(MainControlService::hello_world));
  58. m_restfulServer->regAPI("/api1/script_processer/doscript", RESTFUL_SERVER_BIND(MainControlService::doscript));
  59. m_restfulServer->regAPI("/api1/script_processer/stopscript", RESTFUL_SERVER_BIND(MainControlService::stopscript));
  60. m_restfulServer->start(20000, 20001, "0.0.0.0");
  61. m_iflytopwsService.reset(new IflytopFrontEndService());
  62. m_iflytopwsService->initialize("0.0.0.0");
  63. m_iflytopwsService->onMessage.connect([this](weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
  64. string cmdstr = cmd["command"];
  65. if (cmdstr != "getState") {
  66. logger->info("rx:{}", cmd.dump());
  67. }
  68. processFrontEndMessage(webSocket, cmd, receipt);
  69. if (cmdstr != "getState") {
  70. logger->info("tx:{}", receipt.dump());
  71. }
  72. });
  73. m_iflytopwsService->onUdpCmdMessage.connect([this](struct sockaddr_in* from, char* data, size_t len) {
  74. //
  75. for (size_t i = 0; i < len; i++) {
  76. if (data[i] == '\r' || data[i] == '\n') {
  77. data[i] = '\0';
  78. }
  79. }
  80. bool execsuc = false;
  81. for (size_t i = 0; i < len; i++) {
  82. if (data[i] != '\0') {
  83. int inext = strlen(&data[i]) + i;
  84. {
  85. string retmsg;
  86. execsuc = m_zcanhost->execcmd(string(&data[i]), retmsg);
  87. string retmsgstr = fmt::format("{},{}", execsuc ? "suc" : "fail", retmsg);
  88. m_iflytopwsService->sendToUDP(from, retmsgstr.c_str(), retmsgstr.size());
  89. }
  90. i = inext;
  91. if (!execsuc) {
  92. break;
  93. }
  94. }
  95. }
  96. });
  97. m_iflytopwsService->startListen();
  98. m_reportThread.reset(new Thread("reportThread", [this]() {
  99. ThisThread thisThread;
  100. while (!thisThread.getExitFlag()) {
  101. json report;
  102. report["command"] = "RealtimeSensorDataReport";
  103. report["sensor_data"] = createSensorDataJson();
  104. m_iflytopwsService->sendReport(report);
  105. thisThread.sleepForMs(1000);
  106. }
  107. }));
  108. };
  109. json MainControlService::createSensorDataJson() {
  110. json report;
  111. report["airCompressor"]["io1"] = m_deviceIoControlService->airCompressor_getio1();
  112. report["airCompressor"]["io2"] = m_deviceIoControlService->airCompressor_getio2();
  113. report["airCompressor"]["currentVal"] = m_deviceIoControlService->airCompressor_getcurrentValue();
  114. report["airBlower"]["io1"] = m_deviceIoControlService->airBlower_getio1();
  115. report["airBlower"]["io2"] = m_deviceIoControlService->airBlower_getio2();
  116. report["airBlower"]["currentVal"] = m_deviceIoControlService->airBlower_getcurrentValue();
  117. report["heatingStrip"]["io1"] = m_deviceIoControlService->heatingStrip_getio1();
  118. report["heatingStrip"]["io2"] = m_deviceIoControlService->heatingStrip_getio2();
  119. report["heatingStrip"]["currentVal"] = m_deviceIoControlService->heatingStrip_getcurrentValue();
  120. report["sprinklerPump"] = m_deviceIoControlService->sprayLiquidPump_getRPM();
  121. report["chargingPump"] = m_deviceIoControlService->getChargingPump_PumpRPM();
  122. report["waterImmersionSensor1"] = m_deviceIoControlService->getWaterImmersionSensor1();
  123. report["waterImmersionSensor2"] = m_deviceIoControlService->getWaterImmersionSensor2();
  124. // Water immersion sensor
  125. report["disinfectant_volume"] = m_deviceIoControlService->getDisinfectantVolume_g();
  126. // report["h2o2_1"] = m_deviceIoControlService->getH2O2SenSorData1().h2o2;
  127. report["h2o2_1"] = m_deviceIoControlService->getH2O2SenSorData1().h2o2;
  128. report["temp_1"] = m_deviceIoControlService->getH2O2SenSorData1().temp;
  129. report["humid_1"] = m_deviceIoControlService->getH2O2SenSorData1().humid;
  130. report["saturation_1"] = m_deviceIoControlService->getH2O2SenSorData1().saturation + 1; //为了让曲线不重叠
  131. // logger->info("m_deviceIoControlService->getH2O2SenSorData1().h2o2 {}", m_deviceIoControlService->getH2O2SenSorData1().h2o2);
  132. report["h2o2_2"] = -1;
  133. report["temp_2"] = -1;
  134. report["humid_2"] = -1;
  135. report["saturation_2"] = -1;
  136. report["h2o2_3"] = -1;
  137. report["temp_3"] = -1;
  138. report["humid_3"] = -1;
  139. report["saturation_3"] = -1;
  140. return report;
  141. }
  142. // {"command":"startReplenishingFluids","messageId":"startReplenishingFluids","stopAt":123}
  143. void MainControlService::processFrontEndMessage(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
  144. string cmdstr = cmd["command"];
  145. /*******************************************************************************
  146. * LOGIN_CMD *
  147. *******************************************************************************/
  148. if (cmdstr == "login") {
  149. string uid = cmd["userid"];
  150. string pwd = cmd["passwd"];
  151. auto usr = m_dbService->getUser(uid);
  152. if (usr == nullptr) {
  153. logger->warn("login fail, user {} not exist", uid);
  154. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kuser_not_exist);
  155. receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kuser_not_exist, "");
  156. return;
  157. }
  158. if (usr->passwd != pwd) {
  159. logger->warn("login fail, user {} passwd error", uid);
  160. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kpasswd_error);
  161. receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kpasswd_error, "");
  162. return;
  163. }
  164. m_deviceStateService->setLoginState(uid, usr->permission_level, usr->visible);
  165. logger->info("user {} login success", uid);
  166. return;
  167. }
  168. /*******************************************************************************
  169. * unlogin *
  170. *******************************************************************************/
  171. if (cmdstr == "unlogin") {
  172. m_deviceStateService->unlogin();
  173. logger->info("user unlogin success");
  174. return;
  175. }
  176. /*******************************************************************************
  177. * chpasswd *
  178. *******************************************************************************/
  179. if (cmdstr == "chpasswd") {
  180. string uid = cmd["userid"];
  181. string pwd = cmd["passwd"];
  182. logger->info("changet passwd {} {}", uid, pwd);
  183. return;
  184. }
  185. /*******************************************************************************
  186. * shutdown *
  187. *******************************************************************************/
  188. if (cmdstr == "shutdown") {
  189. int delayms = jsonGet<int>(cmd["delayms"]);
  190. logger->info("shutdown {} ms", delayms);
  191. m_autoshutdownThread.reset(new Thread("autoShutdown", [delayms]() {
  192. ThisThread thisThread;
  193. thisThread.sleepForMs(delayms);
  194. system("shutdown -h now");
  195. }));
  196. return;
  197. }
  198. if (cmdstr == "updateDate") {
  199. #if 0
  200. {
  201. "command":"updateDate",
  202. "messageId":"1111222333444555",
  203. "year":2023,
  204. "month":8,
  205. "day":25,
  206. "hour":11,
  207. "min":12,
  208. "second":13,
  209. }
  210. #endif
  211. int32_t year = jsonGet<int>(cmd["year"]);
  212. int32_t month = jsonGet<int>(cmd["month"]);
  213. int32_t day = jsonGet<int>(cmd["day"]);
  214. int32_t hour = jsonGet<int>(cmd["hour"]);
  215. int32_t min = jsonGet<int>(cmd["min"]);
  216. int32_t second = jsonGet<int>(cmd["second"]);
  217. logger->info("updateDate {} {} {} {}:{}:{}", year, month, day, hour, min, second);
  218. return;
  219. }
  220. /*******************************************************************************
  221. * *
  222. *******************************************************************************/
  223. if (cmdstr == "startDisinfection") {
  224. int loglevel = jsonGet<int>(cmd["loglevel"]);
  225. int roomVolume = jsonGet<int>(cmd["roomVolume"]); //
  226. m_disinfectionCtrlService->startDisinfection(loglevel, roomVolume);
  227. return;
  228. }
  229. if (cmdstr == "stopDisinfection") {
  230. m_disinfectionCtrlService->stopDisinfection();
  231. return;
  232. }
  233. #if 0
  234. //开始加液
  235. {
  236. "command":"startReplenishingFluids",
  237. }
  238. //停止加液
  239. {
  240. "command":"stopReplenishingFluids",
  241. }
  242. //开始排液
  243. {
  244. "command":"startDraining",
  245. }
  246. //停止排液
  247. {
  248. "command":"stopDraining",
  249. }
  250. #endif
  251. if (cmdstr == "startReplenishingFluids") {
  252. int16_t stopAt = jsonGet<int>(cmd["stopAt"]);
  253. logger->info("startReplenishingFluids {}", stopAt);
  254. m_disinfectionCtrlService->startReplenishingFluids(stopAt);
  255. return;
  256. }
  257. if (cmdstr == "stopReplenishingFluids") {
  258. logger->info("stopReplenishingFluids");
  259. m_disinfectionCtrlService->stopReplenishingFluids();
  260. return;
  261. }
  262. if (cmdstr == "startDraining") {
  263. logger->info("startDraining");
  264. m_disinfectionCtrlService->startDraining();
  265. return;
  266. }
  267. if (cmdstr == "stopDraining") {
  268. logger->info("stopDraining");
  269. m_disinfectionCtrlService->stopDraining();
  270. return;
  271. }
  272. /*******************************************************************************
  273. * getState *
  274. *******************************************************************************/
  275. if (cmdstr == "getState") {
  276. receipt["state"]["isLogin"] = m_deviceStateService->isLogin();
  277. receipt["state"]["loginuser"] = m_deviceStateService->getLoginUid();
  278. receipt["state"]["permissionLevel"] = m_deviceStateService->getLoginPermissionLevel();
  279. // receipt["state"]["workState"] = m_disinfectionCtrlService->isDisinfectionRunning();
  280. receipt["state"]["disinfectionWorkState"] = m_disinfectionCtrlService->getDisinfectionWorkState();
  281. receipt["state"]["replenishingFluidsWorkState"] = m_disinfectionCtrlService->getReplenishingFluidsWorkState();
  282. receipt["state"]["drainingWorkState"] = m_disinfectionCtrlService->getDrainingWorkState();
  283. receipt["state"]["estimatedRemainingTimeS"] = m_disinfectionCtrlService->getEstimatedRemainingTimeS();
  284. receipt["state"]["disinfection_id"] = m_disinfectionCtrlService->getDisinfectionID();
  285. // receipt["state"]["preHeat"] = m_disinfectionCtrlService->processPreheatState
  286. // getPreHeatRaminTimeS
  287. // isPreheatState
  288. receipt["state"]["preHeat"] = m_disinfectionCtrlService->isPreheatState();
  289. receipt["state"]["preHeatRaminTimeS"] = m_disinfectionCtrlService->getPreHeatRaminTimeS(); // 预热剩余时间
  290. receipt["state"]["sensor_data"] = createSensorDataJson();
  291. return;
  292. }
  293. /*******************************************************************************
  294. * *
  295. *******************************************************************************/
  296. // {
  297. // "command":"exceCanCmd",
  298. // "cancmd": "",
  299. // }
  300. if (cmdstr == "exceCanCmd") {
  301. string cancmd = cmd["cancmd"];
  302. logger->info("exceCanCmd {}", cancmd);
  303. string receipt_str;
  304. bool suc = m_zcanhost->execcmd(cancmd, receipt_str);
  305. receipt["receipt_str"] = receipt_str;
  306. if (!suc) {
  307. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kfail);
  308. }
  309. return;
  310. }
  311. /*******************************************************************************
  312. * *
  313. *******************************************************************************/
  314. if (cmdstr == "getAllUser") {
  315. auto users = m_dbService->getAllUserJson();
  316. receipt["dbval"] = users;
  317. return;
  318. }
  319. if (cmdstr == "getAllSetting") {
  320. auto dbval = m_dbService->getAllSettingJson();
  321. receipt["dbval"] = dbval;
  322. return;
  323. }
  324. if (cmdstr == "getAllRecords") {
  325. string disinfection_id = cmd["disinfection_id"];
  326. auto dbval = m_dbService->getAllRecords(disinfection_id);
  327. receipt["dbval"] = dbval;
  328. return;
  329. }
  330. if (cmdstr == "setSettingVal") {
  331. string settingName = cmd["settingName"];
  332. int settingVal = jsonGet<int>(cmd["settingVal"]);
  333. bool suc = m_dbService->setSettingVal(settingName, settingVal);
  334. if (!suc) {
  335. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kdb_operate_error);
  336. receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kdb_operate_error, "setSettingVal fail");
  337. }
  338. return;
  339. }
  340. }
  341. HttpResponsePtr MainControlService::hello_world( //
  342. HttpRequestPtr request, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState>) {
  343. return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world");
  344. }
  345. HttpResponsePtr MainControlService::doscript(HttpRequestPtr httpreq, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState> conn) {
  346. // logger->info("do\n{}", httpreq->body);
  347. // if (m_a8000_script_processer->isWorking()) {
  348. // return std::make_shared<HttpResponse>(200, "FAIL", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script fail, script processer is running");
  349. // }
  350. // m_a8000_script_processer->executeScript(httpreq->body);
  351. return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script success");
  352. }
  353. HttpResponsePtr MainControlService::stopscript(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>) {
  354. // m_a8000_script_processer->stopScript();
  355. return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "stop script success");
  356. }