【docker】本地/远程开关电脑,接入米家用小爱音箱控制

查看 110|回复 11
作者:viklion   


powercontrol宽图 (自定义).png (28.21 KB, 下载次数: 0)
下载附件
2024-12-28 18:24 上传

2025.1.15 更新V2.4
1、加入自动清理日志功能,设置保留天数(0为只保留当天日志),每天中午12点自动清理
2、加入查看日志入口(/logs?key=密钥)
3、美化web页面(点击图标可切换深色浅色模式)
-----------------------------------------------------------------------------
2025.1.8 更新V2.2
1、更新教程:添加接入homeassistant方法
2、配置页显示设备在线状态
3、加入代码页,方便复制代码
4、修改ping返回json数据


hapc.png (9.39 KB, 下载次数: 0)
下载附件
2025-1-8 19:39 上传

-----------------------------------------------------------------------------
2024.12.28 更新V2.1
1、更新教程
2、针对关机无法成功的,加入udp关机方式,需要电脑后台运行配套exe程序,使用方法查阅教程关机部分。已经可以正常关机的无需改动,使用netrpc方式即可
3、优化配置页,隐藏未开启功能的参数,加入查看教程和更新日志入口,加入网络唤醒和关机入口,可用于快速测试  
电脑端程序的python代码见github仓库PCshutdown.py

