玩轉OneNET物聯網平臺之HTTP服務③ —— OneNet智慧燈 HTTP版本
阿新 • • 發佈:2019-10-30
授人以魚不如授人以漁,目的不是為了教會你具體專案開發,而是學會學習的能力。希望大家分享給你周邊需要的朋友或者同學,說不定大神成長之路有博哥的奠基石。。。
QQ技術互動交流群:ESP8266&32 物聯網開發 群號622368884,不喜勿噴
一、你如果想學基於Arduino的ESP8266開發技術
一、基礎篇
- ESP8266開發之旅 基礎篇① 走進ESP8266的世界
- ESP8266開發之旅 基礎篇② 如何安裝ESP8266的Arduino開發環境
- ESP8266開發之旅 基礎篇③ ESP8266與Arduino的開發說明
- ESP8266開發之旅 基礎篇④ ESP8266與EEPROM
- ESP8266開發之旅 基礎篇⑤ ESP8266 SPI通訊和I2C通訊
- ESP8266開發之旅 基礎篇⑥ Ticker——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韌體更新
三、應用篇
- ESP8266開發之旅 應用篇① 區域網應用 ——炫酷RGB彩燈
- ESP8266開發之旅 應用篇② OLED顯示天氣屏
- ESP8266開發之旅 應用篇③ 簡易版WiFi小車
四、高階篇
- ESP8266開發之旅 進階篇① 程式碼優化 —— ESP8266記憶體管理
- ESP8266開發之旅 進階篇② 閒聊Arduino IDE For ESP8266配置
- ESP8266開發之旅 進階篇③ 閒聊 ESP8266 Flash
- ESP8266開發之旅 進階篇④ 常見問題 —— 解決困擾
- ESP8266開發之旅 進階篇⑤ 程式碼規範 —— 像寫文章一樣優美
- 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.測試結果
- 整體的測試結果跟 博文 玩轉OneNET物聯網平臺之MQTT服務④ —— 遠端控制LED(數量無限制)+ Android App控制 一直,這裡就不重複了。博主貼上App傳送Http請求的日誌內容:
5.總結
本篇乾貨不多,只是以另一種方式去實現mqtt的操作,可供參考。