You are not logged in.

#1 2012-09-21 11:27:20

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

[SOLVED] Udev rule to hibernate my laptop at certain battery level

Hi!
I'm needing this kind of udev rule, to have my laptop automatically hibernate when battery level is about 3% (or 5, it doesn't matter).
I don't want to have a little script running in the background that every eg 5 seconds polls my battery level, because i find it a really rough system.
I guess i can use udev to reach what i want.

udevadm info --path=/sys/class/power_supply/BAT0
P: /devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/PNP0C09:00/PNP0C0A:00/power_supply/BAT0
E: DEVPATH=/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:0f/PNP0C09:00/PNP0C0A:00/power_supply/BAT0
E: POWER_SUPPLY_CHARGE_FULL=4800000
E: POWER_SUPPLY_CHARGE_FULL_DESIGN=4800000
E: POWER_SUPPLY_CHARGE_NOW=4800000
E: POWER_SUPPLY_CURRENT_NOW=0
E: POWER_SUPPLY_CYCLE_COUNT=0
E: POWER_SUPPLY_MANUFACTURER=SANYO
E: POWER_SUPPLY_MODEL_NAME=AS07B32
E: POWER_SUPPLY_NAME=BAT0
E: POWER_SUPPLY_PRESENT=1
E: POWER_SUPPLY_SERIAL_NUMBER= 7210
E: POWER_SUPPLY_STATUS=Full
E: POWER_SUPPLY_TECHNOLOGY=Li-ion
E: POWER_SUPPLY_VOLTAGE_MIN_DESIGN=14800000
E: POWER_SUPPLY_VOLTAGE_NOW=16142000
E: SUBSYSTEM=power_supply

Any help?
Thank you very much!

Last edited by nierro (2012-09-21 20:36:45)

Offline

#2 2012-09-21 11:52:00

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Uhm something like:

SUBSYSTEM=="power_supply", ENV{POWER_SUPPLY_CHARGE_NOW}=="144000", ENV{POWER_SUPPLY_STATUS}=="Discharging", RUN+="/usr/bin/systemctl hibernate"

Where 144000 is 3% of 4800000?
Is this right?
EDIT: i'll test it and let you know smile BTW I guess it should work...
EDIT2: the only thing i'd like to know is whether udev reads this rule as :"when charge_now is <= 144000 do that" or "when charge_now is 144000 ...", ie: if charge_now passes from 145000 to 143000, will udev execute that command?
EDIT3: better udev rule, that checks if laptop is discharging too, to avoid stupid problems. BTW it won't work.

Last edited by nierro (2012-09-21 14:02:12)

Offline

#3 2012-09-21 12:54:23

brebs
Member
Registered: 2007-04-03
Posts: 3,742

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

I would not expect that to work. You're assuming that udev is polling the power supply.

Polling every 5 seconds is far too frequent. How about every 5 minutes?

Offline

#4 2012-09-21 12:56:37

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

I don't understand what did you mean, sorry.

Offline

#5 2012-09-21 13:11:35

cybertorture
Member
Registered: 2010-05-05
Posts: 339

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

I guess berbs talk about

I don't want to have a little script running in the background that every eg 5 seconds polls my battery level, because i find it a really rough system.


O' rly ? Ya rly Oo

Offline

#6 2012-09-21 13:13:02

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Oh, yes sorry. I see it now smile
Btw, i'm testing the rule, may be i'll add it to the wiki, if anyone thinks it can be useful.
EDIT: does anybody know how to use notify-send from within an udev rule? I made something like :

SUBSYSTEM=="power_supply", ENV{POWER_SUPPLY_CHARGE_NOW}<="250000", ENV{POWER_SUPPLY_STATUS}=="Discharging", RUN+="/usr/bin/notify-send 'laptop is going to hibernate soon'"

But nothing appears.

Last edited by nierro (2012-09-21 13:20:24)

Offline

#7 2012-09-21 13:42:36

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

And i found out udev does not read "<=" in my udev rule, because valid operators are (from man udev) :

==
           Compare for equality.

       !=
           Compare for inequality.

       =
           Assign a value to a key. Keys that represent a list are reset and
           only this single value is assigned.

       +=
           Add the value to a key that holds a list of entries.

       :=
           Assign a value to a key finally; disallow any later changes.

