Control Spotify
using an ultrasonic distance sensor
Check out the code on Github
Canonical WebSocket beta
The existing example uses legacy Spotify command keys. To use the canonical
Spotify resume command, add the following headers before opening the WebSocket
connection and use sendCanonicalSpotifyResume() after it connects.
Canonical handshake headers
webSocket.setExtraHeaders(
"X-Offbeat-WebSocket-Protocol: canonical-v1\r\n"
"Accept: application/json\r\n");
Resume Spotify on its active Connect device
void sendCanonicalSpotifyResume() {
webSocket.sendTXT(
"{\"jsonrpc\":\"2.0\",\"id\":\"play-1\","
"\"method\":\"media.play\",\"params\":{\"target\":\"Spotify\"}}");
}
The response has the same id and an empty result object. The device must be
mapped to a linked Spotify integration and a Spotify Connect player must already
be active.
Quickstart
imports
connecting to offbeat-iot
webSocketClient.begin(host, 443, path);
//Tell Offbeat-IoT that you'd like to receive data in json format
webSocketClient.setExtraHeaders("Accept=application/json");
webSocketClient.setAuthorization(offbeatIotUser, offbeatIotPassword);
Receiving messages
case WStype_TEXT:
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
break;
Determining which commands to send based on distance
//create weirdest remote control ever
if (distance >= 0.0 && distance < 9.99) {
sendCommand("next");
} else if (distance >= 10.0 && distance < 19.99) {
sendCommand("play");
} else if (distance >= 20.0 && distance < 29.99) {
sendCommand("volumeUp");
} else if (distance >= 30.0 && distance < 39.99) {
sendCommand("shuffle");
} else if (distance >= 40.0 && distance < 49.99) {
sendCommand("prev");
} else if (distance >= 50.0 && distance < 59.99) {
sendCommand("pause");
} else if (distance >= 60.0 && distance < 69.99) {
sendCommand("volumeDown");
}
Sending commands to control spotify
bool shuffleEnabled = false;
int spotifyVolume = 25;
void sendCommand(const char* command) {
if (!webSocketClient.isConnected()) {
USE_SERIAL.println(F("Not connected when sending spotify command"));
return;
}
char message[96];
if (strcmp(command, "next") == 0) {
strcpy(message, "{\"spotify.next\":\"\"}");
} else if (strcmp(command, "prev") == 0) {
strcpy(message, "{\"spotify.previous\":\"\"}");
} else if (strcmp(command, "play") == 0) {
strcpy(message, "{\"spotify.play\":\"\"}");
} else if (strcmp(command, "pause") == 0) {
strcpy(message, "{\"spotify.pause\":\"\"}");
} else if (strcmp(command, "shuffle") == 0) {
shuffleEnabled = !shuffleEnabled;
snprintf(message, sizeof(message), "{\"spotify.shuffle\":\"%s\"}", shuffleEnabled ? "on" : "Off");
} else if (strcmp(command, "volumeUp") == 0) {
spotifyVolume = min(100, spotifyVolume + 5);
snprintf(message, sizeof(message), "{\"spotify.volume\":\"%d\"}", spotifyVolume);
} else if (strcmp(command, "volumeDown") == 0) {
spotifyVolume = max(0, spotifyVolume - 5);
snprintf(message, sizeof(message), "{\"spotify.volume\":\"%d\"}", spotifyVolume);
} else {
USE_SERIAL.print(F("Unknown spotify command: "));
USE_SERIAL.println(command);
return;
}
USE_SERIAL.print(F("Sending: "));
USE_SERIAL.println(message);
webSocketClient.sendTXT(message);
}
Todos
-
Listing players
-
Selecting player
-
Toggling player to avoid accidental turning on and off