[前台] 新增環境感測器頁面

This commit is contained in:
Celeste 2023-02-13 09:25:47 +08:00
parent 3f718bb228
commit 05cee2fd87
3 changed files with 624 additions and 64 deletions

555
Frontend/_sysSensor.html Normal file
View File

@ -0,0 +1,555 @@
<style>
</style>
<div class="row">
<div id="leftDiv" class="col-sm-12 col-xl-6">
</div>
<div id="rightDiv" class="col-sm-12 col-xl-6">
</div>
</div>
<!-- Modal center Add -->
<div class="modal fade" id="lightSchModal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered" role="document" style="min-width:60%">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
燈控排程
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<!--<table id="lightSchTable" class="table table-bordered table-striped text-center m-0 w-100">
</table>-->
<div id="lightSchBlock" style="height:60vh"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">關閉</button>
<button type="button" id="lightSchSavBtn" class="btn btn-primary">儲存</button>
</div>
</div>
</div>
</div>
<script>
var allDevList = []; //全設備清單
var subDeviceData = [];
var heatMap = null;
var buildMenuData = {};
var forgeInvType = null;
var forgeInvTypeDef = null;
$(function () {
getBuildMenu((arr, data) => {
buildMenuData = data;
if (arr.indexOf(4) != -1) {
getFloDevList(arr[0] == 4 ? "left" :"right");
setLightColor();
}
if (arr.indexOf(3) != -1) {
getHotspotPoint(() => {
show3DModel(data.urn_3D);
getInviForge();
});
}
});
})
// 依據 drawing type 決定呈現畫面
function getHtmlByType(type = 0, data = {}) {
let strHtml = ``;
switch (type) {
case 2:
strHtml = `<div style="height:85vh">
<iframe src="${data.system_url}" width="100%" height="100%"></iframe>
</div>`;
break;
case 4:
strHtml = `<div class="d-flex mb-4" style="gap:15px">
${setTopLight()}
</div>
<div class="col-12 p-0" id="floDevList">
</div>`;
break;
case 3:
strHtml = `<div class="d-flex mb-4" style="gap:15px">
${setTopHeatBar()}
</div>
<div name="forgeViewer" style="height:85vh;"></div>`;
break;
}
return strHtml;
}
//baja 訂閱設備
function subDevice() {
let myBaja = new subscriptionDevices();
var ordPath = {
"area_tag": pageAct.AreaTag,
"building_tag": pageAct.buiTag,
"system_tag": pageAct.sysMainTag,
"name_tag": pageAct.sysSubTag,
}
myBaja.setSubscribeDevicesByBql(ordPath);
myBaja.setSubscribeDevicesCallBack(function (data) {
let matchDevice = allDevList.filter(x => x.device_number == data.device_number_full)[0];
if (!matchDevice) {
return false;
}
//將訂閱值塞入 subDeviceData
if (subDeviceData.findIndex(x => x.device_number == matchDevice.device_number) == -1) {
let obj = {};
obj.device_number = matchDevice.device_number;
obj.dbid = matchDevice.forge_dbid;
subDeviceData.push(obj)
}
let subData = subDeviceData.filter(x => x.device_number == matchDevice.device_number)[0];
if (subData) {
subData[data.point_name] = data.value;
}
let norDevPoiName = matchDevice.device_normal_point_name;
let cloDevPoiName = matchDevice.device_close_point_name;
let errDevPoiName = matchDevice.device_error_point_name;
if (data.point_name == "Temp") {
heatMap?.changeTemp(data.device_number_full, !isNaN(parseInt(data.value)) ? parseInt(data.value) : 0);
let devIdx = allDevList.findIndex(x => x.device_number == data.device_number_full);
allDevList[devIdx]._temp = !isNaN(parseInt(data.value)) ? parseInt(data.value) : 0;
}
if (data.point_name == norDevPoiName && data.value == matchDevice.device_normal_point_value) {
//顯示正常燈號
$(`#${matchDevice.device_number}_status`).attr("data-light-type", "normal").data("light-type", "normal");
} else if (data.point_name == cloDevPoiName && data.value == matchDevice.device_close_point_value) {
$(`#${matchDevice.device_number}_status`).attr("data-light-type", "close").data("light-type", "close");
} else if (data.point_name == errDevPoiName && data.value == matchDevice.device_error_point_value) {
$(`#${matchDevice.device_number}_status`).attr("data-light-type", "error").data("light-type", "error");
}
setLightColor();
setForgeHotSpotColor(matchDevice);
lightDevForgeSpotLig(matchDevice)
// 從設備訂閱更新每個設備卡片即時點位
setDevItemPoiValBySub(data);
});
myBaja.setSubscribeDeviceEndCallBack(function (data) {
endPageLoading();
if (data.findIndex(x => x.point_name == "Temp") != -1) {
// 顯示溫度條
showHeat("[name=forgeHeatBar]");
}
});
}
function lightDevForgeSpotLig(devObj) {
}
// 從設備訂閱更新每個設備卡片即時點位
function setDevItemPoiValBySub(data) {
let pointSpan = $(`.card.device-wrap[data-number=${data.device_number_full}] span[name=devItemPoiVal]`);
if (pointSpan && pointSpan.data("point") == data.point_name) {
console.log(data)
pointSpan.text(data.value);
}
}
function setLightColor() {
$("[data-light-type]").each((index, ele) => {
let type = $(ele).data("light-type");
let isFlashing = false;
let color = "#000";
switch (type) {
case "normal":
color = pageAct.sysSubObj.device_normal_color ?? "var(--theme-success)";
isFlashing = pageAct.sysSubObj.device_normal_flashing == "1";
break;
case "close":
color = pageAct.sysSubObj.device_close_color ?? "var(--theme-secondary)";
isFlashing = pageAct.sysSubObj.device_close_flashing == "1";
break;
case "error":
color = pageAct.sysSubObj.device_error_color ?? "var(--theme-danger)";
isFlashing = pageAct.sysSubObj.device_error_flashing == "1";
break;
}
$(ele).css("background-color", color);
//是否閃爍
if (isFlashing) {
$(ele).parents(".card.device-wrap").addClass("light-flash");
} else {
$(ele).parents(".card.device-wrap").removeClass("light-flash");
}
})
}
// 設置昇位圖上方 燈號
function setTopLight() {
let sysSubObj = pageAct.sysSubObj;
let strHtml = ``;
if (sysSubObj.device_normal_point_name != null && sysSubObj.device_normal_point_value != null) {
strHtml += ` <div class="row m-0 align-items-center">
<span id="sysNorLight" class="circle-light mr-2 " data-light-type="normal"></span>
<label class="mb-0">${sysSubObj.device_normal_text}</label>
</div>`;
}
if (sysSubObj.device_close_point_name != null && sysSubObj.device_close_point_value != null) {
strHtml += ` <div class="row m-0 align-items-center">
<span id="sysCloLight" class="circle-light mr-2" data-light-type="close"></span>
<label class="mb-0">${sysSubObj.device_close_text}</label>
</div>`;
}
if (sysSubObj.device_error_point_name != null && sysSubObj.device_error_point_value != null) {
strHtml += ` <div class="row m-0 align-items-center">
<span id="sysErrLight" class="circle-light mr-2" data-light-type="error"></span>
<label class="mb-0">${sysSubObj.device_error_text}</label>
</div>`;
}
return strHtml;
}
function setLightSchBlcok(obj) {
let devNum = $(obj).parents(".device-wrap").data("number");
let devPath = devNum.replaceAll("_", "/");
let iframe = `<iframe src="/ord?station:%7Cslot:/${devPath}/Sch|view:?fullScreen=true" style="min-height:100px;width:100%;height:100%"></iframe>`
$("#lightSchBlock").html(iframe);
}
// forge 3D 異常點位變紅色
function setForgeHotSpotColor(device) {
let subData = subDeviceData.filter(x => x.device_number == device.device_number)[0]
if (subData && subData[device.device_error_point_name] == device.device_error_point_value && !isNaN(parseInt(device.spriteDbid))) {
changeColorForHotspot(parseInt(device.spriteDbid), "error");
}
}
// 取得昇位圖點位 (deviceItem)
function getRiserPoiObj() {
let tarDevItem = pageAct.devItems?.filter(x => x.is_show_riserDiagram == 1);
if (tarDevItem && tarDevItem[0]) {
return tarDevItem[0];
}
return null;
}
// 取得設備列表 並繪製卡片
function getFloDevList(position = "left") {
let url = baseApiUrl + "/api/Device/GetDeviceList";
let sendData = {
sub_system_tag: pageAct.sysSubTag,
building_tag: pageAct.buiTag,
floor_tag: pageAct.floTag,
};
objSendData.Data = sendData;
ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
if (!res || res.code != "0000" || !res.data) {
} else {
let strHtml = ``;
$.each(res.data, (index, floObj) => {
strHtml += `<div class='d-flex justify-content-start mb-5 ' style="">`
strHtml += `<button id="floItemBtn${floObj.full_name}" type="button" class="btn btn-primary waves-effect waves-themed mr-5 mt-1 align-self-start" >${floObj.full_name}</button>`
strHtml += `<div class="col p-0 d-grid grid-gap-5 grid-temp-col-c" style="--c-grid-temp-col:repeat(auto-fill,minmax(250px,1fr))">`
$.each(floObj.device_list, (index2, devObj) => {
allDevList.push(devObj);
let devItem = getRiserPoiObj();
strHtml += `<div class="card m-1 border device-wrap" data-number="${devObj.device_number}" data-position="${position}">
<div class="card-body p-2">
<div class="d-flex mb-2">
<div class="mr-5 cur-poi">
<span class="d-inline-block mr-3">
<img src="${baseImgUrl + varPathDevIcon + devObj.device_image}" class="profile-image rounded-circle" onerror="defDev(this)" alt="...">
</span>
<a name="devItemName" data-number="${devObj.device_number}" href="javascript:;">${devObj.full_name}</a>
</div>
</div>
<div class="d-flex mb-0 mt-2 align-items-center">
<span id="${devObj.device_number}_status" class="circle-light"></span>
<span class="${devItem ? "" : "d-none"} ml-2">${devItem?.full_name}<span name="devItemPoiVal" data-point="${devItem?.points}"></span>${devItem?.unit}</span>
<a href="javascript:;" name="devItem" data-id="${devObj.device_guid}" data-number="${devObj.device_number}" data-name="${devObj.full_name}" class=" ml-2 mb-0 ">詳細資料</a>
</div>
</div>
</div>`;
})
strHtml += "</div></div>";
})
// Niagara 產生 file 開頭字串問題
strHtml = strHtml.replaceAll(`src="/file/`, `src="`);
if (!res.data || res.data.length == 0) {
endPageLoading();
} else {
// 訂閱 baja 設備
subDevice();
}
// 繪製 html
$("#floDevList").append(strHtml);
// 存入 device 基本資料至元素 data 屬性
$("#floDevList a[name=devItem]").each((idx, ele) => {
if (allDevList.findIndex(x => x.device_number == $(ele).data("number")) != -1) {
$(ele).data("devobj", allDevList.filter(x => x.device_number == $(ele).data("number"))[0]);
}
})
// 初始化 pop 視窗
initPopover();
// 卡片設備名稱點擊事件
devItemNameEvent();
}
}, null, "POST").send();
}
function getBuildMenu(callback = null) {
let url = baseApiUrl + "/api/Device/GetBuildMenu";
let sendData = {
main_system_tag: pageAct.sysMainTag,
sub_system_tag: pageAct.sysSubTag,
building_tag: pageAct.buiTag,
};
objSendData.Data = sendData;
ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
if (!res || res.code != "0000" || !res.data) {
} else {
let leftData = {}, rightData = {};
for (var key in res.data) {
if (key.startsWith("left")) {
leftData[key.split("left_")[1]] = res.data[key];
} else if (key.startsWith("right")) {
rightData[key.split("right_")[1]] = res.data[key];
}
}
if (res.data.left_drawing != null) {
$("#leftDiv").html(getHtmlByType(res.data.left_drawing, leftData));
} else {
$("#leftDiv").html(getHtmlByType(0, leftData));
}
if (res.data.right_drawing != null) {
$("#rightDiv").html(getHtmlByType(res.data.right_drawing), rightData);
} else {
$("#rightDiv").html(getHtmlByType(0, rightData));
}
callback ? callback([res.data.left_drawing, res.data.right_drawing], res.data) : "";
}
}, null, "POST").send();
}
// Card 即時狀態
function drawStateTabBlo(devNum) {
let devPath = devNum.replaceAll("_", "/");
let position = $(`.card.device-wrap[data-number=${devNum}]`).data("position");
let width = buildMenuData[position + "_icon_click_url_width"] ? buildMenuData[position + "_icon_click_url_width"] + "px" : "100%";
let height = buildMenuData[position + "_icon_click_url_height"] ? buildMenuData[position + "_icon_click_url_height"] + "px" : "100%";
let strHtml = `<div style="height:100%;width:100%">
<iframe src="/ord?station:%7Cslot:/${devPath}|view:?fullScreen=true" style="width:${width};height:${height};min-height:100px;"></iframe>
</div>`
return strHtml;
}
function iframeResize(obj) {
obj.style.height = obj.contentWindow.document.documentElement.scrollHeight + 'px';
}
function show3DModel(urn) {
$(loadEle).Loading("start");
launchViewerForHotspot(urn, (viewer, nodeIds) => {
addHotPoint(viewer)
let devDbIds = allDevList.map(x => x.forge_dbid);
const devices = allDevList.forEach((device) => {
const sensorObj = new Forge3DSensor({
viewer: viewer,
ordPath: {
"area_tag": pageAct.AreaTag,
"building_tag": pageAct.buiTag,
},
curDevice: {
roomDbId: !isNaN(parseInt(device.room_dbid)) ? parseInt(device.room_dbid) : -1,
id: device.device_number,
position: isJSON(device.device_coordinate_3d) ? JSON.parse(device.device_coordinate_3d) : {}, // x: 0, y: 25, z: -2.5 (3.35, -4.81, 12.88
temp: 25,
forge_dbid: parseInt(device.forge_dbid)
}
});
})
// 從資料庫設定不可視模型的類型,若沒有取道該小類不可視類型,則套用資料庫設定預設類型
if (forgeInvType) {
setInviForge(forgeInvType, devDbIds);
} else {
setInviForge(forgeInvTypeDef, devDbIds);
}
$(loadEle).Loading("close");
let elevOption = {
selector: "[name=forgeViewer]",
viewer: viewer,
ordPath: {
"area_tag": pageAct.AreaTag,
"building_tag": pageAct.buiTag,
},
}
// 電梯移動訂閱程序載入
let forge3DElev = new Forge3DElevFull(elevOption);
forge3DElev.bajaEndCallback = function () {
endPageLoading();
}
forge3DElev.init();
if (subDeviceData.length != 0) {
let stSubArr = subDeviceData.map(x => Object.keys(x).filter(y => y == "ST").map(y => x));
for (let sub of stSubArr) {
let matchDevice = allDevList.filter(x => x.device_number == sub[0]?.device_number)[0];
if (matchDevice) {
setForgeHotSpotColor(matchDevice);
}
}
}
getWaterNodeId();
}, () => {
$(loadEle).Loading("close");
}, "[name=forgeViewer]");
}
function getHotspotPoint(callback = null) {
let url = baseApiUrl + "/api/GetDevForCor";
let sendData = {
"device_area_tag": pageAct.AreaTag,
"device_building_tag": pageAct.buiTag,
"device_system_tag": pageAct.sysMainTag,
"device_name_tag": pageAct.sysSubTag,
};
objSendData.Data = sendData;
ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
if (!res || res.code != "0000" || !res.data) {
} else {
let myDataList = [];
$.each(res.data, (idx, data) => {
let item = {};
item.position = {};
if (data.device_coordinate_3d != null && isJSON(data.device_coordinate_3d)) {
item.position = JSON.parse(data.device_coordinate_3d);
}
$.extend(item, data);
myDataList.push(item);
})
setHotspotPoint(myDataList);
if (pageAct.sysMainTag == "LT") {
setLightPoint(myDataList);
}
callback ? callback() : "";
}
}, null, "POST").send();
}
function setHotspotPoint(myDataList = []) {
console.log(myDataList)
getHopspotPoint(myDataList);
}
function setLightPoint(myDataList = []) {
console.log(myDataList)
getLightData(myDataList);
}
// 取得 不可視 3D 模型類型
function getInviForge() {
let url = baseApiUrl + "/api/Device/GetForgeInvType";
ytAjax = new YourTeam.Ajax(url, null, function (res) {
if (!res || res.code != "0000" || !res.data) {
} else {
let datas = res.data;
forgeInvType = datas.filter(x => x.sub_system_tag == pageAct.sysSubTag)[0]?.invisible_value;
forgeInvTypeDef = datas.filter(x => x.invisible_type == "default_value")[0]?.invisible_value;
}
}, null, "POST").send();
}
// 設置 模型隱藏或透明
function setInviForge(type, devDbIds) {
console.log("devDbIds",devDbIds)
if (type == "Hide") {
hideAllObjects(devDbIds);
} else if (type == "Opacity") {
setTransparentBuilding(0, devDbIds);
}
}
var parentEle = "";
onEvent("autodesk:click:sprite", "[name=forgeViewer]", function (e, obj) {
forgeUnFocusAll();
let position = [obj.event.target.toolController.lastClickX, obj.event.target.toolController.lastClickY];
let devObj = obj.myData;
let name = allDevList.filter(x => x.device_guid == devObj.device_guid)[0]?.full_name;
devObj.full_name = name;
parentEle = crePosPopover(position, devObj);
$(parentEle).click();
})
onEvent("autodesk:clickOut:sprite", "[name=forgeViewer]", function (e) {
$(parentEle).YTTooltip("hide");
})
onEvent("autodesk:complete:sprite", "[name=forgeViewer]", function (e, obj) {
$("#floDevList a[name=devItem]").each((idx, ele) => {
let devNum = $(ele).data("number");
let dbid = obj.myDataList.filter(x => x.device_number == devNum)[0]?._dbId;
allDevList.forEach((dev, idx) => {
if (dev.device_number == devNum) {
dev.spriteDbid = dbid;
setForgeHotSpotColor(dev);
}
})
$(ele).data("dbId", dbid);
})
})
onEvent("yt:tooltip:show", "[name=devItem]", function (e, obj) {
forgeUnFocusAll();
})
function forgeUnFocusAll() {
$("#floDevList a[name=devItem]").each((idx, ele) => {
controlFocusHotspot($(ele).data("dbId"), false);
})
}
</script>

