|
前段时间一直在玩mqtt,感觉很方便、透明。最近又迷上了点灯科技,特别是它和小爱之间的关联,让我这样的懒人更有了动口不动手的理由。
虽然小爱好使唤,但我还是想把它集成到MQTT中,通过其他平台统一控制。可是找了好多帖子,没有找到使用MQTT的例子,只好自己研究了。
我买了个220V转5V模块,连接到一个继电器插座上,在上面插上esp8266-01。
大部分是示例中的语句,只不过是把mqtt示例和插座示例合起来了。
下面是我的源码,MQTT在主题homeassistant/zhuwodeng/kaiguan下,发布消息,内容为ON,即是控制开关打开,OFF为关闭。
每个操作执行后,均向状态主题homeassistant/zhuwodeng/zhuangtai发布开关状态消息。
HA平台收到消息后处理开关状态。
- #define BLINKER_WIFI
- #define BLINKER_MIOT_OUTLET
- #include <Blinker.h>
- int GPIO = 0; //定义继电器输入引脚为GPIO/0
- //下面这3行一定要改为自己的
- char auth[] = "888888888888";
- char ssid[] = "ChinaNet-****";
- char pswd[] = "1234567890";
- bool oState = true;
- /************************* Adafruit.io Setup *********************************/
- #define AIO_SERVER "192.168.2.100"
- #define AIO_SERVERPORT 1883 // use 8883 for SSL
- #define AIO_USERNAME "test"
- #define AIO_KEY "test2020"
- Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
- //下面定义了2个主题,1个是灯状态,1个是控制开关
- Adafruit_MQTT_Publish zhuangtai = Adafruit_MQTT_Publish(&mqtt, "homeassistant/zhuwodeng/zhuangtai");
- Adafruit_MQTT_Subscribe kaiguan = Adafruit_MQTT_Subscribe(&mqtt, "homeassistant/zhuwodeng/kaiguan");
- // 新建组件对象(在点灯APP里的开关的名字)
- BlinkerButton Button1("btn-abc");
- // 按下按键即会执行该函数,在APP中按下按钮执行的程序
- void button1_callback(const String & state)
- {
- //digitalWrite(GPIO, !digitalRead(GPIO));
- BLINKER_LOG("get button state: ", state);
-
- if (state == BLINKER_CMD_ON) {
- oState = true;
- }
- else if (state == BLINKER_CMD_OFF) {
- oState = false;
- }
- turnonoff();//调用开关函数
- Blinker.vibrate();
- }
- //小爱控制
- void miotPowerState(const String & state)
- {
- BLINKER_LOG("need set power state: ", state);
- if (state == BLINKER_CMD_ON) {
- oState = true;
- }
- else if (state == BLINKER_CMD_OFF) {
- oState = false;
- }
- turnonoff();
- }
- //小爱查询状态
- void miotQuery(int32_t queryCode)
- {
- BLINKER_LOG("MIOT Query codes: ", queryCode);
- BlinkerMIOT.powerState(oState ? "on" : "off");
- BlinkerMIOT.print();
- }
- void setup()
- {
- Serial.begin(115200);
- BLINKER_DEBUG.stream(Serial);
- pinMode(GPIO, OUTPUT);
- digitalWrite(GPIO, LOW);
- Blinker.begin(auth, ssid, pswd);
- Button1.attach(button1_callback);
- BlinkerMIOT.attachPowerState(miotPowerState);
- BlinkerMIOT.attachQuery(miotQuery);
- mqtt.subscribe(&kaiguan);
- }
- void loop()
- {
- Blinker.run();
- MQTT_connect();
- Adafruit_MQTT_Subscribe *subscription;
- subscription = mqtt.readSubscription();
- // Check if its the onoff button feed
- if (subscription == &kaiguan) {
- Serial.print(F("On-Off button: "));
- Serial.println((char *)kaiguan.lastread);
- if (strcmp((char *)kaiguan.lastread, "ON") == 0) {
- oState = true;
- }
- if (strcmp((char *)kaiguan.lastread, "OFF") == 0) {
- oState = false;
- }
- turnonoff();
- }
- }
- void MQTT_connect() {
- int8_t ret;
- // Stop if already connected.
- if (mqtt.connected()) {
- return;
- }
- Serial.print("Connecting to MQTT... ");
- uint8_t retries = 5;
- ret = mqtt.connect();
- while (ret != 0) { // connect will return 0 for connected
- Serial.println(mqtt.connectErrorString(ret));
- Serial.println("Retrying MQTT connection in 10 seconds...");
- mqtt.disconnect();
- delay(10000); // wait 5 seconds
- retries--;
- ret = mqtt.connect();
- if (retries == 0) {
- // basically die and wait for WDT to reset me
- while (1);
- }
- }
- Serial.println("MQTT Connected!");
- turnonoff();
- }
- //这是自己增加的一个统一控制开关的函数,不管通过哪种方式控制设备,都在这里执行。
- void turnonoff(){
- if (oState){
- digitalWrite(GPIO, LOW);
- Button1.color("#f7dc05");
- Button1.print("on");
- Serial.println("kaiguan is set to ON");
- BlinkerMIOT.powerState("on");
- BlinkerMIOT.print();
- zhuangtai.publish("ON");
- }
- else{
- digitalWrite(GPIO, HIGH);
- Button1.color("#000000");
- Button1.print("off");
- Serial.println("kaiguan is set to OFF");
- BlinkerMIOT.powerState("off");
- BlinkerMIOT.print();
- zhuangtai.publish("OFF");
- }
- }
复制代码 附:源文件
zhuwodeng.zip
(2.48 KB, 下载次数: 63)
|
|