Autor Thema: Publishen von Fhem / Subscribieren bei einem eigenen Sketch funktioniert nicht  (Gelesen 247 mal)

Offline Gisbert

  • Full Member
  • ***
  • Beiträge: 313
  • Das Ziel ist das Ziel, oder so ähnlich !?
Liebe Forumsmitglieder,

ich habe einen Sketch auf einem Sonoff Dual, der einen Rollladen schaltet.

Der Sketch beinhaltet folgende Funktionen (bitte Nachsicht üben, falls die Begriffe nicht stimmen sollten:
a) Bei Eingabe der IP-Adresse des Sonoff Duals öffnet sich eine Webseite, mit der man den Rollladen steuern kann (Hoch, Runter, Luecke, Stop)
b) In Fhem gibt es einen Dummy, mit dem man den Rollladen schalten kann
c) Mit AMAD2 gibt es eine Sprachsteuerung, die ebenfalls den Rollladen schaltet

b) und c) haben mit dem Sketch eigentlich nichts zu tun, da Sie nur Befehle raussenden.

Mein Anliegen war es in Fhem eine Rückmeldung über den Schaltzustand des Rollladens zu bekommen.
Dazu habe ich MQTT in den Sketch implementiert.

Was bisher gut funktioniert, ist das Publishen vom Sonoff Dual / Subscribieren in Fhem.
Der umgekehrte Weg will einfach nicht funktionieren, d.h. Publishen in Fhem und Subscribieren auf dem Sonoff Dual.

Getest habe ich es mit MQTT.fx
- Subcribieren vom Sonoff Dual funktioniert (kein Wunder, das hat ja auch in Fhem funktioniert)
- Publishen von Fhem aus funktioniert, d.h. in MQTT.fx kommt es an, nicht aber auf dem Sonoff Dual

Das Forum hab ich schon erfolglos nach Hinweisen durchsucht.
Falls jemand eine Idee hat, warum das Empfangen von Nachrichten auf dem Sonoff Dual nicht funktioniert, würde ich mich sehr darüber freuen.

Meine Definition in Fhem:
defmod Rollladen MQTT_DEVICE
attr Rollladen IODev MyBroker
attr Rollladen icon fts_shutter_automatic
attr Rollladen publishSet_Terrasse_Luecke /Pub/Rollladen/Terrasse/Luecke
attr Rollladen publishSet_Terrasse_Set /Pub/Rollladen/Terrasse/Set
attr Rollladen room Mobile
attr Rollladen stateFormat Terrassentür: Terrasse
attr Rollladen subscribeReading_Terrasse /Rollladen/Terrasse

setstate Rollladen Terrassentür: Stop
setstate Rollladen 2017-07-17 15:15:58 Terrasse Stop
setstate Rollladen 2017-07-17 14:55:41 Terrasse_Luecke 5000
setstate Rollladen 2017-07-17 14:47:17 Terrasse_Set Hoch
setstate Rollladen 2017-07-17 15:15:58 transmission-state incoming publish received

Der Arduino-Sketch in den wesentliche Auszügen, die fürs Publishen notwendig sind (alles andere hab ich nicht hier reinkopiert, kann ich aber gerne zur Verfügung stellen):
// Update these with values suitable for your network.
byte mac[] = { 0x5C, 0xCF, 0x7F, 0xAA, 0xBB, 0xCC };
IPAddress ip(789, 123, 456, 78);
IPAddress MQTTserver(789, 123, 456, 55);

WiFiClient client;
PubSubClient MQTTclient(MQTTserver, 1883, callback, client);

