Pymodbus 레지스터 읽기와 쓰기
ModbusTcpClient로 레지스터를 읽고 쓰며, 예외 응답은 isError로, 무응답은 ModbusException으로 확인한다.
연결
ModbusTcpClient는 요청을 전송하고 응답을 수신할 때까지 대기하는 동기 방식 클라이언트이다. 호스트만 지정하면 포트 502, 응답 대기 3초, 재시도 3회가 기본값이다. connect()는 연결 여부를 True/False로 반환한다.
읽기와 쓰기 예제
from pymodbus import ModbusException
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient("192.0.2.10")
if not client.connect():
raise SystemExit("연결 실패")
try:
# 주소 0부터 holding register 2개를 읽는다
rr = client.read_holding_registers(0, count=2, device_id=1)
if rr.isError():
print("예외 응답:", rr.exception_code)
else:
print(rr.registers)
# 주소 10에 값 1을 쓴다
wr = client.write_register(10, 1, device_id=1)
if wr.isError():
print("예외 응답:", wr.exception_code)
except ModbusException as exc:
# 응답이 오지 않는 등 통신이 실패한 경우다
print("통신 오류:", exc)
finally:
client.close()
인자
address: 0부터 세는 프로토콜 주소이다. 설명서의40001은 0이다.count: 읽을 레지스터 개수이다. 기본값은 1이다.device_id: 장비 번호(unit identifier)이다. 기본값은 1이다.
count와 device_id는 count=2처럼 키워드 인자로만 전달할 수 있다.
참고
device_id는 3.10에서 변경된 이름이다. 그 이전의 3.x에서는 같은 인자를 slave라는 이름으로 사용한다.
실패 유형
장비가 예외 응답을 전송하면 Python 예외는 발생하지 않는다. 반환된 응답의 isError()가 True이고 exception_code에 장비가 전송한 코드가 저장된다. 존재하지 않는 주소를 읽은 경우가 여기에 해당한다.
응답이 전혀 수신되지 않으면 ModbusException이 발생한다. 통신선이 분리되었거나 장비의 전원이 차단된 경우이다.