#include "HttpEntity.h" #include "database/Dao.h" #include #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 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()); } break; case njson::value_t::boolean: { fields.set(key, json[key].get()); } break; case njson::value_t::number_integer: { fields.set(key, json[key].get()); } break; case njson::value_t::number_unsigned: { fields.set(key, json[key].get()); } break; case njson::value_t::number_float: { fields.set(key, json[key].get()); } 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& 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& 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 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& 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 result, njson& json) { json["count"] = pageinfo.total; json["page"] = pageinfo.index; json["page_size"] = pageinfo.size; json["data"] = FieldsToJsonArray(result); } }; static std::map 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, {})}, {"/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 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 vecPermission; int roleId = fields.get(DMRole::ROLE_ID); DAO::queryRolePermission(dao, roleId, vecPermission); njson nodePermission = njson::array(); std::map mapParentPos; for (int i=0; isecond]["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 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 result; auto err = DAO::queryPermissionList(pageinfo, result); HttpHelper::setPagination(pageinfo, result, json); // 查询所有的角色权限关联 if (err == Errcode::OK) { std::map mapP; for (int i = 0; i vecSubPermission; DaoEntity::execOnce("SELECT * FROM permission WHERE permission.parent_id IS NOT NULL AND permission.parent_id!='';", vecSubPermission); for (int i = 0; i 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 result; auto err = DAO::queryRoleList(pageinfo, result); HttpHelper::setPagination(pageinfo, result, json); // 查询所有的角色权限关联 if (err == Errcode::OK) { std::vector vecPermission; err = DAO::queryRolePermission(NULL, vecPermission); if (err != Errcode::OK) { return err; } std::map> mapRole; std::map> mapChildren; for (int i=0; isecond) { 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()); fields.set("is_open", item["is_open"].get()); fields.set("is_view", item["is_view"].get()); fields.set("is_add", item["is_add"].get()); fields.set("is_edit", item["is_edit"].get()); fields.set("is_del", item["is_del"].get()); } 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 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 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; }; 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 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("station_id"); int workmode = params.get("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 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(); } //if (json.contains("discharge")) { station->gatewayParam.powerDischarge = json["discharge"].get(); } } 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 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("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("category"); int count = fields.get("count"); switch (category) { case 1: { jsonStorage["count"] = jsonStorage["count"].get() + count; } break; case 2: { jsonCharge["count"] = jsonCharge["count"].get() + count; } break; case 3: { jsonSolar["count"] = jsonSolar["count"].get() + count; } break; case 4: { jsonSecurity["count"] = jsonSecurity["count"].get() + 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 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& 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 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("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("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 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("station_id"); int category = params.get("category"); njson jsondata = njson::array(); auto station = Application::data().getStation(stationId); if (station) { std::vector> 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("station_id"); int deviceId = params.get("device_id"); auto device = Application::data().getDevice(stationId, deviceId); int npos = Utils::timeDaySeconds() / 600; std::vector vecU(npos, 0); std::vector vecI(npos, 0); std::vector 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("station_id"); int deviceId = params.get("device_id"); auto device = Application::data().getDevice(stationId, deviceId); njson jsondata = njson::array(); if (device) { for (int i = 0; i<=device->bcuCount && ivecBCUUnit.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 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("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 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) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); pageinfo.size = Utils::toInt(req.get_param_value("page_size")); std::vector result; auto err = DAO::querySystemLogList(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) { PageInfo pageinfo; pageinfo.index = Utils::toInt(req.get_param_value("page")); pageinfo.size = Utils::toInt(req.get_param_value("page_size")); std::vector result; auto err = DAO::queryAlertLogList(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 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 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("E_in"); eOut = fields.get("E_out"); tIn = fields.get("t_in"); tOut = fields.get("t_out"); eGen = fields.get("E_gen"); eGrid = fields.get("E_grid"); eCharge = fields.get("E_charge"); income = fields.get("income"); } } else { eIn += fields.get("E_in"); eOut += fields.get("E_out"); tIn += fields.get("t_in"); tOut += fields.get("t_out"); eGen += fields.get("E_gen"); eGrid = fields.get("E_grid"); eCharge += fields.get("E_charge"); income += fields.get("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("storage_usage") + fields.get("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 result; DAO::exec(NULL, sql, result); for (auto& item: result) { income += item.get("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 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"); jsonnode["usage_rate"] = fields.get("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 result; auto err = DAO::queryStatStationGroup(NULL, stationId, category, startDate, endDate, result); if (!startDate.empty() && !endDate.empty()) { std::map 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"); int i = 0; njson jsondata = njson::array(); for (int64_t t = t0; t<=t1; t += 86400) { i++; 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 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 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 result; int ret = DaoEntity::execOnce(sql, result); if (ret != 0) { return Errcode(ret); } std::vector vecV; std::vector vecI; std::vector vecP; for (auto fields : result) { int datetype = fields.get("datatype"); // 1: 电压,2:电流,3:功率 std::string val = fields.value("value"); // JSON 数组(double) int deviceType = fields.get("device_type"); int deviceCode = fields.get("code"); if (category == "1") { if (!(deviceType == int(EDeviceType::BMS))) // 储能BMS(储能设备以BMS电池的数据作为总数据来展示) { continue; } } njson jsonval; if (JSON::parse(val, jsonval)) { for (int i = 0; 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::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 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> 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; rowmapTempHumUnit; 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 mapFireStatusDef = { {0, "正常"}, {1,"预警"}, {2,"火警"} }; std::map 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 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("station_id"); auto station = Application::data().getStation(stationId); if (params.contains("work_mode")) { int workMode = params.get("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("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 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("etype"); float price = item.get("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("dt"); // 谷 { njson jsonrow; float income = SetPeriodRowJson(jsonrow, "谷", item.get("E_in_G"), item.get("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("E_in_P"), item.get("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("E_in_F"), item.get("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("E_in_J"), item.get("E_out_J"), priceJ, priceC, dt); jsonrow["income"] = Utils::toStr(income); jsondata.push_back(jsonrow); totalIncome += income; } totalIn += item.get("E_in"); totalOut += item.get("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; }