『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 16845|回复: 14

[经验分享] 用小米万能遥控精细控制格力空调【node-red】【IR Remote】

[复制链接]

3

主题

40

帖子

378

积分

论坛分享达人

积分
378
金钱
338
HASS币
0
发表于 2019-2-1 23:57:56 | 显示全部楼层 |阅读模式

小米万能遥控在HA上控制空调就是个坑,不知道空调伴侣是否也是这样,借用坛友cnk700i的话:
1.HA的组件是没有完整的红外码库的,不要想着用了插件就能自动匹配、控制你的空调!!!
2.空调遥控器的红外码大多是组合码,即一段红外码中包含温度、风量、上下风、模式等多种信息,这种情况下学到的红外码是没法单独控制某一个功能,除非破译红外码规则后再根据需要组合控制信息。所以红外控制还是更适合用来控制灯具、电视、电扇之类简单控制逻辑的家电。

其实,难点就在于红外码的组合方式上,好在有现成的格式说明了:https://blog.csdn.net/yannanxiu/article/details/48174649
起始码(S)+35位数据码+连接码(C)+32位数据码 + 结束码
gree.jpg
官方小米遥控插件能接受2种命令格式,raw和pronto hex,第一种,是把红外码用base64编码,便于文本编辑,但不好排错。
这里重点说一下pronto hex:
pronto:0000 006C 0022 0000 015B 00AD 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0041 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041 0016 0623 015B 0057 0016 0E6E
每组数据是由16bit的十六进制数字构成,结构:
分频系数 + 数据长度 + 红外引导码 + 红外数据 + 结束码


分频系数: 0000 006C, 38khz载波
数据长度: 0022 0000, 除了头部的分频系数,其余都要计算进去,2组16进制为1个数据单位。
红外引导码:015B 00AD,这里由分频系数得到,每个分频单位大概为26us,引导码为9ms低电平+4.5ms高电平,015Bx26us = 9022us,下面也以此类推。
红外数据:0016 0016表示0;0016 0041表示1。
结束码:0016 0E6E,需要一个20ms左右的高电平表示结束。格力中间有个连接码,也是这样。




好了,大致原理就是这样,说说流程:
1、在HA中用input_select,input_boolean,input_number这些,建立基本的输入组合。
input_boolean:
  ac_ir_send:
    name: "发送"
  ac_power:
    name: "电源"
  ac_lr_flow:
    name: "左右扫风"
  ac_ud_flow:
    name: "上下扫风"
input_select:
  ac_mode_select:
    name: "运行模式"
    options:
      - "自动"
      - "制冷"
      - "制热"
      - "除湿"
      - "送风"
  ac_fanspeed_select:
    name: "风速"
    options:
      - "自动"
      - "一级"
      - "二级"
      - "三级"
input_number:
  ac_temperature:
    min: 16
    max: 30
    step: 1

group:
  gree_air:
    name: "客厅空调"
    entities:
      - input_boolean.ac_ir_send
      - input_boolean.ac_power
      - input_select.ac_mode_select
      - input_number.ac_temperature
      - input_boolean.ac_lr_flow
      - input_boolean.ac_ud_flow


