Browse Source

first commit

v2
최원형 3 months ago
parent
commit
fc5ef28ad8
  1. 0
      .gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck
  2. 0
      .gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part
  3. 0
      .gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck
  4. 0
      .gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part
  5. 15
      build.gradle
  6. 18
      src/main/java/org/mobidgim/mobidigimproject/MobidigimProjectApplication.java
  7. 24
      src/main/java/org/mobidgim/mobidigimproject/config/DatabaseInitializer.java
  8. 7
      src/main/java/org/mobidgim/mobidigimproject/model/device/DeviceDTO.java
  9. 19
      src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemap.java
  10. 17
      src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemapSign.java
  11. 31
      src/main/java/org/mobidgim/mobidigimproject/model/device/subDTO/Imu.java
  12. 17
      src/main/java/org/mobidgim/mobidigimproject/model/register/RegisterDTO.java
  13. 2
      src/main/java/org/mobidgim/mobidigimproject/model/register/enums/InputDataType.java
  14. 4
      src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/ModbusField.java
  15. 6
      src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OpcUaField.java
  16. 2
      src/main/resources/application.yaml
  17. 229
      src/main/resources/static/index.html
  18. 32
      src/main/resources/static/style.css

0
.gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck

0
.gradle-home/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part

0
.gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.lck

0
.gradle-local/wrapper/dists/gradle-7.6-bin/9l9tetv7ltxvx3i8an4pb86ye/gradle-7.6-bin.zip.part

15
build.gradle

@ -7,13 +7,16 @@ plugins {
group = 'org.mobidgim' group = 'org.mobidgim'
version = '0.0.1-SNAPSHOT' version = '0.0.1-SNAPSHOT'
java { sourceCompatibility = JavaVersion.VERSION_1_8
toolchain { targetCompatibility = JavaVersion.VERSION_1_8
languageVersion = JavaLanguageVersion.of(8)
}
}
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile).configureEach {
options.release = null; options.encoding = 'UTF-8'
options.release = 8
}
bootJar {
archiveFileName.set("${rootProject.name}-${version}.jar")
} }
jar { jar {

18
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.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@SpringBootApplication @SpringBootApplication
// (exclude = { // (exclude = {
// DataSourceAutoConfiguration.class, // DataSourceAutoConfiguration.class,
@ -14,7 +18,21 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurat
public class MobidigimProjectApplication { public class MobidigimProjectApplication {
public static void main(String[] args) { public static void main(String[] args) {
ensureDbDirectory();
SpringApplication.run(MobidigimProjectApplication.class, args); 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);
}
}
} }

24
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" +
")"
);
}
}

7
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 com.fasterxml.jackson.annotation.JsonUnwrapped;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.mobidgim.mobidigimproject.model.device.subDTO.Imu;
import org.mobidgim.mobidigimproject.model.device.subDTO.*; import org.mobidgim.mobidigimproject.model.device.subDTO.*;
import java.util.List; import java.util.List;
@ -15,6 +14,9 @@ import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class DeviceDTO { public class DeviceDTO {
@JsonProperty("wifi_country_code")
private String wifiCountryCode;
@JsonUnwrapped @JsonUnwrapped
private Wifi wifiConfig; private Wifi wifiConfig;
@ -30,9 +32,6 @@ public class DeviceDTO {
@JsonUnwrapped @JsonUnwrapped
private Rs485 rs485Config; private Rs485 rs485Config;
@JsonUnwrapped
private Imu imuConfig;
@JsonUnwrapped @JsonUnwrapped
private Lte lteConfig; private Lte lteConfig;

19
src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemap.java

@ -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;
}
}

17
src/main/java/org/mobidgim/mobidigimproject/model/device/enums/ImuRemapSign.java

@ -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;
}
}

31
src/main/java/org/mobidgim/mobidigimproject/model/device/subDTO/Imu.java

@ -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;
}

17
src/main/java/org/mobidgim/mobidigimproject/model/register/RegisterDTO.java

