Sonos: Neues Feature "LoadSearchlist"

Begonnen von Reinerlein, 06 Februar 2015, 21:14:06

Vorheriges Thema - Nächstes Thema

Reinerlein

Hallo zusammen,

ich hatte die Tage mal etwas Luft, und habe ein lange geplantes Feature eingebaut: "LoadSearchlist".

Damit kann man sich Titel aus der Sonos-Bibliothek zusammensuchen und in die aktuelle Abspielliste übertragen lassen.
Wenn man zum Beispiel 50 zufällige Titel aller Best-of-Alben in die Abspielliste packen will, schreibt man nur noch:

set Sonos_Wohnzimmer LoadSearchlist Tracks . /(?i)best.of/ *50-

Will man das ganze noch auf einen Interpreten einschränken, kann man folgendes schreiben:

set Sonos_Wohnzimmer LoadSearchlist Tracks . /(?i)best.of/(?i)pet.shop.boys *50-

Das ganze braucht bei meiner ca. 20.000 Titel enthaltenen Bibliothek allerdings ca. 4 Minuten, in denen der Sonos-Subprozess beschäftigt ist (Fhem wird natürlich nicht geblockt).
Die anderen Kategorien gehen wegen der geringeren Grundmengen deutlich schneller (eher im unteren Sekundenbereich). z.B. 20 beliebige Titel der Pet Shop Boys:

set Sonos_Wohnzimmer LoadSearchlist Artists /(?i)pet.shop.boys/ // *20-


Als Grundlage dient der Bereich "Bibliothek" auf dem Sonos-Controller. Alles was man dort durchsuchen kann, kann man auch hiermit machen... (Spotify z.B. geht damit nicht, da diese Suche durch den Sonos-Controller selbst durchgeführt wird, und nicht von den Playern).

Die verfügbaren Kategorien kann man sich wie folgt ermitteln:

get Sonos_Wohnzimmer SearchlistCategories


Weitere Infos wie immer im Wiki...

Als weitere Änderungen sind reingekommen:

  • Es wurde im Standard-RemoteControl-Design ein :blank zwischen den Steuerbefehlen und den drei Umschaltbefehlen ("MuteT", "ShuffleT" und "RepeatT") eingefügt.
  • Es gibt ein neues Reading "roomNameAlias", das den Namen enthält, der für das Attribut "alias" beim Erkennen des Players verwendet werden würde (z.B. "Wohnzimmer - Rechts"). Wird zu Laufzeit mit aktualisiert.
  • Es gibt zwei neue Setter-Befehle "LoadSearchlist" und "StartSearchlist". Mit diesen kann eine dynamisch erzeugte Playliste mit Titeln aus der Sonos-Bibliothek geladen werden. Nähere Informationen dazu im Wiki.
  • Es gibt einen neuen Getter-Befehl "SearchlistCategories", mit dem die möglichen Kategorien für den Aufruf von "LoadSearchlist" oder "StartSearchlist" ermittelt werden können.

Wie immer jetzt im SVN, oder ab Morgen im Update...

Grüße
Reinerlein

justme1968

das ist ein sehr schönes feature. klasse.

könnte man über die gleiche schnittstelle die du hierzu verwendest informationen aus der library auch nur auslesen? also z.b. alle alben (und cover) oder interpreten, ...?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Reinerlein

Hi Andre,

es wird eine Fehlermeldung erzeugt, wenn der Kategoriewert nicht matcht. Diese Meldung enthält im Normalfall die gültigen Möglichkeiten.

Also:

set Sonos_Wohnzimmer Albums XXXXXX
Liefert dir eine Fehlermeldung im Reading "LastActionResult" (es sei denn, du hast ein Album mit Namen XXXXXX ;) ) wo alle möglichen Alben enthalten sind.

