Code Examples
Complete, production-ready examples for integrating with WAYSCloud IoT Platform.
Complete Python Application
Full-featured IoT application with error handling and reconnection logic.
import paho.mqtt.client as mqtt
import requests
import json
import time
import os
from datetime import datetime
# Configuration
API_KEY = os.getenv('WAYSCLOUD_API_KEY')
API_URL = 'https://api.wayscloud.services/v1/iot'
MQTT_BROKER = 'mqtt.wayscloud.services'
MQTT_PORT = 8883
class WaysCloudIoTDevice:
def __init__(self, device_name, device_type='sensor'):
self.api_key = API_KEY
self.device_name = device_name
self.device_type = device_type
self.device_id = None
self.mqtt_client = None
self.mqtt_credentials = None
def register(self):
"""Register device and get MQTT credentials"""
headers = {
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json'
}
payload = {
'name': self.device_name,
'type': self.device_type,
'metadata': {
'sdk_version': '1.0.0',
'platform': 'python'
}
}
response = requests.post(
f'{API_URL}/devices',
headers=headers,
json=payload
)
if response.status_code == 200:
data = response.json()
self.device_id = data['device_id']
self.mqtt_credentials = data['mqtt_credentials']
print(f"✓ Device registered: {self.device_id}")
return True
else:
print(f"✗ Registration failed: {response.text}")
return False
def connect_mqtt(self):
"""Connect to MQTT broker with TLS"""
self.mqtt_client = mqtt.Client(
client_id=self.mqtt_credentials['client_id']
)
# Set credentials
self.mqtt_client.username_pw_set(
self.mqtt_credentials['username'],
self.mqtt_credentials['password']
)
# Enable TLS
self.mqtt_client.tls_set()
# Set callbacks
self.mqtt_client.on_connect = self.on_connect
self.mqtt_client.on_disconnect = self.on_disconnect
self.mqtt_client.on_message = self.on_message
try:
self.mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
self.mqtt_client.loop_start()
print(f"✓ Connected to MQTT broker")
return True
except Exception as e:
print(f"✗ MQTT connection failed: {e}")
return False
def on_connect(self, client, userdata, flags, rc):
"""Callback when connected to MQTT broker"""
if rc == 0:
print("✓ MQTT connected successfully")
# Subscribe to command topic
client.subscribe(f"devices/{self.device_id}/commands")
print(f"✓ Subscribed to commands topic")
else:
print(f"✗ MQTT connection failed with code {rc}")
def on_disconnect(self, client, userdata, rc):
"""Callback when disconnected from MQTT broker"""
if rc != 0:
print(f"⚠ Unexpected disconnect. Reconnecting...")
self.reconnect()
def on_message(self, client, userdata, msg):
"""Callback when message received"""
try:
payload = json.loads(msg.payload.decode())
print(f"← Command received: {payload}")
self.handle_command(payload)
except Exception as e:
print(f"✗ Error processing message: {e}")
def handle_command(self, command):
"""Handle incoming commands"""
cmd_type = command.get('type')
if cmd_type == 'ping':
self.send_event('pong', {'timestamp': datetime.now().isoformat()})
elif cmd_type == 'config_update':
print(f"⚙ Config update: {command.get('config')}")
else:
print(f"⚠ Unknown command type: {cmd_type}")
def reconnect(self):
"""Reconnect with exponential backoff"""
retry_delay = 1
max_delay = 60
while True:
try:
self.mqtt_client.reconnect()
print("✓ Reconnected successfully")
break
except:
print(f"⚠ Reconnection failed. Retrying in {retry_delay}s...")
time.sleep(retry_delay)
retry_delay = min(retry_delay * 2, max_delay)
def send_telemetry(self, data):
"""Send telemetry data"""
topic = f"devices/{self.device_id}/telemetry"
payload = json.dumps({
'timestamp': datetime.now().isoformat(),
'data': data
})
result = self.mqtt_client.publish(topic, payload, qos=1)
if result.rc == mqtt.MQTT_ERR_SUCCESS:
print(f"→ Telemetry sent: {data}")
return True
else:
print(f"✗ Failed to send telemetry")
return False
def send_event(self, event_type, data):
"""Send event"""
topic = f"devices/{self.device_id}/events"
payload = json.dumps({
'timestamp': datetime.now().isoformat(),
'event': event_type,
'data': data
})
self.mqtt_client.publish(topic, payload, qos=1)
print(f"→ Event sent: {event_type}")
def update_status(self, status):
"""Update device status"""
topic = f"devices/{self.device_id}/status"
payload = json.dumps({
'status': status,
'timestamp': datetime.now().isoformat()
})
self.mqtt_client.publish(topic, payload, qos=1)
def disconnect(self):
"""Clean disconnect"""
self.update_status('offline')
self.mqtt_client.loop_stop()
self.mqtt_client.disconnect()
print("✓ Disconnected cleanly")
# Example usage
if __name__ == '__main__':
# Create and register device
device = WaysCloudIoTDevice('Temperature Sensor Demo', 'sensor')
if device.register():
if device.connect_mqtt():
# Send status
device.update_status('online')
# Simulate sensor readings
try:
for i in range(10):
temperature = 20 + (i % 5)
humidity = 60 + (i % 10)
device.send_telemetry({
'temperature': temperature,
'humidity': humidity,
'unit': 'celsius'
})
time.sleep(5)
# Send event
device.send_event('maintenance', {
'message': 'Routine check completed'
})
except KeyboardInterrupt:
print("\n⚠ Interrupted by user")
finally:
device.disconnect()
Node.js Gateway Application
Complete gateway application that aggregates data from multiple sensors.
const mqtt = require('mqtt');
const axios = require('axios');
const API_KEY = process.env.WAYSCLOUD_API_KEY;
const API_URL = 'https://api.wayscloud.services/v1/iot';
const MQTT_BROKER = 'mqtts://mqtt.wayscloud.services:8883';
class IoTGateway {
constructor(name) {
this.apiKey = API_KEY;
this.name = name;
this.deviceId = null;
this.mqttClient = null;
this.sensors = new Map();
}
async register() {
try {
const response = await axios.post(
`${API_URL}/devices`,
{
name: this.name,
type: 'gateway',
metadata: {
platform: 'nodejs',
version: '1.0.0'
}
},
{
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
}
);
this.deviceId = response.data.device_id;
this.mqttCredentials = response.data.mqtt_credentials;
console.log(`✓ Gateway registered: ${this.deviceId}`);
return true;
} catch (error) {
console.error('✗ Registration failed:', error.message);
return false;
}
}
connect() {
const options = {
username: this.mqttCredentials.username,
password: this.mqttCredentials.password,
clientId: this.mqttCredentials.client_id,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000
};
this.mqttClient = mqtt.connect(MQTT_BROKER, options);
this.mqttClient.on('connect', () => {
console.log('✓ Gateway connected to MQTT');
this.mqttClient.subscribe(`devices/${this.deviceId}/commands`);
this.publishStatus('online');
});
this.mqttClient.on('error', (error) => {
console.error('✗ MQTT error:', error.message);
});
this.mqttClient.on('message', (topic, message) => {
this.handleCommand(JSON.parse(message.toString()));
});
this.mqttClient.on('close', () => {
console.log('⚠ MQTT connection closed');
});
}
handleCommand(command) {
console.log('← Command received:', command);
switch (command.type) {
case 'list_sensors':
this.reportSensors();
break;
case 'get_sensor_data':
this.getSensorData(command.sensor_id);
break;
default:
console.log('⚠ Unknown command:', command.type);
}
}
registerSensor(sensorId, sensorType, metadata = {}) {
this.sensors.set(sensorId, {
id: sensorId,
type: sensorType,
metadata: metadata,
lastData: null,
lastSeen: new Date()
});
console.log(`✓ Sensor registered: ${sensorId}`);
}
publishSensorData(sensorId, data) {
const sensor = this.sensors.get(sensorId);
if (!sensor) {
console.error(`✗ Unknown sensor: ${sensorId}`);
return;
}
sensor.lastData = data;
sensor.lastSeen = new Date();
const payload = {
gateway_id: this.deviceId,
sensor_id: sensorId,
sensor_type: sensor.type,
timestamp: new Date().toISOString(),
data: data
};
this.mqttClient.publish(
`devices/${this.deviceId}/telemetry`,
JSON.stringify(payload),
{ qos: 1 }
);
console.log(`→ Data from ${sensorId}:`, data);
}
reportSensors() {
const sensorList = Array.from(this.sensors.values()).map(sensor => ({
id: sensor.id,
type: sensor.type,
last_seen: sensor.lastSeen.toISOString()
}));
this.mqttClient.publish(
`devices/${this.deviceId}/events`,
JSON.stringify({
event: 'sensor_list',
timestamp: new Date().toISOString(),
sensors: sensorList
}),
{ qos: 1 }
);
}
publishStatus(status) {
this.mqttClient.publish(
`devices/${this.deviceId}/status`,
JSON.stringify({
status: status,
timestamp: new Date().toISOString(),
sensor_count: this.sensors.size
}),
{ qos: 1 }
);
}
disconnect() {
this.publishStatus('offline');
this.mqttClient.end();
console.log('✓ Gateway disconnected');
}
}
// Example usage
async function main() {
const gateway = new IoTGateway('Smart Home Gateway');
if (await gateway.register()) {
gateway.connect();
// Simulate sensors
gateway.registerSensor('temp_01', 'temperature', { location: 'living_room' });
gateway.registerSensor('humidity_01', 'humidity', { location: 'living_room' });
gateway.registerSensor('motion_01', 'motion', { location: 'hallway' });
// Simulate sensor data
setInterval(() => {
gateway.publishSensorData('temp_01', {
temperature: 20 + Math.random() * 5,
unit: 'celsius'
});
gateway.publishSensorData('humidity_01', {
humidity: 60 + Math.random() * 10,
unit: 'percent'
});
const motion = Math.random() > 0.7;
gateway.publishSensorData('motion_01', {
detected: motion
});
}, 10000);
// Graceful shutdown
process.on('SIGINT', () => {
console.log('\n⚠ Shutting down...');
gateway.disconnect();
process.exit(0);
});
}
}
main();
ESP32 Arduino Example
Complete Arduino sketch for ESP32 with WiFi and MQTT.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// WiFi credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// MQTT Configuration
const char* mqtt_server = "mqtt.wayscloud.services";
const int mqtt_port = 8883;
const char* mqtt_user = "iot_dev_YOUR_DEVICE_ID";
const char* mqtt_password = "YOUR_MQTT_PASSWORD";
const char* client_id = "iot_dev_YOUR_DEVICE_ID";
const char* device_id = "iot_dev_YOUR_DEVICE_ID";
// Topics
char telemetry_topic[100];
char commands_topic[100];
char status_topic[100];
WiFiClientSecure espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
// Build topics
snprintf(telemetry_topic, 100, "devices/%s/telemetry", device_id);
snprintf(commands_topic, 100, "devices/%s/commands", device_id);
snprintf(status_topic, 100, "devices/%s/status", device_id);
// Connect to WiFi
setup_wifi();
// Configure MQTT
espClient.setInsecure(); // For testing only - use proper certificates in production
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
// Parse JSON command
StaticJsonDocument<256> doc;
deserializeJson(doc, payload, length);
const char* cmd_type = doc["type"];
Serial.println(cmd_type);
if (strcmp(cmd_type, "ping") == 0) {
send_event("pong");
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("connected");
client.subscribe(commands_topic);
send_status("online");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
delay(5000);
}
}
}
void send_telemetry(float temperature, float humidity) {
StaticJsonDocument<256> doc;
doc["timestamp"] = millis();
doc["data"]["temperature"] = temperature;
doc["data"]["humidity"] = humidity;
doc["data"]["unit"] = "celsius";
char buffer[256];
serializeJson(doc, buffer);
client.publish(telemetry_topic, buffer, true);
Serial.println("Telemetry sent");
}
void send_status(const char* status) {
StaticJsonDocument<128> doc;
doc["status"] = status;
doc["timestamp"] = millis();
char buffer[128];
serializeJson(doc, buffer);
client.publish(status_topic, buffer, true);
}
void send_event(const char* event_type) {
char event_topic[100];
snprintf(event_topic, 100, "devices/%s/events", device_id);
StaticJsonDocument<128> doc;
doc["event"] = event_type;
doc["timestamp"] = millis();
char buffer[128];
serializeJson(doc, buffer);
client.publish(event_topic, buffer);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// Simulate sensor readings every 10 seconds
static unsigned long lastMsg = 0;
unsigned long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;
float temperature = 20.0 + random(0, 50) / 10.0;
float humidity = 60.0 + random(0, 100) / 10.0;
send_telemetry(temperature, humidity);
}
}
Next Steps
- Device Management - API reference
- MQTT Credentials - Connection setup
- Usage & Stats - Monitor your devices