Skip to content

Real-time Location Integration Guide

This document is intended for developers and describes how to access real-time location data services through API and WebSocket.


1. Overview

This service provides two integration methods:

Method Use Case Description
API + WebSocket Backend/mobile applications requiring real-time location data Obtain access credentials via REST API and subscribe to real-time location data via WebSocket
Embedded Page Quick visualization of location data Embed the ready-to-use location visualization page via WebView or iframe

1.1 Real-time Location Data Acquisition Process

Acquiring real-time location data requires completing the following core steps:

flowchart TD
    subgraph Initialization Phase
        A[1. Obtain IoT Token] -->|Call Token API| B[2. Establish WebSocket Connection]
        B -->|Authenticate with Token| C[3. Subscribe to Location Topic]
    end

    subgraph Data Reception Phase
        C --> D[4. Start Location Reporting]
        D -->|Call Start API| E[Receive Real-time Location Data]
    end

    subgraph Maintenance Phase
        E --> F{Continue Receiving?}
        F -->|Yes| G[Renew Location Reporting]
        G -->|Call Start API every 55s| E
        F -->|No| H[Stop Location Reporting]
    end

    style A fill:#e1f5fe
    style B fill:#e1f5fe
    style C fill:#e1f5fe
    style D fill:#fff3e0
    style E fill:#e8f5e9
    style G fill:#fce4ec

Sequence Diagram

sequenceDiagram
    participant App as Your App
    participant API as Platform API
    participant IoT as IoT Service
    participant Sensor as Sensor

    Note over App,Sensor: Initialization Phase
    App->>API: 1. Obtain IoT Token (POST /v1/iot/tokens)
    API-->>App: Return Token + host
    App->>IoT: 2. Establish WebSocket Connection (with Token)
    IoT-->>App: Connection successful
    App->>IoT: 3. Subscribe to Topic (/location/{sn})

    Note over App,Sensor: Data Reception Phase
    App->>API: 4. Start Location Reporting (PUT .../location/start)
    API->>Sensor: Notify sensor to start reporting
    Sensor-->>IoT: Report location data
    IoT-->>App: 5. Push real-time location data

    Note over App,Sensor: Maintenance Phase (renew every 55 seconds)
    App->>API: Renew location reporting
    API->>Sensor: Extend reporting validity
    Sensor-->>IoT: Continue reporting location data
    IoT-->>App: Continue pushing location data

Key Timing Information

Step Operation Validity Period Description
Obtain IoT Token Call Token API 30 minutes Used for WebSocket authentication
WebSocket Connection Establish MQTT connection 1 hour Policy validity period, maintain heartbeat
Start Location Reporting Call Start API 1 minute Sensor-controlled, must renew before expiration

Important: - You must first establish a WebSocket connection and subscribe to the Topic before starting location reporting - The validity period for starting location reporting is only 1 minute (controlled by the sensor). To continuously receive data, you must call the Start API to renew before expiration


2. Prerequisites

2.1 Obtain API Credentials

You can apply for the following credentials in the Integration Console:

Credential Description Purpose
ApiKey API access key Identifies your integration application
Secret Signing key Used to generate request signatures for security

Note: Each integration application has unique credentials. Please keep your Secret secure and do not expose it.

2.2 Sensor Authorization

Ensure that the sensors you need to access are authorized for your integration application.

2.3 API Authentication

All integration API requests use HMAC-SHA256 signature authentication, including: - Obtain IoT Token - Start/Stop location reporting

Authorization Header Format

All requests must include the Authorization header:

Authorization: HMAC-SHA256 ApiKey=<API_KEY>, Timestamp=<TIMESTAMP>, Nonce=<NONCE>, Signature=<SIGNATURE>
Parameter Description
API_KEY Your API access key
TIMESTAMP Current Unix timestamp (seconds)
NONCE Random string (UUID recommended)
SIGNATURE HMAC-SHA256 signature result (lowercase hexadecimal)

Signature Generation Steps

  1. Build the signature string: <Timestamp>.<Nonce>
  2. Sign the string using HMAC-SHA256 algorithm with your Secret
  3. Convert the signature result to a lowercase hexadecimal string

For complete code examples including HMAC authentication implementation, see Section 5 - Complete Code Example.


3. Integration Method 1: API + WebSocket

3.1 Step 1: Obtain Access Token

Request Specification

Item Description
Endpoint POST /v1/iot/tokens
Authentication HMAC-SHA256 signature authentication (see 2.3 API Authentication)
Content-Type application/json

Request Example

POST /v1/iot/tokens HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: HMAC-SHA256 ApiKey=your_api_key, Timestamp=1738708800, Nonce=550e8400-e29b-41d4-a716-446655440000, Signature=abc123...