Oder brauchst du es systematischer?
Die Frage ist nur, was dann alles in einer solchen Ergebnisliste enthalten sein muss... das wird ganz schnell ganz groß und unhandlich (bei mir sind das hunderte Alben, und tausende Titel)...

Grüße
Reinerlein

justme1968

das sind es bei mir auch :)

die idee wäre in die noch zu bauenden readingsGroup einen browser für die alben mit einzubauen. d.h. direkt aus fhem heraus in der library zu blättern ohne erst auf die sonos app zu wechseln. das würde es für die jenigen familienmitglieder die nicht mehr zu fhem zurück finden deutlich einfacher machen :) und das info panel an der wand bleibt in fhem.

die idee ist noch unausgegoren und ich weiss auch noch nicht ob es wirklich praktikabel ist. damit könnte man aber ein paar dinge einbauen die mit der normalen sonos app nicht möglich sind. z.b. bestimmte player auf bestimmte titel/genre zu beschränken. z.b. im kinderzimmer nur die kinder hörspiele und auch nur for den player dort.

vielleicht ist es aber auch sinnvoller das über sonopad zu machen. die app kann man scheinbar auch direkt in einer bestimmten ansicht öffnen.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Reinerlein

Hi Andre,

also um die Möglichkeiten zu konkretisieren.
Man kann über die Schnittstelle auf der Item-Ebene (das ist die unterste Ebene, wo ich auch diese Titel/Album/Interpret-Filterung drin habe) folgende Informationen auslesen:
- Titel
- Album
- Interpret
- Coververweis
- Ressource (Verweis auf die Datei)
- OriginalTrackNumber

Ich könnte da also z.B. eine Datei generieren o.ä. bezweifele aber, dass du das in einer ReadingsGroup unterbekommst... das wird echt viel Quellcode, wenn das alles in einer Auswahl im Code zur Verfügung stehen muss... Dynamisches Nachladen dürfte wegen der Latenzen die User-Experience nicht gerade steigern...

Melde dich, wenn du dahingehend was gebrauchen könntest... dann schauen wir, wie wir das am Besten rausholen...

Grüße
Reinerlein

der-Lolo

ich hatte ursprünglich mal ähnliche pläne, für mich wurde die aufgabe aber schnell viel zu komplex - ich experimentierte damals mit ampache und hatte es im weblink am laufen...

justme1968

nur eine readingsGroup zu parametrisieren wäre sicher nicht der richtige weg. 

die grobe idee ist nicht den ganzen code in die readingsGroup zu stecken sondern in ein fhem widget zu stecken das eigenintelligenz hat und direkt mit fhem kommuniziert. auf js und jquery-ui ebene gäbe es die probleme mit einer starren readingsGroup nicht. so lange das dynamische nachladen nur zwischen browser und fhem nötig ist und nicht aus dem sonos library könnte sogar das gehen. mit den letzen änderungen an fhemweb geht hier inzwischen einiges.

dieses widget würde dann z.b. in eine readingsGroup gesteckt.

ich bin mir eigentlich ziemlich sicher das es gehen müsste. ich weiß aber noch nicht ob ich den aufwand da rein stecken möchte.

das die informationen prinzipiell zu bekommen sind war aber grundvoraussetzung.

ich probiere mal ein paar dinge aus und melde mich dann.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

justme1968

hallo reiner,

ich habe die idee mal etwas weiter verfolgt und kann im web frontend eine liste einblenden die beim klick auf einen eintrag eine ebene tiefer springt und sich vom fhem server die einträge dieser nächsten ebene holt. es gibt auch eine kopf um eine ebene zurück zu springen. also im prinzip das was die sonos software macht wenn man in der musikbibliothek blättert.

das ganze ist erst mal ein test um zu schauen wie die geschwindigkeit beim nachladen der nächsten ebene ist. die daten die angezeigt werden sind erst mal reiner text (d.h. noch keine icons) aber dafür wird jede ebene komplett geholt und nicht erst beim scrollen fehlende zeilen angefügt. das funktioniert mit bis über 3000 zellen pro ebene völlig problemlos. ich gehe davon aus das man mit dynamischem laden der liste ohne probleme beliebig grosse listen durchblättern kann.

