You are not logged in.
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
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 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
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
I don't understand what did you mean, sorry.
Offline
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
Oh, yes sorry. I see it now
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
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
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
Thanks, but i'm really hoping someone can help me about the first rule
Offline
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
Yes, it periodically checks it. The charge_now is updated every sec or 2s, and obviously it's always less...
Offline
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
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
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
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
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
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
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.
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
Ok. Thanks then, i 'll consider this as solved.
Thank you all very much.
Offline