用blinker做桥,将第三方设备接入小爱-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4253|回复: 5

[分享] 用blinker做桥,将第三方设备接入小爱

[复制链接]
发表于 2020-2-11 22:28 | 显示全部楼层 |阅读模式
本帖最后由 kiddfu 于 2020-2-11 22:58 编辑

背景:

家中装修时,考虑会用到智能家居,但又对市面上流行的无线设备不太满意,所以最终敲定以有线智能为主、辅以少量无线设备。

布线时未采用传统布线方案,而是采用了一种中央辐射式的点到点方案。


使用nodered做服务端数据处理平台

  



前段时间入手了几个小爱音响就想着把非米家设备接入小爱。此方案使用8266承载blinker做桥,通过互通数据达到语音控制的效果。

优点:不需要去破解、拦截小爱音响,只要刷入固件就无脑接入小爱。

缺点:需要添加额外的设备(8266)、接入数量有限(5个)

bug:8266发热巨大、有明显延迟

库自带例子做稍微修改,加入mqtt向服务器上报设备状态。

[mw_shl_code=arduino,true]#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET

#define MYAIO_SERVER      "192.168.0.200"
#define MYAIO_SERVERPORT  1883                   // use 8883 for SSL
#define MYAIO_USERNAME    ""
#define MYAIO_KEY         ""
#define MYAIO_BDNAME      "ESPAIKTZD"

#include <Blinker.h>
//#include "Adafruit_MQTT.h"
//#include "Adafruit_MQTT_Client.h"

char auth[] = "xxxxxxx";                                               //密钥
char ssid[] = "xxxxxx";                                                     //wifiSSID
char pswd[] = "xxxxxxxx";                                               //wifi密码

bool oState = false;                                                        //开关状态

void miotPowerState(const String & state)                                   //反馈电源状态
{
    BLINKER_LOG("need set power state: ", state);

    if (state == BLINKER_CMD_ON) {
        digitalWrite(13, HIGH);

        BlinkerMIOT.powerState("on");
        BlinkerMIOT.print();

        oState = true;
    }
    else if (state == BLINKER_CMD_OFF) {
        digitalWrite(13, LOW);

        BlinkerMIOT.powerState("off");
        BlinkerMIOT.print();

        oState = false;
    }
}


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 dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);

    Blinker.vibrate();
   
    uint32_t BlinkerTime = millis();
   
    Blinker.print("millis", BlinkerTime);
}



WiFiClient MyMqttClient;
Adafruit_MQTT_Client MyMqtt(&MyMqttClient, MYAIO_SERVER, MYAIO_SERVERPORT, MYAIO_USERNAME, MYAIO_KEY);
Adafruit_MQTT_Publish potValue = Adafruit_MQTT_Publish(&MyMqtt, MYAIO_BDNAME "/feeds/potValue");
Adafruit_MQTT_Subscribe ledBrightness = Adafruit_MQTT_Subscribe(&MyMqtt, MYAIO_BDNAME "/feeds/ledBrightness");


//uint32_t x=0;
void MQTT_connect()
{
  int8_t ret;

  if (MyMqtt.connected()) return;

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;

  while ((ret = MyMqtt.connect()) != 0)
  {
       Serial.println(MyMqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       MyMqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0)  while (1);
  }
  Serial.println("MQTT Connected!");
}

uint8_t ledPin = 13;
uint16_t potAdcValue = 0;
uint16_t ledBrightValue = 0;

void setup()
{
  Serial.begin(115200);
  BLINKER_DEBUG.stream(Serial);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Blinker.begin(auth, ssid, pswd);
  Blinker.attachData(dataRead);
  BlinkerMIOT.attachPowerState(miotPowerState);
  BlinkerMIOT.attachQuery(miotQuery);

  MyMqtt.subscribe(&ledBrightness);
}

void loop()
{
  
  Blinker.run();
  MQTT_connect();

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = MyMqtt.readSubscription(5000)))
  {
    if (subscription == &ledBrightness)
    {
      Serial.print(F("Got LED Brightness : "));
      ledBrightValue = atoi((char *)ledBrightness.lastread);
      Serial.println(ledBrightValue);
      //analogWrite(ledPin, ledBrightValue);
      if(ledBrightValue == 0) {digitalWrite(13, LOW);oState = false;}
      else                    {digitalWrite(13, HIGH);oState = true;}
    }
  }


  if(oState == false)
  {
    potAdcValue = 0;
  }
  else potAdcValue = 1;
  if (! potValue.publish(potAdcValue)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }

}[/mw_shl_code]

在米家app里面第三方账号里绑定账号同步设备,然后在nodered里面用订阅消息就ok了
视频还在审核就不展示了

2020-02-09.png
微信图片_20200211222334.jpg
微信图片_20200211222324.jpg
微信图片_20200211222334.jpg
演示文稿1_01.png
演示文稿1_01.png
微信图片_20200211225602.png
发表于 2020-2-12 16:29 | 显示全部楼层
强大,赞一个
发表于 2020-2-14 09:52 | 显示全部楼层
5个继电器连在一起的,用一块esp8266就够了,为什么用5块
发表于 2020-2-15 10:28 | 显示全部楼层
sting2k1 发表于 2020-2-14 09:52
5个继电器连在一起的,用一块esp8266就够了,为什么用5块

因为是5个无线设备呀
发表于 2020-2-15 11:35 | 显示全部楼层
则卷弗兰奇 发表于 2020-2-15 10:28
因为是5个无线设备呀

可以用ESP8266_01S
发表于 2020-2-18 23:32 来自手机 | 显示全部楼层
请问楼主是同时连了自己的mqtt服务器么?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 05:37 , Processed in 0.249073 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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