{
  "sn": "ATR_GN_P4-250120-09527"
}

Response Example

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expireTime": "2025-02-04T12:30:00Z",
  "host": "iot.example.com",
  "data": {
    "scanArea": {
      "left": 0,
      "right": 100,
      "height": 200
    },
    "zones": [
      {
        "name": "Zone1",
        "x": 10,
        "y": 20,
        "width": 30,
        "height": 40
      }
    ],
    "preference": 0
  }
}
Field Type Description Source
token String WebSocket connection credential
expireTime String Token expiration time (ISO 8601 UTC format)
host String WebSocket service address
data.scanArea Object Sensor scan area configuration
data.zones Array Sensor zone list
data.preference Integer Angle preference setting

Important: Token validity is 30 minutes. Please refresh before expiration.


3.2 Step 2: Establish WebSocket Connection

Connection URL

wss://<host>/mqtt?token=<token>&clientId=<clientId>&x-amz-customauthorizer-name=third-party-auth
Parameter Description Requirement
token Access credential Full token obtained from Step 1
clientId Client identifier UUID recommended for uniqueness
x-amz-customauthorizer-name Authorizer name Fixed value: third-party-auth

For complete code example of WebSocket connection, see Section 5 - Complete Code Example.


3.3 Step 3: Subscribe to Real-time Location Data

Topic Format

/location/{sn}

Where {sn} is the sensor serial number.

Data Format

{
  "method": "location.report",
  "params": [
    {
    "id": 1,
    "x": 156,
    "y": 234,
    "z": 175,
    "state": 40,
    "zoneId": 1
    }
  ]
}
Field Type Description Source
method String Message type, fixed as location.report
params[].id Integer Target identifier
params[].x Integer X coordinate (cm)
params[].y Integer Y coordinate (cm)
params[].z Integer Z coordinate/height (cm)
params[].state Integer Status code

Status Code Description

Status Code Description
40 Occupied
80 On couch
90 In bed
99 Suspected fall
100 Fall

3.4 Step 4: Start Real-time Location Reporting

After establishing a WebSocket connection and subscribing to the Topic, you need to start the sensor's real-time location reporting function to begin receiving location data.

Request Specification

Item Description
Endpoint PUT /v1/sensors/{sensorId}/actions/location/start
Authentication HMAC-SHA256 signature authentication (see 2.3 API Authentication)
Content-Type application/json

Request Example

PUT /v1/sensors/ATR_GN_P4-250120-09527/actions/location/start HTTP/1.1
Host: api.example.com
Authorization: HMAC-SHA256 ApiKey=your_api_key, Timestamp=1738708800, Nonce=550e8400-e29b-41d4-a716-446655440000, Signature=abc123...

Response Example

HTTP/1.1 200 OK
Content-Type: application/json

{
  "code": 0,
  "message": "success"
}

Important Notes

  • Validity Period: After each start, the sensor will continuously report location data for 1 minute
  • Renewal Mechanism: To continuously receive data, you must call this API again within 1 minute to renew
  • Recommendation: Call every 55 seconds to ensure reporting doesn't interrupt

Stop Reporting (Optional)

To stop location reporting, call the following API:

PUT /v1/sensors/{sensorId}/actions/location/stop HTTP/1.1
Host: api.example.com
Authorization: HMAC-SHA256 ApiKey=your_api_key, Timestamp=1738708800, Nonce=550e8400-e29b-41d4-a716-446655440000, Signature=abc123...

3.5 Step 5: Ongoing Maintenance and Renewal

To ensure continuous reception of location data, the following renewal mechanisms need to be maintained:

Renewal Schedule

Item Validity Period Recommended Renewal Interval
Location Reporting Start 1 minute Every 55 seconds
IoT Token 30 minutes 5 minutes before expiration
WebSocket Connection 1 hour Maintain active heartbeat

For complete code example of renewal implementation, see Section 5 - Complete Code Example.


4. Integration Method 2: Embedded Page

If you need to quickly display a location visualization interface in your application, you can embed the ready-to-use page via WebView or iframe.

4.1 Mobile Integration (WebView)

iOS Example (Swift):

// Load page
let url = URL(string: "https://domain-name/rtl")!
webView.load(URLRequest(url: url))

// Send location data
let message = """
{
    "type": "PONTOCARE_REAL_LOCATION_DATA",
    "data": {
        "sn": "ATR_GN_P4-159875-00001",
        "endpoint": "wss://iot.example.com",
        "token": "your_token_here",
        "zoneInfo": { ... }
    }
}
"""
webView.evaluateJavaScript("sendMessageToWebView('\(message)')")

Android Example (Kotlin):

