uniapp 开发移动端对接巴法云物联网平台控制ESP8266开关灯

巴法云物联网平台的MQTT接入只有说明文档,没有移动端实例。经过多次连接测试,使用uniapp开发的移动端终于成功连接服务器。

uniapp 开发移动端对接巴法云物联网平台控制ESP8266开关灯_第1张图片

uniapp 开发移动端对接巴法云物联网平台控制ESP8266开关灯_第2张图片
手机端效果图
uniapp 开发移动端对接巴法云物联网平台控制ESP8266开关灯_第3张图片
uniapp 代码(app, 小程序):

<template>
	<view class="content">
		<!-- <image class="logo" src="/static/logo.png" ></image> -->
		<image class="logo" :src="state=='on' ? imgurlon : imgurloff"></image>
		<view class="text-area">
			<view class="title">{{title}}</view>
		</view>
		<view class="btn">
			<button type="default" @click="btnon()"></button>
			<button type="default" @click="btnoff()"></button>
		</view>

	</view>
</template>

<script>
	// mqtt库下载地址 https://unpkg.com/[email protected]/dist/mqtt.min.js
	var mqtt = require('../../mqtt.min.js')  //引入mqtt库	
    var ntime = 0  //计时初始值
	
	export default {
		data() {
			return {
				title: '网络连接中...',							
				state:'off',  //图标状态
				imgurloff:'/static/off.png',
				imgurlon:'/static/on.png',
				timer: null,
				client: null,				
				// mqtt协议在app端和小程序端必须用【 wx:// 或者 wxs:// 】
				// 开发文档见 https://cloud.bemfa.com/docs/#/?id=_43-mqtt%e8%ae%be%e5%a4%87%e4%ba%91				
				url: 'wxs://bemfa.com:9504/wss',								
				options: {
					clientId: '88888888888888888888888',  //巴法云平台用户私钥
					keepalive: 60, //心跳时间
				}
			}
		},
		
		onLoad() {						
			this.mqttconnect()			        
		},
		
		onShow() {
			// esp8266每10秒发布一次消息,ntime清零一次,如果20秒后变量ntime还没有清零,判断设备离线了			
			//建立定时器10秒运行一次
			this.timer = setInterval( () => {				
				ntime = ntime + 10
				if(ntime >= 20 ){
					this.title = '设备离线,请检查! '
					this.state = 'off'
				}				
			}, 1000*10)	
		},
		
		onHide() {
			// 清除定时器			
			if(this.timer) {  
				clearInterval(this.timer);  
				this.timer = null;  
			} 
		},
		
		
		methods: {
			mqttconnect() {
				this.client = mqtt.connect(this.url,this.options)
				
				//连接服务器
				this.client.on('connect', () => {
					this.title = '服务器连接成功!'
					// 订阅主题
					this.client.subscribe('light002',{qos: 1}, (err) => {
						console.log(err || '订阅主题成功')
					})
				})
				
				//收取消息
				this.client.on('message', (topic, message) => {
					let msg = message.toString()
					this.title = '设备在线'					
					this.state = msg
					ntime = 0
					console.log('收到来自'+ topic + '的消息:' + msg)					
				})	
			},

			btnon() {
				//发布开灯指令
				this.client.publish('light002', 'on',{
						qos: 1,  	   //至少传输一次
						retain: true  //保留消息,当订阅主题时发布最后那条消息(在此程序的作用是打开app就知道是关灯还是开灯状态)
					},(err) => {
						console.log(err || '发送信息成功')
					}
				)					
			},

			btnoff() {
				//发布关灯指令
				this.client.publish('light002', 'off',{
						qos: 1,			//至少传输一次
						retain: true 	//保留消息,当订阅主题时发布最后那条消息(在此程序的作用是打开app就知道是关灯还是开灯状态)
					},(err) => {
						console.log(err || '发送信息成功')
					}
				)					
			}

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
	.btn{
		display: flex;
		flex-direction: row;
		margin: 20rpx;
	}
	button{
		margin: 20rpx;
		border-radius: 5rpx;
		color: #0055ff;
		background-color: #909090;
	}
</style>


uniapp 代码(H5):
由于使用H5方式存在跨域问题,需要修改部分代码。

<template>
	<view class="content">
		<image class="logo" @click="btnclose()" src="/static/logo.png"></image>
		<view class="text-area">
			<text class="title">{{title}}</text>
		</view>
		<button type="default" @click="btnopen()">打开</button>
		<button type="default" @click="btnclose()">关闭</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: '远程开关灯',
				uid: '888888888888', //巴法云平台用户私钥
				topic: "light002",
				device_status: "离线", //默认离线
				powerstatus: "已关闭" //默认关闭
			}
		},
		
		onLoad() {
			this.getmsg()			
			setInterval(()=> { //定时器
				this.getmsg()
			},30000)			
		},
		
		methods: {
			btnclose() {
				var that = this				
				uni.request({
					url: '/dev', //调用manifest.json文件中的 H5 代理接口
					method: "POST",
					data: { //请求字段,详见巴法云接入文档,http接口
						uid: that.uid,
						topic: that.topic,
						msg: "off" //发送消息为off的消息
					},
					header: {
						'content-type': "application/x-www-form-urlencoded"
					},
					success(res) {
						console.log(res.data)
						uni.showToast({
							title: '关闭成功',
							icon: 'success',
							duration: 1000
						})
					}
				})
			},

			btnopen() {
				var that = this				
				uni.request({
					//url: 'https://api.bemfa.com/api/device/v1/data/1/', //api接口,详见接入文档
					url: '/dev', //调用maifest.json文件中的 H5 代理接口
					method: "POST",
					data: { //请求字段,详见巴法云接入文档,http接口
						uid: that.uid,
						topic: that.topic,
						msg: "on" //发送消息为off的消息
					},
					header: {
						'content-type': "application/x-www-form-urlencoded"
					},
					success(res) {
						console.log(res.data)
						uni.showToast({
							title: '打开成功',
							icon: 'success',
							duration: 1000
						})
					}
				})
			},

			getmsg() {
				var that = this				
				uni.request({
					//url: 'https://api.bemfa.com/api/device/v1/data/1/', //api接口,详见接入文档
					url: '/dev', //调用maifest.json文件中的 H5 代理接口
					method: "GET",
					data: { //请求字段,详见巴法云接入文档,http接口
						uid: that.uid,
						topic: 'wendu' //订阅主题				
					},
					header: {
						'content-type': "application/x-www-form-urlencoded"
					},
					success(res) {
						console.log(res.data)
						that.title = res.data.msg
					}
				})
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}

	button {
		margin: 20rpx;
	}
</style>

manifest.json 在H5选项内添加代理,解决跨域问题
uniapp 开发移动端对接巴法云物联网平台控制ESP8266开关灯_第4张图片

ESP8266 模块代码

在官方代码的基础上加入了自动配网,当wifi环境改变后,可以使用手机连接esp8266热点进行网络配置。
详见官方文档:https://cloud.bemfa.com/docs/#/?id=_151-%e6%8e%a7%e5%88%b6led%e7%81%af

/*
* 智能语言控制控制,支持同时天猫、小爱、小度、google Assistent控制
* 也同时支持web控制、小程序控制、app控制,定时控制等
* QQ群:566565915
* 项目示例:通过发送on或off控制开关
* 官网:bemfa.com
*/

#include <ESP8266WiFi.h>               //默认,加载WIFI头文件
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <Ticker.h> 
//#include 
#include "PubSubClient.h"              //默认,加载MQTT库文件         

WiFiClient espClient;  //wifi客户端模式
PubSubClient client(espClient);
Ticker ticker;  //定时器对象

//********************需要修改的部分*******************//
#define ID_MQTT  "888888888888888888888888"     //用户私钥,控制台获取
const char*  topic = "light002";        //主题名字,可在巴法云控制台自行创建,名称随意
const int B_led = D1;       //单片机LED引脚值,D系列是NodeMcu引脚命名方式,其他esp8266型号将D2改为自己的引脚
//**************************************************//

const char* mqtt_server = "bemfa.com"; //默认,MQTT服务器
const int mqtt_server_port = 9501;      //默认,MQTT服务器端口
int count;    // Ticker计数用的变量


//灯光函数及引脚定义
void turnOnLed();
void turnOffLed();

//计数
void tickerCount(){
  count++;
}

// 连接MQTT服务器
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(ID_MQTT)) {
      Serial.println("connected");
      Serial.print("subscribe:");
      Serial.println(topic);
      //订阅主题,如果需要订阅多个主题,可发送多条订阅指令client.subscribe(topic2);client.subscribe(topic3);
      client.subscribe(topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Topic:");
  Serial.println(topic);
  String msg = "";
  for (int i = 0; i < length; i++) {
    msg += (char)payload[i];
  }
  Serial.print("Msg:");
  Serial.println(msg);
  if (msg == "on") {//如果接收字符on,亮灯
    turnOnLed();//开灯函数
  } else if (msg == "off") {//如果接收字符off,关灯
    turnOffLed();//关灯函数
  }
  msg = "";  
}

//打开灯泡
void turnOnLed() {
  Serial.println("turn on light");
  digitalWrite(B_led, HIGH);
}

//关闭灯泡
void turnOffLed() {
  Serial.println("turn off light");
  digitalWrite(B_led, LOW);
}

// 发布信息
void pubMQTTmsg(){   
    // 建立发布主题
    //巴法云个性设置,推送消息时:主题名后加/set推送消息,表示向所有订阅这个主题的设备们推送消息,
    //假如推送者自己也订阅了这个主题,消息不会被推送给它自己,以防止自己推送的消息被自己接收。
    String topicString = "light002/set" ;
    char publishTopic[topicString.length() + 1];  //转换成字符数组
    strcpy(publishTopic, topicString.c_str());
   
    // 建立发布信息,当前D1引脚状态
    String messageString;
    if(digitalRead(B_led)){
      messageString = "on"; 
    } else {
      messageString = "off"; 
    }       
    char publishMsg[messageString.length() + 1];   //转换成字符数组
    strcpy(publishMsg, messageString.c_str());
    
    // 实现ESP8266向主题发布信息,并在串口监视器显示出来
    if(client.publish(publishTopic, publishMsg)){
      Serial.println("Publish Topic:");
      Serial.println(publishTopic);
      Serial.println("Publish message:");
      Serial.println(publishMsg);    
    } else {
      Serial.println("Message Publish Failed."); 
    }
}

//程序入口
void setup() {
  pinMode(B_led, OUTPUT); //设置引脚为输出模式
  digitalWrite(B_led, LOW);//默认引脚上电低电平
  Serial.begin(9600);     //设置波特率9600
  
  //********************自动配置网络************************  
  // 建立WiFiManager对象
  WiFiManager wifiManager;  
  // 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称
  wifiManager.autoConnect("AutoConnectAP");  
  // 如果您希望该WiFi添加密码,可以使用以下语句:
  // wifiManager.autoConnect("AutoConnectAP", "12345678"); 
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println(""); 
  Serial.print("ESP8266 Connected to ");
  Serial.println(WiFi.SSID());              // WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // IP
  //*******************************************************  
    
  client.setServer(mqtt_server, mqtt_server_port);//设置mqtt服务器
  client.setCallback(receiveCallback); //mqtt消息处理  
    
  ticker.attach(1, tickerCount); // Ticker定时对象
  
}

//循环执行 
void loop() {
  if (!client.connected()) {
    reconnect();
  }else{
    client.loop();    // 保持心跳
    if (count >= 10){ // 每隔10秒钟发布一次信息
        pubMQTTmsg();
        count = 0;
    }
  } 
}

你可能感兴趣的:(物联网,物联网)