NEWS
Aufruf an alle Nutzer von Bose Soundtouch / Teufel Raumfeld / Sonos / …
-
Hi Zusammen,
aus gegebenem Anlass bitte ich euch um Unterstützung. Die Integration von den oben genannten Systemen geht nur sehr langsam voran bzw. gar nicht.
Bisher ist nur Sonos integriert und das auch nicht Vollständig sondern lediglich die Funktionen die der Großteil der Anwender nutzt.
Da sehr viele Nutzer von ioBroker keine Adapter schreiben können/wollen/etc., sind die die es können immer Beschäftigt.
Um hier schneller voran zu kommen möchte ich Skripte schreiben die diese Systeme Nutzbar machen.
Hier gibt es 2 Hürden:
1. Ich hab nicht jedes dieser Systeme
2. Ist es sehr viel Schreib Arbeit
Hier kommt ihr ins Spiel. Fast alle AV Geräte Unterstützen upnp, die grundlegende Steuerung der Geräte läuft immer nach dem gleichen Schema.
Mit hilfe dieses Schemas ist es Quasi möglich jedes upnp fähige AV Gerät zu steuern.
Folgende Steuerbefehle sind immer möglich:
-
Play
-
Pause
-
Stop
-
Mute
-
Lautstärke ändern
Das hab ich auch schon in einem Skript zusammen gefasst.
Beispiel für Windows Mediaplayer:
! ````
var device = 'upnp.0.Jey_Cee_(JEYCEE-LENOVO_:_Windows_Media_Player)'; //hier das upnp Gerät eintragen das gesteuert werden soll
var control = 'javascript.0.WMP_lenovo'; //hier das Objekt eintragen wo die Steuerobjekte angelegt werden sollen
var oldVol;
! //createState(name, initialValue, forceCreation, common, native, callback);
createState(control + '.Play', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.play'});
createState(control + '.Pause', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.pause'});
createState(control + '.Stop', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.stop'});
createState(control + '.Vol_UP', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.volume_up'});
createState(control + '.Vol_Down', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.volume_down'});
createState(control + '.Mute', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.mute'});
! on({id: control + '.Play', val: true
}, function(obj){//Wiedergabe starten setState(device + '.MediaRenderer.AVTransport.Play.InstanceID', 0); setState(device + '.MediaRenderer.AVTransport.Play.Speed', 1); setState(device + '.MediaRenderer.AVTransport.Play', 'send'); });
on({id: control + '.Pause', val: true
}, function(obj){//Wiedergabe pausieren setState(device + '.MediaRenderer.AVTransport.Pause.InstanceID', 0); setState(device + '.MediaRenderer.AVTransport.Pause', 'send'); });
! on({id: control + '.Stop', val: true
}, function(obj){//Wiedergabe stoppen setState(device + '.MediaRenderer.AVTransport.Stop.InstanceID', 0); setState(device + '.MediaRenderer.AVTransport.Stop', 'send'); });
on({id: control + '.Vol_UP', val: true
}, function(obj){
oldVol = getState(device + '.MediaRenderer.RenderingControl.Volume').val;newVol = parseInt(oldVol) + 5; //der Wert um den die Lautstärke geändert wird, kann beliebig geändert werden //neue Lautstärke senden setState(device + '.MediaRenderer.RenderingControl.SetVolume.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetVolume.DesiredVolume', newVol); setState(device + '.MediaRenderer.RenderingControl.SetVolume.InstanceID', 0); setState(device + '.MediaRenderer.RenderingControl.SetVolume', 'send'); });
on({id: control + '.Vol_Down', val: true
}, function(obj){
oldVol = getState(device + '.MediaRenderer.RenderingControl.Volume').val;newVol = parseInt(oldVol) - 5; //der Wert um den die Lautstärke geändert wird, kann beliebig geändert werden //neue Lautstärke senden setState(device + '.MediaRenderer.RenderingControl.SetVolume.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetVolume.DesiredVolume', newVol); setState(device + '.MediaRenderer.RenderingControl.SetVolume.InstanceID', 0); setState(device + '.MediaRenderer.RenderingControl.SetVolume', 'send'); });
on({id: control + '.Mute', val: true
}, function(){
var oldMute = getState(device + '.MediaRenderer.RenderingControl.Mute').val;if(oldMute === 0){ setState(device + '.MediaRenderer.RenderingControl.SetMute.InstanceID', 0); setState(device + '.MediaRenderer.RenderingControl.SetMute.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetMute.DesiredMute', 1); setState(device + '.MediaRenderer.RenderingControl.SetMute', 'send'); //oldVol = getState(device + '.MediaRenderer.RenderingControl.Volume').val; }else{ setState(device + '.MediaRenderer.RenderingControl.SetMute.InstanceID', 0); setState(device + '.MediaRenderer.RenderingControl.SetMute.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetMute.DesiredMute', 0); setState(device + '.MediaRenderer.RenderingControl.SetMute', 'send'); } });
on({id: control + '.MediaURL'
}, function(obj){
setState(device + '.MediaRenderer.AVTransport.SetAVTransportURI.CurrentURI', obj.newState.val);
setState(device + '.MediaRenderer.AVTransport.SetAVTransportURI.InstanceID', 0);
setState(device + '.MediaRenderer.AVTransport.SetAVTransportURI', 'send');
});Beispiel für Sonos: >! ```` var device = 'upnp.0.192_168_0_230_-_Sonos_PLAY:1'; //hier das upnp Gerät eintragen das gesteuert werden soll var control = 'javascript.0.Sonos_Bad'; //hier das Objekt eintragen wo die Steuerobjekte angelegt werden sollen var oldVol; //Wird zur Berechnung der neuen Lautstärke genutzt >! //createState(name, initialValue, forceCreation, common, native, callback); createState(control + '.MediaControl.Play', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.play'}); createState(control + '.MediaControl.Pause', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.pause'}); createState(control + '.MediaControl.Next', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.next'}); createState(control + '.MediaControl.Previous', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.previous'}); createState(control + '.MediaControl.Stop', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.stop'}); createState(control + '.AudioControl.Vol_UP', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.volume_up'}); createState(control + '.AudioControl.Vol_Down', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.volume_down'}); createState(control + '.AudioControl.Mute', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.mute'}); createState(control + '.SleepTimer', false, {type: 'string', read: 'true', write: 'true'}); createState(control + '.MediaControl.MediaURL', false, {type: 'string', read: 'true', write: 'true'}); //Muss so aussehen: http://127.0.0.1:1234/Ordner/Name.mp3 createState(control + '.MediaControl.PlayMode', false, {type: 'string', read: 'true', write: 'true'}); //Mögliche Werte: NORMAL REPEAT_ALL REPEAT_ONE SHUFFLE_NOREPEAT SHUFFLE SHUFFLE_REPEAT_ONE createState(control + '.MediaControl.Crossfade', false, {type: 'boolean', read: 'true', write: 'true', role: 'button.crossfade'}); >! //Media Controls on({id: control + '.MediaControl.Play', val: true }, function(obj){ //Wiedergabe starten setState(device + '.MediaRenderer.AVTransport.Play.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.Play.Speed', 1); setState(device + '.MediaRenderer.AVTransport.Play', 'send'); setState(control + '.MediaControl.Play', false); }); on({id: control + '.MediaControl.Pause', val: true }, function(obj){ //Wiedergabe pausieren setState(device + '.MediaRenderer.AVTransport.Pause.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.Pause', 'send'); setState(control + '.MediaControl.Pause', false); }); >! on({id: control + '.MediaControl.Next', val: true }, function(obj){ //Wiedergabe pausieren setState(device + '.MediaRenderer.AVTransport.Next.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.Next', 'send'); setState(control + '.MediaControl.Next', false); }); on({id: control + '.MediaControl.Previous', val: true }, function(obj){ //Wiedergabe pausieren setState(device + '.MediaRenderer.AVTransport.Previous.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.Previous', 'send'); setState(control + '.MediaControl.Previous', false); }); on({id: control + '.MediaControl.Stop', val: true }, function(obj){ //Wiedergabe stoppen setState(device + '.MediaRenderer.AVTransport.Stop.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.Stop', 'send'); setState(control + '.MediaControl.Stop', false); }); on({id: control + '.MediaControl.PlayMode' }, function(obj){ setState(device + '.MediaRenderer.AVTransport.SetPlayMode.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.SetPlayMode.NewPlayMode', obj.newState.val); setState(device + '.MediaRenderer.AVTransport.SetPlayMode', 'send'); }); >! on({id: control + 'MediaControl.MediaURL' }, function(obj){ setState(device + '.MediaRenderer.AVTransport.SetAVTransportURI.CurrentURI', obj.newState.val); setState(device + '.MediaRenderer.AVTransport.SetAVTransportURI.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.SetAVTransportURI', 'send'); }); >! var oldCrossfadeMode on({id: control + '.MediaControl.Crossfade', val: true }, function(){ var oldCrossfadeMode = getState(device + '.MediaRenderer.AVTransport.CurrentCrossfadeMode').val; if(oldCrossfadeMode == 0){ setState(device + '.MediaRenderer.AVTransport.SetCrossfadeMode.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.SetCrossfadeMode.CrossfadeMode', 1); setState(device + '.MediaRenderer.AVTransport.SetCrossfadeMode', 'send'); setState(control + '.MediaControl.Crossfade', false); }else{ setState(device + '.MediaRenderer.AVTransport.SetCrossfadeMode.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.AVTransport.SetCrossfadeMode.CrossfadeMode', 0); setState(device + '.MediaRenderer.AVTransport.SetCrossfadeMode', 'send'); setState(control + '.MediaControl.Crossfade', false); } }); //Audio Controls on({id: control + '.AudioControl.Vol_UP', val: true }, function(obj){ oldVol = getState(device + '.MediaRenderer.RenderingControl.Volume').val; newVol = parseInt(oldVol) + 5; //der Wert um den die Lautstärke geändert wird, kann beliebig geändert werden //neue Lautstärke senden setState(device + '.MediaRenderer.RenderingControl.SetVolume.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetVolume.DesiredVolume', newVol); setState(device + '.MediaRenderer.RenderingControl.SetVolume.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.RenderingControl.SetVolume', 'send'); setState(control + '.AudioControl.Vol_UP', false); }); on({id: control + '.AudioControl.Vol_Down', val: true }, function(obj){ oldVol = getState(device + '.MediaRenderer.RenderingControl.Volume').val; newVol = parseInt(oldVol) - 5; //der Wert um den die Lautstärke geändert wird, kann beliebig geändert werden //neue Lautstärke senden setState(device + '.MediaRenderer.RenderingControl.SetVolume.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetVolume.DesiredVolume', newVol); setState(device + '.MediaRenderer.RenderingControl.SetVolume.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.RenderingControl.SetVolume', 'send'); setState(control + '.AudioControl.Vol_Down', false); }); on({id: control + '.AudioControl.Mute', val: true }, function(){ var oldMute = getState(device + '.MediaRenderer.RenderingControl.Mute').val; if(oldMute == 0){ setState(device + '.MediaRenderer.RenderingControl.SetMute.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.RenderingControl.SetMute.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetMute.DesiredMute', 1); setState(device + '.MediaRenderer.RenderingControl.SetMute', 'send'); //oldVol = getState(device + '.MediaRenderer.RenderingControl.Volume').val; setState(control + '.AudioControl.Mute', false); }else{ setState(device + '.MediaRenderer.RenderingControl.SetMute.InstanceID', getInstanceID()); setState(device + '.MediaRenderer.RenderingControl.SetMute.Channel', 'Master'); setState(device + '.MediaRenderer.RenderingControl.SetMute.DesiredMute', 0); setState(device + '.MediaRenderer.RenderingControl.SetMute', 'send'); setState(control + 'AudioControl.Mute', false); } }); >! //Funktionen function getInstanceID(){ var IID = getState(device + '.MediaRenderer.AVTransport.A_ARG_TYPE_InstanceID').val; return(IID); }
Es gibt je nach System/Gerät eine vielzahl an Steuermöglichkeiten, Sonos zum Beispiel bietet alles an was in der App möglich ist. Das kann ich aber nicht Automatisiert im upnp Adapter abbilden. Deswegen müssen hier Skripte erstellt werden, die diese Funktionen einfach für Anwender bereit stellen.
Hier möchte ich ein Bauskasten Prinzip nutzen nachdem die Funktionen erstellt werden um es mit wenig bis gar keinen Anpassungen für Unterschiedliche Systeme zu nutzen.
Wie könnt ihr jetzt Konkret helfen?
-
upnp Adapter installieren und Screenshots des ausgeklappten Objekt Baumes posten
-
selbst Skripte schreiben nachdem Schema meines Beispiels und sie hier posten oder mir Schicken
-
Skripte Testen und Fehler melden
Alles was ihr selbst hier beisteuert kommt euch selbst zu gute, da Bluefox und die anderen Entwickler dadurch entlasstet werden.
Somit von mir die Bitte an euch: Helft euch selbst.
-
-
Es gibt noch eine zweite Variante wie Ihr unterstützen könnt … für viele der Systeme gibt es auf npm bereits Module die vieles an Funktionalität abdecken ...
Beispiel:
https://www.npmjs.com/package/node-raumfeld
https://www.npmjs.com/package/soundtouch
u.ä.
Für die von Euch die ein bissl JavaScript können, wäre es hilfreich die NPM Module im JavaScript-Adapter zu installieren und die Liste der Funktionen von JeyCee mal zu implementieren. So kann ein Entwickler das ggf einfach übernehmen ... Auch das könnte Zeit sparen
-
Screenshots kannst du von mir bekommen. Es sind allerdings ca. 20-25 Seiten.
Kann man die Objekte nicht irgendwie exportieren?
-
Ich helfe auch gern, hab die Sonos daheim in Betrieb
Gruß
Adrian
Gesendet von iPhone mit Tapatalk Pro
-
Doch die gibt es, hab sie gerade gefunden:
-
Ich helfe auch gern, hab die Sonos daheim in Betrieb `
Sehr gut. Bist du Fit in JavaScript?
Ich Arbeite mich gerade durch den MediaRenderer -> AVTransport.
Hier der Code dazu:
Edit3: Code in den ersten Beitrag verschoben
Kannst du die RenderingControl übernehmen? Volume und Mute ist in meinem Script schon drin, das musst also nicht mehr machen.
Edit1: Skript ersetzt, grund dafür ist eine bessere Objektstruktur.
Edit2: Zusätzlich informationen zu den einzelnen Steuerungsmöglichkeiten von Sonos: https://godoc.org/github.com/ianr0bkny/go-sonos/upnp#AVTransport.AddMultipleURIsToQueue
-
Sonos: https://github.com/bencevans/node-sonos schon gesehn? Was kann der noch nicht?
-
@Jey Cee:Ich helfe auch gern, hab die Sonos daheim in Betrieb `
Sehr gut. Bist du Fit in JavaScript? `
Hallo Jey Cee
du bist gut…. ich kann leider in der Hinsicht nicht weiterhelfen
Kleine Scripte bekomme ich hin aber sowas umfangreiches
Gruß
Adrian
-
Kleine Scripte bekomme ich hin aber sowas umfangreiches
`
Das sieht nur Kompliziert aus. Ich Bastel heut Abend mal ein ganz einfaches Beispiel anhand dessen ich dir das Schema verdeutlichen kann.
Sonst hilft es mir auch schon wenn du das Skript testest und mir Feedback gibst wie logisch oder unlogisch die Arbeit mit den Objekten ist. Oder was dir sonst auffällt was man besser machen kann.
@appollon: Du hast recht es gibt für fast alles Node Pakete, die auch die Sachen können. Nur muss das genauso erstmal integriert werden und jeder Entwickler hat sein Paket anders aufgebaut. Ich benutze aber eine Standardisierte Schnittstelle, hier Unterscheidet sich lediglich der Funktionsumfang den ein Hersteller zur Verfügung stellt. Das Schema bleibt gleich. Damit ist es möglich mit wenig bis gar keinen Anpassungen viele Funktionen von einem Gerät zum anderen zu übernehmen. Während es aber nicht möglich ist eine Funktion die auf Basis eines Node Pakets geschrieben wurde auf ein anderes zu Übertragen.
Mein Grund Skript das ich Ursprünglich für den Windows Media Player geschrieben hab kann ich so wie es ist für jeden upnp player nehmen. Es gibt nur 2 ID's die angepasst werden müssen. Dann kann ich sofort die Wichtigsten Steuerlemente nutzen. Das bezieht sich nicht nur auf die oben angegebenen Systeme. Hier mal noch andere Geräte: Xbox One, Samsung TV's, Yamaha AV, Sony AV, PS3/4, Chromecast, … Die Liste ist endlos lang.
Dazu kommt ich kann mir ein View bauen das ich einfach nur Kopieren muss und die Objekt IDs Anpassen muss und schon ist es erledigt. Wenn daraus jetzt noch ein Widget gemacht wird, bei dem nur die Übergeordnete ID eingegeben werden muss und alle Elemente werden Automatisch verknüpft, erstellt man die Visualisierung für einen Player mit 2 Klicks.
An diesem Punkt kann ioBroker deutlich vereinfacht, die Entwicklungszeit bzw. die Integration von neuen Geräten beschleunigt und die Wartung vereinfacht werden.
Stell dir mal vor du Installierst dir ioBroker, du hast eines von Tausend am Markt verfügbaren Internetradios und kannst nicht Programmieren.
Jetzt gibt es noch keinen Adapter dafür, wie bekommst du es über ioBroker gesteuert?
Wäre es da nicht schön, einfach ein Script zu nehmen bei dem es völlig egal ist ob dein Internetradio von Hersteller x oder y ist und zumindest schon mal Grundlegende Funktionen steuern zu können.
Es ist viel einfacher jemandem zu erklären das er Adapter x und y installieren muss das Skript in den Javascript Adapter packen muss und die ersten 2 Zeilen an zu passen. Als ihm das Programmieren bei zu bringen oder selbst ein Skript/Adapter zu schreiben.
Mal ganz davon abgesehen das es einen riesen Unterschied macht ob ich 2 oder 10 Adapter laufen lassen muss um alle meine Geräte zu Steuern.
Und den Javascript Adapter installiert man ja eh auf den meisten Hosts. Mit Blick auf die Schwächeren Hosts wie RPi oder BPi, macht das besonders viel sinn.
Ganz davon abgesehen das man die Abhängigkeiten von anderen Node Pakten dadurch reduzieren kann.
Langfristig ist mein Ziel die Skript mit dem Adapter zu liefern und als Beispiel Skripte im JS Adapter an zu bieten. Eventuell sogar die Skripte Automatisch dort zu Platzieren und gleich die notwendigen ID's anpassen. Damit es wirklich Plaug and Play ist.
-
Aber, wenn ich das richtig verstehe, schreit das ja mehr nach einem 'spezial' upnp Adapter, als nach Scripten.
Klar kann man zum testen jetzt etwas mit den Scripts arbeiten. ABER wäre das nicht einfacher für die Benutzer , wenn das ein Adapter wäre.
Da kann man jedes Media Gerät in den Settings einfügen und der Adapter macht die nötigen Objekte zu Steuerung. Die Auswahl für die Geräte könnte sogar vom upnp Adapter her kommen. :?:
-
Aber, wenn ich das richtig verstehe, schreit das ja mehr nach einem 'spezial' upnp Adapter, als nach Scripten.
Klar kann man zum testen jetzt etwas mit den Scripts arbeiten. ABER wäre das nicht einfacher für die Benutzer , wenn das ein Adapter wäre. `
Noch einen Adapter will ich vermeiden. Ich sehe jetzt auch nicht was es verinfachen würde noch einen Adapter zu bauen der das selbe macht nur "versteckt".Da kann man jedes Media Gerät in den Settings einfügen und der Adapter macht die nötigen Objekte zu Steuerung. Die Auswahl für die Geräte könnte sogar vom upnp Adapter her kommen. `
Das ist genau mein Ziel, der Adapter soll am Ende alles von sich aus machen. Es soll nicht mal nötig sein irgendwelche Gerät eintragen zu müssen.Am Ende soll in den Einstellungen eine Checkbox sein, wenn die Aktiviert ist werden Automatisch für alle Geräte, auch nicht Media Geräte (FritzBox, Epson Drucker, …), entsprechende Skripte geladen, angepasst und Aktiviert.
-
Ja gut soweit; aber den Teil mit den Scripten verstehe ich noch nicht.
Was können die Javascripte, was Dein Adapter nicht kann? (Vielleicht steh ich gerade auf dem Schlauch(Sind vielleicht die Medikamente(Ist aber auch egal)))
-
@Jey Cee:Eventuell sogar die Skripte Automatisch dort zu Platzieren und gleich die notwendigen ID's anpassen. Damit es wirklich Plaug and Play ist. `
Wenn du dafür nen Tip brauchst, meld dich. Ich habe das schon gemacht (ein Skript erstellt ein anderes und führt es aus).Stimme ykuendig aber in seinem Argument zu. Für unbedarfte Nutzer ist es einfacher, auf das [+] in der Adapterliste zu klicken und ein Gerät aus nem Dropdown auszuwählen, als im JS-Adapter Skripte zu verwalten (hier muss man auch noch den richtigen Engine-Typ auswählen etc…)
Die Hemmschwelle, Code zu kopieren und anzupassen, wird deutlich höher sein. Dann wird hier oder da ein " vergessen und schon muss nach Hilfe geschrien werden.
-
Ja gut soweit; aber den Teil mit den Scripten verstehe ich noch nicht.
Was können die Javascripte, was Dein Adapter nicht kann? (Vielleicht steh ich gerade auf dem Schlauch(Sind vielleicht die Medikamente(Ist aber auch egal))) `
Der Adapter stellt nur die Kommunikation bereit. Upnp ist ein relativ Komplexes Konstrukt, was es wiederum sehr Universell macht, daher auch der Name "Universal-plug-and-play". Um hier keine Verluste zu erzeugen, Bilde ich die Schnittstellen Beschreibung der Geräte in den ioBroker Objekten ab. Diese Schnittstellen Beschreibungen werden von dem jeweiligen Gerät als xml ausgeliefert, diese wiederum sind immer nach dem selben Schema aufgebaut. Für Unterschiedliche Geräte/Dienste gibt es auch Unterschiedliche Schemas die von einem Komitee festgelegt werden und allen zugänglich sind.Ich habe mehr als 50% der Entwicklungszeit darauf verwendet die Struktur zu verstehen und in ioBroker logik zu übersetzen.
Die Skripte dienen nur noch zur Steuerung innerhalb von ioBroker, während die Kommunikation vom upnp Adapter übernommen wird.
Im Grunde könnte auch auf die Skripte verzichtet werden und direkt über den upnp Adapter kommuniziert werden. Nur ist es für die meissten zu Kompliziert die Struktur zu verstehen und damit zu Arbeiten.
Die Skripte sind Eigentlich nur eine Vereinfachung und Vereinheitlichung um dem Modularen Prinzip das ioBroker zu grunde liegt zu entsprechen.
Es wäre auch möglich Adapter zu schreiben die die Objekte vom upnp Adapter zur Kommunikation mit dem Gerät nutzen, während der Adapter sich um die Logik kümmert und noch andere Schnittstellen, die nicht via upnp verfügbar sind, einbindet.
@Jey Cee:Eventuell sogar die Skripte Automatisch dort zu Platzieren und gleich die notwendigen ID's anpassen. Damit es wirklich Plaug and Play ist.
Wenn du dafür nen Tip brauchst, meld dich. Ich habe das schon gemacht (ein Skript erstellt ein anderes und führt es aus).
Immer her damit. -
Poste ich hier, sobald ich daheim bin.
-
@Jey Cee:Doch die gibt es, hab sie gerade gefunden:
get_Objekt.PNG `
Schicke dir gleich meinen Export. Sind immerhin 2,4MB json File.
Du bekommst eine PN.
-
So langsam wächst das Fleisch am Knochen.
Wie wäre denn - nur mal lose als Idee - wenn der upnp (oder ein Partner-) Adapter die 'einfache' Gerätestruktur einfach als Objekte(gruppe) erstellt und pollt und mit den Geräten kommuniziert. Für jedes per Dropdown ausgewählte Gerät wird ein Objekt-Gerät aufgebaut. Neben oder ohne den Monster-Baum vom upnp.
Dann kann ein jeder von vis oder manuell oder - wer mag - auch mit Scripten draufhauen, nach gutdünken.
-
@Jey Cee:Immer her damit.
`
Bittesehr:
`for (var i = 0; i < scripts.length; i++) { script = scripts[i]; bData = b64.toByteArray(script.data); buffer = new Buffer(bData); obj = getObject("script.js." + script.name); obj.common.source = buffer.toString(); setObject("script.js." + script.name, obj) }` scripts ist bei mir ein Array von Objekten dieser Form: `~~[code]~~{ name: "ScriptName", data: "<base64 encoded/string="">" } [/code]</base64>` Essentiell sind die letzten 3 Zeilen, wo dein Code (source) herkommt ist eigentlich wurst.[/i]
-
Habe Bose im ganzen Haus verteilt. Steuer diese über Mediola zur Zeit. Über CCU geht es auch. Bin leider zur Programmierung nicht zu gebrauchen, nur copy and past aus dem Netz. Braucht ihr die ganzen Steuerbefehle?? Wie kann ich euch trozdem helfen, ein funktionierender Adapter für meine Bose wäre toll, bzw. halt einer für viele Syteme.
-
für die Bose Soundtouch nutze ich derzeit dieses Script zum Einstellen der Lautstärke und des Preset.
Vielleicht hilft es…
createState('Bose.Volume', 10); createState('Bose.Preset_1', {type: 'boolean'}); createState('Bose.Preset_2', {type: 'boolean'}); createState('Bose.Preset_3', {type: 'boolean'}); function PresetSetzen(pWert) { var BodyString = '<key state="release" sender="Gabbo">' + pWert + '</key>'; var request = require('request'); request.post({ url: 'http://192.168.xxx.xx:8090/key', //body: '<volume>20</volume>' body: BodyString }, function(error, response, body) { if (error) log(error, 'error'); }); } function VolumeSetzen(pWert) { var BodyString = '<volume>' + pWert + '</volume>'; var request = require('request'); request.post({ url: 'http://192.168.xxx.xx:8090/volume', //body: '<volume>20</volume>' body: BodyString }, function(error, response, body) { if (error) log(error, 'error'); }); } on ({id: "javascript.0.Bose.Volume", change: "ne"}, function () { lVolume = getState("javascript.0.Bose.Volume"); VolumeSetzen(lVolume.val); }); on ({id: "javascript.0.Bose.Preset_1", val: true}, function () { PresetSetzen('PRESET_1'); setState("javascript.0.Bose.Preset_1", false); }); on ({id: "javascript.0.Bose.Preset_2", val: true}, function () { PresetSetzen('PRESET_2'); setState("javascript.0.Bose.Preset_2", false); }); on ({id: "javascript.0.Bose.Preset_3", val: true}, function () { PresetSetzen('PRESET_3'); setState("javascript.0.Bose.Preset_3", false); });