From 97e4b182deee6fbbbf1b5d1a0c7ae6d25564be6c Mon Sep 17 00:00:00 2001 From: lixiaoyuan Date: Mon, 1 Dec 2025 18:26:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9http=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/Application.cpp | 2 +- src/app/Device.cpp | 11 +++-- src/app/Station.cpp | 90 +++++++++++++++++++++++----------- src/app/Station.h | 4 ++ src/database/Dao.cpp | 12 ++--- src/protocol/HttpEntity.cpp | 98 ++++++++++++++++++++++--------------- 6 files changed, 139 insertions(+), 78 deletions(-) diff --git a/src/app/Application.cpp b/src/app/Application.cpp index ee2ba57..ee9f634 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -85,7 +85,7 @@ void Application::runThreadMain() } static TimeTick ttMqtt; // 检查 场站的 MQTT 连接 - if (ttMqtt.elapse(30)) + if (ttMqtt.elapse(10)) { for (auto& item : appdata.mapStation) { diff --git a/src/app/Device.cpp b/src/app/Device.cpp index b86e8d3..9136814 100644 --- a/src/app/Device.cpp +++ b/src/app/Device.cpp @@ -6,9 +6,8 @@ #include "common/JsonN.h" #include "app/DataStruct.h" #include - - - +#include "Application.h" +#include "Station.h" static std::unordered_set g_setCacheDeviceType = {3, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110}; static bool CheckCacheType(int type) @@ -276,6 +275,12 @@ void Device::setParam(std::string k, int v) else if (type == 109) // 光伏板 { } + + if (err ) + { + auto station = Application::data().getStation(stationId); + station->err = 1; + } } std::string Device::getParam(std::string k, std::string defaultVal) diff --git a/src/app/Station.cpp b/src/app/Station.cpp index 982a16e..d944b28 100644 --- a/src/app/Station.cpp +++ b/src/app/Station.cpp @@ -308,6 +308,7 @@ string Station::getGatewayParam() void Station::checkDevice() { + int err = 0; for (auto& item: mapDevice) { auto& device = item.second; @@ -317,8 +318,13 @@ void Station::checkDevice() { device->online = 0; } + if (device->type != 5 && (device->err == 1 || device->online == 0)) + { + err = 1; + } } } + this->err = err; } void Station::readAlert(std::shared_ptr device, std::string addr, int v, std::string text) @@ -333,7 +339,7 @@ void Station::readAlert(std::shared_ptr device, std::string addr, int v, if (device) { fields.set("device_id", device->deviceId); } fields.set("type", int(EAlertType::DEVICE)); fields.set("content", text + ":故障(" + std::to_string(v) + ")"); - fields.set("status", 1); + fields.set("status", 0); auto dao = DaoEntity::create("log_alert"); dao->insertFields(fields); mapAlertCache[alertId] = ts; @@ -611,6 +617,31 @@ void Station::writeStatistic() } } + { + Fields fields; + fields.set("dt", Utils::dateStr(statData.ts)); + fields.set("station_id", this->stationId); + fields.set("E_in", statData.totalElectIn); + fields.set("E_in_J", statData.totalElectIn_J); + fields.set("E_in_F", statData.totalElectIn_F); + fields.set("E_in_P", statData.totalElectIn_P); + fields.set("E_in_G", statData.totalElectIn_G); + fields.set("E_out", statData.totalElectOut); + fields.set("E_out_J", statData.totalElectOut_J); + fields.set("E_out_F", statData.totalElectOut_F); + fields.set("E_out_P", statData.totalElectOut_P); + fields.set("E_out_G", statData.totalElectOut_G); + fields.set("fee_in", statData.totalFeeIn); + fields.set("fee_Out", statData.totalFeeOut); + fields.set("income", statData.totalIncome); + dao->setTableName("stat_total"); + + dao->duplicateUpdate(fields, { + "E_in", "E_in_J", "E_in_F", "E_in_P", "E_in_G", + "E_out", "E_out_J", "E_out_F", "E_out_P", "E_out_G", + "fee_in", "fee_Out", "income" + }); + } if (statData.ts > 0) { { // stat_day @@ -622,31 +653,8 @@ void Station::writeStatistic() fields.set("income_elect", statData.dayIncome); DAO::insertStatDay(dao, fields); } - { - Fields fields; - fields.set("dt", Utils::dateStr(statData.ts)); - fields.set("station_id", this->stationId); - fields.set("E_in", statData.totalElectIn); - fields.set("E_in_J", statData.totalElectIn_J); - fields.set("E_in_F", statData.totalElectIn_F); - fields.set("E_in_P", statData.totalElectIn_P); - fields.set("E_in_G", statData.totalElectIn_G); - fields.set("E_out", statData.totalElectOut); - fields.set("E_out_J", statData.totalElectOut_J); - fields.set("E_out_F", statData.totalElectOut_F); - fields.set("E_out_P", statData.totalElectOut_P); - fields.set("E_out_G", statData.totalElectOut_G); - fields.set("fee_in", statData.totalFeeIn); - fields.set("fee_Out", statData.totalFeeOut); - fields.set("income", statData.totalIncome); - dao->setTableName("stat_total"); - - dao->duplicateUpdate(fields, { - "E_in", "E_in_J", "E_in_F", "E_in_P", "E_in_G", - "E_out", "E_out_J", "E_out_F", "E_out_P", "E_out_G", - "fee_in", "fee_Out", "income" - }); - } + + if (statData.dayElectIn > 0.0f || statData.dayElectOut > 0.0f) { Fields fields; fields.set("dt", Utils::dateStr(statData.ts)); @@ -699,6 +707,23 @@ void Station::writeStatistic() fields.set("value", MapValueToJson(pos, mapCacheElectCharger)); dao->duplicateUpdate(fields, {"value"}); } + { + std::string sql = std::format("select dt, station_id, count(1) count from ( " + " select DATE(la.create_time) as dt, station_id, la.device_id, count(1), la.content from log_alert la " + " LEFT JOIN device d ON d.device_id = la.device_id " + "where la.create_time >= '{}' group by la.content, station_id, device_id, dt " + ") as tmp group by tmp.dt, station_id; ", Utils::dateStr(Utils::time()- 86400 * 7)); + vector result; + dao->exec(sql, result); + for (auto& item : result) + { + string dt = item.value("dt"); + string station_id = item.value("station_id"); + string count = item.value("count"); + std::string sqlUpdate = std::format("update stat_day set storage_num_err='{}' where dt='{}' AND station_id='{}'", count, dt, station_id); + dao->exec(sqlUpdate); + } + } } @@ -735,15 +760,24 @@ void Station::predict() if (vdptr) { + int v0 = 0; string& strval = fields.value("value"); std::vector vec; JSON::parseArray(strval, vec); for (int i = 0; isize() && i 0) { - (*vdptr)[i] += v0; + (*vdptr)[i] += v; if (datatype == 1) { countStorageIn[i]++; } else if (datatype == 2) { countStorageOut[i]++; } else if (datatype == 3) { countCharge[i]++; } diff --git a/src/app/Station.h b/src/app/Station.h index ec0c718..70f3310 100644 --- a/src/app/Station.h +++ b/src/app/Station.h @@ -144,6 +144,10 @@ public: //SysPolicy policy; std::string launchDate {}; + int err = 0; + int online = 0; + int running = 0; + bool isConnected {false}; int workMode {}; // 运行模式 diff --git a/src/database/Dao.cpp b/src/database/Dao.cpp index d1b8410..06ba061 100644 --- a/src/database/Dao.cpp +++ b/src/database/Dao.cpp @@ -97,7 +97,7 @@ static Errcode QueryCount(DaoEntity& dao, std::string sqlFrom, int& count) } -static Errcode QueryPagination(std::string sqlFields, std::string sqlFrom, PageInfo& page, vector& result) +static Errcode QueryPagination(std::string sqlFields, std::string sqlFrom, PageInfo& page, vector& result, std::string orderby="") { DaoEntity dao(""); if (!dao.isConnected()) @@ -114,7 +114,7 @@ static Errcode QueryPagination(std::string sqlFields, std::string sqlFrom, PageI if (page.index < 1) page.index = 1; if (page.size <= 0) page.size = 10; page.total = count; - std::string sql = "SELECT " + sqlFields + " " + sqlFrom + DAO::sqlPageLimit(page.index -1, page.size); + std::string sql = "SELECT " + sqlFields + " " + sqlFrom + orderby + DAO::sqlPageLimit(page.index -1, page.size); int ret = dao.exec(sql, result); return Errcode(ret); } @@ -490,7 +490,7 @@ Errcode DAO::deletePolicyById(std::string policyId) Errcode DAO::querySystemLogList(PageInfo& pageInfo, vector& result) { std::string sqlFrom = "FROM " + DMLogSystem::TABLENAME; - return QueryPagination("*", sqlFrom, pageInfo, result); + return QueryPagination("*", sqlFrom, pageInfo, result, " order by create_time desc "); } Errcode DAO::insertSystemLog(Fields& params) { @@ -534,8 +534,8 @@ Errcode DAO::insertSystemLogDevice(int stationId, int deviceId, std::string cont Errcode DAO::queryAlertLogList(PageInfo& pageInfo, vector& result) { - std::string sqlFrom = "FROM " + DMLogAlert::TABLENAME; - return QueryPagination("*", sqlFrom, pageInfo, result); + std::string sqlFrom = "from log_alert la left join device d on d.device_id =la.device_id left join station s on s.station_id = d.station_id"; + return QueryPagination("d.station_id, s.name station_name, d.name device_name, la.*", sqlFrom, pageInfo, result, " order by create_time desc "); } Errcode DAO::insertAlertLog(Fields& params) { @@ -601,7 +601,7 @@ Errcode DAO::queryStatStationList(PageInfo& pageInfo, Fields& params, vector result; auto err = DAO::queryStationList(pageinfo, result); + for (auto& item : result) + { + int stationId = item.get("station_id"); + auto station = Application::data().getStation(stationId); + if (station) + { + item.set("err", station->err); + } + } HttpHelper::setPagination(pageinfo, result, json); return err; }; @@ -1111,7 +1120,7 @@ Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, njson& js for (auto& item : Application::data().mapStation) { auto& station = item.second; - + //auto station = Application::data().getStation(5); for (int i = 0; i < num; ++i) { vecStoreIn[i] += station->predictStorageIn[i]; @@ -1155,6 +1164,8 @@ Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, st electStorageOut += station->electStorageOut; } + float income = 0.0; + njson jsondata; jsondata["launch_date"] = appdata.launchDate; //: 系统上线启用日期,格式:yyyy-mm-dd jsondata["income_total"] = incomeTotal; // : 累计收益(元),精度0.01 @@ -1167,14 +1178,17 @@ Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, st jsondata["storage_elect_in"] = electStorageIn; // : 储能充电总电量(kWh),精度0.001 jsondata["storage_elect_out"] = electStorageOut; // : 储能放电总电量(kWh),精度0.001 - std::string sql = "SELECT SUM(income_elect) income_total FROM stat_day;"; + // 总览页面:累计收益 + std::string sql = "SELECT * FROM stat_total st INNER JOIN " + "(SELECT station_id, MAX(dt) max_dt FROM stat_total GROUP BY station_id) tmp " + "ON st.station_id = tmp.station_id AND st.dt = tmp.max_dt; "; std::vector result; DAO::exec(NULL, sql, result); - if (result.size() > 0) + for (auto& item: result) { - jsondata["income_total"] = result[0].get("income_total"); + income += item.get("income"); } - + jsondata["income_total"] = income; json["data"] = jsondata; return Errcode::OK; } @@ -1184,17 +1198,18 @@ Errcode HttpEntity::queryStatStationGroup(const httplib::Request& req, njson& js njson jsondata = njson::array(); auto dao = DaoEntity::create(""); - std::string sql = R"(SELECT s.station_id, s.name station_name, ss.income_elect, ss.income_charge, ss.storage_usage FROM station s LEFT JOIN - (SELECT station_id, SUM(income_elect ) income_elect , SUM(income_charge) income_charge, avg(storage_usage) storage_usage FROM stat_day GROUP BY station_id) AS ss - ON ss.station_id = s.station_id)"; + std::string sql = R"(SELECT s.name station_name, st.* FROM stat_total st INNER JOIN + (SELECT station_id, MAX(dt) max_dt FROM stat_total GROUP BY station_id) tmp + ON st.station_id=tmp.station_id AND st.dt=tmp.max_dt + LEFT JOIN station s ON s.station_id=st.station_id;)"; std::vector vecStations; auto err = dao->exec(sql, vecStations); for (auto& fields: vecStations) { njson jsonnode; jsonnode["station_name"] = fields.value("station_name"); - jsonnode["income"] = fields.get("income_elect") + fields.get("income_charge"); - jsonnode["usage_rate"] = fields.get("storage_usage"); + jsonnode["income"] = fields.get("income"); + jsonnode["usage_rate"] = fields.get("usage"); jsondata.push_back(jsonnode); } json["data"] = jsondata; @@ -1255,23 +1270,23 @@ Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std { Fields params; std::string sqlCondition = GetRequestStatParams(req, params); - std::string sql = R"(SELECT - SUM(storage_elect_in) storage_elect_in, - SUM(storage_elect_out) storage_elect_out, - SUM(storage_num_in) storage_num_in, - SUM(storage_num_out) storage_num_out, - SUM(storage_num_err) storage_num_err, - SUM(solar_elect_gen) solar_elect_gen, - SUM(solar_elect_grid) solar_elect_grid, - SUM(solar_num_err) solar_num_err, - AVG(storage_usage) storage_usage, - SUM(charge_elect) charge_elect, - SUM(charge_num) charge_num, - SUM(charge_num_err) charge_num_err, - AVG(charge_usage) charge_usage, - SUM(income_elect) income_elect, - SUM(income_charge) income_charge - FROM stat_day ss)" + sqlCondition + ";"; + //std::string sql = R"(SELECT + // SUM(storage_elect_in) storage_elect_in, + // SUM(storage_elect_out) storage_elect_out, + // SUM(storage_num_in) storage_num_in, + // SUM(storage_num_out) storage_num_out, + // SUM(storage_num_err) storage_num_err, + // SUM(solar_elect_gen) solar_elect_gen, + // SUM(solar_elect_grid) solar_elect_grid, + // SUM(solar_num_err) solar_num_err, + // AVG(storage_usage) storage_usage, + // SUM(charge_elect) charge_elect, + // SUM(charge_num) charge_num, + // SUM(charge_num_err) charge_num_err, + // AVG(charge_usage) charge_usage, + // SUM(income_elect) income_elect, + // SUM(income_charge) income_charge + // FROM stat_day ss)" + sqlCondition + ";"; std::string stationId = params.value("station_id"); @@ -1285,6 +1300,9 @@ Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std auto& appdata = Application::data(); std::vector result; + std::string sql = std::format("SELECT * FROM stat_total st INNER JOIN " + "(SELECT station_id, MAX(dt) max_dt FROM stat_total ss {} GROUP BY station_id) tmp " + "ON st.station_id = tmp.station_id AND st.dt = tmp.max_dt; ", sqlCondition); DaoEntity::execOnce(sql, result); if (result.size() > 0) { @@ -1292,20 +1310,20 @@ Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std //jsondata["launch_date"] = appdata.launchDate; //: 系统上线启用日期,格式:yyyy-mm-dd // jsondata["station_id"] = station_id; - jsondata["storage_elect_in"] = fields.value("storage_elect_in"); //储能充电电量(kWh),精度:0.001 - jsondata["storage_elect_out"] = fields.value("storage_elect_out"); //储能放电电量(kWh),精度:0.001 - jsondata["storage_num_in"] = fields.value("storage_elect_out"); //储能设备充电次数 - jsondata["storage_num_out"] = fields.value("storage_num_out"); //储能设备放电次数 - jsondata["storage_num_err"] = fields.value("storage_num_err"); //储能设备故障次数 - jsondata["solar_elect_gen"] = fields.value("solar_elect_gen"); //光伏发电电量(kWh),精度:0.001 - jsondata["solar_elect_grid"] = fields.value("solar_elect_grid"); //光伏入网电量(kWh),精度:0.001 - jsondata["solar_num_err"] = fields.value("solar_num_err"); //光伏设备故障次数 - jsondata["charge_elect"] = fields.value("charge_elect"); //充电设备充电电量(kWh),精度:0.001 - jsondata["charge_num"] = fields.value("charge_num"); //充电设备充电次数 - jsondata["charge_num_err"] = fields.value("charge_num_err"); //充电设备故障次数 - jsondata["income_elect"] = fields.value("income_elect"); //发电收益(元),精度:0.01 + jsondata["storage_elect_in"] = fields.value("E_in"); //储能充电电量(kWh),精度:0.001 + jsondata["storage_elect_out"] = fields.value("E_out"); //储能放电电量(kWh),精度:0.001 + jsondata["storage_num_in"] = fields.value("t_in"); //储能设备充电次数 + jsondata["storage_num_out"] = fields.value("t_out"); //储能设备放电次数 + jsondata["storage_num_err"] = fields.value("n_err"); //储能设备故障次数 + jsondata["solar_elect_gen"] = fields.value("E_gen"); //光伏发电电量(kWh),精度:0.001 + jsondata["solar_elect_grid"] = fields.value("E_grid"); //光伏入网电量(kWh),精度:0.001 + jsondata["solar_num_err"] = fields.value("n_err_solor"); //光伏设备故障次数 + jsondata["charge_elect"] = fields.value("E_charge"); //充电设备充电电量(kWh),精度:0.001 + jsondata["charge_num"] = fields.value("n_charge"); //充电设备充电次数 + jsondata["charge_num_err"] = fields.value("n_err_charge"); //充电设备故障次数 + jsondata["income_elect"] = fields.value("income"); //发电收益(元),精度:0.01 jsondata["income_charge"] = fields.value("income_charge"); //充电收益(元),精度:0.01 - jsondata["usage_rate"] = Utils::toStr(float(fields.get("storage_usage")+fields.get("storage_usage"))*0.5f, 0); + jsondata["usage_rate"] = 0; //Utils::toStr(float(fields.get("storage_usage") + fields.get("storage_usage")) * 0.5f, 0); json["data"] = jsondata; }