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.

399 lines
14 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. /**
  31. * @brief
  32. */
  33. BUILD_AND_REG_SERRVICE(DeviceStateService);
  34. GET_SERVICE(DeviceStateService)->initialize();
  35. GET_TO_SERVICE(m_deviceStateService);
  36. BUILD_AND_REG_SERRVICE(ZCanHost);
  37. GET_SERVICE(ZCanHost)->initialize(m_zconfig->get_iflytopSubDeviceCanIFName(), m_zconfig->get_iflytopSubDeviceCanBitrate(), false);
  38. GET_TO_SERVICE(m_zcanhost);
  39. BUILD_AND_REG_SERRVICE(SensorDataScan);
  40. GET_SERVICE(SensorDataScan)->initialize();
  41. GET_TO_SERVICE(m_sensorDataScan);
  42. m_sensorDataScan->startScan();
  43. /**
  44. * @brief Get the to service object
  45. */
  46. m_disinfectionCtrlService.reset(new DisinfectionCtrlService());
  47. m_disinfectionCtrlService->initialize();
  48. m_restfulServer.reset(new RestfulServer());
  49. m_restfulServer->regAPI("/hello_world", RESTFUL_SERVER_BIND(MainControlService::hello_world));
  50. m_restfulServer->regAPI("/api1/script_processer/doscript", RESTFUL_SERVER_BIND(MainControlService::doscript));
  51. m_restfulServer->regAPI("/api1/script_processer/stopscript", RESTFUL_SERVER_BIND(MainControlService::stopscript));
  52. m_restfulServer->start(20000, 20001, "0.0.0.0");
  53. m_iflytopwsService.reset(new IflytopFrontEndService());
  54. m_iflytopwsService->initialize("0.0.0.0");
  55. m_iflytopwsService->onMessage.connect([this](weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
  56. string cmdstr = cmd["command"];
  57. if (cmdstr != "getState") {
  58. logger->info("rx:{}", cmd.dump());
  59. }
  60. processFrontEndMessage(webSocket, cmd, receipt);
  61. if (cmdstr != "getState") {
  62. logger->info("tx:{}", receipt.dump());
  63. }
  64. });
  65. m_iflytopwsService->onUdpCmdMessage.connect([this](struct sockaddr_in* from, char* data, size_t len) {
  66. //
  67. for (size_t i = 0; i < len; i++) {
  68. if (data[i] == '\r' || data[i] == '\n') {
  69. data[i] = '\0';
  70. }
  71. }
  72. bool execsuc = false;
  73. for (size_t i = 0; i < len; i++) {
  74. if (data[i] != '\0') {
  75. int inext = strlen(&data[i]) + i;
  76. {
  77. string retmsg;
  78. execsuc = m_zcanhost->execcmd(string(&data[i]), retmsg);
  79. string retmsgstr = fmt::format("{},{}", execsuc ? "suc" : "fail", retmsg);
  80. m_iflytopwsService->sendToUDP(from, retmsgstr.c_str(), retmsgstr.size());
  81. }
  82. i = inext;
  83. if (!execsuc) {
  84. break;
  85. }
  86. }
  87. }
  88. });
  89. m_iflytopwsService->startListen();
  90. m_dbService.reset(new DBService());
  91. m_dbService->initialize();
  92. m_reportThread.reset(new Thread("reportThread", [this]() {
  93. ThisThread thisThread;
  94. while (!thisThread.getExitFlag()) {
  95. json report;
  96. report["command"] = "RealtimeSensorDataReport";
  97. report["sensor_data"] = createSensorDataJson();
  98. m_iflytopwsService->sendReport(report);
  99. thisThread.sleepForMs(1000);
  100. }
  101. }));
  102. };
  103. json MainControlService::createSensorDataJson() {
  104. json report;
  105. report["airCompressor"]["io1"] = m_sensorDataScan->getAirCompressor_io1();
  106. report["airCompressor"]["io2"] = m_sensorDataScan->getAirCompressor_io2();
  107. report["airCompressor"]["currentVal"] = m_sensorDataScan->getAirCompressor_currentValue();
  108. report["airBlower"]["io1"] = m_sensorDataScan->getAirBlower_io1();
  109. report["airBlower"]["io2"] = m_sensorDataScan->getAirBlower_io2();
  110. report["airBlower"]["currentVal"] = m_sensorDataScan->getAirBlower_currentValue();
  111. report["heatingStrip"]["io1"] = m_sensorDataScan->getHeatingStrip_io1();
  112. report["heatingStrip"]["io2"] = m_sensorDataScan->getHeatingStrip_io2();
  113. report["heatingStrip"]["currentVal"] = m_sensorDataScan->getHeatingStrip_currentValue();
  114. report["sprinklerPump"] = m_sensorDataScan->getSprinkler_PumpRPM();
  115. report["chargingPump"] = m_sensorDataScan->getChargingPump_PumpRPM();
  116. report["waterImmersionSensor1"] = m_sensorDataScan->getWaterImmersionSensor1();
  117. report["waterImmersionSensor2"] = m_sensorDataScan->getWaterImmersionSensor2();
  118. // Water immersion sensor
  119. report["disinfectant_volume"] = m_sensorDataScan->getDisinfectantVolume_g();
  120. report["h2o2_1"] = m_sensorDataScan->getH2O2SenSorData1().h2o2;
  121. report["temp_1"] = m_sensorDataScan->getH2O2SenSorData1().temp;
  122. report["humid_1"] = m_sensorDataScan->getH2O2SenSorData1().humid;
  123. report["saturation_1"] = m_sensorDataScan->getH2O2SenSorData1().saturation;
  124. report["h2o2_2"] = -1;
  125. report["temp_2"] = -1;
  126. report["humid_2"] = -1;
  127. report["saturation_2"] = -1;
  128. report["h2o2_3"] = -1;
  129. report["temp_3"] = -1;
  130. report["humid_3"] = -1;
  131. report["saturation_3"] = -1;
  132. return report;
  133. }
  134. // {"command":"startReplenishingFluids","messageId":"startReplenishingFluids","stopAt":123}
  135. void MainControlService::processFrontEndMessage(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
  136. string cmdstr = cmd["command"];
  137. /*******************************************************************************
  138. * LOGIN_CMD *
  139. *******************************************************************************/
  140. if (cmdstr == "login") {
  141. string uid = cmd["userid"];
  142. string pwd = cmd["passwd"];
  143. auto usr = m_dbService->getUser(uid);
  144. if (usr == nullptr) {
  145. logger->warn("login fail, user {} not exist", uid);
  146. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kuser_not_exist);
  147. receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kuser_not_exist, "");
  148. return;
  149. }
  150. if (usr->passwd != pwd) {
  151. logger->warn("login fail, user {} passwd error", uid);
  152. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kpasswd_error);
  153. receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kpasswd_error, "");
  154. return;
  155. }
  156. m_deviceStateService->setLoginState(uid, usr->permission_level, usr->visible);
  157. logger->info("user {} login success", uid);
  158. return;
  159. }
  160. /*******************************************************************************
  161. * unlogin *
  162. *******************************************************************************/
  163. if (cmdstr == "unlogin") {
  164. m_deviceStateService->unlogin();
  165. logger->info("user unlogin success");
  166. return;
  167. }
  168. /*******************************************************************************
  169. * chpasswd *
  170. *******************************************************************************/
  171. if (cmdstr == "chpasswd") {
  172. string uid = cmd["userid"];
  173. string pwd = cmd["passwd"];
  174. logger->info("changet passwd {} {}", uid, pwd);
  175. return;
  176. }
  177. /*******************************************************************************
  178. * shutdown *
  179. *******************************************************************************/
  180. if (cmdstr == "shutdown") {
  181. int delayms = jsonGet<int>(cmd["delayms"]);
  182. logger->info("shutdown {} ms", delayms);
  183. m_autoshutdownThread.reset(new Thread("autoShutdown", [delayms]() {
  184. ThisThread thisThread;
  185. thisThread.sleepForMs(delayms);
  186. system("shutdown -h now");
  187. }));
  188. return;
  189. }
  190. if (cmdstr == "updateDate") {
  191. #if 0
  192. {
  193. "command":"updateDate",
  194. "messageId":"1111222333444555",
  195. "year":2023,
  196. "month":8,
  197. "day":25,
  198. "hour":11,
  199. "min":12,
  200. "second":13,
  201. }
  202. #endif
  203. int32_t year = jsonGet<int>(cmd["year"]);
  204. int32_t month = jsonGet<int>(cmd["month"]);
  205. int32_t day = jsonGet<int>(cmd["day"]);
  206. int32_t hour = jsonGet<int>(cmd["hour"]);
  207. int32_t min = jsonGet<int>(cmd["min"]);
  208. int32_t second = jsonGet<int>(cmd["second"]);
  209. logger->info("updateDate {} {} {} {}:{}:{}", year, month, day, hour, min, second);
  210. return;
  211. }
  212. /*******************************************************************************
  213. * *
  214. *******************************************************************************/
  215. if (cmdstr == "startDisinfection") {
  216. int loglevel = jsonGet<int>(cmd["loglevel"]);
  217. int roomVolume = jsonGet<int>(cmd["roomVolume"]); //
  218. m_disinfectionCtrlService->startDisinfection(loglevel, roomVolume);
  219. return;
  220. }
  221. if (cmdstr == "stopDisinfection") {
  222. m_disinfectionCtrlService->stopDisinfection();
  223. return;
  224. }
  225. if (cmdstr == "pauseDisinfection") {
  226. m_disinfectionCtrlService->pauseDisinfection();
  227. return;
  228. }
  229. if (cmdstr == "continueDisinfection") {
  230. m_disinfectionCtrlService->continueDisinfection();
  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"]["sensor_data"] = createSensorDataJson();
  286. return;
  287. }
  288. /*******************************************************************************
  289. * *
  290. *******************************************************************************/
  291. // {
  292. // "command":"exceCanCmd",
  293. // "cancmd": "",
  294. // }
  295. if (cmdstr == "exceCanCmd") {
  296. string cancmd = cmd["cancmd"];
  297. logger->info("exceCanCmd {}", cancmd);
  298. string receipt_str;
  299. bool suc = m_zcanhost->execcmd(cancmd, receipt_str);
  300. receipt["receipt_str"] = receipt_str;
  301. if (!suc) {
  302. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kfail);
  303. }
  304. return;
  305. }
  306. /*******************************************************************************
  307. * *
  308. *******************************************************************************/
  309. if (cmdstr == "getAllUser") {
  310. auto users = m_dbService->getAllUserJson();
  311. receipt["dbval"] = users;
  312. return;
  313. }
  314. if (cmdstr == "getAllSetting") {
  315. auto dbval = m_dbService->getAllSettingJson();
  316. receipt["dbval"] = dbval;
  317. return;
  318. }
  319. if (cmdstr == "getAllRecords") {
  320. string disinfection_id = cmd["disinfection_id"];
  321. auto dbval = m_dbService->getAllRecords(disinfection_id);
  322. receipt["dbval"] = dbval;
  323. return;
  324. }
  325. if (cmdstr == "setSettingVal") {
  326. string settingName = cmd["settingName"];
  327. int settingVal = jsonGet<int>(cmd["settingVal"]);
  328. bool suc = m_dbService->setSettingVal(settingName, settingVal);
  329. if (!suc) {
  330. receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kdb_operate_error);
  331. receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kdb_operate_error, "setSettingVal fail");
  332. }
  333. return;
  334. }
  335. }
  336. HttpResponsePtr MainControlService::hello_world( //
  337. HttpRequestPtr request, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState>) {
  338. return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world");
  339. }
  340. HttpResponsePtr MainControlService::doscript(HttpRequestPtr httpreq, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState> conn) {
  341. // logger->info("do\n{}", httpreq->body);
  342. // if (m_a8000_script_processer->isWorking()) {
  343. // return std::make_shared<HttpResponse>(200, "FAIL", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script fail, script processer is running");
  344. // }
  345. // m_a8000_script_processer->executeScript(httpreq->body);
  346. return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script success");
  347. }
  348. HttpResponsePtr MainControlService::stopscript(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>) {
  349. // m_a8000_script_processer->stopScript();
  350. return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "stop script success");
  351. }