修改HTTP接口测试问题

This commit is contained in:
lixiaoyuan
2025-09-12 18:44:34 +08:00
parent 59b78d678d
commit 7f23138d9c
40 changed files with 1484 additions and 1165 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
{
"103":{
"addr":[
{"key": "0x1009", "datatype": "uint16", "remark": "EPO急停1故障0正常"},
{"key": "0x100A", "datatype": "uint16", "remark": "防雷器异常1告警0正常"},
{"key": "0x100B", "datatype": "uint16", "remark": "负载电压反序1故障0正常"},
{"key": "0x100C", "datatype": "uint16", "remark": "市电电压反序1故障0正常"},
{"key": "0x100D", "datatype": "uint16", "remark": "输出相反序1故障0正常"},
{"key": "0x100E", "datatype": "uint16", "remark": "过载告警1告警0正常"},
{"key": "0x100F", "datatype": "uint16", "remark": "过载超时1故障0正常"},
{"key": "0x1010", "datatype": "uint16", "remark": "交流过流保护1故障0正常"},
{"key": "0x1011", "datatype": "uint16", "remark": "逆变电压异常1故障0正常"},
{"key": "0x1012", "datatype": "uint16", "remark": "内部串口异常1故障0正常"},
{"key": "0x1013", "datatype": "uint16", "remark": "485通信故障1故障0正常"},
{"key": "0x1014", "datatype": "uint16", "remark": "CAN通信故障1故障0正常"},
{"key": "0x1015", "datatype": "uint16", "remark": "E2PROM故障1故障0正常"},
{"key": "0x1016", "datatype": "uint16", "remark": "电网过压1故障0正常"},
{"key": "0x1017", "datatype": "uint16", "remark": "电网欠压1故障0正常"},
{"key": "0x1018", "datatype": "uint16", "remark": "电网过频1故障0正常"},
{"key": "0x1019", "datatype": "uint16", "remark": "电网欠频1故障0正常"},
{"key": "0x101A", "datatype": "uint16", "remark": "电网快检综合异常1故障0正常"},
{"key": "0x101B", "datatype": "uint16", "remark": "电网幅值快检异常1故障0正常"},
{"key": "0x101C", "datatype": "uint16", "remark": "电网拖尾异常1故障0正常"},
{"key": "0x101E", "datatype": "uint16", "remark": "急停按钮信号NC1急停0正常"},
{"key": "0x101F", "datatype": "uint16", "remark": "避雷器NC1故障0正常"},
{"key": "0x1020", "datatype": "uint16", "remark": "避雷器断路器NC1故障0正常"},
{"key": "0x102F", "datatype": "uint16", "remark": "PCS_01下发设置1故障0正常"},
{"key": "0x1030", "datatype": "uint16", "remark": "PCS_02下发设置1故障0正常"},
{"key": "0x1031", "datatype": "uint16", "remark": "PCS_03下发设置1故障0正常"},
{"key": "0x1032", "datatype": "uint16", "remark": "PCS_04下发设置1故障0正常"},
{"key": "0x1033", "datatype": "uint16", "remark": "PCS_05下发设置1故障0正常"},
{"key": "0x1034", "datatype": "uint16", "remark": "PCS_06下发设置1故障0正常"},
{"key": "0x1035", "datatype": "uint16", "remark": "PCS_07下发设置1故障0正常"},
{"key": "0x1036", "datatype": "uint16", "remark": "PCS_08下发设置1故障0正常"},
{"key": "0x1037", "datatype": "uint16", "remark": "PCS_09下发设置1故障0正常"},
{"key": "0x1038", "datatype": "uint16", "remark": "PCS_10下发设置1:故障0正常"},
{"key": "0x1039", "datatype": "uint16", "remark": "内部DSP通信故障1:故障0正常"},
{"key": "0x103A", "datatype": "uint16", "remark": "BMS CAN通信故障1:故障0正常"}
]
},
"104":{
"addr":[
{"key": "0x1010", "datatype": "uint16", "remark": "绝缘故障1:故障0正常"},
{"key": "0x1011", "datatype": "uint16", "remark": "漏电保护1:故障0正常"},
{"key": "0x1012", "datatype": "uint16", "remark": "直流过压1:故障0正常"},
{"key": "0x1013", "datatype": "uint16", "remark": "市电幅值异常1:故障0正常"},
{"key": "0x1014", "datatype": "uint16", "remark": "市电相序异常1:故障0正常"},
{"key": "0x1015", "datatype": "uint16", "remark": "温度开关异常1:故障0正常"},
{"key": "0x1016", "datatype": "uint16", "remark": "市电频率异常1:故障0正常"},
{"key": "0x1017", "datatype": "uint16", "remark": "IGBT过温1:故障0正常"},
{"key": "0x1018", "datatype": "uint16", "remark": "交流接地故障1:故障0正常"},
{"key": "0x1019", "datatype": "uint16", "remark": "逆变过流异常1:故障0正常"},
{"key": "0x101A", "datatype": "uint16", "remark": "直流缓起故障1:故障0正常"},
{"key": "0x101B", "datatype": "uint16", "remark": "直流主继电器故障1:故障0正常"},
{"key": "0x101C", "datatype": "uint16", "remark": "风机异常1:故障0正常"},
{"key": "0x101D", "datatype": "uint16", "remark": "主接触器异常1:故障0正常"},
{"key": "0x101E", "datatype": "uint16", "remark": "均浮充切换超时1:故障0正常"},
{"key": "0x101F", "datatype": "uint16", "remark": "硬件故障1:故障0正常"},
{"key": "0x1020", "datatype": "uint16", "remark": "机内过温1:故障0正常"},
{"key": "0x1021", "datatype": "uint16", "remark": "软启动故障1:故障0正常"},
{"key": "0x1022", "datatype": "uint16", "remark": "触摸屏通讯故障1:故障0正常"},
{"key": "0x1023", "datatype": "uint16", "remark": "防雷器故障1:故障0正常"},
{"key": "0x1024", "datatype": "uint16", "remark": "急停故障1:故障0正常"},
{"key": "0x1025", "datatype": "uint16", "remark": "BMS系统故障1:故障0正常"},
{"key": "0x1026", "datatype": "uint16", "remark": "BMS通讯故障1:故障0正常"},
{"key": "0x1027", "datatype": "uint16", "remark": "BMS干接点通讯故障1:故障0正常"},
{"key": "0x1028", "datatype": "uint16", "remark": "远程通讯故障1:故障0正常"},
{"key": "0x1029", "datatype": "uint16", "remark": "门禁告警1:故障0正常"},
{"key": "0x102A", "datatype": "uint16", "remark": "锁相异常1:故障0正常"},
{"key": "0x102B", "datatype": "uint16", "remark": "IGBT过温告警1:故障0正常"},
{"key": "0x102C", "datatype": "uint16", "remark": "硬件过流保护1:故障0正常"},
{"key": "0x102D", "datatype": "uint16", "remark": "驱动故障1:故障0正常"},
{"key": "0x102E", "datatype": "uint16", "remark": "ID冲突1:故障0正常"},
{"key": "0x102F", "datatype": "uint16", "remark": "电池过压1:故障0正常"},
{"key": "0x1030", "datatype": "uint16", "remark": "电池欠压1:故障0正常"},
{"key": "0x1031", "datatype": "uint16", "remark": "直流过流保护1:故障0正常"},
{"key": "0x1032", "datatype": "uint16", "remark": "输出电压异常1:故障0正常"},
{"key": "0x1033", "datatype": "uint16", "remark": "离网输出电压不符合1:故障0正常"},
{"key": "0x1034", "datatype": "uint16", "remark": "输出过载保护1:故障0正常"},
{"key": "0x1035", "datatype": "uint16", "remark": "输出短路保护1:故障0正常"},
{"key": "0x1036", "datatype": "uint16", "remark": "并机通信异常1:故障0正常"},
{"key": "0x1037", "datatype": "uint16", "remark": "电池保险异常1:故障0正常"},
{"key": "0x1038", "datatype": "uint16", "remark": "电池重载低压1:故障0正常"},
{"key": "0x1039", "datatype": "uint16", "remark": "电池低压告警1:故障0正常"},
{"key": "0x103A", "datatype": "uint16", "remark": "一拖二压差过大1:故障0正常"},
{"key": "0x103B", "datatype": "uint16", "remark": "电池反接故障1:故障0正常"},
{"key": "0x103C", "datatype": "uint16", "remark": "电池电压异常1:故障0正常"},
{"key": "0x103D", "datatype": "uint16", "remark": "过载告警1:故障0正常"},
{"key": "0x103E", "datatype": "uint16", "remark": "外部接触器异常1:故障0正常"},
{"key": "0x103F", "datatype": "uint16", "remark": "IGBT温度传感器异常1:故障0正常"},
{"key": "0x1040", "datatype": "uint16", "remark": "整机温度传感器异常1:故障0正常"},
{"key": "0x1041", "datatype": "uint16", "remark": "市电CT异常1:故障0正常"},
{"key": "0x1042", "datatype": "uint16", "remark": "逆变电流三相不平衡1:故障0正常"},
{"key": "0x1043", "datatype": "uint16", "remark": "逆变电流直流分量异常1:故障0正常"},
{"key": "0x1044", "datatype": "uint16", "remark": "母线不平衡1:故障0正常"},
{"key": "0x1045", "datatype": "uint16", "remark": "逆变电压直流分量异常1:故障0正常"},
{"key": "0x1046", "datatype": "uint16", "remark": "主接触器控制异常1:故障0正常"},
{"key": "0x1047", "datatype": "uint16", "remark": "逆变电压控制异常1:故障0正常"},
{"key": "0x1048", "datatype": "uint16", "remark": "直流霍尔异常1:故障0正常"},
{"key": "0x1049", "datatype": "uint16", "remark": "电池单体过压1:故障0正常"},
{"key": "0x104A", "datatype": "uint16", "remark": "电池单体欠压1:故障0正常"},
{"key": "0x104B", "datatype": "uint16", "remark": "电网过压1:故障0正常"},
{"key": "0x104C", "datatype": "uint16", "remark": "电网欠压1:故障0正常"},
{"key": "0x104D", "datatype": "uint16", "remark": "电网过频1:故障0正常"},
{"key": "0x104E", "datatype": "uint16", "remark": "电网欠频1:故障0正常"},
{"key": "0x104F", "datatype": "uint16", "remark": "市电不平衡1:故障0正常"},
{"key": "0x1050", "datatype": "uint16", "remark": "参数设置不匹配1:故障0正常"},
{"key": "0x1051", "datatype": "uint16", "remark": "SPI通信异常1:故障0正常"},
{"key": "0x1052", "datatype": "uint16", "remark": "SCI通信异常1:故障0正常"},
{"key": "0x1053", "datatype": "uint16", "remark": "IIC通信异常1:故障0正常"},
{"key": "0x1054", "datatype": "uint16", "remark": "Xintf通信异常1:故障0正常"},
{"key": "0x1055", "datatype": "uint16", "remark": "零偏校准异常1:故障0正常"},
{"key": "0x1056", "datatype": "uint16", "remark": "烟雾告警1:故障0正常"},
{"key": "0x1057", "datatype": "uint16", "remark": "无电池组故障1异常0正常"},
{"key": "0x1058", "datatype": "uint16", "remark": "环温降频1异常0正常"},
{"key": "0x1059", "datatype": "uint16", "remark": "交流过载1异常0正常"},
{"key": "0x105A", "datatype": "uint16", "remark": "采样异常1异常0正常"},
{"key": "0x105B", "datatype": "uint16", "remark": "24V辅源故障1异常0正常"},
{"key": "0x105C", "datatype": "uint16", "remark": "直流欠压异常1异常0正常"},
{"key": "0x105D", "datatype": "uint16", "remark": "散热器过温1异常0正常"},
{"key": "0x105E", "datatype": "uint16", "remark": "CAN配置故障1异常0正常"},
{"key": "0x105F", "datatype": "uint16", "remark": "3.3V辅源故障1异常0正常"},
{"key": "0x1060", "datatype": "uint16", "remark": "环境过温1异常0正常"},
{"key": "0x1061", "datatype": "uint16", "remark": "A相IGBT逆变过流1异常0正常"},
{"key": "0x1062", "datatype": "uint16", "remark": "B相IGBT逆变过流1异常0正常"}
]
}
}

