Get communication timing and serialization for the crappy paradox board

parent d890ecf6
...@@ -42,8 +42,9 @@ class ParadoxProtocol(BaseProtocol): ...@@ -42,8 +42,9 @@ class ParadoxProtocol(BaseProtocol):
packet=[] packet=[]
queue=[] queue=[]
sendqueue=[]
replyqueue=[]
packettimeout = 0 packettimeout = 0
waitreply = 0
def __init__(self, logger, core): def __init__(self, logger, core):
self.log = logger self.log = logger
...@@ -52,22 +53,64 @@ class ParadoxProtocol(BaseProtocol): ...@@ -52,22 +53,64 @@ class ParadoxProtocol(BaseProtocol):
def _queueData(self): def _queueData(self):
if len(self.packet) >= 37: if len(self.packet) >= 37:
if self.waitreply > 0:
self.waitreply-=1
packet="".join(self.packet[:37]) packet="".join(self.packet[:37])
self.log.debug("MESSAGE QUEUED: "+''.join( [ "\\x%02X" % ord( x ) for x in packet ] ).strip()) #+str(packet).encode("hex")) if p37b.checkSumTest(packet):
print packet self.log.debug("<< MESSAGE QUEUED: "+''.join( [ "\\x%02X" % ord( x ) for x in packet ] ).strip())
self.queue+=[packet] #print packet
self.packet=self.packet[37:] self.queue+=[packet]
self.packet=self.packet[37:]
else:
self.log.debug("Serial message incorrect: shift queue and discard first byte ("+"\\x%02X" % ord( self.packet[0] )+")")
self.packet=self.packet[1:]
reactor.callLater(0, self._queueData) reactor.callLater(0, self._queueData)
reactor.callLater(0, self._processQueue) reactor.callLater(0, self._processQueue)
elif len(self.packet) > 0: elif len(self.packet) > 0:
self.packettimeout = time.time() self.packettimeout = time.time()
def _queueSendData(self, data, callback=False):
self.sendqueue+=[{'msg': data, 'cb': callback, 'try': 3}]
reactor.callLater(0, self._processSendQueue)
def _processQueue(self): def _processQueue(self):
pass if len(self.queue) > 0:
if p37b.checkCmd(ord(self.queue[0][0]), p37b.CMD_EVENT):
reactor.callLater(0, self._processEvent, self.queue[0])
else:
if len(self.replyqueue) > 0:
# XXX Can we check in some way if is the *RIGHT* reply?
# in theory we don't need it as we will not send anything
# until the reply is received, but it would be more error
# prone that way...
if self.replyqueue[0]['cb'] and callable(self.replyqueue[0]['cb']):
reactor.callLater(0, self.replyqueue[0]['cb'], self.queue[0])
del self.replyqueue[0]
del self.queue[0]
def _processSendQueue(self, addToReplyQueue=True):
if len(self.sendqueue) > 0:
if not len(self.replyqueue) or (not addToReplyQueue and len(self.replyqueue) > 0):
packet = self.sendqueue[0]['msg']
if addToReplyQueue:
self.replyqueue+=[self.sendqueue[0]]
del self.sendqueue[0]
self.log.debug(">> SEND MESSAGE: "+''.join( [ "\\x%02X" % ord( x ) for x in packet ] ).strip())
self.transport.write(packet)
reactor.callLater(.5, self._checkReplies)
else:
reactor.callLater(.1, self._processSendQueue)
def _checkReplies(self):
if len(self.replyqueue) > 0:
# Is there a reply waiting? why?
if self.replyqueue[0]['try'] > 0:
self.replyqueue[0]['try']-=1
self.sendqueue+=[self.replyqueue[0]]
reactor.callLater(0, self._processSendQueue, False)
else:
self.log.error("FAILED TO SEND MESSAGE: "+''.join( [ "\\x%02X" % ord( x ) for x in self.replyqueue[0]['msg'] ] ).strip())
del self.sendqueue[0]
def dataReceived(self, data): def dataReceived(self, data):
if len(self.packet) > 0 and (time.time()-self.packettimeout) > PKTTIMEOUT: if len(self.packet) > 0 and (time.time()-self.packettimeout) > PKTTIMEOUT:
self.log.debug("Serial Timeout: discard packet "+''.join( [ "\\x%02X" % ord( x ) for x in self.packet ] ).strip()) self.log.debug("Serial Timeout: discard packet "+''.join( [ "\\x%02X" % ord( x ) for x in self.packet ] ).strip())
...@@ -78,31 +121,31 @@ class ParadoxProtocol(BaseProtocol): ...@@ -78,31 +121,31 @@ class ParadoxProtocol(BaseProtocol):
def connectionMade(self): def connectionMade(self):
self.log.info("Serial port correctly connected") self.log.info("Serial port correctly connected")
self.login() self.connect()
def _terminating(self, *a, **kw): def _terminating(self, *a, **kw):
self.log.debug("Send Disconnect message") self.log.debug("Send Disconnect message")
self.write(p37b.MSG_DISCONNECT) self.write(p37b.MSG_DISCONNECT)
self.transport.loseConnection()
def connectionLost(self, reason): def connectionLost(self, reason):
self.log.debug("Connection lost for "+str(reason)) self.log.debug("Connection lost for "+str(reason))
def login(self): def connect(self):
self.write(p37b.MSG_LOGIN) self.write(p37b.MSG_CONNECT)
self.write(p37b.MSG_GETSTATUS)
self.write(p37b.MSG_SYNC, self._replySync)
message = '\x50\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' def write(self, message, reply_callback=False):
self.write(message) self._queueSendData(p37b.format37ByteMessage(message), reply_callback)
message = '\x5f\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' def _replySync(self, reply):
self.write(message) self.log.debug("REPLY SYNC RECEIVED")
self.write(reply)
def write(self, message): def _processEvent(self, event):
if self.waitreply == 0: pass
self.transport.write(p37b.format37ByteMessage(message))
self.waitreply+=1
else:
reactor.callLater(0, self.write, message)
class Paradox(object): class Paradox(object):
implements(IPlugin, imodules.IModules) implements(IPlugin, imodules.IModules)
......
...@@ -113,9 +113,11 @@ def checkCmd(byte, cmd): ...@@ -113,9 +113,11 @@ def checkCmd(byte, cmd):
# To save computational timing there is no need to format those messages # To save computational timing there is no need to format those messages
# at runtime, as they are static, so, full string included here. # at runtime, as they are static, so, full string included here.
MSG_LOGIN= '\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' MSG_CONNECT= '\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x72'
MSG_DISCONNECT= '\x70\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x76' MSG_DISCONNECT= '\x70\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x76'
MSG_GETSTATUS= '\x50\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD0'
MSG_GETALARMSTATUS= '\x50\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD1'
MSG_SYNC= '\x5F\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment