【test】小爱同学通过esp32控制电脑开关

一、环境准备

win11、小爱音箱、esp32(通过wol唤醒电脑)、巴法云平台注册

这里使用的是esp32-cam

在这里插入图片描述

二、开关机原理

开机利用WOL技术,Wake-On-LAN简称WOL,是一种电源管理功能;如果存在网络活动,则允许设备将操作系统从待机或休眠模式中唤醒。许多主板厂商支持IBM提出的网络唤醒标准。该标准允许网络管理员远程打开PC机电源,以便进行文件升级、资源跟踪和设备清点等工作。WOL在还未广泛的采用,但在网络时代却具有广阔的发展前景。Wake-On-LAN的实现,主要是向目标主机发送特殊格式的数据包,是AMD公司制作的MagicPacket这套软件以生成网络唤醒所需要的特殊数据包,俗称魔术包(Magic Packet)。MagicPacket格式虽然只是AMD公司开发推广的技术,并非世界公认的标准,但是仍然受到很多网卡制造商的支持,因此许多具有网络唤醒功能的网卡都能与之兼容。wol基本实现原理实现是向需要被唤醒的终端网卡发送FFFFFFFFFFFFFF+目标主机MAC地址(重复16次)所组成的一个数据包,网卡收到数据后终端。(需要主板支持WOL,在BIOS中设置打开)

wol参考:https://blog.csdn.net/a18359388932/article/details/126949062

关机则通过获取巴法云获取关机指令,再通过python执行关机命令实现。

数据传输框架

小爱其实是不直接操作内网被控的电脑,而是通过小爱给一个第三方物联网平台巴法云发送一个消息,而你内网要部署一个用来接收巴法云下发的消息的程序,一旦接收到状态有发生变化,就执行一些执行,比如发送魔术包开机,再比如通过脚本ssh登录你的主机Windows主机执行关机命令.

在这里插入图片描述

三、环境搭建

1.巴法云平台设置

打开巴法科技&巴法云-巴法设备云-巴法物联网云平台 (bemfa.com),点击注册

TCP创客云-》新建主题 pc006 -》设置昵称为电脑

注意:

新建主题的名称pc可以任意修改,但末尾必须是006,表示开关设备

修改设备昵称,这个昵称电脑就是后面在米家中控制的名称

记住私钥、主题(pc006)后续会用到

在这里插入图片描述

2.米家设置

打开手机app米家-我的-添加其他平台-添加-选择巴法-登录巴法账号-同步设备;

同步成功后会显示出电脑图标,后面就可以通过小爱同学语音控制"打开电脑"

3.windows网络唤醒设置

进入BIOS设置wol(自行百度设置)

1.打开设备管理器,点击网络适配器,右键属性,将电源管理的两个勾勾打上;

在高级设置里面将关机网络唤醒和魔术封包唤醒开启

在这里插入图片描述

4.搭建esp32开发环境并部署

参考:

https://blog.csdn.net/weixin_43935402/article/details/125590294

环境搭建完毕后:

本项目使用 Arduino 框架。

  • WakeOnLan : https://github.com/a7md0/WakeOnLan
  • AsyncTCP : https://github.com/me-no-dev/AsyncTCP

参考:

https://github.com/yeyt97/ESP32-Bemfa-WOL-Tool/tree/main

(1)新建项目

在这里插入图片描述

(2)导入esp32库

在这里插入图片描述

(3) 添加库

在这里插入图片描述

添加库WakeOnLan

在这里插入图片描述

添加库AsyncTCP

在这里插入图片描述

(4)导入库AsyncTCP和WakeOnLan

在这里插入图片描述

添加文件bemfa_client.hpp、wifi_helper.hpp:

在这里插入图片描述

将main.cpp拷贝到.ino文件中
见src目录
https://github.com/yeyt97/ESP32-Bemfa-WOL-Tool/tree/main
在这里插入图片描述

#include "bemfa_client.hpp"
#include "WakeOnLan.h"
#include "wifi_helper.hpp"

BemfaClient* bemfaClient;
WifiHelper* wifiHelper;

WiFiUDP UDP;
WakeOnLan WOL(UDP);

const int LED_Pin = 2;

const char *SSID = "xxx";  // wifi名称
const char *PSW = "xxx";  // wifi密码

const char *UID = "xxx";  // 巴法云的UID
const char *TOPIC = "pc006";  // 巴法云中创建的TOPIC(不是昵称)

const char *TARGET_MAC_ADDR = "xxx";  // 要启动的电脑的MAC地址

void blinkTwice() {
    digitalWrite(LED_Pin, HIGH);
    delay(200);
    digitalWrite(LED_Pin, LOW);
    delay(200);
    digitalWrite(LED_Pin, HIGH);
    delay(200);
    digitalWrite(LED_Pin, LOW);
}

