如何将电池充电限制在80%容量?

我刚刚得知,一些联想笔记本电脑包含一个实用程序,可以将电池充电容量限制在0-80%之间,以减缓电池寿命的衰减速度。

screenshot

如何在Ubuntu中完成这个任务?
16个回答

充电阈值非常不幸地是固件和供应商特定的。
幸运的是,联想ThinkPad用户可以在ThinkWiki上找到解决方案。
基本上,它说你需要安装和加载tp_smapi内核模块:
sudo apt-get install tp-smapi-dkms
sudo modprobe tp_smapi

在/sys/devices/platform/smapi中的虚拟文件中写入所需的充电阈值。
echo 40 | sudo tee /sys/devices/platform/smapi/BAT0/start_charge_thresh
echo 80 | sudo tee /sys/devices/platform/smapi/BAT0/stop_charge_thresh

然后一旦充电达到80%,它就会停止充电,只有当电量低于40%时才开始充电。
东芝和其他公司可能会有类似的内核模块,将固件功能暴露给/sys或/proc空间,但由于专利问题,这种可能性非常小。出于同样的原因,能够处理此功能的应用程序要么是专门针对Thinkpad,要么只适用于几个选定的供应商。

1谢谢这个信息。这是一个好的开始,希望至少对于最初提问的人有所帮助。硬件供应商应该为Linux驱动程序开发者提供更多支持。很可惜需要浪费这么多时间来逆向工程硬件协议。 - cfi
在我的ThinkPad X60上运行Ubuntu 11.10时,它的工作方式与描述的一样。 - ændrük
在 cfi 的悬赏结束之前,我会暂时不接受这个答案,以免让那些可能知道更一般解决方案的人在查看此页面之前被排除在外。另外,@cfi,请回应一下。 - ændrük
因为aquaherd花费了时间并且至少成功解决了原始问题,所以被授予奖励。 - cfi
1我在Ubuntu上执行了sudo apt-get install tp-smapi-dkms命令进行安装。安装成功后,我尝试执行echo 40 > /sys/devices/platform/smapi/BAT0/start_charge_thresh命令,但系统提示bash: /sys/devices/platform/smapi/BAT0/start_charge_thresh: No such file or directory。为什么会这样呢? - Alex Malex
@ændrük,不知道为什么,对我来说它不起作用,尽管我按照aquaherd所说的做了。文件没有被创建。为什么呢? - Alex Malex
@Alex,我在上面加了一些细节,原始指示并没有明确提到。如果你在加载tp_smapi时遇到困难,或者加载后/sys/devices/platform/smapi仍然不存在,我建议你就此问题开一个新的提问。 - ændrük
7@ændrük,alex@ubuntu:~$ sudo modprobe tp_smapi FATAL: Error inserting tp_smapi (/lib/modules/3.5.0-17-generic/updates/dkms/tp_smapi.ko): No such device。我错过了什么吗?如果我得不到答案,我将打开一个新的问题。 - Alex Malex
@Alex 我有同样的问题,你开了一个问题吗? - don.joey
@私人,还没有。 - Alex Malex
@Alex 我在这里提出了问题:链接 - don.joey
适用于惠普笔记本电脑吗? - shravan
设置 start_charge_thresh 对我也没有效果。我从某个博客或论坛上读到,我的 T420 型号的API是损坏的。就好像是硬件上的一个bug。而 stop_charge_thresh 则完全正常工作。 - Mika
我遇到了同样的问题,但是在Ubuntu 14.04 LTS(最新更新)的安装过程中出现了这个问题:http://paste2.org/NDdCEtyJ --- 加载模块: $ sudo modprobe hdaps_ec modprobe: 致命错误:找不到hdaps_ec模块。
$ sudo insmod /lib/modules/3.13.0-83-generic/updates/dkms/tp_smapi.ko insmod: 错误:无法插入模块/lib/modules/3.13.0-83-generic/updates/dkms/tp_smapi.ko:模块中有未知符号。
- antivirtel
我完全移除了我的电脑上的Windows,所以我无法访问戴尔电池设置。我将选项保留在最大电池容量80%的状态,现在无法在BIOS中更改。在Dell Latitude上的Ubuntu系统中有没有办法进行更改? - Ljiljan Veselinovic
2@Mika 看起来T420需要安装额外的acpi-call-dkms软件包,具体请参考http://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html#installation - zrooda
这些指示对我在运行Ubuntu 14.04的Thinkpad T400上有效。 - pts
这在IdeaPad上能用吗? - wadie
3需要使用ThinkPad笔记本电脑才能使用TLP设置这些充电值。TLP也支持其他品牌的笔记本电脑(例如戴尔、惠普),但并不支持所有功能,如linrunner页面上FAQ中所述。有关充电阈值的配置,请参见:http://linrunner.de/en/tlp/docs/tlp-configuration.html#chargethresholds - Luckyrings
截至2020年,这个还有效吗? - axolotl
1部分地说,tp_smapi不再起作用了,但是自从4.18版本开始,有一个内核模块thinkpad_acpi可以完成这个任务。 - karlsebal
@karlsebal 和 thinkpad_acpi 一起,我在哪里可以找到电池充电阈值?我在 /sys/devices/platform/thinkpad_acpi/ 里找不到。 - Krzysztof Krasoń
@KrzysztofKrasoń 请参考https://unix.stackexchange.com/a/560047/188466,它位于/sys/class/power_supply/BAT0。 - karlsebal
1在我的Lenovo X1 Carbon上,我在/sys/class/power_supply/BAT0路径下找到了以下文件名的设置:charge_control_end_threshold charge_control_start_threshold charge_start_threshold charge_stop_threshold。我只需将我想要的阈值使用echo命令写入这些文件名中即可。它们会在重启后保持不变,所以可能是我在xubuntu中设置了某些东西来保持它们的持久性。 - NeilG