View File

@@ -0,0 +1,77 @@
import re
import json
def parse_datatype(text):
datatypes = ["int16", "uint16", "int32", "uint32", "int64", "uint64"]
for index, datatype in enumerate(datatypes):
left, separator, right = text.partition(datatype)
if len(separator) != 0:
return datatype, left + right
return "", text
def parse_from_file(filename):
data = ""
with open(filename, "r", encoding='utf-8') as f: # 打开文件
linedata = ""
for line in f: # 行遍历
line = line.strip()
#linedata = f.readline() # 读取文件的一行
flag = bool(re.search(r'0x[0-9A-Fa-f]{4}', line))
linedata += line.strip()
if flag:
# print(linedata)
# left, separator, right = linedata.partition("0x")
parts = re.split(r'(0x[0-9A-Fa-f]{4})', linedata)
linedata = ""
key = parts[1]
datatype, remark = parse_datatype(parts[0].strip())
remark = remark.replace("\t", " ").replace("\"", "")
item = {}
item["key"] = key
item["datatype"] = datatype
item["remark"] = remark
if len(data) > 0:
data += ",\n"
data += ("\t\t\t" + json.dumps(item, ensure_ascii=False))
return data
addritems = {}
addritems["EMS_YT"] = ["EMS遥调.txt", 1]
addritems["BCU_YX"] = ["BCU电池簇遥信.txt", 1]
addritems["BCU_YC"] = ["BCU电池簇遥测.txt", 1]
addritems["BMS_YC"] = ["BMS电池堆遥测.txt", 1]
addritems["EMS_YX"] = ["EMS遥信.txt", 1]
addritems["EMS_YC"] = ["EMS遥测.txt", 1]
addritems["EMS_YT"] = ["EMS遥调.txt", 1]
addritems["PCS_YX"] = ["PCS遥信.txt", 1]
addritems["PCS_YC"] = ["PCS遥测.txt", 1]
addritems["PCU_YX"] = ["PCU遥信.txt", 1]
addritems["PCU_YC"] = ["PCU遥测.txt", 1]
addritems["MEM_YC"] = ["多功能电表遥测.txt", 1]
addritems["TH_YC"] = ["温湿度状态遥测.txt", 1]
addritems["Fire40_YX"] = ["消防4.0遥信.txt", 1]
addritems["Cooling_YX"] = ["冷机遥信.txt", 1]
addritems["Cooling_YC"] = ["冷机遥测.txt", 1]
with open('registeraddr.json', 'w', encoding='utf-8') as f:
f.write("{")
index = 0
for key in addritems:
filename = addritems[key][0]
count = addritems[key][1]
print("parse: ", key, filename)
data = parse_from_file(filename)
if len(data) > 0:
data = "\n" + data + "\n\t"
if index != 0:
f.write(",")
f.write("\n\t\"" + key + "\": {\n\t\t\"count\":" + str(count) + ",\n\t\t\"addr\":[" + data + "\t]\n\t}")
index+=1
f.write("\n}")

