[记录]python使用serial模块实现实时WebConsole
###tornado+websocket+多进程实现:
1.index.html
<!DOCTYPE HTML>
<html>
<head>
<style>
body { margin: 0px; padding: 20px; }
#received { width: 500px; height: 400px; border: 1px solid #dedede; overflow-y:scroll;}
#sent { width: 500px; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="static/main.js"></script>
</head>
<body>
<h1>Websockets serial console</h1> <p>Data received from serial port</p>
<div id="received">
</div>
<button id="clear">Clear</button> <p>Send data to serial port</p>
<form id="sent">
<input type="text" id="cmd_value">
<button id="cmd_send">Send</button>
</form>
</body>
</html>
2.main.js
$(document).ready(function(){ var received = $('#received'); var socket = new WebSocket("ws://localhost:8080/ws"); socket.onopen = function(){
console.log("connected");
}; socket.onmessage = function (message) {
console.log("receiving: " + message.data);
received.append(message.data);
received.append($('<br/>'));
}; socket.onclose = function(){
console.log("disconnected");
}; var sendMessage = function(message) {
console.log("sending:" + message.data);
socket.send(message.data);
}; // GUI Stuff // send a command to the serial port
$("#cmd_send").click(function(ev){
ev.preventDefault();
var cmd = $('#cmd_value').val();
sendMessage({ 'data' : cmd});
$('#cmd_value').val("");
}); $('#clear').click(function(){
received.empty();
}); });
3.serialworker.py
import serial
import time
import multiprocessing ## Change this to match your local settings
SERIAL_PORT = '/dev/ttyACM0'
SERIAL_BAUDRATE = 115200 class SerialProcess(multiprocessing.Process): def __init__(self, input_queue, output_queue):
multiprocessing.Process.__init__(self)
self.input_queue = input_queue
self.output_queue = output_queue
self.sp = serial.Serial(SERIAL_PORT, SERIAL_BAUDRATE, timeout=1) def close(self):
self.sp.close() def writeSerial(self, data):
self.sp.write(data)
# time.sleep(1) def readSerial(self):
return self.sp.readline().replace("\n", "") def run(self): self.sp.flushInput() while True:
# look for incoming tornado request
if not self.input_queue.empty():
data = self.input_queue.get() # send it to the serial device
self.writeSerial(data)
print "writing to serial: " + data # look for incoming serial data
if (self.sp.inWaiting() > 0):
data = self.readSerial()
print "reading from serial: " + data
# send it back to tornado
self.output_queue.put(data)
4.server.py
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.websocket
import tornado.gen
from tornado.options import define, options
import os
import time
import multiprocessing
import serialworker
import json define("port", default=8080, help="run on the given port", type=int) clients = [] input_queue = multiprocessing.Queue()
output_queue = multiprocessing.Queue() class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html') class StaticFileHandler(tornado.web.RequestHandler):
def get(self):
self.render('main.js') class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print 'new connection'
clients.append(self)
self.write_message("connected") def on_message(self, message):
print 'tornado received from client: %s' % json.dumps(message)
#self.write_message('ack')
input_queue.put(message) def on_close(self):
print 'connection closed'
clients.remove(self) ## check the queue for pending messages, and rely that to all connected clients
def checkQueue():
if not output_queue.empty():
message = output_queue.get()
for c in clients:
c.write_message(message) if __name__ == '__main__':
## start the serial worker in background (as a deamon)
sp = serialworker.SerialProcess(input_queue, output_queue)
sp.daemon = True
sp.start()
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[
(r"/", IndexHandler),
(r"/static/(.*)", tornado.web.StaticFileHandler, {'path': './'}),
(r"/ws", WebSocketHandler)
]
)
httpServer = tornado.httpserver.HTTPServer(app)
httpServer.listen(options.port)
print "Listening on port:", options.port mainLoop = tornado.ioloop.IOLoop.instance()
## adjust the scheduler_interval according to the frames sent by the serial port
scheduler_interval = 100
scheduler = tornado.ioloop.PeriodicCallback(checkQueue, scheduler_interval, io_loop = mainLoop)
scheduler.start()
mainLoop.start()
5.扩展:每个页面用户登录时生成一个唯一的key,用户绑定该用户该会话的操作,在进行操作时,把这个key也传给server端的input队列,然后在serialworker的run循环中对data数据进行处理,在self.output_queue.put(data)操作是又带上这个key,然后返回,server中checkQueue方法执行是只发给这个key的会话,然后前端显示结果。这样来实现每个会话信息互不干扰。如果不用key做标记,那么所有会话操作的信息,所有会话之间都能看到。同时,serial是否可以和os.openpty()结合,实现serial操作新建的伪终端来实现shell终端操作模式。linux的pty创建是成对出现的,一个主,一个从,执行命令的时一个写,另一个读。一般是配合subprocess来指定STDOUT=slave,这样执行命令之后把结果写到slave,然后从master读取后再前端显示。pty创建简单代码如下:
#!/usr/bin/python
# -*- coding: UTF-8 -*- import os,sys,time
import serial # 主 pty, 从 tty
master, slave = os.openpty() print master
print slave # 显示终端名
slave_name = os.ttyname(slave)
print master
print slave_name ser = serial.Serial(slave_name, rtscts=True, dsrdtr=True)
print "Open port successful! the port information:"
print ser
print "\n" while ser.isOpen(): #the return is True or Faulse
print "please write the msg(exit to break)"
msg = raw_input(">") #add a break reason:::kill the child thread
if msg == 'exit':
print "\n"
print "Please waiting to close the connection......"
time.sleep(1)
break;
msg = msg + '\r' + '\n' #AT form define #data=ser.write(msg)
os.write(master, msg)
sys.stdout.flush() #flush the buffer
print "\n"
print ("waiting to recv the data...")
time.sleep(2)
msg_recv = os.read(slave, 128)
print ("\n")
print ("\tOK! The recv msg is %s"%(msg_recv))
创建伪终端通信简图:
[记录]python使用serial模块实现实时WebConsole的更多相关文章
- python记录_day23 正则表达式 re模块
一. 正则表达式 使用python的re模块之前应该对正则表达式有一定的了解 正则表达式是对字符串操作的一种逻辑公式.我们一般使用正则表达式对字符串进行匹配和过滤. 正则的优缺点: 优点:灵活, 功能 ...
- python serial模块使用,是pyserial而非serial
import serial from serial.tools.list_ports import comports 运行这两句时分别遇到错误 第一个先提示 no module name of ser ...
- python之路 模块,序列化,迭代器,生成器
一.模块 1.模块简介 模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py.模块可以被别的程序引入,以使用该模块中的函数等功能.这也是使用python标准库的方法. 类似于函数式编程和面向过 ...
- python 3 serial module install
/************************************************************************* * python 3 serial module ...
- python 之serial、pyusb 使用开发
说明:本次是在windows 系统操作实现的. serial 使用场景,获取得力扫码枪的扫码数据,该扫码枪支持三种通讯接口设置,如下图 即插即用的是 USB-KBW功能,插上去即可获取扫码数据,第二种 ...
- python的库有多少个?python有多少个模块?
这里列举了大概500个左右的库: ! Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主 ...
- 学习PYTHON之路, DAY 6 - PYTHON 基础 6 (模块)
一 安装,导入模块 安装: pip3 install 模块名称 导入: import module from module.xx.xx import xx from module.xx.xx impo ...
- Python之logging模块
一.引言 之前在写一些小程序的时候想把日志内容打到文件中,所以就自己写了一个logger.py的程序,如下: #!/usr/bin/python # -*- coding=utf-8 -*- impo ...
- Python 利用pytesser模块识别图像文字
使用的是python的pytesser模块,原先想做的是图片中文识别,搞了一段时间了,在中文的识别上还是有很多问题,这里做记录分享. pytesser,OCR in Python using the ...
随机推荐
- Java底层知识学习:Bytecode and JMM
最近在跟着耗子哥的程序员练级指南学习Java底层知识,结合<深入理解Java虚拟机>这本书在看,写笔记,看资料,成长中…… 目前看完了第二章JMM和各内存区OOM的情况 一篇图文并茂介绍字 ...
- ORACLE 11.2.0.4 安装在 rhel6 上
. 修改host文件,添加本机的host记录 [root@RACDG ~]# vi /etc/hosts 127.0.0.1 localhost localhost.localdomain local ...
- 一个Demo让你掌握Android所有控件
原文:一个Demo让你掌握Android所有控件 本文是转载收藏,侵删,出处:"安卓巴士" 下面给出实现各个组件的源代码: 1.下拉框实现--Spinner packag ...
- GNU自动化工具使用全过程详解,以及在线手册
[root@localhost test3]# cat add.h#ifndef _ADD_H_#define _ADD_H_ extern int add(int, int); #endif [ro ...
- 京东sdk商家上架接口调用问题总结
前言: 最近在做商家发布产品,调用京东sdk,发现问题很多,而且还是在我同事的帮助下完成的,摸索中,菜鸟还请高手门多多提携才好,入正题 首先是引用jd的sdk啦,京东sdk中发布商品需要调用一个 36 ...
- python中的基本数据类型之 int bool str
一.基本数据类型 1. int ==> 整数.主要用来进行数学运算. 2.str ==> 字符串.可以保存少量的数据,并进行相应的操作. 3.bool => 布尔值.判断 ...
- jvm(4)---垃圾回收(哪些对象可以被回收)
1.java堆中几乎放着所有对象的实例,那么什么样子的对象才是可以被回收的呢? 1.1.引用计数法: 给对象添加一个引用计数器,当有地方引用的时候,计数器就+1,引用失效就-1:任何时候当计数器为0, ...
- 系统学习 Java IO (八)----装饰流 FilterInputStream/FilterOutputStream
目录:系统学习 Java IO---- 目录,概览 这两个流的作用是:"封装其它的输入流,并为它们提供额外的功能" 他们的直接子类有: BufferedInputStream 的作 ...
- MagicBook屏幕频闪解决方案(Windows、MacOS)
对于已经看到这篇文章的小伙伴们,就不解释何为PWM调光频闪了. MagicBook笔记本性价比高,但屏幕素质确实很一般,我们人眼看不出来的频闪,实际对眼睛损害很大,如图(需要设置快门参数,如1/400 ...
- 并发编程-concurrent指南-线程池ExecutorService的实例
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...