Browse Source

提取公共代码

master
zhaohe 1 year ago
parent
commit
dda7e13614
  1. 3
      .gitmodules
  2. 6
      .vscode/c_cpp_properties.json
  3. 4
      CMakeLists.txt
  4. 9
      README.md
  5. 29
      src/configs/gconfig.hpp
  6. 663
      src/db/db_service.cpp
  7. 181
      src/db/db_service.hpp
  8. 54
      src/db/user_behavior_des.cpp
  9. 41
      src/db/user_behavior_des.hpp
  10. 737
      src/main_control_service.cpp
  11. 35
      src/main_control_service.hpp
  12. 133
      src/service/data_export_service.cpp
  13. 60
      src/service/data_export_service.hpp
  14. 0
      src/service/device_state_service.cpp
  15. 63
      src/service/device_state_service.hpp
  16. 679
      src/service/disinfection_ctl_service.cpp
  17. 186
      src/service/disinfection_ctl_service.hpp
  18. 99
      src/service/disinfection_logs_manager.cpp
  19. 48
      src/service/disinfection_logs_manager.hpp
  20. 44
      src/service/iflytop_can_host_device.cpp
  21. 39
      src/service/iflytop_can_host_device.hpp

3
.gitmodules

@ -4,3 +4,6 @@
[submodule "iflytoplinuxsdk"]
path = iflytoplinuxsdk
url = zwsd@192.168.1.3:p_transmit_disinfection/iflytoplinuxsdk_ptdv1.git
[submodule "transmit_disinfection_public_code"]
path = transmit_disinfection_public_code
url = zwsd@192.168.1.3:p_transmit_disinfection/transmit_disinfection_public_code.git

6
.vscode/c_cpp_properties.json

@ -5,13 +5,15 @@
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/src",
"${workspaceFolder}/iflytoplinuxsdk/src/**"
"${workspaceFolder}/transmit_disinfection_public_code/",
"${workspaceFolder}/iflytoplinuxsdk/src/**",
"${workspaceFolder}/libs/libixwebsocket/include"
],
"compilerPath": "/usr/bin/g++",
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
"compileCommands": "build/compile_commands.json"
}
],
"version": 4

4
CMakeLists.txt

@ -45,6 +45,8 @@ file(
VAR_APP_SOURCE #
src/*.cpp #
src/*.c #
transmit_disinfection_public_code/*.cpp #
src/*.c #
iflytoplinuxsdk/src/*.cpp #
iflytoplinuxsdk/src/*.c #
)
@ -67,6 +69,7 @@ zadd_executable(
INCLUDE_DIRECTORIES
src
iflytoplinuxsdk/src/iflytop/core/spdlog/include/
transmit_disinfection_public_code/
iflytoplinuxsdk/src/
libs/libixwebsocket/include
./)
@ -79,6 +82,7 @@ zadd_executable(
SRC
test_src/testsqldb.cpp #
INCLUDE_DIRECTORIES
transmit_disinfection_public_code/
iflytoplinuxsdk/src/iflytop/core/spdlog/include/
iflytoplinuxsdk/src/
LINK_LIBRARIES

9
README.md

@ -23,3 +23,12 @@ sudo apt-get install sqlitebrowser
https://www.sqlite.org/docs.html
```
# 编译指令
```
./init.sh
./build.sh
```

29
src/configs/gconfig.hpp

@ -1,29 +0,0 @@
#pragma once
#include <exception>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "iflytop/core/components/config_template/config_template.hpp"
#define ConfigELEMENT_LIST(marco) \
marco(string /* */, deviceId, "") /*设备ID*/ \
marco(string /* */, iflytopSubDeviceCanIFName, "can0") /*子设备Can设备名称*/ \
marco(int32_t /* */, iflytopSubDeviceCanBitrate, 500000) /*子设备Can设备波特率*/ \
marco(string /* */, pipettingRobotCanIFName, "can1") /*移液臂Can设备名称*/ \
marco(int32_t /* */, pipettingRobotCanBitrate, 500000) /*移液臂Can设备波特率*/ \
marco(float /* */, dvalueCoefficient, 1) /*数值越小,相对消毒时间越长*/ \
marco(float /* */, disinfectantWeightCorrectionFactor, 0.9) /*数值越小,相对消毒时间越长*/
configTemplateDEFILE_CONFIG_SERVICE2( //
GConfig, //
ConfigELEMENT_LIST, //
"./configs/config.json", {});

663
src/db/db_service.cpp

