TLP icon indicating copy to clipboard operation
TLP copied to clipboard

Support power-profiles-daemon API

Open ryanabx opened this issue 1 year ago • 11 comments

Is your feature request related to a problem? Please describe.

The problem I face is wanting to have the power savings of tlp with the nice interface that DEs provide with power-profiles-daemon.

Describe the solution you'd like

An API could be implemented that takes calls to change the power profile in ppd and changes to a relevant profile in tlp instead. Since ppd is already recommended to be uninstalled, this would be non-intrusive to a user using tlp, and would allow tlp to hook into the UI components created by GNOME and KDE to control power profiles.

Describe alternatives you've considered

There is a project called TuneD which provides custom configuration profiles similar to tlp, and is implementing the power-profiles-daemon API due to a proposal to replace it with ppd in Fedora, see: https://discussion.fedoraproject.org/t/f40-change-proposal-tuned-replaces-power-profiles-daemon-self-contained/94995 Also see relevant PR: https://github.com/redhat-performance/tuned/pull/579

ryanabx avatar Dec 15 '23 04:12 ryanabx

Hi, thanks for your suggestion.

However, there is a major obstacle: TLP is not implemented as a daemon [1], but in my opinion such a daemon would be required for a DBUS API.

[1] https://linrunner.de/tlp/developers/architecture.html

linrunner avatar Dec 15 '23 08:12 linrunner

Hi, thanks for your suggestion.

However, there is a major obstacle: TLP is not implemented as a daemon [1], but in my opinion such a daemon would be required for a DBUS API.

[1] https://linrunner.de/tlp/developers/architecture.html

Thank you for your response! I think you're right that it's probable that a daemon would be required, since that's how ppd is currently implemented. As such it's probably out of scope for this project. I appreciate your work with tlp by the way!

ryanabx avatar Dec 17 '23 08:12 ryanabx

Indeed, a daemon of some kind is required to implement the API. But it would make sense to implement as a separate, mostly independent, systemd service, to be enabled only if needed. (Or maybe just use the feature of systemd where it can register on dbus and start the daemon only when someone connects)

tbodt avatar Jan 11 '25 19:01 tbodt

@linrunner Are you open to adding a python script to the project? If not...well, bash is one of the few languages you can't write a dbus service in, but I can rewrite it in pretty much any other language.

tbodt avatar Jan 12 '25 02:01 tbodt

@tbodt A daemon just for the user interface for profile selection seems too short-sighted to me. A daemon would have to keep track of the system state and therefore be aware of all events as well as command line actions.

Since the daemon has to run with root privileges to write the tunables on the one hand, and is accessed via the DBUS API with user privileges on the other, there are security concerns to address.

Then there is the question of how to map three power profiles to TLP, which only recognises two. We need to decide how to combine the manual switching of power profiles in the daemon API with the automatic profile selection of TLP.

I don't think it's appropriate to just quickly build a daemon for one subtask.

To clarify: I'm not averse to the idea, but the result would basically be a rewritten TLP.

I see a particular challenge in not losing the users on this great journey.

linrunner avatar Jan 14 '25 17:01 linrunner

Re tracking all system state: Is it not enough to watch for changes to /run/tlp/last_pwr?

Re root privilege: Yeah, seems like it has to become a security boundary. But it's not different from the way power-profiles-daemon itself operates, and if they have it working TLP can too.

Re three power profiles, the PPD API is able to dynamically report that there are only two profiles. There is also the option of repurposing "balanced" as automatic selection.

tbodt avatar Jan 14 '25 18:01 tbodt

I'm currently quite busy with the 1.8 beta test. I'll get back to you as soon as I have time for a proper answer.

linrunner avatar Jan 24 '25 22:01 linrunner

@tbodt sorry for the long delay.

I would say start with implementing your suggestion. Too many users want it. Here's another one: https://github.com/linrunner/TLP/issues/787

However, I would like to start it separately from the main project in its own repository, working title TLP-PD. I hope that's OK for you.

I assume that we need three profiles. I'll think about that separately and start a user survey to design it.

linrunner avatar Mar 01 '25 17:03 linrunner

Separate repo does make sense. In the end it likely should become a separate package in distros anyway.

Are you planning to do it, or would you like me to try? I have a bunch of half finished python code which I haven't worked on since my first comment here.

tbodt avatar Mar 01 '25 17:03 tbodt

I don't speak Python yet, but I've been wanting to start learning it for years. So you have to start ...

linrunner avatar Mar 01 '25 17:03 linrunner

I went and pushed the code I've been writing in the TLP repo so far to a branch over here: https://github.com/tbodt/TLP/commit/fd67ee6d2575fef9ec4de6963558f5c025138337. It's more of a stub, it doesn't talk to TLP yet, but KDE's widget does connect to it at least. TODO move it out to its own repo

tbodt avatar Mar 02 '25 22:03 tbodt

@tbodt Is it intentional that tlp-ppd.policy is installed twice under its original name and modified by sed each time? Shouldn't this happen in the loop as $(BUS_NAME).policy?

https://github.com/tbodt/TLP/blob/ppd/Makefile#L215

linrunner avatar Mar 23 '25 17:03 linrunner

Yes, thanks for pointing that out. But I should also check if it actually has to be installed twice. power-profilers-daemon just installs once.

tbodt avatar Mar 23 '25 19:03 tbodt

Uninstall of .policy, .conf and .service is missing as well.

linrunner avatar Mar 23 '25 20:03 linrunner

Updated. It looks like it's fine to just install one polkit file, that's not an external interface and is just a way for tlp-ppd to ask polkit whether the request comes from an interactive user.