webView.evaluateJavascript("sendMessageToWebView('$message')", null)

4.2 PC Browser Integration (iframe)

<iframe id="locationFrame" src="https://domain-name/rtl"></iframe>

<script>
const iframe = document.getElementById('locationFrame');

iframe.onload = () => {
    const message = {
        type: "PONTOCARE_REAL_LOCATION_DATA",
        data: {
            sn: "ATR_GN_P4-159875-00001",
            endpoint: "wss://iot.example.com",
            token: "your_token_here",
            zoneInfo: { ... }
        }
    };
    iframe.contentWindow.postMessage(message, 'https://domain-name');
};
</script>

4.3 Message Parameter Format

Field Type Description Source
type String Fixed value: PONTOCARE_REAL_LOCATION_DATA Constant
data.sn String Sensor serial number User configuration
data.endpoint String WebSocket service address From Token API response (host)
data.token String Access token From Token API response (token)
data.zoneInfo.scanArea Object Scan area configuration From Token API response (data.scanArea)
data.zoneInfo.zones Array Zone list From Token API response (data.zones)

5. Complete Example Code

5.1 Python Complete Example

#!/usr/bin/env python3
"""
Location Service MQTT Client
===========================
A sample client for receiving sensor location data via MQTT over WebSocket.

This script demonstrates:
1. Authenticating with the IoT platform using HMAC-SHA256
2. Starting the sensor location reporting service
3. Connecting to AWS IoT Core via WebSocket (WSS)
4. Subscribing to and receiving location data

Prerequisites:
    pip install paho-mqtt requests
"""

import json
import hmac
import hashlib
import time
import uuid
import ssl
import requests
import urllib.parse
import paho.mqtt.client as mqtt

# =============================================================================
# Configuration - Update these values with your credentials
# =============================================================================
API_KEY = "your_api_key"          # Your API Key
SECRET = "your_secret"             # Your API Secret
SENSOR_SN = "your_device_sn"       # Device Serial Number
TENANT_ID = "your_tenant_id"       # Tenant ID
API_BASE_URL = "https://your_api_base_url"  # API Base URL

# =============================================================================
# Helper Functions
# =============================================================================

def generate_signature(message: str, secret: str) -> str:
    """
    Generate HMAC-SHA256 signature.

    Args:
        message: The message to sign
        secret: The secret key

    Returns:
        Hexadecimal signature string
    """
    return hmac.new(
        secret.encode('utf-8'),
        message.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

def build_auth_header(api_key: str, secret: str) -> str:
    """
    Build Authorization header with HMAC-SHA256 signature.

    Args:
        api_key: Your API Key
        secret: Your API Secret

    Returns:
        Authorization header value
    """
    timestamp = int(time.time())
    nonce = str(uuid.uuid4())
    message = f"{timestamp}.{nonce}"
    signature = generate_signature(message, secret)
    return f"HMAC-SHA256 ApiKey={api_key}, Timestamp={timestamp}, Nonce={nonce}, Signature={signature}"

# =============================================================================
# API Functions
# =============================================================================

def get_iot_token(device_sn: str) -> dict:
    """
    Get IoT Token for establishing MQTT connection.

    Args:
        device_sn: Device Serial Number

    Returns:
        Dict containing 'token' and 'host'
    """
    auth_header = build_auth_header(API_KEY, SECRET)

    response = requests.post(
        f"{API_BASE_URL}/v1/iot/tokens",
        headers={
            "Content-Type": "application/json",
            "Authorization": auth_header
        },
        json={"sn": device_sn},
        verify=False
    )

    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"Failed to get token: {response.status_code} - {response.text}")

def start_location_service(tenant_id: str, device_sn: str) -> bool:
    """
    Start sensor location reporting service.

    Args:
        tenant_id: Tenant ID
        device_sn: Device Serial Number

    Returns:
        True if successful, False otherwise
    """
    auth_header = build_auth_header(API_KEY, SECRET)
    url = f"{API_BASE_URL}/v1/tenants/{tenant_id}/sensors/{device_sn}/actions/location/start"

    response = requests.put(
        url,
        headers={
            "Authorization": auth_header,
            "Content-Type": "application/json"
        },
        verify=False
    )

    if response.status_code in (200, 204):
        print("[OK] Location service started")
        return True
    else:
        print(f"[ERROR] Failed to start location service: {response.status_code}")
        return False

# =============================================================================
# MQTT Callbacks
# =============================================================================

def on_connect(client, userdata, flags, rc, properties=None):
    """Called when the client connects to the broker."""
    if rc == 0:
        print("[OK] Connected to MQTT broker")
        topic = f"/location/{SENSOR_SN}"
        client.subscribe(topic)
        print(f"[OK] Subscribed to: {topic}")
    else:
        print(f"[ERROR] Connection failed with code: {rc}")

