玩转OneNET物联网平台之MQTT服务⑦ —— 远程控制LED(数量无限制)+ Android App控制 优化第一版
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。
QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷
一、你如果想学基于Arduino的ESP8266开发技术
一、基础篇
二、网络篇
- ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
- ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
- ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
- ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
- ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
- ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
- ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
- ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
- ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
- ESP8266开发之旅 网络篇⑩ UDP服务
- ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
- ESP8266开发之旅 网络篇⑫ 域名服务——ESP8266mDNS库
- ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 Flash文件系统
- ESP8266开发之旅 网络篇⑭ web配网
- ESP8266开发之旅 网络篇⑮ 真正的域名服务——DNSServer
- ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新
三、应用篇
四、高级篇
1.前言
在前面的博文 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制 中,博主只是大体上讲述了整个小项目的构造。但是,如果作为一个产品来开发的话,还是存在不少问题。这里罗列几个我认为比较重要的问题点:
- 问题1:App作为一个特殊的设备,理论上也应该支持自注册功能,不应该由开发者或者用户额外去调用API调试工具创建设备,起码得简化这个流程;
- 问题2:App没有处理设备从在线状态切换成离线状态的过程,需要实时更新设备状态;
接下来,博主就会针对这两个重要的问题点进行解决思路以及解决步骤的讲解,请读者边思考边实验。
2.解决问题点1
App作为一个特殊的设备,理论上也应该支持自注册功能,不应该由开发者或者用户额外去调用API调试工具创建设备,起码得简化这个流程
2.1 解决思路
- 我们目的无非是为了得到一个真实存在的DeviceID,既然OneNet 平台给我们提供了 新增设备 的API,那么我们可以通过它来创建设备并且获取设备ID。

因为创建设备需要设备唯一性标识,而android手机上唯一性东西非常多,我们这里考虑用设备序列号
Android系统2.3版本以上可以通过下面的方法得到Serial Number,且非手机设备也可以通过该接口获取。
String serial= android.os.Build.SERIAL;

2.2 解决步骤
- 修改app逻辑,加上注册方法
/**
* 新增OneNet设备
*/
public class RegisterOneNetDeviceEntity extends BaseResponseEntity {
public dataModel data;
public static class dataModel{
public String device_id;
}
@Override
protected String createArgs(Object... params) {
OneNetDeviceModel model = (OneNetDeviceModel) params[0];
JSONObject object = new JSONObject();
try {
object.put("title",model.getTitle());
object.put("auth_info",model.getAuth_info());
} catch (JSONException e) {
e.printStackTrace();
}
return object.toString();
}
@Override
protected String makeUrl() {
return API_POST_REGISTER_DEVICE;
}
public String request(OneNetDeviceModel model) {
method = HttpUtilCore.Method.Post;
String json = requestJson(model);
//内部消化
return handleResponse(json, new OnResponseListener<RegisterOneNetDeviceEntity>() {
@Override
public void onSuccess(String json, RegisterOneNetDeviceEntity response) {
data = response.data;
}
@Override
public void onFailed(String reason) {
Logger.d(reason);
}
@Override
public void onTimeout() {
Logger.d("请求超时");
}
});
}
}
- 用户点击注册,加上设备序列号
@Override
public void onInitView(Bundle savedInstanceState) {
PreferenceUtil preference = PreferenceUtil.getInstance();
if(!TextUtils.isEmpty(preference.getDeviceId())){
this.onConfigConfirm();
return;
}
getDefaultNavigation().setTitle("配置智能灯");
getDefaultNavigation().getLeftButton().hide();
etDevice.setText("Android_" + android.os.Build.SERIAL);
etProduct.setText(preference.getProductId());
etApikey.setText(preference.getApiKey());
}
- 新增成功之后,存储服务器返回的device_id
@Override
public void register(Context context, final OneNetConfigDALEx config, final ICallBack<String> callBack) {
if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){
task.cancel(true);
}
task = new SimpleTask() {
OneNetDeviceModel device;
RegisterOneNetDeviceEntity entity;
@Override
protected void onPreExecute() {
PreferenceUtil preference = PreferenceUtil.getInstance();
preference.writePreferences(PreferenceUtil.ApiKey,config.getApikey());
preference.writePreferences(PreferenceUtil.ProductId,config.getProductId());
entity = new RegisterOneNetDeviceEntity();
device = new OneNetDeviceModel();
device.setTitle(config.getDeviceId());
device.setAuth_info(config.getDeviceId());
}
@Override
protected Object doInBackground(String... strings) {
return entity.request(device);
}
@Override
protected void onPostExecute(Object o) {
String result = (String) o;
PreferenceUtil preference = PreferenceUtil.getInstance();
if("200".equals(result)){//保存设备id
preference.writePreferences(PreferenceUtil.DeviceId,entity.data.device_id);
callBack.onSuccess("");
}else {
callBack.onFaild(result);
}
}
};
task.startTask();
- 这样就完成了手机自注册设备功能

