Offbeat Iot
Get started
Using the Google Home integration

Using the Google Home integration

These sections show the websocket JSON sent to the device for the supported Google Home execute intents together with matching Arduino device examples from microcontroller-examples.

turn on
{
  "endpointId" : "123",
  "powerstate" : "TurnOn"
}
Arduino device example
void applyGoogleHomePowerState(const char* endpointId, const char* powerState) {
  Serial.print("Apply Google Home power command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(powerState);

  if (strcmp(powerState, "TurnOn") == 0) {
    Serial.println("Turn your output on here");
  } else if (strcmp(powerState, "TurnOff") == 0) {
    Serial.println("Turn your output off here");
  } else {
    Serial.println("Unsupported Google Home power command");
    return;
  }

  Serial.print("POWERSTATE=");
  Serial.println(powerState);
}

void handleGoogleHomePowerCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home power command");
    return;
  }

  JsonVariantConst powerStateValue = root[offbeat::google_home::examples::kPowerStateKey];
  if (powerStateValue.isNull()) {
    Serial.println("No Google Home powerstate payload");
    return;
  }

  applyGoogleHomePowerState(
      offbeat::google_home::examples::readEndpointId(root),
      offbeat::google_home::examples::readString(powerStateValue));
  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
turn off
{
  "endpointId" : "123",
  "powerstate" : "TurnOff"
}
Arduino device example
void applyGoogleHomePowerState(const char* endpointId, const char* powerState) {
  Serial.print("Apply Google Home power command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(powerState);

  if (strcmp(powerState, "TurnOn") == 0) {
    Serial.println("Turn your output on here");
  } else if (strcmp(powerState, "TurnOff") == 0) {
    Serial.println("Turn your output off here");
  } else {
    Serial.println("Unsupported Google Home power command");
    return;
  }

  Serial.print("POWERSTATE=");
  Serial.println(powerState);
}

void handleGoogleHomePowerCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home power command");
    return;
  }

  JsonVariantConst powerStateValue = root[offbeat::google_home::examples::kPowerStateKey];
  if (powerStateValue.isNull()) {
    Serial.println("No Google Home powerstate payload");
    return;
  }

  applyGoogleHomePowerState(
      offbeat::google_home::examples::readEndpointId(root),
      offbeat::google_home::examples::readString(powerStateValue));
  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
