""" In-Sight 2001C-353 트리거 후 전체 셀 스캔 스크립트 SE8 트리거 실행 → 결과 갱신 완료 후 A0~Z50 범위 GV 스캔. 결과는 콘솔 출력과 find_cells_trigger_result.txt 에 동시 저장. """ import socket import string import time IP = "169.254.0.1" PORT = 23 COLS = list(string.ascii_uppercase) # A ~ Z (26개) ROWS = range(0, 251) # 0 ~ 250 (251개) → 총 6526셀 RESULT_FILE = "find_cells_trigger_result.txt" # ------------------------------------------------------------------ # # 저수준 소켓 헬퍼 (insight.py 방식 동일) # ------------------------------------------------------------------ # def _read_line(sock: socket.socket, buf: bytearray) -> str: """버퍼에서 \\r\\n까지 읽어 문자열로 반환. 남은 데이터는 buf에 보존.""" while b"\r\n" not in buf: try: chunk = sock.recv(4096) except socket.timeout: break if not chunk: break buf += chunk if b"\r\n" in buf: idx = buf.index(b"\r\n") line = bytes(buf[:idx]) del buf[:idx + 2] else: line = bytes(buf) buf.clear() for encoding in ["euc-kr", "cp949", "utf-8"]: try: return line.decode(encoding).strip() except Exception: continue return line.decode(errors="ignore").strip() def _send(sock: socket.socket, cmd: str): sock.sendall((cmd + "\r\n").encode()) # ------------------------------------------------------------------ # # 로그인 (insight.py connect() 시퀀스와 동일) # ------------------------------------------------------------------ # def _login(sock: socket.socket, buf: bytearray): banner = _read_line(sock, buf) print(f"[연결] 배너: {banner!r}") _send(sock, "admin") while b"Password:" not in buf: try: chunk = sock.recv(4096) except socket.timeout: break if not chunk: break buf += chunk prompt = buf.decode(errors="ignore").strip() buf.clear() print(f"[연결] 프롬프트: {prompt!r}") sock.sendall(b"\r\n") # 빈 비밀번호 result = _read_line(sock, buf) print(f"[연결] 로그인: {result!r}") if "Logged In" not in result: raise RuntimeError(f"로그인 실패: {result!r}") # ------------------------------------------------------------------ # # SE8 트리거 # ------------------------------------------------------------------ # def _trigger(sock: socket.socket, buf: bytearray): """SE8 소프트웨어 트리거 전송 후 응답 수신.""" _send(sock, "SE8") response = _read_line(sock, buf) print(f"[트리거] SE8 응답: {response!r}") # ------------------------------------------------------------------ # # 셀 스캔 # ------------------------------------------------------------------ # def _scan(sock: socket.socket, buf: bytearray) -> dict: """GV[열][행] 전체 스캔 → {셀주소: 값문자열}""" total = len(COLS) * len(ROWS) found = {} for col in COLS: for row in ROWS: cell = f"{col}{row}" _send(sock, f"GV{cell}") status = _read_line(sock, buf) # "1" 또는 "0" if status == "1": value = _read_line(sock, buf) if not value.strip(): pass else: found[cell] = value try: print(f"\r[{cell:<4}] = {value:<40}") except UnicodeEncodeError: print(f"\r[{cell:<4}] = {value.encode('utf-8', errors='replace')!r}") done = (COLS.index(col)) * len(ROWS) + row + 1 print( f"스캔 중... [{cell} / Z{ROWS[-1]}] ({done}/{total})", end="\r", flush=True, ) print() # 진행바 줄 정리 return found # ------------------------------------------------------------------ # # 결과 저장 # ------------------------------------------------------------------ # def _save(found: dict, path: str = RESULT_FILE): with open(path, "w", encoding="utf-8") as f: f.write(f"스캔 범위: A0 ~ Z{ROWS[-1]} / 유효 셀: {len(found)}개\n") f.write("=" * 40 + "\n") for cell, val in found.items(): f.write(f"[{cell:<4}] = {val}\n") print(f"결과 저장 완료 → {path}") # ------------------------------------------------------------------ # # 값 검색 # ------------------------------------------------------------------ # def _search(found: dict, query: str): matches = {c: v for c, v in found.items() if query.lower() in v.lower()} if matches: print(f"\n[검색] '{query}' 포함 셀 {len(matches)}개:") for cell, val in matches.items(): print(f" [{cell:<4}] = {val}") else: print(f"[검색] '{query}'를 포함한 셀이 없습니다.") # ------------------------------------------------------------------ # # 메인 # ------------------------------------------------------------------ # def main(): print(f"[연결] {IP}:{PORT} 접속 중...") sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(3.0) sock.connect((IP, PORT)) buf = bytearray() try: _login(sock, buf) input("\n준비됐으면 엔터를 누르세요 (리플렉터를 카메라 앞에 올려두세요): ") print("[트리거] SE8 전송 중...") _trigger(sock, buf) print("[대기] 카메라 처리 완료 대기 (1초)...") time.sleep(1) print(f"\n스캔 시작: A0 ~ Z{ROWS[-1]} (총 {len(COLS) * len(ROWS)}셀)\n") found = _scan(sock, buf) finally: sock.close() print(f"\n스캔 완료. 총 {len(found)}개 셀 발견") print("=" * 40) for cell, val in found.items(): try: print(f" [{cell:<4}] = {val}") except UnicodeEncodeError: print(f" [{cell:<4}] = {val.encode('utf-8', errors='replace')!r}") _save(found) print() while True: query = input("찾는 값 입력 (엔터 시 종료): ").strip() if not query: break _search(found, query) if __name__ == "__main__": main()