From 740b3d3ad265f8b4594d96d86cc0a36507226c7c Mon Sep 17 00:00:00 2001
From: ym1026 <1539963735@qq.com>
Date: Wed, 17 Sep 2025 15:08:13 +0800
Subject: [PATCH 1/5] =?UTF-8?q?=E5=BC=B9=E7=AA=97=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=E5=88=B7=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/components/Home/Modal.vue | 27 +++++++++++++++++++++------
web/src/views/sub/Home.vue | 1 -
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/web/src/components/Home/Modal.vue b/web/src/components/Home/Modal.vue
index b913c7e..ecfcb49 100644
--- a/web/src/components/Home/Modal.vue
+++ b/web/src/components/Home/Modal.vue
@@ -60,6 +60,8 @@ export default {
},
data() {
return {
+ refreshInterval:null,
+
modalInfo: {},
list: [
{
@@ -118,16 +120,29 @@ export default {
return this.list.filter((_, index) => index % 2 !== 0).slice(0, 3) // 右列取前3个奇数索引
}
},
+ beforeUnmount() {
+ if(this.refreshInterval){
+ clearInterval(this.refreshInterval)
+ this.refreshInterval=null
+ }
+ },
async mounted() {
- await Promise.all([
- this.getStatTotalList(),
- this.queryStationInfo(),
- this.queryStationData(),
- this.getStatDayList(1)
- ])
+ await this.loadAllData()
+ this.refreshInterval=setInterval(async()=>{
+ await this.loadAllData()
+ },30000) //30s刷新一次
+
},
methods: {
+ async loadAllData(){
+ await Promise.all([
+ this.getStatTotalList(),
+ this.queryStationInfo(),
+ this.queryStationData(),
+ this.getStatDayList(1)
+ ])
+ },
// 查询系统累计统计信息
async getStatTotalList() {
try {
diff --git a/web/src/views/sub/Home.vue b/web/src/views/sub/Home.vue
index 145918b..be6a01d 100644
--- a/web/src/views/sub/Home.vue
+++ b/web/src/views/sub/Home.vue
@@ -111,7 +111,6 @@ export default {
}
},
beforeUnmount() {
- console.log('2222')
if(this.refreshInterval){
clearInterval(this.refreshInterval)
this.refreshInterval=null
From 680be6155f9de79a058249e2b27b38b88a4b9a9c Mon Sep 17 00:00:00 2001
From: ym1026 <1539963735@qq.com>
Date: Wed, 17 Sep 2025 15:18:32 +0800
Subject: [PATCH 2/5] =?UTF-8?q?=E5=9C=B0=E5=9B=BEzoom=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/components/Home/Map.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/src/components/Home/Map.vue b/web/src/components/Home/Map.vue
index 9acf054..86a8523 100644
--- a/web/src/components/Home/Map.vue
+++ b/web/src/components/Home/Map.vue
@@ -58,7 +58,7 @@ export default {
data() {
return {
center: [112.870000,34.180000], // 默认中心点(河南)
- zoom: 12,
+ zoom: 6,
map: null,
currentMarker: {},
showCtrModal: false,
From 27ca787fc59876101588f970524f9c4121230dd1 Mon Sep 17 00:00:00 2001
From: ym1026 <1539963735@qq.com>
Date: Wed, 17 Sep 2025 15:31:35 +0800
Subject: [PATCH 3/5] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AE=A1=E7=90=86?=
=?UTF-8?q?=E5=B8=83=E5=B1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/components/Home/Alarm.vue | 8 +++++++-
web/src/components/Home/Charge.vue | 1 -
web/src/views/system/service.vue | 7 +++----
web/vue.config.js | 2 +-
4 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/web/src/components/Home/Alarm.vue b/web/src/components/Home/Alarm.vue
index 1ac9f99..6b8da47 100644
--- a/web/src/components/Home/Alarm.vue
+++ b/web/src/components/Home/Alarm.vue
@@ -93,8 +93,11 @@ export default {
},
mounted() {},
beforeUnmount() {
- this.faultChart = null
window.removeEventListener('resize', this.handleResize)
+ if (this.faultChart) {
+ this.faultChart.dispose()
+ this.faultChart = null
+ }
},
methods: {
@@ -130,6 +133,9 @@ export default {
drawLineChart(activeKey) {
this.getChargeData(activeKey)
+ if(this.faultChart){
+ this.faultChart.dispose()
+ }
const chartDom = document.getElementById('alarm-chart')
let faultChart = this.$echarts.init(chartDom)
this.faultChart = faultChart
diff --git a/web/src/components/Home/Charge.vue b/web/src/components/Home/Charge.vue
index 6d56dc0..a839e57 100644
--- a/web/src/components/Home/Charge.vue
+++ b/web/src/components/Home/Charge.vue
@@ -154,7 +154,6 @@ export default {
},
drawLineChart(activeKey) {
- console.log(this.$refs.charge)
// const labelCount = Math.floor(500 / 30);
this.getChargeData(activeKey)
if(this.chargeChart){
diff --git a/web/src/views/system/service.vue b/web/src/views/system/service.vue
index 18e5072..54d576f 100644
--- a/web/src/views/system/service.vue
+++ b/web/src/views/system/service.vue
@@ -58,7 +58,7 @@ export default {
props: {},
data() {
return {
- tableData:[],
+ tableData: [],
tableOption: {
select: false
@@ -243,10 +243,9 @@ export default {
diff --git a/web/vue.config.js b/web/vue.config.js
index 00aa3e2..56dc2c6 100644
--- a/web/vue.config.js
+++ b/web/vue.config.js
@@ -14,7 +14,7 @@ module.exports = defineConfig({
proxy: {
'/api': {
// 代理前缀,可以自定义(如 '/api')
- target: 'http://192.168.0.187:19801', // 目标服务器地址
+ target: 'http://192.168.0.187:19800', // 目标服务器地址
changeOrigin: true, // 是否改变请求源(跨域必备)
pathRewrite: {
'^/api': '' // 重写路径,去掉 '/api' 前缀
From 94d6d8a8dbd1411d792171e5a3a79d5bc0b83a47 Mon Sep 17 00:00:00 2001
From: ym1026 <1539963735@qq.com>
Date: Wed, 17 Sep 2025 15:34:01 +0800
Subject: [PATCH 4/5] =?UTF-8?q?=E8=BF=90=E8=A1=8C=E4=BF=A1=E6=81=AF?=
=?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=95=B0=E6=8D=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/components/Home/Modal/OperationalInfo.vue | 2 +-
web/src/components/Home/Operational.vue | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/web/src/components/Home/Modal/OperationalInfo.vue b/web/src/components/Home/Modal/OperationalInfo.vue
index f931c4c..b9f6fc8 100644
--- a/web/src/components/Home/Modal/OperationalInfo.vue
+++ b/web/src/components/Home/Modal/OperationalInfo.vue
@@ -88,7 +88,7 @@ export default {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
- item.value = this.propsTotal[item.key]
+ item.value = this.propsTotal[item.key]||0
})
}
},
diff --git a/web/src/components/Home/Operational.vue b/web/src/components/Home/Operational.vue
index 06a651a..4617190 100644
--- a/web/src/components/Home/Operational.vue
+++ b/web/src/components/Home/Operational.vue
@@ -74,7 +74,7 @@ export default {
const dates = data.map((item) => item.station_name)
const values = []
keys.forEach((item, index) => {
- values[index] = data.map((dataValue) => dataValue[keys[index]])
+ values[index] = data.map((dataValue) => dataValue[keys[index]])||0
})
return {
From c55da0bddcbfb00afb7d6270ef48b9b3b51f6917 Mon Sep 17 00:00:00 2001
From: lixiaoyuan
Date: Wed, 17 Sep 2025 19:55:59 +0800
Subject: [PATCH 5/5] =?UTF-8?q?=E8=B0=83=E8=AF=95=E4=BF=AE=E6=94=B9MQTT?=
=?UTF-8?q?=E9=80=9A=E8=AE=AF=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
bin/Release/assets/config/app.json | 32 +-
bin/Release/assets/config/regaddrs.json | 20 ++
bin/Release/assets/config/regaddrsShow.json | 17 +-
src/app/Application.cpp | 52 ++-
src/app/Config.cpp | 82 ++++-
src/app/Config.h | 43 ++-
src/app/Device.cpp | 66 ++--
src/app/Device.h | 2 +
src/app/Station.cpp | 261 +++++++++------
src/app/Station.h | 46 +--
src/common/Spdlogger.cpp | 8 +-
src/database/Dao.cpp | 1 +
src/database/DaoEntity.cpp | 11 +-
src/main.cpp | 5 +-
src/protocol/HttpEntity.cpp | 140 +++++---
src/protocol/HttpEntity.h | 1 +
src/protocol/MqttEntity.cpp | 349 ++++++++------------
src/protocol/MqttEntity.h | 19 +-
18 files changed, 661 insertions(+), 494 deletions(-)
diff --git a/bin/Release/assets/config/app.json b/bin/Release/assets/config/app.json
index 97f616b..a27c91c 100644
--- a/bin/Release/assets/config/app.json
+++ b/bin/Release/assets/config/app.json
@@ -1,8 +1,34 @@
{
+ "debug":0,
"launchdate": "2025-09-01",
+ "weburl": "http://127.0.0.1:19601/",
"database": {"host": "localhost", "port": 3306, "user": "root", "passwd": "123456", "dbname": "ess"},
- "token":"",
- "http": {"port": 19801},
+
+ "http": {"token":0, "port": 19801, "encryption":0, "encryptKey":""},
"mqtt": {"host":"mqtt://43.136.119.46:6203","username":"jsyhsec","password":"123456"},
- "weburl": "http://127.0.0.1:19601/"
+ "topic": {
+ "EMS_YX": {"deviceType":101, "polling":0, "enabled": 1},
+ "EMS_YC": {"deviceType":101, "polling":0, "enabled": 1},
+ "EMS_YT": {"deviceType":101, "polling":0, "enabled": 1},
+ "PCS_YX": {"deviceType":102, "polling":1, "enabled": 1},
+ "PCS_YC": {"deviceType":102, "polling":1, "enabled": 1},
+ "PCU_YX": {"deviceType":103, "polling":0, "enabled": 1},
+ "PCU_YC": {"deviceType":103, "polling":0, "enabled": 1},
+ "BMS_YX": {"deviceType":104, "polling":0, "enabled": 1},
+ "BMS_YC": {"deviceType":104, "polling":0, "enabled": 1},
+ "BCU_YC": {"deviceType":105, "polling":1, "enabled": 1},
+ "BCU_YX": {"deviceType":105, "polling":1, "enabled": 1},
+ "MEM_YC": {"deviceType":3, "polling":0, "enabled": 1},
+ "TH_YC": {"deviceType":10, "polling":1, "enabled": 1},
+ "Fire40_YX": {"deviceType":7, "polling":1, "enabled": 1},
+ "Cooling_YC": {"deviceType":14, "polling":1, "enabled": 1},
+ "Cooling_YX": {"deviceType":14, "polling":1, "enabled": 1},
+ "Gateway_YX": {"deviceType":15, "polling":1, "enabled": 1},
+ "Gateway_YC": {"deviceType":15, "polling":1, "enabled": 1},
+ "Charger_YC": {"deviceType":106, "polling":0, "enabled": 1}
+ },
+ "view": {"latitude":0,"longitude":0,"altitude":0},
+ "video": {
+ "1":{"host":"", "port":9000, "user":"", "passwd":""}
+ }
}
\ No newline at end of file
diff --git a/bin/Release/assets/config/regaddrs.json b/bin/Release/assets/config/regaddrs.json
index d56984d..2f7ce5a 100644
--- a/bin/Release/assets/config/regaddrs.json
+++ b/bin/Release/assets/config/regaddrs.json
@@ -866,5 +866,25 @@
{"key": "40021", "datatype": "uint16", "remark": "自定时间段"},
{"key": "40038", "datatype": "uint16", "remark": "其他参数"}
]
+ },
+ "Charger_YC":{
+ "addr":[
+ {"key": "11", "datatype": "uint16", "remark": "枪1:状态"},
+ {"key": "12", "datatype": "uint16", "remark": "枪1:需求电压"},
+ {"key": "13", "datatype": "uint16", "remark": "枪1:需求电流"},
+ {"key": "14", "datatype": "uint16", "remark": "枪1:需求功率"},
+ {"key": "15", "datatype": "uint16", "remark": "枪1:输出电压"},
+ {"key": "16", "datatype": "uint16", "remark": "枪1:输出电流"},
+ {"key": "17", "datatype": "uint16", "remark": "枪1:输出功率"},
+ {"key": "18", "datatype": "uint16", "remark": "枪1:功率限值"},
+ {"key": "21", "datatype": "uint16", "remark": "枪2:状态"},
+ {"key": "22", "datatype": "uint16", "remark": "枪2:需求电压"},
+ {"key": "23", "datatype": "uint16", "remark": "枪2:需求电流"},
+ {"key": "24", "datatype": "uint16", "remark": "枪2:需求功率"},
+ {"key": "25", "datatype": "uint16", "remark": "枪2:输出电压"},
+ {"key": "26", "datatype": "uint16", "remark": "枪2:输出电流"},
+ {"key": "27", "datatype": "uint16", "remark": "枪2:输出功率"},
+ {"key": "28", "datatype": "uint16", "remark": "枪2:功率限值"}
+ ]
}
}
\ No newline at end of file
diff --git a/bin/Release/assets/config/regaddrsShow.json b/bin/Release/assets/config/regaddrsShow.json
index 5cf7f6b..94941fe 100644
--- a/bin/Release/assets/config/regaddrsShow.json
+++ b/bin/Release/assets/config/regaddrsShow.json
@@ -96,14 +96,15 @@
"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"]
+ ["工作状态", "11", "空闲", ""],
+ ["需求电压", "12", "0.0", " V", "0.1"],
+ ["需求电流", "13", "0.0", " A", "0.01"],
+ ["需求功率", "14", "0.0", " kW", "0.1"],
+ ["输出电压", "15", "0.0", " V", "0.1"],
+ ["输出电流", "16", "0.0", " A", "0.01"],
+ ["输出功率", "17", "0.0", " kW", "0.1"],
+ ["功率限值", "18", "0.0", " kW", "0.1"],
],
- "addrCurve": ["31079", "31081", "31083"]
+ "addrCurve": ["15", "16", "17"]
}
}
\ No newline at end of file
diff --git a/src/app/Application.cpp b/src/app/Application.cpp
index 3d44d33..cb88ed7 100644
--- a/src/app/Application.cpp
+++ b/src/app/Application.cpp
@@ -16,6 +16,11 @@ void Application::init()
{
// 初始化系统配置,读取配置文件
Config::init("assets/config/app.json");
+ if (Config::option.debug)
+ {
+ spdlog::set_level(spdlog::level::debug); // 设置全局日志等级为 debug
+ spdlog::debug("[app] spdlog debug enable.");
+ }
// MQTT 数据结构
REGAddr::load("assets/config/regaddrs.json");
@@ -77,8 +82,8 @@ void Application::runThreadMain()
if (!this->isInit) { continue; }
}
- static TimeTick ttMqtt(1); // 检查 场站的 MQTT 连接
- if (ttMqtt.elapse(20))
+ static TimeTick ttMqtt; // 检查 场站的 MQTT 连接
+ if (ttMqtt.elapse(30))
{
auto& optionMqtt = Config::option.mqtt;
if (!optionMqtt.host.empty())
@@ -86,22 +91,21 @@ void Application::runThreadMain()
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
- if (station && station->isOpen)
+ if (station)
{
- // 该函数检查连接状态,若已经连接,则无操作;若未连接,则进行连接操作
- item.second->initMqtt();
- // 召测
- item.second->polling();
+ if (station->isOpen)
+ {
+ // 该函数检查连接状态,若已经连接,则无操作;若未连接,则进行连接操作
+ item.second->initMqtt();
+ // 召测
+ item.second->polling();
+ }
+ // 检查设备的在线状态
+ station->checkDevice();
}
}
}
}
-
- static TimeTick ttData(1); // 检查数据
- if (ttData.elapse(20))
- {
- //appdata.initFromDB();
- }
}
}
@@ -110,20 +114,14 @@ void Application::runThreadStat()
int nCachePos = 0;
while (!isQuit)
{
- int64_t tTime = Utils::time();
- int64_t tDate = Utils::date();
- int64_t delta = tTime-tDate;
- int n = delta / 600;
- int offset = delta % 600;
- bool flagStore = (delta >=0 && delta < 86400 && offset <= 10 && n != nCachePos);
- if (flagStore)
+ static TimeTick ttStat(1);
+ if(ttStat.elapse(10))
{
- nCachePos = n;
- std::string dt = Utils::dateStr(tDate);
- // // 设备历史数据(电压、电流、功率),存储到 history_day
+ // 设备历史数据(电压、电流、功率),存储到 history_day
+ // 统计数据,存储到 stat_station
for (auto item: appdata.mapStation)
{
- item.second->writeRuntimeData(dt, nCachePos);
+ item.second->writeStatistic();
}
}
else
@@ -131,12 +129,6 @@ void Application::runThreadStat()
//spdlog::info("保存历史数据倒计时: {}", 600 - offset);
}
- // 统计计算,存储到 stat_station
- for (auto& station : appdata.mapStation)
- {
-
- }
-
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
\ No newline at end of file
diff --git a/src/app/Config.cpp b/src/app/Config.cpp
index e4129f6..b18e153 100644
--- a/src/app/Config.cpp
+++ b/src/app/Config.cpp
@@ -5,6 +5,7 @@
#include "common/JsonN.h"
#include "common/Spdlogger.h"
#include "AppData.h"
+#include "protocol/MqttEntity.h"
AppOption Config::option;
@@ -19,49 +20,106 @@ bool Config::init(std::string filename)
}
spdlog::info("[config] load config file success, filename={}", filename);
+ JSON::read(jsonroot, "debug", option.debug);
+ JSON::read(jsonroot, "weburl", option.webSrvUrl);
+ JSON::read(jsonroot, "launchdate", option.lunchDate);
+
+
if (jsonroot.contains("database"))
{
- njson json = jsonroot.at("database");
+ njson& json = jsonroot.at("database");
JSON::read(json, "host", option.database.host);
JSON::read(json, "port", option.database.port);
JSON::read(json, "user", option.database.user);
JSON::read(json, "passwd", option.database.passwd);
JSON::read(json, "dbname", option.database.dbname);
-
spdlog::info("[config] parse database success. host={}", option.database.host);
}
else
{
- spdlog::info("[config] parse database failed: not found.");
+ spdlog::error("[config] parse database failed: not found.");
}
if (jsonroot.contains("http"))
{
- njson json = jsonroot.at("http");
- std:string token;
- JSON::read(json, "token", token);
- option.http.useToken = !token.empty();
+ njson& json = jsonroot.at("http");
+ JSON::read(json, "token", option.http.useToken);
JSON::read(json, "port", option.http.port);
+ JSON::read(json, "encryption", option.http.encryption);
+ JSON::read(json, "encryptKey", option.http.encryptKey);
}
else
{
- spdlog::info("[config] parse http failed: not found.");
+ spdlog::error("[config] parse http failed: not found.");
}
if (jsonroot.contains("mqtt"))
{
- njson json = jsonroot.at("mqtt");
+ njson& json = jsonroot.at("mqtt");
JSON::read(json, "host", option.mqtt.host);
JSON::read(json, "username", option.mqtt.username);
JSON::read(json, "password", option.mqtt.password);
}
else
{
- spdlog::info("[config] parse mqtt failed: not found.");
+ spdlog::error("[config] parse mqtt failed: not found.");
}
- JSON::read(jsonroot, "weburl", option.webSrvUrl);
- JSON::read(jsonroot, "launchdate", option.lunchDate);
+ if (jsonroot.contains("view"))
+ {
+ njson& json = jsonroot["view"];
+ JSON::read(json, "latitude", option.view.latitude);
+ JSON::read(json, "longitude", option.view.longitude);
+ JSON::read(json, "altitude", option.view.altitude);
+ }
+ else
+ {
+ spdlog::error("[config] parse view failed: not found.");
+ }
+ if (jsonroot.contains("video"))
+ {
+ njson& json = jsonroot["video"];
+ for (auto& item: json.items())
+ {
+ auto& key = item.key();
+ auto& jsonItem = item.value();
+ auto& itemVideo = option.mapVideo[key];
+ JSON::read(jsonItem, "host", itemVideo.host);
+ JSON::read(jsonItem, "port", itemVideo.port);
+ JSON::read(jsonItem, "user", itemVideo.user);
+ JSON::read(jsonItem, "passwd", itemVideo.passwd);
+ }
+ }
+ else
+ {
+ spdlog::error("[config] parse video failed: not found.");
+ }
+
+ if (jsonroot.contains("topic"))
+ {
+ njson& json = jsonroot["topic"];
+ for (auto& item: json.items())
+ {
+ auto& key = item.key();
+ auto& jsonItem = item.value();
+ auto& info = MqttClient::s_mapTopicInfo[key];
+ info.name = key;
+ JSON::read(jsonItem, "deviceType", info.deviceType);
+ JSON::read(jsonItem, "polling", info.polling);
+ JSON::read(jsonItem, "enabled", info.enabled);
+ }
+ }
return true;
+}
+
+
+AppOption::VideoInfo* Config::getVideoInfo(std::string name)
+{
+ auto iter = option.mapVideo.find(name);
+ if (iter!=option.mapVideo.end())
+ {
+ return &(iter->second);
+ }
+ return nullptr;
}
\ No newline at end of file
diff --git a/src/app/Config.h b/src/app/Config.h
index f800504..ad6bd91 100644
--- a/src/app/Config.h
+++ b/src/app/Config.h
@@ -1,23 +1,27 @@
#pragma once
+#include