diff --git a/src/components/EnergyLine.vue b/src/components/EnergyLine.vue index 4cc7eea..4fac865 100644 --- a/src/components/EnergyLine.vue +++ b/src/components/EnergyLine.vue @@ -1,66 +1,107 @@ + + diff --git a/src/components/EnergySankey.vue b/src/components/EnergySankey.vue index 472c690..04f6a2d 100644 --- a/src/components/EnergySankey.vue +++ b/src/components/EnergySankey.vue @@ -8,10 +8,6 @@ const store = useElecStore(); const chartContainer = ref(null); let chart = null; -const initChart = () => { - chart = echarts.init(chartContainer.value); -}; - const updateChart = (elecData) => { if (!chart) { return; @@ -68,12 +64,12 @@ watch( updateChart(newElecData); } }, - { deep: true, immediate: true } + { deep: true } ); onMounted(async () => { await store.getElecDataFromBaja(); - initChart(); + chart = echarts.init(chartContainer.value); store.startTimer(); }); diff --git a/src/stores/useElecDemandStore.ts b/src/stores/useElecDemandStore.ts index ceca673..199f244 100644 --- a/src/stores/useElecDemandStore.ts +++ b/src/stores/useElecDemandStore.ts @@ -1,44 +1,115 @@ import { ref } from "vue"; import { defineStore } from "pinia"; -// import dayjs from "dayjs"; -import type { NiagaraElecData } from "../utils/types"; +import type { NiagaraElecDemandData } from "../utils/types"; -const useElecStore = defineStore("elecData", () => { - const elecData = ref([]); +const useElecDemandStore = defineStore("elecDemand", () => { + const elecData = ref([]); + const subscribers = ref([]); // get data from baja - const getElecDataFromBaja = () => { + const getElecDemandFromBaja = () => { // @ts-ignore window.require && // @ts-ignore window.requirejs(["baja!"], (baja: any) => { - console.log("進入 bajaSubscriber 準備執行 BQL 訂閱"); - let eleclist: NiagaraElecData[] = []; + let eleclist: NiagaraElecDemandData[] = []; baja.Ord.make( `local:|foxs:4912|station:|neql:EMS:kw|bql:select slotPath,parent.displayName,name` ).get({ cursor: { - before: () => { - }, + before: () => {}, each: (record: any) => { - console.log("record", record); - // eleclist.push({ - // slotPath: record.get("slotPath"), - // displayName: record.get("parent$2edisplayName"), - // id: record.get("NumericInterval$2ehistoryConfig$2eid").$cEncStr, - // out: record.get("out").get("value"), - // }); + const slotPath = record.get("slotPath"); + const displayName = record.get("parent$2edisplayName"); + const name = record.get("name"); + + const newItem: NiagaraElecDemandData = { + slotPath: slotPath, + displayName: displayName, + name: name, + out: 0, + }; + eleclist.push(newItem); }, after: () => { - elecData.value = eleclist; - console.log("Niagara 用電:", elecData.value); + elecData.value = []; + elecData.value.push(...eleclist); + eleclist.forEach((item, index) => { + subscribeToHistory(item, index); + }); }, }, }); }); }; - return { getElecDataFromBaja, elecData }; + const subscribeToHistory = (item: NiagaraElecDemandData, index: number) => { + const slotPath = item.slotPath; + const ordString = `local:|foxs:4912|station:|${slotPath}`; + + // @ts-ignore + window.require && + // @ts-ignore + window.requirejs(["baja!"], (baja: any) => { + // 建立訂閱器 + const subscriber = new baja.Subscriber(); + + // 定義 changed 事件的處理函數 + subscriber.attach("changed", (prop: any) => { + try { + if (prop && prop.getName() === "out") { + // 取得 out 的新值 + const match = prop.$display.match(/^(\d+(\.\d+)?)/); + const newValue = match ? parseFloat(match[0]) : 0; + // 更新 elecData 中對應的 out 值 + const updatedIndex = elecData.value.findIndex( + (data) => data.slotPath === item.slotPath + ); + + if (updatedIndex !== -1) { + const newElecData = [...elecData.value]; + newElecData[updatedIndex] = { + ...newElecData[updatedIndex], + out: Number(newValue), + }; + elecData.value = newElecData; + console.log( + `Niagara 用電需求 ${item.name} 更新:`, + newValue + ); + } + } + } catch (error: any) { + console.error( + `處理 ${item.name || index} 告警變化失敗: ${error.message}`, + error + ); + } + }); + + baja.Ord.make(ordString) + .get({ subscriber }) + .then(() => { + console.log(`Successfuly subscribed to ${item.name}`); + }) + .catch((err: any) => { + console.error(`訂閱 ${item.name || index} 失敗: ${err.message}`); + subscriber.detach("changed"); // 移除事件監聽器 + }); + subscribers.value.push(subscriber); + }); + }; + + const clearAllSubscriber = () => { + subscribers.value.forEach((subscriber) => { + subscriber.detach("changed"); + subscriber.unsubscribeAll(); // 移除所有訂閱 + }); + subscribers.value = []; + console.log("所有訂閱已清除"); + }; + + return { getElecDemandFromBaja, elecData, clearAllSubscriber }; }); -export default useElecStore; +export default useElecDemandStore; \ No newline at end of file diff --git a/src/stores/useElecDistStore.ts b/src/stores/useElecDistStore.ts index a01ce76..0a58d0d 100644 --- a/src/stores/useElecDistStore.ts +++ b/src/stores/useElecDistStore.ts @@ -3,7 +3,7 @@ import { defineStore } from "pinia"; import dayjs from "dayjs"; import type { NiagaraElecData } from "../utils/types"; -const useElecStore = defineStore("elecData", () => { +const useElecStore = defineStore("elecDist", () => { const elecData = ref([]); // @ts-ignore let timerId = null; @@ -40,7 +40,8 @@ const useElecStore = defineStore("elecData", () => { const validElecList = eleclist.filter( (item) => item.id !== undefined ); - elecData.value = [...elecData.value, ...validElecList]; + elecData.value = []; + elecData.value.push(...validElecList); validElecList.forEach((item) => { subscribeToHistory(item); }); @@ -108,7 +109,7 @@ const useElecStore = defineStore("elecData", () => { const startTimer = () => { timerId = setInterval(() => { updateHistoryData(); - }, 60 * 1000); // 每小時執行一次 + }, 60 * 60 * 1000); // 每小時執行一次 }; // 停止定時器 diff --git a/src/utils/types.ts b/src/utils/types.ts index f1cf055..0362142 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -4,4 +4,11 @@ export interface NiagaraElecData { displayName: string; id: string; out: number; +} + +export interface NiagaraElecDemandData { + slotPath: string; + displayName: string; + name: string; + out: number; } \ No newline at end of file