von der architektur schaut das ganze zur zeit so aus:
- es gibt ein fhem device list
- zu diesem gibt es auf browser seite das entsprechende gegenstück das die liste anzeigt
- beim klicken im browser werden vom fhem device jeweils die anzeigenden daten angefordert

- die idee wäre jetzt fhem device und js frontend so flexibel zu machen das im prinzip beliebige listen bzw. bäume navigiert werden können. etwas in richtung model, view, controller architektur
- das fhem device bekommt eine konfigurierbare funktion mit der eine perl datenstruktur aufbereitet werden kann
- jeder knoten sollte aus einem optionalen icon und einem text bestehen und entweder das letzte element sein oder noch weitere knoten enthalten können

damit könnte man dann das gleiche widget im frontend und das gleiche modul im backend verwenden um die sonos bibliothek und die favoriten und radio listen anzuzeigen und darin zu navigieren. und man könnt es für andere multimedia module wie z.b. xbmc verwenden. nur das interface in den internen baum müsste jeweils angepasst werden.

von den ideen ist noch so gut wie nichts umgesetzt, geschweige denn hübsch gemacht und es würde noch eine ganze menge arbeit drin stecken. prinzipiell sollte aber alles funktionieren und nicht an latenzen scheitern.

ich würde das ganze als nächstes gerne mal mit 'echten' daten testen. siehst du eine möglichkeit auf einfache art einen solchen baum im speicher in eine verschachtelte liste/hash zu stecken den man dem sonos device auf irgend eine art entlocken kann?

ich weiss nicht wie schnell das sonos system diese daten zurück liefern kann aber ich vermute es wäre gut diesen baum zu cachen und nur auf anforderung bzw. ein mal nachts zu aktualisieren.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Reinerlein

Hi Andre,

ich kann natürlich den kompletten Baum vom Sonos-System abfragen. Das wird nur eine Weile dauern, da ja dann so ziemlich alles übertragen werden muss, was im Player bekannt ist. Hinzukommt, dass viele Einträge auf der "untersten" Ebene (also den eigentlichen Titeln) doppelt vorkommen dürften.

Das würde man aber noch über verschiedene Hashes lösen können:
- Ein Hash, welches die Navigationsstruktur mit den Containern abbildet (also z.B. {Interpreten}->{Pet Shop Boys}->{*ALLE ALBENTITEL*}->{*ID des Titelhashs*}) Die Struktur wäre dann die aus dem Bereich "Bibliothek" im Sonos-Controller...
- Ein Hash welches die eigentlichen Titel enthält, der Key ist dann die Sonos-interne Item-ID, wie sie auch in der Navigationsstruktur abgelegt ist.

Die Abfragezeit wird schon in den Minutenbereich gehen (ja nach Bibliothek), und was noch wichtiger ist: Währenddessen kann keine andere Fhem-Anfrage an einen Sonos-Player versendet werden (oder von dort empfangen werden), da der SubProzess-Thread mit der Abfrage der Werte beschäftigt ist.
Das muss man bei der Zeitplanung berücksichtigen. Anbieten würde sich da ja ein Zeitpunkt nach der Bibliotheksaktualisierung...

Aber was mir noch nicht so klar ist:
Wie soll ich diese Datenmasse am Besten vom SubProzess in einen (bzw. zwei) Hash in Fhem bekommen?
Ich muss ja irgendwie über meine Datenverbindung rüber, Fhem wird solange blockiert, und wie soll es dann in Fhem selbst abgelegt werden?
Ich könnte natürlich im SubProzess eine XML-Datei ablegen, in der diese Daten komplett enthalten sind, und den Fhem-Prozess im Ergebnis antriggern, diese zu parsen und irgendwo Speicherintern abzulegen.
Dann bliebe nur noch die Frage nach eben dieser Ablage.

