From 4c3390e90213cc7ecaccd3534d20020b889fa23d Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sat, 17 Aug 2024 21:41:33 +0800 Subject: [PATCH] update --- README.md | 4 + app_protocols/appexception/appexception.hpp | 10 +-- appsrc/appbase/appbean/disinfection_state.hpp | 16 ++-- appsrc/appcomponents/canchannel/com/socket_can.cpp | 2 + .../devicestate/device_state_service.hpp | 17 +++- appsrc/service/app/add_liquid_service.cpp | 10 ++- .../disinfection_ctrl_service.cpp | 16 ++++ .../disinfection_ctrl_service.hpp | 5 +- .../disinfection_state_machine.cpp | 90 ++++++++++++---------- .../disinfection_state_machine.hpp | 7 +- appsrc/service/app/drain_liquid_service.cpp | 11 ++- .../service/hardware/base/h2o2_sensor_data_mgr.cpp | 6 +- .../disinfectant_weight_update_service.cpp | 9 ++- .../service/hardware/warning_light_controler.cpp | 21 ++++- appsrc/service/test_page_mgr_service.cpp | 4 + appsrc/service/testpage/test_page_processer.cpp | 18 ++--- 16 files changed, 170 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index af75aa6..eb64544 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ TODO: 8. 消毒测试 +9. 处理硬件异常上报 8. 添加一个程序根据全局异常标志位,对设备进行相应的检查,如果检查通过则清空标志位。同时如果发生异常,则发送板子复位指令,对板子进行复位。 5. 单片机支持自动过滤掉重发的指令。 + + + ``` \ No newline at end of file diff --git a/app_protocols/appexception/appexception.hpp b/app_protocols/appexception/appexception.hpp index 26a151c..8351cf2 100644 --- a/app_protocols/appexception/appexception.hpp +++ b/app_protocols/appexception/appexception.hpp @@ -17,8 +17,8 @@ #include #include -#include "app_protocols/apperrorcode/apperrorcode.hpp" #include "app_protocols/apperrorcode/app_errorcode_mgr.hpp" +#include "app_protocols/apperrorcode/apperrorcode.hpp" #include "iflytop/core/thisclass/thisclass.hpp" namespace iflytop { using namespace std; @@ -33,8 +33,8 @@ class appexception : public std::exception { appexception(ThisClass &thisclass, string func, int32_t ecode, const string &description) { this->description = description; this->m_ecode = ecode; - this->whatstr = description; - thisclass.logger->error("[{}:{}] throw exception: {} {}", thisclass.className, func, ecode2str(ecode), description); + this->whatstr = fmt::format("[{}:{}] throw exception: {} {}", thisclass.className, func, ecode2str(ecode), description); + thisclass.logger->error(whatstr); } appexception(ThisClass &thisclass, string func, int32_t ecode, const char *fmt, ...) { @@ -45,8 +45,8 @@ class appexception : public std::exception { this->description = buffer; this->m_ecode = ecode; - this->whatstr = buffer; - thisclass.logger->error("[{}:{}] throw exception: {} {}", thisclass.className, func, ecode2str(ecode), buffer); + this->whatstr = fmt::format("[{}:{}] throw exception: {} {}", thisclass.className, func, ecode2str(ecode), buffer); + thisclass.logger->error(whatstr); } virtual ~appexception() {} diff --git a/appsrc/appbase/appbean/disinfection_state.hpp b/appsrc/appbase/appbean/disinfection_state.hpp index 4fd4a71..195fe3d 100644 --- a/appsrc/appbase/appbean/disinfection_state.hpp +++ b/appsrc/appbase/appbean/disinfection_state.hpp @@ -2,16 +2,16 @@ #include "iflytop/core/components/zenum_template/zenum_template.hpp" - #define DisinfectionState_ZENUM_IMPL ZENUM_IMPL(DisinfectionState, DisinfectionState_LIST) -#define DisinfectionState_LIST(type, marco) /**/ \ - marco(type, idle) /**/ \ - marco(type, preheat) /**/ \ - marco(type, disinfection) /**/ \ - marco(type, degradation) /**/ \ - marco(type, finished) /**/ \ +#define DisinfectionState_LIST(type, marco) /**/ \ + marco(type, idle) /**/ \ + marco(type, preheat) /**/ \ + marco(type, disinfection) /**/ \ + marco(type, degradation) /**/ \ + marco(type, finished) /**/ \ marco(type, dehumidificationBeforeDisinfection) /**/ \ marco(type, dehumidificationAfterDisinfection) /**/ \ - marco(type, emptyLiquidFromTheLine) /**/ + marco(type, emptyLiquidFromTheLine) /**/ \ + marco(type, appexception) /**/ ZENUM_DECLAR(DisinfectionState, DisinfectionState_LIST); diff --git a/appsrc/appcomponents/canchannel/com/socket_can.cpp b/appsrc/appcomponents/canchannel/com/socket_can.cpp index ce96467..a4ef66c 100644 --- a/appsrc/appcomponents/canchannel/com/socket_can.cpp +++ b/appsrc/appcomponents/canchannel/com/socket_can.cpp @@ -381,6 +381,7 @@ void SocketCan::monitorLoop() { if (m_canTriggerError) { // 尝试恢复CAN总线 logger->warn("try to recover can bus............................................"); + if (m_thread) { m_thread->join(); m_thread = nullptr; @@ -410,6 +411,7 @@ void SocketCan::monitorLoop() { m_canBusIsReady = true; logger->warn("recover can bus ok............................................"); + thisThread.sleepForMs(10 * 1000); // 下一次恢复至少等到10s之后 } thisThread.sleepForMs(30); diff --git a/appsrc/baseservice/devicestate/device_state_service.hpp b/appsrc/baseservice/devicestate/device_state_service.hpp index aa8448c..3a77d4e 100644 --- a/appsrc/baseservice/devicestate/device_state_service.hpp +++ b/appsrc/baseservice/devicestate/device_state_service.hpp @@ -40,6 +40,10 @@ class DeviceStateService : public enable_shared_from_this { DeviceState state = DeviceState::Idle; + int32_t m_ecode = 0; + string m_emessage; + bool m_appexception = false; + public: DeviceStateService() {}; @@ -60,6 +64,15 @@ 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; } + void setAppExceptionFlag(const appexception &e) { + m_appexception = true; + m_emessage = e.what(); + m_ecode = e.ecode(); + } + void clearAppExceptionFlag() { m_appexception = false; } + void initialize() {}; }; @@ -80,4 +93,6 @@ static inline int32_t getDeviceBusyReason(DeviceState nowState) { } } -} // namespace iflytop \ No newline at end of file +} // namespace iflytop + +#define DS GET_SERVICE(DeviceStateService) \ No newline at end of file diff --git a/appsrc/service/app/add_liquid_service.cpp b/appsrc/service/app/add_liquid_service.cpp index b724a6d..e1cb0d7 100644 --- a/appsrc/service/app/add_liquid_service.cpp +++ b/appsrc/service/app/add_liquid_service.cpp @@ -36,7 +36,15 @@ void AddLiquidService::start(int stopatg) { } m_workstate = kaddingLiquid; - m_thread.reset(new Thread("addLiquid", [this, stopatg]() { addLiquidWork(stopatg); })); + m_thread.reset(new Thread("addLiquid", [this, stopatg]() { + try { + addLiquidWork(stopatg); + } catch (const appexception& e) { + logger->error("addLiquidWork exception: {}", e.what()); + DS->setAppExceptionFlag(e); + } + m_workstate = kidle; + })); // logger->info("start add liquid success"); } diff --git a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp index 712c576..a8f103f 100644 --- a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp +++ b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp @@ -115,7 +115,9 @@ 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(); } @@ -177,6 +179,20 @@ void DisinfectionCtrlService::traceState() { /******************************************************************************* * StateMachine * *******************************************************************************/ +void DisinfectionCtrlService::exceptionProcesser(const appexception& e) { + logger->error("exceptionProcesser:{}", e); + 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::beforeStateProcess() { s_h2o2Snapshot = dcs->getH2O2SensorMgr()->takeSnapshot(); } void DisinfectionCtrlService::changeToNextState() { diff --git a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp index 12f8f6f..906336e 100644 --- a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp +++ b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp @@ -19,8 +19,6 @@ namespace iflytop { using namespace disinfection; - - class DisinfectionCtrlService : public enable_shared_from_this { THISCLASS(DisinfectionCtrlService); @@ -88,6 +86,9 @@ 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_); @@ -31,59 +32,66 @@ void DisinfectionStateMachine::callStateProcesser(DisinfectionState state, Disin iter->second(event); } } +void DisinfectionStateMachine::loop() { + this_thread::sleep_for(chrono::milliseconds(2)); -void DisinfectionStateMachine::startProcess() { - m_process_thread_.reset(new Thread("DisinfectionStateMachineThread", [this]() { - while (true) { - this_thread::sleep_for(chrono::milliseconds(2)); + shared_ptr event; - shared_ptr event; + bool popevent = false; + { + lock_guard lock(lock_); + if (!m_event_list.empty()) { + event = m_event_list.front(); + m_event_list.pop_front(); + popevent = true; + } + } - bool popevent = false; - { - lock_guard lock(lock_); - if (!m_event_list.empty()) { - event = m_event_list.front(); - m_event_list.pop_front(); - popevent = true; - } - } + if (popevent) { + if (event->event == kevent_change_state) { + DisinfectionEvent exit_event; + DisinfectionEvent enter_event; - if (popevent) { - if (event->event == kevent_change_state) { - DisinfectionEvent exit_event; - DisinfectionEvent enter_event; + exit_event.event = kevent_exit_state; + exit_event.exitState.next = event->changeState.to; - exit_event.event = kevent_exit_state; - exit_event.exitState.next = event->changeState.to; + enter_event.event = kevent_enter_state; + enter_event.enterState.last = event->changeState.from; - enter_event.event = kevent_enter_state; - enter_event.enterState.last = event->changeState.from; + callStateProcesser(m_state, &exit_event); + m_state = event->changeState.to; - callStateProcesser(m_state, &exit_event); - m_state = event->changeState.to; + m_enter_state_tp = zsystem_clock().now(); + logger->info("change state from {} to {}", // + string(event->changeState.from), string(event->changeState.to)); - m_enter_state_tp = zsystem_clock().now(); - logger->info("change state from {} to {}", // - string(event->changeState.from), string(event->changeState.to)); + callStateProcesser(m_state, &enter_event); - callStateProcesser(m_state, &enter_event); + } else { + logger->info("process event: {}", disinfection_event_to_string(event->event)); + callStateProcesser(m_state, event.get()); + } + } - } else { - logger->info("process event: {}", disinfection_event_to_string(event->event)); - callStateProcesser(m_state, event.get()); - } - } + /** + * @brief + */ + if (zsystem_clock().elapsedTimeMs(m_last_tmr_event) > 1000) { + DisinfectionEvent event; + event.event = kevent_tmr_1s; - /** - * @brief - */ - if (zsystem_clock().elapsedTimeMs(m_last_tmr_event) > 1000) { - DisinfectionEvent event; - event.event = kevent_tmr_1s; + callStateProcesser(m_state, &event); + m_last_tmr_event = zsystem_clock().now(); + } +} - callStateProcesser(m_state, &event); - 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 4c9eb56..7b9c798 100644 --- a/appsrc/service/app/disinfection_ctrl/disinfection_state_machine.hpp +++ b/appsrc/service/app/disinfection_ctrl/disinfection_state_machine.hpp @@ -30,7 +30,8 @@ class DisinfectionStateMachine { map> m_state_processer_map; - function m_bf_state_processer; + function m_bf_state_processer; + function m_exception_processer; zsystem_tp m_last_tmr_event; zsystem_tp m_enter_state_tp; @@ -41,6 +42,8 @@ class DisinfectionStateMachine { void regStateProcesser(DisinfectionState state, function processer); void regBfStateProcess(function processer); + void regExceptionProcesser(function processer); + void pushEvent(DisinfectionEvent state); void changeState(DisinfectionState state); @@ -49,6 +52,8 @@ class DisinfectionStateMachine { void startProcess(); void callStateProcesser(DisinfectionState state, DisinfectionEvent* event); + private: + void loop(); }; } // namespace disinfection diff --git a/appsrc/service/app/drain_liquid_service.cpp b/appsrc/service/app/drain_liquid_service.cpp index 0ae4235..a12358c 100644 --- a/appsrc/service/app/drain_liquid_service.cpp +++ b/appsrc/service/app/drain_liquid_service.cpp @@ -24,7 +24,15 @@ void DrainLiquidService::start() { } m_workstate = kwork; - m_thread.reset(new Thread("addLiquid", [this]() { workThread(); })); + m_thread.reset(new Thread("drainLiquid", [this]() { + try { + workThread(); + } catch (const appexception& e) { + logger->error("catch exception: {}", e.what()); + DS->setAppExceptionFlag(e); + } + m_workstate = kidle; + })); } DrainLiquidService::state_t DrainLiquidService::getWorkstate() { return m_workstate; } @@ -84,5 +92,4 @@ void DrainLiquidService::workThread() { if (!thisThread.getExitFlag()) { GET_SERVICE(IflytopFrontEndService)->sendPrompt("排液完成"); } - m_workstate = kidle; } diff --git a/appsrc/service/hardware/base/h2o2_sensor_data_mgr.cpp b/appsrc/service/hardware/base/h2o2_sensor_data_mgr.cpp index 5f13628..88bde10 100644 --- a/appsrc/service/hardware/base/h2o2_sensor_data_mgr.cpp +++ b/appsrc/service/hardware/base/h2o2_sensor_data_mgr.cpp @@ -66,7 +66,11 @@ shared_ptr H2O2SensorDataMgr::getSensorDataCache(uint8_t se void H2O2SensorDataMgr::updateH2o2SensorData(uint8_t sensorId, report_h2o2_data_t* h2o2data) { lock_guard lock(m_lock); - logger->info("update h2o2 : sensorId = {}, h2o2 = {}, temp = {}, humid = {}, saturation = {}", sensorId, h2o2data->h2o2, h2o2data->temp, h2o2data->humid, h2o2data->saturation); + + // 打印10次日志,以后的调试通过前端读取获取 + static int logcnt = 0; + logcnt++; + if (logcnt < 10) logger->info("update h2o2 : sensorId = {}, h2o2 = {}, temp = {}, humid = {}, saturation = {}", sensorId, h2o2data->h2o2, h2o2data->temp, h2o2data->humid, h2o2data->saturation); auto dataCache = getSensorDataCache(sensorId); dataCache->updatetime = zsys_get_ticket(); diff --git a/appsrc/service/hardware/disinfectant_weight_update_service.cpp b/appsrc/service/hardware/disinfectant_weight_update_service.cpp index ea567b5..6784f37 100644 --- a/appsrc/service/hardware/disinfectant_weight_update_service.cpp +++ b/appsrc/service/hardware/disinfectant_weight_update_service.cpp @@ -16,6 +16,12 @@ float DisinfectantWeightUpdateService::getWeight() { // } void DisinfectantWeightUpdateService::updateWeightThread() { while (true) { + if (DS->getAppExceptionFlag()) { + sleep(1); + continue; + } + + // 读取压力传感器数据 try { float pa = deviceIoControlService->LiquidWeightPS_readPa(); pa = filter.filter(pa); @@ -27,8 +33,9 @@ void DisinfectantWeightUpdateService::updateWeightThread() { float weight_g = ProjectPort::ins().pressurePa2VolumeG(pa); weightCache = weight_g; logger->debug("updateWeightThread: pa={}, weight_g={}", pa, weight_g); - } catch (const std::exception& e) { + } catch (const appexception& e) { logger->error("updateWeightThread error: {}", e.what()); + DS->setAppExceptionFlag(e); } sleep(1); } diff --git a/appsrc/service/hardware/warning_light_controler.cpp b/appsrc/service/hardware/warning_light_controler.cpp index 6e974c4..b5ac563 100644 --- a/appsrc/service/hardware/warning_light_controler.cpp +++ b/appsrc/service/hardware/warning_light_controler.cpp @@ -25,7 +25,26 @@ void WarningLightControler::workThread() { void WarningLightControler::initialize() { GET_TO_SERVICE(dcs); logger->warn("WarningLightControler initialize"); - m_thread.reset(new Thread("LightCtrlServiceThread", std::bind(&WarningLightControler::workThread, this))); + + m_thread.reset(new Thread("LightCtrlServiceThread", [this]() { + while (true) { + if (DS->getAppExceptionFlag()) { + ThisThread().sleepForMs(1000); + m_workFlag = false; + m_warningFlag = false; + m_nowState = kstate_uninit; + m_beepState = false; + continue; + } + + try { + workThread(); + } catch (const appexception& e) { + logger->error("WarningLightControler workThread error: {}", e.what()); + DS->setAppExceptionFlag(e); + } + } + })); } void WarningLightControler::beepCtrl(lightState_t state) { diff --git a/appsrc/service/test_page_mgr_service.cpp b/appsrc/service/test_page_mgr_service.cpp index 3c927d5..def4739 100644 --- a/appsrc/service/test_page_mgr_service.cpp +++ b/appsrc/service/test_page_mgr_service.cpp @@ -114,6 +114,10 @@ void TestPageMgrService::initialize() { return string("error"); }); + /******************************************************************************* + * 正负压力控制 * + *******************************************************************************/ + if (PORT.isPipeDM()) { m_dict->insert("AirLeakDetectTestModeCtrl", ""); m_dict->insert("AirLeakDetectTestModeCtrl.normal", "正常模式"); diff --git a/appsrc/service/testpage/test_page_processer.cpp b/appsrc/service/testpage/test_page_processer.cpp index 7ccced0..edfe69e 100644 --- a/appsrc/service/testpage/test_page_processer.cpp +++ b/appsrc/service/testpage/test_page_processer.cpp @@ -39,16 +39,6 @@ void TestPageItemMgr::insertButtons(string name, vector params, vector params, onButton_t onButton) { -// shared_ptr