Lightweight IoT Cloud Platform
Read/write data with just a URL — A lightweight HTTP data storage service built on VBMAN
cHttpServer, making IoT device data cloud upload incredibly simple.📎 Source: Lightweight IoT Cloud Platform - User Documentation
Project Overview
| Project Info | Details |
|---|---|
| Project Name | Lightweight IoT Cloud Platform |
| Author | TechGeek LaoBai |
| Core Module | VBMAN cHttpServer |
| Application Domain | IoT / Smart Hardware / Data Acquisition |
| Technical Difficulty | Intermediate |
| Last Updated | 2026-06-12 |
Use Cases
- 🌡️ IoT sensor data upload (temperature/humidity, air quality, water level, etc.)
- 💡 Remote device control (switches, dimming, motors, etc.)
- 📱 Web/applet data display
- 🏠 Smart home data hub
- 🔧 Rapid project prototype validation
Core Advantages
| Feature | Description |
|---|---|
| ⚡ Lightning Fast Integration | No SDK needed, just send an HTTP request, up and running in 30 seconds |
| 💰 Free Reads | Read operations are completely free, only writes consume credits |
| 🌐 CORS Friendly | Native CORS support, direct frontend calls |
| 🔒 Data Security | Each Key has independent storage space, no interference |
| 💾 Persistent Storage | Data auto-saved to disk, survives service restarts |
VBMAN Technical Implementation
This project is built on the following VBMAN cHttpServer capabilities:
1. Custom Route Mapping
Using VBMAN cHttpServer's routing system, paths like /yun/w/{key}/{var}/{val}, /yun/r/{key}/{var} are mapped to business handler classes:
' === Register business class ===
Dim HttpServer As New cHttpServer
With HttpServer
.Router.Reg "Yun", New bYunCloud ' Register cloud platform business class
.Router.AutoRoute = True ' Enable auto-routing
.Start 800 ' Listen on port 800
End With2. Business Handler Class
' === bYunCloud.cls - Cloud Platform Core Business ===
' Write data: /yun/w/{key}/{var}/{val}
Public Sub W(ctx As cHttpServerContext)
Dim sKey As String: sKey = ctx.Request.UrlParam(1)
Dim sVar As String: sVar = ctx.Request.UrlParam(2)
Dim sVal As String: sVal = ctx.Request.UrlParam(3)
' Validate Key
If Not ValidateKey(sKey) Then
ctx.Response.Json "{""status"":""fail"",""msg"":""invalid key""}"
Exit Sub
End If
' Check write count
If GetWriteCount(sKey) <= 0 Then
ctx.Response.Json "{""status"":""fail"",""msg"":""no count""}"
Exit Sub
End If
' Save data and deduct count
SaveData sKey, sVar, sVal
DeductCount sKey
ctx.Response.Json "{""status"":""ok"",""var"":""" & sVar & """,""val"":""" & sVal & """,""count"":" & GetWriteCount(sKey) & "}"
End Sub
' Read data: /yun/r/{key}/{var}
Public Sub R(ctx As cHttpServerContext)
Dim sKey As String: sKey = ctx.Request.UrlParam(1)
Dim sVar As String: sVar = ctx.Request.UrlParam(2)
Dim sVal As String: sVal = ReadData(sKey, sVar)
If sVal = "" Then
ctx.Response.Json "{""status"":""notfound""}"
Else
ctx.Response.Json "{""status"":""ok"",""var"":""" & sVar & """,""val"":""" & sVal & """}"
End If
End Sub
' Query count: /yun/q/{key}
Public Sub Q(ctx As cHttpServerContext)
Dim sKey As String: sKey = ctx.Request.UrlParam(1)
ctx.Response.Json "{""status"":""ok"",""count"":" & GetWriteCount(sKey) & "}"
End Sub3. CORS Cross-Origin Support
VBMAN cHttpServer natively supports CORS configuration, allowing direct cross-origin calls from frontend:
With HttpServer
.Cors.AllowOrigin = "*" ' Allow all origins
.Cors.AllowMethods = "GET" ' Only allow GET method
End WithAPI Reference
Write Data
Write a variable's value to the cloud platform.
GET /yun/w/{key}/{var}/{val}| Parameter | Description | Example |
|---|---|---|
key | 32-character authorization Key | a1b2c3d4... |
var | Variable name (custom) | temp, led_state |
val | Variable value (string) | 25.6, 1, hello |
Response Example:
{
"status": "ok",
"var": "temp",
"val": "25.6",
"count": 999999
}Read Data
Read a variable's value from the cloud platform.
GET /yun/r/{key}/{var}Response Example:
{
"status": "ok",
"var": "temp",
"val": "25.6"
}Read operations are free
Read operations are completely free — read as many times as you want.
Query Remaining Count
Query how many write credits are left for a Key.
GET /yun/q/{key}Response Example:
{
"status": "ok",
"count": 999999
}Error Status
| status | Description |
|---|---|
ok | Success |
fail | Failed (invalid Key, insufficient credits, etc.) |
notfound | Variable not found |
Multi-Language Call Examples
Browser / Web (fetch)
// Write data
async function yunWrite(key, varName, value) {
const res = await fetch(
`http://your-server-address/yun/w/${key}/${varName}/${value}`,
);
return res.json();
}
// Read data
async function yunRead(key, varName) {
const res = await fetch(`http://your-server-address/yun/r/${key}/${varName}`);
return res.json();
}
// Usage example
yunWrite("your-key", "temp", "25.6").then((data) => {
console.log("Write successful, remaining credits: " + data.count);
});
yunRead("your-key", "temp").then((data) => {
console.log("Temperature is: " + data.val);
});JSONP Cross-Origin Solution
If you encounter cross-origin issues and CORS is not available, you can use path-style JSONP (no ? parameters needed):
// JSONP read data
function yunReadJSONP(key, varName, callbackName) {
var script = document.createElement("script");
script.src =
"http://your-server-address/yun/r/" + key + "/" + varName + "/" + callbackName;
document.body.appendChild(script);
script.onload = function () {
document.body.removeChild(script);
};
}
// Define global callback function
function handleTempData(data) {
console.log("Temperature is: " + data.val);
}
// Call
yunReadJSONP("your-key", "temp", "handleTempData");Note
Path-style JSONP requires server-side support. If unsure, prefer the fetch + CORS approach.
ESP32 / Arduino
#include <HTTPClient.h>
// Write data
void yunWrite(String key, String varName, String value) {
HTTPClient http;
String url = "http://your-server-address/yun/w/" + key + "/" + varName + "/" + value;
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
Serial.println("Write successful");
}
http.end();
}
// Read data
String yunRead(String key, String varName) {
HTTPClient http;
String url = "http://your-server-address/yun/r/" + key + "/" + varName;
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
return http.getString();
}
return "";
}Python
import requests
BASE_URL = "http://your-server-address"
KEY = "your-32-char-key"
# Write data
r = requests.get(f"{BASE_URL}/yun/w/{KEY}/temp/25.6")
print(r.json())
# Read data
r = requests.get(f"{BASE_URL}/yun/r/{KEY}/temp")
print(r.json())
# Query count
r = requests.get(f"{BASE_URL}/yun/q/{KEY}")
print(r.json())cURL Command Line
# Write data
curl "http://your-server-address/yun/w/your-key/temp/25.6"
# Read data
curl "http://your-server-address/yun/r/your-key/temp"
# Query count
curl "http://your-server-address/yun/q/your-key"Important Notes
Do Not Use QueryString
Never add ? parameters at the end of the URL:
- ❌ Wrong:
/yun/r/key/temp?_=123456 - ✅ Correct:
/yun/r/key/temp
The platform does not support parameters after ?. Adding them will cause variable name misidentification and data read failures.
Technical Reason
The developer of this case did not use VBMAN's route parameter (Route Params) mechanism, but instead implemented custom URL path splitting (splitting /yun/r/key/var by / to extract parameters). This custom parsing approach only handles path segments, not the QueryString part. If you add ?_=123456 after the URL, the custom parser will mistakenly treat ?_=123456 as part of the path, causing variable name errors.
In contrast, VBMAN cHttpServer provides standard route parameter functionality (ctx.Request.UrlParam, ctx.Request.QueryString) that correctly distinguishes between path parameters and query parameters. If you use VBMAN route parameters in your own project, you don't need to worry about this issue.
Variable Name Rules
- Allowed characters: letters, numbers, underscore
_, hyphen- - Variable names are case-sensitive:
Tempandtempare different variables - Avoid using non-ASCII variable names
Value Limits
- Value length should be kept within 1024 characters
- Supports multilingual text, numbers, common symbols
- Special characters should use URL encoding
Data Persistence
- Data is automatically saved and survives server restarts
- Data is batch-flushed to disk every 50 seconds; in extreme cases (e.g., sudden power loss), writes within the last 50 seconds may be lost
Pricing
| Item | Price | Description |
|---|---|---|
| Read Data | Free | Unlimited |
| Write Data | 10 CNY / 1 million times | Each write deducts 1 credit |
| Query Count | Free | Unlimited |
Top-up Method: Contact the admin to add credits. After top-up, you can check the latest balance via the /yun/q/{key} endpoint.
FAQ
Q: What if I forget my Key?
Contact the admin to retrieve it.
Q: Can others see my data?
As long as your Key is not leaked, others cannot read your data. Treat your Key like a password — do not share it publicly.
Q: Is HTTPS supported?
Currently only HTTP is supported. If you need HTTPS, contact the admin for configuration, or use VBMAN HttpServer's TLS functionality for self-deployment.
Q: How many variables can I store?
There is no limit on the number of variables per Key.
Q: Will data be automatically deleted?
Data is permanently stored unless you actively overwrite or delete it.
Q: What happens when credits run out?
The write endpoint will return a failure status, while read and query operations remain available. Credits are automatically restored after top-up.
Project Highlights Summary
| Dimension | Highlight |
|---|---|
| VBMAN Capabilities | cHttpServer routing system + CORS + JSON response + data persistence |
| Ultra-Simple Integration | URL as API, zero SDK, up and running in 30 seconds |
| Cross-Platform | Browser / ESP32 / Arduino / Python / cURL full coverage |
| Business Model | Free reads, pay-per-write, lightweight Data-as-a-Service cloud |