一个安卓端app,接收服务器发送的upd控制指令,连接meizu蓝牙红外遥控器,并将反馈的数据通过udp反馈给服务器进行处理。
代码基于FastBLE,增加了udp数据通信功能。
目前基本实现了电池电压、温湿度数据采集和红外发射功能。
软件默认参数:远端udp服务器ip地址:192.168.2.33;服务器监听udp端口号:8086;本机监听udp端口号:8087。参数按实际情况修改。
读电压、温湿度数据udp包数据格式:meizu蓝牙地址+空格+读指令;返回udp数据包格式:meizu蓝牙地址+空格+返回数据;
电压读指令:55030110(16进制);返回数据:55040110xx(16进制)
温湿度读指令:55030111(16进制);返回数据:55070111xxxxxxxx(16进制)
红外发射udp包数据格式:meizu蓝牙地址+空格+写指令;返回udp数据包格式:meizu蓝牙地址+空格+返回数据;
红外指令格式:550c0103xxxxxxxxxxxxxxxxxx(16进制),xxxxxxxxxxxxxx码通过log文件获取;发送成功返回数据:5504010401;不成功返回数据:5504010400
udp指令发送和反馈数据处理可以在node-red中进行处理。
node-red自己用的流以供参考,修改对应的蓝牙地址、udp参数和红外指令:
```
[{"id":"b99b4dee.8f112","type":"udp in","z":"243cad66.6177f2","name":"","iface":"","port":"8086","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":168.16668701171875,"y":1032.3333282470703,"wires":[["9601eff4.0f533","81b72316.b6fff"]]},{"id":"9601eff4.0f533","type":"debug","z":"243cad66.6177f2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":360.16668701171875,"y":967.3333129882812,"wires":[]},{"id":"cde9fc0c.30793","type":"udp out","z":"243cad66.6177f2","name":"","addr":"192.168.2.33","iface":"","port":"8087","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":1115.1666870117188,"y":751.0000610351562,"wires":[]},{"id":"ece113dc.a3fe8","type":"inject","z":"243cad66.6177f2","name":"","topic":"","payload":"","payloadType":"date","repeat":"1800","crontab":"","once":false,"onceDelay":0.1,"x":188.16668701171875,"y":753.3333129882812,"wires":[["1fcba07c.f327"]]},{"id":"81b72316.b6fff","type":"function","z":"243cad66.6177f2","name":"处理meizu反馈数据","func":"var msg1 ={topic:\"\", payload:\"\" };\nvar msg2 ={topic:\"\", payload:\"\" };\nnode.status({fill:\"green\",shape:\"dot\",text:\"Received \"+msg.payload});\n\n\n//获取mac\nvar temp = new Buffer(17);\nfor(var i=0;i<17;i++)\n temp[i] = msg.payload[i];\n\nvar mqttTopic = \"home/meizuIR/\"+temp.toString()+\"/\";\n//获取cmd\nvar tmp1 = msg.payload[21];\n//获取电压\nif(tmp1===0x10)\n{\n var tmpU = msg.payload[22]/10; \n mqttTopic = mqttTopic + \"curU\";\n msg.topic = mqttTopic;\n msg.payload = tmpU;\n return [msg,null,null,null];\n}\n//获取温湿度\nif(tmp1===0x11)\n{\n var tmpT = (msg.payload[23]*256+msg.payload[22])/100; \n var tmpD = (msg.payload[25]*256+msg.payload[24])/100; \n msg1.topic = mqttTopic + \"curT\";\n msg2.topic = mqttTopic + \"curD\"; \n msg1.payload = tmpT;\n msg2.payload = tmpD;\n return [null,msg1,msg2,null];\n}\n//获取红外发射反馈\nif(tmp1===0x04)\n{\n var cmd_isIR = flow.get(\"cmd_isIR\")||false;\n var cmd_mac = flow.get(\"cmd_mac\");\n var cmd_macFlag = flow.get(\"cmd_macFlag\");\n var cmd_typeFlag = flow.get(\"cmd_typeFlag\");\n var cmd_cmdFlag = flow.get(\"cmd_cmdFlag\");\n var cmd_cmdSta = flow.get(\"cmd_cmdSta\");\n var tmpS = msg.payload[22];\n if(cmd_isIR && (cmd_mac == temp.toString()))\n {\n if(tmpS === 0X01)\n {\n msg.topic = \"home/meizuIR/state/\" + cmd_macFlag +\"/\"+ cmd_typeFlag +\"/\"+cmd_cmdFlag;\n msg.payload = cmd_cmdSta;\n return [null,null,null,msg];\n }\n else\n {\n msg.payload = \"err\";\n return [null,null,null,msg];\n }\n\n }\n else\n {\n if(tmpS === 0X01)\n {\n tmpS = \"ok\";\n }\n else\n {\n tmpS = \"err\";\n }\n msg.topic = mqttTopic + \"curS\";\n msg.payload = tmpS;\n return [null,null,null,msg];\n }\n}\n","outputs":4,"noerr":0,"x":409,"y":1032.6666870117188,"wires":[["be21a3b0.f8988","e728e8a0.a81b48"],["e728e8a0.a81b48","be21a3b0.f8988"],["e728e8a0.a81b48","be21a3b0.f8988"],["8d7b5054.ef80f","be21a3b0.f8988"]]},{"id":"1fcba07c.f327","type":"function","z":"243cad66.6177f2","name":"生成查询meizu电压温湿度指令","func":"var count = context.get('count')||0;\n//传感器读取指令\nvar cmd = [new Buffer([0x55,0x03,0x01,0x10]),new Buffer([0x55,0x03,0x01,0x11])];\n//meizu红外模块放置位置\nvar macFlag = [\"keting\",\"ertongfang\"];\n//meizu红外模块蓝牙地址\nvar mac = [\"68:3E:34:CC:DB:97\",\"68:3E:34:CC:DB:98\"];\nvar sendStr = \"\";\n\nfor(var i= 0; i<mac.length;i++)\n{\n for(var j= 0; j<cmd.length;j++)\n {\n sendStr = mac[i] + \" \" + cmd[j];\n flow.set(\"cmd_isIR\",false);\n node.send({payload : sendStr});\n }\n}\n//msg.payload = \"68:3E:34:CC:DB:97 \"+cmd;\n//count++;\n//context.set('count',count);\n//msg.payload = count;\n//node.status({fill:\"green\",shape:\"dot\",text:\"Received \"+msg.payload});\nreturn null;","outputs":1,"noerr":0,"x":412,"y":753.3333129882812,"wires":[["269c9e0d.c522f2"]]},{"id":"be21a3b0.f8988","type":"debug","z":"243cad66.6177f2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":691.0000152587891,"y":984.333381652832,"wires":[]},{"id":"8d7b5054.ef80f","type":"mqtt out","z":"243cad66.6177f2","name":"","topic":"","qos":"0","retain":"true","broker":"38278676.7e196a","x":852.1666870117188,"y":1049.333251953125,"wires":[]},{"id":"269c9e0d.c522f2","type":"delay","z":"243cad66.6177f2","name":"","pauseType":"rate","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"10","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":684.375,"y":754.1328125,"wires":[["77daa76.ec76558"]]},{"id":"77daa76.ec76558","type":"function","z":"243cad66.6177f2","name":"延时发送指令","func":"node.status({fill:\"green\",shape:\"dot\",text:\"Received \"+msg.payload});\nreturn msg;","outputs":1,"noerr":0,"x":889.765625,"y":752.75,"wires":[["f0787e63.e2f6d","cde9fc0c.30793"]]},{"id":"f0787e63.e2f6d","type":"debug","z":"243cad66.6177f2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":792.765625,"y":883.75,"wires":[]},{"id":"2ad4ce98.b1b9d2","type":"comment","z":"243cad66.6177f2","name":"meizu红外模块传感器读取","info":"","x":226.765625,"y":686.75,"wires":[]},{"id":"e728e8a0.a81b48","type":"delay","z":"243cad66.6177f2","name":"","pauseType":"rate","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":680.765625,"y":1024.75,"wires":[["8d7b5054.ef80f"]]},{"id":"51a26e48.7fb52","type":"inject","z":"243cad66.6177f2","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":177.3333282470703,"y":1251.666748046875,"wires":[["86d94a44.b1c028"]]},{"id":"4694ba2b.26ef64","type":"function","z":"243cad66.6177f2","name":"生成红外控制指令","func":"//meizu红外模块放置位置\nvar macFlag = [\"keting\",\"ertongfang\"];\n//meizu红外模块蓝牙地址\nvar mac = [new Buffer(\"68:3E:34:CC:DB:97\"),new Buffer(\"68:3E:34:CC:DB:98\")];\n//风扇类设备红外码名称\nvar fanCmdFlag = [\"power\",\"round\",\"speed\",\"type\"];\n//风扇类设备红外码编码\nvar fanCmd = [new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0X37,0X7C,0XA3,0XC1,0X37,0X10]),new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0X3F,0X18,0XD3,0X2B,0X37,0X10]),new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0X56,0XF7,0X32,0X73,0X37,0X10]),new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0XF2,0X49,0X68,0X6F,0X37,0X10])];\n//空调类设备红外码名称\nvar airCmdFlag = [\"power\",\"cool\",\"hot\",\"temp\",\"speed\"];\n//空调类设备红外码编码\nvar airCmd = [new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0X37,0X7C,0XA3,0XC1,0X37,0X10]),new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0X3F,0X18,0XD3,0X2B,0X37,0X10]),new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0X56,0XF7,0X32,0X73,0X37,0X10]),new Buffer([0x55,0x0C,0X01,0X03,0X65,0X00,0X1C,0XF2,0X49,0X68,0X6F,0X37,0X10])];\n//设备类型\nvar typeFlag = [\"fan\",\"air\"];\n//红外码三维数组\nvar cmdFlag = [fanCmdFlag,airCmdFlag];\nvar cmd = [fanCmd,airCmd];\n//命令对应模块编号\nvar macID=0;\n//命令对应设备类型编号\nvar typeFlagID=0;\n//命令对应设备对应操作编号\nvar cmdFlagID=0;\n//解析mqtt数据\nvar topicStr = msg.topic.split('/');\nfor(var i = 0; i< macFlag.length;i++)\n{\n if(topicStr[3]==macFlag[i])\n {\n macID=i;\n break;\n }\n}\nfor( i = 0; i< typeFlag.length;i++)\n{\n if(topicStr[4]==typeFlag[i])\n {\n typeFlagID=i;\n break;\n }\n}\nfor( i = 0; i< cmdFlag[typeFlagID].length;i++)\n{\n if(topicStr[5]==cmdFlag[typeFlagID][i])\n {\n cmdFlagID=i;\n break;\n }\n}\nflow.set(\"cmd_mac\",mac[macID].toString());\nflow.set(\"cmd_macFlag\",macFlag[macID]);\nflow.set(\"cmd_typeFlag\",typeFlag[typeFlagID]);\nflow.set(\"cmd_cmdFlag\",cmdFlag[typeFlagID][cmdFlagID]);\nflow.set(\"cmd_cmdSta\",msg.payload);\nflow.set(\"cmd_isIR\",true);\n//生成发送操作指令码\nvar sendStr = new Buffer(mac[macID].length + cmd[typeFlagID][cmdFlagID].length+1);\nfor(i= 0; i<mac[macID].length;i++)\n{\n sendStr[i] = mac[macID][i];\n}\nsendStr[18] = 0x20;\nfor( i= 0; i<cmd[typeFlagID][cmdFlagID].length;i++)\n{\n sendStr[i+18] = cmd[typeFlagID][cmdFlagID][i];\n}\nmsg.payload = sendStr;\nreturn msg;","outputs":1,"noerr":0,"x":530.1666259765625,"y":1249.6668701171875,"wires":[["472a18a0.f26468","2da373d7.b0a2fc"]]},{"id":"472a18a0.f26468","type":"udp out","z":"243cad66.6177f2","name":"","addr":"192.168.2.33","iface":"","port":"8087","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":792.3333358764648,"y":1249.3333740234375,"wires":[]},{"id":"2da373d7.b0a2fc","type":"debug","z":"243cad66.6177f2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":694.5000114440918,"y":1190.6666927337646,"wires":[]},{"id":"be73050.06b04f8","type":"mqtt in","z":"243cad66.6177f2","name":"","topic":"home/meizuIR/sent/#","qos":"1","datatype":"auto","broker":"38278676.7e196a","x":219.16667938232422,"y":1199.6667881011963,"wires":[["4694ba2b.26ef64","7c2807a7.3097d8"]]},{"id":"7c2807a7.3097d8","type":"debug","z":"243cad66.6177f2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":478.1666793823242,"y":1174.6666927337646,"wires":[]},{"id":"86d94a44.b1c028","type":"function","z":"243cad66.6177f2","name":"模拟指令","func":"msg.topic = \"home/meizuIR/sent/keting/fan/power\";\nmsg.payload = \"true\";\nnode.status({fill:\"green\",shape:\"dot\",text:\"Received \"+msg.payload});\nreturn msg;","outputs":1,"noerr":0,"x":318.0000190734863,"y":1249.3334159851074,"wires":[["4694ba2b.26ef64","7c2807a7.3097d8"]]},{"id":"fc50db57.6b9028","type":"comment","z":"243cad66.6177f2","name":"meizu红外模块发送控制指令","info":"","x":232.765625,"y":1141.75,"wires":[]},{"id":"38278676.7e196a","type":"mqtt-broker","z":"","name":"","broker":"192.168.2.33","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
```
jstormx / ble2udp Goto Github PK
View Code? Open in Web Editor NEWBLE蓝牙数据读取转UDP发送
License: Apache License 2.0