diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/Protocol.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/Protocol.java
index 0de5dfb..fec2027 100644
--- a/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/Protocol.java
+++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/Protocol.java
@@ -7,7 +7,8 @@ import lombok.AllArgsConstructor;
public enum Protocol {
MODBUS("MODBUS"),
OPC_UA("OPC_UA"),
- CAN("CAN");
+ CAN("CAN"),
+ NONE("NONE");
private final String protocol;
@JsonValue
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index 64632a9..eaf30d1 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -334,22 +334,8 @@
cursor: pointer
}
- .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
- }
+ .config-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;}
+ .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 {
@@ -663,6 +649,8 @@
background: #d0e6ff !important;
}
+ .file-upload-section{padding: 10px;margin: 10px;text-align: center;}
+
@@ -715,7 +703,14 @@
-
+
+
+
+
@@ -754,7 +749,14 @@
id="opc_ua_server_port"/>
-
+
+
+
+
@@ -884,7 +886,14 @@
-
+
+
+
+
@@ -921,7 +930,7 @@
MEID
Protocol
@@ -1015,11 +1024,18 @@
-
-
-
-
+
+
+
+
+
+
+
@@ -1037,7 +1053,7 @@
-
Register_Configuration Modbus화면
+
Modbus Configuration
@@ -1098,11 +1114,18 @@
-
+
+
+
+
-
+
@@ -1173,11 +1196,18 @@
-
+
+
+
+
-
+
@@ -1241,11 +1271,18 @@
-
+
+
+
+
-
+
@@ -1801,6 +1838,417 @@
}
document.addEventListener('DOMContentLoaded', () => {
+
+ // Device 파일 업로드
+ // 모든 파일 업로드 래퍼 섹션을 가져옵니다.
+ const fileUploadWrappersDevice = document.querySelectorAll('.file-upload-wrapper-device');
+
+ fileUploadWrappersDevice.forEach(wrapper => {
+ // 현재 래퍼 내에서 input[type="file"]과 버튼을 찾습니다.
+ const uploadDeviceFileInput = wrapper.querySelector('.upload-input-device');
+ const selectDeviceFileBtn = wrapper.querySelector('.select-file-btn-device');
+
+ // 해당 래퍼의 data 속성들을 가져옵니다.
+ const expectedDeviceFileName = wrapper.dataset.expectedFilename;
+ const uploadDeviceUrl = wrapper.dataset.uploadUrl;
+ const getDeviceUrl = wrapper.dataset.getUrl;
+ const DeviceFileType = wrapper.dataset.fileType;
+
+ // null 체크 (요소가 존재하지 않을 수도 있는 경우를 대비)
+ if (!uploadDeviceFileInput || !selectDeviceFileBtn) {
+ console.warn(`File upload elements not found in wrapper for type: ${DeviceFileType}`);
+ return;
+ }
+
+ // "파일 선택" 버튼 클릭 시 숨겨진 input[type="file"] 클릭 이벤트 발생
+ selectDeviceFileBtn.addEventListener('click', () => {
+ uploadDeviceFileInput.value = ''; // 이전에 선택된 파일 초기화
+ uploadDeviceFileInput.click();
+ });
+
+ // 파일 선택 시 (change 이벤트 발생) 바로 업로드 로직 시작
+ uploadDeviceFileInput.addEventListener('change', async (event) => {
+ if (event.target.files.length === 0) {
+ return;
+ }
+
+ const selectedDeviceFile = event.target.files[0];
+ const DeviceFileName = selectedDeviceFile.name;
+
+ // 파일명 검증 (data-expected-filename 사용)
+ if (DeviceFileName !== expectedDeviceFileName){
+ alert(`잘못된 파일입니다. '${expectedDeviceFileName}' 파일을 선택해주세요. 현재 파일: ${DeviceFileName} `);
+ uploadDeviceFileInput.value = ''; // 잘못된 파일 선택 시 input 초기화
+ return;
+ }
+
+ const reader = new FileReader();
+
+ reader.onload = async (e) => {
+ try {
+ const DeviceFileContent = e.target.result;
+ const jsonData = JSON.parse(DeviceFileContent);
+
+ // JSON 내용 유효성 검증
+ // 모든 파일이 Register 설정이라면 isValidRegisterConfig를 그대로 사용
+ // 만약 파일 타입에 따라 다른 유효성 검사가 필요하다면,
+ // 여기에 조건부 로직을 추가해야 합니다.
+ // if (!isValidDeviceConfig(jsonData)){ // 예를 들어, isValidModbusConfig(jsonData) 등
+ // alert(`선택된 파일의 내용이 유효한 ${DeviceFileType} 설정 파일 형식이 아닙니다.`);
+ // uploadDeviceFileInput.value = '';
+ // return;
+ // }
+
+ // 백엔드 저장 API 호출 (data-upload-url 사용)
+ const response = await fetch(uploadDeviceUrl, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(jsonData)
+ });
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ throw new Error(`파일 업로드 실패: ${response.status} ${response.statusText} - ${errorText}`);
+ }
+
+ const result = await response.json();
+
+ if (result.result && result.result.result_code === 200) {
+ alert(`파일이 Device에 성공적으로 업로드되었습니다! (${DeviceFileType})`);
+ console.log(`Upload successful for ${DeviceFileType}:`, result);
+
+ // 업로드 성공 후 최신 데이터를 Device에서 다시 불러와 UI 업데이트 (data-get-url 사용)
+ // loadFromRegisterJson은 Register 데이터만 처리하는 함수이므로,
+ // 만약 Modbus/OPCUA/CAN 데이터 로드 함수가 별도로 있다면 여기서 조건부 호출 필요
+ fetch(getDeviceUrl)
+ .then(res => res.json())
+ .then(apiResponseData => {
+ if (apiResponseData && apiResponseData.body) {
+ // 여기도 fileType에 따라 다른 load 함수를 호출해야 할 수 있습니다.
+ // 현재는 모든 파일이 Register 설정이라고 가정하여 loadFromRegisterJson 호출
+ loadFromData(apiResponseData.body);
+ console.log(`UI updated with newly uploaded ${DeviceFileType} data.`);
+ } else {
+ console.warn(`업로드 후 ${DeviceFileType} 데이터 재로드 실패: 응답 body 없음`);
+ }
+ })
+ .catch(err => console.error(`업로드 후 ${DeviceFileType} 데이터 재로드 중 오류 발생:`, err));
+
+ uploadDeviceFileInput.value = ''; // input 초기화 (다음 업로드 위함)
+
+ } else {
+ alert(`파일 업로드 실패: ${result.result ? result.result.result_message : '알 수 없는 오류'} (${DeviceFileType})`);
+ console.error(`Upload failed for ${DeviceFileType} with backend error:`, result);
+ uploadDeviceFileInput.value = '';
+ }
+
+ } catch (error) {
+ console.error(`파일 업로드 중 오류 발생 (${DeviceFileType}):`, error);
+ alert(`파일 업로드 중 오류 발생: ${error.message} (${DeviceFileType})`);
+ uploadDeviceFileInput.value = '';
+ }
+ };
+
+ reader.onerror = () => {
+ alert(`파일을 읽는 도중 오류가 발생했습니다. (${DeviceFileType})`);
+ console.error(`FileReader error for ${DeviceFileType}:`, reader.error);
+ uploadDeviceFileInput.value = '';
+ };
+
+ reader.readAsText(selectedDeviceFile);
+ });
+ });
+
+ // Protocol 파일 업로드
+ // 모든 파일 업로드 래퍼 섹션을 가져옵니다.
+ const fileUploadWrappers = document.querySelectorAll('.file-upload-wrapper-protocol');
+
+ fileUploadWrappers.forEach(wrapper => {
+ // 현재 래퍼 내에서 input[type="file"]과 버튼을 찾습니다.
+ const uploadFileInput = wrapper.querySelector('.upload-input-protocol');
+ const selectFileBtn = wrapper.querySelector('.select-file-btn-protocol');
+
+ // 해당 래퍼의 data 속성들을 가져옵니다.
+ const expectedFileName = wrapper.dataset.expectedFilename;
+ const uploadUrl = wrapper.dataset.uploadUrl;
+ const getUrl = wrapper.dataset.getUrl;
+ const fileType = wrapper.dataset.fileType; // 'protocol', 'modbus', 'opcua', 'can'
+
+ // null 체크 (요소가 존재하지 않을 수도 있는 경우를 대비)
+ if (!uploadFileInput || !selectFileBtn) {
+ console.warn(`File upload elements not found in wrapper for type: ${fileType}`);
+ return;
+ }
+
+ // "파일 선택" 버튼 클릭 시 숨겨진 input[type="file"] 클릭 이벤트 발생
+ selectFileBtn.addEventListener('click', () => {
+ uploadFileInput.value = ''; // 이전에 선택된 파일 초기화
+ uploadFileInput.click();
+ });
+
+ // 파일 선택 시 (change 이벤트 발생) 바로 업로드 로직 시작
+ uploadFileInput.addEventListener('change', async (event) => {
+ if (event.target.files.length === 0) {
+ return;
+ }
+
+ const selectedFile = event.target.files[0];
+ const fileName = selectedFile.name;
+
+ // 파일명 검증 (data-expected-filename 사용)
+ if (fileName !== expectedFileName){
+ alert(`잘못된 파일입니다. '${expectedFileName}' 파일을 선택해주세요. 현재 파일: ${fileName} `);
+ uploadFileInput.value = ''; // 잘못된 파일 선택 시 input 초기화
+ return;
+ }
+
+ const reader = new FileReader();
+
+ reader.onload = async (e) => {
+ try {
+ const fileContent = e.target.result;
+ const jsonData = JSON.parse(fileContent);
+
+ // JSON 내용 유효성 검증
+ // 모든 파일이 Register 설정이라면 isValidRegisterConfig를 그대로 사용
+ // 만약 파일 타입에 따라 다른 유효성 검사가 필요하다면,
+ // 여기에 조건부 로직을 추가해야 합니다.
+ if (!isValidRegisterConfig(jsonData)){ // 예를 들어, isValidModbusConfig(jsonData) 등
+ alert(`선택된 파일의 내용이 유효한 ${fileType} 설정 파일 형식이 아닙니다.`);
+ uploadFileInput.value = '';
+ return;
+ }
+
+ // 백엔드 저장 API 호출 (data-upload-url 사용)
+ const response = await fetch(uploadUrl, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(jsonData)
+ });
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ throw new Error(`파일 업로드 실패: ${response.status} ${response.statusText} - ${errorText}`);
+ }
+
+ const result = await response.json();
+
+ if (result.result && result.result.result_code === 200) {
+ alert(`파일이 Device에 성공적으로 업로드되었습니다! (${fileType})`);
+ console.log(`Upload successful for ${fileType}:`, result);
+
+ // 업로드 성공 후 최신 데이터를 Device에서 다시 불러와 UI 업데이트 (data-get-url 사용)
+ // loadFromRegisterJson은 Register 데이터만 처리하는 함수이므로,
+ // 만약 Modbus/OPCUA/CAN 데이터 로드 함수가 별도로 있다면 여기서 조건부 호출 필요
+ fetch(getUrl)
+ .then(res => res.json())
+ .then(apiResponseData => {
+ if (apiResponseData && apiResponseData.body) {
+ // 여기도 fileType에 따라 다른 load 함수를 호출해야 할 수 있습니다.
+ // 현재는 모든 파일이 Register 설정이라고 가정하여 loadFromRegisterJson 호출
+ loadFromRegisterJson(apiResponseData.body);
+ console.log(`UI updated with newly uploaded ${fileType} data.`);
+ } else {
+ console.warn(`업로드 후 ${fileType} 데이터 재로드 실패: 응답 body 없음`);
+ }
+ })
+ .catch(err => console.error(`업로드 후 ${fileType} 데이터 재로드 중 오류 발생:`, err));
+
+ uploadFileInput.value = ''; // input 초기화 (다음 업로드 위함)
+
+ } else {
+ alert(`파일 업로드 실패: ${result.result ? result.result.result_message : '알 수 없는 오류'} (${fileType})`);
+ console.error(`Upload failed for ${fileType} with backend error:`, result);
+ uploadFileInput.value = '';
+ }
+
+ } catch (error) {
+ console.error(`파일 업로드 중 오류 발생 (${fileType}):`, error);
+ alert(`파일 업로드 중 오류 발생: ${error.message} (${fileType})`);
+ uploadFileInput.value = '';
+ }
+ };
+
+ reader.onerror = () => {
+ alert(`파일을 읽는 도중 오류가 발생했습니다. (${fileType})`);
+ console.error(`FileReader error for ${fileType}:`, reader.error);
+ uploadFileInput.value = '';
+ };
+
+ reader.readAsText(selectedFile);
+ });
+ });
+
+ function isValidRegisterConfig(data) {
+ // 1. data가 객체이고 null이 아닌지 확인
+ if (typeof data !== 'object' || data === null) {
+ console.error("Validation Error: Data is not an object or is null.");
+ return false;
+ }
+
+ // RegisterDTO의 필수 필드 (백엔드 snake_case와 일치시키세요)
+ const topLevelRequiredFields = [
+ 'protocol',
+ 'analog_input_level',
+ 'can_input',
+ 'device_type',
+ 'dr_on',
+ 'equipment',
+ 'two_byte',
+ 'four_byte',
+ 'speed_data_source',
+ 'version',
+ 'equipment_id',
+ 'meid',
+ 'heading_on',
+ 'heading_imu_on',
+ 'fixmode_on'
+
+ ];
+
+ // 2. 모든 최상위 필수 필드가 존재하는지 확인
+ for (const field of topLevelRequiredFields) {
+ if (!data.hasOwnProperty(field)) {
+ console.error(`Validation Error: Missing required top-level field: '${field}'`);
+ return false;
+ }
+ }
+
+ // 3. 각 필드의 값 타입 및 유효성 검증
+
+ // protocol 필드 유효성 검사
+ const validProtocols = ['MODBUS', 'OPC_UA', 'CAN', 'NONE'];
+ if (typeof data.protocol !== 'string' || !validProtocols.includes(data.protocol)) {
+ console.error(`Validation Error: Invalid or missing 'protocol' field. Expected one of ${validProtocols.join(', ')}, got '${data.protocol}'`);
+ return false;
+ }
+
+ // ON/OFF 상태를 나타내는 필드 검사
+ const boolLikeFields = ['dr_on', 'heading_on', 'heading_imu_on', 'fixmode_on'];
+ for (const field of boolLikeFields) {
+ if (typeof data[field] !== 'string' || (data[field] !== 'on' && data[field] !== 'off')) {
+ console.error(`Validation Error: Invalid value for boolean-like field '${field}'. Expected 'ON' or 'OFF', got '${data[field]}'`);
+ return false;
+ }
+ }
+
+ // 기타 최상위 필드의 타입 검사 (예시, 필요에 따라 추가)
+ if (typeof data.analog_input_level !== 'string' && typeof data.analog_input_level !== 'number') {
+ console.error("Validation Error: 'analog_input_level' is not a string or number.");
+ return false;
+ }
+
+
+ // 리스트 내부 필드 유효성 검사
+
+ // MODBUS 리스트 검증
+ if (data.protocol === 'MODBUS') {
+ // protocol이 'MODBUS'일 경우, MODBUS 배열은 필수
+ if (!data.hasOwnProperty('MODBUS') || !Array.isArray(data.MODBUS)) {
+ console.error("Validation Error: 'MODBUS' array is required and must be an array when protocol is 'MODBUS'.");
+ return false;
+ }
+ // MODBUS 배열 내용 유효성 검사
+ const modbusRequiredFields = ['field', 'idt', 'addr', 'odt', 'dv'];
+ for (const [index, item] of data.MODBUS.entries()) {
+ if (typeof item !== 'object' || item === null) {
+ console.error(`Validation Error: MODBUS item at index ${index} is not an object.`);
+ return false;
+ }
+ for (const field of modbusRequiredFields) {
+ if (!item.hasOwnProperty(field) || String(item[field]).trim() === '') {
+ console.error(`Validation Error: MODBUS item at index ${index} missing or empty required field: '${field}'`);
+ return false;
+ }
+ }
+ }
+ } else {
+ // protocol이 'MODBUS'가 아닌 경우, MODBUS 배열은 존재하지 않거나 빈 배열이어야 함
+ if (data.hasOwnProperty('MODBUS') && data.MODBUS.length > 0) {
+ console.error("Validation Error: 'MODBUS' array must be empty or absent when protocol is not 'MODBUS'.");
+ return false;
+ }
+ // 만약 존재한다면 배열 타입이어야 함
+ if (data.hasOwnProperty('MODBUS') && !Array.isArray(data.MODBUS)) {
+ console.error("Validation Error: 'MODBUS' field must be an array if present, even when protocol is not 'MODBUS'.");
+ return false;
+ }
+ }
+
+
+ // OPC_UA 리스트 검증
+ if (data.protocol === 'OPC_UA') {
+ // protocol이 'OPC_UA'일 경우, OPC_UA 배열은 필수
+ if (!data.hasOwnProperty('OPC_UA') || !Array.isArray(data.OPC_UA)) {
+ console.error("Validation Error: 'OPC_UA' array is required and must be an array when protocol is 'OPC_UA'.");
+ return false;
+ }
+ // OPC_UA 배열 내용 유효성 검사
+ const opcUaRequiredFields = ['field', 'ns', 'addr', 'odt', 'dv'];
+ for (const [index, item] of data.OPC_UA.entries()) {
+ if (typeof item !== 'object' || item === null) {
+ console.error(`Validation Error: OPC_UA item at index ${index} is not an object.`);
+ return false;
+ }
+ for (const field of opcUaRequiredFields) {
+ if (!item.hasOwnProperty(field) || String(item[field]).trim() === '') {
+ console.error(`Validation Error: OPC_UA item at index ${index} missing or empty required field: '${field}'`);
+ return false;
+ }
+ }
+ }
+ } else {
+ // protocol이 'OPC_UA'가 아닌 경우, OPC_UA 배열은 존재하지 않거나 빈 배열이어야 함
+ if (data.hasOwnProperty('OPC_UA') && data.OPC_UA.length > 0) {
+ console.error("Validation Error: 'OPC_UA' array must be empty or absent when protocol is not 'OPC_UA'.");
+ return false;
+ }
+ // 만약 존재한다면 배열 타입이어야 함
+ if (data.hasOwnProperty('OPC_UA') && !Array.isArray(data.OPC_UA)) {
+ console.error("Validation Error: 'OPC_UA' field must be an array if present, even when protocol is not 'OPC_UA'.");
+ return false;
+ }
+ }
+
+
+ // CAN 리스트 검증 (can_input이 'on'인 경우 필수 - protocol 값과는 독립적)
+ if (data.can_input.toLowerCase() === 'on') {
+ if (!data.hasOwnProperty('CAN') || !Array.isArray(data.CAN)) {
+ console.error("Validation Error: 'CAN' is required when can_input is 'on', and must be an array.");
+ return false;
+ }
+ const canRequiredFields = ['field', 'id', 'odt', 'dv'];
+ for (const [index, item] of data.CAN.entries()) {
+ if (typeof item !== 'object' || item === null) {
+ console.error(`Validation Error: CAN item at index ${index} is not an object.`);
+ return false;
+ }
+ for (const field of canRequiredFields) {
+ if (!item.hasOwnProperty(field) || String(item[field]).trim() === '') {
+ console.error(`Validation Error: CAN item at index ${index} missing or empty required field: '${field}'`);
+ return false;
+ }
+ }
+ }
+ } else {
+ // can_input이 'off'일 경우 CAN이 존재하면 배열이어야 함 (선택 사항)
+ if (data.hasOwnProperty('CAN') && data.CAN.length > 0) {
+ console.error("Validation Error: 'CAN' array must be empty or absent when can_input is 'off'.");
+ return false;
+ }
+ if (data.hasOwnProperty('CAN') && !Array.isArray(data.CAN)) {
+ console.error("Validation Error: 'CAN' field should be an array if present, even when can_input is 'off'.");
+ return false;
+ }
+ }
+
+ // 모든 검사를 통과하면 유효함
+ return true;
+ }
const list = document.getElementById('modbus-field-list');
// 처음에 행이 없으면 빈 행을 하나 추가
if (list.children.length === 0) {
@@ -2151,89 +2599,6 @@
});
});
- 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('loadModbusBtn').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('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('saveProtocolBtn').addEventListener('click', () => {
console.log('버튼 클릭 됨');
@@ -2327,16 +2692,6 @@
});
});
- document.getElementById('loadCanBtn').addEventListener('click', () => {
- fetch('http://localhost:8080/setting/get-register')
- .then(res => res.json())
- .then(apiResponseData => {
- if (apiResponseData && apiResponseData.body) {
- loadFromRegisterJson(apiResponseData.body);
- alert('Protocol 설정 파일 로드 완료');
- }
- });
- });
document.getElementById('saveCanBtn').addEventListener('click', () => {
fetch('http://localhost:8080/setting/register', {
method: 'POST',
@@ -2352,82 +2707,7 @@
});
});
- document.getElementById('uploadProtocolBtn').addEventListener('click', () => {
- fetch('http://localhost:8080/setting/register-upload', {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify(collectConfigData())
- })
- .then(res => res.json())
- .then(data => {
- // result_code가 200이면 성공
- if (data.result && data.result.result_code === 200) {
- alert('하드웨어 업로드 성공!');
- } else {
- alert('하드웨어 업로드 실패: ' + (data.result?.result_message || data.body || ''));
- }
- })
- .catch(err => {
- alert('통신 오류: ' + err.message);
- });
- });
- document.getElementById('uploadModbusBtn').addEventListener('click', () => {
- fetch('http://localhost:8080/setting/register-upload', {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify(collectConfigData())
- })
- .then(res => res.json())
- .then(data => {
- // result_code가 200이면 성공
- if (data.result && data.result.result_code === 200) {
- alert('하드웨어 업로드 성공!');
- } else {
- alert('하드웨어 업로드 실패: ' + (data.result?.result_message || data.body || ''));
- }
- })
- .catch(err => {
- alert('통신 오류: ' + err.message);
- });
- });
- document.getElementById('uploadOpcuaFileBtn').addEventListener('click', () => {
- fetch('http://localhost:8080/setting/register-upload', {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify(collectConfigData())
- })
- .then(res => res.json())
- .then(data => {
- // result_code가 200이면 성공
- if (data.result && data.result.result_code === 200) {
- alert('하드웨어 업로드 성공!');
- } else {
- alert('하드웨어 업로드 실패: ' + (data.result?.result_message || data.body || ''));
- }
- })
- .catch(err => {
- alert('통신 오류: ' + err.message);
- });
- });
- document.getElementById('uploadCanBtn').addEventListener('click', () => {
- fetch('http://localhost:8080/setting/register-upload', {
- method: 'POST',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify(collectConfigData())
- })
- .then(res => res.json())
- .then(data => {
- // result_code가 200이면 성공
- if (data.result && data.result.result_code === 200) {
- alert('하드웨어 업로드 성공!');
- } else {
- alert('하드웨어 업로드 실패: ' + (data.result?.result_message || data.body || ''));
- }
- })
- .catch(err => {
- alert('통신 오류: ' + err.message);
- });
- });
+