有时,躺在床上懒得起来,或者出门在外,忘记电脑关机,这时,我们希望能实现通过手机实现远程关机。这一节,给大家介绍一种简单的方案,只需要简单、少许编码就可以实现。
1. 实现思路
我们这里需要借助一个物联网云平台。其过程如下:
- 首先,物联网云平台创建一个服务应用;
- 然后,在需要关机的电脑上建立与服务应用的网络连接;
- 最后,当需要关机时,通过服务应用向电脑下达关机指令。
这个过程需要解决三个问题:
- 需要一个程序保持和服务应用连接,并等待接收命令的程序;
- 需要搭建一个用于转发指令的服务程序;
- 需要一个 App 客户端程序。
2. 巴法云
实现远程关机的第一步是创建一个服务应用,我们使用巴法云(物联网云平台),目前该平台可以免费使用,地址为:https://cloud.bemfa.com/,请先注册一个账号,然后进入控制台。
第一步:进入控制台之后,点击 MQTT 设备云,如下图所示:
第二步:接下来,在右侧输入主题(可以理解为服务应用)的名字,这个名字尽量用英文和数字组成,然后点击新建主题。这里主题名字格式如下:
主题名 + 主题类型,主题类型有三位数字来确定,如下:
当主题名后三位是001时为插座设备。 当主题名字后三位是002时为灯泡设备。 当主题名字后三位是003时为风扇设备。 当主题名字后三位是004时为传感器设备。 当主题名字后三位是005时为空调设备。 当主题名字后三位是006时为开关设备。 当主题名字后三位是009时为窗帘设备。
如下图所示:
此时,我们的应用就创建完毕。此时,我们将会得到几个比较重要的信息,后面的编码部分需要用到:
- 主题名称:SHUTDOWN
- MQTT 端口:9501
- 请求的主机:bemfa.com
- 连接私钥:左上角可以查看
补充:MQTT(Message Queuing Telemetry Transport)是一种轻量级、开放的消息传输协议,用于在低带宽、高延迟或不稳定的网络环境中,实现设备与设备之间的通信。
3. 连接主题
安装 MQTT 协议 Python 库:
pip install paho-mqtt
文档:https://eclipse.dev/paho/index.php?page=clients/python/docs/index.php
实现的步骤:
- 连接巴法云服务器
- 连接 SHUTDOWN006 主题
- 等待接收 SHUTDOWN006 发送的消息,并进行处理
我们在实现过程中,需要实现以下 3 个回调函数:
- on_connect 建立连接
- on_subscribe 客户端的订阅回调
- on_message 客户端接收到消息
注意:私钥放在了 private.key 文件中。创建 shutdown.py 文件,完整代码如下:
import time from paho.mqtt.client import Client import os import datetime import sys import subprocess host = 'bemfa.com' port = 9501 topic = 'SHUTDOWN006' root = os.path.dirname(os.path.abspath(__file__)) # 输出重定向 sys.stdout = open('shutdown.log', 'w') # 初始化客户端对象 # client_id: 巴法云私钥 # reconnect_on_failure: 连接失败时自动重连 client = Client(client_id=open('private.key').read(), reconnect_on_failure=True) def now(): current_time = datetime.datetime.now() year = current_time.year month = current_time.month day = current_time.day hour = current_time.hour minute = current_time.minute second = current_time.second info = 'none' if sock is None else sock.fileno() return f'{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}' @client.connect_callback() def on_connect(client, userdata, flags, rc): """ :param client: 表示与 MQTT 代理通信的客户端实例 :param userdata: 在回调函数中传递自定义的用户数据 :param flags: 与连接状态相关的标志 :param rc: 连接结果的返回代码, 0表示连接成功,非0连接失败 """ if rc == 0: print(f'{now()} Connected to server', flush=True) # 订阅主题 client.subscribe(topic) else: print(f"{now()} Connection failed with code: {rc}", flush=True) @client.subscribe_callback() def on_subscribe(client, userdata, mid, granted_qos): """ :param client: 表示与 MQTT 代理通信的客户端实例 :param userdata: 在回调函数中传递自定义的用户数据 :param mid: 表示订阅消息的标识符(Message ID) :param granted_qos: 包含了被授予的服务质量等级(QoS,Quality of Service) """ print(f"{now()} Subscribed to topic: {topic}", flush=True) # 告诉服务器我目前的状态 client.publish(topic + '/set', 'on') @client.message_callback() def on_message(client, userdata, message): """ :param client: 表示与 MQTT 代理通信的客户端实例 :param userdata: 在回调函数中传递自定义的用户数据 :param message: 是 MQTTMessage 类型,topic: str,表示消息所属的主题,是一个字符串 payload: bytes,表示实际的消息内容 qos: int,表示消息的服务质量等级 retain: bool,表示消息是否是保留消息 """ cmd = message.payload.decode().strip() print(f"{now()} Recieved massage: {cmd}", flush=True) if cmd == 'off': print(f"{now()} Computer shutdown", flush=True) subprocess.run(['C:\\Windows\\System32\\shutdown.exe', '/s', '/f', '/t', '1']) if __name__ == '__main__': client.connect(host, port, keepalive=50) client.loop_forever()
4. 测试程序
在巴法云控制台,推送消息,查看客户端是否能够正常收到消息,消息的值只有两种:on 和 off。
然后去 https://cloud.bemfa.com/app/ 下载 Android 或者 IOS 的 App, 登录 App,并使用 App 向电脑下达消息指令,查看程序是否正常收到消息。
5. 开机启动
首先,使用 pyinstaller 将程序打包成可执行程序,如下:
# 安装命令 pip install pyinstaller==5.13.2 # 打包命令 pyinstaller --noconsole --onefile shutdown.py
然后,将 private.key、shutdown.log 拷贝到与 shutdown.exe 相同目录下;
接着,创建 shutdown.exe 的快捷方式,并将快捷方式拷贝开机启动目录下;
# 打开启动目录 输入 win + R 打开运行 输入: shell:startup,可打开开机启动目录