改造家里的开关成为智能开关,保留原有开关控制,零火版

改造家里的开关成为智能开关,保留原有开关控制,零火版

亮点

  1. 成本不超20块,这可能是目前能找到的最便宜方案了吧。
  2. 体积较小,可以塞入86开关面板内。
  3. 手机app+智能音箱+物理开关控制,状态能同步。
  4. 接入点灯科技平台,支持wifi配网,包括blinker 设备密钥。
  5. 入手门槛大大降低,有电工基础,会接入线就行。

过程1,下载固件和配网

过程2,接线

过程3,改造过程

过程4,最后效果

点动式物理开关演示

器材

需要的器件如下,
改造家里的开关成为智能开关,保留原有开关控制,零火版_第1张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第2张图片

接线

改造家里的开关成为智能开关,保留原有开关控制,零火版_第3张图片


改造家里的开关成为智能开关,保留原有开关控制,零火版_第4张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第5张图片

手机app端,Blinker设置

1,下载客户端

https://diandeng.tech/doc/app-download, 下载其app, 按注册blinker账号,获取密钥authkey,iOS 在app store 搜索blinker 安装

改造家里的开关成为智能开关,保留原有开关控制,零火版_第6张图片

2,注册账号

改造家里的开关成为智能开关,保留原有开关控制,零火版_第7张图片

3,创建设备

改造家里的开关成为智能开关,保留原有开关控制,零火版_第8张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第9张图片

改造家里的开关成为智能开关,保留原有开关控制,零火版_第10张图片
到这一步,我们拿到设备的密钥,请记录下来,后面要用!!!!

为设备增加一个按钮, 按键设置如下图
改造家里的开关成为智能开关,保留原有开关控制,零火版_第11张图片

改造家里的开关成为智能开关,保留原有开关控制,零火版_第12张图片

固件下载

1,下载网盘工具包

链接:https://pan.baidu.com/s/1LU4XkcYnH83GNsA61ywFqw 提取码:681i 复制这段内容后打开百度网盘手机App,操作更方便哦

改造家里的开关成为智能开关,保留原有开关控制,零火版_第13张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第14张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第15张图片

2,烧写固件

把esp8266插在烧写器上,然后插入电脑的usb口,如下
改造家里的开关成为智能开关,保留原有开关控制,零火版_第16张图片
运行NdoeMcu-pyFlasher-4.0-xx.exe开始下载固件到esp8266

配置wifi上网

1, 重启esp-01
改造家里的开关成为智能开关,保留原有开关控制,零火版_第17张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第18张图片
用手机连接到esp8266的wifi热点,热点名不是根据型号会不一样,多半以esp-xxx开头

改造家里的开关成为智能开关,保留原有开关控制,零火版_第19张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第20张图片
在电脑的浏览器打开http://192.168.4.1
改造家里的开关成为智能开关,保留原有开关控制,零火版_第21张图片
选择要配置的wifi,点击
改造家里的开关成为智能开关,保留原有开关控制,零火版_第22张图片
2,输入密码和点灯科技创建的设备ID
改造家里的开关成为智能开关,保留原有开关控制,零火版_第23张图片
3,点确定开始配网
改造家里的开关成为智能开关,保留原有开关控制,零火版_第24张图片
成功后

改造家里的开关成为智能开关,保留原有开关控制,零火版_第25张图片
手机端
改造家里的开关成为智能开关,保留原有开关控制,零火版_第26张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第27张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第28张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第29张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第30张图片

接入小爱同学配置

1、在手机上安装米家,小米音箱app.
2、在米家APP上添加点灯科技的扩展。

改造家里的开关成为智能开关,保留原有开关控制,零火版_第31张图片
3,从小爱音箱APP上查看有没有找到设备
改造家里的开关成为智能开关,保留原有开关控制,零火版_第32张图片

1、如果发现在设备,就说明配置成功了,我这里设备名叫“新的设备”,现在可以对小爱说 “打开新的设备”
2、你还可以添加小爱学习
改造家里的开关成为智能开关,保留原有开关控制,零火版_第33张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第34张图片