@ -1,663 +0,0 @@
#include <sqlite3.h>
//
#include <stdio.h>
#include <time.h>
#include "db_service.hpp"
//
#include "iflytop/components/sqlite_orm/sqlite_orm.hpp"
using namespace std;
using namespace iflytop;
using namespace iflytop::db;
using namespace sqlite_orm;
using namespace nlohmann;
// 数据库工具使用手册
// auto notJohn = storage.get_all<User>(where(c(&User::firstName) != "John"));
// 主键必须是int,或者不要主键
#define USER_DB_STRUCT \
USER_DB, /**/ \
make_table("users", /**/ \
make_column("id", &User::id, primary_key().autoincrement()), /**/ \
make_column("uid", &User::uid), /**/ \
make_column("passwd", &User::passwd), /**/ \
make_column("permission_level", &User::permission_level), /**/ \
make_column("visible", &User::visible))
#define SETTING_DB_STRUCT \
make_table("settings", /**/ \
make_column("id", &Setting::id, primary_key()), /**/ \
make_column("name", &Setting::name), /**/ \
make_column("name_ch", &Setting::name_ch), /**/ \
make_column("val_lower_limit", &Setting::val_lower_limit), /**/ \
make_column("val_upper_limit", &Setting::val_upper_limit), /**/ \
make_column("permission_level", &Setting::permission_level), /**/ \
make_column("val", &Setting::val))
#define FORMULA_DB_STRUCT \
make_table("formulas", /**/ \
make_column("id", &Formula::id, primary_key()), /**/ \
make_column("loglevel", &Formula::loglevel), /**/ \
make_column("formula_id", &Formula::formula_id), /**/ \
make_column("stoped_gs", &Formula::stoped_gs), /**/ \
make_column("continued_gs", &Formula::continued_gs), /**/ \
make_column("stoped_satur", &Formula::stoped_satur), /**/ \
make_column("continued_satur", &Formula::continued_satur), /**/ \
make_column("stoped_humi", &Formula::stoped_humi), /**/ \
make_column("continued_humi", &Formula::continued_humi), /**/ \
make_column("injection_pump_speed", &Formula::injection_pump_speed))
#define USER_BEHAVIOR_RECORD_STRUCT \
make_table("user_behavior_records", /**/ \
make_column("id", &UserBehaviorRecord::id, primary_key().autoincrement()), /**/ \
make_column("uid", &UserBehaviorRecord::uid), /**/ \
make_column("date", &UserBehaviorRecord::date), /**/ \
make_column("behavior", &UserBehaviorRecord::behavior), /**/ \
make_column("behaviorinfo", &UserBehaviorRecord::behaviorinfo))
DBService::DBService(/* args */) {}
void DBService::initialize() {
/**
* @brief
*/
//
init_usr_db();
init_setting_db();
json settings = getAllSettingJson();
logger->info("settings: {}", settings.dump());
}
void DBService::init_usr_db() {
bool suc = false;
do {
try {
logger->info("init user db");
auto storage = make_storage(USER_DB_STRUCT);
storage.sync_schema();
auto admin = storage.get_all<User>(where(c(&User::uid) == "admin"));
if (admin.size() == 0) {
storage.insert<User>({-1, "admin", "9973", 1, true}); // 管理员
}
auto user = storage.get_all<User>(where(c(&User::uid) == "user"));
if (user.size() == 0) {
storage.insert<User>({-1, "user", "0000", 3, true}); // 普通用户
}
suc = true;
} catch (const std::exception& e) {
logger->error("init user db failed: {}", e.what());
system("rm -rf user.db");
sleep(1);
}
} while (!suc);
}
void DBService::init_setting_db() {
bool suc = false;
#if 0
id setting_name setting_name_ch val_upper_limit val_lower_limit permission_level val
0 stoped_gs 0 2000 1 1000
1 continued_gs 0 2000 1 800
2 stoped_satur 0 100 1 80
3 continued_satur 0 100 1 60
4 max_humidity 湿 0 100 1 90
5 drainage_pump_speed 0 2000 2 500
6 injection_pump_speed 0 2000 2 500
#endif
do {
try {
logger->info("init setting db");
auto storage = make_storage(SETTING_DB, SETTING_DB_STRUCT);
storage.sync_schema();
if (storage.get_all<Setting>(where(c(&Setting::id) == 1)).size() == 0) //
storage.insert(Setting{1, "stoped_gs", "消毒停止过氧化氢溶度", 0, 2000, 0, 1800});
if (storage.get_all<Setting>(where(c(&Setting::id) == 2)).size() == 0)
storage.insert(Setting{2, "continued_gs", "消毒继续过氧化氢溶度", 0, 2000, 0, 1500});
if (storage.get_all<Setting>(where(c(&Setting::id) == 3)).size() == 0)
storage.insert(Setting{3, "stoped_satur", "消毒停止过氧化氢相对饱和度", 0, 100, 0, 85});
if (storage.get_all<Setting>(where(c(&Setting::id) == 4)).size() == 0)
storage.insert(Setting{4, "continued_satur", "消毒继续过氧化氢相对饱和度", 0, 100, 0, 70});
if (storage.get_all<Setting>(where(c(&Setting::id) == 5)).size() == 0) //
storage.insert(Setting{5, "max_humidity", "允许消毒最大湿度", 0, 100, 0, 90});
if (storage.get_all<Setting>(where(c(&Setting::id) == 6)).size() == 0)
storage.insert(Setting{6, "drainage_pump_speed", "排液蠕动泵转速", 0, 90, 0, 90}); // g/min
if (storage.get_all<Setting>(where(c(&Setting::id) == 7)).size() == 0)
storage.insert(Setting{7, "injection_pump_speed", "喷射蠕动泵转速", 0, 50, 0, 50}); // g/min
if (storage.get_all<Setting>(where(c(&Setting::id) == 8)).size() == 0) //
storage.insert(Setting{8, "pre_heat_time_s", "预热时间", 0, 600, 0, 120});
if (storage.get_all<Setting>(where(c(&Setting::id) == 9)).size() == 0) //
storage.insert(Setting{9, "stoped_humi", "消毒停止相对湿度", 0, 100, 0, 85});
if (storage.get_all<Setting>(where(c(&Setting::id) == 10)).size() == 0) //
storage.insert(Setting{10, "continued_humi", "消毒继续相对湿度", 0, 100, 0, 70});
suc = true;
} catch (const std::exception& e) {
logger->error("init setting db failed: {}", e.what());
system("rm -rf setting.db");
sleep(1);
}
} while (!suc);
}
void DBService::init_formula_db() {
bool suc = false;
do {
try {
logger->info("init formula db");
auto storage = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
storage.sync_schema();
suc = true;
} catch (const std::exception& e) {
logger->error("init setting db failed: {}", e.what());
system("rm -rf setting.db");
sleep(1);
}
} while (!suc);
}
list<shared_ptr<User>> DBService::getAllUser() {
lock_guard<recursive_mutex> lock(lock_);
list<shared_ptr<User>> users;
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto all = usertable.get_all<User>();
for (auto& u : all) {
users.push_back(make_shared<User>(u));
}
return users;
}
void DBService::addUser(string uid, string passwd, int permission_level) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
logger->info("add user: {} {} {}", uid, passwd, permission_level);
usertable.insert(User{-1, uid, passwd, permission_level, true});
}
shared_ptr<db::User> DBService::delUser(int id) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
/**
* @brief find admin user
*/
auto admin = usertable.get_all<User>(where(c(&User::uid) == "admin"));
ZCHECK(admin.size() == 1, "admin user not found");
if (admin[0].id == id) {
logger->error("can not delete admin user");
return nullptr;
}
auto remove_user = usertable.get_all<User>(where(c(&User::id) == id));
if (remove_user.size() == 0) {
logger->error("remove user fail, user not found");
return nullptr;
}
logger->info("delete user: {}:{}", id, remove_user[0].uid);
usertable.remove_all<User>(where(c(&User::id) == id));
return make_shared<User>(remove_user[0]);
}
shared_ptr<db::User> DBService::updateUserPermissionLevel(int id, int permission_level) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::id) == id));
if (user.size() == 0) {
logger->error("update user permission level fail, user not found");
return nullptr;
}
logger->info("update user permission level: {} {} -> {}", id, user[0].permission_level, permission_level);
user[0].permission_level = permission_level;
usertable.update(user[0]);
return make_shared<User>(user[0]);
}
shared_ptr<db::User> DBService::changePasswd(string uid, string passwd) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
if (user.size() == 0) {
logger->error("change passwd fail, user not found");
return nullptr;
}
logger->info("change passwd: {} {} -> {}", uid, user[0].passwd, passwd);
user[0].passwd = passwd;
usertable.update(user[0]);
return make_shared<User>(user[0]);
}
shared_ptr<db::User> DBService::updateUserUid(int id, string uid, string& olduid) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::id) == id));
if (user.size() == 0) {
logger->error("change user uid fail, user not found");
return nullptr;
}
olduid = user[0].uid;
logger->info("change user uid: {} {} -> {}", id, user[0].uid, uid);
user[0].uid = uid;
usertable.update(user[0]);
return make_shared<User>(user[0]);
}
json DBService::getAllUserJson() {
lock_guard<recursive_mutex> lock(lock_);
json j_users;
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto all = usertable.get_all<User>();
for (auto& u : all) {
json j_user;
j_user["id"] = u.id;
j_user["uid"] = u.uid;
j_user["passwd"] = u.passwd;
j_user["permission_level"] = u.permission_level;
j_user["visible"] = u.visible;
j_users.push_back(j_user);
}
return j_users;
}
shared_ptr<User> DBService::getUser(string uid) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
if (user.size() == 0) {
return nullptr;
}
return make_shared<User>(user[0]);
}
list<shared_ptr<db::Setting>> DBService::getAllSetting() {
lock_guard<recursive_mutex> lock(lock_);
list<shared_ptr<db::Setting>> settings;
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto all = settingtable.get_all<Setting>();
for (auto& s : all) {
settings.push_back(make_shared<Setting>(s));
}
return settings;
}
json DBService::getAllSettingJson() {
lock_guard<recursive_mutex> lock(lock_);
json j_settings;
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto all = settingtable.get_all<Setting>();
for (auto& s : all) {
json j_setting;
j_setting["id"] = s.id;
j_setting["name"] = s.name;
j_setting["name_ch"] = s.name_ch;
j_setting["val"] = s.val;
j_setting["val_lower_limit"] = s.val_lower_limit;
j_setting["val_upper_limit"] = s.val_upper_limit;
j_setting["permission_level"] = s.permission_level;
j_setting["val"] = s.val;
j_settings.push_back(j_setting);
}
return j_settings;
}
bool DBService::isUserExist(string uid) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
if (user.size() == 0) {
return false;
}
return true;
}
bool DBService::ispasswdCorrect(string uid, string passwd) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
if (user.size() == 0) {
return false;
}
if (user[0].passwd == passwd) {
return true;
}
return false;
}
bool DBService::setSettingVal(int id, int val) {
lock_guard<recursive_mutex> lock(lock_);
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto setting = settingtable.get_all<Setting>(where(c(&Setting::id) == id));
if (setting.size() == 0) {
return false;
}
if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) {
return false;
}
setting[0].val = val;
settingtable.update(setting[0]);
return true;
}
bool DBService::setSettingVal(string setting_name, int val) {
lock_guard<recursive_mutex> lock(lock_);
logger->info("set setting val: {} {}", setting_name, val);
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == setting_name));
if (setting.size() == 0) {
logger->error("set setting val failed: {} not found", setting_name);
return false;
}
if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) {
logger->error("set setting val failed: {} out of range", setting_name);
return false;
}
setting[0].val = val;
Setting s = setting[0];
settingtable.update(s);
settingtable.sync_schema();
return true;
}
int DBService::getSettingVal(string name) {
lock_guard<recursive_mutex> lock(lock_);
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == name));
if (setting.size() == 0) {
return -1;
}
return setting[0].val;
}
list<shared_ptr<db::Formula>> DBService::getAllFormula() {
lock_guard<recursive_mutex> lock(lock_);
list<shared_ptr<db::Formula>> formulas;
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto all = formulatable.get_all<Formula>();
for (auto& f : all) {
formulas.push_back(make_shared<Formula>(f));
}
return formulas;
}
shared_ptr<db::Formula> DBService::getFormula(int id) {
lock_guard<recursive_mutex> lock(lock_);
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(where(c(&Formula::id) == id));
if (formula.size() == 0) {
return nullptr;
}
return make_shared<Formula>(formula[0]);
}
json DBService::getAllFormulaJson() {
lock_guard<recursive_mutex> lock(lock_);
json j_formulas;
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto all = formulatable.get_all<Formula>();
for (auto& f : all) {
json j_formula;
j_formula["id"] = f.id;
j_formula["loglevel"] = f.loglevel;
j_formula["formula_id"] = f.formula_id;
j_formula["stoped_gs"] = f.stoped_gs;
j_formula["continued_gs"] = f.continued_gs;
j_formula["stoped_satur"] = f.stoped_satur;
j_formula["continued_satur"] = f.continued_satur;
j_formula["stoped_humi"] = f.stoped_humi;
j_formula["continued_humi"] = f.continued_humi;
j_formula["injection_pump_speed"] = f.injection_pump_speed;
j_formulas.push_back(j_formula);
}
json jret;
jret["formulas"] = j_formulas;
jret["settings"] = getAllSettingJson();
return jret;
}
void DBService::addFormula(string formula_id, string loglevel, string stoped_gs, string continued_gs, string stoped_satur, string continued_satur,
string stoped_humi, string continued_humi, string injection_pump_speed) {
lock_guard<recursive_mutex> lock(lock_);
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
Formula f;
f.loglevel = loglevel;
f.formula_id = formula_id;
f.stoped_gs = stoped_gs;
f.continued_gs = continued_gs;
f.stoped_satur = stoped_satur;
f.continued_satur = continued_satur;
f.stoped_humi = stoped_humi;
f.continued_humi = continued_humi;
f.injection_pump_speed = injection_pump_speed;
formulatable.insert(f);
formulatable.sync_schema();
}
void DBService::addFormula(string formula_id, int loglevel, int stoped_gs, int continued_gs, int stoped_satur, int continued_satur, int stoped_humi,
int continued_humi, int injection_pump_speed) {
addFormula(formula_id, to_string(loglevel), to_string(stoped_gs), to_string(continued_gs), to_string(stoped_satur), to_string(continued_satur),
to_string(stoped_humi), to_string(continued_humi), to_string(injection_pump_speed));
}
shared_ptr<db::Formula> DBService::delFormula(int id) {
lock_guard<recursive_mutex> lock(lock_);
// remove_all
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(where(c(&Formula::id) == id));
formulatable.remove_all<Formula>(where(c(&Formula::id) == id));
formulatable.sync_schema();
if (formula.size() == 0) {
return nullptr;
}
return make_shared<Formula>(formula[0]);
}
shared_ptr<db::Formula> DBService::updateFormula(shared_ptr<db::Formula> var_formula) {
lock_guard<recursive_mutex> lock(lock_);
if (var_formula == nullptr) {
return nullptr;
}
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(where(c(&Formula::id) == var_formula->id));
if (formula.size() == 0) {
return nullptr;
}
formulatable.update(*var_formula);
formulatable.sync_schema();
return var_formula;
}
shared_ptr<db::Formula> DBService::updateFormula(int id, string column, string val) {
lock_guard<recursive_mutex> lock(lock_);
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(where(c(&Formula::id) == id));
if (formula.size() == 0) {
return nullptr;
}
if (column == "formula_id") {
formula[0].formula_id = val;
} else if (column == "loglevel") {
formula[0].loglevel = val;
} else if (column == "stoped_gs") {
formula[0].stoped_gs = val;
} else if (column == "continued_gs") {
formula[0].continued_gs = val;
} else if (column == "stoped_satur") {
formula[0].stoped_satur = val;
} else if (column == "continued_satur") {
formula[0].continued_satur = val;
} else if (column == "stoped_humi") {
formula[0].stoped_humi = val;
} else if (column == "continued_humi") {
formula[0].continued_humi = val;
} else if (column == "injection_pump_speed") {
formula[0].injection_pump_speed = val;
}
formulatable.update(formula[0]);
formulatable.sync_schema();
return make_shared<Formula>(formula[0]);
}
int DBService::getUserBehaviorRecordCount() {
lock_guard<recursive_mutex> lock(lock_);
auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT);
user_behavior_record_table.sync_schema();
return user_behavior_record_table.count<UserBehaviorRecord>(where(c(&UserBehaviorRecord::id) > 0));
}
int DBService::getUserBehaviorRecordTheFirstId() {
lock_guard<recursive_mutex> lock(lock_);
auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT);
user_behavior_record_table.sync_schema();
auto all = user_behavior_record_table.get_all<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).asc());
if (all.size() == 0) {
return -1;
}
return all[0].id;
}
list<shared_ptr<db::UserBehaviorRecord>> DBService::getAllUserBehaviorRecord() {
lock_guard<recursive_mutex> lock(lock_);
auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT);
user_behavior_record_table.sync_schema();
auto all = user_behavior_record_table.get_all<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).desc());
list<shared_ptr<db::UserBehaviorRecord>> user_behavior_records;
for (auto& u : all) {
user_behavior_records.push_back(make_shared<UserBehaviorRecord>(u));
}
return user_behavior_records;
}
json DBService::getUserBehaviorRecordDescJson(int page, int page_size) {
lock_guard<recursive_mutex> lock(lock_);
json j_user_behavior_records;
auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT);
user_behavior_record_table.sync_schema();
auto all = user_behavior_record_table.get_all<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).desc());
int i = 0;
int from = page * page_size;
int to = (page + 1) * page_size;
for (auto& u : all) {
if (i >= from && i < to) {
json j_user_behavior_record;
j_user_behavior_record["id"] = u.id;
j_user_behavior_record["uid"] = u.uid;
j_user_behavior_record["behavior"] = u.behavior;
j_user_behavior_record["behaviorZH"] = user_behavior_to_str((user_behavior_t)u.behavior);
j_user_behavior_record["behaviorinfo"] = u.behaviorinfo;
j_user_behavior_record["date"] = u.date;
j_user_behavior_records["iterms"].push_back(j_user_behavior_record);
} else if (i >= to) {
break;
}
i++;
}
j_user_behavior_records["total"] = all.size();
j_user_behavior_records["page"] = page;
j_user_behavior_records["totalpage"] = all.size() / page_size + (all.size() % page_size == 0 ? 0 : 1);
return j_user_behavior_records;
}
static string getTime() {
struct tm tm = {0};
time_t t = ::time(nullptr);
struct tm* tmp = localtime_r(&t, &tm);
return fmt::format("{:0>4}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", tm.tm_year + 1900, //
tm.tm_mon + 1, //
tm.tm_mday, //
tm.tm_hour, //
tm.tm_min, tm.tm_sec);
}
void DBService::addUserBehaviorRecord(string uid, int behavior, string behaviorinfo) {
lock_guard<recursive_mutex> lock(lock_);
auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT);
user_behavior_record_table.sync_schema();
UserBehaviorRecord u;
u.uid = uid;
u.behavior = behavior;
u.behaviorinfo = behaviorinfo;
u.date = getTime();
user_behavior_record_table.insert(u);
user_behavior_record_table.sync_schema();
auto all = user_behavior_record_table.get_all<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).asc());
/**
* @brief 5000
*/
if (all.size() > USER_BEHAVIOR_RECORD_DB_MAX_RECORDS) {
user_behavior_record_table.remove_all<UserBehaviorRecord>(where(c(&UserBehaviorRecord::id) == all[0].id));
user_behavior_record_table.sync_schema();
}
return;
}
void DBService::cleanUserBehaviorRecord() {
lock_guard<recursive_mutex> lock(lock_);
system(fmt::format("rm -rf {}", USER_BEHAVIOR_RECORD_DB).c_str());
}

181
src/db/db_service.hpp

@ -1,181 +0,0 @@
#pragma once
#include <sqlite3.h>
#include <stdio.h>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "iflytop/core/spdlogfactory/logger.hpp"
#include "iflytop/core/thread/thread.hpp"
#include "user_behavior_des.hpp"
#define USER_DB "user.db"
#define SETTING_DB "setting.db"
#define DISINFECTION_RECORD_DB "disinfection_record.db"
#define FORMULA_DB "formula.db"
#define USER_BEHAVIOR_RECORD_DB "user_behavior_record.db"
#define USER_BEHAVIOR_RECORD_DB_MAX_RECORDS 30000
/**
* @brief
*
* USER_DB
* table: user
* id uid passwd permission_level
*
*
* SETTING_DB
* table: setting
* id setting_name setting_name_ch val_upper_limit val_lower_limit permission_level val
*
* DISINFECTION_RECORD_DB
* table: disinfection_record
* id uuid uid date loglevel duration
*
*
* table: sensor_record
* id disinfection_id date heating_strip air_compressor sprinkler_pump disinfectant_volume h2o2_1 temp_1 humid_1 saturation_1 h2o2_2 temp_2 humid_2
* saturation_2 h2o2_3 temp_3 humid_3 saturation_3
*
*/
namespace iflytop {
using namespace std;
using namespace std;
using namespace core;
using namespace nlohmann;
namespace db {
struct User {
public:
int id;
string uid;
string passwd;
int permission_level;
int visible;
};
struct Setting {
public:
int id;
string name;
string name_ch;
int val_lower_limit;
int val_upper_limit;
int permission_level;
int val;
};
struct Formula {
public:
int id;
string loglevel;
string formula_id;
string stoped_gs;
string continued_gs;
string stoped_satur;
string continued_satur;
string stoped_humi;
string continued_humi;
string injection_pump_speed;
};
struct UserBehaviorRecord {
int id;
string uid;
string date;
int behavior;
string behaviorinfo;
};
} // namespace db
using namespace db;
class DBService : public enable_shared_from_this<DBService> {
ENABLE_LOGGER(DBService);
recursive_mutex lock_;
public:
DBService();
void initialize();
public:
/*******************************************************************************
* USER_DB *
*******************************************************************************/
list<shared_ptr<db::User>> getAllUser();
json getAllUserJson();
shared_ptr<db::User> getUser(string uid);
vector<string> getUserNames();
bool isUserExist(string uid);
bool ispasswdCorrect(string uid, string passwd);
/**
* @brief
*
* @param uid
* @param passwd
* @param permission_level ,0 3
*/
void addUser(string uid, string passwd, int permission_level);
shared_ptr<db::User> delUser(int id);
shared_ptr<db::User> updateUserPermissionLevel(int id, int permission_level);
shared_ptr<db::User> changePasswd(string uid, string passwd);
shared_ptr<db::User> updateUserUid(int id, string uid, string& olduid);
public:
/*******************************************************************************
* SETTING_DB *
*******************************************************************************/
list<shared_ptr<db::Setting>> getAllSetting();
json getAllSettingJson();
bool setSettingVal(int id, int val);
bool setSettingVal(string name, int val);
int getSettingVal(string name);
public:
/*******************************************************************************
* Formula *
*******************************************************************************/
list<shared_ptr<db::Formula>> getAllFormula();
json getAllFormulaJson();
void addFormula(string formula_id, string loglevel, string stoped_gs, string continued_gs, string stoped_satur, string continued_satur, string stoped_humi,
string continued_humi, string injection_pump_speed);
void addFormula(string formula_id, int loglevel, int stoped_gs, int continued_gs, int stoped_satur, int continued_satur, int stoped_humi, int continued_humi,
int injection_pump_speed);
shared_ptr<db::Formula> delFormula(int id);
shared_ptr<db::Formula> updateFormula(int id, string column, string val);
shared_ptr<db::Formula> updateFormula(shared_ptr<db::Formula> formula);
shared_ptr<db::Formula> getFormula(int id);
/*******************************************************************************
* UserBehaviorRecord *
*******************************************************************************/
list<shared_ptr<db::UserBehaviorRecord>> getAllUserBehaviorRecord();
int getUserBehaviorRecordCount();
int getUserBehaviorRecordTheFirstId();
json getUserBehaviorRecordDescJson(int page, int page_size);
void addUserBehaviorRecord(string uid, int behavior, string behaviorinfo);
void cleanUserBehaviorRecord();
private:
void init_usr_db();
void init_setting_db();
void init_formula_db();
};
}; // namespace iflytop

