设备管理框架
本章主要介绍如何基于爱智设备管理框架进行设备控制。
概述
爱智应用开发中可以直接使用 EdgerOS 设备管理框架进行设备控制,EdgerOS 支持接入 ZigBee 设备和 SDDC 设备,并通过统一接口进行访问,具体请参考:
- ZigBee 设备控制 IoT Device/ZigBeeDev。
- SDDC 设备控制 IoT Device/SddcDev。
应用示例
爱智提供以下设备控制应用示例,供开发者参考:
功能介绍
导入模块
设备控制需要使用 Device 模块来发现和管理设备,爱智模板中的 app-demo-iotpi 和 app-demo-plug 项目集成了 Device 模块,代码位于 main.js 中。
var Device = require("device");
参考以下 IoT Pi 示例,设置两个变量,用于保存发现的 IoT Pi 设备列表和当前访问的 IoT Pi 设备。
/* IoT Pi device */
var iotpi = undefined;
/* IoT Pi devices */
var iotpis = new Map();
设备发现
参考以下 IoT Pi 示例,爱智应用启动时,初始化获取设备列表。
/* * Get All Iot Pi device */ Device.list(true, function(error, list) { if (list) { list.forEach(function(dev) { Device.info(dev.devid, function(error, info) { if (info && info.report.name === "IoT Pi") { iotpis.set(dev.devid, { devid: dev.devid, alias: dev.alias, report: info.report, }); } }); }); } });
Device.list()
获取设备列表后,Device.info()
将进一步获取设备详细信息,然后根据设备筛选出 IoT Pi 设备对象并保存在 iotpis 数组中。参考以下示例,引入 Socket.IO 与前端实时交互,创建 Socket.IO,用于将新设备或设备离线消息及时通知前端。
/* Socket IO */ var io = require("socket.io")(app, { path: "/iotpi", serveClient: false, pingInterval: 10000, pingTimeout: 5000, cookie: false, });
参考以下示例,在前端 Vue 项目中安装 socket.io-client,vue-socket.io-extended,用于使用 Socket.IO。
npm install socket.io-client@2.3 npm install vue-socket.io-extended
参考以下示例,在 socket 连接时加入 auth 参数作为前端认证令牌。
const socket = SocketIO({ path: "/", query: auth, transports: ["websocket"], });
参考以下示例,当 Socket.IO 前端建立连接时,监听前端获取设备列表的请求。
io.on("connection", function(sockio) { // ... sockio.on("iotpi-list", function(result) { var devs = []; iotpis.forEach(function(iotpi) { devs.push(iotpi); }); result(devs); }); });
使用以下命令,前端发送设备列表请求,获取后端设备列表。
this.$socket.client.emit("iotpi-list", (data) => { this.iotpis = data; // ... });
爱智应用运行过程中,通过 join 事件可以监听新设备加入。
Device.on("join", function(devid, info) { if (info.report.name === "IoT Pi") { var devobj = { devid: devid, alias: info.alias, report: info.report, }; iotpis.set(devid, devobj); io.emit("iotpi-join", devobj); } });
参考以下示例,将新加入设备保存到设备列表 iotpis 中, 同时 socket.io 对象将新设备事件 iotpi-join 通知给所有前端,前端 socket 会通过 iotpi-join 事件来监听后端的推送,如有新加入设备,更新本地设备列表。
this.$socket.$subscribe("iotpi-join", (iotpi) => { // ... this.iotpis.push(iotpi); });
参考以下示例,lost 事件可以监听设备离线,离线的设备通过 Socket.IO 消息 iotpi-lost 通知给所有前端。
Device.on("lost", function(devid) { if (iotpis.has(devid)) { iotpis.delete(devid); if (iotpi && iotpi.devid === devid) { iotpiRemove(); } io.emit("iotpi-lost", devid); } });
参考以下示例,前端 socket 通过 iotpi-lost 事件来监听后端的推送,设备离线将处罚本地设备列表更新。
this.$socket.$subscribe("iotpi-lost", (devid) => { // ... this.iotpis = this.iotpis.filter((iotpi) => { return iotpi.devid !== devid; }); });
创建设备
每个设备有唯一的设备 ID(devid),前端从设备列表中选择某个设备时,通过 REST 接口将设备 ID 发送给后端。参考以下示例,爱智应用后端获取有效 devid 后便可创建设备对象。
app.post("/api/select/:devid", function(req, res) { // ... iotpi = new Device(); iotpi.request(req.params.devid, function(error) { // ... iotpi.send( { query: true }, function(error) { if (error) { console.error("Query IoT Pi error:", error.message); } else { console.log("Query IoT Pi Ok!"); } }, 3 ); }); });
参考以下示例,创建 IoT Pi 设备对象,通过 iotpi.request() 与设备关联成功后,iotpi.send() 将检查设备是否可用。前端会发送切换设备请求,根据后端回复进入设备详情页面。
axios .post(`/api/select/${iotpi.devid}`, {}, { headers: getHeaders() }) .then(() => { this.$router.push({ name: "Details", params: iotpi }); }) .catch((error) => { // ... });
设备控制
参考以下 IoT Pi 示例,前端可以通过 Socket.IO 发送 iotpi 指示灯开关控制命令。
this.$socket.client.emit("iotpi-control", msg);
参考以下示例,在后端监听 iotpi-control 事件。
io.on("connection", function(sockio) { sockio.on("iotpi-control", function(msg) { if (iotpi && iotpi.devid) { console.log("Client send message:", JSON.stringify(msg)); iotpi.send( msg, function(error) { if (error) { console.error("Send message to IoT Pi error:", error.message); } }, 3 ); } else { sockio.emit("iotpi-error", { error: "No device!" }); } }); // ... });
参考以下示例,通过
iotpi.send()
向设备发送开关命令。{"led1": true} // 开led1 {"led1": false} // 关led1 {"led2": true} // 开led2 {"led2": false} // 关led2 {"led3": true} // 开led3 {"led3": false} // 关led3
参考以下示例,IoT Pi 设备对象监控 message 消息可获得 IoT Pi 的 led 开关控制状态变化 ,将结果同步给前端,该事件在 iotpi 对象创建时监听。
iotpi.request(req.params.devid, function(error) { iotpi.on("message", function(msg) { io.emit("iotpi-message", msg); }); });
参考以下示例,前端 socket 监听 message 事件获取后端推送来的设备状态。
this.$socket.$subscribe("iotpi-message", (msg) => { if (typeof msg.led1 !== "undefined") { this.iotpi.led1 = msg.led1; } if (typeof msg.led2 !== "undefined") { this.iotpi.led2 = msg.led2; } if (typeof msg.led3 !== "undefined") { this.iotpi.led3 = msg.led3; } });
iotpi-message 消息:
{"led1": true} // 开led1 {"led1": false} // 关led1 {"led2": true} // 开led2 {"led2": false} // 关led2 {"led3": true} // 开led3 {"led3": false} // 关led3