10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication |
12 from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication |
13 |
13 |
14 import paho.mqtt.client as mqtt |
14 import paho.mqtt.client as mqtt |
|
15 |
|
16 from Utilities.crypto import pwConvert |
15 |
17 |
16 |
18 |
17 class MqttClient(QObject): |
19 class MqttClient(QObject): |
18 """ |
20 """ |
19 Class implementing a PyQt wrapper around the paho MQTT client. |
21 Class implementing a PyQt wrapper around the paho MQTT client. |
156 @type bool |
158 @type bool |
157 """ |
159 """ |
158 self.__mqttClient.will_set(topic, payload=payload, qos=qos, |
160 self.__mqttClient.will_set(topic, payload=payload, qos=qos, |
159 retain=retain) |
161 retain=retain) |
160 |
162 |
|
163 def setTLS(self, caCerts=None, certFile=None, keyFile=None): |
|
164 """ |
|
165 Public method to enable secure connections and set the TLS parameters. |
|
166 |
|
167 @param caCerts path to the Certificate Authority certificates file |
|
168 @type str |
|
169 @param certFile PEM encoded client certificate file |
|
170 @type str |
|
171 @param keyFile PEM encoded private key file |
|
172 @type str |
|
173 """ |
|
174 self.__mqttClient.tls_set(ca_certs=caCerts, certfile=certFile, |
|
175 keyfile=keyFile) |
|
176 |
161 def startLoop(self): |
177 def startLoop(self): |
162 """ |
178 """ |
163 Public method to start the MQTT client loop. |
179 Public method to start the MQTT client loop. |
164 """ |
180 """ |
165 self.__mqttClient.loop_start() |
181 self.__mqttClient.loop_start() |
208 this client to |
224 this client to |
209 @type str |
225 @type str |
210 @param options dictionary containing the connection options. This |
226 @param options dictionary containing the connection options. This |
211 dictionary should contain the keys "ClientId", "Keepalive", |
227 dictionary should contain the keys "ClientId", "Keepalive", |
212 "CleanSession", "Username", "Password", "WillTopic", "WillMessage", |
228 "CleanSession", "Username", "Password", "WillTopic", "WillMessage", |
213 "WillQos", "WillRetain" |
229 "WillQos", "WillRetain", "TlsEnable", "TlsCaCert", "TlsClientCert", |
|
230 "TlsClientKey" |
214 @type dict |
231 @type dict |
215 """ |
232 """ |
216 if options: |
233 if options: |
217 parametersDict = self.defaultConnectionOptions() |
234 parametersDict = self.defaultConnectionOptions() |
218 parametersDict.update(options) |
235 parametersDict.update(options) |
224 ) |
241 ) |
225 |
242 |
226 # step 2: set username and password |
243 # step 2: set username and password |
227 if parametersDict["Username"]: |
244 if parametersDict["Username"]: |
228 if parametersDict["Password"]: |
245 if parametersDict["Password"]: |
229 self.setUserCredentials(parametersDict["Username"], |
246 self.setUserCredentials( |
230 parametersDict["Password"]) |
247 parametersDict["Username"], |
|
248 pwConvert(parametersDict["Password"], encode=False)) |
231 else: |
249 else: |
232 self.setUserCredentials(parametersDict["Username"]) |
250 self.setUserCredentials(parametersDict["Username"]) |
233 |
251 |
234 # step 3: set last will data |
252 # step 3: set last will data |
235 if parametersDict["WillTopic"]: |
253 if parametersDict["WillTopic"]: |
241 self.setLastWill(parametersDict["WillTopic"], |
259 self.setLastWill(parametersDict["WillTopic"], |
242 willMessage, |
260 willMessage, |
243 parametersDict["WillQos"], |
261 parametersDict["WillQos"], |
244 parametersDict["WillRetain"]) |
262 parametersDict["WillRetain"]) |
245 |
263 |
246 # step 4: connect to server |
264 # step 4: set TLS parameters |
|
265 if parametersDict["TlsEnable"]: |
|
266 if parametersDict["TlsCaCert"] and \ |
|
267 parametersDict["TlsClientCert"]: |
|
268 # use self signed client certificate |
|
269 self.setTLS(caCerts=parametersDict["TlsCaCert"], |
|
270 certFile=parametersDict["TlsClientCert"], |
|
271 keyFile=parametersDict["TlsClientKey"]) |
|
272 elif parametersDict["TlsCaCert"]: |
|
273 # use CA certificate file |
|
274 self.setTLS(caCerts=parametersDict["TlsCaCert"]) |
|
275 else: |
|
276 # use default TLS configuration |
|
277 self.setTLS() |
|
278 |
|
279 # step 5: connect to server |
247 self.connectToServer(host, port=port, |
280 self.connectToServer(host, port=port, |
248 keepalive=parametersDict["Keepalive"]) |
281 keepalive=parametersDict["Keepalive"]) |
249 else: |
282 else: |
250 keepalive = self.defaultConnectionOptions["Keepalive"] |
283 keepalive = self.defaultConnectionOptions["Keepalive"] |
251 self.connectToServer(host, port=port, keepalive=keepalive, |
284 self.connectToServer(host, port=port, keepalive=keepalive, |
256 Public method to get a connection options dictionary with default |
289 Public method to get a connection options dictionary with default |
257 values. |
290 values. |
258 |
291 |
259 @return dictionary containing the default connection options. It has |
292 @return dictionary containing the default connection options. It has |
260 the keys "ClientId", "Keepalive", "CleanSession", "Username", |
293 the keys "ClientId", "Keepalive", "CleanSession", "Username", |
261 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain" |
294 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", |
|
295 "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey". |
262 @rtype dict |
296 @rtype dict |
263 """ |
297 """ |
264 return { |
298 return { |
265 "ClientId": "ERIC6_MQTT_MONITOR_CLIENT", |
299 "ClientId": "ERIC6_MQTT_MONITOR_CLIENT", |
266 "Keepalive": 60, |
300 "Keepalive": 60, |