PLCController.DoActivate() 가 PLC 연결을 열기 전에 _monitorPlcInterfaceMap 을 기동해, 연결 확립 전 LiveStatusUpdate() 가 돌면서 ALARM_DEVICE_PLC_DISCONNECT(210002) 오알람이 매 기동마다 발생했다. 원인 - Livetimer 가 초기화되지 않아 DateTime.MinValue 상태 → (Now - MinValue) 가 항상 10000ms 를 초과해 워치독이 오판. 임계값 조정으로는 해결 불가. - MicroTimer 첫 콜백이 주기(100ms) 뒤가 아니라 Start() 직후(약 1ms)라 경합이 아니라 100% 재현되는 결정적 버그. 실측 (2026-08-10 16:12:25.904) Livetimer=0001-01-01, elapsed=63921975145904ms, isLive=False, IsActivated=False, IsConnected=False 조치 - _monitorPlcInterfaceMap.Start() 를 base.DoActivate() 성공 이후로 이동 - Livetimer = DateTime.Now 로 기준시각 확보 후 타이머 기동 - 두 조치는 각각 단독으로는 무효. 반드시 함께 적용해야 한다. - 수정 전/후를 #region 2개(검색: 260810 기동 오알람)로 기록해 원복 가능 검증: 2026-08-10 현장 재기동 확인 — 기동 시 210002 미발생 미해결(별건): Livetimer 이중 용도, ReadBit .err 무시, ClearAlarm 부재, SeqAlarmMonitor 의 무지연 루프 및 Laser/Chiller 즉시 알람 상세: docs/분석_PLC210002_기동오알람_260810.md 작업일지: docs/작업일지/2026_08_10.md
91 lines
4.7 KiB
Markdown
91 lines
4.7 KiB
Markdown
# 작업일지 — 2026-08-10
|
|
|
|
## 1. PLC 기동 오알람 210002 — 원인 확정 및 해결
|
|
|
|
### 증상
|
|
|
|
프로그램 첫 기동 시 PLC 연결이 열리기도 전에 `ALARM_DEVICE_PLC_DISCONNECT`(210002) 발생.
|
|
연결은 곧 붙지만 알람은 남는다(자동 해제 없음). 시뮬 모드에서는 무발생.
|
|
|
|
### 210002를 올리는 경로가 2개였음
|
|
|
|
| | 위치 | 판정 | 임계 | 상태 |
|
|
|---|---|---|---|---|
|
|
| A | `PLCController.Config.cs:146` (디바이스, 100ms 타이머) | **엣지** — 비트가 바뀌어야 정상 | 10000ms | 활성 |
|
|
| B | `SeqAlarmMonitor.cs:182` (시퀀스) | **레벨** — 2초 안에 true면 정상 | 2000ms | 활성 |
|
|
| — | `AlarmMonitoring.cs:169` (공통 시퀀스) | — | — | **죽은 코드** |
|
|
|
|
- `AlarmCode_PTOP : AlarmCode`(`AlarmCode_PTOP.cs:10`) 상속이고 210002는 재정의 없음 →
|
|
**A와 B가 같은 코드**를 써서 화면만 봐서는 구분 불가.
|
|
- `AlarmMonitoring.Builder()` 호출처는 `SequenceManager.cs:83` 주석 한 줄뿐(등록 0건).
|
|
주석을 풀어도 동작하지 않는다.
|
|
|
|
### 근본 원인
|
|
|
|
`PLCController.Config.cs`
|
|
|
|
- `DateTime Livetimer`(`:33`)가 초기화되지 않아 `DateTime.MinValue`.
|
|
대입 지점은 토글 감지 시(`:138`) 한 곳뿐이라, 기동 직후에는 값이 들어가지 않는다.
|
|
→ `(Now - MinValue)`가 항상 10000ms를 초과 → 워치독 오판.
|
|
**임계값 10000을 20000으로 키우는 방식은 원리적으로 무효**(MinValue 앞에서는 어떤 값이든 초과).
|
|
- `_monitorPlcInterfaceMap.Start()`(`:185`)가 `base.DoActivate()`(`:187`)보다 **앞**에 있어
|
|
연결 확립 전에 타이머가 돌았다. `beforeLiveStatus` 리셋(`:195`)도 그보다 뒤.
|
|
|
|
### 진단 계측 (적용 → 결과 확보 → 원복 완료)
|
|
|
|
A/B 중 어느 쪽인지 확정하기 위해 두 곳에 임시 로그를 넣고 재기동. 현장 로그:
|
|
|
|
```
|
|
16:12:25.903 MicroTimer: timer interval: 100 [ms]
|
|
16:12:25.904 E PLCController: [210002][A:PLCController.LiveStatusUpdate]
|
|
Livetimer=0001-01-01 00:00:00.000, elapsed=63921975145904ms,
|
|
isLive=False, beforeLiveStatus=False, IsActivated=False, IsConnected=False
|
|
```
|
|
|
|
- `Livetimer=0001-01-01` → 미초기화 확정.
|
|
- `IsActivated=False, IsConnected=False` → **연결 확립 전 발생 확정.**
|
|
사전에 `[추론]`으로 달아 뒀던 "Aurora가 `IsActivated`를 `DoActivate` 반환 뒤에 세팅한다"도 함께 검증됨.
|
|
- `[B:...]` 로그 미출현 → **A 단독**. 시퀀스 계층은 이번 건과 무관.
|
|
- 타이머 기동(`.903`)과 알람(`.904`) 간격이 1ms → `MicroTimer` 첫 콜백이 주기(100ms) 뒤가 아니라
|
|
`Start()` 직후에 발생. 경합이 아니라 **100% 재현되는 결정적 버그**였다.
|
|
|
|
계측 코드는 결과 확보 후 전량 원복(`.cs` 잔존 0건 확인).
|
|
|
|
> 로그 파일에서 한글이 깨진다(`[진단210002]` → `[ 210002]`, `위치:` → `ġ:`).
|
|
> 검색어는 `210002][` 를 쓸 것.
|
|
|
|
### 수정 (최소 수정)
|
|
|
|
`WeldingComponents/WeldingCommon/Devices/PLC/PLCController.Config.cs` 의
|
|
`DoActivate()` **1개 메서드만** 변경. `SeqAlarmMonitor.cs` 등 다른 파일 미변경.
|
|
|
|
- `_monitorPlcInterfaceMap.Start()` 를 `base.DoActivate()` 성공 이후로 이동
|
|
- `Livetimer = DateTime.Now` 로 기준시각 확보 후 타이머 기동
|
|
- **두 조치는 각각 단독으로는 무효** — 타이머만 옮기면 `Livetimer`가 여전히 `MinValue`,
|
|
초기화만 하면 타이머가 그 앞에서 이미 발화. 반드시 함께 적용해야 한다.
|
|
- 수정 전/후를 `#region` 2개로 기록해 원복 가능하게 함 (검색어: `260810 기동 오알람`)
|
|
|
|
부수 효과: `Activate` 실패 시 타이머가 계속 돌던 문제 해소.
|
|
[추론] `LoadMemoryMapFromFiles()` 중 타이머가 같은 맵을 읽던 겹침도 함께 사라진다.
|
|
|
|
### 검증
|
|
|
|
**현장 재기동 확인 — 기동 시 210002 미발생. 해결 완료.**
|
|
|
|
### 잔여 과제 (별건)
|
|
|
|
- `Livetimer` 가 에코 1초 타이머(`:130`)와 워치독 10초 기준시각(`:144`)을 겸용하는 구조
|
|
- `LiveStatusUpdate` 가 `ReadBit` 의 `.err` 를 버려 "PLC 미송신"과 "PC 미수신"이 구분 안 됨
|
|
- `AlarmManager.Alarm`(`AlarmManager.cs:79-104`)에 짝이 되는 `ClearAlarm` 이 없어
|
|
통신 복구 후에도 알람 잔존
|
|
- `SeqAlarmMonitor` — `WaitTime` 무지연 루프(`:145-148`), Laser/Chiller 즉시 알람(grace 없음),
|
|
`:190-193` `_Laser` null 시 NRE 위험, `InitDev` 진입 1회만 실행
|
|
- `AlarmMonitoring.cs` 죽은 코드 정리
|
|
- `Light` 디바이스 `SerialPort.Open()` 실패 (`16:12:25.875 E EquipmentSetup: Light connect fail.`)
|
|
— 본 건과 무관, 미확인
|
|
|
|
### 산출
|
|
|
|
- `docs/분석_PLC210002_기동오알람_260810.md` (분석 상세)
|
|
- 커밋 대상: 위 분석 문서 + `PLCController.Config.cs`
|