这种方案有个好处就是:
- 非常适合多个成员同时控制一组智能灯,并且不会产生掉线的情况。
但是,请读者注意:
如果你先注册了一次,然后卸载app,再重新注册,这个时候会失败的(原因请读者自行分析)。这个时候请到后台手动删除Android_xxxx的设备。
3.解决问题点2
- 问题点:App没有处理设备从在线状态切换成离线状态的过程,需要实时更新设备状态
3.1 解决方案
目前大概有几种方案:
- 方案a:手机端不断轮询批量获取设备列表接口,可以设置较大的时间间隔,这个方案准确性高,但是耗费流量。目前这个方案相对靠谱。
- 方案b:esp8266端发布设备状态topic和信息,手机端订阅该topic,通过mqtt来更新状态;
- 方案c:利用mqtt的遗嘱消息,但是这个博哥验证了OneNet的,感觉不好用。
- 方案d:如果mqtt的遗嘱消息比较快速实时,可以考虑方案b+c的组合,个人觉得这个是比较理想的方案。(不过,目前我还没有很好实现)
- 方案e:本项目不追求实时性,我们可以手动下拉刷新或者在activity的onshow自动刷一遍,基本上满足要求,采取该方案。
4.总结
- 问题1:App作为一个特殊的设备,理论上也应该支持自注册功能,不应该由开发者或者用户额外去调用API调试工具创建设备,起码得简化这个流程;可以解决。
- 问题2:App没有处理设备从在线状态切换成离线状态的过程,需要实时更新设备状态;赞未完美解决,只能兜底方案。
- 但是,我们离产品化越来越近了。
玩转OneNET物联网平台之MQTT服务⑦ —— 远程控制LED(数量无限制)+ Android App控制 优化第一版的更多相关文章
- 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务② —— 远程控制LED
1.理论基础 参考博主线上博文: 玩转PubSubClient MQTT库 玩转OneNET物联网平台之简介 玩转OneNET物联网平台之MQTT服务① 2.远程控制LED 2.1 实验材料 ...
- 玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之MQTT服务① —— OneNetMqtt全方位调试
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之HTTP服务③ —— OneNet智能灯 HTTP版本
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之HTTP服务① —— 模拟上传温度(TcpClient)
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- 玩转OneNET物联网平台之简介
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- HelloX操作系统与中国移动OneNET物联网平台成功完成对接
HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086 ...
随机推荐
- loadrunner12录制手机app
今天第一次使用LR12录制app,遇到了录制不上的问题,最终解决了,记录一下 我安装的版本是12.02社区版 HP_LoadRunner_12.02_Community_Edition_T7177 ...
- ZooKeeper的ACL实现源码阅读
什么是ACL(Access Control List) zookeeper在分布式系统中承担中间件的作用,它管理的每一个节点上可能都存储这重要的信息,因为应用可以读取到任意节点,这就可能造成安全问题, ...
- 接口测试时数据格式是json,如何将响应内容转换为字典解析
import requests url = 'http://127.0.0.1:5050/index' def apiTestPost(url): datas = { 'a':'cisco3', 'b ...
- WinServer 2012 R2 安装python3.6时出现错误:0x80240017 导致安装失败
解决方法: 依次检查并更新补丁:KB2919442,KB2919355,kb2999226 KB2919442:https://www.microsoft.com/zh-cn/download/det ...
- 基于操作系统原理的Linux 系统的安装
一.实验目的 1.了解Linux操作系统的发行版本. 2.掌握Red Hat Linux 9.0的安装方法. (可用Red Hat Linux 5.0版本替代9.0版本) 3.了解Linux其他版本( ...
- 基于WeChat的消息存储备份、远程控制、小功能项目开源分享计划
WeChat+ 关于该项目 起源 该项目的起因是一个比较程(老)序(油)猿(条)的理由,有一天我发现我下班时间比较早,有点尴尬,但是又不想没事干还坐在公司,那么如何解决我的问题呢,初步想法是远程控制电 ...
- UML图标含义及记忆方法
记忆技巧: 箭头的一方为被动方(被调用者): 箭头的端点为主动方(调用者). 箭头为封闭三角形时,表示类间关系 箭头为半封闭尖括号时,表示类内关系.其中,虚线表示参数强制依赖关系,实线表示属性关系.一 ...
- Eureka参数配置->Server端参数
1.基本参数 参数 默认值 说明 eureka.server.enable-self-preservation true 是否开启自我保护模式 eureka.server.renewal-percen ...
- MongoDB的基本操作(增删改查)
目录 概念整理 数据库:一个MongoDB中可以建立多个数据库. 集合:MongoDB的文档组. 文档:实际存放数据的地方. 常见的操作 数据库(新增,删除) 集合(新增,编辑,删除) 文档(增删 ...
- Java入门学习笔记(全)
JAVA https://zhuanlan.zhihu.com/p/21454718 引用部分实验楼代码,侵删 先通读文档 再亲自试标程 复习时自己再批注 1.a = b += c = -~d a = ...