Offbeat Iot
Get started
Control Spotify

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

Examples