# 작업일지 — 2026-06-18 ## 09:22 ### 조명 컨트롤러 연결 완료 (아침) - 조명 컨트롤러 연결을 완료했다. **중요 사항 정리:** - 조명 컨트롤러는 모델의 사양(스펙) 파라미터를 알고 있어야 한다. - 사용 중인 모델은 EROOM E-MINI CONTROLLER 인데, AURORA에서 해당 모델 타입을 제공 중이라 그대로 활용했다. - DEVICE에서 LIGHT1 과 Light 에 대한 파라미터 세팅을 동일하게 맞춰주고, 채널도 맞춰줘야 한다. - 통신 파라미터: 정지 비트(stop bit), 패리티 비트(parity bit), 시작 비트(start bit), Baud 값, 그리고 어떤 COM 포트에 꽂혔는지만 정확히 알면 된다. - **막혔던 부분 (해결):** 장치 관리자에서 COM1 포트 설정은 맞췄지만, 고급 설정에 들어가면 버퍼(buffer) 체크가 되어 있는 항목이 있다. 이걸 꼭 **해제**해줘야 리모트 모드로 조명 컨트롤러에 커맨드를 날릴 수 있다. ## 09:32 ### 현장 update 파일 정리 - 어제(2026-06-17) 수정한 소스 파일들을 현장 소스에 옮기기 위해 `docs/현장update파일/` 폴더를 만들어 복사해두었다. - 포함 파일: - `SequenceSetting.cs` — Axis Position Interlock 파라미터 4개 추가 (수직/수평 기준값·허용오차, 커밋 `9543238`) - `UCScannerObjectTeachingControlBoxViewModel.cs` — Laser Ready 판정을 `DI(9)` → `DI(12) && DI(24)` 동시 조건으로 변경 (커밋 `9aa1b2a`) - `README.md` — 각 파일의 원본 위치 / 변경 부분(diff) / 적용 체크리스트 정리 ### 현장 PC 원격 데스크톱 접속 가능하게 변경 - 금일 현장 PC가 방화벽 때문에 원격 데스크톱이 안 됐는데, **김남오 대리님**께서 세팅하신 뒤 PC를 재부팅해서 원격 접속이 가능하도록 변경해주셨다. ## 09:36 ### 현장 소스 반영(옮기기) 완료 - `docs/현장update파일/`에 정리한 변경 내용을 현장 소스에 옮기기 완료했다. - `SequenceSetting.cs` — Axis Position Interlock 파라미터 4개 추가 반영 - `UCScannerObjectTeachingControlBoxViewModel.cs` — Laser Ready 판정 `DI(12) && DI(24)` 변경 반영 ## 10:02 ### SeqScoutNormal moveSleepTime 50→100ms 변경 - `SeqScoutNormal.cs`의 Scanner Jump 후 `moveSleepTime`을 50 → 100ms로 변경했다. - **이유:** 현장 PTOP의 경우 어제 Scout 이미지가 속도 때문에 제대로 안 됐는데, 현장 PTOP 상황에서 ScoutNormal의 FOV 거리가 멀어서 캡처가 흔들리는 부분 때문에 50에서 100으로 상향함. - 커밋 `81fdf01`로 커밋·푸시 완료. ## 10:18 ### [요청] 레이저 미발진 상태로 Analog만 살려 Power Cal 파일 생성 가능 여부 - **목적:** Laser Voltage를 1V 줬을 때 실제 몇 W가 나오는지 측정하는 **캘리브레이션(Cal) 파일**을 만들고 싶다. - **핵심 요청:** 캘 파일을 만드는 동안 **레이저는 실제로 발진(발사)시키지 않고**, **아날로그 신호만 살려서** RTC5의 기록(로그/데이터)은 그대로 저장되도록 할 수 있는가? - **상세:** - 레시피(또는 메뉴얼) 화면 → **Manual Laser Power Control** 영역에서 레이저를 쏠지 안 쏠지 제어함. - 보통은 **레이저 컨트롤러 IO를 살리지 않으면** 레이저가 실제로 나가지 않는다. - 이때 **아날로그 신호만 활성화**해서, 레이저는 안 나가되 RTC5가 출력 기록은 정상적으로 남기도록(저장되도록) 만들 수 있는지 확인 필요. - **정리:** Laser 발진 IO는 비활성(레이저 OFF) + Analog 출력은 활성 → RTC5 기록은 정상 저장. 이 구성이 가능한지 검토 요청. ## 11:27 ### PTOP 네임스페이스/클래스 마이그레이션 적용 (Scanner → PTOP) + 머신 PTOP 단독화 - 프로젝트명만 PTOP로 바꾸고 Sequence만 손봤던 상태에서, `ILSOS_PrismaticScanner` 네임스페이스/using/클래스명/파일명이 남아있던 것을 참고본(`D:\Git\LGES-OC5-PtoP-Welder_정리후(빌드완)`)과 동일하게 정리. - 분석 문서 기준으로 진행: `docs/분석/2026/06/18/111604_ptop_namespace_migration_guide.md` - **적용 내역:** - 파일 7개 git mv 리네임 (AlarmCode/AlarmManager/PAIX/EquipmentSpecificModel → _PTOP, RMSHandlerForScanner→ForPTOP, SettingUploadDataListForScanner→ForPTOP, SeqAutoRunPrismaticScanner→SeqAutoRunPrismatic) - namespace `ILSOS_PrismaticScanner` → `ILSOS_PrismaticRD_PTOP` (전 .cs/.xaml) - using 동일 변경, 클래스명 참조 전파 (PLCControllerPrismaticScanner→PLCControllerPTOP 등) - ⚠ **PAIX_PrismaticScanner는 머신 참조만 PAIX_PTOP로 변경, WeldingCommon 공유 참조(SeqTestRun.cs)는 보존** — 빌드 깨짐 1순위 함정 회피 - XAML 3종(x:Class/clr-namespace/code-behind) 일치, csproj Compile Include 7줄 갱신 - csproj 빌드 경로 TDC→PTOP (`_out_prismatic_rd_ptop`) - sln에서 Scanner/Gun/CleanLaser 제거, 해당 머신 소스 폴더 삭제, 비-PTOP `_out` 아티팩트 정리 → **Machines에 PTOP만 남김** (참고본과 동일 구조) - **주의:** 이 환경에선 실제 MSBuild 검증 불가 → VS에서 Clean→Rebuild 권장(obj 비워둠). ## 11:34 ### Manual Laser Power Control — Watt 입력 GroupBox 숨김(Collapsed) - 마이그레이션 후 빌드 정상 확인 완료. - `UCScannerLaserControl.xaml`(WeldingCommon)의 Manual Laser Power Control 2영역(%, W) 중 **W 입력 영역은 주로 안 쓰므로** Grid.Row="1"(Watt 기준) GroupBox에 `Visibility="Collapsed"` 추가로 숨김 처리. - Percent(%) 영역만 노출, 공간도 미차지. ViewModel/바인딩(`CMD_LaserShotOnWatt` 등)은 변경 없음. - 관련 분석: `docs/분석/2026/06/18/102847_manual_laser_power_control_groupbox_analysis.md` - 커밋 `ad6cf68`로 커밋·푸시 완료. ## 12:12 ### NoLaser 체크 — 레이저 컨트롤러(IO BIT9/13) 안 켜고 Laser On 가능 - 발진(lasing)을 막는 실제 지점은 `LaserSignalOn`(RTC5 게이트)이 아니라 **IO Control DO9(`CoreLaser_Control`)/DO13(`RingLaser_Control`)** 를 true로 주는 부분이었음. - 위치: `UCScannerObjectTeachingControlBoxViewModel.PerformCmdLaserReadyCheck`(Laser Control GroupBox의 `Laser Ready` 버튼). - 처음엔 `UCScannerLaserControl`에 Analog Only(IsAnalogOnly)로 `LaserSignalOn` 가드를 넣었으나, 실제 IO는 다른 소스(ObjectTeachingControlBox)라 **그 변경은 원복**하고(Watt 숨김은 유지), 정확한 지점에 다시 구현. - 구현: ViewModel에 `IsNoLaser` 추가(기본 false). `Laser Ready` 버튼이 DO9/13을 켜는 분기에서 `ctrlOn = !IsNoLaser`로 적용 → **IsNoLaser=true면 DO9/13을 true로 안 켜고 false 유지** → 레이저 컨트롤러 OFF 상태로 Laser On 가능(Cal/전압 측정용). - XAML: Laser Control GroupBox에 `No Laser (전압만, 발진 안 함)` 체크박스 추가. - 디바이스 레이어(Scanner/RTC5) 무변경, IO 비트 9/13만 제어. - 커밋·푸시 진행. ## 12:20 ### Laser Ready 판정 DI 변경 — IO 결선 변경(12&24 → 11&15) - IO 결선을 바꿔서, 레시피의 Laser Ready 판정 입력을 `ReadDI(12) && ReadDI(24)` → **`ReadDI(11) && ReadDI(15)`** 로 수정. - 위치: `UCScannerObjectTeachingControlBoxViewModel`의 `OnMonitoring` Laser Ready 판정부. - 변경된 결선에 맞춘 단순 입력 번호 교체(로직 동일). ## 13:55 ### RTC5 AnalogOut 전압 Readback 표시 (Laser Shot Control) - `docs/RTC5_AnalogOut_Readback_수정가이드.md`(외부 작성 구현 명세)에 맞춰 RTC5 보드의 AnalogOut(파워 지령 전압) readback 기능 구현. 가이드 파일은 적용 후 삭제. - **Device 계층**: `ScannerObj`에 `abstract int GetAnalogOut(uint portNo)` 추가 → `ScannerRTC5`/`ScannerRTC6`(`n_get_value(signal=portNo+32)`, AnalogOut1=33/AnalogOut2=34)/`ScannerSimul`(더미 0) override + `Scanner` 파사드(미활성 시 -1). - **ViewModel**(`UCScannerLaserControlViewModel`): `AnalogOut1Voltage`/`AnalogOut2Voltage` 속성 + `ReadbackAnalogOut()`(raw/4095×10 [V]) 추가, Laser On 직접 분기(No Use Spot Time)의 WriteDA 직후·출사 전 호출. - **XAML**(`UCScannerLaserControl.xaml`): Control Setting(Percent 영역)에 `DA1 Voltage`/`DA2 Voltage` [V] 읽기전용 표시 추가. - 표시 대상은 Power Calibration(dbVoltage)이 아니라 **ScannerLaserControl 화면**으로 확정(요청). LaserSignalOn 발사 동작은 변경 없음(readback만 추가). - AuroraDevices 변경이라 VS Rebuild로 빌드 확인 예정(abstract 추가 → override 3개 모두 구현). - 관련 분석: `docs/분석/2026/06/18/122432_laser_on_no_emission_analysis.md` ## 14:14 ### NoLaser를 Manual(ScannerLaserControl)로 이동 + Recipe NoLaser 제거 - 어제/오늘 Recipe(UCScannerObjectTeachingControlBox)에 만들었던 NoLaser는 **원래 의도가 Manual 화면**이었음 → Recipe에서 **완전 제거**(속성/InitVariable/체크박스/RowDefinition/`PerformCmdLaserReadyCheck`의 `ctrlOn` 원복하여 `WriteDoBit(9/13,true)`로 환원). **DI 11&15 변경은 유지.** - **Manual**(`UCScannerLaserControlViewModel`): `IsNoLaser` 추가, Laser On 직접 분기(Percent/Watt 두 곳)의 `LaserSignalOn()`을 `if(!IsNoLaser)`로 가드 → 체크 시 발진 없이 전압만 인가. - **Manual XAML**(`UCScannerLaserControl.xaml`): Use Spot Time 토글과 **같은 ToggleSwitch 디자인**의 `No Laser (전압만)` 토글 추가. Timer Set 영역 배치 = Use Spot Time → Time(체크 시만) → No Laser → DA1/DA2 Voltage 순. - 이 NoLaser는 RTC5 발진 게이트(`LaserSignalOn`)를 막는 방식이라 **이 화면만으로 자기완결**(DO9/13 별도 화면 불필요). No Use Spot Time + No Laser + Laser On → 전압 readback 표시 + 발진 없음. ## 14:19 ### DA1/DA2 Voltage 표시를 No Laser 토글에 연동(조건부 표시) - DA1/DA2 Voltage UniformGrid에 `Visibility="{Binding IsNoLaser, Converter={StaticResource convTrueVisible}}"` 추가. - Time이 Use Spot Time 체크 시 표시되는 것과 동일하게, **No Laser 체크(전압만) 시에만 DA1/DA2 Voltage 표시**, Laser Fire(해제) 시 숨김. ## 14:33 ### IOInterfaceView DI 경로 PTOP 전환 분석 (소스 무수정) - Monitoring IOInterfaceView의 DI 표시가 Scanner DI를 보던 원인 분석. `IODevice.MappingDIO`가 `IO_Board.json`의 `IOInterfaceMapDI`(절대경로)를 그대로 읽음(path-agnostic) → 소스 수정 불필요. - PTOP 전환 = `D:\ILSOSConfig\ILSOS_PrismaticRD_PTOP\_config_device\IO_Board.json`의 DI/DO 경로를 PTOP로 + DI/DO.csv 존재 + DataPath 확인. (Device 설정에서 파일 위치만 지정하면 됨) - 분석일지: `docs/분석/2026/06/18/143345_io_interface_di_path_ptop_analysis.md` ## 15:30 ### PLC Recipe Change 인터페이스 구현 (SeqAutoRunPTOP) + 주소/디바이스맵 정합 - 근거: `docs/PLC_RecipeChange_구현_수정가이드.md` + Excel `유니셀 PtoP 단동기 Laser Interface_260618.xlsx`(빨간셀 M70509/M70009/D70502/D70002). 기존 Page Change 핸드셰이크를 미러링해 Recipe Change(상위 개념) 추가. - **STEP1 주소 enum** (`Device/PLC/PLCController.Address.cs`): - eBitInput `PLC_RMS_USED`→`PLC_RECIPE_CHANGE_REQ`(0x09), eBitOutput `PC_EMPTY01`→`PC_RECIPE_CHANGE_COMPLETE`(0x09) - eWordInput `PLC_STEP_NO`→`PLC_RECIPE_NO`(idx2), eWordOutput `EMPTY_02`→`PC_RECIPE_NO`(idx2) - 공용 `eCommonBitOutput`에 `PC_RECIPE_CHANGE_COMPLETE=0x09` 동기화(RestoreDeviceStatus가 common enum 사용) - 충돌: `SeqStatusMonitor`의 RMS_USED 읽기 주석(소비처 0), `SeqAutoRunPrismatic`의 PLC_STEP_NO 참조 이름만 교체(로직 불변) - **STEP2~4,6 시퀀스** (`Sequences/SeqAutoRunPTOP.cs`): - `CheckRecipeNo`(Decision, 논블로킹 peek: REQ OFF면 Page로, ON이면 Comp로) + `CheckRecipeNoComp`(3회 검증→`.Id` 1:1 조회→활성화+반영 폴링→에코/완료비트, Page 미러형) 추가 - Builder: `CheckInitCondition → CheckRecipeNo → CheckRecipeNoComp → CheckPageNo`, REQ-OFF 엣지 추가, 루프백(CheckCycleStop)을 RecipeNo로 회귀 - 리셋: `RestoreDeviceStatus`/`OnSeqActionStop`에 Recipe 비트·워드 초기화 - `_RecipeManager`는 **Enter 노드에서 미리 확보**해 사용 - STEP6: 페이지 상한 하드코딩(`>2`) 제거 → `_ScannerCanvasUserCtrl.Model.Layers.Count()` 가변 검증(Recipe별 2~5페이지) - **CSV 디바이스맵 4종**(`D:\ILSOSConfig\…PTOP\External\PLC`): M70509/M70009/D70502/D70002 라벨을 enum과 정합(`.bak260618` 백업). enum 값/인덱스 ↔ CSV 주소 ↔ Excel 빨간셀 전부 1:1 일치 확인. - STEP5(UI Recipe 표시)는 선택이라 생략. 핸드셰이크는 기존 Page 미러형(COMPLETE 비트만) — PLC 사양 최종 정합/base 절대주소는 PLC 담당자 확인 권장. - ⚠️ 빌드는 VS Rebuild로 검증 필요(레거시 포함). 작업 중 Excel 워킹트리본(57249)을 커밋본(46119)으로 되돌린 이슈 있었음(도연님 확인 → 문제없음). ## 15:33 ### 참고 자료 - 현재 PTOP 현장 레이저 참고 메뉴얼: `Doc/메뉴얼/공통/Laser/Trumpf/OPC UA for CPX.pdf` (Trumpf, OPC UA for CPX). ## 15:56 ### Manual Laser Power Control 시작 파라미터 Power 기본값 0으로 변경 - 프로그램 시작 시 Manual - Laser Power Control의 Power 파라미터 초기값 변경: **Percent 10 → 0, Watt 300 → 0**. - 위치: `UCScannerLaserControlViewModel.InitVariable()` (`LaserPower1Percent`, `LaserPower1Watt`). - 커밋 `5eebe96`. ## 19:44 ### SeqAutoRunPTOP.cs — PLCAddress 애매모호한 참조(CS0104) 분석 (퇴근 후 작업용 / 소스 무수정·diff 프리뷰만) > 요청: `docs/260618_18_40_이후에_확인할_소스.txt` > ① 애매모호한 참조 ② PLCAddress error 해결 ③ 시퀀스 타이밍차트 ④ 분석/정리. **바로 수정 X, diff 프리뷰만.** **■ 근본 원인 (한 줄): `using static` 두 개가 같은 이름의 enum 4종을 동시에 끌어와 충돌.** - `SeqAutoRunPTOP.cs` 상단: - L22 `using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP;` - L23 `using static WeldingCommon.Devices.PLCController;` - 그런데 `eBitInput / eBitOutput / eWordInput / eWordOutput` **4종이 두 클래스에 똑같은 이름으로 각각 정의**되어 있음: - `WeldingCommon.Devices.PLCController` (base) — `PLCController.Address.cs` - `ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP : PLCController` (파생) — `Device/PLC/PLCController.Address.cs` - 두 정의는 **값/멤버가 완전히 동일**(260617 "PLCController.Address 통일" 커밋으로 PTOP에 복제됨). - 결과: 코드에서 `eBitOutput.PC_AUTO_STATUS`처럼 **수식어 없이** 쓰면 컴파일러가 둘 중 무엇인지 못 정함 → **CS0104 '모호한 참조'**. 파일 내 `eBitInput/eBitOutput/eWordInput/eWordOutput`을 쓰는 **모든 줄이 동일 에러**. **■ 헷갈리면 안 되는 점 — 같이 쓰는 다른 enum들은 충돌 아님 (그대로 둘 것)** - `eCommonBitInput/eCommonBitOutput/eCommonWordInput/eCommonWordOutput` → **프레임워크(AuroraPLC) 공용 enum**. `using AuroraPLC;`로 들어옴. base `PLCController.Logic.cs`의 `WriteBit(eCommonBitOutput …)` 등이 이걸 받음. **`using static`와 무관 → 충돌 없음.** (`RestoreDeviceStatus`가 이걸 사용. `PC_RECIPE_CHANGE_COMPLETE`는 15:30 작업에서 공용 enum에 동기화 완료.) - `eADOAddress` → `AjinIO.IOModuleInfo` (L21 `using static …AjinIO.IOModuleInfo;`). 충돌 없음. - `ePrismaticDOAddress` → 이 파일 안에서 로컬 정의. 충돌 없음. **■ 왜 `(int)` 캐스트한 줄은 멀쩡해 보였나 (중요 포인트)** - PTOP는 자기 enum용 타입드 오버로드를 따로 가짐 — `Device/PLC/PLCController.Logic.cs`: - `ReadBit(eBitInput)`, `ReadOutBit(eBitOutput)`, `WriteBit(eBitOutput,…)`, `ReadWord(eWordInput)`, `WriteWord(eWordOutput,…)`, `WriteDWord(eWordOutput,…)`, `ReadWords(eWordInput,eWordInput)`. - 즉 **타입 자체는 PTOP enum이 맞는데**, `using static` 중복 탓에 *이름 해석 단계*에서 먼저 막힌다. 그래서 `(int)eBitOutput.X`(캐스트)든 `eBitOutput.X`(논캐스트)든 **둘 다 CS0104**. (캐스트 유무가 원인이 아님 — 원인은 오로지 이름 모호성.) **■ 해결안 (가장 단순·안전) — L23 한 줄 제거** ```diff using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo; using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP; - using static WeldingCommon.Devices.PLCController; using Application = System.Windows.Application; ``` - 근거: 이 파일의 `_PLC`는 `PLCControllerPTOP` 타입이고, 4종 enum은 PTOP 정의가 base와 **값까지 동일**하므로 PTOP 쪽만 남기면 전부 정상 해석됨. `eCommon*`는 `using AuroraPLC`로 유지되므로 `RestoreDeviceStatus`도 안전. - **부작용 점검 필요(퇴근 후 확인)**: L23를 지웠을 때 base `PLCController`의 *static 멤버/상수*를 수식어 없이 쓰는 곳이 있는지. → 현재 파일에서 base에서만 오는 비수식 심볼은 안 보임(전부 PTOP/AuroraPLC/로컬). VS Rebuild로 최종 검증. **■ 대안 (L23를 꼭 남겨야 한다면)** - 파일 상단에 별칭으로 못박기: `using eBitOutput = ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP.eBitOutput;` (4종 각각). → 장황함. 1안(L23 제거) 권장. - 더 근본책: PTOP `PLCController.Address.cs`의 **중복 enum 정의 자체를 삭제**하고 base 것을 상속해 쓰기. 단 PTOP Logic의 `ReadBit(eBitInput)` 등 오버로드 시그니처가 base enum을 받도록 바꿔야 해서 변경 범위 큼. **지금은 1안으로 끊고, 통일은 별도 과제**( [[plc-devicemap-260617-pending]] 와 함께 ). **■ 적용 전 확인 체크리스트 (퇴근 후)** 1. L23 제거 후 VS **Rebuild** (이 파일뿐 아니라 같은 패턴 쓰는 `SeqAutoRunPrismatic.cs`, `SeqTestRun.cs`, `SeqWaitWeldOrChangePage.cs` 동반 점검). 2. `eCommon*` 사용부(`RestoreDeviceStatus`)가 그대로 빌드되는지. 3. 런타임 동작 변화 없음(이름 해석만 바뀜) — 단 빌드 통과 자체가 목적. --- ### SeqAutoRunPTOP 시퀀스 타이밍 차트 (1 사이클) 플로우(Builder): `Enter → CheckInitCondition → CheckRecipeNo →(REQ ON) CheckRecipeNoComp / (REQ OFF) ─┐ → CheckPageNo → CheckPageNoComp → SetUploadWeldingList → [Sub]UploadWeldingList → GetResult → WeldingStartReadBit → WaitWeldingStart → ExecuteWelding → CheckCycleStop →(loop) CheckRecipeNo` 저장 경로: `… → SaveResultData → WriteCompletionPLCBit → Complete → (다시 Enter)` ``` PC(=우리) PLC 설명 │ ◀── RECIPE_CHANGE_REQ(0x09) ── [CheckRecipeNo] 논블로킹 1회 peek │ OFF → 현 Recipe 유지하고 PageNo로 점프 │ (REQ ON 시에만 아래 Comp 진입) │ read PLC_RECIPE_NO(D, idx2) ×3 [CheckRecipeNoComp] 200ms×3 검증 │ ActivateRecipe + 반영 폴링(10ms) .Id 1:1 조회 후 활성, 일치까지 대기 │ ── PC_RECIPE_NO 에코 ──▶ │ ── PC_RECIPE_CHANGE_COMPLETE=false ─▶ (Page 미러형: COMPLETE 비트만) │ │ ◀── PAGE_CHANGE_REQ(0x08) ON 대기 ── [CheckPageNo] ON까지 무한대기(10ms 폴링, 60s마다 로그) │ read PLC_PAGE_NO ×3 (200ms) [CheckPageNoComp] 3회 검증 │ 페이지 상한 = Layers.Count()로 가변검증 (1..N, 범위밖이면 return null) │ CellId/LotId read, _CurrentPageNo=Page-1 │ ── PC_PAGE_NO 에코 ──▶ │ ── PC_PAGE_CHANGE_COMPLETE=false ─▶ │ EVENT_AUTO_RUN_UPDATE_PAGENUM 발행 │ │ [SetUploadWeldingList] _CurrentPageNo로 Layer 선택 → 용접리스트 파라미터 │ [Sub:UploadWeldingList] 스캐너 리스트 업로드 │ [GetResult] Success=false면 return null(중단) │ │ ◀── WELD_READY_REQ(0x10) ON 대기 ── [WeldingStartReadBit] ON까지 무한대기 │ ── (page1) PC_WELD_READY_ACK=1, BUSY=1 ─▶ [WaitWeldingStart] 200ms 후 COMPLETE=0 │ ── (page2) PC_WELD_P_READY_REQ=1, P_BUSY=1 ─▶ 〃 P_COMP_ACK=0 │ │ ┌───────────── [ExecuteWelding] ───────────── │ IO DO9(Core)=1, DO13(Ring)=1 (Laser Gate ON) │ ── Gate ON Delay 15ms (매뉴얼 ≥10ms) ── │ Scanner.ExecuteList(LIST1) │ Scanner.WaitForListTaskCompleted(1000ms) │ IO DO9=0, DO13=0 (Laser Gate OFF, 완료 즉시) │ JumpAbs(0,0) + SelectCorrectionTable(1) 원복 │ ── (page1) READY_ACK=0 → BUSY=0 → COMPLETE=1 (각 5ms) ─▶ │ ── (page2) P_READY_REQ=0 → P_BUSY=0 → P_COMP_ACK=1 ─▶ │ └─ TactTime 로그(예: ~285ms) │ │ [CheckCycleStop] → 항상 CheckRecipeNo로 루프백 (정지조건 미구현 TODO) │ ※ 정상 종료 경로(Save→WriteCompletionPLCBit→Complete)는 │ 현재 CheckCycleStop이 무조건 루프백이라 도달 안 함 — 흐름 확인 필요. ``` **타이밍차트에서 같이 눈에 띈 것 (참고, 이번 에러와 별개):** - `WaitWeldingStart`/`ExecuteWelding`의 page 분기 비트 네이밍이 음/양극에서 엇갈려 보임(`PC_WELD_P_READY_REQ`를 ACK 의미로 ON). PLC 사양과 1:1 재확인 권장. - `CheckCycleStop`이 무조건 `SEQ_CHECK_RECIPENO` 반환 → `SaveResultData~Complete` 정상경로 미도달. 의도된 건지 확인 필요(카운트 업데이트/결과저장이 안 탈 수 있음). - 위 2건은 **이번 PLCAddress 에러와 무관** — 별도 검토 항목으로만 메모. ### [적용] L23 제거 + 빌드 검증 - **적용함**: `SeqAutoRunPTOP.cs`에서 `using static WeldingCommon.Devices.PLCController;`(L23) 제거. (1안 그대로) - 빌드 검증(MSBuild CLI, x64-Debug): - **PTOP standalone 빌드 → CoreCompile 통과** (CS0104 사라짐, post-build `xcopy`만 `SolutionDir`=`*Undefined*`로 실패 — 산출물은 생성됨). ⇒ `SeqAutoRunPTOP.cs` 정상 컴파일 확인. - SolutionDir 지정 2차 빌드에서 **WeldingCommon `_wpftmp`(WPF 임시컴파일) 패스가 `eCommonBitInput/Output/WordInput/WordOutput`을 CS0246**으로 못 찾음 → 이 enum들은 레포 소스에 정의 없음(External/Aurora 프레임워크 어셈블리 타입). **내 수정과 무관**(WeldingCommon은 PTOP 파일 미참조), CLI 환경/참조 이슈로 판단. - **최종 검증은 VS Rebuild 권장**(Aurora 바이너리가 `_out\x64-Debug`에 정상 배치된 상태). 동일 패턴 파일(`SeqAutoRunPrismatic.cs` 등)은 이번에 미수정 — 추후 동반 점검. ### [정정·최종] 진짜 근본 원인 = HEAD 커밋 `89e9a02 "PLCController.Address 통일"`의 미완성 리네임 - 앞서 CS0246(`eCommon*` 없음)을 "CLI 환경 이슈"로 본 것은 **오판**. VS에서도 동일 에러. 추적 결과 **커밋 `89e9a02`가 base `WeldingCommon/…/PLCController.Address.cs`의 enum 선언만 리네임**한 게 원인: - `eCommonBitInput→eBitInput`, `eCommonBitOutput→eBitOutput`, `eCommonWordInput→eWordInput`, `eCommonWordOutput→eWordOutput` - **소비처(~10파일·60+곳)는 여전히 `eCommon*`** (base `PLCController.Logic.cs`의 타입드 API, `SeqExecutePlcBitInterface`, `RMSHandler`, `AlarmManager`, `AlarmMonitoring`, PTOP `SeqTestRun/SeqWaitWeldOrChangePage/SeqAutoRunPrismatic/SeqAutoRunPTOP`) → 전부 CS0246. - 덤으로, base가 `eBitOutput`을 갖게 되며 PTOP `eBitOutput`과 `using static` 2개에서 충돌 → 처음 보고된 **CS0104**까지 이 커밋이 유발. (도연님 메모: PTOP와 통일하려 복붙하다 base 표기까지 덮인 것.) - **해결(채택: 커밋 되돌리기)**: - `git checkout 89e9a02^ -- WeldingComponents/WeldingCommon/Devices/PLC/PLCController.Address.cs` (base를 `eCommon*`로 원복, 워킹트리만) - `SeqAutoRunPTOP.cs` **L23 `using static WeldingCommon.Devices.PLCController;` 복구**(=내 임시수정 원복). `RestoreDeviceStatus`의 `eCommonBitOutput`이 이걸 통해 해석됨. - 구조 환원: **base=`eCommon*`, PTOP=`eBit*/eWord*`** (이름이 달라 `using static` 2개 공존해도 충돌 없음). - **빌드 검증**: `ILSOS_PrismaticRD_PTOP.csproj` (Debug|x64, SolutionDir 지정) **MSBuild EXITCODE=0, error 0건**. WeldingCommon 포함 정상 컴파일 확인. - 변경 파일: `PLCController.Address.cs`(원복) 1개뿐. `SeqAutoRunPTOP.cs`는 HEAD와 동일(diff 없음). **미커밋** — 도연님 커밋 권장. - 후속: "Address 통일"을 정말 하려면 base 리네임 + 소비처 60+곳 일괄 교체 + PTOP 중복 enum 정리까지 **한 번에** 가야 함(별도 과제). 지금은 되돌려 빌드 정상화 우선. ## 20:33 ### 오늘 작업 마무리 - 퇴근 후 작업으로 시작했던 SeqAutoRunPTOP.cs PLCAddress 에러건 + 현장 PC IO null 에러건 둘 다 정리하고 커밋/푸시까지 완료. - **빌드 깨짐 근본 원인**: 직전 커밋 `89e9a02 "PLCController.Address 통일"`이 base(WeldingCommon)의 `eCommon*` enum 선언만 `eBit*/eWord*`로 리네임하면서, 소비처 60+곳이 CS0246으로 깨지고 PTOP enum과 충돌(CS0104)까지 났던 것. (PTOP랑 통일하려 복붙하다 base 표기까지 덮인 게 원인) → base를 `eCommon*`로 원복해 정상화. - **현장 PC 런타임 꺼짐**: 시뮬 모드가 아니고 IO보드가 없으면 `IODevice._iOUnit`이 null → 레시피 메뉴 진입 시 `OnMonitoring`의 ReadDI(11/15)에서 NRE. `IsConnected()` 가드로 미연결이면 폴링 스킵하게 처리 → 안 꺼지는 것 확인 완료. (토스트 알림은 안 넣기로, 시뮬 체크는 직접 하기로) - `field/ptop-1st`에 **3개 커밋 푸시 완료** (PR은 안 만듦): - `95ef7b9` fix: PLCController.Address eCommon* enum 원복 (빌드 정상화) - `a312e4e` fix: 레시피 화면 IO 미연결 시 null 가드 (OnMonitoring) - `0ca485e` docs: 작업일지 - 워킹트리 잔여물(`AuroraPLC_*_wpftmp.csproj` 빌드 임시파일, `260618_18_40_이후에_확인할_소스.txt` 메모)은 커밋 제외, 필요 시 정리 예정. - 빌드 검증: WeldingCommon 컴파일만(`/t:Compile`) EXITCODE=0, CS 에러 0건. (전체 빌드 시 뜨던 MSB3021/3027은 실행 중인 Aurora.exe의 DLL 복사 잠금일 뿐, 컴파일 에러 아님)