现在有一个更加友好的应用程序可供Ubuntu(和其他发行版)使用:

TLP - Linux高级电源管理

TLP为Linux带来了先进的电源管理功能,无需了解每个技术细节。TLP已经预先配置为优化电池寿命,所以您只需安装并忘记它。然而,TLP也可以根据您的特定要求进行高度自定义。

它控制的参数之一是保持电池充电限制。正如评论中@tanius所指出的(请点赞!),尽管TLP过去只能在Thinkpad上运行,但最新版本已经支持多个厂商的设备,而且考虑到该项目的性质——如果其他设备的适当驱动程序可用,很可能会集成到该项目中。因此,如果您在几年后阅读本评论,请查看文档,也许您的设备现在已被支持。

Ubuntu软件包可以在官方仓库中找到。


支持设备列表在哪里?我找不到文档中的相关部分。你知道吗,tlp 是否也支持 Thinkpad X1 Carbon 吗? - Kasun Siyambalapitiya
3@KasunSiyambalapitiya,目前来说,tlp只是两个工具的前端,用于实现此功能:Tp smapitpacpi-bat。只要您的型号至少被其中一个支持,它应该可以正常工作(或者您可以提交一个错误报告)。根据它们的支持硬件页面,您的型号似乎没有列出,但是快速搜索显示后者可能适用。 - liori
1电池充电阈值、放电和重新校准目前仅支持IBM/Lenovo ThinkPad。不支持任何其他联想笔记本型号,包括IdeaPad和其他所有笔记本品牌。由于系统文件的差异,TLP 1.3.1不支持Asus和华为笔记本的内核natacpi实现。我希望能够为ASUS笔记本提供一个实现。我的笔记本也有一个由Asus提供的充电控制工具,但只适用于Windows操作系统。 - w-sky
2在这里找到了一个关于如何在Asus笔记本电脑上使用充电控制的指南:https://www.linuxuprising.com/2021/02/how-to-limit-battery-charging-set.html - w-sky
5好消息(尤其是针对 @w-sky):TLP ≥1.4 版本还可以为 Asus、Huawei、LG、其他联想和三星 笔记本设置电池充电限制(来源)。 - tanius
更多的供应商已经加入,包括LG!https://linrunner.de/tlp/settings/bc-vendors.html - flyingdrifter

接受的答案在我的新Lenovo T440s上不起作用。显然固件已经改变了。根据http://www.thinkwiki.org/wiki/Tpacpi-bat,我做了以下操作。
git clone https://github.com/teleshoes/tpacpi-bat.git
cd tpacpi-bat/
./install.pl
sudo ./tpacpi-bat -s ST 1 15 # load internal battery when below 15%
sudo ./tpacpi-bat -s SP 1 95 # stop charging at 95%
sudo ./tpacpi-bat -g ST 2 # when is external battery loaded?

仅供参考,我是在Debian Testing上完成的,但我相信在Ubuntu上同样适用。

