[gelöst]asyncOutput: device gone, output was: ... unter iOS nach BlockingCall

Begonnen von mumpitzstuff, 03 Januar 2018, 01:14:44

Vorheriges Thema - Nächstes Thema

mumpitzstuff

Wie übergibt man den Inhalt von $hash->{CL}, wenn man aus GetFn heraus ein HttpUtils_NonblockingGet() startet und asyncOutput in der Callback aufrufen möchte oder wenn man asyncOutput in der Finish Routine eines BlockingCall aufrufen möchte (die Schachtelung der beiden Dinge ist ebenfalls ein Anwendungsfall, also innerhalb der Callback von HttpUtils_NonblockingGet() einen BlockingCall starten und in der Finish Routine dann mit asyncOutput() die Daten ausgeben). Vielleicht hat jemand einen Tip für mich.

Problem 1:
Sobald ich innerhalb der Callback von HttpUtils oder im Finish eines Blocking Calls auf $hash->{CL} zugreife bzw. dieses verwende, klappt entweder der Zugriff nicht oder das Device ist irgendwie abwesend, sobald ich asyncOutput damit verwende...
Notdürftig beholfen habe ich mir nun mit dem Zwischenspeichern von $hash->{CL} schon innerhalb von GetFn. Diese Variable wird dann in der Callback oder dem Finish des Blocking Calls verwendet.

Beispiele:
$hash->{helper}{CL} = $hash->{CL};
SIRD_StartNavigation($hash, -1, 0);

Das ist ein BlockingCall.

$hash->{helper}{CL} = $hash->{CL};
SIRD_SendRequest($hash, 'SET', 'netRemote.nav.action.navigate', -1, \&SIRD_ParseNavigation);

Das ist ein HttpUtils Request.

Gibt es hier einen anderen sauberen Weg? Das Ganze ist aktuell extrem unsauber, da ich unter Umständen die Zwischenvariable überschreibe, während noch ein BlockingCall läuft. Das abzufangen ist relativ aufwendig.

Problem 2 (ist ein etwas anderes Problem, aber ich wollte nicht 2 Anfragen aufmachen):
Ich stelle mit asyncOutput im Prinzip Verzeichnisstrukturen dar, die im asyncOutput Dialog als Links angezeigt werden. Klickt der User auf einen Link, dann wird der Inhalt des neuen Verzeichnisses eingelesen und erneut mit asyncOutput dargestellt. Das hat aber den Nachteil, das jedes Mal ein neuer Dialog über den alten gelegt wird. Kann ich das Dialogfenster irgendwie per Javascript schliessen sobald der User auf einen meiner generierten Links klickt, so dass nur noch der Inhalt des zuletzt geöffneten Verzeichnisses offen bleibt? Aktuell kann der User zwar Navigieren, muss aber nach z.B. 10 Verzeichnisswechseln 10x den OK Button drücken, um die ganzen Dialoge wieder los zu werden. Ich kann leider nicht alle Inhalte bereits im Hintergrund laden und dann alles mit einmal anzeigen. Das würde viele Minuten dauern. Ich muss also den Inhalt immer Häppchenweise holen.

rudolfkoenig

ZitatWie übergibt man den Inhalt von $hash->{CL}, wenn man aus GetFn heraus ein HttpUtils_NonblockingGet() startet und asyncOutput in der Callback aufrufen möchte
Man ruft HttpUtils_NonblockingGet mit einem neuen $hash auf, wo $hash->{CL} und das urspruengliche $hash explizit abgespeichert sind. HttpUtils_NonblockingGet mit dem Device-$hash aufzurufen ist ugluecklich, weil dann mehrere Ausstehende HTTP-Abfragen auf den gleichen $hash operieren.

Zitatoder wenn man asyncOutput in der Finish Routine eines BlockingCall aufrufen möchte
Da ich keine Erfahrung mit der Uebergabe von Zeigern ($hash ist nichts Anderes) ueber Prozessgrenzen habe, wuerde ich im Haupt-Thread einen neuen Hash mit selbstgenerierten Index (Zahl) bauen, und nur die Zahl uebergeben. Bei der Rueckgabe wird CL anhand dieser Nummer aus dem neuen Hash gefischt.