54
src/db/user_behavior_des.cpp

@ -1,54 +0,0 @@
#include "user_behavior_des.hpp"
using namespace iflytop;
using namespace iflytop::db;
namespace iflytop {
namespace db {
string user_behavior_to_str(user_behavior_t behavior) {
switch (behavior) {
case kbehavior_login:
return "登陆";
case kbehavior_logout:
return "登出";
case kbehavior_add_user:
return "添加用户";
case kbehavior_del_user:
return "删除用户";
case kbehavior_update_user_permission_level:
return "更新用户权限";
case kbehavior_update_user_passwd:
return "更新用户密码";
case kbehavior_update_user_uid:
return "更新用户ID";
case kbehavior_set_setting_val:
return "设置参数";
case kbehavior_add_formula:
return "添加配方";
case kbehavior_del_formula:
return "删除配方";
case kbehavior_update_formula:
return "更新配方";
case kbehavior_update_formula_name:
return "更新配方名称";
case kbehavior_do_disinfection:
return "开始消毒";
case kbehavior_stop_disinfection:
return "停止消毒";
case kbehavior_do_formula:
return "执行配方";
case kbehavior_update_setting_val_on_disinfection:
return "消毒中更新参数";
case kbehavior_export_disinfection_data:
return "导出消毒数据";
case kbehavior_export_user_action_data:
return "导出用户操作数据";
default:
break;
}
return "未知行为";
}
} // namespace db
} // namespace iflytop

41
src/db/user_behavior_des.hpp

@ -1,41 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
namespace iflytop {
using namespace std;
namespace db {
typedef enum {
kbehavior_login = 0,
kbehavior_logout = 1,
kbehavior_add_user = 2,
kbehavior_del_user = 3,
kbehavior_update_user_uid = 5,
kbehavior_update_user_permission_level = 6,
kbehavior_update_user_passwd = 7,
kbehavior_set_setting_val = 8,
kbehavior_add_formula = 9,
kbehavior_del_formula = 10,
kbehavior_update_formula = 11,
kbehavior_do_disinfection = 12,
kbehavior_stop_disinfection = 13,
kbehavior_do_formula = 14,
kbehavior_update_setting_val_on_disinfection = 15,
kbehavior_export_disinfection_data = 16,
kbehavior_export_user_action_data = 17,
kbehavior_update_formula_name = 18,
} user_behavior_t;
string user_behavior_to_str(user_behavior_t behavior);
} // namespace db
} // namespace iflytop

737
src/main_control_service.cpp

