天天看點

一例python實作的基于事件響應方式的序列槽封裝

暫時隻實作序列槽,socket(tcp/udp), http等其他方式的後續加上

open points:

1.不知是否可以在執行個體化時控制序列槽預設為關閉狀态?

2.在序列槽執行個體運作過程中,若要修改序列槽參數,比如波特率或奇偶校驗屬性,是否會線上程類中出現異常?(目前正在研究協程,目測用協程可以歸避此類問題,後續更新…)

CommBase.py

# -*- coding: utf-8 -*-
# @Time    : 2019/4/1
# @Author  : 
# @Email   : 
# @File    : CommBase.py
# @Software:
from serial.rs485 import RS485Settings

class CommBase(object):
    def __init__(self):
        self.cbOnRead = None
    
    def IsOpen(self):
        pass

    def Open(self, settings):
        pass

    def Close(self):
        pass

    def Write(self, sendData):
        pass

    def RegstOnReadEvt(self, callback):
        pass

           

CommSerialPort.py

# -*- coding: utf-8 -*-
'''
Created on 2019��5��21��

@author: fredl
'''
from CommService.comm.CommBase import CommBase
import serial
import threading
import time
from logPrinter.LogPrinter import _LogingInit_,_DEBUG_,_INFO_,_ERROR_

class CommSerialPort(CommBase):
    '''
    classdocs
    '''


    def __init__(self):
        CommBase.__init__(self)
        self.m_serial = None
        self.m_com       = 'COM3'
        self.m_BaudRates = 115200
        self.m_ByteSizes = 8
        self.m_Parities  = 'N'
        self.m_StopBits  = 1
        
        self.serialRecvThread = TSerialRecvThread(None, None)
        self.serialRecvThread.m_pause = True
        self.serialRecvThread.start()

    def IsOpen(self):
        return self.m_serial.is_open

    def Open(self, settings):
        if self.m_serial is not None:
            if self.IsOpen():
                self.Close()
        self.m_serial = serial.Serial(port     = self.m_com,
                                      baudrate = self.m_BaudRates,
                                      bytesize = self.m_ByteSizes,
                                      parity   = self.m_Parities,
                                      stopbits = self.m_StopBits)

        self.serialRecvThread.setSerialInst(self.m_serial)
        self.serialRecvThread.m_pause = False
        return True

    def Close(self):
        self.serialRecvThread.m_pause = True
        #self.serialRecvThread.join()
        if self.m_serial:
            self.m_serial.close()

    def SendData(self, sendData):
        if not self.m_serial:
            return False
        self.m_serial.write(sendData)
        return True

    def RegstOnRead(self, cbEvent):
        self.serialRecvThread.m_cbOnRead = cbEvent

# serial recv thread
class TSerialRecvThread (threading.Thread):
    def __init__(self, serial, callbackOnRead):
        threading.Thread.__init__(self)
        self.m_serialInst = serial
        self.m_cbOnRead   = callbackOnRead
        self.m_toStop     = False
        self.m_pause      = True

    def setSerialInst(self, serialInst):
        self.m_serialInst = serialInst

    def run(self):
        _INFO_('serial recv thread start...')
        self.m_pause = False
        while True:
            try:
                if self.m_toStop == True:
                    _INFO_('serial recv thread is stopped...')
                    break
                if self.m_pause == True:
                    _INFO_('serial recv thread is pause...')
                    time.sleep(1)
                    continue
                if self.m_serialInst == None:
                    print('serial is none...')
                    time.sleep(1)
                    continue
                #check if port is opened
                if not self.m_serialInst.is_open:
                    _INFO_('serial not open!!!')
                    continue
                nRecvCount = self.m_serialInst.inWaiting()
                if nRecvCount:
                    strRecvData = self.m_serialInst.read(nRecvCount)
                    if not self.m_cbOnRead is None:
                        self.m_cbOnRead(strRecvData)
                else:
                    time.sleep(0.1)
            except :
                _ERROR_('serial error!!!')
                break

    def stop(self):
        #_INFO_('serial recv thread will be stopped...')
        self.toStop = True