ZitatProblem 2 (ist ein etwas anderes Problem, aber ich wollte nicht 2 Anfragen aufmachen):
Schade, ist nicht sehr freundlich fuer die spaeteren Leser.

ZitatIch stelle mit asyncOutput im Prinzip Verzeichnisstrukturen dar, die im asyncOutput Dialog als Links angezeigt werden.
asyncOutput ist nicht fuer sowas gebaut, sondern fuer kurze Antworten auf eine blockierende Frage wie get. Dialoge kann man natuerlich schliessen, z.Bsp. mit $("#FW_okDialog").remove(). Ein Interface in einem Dialog zu implementieren finde ich sehr gebastelt.

Ich bin der Ansicht, dass so ein Interface nicht ins FHEMWEB gehoert (auch wenn die Grenze schwer zu ziehen ist). Wenn es unbedingt sein muss, dann mit FW_detailFn, dafuer gibt es viele Beispiel, z.Bsp. 00_ZWDongle.pm, 90_at.pm, usw. Fuer eine Benachrichtigung kann ein  fhemweb-Widget implementiert werden, Beispiele dafuer gibt es viele, sowohl in fhemweb.js als auch in den fhemweb_*.js Dateien.
Oder etwas, was staendig benachrichtigt wird, wie svg.js durch updateDevs.

justme1968

rudi hat im prinzip beide fragen schon beantwortet.

zu den prozess grenzen: man kann einen hash nicht über prozess grenzen hinweg übergeben. d.h. du musst wir von rudi vorgeschlagen die zuordnung selber verwalten. als kriterium kann man z.b. die pid des gestarteten prozesses verwenden. aber wenn es um http geht

ansonsten:
im plex modul mache ich das alles auch so. die kommunikation nach aussen geht mit HttpUtils_NonblockingGet , in der getFn wird sich CL gemerkt  und in einem eigenen hash an HttpUtils_NonblockingGet  übergeben. die links zu den neuen get werden automatisch erzeugt. der anwender kann sich so über mehrere get durch seine library klicken, auf jeder ebene geht ein neuer dialog auf den ich absichtlich nicht zu mache weil man so sehr schön wieder zurück navigieren kann.

ZitatasyncOutput ist nicht fuer sowas gebaut
doch. genau dafür habe ich es gebaut. das der 'normalfall' damit auch abgedeckt werden kann habe ich wissentlich in kauf genommen :)
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

mumpitzstuff

Okay Danke für die ausführlichen Antworten.

Ich schaue mir das im Plex Modul an und hoffe dann schlauer zu sein. In den entsprechenden Wikis zu HttpUtils und BlockingCall ist dazu allerdings nichts zu finden (oder es ist mir entgangen). Vielleicht wäre es gut auf die Problematik mit dem Hash hinzuweisen und ein Standardvorgehen in einem Beispiel kurz darzustellen.

mumpitzstuff

Ich habe jetzt alles soweit fertig und es funktioniert unter Windows und Android alles reibungslos. Aber leider nicht unter iOS auf einem iPad. Nach ein wenig debuggen habe ich folgendes festgestellt:

Windows/Android (hier funktioniert alles):

Abfrage aller WEB.* Devices und Ausgabe von $cl ($hash->{CL}) innerhalb von GetFn:
2018.01.04 14:12:17 3: WLAN_RADIO: CL $VAR1 = {
          'LASTACCESS' => 1515071537,
          'NR' => 265,
          'TYPE' => 'FHEMWEB',
          'SNAME' => 'WEB',
          'FW_ID' => '264',
          'CD' => bless( \*Symbol::GEN10084, 'IO::Socket::INET' ),
          'STATE' => 'Connected',
          'BUF' => '',
          'NAME' => 'WEB_<ip>_64210',
          'TEMPORARY' => 1,
          'SSL' => undef,
          'FD' => 67,
          'canAsyncOutput' => 1,
          'PORT' => 64210,
          'Authenticated' => 1,
          'PEER' => '<ip>'
        };