@ -10,30 +10,11 @@ using namespace iflytop;
using namespace core;
using namespace std;
using namespace nlohmann;
#define BIND
namespace iflytop {
extern bool g_in_test;
};
static void getJsonValFromJson(json j, int& val) {
if (j.is_string()) {
string valstr = j;
val = atoi(valstr.c_str());
} else if (j.is_number()) {
val = j;
} else {
throw std::runtime_error("getJsonValFromJson(int) error");
}
}
template <typename T>
static T jsonGet(json j) {
T val;
getJsonValFromJson(j, val);
return val;
}
void MainControlService::dosystem(string order) {
logger->info("do:{}", order);
system(order.c_str());
@ -41,10 +22,6 @@ void MainControlService::dosystem(string order) {
void MainControlService::initialize() {
GET_TO_SERVICE(m_zconfig);
// system("systemctl restart zchromium.service");
// m_dbService.reset(new DBService());
// m_dbService->initialize();
BUILD_AND_REG_SERRVICE(DBService);
GET_SERVICE(DBService)->initialize();
@ -81,6 +58,26 @@ void MainControlService::initialize() {
GET_SERVICE(DataExportService)->initialize();
GET_TO_SERVICE(m_dataExportService);
BUILD_AND_REG_SERRVICE(FrontMsgProcesser);
GET_SERVICE(FrontMsgProcesser)->initialize();
GET_TO_SERVICE(m_frontMsgProcesser);
BUILD_AND_REG_SERRVICE(DeviceStateCmdImpl);
BUILD_AND_REG_SERRVICE(DisinfectionCmdImpl);
BUILD_AND_REG_SERRVICE(RecordMgrCmdImpl);
BUILD_AND_REG_SERRVICE(SettingPageCmdImpl);
BUILD_AND_REG_SERRVICE(SystemOperateCmdImpl);
BUILD_AND_REG_SERRVICE(TestPageCmdImpl);
BUILD_AND_REG_SERRVICE(UserCmdImpl);
GET_SERVICE(DeviceStateCmdImpl)->initialize();
GET_SERVICE(DisinfectionCmdImpl)->initialize();
GET_SERVICE(RecordMgrCmdImpl)->initialize();
GET_SERVICE(SettingPageCmdImpl)->initialize();
GET_SERVICE(SystemOperateCmdImpl)->initialize();
GET_SERVICE(TestPageCmdImpl)->initialize();
GET_SERVICE(UserCmdImpl)->initialize();
/**
* @brief Get the to service object
*/
@ -88,12 +85,6 @@ void MainControlService::initialize() {
m_disinfectionCtrlService.reset(new DisinfectionCtrlService());
m_disinfectionCtrlService->initialize();
m_restfulServer.reset(new RestfulServer());
m_restfulServer->regAPI("/hello_world", RESTFUL_SERVER_BIND(MainControlService::hello_world));
m_restfulServer->regAPI("/api1/script_processer/doscript", RESTFUL_SERVER_BIND(MainControlService::doscript));
m_restfulServer->regAPI("/api1/script_processer/stopscript", RESTFUL_SERVER_BIND(MainControlService::stopscript));
m_restfulServer->start(20000, 20001, "0.0.0.0");
m_iflytopwsService.reset(new IflytopFrontEndService());
m_iflytopwsService->initialize("0.0.0.0");
m_iflytopwsService->onMessage.connect([this](weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
@ -101,696 +92,10 @@ void MainControlService::initialize() {
if (cmdstr != "getState") {
logger->info("rx:{}", cmd.dump());
}
processFrontEndMessage(webSocket, cmd, receipt);
m_frontMsgProcesser->processMsg(cmd, receipt);
if (cmdstr != "getState") {
logger->info("tx:{}", receipt.dump());
}
});
m_iflytopwsService->onUdpCmdMessage.connect([this](struct sockaddr_in* from, char* data, size_t len) {
//
for (size_t i = 0; i < len; i++) {
if (data[i] == '\r' || data[i] == '\n') {
data[i] = '\0';
}
}
bool execsuc = false;
for (size_t i = 0; i < len; i++) {
if (data[i] != '\0') {
int inext = strlen(&data[i]) + i;
{
string retmsg;
execsuc = m_zcanhost->execcmd(string(&data[i]), retmsg);
string retmsgstr = fmt::format("{},{}", execsuc ? "suc" : "fail", retmsg);
m_iflytopwsService->sendToUDP(from, retmsgstr.c_str(), retmsgstr.size());
}
i = inext;
if (!execsuc) {
break;
}
}
}
});
m_iflytopwsService->startListen();
m_reportThread.reset(new Thread("reportThread", [this]() {
ThisThread thisThread;
while (!thisThread.getExitFlag()) {
json report;
report["command"] = "RealtimeSensorDataReport";
report["sensor_data"] = createSensorDataJson();
m_iflytopwsService->sendReport(report);
thisThread.sleepForMs(1000);
}
}));
};
json MainControlService::createSensorDataJson() {
json report;
report["airCompressor"]["io1"] = m_deviceIoControlService->airCompressor_getio1();
report["airCompressor"]["io2"] = m_deviceIoControlService->airCompressor_getio2();
report["airCompressor"]["currentVal"] = m_deviceIoControlService->airCompressor_getcurrentValue();
report["airBlower"]["io1"] = m_deviceIoControlService->airBlower_getio1();
report["airBlower"]["io2"] = m_deviceIoControlService->airBlower_getio2();
report["airBlower"]["currentVal"] = m_deviceIoControlService->airBlower_getcurrentValue();
report["heatingStrip"]["io1"] = m_deviceIoControlService->heatingStrip_getio1();
report["heatingStrip"]["io2"] = m_deviceIoControlService->heatingStrip_getio2();
report["heatingStrip"]["currentVal"] = m_deviceIoControlService->heatingStrip_getcurrentValue();
report["sprinklerPumpRPM"] = m_deviceIoControlService->sprayLiquidPump_getRPM();
report["chargingPumpRPM"] = m_deviceIoControlService->getChargingPump_PumpRPM();
report["sprinklerPumpGPM"] = m_deviceIoControlService->sprayLiquidPump_getGPM();
// report["chargingPumpGPM"] = m_deviceIoControlService->getChargingPump_PumpGPM();
report["waterImmersionSensor1"] = m_deviceIoControlService->getWaterImmersionSensor1();
report["waterImmersionSensor2"] = m_deviceIoControlService->getWaterImmersionSensor2();
// Water immersion sensor
report["disinfectant_volume"] = m_deviceIoControlService->getDisinfectantVolume_g();
// report["h2o2_1"] = m_deviceIoControlService->getH2O2SenSorData1().h2o2;
report["h2o2_1"] = m_deviceIoControlService->getH2O2SenSorData1().h2o2;
report["temp_1"] = m_deviceIoControlService->getH2O2SenSorData1().temp;
report["humid_1"] = m_deviceIoControlService->getH2O2SenSorData1().humid;
report["saturation_1"] = m_deviceIoControlService->getH2O2SenSorData1().saturation + 1; // 为了让曲线不重叠
// logger->info("m_deviceIoControlService->getH2O2SenSorData1().h2o2 {}", m_deviceIoControlService->getH2O2SenSorData1().h2o2);
report["h2o2_2"] = -1;
report["temp_2"] = -1;
report["humid_2"] = -1;
report["saturation_2"] = -1;
report["h2o2_3"] = -1;
report["temp_3"] = -1;
report["humid_3"] = -1;
report["saturation_3"] = -1;
return report;
}
// {"command":"startReplenishingFluids","messageId":"startReplenishingFluids","stopAt":123}
void MainControlService::processFrontEndMessage_userOperate(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
/*******************************************************************************
* LOGIN_CMD *
*******************************************************************************/
if (cmdstr == "login") {
string uid = cmd["userid"];
string pwd = cmd["passwd"];
if (uid == "admin" && pwd == "iflytop9973") {
m_deviceStateService->setLoginState("admin", 0, 1);
logger->info("user {} login success", "admin");
} else {
if (!m_dbService->isUserExist(uid)) {
receipt["ackcode"] = err::zecode(err::kuser_not_exist);
receipt["ackcodeInfo"] = err::zecode2str(err::kuser_not_exist);
return;
}
if (!m_dbService->ispasswdCorrect(uid, pwd)) {
receipt["ackcode"] = err::zecode(err::kpasswd_error);
receipt["ackcodeInfo"] = err::zecode2str(err::kpasswd_error);
return;
}
m_deviceStateService->setLoginState(uid, m_dbService->getUser(uid)->permission_level, m_dbService->getUser(uid)->visible);
m_dbService->addUserBehaviorRecord(uid, kbehavior_login, "");
logger->info("user {} login success", uid);
}
return;
}
/*******************************************************************************
* unlogin *
*******************************************************************************/
if (cmdstr == "unlogin") {
string loginuid = m_deviceStateService->getLoginUid();
m_deviceStateService->unlogin();
logger->info("user unlogin success");
m_dbService->addUserBehaviorRecord(loginuid, kbehavior_logout, "");
return;
}
/*******************************************************************************
* chpasswd *
*******************************************************************************/
if (cmdstr == "chpasswd") {
string uid = cmd["userId"];
string newpasswd = cmd["newpasswd"];
string passwd = cmd["passwd"];
logger->info("changet passwd {} {}", uid, passwd);
if (!m_dbService->isUserExist(uid)) {
receipt["ackcode"] = err::zecode(err::kuser_not_exist);
receipt["ackcodeInfo"] = err::zecode2str(err::kuser_not_exist);
return;
}
if (!m_dbService->ispasswdCorrect(uid, passwd)) {
receipt["ackcode"] = err::zecode(err::kpasswd_error);
receipt["ackcodeInfo"] = err::zecode2str(err::kpasswd_error);
return;
}
auto user = m_dbService->changePasswd(uid, newpasswd);
// kbehavior_update_user_passwd
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_update_user_passwd, fmt::format("({})", uid));
return;
}
if (cmdstr == "addUser") {
string uid = cmd["uid"];
string passwd = cmd["passwd"];
int permission_level = jsonGet<int>(cmd["permission_level"]);
m_dbService->addUser(uid, passwd, permission_level);
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_add_user, fmt::format("({})", uid));
return;
}
if (cmdstr == "delUser") {
int id = jsonGet<int>(cmd["id"]);
auto user = m_dbService->delUser(id);
if (!user) {
receipt["ackcode"] = err::zecode(err::kuser_not_exist);
receipt["ackcodeInfo"] = err::zecode2str(err::kuser_not_exist);
return;
}
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_del_user, fmt::format("({})", user->uid));
return;
}
if (cmdstr == "updateUserPermissionLevel") {
int id = jsonGet<int>(cmd["id"]);
int permission_level = jsonGet<int>(cmd["permission_level"]);
auto user = m_dbService->updateUserPermissionLevel(id, permission_level);
if (!user) {
receipt["ackcode"] = err::zecode(err::kuser_not_exist);
receipt["ackcodeInfo"] = err::zecode2str(err::kuser_not_exist);
return;
}
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_update_user_permission_level,
fmt::format("({},{})", user->uid, permission_level));
return;
}
if (cmdstr == "updateUserUid") {
int id = jsonGet<int>(cmd["id"]);
string uid = cmd["uid"];
string olduid;
auto user = m_dbService->updateUserUid(id, uid, olduid);
if (!user) {
receipt["ackcode"] = err::zecode(err::kuser_not_exist);
receipt["ackcodeInfo"] = err::zecode2str(err::kuser_not_exist);
return;
}
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_update_user_uid, fmt::format("({}->{})", olduid, uid));
}
if (cmdstr == "getAllUser") {
auto users = m_dbService->getAllUserJson();
receipt["dbval"] = users;
return;
}
}
void MainControlService::processFrontEndMessage_systemOperate(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
/*******************************************************************************
* shutdown *
*******************************************************************************/
if (cmdstr == "shutdown") {
int delayms = jsonGet<int>(cmd["delayms"]);
logger->info("shutdown {} ms", delayms);
m_autoshutdownThread.reset(new Thread("autoShutdown", [delayms, this]() {
ThisThread thisThread;
thisThread.sleepForMs(delayms);
dosystem("shutdown -h now");
}));
return;
}
if (cmdstr == "updateDate") {
#if 0
{
"command":"updateDate",
"messageId":"1111222333444555",
"year":2023,
"month":8,
"day":25,
}
#endif
int32_t year = jsonGet<int>(cmd["year"]);
int32_t month = jsonGet<int>(cmd["month"]);
int32_t day = jsonGet<int>(cmd["day"]);
logger->info("updateDate {} {} {}", year, month, day);
// date -s "2023-01-02 02:32:32"
dosystem(fmt::format("date -s \"{}{:02}{:02} `date +%T`\"", year, month, day).c_str());
dosystem(fmt::format("hwclock -w").c_str());
return;
}
if (cmdstr == "updateTime") {
#if 0
{
"command":"updateTime",
"messageId":"1111222333444555",
"hour":11,
"min":12,
"second":13,
}
#endif
int32_t hour = jsonGet<int>(cmd["hour"]);
int32_t min = jsonGet<int>(cmd["min"]);
int32_t second = jsonGet<int>(cmd["second"]);
logger->info("updateDate {}:{}:{}", hour, min, second);
// date -s "2023-01-02 02:32:32"
dosystem(fmt::format("date -s \"`date +%Y-%m-%d` {:02}:{:02}:{:02}\"", hour, min, second).c_str());
dosystem(fmt::format("hwclock -w").c_str());
return;
}
}
void MainControlService::processFrontEndMessage_Disinfection(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
/*******************************************************************************
* *
*******************************************************************************/
string cmdstr = cmd["command"];
if (cmdstr == "startDisinfection") {
m_disinfectionCtrlService->startDisinfection(jsonGet<int>(cmd["loglevel"]), //
m_dbService->getSettingVal("injection_pump_speed"), //
m_dbService->getSettingVal("stoped_gs"), //
m_dbService->getSettingVal("continued_gs"), //
m_dbService->getSettingVal("stoped_satur"), //
m_dbService->getSettingVal("continued_satur"), //
m_dbService->getSettingVal("stoped_humi"), //
m_dbService->getSettingVal("continued_humi"));
// kbehavior_do_disinfection
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_do_disinfection, fmt::format("({})", jsonGet<int>(cmd["loglevel"])));
return;
}
if (cmdstr == "changeDisinfectionParameter") {
int injection_pump_speed = m_disinfectionCtrlService->m_context.injection_pump_speed;
int stoped_gs = m_disinfectionCtrlService->m_context.stoped_gs;
int continued_gs = m_disinfectionCtrlService->m_context.continued_gs;
int stoped_satur = m_disinfectionCtrlService->m_context.stoped_satur;
int continued_satur = m_disinfectionCtrlService->m_context.continued_satur;
int stoped_humi = m_disinfectionCtrlService->m_context.stoped_humi;
int continued_humi = m_disinfectionCtrlService->m_context.continued_humi;
if (cmd.find("injection_pump_speed") != cmd.end()) {
injection_pump_speed = jsonGet<int>(cmd["injection_pump_speed"]);
}
if (cmd.find("stoped_gs") != cmd.end()) {
stoped_gs = jsonGet<int>(cmd["stoped_gs"]);
}
if (cmd.find("continued_gs") != cmd.end()) {
continued_gs = jsonGet<int>(cmd["continued_gs"]);
}
if (cmd.find("stoped_satur") != cmd.end()) {
stoped_satur = jsonGet<int>(cmd["stoped_satur"]);
}
if (cmd.find("continued_satur") != cmd.end()) {
continued_satur = jsonGet<int>(cmd["continued_satur"]);
}
if (cmd.find("stoped_humi") != cmd.end()) {
stoped_humi = jsonGet<int>(cmd["stoped_humi"]);
}
if (cmd.find("continued_humi") != cmd.end()) {
continued_humi = jsonGet<int>(cmd["continued_humi"]);
}
m_disinfectionCtrlService->changeDisinfectionParameter(injection_pump_speed, stoped_gs, continued_gs, stoped_satur, continued_satur, stoped_humi,
continued_humi);
return;
}
if (cmdstr == "stopDisinfection") {
m_disinfectionCtrlService->stopDisinfection();
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_stop_disinfection, "");
return;
}
if (cmdstr == "startReplenishingFluids") {
int16_t stopAt = jsonGet<int>(cmd["stopAt"]);
logger->info("startReplenishingFluids {}", stopAt);
m_disinfectionCtrlService->startReplenishingFluids(stopAt);
return;
}
if (cmdstr == "stopReplenishingFluids") {
logger->info("stopReplenishingFluids");
m_disinfectionCtrlService->stopReplenishingFluids();
return;
}
if (cmdstr == "startDraining") {
logger->info("startDraining");
m_disinfectionCtrlService->startDraining();
return;
}
if (cmdstr == "stopDraining") {
logger->info("stopDraining");
m_disinfectionCtrlService->stopDraining();
return;
}
}
void MainControlService::processFrontEndMessage_test(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
if (cmdstr == "test_sprayLiquidPumpCtrl") {
int ctrl = jsonGet<int>(cmd["ctrl"]);
int speed = jsonGet<int>(cmd["speed"]);
if (ctrl == 1) {
m_deviceIoControlService->sprayLiquidPump_open_for_test(speed);
} else if (ctrl == -1) {
m_deviceIoControlService->sprayLiquidPump_open_for_test(-speed);
} else {
m_deviceIoControlService->sprayLiquidPump_close();
}
return;
}
if (cmdstr == "test_replenishingFluidsPumpCtrl") {
int ctrl = jsonGet<int>(cmd["ctrl"]);
int speed = jsonGet<int>(cmd["speed"]);
if (ctrl == 1) {
m_deviceIoControlService->replenishingFluidsPump_open_for_test(speed);
} else if (ctrl == -1) {
m_deviceIoControlService->replenishingFluidsPump_open_for_test(-speed);
} else {
m_deviceIoControlService->replenishingFluidsPump_close_for_test();
}
return;
}
/*******************************************************************************
* *
*******************************************************************************/
// {
// "command":"exceCanCmd",
// "cancmd": "",
// }
if (cmdstr == "exceCanCmd") {
string cancmd = cmd["cancmd"];
logger->info("exceCanCmd {}", cancmd);
string receipt_str;
bool suc = m_zcanhost->execcmd(cancmd, receipt_str);
receipt["receipt_str"] = receipt_str;
if (!suc) {
receipt["ackcode"] = err::zecode(err::kfail);
}
return;
}
if (cmdstr == "disinfectionLogsGetList") {
receipt["disinfectionLogList"] = m_disinfectionLogsManager->getLoggerList();
return;
}
if (cmdstr == "disinfectionLogsGetRecord") {
string loggerName = cmd["disinfectionLogName"];
receipt["record"] = m_disinfectionLogsManager->getlogger(loggerName);
return;
}
}
void MainControlService::processFrontEndMessage_exportData(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
if (cmdstr == "exportUserBehaviorRecord") {
auto errcode = m_dataExportService->exportAuditData();
if (errcode != err::ksucc) {
receipt["ackcode"] = err::zecode(errcode);
receipt["ackcodeInfo"] = err::zecode2str(errcode);
return;
}
}
if (cmdstr == "exportDisinfectionRecord") {
auto errcode = m_dataExportService->exportDisinfectionData();
if (errcode != err::ksucc) {
receipt["ackcode"] = err::zecode(errcode);
receipt["ackcodeInfo"] = err::zecode2str(errcode);
return;
}
}
if (cmdstr == "cleanDisinfectionRecord") {
dosystem("rm -rf /app/disinfection_logs/*");
}
if (cmdstr == "cleanUserBehaviorRecord") {
m_dbService->cleanUserBehaviorRecord();
return;
}
}
void MainControlService::processFrontEndMessage_setting(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
if (cmdstr == "getAllSetting") {
auto dbval = m_dbService->getAllSettingJson();
receipt["dbval"] = dbval;
return;
}
if (cmdstr == "setSettingVal") {
string settingName = cmd["settingName"];
int settingVal = jsonGet<int>(cmd["settingVal"]);
bool suc = m_dbService->setSettingVal(settingName, settingVal);
if (!suc) {
receipt["ackcode"] = err::zecode(err::kdb_operate_error);
receipt["ackcodeInfo"] = err::zecode2str(err::kdb_operate_error);
return;
}
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_set_setting_val, fmt::format("({},{})", settingName, settingVal));
}
}
void MainControlService::processFrontEndMessage_processFormulaCmd(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
/**
* @brief
*/
string cmdstr = cmd["command"];
if (cmdstr == "startFormula") {
int id = jsonGet<int>(cmd["id"]);
auto formul = m_dbService->getFormula(id);
if (!formul) {
logger->error("formula id {} not exist", id);
receipt["ackcode"] = err::zecode(err::kdb_operate_error);
receipt["ackcodeInfo"] = err::zecode2str(err::kdb_operate_error);
return;
}
m_disinfectionCtrlService->startDisinfection(atoi(formul->loglevel.c_str()), //
atoi(formul->injection_pump_speed.c_str()), //
atoi(formul->stoped_gs.c_str()), //
atoi(formul->continued_gs.c_str()), //
atoi(formul->stoped_satur.c_str()), //
atoi(formul->continued_satur.c_str()), //
atoi(formul->stoped_humi.c_str()), //
atoi(formul->continued_humi.c_str())); //
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_do_formula, fmt::format("({})", formul->formula_id));
return;
}
if (cmdstr == "getAllFormula") {
receipt["formula"] = m_dbService->getAllFormulaJson();
return;
}
if (cmdstr == "addFormula") {
string formula_id = cmd["formula_id"];
m_dbService->addFormula(cmd["formula_id"], //
jsonGet<int>(cmd["loglevel"]), //
jsonGet<int>(cmd["stoped_gs"]), //
jsonGet<int>(cmd["continued_gs"]), //
jsonGet<int>(cmd["stoped_satur"]), //
jsonGet<int>(cmd["continued_satur"]), //
jsonGet<int>(cmd["stoped_humi"]), //
jsonGet<int>(cmd["continued_humi"]), //
jsonGet<int>(cmd["injection_pump_speed"]));
// kbehavior_add_formula
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_add_formula, fmt::format("({})", formula_id));
return;
}
if (cmdstr == "delFormula") {
auto formula = m_dbService->delFormula(jsonGet<int>(cmd["id"]));
if (formula) {
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_del_formula, fmt::format("({})", formula->formula_id));
}
return;
}
if (cmdstr == "updateFormula") {
string val_str;
if (cmd["val"].is_string()) {
val_str = cmd["val"];
} else {
val_str = std::to_string(cmd["val"].get<int>());
}
auto formula = m_dbService->updateFormula(jsonGet<int>(cmd["id"]), cmd["column"], val_str);
if (formula) {
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_update_formula,
fmt::format("({},{},{})", formula->formula_id, cmd["column"], val_str));
}
return;
}
if (cmdstr == "updateFormula2") {
int id = jsonGet<int>(cmd["id"]);
string formula_id = cmd["formula_id"];
int loglevel = jsonGet<int>(cmd["loglevel"]);
int stoped_gs = jsonGet<int>(cmd["stoped_gs"]);
int continued_gs = jsonGet<int>(cmd["continued_gs"]);
int stoped_satur = jsonGet<int>(cmd["stoped_satur"]);
int continued_satur = jsonGet<int>(cmd["continued_satur"]);
int stoped_humi = jsonGet<int>(cmd["stoped_humi"]);
int continued_humi = jsonGet<int>(cmd["continued_humi"]);
int injection_pump_speed = jsonGet<int>(cmd["injection_pump_speed"]);
shared_ptr<Formula> formula = m_dbService->getFormula(id);
string oldname = formula->formula_id;
formula->formula_id = formula_id;
formula->loglevel = std::to_string(loglevel);
formula->stoped_gs = std::to_string(stoped_gs);
formula->continued_gs = std::to_string(continued_gs);
formula->stoped_satur = std::to_string(stoped_satur);
formula->continued_satur = std::to_string(continued_satur);
formula->stoped_humi = std::to_string(stoped_humi);
formula->continued_humi = std::to_string(continued_humi);
formula->injection_pump_speed = std::to_string(injection_pump_speed);
if (!formula) {
logger->error("formula id {} not exist", id);
receipt["ackcode"] = err::zecode(err::kdb_operate_error);
receipt["ackcodeInfo"] = err::zecode2str(err::kdb_operate_error);
return;
}
m_dbService->updateFormula(formula);
if (oldname != formula_id) {
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_update_formula_name,
fmt::format("({}->{})", oldname, formula->formula_id));
}
m_dbService->addUserBehaviorRecord(m_deviceStateService->getLoginUid(), kbehavior_update_formula, fmt::format("({})", formula->formula_id));
return;
}
}
void MainControlService::processFrontEndMessage_processBehaviorRecordCmd(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
if (cmdstr == "getUserBehaviorRecordDescJson") {
receipt["records"] = m_dbService->getUserBehaviorRecordDescJson(jsonGet<int>(cmd["page"]), jsonGet<int>(cmd["page_size"]));
return;
}
// 导入用户行为测试数据
if (cmdstr == "importTestData") {
for (size_t i = 0; i < 100; i++) {
logger->info("addUserBehaviorRecord {}", i);
m_dbService->addUserBehaviorRecord("admin", kbehavior_login, "(admin)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_logout, "(admin)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_add_user, "(zhaohe)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_del_user, "(zhaohe)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_update_user_permission_level, "(zhaohe,3)");
// kbehavior_update_user_uid
m_dbService->addUserBehaviorRecord("admin", kbehavior_update_user_passwd, "()");
m_dbService->addUserBehaviorRecord("admin", kbehavior_set_setting_val, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_add_formula, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_del_formula, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_update_formula, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_do_disinfection, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_stop_disinfection, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_do_formula, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_update_setting_val_on_disinfection, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_export_disinfection_data, "(....)");
m_dbService->addUserBehaviorRecord("admin", kbehavior_export_user_action_data, "(....)");
}
return;
}
}
void MainControlService::processFrontEndMessage(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt) {
string cmdstr = cmd["command"];
processFrontEndMessage_userOperate(webSocket, cmd, receipt);
processFrontEndMessage_systemOperate(webSocket, cmd, receipt);
processFrontEndMessage_Disinfection(webSocket, cmd, receipt);
processFrontEndMessage_test(webSocket, cmd, receipt);
processFrontEndMessage_setting(webSocket, cmd, receipt);
processFrontEndMessage_processFormulaCmd(webSocket, cmd, receipt);
processFrontEndMessage_processBehaviorRecordCmd(webSocket, cmd, receipt);
processFrontEndMessage_exportData(webSocket, cmd, receipt);
/*******************************************************************************
* getState *
*******************************************************************************/
if (cmdstr == "getState") {
receipt["state"]["isLogin"] = m_deviceStateService->isLogin();
receipt["state"]["loginuser"] = m_deviceStateService->getLoginUid();
receipt["state"]["permissionLevel"] = m_deviceStateService->getLoginPermissionLevel();
// receipt["state"]["workState"] = m_disinfectionCtrlService->isDisinfectionRunning();
/*******************************************************************************
* disinfectionState *
*******************************************************************************/
receipt["state"]["replenishingFluidsWorkState"] = m_disinfectionCtrlService->getReplenishingFluidsWorkState();
receipt["state"]["drainingWorkState"] = m_disinfectionCtrlService->getDrainingWorkState();
/**
* @brief
*/
receipt["state"]["preHeat"] = m_disinfectionCtrlService->isPreheatState();
receipt["state"]["preHeatRaminTimeS"] = m_disinfectionCtrlService->getPreHeatRaminTimeS(); // 预热剩余时间
receipt["state"]["estimatedRemainingTimeS"] = m_disinfectionCtrlService->getEstimatedRemainingTimeS();
receipt["state"]["disinfection_id"] = m_disinfectionCtrlService->getDisinfectionID();
// 消毒状态
receipt["state"]["disinfectionWorkState"] = m_disinfectionCtrlService->getDisinfectionWorkState();
receipt["state"]["disinfectionState"]["id"] = m_disinfectionCtrlService->getDisinfectionID();
receipt["state"]["disinfectionState"]["estimatedRemainingTimeS"] = m_disinfectionCtrlService->getEstimatedRemainingTimeS();
receipt["state"]["disinfectionState"]["workState"] = m_disinfectionCtrlService->getDisinfectionWorkState();
receipt["state"]["disinfectionState"]["preHeat"] = m_disinfectionCtrlService->isPreheatState();
receipt["state"]["disinfectionState"]["preHeatRaminTimeS"] = m_disinfectionCtrlService->getPreHeatRaminTimeS(); // 预热剩余时间
receipt["state"]["disinfectionState"]["nowlog"] = m_disinfectionCtrlService->m_context.m_nowLoglevel;
receipt["state"]["disinfectionState"]["targetlog"] = m_disinfectionCtrlService->m_context.m_targetLoglevel;
receipt["state"]["disinfectionState"]["dvalue"] = m_disinfectionCtrlService->m_context.dvalue;
/*******************************************************************************
* sensor *
*******************************************************************************/
receipt["state"]["sensor_data"] = createSensorDataJson();
/*******************************************************************************
* disinfectionConfig *
*******************************************************************************/
receipt["disinfectionConfig"]["loglevel"] = m_disinfectionCtrlService->m_context.m_targetLoglevel;
receipt["disinfectionConfig"]["injection_pump_speed"] = m_disinfectionCtrlService->m_context.injection_pump_speed;
receipt["disinfectionConfig"]["stoped_gs"] = m_disinfectionCtrlService->m_context.stoped_gs;
receipt["disinfectionConfig"]["continued_gs"] = m_disinfectionCtrlService->m_context.continued_gs;
receipt["disinfectionConfig"]["stoped_satur"] = m_disinfectionCtrlService->m_context.stoped_satur;
receipt["disinfectionConfig"]["continued_satur"] = m_disinfectionCtrlService->m_context.continued_satur;
receipt["disinfectionConfig"]["stoped_humi"] = m_disinfectionCtrlService->m_context.stoped_humi;
receipt["disinfectionConfig"]["continued_humi"] = m_disinfectionCtrlService->m_context.continued_humi;
return;
}
if (cmdstr == "getDisinfectionConfig") {
/*******************************************************************************
* disinfectionConfig *
*******************************************************************************/
receipt["disinfectionConfig"]["loglevel"] = m_disinfectionCtrlService->m_context.m_targetLoglevel;
receipt["disinfectionConfig"]["injection_pump_speed"] = m_disinfectionCtrlService->m_context.injection_pump_speed;
receipt["disinfectionConfig"]["stoped_gs"] = m_disinfectionCtrlService->m_context.stoped_gs;
receipt["disinfectionConfig"]["continued_gs"] = m_disinfectionCtrlService->m_context.continued_gs;
receipt["disinfectionConfig"]["stoped_satur"] = m_disinfectionCtrlService->m_context.stoped_satur;
receipt["disinfectionConfig"]["continued_satur"] = m_disinfectionCtrlService->m_context.continued_satur;
receipt["disinfectionConfig"]["stoped_humi"] = m_disinfectionCtrlService->m_context.stoped_humi;
receipt["disinfectionConfig"]["continued_humi"] = m_disinfectionCtrlService->m_context.continued_humi;
return;
}
}
HttpResponsePtr MainControlService::hello_world( //
HttpRequestPtr request, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState>) {
return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "hello_world");
}
HttpResponsePtr MainControlService::doscript(HttpRequestPtr httpreq, shared_ptr<RestfulServer::Context> context, std::shared_ptr<ConnectionState> conn) {
return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "do script success");
}
HttpResponsePtr MainControlService::stopscript(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>) {
return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), "stop script success");
}