View File

@@ -1,77 +1,88 @@
import re
import json
from openpyxl import load_workbook
def parse_datatype(text):
datatypes = ["int16", "uint16", "int32", "uint32", "int64", "uint64"]
for index, datatype in enumerate(datatypes):
left, separator, right = text.partition(datatype)
if len(separator) != 0:
return datatype, left + right
return "", text
def read_cell(sheet, row, col):
val = str(sheet.cell(row, col).value)
if val == "None":
val = ""
return val.strip()
def read_sheet(wb, topic, sht_name):
sheet = wb[sht_name]
text = ""
for i in range(1, sheet.max_row):
# print(str(sheet.cell(i, 1).value))
addr = read_cell(sheet, i, 8)
name = read_cell(sheet,i, 2)
datatype = read_cell(sheet,i, 4)
unit = read_cell(sheet, i, 5)
remark = read_cell(sheet, i, 6)
remark = name + remark
if (len(addr) == 6):
if (len(unit)>0):
remark += '(' + unit + ')'
if (len(text)>0):
text += ',\n'
text += '\t\t\t{"key": "%s", "datatype": "%s", "remark": "%s"}' % (addr, datatype, remark.replace("\n", ""))
def parse_from_file(filename):
data = ""
with open(filename, "r", encoding='utf-8') as f: # 打开文件
linedata = ""
for line in f: # 行遍历
line = line.strip()
#linedata = f.readline() # 读取文件的一行
flag = bool(re.search(r'0x[0-9A-Fa-f]{4}', line))
linedata += line.strip()
if flag:
# print(linedata)
# left, separator, right = linedata.partition("0x")
parts = re.split(r'(0x[0-9A-Fa-f]{4})', linedata)
linedata = ""
key = parts[1]
datatype, remark = parse_datatype(parts[0].strip())
remark = remark.replace("\t", " ").replace("\"", "")
item = {}
item["key"] = key
item["datatype"] = datatype
item["remark"] = remark
if len(data) > 0:
data += ",\n"
data += ("\t\t\t" + json.dumps(item, ensure_ascii=False))
return data
if (len(text)>0):
text = "\n" + text + "\n\t\t"
text = '\t"%s":{\n\t\t"addr":[%s]\n\t}' % (topic, text)
return text
addritems = {}
addritems["EMS_YT"] = ["EMS遥调.txt", 1]
addritems["BCU_YX"] = ["BCU电池簇遥信.txt", 1]
addritems["BCU_YC"] = ["BCU电池簇遥测.txt", 1]
addritems["BMS_YC"] = ["BMS电池堆遥测.txt", 1]
addritems["EMS_YX"] = ["EMS遥信.txt", 1]
addritems["EMS_YC"] = ["EMS遥测.txt", 1]
addritems["EMS_YT"] = ["EMS遥调.txt", 1]
addritems["PCS_YX"] = ["PCS遥信.txt", 1]
addritems["PCS_YC"] = ["PCS遥测.txt", 1]
addritems["PCU_YX"] = ["PCU遥信.txt", 1]
addritems["PCU_YC"] = ["PCU遥测.txt", 1]
addritems["MEM_YC"] = ["多功能电表遥测.txt", 1]
addritems["TH_YC"] = ["温湿度状态遥测.txt", 1]
addritems["Fire40_YX"] = ["消防4.0遥信.txt", 1]
addritems["Cooling_YX"] = ["冷机遥信.txt", 1]
addritems["Cooling_YC"] = ["冷机遥测.txt", 1]
wb = load_workbook('EMU对外通信点表最终修改1版_v9.xlsx', data_only=True)
text = ""
text = read_sheet(wb, "EMS_YT", "EMS遥调")
text += ',\n' + read_sheet(wb, "EMS_YX", "EMS遥信")
text += ',\n' + read_sheet(wb, "PCU_YC", "PCU遥测")
text += ',\n' + read_sheet(wb, "PCU_YX", "PCU遥信")
text += ',\n' + read_sheet(wb, "PCS_YC", "PCS遥测")
text += ',\n' + read_sheet(wb, "PCS_YX", "PCS遥信")
text += ',\n' + read_sheet(wb, "BMS_YC", "BMS电池堆遥测")
text += ',\n' + read_sheet(wb, "BCU_YC", "BCU电池簇遥测")
text += ',\n' + read_sheet(wb, "BCU_YX", "BCU电池簇遥信")
# text += ',\n' + read_sheet(wb, "AirC_YC", "空调遥测")
# text += ',\n' + read_sheet(wb, "AirC_YX", "空调遥信")
text += ',\n' + read_sheet(wb, "MEM_YC", "多功能电表遥测")
text += ',\n' + read_sheet(wb, "TH_YC", "温湿度状态遥测")
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:
f.write("{")
index = 0
for key in addritems:
filename = addritems[key][0]
count = addritems[key][1]
print("parse: ", key, filename)
data = parse_from_file(filename)
if len(data) > 0:
data = "\n" + data + "\n\t"
if index != 0:
f.write(",")
f.write("\n\t\"" + key + "\": {\n\t\t\"count\":" + str(count) + ",\n\t\t\"addr\":[" + data + "\t]\n\t}")
index+=1
f.write("\n}")
f.write("{\n" + text + "\n}")
def read_sheet_alarm(wb, device_type, sht_name):
sheet = wb[sht_name]
text = ""
for i in range(1, sheet.max_row):
addr = read_cell(sheet, i, 8)
is_alarm = (read_cell(sheet, i, 7) == "告警")
if (len(addr) == 6 and is_alarm) :
name = read_cell(sheet,i, 2)
datatype = read_cell(sheet,i, 4)
unit = read_cell(sheet, i, 5)
remark = read_cell(sheet, i, 6)
remark = name + remark
if (len(unit)>0):
remark += '(' + unit + ')'
if (len(text)>0):
text += ',\n'
text += '\t\t\t{"key": "%s", "datatype": "%s", "remark": "%s"}' % (addr, datatype, remark.replace("\n", ""))
if (len(text)>0):
text = "\n" + text + "\n\t\t"
text = '\t"%s":{\n\t\t"addr":[%s]\n\t}' % (device_type, text)
return text;
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:
f.write("{\n" + text_err + "\n}")

