阿里云服务器远程,阿里云可以控制esp8266吗

博主:xiaoweixiaowei 2023-01-18 条评论

有位读者朋友提出了一个很实际的问题:

能用esp8266弄一个远程开电脑的教程吗?需要设置路由器吗?公司路由器设置不了。”

当然可以!而且很简单~

ESP8266是一个非常适合用于物联网和家庭智能项目的带wifi模块的单片机。它的售价非常低廉,只需大约10块

这个问题可以拆解成两部分:

  • 问题一:在无法设置路由器的情况下,远程访问内网设备。
  • 问题二:通过同局域网下的设备发送指令,控制电脑开机。

问题一:访问内网设备

  1. 如果宽带有公网ip,并且有配置路由器的权限的话,可以直接在路由器上设置端口转发等,可以很方便的访问内网设备。
  2. 如果无法设置路由器,例如上面的这位朋友的情况,则需要做内网穿透或者类似的操作,可以通过第三方平台或者自有的云服务器等来控制内网设备。

问题二:控制电脑开机

可以使用WOL(Wake on Lan)网络唤醒功能。

  1. 首先需要进入电脑主板的BIOS设置,开启WOL功能,根据主板的不同,这个功能还有可能叫PCIE设备唤醒(因为网卡也是经PCIE通道传输数据的,也算是PCIE设备)等。开启了该功能后,即使电脑处于关机状态,主板也会带有微弱电流,网卡会低功耗运行,检测本地网络中是否有相关开机信号。
  2. 利用内网设备发出一个称之为魔法包(Magic Packet)的信号,该魔法包内含有目标设备的网卡MAC地址,可以唯一定位到目标设备。目标设备接受到信号后就会开机启动。

这里我们就利用阿里云物联网平台来控制内网设备,再利用ESP8266 NodeMCU这个性价比极高的单片机发出WOL网络唤醒的魔法包来启动目标电脑~

ESP8266的介绍和入门指南可以参见我上次写的这篇文章:十块钱入门物联网!ESP8266新手指南

下面我们就看看具体怎么设置吧~

一、配置阿里云物联网平台

首先进入阿里云物联网平台的控制台首页,没有账号的朋友需要先注册账号。

点击设备-产品-创建产品。

给新建的产品起一个名字,然后选择自定义品类,并设置为直连设备,其他设置如图:

然后点击进入刚才新建成功的产品内,点击产品-Topic类列表-自定义Topic-定义Top类,来新建一个Topic类。

在新建Topic类的对话框中,设备权限选择“订阅”,名字输入“device_boot”。选订阅权限是因为我们的设备只需要接受消息就可以了,不需要发送消息。后面我们需要用到这个topic来给我们的esp8266发送消息来控制电脑开机~

有了产品之后,我们还需要给产品添加设备:点击设备-添加设备。

在添加设备对话框,选择刚才新建的产品,然后给设备起一个名字。

新建完设备之后,点击刚才新建出的设备的查看按钮来进入设备详情页。

进入设备详情页后,点击DeviceSecret的查看按钮,会得到3个码,把他们复制出来并保存好,后面我们会用到这三个码来把esp8266连接到阿里云物联网平台。

二、打开电脑主板的WOL网络唤醒功能

对于需要被网络唤醒的电脑,按开机键开机,然后不停地点击进入BIOS设置的相关热键。进入BIOS设置的热键一般为DEL, F12等。进入相关设置页面后,打开网络唤醒(Wake on Lan)功能,或者叫做PCIE设备唤醒(Wake on PCIE Devices)。

这样即使在电脑关机之后,只要电源线和网线没有拔掉,电脑接受到其他内网设备(例如ESP8266)发出的的WOL信号,就会开机了!

另外,为了定位需要被唤醒的电脑,我们需要获取目标电脑的网卡MAC地址,以windows系统为例:

按win键+R,输入cmd,回车

然后,输入ipconfig /all,回车,圈出的就是该机器的网卡MAC地址

三、 使用Arduino IDE上传代码到ESP8266

首先参照我上次写的ESP8266新手指南,设置好基本开发环境,这里不再赘述:

十块钱入门物联网!ESP8266新手指南

用Arduino IDE点击.ino文件打开相关代码(具体代码包和用到的库和工具我会打包附于文后):

/**
 * Wake on Lan using Aliyun IOT & ESP8266.
 * 通过ESP8266 NodeMCU和阿里云IOT平台实现对内网主机的网络唤醒(WOL)
 * 
 * 零度橙子OrangeZero Copyright @ 2020
 */
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <PubSubClient.h>  // !!! set MQTT_MAX_PACKET_SIZE=256; MQTT_KEEPALIVE=60 in PubSubClient.h due to restriction in Aliyun IOT mqtt
#include <WakeOnLan.h>

#include "aliyun_mqtt.h" // https://github.com/legenddcr/aliyun-mqtt-arduino

#define WIFI_SSID        "ssid"// >>> 替换为自己的wifi名称::ESP8266只支持2.4G的wifi,不支持5G频段的wifi
#define WIFI_PASSWD      "pwd"// >>> 替换为自己的wifi密码

#define PRODUCT_KEY      "a1G8xxxxxx" // >>> 替换为自己阿里云iot的PRODUCT_KEY
#define DEVICE_NAME      "dev1" // >>> 替换为自己的阿里云的DEVICE_NAME
#define DEVICE_SECRET    "xxxxxxxxxxxxxxxxxxxxxxxx"// >>> 替换为自己阿里云的DEVICE_SECRET

