Autor Thema: msgDialog: Instant Messaging als FHEM Interface  (Gelesen 57331 mal)

Offline igami

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2540
  • RTFM
    • commandref
msgDialog: Instant Messaging als FHEM Interface
« am: 30 September 2017, 15:09:01 »
Link zum Wiki Artikel: https://wiki.fhem.de/wiki/MsgDialog

Bei Problemen bitte den Dialog als Raw definition posten (siehe https://wiki.fhem.de/wiki/Import_von_Code_Snippets)



Originalbeitrag:

Hi zusammen,

hier möchte ich euch mein neues Modul msgDialog vorstellen, welches es erlaubt chat Dialoge zu definieren und für jeden Dialog verschiedene Benutzer zu berechtigen.
Selbst nutze ich nur Telegram in FHEM, aber das Modul sollte auch mit Jabber und Whatsapp funktionieren.

Momentan befinde ich mich noch in der Testphase, möchte euch aber doch schon mal ein Video von der Anwendung mit Telegram präsentieren.
https://youtu.be/oRDy2918mVI

Ich hoffe es gefällt euch.
Eine erste Version und Beschreibung folgt nächste Woche.

Grüße,
igami
« Letzte Änderung: 02 November 2017, 22:20:12 von igami »
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal am 12. Januar 2019.

MAINTAINER: archetype, Heating_Control, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap, RandomTimer, Twilight, WeekdayTimer
ToDo: adb, FluxLED
Gefällt mir Gefällt mir x 5 Liste anzeigen

Offline tiroso

  • Full Member
  • ***
  • Beiträge: 260
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #1 am: 30 September 2017, 15:27:15 »
Das Video ist nicht verfügbar

Offline igami

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2540
  • RTFM
    • commandref
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #2 am: 30 September 2017, 15:30:43 »
Das Video ist nicht verfügbar
Sollte nun gehen, stand noch auf Privat :-[
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal am 12. Januar 2019.

MAINTAINER: archetype, Heating_Control, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap, RandomTimer, Twilight, WeekdayTimer
ToDo: adb, FluxLED

Offline binford6000

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 649
  • 🏠⚙️🛠📱
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #3 am: 30 September 2017, 16:35:05 »
Zitat
Sollte nun gehen, stand noch auf Privat :-[

Jepp geht. Sieht bombe aus!

Zitat
Ich hoffe es gefällt euch.
Eine erste Version und Beschreibung folgt nächste Woche.

Ich bin schon sehr gespannt! An der Stelle schon mal vielen Dank im Voraus deine Mühe!
VG Sebastian

FHEM 5.9 auf RPi3, IOserver für alle CULs mit ser2net, Testumgebung: docker pull fhem/fhem
Homematic, EnOcean, IT, HUE + Nanoleaf Aurora,  SONOS, alexa-fhem, homebridge, TelegramBot mit msgDialog, livetracking

Offline ToM_ToM

  • Sr. Member
  • ****
  • Beiträge: 917
    • ThomasZFoto
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #4 am: 30 September 2017, 17:30:16 »
Hallo  igami,

ich habe mir etwas Ähnliches selbst programmiert. Bin aber mal gespannt wenn das von dir fertig ist. Vielleicht ist es damit einfacher und ich kann meine Eigenentwicklung ersetzen. :)

VG, Thomas
Hardware: BananaPi, Busmaster CUL, SanDisk 16GB Ultra SD, 16 GB USB-Stick | Software: Armbian, FHEM 5.8

Offline Fixel2012

  • Hero Member
  • *****
  • Beiträge: 1218
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #5 am: 30 September 2017, 19:08:08 »
Wow, das sieht echt Hammer aus!

Mal schauen, was sich da so Implementieren lässt.
Fhem 5.8 auf Raspi 3, HMLAN und 868MHz CUL mit einigen Komponenten, Z-Wave Rollladenaktoren, Tablet UI, 433 MHz CUL mit Baumarktsteckdosen und Temp Sensoren, Amazon Echo, Echo Dot, 2x SONOS  play1, 1x SONOS Connect AMP,  presence, HUE, Lightify

Offline mrfloppy

  • Full Member
  • ***
  • Beiträge: 151
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #6 am: 30 September 2017, 19:46:46 »
VOll genial. Freue mich schon darauf.
Fhem 5.8, CCU2, RFXtrx433 E USB, KeyMatic, Div. Thermostate, CUL433, Fhemduino, Temp/luftfeuchesensoren,Fensterkontakte,Intertechno Schalter,.......

Offline Ma_Bo

  • Hero Member
  • *****
  • Beiträge: 1112
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #7 am: 30 September 2017, 21:27:41 »
Sieht interessant aus, bin auf die erste Version gespannt...
Grüße Marcel


Tapatalk iPhone, daher kurz gehalten.
NUC mit FHEM, HM Heizungsthermostate, HM Wandthermostate, Intertechno Funksteckdosen, 10" Tablet als Wanddisplay, KeyMatic, Fensterkontakte, Fensterkontakte umgebaut als Wassermelder und Briefkastenmelder, Aussenthermostat, Anwesenheitssteuerung über Fritz Box, Google Home usw. usw.

Offline nanocosmos

  • Full Member
  • ***
  • Beiträge: 156
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #8 am: 30 September 2017, 21:42:39 »
Echt klasse!
Freue mich ebenfalls auf die ersten Versionen.

Offline igami

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2540
  • RTFM
    • commandref
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #9 am: 01 Oktober 2017, 08:48:16 »
Mit dem msgDialog Modul können Dialoge definiert werden, die dann per Instant Messaging durchgegangen werden.
Die Idee zu dem Modul kam mir dadurch, dass ich meine Waschmaschine über eine Funksteckdose schalte. Ich bereite sie meist morgens vor der Arbeit vor und lege dann eine Uhrzeit fest, wann Sie fertig sein soll. Damit ich dabei aber nicht immer auf einen Browser angewiesen bin habe ich mir eine Lösung über Telegram auf Basis von DOIF gebastelt. Diese hat zwar funktioniert, war aber nicht sehr Intuitiv.
Wichtig dabei war mir von Anfang an, dass ich die einzelnen Dialoge für verschiedene Benutzer freigeben kann.
Das msg Dialog Modul baut auf dem msg Befehl auf. Der msg Befehl kann mit ROOMMATE und GUEST devices genutzt werden. Für jeden Bewohner wird die Kontaktart festgelegt. Leider unterstützt der msg Befehl nur ausgehende Nachrichten. Daher habe ich mir für eingehnde Nachrichten ein notify erstellt, welches für Telegram, Jabber und Whatsapp eingehende Nachrichten als readings in die entsprechenden ROOMMATE/GUEST devices schreibt.
Raw definition:
defmod msgPushReceived notify .*(msgText|queryData|(OTR)?LastMessage|message):(\n|.)* {\
  my ($recipient, $received);;\
  my $TYPE = InternalVal($NAME, "TYPE", "");;\
\
  if($TYPE eq "TelegramBot" && $EVENT =~ m/^msgText/){\
    $recipient = ReadingsVal($NAME, "msgPeerId", undef);;\
    $received = ReadingsVal($NAME, "msgText", undef);;\
  }\
  elsif($TYPE eq "TelegramBot" && $EVENT =~ m/^queryData/){\
    $recipient = ReadingsVal($NAME, "queryPeerId", undef);;\
    $received = ReadingsVal($NAME, "queryData", undef);;\
  }\
  elsif($TYPE eq "Jabber" && $EVENT =~ m/^((OTR)?Last)Message/){\
    $received = ReadingsVal($NAME, $1."Message", undef);;\
    ($recipient) = (ReadingsVal($NAME, $1."SenderJID", undef) =~ m/[^\/]+/g);;\
  }\
  elsif($TYPE eq "yowsup" && $EVENT =~ m/^message/){\
    $recipient = $NAME;;\
    $NAME = $modules{yowsup}{defptr}{yowsup}->{NAME};;\
    $received = ReadingsVal($NAME, "message", undef);;\
  }\
\
  return unless($recipient && $received ne "");;\
  \
  my @contacts = devspec2array("TYPE=(ROOMMATE|GUEST):FILTER=msgContactPush=.*$recipient.*");;\
  \
  if(@contacts){\
    foreach (@contacts){\
      my $dev_hash = $defs{$_};;\
\
      readingsBeginUpdate($dev_hash);;\
      readingsBulkUpdate($dev_hash, "fhemMsgPushReceived", $received);;\
      readingsBulkUpdate($dev_hash, "fhemMsgPushReceivedContact", $NAME);;\
      readingsEndUpdate($dev_hash, 1);;\
    }\
  }\
  else{\
    fhem("msg push Unbekannter Kontaktversuch über $NAME von $recipient:\n$received");;\
  }\
}
attr msgPushReceived devStateIcon {ReadingsVal($name, "state", "inactive") eq "active" ? ".*:ios-on-blue:inactive" : ".*:ios-off:active"}
attr msgPushReceived icon audio_mic
attr msgPushReceived room msg
Dadurch bekommen wir nun die Readings "fhemMsgPushReceived", mit dem Inhalt der Nachricht, und "fhemMsgPushReceivedContact" mit dem device aus dem die Nachricht stammt, wobei letzteres bisher noch keine Rolle spielt. Vielleicht kann man das mal weiterentwickeln, dass man eben pro Benutzer mehrere Schnittstellen definieren kann.
Wer den msg Befehl bereits verwendet hat schon ein device vom Typ msgConfig. Alle anderen müssen dies erst noch anlegen.
Meins sieht so aus
Raw definition:
defmod myMsgConfig msgConfig
attr myMsgConfig userattr evalSpecials:textField-long
attr myMsgConfig evalSpecials me=kanaan\
TelegramBot=TelegramBot
attr myMsgConfig msgContactPush TelegramBot
attr myMsgConfig room msg
Dann gibt es noch die verschiedenen ROOMMATEs, bei dem das Attribut  msgContactPush gesetzt werden muss.
Für Telegram sieht das dabei so aus:
attr <ROOMMATE|GUEST> msgContactPush <TelegramBot>:@<PeerID>
Bei Telegram gibt es noch eine weitere Besonderheit. Ich musste das Attribut utf8Special auf 1 setzen, damit ich Nachrichten mit Umlauten gesendet bekomme.

Damit sind alle Vorbereitungen getroffen und wir können den ersten Dialog schreiben.
define Waschmaschine_Dialog msgDialog {}
So bekommen wir einen leeren Dialog und können ihn bequem über das DEF Feld bearbeiten. Die Dialoge sind als JSON aufgebaut und es gibt verschiedene besondere keys.
message: definiert die Antwort, die von dem Bot kommt. Kann entweder eine Einzeilige Nachricht sein, oder ein Array bei dem die Werte dann durch ein \n verbunden werden.
commands: definiert die Befehle die ausgeführt werden, wenn dieser Status des Dialog erreicht ist. Die Befehle werden vor der Antwort ausgeführt. Kann auch entweder ein Befehl sein, oder ein Array von Befehlen. Die Befehle müssen dabei genau so eingegeben werden, wie in der Kommandozeile von FHEM.
match: Hier kann eine REGEX angegeben werden auf die die eingehende Nachricht geprüft wird. Wenn diese zutrifft wird der Dialog an dieser Stelle fortgeführt
setOnly: kann true oder false sein. Bei true wird der Bot nicht auf die Nachricht antworten, auch wenn sie passt. Das ist dazu gedacht um eine Benachrichtigung vom Bot aus zu senden.

Dann gibt es noch das Attribut evalSpecials, was einigen vielleicht auch schon als userattr beim msgConfig device aufgefallen ist. Hier können Synonyme definiert werden. In allen Dialogen wird dann %me% durch "kannan" ersetzt und %TelegramBot% durch "TelegramBot", der name meines TelegramBots. Wenn ich in einem Dialog dann auch noch mal "me" definiere gilt dies nur für diesen Dialog.

Weiterhin gibt es noch einige Variablen:
$SELF: Der Name des Dialog
$recipient: Kommagetrennte Liste aller angesprochenen Empfänger. Im Dialog selbst ist das immer nur ein Empfänger
$message: Inhalt der empfangenen Nachricht

Nun aber weiter zum Dialog. In die DEF schreibe ich nun folgenden:
{ "Waschmaschine": {
    "message": [
      "{return('(Zeitprogramm stoppen) ') if(ReadingsVal('%controlUnit%', 'controlMode', '') eq 'auto')}",
      "{return('(programmieren) (einschalten) ') if(ReadingsVal('%actor%', 'state', '') ne 'on')}",
      "(Verlaufsdiagramm) ",
      "(abbrechen) ",
      "{return('Waschmaschine: ' . (ReadingsVal('%actor%', 'state', '') eq 'on' ? 'eingeschaltet' : 'ausgeschaltet'))}",
      "{return('Modus: ' . (ReadingsVal('%controlUnit%', 'controlMode', '') eq 'auto' ? 'Automatik' : 'Manuell (' . ReadingsVal('%controlUnit%', 'time', '') . ')'))}"
    ],
    "Zeitprogramm stoppen": {
      "commands": "set %controlUnit% controlMode manual",
      "message": [
        "(%me%) ",
        "Das Zeitprogramm wurde gestoppt."
      ]
    },
    "programmieren": {
      "message": [
        "(bestätigen|abbrechen) ",
        "(00:00:00_00|00:30:00_30|01:00:01_00|01:30:01_30|02:00:02_00|02:30:02_30) ",
        "(03:00:03_00|03:30:03_30|04:00:04_00|04:30:04_30|05:00:05_00|05:30:05_30) ",
        "(06:00:06_00|06:30:06_30|07:00:07_00|07:30:07_30|08:00:08_00|08:30:08_30) ",
        "(09:00:09_00|09:30:09_30|10:00:10_00|10:30:10_30|11:00:11_00|11:30:11_30) ",
        "(12:00:12_00|12:30:12_30|13:00:13_00|13:30:13_30|14:00:14_00|14:30:14_30) ",
        "(15:00:15_00|15:30:15_30|16:00:16_00|16:30:16_30|17:00:17_00|17:30:17_30) ",
        "(18:00:18_00|18:30:18_30|19:00:19_00|19:30:19_30|20:00:20_00|20:30:20_30) ",
        "(21:00:21_00|21:30:21_30|22:00:22_00|22:30:22_30|23:00:23_00|23:30:23_30) ",
        "Wann soll die Wäsche fertig sein?",
        "Bitte Uhrzeit in HH:MM angeben.",
        "Aktuell ist [%controlUnit%:time] Uhr eingestellt."
      ],
      "Uhrzeit": {
        "match": "([0-1][0-9]|2[0-3])[:_][0-5][0-9]",
        "commands": [
          "{my $time = '$message';; $time =~ s/_/:/;; fhem(\"set %controlUnit% time $time\");;}",
          "set $SELF say @$recipient Waschmaschine|programmieren|bestätigen"
        ]
      },
      "bestätigen": {
        "commands": "set %controlUnit% controlMode auto",
        "message": [
          "(%me%) ",
          "Das Zeitprogramm wurde eingestellt.",
          "Die Wäsche wird voraussichtlich um [%controlUnit%:time] Uhr fertig sein.",
          "Bitte die Waschmaschine vorbereiten."
        ]
      }
    },
    "einschalten": {
      "commands": [
        "set %controlUnit% controlMode manual",
        "set %actor% on"
      ]
    },
    "Verlaufsdiagramm": {
      "commands": "set %TelegramBot% cmdSend {plotAsPng('%plot%')}",
      "message": [
        "(%me%) ",
        "Waschkeller: Waschmaschine"
      ]
    }
  },
  "auto": {
    "setOnly": true,
    "commands": [
      "set %actor% on",
      "set %controlUnit% controlMode manual"
    ],
    "message": [
      "(%me%) ",
      "Die Wachmaschine wurde automatisch eingeschaltet."
    ]
  },
  "manual": {
    "setOnly": true,
    "message": [
      "(%me%) ",
      "Die Wachmaschine wurde manuell eingeschaltet."
    ]
  },
  "done": {
    "setOnly": true,
    "commands": "set %actor% off",
    "message": [
      "(%me%) ",
      "Die Wachmaschine ist fertig."
    ]
  }
}
Wenn ich nun "Waschmaschine" an meinen Bot sende bekomme ich eine Nachricht abhängig von dem Status zurück.
Ich kann das "Zeitprogramm stoppen", wenn die Waschmaschine vorbereitet is, die Waschmaschine "programmieren" oder "einschalten", wenn sie nicht läuft, ein "Verlaufsdiagramm" anfordern oder den Dialog "abbrechen". Weiterhin bekomme ich noch den "Modus" und den "Status" der Waschmaschine angezeigt.
Lautet meine nächste Nachricht dann "programmieren" bekomme ich die Nachricht
Zitat
Wann soll die Wäsche fertig sein?
Bitte Uhrzeit in HH:MM angeben.
Aktuell ist [%controlUnit%:time] Uhr eingestellt.
Und ein Keyboard mit Uhrzeiten im halbstunden Takt, sowie "bestätigen" und "abbrechen". [%controlUnit%:time] wird natürlich durch das Reading time von meiner controlUnit ersetzt.
Nun kann ich eine beliebige Uhrzeit eingeben oder auf einen der Buttons drücken um dadurch eine Uhrzeit zu senden.
Hier greift dann "match" von dem nächsten Dialog-Schritt "Uhrzeit". Es wird geprüft ob ich eine valide Uhrzeit angegeben habe. Falls ja, werden die Befehle ausgeführt:
"{my $time = '$message';; $time =~ s/_/:/;; fhem(\"set %controlUnit% time $time\");;}"
ersetzt in meiner Nachricht das _ durch einen : und set meine controlUnit dann auf diesen Wert. Das muss ich machen, da ich inlineKeyboards verwende und : dort das Trennzeichen zwischen angezeigtem und gesendetem Text ist.
"set $SELF say @$recipient Waschmaschine|programmieren|bestätigen"
Nachdem ich die Uhrzeit festgelegt habe ist es genau so, als wenn ich die vorherige Uhrzeit bestätigt habe.
Es werden dann alle Befehle die dort angegeben sind ausgeführt und ich bekomme die angegebene Nachricht gesendet.

Intern passiert nun noch folgendes. Um den Verlauf eines Dialogs zu speichern wird pro Benutzer ein Readings <ROOMMATE|GUEST>_history angelegt.
Zuerst nimmt dieses den Wert "Waschmaschine" an. Danach den Wert "Waschmaschine|programmieren" und danach den Wert "", da der Dialog an dieser Stelle beendet ist.

Der Vollständigkeithalber noch mein DOIF welches dann die Waschmaschine schaltet:
Raw definition:
defmod Waschkeller_washer_automation DOIF ### automated on ###\
([([Waschkeller_washer_controlUnit:time]-[HM_2C10D8_Sw_HourCounter:pulseTimeAverage])] and \
 [Waschkeller_washer_controlUnit:controlMode] eq "auto"\
)(\
  set Waschmaschine_Dialog say auto\
)\
### done ###\
DOELSEIF\
([HM_2C10D8_Pwr:power] < [Waschkeller_washer_controlUnit:R-powerDone])(\
  set Waschmaschine_Dialog say done\
)\
### manual on ###\
DOELSEIF\
([HM_2C10D8_Sw:"on"] and \
 [Waschkeller_washer_controlUnit:controlMode] eq "manual" and \
 [$SELF:cmd] != 1\
)(\
  set Waschmaschine_Dialog say manual\
)
attr Waschkeller_washer_automation alias Waschkeller: Waschmaschine Automatik
attr Waschkeller_washer_automation cmdState automated on|done|manual on
attr Waschkeller_washer_automation group Waschmaschine
attr Waschkeller_washer_automation icon time_automatic
attr Waschkeller_washer_automation room Waschkeller
attr Waschkeller_washer_automation wait 0:180:0
Da die Befehle die beim Einschalten erfolgen sollen im Dialog angegeben sind, reicht es aus ein "set Waschmaschine_Dialog say auto" auszuführen. Dann werden alle Berechtigten Nutzer informiert, dass die Waschmaschine eingeschaltet wurde.

Unser Waschmaschine Dialog wird aber noch nicht funktionieren. Wir müssen noch über das Attribut "allowed" festlegen wer Berechtigt ist. Hier werden alle ROOMMATE/GUEST angezeigt, bei denen das "msgContactPush" gepflegt ist. Weiterhin gibt es dort auch die Möglichkeit "everyone" auszuwählen, dann betrifft es alle ROOMMATE/GUEST mit dem Attribut "msgContactPush".

Weiterhin muss auch noch das Attribut "evalSpecials" befüllt werden
Raw definition:
attr Waschmaschine_Dialog evalSpecials actor=HM_2C10D8_Sw\
controlUnit=Waschkeller_washer_controlUnit\
plot=Waschkeller_washer_SVG

Herzlichen Glückwunsch! Wir haben unseren ersten funktionsfähigen Dialog.
Aber es geht direkt weiter. Ich müsste mir ja nun merken was ich alles für Dialoge angelegt habe und wie genau die benannt sind. Da lege ich mir doch lieber einen Dialog für an, der mich darüber informiert:
Raw definition:
defmod meta_Dialog msgDialog {\
  "%me%": {\
    "match": "\/?(start|%me%)",\
    "commands": [\
  "deletereading TYPE=msgDialog $recipient_history",\
  "deletereading %TelegramBot% $recipient_sentMsgId"\
    ],\
    "message": [\
      "{return('(' . join(') (', sort(split('\n', fhem('get TYPE=msgDialog:FILTER=NAME!=$SELF:FILTER=allowed=.*($recipient|everyone).* trigger')))) . ') ')}",\
      "(abbrechen) ",\
      "Ich kann folgendes für dich tun:"\
    ]\
  },\
  "abbrechen": {\
    "match": "\/?abbrechen",\
    "commands": [\
  "deletereading TYPE=msgDialog $recipient_history",\
  "deletereading %TelegramBot% $recipient_sentMsgId"\
    ],\
    "message": [\
      "(%me%) ",\
      "Dialog abgebrochen."\
    ]    \
  },\
  "beenden": {\
    "match": "\/?beenden",\
    "commands": [\
  "deletereading TYPE=msgDialog $recipient_history",\
  "deletereading %TelegramBot% $recipient_sentMsgId"\
    ],\
    "message": [\
      "(%me%) ",\
      "Dialog beendet."\
    ]\
  }\
}
attr meta_Dialog DbLogExclude .*
attr meta_Dialog allowed everyone
attr meta_Dialog room msg
Wenn wir nun in meinem Fall "kanaan" senden, bekommen wir eine Auflistung aller Berechtigten Dialoge. Bisher nur Waschmaschine.
"abbrechen" und "beenden" verhalten sich bis auf die Nachricht identisch.
In allen drei Fällen wird aber das history Reading in allen Dialogen gelöscht.
Das mit dem "deletereading %TelegramBot% $recipient_sentMsgId" hat etwas mit den inlineKeyboards zu tun und das erkläre ich ein anderes Mal.

Viel Spaß beim Testen und umsetzen.
Ich würde mich freuen, wenn sich jemand findet der einen Wiki Artikel dazu schreibt, das liegt mir nicht so.
Im Anhang die erste Version des Moduls, allerdings noch ohne commandref.

Grüße,
igami
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal am 12. Januar 2019.

MAINTAINER: archetype, Heating_Control, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap, RandomTimer, Twilight, WeekdayTimer
ToDo: adb, FluxLED
Gefällt mir Gefällt mir x 1 Liste anzeigen

Offline igami

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2540
  • RTFM
    • commandref
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #10 am: 01 Oktober 2017, 09:41:45 »
Hier nun etwas eher für Bastler:
Wie nutze ich inlineKeyboards und modifiziere die letzte Nachricht bei Telegram

Vorab, das ist alles noch Beta und ich finde die normalen Keyboards besser :D

Um eine Nachricht bei Telegram zu verändern gibt es den Befehl "queryEditInline".
Dafür wird aber die MsgId von der Nachricht benötigt. Also erstmal ein notify, welches die msgId pro Peer abspeichert.
Raw definition:
defmod sentMsgIdByPeerId notify .+:sentMsgId.+ {\
  return unless($TYPE eq "TelegramBot");;\
  \
  my $dev_hash = $defs{$NAME};;\
  my $sentMsgId = ReadingsVal($NAME, "sentMsgId", "");;\
  my $sentMsgPeerId = ReadingsVal($NAME, "sentMsgPeerId", "");;\
  my ($contact) = devspec2array("TYPE=(ROOMMATE|GUEST):FILTER=msgContactPush=.*$sentMsgPeerId.*");;\
  \
  readingsSingleUpdate($dev_hash, "$contact\_sentMsgId", $sentMsgId, 1);;\
}
attr sentMsgIdByPeerId devStateIcon {ReadingsVal($name, "state", "inactive") eq "active" ? ".*:ios-on-blue:inactive" : ".*:ios-off:active"}
attr sentMsgIdByPeerId icon audio_mic
attr sentMsgIdByPeerId room msg

Dann müssen wir aus dem "set <TelegramBot> message" noch das "set <TelegramBot> queryEditInline" machen.
Dafür ein cmdAlias:
Raw definition:
defmod message2queryEditInline cmdalias set .+ message (.|\n)+ AS {\
  my ($NAME, $cmd, $message) = split(/[\s]+/, $EVENT, 3);;\
  my $TYPE = InternalVal($NAME, "TYPE", "");;\
  (my $recipient, $message) = ($message =~ m/(@\S+)? (.+)/s);;\
  \
  if($TYPE eq "TelegramBot" && $recipient){\
    my ($contact) = devspec2array("TYPE=(ROOMMATE|GUEST):FILTER=msgContactPush=.*$recipient.*");;\
    my $sentMsgId = ReadingsVal($NAME, "$contact\_sentMsgId", "");;\
\
    if($sentMsgId ne ""){\
      fhem("set $NAME queryEditInline $sentMsgId $recipient $message");;\
    }\
    else{\
      fhem("set $NAME queryInline $recipient $message");;\
    }\
  }\
  else{\
    fhem("set $EVENT");;\
  }\
}
attr message2queryEditInline room msg

Warum mir das ganze nicht gefällt:
1. Die inlineKeyboards sind immer nur so Breit wie die Nachricht. Im Video sieht man das an der Einkaufsliste. "Waren hinzufügen" ist nicht komplett ausgeschrieben
2. Die inlineKeyboars können lang sein, man muss also immer scrollen. Normale Keyboards sind nur so groß wie die normale Tastatur
3. Wenn eine Nachricht geändert wird ist es keine neue Nachricht und man erhält keine Benachrichtigung darüber. Aktuell ist es so, dass die letzte ID nur im meta_Dialog gelöscht wird. Bekomme ich nun zwischendurch eine Nachricht wie: "Die Waschmaschine ist fertig" Bekomme ich das nicht mit, da es keine neue Nachricht ist.

Warum das ganze aber doch was hat:
1. Im Beleuchtungs-Dialog sieht man sehr schön, wie sich nur der Prozentwert in der Nachricht ändert, ohne dass man eine Wall-of-Text bekommt.
2. Man kann andere Texte anzeigen als gesendet werden.

Man müsste den cmdAlias also so umbauen, dass er am besten nur einen Befehl "set <TelegramBot> message @<Peer> queryInline" ändert.
Das ganze ist aber sehr Telegram Spezifisch und ich weiß nicht was die Mehrheit hier im Forum für IM nutzt. Das Modul sollte ja auch mit Jabber und Whatsapp funktionieren.

Ich werde meine Dialoge aber wieder auf das normale Keyboard umstellen und erst noch weiter damit experimentieren.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal am 12. Januar 2019.

MAINTAINER: archetype, Heating_Control, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap, RandomTimer, Twilight, WeekdayTimer
ToDo: adb, FluxLED
Gefällt mir Gefällt mir x 2 Liste anzeigen

Offline igami

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2540
  • RTFM
    • commandref
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #11 am: 01 Oktober 2017, 11:36:58 »
Hier noch ein Video mit normalem Keyboard: https://youtu.be/yiCOTeR1YVQ
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal am 12. Januar 2019.

MAINTAINER: archetype, Heating_Control, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap, RandomTimer, Twilight, WeekdayTimer
ToDo: adb, FluxLED

Offline binford6000

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 649
  • 🏠⚙️🛠📱
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #12 am: 01 Oktober 2017, 14:16:04 »
Hi igami,
wenn ich hier
Zitat
Nun aber weiter zum Dialog. In die DEF schreibe ich nun folgenden:
deinen Code einfüge bekomme ich folgenden Fehler:
Usage: define <name> msgDialog {JSON}libjson-perl ist natürlich installiert. Sonst käme laut deinem Modul-Code ja auch ein anderer Fehler...
VG Sebastian
FHEM 5.9 auf RPi3, IOserver für alle CULs mit ser2net, Testumgebung: docker pull fhem/fhem
Homematic, EnOcean, IT, HUE + Nanoleaf Aurora,  SONOS, alexa-fhem, homebridge, TelegramBot mit msgDialog, livetracking

Offline igami

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2540
  • RTFM
    • commandref
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #13 am: 01 Oktober 2017, 14:19:45 »
Hi igami,
wenn ich hier  deinen Code einfüge bekomme ich folgenden Fehler:
Usage: define <name> msgDialog {JSON}libjson-perl ist natürlich installiert. Sonst käme laut deinem Modul-Code ja auch ein anderer Fehler...
VG Sebastian
Habe das grad selbt noch mal getestet und bekomme keinen Fehler. Hast du vielleicht vergessen eine Klammer mit zu nehmen?
Ansonsten lässt sich das auch super mit https://jsonlint.com/ überprüfen und ggf. aufzeigen wo ein Fehler ist.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal am 12. Januar 2019.

MAINTAINER: archetype, Heating_Control, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap, RandomTimer, Twilight, WeekdayTimer
ToDo: adb, FluxLED

Offline binford6000

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 649
  • 🏠⚙️🛠📱
Antw:msgDialog: Instant Messaging als FHEM Interface
« Antwort #14 am: 01 Oktober 2017, 15:39:10 »
Zitat
Hast du vielleicht vergessen eine Klammer mit zu nehmen?
Habe deinen Code kopiert. JSONLint sagt der Code sei OK. Aber weder
define Waschmaschine_Dialog msgDialog {} und dann über DEF den Code einfügen noch
das Ganze per defmod und Raw definition anzulegen funktioniert und liefern beide den gleichen Fehler...
FHEM 5.9 auf RPi3, IOserver für alle CULs mit ser2net, Testumgebung: docker pull fhem/fhem
Homematic, EnOcean, IT, HUE + Nanoleaf Aurora,  SONOS, alexa-fhem, homebridge, TelegramBot mit msgDialog, livetracking