Kann man das einfach in so ein Device-Hash schreiben?
Was macht Fhem mit so einem Device, wenn dort im Hash vielleicht mal 20-50MB Daten enthalten sind?
Ich habe ca. 22.000 Titel, wenn im Schnitt so ca. 500Bytes an Informationen im Titel abgelegt sind, dann macht das allein für den Titel-Hash mal eben 11MB. Zzgl. der Navigationsstruktur, in der ja auch noch mal ein Haufen Informationen enthalten sind...

Sollte das lieber in eine Art "globale" Variable in einer myUtils abgelegt werden? Dann wäre es nach einem Fhem-Neustart aber weg...

Hast du dazu eine Idee?

Grüße
Reiner

justme1968

hallo reiner,

ich bin gerade dabei mit dem search list feature zu experimentieren. ich bekomme aber leider bei get SearchlistCategories nichts zurück. hast du eine idee woran das liegt ?

noch mal zur datenmenge: über die verbindung müssten nicht alle daten auf ein mal sondern ebenen weise. je nach sortierkriterium eventuell noch mal häppchenweise. die daten müssen aber auch nur ein mal nach der aktualisierung vom Supports nach oben gereicht werden. der subprozess braucht die daten eigentlich niemals selber. d.h. er könnte auch in ein file schreiben und das fhem modul liest dieses bei bedarf. zur laufzeit kann das das durchaus in den device hash. das wäre vielleicht sowieso ein feature das auf einer mini plattform nicht mehr funktioniert. oder man steckt wenn irgendwann alles geht noch mal etwas in die optimierung. oder man trennt es von fhem komplett ab und steckt das browsen und zurückliefen der daten in einen supports den man per socket abfragen kann. dann würde es fhem nicht beeinträchtigen und liesse sich theoretisch sogar auf einen eigenen rechner auslagern.


und noch etwas anderes: ich bin gerade am überlegen wie ich die aktuelle (ungesicherte) titelliste inklusive der aktuellen position an einen anderen player übertragen kann. also nicht nur den aktuellen titel wie im wiki beispiel. dazu soll es dann auch ein kleines interface geben. quelle player auswählen, ein oder mehrere ziel player, übertragen button. das ganze soll nicht wie in der app über gruppieren erfolgen weil hierbei der quellplayer seine liste bzw. die aktuelle position verliert.

gibt es hierzu ein get das die titel der aktuelle liste liefert? auch wenn diese nicht gespeichert ist.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Reinerlein

Hi Andre,

ich hin an dem Thema leider noch gar nicht vorangekommen, da ich in letzter Zeit mal wieder wenig freie Zeit hatte, und diese für Bugfixings verwendet hatte :)

Ich persönlich würde vermutlich die Datei-Variante am Einfachsten finden. Dann kann der SubProzess den Hash ermitteln und einfach per Dumper in Text umwandeln und in eine Datei wegschreiben.
Dann braucht man nur einen Mechanismus, um diese Datei wieder auszulesen und per eval wieder in einen Hash zu packen...
Dann hat man auch gleich einen Cache über Neustarts hinweg ermöglicht.

Dann würde ich im Modul nur noch eine Prozedur mitliefern, die diese Datei einfach lesen und in die Internals eines übergebenen Fhem-Devices übertragen kann.
Dann wäre alles da, damit du von "der anderen Seite aus" auf diese Daten in Fhem mit Methoden zur Übertragung auf die Oberfläche zugreifen kannst...

Wäre das ein gangbarer Weg? Ich würde dann als Ebenen die von Sonos vorschlagen und eine Trennung zwischen der Struktur und den eigentlichen Titeln machen...