#define DEV_VERSION       "0.0.1"        //固件版本信息
#define ALINK_BODY_FORMAT         "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST     "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP  "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET      "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define ALINK_METHOD_PROP_POST    "thing.event.property.post"
#define ALINK_TOPIC_DEV_INFO      "/ota/device/inform/" PRODUCT_KEY "/" DEVICE_NAME ""    
#define ALINK_VERSION_FROMA      "{\"id\": 123,\"params\": {\"version\": \"%s\"}}"

#define ALINK_TOPIC_DEVICE_BOOT      PRODUCT_KEY "/" DEVICE_NAME "/user/device_boot"

const char *MACAddress = "04:D9:F5:83:03:EF";  // >>> 替换成需要被唤醒的机器的MAC地址
IPAddress computer_ip(255, 255, 255, 255);
unsigned long lastMs = 0;

WiFiClient   espClient;
PubSubClient mqttClient(espClient);
WiFiUDP UDP;
WakeOnLan WOL(UDP);

void init_wifi(const char *ssid, const char *password)
{
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.println("WiFi does not connect, try again ...");
        delay(500);
    }

    Serial.println("Wifi is connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}


void mqtt_callback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    payload[length] = '\0';
    Serial.println((char *)payload);

    if (strstr(topic, ALINK_TOPIC_DEVICE_BOOT)) {
        Serial.print("sending WOL magic packet to: ");
        Serial.println(MACAddress);
        WOL.sendMagicPacket(MACAddress);
    }
}

void mqtt_version_post()
{
    char param[512];
    sprintf(param, "{\"id\": 123,\"params\": {\"version\": \"%s\"}}", DEV_VERSION);
    Serial.println(param);
    mqttClient.publish(ALINK_TOPIC_DEV_INFO, param);
}

void mqtt_check_connect()
{
    Serial.println("checking mqtt connection...");
    while (!mqttClient.connected())
    {
        while (connect_aliyun_mqtt(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET))
        {
            Serial.println("MQTT connect succeed!");
            mqttClient.subscribe(ALINK_TOPIC_PROP_SET);
            mqttClient.subscribe(ALINK_TOPIC_DEVICE_BOOT);
            
            Serial.println("subscribe done");
            mqtt_version_post();
        }
    }
    
}

void setup()
{
    /* initialize serial for debugging */
    Serial.begin(115200);
    Serial.println("Demo Start");
    init_wifi(WIFI_SSID, WIFI_PASSWD);
    mqttClient.setCallback(mqtt_callback);
}

// the loop function runs over and over again forever
void loop()
{
    if (millis() - lastMs >= 20000)
    {
        lastMs = millis();
        mqtt_check_connect();
    }

    mqttClient.loop();

    unsigned int WAIT_MS = 2000;
    delay(WAIT_MS); // ms
    //Serial.println(millis() / WAIT_MS);
}

注意,代码需要替换三处地方:

  • wifi名称和密码
  • 从阿里云物联网平台获取到的你的三个码
  • 需要被网络唤醒的电脑主机的MAC地址

需要额外安装的依赖库有(具体用到的库我会打包附于文后):

  • Crypto:用于阿里云物联网平台通讯时的加密解密
  • PubSubClient:用于通过MQTT协议于阿里云物联网平台通讯
  • WakeOnLan:用于给目标机器发送Magic Packet来实现网络唤醒

大家可以通过arduino IDE的包管理器来安装这些包,如果网络不好下不动的话,也可以下载我打包好的zip包,再导入到arduino IDE。

需要注意的是,由于阿里云物联网平台的MQTT协议的限制,PubSubClient.h文件内定义的MQTT_MAX_PACKET_SIZE需要设置为256,MQTT_KEEPALIVE需要设置为60。不然于阿里云物联网平台的通讯会报错。从arduino IDE下载PubSubClient库的朋友需要修改一下这两个值。使用我给的zip包的朋友,不需要额外修改了,因为我已经修改好了。

点击按钮上传代码到ESP8266,并等待上传完毕

打开arduino IDE中的,工具-串口监视器,确认传输速率为115200波特。查看串口调试信息,确认程序运行正常。

四、远程启动电脑

接下来,我们只需到阿里云物联网平台,点击之前创建的设备,然后找到自定义Topic,找到我们之前新建的Topic:device_boot,点击发布消息。

在新建的对话框中,我们就可以给我们的ESP8266发送消息了!

  • Qos选1:代表这个消息至少会被送达一次,可以确保我们的启动机器的消息被ESP8266接受到
  • 消息内容随便填就可以,因为根据我们的代码,ESP8266只要收到device_boot这个topic的消息就会只需WOL网络唤醒的代码

点击确认发送消息之后,我们可以通过串口监视器看到,WOL信号已经发出。而且内网的目标电脑也开机了!

五、小结

以后,只要ESP8266保持通电,它就会自动连接阿里云物联网平台。我们就可以随时随地通过阿里云物联网平台的控制台来远程启动内网的电脑了!

有兴趣的同学甚至可以利用阿里云物联网平台制作一个好看的远程开机界面或者是在家里远程开启公司电脑的实体按键~

大家还有什么想要做的物联网或者智能家居项目呢?在下面留言告诉我吧~


我是零度橙子,科技达人,谷歌认证云计算架构师,AWS认证devops专家,欢迎大家关注我,了解有用有趣的科技知识~

The End

发布于:2023-01-18,除非注明,否则均为 主机评测原创文章,转载请注明出处。