Skip to content

Commit 525a86b

Browse files
committed
started on experimental python bindings to libmbus
1 parent 8b2ebfc commit 525a86b

File tree

4 files changed

+235
-0
lines changed

4 files changed

+235
-0
lines changed

examples/mbus-test-1.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/python
2+
# ------------------------------------------------------------------------------
3+
# Copyright (C) 2012, Robert Johansson <[email protected]>, Raditex Control AB
4+
# All rights reserved.
5+
# ------------------------------------------------------------------------------
6+
7+
"""
8+
mbus test: send a request frame and receive and parse the reply
9+
"""
10+
11+
from mbus import *
12+
13+
debug = True
14+
address = 1
15+
16+
mbus = Mbus("localhost", 1200)
17+
18+
if debug:
19+
print "mbus =", mbus
20+
21+
mbus.connect()
22+
23+
if debug:
24+
print "mbus =", mbus
25+
26+
mbus.send_request_frame(address)
27+
28+
reply = mbus.recv_frame()
29+
30+
if debug:
31+
print "reply =", reply
32+
33+
reply_data = mbus.frame_data_parse(reply)
34+
35+
if debug:
36+
print "reply_data =", reply_data
37+
38+
xml_buff = mbus.frame_data_xmlreply_data)
39+
40+
print "xml_buff =", xml_buff

