Autor Thema: Vordefinierte Messages an vordefinierte Topics mit einem Set-Befehl absenden...  (Gelesen 617 mal)

Offline Reinerlein

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1999
Hallo,

ich habe mir einen Infrarot-Sender mit Tasmota gebaut. Um damit einen Infrarot-Code abzusenden, muss man eine JSON-Datenstruktur als Message übermitteln. Dabei wird immer dasselbe Topic verwendet.

Mein erster Versuch war ein normales MQTT_DEVICE mit einer EventMap, die z.B. "on" in die Befehlsstruktur
IRSend {"Protocol":"NEC","BITS":32,"DATA":"17695740"}
umwandelt, wobei "IRSend" mein Publish_Set-Attribut ist.

Das funktioniert solange, wie man nicht versucht, z.B. in einem Notify per Fhem-Befehl den Set-Befehl "on" ausführen möchte:
notifyregex {
  fhem("set mqtt_device on");
}
Dann erscheinen komische Fehlermeldungen im Log, die darauf hindeuten, dass eventMap eine einfache String-Ersetzung durchführt, und dann halt die Anführungszeichen nicht mehr hinkommen, und er die JSON-Struktur als Perl-Befehle interpretieren will...

Am einfachsten wäre es, wenn man sozusagen ein "publishSet_" definieren könnte, wo man die Message bereits mitdefiniert, und nur noch einen Befehl zur Ausführung aufruft (und sowohl Topic als auch Message aus der Definition verwendet werden).

Gibt es vielleicht noch andere Varianten?
Und ich möchte gerne explizit auf weitere Devices (wie Dummies und Notifies) verzichten. Diese blähen das ja eigentlich nur unnötig auf...

Danke schon mal...

Grüße
Reiner

Offline Reinerlein

  • Developer
  • Hero Member
  • ****
  • Beiträge: 1999
Hallo zusammen,

ich beantworte mir das mal selber:
Ich habe es so gelöst, dass ich ein MQTT_DEVICE erzeugt habe, welches den Set-Befehl für IRSend (der die JSON-Datenstruktur übergeben bekommt und an das Tasmota-Device sendet) hat, und jedes Device ist ein readingsProxy, da man dort eine setFn angeben kann.

Wen es interessiert, hier mal meine Devicedefinitionen.

Mein MQTT-Device wertet noch die IP-Adressinformationen des Tasmota-Devices aus, und zeigt diese als Reading an. Des Weiteren gibt es ein Reading für den Last Will des Devices.

MQTT_DEVICE:
define wohnzimmer_Infrarot_01 MQTT_DEVICE
attr wohnzimmer_Infrarot_01 group Host
attr wohnzimmer_Infrarot_01 icon it_wifi
attr wohnzimmer_Infrarot_01 publishSet_IRSend cmnd/wohnzimmer_Infrarot_01/IRsend
attr wohnzimmer_Infrarot_01 publishSet_getIP noArg cmnd/wohnzimmer_Infrarot_01/IPAddress1
attr wohnzimmer_Infrarot_01 room Wohnzimmer
attr wohnzimmer_Infrarot_01 stateFormat transmission-state
attr wohnzimmer_Infrarot_01 subscribeReading_LWT tele/wohnzimmer_Infrarot_01/LWT
attr wohnzimmer_Infrarot_01 subscribeReading_RESULT stat/wohnzimmer_Infrarot_01/RESULT
attr wohnzimmer_Infrarot_01 userReadings IP:RESULT.*?IPAddress1.* {\
  my $json = decode_json(ReadingsVal($name, 'RESULT', '{}'));;\
  if ($json->{IPAddress1} =~ m/.*?\((.*?)\)/) {\
    return $1;;\
  } else {\
    return 'NA';;\
  }\
},\
\
RESULT:LWT.*?Online {\
  reDefine($name.'_IPTrigger', "at +00:00:00 set $name getIP");;\
  return 'getIP';;\
}

Hier mal mein Device für meinen Harman/Kardon-Verstärker Zone 2 Steuerung:
defmod wohnzimmer_AVReceiver_Zone2 readingsProxy wohnzimmer_Infrarot_01:IRSend
attr wohnzimmer_AVReceiver_Zone2 alias AV Receiver Zone 2
attr wohnzimmer_AVReceiver_Zone2 devStateIcon off:taster_ch_aus_rot:on on:taster_ch_an_gruen:off
attr wohnzimmer_AVReceiver_Zone2 group AV Receiver
attr wohnzimmer_AVReceiver_Zone2 room Wohnzimmer
attr wohnzimmer_AVReceiver_Zone2 setFn { if ($CMD eq 'on') {\
    return 'IRSend {"Protocol":"NEC","BITS":32,"DATA":"1634599167"}';;\
  } elsif ($CMD eq 'off') { \
    return 'IRSend {"Protocol":"NEC","BITS":32,"DATA":"1634631807"}';;\
  } elsif ($CMD eq 'volumeDown') {\
    return 'IRSend {"Protocol":"NEC","BITS":32,"DATA":"1634612427"}';;\
  } elsif ($CMD eq 'volumeUp') {\
    return 'IRSend {"Protocol":"NEC","BITS":32,"DATA":"1634653227"}';;\
  } else {\
    return undef;;\
  }\
}
attr wohnzimmer_AVReceiver_Zone2 setList on:noArg off:noArg volumeDown:noArg volumeUp:noArg
attr wohnzimmer_AVReceiver_Zone2 sortby 2
attr wohnzimmer_AVReceiver_Zone2 stateFormat state
attr wohnzimmer_AVReceiver_Zone2 valueFn { \
  if ($LASTCMD eq 'on' || $LASTCMD eq 'off') {\
    return $LASTCMD;; \
  } else {\
    return undef;;\
  }\
}
attr wohnzimmer_AVReceiver_Zone2 webCmd on:off:volumeDown:volumeUp
Der State wird nur von Gerätezustandsverändernden Befehlen wie An und Aus verändert. Lauter und Leiser möchte ich nicht im State sehen...

Das finde ich für mich elegant genug :)

Ich lasse das hier mal offen, für eine Diskussion, ob eine solche Funktionalität nicht doch noch irgendwie in das MQTT_DEVICE Einzug finden soll oder kann...

Grüße
Reinerlein

Offline Skusi

  • Full Member
  • ***
  • Beiträge: 184
Der Thread ist zwar schon etwas älter, aber genau diesen code habe ich gesucht.

So habe ich nun den Sat Receiver, den Marantz AVR und meinen Beamer als eigenständige Devices angelegt (readingsProxy) und kann per Sonoff Basic mit IR extension und Tasmota FW per Infrarot endlich mein Kino steuern.

Vielen Dank für den Denkanstoß und den Code !
RPI2, NanoCul433 (a-culfw), NanoCul868 (a-culfw), JeeLink Clone (LaCrosse), Firmata  für FB Heizung,Wasser+Gas+Klingel+Lux, Somfy Rolladen, Pollin Steckd.,TX29DTH,ESPEasy an S0 Stromz., MAX Fensterkontakte, IButton, SonOff Tasmota, ESP LED Controler