The actual polkit authorization request is implemented with some internals of pydbus, though, because pydbus is unmaintained... TODO pick another dbus library or something. The hard part is finding one that will give you a handle to the sender in property set requests.

tbodt avatar Mar 23 '25 21:03 tbodt

Relating to the number of profiles, the protocol is in theory highly flexible and would support any set of profiles with any name, but unfortunately KDE Powerdevil (at least) behaves somewhat strangely when the returned set of profiles is different from the 3 that power-profiles-daemon returns.

tbodt avatar Mar 24 '25 05:03 tbodt

@tbodt I would prefer that we call the daemon tlp-pd (“TLP Profiles Daemon”) instead of tlp-ppd. I'd like to avoid having the competition in the name. Please also rename your repo to TLP-PD, otherwise I can't fork it and send you changes ... ;-)

linrunner avatar Mar 24 '25 14:03 linrunner

Relating to the number of profiles, the protocol is in theory highly flexible and would support any set of profiles with any name, but unfortunately KDE Powerdevil (at least) behaves somewhat strangely when the returned set of profiles is different from the 3 that power-profiles-daemon returns.

I think users will insist on three profiles anyway, simply because they are used to it from ppd. We might as well call them power-saver, balanced and performance as ppd does.

My (tricky) task is to figure out how to map this to AC/BAT plus “something” in TLP.

linrunner avatar Mar 24 '25 14:03 linrunner

My (tricky) task is to figure out how to map this to AC/BAT plus “something” in TLP.

When I thought about this last time I imagined that you could change 0/1 function arguments to be AC/BAT, expand those directly into the variable name, and now it's possible to make as many profiles as you want by changing the last word of the settings variable. But talk is cheap.

tbodt avatar Mar 24 '25 15:03 tbodt

@tbodt I would prefer that we call the daemon tlp-pd (“TLP Profiles Daemon”) instead of tlp-ppd. I'd like to avoid having the competition in the name. Please also rename your repo to TLP-PD, otherwise I can't fork it and send you changes ... ;-)

I've renamed the repo and also added you as a committer.

tbodt avatar Mar 24 '25 15:03 tbodt

I've renamed the repo and also added you as a committer.

Thank you for your trust. I think I'll send you oldschool pull requests for the time being.

linrunner avatar Mar 24 '25 15:03 linrunner

@tbodt GitHub doesn't let me fork your repository, perhaps because it is forked from TLP.

I think it can't be avoided that you set up only your contribution, i.e. what is necessary for TLP-PD as a new repository without the whole history of TLP. Delete the TLP-PD repository on GitHub beforehand.

So in the first approach LICENSE (GPL2), COPYING (you as author) and Makefile plus your stuff.

You can leave the Makefile as it is for now, and I'll strip it down.

linrunner avatar Mar 24 '25 16:03 linrunner

I'll try that this evening.

tbodt avatar Mar 24 '25 17:03 tbodt

Take your time. We're not in a hurry, aren't we?

linrunner avatar Mar 24 '25 17:03 linrunner

Just got around to it :) https://github.com/tbodt/TLP-PD. I also stripped down the makefile so it still actually works.

tbodt avatar Mar 27 '25 06:03 tbodt

Well. I just sat down trying to understand the Makefile and the BUS_NAME replacements there and I don't get it (yet):

  1. There is a loop for BUS_NAME over org.freedesktop.UPower.PowerProfiles net.hadess.PowerProfiles creating two renamed copies each of tlp-pd.dbus.conf and tlp-pd.dbus.service and also doing the replacements for @BUS_NAME@.
  2. There is an instance of @BUS_NAME@ in tlp-pd.service.in which is replaced by the $(INFILES) target.
  3. But tlp-pd contains three instances of @BUS_NAME@ that are replaced nowhere - is this intended?
  4. Do we really need both interfaces org.freedesktop.UPower.PowerProfiles and net.hadess.PowerProfiles?

linrunner avatar Mar 30 '25 17:03 linrunner

  1. But tlp-pd contains three instances of @BUS_NAME@ that are replaced nowhere - is this intended?

It is replaced at the bottom in python code before bus.publish.

  1. Do we really need both interfaces org.freedesktop.UPower.PowerProfiles and net.hadess.PowerProfiles?

Sadly, yes...because the PowerProfiles project changed ownership and changed the interface name along with that. But some clients still use the old name, so they have to keep both working.

tbodt avatar Mar 30 '25 18:03 tbodt

@tbodt I have been thinking quite some time about how to map profiles. My proposal is that we implement three profiles:

04.07.2025 Spec updated

Profile Command Config Used Remarks
performance tlp performance *) _AC
balanced tlp balanced *) _BAT
power-saver tlp power-saver _SAV, _BAT In the first step there is not a full set of _SAV parameters, only the small subset ppd does atm -> https://linrunner.de/tlp/faq/ppd.html. For the rest, power-saver uses _BAT.

The profile commands do not enter manual mode, automatic switching remains active.

*) I deliberately do not employ tlp ac/batso that the behavior may be changed later if necessary.

linrunner avatar Apr 18 '25 12:04 linrunner

@tbodt smart-ass question (sorry) from someone with no Python experience about the D-BUS library used: pydbus has not been developed on for 7 years. Of the alternatives listed here, only python-sdbus seems to be alive.

I'm unable to decipher what tuned-ppd uses.

linrunner avatar Apr 18 '25 13:04 linrunner

Seems like GNOME 48 does not support arbitrary profiles, only performance, balanced, power-saver ... :-(

So how do to disable manual mode then?

linrunner avatar Apr 18 '25 13:04 linrunner