From 5abd4033e0014e47f0764b7769ce6ac4049d7594 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Fri, 16 Aug 2024 19:13:55 +0800 Subject: [PATCH] recode --- .../disinfection_ctrl_service.cpp | 510 +++++++++++++++++ .../disinfection_ctrl_service.hpp | 101 ++++ appsrc/service/app/disinfection_ctrl_service.cpp | 613 --------------------- appsrc/service/app/disinfection_ctrl_service.hpp | 137 ----- .../service/app/disinfection_ctrl_service_ext.cpp | 125 +++++ .../service/app/disinfection_ctrl_service_ext.hpp | 61 ++ appsrc/service/main_control_service.cpp | 2 +- 7 files changed, 798 insertions(+), 751 deletions(-) create mode 100644 appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp create mode 100644 appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp delete mode 100644 appsrc/service/app/disinfection_ctrl_service.cpp delete mode 100644 appsrc/service/app/disinfection_ctrl_service.hpp create mode 100644 appsrc/service/app/disinfection_ctrl_service_ext.cpp create mode 100644 appsrc/service/app/disinfection_ctrl_service_ext.hpp diff --git a/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp new file mode 100644 index 0000000..6892f1f --- /dev/null +++ b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp @@ -0,0 +1,510 @@ +#include "disinfection_ctrl_service.hpp" + +#include "appcomponents/algo/dvalue_computer.hpp" +#include "service/hardware/warning_light_controler.hpp" +using namespace iflytop; +using namespace disinfection; + +#define DEFAULT_BLOWSER_LEVEL 90 +#define DVALUE_COMPUTEPERIOD_TIME_S (10.0) + +#define SETTING_DB SettingDBDao::ins() +#define FORMULA_DB FormulaDBDao::ins() + +string DisinfectionCtrlService::getSetting(SettingId sid) { + // 1. 从 realtimeCfg 中进行查找 + // 2. 从 系统配置 中进行查找 + // m_realtimeCfg.find + auto value = m_realtimeCfg.find(sid); + if (value != m_realtimeCfg.end()) { + return value->second; + } + 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()); + } + return str; +} + +int DisinfectionCtrlService::getSettingAsInt(SettingId sid) { return atoi(getSetting(sid).c_str()); } +bool DisinfectionCtrlService::getSettingAsBool(SettingId sid) { return getSetting(sid) == "true" || getSetting(sid) == "1"; } +float DisinfectionCtrlService::getSettingAsFloat(SettingId sid) { return atof(getSetting(sid).c_str()); } + +float DisinfectionCtrlService::computeNextLogLevel(float nowloglevel, float dval) { + float dvalue = dval; + if (dvalue > 0) { + return nowloglevel + DVALUE_COMPUTEPERIOD_TIME_S / (dvalue * 60); + } + return nowloglevel; +} + +void DisinfectionCtrlService::updateRemainTime(int dval, float nlog, float tlog, int& remaintime) { + /** + * @brief 计算Dvalue + */ + if (dval > 0) { + /** + * @brief 计算 now_loglevel + */ + if (tlog >= nlog) { + remaintime = (tlog - nlog) * (dval * 60); + } else { + remaintime = 0; + } + } else { + // + } +} + +bool DisinfectionCtrlService::isTimeToPauseDisinfection() { + /** + * @brief 检查当前 + */ + float nowSatur = s_h2o2Snapshot->maxSaturation; + float nowh2o2 = s_h2o2Snapshot->maxH2O2; + float humid = s_h2o2Snapshot->maxHumid; + + if (nowSatur > getSettingAsInt(SettingId::stoped_satur)) { + logger->info("nowSatur {} > getSettingAsInt(SettingId::stoped_satur) {}", nowSatur, getSettingAsInt(SettingId::stoped_satur)); + return true; + } + + if (nowh2o2 > getSettingAsInt(SettingId::stoped_gs)) { + logger->info("nowh2o2 {} > getSettingAsInt(SettingId::stoped_gs) {}", nowh2o2, getSettingAsInt(SettingId::stoped_gs)); + return true; + } + + if (humid > getSettingAsInt(SettingId::stoped_humi)) { + logger->info("humid {} > getSettingAsInt(SettingId::stoped_humi) {}", humid, getSettingAsInt(SettingId::stoped_humi)); + return true; + } + + return false; +} +bool DisinfectionCtrlService::isTimeToResumeDisinfection() { + /** + * @brief 检查当前 + */ + float nowSatur = s_h2o2Snapshot->maxSaturation; + float nowh2o2 = s_h2o2Snapshot->maxH2O2; + float humid = s_h2o2Snapshot->maxHumid; + + if (nowSatur < getSettingAsInt(SettingId::continued_satur) && // + nowh2o2 < getSettingAsInt(SettingId::continued_gs) && // + humid < getSettingAsInt(SettingId::continued_humi)) { + logger->info("nowSatur {} < getSettingAsInt(SettingId::continued_satur) {} && nowh2o2 {} < getSettingAsInt(SettingId::continued_gs) {} && humid {} < getSettingAsInt(SettingId::continued_humi) {}", // + nowSatur, getSettingAsInt(SettingId::continued_satur), nowh2o2, getSettingAsInt(SettingId::continued_gs), humid, getSettingAsInt(SettingId::continued_humi)); + return true; + } + + return false; +} + +void DisinfectionCtrlService::initialize() { + GET_TO_SERVICE(db); + GET_TO_SERVICE(ds); + GET_TO_SERVICE(gConfig); + GET_TO_SERVICE(dcs); + GET_TO_SERVICE(dwus); + + + sm.regStateProcesser(DisinfectionState::idle, bind(&DisinfectionCtrlService::processStateIdle, 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)); + sm.regStateProcesser(DisinfectionState::finished, bind(&DisinfectionCtrlService::processStateFinished, this, placeholders::_1)); + 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.regBfStateProcess(bind(&DisinfectionCtrlService::beforeStateProcess, this)); + sm.startProcess(); +} + +/******************************************************************************* + * APP_IMPL * + *******************************************************************************/ + +void DisinfectionCtrlService::start() { + DisinfectionEvent event; + event.event = kevent_start; + sm.pushEvent(event); + + // 等待任务开始 + while (sm.getState() == DisinfectionState::finished) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } +} +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)); + } +} +void DisinfectionCtrlService::updateCfg() { + DisinfectionEvent event; + event.event = kevent_update_cfg; + sm.pushEvent(event); +} + +void DisinfectionCtrlService::tryLogState(bool forceLog) { + // 每隔离10秒记录一次 + if (forceLog || zsteady_clock().elapsedTimeS(s_lastTakeSnapt) > 10) { + s_lastTakeSnapt = zsteady_clock().now(); + logState(); + traceState(); + } +} + +void DisinfectionCtrlService::logState() {} +void DisinfectionCtrlService::traceState() { + string tracecontent; + + tracecontent += fmt::format("[{}] ", string(sm.getState())); + tracecontent += fmt::format("dvalue:{} ", s_dvalue); + tracecontent += fmt::format("log:{}->{} ", s_nlog, s_tlog); + tracecontent += fmt::format("takebreak:{} ", s_isDisinfectionTakeBreak); + tracecontent += fmt::format("remaintime:{} ", s_remaintime); + + logger->info(tracecontent); +} + +/******************************************************************************* + * StateMachine * + *******************************************************************************/ +void DisinfectionCtrlService::beforeStateProcess() { s_h2o2Snapshot = dcs->getH2O2SensorMgr()->takeSnapshot(); } + +void DisinfectionCtrlService::changeToNextState() { + /** + * @brief + * + * + * kstate_idle + * | + * kstate_finished ------------------------ + * | | + * kstate_dehumidification_before_disinfection | + * | | + * kstate_preheat <----------------------| + * | + * kstate_disinfection + * | + * kstate_empty_liquid_from_the_line -----| + * | | + * kstate_dehumidification_after_disinfection | + * | | + * kstate_degradation <----| + * | + * kstate_finished + * + */ + + if (sm.getState() == DisinfectionState::idle) { + sm.changeState(DisinfectionState::finished); + } + + // + else if (sm.getState() == DisinfectionState::finished) { + if (PORT.isDrawBarDM()) { + if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dcs->ExtChSelector_isOnline()) { + sm.changeState(DisinfectionState::dehumidificationBeforeDisinfection); + } + } else { + sm.changeState(DisinfectionState::preheat); + } + } + // + else if (sm.getState() == DisinfectionState::dehumidificationBeforeDisinfection) { + sm.changeState(DisinfectionState::preheat); + } + // + else if (sm.getState() == DisinfectionState::preheat) { + sm.changeState(DisinfectionState::disinfection); + } + // + else if (sm.getState() == DisinfectionState::disinfection) { + sm.changeState(DisinfectionState::emptyLiquidFromTheLine); + } + // + else if (sm.getState() == DisinfectionState::emptyLiquidFromTheLine) { + if (PORT.isDrawBarDM()) { + if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dcs->ExtChSelector_isOnline()) { + sm.changeState(DisinfectionState::dehumidificationAfterDisinfection); + } + } else { + sm.changeState(DisinfectionState::degradation); + } + } + // + else if (sm.getState() == DisinfectionState::dehumidificationAfterDisinfection) { + sm.changeState(DisinfectionState::degradation); + } + // + else if (sm.getState() == DisinfectionState::degradation) { + sm.changeState(DisinfectionState::finished); + } +} + +void DisinfectionCtrlService::processStateIdle(DisinfectionEvent* event) { sm.changeState(DisinfectionState::finished); } +void DisinfectionCtrlService::processStateDehumidificationBeforeDisinfection(DisinfectionEvent* event) { + auto h2o2s = dcs->getH2O2SensorMgr(); + if (event->event == kevent_enter_state) { + tryLogState(true); + ZASSERT(PORT.isDrawBarDM()); + + dcs->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); + usleep(100 * 1000); + dcs->ExtChSelector_trySelectCh(kext_ch_dehumidification); + } + // + else if (event->event == kevent_exit_state) { + dcs->Blower_ctrl(0); + dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); + tryLogState(true); + } + // + else if (event->event == kevent_tmr_1s) { + int max_humid = h2o2s->getMaxHumid(); + int targetHumid = getSettingAsInt(SettingId::bd_dehumidify_threshold); + + if (max_humid <= targetHumid) { + logger->info("exit dehumidification state, because humidity is lower than target value"); + changeToNextState(); + return; + } else { + logger->info("dehumidification {} > {} ", max_humid, targetHumid); + } + changeToNextState(); + tryLogState(false); + } + + else if (event->event == kevent_stop) { + sm.changeState(DisinfectionState::finished); + } +} + +void DisinfectionCtrlService::processStatePreheat(DisinfectionEvent* event) { + if (event->event == kevent_enter_state) { + logger->info("preheat state enter"); + tryLogState(true); + + dcs->Blower_ctrl(90); + usleep(1000 * 1000); + dcs->Heater_ctrl(100); + + } else if (event->event == kevent_exit_state) { + logger->info("preheat state exit"); + + dcs->Blower_ctrl(0); + usleep(1000 * 1000); + dcs->Heater_ctrl(0); + + tryLogState(true); + } else if (event->event == kevent_tmr_1s) { + int preHeatTimeS = getSettingAsInt(SettingId::pre_heat_time_s); + + if (sm.getStateHasPassedTimeMs() > preHeatTimeS * 1000) { + // 退出预热状态,进入消毒状态 + changeToNextState(); + } + tryLogState(false); + } else if (event->event == kevent_stop) { + sm.changeState(DisinfectionState::finished); + } +} + +void DisinfectionCtrlService::processStateDisinfection(DisinfectionEvent* event) { + if (event->event == kevent_enter_state) { + tryLogState(true); + s_isDisinfectionTakeBreak = false; + if (PORT.isPipeDM()) { + dcs->AirLeakDetectTestChannelCtrl_releaseCh(); + } + 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)); + } else if (event->event == kevent_exit_state) { + s_isDisinfectionTakeBreak = false; + dcs->AC_close(); + dcs->Blower_close(); + dcs->Heater_close(); + dcs->SprayPump_stop(); + s_dvalue = 0; + tryLogState(true); + } else if (event->event == kevent_tmr_1s) { + /** + * @brief + * 计算D值 + * 计算消毒时间 + * 打印日志 + */ + + s_dvalue = DValueComputer().computeDValue(gConfig->get_dvalueCoefficient(), s_h2o2Snapshot->minH2O2); + + 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); + traceState(); + } + + s_remaintime--; + if (s_remaintime < 0) s_remaintime = 0; + + if (!s_isDisinfectionTakeBreak) { + if (isTimeToPauseDisinfection()) { + logger->info("pauseDisinfection"); + dcs->SprayPump_stop(); + dcs->AC_close(); + s_isDisinfectionTakeBreak = true; + traceState(); + } + } else { + if (isTimeToResumeDisinfection()) { + logger->info("resumeDisinfection"); + dcs->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); + dcs->AC_ctrl(1); + s_isDisinfectionTakeBreak = false; + traceState(); + } + } + + if (s_remaintime <= 0 && s_nlog > (s_tlog + 0.01)) { + /** + * @brief 消毒结束 + */ + changeToNextState(); + } + tryLogState(false); + + // 检查是否消毒完成 + } else if (event->event == kevent_update_cfg) { + if (!s_isDisinfectionTakeBreak) { + dcs->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()); + + } else if (event->event == kevent_exit_state) { + tryLogState(true); + dcs->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); + } else if (event->event == kevent_exit_state) { + dcs->Blower_close(); + dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); + tryLogState(true); + } else if (event->event == kevent_tmr_1s) { + if (!dcs->ExtChSelector_isOnline()) { + logger->error("exit dehumidification state, because extValBoard is offline"); + changeToNextState(); + return; + } + auto maxHumid = s_h2o2Snapshot->maxHumid; + + if (maxHumid <= getSettingAsInt(SettingId::ad_dehumidify_threshold)) { + logger->info("exit dehumidification state, because humidity is lower than target value"); + changeToNextState(); + + return; + } else { + logger->info("dehumidification {} > {} ", maxHumid, getSettingAsInt(SettingId::ad_dehumidify_threshold)); + } + + 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); + } else if (event->event == kevent_exit_state) { + dcs->Blower_close(); + dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); + tryLogState(true); + } else if (event->event == kevent_tmr_1s) { + auto maxH2O2 = s_h2o2Snapshot->maxH2O2; + + logger->info("waitting for h2o2 concentration to safe value {}=>{}", maxH2O2, 1); + if (maxH2O2 < 1) { + logger->info("h2o2 concentration to safe value"); + changeToNextState(); + } + tryLogState(false); + } else if (event->event == kevent_stop) { + sm.changeState(DisinfectionState::finished); + } +} +void DisinfectionCtrlService::processStateFinished(DisinfectionEvent* event) { + if (event->event == kevent_enter_state) { + // if (event->enterState.last != kstate_idle && event->enterState.last != kstate_finished) { + if (event->enterState.last != DisinfectionState::idle && event->enterState.last != DisinfectionState::finished) { + /** + * @brief 消毒结束 + */ + + dcs->SprayPump_stop(); + dcs->AC_ctrl(0); + dcs->Blower_close(); + dcs->Heater_close(); + + s_remaintime = 0; + s_complete_tp = zsystem_clock().now(); + if (PORT.isLageSpaceDM() || PORT.isSmallSpaceDM() || PORT.isPipeDM()) { + s_afterDisinfectantVolume_g = dcs->DisinfectantVolume_readVal(); + } else if (PORT.isDrawBarDM()) { + s_afterDisinfectantVolume_g = 0; + } + + GET_SERVICE(WarningLightControler)->setworkFlag(false); + + // tryLogSatate(true); + tryLogState(true); + 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 new file mode 100644 index 0000000..12f8f6f --- /dev/null +++ b/appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp @@ -0,0 +1,101 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include "appbase/disinfection_state.hpp" +#include "baseservice/baseservice.hpp" +#include "disinfection_state_machine.hpp" +#include "service/hardware/base/h2o2_sensor_data_mgr.hpp" +#include "service/hardware/device_ctrl_service.hpp" +#include "service/hardware/disinfectant_weight_update_service.hpp" +// +namespace iflytop { +using namespace disinfection; + + + +class DisinfectionCtrlService : public enable_shared_from_this { + THISCLASS(DisinfectionCtrlService); + + public: + shared_ptr db; + shared_ptr ds; + shared_ptr gConfig; + + shared_ptr dcs; + shared_ptr dwus; + + DisinfectionState m_state = DisinfectionState::idle; + + map m_realtimeCfg; + json m_defaultFormulaJson; + string m_formulaid; + + DisinfectionStateMachine sm; + + // + string s_sessionId; + zsystem_tp s_start_tp; + zsystem_tp s_complete_tp; + zsteady_tp start_steady_tp; + zsteady_tp s_lastTakeSnapt; // 上次日志时间 + zsteady_tp s_lastComputeDvalueTp; // 上次计算dvalue时间 + bool s_isDisinfectionTakeBreak = false; + shared_ptr s_h2o2Snapshot; + int32_t s_dvalue = 0; + int32_t s_remaintime; + float s_nlog; + float s_tlog; + int s_beforeDisinfectantVolume_g; // 消毒前消毒剂量 + int s_afterDisinfectantVolume_g; // 消毒后消毒剂量 + + public: + void initialize(); + + public: + string getSetting(SettingId sid); + int getSettingAsInt(SettingId sid); + bool getSettingAsBool(SettingId sid); + float getSettingAsFloat(SettingId sid); + + static float computeNextLogLevel(float nowloglevel, float dval); + static void updateRemainTime(int dval, float nlog, float tlog, int& remaintime); + bool isTimeToPauseDisinfection(); + bool isTimeToResumeDisinfection(); + + public: + // impl + + void start(); + void stop(); + void updateCfg(); + + private: + void beforeStateProcess(); + + void processStateIdle(DisinfectionEvent* event); + void processStatePreheat(DisinfectionEvent* event); + void processStateDisinfection(DisinfectionEvent* event); + void processStateDegradation(DisinfectionEvent* event); + void processStateFinished(DisinfectionEvent* event); + void processStateDehumidificationBeforeDisinfection(DisinfectionEvent* event); + void processStateDehumidificationAfterDisinfection(DisinfectionEvent* event); + void processStateEmpytLiquidFromTheLine(DisinfectionEvent* event); + + void changeToNextState(); + + private: + void tryLogState(bool forceLog); + void logState(); + void traceState(); + void initState(); +}; + +} // namespace iflytop diff --git a/appsrc/service/app/disinfection_ctrl_service.cpp b/appsrc/service/app/disinfection_ctrl_service.cpp deleted file mode 100644 index ac8554b..0000000 --- a/appsrc/service/app/disinfection_ctrl_service.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include "disinfection_ctrl_service.hpp" - -#include "appcomponents/algo/dvalue_computer.hpp" -#include "service/hardware/warning_light_controler.hpp" -using namespace iflytop; -using namespace disinfection; - -#define DEFAULT_BLOWSER_LEVEL 90 -#define DVALUE_COMPUTEPERIOD_TIME_S (10.0) - -#define SETTING_DB SettingDBDao::ins() -#define FORMULA_DB FormulaDBDao::ins() - -static string toDisplayName(DisinfectionState state) { - switch (state.id) { - case DisinfectionState::kidle: - return "空闲"; - case DisinfectionState::kpreheat: - return "预热"; - case DisinfectionState::kdisinfection: - return "消毒中"; - case DisinfectionState::kdegradation: - return "降解中"; - case DisinfectionState::kfinished: - return "消毒完成"; - case DisinfectionState::kdehumidificationBeforeDisinfection: - return "消毒前除湿"; - case DisinfectionState::kdehumidificationAfterDisinfection: - return "消毒后除湿"; - case DisinfectionState::kemptyLiquidFromTheLine: - return "排空管路"; - default: - return "未知"; - } -} - -string DisinfectionCtrlService::getSetting(SettingId sid) { - // 1. 从 realtimeCfg 中进行查找 - // 2. 从 系统配置 中进行查找 - // m_realtimeCfg.find - auto value = m_realtimeCfg.find(sid); - if (value != m_realtimeCfg.end()) { - return value->second; - } - 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()); - } - return str; -} - -int DisinfectionCtrlService::getSettingAsInt(SettingId sid) { return atoi(getSetting(sid).c_str()); } -bool DisinfectionCtrlService::getSettingAsBool(SettingId sid) { return getSetting(sid) == "true" || getSetting(sid) == "1"; } -float DisinfectionCtrlService::getSettingAsFloat(SettingId sid) { return atof(getSetting(sid).c_str()); } - -float DisinfectionCtrlService::computeNextLogLevel(float nowloglevel, float dval) { - float dvalue = dval; - if (dvalue > 0) { - return nowloglevel + DVALUE_COMPUTEPERIOD_TIME_S / (dvalue * 60); - } - return nowloglevel; -} - -void DisinfectionCtrlService::updateRemainTime(int dval, float nlog, float tlog, int& remaintime) { - /** - * @brief 计算Dvalue - */ - if (dval > 0) { - /** - * @brief 计算 now_loglevel - */ - if (tlog >= nlog) { - remaintime = (tlog - nlog) * (dval * 60); - } else { - remaintime = 0; - } - } else { - // - } -} - -bool DisinfectionCtrlService::isTimeToPauseDisinfection() { - /** - * @brief 检查当前 - */ - float nowSatur = s_h2o2Snapshot->maxSaturation; - float nowh2o2 = s_h2o2Snapshot->maxH2O2; - float humid = s_h2o2Snapshot->maxHumid; - - if (nowSatur > getSettingAsInt(SettingId::stoped_satur)) { - logger->info("nowSatur {} > getSettingAsInt(SettingId::stoped_satur) {}", nowSatur, getSettingAsInt(SettingId::stoped_satur)); - return true; - } - - if (nowh2o2 > getSettingAsInt(SettingId::stoped_gs)) { - logger->info("nowh2o2 {} > getSettingAsInt(SettingId::stoped_gs) {}", nowh2o2, getSettingAsInt(SettingId::stoped_gs)); - return true; - } - - if (humid > getSettingAsInt(SettingId::stoped_humi)) { - logger->info("humid {} > getSettingAsInt(SettingId::stoped_humi) {}", humid, getSettingAsInt(SettingId::stoped_humi)); - return true; - } - - return false; -} -bool DisinfectionCtrlService::isTimeToResumeDisinfection() { - /** - * @brief 检查当前 - */ - float nowSatur = s_h2o2Snapshot->maxSaturation; - float nowh2o2 = s_h2o2Snapshot->maxH2O2; - float humid = s_h2o2Snapshot->maxHumid; - - if (nowSatur < getSettingAsInt(SettingId::continued_satur) && // - nowh2o2 < getSettingAsInt(SettingId::continued_gs) && // - humid < getSettingAsInt(SettingId::continued_humi)) { - logger->info("nowSatur {} < getSettingAsInt(SettingId::continued_satur) {} && nowh2o2 {} < getSettingAsInt(SettingId::continued_gs) {} && humid {} < getSettingAsInt(SettingId::continued_humi) {}", // - nowSatur, getSettingAsInt(SettingId::continued_satur), nowh2o2, getSettingAsInt(SettingId::continued_gs), humid, getSettingAsInt(SettingId::continued_humi)); - return true; - } - - return false; -} - -void DisinfectionCtrlService::initialize() { - GET_TO_SERVICE(db); - GET_TO_SERVICE(ds); - GET_TO_SERVICE(gConfig); - GET_TO_SERVICE(dcs); - GET_TO_SERVICE(dwus); - - REGFNV2(DisinfectionCtrlService, start); - REGFNV2(DisinfectionCtrlService, startWithFormula); - REGFNV2(DisinfectionCtrlService, stop); - REGFNV2(DisinfectionCtrlService, getState); - REGFNV2(DisinfectionCtrlService, getRealtimeConfig); - REGFNV2(DisinfectionCtrlService, setRealtimeConfig); - REGFNV2(DisinfectionCtrlService, getServiceConfig); - - sm.regStateProcesser(DisinfectionState::idle, bind(&DisinfectionCtrlService::processStateIdle, 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)); - sm.regStateProcesser(DisinfectionState::finished, bind(&DisinfectionCtrlService::processStateFinished, this, placeholders::_1)); - 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.regBfStateProcess(bind(&DisinfectionCtrlService::beforeStateProcess, this)); - sm.startProcess(); -} - -void DisinfectionCtrlService::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; - } - // - - // m_state = DisinfectionState::preheat; -} -void DisinfectionCtrlService::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 DisinfectionCtrlService::fn_stop(shared_ptr cxt) { - m_formulaid = ""; - m_state = DisinfectionState::idle; -} - -void DisinfectionCtrlService::fn_getRealtimeConfig(shared_ptr cxt) { - json& rely = cxt->content; - for (auto& cfg : m_realtimeCfg) { - rely[cfg.first] = cfg.second; - } -} -void DisinfectionCtrlService::fn_setRealtimeConfig(shared_ptr cxt) { - string key = cxt->params["key"]; - string val = cxt->params; - m_realtimeCfg[key] = val; -} - -void DisinfectionCtrlService::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"; - - 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; - - rely["h2o2SensorData"] = sensordata; -} - -void DisinfectionCtrlService::fn_getServiceConfig(shared_ptr cxt) { - json& rely = cxt->content; - rely["curveNum"] = 3; - rely["updatePeriodMs"] = 5000; -} - -/******************************************************************************* - * APP_IMPL * - *******************************************************************************/ - -void DisinfectionCtrlService::start() { - DisinfectionEvent event; - event.event = kevent_start; - sm.pushEvent(event); - - // 等待任务开始 - while (sm.getState() == DisinfectionState::finished) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } -} -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)); - } -} -void DisinfectionCtrlService::updateCfg() { - DisinfectionEvent event; - event.event = kevent_update_cfg; - sm.pushEvent(event); -} - -void DisinfectionCtrlService::tryLogState(bool forceLog) { - // 每隔离10秒记录一次 - if (forceLog || zsteady_clock().elapsedTimeS(s_lastTakeSnapt) > 10) { - s_lastTakeSnapt = zsteady_clock().now(); - logState(); - traceState(); - } -} - -void DisinfectionCtrlService::logState() {} -void DisinfectionCtrlService::traceState() { - string tracecontent; - - tracecontent += fmt::format("[{}] ", string(sm.getState())); - tracecontent += fmt::format("dvalue:{} ", s_dvalue); - tracecontent += fmt::format("log:{}->{} ", s_nlog, s_tlog); - tracecontent += fmt::format("takebreak:{} ", s_isDisinfectionTakeBreak); - tracecontent += fmt::format("remaintime:{} ", s_remaintime); - - logger->info(tracecontent); -} - -/******************************************************************************* - * StateMachine * - *******************************************************************************/ -void DisinfectionCtrlService::beforeStateProcess() { s_h2o2Snapshot = dcs->getH2O2SensorMgr()->takeSnapshot(); } - -void DisinfectionCtrlService::changeToNextState() { - /** - * @brief - * - * - * kstate_idle - * | - * kstate_finished ------------------------ - * | | - * kstate_dehumidification_before_disinfection | - * | | - * kstate_preheat <----------------------| - * | - * kstate_disinfection - * | - * kstate_empty_liquid_from_the_line -----| - * | | - * kstate_dehumidification_after_disinfection | - * | | - * kstate_degradation <----| - * | - * kstate_finished - * - */ - - if (sm.getState() == DisinfectionState::idle) { - sm.changeState(DisinfectionState::finished); - } - - // - else if (sm.getState() == DisinfectionState::finished) { - if (PORT.isDrawBarDM()) { - if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dcs->ExtChSelector_isOnline()) { - sm.changeState(DisinfectionState::dehumidificationBeforeDisinfection); - } - } else { - sm.changeState(DisinfectionState::preheat); - } - } - // - else if (sm.getState() == DisinfectionState::dehumidificationBeforeDisinfection) { - sm.changeState(DisinfectionState::preheat); - } - // - else if (sm.getState() == DisinfectionState::preheat) { - sm.changeState(DisinfectionState::disinfection); - } - // - else if (sm.getState() == DisinfectionState::disinfection) { - sm.changeState(DisinfectionState::emptyLiquidFromTheLine); - } - // - else if (sm.getState() == DisinfectionState::emptyLiquidFromTheLine) { - if (PORT.isDrawBarDM()) { - if (getSettingAsBool(SettingId::enable_bd_dehumidify) && dcs->ExtChSelector_isOnline()) { - sm.changeState(DisinfectionState::dehumidificationAfterDisinfection); - } - } else { - sm.changeState(DisinfectionState::degradation); - } - } - // - else if (sm.getState() == DisinfectionState::dehumidificationAfterDisinfection) { - sm.changeState(DisinfectionState::degradation); - } - // - else if (sm.getState() == DisinfectionState::degradation) { - sm.changeState(DisinfectionState::finished); - } -} - -void DisinfectionCtrlService::processStateIdle(DisinfectionEvent* event) { sm.changeState(DisinfectionState::finished); } -void DisinfectionCtrlService::processStateDehumidificationBeforeDisinfection(DisinfectionEvent* event) { - auto h2o2s = dcs->getH2O2SensorMgr(); - if (event->event == kevent_enter_state) { - tryLogState(true); - ZASSERT(PORT.isDrawBarDM()); - - dcs->Blower_ctrl(DEFAULT_BLOWSER_LEVEL); - usleep(100 * 1000); - dcs->ExtChSelector_trySelectCh(kext_ch_dehumidification); - } - // - else if (event->event == kevent_exit_state) { - dcs->Blower_ctrl(0); - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); - tryLogState(true); - } - // - else if (event->event == kevent_tmr_1s) { - int max_humid = h2o2s->getMaxHumid(); - int targetHumid = getSettingAsInt(SettingId::bd_dehumidify_threshold); - - if (max_humid <= targetHumid) { - logger->info("exit dehumidification state, because humidity is lower than target value"); - changeToNextState(); - return; - } else { - logger->info("dehumidification {} > {} ", max_humid, targetHumid); - } - changeToNextState(); - tryLogState(false); - } - - else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); - } -} - -void DisinfectionCtrlService::processStatePreheat(DisinfectionEvent* event) { - if (event->event == kevent_enter_state) { - logger->info("preheat state enter"); - tryLogState(true); - - dcs->Blower_ctrl(90); - usleep(1000 * 1000); - dcs->Heater_ctrl(100); - - } else if (event->event == kevent_exit_state) { - logger->info("preheat state exit"); - - dcs->Blower_ctrl(0); - usleep(1000 * 1000); - dcs->Heater_ctrl(0); - - tryLogState(true); - } else if (event->event == kevent_tmr_1s) { - int preHeatTimeS = getSettingAsInt(SettingId::pre_heat_time_s); - - if (sm.getStateHasPassedTimeMs() > preHeatTimeS * 1000) { - // 退出预热状态,进入消毒状态 - changeToNextState(); - } - tryLogState(false); - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); - } -} - -void DisinfectionCtrlService::processStateDisinfection(DisinfectionEvent* event) { - if (event->event == kevent_enter_state) { - tryLogState(true); - s_isDisinfectionTakeBreak = false; - if (PORT.isPipeDM()) { - dcs->AirLeakDetectTestChannelCtrl_releaseCh(); - } - 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)); - } else if (event->event == kevent_exit_state) { - s_isDisinfectionTakeBreak = false; - dcs->AC_close(); - dcs->Blower_close(); - dcs->Heater_close(); - dcs->SprayPump_stop(); - s_dvalue = 0; - tryLogState(true); - } else if (event->event == kevent_tmr_1s) { - /** - * @brief - * 计算D值 - * 计算消毒时间 - * 打印日志 - */ - - s_dvalue = DValueComputer().computeDValue(gConfig->get_dvalueCoefficient(), s_h2o2Snapshot->minH2O2); - - 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); - traceState(); - } - - s_remaintime--; - if (s_remaintime < 0) s_remaintime = 0; - - if (!s_isDisinfectionTakeBreak) { - if (isTimeToPauseDisinfection()) { - logger->info("pauseDisinfection"); - dcs->SprayPump_stop(); - dcs->AC_close(); - s_isDisinfectionTakeBreak = true; - traceState(); - } - } else { - if (isTimeToResumeDisinfection()) { - logger->info("resumeDisinfection"); - dcs->SprayPump_start(getSettingAsInt(SettingId::injection_pump_speed)); - dcs->AC_ctrl(1); - s_isDisinfectionTakeBreak = false; - traceState(); - } - } - - if (s_remaintime <= 0 && s_nlog > (s_tlog + 0.01)) { - /** - * @brief 消毒结束 - */ - changeToNextState(); - } - tryLogState(false); - - // 检查是否消毒完成 - } else if (event->event == kevent_update_cfg) { - if (!s_isDisinfectionTakeBreak) { - dcs->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()); - - } else if (event->event == kevent_exit_state) { - tryLogState(true); - dcs->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); - } else if (event->event == kevent_exit_state) { - dcs->Blower_close(); - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); - tryLogState(true); - } else if (event->event == kevent_tmr_1s) { - if (!dcs->ExtChSelector_isOnline()) { - logger->error("exit dehumidification state, because extValBoard is offline"); - changeToNextState(); - return; - } - auto maxHumid = s_h2o2Snapshot->maxHumid; - - if (maxHumid <= getSettingAsInt(SettingId::ad_dehumidify_threshold)) { - logger->info("exit dehumidification state, because humidity is lower than target value"); - changeToNextState(); - - return; - } else { - logger->info("dehumidification {} > {} ", maxHumid, getSettingAsInt(SettingId::ad_dehumidify_threshold)); - } - - 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); - } else if (event->event == kevent_exit_state) { - dcs->Blower_close(); - dcs->ExtChSelector_trySelectCh(kext_ch_disinfection); - tryLogState(true); - } else if (event->event == kevent_tmr_1s) { - auto maxH2O2 = s_h2o2Snapshot->maxH2O2; - - logger->info("waitting for h2o2 concentration to safe value {}=>{}", maxH2O2, 1); - if (maxH2O2 < 1) { - logger->info("h2o2 concentration to safe value"); - changeToNextState(); - } - tryLogState(false); - } else if (event->event == kevent_stop) { - sm.changeState(DisinfectionState::finished); - } -} -void DisinfectionCtrlService::processStateFinished(DisinfectionEvent* event) { - if (event->event == kevent_enter_state) { - // if (event->enterState.last != kstate_idle && event->enterState.last != kstate_finished) { - if (event->enterState.last != DisinfectionState::idle && event->enterState.last != DisinfectionState::finished) { - /** - * @brief 消毒结束 - */ - - dcs->SprayPump_stop(); - dcs->AC_ctrl(0); - dcs->Blower_close(); - dcs->Heater_close(); - - s_remaintime = 0; - s_complete_tp = zsystem_clock().now(); - if (PORT.isLageSpaceDM() || PORT.isSmallSpaceDM() || PORT.isPipeDM()) { - s_afterDisinfectantVolume_g = dcs->DisinfectantVolume_readVal(); - } else if (PORT.isDrawBarDM()) { - s_afterDisinfectantVolume_g = 0; - } - - GET_SERVICE(WarningLightControler)->setworkFlag(false); - - // tryLogSatate(true); - tryLogState(true); - 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_service.hpp b/appsrc/service/app/disinfection_ctrl_service.hpp deleted file mode 100644 index 4d13a8e..0000000 --- a/appsrc/service/app/disinfection_ctrl_service.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -// -#include "appbase/disinfection_state.hpp" -#include "baseservice/baseservice.hpp" -#include "disinfection_ctrl/disinfection_state_machine.hpp" -#include "service/hardware/base/h2o2_sensor_data_mgr.hpp" -#include "service/hardware/device_ctrl_service.hpp" -#include "service/hardware/disinfectant_weight_update_service.hpp" -// -namespace iflytop { -using namespace disinfection; - -class DisinfectionCtrlServiceContext { - public: - string id; - zsteady_tp start_steady_tp; - zsystem_tp start_tp; - zsystem_tp complete_tp; - - zsteady_tp last_compute_dvalue_tp; // 上次计算dvalue时间 - zsteady_tp lastlog_tp; // 上次日志时间 - zsteady_tp last_log_printer_data_tp; // 上次日志时间 - int remaintime = 0; - float now_loglevel = 0; - float dvalue = 0; - bool is_disinfection_take_break; // 消毒工作中是否因为RS,RH,PPM过大而暂停工作 - - int beforeDisinfectantVolume_g; // 消毒前消毒剂量 - int afterDisinfectantVolume_g; // 消毒后消毒剂量 -}; - -class DisinfectionCtrlService : public enable_shared_from_this { - THISCLASS(DisinfectionCtrlService); - - public: - shared_ptr db; - shared_ptr ds; - shared_ptr gConfig; - - shared_ptr dcs; - shared_ptr dwus; - - DisinfectionState m_state = DisinfectionState::idle; - - map m_realtimeCfg; - json m_defaultFormulaJson; - string m_formulaid; - - DisinfectionStateMachine sm; - - shared_ptr context; - - // - string s_sessionId; - zsystem_tp s_start_tp; - zsystem_tp s_complete_tp; - zsteady_tp start_steady_tp; - zsteady_tp s_lastTakeSnapt; // 上次日志时间 - zsteady_tp s_lastComputeDvalueTp; // 上次计算dvalue时间 - bool s_isDisinfectionTakeBreak = false; - shared_ptr s_h2o2Snapshot; - int32_t s_dvalue = 0; - int32_t s_remaintime; - float s_nlog; - float s_tlog; - int s_beforeDisinfectantVolume_g; // 消毒前消毒剂量 - int s_afterDisinfectantVolume_g; // 消毒后消毒剂量 - - public: - void initialize(); - - public: - string getSetting(SettingId sid); - int getSettingAsInt(SettingId sid); - bool getSettingAsBool(SettingId sid); - float getSettingAsFloat(SettingId sid); - - static float computeNextLogLevel(float nowloglevel, float dval); - static void updateRemainTime(int dval, float nlog, float tlog, int& remaintime); - bool isTimeToPauseDisinfection(); - bool isTimeToResumeDisinfection(); - - public: - public: - /******************************************************************************* - * 控制 * - *******************************************************************************/ - void fn_start(shared_ptr cxt); - void fn_startWithFormula(shared_ptr cxt); - void fn_stop(shared_ptr cxt); - - void fn_getRealtimeConfig(shared_ptr cxt); - void fn_setRealtimeConfig(shared_ptr cxt); - /******************************************************************************* - * 状态 * - *******************************************************************************/ - void fn_getState(shared_ptr cxt); - void fn_getServiceConfig(shared_ptr cxt); - - public: - // impl - - void start(); - void stop(); - void updateCfg(); - - private: - void beforeStateProcess(); - - void processStateIdle(DisinfectionEvent* event); - void processStatePreheat(DisinfectionEvent* event); - void processStateDisinfection(DisinfectionEvent* event); - void processStateDegradation(DisinfectionEvent* event); - void processStateFinished(DisinfectionEvent* event); - void processStateDehumidificationBeforeDisinfection(DisinfectionEvent* event); - void processStateDehumidificationAfterDisinfection(DisinfectionEvent* event); - void processStateEmpytLiquidFromTheLine(DisinfectionEvent* event); - - void changeToNextState(); - - private: - void tryLogState(bool forceLog); - void logState(); - void traceState(); - void initState(); -}; - -} // namespace iflytop diff --git a/appsrc/service/app/disinfection_ctrl_service_ext.cpp b/appsrc/service/app/disinfection_ctrl_service_ext.cpp new file mode 100644 index 0000000..8f018be --- /dev/null +++ b/appsrc/service/app/disinfection_ctrl_service_ext.cpp @@ -0,0 +1,125 @@ +#include "disinfection_ctrl_service_ext.hpp" + +#include "appcomponents/algo/dvalue_computer.hpp" +#include "service/hardware/warning_light_controler.hpp" +using namespace iflytop; +using namespace disinfection; + +#define DEFAULT_BLOWSER_LEVEL 90 +#define DVALUE_COMPUTEPERIOD_TIME_S (10.0) + +#define SETTING_DB SettingDBDao::ins() +#define FORMULA_DB FormulaDBDao::ins() + +static string toDisplayName(DisinfectionState state) { + switch (state.id) { + case DisinfectionState::kidle: + return "空闲"; + case DisinfectionState::kpreheat: + return "预热"; + case DisinfectionState::kdisinfection: + return "消毒中"; + case DisinfectionState::kdegradation: + return "降解中"; + case DisinfectionState::kfinished: + return "消毒完成"; + case DisinfectionState::kdehumidificationBeforeDisinfection: + return "消毒前除湿"; + case DisinfectionState::kdehumidificationAfterDisinfection: + return "消毒后除湿"; + case DisinfectionState::kemptyLiquidFromTheLine: + return "排空管路"; + default: + return "未知"; + } +} + +void DisinfectionCtrlServiceExt::initialize() { + GET_TO_SERVICE(db); + GET_TO_SERVICE(ds); + GET_TO_SERVICE(gConfig); + GET_TO_SERVICE(dcs); + GET_TO_SERVICE(dwus); + + REGFNV2(DisinfectionCtrlServiceExt, start); + REGFNV2(DisinfectionCtrlServiceExt, startWithFormula); + REGFNV2(DisinfectionCtrlServiceExt, stop); + REGFNV2(DisinfectionCtrlServiceExt, getState); + 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; + } + // + + // 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; +} + +void DisinfectionCtrlServiceExt::fn_getRealtimeConfig(shared_ptr cxt) { + json& rely = cxt->content; + for (auto& cfg : m_realtimeCfg) { + 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; +} + +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"; + + 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; + + rely["h2o2SensorData"] = sensordata; +} + +void DisinfectionCtrlServiceExt::fn_getServiceConfig(shared_ptr cxt) { + json& rely = cxt->content; + rely["curveNum"] = 3; + rely["updatePeriodMs"] = 5000; +} diff --git a/appsrc/service/app/disinfection_ctrl_service_ext.hpp b/appsrc/service/app/disinfection_ctrl_service_ext.hpp new file mode 100644 index 0000000..8fd9193 --- /dev/null +++ b/appsrc/service/app/disinfection_ctrl_service_ext.hpp @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include "appbase/disinfection_state.hpp" +#include "disinfection_ctrl/disinfection_ctrl_service.hpp" +#include "baseservice/baseservice.hpp" +#include "disinfection_ctrl/disinfection_state_machine.hpp" +#include "service/hardware/base/h2o2_sensor_data_mgr.hpp" +#include "service/hardware/device_ctrl_service.hpp" +#include "service/hardware/disinfectant_weight_update_service.hpp" +// +namespace iflytop { +using namespace disinfection; + +class DisinfectionCtrlServiceExt : public enable_shared_from_this { + THISCLASS(DisinfectionCtrlServiceExt); + + public: + shared_ptr db; + shared_ptr ds; + shared_ptr gConfig; + + shared_ptr dcs; + shared_ptr dwus; + + DisinfectionState m_state = DisinfectionState::idle; + + map m_realtimeCfg; + json m_defaultFormulaJson; + string m_formulaid; + + public: + void initialize(); + + public: + /******************************************************************************* + * 控制 * + *******************************************************************************/ + void fn_start(shared_ptr cxt); + void fn_startWithFormula(shared_ptr cxt); + void fn_stop(shared_ptr cxt); + + void fn_getRealtimeConfig(shared_ptr cxt); + void fn_setRealtimeConfig(shared_ptr cxt); + /******************************************************************************* + * 状态 * + *******************************************************************************/ + void fn_getState(shared_ptr cxt); + void fn_getServiceConfig(shared_ptr cxt); + +}; + +} // namespace iflytop diff --git a/appsrc/service/main_control_service.cpp b/appsrc/service/main_control_service.cpp index 3d75d06..b58772c 100644 --- a/appsrc/service/main_control_service.cpp +++ b/appsrc/service/main_control_service.cpp @@ -12,7 +12,7 @@ // #include "service/app/add_liquid_service.hpp" #include "service/app/air_leak_detect_test.hpp" -#include "service/app/disinfection_ctrl_service.hpp" +#include "service/app/disinfection_ctrl_service_ext.hpp" #include "service/app/drain_liquid_service.hpp" #include "service/app/pipeline_pressure_control.hpp" //