首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何创建一个pyserial服务?

我如何创建一个pyserial服务?
EN

Stack Overflow用户
提问于 2011-03-10 21:50:51
回答 2查看 2.1K关注 0票数 0

我编写了一个web应用程序,它与/dev/ttyS02 02上的串行设备进行交互。问题是我当前的消息传递和队列解决方案。请阅读下面的内容。

下面是应用程序和pyserial之间的通信桥:

  • 我的web应用程序通过PHP将请求记录插入到d_requests表中的MySQL中。插入记录的处理列设置为0。插入的记录的id保存在$id变量中,PHP应用程序进入循环状态,它将继续使用$id作为查找引用来检查$id列是否=1。
  • 我有一个python服务,它每秒钟检查一次处理后的列= 0的d_requests表中的记录。这被认为是一个新的请求.(参考源代码- python服务)
  • 然后,python服务使用记录的信息通过pyserial连接到端口。
  • 执行请求的操作。然后将记录的处理列更新为1,并更新其他几个字段。这将记录标记为已处理。
  • 然后PHP控制块退出循环(第1点)。并将结果作为json返回给JS application.Where,它将显示给用户。

注意事项的几点

  • 所述串行设备能够每250 ms处理1次请求。
  • python服务每1秒监视d_requests表中处理的列=0的记录。
  • 我的web应用程序与python服务的唯一通信是MySQL。 DB通过在d_requests表中插入请求记录。
  • 我使用PHP块代码来查找请求,每秒钟使用插入的id来检查已处理的列是否已更新为1。

My Concerns

单点故障

当守护进程服务没有运行时,不能发生串行请求。

极限资源使用

我预计每秒对串行设备的请求大约为4-5次。使用当前处理消息的实现,db将超时工作,CPU使用率将很高,因为PHP应用程序和python守护进程/服务将连接并执行DB上的查询,并且请求的处理将出现延迟。

结论:是否有更好的方法来改进我目前的消息传递和排队解决方案?我认为在这种情况下,一个pyserial服务会工作得很好,在这里,串口可以用于例如。连接到网络插座上。host:<7000>和我可以通过PHP向它发送一个请求,然后等待来自web服务的响应。不幸的是,我不知道该怎么做。

有什么想法吗?

谢谢

源代码

python服务

代码语言:javascript
复制
    import sys, time
    from daemon import Daemon
    import MySQLdb 

#Database parameters
config = {"host":"localhost","username":"root","password":"cake","database":"mydb"}

#Check if MySQLdb library is present
try:
    conn = MySQLdb.connect(config['host'],config['username'],config['password'],config['database'])
except MySQLdb.Error, e:
    print "Error %d: %s" % (e.args[o], e.args[1])
    sys.exit(1);

#Check if pyserial library is present
try:
    import serial
except ImportError:
    print "Error,pySerial module not installed"
    sys.exit(1);

#Create DB cursor  
#cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
#Declare global variables here
class MyDaemon(Daemon): 
    def run(self):
        while True:
            time.sleep(2)
            cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
            data = ''
            try:
                cursor.execute ("""SELECT * FROM d_requests where processed = 0""")
                rows=cursor.fetchall()
                print "Waiting for requests..."
            except MySQLdb.Error as detail:
                print "MySQL Error,",detail
            if len(rows) == 0:
                cursor.close()
                print "No request found..."
                continue
            for row in rows:
                try:                
                    print "Processing request..."                   
                    ser = serial.Serial(port=row['port'],
                    baudrate = row['baud'],
                    bytesize = row['bytesize'], #8
                    parity = row['parity'], #serial.PARITY_NONE or N or C
                    stopbits = row['stopbits'], #1
                    timeout = row['wait_for_reply'], #0.5
                    xonxoff = row['sw_flowcontrol'], #0
                    rtscts = row['hw_flowcontrol']) #0                  
                    #Send command to device
                    ser.write(row['request_string'] + "\r")
                    #Read device response                   
                    data = ser.read(100)#TBD:This value needs to be changeable,not always 100 bytes
                    ser.close()
                    print "RESULT : " + data                    
                except (serial.SerialException, AttributeError, NameError) as detail:
                    data = "Error, could not open port"
                    print data                  
                except serial.SerialTimeoutException as detail:
                    data = "Error, port connection timeout" #Error ,detail
                    print data
                except:
                    data = "Error,Unexpected error"
                    print data              
                finally:
                    #ser.close()
                    try:
                        cursor.execute("""UPDATE d_requests SET processed = %s, result_string = %s WHERE id = %s""",(1,data,row['id']))
                    except MySQLdb.Error as detail:
                        print "MySQL Error,",detail
                #cursor.commit() for innoDB table engines
            cursor.close()
if __name__ == "__main__":
    daemon = MyDaemon('/tmp/daemon-example.pid')
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()          
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        elif 'foreground' == sys.argv[1]: #this runs the daemon in the foreground
            daemon.run()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-11 00:11:31

是否有更好的方法来改进我当前的消息传递和队列解决方案?

行!没问题!它们被称为消息队列,它们是非常棒的。

我最喜欢的是吉尔曼,它是由给我们带来memcached的同一个团队编写的。它有PHPPython绑定。它实际上不是消息队列,而是RPC服务。无论如何,它将允许您从一个环境调用方法,并在另一个环境中处理它们。

在本例中,您希望用Python编写串行接口代码,并让它公开它作为Gearman函数可以做的所有事情。它将作为守护进程打开。PHP代码可以通过Gearman调用这些函数。

票数 1
EN

Stack Overflow用户

发布于 2011-08-25 17:35:50

研究类似的需求。到目前为止,"ser2net“和"termnetd”守护进程都很有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5266347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档