改造家里的开关成为智能开关,保留原有开关控制,零火版_第35张图片

接入小度配置

代码已经支持,作者还没来得及测试,参考小爱同学配置一下

接入天猫精灵配置

代码已经支持,作者还没来得及测试,参考小爱同学配置一下

接入siri配置

1,安装“快捷指令”app,点击打开

改造家里的开关成为智能开关,保留原有开关控制,零火版_第36张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第37张图片
点运行按钮测试一下开关,passwd是123456

出现下图结果,说明接口调用成功了。

改造家里的开关成为智能开关,保留原有开关控制,零火版_第38张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第39张图片
改造家里的开关成为智能开关,保留原有开关控制,零火版_第40张图片
现在对着siri说,“打开台灯”“关闭台灯”

代码

/*
NodeMcu或esp-01/01s控制1路继电器,集成blinker平台,
用手机app控制1路继电器开关,添加一路物理开关控制,继电器用常开(NO)模式
 
v1.0
Created 2021
by 阳阳学编程
www.sooncore.com
抖音号:yyxbc2010
微信号:yyxbc2010

固件有网页配网功能,固件烧写工具:
链接:https://pan.baidu.com/s/1WsE_2gERyjaUZFbwgJnsOw 提取码:56r8 

说明:

1,继电器高电平触发时,YYXBC_HIGH = 1,YYXBC_LOW  = 0
继电器低电平触发时,YYXBC_HIGH = 0,YYXBC_LOW  = 1
const int YYXBC_HIGH = 0 ;
const int YYXBC_LOW  = 1 ;

2,用esp-01时,物理开关接在vcc 和gpio2上,继电器接在gpio0上
用nodeMcu时,物理开关接在vcc 和D4上,继电器接在D3上,下面的宏
定义只能同时有一个生效

//NodeMCU 继电器接D3,物理开关接D4
#define LED_BUILTIN_LIGHT 0
#define LED_BUILTIN_K2 2

//Esp-01/01s,继电器接GPIO0,物理开关接GPIO2
//#define LED_BUILTIN_LIGHT D3
//#define LED_BUILTIN_K2 D4

3,YYXBC_BUTTON_TYPE = 1时表示物理开关为点动模式,0时表示自锁模式
const int YYXBC_BUTTON_TYPE = 1;

获得具体连接电路图和更多资源,请参阅阳阳学编程网站 www.sooncore.com。
   
This example code is in the public domain.
*/

#define BLINKER_PRINT Serial
#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET              // 设置小爱灯类库
#define BLINKER_DUEROS_OUTLET            // 设置小度灯类库
#define BLINKER_ALIGENIE_OUTLET          // 设置天猫灯类库

#define BLINKER_WITHOUT_SSL              //使用这个宏,表示不用SSL加密,可以得到更多内存

//
如果要使用apconfig配网模式,打开注释掉,加让这行代码生效
//#define BLINKER_APCONFIG

如果要使用smartconfig配网模式,打开注释掉,加让这行代码生效
//#define BLINKER_ESP_SMARTCONFIG

#include 
#include 

char auth[] = "a7a437131912";
char ssid[] = "panzujiMi10";
char pswd[] = "moto1984";

String version  = "1.0.3";

//NodeMCU 继电器接D3,物理开关接D4
#define LED_BUILTIN_LIGHT 0
#define LED_BUILTIN_K2 2

//Esp-01/01s,继电器接GPIO0,物理开关接GPIO2
//#define LED_BUILTIN_LIGHT D3
//#define LED_BUILTIN_K2 D4

/***
 * 继电器高电平触发时,YYXBC_HIGH = 1,YYXBC_LOW  = 0
 * 继电器低电平触发时,YYXBC_HIGH = 0,YYXBC_LOW  = 1
 */
const int YYXBC_HIGH = 0 ;
const int YYXBC_LOW  = 1 ;

/***
 * 物理开关点动模式1,自锁模式0
 */