2018.01.04 14:12:17 3: WLAN_RADIO: WEB
WEB_<ip>_63652
WEB_<ip>_63653
WEB_<ip>_64209
WEB_<ip>_64210
WEB_<ip>_64217
WEB_<ip>_64218


Abfrage aller WEB.* Devices und Ausgabe von $cl ($hash->{CL}) nachdem BlockingCall beendet wurde:
2018.01.04 14:12:17 3: WLAN_RADIO: CL $VAR1 = {
          'FD' => 67,
          'SSL' => undef,
          'Authenticated' => 1,
          'PEER' => '<ip>',
          'canAsyncOutput' => 1,
          'PORT' => 64210,
          'CD' => bless( \*Symbol::GEN10084, 'IO::Socket::INET' ),
          'SNAME' => 'WEB',
          'FW_ID' => '264',
          'TYPE' => 'FHEMWEB',
          'LASTACCESS' => 1515071537,
          'NR' => 265,
          'BUF' => '',
          'NAME' => 'WEB_<ip>_64210',
          'TEMPORARY' => 1,
          'STATE' => 'Connected'
        };

2018.01.04 14:12:17 3: WLAN_RADIO: WEB
WEB_<ip>_63652
WEB_<ip>_63653
WEB_<ip>_64209
WEB_<ip>_64210
WEB_<ip>_64217
WEB_<ip>_64218


WEB_<ip>_64210 ist in beiden Fällen vorhanden und die Ausgabe erfolgt wie gewünscht.

iOS (hier funktioniert es nicht, egal welcher Browser):

Abfrage aller WEB.* Devices und Ausgabe von $cl ($hash->{CL}) innerhalb von GetFn:
2018.01.04 14:12:56 3: WLAN_RADIO: CL $VAR1 = {
          'BUF' => '',
          'NAME' => 'WEB_<ip>_58577',
          'TEMPORARY' => 1,
          'STATE' => 'Connected',
          'SNAME' => 'WEB',
          'FW_ID' => '272',
          'CD' => bless( \*Symbol::GEN10863, 'IO::Socket::INET' ),
          'LASTACCESS' => 1515071576,
          'NR' => 279,
          'TYPE' => 'FHEMWEB',
          'canAsyncOutput' => 1,
          'PORT' => 58577,
          'Authenticated' => 1,
          'PEER' => '<ip>',
          'FD' => 73,
          'SSL' => undef
        };

2018.01.04 14:12:56 3: WLAN_RADIO: WEB
WEB_<ip>_58574
WEB_<ip>_58575
WEB_<ip>_58576
WEB_<ip>_58577
WEB_<ip>_63653
WEB_<ip>_64209
WEB_<ip>_64210
WEB_<ip>_64217
WEB_<ip>_64218
WEB_<ip>_64221


Abfrage aller WEB.* Devices und Ausgabe von $cl ($hash->{CL}) nachdem BlockingCall beendet wurde:
2018.01.04 14:12:56 3: WLAN_RADIO: CL $VAR1 = {
          'SSL' => undef,
          'canAsyncOutput' => 1,
          'PORT' => 58577,
          'Authenticated' => 1,
          'PEER' => '<ip>',
          'LASTACCESS' => 1515071576,
          'NR' => 279,
          'TYPE' => 'FHEMWEB',
          'SNAME' => 'WEB',
          'FW_ID' => '272',
          'STATE' => 'Connected',
          'BUF' => '',
          'NAME' => 'WEB_<ip>_58577',
          'TEMPORARY' => 1
        };

2018.01.04 14:12:56 3: WLAN_RADIO: WEB
WEB_<ip>_58574
WEB_<ip>_58575
WEB_<ip>_58576
WEB_<ip>_63653    <- WEB_<ip>_58577 ist verschwunden???
WEB_<ip>_64209
WEB_<ip>_64210
WEB_<ip>_64217
WEB_<ip>_64218
WEB_<ip>_64221


