from socket import *
import threading
from time import ctime
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import time
HOST = ''
PORT1 = 20023#端口号
BUFSIZ = 2048#缓存区大小,单位是字节,这里设定了2K的缓冲区
ADDR = (HOST, PORT1)#链接地址
tcpSerSock = socket(AF_INET, SOCK_STREAM)#创建TCP套接字
tcpSerSock.bind(ADDR)#绑定一个端口号
tcpSerSock.listen(5)#监听
file1=open('/srv/www/htdocs/serialports_set.txt','r')#打开配置文件
port = file1.readline()#读取配置文件中的端口号
baudrate = file1.readline()#读取配置文件中的波特率
databit = file1.readline()#读取配置文件中的数据位
stopbit = file1.readline()#读取配置文件中的停止位
datavalidation = file1.readline()#读取配置文件中的数据校验位
file1.close()
PORT2 = "/dev/ttyUSB1"#串口号
logger = modbus_tk.utils.create_logger("console")
master = modbus_rtu.RtuMaster(
serial.Serial(port=PORT2, baudrate=int(baudrate), bytesize=int(databit), parity='N', stopbits=int(stopbit), xonxoff=0)
)#建立串口连接
master.set_timeout(5.0)
master.set_verbose(True)
logger.info("connect to plc")
file2=open('/srv/www/htdocs/read_plc.txt','r')
start_addr = file2.readline()#读取配置文件中要读取的PLC寄存器的起始位
number = file2.readline()#读取配置文件中要读取的PLC寄存器的个数
file2.close()
file3=open('/srv/www/htdocs/write_plc.txt','r')
welche = file3.readline()#读取配置文件中要写的PLC寄存器的地址
statistik = file3.readline()#读取配置文件中要向PLC寄存器写的数据
file3.close()
while True:
print('waiting pc connection')
tcpCliSock, addr = tcpSerSock.accept()#连接客户端
print('connection to pc:', addr)
while True:
tcpCliSock.setblocking(1)#将数据的接收设为阻塞
data = tcpCliSock.recv(BUFSIZ)#接收客户端数据
tcpCliSock.setblocking(0)#将数据的接收设为非阻塞
if data.decode() == '1':#若收到指令1
data1 = ''
while data1 != b'q':#若没收到指令q
a = master.execute(int(port), cst.READ_HOLDING_REGISTERS, int(start_addr), int(number))#读取PLC寄存器
message=''
if int(number)>1:#将收到的PLC数据转换为指定格式
for i in range(0,int(number)-1):
message = message + str(a[i]) + ','
message = message + str(a[int(number) - 1])
else: message = str(a[0])
tcpCliSock.send(message.encode("utf-8"))#发送收到的PLC寄存器数据
try:
data1 = tcpCliSock.recv(BUFSIZ)#尝试接收客户端数据
except Exception:#没有收到数据则睡眠1s后继续循环
time.sleep(1)
continue
elif data.decode() == '2':#若收到指令2则写PLC寄存器
a = master.execute(int(port), cst.WRITE_SINGLE_REGISTER, int(welche), output_value=int(statistik))
tcpCliSock.close()#断开与客户端的连接