授人以鱼不如授人以渔, 目的不是为了教会你具体项目开发, 而是学会学习的能力. 希望大家分享给你周边需要的朋友或者同学, 说不定大神成长之路有博哥的奠基石...
QQ 技术互动交流群: ESP8266&32 物联网开发 群号 622368884, 不喜勿喷
一, 你如果想学基于 Arduino 的 ESP8266 开发技术
一, 基础篇
ESP8266 开发之旅 基础篇1 走进 ESP8266 的世界
ESP8266 开发之旅 基础篇2 如何安装 ESP8266 的 Arduino 开发环境
ESP8266 开发之旅 基础篇3 ESP8266 与 Arduino 的开发说明
ESP8266 开发之旅 基础篇4 ESP8266 与 EEPROM
ESP8266 开发之旅 基础篇5 ESP8266 SPI 通信和 I2C 通信
ESP8266 开发之旅 基础篇6 Ticker--ESP8266 定时库
二, 网络篇
ESP8266 开发之旅 网络篇1 认识一下 Arduino Core For ESP8266
ESP8266 开发之旅 网络篇2 ESP8266 工作模式与 ESP8266WiFi 库
ESP8266 开发之旅 网络篇3 Soft-AP--ESP8266WiFiAP 库的使用
ESP8266 开发之旅 网络篇4 Station--ESP8266WiFiSTA 库的使用
ESP8266 开发之旅 网络篇5 Scan Wi-Fi--ESP8266WiFiScan 库的使用
ESP8266 开发之旅 网络篇6 ESP8266WiFiGeneric-- 基础库
ESP8266 开发之旅 网络篇7 TCP Server & TCP Client
ESP8266 开发之旅 网络篇8 SmartConfig-- 一键配网
ESP8266 开发之旅 网络篇9 HttpClient--ESP8266HTTPClient 库的使用
ESP8266 开发之旅 网络篇10 UDP 服务
ESP8266 开发之旅 网络篇 webServer--ESP8266WebServer 库的使用
ESP8266 开发之旅 网络篇 域名服务 --ESP8266mDNS 库
ESP8266 开发之旅 网络篇 SPIFFS--ESP8266 Flash 文件系统
ESP8266 开发之旅 网络篇 Web 配网
ESP8266 开发之旅 网络篇 真正的域名服务 --DNSServer
ESP8266 开发之旅 网络篇 无线更新 --OTA 固件更新
三, 应用篇
ESP8266 开发之旅 应用篇1 局域网应用 -- 炫酷 RGB 彩灯
ESP8266 开发之旅 应用篇2 OLED 显示天气屏
ESP8266 开发之旅 应用篇3 简易版 Wi-Fi 小车
四, 高级篇
ESP8266 开发之旅 进阶篇1 代码优化 -- ESP8266 内存管理
ESP8266 开发之旅 进阶篇2 闲聊 Arduino IDE For ESP8266 配置
ESP8266 开发之旅 进阶篇3 闲聊 ESP8266 Flash
ESP8266 开发之旅 进阶篇4 常见问题 -- 解决困扰
ESP8266 开发之旅 进阶篇5 代码规范 -- 像写文章一样优美
ESP8266 开发之旅 进阶篇6 ESP-specific APIs 说明
1. 前言
在前面的博文 玩转 OneNET 物联网平台之 MQTT 服务4 -- 远程控制 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 没有处理设备从在线状态切换成离线状态的过程, 需要实时更新设备状态; 赞未完美解决, 只能兜底方案.
但是, 我们离产品化越来越近了.
来源: https://www.cnblogs.com/danpianjicainiao/p/11769440.html