|
|
#include "main_control_service.hpp"
#include "configs/project_setting.hpp"
#include "iflytop/components/zcanreceiver/zcanreceiverhost.hpp"
#include "iflytop/core/components/stringutils.hpp"
#include "iflytop/core/core.hpp"
#include "version.hpp"
using namespace iflytop; using namespace core; using namespace std; using namespace nlohmann;
#define BIND
static void getJsonValFromJson(json j, int& val) { if (j.is_string()) { string valstr = j; val = atoi(valstr.c_str()); } else if (j.is_number()) { val = j; } else { throw std::runtime_error("getJsonValFromJson(int) error"); } }
template <typename T> static T jsonGet(json j) { T val; getJsonValFromJson(j, val); return val; }
void MainControlService::initialize() { GET_TO_SERVICE(m_zconfig);
// m_dbService.reset(new DBService());
// m_dbService->initialize();
BUILD_AND_REG_SERRVICE(DBService); GET_SERVICE(DBService)->initialize(); GET_TO_SERVICE(m_dbService);
/**
* @brief 构造系统中的单例服务 */ BUILD_AND_REG_SERRVICE(DeviceStateService); GET_SERVICE(DeviceStateService)->initialize(); GET_TO_SERVICE(m_deviceStateService);
BUILD_AND_REG_SERRVICE(ZCanHost); GET_SERVICE(ZCanHost)->initialize(m_zconfig->get_iflytopSubDeviceCanIFName(), m_zconfig->get_iflytopSubDeviceCanBitrate(), false); GET_TO_SERVICE(m_zcanhost);
BUILD_AND_REG_SERRVICE(DisinfectionLogsManager); GET_SERVICE(DisinfectionLogsManager)->initialize(); GET_TO_SERVICE(m_disinfectionLogsManager);
BUILD_AND_REG_SERRVICE(DeviceIoControlService); GET_SERVICE(DeviceIoControlService)->initialize(); GET_TO_SERVICE(m_deviceIoControlService);
m_deviceIoControlService->startScan();
/**
* @brief Get the to service object */
m_disinfectionCtrlService.reset(new DisinfectionCtrlService()); m_disinfectionCtrlService->initialize();
m_restfulServer.reset(new RestfulServer()); m_restfulServer->regAPI("/hello_world", RESTFUL_SERVER_BIND(MainControlService::hello_world)); m_restfulServer->regAPI("/api1/script_processer/doscript", RESTFUL_SERVER_BIND(MainControlService::doscript)); m_restfulServer->regAPI("/api1/script_processer/stopscript", RESTFUL_SERVER_BIND(MainControlService::stopscript)); m_restfulServer->start(20000, 20001, "0.0.0.0");
m_iflytopwsService.reset(new IflytopFrontEndService()); m_iflytopwsService->initialize("0.0.0.0"); m_iflytopwsService->onMessage.connect([this](weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) { string cmdstr = cmd["command"]; if (cmdstr != "getState") { logger->info("rx:{}", cmd.dump()); } processFrontEndMessage(webSocket, cmd, receipt); if (cmdstr != "getState") { logger->info("tx:{}", receipt.dump()); } }); m_iflytopwsService->onUdpCmdMessage.connect([this](struct sockaddr_in* from, char* data, size_t len) { //
for (size_t i = 0; i < len; i++) { if (data[i] == '\r' || data[i] == '\n') { data[i] = '\0'; } } bool execsuc = false; for (size_t i = 0; i < len; i++) { if (data[i] != '\0') { int inext = strlen(&data[i]) + i; { string retmsg; execsuc = m_zcanhost->execcmd(string(&data[i]), retmsg); string retmsgstr = fmt::format("{},{}", execsuc ? "suc" : "fail", retmsg); m_iflytopwsService->sendToUDP(from, retmsgstr.c_str(), retmsgstr.size()); } i = inext; if (!execsuc) { break; } } } }); m_iflytopwsService->startListen();
m_reportThread.reset(new Thread("reportThread", [this]() { ThisThread thisThread; while (!thisThread.getExitFlag()) { json report; report["command"] = "RealtimeSensorDataReport"; report["sensor_data"] = createSensorDataJson(); m_iflytopwsService->sendReport(report); thisThread.sleepForMs(1000); } })); };
json MainControlService::createSensorDataJson() { json report; report["airCompressor"]["io1"] = m_deviceIoControlService->airCompressor_getio1(); report["airCompressor"]["io2"] = m_deviceIoControlService->airCompressor_getio2(); report["airCompressor"]["currentVal"] = m_deviceIoControlService->airCompressor_getcurrentValue();
report["airBlower"]["io1"] = m_deviceIoControlService->airBlower_getio1(); report["airBlower"]["io2"] = m_deviceIoControlService->airBlower_getio2(); report["airBlower"]["currentVal"] = m_deviceIoControlService->airBlower_getcurrentValue();
report["heatingStrip"]["io1"] = m_deviceIoControlService->heatingStrip_getio1(); report["heatingStrip"]["io2"] = m_deviceIoControlService->heatingStrip_getio2(); report["heatingStrip"]["currentVal"] = m_deviceIoControlService->heatingStrip_getcurrentValue();
report["sprinklerPump"] = m_deviceIoControlService->sprayLiquidPump_getRPM(); report["chargingPump"] = m_deviceIoControlService->getChargingPump_PumpRPM();
report["waterImmersionSensor1"] = m_deviceIoControlService->getWaterImmersionSensor1(); report["waterImmersionSensor2"] = m_deviceIoControlService->getWaterImmersionSensor2();
// Water immersion sensor
report["disinfectant_volume"] = m_deviceIoControlService->getDisinfectantVolume_g(); // report["h2o2_1"] = m_deviceIoControlService->getH2O2SenSorData1().h2o2;
report["h2o2_1"] = m_deviceIoControlService->getH2O2SenSorData1().h2o2; report["temp_1"] = m_deviceIoControlService->getH2O2SenSorData1().temp; report["humid_1"] = m_deviceIoControlService->getH2O2SenSorData1().humid; report["saturation_1"] = m_deviceIoControlService->getH2O2SenSorData1().saturation + 1; //为了让曲线不重叠
// logger->info("m_deviceIoControlService->getH2O2SenSorData1().h2o2 {}", m_deviceIoControlService->getH2O2SenSorData1().h2o2);
report["h2o2_2"] = -1; report["temp_2"] = -1; report["humid_2"] = -1; report["saturation_2"] = -1; report["h2o2_3"] = -1; report["temp_3"] = -1; report["humid_3"] = -1; report["saturation_3"] = -1; return report; } // {"command":"startReplenishingFluids","messageId":"startReplenishingFluids","stopAt":123}
void MainControlService::processFrontEndMessage(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) { string cmdstr = cmd["command"]; /*******************************************************************************
* LOGIN_CMD * *******************************************************************************/ if (cmdstr == "login") { string uid = cmd["userid"]; string pwd = cmd["passwd"]; auto usr = m_dbService->getUser(uid); if (usr == nullptr) { logger->warn("login fail, user {} not exist", uid); receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kuser_not_exist); receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kuser_not_exist, ""); return; }
if (usr->passwd != pwd) { logger->warn("login fail, user {} passwd error", uid); receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kpasswd_error); receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kpasswd_error, ""); return; }
m_deviceStateService->setLoginState(uid, usr->permission_level, usr->visible); logger->info("user {} login success", uid); return; }
/*******************************************************************************
* unlogin * *******************************************************************************/ if (cmdstr == "unlogin") { m_deviceStateService->unlogin(); logger->info("user unlogin success"); return; }
/*******************************************************************************
* chpasswd * *******************************************************************************/ if (cmdstr == "chpasswd") { string uid = cmd["userid"]; string pwd = cmd["passwd"]; logger->info("changet passwd {} {}", uid, pwd); return; }
/*******************************************************************************
* shutdown * *******************************************************************************/ if (cmdstr == "shutdown") { int delayms = jsonGet<int>(cmd["delayms"]); logger->info("shutdown {} ms", delayms); m_autoshutdownThread.reset(new Thread("autoShutdown", [delayms]() { ThisThread thisThread; thisThread.sleepForMs(delayms); system("shutdown -h now"); })); return; }
if (cmdstr == "updateDate") { #if 0
{ "command":"updateDate", "messageId":"1111222333444555", "year":2023, "month":8, "day":25, "hour":11, "min":12, "second":13, } #endif
int32_t year = jsonGet<int>(cmd["year"]); int32_t month = jsonGet<int>(cmd["month"]); int32_t day = jsonGet<int>(cmd["day"]); int32_t hour = jsonGet<int>(cmd["hour"]); int32_t min = jsonGet<int>(cmd["min"]); int32_t second = jsonGet<int>(cmd["second"]); logger->info("updateDate {} {} {} {}:{}:{}", year, month, day, hour, min, second); return; }
/*******************************************************************************
* 消毒相关指令 * *******************************************************************************/
if (cmdstr == "startDisinfection") { int loglevel = jsonGet<int>(cmd["loglevel"]); int roomVolume = jsonGet<int>(cmd["roomVolume"]); //
m_disinfectionCtrlService->startDisinfection(loglevel, roomVolume); return; }
if (cmdstr == "stopDisinfection") { m_disinfectionCtrlService->stopDisinfection(); return; }
#if 0
//开始加液
{ "command":"startReplenishingFluids", } //停止加液
{ "command":"stopReplenishingFluids", } //开始排液
{ "command":"startDraining", } //停止排液
{ "command":"stopDraining", } #endif
if (cmdstr == "startReplenishingFluids") { int16_t stopAt = jsonGet<int>(cmd["stopAt"]); logger->info("startReplenishingFluids {}", stopAt); m_disinfectionCtrlService->startReplenishingFluids(stopAt); return; }
if (cmdstr == "stopReplenishingFluids") { logger->info("stopReplenishingFluids"); m_disinfectionCtrlService->stopReplenishingFluids(); return; }
if (cmdstr == "startDraining") { logger->info("startDraining"); m_disinfectionCtrlService->startDraining(); return; }
if (cmdstr == "stopDraining") { logger->info("stopDraining"); m_disinfectionCtrlService->stopDraining(); return; }
/*******************************************************************************
* getState * *******************************************************************************/ if (cmdstr == "getState") { receipt["state"]["isLogin"] = m_deviceStateService->isLogin(); receipt["state"]["loginuser"] = m_deviceStateService->getLoginUid(); receipt["state"]["permissionLevel"] = m_deviceStateService->getLoginPermissionLevel(); // receipt["state"]["workState"] = m_disinfectionCtrlService->isDisinfectionRunning();
receipt["state"]["disinfectionWorkState"] = m_disinfectionCtrlService->getDisinfectionWorkState(); receipt["state"]["replenishingFluidsWorkState"] = m_disinfectionCtrlService->getReplenishingFluidsWorkState(); receipt["state"]["drainingWorkState"] = m_disinfectionCtrlService->getDrainingWorkState();
receipt["state"]["estimatedRemainingTimeS"] = m_disinfectionCtrlService->getEstimatedRemainingTimeS(); receipt["state"]["disinfection_id"] = m_disinfectionCtrlService->getDisinfectionID(); // receipt["state"]["preHeat"] = m_disinfectionCtrlService->processPreheatState
// getPreHeatRaminTimeS
// isPreheatState
receipt["state"]["preHeat"] = m_disinfectionCtrlService->isPreheatState(); receipt["state"]["preHeatRaminTimeS"] = m_disinfectionCtrlService->getPreHeatRaminTimeS(); // 预热剩余时间
receipt["state"]["sensor_data"] = createSensorDataJson(); return; }
/*******************************************************************************
* 执行测试指令 * *******************************************************************************/ // {
// "command":"exceCanCmd",
// "cancmd": "",
// }
if (cmdstr == "exceCanCmd") { string cancmd = cmd["cancmd"]; logger->info("exceCanCmd {}", cancmd); string receipt_str; bool suc = m_zcanhost->execcmd(cancmd, receipt_str); receipt["receipt_str"] = receipt_str; if (!suc) { receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kfail); } return; }
/*******************************************************************************
* 数据库查询 * *******************************************************************************/
if (cmdstr == "getAllUser") { auto users = m_dbService->getAllUserJson(); receipt["dbval"] = users; return; }
if (cmdstr == "getAllSetting") { auto dbval = m_dbService->getAllSettingJson(); receipt["dbval"] = dbval; return; }
if (cmdstr == "getAllRecords") { string disinfection_id = cmd["disinfection_id"]; auto dbval = m_dbService->getAllRecords(disinfection_id); receipt["dbval"] = dbval; return; }
if (cmdstr == "setSettingVal") { string settingName = cmd["settingName"]; int settingVal = jsonGet<int>(cmd["settingVal"]); bool suc = m_dbService->setSettingVal(settingName, settingVal); if (!suc) { receipt["ackcode"] = err::error_code_get_get_ecode(err::kce, err::kdb_operate_error); receipt["ackcodeInfo"] = err::error_code_get_desc(err::kce, err::kdb_operate_error, "setSettingVal fail"); } return; } }
HttpResponsePtr MainControlService::hello_world( //
HttpRequestPtr request, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState>) { return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world"); }
HttpResponsePtr MainControlService::doscript(HttpRequestPtr httpreq, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState> conn) { // logger->info("do\n{}", httpreq->body);
// if (m_a8000_script_processer->isWorking()) {
// return std::make_shared<HttpResponse>(200, "FAIL", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script fail, script processer is running");
// }
// m_a8000_script_processer->executeScript(httpreq->body);
return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script success"); }
HttpResponsePtr MainControlService::stopscript(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>) { // m_a8000_script_processer->stopScript();
return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "stop script success"); }
|