Python 和三菱FX5U 进行通信

三菱FX5U 支持SMTP 协议,可利用Python 的Socket 通信按照三菱的协议格式进行通信,上位机作为客户端,PLC作为服务器

"""
author: alai
date:2018/05/01
"""

import socket
import time
import xlwt,xlrd,struct
from xlutils.copy import copy
import sys
import re,os,sys

data="ok"

           
class TcpThread(QThread):

    trigger = pyqtSignal(str)
    trigger1=pyqtSignal(str)

    def __int__(self):
        super(TcpThread, self).__init__()

    # 分离出一个函数用于循环tcp 重连

    def doConnect(self):
        with open('IP_Address.txt', 'r')as fn:
            s1 = fn.read()
        host = ''.join(re.findall(r'IP:(.*)', s1))  # 服务器IP地址取出来,并转成字符串
        port = int(''.join(re.findall(r'PORT:(.*)', s1)))  # 从文本中提取端口号转成整数
        BUFFSIZE = int(''.join(re.findall(r'BUFFSIZE:(.*)', s1)))  # 从文本中提取字符长度转整数
        ADDRESS = (''.join(re.findall(r'ADDRESS:(.*)', s1)))  # 从文本中提取字符长度转整数
        LENGTH = (''.join(re.findall(r'LENGTH:(.*)', s1)))  # 从文本中提取字符长度转整数
        print(host,port,ADDRESS,LENGTH)

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((host, port))
            print("connect is ok")
        except:
            print('fail to setup socket connection')
        return sock, BUFFSIZE,ADDRESS,LENGTH

    # 发送数据

    def tcpClient(self):
        global glb_tag
        glb_tag=0
        global glb_data

        sockLocal, BUFFSIZE,ADDRESS,LENGTH = self.doConnect()


        while True:

            # 等于0,那么一直查询
            if glb_tag==0:
                self.data1 = '500000FF03FF000018000004010000D*00'

                self.data = self.data1+ADDRESS+LENGTH
                # print(self.data)


                try:
                    sockLocal.send(self.data.encode())
                except socket.error:
                    print("\r\nsocket error,do reconnect ")
                    sockLocal.close()
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()
                except:
                    sockLocal.close()
                    print("other error")
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()

                time.sleep(0.5)
                str1 = sockLocal.recv(BUFFSIZE).decode()


                if str1[22:26]=="0001":

                    glb_tag=1
            # 等于1,写入并等待结果

            elif glb_tag==1:
                # 发射信号,连接到datadisplay

                self.trigger.emit(str1)

                self.data1 = '500000FF03FF00001C000014010000D*00499900010001'
                try:
                    sockLocal.send(self.data1.encode())

                except socket.error:
                    print("\r\nsocket error,do reconnect ")
                    sockLocal.close()
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()
                except:
                    sockLocal.close()
                    print("other error")
                    time.sleep(1)

                    sockLocal, BUFFSIZE = self.doConnect()

                time.sleep(0.3)
                str1 = sockLocal.recv(BUFFSIZE).decode()
                # print(glb_str1[16:18])
                # 如果返回的数据长度是对应长度,那么不再写
                if str1[16:18]=="04":
                    glb_tag = 0
            # 等于2,PLC 数据查询
            elif glb_tag==2:
                self.data1='500000FF03FF000018000004010000D*00'
                # 先转成字符串,然后填满四位
                self.data2=("".join(re.findall("[D|d](\d+)",glb_data)))
                self.data3=self.data2.zfill(4)
                # print(glb_data+str(12))
                # print(self.data2)
                self.data=self.data1+self.data3+"0010"
                # print(self.data)

                try:
                    sockLocal.send(self.data.encode())

                except socket.error:
                    print("\r\nsocket error,do reconnect ")
                    sockLocal.close()
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()
                except:
                    sockLocal.close()
                    print("other error")
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()


                time.sleep(0.3)
                glb_tag = 0
                str1 = sockLocal.recv(BUFFSIZE).decode()
                # print(glb_str1)
                self.trigger1.emit(str1)
            #     PLC数据写入
            elif glb_tag==3:
                # print("li")
                self.data1='500000FF03FF00001C000014010000D*00'
                # 先转成字符串,然后填满四位
                self.data2=("".join(re.findall("(\d+)=",glb_data))).zfill(4)
                self.data3=("".join(re.findall("=(\d+)",glb_data))).zfill(4)
                # print(hex(int(self.data3)))
                # 先转成16进制,然后匹配出来,舍掉0x,然后转成字符串,然后填满0
                self.data4=("".join(re.findall("0x(\w+)",hex(int(self.data3))))).zfill(4)

                self.data=self.data1+self.data2+"0001"+self.data4
                # print(self.data)

                try:
                    sockLocal.send(self.data.encode())

                except socket.error:
                    print("\r\nsocket error,do reconnect ")
                    sockLocal.close()
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()
                except:
                    sockLocal.close()
                    print("other error")
                    time.sleep(1)
                    sockLocal, BUFFSIZE = self.doConnect()


                time.sleep(0.3)
                str1 = sockLocal.recv(BUFFSIZE).decode()
                glb_tag = 2
                # glb_str1 = sockLocal.recv(BUFFSIZE).decode()


    def run(self):
        #必须从run开始启动程序

        # global data


        self.tcpClient()

 

你可能感兴趣的:(Python 和三菱FX5U 进行通信)