PowerControl
docker容器远程网络唤醒设备,远程关闭windows设备,并可依赖巴法云接入米家,通过米家远程操作(需要小爱音箱)
linux/amd64,linux/arm/v7,linux/arm64,linux/386
前言

  • 上一个帖子:将电脑接入米家,远程、语音开关机,推送消息,提供了思路和python代码,但是部署有难度,也不是教程,只适合有较强折腾力的朋友。

  • 现在带来docker版本,仍旧需要配置电脑,附带详细教程(文末或github仓库中),命名PowerControl
    ">项目地址:https://github.com/viklion/PowerControl
    ">视频教程:https://www.bilibili.com/video/BV1cykZY7Er9/

  • 两者相比较而言各有优缺点,前者可以运行在支持python的低功耗设备中但部署难(比如路由器),而后者则是部署便捷但需要能跑docker的设备(比如nas)

  • 费老大劲接入米家能做到什么呢:①远程开机和关机,不依赖额外的开机卡智能插座等  ②便捷开关机,手机上点一下或者动动嘴小爱同学帮你搞定,从此告别电源按钮   ③自动化场景,例如回家场景自动开启电脑

    * docker版提供访问网页开关机,端口转发或反代后也可远程操作,可不接入米家
    部署
    不要直接复制命令运行,需要修改参数
    1 将容器/app/data目录映射到你的主机目录,存放配置文件和日志文件:
    修改/your/path
    2 修改环境变量:
    WEB_PORT:网页端口
    WEB_KEY:密钥
    1 Docker
    docker run -d --restart unless-stopped -v /your/path:/app/data -e WEB_PORT=7678 -e WEB_KEY=yourkey --network host --name powercontrol viklion/powercontrol:latest
    2 Docker-Compose
    services:
        powercontrol:
            image: viklion/powercontrol:latest
            container_name: powercontrol
            restart: unless-stopped
            network_mode: host
            volumes:
                - /your/path:/app/data
            environment:
                - WEB_PORT=7678
                - WEB_KEY=yourkey
    配置
    查看仓库内pdf教程(最新)
    访问 ip:端口 查看教程(不一定是最新)
    关键代码
    仍旧是python语言,web使用flask,接入巴法沿用上篇帖子内代码并作修改
    网络唤醒:
    使用wakeonlan模块:
    pip install wakeonlan
    from wakeonlan import send_magic_packet
    # 网络唤醒
    def pcwol():
        if wol_enabled:
            try:
                # 唤醒设备
                send_magic_packet(pc_mac,  interface = local_ip)
                return True
            except Exception as e:
                return str(e)
        return None
    关机指令:
    使用linux net rpc指令
    # 关机
    def pcshutdown():
        if shutdown_enabled:
            try:
                # 构建命令
                command = [
                    "net", "rpc", "shutdown",
                    "-f", "-t", shutdown_time, "-C", f"设备将于{shutdown_time}秒后关闭",
                    "-U", f"{pc_account}%{pc_password}", "-I", device_ip
                ]
                # 使用 subprocess.run() 执行命令并获取输出
                result = subprocess.run(command, check=True, capture_output=True, text=True, timeout=2)
                return result.stdout
            except Exception as e:
                return str(e)
        return None
    ping指令:
    使用pythonping模块:
    pip install pythonping
    from pythonping import ping
    # 网络唤醒
    def pcwol():
        if wol_enabled:
            try:
                # 唤醒设备
                send_magic_packet(pc_mac,  interface = local_ip)
                return True
            except Exception as e:
                return str(e)
        return None
    web:
    使用flask框架:
    pip install flask
    from flask import Flask, request, render_template, redirect, url_for, flash, send_file, Response
    部分代码
    # 首页
    @app.route('/', methods=['GET', 'POST'])
    def home():
        return send_file('PowerControl教程.pdf', mimetype='application/pdf')
    # 配置页
    @app.route('/config', methods=['GET', 'POST'])
    def index():
        yaml_config = read_config_yaml()
        if not bool(yaml_config):
            return '配置文件读取失败,检查权限' ,500
        # 获取请求中的密钥
        web_key = request.args.get('key')
        if web_key != Web_data.web_key:
            return '请在url中填入正确的key', 401
        if request.method == 'POST':
            # 获取表单数据
                    以下省略
    # 网络唤醒
    @app.route('/wol', methods=['GET', 'POST'])
    def wol():
        web_key = request.args.get('key')
        if web_key != Web_data.web_key:
            return '请在url中填入正确的key', 401
        rs = pcwol()
    # 关机
    @app.route('/shutdown', methods=['GET', 'POST'])
    def shutdown():
        # 获取请求中的密钥
        web_key = request.args.get('key')
        if web_key != Web_data.web_key:
            return '请在url中填入正确的key', 401
        rs = pcshutdown()
    最后
    编程只是爱好,是为了能实现一些特别需求,欢迎讨论交流指导~
    教程蓝奏云:https://viklion.lanzoub.com/b0r9rwlli    密码:52pj

    教程, 代码

  • 星峰   


    viklion 发表于 2024-12-28 00:54
    拉取viklion/powercontrol:dev
    已经把配套服务程序放进去了,教程也更新了,我自己测试下来Atlas和win11 ...

    udp模式测试成功,十分感谢
    另外你github的源代码貌似没更新
    还测试到,有这么个情况
    多次用小爱控制开关机后,可以发送指令到巴法云,控制台也会更新on和off,但是docker不会响应,日志里面都没有
    而用web控制开关都没问题,以及巴法云里面推送on或off也没问题
    以下是设置日志级别1时获取到的,小爱触发的命令没有带&msg=off和&msg=on
    [电脑][Result]: 2024-12-28 13:42:31  cmd=2&uid=myuuidxxxxx&topic=mypc001(小爱关机)
    [电脑][Result]: 2024-12-28 13:43:42  cmd=2&uid=myuuidxxxxx&topic=mypc001&msg=off(巴法云推送off)
    [电脑][Result]: 2024-12-28 13:44:41  cmd=2&uid=myuuidxxxxx&topic=mypc001(小爱开机)
    [电脑][Result]: 2024-12-28 13:44:52  cmd=2&uid=myuuidxxxxx&topic=mypc001&msg=on(巴法云推送on)
    修改PowerControl.py中以下代码解决了
                   
    [color=]elif

    [color=]f
    [color=]'uid=
    [color=]{
    [color=]self
    .
    [color=]uid
    [color=]}
    [color=]'

    [color=]in

    [color=]recv_str
    :
                        
    [color=]#收到开机消息
                        
    [color=]if

    [color=]'msg=on'

    [color=]in

    [color=]recv_str
    :
                            
    [color=]self
    .
    [color=]power_control
    (
    [color=]'on'
    )
                        
    [color=]#收到关机消息
                        
    [color=]elif

    [color=]'msg=off'

    [color=]in

    [color=]recv_str
    :
                            
    [color=]self
    .
    [color=]power_control
    (
    [color=]'off'
    )
                        
    [color=]else
    :
                            
    [color=]#获取一次已发消息,可获取到相应msg值
                            
    [color=]substr

    [color=]=

    [color=]f
    [color=]'cmd=9&uid=
    [color=]{
    [color=]self
    .
    [color=]uid
    [color=]}
    [color=]&topic=
    [color=]{
    [color=]self
    .
    [color=]topic
    [color=]}
    [color=]\r\n
    [color=]'
                            
    [color=]self
    .
    [color=]tcp_client_socket
    .
    [color=]send
    (
    [color=]substr
    .
    [color=]encode
    (
    [color=]"utf-8"
    ))
    星峰   


    viklion 发表于 2024-12-28 16:30
    代码没问题,我之前路由器跑都用了2年了,我现在也收不到msg=on或off,巴法控制台推送on、off是正常的, ...

    嗯,我也是用着用着收不到on和off了,按我给出的代码跑就可以兼容了
                    elif f'uid={self.uid}' in recv_str:
                        #收到开机消息
                        if 'msg=on' in recv_str:
                            self.power_control('on')
                        #收到关机消息
                        elif 'msg=off' in recv_str:
                            self.power_control('off')
                        else:
                            #获取一次已发消息,可获取到相应msg值
                            substr = f'cmd=9&uid={self.uid}&topic={self.topic}\r\n'
                            self.tcp_client_socket.send(substr.encode("utf-8"))
    qi1990   

    谢谢大佬提供下载
    congcongzhidao   

    正好需要,谢谢大佬
    yuan12345   

    感谢大佬!
    zx360717966   

    厉害,感谢分享~
    立竿见影   

    我猜这个帖子能上热门🔥
    Yifan2007   

    楼主有没有试过给小爱音响替换音源的,网上有大神操作过,不过实操性有点差
    uluckyXH   

    我倒是弄的很简单,一个智能插座,然后设置通电开机,然后就可以远程rustdesk了
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部