diff --git a/README.md b/README.md index 4b4170d..24b1a8c 100644 --- a/README.md +++ b/README.md @@ -70,14 +70,18 @@ TODO: --------------------------------------------------------------------- 10.添加异常上报前端程序,添加异常状态读取程序 + +----------------------------------------------------------------- 9. 对接消毒服务 11.针对关键接口添加异常标志位检测程序。(消毒,加液,排液体,气密性测试) 8. 添加消毒日志打印程序 8. 消毒测试 9. 添加气密封性测试逻辑代码。 +----------------------------------------------------------------- -9. 处理硬件异常上报 +9. 处理硬件异常上报 (OK) 8. 添加一个程序根据全局异常标志位,对设备进行相应的检查,如果检查通过则清空标志位。同时如果发生异常,则发送板子复位指令,对板子进行复位。 +整理错误码,为所有错误吗添加中文示意 ... 5. 单片机支持自动过滤掉重发的指令。 @@ -88,6 +92,5 @@ TODO: ``` TODO文档: getLoginUser - - + getState ``` \ No newline at end of file diff --git a/app_protocols/apperrorcode/apperrorcode.hpp b/app_protocols/apperrorcode/apperrorcode.hpp index 93f4ba6..cf0a123 100644 --- a/app_protocols/apperrorcode/apperrorcode.hpp +++ b/app_protocols/apperrorcode/apperrorcode.hpp @@ -74,7 +74,10 @@ typedef enum { kappe_is_disinfecting = 10023, // 消毒中 kappe_is_air_leak_detect_testing = 10024, // 气密性测试中 - kappe_is_cant_find_setting_id = 10025, // 未找到设置ID + kappe_is_cant_find_setting_id = 10025, // 未找到设置ID + kappe_exception_flag_is_setted = 10026, // + kappe_sensor_is_pre_hearting = 10027, // 传感器正在预热 + kappe_disinfection_state_is_wrong = 10028, // 消毒状态错误 } apperror_t; } diff --git a/appsrc/appbase/appbean/disinfection_state.hpp b/appsrc/appbase/appbean/disinfection_state.hpp index 195fe3d..cdebcbc 100644 --- a/appsrc/appbase/appbean/disinfection_state.hpp +++ b/appsrc/appbase/appbean/disinfection_state.hpp @@ -5,13 +5,13 @@ #define DisinfectionState_ZENUM_IMPL ZENUM_IMPL(DisinfectionState, DisinfectionState_LIST) #define DisinfectionState_LIST(type, marco) /**/ \ marco(type, idle) /**/ \ + marco(type, init) /**/ \ marco(type, preheat) /**/ \ marco(type, disinfection) /**/ \ marco(type, degradation) /**/ \ - marco(type, finished) /**/ \ marco(type, dehumidificationBeforeDisinfection) /**/ \ marco(type, dehumidificationAfterDisinfection) /**/ \ marco(type, emptyLiquidFromTheLine) /**/ \ - marco(type, appexception) /**/ + marco(type, finished) /**/ ZENUM_DECLAR(DisinfectionState, DisinfectionState_LIST); diff --git a/appsrc/appbase/appevent/app_event.hpp b/appsrc/appbase/appevent/app_event.hpp new file mode 100644 index 0000000..326343a --- /dev/null +++ b/appsrc/appbase/appevent/app_event.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace iflytop { +using namespace std; +class AppEvent { + public: + AppEvent(/* args */) {} + virtual ~AppEvent() {} +}; + +} // namespace ifytop \ No newline at end of file diff --git a/appsrc/appbase/appevent/app_promopt_event.hpp b/appsrc/appbase/appevent/app_promopt_event.hpp new file mode 100644 index 0000000..6f8b986 --- /dev/null +++ b/appsrc/appbase/appevent/app_promopt_event.hpp @@ -0,0 +1,14 @@ +#include "app_event.hpp" +namespace iflytop { + +class AppPromoptEvent : public AppEvent { + private: + string message; + + public: + AppPromoptEvent(string message) : message(message) {} + virtual ~AppPromoptEvent() {} + string getMessage() { return message; } +}; + +} // namespace iflytop \ No newline at end of file diff --git a/appsrc/appbase/appevent/app_warning_promopt_event.hpp b/appsrc/appbase/appevent/app_warning_promopt_event.hpp new file mode 100644 index 0000000..007bb5c --- /dev/null +++ b/appsrc/appbase/appevent/app_warning_promopt_event.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "app_event.hpp" +namespace iflytop { +class AppWarningPromoptEvent : public AppEvent { + private: + string message; + + public: + AppWarningPromoptEvent(string message) : message(message) {} + virtual ~AppWarningPromoptEvent() {} + string getMessage() { return message; } +}; + +} // namespace iflytop \ No newline at end of file diff --git a/appsrc/baseservice/app_event_bus.cpp b/appsrc/baseservice/app_event_bus.cpp new file mode 100644 index 0000000..a782e7c --- /dev/null +++ b/appsrc/baseservice/app_event_bus.cpp @@ -0,0 +1 @@ +#include "app_event_bus.hpp" \ No newline at end of file diff --git a/appsrc/baseservice/app_event_bus.hpp b/appsrc/baseservice/app_event_bus.hpp new file mode 100644 index 0000000..50976ce --- /dev/null +++ b/appsrc/baseservice/app_event_bus.hpp @@ -0,0 +1,43 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +#include "appbase/appbase.hpp" +#include "appbase/appevent/app_event.hpp" +#include "appsetting/appsetting.hpp" +// +namespace iflytop { +class AppEventBus : public enable_shared_from_this { + THISCLASS(AppEventBus); + + bool isInitialized = false; + + public: + nod::signal)> onEvent; + + public: + static AppEventBus* ins() { + static AppEventBus instance; + if (instance.isInitialized == false) { + instance.initialize(); + instance.isInitialized = true; + } + return &instance; + } + + void push(shared_ptr event) {} + + private: + void initialize() {} +}; + +} // namespace iflytop diff --git a/appsrc/baseservice/db/formula_db_dao.cpp b/appsrc/baseservice/db/formula_db_dao.cpp index 628e2b4..d335bc0 100644 --- a/appsrc/baseservice/db/formula_db_dao.cpp +++ b/appsrc/baseservice/db/formula_db_dao.cpp @@ -35,6 +35,22 @@ void FormulaDBDao::updateFormula(string formulaid, string key, string val) { formula[key] = val; keyvaldb.set(formulaid, formula); } +string FormulaDBDao::getFormula(string formulaid, string key) { + json formula = keyvaldb.get(formulaid); + if (formula.find(key) != formula.end()) { + return formula[key]; + } + return ""; + // THROW_APP_EXCEPTION(err::kappe_code_error, "fomula key [%s] not found", key); +} +string FormulaDBDao::getFormulaWithExcep(string formulaid, string key) { + json formula = keyvaldb.get(formulaid); + if (formula.find(key) != formula.end()) { + return formula[key]; + } + THROW_APP_EXCEPTION(err::kappe_code_error, "fomula key [%s] not found", key); +} + void FormulaDBDao::deleteFormula(string formulaid) { keyvaldb.del(formulaid); } json FormulaDBDao::newFormula() { @@ -51,4 +67,10 @@ json FormulaDBDao::newFormula() { keyvaldb.set(formula["formula_id"], formula.dump()); return formula; } -json FormulaDBDao::getFormula(string formulaid) { return keyvaldb.get(formulaid); } +json FormulaDBDao::getFormulaWithExcep(string formulaid) { + string val = keyvaldb.get(formulaid); + if (val.empty()) { + THROW_APP_EXCEPTION(err::kappe_code_error, "fomula [%s] not found", formulaid); + } + return json::parse(val); +} diff --git a/appsrc/baseservice/db/formula_db_dao.hpp b/appsrc/baseservice/db/formula_db_dao.hpp index 4513ad6..9b60e7c 100644 --- a/appsrc/baseservice/db/formula_db_dao.hpp +++ b/appsrc/baseservice/db/formula_db_dao.hpp @@ -17,7 +17,6 @@ #include "appbase/appbase.hpp" #include "appsetting/appsetting.hpp" - #include "base/dbbase.hpp" #include "base/keyvaldb.hpp" #include "user_behavior_des.hpp" @@ -50,12 +49,14 @@ class FormulaDBDao : public enable_shared_from_this { } public: - json getAllFormula(); - void updateFormula(string formulaid, json formula); - void updateFormula(string formulaid, string key, string val); - void deleteFormula(string formulaid); - json getFormula(string formulaid); - json newFormula(); + json getAllFormula(); + void updateFormula(string formulaid, json formula); + void updateFormula(string formulaid, string key, string val); + void deleteFormula(string formulaid); + string getFormula(string formulaid, string key); + json getFormulaWithExcep(string formulaid); + string getFormulaWithExcep(string formulaid, string key); + json newFormula(); public: }; diff --git a/appsrc/baseservice/db/setting_db_dao.cpp b/appsrc/baseservice/db/setting_db_dao.cpp index e39860d..ba94ce2 100644 --- a/appsrc/baseservice/db/setting_db_dao.cpp +++ b/appsrc/baseservice/db/setting_db_dao.cpp @@ -78,7 +78,7 @@ static Setting settingInitTable[] = { INT_SETTING(SettingId::krecord_period_min, "消毒日志记录间隔(Min)", "2", "1", "30", true, true, false, false), INT_SETTING(SettingId::krecord_printer_period_min, "消毒日志打印间隔(Min)", "5", "1", "30", true, true, false, false), ENUM_SETTING(SettingId::kloglevel, "消毒等级", "1", vector({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}), // - vector({"LOG1", "LOG2", "LOG3", "LOG4", "LOG5", "LOG6", "LOG7", "LOG8", "LOG9", "LOG10", "LOG11", "LOG12"}), true, false, true, true), + vector({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}), true, false, true, true), BOOL_SETTING(SettingId::kenable_bd_dehumidify, "是否启用消毒前除湿", "false", true, false, false, false), INT_SETTING(SettingId::kbd_dehumidify_threshold, "消毒前除湿阈值", "0", "0", "100", true, false, false, false), BOOL_SETTING(SettingId::kenable_ad_dehumidify, "是否启用消毒后除湿", "false", true, false, false, false), @@ -151,7 +151,7 @@ list> SettingDBDao::getAllSetting() { // shared_ptr SettingDBDao::getSetting(string name) { string settingContent = keyvaldb.get(name); if (settingContent.empty()) { - return nullptr; + THROW_APP_EXCEPTION(err::kappe_code_error, "SettingDBDao::getSettingValAsString setting is null"); } auto setting = make_shared(); json val = json::parse(settingContent); @@ -165,7 +165,7 @@ void SettingDBDao::updateSetting(shared_ptr setting) { // bool SettingDBDao::setSettingVal(string name, string val) { auto setting = getSetting(name); if (setting == nullptr) { - return false; + THROW_APP_EXCEPTION(err::kappe_code_error, "SettingDBDao::getSettingValAsString setting is null"); } setting->val = val; updateSetting(setting); @@ -174,21 +174,21 @@ bool SettingDBDao::setSettingVal(string name, string val) { int SettingDBDao::getSettingValAsInt(string name) { auto setting = getSetting(name); if (setting == nullptr) { - return -1; + THROW_APP_EXCEPTION(err::kappe_code_error, "SettingDBDao::getSettingValAsString setting is null"); } return stoi(setting->val); } string SettingDBDao::getSettingValAsString(string name) { auto setting = getSetting(name); if (setting == nullptr) { - return ""; + THROW_APP_EXCEPTION(err::kappe_code_error, "SettingDBDao::getSettingValAsString setting is null"); } return setting->val; } bool SettingDBDao::getSettingValAsBool(string name) { auto setting = getSetting(name); if (setting == nullptr) { - return false; + THROW_APP_EXCEPTION(err::kappe_code_error, "SettingDBDao::getSettingValAsString setting is null"); } return setting->val == "true"; } diff --git a/appsrc/baseservice/devicestate/device_state_service.hpp b/appsrc/baseservice/devicestate/device_state_service.hpp index 3a77d4e..e05e65a 100644 --- a/appsrc/baseservice/devicestate/device_state_service.hpp +++ b/appsrc/baseservice/devicestate/device_state_service.hpp @@ -45,6 +45,9 @@ class DeviceStateService : public enable_shared_from_this { bool m_appexception = false; public: + nod::signal onException; + + public: DeviceStateService() {}; void setLoginState(string uid, bool isadmin) { @@ -64,14 +67,27 @@ class DeviceStateService : public enable_shared_from_this { DeviceState getDeviceState() { return state; } void setDeviceState(DeviceState s) { state = s; } - bool getAppExceptionFlag() { return m_appexception; } - int getAppExceptionCode() { return m_ecode; } + /******************************************************************************* + * exception * + *******************************************************************************/ + void clearAppExceptionFlag() { m_appexception = false; } void setAppExceptionFlag(const appexception &e) { m_appexception = true; m_emessage = e.what(); m_ecode = e.ecode(); + onException(e.ecode(), e.what()); } - void clearAppExceptionFlag() { m_appexception = false; } + + void setAppExceptionFlag(int32_t ecode, const string &emessage) { + m_appexception = true; + m_emessage = emessage; + m_ecode = ecode; + onException(ecode, emessage); + } + + bool getAppExceptionFlag() { return m_appexception; } + int getAppExceptionCode() { return m_ecode; } + string getAppExceptionMessage() { return m_emessage; } void initialize() {}; }; diff --git a/appsrc/baseservice/iflytop_front_end_service/iflytop_front_end_service.hpp b/appsrc/baseservice/iflytop_front_end_service/iflytop_front_end_service.hpp index 5d9ae92..b6e13aa 100644 --- a/appsrc/baseservice/iflytop_front_end_service/iflytop_front_end_service.hpp +++ b/appsrc/baseservice/iflytop_front_end_service/iflytop_front_end_service.hpp @@ -61,4 +61,7 @@ class IflytopFrontEndService : public enable_shared_from_this webSocket, shared_ptr connectionState, const ix::WebSocketMessagePtr& msg); void processRxMessage(weak_ptr webSocket, string rxmsg); }; -} // namespace iflytop \ No newline at end of file +} // namespace iflytop + +// #define SEND_PROMPT(message) GET_SERVICE(IflytopFrontEndService)->sendPrompt(message); +#define SEND_CLASS_REPORT(fromclass, fromfn, content) GET_SERVICE(IflytopFrontEndService)->sendClassReport(fromclass, fromfn, content); \ No newline at end of file diff --git a/appsrc/main.cpp b/appsrc/main.cpp index 3a0c380..93c14be 100644 --- a/appsrc/main.cpp +++ b/appsrc/main.cpp @@ -4,7 +4,7 @@ #include "appbase/appbase.hpp" #include "appsetting/appsetting.hpp" -#include "service/main_control_service.hpp" +#include "service/app_core.hpp" using namespace iflytop; using namespace core; @@ -51,8 +51,7 @@ int main(int argc, char *argv[]) { main.run(argc, argv); } } -namespace iflytop { -} +namespace iflytop {} void Main::onsignal(int signo) { exit(0); } void Main::run(int argc, char *argv[]) { // ::signal(SIGINT, Main::_onsignal); @@ -60,7 +59,6 @@ void Main::run(int argc, char *argv[]) { while (true) sleep(1000); } int Main::main(int argc, char *argv[]) { - /** * @brief 系统初始化 */ @@ -84,7 +82,7 @@ int Main::main(int argc, char *argv[]) { auto config = GET_SERVICE(GConfig); // 构造MainControlService - BUILD_AND_REG_SERRVICE(MainControlService); + BUILD_AND_REG_SERRVICE(AppCore); logger->info("system setup end."); while (true) sleep(1000); } diff --git a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp index 1063ed9..8568f7d 100644 --- a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp +++ b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp @@ -15,10 +15,20 @@ string DisinfectionCtrlService::getSetting(SettingId sid) { // 1. 从 realtimeCfg 中进行查找 // 2. 从 系统配置 中进行查找 // m_realtimeCfg.find + if (sid == SettingId::loglevel) { + return fmt::format("{:.2f}", m_tlog); + } auto value = m_realtimeCfg.find(sid); if (value != m_realtimeCfg.end()) { return value->second; } + if (m_runType == RunType_t::kFormulaMode) { + string str = GET_SERVICE(FormulaDBDao)->getFormula(m_formulaid, sid); + if (!str.empty()) { + return str; + } + } + string str = GET_SERVICE(SettingDBDao)->getSettingValAsString(sid); if (str.empty()) { THROW_APP_EXCEPTION(err::kappe_is_cant_find_setting_id, "%s", string(sid).c_str()); @@ -104,10 +114,11 @@ void DisinfectionCtrlService::initialize() { GET_TO_SERVICE(db); GET_TO_SERVICE(ds); GET_TO_SERVICE(gConfig); - GET_TO_SERVICE(dcs); + GET_TO_SERVICE(dics); GET_TO_SERVICE(dwus); sm.regStateProcesser(DisinfectionState::idle, bind(&DisinfectionCtrlService::processStateIdle, this, placeholders::_1)); + sm.regStateProcesser(DisinfectionState::init, bind(&DisinfectionCtrlService::processStateInit, this, placeholders::_1)); sm.regStateProcesser(DisinfectionState::preheat, bind(&DisinfectionCtrlService::processStatePreheat, this, placeholders::_1)); sm.regStateProcesser(DisinfectionState::disinfection, bind(&DisinfectionCtrlService::processStateDisinfection, this, placeholders::_1)); sm.regStateProcesser(DisinfectionState::degradation, bind(&DisinfectionCtrlService::processStateDegradation, this, placeholders::_1)); @@ -115,37 +126,109 @@ void DisinfectionCtrlService::initialize() { sm.regStateProcesser(DisinfectionState::dehumidificationBeforeDisinfection, bind(&DisinfectionCtrlService::processStateDehumidificationBeforeDisinfection, this, placeholders::_1)); sm.regStateProcesser(DisinfectionState::dehumidificationAfterDisinfection, bind(&DisinfectionCtrlService::processStateDehumidificationAfterDisinfection, this, placeholders::_1)); sm.regStateProcesser(DisinfectionState::emptyLiquidFromTheLine, bind(&DisinfectionCtrlService::processStateEmpytLiquidFromTheLine, this, placeholders::_1)); - sm.regStateProcesser(DisinfectionState::appexception, bind(&DisinfectionCtrlService::processStateAppexception, this, placeholders::_1)); sm.regBfStateProcess(bind(&DisinfectionCtrlService::beforeStateProcess, this)); - sm.regExceptionProcesser(bind(&DisinfectionCtrlService::exceptionProcesser, this, placeholders::_1)); - sm.startProcess(); } /******************************************************************************* * APP_IMPL * *******************************************************************************/ -void DisinfectionCtrlService::start() { - DisinfectionEvent event; - event.event = kevent_start; - sm.pushEvent(event); +void DisinfectionCtrlService::start(int loglevel) { + logger->info("start loglevel:{}", loglevel); + checkBeforeStart(); + m_tlog = loglevel; + m_runType = kNormalMode; - // 等待任务开始 - while (sm.getState() == DisinfectionState::finished) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + auto allrealtimesetting = SETTING_DB->getRealtimeSetting(); + for (auto& setting : allrealtimesetting) { + m_realtimeCfg[string(setting->setting_id)] = SETTING_DB->getSettingValAsString(setting->setting_id); } + + json cfg = m_realtimeCfg; + logger->info("start tlog:{} cfg: {}", m_tlog, cfg.dump(2)); + + startWorkThread(); } +void DisinfectionCtrlService::startWithFormula(string formulaid) { + logger->info("startWithFormula formulaid:{}", formulaid); + checkBeforeStart(); + + json formulacfg = FORMULA_DB->getFormulaWithExcep(m_formulaid); + m_runType = kFormulaMode; + + m_tlog = atoi(FORMULA_DB->getFormulaWithExcep(m_formulaid, string(SettingId::loglevel)).c_str()); + + m_realtimeCfg.clear(); + auto allrealtimesetting = SETTING_DB->getRealtimeSetting(); + for (auto& setting : allrealtimesetting) { + if (formulacfg.find(string(setting->setting_id)) != formulacfg.end()) { + m_realtimeCfg[string(setting->setting_id)] = formulacfg[string(setting->setting_id)]; + } else { + m_realtimeCfg[string(setting->setting_id)] = SETTING_DB->getSettingValAsString(setting->setting_id); + } + } + + json cfg = m_realtimeCfg; + logger->info("startWithFormula tlog:{} cfg: {}", m_tlog, cfg.dump(2)); + startWorkThread(); +} + +void DisinfectionCtrlService::checkBeforeStart() { + if (DS->getAppExceptionFlag()) { + THROW_APP_EXCEPTION(err::kappe_exception_flag_is_setted, ""); + } + + if (DS->getDeviceState() != DeviceState::Idle) { + THROW_APP_EXCEPTION(err::kappe_state_is_busy, ""); + } + + if (zsteady_clock().gets() < SENSOR_PREHEART_TIME_S) { + THROW_APP_EXCEPTION(err::kappe_sensor_is_pre_hearting, ""); + } + + if (m_thread->isWaitingForJoin()) { + THROW_APP_EXCEPTION(err::kappe_disinfection_state_is_wrong, ""); + } +} + +void DisinfectionCtrlService::startWorkThread() { + m_thread.reset(new Thread("DisinfectionStateMachineThread", [this]() { + DS->setDeviceState(DeviceState::Disinfection); + logger->info("DisinfectionStateMachineThread start"); + sm.resetState(); + GET_SERVICE(WarningLightControler)->setworkFlag(true); + sm.changeState(DisinfectionState::init); + bool stopbyusrflag = false; + while (true) { + try { + sm.process(); + } catch (const appexception& e) { + DS->setAppExceptionFlag(e); + break; + } + if (sm.getState() == DisinfectionState::finished) { + break; + } + + if (!stopbyusrflag && ThisThread().getExitFlag()) { + stopbyusrflag = true; + sm.changeState(DisinfectionState::finished); + } + } + + logger->info("DisinfectionStateMachineThread end"); + GET_SERVICE(WarningLightControler)->setworkFlag(false); + DS->setDeviceState(DeviceState::Idle); + })); +} + void DisinfectionCtrlService::stop() { if (sm.getState() == DisinfectionState::finished) return; if (sm.getState() == DisinfectionState::idle) return; - DisinfectionEvent event; - event.event = kevent_stop; - sm.pushEvent(event); - - // 等待任务结束 - while (sm.getState() != DisinfectionState::finished) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + if (m_thread) { + m_thread->join(); + m_thread = nullptr; } } void DisinfectionCtrlService::updateCfg() { @@ -169,7 +252,7 @@ void DisinfectionCtrlService::traceState() { tracecontent += fmt::format("[{}] ", string(sm.getState())); tracecontent += fmt::format("dvalue:{} ", s_dvalue); - tracecontent += fmt::format("log:{}->{} ", s_nlog, s_tlog); + tracecontent += fmt::format("log:{}->{} ", s_nlog, m_tlog); tracecontent += fmt::format("takebreak:{} ", s_isDisinfectionTakeBreak); tracecontent += fmt::format("remaintime:{} ", s_remaintime); @@ -179,21 +262,9 @@ void DisinfectionCtrlService::traceState() { /******************************************************************************* * StateMachine * *******************************************************************************/ -void DisinfectionCtrlService::exceptionProcesser(const appexception& e) { - logger->error("exceptionProcesser:{}", e.what()); - sm.changeState(DisinfectionState::appexception); - DS->setAppExceptionFlag(e); -} -void DisinfectionCtrlService::processStateAppexception(DisinfectionEvent* event) { - if (event->event == kevent_tmr_1s) { - if (!DS->getAppExceptionFlag()) { - // 异常恢复 - sm.changeState(DisinfectionState::idle); - } - } -} +void DisinfectionCtrlService::initState() {} -void DisinfectionCtrlService::beforeStateProcess() { s_h2o2Snapshot = dcs->getH2O2SensorMgr()->takeSnapshot(); } +void DisinfectionCtrlService::beforeStateProcess() { s_h2o2Snapshot = dics->getH2O2SensorMgr()->takeSnapshot(); } void DisinfectionCtrlService::changeToNextState() { /** @@ -227,7 +298,7 @@ void DisinfectionCtrlService::changeToNextState() { // else if (sm.getState() == DisinfectionState::finished) { if (PORT.isDrawBarDM()) { - if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dcs->ExtChSelector_isOnline()) { + if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dics->ExtChSelector_isOnline()) { sm.changeState(DisinfectionState::dehumidificationBeforeDisinfection); } } else { @@ -249,7 +320,7 @@ void DisinfectionCtrlService::changeToNextState() { // else if (sm.getState() == DisinfectionState::emptyLiquidFromTheLine) { if (PORT.isDrawBarDM()) { - if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dcs->ExtChSelector_isOnline()) { + if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dics->ExtChSelector_isOnline()) { sm.changeState(DisinfectionState::dehumidificationAfterDisinfection); } } else { @@ -266,21 +337,33 @@ void DisinfectionCtrlService::changeToNextState() { } } -void DisinfectionCtrlService::processStateIdle(DisinfectionEvent* event) { sm.changeState(DisinfectionState::finished); } +void DisinfectionCtrlService::processStateIdle(DisinfectionEvent* event) {} + +void DisinfectionCtrlService::processStateInit(DisinfectionEvent* event) { + if (event->event == kevent_enter_state) { + /** + * @brief 开始消毒 + */ + + GET_SERVICE(WarningLightControler)->setworkFlag(true); + changeToNextState(); + } +} + void DisinfectionCtrlService::processStateDehumidificationBeforeDisinfection(DisinfectionEvent* event) { - auto h2o2s = dcs->getH2O2SensorMgr(); + auto h2o2s = dics->getH2O2SensorMgr(); if (event->event == kevent_enter_state) { tryLogState(true); ZASSERT(PORT.isDrawBarDM()); - dcs->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); + dics->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); usleep(100 * 1000); - dcs->ExtChSelector_trySelectCh(kext_ch_dehumidification); + dics->ExtChSelector_trySelectCh(kext_ch_dehumidification); } // else if (event->event == kevent_exit_state) { - dcs->Blower_ctrl(0); - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); + dics->Blower_ctrl(0); + dics->ExtChSelector_trySelectCh(kext_ch_disinfection); tryLogState(true); } // @@ -298,10 +381,6 @@ void DisinfectionCtrlService::processStateDehumidificationBeforeDisinfection(Dis changeToNextState(); tryLogState(false); } - - else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); - } } void DisinfectionCtrlService::processStatePreheat(DisinfectionEvent* event) { @@ -309,16 +388,16 @@ void DisinfectionCtrlService::processStatePreheat(DisinfectionEvent* event) { logger->info("preheat state enter"); tryLogState(true); - dcs->Blower_ctrl(90); + dics->Blower_ctrl(90); usleep(1000 * 1000); - dcs->Heater_ctrl(100); + dics->Heater_ctrl(100); } else if (event->event == kevent_exit_state) { logger->info("preheat state exit"); - dcs->Blower_ctrl(0); + dics->Blower_ctrl(0); usleep(1000 * 1000); - dcs->Heater_ctrl(0); + dics->Heater_ctrl(0); tryLogState(true); } else if (event->event == kevent_tmr_1s) { @@ -329,8 +408,6 @@ void DisinfectionCtrlService::processStatePreheat(DisinfectionEvent* event) { changeToNextState(); } tryLogState(false); - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); } } @@ -339,19 +416,19 @@ void DisinfectionCtrlService::processStateDisinfection(DisinfectionEvent* event) tryLogState(true); s_isDisinfectionTakeBreak = false; if (PORT.isPipeDM()) { - dcs->AirLeakDetectTestModeCtrl_setMode(0); + dics->AirLeakDetectTestModeCtrl_setMode(0); } - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); - dcs->AC_ctrl(1); - dcs->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); - dcs->Heater_ctrl(1); - dcs->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); + dics->ExtChSelector_trySelectCh(kext_ch_disinfection); + dics->AC_ctrl(1); + dics->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); + dics->Heater_ctrl(1); + dics->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); } else if (event->event == kevent_exit_state) { s_isDisinfectionTakeBreak = false; - dcs->AC_close(); - dcs->Blower_close(); - dcs->Heater_close(); - dcs->SprayPump_stop(); + dics->AC_close(); + dics->Blower_close(); + dics->Heater_close(); + dics->SprayPump_stop(); s_dvalue = 0; tryLogState(true); } else if (event->event == kevent_tmr_1s) { @@ -367,7 +444,7 @@ void DisinfectionCtrlService::processStateDisinfection(DisinfectionEvent* event) if (zsteady_clock().elapsedTimeS(s_lastComputeDvalueTp) > DVALUE_COMPUTEPERIOD_TIME_S) { s_lastComputeDvalueTp = zsteady_clock().now(); s_nlog = computeNextLogLevel(s_nlog, s_dvalue); - updateRemainTime(s_dvalue, s_nlog, s_tlog, s_remaintime); + updateRemainTime(s_dvalue, s_nlog, m_tlog, s_remaintime); traceState(); } @@ -377,22 +454,22 @@ void DisinfectionCtrlService::processStateDisinfection(DisinfectionEvent* event) if (!s_isDisinfectionTakeBreak) { if (isTimeToPauseDisinfection()) { logger->info("pauseDisinfection"); - dcs->SprayPump_stop(); - dcs->AC_close(); + dics->SprayPump_stop(); + dics->AC_close(); s_isDisinfectionTakeBreak = true; traceState(); } } else { if (isTimeToResumeDisinfection()) { logger->info("resumeDisinfection"); - dcs->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); - dcs->AC_ctrl(1); + dics->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); + dics->AC_ctrl(1); s_isDisinfectionTakeBreak = false; traceState(); } } - if (s_remaintime <= 0 && s_nlog > (s_tlog + 0.01)) { + if (s_remaintime <= 0 && s_nlog > (m_tlog + 0.01)) { /** * @brief 消毒结束 */ @@ -403,39 +480,35 @@ void DisinfectionCtrlService::processStateDisinfection(DisinfectionEvent* event) // 检查是否消毒完成 } else if (event->event == kevent_update_cfg) { if (!s_isDisinfectionTakeBreak) { - dcs->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); + dics->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); } - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); } } void DisinfectionCtrlService::processStateEmpytLiquidFromTheLine(DisinfectionEvent* event) { if (event->event == kevent_enter_state) { tryLogState(true); - dcs->SprayPump_startInRPM(-PORT.getSprayLiquidPumpMaxRPM()); + dics->SprayPump_startInRPM(-PORT.getSprayLiquidPumpMaxRPM()); } else if (event->event == kevent_exit_state) { tryLogState(true); - dcs->SprayPump_stop(); + dics->SprayPump_stop(); } else if (event->event == kevent_tmr_1s) { if (sm.getStateHasPassedTimeMs() > EMTPTY_LINE_WHEN_DISINFECTION * 1000) { changeToNextState(); } - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); } } void DisinfectionCtrlService::processStateDehumidificationAfterDisinfection(DisinfectionEvent* event) { if (event->event == kevent_enter_state) { tryLogState(true); - dcs->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); - dcs->ExtChSelector_trySelectCh(kext_ch_dehumidification); + dics->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); + dics->ExtChSelector_trySelectCh(kext_ch_dehumidification); } else if (event->event == kevent_exit_state) { - dcs->Blower_close(); - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); + dics->Blower_close(); + dics->ExtChSelector_trySelectCh(kext_ch_disinfection); tryLogState(true); } else if (event->event == kevent_tmr_1s) { - if (!dcs->ExtChSelector_isOnline()) { + if (!dics->ExtChSelector_isOnline()) { logger->error("exit dehumidification state, because extValBoard is offline"); changeToNextState(); return; @@ -453,19 +526,16 @@ void DisinfectionCtrlService::processStateDehumidificationAfterDisinfection(Disi changeToNextState(); tryLogState(false); - - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); } } void DisinfectionCtrlService::processStateDegradation(DisinfectionEvent* event) { if (event->event == kevent_enter_state) { tryLogState(true); - dcs->ExtChSelector_trySelectCh(kext_ch_degradation); - dcs->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); + dics->ExtChSelector_trySelectCh(kext_ch_degradation); + dics->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); } else if (event->event == kevent_exit_state) { - dcs->Blower_close(); - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); + dics->Blower_close(); + dics->ExtChSelector_trySelectCh(kext_ch_disinfection); tryLogState(true); } else if (event->event == kevent_tmr_1s) { auto maxH2O2 = s_h2o2Snapshot->maxH2O2; @@ -476,8 +546,6 @@ void DisinfectionCtrlService::processStateDegradation(DisinfectionEvent* event) changeToNextState(); } tryLogState(false); - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); } } void DisinfectionCtrlService::processStateFinished(DisinfectionEvent* event) { @@ -488,10 +556,10 @@ void DisinfectionCtrlService::processStateFinished(DisinfectionEvent* event) { * @brief 消毒结束 */ - dcs->SprayPump_stop(); - dcs->AC_ctrl(0); - dcs->Blower_close(); - dcs->Heater_close(); + dics->SprayPump_stop(); + dics->AC_ctrl(0); + dics->Blower_close(); + dics->Heater_close(); s_remaintime = 0; s_complete_tp = zsystem_clock().now(); @@ -509,18 +577,5 @@ void DisinfectionCtrlService::processStateFinished(DisinfectionEvent* event) { logger->info("finished disinfection {}", s_sessionId); return; } - - } - - // - else if (event->event == kevent_start) { - /** - * @brief 开始消毒 - */ - initState(); - GET_SERVICE(WarningLightControler)->setworkFlag(true); - changeToNextState(); } } - -void DisinfectionCtrlService::initState() {} diff --git a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp index 7779cde..bb760b2 100644 --- a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp +++ b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp @@ -22,22 +22,29 @@ class DisinfectionCtrlService : public enable_shared_from_this db; shared_ptr ds; shared_ptr gConfig; - shared_ptr dcs; + shared_ptr dics; shared_ptr dwus; - DisinfectionState m_state = DisinfectionState::idle; + RunType_t m_runType = kNormalMode; + string m_formulaid; // 配方ID + int m_tlog; - map m_realtimeCfg; - json m_defaultFormulaJson; - string m_formulaid; + DisinfectionStateMachine sm; // 状态机 + map m_realtimeCfg; - DisinfectionStateMachine sm; + unique_ptr m_thread; - // + // 实时任务状态 string s_sessionId; zsystem_tp s_start_tp; zsystem_tp s_complete_tp; @@ -49,7 +56,6 @@ class DisinfectionCtrlService : public enable_shared_from_this& getRealtimeCfg() { return m_realtimeCfg; } + DisinfectionState getState() { return sm.getState(); } + int getCurStateRemainTimeS() { return s_remaintime; } + float getTlog() { return m_tlog; } + float getNlog() { return s_nlog; } + shared_ptr getH2O2Snapshot() { return dics->getH2O2SensorMgr()->takeSnapshot(); } + private: void beforeStateProcess(); void processStateIdle(DisinfectionEvent* event); + void processStateInit(DisinfectionEvent* event); void processStatePreheat(DisinfectionEvent* event); void processStateDisinfection(DisinfectionEvent* event); void processStateDegradation(DisinfectionEvent* event); @@ -85,9 +102,6 @@ class DisinfectionCtrlService : public enable_shared_from_this processer) { m_bf_state_processer = processer; } -void DisinfectionStateMachine::regExceptionProcesser(function processer) { m_exception_processer = processer; } - void DisinfectionStateMachine::pushEvent(DisinfectionEvent event) { lock_guard lock(lock_); shared_ptr event_ptr(new DisinfectionEvent()); @@ -32,7 +30,17 @@ void DisinfectionStateMachine::callStateProcesser(DisinfectionState state, Disin iter->second(event); } } -void DisinfectionStateMachine::loop() { +void DisinfectionStateMachine::resetState() { + { + lock_guard lock(lock_); + m_event_list.clear(); + m_state = DisinfectionState::idle; + m_enter_state_tp = zsystem_clock().now(); + m_last_tmr_event = zsystem_clock().now(); + } +} + +void DisinfectionStateMachine::process() { this_thread::sleep_for(chrono::milliseconds(2)); shared_ptr event; @@ -72,7 +80,6 @@ void DisinfectionStateMachine::loop() { callStateProcesser(m_state, event.get()); } } - /** * @brief */ @@ -84,15 +91,3 @@ void DisinfectionStateMachine::loop() { m_last_tmr_event = zsystem_clock().now(); } } - -void DisinfectionStateMachine::startProcess() { - m_process_thread_.reset(new Thread("DisinfectionStateMachineThread", [this]() { - while (true) { - try { - loop(); - } catch (const appexception& e) { - if (m_exception_processer) m_exception_processer(e); - } - } - })); -} diff --git a/appsrc/service/app/disinfection_ctrl/disinfection_state_machine.hpp b/appsrc/service/app/disinfection_ctrl/disinfection_state_machine.hpp index 5e631ed..7080873 100644 --- a/appsrc/service/app/disinfection_ctrl/disinfection_state_machine.hpp +++ b/appsrc/service/app/disinfection_ctrl/disinfection_state_machine.hpp @@ -21,11 +21,9 @@ using namespace std; class DisinfectionStateMachine { THISCLASS(DisinfectionStateMachine) private: - DisinfectionState m_state = DisinfectionState::idle; - + DisinfectionState m_state = DisinfectionState::idle; list> m_event_list; recursive_mutex lock_; - unique_ptr m_process_thread_; map> m_state_processer_map; @@ -36,12 +34,19 @@ class DisinfectionStateMachine { zsystem_tp m_enter_state_tp; public: + nod::signal onStartDisinfection; + nod::signal onStopDisinfection; + + public: DisinfectionStateMachine() {} ~DisinfectionStateMachine() {} void regStateProcesser(DisinfectionState state, function processer); void regBfStateProcess(function processer); - void regExceptionProcesser(function processer); + + public: + void resetState(); + void process(); void pushEvent(DisinfectionEvent state); void changeState(DisinfectionState state); @@ -49,10 +54,8 @@ class DisinfectionStateMachine { DisinfectionState getState() { return m_state; } int32_t getStateHasPassedTimeMs() { return zsystem_clock().elapsedTimeMs(m_enter_state_tp); } - void startProcess(); + public: void callStateProcesser(DisinfectionState state, DisinfectionEvent* event); - private: - void loop(); }; } // namespace disinfection diff --git a/appsrc/service/app/disinfection_ctrl_service_ext.cpp b/appsrc/service/app/disinfection_ctrl_service_ext.cpp index 8f018be..849ec51 100644 --- a/appsrc/service/app/disinfection_ctrl_service_ext.cpp +++ b/appsrc/service/app/disinfection_ctrl_service_ext.cpp @@ -15,6 +15,8 @@ static string toDisplayName(DisinfectionState state) { switch (state.id) { case DisinfectionState::kidle: return "空闲"; + case DisinfectionState::kinit: + return "初始化"; case DisinfectionState::kpreheat: return "预热"; case DisinfectionState::kdisinfection: @@ -39,7 +41,6 @@ void DisinfectionCtrlServiceExt::initialize() { GET_TO_SERVICE(ds); GET_TO_SERVICE(gConfig); GET_TO_SERVICE(dcs); - GET_TO_SERVICE(dwus); REGFNV2(DisinfectionCtrlServiceExt, start); REGFNV2(DisinfectionCtrlServiceExt, startWithFormula); @@ -48,78 +49,58 @@ void DisinfectionCtrlServiceExt::initialize() { REGFNV2(DisinfectionCtrlServiceExt, getRealtimeConfig); REGFNV2(DisinfectionCtrlServiceExt, setRealtimeConfig); REGFNV2(DisinfectionCtrlServiceExt, getServiceConfig); - } void DisinfectionCtrlServiceExt::fn_start(shared_ptr cxt) { // 从setting中获取实时参数 - m_formulaid = ""; - auto allrealtimesetting = SETTING_DB->getRealtimeSetting(); - m_realtimeCfg.clear(); - for (auto& setting : allrealtimesetting) { - m_realtimeCfg[string(setting->setting_id)] = setting->val; - } - // - + string loglevel = cxt->params["loglevel"]; + int level = atoi(loglevel.c_str()); + dcs->start(level); // m_state = DisinfectionState::preheat; } void DisinfectionCtrlServiceExt::fn_startWithFormula(shared_ptr cxt) { // - m_formulaid = cxt->params["formula_id"]; - m_defaultFormulaJson = FORMULA_DB->getFormula(m_formulaid); - m_realtimeCfg.clear(); - - auto allrealtimesetting = SETTING_DB->getRealtimeSetting(); - for (auto& setting : allrealtimesetting) { - m_realtimeCfg[string(setting->setting_id)] = m_defaultFormulaJson[string(setting->setting_id)]; - } - // m_state = DisinfectionState::preheat; -} -void DisinfectionCtrlServiceExt::fn_stop(shared_ptr cxt) { - m_formulaid = ""; - m_state = DisinfectionState::idle; + string formulaid = cxt->params["formulaId"]; + dcs->startWithFormula(formulaid); } +void DisinfectionCtrlServiceExt::fn_stop(shared_ptr cxt) { dcs->stop(); } void DisinfectionCtrlServiceExt::fn_getRealtimeConfig(shared_ptr cxt) { json& rely = cxt->content; - for (auto& cfg : m_realtimeCfg) { + for (auto& cfg : dcs->getRealtimeCfg()) { rely[cfg.first] = cfg.second; } } void DisinfectionCtrlServiceExt::fn_setRealtimeConfig(shared_ptr cxt) { - string key = cxt->params["key"]; - string val = cxt->params; - m_realtimeCfg[key] = val; + string key = cxt->params["key"]; + string val = cxt->params; + dcs->getRealtimeCfg()[key] = val; } void DisinfectionCtrlServiceExt::fn_getState(shared_ptr cxt) { json& rely = cxt->content; - rely["statedisplayName"] = toDisplayName(m_state); - rely["state"] = string(m_state); - rely["curStateRemainTimeS"] = 60; - rely["tlog"] = "12.0"; - rely["nlog"] = "3.0"; + rely["statedisplayName"] = toDisplayName(string(dcs->getState())); + rely["state"] = string(dcs->getState()); + rely["curStateRemainTimeS"] = dcs->getCurStateRemainTimeS(); + rely["tlog"] = dcs->getTlog(); + rely["nlog"] = dcs->getNlog(); - json sensordata; - sensordata[0]["h2o2"] = 11.1; - sensordata[0]["temp"] = 12.2; - sensordata[0]["rh"] = 13.3; - sensordata[0]["rs"] = 14.4; - - sensordata[1]["h2o2"] = 21.1; - sensordata[1]["temp"] = 22.2; - sensordata[1]["rh"] = 23.3; - sensordata[1]["rs"] = 24.4; - - sensordata[2]["h2o2"] = 31.1; - sensordata[2]["temp"] = 32.2; - sensordata[2]["rh"] = 33.3; - sensordata[2]["rs"] = 34.4; + auto h2o2 = dcs->getH2O2Snapshot(); + json sensordata; + for (int i = 0; i < h2o2->getSensorDataNum(); i++) { + json sensor; + sensor["h2o2"] = h2o2->h2o2[i]; + sensor["temp"] = h2o2->temp[i]; + sensor["rh"] = h2o2->humid[i]; + sensor["rs"] = h2o2->saturation[i]; + sensor["online"] = !h2o2->isExpired[i]; + sensordata.push_back(sensor); + } rely["h2o2SensorData"] = sensordata; } void DisinfectionCtrlServiceExt::fn_getServiceConfig(shared_ptr cxt) { - json& rely = cxt->content; - rely["curveNum"] = 3; - rely["updatePeriodMs"] = 5000; + json& rely = cxt->content; + rely["curveNum"] = PORT.getExtH2O2SensorNum() + 1; + rely["curveUpdatePeriodMs"] = 10000; } diff --git a/appsrc/service/app/disinfection_ctrl_service_ext.hpp b/appsrc/service/app/disinfection_ctrl_service_ext.hpp index 80eb731..9fe9b0c 100644 --- a/appsrc/service/app/disinfection_ctrl_service_ext.hpp +++ b/appsrc/service/app/disinfection_ctrl_service_ext.hpp @@ -9,8 +9,8 @@ #include #include // -#include "disinfection_ctrl/disinfection_ctrl_service.hpp" #include "baseservice/baseservice.hpp" +#include "disinfection_ctrl/disinfection_ctrl_service.hpp" #include "disinfection_ctrl/disinfection_state_machine.hpp" #include "service/hardware/base/h2o2_sensor_data_mgr.hpp" #include "service/hardware/device_io_ctrl_service.hpp" @@ -27,14 +27,7 @@ class DisinfectionCtrlServiceExt : public enable_shared_from_this ds; shared_ptr gConfig; - shared_ptr dcs; - shared_ptr dwus; - - DisinfectionState m_state = DisinfectionState::idle; - - map m_realtimeCfg; - json m_defaultFormulaJson; - string m_formulaid; + shared_ptr dcs; public: void initialize(); @@ -54,7 +47,6 @@ class DisinfectionCtrlServiceExt : public enable_shared_from_this cxt); void fn_getServiceConfig(shared_ptr cxt); - }; } // namespace iflytop diff --git a/appsrc/service/main_control_service.cpp b/appsrc/service/app_core.cpp similarity index 62% rename from appsrc/service/main_control_service.cpp rename to appsrc/service/app_core.cpp index 154dcbf..85076b1 100644 --- a/appsrc/service/main_control_service.cpp +++ b/appsrc/service/app_core.cpp @@ -1,4 +1,4 @@ -#include "main_control_service.hpp" +#include "app_core.hpp" #include "baseservice/baseservice.hpp" #include "service/audit_mgr_service.hpp" @@ -25,12 +25,12 @@ using namespace core; using namespace std; using namespace nlohmann; -void MainControlService::dosystem(string order, bool dump) { +void AppCore::dosystem(string order, bool dump) { if (dump) logger->info("do:{}", order); system(order.c_str()); } -void MainControlService::initialize() { +void AppCore::initialize() { // FrontEnd BUILD_AND_REG_SERRVICE(IflytopFrontEndService); BUILD_AND_REG_SERRVICE(FrontMsgProcesser); @@ -40,6 +40,7 @@ void MainControlService::initialize() { BUILD_AND_REG_SERRVICE(DeviceStateService); // Hardware BUILD_AND_REG_SERRVICE(DeviceIoControlService); + BUILD_AND_REG_SERRVICE(DisinfectantWeightUpdateService); BUILD_AND_REG_SERRVICE(WarningLightControler); // @@ -74,5 +75,52 @@ void MainControlService::initialize() { cmd = cxt->cmd; receipt = cxt->receipt; }); - + + /******************************************************************************* + * // APPCore * + *******************************************************************************/ + + wq.reset(new WorkQueue("AppCoreWorkQueue")); + + REGFN(AppCore, getState); + DS->onException.connect([this](int32_t ecode, string emessage) { + static int32_t _ecode = 0; + static string _emessage; + static tp_steady lasttime; + + if (_ecode == ecode && _emessage== emessage && tu_steady().elapsedTimeS(lasttime) < 5) { + return; + } + + _ecode = ecode; + _emessage = emessage; + lasttime = steady_clock::now(); + // SEND_PROMPT(emessage); + wq->enQueue([this]() { // + sleep(5); + logger->warn("AppCore::onException:{},force stop device", DS->getAppExceptionMessage()); + GET_SERVICE(DeviceIoControlService)->forceStopDeviceWithoutExc(); + }); + }); }; + +void AppCore::getState(shared_ptr cxt) { + // + auto& content = cxt->content; + + content["state"] = DS->getDeviceState(); + + content["loginInfo"]["loginFlag"] = DS->isLogin(); + content["loginInfo"]["loginUid"] = DS->getLoginUid(); + content["loginInfo"]["isLoginAdmin"] = DS->isLoginAdmin(); + + content["estate"]["ecode"] = DS->getAppExceptionCode(); + content["estate"]["state"] = DS->getAppExceptionFlag(); + content["estate"]["emessage"] = DS->getAppExceptionMessage(); +} + +void AppCore::loop() { + /** + * @brief + */ +} diff --git a/appsrc/service/main_control_service.hpp b/appsrc/service/app_core.hpp similarity index 50% rename from appsrc/service/main_control_service.hpp rename to appsrc/service/app_core.hpp index f0722b5..31e9b2f 100644 --- a/appsrc/service/main_control_service.hpp +++ b/appsrc/service/app_core.hpp @@ -15,11 +15,12 @@ #include "appbase/appbase.hpp" #include "appsetting/appsetting.hpp" +#include "baseservice/front_msg_processer/front_msg_processer.hpp" /** * @brief * - * service: MainControlService + * service: AppCore * * 监听事件: * 依赖状态: @@ -31,14 +32,29 @@ namespace iflytop { using namespace std; using namespace core; -class MainControlService : public enable_shared_from_this { - THISCLASS(MainControlService); +class WarningPrompt { public: - MainControlService() {}; + string promptId; + string message; + bool confirmedByUser; +}; + +class AppCore : public enable_shared_from_this { + THISCLASS(AppCore); + + unique_ptr wq; + list> warningPromptList; + + public: + AppCore() {}; void initialize(); private: + void getState(shared_ptr cxt); + + // void warningPro(); void dosystem(string order, bool dump); + void loop(); }; } // namespace iflytop \ No newline at end of file diff --git a/appsrc/service/device_info_mgr_service.cpp b/appsrc/service/device_info_mgr_service.cpp index 15b3560..ea0ba27 100644 --- a/appsrc/service/device_info_mgr_service.cpp +++ b/appsrc/service/device_info_mgr_service.cpp @@ -18,6 +18,6 @@ void DeviceInfoMgrService::getDeviceInfo(shared_ptr cxt) { / auto& content = cxt->content; content["projectType"] = m_gConfig->get_projectType(); content["appVersion"] = VERSION; - content["mircoVersion"] = "3.0.0"; + content["mircoVersion"] = "3.0.0";//TODO:换成真实的版本信息 content["ip"] = "192.168.8.10"; } diff --git a/appsrc/service/device_state_service_ext.cpp b/appsrc/service/device_state_service_ext.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/appsrc/service/device_state_service_ext.hpp b/appsrc/service/device_state_service_ext.hpp deleted file mode 100644 index eb83820..0000000 --- a/appsrc/service/device_state_service_ext.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -// -#include "appbase/appbase.hpp" -#include "appsetting/appsetting.hpp" -#include "baseservice/baseservice.hpp" -#include "iflytop/core/components/zcsv/zcsv.hpp" - -namespace iflytop { - -/** - * @brief - * getState中包含 - * - * - */ - - -class DeviceStateServiceExt : public enable_shared_from_this { - THISCLASS(DeviceStateServiceExt); - - public: - DeviceStateServiceExt(); - void initialize(); - - private: - void getState(shared_ptr cxt); -}; -} // namespace iflytop diff --git a/appsrc/service/hardware/device_io_ctrl_service.cpp b/appsrc/service/hardware/device_io_ctrl_service.cpp index e902bce..7e43297 100644 --- a/appsrc/service/hardware/device_io_ctrl_service.cpp +++ b/appsrc/service/hardware/device_io_ctrl_service.cpp @@ -50,18 +50,86 @@ void DeviceIoControlService::initialize() { } }); REGFNV2(DeviceIoControlService, test); + + /** + * @brief 初始化所有硬件状态 + */ + try { + if (PORT.isLageSpaceDM() || PORT.isSmallSpaceDM() || PORT.isPipeDM()) { + AddLiquidPump_stop(); + SprayPump_stop(); + Blower_close(); + AC_close(); + Heater_close(); + WarningLight_setState(0, 0, 0, 0); + if (PORT.isPipeDM()) { + PosiPressureProp_setValve(0); + NegaPressureProp_setValve(0); + AirLeakDetectTestModeCtrl_setMode(0); + } + } + } catch (const appexception &e) { + logger->error("initialize hardware error:{}", e.what()); + DS->setAppExceptionFlag(e); + } } + +#define TRY_DO(func) \ + try { \ + func; \ + } catch (...) { \ + } +void DeviceIoControlService::forceStopDeviceWithoutExc() { + if (PORT.isLageSpaceDM() || PORT.isSmallSpaceDM() || PORT.isPipeDM()) { + TRY_DO(AddLiquidPump_stop()); + TRY_DO(SprayPump_stop()); + TRY_DO(Blower_close()); + TRY_DO(AC_close()); + TRY_DO(Heater_close()); + TRY_DO(WarningLight_setState(0, 0, 0, 0)); + if (PORT.isPipeDM()) { + TRY_DO(PosiPressureProp_setValve(0)); + TRY_DO(NegaPressureProp_setValve(0)); + TRY_DO(AirLeakDetectTestModeCtrl_setMode(0)); + } + } +} + void DeviceIoControlService::processReportMsg(uint8_t from, uint8_t *hex, uint32_t hexlen) { // zcanbus_packet_t *packet = (zcanbus_packet_t *)hex; if (packet->function_id == kreport_h2o2_sensor_data) { + /******************************************************************************* + * H2O2 上报 * + *******************************************************************************/ report_h2o2_data_t *h2o2data = (report_h2o2_data_t *)packet->params; int sensorId = 0; - if (from < 100) sensorId = 0; else sensorId = from - 100; m_h2o2SensorDataMgr->updateH2o2SensorData(sensorId, h2o2data); + } else if (packet->function_id == kreport_heatpacket_pong) { + report_heatpacket_data_t *ack = (report_heatpacket_data_t *)packet->params; + logger->info("[Heat ][FROM:%03d] HeatIndex:%x ToardType:%s flag:%x", from, ack->heartIndex, BoardTypeId2Str(ack->boardType), ack->flag); + } else if (packet->function_id == kreport_exception_error) { + report_exeception_data_t *ack = (report_exeception_data_t *)packet->params; + logger->error("[Exception][FROM:%03d] subid:%x ecode:%s", from, ack->subid, ecode2str(ack->ecode)); + DS->setAppExceptionFlag(ack->ecode, ecode2str(ack->ecode)); + // TODO:添加异常读取指令 + } else if (packet->function_id == kreport_pressure_data) { + report_pressure_data_t *ack = (report_pressure_data_t *)packet->params; + string info; + info.append(fmt::format("[Pressure][FROM:{}]({})", from, ack->sensorDataNum)); + for (int i = 0; i < ack->sensorDataNum; i++) { + info.append(fmt::format("{}:{}, ", ack->data[i].subid, ack->data[i].pressureVal)); + } + logger->info(info); + } else if (packet->function_id == kreport_evaporation_bin_water_sensor) { + report_water_sensor_state_t *ack = (report_water_sensor_state_t *)packet->params; + logger->info("[蒸发仓内水浸][FROM:%03d] (%d)", from, ack->state); + } else if (packet->function_id == kreport_device_bottom_water_sensor) { + report_water_sensor_state_t *ack = (report_water_sensor_state_t *)packet->params; + logger->info("[设备底部水浸][FROM:%03d] (%d)", from, ack->state); } } diff --git a/appsrc/service/hardware/device_io_ctrl_service.hpp b/appsrc/service/hardware/device_io_ctrl_service.hpp index 3536931..3e74a8f 100644 --- a/appsrc/service/hardware/device_io_ctrl_service.hpp +++ b/appsrc/service/hardware/device_io_ctrl_service.hpp @@ -41,6 +41,7 @@ class DeviceIoControlService : public enable_shared_from_this getH2O2SensorMgr() { return m_h2o2SensorDataMgr; } private: - void fn_test(shared_ptr cxt) ; + void fn_test(shared_ptr cxt); }; } // namespace iflytop \ No newline at end of file diff --git a/appsrc/service/hardware/disinfectant_weight_update_service.cpp b/appsrc/service/hardware/disinfectant_weight_update_service.cpp index 6784f37..16ce601 100644 --- a/appsrc/service/hardware/disinfectant_weight_update_service.cpp +++ b/appsrc/service/hardware/disinfectant_weight_update_service.cpp @@ -12,6 +12,9 @@ void DisinfectantWeightUpdateService::initialize() { // } float DisinfectantWeightUpdateService::getWeight() { // + if (DS->getAppExceptionFlag()) { + THROW_APP_EXCEPTION(DS->getAppExceptionCode(), DS->getAppExceptionMessage()); + } return weightCache; } void DisinfectantWeightUpdateService::updateWeightThread() { diff --git a/appsrc/service/test_page_mgr_service.cpp b/appsrc/service/test_page_mgr_service.cpp index def4739..58cf392 100644 --- a/appsrc/service/test_page_mgr_service.cpp +++ b/appsrc/service/test_page_mgr_service.cpp @@ -23,7 +23,7 @@ void TestPageMgrService::initialize() { m_dict = make_shared(); m_testPageItemMgr.installDict(m_dict); - // 喷液泵 + // 喷液泵1 m_dict->insert("pumpVel", "速度"); m_dict->insert("sprayPumpCtrl", "喷液泵控制"); m_dict->insert("sprayPumpCtrl.forward", "正转"); @@ -43,7 +43,7 @@ void TestPageMgrService::initialize() { }); - // 加液泵 + // 加液泵2 m_dict->insert("addDischargePumpCtrl", "加液泵控制"); m_dict->insert("addDischargePumpCtrl.addingLiquid", "加液"); m_dict->insert("addDischargePumpCtrl.drainLiquid", "排液"); @@ -56,7 +56,7 @@ void TestPageMgrService::initialize() { } }); - // 空压机 + // 空压机3 m_dict->insert("airCompressorCtrl", "空压机控制"); m_dict->insert("airCompressorCtrl.on", "打开"); m_dict->insert("airCompressorCtrl.off", "关闭"); @@ -68,13 +68,13 @@ void TestPageMgrService::initialize() { } }); - // 空压机电流 + // 空压机电流4 m_dict->insert("acCurrent", "空压机电流"); m_testPageItemMgr.insertState("acCurrent", [this](string stateName) { // return fmt::format("{:.2f}A", dcs->AC_readEI()); }); - // 风机 + // 风机5 m_dict->insert("blowerCtrl", "风机控制"); m_testPageItemMgr.insertButtons("blowerCtrl", {}, {"on", "off"}, [this](string buttonName, vector param) { // if (buttonName == "on") { @@ -85,12 +85,13 @@ void TestPageMgrService::initialize() { return "error"; }); + // 风机电流6 m_dict->insert("blowerCurrent", "风机电流"); m_testPageItemMgr.insertState("blowerCurrent", [this](string stateName) { // return fmt::format("{:.2f}A", dcs->Blower_readEI()); }); - // 加热片 + // 加热片7 m_dict->insert("heatingCtrl", "加热片控制"); m_dict->insert("heatingCtrl.on", "打开"); m_dict->insert("heatingCtrl.off", "关闭"); @@ -102,6 +103,7 @@ void TestPageMgrService::initialize() { } }); + // 加热片状态8 m_dict->insert("heatingState", "加热片状态"); m_dict->insert("heatingState.temperature", "温度"); m_dict->insert("heatingState.current", "电流"); @@ -114,11 +116,26 @@ void TestPageMgrService::initialize() { return string("error"); }); + // 9 + m_dict->insert("printerTest", "打印机测试"); + m_dict->insert("printerTest.test", "测试"); + m_testPageItemMgr.insertButtons("printerTest", {}, {"test"}, [this](string buttonName, vector param) { // + GET_SERVICE(UartPrinter)->print("abcdefghijklmn\nopqrstuvwxyz\n1234567890"); + GET_SERVICE(UartPrinter)->print("一二三四五六七八九十\n十九八七六五四三二一"); + GET_SERVICE(UartPrinter)->print("\n"); + GET_SERVICE(UartPrinter)->print("\n"); + GET_SERVICE(UartPrinter)->print("\n"); + GET_SERVICE(UartPrinter)->print("\n"); + }); + + // 10 + m_testPageItemMgr.insertPlaceHolder(); + /******************************************************************************* * 正负压力控制 * *******************************************************************************/ - if (PORT.isPipeDM()) { + // 11 m_dict->insert("AirLeakDetectTestModeCtrl", ""); m_dict->insert("AirLeakDetectTestModeCtrl.normal", "正常模式"); m_dict->insert("AirLeakDetectTestModeCtrl.airTight", "密封模式"); @@ -130,7 +147,7 @@ void TestPageMgrService::initialize() { } }); - // 比例阀控制 + // 比例阀控制 12 m_dict->insert("PosiPressurePropCtrl", "正压比例阀控制"); m_dict->insert("PosiPressurePropCtrl.set", "设置"); m_dict->insert("PosiPressurePropCtrl.close", "关闭"); @@ -149,6 +166,7 @@ void TestPageMgrService::initialize() { } }); + // 比例阀控制 13 m_testPageItemMgr.insertButtons("NegaPressurePropCtrl", {"proportionalOpenPercent"}, {"set", "close"}, [this](string buttonName, vector param) { // if (buttonName == "set") { dcs->NegaPressureProp_setValve(atoi(param[0].c_str()));