def on_message(client, userdata, msg):
    """Called when a message is received."""
    try:
        payload = json.loads(msg.payload.decode())
        print(f"\n[RECEIVED] Topic: {msg.topic}")
        print(f"Data: {json.dumps(payload, indent=2)}")
    except Exception as e:
        print(f"[ERROR] Failed to parse message: {e}")

# =============================================================================
# Main
# =============================================================================

def main():
    print("=" * 60)
    print("Location Service MQTT Client")
    print("=" * 60)

    # Step 1: Get IoT Token
    print("\n[1/4] Getting IoT token...")
    try:
        token_data = get_iot_token(SENSOR_SN)
        token = token_data["token"]
        iot_host = token_data["host"]
        print(f"[OK] Token obtained, host: {iot_host}")
    except Exception as e:
        print(f"[ERROR] {e}")
        return

    # Step 2: Start location service
    print("\n[2/4] Starting location service...")
    start_location_service(TENANT_ID, SENSOR_SN)

    # Step 3: Configure MQTT client
    print("\n[3/4] Connecting to MQTT broker...")
    client_id = f"client-{uuid.uuid4().hex[:8]}"

    client = mqtt.Client(
        client_id=client_id,
        transport="websockets",
        callback_api_version=mqtt.CallbackAPIVersion.VERSION2
    )

    client.on_connect = on_connect
    client.on_message = on_message

    # Build WebSocket path with authentication
    encoded_token = urllib.parse.quote(token, safe='')
    encoded_client_id = urllib.parse.quote(client_id)
    ws_path = f"/mqtt?token={encoded_token}&clientId={encoded_client_id}&x-amz-customauthorizer-name=third-party-auth"

    client.ws_set_options(path=ws_path)

    # Configure SSL (disable certificate verification for self-signed certs)
    ssl_context = ssl.create_default_context()
    ssl_context.check_hostname = False
    ssl_context.verify_mode = ssl.CERT_NONE
    client.tls_set_context(ssl_context)

    # Step 4: Connect and loop
    print(f"       Connecting to: {iot_host}")
    try:
        client.connect(iot_host, 443, 60)
        print("[OK] Connection established, waiting for messages...")
        print("       Press Ctrl+C to exit\n")
        client.loop_forever()
    except Exception as e:
        print(f"[ERROR] Connection failed: {e}")

if __name__ == "__main__":
    main()

6. Best Practices

6.1 Location Reporting Renewal Management

  • Periodic Renewal: Call Start API every 55 seconds to ensure reporting doesn't interrupt
  • Retry on Failure: Implement retry mechanism when renewal fails
  • Status Monitoring: Monitor if location data is being received normally, auto-renew when abnormal

6.2 Token Management

  • Cache and Reuse: Reuse tokens within validity period to avoid frequent requests
  • Preemptive Refresh: Obtain new token 5 minutes before expiration
  • Secure Storage: Store tokens securely, avoid logging or exposing them

6.3 Connection Management

  • Auto-reconnect: Implement disconnect-reconnect mechanism
  • Heartbeat: Send heartbeat packets periodically to keep connection alive
  • Exception Handling: Properly handle various connection exceptions

6.4 Performance Optimization

  • Connection Pool: Reasonably control WebSocket connection count
  • Message Queue: Use queues to process location data asynchronously
  • Data Filtering: Filter necessary data according to business needs

7. FAQ

Q1: Why am I not receiving location data?

Please check the following: 1. Have you called the Start API to start location reporting? 2. Has the location reporting expired? (Valid for 1 minute) 3. Is the WebSocket correctly connected and subscribed to the Topic? 4. Is the sensor online and authorized?

Q2: How long is the validity period for location reporting?

After each call to the Start API, the sensor will continuously report location data for 1 minute. To continuously receive data, you must renew before expiration.

Q3: How to handle token expiration?

Proactively refresh the token before it expires, or catch connection disconnect events and re-obtain the token to reconnect.

Q4: Can one token be used for multiple sensors?

No. Each token is bound to a specific sensor. You need to obtain separate tokens for different sensors.

Q5: What is the maximum WebSocket connection duration?

The maximum connection validity is 1 hour. You need to re-establish the connection after timeout.

Q6: How to monitor multiple sensors simultaneously?

Create independent WebSocket connections for each sensor, and separately start location reporting and obtain tokens for each.


8. Technical Support

If you encounter any issues during integration, please contact technical support with the following information:

  • Your API Key (do not share your Secret)
  • Sensor serial number
  • Error message screenshots or logs
  • Steps to reproduce the issue