const int YYXBC_BUTTON_TYPE = 0;

//http接口请求密码
String httppswd = "123456";

bool oDuerState = YYXBC_LOW;
bool oMioState = YYXBC_LOW;
bool oAligenieState = YYXBC_LOW;

// 新建组件对象
BlinkerButton Button1("btn-abc");

//webserver for siri
static ESP8266WebServer esp8266_server(80);

//心跳回调
void heartbeat()
{
     
   BLINKER_LOG("heartbeat,state: ", digitalRead(LED_BUILTIN));

    //较正app的按钮状态
    if(YYXBC_HIGH == digitalRead(LED_BUILTIN_LIGHT) ){
     
        Button1.print("on");
    }else{
     
       Button1.print("off");
    }
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果是手机app 有对设备进行操作就执行下面

void button1_callback(const String & state)
{
     
    BLINKER_LOG("button1_callback get button state: ", state);

    if (state == BLINKER_CMD_ON) {
     
        BLINKER_LOG("Toggle on!");
        Button1.print("on");
        digitalWrite(LED_BUILTIN_LIGHT, YYXBC_HIGH);
        oDuerState = YYXBC_HIGH;
        oMioState =YYXBC_HIGH;
        oAligenieState = YYXBC_HIGH;
    }
    else if (state == BLINKER_CMD_OFF) {
     
        BLINKER_LOG("Toggle off!");
        Button1.print("off");
        digitalWrite(LED_BUILTIN_LIGHT, YYXBC_LOW);
        oDuerState = YYXBC_LOW;
        oMioState = YYXBC_LOW;
        oAligenieState = YYXBC_LOW;
    }
    BlinkerDuerOS.powerState(oDuerState == YYXBC_HIGH ? "on" : "off");
    BlinkerDuerOS.report();
    BlinkerMIOT.powerState(oMioState == YYXBC_HIGH ? "on" : "off");
    BlinkerMIOT.print();
    BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH ? "on" : "off");
    BlinkerAliGenie.print(); 
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果小度 有对设备进行操作就执行下面
void duerPowerState(const String & state)
{
     
    BLINKER_LOG("duerPowerState need set power state: ", state);

    if (state == BLINKER_CMD_ON) {
     
       button1_callback(BLINKER_CMD_ON);
    }
    else if (state == BLINKER_CMD_OFF) {
     
      button1_callback(BLINKER_CMD_OFF);
    }
}

void duerQuery(int32_t queryCode)
{
     
    BLINKER_LOG("DuerOS Query codes: ", queryCode);

    switch (queryCode)
    {
     
        case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :        
            BLINKER_LOG("DuerOS Query power state");
            BlinkerDuerOS.powerState(oDuerState == YYXBC_HIGH? "on" : "off");
            BlinkerDuerOS.print();
            break;
        case BLINKER_CMD_QUERY_TIME_NUMBER :
            BLINKER_LOG("DuerOS Query time");
            BlinkerDuerOS.time(millis());
            BlinkerDuerOS.print();
            break;
        default :
            BlinkerDuerOS.powerState(oDuerState == YYXBC_HIGH? "on" : "off");
            BlinkerDuerOS.print();
            break;
    }
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果小爱有对设备进行操作就执行下面
void miotPowerState(const String & state)
{
     
    BLINKER_LOG("miotPowerState need set power state: ", state);

    if (state == BLINKER_CMD_ON) {
     
       button1_callback(BLINKER_CMD_ON);
    }
    else if (state == BLINKER_CMD_OFF) {
     
      button1_callback(BLINKER_CMD_OFF);
    }
}

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(oMioState == YYXBC_HIGH? "on" : "off");
          BlinkerMIOT.print();
          break;
      case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
          BLINKER_LOG("MIOT Query Power State");
          BlinkerMIOT.powerState(oMioState ==YYXBC_HIGH ? "on" : "off");
          BlinkerMIOT.print();
          break;
      default :
          BlinkerMIOT.powerState(oMioState ==YYXBC_HIGH ? "on" : "off");
          BlinkerMIOT.print();
          break;
    }
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果天猫精灵有对设备进行操作就执行下面
void aligeniePowerState(const String & state)
{
     
    BLINKER_LOG("aligeniePowerState need set power state: ", state);

    if (state == BLINKER_CMD_ON) {
     
       button1_callback(BLINKER_CMD_ON);
    }
    else if (state == BLINKER_CMD_OFF) {
     
      button1_callback(BLINKER_CMD_OFF);
    }
}

void aligenieQuery(int32_t queryCode)
{
     
    BLINKER_LOG("AliGenie Query codes: ", queryCode);

    switch (queryCode)
    {
     
      case BLINKER_CMD_QUERY_ALL_NUMBER :
          BLINKER_LOG("AliGenie Query All");
          BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH? "on" : "off");
          BlinkerAliGenie.print();
          break;
      case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
          BLINKER_LOG("AliGenie Query Power State");
          BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH? "on" : "off");
          BlinkerAliGenie.print();
          break;
      default :
          BlinkerAliGenie.powerState(oAligenieState == YYXBC_HIGH ? "on" : "off");
          BlinkerAliGenie.print();
          break;
    }
}

