手上有一块ESP32C3的板子空闲,想试试能不能做个小灯,接入HA或者米家,最终实现用小爱同学来控制灯的开关。实际操作过程中发现,米家设备可以接入HA,但是HA设备无法接入米家。所以选择了ESP32C3直接接入米家的方案,并最终实现用小爱同学控制。
视频可参考我在B站发布的:ESP32C3快速接入米家
注册点灯科技
通过下载点灯科技app进行注册。点灯科技官网:https://www.diandeng.tech/home
管理台
管理台为:https://admin.diandeng.tech/index
开发文档
开发文档详见:https://diandeng.tech/doc
APP&SDK下载
APP和开发SDK下载地址:https://diandeng.tech/dev
下载安装app,下载Arduino SDK。
安装SDK
Arduino导入安装刚刚下载的ZIP库(点灯科技SDK)
安装App
添加独立设备,似乎一个账号只能添加一个。。。
注意这里要选网络接入,不建议使用蓝牙方式。(后面会发现,官方例程接入米家使用了WiFi头文件)
获取独立设备Secret Key
上一步点击网络方式,设备便创建好了,会生成Secret Key,也就是密钥,需要写到程序里的。
管理设备
去官网登录管理台,进入设备管理。可看见设备id、设备类型、设备名称、接入模式、用户等信息。
载入示例
更多信息在App修改,点击刚刚新建的设备,会弹出设置向导,点击下方载入示例。
修改属性
默认示例如下,可点击右上角三个点修改属性:
改好了如下,可修改设备名称,可看见设备类型、识别码、密钥(Seccret Key)。其中设备名称会出现在米家其它平台的列表中,可以取个更实际的名称,比如卧室灯。
编辑并上传示例程序
开发板属性
管脚
原理图
从原理图可看出,板载LED有两个,其中有一个LED R接了VSYS(VBUS后端)和GND了,是指示灯;而另一个LED可用GPIO8控制,所以需要的是LED B,低电平亮,高电平灭。
LED B可暂时放在点灯科技例程里当作灯泡来模拟。
编辑示例程序并上传
从文件——示例——Blinker——Blinker_Hello——Hello_WiFi载入示例程序,修改WiFi和LED信息(注意另存为以后再修改信息)[1]。
修改例程并编译
要修改的地方如下,密钥、WiFi名称和密码,以及LED位置:
可以看出来例程的LED为LED_BUILTIN,在头文件Blinker.h里面,查询可知他定义的是GPIO2,然而我这个是GPIO8,所以要改改例程。
修改好是这样:
第一次编译的时候电脑CPU比较吃力
上传程序
测试
上传程序后重启开发板,然后进入Blinker App,刷新一下,可看见设备已在线,点击开关灯按钮,可翻转蓝色LED亮灭状态。
接入米家
绑定点灯科技账号
点灯科技App上测试成功,准备接入米家。方法就是在米家App的“添加其他平台”处添加点灯科技,绑定点灯科技账号。
不过奇怪的是,绑定点灯科技账号后怎么刷新都提示没发现设备。于是查询点灯科技官网,发现有小爱同学接口函数[2],要添加设备类型。
添加设备类型
灯的设备类型是:
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#include <Blinker.h>
前面已经有WiFi类型了,于是只需要添加#define BLINKER_MIOT_LIGHT
,然后准备再次编译并上传。
PS. 这里庆幸还好之前创建设备选的WiFi接入。
然后再去米家App同步一下,就出来了
但是发现还是有问题,米家能在点灯科技可见该设备,却不可以访问该设备。
于是仔细看了下,结合知乎某大佬的成功案例,还需要添加两个函数才行[3]:小爱电源类的操作接口、小爱设备查询接口
小爱电源类的操作接口
小爱设备查询接口
添加小爱同学接口
修改代码,添加小爱电源类的操作接口和小爱设备查询接口,并注册对应的回调函数。
但是发现powerState里面不能空着,会报错。
于是学着知乎大佬添加bool变量ledState给powerState。
发现米家还是访问不了这个设备,准确一点是点不了。然后查了下才发现,这个接入米家是不会出现在米家面板,只是可以用小爱同学控制。。
不过问题又来了,发现控制灯的状态是反的,我让他开灯他关灯。。。仔细检查发现是状态码命名问题,必须叫做POWERSTATE,而我用的是默认的PM25.。。
改过后发现还是不对,再查,我去,是电源接口搞反了,默认的CMD_ON是HIGH,这不对,我这个灯是低电平点亮。于是CMD_ON对应LOW,CMD_OFF对应HIGH。
此外bool变量ledState可以代替if给powerState赋值
其中?:运算可参考微软说明[4]
最终效果
在正确处理电源接口和查询接口后,小爱同学可以正常操作点灯科技的灯了。于是ESP32C3上的LED通过点灯科技接入了米家。
完整代码
/* *****************************************************************
*
* Download latest Blinker library here:
* https://github.com/blinker-iot/blinker-library/archive/master.zip
*
*
* Blinker is a cross-hardware, cross-platform solution for the IoT.
* It provides APP, device and server support,
* and uses public cloud services for data transmission and storage.
* It can be used in smart home, data monitoring and other fields
* to help users build Internet of Things projects better and faster.
*
* Make sure installed 2.7.4 or later ESP8266/Arduino package,
* if use ESP8266 with Blinker.
* https://github.com/esp8266/Arduino/releases
*
* Make sure installed 1.0.5 or later ESP32/Arduino package,
* if use ESP32 with Blinker.
* https://github.com/espressif/arduino-esp32/releases
*
* Docs: https://diandeng.tech/doc
*
*
* *****************************************************************
*
* Blinker 库下载地址:
* https://github.com/blinker-iot/blinker-library/archive/master.zip
*
* Blinker 是一套跨硬件、跨平台的物联网解决方案,提供APP端、设备端、
* 服务器端支持,使用公有云服务进行数据传输存储。可用于智能家居、
* 数据监测等领域,可以帮助用户更好更快地搭建物联网项目。
*
* 如果使用 ESP8266 接入 Blinker,
* 请确保安装了 2.7.4 或更新的 ESP8266/Arduino 支持包。
* https://github.com/esp8266/Arduino/releases
*
* 如果使用 ESP32 接入 Blinker,
* 请确保安装了 1.0.5 或更新的 ESP32/Arduino 支持包。
* https://github.com/espressif/arduino-esp32/releases
*
* 文档: https://diandeng.tech/doc
*
*
* *****************************************************************/
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT
#define LED_B 8
#include <Blinker.h>
char auth[] = "Your Secret Key";
char ssid[] = "Your WiFi SSID";
char pswd[] = "Your WiFi password";
// 新建组件对象
BlinkerButton Button1("btn-led");
BlinkerNumber Number1("num-abc");
bool ledState;
int counter = 0;
// 按下按键即会执行该函数
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_B, !digitalRead(LED_B));
}
// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}
// 小爱电源类的操作接口
void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON) {
digitalWrite(LED_B, LOW);
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
ledState = true;
}
else if (state == BLINKER_CMD_OFF) {
digitalWrite(LED_B, HIGH);
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
ledState = false;
}
}
// 小爱设备查询接口
void miotQuery(int32_t queryCode)
{
BLINKER_LOG("MIOT Query codes: ", queryCode);
switch (queryCode)
{
case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
BLINKER_LOG("MIOT Query Power State");
BlinkerMIOT.powerState(ledState ? "on" : "off");
BlinkerMIOT.print();
break;
default :
BlinkerMIOT.powerState(ledState ? "on" : "off");
BlinkerMIOT.print();
break;
}
}
void setup()
{
// 初始化串口
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
// 初始化有LED的IO
pinMode(LED_B, OUTPUT);
digitalWrite(LED_B, HIGH);
ledState = false;
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
Button1.attach(button1_callback);
// 小爱电源类的操作接口,注册回调函数
BlinkerMIOT.attachPowerState(miotPowerState);
// 小爱设备查询接口,注册回调函数
BlinkerMIOT.attachQuery(miotQuery);
}
void loop() {
Blinker.run();
}
参考文献
[1] 点灯科技. 使用esp32 & WiFi接入. https://diandeng.tech/doc/getting-start-esp32-wifi
[3] TonyCode.(2020). 小爱同学控制EP8266点灯. https://zhuanlan.zhihu.com/p/128643917.