前言
随着经济的不断发展,人们的生活越来越便利,科技是第一发展力,不!懒惰是第一创新力。
噗~,开个窗帘都要电动的了,这生活……
前提条件
- 你得有一个房子
- 你房子得有一个窗户
- 你得有钱买的起电动窗帘
- 以上三个条件可以忽略,下面才是正题
- Node-red 是否安装 下面简称‘小红’
- 485线路是否到位
- 需要一个485转TCP设备
批注:Node-red不会安装的进 Node-red 中文文档自行学习。
注意事项:KT82TV的485控制线是4P的头子 型号:4p4c
功能介绍
这边基本上已经包含正常功能部分了(打开,关闭,暂停,位置反馈)
工作原理
上面一共两个部分组成,一个是去控制电机,一个是接收电机反馈信息。
发送部分: Mqtt - 485处理 - TCP传给电机
接受部分: 电机把信息传到网络上 - 通过switch塞选 - 反馈到Mqtt(HA显示)
代码部分
因为KT82TV用的不是标准Modbus协议,验证部分用了CRC16 所以要自己去计算验证部分。 下面就是CRC16校验函数:
function crc16(buffer) {
var crc = 0xFFFF;
var odd;
for (var i = 0; i < buffer.length; i++) {
crc = crc ^ buffer*;
for (var j = 0; j < 8; j++) {
odd = crc & 0x0001;
crc = crc >> 1;
if (odd) {
crc = crc ^ 0xA001;
}
}
}
return crc;
}
这里是一个Ha配置的yaml文件:
- platform: mqtt
name: "MQTT Cover"
command_topic: "Cover/Set/tLivingRoom/01"
position_topic: "Cover/Position/LivingRoom/01"
set_position_topic: "Cover/Set_position/LivingRoom/01"
payload_open: "OPEN"
payload_close: "CLOSE"
payload_stop: "STOP"
position_open: 100
position_closed: 0
Node-Red 代码
{"id":"c94c14d7.d18938","type":"tab","label":"窗帘控制","disabled":false,"info":""},{"id":"b4b8a118.3a825","type":"tcp out","z":"c94c14d7.d18938","host":"10.0.0.20","port":"8888","beserver":"client","base64":false,"end":true,"name":"","x":690,"y":100,"wires":]},{"id":"53c7fe78.d3935","type":"function","z":"c94c14d7.d18938","name":"CRC16 校验","func":"function crc16(buffer) {\n var crc = 0xFFFF;\n var odd;\n\n for (var i = 0; i < buffer.length; i++) {\n crc = crc ^ buffer*;\n\n for (var j = 0; j < 8; j++) {\n odd = crc & 0x0001;\n crc = crc >> 1;\n if (odd) {\n crc = crc ^ 0xA001;\n }\n }\n }\n\n return crc;\n}\n\ntemp = \"0000\" + crc16(msg.payload).toString(16)\ntemp = temp.substr(-4);\n\nlet temp1 = Buffer.from('0x'+temp.substr(-2))\nlet temp2 = Buffer.from('0x'+temp.substr(0,2))\nlet temp3 = Buffer.from([temp1,temp2])\nmsg.payload = Buffer.concat([msg.payload,temp3])\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":100,"wires":"b4b8a118.3a825"]]},{"id":"6d083393.c91fdc","type":"function","z":"c94c14d7.d18938","name":"控制","func":"let arr1\nlet arr2\nvar mqtt_topic = \n 'FE,FE', 'Cover/Set/LivingRoom/01', 'Cover/Set_position/LivingRoom/01'], //客厅\n '02,01', 'Cover/Set/MasterBedRoom/01', 'Cover/Set_position/MasterBedRoom/01'] //主卧\n];\n\n//循环遍历二维数组\nfor (let topic_info of mqtt_topic) {\n if (topic_info[1].indexOf(msg.topic) != -1 || topic_info[2].indexOf(msg.topic) != -1) {\n arr1 = topic_info[0].split(\",\");\n break;\n }\n}\n\n//判断开 还是关\nif (msg.payload == 'OPEN'){\n arr2 = '01'\n}\nelse if (msg.payload == 'CLOSE'){\n arr2 = '02'\n}\nelse if (msg.payload == 'STOP'){\n arr2 = '03'\n}\nelse {\n arr2 = '04'\n}\n\nif (arr2 == '04'){\n msg.payload = Buffer([0x55,'0x'+arr1[0],'0x'+arr1[1],0x03,'0x'+arr2,'0'+msg.payload])\n}\nelse {\n msg.payload = Buffer([0x55,'0x'+arr1[0],'0x'+arr1[1],0x03,'0x'+arr2])\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":100,"wires":"53c7fe78.d3935"]]},{"id":"1d8b6583.a1732a","type":"mqtt in","z":"c94c14d7.d18938","name":"窗帘开合","topic":"Cover/Set/#","qos":"2","broker":"19cdf3af.7a4e1c","x":120,"y":120,"wires":"6d083393.c91fdc"]]},{"id":"e205359a.f6d258","type":"tcp in","z":"c94c14d7.d18938","name":"","server":"client","host":"10.0.0.20","port":"8888","datamode":"stream","datatype":"buffer","newline":"","topic":"","base64":false,"x":150,"y":180,"wires":"d63f45a8.dfb578"]]},{"id":"dc51335d.27c1c","type":"switch","z":"c94c14d7.d18938","name":"","property":"payload[4]","propertyType":"msg","rules":{"t":"eq","v":"4","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":470,"y":180,"wires":"c64bf968.92ad68"]]},{"id":"d63f45a8.dfb578","type":"switch","z":"c94c14d7.d18938","name":"","property":"msg.payload[0]","propertyType":"msg","rules":{"t":"eq","v":"85","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":330,"y":180,"wires":"dc51335d.27c1c"]]},{"id":"c64bf968.92ad68","type":"function","z":"c94c14d7.d18938","name":"处理","func":"var add\nvar topic\nvar mqtt_topic = \n 'fe,fe', 'Cover/Position/LivingRoom/01'], //客厅\n '02,01', 'Cover/Position/MasterBedRoom/01'], //主卧\n];\n\nadd = msg.payload[1].toString(16) +','+ msg.payload[2].toString(16)\n\n//循环遍历二维数组\nfor (let mqtt_add of mqtt_topic) {\n if (mqtt_add[0] == add) {\n topic = mqtt_add[1];\n break;\n }\n}\nmsg.topic = topic;\nmsg.payload = msg.payload[5];\n\nreturn msg;","outputs":1,"noerr":0,"x":610,"y":180,"wires":"2d37813d.7a382e"]]},{"id":"2d37813d.7a382e","type":"mqtt out","z":"c94c14d7.d18938","name":"定位反馈","topic":"","qos":"0","retain":"","broker":"19cdf3af.7a4e1c","x":760,"y":180,"wires":]},{"id":"e1ea17e2.68b228","type":"mqtt in","z":"c94c14d7.d18938","name":"窗帘定位","topic":"Cover/Set_position/#","qos":"2","broker":"19cdf3af.7a4e1c","x":120,"y":80,"wires":"6d083393.c91fdc"]]},{"id":"19cdf3af.7a4e1c","type":"mqtt-broker","z":"","name":"","broker":"10.0.0.8","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
附件
**KT82TV电机官方说明手册KT82TV电机485协议.pdf (577 KB)