Amazon API Gateway

Integrate Thingsee IoT data with Amazon API Gateway and AWS Lambda

Amazon API Gateway is an AWS service for creating, securing, and managing APIs at scale. It provides a gateway between applications and backend services for secure and efficient communication.

Overview

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#73F9C1','primaryTextColor':'#143633','primaryBorderColor':'#143633','lineColor':'#143633','secondaryColor':'#C7FDE6','tertiaryColor':'#F6FAFA','clusterBkg':'#F6FAFA','clusterBorder':'#143633'}}}%%
flowchart TB
    subgraph AWS["AWS Cloud"]
        DDB[(DynamoDB)]
        S3[(S3)]
        OTHER[Other AWS Services]
        LAMBDA[Lambda Function]
        APIGW[API Gateway]
    end
    
    subgraph Thingsee["Thingsee"]
        T[Thingsee Cloud]
    end
    
    T -->|HTTPS POST| APIGW
    APIGW --> LAMBDA
    LAMBDA --> DDB & S3 & OTHER

Setup Steps

1. Create API Gateway

  1. Open AWS Console → API Gateway
  2. Create a new REST API or HTTP API
  3. Create a resource (e.g., /thingsee)
  4. Add POST method to the resource

2. Create Lambda Function

Create a Lambda function to process incoming messages:

import json
import boto3
from datetime import datetime

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('ThingseeSensorData')

def lambda_handler(event, context):
    # Parse incoming Thingsee messages
    messages = json.loads(event['body'])
    
    for message in messages:
        # Store in DynamoDB
        table.put_item(Item={
            'tuid': message['tsmTuid'],
            'timestamp': message['tsmTs'],
            'messageId': message['tsmId'],
            'data': message
        })
    
    return {
        'statusCode': 200,
        'body': json.dumps({'status': 'ok'})
    }

3. Configure Authentication

Choose an authentication method:

MethodUse Case
API KeySimple authentication
IAMAWS service authentication
CognitoUser pool authentication
Lambda AuthorizerCustom authentication

Example with API Key:

  1. Create API Key in API Gateway console
  2. Create Usage Plan and associate with API
  3. Require API key on the POST method

4. Deploy API

  1. Create a deployment stage (e.g., prod)
  2. Note the invoke URL: https://{api-id}.execute-api.{region}.amazonaws.com/prod/thingsee

5. Configure Thingsee Integration

Contact Haltian support with:

  • Endpoint URL: Your API Gateway invoke URL
  • Authentication: API key or other credentials
  • Headers: Any required custom headers

Message Format

Thingsee sends messages as JSON arrays:

[
  {
    "tsmId": 12100,
    "tsmEv": 10,
    "tsmTs": 1520416221,
    "tsmTuid": "TSPR04E2O90201558",
    "tsmGw": "TSGW01ABC123456",
    "temp": 21.3,
    "humd": 45.2
  }
]

Advanced Configuration

Serverless Framework

Use Serverless Framework for infrastructure as code:

# serverless.yml
service: thingsee-integration

provider:
  name: aws
  runtime: python3.9
  region: eu-west-1

functions:
  processThingsee:
    handler: handler.lambda_handler
    events:
      - http:
          path: thingsee
          method: post
          private: true  # Requires API key
    environment:
      DYNAMODB_TABLE: ${self:service}-${self:provider.stage}

resources:
  Resources:
    SensorDataTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:service}-${self:provider.stage}
        AttributeDefinitions:
          - AttributeName: tuid
            AttributeType: S
          - AttributeName: timestamp
            AttributeType: N
        KeySchema:
          - AttributeName: tuid
            KeyType: HASH
          - AttributeName: timestamp
            KeyType: RANGE
        BillingMode: PAY_PER_REQUEST

Error Handling

Implement dead letter queues for failed messages:

import boto3

sqs = boto3.client('sqs')
DLQ_URL = 'https://sqs.region.amazonaws.com/account/thingsee-dlq'

def lambda_handler(event, context):
    try:
        # Process messages
        process_messages(event)
    except Exception as e:
        # Send to DLQ for retry
        sqs.send_message(
            QueueUrl=DLQ_URL,
            MessageBody=event['body'],
            MessageAttributes={
                'Error': {'StringValue': str(e), 'DataType': 'String'}
            }
        )
        raise

Resources