Gelöst: MQTT EMON ESP-LINK Kombination

Begonnen von sabom.2d, 31 März 2017, 07:48:54

Vorheriges Thema - Nächstes Thema

sabom.2d

Hallo FHEM-Fangemeinde,

ich mach dann hier im neuen Themenbereich MQTT mal den Anfang.
Aber zu erst mal: vielen Dank an Rince, für die beiden Einführungsteile.

Nun zu meinem Problem:
Ich möchte gerne den Stromverbrauch am Verteiler ermitteln, dazu habe ich 3 CT sensoren an einen Arduino gekoppelt. Dieser Prozess läuft und liefert im Seriellen Monitor auch die Werte zurück.
Allerdings möchte ich diesen Arduino nun mittels esp-link und MQTT an das FHEM system koppeln, und da stoße ich jetzt auf Probleme. Nun stehe ich mit MQTT noch auf Kriegsfuß und bin leider nicht in der Lage, selber den Fehler zu sehen. Anbei der Arduino sketch, den ich aus verschiedenen Sketchen zusammengebaut habe, auf dem ESP8266 läuft wie gesagt esp-link mit MQTT, in FHEM hab ich jetzt mal zwei emon MQTT devices angelegt, aber erhalte keine Werte in FHEM. Vielleicht kann sich da ja mal jemand anschauen, und mir sagen, wo ich einen Fehler eingebaut habe.


#include "EmonLib.h"                   // Include Emon Library
#include "PubSubClient.h"
//#include "ESP8266WiFi.h"         // Unnötig wegen esp
#define mqtt_server "192.168.90.40"

EnergyMonitor emon1;                   // Create an instance
EnergyMonitor emon2;             // Create an instance
EnergyMonitor emon3;             // Create an instance

#define topic1 "emon1"
#define topic2 "emon2"
#define topic3 "emon3"

//WiFiClient eClient; den Brauche ich ja nicht, da der esp das ja übernímmt
PubSubClient client;
void setup() {
    Serial.begin(115200);
   // setup_wifi();
    client.setServer(mqtt_server, 1883);
    emon1.current(1, 60);             // Current: input pin, calibration.
    emon2.current(2, 60);             // Current: input pin, calibration.
    emon3.current(3, 60);             // Current: input pin, calibration.
  //calibration is explained bellow
}

void pubMQTT(String topic,float topic_val){
    Serial.print("Newest topic " + topic + " value:");
    Serial.println(String(topic_val).c_str());
    client.publish(topic.c_str(), String(topic_val).c_str(), true);
}

void loop()
{
    double valIrms1 = emon1.calcIrms(1480);
    double valIrms2 = emon2.calcIrms(1480);
    double valIrms3 = emon3.calcIrms(1480);  // Calculate Irms only

  //Serial.print(Irms*230.0);         // Apparent power >>Das war der alte code nur für Serielle Ausgabe
  //Serial.print(" ");
  //Serial.println(Irms);          // Irms

    Serial.print(valIrms1); // Current1 reading
    pubMQTT(topic1,valIrms1);
    Serial.print(" ");
    Serial.print(valIrms1*230); // Apparent Power = I*V = I*230 
    Serial.print(" | ");
    Serial.print(valIrms2); // Current2 reading
    pubMQTT(topic2,valIrms2);
    Serial.print(" ");
    Serial.print(valIrms2*230); // Apparent Power = I*V = I*230
    Serial.print(" | ");
    Serial.print(valIrms3); // Current3 reading
    pubMQTT(topic3,valIrms3);
    Serial.print(" ");
    Serial.println(valIrms3*230); // Apparent Power = I*V = I*230
}





Hier die definition in fhem.cfg:


define MQTT_STROM MQTT_DEVICE
attr MQTT_STROM IODev TEC_MQTT_BROKER
attr MQTT_STROM room MQTT
attr MQTT_STROM stateFormat transmission-state
attr MQTT_STROM subscribeReading_.* 1
attr MQTT_STROM subscribeReading_emon1 emon1
attr MQTT_STROM subscribeReading_emon2 emon2
attr MQTT_STROM verbose 5


Und im Anhang so stellt sich das FHME device dar......

Gruß

sabom
Vielleicht findet ja jemand den Fehler....oder schubst mich in die richtige Richtung

bartman121

#1
ich bin da nicht der Profi, aber deine in fhem-subribed_readings sehen komisch aus....

am besten du schaust erstmal was auf dem Broker ankommt, wenn deine Devices publishen:
mosquitto_sub -d -v -t \#

Ansonsten bin ich mir relativ sicher, dass topics mit "\" beginnen ....