Hier verschwindet genau das eine Device WEB_<ip>_58577 auf dem die Ausgabe erfolgen soll und dadurch funktioniert asyncOutput nicht. Hat jemand eine Vermutung woran das liegen könnte? Und weshalb passiert das nur unter iOS, nicht jedoch unter Windows oder Android?

mumpitzstuff

Bug oder Feature?

Inzwischen habe ich viele Dinge versucht und noch folgendes festgestellt (ich kann nur als Außenstehender beschreiben was ich sehe, ich kenne die internen Vorgänge nicht genau).

1.) Wenn ich FHEM in einem Browser aufrufe, dann wird logischerweise eine Verbindung aufgebaut, die sich dann in FHEM als WEB_<ip>_<port> wiederfindet.

2.) Wenn ich GetFn auslöse, dann scheint eine weitere Verbindung aufgebaut zu werden und diese resultiert wieder in einem WEB_<ip>_<port> Device. Diese findet man dann auch in $hash->{CL}, wenn man sich $hash->{CL} im Kontext von GetFn ansieht.

3.) Wenn ich einen Browser unter Windows/Android verwende, dann wird das unter 2.) erwähnte Device am Leben erhalten und ich kann mit asyncOutput darauf zugreifen und entsprechend Daten ausgeben.

4.) Wenn ich einen Browser unter iOS verwende, dann wird die Verbindung von 2.) einfach abgebaut und das Device gelöscht. Es ist somit egal was ich im Kontext von GetFn mit $hash->{CL} mache, die darin enthaltenen Daten werden einfach ungültig. asyncOutput funktioniert dann schlicht nicht mehr.

Wenn ich mir jetzt das Device aus 1.) mit einigen Befehlen suche, dann kann ich darüber aber wunderbar die Daten mit asyncOutput ausgeben und das sowohl auf Windows/Android als auch auf iOS.

Vermutung:
Die Probleme haben wahrscheinlich mit dem von mir verwendeten BlockingCall in Zusammenhang mit der Verwendung von iOS zu tun. Ich habe alle existierenden Module nach asyncOutput in Zusammenhang mit BlockingCall durchsucht und keins gefunden. Andere Module verwenden lediglich HttpUtils + asyncOutput.

Kann dazu noch irgend jemand etwas sagen? Ich komme hier nicht mehr weiter.


rudolfkoenig

@mumpitzstuff: 1.) und 2.) ist richtig, 3.) & 4.) nur halb.
- FW_AsyncOutput sucht die zu "deine" bzw. "get" CL gehoerende inform Verbindung und sendet die Daten darueber an dem Browser.
- Wenn "deine" bzw. die "get" Verbindung stirbt, dann wird sie aus $defs entfernt, und es gibt die "device gone" Meldung.

Ich habe FHEMWEB jetzt angepasst, dass als CL die inform Verbindung weitergegeben wird (wenn eins existiert, sonst der Ausloeser). Dafuer wird %FW_id2inform verwendet, wo die letzte inform Verbindung fuer jede aktuell Verbundene FHEMWEB-Seite gespeichert wird. Die Suche in FW_AsyncOutput habe ich entfernt, und $defs{$FW_wname}{asyncOutput} auch, weil ich meine, dass es nicht auftreten kann, weil eher die "get" Verbindung geschlossen wird, als die inform-Verbindung.

@mumpitzstuff/@choetzu: koennt ihr bitte testen?

@justme1968:
- falls ich mich wg. $defs{$FW_wname}{asyncOutput} irre, kannst du mir einen Fall konstruiren?
- wozu wird $hash->{canAsyncOutput} benoetigt?

justme1968

das die passende longpoll verbindung genommen wird war eigentlich schon immer so vorgesehen. das über den %FW_id2inform hash zu machen ist zwar im prinzip besser als das alte suchen zur laufzeit, es sollte unterm strich das gleiche passieren. ich bin mir nicht sicher was das iOS problem ist und ob deine änderung es löst.




