const _apiUri = '/api/vms/control'; let _listTable = null; let _selectedVideo = null; let _listData = null; let _listMap = new Map(); let _wcamIp = null; let _wcamCtrlBtn = null; const _userId = window.opener.$userId; let _selectedId = null; let _brghColumns = []; let _tempColumns = []; let _operCheckArr = []; let _onOfftimeArr = []; $(()=>{ creatBtn($('.close-btn'), null, '닫기', '닫기', 'outlined', () => window.close()); //VMS 전체조회 테이블 _listTable = $(".stts-table").width('100%').height('100%').dxDataGrid({ dataSource : null, allowColumnReordering : true, showColumnLines : true, showBorders : true, allowColumnResizing : true, rowAlternationEnabled : true, columnAutoWidth : true, focusedRowEnabled : true, noDataText : '표출할 정보가 없습니다.', // headerFilter: { // visible: true, // }, keyExpr : 'vms_ctlr_nmbr', paging: { enabled: false, pageSize: 1000, }, selection : { mode : 'multiple', showCheckBoxesMode : "onClick" }, scrolling: { mode: 'standard', }, columns:[ { caption : 'VMS 정보', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "vms_ctlr_nmbr", caption : "VMS 번호", alignment : "center", sortIndex : 0, sortOrder : "asc", width : 110, }, { dataField : "vms_ctlr_id", caption : "VMS ID", alignment : "center", }, { dataField : "vms_nm", caption : "VMS 명칭", alignment : "center", width : 130, cellTemplate(c,e){ c.css('text-align','left'); c.text(e.displayValue) } }, ] }, { caption : '통신', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "cmnc_stts_desc", caption : "통신", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'cmnc_stts_cd'); } }, ] }, { caption : '모듈', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "pwer_stts_desc", caption : "전원상태", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'pwer_stts_cd'); } }, ] }, { caption : '함체', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "cbox_door_stts_desc", caption : "도어", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'cbox_door_stts_cd'); } }, { dataField : "fan_stts_desc", caption : "팬상태", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'fan_stts_cd'); } }, { dataField : "hetr_stts_desc", caption : "히터상태", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'hetr_stts_cd'); } }, { dataField : "cbox_tmpr", caption : "온도", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'cbox_tmpr'); } }, { dataField : "brgh_val", caption : "화면휘도", alignment : "center", width : 80, cellTemplate(c,e){ return state(c, e, 'brgh_val'); } }, ] }, { caption : '메시지 표출', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "oper_mode_desc", caption : "운영모드", alignment : "center", width : 80, cellTemplate(c, e){ return operMode(c, e); } }, { dataField : "provide_time", caption : "제공시각", width : 150, alignment : "center", dataType : "datetime", format : "yyyy-MM-dd HH:mm:ss", }, { dataField : "provide_cnt", caption : "제공", width : 80, alignment : "center", }, ] }, ], onRowClick(info){ listTableClick(info); }, }).dxDataGrid("instance"); _tabs = $(".tabs").width('100%').height('100%').dxTabPanel({ dataSource : null, selectIndex : 0, loop : false, animationEnabled : true, swipeEnabled : false, noDataText : '표출할 정보가 없습니다.', itemTitleTemplate: function(e){ return $('
'+e.name+'
') }, itemTemplate: function(e, idx, c){ c.css('display', 'flex'); c.append(e.div); return c; }, }).dxTabPanel('instance'); fetchBaseData(); _wcamCtrlBtn = creatBtn($('.wcam_ctrl_btn'), 'preferences', '웹카메라 제어', '웹카메라 제어', 'outlined', wcamCtlrClick, null, true, true); }); function fetchBaseData(){ refreshListData(); let controlArr = controlDiv(); let operArr = operDiv(); let doorArr = cBoxDiv(); //let networkArr = networkDiv(); let dataSource = []; dataSource.push(controlArr); dataSource.push(operArr); dataSource.push(doorArr); //dataSource.push(networkArr); _tabs.option('dataSource', dataSource); }; function refreshListData() { let data = []; let baseData = []; let listData = []; getData('/api/vms/monitoring/stts', data); getData('/api/vms/manager/info', baseData); let formatData = null; _listMap = new Map(); if (data[0].length > 0) { data[0].map((item)=>{ if (item.updt_dt) { item.updt_dt = getParseDateTime(item.updt_dt); } item.auto = item.auto_used + '/' + item.auto_total; item.basic = item.basic_used + '/' + item.basic_total; item.fixed = item.fixed_used + '/' + item.fixed_total; if (item.provide_time) { item.provide_time = new Date(getParseDateTime(item.provide_time)); } _listMap.set(item.vms_ctlr_nmbr, item); }); } if (baseData[0].length > 0) { baseData[0].map((item)=>{ if (_listMap.get(item.vms_ctlr_nmbr)) { let formatData = {..._listMap.get(item.vms_ctlr_nmbr)} formatData.web_cmra_ip = item.web_cmra_ip; formatData.web_cmra_port = item.web_cmra_port; formatData.curr_step = item.brgh_curr_step; formatData.nght_step = item.brgh_nght_step; formatData.week_step = item.brgh_week_step; formatData.fan_run_tmpr = item.fan_run_tmpr; formatData.hetr_run_tmpr = item.hetr_run_tmpr; formatData.web_rtc_id = item.web_rtc_id; formatData.web_rtc_svr_ip = item.web_rtc_svr_ip; formatData.web_rtc_svr_port = item.web_rtc_svr_port; _listMap.set(item.vms_ctlr_nmbr, formatData); } }); formatData = Array.from(_listMap.values()); } _listTable.option('dataSource', formatData); } function controlDiv(){ const div = $('
'); div.html(`
현재 휘도값
( 0 ~ 100, 수동모드 일때 유효 )
주간 휘도값
( 0 ~ 100, 주간모드 일때 유효 )
야간 휘도값
( 0 ~ 100, 야간모드 일때 유효, 휘도모드가 자동일 경우 센서값에 따름 )
`); const onBtn = div.children().eq(0).children().eq(0).children().eq(0); const offBtn = div.children().eq(0).children().eq(1).children().eq(0); const softResBtn = div.children().eq(0).children().eq(2).children().eq(0); const hardResBtn = div.children().eq(0).children().eq(3).children().eq(0); const presNum = div.children().eq(1).children().eq(1).children().eq(0); const dayNum = div.children().eq(2).children().eq(1).children().eq(0); const nightNum = div.children().eq(3).children().eq(1).children().eq(0); const brghAutoBtn = div.children().eq(4).children().eq(0).children().eq(0); const brghSelfBtn = div.children().eq(4).children().eq(1).children().eq(0); const brghDayBtn = div.children().eq(4).children().eq(2).children().eq(0); const brghNightBtn = div.children().eq(4).children().eq(3).children().eq(0); _brghColumns = [ { number : null, position : presNum, showSpinButtons : true, text : '현재 휘도값', val : 80, column : 'curr_step', }, { number : null, position : dayNum, showSpinButtons : true, text : '주간 휘도값', val : 100, column : 'week_step', }, { number : null, position : nightNum, showSpinButtons : true, text : '야간 휘도값', val : 40, column : 'nght_step', } ] //체크박스 상자 옵션 const btnColumns = [ { btn : null, position : onBtn, text : '전광판 ON', alert : 'VMS 전광판 전원 ON', uri : '/power/', val : '0', }, { btn : null, position : offBtn, text : '전광판 OFF', alert : 'VMS 전광판 전원 OFF', uri : '/power/', val : '1', }, { btn : null, position : softResBtn, text : '소프트웨어 리셋', alert : 'VMS 제어기 소프트웨어 리셋', uri : '/reset/', val : '0', }, { btn : null, position : hardResBtn, text : '하드웨어 리셋', alert : 'VMS 제어기 하드웨어 리셋', uri : '/reset/', val : '1', }, { btn : null, position : brghAutoBtn, text : '휘도-자동 설정', alert : 'VMS 휘도-자동 설정', uri : '/luminance/', val : '2', brgh : true, }, { btn : null, position : brghSelfBtn, text : '휘도-수동 설정', alert : 'VMS 휘도-수동 설정', uri : '/luminance/', val : '9', brgh : true, }, { btn : null, position : brghDayBtn, text : '휘도-주간 설정', alert : 'VMS 휘도-주간 설정', uri : '/luminance/', val : '0', brgh : true, }, { btn : null, position : brghNightBtn, text : '휘도-야간 설정', alert : 'VMS 휘도-야간 설정', uri : '/luminance/', val : '1', brgh : true, }, ]; btnColumns.map((item)=>{ item.btn = new dxBtn(item.position, item.text, 'preferences', 'outlined', null, null, false, true); item.btn.onClick(() => controlEvent('전광판/제어기 제어 [ ' + item.text + ' ]', item)); }); _brghColumns.map((item)=>{ item.number = new dxNumber(item.position, 'outlined', 100, 30, 0, 100, item.showSpinButtons, item.val, null, '##0', false); }); let dataSource = { name : '전광판/제어기 제어', div : div, } return dataSource; }; function operDiv(){ const div = $('
'); div.html(`
운영모드 변경시 해당 운영시나리오가 존재하지 않으면
VMS에 메시지가 표출되지 않습니다.
표출폼을 주기와 상관없이 즉시 다운로드 합니다.
`); const autoOper = div.children().eq(0).children().eq(0); const fixedOper = div.children().eq(1).children().eq(0); const operChangeBtn = div.children().eq(2).children().eq(0); const formDownload = div.children().eq(3).children().eq(0); //체크박스 상자 옵션 _operCheckArr = [ { position : autoOper, text : '자동 운영모드 (자동 스케줄에 등록되어 있는 메시지를 표출 합니다.)', box : null, code : 'A', value : true, oper_mode_desc : '자동 운영모드', }, { position : fixedOper, text : '고정 운영모드 (고정 스케줄에 등록되어 있는 메시지를 표출 합니다.)', box : null, code : 'F', value : false, oper_mode_desc : '고정 운영모드', }, ]; _operCheckArr.map((item)=>{ item.box = new dxCheck($(item.position), item.text, item.value, false, item.code); }); //체크 박스 꺼짐 방지 이벤트 $(autoOper).on('click',()=>{ if(!_operCheckArr[0].box.getValue()) _operCheckArr[0].box.setValue(true); }); $(fixedOper).on('click',()=>{ if(!_operCheckArr[1].box.getValue()) _operCheckArr[1].box.setValue(true); }); //체크박스 선택시 나머지 체크 박스 값 초기화 _operCheckArr[0].box.onValueChanged((e)=>{ if (_operCheckArr[1].box.getValue()) _operCheckArr[1].box.setValue(!e.value); }); _operCheckArr[1].box.onValueChanged((e)=>{ if (_operCheckArr[0].box.getValue()) _operCheckArr[0].box.setValue(!e.value); }); const btnArr = [ { position : operChangeBtn, text : '운영모드 변경', uri : '/opr-mode/', data : { opr_mode: _operCheckArr[1].box.getValue() === true ? "A" : "F", user_id: _userId, } }, { position : formDownload, text : '폼 즉시 다운로드', uri : '/imm-scnr-dnld/', data : { user_id: _userId, }, } ] btnArr.map((item)=>{ const btn = new dxBtn(item.position, item.text , 'preferences', 'outlined', 160, null, false, true); btn.onClick(() => controlEvent(item.text, item)); }) let dataSource = { name : '운영모드 변경', div : div, }; return dataSource; }; function controlEvent(confirmText, input){ const selectedData =_listTable.getSelectedRowsData(); if (selectedData.length <= 0 || selectedData[0].cmnc_stts_desc === '통신두절') { return alertWarning('VMS가 선택되지 않았습니다.
VMS 목록에서 VMS를 선택하십시오.
현재 통신이 비정상적인 VMS는 선택하실 수 없습니다.'); } let updateData; switch (input.uri) { case '/luminance/': updateData = { user_id : _userId, value : input.val, curr_step : 0, nght_step : 0, week_step : 0, } for (let brghNo of _brghColumns){ const value = brghNo.number.getValue(); updateData[brghNo.column] = value; } break; case '/opr-mode/': let operMode; if (_operCheckArr[0].box.getValue() === true) { operMode = "A"; confirmText = confirmText + " [ "+ _operCheckArr[0].oper_mode_desc +" ]" } else { operMode = "F"; confirmText = confirmText + " [ "+ _operCheckArr[1].oper_mode_desc +" ]" } updateData = { opr_mode: operMode, user_id: _userId, } break; case '/imm-scnr-dnld/': updateData = { user_id: _userId, } break; case '/param/': updateData = { fan_run_tmpr: 0, hetr_run_tmpr: 0, panl_off_time: 0, panl_on_time: 0, user_id: _userId, } for (let onOffTime of _onOfftimeArr){ const value = onOffTime.time.getSendTimeValue(); if (onOffTime.time.isValidation()){ return alertWarning( onOffTime.text + '을 바르게 입력해주세요', null, onOffTime.time.text); } else if (onOffTime.time.isNull(value)){ return alertWarning( onOffTime.text + '을 입력해주세요', null, onOffTime.time.text); } else { updateData[onOffTime.column] = value; } } for (let temp of _tempColumns) { if(temp.box.isNull()){ return alertWarning( numBox.text + ' 값을 입력해주세요', null, numBox.box.number); } updateData[temp.column] = temp.box.getValue(); } break; default: updateData = { value: input.val, user_id: _userId, } break; } confirmMessage("선택하신 VMS 제어기에 " + confirmText + " 명령을 요청 하시겠습니까?").done((yes) => { if (yes === true) { let successCnt = 0; for (let data of selectedData) { let result = postInsertUpdate(_apiUri + input.uri + data.vms_ctlr_nmbr, updateData); successCnt += result; if (result > 0) { refreshListData(); return alertConfirm(selectedData.length + ' 개의 선택 VMS 중에 ' + successCnt +' 개의 '+ confirmText + ' 명령을 요청하였습니다.'); } } } }); } function cBoxDiv(){ const div = $('
'); div.html(`
팬동작온도
(Fan동작 기준온도)
히터동작온도
(Heartr동작 기준온도)
전광판 가동 시작/종료 시각
(00:00 ~ 23:59)
설정 값에 따라 VMS 제어기가 비정상적으로 동작 할 수 있습니다.
`); const fanTemp = div.children().eq(0).children().eq(1).children().eq(0); const hearterTemp = div.children().eq(1).children().eq(1).children().eq(0); const strtTime = div.children().eq(2).children().eq(1).children().eq(0); const endTime = div.children().eq(2).children().eq(2).children().eq(0); const doorEditBtn = div.children().eq(3).children().eq(0); _onOfftimeArr = [ { position : strtTime, time : null, text : '전광판 가동 시각', column : 'panl_off_time', }, { position : endTime, time : null, text : '전광판 종료 시각', column : 'panl_on_time', }, ]; _onOfftimeArr.map((item)=>{ item.time = new dxDate(item.position, 'HH:mm', null, 80, 30, 'time', 10); item.time.setValue(firstSettingTime); }) //체크박스 상자 옵션 _tempColumns = [ { position : fanTemp, column : 'fan_run_tmpr', text : '팬동작온도', box : null, max : 255, value : 35, }, { position : hearterTemp, column : 'hetr_run_tmpr', text : '히터동작온도', box : null, max : 255, value : 0, }, ]; _tempColumns.map((item)=>{ item.box = new dxNumber(item.position, 'outlined', 80, 30, 0, 255, true, item.value, item.column, '##0', false); }); let btn = new dxBtn(doorEditBtn, '함체환경 설정', 'preferences', 'outlined', null, null, false, true); let btnBox = { uri : '/param/', } btn.onClick(() => controlEvent('VMS 함체환경 설정', btnBox)); let dataSource = { name : 'VMS 함체환경 설정', div : div, } return dataSource; }; function networkDiv(){ const div = $('
'); div.html(`
IP Address 컬럼을 더블클릭하면 네트워크 체크를 합니다.
Ping Time Out
mili-second
`); const networkTable = div.children().eq(0).children().eq(0); const networkCheckBtn = div.children().eq(2).children().eq(0).children().eq(0); const resetBtn = div.children().eq(2).children().eq(1).children().eq(0); const timeOutNumber = div.children().eq(2).children().eq(3).children().eq(0); const btnArr = [ { position : networkCheckBtn, text : '네트워크 체크', btn : null, }, { position : resetBtn, text : '초기화', btn : null, }, ] const pingNumber = new dxNumber(timeOutNumber, 'outlined', 100, 26, 0, 10000, true, 1000, null, '####0', false); btnArr.map((item)=>{ item.btn = new dxBtn(item.position, item.text , 'preferences', 'outlined', null, null, false, true); }); let tableData = []; getData('/api/vms/manager/info', tableData); const table = networkTable.width('100%').height('100%').dxDataGrid({ dataSource : tableData[0], allowColumnReordering : true, showColumnLines : true, showBorders : true, allowColumnResizing : true, rowAlternationEnabled : true, columnAutoWidth : true, focusedRowEnabled : true, noDataText : '표출할 정보가 없습니다.', headerFilter: { visible: true, }, keyExpr : 'vms_ctlr_nmbr', paging: { enabled: false, pageSize: 1000, }, selection : { mode : 'multiple', showCheckBoxesMode : "onClick" }, scrolling: { mode: 'standard', }, columns:[ { caption : 'VMS Infromation', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "vms_ctlr_nmbr", caption : "VMS No", alignment : "center", sortIndex : 0, sortOrder : "asc", width : 110, }, { dataField : "vms_ctlr_id", caption : "VMS ID", alignment : "center", }, { dataField : "cmnc_stts_desc", caption : "Comm.", alignment : "center", width : 130, cellTemplate(c,e){ c.css('padding','2px'); c.css('height','1px'); let classNm = e.data.cmnc_stts_cd; if (!e.data.cmnc_stts_cd){ classNm = 'gray' } const div = $('
') div.text(e.displayValue); return c.append(div); } }, ] }, { caption : 'Controller', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "vms_ctlr_ip", caption : "IP Address", alignment : "center", cssClass : 'padding-ctrl', }, { dataField : "vms_ctrl_resp", caption : "Response", alignment : "center", width : 100, cssClass : 'padding-ctrl', }, { dataField : "vms_ctrl_total", caption : "TTL", width : 80, alignment : "center", cssClass : 'padding-ctrl', }, { dataField : "vms_ctrl_status", caption : "Status", width : 90, alignment : "center", cssClass : 'padding-ctrl', }, ] }, { caption : 'Web Camera', alignment : 'center', cssClass : 'padding-ctrl', columns : [ { dataField : "web_cmra_ip", caption : "IP Adress", alignment : "center", }, { dataField : "web_cmra_response", caption : "Response", alignment : "center", width : 100, cssClass : 'padding-ctrl', }, { dataField : "web_cmra_total", caption : "TTL", alignment : "center", width : 80, cssClass : 'padding-ctrl', }, { dataField : "web_cmra_status", caption : "Status", alignment : "center", width : 90, cssClass : 'padding-ctrl', }, ] }, ], }).dxDataGrid("instance"); table.selectAll(); let dataSource = { name : 'Netowork Ping', div : div, num : null, btn : null, } return dataSource; }; function wcamCtlrClick(){ window.open('http://'+ _wcamIp); }; function listTableClick(info){ let selectedData = info.data; if ( _selectedId === null || _selectedId !== selectedData.vms_ctlr_nmbr) { _selectedId = selectedData.vms_ctlr_nmbr; dsblOffBtn(_wcamCtrlBtn) _wcamIp = selectedData.web_cmra_ip; const videoBox = $('.video-box'); videoBox.css('background-color', 'black'); if (_selectedVideo){ $('#video').stop(); videoBox.empty(); videoBox.append('') } _selectedVideo = webRtcConnector(selectedData, videoBox, "video", true); _brghColumns.map((item)=>{ let val = selectedData[item.column]; if (nullChecker(val) !== "") { item.number.setValue(val) } }); _operCheckArr.map((item)=>{ if (item.code === selectedData.oper_mode) { item.box.setValue(true); } }); _tempColumns.map((item)=>{ item.box.setValue(selectedData[item.column]); }); _onOfftimeArr.map((item)=>{ let timeVal = selectedData[item.column]; item.time.setTimeValue(timeVal); }) $('.title-text').text('[' + selectedData.vms_ctlr_id + '] - '+selectedData.vms_nm); } }