2

次のプロトコル クラスを使用して、RFID シリアル接続からのデータを読み取って解析しています。接続は、pyserial を使用して読み取った内容を吐き出すだけで正常に機能します。twisted には、複数のエントリを読み取る際に問題があるようです。テスト アカウントの 1 つをスキャンすると、そこで停止します。

ここが紛らわしい部分です - 一貫性がありません。期待どおりに動作することもありますが、ほとんどの場合はそうではありません。ここで何が間違っていますか?

import time, sys

from twisted.internet import reactor, fdesc
from twisted.python import usage, log
from twisted.protocols.basic import LineReceiver
from twisted.internet.serialport import SerialPort
from twisted.web.server import Site
from twisted.web.static import File

from autobahn.websocket import listenWS
from autobahn.wamp import WampServerFactory, WampServerProtocol, exportRpc

test_people = [
    ('8400346926', 'Mary Jones', 'http://placehold.it/150x150&text=Mary+Jones'),
    ('6500129A82', 'Bob Smith', 'http://placehold.it/150x150&text=Bob+Smith'),
]

class ReaderProtocol(LineReceiver):

    t, n, first_pass_time = 0, 0, 0
    first_pass, line, _read_cache, __buffer = None, None, (None, None), ''

    def __init__(self, wsFactory):
        log.msg("Connected to wsfactory %s" % str(wsFactory))
        self.t = time.time()
        self.wsFactory = wsFactory
        self.__buffer = ''

    def connectionMade(self):
        log.msg("Connected to serial port")

    def find_person(self, id):
        for p in test_people:
            if p[0] == id:
                return p

    def dataReceived(self, data):
        stripped_data = data.decode('utf-8').strip()
        if len(stripped_data) == 7:
            self.__buffer = stripped_data
        elif len(stripped_data) == 3 and len(self.__buffer) == 7:
            d = self.__buffer + stripped_data
            self.__buffer = ''
            if len(d) == 10:
                return self.lineReceived(d)
            else:
                log.msg("Incorrect data size. Resetting buffer.")
        else:
            self.__buffer = ''
            log.msg("Incorrect frame size.")
        return

    def lineReceived(self, line):
        i = line.decode('utf-8').strip()
        self.n = time.time()
        if not self.first_pass:
            self.first_pass = i
            self.first_pass_time = time.time()
            self.logLogin(i)
        elif time.time() - self.first_pass_time > 1.5: # make sure past 1.5 seconds
            self.first_pass = i
            self.first_pass_time = time.time()
        else:
            # Make sure that it's not just noise
            if self.first_pass_time > 0 and self.n - self.first_pass_time < 1.5: # not noise
                self.first_pass = None
                self.first_pass_time = 0
                self.logLogin(i)
            else:
                self.__buffer = ''
        return

    def logLogin(self, code):
        f = code != self._read_cache[0] or self._read_cache[1] + 30 <= self.n
        if self.n > self.t + 1.5 and f:
            info = self.find_person(code)
            if info:
                log.msg("ID: %s - Name: %s - Image URL: %s" % (info[0], info[1], info[2]))
                j = "%s|%s|%s" % (info[0], info[1], info[2])
                self.wsFactory.dispatch("http://example.com/serial#login", j)
                self.t = self.n
            else:
                self.wsFactory.dispatch("http://example.com/serial#error", "Unable to find this person.")
            self._read_cache = (code, self.n)
        else:
            pass # this can be safely ignored
        return
4

0 に答える 0