$defs{$FW_wname}{asyncOutput} ist/war dazu da eine async ausgabe zwischenzuspeichern wenn die longpoll verbindung noch nicht (wieder) aufgebaut ist. direkt nach dem seiten aufbau (unwahrscheinlich) oder wegen buffer größe oder fehler zugemacht und neu aufgebaut wird. damals ist das auf jeden fall passiert. sonst hätte ich den fall nicht eingebaut. ich muss mal meine test fälle raus kramen und schauen ob das noch relevant ist.

mit dem %FW_id2inform statt der laufzeit suche geht das aber nur wenn der %FW_id2inform eintrag jeweils entfernt wird wenn die longpoll verbindung geschlossen wird.




die idee hinter canAsyncOutput ist: nicht jedes frontend muss asyncOutput (immer) unterstützen. ein modul kann dann gegebenenfalls auf blockieren und synchronen output zurück schalten.

z.b. wird FHEMWEB canAsyncOutput nicht auf 1 setzen wenn longpoll deaktiviert ist. das war zumindest vor zwei jahren nicht so selten.

telnet könnte canAsyncOutput erst 2-3 sekunden nach dem verbindungsprobleme aufbau aktivieren. damit würde man eine interaktive von einer per script aufgebauten verbindung z.b. per nc unterscheiden können. mit dauernd gesetztem canAsyncOutput bekommt ein per nc abgesetztes kommando keine antwort weil die verbindung abgebaut wird bevor die asynchrone antwort kommt.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

mumpitzstuff

#8
Ich habe es eben getestet und es funktioniert jetzt alles reibungslos auf allen Systemen. Ich habe allerdings an dem Modul inzwischen so viel rumgeschraubt um das Problem zu finden/umgehen, dass ich das jetzt erst mal zurück bauen muss. Ich melde mich morgen noch mal, im Moment sieht es aber sehr gut aus.

Hab jetzt alles rückgebaut und es funktioniert tadellos auf Windows 10, Android und jetzt auch iOS.

Vielen Dank!!!! Ich war schon am verzweifeln.

Ich hoffe jetzt nur, das die Änderungen nicht irgendwelche anderen negativen Auswirkungen nach sich ziehen. Wenn ich noch etwas untersuchen soll/kann, dann lasst ich mich wissen.

DS_Starter

Hallo zusammen,

nach dem update mit der Änderung bzgl. asynchOutput klappt meine bisher prima funktionierende Implementierung der Ausgabe einer Schnapschußgalerie in SSCAM nicht mehr über den get-Zweig.
Ich habe momentan keine Zeit mir das genauer anzuschauen wie/was ich an dieser Stelle nun wieder ändern muss damit es wieder funktioniert.
Wollte  nur erstmal bekannt geben dass die vorgenommene Änderung auf bestehende Implementierungen Einfluß hat/haben kann.
Melde mich später nochmal dazu wenn ich dazu gekommen bin mir dies genauer anzuschauen.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

rudolfkoenig

Zitatich bin mir nicht sicher was das iOS problem ist und ob deine änderung es löst.
iOS schliesst die "get" Verbindung, nachdem FHEM "Danke, noch keine Daten" gemeldet hat. Damit wird CL aus %defs entfernt, und asyncOutput meldet "device gone", auch wenn die Inform-Verbindung fuer diese Seite noch existiert. Die Aenderung setzt statt den urpruenglichen "get" Verbindung die Inform-Verbindung als CL.

Zitat$defs{$FW_wname}{asyncOutput} ist/war dazu da eine async ausgabe zwischenzuspeichern wenn die longpoll verbindung noch nicht (wieder) aufgebaut ist.
In diesem Fall duerfte aber auch noch keine Anforderung mit CL vom Browser gekommen sein. Nicht falsch verstehen: ich will asyncOutput nicht unbedingt weghaben, nur einen Fall kennen, wo es benoetigt wird. Aber vielleicht liefert DS_Starter das gleich :)

