티스토리 뷰

단계의 목표
이 단계의 목표는 파이썬으로 프린터와 관련한 기능을 수행하는 코드를 작성하는 것이다.
핵심 기능은 다음과 같으며, 사실상 사용하는 기능은 프린터 출력이 전부이다.
- 프린터 출력하기
- 사용가능한 프린터 목록 가져오기
- 프린터 상태 확인하기
양해
GitHub: https://github.com/nicewook/receipt-printer
- GitHub 리포지토리는 참고 공유하지만 별도로 정리가 잘 되어있지는 않으며 블로그 포스팅의 내용과는 달라질 수 있다.
- 범용성을 고려하지 않았다. 하드코딩 된 부분이 많다는 것이다.
기능 보기
각각의 기능들을 확인해보자. 리포지토리에서 printer.py 파일을 보면 된다.
바이브 코딩의 시대이다. 이제 실제 코드를 하나하나 뜯어보는 것은 의미가 없을 수 있다.
어떤 기능이 필요한지만 알면 AI에게 각자의 필요에 따른 기능 구현을 요청하고 검증하기만 하면 된다.
프린터 출력하기
요약
출력 요청을 받은 텍스트를 줄바꿈 해주고, 프린터 명령을 추가한 다음에 출력하는 것이 전부이다.
기능 설명
매개변수
- text: 출력할 텍스트 (최대 200자)
- printer_name: 프린터 이름 (기본값: "BIXOLON_SRP_330II")
- isFromMCP: MCP 서버에서 호출 여부. MCP 서버와 stdin/stdout으로 통신하기에 이를 구분한 것이다.
반환값
- True: 출력 성공
- False: 출력 실패
프로세스
- prepare_print_content 함수로 텍스트를 40자 폭으로 줄바꿈 처리(영수증 프린터의 폭 감안)
- create_esc_pos_content 함수로 ESC/POS 명령어 포함 이진 데이터 생성
- ESC/POS 명령어로 CP949/EUC-KR 인코딩, 용지 자르기 등의 명령을 포함하는 것이다.
- 임시 파일 생성 및 이진 데이터 저장
- lp -d [프린터명] -o raw [파일경로] 명령어로 출력
- 임시 파일 삭제 및 결과 반환
def printer_print(text, printer_name="BIXOLON_SRP_330II", isFromMCP=False):
"""CUPS를 통해 프린터로 출력"""
try:
# 출력할 내용 준비
lines = prepare_print_content(text)
# ESC/POS 명령어 포함한 내용 생성
print_content = create_esc_pos_content(lines)
# 임시 파일 생성
with tempfile.NamedTemporaryFile(delete=False, suffix='.bin') as temp_file:
temp_file.write(print_content)
temp_file_path = temp_file.name
# lp 명령어로 출력
cmd = ['lp', '-d', printer_name, '-o', 'raw', temp_file_path]
result = subprocess.run(cmd, capture_output=True, text=True)
# 임시 파일 삭제
import os
os.unlink(temp_file_path)
if result.returncode == 0:
if not isFromMCP:
print(f"✅ 출력 완료: {len(lines)}줄 → {printer_name}")
if result.stdout.strip():
print(f"📝 작업 ID: {result.stdout.strip()}")
return True
else:
if not isFromMCP:
print(f"❌ 출력 실패: {result.stderr}")
return False
except Exception as e:
if not isFromMCP:
print(f"❌ 출력 오류: {e}")
return False
사용가능한 프린터 목록 가져오기
요약
printer_list 함수는 CUPS 시스템에서 사용 가능한 프린터 목록을 조회한다.
기능
반환값
- 프린터 이름 문자열 리스트
주요 동작 과정
- lpstat -p 명령어 실행
- 출력 결과를 줄별로 분석
- "printer "로 시작하는 줄에서 프린터 이름 추출
- 프린터 이름 리스트 반환
def printer_list():
"""사용 가능한 프린터 목록 가져오기"""
try:
result = subprocess.run(['lpstat', '-p'], capture_output=True, text=True)
if result.returncode == 0:
printers = []
for line in result.stdout.split('\\n'):
if line.startswith('printer '):
printer_name = line.split()[1]
printers.append(printer_name)
return printers
return []
except Exception:
return []
프린터 상태 확인하기
요약
특정 프린터의 상태를 확인한다.
기능
- 프린터 상태 확인: lpstat -p [프린터명] 명령어로 특정 프린터 상태 조회
- 상태 정보 반환: 프린터의 현재 상태 문자열 반환
매개변수
- printer_name: 상태를 확인할 프린터 이름
반환값
- str: 프린터 상태 정보 (예: "printer BIXOLON_SRP_330II is idle")
- str: 오류 메시지 (프린터를 찾을 수 없거나 명령어 실행 실패 시)
주요 동작 과정
- lpstat -p [프린터명] 명령어 실행
- 성공 시 상태 정보 문자열 반환
- 실패 시 "프린터를 찾을 수 없습니다" 메시지 반환
- 예외 발생 시 "상태 확인 실패" 메시지 반환
def printer_status(printer_name):
"""프린터 상태 확인"""
try:
result = subprocess.run(['lpstat', '-p', printer_name], capture_output=True, text=True)
if result.returncode == 0:
return result.stdout.strip()
else:
return f"프린터 '{printer_name}'을 찾을 수 없습니다."
except Exception as e:
return f"상태 확인 실패: {e}"
결과물 미리보기
출력 요청
클로드 코드에 다음과 같이 출력을 요청한다.
- > 를 붙여서 메모하면 출력해준다.
- 출력 해달라는 말을 명시적으로 할 수도 있다.
- 하나의 프롬프트에 여러 개의 출력을 요청할 수도 있다.
- 마지막의 경우가 가장 인상적인데 > 나 출력 요청을 명시적으로 하지 않았는데도 메모를 둘로 나누어서 출력해준다.
- 클로드가 앞선 요청들의 맥락상 출력을 요청한 것으로 이해하고, 또한 별개의 두 메모라고 인식한 것이다.
- 항상 이렇게 출력되는 것은 아니다(non-deterministic). 이를 좀더 강제하려면 description 등에 프롬프트 엔지니어링을 해주어야 할 것이다. 혹은 가까운 미래에 공짜 점심으로 AI가 의도를 더욱 잘 알아듣게 될 수도 있겠다.

출력 결과
이렇게 출력하여 테이블에 올려두었다가 하나씩 해결하며 오른쪽의 빈 용기에 넣어둔다.

반응형
'develop-and-AI' 카테고리의 다른 글
| 영수증 프린터로 할 일 관리 - MCP 서버 코드(개선) (0) | 2025.07.15 |
|---|---|
| 영수증 프린터로 할 일 관리 - MCP 서버 코드 (0) | 2025.07.11 |
| 영수증 프린터로 할 일 관리 - 프린터 준비 (0) | 2025.07.11 |
| 영수증 프린터로 할 일 관리 - 시작 (0) | 2025.07.11 |
| 내가 궁금해서 정리해보는 MCP (0) | 2025.07.04 |
반응형
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- API
- clean agile
- bun
- 독서
- github
- 클린 애자일
- intellij
- agile
- Echo
- 독서후기
- solid
- gocore
- middleware
- MCP
- postgres
- 잡학툰
- notion
- ChatGPT
- 오블완
- 영화
- OpenAI
- Gin
- 티스토리챌린지
- go
- 인텔리제이
- golang
- strange
- 체호프
- backend
- websocket
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
글 보관함