Paradox plugin config and mappings structure

parent 1956846e
[connection]
port: /dev/ttyUSB0
baudrate: 9600
[panel]
autodetect: yes
paneltype: MG5050
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Copyright (c) 2011-2014 Unixmedia S.r.l. <info@unixmedia.it> ; Copyright (c) 2018- Franco (nextime) Lanza <franco@nexlab.it>
; Copyright (c) 2011-2014 Franco (nextime) Lanza <franco@unixmedia.it>
; ;
; Domotika System Controller Daemon "domotikad" [http://trac.unixmedia.it] ; Domotika System Linux client Daemon "Penguidomd"
; ;
; This file is part of domotikad. ; This file is part of domotikad.
; ;
; domotikad is free software: you can redistribute it and/or modify ; penguidomd is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by ; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or ; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version. ; (at your option) any later version.
...@@ -22,7 +21,7 @@ ...@@ -22,7 +21,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[general] [general]
loglevel: info loglevel: debug
timeserver: yes timeserver: yes
timeinterval: 480 timeinterval: 480
action_status_timer: 2 action_status_timer: 2
...@@ -33,14 +32,8 @@ devices_admpwd: domotika ...@@ -33,14 +32,8 @@ devices_admpwd: domotika
notify_expiretime: 604800 notify_expiretime: 604800
language: it language: it
[geo]
latitude: 45.5967710 ; milan-> 45.4636889
longitude: 8.7547400 ; milan-> 9.1881408
elevation: 205.000000 ; milan-> 122.246513
location: Lonate Pozzolo,it
openweathermap_appid: 7c9892bf8419193b5ea234f5cf6ad87d
[ikapserver] [ikap]
enable = yes enable = yes
interface: 0.0.0.0 interface: 0.0.0.0
ethdev: eth0 ethdev: eth0
...@@ -50,110 +43,11 @@ tcpenable: yes ...@@ -50,110 +43,11 @@ tcpenable: yes
tcpport: 6654 tcpport: 6654
tcpinterface: 127.0.0.1 tcpinterface: 127.0.0.1
loglevel: error loglevel: error
timeupdates: 1
rollingupdates: yes
rollinnum: 5
timeoffline:15
timecheckoffline:5
[proxy]
loglevel: info
localproxypaths: phpmyadmin,domotika,admin,daemons,plugins
localproxyhosts: none
localproxypathsnologin: none
localproxyhostsnologin: none
localproxyport: 80
[protocol]
loglevel: info
timecheck: yes timecheck: yes
tollerance: 10 tollerance: 10
netpwd: netpwd:
[web] [plugins]
enable: yes
enableusergui: yes
enablesqlgui: yes
enablemysqlgui: yes
enableajaxgui: yes
enablerestgui: yes
enablemediagui: yes
logintheme: theme_dmblack
interface: 0.0.0.0
sslport: 443
port: 81
defaultpath: /lowp/home
nologinpaths: resources/js
privkey: ssl/privkey.key
cacert: ssl/cacert.crt
loglevel: info
nologindefaultuser: guest
nologindefaultpass: guest
nologinips: none
cookie_aeskey: CHANGE_ME_PLEASE
[media]
loglevel: info
localtranscode: 15
local_only: yes
transcode: ffmpeg,vlc
transcode_h264: vlc
transcode_webm: ffmpeg
transcode_raw: ffmpeg
[upnp]
enable: yes
ethdev: eth0
loglevel: info
[database]
loglevel: info
dbtype: mysql
dbhost: localhost
dmdbname: domotika
dbuser: domotika
dbpass: dmdbpwdmsql
[smtp]
enable: yes
interface: 127.0.0.1
port: 27
loglevel: info
[asterisk]
loglevel: info
manager_enable: yes
manager_ip: 127.0.0.1
manager_port: 5038
manager_user: domotika
manager_pass: dmastpwd
fagi_enable: yes
fagi_timeout: 50
fagi_iface: 127.0.0.1
fagi_port: 4573
sip_localnet: 192.168.0.0/16
sip_externaddr:
sip_externhost:
[voiceui]
loglevel: debug loglevel: debug
triggerword: domotica
stopword: basta cosi domotica grazie
stopcommand: silenzio domotica
useoutput: no
[dns]
ns1: 8.8.8.8
ns2: 8.8.9.9
host: q.unixmedia.net
ip: auto
[messenger]
app_secret:
verify_token:
page_token:
auth_host: https://[YOURHOST]/botauth/messenger/
auth_img: https://[YOURHOST]/img/logo_login.png
auth_title: Nexlab's domotika
paradox: yes
...@@ -121,3 +121,10 @@ class penguidomService(service.Service): ...@@ -121,3 +121,10 @@ class penguidomService(service.Service):
def on_configGet(self, section, var): def on_configGet(self, section, var):
return self.config.get(section, var) return self.config.get(section, var)
def on_readPluginConfig(self, plugname):
cfg = configFile(self.curdir+'/conf/'+plugname+'.conf')
cfg.readConfig()
return cfg
...@@ -24,6 +24,7 @@ import logging ...@@ -24,6 +24,7 @@ import logging
import os, sys import os, sys
import imodules, plugins import imodules, plugins
from nexlibs.utils.genutils import ConvenienceCaller from nexlibs.utils.genutils import ConvenienceCaller
from nexlibs.utils import genutils
log = logging.getLogger('Plugins') log = logging.getLogger('Plugins')
...@@ -80,9 +81,13 @@ class Loader(object): ...@@ -80,9 +81,13 @@ class Loader(object):
for name in os.listdir(PLUGINDIR): for name in os.listdir(PLUGINDIR):
plugpath = "/".join([PLUGINDIR, name]) plugpath = "/".join([PLUGINDIR, name])
if os.path.isdir(plugpath): if os.path.isdir(plugpath):
p = getPlugin(name, core) try:
self.plugreg[name] = p if genutils.isTrue(self.core.configGet('plugins', name)):
p.initialize(ConvenienceCaller(lambda c: self._plugincback(name, c)), PluginLogger(name)) p = getPlugin(name, core)
self.plugreg[name] = p
p.initialize(ConvenienceCaller(lambda c: self._plugincback(name, c)), PluginLogger(name))
except:
log.error("Trying to load "+name+" plugin but no value in config file plugins section")
def _plugincback(self, who, cmd, *args, **kwargs): def _plugincback(self, who, cmd, *args, **kwargs):
...@@ -101,7 +106,7 @@ class Loader(object): ...@@ -101,7 +106,7 @@ class Loader(object):
try: try:
f=getattr(self, 'on_'+cmd) f=getattr(self, 'on_'+cmd)
except: except:
f=self.core.cmd f=getattr(self.core, cmd)
if f and callable(f): if f and callable(f):
return f return f
except: except:
......
###########################################################################
# 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/>.
#
##############################################################################
...@@ -32,10 +32,10 @@ import time ...@@ -32,10 +32,10 @@ import time
import paradox37b as p37b import paradox37b as p37b
SERIAL_PORT="/dev/ttyUSB0" SERIAL_PORT="/dev/ttyS0"
BAUDRATE=9600 BAUDRATE=9600
PKTTIMEOUT=2 # Seconds PKTTIMEOUT=2 # Seconds
REPLYTIMEOUT=1 # Seconds
class ParadoxProtocol(BaseProtocol): class ParadoxProtocol(BaseProtocol):
...@@ -46,9 +46,11 @@ class ParadoxProtocol(BaseProtocol): ...@@ -46,9 +46,11 @@ class ParadoxProtocol(BaseProtocol):
replyqueue=[] replyqueue=[]
packettimeout = 0 packettimeout = 0
def __init__(self, logger, core): def __init__(self, logger, core, cfg):
self.log = logger self.log = logger
self.core = core self.core = core
self.cfg = cfg
self.log.debug(str(self.cfg))
reactor.addSystemEventTrigger('before', 'shutdown', self._terminating) reactor.addSystemEventTrigger('before', 'shutdown', self._terminating)
def _queueData(self): def _queueData(self):
...@@ -95,7 +97,7 @@ class ParadoxProtocol(BaseProtocol): ...@@ -95,7 +97,7 @@ class ParadoxProtocol(BaseProtocol):
del self.sendqueue[0] del self.sendqueue[0]
self.log.debug(">> SEND MESSAGE: "+''.join( [ "\\x%02X" % ord( x ) for x in packet ] ).strip()) self.log.debug(">> SEND MESSAGE: "+''.join( [ "\\x%02X" % ord( x ) for x in packet ] ).strip())
self.transport.write(packet) self.transport.write(packet)
reactor.callLater(.5, self._checkReplies) reactor.callLater(REPLYTIMEOUT, self._checkReplies)
else: else:
reactor.callLater(.1, self._processSendQueue) reactor.callLater(.1, self._processSendQueue)
...@@ -105,10 +107,10 @@ class ParadoxProtocol(BaseProtocol): ...@@ -105,10 +107,10 @@ class ParadoxProtocol(BaseProtocol):
if self.replyqueue[0]['try'] > 0: if self.replyqueue[0]['try'] > 0:
self.replyqueue[0]['try']-=1 self.replyqueue[0]['try']-=1
self.sendqueue+=[self.replyqueue[0]] self.sendqueue+=[self.replyqueue[0]]
reactor.callLater(0, self._processSendQueue, False) reactor.callLater(.1, self._processSendQueue, False)
else: else:
self.log.error("FAILED TO SEND MESSAGE: "+''.join( [ "\\x%02X" % ord( x ) for x in self.replyqueue[0]['msg'] ] ).strip()) self.log.error("FAILED TO SEND MESSAGE: "+''.join( [ "\\x%02X" % ord( x ) for x in self.replyqueue[0]['msg'] ] ).strip())
del self.sendqueue[0] del self.replyqueue[0]
def dataReceived(self, data): def dataReceived(self, data):
...@@ -135,6 +137,7 @@ class ParadoxProtocol(BaseProtocol): ...@@ -135,6 +137,7 @@ class ParadoxProtocol(BaseProtocol):
self.write(p37b.MSG_CONNECT) self.write(p37b.MSG_CONNECT)
self.write(p37b.MSG_GETSTATUS) self.write(p37b.MSG_GETSTATUS)
self.write(p37b.MSG_SYNC, self._replySync) self.write(p37b.MSG_SYNC, self._replySync)
def write(self, message, reply_callback=False): def write(self, message, reply_callback=False):
self._queueSendData(p37b.format37ByteMessage(message), reply_callback) self._queueSendData(p37b.format37ByteMessage(message), reply_callback)
...@@ -142,7 +145,18 @@ class ParadoxProtocol(BaseProtocol): ...@@ -142,7 +145,18 @@ class ParadoxProtocol(BaseProtocol):
def _replySync(self, reply): def _replySync(self, reply):
self.log.debug("REPLY SYNC RECEIVED") self.log.debug("REPLY SYNC RECEIVED")
self.write(reply) self.write(reply, self._endHandshacke)
def _endHandshacke(self, reply=None):
# XXX Here things starts to get weird.
# I have no idea of what exactly those two messages do,
# but they seems to be needed for the initial handshake
# when connecting. So, we just send both, hope
# sometime i will fully understand what they do exactly.
self.write(p37b.MSG_UNKWNOWN_HS1)
self.write(p37b.MSG_UNKWNOWN_HS2)
def _processEvent(self, event): def _processEvent(self, event):
pass pass
...@@ -151,9 +165,18 @@ class Paradox(object): ...@@ -151,9 +165,18 @@ class Paradox(object):
implements(IPlugin, imodules.IModules) implements(IPlugin, imodules.IModules)
def _openSerial(self, port=SERIAL_PORT, retry=3): def _openSerial(self, port=SERIAL_PORT, retry=3):
try:
dev = self.cfg.get('connection', 'port')
except:
dev = port
try:
brate = int(self.cfg.get('connection', 'baudrate'))
except:
brate = BAUDRATE
if retry > 0: if retry > 0:
try: try:
self.port = SerialPort(ParadoxProtocol(self.log, self.core), port, reactor, baudrate=BAUDRATE) self.port = SerialPort(ParadoxProtocol(self.log, self.core, self.cfg), dev, reactor, baudrate=brate)
except serial.SerialException as err: except serial.SerialException as err:
self.log.info("Serial Port ERROR: "+str(err)) self.log.info("Serial Port ERROR: "+str(err))
reactor.callLater(1, self._openSerial, port, retry-1) reactor.callLater(1, self._openSerial, port, retry-1)
...@@ -165,6 +188,7 @@ class Paradox(object): ...@@ -165,6 +188,7 @@ class Paradox(object):
def initialize(self, callback, logger): def initialize(self, callback, logger):
self.log = logger self.log = logger
self.core = callback self.core = callback
self.cfg = self.core.readPluginConfig('paradox')
logger.info("Initialize Serial Connection...") logger.info("Initialize Serial Connection...")
self._openSerial() self._openSerial()
logger.info("Plugin initialized") logger.info("Plugin initialized")
......
...@@ -118,7 +118,8 @@ MSG_DISCONNECT= '\x70\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0 ...@@ -118,7 +118,8 @@ MSG_DISCONNECT= '\x70\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0
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_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_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' 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'
MSG_UNKWNOWN_HS1= '\x50\x00\x1F\xE0\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\x4F'
MSG_UNKWNOWN_HS2= '\x50\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\x50'
def checkSumCalc(message): def checkSumCalc(message):
......
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