Ich habe eine Beaglebone Black Verbindung zu einem CAN-Bus-Geräte: Batterie.Wie man mehrere Ioloop in Tornado benutzt und Daten zwischen den Ioloop (s) teilt?
Ein Tornado Web läuft auf Beaglebone Black als GUI.
CAN-Bus-Leseschleife halten Lesen von Daten von CAN-Bus den Status der Batterie Instanz zu aktualisieren
Aber wie kann ich die beiden IOLOOP machen zusammen arbeiten und Batterie Instanz teilen?
Tornado web:
class Battery(object):
status = {}
class API_Handler(web.RequestHandler):
def get(self, dev, cmd):
if cmd == 'data':
self.write(self.application.battery0.status)
class Application(web.Application):
def __init__(self):
self.battery0 = Battery('bat0')
routing = [
(r'/api/battery/(data|)', API_Handler),
]
settings = {
'template_path': os.path.join(os.path.dirname(__file__), "templates"),
'static_path': os.path.join(os.path.dirname(__file__), "static"),
}
web.Application.__init__(self, routing, debug=True, **settings)
if __name__ == "__main__":
import tornado
app = Application()
app.listen(address='0.0.0.0', port=8888)
tornado.ioloop.IOLoop.instance().start()
CAN-Bus-Leseschleife, Code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import errno
import functools
import tornado.ioloop
import socket
import struct
can_frame_fmt = "=IB3x8s"
can_frame_size = struct.calcsize(can_frame_fmt)
def build_can_frame(can_id, data):
can_dlc = len(data)
data = data.ljust(8, b'\x00')
return struct.pack(can_frame_fmt, can_id, can_dlc, data)
def dissect_can_frame(frame):
can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
return (can_id, can_dlc, data[:can_dlc])
def connection_ready(sock, fd, events):
while True:
try:
cf, addr = sock.recvfrom(can_frame_size)
except socket.error as e:
if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
raise
return
dissect_can_frame(cf)
if __name__ == '__main__':
sock = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
sock.bind(('can0',))
sock.setblocking(0)
io_loop = tornado.ioloop.IOLoop.current()
callback = functools.partial(connection_ready, sock)
io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
io_loop.start()
Wenn Sie Tornado verwenden, das in der Lage ist [WebSockets] (https://en.wikipedia.org/wiki/WebSocket), warum der Benutzer senden hat ein Befehl um einen Status zu bekommen? Sie müssen nur einen Thread starten, der den Batteriestatus mit der angegebenen Häufigkeit liest und den Browser automatisch über eine Websocket-Verbindung aktualisiert. – yegorich
@yegorich Ich kenne Ihre Bedenken. aber das ist nur ein Beispiel für cmd. Ich habe viele andere von cmd auch. Ein weiterer Grund ist, dass die Daten innerhalb von Änderungen viel häufiger sind, aber die GUI nicht als die gleiche Häufigkeit aktualisiert werden muss. Der dritte Grund ist, dass andere Module, die dieselbe API verwenden, Daten in ihrer eigenen Häufigkeit anfordern können. –