在我新的Thinkpad E495上,即使过去6年了,上面的指示仍然有效。但是如果启用了安全启动(secureboot),我不能只添加一个内核模块,而且./install.pl步骤会失败并显示modprobe: ERROR: could not insert 'acpi_call': Operation not permitted。一个解决方法是禁用安全启动或手动签名模块;参考例如https://askubuntu.com/questions/1114867。 - Fred Schoen
这是适用于我的ThinkPad E15 Gen3(2021)与Ubuntu 22.04的解决方案。 - alierdogan7

  1. 安装TLP
    sudo add-apt-repository ppa:linrunner/tlp
    sudo apt update
    sudo apt install tlp
    
    # 检查电池所需的软件包:
    sudo tlp-stat -b
    
    # 如果推荐使用acpi_call
    sudo apt install acpi-call-dkms
    
    # 如果推荐使用smapi
    sudo apt install tp-smapi-dkms
    
  2. 打开TLP的配置文件
    sudo gedit /etc/tlp.conf
    
  3. 找到有关电池设置的行,删除注释符号前的 #,并可能插入您想要的值
    START_CHARGE_THRESH_BAT0=75
    STOP_CHARGE_THRESH_BAT0=80
    
  4. 重新启动tlp
    sudo tlp start
    
  5. 检查配置状态
    sudo tlp-stat -b
    

在我的ThinkPad上,配置文件位于/etc/default/tlp。 - xuancong84
1我的设置是 START_CHARGE_THRESH_BAT0=60 STOP_CHARGE_THRESH_BAT0=81 当我插上充电器时,电池电量达到80%就停止充电。一切都符合预期。但是下限范围是如何工作的呢?插上充电器后,电量始终保持在80%不变。 - Jekson
这个只适用于Thinkpad吗?它能在Toshiba Satellite上工作吗? - Gabriel Staples
3适用于运行Ubuntu 21.10的Thinkpad L490。在第3步之后,运行以下命令以在重启后启用该服务:systemctl enable tlp.service - Ron Michael

在我的Toshiba R830上运行Windows 8.1,我安装了Toshiba Power Saver应用程序,以便将电池充电限制在80%。
当我启动Linux(Ubuntu,Mint等)时,最大充电仍然被限制在80%。
因此,Toshiba Power Saver似乎将其配置存储在BIOS中。
唯一的缺点是,如果我想带着充满电的电池旅行,我必须重新启动到Windows并更改Power Saver的配置。

1欢迎来到AskUbuntu!你的结果似乎与Ubuntu无关。你能否用与本网站相关的术语重新表达你的回答?谢谢! - Elder Geek
17你好,Elder Geek。这是与BIOS相关的内容,因此可以在双系统启动配置下适用于任何操作系统。 这个Toshiba BIOS配置无法通过BIOS菜单访问,只能通过仅在Windows上运行的Power Saver应用程序来进行配置。 - eosphere
2我也是在联想Yoga 3 11英寸上遇到同样的问题。 - ctrl-alt-delor
5Mint的结果显然与Ubuntu有关。 - Stefan Reich
我的Toshiba上没有Windows,只有Ubuntu 20.04。我知道在Windows双启动设置中这是可行的(我在另一台电脑上已经证明过),但我想知道如果我在VirtualBox虚拟机中运行来自Windows 10的Toshiba程序是否也能行得通。有人知道吗? - Gabriel Staples

我有一台华硕笔记本电脑,我从互联网上找到的方法如下。这种方法可能已经是上述某些应用程序的一部分,但这里提供它作为信息。

创建一个名为battery_charge_threshold.service的服务文件,内容如下:
[Unit]
Description=设置电池充电阈值
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold'

[Install]
WantedBy=multi-user.target

将该文件移动到以下位置:/etc/systemd/system 运行以下命令:
sudo chmod 644 /etc/systemd/system/battery-charge-threshold.service
sudo systemctl daemon-reload
sudo systemctl enable battery-charge-threshold.service

这样做后,80%的充电阈值(依据服务文件)将在重新启动之间保持。如果当前电平高于80%,它也会停止充电电池。 希望能有所帮助。我已经使用了将近1.5年而没有任何问题。

