之前预留了ESS服务,就是为了实现和小程序的对接,事实证明,和大模型说了使用标准的ess对接。一步就直接生成了最终的代码。
账号注册
注册方法很简单,直接打开微信公众平台,打开后点击小程序,会弹到小程序页面,在这个页面中点击前往注册便可执行对应的注册流程。
工具安装
这一步可以直接在注册账号后按照指引安装工具,也可以直接跑微软的Misrosoft Store直接搜索微信开发者工具安装。
工程创建
打开微信开发者工具软件(首次打开需登录,拿注册开发者账号的微信登录即可)后,点击左上角的项目,之后选择新建项目,便会弹出新建项目的弹窗(见下图)

在新建项目界面中,选择好工程的保存路径,选用注册时对应的appid(软件登陆时就已经绑定了,直接选择即可),后端服务选择不使用云服务,模板选择 JS-基础模板,之后点击创建便可生成工程,建好后的工程目录结构如下:
├── app.js ├── app.json ├── app.wxss └── pages └── index ├── index.js ├── index.json ├── index.wxml └── index.wxss
代码修改
这部分我是直接丢给大模型生成的,也就说了这么一句话:我想做这样的微信小程序,基于小程序的JS框架。界面上,有一个选择框和一个确认按钮,选择框可以显示手机搜索到的支持BLE ESS(标准实现,非私有协议)的温湿度计列表,确认按钮则执行连接和断开此设备。连上后,界面中出现两个显示框,一个显示传感器传来的温度信息,一个显示传感器传过来的湿度信息,帮忙实现一下
app.json
配置全局参数
{
"pages": [
"pages/index/index"
],
"window": {
"navigationBarTitleText": "BLE ESS温湿度计",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#007AFF"
},
"requiredBackgroundModes": ["bluetooth"],
"permission": {
"scope.bluetooth": {
"desc": "用于搜索并连接BLE温湿度设备"
}
},
"lazyCodeLoading": "requiredComponents"
}app.js
App({
onLaunch() {
console.log("小程序启动")
}
})app.wxss
用于设置全局样式
page {
background: #f5f5f5;
padding: 10rpx;
}pages/index/index.json
用于配置页面信息,个人理解就是这个子页面的名称
{
"navigationBarTitleText": "ESS温湿度"
}pages/index/index.wxml
界面显示的内容和显示规则
<!-- 设备选择 -->
<view class="card">
<text class="label">选择ESS设备:</text>
<picker bindchange="onDeviceSelect" value="{{selectedIndex}}" range="{{deviceNames}}">
<view class="picker-box">
{{deviceNames[selectedIndex] || '点击搜索设备'}}
</view>
</picker>
</view>
<!-- 按钮 -->
<view class="btn-group">
<button type="primary" bindtap="startSearch" disabled="{{isConnecting}}">搜索BLE设备</button>
<button type="{{connected ? 'warn' : 'primary'}}" bindtap="connectOrDisconnect" disabled="{{!hasSelected}}">
{{connected ? '断开连接' : '连接设备'}}
</button>
</view>
<!-- 温湿度显示(连接成功才显示) -->
<view class="data-card" wx:if="{{connected}}">
<view class="data-item">
<text>温度</text>
<text class="value">{{temperature}} ℃</text>
</view>
<view class="data-item">
<text>湿度</text>
<text class="value">{{humidity}} %RH</text>
</view>
</view>pages/index/index.wxss
说明各控件的样式
.card {
background: white;
border-radius: 16rpx;
padding: 30rpx;
margin: 20rpx;
}
.label {
font-size: 30rpx;
color: #333;
margin-bottom: 20rpx;
display: block;
}
.picker-box {
background: #f2f2f2;
padding: 24rpx;
border-radius: 12rpx;
font-size: 28rpx;
text-align: center;
}
.btn-group {
display: flex;
gap: 20rpx;
margin: 20rpx;
}
button {
flex: 1;
border-radius: 12rpx;
}
.data-card {
background: white;
border-radius: 16rpx;
padding: 40rpx 30rpx;
margin: 30rpx 20rpx;
}
.data-item {
display: flex;
justify-content: space-between;
font-size: 36rpx;
margin: 20rpx 0;
}
.value {
color: #007AFF;
font-weight: bold;
}pages/index/index.js
核心功能实现,具体的搜索设备,数据更新逻辑等都是在这部分实现的
Page({
data: {
devices: [], // 设备列表
deviceNames: [], // 选择框显示名称
selectedIndex: 0, // 选中下标
connected: false, // 是否连接
hasSelected: false, // 是否选了设备
deviceId: '', // 连接的设备ID
temperature: '---', // 温度
humidity: '---', // 湿度
// BLE ESS 标准UUID(官方固定,不用改)
ESS_SERVICE_UUID: '0000181A-0000-1000-8000-00805F9B34FB',
TEMP_CHAR_UUID: '00002A6E-0000-1000-8000-00805F9B34FB',
HUMI_CHAR_UUID: '00002A6F-0000-1000-8000-00805F9B34FB'
},
onLoad() {
this.initBluetooth()
},
// 初始化蓝牙
initBluetooth() {
wx.openBluetoothAdapter({
fail: () => {
wx.showToast({ title: '请开启蓝牙', icon: 'error' })
}
})
},
// 搜索 BLE ESS 设备
startSearch() {
if (this.data.connected) {
wx.showToast({ title: '请先断开', icon: 'none' })
return
}
wx.showToast({ title: '搜索中...', icon: 'loading' })
this.setData({ devices: [], deviceNames: [] })
// 只搜索 ESS 服务
wx.startBluetoothDevicesDiscovery({
services: [this.data.ESS_SERVICE_UUID],
allowDuplicatesKey: false,
success: () => {
wx.onBluetoothDeviceFound((res) => {
const dev = res.devices[0]
if (dev.name && dev.name.trim() !== '') {
this.addDevice(dev)
}
})
// 5秒后自动停止
setTimeout(() => {
wx.stopBluetoothDevicesDiscovery()
wx.showToast({ title: '搜索完成' })
}, 5000)
}
})
},
// 添加设备到列表
addDevice(device) {
const { devices } = this.data
const exist = devices.some(item => item.deviceId === device.deviceId)
if (!exist) {
devices.push(device)
const names = devices.map(d => d.name)
this.setData({ devices, deviceNames: names })
}
},
// 选择设备
onDeviceSelect(e) {
const idx = e.detail.value
this.setData({
selectedIndex: idx,
hasSelected: true
})
},
// 连接 / 断开
connectOrDisconnect() {
const { connected, devices, selectedIndex } = this.data
if (devices.length === 0) return
const device = devices[selectedIndex]
connected ? this.disconnect() : this.connect(device)
},
// 连接设备
connect(device) {
wx.showLoading({ title: '连接中...' })
wx.createBLEConnection({
deviceId: device.deviceId,
success: () => {
this.setData({
connected: true,
deviceId: device.deviceId
})
wx.hideLoading()
wx.showToast({ title: '连接成功' })
this.startListenESS()
},
fail: () => {
wx.hideLoading()
wx.showToast({ title: '连接失败', icon: 'error' })
}
})
},
// 断开连接
disconnect() {
wx.closeBLEConnection({
deviceId: this.data.deviceId,
success: () => {
this.setData({
connected: false,
temperature: '---',
humidity: '---'
})
wx.showToast({ title: '已断开' })
}
})
},
// 订阅标准ESS温湿度
startListenESS() {
const { deviceId, ESS_SERVICE_UUID, TEMP_CHAR_UUID, HUMI_CHAR_UUID } = this.data
// 打开通知
wx.notifyBLECharacteristicValueChange({
deviceId, serviceId: ESS_SERVICE_UUID, characteristicId: TEMP_CHAR_UUID, state: true
})
wx.notifyBLECharacteristicValueChange({
deviceId, serviceId: ESS_SERVICE_UUID, characteristicId: HUMI_CHAR_UUID, state: true
})
// 接收数据
wx.onBLECharacteristicValueChange((res) => {
const buf = new DataView(res.value)
// 温度:int16,单位 0.01℃
if (res.characteristicId === TEMP_CHAR_UUID) {
const temp = buf.getInt16(0, true) / 100
this.setData({ temperature: temp.toFixed(1) })
}
// 湿度:uint16,单位 0.01%RH
if (res.characteristicId === HUMI_CHAR_UUID) {
const humi = buf.getUint16(0, true) / 100
this.setData({ humidity: humi.toFixed(1) })
}
})
}
})最终效果

点击界面顶部的真机调试,编译后会二维码,此时用注册的微信扫描二维码

最后
如果要把这部分代码直接公开使用,其实就是按照开发者指南的方法把APPID更换成正式的appid,之后点击界面右侧的上传即可进行后续操作。不过发布小程序涉及的内容还挺多,主要是一些法规之类的东东,因此暂时就不去折腾他了,等后续真正有需求时再去研究个人发布应用需要怎么操作。
我要赚赏金
