Autodetect board and start name mapping

parent db47e3f7
###########################################################################
# Copyright (c) 2018- Franco (nextime) Lanza <franco@nexlab.it>
#
# Penguidom System client Daemon "penguidomd" [https://git.nexlab.net/domotika/Penguidom]
#
# This file is part of penguidom.
#
# penguidom is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from nexlibs.singleton import Singleton
class ParadoxEventMap(Singleton):
eventMap = {}
def __init__(self, *args, **kwargs):
Singleton.__init__( self )
def loadEvents(self, eventmap):
self.eventMap = eventmap
def getEventGroupDescription(self, eg):
try:
return self.eventMap.eventGroupMap[eg]
except KeyError:
print "No ParadoxMap for: eg=%d"%(eg)
return "-"
def getSubEventGroupDescription(self, eg, seg):
try:
return self.eventMap.subEventGroupMap[eg][seg]
except KeyError:
print "No ParadoxMap for: eg=%d \t seg=%d"%(eg,seg)
return "-"
def getEventDescription(self, eg, seg):
try:
return self.eventMap.eventGroupMap[eg], self.eventMap.subEventGroupMap[eg][seg]
except KeyError:
print "No ParadoxMap for: eg=%d \t seg=%d" % (eg, seg)
return "-"
def getLabelTypeDescription(self, lt):
return self.eventMap.labelTypeMap[lt]
def setzoneLabel(self, number, value):
self.eventMap._zoneLabel.update({number: value})
return
def getzoneLabel(self, number):
value = self.eventMap._zoneLabel[number]
return value
def getAllzoneLabel(self):
return self.eventMap._zoneLabel
def setuserLabel(self, number, value):
self.eventMap._userLabel.update({number: value})
return
def getAlluserLabel(self):
return self.eventMap._userLabel
def setpartitionLabel(self, number, value):
self.eventMap._partitionLabel.update({number: value})
return
def getAllpartitionLabel(self):
return self.eventMap._partitionLabel
def setbusModuleLabel(self, number, value):
self.eventMap._busModuleLabel.update({number: value})
return
def getbusModuleLabel(self, number):
value = self.eventMap._busModuleLabel[number]
return value
def getAllbusModuleLabel(self):
return self.eventMap._busModuleLabel
def setwirelessRepeaterLabel(self, number, value):
self.eventMap._wirelessRepeater.update({number: value})
return
def getwirelessRepeaterLabel(self, number):
value = self.eventMap._wirelessRepeater[number]
return value
def getAllwirelessRepeaterLabel(self):
return self.eventMap._wirelessRepeater
def setwirelessKeypadLabel(self, number, value):
self.eventMap._wirelessKeypad.update({number: value})
return
def getwirelessKeypadLabel(self, number):
value = self.eventMap._wirelessKeypad[number]
return value
def getAllwirelessKeypadLabel(self):
return self.eventMap._wirelessKeypad
def setsiteNameLabel(self, number, value):
self.eventMap._siteNameLabel.update({number: value})
return
def setwirelessSirenLabel(self, number, value):
self.eventMap._wirelessSiren.update({number: value})
return
def getwirelessSirenLabel(self, number):
value = self.eventMap._wirelessSiren[number]
return value
def getAllwirelessSirenLabel(self):
return self.eventMap._wirelessSiren
def setoutputLabel(self, number, value):
self.eventMap._outputLabel.update({number: value})
return
def getoutputLabel(self, number):
value = self.eventMap._outputLabel[number]
return value
def getAlloutputLabel(self):
return self.eventMap._outputLabel
class ParadoxRegisters(Singleton):
registers = {}
def __init__(self, *args, **kwargs):
Singleton.__init__( self )
def loadRegisters(self, register):
self.registers = register
def getzoneLabelRegister(self):
return self.registers.zoneLabel
def getpartitionLabelRegister():
return self.registers.partitionLabel
def getuserLabelRegister(self):
return self.registers.userLabel
def getbusModuleLabelRegister(self):
return self.registers.busModuleLabel
def getwirelessRepeaterLabelRegister(self):
return self.registers.wirelessRepeaterLabel
def getwirelessKeypadLabelRegister(self):
return self.registers.wirelessKeypadLabel
def getsiteNameLabelRegister(self):
return self.registers.siteNameLabel
def getwirelessSirenLabelRegister(self):
return self.registers.wirelessSirenLabel
def getoutputLabelRegister(self):
return self.registers.outputLabel
def getcontrolOutputRegister(self):
return self.registers.controlOutput
def getsupportedItems(self):
return self.registers.supportedItems
def getParadoxEventMap():
return ParadoxEventMap.getInstance()
def getParadoxRegisters():
return ParadoxRegisters.getInstance()
EVENTMAP = getParadoxEventMap()
REGISTERS = getParadoxRegisters()
This diff is collapsed.
...@@ -29,15 +29,20 @@ from twisted.internet.protocol import BaseProtocol, Protocol, Factory ...@@ -29,15 +29,20 @@ from twisted.internet.protocol import BaseProtocol, Protocol, Factory
from twisted.internet import reactor, tcp from twisted.internet import reactor, tcp
from nexlibs.utils import genutils from nexlibs.utils import genutils
from importlib import import_module
import serial import serial
import time import time
import paradox37b as p37b import paradox37b as p37b
from mapping import EVENTMAP, REGISTERS
SERIAL_PORT="/dev/ttyS0" SERIAL_PORT="/dev/ttyS0"
BAUDRATE=9600 BAUDRATE=9600
PKTTIMEOUT=2 # Seconds PKTTIMEOUT=2 # Seconds
REPLYTIMEOUT=1 # Seconds REPLYTIMEOUT=1 # Seconds
BOARDTYPE="MG5050" # Just a default
class ParadoxProtocol(BaseProtocol): class ParadoxProtocol(BaseProtocol):
...@@ -48,12 +53,21 @@ class ParadoxProtocol(BaseProtocol): ...@@ -48,12 +53,21 @@ class ParadoxProtocol(BaseProtocol):
replyqueue=[] replyqueue=[]
packettimeout = 0 packettimeout = 0
proxy = False proxy = False
zonemap = False
def __init__(self, logger, core, cfg): def __init__(self, logger, core, cfg):
self.log = logger self.log = logger
self.core = core self.core = core
self.cfg = cfg self.cfg = cfg
self.log.debug(str(self.cfg)) self.log.debug(str(self.cfg))
try:
self.proxyonly = genutils.isTrue(self.cfg.get('connection', 'proxyonly'))
self.mapnames = genutils.isTrue(self.cfg.get('panel', 'mapNames'))
self.autodetect = genutils.isTrue(self.cfg.get('panel', 'autodetect'))
except:
self.proxyonly = False
self.mapnames = False
self.autodetect = False
reactor.addSystemEventTrigger('before', 'shutdown', self._terminating) reactor.addSystemEventTrigger('before', 'shutdown', self._terminating)
def _queueData(self): def _queueData(self):
...@@ -161,8 +175,8 @@ class ParadoxProtocol(BaseProtocol): ...@@ -161,8 +175,8 @@ class ParadoxProtocol(BaseProtocol):
self.log.debug("Connection lost for "+str(reason)) self.log.debug("Connection lost for "+str(reason))
def connect(self): def connect(self):
if not genutils.isTrue(self.cfg.get('connection', 'proxyonly')): if not self.proxyonly:
self.write(p37b.MSG_CONNECT, expected_reply=p37b.REPLY_CONNECT) self.write(p37b.MSG_CONNECT, self._detectBoard, expected_reply=p37b.REPLY_CONNECT)
self.write(p37b.MSG_GETSTATUS, expected_reply=p37b.REPLY_GETSTATUS) self.write(p37b.MSG_GETSTATUS, expected_reply=p37b.REPLY_GETSTATUS)
self.write(p37b.MSG_SYNC, self._replySync, expected_reply=p37b.REPLY_SYNC) self.write(p37b.MSG_SYNC, self._replySync, expected_reply=p37b.REPLY_SYNC)
...@@ -182,17 +196,36 @@ class ParadoxProtocol(BaseProtocol): ...@@ -182,17 +196,36 @@ class ParadoxProtocol(BaseProtocol):
# but they seems to be needed for the initial handshake # but they seems to be needed for the initial handshake
# when connecting. So, we just send both, hope # when connecting. So, we just send both, hope
# sometime i will fully understand what they do exactly. # sometime i will fully understand what they do exactly.
#
# After the end of the handshake we proceed to map zone names,
# so, callback for last message drive the runflow in that direction.
self.write(p37b.MSG_UNKWNOWN_HS1) self.write(p37b.MSG_UNKWNOWN_HS1)
self.write(p37b.MSG_UNKWNOWN_HS2, self.mapNames) self.write(p37b.MSG_UNKWNOWN_HS2, self.mapNames)
def _detectBoard(self, reply):
board = p37b.getPanelName(reply)
self.log.info('Detected Panel Board as '+board)
if self.autodetect:
try:
self.log.info("Autoload panel board mapping for "+str(board))
maps = import_module("penguidom.plugins.paradox.panels."+str(board))
EVENTMAP.loadEvents(maps.EventMap())
REGISTERS.loadRegisters(maps.Registers())
self.log.info("Panel board mapping for "+str(board)+" loaded successfully")
except:
self.log.error("Cannot autoload board mapping for "+str(board))
def _processEvent(self, event): def _processEvent(self, event):
pass pass
def mapNames(self, reply=None): def mapNames(self, reply=None):
if genutils.isTrue(self.cfg.get('connection', 'mapNames')): if self.mapnames:
pass self.log.info("Start Mapping names...")
self.log.info("Supported Items:")
for i in REGISTERS.getsupportedItems():
self.log.info(" "+i)
...@@ -271,7 +304,17 @@ class Paradox(object): ...@@ -271,7 +304,17 @@ class Paradox(object):
self.log.debug("TCP Port "+str(tcpport)+" OPEN") self.log.debug("TCP Port "+str(tcpport)+" OPEN")
port = tcp.Port(int(tcpport), self.proxy, 50, self.cfg.get("connection", "tcpaddr"), reactor) port = tcp.Port(int(tcpport), self.proxy, 50, self.cfg.get("connection", "tcpaddr"), reactor)
port.startListening() port.startListening()
try:
defboard = self.cfg.get("panel", "paneltype")
except:
defboard = BOARDTYPE
try:
maps = import_module("penguidom.plugins.paradox.panels."+str(defboard))
EVENTMAP.loadEvents(maps.EventMap())
REGISTERS.loadRegisters(maps.Registers())
self.log.info("Loaded registers and event mapping for default panel type "+str(defboard))
except:
self.log.error("Cannot import panel mapping for panel type "+str(defboard))
logger.info("Plugin initialized") logger.info("Plugin initialized")
......
...@@ -145,3 +145,8 @@ def format37ByteMessage(message): ...@@ -145,3 +145,8 @@ def format37ByteMessage(message):
message += checkSumCalc(message) # Add check to end of message message += checkSumCalc(message) # Add check to end of message
return message return message
def getPanelName(message):
return str(message[28:36]).strip('\x00')
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