NEWS
Tips und Tricks zum Sonos Adapter
-
Nach einigem Trial and Error habe ich mal mein Vorgehen zur Ansteuerung meiner Sonos Lautsprecher aufgeschrieben.
Ich habe das Ganze auf Englisch gemacht, weil ich es nach Review in die Sonos Dok auf dem GitHub stellen möchte.
BItte Feedback bzgl. Terminologie, Inhalt und Verständlichkeit
Tips and Trick using the Sonos Adapter
Playing arbitrary sounds
If you want to play sounds with the Sonos Adapter you can use the “tts” state which is located under the Sonos Adapter object e.g. sonos.0.root.192_168_178_32.tts.
The tts state is meant to play the mp3 file created by the related sayit Adapter but it can also be used to play sound from any server that is able to provide access to a mp3 file via http.
Conveniently if you have the sayit Adapter installed you also have instantiated such a server that is able to provide mp3 files that a located under <the folder/where/iobroker/is/installed="">/ioBroker-data/files/sayit.<instance of/sayit/adapter="">. e.g. in a Linux installation “/opt/iobroker/iobroker-data/files/sayit.1/tts.userfiles/gong.mp3”
The command to playback a file can be constructed the by following.
setState(<state of/the/sonos/tts/state="">,”<volume>;<soundserverurl><mp3file>”)
e.g.
setState(“sonos.0.root.192_168_178_32.tts”,30; sayit.1/tts.userfiles/gong.mp3”).
Avoiding command collisions
The Sonos Command interface requires a certain sequence and is susceptible to errors if it receives concurrent commands from difference, independent sources. The symptoms which I observed where that sound play back was not working anymore and that the playback list in the sonos app was proliferated by sequence of sayit.1.mp3 files.
To block concurrency, I have created an interface which handles all sonos commands for all my scripts.
var soundserverurl = 'http://192.168.178.78:8082/'; var path_of_soundfiles = 'sayit.1/tts.userfiles/'; var speechfile = 'state/sayit.1.tts.mp3'; var sonosWZstate = 'sonos.0.root.192_168_178_32.state'; var sonosWZvolume = "sonos.0.root.192_168_178_32.volume"; var sonosWZtts = "sonos.0.root.192_168_178_32.tts"; var Harmony_currentStatus= "harmony.0.Wohnzimmer.activities.currentStatus"; var sonosactive = false; var sonosvolume; var alarmvolume = 100; var sonosWZdefaultvol = 40; function sonosmp3play(sound,vol) { var harmony = getState(Harmony_currentStatus).val; if (!sonosactive && ((harmony === 2) || (harmony === 0))) { sonosactive = true; sonosvolume = getState(sonosWZvolume).val; if (vol === undefined) vol = sonosWZdefaultvol; setState(sonosWZtts,vol+";"+soundserverurl + sound); } else { log("Sonos speaker busy"); } } on({id:sonosWZstate, change: 'ne'},function(obj) { if (sonosactive && (obj.state.val==='stop')) { sonosactive = false; setStateDelayed(sonosWZvolume,sonosvolume,1000); } });The functionality is working as such. If a sound should be played back on the sonos speaker the function sonosmp3play is called which receives the parameter sound and volume.
The parameter sound contains the path and the file which can be served by your sound server. (e.g. “sayit.1/tts.userfiles/gong.mp3”).
The function only issues the command to the sonos speaker if the semaphore sonosactive is false (see below) and no commands from my harmony hub are active.
Sonosactive is a semaphore that is set true if a sonos sound is played back. It is set to false again if the playback of the sound is completed. If this semaphore is set concurrent sounds are not played and the log says “sonos speaker busy”.
Additionally, I have added a second semaphore which is true if my harmony hub is actively changing to different state because also the harmony hub can issue commands to sonos speaker which may also create conflicts.
Tip on saving memory space
In my case I have a wall mounded tablet which receives every sayit commands. The sayit adapter is therefore configured to “browser”. After the text2speech conversion the related mp3 can also be used by the sonos speaker without installing a second instance of sayit adapter for the sonos speaker. Therefore I am using the sonosmp3play function to play back this generated file. The issueing of the sonosmp3play has to be delayed until the mp3 file has been generated. In my case a delay of 2 seconds is working. The location of this file can be reach under e.g.'state/sayit.1.tts.mp3'.
The additional benefit is that the playback of this text to speech sound file is also protected by the mechanism described above.</mp3file></soundserverurl></volume></state></instance></the>