// handle message arrived
void callback(char* topic, byte* payload, unsigned int length)
{
  payload[length] = '\0';
  String sPayload = String((char *)payload);
  String sTopic = String(topic);
    if (sTopic == "/Pub/Rollladen/Terrasse/Set")
      {
        if (sPayload == "Stop")
        {
          switch_relay(0);
          ulMotorEventEnd=millis();
          if(MQTTclient.connect("arduinoClient", "user", "passwd"))
          {
            MQTTclient.publish("/Rollladen/Terrasse","Stop");
          }
        }
        else if (sPayload == "Runter")
        {       
          delay(RELAISWAIT);       
          switch_relay(0);
          delay(MOTORWAIT);
          switch_relay(1);
          ulMotorEventEnd=millis()+EVENT;
          if(MQTTclient.connect("arduinoClient", "user", "passwd"))
          {
            MQTTclient.publish("/Rollladen/Terrasse","Runter");
          }       
        }
        else if (sPayload == "Luecke")
        {       
          delay(RELAISWAIT);       
          switch_relay(0);
          delay(MOTORWAIT);
          switch_relay(1);
          ulMotorEventEnd=millis()+zeit_luecke;
          if(MQTTclient.connect("arduinoClient", "user", "passwd"))
          {
            MQTTclient.publish("/Rollladen/Terrasse","Lücke");
          }       
        }
        else if (sPayload == "Hoch")
        {       
          delay(RELAISWAIT);       
          switch_relay(0);
          delay(MOTORWAIT);
          switch_relay(2);
          ulMotorEventEnd=millis()+EVENT;
          if(MQTTclient.connect("arduinoClient", "user", "passwd"))
          {
            MQTTclient.publish("/Rollladen/Terrasse","Hoch");
          }       
        }
      }
    if (sTopic == "/Pub/Rollladen/Terrasse/Luecke")
      zeit_luecke = sPayload.toInt();
}


long lastReconnectAttempt = 0;

