将电脑接入米家,远程、语音开关机,推送消息

查看 178|回复 11
作者:viklion   
1.前言
1.1 要求:电脑主板支持网络唤醒,并且需要另一台设备运行服务,理论上可以跑python、24小时运行、能上网在同一局域网内的都行,比如路由器、nas、不用的手机等(我是运行在华硕路由器上)
1.2 门槛不低,并非拿来就能用,需要有点基础,因为要亿点点设置,所以应该也算不上是教程
1.3 搜索了各种实现方法,参考内容写在最后
1.4 并不是python高手,AI指导,欢迎给出各种意见,讨论学习
2.功能
2.1 通过小爱音箱、天猫精灵等语音开关电脑,解放双手¿
2.2 通过巴法云的app或微信小程序远程开关电脑
2.3 电脑开机或关机,会推送消息
3.实现
3.1 电脑设置:开启网络唤醒,可能需要从bios里设置,记录网卡mac地址
3.2 巴法云中新建TCP创客云虚拟设备,主题名最后以001结尾,昵称可以设置为电脑,记录下私钥和主题名
3.3 米家为例,添加第三方平台设备,选择巴法,同步设备
3.4 设备python环境安装模块
[Python] 纯文本查看 复制代码pip3 install wakeonlan pythonping pywinrm
3.5 代码中有4个方法可以自由选择是否启用
3.5.1 ping检测更新电脑状态:用于手动开关电脑后,同步更新巴法云虚拟设备的状态,如果开启消息推送,还会告诉你电脑开机/关机了
3.5.2 关机指令:如果想要语音或远程关机,需要电脑配置好winRM,并填写好参数
3.5.3 日志记录:指定目录内生成日志文件记录
3.5.4 消息推送:用的方糖推送,也就是Server酱(ServerChan),需要填写参数
3.6 填写必要参数,运行python代码
3.7 可以百度最后的参考内容获得更详细的教程
4.代码
[Python] 纯文本查看 复制代码# -*- coding: utf-8
import re
import socket
import threading
import time
from datetime import datetime
import winrm
import requests
from pythonping import ping
from wakeonlan import send_magic_packet
class PCpower():
    '''
    PCpower类,已测试:python3.8.18
    :param uid: 巴法云用户私钥,必填
    :param topic: 巴法云设备主题,必填
    :param pc_mac: 电脑mac地址,必填(格式:xx:xx:xx……或xx-xx-xx……)
    :param local_ip: 本机ip地址,非电脑ip地址,必填(运行python的设备局域网ip地址,或填写'auto'尝试自动获取)
    :param use_ping: 是否开启ping检测更新电脑状态,True为开启,False为关闭
    :param use_shutdown: 是否需要关机指令,True为开启,False为关闭
    :param pc_ip: 电脑局域网ip地址,非必填,如开启ping或关机指令,则必填
    :param pc_account: 电脑登录账户,非必填,如开启关机指令,则必填
    :param pc_password: 电脑登录密码,非必填,如开启关机指令,则必填
    :param shutdown_time: 延迟关机时间,非必填,如开启关机指令,则必填(单位:秒,立即关机填0)
    :param use_write_log: 是否开启日志记录,True为开启,False为关闭
    :param log_path: 日志文件路径,非必填,如开启日志记录,则必填
    :param use_send_message: 是否开启消息推送[方糖推送],True为开启,False为关闭
    :param url_send_message: [方糖推送]的个人接口,非必填,如开启消息推送,则必填
    :param channel_send_message: [方糖推送]的频道,非必填,如开启消息推送,则必填
    '''
    def __init__(self, uid:str, topic:str, pc_mac:str, local_ip:str, use_ping:bool=False, use_shutdown:bool=False, pc_ip:str ='', pc_account:str='', pc_password:str='', shutdown_time:int=0, use_write_log:bool=False, log_path:str='', use_send_message:bool=False, url_send_message:str='', channel_send_message:str=''):
        self.__uid = uid
        self.__topic = topic
        self.__pc_mac = pc_mac
        self.__local_ip = local_ip if not local_ip == 'auto' else self.get_ip_address()
        self.__use_ping = use_ping
        self.__use_shutdown = use_shutdown
        self.__pc_ip = pc_ip
        self.__pc_account = pc_account
        self.__pc_password = pc_password
        self.__shutdown_time = shutdown_time
        self.__use_write_log = use_write_log
        self.__log_path = log_path
        self.__use_send_message = use_send_message
        self.__url_send_message = url_send_message
        self.__channel_send_message = channel_send_message
        
        self.__pc_state = None
        self.__t_check = None
        
        self.__check_correct(self.__uid, 'uid')
        self.__check_correct(self.__topic, 'topic')
        self.__check_correct(self.__pc_mac, 'pc_mac', is_mac=True)
        self.__check_correct(self.__local_ip, 'local_ip', is_ip=True)
        self.__check_correct(self.__use_ping, 'use_ping', is_bool=True)
        self.__check_correct(self.__use_shutdown, 'use_shutdown', is_bool=True)
        self.__check_correct(self.__use_write_log, 'use_write_log', is_bool=True)
        self.__check_correct(self.__use_send_message, 'use_send_message', is_bool=True)
        if self.__use_ping or self.__use_shutdown:
            self.__check_correct(self.__pc_ip, 'pc_ip', is_ip=True)
        if self.__use_shutdown:
            self.__check_correct(self.__pc_account, 'pc_account')
            self.__check_correct(self.__pc_password, 'pc_password')
            self.__check_correct(self.__shutdown_time, 'shutdown_time', is_int=True)
        if self.__use_write_log:
            self.__check_correct(self.__log_path, 'log_path')
        if self.__use_send_message:
            self.__check_correct(self.__url_send_message, 'url_send_message')
            self.__check_correct(self.__channel_send_message, 'channel_send_message')
            
        print("初始化成功")
        self.__write_log("初始化成功")
        if local_ip == 'auto':
            print(f"自动获取本机局域网ip地址:{self.__local_ip}")
            self.__write_log(f"自动获取本机局域网ip地址:{self.__local_ip}")
   
    def __check_correct(self, self_var, var_name, is_mac=False, is_ip=False, is_bool=False, is_int=False):
        if is_mac:  
            if not isinstance(self_var, str) or not self.check_mac_address(self_var):  
                raise ValueError(f"{var_name}必须是有效的MAC地址,当前为:{self_var}")  
        elif is_ip:  
            if not isinstance(self_var, str) or not self.check_ip_address(self_var):  
                raise ValueError(f"{var_name}必须是有效的IP地址,当前为:{self_var}")  
        elif is_bool:  
            if not isinstance(self_var, bool):  
                raise TypeError(f"{var_name}必须是True或False,当前为:{self_var},类型:{type(self_var)}")  
        elif is_int:  
            if not isinstance(self_var, int) or self_var
