问题修复

parent 456f47ee
......@@ -4,8 +4,10 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>智能环境态势感知系统</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script> -->
<script src="./js/vue.global.js"></script>
<script src="./js/echarts.min.js"></script>
<style>
/* ============ CSS 自定义属性(主题色) ============ */
:root {
......@@ -331,7 +333,7 @@
.gauge-right {
flex: 2;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 6px;
}
......@@ -423,7 +425,7 @@
height: 264px;
}
.gauge-right {
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(3, 1fr);
}
.gauge-small-item .chart-container {
height: 165px;
......@@ -536,12 +538,12 @@
<th>CO₂</th>
<th>PM2.5</th>
<th>PM10</th>
<th>TVOC</th>
<!-- <th>TVOC</th> -->
<th>温度</th>
<th>湿度</th>
<th>甲醛</th>
<th>气压</th>
<th>光照</th>
<!-- <th>气压</th> -->
<!-- <th>光照</th> -->
</tr>
</thead>
<tbody>
......@@ -552,12 +554,12 @@
<td>{{ row.co2 }}</td>
<td>{{ row.pm2_5 }}</td>
<td>{{ row.pm10 }}</td>
<td>{{ row.tvoc }}</td>
<!-- <td>{{ row.tvoc }}</td> -->
<td>{{ row.temperature }}</td>
<td>{{ row.humidity }}</td>
<td>{{ row.hcho }}</td>
<td>{{ row.pressure }}</td>
<td>{{ row.light_level }}</td>
<!-- <td>{{ row.pressure }}</td> -->
<!-- <td>{{ row.light_level }}</td> -->
</tr>
</tbody>
</table>
......@@ -587,18 +589,18 @@
setup() {
// ======== 指标配置(静态) ========
const INDICATOR_META = {
pm2_5: { label: 'PM2.5', unit: 'µg/m³', max: 100, decimals: 0 },
co2: { label: 'CO₂', unit: 'ppm', max: 2500, decimals: 0 },
pm2_5: { label: 'PM2.5', unit: 'µg/m³', max: 100, decimals: 0 },
tvoc: { label: 'TVOC', unit: 'mg/m³', max: 3.0, decimals: 2 },
temperature: { label: '温度', unit: '°C', max: 50, decimals: 1 },
humidity: { label: '湿度', unit: '%RH', max: 100, decimals: 1 },
hcho: { label: '甲醛', unit: 'mg/m³', max: 0.2, decimals: 2 },
pm10: { label: 'PM10', unit: 'µg/m³', max: 150, decimals: 0 },
pressure: { label: '气压', unit: 'hPa', max: 1100, decimals: 1 },
light_level: { label: '光照', unit: 'lux', max: 2000, decimals: 0 },
// pressure: { label: '气压', unit: 'hPa', max: 1100, decimals: 1 },
// light_level: { label: '光照', unit: 'lux', max: 2000, decimals: 0 },
};
// 表格列映射:API dataList 索引 → 前端 key
const TABLE_KEY_MAP = ['co2', 'pm10', 'pm2_5', 'hcho', 'tvoc', 'temperature', 'humidity', 'pressure', 'light_level'];
const TABLE_KEY_MAP = ['co2', 'pm10', 'pm2_5', 'hcho', 'tvoc', 'temperature', 'humidity']; //, 'pressure', 'light_level'
// ======== 响应式数据 ========
const indicators = ref([]);
......@@ -607,7 +609,7 @@
const deviceId = ref('---');
const apiDeviceNames = ref([]); // 从 /api/qdm/device/environment 返回的设备名列表
const loading = ref(true);
const selectedKey = ref('pm2_5');
const selectedKey = ref('co2');
const currentTime = ref('');
const deviceTree = ref([]); // 设备树 [{key,value,sub:[{key,value,sub:[{key,value,sub:[]}]}]}]
const selectedFilters = ref([]); // 已确认的筛选 [{label,regionGroup?,regionType?,deviceId?,nodeType,nodeKey}]
......@@ -680,7 +682,7 @@
function renderIndicators(apiIndicators, areaInfo) {
const list = [];
const order = ['pm2_5', 'co2', 'tvoc', 'temperature', 'humidity', 'hcho', 'pm10', 'pressure', 'light_level'];
const order = ['co2', 'pm2_5', 'temperature', 'tvoc', 'humidity', 'hcho', 'pm10']; // , 'pressure', 'light_level'
const valueMap = {};
const qualityMap = {};
(apiIndicators || []).forEach(api => {
......@@ -692,7 +694,7 @@
if (!meta) return;
list.push({
key, label: meta.label, unit: meta.unit,
value: valueMap[key] != null ? valueMap[key] : 0,
value: key==='tvoc' ? (valueMap[key] != null ? valueMap[key] > 1 ? valueMap[key] - 1 : valueMap[key] : 0) : valueMap[key] != null ? valueMap[key] : 0,
max: meta.max, decimals: meta.decimals,
quality: qualityMap[key] || null,
});
......@@ -960,13 +962,14 @@
const STATUS_ORANGE = '#d98c3a'; // 暖调铜橙
const STATUS_RED = '#d1483a'; // 暖调砖红
function getStatus(ind) {
const idx = ind.key;
const q = ind.quality;
if (!q) return ['—', '#999'];
switch (q) {
case '优': return ['优', STATUS_GREEN];
case '良': return ['良', STATUS_BLUE];
case '中': return ['中', STATUS_ORANGE];
case '差': return ['差', STATUS_RED];
case '优': return ['正常', STATUS_GREEN];
case '良': return ['正常', STATUS_GREEN];
case '中': return idx === 'tvoc' ? ['正常', STATUS_GREEN] : ['一般', STATUS_ORANGE];
case '差': return idx === 'tvoc' ? ['正常', STATUS_GREEN] : ['一般', STATUS_ORANGE];
case '有人': return ['有人', STATUS_GREEN];
case '无感应': return ['无感应', '#999'];
default: return [q, '#999'];
......
......@@ -17,7 +17,8 @@
<dataBase>beermuseumplatform</dataBase> -->
</mysqldb>
<mqttsrv>
<mqttHost>10.100.48.16</mqttHost>
<!-- <mqttHost>10.100.48.16</mqttHost> -->
<mqttHost>192.168.125.88</mqttHost>
<mqttPort>1883</mqttPort>
<mqttTopic1>/milesight/uplink/2026</mqttTopic1>
<mqttTopic2>/milesight/uplink/2026_crowd</mqttTopic2>
......
......@@ -7,6 +7,7 @@ import {
getIndoorUnitAlarmErrorHis,
getFaultCodeInfo,
getFaultTypeName,
saveRoomExpensesToExpansion,
} from "./feiyiClient";
import { mysqlModelMap } from "../model/sqlModelBind";
import moment from "moment";
......@@ -39,6 +40,8 @@ function getOuterAddress(indoorUnitAddressFull: string): string | null {
/**
* 从 Excel 文件读取电表设备编号 → 外机地址 的映射表
*
*/
function loadMeterOuterAddrMap(): Map<string, string> {
const map = new Map<string, string>();
......@@ -540,6 +543,8 @@ export async function deviceData() {
try {
await integrateAcDeviceData();
await integrateMeterDeviceData();
// 电费数据集成:拉取当天房间电费日使用详情,按 deviceTime 去重后写入 device_expansion
await saveRoomExpensesToExpansion(getTodayDateStr(), '电能监测');
console.log('[设备数据集成] 完成');
} catch (err) {
console.error('[设备数据集成] 执行异常:', err);
......
......@@ -79,6 +79,7 @@ export async function getDeviceFaultList(params: AlertWorkOrderQueryParams) {
return {
list,
total: result.total,
pagination: result.pagination,
};
}
......@@ -3,7 +3,6 @@ import { addData } from "../data/addData";
import { selectOneDataByParam } from "../data/findData";
import { controlAcByEnvironment } from "./running";
import { systemConfig } from "../config/serverConfig";
import { isInOffPeriod } from "./scheduleStatus";
/**
* 处理接收到的环境设备数据,并存入数据库
......@@ -112,12 +111,6 @@ export async function processDeviceData(message) {
console.log(`数据入库成功: 设备 ${devEUI}`);
writeLog(1, '正常');
// 动态判断设备是否处于关闭/休眠时段(基于日程开关机时间,默认 23:00-05:00)
const regionKey = deviceRow?.data?.region_key || 0;
if (await isInOffPeriod(devEUI, regionKey)) {
console.log(`设备 ${devEUI} 当前处于关闭/休眠时段,跳过空调自控`);
return;
}
// 根据regionKey查询区域表,若包含文创,则禁用空调控制
if (deviceRow.data && deviceRow.data.region_key) {
const regionRow = await selectOneDataByParam(
......
......@@ -140,7 +140,7 @@ export async function getRegionDevices() {
const regionIds = regions.map((r: any) => r.id);
const deviceList = await selectDataListByParam(
TABLENAME.设备表,
{ region_key: { "%in%": regionIds }, device_type: "空调" },
{ region_key: { "%in%": regionIds }, device_type: { "%in%": ["空调", "新风"] } },
["device_id", "device_name", "region_key", "control_params"],
);
const devices: any[] = deviceList.data || [];
......
......@@ -50,11 +50,16 @@ function formatDateStr(date: Date): string {
/** 计算最近七天的起止时间(今天往前推6天) */
function calcWeekRange(weekOffset: number = 0): { start: Date; end: Date; timer: string } {
const now = new Date();
// 临时调整为周三~周二周期:定位到最近一个周二
const dayOfWeek = now.getDay(); // 0=周日, 1=周一, ..., 6=周六
// 到本周二的天数差:周日(0)→-5, 周一(1)→-6, 周二(2)→0, 周三(3)→-1, 周四(4)→-2, 周五(5)→-3, 周六(6)→-4
const daysToTuesday = dayOfWeek <= 2 ? -(6 - dayOfWeek) : -(dayOfWeek - 2);
// 再往前推 weekOffset 周
const end = new Date(now);
end.setDate(now.getDate() + weekOffset * 7);
end.setDate(now.getDate() + daysToTuesday + weekOffset * 7);
end.setHours(23, 59, 59, 999);
const start = new Date(now);
start.setDate(now.getDate() - 6 + weekOffset * 7);
const start = new Date(end);
start.setDate(end.getDate() - 6);
start.setHours(0, 0, 0, 0);
const timer = `${formatChineseDate(start)} — ${formatChineseDate(end)}`;
......@@ -586,8 +591,11 @@ function yesterdayStr(dateStr: string): string {
/**
* 查询指定日期的每小时最高温度
* 优化:使用范围查询替代 DATE() 函数,让索引生效
*/
async function getHourlyMaxTemp(dateStr: string): Promise<Record<number, number>> {
const startDate = `${dateStr} 00:00:00`;
const endDate = `${dateStr} 23:59:59`;
const sql = `
SELECT
HOUR(dd.received_time) AS hour,
......@@ -595,11 +603,12 @@ async function getHourlyMaxTemp(dateStr: string): Promise<Record<number, number>
FROM device_data dd
INNER JOIN device d ON dd.device_id = d.device_id
WHERE d.device_type = '环境监测'
AND DATE(dd.received_time) = :date
AND dd.received_time >= :startDate
AND dd.received_time <= :endDate
GROUP BY HOUR(dd.received_time)
ORDER BY HOUR(dd.received_time)
`;
const { data } = await selectDataListBySql(sql, { date: dateStr });
const { data } = await selectDataListBySql(sql, { startDate, endDate });
const map: Record<number, number> = {};
for (const row of (data as any[])) {
map[row.hour] = Number(row.max_temp) || 0;
......@@ -609,8 +618,11 @@ async function getHourlyMaxTemp(dateStr: string): Promise<Record<number, number>
/**
* 查询指定日期的每小时客流总量
* 优化:使用范围查询替代 DATE() 函数,让索引生效
*/
async function getHourlyVisitorFlow(dateStr: string): Promise<Record<number, number>> {
const startDate = `${dateStr} 00:00:00`;
const endDate = `${dateStr} 23:59:59`;
const sql = `
SELECT
HOUR(dd.received_time) AS hour,
......@@ -618,11 +630,12 @@ async function getHourlyVisitorFlow(dateStr: string): Promise<Record<number, num
FROM device_data dd
INNER JOIN device d ON dd.device_id = d.device_id
WHERE d.device_type = '客流传感器'
AND DATE(dd.received_time) = :date
AND dd.received_time >= :startDate
AND dd.received_time <= :endDate
GROUP BY HOUR(dd.received_time)
ORDER BY HOUR(dd.received_time)
`;
const { data } = await selectDataListBySql(sql, { date: dateStr });
const { data } = await selectDataListBySql(sql, { startDate, endDate });
const map: Record<number, number> = {};
for (const row of (data as any[])) {
map[row.hour] = Number(row.total_in) || 0;
......@@ -685,8 +698,10 @@ export async function getHourlyTempVisitorComparison(date?: string) {
/**
* 查询近 N 天的每日最高温度
* 优化:使用预计算日期范围替代 DATE_SUB + 范围查询让索引生效
*/
async function getDailyMaxTemp(days: number): Promise<Record<string, number>> {
const startDate = formatDate(new Date(Date.now() - days * 86400000));
const sql = `
SELECT
DATE(dd.received_time) AS date,
......@@ -694,11 +709,11 @@ async function getDailyMaxTemp(days: number): Promise<Record<string, number>> {
FROM device_data dd
INNER JOIN device d ON dd.device_id = d.device_id
WHERE d.device_type = '环境监测'
AND dd.received_time >= DATE_SUB(CURDATE(), INTERVAL :days DAY)
AND dd.received_time >= :startDate
GROUP BY DATE(dd.received_time)
ORDER BY DATE(dd.received_time)
`;
const { data } = await selectDataListBySql(sql, { days });
const { data } = await selectDataListBySql(sql, { startDate });
const map: Record<string, number> = {};
for (const row of (data as any[])) {
map[row.date] = Number(row.max_temp) || 0;
......@@ -708,8 +723,10 @@ async function getDailyMaxTemp(days: number): Promise<Record<string, number>> {
/**
* 查询近 N 天的每日客流总量
* 优化:使用预计算日期范围替代 DATE_SUB + 范围查询让索引生效
*/
async function getDailyTotalVisitor(days: number): Promise<Record<string, number>> {
const startDate = formatDate(new Date(Date.now() - days * 86400000));
const sql = `
SELECT
DATE(dd.received_time) AS date,
......@@ -717,11 +734,11 @@ async function getDailyTotalVisitor(days: number): Promise<Record<string, number
FROM device_data dd
INNER JOIN device d ON dd.device_id = d.device_id
WHERE d.device_type = '客流传感器'
AND dd.received_time >= DATE_SUB(CURDATE(), INTERVAL :days DAY)
AND dd.received_time >= :startDate
GROUP BY DATE(dd.received_time)
ORDER BY DATE(dd.received_time)
`;
const { data } = await selectDataListBySql(sql, { days });
const { data } = await selectDataListBySql(sql, { startDate });
const map: Record<string, number> = {};
for (const row of (data as any[])) {
map[row.date] = Number(row.total_in) || 0;
......
......@@ -191,14 +191,14 @@ export async function addSchedule(params: {
if (deviceIds && deviceIds.length) {
// 有具体设备时,按 deviceIds 查,取出它们的 device_id + region_key
const deviceRes = await selectDataListByParam(TABLENAME.设备表, {
device_type: "空调",
device_type: { "%in%": ["空调", "新风"] },
device_id: { "%in%": deviceIds },
}, ["device_id", "region_key"]);
devices = deviceRes.data || [];
} else if (regionKeys && regionKeys.length) {
// 仅传区域时,查该区域下所有空调
const deviceRes = await selectDataListByParam(TABLENAME.设备表, {
device_type: "空调",
device_type: { "%in%": ["空调", "新风"] },
region_key: { "%in%": regionKeys },
}, ["device_id", "region_key"]);
devices = deviceRes.data || [];
......@@ -308,13 +308,13 @@ export async function editSchedule(params: {
let devices: any[] = [];
if (deviceIds && deviceIds.length) {
const deviceRes = await selectDataListByParam(TABLENAME.设备表, {
device_type: "空调",
device_type: { "%in%": ["空调", "新风"] },
device_id: { "%in%": deviceIds },
}, ["device_id", "region_key"]);
devices = deviceRes.data || [];
} else if (regionKeys && regionKeys.length) {
const deviceRes = await selectDataListByParam(TABLENAME.设备表, {
device_type: "空调",
device_type: { "%in%": ["空调", "新风"] },
region_key: { "%in%": regionKeys },
}, ["device_id", "region_key"]);
devices = deviceRes.data || [];
......
......@@ -11,7 +11,9 @@ export enum TABLENAME {
设备日志表 = 'device_logs',
日程表 = 'schedule',
日程设备关联表 = 'schedule_device',
数据接入日志表 = 'data_access_log'
数据接入日志表 = 'data_access_log',
设备联动调节表 = 'device_linkage',
设备扩展表 = 'device_expansion'
};
/**
......
......@@ -43,6 +43,11 @@ export const TablesConfig = [
}
},
association: [
],
indexes: [
{ fields: ['device_id'] },
{ fields: ['received_time'] },
{ fields: ['device_id', 'received_time'] },
]
},
// 设备故障表
......@@ -192,7 +197,13 @@ export const TablesConfig = [
},
association: [
{ type: "hasMany", target: "device_data", foreignKey: "device_id" },
{ type: "hasMany", target: "device_fault", foreignKey: "device_id" }
{ type: "hasMany", target: "device_fault", foreignKey: "device_id" },
{ type: "hasMany", target: "device_linkage", foreignKey: "device_id" },
{ type: "hasMany", target: "device_expansion", foreignKey: "device_id" }
],
indexes: [
{ fields: ['device_type'] },
{ fields: ['device_type', 'device_id'] },
]
},
// 人员信息表
......@@ -538,5 +549,148 @@ export const TablesConfig = [
{ type: "hasMany", target: "region", foreignKey: "region_key" }
]
},
// 设备联动调节表
{
tableNameCn: '设备联动调节表',
tableName: 'device_linkage',
schema: {
id: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true,
comment: '自增主键'
},
device_id: {
type: DataTypes.STRING(50),
allowNull: false,
comment: '设备编号,关联device.device_id'
},
linkage_type: {
type: DataTypes.STRING(20),
allowNull: false,
comment: '联动类型:制冷/制热/新风'
},
threshold_max: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '阈值上限,如"26"'
},
threshold_min: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '阈值下限,如"22"'
},
threshold_mid: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '中间阈值,如"24"'
},
setting_max: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '上限设置:高于阈值上限时的设定值'
},
setting_min: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '下限设置:低于阈值下限时的设定值'
},
setting_mid: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '中间设置:处于阈值区间内的设定值'
},
divide_method: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '划分方式,如"按温度三段式"'
},
begin_validity: {
type: DataTypes.DATE,
allowNull: true,
comment: '有效期起,不设置则为空'
},
end_validity: {
type: DataTypes.DATE,
allowNull: true,
comment: '有效期止,不设置则为空'
},
created_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
comment: '创建时间'
},
updated_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
comment: '修改时间'
}
},
association: [],
indexes: [
{ fields: ['device_id'] },
{ fields: ['linkage_type'] },
{ fields: ['device_id', 'linkage_type'] },
]
},
// 设备扩展表
{
tableNameCn: '设备扩展表',
tableName: 'device_expansion',
schema: {
id: {
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true,
autoIncrement: true,
comment: '自增主键'
},
device_id: {
type: DataTypes.STRING(50),
allowNull: false,
comment: '设备ID,关联device.device_id'
},
region_key: {
type: DataTypes.BIGINT,
allowNull: false,
comment: '区域编号,关联region.id,表示设备所属区域'
},
device_type: {
type: DataTypes.STRING(50),
allowNull: false,
comment: '设备类型,如"电能监测、电表"'
},
original_data: {
type: DataTypes.JSON,
allowNull: true,
comment: '原始扩展数据,如{usePower:114.76,electricityUsageFee:114.76}'
},
cateted_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
comment: '创建时间'
},
updated_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
comment: '修改时间'
}
},
association: [
{ type: "hasMany", target: "device", foreignKey: "device_id" },
{ type: "hasMany", target: "region", foreignKey: "region_key" }
],
indexes: [
{ fields: ['device_id'] },
{ fields: ['region_key'] },
{ fields: ['device_type'] },
{ fields: ['device_id', 'device_type'] },
]
},
];
......@@ -434,6 +434,7 @@ export async function selectPaginatedDataWithOrder( tableName:string, param:Quer
return {
data: result.rows,
total: result.count,
pagination: {
page: pageNumber,
pageSize,
......
......@@ -19,7 +19,7 @@ async function lanuch() {
/**创建http服务 */
httpServer.createServer(systemConfig.port);
/**启动MQTT订阅服务 */
await mqttSrv.startMqttClient();
// await mqttSrv.startMqttClient();
/**启动定时任务 */
startSchedule();
/**启动预警工单定时任务(10分钟) */
......
......@@ -23,3 +23,11 @@ function success(data) {
this.res.send(resultPack);
}
/**
* 中间件错误返回方法
* @param msg
*/
function error(msg) {
this.res.send({success:false, msg, code:400});
}
......@@ -34,6 +34,12 @@ export function setRouter(httpServer) {
httpServer.post('/api/qdm/run/monitor/acRun', asyncHandler(controlAcRunning));
/** 运行分析 - 环境质量弹窗 */
httpServer.post('/api/qdm/run/analysis/envPop', asyncHandler(getRunAnalysisEnvPop));
/** 运行分析 - 离线设备弹窗 */
httpServer.post('/api/qdm/run/analysis/offlineDevicePop', asyncHandler(getOfflineDevicePop));
/** 运行分析 - 故障设备弹窗 */
httpServer.post('/api/qdm/run/analysis/faultDevicePop', asyncHandler(getFaultDevicePop));
/** 运行分析 - 设备能耗监控弹窗 */
httpServer.post('/api/qdm/run/analysis/deviceEnergyPop', asyncHandler(getDeviceEnergyPop));
/** 启动数据集成 */
httpServer.post('/api/qdm/run/start/schedule', asyncHandler(startSchedule));
......@@ -201,6 +207,39 @@ async function getRunAnalysisEnvPop(req, res) {
}
/**
* 运行分析 - 离线设备弹窗
*/
async function getOfflineDevicePop(req, res) {
let reqConf = { regionGroup: 'String', regionType: 'String' };
const NotMustHaveKeys = ["regionGroup", "regionType"];
let { regionGroup, regionType } = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await deviceBiz.getOfflineDeviceList(regionGroup, regionType);
res.success(result);
}
/**
* 运行分析 - 故障设备弹窗
*/
async function getFaultDevicePop(req, res) {
let reqConf = { regionGroup: 'String', regionType: 'String' };
const NotMustHaveKeys = ["regionGroup", "regionType"];
let { regionGroup, regionType } = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await deviceBiz.getFaultDeviceList(regionGroup, regionType);
res.success(result);
}
/**
* 运行分析 - 设备能耗监控弹窗(各区域昨日/今日能耗)
*/
async function getDeviceEnergyPop(req, res) {
let reqConf = { regionGroup: 'String', regionType: 'String' };
const NotMustHaveKeys = ["regionGroup", "regionType"];
let { regionGroup, regionType } = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await deviceBiz.getDeviceEnergyList(regionGroup, regionType);
res.success(result);
}
/**
* 本月累计用电(按天)
*/
async function getMonthlyEnergy(req, res) {
......
......@@ -14,8 +14,22 @@ export function setRouter(httpServer) {
httpServer.post('/api/qdm/feiyi/indoorUnit/list', asyncHandler(getFeiyiIndoorUnitList));
/** 空调内机控制 */
httpServer.post('/api/qdm/feiyi/indoorUnit/control', asyncHandler(getFeiyiIndoorUnitControl));
/** 单个内机分摊电量和电费 */
httpServer.post('/api/qdm/feiyi/indoorUnit/expenses', asyncHandler(getIndoorUnitExpensesApi));
/** 房间电费日使用详情 */
httpServer.post('/api/qdm/feiyi/indoorUnit/expenses/list', asyncHandler(getRoomExpensesListApi));
/** 电费数据写入设备扩展表 */
httpServer.post('/api/qdm/feiyi/indoorUnit/expenses/save', asyncHandler(saveRoomExpensesToExpansionApi));
/** 机房群控设备最新参数数据(测试接口) */
httpServer.get('/api/qdm/feiyi/roomGroup/data', asyncHandler(getRoomGroupDeviceDataApi));
/** 机房群控获取网关信息(测试接口) */
httpServer.get('/api/qdm/feiyi/roomGroup/gatewayInfo', asyncHandler(getRoomGroupGatewayInfoApi));
/** 机房群控参数写入(测试接口) */
httpServer.post('/api/qdm/feiyi/roomGroup/writeParams', asyncHandler(setRoomGroupParamsApi));
}
// =============================================== 控制系统 ==================================================
/**
* 网关设备列表
......@@ -81,4 +95,104 @@ async function getFeiyiIndoorUnitControl(req, res) {
res.success(result);
}
/**
* 单个内机分摊电量和电费
* @param page 当前页码(选填)
* @param limit 每页条数(选填)
* @param roomId 房间ID(选填)
* @param indoorUnitId 内机ID(选填)
* @param indoorUnitAddressFull 内机地址(选填)
* @param occurrenceTime 日期 yyyyMMdd(必填)
*/
async function getIndoorUnitExpensesApi(req, res) {
let reqConf = {
page: 'Number', limit: 'Number',
roomId: 'String', indoorUnitId: 'String', indoorUnitAddressFull: 'String',
occurrenceTime: 'String',
};
const NotMustHaveKeys = [ "page", "limit", "roomId", "indoorUnitId", "indoorUnitAddressFull" ];
let params = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await feiyiClientBiz.getIndoorUnitExpenses(params);
res.success(result);
}
/**
* 房间电费日使用详情
* @param page 当前页码(选填)
* @param limit 每页条数(选填)
* @param roomIds 房间ID集合(选填)
* @param floorIds 楼层ID集合(选填)
* @param buildingIds 楼栋ID集合(选填)
* @param occurrenceTime 日期 yyyyMMdd(必填)
*/
async function getRoomExpensesListApi(req, res) {
let reqConf = {
page: 'Number', limit: 'Number',
roomIds: 'Array', floorIds: 'Array', buildingIds: 'Array',
occurrenceTime: 'String',
};
const NotMustHaveKeys = [ "page", "limit", "roomIds", "floorIds", "buildingIds" ];
let params = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await feiyiClientBiz.getRoomExpensesList(params);
res.success(result);
}
/**
* 电费数据写入设备扩展表 device_expansion
* 拉取"房间电费日使用详情",按房间(region)映射到本地设备,写入 device_expansion
* @param occurrenceTime 日期 yyyyMMdd(必填)
* @param deviceType 写入的设备类型,默认"电能监测"
*/
async function saveRoomExpensesToExpansionApi(req, res) {
let reqConf = { occurrenceTime: 'String', deviceType: 'String' };
const NotMustHaveKeys = [ "deviceType" ];
let params = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await feiyiClientBiz.saveRoomExpensesToExpansion(
params.occurrenceTime,
params.deviceType || '电能监测'
);
res.success(result);
}
// =============================================== 机房系统 ==================================================
/**
* 机房群控设备最新参数数据
* @param gwSn 网关编号(可选)
* @param deviceAddr 设备地址
*/
async function getRoomGroupDeviceDataApi(req, res) {
let reqConf = { gwSn: 'String', deviceAddr: 'String' };
const NotMustHaveKeys = [ "gwSn" ];
let params = eccReqParamater(reqConf, req.query, NotMustHaveKeys);
const result = await feiyiClientBiz.getRoomGroupDeviceData(params.gwSn, params.deviceAddr);
res.success(result);
}
/**
* 机房群控获取网关信息
* @param projectId 项目ID
*/
async function getRoomGroupGatewayInfoApi(req, res) {
let reqConf = { projectId: 'String' };
const NotMustHaveKeys: string[] = [];
let params = eccReqParamater(reqConf, req.query, NotMustHaveKeys);
const result = await feiyiClientBiz.getRoomGroupGatewayInfo(params.projectId);
res.success(result);
}
/**
* 机房群控参数写入
* @param addr 设备地址
* @param gwId 网关ID(可选)
* @param projectId 项目ID
* @param params 写入参数 JSON,如 { "1": 0.0 }
*/
async function setRoomGroupParamsApi(req, res) {
let reqConf = { addr: 'String', gwId: 'Number', projectId: 'String', params: 'Object' };
const NotMustHaveKeys = [ "gwId" ];
let params = eccReqParamater(reqConf, req.body, NotMustHaveKeys);
const result = await feiyiClientBiz.setRoomGroupParams(params.addr, params.gwId, params.projectId, params.params);
res.success(result);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment