如何利用米家实现回家靠近自动打开空调等
【摘要】 夏天到了、每次从炎热的室外到达室内的时候,比如下个班骑车回家,又或者跟朋友出去玩,然后再回到家。都会觉得很热,第一件事,那肯定是想打开空调。自动打开空调的必要性如何打开空调 ? 我能想到的有以下几种方式刚到家,呼叫 小爱同学 打开空调优点:不浪费一点电 ?缺点:燥热的天气恨不得立马凉快下来。所以我通常都是直接先开17度,然后等感觉到冷了再慢慢调上去在即将快到家得时候,在米家上手动操作空调,远...
夏天到了、每次从炎热的室外到达室内的时候,比如下个班骑车回家,又或者跟朋友出去玩,然后再回到家。都会觉得很热,第一件事,那肯定是想打开空调。
自动打开空调的必要性
如何打开空调 ? 我能想到的有以下几种方式
- 刚到家,呼叫 小爱同学 打开空调
- 优点:不浪费一点电 ?
- 缺点:燥热的天气恨不得立马凉快下来。所以我通常都是直接先开17度,然后等感觉到冷了再慢慢调上去
- 在即将快到家得时候,在米家上手动操作空调,远程打开
- 优点: 想不到有什么优点
- 缺点: 几乎不能想起,对,是几乎
除了以上这2种方式还有其他的方式吗?
利用实时距离探测来实现对空调的打开
我想是有的。如何在后台自动的检测到我离家比如400米的时候,就提前打开空调。这样也就根本不用担心是否忘记在手机上操作,或者是等到家了才想起立马开空调了
首先要解决多个设备之间的传感互通问题。
针对米家。基本上也有这3种方式
- 语音操控,这种得在家控制
- App操作,这种起码也得在后台操作
- api操作,这不就是工程师打开的方式了
首先利用苹果的快捷指令
自动化–>新建–>到达–>位置–>选取想要选取的位置(比如 西二旗地铁站)–>当前日期–>后置到iCloud的文件夹里面–保存在比如a.txt文件里
在当前位置这里可以选择精度
这样就完成了第一步,位置上报了。
第二步 米家api接入
登录 先利用账号密码登录
import requests
import json
from hashlib import md5
import random
def login(sid: str, user: str, pwd: str) -> dict:
msgUrl = "https://account.xiaomi.com/pass/serviceLogin?sid=" + sid + "&_json=true"
loginUrl = "https://account.xiaomi.com/pass/serviceLoginAuth2"
tempStr = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
deviceId = ''
for i in range(16):
deviceId += tempStr[random.randint(0, len(tempStr) - 1)]
authorize = {}
userAgent = 'APP/com.xiaomi.mihome APPV/6.0.103 iosPassportSDK/3.9.0 iOS/14.4 miHSTS'
request = requests.session()
request.cookies = requests.cookies.RequestsCookieJar()
request.headers['User-Agent'] = userAgent
request.headers['Accept'] = '*/*'
request.headers['Accept-Language'] = 'zh-tw'
request.headers['Cookie'] = 'deviceId=' + deviceId + '; sdkVersion=3.4.1'
msg = request.get(msgUrl)
result = json.loads(msg.text[11:])
body = {}
body['qs'] = result['qs']
body['sid'] = result['sid']
body['_sign'] = result['_sign']
body['callback'] = result['callback']
body['user'] = user
pwd = md5(pwd.encode()).hexdigest().upper()
pwd += '0' * (32 - len(pwd))
body['hash'] = pwd
body['_json'] = 'true'
msg = request.post(loginUrl, data=body)
result = json.loads(msg.text[11:])
if result['code'] != 0:
authorize['code'] = result['code']
authorize['message'] = result['desc']
return authorize
msg = request.get(result['location'])
for item in msg.headers['Set-Cookie'].split(', '):
item = item.split('; ')[0]
item = item.split('=', maxsplit=1)
authorize[item[0]] = item[1]
authorize['code'] = 0
authorize['sid'] = sid
authorize['userId'] = result['userId']
authorize['securityToken'] = result['ssecurity']
authorize['deviceId'] = deviceId
authorize['message'] = '成功'
return authorize
def read_mem(src):
F = open(src, 'r', encoding='utf-8')
content = F.read()
F.close()
return json.loads(content)
def login_config():
config = read_mem('config.json')
config_user = config['user']
config_pwd = config['password']
authorize = login("xiaomiio", config_user, config_pwd)
print(authorize['message'])
if authorize['code'] == 0:
with open("./json/authorize.json", "w", encoding='utf-8') as f:
f.write(json.dumps(authorize, indent=4, ensure_ascii=False))
if __name__ == '__main__':
config = read_mem('config.json')
config_user = config['user']
config_pwd = config['password']
authorize = login("xiaomiio", config_user, config_pwd)
print(authorize['message'])
if authorize['code'] == 0:
with open("./json/authorize.json", "w", encoding='utf-8') as f:
f.write(json.dumps(authorize, indent=4, ensure_ascii=False))
然后获取其设备列表
def post_data(uri: str, data: dict, authorize: dict) -> None:
data = str(data).replace("'", '"').replace('True', 'true').replace('False', 'false')
try:
serviceToken = authorize['serviceToken']
securityToken = authorize['securityToken']
except KeyError:
print('serviceToken not found, Unauthorized')
return
tempStr = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
nonce = ''
for i in range(16):
nonce += tempStr[random.randint(0, len(tempStr) - 1)]
signedNonce = generateSignedNonce(securityToken, nonce)
signature = generateSignature(uri, signedNonce, nonce, data)
body = {'_nonce': nonce, 'data': data, 'signature': signature}
userAgent = 'APP/com.xiaomi.mihome APPV/6.0.103 iosPassportSDK/3.9.0 iOS/14.4 miHSTS'
request = requests.session()
request.cookies = requests.cookies.RequestsCookieJar()
request.headers['User-Agent'] = userAgent
request.headers['x-xiaomi-protocal-flag-cli'] = 'PROTOCAL-HTTP2'
request.headers['Cookie'] = 'PassportDeviceId=' + authorize['deviceId'] + ';userId=' + str(
authorize['userId']) + ';serviceToken=' + serviceToken + ';'
msg = request.post('https://api.io.mi.com/app' + uri, data=body)
return msg.text
def get_devices(save: bool) -> dict:
"""
获取设备列表
:param save:
:return:
"""
authorize = json.load(open('./json/authorize.json', 'r', encoding='utf-8'))
data = {"getVirtualModel": False, "getHuamiDevices": 0}
msg = post_data('/home/device_list', data, authorize)
devs = json.loads(msg)
if save:
with open('./json/devices.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(devs, indent=4, ensure_ascii=False))
return devs
在米家里有这样的一些自己添加的场景
然后获取场景代码
def get_scenes(save: bool, room_idx=0) -> dict:
"""
获取场景列表
:param save:
:param roomIdx:
:return:
"""
authorize = json.load(open('./json/authorize.json', 'r', encoding='utf-8'))
if os.path.exists('./json/rooms.json'):
rooms = json.load(open('./json/rooms.json', 'r', encoding='utf-8'))
else:
rooms = get_rooms(save)
try:
homeId = rooms['result']['homelist'][room_idx]['id']
except IndexError:
print('房间号超出范围')
return
data = {"home_id": homeId}
msg = post_data('/appgateway/miot/appsceneservice/AppSceneService/GetSceneList', data, authorize)
scenes = json.loads(msg)
if save:
with open('./json/scenes.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(scenes, indent=4, ensure_ascii=False))
return scenes
运行场景代码
def run_scene(name: str) -> int:
"""
运行场景
:param name:
:return:
"""
global scene_id
authorize = json.load(open('./json/authorize.json', 'r', encoding='utf-8'))
if os.path.exists('./json/scenes.json'):
scenes = json.load(open('./json/scenes.json', 'r', encoding='utf-8'))
else:
scenes = get_scenes(True)
scenesList = scenes['result']['scene_info_list']
for scene in scenesList:
if scene['name'] == name:
scene_id = scene['scene_id']
break
try:
data = {"scene_id": scene_id, "trigger_key": "user.click"}
except NameError:
print("场景名称不存在")
return -1
msg = post_data('/appgateway/miot/appsceneservice/AppSceneService/RunScene', data, authorize)
msg = json.loads(msg)
if msg['result']:
return 0
else:
print(msg)
return -1
运行
这样就可以在自己家里的电脑上对其一些文件的监控操作api来完成这个事情了。
最终效果
当我在下班时间范围内的时候。如果我离家只有几百米了。而且判定一下当前的天气,如果适合开空调就自动打开空调了。
一些其他的思考
- 对于一些没有编程基础的人群来说,有其他方式吗?
- 我想是有的,同样去利用快捷指令,当满足xxx条件,然后就对其米家里的App进行一些指令的操作。不过这个点我是刚好写这点思考的时候才想到的
- 除了米家api是否还有其他方式来完成操作对小爱同学的操作
- 去探索了一下,GitHub上有这个开源的库也可以,地址,这样也能在云端进行操作,不过账号安全问题。大家记得对账号的密码保存好
- 苹果的快捷指令,这玩意我之前是几乎不用的,今天这个位置这个事情,如果想对一些人行踪的掌握。或者揭露谎言的。那真是interesting。慎用!
工程师理应该学会利用现有工具,最大程度的偷懒
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)