玩轉OneNET物聯網平台之HTTP服務③ —— OneNet智慧燈 HTTP版本

  • 2019 年 10 月 30 日
  • 筆記

授人以魚不如授人以漁,目的不是為了教會你具體項目開發,而是學會學習的能力。希望大家分享給你周邊需要的朋友或者同學,說不定大神成長之路有博哥的奠基石。。。

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控制 中,這個版本的App控制消息的發送是通過Mqtt客戶端去操作,這就意味著一個長連接。部落客仔細翻閱了一下OneNet的官方文檔,發現可以通過HTTP協議的請求去完成MQTT相同的操作,對於一些適用短連接的場合我們可以使用這個方式去實現。

具體可以參考 OneNet發布消息,讀者重點關注紅色框框。

在這裡插入圖片描述

2.ESP8266端程式碼

  • 完全不需要改造,沿用之前博文的程式碼即可

3. App端程式碼

重點改造幾個地方,讀者直接看注釋地方:

3.1 MVP三劍客

public interface IMainContract {        interface IMainModel extends IBaseModel {          void loadData(Context context, ICallBack<List<OneNetDeviceModel>> callBack);          void updateDeviceDetail(Context context,OneNetDeviceModel model, ICallBack<String> callBack);          //加入http方式          void publishMsgToOneNet(String topic,int qos,String payload);      }        interface IMainView extends IBaseView {          void showLoading(String loadmsg);          void dismissLoading(OnDismissCallbackListener callback);          void refreshList(List<OneNetDeviceModel> list);      }  }

3.1.1 Model層

model層實現上面多加入的方法 publishMsgToOneNet

public class MainModel implements IMainContract.IMainModel {        SimpleTask task;        @Override      public void loadData(Context context, final ICallBack<List<OneNetDeviceModel>> callBack) {            if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){              task.cancel(true);          }          task = new SimpleTask() {                GetOneNetDeviceListEntity entity;                @Override              protected void onPreExecute() {                  entity = new GetOneNetDeviceListEntity();              }                @Override              protected Object doInBackground(String... strings) {                  return entity.request();              }                @Override              protected void onPostExecute(Object o) {                  String result = (String) o;                  if("200".equals(result)){                     if(entity.data != null && entity.data.devices.size()!=0) {                         List<OneNetDeviceModel> list = new ArrayList<>();                         for(OneNetDeviceModel model:entity.data.devices){                             if(!model.getId().equals(PreferenceUtil.getInstance().getDeviceId())){                                 list.add(model);                             }                         }                           callBack.onSuccess(list);                     }                  }else {                      callBack.onFaild(result);                  }              }          };          task.startTask();      }        @Override      public void updateDeviceDetail(Context context, final OneNetDeviceModel model, final ICallBack<String> callBack) {          if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){              task.cancel(true);          }          task = new SimpleTask() {                UpdateOneNetDeviceDetailEntity entity;                @Override              protected void onPreExecute() {                  entity = new UpdateOneNetDeviceDetailEntity(model.getId());              }                @Override              protected Object doInBackground(String... strings) {                  return entity.request(model);              }                @Override              protected void onPostExecute(Object o) {                  String result = (String) o;                  if("200".equals(result)){                      callBack.onSuccess("更新成功");                  }else {                      callBack.onFaild(result);                  }              }          };          task.startTask();      }        @Override      //實現http具體邏輯 也就是訪問onenet的發布消息介面      public void publishMsgToOneNet(final String topic, int qos, final String payload) {          if(task != null && task.getStatus()== AsyncTask.Status.RUNNING){              task.cancel(true);          }          task = new SimpleTask() {                PublishMsgToOneNetlEntity entity;                @Override              protected void onPreExecute() {                  entity = new PublishMsgToOneNetlEntity(topic);              }                @Override              protected Object doInBackground(String... strings) {                  return entity.request(payload);              }                @Override              protected void onPostExecute(Object o) {                  String result = (String) o;                  if("200".equals(result)){                    }else {                    }              }          };          task.startTask();      }  }

3.1.2 View層

  • V層直接調用P層的方法,兩種方式二選一
open.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  JSONObject obj = new JSONObject();                  try {                      obj.put("Did",item.getId());                      obj.put("sta",1);                      //http方式                      presenter.httpPublishMsgToOneNet(AppConstant.Topic.Default_Topic,1,obj.toString());                      //mqtt方式                      //presenter.mqttPublishMsgToOneNet(AppConstant.Topic.Default_Topic,1,obj.toString());                  } catch (JSONException e) {                      e.printStackTrace();                  }              }          });            close.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  JSONObject obj = new JSONObject();                  try {                      obj.put("Did",item.getId());                      obj.put("sta",0);                      //http方式                      presenter.httpPublishMsgToOneNet(AppConstant.Topic.Default_Topic,1,obj.toString());                      //mqtt方式                      // presenter.mqttPublishMsgToOneNet(AppConstant.Topic.Default_Topic,1,obj.toString());                  } catch (JSONException e) {                      e.printStackTrace();                  }              }          });

3.1.3 Presenter層

  • P層同時預留了Http和mqtt的請求方式
public class MainPresenter extends BasePresenter<IMainContract.IMainView> {        private IMainContract.IMainModel mMainModel;        public MainPresenter(){          mMainModel = new MainModel();      }        public void refreshList(Context context){          mView.showLoading("獲取設備列表中...");            mMainModel.loadData(context, new ICallBack<List<OneNetDeviceModel>>() {              @Override              public void onSuccess(final List<OneNetDeviceModel> list) {                  mView.refreshList(list);                  mView.dismissLoading();              }                @Override              public void onFaild(String msg) {                  mView.dismissLoading(new OnDismissCallbackListener(msg, SweetAlertDialog.ERROR_TYPE));              }          });      }        public void updateDeviceDetail(final Context context, OneNetDeviceModel model){          mView.showLoading("更新設備資訊中...");            mMainModel.updateDeviceDetail(context,model, new ICallBack<String>() {              @Override              public void onSuccess(final String result) {                  mView.dismissLoading();                  refreshList(context);              }                @Override              public void onFaild(String msg) {                  mView.dismissLoading(new OnDismissCallbackListener(msg, SweetAlertDialog.ERROR_TYPE));              }          });      }        /**       * 以應用層mqtt協議發布消息       **/      public void mqttPublishMsgToOneNet(String topic,int qos,String payload ){          MqttManager.getInstance().publish(AppConstant.Topic.Default_Topic,qos,payload);      }        /**       * 以應用層http協議發布消息       **/      public void httpPublishMsgToOneNet(String topic,int qos,String payload ){          mMainModel.publishMsgToOneNet(topic,qos,payload);      }  }

4.測試結果