In fact it read <= as =, and set my CHARGE_NOW to 144000...this is kind of stupid...and obviously it won't work...
So, how can I achieve what i want to?
EDIT: i'm starting to think that it can't be done through udev...

Last edited by nierro (2012-09-21 14:06:17)

Offline

#8 2012-09-21 17:52:14

cybertorture
Member
Registered: 2010-05-05
Posts: 339

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

I do not know about if udev respond on power level changes, but i m almoust sure that "notify-send" need at least "export DISPLAY=:0"


O' rly ? Ya rly Oo

Offline

#9 2012-09-21 17:57:54

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Thanks, but i'm really hoping someone can help me about the first rule smile

Offline

#10 2012-09-21 18:08:29

cybertorture
Member
Registered: 2010-05-05
Posts: 339

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

as start try to monitor if udev realy periodicaly check for battery charge with

udevadm monitor --subsystem-match=power_supply

O' rly ? Ya rly Oo

Offline

#11 2012-09-21 18:12:03

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Yes, it periodically checks it. The charge_now is updated every sec or 2s, and obviously it's always less...

Offline

#12 2012-09-21 18:22:18

tomk
Forum Fellow
From: Ireland
Registered: 2004-07-21
Posts: 9,839

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Are you aware that acpid is intended for this exact purpose? I know, you're using systemd now, but I'm sure you would agree that its power management capabilities are fairly basic so far - systemd is not even close to being a complete replacement in this area.

Offline

#13 2012-09-21 18:26:49

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Yes, i know. But since i'm using an udev rule to exec my powersave script whether i'm on ac or on battery, i'd like not to use acpid (and I don't like acpid too).
I think this udev rule can be done someway, i just need to find the right way...

Offline

#14 2012-09-21 19:02:41

tomk
Forum Fellow
From: Ireland
Registered: 2004-07-21
Posts: 9,839

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

nierro wrote:

Yes, it periodically checks it. The charge_now is updated every sec or 2s, and obviously it's always less...

So udevadm monitor is showing you periodic uevents corresponding to the reducing battery charge? It doesn't do that here.

Offline

#15 2012-09-21 19:04:41

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Uhm, no, i was referring to this:

udevadm info --path=/sys/class/power_supply/BAT0 | grep CHARGE_NOW; sleep 5; udevadm info --path=/sys/class/power_supply/BAT0 | grep CHARGE_NOW;
E: POWER_SUPPLY_CHARGE_NOW=4587000
E: POWER_SUPPLY_CHARGE_NOW=4585000

As you can see, CHARGE_NOW is always decreasing.

Last edited by nierro (2012-09-21 19:10:28)

Offline

#16 2012-09-21 19:35:40

tomk
Forum Fellow
From: Ireland
Registered: 2004-07-21
Posts: 9,839

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Well, yeah - but udev needs a uevent to trigger a rule. What you're doing there is just polling the battery level, no better than the script that you said you don't want running in the background.

Offline

#17 2012-09-21 19:37:10

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Well, but this is not an external script. It is udev... it does it anyway (polling the battery level, i mean), i only check if the level is == to what i want...else it won't do anything.

Offline

#18 2012-09-21 20:15:52

tomk
Forum Fellow
From: Ireland
Registered: 2004-07-21
Posts: 9,839

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

It is indeed udev, displaying device info from its database in response to a query - that's what 'udevadm info' does. But you can't write a udev rule against that info - you need a uevent.

man udev wrote:

The udev daemon, systemd-udevd.service(8), receives device uevents directly from the kernel whenever a device is added or removed from the system, or it changes its state. When udev receives a device event, it matches its configured set of rules against various device attributes to identify the device. Rules that match may provide additional device information to be stored in the udev database or to be used to create meaningful symlink names.

If you run cybertorture's 'udevadm monitor' command above, as your battery is running down, you will not see any uevents. If you connect or disconnect your AC adapter, you will see uevents - in fact, you're using those ones already, to trigger your powersave script. So although the general description I've quoted mentions kernel uevents generated when a device "changes its state", this does not cover all possible changes, and in this particular case, it does not cover changes in battery charge level.

Offline

#19 2012-09-21 20:36:07

nierro
Member
From: Milan, Italy
Registered: 2011-09-02
Posts: 849

Re: [SOLVED] Udev rule to hibernate my laptop at certain battery level

Ok. Thanks then, i 'll consider this as solved.
Thank you all very much.

Offline

Board footer

Powered by FluxBB