Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
int LED = D1;
int PR = A0; // photoresistor port
int BUTTON = D0; // button port
bool bright;
bool pressed;
bool playing;
int brightness = 0; // to store the current brightness
// Sonos stuff grabbed from Hover_particle
// Set to IP of your Sonos player
byte sonosip[] = { 192, 168, 0, 217 };
#define SOAP_HEADER "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>"
#define SOAP_FOOTER "</s:Body></s:Envelope>\r\n"
#define SONOS_PAUSE "<u:Pause xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Pause>"
#define SONOS_PLAY "<u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play>"
#define SONOS_NEXT "<u:Next xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Next>"
#define SONOS_PREVIOUS "<u:Previous xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Previous>"
#define SONOS_SETVOLUME_HEADER "<u:SetVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>"
#define SONOS_SETVOLUME_FOOTER "</DesiredVolume></u:SetVolume></s:Body></s:Envelope>"
#define SONOS_TRANSPORT_INFO "<u:GetPositionInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetPositionInfo>"
#define SONOS_GETVOLUME "<u:GetVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel></u:GetVolume>"
#define PAUSE 0
#define PLAY 1
#define NEXT 2
#define PREVIOUS 3
#define VOLUME 4
#define TRANSPORTINFO 5
#define GETVOLUME 6
TCPClient client;
unsigned long timeout;
int sonosVolume;
char songTitle[32];
char songArtist[32];
char songVolume[12];
void setup() {
pinMode(LED, OUTPUT);
pinMode(PR, INPUT);
pinMode(BUTTON, INPUT);
digitalWrite(LED, LOW);
//check environment and set bright accordingly
if(analogRead(PR)>=2000) bright=true;
else bright=false;
//set pressed state
if(digitalRead(BUTTON)==HIGH) pressed=true;
else pressed=false;
Particle.function("led", ledToggler);
Particle.variable("brightness", &brightness, INT);
//pause Sonos
playing=false;
sonos(PAUSE);
}
void loop() {
brightness=analogRead(PR);
if(digitalRead(BUTTON)==HIGH && !pressed) {
Particle.publish("button pressed", NULL);
pressed=true;
// toggle between PLAY and PAUSE when button is pressed
if(!playing) {
sonos(PLAY);
playing=true;
} else {
sonos(PAUSE);
playing=false;
}
} else if(digitalRead(BUTTON)==LOW && pressed) {
pressed=false;
}
if(brightness >= 2000 && !bright) {
Particle.publish("lights on", String(brightness), 60, PRIVATE);
bright=true;
}
else if(brightness < 2000 && bright) {
Particle.publish("lights out", String(brightness), 60, PRIVATE);
bright=false;
}
delay(1000);
}
int ledToggler(String command) {
if(command=="on") {
digitalWrite(LED, HIGH);
return 1;
}
else if(command=="off") {
digitalWrite(LED, LOW);
return 0;
}
else
{
return -1;
}
}
void out(const char *s)
{
client.write( (const uint8_t*)s, strlen(s) );
}
void sonos(int cmd)
{
char buf[512];
char soapmsg[1024];
char cmdtag[20];
sonosVolume = 35;
if (client.connect(sonosip, 1400)) {
switch (cmd) {
case PAUSE:
sprintf(soapmsg, "%s%s%s", SOAP_HEADER, SONOS_PAUSE, SOAP_FOOTER);
strcpy(cmdtag, "Pause");
break;
case PLAY:
sprintf(soapmsg, "%s%s%s", SOAP_HEADER, SONOS_PLAY, SOAP_FOOTER);
strcpy(cmdtag, "Play");
break;
case NEXT:
sprintf(soapmsg, "%s%s%s", SOAP_HEADER, SONOS_NEXT, SOAP_FOOTER);
strcpy(cmdtag, "Next");
break;
case PREVIOUS:
sprintf(soapmsg, "%s%s%s", SOAP_HEADER, SONOS_PREVIOUS, SOAP_FOOTER);
strcpy(cmdtag, "Previous");
break;
case VOLUME:
sprintf(soapmsg, "%s%s%i%s", SOAP_HEADER, SONOS_SETVOLUME_HEADER, sonosVolume, SONOS_SETVOLUME_FOOTER);
strcpy(cmdtag, "SetVolume");
break;
case TRANSPORTINFO:
sprintf(soapmsg, "%s%s%s", SOAP_HEADER, SONOS_TRANSPORT_INFO, SOAP_FOOTER);
strcpy(cmdtag, "GetPositionInfo");
break;
case GETVOLUME:
sprintf(soapmsg, "%s%s%s", SOAP_HEADER, SONOS_GETVOLUME, SOAP_FOOTER);
strcpy(cmdtag, "GetVolume");
break;
}
if (String(cmdtag) == "SetVolume" || String(cmdtag) == "GetVolume") {
out("POST /MediaRenderer/RenderingControl/Control HTTP/1.1\r\n");
} else {
out("POST /MediaRenderer/AVTransport/Control HTTP/1.1\r\n");
}
sprintf(buf, "Host: %d.%d.%d.%d:1400\r\n", sonosip[0], sonosip[1], sonosip[2], sonosip[3]);
out(buf);
sprintf(buf, "Content-Length: %d\r\n", strlen(soapmsg));
out(buf);
out("Content-Type: text/xml; charset=\"utf-8\"\r\n");
if (String(cmdtag) == "SetVolume" || String(cmdtag) == "GetVolume") {
sprintf(buf, "Soapaction: \"urn:schemas-upnp-org:service:RenderingControl:1#%s\"\r\n", cmdtag);
} else {
sprintf(buf, "Soapaction: \"urn:schemas-upnp-org:service:AVTransport:1#%s\"\r\n", cmdtag);
}
out(buf);
out("\r\n");
out(soapmsg);
/*wait 1s for timeout*/
timeout = millis();
while ((!client.available()) && ((millis() - timeout) < 1000));
int i = 0;
char sonosResponse[3072];
while (client.available()) {
char c = client.read();
Serial.print(c);
if (String(cmdtag) == "GetPositionInfo" || String(cmdtag) == "GetVolume") {
sonosResponse[i] = c;
Serial.print(sonosResponse[i]); //This line prints the entire response
i++;
}
}
if (String(cmdtag) == "GetPositionInfo") {
sonosResponse[i] = '\0';
/* Get the song title */
char *p1 = strcasestr(sonosResponse,"dc:title&gt;");
char *p2 = strcasestr(sonosResponse,"&lt;/dc:title");
int c = 0;
for (p1 = p1 + 12; p1 != p2; p1++) {
songTitle[c] = *p1;
c++;
}
songTitle[c] = '\0';
Serial.println(songTitle);
/* Get the Artist */
p1 = strcasestr(sonosResponse,"dc:creator&gt;");
p2 = strcasestr(sonosResponse,"&lt;/dc:creator");
c = 0;
for (p1 = p1 + 14; p1 != p2; p1++) {
songArtist[c] = *p1;
c++;
}
songArtist[c] = '\0';
Serial.println(songArtist);
/* Get the Album */
/*p1 = strcasestr(sonosResponse,";upnp:album&gt;");
p2 = strcasestr(sonosResponse,"&lt;/upnp:album&gt");
c = 0;
for (p1 = p1 + 15; p1 != p2; p1++) {
songAlbum[c] = *p1;
c++;
}
songAlbum[c] = '\0';
Serial.println(songAlbum);*/
} else if (String(cmdtag) == "GetVolume") {
sonosResponse[i] = '\0';
char *p1 = strcasestr(sonosResponse,"<CurrentVolume>");
char *p2 = strcasestr(sonosResponse,"</CurrentVolume>");
int c = 0;
for (p1 = p1 + 15; p1 != p2; p1++) {
songVolume[c] = *p1;
c++;
}
songVolume[c] = '\0';
Serial.println(songVolume);
sscanf(songVolume, "%d", &sonosVolume);
Serial.println(sonosVolume);
}
//while (client.available()) client.read();
//delay(100);
client.stop();
} else {
Serial.println("Not yet connected to Sonos.");
}
}
@IwonGit

This comment has been minimized.

Copy link

commented Aug 10, 2019

TCPClient client; error

@IwonGit

This comment has been minimized.

Copy link

commented Aug 10, 2019

which library?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.