UPnP - Simple Service Discovery Protocol (SSDP) als Basismodul

Begonnen von klaus.schauer, 23 September 2020, 20:19:55

Vorheriges Thema - Nächstes Thema

klaus.schauer

Zitat von: KölnSolar am 23 Januar 2021, 13:32:48
Folgendes muss ablaufen:
- 3 NOTIFY-messages als "advertisement"(quasi "server hello") als multicast an 239.255.255.250:1900
  - rootdevice mit parameter: location, devicetype,urn
  - device UUID...
  - devicetype(service)...
- 3 NOTIFY-messages als "advertisement"(quasi "disconnect") als multicast an 239.255.255.250:1900
  (keine "neuen" Parameter nötig)
 
Die Parameter könnte man als "Schnittstelle" über Attribute definieren
Das 2-stufige Modell hat über die X_Parse-Funktion u. a. den Vorteil, dass die nachgelagerten Module automatisch Devices anlegen können, sobald sie die für sie passenden SSDP-notify-Meldungen eines für sie noch unbekannten DeviceManagers erhalten. Dies über eine permanente Überwachung von Fhem-notifys durch die nachgelagerten Module machen zu wollen, führt dazu dass die SSDP-notifys permanent Fhem-notifys auslösen müssten. Dies gilt auch für die SSDP-bye-Meldungen.

Zitat
Spannend wird es dann mit der "Forderung", dass auch auf Port 1900 gelauscht werden soll, für den Fall, dass der SHM connected NACHDEM das device sich zuvor connected hatte. Entweder haben wir nun einen Konflikt(Controlpoint lauscht bereits auf 1900), weil das DeviceManager-device auch port 1900 öffnen will oder das Paket ist so gebaut, dass der Controlpoint genutzt wird. Müsste man ausprobieren wie sich das beim DeviceManager verhält.
Bei letzterem Fall müsste der Controlpoint den search request an das device weiterreichen. Dieses sendet als Antwort die o.g. 3 notifys.

Edit: Ich bin so weit. Nur leider wurde ich bestätigt: Es "krallt" sich den Port 1900. Gut, dann wieder schließen und UPNPControlpoint danach definieren. Aber dann gehen die requests vom SHM unter. Keine Idee wie ich das dem Controlpoint entlockt bekomme. Das Problem ist ja, dass das Lesen u. verarbeiten eingehender search-messages in der black-box upnp-Paket erfolgen. :'(
Ich hatte angenommen, dass das SSDP-Paket einen Parallelbetrieb der ControlPoint- und DeviceManager-Funktionen ermöglich. Schade wenn es nicht so wäre.

Wzut

