pymqttusb-tk 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymqttusb_tk-1.0.1/LICENCE +21 -0
- pymqttusb_tk-1.0.1/PKG-INFO +53 -0
- pymqttusb_tk-1.0.1/README.md +22 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk/__init__.py +1 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk/main.py +308 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk.egg-info/PKG-INFO +53 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk.egg-info/SOURCES.txt +10 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk.egg-info/dependency_links.txt +1 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk.egg-info/requires.txt +2 -0
- pymqttusb_tk-1.0.1/pymqttusb_tk.egg-info/top_level.txt +1 -0
- pymqttusb_tk-1.0.1/setup.cfg +4 -0
- pymqttusb_tk-1.0.1/setup.py +32 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2021] [Didier Orlandi]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pymqttusb_tk
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Connexion USB <-> MQTT (SSL ou WSS) avec interface Tkinter
|
|
5
|
+
Home-page: https://github.com/didierorlandi/pymqttusb_tk
|
|
6
|
+
Author: Didier Orlandi
|
|
7
|
+
Author-email: didier.orlandi06@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Topic :: Communications
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
14
|
+
Classifier: Environment :: MacOS X
|
|
15
|
+
Classifier: Environment :: X11 Applications :: GTK
|
|
16
|
+
Requires-Python: >=3.6
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENCE
|
|
19
|
+
Requires-Dist: paho-mqtt<2.0.0
|
|
20
|
+
Requires-Dist: pyserial>=3.5
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: requires-dist
|
|
29
|
+
Dynamic: requires-python
|
|
30
|
+
Dynamic: summary
|
|
31
|
+
|
|
32
|
+
#pymqttusb-tk
|
|
33
|
+
|
|
34
|
+
Permet la connexion d'un microprocesseur branché sur un port usb vers un serveur MQTT.<br />
|
|
35
|
+
|
|
36
|
+
L'affichage graphique permet de configurer le broker <br />
|
|
37
|
+
Contenu du fichier "arduino_mqtt_data.json" :<br />
|
|
38
|
+
|
|
39
|
+
-----------<br />
|
|
40
|
+
|
|
41
|
+
Le topic de réception sera : salle/KEY/out<br />
|
|
42
|
+
|
|
43
|
+
Le topic d'envoi sera : salle/KEY/in<br />
|
|
44
|
+
|
|
45
|
+
Les protocoles possibles sont "wss" websockets sécurisés avec login et mot de passe ( pas de certificat)
|
|
46
|
+
ou "tcp" pour ssl avec login et mot de passe ( pas de certificats client) <br />
|
|
47
|
+
|
|
48
|
+
Lancement du programme :<br />
|
|
49
|
+
|
|
50
|
+
py -m pymqttusb-tk.main <br />
|
|
51
|
+
|
|
52
|
+
<br />
|
|
53
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#pymqttusb-tk
|
|
2
|
+
|
|
3
|
+
Permet la connexion d'un microprocesseur branché sur un port usb vers un serveur MQTT.<br />
|
|
4
|
+
|
|
5
|
+
L'affichage graphique permet de configurer le broker <br />
|
|
6
|
+
Contenu du fichier "arduino_mqtt_data.json" :<br />
|
|
7
|
+
|
|
8
|
+
-----------<br />
|
|
9
|
+
|
|
10
|
+
Le topic de réception sera : salle/KEY/out<br />
|
|
11
|
+
|
|
12
|
+
Le topic d'envoi sera : salle/KEY/in<br />
|
|
13
|
+
|
|
14
|
+
Les protocoles possibles sont "wss" websockets sécurisés avec login et mot de passe ( pas de certificat)
|
|
15
|
+
ou "tcp" pour ssl avec login et mot de passe ( pas de certificats client) <br />
|
|
16
|
+
|
|
17
|
+
Lancement du programme :<br />
|
|
18
|
+
|
|
19
|
+
py -m pymqttusb-tk.main <br />
|
|
20
|
+
|
|
21
|
+
<br />
|
|
22
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import tkinter as tk
|
|
2
|
+
from tkinter import ttk, scrolledtext
|
|
3
|
+
import threading, time, ssl, random, string
|
|
4
|
+
import paho.mqtt.client as mqtt
|
|
5
|
+
import serial
|
|
6
|
+
import serial.tools.list_ports
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def randomword(length):
|
|
10
|
+
lettresEtChiffres = string.ascii_letters + string.digits
|
|
11
|
+
return ''.join(random.choice(lettresEtChiffres) for i in range(length))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MQTTSerialBridgeApp:
|
|
15
|
+
def __init__(self, master):
|
|
16
|
+
self.master = master
|
|
17
|
+
self.master.title("FABLAB UniCA - Publication MQTT")
|
|
18
|
+
self.master.geometry("800x740")
|
|
19
|
+
|
|
20
|
+
# --- Titre principal ---
|
|
21
|
+
title_label = tk.Label(
|
|
22
|
+
master,
|
|
23
|
+
text="FABLAB UniCA - Publication MQTT",
|
|
24
|
+
font=("Helvetica", 18, "bold"),
|
|
25
|
+
fg="blue"
|
|
26
|
+
)
|
|
27
|
+
title_label.pack(pady=5)
|
|
28
|
+
|
|
29
|
+
# --- Frame Configuration ---
|
|
30
|
+
frame_conf = ttk.LabelFrame(master, text="Configuration")
|
|
31
|
+
frame_conf.pack(fill="x", padx=10, pady=5)
|
|
32
|
+
|
|
33
|
+
# Ligne 1 : Port série + Baudrate
|
|
34
|
+
ttk.Label(frame_conf, text="Port série :").grid(row=0, column=0, sticky="w", padx=2, pady=2)
|
|
35
|
+
self.port_box = ttk.Combobox(frame_conf, width=20, values=self.list_serial_ports())
|
|
36
|
+
self.port_box.grid(row=0, column=1, sticky="w") # ← aligné à gauche
|
|
37
|
+
if self.port_box["values"]:
|
|
38
|
+
self.port_box.set(self.port_box["values"][0])
|
|
39
|
+
else:
|
|
40
|
+
self.port_box.set("Aucun port trouvé")
|
|
41
|
+
|
|
42
|
+
# Styles personnalisés pour les boutons
|
|
43
|
+
style = ttk.Style()
|
|
44
|
+
style.theme_use("clam") # <-- permet de colorer le fond
|
|
45
|
+
|
|
46
|
+
style.configure("Connect.TButton",# vert clair
|
|
47
|
+
background="#b3ffb3",
|
|
48
|
+
foreground="black",
|
|
49
|
+
relief="raised")
|
|
50
|
+
style.map("Connect.TButton",
|
|
51
|
+
background=[('active', '#99ff99')])
|
|
52
|
+
|
|
53
|
+
style.map("Connect.TButton", background=[('active', '#99ff99')])
|
|
54
|
+
|
|
55
|
+
style.configure("Disconnect.TButton",
|
|
56
|
+
background="#ffb3b3",
|
|
57
|
+
foreground="black",
|
|
58
|
+
relief="raised")
|
|
59
|
+
style.map("Disconnect.TButton",
|
|
60
|
+
background=[('active', '#ff9999')])
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# Bouton Actualiser
|
|
64
|
+
ttk.Button(frame_conf, text="🔄 Actualiser", command=self.refresh_ports).grid(row=0, column=2, sticky="w", padx=(5, 2))
|
|
65
|
+
|
|
66
|
+
# Sous-frame pour Baudrate (collé au bouton)
|
|
67
|
+
baud_frame = ttk.Frame(frame_conf)
|
|
68
|
+
baud_frame.grid(row=0, column=3, sticky="w", padx=(0, 0))
|
|
69
|
+
|
|
70
|
+
ttk.Label(baud_frame, text="Baudrate :").pack(side="left", padx=(6, 3))
|
|
71
|
+
self.baud_entry = ttk.Entry(baud_frame, width=10)
|
|
72
|
+
self.baud_entry.insert(0, "9600")
|
|
73
|
+
self.baud_entry.pack(side="left")
|
|
74
|
+
|
|
75
|
+
# Ligne 2 : Broker + Port MQTT
|
|
76
|
+
ttk.Label(frame_conf, text="Broker MQTT :").grid(row=1, column=0, sticky="w", padx=2)
|
|
77
|
+
self.broker_entry = ttk.Entry(frame_conf, width=25)
|
|
78
|
+
self.broker_entry.insert(0, "mqtt.univ-cotedazur.fr")
|
|
79
|
+
self.broker_entry.grid(row=1, column=1, columnspan=2, sticky="w") # ← aligné à gauche
|
|
80
|
+
|
|
81
|
+
# Sous-frame pour Port (collé au broker)
|
|
82
|
+
port_frame = ttk.Frame(frame_conf)
|
|
83
|
+
port_frame.grid(row=1, column=3, sticky="w", padx=(5, 0))
|
|
84
|
+
ttk.Label(port_frame, text="Port :").pack(side="left", padx=(2, 4))
|
|
85
|
+
self.mqtt_port_entry = ttk.Entry(port_frame, width=8)
|
|
86
|
+
self.mqtt_port_entry.insert(0, "443")
|
|
87
|
+
self.mqtt_port_entry.pack(side="left")
|
|
88
|
+
|
|
89
|
+
""" ttk.Label(frame_conf, text="Port :").grid(row=1, column=3, sticky="w", padx=2)
|
|
90
|
+
self.mqtt_port_entry = ttk.Entry(frame_conf, width=8)
|
|
91
|
+
self.mqtt_port_entry.insert(0, "443")
|
|
92
|
+
self.mqtt_port_entry.grid(row=1, column=4, sticky="w") # ← aligné à gauche """
|
|
93
|
+
|
|
94
|
+
# Ligne 3 : Salle / KEY
|
|
95
|
+
ttk.Label(frame_conf, text="Salle :").grid(row=2, column=0, sticky="w", padx=2)
|
|
96
|
+
self.salle_entry = ttk.Entry(frame_conf, width=15)
|
|
97
|
+
self.salle_entry.insert(0, "FABLAB_21_22")
|
|
98
|
+
self.salle_entry.grid(row=2, column=1, sticky="w") # aligné à gauche
|
|
99
|
+
|
|
100
|
+
ttk.Label(frame_conf, text="Clé (KEY) :").grid(row=2, column=2, sticky="w", padx=2)
|
|
101
|
+
self.key_entry = ttk.Entry(frame_conf, width=30)
|
|
102
|
+
self.key_entry.insert(0, "TEST")
|
|
103
|
+
self.key_entry.grid(row=2, column=3, sticky="w") # aligné à gauche
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# Ligne 4 : Identifiants MQTT
|
|
107
|
+
ttk.Label(frame_conf, text="Utilisateur MQTT :").grid(row=3, column=0, sticky="w", padx=2)
|
|
108
|
+
self.user_entry = ttk.Entry(frame_conf, width=15)
|
|
109
|
+
self.user_entry.insert(0, "fablab2122")
|
|
110
|
+
self.user_entry.grid(row=3, column=1, sticky="w") # aligné à gauche
|
|
111
|
+
|
|
112
|
+
ttk.Label(frame_conf, text="Mot de passe :").grid(row=3, column=2, sticky="w", padx=2)
|
|
113
|
+
self.pwd_entry = ttk.Entry(frame_conf, width=30, show="*") # largeur augmentée pour alignement
|
|
114
|
+
self.pwd_entry.grid(row=3, column=3, sticky="w") # aligné à gauche
|
|
115
|
+
|
|
116
|
+
# Ligne 5 : Protocole
|
|
117
|
+
ttk.Label(frame_conf, text="Protocole :").grid(row=4, column=0, sticky="w", padx=2)
|
|
118
|
+
self.proto_box = ttk.Combobox(frame_conf, values=["mqtt", "mqtts", "ws", "wss"], width=10)
|
|
119
|
+
self.proto_box.set("wss")
|
|
120
|
+
self.proto_box.grid(row=4, column=1, sticky="w")
|
|
121
|
+
|
|
122
|
+
#Button
|
|
123
|
+
ttk.Button(frame_conf, text="Connecter", style="Connect.TButton", command=self.start_connection).grid(row=4, column=3, padx=5)
|
|
124
|
+
ttk.Button(frame_conf, text="Déconnecter", style="Disconnect.TButton", command=self.stop_connection).grid(row=4, column=4, padx=5)
|
|
125
|
+
|
|
126
|
+
# --- Frame Publication manuelle ---
|
|
127
|
+
frame_pub = ttk.LabelFrame(master, text="Publication manuelle MQTT")
|
|
128
|
+
frame_pub.pack(fill="x", padx=10, pady=5)
|
|
129
|
+
|
|
130
|
+
ttk.Label(frame_pub, text="Topic :").grid(row=0, column=0, sticky="w", padx=5, pady=5)
|
|
131
|
+
self.manual_topic = ttk.Entry(frame_pub, width=40)
|
|
132
|
+
self.manual_topic.insert(0, "FABLAB_21_22/TEST/out/")
|
|
133
|
+
self.manual_topic.grid(row=0, column=1, padx=5, pady=5)
|
|
134
|
+
|
|
135
|
+
ttk.Label(frame_pub, text="Données :").grid(row=1, column=0, sticky="w", padx=5, pady=5)
|
|
136
|
+
self.manual_msg = ttk.Entry(frame_pub, width=60)
|
|
137
|
+
self.manual_msg.grid(row=1, column=1, padx=5, pady=5)
|
|
138
|
+
|
|
139
|
+
ttk.Button(frame_pub, text="📤 Publier", command=self.publish_manual).grid(row=0, column=2, rowspan=2, padx=10)
|
|
140
|
+
|
|
141
|
+
# --- Zone de Logs ---
|
|
142
|
+
frame_log = ttk.LabelFrame(master, text="Console / Journal")
|
|
143
|
+
frame_log.pack(fill="both", expand=True, padx=10, pady=10)
|
|
144
|
+
|
|
145
|
+
ttk.Button(frame_log, text="🧹 Effacer le journal", command=self.clear_log).pack(anchor="e", padx=5, pady=3)
|
|
146
|
+
|
|
147
|
+
self.log_area = scrolledtext.ScrolledText(frame_log, height=20, state='disabled', wrap=tk.WORD)
|
|
148
|
+
self.log_area.pack(fill="both", expand=True, padx=5, pady=5)
|
|
149
|
+
|
|
150
|
+
# --- Variables internes ---
|
|
151
|
+
self.client = None
|
|
152
|
+
self.ser = None
|
|
153
|
+
self.running = False
|
|
154
|
+
self.thread_serial = None
|
|
155
|
+
|
|
156
|
+
# --- Détection des ports disponibles ---
|
|
157
|
+
def list_serial_ports(self):
|
|
158
|
+
ports = serial.tools.list_ports.comports()
|
|
159
|
+
return [p.device for p in ports]
|
|
160
|
+
|
|
161
|
+
def refresh_ports(self):
|
|
162
|
+
ports = self.list_serial_ports()
|
|
163
|
+
self.port_box["values"] = ports if ports else ["Aucun port trouvé"]
|
|
164
|
+
if ports:
|
|
165
|
+
self.port_box.set(ports[0])
|
|
166
|
+
self.log(f"🔄 Ports détectés : {', '.join(ports)}")
|
|
167
|
+
else:
|
|
168
|
+
self.port_box.set("Aucun port trouvé")
|
|
169
|
+
self.log("⚠️ Aucun port série détecté.")
|
|
170
|
+
|
|
171
|
+
# --- Connexion principale ---
|
|
172
|
+
def start_connection(self):
|
|
173
|
+
if self.running:
|
|
174
|
+
self.log("⚠️ Déjà connecté.")
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
broker = self.broker_entry.get()
|
|
178
|
+
port = int(self.mqtt_port_entry.get())
|
|
179
|
+
salle = self.salle_entry.get()
|
|
180
|
+
key = self.key_entry.get()
|
|
181
|
+
username = self.user_entry.get()
|
|
182
|
+
password = self.pwd_entry.get()
|
|
183
|
+
proto = self.proto_box.get()
|
|
184
|
+
serial_port = self.port_box.get()
|
|
185
|
+
baud = int(self.baud_entry.get())
|
|
186
|
+
|
|
187
|
+
if not password.strip():
|
|
188
|
+
self.log("❌ Indiquez le mot de passe pour la connexion MQTT !")
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
if serial_port == "Aucun port trouvé" or not serial_port.strip():
|
|
192
|
+
self.log("❌ Vérifier la connexion de votre port série !")
|
|
193
|
+
return
|
|
194
|
+
|
|
195
|
+
self.topic_in = f"{salle}/{key}/in/"
|
|
196
|
+
self.topic_out = f"{salle}/{key}/out/"
|
|
197
|
+
protocol = "websockets" if proto in ["ws", "wss"] else "tcp"
|
|
198
|
+
|
|
199
|
+
# Configuration MQTT
|
|
200
|
+
self.client = mqtt.Client(client_id=randomword(8),
|
|
201
|
+
clean_session=True,
|
|
202
|
+
protocol=mqtt.MQTTv311,
|
|
203
|
+
transport=protocol)
|
|
204
|
+
self.client.username_pw_set(username, password)
|
|
205
|
+
if proto in ["mqtts", "wss"]:
|
|
206
|
+
self.client.tls_set(tls_version=ssl.PROTOCOL_TLSv1_2)
|
|
207
|
+
|
|
208
|
+
self.client.on_connect = self.on_connect
|
|
209
|
+
self.client.on_message = self.on_message
|
|
210
|
+
self.client.connected_flag = False
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
self.ser = serial.Serial(serial_port, baud, timeout=1)
|
|
214
|
+
self.log(f"✅ Port série {serial_port} ouvert ({baud} bauds)")
|
|
215
|
+
except Exception:
|
|
216
|
+
self.log("❌ Vérifier la connexion de votre port série !")
|
|
217
|
+
return
|
|
218
|
+
|
|
219
|
+
self.running = True
|
|
220
|
+
threading.Thread(target=self.serial_loop, daemon=True).start()
|
|
221
|
+
threading.Thread(target=self.mqtt_loop, args=(broker, port), daemon=True).start()
|
|
222
|
+
|
|
223
|
+
# --- Boucles principales ---
|
|
224
|
+
def mqtt_loop(self, broker, port):
|
|
225
|
+
try:
|
|
226
|
+
self.client.connect(broker, port, 60)
|
|
227
|
+
self.client.loop_forever()
|
|
228
|
+
except Exception as e:
|
|
229
|
+
self.log(f"❌ Erreur MQTT : {e}")
|
|
230
|
+
|
|
231
|
+
def serial_loop(self):
|
|
232
|
+
while self.running:
|
|
233
|
+
try:
|
|
234
|
+
data = self.ser.readline().decode().strip()
|
|
235
|
+
if data and self.client.connected_flag:
|
|
236
|
+
self.client.publish(self.topic_out, data)
|
|
237
|
+
self.log(f"📤 Envoi MQTT → {self.topic_out} : {data}")
|
|
238
|
+
except Exception as e:
|
|
239
|
+
self.log(f"⚠️ Erreur lecture série : {e}")
|
|
240
|
+
time.sleep(0.1)
|
|
241
|
+
|
|
242
|
+
# --- Publication manuelle ---
|
|
243
|
+
def publish_manual(self):
|
|
244
|
+
if not self.client or not self.client.connected_flag:
|
|
245
|
+
self.log("⚠️ Client MQTT non connecté.")
|
|
246
|
+
return
|
|
247
|
+
|
|
248
|
+
topic = self.manual_topic.get().strip()
|
|
249
|
+
msg = self.manual_msg.get().strip()
|
|
250
|
+
|
|
251
|
+
if not topic or not msg:
|
|
252
|
+
self.log("⚠️ Indiquez un topic et un message avant de publier.")
|
|
253
|
+
return
|
|
254
|
+
|
|
255
|
+
self.client.publish(topic, msg)
|
|
256
|
+
self.log(f"✉️ Publication manuelle → {topic} : {msg}")
|
|
257
|
+
|
|
258
|
+
# Efface le champ message après envoi
|
|
259
|
+
self.manual_msg.delete(0, tk.END)
|
|
260
|
+
|
|
261
|
+
# --- Callbacks MQTT ---
|
|
262
|
+
def on_connect(self, client, userdata, flags, rc):
|
|
263
|
+
if rc == 0:
|
|
264
|
+
client.connected_flag = True
|
|
265
|
+
client.subscribe(self.topic_in)
|
|
266
|
+
self.log(f"🔗 Connecté au broker et abonné à {self.topic_in}")
|
|
267
|
+
else:
|
|
268
|
+
self.log(f"❌ Erreur connexion MQTT : code {rc}")
|
|
269
|
+
|
|
270
|
+
def on_message(self, client, userdata, msg):
|
|
271
|
+
data = msg.payload.decode()
|
|
272
|
+
self.log(f"📥 Réception MQTT ← {msg.topic} : {data}")
|
|
273
|
+
try:
|
|
274
|
+
self.ser.write((data + "\n").encode())
|
|
275
|
+
except:
|
|
276
|
+
self.log("⚠️ Erreur écriture vers série")
|
|
277
|
+
|
|
278
|
+
def stop_connection(self):
|
|
279
|
+
self.running = False
|
|
280
|
+
try:
|
|
281
|
+
if self.client:
|
|
282
|
+
self.client.disconnect()
|
|
283
|
+
self.log("🔌 Déconnexion MQTT")
|
|
284
|
+
if self.ser and self.ser.is_open:
|
|
285
|
+
self.ser.close()
|
|
286
|
+
self.log("🛑 Port série fermé")
|
|
287
|
+
except Exception as e:
|
|
288
|
+
self.log(f"⚠️ Erreur arrêt : {e}")
|
|
289
|
+
|
|
290
|
+
def log(self, msg):
|
|
291
|
+
self.log_area.config(state='normal')
|
|
292
|
+
self.log_area.insert(tk.END, msg + "\n")
|
|
293
|
+
self.log_area.yview(tk.END)
|
|
294
|
+
self.log_area.config(state='disabled')
|
|
295
|
+
|
|
296
|
+
def clear_log(self):
|
|
297
|
+
self.log_area.config(state='normal')
|
|
298
|
+
self.log_area.delete("1.0", tk.END)
|
|
299
|
+
self.log_area.config(state='disabled')
|
|
300
|
+
self.log("🧹 Journal effacé.")
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# --- Exécution ---
|
|
304
|
+
if __name__ == "__main__":
|
|
305
|
+
root = tk.Tk()
|
|
306
|
+
app = MQTTSerialBridgeApp(root)
|
|
307
|
+
root.mainloop()
|
|
308
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pymqttusb_tk
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Connexion USB <-> MQTT (SSL ou WSS) avec interface Tkinter
|
|
5
|
+
Home-page: https://github.com/didierorlandi/pymqttusb_tk
|
|
6
|
+
Author: Didier Orlandi
|
|
7
|
+
Author-email: didier.orlandi06@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Topic :: Communications
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
14
|
+
Classifier: Environment :: MacOS X
|
|
15
|
+
Classifier: Environment :: X11 Applications :: GTK
|
|
16
|
+
Requires-Python: >=3.6
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENCE
|
|
19
|
+
Requires-Dist: paho-mqtt<2.0.0
|
|
20
|
+
Requires-Dist: pyserial>=3.5
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: requires-dist
|
|
29
|
+
Dynamic: requires-python
|
|
30
|
+
Dynamic: summary
|
|
31
|
+
|
|
32
|
+
#pymqttusb-tk
|
|
33
|
+
|
|
34
|
+
Permet la connexion d'un microprocesseur branché sur un port usb vers un serveur MQTT.<br />
|
|
35
|
+
|
|
36
|
+
L'affichage graphique permet de configurer le broker <br />
|
|
37
|
+
Contenu du fichier "arduino_mqtt_data.json" :<br />
|
|
38
|
+
|
|
39
|
+
-----------<br />
|
|
40
|
+
|
|
41
|
+
Le topic de réception sera : salle/KEY/out<br />
|
|
42
|
+
|
|
43
|
+
Le topic d'envoi sera : salle/KEY/in<br />
|
|
44
|
+
|
|
45
|
+
Les protocoles possibles sont "wss" websockets sécurisés avec login et mot de passe ( pas de certificat)
|
|
46
|
+
ou "tcp" pour ssl avec login et mot de passe ( pas de certificats client) <br />
|
|
47
|
+
|
|
48
|
+
Lancement du programme :<br />
|
|
49
|
+
|
|
50
|
+
py -m pymqttusb-tk.main <br />
|
|
51
|
+
|
|
52
|
+
<br />
|
|
53
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENCE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
pymqttusb_tk/__init__.py
|
|
5
|
+
pymqttusb_tk/main.py
|
|
6
|
+
pymqttusb_tk.egg-info/PKG-INFO
|
|
7
|
+
pymqttusb_tk.egg-info/SOURCES.txt
|
|
8
|
+
pymqttusb_tk.egg-info/dependency_links.txt
|
|
9
|
+
pymqttusb_tk.egg-info/requires.txt
|
|
10
|
+
pymqttusb_tk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pymqttusb_tk
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import setuptools
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setuptools.setup(
|
|
7
|
+
name="pymqttusb_tk",
|
|
8
|
+
version="1.0.1",
|
|
9
|
+
author="Didier Orlandi",
|
|
10
|
+
author_email="didier.orlandi06@gmail.com",
|
|
11
|
+
description="Connexion USB <-> MQTT (SSL ou WSS) avec interface Tkinter",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/didierorlandi/pymqttusb_tk",
|
|
15
|
+
packages=setuptools.find_packages(),
|
|
16
|
+
include_package_data=True,
|
|
17
|
+
classifiers=[
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Topic :: Communications",
|
|
22
|
+
"Intended Audience :: Education",
|
|
23
|
+
"Environment :: Win32 (MS Windows)",
|
|
24
|
+
"Environment :: MacOS X",
|
|
25
|
+
"Environment :: X11 Applications :: GTK",
|
|
26
|
+
],
|
|
27
|
+
python_requires=">=3.6",
|
|
28
|
+
install_requires=[
|
|
29
|
+
"paho-mqtt<2.0.0",
|
|
30
|
+
"pyserial>=3.5",
|
|
31
|
+
],
|
|
32
|
+
)
|