diff --git a/ibms_react/ibms_react.esproj b/ibms_react/ibms_react.esproj
index ff0c898..9e5face 100644
--- a/ibms_react/ibms_react.esproj
+++ b/ibms_react/ibms_react.esproj
@@ -4,10 +4,17 @@
src\
Jest
-
+
+
npm run build
$(MSBuildProjectDirectory)\build
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ibms_react/src/App.css b/ibms_react/src/App.css
deleted file mode 100644
index 74b5e05..0000000
--- a/ibms_react/src/App.css
+++ /dev/null
@@ -1,38 +0,0 @@
-.App {
- text-align: center;
-}
-
-.App-logo {
- height: 40vmin;
- pointer-events: none;
-}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
-}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
-}
-
-@keyframes App-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
diff --git a/ibms_react/src/App.js b/ibms_react/src/App.js
index d9a7b47..77b3539 100644
--- a/ibms_react/src/App.js
+++ b/ibms_react/src/App.js
@@ -1,4 +1,4 @@
-import { useMemo, useEffect, useState } from "react";
+import { useMemo, useEffect, useState, useCallback } from "react";
import { Outlet, NavLink } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import { Container, Nav, Navbar, NavDropdown } from "react-bootstrap";
@@ -49,6 +49,16 @@ function App() {
dispatch(fetchSysMainSub(selectedBuiTag));
}
}, [selectedBuiTag]);
+
+ // 離開頁面就清除所有 cookie
+ //const removeAllCookie = useCallback(() => {
+ // console.log("關閉分頁時,清除所有 cookie")
+ // window.addEventListener("beforeunload",() => {
+ // document.cookie.match(/[^ =;]+(?=\=)/g).forEach(key => {
+ // document.cookie = `${key}=""; max-age=0`;
+ // }) })
+ //}, [])
+
return (
{/* 主選單 */}
diff --git a/ibms_react/src/App.test.js b/ibms_react/src/App.test.js
deleted file mode 100644
index 1f03afe..0000000
--- a/ibms_react/src/App.test.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
- render(
);
- const linkElement = screen.getByText(/learn react/i);
- expect(linkElement).toBeInTheDocument();
-});
diff --git a/ibms_react/src/components/forges/ForgeModel.js b/ibms_react/src/components/forges/ForgeModel.js
index 60478bc..56236ee 100644
--- a/ibms_react/src/components/forges/ForgeModel.js
+++ b/ibms_react/src/components/forges/ForgeModel.js
@@ -1,17 +1,29 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { useEffect, useRef, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import * as THREE from "three";
import { fetchForge, shutdownForge } from "@STORE/forgeSlice";
+import { SubscribeDeviceTempByBaja } from "@UTIL"
import hotspot from "@ASSET/img/hotspot.svg";
-function ForgeModel({ forgeHeight, sprites = [] }) {
+function ForgeModel({ forgeHeight, deviceList = [] }) {
const dispatch = useDispatch();
const viewerEl = useRef(null);
const {
buildingInfo: { urn_3D },
- forgeViewer: { viewer, dataVizExtn, DataVizCore },
+ forgeViewer: { viewer, model,dataVizExtn, DataVizCore, structureInfo },
+ device: { selectedDeviceSysTag,selectedDeviceNameTag,tempsensorDevList }
} = useSelector((store) => store);
+ const deviceArray = useMemo(()=> deviceList.map(({ device_number, device_coordinate_3d, room_dbid }) => {
+ return {
+ id: device_number, // An ID to identify this device
+ position: JSON.parse(device_coordinate_3d), // World coordinates of this device
+ roomId: room_dbid,
+ sensorTypes: ["temperature", "humidity"], // The types/properties this device exposes
+ temp: 0,
+ }
+ }), [selectedDeviceNameTag])
+
// 載入 Forge Viewer
useEffect(() => {
if (urn_3D) {
@@ -21,9 +33,9 @@ function ForgeModel({ forgeHeight, sprites = [] }) {
urn: urn_3D,
}),
);
+ };
return () => {
dispatch(shutdownForge());
- };
}
}, [urn_3D]);
@@ -38,7 +50,7 @@ function ForgeModel({ forgeHeight, sprites = [] }) {
// 熱點點擊事件
const onSpriteClicked = (event) => {
const targetDbIds = [event.dbId];
- spriteUpdate(event, targetDbIds, { scale: 1.3, color: { r: 1, g: 0, b: 0 } });
+ spriteUpdate(event, targetDbIds, { scale: 1.3, color: { r: 1.0, g: 0, b: 0 } });
console.log(`Sprite clicked:${targetDbIds}`);
};
@@ -51,10 +63,9 @@ function ForgeModel({ forgeHeight, sprites = [] }) {
// 進入系統監控頁面,出現熱點
useEffect(() => {
- if (sprites.length !== 0 && viewer && dataVizExtn) {
- // const filterSprites = sprites.map;
+ if (deviceList.length !== 0 && viewer && dataVizExtn) {
dataVizExtn.removeAllViewables();
- sprites.forEach(async ({ device_coordinate_3d, forge_dbid }, index) => {
+ deviceList.forEach(async ({ device_coordinate_3d, forge_dbid }, index) => {
const viewableType = DataVizCore.ViewableType.SPRITE;
const spriteColor = new THREE.Color(0xffffff);
const spriteIconUrl = hotspot;
@@ -78,12 +89,84 @@ function ForgeModel({ forgeHeight, sprites = [] }) {
}
return () => {
- if (sprites.length !== 0 && viewer && dataVizExtn) {
+ if (deviceList.length !== 0 && viewer && dataVizExtn) {
viewer.removeEventListener(DataVizCore.MOUSE_CLICK, onSpriteClicked);
viewer.removeEventListener(DataVizCore.MOUSE_CLICK_OUT, onSpriteClickedOut);
}
};
- }, [sprites, dataVizExtn, viewer]);
+ }, [deviceList, dataVizExtn]);
+
+ // 熱圖
+ const getSensorValue = (surfaceShadingPoint) => {
+ // The `SurfaceShadingPoint.id` property matches one of the identifiers passed to `generateSurfaceShadingData`
+ const { temp } = surfaceShadingPoint;
+ return temp / 40;
+ }
+
+ // 構建熱圖
+ const establishHeatMaps = async (deviceList, dataVizExtn) => {
+ // 不重複的房間值
+ const uniqueRoomIds = [...new Set(deviceArray.map(r => r.roomId))]; // 房間唯一值
+ const {
+ SurfaceShadingData,
+ SurfaceShadingPoint,
+ SurfaceShadingNode,
+ } = DataVizCore;
+ const heatmapData = new SurfaceShadingData();
+ uniqueRoomIds.forEach(room_Id => {
+ // 為每個房間都建立一個 Node
+ const shadingNode = new SurfaceShadingNode("TemperatureSensor", room_Id);
+ deviceArray.forEach(({ id, position, roomId, sensorTypes }) => {
+ // 設備對應的 roomId 用來判斷要加入哪個 Node
+ if (room_Id === roomId) {
+ const pt = new SurfaceShadingPoint(id, position, sensorTypes);
+ shadingNode.addPoint(pt);
+ }
+
+ })
+ heatmapData.addChild(shadingNode);
+ heatmapData.initialize(viewer.model);
+ })
+ await dataVizExtn.setupSurfaceShading(viewer.model, heatmapData, {
+ type: "PlanarHeatmap",
+ slicingPosition: 0.5, // Slicing happens at the vertical mid-point of the geometry
+ placementPosition: 1.0, // The sliced planar heatmap placed at the base of geometry
+ minOpacity: 0.0, // The default value if this option is omitted
+ maxOpacity: 0.5, // The default value if this option is omitted
+ });
+ // 對 "temperature" 的溫度設定兩種顏色:紅色和藍色
+ dataVizExtn.registerSurfaceShadingColors("temperature", [0x0000ff, 0x00ff00, 0xffff00, 0xff0000]);
+
+ if (deviceArray.length !== 0) {
+ const sensorType = "temperature";
+ deviceArray.forEach(({ id }) => {
+ dataVizExtn.renderSurfaceShading(id, sensorType, getSensorValue);
+ })
+ }
+ }
+
+ useEffect(() => {
+ if (deviceList && structureInfo && dataVizExtn && selectedDeviceSysTag == "ME") {
+ // 訂閱有 Temp 的設備
+ deviceList.forEach(({ device_number }) => {
+ SubscribeDeviceTempByBaja(device_number, dispatch)
+ })
+ establishHeatMaps(deviceList, dataVizExtn, structureInfo);
+ }
+ return () => { }
+}, [selectedDeviceNameTag]);
+
+ useEffect(() => {
+ if (tempsensorDevList.length !== 0) {
+ deviceArray.forEach((device) => {
+ if (tempsensorDevList.findIndex(({ device_number }) => device_number === device.id) !== -1) {
+ const newTempObj = tempsensorDevList.find(({ device_number }) => device_number === device.id)
+ device.temp = newTempObj.temp;
+ dataVizExtn.updateSurfaceShading(getSensorValue);
+ }
+ })
+ }
+ }, [tempsensorDevList])
return
;
}
diff --git a/ibms_react/src/index.css b/ibms_react/src/index.css
deleted file mode 100644
index ec2585e..0000000
--- a/ibms_react/src/index.css
+++ /dev/null
@@ -1,13 +0,0 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
-}
diff --git a/ibms_react/src/logo.svg b/ibms_react/src/logo.svg
deleted file mode 100644
index 9dfc1c0..0000000
--- a/ibms_react/src/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ibms_react/src/pages/Monitor.js b/ibms_react/src/pages/Monitor.js
index 09f6f00..b58f3be 100644
--- a/ibms_react/src/pages/Monitor.js
+++ b/ibms_react/src/pages/Monitor.js
@@ -3,26 +3,49 @@ import { useParams } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import { Container, Row, Col, Card, ButtonGroup, Button } from "react-bootstrap";
import ForgeModel from "@COM/forges/ForgeModel";
-import { fetchSelectedDeviceMenu, fetchSelectedDeviceList, fetchSelectedDevFlTags } from "@STORE";
+import { fetchSelectedDeviceMenu, fetchSelectedDeviceList, fetchSelectedDevFlTags, changeMainSubSys } from "@STORE";
import defdev from "@ASSET/img/defdev.png";
function Monitor() {
const params = useParams().systemId; // main_sub
const [main_system_tag, sub_system_tag] = params.split("_");
const dispatch = useDispatch();
const {
- buildingInfo: { selectedBuiTag },
device: { selectedDeviceMenu, selectedDeviceList, selectedDeviceFloorTags },
system: { mainSub },
+ forgeViewer: { viewer, model },
} = useSelector((state) => state);
useEffect(() => {
- if (selectedBuiTag && main_system_tag && sub_system_tag) {
+ if (main_system_tag && sub_system_tag) {
+ dispatch(changeMainSubSys({ main_system_tag, sub_system_tag }))
dispatch(fetchSelectedDeviceMenu({ main_system_tag, sub_system_tag }));
dispatch(fetchSelectedDeviceList({ sub_system_tag }));
dispatch(fetchSelectedDevFlTags({ sub_system_tag }));
}
// 載入資料
- }, [main_system_tag, sub_system_tag, selectedBuiTag]);
+ }, [main_system_tag, sub_system_tag]);
+
+ // 只顯示指定的設備
+ // 取得所有 forge dbid
+ const getAllDbIds = (model) => {
+ const instanceTree = model.getInstanceTree();
+ const allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
+ return allDbIdsStr.map(id => parseInt(id));
+ }
+ useEffect(() => {
+ if (model && selectedDeviceList.length !== 0) {
+ console.log(model)
+ const allDbIds = getAllDbIds(model)
+ viewer.hide(allDbIds)
+ const showDbIds = selectedDeviceList.map((d) => parseInt(d.forge_dbid))
+ let showNodeDbId = [];
+ selectedDeviceList.forEach(({ device_nodes }) => {
+ showNodeDbId = [...showNodeDbId, ...device_nodes.map(({ forge_dbid }) => forge_dbid)]
+ })
+ viewer.show([...showDbIds, ...showNodeDbId])
+ }
+ }, [model, selectedDeviceList])
+
return (
<>
-
- {selectedDeviceList.map(({ device_guid, full_name, forge_dbid }) => (
-
+ {selectedDeviceList.map(({ device_guid, full_name, forge_dbid, device_floor }) => (
+ device_floor === floor_tag ?
+
@@ -77,13 +101,14 @@ function Monitor() {
功率 kW
詳細內容
-
+ :
+ <>>
))}
@@ -91,7 +116,7 @@ function Monitor() {
)}
-
+
diff --git a/ibms_react/src/reportWebVitals.js b/ibms_react/src/reportWebVitals.js
deleted file mode 100644
index 5253d3a..0000000
--- a/ibms_react/src/reportWebVitals.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const reportWebVitals = onPerfEntry => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
- getCLS(onPerfEntry);
- getFID(onPerfEntry);
- getFCP(onPerfEntry);
- getLCP(onPerfEntry);
- getTTFB(onPerfEntry);
- });
- }
-};
-
-export default reportWebVitals;
diff --git a/ibms_react/src/routes/routes.js b/ibms_react/src/routes/routes.js
index d93b271..74b28df 100644
--- a/ibms_react/src/routes/routes.js
+++ b/ibms_react/src/routes/routes.js
@@ -20,8 +20,8 @@ const routes = [
/(?:(?:^|.*;\s*)JWT-Authorization\s*\=\s*([^;]*).*$)|^.*$/,
"$1",
);
- if (window.location.href.includes("localhost:3000") && !JWT_Authorization) {
console.log(JWT_Authorization);
+ if (window.location.href.includes("localhost:3000") && !JWT_Authorization) {
return redirect("/login");
} else if (window.location.href.includes("http://220.132.206.5") && !JWT_Authorization) {
const account = await setUserAccountByBaja();
diff --git a/ibms_react/src/setupTests.js b/ibms_react/src/setupTests.js
deleted file mode 100644
index 8f2609b..0000000
--- a/ibms_react/src/setupTests.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// jest-dom adds custom jest matchers for asserting on DOM nodes.
-// allows you to do things like:
-// expect(element).toHaveTextContent(/react/i)
-// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
diff --git a/ibms_react/src/stores/buildingSlice.js b/ibms_react/src/stores/buildingSlice.js
index 73bb081..272f5d6 100644
--- a/ibms_react/src/stores/buildingSlice.js
+++ b/ibms_react/src/stores/buildingSlice.js
@@ -16,7 +16,7 @@ const buildingSlice = createSlice({
buildingList: ["中凌大樓"],
urn_3D: "",
selectedBuiArea: "TPE",
- selectedBuiTag: "",
+ selectedBuiTag: "B1",
selectedBuiFullName: "",
errMsg: "",
},
diff --git a/ibms_react/src/stores/deviceListSlice.js b/ibms_react/src/stores/deviceListSlice.js
index 3ea2027..7571781 100644
--- a/ibms_react/src/stores/deviceListSlice.js
+++ b/ibms_react/src/stores/deviceListSlice.js
@@ -3,6 +3,7 @@ import axios from "axios";
import { deviceBuiMenuBaseUrl, deviceListBaseUrl, deviceFloorBaseUrl } from "@CON";
import { ajaxRes } from "@UTIL";
+// 獲取小類中總覽資料
export const fetchSelectedDeviceMenu = createAsyncThunk(
"deviceList/fetchSelectedDeviceMenu",
async ({ main_system_tag, sub_system_tag }, thunkAPI) => {
@@ -29,14 +30,12 @@ export const fetchSelectedDeviceList = createAsyncThunk(
if (code !== "0000" || !data) {
return rejectWithValue(msg);
} else {
- console.log(data)
let results=[];
data.forEach((p) => {
p.device_list.forEach((d) => {
results.push({ ...d, device_floor: p.full_name });
});
});
- console.log("v", [...results]);
return fulfillWithValue([...results]);
}
},
@@ -66,16 +65,30 @@ const deviceListSlice = createSlice({
selectedDeviceMaster: "", // BANK1
selectedDeviceLastName: "", // ELEV
selectedDeviceSerialTag: "", // N1
+ tempsensorDevList: [],
},
reducers: {
- getAllDevice: (state, action) => {},
+ getAllDevice: (state, action) => { },
+ getCurDeviceTemp: (state, { payload }) => {
+ const { device_number, temp } = payload;
+ state.tempsensorDevList = state.tempsensorDevList.map((sensor) => {
+ if (sensor.some(s => s.device_number == device_number)) {
+ return { ...sensor, temp }
+ }
+ return sensor
+ })
+ },
+ changeMainSubSys: (state, { payload }) => {
+ const { main_system_tag, sub_system_tag } = payload;
+ state.selectedDeviceSysTag = main_system_tag;
+ state.selectedDeviceNameTag = sub_system_tag;
+ }
},
extraReducers: (builder) => {
builder.addCase(fetchSelectedDeviceMenu.fulfilled, (state, { payload }) => {
state.selectedDeviceMenu = payload;
});
builder.addCase(fetchSelectedDeviceList.fulfilled, (state, { payload }) => {
- console.log("de", payload);
state.selectedDeviceList = payload;
});
@@ -88,5 +101,5 @@ const deviceListSlice = createSlice({
});
const { reducer, actions } = deviceListSlice;
-export const { getAllDevice } = actions;
+export const { getCurDeviceTemp, changeMainSubSys } = actions;
export default reducer;
diff --git a/ibms_react/src/stores/forgeSlice.js b/ibms_react/src/stores/forgeSlice.js
index d7afdfc..2ce9870 100644
--- a/ibms_react/src/stores/forgeSlice.js
+++ b/ibms_react/src/stores/forgeSlice.js
@@ -6,7 +6,7 @@ export const fetchForge = createAsyncThunk(
async ({ viewerEl, urn }, { dispatch, fulfillWithValue, rejectWithValue }) => {
const res = await forgeInit(viewerEl);
if (res.ok) {
- modelLoad(res.viewer, urn, dispatch);
+ await modelLoad(res.viewer, urn, dispatch);
return fulfillWithValue(res.viewer);
} else {
return rejectWithValue(res.errCode);
@@ -18,8 +18,10 @@ const forgeSlice = createSlice({
name: "forge",
initialState: {
viewer: null,
+ model: null,
dataVizExtn: null,
DataVizCore: null,
+ structureInfo: null,
errCode: 0,
urn_3D: "",
},
@@ -27,6 +29,14 @@ const forgeSlice = createSlice({
loadDataVizExtn: (state, { payload }) => {
state.dataVizExtn = payload;
state.DataVizCore = window.Autodesk.DataVisualization.Core;
+ // heatmap
+ state.structureInfo = new window.Autodesk.DataVisualization.Core.ModelStructureInfo(state.model);
+ },
+ loadStructureInfo: (state, { payload }) => {
+ state.structureInfo = payload
+ },
+ loadModel: (state, { payload }) => {
+ state.model = payload
},
shutdownForge: (state, action) => {
state.viewer?.finish();
@@ -46,5 +56,5 @@ const forgeSlice = createSlice({
});
const { reducer, actions } = forgeSlice;
-export const { shutdownForge, loadDataVizExtn } = actions;
+export const { shutdownForge, loadDataVizExtn, loadModel } = actions;
export default reducer;
diff --git a/ibms_react/src/stores/index.js b/ibms_react/src/stores/index.js
index fbf58e2..218f28a 100644
--- a/ibms_react/src/stores/index.js
+++ b/ibms_react/src/stores/index.js
@@ -5,8 +5,10 @@ import device, {
fetchSelectedDeviceList,
fetchSelectedDeviceMenu,
fetchSelectedDevFlTags,
+ getCurDeviceTemp,
+ changeMainSubSys,
} from "./deviceListSlice";
-import forgeViewer, { fetchForge, loadDataVizExtn, shutdownForge } from "./forgeSlice";
+import forgeViewer, { fetchForge, loadDataVizExtn, loadModel, shutdownForge } from "./forgeSlice";
import system, { fetchSysMainSub } from "./systemSlice";
import user, { fetchUserInfo, fetchUserAuthPages } from "./userSlice";
import alarm, { fetchBuiAlarmStateByBaja } from "./alarmSlice";
@@ -40,16 +42,25 @@ export default store;
export {
fetchBuiList,
changeBuilding,
+
fetchSelectedDeviceList,
fetchSelectedDeviceMenu,
fetchSelectedDevFlTags,
+ getCurDeviceTemp,
+ changeMainSubSys,
+
fetchForge,
loadDataVizExtn,
+ loadModel,
shutdownForge,
+
fetchSysMainSub,
+
fetchUserInfo,
fetchUserAuthPages,
+
fetchBuiAlarmStateByBaja,
+
fetchInitElecMeterByBaja,
getElectricMeter,
getHourElectricMeter,
diff --git a/ibms_react/src/utils/baja/alarmBaja.js b/ibms_react/src/utils/baja/alarmBaja.js
index e50c395..5bd672c 100644
--- a/ibms_react/src/utils/baja/alarmBaja.js
+++ b/ibms_react/src/utils/baja/alarmBaja.js
@@ -14,7 +14,8 @@ export async function getBuiAlarmStateByBaja(area_tag, building_tag) {
const { msgText, sourceName } = this.get("alarmData").$map.$map;
const { $enc: ackState } = this.get("ackState").getType();
const { $enc: sourceState } = this.get("sourceState").getType();
- if (ackState !== "acked" && sourceState !== "normal") {
+ // 在選單上的顯示警告,只須出現在緊急的 offnormal 設備
+ if (sourceState !== "normal") {
result.push({
msgText,
sourceName,
diff --git a/ibms_react/src/utils/baja/bajaUtil.js b/ibms_react/src/utils/baja/bajaUtil.js
new file mode 100644
index 0000000..c3c1d30
--- /dev/null
+++ b/ibms_react/src/utils/baja/bajaUtil.js
@@ -0,0 +1,12 @@
+export function PointSubscribe(baja, sub, ordPath, pointName) {
+ // ord nq\I
+ baja.Ord.make(`local:|foxs:|station:|slot:/${ordPath}`)
+ .get()
+ .then(folder => {
+ folder.getSlots().is("control:NumericWritable").eachValue((point) => {
+ if (point.getDisplayName() === pointName) {
+ baja.Ord.make(`local:|foxs:|station:|slot:/${ordPath}/${pointName}`).get({ subscriber: sub })
+ }
+ })
+ })
+}
\ No newline at end of file
diff --git a/ibms_react/src/utils/baja/deviceBaja.js b/ibms_react/src/utils/baja/deviceBaja.js
index 9a6bfde..022a513 100644
--- a/ibms_react/src/utils/baja/deviceBaja.js
+++ b/ibms_react/src/utils/baja/deviceBaja.js
@@ -1,26 +1,35 @@
+import { getCurDeviceTemp } from "@STORE"
+import { roundDecimal } from "@UTIL";
// 訂閱設備
// 針對數值的點位
-export function SubscribeDeviceByBaja(ord) {
+export function SubscribeDeviceTempByBaja(ordPath, dispatch) {
window.require &&
window.requirejs(["baja!"], (baja) => {
console.log("進入 bajaSubscriber 準備執行BQL訂閱");
- const sub = new baja.subscriber();
- sub.attach("changed", (prop, cx) => {
- console.log(prop, cx);
- });
+ const sub = new baja.Subscriber();
+ function passValueToFront(temp) {
+ dispatch(getCurDeviceTemp({ device_number: ordPath, temp }))
+ }
+ sub.attach("changed", (prop) => {
+ if (prop && prop.$displayName === "Out") {
+ passValueToFront(prop.$getValue().getValueDisplay())
+ }
+ })
+ sub.attach("subscribed", (prop) => {
+ if (prop && prop.$displayName === "Out") {
+ passValueToFront(prop.$getValue().getValueDisplay())
+ }
+ })
// ord 為要訂閱的點位
- baja.Ord.make(ord)
- .get({
- subscriber: sub,
- // cursor 對返回的數據做處理
- cursor: {
- before: function () {},
- each: function () {},
- after: function () {},
- },
+ // ord 為要訂閱的點位
+ baja.Ord.make(`local:|foxs:|station:|slot:/${ordPath}`)
+ .get()
+ .then(folder => {
+ folder.getSlots().is("control:NumericWritable").eachValue((point) => {
+ if (point.getDisplayName() === "Temp" || point.getDisplayName() === "TEMP") {
+ baja.Ord.make(`local:|foxs:|station:|slot:/${ordPath}/${point.getDisplayName()}`).get({ subscriber: sub })
+ }
+ })
})
- .then((point) => {
- console.log(point);
- });
- });
+ })
}
diff --git a/ibms_react/src/utils/baja/electricityBaja.js b/ibms_react/src/utils/baja/electricityBaja.js
index 0169525..d39604f 100644
--- a/ibms_react/src/utils/baja/electricityBaja.js
+++ b/ibms_react/src/utils/baja/electricityBaja.js
@@ -89,30 +89,34 @@ export async function getCurPower(ordPath, dispatch) {
window.require &&
window.require(["baja!"], function (baja) {
const sub = new baja.Subscriber();
- sub.attach("changed", function (prop) {
- const value = roundDecimal(this.get("out").getValue());
+ function passValueToFront(value) {
+ const newValue = roundDecimal(value);
dispatch(
getCurElectricity([
- { data: value, text: "即時功率 " },
- { data: roundDecimal(value / 4), text: "即時契約容量占比 " },
+ { data: newValue, text: "即時功率 " },
+ { data: roundDecimal(newValue / 4), text: "即時契約容量占比 " },
]),
);
+ }
+ sub.attach("changed", function (prop) {
+ if (prop && prop.$displayName === "Out") {
+ passValueToFront(prop.$getValue().getValueDisplay())
+ }
+ })
+ sub.attach("subscribed", function (prop) {
+ if (prop && prop.$displayName === "Out") {
+ passValueToFront(prop.$getValue().getValueDisplay())
+ }
});
+ // ord 為要訂閱的點位
baja.Ord.make(`local:|foxs:|station:|slot:/${ordPath}`)
.get()
- .then((folder) => {
- folder
- .getSlots()
- .is("control:NumericWritable")
- .eachValue((point) => {
- if (point.getDisplayName() === "P") {
- baja.Ord.make(
- `local:|foxs:|station:|slot:/TPE/B1/EE/E4/R2F/NA/WHT/N1/${point.getDisplayName()}`,
- ).get({
- subscriber: sub,
- });
- }
- });
- });
+ .then(folder => {
+ folder.getSlots().is("control:NumericWritable").eachValue((point) => {
+ if (point.getDisplayName() === "P") {
+ baja.Ord.make(`local:|foxs:|station:|slot:/${ordPath}/${point.getDisplayName() }`).get({ subscriber: sub })
+ }
+ })
+ })
});
}
diff --git a/ibms_react/src/utils/baja/index.js b/ibms_react/src/utils/baja/index.js
index e587455..d14d4f5 100644
--- a/ibms_react/src/utils/baja/index.js
+++ b/ibms_react/src/utils/baja/index.js
@@ -1,5 +1,5 @@
import { getBuiAlarmStateByBaja, getDeviceAlarmByBaja } from "./alarmBaja";
-import { SubscribeDeviceByBaja } from "./deviceBaja";
+import { SubscribeDeviceTempByBaja } from "./deviceBaja";
import { getTotalElectricByBaja, getCurPower } from "./electricityBaja";
// 下載 N4 內置requireJS
function loadRequireJS() {
@@ -25,10 +25,14 @@ function setUserAccountByBaja(callBackFunc = null) {
export {
loadRequireJS,
+ // 使用者
setUserAccountByBaja,
+ // alarm
getBuiAlarmStateByBaja,
getDeviceAlarmByBaja,
- SubscribeDeviceByBaja,
+ // device
+ SubscribeDeviceTempByBaja,
+ // eletricity
getTotalElectricByBaja,
getCurPower,
};
diff --git a/ibms_react/src/utils/forge.js b/ibms_react/src/utils/forge.js
index c9ae377..f476416 100644
--- a/ibms_react/src/utils/forge.js
+++ b/ibms_react/src/utils/forge.js
@@ -1,5 +1,5 @@
import { forgeTokenBaseUrl } from "@CON";
-import { loadDataVizExtn } from "@STORE";
+import { loadDataVizExtn, loadModel } from "@STORE";
// 載入 forgeCss 樣式
function loadForgeCss(src) {
const link = document.createElement("link");
@@ -72,15 +72,19 @@ export function modelLoad(viewer, urn, dispatch) {
const documentId = `urn:${urn}`;
window.Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
- function onDocumentLoadSuccess(viewerDocument) {
+ async function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
- viewer.addEventListener(window.Autodesk.Viewing.GEOMETRY_LOADED_EVENT, async function () {
- // 取得所有 forge dbid
- const allDbIds = getAllDbIds(this);
- const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
- dispatch(loadDataVizExtn(dataVizExtn));
+ viewer.addEventListener(window.Autodesk.Viewing.GEOMETRY_LOADED_EVENT, async ()=> {
+ console.log(viewer.model)
+ dispatch(loadModel(viewer.model))
+ // sprites
+ const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
+ dispatch(loadDataVizExtn(dataVizExtn));
+ // heatmap
+ //const structureInfo = new window.Autodesk.DataVisualization.Core.ModelStructureInfo(viewer.model);
+ //dispatch(loadStructureInfo(structureInfo));
});
}
@@ -89,13 +93,4 @@ export function modelLoad(viewer, urn, dispatch) {
}
}
-// 取得 forge dbid
-function getAllDbIds(viewer) {
- var instanceTree = viewer.model?.getData().instanceTree;
- var allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
-
- return allDbIdsStr.map(function (id) {
- return parseInt(id);
- });
-}
diff --git a/ibms_react/src/utils/index.js b/ibms_react/src/utils/index.js
index 5a408e8..f5fb894 100644
--- a/ibms_react/src/utils/index.js
+++ b/ibms_react/src/utils/index.js
@@ -1,9 +1,13 @@
import {
loadRequireJS,
+ // ϥΪ
setUserAccountByBaja,
+ // alarm
getBuiAlarmStateByBaja,
getDeviceAlarmByBaja,
- SubscribeDeviceByBaja,
+ // device
+ SubscribeDeviceTempByBaja,
+ // eletricity
getTotalElectricByBaja,
getCurPower,
} from "./baja/index";
@@ -14,10 +18,14 @@ import { userLogin } from "./login";
import { roundDecimal } from "./math";
export {
loadRequireJS,
+ // ϥΪ
setUserAccountByBaja,
+ // alarm
getBuiAlarmStateByBaja,
getDeviceAlarmByBaja,
- SubscribeDeviceByBaja,
+ // device
+ SubscribeDeviceTempByBaja,
+ // eletricity
getTotalElectricByBaja,
getCurPower,
forgeInit,