说明
基于Blinker点灯,可用Blinker软件和小爱语音控制的esp8266红外遥控志高空调。
空调使用的遥控器是志高的ZH/JT-03,理论上使用这个遥控器的空调都可以使用这个项目。
硬件准备
- ESP8266 开发板一块
- 数字38KHZ红外发射模块(建议买有两个红外发射模块,否则只能向我一样挂在空调)
红外模块的信号线需要连接开发版的D2针脚 - Micro usb 数据线
本项目是基于IRremote的,所以没有使用红外接受模块来学习编码。
我的硬件已经挂在空调上,不太方便拍照。
软件准备
需要点灯Blinker中申请一个设备,获取秘钥,网上都有教程,这里就不多赘述了。
代码
不多废话,直接上代码,烧录部分也不赘述了,用Arduino就行了,需要导入Blinker库和IRremoterESP8266库
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#include <Blinker.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Goodweather.h>
const uint16_t kIrLed = 4; //D02针脚
int colorW;
int nowMode = 1;
int nowFan = 3;
int nowSwing = 3;
bool nowSleep = false;
bool nowTurbo = false;
bool nowACLight = false;
bool oState = false;
int nowTemp =24;
BlinkerNumber NUM1("settemp");
BlinkerButton AC_Power("btn-pwr");
BlinkerButton AC_Mode("btn-mode");
BlinkerButton AC_Fan("btn-fan");
BlinkerButton AC_Swing("btn-swing");
BlinkerButton AC_Sleep("btn-sleep");
BlinkerButton AC_Turbo("btn-turbo");
BlinkerButton AC_Light("btn-light");
BlinkerSlider AC_Temp("ran-temp");
IRGoodweatherAc Chigo_ac(kIrLed);
char auth[] = "************";//这里面填写设备的密钥
char ssid[] = "************";//这里填写你的wifi名字
char pswd[] = "************";//这里填写你的WiFi密码
void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON) {
Chigo_ac.on();
Chigo_ac.setTemp(24); //温度24度
Chigo_ac.setMode(kGoodweatherCool); //制冷模式
Chigo_ac.setFan(kGoodweatherFanMed); //风速中
Chigo_ac.setSwing(kGoodweatherSwingFast); //上下摆风快速
Chigo_ac.setLight(false); //空调灯光开
Chigo_ac.setTurbo(false); //强力模式关
Chigo_ac.setSleep(false); //睡眠关
Chigo_ac.send();
AC_Power.icon("fal fa-power-off");
AC_Power.color("#00FF00");
AC_Power.text("开");
AC_Power.print("on");
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
}
else if (state == BLINKER_CMD_OFF) {
Chigo_ac.off();
Chigo_ac.setLight(true);
Chigo_ac.send();
AC_Power.icon("fal fa-power-off");
AC_Power.color("#FF0000");
AC_Power.text("关");
AC_Power.print("off");
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
}
}
void miotBright(const String & bright)
{
BLINKER_LOG("need set brightness: ", bright);
colorW = bright.toInt();
BLINKER_LOG("now set brightness: ", colorW);
switch(colorW){
//模式
//自动
case 1:
Chigo_ac.setMode(kGoodweatherAuto);
Chigo_ac.send();
nowMode = 1;
AC_Mode.icon("fal fa-recycle");
AC_Mode.color("#008000");
AC_Mode.text("自动");
break;
//制冷
case 2:
Chigo_ac.setMode(kGoodweatherCool);
Chigo_ac.send();
nowMode = 2;
AC_Mode.icon("fal fa-snowflake");
AC_Mode.color("#1E90FF");
AC_Mode.text("制冷");
break;
//除湿
case 3:
Chigo_ac.setMode(kGoodweatherDry);
Chigo_ac.send();
nowMode = 3;
AC_Mode.icon("fal fa-tint-slash");
AC_Mode.color("#87CEFA");
AC_Mode.text("除湿");
break;
//送风
case 4:
Chigo_ac.setMode(kGoodweatherFan);
Chigo_ac.send();
nowMode = 3;
AC_Mode.icon("fab fa-first-order-alt");
AC_Mode.color("#2E8B57");
AC_Mode.text("送风");
break;
//制热
case 5:
Chigo_ac.setMode(kGoodweatherHeat);
Chigo_ac.send();
nowMode = 4;
AC_Mode.icon("fas fa-sun");
AC_Mode.color("#FF0000");
AC_Mode.text("制热");
break;
//风速
//自动
case 6:
Chigo_ac.setFan(kGoodweatherFanAuto);
Chigo_ac.send();
nowFan = 1;
AC_Fan.color("#008000");
AC_Fan.text("自动");
break;
//低风速
case 7:
Chigo_ac.setFan(kGoodweatherFanLow);
Chigo_ac.send();
nowFan = 2;
AC_Fan.color("#1E90FF");
AC_Fan.text("低风速");
break;
//中风速
case 8:
Chigo_ac.setFan(kGoodweatherFanMed);
Chigo_ac.send();
nowFan = 3;
AC_Fan.color("#87CEFA");
AC_Fan.text("中风速");
break;
//高风速
case 9:
Chigo_ac.setFan(kGoodweatherFanHigh);
Chigo_ac.send();
nowFan = 4;
AC_Fan.color("#2E8B57");
AC_Fan.text("高风速");
break;
//上下摆风
//关闭
case 10:
Chigo_ac.setSwing(kGoodweatherSwingOff);
Chigo_ac.send();
nowSwing = 1;
AC_Swing.color("#999999");
AC_Swing.text("上下风");
break;
//低风速
case 11:
Chigo_ac.setSwing(kGoodweatherSwingSlow);
Chigo_ac.send();
nowSwing = 2;
AC_Swing.color("#00FF00");
AC_Swing.text("低风速");
break;
//高风速
case 12:
Chigo_ac.setSwing(kGoodweatherSwingFast);
Chigo_ac.send();
nowSwing = 3;
AC_Swing.color("#87CEFA");
AC_Swing.text("高风速");
break;
//睡眠
//睡眠关闭
case 13:
Chigo_ac.setSleep(false);
Chigo_ac.send();
nowSleep = false;
AC_Sleep.color("#00FF00");
AC_Sleep.text("睡眠开");
AC_Sleep.print("on");
break;
//睡眠开启
case 14:
Chigo_ac.setSleep(true);
Chigo_ac.send();
nowSleep = true;
AC_Sleep.color("#999999");
AC_Sleep.text("睡眠关");
AC_Sleep.print("off");
break;
//温度
//16~30度
case 16:
Chigo_ac.setTemp(16);
Chigo_ac.send();
nowTemp=16;
NUM1.print(nowTemp);
break;
case 17:
Chigo_ac.setTemp(17);
Chigo_ac.send();
nowTemp=17;
NUM1.print(nowTemp);
break;
case 18:
Chigo_ac.setTemp(18);
Chigo_ac.send();
nowTemp=18;
NUM1.print(nowTemp);
break;
case 19:
Chigo_ac.setTemp(19);
Chigo_ac.send();
nowTemp=19;
NUM1.print(nowTemp);
break;
case 20:
Chigo_ac.setTemp(20);
Chigo_ac.send();
nowTemp=20;
NUM1.print(nowTemp);
break;
case 21:
Chigo_ac.setTemp(21);
Chigo_ac.send();
nowTemp=21;
NUM1.print(nowTemp);
break;
case 22:
Chigo_ac.setTemp(22);
Chigo_ac.send();
nowTemp=22;
NUM1.print(nowTemp);
break;
case 23:
Chigo_ac.setTemp(23);
Chigo_ac.send();
nowTemp=23;
NUM1.print(nowTemp);
break;
case 24:
Chigo_ac.setTemp(24);
Chigo_ac.send();
nowTemp=24;
NUM1.print(nowTemp);
break;
case 25:
Chigo_ac.setTemp(25);
Chigo_ac.send();
nowTemp=25;
NUM1.print(nowTemp);
break;
case 26:
Chigo_ac.setTemp(26);
Chigo_ac.send();
nowTemp=26;
NUM1.print(nowTemp);
break;
case 27:
Chigo_ac.setTemp(27);
Chigo_ac.send();
nowTemp=27;
NUM1.print(nowTemp);
break;
case 28:
Chigo_ac.setTemp(28);
Chigo_ac.send();
nowTemp=28;
NUM1.print(nowTemp);
break;
case 29:
Chigo_ac.setTemp(29);
Chigo_ac.send();
nowTemp=29;
NUM1.print(nowTemp);
break;
case 30:
Chigo_ac.setTemp(30);
Chigo_ac.send();
nowTemp=30;
NUM1.print(nowTemp);
break;
//强力
//开
case 31:
Chigo_ac.setTurbo(true);
Chigo_ac.send();
nowTurbo = true;
AC_Turbo.color("#00FF00");
AC_Turbo.text("强力开");
AC_Turbo.print("on");
break;
//关
case 32:
Chigo_ac.setTurbo(false);
Chigo_ac.send();
nowTurbo = false;
AC_Turbo.color("#999999");
AC_Turbo.text("强力关");
AC_Turbo.print("off");
break;
//空调灯光
//开
case 33:
Chigo_ac.setLight(false);
Chigo_ac.send();
nowACLight = false;
AC_Light.color("#00FF00");
AC_Light.text("灯光开");
AC_Light.print("on");
break;
//关
case 34:
Chigo_ac.setLight(true);
Chigo_ac.send();
nowACLight = true;
AC_Light.color("#999999");
AC_Light.text("灯光关");
AC_Light.print("off");
break;
}
BlinkerMIOT.brightness(colorW);
BlinkerMIOT.print();
}
void miotQuery(int32_t queryCode)
{
BLINKER_LOG("MIOT Query codes: ", queryCode);
switch (queryCode)
{
case BLINKER_CMD_QUERY_ALL_NUMBER :
BLINKER_LOG("MIOT Query All");
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
BLINKER_LOG("MIOT Query Power State");
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
default :
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
}
}
//空调电源按钮
void AC_Power_callback(const String &state)
{
BLINKER_LOG("get button state: ", state);
if (state == BLINKER_CMD_ON)
{
Chigo_ac.on();
Chigo_ac.setTemp(24); //温度24度
Chigo_ac.setMode(kGoodweatherCool); //制冷模式
Chigo_ac.setFan(kGoodweatherFanMed); //风速中
Chigo_ac.setSwing(kGoodweatherSwingFast); //上下摆风快速
Chigo_ac.setLight(false); //空调灯光开
Chigo_ac.setTurbo(false); //强力模式关
Chigo_ac.setSleep(false); //睡眠关
Chigo_ac.send();
AC_Power.icon("fal fa-power-off");
AC_Power.color("#00FF00");
AC_Power.text("开");
AC_Power.print("on");
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
oState = true;
}
else if (state == BLINKER_CMD_OFF)
{
Chigo_ac.off();
Chigo_ac.setLight(true);
Chigo_ac.send();
AC_Power.icon("fal fa-power-off");
AC_Power.color("#FF0000");
AC_Power.text("关");
AC_Power.print("off");
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
oState = false;
}
}
//空调模式按钮
void AC_Mode_callback(const String &state)
{
if (state == BLINKER_CMD_BUTTON_TAP)
{
nowMode++;
if (nowMode >= 6)
{
nowMode = 1;
}
switch (nowMode)
{
case 1:
Chigo_ac.setMode(kGoodweatherAuto);
AC_Mode.icon("fal fa-recycle");
AC_Mode.color("#008000");
AC_Mode.text("自动");
break;
case 2:
Chigo_ac.setMode(kGoodweatherCool);
AC_Mode.icon("fal fa-snowflake");
AC_Mode.color("#1E90FF");
AC_Mode.text("制冷");
break;
case 3:
Chigo_ac.setMode(kGoodweatherDry);
AC_Mode.icon("fal fa-tint-slash");
AC_Mode.color("#87CEFA");
AC_Mode.text("除湿");
break;
case 4:
Chigo_ac.setMode(kGoodweatherFan);
AC_Mode.icon("fab fa-first-order-alt");
AC_Mode.color("#2E8B57");
AC_Mode.text("送风");
break;
case 5:
Chigo_ac.setMode(kGoodweatherHeat);
AC_Mode.icon("fas fa-sun");
AC_Mode.color("#FF0000");
AC_Mode.text("制热");
break;
}
AC_Mode.print();
Chigo_ac.send();
}
}
//空调风速按钮
void AC_Fan_callback(const String &state)
{
if (state == BLINKER_CMD_BUTTON_TAP)
{
nowFan++;
if (nowFan >= 5)
{
nowFan = 1;
}
switch (nowFan)
{
case 1:
Chigo_ac.setFan(kGoodweatherFanAuto);
AC_Fan.color("#008000");
AC_Fan.text("自动");
break;
case 2:
Chigo_ac.setFan(kGoodweatherFanLow);
AC_Fan.color("#1E90FF");
AC_Fan.text("低风速");
break;
case 3:
Chigo_ac.setFan(kGoodweatherFanMed);
AC_Fan.color("#87CEFA");
AC_Fan.text("中风速");
break;
case 4:
Chigo_ac.setFan(kGoodweatherFanHigh);
AC_Fan.color("#2E8B57");
AC_Fan.text("高风速");
break;
}
AC_Fan.print();
Chigo_ac.send();
}
}
//空调摆风按钮
void AC_Swing_callback(const String &state)
{
if (state == BLINKER_CMD_BUTTON_TAP)
{
nowSwing++;
if (nowSwing >= 4)
{
nowSwing = 1;
}
switch (nowSwing)
{
case 1:
Chigo_ac.setSwing(kGoodweatherSwingOff);
AC_Swing.color("#999999");
AC_Swing.text("上下风");
break;
case 2:
Chigo_ac.setSwing(kGoodweatherSwingSlow);
AC_Swing.color("#00FF00");
AC_Swing.text("低风速");
break;
case 3:
Chigo_ac.setSwing(kGoodweatherSwingFast);
AC_Swing.color("#87CEFA");
AC_Swing.text("高风速");
break;
}
AC_Swing.print();
Chigo_ac.send();
}
}
//空调睡眠
void AC_Sleep_callback(const String &state)
{
BLINKER_LOG("get button state: ", state);
if (state == BLINKER_CMD_ON)
{
Chigo_ac.setSleep(true);
Chigo_ac.send();
nowSleep = true;
AC_Sleep.color("#00FF00");
AC_Sleep.text("睡眠开");
AC_Sleep.print("on");
}
else if (state == BLINKER_CMD_OFF)
{
Chigo_ac.setSleep(false);
Chigo_ac.send();
nowSleep = false;
AC_Sleep.color("#999999");
AC_Sleep.text("睡眠关");
AC_Sleep.print("off");
}
}
//空调强力
void AC_Turbo_callback(const String &state)
{
BLINKER_LOG("get button state: ", state);
if (state == BLINKER_CMD_ON)
{
Chigo_ac.setTurbo(true);
Chigo_ac.send();
nowTurbo = true;
AC_Turbo.color("#00FF00");
AC_Turbo.text("强力开");
AC_Turbo.print("on");
}
else if (state == BLINKER_CMD_OFF)
{
Chigo_ac.setTurbo(false);
Chigo_ac.send();
nowTurbo = false;
AC_Turbo.color("#999999");
AC_Turbo.text("强力关");
AC_Turbo.print("off");
}
}
//空调灯光
void AC_Light_callback(const String &state)
{
BLINKER_LOG("get button state: ", state);
if (state == BLINKER_CMD_ON)
{
Chigo_ac.setLight(false);
Chigo_ac.send();
nowACLight = false;
AC_Light.color("#00FF00");
AC_Light.text("灯光开");
AC_Light.print("on");
}
else if (state == BLINKER_CMD_OFF)
{
Chigo_ac.setLight(true);
Chigo_ac.send();
nowACLight = true;
AC_Light.color("#999999");
AC_Light.text("灯光关");
AC_Light.print("off");
}
}
//空调温度
void AC_Temp_callback(int32_t value)
{
BLINKER_LOG("get slider value: ", value);
nowTemp=value;
NUM1.print(nowTemp);
Chigo_ac.setTemp(nowTemp);
Chigo_ac.send();
}
void setup()
{
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Chigo_ac.begin();
AC_Power.attach(AC_Power_callback);
AC_Mode.attach(AC_Mode_callback);
AC_Fan.attach(AC_Fan_callback);
AC_Swing.attach(AC_Swing_callback);
AC_Sleep.attach(AC_Sleep_callback);
AC_Turbo.attach(AC_Turbo_callback);
AC_Light.attach(AC_Light_callback);
AC_Temp.attach(AC_Temp_callback);
Blinker.begin(auth, ssid, pswd);
BlinkerMIOT.attachPowerState(miotPowerState);
BlinkerMIOT.attachBrightness(miotBright);
BlinkerMIOT.attachQuery(miotQuery);
}
void loop()
{
Blinker.run();
}
代码或许有很多杂乱的地方,可以自行修改下。
这里用了一个小技巧,因为Blinker本身免费类型没有空调这个类型,所以选择用灯的亮度来匹配温度和各种模式。
Blinker 界面
界面
配置码
{¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/bg/f1.jpg¨¨isFull¨»}}¨dashboard¨|{¨type¨¨btn¨¨ico¨¨fal fa-power-off¨¨mode¨Ê¨t0¨¨开关¨¨t1¨¨文本2¨¨bg¨É¨cols¨Ë¨rows¨Ë¨key¨¨btn-pwr¨´x´É´y´Ë¨speech¨|÷¨lstyle¨É}{ßAßBßC¨fad fa-air-conditioner¨ßEÉßF¨模式¨ßHßIßJÉßKËßLËßM¨btn-mode¨´x´Ë´y´ËßO|÷ßPÉ}{ßAßBßC¨fad fa-fan¨ßEÉßF¨风速¨ßHßIßJÉßKËßLËßM¨btn-fan¨´x´Í´y´ËßO|÷ßPÉ}{ßAßBßC¨fad fa-wind¨ßEÉßF¨摆风¨ßHßIßJÉßKËßLËßM¨btn-swing¨´x´Ï´y´ËßO|÷ßPÉ}{ßAßBßC¨fad fa-bed¨ßEÊßF¨睡眠¨ßHßIßJÉßKËßLËßM¨btn-sleep¨´x´É´y´ÍßO|÷ßPÉ}{ßAßBßC¨fad fa-thunderstorm¨ßEÊßF¨强力¨ßHßIßJÉßKËßLËßM¨btn-turbo¨´x´Ë´y´ÍßO|÷}{ßAßBßC¨fad fa-lightbulb¨ßEÊßF¨灯光¨ßHßIßJÉßKËßLËßM¨btn-light¨´x´Í´y´ÍßO|÷}{ßA¨ran¨ßF¨温度¨¨clr¨¨#389BEE¨¨max¨¤U¨min¨¤GßJÉßKÑßLËßM¨ran-temp¨´x´É´y´ÏßO|÷}÷¨actions¨|¦¨cmd¨¦¨switch¨‡¨text¨‡¨on¨¨打开?name¨¨off¨¨关闭?name¨—÷¨triggers¨|{¨source¨ßr¨source_zh¨¨开关状态¨¨state¨|ßtßv÷¨state_zh¨|´打开´´关闭´÷}÷}
小爱语音配置
在小爱APP或小爱音箱中创建小爱训练计划,对小爱说中添加对空调的控制语音,小爱会执行中选择自定义(不是设备控制,不是设备控制,不是设备控制),指令输入类似“将空调的亮度调的到XX”的命令。
这部分比较繁琐,温度可以不设置,直接说亮度也行。
如图所示
感谢
代码借鉴了
https://www.bilibili.com/video/av328893851/
https://www.bilibili.com/video/BV1po4y197mi/
两位UP的代码