7.2.4.1 텔레메트리(Telemetry) 라우팅을 위한 퍼블리셔(Publisher) 네이티브 스크립트 작성
산업용 로보틱스 스택에서 텔레메트리(Telemetry)란 단말 기기(Edge Node)의 심장 박동과도 같다. 배터리 소모량, CPU 온도, 관절 액추에이터 상태, 라이다(LiDAR) 점군 데이터 등 거대한 물리적 변화량의 원천 소스가 생성되는 지점이다. 이러한 트래픽을 효율적으로 라우팅하는 출발점인 퍼블리셔(Publisher) 엔드포인트를 구축할 때, 파이썬 기반의 단순한 put 호출을 넘어 zenoh-python 바인딩이 제공하는 네이티브 특성을 최대 한도로 끌어내야 한다.
본 절에서는 엣지 단말 파이썬 환경에서 Zenoh 텔레메트리 퍼블리셔를 선언적으로 구성하고 데이터를 네트워크로 밀어 넣는(Ingestion) 가장 정석적인 네이티브 스크립팅 기법을 설계한다.
1. 데이터 평면(Data Plane)과 키 표현식(Key Expression) 설계
Zenoh 통신망의 가장 큰 특징은 사전에 브로커에 큐(Queue)를 생성할 필요 없이, 데이터의 고유한 이름인 Key Expression(키 표현식) 자체가 네트워크 라우팅의 주소로 기능한다는 점이다. 텔레메트리 퍼블리셔는 자신이 뱉어낼 트래픽의 본질을 명확히 규정하는 식별자 규칙을 가장 먼저 파싱해야 한다.
import zenoh
import time
import json
# 1. 분산 및 확장을 고려한 라우팅 키 네임스페이스 수립
# 문법: [도메인]/[기기ID]/[데이터유형]/[하위분류]
ROBOT_ID = "agv_402"
TOPIC_TELEMETRY = f"factory/{ROBOT_ID}/telemetry/status"
위와 같이 계층적인 구조를 가져감으로써, 향후 통제실(Control Room)에서 factory/*/telemetry/** 와 같은 와일드카드(Wildcard) 서브스크립션을 통해 전체 공장 내 모든 기기의 텔레메트리를 병목 없이(Agregation) 일괄 수집할 수 있는 기반이 마련된다.
2. 퍼블리셔(Publisher) 네이티브 선언 및 혼잡 통제(Congestion Control)
Zenoh 파이썬 래퍼에서 퍼블리셔 객체를 선언(declare_publisher)할 때는, 단순히 데이터를 쏘아 보내는 빈 깡통 객체가 아닌 내부 C-ABI 버퍼 큐가 내장된 핸들러를 반환받는다. 여기서 가장 극히 주의해야 할 점은 혼잡 제어(Congestion Control) 정책 모델의 차용이다.
파이썬 코드에서 화상 카메라 프레임을 초당 120회 넘게 쏘아 보낸다고 가정하자. 만약 와이파이(Wi-Fi) 망이 열화되어 대역폭이 좁아질 경우, 로컬 캐시 버퍼는 터져나갈 것이다. Zenoh는 기본적으로 네트워크가 꽉 찼을 때 put 함수 호출을 블로킹(Blocking) 시키는 옵션(CongestionControl.BLOCK)과 즉시 폐기하는 옵션(CongestionControl.DROP)을 제공한다.
def start_telemetry_publisher(session: zenoh.Session):
# 퍼블리셔 선언: 통신망 병목 시 파이썬 프로그램이 멈추지 않고 과거 데이터를 버리도록 DROP 정책 선언
pub = session.declare_publisher(
TOPIC_TELEMETRY,
congestion_control=zenoh.CongestionControl.DROP
)
print(f"[{ROBOT_ID}] 텔레메트리 퍼블리셔 활성화: {TOPIC_TELEMETRY}")
try:
while True:
# 엣지 단말의 센서 값 수집 흉내
sensor_data = {
"timestamp": time.time(),
"battery_level": 84.5,
"cpu_temp": 45.2,
"status": "OPERATING"
}
# 2. 직렬화(Serialization): Python 딕셔너리를 바이트 버퍼 구조로 파싱
# 실무에서는 JSON 대신 Protobuf나 Apache Arrow 등으로 마샬링 오버헤드를 줄일 것
payload = json.dumps(sensor_data).encode("utf-8")
# 3. 데이터 송출: PyO3 레이어를 거쳐 Rust 코어 백그라운드 스레드로 진입
pub.put(payload)
# 10 Hz 주기로 전송 슬립 (루프 블로킹 방어)
time.sleep(0.1)
except KeyboardInterrupt:
pass
finally:
# 4. 자원 명시적 해제 및 파이프라인 우아한 종료
pub.undeclare()
3. 네트워크 토폴로지 분리와 피어(Peer) 모드 동작 검열
파이썬 개발자가 작성한 코드를 실행할 때, 백그라운드에서 zenoh.open()이 발포하며 주변의 라우터(Router) 노드를 탐색한다. 이때 유의해야 할 것은 실행 모드 구조다.
일반적으로 엣지 단말은 클라이언트 모드(Client Mode)로 구동되어 무선 백홀 망 바깥에 위치한 코어 라우터와 1:1 세션을 매듭짓는다. 이 방식은 단말의 CPU 로드를 최적화시킨다. 그러나 오프라인 환경에서 로봇과 모니터링 PC가 다이렉트 랜선으로 연결되는 상황이라면 자동으로 피어 모드(Peer Mode)로 스위칭되어 그 어떠한 브로커 없이도 두 통신 기기간 직결 데이터를 발포하게 된다.
위의 파이썬 스크립트 작성 시에는 프로토콜이나 호스트 IP에 대한 하드코딩(Hard-coding)을 절대 삼가하고, zenoh.Config() 선언 외에 인프라스트럭처 디스커버리를 프로토콜 자체에 온전히 위임(Delegation)하는 선언적 코딩 철학을 사수하라.