35
src/main_control_service.hpp

@ -28,12 +28,24 @@
//
//
#include "api/front_msg_processer.hpp"
#include "db/db_service.hpp"
#include "iflytop/components/zcanreceiver/zcanhost.hpp"
#include "service/data_export_service.hpp"
#include "service/device_io_control_service.hpp"
#include "service/disinfection_logs_manager.hpp"
#include "src/service/iflytop_can_host_device.hpp"
//
#include "api/cmds/device_state_cmd_impl.hpp"
#include "api/cmds/disinfection_cmd_impl.hpp"
#include "api/cmds/record_mgr_cmd_impl.hpp"
#include "api/cmds/setting_page_cmd_impl.hpp"
#include "api/cmds/system_operate_cmd_impl.hpp"
#include "api/cmds/test_page_cmd_impl.hpp"
#include "api/cmds/usrcmd_impl.hpp"
/**
* @brief
@ -54,7 +66,6 @@ class MainControlService : public enable_shared_from_this<MainControlService> {
ENABLE_LOGGER(MainControlService);
shared_ptr<GConfig> m_zconfig;
shared_ptr<RestfulServer> m_restfulServer;
shared_ptr<IflytopFrontEndService> m_iflytopwsService;
shared_ptr<DBService> m_dbService;
shared_ptr<DeviceStateService> m_deviceStateService;
@ -63,6 +74,10 @@ class MainControlService : public enable_shared_from_this<MainControlService> {
shared_ptr<DisinfectionLogsManager> m_disinfectionLogsManager;
shared_ptr<ZCanHost> m_zcanhost;
shared_ptr<DataExportService> m_dataExportService;
shared_ptr<FrontMsgProcesser> m_frontMsgProcesser;
unique_ptr<Thread> m_reportThread;
@ -82,25 +97,9 @@ class MainControlService : public enable_shared_from_this<MainControlService> {
HttpResponsePtr reactionConfigCardInfo_read(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
HttpResponsePtr reactionConfigCardInfo_trigger_once_report(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
HttpResponsePtr reactionConfigCardInfo_read_state(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
HttpResponsePtr hello_world(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
//
HttpResponsePtr doscript(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
HttpResponsePtr doscriptblock(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
HttpResponsePtr stopscript(HttpRequestPtr, shared_ptr<RestfulServer::Context>, std::shared_ptr<ConnectionState>);
void createReactionConfigCardInfoReportAndSend();
void processFrontEndMessage(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_userOperate(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_systemOperate(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_Disinfection(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_test(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_setting(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_processFormulaCmd(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_processBehaviorRecordCmd(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
void processFrontEndMessage_exportData(weak_ptr<WebSocket> webSocket, json& cmd, json& receipt);
json createSensorDataJson();
void dosystem(string order);

133
src/service/data_export_service.cpp

@ -1,133 +0,0 @@
#include "data_export_service.hpp"
using namespace iflytop;
void DataExportService::loop() {
ThisThread thisThread;
while (!thisThread.getExitFlag()) {
}
}
void DataExportService::initialize() { GET_TO_SERVICE(m_dbService); }
bool DataExportService::isDetectedUDisk(string& diskpath) {
/**
* @brief /dev/sda是否存在
*/
// 检查 /dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh 是否存在
for (int i = 0; i < 8; i++) {
string dev = fmt::format("/dev/sd{}", (char)('a' + i));
logger->info("check dev: {}", dev);
if (access(dev.c_str(), F_OK) == 0) {
string subdev = fmt::format("/dev/sd{}1", (char)('a' + i));
if (access(subdev.c_str(), F_OK) == 0) {
diskpath = subdev;
} else {
diskpath = dev;
}
m_ismounted = true;
return true;
}
}
return false;
}
bool DataExportService::dosystem(string cmd) {
logger->info("do cmd: {}", cmd);
int ret = system(cmd.c_str());
if (ret == 0) {
return true;
} else {
logger->error("do cmd: {} failed,{}", cmd, ret);
return false;
}
}
static string getTime() {
struct tm tm = {0};
time_t t = ::time(nullptr);
struct tm* tmp = localtime_r(&t, &tm);
return fmt::format("{:0>4}{:0>2}{:0>2}{:0>2}{:0>2}{:0>2}", tm.tm_year + 1900, //
tm.tm_mon + 1, //
tm.tm_mday, //
tm.tm_hour, //
tm.tm_min, tm.tm_sec);
}
#define IF_ERROR_RETURN(x) \
if (!x) { \
return err::ksys_copy_file_error; \
}
err::error_t DataExportService::exportDisinfectionData() {
lock_guard<mutex> lock(lock_);
string diskpath;
if (!isDetectedUDisk(diskpath)) {
logger->error("no disk detected");
return err::kharde_unfound;
}
logger->info("diskpath: {}", diskpath);
// 创建目录
IF_ERROR_RETURN(dosystem(fmt::format("rm -rf /mnt/exportdata")));
IF_ERROR_RETURN(dosystem(fmt::format("mkdir -p /mnt/exportdata")));
// 挂载目录
IF_ERROR_RETURN(dosystem(fmt::format("mount {} /mnt/exportdata", diskpath)));
// 拷贝文件
IF_ERROR_RETURN(dosystem(fmt::format("cp -rf /app/disinfection_logs /mnt/exportdata/disinfection_logs{}", getTime())));
// 卸载目录
IF_ERROR_RETURN(dosystem(fmt::format("umount /mnt/exportdata")));
// 删除目录
IF_ERROR_RETURN(dosystem(fmt::format("rm -rf /mnt/exportdata")));
return err::ksucc;
}
err::error_t DataExportService::exportAuditData() {
lock_guard<mutex> lock(lock_);
string diskpath;
if (!isDetectedUDisk(diskpath)) {
logger->error("no disk detected");
return err::kharde_unfound;
}
logger->info("diskpath: {}", diskpath);
/**
* @brief csv
*/
auto records = m_dbService->getAllUserBehaviorRecord();
string filename = fmt::format("/tmp/audit{}.csv", getTime());
ofstream ofs(filename);
if (!ofs.is_open()) {
logger->error("open file {} failed", filename);
return err::ksys_open_file_error;
}
ofs << "date,uid,operation" << endl;
for (auto& record : records) {
ofs << fmt::format("{},{},\"{}{}\"", record->date, record->uid, db::user_behavior_to_str((user_behavior_t)record->behavior), record->behaviorinfo) << endl;
}
ofs.close();
// 文件编码转换
IF_ERROR_RETURN(dosystem(fmt::format("iconv -f UTF-8 -tgb18030 {} -o {}", filename, filename + ".1")));
dosystem(fmt::format("mv {} {}", filename + ".1", filename));
/**
* @brief U盘
*/
// 创建目录
IF_ERROR_RETURN(dosystem(fmt::format("rm -rf /mnt/exportdata")));
IF_ERROR_RETURN(dosystem(fmt::format("mkdir -p /mnt/exportdata")));
// 挂载目录
IF_ERROR_RETURN(dosystem(fmt::format("mount {} /mnt/exportdata", diskpath)));
// 拷贝文件
IF_ERROR_RETURN(dosystem(fmt::format("cp -rf {} /mnt/exportdata", filename)));
// 卸载目录
IF_ERROR_RETURN(dosystem(fmt::format("umount /mnt/exportdata")));
// 删除目录
IF_ERROR_RETURN(dosystem(fmt::format("rm -rf /mnt/exportdata")));
return err::ksucc;
}