2、在Node-red中,获取组合状态,并生成出合适的pronto hex码,调用remote.send_command服务,发送红外数据。
[{"id":"d89906f9.5f71b8","type":"tab","label":"格力空调","disabled":false,"info":""},{"id":"61065ac0.d38f84","type":"debug","z":"d89906f9.5f71b8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":827,"y":277,"wires":[]},{"id":"82bbfd1.140bc","type":"function","z":"d89906f9.5f71b8","name":"数据处理","func":"/*\n * 具体格式分析见:[url]https://blog.csdn.net/dddxxxx/article/details/53033748[/url]\n */\n\nvar ac_ir = msg.payload.split('\\n');\nvar w = {};\nvar CMD_LEN = 67;\nvar cmd = new ArrayBuffer(CMD_LEN);       //命令长度,67bit,第一部分35bit,第二部分32bit\nvar dv = new DataView(cmd);\n\nfunction makeCode(idx, cmd) {\n  for(var i = 0; i < cmd.length; i++) {\n    dv.setUint8(idx + i, cmd[i].charCodeAt(0));\n  }\n}\n\nfor(var i = 0; i < CMD_LEN; i++) {\n    dv.setUint8(i, 48);                  //初始化为"0"\n  }\n\nvar set_mode = ac_ir[0];                //工作模式\nvar set_temp = ac_ir[1];                //设置温度\nvar set_fanSpeed = ac_ir[2];            //风量\nvar set_power = ac_ir[3];               //电源开关\n\nvar LR_flow = ac_ir[4];                 //左右扫风\nvar UD_flow = ac_ir[5];                 //上下扫风\n\n// 空调工作模式\nvar ac_mod = 0;\nif(set_mode == "自动")\n{\n    makeCode(0,"000");\n}else if(set_mode == "制冷")\n{\n    ac_mod = 1;\n    makeCode(0,"100");\n}else if(ac_ir[0] == "制热")\n{\n    ac_mod = 4;\n    makeCode(0,"001");\n}else if(set_mode == "除湿")\n{\n    ac_mod = 2;\n    makeCode(0,"010");\n}\nelse if(set_mode == "送风")\n{\n    ac_mod = 3;\n    makeCode(0,"110");\n}\n \n//风速\nif(set_fanSpeed == "自动")\n{\n    makeCode(4,"00");\n}else if(set_fanSpeed == "一级")\n{\n    makeCode(4,"10");\n}else if(set_fanSpeed == "二级")\n{\n    makeCode(4,"01");\n}\nelse if(set_fanSpeed == "三级")\n{\n    makeCode(4,"11");\n}\n\n// 温度\nvar temp_code = "";\ntemp_code = (set_temp - 16).toString("2");  //转为二进制\nfor(var i = 0; i < 4; i++) {\n    dv.setUint8(8 + i, temp_code[3-i].charCodeAt(0));    //反序\n  }\nw['temp'] = temp_code;\n\n//电源\nvar power_mod = 0;\nif(set_power == "off")\n{\n    makeCode(3,"0"); \n}else\n{\n    power_mod = 1;\n     makeCode(3,"1");\n}\n\n//扫风\nvar lr_mod = 0;\nif(LR_flow == "on")\n{\n    dv.setUint8(6,49);\n    dv.setUint8(39,49);\n    lr_mod = 1;\n}\n\nif(UD_flow == "on")\n{\n    dv.setUint8(6,49);\n    dv.setUint8(35,49);\n}\n\n// 默认值\ndv.setUint8(21,49);           //灯光开\nmakeCode(43,"10");            //显示温度\nmakeCode(27,"01010010");      //第一部分结束码\ndv.setUint8(48,49);  \n//计算校验值\n//校验码 = (模式 – 1) + (温度 – 16) + 5 + 左右扫风 + 换气 + 节能\n//取二进制后四位,再逆序\n\nvar dat = (ac_mod - 1) + (set_temp - 16) + 5 + lr_mod;\nvar crc_code = dat.toString("2");\nw['crc'] = crc_code;\nvar crc4 = crc_code.substr(-4);\nfor(var i = 0; i < 4; i++) {\n    dv.setUint8(63 + i, crc4[3-i].charCodeAt(0));    //反序\n}\n// 如果是关机,最后一位校验位取反\nif(power_mod === 0)\n{\n   if(dv.getUint8(66) == 48)\n   {\n       dv.setUint8(66, 49);\n   }else{\n       dv.setUint8(66, 48);\n   }\n}\n\n//生成pronto hex码\nvar pre_code = "pronto:0000 006C 0046 0000 "; //包含连接码共68bit\nvar leader_code = "015A 00AD ";\nvar end_code = "0019 0300 ";            //连接码与此相同\nvar high_level = "0019 003E ";\nvar low_level = "0019 0015 ";\nvar raw_str = pre_code + leader_code;\n\n\n\n\nvar str_code="";\nfor(var i = 0; i < CMD_LEN; i++) {\n    \n     str_code = str_code + String.fromCharCode(dv.getUint8(i));\n     if(dv.getUint8(i) == 48)\n        raw_str += low_level;\n    else\n        raw_str += high_level;\n    if(i == 34)\n       raw_str += end_code;            //35bit之后添加连接码\n  }\nraw_str += end_code;  \n\nvar call_str = {"entity_id":"remote.ir_remote","command":raw_str};\nw['code'] = str_code;\nw['data'] = call_str;\n\nmsg.payload = w;\nreturn msg;\n","outputs":1,"noerr":0,"x":543,"y":277,"wires":[["61065ac0.d38f84","55679b99.e3b6e4"]]},{"id":"5797567e.1d7898","type":"api-render-template","z":"d89906f9.5f71b8","name":"数据模板","server":"3e738894.04e198","template":"{{ states('input_select.ac_mode_select') }}\n{{ states('input_number.ac_temperature') }}\n{{ states('input_select.ac_fanspeed_select') }}\n{{ states('input_boolean.ac_power') }}\n{{ states('input_boolean.ac_lr_flow') }}\n{{ states('input_boolean.ac_ud_flow') }}","x":288,"y":277,"wires":[["82bbfd1.140bc"]]},{"id":"c871692f.d2ed28","type":"server-state-changed","z":"d89906f9.5f71b8","name":"发送事件","server":"3e738894.04e198","entityidfilter":"input_boolean.ac_ir_send","entityidfiltertype":"substring","haltifstate":"off","x":89,"y":304,"wires":[["5797567e.1d7898"]]},{"id":"55679b99.e3b6e4","type":"api-call-service","z":"d89906f9.5f71b8","name":"小米红外遥控","server":"3e738894.04e198","service_domain":"remote","service":"send_command","data":"","mergecontext":"","x":816,"y":429,"wires":[[]]},{"id":"3e738894.04e198","type":"server","z":"","name":"HASS","url":"http://192.168.1.19:8123","pass":""}]