View File

@ -870,7 +870,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
if (isJSON(sessionStorage.getItem("pageAct"))) { if (isJSON(sessionStorage.getItem("pageAct"))) {
lastPageAct = JSON.parse(sessionStorage.getItem("pageAct")); lastPageAct = JSON.parse(sessionStorage.getItem("pageAct"));
} }
if ((lastPageAct.sysSubTag && lastPage == "systemMonitor") || lastPage == "sysElevator") { if ((lastPageAct.sysSubTag && lastPage == "systemMonitor") || lastPage == "sysElevator" || lastPage == "sysSensor") {
$(`#subSysBtn${lastPageAct.sysSubTag}`).click(); $(`#subSysBtn${lastPageAct.sysSubTag}`).click();
$("#sysMonTopBtn").YTTab("set"); $("#sysMonTopBtn").YTTab("set");
} else { } else {
@ -946,7 +946,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
if (!page) { if (!page) {
return; return;
} }
if (page != "systemMonitor" && page != "sysElevator") { if (page != "systemMonitor" && page != "sysElevator" && page != "sysSenesor") {
$("#sysMonBtnList [name=topFunBtn]").removeClass("active"); $("#sysMonBtnList [name=topFunBtn]").removeClass("active");
pageAct.sysMainTag = null; pageAct.sysMainTag = null;
pageAct.sysSubTag = null; pageAct.sysSubTag = null;
@ -1626,6 +1626,10 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
if (subSysObj.sub_system_tag == "EL") { if (subSysObj.sub_system_tag == "EL") {
page = "sysElevator"; page = "sysElevator";
} }
console.log(subSysObj.sub_system_tag)
if (subSysObj.sub_system_tag == "M12") {
page = "sysSensor";
}
let li = creEle("li"); let li = creEle("li");
let a = creA(subSysObj.full_name, { "href": "javascript:;" }, [], `subSysBtn${subSysObj.sub_system_tag}`, { page: page, tabname: "systemMonitor" }, "topFunBtn"); let a = creA(subSysObj.full_name, { "href": "javascript:;" }, [], `subSysBtn${subSysObj.sub_system_tag}`, { page: page, tabname: "systemMonitor" }, "topFunBtn");

View File

@ -301,8 +301,9 @@ body:not(.mod-skin-light):not(.mod-skin-dark) #skin-default:before {
color: #bdbdbd; } color: #bdbdbd; }
.mod-skin-dark:not(.mod-skin-light) .page-content-wrapper a:not(.btn):not(.badge):not(.dropdown-item):not(.nav-link):not(.navbar-brand):not(.card-title):not([class*="fc-"]):not([class*="text-"]):not(.btn-search-close), .mod-skin-dark:not(.mod-skin-light) .page-content-wrapper a:not(.btn):not(.badge):not(.dropdown-item):not(.nav-link):not(.navbar-brand):not(.card-title):not([class*="fc-"]):not([class*="text-"]):not(.btn-search-close),
.mod-skin-dark:not(.mod-skin-light) .modal-body a:not(.btn):not(.badge):not(.dropdown-item):not(.nav-link):not(.page-link):not(.navbar-brand):not(.card-title) { .mod-skin-dark:not(.mod-skin-light) .modal-body a:not(.btn):not(.badge):not(.dropdown-item):not(.nav-link):not(.page-link):not(.navbar-brand):not(.card-title) {
color: #ffffff; /*color: #ffffff;*/
/*color: var(--theme-primary-200);*/ } color: var(--theme-primary-200);
}
.mod-skin-dark:not(.mod-skin-light) .text-success { .mod-skin-dark:not(.mod-skin-light) .text-success {
color: var(--theme-success-300) !important; } color: var(--theme-success-300) !important; }
.mod-skin-dark:not(.mod-skin-light) .text-danger { .mod-skin-dark:not(.mod-skin-light) .text-danger {