From fc5ef28ad8971d897f854b1bb8719b3423416195 Mon Sep 17 00:00:00 2001 From: bless Date: Wed, 6 May 2026 10:18:45 +0900 Subject: [PATCH] first commit --- .../gradle-7.6-bin.zip.lck | 0 .../gradle-7.6-bin.zip.part | 0 .../gradle-7.6-bin.zip.lck | 0 .../gradle-7.6-bin.zip.part | 0 build.gradle | 15 +- .../MobidigimProjectApplication.java | 18 ++ .../config/DatabaseInitializer.java | 24 ++ .../model/device/DeviceDTO.java | 9 +- .../model/device/enums/ImuRemap.java | 19 -- .../model/device/enums/ImuRemapSign.java | 17 -- .../model/device/subDTO/Imu.java | 31 --- .../model/register/RegisterDTO.java | 17 -- .../model/register/enums/InputDataType.java | 2 +- .../model/register/sebDTO/ModbusField.java | 4 - .../model/register/sebDTO/OpcUaField.java | 6 - src/main/resources/application.yaml | 2 +- src/main/resources/static/index.html | 231 ++++-------------- src/main/resources/static/style.css | 34 ++- 18 files changed, 136 insertions(+), 293 deletions(-) create mode 100644 .gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck create mode 100644 .gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part create mode 100644 .gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck create mode 100644 .gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part create mode 100644 src/main/java/org/mobidgim/mobidigimproject/config/DatabaseInitializer.java delete mode 100644 src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemap.java delete mode 100644 src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemapSign.java delete mode 100644 src/main/java/org/mobidgim/mobidigimproject/model/device/subDTO/Imu.java diff --git a/.gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck b/.gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck new file mode 100644 index 0000000..e69de29 diff --git a/.gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part b/.gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part new file mode 100644 index 0000000..e69de29 diff --git a/.gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck b/.gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck new file mode 100644 index 0000000..e69de29 diff --git a/.gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part b/.gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part new file mode 100644 index 0000000..e69de29 diff --git a/build.gradle b/build.gradle index be7feef..5a9b1cf 100644 --- a/build.gradle +++ b/build.gradle @@ -7,13 +7,16 @@ plugins { group = 'org.mobidgim' version = '0.0.1-SNAPSHOT' -java { - toolchain { - languageVersion = JavaLanguageVersion.of(8) - } -} +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + tasks.withType(JavaCompile).configureEach { - options.release = null; + options.encoding = 'UTF-8' + options.release = 8 +} + +bootJar { + archiveFileName.set("${rootProject.name}-${version}.jar") } jar { diff --git a/src/main/java/org/mobidgim/mobidigimproject/MobidigimProjectApplication.java b/src/main/java/org/mobidgim/mobidigimproject/MobidigimProjectApplication.java index 77243e4..705a770 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/MobidigimProjectApplication.java +++ b/src/main/java/org/mobidgim/mobidigimproject/MobidigimProjectApplication.java @@ -5,6 +5,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + @SpringBootApplication // (exclude = { // DataSourceAutoConfiguration.class, @@ -14,7 +18,21 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurat public class MobidigimProjectApplication { public static void main(String[] args) { + ensureDbDirectory(); SpringApplication.run(MobidigimProjectApplication.class, args); } + private static void ensureDbDirectory() { + try { + Path dbDir = Paths.get(System.getProperty("user.home"), "db"); + Files.createDirectories(dbDir); + Path dbFile = dbDir.resolve("dynamic_data.db"); + if (Files.notExists(dbFile)) { + Files.createFile(dbFile); + } + } catch (Exception e) { + throw new IllegalStateException("Failed to prepare SQLite DB file", e); + } + } + } diff --git a/src/main/java/org/mobidgim/mobidigimproject/config/DatabaseInitializer.java b/src/main/java/org/mobidgim/mobidigimproject/config/DatabaseInitializer.java new file mode 100644 index 0000000..023c077 --- /dev/null +++ b/src/main/java/org/mobidgim/mobidigimproject/config/DatabaseInitializer.java @@ -0,0 +1,24 @@ +package org.mobidgim.mobidigimproject.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class DatabaseInitializer implements ApplicationRunner { + + private final JdbcTemplate jdbcTemplate; + + @Override + public void run(ApplicationArguments args) { + jdbcTemplate.execute( + "CREATE TABLE IF NOT EXISTS board_config (" + + "\"key\" TEXT PRIMARY KEY, " + + "\"value\" TEXT NOT NULL" + + ")" + ); + } +} diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/device/DeviceDTO.java b/src/main/java/org/mobidgim/mobidigimproject/model/device/DeviceDTO.java index d65d66e..7542e6a 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/device/DeviceDTO.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/device/DeviceDTO.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonUnwrapped; import lombok.Getter; import lombok.Setter; -import org.mobidgim.mobidigimproject.model.device.subDTO.Imu; import org.mobidgim.mobidigimproject.model.device.subDTO.*; import java.util.List; @@ -15,6 +14,9 @@ import java.util.List; @JsonInclude(JsonInclude.Include.NON_NULL) public class DeviceDTO { + @JsonProperty("wifi_country_code") + private String wifiCountryCode; + @JsonUnwrapped private Wifi wifiConfig; @@ -30,9 +32,6 @@ public class DeviceDTO { @JsonUnwrapped private Rs485 rs485Config; - @JsonUnwrapped - private Imu imuConfig; - @JsonUnwrapped private Lte lteConfig; @@ -41,4 +40,4 @@ public class DeviceDTO { @JsonProperty("WIFI_SSID") private List wifiSsid; -} \ No newline at end of file +} diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemap.java b/src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemap.java deleted file mode 100644 index 5049e32..0000000 --- a/src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemap.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.mobidgim.mobidigimproject.model.device.enums; - -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; - - -@AllArgsConstructor -public enum ImuRemap { - NONE(""), - X("x"), - Y("y"), - Z("z"); - private final String remap; - - @JsonValue - public String getRemap() { - return remap; - } -} diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemapSign.java b/src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemapSign.java deleted file mode 100644 index bafbbcd..0000000 --- a/src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemapSign.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mobidgim.mobidigimproject.model.device.enums; - -import com.fasterxml.jackson.annotation.JsonValue; -import lombok.AllArgsConstructor; - -@AllArgsConstructor -public enum ImuRemapSign { - NONE(""), - MINUS("minus"), - PLUS("plus"); - private final String sign; - - @JsonValue - public String getSign() { - return sign; - } -} diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/device/subDTO/Imu.java b/src/main/java/org/mobidgim/mobidigimproject/model/device/subDTO/Imu.java deleted file mode 100644 index 8f7a630..0000000 --- a/src/main/java/org/mobidgim/mobidigimproject/model/device/subDTO/Imu.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.mobidgim.mobidigimproject.model.device.subDTO; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; -import lombok.Setter; -import org.mobidgim.mobidigimproject.model.device.enums.ImuRemap; -import org.mobidgim.mobidigimproject.model.device.enums.ImuRemapSign; - -@Getter -@Setter -@JsonInclude(JsonInclude.Include.NON_NULL) -public class Imu { - @JsonProperty("imu_remap_x") - private ImuRemap imuRemapX; - - @JsonProperty("imu_remap_y") - private ImuRemap imuRemapY; - - @JsonProperty("imu_remap_z") - private ImuRemap imuRemapZ; - - @JsonProperty("imu_remap_x_sign") - private ImuRemapSign imuRemapXSign; - - @JsonProperty("imu_remap_y_sign") - private ImuRemapSign imuRemapYSign; - - @JsonProperty("imu_remap_z_sign") - private ImuRemapSign imuRemapZSign; -} diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/RegisterDTO.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/RegisterDTO.java index 946fc2b..8c334bc 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/register/RegisterDTO.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/RegisterDTO.java @@ -26,18 +26,10 @@ public class RegisterDTO { private AnalogPort ai1; - private AnalogPort ai2; - - private AnalogPort ai3; - private AnalogPort di0; private AnalogPort di1; - private AnalogPort di2; - - private AnalogPort di3; - @JsonProperty("can_input") private CanInput canInput; @@ -69,15 +61,6 @@ public class RegisterDTO { @JsonDeserialize(using = MeidDeserializer.class) private String meid; - @JsonProperty("heading_on") - private HeadingOn headingOn; - - @JsonProperty("heading_imu_on") - private HeadingImuOn headingImuOn; - - @JsonProperty("fix_mode_on") - private FixmodeOn fixModeOn; - @JsonProperty("MODBUS") private List MODBUS; diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/InputDataType.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/InputDataType.java index 6e07ec7..64ffa95 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/InputDataType.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/enums/InputDataType.java @@ -6,7 +6,7 @@ import lombok.AllArgsConstructor; @AllArgsConstructor public enum InputDataType { integer("integer"), - flo("float64"), + flo("float"), bool("boolean"), unsignedInteger("unsignedInteger"), shor("short"), diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/ModbusField.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/ModbusField.java index 191d33f..c1d2c52 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/ModbusField.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/ModbusField.java @@ -25,10 +25,6 @@ public class ModbusField { @JsonProperty("dv") // default value private String defaultValue; - private int shift; - - private String mask; - private String expr; // expression } \ No newline at end of file diff --git a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OpcUaField.java b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OpcUaField.java index 690a832..05f3aa7 100644 --- a/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OpcUaField.java +++ b/src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OpcUaField.java @@ -23,11 +23,5 @@ public class OpcUaField { @JsonProperty("dv") // default value private String defaultValue; - private int shift; - - private String mask; - private String expr; // expression - - } \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 291b6fd..9dca12b 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -8,7 +8,7 @@ spring: jpa: hibernate: - ddl-auto: none # 초기엔 update, 이후 none 권장 + ddl-auto: none # SQLite는 자동 스키마 변경이 약해서 수동/초기화 코드로 관리 properties: hibernate: format_sql: true diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index d638b2e..d070140 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -57,6 +57,14 @@
+
+

Region

+
+ + + 2-letter code such as KR, EU, JP, US +
+
-

CAN / IMU Re-map

+

CAN

Can Type:
-
imu re-map x: - -
-
imu re-map y:
-
imu re-map z:
-
@@ -317,20 +293,6 @@ -
heading_on - -
-
heading_imu_on - -
DR On/Off @@ -370,13 +332,6 @@
-
fixmode_on - -
Analog Input Level AI1 - -
@@ -437,9 +380,7 @@ - - @@ -455,9 +396,7 @@ IDT ODT Default Value - Shift Expression - Mask @@ -472,7 +411,7 @@ - - - -
@@ -526,9 +461,7 @@ - - @@ -544,9 +477,7 @@ NS ODT Default Value - Shift Expression - Mask @@ -569,14 +500,10 @@ - - - -
@@ -686,9 +613,11 @@ const ssidList = document.getElementById('ssid-list'); const ssidTmpl = document.getElementById('ssid-template'); + const countryCodeInput = document.getElementById('wifi_country_code'); const data = { /* Wi-Fi */ wifi_static: '', wifi_ip: '', wifi_netmask: '', wifi_gateway: '', wifi_dns1: '', wifi_dns2: '', + wifi_country_code: '', /* Ethernet */ eth_ip: '', eth_netmask: '', eth_gateway: '', @@ -711,10 +640,6 @@ rs485_mode: '', rs485_baudrate: null, rs485_databits: null, rs485_parity: '', rs485_stopbits: null, - /* IMU (축 + 부호) */ - imu_remap_x: '', imu_remap_y: '', imu_remap_z: '', - imu_remap_x_sign: '', imu_remap_y_sign: '', imu_remap_z_sign: '', - /* LTE 설정 */ lte_ip: '', lte_netmask: '', lte_gateway: '', lte_port: null, @@ -729,12 +654,8 @@ 'reg_analog_input_level': 'analog_input_level', 'ai0': 'ai0', 'ai1': 'ai1', - 'ai2': 'ai2', - 'ai3': 'ai3', 'di0': 'di0', 'di1': 'di1', - 'di2': 'di2', - 'di3': 'di3', 'reg_can_input': 'can_input', 'reg_device_type': 'dev_type', 'reg_dr_on_off': 'dr_on', @@ -746,9 +667,6 @@ 'reg_version': 'version', 'reg_equipment_id': 'equipment_id', 'reg_meid': 'MEID', - 'reg_heading_on': 'heading_on', - 'reg_heading_imu_on': 'heading_imu_on', - 'reg_fixmode_on': 'fix_mode_on' }; let lastLoadedRegisterData = {}; @@ -963,9 +881,7 @@ document.getElementById('modbus_idt_input').value = tr.querySelector('.idt-display').textContent; document.getElementById('modbus_odt_input').value = tr.querySelector('.odt-display').textContent; document.getElementById('modbus_dv_input').value = tr.querySelector('.dv-display').textContent; - document.getElementById('modbus_shift_input').value = tr.querySelector('.shift-display').textContent; document.getElementById('modbus_expr_input').value = tr.querySelector('.expr-display').textContent; - document.getElementById('modbus_mask_input').value = tr.querySelector('.mask-display').textContent; }); // 처음에 행이 없으면 빈 행을 하나 추가 if (modbusList.children.length === 0) { @@ -992,9 +908,7 @@ document.getElementById('opcua_ns_input').value = tr.querySelector('.opcua-ns-display').textContent; document.getElementById('opcua_odt_input').value = tr.querySelector('.opcua-odt-display').textContent; document.getElementById('opcua_dv_input').value = tr.querySelector('.opcua-dv-display').textContent; - document.getElementById('opcua_shift_input').value = tr.querySelector('.opcua-shift-display').textContent; document.getElementById('opcua_expr_input').value = tr.querySelector('.opcua-expr-display').textContent; - document.getElementById('opcua_mask_input').value = tr.querySelector('.opcua-mask-display').textContent; }); // 처음에 행이 없으면 빈 행을 하나 추가 if (opcUaList.children.length === 0) { @@ -1037,9 +951,7 @@ const idt = document.getElementById('modbus_idt_input').value; const odt = document.getElementById('modbus_odt_input').value; const defaultValue = document.getElementById('modbus_dv_input').value; - const shift = document.getElementById('modbus_shift_input').value; const expr = document.getElementById('modbus_expr_input').value; - const mask = document.getElementById('modbus_mask_input').value; const firstRow = modbusFieldList.querySelector('tr'); @@ -1050,9 +962,7 @@ firstRow.querySelector('.idt-display').textContent = idt; firstRow.querySelector('.odt-display').textContent = odt; firstRow.querySelector('.dv-display').textContent = defaultValue; - firstRow.querySelector('.shift-display').textContent = shift; firstRow.querySelector('.expr-display').textContent = expr; - firstRow.querySelector('.mask-display').textContent = mask; } else { // 새로운 행을 추가 const newRow = modbusRowTemplate.content.cloneNode(true); @@ -1061,9 +971,7 @@ newRow.querySelector('.idt-display').textContent = idt; newRow.querySelector('.odt-display').textContent = odt; newRow.querySelector('.dv-display').textContent = defaultValue; - newRow.querySelector('.shift-display').textContent = shift; newRow.querySelector('.expr-display').textContent = expr; - newRow.querySelector('.mask-display').textContent = mask; modbusFieldList.appendChild(newRow); } @@ -1074,9 +982,7 @@ document.getElementById('modbus_idt_input').value = ''; document.getElementById('modbus_odt_input').value = ''; document.getElementById('modbus_dv_input').value = ''; - document.getElementById('modbus_shift_input').value = ''; document.getElementById('modbus_expr_input').value = ''; - document.getElementById('modbus_mask_input').value = ''; }); @@ -1087,9 +993,7 @@ selectedRow.querySelector('.idt-display').textContent = document.getElementById('modbus_idt_input').value; selectedRow.querySelector('.odt-display').textContent = document.getElementById('modbus_odt_input').value; selectedRow.querySelector('.dv-display').textContent = document.getElementById('modbus_dv_input').value; - selectedRow.querySelector('.shift-display').textContent = document.getElementById('modbus_shift_input').value; selectedRow.querySelector('.expr-display').textContent = document.getElementById('modbus_expr_input').value; - selectedRow.querySelector('.mask-display').textContent = document.getElementById('modbus_mask_input').value; }; // 삭제 버튼 @@ -1107,9 +1011,7 @@ const ns = document.getElementById('opcua_ns_input').value; const odt = document.getElementById('opcua_odt_input').value; const defaultValue = document.getElementById('opcua_dv_input').value; - const shift = document.getElementById('opcua_shift_input').value; const expr = document.getElementById('opcua_expr_input').value; - const mask = document.getElementById('opcua_mask_input').value; const firstRow = opcUaFieldList.querySelector('tr'); @@ -1120,9 +1022,7 @@ firstRow.querySelector('.opcua-ns-display').textContent = ns; firstRow.querySelector('.opcua-odt-display').textContent = odt; firstRow.querySelector('.opcua-dv-display').textContent = defaultValue; - firstRow.querySelector('.opcua-shift-display').textContent = shift; firstRow.querySelector('.opcua-expr-display').textContent = expr; - firstRow.querySelector('.opcua-mask-display').textContent = mask; } else { // 새로운 행을 추가 const newRow = opcUaRowTemplate.content.cloneNode(true); @@ -1131,9 +1031,7 @@ newRow.querySelector('.opcua-ns-display').textContent = ns; newRow.querySelector('.opcua-odt-display').textContent = odt; newRow.querySelector('.opcua-dv-display').textContent = defaultValue; - newRow.querySelector('.opcua-shift-display').textContent = shift; newRow.querySelector('.opcua-expr-display').textContent = expr; - newRow.querySelector('.opcua-mask-display').textContent = mask; opcUaFieldList.appendChild(newRow); } @@ -1144,9 +1042,7 @@ document.getElementById('opcua_ns_input').value = ''; document.getElementById('opcua_odt_input').value = ''; document.getElementById('opcua_dv_input').value = ''; - document.getElementById('opcua_shift_input').value = ''; document.getElementById('opcua_expr_input').value = ''; - document.getElementById('opcua_mask_input').value = ''; }); @@ -1158,9 +1054,7 @@ selectedRow.querySelector('.opcua-ns-display').textContent = document.getElementById('opcua_ns_input').value; selectedRow.querySelector('.opcua-odt-display').textContent = document.getElementById('opcua_odt_input').value; selectedRow.querySelector('.opcua-dv-display').textContent = document.getElementById('opcua_dv_input').value; - selectedRow.querySelector('.opcua-shift-display').textContent = document.getElementById('opcua_shift_input').value; selectedRow.querySelector('.opcua-expr-display').textContent = document.getElementById('opcua_expr_input').value; - selectedRow.querySelector('.opcua-mask-display').textContent = document.getElementById('opcua_mask_input').value; }; // 삭제 버튼 @@ -1257,7 +1151,7 @@ } /*----서버로 데이터 전송하는 함수----*/ - function saveToConfig() { + async function saveToConfig() { const deviceData = collectDeviceData(); const protocolData = collectProtocolData(); const normalizedProtocol = normalizeRegisterForPost(protocolData); @@ -1265,34 +1159,34 @@ alert("Register settings are currently invalid. Cannot be saved."); return; } - //device - const deviceReq = fetch('/setting/device', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(deviceData) - }); - - //protocol - const protocolReq = fetch('/setting/protocol', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(normalizedProtocol) - }); + try { + const deviceRes = await fetch('/setting/device', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(deviceData) + }); - // 모든 요청이 성공하면 성공 알림 - Promise.all([deviceReq, protocolReq]) - .then(([res1, res2]) => { - if (res1.ok && res2.ok) { - alert('saved successfully'); - } else { - alert('save failure'); - console.error('device response:', res1.status, 'protocol response:', res2.status); - } - }) - .catch(err => { - console.error('Error during transfer:', err); - alert('save failure'); + const protocolRes = await fetch('/setting/protocol', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(normalizedProtocol) }); + + if (deviceRes.ok && protocolRes.ok) { + alert('saved successfully'); + return; + } + + const protocolErrorText = protocolRes.ok ? '' : await protocolRes.text(); + alert('save failure'); + console.error('device response:', deviceRes.status, 'protocol response:', protocolRes.status); + if (protocolErrorText) { + console.error('protocol error body:', protocolErrorText); + } + } catch (err) { + console.error('Error during transfer:', err); + alert('save failure'); + } } }); @@ -1305,6 +1199,9 @@ //ssid 행 추가 버튼 document.getElementById('add-ssid').addEventListener('click', addSsidRow); + countryCodeInput?.addEventListener('input', () => { + countryCodeInput.value = countryCodeInput.value.replace(/[^a-zA-Z]/g, '').slice(0, 2).toUpperCase(); + }); // function clearAllInputs() { // // 모든 input[type="text"], [type="number"], [type="password"] 등 초기화 @@ -1343,8 +1240,6 @@ // can_bus_type: '', can_baudrate: null, // rs485_mode: '', rs485_baudrate: null, rs485_data_bits: null, // rs485_parity: '', rs485_stop_bits: null, - // imu_remap_x: '', imu_remap_y: '', imu_remap_z: '', - // imu_remap_x_sign: '', imu_remap_y_sign: '', imu_remap_z_sign: '', // lte_ip: '', lte_netmask: '', lte_gateway: '', lte_port: null, // WIFI_SSID: [{wifi_ssid: '', wifi_password: '', wifi_security: 'none'}], // }; @@ -1368,13 +1263,10 @@ } } //x,y,z,부호 처리 - ['x', 'y', 'z'].forEach(a => { - const { axis, sign } = axisValueToPair(document.getElementById(`imu_remap_${a}`).value); - res[`imu_remap_${a}`] = axis; - res[`imu_remap_${a}_sign`] = sign; - }); - res.WIFI_SSID = gatherSsidRows(); + if (typeof res.wifi_country_code === 'string') { + res.wifi_country_code = res.wifi_country_code.trim().toUpperCase(); + } //null, 공백 없이 데이터 전처리 const filtered = {}; @@ -1427,16 +1319,12 @@ const idt = row.querySelector('.idt-display')?.textContent.trim(); const odt = row.querySelector('.odt-display')?.textContent.trim(); const dv = row.querySelector('.dv-display')?.textContent.trim(); - const shift = row.querySelector('.shift-display')?.textContent.trim(); const expr = row.querySelector('.expr-display')?.textContent.trim(); - const mask = row.querySelector('.mask-display')?.textContent.trim(); if (addr) obj.addr = addr; if (idt) obj.idt = idt; if (odt) obj.odt = odt; if (dv) obj.dv = dv; - if (shift) obj.shift = shift; if (expr) obj.expr = expr; - if (mask) obj.mask = mask; collectedRegister.MODBUS.push(obj); } }); @@ -1453,16 +1341,12 @@ const ns = row.querySelector('.opcua-ns-display')?.textContent.trim(); const odt = row.querySelector('.opcua-odt-display')?.textContent.trim(); const dv = row.querySelector('.opcua-dv-display')?.textContent.trim(); - const shift = row.querySelector('.opcua-shift-display')?.textContent.trim(); const expr = row.querySelector('.opcua-expr-display')?.textContent.trim(); - const mask = row.querySelector('.opcua-mask-display')?.textContent.trim(); if (addr) obj.addr = addr; if (ns) obj.ns = ns; if (odt) obj.odt = odt; if (dv) obj.dv = dv; - if (shift) obj.shift = shift; if (expr) obj.expr = expr; - if (mask) obj.mask = mask; collectedRegister.OPC_UA.push(obj); } }); @@ -1673,9 +1557,6 @@ 'version', 'equipment_id', 'MEID', - 'heading_on', - 'heading_imu_on', - 'fix_mode_on' ]; @@ -1818,16 +1699,6 @@ /*-----------------------------------------------------*/ /*-------imu-remap 정수와 부호 분리 함수-------------*/ - function axisValueToPair(val) { - if (!val || val === '') return { axis: '', sign: '' }; - return val.startsWith('-') - ? { axis: val.slice(1), sign: 'minus' } - : { axis: val, sign: 'plus' }; - } - - function pairToAxisValue(axis, sign) { - return sign === 'minus' ? `-${axis}` : axis; - } /*-----------------------------------------------------*/ /*--------초기 랜더링 화면 함수------------*/ @@ -1849,12 +1720,6 @@ } /* IMU select 값 재구성 */ - ['x', 'y', 'z'].forEach(a => { - const axis = obj[`imu_remap_${a}`] || ''; - const sign = obj[`imu_remap_${a}_sign`] || ''; - document.getElementById(`imu_remap_${a}`).value = pairToAxisValue(axis, sign); - }); - /* SSID */ ssidList.innerHTML = ''; (obj.WIFI_SSID || []).forEach(o => ssidList.appendChild(createSsidRow(o))); @@ -1957,9 +1822,7 @@ newRow.querySelector('.idt-display').textContent = field.idt ?? ''; newRow.querySelector('.odt-display').textContent = field.odt ?? ''; newRow.querySelector('.dv-display').textContent = field.dv ?? ''; - newRow.querySelector('.shift-display').textContent = field.shift ?? ''; newRow.querySelector('.expr-display').textContent = field.expr ?? ''; - newRow.querySelector('.mask-display').textContent = field.mask ?? ''; modbusFieldList.appendChild(newRow); }); } else { @@ -1984,9 +1847,7 @@ newRow.querySelector('.opcua-ns-display').textContent = field.ns ?? ''; newRow.querySelector('.opcua-odt-display').textContent = field.odt ?? ''; newRow.querySelector('.opcua-dv-display').textContent = field.dv ?? ''; - newRow.querySelector('.opcua-shift-display').textContent = field.shift ?? ''; newRow.querySelector('.opcua-expr-display').textContent = field.expr ?? ''; - newRow.querySelector('.opcua-mask-display').textContent = field.mask ?? ''; opcUaFieldList.appendChild(newRow); }); } else { @@ -2019,4 +1880,4 @@ } - \ No newline at end of file + diff --git a/src/main/resources/static/style.css b/src/main/resources/static/style.css index b92ac57..3f06eb1 100644 --- a/src/main/resources/static/style.css +++ b/src/main/resources/static/style.css @@ -166,6 +166,36 @@ details.nav { .icon-button:active { background-color: #c0c0c0; } + +.ssid-country-code { + display: flex; + align-items: center; + gap: 12px; + margin-top: 16px; +} + +.ssid-country-code label { + min-width: 100px; + font-weight: 600; +} + +.ssid-country-code input { + width: 80px; + padding: 6px 8px; + font-size: 16px; + border: 1px solid #aaa; + border-radius: 4px; + text-transform: uppercase; +} + +.separate-setting-card { + margin-top: 16px; +} + +.field-hint { + color: #666; + font-size: 13px; +} /* 3-column grids (Network / Server) */ .grid-3-col { display: grid; @@ -256,6 +286,7 @@ details.nav { #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 tbody td {height: 34px;vertical-align: middle;} #page-modbus .modbus-input-area {display: grid;grid-template-columns: 200px 200px 200px 200px;gap: 20px 20px;margin: 24px auto 16px auto;background: #eaeaea;padding: 16px;border-radius: 4px;margin-left: auto;margin-right: auto;} #page-modbus .input-row {display: contents;} #page-modbus .modbus-input-area label.nowrap {white-space: nowrap;} @@ -272,6 +303,7 @@ details.nav { #page-opcua table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} #page-opcua th, #page-opcua td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} #page-opcua th {background: #e5e5e5;font-weight: 500;} +#page-opcua tbody td {height: 34px;vertical-align: middle;} #page-opcua .opcua-input-area {display: grid;grid-template-columns: 200px 200px 200px 200px;gap: 20px 20px;margin: 24px auto 16px auto;background: #eaeaea;padding: 16px;border-radius: 4px;margin-left: auto;margin-right: auto;} #page-opcua .input-row {display: contents;} #page-opcua .opcua-input-area label.nowrap {white-space: nowrap;} @@ -300,4 +332,4 @@ details.nav { .selected-row {background: #d0e6ff !important;} .selected-row > td {background: #d0e6ff !important;} -.file-upload-section{padding: 10px;margin: 10px;text-align: center;} \ No newline at end of file +.file-upload-section{padding: 10px;margin: 10px;text-align: center;}