{"id":10295,"date":"2019-05-19T22:13:45","date_gmt":"2019-05-19T20:13:45","guid":{"rendered":"https:\/\/pi3g.com\/?p=10295"},"modified":"2019-05-19T22:14:11","modified_gmt":"2019-05-19T20:14:11","slug":"python-paho-mqtt-client-self-signed-certificates-websockets-howto","status":"publish","type":"post","link":"https:\/\/pi3g.com\/de\/python-paho-mqtt-client-self-signed-certificates-websockets-howto\/","title":{"rendered":"Python Paho MQTT-Client selbstsignierte Zertifikate Websockets, howto"},"content":{"rendered":"<p>Using Paho in Python with websockets and self-signed certificates for a https:\/\/ websocket connection has a couple of pitfalls, so I\u2019m addressing this with some sample code here:<\/p>\n<blockquote>\n<p>import ssl<br \/>\nimport time<br \/>\nimport paho.mqtt.client as mqtt<\/p>\n<p>\nclass PCPMQTTClient:<br \/>&nbsp;&nbsp;&nbsp;&nbsp; def on_connect(self, client, userdata, flags, rc):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connection_status = rc<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if rc == 0:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connected_flag = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connection_error_flag = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connected_flag = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connection_error_flag = True<\/p>\n<p>&nbsp;&nbsp;&nbsp; # called when a mesage that was to be sent using publish()<br \/>&nbsp;&nbsp;&nbsp;&nbsp; # has completed transmission to the broker<br \/>&nbsp;&nbsp;&nbsp;&nbsp; # for qos=0 -&gt; message has left the client<br \/>&nbsp;&nbsp;&nbsp;&nbsp; # for qos=1 &amp; 2 -&gt; handshakes have been completed.<br \/>&nbsp;&nbsp;&nbsp;&nbsp; # mid variable matches mid variable which publish() returns<br \/>&nbsp;&nbsp;&nbsp;&nbsp; def on_publish(self, client, userdata, mid):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.verbose:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;publish callback mid: &#8221; + str(mid))<\/p>\n<p>&nbsp;&nbsp;&nbsp; def on_log(client, userdata, level, buf):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(buf)<\/p>\n<p>&nbsp;&nbsp;&nbsp; def testconnection(self):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self.connect(test=True)<\/p>\n<p>&nbsp;&nbsp;&nbsp; def connect(self, test=False):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if test:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;Connecting to MQTT&#8221;, end=&#8221;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connection_status = -1&nbsp; # no connection attempts yet<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connection_error_flag = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.connect_async(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host=self.connectiondata[&#8216;host&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port=self.connectiondata[&#8216;port&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keepalive=60,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bind_address=&#8221;&#8221;)\n<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.loop_start()&nbsp; # according to Steve better AFTER connect<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue_flag = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keep_connection_flag = not test<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout_counter = 0<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while not continue_flag:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(1)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout_counter += 1<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if test:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;.&#8221;, end=&#8221;)&nbsp; # end=&#8221; will suppress newline<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.connected_flag:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue_flag = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if timeout_counter &gt; 6:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue_flag = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keep_connection_flag = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code = self.connection_status<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if code == 0:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection successful!&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connected_flag = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not keep_connection_flag:&nbsp; # necessary to be this, to detect if we are not able to connect!<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.disconnect()&nbsp; # clean disconnect from server<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif code == -1:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection timed out &#8211; server not online? Certificate error (try &#8211;selfsigned)?&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif code == 1:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection refused &#8211; incorrect protocol version&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif code == 2:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection refused &#8211; invalid client identifier&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif code == 3:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection refused &#8211; server unavailable&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif code == 4:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection refused &#8211; bad username or password&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif code == 5:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Connection refused &#8211; not authorised&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message = &#8220;Another error &#8221; + str(code) + &#8221; occured, please check the Paho documentation&#8221;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8221;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return {&#8220;success&#8221;: success, &#8220;code&#8221;: code, &#8220;message&#8221;: message}<\/p>\n<p>&nbsp;&nbsp;&nbsp; def publish(self, topic, message, qos=0, retain=False):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code = &#8216;PCP_WRONG_INPUTFORMAT&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error_message = &#8216;Wrong input format of data (e.g. topic cannot be Null)&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if topic:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pubresult = self.mqttc.publish(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; topic=topic,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; payload=message,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; qos=qos,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retain=retain)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # process pubresult<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if pubresult.rc == mqtt.MQTT_ERR_SUCCESS:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code = &#8216;MQTT_ERR_SUCCESS&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error_message = &#8216;Successfully sent message to broker.&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif pubresult.rc == mqtt.MQTT_ERR_NO_CONN:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code = &#8216;MQTT_ERR_NO_CONN&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error_message = &#8216;No connection to MQTT server, try to reconnect&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elif pubresult.rc == mqtt.MQTT_ERR_QUEUE_SIZE:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code = &#8216;MQTT_ERR_QUEUE_SIZE&#8217;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error_message = &#8216;Message is neither queued nor sent.&#8217;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return {&#8220;success&#8221;: success, &#8220;code&#8221;: code, &#8220;message&#8221;: error_message, &#8220;mid&#8221;: pubresult.mid}<\/p>\n<p>&nbsp;&nbsp;&nbsp; def disconnect(self):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # as per steve <a href=\"http:\/\/www.steves-internet-guide.com\/client-connections-python-mqtt\/\">http:\/\/www.steves-internet-guide.com\/client-connections-python-mqtt\/<\/a><br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.loop_stop()<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.disconnect()<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connected_flag = False<\/p>\n<p>&nbsp;&nbsp;&nbsp; def __init__(self, connectiondata, verbose=False, insecure=False):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.verbose = verbose<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clean_session = True<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc = mqtt.Client(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client_id=connectiondata[&#8216;client_id&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clean_session=clean_session,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userdata=None,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protocol=mqtt.MQTTv311,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transport=connectiondata[&#8216;transport&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connectiondata = connectiondata<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.connected_flag = False<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.on_connect = self.on_connect<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.on_publish = self.on_publish<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.verbose:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;### enabling logging for MQTT Client ###&#8221;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.on_log = self.on_log<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.username_pw_set(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username=connectiondata[&#8216;username&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password=connectiondata[&#8216;password&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if connectiondata[&#8216;transport&#8217;] == &#8220;websockets&#8221;:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.ws_set_options(path=self.connectiondata[&#8216;path&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.verbose:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;### connecting with the following parameters ###&#8221;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;* client_id: &#8221; + connectiondata[&#8216;client_id&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;* clean_session: &#8221; + str(clean_session))<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;* transport: &#8221; + connectiondata[&#8216;transport&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;* path: &#8221; + connectiondata[&#8216;path&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;* username: &#8221; + connectiondata[&#8216;username&#8217;])<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;* password: (not being shown!)&#8221;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # self.mqttc.tls_set_context()<br \/><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if insecure:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.tls_set(cert_reqs=ssl.CERT_NONE)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if self.verbose:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(&#8220;### insecure operation mode (&#8211;selfsigned) set! ###&#8221;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.tls_insecure_set(True)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.tls_set()<\/strong>\n<\/p>\n<\/blockquote>\n<p>As you can see, it is important to do TWO things for an insecure connection:<\/p>\n<ul>\n<li>tls_set(cert_reqs=ssl.CERT_NONE)<\/li>\n<li>tls_insecure_set(True)<\/li>\n<\/ul>\n<p>The tls_insecure_set(True) call will allow you to omit certificate name matching. It will still try to ensure that the certificate is <strong>valid <\/strong>as per the certificate chain!<\/p>\n<p>Thus it is a bit of a misnomer, I guess. <\/p>\n<p>The sample code shown above is part of a development on picockpit-client, for the <a href=\"https:\/\/picockpit.com\" target=\"_blank\">picockpit.com platform<\/a><\/p>\n<h2>Paho \/ Websockets<\/h2>\n<p>connectiondata[\u2018transport\u2019] is set elsewhere in the code. It can be either (a string) \u201ctcp\u201d or \u201cwebsockets\u201d. <\/p>\n<p>If you specify websockets, you can additionally use ws_set_options to set a path, for example \u201c\/mqtt\u201d. <\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host=self.connectiondata[&#8216;host&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port=self.connectiondata[&#8216;port&#8217;],<\/p>\n<p>the host is your webhost \u2013 without http \/ https prefix. For local development, for instance, I use \u201cpicockpit.local\u201d (proxied through envoy, see my other articles). <\/p>\n<p>the port, in the case of a TLS \/ SSL connection over the default https port is 443<\/p>\n<h2>Suggestion for easier debugging: <\/h2>\n<p>For better debugging switch from the async connection code to a synchronious connection (replace connect_async): <\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.mqttc.connect(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host=self.connectiondata[&#8216;host&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port=self.connectiondata[&#8216;port&#8217;],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keepalive=60,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bind_address=&#8221;&#8221;)<\/p>\n<h1>References:<\/h1>\n<ul>\n<li><a href=\"https:\/\/github.com\/eclipse\/paho.mqtt.python\/issues\/85\">https:\/\/github.com\/eclipse\/paho.mqtt.python\/issues\/85<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/eclipse\/paho.mqtt.python\/issues\/148\">https:\/\/github.com\/eclipse\/paho.mqtt.python\/issues\/148<\/a><\/li>\n<li><a href=\"https:\/\/aws.amazon.com\/blogs\/iot\/how-to-implement-mqtt-with-tls-client-authentication-on-port-443-from-client-devices-python\/\">https:\/\/aws.amazon.com\/blogs\/iot\/how-to-implement-mqtt-with-tls-client-authentication-on-port-443-from-client-devices-python\/<\/a><\/li>\n<li><a href=\"https:\/\/www.eclipse.org\/paho\/clients\/python\/docs\/\">https:\/\/www.eclipse.org\/paho\/clients\/python\/docs\/<\/a> \u2013 the official Paho Python documentation<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Die Verwendung von Paho in Python mit Websockets und selbstsignierten Zertifikaten f\u00fcr eine https:\/\/ Websocket-Verbindung birgt einige Fallstricke, die ich hier mit etwas Beispielcode angehe: import ssl import time import paho.mqtt.client as mqtt class PCPMQTTClient: def on_connect(self, client, userdata, flags, rc): self.connection_status = rc if rc == 0: self.connected_flag = True self.connection_error_flag...<\/p>","protected":false},"author":830,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[402,610],"tags":[598,572,611,612,613,602],"class_list":["post-10295","post","type-post","status-publish","format-standard","hentry","category-development","category-python","tag-paho","tag-python","tag-self-signed-certificates","tag-ssl","tag-tls","tag-websockets"],"_links":{"self":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/10295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/users\/830"}],"replies":[{"embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/comments?post=10295"}],"version-history":[{"count":2,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/10295\/revisions"}],"predecessor-version":[{"id":10297,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/10295\/revisions\/10297"}],"wp:attachment":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/media?parent=10295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/categories?post=10295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/tags?post=10295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}