diff --git a/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx b/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx index c243f3e..952762d 100644 Binary files a/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx and b/bin/Release/assets/config/EMU对外通信点表最终修改1版_v9.xlsx differ diff --git a/bin/Release/assets/config/app.json b/bin/Release/assets/config/app.json index c7083b1..97f616b 100644 --- a/bin/Release/assets/config/app.json +++ b/bin/Release/assets/config/app.json @@ -1,8 +1,8 @@ { "launchdate": "2025-09-01", - "database": {"host": "localhost", "port": 3306, "user": "root", "passwd": "123456", "dbname": "ees"}, + "database": {"host": "localhost", "port": 3306, "user": "root", "passwd": "123456", "dbname": "ess"}, "token":"", - "http": {"port": 19800}, + "http": {"port": 19801}, "mqtt": {"host":"mqtt://43.136.119.46:6203","username":"jsyhsec","password":"123456"}, - "weburl": "http://127.0.0.1:19600/" + "weburl": "http://127.0.0.1:19601/" } \ No newline at end of file diff --git a/bin/Release/assets/config/monitoraddr.json b/bin/Release/assets/config/bak.monitoraddr.json similarity index 70% rename from bin/Release/assets/config/monitoraddr.json rename to bin/Release/assets/config/bak.monitoraddr.json index 06e9005..7ec1c19 100644 --- a/bin/Release/assets/config/monitoraddr.json +++ b/bin/Release/assets/config/bak.monitoraddr.json @@ -2,11 +2,11 @@ "EMS":{ "deviceType":101, "addr_YC":[ - ["A相电压", "0x107E", "0.0", " V", "0.1"], + ["A相电压", "0x107E", "0.0", " V", "1"], ["A相电流", "0x1084", "0.0", " A"], - ["B相电压", "0x1080", "0.0", " V", "0.1"], + ["B相电压", "0x1080", "0.0", " V", "1"], ["B相电流", "0x1086", "0.0", " A"], - ["C相电压", "0x1082", "0.0", " V", "0.1"], + ["C相电压", "0x1082", "0.0", " V", "1"], ["C相电流", "0x1088", "0.0", " A"] ], "addr_YX": [ ] @@ -14,11 +14,11 @@ "PCS":{ "deviceType":102, "addr_YC":[ - ["A相电压", "0x0010", "0.0", " V", "0.1"], + ["A相电压", "0x0010", "0.0", " V", "1"], ["A相电流", "0x0019", "0.0", " A"], - ["B相电压", "0x0011", "0.0", " V", "0.1"], + ["B相电压", "0x0011", "0.0", " V", "1"], ["B相电流", "0x001A", "0.0", " A"], - ["C相电压", "0x0011", "0.0", " V", "0.1"], + ["C相电压", "0x0011", "0.0", " V", "1"], ["C相电流", "0x001B", "0.0", " A"] ], "addr_YX": [ ] @@ -26,11 +26,11 @@ "PCU":{ "deviceType":103, "addr_YC":[ - ["A相电压", "0x0013", "0.0", " V", "0.1"], + ["A相电压", "0x0013", "0.0", " V", "1"], ["A相电流", "0x001C", "0.0", " A"], - ["B相电压", "0x0014", "0.0", " V", "0.1"], + ["B相电压", "0x0014", "0.0", " V", "1"], ["B相电流", "0x001D", "0.0", " A"], - ["C相电压", "0x0015", "0.0", " V", "0.1"], + ["C相电压", "0x0015", "0.0", " V", "1"], ["C相电流", "0x001E", "0.0", " A"] ], "addr_YX": [ ] @@ -38,26 +38,26 @@ "BMS":{ "deviceType":104, "addr_YC":[ - ["SOC", "0x0001", "0", " %"], - ["SOH", "0x0002", "0", " %"], + ["SOC", "0x0001", "0", " %", "0.1"], + ["SOH", "0x0002", "0", " %", "0.1"], ["电压", "0x0003", "0.0", " V", "0.1"], - ["电流", "0x0005", "0.0", " A"], + ["电流", "0x0005", "0.0", " A", "0.1"], ["单体最大电压", "0x0021", "0.0", " V", "0.1"], ["单体最小电压", "0x0024", "0.0", " V", "0.1"], - ["单体最大温度", "0x0029", "0.0", " ℃"], - ["单体最小温度", "0x002C", "0.0", " ℃"] + ["单体最大温度", "0x0029", "0.0", " ℃", "0.1"], + ["单体最小温度", "0x002C", "0.0", " ℃", "0.1"] ], "addr_YX": [ ] }, "BCU":{ "deviceType":105, "addr_YC":[ - ["簇电压", "0x0003", "0.0", " V"], - ["簇电流", "0x0005", "0", " A"], - ["簇温度", "0x0007", "0.0", " ℃"], + ["簇电压", "0x0003", "0.0", " V", "0.1"], + ["簇电流", "0x0005", "0", " A", "0.1"], + ["簇温度", "0x0007", "0.0", " ℃", "0.1"], ["簇电阻", "0x0009", "0.0", " Ω"], - ["簇SOC", "0x000B", "0", " %"], - ["簇SOH", "0x000C", "0", " %"] + ["簇SOC", "0x000B", "0", " %", "0.1"], + ["簇SOH", "0x000C", "0", " %", "0.1"] ], "addr_YX": [ ] }, diff --git a/bin/Release/assets/config/registeraddr.json b/bin/Release/assets/config/regaddrs.json similarity index 99% rename from bin/Release/assets/config/registeraddr.json rename to bin/Release/assets/config/regaddrs.json index 49c89d5..d56984d 100644 --- a/bin/Release/assets/config/registeraddr.json +++ b/bin/Release/assets/config/regaddrs.json @@ -783,7 +783,9 @@ "addr":[ {"key": "0x0001", "datatype": "uint16", "remark": "所属通道号1"}, {"key": "0x0002", "datatype": "uint16", "remark": "所属温湿度号1~10"}, - {"key": "0x0003", "datatype": "int16", "remark": "温度(0.1℃)"} + {"key": "0x0003", "datatype": "int16", "remark": "温度(0.1℃)"}, + {"key": "0x0004", "datatype": "int16", "remark": "湿度(0.1℃)"} + ] }, "Fire40_YX":{ @@ -792,6 +794,8 @@ {"key": "0x0002", "datatype": "uint16", "remark": "主控数量1"}, {"key": "0x0003", "datatype": "uint16", "remark": "主控ID1"}, {"key": "0x0004", "datatype": "uint16", "remark": "主控状态0:正常 1:预警 2:火警"}, + {"key": "0x0005", "datatype": "uint32", "remark": "主控硬件版本"}, + {"key": "0x0007", "datatype": "uint32", "remark": "主控软件版本"}, {"key": "0x0009", "datatype": "uint16", "remark": "主电状态0:使用市电 1:使用备电"}, {"key": "0x000A", "datatype": "uint32", "remark": "备电电流(0.1A)"}, {"key": "0x000C", "datatype": "uint32", "remark": "备电电压(0.1V)"}, @@ -854,5 +858,13 @@ {"key": "0x100D", "datatype": "uint16", "remark": "进水压力传感器0:正常,1:告警"}, {"key": "0x100E", "datatype": "uint16", "remark": "出水压力传感器0:正常,1:告警"} ] + }, + "Gateway_YC":{ + "addr":[ + {"key": "40001", "datatype": "uint16", "remark": "模式"}, + {"key": "40002", "datatype": "uint16", "remark": "峰谷时间段"}, + {"key": "40021", "datatype": "uint16", "remark": "自定时间段"}, + {"key": "40038", "datatype": "uint16", "remark": "其他参数"} + ] } } \ No newline at end of file diff --git a/bin/Release/assets/config/registeraddrs.py b/bin/Release/assets/config/regaddrs.py similarity index 96% rename from bin/Release/assets/config/registeraddrs.py rename to bin/Release/assets/config/regaddrs.py index d6f7043..7c46c92 100644 --- a/bin/Release/assets/config/registeraddrs.py +++ b/bin/Release/assets/config/regaddrs.py @@ -54,7 +54,7 @@ text += ',\n' + read_sheet(wb, "Fire40_YX", "消防4.0遥信") text += ',\n' + read_sheet(wb, "Cooling_YC", "冷机遥测") text += ',\n' + read_sheet(wb, "Cooling_YX", "冷机遥信") -with open('registeraddr.json', 'w', encoding='utf-8') as f: +with open('regaddrs.json', 'w', encoding='utf-8') as f: f.write("{\n" + text + "\n}") @@ -85,5 +85,5 @@ def read_sheet_alarm(wb, device_type, sht_name): text_err = "" text_err = read_sheet_alarm(wb, 103, "PCU遥信") text_err += ',\n' + read_sheet_alarm(wb, 104, "PCS遥信") -with open('registeraddrErr.json', 'w', encoding='utf-8') as f: +with open('regddrsErr.json', 'w', encoding='utf-8') as f: f.write("{\n" + text_err + "\n}") diff --git a/bin/Release/assets/config/regaddrsShow.json b/bin/Release/assets/config/regaddrsShow.json new file mode 100644 index 0000000..5cf7f6b --- /dev/null +++ b/bin/Release/assets/config/regaddrsShow.json @@ -0,0 +1,109 @@ +{ + "EMS":{ + "deviceType":101, + "addrYC":[ + ["A相电压", "0x107E", "0.0", " V", "1"], + ["A相电流", "0x1084", "0.0", " A"], + ["B相电压", "0x1080", "0.0", " V", "1"], + ["B相电流", "0x1086", "0.0", " A"], + ["C相电压", "0x1082", "0.0", " V", "1"], + ["C相电流", "0x1088", "0.0", " A"] + ], + "addrCurve": ["0x107E", "0x1084", "0x1096"] + }, + "PCS":{ + "deviceType":102, + "addrYC":[ + ["A相电压", "0x0010", "0.0", " V", "1"], + ["A相电流", "0x0019", "0.0", " A"], + ["B相电压", "0x0011", "0.0", " V", "1"], + ["B相电流", "0x001A", "0.0", " A"], + ["C相电压", "0x0011", "0.0", " V", "1"], + ["C相电流", "0x001B", "0.0", " A"] + ], + "addrCurve": ["0x0010", "0x0019", "0x0025"] + }, + "PCU":{ + "deviceType":103, + "addrYC":[ + ["A相电压", "0x0013", "0.0", " V", "1"], + ["A相电流", "0x001C", "0.0", " A"], + ["B相电压", "0x0014", "0.0", " V", "1"], + ["B相电流", "0x001D", "0.0", " A"], + ["C相电压", "0x0015", "0.0", " V", "1"], + ["C相电流", "0x001E", "0.0", " A"] + ], + "addrCurve": ["0x0013", "0x001C", "0x0028"] + }, + "BMS":{ + "deviceType":104, + "addrYC":[ + ["SOC", "0x0001", "0", " %", "0.1"], + ["SOH", "0x0002", "0", " %", "0.1"], + ["电压", "0x0003", "0.0", " V", "0.1"], + ["电流", "0x0005", "0.0", " A", "0.1"], + ["单体最大电压", "0x0021", "0.0", " V", "0.1"], + ["单体最小电压", "0x0024", "0.0", " V", "0.1"], + ["单体最大温度", "0x0029", "0.0", " ℃", "0.1"], + ["单体最小温度", "0x002C", "0.0", " ℃", "0.1"] + ], + "addrCurve": ["0x0003", "0x0005", ""] + }, + "BCU":{ + "deviceType":105, + "addrYC":[ + ["簇电压", "0x0003", "0.0", " V", "0.1"], + ["簇电流", "0x0005", "0", " A", "0.1"], + ["簇温度", "0x0007", "0.0", " ℃", "0.1"], + ["簇电阻", "0x0009", "0.0", " Ω"], + ["簇SOC", "0x000B", "0", " %", "0.1"], + ["簇SOH", "0x000C", "0", " %", "0.1"] + ], + "addrCurve": ["0x0003", "0x0005", ""] + }, + "MEM":{ + "deviceType":3, + "addrYC":[ + ["A相电压", "0x000B", "0.0", " V"], + ["A相电流", "0x000D", "0.0", " A"], + ["B相电压", "0x000F", "0.0", " V"], + ["B相电流", "0x0011", "0.0", " A"], + ["C相电压", "0x0013", "0.0", " V"], + ["C相电流", "0x0015", "0.0", " A"] + ], + "addrCurve": ["0x000B","0x0011","0x0023"] + }, + "TH": { + "deviceType":10, + "addrYC":[ + ["温度", "0x0003", "0.0", " ℃", "0.1"], + ["湿度", "0x0004", "0.0", " %", "0.1"] + ] + }, + "Cooling": { + "deviceType":14, + "addrYC":[ + ["开关", "0x1003", "0", "", "1"], + ["采样模式", "0x1004", "0", "", "1"], + ["制冷状态", "0x1005", "0", "", "1"], + ["制热状态", "0x1006", "0", "", "1"], + ["高温告警", "0x1007", "0", "", "1"], + ["低温告警", "0x1008", "0", "", "1"], + ["高压告警", "0x1009", "0", "", "1"], + ["低压告警", "0x100A", "0", "", "1"] + ] + }, + "Charger": { + "deviceType":106, + "addrYC":[ + ["需求电压", "31071", "0.0", " V"], + ["需求电流", "31073", "0.0", " A"], + ["需求功率", "31075", "0.0", " kW"], + ["功率限值", "31077", "0.0", " kW"], + ["输出电压", "31079", "0.0", " V"], + ["输出电流", "31081", "0.0", " A"], + ["输出功率", "31083", "0.0", " kW"] + ], + "addrCurve": ["31079", "31081", "31083"] + } +} \ No newline at end of file diff --git a/bin/Release/assets/config/~$EMU对外通信点表最终修改1版_v9.xlsx b/bin/Release/assets/config/~$EMU对外通信点表最终修改1版_v9.xlsx new file mode 100644 index 0000000..7b92221 Binary files /dev/null and b/bin/Release/assets/config/~$EMU对外通信点表最终修改1版_v9.xlsx differ diff --git a/src/app/AppData.cpp b/src/app/AppData.cpp index 6e3d922..67a853e 100644 --- a/src/app/AppData.cpp +++ b/src/app/AppData.cpp @@ -48,6 +48,7 @@ bool AppData::initFromDB() { // 数据库读取工作模式定义 str = "", result.clear(); DAO::queryWorkModeDef(dao, result); + this->mapping.workMode.clear(); for (auto& fields: result) { int workModeId = fields.get(DMDefWorkMode::WORK_MODE_ID); @@ -61,6 +62,7 @@ bool AppData::initFromDB() { // 数据库读取策略类型定义 str = "", result.clear(); DAO::queryPolicyTypeDef(dao, result); + this->mapping.policyType.clear(); for (auto& fields: result) { int policyTypeId = fields.get(DMDefPolicyType::POLICY_TYPE_ID); @@ -74,6 +76,7 @@ bool AppData::initFromDB() { // 数据库读取设备类型定义 str = "", result.clear(); DAO::queryDeviceTypeDef(dao, result); + mapping.deviceType.clear(); for (auto& fields: result) { auto item = std::make_shared(); @@ -90,8 +93,8 @@ bool AppData::initFromDB() } { // 数据库读取角色定义 str = "", result.clear(); - this->mapping.role.clear(); DAO::queryRoleList(dao, result); + this->mapping.role.clear(); for (auto& fields : result) { auto item = std::make_shared(); @@ -108,19 +111,20 @@ bool AppData::initFromDB() str = "", result.clear(); 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;"; dao->exec(sql, result); + this->mapping.stationName.clear(); for (auto& fields: result) { auto station = std::make_shared(); station->setFields(fields); this->mapStation[station->stationId] = station; - mapping.stationName.push_back({std::to_string(station->stationId), station->name}); + this->mapping.stationName.push_back({std::to_string(station->stationId), station->name}); str += ("场站: {" + std::to_string(station->stationId) + ":" + station->name + "},"); } spdlog::info(str); } { // 数据库读取设备信息 str = "", result.clear(); - DAO::queryDeviceList(dao, result); + DAO::queryDeviceList(dao, result, 1); for (auto& fields: result) { int deviceId = fields.get(DMDevice::DEVICE_ID); @@ -135,6 +139,10 @@ bool AppData::initFromDB() spdlog::error("init device error: unknown station_id:, device_id=", stationId, deviceId); } } + for (auto& item : mapStation) + { + item.second->groupDevice(); + } } { // 数据库读取策略信息 str = "", result.clear(); diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 43bbcd7..3d44d33 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -10,6 +10,7 @@ #include "protocol/HttpEntity.h" #include "common/Spdlogger.h" #include "protocol/MqttEntity.h" +#include "DataStruct.h" void Application::init() { @@ -17,9 +18,9 @@ void Application::init() Config::init("assets/config/app.json"); // MQTT 数据结构 - MqttClient::loadDataStruct("assets/config/registeraddr.json"); + REGAddr::load("assets/config/regaddrs.json"); // 设备读取寄存器的地址定义 - Device::loadParamAddr("assets/config/monitoraddr.json"); + Device::loadParamAddr("assets/config/regaddrsShow.json"); // 设置数据库配置 DaoEntity::setOption(Config::option.database.host, @@ -67,49 +68,43 @@ void Application::runThreadDevice() void Application::runThreadMain() { - std::string addr = "tcp://localhost:1883"; - //mqttCli = std::make_shared(); - //mqttCli->init(addr, "ESS", "", "", {}); - while (!isQuit) { if (!this->isInit) // 初始化失败 { - std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + std::this_thread::sleep_for(std::chrono::seconds(10)); this->isInit = appdata.init(); if (!this->isInit) { continue; } } - static TimeTick ttMqtt; - // 检查 场站的 MQTT 连接 - if (ttMqtt.elapse(10)) + static TimeTick ttMqtt(1); // 检查 场站的 MQTT 连接 + if (ttMqtt.elapse(20)) { auto& optionMqtt = Config::option.mqtt; if (!optionMqtt.host.empty()) { for (auto& item : appdata.mapStation) { - if (item.second) + auto& station = item.second; + if (station && station->isOpen) { + // 该函数检查连接状态,若已经连接,则无操作;若未连接,则进行连接操作 item.second->initMqtt(); - //item.second->polling(); + // 召测 + item.second->polling(); } } } } - /////////////////////////////////////////////////////////////////////////////////////////// - /// 召测 - static TimeTick tt1; - if (tt1.elapse(10)) - { - + static TimeTick ttData(1); // 检查数据 + if (ttData.elapse(20)) + { + //appdata.initFromDB(); } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } - void Application::runThreadStat() { int nCachePos = 0; @@ -125,6 +120,7 @@ void Application::runThreadStat() { nCachePos = n; std::string dt = Utils::dateStr(tDate); + // // 设备历史数据(电压、电流、功率),存储到 history_day for (auto item: appdata.mapStation) { item.second->writeRuntimeData(dt, nCachePos); @@ -135,15 +131,12 @@ void Application::runThreadStat() //spdlog::info("保存历史数据倒计时: {}", 600 - offset); } - - - + // 统计计算,存储到 stat_station for (auto& station : appdata.mapStation) { - + } - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + std::this_thread::sleep_for(std::chrono::seconds(1)); } } \ No newline at end of file diff --git a/src/app/DataStruct.cpp b/src/app/DataStruct.cpp index de57163..c17f742 100644 --- a/src/app/DataStruct.cpp +++ b/src/app/DataStruct.cpp @@ -1,62 +1,57 @@ #include "DataStruct.h" +#include "common/JsonN.h" +#include "common/Utils.h" -void EMSYX::fromJson(const std::string& str) +std::string REGAddrOffset(std::string addr, int offset) { - njson jsonroot; - auto ret = JSON::parse(str, jsonroot); - if (!ret) { return; } - JSON::read(jsonroot, "mcu", mcu); - JSON::read(jsonroot, "pcs", pcs); - JSON::read(jsonroot, "electMeterMainPoint", electMeterMainPoint); - JSON::read(jsonroot, "electMeter", electMeter); - JSON::read(jsonroot, "fireSystem", fireSystem); - JSON::read(jsonroot, "ups", ups); - JSON::read(jsonroot, "temHumMainPoint", temHumMainPoint); - JSON::read(jsonroot, "temHum", temHum); - JSON::read(jsonroot, "aircMainPoint", aircMainPoint); - JSON::read(jsonroot, "airc", airc); - JSON::read(jsonroot, "controlDryContact", controlDryContact); - JSON::read(jsonroot, "statusDryContact", statusDryContact); - JSON::read(jsonroot, "bcuMain", bcuMain); - JSON::read(jsonroot, "pcuMain", pcuMain); - JSON::read(jsonroot, "electMeterMain", electMeterMain); - JSON::read(jsonroot, "fireSystemMain", fireSystemMain); - JSON::read(jsonroot, "upsMain", upsMain); - JSON::read(jsonroot, "temHumMain", temHumMain); - JSON::read(jsonroot, "aircMain", aircMain); - JSON::read(jsonroot, "emu", emu); - JSON::read(jsonroot, "chillerMain", chillerMain); - JSON::read(jsonroot, "chillerMainPoint", chillerMainPoint); - JSON::read(jsonroot, "chiller", chiller); + unsigned int val; + std::stringstream ss; + ss << std::hex << addr; + ss >> val; + return Utils::toHexStr(val + offset); } -std::string EMSYX::toJson() +std::map> REGAddr::s_mapReg; + + +void REGAddr::load(std::string filename) { - njson jsonroot; - jsonroot["bms"] = bms; - jsonroot["bcu"] = bcu; - jsonroot["mcu"] = mcu; - jsonroot["pcs"] = pcs; - jsonroot["electMeterMainPoint"] = electMeterMainPoint; - jsonroot["electMeter"] = electMeter; - jsonroot["fireSystem"] = fireSystem; - jsonroot["ups"] = ups; - jsonroot["temHumMainPoint"] = temHumMainPoint; - jsonroot["temHum"] = temHum; - jsonroot["aircMainPoint"] = aircMainPoint; - jsonroot["airc"] = airc; - jsonroot["controlDryContact"] = controlDryContact; - jsonroot["statusDryContact"] = statusDryContact; - jsonroot["bcuMain"] = bcuMain; - jsonroot["pcuMain"] = pcuMain; - jsonroot["electMeterMain"] = electMeterMain; - jsonroot["fireSystemMain"] = fireSystemMain; - jsonroot["upsMain"] = upsMain; - jsonroot["temHumMain"] = temHumMain; - jsonroot["aircMain"] = aircMain; - jsonroot["emu"] = emu; - jsonroot["chillerMain"] = chillerMain; - jsonroot["chillerMainPoint"] = chillerMainPoint; - jsonroot["chiller"] = chiller; - return jsonroot.dump(); + njson json; + JSON::load(filename, json); + + // 遍历 JSON 对象 + for (auto& jsonitem : json.items()) + { + std::string name = jsonitem.key(); + auto& jsonnodeItem = jsonitem.value(); + //int count = jsonnodeItem["count"]; + auto jsonaddrs = jsonnodeItem["addr"]; + + auto& mapItem = s_mapReg[name]; + int size = 0; + for (int i = 0; i<2; ++i) + { + for (auto& item : jsonaddrs) + { + std::string addr = item["key"]; + mapItem[addr] = RegAddrUnit(addr, item["datatype"], item["remark"]); + } + } + } + + //for (auto& item: s_mapReg["EMS_YC"]) + //{ + // auto& unit = item.second; + // spdlog::info("[{}]={}, {}", unit.key, unit.datatype, unit.remark); + //} +} + +std::map* REGAddr::getRegMap(std::string name) +{ + auto iter = s_mapReg.find(name); + if (iter != s_mapReg.end()) + { + return &(iter->second); + } + return nullptr; } \ No newline at end of file diff --git a/src/app/DataStruct.h b/src/app/DataStruct.h index 2818bdf..989a398 100644 --- a/src/app/DataStruct.h +++ b/src/app/DataStruct.h @@ -1,975 +1,31 @@ -#pragma - -#include -#include "common/JsonN.h" +#pragma once +#include +#include -// EMS遥信 -struct EMSYX +struct RegAddrUnit { - uint16_t bms; //BMS(电池堆)通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint64_t bcu; //BCU(电池簇)通信状态 R uint64 "0:正常 1:故障" bit位从低到高分别对应1~64 - uint16_t mcu; //PCU(主控)通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint64_t pcs; //PCS(模块)通信状态 R uint64 "0:正常 1:故障" bit位从低到高分别对应1~64 - uint16_t electMeterMainPoint; //电表总接点通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint32_t electMeter; //电表通信状态 R uint32 "0:正常 1:故障" bit位从低到高分别对应1~32 - uint16_t fireSystem; //消防通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint16_t ups; //UPS通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint16_t temHumMainPoint; //温湿度总接点通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint32_t temHum; //温湿度通信状态 R uint32 "0:正常 1:故障" bit位从低到高分别对应1~32 - uint16_t aircMainPoint; //空调总接点通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint32_t airc; //空调通信状态 R uint32 "0:正常 1:故障" bit位从低到高分别对应1~32 - uint16_t controlDryContact; //控制干接点(配电系统)状态 R uint16 "0:开路 1:闭合" bit位从低到高分别对应1~16 - uint16_t statusDryContact; //状态干接点(配电系统)状态 R uint16 "0:开路 1:闭合" bit位从低到高分别对应1~16 - uint16_t bcuMain; //BCU总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t pcuMain; //PCU总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t electMeterMain; //电表总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t fireSystemMain; //消防总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t upsMain; //UPS总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t temHumMain; //温湿度总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t aircMain; //空调总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t emu; //EMU通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t chillerMain; //冷机总通信状态 R uint16 0:正常 1:告警 2:故障 - uint16_t chillerMainPoint; //冷机总接点通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - uint16_t chiller; //冷机通信状态 R uint16 "0:正常 1:故障" bit位从低到高分别对应1~16 - //预留 - //预留 - uint16_t energyStatus; //判断总表的三相总有功 < -5.0fkW 充电 >5.0fkW放电 否则停机 R uint16 0:充电 1 : 放电 2 : 停机 储能状态 + std::string key; + std::string datatype; + int bytes {0}; + std::string remark; + int ratio {1}; - void fromJson(const std::string& str); - std::string toJson(); + RegAddrUnit() {} + RegAddrUnit(std::string key, std::string datatype, std::string remark) + : key(key), datatype(datatype), remark(remark) + { + if (datatype == "uint16" || datatype == "int16") { bytes = 1; } + else if (datatype == "uint32" || datatype == "int32") { bytes = 2; } + } }; -// EMS遥测 -struct EMSYC +class REGAddr { - //BMS(电池堆)个数 R uint16 1 0x1001 - //BCU通道个数 R uint16 1~2 0x1002 - //BCU(电池簇)个数 R uint16 1~40 0x1003 - //PCU(主控)个数 R uint16 1~4 0x1004 - //PCU通道个数 R uint16 1~4 0x1005 - //PCS(模块)个数 R uint16 1~40 0x1006 - //电表通道个数 R uint16 1 0x1007 - //电表个数 R uint16 1~10 0x1008 - //消防通道个数 R uint16 1~10 0x1009 - //消防个数 R uint16 1~10 0x100A - //UPS通道个数 R uint16 1~10 0x100B - //UPS个数 R uint16 1~10 0x100C - //温湿度通道个数 R uint16 1 0x100D - //温湿度个数 R uint16 1~10 0x100E - //空调通道个数 R uint16 1 0x100F - //空调个数 R uint16 1~10 0x1010 - //控制干接点(配电系统)个数 R uint16 16 0x1011 - //状态干接点(配电系统)个数 R uint16 16 0x1012 - //预留 0x1013~0x1071 - //预留 - //预留 - //预留 - //预留 - //预留 - //预留 - //预留 - //预留 - //系统最大可充电功率 R uint32 1KW Pcu数据 0x1072 储能侧 - //系统最大可放电功率 R uint32 1KW 0x1074 - //储能母线电压 R uint32 0.1V 堆数据 0x1076 - //储能母线电流 R int32 0.1A 0x1078 - //储能系统SOC R uint16 0.1 0x107A - //储能系统SOH R uint16 0.1 0x107B - //电流变比 R uint16 电表总表数据 0x107C - //电压变比 R uint16 0x107D - //A相电压 R uint32 1V 0x107E - //B相电压 R uint32 1V 0x1080 - //C相电压 R uint32 1V 0x1082 - //A相电流 R int32 1A 0x1084 - //B相电流 R int32 1A 0x1086 - //C相电流 R int32 1A 0x1088 - //AB相电压 R uint32 1V 0x108A - //BC相电压 R uint32 1V 0x108C - //CA相电压 R uint32 1V 0x108E - //A相有功功率 R int32 1kW 0x1090 - //B相有功功率 R int32 1kW 0x1092 - //C相有功功率 R int32 1kW 0x1094 - //三相总有功功率 R int32 1kW 0x1096 - //当前控制功率 R int32 0.1kW 堆数据 0x1098 - //负荷率 R uint32 1% 台区控制策略数据 0不拿 大于0 默认拿第一个 0x109A - //三相不平衡度  R uint32 1% 0x109C - //功率因素比率  R uint32 1% 0x109E - //进线开关柜功率 R int32 1kW 并网口电表 0x10A0 - //用户关口表功率 R int32 1kW 并网口电表 0x10A2 - //预留 0x10A4~0x1103 - //预留 - //正向总有功总需量 R int32 1kW 0x1104 收益 总表 - //尖段电价 R uint32 1RMB 0x1106 - //峰段电价 R uint32 1RMB 0x1108 - //平段电价 R uint32 1RMB 0x110A - //谷段电价 R uint32 1RMB 0x110C - //日充电电量 R uint32 1kWh 0x110E - //日放电电量 R uint32 1kWh 0x1110 - //日充电费用 R uint32 1RMB 0x1112 - //日放电费用 R uint32 1RMB 0x1114 - //日收益 R int32 1RMB 0x1116 - //日正向尖有功电能 R uint32 1kWh 0x1118 - //日正向峰有功电能 R uint32 1kWh 0x111A - //日正向平有功电能 R uint32 1kWh 0x111C - //日正向谷有功电能 R uint32 1kWh 0x111E - //日正向总有功电能 R uint32 1kWh 0x1120 - //日反向尖有功电能 R uint32 1kWh 0x1122 - //日反向峰有功电能 R uint32 1kWh 0x1124 - //日反向平有功电能 R uint32 1kWh 0x1126 - //日反向谷有功电能 R uint32 1kWh 0x1128 - //日反向总有功电能 R uint32 1kWh 0x112A - //总充电电量 R uint32 1kWh 0x112C - //总放电电量 R uint32 1kWh 0x112E - //总充电费用 R uint32 1RMB 0x1130 - //总放电费用 R uint32 1RMB 0x1132 - //总收益 R int32 1RMB 0x1134 - //总正向尖有功电能 R uint32 1kWh 0x1136 - //总正向峰有功电能 R uint32 1kWh 0x1138 - //总正向平有功电能 R uint32 1kWh 0x113A - //总正向谷有功电能 R uint32 1kWh 0x113C - //总正向总有功电能 R uint32 1kWh 0x113E - //总反向尖有功电能 R uint32 1kWh 0x1140 - //总反向峰有功电能 R uint32 1kWh 0x1142 - //总反向平有功电能 R uint32 1kWh 0x1144 - //总反向谷有功电能 R uint32 1kWh 0x1146 - //总反向总有功电能 R uint32 1kWh 0x1148 - //预留 0x114A~0x11AD - //预留 - //预留 - //交流A相电压 R int16 1V 0x11AE 电网侧 并网口电表 - //交流B相电压 R int16 1V 0x11AF - //交流C相电压 R int16 1V 0x11B0 - //交流A相频率 R int16 1Hz 0x11B1 Pcs - //交流B相频率 R int16 1Hz 0x11B2 - //交流C相频率 R int16 1Hz 0x11B3 - //总直流功率 R int32 1kW 0x11B4 堆 - //总直流电压 R uint32 0.1V 0x11B6 - //总直流电流 R int32 0.1A 0x11B8 - //预留 0x11B9~0x121A - //预留 - //预留 - //储能系统温度 R int16 0.1℃ 堆里面单体温度最高 0x121B 充放电运行状态 - //储能充放电时段hh R uint16 时 0x01 0x121C 普通控制功率取 默认给0 - //储能充放电时段mm R uint16 分 0x01 0x121D - //储能充放电时段ss R uint16 秒 0x01 0x121E - //储能系统各时段功率 R int16 1kW 0x01 0x121F -}; +public: + static std::map> s_mapReg; -// EMS遥调 -struct EMSYT -{ - //EMS工作模式 RW uint16 - "0:无效 1:本地控制模式, EMS不接受平台调控 2 : 平台控制模式, EMS接收平台调控指令" 0x0001 - //有功功率 RW int16 kW "并网恒功率模式下交流侧功率值: <0 : 充电功率 0 : 静置 >0 : 放电功率" 0x0002 - //PCS开关机 RW uint16 - "0: 关机 1 : 开机" 软件开关机 0x0003 - //主控对象 RW uint16 "储能遥控对象:0:无效 1:华云 2:轻舟" 0x0004 - //A相有功功率 RW int16 1kW 0x0005 - //B相有功功率 RW int16 1kW 0x0006 - //C相有功功率 RW int16 1kW 0x0007 - //三相总有功功率 RW int16 1kW 0x0008 - //A相无功功率 RW int16 1kVar 0x0009 - //B相无功功率 RW int16 1kVar 0x000A - //C相无功功率 RW int16 1kVar 0x000B - //三相总无功功率 RW int16 1kVar 0x000C - //A相电流 RW int16 0.01A 在使用的时候除以100转float 0x000D - //B相电流 RW int16 0.01A 0x000E - //C相电流 RW int16 0.01A 0x000F - //A相电压 RW uint16 1V 0x0010 - //B相电压 RW uint16 1V 0x0011 - //C相电压 RW uint16 1V 0x0012 - //A相交流功率因数 RW int16 0.01 在使用的时候除以100转float 0x0013 - //B相交流功率因数 RW int16 0.01 0x0014 - //C相交流功率因数 RW int16 0.01 0x0015 - //A相视在功率 RW int16 1kVA 0x0016 - //B相视在功率 RW int16 1kVA 0x0017 - //C相视在功率 RW int16 1kVA 0x0018 - //正向总有功总需量 RW int16 1kW 0x0019 - //数据有效性 RW int16 0无效 1有效 0x001A - //EMS工作模式 RW uint16 - "0:无效 1:本地控制模式, EMS不接受平台调控 2 : 平台控制模式, EMS接收平台调控指令" 2413项目需求 0x001B - //有功功率 RW uint16 kW "并网恒功率模式下交流侧功率值:功率绝对值 没有正负" 2413项目需求 0x001C - //充放电类型 RW uint16 - "0: 关机 1 : 充电 2 : 放电 3 : 待机" "2413项目需求充放电类型" 0x001D - //最大SOC RW uint16 2413项目需求 0x001E - //最小SOC RW uint16 2413项目需求 0x001F - //自动并离网 RW uint16 "0:手动 1:自动" "2332项目需求(若为自动,则通过主控进行并离网切换)" 0x0020 - //并网离网 RW uint16 "0:并网 1:离网" "2332项目需求(该下发参数的前提为手动模式下)" 0x0021 -}; + static void load(std::string filename); - -// PCU遥信 -struct PCUYX -{ - //所属通道号 R uint16 1~4 0x1001 - //故障状态 R uint16 1故障,0正常 0x1002 - //告警状态 R uint16 1告警,0正常 0x1003 - //设备在线 R uint16 1在线,0无效 0x1004 - //本地远程 R uint16 1本地,0远程 0x1005 - //启停状态 R uint16 1开机,0关机 0x1006 - //电网状态 R uint16 1离网,0并网 0x1007 - //模块状态 R uint16 1开机,0待机 0x1008 - //EPO急停 R uint16 1故障,0正常 0x1009 - //防雷器异常 R uint16 1告警,0正常 0x100A - //负载电压反序 R uint16 1故障,0正常 0x100B - //市电电压反序 R uint16 1故障,0正常 0x100C - //输出相反序 R uint16 1故障,0正常 0x100D - //过载告警 R uint16 1告警,0正常 0x100E - //过载超时 R uint16 1故障,0正常 0x100F - //交流过流保护 R uint16 1故障,0正常 0x1010 - //逆变电压异常 R uint16 1故障,0正常 0x1011 - //内部串口异常 R uint16 1故障,0正常 0x1012 - //485通信故障 R uint16 1故障,0正常 0x1013 - //CAN通信故障 R uint16 1故障,0正常 0x1014 - //E2PROM故障 R uint16 1故障,0正常 0x1015 - //电网过压 R uint16 1故障,0正常 0x1016 - //电网欠压 R uint16 1故障,0正常 0x1017 - //电网过频 R uint16 1故障,0正常 0x1018 - //电网欠频 R uint16 1故障,0正常 0x1019 - //电网快检综合异常 R uint16 1故障,0正常 0x101A - //电网幅值快检异常 R uint16 1故障,0正常 0x101B - //电网拖尾异常 R uint16 1故障,0正常 0x101C - //消防输入信号NO R uint16 1闭合,0断开 0x101D - //急停按钮信号NC R uint16 1急停,0正常 0x101E - //避雷器NC R uint16 1故障,0正常 0x101F - //避雷器断路器NC R uint16 1故障,0正常 0x1020 - //PCS总断路器NC R uint16 1闭合,0断开 0x1021 - //电操状态NO R uint16 1闭合,0断开 0x1022 - //远程关机NO R uint16 1开机,0无效 0x1023 - //远程开机NO R uint16 1开机,0无效 0x1024 - //BA故障信号NO R uint16 1故障,0正常 0x1025 - //PCS_01状态 R uint16 1在线,0掉线 0x1026 - //PCS_02状态 R uint16 1在线,0掉线 0x1027 - //PCS_03状态 R uint16 1在线,0掉线 0x1028 - //PCS_04状态 R uint16 1在线,0掉线 0x1029 - //PCS_05状态 R uint16 1在线,0掉线 0x102A - //PCS_06状态 R uint16 1在线,0掉线 0x102B - //PCS_07状态 R uint16 1在线,0掉线 0x102C - //PCS_09状态 R uint16 1在线,0掉线 0x102D - //PCS_10状态 R uint16 1在线,0掉线 0x102E - //PCS_01下发设置 R uint16 1故障,0正常 0x102F - //PCS_02下发设置 R uint16 1故障,0正常 0x1030 - //PCS_03下发设置 R uint16 1故障,0正常 0x1031 - //PCS_04下发设置 R uint16 1故障,0正常 0x1032 - //PCS_05下发设置 R uint16 1故障,0正常 0x1033 - //PCS_06下发设置 R uint16 1故障,0正常 0x1034 - //PCS_07下发设置 R uint16 1故障,0正常 0x1035 - //PCS_08下发设置 R uint16 1故障,0正常 0x1036 - //PCS_09下发设置 R uint16 1故障,0正常 0x1037 - //PCS_10下发设置 R uint16 1:故障,0正常 0x1038 - //内部DSP通信故障 R uint16 1 : 故障,0正常 0x1039 - //BMS CAN通信故障 R uint16 1 : 故障,0正常 0x103A - //下发设置失败 R uint16 1 : 故障,0正常 0x103B -}; - -// PCU 遥测 -struct PCUYC -{ - //所属通道号 R uint16 1~4 0x0001 - //充电功率最大许可 R uint32 1KW 0x0002 - //放电功率最大许可 R uint32 1KW 0x0004 - //交流日总充电量 R uint32 1KWh 0x0006 - //交流日总放电量 R uint32 1KWh 0x0008 - //交流总充电量 R uint32 1KWh 0x000A - //交流总放电量 R uint32 1KWh 0x000C - //有功功率期望值 R int16 1KW 0x000E - //无功功率期望值 R int16 1kVar 0x000F - //PCS侧线电压VAB R int16 1v 0x0010 - //PCS侧线电压VBC R int16 1v 0x0011 - //PCS侧线电压VCA R int16 1v 0x0012 - //PCS侧线A相电压 R int16 1v 0x0013 - //PCS侧线B相电压 R int16 1v 0x0014 - //PCS侧线C相电压 R int16 1v 0x0015 - //PCS侧A相频率 R int16 1Hz 0x0016 - //PCS侧B相频率 R int16 1Hz 0x0017 - //PCS侧C相频率 R int16 1Hz 0x0018 - //PCS侧功率因数A R int16 1 0x0019 - //PCS侧功率因数B R int16 1 0x001A - //PCS侧功率因数C R int16 1 0x001B - //PCS侧相电流A R int16 1A 0x001C - //PCS侧相电流B R int16 1A 0x001D - //PCS侧相电流C R int16 1A 0x001E - //PCS侧有功功率A R int16 1kW 0x001F - //PCS侧有功功率B R int16 1kW 0x0020 - //PCS侧有功功率C R int16 1kW 0x0021 - //PCS侧无功功率A R int16 1kVar 0x0022 - //PCS侧无功功率B R int16 1kVar 0x0023 - //PCS侧无功功率C R int16 1kVar 0x0024 - //PCS侧视在功率A R int16 1kVar 0x0025 - //PCS侧视在功率B R int16 1kVar 0x0026 - //PCS侧视在功率C R int16 1kVar 0x0027 - //PCS侧三相总有功功率 R int16 1kW 0x0028 - //PCS侧三相总无功功率 R int16 1kVar 0x0029 - //PCS侧三相总视在功率 R int16 1kVA 0x002A - //PCS侧三相总功率因数 R int16 1 0x002B - //PCU模块温度 R int16 1℃ 0x002C - //外部温度NTC1 R int16 1℃ 0x002D - //外部温度NTC2 R int16 1℃ 0x002E - //外部温度NTC3 R int16 1℃ 0x002F - //台区负载侧A相电流 R int16 1A 0x0030 - //台区负载侧B相电流 R int16 1A 0x0031 - //台区负载侧C相电流 R int16 1A 0x0032 - //台区负载侧A相有功功率 R int16 1kW 0x0033 - //台区负载侧B相有功功率 R int16 1kW 0x0034 - //台区负载侧C相有功功率 R int16 1kW 0x0035 - //台区负载侧总有功功率 R int16 1kW 0x0036 - //台区负载侧A相无功功率 R int16 1kVar 0x0037 - //台区负载侧B相无功功率 R int16 1kVar 0x0038 - //台区负载侧C相无功功率 R int16 1kVar 0x0039 - //台区负载侧总无功功率 R int16 1kVar 0x003A - //台区负载侧A相视在功率 R int16 1kVA 0x003B - //台区负载侧B相视在功率 R int16 1kVA 0x003C - //台区负载侧C相视在功率 R int16 1kVA 0x003D - //台区负载侧总视在功率 R int16 1kVA 0x003E - //台区负载侧A相功率因数 R int16 1 0x003F - //台区负载侧B相功率因数 R int16 1 0x0040 - //台区负载侧C相功率因数 R int16 1 0x0041 - //台区负载侧总功率因数 R int16 1 0x0042 - //负载侧线电压AB R int16 1V 0x0043 - //负载侧线电压BC R int16 1V 0x0044 - //负载侧线电压CA R int16 1V 0x0045 - //负载侧相电压AN R int16 1V 0x0046 - //负载侧相电压BN R int16 1V 0x0047 - //负载侧相电压CN R int16 1V 0x0048 - //负载侧A功率因素 R int16 1 0x0049 - //负载侧B功率因素 R int16 1 0x004A - //负载侧C功率因素 R int16 1 0x004B - //负载侧A视在功率 R int16 1kVA 0x004C - //负载侧B视在功率 R int16 1kVA 0x004D - //负载侧C视在功率 R int16 1kVA 0x004E -}; - -// PCS 遥信 -struct PCSYX -{ - //所属主控号 R uint16 1~4 0x1001 - //所属PCS号 R uint16 1~40 0x1002 - //故障状态 R uint16 1故障,0正常 0x1003 - //告警状态 R uint16 1告警,0正常 0x1004 - //设备在线 R uint16 1在线,0无效 0x1005 - //禁止充电 R uint16 1禁止,0无效 0x1006 - //禁止放电 R uint16 1禁止,0无效 0x1007 - //运行状态 R uint16 1开机,0关机 0x1008 - //充放状态 R uint16 0:待机, 1:充电, 2:放电, 3:搁置 0x1009 - //电网状态 R uint16 1离网,0并网 0x100A - //逆变供电 R uint16 0禁止,1使能 0x100B - //缓启动完成 R uint16 0禁止,1使能 0x100C - //主机标志 R uint16 0禁止,1使能 0x100D - //并离网状态 R uint16 0:并网, 1:离网 0x100E - //同步请求标志 R uint16 0:无效;1:动作 0x100F - //绝缘故障 R uint16 1:故障,0正常 0x1010 - //漏电保护 R uint16 1 : 故障,0正常 0x1011 - //直流过压 R uint16 1 : 故障,0正常 0x1012 - //市电幅值异常 R uint16 1 : 故障,0正常 0x1013 - //市电相序异常 R uint16 1 : 故障,0正常 0x1014 - //温度开关异常 R uint16 1 : 故障,0正常 0x1015 - //市电频率异常 R uint16 1 : 故障,0正常 0x1016 - //IGBT过温 R uint16 1 : 故障,0正常 0x1017 - //交流接地故障 R uint16 1 : 故障,0正常 0x1018 - //逆变过流异常 R uint16 1 : 故障,0正常 0x1019 - //直流缓起故障 R uint16 1 : 故障,0正常 0x101A - //直流主继电器故障 R uint16 1 : 故障,0正常 0x101B - //风机异常 R uint16 1 : 故障,0正常 0x101C - //主接触器异常 R uint16 1 : 故障,0正常 0x101D - //均浮充切换超时 R uint16 1 : 故障,0正常 0x101E - //硬件故障 R uint16 1 : 故障,0正常 0x101F - //机内过温 R uint16 1 : 故障,0正常 0x1020 - //软启动故障 R uint16 1 : 故障,0正常 0x1021 - //触摸屏通讯故障 R uint16 1 : 故障,0正常 0x1022 - //防雷器故障 R uint16 1 : 故障,0正常 0x1023 - //急停故障 R uint16 1 : 故障,0正常 0x1024 - //BMS系统故障 R uint16 1 : 故障,0正常 0x1025 - //BMS通讯故障 R uint16 1 : 故障,0正常 0x1026 - //BMS干接点通讯故障 R uint16 1 : 故障,0正常 0x1027 - //远程通讯故障 R uint16 1 : 故障,0正常 0x1028 - //门禁告警 R uint16 1 : 故障,0正常 0x1029 - //锁相异常 R uint16 1 : 故障,0正常 0x102A - //IGBT过温告警 R uint16 1 : 故障,0正常 0x102B - //硬件过流保护 R uint16 1 : 故障,0正常 0x102C - //驱动故障 R uint16 1 : 故障,0正常 0x102D - //ID冲突 R uint16 1 : 故障,0正常 0x102E - //电池过压 R uint16 1 : 故障,0正常 0x102F - //电池欠压 R uint16 1 : 故障,0正常 0x1030 - //直流过流保护 R uint16 1 : 故障,0正常 0x1031 - //输出电压异常 R uint16 1 : 故障,0正常 0x1032 - //离网输出电压不符合 R uint16 1 : 故障,0正常 0x1033 - //输出过载保护 R uint16 1 : 故障,0正常 0x1034 - //输出短路保护 R uint16 1 : 故障,0正常 0x1035 - //并机通信异常 R uint16 1 : 故障,0正常 0x1036 - //电池保险异常 R uint16 1 : 故障,0正常 0x1037 - //电池重载低压 R uint16 1 : 故障,0正常 0x1038 - //电池低压告警 R uint16 1 : 故障,0正常 0x1039 - //一拖二压差过大 R uint16 1 : 故障,0正常 0x103A - //电池反接故障 R uint16 1 : 故障,0正常 0x103B - //电池电压异常 R uint16 1 : 故障,0正常 0x103C - //过载告警 R uint16 1 : 故障,0正常 0x103D - //外部接触器异常 R uint16 1 : 故障,0正常 0x103E - //IGBT温度传感器异常 R uint16 1 : 故障,0正常 0x103F - //整机温度传感器异常 R uint16 1 : 故障,0正常 0x1040 - //市电CT异常 R uint16 1 : 故障,0正常 0x1041 - //逆变电流三相不平衡 R uint16 1 : 故障,0正常 0x1042 - //逆变电流直流分量异常 R uint16 1 : 故障,0正常 0x1043 - //母线不平衡 R uint16 1 : 故障,0正常 0x1044 - //逆变电压直流分量异常 R uint16 1 : 故障,0正常 0x1045 - //主接触器控制异常 R uint16 1 : 故障,0正常 0x1046 - //逆变电压控制异常 R uint16 1 : 故障,0正常 0x1047 - //直流霍尔异常 R uint16 1 : 故障,0正常 0x1048 - //电池单体过压 R uint16 1 : 故障,0正常 0x1049 - //电池单体欠压 R uint16 1 : 故障,0正常 0x104A - //电网过压 R uint16 1 : 故障,0正常 0x104B - //电网欠压 R uint16 1 : 故障,0正常 0x104C - //电网过频 R uint16 1 : 故障,0正常 0x104D - //电网欠频 R uint16 1 : 故障,0正常 0x104E - //市电不平衡 R uint16 1 : 故障,0正常 0x104F - //参数设置不匹配 R uint16 1 : 故障,0正常 0x1050 - //SPI通信异常 R uint16 1 : 故障,0正常 0x1051 - //SCI通信异常 R uint16 1 : 故障,0正常 0x1052 - //IIC通信异常 R uint16 1 : 故障,0正常 0x1053 - //Xintf通信异常 R uint16 1 : 故障,0正常 0x1054 - //零偏校准异常 R uint16 1 : 故障,0正常 0x1055 - //烟雾告警 R uint16 1 : 故障,0正常 0x1056 - //无电池组故障 R uint16 1异常,0正常 0x1057 - //环温降频 R uint16 1异常,0正常 0x1058 - //交流过载 R uint16 1异常,0正常 0x1059 - //采样异常 R uint16 1异常,0正常 0x105A - //24V辅源故障 R uint16 1异常,0正常 0x105B - //直流欠压异常 R uint16 1异常,0正常 0x105C - //散热器过温 R uint16 1异常,0正常 0x105D - //CAN配置故障 R uint16 1异常,0正常 0x105E - //3.3V辅源故障 R uint16 1异常,0正常 0x105F - //环境过温 R uint16 1异常,0正常 0x1060 - //A相IGBT逆变过流 R uint16 1异常,0正常 0x1061 - //B相IGBT逆变过流 R uint16 1异常,0正常 0x1062 - //C相IGBT逆变过流 R uint16 1异常,0正常 0x1063 -}; - -// PCS 遥测 -struct PCSYC -{ - //所属主控号 R uint16 1~4 0x0001 - //所属PCS号 R uint16 1~40 0x0002 - //总充电量 R uint32 1kWh 0x0003 - //总放电量 R uint32 1kWh 0x0005 - //散热器温度 R int16 1℃ 0x0007 - //内部温度 R int16 1℃ 0x0008 - //最大允许充电功率 R int16 0.1kW 0x0009 - //最大允许放电功率 R int16 0.1kW 0x000A - //有功功率期望 R int16 1kWh 0x000B - //无功功率期望 R int16 1kVar 0x000C - //AB线电压 R int16 1V 0x000D - //BC线电压 R int16 1V 0x000E - //CA线电压 R int16 1V 0x000F - //A相电压 R int16 1V 0x0010 - //B相电压 R int16 1V 0x0011 - //C相电压 R int16 1V 0x0012 - //A相频率 R int16 1Hz 0x0013 - //B相频率 R int16 1Hz 0x0014 - //C相频率 R int16 1Hz 0x0015 - //A相功率因数 R int16 1 0x0016 - //B相功率因数 R int16 1 0x0017 - //C相功率因数 R int16 1 0x0018 - //A相电流 R int16 1A 0x0019 - //B相电流 R int16 1A 0x001A - //C相电流 R int16 1A 0x001B - //A相有功功率 R int16 1kW 0x001C - //B相有功功率 R int16 1kW 0x001D - //C相有功功率 R int16 1kW 0x001E - //A相无功功率 R int16 1kVar 0x001F - //B相无功功率 R int16 1kVar 0x0020 - //C相无功功率 R int16 1kVar 0x0021 - //A相视在功率 R int16 1kVA 0x0022 - //B相视在功率 R int16 1kVA 0x0023 - //C相视在功率 R int16 1kVA 0x0024 - //三相总有功功率 R int16 1kW 0x0025 - //三相总无功功率 R int16 1kVar 0x0026 - //三相总视在功率 R int16 1kVA 0x0027 - //三相总功率因数 R int16 1 0x0028 - //直流功率 R int16 1kW 0x0029 - //直流电压 R int16 1V 0x002A - //直流电流 R int16 1A 0x002B - //充电功率 R int16 1kW 0x002C - //放电功率 R int16 1kW 0x002D - //PF值 R int16 1 0x002E - //UV线/U相电网计量线电压 R int16 1V 0x002F - //VW线/V相电网计量线电压 R int16 1V 0x0030 - //WU线/W相电网计量线电压 R int16 1V 0x0031 - //U相电网计量电流 R int16 1A 0x0032 - //V相电网计量电流 R int16 1A 0x0033 - //W相电网计量电流 R int16 1A 0x0034 - //正母线电压 R int16 1V 0x0035 - //可用功率 R int16 1kVA 0x0036 - //负母线电压 R int16 1V 0x0037 - //A相IGBT温度 R int16 1℃ 0x0038 - //B相IGBT温度 R int16 1℃ 0x0039 - //C相IGBT温度 R int16 1℃ 0x003A - //逆变侧AB线电压 R int16 1V 0x003B - //逆变侧BC线电压 R int16 1V 0x003C - //逆变侧CA线电压 R int16 1V 0x003D - //逆变侧A相电压 R int16 1V 0x003E - //逆变侧B相电压 R int16 1V 0x003F - //逆变侧C相电压 R int16 1V 0x0040 - //逆变侧A相电流 R int16 1A 0x0041 - //逆变侧B相电流 R int16 1A 0x0042 - //逆变侧C相电流 R int16 1A 0x0043 - //逆变侧A相电流直流分量 R int16 1A 0x0044 - //逆变侧B相电流直流分量 R int16 1A 0x0045 - //逆变侧C相电流直流分量 R int16 1A 0x0046 - //离网频率 R int16 1Hz 0x0047 - //A相负载量 R int16 1 0x0048 - //B相负载量 R int16 1 0x0049 - //C相负载量 R int16 1 0x004A - //总负载量 R int16 1 0x004B - //逆变侧AB线电压直流分量 R int16 1A 0x004C - //逆变侧BC线电压直流分量 R int16 1A 0x004D - //逆变侧CA线电压直流分量 R int16 1A 0x004E - //在线数量 R int16 0x004F - //逆变数量 R int16 0x0050 -}; - -// BMS 遥测 -struct BMSYC -{ - //SOC R uint16 0.1 0x0001 - //SOH R uint16 0.1 0x0002 - //电压 R uint32 0.1V 0x0003 - //电流 R int32 0.1A 0x0005 - //可充电量 R uint32 1kWh 0x0007 - //可放电量 R uint32 1kWh 0x0009 - //单次可充电量 R uint32 1kWh 0x000B - //单次可放电量 R uint32 1kWh 0x000D - //堆功率 R int32 1kW 0x000F - //充电量累加 R uint32 1kWh 0x0011 - //放电量累加 R uint32 1kWh 0x0013 - //簇最大SOC R uint16 0.1 0x0015 - //簇最小SOC R uint16 0.1 0x0016 - //簇最大SOC号 R uint16 0x0017 - //簇最小SOC号 R uint16 0x0018 - //簇SOC差值 R uint16 0.1 0x0019 - //簇最大电压 R uint16 0.1V 0x001A - //簇最小电压 R uint16 0.1V 0x001B - //簇最大电压号 R uint16 0x001C - //簇最小电压号 R uint16 0x001D - //簇电压差值 R uint16 0.1V 0x001E - //单体最大电压簇号 R uint16 0x001F - //单体最大电压节号 R uint16 0x0020 - //单体最大电压 R uint16 mV 0x0021 - //单体最小电压簇号 R uint16 0x0022 - //单体最小电压节号 R uint16 0x0023 - //单体最小电压 R uint16 mV 0x0024 - //单体平均电压 R uint16 mV 0x0025 - //单体电压差 R uint16 mV 0x0026 - //单体最大温度簇号 R uint16 0x0027 - //单体最大温度节号 R uint16 0x0028 - //单体最大温度 R int16 0.1℃ 0x0029 - //单体最小温度簇号 R uint16 0x002A - //单体最小温度节号 R uint16 0x002B - //单体最小温度 R int16 0.1℃ 0x002C - //单体平均温度 R int16 0.1℃ 0x002D - //单体温度差 R int16 0.1℃ 0x002E - //最大内阻簇号 R uint16 0x002F - //最大内阻节号 R uint16 0x0030 - //最大内阻 R uint16 mΩ 0x0031 - //最小内阻簇号 R uint16 0x0032 - //最小内阻节号 R uint16 0x0033 - //最小内阻 R uint16 mΩ 0x0034 - //单体平均内阻 R uint16 mΩ 0x0035 - //单体内阻差 R uint16 mΩ 0x0036 - //单体最大SOH簇号 R uint16 0x0037 - //单体最大SOH节号 R uint16 0x0038 - //单体最大SOH R uint16 0.10% 0x0039 - //单体最小SOH簇号 R uint16 0x003A - //单体最小SOH节号 R uint16 0x003B - //单体最小SOH R uint16 0.10% 0x003C - //单体最大SOc簇号 R uint16 0x003D - //单体最大SOc节号 R uint16 0x003E - //单体最大Soc R uint16 0.10% 0x0040 - //单体最小SOc簇号 R uint16 0x0041 - //单体最小SOc节号 R uint16 0x0042 - //单体最小SOc R uint16 0.10% 0x0043 - //系统剩余最大可充电功率 R uint32 1KW 0x0043 - //系统剩余最大可放电功率 R uint32 1KW 0x0045 - //可充电状态 R uint16 1:可充电;0:不可充电 0x0047 - //可放电状态 R uint16 1:可放电;0:不可放电 0x0048 - //运行状态 R uint16 运行状态 0-正常 1-告警 2-保护 0x0049 - //充放电状态 R uint16 0-待机 1-充电 2-放电 0x004A - -}; - - -// BCU遥信 -struct BCUYX -{ - //所属通道号 R uint16 1~4 0xA001 - //所属BCU号 R uint16 1~40 0xA002 - //蓄电池充放电状态 R uint16 "0x11开路 - //0x22待机 - //0x33充电 - //0x44放电" 0xA003 - //电池组运行状态 R uint16 "0x11跳机 - //0x22待机 - //0x33放空 - //0x44充满 - //0x55预警 - //0x66正常" 0xA004 - //簇DO1状态 R uint16 1:断开 2:闭合 0xA005 - //簇DO2状态 R uint16 1:断开 2:闭合 0xA006 - //继电器总正 R uint16 0:断开 1:闭合 2:粘连 0xA007 - //继电器总负 R uint16 0 : 断开 1:闭合 2:粘连 0xA008 - //继电器预充 R uint16 0 : 断开 1:闭合 2:粘连 0xA009 - //继电器bmu供电 R uint16 0 : 断开 1:闭合 2:粘连 0xA00A - //整簇总电压过高告警 R uint16 0:正常 1:告警 0xA00B - //整簇总电压过低告警 R uint16 0:正常 1:告警 0xA00C - //整簇中单体电压过高告警 R uint16 0:正常 1:告警 0xA00D - //整簇中单体电压过低告警 R uint16 0:正常 1:告警 0xA00E - //整簇中单体电压偏差过大告警 R uint16 0:正常 1:告警 0xA00F - //整簇中单体温度偏差过大告警 R uint16 0:正常 1:告警 0xA010 - //整簇中单体温度过高告警 R uint16 0:正常 1:告警 0xA011 - //整簇中单体温度过低告警 R uint16 0:正常 1:告警 0xA012 - //整簇总充电电流过高告警 R uint16 0:正常 1:告警 0xA013 - //整簇总放电电流过高告警 R uint16 0:正常 1:告警 0xA014 - //整簇总SOC过高告警 R uint16 0:正常 1:告警 0xA015 - //整簇总SOC过低告警 R uint16 0:正常 1:告警 0xA016 - //高压盒主正接触器粘连告警 R uint16 0:正常 1:告警 0xA017 - //高压盒主正接触器不能吸合告警 R uint16 0:正常 1:告警 0xA018 - //高压盒主负接触器粘连告警 R uint16 0:正常 1:告警 0xA019 - //高压盒主负接触器不能吸合告警 R uint16 0:正常 1:告警 0xA01A - //高压盒预充接触器粘连告警 R uint16 0:正常 1:告警 0xA01B - //高压盒预充接触器不能吸合告警 R uint16 0:正常 1:告警 0xA01C - //预充失败告警 R uint16 0:正常 1:告警 0xA01D - //BCU电压检测模块出现问题告警 R uint16 0:正常 1:告警 0xA01E - //BCU温度检测模块出现问题告警 R uint16 0:正常 1:告警 0xA01F - //BCU电流检测模块出现问题告警 R uint16 0:正常 1:告警 0xA020 - //BCU绝缘检测模块出现问题告警 R uint16 0:正常 1:告警 0xA021 - //高压盒内总压检测模块出现问题告警 R uint16 0:正常 1:告警 0xA022 - //高压盒外总压检测模块出现问题告警 R uint16 0:正常 1:告警 0xA023 - //PCS-CAN通信故障告警 R uint16 0:正常 1:告警 0xA024 - //高压盒供电电压过高告警 R uint16 0:正常 1:告警 0xA025 - //绝缘正极故障告警 R uint16 0:正常 1:告警 0xA026 - //绝缘负极故障告警 R uint16 0:正常 1:告警 0xA027 - //绝缘中间侧故障告警 R uint16 0:正常 1:告警 0xA028 - //绝缘故障告警 R uint16 0:正常 1:告警 0xA029 - //BMU中电压采样线开路告警 R uint16 0:正常 1:告警 0xA02A - //BMU中NTC采样线短开路告警 R uint16 0:正常 1:告警 0xA02B - //BMU中采样芯片故障告警 R uint16 0:正常 1:告警 0xA02C - //BMU中电池温度升高过快告警 R uint16 0:正常 1:告警 0xA02D - //BMU中电池内部短路告警 R uint16 0:正常 1:告警 0xA02E - //BMU充电均衡模块出现故障告警 R uint16 0:正常 1:告警 0xA02F - //BMU放电均衡模块出现故障告警 R uint16 0:正常 1:告警 0xA030 - //BMU通信故障告警 R uint16 0:正常 1:告警 0xA031 - //单体内阻过大告警 R uint16 0:正常 1:告警 0xA032 - //单体内阻过小告警 R uint16 0:正常 1:告警 0xA033 - //单体内阻阻差过大告警 R uint16 0:正常 1:告警 0xA034 - //簇内阻过大告警 R uint16 0:正常 1:告警 0xA035 - //簇内阻过小告警 R uint16 0:正常 1:告警 0xA036 - //SOC初始化无效告警 R uint16 0:正常 1:告警 0xA037 - //充电时soc降低故障告警 R uint16 0:正常 1:告警 0xA038 - //放电时soc升高告警 R uint16 0:正常 1:告警 0xA039 - //静止时SOC跳变告警 R uint16 0:正常 1:告警 0xA03A - //整簇总电压过高保护 R uint16 0:正常 1:保护 0xA03B - //整簇总电压过低保护 R uint16 0:正常 1:保护 0xA03C - //整簇中单体电压过高保护 R uint16 0:正常 1:保护 0xA03D - //整簇中单体电压过低保护 R uint16 0:正常 1:保护 0xA03E - //整簇中单体电压偏差过大保护 R uint16 0:正常 1:保护 0xA03F - //整簇中单体温度偏差过大保护 R uint16 0:正常 1:保护 0xA040 - //整簇中单体温度过高保护 R uint16 0:正常 1:保护 0xA041 - //整簇中单体温度过低保护 R uint16 0:正常 1:保护 0xA042 - //整簇总充电电流过高保护 R uint16 0:正常 1:保护 0xA043 - //整簇总放电电流过高保护 R uint16 0:正常 1:保护 0xA044 - //整簇总SOC过高保护 R uint16 0:正常 1:保护 0xA045 - //整簇总SOC过低保护 R uint16 0:正常 1:保护 0xA046 - //高压盒主正接触器粘连保护 R uint16 0:正常 1:保护 0xA047 - //高压盒主正接触器不能吸合保护 R uint16 0:正常 1:保护 0xA048 - //高压盒主负接触器粘连保护 R uint16 0:正常 1:保护 0xA049 - //高压盒主负接触器不能吸合保护 R uint16 0:正常 1:保护 0xA04A - //高压盒预充接触器粘连保护 R uint16 0:正常 1:保护 0xA04B - //高压盒预充接触器不能吸合保护 R uint16 0:正常 1:保护 0xA04C - //预充失败保护 R uint16 0:正常 1:保护 0xA04D - //BCU电压检测模块出现问题保护 R uint16 0:正常 1:保护 0xA04E - //BCU温度检测模块出现问题保护 R uint16 0:正常 1:保护 0xA04F - //BCU电流检测模块出现问题保护 R uint16 0:正常 1:保护 0xA050 - //BCU绝缘检测模块出现问题保护 R uint16 0:正常 1:保护 0xA051 - //高压盒内总压检测模块出现问题保护 R uint16 0:正常 1:保护 0xA052 - //高压盒外总压检测模块出现问题保护 R uint16 0:正常 1:保护 0xA053 - //PCS-CAN通信故障保护 R uint16 0:正常 1:保护 0xA054 - //高压盒供电电压过高保护 R uint16 0:正常 1:保护 0xA055 - //绝缘正极故障保护 R uint16 0:正常 1:保护 0xA056 - //绝缘负极故障保护 R uint16 0:正常 1:保护 0xA057 - //绝缘中间侧故障保护 R uint16 0:正常 1:保护 0xA058 - //绝缘故障保护 R uint16 0:正常 1:保护 0xA059 - //BMU中电压采样线开路保护 R uint16 0:正常 1:保护 0xA05A - //BMU中NTC采样线短开路保护 R uint16 0:正常 1:保护 0xA05B - //BMU中采样芯片故障保护 R uint16 0:正常 1:保护 0xA05C - //BMU中电池温度升高过快保护 R uint16 0:正常 1:保护 0xA05D - //BMU中电池内部短路保护 R uint16 0:正常 1:保护 0xA05E - //BMU充电均衡模块出现故障保护 R uint16 0:正常 1:保护 0xA05F - //BMU放电均衡模块出现故障保护 R uint16 0:正常 1:保护 0xA060 - //BMU通信故障保护 R uint16 0:正常 1:保护 0xA061 - //单体内阻过大保护 R uint16 0:正常 1:保护 0xA062 - //单体内阻过小保护 R uint16 0:正常 1:保护 0xA063 - //单体内阻阻差过大保护 R uint16 0:正常 1:保护 0xA064 - //簇内阻过大保护 R uint16 0:正常 1:保护 0xA065 - //簇内阻过小保护 R uint16 0:正常 1:保护 0xA066 - //SOC初始化无效保护 R uint16 0:正常 1:保护 0xA067 - //充电时soc降低故障保护 R uint16 0:正常 1:保护 0xA068 - //放电时soc升高保护 R uint16 0:正常 1:保护 0xA069 - //静止时SOC跳变保护 R uint16 0:正常 1:保护 0xA06A -}; - -// BCU遥测 -struct BCUYC -{ - //所属通道号 R uint16 1~4 0x0001 - //所属BCU号 R uint16 1~40 0x0002 - //簇电压 R uint32 0.1V 0x0003 - //簇电流 R int32 0.1A 0x0005 - //簇温度 R int32 0.1℃ 0x0007 - //簇电阻 R uint32 1mΩ 0x0009 - //簇SOC R uint16 0.1 0x000B - //簇SOH R uint16 0.1 0x000C - //簇正绝缘电阻 R uint32 1kΩ 0x000D - //簇负绝缘电阻 R uint32 1kΩ 0x000F - //簇允许最大充电电流 R int32 0.1A 0x0011 - //簇允许最大放电电流 R int32 0.1A 0x0013 - //簇允许最大充电功率 R uint32 1kW 0x0015 - //簇允许最大放电功率 R uint32 1kW 0x0017 - //簇可充容量 R uint32 0.1Ah 0x0019 - //簇可放容量 R uint32 0.1Ah 0x001B - //簇单次累计充容量 R uint32 0.1Ah 0x001D - //簇单次累计放容量 R uint32 0.1Ah 0x001F - //簇总累计充容量 R uint32 0.1Ah 0x0021 - //簇总累计放容量 R uint32 0.1Ah 0x0023 - //簇可充电量 R uint32 1kWh 0x0025 - //簇可放电量 R uint32 1kWh 0x0027 - //簇单次充电量 R uint32 1kWh 0x0029 - //簇单次放电量 R uint32 1kWh 0x002B - //簇累计充电量 R uint32 1kWh 0x002D - //簇累计放电量 R uint32 1kWh 0x002F - //pack累计簇总压 R uint32 0.1V 0x0031 - //簇与pack压差 R uint32 0.1V 0x0033 - //簇与PCS压差 R uint32 0.1V 0x0035 - //簇中BMU个数 R uint16 0x0037 - //簇中BMU中单体个数 R uint16 0x0038 - //簇中BMU中温度个数 R uint16 0x0039 - //簇中单体个数 R uint16 0x003A - //簇中温度个数 R uint16 0x003B - //单体最高SOC节号 R uint16 0x003C - //单体最高SOC R uint16 0.1 0x003D - //单体最低SOC节号 R uint16 0x003E - //单体最低SOC R uint16 0.1 0x003F - //单体最高SOH节号 R uint16 0x0040 - //单体最高SOH R uint16 0.1 0x0041 - //单体最低SOH节号 R uint16 0x0042 - //单体最低SOH R uint16 0.1 0x0043 - //单体最高电压节号 R uint16 0x0044 - //单体最高电压 R uint16 mV 0x0045 - //单体最低电压节号 R uint16 0x0046 - //单体最低电压 R uint16 mV 0x0047 - //单体电压差 R uint16 mV 0x0048 - //单体平均电压 R uint16 mV 0x0049 - //单体最高温度节号 R uint16 0x004A - //单体最高温度 R int16 0.1℃ 0x004B - //单体最低温度节号 R uint16 0x004C - //单体最低温度 R int16 0.1℃ 0x004D - //单体温度差 R int16 0.1℃ 0x004E - //单体平均温度 R int16 0.1℃ 0x004F - //单体最高内阻节号 R uint16 0x0050 - //单体最高内阻 R uint16 mΩ 0x0051 - //单体最低内阻节号 R uint16 0x0052 - //单体最低内阻 R uint16 mΩ 0x0053 - //单体内阻差 R uint16 mΩ 0x0054 - //单体平均内阻 R uint16 mΩ 0x0055 - //单体SOC R uint16[1000] 0.1 0x0056~0x043D - //单体SOH R uint16[1000] 0.1 0x043E~0x0825 - //单体电压 R uint16[1000] mV 0x0826~0x0C0D - //单体温度 R int16[1000] 0.01℃ 0x0C0E~0x0FF5 - //单体内阻 R uint16[1000] mΩ 0x0FF6~0x13DD -}; - -// 空调遥信 -struct AirCYX -{ - //所属通道号 R uint16 1 0x1001 - //所属空调号 R uint16 1~10 0x1002 - //开关 R uint16 0:关机,1:开机 0x1003 - //启动制冷指令 R uint16 0:关闭, 1:启动 0x1004 - //启动送风指令 R uint16 0:关闭, 1:启动 0x1005 - //启动待机指令 R uint16 0:关闭, 1:启动 0x1006 - //启动加热指令 R uint16 0:关闭, 1:启动 0x1007 - //传感器故障 R uint16 0:正常,1:告警 0x1008 - //高低电压告警 R uint16 0:正常,1:告警 0x1009 - //高低温告警 R uint16 0:正常,1:告警 0x100A - //高低压告警 R uint16 0:正常,1:告警 0x100B - //压缩机告警 R uint16 0:正常,1:告警 0x100C - -}; - -// 空调遥测 -struct AirCYC -{ - //所属通道号 R uint16 1 0x0001 - //所属空调号 R uint16 1~10 0x0002 - //制冷点 R int16 0.1℃ 0x0003 - //制冷偏差 R int16 0.1℃ 0x0004 - //高温告警值 R int16 0.1℃ 0x0005 - //低温告警值 R int16 0.1℃ 0x0006 - //制热点 R int16 0.1℃ 0x0007 - //制热偏差 R int16 0.1℃ 0x0008 - //当前温度 R int16 0.1℃ 0x0009 - //当前湿度 R int16 0.1℃ 0x000A - //除湿开启温度 R int16 0.1℃ 0x000B - //除湿停止温度 R int16 0.1℃ 0x000C - //除湿开启湿度 R int16 0.1℃ 0x000D - //除湿停止湿度 R int16 0.1℃ 0x000E -}; - -// 电表遥测 -struct EMeterYC -{ - //所属通道号 R uint16 1 0x0001 - //电表地址 R uint16[6] 0x0002~0x0007 - //电表类型 R uint16 "0:储能站总表 - //1:逆变前侧电表 - //2:逆变后侧电表 - //3:配电柜电表 - //4:并网口电表" 0x0008 - //电流变比 R uint16 0x0009 - //电压变比 R uint16 0x000A - //A相电压 R uint32 1V 0x000B - //B相电压 R uint32 1V 0x000D - //C相电压 R uint32 1V 0x000F - //A相电流 R int32 1A 0x0011 - //B相电流 R int32 1A 0x0013 - //C相电流 R int32 1A 0x0015 - //AB相电压 R uint32 1V 0x0017 - //BC相电压 R uint32 1V 0x0019 - //CA相电压 R uint32 1V 0x001B - //A相有功 R int32 1kW 0x001D - //B相有功 R int32 1kW 0x001F - //C相有功 R int32 1kW 0x0021 - //三相总有功 R int32 1kW 0x0023 - //正向总有功总需量 R int32 1kW 0x0025 - //尖段电价 R uint32 1RMB 0x0027 - //峰段电价 R uint32 1RMB 0x0029 - //平段电价 R uint32 1RMB 0x002B - //谷段电价 R uint32 1RMB 0x002D - //日充电电量 R uint32 1kWh 0x002F - //日放电电量 R uint32 1kWh 0x0031 - //日充电费用 R uint32 1RMB 0x0033 - //日放电费用 R uint32 1RMB 0x0035 - //日收益 R int32 1RMB 0x0037 - //日正向尖有功电能 R uint32 1kWh 0x0039 - //日正向峰有功电能 R uint32 1kWh 0x003B - //日正向平有功电能 R uint32 1kWh 0x003D - //日正向谷有功电能 R uint32 1kWh 0x003F - //日正向总有功电能 R uint32 1kWh 0x0041 - //日反向尖有功电能 R uint32 1kWh 0x0043 - //日反向峰有功电能 R uint32 1kWh 0x0045 - //日反向平有功电能 R uint32 1kWh 0x0047 - //日反向谷有功电能 R uint32 1kWh 0x0049 - //日反向总有功电能 R uint32 1kWh 0x004B - //总充电电量 R uint32 1kWh 0x004D - //总放电电量 R uint32 1kWh 0x004F - //总充电费用 R uint32 1RMB 0x0051 - //总放电费用 R uint32 1RMB 0x0053 - //总收益 R int32 1RMB 0x0055 - //总正向尖有功电能 R uint32 1kWh 0x0057 - //总正向峰有功电能 R uint32 1kWh 0x0059 - //总正向平有功电能 R uint32 1kWh 0x005B - //总正向谷有功电能 R uint32 1kWh 0x005D - //总正向总有功电能 R uint32 1kWh 0x005F - //总反向尖有功电能 R uint32 1kWh 0x0061 - //总反向峰有功电能 R uint32 1kWh 0x0063 - //总反向平有功电能 R uint32 1kWh 0x0065 - //总反向谷有功电能 R uint32 1kWh 0x0067 - //总反向总有功电能 R uint32 1kWh 0x0069 -}; - -// 温湿度遥测 -struct TemHumYC -{ - //所属通道号 R uint16 1 0x0001 - //所属温湿度号 R uint16 1~10 0x0002 - //温度 R int16 0.1℃ 0x0003 - //湿度 R int16 0.1℃ 0x0004 -}; - -struct Fire20YX -{ - // 测点太多(1000多个) -}; - -struct Fire30YX -{ - // 测点太多(1000多个) -}; - -struct Fire40YX -{ - //所属通道号 R uint16 1~10 0x0001 - //主控数量 R uint16 1 0x0002 - //主控ID R uint16 1 0x0003 - //主控状态 R uint16 0:正常 1:预警 2:火警 0x0004 - //主控硬件版本 R uint16[2] 主控硬件版本 0x0005~0x0006 - //主控软件版本 R uint16[2] 主控软件版本 0x0007~0x0008 - //主电状态 R uint16 0:使用市电 1:使用备电 0x0009 - //备电电流 R uint32 0.1A 0x000A - //备电电压 R uint32 0.1V 0x000C - //可用容量 R uint32 0.01Ah 0x000E - //可充放容量 R uint32 0.01Ah 0x0010 - //警铃是否使用 R uint16 0x0012 - //警铃状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0013 - //瓶头阀是否使用 R uint16 0x0014 - //瓶头阀状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0015 - //手报是否使用 R uint16 0x0016 - //手报状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0017 - //簇控制器数量 R uint16 0x0018 - //复合探测器总数量 R uint16 0x0019 - //烟雾探测器总数量 R uint16 0x001A - //压力探测器总数量 R uint16 0x001B - //吸气式探测器总数量 R uint16 0x001C - //PACK探测器总数量 R uint16 0x001D - //电池总数量 R uint16 0x001E - -}; - -// 冷机遥信 -struct ChillerYX -{ - //所属通道号 R uint16 1 0x1001 - //所属冷机号 R uint16 1~10 0x1002 - //开关 R uint16 0:关机,1:开机 0x1003 - //采样模式 R uint16 0-出水温度 1-电芯温度 0x1004 - //制冷状态 R uint16 0:关闭, 1:启动 0x1005 - //制热状态 R uint16 0:关闭, 1:启动 0x1006 - //高温告警 R uint16 0:正常,1:告警 0x1007 - //低温告警 R uint16 0:正常,1:告警 0x1008 - //高压告警 R uint16 0:正常,1:告警 0x1009 - //低压告警 R uint16 0:正常,1:告警 0x100A - //进水温度传感器 R uint16 0:正常,1:告警 0x100B - //出水温度传感器 R uint16 0:正常,1:告警 0x100C - //进水压力传感器 R uint16 0:正常,1:告警 0x100D - //出水压力传感器 R uint16 0:正常,1:告警 0x100E -}; - -// 冷机遥测 -struct ChillerYC -{ - //所属通道号 R uint16 1 0x0001 - //所属冷机号 R uint16 1~10 0x0002 - //制冷点 R int16 0.1℃ 0x0003 - //制冷偏差 R int16 0.1℃ 0x0004 - //高温告警值 R int16 0.1℃ 0x0005 - //低温告警值 R int16 0.1℃ 0x0006 - //制热点 R int16 0.1℃ 0x0007 - //制热偏差 R int16 0.1℃ 0x0008 - //电芯温度 R int16 0.1℃ 0x0009 - //环境湿度 R int16 0.1℃ 0x000A - //吸气温度 R int16 0.1℃ 0x000B - //排气温度 R int16 0.1℃ 0x000C - //进水温度/供液温度 R int16 0.1℃ 0x000D - //出水温度/回液温度 R int16 0.1℃ 0x000E - //进水压力/供液压力 R int16 0.1 0x000F - //出水压力/回液压力 R int16 0.1 0x0010 - //高压压力 R int16 0.1 0x0011 - //低压压力 R int16 0.1 0x0012 - //循环水泵转速 R int16 0x0013 - //压缩机频率 R int16 0x0014 - //室外风机转速 R int16 0x0015 + static std::map* getRegMap(std::string name); }; \ No newline at end of file diff --git a/src/app/Device.cpp b/src/app/Device.cpp index 8c95cb2..5fcce92 100644 --- a/src/app/Device.cpp +++ b/src/app/Device.cpp @@ -7,13 +7,14 @@ #include -std::map> Device::s_mapDeviceParamAddr; +std::map> Device::s_mapDeviceAddrParam; +std::map> Device::s_mapDeviceAddrCurve; static std::vector& GetDeviceParamAddrs(int deviceType) { static std::vector vecAddrs = {}; - auto iter = Device::s_mapDeviceParamAddr.find(deviceType); - if (iter != Device::s_mapDeviceParamAddr.end()) + auto iter = Device::s_mapDeviceAddrParam.find(deviceType); + if (iter != Device::s_mapDeviceAddrParam.end()) { return iter->second; } @@ -47,11 +48,10 @@ void Device::loadParamAddr(std::string filename) { std::string key = jsonitem.key(); auto& jsonnodeItem = jsonitem.value(); - spdlog::info(jsonnodeItem.dump()); int type = jsonnodeItem["deviceType"]; - auto& vec = s_mapDeviceParamAddr[type]; - for (auto& v : jsonnodeItem["addr_YC"]) + auto& vec = s_mapDeviceAddrParam[type]; + for (auto& v : jsonnodeItem["addrYC"]) { std::string name = JSON::get(v[0]); std::string addr = JSON::get(v[1]); @@ -60,6 +60,14 @@ void Device::loadParamAddr(std::string filename) float ratio = Utils::toFloat(JSON::get(v[4])); vec.push_back(DeviceParamAddr(name, addr, defaultVal, unit, ratio)); } + if (jsonnodeItem.contains("addrCurve")) + { + auto& vec = s_mapDeviceAddrCurve[type]; + for (auto& v : jsonnodeItem["addrCurve"]) + { + vec.push_back(v.get()); + } + } } } catch (nlohmann::json::parse_error& e) @@ -70,6 +78,7 @@ void Device::loadParamAddr(std::string filename) void Device::setFields(Fields& fields) { + fields.get("station_id", this->stationId); fields.get("device_id", this->deviceId); fields.get("type", this->type); fields.get("name", this->name); @@ -77,6 +86,7 @@ void Device::setFields(Fields& fields) fields.get("is_open", this->isOpen); fields.get("attrs", this->attrsJson); fields.get("category", this->category); + fields.get("sort_no", this->sortNo); // 解析属性的JSON字符串,转换成键值对 njson jsonroot; @@ -216,11 +226,27 @@ bool Device::cache(int npos) mapCacheCurrent.clear(); mapCachePower.clear(); } - // 根据设备类型从参数(寄存器地址)中读取实时数据进行保存 - mapCacheVoltage[npos] = Utils::random(100, 200); - mapCacheCurrent[npos] = Utils::random(100, 200); - mapCachePower[npos] = Utils::random(100, 200); + std::string addrV; + std::string addrI; + std::string addrP; + auto iter = s_mapDeviceAddrCurve.find(this->type); + if (iter != s_mapDeviceAddrCurve.end()) + { + auto& vecAddr = iter->second; + auto size = addrV.size(); + if (size >= 1) { addrV = vecAddr[0]; } + else if (size >= 2) { addrI = vecAddr[1]; } + else if (size >= 3) { addrP = vecAddr[2]; } + } + + // 根据设备类型从参数(寄存器地址)中读取实时数据进行保存 + int U = Utils::toInt(this->getParam(addrV, "0")); + int I = Utils::toInt(this->getParam(addrI, "0")); + int P = addrP.empty() ? U*I : Utils::toInt(this->getParam(addrP, "0")); + mapCacheVoltage[npos] = U; + mapCacheCurrent[npos] = I; + mapCachePower[npos] = P; return true; } @@ -235,10 +261,10 @@ void Device::setParam(std::string k, int v) if (iter != mapMyParams.end()) { ratio = iter->second->ratio; - spdlog::info("[device] set param: {} {}={}, ratio={}", iter->second->name, k, v, ratio); + //spdlog::info("[device] set param: {} {}={}, ratio={}", iter->second->name, k, v, ratio); } - int precision = (ratio != 1.0f) ? 2 : 0; + int precision = (ratio != 1.0f) ? 1 : 0; mapParams[k] = Utils::toStr(v*ratio, precision); if (type == 3 ) // 电表 @@ -280,6 +306,10 @@ void Device::setParam(std::string k, int v) std::string Device::getParam(std::string k, std::string defaultVal) { + if (k.empty()) + { + return defaultVal; + } auto iter = mapParams.find(k); if (iter != mapParams.end()) { @@ -298,10 +328,14 @@ void Device::getRuntimeParams(std::vector>& // 105 BCU // 106 充电桩 // 109 光伏板 - auto& vecAddr = s_mapDeviceParamAddr[this->type]; + auto& vecAddr = s_mapDeviceAddrParam[this->type]; for (auto& itemAddr: vecAddr) { - params.push_back({itemAddr.name, getParam(itemAddr.addr, itemAddr.defaultVal) + itemAddr.unit}); + std::string v; + v = getParam(itemAddr.addr, itemAddr.defaultVal) + itemAddr.unit; + //if (this->online) { } + //else { v = "--"; } + params.push_back({itemAddr.name, v}); } } diff --git a/src/app/Device.h b/src/app/Device.h index 187cd6b..d044dfd 100644 --- a/src/app/Device.h +++ b/src/app/Device.h @@ -56,15 +56,18 @@ public: void getRuntimeParams1(std::vector>& params); public: - static std::map> s_mapDeviceParamAddr; + static std::map> s_mapDeviceAddrParam; + static std::map> s_mapDeviceAddrCurve; - int deviceId = -1; - int type = -1; + int stationId = {0}; + int deviceId = {0}; + int type = {0}; std::string name; std::string code; int category; bool isOpen = false; std::string attrsJson = ""; + int sortNo {0}; int err = 0; int online = 0; diff --git a/src/app/Station.cpp b/src/app/Station.cpp index a9b9062..b5eb7c2 100644 --- a/src/app/Station.cpp +++ b/src/app/Station.cpp @@ -14,10 +14,6 @@ Station::Station() : stationId(0) mqttCli = std::make_shared(); // 测试,设置默认值 - for (int i = 1; i<=5; i++) { mapTempHumUnit[i] = TempHumUnit(Utils::random(20, 40), Utils::random(20, 80)); } - - for (int i = 1; i<=5; i++) { mapFire40Unit[i] = 0; } - for (int i = 1; i<=5; i++) { auto& unit = mapCoolingUnit[i]; unit.powerOn = 1; @@ -41,6 +37,7 @@ void Station::setFields(Fields& fields) this->code = fields.value(DMStation::CODE); this->status = fields.get(DMStation::STATUS); this->operationDate = fields.value(DMStation::OPERATION_DATE); + this->isOpen = fields.get(DMStation::STATUS); this->policy.setFields(fields); } @@ -48,7 +45,6 @@ void Station::setFields(Fields& fields) void Station::addDevice(int deviceId, std::shared_ptr device) { mapDevice[deviceId] = device; - mapDeviceGroup[device->category].push_back(device); } void Station::addDevice(Fields& fields) @@ -63,7 +59,6 @@ void Station::addDevice(Fields& fields) { auto device = Device::create(fields); mapDevice[deviceId] = device; - mapDeviceGroup[device->category].push_back(device); } } @@ -77,6 +72,17 @@ std::shared_ptr Station::getDevice(int deviceId) return nullptr; } +void Station::groupDevice() +{ + for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter) + { + auto& device = iter->second; + char key[20] = {}; + sprintf(key, "%03d_%03d_%04d", device->stationId, device->sortNo, device->deviceId); + mapDeviceGroup[device->category][key] = device; + } +} + std::shared_ptr Station::getDeviceByType(int deviceType, std::string code) { for (auto iter = mapDevice.begin(); iter!=mapDevice.end(); ++iter) @@ -112,12 +118,17 @@ int Station::getDeviceCount(int category) return 0; } -void Station::getDeviceByGroup(int category, std::vector>& res) +void Station::getDeviceByCategory(int category, std::vector>& res) { auto iter = mapDeviceGroup.find(category); if (iter != mapDeviceGroup.end()) { - res = iter->second; + res.resize(iter->second.size()); + int i = 0; + for (auto& item: iter->second) + { + res[i++] = item.second; + } } } @@ -185,6 +196,32 @@ void Station::writeRuntimeData(std::string dt, int npos) } } +void Station::writeStatistic(std::string dt) +{ + Fields fields; + fields.set("storage_elect_in", statData.totalElectIn); + fields.set("storage_elect_out", statData.totalElectOut); + //fields.set("storage_num_in", statData.totalElectIn); + //fields.set("storage_num_out", 0); + //fields.set("storage_num_err", 0); + //fields.set("storage_t_in", 0); + //fields.set("storage_t_out", 0); + //fields.set("storage_usage", 0); + //fields.set("solar_elect_gen", 0); + //fields.set("solar_elect_grid", 0); + //fields.set("solar_num_err", 0); + //fields.set("solar_t", 0); + //fields.set("solar_usage", 0); + //fields.set("charge_elect", 0); + //fields.set("charge_num", 0); + //fields.set("charge_num_err", 0); + //fields.set("charge_t", 0); + //fields.set("charge_usage", 0); + fields.set("income_elect", statData.totalIncome); + //fields.set("income_charge", 0); + //fields.set("usage_rate", 0); +} + void Station::initMqtt() { if (status!=0 && mqttCli) @@ -229,3 +266,78 @@ void Station::setGarewayWorkMode() spdlog::info(text); mqttCli->publish("Gateway_YT", text); } + + +void Station::setRuntimeData(string addr, int val) +{ + if (addr == "0x110E") { statData.dayElectIn = val; } //日充电电量 R uint32 1kWh 0 0x110E + else if (addr == "0x1110") { statData.dayElectOut = val; } //日放电电量 R uint32 1kWh 0 0x1110 + else if (addr == "0x1112") { statData.dayIncomeIn = val; } //日充电费用 R uint32 1RMB 0 0x1112 + else if (addr == "0x1114") { statData.dayIncomeOut = val; } //日放电费用 R uint32 1RMB 0 0x1114 + else if (addr == "0x1116") { statData.dayIncome = val; } //日收益 R int32 1RMB 0 0x1116 + else if (addr == "0x112C") { statData.totalElectIn = val; } //总充电电量 R uint32 1kWh 6659(0x112D) 0x112C + else if (addr == "0x112E") { statData.totalElectOut = val; } //总放电电量 R uint32 1kWh 4925(0x112F) 0x112E + else if (addr == "0x1130") { statData.totalIncomeIn = val; } //总充电费用 R uint32 1RMB 6605(0x1131) 0x1130 + else if (addr == "0x1132") { statData.totalIncomeOut = val; } //总放电费用 R uint32 1RMB 4949(0x1133) 0x1132 + else if (addr == "0x1134") { statData.totalIncome = val; } //总收益 R int32 1RMB -1 0x1134 +} + +void Station::setTHData(int deviceNo, string addr, int val) +{ + auto& unit = mapTempHumUnit[deviceNo]; + if (addr == "0x0001") { ; } //所属通道号 R uint16 1 0x0001 + else if (addr == "0x0002") { ; } //所属温湿度号 R uint16 1~10 0x0002 + else if (addr == "0x0003") { unit.temp = float(val) * 0.1; } //温度 R int16 0.1℃ 0x0003 + else if (addr == "0x0004") { unit.hum = float(val) * 0.1; } //湿度 R int16 0.1℃ 0x0004 +} + +void Station::setFire40Data(int deviceNo, string addr, int val) +{ + auto& unit = mapFire40Unit[deviceNo]; + + if (addr == "0x0001") { ; } //所属通道号 R uint16 1~10 0x0001 + else if (addr == "0x0002") { ; } //主控数量 R uint16 1 0x0002 + else if (addr == "0x0003") { ; } //主控ID R uint16 1 0x0003 + else if (addr == "0x0004") { unit.statusMain = val; } //主控状态 R uint16 0:正常 1:预警 2:火警 0x0004 + else if (addr == "0x0005") { ; } //主控硬件版本 R uint16[2] 主控硬件版本 0x0005 + else if (addr == "0x0007") { ; } //主控软件版本 R uint16[2] 主控软件版本 0x0007 + else if (addr == "0x0009") { ; } //主电状态 R uint16 0:使用市电 1:使用备电 0x0009 + else if (addr == "0x000A") { ; } //备电电流 R uint32 0.1A 0x000A + else if (addr == "0x000C") { ; } //备电电压 R uint32 0.1V 0x000C + else if (addr == "0x000E") { ; } //可用容量 R uint32 0.01Ah 0x000E + else if (addr == "0x0010") { ; } //可充放容量 R uint32 0.01Ah 0x0010 + else if (addr == "0x0012") { unit.usedAlarm = val; } //警铃是否使用 R uint16 0x0012 + else if (addr == "0x0013") { unit.statusAlarm = val; } //警铃状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0013 + else if (addr == "0x0014") { unit.usedValve = val; } //瓶头阀是否使用 R uint16 0x0014 + else if (addr == "0x0015") { unit.statusValve = val; } //瓶头阀状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0015 + else if (addr == "0x0016") { unit.usedMCP = val; } //手报是否使用 R uint16 0x0016 + else if (addr == "0x0017") { unit.statusMCP = val; } //手报状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0017 + else if (addr == "0x0018") { ; } //簇控制器数量 R uint16 0x0018 + else if (addr == "0x0019") { ; } //复合探测器总数量 R uint16 0x0019 + else if (addr == "0x001A") { ; } //烟雾探测器总数量 R uint16 0x001A + else if (addr == "0x001B") { ; } //压力探测器总数量 R uint16 0x001B + else if (addr == "0x001C") { ; } //吸气式探测器总数量 R uint16 0x001C + else if (addr == "0x001D") { ; } //PACK探测器总数量 R uint16 0x001D + else if (addr == "0x001E") { ; } //电池总数量 R uint16 0x001E +} + + +void Station::setCoolingData(int deviceNo, string addr, int val) +{ + auto& unit = mapCoolingUnit[deviceNo]; + + if (addr == "0x1001") { ; } //所属通道号 R uint16 1 0x1001 + else if (addr == "0x1002") { ; }// 所属冷机号 R uint16 1~10 0x1002 + else if (addr == "0x1003") { unit.powerOn = val; }// 开关 R uint16 0:关机,1:开机 0x1003 + else if (addr == "0x1004") { ; }// 采样模式 R uint16 0-出水温度 1-电芯温度 0x1004 + else if (addr == "0x1005") { unit.cooling = val; }// 制冷状态 R uint16 0:关闭, 1:启动 0x1005 + else if (addr == "0x1006") { unit.heating = val; }// 制热状态 R uint16 0:关闭, 1:启动 0x1006 + else if (addr == "0x1007") { unit.highTemp = val; }// 高温告警 R uint16 0:正常,1:告警 0x1007 + else if (addr == "0x1008") { unit.lowTemp = val; }// 低温告警 R uint16 0:正常,1:告警 0x1008 + else if (addr == "0x1009") { unit.highPressure = val; }// 高压告警 R uint16 0:正常,1:告警 0x1009 + else if (addr == "0x100A") { unit.lowPressure = val; }// 低压告警 R uint16 0:正常,1:告警 0x100A + else if (addr == "0x100B") { ; }// 进水温度传感器 R uint16 0:正常,1:告警 0x100B + else if (addr == "0x100C") { ; }// 出水温度传感器 R uint16 0:正常,1:告警 0x100C + else if (addr == "0x100D") { ; }// 进水压力传感器 R uint16 0:正常,1:告警 0x100D + else if (addr == "0x100E") { ; }// 出水压力传感器 R uint16 0:正常,1:告警 0x100E +} \ No newline at end of file diff --git a/src/app/Station.h b/src/app/Station.h index 335be31..e14a641 100644 --- a/src/app/Station.h +++ b/src/app/Station.h @@ -10,9 +10,9 @@ class MqttClient; struct TempHumUnit { - int temp {0}; - int hum {0}; - TempHumUnit(int temp, int hum) : temp(temp), hum(hum) {}; + float temp {0}; + float hum {0}; + TempHumUnit(float temp, float hum) : temp(temp), hum(hum) {}; TempHumUnit() {} }; @@ -20,7 +20,7 @@ struct Fire40Unit { //主控数量 R uint16 1 0x0002 //主控ID R uint16 1 0x0003 - //主控状态 R uint16 0:正常 1:预警 2:火警 0x0004 + int statusMain {0}; //主控状态 R uint16 0:正常 1:预警 2:火警 0x0004 //主控硬件版本 R uint16[2] 主控硬件版本 0x0005~0x0006 //主控软件版本 R uint16[2] 主控软件版本 0x0007~0x0008 //主电状态 R uint16 0:使用市电 1:使用备电 0x0009 @@ -28,12 +28,12 @@ struct Fire40Unit //备电电压 R uint32 0.1V 0x000C //可用容量 R uint32 0.01Ah 0x000E //可充放容量 R uint32 0.01Ah 0x0010 - //警铃是否使用 R uint16 0x0012 - //警铃状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0013 - //瓶头阀是否使用 R uint16 0x0014 - //瓶头阀状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0015 - //手报是否使用 R uint16 0x0016 - //手报状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0017 + int usedAlarm {0}; //警铃是否使用 R uint16 0x0012 + int statusAlarm {0}; //警铃状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0013 + int usedValve {0}; //瓶头阀是否使用 R uint16 0x0014 + int statusValve {0}; //瓶头阀状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0015 + int usedMCP {0}; //手报是否使用 R uint16 0x0016 + int statusMCP {0}; //手报状态 R uint16 0:无效 1:掉线 2:正常 3:启动 0x0017 // Manual Call Point (MCP) //簇控制器数量 R uint16 0x0018 //复合探测器总数量 R uint16 0x0019 //烟雾探测器总数量 R uint16 0x001A @@ -98,21 +98,29 @@ public: void addDevice(int deviceId, std::shared_ptr device); void addDevice(Fields& fields); std::shared_ptr getDevice(int deviceId); + + void groupDevice(); std::shared_ptr getDeviceByType(int deviceType, std::string code); void getDeviceByType(int typeId, std::vector>& res); int getDeviceCount(int category); - void getDeviceByGroup(int category, std::vector>& res); + void getDeviceByCategory(int category, std::vector>& res); void setWorkMode(int modeId); void setPolicy(int policyId); void writeRuntimeData(std::string dt, int npos); + void writeStatistic(std::string dt); void initMqtt(); void polling(); void setGarewayWorkMode(); + void setRuntimeData(string addr, int val); + void setTHData(int deviceNo, string addr, int val); + void setFire40Data(int deviceNo, string addr, int val); + void setCoolingData(int deviceNo, string addr, int val); + public: int stationId {}; std::string name; @@ -127,6 +135,8 @@ public: int workModeId {}; // 运行模式 int runPolicyId {}; // 运行策略 + + /////////////////////////////////////////////////////////////////////////////////////////////// /// === 系统统计 === // 累计发电量,单位:kWh @@ -179,13 +189,13 @@ public: /////////////////////////////////////////////////////////////////////////////////////////////// /// === 设备信息 === std::unordered_map> mapDevice; - std::map>> mapDeviceGroup; + std::map>> mapDeviceGroup; // 温湿度信息 std::map mapTempHumUnit; // 消防4.0信息 - std::map mapFire40Unit; + std::map mapFire40Unit; // 冷机信息 std::map mapCoolingUnit; // 空调信息 @@ -195,5 +205,32 @@ public: /// === MQTT client std::shared_ptr mqttCli {nullptr}; - + + struct { + int64_t ts; + + double totalElectIn; //总充电电量 R uint32 1kWh 6659(0x112D) 0x112C + double totalElectOut; //总放电电量 R uint32 1kWh 4925(0x112F) 0x112E + double totalIncomeIn; //总充电费用 R uint32 1RMB 6605(0x1131) 0x1130 + double totalIncomeOut; //总放电费用 R uint32 1RMB 4949(0x1133) 0x1132 + double totalIncome; //总收益 R int32 1RMB -1 0x1134 + //储能充放电时段hh R uint16 时 336 0x01 0x121C + //储能充放电时段mm R uint16 分 0 0x01 0x121D + //储能充放电时段ss R uint16 秒 0 0x01 0x121E + + double totalDurationIn; + double totalDurationOut; + + double dayElectIn; // 日充电电量 R uint32 1kWh 0 0x110E + double dayElectOut; // 日放电电量 R uint32 1kWh 0 0x1110 + double dayIncomeIn; // 日充电费用 R uint32 1RMB 0 0x1112 + double dayIncomeOut; // 日放电费用 R uint32 1RMB 0 0x1114 + double dayIncome; // 日收益 R int32 1RMB 0 0x1116 + + } statData; + + /////////////////////////////////////////////////////////////////////////////////////////////// + struct { + } runtimeData; + }; \ No newline at end of file diff --git a/src/database/Dao.cpp b/src/database/Dao.cpp index bd41202..d41476b 100644 --- a/src/database/Dao.cpp +++ b/src/database/Dao.cpp @@ -96,7 +96,7 @@ static Errcode QueryCount(DaoEntity& dao, std::string sqlFrom, int& count) } -static Errcode QueryPagination(std::string sqlFields, std::string sqlCondition, PageInfo& page, vector& result) +static Errcode QueryPagination(std::string sqlFields, std::string sqlFrom, PageInfo& page, vector& result) { DaoEntity dao(""); if (!dao.isConnected()) @@ -104,7 +104,7 @@ static Errcode QueryPagination(std::string sqlFields, std::string sqlCondition, return Errcode::ERR_DB_CONN; } int count {0}; - Errcode err = QueryCount(dao, sqlCondition, count); + Errcode err = QueryCount(dao, sqlFrom, count); if (err != Errcode::OK) { return err; @@ -113,7 +113,7 @@ static Errcode QueryPagination(std::string sqlFields, std::string sqlCondition, if (page.index < 1) page.index = 1; if (page.size <= 0) page.size = 10; page.total = count; - std::string sql = "SELECT " + sqlFields + " " + sqlCondition + DAO::sqlPageLimit(page.index -1, page.size); + std::string sql = "SELECT " + sqlFields + " " + sqlFrom + DAO::sqlPageLimit(page.index -1, page.size); int ret = dao.exec(sql, result); return Errcode(ret); } @@ -432,9 +432,11 @@ Errcode DAO::updateStationById(Fields& params) } // 查询设备信息列表 -Errcode DAO::queryDeviceList(std::shared_ptr dao, vector& result) +Errcode DAO::queryDeviceList(std::shared_ptr dao, vector& result, bool sort/* = false*/) { - std::string sql = "SELECT d.*, ddt.category FROM device d LEFT JOIN def_device_type ddt ON d.`type`=ddt.device_type_id;"; + std::string sql = "SELECT d.*, ddt.category FROM device d LEFT JOIN def_device_type ddt ON d.`type`=ddt.device_type_id"; + if (sort) sql += " ORDER BY station_id, sort_no"; + sql += ";"; return DAO::exec(dao, sql, result); } @@ -554,6 +556,78 @@ Errcode DAO::queryStatDataList(std::shared_ptr dao, std::string start return DAO::exec(dao, sql, result); } +Errcode DAO::queryStatStationGroup(std::shared_ptr dao, string stationId, string category, string startDate, string endDate, vector& result) +{ + std::string sqlCondition; + if (!startDate.empty() && endDate.empty()) + { + sqlCondition += "dt BETWEEN '" + startDate + "' AND '" + endDate + "'"; + } + if (!stationId.empty()) + { + if (!sqlCondition.empty()) sqlCondition += " AND "; + sqlCondition += "station_id='" + stationId + "'"; + } + if (!category.empty() && category != "0") + { + if (!sqlCondition.empty()) sqlCondition += " AND "; + sqlCondition += "category='" + category + "'";; + } + if (!sqlCondition.empty()) { sqlCondition = " WHERE " + sqlCondition; } + + std::string sql = R"(SELECT dt, + SUM(ss.storage_elect_in) storage_elect_in, + SUM(storage_elect_in) storage_elect_in, + SUM(storage_elect_out) storage_elect_out, + SUM(storage_num_in) storage_num_in, + SUM(storage_num_out) storage_num_out, + SUM(storage_num_err) storage_num_err, + SUM(solar_elect_gen) solar_elect_gen, + SUM(solar_elect_grid) solar_elect_grid, + SUM(solar_num_err) solar_num_err, + AVG(storage_usage) storage_usage, + SUM(charge_elect) charge_elect, + SUM(charge_num) charge_num, + SUM(charge_num_err) charge_num_err, + AVG(charge_usage) charge_usage, + SUM(income_elect) income_elect, + SUM(income_charge) income_charge + FROM stat_station ss)" + sqlCondition + "GROUP by dt;"; + return DAO::exec(dao, sql, result); +} + +Errcode DAO::queryStatStationList(PageInfo& pageInfo, Fields& params, vector& result) +{ + 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 sqlCondition; + if (!startDate.empty() && endDate.empty()) + { + sqlCondition += "dt BETWEEN '" + startDate + "' AND '" + endDate + "'"; + } + 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; } + + std::string sqlFields = "ss.*, d.name device_name, ddt.name device_type"; + std::string sqlFrom = R"(FROM stat_station 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; + + return QueryPagination(sqlFields, sqlFrom, pageInfo, result); +} + Errcode DAO::queryWorkModeDef(std::shared_ptr dao, vector& result) { std::string sql = "SELECT * FROM " + DMDefWorkMode::TABLENAME + ";"; @@ -566,6 +640,37 @@ Errcode DAO::queryPolicyTypeDef(std::shared_ptr dao, vector& return DAO::exec(dao, sql, result); } +Errcode DAO::insertStatStation(std::shared_ptr dao, Fields& fields) +{ + // 根据主键(dt、station_id、category),写入或更新数据 + if (!dao) { dao = DaoEntity::create("stat_station"); } + std::vector vecKeys = { + "storage_elect_in", + "storage_elect_out", + "storage_num_in", + "storage_num_out", + "storage_num_err", + "storage_t_in", + "storage_t_out", + "storage_usage", + "solar_elect_gen", + "solar_elect_grid", + "solar_num_err", + "solar_t", + "solar_usage", + "charge_elect", + "charge_num", + "charge_num_err", + "charge_t", + "charge_usage", + "income_elect", + "income_charge", + "usage_rate" + }; + int ret = dao->duplicateUpdate(fields, vecKeys); + return Errcode(ret); +} + Errcode DAO::insertRuntimeData(std::shared_ptr dao, Fields& fields) { if (!dao) { dao = DaoEntity::create("history_day"); } diff --git a/src/database/Dao.h b/src/database/Dao.h index 4945f11..795c533 100644 --- a/src/database/Dao.h +++ b/src/database/Dao.h @@ -75,7 +75,7 @@ public: // 查询设备信息列表(分页) static Errcode queryDeviceList(PageInfo& pageInfo, vector& result); // 查询设备信息列表 - static Errcode queryDeviceList(std::shared_ptr dao, vector& result); + static Errcode queryDeviceList(std::shared_ptr dao, vector& result, bool sort=false); // 查询设备类型定义 static Errcode queryDeviceTypeDef(std::shared_ptr dao, vector& result); // 新增设备信息 @@ -113,12 +113,16 @@ public: // === 统计数据管理 === static Errcode queryStatDataList(std::shared_ptr dao, std::string startDate, std::string endDate, vector& result); + static Errcode queryStatStationGroup(std::shared_ptr dao, string stationId, string category, string startDate, string endDate, vector& result); + + static Errcode queryStatStationList(PageInfo& pageInfo, Fields& params, vector& result); + static Errcode queryWorkModeDef(std::shared_ptr dao, vector& result); static Errcode queryPolicyTypeDef(std::shared_ptr dao, vector& result); - + static Errcode insertStatStation(std::shared_ptr dao, Fields& fields); /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/database/DataModelDef.h b/src/database/DataModelDef.h index 35e07b1..eec5e04 100644 --- a/src/database/DataModelDef.h +++ b/src/database/DataModelDef.h @@ -169,7 +169,7 @@ namespace DMLogAlert namespace DMStatStation { - const string TABLENAME = "stat_staion"; + const string TABLENAME = "stat_station"; const string DT = "dt"; const string STATION_ID = "station_id"; const string STORAGE_ELECT_IN = "storage_elect_in"; diff --git a/src/main.cpp b/src/main.cpp index 1cee7a3..980dfd8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -117,10 +117,6 @@ void memberJsonTest() //std::cout << to << std::endl; } - - - - int main(int argc, char** argv) { // 设置控制台输出为 UTF-8 编码 @@ -131,13 +127,13 @@ int main(int argc, char** argv) Spdlogger::init(spdlog::level::debug, ""); spdlog::info("[main] start ... ======================================================================"); - njson json; - json = {1, 2, 3, 4}; - spdlog::info(json.dump()); + qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blacklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --num-raster-threads=4"); // 运行后台服务 Application::instance().init(); + while (1) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); }; + // 启动 PV 服务主线程 //std::thread([=]() // { @@ -154,11 +150,10 @@ int main(int argc, char** argv) // } // }).detach(); - QApplication qapp(argc, argv); - qapp.setWindowIcon(QIcon("./yhicon.ico")); - MainWeb mainWin; - qapp.exec(); - + //QApplication qapp(argc, argv); + //qapp.setWindowIcon(QIcon("./yhicon.ico")); + //MainWeb mainWin; + //qapp.exec(); //QApplication a(argc, argv); //QMainWindow w; @@ -173,8 +168,6 @@ int main(int argc, char** argv) //webView.show(); //a.exec(); - - // 运行QT主窗口 //QApplication qapp(argc, argv); //MainWindow mainWin; diff --git a/src/protocol/HttpEntity.cpp b/src/protocol/HttpEntity.cpp index 1bd8c6b..7a2ba32 100644 --- a/src/protocol/HttpEntity.cpp +++ b/src/protocol/HttpEntity.cpp @@ -165,9 +165,10 @@ static std::map g_mapHttpHandlerGet = {"/queryPredictionDetail", HandlerOptions(&HttpEntity::queryPredictionDetail, {})}, {"/queryStatSystem", HandlerOptions(&HttpEntity::queryStatSystem, {})}, - {"/queryStatStation", HandlerOptions(&HttpEntity::queryStatStation, {})}, + {"/queryStatStation", HandlerOptions(&HttpEntity::queryStatStationGroup, {})}, {"/queryStatTotal", HandlerOptions(&HttpEntity::queryStatTotal, {})}, {"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})}, + {"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})}, {"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})}, {"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})}, @@ -827,7 +828,7 @@ Errcode HttpEntity::queryDevicByCategory(const httplib::Request& req, njson& jso if (station && station->status == 1) { std::vector> vecDevice; - station->getDeviceByGroup(category, vecDevice); + station->getDeviceByCategory(category, vecDevice); for(auto& device: vecDevice) { @@ -1041,13 +1042,13 @@ Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, st return Errcode::OK; } -Errcode HttpEntity::queryStatStation(const httplib::Request& req, njson& json, std::string& errmsg) +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.station_id, s.name station_name, ss.income_elect, ss.income_charge, ss.usage_rate FROM station s LEFT JOIN - (SELECT station_id, SUM(income_elect ) income_elect , SUM(income_charge) income_charge, avg(usage_rate) usage_rate FROM stat_staion GROUP BY station_id) AS ss + std::string sql = R"(SELECT s.station_id, s.name station_name, ss.income_elect, ss.income_charge, ss.storage_usage FROM station s LEFT JOIN + (SELECT station_id, SUM(income_elect ) income_elect , SUM(income_charge) income_charge, avg(storage_usage) storage_usage FROM stat_station GROUP BY station_id) AS ss ON ss.station_id = s.station_id)"; std::vector vecStations; auto err = dao->exec(sql, vecStations); @@ -1056,96 +1057,151 @@ Errcode HttpEntity::queryStatStation(const httplib::Request& req, njson& json, s njson jsonnode; jsonnode["station_name"] = fields.value("station_name"); jsonnode["income"] = fields.get("income_elect") + fields.get("income_charge"); - jsonnode["usage_rate"] = fields.get("usage_rate"); + jsonnode["usage_rate"] = fields.get("storage_usage"); jsondata.push_back(jsonnode); } json["data"] = jsondata; return Errcode(err); } -Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg) +static void VerifyRequstParamsStatDate(Fields& params) { - std::string station_id = req.get_param_value("station_id"); - std::string category = req.get_param_value("category"); - - njson jsondata; - auto station = Application::data().getStation(Utils::toInt(station_id)); - if (station) + if (!params.contains("end_date")) { - jsondata["station_id"] = station_id; - jsondata["launch_date"] = "2025-09-01"; //场站上线日期 - jsondata["usage_rate"] = "12"; - jsondata["storage_elect_in"] = "123.123"; //储能充电电量(kWh),精度:0.001 - jsondata["storage_elect_out"] = "123.123"; //储能放电电量(kWh),精度:0.001 - jsondata["storage_num_in"] = "1"; //储能设备充电次数 - jsondata["storage_num_out"] = "1"; //储能设备放电次数 - jsondata["storage_num_err"] = "1"; //储能设备故障次数 - jsondata["solar_elect_gen"] = "123.123"; //光伏发电电量(kWh),精度:0.001 - jsondata["solar_elect_grid"] = "123.123"; //光伏入网电量(kWh),精度:0.001 - jsondata["solar_num_err"] = "1"; //光伏设备故障次数 - jsondata["charge_elect"] = "123.123"; //充电设备充电电量(kWh),精度:0.001 - jsondata["charge_num"] = "1"; //充电设备充电次数 - jsondata["charge_num_err"] = "1"; //充电设备故障次数 - jsondata["income_elect"] = "123.123"; //发电收益(元),精度:0.01 - jsondata["income_charge"] = "123.123"; //充电收益(元),精度:0.01 - - } - json["data"] = jsondata; - return Errcode::OK; -} - -Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg) -{ - //std::string stationId = req.get_param_value("station_id"); - //std::string category = req.get_param_value("category"); - std::string dtStart = req.get_param_value("start_date"); - std::string dtEnd = req.get_param_value("end_date"); - if (dtEnd.empty()) - { - if (dtStart.empty()) + if (!params.contains("start_date")) { - dtEnd = Utils::dateStr(); - dtStart = Utils::dateStr(Utils::date() - 86400*7); + params.set("end_date", Utils::dateStr()); + params.set("start_date", Utils::dateStr(Utils::date() - 86400*7)); } else { - dtEnd = Utils::dateStr(Utils::time(dtStart + " 00:00:00") + 86400*7); + 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; + GetRequestParam(req, {"station_id", "category", "start_date", "end_date"}, params); + VerifyRequstParamsStatDate(params); + return VerifyStatSqlCondition(params); +} + +Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg) +{ + std::string sqlCondition = GetRequestStatParams(req); + std::string sql = R"(SELECT SUM(ss.storage_elect_in) storage_elect_in, + SUM(storage_elect_in) storage_elect_in, + SUM(storage_elect_out) storage_elect_out, + SUM(storage_num_in) storage_num_in, + SUM(storage_num_out) storage_num_out, + SUM(storage_num_err) storage_num_err, + SUM(solar_elect_gen) solar_elect_gen, + SUM(solar_elect_grid) solar_elect_grid, + SUM(solar_num_err) solar_num_err, + AVG(storage_usage) storage_usage, + SUM(charge_elect) charge_elect, + SUM(charge_num) charge_num, + SUM(charge_num_err) charge_num_err, + AVG(charge_usage) charge_usage, + SUM(income_elect) income_elect, + SUM(income_charge) income_charge + FROM stat_station ss)" + sqlCondition + ";"; std::vector result; - Errcode err = DAO::queryStatDataList(NULL, dtStart, dtEnd, result); + DaoEntity::execOnce(sql, result); + if (result.size() > 0) + { + auto& fields = result[0]; + njson jsondata; + // jsondata["launch_date"] = "2025-09-01"; //场站上线日期 + // jsondata["station_id"] = station_id; + jsondata["storage_elect_in"] = fields.value("storage_elect_in"); //储能充电电量(kWh),精度:0.001 + jsondata["storage_elect_out"] = fields.value("storage_elect_out"); //储能放电电量(kWh),精度:0.001 + jsondata["storage_num_in"] = fields.value("storage_elect_out"); //储能设备充电次数 + jsondata["storage_num_out"] = fields.value("storage_num_out"); //储能设备放电次数 + jsondata["storage_num_err"] = fields.value("storage_num_err"); //储能设备故障次数 + jsondata["solar_elect_gen"] = fields.value("solar_elect_gen"); //光伏发电电量(kWh),精度:0.001 + jsondata["solar_elect_grid"] = fields.value("solar_elect_grid"); //光伏入网电量(kWh),精度:0.001 + jsondata["solar_num_err"] = fields.value("solar_num_err"); //光伏设备故障次数 + jsondata["charge_elect"] = fields.value("charge_elect"); //充电设备充电电量(kWh),精度:0.001 + jsondata["charge_num"] = fields.value("charge_num"); //充电设备充电次数 + jsondata["charge_num_err"] = fields.value("charge_num_err"); //充电设备故障次数 + jsondata["income_elect"] = fields.value("income_elect"); //发电收益(元),精度:0.01 + jsondata["income_charge"] = fields.value("income_charge"); //充电收益(元),精度:0.01 + jsondata["usage_rate"] = Utils::toStr(float(fields.get("storage_usage")+fields.get("storage_usage"))*0.5f, 0); + json["data"] = jsondata; + } + + return Errcode::OK; +} +Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg) +{ + Fields params; + GetRequestParam(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"); + std::vector result; + auto err = DAO::queryStatStationGroup(NULL, stationId, category, startDate, endDate, result); json["data"] = FieldsToJsonArray(result); return err; +} - //int64_t t1 = Utils::time(dtStart); - //int64_t t2 = Utils::time(dtEnd); - //int64_t tMax = t1+ 86400 * 30; - //njson jsondata = njson::array(); - //for (int64_t t = t1; t<=t2 && t<=tMax; t += 86400) - //{ - // njson jnode; - // jnode["station_id"] = station_id; - // if (!category.empty()) jnode["category"] = category; - // jnode["dt"] = Utils::dateStr(t); //日期 - // jnode["storage_elect_in"] = std::to_string(Utils::random(100, 200)); //储能充电电量(kWh),精度:0.001 - // jnode["storage_elect_out"] = std::to_string(Utils::random(100, 200)); //储能放电电量(kWh),精度:0.001 - // jnode["storage_num_in"] = std::to_string(Utils::random(1,5)); //储能设备充电次数 - // jnode["storage_num_out"] = std::to_string(Utils::random(1, 5)); //储能设备放电次数 - // jnode["storage_num_err"] = std::to_string(Utils::random(1, 5)); //储能设备故障次数 - // jnode["solar_elect_gen"] = std::to_string(Utils::random(100, 200)); //光伏发电电量(kWh),精度:0.001 - // jnode["solar_elect_grid "] = std::to_string(Utils::random(100, 200)); //光伏入网电量(kWh),精度:0.001 - // jnode["solar_num_err"] = std::to_string(Utils::random(1, 5)); //光伏设备故障次数 - // jnode["charge_elect"] = std::to_string(Utils::random(100, 200)); //充电设备充电电量(kWh),精度:0.001 - // jnode["charge_num"] = std::to_string(Utils::random(1, 5)); //充电设备充电次数 - // jnode["charge_num_err"] = std::to_string(Utils::random(1, 5)); //充电设备故障次数 - // jnode["income_elect"] = std::to_string(Utils::random(100, 200)); //发电收益(元),精度:0.01 - // jnode["income_charge"] = std::to_string(Utils::random(100, 200)); //充电收益(元),精度:0.01 - // jnode["usage_rate"] = std::to_string(Utils::random(10, 50)); //利用率 - // jsondata.push_back(jnode); - //} - //json["data"] = jsondata; - return Errcode::OK; +//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_station 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; + GetRequestParam(req, {"station_id", "category", "start_date", "end_date"}, params); + + std::vector result; + auto err = DAO::queryStatStationList(pageinfo, params, result); + json["data"] = FieldsToJsonArray(result); + return err; } Errcode HttpEntity::queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg) @@ -1243,7 +1299,6 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, njson& json, s njson nodearray = njson::array(); if (unit) { - njson node; nodearray.push_back({{"pos", "开关"}, {"status", unit->powerOn == 0 ? "关机" : "开机"}}); nodearray.push_back({{"pos", "启动制冷指令"}, {"status", unit->cooling == 0 ? "启动" : "关闭"}}); nodearray.push_back({{"pos", "启动送风指令"}, {"status", unit->airSupply == 0 ? "关闭" : "启动"}}); @@ -1262,14 +1317,22 @@ Errcode HttpEntity::queryEnvironment(const httplib::Request& req, njson& json, s { // 消防 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) { - njson node; - node["pos"] = "#" + std::to_string(iter->first); - node["status"] = mapFireStatusDef[iter->second]; // 0:正常 1:预警 2:火警 - nodearray.push_back(node); + 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.statusAlarm]}}); // 0:无效 1:掉线 2:正常 3:启动 + nodearray.push_back({{"pos", "手报是否使用"}, {"status", unit.usedMCP == 0 ? "否" : "是"}}); + nodearray.push_back({{"pos", "手报状态"}, {"status", mapStatusDef[unit.statusAlarm]}}); // 0:无效 1:掉线 2:正常 3:启动 + break; } jsondata["fire40"] = nodearray; } diff --git a/src/protocol/HttpEntity.h b/src/protocol/HttpEntity.h index 5ea0ac1..edd8418 100644 --- a/src/protocol/HttpEntity.h +++ b/src/protocol/HttpEntity.h @@ -83,13 +83,17 @@ public: // 系统总览所有场站统计 (总览页 运行状况) Errcode queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg); - Errcode queryStatStation(const httplib::Request& req, njson& json, std::string& errmsg); + Errcode queryStatStationGroup(const httplib::Request& req, njson& json, std::string& errmsg); // 一个场站的累计统计 Errcode queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg); // 场站按类别按天统计 Errcode queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg); + //Errcode queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg); + + Errcode queryStatDetailList(const httplib::Request& req, njson& json, std::string& errmsg); + // 场站按类某一天的历史曲线数据 Errcode queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg); diff --git a/src/protocol/MqttEntity.cpp b/src/protocol/MqttEntity.cpp index a0d8296..b12b9e1 100644 --- a/src/protocol/MqttEntity.cpp +++ b/src/protocol/MqttEntity.cpp @@ -5,85 +5,44 @@ #include "app/AppData.h" #include "app/Station.h" #include "app/Device.h" +#include "app/DataStruct.h" #define TIMEOUT 10000L -std::string REGAddrOffset(std::string addr, int offset) -{ - unsigned int val; - std::stringstream ss; - ss << std::hex << addr; - ss >> val; - return Utils::toHexStr(val + offset); -} - -static std::map> g_mapRegInfo; - -void MqttClient::loadDataStruct(std::string filename) -{ - njson json; - JSON::load(filename, json); - - // 遍历 JSON 对象 - for (auto& jsonitem : json.items()) - { - std::string name = jsonitem.key(); - auto& jsonnodeItem = jsonitem.value(); - //int count = jsonnodeItem["count"]; - auto jsonaddrs = jsonnodeItem["addr"]; - - auto& mapItem = g_mapRegInfo[name]; - int size = 0; - for (int i = 0; i<2; ++i) - { - for (auto& item : jsonaddrs) - { - std::string addr = item["key"]; - if (i > 0) - { - addr = REGAddrOffset(addr, size*i); - } - mapItem[addr] = REGInfo(addr, item["datatype"], item["remark"]); - if (i ==0) - { - size += mapItem[addr].bytes; - } - } - } - } -} -// int MqttClient::init(string addr, string clientId, string username, string password) { - if (isConnected) - { - return MQTTASYNC_SUCCESS; - } if (addr.empty()) { return MQTTASYNC_FAILURE; } - + if (isConnected) + { + return MQTTASYNC_SUCCESS; + } + isConnected = false; this->addr = addr; this->clientId = clientId; - this->mapTopicInfo["EMS_YX"] = TopicInfo("EMS_YX", 101); + //this->mapTopicInfo["EMS_YX"] = TopicInfo("EMS_YX", 101); this->mapTopicInfo["EMS_YC"] = TopicInfo("EMS_YC", 101); - this->mapTopicInfo["EMS_YT"] = TopicInfo("EMS_YT", 101); - this->mapTopicInfo["PCS_YX"] = TopicInfo("PCS_YX", 102, 1); - this->mapTopicInfo["PCS_YC"] = TopicInfo("PCS_YC", 102, 1); - this->mapTopicInfo["PCU_YX"] = TopicInfo("PCU_YX", 103); - this->mapTopicInfo["PCU_YC"] = TopicInfo("PCU_YC", 103); - this->mapTopicInfo["BMS_YX"] = TopicInfo("BMS_YX", 104); - this->mapTopicInfo["BMS_YC"] = TopicInfo("BMS_YC", 104); - this->mapTopicInfo["BCU_YX"] = TopicInfo("BCU_YX", 105, 1); - this->mapTopicInfo["BCU_YC"] = TopicInfo("BCU_YC", 105, 1); - this->mapTopicInfo["MEM_YC"] = TopicInfo("MEM_YC", 3); - this->mapTopicInfo["Cooling_YC"] = TopicInfo("Cooling_YC", 110); - this->mapTopicInfo["TH_YC"] = TopicInfo("TH_YC", 111); - this->mapTopicInfo["Gateway_YX"] = TopicInfo("Gateway_YX", 112); - this->mapTopicInfo["Charger_YC"] = TopicInfo("Charger_YC", 113); + //this->mapTopicInfo["EMS_YT"] = TopicInfo("EMS_YT", 101); + //this->mapTopicInfo["PCS_YX"] = TopicInfo("PCS_YX", 102, 1); + //this->mapTopicInfo["PCS_YC"] = TopicInfo("PCS_YC", 102, 1); + //this->mapTopicInfo["PCU_YX"] = TopicInfo("PCU_YX", 103); + //this->mapTopicInfo["PCU_YC"] = TopicInfo("PCU_YC", 103); + //this->mapTopicInfo["BMS_YX"] = TopicInfo("BMS_YX", 104); // BMS没有遥信 + //this->mapTopicInfo["BMS_YC"] = TopicInfo("BMS_YC", 104); + //this->mapTopicInfo["BCU_YX"] = TopicInfo("BCU_YX", 105, 1); + //this->mapTopicInfo["BCU_YC"] = TopicInfo("BCU_YC", 105, 1); + //this->mapTopicInfo["MEM_YC"] = TopicInfo("MEM_YC", 3, 1); + //this->mapTopicInfo["TH_YC"] = TopicInfo("TH_YC", 10, 1); + //this->mapTopicInfo["Fire40_YX"] = TopicInfo("Fire40_YX", 7, 1); + this->mapTopicInfo["Cooling_YC"] = TopicInfo("Cooling_YC", 14, 1); + this->mapTopicInfo["Cooling_YX"] = TopicInfo("Cooling_YX", 14, 1); + //this->mapTopicInfo["Gateway_YX"] = TopicInfo("Gateway_YX", 15, 1); + //this->mapTopicInfo["Gateway_YC"] = TopicInfo("Gateway_YC", 15, 1); + //this->mapTopicInfo["Charger_YC"] = TopicInfo("Charger_YC", 106, 1); MQTTAsync_connectOptions option = MQTTAsync_connectOptions_initializer; MQTTAsync_message pubmsg = MQTTAsync_message_initializer; @@ -211,11 +170,11 @@ int MqttClient::publish(std::string topic, std::string text) int rc = MQTTAsync_sendMessage(client, topicName.c_str(), &msg, &options); if (rc == MQTTASYNC_SUCCESS) { - spdlog::info("[mqtt] publish MQTTAsync_sendMessage success, topic={}, text={}", topicName, text); + spdlog::info("[mqtt] publish success, topic={}, text={}", topicName, text); } else { - spdlog::error("[mqtt] publish MQTTAsync_sendMessage error, topic={}, text={}", topicName, text); + spdlog::error("[mqtt] publish error, topic={}, text={}", topicName, text); } return 0; } @@ -224,6 +183,7 @@ int MqttClient::polling() { if (!isConnected) { + spdlog::error("[mqtt] poll error, mqtt is not connected, clientId={}", clientId); return 0; } @@ -233,21 +193,31 @@ int MqttClient::polling() auto& appdata = Application::data(); auto station = appdata.getStationByCode(clientId); + if (!station) + { + spdlog::error("[mqtt] poll error, get station NULL, mqtt clientId={}", clientId); + return 0; + } for (auto& item: mapTopicInfo) { auto& topicInfo = item.second; if (topicInfo.polling) { - if (station) + std::vector> vecDevice; + station->getDeviceByType(topicInfo.deviceType, vecDevice); + for (auto device: vecDevice) { - std::vector> vecDevice; - station->getDeviceByType(topicInfo.deviceType, vecDevice); - for (auto device: vecDevice) + json["no"] = Utils::toInt(device->code); + if (topicInfo.name == "Gateway_YC") { - json["no"] = Utils::toInt(device->code); - this->publish(topicInfo.name, json.dump()); + json["addr"] = {"40001", "40002", "40021", "40038"}; } + else + { + json["addr"] = njson::array(); + } + this->publish(topicInfo.name, json.dump()); } } } @@ -278,6 +248,116 @@ std::string GetSubStr(std::string c, std::string& str) return v; } +// 交付完成回调(可选) +void MqttClient::onDeliveryComplete(MQTTAsync_token token) +{ + //spdlog::info("MQTT delivery complete, token={}", token); +} + +void MqttClient::onConnectSuccess( MQTTAsync_successData* resp) +{ + spdlog::info("[mqtt] connect to {} success, clientId={}.", addr, clientId); + this->isConnected = true; + this->subscribe(); +} + +void MqttClient::onConnectFaiure(MQTTAsync_failureData* resp) +{ + spdlog::error("[mqtt] connect to {} error, clientId={}.", addr, clientId); + this->isConnected = false; + this->destory(); +} + + +void MqttClient::ParseArrivedMessage(njson& json, string clientId, string command, std::shared_ptr station) +{ + std::string stationNo = clientId; + + auto mapRegPtr = REGAddr::getRegMap(command); + if (!mapRegPtr) + { + spdlog::error("[mqtt] get register add info error, clientId={}, stationId={}, command={}", clientId, stationNo, command); + return; + } + + auto iterTopic = mapTopicInfo.find(command); + if (iterTopic == mapTopicInfo.end()) + { + spdlog::error("[mqtt] get topic info error, clientId={}, stationId={}, command={}", clientId, stationNo, command); + return; + } + TopicInfo& topicInfo = iterTopic->second; + + int deviceNo = -1; + JSON::read(json, "no", deviceNo); + auto device = station->getDeviceByType(topicInfo.deviceType, Utils::toStr(deviceNo)); + if (!device) + { + return; + } + for (auto& item: json.items()) + { + std::string key = item.key(); + if (key != "ts" && key != "no") + { + auto data = json.at(key); + if (data.is_array()) + { + std::string addrText; + auto iter = mapRegPtr->find(key); + for (int i = 0; iend()) + { + + auto addr = iter->first; + int val = data[i]; + device->setParam(addr, val); + spdlog::info("[mqtt] read [{}]={},{}", addr, val, iter->second.remark); + + if (command == "EMS_YC" && addr == "0x110C") + { + int a = 30; + a = 100; + } + + if (command == "EMS_YC") + { + station->setRuntimeData(addr, val); + } + else if (command == "Fire40_YX") + { + station->setFire40Data(deviceNo, addr, val); + } + else if (command == "TH_YC") + { + station->setTHData(deviceNo, addr, val); + } + else if (command == "Cooling_YX" || command == "Cooling_YC") + { + station->setCoolingData(deviceNo, addr, val); + } + else if (command == "Gateway_YX") + { + //if (key == "CDZ") "CDZ": 1, //充电桩 1:在线,0:离线 + //else if (key == "EMU") //储能 1:在线,0:离线 + } + ++iter; + } + } + } + else if (data.is_number()) + { + device->setParam(key, data.get()); + } + else if (data.is_string()) + { + device->setParam(key, Utils::toInt(data.get())); + } + } + } +} + int MqttClient::onMessageArrived(char* topic, int topicLen, MQTTAsync_message* msg) { std::string topicStr = topic; @@ -308,62 +388,32 @@ int MqttClient::onMessageArrived(char* topic, int topicLen, MQTTAsync_message* m return 1; } - auto iter = g_mapRegInfo.find(command); - if (iter == g_mapRegInfo.end()) + if (command == "Gateway_YC") { - spdlog::error("[mqtt] get register add info error, clientId={}, stationId={}, command={}", clientId, stationNo, command); - return 1; - } - std::map& mapRegInfo = iter->second; - - - auto iterTopic = mapTopicInfo.find(command); - if (iterTopic == mapTopicInfo.end()) - { - spdlog::error("[mqtt] get topic info error, clientId={}, stationId={}, command={}", clientId, stationNo, command); - return 1; - } - TopicInfo& topicInfo = iterTopic->second; - - int deviceNo = -1; - JSON::read(json, "no", deviceNo); - auto device = station->getDeviceByType(topicInfo.deviceType, Utils::toStr(deviceNo)); - if (!device) - { - return 1; - } - - for (auto& item: json.items()) - { - std::string key = item.key(); - if (key != "ts" && key != "no") + for (auto& item: json.items()) { - auto data = json.at(key); - if (data.is_array()) - { - auto iter = mapRegInfo.find(key); - for (int i = 0; ifirst; - auto& val = data[i]; - //spdlog::info("[mqtt] read register addr: [{}]={}, {}", addr, val, iter->second.remark); - device->setParam(addr, val); - ++iter; - } - } - } - else if (data.is_number()) - { - device->setParam(key, data.get()); - } - else if (data.is_string()) - { - device->setParam(key, Utils::toInt(data.get())); - } + std::string key = item.key(); + auto& val = item.value(); + if (key == "40001") { spdlog::info("[mqtt] read register addr: [{}]={}, {}", key, val.dump(), "模式"); } + else if (key == "40002") { spdlog::info("[mqtt] read register addr: [{}]={}, {}", key, val.dump(), "峰谷时间段"); } + else if (key == "40021") { spdlog::info("[mqtt] read register addr: [{}]={}, {}", key, val.dump(), "自定时间段"); } + else if (key == "40038") { spdlog::info("[mqtt] read register addr: [{}]={}, {}", key, val.dump(), "其他参数"); } } } + else if (command == "Gateway_YX") + { + for (auto& item: json.items()) + { + std::string key = item.key(); + auto& val = item.value(); + if (key == "cdz") { spdlog::info("[mqtt] read register addr: [{}]={}, {}", key, val.dump(), "充电桩通讯状态"); } + else if (key == "emu") { spdlog::info("[mqtt] read register addr: [{}]={}, {}", key, val.dump(), "充电桩通讯状态"); } + } + } + else + { + ParseArrivedMessage(json, clientId, command, station); + } // 必须释放消息内存! MQTTAsync_freeMessage(&msg); @@ -371,67 +421,6 @@ int MqttClient::onMessageArrived(char* topic, int topicLen, MQTTAsync_message* m return 1; // 1表示消息已经处理 } -// 交付完成回调(可选) -void MqttClient::onDeliveryComplete(MQTTAsync_token token) -{ - //spdlog::info("MQTT delivery complete, token={}", token); -} - -void MqttClient::onConnectSuccess( MQTTAsync_successData* resp) -{ - spdlog::info("[mqtt] connect to {} success, clientId={}.", addr, clientId); - this->isConnected = true; - this->subscribe(); -} - -void MqttClient::onConnectFaiure(MQTTAsync_failureData* resp) -{ - spdlog::error("[mqtt] connect to {} error, clientId={}.", addr, clientId); - this->isConnected = false; - this->destory(); -} - -void MqttClient::parseEMS_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo) -{ - int deviceNo = -1; - JSON::read(json, "no", deviceNo); - auto device = station->getDeviceByType(101, Utils::toStr(deviceNo)); - if (!device) - { - return; - } - - for (auto& item: json.items()) - { - std::string key = item.key(); - if (key != "ts" && key != "no") - { - auto data = json.at(key); - if (data.is_array()) - { - auto iter = mapRegInfo.find(key); - for (int i = 0; ifirst; - device->mapParams[addr] = JSON::readStr(data[i], addr); - ++iter; - } - } - } - else if (data.is_number()) - { - device->mapParams[key] = Utils::toStr(data.get()); - } - else if (data.is_string()) - { - device->mapParams[key] = Utils::toStr(data.get()); - } - } - } -} - string MQTT::pack(std::string name) { diff --git a/src/protocol/MqttEntity.h b/src/protocol/MqttEntity.h index 2d3c106..908d0a2 100644 --- a/src/protocol/MqttEntity.h +++ b/src/protocol/MqttEntity.h @@ -8,22 +8,6 @@ class Station; -struct REGInfo -{ - std::string key; - std::string datatype; - int bytes {0}; - std::string remark; - int ratio {1}; - - REGInfo() {} - REGInfo(std::string key, std::string datatype, std::string remark) - : key(key), datatype(datatype), remark(remark) - { - if (datatype == "uint16" || datatype == "int16") { bytes = 1; } - else if (datatype == "uint32" || datatype == "int32") { bytes = 2; } - } -}; struct TopicInfo { @@ -41,8 +25,6 @@ using namespace std; class MqttClient { public: - static void loadDataStruct(std::string filename); - int init(string addr, string clientId, string username, string password); void destory(); @@ -51,13 +33,13 @@ public: int polling(); void onConnectionLost(char* cause); - int onMessageArrived(char* topic, int len, MQTTAsync_message* msg); void onDeliveryComplete(MQTTAsync_token token); void onConnectSuccess(MQTTAsync_successData* resp); void onConnectFaiure(MQTTAsync_failureData* resp); - void parseEMS_YX(std::shared_ptr station, njson& json, std::map& mapRegInfo); + int onMessageArrived(char* topic, int len, MQTTAsync_message* msg); + void ParseArrivedMessage(njson& json, string clientId, string command, std::shared_ptr station); public: // MQTT clientId (使用station 的 code) diff --git a/src/qt/MainWeb.cpp b/src/qt/MainWeb.cpp index 7a96ca8..0452e22 100644 --- a/src/qt/MainWeb.cpp +++ b/src/qt/MainWeb.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "common/Spdlogger.h" @@ -45,6 +46,9 @@ void MySplash(MainWeb* mainWin) MainWeb::MainWeb() { + QNetworkProxyFactory::setUseSystemConfiguration(false); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + this->setWindowTitle("光储充站监控与运营管理平台"); this->setGeometry(0, 0, 1920, 1080); this->hide(); @@ -85,8 +89,8 @@ void MainWeb::initWebview() labelWebErr.setStyleSheet("font: bold 20px;"); labelWebErr.hide(); - qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "9222"); // 即使内置视图,有时也需要开启调试端口 - //this->setCentralWidget(&webView); + + this->setCentralWidget(&webView); webView.setParent(this); webView.setGeometry(0, 0, 1920, 1080); @@ -102,8 +106,10 @@ void MainWeb::initWebview() //webView.setContextMenuPolicy(Qt::NoContextMenu); webView.load(QUrl(Config::option.webSrvUrl.c_str())); webView.hide(); + // 将主 Web 页面的开发者工具页面设置为 devToolsView 的页面 - webView.page()->setDevToolsPage(devTools.page()); + //qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "9222"); // 即使内置视图,有时也需要开启调试端口 + //webView.page()->setDevToolsPage(devTools.page()); QObject::connect(&webView, &QWebEngineView::loadFinished, [=](bool ok) { @@ -168,6 +174,15 @@ void MainWeb::showDevTools() } else { + qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "9222"); // 即使内置视图,有时也需要开启调试端口 + webView.page()->setDevToolsPage(devTools.page()); + + QWidget* w = new QWidget; + w->resize(800, 900); + devTools.setParent(w); + devTools.resize(800, 900); + w->show(); + // 如果你需要先导航主页面,然后在某个事件(如按钮点击)后显示开发者工具,可以将这行代码放在事件处理函数中。 layout = new QHBoxLayout(this); // 将两个视图添加到布局中 @@ -201,6 +216,7 @@ void MainWeb::keyPressEvent(QKeyEvent* e) } else if (key == Qt::Key_F5) { - webView.load(QUrl(Config::option.webSrvUrl.c_str())); + webView.update(); + //webView.load(QUrl(Config::option.webSrvUrl.c_str())); } } \ No newline at end of file diff --git a/src/qt/MainWeb.h b/src/qt/MainWeb.h index ce3aeb4..fff9a34 100644 --- a/src/qt/MainWeb.h +++ b/src/qt/MainWeb.h @@ -5,7 +5,7 @@ #include #include -class MainWeb : public QWidget +class MainWeb : public QMainWindow { Q_OBJECT public: