485之电动窗帘电机(KT82TV) by 小鬼

前言

随着经济的不断发展,人们的生活越来越便利,科技是第一发展力,不!懒惰是第一创新力。
噗~,开个窗帘都要电动的了,这生活……

前提条件

  1. 你得有一个房子
  2. 你房子得有一个窗户
  3. 你得有钱买的起电动窗帘
  4. 以上三个条件可以忽略,下面才是正题
  5. Node-red 是否安装 下面简称‘小红’
  6. 485线路是否到位
  7. 需要一个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)

2 个赞

鬼总v5~
期待鬼总485系列教程:lol

来膜拜下鬼总。

来膜拜下鬼总。

来膜拜下鬼总。能否让我的 485 电机焕发青春

鬼总485

鬼总 666666

666666:lol

鬼总 485再来点

分享添加不上 能否再次分享下你的流?

您的流不能正常部署哦

摸你pp,2333, 你也是485 的?

你的流能否再分享下 前期分享的流不正常,不能正常使用

你的流能否再分享下 前期分享的流不正常,不能正常使用

鬼总,威武啊,,,,666

代码有附件吗?? 复制的不能用了

鬼总,您能重新发一个node-red例子流程吗? 上面导入,提示: Error: 输入的不是JSON数组

你的 电机搞定了吗

NR 流 没法使用 可以重新分享下吗 谢谢

我现在家里就是买的杜亚KT82TV的电机,您的NR流可以分享一下么?