void setup() {
    Serial.begin(115200);
    Serial.println("Beginning...");
    wifiHelper = new WifiHelper(SSID, PSW, LED_Pin);
    bemfaClient = new BemfaClient(UID, TOPIC);
    bemfaClient->addCommand("on", []{
        Serial.println("Send magic packet");
        WOL.setRepeat(3, 100);
        WOL.calculateBroadcastAddress(WiFi.localIP(), WiFi.subnetMask());
        WOL.sendMagicPacket(TARGET_MAC_ADDR);
        blinkTwice();
    });
}

void loop() {
    wifiHelper->tick();
    bemfaClient->tick();
}

编译烧录即可,然后通过小爱同学“打开电脑”即可控制电脑开机

5.关机python脚本配置

安装python

参考:https://docs.python.org/zh-cn/3/using/index.html

#安装相关依赖
pip install requests
pip install schedule
pip install pyinstaller

python打包
https://www.cnblogs.com/weilaiqinkong/p/17240065.html

如:pyinstaller -F -w main.py

巴法云平台tcp连接参考:https://bbs.bemfa.com/81

main.py


# -*- coding: utf-8
import socket
import threading
import time
import os
import shutil
import sys
import getpass

def connTCP():
    global tcp_client_socket
    # 创建socket
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # IP 和端口
    server_ip = 'bemfa.com'
    server_port = 8344
    try:
        # 连接服务器
        tcp_client_socket.connect((server_ip, server_port))
        #发送订阅指令
        substr = 'cmd=1&uid=巴法云私钥&topic=pc006\r\n'
        tcp_client_socket.send(substr.encode("utf-8"))
    except:
        time.sleep(2)
        connTCP()

#心跳
def Ping():
    # 发送心跳
    try:
        keeplive = 'ping\r\n'
        tcp_client_socket.send(keeplive.encode("utf-8"))
    except:
        time.sleep(2)
        connTCP()
    #开启定时,30秒发送一次心跳
    t = threading.Timer(30,Ping)
    t.start()


connTCP()
Ping()

while True:
    # 接收服务器发送过来的数据
    recvData = tcp_client_socket.recv(1024)
    if len(recvData) != 0:
        data = recvData.decode('utf-8')
        print('recv:', data)
        if "on" in data:
            print("do nothing!")
        elif "off" in data:
            print("starting poweroff after 3s ...")
            # 3s后 系统自动关机
            print(os.system('shutdown -s -t 3'))
    else:
        print("conn err")
        connTCP()

设置main.exe开机启动

windows下如何设置开机自动运行批处理脚本
1)创建文本文件,点击文件下的另存为,然后保存以bat结尾的文件
2)使用快捷键,win+r 输入:gpedit.msc进入本地策略管理器
3)点击windows设置下的脚本(启动/关机),然后双击启动
4)点击添加,然后点击浏览,选择批处理文件然后确定就可以了
windows下如何设置开机自动运行exe程序
1.选中可执行程序(.exe)→右键创建快捷方式;
2.使用快捷键,win+r 输入: shell:startup
3.打开[启动文件夹]之后,将需要设置开机自启动的软件快捷方式放入其中即可。
4.电脑开机或者重启时,该【启动文件夹】下的软件则会自动开启运行。
参考
https://www.cnblogs.com/muxiaomu/p/16649990.html

四、ubuntu 通过网卡开启网络唤醒 wake on lan

sudo apt-get install ethtool

#查看网卡名称
ifconfig

添加设置服务
sudo vim /etc/systemd/system/wol.service

[Unit]
Description=Wake-on-LAN
Requires=network.target
After=network.target

[Service]
ExecStart=/sbin/ethtool -s enp3s0 wol g
Type=oneshot

[Install]
WantedBy=multi-user.target

保存配置,启用:

sudo systemctl enable wol
sudo systemctl start wol

poweroff.py

# -*- coding: utf-8
import socket
import threading
import time
import os
import shutil
import sys
import getpass

def connTCP():
    global tcp_client_socket
    # 创建socket
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # IP 和端口
    server_ip = 'bemfa.com'
    server_port = 8344
    try:
        # 连接服务器
        tcp_client_socket.connect((server_ip, server_port))
        #发送订阅指令
        substr = 'cmd=1&uid=巴法云私钥&topic=pc006\r\n'
        tcp_client_socket.send(substr.encode("utf-8"))
    except:
        time.sleep(2)
        connTCP()

#心跳
def Ping():
    # 发送心跳
    try:
        keeplive = 'ping\r\n'
        tcp_client_socket.send(keeplive.encode("utf-8"))
    except:
        time.sleep(2)
        connTCP()
    #开启定时,30秒发送一次心跳
    t = threading.Timer(30,Ping)
    t.start()


connTCP()
Ping()

while True:
    # 接收服务器发送过来的数据
    recvData = tcp_client_socket.recv(1024)
    if len(recvData) != 0:
        data = recvData.decode('utf-8')
        print('recv:', data)
        if "on" in data:
            print("do nothing!")
        elif "off" in data:
            # 3s后 系统自动关机
            print(os.system('poweroff'))
    else:
        print("conn err")
        connTCP()

程序自启动
sudo vim /etc/profile

#将poweroff可执行文件路径添加到 /etc/profile文件末尾
/home/user/poweroff 2>&1  > /dev/null &
  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yengi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值