Files
energy_storage/src/protocol/HttpEntity.cpp

2212 lines
87 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "HttpEntity.h"
#include "database/Dao.h"
#include <functional>
#include "common/Utils.h"
#include "common/Snowflake.h"
#include "app/Application.h"
#include "app/AppData.h"
#include "app/Config.h"
#include "app/Station.h"
#include "app/Device.h"
#include "common/XlsxEntity.h"
static void FieldsToJson(Fields& fields, njson& json)
{
for (auto& item : fields.map())
{
json[item.first] = item.second;
}
}
static void JsonToFields(njson& json, std::vector<std::string> vecKeys, Fields& fields)
{
if (vecKeys.empty())
{
for (auto& item: json.items())
{
auto key = item.key();
auto& val = json[key];
}
}
for (auto& key : vecKeys)
{
if (json.contains(key)) {
switch (json[key].type())
{
case njson::value_t::string: { fields.set(key, json[key].get<std::string>()); } break;
case njson::value_t::boolean: { fields.set(key, json[key].get<bool>()); } break;
case njson::value_t::number_integer: { fields.set(key, json[key].get<int>()); } break;
case njson::value_t::number_unsigned: { fields.set(key, json[key].get<int>()); } break;
case njson::value_t::number_float: { fields.set(key, json[key].get<float>()); } break;
case njson::value_t::null: {} break;
case njson::value_t::object: { fields.set(key, json[key].dump()); } break;
case njson::value_t::array: { fields.set(key, json[key].dump()); } break;
case njson::value_t::binary: {} break;
case njson::value_t::discarded: {} break;
default:
break;
}
}
}
}
static njson FieldsToJsonArray(std::vector<Fields>& vecFields)
{
njson jsonnode = njson::array();
for (auto& fields : vecFields)
{
njson jnode;
for (auto& item : fields.map())
{
jnode[item.first] = item.second;
}
jsonnode.push_back(jnode);
}
return jsonnode;
}
static void GetRequestParams(const httplib::Request& req, const std::vector<std::string>& vecKeys, Fields& fields)
{
if (req.method == "GET")
{
for (auto& key : vecKeys)
{
if (req.has_param(key))
{
fields.set(key, req.get_param_value(key));
}
}
}
else if (req.method == "POST")
{
njson json;
JSON::parse(req.body, json);
JsonToFields(json, vecKeys, fields);
}
}
static void CheckRequiredParams(Fields& params, std::vector<std::string> keys, std::string& errmsg)
{
for (auto& key : keys)
{
if (!params.contains(key))
{
errmsg = "参数[" + key + "]错误";;
return;
}
}
}
class HttpHelper
{
public:
static bool CheckRequestParam(const httplib::Request& req, httplib::Response& resp, const std::vector<std::string>& vecKeys, std::string& errmsg)
{
errmsg = "";
for (auto& key : vecKeys)
{
bool hasParam = false;
if (req.method == "GET")
{
hasParam = req.has_param(key);
}
else
{
hasParam = (req.body.find("\"" + key + "\"") != std::string::npos);
}
if (!hasParam)
{
if (!errmsg.empty()) { errmsg += ","; }
errmsg += "缺少参数[" + key + "]";
}
}
if (!errmsg.empty())
{
return false;
}
return true;
}
static void setPagination(PageInfo& pageinfo, std::vector<Fields> result, njson& json)
{
json["count"] = pageinfo.total;
json["page"] = pageinfo.index;
json["page_size"] = pageinfo.size;
json["data"] = FieldsToJsonArray(result);
}
};
static std::map<std::string, HandlerOptions> g_mapHttpHandlerGet =
{
{"/queryBaseinfo", HandlerOptions(&HttpEntity::logqueryBaseinfoin, {})},
{"/login", HandlerOptions(&HttpEntity::login, {DMUser::ACCOUNT, DMUser::PASSWD})},
{"/queryUserList", HandlerOptions(&HttpEntity::queryUserList, {})},
{"/deleteUser", HandlerOptions(&HttpEntity::deleteUser, { DMUser::USER_ID})},
{"/queryPermissionList", HandlerOptions(&HttpEntity::queryPermissionList, {})},
{"/deletePermission", HandlerOptions(&HttpEntity::deletePermission, { DMPermission::PERMISSION_ID})},
{"/queryRoleList", HandlerOptions(&HttpEntity::queryRoleList, {})},
{"/deleteRole", HandlerOptions(&HttpEntity::deleteRole, { DMRole::ROLE_ID})},
{"/queryStationList", HandlerOptions(&HttpEntity::queryStationList, {})},
{"/deleteStation", HandlerOptions(&HttpEntity::deleteStation, { DMStation::STATION_ID})},
{"/queryStationInfo", HandlerOptions(&HttpEntity::queryStationInfo, { DMStation::STATION_ID})},
{"/queryStationData", HandlerOptions(&HttpEntity::queryStationData, { DMStation::STATION_ID})},
{"/queryStationOverview", HandlerOptions(&HttpEntity::queryStationOverview, {DMStation::STATION_ID})},
{"/queryStationTodayU", HandlerOptions(&HttpEntity::queryStationTodayU, {DMStation::STATION_ID, "category"})},
{"/queryStationTodayI", HandlerOptions(&HttpEntity::queryStationTodayI, {DMStation::STATION_ID, "category"})},
{"/queryStationTodayP", HandlerOptions(&HttpEntity::queryStationTodayP, {DMStation::STATION_ID, "category"})},
{"/queryDeviceList", HandlerOptions(&HttpEntity::queryDeviceList, {})},
{"/deleteDevice", HandlerOptions(&HttpEntity::deleteDevice, { DMDevice::DEVICE_ID})},
{"/queryDevicTypeDef", HandlerOptions(&HttpEntity::queryDevicTypeDef, {})},
{"/queryDevicByCategory", HandlerOptions(&HttpEntity::queryDevicByCategory, {DMStation::STATION_ID, "category"})},
{"/queryDevicCharts", HandlerOptions(&HttpEntity::queryDevicCharts, {DMStation::STATION_ID, "device_id"})},
{"/queryDeviceBCUDetail", HandlerOptions(&HttpEntity::queryDeviceBCUDetail, {DMStation::STATION_ID, "device_id"})},
{"/queryPolicyList", HandlerOptions(&HttpEntity::queryPolicyList, {})},
{"/deletePolicy", HandlerOptions(&HttpEntity::deletePolicy, { DMPolicy::POLICY_ID})},
{"/queryPolicyByType", HandlerOptions(&HttpEntity::queryPolicyByType, {"type"})},
{"/querySystemLogList", HandlerOptions(&HttpEntity::querySystemLogList, {})},
{"/queryAlertLogList", HandlerOptions(&HttpEntity::queryAlertLogList, {})},
{"/queryPredictionDetail", HandlerOptions(&HttpEntity::queryPredictionDetail, {})},
{"/queryStatSystem", HandlerOptions(&HttpEntity::queryStatSystem, {})},
{"/queryStatStation", HandlerOptions(&HttpEntity::queryStatStationGroup, {})},
{"/queryStatTotal", HandlerOptions(&HttpEntity::queryStatTotal, {})},
{"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})},
{"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})},
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
{"/exportStatReport", HandlerOptions(&HttpEntity::exportStatReport, {})},
{"/queryStatStationMode", HandlerOptions(&HttpEntity::queryStatStationMode, {})},
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
{"/queryServiceApiList", HandlerOptions(&HttpEntity::queryServiceApiList, {})},
{"/deleteServiceApi", HandlerOptions(&HttpEntity::deleteServiceApi, {"api_id"})},
{"/queryEGridPeriod", HandlerOptions(&HttpEntity::queryEGridPeriod, {})},
//{"/insert", HandlerOptions(&HttpEntity::insert, {})},
//{"/update", HandlerOptions(&HttpEntity::update, {})},
//{"/delete", HandlerOptions(&HttpEntity::delete, {})},
};
static std::map<std::string, HandlerOptions> g_mapHttpHandlerPost
{
{"/insertUser", HandlerOptions(&HttpEntity::insertUser, { DMUser::ACCOUNT})},
{"/updateUser", HandlerOptions(&HttpEntity::updateUser, { DMUser::USER_ID})},
{"/insertPermission", HandlerOptions(&HttpEntity::insertPermission, { DMPermission::NAME})},
{"/updatePermission", HandlerOptions(&HttpEntity::updatePermission, { DMPermission::PERMISSION_ID})},
{"/insertRole", HandlerOptions(&HttpEntity::insertRole, { DMRole::NAME})},
{"/updateRole", HandlerOptions(&HttpEntity::updateRole, { DMRole::ROLE_ID})},
{"/insertStation", HandlerOptions(&HttpEntity::insertStation, { DMStation::NAME})},
{"/updateStation", HandlerOptions(&HttpEntity::updateStation, { DMStation::STATION_ID})},
{"/insertDevice", HandlerOptions(&HttpEntity::insertDevice, { DMDevice::NAME})},
{"/updateDevice", HandlerOptions(&HttpEntity::updateDevice, { DMDevice::DEVICE_ID})},
{"/insertPolicy", HandlerOptions(&HttpEntity::insertPolicy, { DMPolicy::NAME})},
{"/updatePolicy", HandlerOptions(&HttpEntity::updatePolicy, { DMPolicy::POLICY_ID})},
{"/insertServiceApi", HandlerOptions(&HttpEntity::insertServiceApi, {})},
{"/updateServiceApi", HandlerOptions(&HttpEntity::updateServiceApi, {"api_id"})},
{"/updateGatewayParams", HandlerOptions(&HttpEntity::updateGatewayParams, {DMStation::STATION_ID})},
};
bool CheckHttpToken(const httplib::Request& req)
{
// 验证token
std::string token = req.get_param_value("token");
if (!token.empty())
{
User user = Application::data().getUser(token);
if (!user.userId.empty())
{
return true;
}
}
return false;
}
HttpEntity::HttpEntity()
{
for (auto& item : g_mapHttpHandlerGet)
{
std::string name = item.first;
HandlerOptions& handler = item.second;
this->httpsvr.Get(name, [=, &handler](const httplib::Request& req, httplib::Response& resp)
{
this->runHandler(name, handler, req, resp);
});
}
for (auto& item : g_mapHttpHandlerPost)
{
std::string name = item.first;
HandlerOptions& handler = item.second;
this->httpsvr.Post(name, [=](const httplib::Request& req, httplib::Response& resp)
{
this->runHandler(name, handler, req, resp);
});
}
}
void HttpEntity::listen(std::string addr, int port)
{
if (addr.empty()) addr = "0.0.0.0";
spdlog::info("[http] start listen: addr={}:{},token={}", addr, port, Config::option.http.useToken);
httpsvr.listen(addr, port); // 阻塞
}
void HttpEntity::runHandler(std::string name, const HandlerOptions& handler, const httplib::Request& req, httplib::Response& resp)
{
spdlog::info("[http] request: {}", name);
bool useToken = Config::option.http.useToken;
Errcode errcode = Errcode::OK;
std::string errmsg;
if (name != "/login" && useToken)
{
bool ret = CheckHttpToken(req);
errcode = ret ? Errcode::OK : Errcode::ERR_TOKEN;
}
njson jsonresp;
if (errcode == Errcode::OK)
{
if (!HttpHelper::CheckRequestParam(req, resp, handler.requiredKeys, errmsg))
{
errcode = Errcode::ERR_PARAM;
}
else
{
errcode = (this->*(handler.func))(req, jsonresp, errmsg);
}
}
jsonresp["errcode"] = errcode;
jsonresp["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg));
resp.set_content(jsonresp.dump(), "text/plain; charset=utf-8");
resp.status = 200;
spdlog::info("[http] request: {}, response: {}.", name, int(errcode));
}
void HttpEntity::registGet(std::string name, void (HttpEntity::* func)(const httplib::Request& req, httplib::Response& resp))
{
this->httpsvr.Get(name, std::bind(func, this, std::placeholders::_1, std::placeholders::_2));
}
Errcode HttpEntity::logqueryBaseinfoin(const httplib::Request& req, njson& json, std::string& errmsg)
{
json["data"] = {
{"encryption", Config::option.http.encryption},
{"encryptKey", Config::option.http.encryptKey},
{"latitude", Config::option.view.latitude},
{"longitude", Config::option.view.longitude},
{"altitude", Config::option.view.altitude}
};
return Errcode::OK;
}
Errcode HttpEntity::login(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string userId;
std::string token;
std::string account = req.get_param_value("account");
std::string passwd = req.get_param_value("passwd");
Fields fields;
auto dao = DaoEntity::create("");
Errcode err = DAO::login(dao, account, passwd, fields);
userId = fields.value(DMUser::USER_ID);
token = Application::data().userLogin(userId, account);
if (err == Errcode::OK)
{
json["token"] = token;
json["account"] = account;
std::vector<Fields> vecPermission;
int roleId = fields.get<int>(DMRole::ROLE_ID);
DAO::queryRolePermission(dao, roleId, vecPermission);
njson nodePermission = njson::array();
std::map<std::string, int> mapParentPos;
for (int i=0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
if (item.value("parent_id") == "")
{
mapParentPos[item.value("permission_id")] = i;
njson node;
FieldsToJson(item, node);
node["children"] = njson::array();
nodePermission.push_back(node);
}
}
// 重新遍历处理二级子权限,防止父权限信息还未创建时导致错误
for (int i = 0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
std::string id = item.value("permission_id");
std::string parentId = item.value("parent_id");
if (parentId != "")
{
auto iter = mapParentPos.find(parentId);
if (iter != mapParentPos.end())
{
njson node;
FieldsToJson(item, node);
nodePermission[iter->second]["children"].push_back(node);
}
}
}
json["permission"] = nodePermission;
}
DAO::insertSystemLogUser(token, "用户[" + account + "]登录:" + ErrcodeStr(err), (err==Errcode::OK) ? 1: 0);
return err;
}
Errcode HttpEntity::queryUserList(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string token = req.get_param_value("token");
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryUserList(pageinfo, result);
if (err == Errcode::OK)
{
HttpHelper::setPagination(pageinfo, result, json);
}
//DAO::insertSystemLogUser(token, "查询用户列表:" + ErrcodeStr(err), (err==Errcode::OK) ? 1 : 0);
return err;
}
Errcode HttpEntity::insertUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::insertUser(params);
}
Errcode HttpEntity::updateUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"user_id", "account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::updateUserById(params);
}
Errcode HttpEntity::deleteUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string userId = req.get_param_value("user_id");
return DAO::deleteUserById(userId);
}
Errcode HttpEntity::queryPermissionList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryPermissionList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
std::map<std::string, int> mapP;
for (int i = 0; i<result.size(); ++i)
{
auto& item = result[i];
std::string id = item.value("permission_id");
mapP[id] = json["data"].size() - 1;
}
std::vector<Fields> vecSubPermission;
DaoEntity::execOnce("SELECT * FROM permission WHERE permission.parent_id IS NOT NULL AND permission.parent_id!='';", vecSubPermission);
for (int i = 0; i<vecSubPermission.size(); ++i)
{
auto& item = vecSubPermission[i];
std::string parentId = item.value("parent_id");
std::string id = item.value("permission_id");
if (!parentId.empty())
{
if (mapP.count(parentId) > 0)
{
int index = mapP[parentId];
njson jsonnode;
FieldsToJson(item, jsonnode);
json["data"][index]["children"].push_back(jsonnode);
}
}
}
}
return err;
}
Errcode HttpEntity::insertPermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "describe", "is_open"}, params);
return DAO::insertPermission(params);
}
Errcode HttpEntity::updatePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"permission_id", "name", "describe", "is_open"}, params);
return DAO::updatePermissionById(params);
}
Errcode HttpEntity::deletePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string permissionId = req.get_param_value("permission_id");
return DAO::deletePermissionById(permissionId);
}
Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string token = req.get_param_value("page");
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryRoleList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
std::vector<Fields> vecPermission;
err = DAO::queryRolePermission(NULL, vecPermission);
if (err != Errcode::OK)
{
return err;
}
std::map<std::string, std::vector<int>> mapRole;
std::map<std::string, std::vector<int>> mapChildren;
for (int i=0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
std::string roleId = item.value("role_id");
std::string parentId = item.value("parent_id");
mapRole[roleId].push_back(i);
if (parentId != "")
{
mapChildren[roleId + "-" + parentId].push_back(i);
}
}
for (auto& item : json["data"])
{
auto jsonpermission = njson::array();
std::string roleId = item["role_id"];
for (auto& fieldsPos : mapRole[roleId])
{
auto& fields = vecPermission[fieldsPos];
string parentId = fields.value("parent_id");
string permissionId = fields.value("permission_id");
if (parentId == "")
{
njson node;
FieldsToJson(fields, node);
njson nodeChildren = njson::array();
auto iter = mapChildren.find(roleId + "-" + permissionId);
if (iter != mapChildren.end())
{
for (auto& fieldsChildPos : iter->second)
{
njson nodeChild;
FieldsToJson(vecPermission[fieldsChildPos], nodeChild);
nodeChildren.push_back(nodeChild);
}
}
node["children"] = nodeChildren;
jsonpermission.push_back(node);
}
}
item["permission"] = jsonpermission;
}
}
return err;
}
Errcode HttpEntity::queryRolePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"role_id"}, params);
if (!params.contains("role_id")) { errmsg = "缺少参数[role_id]"; return Errcode::ERR_PARAM; }
return Errcode::OK;
}
Errcode HttpEntity::insertRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "describe", "is_open", "permission"}, params);
return DAO::insertRole(params);
};
static void JsonToFieldsRole(string roleId, njson& item, Fields& fields)
{
fields.set("role_id", roleId);
fields.set("permission_id", item["permission_id"].get<std::string>());
fields.set("is_open", item["is_open"].get<std::string>());
fields.set("is_view", item["is_view"].get<std::string>());
fields.set("is_add", item["is_add"].get<std::string>());
fields.set("is_edit", item["is_edit"].get<std::string>());
fields.set("is_del", item["is_del"].get<std::string>());
}
Errcode HttpEntity::updateRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
auto roleId = params.value("role_id");
std::string permission = params.remove("permission");
auto dao = DaoEntity::create("");
auto err = Errcode::OK;
if (params.size() > 1)
{
err = DAO::updateRoleById(dao, params);
}
if (err == Errcode::OK && !permission.empty())
{
njson jsonarray;
if (JSON::parse(permission, jsonarray))
{
std::vector<Fields> vecFields;
for (auto& item: jsonarray)
{
Fields fields;
JsonToFieldsRole(roleId, item, fields);
vecFields.push_back(fields);
if (item.contains("children"))
{
for (auto& item : item["children"])
{
Fields fields;
JsonToFieldsRole(roleId, item, fields);
vecFields.push_back(fields);
}
}
}
err = DAO::updateRolePermission(dao, roleId, vecFields);
}
}
return err;
};
Errcode HttpEntity::deleteRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string roleId = req.get_param_value(DMRole::ROLE_ID);
return DAO::remove(NULL, DMRole::TABLENAME, DMRole::ROLE_ID, roleId);
};
Errcode HttpEntity::queryStationList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryStationList(pageinfo, result);
for (auto& item : result)
{
int stationId = item.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station)
{
item.set("err", station->err);
}
}
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
return DAO::insertStation(params);
};
Errcode HttpEntity::updateStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "name", "address", "lon", "lat", "tel", "capacity", "status", "work_mode", "policy_id", "operation_date"}, params);
std::string stationId = params.value("station_id");
params.check("capacity", "", "0.0");
params.check("lon", "", "0.0");
params.check("lat", "", "0.0");
params.check("status", "", "1");
params.check("policy_id", "", "NULL");
params.check("operation_date", "", "NULL");
Errcode err = DAO::updateStationById(params);
if (err == Errcode::OK)
{
std::string sql = "SELECT s.*, p.name policy_name, p.`type` policy_type, p.value FROM station s LEFT JOIN policy p ON s.policy_id=p.policy_id"
" WHERE s.station_id='" + stationId + "';";
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
if (ret != 0)
{
spdlog::error("[http] update station success, set station cache error, station_id={}", stationId);
}
else
{
auto station = Application::data().getStation(Utils::toInt(stationId));
if (result.size() > 0 && station)
{
station->setFields(result[0]);
}
}
}
// 发送指令到网关
if (params.contains("station_id") && params.contains("work_mode"))
{
int stationId = params.get<int>("station_id");
int workmode = params.get<int>("work_mode");
auto station = Application::data().getStation(stationId);
if (station)
{
station->setGarewayWorkMode();
// 根据 work_mode 到数据库查询策略信息
std::string sql = std::format("select * from policy where `type`='{}'", workmode);
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
if (result.size() > 0)
{
auto& item = result[0];
std::string valJson = item.value("value");
njson json = njson::parse(valJson);
if (json.is_object())
{
// 设置 station 的网关参数,然后调用 setGarewayParams 向网关发送指令
if (workmode == 6)
{
if (json.contains("soc_min")) { station->gatewayParam.socMin = Utils::toFloat(json["soc_min"])*100; }
if (json.contains("soc_max")) { station->gatewayParam.socMax = Utils::toFloat(json["soc_max"])*100; }
}
else if (workmode == 7)
{
//if (json.contains("charge")) { station->gatewayParam.powerCharge = json["charge"].get<float>(); }
//if (json.contains("discharge")) { station->gatewayParam.powerDischarge = json["discharge"].get<float>(); }
}
else if (workmode == 8)
{
if (json.contains("charge")) { station->gatewayParam.powerCharge = Utils::toInt(json["charge"]); }
if (json.contains("discharge")) { station->gatewayParam.powerDischarge = Utils::toInt(json["discharge"]); }
if (json.contains("power_reverse")) { station->gatewayParam.backflow = Utils::toInt(json["power_reverse"]); }
}
else if (workmode == 9)
{
if (json.contains("charge")) { station->gatewayParam.powerCharge = Utils::toInt(json["charge"]); }
if (json.contains("discharge")) { station->gatewayParam.powerDischarge = Utils::toInt(json["discharge"]); }
}
}
//station->setGarewayParams();
}
////params.get("work_mode", station->workMode);
//ps.get("soc_min", station->gatewayParam.socMin); // 储能放电下限值 SOC 40038 (%, 0-99)
//ps.get("soc_max", station->gatewayParam.socMax); // 储能充电上限值 SOC 40039 (%:1-100)
//ps.get("capacity", station->gatewayParam.capacity); // 台区变压器容量 40040 (KVA 160-1600)
//ps.get("power_safe", station->gatewayParam.powerSafe); // 安全输入功率 40041 (KW 0-400)
//ps.get("power_discharge", station->gatewayParam.powerDischarge); // 储能最大放电功率 40042 (1KW 0-150)
//ps.get("power_charge", station->gatewayParam.powerCharge); // 储能最大充电功率 40043 (1KW 0-150)
//ps.get("backflow", station->gatewayParam.backflow); // 防逆流回差 40058(1KW 10-300)
//ps.get("overload", station->gatewayParam.overload); // 防过载回差 40059(1KW 10-300)
}
}
return err;
};
Errcode HttpEntity::deleteStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string primaryKey = DMStation::STATION_ID;
return DAO::remove(NULL, DMStation::TABLENAME, primaryKey, req.get_param_value(primaryKey));
};
Errcode HttpEntity::queryStationOverview(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id"}, params);
std::string stationId = params.value("station_id");
if (stationId.empty())
{
return Errcode::ERR_PARAM;
}
auto dao = DaoEntity::create("");
std::vector<Fields> result;
// 运行模式
std::string sql = "SELECT * FROM station WHERE station_id='" + stationId + "';";
int ret = dao->exec(sql, result);
if (ret != 0)
{
return Errcode(ret);
}
if (result.size() > 0)
{
json["data"]["work_mode"] = result[0].get<int>("work_mode");
}
// 储能设备:总功率,数量
// 充电设备:总功率,数量
// 光伏设备:总功率,数量
sql = R"(SELECT d.`type`, count(1) count, ddt.name typename, ddt.category FROM device d
LEFT JOIN def_device_type ddt ON ddt.device_type_id=d.`type` WHERE d.station_id=')" + stationId + "' GROUP BY `type`;";
ret = dao->exec(sql, result);
if (ret != 0)
{
return Errcode(ret);
}
njson jsonStorage = njson::parse(R"({"category":1, "count":0, "power":0.0})");
njson jsonCharge = njson::parse(R"({"category":2, "count":0, "power":0.0})");
njson jsonSolar = njson::parse(R"({"category":3, "count":0, "power":0.0})");
njson jsonSecurity = njson::parse(R"({"category":4, "count":0, "power":0.0})");
//auto station = Application::data().getStation(Utils::toInt(stationId));
//if (station)
//{
// jsonStorage["msg"] = station->getGatewayParam();
// jsonStorage["workmode"] = station->getGatewayMode();
// jsonStorage["emu"] = station->emuStatus == 1 ? "在线" : (station->emuStatus == 0 ? "离线" : "--");
// jsonStorage["cdz"] = station->cdzStatus == 1 ? "在线" : (station->cdzStatus == 0 ? "离线" : "--");
//}
auto videoInfo = Config::getVideoInfo(stationId);
if (videoInfo)
{
jsonSecurity["host"] = videoInfo->host;
jsonSecurity["port"] = videoInfo->port;
jsonSecurity["user"] = videoInfo->user;
jsonSecurity["passwd"] = videoInfo->passwd;
}
for (auto& fields : result)
{
int category = fields.get<int>("category");
int count = fields.get<int>("count");
switch (category)
{
case 1: { jsonStorage["count"] = jsonStorage["count"].get<int>() + count; } break;
case 2: { jsonCharge["count"] = jsonCharge["count"].get<int>() + count; } break;
case 3: { jsonSolar["count"] = jsonSolar["count"].get<int>() + count; } break;
case 4: { jsonSecurity["count"] = jsonSecurity["count"].get<int>() + count; } break;
default:
break;
}
}
// 从运行数据中读取功率信息(待补充)
json["data"]["device_group"] = {jsonStorage, jsonCharge, jsonSolar, jsonSecurity};
return Errcode::OK;
}
Errcode HttpEntity::queryStationInfo(const httplib::Request& req, njson& json, std::string& errmsg)
{
// 查询场站的基础配置信息
std::string stationId = req.get_param_value("station_id");
if (stationId.empty())
{
return Errcode::ERR_PARAM;
}
std::string sql = "SELECT * FROM " + DMStation::TABLENAME + " WHERE station_id=" + stationId + ";";
std::vector<Fields> result;
Errcode err = DAO::exec(NULL, sql, result);
if (err != Errcode::OK)
{
return err;
}
if (result.size() == 0)
{
return Errcode::ERR_DATA_NUL;
}
auto& fields = result[0];
njson jsondata;
std::string attr = fields.remove(DMStation::ATTR);
JSON::parse(attr, jsondata);
FieldsToJson(fields, jsondata);
json["data"] = jsondata;
return Errcode::OK;
// work_mode: 运行模式:
// capacity: 储能容量:
// {"batttey_type": "磷酸铁锂", "cooling_type":"风冷", "voltage_rated":"300", "power_rated": "1500"}
// batttey_type: 电池类型:
// cooling_type: 冷却方式:
// voltage_rated: 电池额定电压:
// power_rated: PCS额定功率
}
Errcode HttpEntity::queryStationData(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
auto station = Application::data().getStation(Utils::toInt(stationId));
njson jsondata;
if (station)
{
/// 储能:电压、电流、功率、功率因数
{
njson json = njson::object();
json["U"] = Utils::toStr(station->storage.voltage);
json["I"] = Utils::toStr(station->storage.current);
json["P"] = Utils::toStr(station->storage.power);
//json["PF"] = Utils::toStr(station->storage.powerFactor, 1);
jsondata["storage"] = json;
}
/// 充电:电压、电流、功率、功率因数
{
njson json = njson::object();
json["U"] = Utils::toStr(station->charge.connector1.voltage);
json["I"] = Utils::toStr(station->charge.connector1.current);
json["P"] = Utils::toStr(station->charge.connector1.power);
jsondata["charge"] = json;
}
/// 光伏
{
njson json = njson::object();
json["P"] = Utils::toStr(station->pv.power);
jsondata["pv"] = json;
}
/// 电网
{
njson json = njson::object();
json["U"] = Utils::toStr(station->grid.voltage);
json["I"] = Utils::toStr(station->grid.current);
json["P"] = Utils::toStr(station->grid.power);
//json["PF"] = Utils::toStr(station->grid.powerFactor, 1);
jsondata["grid"] = json;
}
/// 环境:温度、湿度
{
njson json = njson::object();
json["envTemp"] = Utils::toStr(station->temperature, 0);
json["envhum"] = Utils::toStr(station->humidity, 0);
json["aircStatus"] = station->aircStatus;
json["coolingStatus"] = station->coolingStatus;
jsondata["env"] = json;
}
}
json["data"] = jsondata;
return Errcode::OK;
}
static njson VectorToJsonArray(vector<float>& vec, int n)
{
njson jsonArray = njson::array();
for (int i = 0; i <= n && i < vec.size(); ++i)
{
jsonArray.push_back(int(vec[i]));
}
return jsonArray;
}
// 获取场站今日电压曲线数据category: 1储能2充电3光伏
Errcode HttpEntity::queryStationTodayU(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
std::string catogray = req.get_param_value("category");
njson jsondata;
auto station = Application::data().getStation(Utils::toInt(stationId));
if (station)
{
int n = Utils::timeDaySeconds() / 600;
if (catogray == "1")
{
auto device = station->getDeviceByType(int(EDeviceType::BMS), "1"); // 使用 BMS 的数据
if (device) {
jsondata["U"] = VectorToJsonArray(device->cacheU, n);
jsondata["I"] = VectorToJsonArray(device->cacheI, n);
jsondata["P"] = VectorToJsonArray(device->cacheP, n);
}
}
else if (catogray == "2")
{
auto device = station->getDeviceByType(int(EDeviceType::CHARGER), "1");
if (device) {
jsondata["U"] = VectorToJsonArray(device->cacheU, n);
jsondata["I"] = VectorToJsonArray(device->cacheI, n);
jsondata["P"] = VectorToJsonArray(device->cacheP, n);
}
}
else if (catogray == "3")
{
}
}
json["data"] = jsondata;
return Errcode::OK;
}
// 获取场站今日电流曲线数据category: 1储能2充电3光伏
Errcode HttpEntity::queryStationTodayI(const httplib::Request& req, njson& json, std::string& errmsg)
{
return Errcode::OK;
}
// 获取场站今日功率曲线数据category: 1储能2充电3光伏
Errcode HttpEntity::queryStationTodayP(const httplib::Request& req, njson& json, std::string& errmsg)
{
return Errcode::OK;
}
Errcode HttpEntity::queryDeviceList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
string stationId = req.get_param_value("station_id");
std::vector<Fields> result;
auto err = DAO::queryDeviceListByStation(pageinfo, stationId, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
Errcode err = DAO::insertDevice(params);
if (err == Errcode::OK)
{
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station) { station->addDevice(params); }
}
return err;
};
Errcode HttpEntity::updateDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
Errcode err = DAO::updateDeviceById(params);
if (err == Errcode::OK)
{
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station) { station->addDevice(params); }
}
return err;
};
Errcode HttpEntity::deleteDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string primaryKey = DMDevice::DEVICE_ID;
return DAO::remove(NULL, DMDevice::TABLENAME, primaryKey, req.get_param_value(primaryKey));
};
Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string sql = "SELECT device_type_id, name FROM def_device_type;";
std::vector<Fields> result;
auto err = DAO::exec(NULL, sql, result);
json["data"] = FieldsToJsonArray(result);
return err;
}
Errcode HttpEntity::queryDevicByCategory(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("category")) { errmsg = "缺少参数[category]"; return Errcode::ERR_PARAM; }
int stationId = params.get<int>("station_id");
int category = params.get<int>("category");
njson jsondata = njson::array();
auto station = Application::data().getStation(stationId);
if (station)
{
std::vector<std::shared_ptr<Device>> vecDevice;
station->getDeviceByCategory(category, vecDevice);
for(auto& device: vecDevice)
{
if (device->isOpen)
{
njson jsonnode;
jsonnode["stationId"] = stationId;
jsonnode["category"] = category;
jsonnode["device_id"] = device->deviceId;
jsonnode["name"] = device->name;
jsonnode["code"] = device->code;
jsonnode["type"] = device->type;
jsonnode["typename"] = Application::data().getDeviceNameById(device->type);
jsonnode["view"] = 1;
jsonnode["is_online"] = device->online;// ? "在线" : "离线";
jsonnode["is_error"] = device->err;// ? "故障" : "正常";
jsonnode["is_running"] = device->running;// ? "工作" : "空闲";
{
VecPairSS vec;
device->getRuntimeParams(vec);
njson jsonarrayParams = njson::array();
for (auto& item: vec)
{
jsonarrayParams.push_back({{"k", item.first}, {"v", item.second}});
}
jsonnode["params"] = jsonarrayParams;
}
if (device->type == 106)
{
VecPairSS vec;
device->getRuntimeParams1(vec);
njson jsonarrayParams = njson::array();
for (auto& item: vec)
{
jsonarrayParams.push_back({{"k", item.first}, {"v", item.second}});
}
jsonnode["params1"] = jsonarrayParams;
}
jsondata.push_back(jsonnode);
}
}
}
json["data"] = jsondata;
njson jsongateway = njson::object();
if (station)
{
jsongateway["msg"] = station->getGatewayParam();
jsongateway["workmode"] = station->getGatewayMode();
jsongateway["emu"] = station->emuStatus == 1 ? "在线" : (station->emuStatus == 0 ? "离线" : "--");
jsongateway["cdz"] = station->cdzStatus == 1 ? "在线" : (station->cdzStatus == 0 ? "离线" : "--");
jsongateway["soc_min"] = station->gatewayParam.socMin;
jsongateway["soc_max"] = station->gatewayParam.socMax;
jsongateway["capacity"] = station->gatewayParam.capacity;
jsongateway["power_safe"] = station->gatewayParam.powerSafe;
jsongateway["power_discharge"] = station->gatewayParam.powerDischarge;
jsongateway["power_charge"] = station->gatewayParam.powerCharge;
jsongateway["backflow"] = station->gatewayParam.backflow;
jsongateway["overload"] = station->gatewayParam.overload;
}
json["gateway"] = jsongateway;
return Errcode::OK;
}
Errcode HttpEntity::queryDevicCharts(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "device_id"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; }
int stationId = params.get<int>("station_id");
int deviceId = params.get<int>("device_id");
auto device = Application::data().getDevice(stationId, deviceId);
int npos = Utils::timeDaySeconds() / 600;
std::vector<int> vecU(npos, 0);
std::vector<int> vecI(npos, 0);
std::vector<int> vecP(npos, 0);
if (device)
{
for (size_t i = 0; i < npos; ++i)
{
if (i < device->cacheU.size()) vecU[i] = int(device->cacheU[i]);
if (i < device->cacheI.size()) vecI[i] = int(device->cacheI[i]);
if (i < device->cacheP.size()) vecP[i] = int(device->cacheP[i]);
}
}
json["data"] = {{"V", vecU}, {"I", vecI}, {"P", vecP}};
return Errcode::OK;
}
Errcode HttpEntity::queryDeviceBCUDetail(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "device_id"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; }
int stationId = params.get<int>("station_id");
int deviceId = params.get<int>("device_id");
auto device = Application::data().getDevice(stationId, deviceId);
njson jsondata = njson::array();
if (device)
{
for (int i = 0; i<=device->bcuCount && i<device->vecBCUUnit.size(); ++i)
{
auto& row = device->vecBCUUnit[i];
std::string soc = Utils::toStr(row[0], 1);
std::string soh = Utils::toStr(row[1], 1);
std::string u = Utils::toStr(row[2], 3);
std::string t = Utils::toStr(row[3], 2);
std::string r_i = Utils::toStr(row[4], 0);
jsondata.push_back({{"SOC", soc}, {"SOH", soh}, {"V", u}, {"T", t}, {"R_i", r_i}});
}
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryPolicyList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryPolicyList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertPolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"type", "name", "describe", "value", "is_open"}, params);
return DAO::insertPolicy(params);
};
Errcode HttpEntity::updatePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"policy_id", "type", "name", "describe", "value", "is_open"}, params);
auto err = DAO::updatePolicyById(params);
if (err == Errcode::OK)
{
int policyId = params.get<int>("policy_id");
auto policy = Application::data().getPolicyById(policyId);
if (policy)
{
policy->setFields(params);
}
}
return err;
};
Errcode HttpEntity::deletePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"policy_id"}, params);
return DAO::deletePolicyById(params.value("policy_id"));
};
Errcode HttpEntity::queryPolicyByType(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string type = req.get_param_value("type");
std::string sql = "SELECT policy_id, `type`, name from policy WHERE `type`='" + type + "';";
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
json["data"] = FieldsToJsonArray(result);
return Errcode(ret);
}
Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id"}, params);
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::string stationId = params.value("station_id");
std::vector<Fields> result;
auto err = DAO::querySystemLogList(stationId, pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
//Errcode insertSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode HttpEntity::updateSystemLog(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"log_id", "status"}, params);
return DAO::updateSystemLogById(params);
}
Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id"}, params);
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::string stationId = params.value("station_id");
std::vector<Fields> result;
auto err = DAO::queryAlertLogList(stationId, pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
//Errcode insertAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode HttpEntity::updateAlertLog(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"log_id", "status"}, params);
return DAO::updateAlertLogById(params);
}
Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, njson& json, std::string& errmsg)
{
const int num = 144;
std::vector<int> vecStoreIn(num, 0), vecStoreOut(num, 0), vecCharge(num, 0), vecSolar(num, 0), vecSolarP(num, 0);
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];
vecStoreOut[i] += station->predictStorageOut[i];
vecCharge[i] += station->predictCharge[i];
vecSolar[i] = 0;
vecSolarP[i] = 0;
}
}
json["data"] = {
{"W_store_in", vecStoreIn},
{"W_store_out", vecStoreOut},
{"W_charge", vecCharge},
{"W_solar", vecSolar},
{"P_solar", vecSolarP }
};
return Errcode::OK;
}
static void VerifyRequstParamsStatDate(Fields& params)
{
if (!params.contains("end_date"))
{
if (!params.contains("start_date"))
{
params.set("end_date", Utils::dateStr());
params.set("start_date", Utils::dateStr(Utils::date() - 86400 * 7));
}
else
{
params.set("end_date", Utils::dateStr(Utils::time(params.value("start_date") + " 00:00:00") + 86400 * 7));
}
}
}
static std::string VerifyStatSqlCondition(Fields& params)
{
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string dtStart = params.value("start_date");
std::string dtEnd = params.value("end_date");
std::string sqlCondition;
if (!dtStart.empty() && dtEnd.empty())
{
sqlCondition += "dt BETWEEN '" + dtStart + "' AND '" + dtEnd + "'";
}
if (!stationId.empty())
{
if (!sqlCondition.empty()) sqlCondition += " AND ";
sqlCondition += "ss.station_id='" + stationId + "'";
}
if (!category.empty() && category != "0")
{
//if (!sqlCondition.empty()) sqlCondition += " AND ";
//sqlCondition += "ss.category='" + category + "'";;
}
if (!sqlCondition.empty()) { sqlCondition = " WHERE " + sqlCondition; }
return sqlCondition;
}
static std::string GetRequestStatParams(const httplib::Request& req, Fields& params)
{
GetRequestParams(req, { "station_id", "category", "start_date", "end_date" }, params);
VerifyRequstParamsStatDate(params);
return VerifyStatSqlCondition(params);
}
static string GetStationStatusStr(int status)
{
if (status == 1) return "空闲";
else if (status == 2) return "充电";
else if (status == 3) return "放电";
else if (status == 9) return "故障";
else return "离线";
}
Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
std::string sqlCondition = GetRequestStatParams(req, params);
njson jsondata;
std::string launchDate;
float incomeTotal{};
int storageDeviceNum = 0;
int chargeDeviceNum = 0;
int solarDeviceNum = 0;
int capacityTotal{};
bool isQueryStation = params.contains("station_id");
if (isQueryStation)
{
std::string stationId = params.value("station_id");
auto station = Application::data().getStation(Utils::toInt(stationId));
if (station)
{
launchDate = station->launchDate;
storageDeviceNum = 1; //: 储能设备数量
chargeDeviceNum = station->getDeviceCount(2); //: 光伏设备数量
solarDeviceNum = station->getDeviceCount(3); //: 光伏设备数量
capacityTotal = station->capacity; // : 储能总容量kWh精度0.001
jsondata["storage_status"] = GetStationStatusStr(station->storage.status);
jsondata["charge_status"] = GetStationStatusStr(station->charge.status);
jsondata["pv_status"] = "离线";
}
}
else
{
auto& appdata = Application::data();
launchDate = appdata.launchDate; //: 系统上线启用日期格式yyyy-mm-dd
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
storageDeviceNum += 1;
chargeDeviceNum += station->getDeviceCount(2);
solarDeviceNum += station->getDeviceCount(3);
capacityTotal += station->capacity;
}
}
jsondata["launch_date"] = launchDate; // 场站上线启用日期格式yyyy-mm-dd
jsondata["storage_device_num"] = storageDeviceNum; //: 储能设备数量
jsondata["charge_device_num"] = chargeDeviceNum; //: 储能设备数量
jsondata["income_total"] = incomeTotal; // : 累计收益精度0.01
jsondata["solar_device_num"] = solarDeviceNum; //: 光伏设备数量
jsondata["capacity_total"] = capacityTotal; // : 储能总容量kWh精度0.001
// 从 stat_total 表中查询日期最新的一条数据
std::vector<Fields> result;
std::string sql = std::format("SELECT st.* 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);
int eIn = 0;
int eOut = 0;
int tIn = 0;
int tOut = 0;
int nErr = 0;
int eGen = 0;
int eGrid = 0;
int eCharge = 0;
int income = 0;
int incomeCharge = 0;
for (int i=0; i<result.size(); ++i)
{
auto& fields = result[i];
if (isQueryStation)
{
if (params.value("station_id") == fields.value("station_id"))
{
eIn = fields.get<int>("E_in");
eOut = fields.get<int>("E_out");
tIn = fields.get<int>("t_in");
tOut = fields.get<int>("t_out");
eGen = fields.get<int>("E_gen");
eGrid = fields.get<int>("E_grid");
eCharge = fields.get<int>("E_charge");
income = fields.get<int>("income");
}
}
else
{
eIn += fields.get<int>("E_in");
eOut += fields.get<int>("E_out");
tIn += fields.get<int>("t_in");
tOut += fields.get<int>("t_out");
eGen += fields.get<int>("E_gen");
eGrid = fields.get<int>("E_grid");
eCharge += fields.get<int>("E_charge");
income += fields.get<int>("income");
}
}
jsondata["storage_elect_in"] = eIn; //储能充电电量kWh精度0.001
jsondata["storage_elect_out"] = eOut; //储能放电电量kWh精度0.001
jsondata["storage_num_in"] = tIn; //储能设备充电次数
jsondata["storage_num_out"] = tOut; //储能设备放电次数
//jsondata["storage_num_err"] = fields.value("n_err"); //储能设备故障次数
jsondata["solar_elect_gen"] = eGen; //光伏发电电量kWh精度0.001
jsondata["solar_elect_grid"] = eGrid; //光伏入网电量kWh精度0.001
//jsondata["solar_num_err"] = fields.value("n_err_solor"); //光伏设备故障次数
jsondata["charge_elect"] = eCharge; //充电设备充电电量kWh精度0.001
//jsondata["charge_num"] = fields.value("n_charge"); //充电设备充电次数
//jsondata["charge_num_err"] = fields.value("n_err_charge"); //充电设备故障次数
jsondata["income_elect"] = income; //发电收益精度0.01
//jsondata["income_charge"] = fields.value("income_charge"); //充电收益精度0.01
//jsondata["usage_rate"] = 0; //Utils::toStr(float(fields.get<int>("storage_usage") + fields.get<int>("storage_usage")) * 0.5f, 0);
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg)
{
auto& appdata = Application::data();
float income = 0.0;
int nStation = 0;
int nSolar {};
int capacity {};
int eGen {};
int eGrid {};
int eIn {};
int eOut {};
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
nStation += 1;
nSolar += station->getDeviceCount(3);
capacity += station->capacity;
eGen += station->electGenTotal;
eGrid += station->electGridTotal;
eIn += station->statData.totalElectIn;
eOut += station->statData.totalElectOut;
}
njson jsondata;
jsondata["launch_date"] = appdata.launchDate; //: 系统上线启用日期格式yyyy-mm-dd
jsondata["income_total"] = income; // : 累计收益精度0.01
jsondata["storage_device_num"] = nStation; //: 储能设备数量
jsondata["solar_device_num"] = nSolar; //: 光伏设备数量
jsondata["capacity_total"] = capacity; // : 储能总容量kWh精度0.001
jsondata["solar_elect_gen"] = eGen; // : 发电总电量kWh精度0.001
jsondata["solar_elect_grid"] = eGrid; // : 入网总电量kWh精度0.001
jsondata["storage_elect_in"] = eIn; // : 储能充电总电量kWh精度0.001
jsondata["storage_elect_out"] = eOut; // : 储能放电总电量kWh精度0.001
// 总览页面:累计收益
std::string sql = "SELECT 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; ";
std::vector<Fields> result;
DAO::exec(NULL, sql, result);
for (auto& item: result)
{
income += item.get<float>("income");
}
jsondata["income_total"] = income;
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryStatStationGroup(const httplib::Request& req, njson& json, std::string& errmsg)
{
njson jsondata = njson::array();
auto dao = DaoEntity::create("");
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<Fields> vecStations;
auto err = dao->exec(sql, vecStations);
for (auto& fields: vecStations)
{
njson jsonnode;
jsonnode["station_name"] = fields.value("station_name");
jsonnode["income"] = fields.get<float>("income");
jsonnode["usage_rate"] = fields.get<float>("usage");
jsondata.push_back(jsonnode);
}
json["data"] = jsondata;
return Errcode(err);
}
Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string startDate = params.value("start_date");
std::string endDate = params.value("end_date");
if (endDate.empty())
{
int64_t t = Utils::time();
endDate = Utils::dateStr(t);
startDate = Utils::dateStr(t - 86400*7);
}
std::vector<Fields> result;
auto err = DAO::queryStatStationGroup(NULL, stationId, category, startDate, endDate, result);
if (!startDate.empty() && !endDate.empty())
{
std::map<std::string, Fields*> mapTemp;
for (auto& item: result)
{
auto& dt = item.value("dt");
mapTemp[dt] = &item;
}
int64_t t0 = Utils::time(startDate + " 00:00:00");
int64_t t1 = Utils::time(endDate + " 00:00:00");
njson jsondata = njson::array();
for (int64_t t = t0; t<=t1; t += 86400)
{
njson jsonrow;
std::string dt = Utils::dateStr(t);
Fields* fields = NULL;
auto iter = mapTemp.find(dt);
if (iter != mapTemp.end()) { fields = iter->second; }
jsonrow["dt"] = dt.substr(5);
jsonrow["storage_elect_in"] = fields ? fields->value("storage_elect_in") : "0";
jsonrow["storage_elect_out"] = fields ? fields->value("storage_elect_out") : "0";
jsonrow["storage_num_in"] = fields ? fields->value("storage_num_in") : "0";
jsonrow["storage_num_out"] = fields ? fields->value("storage_num_out") : "0";
jsonrow["storage_num_err"] = fields ? fields->value("storage_num_err") : "0";
jsonrow["solar_elect_gen"] = fields ? fields->value("solar_elect_gen") : "0";
jsonrow["solar_elect_grid"] = fields ? fields->value("solar_elect_grid") : "0";
jsonrow["solar_num_err"] = fields ? fields->value("solar_num_err") : "0";
jsonrow["storage_usage"] = fields ? fields->value("storage_usage") : "0";
jsonrow["charge_elect"] = fields ? fields->value("charge_elect") : "0";
jsonrow["charge_num"] = fields ? fields->value("charge_num") : "0";
jsonrow["charge_num_err"] = fields ? fields->value("charge_num_err") : "0";
jsonrow["charge_usage"] = fields ? fields->value("charge_usage") : "0";
jsonrow["income_elect"] = fields ? fields->value("income_elect") : "0";
jsonrow["income_charge"] = fields ? fields->value("income_charge") : "0";
jsondata.push_back(jsonrow);
}
json["data"] = jsondata;
}
else
{
json["data"] = FieldsToJsonArray(result);
}
return err;
}
//Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
//{
// std::string sqlCondition = GetRequestStatParams(req);
// std::string sql = R"(SELECT ss.*, d.name device_name, ddt.name device_type FROM stat_day ss
// LEFT JOIN device d ON d.device_id = ss.device_id
// LEFT JOIN def_device_type ddt ON ddt.device_type_id = d.`type`)" + sqlCondition + ";";
//
// std::vector<Fields> result;
// int ret = DaoEntity::execOnce(sql, result);
// json["data"] = FieldsToJsonArray(result);
// return Errcode(ret);
//}
Errcode HttpEntity::queryStatDetailList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
std::vector<Fields> result;
auto err = DAO::queryStatStationList(pageinfo, params, result);
//json["data"] = FieldsToJsonArray(result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
Errcode HttpEntity::queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string dt = req.get_param_value("dt");
std::string stationId = req.get_param_value("station_id");
std::string category = req.get_param_value("category");
if (stationId.empty()) { errmsg = "参数[station_id]错误"; return Errcode::ERR_PARAM; }
if (category.empty()) { errmsg = "参数[category]错误"; return Errcode::ERR_PARAM; }
if (dt.empty()) { dt=Utils::dateStr(); }
njson jsondata;
std::string sql = R"(SELECT hd.*, d.`type` device_type, d.code, ddt.category FROM history_day hd
LEFT JOIN device d ON d.device_id = hd.device_id
LEFT JOIN def_device_type ddt ON d.`type` = ddt.device_type_id
WHERE dt=')" + dt + "' AND d.station_id='" + stationId + "' AND ddt.category='" + category + "';";
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
if (ret != 0)
{
return Errcode(ret);
}
std::vector<double> vecV;
std::vector<double> vecI;
std::vector<double> vecP;
for (auto fields : result)
{
int datetype = fields.get<int>("datatype"); // 1: 电压2电流3功率
std::string val = fields.value("value"); // JSON 数组(double)
int deviceType = fields.get<int>("device_type");
int deviceCode = fields.get<int>("code");
if (category == "1")
{
if (!(deviceType == int(EDeviceType::BMS))) // 储能BMS储能设备以BMS电池的数据作为总数据来展示
{
continue;
}
}
njson jsonval;
if (JSON::parse(val, jsonval))
{
for (int i = 0; i<jsonval.size(); ++i)
{
double val = jsonval[i];
if (datetype == 1)
{
// 电压取最大
i >= vecV.size() ? vecV.push_back(val) : (val > vecV[i] ? (vecV[i] = val, (void)0) : (void)0);
}
else if (datetype == 2)
{
// 电流取最大
i >= vecI.size() ? vecI.push_back(val) : (val > vecI[i] ? (vecI[i] = val, (void)0) : (void)0);
}
else if (datetype == 3)
{
// 功率累加
i >= vecP.size() ? vecP.push_back(val) : (vecP[i] = vecP[i] + val, (void)0);
}
}
}
}
json["data"] = {{"V", vecV}, {"I", vecI}, {"P", vecP}};
return Errcode::OK;
}
Errcode HttpEntity::queryStatStationMode(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "start_date", "end_date", "mode"}, params);
std::string stationId = params.value("station_id");
std::string startDate = params.value("start_date");
std::string endDate = params.value("end_date");
std::string mode = params.value("mode");
std::string sqlC = std::format(" WHERE dt>='{}' AND dt<='{}'", startDate, endDate);
if (!stationId.empty()) sqlC += std::format(" AND station_id='{}'", stationId);
std::string sql = " SUM(E_in) E_in, SUM(E_out) E_out, SUM(fee_in) fee_in, SUM(fee_out) fee_out, SUM(income) income FROM stat_total_day";
std::string sqlGroupBy;
if (mode == "year") {
sql = "SELECT YEAR(dt) AS year, " + sql + sqlC + " GROUP BY YEAR(dt);";
} else if (mode == "quarter") {
sql = "SELECT YEAR(dt) AS year, QUARTER(dt) quarter, " + sql + sqlC+ " GROUP BY YEAR(dt), QUARTER(dt);";
} else if (mode == "month") {
sql = "SELECT YEAR(dt) AS year, MONTH(dt) month, " + sql + sqlC + "GROUP BY YEAR(dt), MONTH(dt);";
} else if (mode == "week") {
sql = "SELECT YEAR(dt) AS year, WEEK(dt) week, " + sql + sqlC + " GROUP BY YEAR(dt), WEEK(dt);";
} else {
mode = "date";
sql = "SELECT dt, E_in, E_out, fee_in, fee_out, income FROM stat_total_day " + sqlC + " LIMIT 1000;";
}
std::vector<Fields> result;
Errcode err = DAO::exec(NULL, sql, result);
njson jsondata = njson::array();
if (mode == "date")
{
std::map<std::string, Fields*> mapTemp;
for (auto& item: result)
{
auto& dt = item.value("dt");
mapTemp[dt] = &item;
}
int64_t t0 = Utils::time(startDate + " 00:00:00");
int64_t t1 = Utils::time(endDate + " 00:00:00");
for (int64_t t = t0; t<=t1; t += 86400)
{
njson jsonrow;
std::string dt = Utils::dateStr(t);
Fields* item = NULL;
auto iter = mapTemp.find(dt);
if (iter != mapTemp.end()) { item = iter->second; }
jsonrow["dt"] = dt;
jsonrow["E_in"] = item ? item->value("E_in") : "0";
jsonrow["E_out"] = item ? item->value("E_out") : "0";
jsonrow["fee_in"] = item ? item->value("fee_in") : "0";
jsonrow["fee_out"] = item ? item->value("fee_out") : "0";
jsonrow["income"] = item ? item->value("income") : "0";
int rate = 0;
if (item) {
int E_in = item->get<int>("E_in");
int E_out = item->get<int>("E_out");
if (E_in != 0) {
rate = (float(E_out)/float(E_in)) * 100;
}
}
jsonrow["E_rate"] = rate;
jsondata.push_back(jsonrow);
}
}
else
{
for (auto& item: result)
{
njson jsonrow;
if (mode == "year") {
jsonrow["dt"] = item.value("year") + "";
}
else if (mode == "quarter") {
jsonrow["dt"] = item.value("year") + "" + item.value("quarter") + "季度";
}
else if (mode == "month") {
jsonrow["dt"] = item.value("year") + "" + item.value("month") + "";
}
else if (mode == "week") {
jsonrow["dt"] = item.value("year") + "" + item.value("week") + "";
}
else {
jsonrow["dt"] = item.value("dt");
}
jsonrow["E_in"] = item.value("E_in");
jsonrow["E_out"] = item.value("E_out");
int rate = 0;
int E_in = item.get<int>("E_in");
int E_out = item.get<int>("E_out");
if (E_in != 0) {
rate = (float(E_out)/float(E_in)) * 100;
}
jsonrow["E_rate"] = rate;
jsonrow["fee_in"] = item.value("fee_in");
jsonrow["fee_out"] = item.value("fee_out");
jsonrow["income"] = item.value("income");
jsondata.push_back(jsonrow);
}
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
CheckRequiredParams(params, {"station_id", "category", "start_date", "end_date"}, errmsg);
if (!errmsg.empty())
{
return Errcode::ERR_PARAM;
}
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string startDate = params.value("start_date");
std::string endDate = params.value("end_date");
std::string sql = "SELECT s.name station_name, sd.* FROM stat_day sd LEFT JOIN station s ON sd.station_id=s.station_id";
sql += " WHERE sd.station_id = '" + stationId + "' AND category = '" + category + "'";
sql += " AND dt BETWEEN '" + startDate + "' AND '" + endDate + "2025-09-19' AND sd.category = '1'";
std::string filename;
std::vector<Fields> result;
Errcode err = DAO::exec(NULL, sql, result);
if (result.size() > 0)
{
filename = "export_" + Utils::timeStr(0, "%Y%m%d%H%M%S") + ".xlsx";
XlsxEntity xlsx(Config::option.exportpath + "/" + filename);
std::vector<std::pair<std::string, std::string>> headers;
if (category == "1")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"充电电量", "storage_elect_in"}, {"放电电量", "storage_elect_out"},
{"充电次数", "storage_num_in"}, {"放电次数", "storage_num_out"},
{"充电时长", "storage_t_in"}, {"放电时长", "storage_t_out"}
};
}
else if (category == "2")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"充电电量", "charge_elect"}, {"充电次数", "charge_num"}, {"充电时长", "charge_t"}
};
}
else if (category == "3")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"发电电量", "solar_elect_gen"}, {"入网电量", "solar_elect_grid"}, {"发电时长", "solar_t"},
};
}
for (int row = 0; row<result.size(); ++row)
{
auto& fields = result[row];
if (category == "1") { fields.value("category") = "储能设备"; }
else if (category == "2") { fields.value("category") = "充电设备"; }
else if (category == "3") { fields.value("category") = "发电设备"; }
for (int col = 0; col<headers.size(); ++col)
{
if (row == 0)
{
xlsx.setCell(row+1, col+1, headers[col].first);
}
xlsx.setCell(row+2, col+1, fields.value(headers[col].second));
}
}
xlsx.close();
}
json["data"] = filename;
return err;
}
Errcode HttpEntity::queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
auto& appdata = Application::data();
auto station = appdata.getStation(Utils::toInt(stationId));
if (!station)
{
spdlog::error("[http] request queryEnvironment failed, get station info error, station_id={}", stationId);
return Errcode::ERR_PARAM;
}
njson jsondata;
{ // 温湿度
auto& mapTempHumUnit = station->mapTempHumUnit;
njson nodearray = njson::array();
for (auto iter = mapTempHumUnit.begin(); iter!=mapTempHumUnit.end(); iter++)
{
auto& unit = iter->second;
njson node;
node["pos"] = "#" + std::to_string(iter->first);
node["temp"] = Utils::toStr(unit.temp);
node["hum"] = Utils::toStr(unit.hum);
nodearray.push_back(node);
}
jsondata["temp_hum"] = nodearray;
}
{ //空调
auto& mapAircUnit = station->mapAircUnit;
njson nodearray = njson::array();
for (auto& item: mapAircUnit)
{
auto& unit = item.second;
nodearray.push_back({{"pos", "开关"}, {"status", unit.powerOn == 0 ? "关机" : "开机"}});
nodearray.push_back({{"pos", "启动制冷指令"}, {"status", unit.cooling == 0 ? "启动" : "关闭"}});
nodearray.push_back({{"pos", "启动送风指令"}, {"status", unit.airSupply == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "启动待机指令"}, {"status", unit.standby == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "启动加热指令"}, {"status", unit.heating == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "传感器故障"}, {"status", unit.sensorAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高低电压告警"}, {"status", unit.voltageAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高低温告警"}, {"status", unit.tempAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高低压告警"}, {"status", unit.pressureAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "压缩机告警"}, {"status", unit.compressorAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "当前温度"}, {"status", std::to_string(unit.temp) + ""}});
nodearray.push_back({{"pos", "当前湿度"}, {"status", std::to_string(unit.hum) + "%"}});
break;
}
jsondata["airc"] = nodearray;
}
{ // 消防
static std::map<int, std::string> mapFireStatusDef = { {0, "正常"}, {1,"预警"}, {2,"火警"} };
std::map<int, string> mapStatusDef = {{0, "无效"}, {1, "掉线"}, {2, "正常"}, {3, "启动"}};
auto& mapFire40Unit = station->mapFire40Unit;
njson nodearray = njson::array();
for (auto iter = mapFire40Unit.begin(); iter!=mapFire40Unit.end(); ++iter)
{
auto& unit = iter->second;
nodearray.push_back({{"pos", "主控状态"}, {"status", unit.statusMain == 0 ? "正常" : (unit.statusMain == 1 ? "预警" : "火警")}});
nodearray.push_back({{"pos", "警铃是否使用"}, {"status", unit.usedAlarm == 0 ? "" : ""}});
nodearray.push_back({{"pos", "警铃状态"}, {"status", mapStatusDef[unit.statusAlarm]}}); // 0无效 1掉线 2正常 3启动
nodearray.push_back({{"pos", "瓶头阀是否使用"}, {"status", unit.usedValve == 0 ? "" : ""}});
nodearray.push_back({{"pos", "瓶头阀状态"}, {"status", mapStatusDef[unit.statusValve]}}); // 0无效 1掉线 2正常 3启动
nodearray.push_back({{"pos", "手报是否使用"}, {"status", unit.usedMCP == 0 ? "" : ""}});
nodearray.push_back({{"pos", "手报状态"}, {"status", mapStatusDef[unit.statusMCP]}}); // 0无效 1掉线 2正常 3启动
break;
}
jsondata["fire40"] = nodearray;
}
{ // 冷机
auto& mapCoolingUnit = station->mapCoolingUnit;
njson nodearray = njson::array();
for (auto& item: mapCoolingUnit)
{
auto& unit = item.second;
njson node;
nodearray.push_back({{"pos", "开关"}, {"status", unit.powerOn == 0 ? "关机" : "开机"}});
nodearray.push_back({{"pos", "采样模式"}, {"status", unit.mode == 0 ? "出水温度" : "电芯温度"}});
nodearray.push_back({{"pos", "制冷状态"}, {"status", unit.cooling == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "制热状态"}, {"status", unit.heating == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "高温告警"}, {"status", unit.highTempAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "低温告警"}, {"status", unit.lowTempAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高压告警"}, {"status", unit.highPressureAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "低压告警"}, {"status", unit.lowPressureAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "制冷点"}, {"status", std::format("{:.1f} ℃", unit.coolPoint * 0.1f)}});
nodearray.push_back({{"pos", "制冷偏差"}, {"status", std::format("{:.1f} ℃", unit.coolDeviation*0.1f)}});
nodearray.push_back({{"pos", "高温告警值"}, {"status", std::format("{:.1f} ℃", unit.highTempTH*0.1f)}});
nodearray.push_back({{"pos", "低温告警值"}, {"status", std::format("{:.1f} ℃", unit.lowTempTH*0.1f)}});
nodearray.push_back({{"pos", "制热点"}, {"status", std::format("{:.1f} ℃", unit.heatPoint*0.1f)}});
nodearray.push_back({{"pos", "制热偏差"}, {"status", std::format("{:.1f} ℃", unit.heatDeviation*0.1f)}});
nodearray.push_back({{"pos", "电芯温度"}, {"status", std::format("{:.1f} ℃", unit.cellTemp*0.1f)}});
nodearray.push_back({{"pos", "环境湿度"}, {"status", std::format("{:.1f} ℃", unit.ambientHumi*0.1f)}});
nodearray.push_back({{"pos", "吸气温度"}, {"status", std::format("{:.1f} ℃", unit.suctionTemp*0.1f)}});
nodearray.push_back({{"pos", "排气温度"}, {"status", std::format("{:.1f} ℃", unit.dischTemp*0.1f)}});
nodearray.push_back({{"pos", "进水温度"}, {"status", std::format("{:.1f} ℃", unit.inletTemp*0.1f)}});
nodearray.push_back({{"pos", "出水温度"}, {"status", std::format("{:.1f} ℃", unit.outletTemp*0.1f)}});
nodearray.push_back({{"pos", "进水压力"}, {"status", std::format("{:.1f}", unit.inletPressure*0.1f)}});
nodearray.push_back({{"pos", "出水压力"}, {"status", std::format("{:.1f}", unit.outletPressure*0.1f)}});
nodearray.push_back({{"pos", "高压压力"}, {"status", std::format("{:.1f}", unit.highPressure*0.1f)}});
nodearray.push_back({{"pos", "低压压力"}, {"status", std::format("{:.1f}", unit.lowPressure*0.1f)}});
nodearray.push_back({{"pos", "循环水泵转速"}, {"status", std::format("{}", unit.pumpSpeed)}});
nodearray.push_back({{"pos", "压缩机频率"}, {"status", std::format("{}", unit.compFreq)}});
nodearray.push_back({{"pos", "室外风机转速"}, {"status", std::format("{}", unit.fanSpeed)}});
}
jsondata["cooling"] = nodearray;
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryServiceApiList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
std::string sql = "SELECT * FROM serviceapi;" ;
auto err = DAO::exec(NULL, sql, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
Errcode HttpEntity::insertServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "describe", "params", "is_open"}, params);
if (params.size() == 0) { return Errcode::ERR_PARAM; }
return DAO::insert(NULL, "serviceapi", params);
}
Errcode HttpEntity::updateServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"api_id", "name", "describe", "params", "is_open"}, params);
if (params.size() == 0) { return Errcode::ERR_PARAM; }
return DAO::update(NULL, "serviceapi", params, "api_id");
}
Errcode HttpEntity::deleteServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"api_id"}, params);
return DAO::remove(NULL, "serviceapi", "api_id", params.value("api_id"));
}
Errcode HttpEntity::updateGatewayParams(const httplib::Request& req, njson& json, std::string& errmsg)
{
//上下限SOC安全输入功率储能最大充放电功率防逆流防过载回差。
Fields params;
GetRequestParams(req, {"station_id", "work_mode", "soc_min", "soc_max", "capacity", "power_safe", "power_discharge", "power_charge", "backflow", "overload"}, params);
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (params.contains("work_mode"))
{
int workMode = params.get<int>("work_mode");
Fields fields;
fields.set("station_id", params.value("station_id"));
fields.set("work_mode", workMode);
Errcode err = DAO::updateStationById(params);
}
if (station)
{
//params.get("work_mode", station->workMode);
params.get("soc_min", station->gatewayParam.socMin); // 储能放电下限值 SOC 40038 (%, 0-99)
params.get("soc_max", station->gatewayParam.socMax); // 储能充电上限值 SOC 40039 (%:1-100)
params.get("capacity", station->gatewayParam.capacity); // 台区变压器容量 40040 (KVA 160-1600)
params.get("power_safe", station->gatewayParam.powerSafe); // 安全输入功率 40041 (KW 0-400)
params.get("power_discharge", station->gatewayParam.powerDischarge); // 储能最大放电功率 40042 (1KW 0-150)
params.get("power_charge", station->gatewayParam.powerCharge); // 储能最大充电功率 40043 (1KW 0-150)
params.get("backflow", station->gatewayParam.backflow); // 防逆流回差 40058(1KW 10-300)
params.get("overload", station->gatewayParam.overload); // 防过载回差 40059(1KW 10-300)
station->setGarewayParams();
return Errcode::OK;
}
return Errcode::ERR_PARAM;
}
static float SetPeriodRowJson(njson& jsonrow, std::string period, int eIn, int eOut, float priceIn, float priceOut, std::string dt)
{
jsonrow["dt"] = dt;
jsonrow["period"] = period;
jsonrow["E_in"] = eIn;
jsonrow["E_out"] = eOut;
jsonrow["grid_price"] = Utils::toStr(priceIn);
jsonrow["charge_price"] = Utils::toStr(priceOut);
return eOut * priceOut - eIn * priceIn;
}
Errcode HttpEntity::queryEGridPeriod(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"dt_start", "dt_end", "station_id"}, params);
int stationId = params.get<int>("station_id");
std::string dtStart = params.value("dt_start");
std::string dtEnd = params.value("dt_end");
//int year = 0;
//int month = 0;
//int day = 0;
//int ret = sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day); // 解析3个值成功返回3
//if (ret != 3)
//{
// return Errcode::ERR_PARAM;
//}
if (stationId == 0 || dtStart.empty() || dtEnd.empty())
{
return Errcode::ERR_PARAM;
}
float priceJ = 0.0;
float priceF = 0.0;
float priceP = 0.0;
float priceG = 0.0;
float priceC = 0.0;
std::vector<Fields> result;
auto err = DAO::exec(NULL, "select * from egrid_price;", result);
if (err != Errcode::OK)
{
return err;
}
if (result.size() > 0)
{
for (auto& item: result)
{
int etype = item.get<int>("etype");
float price = item.get<float>("price", 2);
if (etype == 1) { priceG = price; }
else if (etype == 2) { priceP = price; }
else if (etype == 3) { priceF = price; }
else if (etype == 4) { priceJ = price; }
else if (etype == 9) { priceC = price; }
}
}
//std::string sql = std::format("SELECT ep.*, ep2.price FROM egrid_period ep LEFT JOIN egrid_price ep2 ON ep.etype=ep2.etype WHERE ep.`month`={};", month);
std::string sql = std::format("select * from stat_total_day WHERE dt>='{}' AND dt<='{}' AND station_id='{}';", dtStart, dtEnd, stationId);
err = DAO::exec(NULL, sql, result);
if (err != Errcode::OK)
{
return err;
}
int totalIn {};
int totalOut {};
float totalIncome {0.0f};
njson jsondata = njson::array();
for (auto& item: result)
{
std::string dt = item.get<std::string>("dt");
// 谷
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_G"), item.get<int>("E_out_G"), priceG, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
totalIncome += income;
}
// 平
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_P"), item.get<int>("E_out_P"), priceP, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
totalIncome += income;
}
// 峰
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_F"), item.get<int>("E_out_F"), priceF, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
totalIncome += income;
}
// 尖
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_J"), item.get<int>("E_out_J"), priceJ, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
totalIncome += income;
}
totalIn += item.get<int>("E_in");
totalOut += item.get<int>("E_out");
}
// 总计
{
njson jsonrow;
jsonrow["dt"] = "";
jsonrow["period"] = "总计";
jsonrow["E_in"] = totalIn;
jsonrow["E_out"] = totalOut;
jsonrow["grid_price"] = "";
jsonrow["charge_price"] = "";
jsonrow["income"] = Utils::toStr(totalIncome);
jsondata.push_back(jsonrow);
}
json["data"] = jsondata;
return Errcode::OK;
}