View File

@@ -0,0 +1,84 @@
0x100F 绝缘故障 1:故障0正常
0x1010 漏电保护 1:故障0正常
0x1011 直流过压 1:故障0正常
0x1012 市电幅值异常 1:故障0正常
0x1013 市电相序异常 1:故障0正常
0x1014 温度开关异常 1:故障0正常
0x1015 市电频率异常 1:故障0正常
0x1016 IGBT过温 1:故障0正常
0x1017 交流接地故障 1:故障0正常
0x1018 逆变过流异常 1:故障0正常
0x1019 直流缓起故障 1:故障0正常
0x101A 直流主继电器故障 1:故障0正常
0x101B 风机异常 1:故障0正常
0x101C 主接触器异常 1:故障0正常
0x101D 均浮充切换超时 1:故障0正常
0x101E 硬件故障 1:故障0正常
0x101F 机内过温 1:故障0正常
0x1020 软启动故障 1:故障0正常
0x1021 触摸屏通讯故障 1:故障0正常
0x1022 防雷器故障 1:故障0正常
0x1023 急停故障 1:故障0正常
0x1024 BMS系统故障 1:故障0正常
0x1025 BMS通讯故障 1:故障0正常
0x1026 BMS干接点通讯故障 1:故障0正常
0x1027 远程通讯故障 1:故障0正常
0x1028 门禁告警 1:故障0正常
0x1029 锁相异常 1:故障0正常
0x102A IGBT过温告警 1:故障0正常
0x102B 硬件过流保护 1:故障0正常
0x102C 驱动故障 1:故障0正常
0x102D ID冲突 1:故障0正常
0x102E 电池过压 1:故障0正常
0x102F 电池欠压 1:故障0正常
0x1030 直流过流保护 1:故障0正常
0x1031 输出电压异常 1:故障0正常
0x1032 离网输出电压不符合 1:故障0正常
0x1033 输出过载保护 1:故障0正常
0x1034 输出短路保护 1:故障0正常
0x1035 并机通信异常 1:故障0正常
0x1036 电池保险异常 1:故障0正常
0x1037 电池重载低压 1:故障0正常
0x1038 电池低压告警 1:故障0正常
0x1039 一拖二压差过大 1:故障0正常
0x103A 电池反接故障 1:故障0正常
0x103B 电池电压异常 1:故障0正常
0x103C 过载告警 1:故障0正常
0x103D 外部接触器异常 1:故障0正常
0x103E IGBT温度传感器异常 1:故障0正常
0x103F 整机温度传感器异常 1:故障0正常
0x1040 市电CT异常 1:故障0正常
0x1041 逆变电流三相不平衡 1:故障0正常
0x1042 逆变电流直流分量异常 1:故障0正常
0x1043 母线不平衡 1:故障0正常
0x1044 逆变电压直流分量异常 1:故障0正常
0x1045 主接触器控制异常 1:故障0正常
0x1046 逆变电压控制异常 1:故障0正常
0x1047 直流霍尔异常 1:故障0正常
0x1048 电池单体过压 1:故障0正常
0x1049 电池单体欠压 1:故障0正常
0x104A 电网过压 1:故障0正常
0x104B 电网欠压 1:故障0正常
0x104C 电网过频 1:故障0正常
0x104D 电网欠频 1:故障0正常
0x104E 市电不平衡 1:故障0正常
0x104F 参数设置不匹配 1:故障0正常
0x1050 SPI通信异常 1:故障0正常
0x1051 SCI通信异常 1:故障0正常
0x1052 IIC通信异常 1:故障0正常
0x1053 Xintf通信异常 1:故障0正常
0x1054 零偏校准异常 1:故障0正常
0x1055 烟雾告警 1:故障0正常
0x1056 无电池组故障 1异常0正常
0x1057 环温降频 1异常0正常
0x1058 交流过载 1异常0正常
0x1059 采样异常 1异常0正常
0x105A 24V辅源故障 1异常0正常
0x105B 直流欠压异常 1异常0正常
0x105C 散热器过温 1异常0正常
0x105D CAN配置故障 1异常0正常
0x105E 3.3V辅源故障 1异常0正常
0x105F 环境过温 1异常0正常
0x1060 A相IGBT逆变过流 1异常0正常
0x1061 B相IGBT逆变过流 1异常0正常
0x1062 C相IGBT逆变过流 1异常0正常

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -127,8 +127,7 @@ void AppData::initFromDB()
auto station = this->getStation(stationId);
if (station)
{
auto device = Device::create(fields);
station->addDevice(deviceId, device);
station->addDevice(fields);
}
else
{
@@ -248,7 +247,6 @@ void AppData::init()
for (auto& item : mapStation)
{
auto& station = item.second;
if (station->status == 1)
{
// "tcp://localhost:1883"
@@ -256,7 +254,6 @@ void AppData::init()
}
}
}
this->launchDate = Config::option.lunchDate;
}

View File

