본문 바로가기
Python/Study

[Python] Snap7 ─ Siemens S7 PLC 통신 라이브러리

by VANCODER 2024. 11. 22.

python-snap7

: Snap7 라이브러리를 위한 Python wrapper

  • TCP/IP 프로토콜을 통해 Siemens PLC에 대한 액세스를 제공
  • Snap7 1.1.0과 Python 3.7+를 위해 개발 
*Snap7: Siemens S7 PLC와 네이티브로 인터페이스하기 위한 오픈 소스, 32/64비트 멀티 플랫폼 이더넷 통신 스위트

 

Snap7 모듈 설치

pip install python-snap7

 

Import

import snap7

1. Client

1-1. Client 연결

1) `snap7.client.Client` 클래스

: Snap7 Client 객체를 생성하고 사용하는 클래스

 

사용 예제

import snap7
client = snap7.client.Client()
client.connect("127.0.0.1", 0, 0, 1102)  # PLC에 연결
print(client.get_connected())  # 연결 상태 확인
# 출력: True

data = client.db_read(1, 0, 4)  # DB 번호 1에서 바이트 0부터 4개 읽기
print(data)
# 출력: bytearray(b"\x00\x00\x00\x00")

data[3] = 0b00000001  # 데이터 수정
print(data)
# 출력: bytearray(b'\x00\x00\x00\x01')

client.db_write(1, 0, data)  # 수정된 데이터를 다시 DB에 쓰기

2) __init__()

__init__(lib_location: str | None = None)

 

: 새로운 Client 인스턴스를 생성

 

매개변수

  • lib_location: snap7.dll 파일의 전체 경로 (선택사항)
    • 경로를 지정하지 않으면, 시스템 PATH에 등록된 snap7.dll 파일을 사용

사용 예제

import snap7

# snap7.dll 파일이 PATH에 있는 경우
client = snap7.client.Client()

# snap7.dll 파일이 특정 경로에 있는 경우
client2 = snap7.client.Client(lib_location="/path/to/snap7.dll")
print(client2)
# 출력: <snap7.client.Client object at 0x0000028B257128E0>

3) connect()

connect(address: str, rack: int, slot: int, tcp_port: int = 102) → Client

 

: PLC에 클라이언트 객체를 연결

 

매개변수

  • address: PLC의 IP 주소
  • rack: PLC가 위치한 랙 번호
  • slot: CPU가 위치한 슬롯 번호
  • tcp_port: PLC의 TCP 포트 (기본값: 102)

반환값

  • Snap7 Logo 인스턴스

사용 예제

import snap7

client = snap7.client.Client()
client.connect("192.168.0.1", 0, 0)  # IP 주소, 랙 0, 슬롯 0에 연결

1-2. 데이터 읽기

db_read()

db_read(db_number: int, start: int, size: int) → bytearray

 

: PLC에서 특정 DB의 일부를 읽음

<참고> 이 메소드는 DB를 읽는 데만 사용해야 하며, Marks, Inputs, Outputs를 읽는 데는 사용 X

 

매개변수

  • db_number: 읽을 DB의 번호
  • start: 읽기를 시작할 바이트의 시작 인덱스
  • size: 읽을 바이트의 크기

반환값

  • 읽은 데이터를 포함하는 버퍼 (bytearray)

사용 예제

import snap7
client = snap7.client.Client()
client.connect("192.168.0.1", 0, 0)
buffer = client.db_read(1, 10, 4)  # DB 번호 1에서 바이트 10부터 14까지 읽음
print(buffer)
# 출력: bytearray(b'\x00\x00')
 

2. Util

`bytearray`에서 값 조회

1) get_int()

snap7.util.get_int(bytearray_: bytearray, byte_index: int) → int

 

: bytearray에서 정수(int) 값을 가져옴

<참고> PLC에서 데이터 타입 int는 2바이트로 표현

 

매개변수

  • bytearray_: 데이터를 읽을 버퍼
  • byte_index: 읽기를 시작할 바이트 인덱스

반환값

  • 읽은 정수 값

사용 예제

from snap7.util import get_int

data = bytearray([0, 255])
value = get_int(data, 0)  # 바이트 배열에서 정수 값을 읽음
print(value)
# 출력: 255

2) get_real()

snap7.util.get_real(bytearray_: bytearray, byte_index: int) → float

 

: 실수(real) 값을 가져옴

<참고> PLC에서 데이터 타입 real은 4바이트로 표현
IEEE 754 binary32 형식을 사용하여 실수를 표현

 

매개변수

  • bytearray_: 데이터를 읽을 버퍼
  • byte_index: 읽기를 시작할 바이트 인덱스

반환값

  • 읽은 실수 값(float)

사용 예제

from snap7.util import get_real

data = bytearray(b'B\xf6\xa4Z')  # IEEE 754 형식의 실수 값
value = get_real(data, 0)  # 바이트 배열에서 실수 값을 읽음
print(value)
# 출력: 123.32099914550781

참고 문서

https://python-snap7.readthedocs.io/en/stable/index.html#

https://medium.com/@kardelenyurtkuran/snap7-python-communication-with-siemens-plc-41829626b2b0

'Python > Study' 카테고리의 다른 글

[Python] asyncpg 비동기 함수 정리  (2) 2024.11.21
[Python] asyncpg ─ PostgreSQL 비동기 연결  (0) 2024.11.21
[Python] asyncio ─ 비동기 방식  (1) 2024.11.18