Page 1 of 9
Python plugin: Sonos [old version]
Posted: Wednesday 18 January 2017 22:18
by G3rard
Tester22 wrote an excellent plugin for Sonos as part of the new Python plugin by @Dnpwwo
https://www.domoticz.com/wiki/Developin ... hon_plugin.
The plugin is available at
https://github.com/tester22/Domoticz-Sonos.
Just place the code in a file called plugin.py and place it in the folder domoticz/plugin/sonos.
After a restart of Domoticz you can add your Sonos via the Hardware settings under Sonos Players.
The Python plugin is still in beta and only available on the latest Domoticz beta versions.
See
http://www.domoticz.com/forum/viewtopic.php?f=4&t=15233.
Re: Python plugin: Sonos
Posted: Wednesday 18 January 2017 22:31
by G3rard
@Tester22, I was wondering how I can add more information from the Sonos player to the python script (I have zero python knowledge...).
The script uses GetPositionInfo to get details on the song that is being played.
Is there any information which data is present in the PositionInfo?
And is it also possible to add data from GetMediaInfo?
I currently use a PHP script for the status of my Sonos which retrieves data from PositionInfo and MediaInfo.
The MediaInfo containts the best information regarding the radio station which is playing.
For example:
* PositionInfo shows "Qmusic_nl_nonstop_96.mp3" where MediaInfo shows "QMusic Nonstop" which is the actual name of the radio station.
* The Sonos plugin shows "None - Qmusic_nl_nonstop_96.mp3" when playing radio, and with the PHP script it shows "QMusic Nonstop - Mirrors - JUSTIN TIMBERLAKE" (using streamContent from PositionInfo for the artist and song being played).
Hopefully there is some information available on this so I can try to add some more fields to the script.
Re: Python plugin: Sonos
Posted: Saturday 21 January 2017 9:55
by tester22
Hi, didn't notice you mentioned me so found this thread by accident.
Anyway the plugin was just a test of the new capabilities of the python plugins and I have planed to clean it up once the http functions was added to the api.
Do you have any example of your php code you are using and I will implement it while cleaning up the current code.
My philosophy have as always been to avoid load when possible (e.g. Don't check mediainfo we hen nothing is playing) but if this only is some more calls I can of course implement it.
Re: Python plugin: Sonos
Posted: Saturday 21 January 2017 17:05
by G3rard
This is the PHP code I currently use. It's using the PHP wrapper from
https://github.com/gerard33/sonos.
Thanks for looking into this
Code: Select all
<?php
//----------fill in parameters below----------
$path='http://127.0.0.1/fp/sonos/'; //localhost, path to Sonos Wrapper
//$path='http://192.168.1.157/fp/sonos/'; //used for debugging
$status_off="Uit"; //message shown when Sonos is not playing
$sonos=array( //key and value of Sonos, key corresponds to idx in Sonos Wrapper config file
'115' => 'kantoor', //key, value
'116' => 'keuken'
);
$ar1=getSonosInformation('kantoor'); //not so nice, but call function for each sonos
$ar2=getSonosInformation('keuken');
$album_info='';
//----------end of parameters----------
//array_walk($sonos, 'getSonosInformation'); //start function for all values from array
$output=json_encode(array_merge($ar1, $ar2));
//$output=json_encode(array_merge(array_walk($sonos, 'getSonosInformation')));
print_r($output);
//echo $album_info;
function getSonosInformation($sonos_name) {
global $path,$status_off,$sonos; //load variables
//echo '<pre>'; print_r($sonos); echo '</pre>'; //show array
//echo '<pre>'; print_r(array_values($sonos)); echo '</pre>'; //show values from array
//echo '<pre>'; print_r(array_keys($sonos)); echo '</pre>'; //show key from array
$id = array_search($sonos_name, $sonos); //search sonos id from array corresponding to name
//get info from Sonos
$mediainfo=json_decode(file_get_contents($path.'index.php?zone='.$id.'&action=GetMediaInfo'),true); //media info
$positioninfo=json_decode(file_get_contents($path.'index.php?zone='.$id.'&action=GetPositionInfo'),true); //position info
$volumeinfo=file_get_contents($path.'index.php?zone='.$id.'&action=GetVolume'); //volume info
if(!empty($mediainfo['title'])) { //title not empty then radio is played, get data from GetMediaInfo
$title=$mediainfo['title']; //radio station
$streamcontent=$positioninfo['streamContent']; //what is playing
$album=''; //no album information
$artist=''; //no artist information
} else { //other source, get data from GetPositionInfo
$title=$positioninfo['title']; //title of the song
$title=substr($title, 0, 50); //show first 50 characters
$artist=$positioninfo['artist']; //artist
$album=$positioninfo['album']; //album
$album=substr($album, 0, 30); //show first 30 characters
$album_info=$positioninfo['albumArtURI']; //URL to album picture
$album_info=stripslashes($album_info);
if(!empty($positioninfo['albumTrackNumber'])) { //tracknumber can be on 2 places
$tracknumber=$positioninfo['albumTrackNumber'];
} else {
$tracknumber=$positioninfo['Track'];
}
$streamcontent= '#'.$tracknumber; //shows: #:10
}
//get status of Sonos
$status=file_get_contents($path.'index.php?zone='.$id.'&action=GetTransportInfo', 'r');
if ($status != 1) { //1=Playing, 2=Pause, 3=Stopped
$title=$status_off; //title empty if Sonos is not playing
}
//make JSON from array
$ar=array();
if ($title==$status_off) { //if Sonos is not playing
$ar[$sonos_name] = array(
"playing" => $title
);
} else {
if(!empty($mediainfo['title'])) {
if(!empty($streamcontent)) {
$ar[$sonos_name] = array(
"playing" => $title.' - '.$streamcontent, //radio station and number <br>
);
} else {
$ar[$sonos_name] = array(
"playing" => $title, //radio station
);
}
} else {
$ar[$sonos_name] = array(
"playing" => '<a target="blank" href="'.$album_info.'">'.$artist.' - '.$title.'</a>', //artist and number with link to album information
);
}
}
return $ar;
}
?>
Re: Python plugin: Sonos
Posted: Sunday 22 January 2017 14:14
by tester22
Hi.
I do not want to make unneccecary calls to the the players but have implemented something that I think is good enough.
Have a look and let me know if this is enough:
https://github.com/tester22/Domoticz-Sonos
Re: Python plugin: Sonos
Posted: Sunday 22 January 2017 23:47
by G3rard
Thanks for the update. Much appreciated!
It's now showing the song which is playing on the radio
But not all radio stations are showing that information, so in that case nothing is being showed.
So is it possible that you implement the title from GetMediaInfo? And prevent unneccessary calls by only loading that info when creator is empty?
Re: Python plugin: Sonos
Posted: Monday 23 January 2017 8:41
by tester22
Ok, will try to implement it.
The problem is that all web calls are asynchronous but I could place an global variable.
The drawback of this is that the radio station might be wrong for a couple of seconds after any change.
Re: Python plugin: Sonos
Posted: Tuesday 24 January 2017 13:01
by mvzut
Great, it worked instantly for me!
Well, almost instantly. I assumed the IP adress didnt matter as I expected it to look for all Sonos players in the current network and add devices for each of them. This didn't seem to work, so I changed the address into the IP address of my (only) Sonos player, which did the trick. Or was this a coincidence and should it find all players?
Would you reckon that setting the polling interval to e.g. 5 seconds would be a problem? I would like to experiment with automatic switching on/off my amplifier (I have a Sonos Connect). I am now doing this using Eventghost running on a Windows server, since the Sonos plugin in Eventghost sees state changes immediately (don't know how it does that by the way). But at the moment this is the ONLY reason for having Eventghost running on that system, I would prefer to do everything from Domoticz.
Re: Python plugin: Sonos
Posted: Tuesday 24 January 2017 13:07
by tester22
Well the problem is that autodiscover would be slow but maybe it could be fixed.
I see no problem setting it to 5. I use the same config on my sonos conenct to start the amplifier and switch to the right input.
Python plugin: Sonos
Posted: Tuesday 24 January 2017 13:09
by mvzut
tester22 wrote:Well the problem is that autodiscover would be slow but maybe it could be fixed.
I see no problem setting it to 5. I use the same config on my sonos conenct to start the amplifier and switch to the right input.
Great! I'll try it.
P.S.
I just noticed that the virtual remote isn't working. If I click on it I dont see anything. The code suggests that commands like "previous" and "next" are supported. Am I doing something wrong?
Re: Python plugin: Sonos
Posted: Tuesday 24 January 2017 13:24
by tester22
Think this is an domoticz bug. Have the seme problem with Kodi
Python plugin: Sonos
Posted: Tuesday 24 January 2017 19:58
by mvzut
tester22 wrote:Think this is an domoticz bug. Have the seme problem with Kodi
Hmmm, I don't use the Kodi plugin anymore, but that remote panel used to work well for me when I was still using it (a few months ago). Do you think this bug was introduced recently? Have you already reported it anywhere?
Re: Python plugin: Sonos
Posted: Tuesday 24 January 2017 22:04
by G3rard
The remote in the Kodi Media Server hardware type is indeed working (that's the "old" version), but the remote of the new Kodi Python plugin (Kodi Players) is not working.
@Dnpwwo, is the remote supported in the Python plugin?
Python plugin: Sonos
Posted: Thursday 26 January 2017 9:19
by mvzut
tester22 wrote:Well the problem is that autodiscover would be slow but maybe it could be fixed.
I see no problem setting it to 5. I use the same config on my sonos conenct to start the amplifier and switch to the right input.
Works great!!! My amp is now switched on within a few seconds after I press play on any remote or on the Sonos Connect itself. It took some creativity to find an elegant solution for turning the amp off, since I don't want it to shut down immediately when the player is stopped (paused). "Off AFTER 300" also doesn't work, since this delay timer cannot be cancelled when you continue playing within those five minutes. But I managed to do it via an additional user variable.
Thanks for this great plugin, you made me and my family members very happy! Would be even nicer if the transports would be supported too at some point (e.g. using the virtual remote), but I guess (hope) that will be repaired soon.
Re: Python plugin: Sonos
Posted: Friday 27 January 2017 1:28
by Dnpwwo
@G3rard,
I expected it to work but saw that it didn't. I assumed it was broken for the other Kodi plugin as well, now I know it's not I will have a look.
The plugin itself should accept the commands if they come through.
Re: Python plugin: Sonos
Posted: Friday 27 January 2017 8:42
by G3rard
@Dnpwwo, I haven't used the remote of the other Kodi plugin lately, so it could indeed be broken. Will do some testing and let you know.
Re: Python plugin: Sonos
Posted: Sunday 29 January 2017 20:17
by tester22
G3rard wrote:Thanks for the update. Much appreciated!
It's now showing the song which is playing on the radio
But not all radio stations are showing that information, so in that case nothing is being showed.
So is it possible that you implement the title from GetMediaInfo? And prevent unneccessary calls by only loading that info when creator is empty?
I have implemented this in the latest version on Github. The drawback is that the first time you start an specific radion station you might get an entry like: None - <Program>. This is since there will always be an delay when I try to load the data and when it is delivered. But this information should only be visible for about 1-2 seconds.
Re: Python plugin: Sonos
Posted: Sunday 29 January 2017 22:37
by G3rard
@tester22, thanks!
I get the following error on Domoticz v.36561.
Code: Select all
2017-01-29 22:32:39.220 (Sonos kantoor) Initialized version 1.0, author 'tester22'
2017-01-29 22:32:39.221 (Sonos kantoor) Update interval set to 10
2017-01-29 22:32:48.747 (Sonos kantoor) Update 1:'' (Sonos kantoor - Status)
2017-01-29 22:32:48.790 Error: (Sonos kantoor) 'onHeartbeat' failed 'ParseError'.
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 186 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function onHeartbeat
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 212 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function sendMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 117 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function onMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 212 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function sendMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 129 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function onMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 1325 in /usr/lib/python3.4/xml/etree/ElementTree.py, function XML
The previous version of the Sonos plugin is still working on this Domoticz version.
Re: Python plugin: Sonos
Posted: Monday 30 January 2017 7:37
by tester22
G3rard wrote:@tester22, thanks!
I get the following error on Domoticz v.36561.
Code: Select all
2017-01-29 22:32:39.220 (Sonos kantoor) Initialized version 1.0, author 'tester22'
2017-01-29 22:32:39.221 (Sonos kantoor) Update interval set to 10
2017-01-29 22:32:48.747 (Sonos kantoor) Update 1:'' (Sonos kantoor - Status)
2017-01-29 22:32:48.790 Error: (Sonos kantoor) 'onHeartbeat' failed 'ParseError'.
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 186 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function onHeartbeat
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 212 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function sendMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 117 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function onMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 212 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function sendMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 129 in /home/gerard/domoticz/plugins/Sonos/plugin.py, function onMessage
2017-01-29 22:32:48.790 Error: (Sonos kantoor) ----> Line 1325 in /usr/lib/python3.4/xml/etree/ElementTree.py, function XML
The previous version of the Sonos plugin is still working on this Domoticz version.
I have added some more error handeling.
Try to use the plugin with debug enabled.
Re: Python plugin: Sonos
Posted: Monday 30 January 2017 22:41
by G3rard
tester22 wrote:
I have added some more error handeling.
Try to use the plugin with debug enabled.
The plugin is now working again. When listening to a radio station I get the following message in the log (debug enabled).
Code: Select all
2017-01-30 22:27:27.253 (Sonos kantoor) Calling message handler 'onHeartbeat'.
2017-01-30 22:27:27.274 (Sonos kantoor) Failed to parse data
2017-01-30 22:27:27.274 (Sonos kantoor) QMusic Nonstopobject.item.audioItem.audioBroadcastSA_RINCON65031_.
2017-01-30 22:38:29.071 (Sonos kantoor) Calling message handler 'onHeartbeat'.
2017-01-30 22:38:29.100 (Sonos kantoor) Failed to parse data
2017-01-30 22:38:29.100 (Sonos kantoor) 538object.item.audioItem.audioBroadcastSA_RINCON65031_.
Where QMusic Nonstop and 538 are the radio stations.