linrunner / TLP

TLP - Optimize Linux Laptop Battery Life
https://linrunner.de/tlp
GNU General Public License v2.0
2.69k stars 128 forks source link

[Dell] Battery Wear Control #379

Open hyperfekt opened 5 years ago

hyperfekt commented 5 years ago

EDIT by @linrunner

The wait is over: an initial version of the Dell plugin is ready to test. Kernel 6.11 is required. Testing instructions -> https://github.com/linrunner/TLP/issues/379#issuecomment-2394182769

=============================================================================================== My understanding is that currently only ThinkPad devices have advanced battery features available, due to the existence of tp_smapi. For Dell devices there exists the 'Dell Command | Configure' which appears to provide similar functionality in regards to battery management, for example running off AC power and express charging, even though the interface is rather suboptimal. That's all the more reason to build a tool for it, but the question is if it should be this one.

linrunner commented 5 years ago

These are Windows binaries, dear. If you want things moving, implement a kernel interface e.g. driver for your hardware. See: https://github.com/linrunner/TLP/issues/321

hyperfekt commented 5 years ago

I'm afraid you are mistaken, there are Linux binaries available as well: https://www.dell.com/support/article/us/en/04/sln311302/dell-command-configure?lang=en

linrunner commented 5 years ago

I see.

--PrimaryBattChargeCfg seems do to charge thresholds. Did you spot something like force_discharge (for recalibration)?

Contras:

linrunner commented 5 years ago

Yesterday I stumbled over smbios-utils: https://github.com/dell/libsmbios/ Any volunteers to check out and document how to use it? Command line args are a bit cryptic.

ps. I don't have Dell hardware within reach.

spockfish commented 5 years ago

My daily machine is a Dell XPS running openSUSE with TLP. So what do you exactly need?

linrunner commented 5 years ago

General question: are Dell battery features similar enough to the ThinkPad approach so one can integrate them into the existing TLP commands (setcharge/discharge/recalibrate):

spockfish commented 5 years ago

Ok. I've got the latest smbios installed. It's shipped with openSUSE, so that's the good news. The bad news is that I get nothing out of it. For example, a 'sudo smbios-battery-ctl --battery-charge' results in this:

Libsmbios version : 2.4.2
smbios-battery-ctl version : 2.4.2

 Supported battery charging features: 
         NIL

 Battery charging Status: 
         NIL

No difference what so ever with AC plugged in or not. So I'm not sure if this libsmbios is actually bringing something to the table...

linrunner commented 5 years ago

Dead end? Just for the record: could you post the output of

tlp-stat -s
marmistrz commented 5 years ago

As for the first three points: the relevant option is described in the manual here As for the last two points, I can't find anything that would allow it.

I'm also getting NILs from smbios, I'm going to report it in the libsmbios repository.

In any case, smbios-battery-ctl is pretty low-level could do the trick, but on the other hand, I'm not sure if it wouldn't conflict with the BIOS settings.

$ tlp-stat -s                                                                              
--- TLP 1.2.2 --------------------------------------------

+++ System Info
System         = Dell Inc.  Vostro 3580
BIOS           = 1.0.0
Kernel         = 4.19.45-1-lts #1 SMP Wed May 22 13:02:41 CEST 2019 x86_64
/proc/cmdline  = BOOT_IMAGE=/vmlinuz-linux-lts <mount-related options>
Init system    = systemd 
Boot mode      = UEFI

+++ TLP Status
State          = enabled
RDW state      = enabled
Last run       = 02:29:23,      8 sec(s) ago
Mode           = battery
Power source   = battery
linrunner commented 5 years ago

Thanks. Just for the record:

cctk --PrimaryBattChargeCfg=Custom:50-70

marmistrz commented 5 years ago

/remark: the reply was substantially edited

On the other hand, I have second thoughts about introducing a proprietary opt-dependency to tlp.

It appears that smbios already exposes the API using the low-level token API: token_list.csv Still

# smbios-token-ctl -i 0x0349

prints the token as a bool, which is clearly invalid

================================================================================
  Token: 0x0349 - Primary Battery Custom Charge Start (NA)
  value: bool = false
   Desc: Sets the percentage value at which the battery charging will start Impl
         ementation Note: This field must be in the range [50, 95] with a step v
         alue of 1 and at least 5% less than Primary Custom Charge End

