author | Edouard Tisserant <edouard@beremiz.fr> |
Fri, 28 Feb 2025 16:53:33 +0100 (3 weeks ago) | |
changeset 4124 | 6220f357a726 |
parent 4081 | 86fbb3991af6 |
child 4099 | 97e93962be0c |
permissions | -rw-r--r-- |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
1 |
# mqtt/client.py |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
2 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
3 |
from __future__ import absolute_import |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
4 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
5 |
import os |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
6 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
7 |
from POULibrary import POULibrary |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
8 |
import util.paths as paths |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
9 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
10 |
mqtt_python_lib_code = """ |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
11 |
def MQTT_publish(clientname, topic, payload, QoS = 1, Retained = False): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
12 |
c_function_name = "__mqtt_python_publish_" + clientname |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
13 |
c_function = getattr(PLCBinary, c_function_name) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
14 |
c_function.restype = ctypes.c_int # error or 0 |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
15 |
c_function.argtypes = [ |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
16 |
ctypes.c_char_p, # topic |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
17 |
ctypes.c_char_p, # data |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
18 |
ctypes.c_uint32, # datalen |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
19 |
ctypes.c_uint8, # QoS |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
20 |
ctypes.c_uint8, # Retained |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
21 |
] |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
22 |
res = c_function(topic, payload, len(payload), QoS, Retained) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
23 |
return res |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
24 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
25 |
# C per client CallBack type for __mqtt_python_subscribe_{name} |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
26 |
c_cb_type = ctypes.CFUNCTYPE(ctypes.c_int, # return |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
27 |
ctypes.c_char_p, # topic |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
28 |
ctypes.POINTER(ctypes.c_char), # data |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
29 |
ctypes.c_uint32) # data length |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
30 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
31 |
# CallBacks management |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
32 |
# - each call to MQTT_subscribe registers a callback |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
33 |
MQTT_subscribers_cbs = {} |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
34 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
35 |
# - one callback registered to C side per client |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
36 |
MQTT_client_cbs = {} |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
37 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
38 |
def per_client_cb_factory(client): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
39 |
def per_client_cb(topic, dataptr, datalen): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
40 |
payload = ctypes.string_at(dataptr, datalen) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
41 |
subscriber = MQTT_subscribers_cbs[client].get(topic, None) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
42 |
if subscriber: |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
43 |
subscriber(topic, payload) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
44 |
return 0 |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
45 |
return 1 |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
46 |
return per_client_cb |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
47 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
48 |
def MQTT_subscribe(clientname, topic, cb, QoS = 1): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
49 |
global MQTT_client_cbs, MQTT_subscribers_cbs |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
50 |
c_function_name = "__mqtt_python_subscribe_" + clientname |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
51 |
c_function = getattr(PLCBinary, c_function_name) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
52 |
c_function.restype = ctypes.c_int # error or 0 |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
53 |
c_function.argtypes = [ |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
54 |
ctypes.c_char_p, # topic |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
55 |
ctypes.c_uint8] # QoS |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
56 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
57 |
MQTT_subscribers_cbs.setdefault(clientname, {})[topic] = cb |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
58 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
59 |
c_cb = MQTT_client_cbs.get(clientname, None) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
60 |
if c_cb is None: |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
61 |
c_cb = c_cb_type(per_client_cb_factory(clientname)) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
62 |
MQTT_client_cbs[clientname] = c_cb |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
63 |
register_c_function = getattr(PLCBinary, "__mqtt_python_callback_setter_"+clientname ) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
64 |
register_c_function.argtypes = [c_cb_type] |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
65 |
register_c_function(c_cb) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
66 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
67 |
res = c_function(topic, QoS) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
68 |
return res |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
69 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
70 |
""" |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
71 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
72 |
class MQTTLibrary(POULibrary): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
73 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
74 |
def GetLibraryPath(self): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
75 |
return paths.AbsNeighbourFile(__file__, "pous.xml") |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
76 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
77 |
def Generate_C(self, buildpath, varlist, IECCFLAGS): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
78 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
79 |
runtimefile_path = os.path.join(buildpath, "runtime_00_mqtt.py") |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
80 |
runtimefile = open(runtimefile_path, 'w') |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
81 |
runtimefile.write(mqtt_python_lib_code) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
82 |
runtimefile.close() |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
83 |
return ((["mqtt"], [], False), "", |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
84 |
("runtime_00_mqtt.py", open(runtimefile_path, "rb"))) |