60
src/service/data_export_service.hpp

@ -1,60 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <mutex>
#include "iflytop/components/zcanreceiver/zcanhost.hpp"
#include "iflytop/core/core.hpp"
#include "zservice_container/zservice_container.hpp"
// lock_guard<mutex> lock(lock_);
#include <mutex>
// std::lock_guard<std::recursive_mutex> lock(lock_);
#include "iflytop/core/error/error_code.hpp"
//
#include "db/db_service.hpp"
namespace iflytop {
class DataExportService {
ENABLE_LOGGER(DataExportService);
private:
bool m_ismounted = false;
unique_ptr<Thread> m_thread;
shared_ptr<DBService> m_dbService;
mutex lock_;
public:
DataExportService(/* args */){};
~DataExportService(){};
void initialize();
bool isDetectedUDisk(string& diskpath);
void mountDisk();
void unmountDisk();
err::error_t exportDisinfectionData();
err::error_t exportAuditData();
private:
void loop();
bool dosystem(string cmd);
};
}; // namespace iflytop

0
src/service/device_state_service.cpp

63
src/service/device_state_service.hpp

@ -1,63 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "iflytop/core/core.hpp"
/**
* @brief
*
* service: DeviceStateService
*
* :
* :
* :
* :
*
*/
namespace iflytop {
using namespace std;
using namespace core;
class DeviceStateService : public enable_shared_from_this<DeviceStateService> {
ENABLE_LOGGER(DeviceStateService);
bool loginFlag = false;
string login_uid;
int login_permission_level;
int login_visible;
public:
DeviceStateService(){};
void setLoginState(string uid, int permission_level, int visible) {
loginFlag = true;
login_uid = uid;
login_permission_level = permission_level;
login_visible = visible;
}
void unlogin() {
loginFlag = false;
login_uid = "";
login_permission_level = 0;
}
bool isLogin() { return loginFlag; }
int getLoginPermissionLevel() { return login_permission_level; }
int getLoginVisible() { return login_visible; }
string getLoginUid() { return login_uid; }
void initialize(){};
};
} // namespace iflytop

679
src/service/disinfection_ctl_service.cpp

