Forum: Mikrocontroller und Digitale Elektronik MQTT+PubSubClient+subscribe


von Timo (Gast)


Lesenswert?

Hallo,

versuche mich hier vergeblich an einer MQTT Auswertung via CloudMQTT und 
benutzte dabei die Library "PubSubClient.H"; Hardware ist ein ESP8266

Publishen funktioniert problemlos, nur beim Subscribe bekomme ich nichts 
zurück.
Das angefügte Beispiel schickt alle 5sek Daten an den MQTT Server und 
müsste ja dann sofort eine Rückmeldung geben - das passiert aber nicht. 
Auch direktes Eintragen in die GUI auf CloudMQTT bleibt ohne Reaktion.

Hat jemand 'ne Idee was falsch ist?

Gruß
Timo
1
#include <ESP8266WiFi.h>
2
#include <PubSubClient.h>
3
4
5
#define wifi_ssid "My_SSID"
6
#define wifi_password "My_PW"
7
8
#define mqtt_server "m20.cloudmqtt.com"
9
#define mqtt_user "user" 
10
#define mqtt_password "password" //
11
12
13
14
#define humidity_topic "tr_test"
15
#define cloudmqttport 17208
16
WiFiClient espClient;
17
18
PubSubClient client(mqtt_server, cloudmqttport,callback,espClient);
19
20
21
void setup() {
22
  Serial.begin(115200);
23
  setup_wifi();
24
 // client.setServer(mqtt_server, 17208); // dieser Port ist wichtig
25
  //client.setCallback(callback);
26
  //client.subscribe(humidity_topic);
27
28
  }
29
30
void setup_wifi() {
31
  delay(10);
32
  // We start by connecting to a WiFi network
33
  Serial.println();
34
  Serial.print("Connecting to ");
35
  Serial.println(wifi_ssid);
36
37
  WiFi.begin(wifi_ssid, wifi_password);
38
39
  while (WiFi.status() != WL_CONNECTED) {
40
    delay(500);
41
    Serial.print(".");
42
  }
43
44
  Serial.println("");
45
  Serial.println("WiFi connected");
46
  Serial.println("IP address: ");
47
  Serial.println(WiFi.localIP());
48
}
49
50
void reconnect() {
51
  // Loop until we're reconnected
52
  while (!client.connected()) {
53
    Serial.print("Attempting MQTT connection...");
54
    // Attempt to connect
55
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
56
      Serial.println("connected");
57
    } else {
58
      Serial.print("failed, rc=");
59
      Serial.print(client.state());
60
      Serial.println(" try again in 5 seconds");
61
      // Wait 5 seconds before retrying
62
      delay(5000);
63
    }
64
  }
65
}
66
67
68
long lastMsg = 0;
69
float temp = 0.0;
70
float hum = 0.0;
71
float diff = 1.0;
72
73
void loop() {
74
  if (!client.connected()) {
75
    reconnect();
76
  }
77
  
78
  client.loop();
79
80
  long now = millis();
81
  if (now - lastMsg > 5000) {
82
    lastMsg = now;
83
84
    float newHum = random(0,100);
85
86
    if (newHum != hum) {
87
      hum = newHum;
88
       //Serial.print("New humidity:");
89
       //Serial.println(String(hum).c_str());
90
      client.publish(humidity_topic, String(hum).c_str(), true);
91
    }
92
  }
93
}
94
95
void callback(char* topic, byte* payload, unsigned int length) {
96
  Serial.print("Message arrived [");
97
  Serial.print(topic);
98
  Serial.print("] ");
99
  for (int i = 0; i < length; i++) {
100
    Serial.print((char)payload[i]);
101
  }
102
  Serial.println();
103
}

von Michael U. (amiga)


Lesenswert?

Hallo,

ich spiele auch gerade etwas mit MQTT rum. CloudMQTT habe ich nicht 
benutzt, bei mit läuft ein Mosquitto unter Windows zum Testen. Da sehe 
ich wenigstens, was passiert. Testclient ist MQTT.fx unter Windows.
Seit vorhin gibt es auch ein altes Pearl-Laufschrift-Display mit ESP 
drin als Actor.
Mosquitto habe ich vorhan auf dem soweiso nur rumliegenden RasPi 
intstallert und meinen Test-ESP, der sinnigerweise EANs scannt und 
published angeworfen.

