Browse Source

fix some bug

storage-in-realtime
zhaohe 12 months ago
parent
commit
fd2a4c25f0
  1. 2
      appdep/iflytop/core/components/timeutils.hpp
  2. 245
      appsrc/service/disinfection_logs_service.cpp
  3. 23
      appsrc/service/disinfection_logs_service.hpp
  4. 0
      doc/TESTCMD.md

2
appdep/iflytop/core/components/timeutils.hpp

@ -78,7 +78,7 @@ class T_TimeUtils {
std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::string s(30, '\0');
std::strftime(&s[0], s.size(), fmt, std::localtime(&now));
return s;
return s.c_str();
}
};

245
appsrc/service/disinfection_logs_service.cpp

@ -15,6 +15,7 @@
#include <vector>
#include "appbase/appbean/disinfection_record_csv_header.hpp"
#include "appbase/utils/zsimplepdf.hpp"
using namespace std;
using namespace iflytop;
typedef DisinfectionRecordCSVHeader CSVHeader;
@ -25,6 +26,7 @@ typedef DisinfectionRecordCSVHeader CSVHeader;
#define LOG_STORGE_PATH "./disinfection_logs/"
#define EXPORT_PATH "/mnt/exportdata/Transmit/"
#define MAX_LOG_NUM 5
#define IF_ERROR_RETURN(x) \
if (!x) { \
return err::kappe_udisk_wr_fail; \
@ -99,6 +101,25 @@ static void listDirCSVFile(string path, vector<string>& sv) {
}
return;
}
static int getDirFileNum(string path) {
DIR* dir;
struct dirent* ptr;
if ((dir = opendir(path.c_str())) == NULL) {
return 0;
}
int num = 0;
while ((ptr = readdir(dir)) != NULL) {
if (ptr->d_name[0] == '.') continue;
if (ptr->d_type == 8) {
string filename = ptr->d_name;
num++;
}
}
return num;
}
static void split(const string& s, vector<string>& sv, const char delim = ' ') {
sv.clear();
istringstream iss(s);
@ -110,6 +131,25 @@ static void split(const string& s, vector<string>& sv, const char delim = ' ') {
return;
}
static string createDisinfectionID() {
struct tm tm = {0};
time_t t = time(nullptr);
if (t == -1) {
printf("time error\n");
exit(-1);
}
struct tm* tmp = localtime_r(&t, &tm);
if (!tmp) {
printf("localtime_r error\n");
exit(-1);
}
return fmt::format("{:0>4}-{: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);
}
/*******************************************************************************
* CLASS *
*******************************************************************************/
@ -121,11 +161,12 @@ void DisinfectionLogsService::initialize() {
GET_TO_SERVICE(m_gConfig);
GET_TO_SERVICE(m_udiskMgrService);
REGFN(DisinfectionLogsService, getRecordList);
REGFN(DisinfectionLogsService, getRecord);
REGFN(DisinfectionLogsService, deleteReport);
REGFN(DisinfectionLogsService, exportRecord);
REGFN(DisinfectionLogsService, printRecord);
REGFNV2(DisinfectionLogsService, getRecordList);
REGFNV2(DisinfectionLogsService, getRecord);
REGFNV2(DisinfectionLogsService, deleteReport);
REGFNV2(DisinfectionLogsService, exportRecord);
REGFNV2(DisinfectionLogsService, printRecord);
REGFNV2(DisinfectionLogsService, selftest);
m_csvHeaderDict.insert(CSVHeader::time, "时间");
m_csvHeaderDict.insert(CSVHeader::state, "设备状态");
@ -163,38 +204,57 @@ void DisinfectionLogsService::initialize() {
AppEventBus::ins()->onEvent.connect([this](shared_ptr<IAppEvent> event) {
if (auto e = dynamic_pointer_cast<AppDisinfectionStartEvent>(event); e) {
logger->info("DisinfectionLogsService: start new disinfection session");
startNewDisinfectionSession(e->getSessionId());
onAppDisinfectionStartEvent(e->getSessionId());
return;
}
if (auto e = dynamic_pointer_cast<AppDisinfectionFinishedEvent>(event); e) {
logger->info("DisinfectionLogsService: finish disinfection session");
finishDisinfectionSession();
m_statistics = e->getDisinfectionStatistics();
onAppDisinfectionFinishedEvent(e->getDisinfectionStatistics());
return;
}
if (auto e = dynamic_pointer_cast<AppDisinfectionSnapshotEvent>(event); e) {
logger->info("DisinfectionLogsService: push state snapshot");
pushStateSnapshot(e->getStateSnapshot());
onAppDisinfectionSnapshotEvent(e->getStateSnapshot());
return;
}
});
// m_recordFiles
/**
* @brief
*/
vector<string> files;
listDirCSVFile(LOG_STORGE_PATH, files);
for (auto& file : files) {
// 获取文件名去掉.csv
file = file.substr(0, file.find(".csv"));
m_recordFiles.push_back(file);
}
for (auto& file : m_recordFiles) {
logger->info("DisinfectionLogsService: load record file: {}", file);
}
return;
}
void DisinfectionLogsService::startNewDisinfectionSession(string sessionId) { //
void DisinfectionLogsService::onAppDisinfectionStartEvent(string sessionId) { //
m_snapshots.clear();
m_sessionId = sessionId;
}
void DisinfectionLogsService::pushStateSnapshot(shared_ptr<DisinfectionStateSnapshot> snapshot) { m_snapshots.push_back(snapshot); }
void DisinfectionLogsService::finishDisinfectionSession() {
void DisinfectionLogsService::onAppDisinfectionSnapshotEvent(shared_ptr<DisinfectionStateSnapshot> snapshot) { m_snapshots.push_back(snapshot); }
void DisinfectionLogsService::onAppDisinfectionFinishedEvent(shared_ptr<DisinfectionStatistics> statistics) {
m_statistics = statistics;
dumpDisinfectionRecord(m_sessionId, m_snapshots);
dumpDisinfectionToPrinterLog(m_sessionId, m_snapshots);
m_recordFiles.push_back(m_sessionId);
/**
* @brief
* 1.
* 2.PDF文件缓存
*/
clearRecordFiles();
}
@ -235,7 +295,7 @@ void DisinfectionLogsService::dumpDisinfectionRecord(string sessionId, list<shar
csv.addValue(m_csvHeaderDict.getChName(CSVHeader::state), /*****************/ m_dmStateDict.getChName(s->state));
auto h2o2data = s->h2o2Snapshot;
for (uint32_t i = 0; i < h2o2data->getSensorDataNum(); i++) {
for (int i = 0; i < h2o2data->getSensorDataNum(); i++) {
if (i == 0) {
csv.addValue(m_csvHeaderDict.getChName(CSVHeader::ho2o2_0), /***************/ h2o2data->isExpired[0] ? "N/A" : formatSensorVal(h2o2data->h2o2[0]));
csv.addValue(m_csvHeaderDict.getChName(CSVHeader::temp_0), /****************/ h2o2data->isExpired[0] ? "N/A" : formatSensorVal(h2o2data->temp[0]));
@ -313,11 +373,13 @@ void DisinfectionLogsService::dumpDisinfectionToPrinterLog(string sessionId, lis
if (tu_sys().dToS(snapshot->time - lastlogtime) > logdtime) logthis = true;
if (!logthis) continue;
state = snapshot->state;
content += fmt::format("{}\n", format_zsystem_tp(snapshot->time));
if (stateChanged) {
content += fmt::format("{}\n", m_dmStateDict.getChName(snapshot->state));
}
if (state == DisinfectionState::disinfection) {
content += fmt::format("LOG: {}\n", snapshot->nlog);
}
@ -350,15 +412,58 @@ void DisinfectionLogsService::dumpDisinfectionToPrinterLog(string sessionId, lis
content += ("\n");
content += ("\n");
FileUtils().writeToFile(fmt::format("{}{}.log", LOG_STORGE_PATH, sessionId), content.c_str(), content.size());
logger->info("dump log to printer log file: {},\n", fmt::format("{}{}.log", LOG_STORGE_PATH, sessionId), content);
string logtxtpath = fmt::format("{}{}.log", LOG_STORGE_PATH, sessionId);
logger->info("dump log to printer log file: {},\n", logtxtpath, content);
FileUtils().writeToFile(logtxtpath, content.c_str(), content.size());
string pdfpath = fmt::format("{}{}.pdf", LOG_STORGE_PATH, sessionId);
ZSimplePDF pdfwriter(pdfpath);
pdfwriter.addText("\n");
pdfwriter.addText(content);
pdfwriter.dump();
}
void DisinfectionLogsService::dumpDisinfectionToPrinterPdf(string sessionId, list<shared_ptr<DisinfectionStateSnapshot>> snapshots) {}
/**
* @brief ,
*/
void DisinfectionLogsService::clearRecordFiles() {
// TODO: 删除掉多余的csv文件
// TODO: 检查时间,如果已经存储文件的时间大于当前时间,也删掉
//
vector<string> recordlist;
for (auto& record : m_recordFiles) {
recordlist.push_back(record);
}
if (recordlist.size() == 0) {
logger->info("no record files");
return;
}
// 从后往前删除,保留最新的MAX_LOG_NUM个
vector<string> delFiles;
int removeFileNum = recordlist.size() - MAX_LOG_NUM;
if (removeFileNum > 0) {
for (int i = 0; i < removeFileNum; i++) {
delFiles.push_back(recordlist[recordlist.size() - 1 - i]);
}
}
for (auto& file : delFiles) {
deleteRecordFile(file);
}
int fileNum = getDirFileNum(LOG_STORGE_PATH);
if ((uint32_t)fileNum != m_recordFiles.size() * 3) {
logger->error("record file num error, delete all record files");
logger->info("delete all record files");
dosystem(fmt::format("rm -rf {}/*", LOG_STORGE_PATH));
m_recordFiles.clear();
}
}
void DisinfectionLogsService::deleteRecordFile(string file) {
string filepath = fmt::format("{}{}.*", LOG_STORGE_PATH, file);
dosystem(fmt::format("rm -rf {}", filepath));
m_recordFiles.remove_if([file](const string& s) { return s == file; });
}
int32_t DisinfectionLogsService::exportDisinfectionData(vector<string> files) {
string diskpath;
if (!m_udiskMgrService->isDetectedUDisk(diskpath)) {
@ -378,6 +483,7 @@ int32_t DisinfectionLogsService::exportDisinfectionData(vector<string> files) {
for (auto& file : files) {
logger->info("copy file: {}", file);
/**********************************拷贝CSV**********************************/
// 拷贝文件到TMP目录
IF_ERROR_RETURN(dosystem(fmt::format("cp -rf /app/disinfection_logs/{}.csv /tmp/{}.csv", file, file)));
// 编码转换
@ -386,6 +492,12 @@ int32_t DisinfectionLogsService::exportDisinfectionData(vector<string> files) {
IF_ERROR_RETURN(dosystem(fmt::format("mv /tmp/{}.csv.1 /tmp/{}.csv", file, file)));
// 拷贝文件到U盘
IF_ERROR_RETURN(dosystem(fmt::format("cp -rf /tmp/{}.csv {}", file, EXPORT_PATH)));
// 删除文件
IF_ERROR_RETURN(dosystem(fmt::format("rm -rf /tmp/{}.csv", file)));
/**********************************拷贝PDF**********************************/
// 拷贝pdf文件
dosystem(fmt::format("cp -rf /app/disinfection_logs/{}.pdf {}", file, EXPORT_PATH));
}
// 卸载目录
@ -411,62 +523,93 @@ bool DisinfectionLogsService::dosystem(string cmd) {
* EXT_API *
*******************************************************************************/
void DisinfectionLogsService::getRecordList(shared_ptr<MsgProcessContext> cxt) {
void DisinfectionLogsService::fn_getRecordList(shared_ptr<MsgProcessContext> cxt) {
/**
* @brief
*/
vector<string> files;
listDirCSVFile(LOG_STORGE_PATH, files);
nlohmann::json loggerlist;
for (auto& file : files) {
// 获取文件名去掉.csv
file = file.substr(0, file.find(".csv"));
loggerlist.push_back(file);
}
cxt->content = loggerlist;
vector<string> record;
for (auto& file : m_recordFiles) record.push_back(file);
cxt->content = record;
return;
}
void DisinfectionLogsService::getRecord(shared_ptr<MsgProcessContext> cxt) {
string logName = cxt->params["logName"];
void DisinfectionLogsService::fn_getRecord(shared_ptr<MsgProcessContext> cxt) {
string logName = cxt->params["logName"];
string content = FileUtils().readFileAsString(fmt::format("{}{}.csv", LOG_STORGE_PATH, logName));
vector<string> lines;
split(content, lines, '\n');
for (auto& line : lines) {
cxt->content.push_back(line);
}
}
void DisinfectionLogsService::deleteReport(shared_ptr<MsgProcessContext> cxt) {
void DisinfectionLogsService::fn_deleteReport(shared_ptr<MsgProcessContext> cxt) {
string logName = cxt->params["logName"];
system(fmt::format("rm -f {}{}.csv", LOG_STORGE_PATH, logName).c_str());
deleteRecordFile(logName);
}
void DisinfectionLogsService::exportRecord(shared_ptr<MsgProcessContext> cxt) {
void DisinfectionLogsService::fn_exportRecord(shared_ptr<MsgProcessContext> cxt) {
vector<string> files;
for (auto& key : cxt->params["logNames"]) {
files.push_back(key);
}
auto errcode = exportDisinfectionData(files);
if (errcode != err::ksucc) {
cxt->ackcode = errcode;
return;
}
/**
* TODO: pdf
*/
}
void DisinfectionLogsService::printRecord(shared_ptr<MsgProcessContext> cxt) {
void DisinfectionLogsService::fn_printRecord(shared_ptr<MsgProcessContext> cxt) {
//
logger->info("printRecord");
GET_SERVICE(UartPrinter)->print("打印成功测试");
GET_SERVICE(UartPrinter)->print("打印成功测试");
GET_SERVICE(UartPrinter)->print("打印成功测试");
GET_SERVICE(UartPrinter)->print("打印成功测试");
GET_SERVICE(UartPrinter)->print("打印成功测试");
GET_SERVICE(UartPrinter)->print("");
GET_SERVICE(UartPrinter)->print("");
GET_SERVICE(UartPrinter)->print("");
}
}
void DisinfectionLogsService::fn_selftest(shared_ptr<MsgProcessContext> cxt) {
string ssid = createDisinfectionID();
onAppDisinfectionStartEvent(ssid);
shared_ptr<H2O2SensorDataSnapshot> h2o2Snapshot = make_shared<H2O2SensorDataSnapshot>();
h2o2Snapshot->h2o2.push_back(0.1);
h2o2Snapshot->h2o2.push_back(0.2);
h2o2Snapshot->h2o2.push_back(0.3);
h2o2Snapshot->humid.push_back(0.4);
h2o2Snapshot->humid.push_back(0.5);
h2o2Snapshot->humid.push_back(0.6);
h2o2Snapshot->temp.push_back(0.7);
h2o2Snapshot->temp.push_back(0.8);
h2o2Snapshot->temp.push_back(0.9);
h2o2Snapshot->saturation.push_back(1.0);
h2o2Snapshot->saturation.push_back(1.1);
h2o2Snapshot->saturation.push_back(1.2);
h2o2Snapshot->isExpired.push_back(false);
h2o2Snapshot->isExpired.push_back(false);
h2o2Snapshot->isExpired.push_back(false);
h2o2Snapshot->minH2O2 = 10;
h2o2Snapshot->maxH2O2 = 20;
h2o2Snapshot->maxHumid = 30;
h2o2Snapshot->maxSaturation = 40;
shared_ptr<DisinfectionStateSnapshot> snapshot = make_shared<DisinfectionStateSnapshot>();
snapshot->state = DisinfectionState::disinfection;
snapshot->time = zsystem_clock().now();
snapshot->h2o2Snapshot = h2o2Snapshot;
snapshot->forcelog = false;
snapshot->dval = 0;
snapshot->nlog = 0;
snapshot->tlog = 0;
snapshot->remainDisinfectant = 0;
snapshot->remainTime = 0;
snapshot->ecode = 0;
onAppDisinfectionSnapshotEvent(snapshot);
onAppDisinfectionSnapshotEvent(snapshot);
onAppDisinfectionSnapshotEvent(snapshot);
shared_ptr<DisinfectionStatistics> statistics = make_shared<DisinfectionStatistics>();
statistics->start_tp = zsystem_clock().now();
statistics->complete_tp = zsystem_clock().now();
statistics->disinfectantVolume_g = 0;
statistics->tLog = 0;
statistics->finalLog = 0;
onAppDisinfectionFinishedEvent(statistics);
}

23
appsrc/service/disinfection_logs_service.hpp

@ -31,14 +31,16 @@ class DisinfectionLogsService : public enable_shared_from_this<DisinfectionLogsS
ZDictionary m_csvHeaderDict;
ZDictionary m_dmStateDict;
list<string> m_recordFiles;
public:
DisinfectionLogsService();
void initialize();
public:
void startNewDisinfectionSession(string sessionId);
void pushStateSnapshot(shared_ptr<DisinfectionStateSnapshot> snapshot);
void finishDisinfectionSession();
private:
void onAppDisinfectionStartEvent(string sessionId);
void onAppDisinfectionSnapshotEvent(shared_ptr<DisinfectionStateSnapshot> snapshot);
void onAppDisinfectionFinishedEvent(shared_ptr<DisinfectionStatistics> statistics);
private:
void dumpDisinfectionRecord(string sessionId, list<shared_ptr<DisinfectionStateSnapshot>> snapshots);
@ -49,15 +51,18 @@ class DisinfectionLogsService : public enable_shared_from_this<DisinfectionLogsS
/*******************************************************************************
* *
*******************************************************************************/
void getRecordList(shared_ptr<MsgProcessContext> cxt);
void getRecord(shared_ptr<MsgProcessContext> cxt);
void deleteReport(shared_ptr<MsgProcessContext> cxt);
void exportRecord(shared_ptr<MsgProcessContext> cxt);
void printRecord(shared_ptr<MsgProcessContext> cxt);
void fn_getRecordList(shared_ptr<MsgProcessContext> cxt);
void fn_getRecord(shared_ptr<MsgProcessContext> cxt);
void fn_deleteReport(shared_ptr<MsgProcessContext> cxt);
void fn_exportRecord(shared_ptr<MsgProcessContext> cxt);
void fn_printRecord(shared_ptr<MsgProcessContext> cxt);
void fn_selftest(shared_ptr<MsgProcessContext> cxt);
private:
int32_t exportDisinfectionData(vector<string> files);
void clearRecordFiles();
void deleteRecordFile(string file);
bool dosystem(string cmd);
};
} // namespace iflytop

0
TESTCMD.md → doc/TESTCMD.md

Loading…
Cancel
Save