hier nur mal ein Beispiel:
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoff_dht/DHT/TEMPERATURE', ... (6 bytes))
tele/sonoff_dht/DHT/TEMPERATURE 21.8 C


hier wäre dann das zu subscibrende-topic: tele/sonoff_dht/DHT/TEMPERATURE

sabom.2d

#2
Hallo bartman,

danke für den Schubser, werd ich ausprobieren und mich wieder melden.......

Ok, so wies aussieht kommt da von dem Arduino nix an, ich hab zu Testzwecken einen ESp laufen, der einfach zwei Temperturmessungen vorgaukelt, und diese Daten kommen an:

Client mosqsub/29750-raspberry received PUBLISH (d0, q0, r0, m0, 't1', ... (5 bytes))
t1 46.00
Client mosqsub/29750-raspberry received PUBLISH (d0, q0, r0, m0, 't2', ... (5 bytes))
t2 21.00


aber von dem Strom Arduino kommt da nix an. Hab ja schon vermutet, dass der Sketch fehlerhaft ist. Ich bin für jeden weiteren Schubser dankbar.....leider kann ich den Sketch nur ändern wenn ich davor sitze, da der Arduino sich nur noch per USBasp flaschen läßt, d.h. abklemmen programmieren, wieder anklemmen, schauen was sich ändert......

Und zu deinem Hinweis mit dem Backslash kann ich jetzt nur das wiedergeben, wie es in dem Beispiel mit den Temperaturen drin steht : einfach t1 ohne Backslash, zum Testen funktionert das.....

Vielleicht wirft ja noch ein MQTT Fachman einen Blick drauf und sieht direkt welche Anfängerfehler ich gemacht hab.




Rince


//#include "ESP8266WiFi.h"         // Unnötig wegen esp


Das halte ich für einen Trugschluss. Du musst sicherlich die Library auch benutzen. Woher soll der ESP wissen welches WLAN er nehmen soll, wie das Passwort ist etc???
Vom Management der Verbindung ganz abgesehen.
Wer zu meinen Posts eine Frage schreibt und auf eine Antwort wartet, ist hiermit herzlich eingeladen mich per PN darauf aufmerksam zu machen. (Bitte mit Link zum betreffenden Thread)

sabom.2d

#4
Hallo Rince,

das Wlan handling macht der ESP ja schon per esp-link, ich muß denke ich im Arduino nur die MQTT Dinge definieren.  Kann natürlich mal ausprobieren, ob es zusätzlich nötig ist, das auch im Arduino sketch zu definieren...
Hab zwischenzeitlich mal die el-client Bibliothek probiert und das dazugehörige MQTT Besipiel zum Testen aufgespielt, aber dort wird seltsamer Weise noch nicht einmal der MQTT Server angegeben....oder ich hab Tomaten auf den Augen und seh nicht wo man das einträgt. Ich häng es mal mit an.....
hier die Quelle
https://github.com/jeelabs/el-client/tree/master/ELClient/examples/mqtt

hier der beigefügte Beispielsketch für Mqtt über esp-link

/**
* Simple example to demo the esp-link MQTT client
*/

#include <ELClient.h>
#include <ELClientCmd.h>
#include <ELClientMqtt.h>

// Initialize a connection to esp-link using the normal hardware serial port both for
// SLIP and for debug messages.
ELClient esp(&Serial, &Serial);

// Initialize CMD client (for GetTime)
ELClientCmd cmd(&esp);

// Initialize the MQTT client
ELClientMqtt mqtt(&esp);

// Callback made from esp-link to notify of wifi status changes
// Here we just print something out for grins
void wifiCb(void* response) {
  ELClientResponse *res = (ELClientResponse*)response;
  if (res->argc() == 1) {
    uint8_t status;
    res->popArg(&status, 1);

    if(status == STATION_GOT_IP) {
      Serial.println("WIFI CONNECTED");
    } else {
      Serial.print("WIFI NOT READY: ");
      Serial.println(status);
    }
  }
}

bool connected;

// Callback when MQTT is connected
void mqttConnected(void* response) {
  Serial.println("MQTT connected!");
  mqtt.subscribe("/esp-link/1");
  mqtt.subscribe("/hello/world/#");
  //mqtt.subscribe("/esp-link/2", 1);
  //mqtt.publish("/esp-link/0", "test1");
  connected = true;
}

// Callback when MQTT is disconnected
void mqttDisconnected(void* response) {
  Serial.println("MQTT disconnected");
  connected = false;
}

// Callback when an MQTT message arrives for one of our subscriptions
void mqttData(void* response) {
  ELClientResponse *res = (ELClientResponse *)response;

  Serial.print("Received: topic=");
  String topic = res->popString();
  Serial.println(topic);

  Serial.print("data=");
  String data = res->popString();
  Serial.println(data);
}