5.参考内容
5.1 《用小爱同学控制台式机睡眠和唤醒的思路》,来自知乎,作者:Comzyh
5.2 《电脑接入米家,控制电脑开关机,并且无需购买米家外设》,来自cnblogs,作者:hackyo
5.3 《python 接入,mqtt和tcp》,来自巴法开放论坛
5.4 巴法文档中心

微软, 必填

kkelay   

我也是同样的思路,
也是用的  巴法云只不过是mqtt连接的
用的是SSH控制电脑关机      
脚本部署在公网上面,    只不过 用一段时间就不管用了,得重启脚本
dmxayjn   

哈哈,我是某宝上买了一个人家的开关机模块硬件,插在主板上,用人家的 微信公众号来开关机,这个模块wifi 链接路由器就可以了,然后模块有2根线,插在 主板的开机+-上,这样就OK了,消费:25
ZhjhJZ   

牛,家庭设备智能化了
redapple2015   

这个功能强大,现在全设备向智能化发展。
心伤的天堂   

这个不错
dingqh   

666666   将电脑接入米家  这你是怎么想到的,太神奇了...
aigo891   

只能开关机,能像控制智能音箱那样就好了,想放音乐就放音乐,想查什么就查什么
squallzcy   

确实神奇,但是我一开始理解错了,哈哈哈哈,感谢大佬无私分享
淼先森   


aigo891 发表于 2024-5-8 17:03
只能开关机,能像控制智能音箱那样就好了,想放音乐就放音乐,想查什么就查什么

可以搭配神秘鸭试下,我现在是这样弄的
您需要登录后才可以回帖 登录 | 立即注册

返回顶部