# ESC/POS 영수증 프린터 트러블슈팅 가이드

> 작성일: 2026-03-05  
> 프린터: 192.168.0.174:9100 (올댓포스 오른쪽)

---

## 핵심 요약

| 항목 | 올바른 방식 | 잘못된 방식 |
|------|------------|------------|
| **인코딩** | EUC-KR | UTF-8 |
| **전송 방식** | socket 직접 전송 | python-escpos 라이브러리 |
| **이모지** | 사용 금지 (`>>`, `[V]`) | ❌ 🖨️ ✅ |
| **이미지** | 사용 금지 | PIL Image |
| **용지 폭** | 48자 기준 | 글자수 무제한 |
| **용지 길이** | 무제한 (롤 용지) | 제한 없음 |

---

## 증상별 해결책

### 1. 아무것도 안 나옴
```
원인: 프린터 연결 실패
해결:
1. ping 192.168.0.174 확인
2. 포트 9100 확인 (Test-NetConnection -ComputerName 192.168.0.174 -Port 9100)
3. 프린터 전원 확인
```

### 2. "EAT" 또는 깨진 문자만 나옴
```
원인: 이미지 인쇄 방식 사용
해결: 이미지 방식 사용 금지! 텍스트 + EUC-KR 인코딩 사용

❌ 잘못된 코드:
from escpos.printer import Network
p = Network(...)
p.image(img)  # 이미지 인쇄 - 안 됨!

✅ 올바른 코드:
sock = socket.socket(...)
text_bytes = message.encode('euc-kr', errors='replace')
sock.sendall(INIT + text_bytes + CUT)
```

### 3. 한글이 ???? 로 나옴
```
원인: UTF-8 인코딩 사용
해결: EUC-KR 인코딩 사용

❌ 잘못된 코드:
text.encode('utf-8')

✅ 올바른 코드:
text.encode('euc-kr', errors='replace')
```

### 4. 이모지가 ? 로 나옴
```
원인: ESC/POS 프린터는 이모지 미지원
해결: 텍스트로 대체

❌ ✅ 상호작용 없음
✅ [V] 상호작용 없음

❌ ⚠️ 주의 필요
✅ [!] 주의 필요

❌ 📋 처방 해석
✅ >> 처방 해석
```

### 5. 첫 줄만 나오고 잘림
```
원인: python-escpos 라이브러리의 set() 함수 문제
해결: socket 직접 전송 방식 사용

❌ 잘못된 코드:
from escpos.printer import Network
p = Network(...)
p.set(align='center', bold=True)  # 이 명령이 문제!
p.text("내용")

✅ 올바른 코드:
sock = socket.socket(...)
sock.sendall(INIT + text.encode('euc-kr') + CUT)
```

### 6. 연결은 되는데 인쇄 안 됨
```
원인: 프린터가 이전 작업에서 hang 상태
해결: 
1. 프린터 전원 껐다 켜기
2. 또는 INIT 명령 먼저 전송: ESC + b'@'
```

---

## 올바른 코드 템플릿

### 기본 텍스트 인쇄
```python
import socket

# 프린터 설정
PRINTER_IP = "192.168.0.174"
PRINTER_PORT = 9100

# ESC/POS 명령어
ESC = b'\x1b'
INIT = ESC + b'@'           # 프린터 초기화
CUT = ESC + b'd\x03'        # 피드 + 커트

def print_text(message: str) -> bool:
    try:
        # EUC-KR 인코딩 (한글 지원)
        text_bytes = message.encode('euc-kr', errors='replace')
        
        # 명령어 조합
        command = INIT + text_bytes + b'\n\n\n' + CUT
        
        # 소켓 전송
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(10)
        sock.connect((PRINTER_IP, PRINTER_PORT))
        sock.sendall(command)
        sock.close()
        return True
    except Exception as e:
        print(f"인쇄 오류: {e}")
        return False

# 사용 예시
message = """
================================================
              [ 테스트 출력 ]
================================================
환자: 홍길동
처방번호: 20260305000001

[V] 상호작용 없음

>> 처방 해석
  감기 증상 완화를 위한 처방입니다.

================================================
                 청춘약국
================================================
"""
print_text(message)
```

### 중앙 정렬 헬퍼
```python
def center_text(text: str, width: int = 48) -> str:
    """48자 기준 중앙 정렬"""
    text_len = len(text)
    if text_len >= width:
        return text
    spaces = (width - text_len) // 2
    return " " * spaces + text

# 사용
print(center_text("[ PAAI 복약안내 ]"))
# 출력: "               [ PAAI 복약안내 ]"
```

### 줄바꿈 헬퍼
```python
def wrap_text(text: str, width: int = 44) -> list:
    """44자 기준 줄바꿈 (들여쓰기 여유)"""
    lines = []
    words = text.split()
    current = ""
    
    for word in words:
        if len(current) + len(word) + 1 <= width:
            current = current + " " + word if current else word
        else:
            if current:
                lines.append(current)
            current = word
    
    if current:
        lines.append(current)
    
    return lines if lines else [text[:width]]

# 사용
long_text = "경골 하단 및 중족골 골절로 인한 통증과 부종 관리를 위해 NSAIDs를 처방합니다."
for line in wrap_text(long_text, 44):
    print(f"  {line}")
```

---

## 프린터 사양

| 항목 | 값 |
|------|-----|
| IP | 192.168.0.174 |
| Port | 9100 |
| 용지 폭 | 80mm (48자) |
| 인코딩 | EUC-KR (CP949) |
| 한글 | 지원 |
| 이모지 | 미지원 |
| 이미지 | 미지원 (이 프린터) |

---

## 참고 파일

| 파일 | 설명 |
|------|------|
| `backend/pos_printer.py` | ESC/POS 기본 유틸리티 |
| `backend/paai_printer_cli.py` | PAAI 인쇄 전용 CLI |
| `clawd/memory/3월4일 동물약_복약지도서.md` | 동물약 인쇄 가이드 |

---

## 테스트 명령어

```powershell
# 연결 테스트
Test-NetConnection -ComputerName 192.168.0.174 -Port 9100

# 간단 인쇄 테스트
python -c "
import socket
sock = socket.socket()
sock.connect(('192.168.0.174', 9100))
sock.sendall(b'\x1b@Test OK\n\n\n\x1bd\x03')
sock.close()
print('OK')
"

# pos_printer.py 테스트
cd C:\Users\청춘약국\source\pharmacy-pos-qr-system\backend
python pos_printer.py
```

---

## 히스토리

| 날짜 | 문제 | 해결 |
|------|------|------|
| 2026-03-04 | 동물약 투약지도서 이모지 깨짐 | 이모지 제거, 텍스트로 대체 |
| 2026-03-05 | PAAI 인쇄 "EAT"만 출력 | 이미지 방식 → 텍스트 방식 변경 |
| 2026-03-05 | python-escpos 라이브러리 문제 | socket 직접 전송으로 변경 |
