- **프로토콜 레지스터 필드를 디바이스 config-reader 계약에 정렬 (Modbus/OPC-UA)**:
- Modbus 레지스터 `idt` 를 디바이스가 기대하는 **공백형**으로 저장 (`unsignedInteger`→`unsigned integer`, `unsignedShort`→`unsigned short`). UI 드롭다운 라벨은 그대로 유지(저장 시에만 변환, 로드 시 역변환). 이전에는 camelCase 로 저장돼 **Modbus 설정 전체가 로드 실패**할 수 있었습니다.
- **Modbus·OPC-UA 레지스터 폼에서 `Shift`/`Expr`/`Mask` 제거** — 해당 프로토콜에서는 디바이스가 사용하지 않는 필드입니다(`Expr` 은 저장되나 값에 미적용, `Shift`/`Mask` 는 Modbus/OPC-UA 레지스터 필드가 아님). **CAN 은 유지**(실제 적용됨).
- **ODT `string` 옵션**: Modbus·CAN 에서 제거(디바이스가 Modbus 는 거부, CAN 은 출력 없음), **OPC-UA 는 유지**. 백엔드도 Modbus/CAN 의 `string` 저장을 400 으로 거부.
- **레지스터 매핑 테이블 UI 정돈**: 컬럼 헤더를 축약어 없이 풀네임으로 통일 — Modbus `Field / Address / Input Type / Output Type / Default Value`, OPC-UA `Field / Namespace / Node ID / Output Type / Default Value`, CAN `Field / CAN ID / Output Type / Default Value / Shift / Expr / Mask`. CAN Baud Rate 드롭다운에서 미사용 `NONE` 항목을 표시에서 숨김(내부 데이터 계약·firmware 값 검증은 유지).
### Added
- 기존 디바이스 DB 의 위 표기를 **부팅 시 1회 자동 정합**(멱등 마이그레이션, 이전 계약-정합 마이그레이션을 거친 디바이스에서도 실행되도록 별도 플래그).
### Note
- 설치 경로(`/usr/lib/web-configurator`)·기본 포트(`:9090`) 유지. dpworldapp 공유 DB·계약·타입 무변경(레지스터 표기 정합만).
## [v1.12.1] — 2026-06-29
### Added
- **텔레메트리 Uplink (Ethernet 전환)**: dpworldapp 클라우드 텔레메트리(프로토콜·업데이트·RTCM) 송신을 웹 UI 에서 Wi-Fi↔Ethernet 전환. 호스트 라우트(/32)만 사용 — dpworldapp·OS 설정 무접촉. 워치독 자가복원 + 관리 인터페이스 보호.
- **대상**: 디바이스 BSP 이미지 포함용 (DP World Smart Solutions · IoT 디바이스)
- **패키지**: 내부 git 태그 `v1.12.3` (커밋 히스토리가 없는 **클린 스냅샷**)
- **이전 전달**: v1.12.1 — 본 전달은 v1.12.2·v1.12.3 변경을 함께 포함합니다.
- **패키지**: 내부 git 태그 `v1.12.4` (커밋 히스토리가 없는 **클린 스냅샷**)
- **이전 전달**: v1.12.1 — 본 전달은 v1.12.2·v1.12.3·v1.12.4 변경을 함께 포함합니다.
---
## 0. v1.12.1 → v1.12.3 신규/변경 (이번 전달의 핵심)
## 0. v1.12.1 → v1.12.4 신규/변경 (이번 전달의 핵심)
이번 전달은 v1.12.1 위에 **v1.12.2(신규/빈 디바이스 DB-init 안정화)** 와 **v1.12.3(Wi-Fi AP 채널 선택 + 네트워크 즉시적용 실측 검증)** 을 함께 반영한 것입니다.
이번 전달은 v1.12.1 위에 **v1.12.2·v1.12.3·v1.12.4** 를 함께 반영한 것입니다.
### v1.12.4 — 프로토콜 레지스터 필드를 디바이스 계약에 정합 (Modbus/OPC-UA)
- **Modbus `idt` 공백형 저장**: 레지스터 입력 데이터타입을 디바이스 config-reader 가 기대하는 공백형으로 저장합니다(`unsignedInteger`→`unsigned integer`, `unsignedShort`→`unsigned short`). UI 라벨은 그대로 두고 저장 시에만 변환하며, 로드 시 역변환합니다. 이전에는 camelCase 로 저장돼 **Modbus 설정 전체가 로드 실패**할 수 있었습니다.
- **Modbus·OPC-UA 폼에서 `Shift`/`Expr`/`Mask` 제거**: 해당 프로토콜에서 디바이스가 사용하지 않는 필드입니다(`Expr` 은 저장되나 값에 미적용, `Shift`/`Mask` 는 레지스터 필드가 아님). **CAN 은 유지**(CAN 에서는 실제 적용됨).
- **ODT `string`**: Modbus·CAN 에서 제거(디바이스가 Modbus 는 거부, CAN 은 출력 없음), OPC-UA 는 유지(완전 지원). 잘못된 저장은 400 으로 거부.
- 기존 디바이스 DB 의 위 표기는 **부팅 시 1회 자동 정합**(멱등 마이그레이션, 이전 계약-정합 마이그레이션을 거친 디바이스에서도 실행되도록 별도 플래그).
- dpworldapp 공유 DB·계약·타입 무변경(레지스터 표기 정합만). 설치 경로(`/usr/lib/web-configurator`)·기본 포트(`:9090`) 유지.
- **레지스터 테이블 UI 정돈**: 3개 매핑 표(Modbus/OPC-UA/CAN)의 컬럼 헤더를 축약어 없이 풀네임으로 통일(`Output Type`·`Default Value`·`Input Type`·`Namespace`·`Node ID`·`Address`). CAN Baud Rate 드롭다운에서 미사용 `NONE` 항목을 표시에서 숨김(데이터 계약·firmware 값 검증은 유지).
### v1.12.2 — 신규/빈 디바이스 DB-init 안정화 (fail-soft)
펌웨어 업데이트 직후 동기화 문제로 `device_config`/`protocol_config` 가 비어 있을 때, **웹이 그 값을 생성·덮어쓰지 않도록** 하여 dpworldapp 의 시딩을 선점하지 않습니다. 단일 판정(`config_initialized`)을 아래에 일관 적용합니다.