@ -1,679 +0,0 @@
#include "disinfection_ctl_service.hpp"
using namespace iflytop;
using namespace std;
/**
* @brief
*
* :
*
*
* 1s
*
* 1s
*
* 1s
*
*
*
* 1s
*
* 1s
*
*
*/
// #define PRE_HEAT_TIME (2)
// #define PRE_HEAT_TIME (5 * 60)
#define DVALUE_COMPUTEPERIOD_TIME_S (10.0)
#define MAX_VOLUME (5000)
namespace iflytop {
extern bool g_in_test;
}
DisinfectionCtrlService::DisinfectionCtrlService() {}
void DisinfectionCtrlService::initialize() {
GET_TO_SERVICE(m_zcanHost);
GET_TO_SERVICE(m_deviceIoControlService);
GET_TO_SERVICE(m_dbService);
GET_TO_SERVICE(m_disinfectionLogsManager);
m_deviceIoControlService->drainingPump_close();
m_deviceIoControlService->replenishingFluidsPump_close();
m_deviceIoControlService->sprayLiquidPump_close();
m_deviceIoControlService->heartingPlate_setPower(false);
m_deviceIoControlService->airBlower_setState(false);
m_deviceIoControlService->airCompressor_setState(false);
m_dvalueComputer.initialize();
}
static string getTime() {
struct tm tm = {0};
time_t t = time(nullptr);
struct tm* tmp = localtime_r(&t, &tm);
return fmt::format("{:0>4}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", tm.tm_year + 1900, //
tm.tm_mon + 1, //
tm.tm_mday, //
tm.tm_hour, //
tm.tm_min, tm.tm_sec);
}
string DisinfectionCtrlService::createDisinfectionID() {
struct tm tm = {0};
time_t t = time(nullptr);
if (t == -1) {
logger->error("time(nullptr) failed");
exit(-1);
}
struct tm* tmp = localtime_r(&t, &tm);
if (!tmp) {
logger->error("localtime_r failed");
exit(-1);
}
// tm = *utctime::tm_increment_hour(&tm, 8);
// logger->info("trace sendmsg_startCapture {}:{}", __FILE__, __LINE__);
return fmt::format("{:0>4}-{:0>2}{:0>2}-{:0>2}{:0>2}{:0>2}", tm.tm_year + 1900, //
tm.tm_mon + 1, //
tm.tm_mday, //
tm.tm_hour, //
tm.tm_min, tm.tm_sec);
}
static bool zfeq(float a, float b, float eps = 0.01) {
if (fabs(a - b) < eps) {
return true;
}
return false;
}
float DisinfectionCtrlService::getDisinfectionDValue(float ppm) { //
return m_dvalueComputer.computeDValue(ppm);
}
float DisinfectionCtrlService::computeNowLogLevel(DisinfectionContext& context) {
float dvalue = context.dvalue;
if (dvalue > 0) {
/**
* @brief m_nowLoglevel
*/
return context.m_nowLoglevel + DVALUE_COMPUTEPERIOD_TIME_S / (dvalue * 60);
}
return context.m_nowLoglevel;
}
void DisinfectionCtrlService::computeRemainTime(DisinfectionContext& context) {
/**
* @brief Dvalue
*/
float dvalue = context.dvalue;
if (dvalue > 0) {
/**
* @brief m_nowLoglevel
*/
if (context.m_targetLoglevel >= context.m_nowLoglevel) {
context.m_remaintime = (context.m_targetLoglevel - context.m_nowLoglevel) * (dvalue * 60);
} else {
context.m_remaintime = 0;
}
} else {
//
}
logger->info("computeRemainTime minh2o2 {} dvalue {}", context.h2o2data.min_h2o2, dvalue);
}
void DisinfectionCtrlService::initContext(DisinfectionContext& context, //
int loglevel, //
float injection_pump_speed, //
float stoped_gs, //
float continued_gs, //
float stoped_satur, //
float continued_satur, //
float stoped_humi, //
float continued_humi //
) {
context.m_disinfectionID = createDisinfectionID();
context.pre_heat_time_s = m_dbService->getSettingVal("pre_heat_time_s");
context.stoped_gs = stoped_gs;
context.continued_gs = continued_gs;
context.stoped_satur = stoped_satur;
context.continued_satur = continued_satur;
context.stoped_humi = stoped_humi;
context.continued_humi = continued_humi;
context.injection_pump_speed = injection_pump_speed;
context.injection_pump_speed_changed = true;
if (g_in_test) {
logger->warn("in test mode, pre_heat_time_s = 5");
context.pre_heat_time_s = 5;
}
logger->info("startDisinfection {} {}", m_context.m_targetLoglevel, m_context.m_disinfectionID);
logger->info(" stoped_gs {}", context.stoped_gs);
logger->info(" continued_gs {}", context.continued_gs);
logger->info(" stoped_satur {}", context.stoped_satur);
logger->info(" continued_satur {}", context.continued_satur);
logger->info(" stoped_humi {}", context.stoped_humi);
logger->info(" continued_humi {}", context.continued_humi);
logger->info(" pre_heat_time_s {}", context.pre_heat_time_s);
logger->info("");
// m_remaintime = loglevel * 20 * 60; // 计算总的加热时间
context.m_remaintime = context.pre_heat_time_s + loglevel * 90 * 60; // 计算总的加热时间
m_disinfectionWorkState = 1;
context.m_targetLoglevel = loglevel;
context.m_nowLoglevel = 0;
// m_context.m_preheatFlag = true;
m_context.dvalue = 0;
// m_context.stopedflag = false;
m_context.m_state = kpreheat;
m_context.m_starttp = zsteady_clock().now();
m_zcanHost->warning_light_ctrl_c1002(1, 0, 0, 1, 0);
m_deviceIoControlService->heartingPlate_setPower(true);
context.csvlogger = m_disinfectionLogsManager->createNewLogger(context.m_disinfectionID);
// zsteady_clock().elapsedTimeS(m_context.m_starttp), //
// sensors[0].h2o2, sensors[0].temp, sensors[0].humid, sensors[0].saturation, //
// sensors[1].h2o2, sensors[1].temp, sensors[1].humid, sensors[1].saturation, //
// sensors[2].h2o2, sensors[2].temp, sensors[2].humid, sensors[2].saturation, //
// m_context.dvalue, m_context.m_nowLoglevel, (int)m_context.m_targetLoglevel, //
// ds->heatingStrip_getstate(), ds->airBlower_getstate(), ds->airCompressor_getstate(), ds->sprayLiquidPump_getRPM(), //
// ds->getPressureSensorData(1), ds->getPressureSensorData(2), ds->getPressureSensorData(3), ds->getPressureSensorData(4), //
// m_deviceIoControlService->getDisinfectantVolume_g(), //
// m_context.m_remaintime
context.csvlogger->write(
"Date," //
"Hydrogen peroxide volume(ppm),Temperature(C),Relative humidity(%RH),H2O H2O2 RS(%RS)," //
// "h2o22,temp2,humi2,saturation2," //
// "h2o23,temp3,humi3,saturation3," //
"Dvalue,Loglevel,Targetloglevel," //
"Heating,Blower,Compressor,Pump(g/min)," //
"Disinfectant Volume(g)," //
"Remaining time (s)\n" //
);
}
static string formattimeS(int sec) {
if (sec >= 0) {
return fmt::format("{:0>2}:{:0>2}:{:0>2}", sec / 3600, sec % 3600 / 60, sec % 60);
} else {
return fmt::format("--:--:--");
}
}
void DisinfectionCtrlService::dumpDisinfectionLogsToCSV(DisinfectionContext& context) {
auto* sensors = &m_context.h2o2data.h2o2sensor_data[0];
auto ds = m_deviceIoControlService;
float dvalue = 0;
if (m_context.dvalue <= 0) {
dvalue = 0;
} else {
dvalue = m_context.dvalue;
}
int remaintime = getEstimatedRemainingTimeS();
context.csvlogger->write(
fmt::format("{}," //
"{},{},{},{}," //
// "{},{},{},{}," //
// "{},{},{},{}," //
"{},{},{}," //
"{},{},{},{}," //
// "{},{},{},{}," //
"{}," //
"{}\n" //
,
getTime(), //
sensors[0].h2o2, sensors[0].temp, sensors[0].humid, sensors[0].saturation, //
// sensors[1].h2o2, sensors[1].temp, sensors[1].humid, sensors[1].saturation, //
// sensors[2].h2o2, sensors[2].temp, sensors[2].humid, sensors[2].saturation, //
(int32_t)dvalue, (int32_t)m_context.m_nowLoglevel, (int32_t)m_context.m_targetLoglevel, //
ds->heatingStrip_getstate(), ds->airBlower_getstate(), ds->airCompressor_getstate(), ds->sprayLiquidPump_getGPM(), //
m_deviceIoControlService->getDisinfectantVolume_g(), //
formattimeS(remaintime)));
}
void DisinfectionCtrlService::finishDisinfection(DisinfectionContext& context) {
context.m_remaintime = 0;
logger->info("stop disinfection {}", context.m_disinfectionID);
// sprayLiquidPump_close();
m_deviceIoControlService->sprayLiquidPump_close();
usleep(1000 * 1000);
// airCompressor(false);
m_deviceIoControlService->airCompressor_setState(false);
usleep(1000 * 1000);
// blower_setPower(false);
m_deviceIoControlService->airBlower_setState(false);
usleep(1000 * 1000);
// heartingPlate_setPower(false);
m_deviceIoControlService->heartingPlate_setPower(false);
m_disinfectionWorkState = 3;
m_zcanHost->warning_light_ctrl_c1002(1, 0, 0, 0, 0);
context.csvlogger = nullptr;
}
void DisinfectionCtrlService::processPreheatState(DisinfectionContext& context) {
int hasstarttime = zsteady_clock().elapsedTimeS(context.m_starttp);
// logger->info("preheat {}", context.m_disinfectionID);
if ((context.m_state == kpreheat && hasstarttime > m_context.pre_heat_time_s)) {
logger->info("preheat finished {}", context.m_disinfectionID);
// blower_setPower(true);
m_deviceIoControlService->airBlower_setState(true);
usleep(1000 * 1000);
// airCompressor(true);
m_deviceIoControlService->airCompressor_setState(true);
usleep(1000 * 1000);
// sprayLiquidPump_open();
m_deviceIoControlService->sprayLiquidPump_open(context.injection_pump_speed);
context.m_state = kdisinfection;
// context.m_preheatFlag = false;
// context.sprayLiquidFlag = true;
} else {
logger->info("{}: preheat {}", context.m_disinfectionID, m_context.pre_heat_time_s - hasstarttime);
}
}
void DisinfectionCtrlService::dumpDisinfectionLogs(DisinfectionContext& context) {
// float h2o2_g = m_deviceIoControlService->getDisinfectantVolume_g();
auto* sensors = &m_context.h2o2data.h2o2sensor_data[0];
auto ds = m_deviceIoControlService;
logger->info(
"T:{}," //
"s1:({},{},{},{})," //
"s2:({},{},{},{})," //
"s3:({},{},{},{})," //
"D:{},log:({}:{})," //
"io:({},{},{},{})," //
"p:({},{},{},{})," //
"h2o2g:{}," //
"rt:{}" //
,
zsteady_clock().elapsedTimeS(m_context.m_starttp), //
sensors[0].h2o2, sensors[0].temp, sensors[0].humid, sensors[0].saturation, //
sensors[1].h2o2, sensors[1].temp, sensors[1].humid, sensors[1].saturation, //
sensors[2].h2o2, sensors[2].temp, sensors[2].humid, sensors[2].saturation, //
m_context.dvalue, m_context.m_nowLoglevel, (int)m_context.m_targetLoglevel, //
ds->heatingStrip_getstate(), ds->airBlower_getstate(), ds->airCompressor_getstate(), ds->sprayLiquidPump_getRPM(), //
ds->getPressureSensorData(1), ds->getPressureSensorData(2), ds->getPressureSensorData(3), ds->getPressureSensorData(4), //
m_deviceIoControlService->getDisinfectantVolume_g(), //
getEstimatedRemainingTimeS());
}
/**
* @brief
*
*/
void DisinfectionCtrlService::processDisinfectionState(DisinfectionContext& context) {
ZCHECK(context.m_state == kdisinfection || context.m_state == kdisinfection_take_a_break, "state error");
/**
* @brief
*/
/**
* @brief 湿
*/
if (m_context.m_state == kdisinfection) {
/**
* @brief
*/
float nowSatur = m_context.h2o2data.max_saturation;
float nowh2o2 = m_context.h2o2data.max_h2o2;
float humid = m_context.h2o2data.max_humid;
if (m_context.injection_pump_speed_changed) {
m_deviceIoControlService->sprayLiquidPump_open(context.injection_pump_speed);
m_context.injection_pump_speed_changed = false;
}
// humid > m_context.stoped_satur
if (nowSatur > m_context.stoped_satur || nowh2o2 > m_context.stoped_gs || humid > m_context.stoped_humi) {
logger->info("stop sprayLiquid");
m_deviceIoControlService->sprayLiquidPump_close();
usleep(1000 * 1000);
m_deviceIoControlService->airCompressor_setState(false);
// m_context.sprayLiquidFlag = false;
m_context.m_state = kdisinfection_take_a_break;
}
} else {
float nowSatur = m_context.h2o2data.max_saturation;
float nowh2o2 = m_context.h2o2data.max_h2o2;
float humid = m_context.h2o2data.max_humid;
// && humid < m_context.continued_satur
if (nowSatur < m_context.continued_satur && nowh2o2 < m_context.continued_gs && humid < context.continued_humi) {
logger->info("start sprayLiquid");
m_deviceIoControlService->sprayLiquidPump_open(context.injection_pump_speed);
usleep(1000 * 1000);
m_deviceIoControlService->airCompressor_setState(true);
m_context.m_state = kdisinfection;
}
}
}
void DisinfectionCtrlService::disinfectionLoop(bool& breakflag) {
// logger->info("disinfection running {} {}s preheatFlag:{}", m_context.m_disinfectionID, m_context.m_remaintime, m_context.m_preheatFlag);
m_context.m_remaintime--;
bool forcelog = false;
if (m_context.m_remaintime < 0) {
m_context.m_remaintime = 0;
}
/**
* @brief
*/
m_deviceIoControlService->getAllSensorData(m_context.h2o2data);
/**
* @brief D值
*/
m_context.dvalue = getDisinfectionDValue(m_context.h2o2data.min_h2o2);
if (zsteady_clock().elapsedTimeS(m_context.m_lastComputeDvalueTp) > DVALUE_COMPUTEPERIOD_TIME_S) {
m_context.m_lastComputeDvalueTp = zsteady_clock().now();
//
if (m_context.m_state == kdisinfection || m_context.m_state == kdisinfection_take_a_break) {
m_context.m_nowLoglevel = computeNowLogLevel(m_context);
computeRemainTime(m_context);
}
}
if (m_context.m_state == kpreheat) {
/**
* @brief
*/
processPreheatState(m_context);
} else if (m_context.m_state == kdisinfection || m_context.m_state == kdisinfection_take_a_break) {
/**
* @brief
*/
processDisinfectionState(m_context);
//
if (m_context.m_remaintime <= 0 && m_context.m_nowLoglevel > (m_context.m_targetLoglevel + 0.01)) {
m_context.m_remaintime = 0;
m_context.m_nowLoglevel = m_context.m_targetLoglevel + 0.01;
logger->info("disinfection finished {},but waitting for h2o2 to safe", m_context.m_disinfectionID);
m_deviceIoControlService->sprayLiquidPump_close();
usleep(1000 * 1000);
m_deviceIoControlService->airCompressor_setState(false);
usleep(1000 * 1000);
m_deviceIoControlService->heartingPlate_setPower(false);
m_context.m_state = kwait_for_h2o2_down;
forcelog = true;
}
} else if (m_context.m_state == kwait_for_h2o2_down) {
/**
* @brief h2o2浓度下降
*/
logger->info("waitting for h2o2 concentration to safe value {}=>{}", m_context.h2o2data.min_h2o2, 1);
if (m_context.h2o2data.min_h2o2 < 1) {
logger->info("h2o2 concentration to safe value");
breakflag = true;
forcelog = true;
m_context.m_state = kfinished;
}
} else {
ZCHECK(false, "state error");
}
if (forcelog || zsteady_clock().elapsedTimeS(m_context.m_lastlogTp) > DVALUE_COMPUTEPERIOD_TIME_S) {
m_context.m_lastlogTp = zsteady_clock().now();
dumpDisinfectionLogs(m_context);
dumpDisinfectionLogsToCSV(m_context);
}
}
void DisinfectionCtrlService::changeDisinfectionParameter(int injection_pump_speed, //
int stoped_gs, //
int continued_gs, //
int stoped_satur, //
int continued_satur, //
int stoped_humi, //
int continued_humi) {
lock_guard<recursive_mutex> lock(lock_);
// logger->info("changeInjectionPumpSpeed {}=>{}", m_context.injection_pump_speed, speed);
// m_context.injection_pump_speed = speed;
m_context.injection_pump_speed = injection_pump_speed;
m_context.stoped_gs = stoped_gs;
m_context.continued_gs = continued_gs;
m_context.stoped_satur = stoped_satur;
m_context.continued_satur = continued_satur;
m_context.stoped_humi = stoped_humi;
m_context.continued_humi = continued_humi;
m_context.injection_pump_speed_changed = true;
logger->info("changeDisinfectionParameter {} {} {} {} {} {} {}", injection_pump_speed, stoped_gs, continued_gs, stoped_satur, continued_satur, stoped_humi,
continued_humi);
}
void DisinfectionCtrlService::startDisinfection(int loglevel, //
int injection_pump_speed, //
int stoped_gs, //
int continued_gs, //
int stoped_satur, //
int continued_satur, //
int stoped_humi, //
int continued_humi //
) {
lock_guard<recursive_mutex> lock(lock_);
/**
* @TODO
* 湿湿
*/
if (m_disinfectionThread) {
stopDisinfection();
}
initContext(m_context, loglevel, injection_pump_speed, stoped_gs, continued_gs, stoped_satur, continued_satur, stoped_humi, continued_humi);
m_disinfectionThread.reset(new Thread("m_disinfectionThread", [this]() {
ThisThread thisThread;
while (!thisThread.getExitFlag()) {
thisThread.sleepForMs(1000);
bool breakflag = false;
disinfectionLoop(breakflag);
if (breakflag) {
break;
}
}
//
finishDisinfection(m_context);
}));
//
}
int DisinfectionCtrlService::getDisinfectionWorkState() { return m_context.m_state; }
void DisinfectionCtrlService::stopDisinfection() {
lock_guard<recursive_mutex> lock(lock_);
if (m_disinfectionThread) {
m_disinfectionThread->join();
m_disinfectionThread = nullptr;
}
m_context.m_state = kfinished;
m_disinfectionWorkState = 0;
}
int32_t DisinfectionCtrlService::getEstimatedRemainingTimeS() {
lock_guard<recursive_mutex> lock(lock_);
if (m_context.m_state == kpreheat) {
return getPreHeatRaminTimeS();
} else if (m_context.m_state == kdisinfection || m_context.m_state == kdisinfection_take_a_break) {
if (m_context.dvalue > 0) {
return m_context.m_remaintime;
} else {
return -1;
}
} else {
return 0;
}
}
int32_t DisinfectionCtrlService::getPreHeatRaminTimeS() {
lock_guard<recursive_mutex> lock(lock_);
int32_t remaintime = 0;
if (m_context.m_state == kpreheat) {
remaintime = m_context.pre_heat_time_s - zsteady_clock().elapsedTimeS(m_context.m_starttp);
if (remaintime < 0) {
remaintime = 0;
}
return remaintime;
} else {
return 0;
}
}
string DisinfectionCtrlService::getDisinfectionID() {
lock_guard<recursive_mutex> lock(lock_);
return m_context.m_disinfectionID;
}
bool DisinfectionCtrlService::isPreheatState() {
lock_guard<recursive_mutex> lock(lock_);
return m_context.m_state == kpreheat;
}
int DisinfectionCtrlService::getReplenishingFluidsWorkState() { return m_replenishingFluidsWorkState; }
int DisinfectionCtrlService::getDrainingWorkState() { return m_drainingWorkState; }
/*******************************************************************************
* // 加液 *
*******************************************************************************/
/**
* @brief
*
* @param stopatg
*/
void DisinfectionCtrlService::startReplenishingFluids(int stopatg) {
lock_guard<recursive_mutex> lock(lock_);
if (m_disinfectionThread) {
m_disinfectionThread->join();
m_disinfectionThread = nullptr;
}
int32_t nowvolume = m_deviceIoControlService->getDisinfectantVolume_g();
if (nowvolume > stopatg) {
logger->warn("start Replenishing fail, nowvolume {} > stopatg {}", nowvolume, stopatg);
return;
}
m_disinfectionThread.reset(new Thread("disinfectionThread", [this, stopatg]() {
ThisThread thisThread;
m_deviceIoControlService->replenishingFluidsPump_open();
logger->info("startReplenishingFluids {}g", stopatg);
while (!thisThread.getExitFlag()) {
int32_t nowvolume = m_deviceIoControlService->getDisinfectantVolume_g();
logger->info("replenishingFluids {}g", nowvolume);
if (nowvolume > stopatg) {
break;
}
if (nowvolume > MAX_VOLUME) {
logger->warn("replenishingFluids reach full level {}g", nowvolume);
break;
}
thisThread.sleepForMs(1000);
}
logger->info("stopReplenishingFluids");
// replenishingFluidsPump_close();
m_deviceIoControlService->replenishingFluidsPump_close();
m_replenishingFluidsWorkState = 0;
}));
//
m_replenishingFluidsWorkState = 1;
logger->info("startReplenishingFluids ");
}
/**
* @brief
*
*/
void DisinfectionCtrlService::stopReplenishingFluids() {
lock_guard<recursive_mutex> lock(lock_);
if (m_disinfectionThread) {
m_disinfectionThread->join();
m_disinfectionThread = nullptr;
}
logger->info("stopReplenishingFluids");
// replenishingFluidsPump_close();
m_deviceIoControlService->replenishingFluidsPump_close();
m_replenishingFluidsWorkState = 0;
}
/*******************************************************************************
* *
*******************************************************************************/
/**
* @brief
*
*/
void DisinfectionCtrlService::startDraining() {
lock_guard<recursive_mutex> lock(lock_);
if (m_disinfectionThread) {
m_disinfectionThread->join();
m_disinfectionThread = nullptr;
}
m_disinfectionThread.reset(new Thread("disinfectionThread", [this]() {
ThisThread thisThread;
m_deviceIoControlService->drainingPump_open();
logger->info("startDraining ");
auto startdrainingtime = zsteady_clock().now();
zsteady_tp volumeReachZeroTime;
bool volumeReachZeroFlag = false;
while (!thisThread.getExitFlag()) {
int32_t nowvolume = m_deviceIoControlService->getDisinfectantVolume_g();
logger->info("draining remain {} g", nowvolume);
if (!volumeReachZeroFlag && nowvolume == 0) {
volumeReachZeroTime = zsteady_clock().now();
volumeReachZeroFlag = true;
}
if (volumeReachZeroFlag) {
logger->info("stopDraining after {} s", 30 - zsteady_clock().elapsedTimeS(volumeReachZeroTime));
if (zsteady_clock().elapsedTimeS(volumeReachZeroTime) > 30) {
break;
}
}
thisThread.sleepForMs(1000);
}
logger->info("stopDraining");
// replenishingFluidsPump_close();
m_deviceIoControlService->drainingPump_close();
m_drainingWorkState = 0;
}));
logger->info("startDraining");
// drainingPump_open();
m_drainingWorkState = 1;
}
/**
* @brief
*/
void DisinfectionCtrlService::stopDraining() {
lock_guard<recursive_mutex> lock(lock_);
if (m_disinfectionThread) {
m_disinfectionThread->join();
m_disinfectionThread = nullptr;
}
logger->info("stopDraining");
m_drainingWorkState = 0;
// drainingPump_close();
m_deviceIoControlService->drainingPump_close();
}