Zitatz.b. wird FHEMWEB canAsyncOutput nicht auf 1 setzen wenn longpoll deaktiviert ist. das war zumindest vor zwei jahren nicht so selten.
Soweit ich sehe, wird canAsyncOutput aktuell gesetzt, wenn das Frontend an FHEM eine Abfrage sendet, was mehr als die Auslieferung einer Datei bedeutet (z.Bsp. Raumuebersicht oder Detailansicht), d.h. es hat nichts mit longpoll zu tun.
Ich meine canAsyncOutput kann wegfallen: falls eine Inform-Verbindung gibt, dann werden die Daten darueber gesendet, sonst auf der "get" Verbindung. Und wer nach etwas fragt, der hat mit einer Antwort zu rechnen.
asyncOutput ermoeglicht in meinen Augen eine verspaetete Antwort auf eine Frage.
Wenn du damit was Anderes vor hast, dann bitte beschreibe es.

justme1968

1. ja klar das die get Verbindung geschlossen wird. deshalb hat der alte code nicht einfach die get connection genommen sondern die zum get gehörende longpoll verbindung gesucht: next if( !$chash->{inform} );

deshalb verstehe ich gerade den unterschied nicht.


2. doch :) damals wurde bei einem get die seite neu aufgebaut. zwischen dem absetzen der get und dem kompletten aufbau der seite steht die longpoll verbindung noch nicht. wenn das asyncOutput genau in diesem zeitraum etwas liefert geht es verloren. da inzwischen das get über xhr gemacht wird kann es sein das dieser fall nicht mehr relevant ist. damals war er es aber definitiv.

wenn das get ein redirect auf eine neue seite zur folge hat (gibt es das ?) gilt das gleiche.

wenn man in einen anderen raum wechselt auch.

für den fall das die longpoll verbindung von der js seite zu gemacht wird (fehler oder buffer größe) gibt es auch für einen kurzen oder längeren zeitraum keine longpoll verbindung.


3. das heisst aber nur das $canAsyncOutput aktuell an der falschen stelle gesetzt wird. es muss dann gesetzt werden wenn die longpoll verbindung aufgebaut wird. eigentlich muss die frontend seite sogar sagen 'ich kann asyncOutput'. da longpoll inzwischen nicht mehr nur von fhemweb genutzt wird ist das nicht mehr immer der fall.

die anderen beiden fälle die ich oben beschrieben hatte sind auch valide. der fallback auf get ist nicht der richtige ersatz da es ersten nicht immer geht und nur fhemweb betrifft.

ich denke $canAsyncOutput sollte bleiben und repariert werden. mach ich.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Zitatdeshalb verstehe ich gerade den unterschied nicht.
Wenn CL weg ist (aus %defs entfernt, wird bei close gemacht), dann ist asyncOutput eingeschnappt, und leitet die Anfrage nicht weiter. Die Abfrage koennten wir rausnehmen, habe ueber die Seiteneffekte noch nicht nachgedacht.

Zitatda inzwischen das get über xhr gemacht wird kann es sein das dieser fall nicht mehr relevant ist.
Ich glaube das ist das was ich uebersehen habe. Und dass mit fw_id auch ohne longpoll die "Kontinuitaet" einer Seite gegeben ist.

Nach meinem Gefuehl ist das Problem aber noch nicht sauber geloest. Hier eine Liste der Moeglichkeiten, die ich sehe:

1. Frontend hat nur eine Verbindung zu FHEM (w.bsp. wget, oder erste Version des FHEM Frontends), wartet auf Antwort ueber diese Verbindung. CL ist auf diese Verbindung gesetzt, asyncOutput sollte darueber die Daten zurueckliefern. Aktuell koennen wir diesen Fall nicht richtig behandeln, weil wir per HTTP zu frueh "kein Ergebnis" melden, wget mit einem FHEM-get liefert nie ein Ergebnis.

2. Frontend hat ein inform, will fuer get eine neue Seite aufbauen (zweite version des FHEM Frontends). In diesem Fall braucht man den asyncOutput Puffer, falls get schneller fertig ist, als die Inform-Anfrage vom Browser kommt. Das kann durchaus vorkommen.

