当前位置: 首页 > 后端技术 > Node.js

从零开始DIY智能浇花APP

时间:2023-04-03 10:50:04 Node.js

前言作为新世纪的农民工,平时会种些花草,为自己的房间增添一些绿色和生机,但也常常因为工作忙而忘记一些东西。毕竟我大部分时间都是对着电脑的(郑重声明:我不是单身狗!!!(???)?),之前在淘宝上买了土壤湿度传感器和浇水设备,自己改装自己一段时间后,通过WiFi和SDDC成功连接到爱智盒子,现在准备搭建一个爱智应用来控制设备;来看看我为场景演示改装的成品ヾ(????)?",直接放在我房间的展示柜上就可以开始使用了。这就是洒水器!这是插入土壤水分传感器的屁股!(σ???)σ..:*☆哦,是不是很神奇!这个在花盆里,我插入了之前的土壤水分传感器和浇水器的出水口,然后我把饮水器的进水口装在一个装满水的瓶子里,这样一个自动浇水的东西就完成了。因为这是我自己室内用的小设备,规模比较小,有想法的兄弟可以拓展一下并在农业灌溉中尝试一下,想想就有点小激动ヾ(>?<)(ノ?`)?应用demo不多说了─=≡Σ(((つ??ω??)つ,先看看我的应用页面是什么样子的,我一如既往的放了一个数据显示面板和一个设备选择模块。一个设备参数设置模块。使用起来也很简单,直接选择土壤水分传感器和浇水设备,拖动两个光标,设置浇水适宜范围。每当我的花盆里的土壤湿度低于60%的时候,它就会通过Spirit向浇水机发出浇水信号,开始加水。当湿度达到85%时,停止浇水。这样一个智能的浇水场景就完成了。整体实现逻辑比较简单,后面也会做。逐步在网上购买一些其他设备,搭建一些比较完善的智能场景。关于代码实现的代码分析也是使用了前面的device模块device。我认为没有必要炫耀前端。这是一个相对简单的页面。没什么好说的,直接贴出后端js部分的关键代码<( ̄¢ ̄)@m.//因为使用频率比较高,又比较懒,所以基于正常的逻辑,基本上可以满足我现在和以后的大部分需求,其他的个性化需求再扩展。//device_manager.jsconstDevice=require('device');constEventEmitter=require('events');classDeviceManagerextendsEventEmitter{constructor(){super();this.devMap=newMap();this.controllerMap=newMap();这个。初始化();}init(){//获取当前所有已接入网络的在线设备!Device.list(true,(error,list)=>{if(error){console.error('Device.listerror!'+error);}else{list.forEach((item)=>{Device.info(item.devid,(error,info)=>{if(error){console.error('Device.infoerror!'+error);}else{this.devMap.set(item.devid,{devid:item.devid,别名:info.alias,report:info.report});}});});}});Device.on('join',async(devid,info)=>{constdev={devid,...info};this.devMap.set(devid,dev);this.emit('join',dev);});Device.on('lost',(devid)=>{constdev=this.devMap.get(devid);this.devMap.delete(devid);if(this.controllerMap.has(devid)){this.controllerMap.delete(devid);}if(!dev){this.emit('error','应用程序发生未知错误,请退出并重试!');}else{this.emit('lost',开发);}});}//构建设备控制对象generateController(devid){if(this.controllerMap.has(devid)){returnPromise.resolve(this.controllerMap.get(devid))}constcontroller=newDevice();returnnewPromise((resolve,reject)=>{controller.request(devid,(error)=>{if(error){reject(error);}else{this.controllerMap.set(devid,controller);resolve(controller);}});})}//删除控制器deleteController(devid){this.controllerMap.delete(devid);}//发送设备消息sendDeviceInfo(devid,data){constcontroller=this.controllerMap.get(devid);如果(!controller){returnPromise.reject('程序出现未知错误,请退出并重试!')}returnnewPromise((resolve,reject)=>{controller.send(data,(err)=>{if(err){reject('控制设备失败,请重试!')}else{resolve();}},3)})}}constdevManager=newDeviceManager();module.exports={devManager}上面封装了设备管理模块,在main.js中会用到该模块中的相关方法;//main.js...functiongenerateDevController(devid){returnnewPromise((resolve,reject)=>{constdev=devManager.devMap.get(devid);devManager.generateController(devid).then((controller)=>{controller.on('message',(data)=>{constpoints=humidity_water_scene.settings.points;if(isSceneDev(devid)&&getDeviceType(dev)==='humidity'){socketIO.emit('湿度',Number(data.data.soil_humidity.toFixed(1)));//0-100if(!waterDev){返回;}if(data.data.soil_humidity=points[0]&&watering){stopWater();//停止浇水}}elseif(getDeviceType(dev)==='water'){if(data.data.watering==='ON'&&watering&&t===0&&humidityDev){setHumidityTimer(1000);}elseif(data.data.watering==='OFF'&&!watering&&t){clearInterval(t);t=0}}});解决(控制器);}).catch(()=>{reject(`应用程序缺少控制${dev.alias}的权限!`);})})}...以上代码调用封装设备管理的generateController方法模块实例构造设备控制对象,可以在设备消息监控事件消息中看到湿度感应如果设备返回的数据值小于我们指定的值,就会调用startWater方法浇水,否则停止浇水;同理,浇水器会根据控制浇水开关指令返回当前设备状态,如果浇水器在运行过程中,会主动加速采集湿度传感器的实时值,便于对设备进行实时控制。整体实现没有太大问题。可能有些细节需要优化,但是已经开始用了,当然肯定不会直接连上。给水龙头,不然要是程序有BUG,价格就有点高了(uTェTu)!今天的分享到此结束。具体详细代码可以去灵感桌面的秘密宝库查看。