Willkommen im Loxone Community Forum. Um alle Funktionen nutzen und sehen zu können, registriere dich bitte zuerst. Dies gilt auch für das herunterladen von Dateien.
Ich habe in meinen Loxone Steuer für meine Sonos-System integriert. Das einzige was nicht funktioniert, ist wenn Sonos über die Sonos-App und nicht die Loxone App aktiviert wurde. Dann wissen Loxone ja nicht dass die Sonos aktiviert ist.
Ist es möglich, Loxone dass mitzuteilen, in der einen oder anderen Weise?
An HTTP API bridge for Sonos easing automation. Hostable on any node.js capable device, like a raspberry pi or similar. - jishi/node-sonos-http-api
Raspberry übernimmt die Komunikation, es können auch z.B. Songtitel aktuelle Lautstärke usw. per UDP weitergegeben werden.
Ist etwas Scriptarbeit nötig aber recht einfach machbar.
Ein anderer User hat mal einen PicoC Bloc geschrieben, der den Status "Playing, Paused" oder "Stopped" anzeigt. Den Usernamen weiß ich nicht mehr, aber der Dank gehört dem "Unbekannten" :-)
Am Textausgang soll auch noch der aktuelle Songtitel angezeigt geben. Das ging bei mir nicht. Ich höre aber auch nur Webradio darüber. Eventuell ist das der Grund.
Code:
// Sonos - Status and Info
//
//
// Inputs
//
// AI1 - High -> Run update with SECONDS_BETWEEN_UPDATE intervall
//
// Outputs
//
// TQ - Text output (Format: Artist - Title)
// AQ1 - Analogue (-1 - ERROR,0 - STOPPED, 1 - PAUSED, 2 - PLAYING)
// AQ2 - Digital pulse - Song changed
// AQ3 - Digital pulse - State changed
//
#define BUFF_SIZE 40000
#define RD_BLOCK_SIZE 128
#define SECONDS_BETWEEN_UPDATE 1
// Change the ip for your player
char* SonosAddress = "/dev/tcp/192.168.xxx.xxx/1400";
int nEvents, Event;
int Running = 0;
int curstate = -1;
char* curinfo = "No info";
//
// Function to decode reply from sonoscontroller.
//
// Ex: Simon & Garfunkel -> Simon & Garfunkel
//
char* DecodeText(char* Text) {
char *ptr = strstr(Text, "&");
if (ptr!=NULL)
do {
strcpy(Text+(strlen(Text)-strlen(ptr)), "&");
strcpy(Text+(strlen(Text)-strlen(ptr)+1),ptr+9);
ptr = strstr(Text, "&");
} while (ptr!=NULL);
ptr = strstr(Text, "'");
if (ptr!=NULL)
do {
strcpy(Text+(strlen(Text)-strlen(ptr)), "'");
strcpy(Text+(strlen(Text)-strlen(ptr)+1),ptr+10);
ptr = strstr(Text, "'");
} while (ptr!=NULL);
return Text;
}
// End Function
// Function witch returns the state off the player. -1 error, 0 - stopped, 1 - paused, 2 - playing
int GetPlayerStatus(char* PlayerAddress) {
int State = -1;
char *pS;
char* cstate;
STREAM* pTcpStream = stream_create(PlayerAddress,0,0);
char* Command = "POST /MediaRenderer/AVTransport/Control HTTP/1.1\r\nCONNECTION: close\r\nCONTENT-LENGTH: 272\r\nCONTENT-TYPE: text/xml; charset=\"utf-8\"\r\nSOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo\"\r\n\r \n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:GetTransportInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetTransportInfo></s:Body></s:Envelope> ";
stream_write(pTcpStream,Command,strlen(Command));
stream_flush(pTcpStream);
char szBuffer[BUFF_SIZE];
char szTmpBuffer[RD_BLOCK_SIZE];
int nCnt;
int i = 0;
do {
nCnt = stream_read(pTcpStream,szTmpBuffer,RD_BLOCK_SIZE,4000);
if(nCnt > 0)
strncpy((char*)szBuffer+i*RD_BLOCK_SIZE,szTmpBuffer,nCnt);;
i++;
}
while (nCnt > 0);
pS = szBuffer;
while(*pS) {
cstate = strstr(pS, "STOPPED");
if (cstate !=NULL) { State = 0; }
cstate = strstr(pS, "PAUSED");
if (cstate !=NULL) { State = 1; }
cstate = strstr(pS, "PLAYING");
if (cstate !=NULL) { State = 2; }
pS += (strlen(pS) + 1); }
stream_close(pTcpStream);
return State;
}
// End Function
// Function witch gets information on the current song
char* GetCurrentlyPlaying(char* PlayerAddress) {
char *pS;
char* cEndAtt = "<"; // end of node <
char* cTitle = "title>"; // titlenode title>
char* cCreator = "creator>"; // creatornode creator>
char* cAlbum = "album>"; // albumnode album>
char Title[70], Creator[70], Album[70];
STREAM* InfoStream = stream_create(PlayerAddress,0,0);
char* Command = "POST /MediaRenderer/AVTransport/Control HTTP/1.1\r\nCONNECTION: close\r\nCONTENT-LENGTH: 295\r\nCONTENT-TYPE: text/xml; charset=\"utf-8\"\r\nSOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo\"\r\n\r\ n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:GetPositionInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Channel>Master</Channel></u:GetPositionInfo></s:Body></s:Envelope> ";
stream_write(InfoStream,Command,strlen(Command));
stream_flush(InfoStream);
char InfoBuffer[BUFF_SIZE];
char InfoTmpBuffer[RD_BLOCK_SIZE];
int iCnt;
int i = 0;
do {
iCnt = stream_read(InfoStream,InfoTmpBuffer,RD_BLOCK_SIZE ,4000);
if(iCnt > 0)
strncpy((char*)InfoBuffer+i*RD_BLOCK_SIZE,InfoTmpBuffer,iCnt);;
i++;
} while (iCnt > 0);
pS = InfoBuffer;
char* p = strstrskip(pS, cTitle);
int length;
if (p!=NULL) {
char* pp = strstr(p, cEndAtt);
length = strlen(p)-strlen(pp);
strncpy(Title, p, length);
p = strstrskip(pS, cCreator);
if (p!=NULL) {
pp = strstr(p, cEndAtt);
length = strlen(p)-strlen(pp);
strncpy(Creator, p, length);
p = strstrskip(pS, cAlbum);
if (p!=NULL) {
pp = strstr(p, cEndAtt);
length = strlen(p)-strlen(pp);
strncpy(Album, p, length);
}
}
}
char rString[200];
//printf("Title: %s Artist: %s Album: %s", Title, Creator, Album);
strcpy(rString, DecodeText(Creator));
strcat(rString, " - ");
strcat(rString, DecodeText(Title));
stream_close(InfoStream);
return rString;
}
// End Function
while(1==1) {
if (getinput(0)) { // check if we are active
int changed = 0;
int state = GetPlayerStatus(SonosAddress);
char* info = GetCurrentlyPlaying(SonosAddress);
if (strcmp(info, curinfo)!=0) { // media changed
setoutputtext(0,info);
setoutput(1, 1); sleep(200); setoutput(1, 0);
strcpy(curinfo,info);
changed = 1;
}
if (curstate!=state) { // state changed
setoutput(0, state); setoutputtext(0,info);
setoutput(2, 1); sleep(200); setoutput(2, 0);
curstate = state;
changed = 1;
}
if (changed) {
switch (state) {
case -1:
printf("Error getting status for player %s", SonosAddress); break;
case 0:
printf("Player %s has STOPPED (%s)", SonosAddress, info); break;
case 1:
printf("Player %s has been PAUSED (%s)", SonosAddress, info); break;
case 2:
printf("Player %s is now PLAYING (%s)", SonosAddress, info); break;
}
}
}
sleeps(SECONDS_BETWEEN_UPDATE);
}
]
Sonos wurde schon des öfteren im alten Forum behandelt. Es gibt dort einige Themen über Loxone im Zusammenhang mit Sonos.
Oben aufgeführter Code dürfte aus #18 von Thema: Sonos - Program block for status
kommen.
Der "Urheber" des aufgeführten Codes könnte also Thomas Øderud sein.
Diesen Code habe ich in etwas abgeänderter Form in der Config unter #18 eingebunden.
Da immer wieder Fragen über Sonos kommen, hier noch weitere Themen (sicher nicht alle) aus dem alten Forum. Weitere Themen über Sonos aus dem alten Forum:
Thema: Sonos EASY
Wir verarbeiten personenbezogene Daten über Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen, Werbung zu personalisieren und Websiteaktivitäten zu analysieren. Wir können bestimmte Informationen über unsere Nutzer mit unseren Werbe- und Analysepartnern teilen. Weitere Einzelheiten finden Sie in unserer Datenschutzrichtlinie.
Wenn Sie unten auf "Einverstanden" klicken, stimmen Sie unserer Datenschutzrichtlinie und unseren Datenverarbeitungs- und Cookie-Praktiken wie dort beschrieben zu. Sie erkennen außerdem an, dass dieses Forum möglicherweise außerhalb Ihres Landes gehostet wird und Sie der Erhebung, Speicherung und Verarbeitung Ihrer Daten in dem Land, in dem dieses Forum gehostet wird, zustimmen.
Kommentar