Zu deiner aktuellen Abspielliste:
Ich schaue mal, dass ich den LoadPlaylist-Befehl so erweitere, dass man ein SonosPlayer-Device angeben kann, und dann entsprechend dessen aktuelle Abspielliste geladen wird.
Momentan kannst du dir über eine temporäre Playliste behelfen:

set Sonos_Quelle SavePlaylist TMPTRANSFER
set Sonos_Ziel LoadPlaylist TMPTRANSFER 1

Der Nachteil hier ist, dass da eine temporäre Playliste im Sonos-System rumlungert, da man mit dem Modul (noch) keine Playliste löschen kann.

Zum "get SearchlistCategories":
Das landet asyncron im Reading "LastActionResult". Dort müsste im Fehlerfall auch eine Fehlermeldung stehen, die hoffentlich bei der Problemsuche helfen kann :)

Grüße
Reiner

justme1968

das auslesen der mediendatenbank klingt so gut.

eine einzelne temporäre liste ist erst mal ok. das löschen kommt ja bestimmt demnächst :)

da hab ich nicht aufgepasst und gedacht das get liefert direkt etwas zurück.

wie wäre es dafür (wie in den meisten modulen) ein set requestSearchlistCategories zu verwenden das dann asynchron abgearbeitet wird und das get direkt die dann vorhandenen daten zurück liefern zu lassen?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Reinerlein

Hi Andre,

mit Änderungen von Befehlen und Logik tue ich mich immer sehr schwer :)
Zumal in diesem Modul alle Get-Befehle, die vom Player beantwortet werden müssen (nur Alarm und EthernetPortStatus bilden eine Ausnahme, da sie nur eine Vereinfachung für den Anwender darstellen sollen), indirekt arbeiten.
Ansonsten greift man ja einfach auf die bestehenden Readings zu.
Für diese Verarbeitung von Antworten gibt es ja schon ein Beispiel über UserReadings, dann hat man dort auch die Freiheit über die Reading-Namen...

Grüße
Reiner

Reinerlein

Hi Andre,

ich habe das mit dem Export gerade mal eingebaut. Ich werde da nochmal eine Nacht drüber schlafen, es morgen dokumentieren, und dann einchecken :)
Da das ja ein "verstecktes" Feature ist, was die übrige Funktionalität nicht beeinflußt, können wir da ja über den normalen Update-Mechanismus gehen...

Hier schon mal die Ermittlungsdaten bei mir auf meinem Windows Server mit Intel Core i5 bei 2.8GHz:
- Grundlage: ca. 21.000 Titel in der Bibliothek
- 8 Minuten Dauer
- 1GB RAM Belegung beim Ermitteln und Abspeichern
- Resultierende Textdatei: ca. 52MB
Das erscheint mir eher unhandlich für einen Raspberry Pi, berücksichtigt allerdings nur die sichtbare Belegung (durch den Process Explorer ermittelt) :)

Wie gesagt, werde ich das Morgen (eigentlich also heute) im Laufe des Tages/Abends einchecken, wenn ich wieder etwas aufgeräumt und vor Allem ein bißchen dokumentiert habe...

Und dann müssen wir mal schauen, ob das Hash-Format so OK ist, und u.U. anpassen :)

Grüße
Reiner

Reinerlein

Hi Andre,

so, ich habe das mit dem Export also gerade eingecheckt...
Im Wiki unter http://www.fhemwiki.de/wiki/SONOS#Die_Funktionalit.C3.A4t_.22ExportSonosBibliothek.22 habe ich eine Beschreibung der Features und dem Datenformat abgelegt.

Ich hatte Gestern noch einiges vergessen, sodass er nicht alle Daten abgeholt hatte. Nun sollte alles drin sein...
Damit hat sich auch gleich die Laufzeit auf eine knappe halbe Stunde erweitert, und die Dateigröße auf ca. 90MB (bei meinen 22.000 Titeln).

Wenn du etwas im Datenformat vermisst, oder etwas fehlerhaft oder unklar ist, einfach melden...

Grüße
Reiner