treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

Linux(Debian)でのバッテリ充電制御 on ThinkPad

前回「Linux(Debian)でバッテリ状態を確認する。 - treedown’s Report」にてバッテリの稼働状態などを確認するコマンドをやってみたのですが、今回は実際にバッテリを設定する機能を導入してみたのでご報告です。

例によって環境はDebian buster(10.8)をインストールしたThinkPad X40という環境です。

必要なソフトウェアのインストール

DebianパッケージからpowertopとTLPをインストールします。

~$ sudo apt-get install powertop

を実行すると、powertopは既にインストールされていました。

f:id:treedown:20210517200012p:plain
続いて、

~$ sudo apt-get install tlp tlp-rdw

を実行。依存関係にあるパッケージが同時にインストールされました。

f:id:treedown:20210517200033p:plain

今回は、TLPを主に使っていきます。

無事インストールは完了。

tlpで充電制御の設定箇所を確認

設定ファイルは「/etc/default/tlp」を編集。

※Ubuntu20以降やLinuxMint20などで設定している他の情報では「/etc/tlp.conf」を編集する、という情報もあり。OSやTLPのバージョンによって設定箇所は異なる模様。もしくは、touchコマンドで「/etc/tlp.conf」を生成して設定したい箇所だけ書き込むことによって、不足分は「/etc/default/tlp」から設定項目を読み込んでくれる、という仕様なのかも(未確認)

ファイルの編集箇所は、デフォルトでコメントアウトされている以下の箇所。
--------------------------------------------------------------
$ cat /etc/default/tlp | grep CHARGE_THRESH_
#START_CHARGE_THRESH_BAT0=75
#STOP_CHARGE_THRESH_BAT0=80
#START_CHARGE_THRESH_BAT1=75
#STOP_CHARGE_THRESH_BAT1=80
--------------------------------------------------------------
「START_CHARGE_THRESH_BAT0=75」は充電を開始する%を数字で指定する箇所。省電力マネージャーで言えば、

f:id:treedown:20210517200109p:plain
この部分、「このレベルより低くなると充電を開始」の設定箇所に該当します。
※注)上記はWindows省電力マネージャーの画面であって、LinuxのTLPでこの画面が表示できるわけではありません。

「STOP_CHARGE_THRESH_BAT0=80」は充電を停止する%を数字で指定する箇所。上記と同じく省電力マネージャーで言うところの、

f:id:treedown:20210517200123p:plain
この部分、「このレベルで充電を停止」の設定箇所に該当します。
デフォルトだと、「75%以下で充電開始、80%で充電を停止する」ようになっているようです。

次の「START_CHARGE_THRESH_BAT1=75」と「STOP_CHARGE_THRESH_BAT1=80」は、複数バッテリを搭載している場合に、省電力マネージャーだと、

f:id:treedown:20210517200141p:plain
ここでバッテリ1 / バッテリ2 を選んで個別に設定値を入れることができるのですが、そのバッテリ種別(プライマリバッテリとセカンダリバッテリ)のうちのセカンダリバッテリを指しています。
Lenovo Vantageでも複数のバッテリを搭載しているThinkPadでは

f:id:treedown:20210517200158p:plain
このように二つのバッテリが個別に表示され、個別に設定が可能です。

tlpで充電制御の設定をやってみる

まずtlpのコマンドでバッテリ状態を見てみます。
コマンドは
$ sudo tlp-stat -b
と実行、すると

f:id:treedown:20210517200227p:plain
詳細なバッテリ情報が表示されます。前回同様消耗したバッテリなので100%充電されていますが、劣化によって新品状態の13.8%しか使えないような状態になっていることが分ります。
さっそく設定を、コマンドは
$ sudo vi /etc/default/tlp
で、エディタ起動。
起動後に、コメントアウトされている設定箇所に追記
--------------------------------------------------------------
省略~

# Battery charge thresholds (ThinkPad only, tp-smapi or acpi-call kernel module
# required). Charging starts when the remaining capacity falls below the
# START_CHARGE_THRESH value and stops when exceeding the STOP_CHARGE_THRESH value.
# Main / Internal battery (values in %)
#START_CHARGE_THRESH_BAT0=75
#STOP_CHARGE_THRESH_BAT0=80
START_CHARGE_THRESH_BAT0=50
STOP_CHARGE_THRESH_BAT0=80

# Ultrabay / Slice / Replaceable battery (values in %)
#START_CHARGE_THRESH_BAT1=75
#STOP_CHARGE_THRESH_BAT1=80

--------------------------------------------------------------

差が無いと分りにくいため50%で充電開始、80%で充電停止、となるよう設定をしました。

設定の適用に
$ sudo systemctl restart tlp
プロセスリスタート。

実際にバッテリを減らして充電

