Arduino ESP8266 MQTT 阿里 腾讯 连接示例
ESP8266基于Arduino IDE 快速搭建IoT还是很方便的,降低了很多门槛。官方的示例丰富的话,中小学生都能搞物联网了。真希望各大厂能开办这方面的平台,是素质教育平台,也是播种机,长远来看必有收益。
这里的内容就是实践物联网平台可能用到的代码,简单做个对比,抛砖引玉啦。
有兴趣的同学可以参看大厂官方的文档。
腾讯
设备基于 TCP 的 MQTT 接入
https://cloud.tencent.com/document/product/634/32546
void TENCENTIoTSDK::begin(Client& espClient,
const char* _productKey,
const char* _deviceName,
const char* _deviceSecret,
const char* _region,
long expr)
{
//*
mqttConnecting = false;
if(client != NULL){
delete client;
client=NULL;
}
client = new PubSubClient(espClient);
productKey = _productKey;
deviceName = _deviceName;
deviceSecret = _deviceSecret;
region = _region;
long times = millis();
//# 1. 生成 connid 为一个随机字符串,方便后台定位问题
//connid = "zzz"#RandomConnid(5)
String connid = "zzz12";//#RandomConnid(5);
//# 2. 生成过期时间,表示签名的过期时间,从纪元1970年1月1日 00:00:00 UTC 时间至今秒数的 UTF8 字符串
//expiry = 1234567890#int(time.time()) + 60 * 60
String expiry = String(expr);//exp;
//# 3. 生成 MQTT 的 clientid 部分, 格式为 ${productid}${devicename}
//clientid = "{}{}".format(productID, devicename)
String clientid = "";
clientid += productKey ;
clientid += deviceName;
//# 4. 生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}
//username = "{};12010126;{};{}".format(clientid, connid, expiry)
String username = clientid + ";12010126;" + connid + ";" + expiry;
//# 5. 对 username 进行签名,生成token
//secret_key = devicePsk.encode('utf-8') # convert to bytes
String secret_key = deviceSecret;//-----------------------------------
//data_to_sign = username.encode('utf-8') # convert to bytes
//secret_key = base64.b64decode(secret_key) # this is still bytes
int inputStringLength = secret_key.length();
char sk[inputStringLength + 1];
for (size_t i = 0; i < inputStringLength; i++) {
sk[i] = deviceSecret[i];
}
sk[inputStringLength] = 0;
int decodedLength = Base64.decodedLength(sk, inputStringLength);
char decodedString[decodedLength];
Base64.decode(decodedString, sk, inputStringLength);
String data_to_sign = username;
//secret_key = base64.b64decode(secret_key);
//token = hmac.new(secret_key, data_to_sign, digestmod=hashlib.sha256).hexdigest()
String token = hmac256(data_to_sign, decodedString, decodedLength);
//# 6. 根据物联网通信平台规则生成 password 字段
//password = "{};{}".format(token, "hmacsha256")
String password = token + ";hmacsha256";
//return {
//"clientid" : clientid,
//"username" : username,
//"password" : password
//}
strcpy(mqttUsername, username.c_str());
strcpy(mqttPwd, password.c_str());
Serial.println(clientid);
Serial.println(username);
Serial.println(password);
//设备属性上报
//当设备需要向云端上报数据时,开发平台为设备设定了默认的 Topic:
//上行请求 Topic: $thing/up/property/{ProductID}/{DeviceName}
//上行响应 Topic: $thing/down/property/{ProductID}/{DeviceName}
//设备订阅能收到下发命令zzz响应和下发是走订阅的同一个主题
//$thing/down/property/7IL05FSCJ8/cp1
sprintf(TCLINK_TOPIC_PROP_POST, "$thing/up/property/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_PROP_GET, "$thing/down/property/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_SERVICE_GET, "$thing/down/service/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_SHADOW_POST, "$shadow/operation/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_SHADOW_GET, "$shadow/operation/result/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_EVENT_POST, "$thing/up/event/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_EVENT_GET, "$thing/down/event/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_ACTION_POST, "$thing/up/action/%s/%s", productKey, deviceName);
sprintf(TCLINK_TOPIC_ACTION_GET, "$thing/down/action/%s/%s", productKey, deviceName);
//$shadow/operation/${productId}/${deviceName}
//MQTT 服务器连接地址,广州域设备填入:${ ProductId }.iotcloud.tencentdevices.com,
//这里 ${ ProductId } 为变量参数,用户需填入创建产品时自动生成的产品 ID,
//例如 1A17RZR3XX.iotcloud.tencentdevices.com;端口:8883
sprintf(domain, "%s.iotcloud.tencentdevices.com", productKey);
Serial.println("setBufferSize:");
bool bufok = client->setBufferSize(512);
Serial.println(bufok);
client->setServer(domain, MQTT_PORT); // 连接WiFi之后,连接MQTT服务器 //
client->setCallback(callback);
mqttCheckConnect();
//*/
}
阿里
使用MQTT.fx接入物联网平台
https://help.aliyun.com/document_detail/86706.html?spm=a2c4g.11186631.6.791.3cc43a20M64Pa1
void ALIIoTSDK::begin(Client &espClient,
const char *_productKey,
const char *_deviceName,
const char *_deviceSecret,
const char *_region)
{
mqttConnecting = false;
if(client != NULL){
delete client;
client=NULL;
}
client = new PubSubClient(espClient);
productKey = _productKey;
deviceName = _deviceName;
deviceSecret = _deviceSecret;
region = _region;
long times = millis();
String timestamp = String(times);
//sprintf(clientId, "%s|securemode=3,signmethod=hmacsha256,timestamp=%s|", deviceName, timestamp.c_str());
sprintf(clientId, "%s|securemode=3,signmethod=hmacsha256,timestamp=%s|", deviceName, timestamp.c_str());
String signcontent = "clientId";
signcontent += deviceName;
signcontent += "deviceName";
signcontent += deviceName;
signcontent += "productKey";
signcontent += productKey;
signcontent += "timestamp";
signcontent += timestamp;
//sprintf(clientId, "%s|securemode=3,timestamp=%s,signmethod=hmacsha256|", deviceName, timestamp.c_str());
String pwd = hmac256(signcontent, deviceSecret);
//sprintf(clientId, "xNhylKuXAG775N3GyTyn|securemode=3,timestamp=1610292470098,signmethod=hmacsha1|");
//String pwd = hmacSHA1(signcontent, deviceSecret);
//String pwd = "4B00863263E64F77280AA23D22AE291EAFCF5238";
strcpy(mqttPwd, pwd.c_str());
Serial.println(clientId);
Serial.println(signcontent);
Serial.println(deviceSecret);
Serial.println(pwd);
sprintf(mqttUsername, "%s&%s", deviceName, productKey);
sprintf(ALINK_TOPIC_PROP_POST, "/sys/%s/%s/thing/event/property/post", productKey, deviceName);
sprintf(ALINK_TOPIC_PROP_SET, "$thing/up/property/%s/%s", productKey, deviceName);
sprintf(ALINK_TOPIC_EVENT, "/sys/%s/%s/thing/event", productKey, deviceName);
sprintf(domain, "%s.iot-as-mqtt.%s.aliyuncs.com", productKey, region);
client->setServer(domain, MQTT_PORT); // 连接WiFi之后,连接MQTT服务器
client->setCallback(callback);
mqttCheckConnect();
}
个人觉得使用腾讯平台开发省一些,毕竟微信啊,小程序啊这么的易上手。能免掉开发app的大工程。