author | Edouard Tisserant <edouard.tisserant@gmail.com> |
Sun, 26 Jan 2025 14:58:13 +0100 (8 weeks ago) | |
changeset 4103 | 63c002e87c57 |
parent 4100 | c6c80c088497 |
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 |
|
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
25 |
# C per client CallBack type for __mqtt_python_onmsg_{name} |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
26 |
mqtt_c_cb_onmsg_type = ctypes.CFUNCTYPE(ctypes.c_int, # return |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
27 |
ctypes.c_char_p, # topic |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
28 |
ctypes.POINTER(ctypes.c_char), # data |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
29 |
ctypes.c_uint32) # data length |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
30 |
|
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
31 |
# C per client CallBack type for __mqtt_python_resub_{name} |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
32 |
mqtt_c_cb_resub_type = ctypes.CFUNCTYPE(ctypes.c_int) # return |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
33 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
34 |
# CallBacks management |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
35 |
# - 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
|
36 |
MQTT_subscribers_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 |
# - 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
|
39 |
MQTT_client_cbs = {} |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
40 |
|
4100
c6c80c088497
MQTT: fix typo in resub python callback.
Edouard Tisserant <edouard@beremiz.fr>
parents:
4099
diff
changeset
|
41 |
def mqtt_per_client_cb_factory(clientname): |
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
42 |
def per_client_onmsg_cb(topic, dataptr, datalen): |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
43 |
payload = ctypes.string_at(dataptr, datalen) |
4100
c6c80c088497
MQTT: fix typo in resub python callback.
Edouard Tisserant <edouard@beremiz.fr>
parents:
4099
diff
changeset
|
44 |
subscriber,_Qos = MQTT_subscribers_cbs[clientname].get(topic, None) |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
45 |
if subscriber: |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
46 |
subscriber(topic, payload) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
47 |
return 0 |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
48 |
return 1 |
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
49 |
def per_client_resub_cb(): |
4100
c6c80c088497
MQTT: fix typo in resub python callback.
Edouard Tisserant <edouard@beremiz.fr>
parents:
4099
diff
changeset
|
50 |
for topic,(_cb,QoS) in MQTT_subscribers_cbs[clientname].items(): |
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
51 |
_MQTT_subscribe(clientname, topic, QoS) |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
52 |
return 1 |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
53 |
return per_client_onmsg_cb,per_client_resub_cb |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
54 |
|
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
55 |
def _MQTT_subscribe(clientname, topic, QoS): |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
56 |
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
|
57 |
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
|
58 |
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
|
59 |
c_function.argtypes = [ |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
60 |
ctypes.c_char_p, # topic |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
61 |
ctypes.c_uint8] # QoS |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
62 |
|
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
63 |
return c_function(topic, QoS) |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
64 |
|
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
65 |
def MQTT_subscribe(clientname, topic, cb, QoS = 1): |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
66 |
global MQTT_client_cbs, MQTT_subscribers_cbs |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
67 |
|
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
68 |
MQTT_subscribers_cbs.setdefault(clientname, {})[topic] = (cb, QoS) |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
69 |
res = _MQTT_subscribe(clientname, topic, QoS) |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
70 |
|
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
71 |
c_cbs = MQTT_client_cbs.get(clientname, None) |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
72 |
if c_cbs is None: |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
73 |
cb_onmsg, cb_resub = mqtt_per_client_cb_factory(clientname) |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
74 |
c_cbs = (mqtt_c_cb_onmsg_type(cb_onmsg), |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
75 |
mqtt_c_cb_resub_type(cb_resub)) |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
76 |
MQTT_client_cbs[clientname] = c_cbs |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
77 |
register_c_function = getattr(PLCBinary, "__mqtt_python_callback_setter_"+clientname ) |
4099
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
78 |
register_c_function.argtypes = [mqtt_c_cb_onmsg_type, mqtt_c_cb_resub_type] |
97e93962be0c
MQTT: fix non reconnecting python topics. WIP
Edouard Tisserant <edouard@beremiz.fr>
parents:
4081
diff
changeset
|
79 |
register_c_function(*c_cbs) |
4081
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
80 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
81 |
return res |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
82 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
83 |
""" |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
84 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
85 |
class MQTTLibrary(POULibrary): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
86 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
87 |
def GetLibraryPath(self): |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
88 |
return paths.AbsNeighbourFile(__file__, "pous.xml") |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
89 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
90 |
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
|
91 |
|
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
92 |
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
|
93 |
runtimefile = open(runtimefile_path, 'w') |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
94 |
runtimefile.write(mqtt_python_lib_code) |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
95 |
runtimefile.close() |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
96 |
return ((["mqtt"], [], False), "", |
86fbb3991af6
MQTT: allow publish and subscribe from user python code.
Edouard Tisserant <edouard@beremiz.fr>
parents:
diff
changeset
|
97 |
("runtime_00_mqtt.py", open(runtimefile_path, "rb"))) |