Zitat von: KölnSolar am 18 Januar 2021, 20:34:03
danach geht alles wie von selbst und über die Zeit sammeln sich die readings
Wollte ich bei mir mal testen , aber selbst bei verbose 5 blieb das Log leer :(
Im nächsten Schritt habe ich set searchterm ssdp:all versucht : die ersten Zeilen im Log über gefundene Geräte, aber keine neuen Readings.
Schritt zwei :   in der sub _addedDevice das $testflag auf 1 gesetzt , jetzt gibt es einige neue Readings.
In Summe hat er zwei FBs erkannt und das Synologie NAS, aber vom SMA HM2.0 ist da nichts zu sehen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

klaus.schauer

Zitat von: Wzut am 24 Januar 2021, 11:13:09
Wollte ich bei mir mal testen ... In Summe hat er zwei FBs erkannt und das Synologie NAS, aber vom SMA HM2.0 ist da nichts zu sehen.
Der SMA HomeManager ist in UPnP-ControlPoint, der UPnP-DeviceManager sucht. Fhem müsste also ein UPnP-DeviceManager sein. Diese Funktion ist bisher in Fhem nicht vorhanden.

KölnSolar

#33
Ja. Ein Controlpoint sendet keine Notify-messages und empfängt sie nur. Entweder auf eigenen request oder periodisch(in der Regel wohl 30min.) durch ein device(keep-alive) ausgelöst.
ZitatIm nächsten Schritt habe ich set searchterm ssdp:all versucht : die ersten Zeilen im Log über gefundene Geräte, aber keine neuen Readings.
Das wundert mich. Logging und Anlage von readings findet gleichzeitig statt. Ich hab zwischenzeitlich noch einmal die searchterms über Wireshark getestet, weil auch bei mir irgendwie unklar war, auf welchen searchterm die devices reagieren. In der letzten Version hab ich bei der Initialisierung upnp:rootdevice. Da konnte ich aber jetzt mit Wireshark gar keine Reaktion feststellen. Wohl aber mit ssdp:all Warte auch mal  die 30min. ab, um vielleicht devices zu bekommne, die nicht auf einen search-request reagieren.
ZitatBei ShellyMonitor verwende ich die IO::Socket::Multicast-Bibliothek. Den Socket öffne ich mit
$conn = IO::Socket::Multicast->new(LocalPort=>5683, ReuseAddr=>1) or $err = "Cannot open Multicast socket: $^E";
damit eben "auch andere" ihn belauschen können. Ist das eine Lösung für Dein Problem, oder habe ich da etwas nicht verstanden?
Ich hab dann mal den Quellcode studiert. Für 1900 wird tatsächlich reuse benutzt. Hilft nur leider wenig, denn meines Erachtens kann die FHEM-selectloop ja nur einen filedescriptor bedienen. Wäre  auch nicht so schlimm. Ich hab es jetzt so definiert, dass nur der Controlpoint lauscht und per ReadFn bedient wird. Nun hab ich aber das Problem, dass ich hier bereits ähnlich und unbeantwortet angefragt hatte: Lesen ohne "Leeren" der message queue, um zu entscheiden, wer die Nachricht verarbeiten soll und dort dann auch noch die message zur Verfügung steht.
ZitatDas 2-stufige Modell hat über die X_Parse-Funktion u. a. den Vorteil, dass die nachgelagerten Module automatisch Devices anlegen können, sobald sie die für sie passenden SSDP-notify-Meldungen eines für sie noch unbekannten DeviceManagers erhalten. Dies über eine permanente Überwachung von Fhem-notifys durch die nachgelagerten Module machen zu wollen, führt dazu dass die SSDP-notifys permanent Fhem-notifys auslösen müssten. Dies gilt auch für die SSDP-bye-Meldungen.
Bei dem bisher "sichtbaren" Bedarf halte ich das in der Entwicklung zu aufwändig. Und eigentlich muss doch sowieso alles manuell angelegt werden. Die "nachgelagerten" Module kennen doch gar kein SSDP. :-\ Umgekeht könnt ich mir eher noch vorstellen, dass bei der Definition eines devices eines "nachgelagerten" Moduls ein passendes UPNPdevice erzeugt wird.

Ich lass jetzt mal den Controlpoint und DeviceManager in 2 unterschiedlichen FHEM-System laufen, um den SHM zu simulieren. Sobald es stabil läuft attache ich die Versionen und beschreibe es ein wenig.

Grüße Markus

Edit: Ich attache mal meine xml-Beschreibung zum SEMP-device. Basis ist die Specification von SMA u. Literale habe ich mal angepasst. Uns fehlen der deviceType(müsste man mal wissen, was ein Gateway da nutzt bzw. der SHM "will") und eine uuid(der Einfachheit halber sollte die durch den user ermittelt und ins Template eingetragen werden. Ich hab mal http://www.uuid.online dazu ausprobiert).
So sehen dann im Controlpoint die readings aussetstate UPNP_Controller 2021-01-25 11:05:05 192.168.x.y:4004-UDN uuid:UUID
setstate UPNP_Controller 2021-01-25 11:05:05 192.168.x.y:4004-friendlyName this is just a test device
setstate UPNP_Controller 2021-01-25 11:05:05 192.168.x.y:4004-location http://192.168.x.y:4004/opt/fhem/SEMPdevice.xml
setstate UPNP_Controller 2021-01-25 11:05:05 192.168.x.y:4004-manufacturer FHEM
setstate UPNP_Controller 2021-01-25 11:05:05 192.168.x.y:4004-modelName FHEM UPNP SEMP device
setstate UPNP_Controller 2021-01-25 11:05:05 192.168.x.y:4004-presence online

Und so der Aufruf der "location" über einen Browser. Man sieht, dass das Modul die URLBase generiert und hinzugefügt hat.<?xml version="1.0"?>
-<root xmlns="urn:schemas-upnp-org:device-1-0">
-<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
-<device>
<deviceType>urn:domain-name:device:deviceType:ver</deviceType>
<friendlyName>this is just a test device</friendlyName>
<manufacturer>FHEM</manufacturer>
<modelName>FHEM UPNP SEMP device</modelName>
<UDN>uuid:UUID</UDN>
<serviceList> </serviceList>
<deviceList> </deviceList>
-<semp:X_SEMPSERVICE xmlns:semp="urn:schemas-simple-energy-management-protocol:service-1-0">
<semp:server>http://IP[:port]</semp:server>
<semp:basePath>/SEMP</semp:basePath>
<semp:transport>HTTP/Pull</semp:transport>
<semp:exchangeFormat>XML</semp:exchangeFormat>
<semp:wsVersion>x.y.z</semp:wsVersion>
</semp:X_SEMPSERVICE>
</device>
<URLBase>http://192.168.x.y:4004</URLBase>
</root>
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

klaus.schauer

Der Einstieg in die UPnP DeviceManager-Funktionen ist ja auch schon gemacht. Damit habe ich jetzt noch gar nicht gerecht, super und danke. Im u. a. File habe ich mal hoffentlich brauchbare Parameter aus der SEMP-Spezifikation eingetragen. Die IP-Adressen müssten für Tests nur noch passend gemacht werden. Dann könnte ein stolzer Besitzer eines SMA Home Managers mal sehen, was das Gateway mit den Parametern anstellt. Eigentlich sollte es dann periodisch versuchen, das Gateway abzufragen.

KölnSolar

#35
Wieso hast Du einen service eingetragen ? Wir haben doch gar keinen UPnP-service beim Gateway.  :-\ UPnP/SSDP wird doch "nur" für connect/disconnect benutzt und nach einem connect entnimmt der SHM aus dem Abschnitt semp:X_SEMPSERVICE die Daten für den http-SEMP-server u. Pfad.

Ich hab noch Probleme von blockierendem Verhalten. Ich blicke noch nicht, was da blockiert. Erst wenn ich da schlauer bin, veröffentliche ich die Version.
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

klaus.schauer

In der SEMP-Spezifikation Kap. 3.2.2/Service List wird empfohlen, einen NULL-service als dummy service aufzunehmen, siehe auch Beispiel auf Seite 16.

KölnSolar

Ah ja, so weit hatte ich gar nicht gelesen.  ::) Ich halte es aber trotzdem für sinnfrei einen service im Netz zu propagieren, den es nicht gibt. Keine Information auf die ein anderes device subscriben könnte, keine action, die ein Controller auslösen könnte. Oder anders formuliert: Ein Service ohne Leistung ist doch kein service.  ;D Und der SHM(das einzige device, das sich wirklich für das Gateway "interessiert") braucht es nicht.
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

KölnSolar

Hab ichs mir doch irgendwie gedacht. War aber zu unbedarft, zumal seltsamerweise(für mich) die Perl warning PERL WARNING: Loading device description failed with error: 500 read timeout (Location: http://192.168.x.y:4004/opt/fhem/SEMPdevice.xml)erst nach Einschalten von stacktrace gelogged wurde. :o Und stacktrace sagt, dass es das parallel laufende UPNPController ist, das das Problem hat, wenn es das advertisement auf 1900 empfängt und das device anlegen möchte. Dabei tritt dann der unspezifische 500 auf. Irgendwo in den Modulen LWP, HTTP...

t.b.c.
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

KölnSolar

kurzes update: der 3*20s freeze kommt aus dem Controlpoint(3 notifys vom DeviceManager) . Ich bin ihm(u. dem timeout=20s) näher gekommen, aber noch nicht identifiziert. Ich hab daher ein wenig am Modul bzgl. defmod etc. und exclusion gearbeitet und als workaround nun die IP ausgeschlossen. ::)

Der neue Renderer(DLNAManager ?) bekommt als logisches Modul schon die events vom Controlpoint zur Verarbeitung u. autocreate funktioniert auch(tw.).
Nächste Schritte:
- Befehle vom logischen Modul über den Controlpoint an das enddevice
- initial subscription bei device definition
- disable-flag(unsubscribe)
- finales Design
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

KölnSolar

So, ich hab jetzt mal einen neuen Thread zu meiner Entwicklung mit den Attachements aufgemacht. Weil UPNPDevice eher uninteressant für den gewöhnlichen Anwender ist, sollten wir die weitere Entwicklung hier diskutieren. Neue Versionen würde ich im anderen Thread ablegen. Das description.xml ist Dein letzter Stand für das SEMPdevice.

Viel hab ich nicht mehr geändert. Die wenige Funktionalität start, stop, advertise sollte funktionieren. Und dann wäre das meines Erachtens schon fast erledigt.(mal abgesehen von der freeze-Thematik.

Nun bin ich gespannt auf Deinen Testbericht.

Grüße Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

klaus.schauer

Herzlichen Dank für Deine Arbeit an den Modulen. Nach dem ersten Start , bisher ohne UPNPDevice, werden diverse UPnP-Manager Devices gefunden und DLNA-Devices angelegt. Leider gibt es beim Fhem-Restart aber Probleme. Fhem start nach der Fehlermeldung

2021.02.16 12:26:44 2: UPNPController: UPNP Controller v0.0.1 started
Can't call method "services" on an undefined value at ./FHEM/98_UPNPController.pm line 947, <$fh> line 947.

mit

2021.02.16 12:26:45 1: Including fhem.cfg

immer wieder neu.

KölnSolar

Hi,
danke fürs testen.

Ähnliche Probleme hab ich befürchtet(getestet hatte ich den restart nie  :-[). Ich nehme an, Du hattest services subscribed ? Dann ist die Problematik sicherlich, dass die vorhandenen readings(per setstate) noch nicht wieder gefunden wurden. Hast Du dann erneut subscribed oder war das dann ein renewal, also subscribed,shutdown,restart ?

Ich hatte mir schon überlegt, ob es nicht einfacher, sogar sinnvoller ist, bei jedem define sämtliche readings des Controllers zu löschen. Die vorhandenen logischen devices müssten solange in den presence=offline Status(könnte man evtl. beim restart generell machen). Was meinst Du ?

Nach längerer Zeit hab ich dann auch  mal wieder UPNPDevice getestet. Ich fiel auf die Nase. :o Irgendwie war das Problem der filename. Teste also bitte erst einmal mit der im Thread attachten description.xml. Dort hab ich gegenüber Deiner letzten Version nur minimalste Veränderungen vorgenommen, weil sonst spaces/tabs/lf im reading stehen.

Grüße Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

klaus.schauer

Zitat von: KölnSolar am 16 Februar 2021, 13:01:59
Ähnliche Probleme hab ich befürchtet(getestet hatte ich den restart nie  :-[). Ich nehme an, Du hattest services subscribed ? Dann ist die Problematik sicherlich, dass die vorhandenen readings(per setstate) noch nicht wieder gefunden wurden. Hast Du dann erneut subscribed oder war das dann ein renewal, also subscribed,shutdown,restart ?
Ich habe bisher keine Aktionen ausgelöst. Folgende Devices wurden automatisch angelegt:

define UPNP_Controller UPNPController
setuuid UPNP_Controller ?
attr UPNP_Controller userattr acceptedUDNs defaultRoom ignoreUDNs
define DLNAManager_192.168.6.41_8080 DLNAManager 192.168.6.41_8080
setuuid DLNAManager_192.168.6.41_8080 ?
attr DLNAManager_192.168.6.41_8080 userattr channel_01 channel_02 channel_03 channel_04 channel_05 channel_06 channel_07 channel_08 channel_09 channel_10 multiRoomGroups ttsLanguage
attr DLNAManager_192.168.6.41_8080 IODev UPNP_Controller
attr DLNAManager_192.168.6.41_8080 room DLNAManager
define FileLog_DLNAManager_192.168.6.41_8080 FileLog ./log/DLNAManager_192.168.6.41_8080-%Y.log DLNAManager_192.168.6.41_8080
setuuid FileLog_DLNAManager_192.168.6.41_8080 ?
attr FileLog_DLNAManager_192.168.6.41_8080 logtype text
attr FileLog_DLNAManager_192.168.6.41_8080 room DLNAManager
define DLNAManager_192.168.6.40_8080 DLNAManager 192.168.6.40_8080
setuuid DLNAManager_192.168.6.40_8080 ?
attr DLNAManager_192.168.6.40_8080 userattr channel_01 channel_02 channel_03 channel_04 channel_05 channel_06 channel_07 channel_08 channel_09 channel_10 multiRoomGroups ttsLanguage
attr DLNAManager_192.168.6.40_8080 IODev UPNP_Controller
attr DLNAManager_192.168.6.40_8080 room DLNAManager
define FileLog_DLNAManager_192.168.6.40_8080 FileLog ./log/DLNAManager_192.168.6.40_8080-%Y.log DLNAManager_192.168.6.40_8080
setuuid FileLog_DLNAManager_192.168.6.40_8080 ?
attr FileLog_DLNAManager_192.168.6.40_8080 logtype text
attr FileLog_DLNAManager_192.168.6.40_8080 room DLNAManager

Zitat
Ich hatte mir schon überlegt, ob es nicht einfacher, sogar sinnvoller ist, bei jedem define sämtliche readings des Controllers zu löschen. Die vorhandenen logischen devices müssten solange in den presence=offline Status(könnte man evtl. beim restart generell machen). Was meinst Du ?
Das kann ich nicht beurteilen, da ich die Auswirkungen auf die logischen Devices nicht abschätzen kann.

KölnSolar

 ;D ;D ;D
ZitatIch habe bisher keine Aktionen ausgelöst
Doch hast Du.
ZitatFolgende Devices wurden automatisch angelegt
Bei der Anlage wird auch automatisch das subscribe ausgeführt.  ;)
Das Problem liegt dann darin, dass beim restart natürlich auch wieder für das DLNA-device subscribed werden soll. Warum das dann aber nicht fluppt, muss ich mir im Hinblick auf den restart mal in Ruhe angucken. Oder nein, jetzt wird's mir klar. Das DLNA-device wird angelegt. Die subscription geht dann in die Hose, weil der Controller den service noch gar nicht kennt(noch gar kein alive-NOTIFY angekommen ist).

Muss ich mir in Ruhe zu Gemüte führen.

Auf die Schnelle könntest Du so um Zeile 240 rum das
  my ($dev) = $hash->{helper}{$uniqueDeviceName};
  my $upnpService = UPNPController_GetService($hash, $dev, $service);

durch das my ($dev) = $hash->{helper}{$uniqueDeviceName};
return if (!defined($dev));
  my $upnpService = UPNPController_GetService($hash, $dev, $service);
ersetzen.

ZitatDas kann ich nicht beurteilen, da ich die Auswirkungen auf die logischen Devices nicht abschätzen kann.
Doch, kannst Du.  ;) Es ist ja so, dass die reading-names des Controller sich NIE verändern, egal, ob man später per IP oder UDN einschränkt, das device gar nicht mehr im LAN existiert..... Da würde es meines Erachtens Sinn machen, wenn wenigstens zu jedem restart eine Löschung erfolgt. "Noch" vorhandene/gewünschte devices werden beim Restart, spätestens beim nächsten Einschalten wieder gefunden. Man hat dann wieder eine aktuelle Übersicht bzw. nur die gewünschten devices. Sonst schleppt man den reading-"Schrott" ewig mit sich rum. Das logische device muss eh erst einmal im offline-Status verbleiben, bis es vom Controller "entdeckt" wurde und dadurch in den online-state wechselt. Ansonsten ist der Zustand undefiniert und in der jetzigen Version passiert dann das von Dir geschilderte Problem.
Grüße Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt