|
|
|
@ -78,6 +78,91 @@ |
|
|
|
|
|
|
|
.config-actions{display:flex;gap:24px;justify-content:center;padding: 20px} |
|
|
|
.config-actions button{min-width:140px;padding:10px 18px;font-size:16px;border:1px solid #bbb;background:#d9d9d9;border-radius:4px;cursor:pointer} |
|
|
|
|
|
|
|
/* MODBUS 화면 심플 스타일 */ |
|
|
|
#page-modbus .card { |
|
|
|
background: #f7f7f7; |
|
|
|
border: 1px solid #bbb; |
|
|
|
box-shadow: none; |
|
|
|
padding: 24px; |
|
|
|
border-radius: 4px; |
|
|
|
} |
|
|
|
#page-modbus table { |
|
|
|
width: 100%; |
|
|
|
border-collapse: collapse; |
|
|
|
background: #fff; |
|
|
|
border: 1px solid #bbb; |
|
|
|
} |
|
|
|
#page-modbus th, #page-modbus td { |
|
|
|
border: 1px solid #bbb; |
|
|
|
padding: 6px 8px; |
|
|
|
text-align: left; |
|
|
|
background: #fff; |
|
|
|
} |
|
|
|
#page-modbus th { |
|
|
|
background: #e5e5e5; |
|
|
|
font-weight: 500; |
|
|
|
} |
|
|
|
#page-modbus .modbus-input-area { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: 1fr 1fr; |
|
|
|
gap: 8px 32px; |
|
|
|
margin: 24px 0 16px 0; |
|
|
|
background: #eaeaea; |
|
|
|
padding: 16px 0; |
|
|
|
border-radius: 4px; |
|
|
|
} |
|
|
|
#page-modbus .input-row { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 12px; |
|
|
|
margin-bottom: 8px; |
|
|
|
} |
|
|
|
#page-modbus .input-row label { |
|
|
|
min-width: 80px; |
|
|
|
color: #444; |
|
|
|
} |
|
|
|
#page-modbus .input-row input { |
|
|
|
background: #e0e0e0; |
|
|
|
border: none; |
|
|
|
border-radius: 2px; |
|
|
|
padding: 4px 8px; |
|
|
|
min-width: 120px; |
|
|
|
} |
|
|
|
#page-modbus .modbus-actions { |
|
|
|
display: flex; |
|
|
|
gap: 24px; |
|
|
|
justify-content: center; |
|
|
|
margin: 16px 0 0 0; |
|
|
|
} |
|
|
|
#page-modbus .modbus-actions button { |
|
|
|
background: #d3d3d3; |
|
|
|
border: 1px solid #aaa; |
|
|
|
border-radius: 2px; |
|
|
|
padding: 8px 24px; |
|
|
|
font-size: 16px; |
|
|
|
cursor: pointer; |
|
|
|
} |
|
|
|
/* 하단 버튼 영역 */ |
|
|
|
#modbus-bottom-actions { |
|
|
|
display: flex; |
|
|
|
gap: 24px; |
|
|
|
justify-content: center; |
|
|
|
background: #f7f7f7; |
|
|
|
border: 1px solid #bbb; |
|
|
|
border-radius: 4px; |
|
|
|
margin: 24px 0 0 0; |
|
|
|
padding: 20px 0; |
|
|
|
} |
|
|
|
#modbus-bottom-actions button { |
|
|
|
background: #e0e0e0; |
|
|
|
border: 1px solid #aaa; |
|
|
|
border-radius: 2px; |
|
|
|
padding: 10px 18px; |
|
|
|
font-size: 16px; |
|
|
|
min-width: 140px; |
|
|
|
cursor: pointer; |
|
|
|
} |
|
|
|
</style> |
|
|
|
</head> |
|
|
|
<body> |
|
|
|
@ -402,19 +487,9 @@ |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
<template id="modbus-row-template"> |
|
|
|
<tr class="modbus-row"> |
|
|
|
<td><span class="modbus-field-display"></span></td> |
|
|
|
<td><span class="modbus-addr-display"></span></td> |
|
|
|
<td><span class="modbus-idt-display"></span></td> |
|
|
|
<td><span class="modbus-odt-display"></span></td> |
|
|
|
<td><span class="modbus-dv-display"></span></td> |
|
|
|
</tr> |
|
|
|
</template> |
|
|
|
|
|
|
|
<section id="page-modbus" class="page" style="display:none;"> |
|
|
|
<div class="card"> |
|
|
|
<h3>MODBUS Configuration</h3> |
|
|
|
<h3>Register configuration</h3> |
|
|
|
<div class="modbus-table-container"> |
|
|
|
<table> |
|
|
|
<thead> |
|
|
|
@ -424,6 +499,9 @@ |
|
|
|
<th>idt</th> |
|
|
|
<th>odt</th> |
|
|
|
<th>dv</th> |
|
|
|
<th>shift</th> |
|
|
|
<th>expr</th> |
|
|
|
<th>mask</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
<tbody id="modbus-field-list"> |
|
|
|
@ -457,9 +535,10 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="actions"> |
|
|
|
<button id="loadModbusFileBtn">Load Protocol File</button> |
|
|
|
<button id="saveModbusFileBtn">Save to Protocol</button> |
|
|
|
<!-- 하단 버튼 영역 추가 --> |
|
|
|
<div id="modbus-bottom-actions"> |
|
|
|
<button id="loadModbusBtn">Load Protocol File</button> |
|
|
|
<button id="saveModbusBtn">Save Protocol File</button> |
|
|
|
</div> |
|
|
|
</section> |
|
|
|
|
|
|
|
@ -646,9 +725,9 @@ |
|
|
|
} |
|
|
|
|
|
|
|
// 페이지 전환 시 항상 마지막으로 로드된 전체 데이터를 UI에 반영 |
|
|
|
if (lastLoadedRegisterData && Object.keys(lastLoadedRegisterData).length > 0) { |
|
|
|
loadFromRegisterJson(lastLoadedRegisterData); |
|
|
|
} |
|
|
|
// if (lastLoadedRegisterData && Object.keys(lastLoadedRegisterData).length > 0) { |
|
|
|
// loadFromRegisterJson(lastLoadedRegisterData); |
|
|
|
// } |
|
|
|
toggleNetInputs(); // Network 페이지 로드 시 IP 모드에 따른 입력 필드 활성화/비활성화 |
|
|
|
|
|
|
|
} |
|
|
|
@ -763,6 +842,27 @@ |
|
|
|
} |
|
|
|
loadFromData(data); |
|
|
|
|
|
|
|
let regProtocolSelect; |
|
|
|
function toggleProtocolMenus() { |
|
|
|
if(!regProtocolSelect) return; |
|
|
|
const selectProtocol = regProtocolSelect.value; |
|
|
|
const modbusSidebarBtn = document.getElementById('modbusSidebarBtn'); |
|
|
|
const opcUaSidebarBtn = document.getElementById('opcUaSidebarBtn'); |
|
|
|
|
|
|
|
if(modbusSidebarBtn) modbusSidebarBtn.style.display = 'none'; |
|
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'none'; |
|
|
|
|
|
|
|
if(selectProtocol === 'MODBUS'){ |
|
|
|
if (modbusSidebarBtn) modbusSidebarBtn.style.display = 'block'; |
|
|
|
} |
|
|
|
else if(selectProtocol === 'OPC_UA'){ |
|
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'block'; |
|
|
|
} |
|
|
|
|
|
|
|
// Protocol configuration 메뉴를 자동으로 펼치기 |
|
|
|
const protocolDetails = document.querySelectorAll('details.nav')[1]; |
|
|
|
if (protocolDetails) protocolDetails.open = true; |
|
|
|
} |
|
|
|
|
|
|
|
function loadFromRegisterJson(register) { // register.json 데이터 로드 |
|
|
|
if (!register) { |
|
|
|
@ -804,7 +904,16 @@ |
|
|
|
console.warn(`HTML element with ID '${htmlId}' not found for DTO key '${dtoKey}'.`); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// protocol 값이 있으면 select 값을 변경 (데이터 로드 시에만) |
|
|
|
if (register.protocol && regProtocolSelect) { |
|
|
|
regProtocolSelect.value = register.protocol; |
|
|
|
} |
|
|
|
|
|
|
|
// 프로토콜 값에 따라 사이드바 버튼 토글 |
|
|
|
toggleProtocolMenus(); |
|
|
|
|
|
|
|
// 예시: MODBUS 필드를 UI에 표시하는 가상의 로직 (HTML 컨테이너 필요) |
|
|
|
const modbusContainer = document.getElementById('modbus_fields_container'); // HTML에 이 ID의 div가 있다고 가정 |
|
|
|
@ -843,9 +952,10 @@ |
|
|
|
canContainer.textContent = 'No CAN fields configured.'; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function collectData() { |
|
|
|
function collectData() { |
|
|
|
const res = {...data}; |
|
|
|
|
|
|
|
res.wifi_static = document.querySelector('input[name="ipMode"]:checked')?.value === 'static' |
|
|
|
@ -893,340 +1003,259 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// MODBUS, OPC_UA, CAN 리스트 필드 처리 |
|
|
|
if (lastLoadedRegisterData.MODBUS) { |
|
|
|
collectedRegister.MODBUS = lastLoadedRegisterData.MODBUS; |
|
|
|
} else { |
|
|
|
collectedRegister.MODBUS = []; // 데이터가 없으면 빈 배열로 초기화 |
|
|
|
} |
|
|
|
if (lastLoadedRegisterData.OPC_UA) { |
|
|
|
collectedRegister.OPC_UA = lastLoadedRegisterData.OPC_UA; |
|
|
|
} else { |
|
|
|
collectedRegister.OPC_UA = []; |
|
|
|
} |
|
|
|
if (lastLoadedRegisterData.CAN) { |
|
|
|
collectedRegister.CAN = lastLoadedRegisterData.CAN; |
|
|
|
} else { |
|
|
|
collectedRegister.CAN = []; |
|
|
|
} |
|
|
|
|
|
|
|
// input_data_type, output_data_type과 같은 필드 처리 (DTO 필드명은 camelCase로 가정) |
|
|
|
// DTO의 필드명은 `inputDataType`, `outputDataType`일 것이므로 이에 맞춰야 합니다. |
|
|
|
// if (lastLoadedRegisterData.inputDataType !== undefined) { |
|
|
|
// collectedRegister.inputDataType = lastLoadedRegisterData.inputDataType; |
|
|
|
// } else { |
|
|
|
// // configData에 inputDataType이 없으면 빈 문자열 사용 (초기 configData에는 snake_case로 되어있었음) |
|
|
|
// collectedRegister.inputDataType = collectedRegister.inputDataType || ''; |
|
|
|
// } |
|
|
|
// |
|
|
|
// if (lastLoadedRegisterData.outputDataType !== undefined) { |
|
|
|
// collectedRegister.outputDataType = lastLoadedRegisterData.outputDataType; |
|
|
|
// } else { |
|
|
|
// // configData에 outputDataType이 없으면 빈 문자열 사용 |
|
|
|
// collectedRegister.outputDataType = collectedRegister.outputDataType || ''; |
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
// 5. 현재 UI에 선택된 프로토콜과 CAN Input 값에 따라 리스트 필드를 `null`로 만들지 여부 결정 (선택 사항) |
|
|
|
// 백엔드 `SettingService`의 `saveFileWithRegister` 메서드에서 이미 이 로직을 처리하고 있으므로, |
|
|
|
// 프론트엔드에서 굳이 이 로직을 중복해서 넣지 않아도 됩니다. |
|
|
|
// 다만, 프론트엔드에서 정확한 데이터를 보내고 싶다면 유지해도 무방합니다. |
|
|
|
// 여기서는 UI 값에 따라 `null`로 설정하는 로직을 유지하면서, |
|
|
|
// 'canInput'의 대소문자 문제만 수정합니다. |
|
|
|
|
|
|
|
const currentProtocolFromUI = collectedRegister.protocol; |
|
|
|
// ⭐ 중요: UI의 option value="ON"과 일치하도록 'ON' 사용 |
|
|
|
const currentCanInputFromUI = collectedRegister.canInput; |
|
|
|
|
|
|
|
if (currentProtocolFromUI !== 'OPC_UA') { |
|
|
|
collectedRegister.opcUaFields = null; |
|
|
|
} |
|
|
|
if (currentProtocolFromUI !== 'MODBUS') { |
|
|
|
collectedRegister.modbusFields = null; |
|
|
|
} |
|
|
|
// ⭐ 수정: 'On' -> 'ON' (UI select option 값과 일치) |
|
|
|
if (currentCanInputFromUI !== 'ON') { |
|
|
|
collectedRegister.canFields = null; |
|
|
|
} |
|
|
|
|
|
|
|
// 디버깅을 위해 전송 직전의 데이터 로깅 |
|
|
|
console.log("Collected Register Data before sending:", collectedRegister); |
|
|
|
|
|
|
|
return collectedRegister; |
|
|
|
} |
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('loadDeviceBtn_ssid')?.addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/get-device') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Device file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(deviceJsonData => { |
|
|
|
loadFromData(deviceJsonData); |
|
|
|
alert('Device 설정 파일 로드 완료'); |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Device 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Device 설정 파일 로드 실패! 기본값으로 시작합니다.'); |
|
|
|
loadFromData(data); // 오류 발생 시 data의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('loadDeviceBtn_network')?.addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/get-device') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Device file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(deviceJsonData => { |
|
|
|
loadFromData(deviceJsonData); |
|
|
|
alert('Device 설정 파일 로드 완료'); |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Device 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Device 설정 파일 로드 실패! 기본값으로 시작합니다.'); |
|
|
|
loadFromData(data); // 오류 발생 시 data의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('loadDeviceBtn_io')?.addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/get-device') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Device file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(deviceJsonData => { |
|
|
|
loadFromData(deviceJsonData); |
|
|
|
alert('Device 설정 파일 로드 완료'); |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Device 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Device 설정 파일 로드 실패! 기본값으로 시작합니다.'); |
|
|
|
loadFromData(data); // 오류 발생 시 data의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
|
regProtocolSelect = document.getElementById('reg_protocol'); |
|
|
|
if(regProtocolSelect) { |
|
|
|
regProtocolSelect.addEventListener('change', () => { |
|
|
|
console.log('regProtocolSelect 변경 감지',regProtocolSelect.value); |
|
|
|
toggleProtocolMenus(); |
|
|
|
}); |
|
|
|
|
|
|
|
toggleProtocolMenus(); |
|
|
|
} |
|
|
|
|
|
|
|
document.getElementById('saveDeviceBtn_ssid').addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/device', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectData()) |
|
|
|
document.getElementById('loadDeviceBtn_ssid')?.addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/get-device') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Device file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(() => alert('전송 완료')) |
|
|
|
.catch(console.error); |
|
|
|
}); |
|
|
|
.then(deviceJsonData => { |
|
|
|
loadFromData(deviceJsonData); |
|
|
|
alert('Device 설정 파일 로드 완료'); |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Device 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Device 설정 파일 로드 실패! 기본값으로 시작합니다.'); |
|
|
|
loadFromData(data); // 오류 발생 시 data의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('saveDeviceBtn_network').addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/device', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectData()) |
|
|
|
document.getElementById('loadDeviceBtn_network')?.addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/get-device') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Device file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(() => alert('전송 완료')) |
|
|
|
.catch(console.error); |
|
|
|
}); |
|
|
|
.then(deviceJsonData => { |
|
|
|
loadFromData(deviceJsonData); |
|
|
|
alert('Device 설정 파일 로드 완료'); |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Device 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Device 설정 파일 로드 실패! 기본값으로 시작합니다.'); |
|
|
|
loadFromData(data); // 오류 발생 시 data의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('saveDeviceBtn_io').addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/device', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectData()) |
|
|
|
document.getElementById('loadDeviceBtn_io')?.addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/get-device') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Device file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(() => alert('전송 완료')) |
|
|
|
.catch(console.error); |
|
|
|
}); |
|
|
|
.then(deviceJsonData => { |
|
|
|
loadFromData(deviceJsonData); |
|
|
|
alert('Device 설정 파일 로드 완료'); |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Device 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Device 설정 파일 로드 실패! 기본값으로 시작합니다.'); |
|
|
|
loadFromData(data); // 오류 발생 시 data의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('loadProtocolBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
|
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Register file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(apiResponseData => { |
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
} else { |
|
|
|
console.error('API 응답에 body 필드가 없습니다.', apiResponseData); |
|
|
|
alert('Protocol 설정 파일 로드 실패! 유효한 응답 형식이 아닙니다.'); |
|
|
|
loadFromRegisterJson(configData); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Protocol 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Protocol 설정 파일 로드 실패! ' + error.message + ' 기본값으로 시작합니다.'); |
|
|
|
loadFromRegisterJson(configData); // 오류 발생 시 configData의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('loadModbusFileBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
|
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Register file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(apiResponseData => { |
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
} else { |
|
|
|
console.error('API 응답에 body 필드가 없습니다.', apiResponseData); |
|
|
|
alert('Protocol 설정 파일 로드 실패! 유효한 응답 형식이 아닙니다.'); |
|
|
|
loadFromRegisterJson(configData); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Protocol 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Protocol 설정 파일 로드 실패! ' + error.message + ' 기본값으로 시작합니다.'); |
|
|
|
loadFromRegisterJson(configData); // 오류 발생 시 configData의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
document.getElementById('saveDeviceBtn_ssid').addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/device', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectData()) |
|
|
|
}) |
|
|
|
.then(() => alert('전송 완료')) |
|
|
|
.catch(console.error); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('loadOpcUaFileBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
|
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Register file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(apiResponseData => { |
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
} else { |
|
|
|
console.error('API 응답에 body 필드가 없습니다.', apiResponseData); |
|
|
|
alert('Protocol 설정 파일 로드 실패! 유효한 응답 형식이 아닙니다.'); |
|
|
|
loadFromRegisterJson(configData); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Protocol 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Protocol 설정 파일 로드 실패! ' + error.message + ' 기본값으로 시작합니다.'); |
|
|
|
loadFromRegisterJson(configData); // 오류 발생 시 configData의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
document.getElementById('saveDeviceBtn_network').addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/device', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectData()) |
|
|
|
}) |
|
|
|
.then(() => alert('전송 완료')) |
|
|
|
.catch(console.error); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('saveProtocolBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
if (res.ok) { |
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
} else { |
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
console.error('Register 설정 전송 실패:', res); // 응답 객체 자체를 로깅 |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Register 설정 전송 중 오류 발생:', error); // 네트워크 오류 로깅 |
|
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
document.getElementById('saveDeviceBtn_io').addEventListener('click', () => { |
|
|
|
fetch('http://localhost:8080/setting/device', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectData()) |
|
|
|
}) |
|
|
|
.then(() => alert('전송 완료')) |
|
|
|
.catch(console.error); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('saveModbusFileBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
if (res.ok) { |
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
} else { |
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
console.error('Register 설정 전송 실패:', res); // 응답 객체 자체를 로깅 |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Register 설정 전송 중 오류 발생:', error); // 네트워크 오류 로깅 |
|
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
document.getElementById('loadProtocolBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
|
|
|
|
document.getElementById('saveOpcUaFileBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Register file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
if (res.ok) { |
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
} else { |
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
console.error('Register 설정 전송 실패:', res); // 응답 객체 자체를 로깅 |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Register 설정 전송 중 오류 발생:', error); // 네트워크 오류 로깅 |
|
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
const regProtocolSelect = document.getElementById('reg_protocol'); |
|
|
|
const modbusSidebarBtn = document.getElementById('modbusSidebarBtn'); |
|
|
|
const opcUaSidebarBtn = document.getElementById('opcUaSidebarBtn'); |
|
|
|
|
|
|
|
function toggleProtocolMenus() { |
|
|
|
const selectProtocol = regProtocolSelect.value; |
|
|
|
.then(apiResponseData => { |
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
} else { |
|
|
|
console.error('API 응답에 body 필드가 없습니다.', apiResponseData); |
|
|
|
alert('Protocol 설정 파일 로드 실패! 유효한 응답 형식이 아닙니다.'); |
|
|
|
loadFromRegisterJson(configData); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Protocol 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Protocol 설정 파일 로드 실패! ' + error.message + ' 기본값으로 시작합니다.'); |
|
|
|
loadFromRegisterJson(configData); // 오류 발생 시 configData의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
if(modbusSidebarBtn) modbusSidebarBtn.style.display = 'none'; |
|
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'none'; |
|
|
|
document.getElementById('loadModbusBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
|
|
|
|
if(selectProtocol === 'MODBUS'){ |
|
|
|
if (modbusSidebarBtn) modbusSidebarBtn.style.display = 'block'; |
|
|
|
} |
|
|
|
else if(selectProtocol === 'OPC_UA'){ |
|
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'block'; |
|
|
|
} |
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Register file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(apiResponseData => { |
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
} else { |
|
|
|
console.error('API 응답에 body 필드가 없습니다.', apiResponseData); |
|
|
|
alert('Protocol 설정 파일 로드 실패! 유효한 응답 형식이 아닙니다.'); |
|
|
|
loadFromRegisterJson(configData); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Protocol 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Protocol 설정 파일 로드 실패! ' + error.message + ' 기본값으로 시작합니다.'); |
|
|
|
loadFromRegisterJson(configData); // 오류 발생 시 configData의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
const currentPageId = Object.keys(pages).find(key => pages[key].style.display === 'block'); |
|
|
|
if (currentPageId === 'modbus' && selectProtocol !== 'MODBUS'){ |
|
|
|
showPage('reg'); |
|
|
|
} |
|
|
|
} |
|
|
|
toggleProtocolMenus(); |
|
|
|
document.getElementById('loadOpcUaFileBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
|
|
|
|
regProtocolSelect.addEventListener('change', toggleProtocolMenus); |
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
.then(res => { |
|
|
|
if (!res.ok) { |
|
|
|
console.error(`HTTP error! status: ${res.status}`); |
|
|
|
throw new Error('Register file not found or server error'); |
|
|
|
} |
|
|
|
return res.json(); |
|
|
|
}) |
|
|
|
.then(apiResponseData => { |
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
} else { |
|
|
|
console.error('API 응답에 body 필드가 없습니다.', apiResponseData); |
|
|
|
alert('Protocol 설정 파일 로드 실패! 유효한 응답 형식이 아닙니다.'); |
|
|
|
loadFromRegisterJson(configData); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Protocol 설정 파일 로드 중 오류 발생:', error); |
|
|
|
alert('Protocol 설정 파일 로드 실패! ' + error.message + ' 기본값으로 시작합니다.'); |
|
|
|
loadFromRegisterJson(configData); // 오류 발생 시 configData의 초기값으로 UI 초기화 |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('saveProtocolBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
console.log(collectConfigData()); |
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
if (res.ok) { |
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
} else { |
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
console.error('Register 설정 전송 실패:', res); // 응답 객체 자체를 로깅 |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Register 설정 전송 중 오류 발생:', error); // 네트워크 오류 로깅 |
|
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
document.getElementById('saveModbusBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
if (res.ok) { |
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
} else { |
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
console.error('Register 설정 전송 실패:', res); // 응답 객체 자체를 로깅 |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Register 설정 전송 중 오류 발생:', error); // 네트워크 오류 로깅 |
|
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('saveOpcUaFileBtn').addEventListener('click', () => { |
|
|
|
console.log('버튼 클릭 됨'); |
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
}) |
|
|
|
.then(res => { |
|
|
|
if (res.ok) { |
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
} else { |
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
console.error('Register 설정 전송 실패:', res); // 응답 객체 자체를 로깅 |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch(error => { |
|
|
|
console.error('Register 설정 전송 중 오류 발생:', error); // 네트워크 오류 로깅 |
|
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
</script> |
|
|
|
</body> |
|
|
|
</html> |