有没有办法设置两个阈值,比如start_charge_thresholdstop_charge_threshold?这样我们就可以控制充电的开始和结束。 - Hosein Rahnama
我在ASUS-N580V上使用了这种方法,但是这导致电池异常发热,而当我在Windows上使用ASUS Battery Health Charging时并非如此。 - Hosein Rahnama
1@HoseinRahnama :我在Ubuntu上没有遇到过任何发热问题。我的是ASUS S430UA。对于设置启动阈值的任何技巧/黑科技,我并不了解。 - AjayC
我还有一个问题是,当我连接充电线并将阈值设置为60时,如果电池处于80的状态,操作系统会显示电池未充电,但随着时间的推移,电池并不会降至60。我正在使用Ubuntu 20.04 LTS。 - Hosein Rahnama
是的,我和@HoseinRahnama有同样的问题,我的启动和停止阈值分别为25%和80%,但当充电器插入时,我的电池仍然停留在59%。系统显示没有进行充电。编辑:我的操作系统是Ubuntu 18.04。 - scovic
在Ubuntu中没有启动和停止阈值。只有charge_control_end_threshold可用。 - lance2k

在我的戴尔XPS上,我使用sudo apt install smbios-utils安装了smbios-utils软件包。这个软件包提供了一个名为smbios-battery-ctl的命令。从Ubuntu 20.04开始,似乎已经支持基于电池电量的充电控制。所有详细信息都可以在manpage中找到manpage,但是对于基本的80%设置,我认为这将起作用:
sudo smbios-battery-ctl --set-custom-charge-interval 75 80
sudo smbios-battery-ctl --set-charging-mode=custom

当电池电量低于75%时,充电将开始,并在达到80%时停止充电。
要恢复设置,请执行以下操作:
sudo smbios-battery-ctl --set-charging-mode=adaptive

太棒了!这似乎也适用于其他戴尔型号,如Latitude 5420。而且它是开源的 https://github.com/dell/libsmbios/blob/master/src/bin/smbios-battery-ctl - bmaupin
我的Toshiba Satellite C55t-B5109在运行Ubuntu 20.04时程序崩溃了。堆栈跟踪的最后一部分是:File "/usr/lib/python3/dist-packages/libsmbios_c/smbios_token.py", line 145, in __getitem__ raise IndexError(_("SMBIOS Token ID 0x%04x not found") % id ) IndexError: SMBIOS Token ID 0x0349 not found - Gabriel Staples

你有没有检查一下你的笔记本电脑上是否有一个BIOS设置来实现这个功能?我的笔记本电脑上有一个Windows应用程序,以及一个BIOS中的“电池寿命延长器”设置,可以实现这个功能。

3在BIOS设置屏幕中没有这样的选项。 - ændrük

我写了一个命令行应用程序来完成这个任务。
最简单的方法是从发布页面下载该应用,并运行。
$ ./bat --help

在所在目录的终端中运行,应该会显示帮助文档。

如果出现错误,可能与权限有关。以下命令可能会解决问题。

chmod +x ./bat

基本上,跑步。
$ ./bat --threshold

将打印出当前的阈值。
要设置新的阈值,运行以下命令,例如设为60%。
./bat --threshold 60

为了在重新启动之间保持当前的阈值,请运行
sudo ./bat --persist

注意:在幕后,持续使用systemd,但这已经与大多数Linux发行版(包括Ubuntu)捆绑在一起。
提示:将应用程序放在像/usr/local/bin/这样的目录中,该目录位于$PATH中,这将使您能够从任何地方运行它,而不仅仅是在应用程序所在的目录中。然后上述命令变为:
bat --help

bat --threshold 60

bat --persist

分别。


很遗憾,不兼容我的Toshiba Satellite C55t-B5109。运行bat版本0.8.4:命令:./bat --threshold 响应:"这个程序很可能与您的系统不兼容。请参阅https://github.com/tshakalekholoane/bat#disclaimer了解详情。" - Gabriel Staples
1程序的语法已经改变(不需要使用破折号)。 - undefined
无法在联想Ideapad上的Ubuntu 22 LTS上运行 :( - undefined

我刚刚发现了一种适用于戴尔笔记本电脑的硬件黑客方法:
戴尔充电器使用3个引脚,一个用于正极(+),一个用于负极(-),还有一个用于戴尔充电器识别通信(1-Wire协议)的引脚。这个通信线通常位于连接器的中心位置,类似针状的引脚。
如果你切断这个通信线,笔记本电脑将继续从交流电运行,但电池将不再充电。
找到通信线,切断它,在中间加一个开关。尽情充电你的笔记本电脑电池,然后关闭那个开关。你的笔记本电脑将使用交流电,但电池将保持在你离开时的电量。
查看此答案以获取各种情况下推荐的充电水平:https://superuser.com/a/664583/187576

编辑

显然,这种方法的一个缺点是,如果没有识别到充电器,笔记本电脑的性能会下降。
对于正常使用来说,这可能不是一个问题,但如果你需要CPU的强大性能,比如进行3D设计,性能会明显下降。