147 lines
4.5 KiB
TypeScript
147 lines
4.5 KiB
TypeScript
import { ref } from "vue";
|
|
import { defineStore } from "pinia";
|
|
import type { NiagaraElecData } from "../utils/types";
|
|
import axios from "axios";
|
|
|
|
const useElecPriceStore = defineStore("elecPriceData", () => {
|
|
const elecData = ref<NiagaraElecData[]>([]);
|
|
const subscribers = ref<any[]>([]);
|
|
|
|
// get data from baja
|
|
const getElecDataFromBaja = () => {
|
|
// @ts-ignore
|
|
window.require &&
|
|
// @ts-ignore
|
|
window.requirejs(["baja!"], (baja: any) => {
|
|
console.log("進入 bajaSubscriber 準備執行 BQL 訂閱");
|
|
|
|
// 定義BQL 查詢
|
|
const Total_kwhBql = `local:|foxs:4918|station:|neql:EMS:parameter|bql:select slotPath,parent.displayName,displayName,NumericInterval.historyConfig.id,out`;
|
|
|
|
// 執行查詢
|
|
fetchElecData(baja, Total_kwhBql);
|
|
});
|
|
};
|
|
|
|
const fetchElecData = (baja: any, bql: string) => {
|
|
let eleclist: NiagaraElecData[] = [];
|
|
baja.Ord.make(bql).get({
|
|
cursor: {
|
|
before: () => {},
|
|
each: (record: any) => {
|
|
eleclist.push({
|
|
slotPath: record.get("slotPath"),
|
|
displayName: record.get("displayName"),
|
|
id: record.get("NumericInterval$2ehistoryConfig$2eid").$cEncStr,
|
|
out: record.get("out")?.get("value") ?? 0,
|
|
});
|
|
},
|
|
after: () => {
|
|
elecData.value = [];
|
|
elecData.value.push(...eleclist);
|
|
elecData.value.forEach((item, index) => {
|
|
subscribeToCost(item, index);
|
|
});
|
|
},
|
|
limit: -1,
|
|
offset: 0,
|
|
},
|
|
});
|
|
};
|
|
|
|
const subscribeToCost = (item: NiagaraElecData, index: number) => {
|
|
const slotPath = item.slotPath;
|
|
const ordString = `local:|foxs:4918|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) {
|
|
elecData.value[updatedIndex].out = Number(newValue);
|
|
console.log(`電價表更新 ${item.displayName} 更新:`, newValue);
|
|
}
|
|
}
|
|
} catch (error: any) {
|
|
console.error(
|
|
`處理 ${item.displayName || index} 電價表變化失敗: ${
|
|
error.message
|
|
}`,
|
|
error
|
|
);
|
|
}
|
|
});
|
|
|
|
baja.Ord.make(ordString)
|
|
.get({ subscriber })
|
|
.then(() => {
|
|
console.log(`Successfuly subscribed to ${item.displayName}`);
|
|
})
|
|
.catch((err: any) => {
|
|
console.error(
|
|
`訂閱 ${item.displayName || index} 失敗: ${err.message}`
|
|
);
|
|
subscriber.detach("changed"); // 移除事件監聽器
|
|
});
|
|
subscribers.value.push(subscriber);
|
|
});
|
|
};
|
|
|
|
const updatePrice = async (slotPath: string, out: number) => {
|
|
const domain = window.location.origin;
|
|
try {
|
|
console.log("updatePrice",`${domain}/obix/config/${slotPath}/fallback/value`)
|
|
const res = await axios.put(
|
|
`${domain}/obix/config/${slotPath}/fallback/value`,
|
|
`<real name="in" val="${out}"/> `,
|
|
{
|
|
headers: { "Content-Type": "text/xml" },
|
|
}
|
|
);
|
|
if (res.status === 200) {
|
|
console.log(`成功更新 ${slotPath} 為 ${out}`);
|
|
return true;
|
|
} else {
|
|
console.error(`更新 ${slotPath} 失敗,狀態碼: ${res.status}`);
|
|
return false;
|
|
}
|
|
} catch (error) {
|
|
console.error(`更新 ${slotPath} 出錯:`, error);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
const clearAllSubscriber = () => {
|
|
subscribers.value.forEach((subscriber) => {
|
|
subscriber.detach("changed");
|
|
subscriber.unsubscribeAll(); // 移除所有訂閱
|
|
});
|
|
subscribers.value = [];
|
|
console.log("所有訂閱已清除");
|
|
};
|
|
|
|
return {
|
|
getElecDataFromBaja,
|
|
updatePrice,
|
|
clearAllSubscriber,
|
|
elecData,
|
|
};
|
|
});
|
|
|
|
export default useElecPriceStore;
|