从抽屉翻出来一块ESP8266的开发板,因家里的所有设备都是用的小爱全家桶,所以想使用小爱同学来控制电脑开机。原来使用的FRP做内网穿透,实现WOL开机,但是需要在WakeOnLan的APP中去打开,稍显麻烦。所以想通过ESP8266开发板,实现使用小爱同学语音开机,通过自定义任务,实现手机一键开机,然后使用心跳包检测开机的状态,返回APP。

/*ESP8266电脑WOL开机控制 By kaixing.wang*/
#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET
#include <Blinker.h>
#include <WiFiUdp.h>
#include <WakeOnLan.h>
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>


char auth[] = "***"; //点灯科技KEY
char ssid[] = "***"; //WIFI SSID
char pswd[] = "***"; //WIFI密码

// 变量定义
bool PCState = 0; //存储开关状态的变量
const char *MACAddress = "E0:D5:5E:A3:15:3C"; //储存主机MAC地址
IPAddress ip(192, 168, 2, 120); //用于PING主机状态的IP地址
BlinkerButton button("btn-pc"); //点灯APP上的按钮名称

WiFiUDP udp;
WakeOnLan wol(udp);

void change_state(const String & state){
    if (state == "on"){   
      digitalWrite(LED_BUILTIN, LOW);
      wol.sendMagicPacket(MACAddress);
    }   
    PCState = state == "on" ? 1 : 0;
    BUILTIN_SWITCH.print(state);
    button.print(state);

    BlinkerMIOT.powerState(state);
    BlinkerMIOT.print();
    delay(1500);    
    digitalWrite(LED_BUILTIN, HIGH);
}

void switch_callback(const String & state)
{
    BLINKER_LOG("APP列表开关状态: ", state);
    change_state(state);
}

void button_callback(const String & state)
{
    BLINKER_LOG("APP按钮状态: ", state);
    change_state(state);
    Blinker.vibrate();
}

void miotPowerState(const String & state)
{
    BLINKER_LOG("小爱同学状态: ", state);
    change_state(state);
}

void dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);
    Blinker.vibrate();
    uint32_t BlinkerTime = millis();
    Blinker.print("millis", BlinkerTime);
}

void miotQuery(int32_t queryCode, uint8_t num)
{
    BLINKER_LOG("AliGenie Query outlet: ", num,", codes: ", queryCode);

    switch (queryCode)
    {
        case BLINKER_CMD_QUERY_ALL_NUMBER :
            BLINKER_LOG("MIOT Query All");
            BlinkerMIOT.powerState(PCState ? "on" : "off");
            BlinkerMIOT.print();
            break;
        case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :
            BLINKER_LOG("MIOT Query Power State");
            BlinkerMIOT.powerState(PCState ? "on" : "off");
            BlinkerMIOT.print();
            break;
        default :
            BlinkerMIOT.powerState(PCState ? "on" : "off");
            BlinkerMIOT.print();
            break;
    }
}
  
void heartbeat()
{    
    PCState = Ping.ping(ip) ? 1 : 0;
    BUILTIN_SWITCH.print(PCState ? "on" : "off");
    button.print(PCState ? "on" : "off");
    BLINKER_LOG("心跳检测PC状态",PCState);
}

void setup()
{
    //初始化串口,并开启调试信息,调试用可以删除
    Serial.begin(115200);
    BLINKER_DEBUG.stream(Serial);
    
    //初始化IO
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);  
  
    //初始化blinker
    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);
    Blinker.attachHeartbeat(heartbeat);
    BUILTIN_SWITCH.attach(switch_callback);
    button.attach(button_callback);
    
    while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
    }
    wol.setRepeat(3, 100); 

    //给APP发送当前的状态
    BUILTIN_SWITCH.print(PCState ? "on" : "off");
    button.print(PCState ? "on" : "off");
  
    //小爱同学务必在回调函数中反馈该控制状态
    BlinkerMIOT.attachPowerState(miotPowerState);
}

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

点灯APP界面代码

{¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/bg/1.jpg¨}}¨dashboard¨|{¨type¨¨btn¨¨ico¨¨fal fa-power-off¨¨mode¨Ê¨t0¨´´¨t1¨¨文本2¨¨bg¨Ì¨cols¨Í¨rows¨Í¨key¨¨btn-pc¨´x´Ë´y´Í¨lstyle¨Ë¨clr¨¨#00A90C¨}÷¨actions¨|¦¨cmd¨¦¨switch¨‡¨text¨‡¨on¨¨打开?name¨¨off¨¨关闭?name¨—÷¨triggers¨|{¨source¨ßR¨source_zh¨¨开关状态¨¨state¨|ßTßV÷¨state_zh¨|¨打开¨¨关闭¨÷}÷¨rt¨|÷}

引用库文件:

https://github.com/a7md0/WakeOnLan
https://github.com/bluemurder/esp8266-ping