@@ -102,6 +102,17 @@ void Application::runThreadMain()
// }
//}
///////////////////////////////////////////////////////////////////////////////////////////
/// 召测
static TimeTick tt1;
if (tt1.elapse(10))
{
for (auto& item: appdata.mapStation)
{
auto& station = item.second;
station->polling();
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
@@ -131,6 +142,16 @@ void Application::runThreadStat()
{
//spdlog::info("保存历史数据倒计时: {}", 600 - offset);
}
for (auto& station : appdata.mapStation)
{
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}

View File

@@ -16,53 +16,45 @@ static bool CheckCacheType(int type)
std::shared_ptr<Device> Device::create(Fields& fields)
{
auto device = std::make_shared<Device>();
device->deviceId = fields.get<int>("device_id");
device->type = fields.get<int>("type");
device->name = fields.value("name");
device->code = fields.value("code");
device->isOpen = fields.get<int>("is_open");
device->attrsJson = fields.value("attrs");
device->category = fields.get<int>("category");
device->setFields(fields);
return device;
}
void Device::setFields(Fields& fields)
{
fields.get("device_id", this->deviceId);
fields.get("type", this->type);
fields.get("name", this->name);
fields.get("code", this->code);
fields.get("is_open", this->isOpen);
fields.get("attrs", this->attrsJson);
fields.get("category", this->category);
// 解析属性的JSON字符串转换成键值对
njson jsonroot;
bool ret = JSON::parse(device->attrsJson, jsonroot);
bool ret = JSON::parse(this->attrsJson, jsonroot);
if (!ret) // 解析错误
{
spdlog::error("[device] device attr json parse error, device_id={}", device->deviceId);
spdlog::error("[device] device attr json parse error, device_id={}", this->deviceId);
}
else
{
this->attrs.clear();
for (auto& [key, val] : jsonroot.items()) {
std::string valType = val.type_name();
if (valType == "string") {
device->attrs.set(key, val.get<std::string>());
this->attrs.set(key, val.get<std::string>());
}
else if (valType == "number") {
device->attrs.set(key, val.get<int>());
this->attrs.set(key, val.get<int>());
}
else {
spdlog::error("[device] device attr unknown type: key={}, valtype={}", key, valType);
}
}
}
//int step = 600;
//for (int i = 0; i*600<86400; ++i)
//{
// double voltage = double(Utils::random(20000, 30000))*0.01;
// double current = double(Utils::random(1000, 2000))*0.01;
// device->mapCacheVoltage[i*step] = voltage;
// device->mapCacheCurrent[i*step] = current;
// device->mapCachePower[i*step] = voltage * current;
//}
// 启动通讯该函数中会自动判断isOpen状态选择是否进行通讯连接
//device->startComm();
return device;
}
int Device::startComm()
{
if (!isOpen)

View File

@@ -16,6 +16,8 @@ class Device
public:
static std::shared_ptr<Device> create(Fields& fields);
void setFields(Fields& fields);
int startComm();
void getCacheVoltage(std::vector<std::string>& vec);

View File

@@ -35,7 +35,7 @@ void Station::setFields(Fields& fields)
{
this->stationId = fields.get<int>(DMStation::STATION_ID);
this->name = fields.value(DMStation::NAME);
this->energyCapacity = fields.get<double>(DMStation::CAPACITY);
this->capacity = fields.get<double>(DMStation::CAPACITY);
this->workModeId = fields.get<int>(DMStation::WORK_MODE);
this->code = fields.value(DMStation::CODE);
this->status = fields.get<int>(DMStation::STATUS);
@@ -47,6 +47,22 @@ void Station::addDevice(int deviceId, std::shared_ptr<Device> device)
mapDeviceGroup[device->category].push_back(device);
}
void Station::addDevice(Fields& fields)
{
int deviceId = fields.get<int>(DMDevice::DEVICE_ID);
int stationId = fields.get<int>(DMDevice::STATION_ID);
if (mapDevice.find(deviceId) != mapDevice.end())
{
mapDevice[deviceId]->setFields(fields);
}
else
{
auto device = Device::create(fields);
mapDevice[deviceId] = device;
mapDeviceGroup[device->category].push_back(device);
}
}
std::shared_ptr<Device> Station::getDevice(int deviceId)
{
auto iter = mapDevice.find(deviceId);
@@ -82,8 +98,13 @@ void Station::getDeviceByType(int deviceType, std::vector<std::shared_ptr<Device
}
}
int Station::getDeviceNumByGroup(int category)
int Station::getDeviceCount(int category)
{
auto iter = mapDeviceGroup.find(category);
if (iter != mapDeviceGroup.end())
{
return iter->second.size();
}
return 0;
}
@@ -159,3 +180,12 @@ void Station::writeRuntimeData(std::string dt, int npos)
}
}
}
void Station::polling()
{
if (mqttCli)
{
mqttCli->polling();
}
}

View File

@@ -95,11 +95,12 @@ public:
void setFields(Fields& fields);
void addDevice(int deviceId, std::shared_ptr<Device> device);
void addDevice(Fields& fields);
std::shared_ptr<Device> getDevice(int deviceId);
std::shared_ptr<Device> getDeviceByType(int deviceType, std::string code);
void getDeviceByType(int typeId, std::vector<std::shared_ptr<Device>>& res);
int getDeviceNumByGroup(int category);
int getDeviceCount(int category);
void getDeviceByGroup(int category, std::vector<std::shared_ptr<Device>>& res);
void setWorkMode(int modeId);
@@ -108,6 +109,7 @@ public:
void writeRuntimeData(std::string dt, int npos);
void polling();
public:
int stationId {};
@@ -119,24 +121,22 @@ public:
int workModeId {}; // 运行模式
int runPolicyId {}; // 运行策略
// 储能容量
double energyCapacity {};
///////////////////////////////////////////////////////////////////////////////////////////////
/// === 系统统计 ===
// 累计发电量单位kWh
double electGenTatal {};
double electGenTotal {};
// 累计入网电量单位kWh
double electGridTotal {};
// 累计收益,单位:元
double incomeTotal {};
// 碳减排量, 单位:吨
double ccers {};
// 累计储能充电电量
double electStorageIn {};
// 累计储能放电电量
double electStorageOut {};
// 储能容量
double capacity {};
///////////////////////////////////////////////////////////////////////////////////////////////
/// === 日统计 ===
double storageIn {}; // 储能充电电量

View File

