Search code examples
google-cloud-platformgoogle-cloud-iot

GCP IoTCore won't parse payload using Gateways and HTTP bridge


Steps taken so far

  1. Create a new key pair and use it for the gateway that is about to be created
  2. Create a gateway, let's call it 'my_first_gateway'
  3. Create a new device, let's call it 'gw_device_1'
  4. Associate gw_device_1 with my_first_gateway

Works fine so far.

Now I want to use the HTTP bridge to send gw_device_1's state data to IoTCore via my gateway using my_first_gateway's private key, following this tutorial: https://cloud.google.com/iot/docs/how-tos/gateways/http-bridge#setting_device_state_through_the_gateway

Observation1: the URL in this tutorial seems malformatted, there is a missing double quote at the end of 'delegated_device_id':

curl -X POST -H 'authorization: Bearer GATEWAY_JWT' -H 'content-type: application/json' --data '{"binary_data": "DATA", "gateway_info": {"delegated_device_id: "device-id"}}' -H 'cache-control: no-cache' 'https://cloudiotdevice.googleapis.com/v1/projects/{project-id}/locations/{cloud-region}/registries/{registry-id}/devices/{gateway-id}:setState'

When I am now replacing all placeholders and replace "DATA" with say "ewogICJhUHJvcCI6ICJhVmFsdWUiCn0" I execute the following curl (the token is obviously not real):

curl -X POST -H 'authorization: Bearer GW_JWT_TOKEN' -H 'content-type: application/json' --data '{"binary_data": "ewogICJhUHJvcCI6ICJhVmFsdWUiCn0=", "gateway_info": {"delegated_device_id": "gw_device_1"}}' -H 'cache-control: no-cache' 'https://cloudiotdevice.googleapis.com/v1/projects/my_project_id/locations/europe-west1/registries/my_registry/devices/my_first_gateway:setState'

I receive this error:

{
  "error": {
    "code": 400,
    "message": "Invalid JSON payload received. Unknown name \"binary_data\": Cannot find field.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "description": "Invalid JSON payload received. Unknown name \"binary_data\": Cannot find field."
          }
        ]
      }
    ]
  }
}

The fun thing is: There is another 'endpoint' that is used to publish events to IoTCore. It has the same signature but instead of 'setState' it ends with 'publishEvent' (see: https://cloud.google.com/iot/docs/how-tos/gateways/http-bridge#publishing_the_devices_telemetry_events_through_the_gateway). Executing the exact same request with this method works just fine:

curl -X POST -H 'authorization: Bearer GW_JWT_TOKEN' -H 'content-type: application/json' --data '{"binary_data": "ewogICJhUHJvcCI6ICJhVmFsdWUiCn0=", "gateway_info": {"delegated_device_id": "gw_device_1"}}' -H 'cache-control: no-cache' 'https://cloudiotdevice.googleapis.com/v1/projects/my_project_id/locations/europe-west1/registries/my_registry/devices/my_first_gateway:publishEvent'

Am I missing something? Any help appreciated.


Solution

  • Actually, the curl that google provides is not correct. The payload needs to be adapted a bit, the binary_data string needs to be wrapped in an object called 'state'

    { "state": { "binary_data": "ewogICJhUHJvcCI6ICJhVmFsdWUiCn0=" }, "gateway_info": {"delegated_device_id": "gw_device_1"}}
    

    The curl then works as expected.