Trying to access the token directly using the Python bindings is weird but feasible - they numeric values are encoded as 2-byte little-endian integers.

# ipython
In [1]: from libsmbios_c import smbios_token                                                                                                                                                  
In [2]: t = smbios_token.TokenTable()  
In [3]: tok = t[0x0349]       
In [7]: tok.getString()                                                                                                                                                                       
Out[7]: b'2\x00'
In [9]: tok.getType()                                                                                                                                                                         
Out[9]: 218
In [10]: tok.isBool()             # What the hell?                                                                                                                                                              
Out[10]: True
In [11]: tok.isString()                                                                                                                                                                       
Out[11]: True 
In [20]: int.from_bytes(tok.getString(), "little")                                                                                                                                      
Out[20]: 50
In [21]: int.from_bytes(t[0x034A].getString(), "little")                                                                                                                                      
Out[21]: 90

Probably the best idea would be to contribute the API to smbios-battery-ctl and only use the shell tool through tlp.

While I can't guarantee code contributions to this one (I'll see what I can do), I can promise I'll test the changes related to power-management on Dell laptops.

For reference, here's the issue about smbios-battery-ctl returning NILs: https://github.com/dell/libsmbios/issues/71

linrunner commented 5 years ago

However, i'm not going to include code that calls a proprietary tool.

ps. and i would definitely prefer a kernel solution that uses the natacpi framework laid out in #321.

marmistrz commented 5 years ago

On the other hand, I have second thoughts about introducing a proprietary opt-dependency to tlp.

However, i'm not going to include code that calls a proprietary tool. ps. and i would definitely prefer a kernel solution that uses the natacpi framework laid out in #321.

What I meant was that cctk is proprietary and that I think it may be a bad idea to depend on it ;) It's great that we agree on this. :)

So we can either use libsmbios (GPL2) or natacpi. It looks like I've already solved the major obstacles, so I think I can extend smbios-battery-ctl to support PrimaryBatteryChargeCfg during the weekend.

I won't be able to help with natacpi in any other way than testing. You may consider contacting the Dell developers. (I'm not affiliated with Dell in any way, I'm just using a laptop produced by the company)

marmistrz commented 5 years ago

@linrunner let me know if you're ok with this CLI

marmistrz commented 5 years ago

@linrunner the pull request to dell/libsmbios has been merged. You can now use it to implement tlp fullcharge and tlp setcharge on Dell laptops.

linrunner commented 5 years ago

OK, then let's get started.

I'll need a bit more than just the description of the CLI because the routines in func.d/35-tlp-func-batt do a lot of checks before actually writing anything - and I don't have the hardware of course ...

I need the exact commands and their corresponding outputs / return codes for the following:

(1) Is libsmbios installed and is it supporting the new CLI?

OK, i'll guess we just have to check for smbios-battery-ctl in the PATH.

(2) Does the laptop actually support thresholds?

(3) Reading the thresholds

(4) Writing the thresholds (+ what happens with invalid param values?)

(5) Checking for batteries: are Dell laptops BAT0 only or are there models with two batteries?

For reference: I'll call the feature dellsm in TLP.

userofryzen commented 5 years ago

What happened here? I was very interested in this work as I am thinking in buying a dell device

awehrfritz commented 4 years ago

For reference: I'll call the feature dellsm in TLP.

@linrunner and @marmistrz: did you start implementing this somewhere? For instance, is there a branch that contains the initial pluming for using smbios rather than one of the kernel modules?

I have a Dell Latitude laptop that supports setting the thresholds in the bios or via the cctk utility and I would be interested in getting this to work in TLP.

marmistrz commented 4 years ago

Sorry, I completely forgot about it. Unfortunately, smbios didn't have a new release after my changes accepted, so you need to patch smbios-battery-ctl manually.

OK, then let's get started.

I'll need a bit more than just the description of the CLI because the routines in func.d/35-tlp-func-batt do a lot of checks before actually writing anything - and I don't have the hardware of course ...

I need the exact commands and their corresponding outputs / return codes for the following:

(1) Is libsmbios installed and is it supporting the new CLI? OK, i'll guess we just have to check for smbios-battery-ctl in the PATH.

You can probably grep smbios-battery-ctl --help

(2) Does the laptop actually support thresholds?

I don't know, but I guess that smbios-battery-ctl would return an error

