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
- Build the signature string:
<Timestamp>.<Nonce> - Sign the string using HMAC-SHA256 algorithm with your
Secret - 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
| 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
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
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):
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