Sicher sie "sinnvollste" Anwendung: das Display zeigt per MQTT eine 
gescannte EAN an...

Wenn CloudMQTT als reiner Broker funktioniert, müßtest Du ja Deinen 
eigenen topic subscriben können und Dir an die serielle schicken lassen.

Gruß aus Berlin
Michael

von Timo (Gast)


Lesenswert?

Hi,
habe mich jetzt nochmals intensiv mit dem Thema beschäftigt und mein 
vermeindlichen Fehler gefunden: Nach dem Reconnect muss ein Subscribe 
erfolgen, dann klappt es auch.

CloudMQTT lässt auch über das GUI eine Sicht auf die Daten zu, noch dazu 
nutze ich ein Android-Tool "MyMQTT", welches astreine Dienste leistet.

Gruß
Timo

von Michael U. (amiga)


Lesenswert?

Hallo,

naja, Dein angehängtes Programm hat ja auch nur als Publisher die Daten 
des Feuchtesenders zum Brooker geschickt. Mit QoS = 0 wird die Nachricht 
genau einmal an den Brooker gesendet.
Subscribe sagt dem Brooker ja erst, daß Du Nachrichten mit diesem Topic 
erhalten willst.

Du hast zwar in
client.publish(humidity_topic, String(hum).c_str(), true);
retained auf true gesetzt, dann mußt Du aber den Rückgabewert auswerten, 
wenn Du nur wissen willst, ob die Nachricht beim Brooker angekommen ist.

Müßte dann wohl
1
 bool test = client.publish(humidity_topic, String(hum).c_str(), true);
2
 if (test)
3
 {
4
   Serial.println("Nachricht angekommen");
5
 }
6
 {
7
   Serial.println("Nachricht NICHT angekommen");
8
 }

aussehen. Habe ich selber aber noch nicht benutzt.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Dan (Gast)


Lesenswert?

Hallo

Weißt Jemand wie man MQTT mit Sicherheit in der Industrie implementieren 
kann?

Gruß

Dan

von damichl (Gast)


Lesenswert?

Ja.

von Dan (Gast)


Lesenswert?

Also ich brauche interessante Quellen für die Security bei der Anwendung 
der MQTT.

Vielen Dank

von Jay (Gast)


Lesenswert?

Dan schrieb:
> Weißt Jemand wie man MQTT mit Sicherheit in der Industrie implementieren
> kann?

Ja, ich weiß es, aber die Antwort wird dir nicht gefallen.

MQTT ist sicherheitmäßig eine Katastrophe. Username/Password im 
Klartext, das ist alles was MQTT an "Sicherheit" bietet. Ein Witz.

MQTTs Antwort drauf ist MQTT über TLS laufen zu lassen. Klar, kann man 
machen. Bei der Implementierung von TLS, auch wenn man eine Bibliothek 
verwendet, kann man als nicht Crypto-Experte so viele Fehler machen, 
dass das Ergebnis nicht mehr als Kosmetik ist. Wählt man eine 
fehleranfällige Bibliothek (räusper OpenSSL räusper), kann man sich 
TLS fast schon schenken.

Alles das ist besonders unschön, da MQTT aus der SCADA-Welt kommt und 
man dort eigentlich erhöhte Sicherheitsanforderungen hat. Das 
interessiert in der SCADA-Welt niemanden :-( Ich rechne in den nächsten 
Jahrzehnten mit sehr vielen gehackten Industrieanwendungen. Ein Fest für 
Hacker.

Warum ist MQTTs Antwort "dann nimm doch TLS" zu billig? Industrien, die 
sich wirklich um Sicherheit bemühen, wie in der Luftfahrt, haben es auf 
die harte Tour gelernt. Der Effekt wird mit dem Swiss Cheese Model 
beschrieben https://en.wikipedia.org/wiki/Swiss_cheese_model .

Sicherheitslayer haben Löcher. Daher legt man mehrere übereinander (also 
nicht wie bei MQTT nichts machen, selber ein einziges großes 
Sicherheitsloch sein und sich einfach auf TLS verlassen). Sogar wenn man 
viele Layer übereinander legt geht es manchmal noch schief (-> 
Flugzeugabsturz). Aber seltener als wenn man keine Layer übereinander 
legt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.