void dataRead(const String & data){
     
  BLINKER_LOG("Blinker readString: ", data);

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

}

void setup() {
     
    // 初始化串口
    Serial.begin(115200);

    #if defined(BLINKER_PRINT)
        BLINKER_DEBUG.stream(BLINKER_PRINT);
    #endif

//        //debug 命令
//    BLINKER_DEBUG.stream(BLINKER_PRINT);
//    BLINKER_DEBUG.debugAll();

    // 初始化有LED的IO
    pinMode(LED_BUILTIN_LIGHT, OUTPUT);
    digitalWrite(LED_BUILTIN_LIGHT, YYXBC_LOW);
    
    pinMode(LED_BUILTIN_K2, OUTPUT);
//    digitalWrite(LED_BUILTIN_K2, LOW);
    
 #if (defined(BLINKER_APCONFIG)) || (defined(BLINKER_ESP_SMARTCONFIG))
     //启动配网模式用这行代码
    Blinker.begin(auth);
 #else 
    Blinker.begin(auth, ssid, pswd);
 #endif
 
    Blinker.attachData(dataRead);

    BlinkerDuerOS.attachPowerState(duerPowerState); //小度语音操作注册函数
    BlinkerDuerOS.attachQuery(duerQuery);

    BlinkerMIOT.attachPowerState(miotPowerState);//小爱语音操作注册函数
    BlinkerMIOT.attachQuery(miotQuery);

    BlinkerAliGenie.attachPowerState(aligeniePowerState);//天猫语音操作注册函数
    BlinkerAliGenie.attachQuery(aligenieQuery);     
  
    Button1.attach(button1_callback);
    //注册回调函数
    Blinker.attachHeartbeat(heartbeat);
    
    //启动webserver ,提供接口给siri用
    esp8266_server.on("/", handleRoot); 
    esp8266_server.on("/post", handleSetConfig);           
    esp8266_server.onNotFound(handleNotFound);  
    esp8266_server.begin();                  
      
    Serial.println("HTTP esp8266_server started");
}

void loop() {
     

    static int lastms = 0;
    if (millis()-lastms > 10000) {
     
      lastms = millis();
      Serial.printf(PSTR("Running (%s),state(%s),version %s for %d Free mem=%d\n"),
          WiFi.localIP().toString().c_str(),
          oAligenieState == YYXBC_HIGH  ? "YYXBC_HIGH" : "CLOES",
          version.c_str(), lastms/1000, ESP.getFreeHeap());
    }
    
    Blinker.run();//运行Blinker
    esp8266_server.handleClient();// 处理http服务器访问
    
    //检查物理开关状态
    if(YYXBC_BUTTON_TYPE == 1){
     
       btnHandler1();
    }else{
     
       btnHandler2();
    }
   
}


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******如果iOS的siri有对设备进行操作就执行下面
                                                                  