(3) Reading the thresholds

smbios-battery-ctl --get-charging-cfg

(4) Writing the thresholds (+ what happens with invalid param values?)

smbios-battery-ctl --set-charging-mode X
smbios-battery-ctl --set-custom-charge-interval low high

I don't know what happens if params are invalid.

(5) Checking for batteries: are Dell laptops BAT0 only or are there models with two batteries?

No idea. For all those things I don't know about it's probably best to ask in dell/libsmbios (e.g. through github issues)

See also this fragment from --help.

  --get-charging-cfg    Get the current Primary Battery Charge Configuration
  --set-charging-mode=<MODE>
                        Set the current Primary Battery Charge Configuration.
                        Valid choices are: ['primarily_ac', 'adaptive',
                        'custom', 'standard', 'express']
  --set-custom-charge-interval=<START> <END>
                        Set the percentage bounds for custom charge. Both must
                        be integers. START must lie in the range [50, 95], END
                        must lie in the range [55, 100], END must be at least
                        (START + 5)
linrunner commented 4 years ago

I have no plans to implement this myself. Reasons are:

  1. It's hopeless without a Dell laptop at hand for try and error
  2. I've not enough time
cheng3100 commented 4 years ago

Hi guys, I'm confused by your discussion. I'm thinking of buying a dell laptop. My question is simple. Is the latest version now available to set battery threshold of dell laptops? I only have a thinkpad at hand. Is there anyone who has tested command like smbios-battery-ctl --set-custom-charge-interval low high on a dell machine?

raduburla commented 4 years ago

Hi,

With TLP i don't think something was implemented but you can use dell tools and smbios to change thermal and charge thresholds, I created the above script that I use to change them and it works great on Dell XPS 7590

#!/bin/bash