mbus/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
mbus for python
3+
"""

mbus/mbus.py

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#!/usr/bin/python
2+
# ------------------------------------------------------------------------------
3+
# Copyright (C) 2012, Robert Johansson <[email protected]>, Raditex Control AB
4+
# All rights reserved.
5+
# ------------------------------------------------------------------------------
6+
7+
"""
8+
Python bindings for rSCADA libmbus.
9+
"""
10+
11+
from ctypes import *
12+
13+
libmbus = cdll.LoadLibrary('libmbus.so')
14+
15+
class MBusHandle(Structure):
16+
_fields_ = [("fd", c_uint32),
17+
("is_serial", c_uint8),
18+
("internal", c_uint32 * 6)] # pointers
19+
20+
def __str__(self):
21+
return "MBusHandle: XXX"
22+
23+
class MBusFrameFixed(Structure):
24+
_fields_ = [("id_bcd", c_uint8 * 4),
25+
("tx_cnt", c_uint8),
26+
("status", c_uint8),
27+
("cnt1_type", c_uint8),
28+
("cnt2_type", c_uint8),
29+
("cnt1_val", c_uint8 * 4),
30+
("cnt2_val", c_uint8 * 4)]
31+
32+
def __str__(self):
33+
return "MBusFrameVariable: XXX"
34+
35+
class MBusFrameFixed(Structure):
36+
_fields_ = [("id_bcd", c_uint8 * 4),
37+
("tx_cnt", c_uint8),
38+
("status", c_uint8),
39+
("cnt1_type", c_uint8),
40+
("cnt2_type", c_uint8),
41+
("cnt1_val", c_uint8 * 4),
42+
("cnt2_val", c_uint8 * 4)]
43+
44+
def __str__(self):
45+
return "MBusFrameFixed: XXX"
46+
47+
class MBusFrame(Structure):
48+
_fields_ = [("start1", c_uint8 * 16), # MBusFrameFixed
49+
("length1", c_uint8),
50+
("length2", c_uint8),
51+
("start2", c_uint8),
52+
("control", c_uint8),
53+
("address", c_uint8),
54+
("control_infomation", c_uint8),
55+
("checksum", c_uint8),
56+
("stop", c_uint8),
57+
("data", c_uint8 * 252),
58+
("data_size", c_uint32), # check
59+
("stop", c_uint8),
60+
("timestamp", c_uint32), # check
61+
("next", c_uint8)] # pointer
62+
63+
def __str__(self):
64+
return "MBusFrame: XXX"
65+
66+
67+
class MBusFrameData(Structure):
68+
_fields_ = [("data_var", c_uint8 * 16), # MBusFrameFixed
69+
("data_fixed", c_uint8),
70+
("type", c_uint32),
71+
("error", c_uint32)]
72+
73+
def __str__(self):
74+
return "MBusFrame: XXX"
75+
76+
77+
class MBus:
78+
79+
def __init__(self, device=None, host=None, port=8888):
80+
"""
81+
82+
"""
83+
84+
if device:
85+
self.handle = libmbus.mbus_context_serial(device)
86+
elif address and port:
87+
self.handle = libmbus.mbus_context_tcp(host)
88+
else:
89+
raise Exception("Must provide either device or host keyword arguments")
90+
91+
def connect(self):
92+
"""
93+
94+
"""
95+
if self.handle:
96+
if libmbus.mbus_connect(self.handle) == -1:
97+
raise Exception("libmbus.mbus_connect failed")
98+
else:
99+
raise Exception("Handle object not configure")
100+
101+
102+
def disconnect(self):
103+
"""
104+
105+
"""
106+
if self.handle:
107+
if libmbus.mbus_disconnect(self.handle) == -1:
108+
raise Exception("libmbus.mbus_disconnect failed")
109+
else:
110+
raise Exception("Handle object not configure")
111+
112+
def send_request_frame(self, address):
113+
"""
114+
Low-level function: send an request frame to the given address.
115+
"""
116+
if self.handle:
117+
if libmbus.mbus_send_request_frame(byref(self.handle), c_int(address)) == -1:
118+
raise Exception("libmbus.mbus_send_request_frame failed")
119+
else:
120+
raise Exception("Handle object not configure")
121+
122+
def recv_frame(self):
123+
"""
124+
Low-level function: receive a request frame.
125+
"""
126+
127+
if self.handle:
128+
raise Exception("Handle object not configure")
129+
130+
reply = MBusFrame()
131+
132+
if libmbus.mbus_recv_frame(byref(self.handle), byref(reply))) != 0:
133+
raise Exception("libmbus.mbus_recv_frame failed")
134+
135+
return reply
136+
137+
def frame_data_parse(self, reply):
138+
"""
139+
Low-level function: parse data in frame.
140+
"""
141+
142+
reply_data = MBusFrameData()
143+
144+
if libmbus.mbus_frame_data_parse(byref(reply), byref(reply_data))) != 0:
145+
raise Exception("libmbus.mbus_frame_data_parse failed")
146+
147+
return reply_data
148+
149+
def frame_data_xml(self, reply_data):
150+
"""
151+
Low-level function: convert reply data frame to xml.
152+
"""
153+
154+
xml_result = libmbus.mbus_frame_data_xml(byref(reply_data)))
155+
156+
return reply_data
157+

setup.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env python
2+
"""mbus: Python bindings to the libmbus library from rSCADA.
3+
4+
mbus offers binding to the libmbus C library.
5+
"""
6+
7+
DOCLINES = __doc__.split('\n')
8+
9+
CLASSIFIERS = """\
10+
Programming Language :: Python
11+
Topic :: Engineering
12+
Operating System :: POSIX
13+
Operating System :: Unix
14+
"""
15+
16+
from distutils.core import setup
17+
18+
MAJOR = 0
19+
MINOR = 0
20+
MICRO = 1
21+
22+
setup(
23+
name = "mbus",
24+
version = "%d.%d.%d" % (MAJOR, MINOR, MICRO),
25+
packages = ['mbus'],
26+
scripts = ['examples/mbus-test-1.py'],
27+
author = "Robert Johansson",
28+
author_email = "[email protected]",
29+
license = "BSD",
30+
description = DOCLINES[0],
31+
long_description = "\n".join(DOCLINES[2:]),
32+
keywords = "M-Bus library for python",
33+
url = "http://www.rscada.se",
34+
platforms = ["Linux", "Unix"],
35+
)

0 commit comments

Comments
 (0)