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.
@@ -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,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,2 @@
1
+ paho-mqtt<2.0.0
2
+ pyserial>=3.5
@@ -0,0 +1 @@
1
+ pymqttusb_tk
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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
+ )