void handleRoot() {
        //处理网站根目录“/”的访问请求 
   String data = "";
      data += "设置";
      data += "";
      data +=" 

ESP8266 智能开关,技术支持 微信:yyxbc2010


"
; data +="

SSID:"+ WiFi.SSID() + "


"
; data +="

PSW:"+ WiFi.psk() + "


"
; data += ""; data += ""; esp8266_server.send(200, "text/html; charset=utf-8", data); } void handleSetConfig() { //处理来自siri的访问请求 if (esp8266_server.method() != HTTP_POST) { esp8266_server.send(405, "text/plain", "Method Not Allowed"); } else { // String message = "POST form was:\n"; String btnName,btnState,btnPswd; for (uint8_t i = 0; i < esp8266_server.args(); i++) { String name = esp8266_server.argName(i); if(name == "btn") { btnName = esp8266_server.arg(i); } else if (name == "state"){ btnState = esp8266_server.arg(i); } else if (name == "passwd"){ btnPswd = esp8266_server.arg(i); } } if(btnPswd != httppswd){ String message = "{\"errcode\":0,\"msg\":\"password error\"}"; esp8266_server.send(200, "text/html; charset=utf-8", message); return; } if(btnName.length() >0 && btnState.length() >0) { //开关btn-abc if(btnName == "btn-1"){ if(btnState == "on"){ button1_callback( BLINKER_CMD_ON); }else if (btnState == "off"){ button1_callback( BLINKER_CMD_OFF); } } } String message = "{\"errcode\":0,\"msg\":\" ok\"}"; esp8266_server.send(200, "text/html; charset=utf-8", message); } } // 设置处理404情况的函数'handleNotFound' void handleNotFound(){ // digitalWrite(led, 1); String message = "File Not Found\n\n"; message += "URI: "; message += esp8266_server.uri(); message += "\nMethod: "; message += (esp8266_server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += esp8266_server.args(); message += "\n"; for (uint8_t i = 0; i < esp8266_server.args(); i++) { message += " " + esp8266_server.argName(i) + ": " + esp8266_server.arg(i) + "\n"; } esp8266_server.send(404, "text/plain", message); } //点动模式按钮,监听按钮状态,执行相应处理 void btnHandler1() { static bool oButtonState = false; int state1 = digitalRead(LED_BUILTIN_K2); //按钮状态 int state2 = digitalRead(LED_BUILTIN_LIGHT); //灯的状态 if(state1 == HIGH ) { if(oButtonState ){ if(state2 == YYXBC_HIGH ) { button1_callback(BLINKER_CMD_OFF); Serial.println("按钮对灯已执行关闭"); }else{ button1_callback(BLINKER_CMD_ON); Serial.println("按钮对灯已执行打开"); } oButtonState = false; } }else{ oButtonState = true; } } //自锁模式按钮,监听按钮状态,执行相应处理 void btnHandler2() { static bool is_btn = false;//按钮的标志位,用来逻辑处理对比,判断按钮有没有改变状态 bool is = digitalRead(LED_BUILTIN_K2); //按钮状态 if ( is != is_btn) { bool is_led = digitalRead(LED_BUILTIN_LIGHT); digitalWrite(LED_BUILTIN_LIGHT, !is_led); if (is_led == YYXBC_HIGH) { button1_callback(BLINKER_CMD_OFF); Serial.println("按钮对灯已执行关闭"); } else { button1_callback(BLINKER_CMD_ON); Serial.println("按钮对灯已执行打开"); } is_btn = digitalRead(LED_BUILTIN_K2); //更新按钮状态 } }

资源下载

本文章相关资源链接:https://pan.baidu.com/s/1LU4XkcYnH83GNsA61ywFqw 提取码:681i 复制这段内容后打开百度网盘手机App,操作更方便哦

关注阳阳学编程抖音号

改造家里的开关成为智能开关,保留原有开关控制,零火版_第41张图片

你可能感兴趣的:(c++,linux,下开发,物联网编程,智能开关编程,创客编程)