diff --git a/README.md b/README.md index 323262c..8cfdd1c 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ 1. 磁盘空间管理 2. 日志过期自动删除 3. DB过期记录自动删除 +4. 量产时记得将websocketIP修改成127.0.0.1 ---------------------------------- diff --git a/iflytoplinuxsdk b/iflytoplinuxsdk index e248cbe..7be7036 160000 --- a/iflytoplinuxsdk +++ b/iflytoplinuxsdk @@ -1 +1 @@ -Subproject commit e248cbe39e9a9c4dc448c5e354b1f5ea352275cb +Subproject commit 7be7036d99eca24b6a5d4e9ae0361fcbc936b90f diff --git a/src/main_control_service.cpp b/src/main_control_service.cpp index 0ce66af..513b104 100644 --- a/src/main_control_service.cpp +++ b/src/main_control_service.cpp @@ -2,26 +2,254 @@ #include "configs/project_setting.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"); + } +} + +static void getJsonValFromJson(json j, float& val) { + if (j.is_string()) { + string jstr = j; + val = atof(jstr.c_str()); + } else if (j.is_number()) { + val = j; + } else { + throw std::runtime_error("getJsonValFromJson(float) error"); + } +} + +static void getJsonValFromJson(json j, string& val) { + if (j.is_string()) { + string val = j; + } else { + throw std::runtime_error("getJsonValFromJson(string) error"); + } +} + +template +static T jsonGet(json j) { + T val; + getJsonValFromJson(j, val); + return val; +} + void MainControlService::initialize() { + /** + * @brief 构造系统中的单例服务 + */ + BUILD_AND_REG_SERRVICE(DeviceStateService); + GET_SERVICE(DeviceStateService)->initialize(); + + /** + * @brief Get the to service object + */ GET_TO_SERVICE(m_zconfig); - // m_iflytopCanProtocolControler.reset(new IflytopCanProtocolControler()); - // m_iflytopCanProtocolControler->initialize(m_zconfig->get_iflytopSubDeviceCanIFName(), m_zconfig->get_iflytopSubDeviceCanBitrate(), false); - // m_iflytopCanProtocolControler->start(); + GET_TO_SERVICE(m_deviceStateService); + + 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, json& cmd, json& receipt) { processFrontEndMessage(webSocket, cmd, receipt); }); + + m_dbService.reset(new DBService()); + m_dbService->initialize(); }; +void MainControlService::processFrontEndMessage(weak_ptr webSocket, json& cmd, json& receipt) { +#if 0 + //login +{ + "command":"login", + "userid":"zhaohe", + "passwd":"xxxxxx" +} +//unlogin +{ + "command":"unlogin" +} +//chpasswd +{ + "command":"chpasswd", + "userId":"1", + "passwd":"xxxxxxxxx" +} +//shutdown +{ + "command":"shutdown", + "delayms": 10, +} +// + +//startDisinfection +{ + "command":"startDisinfection", +} + +//stopDisinfection +{ + "command":"stopDisinfection", +} +--------------------------------------------------- +//getState +{ + "command":"getState", +} +//receipt +{ + "ackcode":0 + "state":{ + //存放所有当前设备的状态信息 + "loginuser":"", + "permissionLevel":1, + "workState":0, //0,idle,1,消毒中,2,测试中 + "estimatedRemainingTimeS":10000,//预计消毒结束剩余时间,数值是不断修正的,可能会变大。 + "disinfection_id":"2023-0825-111059" + } +} +#endif + + string cmdstr = cmd["command"]; + /******************************************************************************* + * LOGIN_CMD * + *******************************************************************************/ + if (cmdstr == "login") { + string uid = jsonGet(cmd["userid"]); + string pwd = jsonGet(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::kcommon_error_code, err::kuser_not_exist); + receipt["ackcodeInfo"] = err::error_code_get_desc(err::kcommon_error_code, 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::kcommon_error_code, err::kpasswd_error); + receipt["ackcodeInfo"] = err::error_code_get_desc(err::kcommon_error_code, 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 = jsonGet(cmd["userid"]); + string pwd = jsonGet(cmd["passwd"]); + logger->info("changet passwd {} {}", uid, pwd); + return; + } + + /******************************************************************************* + * shutdown * + *******************************************************************************/ + if (cmdstr == "shutdown") { + int delayms = jsonGet(cmd["delayms"]); + logger->info("shutdown {} ms", delayms); + // system("shutdown -r -t"); + return; + } + + /******************************************************************************* + * 消毒相关指令 * + *******************************************************************************/ + + if (cmdstr == "startDisinfection") { + int loglevel = jsonGet(cmd["loglevel"]); + int roomVolume = jsonGet(cmd["roomVolume"]);// + m_disinfectionCtrlService->startDisinfection(loglevel, roomVolume); + return; + } + + if (cmdstr == "stopDisinfection") { + m_disinfectionCtrlService->stopDisinfection(); + return; + } + + /******************************************************************************* + * getState * + *******************************************************************************/ + if (cmdstr == "getState") { + receipt["state"]["loginuser"] = m_deviceStateService->getLoginUid(); + receipt["state"]["permissionLevel"] = m_deviceStateService->getLoginPermissionLevel(); + receipt["state"]["workState"] = m_disinfectionCtrlService->isDisinfectionRunning(); + receipt["state"]["estimatedRemainingTimeS"] = m_disinfectionCtrlService->getEstimatedRemainingTimeS(); + receipt["state"]["disinfection_id"] = m_disinfectionCtrlService->getDisinfectionID(); + 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 = jsonGet(cmd["disinfection_id"]); + auto dbval = m_dbService->getAllRecords(disinfection_id); + receipt["dbval"] = dbval; + return; + } + + if (cmdstr == "setSettingVal") { + string settingName = jsonGet(cmd["settingName"]); + int settingVal = jsonGet(cmd["settingVal"]); + bool suc = m_dbService->setSettingVal(settingName, settingVal); + if (!suc) { + receipt["ackcode"] = err::error_code_get_get_ecode(err::kcommon_error_code, err::kdb_operate_error); + receipt["ackcodeInfo"] = err::error_code_get_desc(err::kcommon_error_code, err::kdb_operate_error, "setSettingVal fail"); + } + return; + } +} + HttpResponsePtr MainControlService::hello_world( // HttpRequestPtr request, shared_ptr context, std::shared_ptr) { return std::make_shared(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world"); diff --git a/src/main_control_service.hpp b/src/main_control_service.hpp index 275fa20..8d41352 100644 --- a/src/main_control_service.hpp +++ b/src/main_control_service.hpp @@ -18,12 +18,17 @@ #include "iflytop/core/components/timer/simple_timer.hpp" #include "iflytop/core/spdlogfactory/logger.hpp" #include "iflytoplinuxsdk/src/iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" +#include "service/device_state_service.hpp" +#include "service/disinfection_ctl_service.hpp" + // #include "configs/gconfig.hpp" +#include "iflytop/components/iflytop_front_end_service/iflytop_front_end_service.hpp" #include "zservice_container/zservice_container.hpp" // // +#include "db/db_service.hpp" #include "src/service/iflytop_can_host_device.hpp" /** @@ -44,9 +49,12 @@ using namespace core; class MainControlService : public enable_shared_from_this { ENABLE_LOGGER(MainControlService); - shared_ptr m_zconfig; - shared_ptr m_restfulServer; - shared_ptr m_iflytopwsService; + shared_ptr m_zconfig; + shared_ptr m_restfulServer; + shared_ptr m_iflytopwsService; + shared_ptr m_dbService; + shared_ptr m_deviceStateService; + shared_ptr m_disinfectionCtrlService; public: MainControlService(){}; @@ -69,5 +77,6 @@ class MainControlService : public enable_shared_from_this { HttpResponsePtr stopscript(HttpRequestPtr, shared_ptr, std::shared_ptr); void createReactionConfigCardInfoReportAndSend(); + void processFrontEndMessage(weak_ptr webSocket, json& cmd, json& receipt); }; } // namespace iflytop \ No newline at end of file diff --git a/src/service/device_state_service.cpp b/src/service/device_state_service.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/service/device_state_service.hpp b/src/service/device_state_service.hpp new file mode 100644 index 0000000..a14e982 --- /dev/null +++ b/src/service/device_state_service.hpp @@ -0,0 +1,59 @@ +// +// Created by zwsd +// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iflytop/core/core.hpp" + +/** + * @brief + * + * service: DeviceStateService + * + * 监听事件: + * 依赖状态: + * 依赖服务: + * 作用: + * + */ + +namespace iflytop { +using namespace std; +using namespace core; +class DeviceStateService : public enable_shared_from_this { + ENABLE_LOGGER(DeviceStateService); + + bool loginFlag = false; + string login_uid; + int login_permission_level; + int login_visible; + + public: + DeviceStateService(){}; + + void setLoginState(string uid, int permission_level, int visible) { + loginFlag = true; + login_uid = uid; + login_permission_level = permission_level; + login_visible = visible; + } + + void unlogin() { loginFlag = false; } + bool isLogin() { return loginFlag; } + int getLoginPermissionLevel() { return login_permission_level; } + int getLoginVisible() { return login_visible; } + string getLoginUid() { return login_uid; } + + void initialize(){}; +}; +} // namespace iflytop \ No newline at end of file diff --git a/src/service/disinfection_ctl_service.cpp b/src/service/disinfection_ctl_service.cpp new file mode 100644 index 0000000..ee1467e --- /dev/null +++ b/src/service/disinfection_ctl_service.cpp @@ -0,0 +1,84 @@ +#include "disinfection_ctl_service.hpp" +using namespace iflytop; +using namespace std; + +DisinfectionCtrlService::DisinfectionCtrlService() {} + +string DisinfectionCtrlService::createDisinfectionID() { + struct tm tm = {0}; + + time_t t = time(nullptr); + if (t == -1) { + logger->error("time(nullptr) failed"); + exit(-1); + } + struct tm* tmp = localtime_r(&t, &tm); + if (!tmp) { + logger->error("localtime_r failed"); + exit(-1); + } + // tm = *utctime::tm_increment_hour(&tm, 8); + // logger->info("trace sendmsg_startCapture {}:{}", __FILE__, __LINE__); + return fmt::format("{:0>4}-{:0>2}{:0>2}-{:0>2}{:0>2}{:0>2}", tm.tm_year + 1900, // + tm.tm_mon + 1, // + tm.tm_mday, // + tm.tm_hour, // + tm.tm_min, tm.tm_sec); +} + +void DisinfectionCtrlService::initialize() {} +void DisinfectionCtrlService::startDisinfection(int loglevel,float roomVol) { + lock_guard lock(lock_); + + if (m_disinfectionThread) { + stopDisinfection(); + } + + m_disinfectionID = createDisinfectionID(); + m_remaintime = 100; + m_isDisinfectionRunning = true; + m_disinfectionThread.reset(new Thread("m_disinfectionThread", [this, loglevel]() { + // do something + // m_disinfectionThread->detach(); + ThisThread thisThread; + + // 发送开始拍照消息 + logger->info("start feeding {}", m_disinfectionID); + + while (!thisThread.getExitFlag()) { + m_remaintime--; + if (m_remaintime == 0) { + logger->info("feeding finished {}", m_disinfectionID); + break; + } + thisThread.sleepForMs(1000); + } + + { + lock_guard lock(lock_); + m_isDisinfectionRunning = false; + } + })); +} +void DisinfectionCtrlService::stopDisinfection() { + lock_guard lock(lock_); + + if (m_disinfectionThread) { + m_disinfectionThread->join(); + m_disinfectionThread = nullptr; + } + logger->info("stop feeding {}", m_disinfectionID); +} +bool DisinfectionCtrlService::isDisinfectionRunning() { + lock_guard lock(lock_); + return m_isDisinfectionRunning; +} + +int32_t DisinfectionCtrlService::getEstimatedRemainingTimeS() { + lock_guard lock(lock_); + return m_remaintime; +} +string DisinfectionCtrlService::getDisinfectionID() { + lock_guard lock(lock_); + return m_disinfectionID; +} \ No newline at end of file diff --git a/src/service/disinfection_ctl_service.hpp b/src/service/disinfection_ctl_service.hpp new file mode 100644 index 0000000..bf71ca2 --- /dev/null +++ b/src/service/disinfection_ctl_service.hpp @@ -0,0 +1,63 @@ +// +// Created by zwsd +// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iflytop/core/core.hpp" + +/** + * @brief + * + * service: DisinfectionCtrlService + * + * 监听事件: + * 依赖状态: + * 依赖服务: + * 作用: + * + */ + +namespace iflytop { +using namespace std; +using namespace core; +class DisinfectionCtrlService : public enable_shared_from_this { + ENABLE_LOGGER(DisinfectionCtrlService); + + unique_ptr m_disinfectionThread; + string m_disinfectionID; + + int m_remaintime = 0; + bool m_isDisinfectionRunning = false; + recursive_mutex lock_; + + public: + DisinfectionCtrlService(); + + public: + void initialize(); + /** + * @brief 开始消毒 + * + * @param loglevel 消毒等级 + */ + void startDisinfection(int loglevel,float roomVol); + void stopDisinfection(); + bool isDisinfectionRunning(); + int32_t getEstimatedRemainingTimeS(); + string getDisinfectionID(); + + private: + string createDisinfectionID(); +}; +} // namespace iflytop \ No newline at end of file