有时,躺在床上懒得起来,或者出门在外,忘记电脑关机,这时,我们希望能实现通过手机实现远程关机。这一节,给大家介绍一种简单的方案,只需要简单、少许编码就可以实现。
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,可打开开机启动目录