if [ $# -eq 0 ]
then
 echo "\$0 charge/thermal"
 echo "\$1 value"

 exit 1
fi

if [ $1 = 'charge' ]
then
 if [ $# -eq 1 ]
 then
        echo "a value of: 
                        PrimAcUse, Custom:50-70, 
                        Adaptive, Express, Standard"
        exit 1
 fi

 read -sp "Setup Password:" password

 /opt/dell/dcc/cctk --ValSetupPwd=$password --PrimaryBattChargeCfg=$2
 exit 0
fi

if [ $1 = 'thermal' ]
then
 if [ $# -eq 1 ]
 then
        echo "a value of: 
                        balanced, cool-bottom,
                        quiet, performance"
        /usr/sbin/smbios-thermal-ctl -g
                        exit 1
 fi

 /usr/sbin/smbios-thermal-ctl --set-thermal-mode=$2
 /usr/sbin/smbios-thermal-ctl -g
 exit 0

/opt/dell/dcc/cctk is Dell Command Configure util developed by Dell, you can download a .deb from their website

awehrfritz commented 4 years ago

I have only used the cctk utility a few times and never got to test the libsmbios utilities properly since the version on my system is too old. Also, I don't really need it as I set the thresholds once and use them ever since without modification.

I reckon this will become all much easier once there is support for this in the kernel which is currently work-in-progress, see: https://lkml.org/lkml/2020/7/29/87. There is also an open issue in libsmbios which has some further information, but no progress on the libsmbios side yet since the kernel interface is still missing obviously.

cheng3100 commented 4 years ago

@raduburla Wow, this is very good. Thank you! I think I will get a dell laptop!

cheng3100 commented 4 years ago

@awehrfritz I see it now. Thank you for your link. After some research. I found that the battery threshold is closely related to battery firmware which is much more closesource compared to the host driver. Maybe that is reason why it is so hard to implement.

marmistrz commented 4 years ago

@cheng3100 smbios-battery-ctl --set-custom-charge-interval low high was implemented by me and works on my Dell laptop :P You also need smbios-battery-ctl --set-charging-mode custom

But I'm using it standalone, without tlp.

cheng3100 commented 3 years ago

@marmistrz Thanks, I will try it after my new dell laptop arrive.

bllooi commented 3 years ago

Hi,

With TLP i don't think something was implemented but you can use dell tools and smbios to change thermal and charge thresholds, I created the above script that I use to change them and it works great on Dell XPS 7590

#!/bin/bash

if [ $# -eq 0 ]
then
 echo "\$0 charge/thermal"
 echo "\$1 value"

 exit 1
fi

if [ $1 = 'charge' ]
then
 if [ $# -eq 1 ]
 then
        echo "a value of: 
                        PrimAcUse, Custom:50-70, 
                        Adaptive, Express, Standard"
        exit 1
 fi

 read -sp "Setup Password:" password

 /opt/dell/dcc/cctk --ValSetupPwd=$password --PrimaryBattChargeCfg=$2
 exit 0
fi

if [ $1 = 'thermal' ]
then
 if [ $# -eq 1 ]
 then
        echo "a value of: 
                        balanced, cool-bottom,
                        quiet, performance"
        /usr/sbin/smbios-thermal-ctl -g
                        exit 1
 fi

 /usr/sbin/smbios-thermal-ctl --set-thermal-mode=$2
 /usr/sbin/smbios-thermal-ctl -g
 exit 0

/opt/dell/dcc/cctk is Dell Command Configure util developed by Dell, you can download a .deb from their website

This is actually a super cool script! Would it be possible for you to explain it?

raduburla commented 3 years ago

Hi,

Sure, to use it save it as a .sh file then chmod +x that file. For the bellow examples I use the name of the sh file as dell.sh

The script supports 2 main options that you want to change:

  1. charge - where you set charge thresholds like PrimAcUse, Custom:50-70, Adaptive, Express or Standard For example if you want to set the laptop to Adaptive charge you run it like this:

sudo bash dell.sh charge Adaptive

If you have set a Bios password it will ask for the password. I did not test without a password, if it does not work try replace the following line in the script /opt/dell/dcc/cctk --ValSetupPwd=$password --PrimaryBattChargeCfg=$2 with /opt/dell/dcc/cctk --PrimaryBattChargeCfg=$2 and remove read -sp "Setup Password:" password

  1. thermal - to change the thermal settings of the laptop, like balanced, cool-bottom, quiet or performance For example if you want it to performance you run it like this:

sudo bash dell.sh thermal performance

You will need cctk (https://www.dell.com/support/kbdoc/ro-ro/000178000/dell-command-configure) and smbios (https://github.com/dell/libsmbios) installed

If you get errors you might need to change some Bios configurations. I had to disable some security features from the Bios for the charge settings to work, I can't remember exactly what settings. Can post a list of my actual settings if needed.

Hope this help

linrunner commented 3 years ago

Current state of things is: I would love to support Dell, but not by means of an external tool (or external kernel module). I had my fair share of experience with that in > 10 years on ThinkPads.

So the prerequisite is mainline kernel support for

/sys/class/power_supply/BAT0/charge_control_start_threshold
/sys/class/power_supply/BAT0/charge_control_end_threshold

Let's see what happens here:

zalaps commented 2 years ago

Sorry, I completely forgot about it. Unfortunately, smbios didn't have a new release after my changes accepted, so you need to patch smbios-battery-ctl manually.

Thanks!!!

I've dell vostro originally with Win11. Changed to ubuntu 20.04 LTS with UEFI. TLP is not supported. Following commands worked:

sudo smbios-battery-ctl --set-charging-mode=custom
sudo smbios-battery-ctl --set-custom-charge-interval=50 55
sudo smbios-battery-ctl --get-charging-cfg 
tlvu commented 2 years ago
$ sudo smbios-battery-ctl --get-charging-cfg
Charging mode: custom
Charging interval: (70, 80)

Unplug charger, then the config is lost !

$ sudo smbios-battery-ctl --get-charging-cfg
Charging mode: express

I have smbios-battery-ctl 2.4.3, latest Ubuntu 20.04.3 LTS and I am on a Dell Latitude E6230.

Any idea why the config did not persist?

linrunner commented 2 years ago

@tlvu , @zalaps : Be so kind and stay on topic. The discussion about smbios-battery-ctl does not belong here. Thank you.

zalaps commented 2 years ago

@tlvu , @zalaps : Be so kind and stay on topic. The discussion about smbios-battery-ctl does not belong here. Thank you.

@linrunner Frankly, We found references to smbios-battery-ctl from this thread only. Also, there weren't any request to exclude smbios stuff earlier. Let me know, I would gladly delete the post if required. :)

linrunner commented 2 years ago

@zalaps : no problem, no need to delete. I only wanted to sharpen the topic with my hint :-)

gagath commented 2 years ago

I have asked Dell an update about kernel support on https://github.com/dell/libsmbios/issues/84. FYI the employees working on the driver seem to have left the company 5 months ago, so support for a proper kernel interface might still take a while.

As of today, one has to use smbios-battery-ctl and not rely on TLP for setting battery wear control for Dell devices.

linrunner commented 1 month ago

Light at the end of the tunnel?

https://patchwork.kernel.org/project/platform-driver-x86/patch/20240820033005.09e03af1@5400/

linrunner commented 4 days ago

Released with 6.11 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/platform/x86/dell?id=ab58016c68cc5b8c3622e38b7db64994e4833d9f

Anybody willing to test if I supply a plugin?

AkechiShiro commented 4 days ago

Will see if I can test, thanks a lot for the work done here

EDIT: Sorry read your message a little too fast, I skipped that you needed to write a plugin, will wait for it, thanks !

linrunner commented 3 days ago

@AkechiShiro Wait a minute. I have to write the plugin first. Stay tuned and thanks for your help.

linrunner commented 1 day ago

@AkechiShiro I would need the output of tlp-stat -s -b. Thanks.

AkechiShiro commented 1 day ago

Under Linux 6.11's kernel right ?

EDIT : Is there a specific commit I should use to build tlp befire running this command ?

I'm aware the command is working on the latest release @linrunner

I'll upload the output from the release I have installed at the moment, if that is enough, I'll let you check

linrunner commented 1 day ago

@AkechiShiro if you already run 6.11 then I'd prefer

 grep . /sys/class/power_supply/BAT?/*

Otherwise

tlp-stat -s -b

suffices atm.

linrunner commented 1 day ago

@AkechiShiro You shall/need not build anything atm. Just show the output requested above, works with any recent TLP version. I just need some facts about Dell laptops. Thanks.

AkechiShiro commented 1 day ago

Here is the output :

--- TLP 1.6.1 --------------------------------------------

+++ System Info
System         = Dell Inc.  Latitude 5320
BIOS           = 1.38.0
OS Release     = NixOS 24.05 (Uakari)
Kernel         = 6.6.51 #1-NixOS SMP PREEMPT_DYNAMIC Thu Sep 12 09:11:45 UTC 2024 x86_64
/proc/cmdline  = init=/nix/store/qzl0q13j9xljfkil8qsam3h9jba0z6f8-nixos-system-hostname-24.05.4997.086b448a5d54/init root=fstab loglevel=4
Init system    = systemd 
Boot mode      = UEFI
Suspend mode   = [s2idle]

+++ TLP Status
State          = disabled
RDW state      = not installed
Last run       = unknown
Mode           = unknown
Power source   = AC

+++ Battery Care
Plugin: generic
Supported features: none available

+++ Battery Status: BAT0
/sys/class/power_supply/BAT0/manufacturer                   = SWD-ATL4.175
/sys/class/power_supply/BAT0/model_name                     = DELL 1PP6312
/sys/class/power_supply/BAT0/cycle_count                    =      0 (or not supported)
/sys/class/power_supply/BAT0/charge_full_design             =   4077 [mAh]
/sys/class/power_supply/BAT0/charge_full                    =   1937 [mAh]
/sys/class/power_supply/BAT0/charge_now                     =   1937 [mAh]
/sys/class/power_supply/BAT0/current_now                    =      1 [mA]
/sys/class/power_supply/BAT0/status                         = Full

/sys/class/power_supply/BAT0/charge_control_start_threshold = (not available) 
/sys/class/power_supply/BAT0/charge_control_end_threshold   = (not available) 

Charge                                                      =  100.0 [%]
Capacity                                                    =   47.5 [%]
linrunner commented 1 day ago

The wait is over: an initial version of the Dell plugin is ready to test.

Kernel 6.11 is required.

For the test you either need TLP 1.7.0, supplemented by the download of /usr/share/tlp/bat.d/65-dell, or you can build a package for your distribution based on Branch feature/bat.d/dell.

I need at least the output of

sudo tlp-stat -s -b 

Please also run the automatic test script (with sudo or as root) and show the output: unit-tests/charge-thresholds_dell

It requires the tool clitest to be installed. Should be available as a package in most distributions.

@hyperfekt @cheng3100 @gagath @marmistrz @awehrfritz @zalaps @spockfish @raduburla @AkechiShiro