186
src/service/disinfection_ctl_service.hpp

@ -1,186 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "db/db_service.hpp"
#include "disinfection_logs_manager.hpp"
#include "iflytop/components/zcanreceiver/zcanhost.hpp"
#include "iflytop/core/core.hpp"
#include "service/device_io_control_service.hpp"
#include "utils/dvalue_computer.hpp"
#include "zservice_container/zservice_container.hpp"
/**
* @brief
*
* service: DisinfectionCtrlService
*
* :
* :
* :
* :
*
*/
namespace iflytop {
using namespace std;
using namespace core;
class DisinfectionCtrlService : public enable_shared_from_this<DisinfectionCtrlService> {
ENABLE_LOGGER(DisinfectionCtrlService);
public:
typedef enum {
kidle = 0,
kpreheat = 1,
kdisinfection = 2,
kdisinfection_take_a_break = 3,
kwait_for_h2o2_down = 4,
kfinished = 5,
} state_t;
private:
unique_ptr<Thread> m_disinfectionThread;
shared_ptr<DeviceIoControlService> m_deviceIoControlService;
shared_ptr<DBService> m_dbService;
shared_ptr<DisinfectionLogsManager> m_disinfectionLogsManager;
DValueComputer m_dvalueComputer;
recursive_mutex lock_;
int m_disinfectionWorkState = 0;
int m_replenishingFluidsWorkState = 0;
int m_drainingWorkState = 0;
shared_ptr<ZCanHost> m_zcanHost;
class DisinfectionContext {
public:
string m_disinfectionID;
zsteady_tp m_starttp;
zsteady_tp m_lastComputeDvalueTp;
zsteady_tp m_lastlogTp;
DeviceIoControlService::all_h2o2sensor_data_t h2o2data;
// bool m_preheatFlag = false;
// bool stopedflag = false; // 消毒停止标志,但继续等待h2o2浓度下降
int m_remaintime = 0;
float m_targetLoglevel = 0;
float m_nowLoglevel = 0;
float dvalue = 0;
state_t m_state = kidle;
// bool sprayLiquidFlag = false;
int injection_pump_speed;
bool injection_pump_speed_changed = false;
int pre_heat_time_s = 0;
int stoped_gs = 0;
int continued_gs = 0;
int stoped_satur = 0;
int continued_satur = 0;
int stoped_humi = 0;
int continued_humi = 0;
shared_ptr<DisinfectionLogger> csvlogger;
};
public:
DisinfectionContext m_context;
public:
DisinfectionCtrlService();
public:
void initialize();
/**
* @brief
*
* @param loglevel
*/
void startDisinfection(int loglevel, //
int injection_pump_speed, //
int stoped_gs, //
int continued_gs, //
int stoped_satur, //
int continued_satur, //
int stoped_humi, //
int continued_humi //
);
void changeDisinfectionParameter(int injection_pump_speed, //
int stoped_gs, //
int continued_gs, //
int stoped_satur, //
int continued_satur, //
int stoped_humi, //
int continued_humi //
);
void stopDisinfection();
int getDisinfectionWorkState();
int getReplenishingFluidsWorkState();
int getDrainingWorkState();
/*******************************************************************************
* *
*******************************************************************************/
void startReplenishingFluids(int stopatg);
void stopReplenishingFluids();
/*******************************************************************************
* *
*******************************************************************************/
void startDraining();
void stopDraining();
/*******************************************************************************
* State *
*******************************************************************************/
bool isDisinfectionRunning();
int32_t getEstimatedRemainingTimeS();
string getDisinfectionID();
bool isPreheatState();
int32_t getPreHeatRaminTimeS();
private:
string createDisinfectionID();
private:
float getDisinfectionDValue(float ppm);
void initContext(DisinfectionContext& context, //
int loglevel, //
float injection_pump_speed, //
float stoped_gs, //
float continued_gs, //
float stoped_satur, //
float continued_satur, //
float stoped_humi, //
float continued_humi //
);
void computeRemainTime(DisinfectionContext& context);
float computeNowLogLevel(DisinfectionContext& context);
void processPreheatState(DisinfectionContext& context);
void processDisinfectionState(DisinfectionContext& context);
void dumpDisinfectionLogs(DisinfectionContext& context);
void dumpDisinfectionLogsToCSV(DisinfectionContext& context);
void finishDisinfection(DisinfectionContext& context);
void disinfectionLoop(bool& breakflag);
};
} // namespace iflytop

99
src/service/disinfection_logs_manager.cpp

@ -1,99 +0,0 @@
#include "disinfection_logs_manager.hpp"
#include <dirent.h>
#include <errno.h>
#include "iflytop/core/components/fileutils.hpp"
using namespace iflytop;
using namespace core;
using namespace std;
#define LOG_STORGE_PATH "./disinfection_logs/"
DisinfectionLogger::DisinfectionLogger() {}
DisinfectionLogger::~DisinfectionLogger() {
if (m_logfile.is_open()) {
m_logfile.close();
}
}
void DisinfectionLogger::initialize(string log_file_name) { //
logger->info("create loggers:{}", log_file_name);
m_logfile.open(log_file_name, ios::out | ios::binary | ios::trunc);
if (!m_logfile.is_open()) {
logger->error("create loggers:{} failed", log_file_name);
}
}
void DisinfectionLogger::write(string log) {
m_logfile.write(log.c_str(), log.size());
if (m_logfile.fail()) {
logger->error("write log failed:{}", strerror(errno));
}
m_logfile.flush();
}
DisinfectionLogsManager::DisinfectionLogsManager(/* args */) {}
DisinfectionLogsManager::~DisinfectionLogsManager() {}
shared_ptr<DisinfectionLogger> DisinfectionLogsManager::createNewLogger(string log_file_name) {
system(fmt::format("mkdir -p {}", LOG_STORGE_PATH).c_str());
shared_ptr<DisinfectionLogger> logger = make_shared<DisinfectionLogger>();
logger->initialize(fmt::format("{}{}.csv", LOG_STORGE_PATH, log_file_name));
return logger;
}
static void split(const string& s, vector<string>& sv, const char delim = ' ') {
sv.clear();
istringstream iss(s);
string temp;
while (getline(iss, temp, delim)) {
sv.push_back(temp);
}
return;
}
void DisinfectionLogsManager::list_dir_csvfile(string path, vector<string>& sv) {
sv.clear();
DIR* dir;
struct dirent* ptr;
if ((dir = opendir(path.c_str())) == NULL) {
logger->error("Open dir {} error...", path);
return;
}
while ((ptr = readdir(dir)) != NULL) {
if (ptr->d_name[0] == '.') continue;
if (ptr->d_type == 8) {
string filename = ptr->d_name;
if (filename.find(".csv") != string::npos) {
sv.push_back(filename);
}
}
}
closedir(dir);
return;
}
nlohmann::json DisinfectionLogsManager::getlogger(string log_file_name) {
string content = FileUtils().readFileAsString(fmt::format("{}{}.csv", LOG_STORGE_PATH, log_file_name));
nlohmann::json csvcontent;
vector<string> lines;
split(content, lines, '\n');
for (auto& line : lines) {
csvcontent["content"].push_back(line);
}
return csvcontent;
}
nlohmann::json DisinfectionLogsManager::getLoggerList() {
//
// 1. get all files in LOG_STORGE_PATH
vector<string> files;
list_dir_csvfile(LOG_STORGE_PATH, files);
nlohmann::json loggerlist;
for (auto& file : files) {
// 获取文件名去掉.csv
file = file.substr(0, file.find(".csv"));
loggerlist.push_back(file);
}
return loggerlist;
}

48
src/service/disinfection_logs_manager.hpp

@ -1,48 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "iflytop/core/basic/nlohmann/json.hpp"
#include "iflytop/core/core.hpp"
namespace iflytop {
using namespace std;
class DisinfectionLogger {
ENABLE_LOGGER(DisinfectionLogger);
ofstream m_logfile;
public:
DisinfectionLogger();
~DisinfectionLogger();
void initialize(string log_file_name);
void write(string log);
};
class DisinfectionLogsManager {
ENABLE_LOGGER(DisinfectionLogsManager);
public:
DisinfectionLogsManager(/* args */);
~DisinfectionLogsManager();
void initialize(){};
shared_ptr<DisinfectionLogger> createNewLogger(string log_file_name);
nlohmann::json getlogger(string log_file_name);
nlohmann::json getLoggerList();
private:
void list_dir_csvfile(string path, vector<string>& sv);
};
} // namespace iflytop

44
src/service/iflytop_can_host_device.cpp

@ -1,44 +0,0 @@
#include "iflytop_can_host_device.hpp"
using namespace std;
using namespace iflytop;
void IflytopCanHostDevice::initialize(string can_if_name, int baudrate, bool enablLoopback) {
// m_iflytopCanProtocolStack.reset(new IflytopCanProtocolStack());
m_can_if_name = can_if_name;
m_baudrate = baudrate;
m_enablLoopback = enablLoopback;
resetSocketCan();
}
void IflytopCanHostDevice::startListen() {}
void IflytopCanHostDevice::processRx(shared_ptr<SocketCanFrame> frame) {
if (!frame) {
return;
}
if (frame->getCanIdentifier() == socketcan::kextFrame && //
frame->getFanFrameType() == socketcan::kdataframe) {
/**
* @brief can消息
*/
} else {
logger->warn("Rx unknown can frame");
}
}
void IflytopCanHostDevice::resetSocketCan() {
auto socketCanConfig = make_shared<SocketCanConfig>();
socketCanConfig->enablLoopback = m_enablLoopback; // 根据 SocketCan::dumpCanDriverInfo() 的输出,确定该标志位是false还是true
socketCanConfig->m_canName = m_can_if_name;
socketCanConfig->m_canBaudrate = m_baudrate;
socketCanConfig->m_canfilters = {};
logger->info("initialize() m_canName:{} {}", socketCanConfig->m_canName, socketCanConfig->m_canBaudrate);
m_socketCan.reset(new SocketCan());
m_socketCan->initialize(socketCanConfig);
m_socketCan->startListen();
m_socketCan->onSocketCanFrame.connect([this](shared_ptr<SocketCanFrame> canframe) { //
processRx(canframe);
});
}

39
src/service/iflytop_can_host_device.hpp

@ -1,39 +0,0 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "iflytop/core/basic/nlohmann/json.hpp"
#include "iflytop/core/driver/socketcan/socket_can.hpp"
#include "iflytop/core/spdlogfactory/logger.hpp"
#include "zservice_container/zservice_container.hpp"
namespace iflytop {
using namespace std;
class IflytopCanHostDevice {
ENABLE_LOGGER(IflytopCanHostDevice);
shared_ptr<SocketCan> m_socketCan;
string m_can_if_name;
int m_baudrate;
bool m_enablLoopback;
public:
IflytopCanHostDevice(){};
void initialize(string can_if_name, int baudrate, bool enablLoopback);
void startListen();
void processRx(shared_ptr<SocketCanFrame> frame);
private:
void resetSocketCan();
};
} // namespace iflytop
Loading…
Cancel
Save