如何安全的二次利用你的旧手机

2021年11月26日 12449点热度 1人点赞 0条评论

之前讲过一个好玩的东西,闲置安卓机妙用 —— termux。当时就把手机接上充电器放到弱电柜中了。发文前天晚上小米5断联了,打开一看电池已经鼓包,后盖已经被顶开了。但是手机是正常开机的,看样是经历过重启,除了电池其他正常,发文当天小米note也未能幸免...

后怕

发现的及时,也在第一时间将旧电池拆卸下扔掉了,新电池还在快递路上。这要是引起火灾后果不堪设想。

小米5电池鼓包

问题分析

猜测是因为手机高频率的充放电导致电池问题,因为不会有其他的问题,弱电箱中放置了一个米家蓝牙温湿度计,做了温度湿度阈值报警。除了温度和撞击那只有过充问题,何止是过充啊,从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(面具)的支持,这个要是展开将就略麻烦了,可以百度一下。

情景模式

可以根据不同的需求定制不同的充电模式,冲到多少停止,温度超过多少暂停充电等等。

其中电池闲置模式就相当于不使用电池,充电器直连手机。部分笔记本厂商有这个选项,但这个功能在手机上是需要内核支持的,很可惜我手里的这几个都不支持,至少提示是不支持。

很容易忽略的一个安全问题,也是很多老旧手机再焕发第二春的同时会遇到的问题。

文章评论