回复

使用道具 举报

8

主题

870

帖子

5218

积分

论坛元老

Rank: 8Rank: 8

积分
5218
金钱
4348
HASS币
0
发表于 2019-2-2 00:12:56 | 显示全部楼层
666666谢谢分享
回复

使用道具 举报

5

主题

170

帖子

490

积分

中级会员

Rank: 3Rank: 3

积分
490
金钱
320
HASS币
0
发表于 2019-2-2 00:12:57 | 显示全部楼层
看着就高大上啊:)
回复

使用道具 举报

0

主题

18

帖子

91

积分

注册会员

Rank: 2

积分
91
金钱
73
HASS币
0
发表于 2019-2-2 12:04:44 | 显示全部楼层
好厉害的感觉。。
回复

使用道具 举报

10

主题

680

帖子

5654

积分

论坛元老

Rank: 8Rank: 8

积分
5654
金钱
4969
HASS币
50
发表于 2019-2-2 12:15:37 | 显示全部楼层
牛逼了。。
回复

使用道具 举报

12

主题

243

帖子

1920

积分

论坛技术达人

积分
1920
金钱
1667
HASS币
40
发表于 2019-2-2 14:46:46 | 显示全部楼层
能控制中央空调么
回复

使用道具 举报

11

主题

108

帖子

833

积分

论坛技术达人

积分
833
金钱
715
HASS币
50
发表于 2019-2-2 14:49:08 | 显示全部楼层
红外的问题在于没有状态反馈, 不适合远程控制
回复

使用道具 举报

3

主题

40

帖子

378

积分

论坛分享达人

积分
378
金钱
338
HASS币
0
 楼主| 发表于 2019-2-2 21:01:05 | 显示全部楼层
needs 发表于 2019-2-2 14:46
能控制中央空调么

这是红外线的,中央空调一般都支持rs485接口,比这个更好用
回复

使用道具 举报

3

主题

40

帖子

378

积分

论坛分享达人

积分
378
金钱
338
HASS币
0
 楼主| 发表于 2019-2-2 21:02:18 | 显示全部楼层
iwha 发表于 2019-2-2 14:49
红外的问题在于没有状态反馈, 不适合远程控制

对,不过空调是全码发送,不需要反馈也行。
回复

使用道具 举报

8

主题

690

帖子

4558

积分

论坛元老

Rank: 8Rank: 8

积分
4558
金钱
3863
HASS币
0
QQ
发表于 2019-2-2 23:40:52 来自手机 | 显示全部楼层
厉害厉害
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-26 01:38 , Processed in 0.070082 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表