Skip to content

Commit 646fdd6

Browse files
committed
Python wrapper for the Wirepas C Mesh API library
This commit implements a Python wrapper for the Wirepas C Mesh API library, done using the Cython compiler: https://cython.org. Tested with Cython v0.29.14. Build script is very rudimentary at this point.
1 parent 38a5e89 commit 646fdd6

File tree

6 files changed

+1538
-0
lines changed

6 files changed

+1538
-0
lines changed

python/MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
recursive-include wirepas *.pyx *.pxd *.py *.c *.h

python/setup.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
import os
5+
import shutil
6+
from setuptools import Extension, setup
7+
from Cython.Distutils import build_ext as built_ext_cython
8+
from distutils.command.clean import clean
9+
10+
# Package settings
11+
PACKAGE = "wirepas.mesh_api"
12+
DIST_NAME = PACKAGE.replace(".", "-").replace("_", "-")
13+
PACKAGE_DIR = PACKAGE.replace(".", "/")
14+
EXT_NAME = "_mesh_api"
15+
LIB_DIR = "../lib"
16+
17+
# C static library name
18+
if sys.platform == "win32":
19+
LIB_EXT = ".lib"
20+
else:
21+
LIB_EXT = ".a"
22+
23+
# Cython extension
24+
ext_1 = Extension(
25+
PACKAGE + "." + EXT_NAME,
26+
sources=[PACKAGE_DIR + "/" + EXT_NAME + ".pyx"],
27+
include_dirs=[PACKAGE_DIR, LIB_DIR + "/api"],
28+
extra_objects=[LIB_DIR + "/build/mesh_api_lib" + LIB_EXT],
29+
)
30+
31+
32+
# Custom "clean" command
33+
class clean_custom(clean):
34+
def run(self):
35+
# No need to run the original clean command: clean.run(self)
36+
37+
# Delete build directories
38+
self._rmdir(PACKAGE_DIR + "/__pycache__")
39+
self._rmdir(DIST_NAME.replace("-", "_") + ".egg-info")
40+
self._rmdir("build")
41+
self._rmdir("dist")
42+
43+
# Delete generated C file
44+
self._rm(PACKAGE_DIR + "/" + EXT_NAME + ".c")
45+
46+
def _rmdir(self, dir):
47+
try:
48+
shutil.rmtree(dir)
49+
except OSError:
50+
pass
51+
52+
def _rm(self, file):
53+
try:
54+
os.remove(file)
55+
except OSError:
56+
pass
57+
58+
59+
# Main setup functionality
60+
setup(
61+
name=DIST_NAME,
62+
version="0.0",
63+
author="Wirepas Ltd",
64+
author_email="[email protected]",
65+
description="Wirepas Mesh API for Python",
66+
classifiers=[
67+
"Development Status :: 4 - Beta",
68+
"Intended Audience :: Developers",
69+
"License :: OSI Approved :: Apache Software License",
70+
"Operating System :: MacOS :: MacOS X",
71+
"Operating System :: Microsoft :: Windows",
72+
"Operating System :: POSIX :: Linux",
73+
"Programming Language :: C",
74+
"Programming Language :: Cython",
75+
"Programming Language :: Python :: 3 :: Only",
76+
"Topic :: Communications",
77+
],
78+
url="https://github.com/wirepas/c-mesh-api",
79+
packages=[PACKAGE],
80+
ext_modules=[ext_1],
81+
python_requires=">=3.4",
82+
cmdclass={"build_ext": built_ext_cython, "clean": clean_custom},
83+
zip_safe=False,
84+
)

python/testbench.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
import time
5+
6+
import wirepas.mesh_api as wm
7+
8+
c = wm.Connection(b"/dev/ttyACM0", 125000)
9+
10+
try:
11+
addr = "%d" % c.get_node_address()
12+
except wm.MeshAPIError:
13+
addr = "<not set>"
14+
15+
try:
16+
nw_addr = c.get_network_address()
17+
nw_addr = "%d (0x%06x)" % (nw_addr, nw_addr)
18+
except wm.MeshAPIError:
19+
nw_addr = "<not set>"
20+
21+
try:
22+
nw_channel = "%d" % c.get_network_channel()
23+
except wm.MeshAPIError:
24+
nw_channel = "<not set>"
25+
26+
try:
27+
role = "%s" % c.get_role()
28+
except wm.MeshAPIError:
29+
role = "<not set>"
30+
31+
auth_key_set = c.is_authentication_key_set() and "<set>" or "<not set>"
32+
cipher_key_set = c.is_cipher_key_set() and "<set>" or "<not set>"
33+
34+
try:
35+
diag_interval = c.get_app_config_data().interval
36+
except wm.MeshAPIError:
37+
diag_interval = "<not set>"
38+
39+
stack_status = c.get_stack_status()
40+
41+
print("node address: %s" % addr)
42+
print("network address: %s" % nw_addr)
43+
print("network channel: %s" % nw_channel)
44+
print("role: %s" % role)
45+
print("authentication key: %s" % auth_key_set)
46+
print("encryption key: %s" % cipher_key_set)
47+
print("diagnostic interval: %s" % diag_interval)
48+
print("stack status: %s" % stack_status)
49+
50+
51+
def app_config_data_callback(app_config_data):
52+
sys.stdout.write(
53+
"\nIn app_config_data_callback(app_config_data = %s)\n" % repr(app_config_data)
54+
)
55+
sys.stdout.flush()
56+
57+
58+
c.register_for_app_config_data(app_config_data_callback)
59+
60+
61+
def reception_callback(data):
62+
sys.stdout.write("\nIn reception_callback(data = %s)\n" % repr(data))
63+
sys.stdout.flush()
64+
65+
66+
for n in range(256):
67+
c.register_for_data(n, reception_callback)
68+
69+
70+
def scan_callback(scan_ready):
71+
sys.stdout.write("\nIn scan_callback(scan_ready = %s)\n" % repr(scan_ready))
72+
sys.stdout.flush()
73+
74+
75+
c.register_for_scan_neighbors_done(scan_callback)
76+
77+
78+
def other_callback(*args, **kwargs):
79+
sys.stdout.write("\nIn other_callback(%s, %s)\n" % (args, kwargs))
80+
sys.stdout.flush()
81+
82+
83+
c.register_for_remote_status(other_callback)
84+
c.register_from_stack_status(other_callback)
85+
86+
87+
def wait():
88+
while True:
89+
time.sleep(1)
90+
sys.stdout.write(".")
91+
sys.stdout.flush()
92+
93+
94+
wait()

python/wirepas/mesh_api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from ._mesh_api import * # noqa

0 commit comments

Comments
 (0)