adjust volume
{
  "endpointId" : "123",
  "volumesteps" : -1
}
Arduino device example
void applyGoogleHomeSetVolume(const char* endpointId, long volume) {
  Serial.print("Set volume on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(volume);

  Serial.print("VOLUME=");
  Serial.println(volume);
}

void applyGoogleHomeAdjustVolume(const char* endpointId, long volumeSteps) {
  Serial.print("Adjust volume on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(volumeSteps);

  Serial.print("VOLUME_STEPS=");
  Serial.println(volumeSteps);
}

void handleGoogleHomeVolumeCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home volume command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst volumeValue = root[offbeat::google_home::examples::kVolumeKey];
  JsonVariantConst volumeStepsValue = root[offbeat::google_home::examples::kVolumeStepsKey];

  if (!volumeValue.isNull()) {
    applyGoogleHomeSetVolume(endpointId, offbeat::google_home::examples::readLong(volumeValue));
  } else if (!volumeStepsValue.isNull()) {
    applyGoogleHomeAdjustVolume(endpointId, offbeat::google_home::examples::readLong(volumeStepsValue));
  } else {
    Serial.println("No Google Home volume payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
set volume
{
  "volume" : 665,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeSetVolume(const char* endpointId, long volume) {
  Serial.print("Set volume on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(volume);

  Serial.print("VOLUME=");
  Serial.println(volume);
}

void applyGoogleHomeAdjustVolume(const char* endpointId, long volumeSteps) {
  Serial.print("Adjust volume on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(volumeSteps);

  Serial.print("VOLUME_STEPS=");
  Serial.println(volumeSteps);
}

void handleGoogleHomeVolumeCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home volume command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst volumeValue = root[offbeat::google_home::examples::kVolumeKey];
  JsonVariantConst volumeStepsValue = root[offbeat::google_home::examples::kVolumeStepsKey];

  if (!volumeValue.isNull()) {
    applyGoogleHomeSetVolume(endpointId, offbeat::google_home::examples::readLong(volumeValue));
  } else if (!volumeStepsValue.isNull()) {
    applyGoogleHomeAdjustVolume(endpointId, offbeat::google_home::examples::readLong(volumeStepsValue));
  } else {
    Serial.println("No Google Home volume payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
set color
{
  "saturation" : 123.0,
  "brightness" : 456.0,
  "endpointId" : "123",
  "hue" : 665.0
}
Arduino device example
void applyGoogleHomeColorCommand(const char* endpointId, double hue, double saturation, double brightness) {
  Serial.print("Set color on ");
  Serial.println(endpointId);
  offbeat::google_home::examples::printLine("Hue: ", hue, 2);
  offbeat::google_home::examples::printLine("Saturation: ", saturation, 2);
  offbeat::google_home::examples::printLine("Brightness: ", brightness, 2);

  Serial.print("HUE=");
  Serial.println(hue, 2);
  Serial.print("SATURATION=");
  Serial.println(saturation, 2);
  Serial.print("BRIGHTNESS=");
  Serial.println(brightness, 2);
}

void handleGoogleHomeColorCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home color command");
    return;
  }

  JsonVariantConst hueValue = root[offbeat::google_home::examples::kHueKey];
  JsonVariantConst saturationValue = root[offbeat::google_home::examples::kSaturationKey];
  JsonVariantConst brightnessValue = root[offbeat::google_home::examples::kBrightnessKey];
  if (hueValue.isNull() || saturationValue.isNull() || brightnessValue.isNull()) {
    Serial.println("Incomplete Google Home color payload");
    return;
  }

  applyGoogleHomeColorCommand(
      offbeat::google_home::examples::readEndpointId(root),
      offbeat::google_home::examples::readDouble(hueValue),
      offbeat::google_home::examples::readDouble(saturationValue),
      offbeat::google_home::examples::readDouble(brightnessValue));
  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
set brightness to 456
{
  "brightness" : 456,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeBrightnessPercent(const char* endpointId, long brightnessPercent) {
  Serial.print("Set brightness percent on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessPercent);

  Serial.print("BRIGHTNESS_PERCENT=");
  Serial.println(brightnessPercent);
}

void applyGoogleHomeBrightnessWeight(const char* endpointId, long brightnessWeight) {
  Serial.print("Adjust brightness weight on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(brightnessWeight);

  Serial.print("BRIGHTNESS_WEIGHT=");
  Serial.println(brightnessWeight);
}

void applyGoogleHomeBrightnessAbsolute(const char* endpointId, long brightnessValue) {
  Serial.print("Set absolute brightness on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessValue);

  Serial.print("BRIGHTNESS=");
  Serial.println(brightnessValue);
}

void handleGoogleHomeBrightnessCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home brightness command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst percentValue = root[offbeat::google_home::examples::kAdjustBrightnessPercentKey];
  JsonVariantConst weightValue = root[offbeat::google_home::examples::kAdjustBrightnessWeightKey];
  JsonVariantConst brightnessValue = root[offbeat::google_home::examples::kBrightnessKey];

  if (!percentValue.isNull()) {
    applyGoogleHomeBrightnessPercent(endpointId, offbeat::google_home::examples::readLong(percentValue));
  } else if (!weightValue.isNull()) {
    applyGoogleHomeBrightnessWeight(endpointId, offbeat::google_home::examples::readLong(weightValue));
  } else if (!brightnessValue.isNull()) {
    applyGoogleHomeBrightnessAbsolute(endpointId, offbeat::google_home::examples::readLong(brightnessValue));
  } else {
    Serial.println("No Google Home brightness payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
set brightness to 416
{
  "brightness" : 416,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeBrightnessPercent(const char* endpointId, long brightnessPercent) {
  Serial.print("Set brightness percent on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessPercent);

  Serial.print("BRIGHTNESS_PERCENT=");
  Serial.println(brightnessPercent);
}

void applyGoogleHomeBrightnessWeight(const char* endpointId, long brightnessWeight) {
  Serial.print("Adjust brightness weight on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(brightnessWeight);

  Serial.print("BRIGHTNESS_WEIGHT=");
  Serial.println(brightnessWeight);
}

void applyGoogleHomeBrightnessAbsolute(const char* endpointId, long brightnessValue) {
  Serial.print("Set absolute brightness on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessValue);

  Serial.print("BRIGHTNESS=");
  Serial.println(brightnessValue);
}

void handleGoogleHomeBrightnessCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home brightness command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst percentValue = root[offbeat::google_home::examples::kAdjustBrightnessPercentKey];
  JsonVariantConst weightValue = root[offbeat::google_home::examples::kAdjustBrightnessWeightKey];
  JsonVariantConst brightnessValue = root[offbeat::google_home::examples::kBrightnessKey];

  if (!percentValue.isNull()) {
    applyGoogleHomeBrightnessPercent(endpointId, offbeat::google_home::examples::readLong(percentValue));
  } else if (!weightValue.isNull()) {
    applyGoogleHomeBrightnessWeight(endpointId, offbeat::google_home::examples::readLong(weightValue));
  } else if (!brightnessValue.isNull()) {
    applyGoogleHomeBrightnessAbsolute(endpointId, offbeat::google_home::examples::readLong(brightnessValue));
  } else {
    Serial.println("No Google Home brightness payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
adjust brightness percent
{
  "adjustBrightnessPercent" : 20,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeBrightnessPercent(const char* endpointId, long brightnessPercent) {
  Serial.print("Set brightness percent on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessPercent);

  Serial.print("BRIGHTNESS_PERCENT=");
  Serial.println(brightnessPercent);
}

void applyGoogleHomeBrightnessWeight(const char* endpointId, long brightnessWeight) {
  Serial.print("Adjust brightness weight on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(brightnessWeight);

  Serial.print("BRIGHTNESS_WEIGHT=");
  Serial.println(brightnessWeight);
}

void applyGoogleHomeBrightnessAbsolute(const char* endpointId, long brightnessValue) {
  Serial.print("Set absolute brightness on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessValue);

  Serial.print("BRIGHTNESS=");
  Serial.println(brightnessValue);
}

void handleGoogleHomeBrightnessCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home brightness command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst percentValue = root[offbeat::google_home::examples::kAdjustBrightnessPercentKey];
  JsonVariantConst weightValue = root[offbeat::google_home::examples::kAdjustBrightnessWeightKey];
  JsonVariantConst brightnessValue = root[offbeat::google_home::examples::kBrightnessKey];

  if (!percentValue.isNull()) {
    applyGoogleHomeBrightnessPercent(endpointId, offbeat::google_home::examples::readLong(percentValue));
  } else if (!weightValue.isNull()) {
    applyGoogleHomeBrightnessWeight(endpointId, offbeat::google_home::examples::readLong(weightValue));
  } else if (!brightnessValue.isNull()) {
    applyGoogleHomeBrightnessAbsolute(endpointId, offbeat::google_home::examples::readLong(brightnessValue));
  } else {
    Serial.println("No Google Home brightness payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
adjust brightness weight
{
  "endpointId" : "123",
  "adjustBrightnessWeight" : -1
}
Arduino device example
void applyGoogleHomeBrightnessPercent(const char* endpointId, long brightnessPercent) {
  Serial.print("Set brightness percent on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessPercent);

  Serial.print("BRIGHTNESS_PERCENT=");
  Serial.println(brightnessPercent);
}

void applyGoogleHomeBrightnessWeight(const char* endpointId, long brightnessWeight) {
  Serial.print("Adjust brightness weight on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(brightnessWeight);

  Serial.print("BRIGHTNESS_WEIGHT=");
  Serial.println(brightnessWeight);
}

void applyGoogleHomeBrightnessAbsolute(const char* endpointId, long brightnessValue) {
  Serial.print("Set absolute brightness on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(brightnessValue);

  Serial.print("BRIGHTNESS=");
  Serial.println(brightnessValue);
}

void handleGoogleHomeBrightnessCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home brightness command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst percentValue = root[offbeat::google_home::examples::kAdjustBrightnessPercentKey];
  JsonVariantConst weightValue = root[offbeat::google_home::examples::kAdjustBrightnessWeightKey];
  JsonVariantConst brightnessValue = root[offbeat::google_home::examples::kBrightnessKey];

  if (!percentValue.isNull()) {
    applyGoogleHomeBrightnessPercent(endpointId, offbeat::google_home::examples::readLong(percentValue));
  } else if (!weightValue.isNull()) {
    applyGoogleHomeBrightnessWeight(endpointId, offbeat::google_home::examples::readLong(weightValue));
  } else if (!brightnessValue.isNull()) {
    applyGoogleHomeBrightnessAbsolute(endpointId, offbeat::google_home::examples::readLong(brightnessValue));
  } else {
    Serial.println("No Google Home brightness payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media resume
{
  "playerControl" : "Play",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media stop
{
  "playerControl" : "Stop",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media next
{
  "playerControl" : "Next",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media previous
{
  "playerControl" : "Prev",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media pause
{
  "playerControl" : "Pause",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media seek relative
{
  "endpointId" : "123",
  "Seek" : -10000
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media seek absolute
{
  "endpointId" : "123",
  "SeekAbsolute" : 30000
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media repeat
{
  "playerControl" : "Repeat",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
media shuffle
{
  "playerControl" : "Shuffle",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
closed captioning on
{
  "playerControl" : "CaptionsOn",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
closed captioning off
{
  "playerControl" : "CaptionsOff",
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomePlayerControl(const char* endpointId, const char* playerControl) {
  Serial.print("Apply media command for ");
  Serial.print(endpointId);
  Serial.print(": ");
  Serial.println(playerControl);

  Serial.print("PLAYER_CONTROL=");
  Serial.println(playerControl);
}

void applyGoogleHomeSeekAbsolute(const char* endpointId, long absolutePositionMs) {
  Serial.print("Seek absolute on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(absolutePositionMs);

  Serial.print("SEEK_ABSOLUTE_MS=");
  Serial.println(absolutePositionMs);
}

void applyGoogleHomeSeekRelative(const char* endpointId, long relativePositionMs) {
  Serial.print("Seek relative on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(relativePositionMs);

  Serial.print("SEEK_RELATIVE_MS=");
  Serial.println(relativePositionMs);
}

void handleGoogleHomeMediaCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home media command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst playerControlValue = root[offbeat::google_home::examples::kPlayerControlKey];
  JsonVariantConst seekAbsoluteValue = root[offbeat::google_home::examples::kSeekAbsoluteKey];
  JsonVariantConst seekRelativeValue = root[offbeat::google_home::examples::kSeekRelativeKey];

  if (!playerControlValue.isNull()) {
    applyGoogleHomePlayerControl(endpointId, offbeat::google_home::examples::readString(playerControlValue));
  } else if (!seekAbsoluteValue.isNull()) {
    applyGoogleHomeSeekAbsolute(endpointId, offbeat::google_home::examples::readLong(seekAbsoluteValue));
  } else if (!seekRelativeValue.isNull()) {
    applyGoogleHomeSeekRelative(endpointId, offbeat::google_home::examples::readLong(seekRelativeValue));
  } else {
    Serial.println("No Google Home media payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
select channel
{
  "endpointId" : "123",
  "SetChannel" : 9
}
Arduino device example
void applyGoogleHomeSetChannel(const char* endpointId, long channelNumber) {
  Serial.print("Set channel on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(channelNumber);

  Serial.print("SET_CHANNEL=");
  Serial.println(channelNumber);
}

void applyGoogleHomeSkipChannel(const char* endpointId, long channelOffset) {
  Serial.print("Skip channel on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(channelOffset);

  Serial.print("SKIP_CHANNEL=");
  Serial.println(channelOffset);
}

void handleGoogleHomeChannelCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home channel command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst setChannelValue = root[offbeat::google_home::examples::kSetChannelKey];
  JsonVariantConst skipChannelValue = root[offbeat::google_home::examples::kSkipChannelKey];

  if (!setChannelValue.isNull()) {
    applyGoogleHomeSetChannel(endpointId, offbeat::google_home::examples::readLong(setChannelValue));
  } else if (!skipChannelValue.isNull()) {
    applyGoogleHomeSkipChannel(endpointId, offbeat::google_home::examples::readLong(skipChannelValue));
  } else {
    Serial.println("No Google Home channel payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
relative channel
{
  "skipChannel" : 1,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeSetChannel(const char* endpointId, long channelNumber) {
  Serial.print("Set channel on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(channelNumber);

  Serial.print("SET_CHANNEL=");
  Serial.println(channelNumber);
}

void applyGoogleHomeSkipChannel(const char* endpointId, long channelOffset) {
  Serial.print("Skip channel on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(channelOffset);

  Serial.print("SKIP_CHANNEL=");
  Serial.println(channelOffset);
}

void handleGoogleHomeChannelCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home channel command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst setChannelValue = root[offbeat::google_home::examples::kSetChannelKey];
  JsonVariantConst skipChannelValue = root[offbeat::google_home::examples::kSkipChannelKey];

  if (!setChannelValue.isNull()) {
    applyGoogleHomeSetChannel(endpointId, offbeat::google_home::examples::readLong(setChannelValue));
  } else if (!skipChannelValue.isNull()) {
    applyGoogleHomeSkipChannel(endpointId, offbeat::google_home::examples::readLong(skipChannelValue));
  } else {
    Serial.println("No Google Home channel payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
return channel
{
  "skipChannel" : -1,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeSetChannel(const char* endpointId, long channelNumber) {
  Serial.print("Set channel on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.println(channelNumber);

  Serial.print("SET_CHANNEL=");
  Serial.println(channelNumber);
}

void applyGoogleHomeSkipChannel(const char* endpointId, long channelOffset) {
  Serial.print("Skip channel on ");
  Serial.print(endpointId);
  Serial.print(" by ");
  Serial.println(channelOffset);

  Serial.print("SKIP_CHANNEL=");
  Serial.println(channelOffset);
}

void handleGoogleHomeChannelCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home channel command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst setChannelValue = root[offbeat::google_home::examples::kSetChannelKey];
  JsonVariantConst skipChannelValue = root[offbeat::google_home::examples::kSkipChannelKey];

  if (!setChannelValue.isNull()) {
    applyGoogleHomeSetChannel(endpointId, offbeat::google_home::examples::readLong(setChannelValue));
  } else if (!skipChannelValue.isNull()) {
    applyGoogleHomeSkipChannel(endpointId, offbeat::google_home::examples::readLong(skipChannelValue));
  } else {
    Serial.println("No Google Home channel payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
set blind tilt percent
{
  "setTiltPercent" : 60,
  "endpointId" : "123"
}
Arduino device example
void applyGoogleHomeBlindTiltPercent(const char* endpointId, long tiltPercent) {
  long clampedTiltPercent = clampPercent(tiltPercent);
  long tiltDegrees = percentToDegrees(clampedTiltPercent);

  Serial.print("Set Google Home blind tilt on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.print(clampedTiltPercent);
  Serial.println("%");

  Serial.print("TILT_PERCENT=");
  Serial.println(clampedTiltPercent);
  Serial.print("TILT_DEGREES=");
  Serial.println(tiltDegrees);
}

void applyGoogleHomeBlindTiltDegrees(const char* endpointId, long tiltDegrees) {
  long clampedTiltDegrees = clampDegrees(tiltDegrees);
  long tiltPercent = degreesToPercent(clampedTiltDegrees);

  Serial.print("Set Google Home blind tilt on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.print(clampedTiltDegrees);
  Serial.println(" degrees");

  Serial.print("TILT_DEGREES=");
  Serial.println(clampedTiltDegrees);
  Serial.print("TILT_PERCENT=");
  Serial.println(tiltPercent);
}

void handleGoogleHomeBlindTiltCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home blind tilt command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst rotationPercent = root[offbeat::google_home::examples::kRotationPercentKey];
  JsonVariantConst rotationDegrees = root[offbeat::google_home::examples::kRotationDegreesKey];

  if (!rotationPercent.isNull()) {
    applyGoogleHomeBlindTiltPercent(
        endpointId, offbeat::google_home::examples::readLong(rotationPercent));
  } else if (!rotationDegrees.isNull()) {
    applyGoogleHomeBlindTiltDegrees(
        endpointId, offbeat::google_home::examples::readLong(rotationDegrees));
  } else {
    Serial.println("No Google Home blind tilt payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
set blind tilt degrees
{
  "endpointId" : "123",
  "setTiltDegrees" : 90
}
Arduino device example
void applyGoogleHomeBlindTiltPercent(const char* endpointId, long tiltPercent) {
  long clampedTiltPercent = clampPercent(tiltPercent);
  long tiltDegrees = percentToDegrees(clampedTiltPercent);

  Serial.print("Set Google Home blind tilt on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.print(clampedTiltPercent);
  Serial.println("%");

  Serial.print("TILT_PERCENT=");
  Serial.println(clampedTiltPercent);
  Serial.print("TILT_DEGREES=");
  Serial.println(tiltDegrees);
}

void applyGoogleHomeBlindTiltDegrees(const char* endpointId, long tiltDegrees) {
  long clampedTiltDegrees = clampDegrees(tiltDegrees);
  long tiltPercent = degreesToPercent(clampedTiltDegrees);

  Serial.print("Set Google Home blind tilt on ");
  Serial.print(endpointId);
  Serial.print(" to ");
  Serial.print(clampedTiltDegrees);
  Serial.println(" degrees");

  Serial.print("TILT_DEGREES=");
  Serial.println(clampedTiltDegrees);
  Serial.print("TILT_PERCENT=");
  Serial.println(tiltPercent);
}

void handleGoogleHomeBlindTiltCommand(uint8_t* payload, size_t length) {
  StaticJsonDocument<256> document;
  JsonObjectConst root;
  offbeat::google_home::examples::ParseStatus status =
      offbeat::google_home::examples::parseRoot(payload, length, document, root);

  if (status == offbeat::google_home::examples::ParseStatus::kInvalidPayload) {
    Serial.println("Unable to parse Google Home blind tilt command");
    return;
  }

  const char* endpointId = offbeat::google_home::examples::readEndpointId(root);
  JsonVariantConst rotationPercent = root[offbeat::google_home::examples::kRotationPercentKey];
  JsonVariantConst rotationDegrees = root[offbeat::google_home::examples::kRotationDegreesKey];

  if (!rotationPercent.isNull()) {
    applyGoogleHomeBlindTiltPercent(
        endpointId, offbeat::google_home::examples::readLong(rotationPercent));
  } else if (!rotationDegrees.isNull()) {
    applyGoogleHomeBlindTiltDegrees(
        endpointId, offbeat::google_home::examples::readLong(rotationDegrees));
  } else {
    Serial.println("No Google Home blind tilt payload");
    return;
  }

  offbeat::google_home::examples::printEndpoint(root);
  Serial.println("TEST:PASS");
}
Examples