@ -26,18 +26,10 @@ public class RegisterDTO {
private AnalogPort ai1; private AnalogPort ai1;
private AnalogPort ai2;
private AnalogPort ai3;
private AnalogPort di0; private AnalogPort di0;
private AnalogPort di1; private AnalogPort di1;
private AnalogPort di2;
private AnalogPort di3;
@JsonProperty("can_input") @JsonProperty("can_input")
private CanInput canInput; private CanInput canInput;
@ -69,15 +61,6 @@ public class RegisterDTO {
@JsonDeserialize(using = MeidDeserializer.class) @JsonDeserialize(using = MeidDeserializer.class)
private String meid; 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") @JsonProperty("MODBUS")
private List<ModbusField> MODBUS; private List<ModbusField> MODBUS;

2
src/main/java/org/mobidgim/mobidigimproject/model/register/enums/InputDataType.java

@ -6,7 +6,7 @@ import lombok.AllArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
public enum InputDataType { public enum InputDataType {
integer("integer"), integer("integer"),
flo("float64"), flo("float"),
bool("boolean"), bool("boolean"),
unsignedInteger("unsignedInteger"), unsignedInteger("unsignedInteger"),
shor("short"), shor("short"),

4
src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/ModbusField.java

@ -25,10 +25,6 @@ public class ModbusField {
@JsonProperty("dv") // default value @JsonProperty("dv") // default value
private String defaultValue; private String defaultValue;
private int shift;
private String mask;
private String expr; // expression private String expr; // expression
} }

6
src/main/java/org/mobidgim/mobidigimproject/model/register/sebDTO/OpcUaField.java

@ -23,11 +23,5 @@ public class OpcUaField {
@JsonProperty("dv") // default value @JsonProperty("dv") // default value
private String defaultValue; private String defaultValue;
private int shift;
private String mask;
private String expr; // expression private String expr; // expression
} }

2
src/main/resources/application.yaml

@ -8,7 +8,7 @@ spring:
jpa: jpa:
hibernate: hibernate:
ddl-auto: none # 초기엔 update, 이후 none 권장 ddl-auto: none # SQLite는 자동 스키마 변경이 약해서 수동/초기화 코드로 관리
properties: properties:
hibernate: hibernate:
format_sql: true format_sql: true

229
src/main/resources/static/index.html

@ -57,6 +57,14 @@
<div id="ssid-list"></div> <div id="ssid-list"></div>
<button id="add-ssid" class="icon-button" title="add SSID"></button> <button id="add-ssid" class="icon-button" title="add SSID"></button>
</div> </div>
<div class="card separate-setting-card">
<h3>Region</h3>
<div class="ssid-country-code">
<label for="wifi_country_code">Country Code</label>
<input id="wifi_country_code" maxlength="2" placeholder="KR" />
<span class="field-hint">2-letter code such as KR, EU, JP, US</span>
</div>
</div>
<div class="actions"> <div class="actions">
<div class="file-upload-wrapper-device" <div class="file-upload-wrapper-device"
data-file-type="device" data-file-type="device"
@ -184,7 +192,7 @@
</div> </div>
<!-- CAN --> <!-- CAN -->
<div class="io-group"> <div class="io-group">
<h4>CAN / IMU Re-map</h4> <h4>CAN</h4>
<div class="io-fieldset"> <div class="io-fieldset">
<div class="io-row"><span class="label-inline">Can Type</span><span class="colon">:</span> <div class="io-row"><span class="label-inline">Can Type</span><span class="colon">:</span>
<select id="can_bus_type"> <select id="can_bus_type">
@ -203,38 +211,6 @@
<option value="10000">1M/s</option> <option value="10000">1M/s</option>
</select> </select>
</div> </div>
<div class="io-row"><span class="label-inline">imu re-map x</span><span class="colon">:</span>
<select id="imu_remap_x">
<option value="">NONE</option>
<option value="x">x</option>
<option value="y">y</option>
<option value="z">z</option>
<option value="-x">-x</option>
<option value="-y">-y</option>
<option value="-z">-z</option>
</select>
</div>
<div class="io-row"><span class="label-inline">imu re-map y</span><span
class="colon">:</span><select id="imu_remap_y">
<option value="">NONE</option>
<option value="x">x</option>
<option value="y">y</option>
<option value="z">z</option>
<option value="-x">-x</option>
<option value="-y">-y</option>
<option value="-z">-z</option>
</select></div>
<div class="io-row"><span class="label-inline">imu re-map z</span><span
class="colon">:</span><select id="imu_remap_z">
<option value="">NONE</option>
<option value="x">x</option>
<option value="y">y</option>
<option value="z">z</option>
<option value="-x">-x</option>
<option value="-y">-y</option>
<option value="-z">-z</option>
</select></div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -317,20 +293,6 @@
<option value="OPC_UA">OPC_UA</option> <option value="OPC_UA">OPC_UA</option>
</select> </select>
</div> </div>
<div class="io-row"><span class="label">heading_on</span>
<select id="reg_heading_on">
<option selected disabled hidden="hidden"></option>
<option value="on">on</option>
<option value="off">off</option>
</select>
</div>
<div class="io-row"><span class="label">heading_imu_on</span>
<select id="reg_heading_imu_on">
<option selected disabled hidden="hidden"></option>
<option value="on">on</option>
<option value="off">off</option>
</select>
</div>
</div> </div>
<div class="io-fieldset"> <div class="io-fieldset">
<div class="io-row"><span class="label">DR On/Off</span> <div class="io-row"><span class="label">DR On/Off</span>
@ -370,13 +332,6 @@
<option value="off">off</option> <option value="off">off</option>
</select> </select>
</div> </div>
<div class="io-row"><span class="label">fixmode_on</span>
<select id="reg_fixmode_on">
<option selected disabled hidden="hidden"></option>
<option value="on">on</option>
<option value="off">off</option>
</select>
</div>
<div class="io-row"><span class="label">Analog Input Level</span> <div class="io-row"><span class="label">Analog Input Level</span>
<select id="reg_analog_input_level"> <select id="reg_analog_input_level">
<option selected disabled hidden="hidden"></option> <option selected disabled hidden="hidden"></option>
@ -392,12 +347,6 @@
<label class="checkbox-with-text"> <label class="checkbox-with-text">
<input type="checkbox" id="ai1"/>AI1 <input type="checkbox" id="ai1"/>AI1
</label> </label>
<label class="checkbox-with-text">
<input type="checkbox" id="ai2"/>AI2
</label>
<label class="checkbox-with-text">
<input type="checkbox" id="ai3"/>AI3
</label>
</div> </div>
<div class="io-row checkbox-group"> <div class="io-row checkbox-group">
<label class="checkbox-with-text"> <label class="checkbox-with-text">
@ -406,12 +355,6 @@
<label class="checkbox-with-text"> <label class="checkbox-with-text">
<input type="checkbox" id="di1"/>DI1 <input type="checkbox" id="di1"/>DI1
</label> </label>
<label class="checkbox-with-text">
<input type="checkbox" id="di2"/>DI2
</label>
<label class="checkbox-with-text">
<input type="checkbox" id="di3"/>DI3
</label>
</div> </div>
</div> </div>
</div> </div>
@ -437,9 +380,7 @@
<td><span class="idt-display"></span></td> <td><span class="idt-display"></span></td>
<td><span class="odt-display"></span></td> <td><span class="odt-display"></span></td>
<td><span class="dv-display"></span></td> <td><span class="dv-display"></span></td>
<td><span class="shift-display"></span></td>
<td><span class="expr-display"></span></td> <td><span class="expr-display"></span></td>
<td><span class="mask-display"></span></td>
</tr> </tr>
</template> </template>
@ -455,9 +396,7 @@
<th>IDT</th> <th>IDT</th>
<th>ODT</th> <th>ODT</th>
<th>Default Value</th> <th>Default Value</th>
<th>Shift</th>
<th>Expression</th> <th>Expression</th>
<th>Mask</th>
</tr> </tr>
</thead> </thead>
<tbody id="modbus-field-list"> <tbody id="modbus-field-list">
@ -472,7 +411,7 @@
<select id="modbus_idt_input"> <select id="modbus_idt_input">
<option selected disabled hidden="hidden"></option> <option selected disabled hidden="hidden"></option>
<option value="integer">integer</option> <option value="integer">integer</option>
<option value="float64">float64</option> <option value="float">float</option>
<option value="boolean">boolean</option> <option value="boolean">boolean</option>
<option value="unsignedInteger">unsignedInteger</option> <option value="unsignedInteger">unsignedInteger</option>
<option value="short">short</option> <option value="short">short</option>
@ -488,14 +427,10 @@
<option value="boolean">boolean</option> <option value="boolean">boolean</option>
<option value="string">string</option> <option value="string">string</option>
</select> </select>
<label>shift</label>
<input type="text" id="modbus_shift_input" placeholder="Enter shift value">
<label class="nowrap">dv</label> <label class="nowrap">dv</label>
<input type="text" id="modbus_dv_input" placeholder="Enter default value"> <input type="text" id="modbus_dv_input" placeholder="Enter default value">
<label>expr</label> <label>expr</label>
<input type="text" id="modbus_expr_input" placeholder="Enter expression"> <input type="text" id="modbus_expr_input" placeholder="Enter expression">
<label class="nowrap">mask</label>
<input type="text" id="modbus_mask_input" placeholder="Enter mask">
</div> </div>
<div class="modbus-actions"> <div class="modbus-actions">
@ -526,9 +461,7 @@
<td><span class="opcua-ns-display"></span></td> <td><span class="opcua-ns-display"></span></td>
<td><span class="opcua-odt-display"></span></td> <td><span class="opcua-odt-display"></span></td>
<td><span class="opcua-dv-display"></span></td> <td><span class="opcua-dv-display"></span></td>
<td><span class="opcua-shift-display"></span></td>
<td><span class="opcua-expr-display"></span></td> <td><span class="opcua-expr-display"></span></td>
<td><span class="opcua-mask-display"></span></td>
</tr> </tr>
</template> </template>
@ -544,9 +477,7 @@
<th>NS</th> <th>NS</th>
<th>ODT</th> <th>ODT</th>
<th>Default Value</th> <th>Default Value</th>
<th>Shift</th>
<th>Expression</th> <th>Expression</th>
<th>Mask</th>
</tr> </tr>
</thead> </thead>
<tbody id="opcua-field-list"> <tbody id="opcua-field-list">
@ -569,14 +500,10 @@
<option value="boolean">boolean</option> <option value="boolean">boolean</option>
<option value="string">string</option> <option value="string">string</option>
</select> </select>
<label>shift</label>
<input type="text" id="opcua_shift_input" placeholder="Enter shift value">
<label class="nowrap">dv(Default Value)</label> <label class="nowrap">dv(Default Value)</label>
<input type="text" id="opcua_dv_input" placeholder="Enter default value"> <input type="text" id="opcua_dv_input" placeholder="Enter default value">
<label>expr</label> <label>expr</label>
<input type="text" id="opcua_expr_input" placeholder="Enter expression"> <input type="text" id="opcua_expr_input" placeholder="Enter expression">
<label class="nowrap">mask</label>
<input type="text" id="opcua_mask_input" placeholder="Enter mask">
</div> </div>
<div class="opcua-actions"> <div class="opcua-actions">
@ -686,9 +613,11 @@
const ssidList = document.getElementById('ssid-list'); const ssidList = document.getElementById('ssid-list');
const ssidTmpl = document.getElementById('ssid-template'); const ssidTmpl = document.getElementById('ssid-template');
const countryCodeInput = document.getElementById('wifi_country_code');
const data = { const data = {
/* Wi-Fi */ /* Wi-Fi */
wifi_static: '', wifi_ip: '', wifi_netmask: '', wifi_gateway: '', wifi_dns1: '', wifi_dns2: '', wifi_static: '', wifi_ip: '', wifi_netmask: '', wifi_gateway: '', wifi_dns1: '', wifi_dns2: '',
wifi_country_code: '',
/* Ethernet */ /* Ethernet */
eth_ip: '', eth_netmask: '', eth_gateway: '', eth_ip: '', eth_netmask: '', eth_gateway: '',
@ -711,10 +640,6 @@
rs485_mode: '', rs485_baudrate: null, rs485_databits: null, rs485_mode: '', rs485_baudrate: null, rs485_databits: null,
rs485_parity: '', rs485_stopbits: 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 설정 */
lte_ip: '', lte_netmask: '', lte_gateway: '', lte_port: null, lte_ip: '', lte_netmask: '', lte_gateway: '', lte_port: null,
@ -729,12 +654,8 @@
'reg_analog_input_level': 'analog_input_level', 'reg_analog_input_level': 'analog_input_level',
'ai0': 'ai0', 'ai0': 'ai0',
'ai1': 'ai1', 'ai1': 'ai1',
'ai2': 'ai2',
'ai3': 'ai3',
'di0': 'di0', 'di0': 'di0',
'di1': 'di1', 'di1': 'di1',
'di2': 'di2',
'di3': 'di3',
'reg_can_input': 'can_input', 'reg_can_input': 'can_input',
'reg_device_type': 'dev_type', 'reg_device_type': 'dev_type',
'reg_dr_on_off': 'dr_on', 'reg_dr_on_off': 'dr_on',
@ -746,9 +667,6 @@
'reg_version': 'version', 'reg_version': 'version',
'reg_equipment_id': 'equipment_id', 'reg_equipment_id': 'equipment_id',
'reg_meid': 'MEID', 'reg_meid': 'MEID',
'reg_heading_on': 'heading_on',
'reg_heading_imu_on': 'heading_imu_on',
'reg_fixmode_on': 'fix_mode_on'
}; };
let lastLoadedRegisterData = {}; let lastLoadedRegisterData = {};
@ -963,9 +881,7 @@
document.getElementById('modbus_idt_input').value = tr.querySelector('.idt-display').textContent; 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_odt_input').value = tr.querySelector('.odt-display').textContent;
document.getElementById('modbus_dv_input').value = tr.querySelector('.dv-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_expr_input').value = tr.querySelector('.expr-display').textContent;
document.getElementById('modbus_mask_input').value = tr.querySelector('.mask-display').textContent;
}); });
// 처음에 행이 없으면 빈 행을 하나 추가 // 처음에 행이 없으면 빈 행을 하나 추가
if (modbusList.children.length === 0) { if (modbusList.children.length === 0) {
@ -992,9 +908,7 @@
document.getElementById('opcua_ns_input').value = tr.querySelector('.opcua-ns-display').textContent; 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_odt_input').value = tr.querySelector('.opcua-odt-display').textContent;
document.getElementById('opcua_dv_input').value = tr.querySelector('.opcua-dv-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_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) { if (opcUaList.children.length === 0) {
@ -1037,9 +951,7 @@
const idt = document.getElementById('modbus_idt_input').value; const idt = document.getElementById('modbus_idt_input').value;
const odt = document.getElementById('modbus_odt_input').value; const odt = document.getElementById('modbus_odt_input').value;
const defaultValue = document.getElementById('modbus_dv_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 expr = document.getElementById('modbus_expr_input').value;
const mask = document.getElementById('modbus_mask_input').value;
const firstRow = modbusFieldList.querySelector('tr'); const firstRow = modbusFieldList.querySelector('tr');
@ -1050,9 +962,7 @@
firstRow.querySelector('.idt-display').textContent = idt; firstRow.querySelector('.idt-display').textContent = idt;
firstRow.querySelector('.odt-display').textContent = odt; firstRow.querySelector('.odt-display').textContent = odt;
firstRow.querySelector('.dv-display').textContent = defaultValue; firstRow.querySelector('.dv-display').textContent = defaultValue;
firstRow.querySelector('.shift-display').textContent = shift;
firstRow.querySelector('.expr-display').textContent = expr; firstRow.querySelector('.expr-display').textContent = expr;
firstRow.querySelector('.mask-display').textContent = mask;
} else { } else {
// 새로운 행을 추가 // 새로운 행을 추가
const newRow = modbusRowTemplate.content.cloneNode(true); const newRow = modbusRowTemplate.content.cloneNode(true);
@ -1061,9 +971,7 @@
newRow.querySelector('.idt-display').textContent = idt; newRow.querySelector('.idt-display').textContent = idt;
newRow.querySelector('.odt-display').textContent = odt; newRow.querySelector('.odt-display').textContent = odt;
newRow.querySelector('.dv-display').textContent = defaultValue; newRow.querySelector('.dv-display').textContent = defaultValue;
newRow.querySelector('.shift-display').textContent = shift;
newRow.querySelector('.expr-display').textContent = expr; newRow.querySelector('.expr-display').textContent = expr;
newRow.querySelector('.mask-display').textContent = mask;
modbusFieldList.appendChild(newRow); modbusFieldList.appendChild(newRow);
} }
@ -1074,9 +982,7 @@
document.getElementById('modbus_idt_input').value = ''; document.getElementById('modbus_idt_input').value = '';
document.getElementById('modbus_odt_input').value = ''; document.getElementById('modbus_odt_input').value = '';
document.getElementById('modbus_dv_input').value = ''; document.getElementById('modbus_dv_input').value = '';
document.getElementById('modbus_shift_input').value = '';
document.getElementById('modbus_expr_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('.idt-display').textContent = document.getElementById('modbus_idt_input').value;
selectedRow.querySelector('.odt-display').textContent = document.getElementById('modbus_odt_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('.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('.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 ns = document.getElementById('opcua_ns_input').value;
const odt = document.getElementById('opcua_odt_input').value; const odt = document.getElementById('opcua_odt_input').value;
const defaultValue = document.getElementById('opcua_dv_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 expr = document.getElementById('opcua_expr_input').value;
const mask = document.getElementById('opcua_mask_input').value;
const firstRow = opcUaFieldList.querySelector('tr'); const firstRow = opcUaFieldList.querySelector('tr');
@ -1120,9 +1022,7 @@
firstRow.querySelector('.opcua-ns-display').textContent = ns; firstRow.querySelector('.opcua-ns-display').textContent = ns;
firstRow.querySelector('.opcua-odt-display').textContent = odt; firstRow.querySelector('.opcua-odt-display').textContent = odt;
firstRow.querySelector('.opcua-dv-display').textContent = defaultValue; firstRow.querySelector('.opcua-dv-display').textContent = defaultValue;
firstRow.querySelector('.opcua-shift-display').textContent = shift;
firstRow.querySelector('.opcua-expr-display').textContent = expr; firstRow.querySelector('.opcua-expr-display').textContent = expr;
firstRow.querySelector('.opcua-mask-display').textContent = mask;
} else { } else {
// 새로운 행을 추가 // 새로운 행을 추가
const newRow = opcUaRowTemplate.content.cloneNode(true); const newRow = opcUaRowTemplate.content.cloneNode(true);
@ -1131,9 +1031,7 @@
newRow.querySelector('.opcua-ns-display').textContent = ns; newRow.querySelector('.opcua-ns-display').textContent = ns;
newRow.querySelector('.opcua-odt-display').textContent = odt; newRow.querySelector('.opcua-odt-display').textContent = odt;
newRow.querySelector('.opcua-dv-display').textContent = defaultValue; newRow.querySelector('.opcua-dv-display').textContent = defaultValue;
newRow.querySelector('.opcua-shift-display').textContent = shift;
newRow.querySelector('.opcua-expr-display').textContent = expr; newRow.querySelector('.opcua-expr-display').textContent = expr;
newRow.querySelector('.opcua-mask-display').textContent = mask;
opcUaFieldList.appendChild(newRow); opcUaFieldList.appendChild(newRow);
} }
@ -1144,9 +1042,7 @@
document.getElementById('opcua_ns_input').value = ''; document.getElementById('opcua_ns_input').value = '';
document.getElementById('opcua_odt_input').value = ''; document.getElementById('opcua_odt_input').value = '';
document.getElementById('opcua_dv_input').value = ''; document.getElementById('opcua_dv_input').value = '';
document.getElementById('opcua_shift_input').value = '';
document.getElementById('opcua_expr_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-ns-display').textContent = document.getElementById('opcua_ns_input').value;
selectedRow.querySelector('.opcua-odt-display').textContent = document.getElementById('opcua_odt_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-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-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 deviceData = collectDeviceData();
const protocolData = collectProtocolData(); const protocolData = collectProtocolData();
const normalizedProtocol = normalizeRegisterForPost(protocolData); const normalizedProtocol = normalizeRegisterForPost(protocolData);
@ -1265,34 +1159,34 @@
alert("Register settings are currently invalid. Cannot be saved."); alert("Register settings are currently invalid. Cannot be saved.");
return; return;
} }
//device try {
const deviceReq = fetch('/setting/device', { const deviceRes = await fetch('/setting/device', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(deviceData) body: JSON.stringify(deviceData)
}); });
//protocol
const protocolReq = fetch('/setting/protocol', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(normalizedProtocol)
});
// 모든 요청이 성공하면 성공 알림 const protocolRes = await fetch('/setting/protocol', {
Promise.all([deviceReq, protocolReq]) method: 'POST',
.then(([res1, res2]) => { headers: { 'Content-Type': 'application/json' },
if (res1.ok && res2.ok) { body: JSON.stringify(normalizedProtocol)
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');
}); });
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 행 추가 버튼 //ssid 행 추가 버튼
document.getElementById('add-ssid').addEventListener('click', addSsidRow); 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() { // function clearAllInputs() {
// // 모든 input[type="text"], [type="number"], [type="password"] 등 초기화 // // 모든 input[type="text"], [type="number"], [type="password"] 등 초기화
@ -1343,8 +1240,6 @@
// can_bus_type: '', can_baudrate: null, // can_bus_type: '', can_baudrate: null,
// rs485_mode: '', rs485_baudrate: null, rs485_data_bits: null, // rs485_mode: '', rs485_baudrate: null, rs485_data_bits: null,
// rs485_parity: '', rs485_stop_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, // lte_ip: '', lte_netmask: '', lte_gateway: '', lte_port: null,
// WIFI_SSID: [{wifi_ssid: '', wifi_password: '', wifi_security: 'none'}], // WIFI_SSID: [{wifi_ssid: '', wifi_password: '', wifi_security: 'none'}],
// }; // };
@ -1368,13 +1263,10 @@
} }
} }
//x,y,z,부호 처리 //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(); res.WIFI_SSID = gatherSsidRows();
if (typeof res.wifi_country_code === 'string') {
res.wifi_country_code = res.wifi_country_code.trim().toUpperCase();
}
//null, 공백 없이 데이터 전처리 //null, 공백 없이 데이터 전처리
const filtered = {}; const filtered = {};
@ -1427,16 +1319,12 @@
const idt = row.querySelector('.idt-display')?.textContent.trim(); const idt = row.querySelector('.idt-display')?.textContent.trim();
const odt = row.querySelector('.odt-display')?.textContent.trim(); const odt = row.querySelector('.odt-display')?.textContent.trim();
const dv = row.querySelector('.dv-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 expr = row.querySelector('.expr-display')?.textContent.trim();
const mask = row.querySelector('.mask-display')?.textContent.trim();
if (addr) obj.addr = addr; if (addr) obj.addr = addr;
if (idt) obj.idt = idt; if (idt) obj.idt = idt;
if (odt) obj.odt = odt; if (odt) obj.odt = odt;
if (dv) obj.dv = dv; if (dv) obj.dv = dv;
if (shift) obj.shift = shift;
if (expr) obj.expr = expr; if (expr) obj.expr = expr;
if (mask) obj.mask = mask;
collectedRegister.MODBUS.push(obj); collectedRegister.MODBUS.push(obj);
} }
}); });
@ -1453,16 +1341,12 @@
const ns = row.querySelector('.opcua-ns-display')?.textContent.trim(); const ns = row.querySelector('.opcua-ns-display')?.textContent.trim();
const odt = row.querySelector('.opcua-odt-display')?.textContent.trim(); const odt = row.querySelector('.opcua-odt-display')?.textContent.trim();
const dv = row.querySelector('.opcua-dv-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 expr = row.querySelector('.opcua-expr-display')?.textContent.trim();
const mask = row.querySelector('.opcua-mask-display')?.textContent.trim();
if (addr) obj.addr = addr; if (addr) obj.addr = addr;
if (ns) obj.ns = ns; if (ns) obj.ns = ns;
if (odt) obj.odt = odt; if (odt) obj.odt = odt;
if (dv) obj.dv = dv; if (dv) obj.dv = dv;
if (shift) obj.shift = shift;
if (expr) obj.expr = expr; if (expr) obj.expr = expr;
if (mask) obj.mask = mask;
collectedRegister.OPC_UA.push(obj); collectedRegister.OPC_UA.push(obj);
} }
}); });
@ -1673,9 +1557,6 @@
'version', 'version',
'equipment_id', 'equipment_id',
'MEID', 'MEID',
'heading_on',
'heading_imu_on',
'fix_mode_on'
]; ];
@ -1818,16 +1699,6 @@
/*-----------------------------------------------------*/ /*-----------------------------------------------------*/
/*-------imu-remap 정수와 부호 분리 함수-------------*/ /*-------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 값 재구성 */ /* 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 */ /* SSID */
ssidList.innerHTML = ''; ssidList.innerHTML = '';
(obj.WIFI_SSID || []).forEach(o => ssidList.appendChild(createSsidRow(o))); (obj.WIFI_SSID || []).forEach(o => ssidList.appendChild(createSsidRow(o)));
@ -1957,9 +1822,7 @@
newRow.querySelector('.idt-display').textContent = field.idt ?? ''; newRow.querySelector('.idt-display').textContent = field.idt ?? '';
newRow.querySelector('.odt-display').textContent = field.odt ?? ''; newRow.querySelector('.odt-display').textContent = field.odt ?? '';
newRow.querySelector('.dv-display').textContent = field.dv ?? ''; newRow.querySelector('.dv-display').textContent = field.dv ?? '';
newRow.querySelector('.shift-display').textContent = field.shift ?? '';
newRow.querySelector('.expr-display').textContent = field.expr ?? ''; newRow.querySelector('.expr-display').textContent = field.expr ?? '';
newRow.querySelector('.mask-display').textContent = field.mask ?? '';
modbusFieldList.appendChild(newRow); modbusFieldList.appendChild(newRow);
}); });
} else { } else {
@ -1984,9 +1847,7 @@
newRow.querySelector('.opcua-ns-display').textContent = field.ns ?? ''; newRow.querySelector('.opcua-ns-display').textContent = field.ns ?? '';
newRow.querySelector('.opcua-odt-display').textContent = field.odt ?? ''; newRow.querySelector('.opcua-odt-display').textContent = field.odt ?? '';
newRow.querySelector('.opcua-dv-display').textContent = field.dv ?? ''; 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-expr-display').textContent = field.expr ?? '';
newRow.querySelector('.opcua-mask-display').textContent = field.mask ?? '';
opcUaFieldList.appendChild(newRow); opcUaFieldList.appendChild(newRow);
}); });
} else { } else {

32
src/main/resources/static/style.css

@ -166,6 +166,36 @@ details.nav {
.icon-button:active { .icon-button:active {
background-color: #c0c0c0; 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) */ /* 3-column grids (Network / Server) */
.grid-3-col { .grid-3-col {
display: grid; display: grid;
@ -256,6 +286,7 @@ details.nav {
#page-modbus table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} #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, #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 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 .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 .input-row {display: contents;}
#page-modbus .modbus-input-area label.nowrap {white-space: nowrap;} #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 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, #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 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 .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 .input-row {display: contents;}
#page-opcua .opcua-input-area label.nowrap {white-space: nowrap;} #page-opcua .opcua-input-area label.nowrap {white-space: nowrap;}

Loading…
Cancel
Save