ここで充電制御が効くかどうかを確認するため、しばらくバッテリ駆動。
劣化したバッテリなので、秒単位で充電した電力を消費していきます。
いったん一桁まで減ったところで、再度充電開始。
--------------------------------------------------------------
$ acpi -i
Battery 0: Charging, 8%, 00:19:02 until charged
Battery 0: design capacity 1632 mAh, last full capacity 224 mAh = 13%
--------------------------------------------------------------
これでしばらく、充電させてみます。
--------------------------------------------------------------
$ acpi -b
Battery 0: Charging, 19%, 00:25:39 until charged
--------------------------------------------------------------
Battery 0: Chargingの状態表示が指定した80%で停止すれば充電制御は成功と言うことになります。しばらく待ちます。
--------------------------------------------------------------
$ acpi -b
Battery 0: Unknown, 79%
--------------------------------------------------------------
充電完了、1%は誤差です。詳細を見てみると、
--------------------------------------------------------------
$ sudo tlp-stat -b
--- TLP 1.1 --------------------------------------------

+++ ThinkPad Battery Features
tp-smapi = inactive (kernel module 'tp_smapi' not installed)
tpacpi-bat = inactive (unsupported hardware)

+++ Battery Status
/sys/class/power_supply/BAT0/manufacturer = SANYO
/sys/class/power_supply/BAT0/model_name = IBM-92P0998
/sys/class/power_supply/BAT0/cycle_count = (not supported)
/sys/class/power_supply/BAT0/energy_full_design = 27360 [mWh]
/sys/class/power_supply/BAT0/energy_full = 3770 [mWh]
/sys/class/power_supply/BAT0/energy_now = 3010 [mWh]
/sys/class/power_supply/BAT0/power_now = 0 [mW]
/sys/class/power_supply/BAT0/status = Unknown

Charge = 79.8 [%]
Capacity = 13.8 [%]
--------------------------------------------------------------
充電が79.8%まで到達したところでstatus = Unknownとなっており、充電が停止していることが分ります。

これで、Linuxでも(Debian系なら)省電力マネージャーのように充電制御ができるということが確認できました。

※これ以降は、やってみて当方の環境では上手く動作しませんでしたが、備忘録として記載しています。

TIPS:一時的に充電制御設定変更

tlpコマンドはいくつものオプションがあります。(以下)

Usage: tlp start|true|bat|false|ac|usb|bayoff|discharge|setcharge|fullcharge|recalibrate|stat|diskid

statはこれまでで-bオプションで(ちなみに-cオプションで設定一覧を画面表示できます。)使いましたが、この他で役に立ちそうなオプションをご紹介。まずsetchargeを。

ここまでは恒久的な充電制御設定として、「/etc/default/tlp」を編集して設定を適用させましたが、OS起動後にコマンドを実行して一時的に充電閾値の設定を変更することもできます。
コマンドは、例えば、60%-85%(60%切ったら充電、85%で充電停止)に設定したい場合、

$ sudo tlp setcharge 60 85

と実行。
すると、
--------------------------------------------------------------
$ sudo tlp setcharge 60 85
Setting temporary charge thresholds for BAT0:
start = 60 (no change)
stop = 85 (no change)
--------------------------------------------------------------
という具合に、一時的に設定を入れることができます。

しかし当方の環境では、

--------------------------------------------------------------
~$ sudo tlp setcharge 60 85
Error: ThinkPad battery features not available.
--------------------------------------------------------------

エラーになっちゃいました。なぜだろう(後述)。

TIPS:一時的に満タン充電実行

省電力マネージャーと違って、充電制御の設定を入れていても、モバイルで持ち出す直前に一時的に満タン充電をしたいことがあります。
省電力マネージャーの時は設定値を手動で変更して一時的に充電をしますが、TLPの場合には一時的に満タンにするコマンドを実行することで充電設定値を変更せずに満タン充電をさせることができます。これは便利そう。

前述の80%まで充電できた状態から試してみました。
コマンドは、

$ sudo tlp fullcharge

と実行。

しかし当方の環境では、

--------------------------------------------------------------
~$ sudo tlp fullcharge
Error: ThinkPad battery features not available.
--------------------------------------------------------------

エラーになっちゃいました。

両方エラーになってしまったのは、Debianの標準リポジトリにあるtlpのバージョンが古いから、なのかも。
今回の環境は、
--------------------------------------------------------------
~$ dpkg --list | grep tlp
ii tlp 1.1-2 all Save battery power on laptops
ii tlp-rdw 1.1-2 all Radio device wizard
--------------------------------------------------------------
バージョン1.1-2なのですが、1.2.2なら動作するということかも。機種(正確にはバッテリの世代だと思う)によってtlpバージョン依存で正常動作する/しないがあるようなので、フル機能正常に使うには、Ubuntuユーザが「sudo add-apt-repository ppa:linrunner/tlp」とリポジトリを追加しているように、手を入れないといけないのかも。