实现系统总览、统计分析的图标数据接口

This commit is contained in:
lixiaoyuan
2025-07-31 17:56:08 +08:00
parent 0958fcc224
commit 697193a7aa
19 changed files with 984 additions and 640 deletions

View File

@@ -33,7 +33,7 @@
<option value="3">储能设备</option>
<option value="4">充电设备</option>
<option value="5">负荷设备</option>
<option value="0">其它</option>0
<option value="0">其它</option>
</select>
</div>
<div class="input-group mb-3">

View File

@@ -38,27 +38,6 @@ $(document).ready(function () {
$('div.gotopage').html('<b style="color:#7f8fa4">跳转至 </b><input id="searchNumber" style="width:80px"/><b style="color:#7f8fa4;"> 页</b>')
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['5214875222', 'C018', 'XH150', '', '', '2025-03-03', 'TCP', '', '', '', '', ''])
// myTable.row.add(['1', '2', '3', '', '', '', '', '', '', '', '', ''])
// myTable.row.add(['1', '2', '3', '', '', '', '', '', '', '', '', ''])
// myTable.row.add(['1', '2', '3', '', '', '', '', '', '', '', '', ''])

View File

@@ -1,67 +1,65 @@
optionBar.xAxis.data = ['03/01', '03/02', '03/03', '03/04', '03/05', '03/06', '03/07']
var optionBar = echartGetOptionBar()
optionBar.xAxis.data = []
optionBar.legend.data = ['发电电量', '入网电量']
optionBar.series = [
{ name: '发电电量', type: 'bar', data: [50, 28, 35, 18, 36, 27, 19] },
{ name: '入网电量', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '发电电量', type: 'bar', data: [] },
{ name: '入网电量', type: 'bar', data: [] },
]
optionBar.yAxis[0].name = '电量'
optionBar.yAxis[1].name = ''
var mychartSolar = echarts.init(document.getElementById('mychartSolar'))
mychartSolar.setOption(optionBar)
optionBar.legend.data = ['充电电量', '放电电量']
optionBar.series = [
{ name: '充电电量', type: 'bar', data: [50, 28, 35, 18, 36, 27, 19] },
{ name: '放电电量', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '充电电量', type: 'bar', data: [] },
{ name: '放电电量', type: 'bar', data: [] },
]
optionBar.yAxis[0].name = '电量'
optionBar.yAxis[1].name = ''
var mychartStorage = echarts.init(document.getElementById('mychartStorage'))
mychartStorage.setOption(optionBar)
optionBar.legend.data = ['用电电量', '最大功率']
optionBar.series = [
{ name: '用电电量', type: 'bar', data: [50, 28, 35, 18, 36, 27, 19] },
{ name: '最大功率', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '用电电量', type: 'bar', data: [] },
{ name: '最大功率', type: 'bar', data: [] },
]
optionBar.yAxis[0].name = '电量'
optionBar.yAxis[1].name = '功率'
var mychartLoad = echarts.init(document.getElementById('mychartLoad'))
mychartLoad.setOption(optionBar)
optionBar.legend.data = ['充电电量', '充电次数', '充电收益']
optionBar.series = [
{ name: '充电电量', type: 'bar', data: [50, 28, 35, 18, 36, 27, 19] },
{ name: '充电次数', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '充电收益', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '充电电量', type: 'bar', data: [] },
{ name: '充电次数', type: 'bar', data: [] },
{ name: '充电收益', type: 'bar', data: [] },
]
optionBar.yAxis[0].name = '电量'
optionBar.yAxis[1].name = '收益'
var mychartCharge = echarts.init(document.getElementById('mychartCharge'))
mychartCharge.setOption(optionBar)
optionBar.legend.data = ['光伏设备', '储能设备', '负荷设备']
optionBar.series = [
{ name: '光伏设备', type: 'bar', data: [50, 28, 35, 18, 36, 27, 19] },
{ name: '储能设备', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '负荷设备', type: 'bar', data: [10, 32, 20, 33, 39, 13, 22] },
{ name: '光伏设备', type: 'bar', data: [] },
{ name: '储能设备', type: 'bar', data: [] },
{ name: '负荷设备', type: 'bar', data: [] },
]
optionBar.yAxis[0].name = '次数'
optionBar.yAxis[1].name = ''
var mychartAlert = echarts.init(document.getElementById('mychartAlert'))
mychartAlert.setOption(optionBar)
function getRandomCurveData(m, n) {
var data = []
var t0 = Date.parse('2025-03-01 00:00:00')
var step = 600
var N = 86400 / step
var y = 500
for (var i = 0; i <= N; ++i) {
var t = t0 + i * step * 1000
//var y = Math.sin(i * 0.1) * (n - m) + m
y = Math.floor((y + RAND(0, 50) - 25) * 100) / 100
data[i] = { name: t, value: [t, y] }
}
return data
}
var optionCurve = echartGetOptionCurve()
optionCurve.legend.data = ['发电功率', '辐照度']
optionCurve.series = [
{ name: '发电功率', type: 'line', hoverAnimation: false, smooth: false, symbolSize: 0, data: getRandomCurveData(100, 200) },
{ name: '辐照度', type: 'line', hoverAnimation: false, smooth: false, symbolSize: 0, data: getRandomCurveData(100, 200) },
{ name: '发电功率', type: 'line', hoverAnimation: false, smooth: false, symbolSize: 0, data: [] },
{ name: '辐照度', type: 'line', hoverAnimation: false, smooth: false, symbolSize: 0, data: [] },
]
optionCurve.yAxis[0].name = '功率kw'
optionCurve.yAxis[1].name = '光照Lux'
var mychartRunning = echarts.init(document.getElementById('mychartRunning'))
mychartRunning.setOption(optionCurve)
@@ -95,8 +93,8 @@ function updatePageData() {
var charge = { d1: [], d2: [], d3: [] }
res.forEach(item => {
solar.d1.push(item['elect_gen_solar'])
solar.d2.push(item['elect_in_solar'])
solar.d1.push(item['elect_gen'])
solar.d2.push(item['elect_in'])
storage.d1.push(item['elect_store'])
storage.d2.push(item['elect_discharge'])
@@ -113,21 +111,32 @@ function updatePageData() {
// var data2 = [1, 2, 3, 4, 3, 2, 1]
// var data3 = [1, 2, 3, 4, 3, 2, 1]
mychartSolar.setOption({ series: [{ data: solar.d1 }, { data: solar.d2 }, { data: solar.d3 }] });
mychartStorage.setOption({ series: [{ data: storage.d1 }, { data: storage.d2 }, { data: storage.d3 }] });
mychartLoad.setOption({ series: [{ data: load.d1 }, { data: load.d2 }, { data: load.d3 }] });
mychartCharge.setOption({ series: [{ data: charge.d1 }, { data: charge.d2 }, { data: charge.d3 }] });
mychartAlert.setOption({ series: [{ data: solar.d1 }, { data: solar.d2 }, { data: solar.d3 }] });
var xdata = []
for (let i = 6; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
xdata.push(G.formatDateMD(date));
}
updateEchartBar(mychartSolar, xdata, [{ data: solar.d1 }, { data: solar.d2 }, { data: solar.d3 }])
updateEchartBar(mychartStorage, xdata, [{ data: storage.d1 }, { data: storage.d2 }, { data: storage.d3 }])
updateEchartBar(mychartLoad, xdata, [{ data: load.d1 }, { data: load.d2 }, { data: load.d3 }])
updateEchartBar(mychartCharge, xdata, [{ data: charge.d1 }, { data: charge.d2 }, { data: charge.d3 }])
updateEchartBar(mychartAlert, xdata, [{ data: solar.d1 }, { data: solar.d2 }, { data: solar.d3 }])
}))
G.cppNative.getStatisticPowerDay().then(res => {
mychartRunning.setOption({ series: [{ data: res }] })
})
G.cppNative.getStatisticIrradianceDay().then(res => {
mychartRunning.setOption({ series: [{}, { data: res, yAxisIndex: 1 }] })
})
// 查询数据获取环境信息:光照、风速、环境温度、湿度
G.cppNative.getEnvironmentInfo().then(res => {
$('#envIllumination').text(res['illumination'] + ' Lux')
$('#envWindspeed').text(res['windspeed'] + ' m/s')
$('#envTemperture').text(res['temperature'] + ' ℃')
$('#envHumidity').text(res['humidity'] + ' %')
})
}
@@ -139,6 +148,8 @@ document.currentScript.addEventListener('DOMNodeRemoved', () => {
});
$(document).ready(function () {
updatePageData()
// 定时器更新页面数据

View File

@@ -253,15 +253,14 @@
</div>
<div id="deviceAttrPop" class="mask">
<div class="pop" style="height: 500px">
<div id="deviceAttrPopPanel" class="pop" style="height: 500px">
<p id="devicePopTitle" class="pop_title">设备属性设置</p>
<form id="deviceAttrForm" class="was-validated" style="margin: 0 80px 0 80px; padding-top: 30px">
<div class="input-group mb-3"></div>
<div class="input-group mb-3"></div>
</form>
<div style="display: flex; justify-content: center; padding: 20px 20px 20px 20px">
<button id="deviceAttrFormOk" class="btn btn-success" style="width: 90px; margin-right: 20px"
disabled>确定</button>
<button id="deviceAttrFormOk" class="btn btn-success" style="width: 90px; margin-right: 20px">确定</button>
<button class="btn btn-danger" style="width: 90px; margin-left: 20px"
onclick="G.showElement('deviceAttrPop', false)">取消</button>
</div>
@@ -298,7 +297,7 @@
</div>
</form>
<div style="display: flex; justify-content: center; padding: 20px 20px 20px 20px">
<button id="priceFormOk" class="btn btn-success" style="width: 90px; margin-right: 20px" disabled>确定</button>
<button id="priceFormOk" class="btn btn-success" style="width: 90px; margin-right: 20px">确定</button>
<button class="btn btn-danger" style="width: 90px; margin-left: 20px"
onclick="G.showElement('pricePop', false)">取消</button>
</div>

View File

@@ -254,23 +254,18 @@ async function initSubpage(id) {
})
})
}
else if (id == 'role') {
}
else if (id == 'role') { }
else if (id == 'price') {
var elementSelectPriceType = document.getElementById('priceForm_type')
elementSelectPriceType.innerHTML = ''
await G.cppNative.queryPriceTypeList().then(res => {
res.forEach(item => {
elementSelectPriceType.options.add(new Option(item.name, item.id))
})
G.cppNative.queryPriceTypeList().then(res => {
res.forEach(item => { elementSelectPriceType.options.add(new Option(item.name, item.id)) })
})
}
else if (id == 'policy') {
var elementSelectPolicyType = document.getElementById('policyForm_type')
elementSelectPolicyType.innerHTML = ''
for (var k in policyTypeDef) {
elementSelectPolicyType.options.add(new Option(policyTypeDef[k], k))
}
for (var k in policyTypeDef) { elementSelectPolicyType.options.add(new Option(policyTypeDef[k], k)) }
}
var tableInfo = tableDef[id]
@@ -280,8 +275,11 @@ async function initSubpage(id) {
return
}
// 初始化表格
G.initTable(id, tableInfo)
// 初始化弹窗Form
G.initForm(id, popConfirm)
if (id == 'device') { G.initForm("deviceAttr", popConfirm) }
// 绑定行编辑
tableInfo.table.on('click', '#btnRowEdit', function () {
@@ -310,50 +308,67 @@ function showPop(id, rowData) {
// 设置弹框的参数信息
G.popSetParams(id, tableInfo.popkeys, popRowdata, callbackPopSetParams)
if (id == 'user') {
G.popSetParamReadonly('user', 'account', isEdit)
}
if (id == 'user') { G.popSetParamReadonly('user', 'account', isEdit) }
}
var deviceAttrKeyDef = {
commType: "通讯方式",
ip: "通讯地址",
port: "通讯端口",
isclient: "客户端",
}
var deviceAttrKeyDef = { commType: "通讯方式", ip: "通讯地址", port: "通讯端口", isclient: "客户端" }
// 显示设备的属性编辑弹窗属性字段格式为JSON: attrs="{}"
function showPopDeviceAttr(rowData) {
G.showElement('deviceAttrPop', true)
popRowdata = (rowData && rowData.length > 0) ? rowData : null
var device_id = rowData[0]
var deviceType = rowData[1]
var deviceTypeStr = deviceTypeDef[deviceType]
var attrsStr = rowData[9]
var attrs = { commType: "", ip: "", port: 0, isclient: 1 }
try {
attrs = JSON.parse(attrsStr);
} catch (error) {
}
var attrs = {}
try { attrs = JSON.parse(attrsStr); } catch (error) { attrs = {} }
if (Object.keys(attrs).length == 0) { attrs = { commType: "", ip: "", port: 0, isclient: 1 } }
var elemtForm = document.getElementById('deviceAttrForm')
elemtForm.innerHTML =
`<div class="input-group mb-3">
<span class="input-group-text" style="width: 90px; background-color: #a6c0da">编号</span>
<span class="input-group-text" style="width: 90px; background-color: #a6c0da">ID</span>
<input type="text" class="form-control" value='${device_id}' disabled />
</div>
<div class="input-group mb-3">
<span class="input-group-text" style="width: 90px; background-color: #a6c0da">设备类型</span>
<input type="text" class="form-control" value='${deviceTypeStr}' disabled />
</div>`
</div>
`
for (k in attrs) {
var title = deviceAttrKeyDef[k]
elemtForm.innerHTML += `<div class="input-group mb-3">
<span class="input-group-text" style="width: 90px; background-color: #a6c0da">${title}</span>
<input type="text" class="form-control" value='${attrs[k]}' />
</div>`
}
}
var v = attrs[k]
if (k == "commType") {
var optionStr = ('<option ' + (v == "TCP" ? 'selected ' : '') + 'value="TCP">TCP</option>')
+ ('<option ' + (v == "MODBUS" ? 'selected ' : '') + 'value="MODBUS">MODBUS</option>')
+ ('<option ' + (v == "SDK" ? 'selected ' : '') + 'value="SDK">SDK</option>')
+ ('<option ' + (v == "ACTIVEX" ? 'selected ' : '') + 'value="ACTIVEX">ACTIVEX</option>')
elemtForm.innerHTML +=
`<div class="input-group mb-3">
<span class="input-group-text" style="width: 90px; background-color: #a6c0da">${title}</span>
<select id="${k}" class="form-select" required>
${optionStr}
</select>
</div>
`
} else {
elemtForm.innerHTML +=
`<div class="input-group mb-3">
<span class="input-group-text" style="width: 90px; background-color: #a6c0da">${title}</span>
<input id="${k}" type="text" class="form-control" value='${v}' />
</div>
`
}
}
G.cppNative.log(elemtForm.innerHTML);
}
function showPrompt(text, status) {
G.showElement('promptPop', true)
@@ -404,9 +419,7 @@ function callbackPopGetParams(id, key) {
val = []
var elemtFormPermission = document.getElementById('roleForm_permission')
var elemtPermissionList = elemtFormPermission.querySelectorAll('input')
elemtPermissionList.forEach((elemt => {
val.push({ permission_id: elemt.value, is_open: (elemt.checked ? 1 : 0) })
}))
elemtPermissionList.forEach((elemt => { val.push({ permission_id: elemt.value, is_open: (elemt.checked ? 1 : 0) }) }))
}
return val
}
@@ -417,13 +430,36 @@ function updateTableData(id) {
if (!queryFunc) return
queryFunc(1, 10).then((res) => {
})
}
// 用户弹窗确认
function popConfirm(id) {
// 设备属性弹窗: 读取属性配置
if (id == "deviceAttr") {
/// 选择所有表单元素(input, select, textarea) $('#parentElement :input')
/// :input 是jQuery特有的选择器可以匹配所有input、select、textarea和button元素。
/// 同时选择input和select元素 $('#parentElement input, #parentElement select')
var param = {}
$("#deviceAttrForm :input").each(function () {
var id = $(this).attr('id'); // 获取id属性
var val = $(this).val(); // 获取value值
if ((id == "port" || id == "isclient")) { param[id] = parseInt(val) }
else if (id == "commType") { }
else if (id) { param[id] = val }
});
G.cppNative.log(JSON.stringify(param))
// 存储更新数据
G.cppNative.log("rowdata: " + JSON.stringify(popRowdata))
var dataId = popRowdata[0]
G.cppNative.updateDevice(dataId, { attrs: JSON.stringify(param) }).then(ret => {
G.showElement('deviceAttrPop', false)
showPrompt((ret == 0 ? '操作成功!' : '操作失败!'), ret)
})
return;
}
// 获取数据表格操作对象
var mytable = $('#' + id + 'Table').DataTable()
// 获取弹框的参数信息
@@ -471,6 +507,5 @@ for (k in deviceTypeDef) {
$(document).ready(function () {
initSubpage('user')
//G.initTable('user', tableDef['user'])
})

View File

@@ -6,6 +6,8 @@
onclick="initSubPage('storage')">储能设备运行分析</button>
<button id="chargeBtn" class="btn btn-primary" style="width: 200px;margin-left: 10px"
onclick="initSubPage('charge')">充电设备运行分析</button>
<input id="statisticDate" type="date" class="form-control" style="width: 240px; margin-left: 30px;">
</div>
<hr style="margin: 10px 0 10px 0;" />
<!-- <div

View File

@@ -2,80 +2,48 @@
var pageDef = {
solar: {
charts: [
{ id: 'solarEchart1', echart: null, type: 'bar', series: ['发电电量', '入网电量'] },
{ id: 'solarEchart2', echart: null, type: 'bar', series: ['发电时长', '故障次数'] },
{ id: 'solarEchart3', echart: null, type: 'line', series: ['日电压', '日电流'] },
{ id: 'solarEchart4', echart: null, type: 'line', series: ['日功率'] }
{ id: 'solarEchart1', echart: null, type: 'bar', series: ['发电电量', '入网电量'], yAxisLeft: "电量kWh", yAxisRight: "" },
{ id: 'solarEchart2', echart: null, type: 'bar', series: ['发电时长', '故障次数'], yAxisLeft: "时长s", yAxisRight: "次数" },
{ id: 'solarEchart3', echart: null, type: 'line', series: ['日电压', '日电流'], yAxisLeft: "电压V", yAxisRight: "电流A" },
{ id: 'solarEchart4', echart: null, type: 'line', series: ['日功率'], yAxisLeft: "功率kw" },
],
},
storage: {
charts: [
{ id: 'storageEchart1', echart: null, type: 'bar', series: ['储能电量', '放电电量'] },
{ id: 'storageEchart2', echart: null, type: 'bar', series: ['储能时长', '放电时长', '故障次数'] },
{ id: 'storageEchart3', echart: null, type: 'line', series: ['日电压', '日电流'] },
{ id: 'storageEchart4', echart: null, type: 'line', series: ['日功率'] }
{ id: 'storageEchart1', echart: null, type: 'bar', series: ['储能电量', '放电电量'], yAxisLeft: "电量kWh" },
{ id: 'storageEchart2', echart: null, type: 'bar', series: ['储能时长', '放电时长', '故障次数'], yAxisLeft: "时长s" },
{ id: 'storageEchart3', echart: null, type: 'line', series: ['日电压', '日电流'], yAxisLeft: "电压V" },
{ id: 'storageEchart4', echart: null, type: 'line', series: ['日功率'], yAxisLeft: "功率kw" }
],
},
charge: {
charts: [
{ id: 'chargeEchart1', echart: null, type: 'bar', series: ['充电电量', '充电收益'] },
{ id: 'chargeEchart2', echart: null, type: 'bar', series: ['充电次数', '充电时长', '故障次数'] },
{ id: 'chargeEchart3', echart: null, type: 'line', series: ['日电压', '日电流'] },
{ id: 'chargeEchart4', echart: null, type: 'line', series: ['日功率'] }
{ id: 'chargeEchart1', echart: null, type: 'bar', series: ['充电电量', '充电收益'], yAxisLeft: "电量kWh" },
{ id: 'chargeEchart2', echart: null, type: 'bar', series: ['充电次数', '充电时长', '故障次数'], yAxisLeft: '次数' },
{ id: 'chargeEchart3', echart: null, type: 'line', series: ['日电压', '日电流'], yAxisLeft: "电压V" },
{ id: 'chargeEchart4', echart: null, type: 'line', series: ['日功率'], yAxisLeft: "功率kw" }
],
}
}
var xdataBar = ['2025/3/1', '2025/3/2', '2025/3/3', '2025/3/4', '2025/3/5', '2025/3/6', '2025/3/7']
var ydataBar = [
[30, 28, 35, 18, 36, 27, 19],
[10, 32, 20, 33, 39, 13, 22],
]
var curActiveId = 'solar'
function getRandomCurveData(m, n) {
var data = []
var t0 = Date.parse('2025-03-01 00:00:00')
var step = 600
var N = 86400 / step
var y = 500;
for (var i = 0; i < N; ++i) {
// data[i] = { x: t0 + i * step * 1000, y: Math.sin(i * 0.1) * (n - m) }
y = Math.floor((y + RAND(0, 50) - 25) * 100) / 100
data[i] = { x: t0 + i * step * 1000, y: y }
}
return data
}
function getCurveData(a, b, n) {
var d = [[], []]
for (var i = 0; i < n; ++i) {
var v = RAND(a, b)
d[0].push(v)
d[1].push(v - RAND(50, 200))
}
return d
}
function RAND(a, b) {
return a + Math.random() * (b - a)
}
var activeModuleId = ''
// 点击子页面菜单按钮,切换子页面
function initSubPage(id) {
//if (curActiveId == id) return
//if (activeModuleId == id) return
// 切换子菜单按钮样式,旧选择按钮恢复样式
if (curActiveId && curActiveId != '') {
document.getElementById(curActiveId + 'Btn').className = 'btn btn-primary'
if (activeModuleId && activeModuleId != '') {
document.getElementById(activeModuleId + 'Btn').className = 'btn btn-primary'
// 隐藏旧菜单对应的表格子页面
$('#' + curActiveId).hide()
$('#' + activeModuleId).hide()
}
curActiveId = id
activeModuleId = id
// 切换子菜单按钮样式,新选择按钮设置样式
document.getElementById(curActiveId + 'Btn').className = 'btn btn-success btn-lg'
document.getElementById(activeModuleId + 'Btn').className = 'btn btn-success btn-lg'
// 显示新菜单对应的表格子页面
$('#' + curActiveId).show()
$('#' + activeModuleId).show()
var page = pageDef[id]
if (!page) {
@@ -83,46 +51,131 @@ function initSubPage(id) {
return
}
// 更新曲线数据
G.cppNative.getCurveDataDay(200, 300).then(res => {
updateEchartCurve(pageDef[activeModuleId].charts[2].echart, 0, res)
})
G.cppNative.getCurveDataDay(100, 300).then(res => {
updateEchartCurve(pageDef[activeModuleId].charts[2].echart, 1, res)
})
G.cppNative.getCurveDataDay(300, 400).then(res => {
updateEchartCurve(pageDef[activeModuleId].charts[3].echart, 0, res)
})
// 柱状图的 x 轴, 7天的时间的日期
var dateStr = $('#statisticDate').val()
var xdata = []
for (let i = 6; i >= 0; i--) {
const date = new Date(dateStr);
date.setDate(date.getDate() - i);
xdata.push(G.formatDateMD(date));
}
page.charts.forEach(item => {
if (item.type == 'bar') {
item.echart = initEchartBar(item.id, item.series)
item.echart = initEchartBar(item.id, item.series, xdata, item.yAxisLeft, item.yAxisRight)
for (var i = 0; i < item.series.length; ++i) {
//updateEchartBar(item.echart, i, xdataBar, ydataBar[i])
}
} else if (item.type == 'line') {
item.echart = initEchartCurve(item.id, item.series)
item.echart = initEchartCurve(item.id, item.series, item.yAxisLeft, item.yAxisRight)
for (var i = 0; i < item.series.length; ++i) {
updateEchartCurve(item.echart, i, G.getRandDataDay(100 * (i + 1), 200 * (i + 1)))
}
}
if (id == 'solar') {
if (item.id == 'solarEchart1') {
var d = getCurveData(400, 500, 7)
updateEchartBar(item.echart, 0, xdataBar, d[0])
updateEchartBar(item.echart, 1, xdataBar, d[1])
} else if (item.id == 'solarEchart2') {
var d = getCurveData(480, 780, 7)
updateEchartBar(item.echart, 0, xdataBar, d[0])
updateEchartBar(item.echart, 1, xdataBar, [0, 2, 0, 0, 3, 0, 1])
}
} else if (id == 'storage') {
} else if (id == 'charge') {
}
});
}
window.onresize = () => {
var page = pageDef[curActiveId]
charts.charts.forEach(item => {
if (item.echart) { item.echart.resize() }
})
// 更新页面数据
function updatePageData() {
// 柱状图的 x 轴, 7天的时间的日期
var dateStr = $('#statisticDate').val()
var xdata = []
for (let i = 6; i >= 0; i--) {
const date = new Date(dateStr);
date.setDate(date.getDate() - i);
xdata.push(G.formatDateMD(date));
}
// 光伏统计
if (activeModuleId == "solar") {
G.cppNative.getStatisticDay(7).then(res => {
var d1 = [], d2 = [], d3 = [], d4 = [], d5 = []
res.forEach(item => {
d1.push(item['elect_gen'])
d2.push(item['elect_in'])
d3.push(item['elect_gen_t'])
d4.push(item['num_fault_solar'])
})
// 发电电量、入网电量
updateEchartBar(pageDef.solar.charts[0].echart, xdata, [{ data: d1 }, { data: d2 }]);
// 发电时长、故障次数
updateEchartBar(pageDef.solar.charts[1].echart, xdata, [{ data: d3 }, { data: d4 }]);
})
}
// 储能统计
else if (activeModuleId == "storage") {
G.cppNative.getStatisticDay(7).then(res => {
var d1 = [], d2 = [], d3 = [], d4 = [], d5 = []
res.forEach(item => {
d1.push(item['elect_store'])
d2.push(item['elect_discharge'])
d3.push(item['elect_store_t'])
d4.push(item['elect_discharge_t'])
d5.push(item['num_fault_store'])
})
// 储能电量、放电电量
updateEchartBar(pageDef.storage.charts[0].echart, xdata, [{ data: d1 }, { data: d2 }]);
// 储能时长、放电时长、故障次数
updateEchartBar(pageDef.storage.charts[1].echart, xdata, [{ data: d3 }, { data: d4 }, { data: d5 }]);
})
}
// 充电统计
else if (activeModuleId == "charge") {
G.cppNative.getStatisticDay(7).then(res => {
var d1 = [], d2 = [], d3 = [], d4 = [], d5 = []
res.forEach(item => {
d1.push(item['elect_charge'])
d2.push(item['income_charge'])
d3.push(item['num_charge'])
d4.push(item['elect_charge_t'])
d5.push(item['num_fault_charge'])
})
// 充电电量、充电收益
updateEchartBar(pageDef.charge.charts[0].echart, xdata, [{ data: d1 }, { data: d2 }]);
// 充电次数、充电时长、故障次数
updateEchartBar(pageDef.charge.charts[1].echart, xdata, [{ data: d3 }, { data: d4 }, { data: d5 }]);
})
}
}
window.onresize = () => {
var page = pageDef[activeModuleId]
page.charts.forEach(item => { if (item.echart) { item.echart.resize() } })
}
/// 清理资源
var timerId = null
document.currentScript.addEventListener('DOMNodeRemoved', () => {
G.cppNative.log('DOMNodeRemoved: 统计分析')
clearInterval(timerId);
});
$(document).ready(function () {
var dateStr = new Date().toLocaleString('zh', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\//g, '-')
$('#statisticDate').val(dateStr)
document.getElementById('statisticDate').addEventListener('input', function (e) {
// updatePageData()
});
initSubPage("solar")
updatePageData()
// 定时器更新页面数据
timerId = setInterval(updatePageData, 1000)
})

View File

@@ -86,8 +86,8 @@
<div class="myrow"
style="font-size: 14px; font-weight: 600; justify-content: space-between; border: solid #00fffb; border-radius: 0 0 8px 8px; border-width: 0 1px 1px 1px; height: 40px; line-height: 40px;">
<div style="width: 33%; text-align: center;">#1</div>
<div style="width: 33%; text-align: center;">20℃</div>
<div style="width: 33%; text-align: center;">20%</div>
<div id="envTemperture" style="width: 33%; text-align: center;">20℃</div>
<div id="envHumidity" style="width: 33%; text-align: center;">20%</div>
</div>
</div>
@@ -142,12 +142,69 @@
<div id="deviceSettingPop" class="mask" style="display: none;">
<div
style="margin: 200px auto;width:800px; padding: 20px; height: 500px; background-color: #012036f0; border:4px solid #14dcfb; ">
style="margin: 200px auto; padding: 20px; width:550px; height: 380px; background-color: #012036f0; border:4px solid #14dcfb; ">
<div id="popDeviceInfo" style="height: 30px;"></div>
<div class="myline-b" style="color:white;">控制功能</div>
<div style="display: flex; justify-content: center; width: 100%; margin-top: 100px;">
<div class="myrow" style="height: 26px; margin-top:30px;">
<div style="width: 120px;">开关机控制</div>
<div class="btn-group" style="width:80px;">
<input id="deviceSwitch_on" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('deviceSwitch_on', 'deviceSwitch_off', this.checked)" />
<label class="btn btn-outline-primary" for="deviceSwitch_on" style="padding: 0;"></label>
<input id="deviceSwitch_off" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('deviceSwitch_on', 'deviceSwitch_off', !this.checked)" checked />
<label class="btn btn-outline-danger" for="deviceSwitch_off" style="padding: 0;"></label>
</div>
</div>
<div class="myrow" style="height: 26px; margin-top:16px;">
<div style="width: 120px;">功率调控</div>
<div class="btn-group" style="width:80px;">
<input id="powerCtrl_on" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('powerCtrl_on', 'powerCtrl_off', this.checked)" />
<label class="btn btn-outline-primary" for="powerCtrl_on" style="padding: 0;"></label>
<input id="powerCtrl_off" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('powerCtrl_on', 'powerCtrl_off', !this.checked)" checked />
<label class="btn btn-outline-danger" for="powerCtrl_off" style="padding: 0;"></label>
</div>
<div style="margin-left:60px; width: 90px;">调控策略</div>
<select class="form-select" aria-label="选择策略"
style="width: 100px; padding: 0 0 0 10px; background-color: #0c283b; color: white;">
<option value="0">策略1</option>
<option value="1">策略2</option>
<option value="2">策略3</option>
<option value="3">策略4</option>
</select>
</div>
<div class="myrow" style="height: 26px; margin-top:16px;">
<div style="width: 120px;">充放电模式控制</div>
<div class="btn-group" style="width:80px;">
<input id="chargeMode_on" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('chargeMode_on', 'chargeMode_off', this.checked)" />
<label class="btn btn-outline-primary" for="chargeMode_on" style="padding: 0;"></label>
<input id="chargeMode_off" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('chargeMode_on', 'chargeMode_off', !this.checked)" checked />
<label class="btn btn-outline-danger" for="chargeMode_off" style="padding: 0;"></label>
</div>
</div>
<div class="myrow" style="height: 26px; margin-top:16px;">
<div style="width: 120px;">并离网模式控制</div>
<div class="btn-group" style="width:80px;">
<input id="workMode_on" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('workMode_on', 'workMode_off', this.checked)" />
<label class="btn btn-outline-primary" for="workMode_on" style="padding: 0;"></label>
<input id="workMode_off" type="checkbox" class="btn-check" autocomplete="off"
onclick="G.switchSetStatus('workMode_on', 'workMode_off', !this.checked)" checked />
<label class="btn btn-outline-danger" for="workMode_off" style="padding: 0;"></label>
</div>
</div>
<div style="display: flex; justify-content: flex-end; width: 100%; margin-top: 50px; ">
<button class="btn btn-success" style="width:80px; color: white;"
onclick="G.showElement('deviceSettingPop', false)">确定</button>
<button class="btn btn-default" style="width:80px; color: white; margin-left: 50px;"
<button class="btn btn-default" style="width:80px; color: white; margin-left: 20px;"
onclick="G.showElement('deviceSettingPop', false)">取消</button>
</div>
</div>

View File

@@ -113,14 +113,14 @@ function setDeviceCardParam(deviceid, subid, key, text) {
}
var activeCardBtn = null
var activeModuleId = null
function onClickCardBtn(btn, id) {
if (activeCardBtn) activeCardBtn.className = 'mycardbtn'
activeCardBtn = btn
activeCardBtn.className = 'mycardbtn-active'
var deviceType = id
initDeviceList(deviceType)
activeModuleId = id
initDeviceList(activeModuleId)
}
function creatElementSwitch(id, x, y) {
@@ -223,19 +223,46 @@ function initDeviceList(deviceType) {
})
}
var elemtPanel = document.getElementById(item.device_id)
elemtPanel.innerHTML += `<button
class="btn btn-outline-primary btn-sm"
style="height:30px; margin: 5px 0 0 10px"
onclick="onDeviceSetting(${item.device_id})">
//JSON.stringify(item)
var paramStr = JSON.stringify(item).replace(/"/g, '"')
elemtPanel.innerHTML += `<button
class="btn btn-outline-primary btn-sm"
style="height:30px; margin: 5px 0 0 10px"
onclick='onDeviceSetting(${paramStr})'>
参数设置
</button>`
})
})
}
function onDeviceSetting(deviceid) {
function onDeviceSetting(param) {
var deviceType = getDeviceTypeName(param.type)
$('#popDeviceInfo').text(param.device_id + ":" + deviceType + ":" + param.name)
G.showElement('deviceSettingPop', true)
if (deviceType == "逆变器") {
}
}
function updatePageData() {
if (activeModuleId == "security") {
// 查询数据获取环境信息:光照、风速、环境温度、湿度
G.cppNative.getEnvironmentInfo().then(res => {
// $('#envIllumination').text(res['illumination'] + ' Lux')
// $('#envWindspeed').text(res['windspeed'] + ' m/s')
$('#envTemperture').text(res['temperature'] + '℃')
$('#envHumidity').text(res['humidity'] + '%')
})
// 消防信息
G.cppNative.getFireInfo().then(res => {
//res.data.forEach(item => { })
})
}
}
// ====================================================================================================
@@ -252,9 +279,6 @@ document.currentScript.addEventListener('DOMNodeRemoved', () => {
$(document).ready(function () {
onClickCardBtn(document.getElementById('solarCardBtn'), 'solar')
// timerId = setInterval(() => {
// updateParam('1', '电压', Math.floor(Math.random() * 220) + ' V')
// }, 2000);
G.cppNative.getDeviceInfo([0]).then((res) => {
var nums = {
@@ -271,6 +295,7 @@ $(document).ready(function () {
if (item.err != 0) nums[deviceType].numFault += 1
}
})
$('#solarDeviceNum').text('光伏板数量: ' + nums['103'].num + ' 个')
$('#solarIdleNum').text('空闲: ' + nums['103'].numIdle + ' 个')
$('#solarOfflineNum').text('离线: ' + nums['103'].numOffline + ' 个')
@@ -285,7 +310,8 @@ $(document).ready(function () {
$('#chargeIdleNum').text('空闲: ' + nums['108'].numIdle + ' 个')
$('#chargeOfflineNum').text('离线: ' + nums['108'].numOffline + ' 个')
$('#chargeFaultNum').text('故障: ' + nums['108'].numFault + ' 个')
})
// 定时更新页面数据
timerId = setInterval(updatePageData, 1000);
})

View File

@@ -4,42 +4,25 @@ var chartDef = [
{ id: 'loadEchart', echart: null, type: 'line', series: ['预测功率', '实时功率'] },
]
function RAND(a, b) {
return (a + Math.random() * (b - a))
}
function getRandomCurveData(m, n) {
var data = []
var t0 = Date.parse('2025-03-01 00:00:00')
var step = 600
var N = 86400 / step
for (var i = 0; i < N; ++i) {
//data[i] = { x: t0 + i * step * 1000, y: Math.sin(i * 0.1) * (n - m) }
data[i] = { x: t0 + i * step * 1000, y: RAND(m, n) }
}
return data
}
function getRandomData1(m, n) {
var data = []
var t0 = Date.parse('2025-03-01 00:00:00')
var t0 = Date.parse('2025-07-01 00:00:00')
var step = 600
var N = 86400 / step
var y = 500;
for (var i = 0; i < N; ++i) {
//data[i] = { x: t0 + i * step * 1000, y: Math.sin(i * 0.1) * (n - m) }
y = Math.floor((y + RAND(0, 50) - 25) * 100) / 100
data[i] = { x: t0 + i * step * 1000, y: y }
var x = t0 + i * step * 1000
y = Math.floor((y + RAND(0, 20) - 10) * 100) / 100
data[i] = { name: x, value: [x, y] }
}
return data
}
chartDef.forEach((item) => {
item.echart = initEchartCurve(item.id, item.series)
updateEchartCurve(item.echart, 1, getRandomData1(100, 200))
item.echart = initEchartCurve(item.id, item.series, item.yAxisLeft, item.yAxisRight)
updateEchartCurve(item.echart, 1, getRandomCurveData(100, 200))
for (var i = 0; i < item.series.length; ++i) {
updateEchartCurve(item.echart, i, getRandomData1(300 * (i + 1), 400 * (i + 1)))
updateEchartCurve(item.echart, i, getRandomCurveData(300 * (i + 1), 400 * (i + 1)))
}
})