阿里云物联网新手指南利用ESP8266远程启动电脑
有位读者朋友提出了一个很实际的问题:
“能用esp8266弄一个远程开电脑的教程吗?需要设置路由器吗?公司路由器设置不了。”
当然可以!而且很简单~
ESP8266是一个非常适合用于物联网和家庭智能项目的带wifi模块的单片机。它的售价非常低廉,只需大约10块
这个问题可以拆解成两部分:
问题一:在无法设置路由器的情况下,远程访问内网设备。问题二:通过同局域网下的设备发送指令,控制电脑开机。问题一:访问内网设备
如果宽带有公网ip,并且有配置路由器的权限的话,可以直接在路由器上设置端口转发等,可以很方便的访问内网设备。如果无法设置路由器,例如上面的这位朋友的情况,则需要做内网穿透或者类似的操作,可以通过第三方平台或者自有的云服务器等来控制内网设备。问题二:控制电脑开机
可以使用WOL(WakeonLan)网络唤醒功能。
首先需要进入电脑主板的BIOS设置,开启WOL功能,根据主板的不同,这个功能还有可能叫PCIE设备唤醒(因为网卡也是经PCIE通道传输数据的,也算是PCIE设备)等。开启了该功能后,即使电脑处于关机状态,主板也会带有微弱电流,网卡会低功耗运行,检测本地网络中是否有相关开机信号。利用内网设备发出一个称之为魔法包(MagicPacket)的信号,该魔法包内含有目标设备的网卡MAC地址,可以唯一定位到目标设备。目标设备接受到信号后就会开机启动。这里我们就利用阿里云物联网平台来控制内网设备,再利用ESP8266NodeMCU这个性价比极高的单片机发出WOL网络唤醒的魔法包来启动目标电脑~
ESP8266的介绍和入门指南可以参见我上次写的这篇文章:十块钱入门物联网!ESP8266新手指南下面我们就看看具体怎么设置吧~一、配置阿里云物联网平台首先进入阿里云物联网平台的控制台首页,没有账号的朋友需要先注册账号。
点击设备-产品-创建产品。给新建的产品起一个名字,然后选择自定义品类,并设置为直连设备,其他设置如图:然后点击进入刚才新建成功的产品内,点击产品-Topic类列表-自定义Topic-定义Top类,来新建一个Topic类。在新建Topic类的对话框中,设备权限选择“订阅”,名字输入“device_boot”。选订阅权限是因为我们的设备只需要接受消息就可以了,不需要发送消息。后面我们需要用到这个topic来给我们的esp8266发送消息来控制电脑开机~有了产品之后,我们还需要给产品添加设备:点击设备-添加设备。在添加设备对话框,选择刚才新建的产品,然后给设备起一个名字。新建完设备之后,点击刚才新建出的设备的查看按钮来进入设备详情页。进入设备详情页后,点击DeviceSecret的查看按钮,会得到3个码,把他们复制出来并保存好,后面我们会用到这三个码来把esp8266连接到阿里云物联网平台。
二、打开电脑主板的WOL网络唤醒功能对于需要被网络唤醒的电脑,按开机键开机,然后不停地点击进入BIOS设置的相关热键。进入BIOS设置的热键一般为DEL,F12等。进入相关设置页面后,打开网络唤醒(WakeonLan)功能,或者叫做PCIE设备唤醒(WakeonPCIEDevices)。
这样即使在电脑关机之后,只要电源线和网线没有拔掉,电脑接受到其他内网设备(例如ESP8266)发出的的WOL信号,就会开机了!
另外,为了定位需要被唤醒的电脑,我们需要获取目标电脑的网卡MAC地址,以windows系统为例:
按win键+R,输入cmd,回车然后,输入ipconfig/all,回车,圈出的就是该机器的网卡MAC地址
三、使用ArduinoIDE上传代码到ESP8266首先参照我上次写的ESP8266新手指南,设置好基本开发环境,这里不再赘述:
十块钱入门物联网!ESP8266新手指南
用ArduinoIDE点击.ino文件打开相关代码(具体代码包和用到的库和工具我会打包附于文后):
/***WakeonLanusingAliyunIOT&ESP8266.*通过ESP8266NodeMCU和阿里云IOT平台实现对内网主机的网络唤醒(WOL)**零度橙子OrangeZeroCopyright@2020*/#include#include#include//!!!setMQTT_MAX_PACKET_SIZE=256;MQTT_KEEPALIVE=60inPubSubClient.hduetorestrictioninAliyunIOTmqtt#include#include"aliyun_mqtt.h"//#defineWIFI_SSID"ssid"//>>>替换为自己的wifi名称::ESP8266只支持2.4G的wifi,不支持5G频段的wifi#defineWIFI_PASSWD"pwd"//>>>替换为自己的wifi密码#definePRODUCT_KEY"a1G8xxxxxx"//>>>替换为自己阿里云iot的PRODUCT_KEY#defineDEVICE_NAME"dev1"//>>>替换为自己的阿里云的DEVICE_NAME#defineDEVICE_SECRET"xxxxxxxxxxxxxxxxxxxxxxxx"//>>>替换为自己阿里云的DEVICE_SECRET#defineDEV_VERSION"0.0.1"//固件版本信息#defineALINK_BODY_FORMAT"{"id":"123","version":"1.0","method":"%s","params":%s}"#defineALINK_TOPIC_PROP_POST"/sys/"PRODUCT_KEY"/"DEVICE_NAME"/thing/event/property/post"#defineALINK_TOPIC_PROP_POSTRSP"/sys/"PRODUCT_KEY"/"DEVICE_NAME"/thing/event/property/post_reply"#defineALINK_TOPIC_PROP_SET"/sys/"PRODUCT_KEY"/"DEVICE_NAME"/thing/service/property/set"#defineALINK_METHOD_PROP_POST"thing.event.property.post"#defineALINK_TOPIC_DEV_INFO"/ota/device/inform/"PRODUCT_KEY"/"DEVICE_NAME""#defineALINK_VERSION_FROMA"{"id":123,"params":{"version":"%s"}}"#defineALINK_TOPIC_DEVICE_BOOTPRODUCT_KEY"/"DEVICE_NAME"/user/device_boot"constchar*MACAddress="04:D9:F5:83:03:EF";//>>>替换成需要被唤醒的机器的MAC地址IPAddresscomputer_ip(255,255,255,255);unsignedlonglastMs=0;WiFiClientespClient;PubSubClientmqttClient(espClient);WiFiUDPUDP;WakeOnLanWOL(UDP);voidinit_wifi(constchar*ssid,constchar*password){WiFi.mode(WIFI_STA);WiFi.begin(ssid,password);while(WiFi.status()!=WL_CONNECTED){Serial.println("WiFidoesnotconnect,tryagain...");delay(500);}Serial.println("Wifiisconnected.");Serial.println("IPaddress:");Serial.println(WiFi.localIP());}voidmqtt_callback(char*topic,byte*payload,unsignedintlength){Serial.print("Messagearrived[");Serial.print(topic);Serial.print("]");payload[length]='0';Serial.println((char*)payload);if(strstr(topic,ALINK_TOPIC_DEVICE_BOOT)){Serial.print("sendingWOLmagicpacketto:");Serial.println(MACAddress);WOL.sendMagicPacket(MACAddress);}}voidmqtt_version_post(){charparam[512];sprintf(param,"{"id":123,"params":{"version":"%s"}}",DEV_VERSION);Serial.println(param);mqttClient.publish(ALINK_TOPIC_DEV_INFO,param);}voidmqtt_check_connect(){Serial.println("checkingmqttconnection...");while(!mqttClient.connected()){while(connect_aliyun_mqtt(mqttClient,PRODUCT_KEY,DEVICE_NAME,DEVICE_SECRET)){Serial.println("MQTTconnectsucceed!");mqttClient.subscribe(ALINK_TOPIC_PROP_SET);mqttClient.subscribe(ALINK_TOPIC_DEVICE_BOOT);Serial.println("subscribedone");mqtt_version_post();}}}voidsetup(){/*initializeserialfordebugging*/Serial.begin(115200);Serial.println("DemoStart");init_wifi(WIFI_SSID,WIFI_PASSWD);mqttClient.setCallback(mqtt_callback);}//theloopfunctionrunsoverandoveragainforevervoidloop(){if(millis()-lastMs>=20000){lastMs=millis();mqtt_check_connect();}mqttClient.loop();unsignedintWAIT_MS=2000;delay(WAIT_MS);//ms//Serial.println(millis()/WAIT_MS);}注意,代码需要替换三处地方:
wifi名称和密码从阿里云物联网平台获取到的你的三个码需要被网络唤醒的电脑主机的MAC地址
需要额外安装的依赖库有(具体用到的库我会打包附于文后):
Crypto:用于阿里云物联网平台通讯时的加密解密PubSubClient:用于通过MQTT协议于阿里云物联网平台通讯WakeOnLan:用于给目标机器发送MagicPacket来实现网络唤醒大家可以通过arduinoIDE的包管理器来安装这些包,如果网络不好下不动的话,也可以下载我打包好的zip包,再导入到arduinoIDE。需要注意的是,由于阿里云物联网平台的MQTT协议的限制,PubSubClient.h文件内定义的MQTT_MAX_PACKET_SIZE需要设置为256,MQTT_KEEPALIVE需要设置为60。不然于阿里云物联网平台的通讯会报错。从arduinoIDE下载PubSubClient库的朋友需要修改一下这两个值。使用我给的zip包的朋友,不需要额外修改了,因为我已经修改好了。点击按钮上传代码到ESP8266,并等待上传完毕打开arduinoIDE中的,工具-串口监视器,确认传输速率为115200波特。查看串口调试信息,确认程序运行正常。四、远程启动电脑接下来,我们只需到阿里云物联网平台,点击之前创建的设备,然后找到自定义Topic,找到我们之前新建的Topic:device_boot,点击发布消息。在新建的对话框中,我们就可以给我们的ESP8266发送消息了!
Qos选1:代表这个消息至少会被送达一次,可以确保我们的启动机器的消息被ESP8266接受到消息内容随便填就可以,因为根据我们的代码,ESP8266只要收到device_boot这个topic的消息就会只需WOL网络唤醒的代码点击确认发送消息之后,我们可以通过串口监视器看到,WOL信号已经发出。而且内网的目标电脑也开机了!
五、小结以后,只要ESP8266保持通电,它就会自动连接阿里云物联网平台。我们就可以随时随地通过阿里云物联网平台的控制台来远程启动内网的电脑了!
有兴趣的同学甚至可以利用阿里云物联网平台制作一个好看的远程开机界面或者是在家里远程开启公司电脑的实体按键~
大家还有什么想要做的物联网或者智能家居项目呢?在下面留言告诉我吧~
我是零度橙子,科技达人,谷歌认证云计算架构师,AWS认证devops专家,欢迎大家关注我,了解有用有趣的科技知识~