From 4e73410495216f72ec3b64a56d07ba937136c214 Mon Sep 17 00:00:00 2001 From: lb Date: Thu, 28 Dec 2023 15:16:23 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E8=83=BD=E6=BA=90=EF=BC=8C=E8=A7=84?= =?UTF-8?q?=E6=A0=BC:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Energy/EnergyCostChart/index.jsx | 172 ++++++----- src/components/Common/Energy/index.jsx | 3 +- src/store/features/EnergySlice.js | 87 ++++++ src/utils/IS.ts | 50 ++++ src/utils/cutting.ts | 42 +++ src/utils/dcs.ts | 138 +++++++++ src/utils/energe.ts | 30 ++ src/utils/index.ts | 269 ++---------------- 8 files changed, 461 insertions(+), 330 deletions(-) create mode 100644 src/utils/IS.ts create mode 100644 src/utils/cutting.ts create mode 100644 src/utils/dcs.ts create mode 100644 src/utils/energe.ts diff --git a/src/components/Common/Energy/EnergyCostChart/index.jsx b/src/components/Common/Energy/EnergyCostChart/index.jsx index 7bc8ddd..42a923d 100644 --- a/src/components/Common/Energy/EnergyCostChart/index.jsx +++ b/src/components/Common/Energy/EnergyCostChart/index.jsx @@ -1,25 +1,98 @@ import cls from "./index.module.css"; -import { randomInt } from "../../../../utils"; import * as echarts from "echarts"; import { Switch, Radio } from "antd"; import ReactECharts from "echarts-for-react"; +import { useState } from "react"; +import { useSelector } from "react-redux"; const EnergyCostChart = (props) => { - const options = { + const elecTrend = useSelector((state) => state.energy.trend.elec); + const gasITrend = useSelector((state) => state.energy.trend.natGas1); + const gasIITrend = useSelector((state) => state.energy.trend.natGas2); + const [source, setSource] = useState("elec"); + const [period, setPeriod] = useState("week"); + + const currentTrend = + source == "elec" ? elecTrend : source == "gasi" ? gasITrend : gasIITrend; + + const options = getOptions( + period, + source, + currentTrend ?? { week: [], month: [], year: [] } + ); + + return ( +
+
+

能耗趋势图

+
+ +
+ setSource(v.target.value)} + className={`${cls.radioGroup} flex items-center justify-between`} + > + + 电 + + + 天然气I + + + 天然气II + + + + setPeriod(v.target.value)} + className={cls.radioGroup} + > + + 周 + + + 月 + + + 年 + + +
+ +
+ +
+
+ ); +}; + +export default EnergyCostChart; + +function getOptions(period, source, trend) { + console.log("trend ==> ", trend); + + return { color: ["#FFD160", "#12FFF5", "#2760FF"], grid: { top: 32, right: 12, bottom: 56, left: 48 }, xAxis: { type: "category", - data: Array(7) - .fill(1) - .map((_, index) => { - const today = new Date(); - const dtimestamp = today - index * 24 * 60 * 60 * 1000; - return `${new Date(dtimestamp).getMonth() + 1}.${new Date( - dtimestamp - ).getDate()}`; - }) - .reverse(), + data: + source == "elec" + ? trend[period].map((item) => item.time) + : Array(period == "week" ? 7 : period == "year" ? 12 : 30) + .fill(1) + .map((_, index) => { + const today = new Date(); + const dtimestamp = today - index * 24 * 60 * 60 * 1000; + return `${new Date(dtimestamp).getMonth() + 1}.${new Date( + dtimestamp + ).getDate()}`; + }) + .reverse(), axisLabel: { color: "#fff", fontSize: 12, @@ -43,7 +116,7 @@ const EnergyCostChart = (props) => { axisLabel: { color: "#fff", fontSize: 12, - formatter: "{value} %", + // formatter: "{value} %", }, axisLine: { show: true, @@ -56,17 +129,16 @@ const EnergyCostChart = (props) => { color: "#213259a0", }, }, - interval: 10, - min: 0, - max: 100, + // interval: 10, + // min: 0, + // max: 100, }, series: [ { - data: Array(7) - .fill(1) - .map((_) => { - return randomInt(60, 100); - }), + data: + source == "elec" + ? trend[period].map((item) => item.qty) + : trend[period], type: "line", areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ @@ -82,60 +154,4 @@ const EnergyCostChart = (props) => { trigger: "axis", }, }; - - function handleSwitchChange(val) {} - - return ( -
-
-

能耗趋势图

-
- -
- - - 氧气含量 - - - 二氧化硫 - - - 一氧化氮 - - - 二氧化氮 - - - - - - 日 - - - 周 - - - 月 - - - 年 - - -
- -
- -
-
- ); -}; - -export default EnergyCostChart; +} diff --git a/src/components/Common/Energy/index.jsx b/src/components/Common/Energy/index.jsx index c0e890a..edeebe1 100644 --- a/src/components/Common/Energy/index.jsx +++ b/src/components/Common/Energy/index.jsx @@ -6,8 +6,7 @@ import { useSelector } from "react-redux"; function EnergyCost(props) { const energyInfo = useSelector((state) => state.energy?.info); - if (energyInfo) { - } + return (
diff --git a/src/store/features/EnergySlice.js b/src/store/features/EnergySlice.js index 6a4f157..31c857a 100644 --- a/src/store/features/EnergySlice.js +++ b/src/store/features/EnergySlice.js @@ -13,6 +13,76 @@ export const initialState = { // 天然气2 ngQty2: "0", // m³ }, + trend: { + natGas1: { + // 暂时只存了周数据: + week: [], + month: [], + year: [], + }, + natGasII: { + week: [], + month: [], + year: [], + }, + elec: { + week: [ + // { qty: 10, time: "01" }, + // { qty: 20, time: "02" }, + // { qty: 30, time: "03" }, + // { qty: 40, time: "04" }, + // { qty: 50, time: "05" }, + // { qty: 60, time: "06" }, + // { qty: 70, time: "07" }, + ], + month: [ + // { qty: 20, time: "02" }, + // { qty: 30, time: "03" }, + // { qty: 40, time: "04" }, + // { qty: 50, time: "05" }, + // { qty: 60, time: "06" }, + // { qty: 70, time: "07" }, + // { qty: 80, time: "08" }, + // { qty: 90, time: "09" }, + // { qty: 100, time: "10" }, + // { qty: 110, time: "11" }, + // { qty: 120, time: "12" }, + // { qty: 130, time: "13" }, + // { qty: 140, time: "14" }, + // { qty: 150, time: "15" }, + // { qty: 160, time: "16" }, + // { qty: 170, time: "17" }, + // { qty: 180, time: "18" }, + // { qty: 190, time: "19" }, + // { qty: 200, time: "20" }, + // { qty: 210, time: "21" }, + // { qty: 220, time: "22" }, + // { qty: 230, time: "23" }, + // { qty: 240, time: "24" }, + // { qty: 250, time: "25" }, + // { qty: 260, time: "26" }, + // { qty: 270, time: "27" }, + // { qty: 280, time: "28" }, + // { qty: 290, time: "29" }, + // { qty: 300, time: "30" }, + // { qty: 310, time: "31" }, + ], + year: [ + // { qty: 10, time: "01" }, + // { qty: 20, time: "02" }, + // { qty: 30, time: "03" }, + // { qty: 40, time: "04" }, + // { qty: 50, time: "05" }, + // { qty: 60, time: "06" }, + // { qty: 70, time: "07" }, + // { qty: 80, time: "08" }, + // { qty: 90, time: "09" }, + // { qty: 100, time: "10" }, + // { qty: 110, time: "11" }, + // { qty: 120, time: "12" }, + ], + }, + }, }; const energySlice = createSlice({ @@ -22,6 +92,23 @@ const energySlice = createSlice({ setInfo: (state, action) => { state.info = { ...state.info, ...action.payload }; }, + setElecTrend: (state, action) => { + state.trend.elec = action.payload; + }, + setSumGasData: (state, action) => { + if ("sumGas1Now" in action.payload) { + state.info.ngQty1 = action.payload.sumGas1Now; + } + if ("sumGas2Now" in action.payload) { + state.info.ngQty2 = action.payload.sumGas2Now; + } + if ("hisSumGas1" in action.payload) { + state.trend.natGas1.week = action.payload.hisSumGas1; + } + if ("hisSumGas2" in action.payload) { + state.trend.natGas2.week = action.payload.hisSumGas2; + } + }, }, }); diff --git a/src/utils/IS.ts b/src/utils/IS.ts new file mode 100644 index 0000000..767b6f7 --- /dev/null +++ b/src/utils/IS.ts @@ -0,0 +1,50 @@ +import { store } from "../store"; +import { MessageItem } from "./checkTypeHelper"; + +export default function handler(msg: MessageEvent) { + let serializedData: MessageItem | null = null; + try { + serializedData = JSON.parse(msg.data); + } catch (error) { + console.log("[*] websocket: [unable to serialize] ---> ", msg); + } + + console.log("[ISRA DATA] ---> ", serializedData); + + if (serializedData == null) return; + + // 处理 checkTypeList + store.dispatch({ + type: "isra/setCheckType", + payload: serializedData.checkType, + }); + // for (const checkType of serializedData.checkTypeList) { + // store.dispatch({ + // type: 'isra/setCheckTypeList', + // payload: serializedData.checkTypeList + // }) + // } + + // 处理 dayStatistic 等数据 + if ("dayStatistic" in serializedData) { + store.dispatch({ + type: "isra/setDayStatistic", + payload: serializedData.dayStatistic, + }); + } else if ("weekStatistic" in serializedData) { + store.dispatch({ + type: "isra/setWeekStatistic", + payload: serializedData.weekStatistic, + }); + } else if ("monthStatistic" in serializedData) { + store.dispatch({ + type: "isra/setMonthStatistic", + payload: serializedData.monthStatistic, + }); + } else if ("yearStatistic" in serializedData) { + store.dispatch({ + type: "isra/setYearStatistic", + payload: serializedData.yearStatistic, + }); + } +} diff --git a/src/utils/cutting.ts b/src/utils/cutting.ts new file mode 100644 index 0000000..6db47d5 --- /dev/null +++ b/src/utils/cutting.ts @@ -0,0 +1,42 @@ +import { store } from "../store"; +type TableDataType = { + name: "table"; + type: "cutting"; + data: any[]; +}; +type ChartDataType = { + name: "chart"; + type: "cutting"; + nightPushData: any[]; + dayPushData: any[]; + allPushData: any[]; + dateType: "day" | "week" | "month" | "year"; +}; + +export default function handler(msg: MessageEvent) { + let serializedData: TableDataType | ChartDataType | null = null; + try { + serializedData = JSON.parse(msg.data); + } catch (error) { + console.log("[*] websocket: [unable to serialize] ---> ", msg); + } + + console.log("[CUTTING DATA] ---> ", serializedData); + + if (serializedData == null) return; + + switch (serializedData.name) { + case "table": + store.dispatch({ + type: "cutting/setCuttingTable", + payload: serializedData, + }); + break; + case "chart": + store.dispatch({ + type: "cutting/setCuttingChart", + payload: serializedData, + }); + break; + } +} diff --git a/src/utils/dcs.ts b/src/utils/dcs.ts new file mode 100644 index 0000000..515b3ac --- /dev/null +++ b/src/utils/dcs.ts @@ -0,0 +1,138 @@ +import { store } from "../store"; + +export default function handler(msg: MessageEvent) { + let serializedData: { type: string; data: any } | null = null; + try { + serializedData = JSON.parse(msg.data); + } catch (error) { + console.log("[*] websocket: [unable to serialize] ---> ", msg); + } + switch (serializedData?.type) { + case "KilnInfo": { + store.dispatch({ + type: "kiln/setKilnInfo", + payload: serializedData.data, + }); + break; + } + case "CombustionAirInfo": { + // 助燃风流量 实时 + store.dispatch({ + type: "combustionAir/setRuntime", + payload: serializedData.data.combustionAirNow, // [] + }); + // 助燃风流量 历史 + store.dispatch({ + type: "combustionAir/setHistory", + payload: serializedData.data.combustionAirHis, // {} + }); + break; + } + case "GasInfo": { + // 天然气流量 1 实时 + store.dispatch({ + type: "natGas/setGasIRuntime", + payload: serializedData.data.gas1Now, + }); + // 天然气流量 1 历史 + store.dispatch({ + type: "natGas/setGasIHistory", + payload: serializedData.data.hisGas1, + }); + // 天然气流量 2 实时 + store.dispatch({ + type: "natGas/setGasIIRuntime", + payload: serializedData.data.gas2Now, + }); + // 天然气流量 2 历史 + store.dispatch({ + type: "natGas/setGasIIHistory", + payload: serializedData.data.hisGas2, + }); + break; + } + case "FanFrequencyInfo": { + // 风机运行频率 暂时只有实时数据 + store.dispatch({ + type: "fanFrequence/setRuntime", + payload: serializedData.data.FanFrequencyInfo, + }); + // 风机运行频率 历史 暂无 + break; + } + case "TopTempInfo": { + // 碹顶温度列表 + store.dispatch({ + type: "temperature/setTopTemp", + payload: serializedData.data.topTempInfo, + }); + break; + } + case "BottomTempInfo": { + // 碹底温度列表 + store.dispatch({ + type: "temperature/setBottomTemp", + payload: serializedData.data.bottomTempInfo, + }); + break; + } + case "FeederInfo": { + // 投料机信息 + store.dispatch({ + type: "feeder/setFeederInfo", + payload: serializedData.data, + }); + break; + } + case "FireInfo": { + // 火向时间信息 + store.dispatch({ + type: "fireInfo/setFireInfo", + payload: serializedData.data, + }); + break; + } + case "FanInfo": { + // 风机信息 + store.dispatch({ + type: "fanInfo/setInfo", + payload: serializedData.data.fanInfo, + }); + break; + } + case "AnnealFanFrequencyInfo": { + // 退火-风机运行频率 + store.dispatch({ + type: "annealFanFrequence/setRuntime", + payload: serializedData.data.AnnealFanFrequencyInfo, + }); + break; + } + case "AnnealTempInfo": { + // 退火-温度列表 + store.dispatch({ + type: "annealTemperature/setTemp", + payload: serializedData.data, + }); + break; + } + case "AnnealFanInfo": { + // 退火-风机故障信息 + store.dispatch({ + type: "annealFanInfo/setInfo", + payload: serializedData.data.annealFanInfo, + }); + break; + } + case "SumGasInfo": { + store.dispatch({ + type: "energy/setSumGasData", + payload: serializedData.data, + }); + break; + } + default: { + console.log("websocket message: [unknown] ---> ", msg.data); + } + } +} diff --git a/src/utils/energe.ts b/src/utils/energe.ts new file mode 100644 index 0000000..534e367 --- /dev/null +++ b/src/utils/energe.ts @@ -0,0 +1,30 @@ +import { store } from "../store"; + +export default function handler(msg: MessageEvent) { + let serializedData: { type: string; data: any } | null = null; + try { + serializedData = JSON.parse(msg.data); + } catch (error) { + console.log("[*] websocket: [unable to serialize] ---> ", msg); + } + switch (serializedData?.type) { + case "EnergyInfo": { + // 能耗数据 + store.dispatch({ + type: "energy/setInfo", + payload: serializedData.data, + }); + break; + } + case "EnergyTrend": { + store.dispatch({ + type: "energy/setTrend", + payload: serializedData.data, + }); + break; + } + default: { + console.log("websocket message: [unknown] ---> ", msg.data); + } + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts index eb34f3c..06569d4 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,15 +1,8 @@ -import { store } from "../store"; -import { MessageItem } from "./checkTypeHelper"; -import { v4 as uuidv4 } from 'uuid' - -export function randomInt(min: number, max: number, includeMax = false) { - let Fn = includeMax ? Math.ceil : Math.floor; - let num = Fn(Math.random() * max); - while (num < min) { - num = Fn(Math.random() * max); - } - return num; -} +import { v4 as uuidv4 } from "uuid"; +import cuttingHandler from "./cutting"; +import energeHandler from "./energe"; +import IsHandler from "./IS"; +import dcsHandler from "./dcs"; /** * new XClient('ws://192.168.1.12:8081/xc-screen/websocket/xc001', 'DCS') @@ -45,164 +38,16 @@ new XClient( "ws://10.70.180.10:8081/xc-screen/websocket/xc001", // "ws://192.168.1.12:8081/xc-screen/websocket/xc001", "DCS_DATA", - (msg: MessageEvent) => { - let serializedData: { type: string; data: any } | null = null; - try { - serializedData = JSON.parse(msg.data); - } catch (error) { - console.log("[*] websocket: [unable to serialize] ---> ", msg); - } - switch (serializedData?.type) { - case "KilnInfo": { - store.dispatch({ - type: "kiln/setKilnInfo", - payload: serializedData.data, - }); - break; - } - case "CombustionAirInfo": { - // 助燃风流量 实时 - store.dispatch({ - type: "combustionAir/setRuntime", - payload: serializedData.data.combustionAirNow, // [] - }); - // 助燃风流量 历史 - store.dispatch({ - type: "combustionAir/setHistory", - payload: serializedData.data.combustionAirHis, // {} - }); - break; - } - case "GasInfo": { - // 天然气流量 1 实时 - store.dispatch({ - type: "natGas/setGasIRuntime", - payload: serializedData.data.gas1Now, - }); - // 天然气流量 1 历史 - store.dispatch({ - type: "natGas/setGasIHistory", - payload: serializedData.data.hisGas1, - }); - // 天然气流量 2 实时 - store.dispatch({ - type: "natGas/setGasIIRuntime", - payload: serializedData.data.gas2Now, - }); - // 天然气流量 2 历史 - store.dispatch({ - type: "natGas/setGasIIHistory", - payload: serializedData.data.hisGas2, - }); - break; - } - case "FanFrequencyInfo": { - // 风机运行频率 暂时只有实时数据 - store.dispatch({ - type: "fanFrequence/setRuntime", - payload: serializedData.data.FanFrequencyInfo, - }); - // 风机运行频率 历史 暂无 - break; - } - case "TopTempInfo": { - // 碹顶温度列表 - store.dispatch({ - type: "temperature/setTopTemp", - payload: serializedData.data.topTempInfo, - }); - break; - } - case "BottomTempInfo": { - // 碹底温度列表 - store.dispatch({ - type: "temperature/setBottomTemp", - payload: serializedData.data.bottomTempInfo, - }); - break; - } - case "FeederInfo": { - // 投料机信息 - store.dispatch({ - type: "feeder/setFeederInfo", - payload: serializedData.data, - }); - break; - } - case "FireInfo": { - // 火向时间信息 - store.dispatch({ - type: "fireInfo/setFireInfo", - payload: serializedData.data, - }); - break; - } - case "FanInfo": { - // 风机信息 - store.dispatch({ - type: "fanInfo/setInfo", - payload: serializedData.data.fanInfo, - }); - break; - } - case "AnnealFanFrequencyInfo": { - // 退火-风机运行频率 - store.dispatch({ - type: "annealFanFrequence/setRuntime", - payload: serializedData.data.AnnealFanFrequencyInfo, - }); - break; - } - case "AnnealTempInfo": { - // 退火-温度列表 - store.dispatch({ - type: "annealTemperature/setTemp", - payload: serializedData.data, - }); - break; - } - case "AnnealFanInfo": { - // 退火-风机故障信息 - store.dispatch({ - type: "annealFanInfo/setInfo", - payload: serializedData.data.annealFanInfo, - }); - break; - } - default: { - console.log("websocket message: [unknown] ---> ", msg.data); - } - } - } + dcsHandler ); -const newUser = uuidv4() +const newUser = uuidv4(); new XClient( "ws://192.168.1.74:48080/websocket/message?userId=ENERGY" + newUser, // "ws://10.70.2.2:8080/websocket/message?userId=ENERGY" + newUser, // "ws://192.168.1.74:48080/websocket/message?userId=ENERGY111", "MES_DATA", - (msg) => { - let serializedData: { type: string; data: any } | null = null; - try { - serializedData = JSON.parse(msg.data); - } catch (error) { - console.log("[*] websocket: [unable to serialize] ---> ", msg); - } - switch (serializedData?.type) { - case "EnergyInfo": { - // 能耗数据 - store.dispatch({ - type: "energy/setInfo", - payload: serializedData.data, - }); - break; - } - default: { - console.log("websocket message: [unknown] ---> ", msg.data); - } - } - } + energeHandler ); // 产线缺陷相关数据 @@ -210,98 +55,22 @@ new XClient( "ws://10.70.2.2:8080/websocket/message?userId=IS" + newUser, // "ws://192.168.0.33:48082/websocket/message?userId=IS111", "QUALITY_DATA", - (msg) => { - let serializedData: MessageItem | null = null; - try { - serializedData = JSON.parse(msg.data); - } catch (error) { - console.log("[*] websocket: [unable to serialize] ---> ", msg); - } - - console.log("[ISRA DATA] ---> ", serializedData); - - if (serializedData == null) return; - - // 处理 checkTypeList - store.dispatch({ - type: "isra/setCheckType", - payload: serializedData.checkType, - }); - // for (const checkType of serializedData.checkTypeList) { - // store.dispatch({ - // type: 'isra/setCheckTypeList', - // payload: serializedData.checkTypeList - // }) - // } - - // 处理 dayStatistic 等数据 - if ("dayStatistic" in serializedData) { - store.dispatch({ - type: "isra/setDayStatistic", - payload: serializedData.dayStatistic, - }); - } else if ("weekStatistic" in serializedData) { - store.dispatch({ - type: "isra/setWeekStatistic", - payload: serializedData.weekStatistic, - }); - } else if ("monthStatistic" in serializedData) { - store.dispatch({ - type: "isra/setMonthStatistic", - payload: serializedData.monthStatistic, - }); - } else if ("yearStatistic" in serializedData) { - store.dispatch({ - type: "isra/setYearStatistic", - payload: serializedData.yearStatistic, - }); - } - } + IsHandler ); -type TableDataType = { - name: "table"; - type: "cutting"; - data: any[]; -}; -type ChartDataType = { - name: "chart"; - type: "cutting"; - nightPushData: any[]; - dayPushData: any[]; - allPushData: any[]; - dateType: "day" | "week" | "month" | "year"; -}; // 良品率相关数据 new XClient( // "ws://10.70.27.122:8080/websocket/message?userId=CUTTING", "ws://10.70.2.2:8080/websocket/message?userId=CUTTING" + newUser, "CUTTING_DATA", - (msg) => { - let serializedData: TableDataType | ChartDataType | null = null; - try { - serializedData = JSON.parse(msg.data); - } catch (error) { - console.log("[*] websocket: [unable to serialize] ---> ", msg); - } - - console.log("[CUTTING DATA] ---> ", serializedData); - - if (serializedData == null) return; - - switch (serializedData.name) { - case "table": - store.dispatch({ - type: "cutting/setCuttingTable", - payload: serializedData, - }); - break; - case "chart": - store.dispatch({ - type: "cutting/setCuttingChart", - payload: serializedData, - }); - break; - } - } + cuttingHandler ); + +export function randomInt(min: number, max: number, includeMax = false) { + let Fn = includeMax ? Math.ceil : Math.floor; + let num = Fn(Math.random() * max); + while (num < min) { + num = Fn(Math.random() * max); + } + return num; +}