@@ -22,7 +22,7 @@ public:
Fields() {};
template <typename T>
void set(string key, T val, int precision=6)
void set(string key, T val, int precision=2)
{
stringstream ss;
ss.precision(precision);
@@ -31,7 +31,7 @@ public:
}
template <typename T>
T get(string key, int precision = 6)
T get(string key, int precision = 2)
{
T val {};
auto iter = mapFields.find(key);
@@ -44,6 +44,18 @@ public:
return val;
}
template <typename T>
void get(string key, T& val, int precision = 2)
{
auto iter = mapFields.find(key);
if (iter != mapFields.end())
{
stringstream ss(iter->second);
ss.precision(precision);
ss >> val;
}
}
/**
* 获取值
* @param: [string key] 索引名称

View File

@@ -99,10 +99,10 @@ public:
if (t !=0) { tickMS_ = Utils::time(); }
}
bool elapse(int64_t ms, bool reset = true)
bool elapse(int64_t second, bool reset = true)
{
auto tick_now = Utils::time();
bool res = tick_now - tickMS_ > ms;
bool res = tick_now - tickMS_ > second;
if (res && reset)
{
tickMS_ = tick_now;

View File

@@ -280,7 +280,7 @@ Errcode DAO::deleteUserById(std::string userId)
Errcode DAO::queryPermissionList(PageInfo& pageInfo, vector<Fields>& result)
{
std::string sqlFrom = "FROM " + DMPermission::TABLENAME;
std::string sqlFrom = "FROM permission WHERE permission.parent_id IS NULL OR permission.parent_id=''";
return QueryPagination("*", sqlFrom, pageInfo, result);
}
@@ -343,14 +343,31 @@ Errcode DAO::insertRole(Fields& params)
if (err == Errcode::OK && !permission.empty())
{
// 查询获取 roleId
std::vector<Fields> res;
std::string sql = "SELECT * FROM " + DMRole::TABLENAME + " WHERE name='" + name + "';";
err = DAO::exec(dao, sql, res);
if (err == Errcode::OK && res.size() > 0)
njson jsonarray;
if (JSON::parse(permission, jsonarray))
{
//std::string roleId = res[0].value("role_id");
//err = DAO::updateRolePermission(dao, roleId, permission);
// 查询获取 roleId
std::vector<Fields> res;
std::string sql = "SELECT * FROM " + DMRole::TABLENAME + " WHERE name='" + name + "';";
err = DAO::exec(dao, sql, res);
if (err == Errcode::OK && res.size() > 0)
{
std::string roleId = res[0].value("role_id");
std::vector<Fields> vecFields;
for (auto& item: jsonarray)
{
Fields fields;
fields.set("role_id", roleId);
fields.set("permission_id", item["permission_id"].get<std::string>());
fields.set("is_open", item["is_open"].get<std::string>());
fields.set("is_view", item["is_view"].get<std::string>());
fields.set("is_add", item["is_add"].get<std::string>());
fields.set("is_edit", item["is_edit"].get<std::string>());
fields.set("is_del", item["is_del"].get<std::string>());
vecFields.push_back(fields);
}
err = DAO::updateRolePermission(dao, roleId, vecFields);
}
}
}
return err;

View File

@@ -113,7 +113,6 @@ public:
// === 统计数据管理 ===
static Errcode queryStatDataList(std::shared_ptr<DaoEntity> dao, std::string startDate, std::string endDate, vector<Fields>& result);
static Errcode queryWorkModeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
static Errcode queryPolicyTypeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);

View File

@@ -128,13 +128,6 @@ int main(int argc, char** argv)
Spdlogger::init(spdlog::level::debug, "");
spdlog::info("[main] start ... ======================================================================");
spdlog::info("");
std::cout << Snowflake::instance().getId() << std::endl;
for (int i = 0; i<=10; ++i) {
std::cout << Snowflake::instance().getId() << std::endl;
}
// 运行后台服务
Application::instance().init();

View File

@@ -39,8 +39,8 @@ static void JsonToFields(njson& json, std::vector<std::string> vecKeys, Fields&
case njson::value_t::number_unsigned: { fields.set(key, json[key].get<int>()); } break;
case njson::value_t::number_float: { fields.set(key, json[key].get<float>()); } break;
case njson::value_t::null: {} break;
case njson::value_t::object: {} break;
case njson::value_t::array: {} break;
case njson::value_t::object: { fields.set(key, json[key].dump()); } break;
case njson::value_t::array: { fields.set(key, json[key].dump()); } break;
case njson::value_t::binary: {} break;
case njson::value_t::discarded: {} break;
default:
@@ -165,6 +165,7 @@ static std::map<std::string, HandlerOptions> g_mapHttpHandlerGet =
{"/queryPredictionDetail", HandlerOptions(&HttpEntity::queryPredictionDetail, {})},
{"/queryStatSystem", HandlerOptions(&HttpEntity::queryStatSystem, {})},
{"/queryStatStation", HandlerOptions(&HttpEntity::queryStatStation, {})},
{"/queryStatTotal", HandlerOptions(&HttpEntity::queryStatTotal, {})},
{"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})},
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
@@ -390,6 +391,38 @@ Errcode HttpEntity::queryPermissionList(const httplib::Request& req, njson& json
std::vector<Fields> result;
auto err = DAO::queryPermissionList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
std::map<std::string, int> mapP;
for (int i = 0; i<result.size(); ++i)
{
auto& item = result[i];
std::string id = item.value("permission_id");
mapP[id] = json["data"].size() - 1;
}
std::vector<Fields> vecSubPermission;
DaoEntity::execOnce("SELECT * FROM permission WHERE permission.parent_id IS NOT NULL AND permission.parent_id!='';", vecSubPermission);
for (int i = 0; i<vecSubPermission.size(); ++i)
{
auto& item = vecSubPermission[i];
std::string parentId = item.value("parent_id");
std::string id = item.value("permission_id");
if (!parentId.empty())
{
if (mapP.count(parentId) > 0)
{
int index = mapP[parentId];
njson jsonnode;
FieldsToJson(item, jsonnode);
json["data"][index]["children"].push_back(jsonnode);
}
}
}
}
return err;
}
@@ -423,6 +456,8 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std:
std::vector<Fields> result;
auto err = DAO::queryRoleList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
@@ -432,8 +467,8 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std:
{
return err;
}
std::map<std::string, std::vector<Fields>> mapP;
std::map<std::string, std::vector<Fields>> mapP;
for (int i = 0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
@@ -444,7 +479,6 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std:
mapP[roleId].push_back(vecPermission[i]);
}
HttpHelper::setPagination(pageinfo, result, json);
for (auto& item : json["data"])
{
auto jsonpermission = njson::array();
@@ -487,6 +521,14 @@ Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std:
return err;
}
Errcode HttpEntity::queryRolePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"role_id"}, params);
if (!params.contains("role_id")) { errmsg = "缺少参数[role_id]"; return Errcode::ERR_PARAM; }
return Errcode::OK;
}
Errcode HttpEntity::insertRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
@@ -496,33 +538,34 @@ Errcode HttpEntity::insertRole(const httplib::Request& req, njson& json, std::st
Errcode HttpEntity::updateRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
//GetRequestParam(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
njson jsonparam;
if (!JSON::parse(req.body, jsonparam))
{
return Errcode::ERR_PARAM;
}
JsonToFields(jsonparam, {"role_id", "name", "describe", "is_open"}, params);
GetRequestParam(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
auto roleId = params.value("role_id");
std::string permission = params.remove("permission");
auto dao = DaoEntity::create("");
auto err = DAO::updateRoleById(dao, params);
if (err == Errcode::OK && jsonparam.contains("permission"))
auto err = Errcode::OK;
if (params.size() > 1)
{
if (jsonparam["permission"].is_array())
err = DAO::updateRoleById(dao, params);
}
if (err == Errcode::OK && !permission.empty())
{
njson jsonarray;
if (JSON::parse(permission, jsonarray))
{
auto& jsonPermission = jsonparam["permission"];
std::vector<Fields> vecFields(jsonPermission.size());
int i = 0;
for (auto& item: jsonPermission)
std::vector<Fields> vecFields;
for (auto& item: jsonarray)
{
auto& fields = vecFields[i];
i++;
JsonToFields(item, {"permission_id", "is_add", "is_del", "is_edit", "is_view"}, fields);
Fields fields;
fields.set("role_id", roleId);
fields.set("permission_id", item["permission_id"].get<std::string>());
fields.set("is_open", item["is_open"].get<std::string>());
fields.set("is_view", item["is_view"].get<std::string>());
fields.set("is_add", item["is_add"].get<std::string>());
fields.set("is_edit", item["is_edit"].get<std::string>());
fields.set("is_del", item["is_del"].get<std::string>());
vecFields.push_back(fields);
}
err = DAO::updateRolePermission(dao, roleId, vecFields);
}
@@ -704,13 +747,31 @@ Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::
{
Fields params;
GetRequestParam(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
return DAO::insertDevice(params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
Errcode err = DAO::insertDevice(params);
if (err == Errcode::OK)
{
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station) { station->addDevice(params); }
}
return err;
};
Errcode HttpEntity::updateDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParam(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
return DAO::updateDeviceById(params);
Errcode err = DAO::updateDeviceById(params);
if (err == Errcode::OK)
{
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station) { station->addDevice(params); }
}
return err;
};
Errcode HttpEntity::deleteDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
@@ -906,21 +967,63 @@ Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, st
{
auto& appdata = Application::data();
double incomeTotal {};
double station_num = appdata.getStationCount();
double solarDeviceNum {};
double capacityTotal {};
double electGenTotal {};
double electGridTotal {};
double electStorageIn {};
double electStorageOut {};
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
solarDeviceNum += station->getDeviceCount(3);
capacityTotal += station->capacity;
electGenTotal += station->electGenTotal;
electGridTotal += station->electGridTotal;
electStorageIn += station->electStorageIn;
electStorageOut += station->electStorageOut;
}
njson jsondata;
jsondata["launch_date"] = appdata.launchDate; //: 系统上线启用日期格式yyyy-mm-dd
jsondata["income_total"] = std::to_string(Utils::random(100, 200)); // : 累计收益精度0.01
jsondata["station_num"] = Utils::toStr(appdata.getStationCount()); // : 能源站数量
jsondata["storage_device_num "] = Utils::toStr(appdata.getStationCount()); //: 储能设备数量
jsondata["solar_device_num"] = "0"; // : 光伏设备数量
jsondata["capacity_total"] = std::to_string(Utils::random(100, 200)); // : 储能总容量kWh精度0.001
jsondata["solar_elect_gen"] = std::to_string(Utils::random(100, 200)); // : 发电总电量kWh精度0.001
jsondata["solar_elect_grid"] = std::to_string(Utils::random(100, 200)); // : 入网种电量kWh精度0.001
jsondata["storage_elect_in"] = std::to_string(Utils::random(100, 200)); // : 储能充电总电量kWh精度0.001
jsondata["storage_elect_out"] = std::to_string(Utils::random(100, 200)); // : 储能放电总电量kWh精度0.001
jsondata["income_total"] = incomeTotal; // : 累计收益精度0.01
jsondata["station_num"] = station_num; // : 能源站数量
jsondata["storage_device_num"] = station_num; //: 储能设备数量
jsondata["solar_device_num"] = solarDeviceNum; //: 光伏设备数量
jsondata["capacity_total"] = capacityTotal; // : 储能总容量kWh精度0.001
jsondata["solar_elect_gen"] = electGenTotal; // : 发电总电量kWh精度0.001
jsondata["solar_elect_grid"] = electGridTotal; // : 入网种电量kWh精度0.001
jsondata["storage_elect_in"] = electStorageIn; // : 储能充电总电量kWh精度0.001
jsondata["storage_elect_out"] = electStorageOut; // : 储能放电总电量kWh精度0.001
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryStatStation(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
ON ss.station_id = s.station_id)";
std::vector<Fields> vecStations;
auto err = dao->exec(sql, vecStations);
for (auto& fields: vecStations)
{
njson jsonnode;
jsonnode["station_name"] = fields.value("station_name");
jsonnode["income"] = fields.get<float>("income_elect") + fields.get<float>("income_charge");
jsonnode["usage_rate"] = fields.get<float>("usage_rate");
jsondata.push_back(jsonnode);
}
json["data"] = jsondata;
return Errcode(err);
}
Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string station_id = req.get_param_value("station_id");
@@ -948,48 +1051,61 @@ Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std
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 station_id = req.get_param_value("station_id");
std::string category = req.get_param_value("category");
std::string dt_start = req.get_param_value("start_date");
std::string dt_end = req.get_param_value("end_date");
int64_t t1 = Utils::time(dt_start)/1000;
int64_t t2 = Utils::time(dt_end)/1000;
int64_t tMax = t1+ 86400 * 30;
njson jsondata = njson::array();
for (int64_t t = t1; t<=t2 && t<=tMax; t += 86400)
//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())
{
njson jnode;
jnode["station_id"] = station_id;
if (!category.empty()) jnode["category"] = category;
jnode["dt"] = Utils::dateStr(t*1000); //日期
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);
if (dtStart.empty())
{
dtEnd = Utils::dateStr();
dtStart = Utils::dateStr(Utils::date() - 86400*7);
}
else
{
dtEnd = Utils::dateStr(Utils::time(dtStart + " 00:00:00") + 86400*7);
}
}
json["data"] = jsondata;
std::vector<Fields> result;
Errcode err = DAO::queryStatDataList(NULL, dtStart, dtEnd, 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;
}
@@ -999,10 +1115,11 @@ Errcode HttpEntity::queryStatCharts(const httplib::Request& req, njson& json, st
std::string stationId = req.get_param_value("station_id");
std::string category = req.get_param_value("category");
if (dt.empty()) { errmsg = "参数[dt]错误"; return Errcode::ERR_PARAM; }
if (stationId.empty()) { errmsg = "参数[station_id]错误"; return Errcode::ERR_PARAM; }
if (category.empty()) { errmsg = "参数[category]错误"; return Errcode::ERR_PARAM; }
if (dt.empty()) { dt=Utils::dateStr(); }
njson jsondata;
std::string sql = R"(SELECT hd.*, d.`type` device_type, ddt.category FROM history_day hd

View File

@@ -43,6 +43,7 @@ public:
Errcode queryRoleList(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode queryRolePermission(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode insertRole(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode updateRole(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode deleteRole(const httplib::Request& req, njson& json, std::string& errmsg);
@@ -80,8 +81,10 @@ public:
Errcode queryPredictionDetail(const httplib::Request& req, njson& json, std::string& errmsg);
// 系统总览所有场站统计
// 系统总览所有场站统计 (总览页 运行状况)
Errcode queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg);
Errcode queryStatStation(const httplib::Request& req, njson& json, std::string& errmsg);
// 一个场站的累计统计
Errcode queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg);
// 场站按类别按天统计

View File

@@ -29,7 +29,7 @@ void MqttClient::loadDataStruct(std::string filename)
{
std::string name = jsonitem.key();
auto jsonnodeItem = jsonitem.value();
int count = jsonnodeItem["count"];
//int count = jsonnodeItem["count"];
auto jsonaddrs = jsonnodeItem["addr"];
auto& mapItem = g_mapRegInfo[name];
@@ -59,23 +59,22 @@ int MqttClient::init(string addr, string clientId, string username, string passw
this->addr = addr;
this->clientId = clientId;
this->mapTopicInfo["EMS_YX"] = 101;
this->mapTopicInfo["EMS_YX"] = 101;
this->mapTopicInfo["EMS_YC"] = 101;
this->mapTopicInfo["EMS_YT"] = 101;
this->mapTopicInfo["PCS_YX"] = 102;
this->mapTopicInfo["PCS_YC"] = 102;
this->mapTopicInfo["PCU_YX"] = 103;
this->mapTopicInfo["PCU_YC"] = 103;
this->mapTopicInfo["BMS_YX"] = 104;
this->mapTopicInfo["BMS_YC"] = 104;
this->mapTopicInfo["BCU_YX"] = 105;
this->mapTopicInfo["BCU_YC"] = 105;
this->mapTopicInfo["MEM_YC"] = 3;
this->mapTopicInfo["Cooling_YC"] = 110;
this->mapTopicInfo["TH_YC"] = 111;
this->mapTopicInfo["Gateway_YX"] = 112;
this->mapTopicInfo["Charger_YC"] = 113;
//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);
MQTTAsync_connectOptions option = MQTTAsync_connectOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
@@ -168,25 +167,6 @@ void MqttClient::subscribe()
MQTTAsync_responseOptions options = MQTTAsync_responseOptions_initializer;
options.onSuccess = funcSuccess;
options.onFailure = funcFailure;
std::vector<std::string> vecTopic = {
//"up/json/" + clientId + "/EMS_YX",
"up/json/" + clientId + "/EMS_YC",
//"up/json/" + clientId + "/EMS_YT",
//"up/json/" + clientId + "/PCU_YX",
//"up/json/" + clientId + "/PCU_YC",
//"up/json/" + clientId + "/PCS_YX",
"up/json/" + clientId + "/PCS_YC",
//"up/json/" + clientId + "/BCU_YX",
//"up/json/" + clientId + "/BCU_YC",
//"up/json/" + clientId + "/BMS_YX",
//"up/json/" + clientId + "/BMS_YC",
//"up/json/" + clientId + "/MEM_YC",
//"up/json/" + clientId + "/Cooling_YC",
//"up/json/" + clientId + "/TH_YC",
//"up/json/" + clientId + "/Gateway_YX",
//"up/json/" + clientId + "/Charger_YC",
};
for (auto& item: mapTopicInfo)
{
std::string topic = "up/json/" + clientId + "/" + item.first;
@@ -199,38 +179,11 @@ void MqttClient::subscribe()
}
}
int MqttClient::polling()
int MqttClient::publish(std::string topic, std::string text)
{
// 召测 发布
std::vector<std::string> vecTopic = {
"down/json/" + clientId + "/EMS_YX",
"down/json/" + clientId + "/EMS_YC",
//"down/json/" + clientId + "/EMS_YT",
//"down/json/" + clientId + "/PCU_YX",
//"down/json/" + clientId + "/PCU_YC",
//"down/json/" + clientId + "/PCS_YX",
"down/json/" + clientId + "/PCS_YC",
//"down/json/" + clientId + "/BCU_YX",
//"down/json/" + clientId + "/BCU_YC",
//"down/json/" + clientId + "/BMS_YX",
//"down/json/" + clientId + "/BMS_YC",
//"down/json/" + clientId + "/MEM_YC",
//"down/json/" + clientId + "/Cooling_YC",
//"down/json/" + clientId + "/TH_YC",
//"down/json/" + clientId + "/Gateway_YX",
//"down/json/" + clientId + "/Charger_YC",
};
njson json;
json["ts"] = Utils::time();
json["no"] = 1;
std::string text = json.dump();
MQTTAsync_responseOptions options = MQTTAsync_responseOptions_initializer;
//options.onSuccess = onSend;
//options.onFailure = onSendFailure;
options.onSuccess = [](void* context, MQTTAsync_successData* response) {};
options.onFailure = [](void* context, MQTTAsync_failureData* response) {};
options.context = this;
MQTTAsync_message msg = MQTTAsync_message_initializer;
@@ -239,16 +192,48 @@ int MqttClient::polling()
msg.payloadlen = text.size();
msg.retained = 0;
for (auto& topic: vecTopic)
std::string topicName = "down/json/" + clientId + "/" + topic;
int rc = MQTTAsync_sendMessage(client, topicName.c_str(), &msg, &options);
if (rc == MQTTASYNC_SUCCESS)
{
int rc = MQTTAsync_sendMessage(client, topic.c_str(), &msg, &options);
if (rc == MQTTASYNC_SUCCESS)
spdlog::info("[mqtt] publish MQTTAsync_sendMessage success, topic={}, text={}", topicName, text);
}
else
{
spdlog::error("[mqtt] publish MQTTAsync_sendMessage error, topic={}, text={}", topicName, text);
}
return 0;
}
int MqttClient::polling()
{
if (!isConnected)
{
return 0;
}
njson json;
json["ts"] = Utils::time();
json["no"] = 0; // 设备编号
auto& appdata = Application::data();
auto station = appdata.getStationByCode(clientId);
for (auto& item: mapTopicInfo)
{
auto& topicInfo = item.second;
if (topicInfo.polling)
{
spdlog::info("MQTT send message success, topic={}, text={}", topic, msg.payload);
}
else
{
spdlog::error("MQTT send message error, topic={}, text={}", topic, msg.payload);
if (station)
{
std::vector<std::shared_ptr<Device>> vecDevice;
station->getDeviceByType(topicInfo.deviceType, vecDevice);
for (auto device: vecDevice)
{
json["no"] = Utils::toInt(device->code);
this->publish(topicInfo.name, json.dump());
}
}
}
}
return 0;
@@ -292,8 +277,7 @@ int MqttClient::onMessageArrived(char* topic, int topicLen, MQTTAsync_message* m
std::string command = GetSubStr("/", topicStr);
std::string deviceCode = GetSubStr("/", topicStr);
spdlog::info("[mqtt] message arrived: topic=[{},{}], len={}, payload={}", topic, msg->qos, len, payload);
spdlog::info("[mqtt] parse topic: {}, stationNo={}, command={}", topic, stationNo, command);
spdlog::info("[mqtt] <<<<<<<<<< message arrived: topic=[{},{}], len={}, payload={}", topic, msg->qos, len, payload);
njson json;
bool ret = JSON::parse(payload, json);
@@ -317,16 +301,23 @@ int MqttClient::onMessageArrived(char* topic, int topicLen, MQTTAsync_message* m
}
std::map<std::string, REGInfo>& 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(mapTopicInfo[command], Utils::toStr(deviceNo));
auto device = station->getDeviceByType(topicInfo.deviceType, Utils::toStr(deviceNo));
if (!device)
{
return 1;
}
spdlog::info("[mqtt] deviceNo={}", deviceNo);
for (auto& item: json.items())
{
std::string key = item.key();
@@ -371,36 +362,13 @@ 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();
//MQTTAsync_responseOptions options = MQTTAsync_responseOptions_initializer;
//options.context = this;
//options.onSuccess = [](void* context, MQTTAsync_successData* response)
// {
// spdlog::info("[mqtt] subscribe success.");
// };
//options.onFailure = [](void* context, MQTTAsync_failureData* response)
// {
// spdlog::info("[mqtt] subscribe failed.");
// };
//
//for (auto& topic: vecTopic)
//{
// int rc = MQTTAsync_subscribe(client, topic.c_str(), qos, &options);
// if (rc != MQTTASYNC_SUCCESS)
// {
// spdlog::error("[mqtt] subscribe [{},{}] failed, err={}", topic, qos, rc);
// }
// else
// {
// spdlog::info("[mqtt] subscribe [{},{}] success", topic, qos);
// }
//}
}
void MqttClient::onConnectFaiure(MQTTAsync_failureData* resp)
{
spdlog::error("[mqtt] connect to {} error, clientId={}.", addr, clientId);

View File

@@ -25,16 +25,16 @@ struct REGInfo
}
};
//struct TopicInfo
//{
// std::string name;
// std::string topic;
// int deviceType;
// TopicInfo() {};
// TopicInfo(std::string name, std::string topic, int deviceType)
// :name(name), topic(topic), deviceType(deviceType)
// {};
//};
struct TopicInfo
{
std::string name;
int deviceType {0};
int polling {0}; // 召测
TopicInfo() {};
TopicInfo(std::string name, int deviceType, int polling=0)
:name(name), deviceType(deviceType), polling(polling)
{};
};
using namespace std;
@@ -47,8 +47,7 @@ public:
void destory();
void subscribe();
//int publish();
int publish(std::string topic, std::string text);
int polling();
void onConnectionLost(char* cause);
@@ -61,6 +60,7 @@ public:
void parseEMS_YX(std::shared_ptr<Station> station, njson& json, std::map<std::string, REGInfo>& mapRegInfo);
public:
// MQTT clientId (使用station 的 code)
std::string clientId;
MQTTAsync client = nullptr;
@@ -69,7 +69,7 @@ public:
bool isConnected {false};
bool isSubscribed {false};
std::map<std::string, int> mapTopicInfo;
std::map<std::string, TopicInfo> mapTopicInfo;
};