boolean reconnect()
{
  if (MQTTclient.connect("arduinoClient", "user", "passwd"))
  {
    MQTTclient.publish("/Rollladen/Terrasse","online");
    MQTTclient.subscribe("/Pub/Rollladen/Terrasse/Set");
    MQTTclient.subscribe("/Pub/Rollladen/Terrasse/Luecke");   
  }
  return MQTTclient.connected();

void setup()
{
  Ethernet.begin(mac, ip);
  // Note - the default maximum packet size is 128 bytes.
  // If the combined length of clientId, username and password exceed this,
  // you will need to increase the value of MQTT_MAX_PACKET_SIZE in PubSubClient.h

  MQTTclient.loop();
}

void loop()
{
  if (!MQTTclient.connected())
  {
    long now = millis();
    if (now - lastReconnectAttempt > 5000)
    {
      lastReconnectAttempt = now;
      if (reconnect())
      {
        lastReconnectAttempt = 0;
      }
    }
  }
  else
  {
    MQTTclient.loop();
  }
}
« Letzte Änderung: 17 Juli 2017, 15:47:55 von Gisbert »
Fhem 5.8 auf RPi3 B, Homematic, ESP8266, Sonoff Dual, 1-Wire-Temperatursensoren, Wlan-Kamera

Offline Gisbert

  • Full Member
  • ***
  • Beiträge: 313
  • Das Ziel ist das Ziel, oder so ähnlich !?
Liebe Forumsmitglieder,

hat keiner eine Idee oder was Vergleichbares bei sich realisiert?
Das Problem scheint mir in den folgenden Zeilen zu liegen:

// handle message arrived
void callback(char* topic, byte* payload, unsigned int length)
{
  payload[length] = '\0';
  String sPayload = String((char *)payload);
  String sTopic = String(topic);
    if (sTopic == "/Pub/Rollladen/Terrasse/Set")
      {
        if (sPayload == "Stop")

Ich bin über jeden Vorschlag oder Hinweis dankbar.
Viele Grüße Gisbert
Fhem 5.8 auf RPi3 B, Homematic, ESP8266, Sonoff Dual, 1-Wire-Temperatursensoren, Wlan-Kamera

Offline Gisbert

  • Full Member
  • ***
  • Beiträge: 313
  • Das Ziel ist das Ziel, oder so ähnlich !?
Hallo,

ich wollte mich nochmals in Erinnerung rufen, denn ich bin noch nicht weitergekommen mit meinem Problem.
Falls jemand eine Idee hat, oder was ähnliches implementiert hatte, dann wäre es super, wenn ich hier Hilfe finden könnte.

Viele Grüße Gisbert
Fhem 5.8 auf RPi3 B, Homematic, ESP8266, Sonoff Dual, 1-Wire-Temperatursensoren, Wlan-Kamera

Offline dev0

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2824
    • _.:|:._
Wenn niemand helfen kann/will dann hilft nur debuggen...

Offline Gisbert

  • Full Member
  • ***
  • Beiträge: 313
  • Das Ziel ist das Ziel, oder so ähnlich !?
Hallo dev0,

debuggen ist schwierig bis unmöglich (?), zumindest für mich, da die beiden Relais über I2C am ESP8266 des Sonoff Duals hängen.
Eine sonst übliche serielle Ausgabe ist damit anscheinend nicht möglich.
Eine Idee wäre es, den Sketch auf einen "normalen" ESP8266 anstatt auf den Sonoff Dual zu flashen, dann hätte man den seriellen Monitor als Ausgabemöglichkeit.
Da ich weder über ausreichende Programmierkenntnisse verfüge, noch weiß, wie man beim debuggen vorgehen sollte, bleibt es schwierig.

Ich gebe nicht auf, es dauert dann nur länger, bis ich am Ziel bin.

Viele Grüße Gisbert
Fhem 5.8 auf RPi3 B, Homematic, ESP8266, Sonoff Dual, 1-Wire-Temperatursensoren, Wlan-Kamera

Offline PatrickR

  • Developer
  • Full Member
  • ****
  • Beiträge: 461
Hallo Gisbert!

debuggen ist schwierig bis unmöglich (?), zumindest für mich, da die beiden Relais über I2C am ESP8266 des Sonoff Duals hängen.
Eine sonst übliche serielle Ausgabe ist damit anscheinend nicht möglich.
Eine Idee wäre es, den Sketch auf einen "normalen" ESP8266 anstatt auf den Sonoff Dual zu flashen, dann hätte man den seriellen Monitor als Ausgabemöglichkeit.
Da ich weder über ausreichende Programmierkenntnisse verfüge, noch weiß, wie man beim debuggen vorgehen sollte, bleibt es schwierig.

Ich habe das in meinen Projekten quick'n'dirty implementiert und zwar über UDP:
// Debugging
#define DEBUG
#define DEBUG_HOSTNAME                    "epsilon"
#define DEBUG_PORT                        1234
#define DEBUGSTR_BUF_SIZE                 1024

#ifdef DEBUG
  #define DPRINT(...) \
    Udp.beginPacket(DEBUG_HOSTNAME, DEBUG_PORT); \
    Udp.write(__VA_ARGS__); \
    Udp.endPacket();
  #define DPRINTLN(...) \
    Udp.beginPacket(DEBUG_HOSTNAME, DEBUG_PORT); \
    Udp.write(__VA_ARGS__); \
    Udp.write("\n"); \
    Udp.endPacket();
  #define DPRINTF(...) \
    Udp.beginPacket(DEBUG_HOSTNAME, DEBUG_PORT); \
    snprintf(debugstr, sizeof(debugstr), __VA_ARGS__); \
    Udp.write(debugstr); \
    Udp.endPacket();
#else
  #define DPRINT(...)
  #define DPRINTLN(...)
  #define DPRINTF(...)
#endif

#ifdef DEBUG
  WiFiUDP Udp;
  char debugstr[DEBUGSTR_BUF_SIZE];
#endif

DPRINTF("updatevr100state(): %u -> %u\n", vr100state, newstate);

Dann kannst Du auf Deinem Clientrechner mit netcat lauschen:
nc -ul 1234

Patrick
« Letzte Änderung: 05 August 2017, 15:21:15 von PatrickR »
lepresenced - Tracking von Bluetooth-LE-Tags (Gigaset G-Tag) mittels PRESENCE