3. Aktuelle Frontend-Variante: die Frage kommt per XHR, die Antwort geht ueber die bestehende Inform-Verbindung zurueck, asyncOutput braucht man trotzdem, weil bei einem nachfolgenden Raumwechsel die get-Antwort vor dem Aufbau der neuen inform-Verbindung eintreffen koennte. Ok, die Wahrscheinlichkeit dafuer ist sehr gering.

Zusammengefasst:
- man braucht den asyncOutput Puffer. Eigentlich muessten mehrere davon geben, je nach FW_id
- die %defs Pruefung muss aus asyncOutput() ausgebaut werden.
-  FW_asyncOutput muss nochmal ueber FW_id2inform gehen (wg. Raumwechsel)
- damit kann man einfachheitshalber die get Verbindung als CL uebergeben.
- canAsyncOutput ist in jedem Fall irrelevant, und kann entfernt werden.
- Fall 1 erfordert Unterstuetzung vom Modul ("die Antwort kommt spaeter, bitte keine HTTP-Antwort senden"), und Code in FHEMWEB. Bin noch unentschlossen, ob wir es implementieren sollten.

DS_Starter

#13
Hallo zusammen,

also erstmal Entwarnung von meiner Seite.

Ich habe das Update heute auf meiner Testmaschine vorgenommen und festgestellt dass die Ausgabe der Snaps nicht mehr sauber funktioniert (es fehlen Bilddaten im Popup). Nun hatte ich im Code hin und hergesucht um einen möglichen Fehler zu finden ... ohne Erfolg.
Dann habe ich mich entschlossen auf meinem Prod.Server das Update einzuspielen ... hier funktioniert alles nach wie vor problemlos !

Es ist zum Haareraufen, beide Server sind Debian Jessie, gleicher FHEM-Updatestand. Auch die Deviceeinstellungen der Cams habe ich verglichen und keine Unterschiede gefunden. Die Cam-Devices arbeiten von beiden Servern gegen das gleiche physikalische Device ... nichts zu machen.

Bin momentan dabei meine restlichen grauen Haare zu verlieren  ;)  ... aber was die asyncOutput-Änderung betrifft hat mein festgestelltes Problem wohl nichts damit zu tun, da muss ich weiter suchen.

Zitat- canAsyncOutput ist in jedem Fall irrelevant, und kann entfernt werden.
Das wäre eine für mich relevante Änderung. Zur Zeit stelle ich einen CL-Hash zusammen wenn der User zum Beispiel per Bwegungsmelder Schnappschüsse auslöst und sich dann auf dem Tablet die Schnappschüsse aufpoppen lassen möchte. In dem Fall wird das get ja nicht vom FHEMWEB ausgelöst.

Dazu schaue ich ob ein CL übergeben wurde. Wenn nicht analysiere ich die vorhandenen FHEMWEB-Instanzen bzgl. ihrer Eigenschaften, unter anderem auch auf canAsyncOutput=1, da ich bisher annahm dies wäre ein Merkmal um sicher zu stellen dass das WEB-Device das PopUp auch erzeugen kann.
Die ermittelten CL's werden dann für die Verwendung im asyncOutput im Helper gespeichert.


  if (!defined($hash->{CL})) {
      # Clienthash wurde nicht übergeben und wird erstellt (FHEMWEB Instanzen mit canAsyncOutput=1 analysiert)
      my $outdev;
      my @webdvs = devspec2array("TYPE=FHEMWEB:FILTER=canAsyncOutput=1:FILTER=STATE=Connected");
      my $i = 1;
      foreach (@webdvs) {
          $outdev = $_;
          next if(!$defs{$outdev});
  $hash->{HELPER}{CL}{$i}->{NAME} = $defs{$outdev}{NAME};
          $hash->{HELPER}{CL}{$i}->{NR}   = $defs{$outdev}{NR};
          $hash->{HELPER}{CL}{$i}->{COMP} = 1;
          $i++;  
      }
  } else {
      # übergebenen CL-Hash in Helper eintragen
  $hash->{HELPER}{CL}{1} = $hash->{CL};
  }