void mqttPublished(void* response) {
  Serial.println("MQTT published");
}

void setup() {
  Serial.begin(115200);
  Serial.println("EL-Client starting!");

  // Sync-up with esp-link, this is required at the start of any sketch and initializes the
  // callbacks to the wifi status change callback. The callback gets called with the initial
  // status right after Sync() below completes.
  esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
  bool ok;
  do {
    ok = esp.Sync();      // sync up with esp-link, blocks for up to 2 seconds
    if (!ok) Serial.println("EL-Client sync failed!");
  } while(!ok);
  Serial.println("EL-Client synced!");

  // Set-up callbacks for events and initialize with es-link.
  mqtt.connectedCb.attach(mqttConnected);
  mqtt.disconnectedCb.attach(mqttDisconnected);
  mqtt.publishedCb.attach(mqttPublished);
  mqtt.dataCb.attach(mqttData);
  mqtt.setup();

  //Serial.println("ARDUINO: setup mqtt lwt");
  //mqtt.lwt("/lwt", "offline", 0, 0); //or mqtt.lwt("/lwt", "offline");

  Serial.println("EL-MQTT ready");
}

static int count;
static uint32_t last;

void loop() {
  esp.Process();

  if (connected && (millis()-last) > 4000) {
    Serial.println("publishing");
    char buf[12];

    itoa(count++, buf, 10);
    mqtt.publish("/esp-link/1", buf);

    itoa(count+99, buf, 10);
    mqtt.publish("/hello/world/arduino", buf);

    uint32_t t = cmd.GetTime();
    Serial.print("Time: "); Serial.println(t);

    last = millis();
  }
}




wenn ich den seriellen monitor zum Arduino öffne, sagt der auch Wlan verbunden, aber am FHEM kommt ebenfalls nix an.....


sabom.2d

#5
Update:

ich hab jetzt mal bei beiden esp-links (63 und 68) das Statusreporting eingeschaltet, damit hat man eine gute Möglichkeit festzustellen, ob MQTT überhaupt funktioniert, und siehe da, sowohl der Testesp (68) als auch der esp-link mit dem gekoppelten Arduino für die Strommessung funktionieren und senden beide iher Statusinformationen ( siehe Screenshot im Anhang ), Jetze besteht nur die Frage, wie setze ich das im Arduinosketch um, dass dessen Werte auch per MQTT durch den esp-link an FHEM geschikt werden......
und da sind wir wieder bei meinem Problem......wie setzte ich das in code um....?

sabom.2d

Update #2:
Bin jetzt der Lösung einen Schritt näher gekommen:
hab den el-client Testsketch nochmal aufgespielt, MQTT publish im sketch eingeschaltet, vorher waren nämlich nur subscirbes aktiv:

// Callback when MQTT is connected
void mqttConnected(void* response) {
  Serial.println("MQTT connected!");
  //mqtt.subscribe("/esp-link/1");
  //mqtt.subscribe("/hello/world/#");
  //mqtt.subscribe("/esp-link/2", 1);
  [i]mqtt.publish("/esp-link/0", "test1");[/i]
  connected = true;
}



und wohl vorher vergessen im esp-link unter REST/MQTT den SLIP support eingschaltet, und siehe da im Seriellen Monitor wird sofort eine erfolgreiche Verbindung zum MQTT-Server und das erfolgreiche publish der Werte angezeigt.

Zur Kontrolle hab ich das topic "/esp-link/0" noch im MQTT.Fx aboniert und auch dort wurden sofort die Werte dargestellt, soweit so gut,  nun muß ich in diesem Sketchnnoch irgendwie die emon Angelegenheiten unterbringen, da ich am WE dazu keine Zeit habe, muß das leider bis zur nächsten Woche warten.

Gruß und genießt das kommende WE

sabom

sabom.2d

was lange währt.....

hab das Problem jetzt nach dem Urlaub gelöst.
Eine falsche Verbindung der Kontakte war dafür verantwortlich, dass gar keine MQTT Werte gesendet wurden.
Manchmal lohnt es sich ein Problem mit Abstand neu zu betrachten.....
Nachdem das jetzt behoben ist, funktioniert die Kombi auch, esp-link kümmert sich ums Netzwerk, der Nano um die MQTT und emon Werte.
Allerdings nutze ich nicht die PubSubClient Bibliothek, sondern el-Client.h in Verbindung mit emon.h.
Nur die Schwankungsbreite der Werte macht noch etwas Kopfzerbrechen, das muß ich nochmals genauer überprüfen.

Gruß

sabom