Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
Penguidom
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
domotika
Penguidom
Commits
e8e2d808
Commit
e8e2d808
authored
Jan 10, 2018
by
Franco (nextime) Lanza
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add TCP Proxy to permit babyware and other paradox clients
parent
9ee8c278
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
101 additions
and
19 deletions
+101
-19
paradox.conf
conf/defaults/paradox.conf
+3
-0
pluggable.py
penguidom/pluggable.py
+2
-2
paradox.py
penguidom/plugins/paradox/paradox.py
+91
-17
paradox37b.py
penguidom/plugins/paradox/paradox37b.py
+5
-0
No files found.
conf/defaults/paradox.conf
View file @
e8e2d808
...
@@ -2,6 +2,9 @@
...
@@ -2,6 +2,9 @@
port
: /
dev
/
ttyUSB0
port
: /
dev
/
ttyUSB0
baudrate
:
9600
baudrate
:
9600
enableTCPProxy
:
no
tcpport
:
10001
tcpaddr
:
127
.
0
.
0
.
1
[
panel
]
[
panel
]
autodetect
:
yes
autodetect
:
yes
...
...
penguidom/pluggable.py
View file @
e8e2d808
...
@@ -25,7 +25,7 @@ import os, sys
...
@@ -25,7 +25,7 @@ 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
from
nexlibs.utils
import
genutils
from
ConfigParser
import
NoSectionError
log
=
logging
.
getLogger
(
'Plugins'
)
log
=
logging
.
getLogger
(
'Plugins'
)
...
@@ -86,7 +86,7 @@ class Loader(object):
...
@@ -86,7 +86,7 @@ class Loader(object):
p
=
getPlugin
(
name
,
core
)
p
=
getPlugin
(
name
,
core
)
self
.
plugreg
[
name
]
=
p
self
.
plugreg
[
name
]
=
p
p
.
initialize
(
ConvenienceCaller
(
lambda
c
:
self
.
_plugincback
(
name
,
c
)),
PluginLogger
(
name
))
p
.
initialize
(
ConvenienceCaller
(
lambda
c
:
self
.
_plugincback
(
name
,
c
)),
PluginLogger
(
name
))
except
:
except
NoSectionError
:
log
.
error
(
"Trying to load "
+
name
+
" plugin but no value in config file plugins section"
)
log
.
error
(
"Trying to load "
+
name
+
" plugin but no value in config file plugins section"
)
...
...
penguidom/plugins/paradox/paradox.py
View file @
e8e2d808
...
@@ -25,8 +25,10 @@ from zope.interface import implements
...
@@ -25,8 +25,10 @@ from zope.interface import implements
from
twisted.plugin
import
IPlugin
from
twisted.plugin
import
IPlugin
from
twisted.internet.serialport
import
SerialPort
from
twisted.internet.serialport
import
SerialPort
from
twisted.internet.protocol
import
BaseProtocol
from
twisted.internet.protocol
import
BaseProtocol
,
Protocol
,
Factory
from
twisted.internet
import
reactor
from
twisted.internet
import
reactor
,
tcp
from
nexlibs.utils
import
genutils
import
serial
import
serial
import
time
import
time
...
@@ -45,6 +47,7 @@ class ParadoxProtocol(BaseProtocol):
...
@@ -45,6 +47,7 @@ class ParadoxProtocol(BaseProtocol):
sendqueue
=
[]
sendqueue
=
[]
replyqueue
=
[]
replyqueue
=
[]
packettimeout
=
0
packettimeout
=
0
proxy
=
False
def
__init__
(
self
,
logger
,
core
,
cfg
):
def
__init__
(
self
,
logger
,
core
,
cfg
):
self
.
log
=
logger
self
.
log
=
logger
...
@@ -69,23 +72,45 @@ class ParadoxProtocol(BaseProtocol):
...
@@ -69,23 +72,45 @@ class ParadoxProtocol(BaseProtocol):
elif
len
(
self
.
packet
)
>
0
:
elif
len
(
self
.
packet
)
>
0
:
self
.
packettimeout
=
time
.
time
()
self
.
packettimeout
=
time
.
time
()
def
_queueSendData
(
self
,
data
,
callback
=
False
):
def
_queueSendData
(
self
,
data
,
callback
=
False
,
expected_reply
=
None
):
self
.
sendqueue
+=
[{
'msg'
:
data
,
'cb'
:
callback
,
'try'
:
3
}]
self
.
sendqueue
+=
[{
'msg'
:
data
,
'cb'
:
callback
,
'try'
:
3
,
'expected_reply'
:
expected_reply
}]
reactor
.
callLater
(
0
,
self
.
_processSendQueue
)
reactor
.
callLater
(
0
,
self
.
_processSendQueue
)
def
_processQueue
(
self
):
def
_processQueue
(
self
):
def
_expected_reply
(
replystart
,
expected
):
if
expected
:
if
isinstance
(
expected
,
(
list
,
tuple
)):
for
i
in
expected
:
if
p37b
.
checkCmd
(
replystart
,
i
):
return
True
else
:
if
p37b
.
checkCmd
(
replystart
,
expected
):
return
True
else
:
return
True
return
False
if
len
(
self
.
queue
)
>
0
:
if
len
(
self
.
queue
)
>
0
:
if
p37b
.
checkCmd
(
ord
(
self
.
queue
[
0
][
0
]),
p37b
.
CMD_EVENT
):
if
p37b
.
checkCmd
(
ord
(
self
.
queue
[
0
][
0
]),
p37b
.
CMD_EVENT
):
reactor
.
callLater
(
0
,
self
.
_processEvent
,
self
.
queue
[
0
])
reactor
.
callLater
(
0
,
self
.
_processEvent
,
self
.
queue
[
0
])
else
:
else
:
if
len
(
self
.
replyqueue
)
>
0
:
if
len
(
self
.
replyqueue
)
>
0
:
# XXX Can we check in some way if is the *RIGHT* reply?
if
_expected_reply
(
ord
(
self
.
queue
[
0
][
0
]),
self
.
replyqueue
[
0
][
'expected_reply'
]):
# in theory we don't need it as we will not send anything
# XXX Can we check in some way if is the *RIGHT* reply?
# until the reply is received, but it would be more error
# in theory we don't need it as we will not send anything
# prone that way...
# until the reply is received, but it would be more error
if
self
.
replyqueue
[
0
][
'cb'
]
and
callable
(
self
.
replyqueue
[
0
][
'cb'
]):
# prone that way...
reactor
.
callLater
(
0
,
self
.
replyqueue
[
0
][
'cb'
],
self
.
queue
[
0
])
if
self
.
replyqueue
[
0
][
'cb'
]
and
callable
(
self
.
replyqueue
[
0
][
'cb'
]):
del
self
.
replyqueue
[
0
]
reactor
.
callLater
(
0
,
self
.
replyqueue
[
0
][
'cb'
],
self
.
queue
[
0
])
del
self
.
replyqueue
[
0
]
else
:
if
isinstance
(
self
.
replyqueue
[
0
][
'expected_reply'
],
(
list
,
tuple
)):
expected
=
"["
+
","
.
join
([
"
\\
x
%02
X"
%
(
x
)
for
x
in
self
.
replyqueue
[
0
][
'expected_reply'
]])
+
"]"
else
:
print
self
.
replyqueue
[
0
][
'expected_reply'
]
<<
4
expected
=
"
\\
x
%02
X"
%
(
self
.
replyqueue
[
0
][
'expected_reply'
])
self
.
log
.
error
(
"Wrong Expected Reply! (have "
+
"
\\
x
%02
X"
%
(
ord
(
self
.
queue
[
0
][
0
])
>>
4
)
+
" expect "
+
expected
+
")"
)
del
self
.
queue
[
0
]
del
self
.
queue
[
0
]
def
_processSendQueue
(
self
,
addToReplyQueue
=
True
):
def
_processSendQueue
(
self
,
addToReplyQueue
=
True
):
...
@@ -114,6 +139,8 @@ class ParadoxProtocol(BaseProtocol):
...
@@ -114,6 +139,8 @@ class ParadoxProtocol(BaseProtocol):
def
dataReceived
(
self
,
data
):
def
dataReceived
(
self
,
data
):
if
self
.
proxy
:
self
.
proxy
.
serialInData
(
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
%02
X"
%
ord
(
x
)
for
x
in
self
.
packet
]
)
.
strip
())
self
.
log
.
debug
(
"Serial Timeout: discard packet "
+
''
.
join
(
[
"
\\
x
%02
X"
%
ord
(
x
)
for
x
in
self
.
packet
]
)
.
strip
())
self
.
packet
=
[]
self
.
packet
=
[]
...
@@ -134,13 +161,13 @@ class ParadoxProtocol(BaseProtocol):
...
@@ -134,13 +161,13 @@ 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
):
self
.
write
(
p37b
.
MSG_CONNECT
)
self
.
write
(
p37b
.
MSG_CONNECT
,
expected_reply
=
p37b
.
REPLY_CONNECT
)
self
.
write
(
p37b
.
MSG_GETSTATUS
)
self
.
write
(
p37b
.
MSG_GETSTATUS
,
expected_reply
=
p37b
.
REPLY_GETSTATUS
)
self
.
write
(
p37b
.
MSG_SYNC
,
self
.
_replySync
)
self
.
write
(
p37b
.
MSG_SYNC
,
self
.
_replySync
,
expected_reply
=
p37b
.
REPLY_SYNC
)
def
write
(
self
,
message
,
reply_callback
=
False
):
def
write
(
self
,
message
,
reply_callback
=
False
,
expected_reply
=
False
):
self
.
_queueSendData
(
p37b
.
format37ByteMessage
(
message
),
reply_callback
)
self
.
_queueSendData
(
p37b
.
format37ByteMessage
(
message
),
reply_callback
,
expected_reply
)
def
_replySync
(
self
,
reply
):
def
_replySync
(
self
,
reply
):
...
@@ -161,8 +188,47 @@ class ParadoxProtocol(BaseProtocol):
...
@@ -161,8 +188,47 @@ class ParadoxProtocol(BaseProtocol):
def
_processEvent
(
self
,
event
):
def
_processEvent
(
self
,
event
):
pass
pass
class
ParadoxTCPProxy
(
Protocol
):
cid
=
0
def
__init__
(
self
,
clients
,
factory
):
self
.
clients
=
clients
self
.
factory
=
factory
def
connectionMade
(
self
):
cid
=
len
(
self
.
clients
)
self
.
clients
[
cid
]
=
self
self
.
cid
=
cid
def
connectionLost
(
self
,
reason
):
if
self
.
cid
in
self
.
clients
.
keys
():
del
self
.
clients
[
self
.
cid
]
def
dataReceived
(
self
,
data
):
self
.
factory
.
log
.
debug
(
"Data FROM TCP Client "
+
str
(
self
.
cid
)
+
": "
+
''
.
join
(
[
"
\\
x
%02
X"
%
ord
(
x
)
for
x
in
data
]
)
.
strip
())
self
.
factory
.
serproto
.
transport
.
write
(
data
)
class
ParadoxTCPFactory
(
Factory
):
def
__init__
(
self
,
core
,
serproto
,
logger
):
self
.
clients
=
{}
self
.
serproto
=
serproto
self
.
serproto
.
proxy
=
self
self
.
log
=
logger
def
serialInData
(
self
,
data
):
for
cid
in
self
.
clients
.
keys
():
self
.
clients
[
cid
]
.
transport
.
write
(
data
)
def
buildProtocol
(
self
,
addr
):
return
ParadoxTCPProxy
(
self
.
clients
,
self
)
class
Paradox
(
object
):
class
Paradox
(
object
):
implements
(
IPlugin
,
imodules
.
IModules
)
implements
(
IPlugin
,
imodules
.
IModules
)
serproto
=
False
def
_openSerial
(
self
,
port
=
SERIAL_PORT
,
retry
=
3
):
def
_openSerial
(
self
,
port
=
SERIAL_PORT
,
retry
=
3
):
try
:
try
:
...
@@ -176,7 +242,8 @@ class Paradox(object):
...
@@ -176,7 +242,8 @@ class Paradox(object):
if
retry
>
0
:
if
retry
>
0
:
try
:
try
:
self
.
port
=
SerialPort
(
ParadoxProtocol
(
self
.
log
,
self
.
core
,
self
.
cfg
),
dev
,
reactor
,
baudrate
=
brate
)
self
.
serproto
=
ParadoxProtocol
(
self
.
log
,
self
.
core
,
self
.
cfg
)
self
.
port
=
SerialPort
(
self
.
serproto
,
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
)
...
@@ -191,6 +258,13 @@ class Paradox(object):
...
@@ -191,6 +258,13 @@ class Paradox(object):
self
.
cfg
=
self
.
core
.
readPluginConfig
(
'paradox'
)
self
.
cfg
=
self
.
core
.
readPluginConfig
(
'paradox'
)
logger
.
info
(
"Initialize Serial Connection..."
)
logger
.
info
(
"Initialize Serial Connection..."
)
self
.
_openSerial
()
self
.
_openSerial
()
if
genutils
.
isTrue
(
self
.
cfg
.
get
(
"connection"
,
"enableTCPProxy"
))
and
self
.
serproto
:
self
.
proxy
=
ParadoxTCPFactory
(
self
.
core
,
self
.
serproto
,
self
.
log
)
tcpport
=
self
.
cfg
.
get
(
"connection"
,
"tcpport"
)
self
.
log
.
debug
(
"TCP Port "
+
str
(
tcpport
)
+
" OPEN"
)
port
=
tcp
.
Port
(
int
(
tcpport
),
self
.
proxy
,
50
,
self
.
cfg
.
get
(
"connection"
,
"tcpaddr"
),
reactor
)
port
.
startListening
()
logger
.
info
(
"Plugin initialized"
)
logger
.
info
(
"Plugin initialized"
)
...
...
penguidom/plugins/paradox/paradox37b.py
View file @
e8e2d808
...
@@ -121,6 +121,11 @@ MSG_SYNC= '\x5F\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0
...
@@ -121,6 +121,11 @@ MSG_SYNC= '\x5F\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0
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_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
'
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
'
# Expected replies command
REPLY_CONNECT
=
0x7
REPLY_GETSTATUS
=
[
0x5
,
0x7
]
REPLY_SYNC
=
0x0
def
checkSumCalc
(
message
):
def
checkSumCalc
(
message
):
checksum
=
0
checksum
=
0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment