授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷

一、你如果想学基于Arduino的ESP8266开发技术

一、基础篇

  1. ESP8266开发之旅 基础篇① 走进ESP8266的世界
  2. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境
  3. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明
  4. ESP8266开发之旅 基础篇④ ESP8266与EEPROM
  5. ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
  6. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

二、网络篇

  1. ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
  2. ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
  3. ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
  4. ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
  5. ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
  6. ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
  7. ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
  8. ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
  9. ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
  10. ESP8266开发之旅 网络篇⑩ UDP服务
  11. ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
  12. ESP8266开发之旅 网络篇⑫ 域名服务——ESP8266mDNS库
  13. ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 Flash文件系统
  14. ESP8266开发之旅 网络篇⑭ web配网
  15. ESP8266开发之旅 网络篇⑮ 真正的域名服务——DNSServer
  16. ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新

三、应用篇

  1. ESP8266开发之旅 应用篇① 局域网应用 ——炫酷RGB彩灯
  2. ESP8266开发之旅 应用篇② OLED显示天气屏
  3. ESP8266开发之旅 应用篇③ 简易版WiFi小车

四、高级篇

  1. ESP8266开发之旅 进阶篇① 代码优化 —— ESP8266内存管理
  2. ESP8266开发之旅 进阶篇② 闲聊Arduino IDE For ESP8266配置
  3. ESP8266开发之旅 进阶篇③ 闲聊 ESP8266 Flash
  4. ESP8266开发之旅 进阶篇④ 常见问题 —— 解决困扰
  5. ESP8266开发之旅 进阶篇⑤ 代码规范 —— 像写文章一样优美
  6. ESP8266开发之旅 进阶篇⑥ ESP-specific APIs说明

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的设备。

  • App下载地址

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控制 优化第一版的更多相关文章

  1. 玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  2. 玩转OneNET物联网平台之MQTT服务③ —— 远程控制LED(设备自注册)

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  3. 玩转OneNET物联网平台之MQTT服务② —— 远程控制LED

    1.理论基础     参考博主线上博文: 玩转PubSubClient MQTT库 玩转OneNET物联网平台之简介 玩转OneNET物联网平台之MQTT服务① 2.远程控制LED 2.1 实验材料 ...

  4. 玩转OneNET物联网平台之MQTT服务⑤ —— OneNet智能灯+MVP框架

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. 玩转OneNET物联网平台之MQTT服务① —— OneNetMqtt全方位调试

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  6. 玩转OneNET物联网平台之HTTP服务③ —— OneNet智能灯 HTTP版本

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  7. 玩转OneNET物联网平台之HTTP服务① —— 模拟上传温度(TcpClient)

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  8. 玩转OneNET物联网平台之简介

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  9. HelloX操作系统与中国移动OneNET物联网平台成功完成对接

    HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086 ...

随机推荐

  1. Codeforces Numbers 题解

    这题只需要会10转P进制就行了. PS:答案需要约分,可以直接用c++自带函数__gcd(x,y). 洛谷网址 Codeforces网址 Code(C++): #include<bits/std ...

  2. Android Studio [跑马灯]

    MainActivity package com.xdw.secondapp; import android.graphics.Paint; import android.support.v7.app ...

  3. Centos安装PhantomJS

    1.下载PhantomJS [root@liuge ~]# wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-l ...

  4. Flask基础(13)-->Flask扩展Flask-Script

    Flask基础(12)-->Flask扩展Flask-Script # 前提是安装了Flask-Script # 联网运行 pip install flask-script from flask ...

  5. ES6入门之Promise对象

    1. Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件更合理.更强大. 1.1 什么是Promise 简单来说就是一个容器,里面保存着某个未来才会结 ...

  6. [LeetCode] 470. Implement Rand10() Using Rand7()

    Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a functio ...

  7. Drill 学习笔记之 与Mongo性能测试比较

    性能测试: 竟然用了30秒.... 如果使用mongo 客户端只有1-2秒 感觉Drill是把数据拉过来再进行sql优化,并没有使用Mongo的API,效率低下让人失望...

  8. 新手安装vue-cli脚手架

    首先这片文章借鉴了很多博主的,再此对他们表示感谢. 什么是vue? Vue.js是一套构建用户界面的渐进式框架.Vue 只关注视图层,采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 A ...

  9. BZOJ 1965 [AHOI2005]洗牌

    题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联提议用扑克牌打 ...

  10. js通过方法返回对象的注意点

    问题:js通过方法返回一个字面量对象和返回一个提前已经定义好的字面量对象有区别吗? 答案:有 我们先来看看第一种情况,fun1方法返回一个提前没定义的字面量对象,然后通过调用方法返回三个对象,分别是o ...