如何安全的二次利用你的旧手机
之前讲过一个好玩的东西,闲置安卓机妙用 —— termux。当时就把手机接上充电器放到弱电柜中了。发文前天晚上小米5断联了,打开一看电池已经鼓包,后盖已经被顶开了。但是手机是正常开机的,看样是经历过重启,除了电池其他正常,发文当天小米note也未能幸免...
后怕
发现的及时,也在第一时间将旧电池拆卸下扔掉了,新电池还在快递路上。这要是引起火灾后果不堪设想。
问题分析
猜测是因为手机高频率的充放电导致电池问题,因为不会有其他的问题,弱电箱中放置了一个米家蓝牙温湿度计,做了温度湿度阈值报警。除了温度和撞击那只有过充问题,何止是过充啊,从5月份开始就一直在充电,没有停止过。能挺半年没有自燃感觉已经不错了?
解决问题
确定了问题所在,其实就好解决了。只要不一直充电不就可以了,adb可以获取电池情况,配合只能插座,就可以设置在低电量下连接电源,高电量就断电了。
Gosund智能插座
购买的是 Gosund 智能插座CP1白色(WIFI版),同大小有个带电量统计的,因为精确度也不高也用不上所以就没买那个。这里说一点WIFI的好控制,蓝牙的需要连接网关,虽然家里有个多模网关,但是在网络中没有找到可以直接控制的方法。
编写代码
之前就查找过相关代码,因为想不通过米家或使用更复杂的逻辑触发智能动作。就找到了这个开源库python-miio,miio是小米在米家与相关设备通信时使用的一种协议,python-miio只是用python来实现,还有nodejs相关库。
又使用了Get_MiHome_devices_token这一程序来获取,智能设备的IP和通信认证所需要的token。其代码会有些问题,遇到其库中(https://github.com/Maxmudjon/Get_MiHome_devices_token/blob/main/only_images_and_models.json)没有的设备模型ID,则会报错。 但其实这只是用来匹配一个图片,随便给个默认值就行,因为用名字就可以区分。
# -*- coding: utf-8 -*-
# @Author : Virace
# @Email : Virace@aliyun.com
# @Site : x-item.com
# @Software: PyCharm
# @Create : 2021/11/25 14:54
# @Detail : Gosund插座封装
from miio import Device
class GosundPlug(Device):
def on(self):
return self.send("set_properties", [{'siid': 2, 'piid': 1, 'did': 'state', 'value': True}])
def off(self):
return self.send("set_properties", [{'siid': 2, 'piid': 1, 'did': 'state', 'value': False}])
def status(self):
data = self.send("get_properties", [{'siid': 2, 'piid': 1, 'did': 'state'}])
if data:
return data[0]['value']
然后封装了一个插座的类,不知道为何无法使用其默认提供的相关”Plug“模块进行控制,在GitHub中搜了一下模型名称,得到了以上数据,测试可以正常使用。
adb -s 127.0.0.1:5555 shell dumpsys battery
通过上面命令可以获取电池信息,其中的level为当前电量,temperature为电池温度,既然提供了数据,就对电量以及电池问题进行监控。
# -*- coding: utf-8 -*-
# @Author : Virace
# @Email : Virace@aliyun.com
# @Site : x-item.com
# @Software: PyCharm
# @Create : 2021/11/25 15:42
# @Update : 2021/11/25 15:42
# @Detail : 自动充电
from Plug.gosund import GosundPlug
import os
import subprocess
def run_shell(command, cwd=os.getcwd()):
cmd = subprocess.Popen(command, cwd=cwd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)
return cmd.stdout.readlines()
def get_battrty_info(ip):
run_shell(f'adb connect {ip}:5555')
raw = run_shell(f'adb -s {ip}:5555 shell dumpsys battery')
res = dict()
for line in raw:
d_line = line.decode('utf-8').replace('\r\n', '').strip()
if ': ' not in d_line:
continue
key, value = d_line.split(': ')
res[key] = value
return res
class Power:
def __init__(self, ip, token):
self.plug = GosundPlug(ip, token)
def on(self):
self.plug.on()
return self.plug.status() is True
def off(self):
self.plug.off()
return self.plug.status() is False
def main():
power = Power('192.168.31.42', '2c8481925eddef1a46f24613da644408')
data = get_battrty_info('192.168.31.44')
# 剩余电量
charge = int(data['level'])
# 电池温度
temperature = int(data['temperature'])
print(data, charge, temperature)
if charge <= 30:
result = power.on()
# 返回执行结果,加通知
elif charge >= 98:
result = power.off()
elif temperature >= 390:
# 39° 温度过高通知
pass
if __name__ == '__main__':
main()
电量低于30插座打开,开始充电。高于98,断电。温度高于39°预警,通知这方面还没做,之前写过微信通知相关程序,复制粘贴以下就行了。因为弱电箱里面其实温度不高,并且手机是熄屏执行任务,如果超过了这个阈值,说明有问题了,满载时间过长或其他情况。就需要及时降温,检查运行程序并且断开电源,解除充电状态。
程序不完善,很多细节还未去处理,比如说温度超过多少度暂停充电,停止多长时间等等。需要后续等电池到了,手机恢复后再去测试了。
AccA (Advanced Charging Controller App)
来源: https://github.com/MatteCarra/AccA,这是一个安卓App,看名字其实就能知道这是一个充电控制软件。没有把它排在智能插座前面是因为,他需要Magisk(面具)的支持,这个要是展开将就略麻烦了,可以百度一下。
可以根据不同的需求定制不同的充电模式,冲到多少停止,温度超过多少暂停充电等等。
其中电池闲置模式就相当于不使用电池,充电器直连手机。部分笔记本厂商有这个选项,但这个功能在手机上是需要内核支持的,很可惜我手里的这几个都不支持,至少提示是不支持。
很容易忽略的一个安全问题,也是很多老旧手机再焕发第二春的同时会遇到的问题。
文章评论