Wenn also asyncOutput irrelevant ist, kann ich mir den Check an dieser Stelle ja sparen (STATE=Connected) sollte dann ja reichen ?
Aber das versuche ich erst wenn ich wieder mit meiner Testinstanz im reinen bin  ;)

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

rudolfkoenig

ZitatZur Zeit stelle ich einen CL-Hash zusammen wenn der User zum Beispiel per Bwegungsmelder Schnappschüsse auslöst und sich dann auf dem Tablet die Schnappschüsse aufpoppen lassen möchte

Fuer sowas gibts schon laenger FW_directNotify.
Mich wundert, dass deine Loesung funktioniert, weil FW_ID nicht gesetzt ist, und auch die alte Variante es benoetigt hat.
Wenn mehrere Tablets verbunden sind, auf welchem sollte die Ausgabe stattfinden?

DS_Starter

#15
ZitatFuer sowas gibts schon laenger FW_directNotify.
Klappt das auch aus HttpUtils_NonblockingGet heraus ?
Also es gibt diese Funktion nun schon etliche Zeit und ich glaube mich zu erinnern auch mit FW_directNotify experimentiert zu haben ... kann mich aber auch täuschen. Wir hatten in der Vergangenheit auch schonmal bzgl. dieses Einsatzzwecks über asyncOutput philosophiert.

ZitatMich wundert, dass deine Loesung funktioniert, weil FW_ID nicht gesetzt ist, und auch die alte Variante es benoetigt hat.
ja, funktioniert.

ZitatWenn mehrere Tablets verbunden sind, auf welchem sollte die Ausgabe stattfinden?
Auf allen, die eben verbunden sind. Das war der Ansatz.

Edit: Um es mal ein bisschen greifbarer zu machen wie so ein popup aussieht den ich mit Hilfe von asyncOutput erzeuge, habe ich mal einen (älteren) Screeshot angehängt.

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

rudolfkoenig

ZitatMich wundert, dass deine Loesung funktioniert, weil FW_ID nicht gesetzt ist, und auch die alte Variante es benoetigt hat.
Ok, jetzt wundert es mich nicht mehr: asyncOutput hat $hash mit $defs{$hash->{NAME}} ersetzt.

ZitatEdit: Um es mal ein bisschen greifbarer zu machen wie so ein popup aussieht den ich mit Hilfe von asyncOutput erzeuge, habe ich mal einen (älteren) Screeshot angehängt.
*Staun*

Habe meine Vorschlaege von vorhin implementiert und eingecheckt. Abweichungen:
- asyncOutput uebernimmt aus Kompatibilitaetsgruenden $defs{$cl->{NAME}}, falls existiert. Vermutlich haette diese eine Zeile gereicht, um das urspruenglich Problem zu loesen.
- Bei einem Raumwechsel wird FW_id nicht behalten, und es ist mir zu viel Aenderung das einzubauen. D.h. der asyncOuput Puffer in FHEMWEB ist vermutlich aktuell sinnlos, ich habe es aber trotzdem wieder uebernomen.
- ich habe getAllSets/getAllGets mit einem optionalem $cl erweitert (was von FHEMWEB gesetzt wird), und sleep gibt $cl an die nachfolgenden Befehle weiter.

canAsyncOuput koennte man auch durch inform ersetzen, aber die devspec2array suche mit "inform=.+" ist kryptischer als "canAsyncOutput=1", und dann muessen auch die existierenden Module nicht geaendert werden, also kann canAsyncOuput von mir aus bleiben.

mumpitzstuff

Ich habe heute ein Update gemacht und erhalte jetzt wieder unter iOS:

Strange call for nonexistent WEB_109.193.91.155_51846: AsyncOutputFn

Die Fehlermeldung ist anders als früher, das Ergebnis leider das Selbe. Unter Android gehts. Windows habe ich bisher noch nicht getestet.

Ich hatte vorher noch den ersten Patch drin und damit hatte alles Problemlos funktioniert.

rudolfkoenig

ZitatStrange call for nonexistent WEB_109.193.91.155_51846: AsyncOutputFn
Sorry, das haette ich merken koennen. Ich meine ich habe das jetzt gefixt.

mumpitzstuff