Python 远程关机


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

1. 实现思路

我们这里需要借助一个物联网云平台。其过程如下:

  1. 首先,物联网云平台创建一个服务应用;
  2. 然后,在需要关机的电脑上建立与服务应用的网络连接;
  3. 最后,当需要关机时,通过服务应用向电脑下达关机指令。

这个过程需要解决三个问题:

  1. 需要一个程序保持和服务应用连接,并等待接收命令的程序;
  2. 需要搭建一个用于转发指令的服务程序;
  3. 需要一个 App 客户端程序。

2. 巴法云

实现远程关机的第一步是创建一个服务应用,我们使用巴法云(物联网云平台),目前该平台可以免费使用,地址为:https://cloud.bemfa.com/,请先注册一个账号,然后进入控制台。

第一步:进入控制台之后,点击 MQTT 设备云,如下图所示:

第二步:接下来,在右侧输入主题(可以理解为服务应用)的名字,这个名字尽量用英文和数字组成,然后点击新建主题。这里主题名字格式如下:

主题名 + 主题类型,主题类型有三位数字来确定,如下:

当主题名后三位是001时为插座设备。
当主题名字后三位是002时为灯泡设备。
当主题名字后三位是003时为风扇设备。
当主题名字后三位是004时为传感器设备。
当主题名字后三位是005时为空调设备。
当主题名字后三位是006时为开关设备。
当主题名字后三位是009时为窗帘设备。

如下图所示:

此时,我们的应用就创建完毕。此时,我们将会得到几个比较重要的信息,后面的编码部分需要用到:

  1. 主题名称:SHUTDOWN
  2. MQTT 端口:9501
  3. 请求的主机:bemfa.com
  4. 连接私钥:左上角可以查看

补充:MQTT(Message Queuing Telemetry Transport)是一种轻量级、开放的消息传输协议,用于在低带宽、高延迟或不稳定的网络环境中,实现设备与设备之间的通信。

3. 连接主题

安装 MQTT 协议 Python 库:

pip install paho-mqtt

文档:https://eclipse.dev/paho/index.php?page=clients/python/docs/index.php

实现的步骤:

  1. 连接巴法云服务器
  2. 连接 SHUTDOWN006 主题
  3. 等待接收 SHUTDOWN006 发送的消息,并进行处理

我们在实现过程中,需要实现以下 3 个回调函数:

  1. on_connect 建立连接
  2. on_subscribe 客户端的订阅回调
  3. 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,可打开开机启动目录

未经允许不得转载:一亩三分地 » Python 远程关机
评论 (0)

4 + 9 =