ฉันจะทำให้แล็ปท็อปของฉันเข้าสู่สถานะแบตเตอรี่ต่ำได้อย่างไร


24

ฉันใช้ Ubuntu แต่ฉันมี i3 เป็นตัวจัดการหน้าต่างแทนสภาพแวดล้อมเดสก์ท็อป

เมื่อแบตเตอรีของฉันถึง 0% คอมพิวเตอร์จะปิดตัวลงทันทีไม่มีการเตือนหรือสิ่งใด

มีสคริปต์หรือการกำหนดค่าอย่างง่ายที่ฉันสามารถตั้งค่าเพื่อให้เข้าสู่โหมดพูดว่าแบตเตอรี่ 4% หรือไม่?

คำตอบ:


12

นี่คือสคริปต์ขนาดเล็กที่ตรวจสอบระดับแบตเตอรี่และเรียกคำสั่งที่กำหนดเองที่นี่pm-hibernateในกรณีที่ระดับแบตเตอรี่ต่ำกว่าขีด จำกัด ที่แน่นอน

#!/bin/sh

###########################################################################
#
# Usage: system-low-battery
#
# Checks if the battery level is low. If “low_threshold” is exceeded
# a system notification is displayed, if “critical_threshold” is exceeded
# a popup window is displayed as well. If “OK” is pressed, the system
# shuts down after “timeout” seconds. If “Cancel” is pressed the script
# does nothing.
#
# This script is supposed to be called from a cron job.
#
###########################################################################

# This is required because the script is invoked by cron. Dbus information
# is stored in a file by the following script when a user logs in. Connect
# it to your autostart mechanism of choice.
#
# #!/bin/sh
# touch $HOME/.dbus/Xdbus
# chmod 600 $HOME/.dbus/Xdbus
# env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
# echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus
# exit 0
#
if [ -r ~/.dbus/Xdbus ]; then
  . ~/.dbus/Xdbus
fi

low_threshold=10
critical_threshold=4
timeout=59
shutdown_cmd='/usr/sbin/pm-hibernate'

level=$(cat /sys/devices/platform/smapi/BAT0/remaining_percent)
state=$(cat /sys/devices/platform/smapi/BAT0/state)

if [ x"$state" != x'discharging' ]; then
  exit 0
fi

do_shutdown() {
  sleep $timeout && kill $zenity_pid 2>/dev/null

  if [ x"$state" != x'discharging' ]; then
    exit 0
  else
    $shutdown_cmd
  fi
}

if [ "$level" -gt $critical_threshold ] && [ "$level" -lt $low_threshold ]; then
  notify-send "Battery level is low: $level%"
fi

if [ "$level" -lt $critical_threshold ]; then

  notify-send -u critical -t 20000 "Battery level is low: $level%" \
    'The system is going to shut down in 1 minute.'

  DISPLAY=:0 zenity --question --ok-label 'OK' --cancel-label 'Cancel' \
    --text "Battery level is low: $level%.\n\n The system is going to shut down in 1 minute." &
  zenity_pid=$!

  do_shutdown &
  shutdown_pid=$!

  trap 'kill $shutdown_pid' 1

  if ! wait $zenity_pid; then
    kill $shutdown_pid 2>/dev/null
  fi

fi

exit 0

มันเป็นสคริปต์ที่ง่ายมาก แต่ฉันคิดว่าคุณเข้าใจและสามารถปรับให้เข้ากับความต้องการของคุณได้อย่างง่ายดาย เส้นทางไปยังระดับแบตเตอรี่อาจแตกต่างกันในระบบของคุณ แบบพกพาอีกเล็กน้อยอาจจะใช้สิ่งที่ต้องการacpi | cut -f2 -d,ได้รับระดับแบตเตอรี่ สคริปต์นี้สามารถกำหนดเวลาโดย cron ให้ทำงานทุกนาที แก้ไข crontab ของคุณด้วยcrontab -eและเพิ่มสคริปต์:

*/1 * * * * /home/me/usr/bin/low-battery-shutdown

วิธีแก้ปัญหาอื่นคือการติดตั้งสภาพแวดล้อมเดสก์ท็อปเช่น Gnome หรือ Xfce (และเปลี่ยนโปรแกรมจัดการหน้าต่างของคุณเป็น i3) ทั้งสภาพแวดล้อม destop ที่กล่าวถึงมี daemons การจัดการพลังงานซึ่งดูแลการปิดเครื่องคอมพิวเตอร์ แต่ฉันคิดว่าคุณจงใจไม่ใช้มันและกำลังมองหาทางออกที่เรียบง่ายกว่า


หืมฉันพยายามวิ่งsleepd -b 40และไม่มีอะไรเกิดขึ้นหลังจากทำเครื่องหมาย 40% ฉันลองsudo sleepd -b 40 -s pm-suspendแล้วและไม่มีอะไรเกิดขึ้น ...
o_o_o

@NoamGagliardi ยืนยันแล้วมันไม่ทำงานที่นี่เหมือนกัน นอกจากนี้แพคเกจดูเหมือนไร้สี ฉันลองถ้าฉันสามารถหาทางเลือกที่ดีกว่าและอัปเดตคำตอบของฉันมิฉะนั้นฉันจะลบมัน
Marco

(TIL " cut") สคริปต์ใช้งานได้! ฉันมีacpi | cut -f2 -d, | cut -f1 d%- ฉันจะอ่าน cron เพื่อให้มันทำงานได้ด้วยตัวเอง ขอบคุณ!
o_o_o--

ฉันไม่มี/sys/devices/platform/smapi/ไดเรกทอรี ฉันจะหาเปอร์เซ็นต์พลังงานแบตเตอรี่ที่เหลือได้จากที่ใด ฉันใช้เคอร์เนลแบบกำหนดเอง 3.10
Martin Vegter

2
@MartinVegter /sys/class/power_supply/BAT0/capacityมันขึ้นอยู่กับฮาร์ดแวร์ของคุณคุณสามารถลอง มิฉะนั้นให้ใช้acpiคำสั่ง
Marco

6

แทนที่จะแฮ็คสคริปต์ของคุณเองและหากคุณใช้ Ubuntu เป็นแท็กแนะนำคุณก็สามารถติดตั้งแพ็คเกจ upower ได้ มันควรจะมีอยู่ในตราสารอนุพันธ์ Debian ทั้งหมดรวมถึง Ubuntu โดยค่าเริ่มต้นมันมาพร้อมกับการกำหนดค่า/etc/UPower/UPower.confที่เปิดใช้งานไฮบริดสลีเมื่อระดับแบตเตอรี่ถึงค่าที่สำคัญ ค่าเริ่มต้นสำหรับระดับวิกฤติคือ 2%

สำหรับผู้ใช้งานของการแจกแจงอื่น ๆ รายการที่เกี่ยวข้องสำหรับ/etc/UPower/UPower.confคือ:

PercentageAction=2
CriticalPowerAction=HybridSleep

คุณสามารถใช้TimeActionร่วมกับUsePercentageForPolicy=falseเพื่อให้การดำเนินการทำได้เพียงครั้งเดียวเท่านั้นที่เหลือเวลา:

TimeAction=120

ค่าที่ถูกต้องสำหรับการCriticalPowerActionมีPowerOff, และHibernate HybridSleepหากตั้งค่า HybridSleep แต่ไม่สามารถใช้งานได้จะใช้ Hibernate หากมีการตั้งค่า Hibernate แต่ไม่พร้อมใช้งาน PowerOff จะถูกใช้

ข้อดีของ HybridSleep คือนอกเหนือจากการเขียนหน่วยความจำลงในพื้นที่สว็อปของคุณแล้วระบบจะหยุดทำงานชั่วคราว การหยุดชั่วคราวจะยังคงใช้แบตเตอรี่บางส่วน แต่ถ้าคุณกลับมาก่อนที่แบตเตอรี่จะหมดคุณสามารถกลับมาทำงานต่อได้อย่างรวดเร็วจากระบบที่ถูกระงับมากกว่าที่จะจำศีล ในกรณีที่แบตเตอรีหมดก่อนที่คุณจะกลับไปยังเต้ารับไฟฟ้าคุณสามารถกลับมาทำงานระบบได้หลังจากไฮเบอร์เนตเมื่อคุณมีพลังงานอีกครั้ง


หมายเหตุ: ฉันคิดว่าHybridSleepต้องมีพื้นที่สว็อป

2
@cipricus ที่ถูกต้อง แต่ upower จะเลือกปิดเครื่องโดยอัตโนมัติหากไม่สามารถจำศีล
josch

2

คำตอบที่ได้รับการยอมรับในขณะนี้นั้นยอดเยี่ยม แต่ค่อนข้างล้าสมัยสำหรับ Ubuntu 16.04:

  • คำสั่งเพื่อรับสถานะแบตเตอรี่มีการเปลี่ยนแปลง
  • ตัวแปรสภาพแวดล้อมที่จำเป็นสำหรับการแจ้งส่งไปทำงานที่มีการเปลี่ยนแปลง
  • สคริปต์ที่ให้ไว้จะไม่มีการทำงานจาก cron ของผู้ใช้อีกต่อไปเนื่องจาก hibernate ต้องการ root
  • systemctl hibernatepm-hibernateเป็นที่ต้องการมากกว่า

ดังนั้นนี่คือสคริปต์ที่ฉันใช้:

#!/usr/bin/env bash

# Notifies the user if the battery is low.
# Executes some command (like hibernate) on critical battery.
# This script is supposed to be called from a cron job.
# If you change this script's name/path, don't forget to update it in crontab !!

level=$(cat /sys/class/power_supply/BAT1/capacity)
status=$(cat /sys/class/power_supply/BAT1/status)

# Exit if not discharging
if [ "${status}" != "Discharging" ]; then
  exit 0
fi


# Source the environment variables required for notify-send to work.
. /home/anmol/.env_vars

low_notif_percentage=20
critical_notif_percentage=15
critical_action_percentage=10


if [ "${level}" -le ${critical_action_percentage} ]; then
  # sudo is required when running from cron
  sudo systemctl hibernate
  exit 0
fi

if [ "${level}" -le ${critical_notif_percentage} ]; then
  notify-send -i '/usr/share/icons/gnome/256x256/status/battery-caution.png' "Battery critical: ${level}%"
  exit 0
fi

if [ "${level}" -le ${low_notif_percentage} ]; then
  notify-send -i '/usr/share/icons/gnome/256x256/status/battery-low.png' "Battery low: $level%"
  exit 0
fi

ตัวแปรสภาวะแวดล้อมที่จำเป็นสำหรับnotify-sendการทำงานถูกสร้างขึ้นโดยใช้สคริปต์นี้ :

#!/usr/bin/env bash

# Create a new file containing the values of the environment variables
# required for cron scripts to work.
# This script is supposed to be scheduled to run at startup.

env_vars_path="$HOME/.env_vars"

rm -f "${env_vars_path}"
touch "${env_vars_path}"
chmod 600 "${env_vars_path}"

# Array of the environment variables.
env_vars=("DBUS_SESSION_BUS_ADDRESS" "XAUTHORITY" "DISPLAY")

for env_var in "${env_vars[@]}"
do
    echo "$env_var"
    env | grep "${env_var}" >> "${env_vars_path}";
    echo "export ${env_var}" >> "${env_vars_path}";
done

ไฟล์นี้จำเป็นต้องเรียกใช้เมื่อเริ่มต้น (สามารถทำได้โดยใช้วิธีการใด ๆ ที่คุณเลือกฉันใช้โปรแกรมเริ่มต้นของ Ubuntu ในตัว)

หมายเหตุ: sudo systemctl hibernateอาจไม่ทำงานจาก cron ทำตามนี้เพื่อแก้ปัญหา


0

มีหลายวิธีที่สามารถนำไปใช้ได้เนื่องจากมีแผนการจัดการพลังงานที่แตกต่างกันจำนวนมากซึ่งขึ้นอยู่กับสิ่งที่คุณติดตั้ง

อันนี้ใช้งานง่ายสำหรับฉันใน Debian Jessie ที่เรียบง่ายโดยไม่มีสภาพแวดล้อมเดสก์ท็อปใด ๆ เพียงแค่มีตัวจัดการหน้าต่าง icewm ขนาดเล็กและรวดเร็ว (มันถูกตัดทอนเพราะมันช้าเกินไปและอย่างนี้มันมีประสิทธิภาพเหนือกว่า GNOME บนฮาร์ดแวร์ที่ดีกว่ามาก)

โดยเฉพาะฉันติดตั้งแพ็กเกจต่อไปนี้: acpi acpi-fakekey acpi-support-base acpid pm-utils แต่มี NONE ดังต่อไปนี้ (มีการลบทิ้ง): gnome * kde * systemd * uswsusp upower โหมดเครื่องมือแล็ปท็อป Hibernate policykit-1

ดังนั้นฉันแค่ใส่มันลงไป/etc/cron.d/battery_low_check(ในหนึ่งบรรทัดแยกเพื่อให้อ่านง่าย):

*/5 * * * *   root  acpi --battery | 
   awk -F, '/Discharging/ { if (int($2) < 10) print }' | 
   xargs -ri acpi_fakekey 205

มันรวดเร็วใช้ทรัพยากรน้อยและไม่ได้ขึ้นอยู่กับคณบดีคนอื่น ๆ (ถ้าเป็นจริงมันจะถูกละเว้นหากใช้งานอยู่ - ดู/usr/share/acpi-support/policy-funcsรายละเอียด)

ให้ทำอะไร:ทุก ๆ 5 นาที ( */5- คุณสามารถเปลี่ยนเป็นทุก ๆ นาทีโดยใช้*ถ้าคุณต้องการให้ตรวจสอบแบตเตอรี่บ่อยขึ้น) มันจะสำรวจสถานะของแบตเตอรี่ (" acpi - แบตเตอรี่ ") และดำเนินการคำสั่งxargs -riเฉพาะเมื่อแบตเตอรี่อยู่ " การคายประจุ "(นั่นคือคุณไม่ได้เชื่อมต่อกับ AC) และสถานะแบตเตอรี่น้อยกว่า10%(" int ($ 2) <10 "- อย่าลังเลที่จะปรับแต่งมันตามความต้องการของคุณ)

acpi_fakekey 205โดยค่าเริ่มต้นจะส่งKEY_SUSPENDเหตุการณ์ ACPI (เช่นคุณกดปุ่มบนแล็ปท็อปที่ขอให้ระงับ) ซึ่งจะทำทุกอย่างที่มันทำเพื่อคุณ (กำหนดค่าไว้/etc/default/acpi-support) - สำหรับฉันมันจำศีลในดิสก์

คุณสามารถใช้คำสั่งอื่นแทนacpi_fakekey 205แน่นอน: เช่นhibernate(จากแพ็คเกจไฮเบอร์เนต) s2diskหรือs2mem(จากแพคเกจ uswsusp), pm-suspend-hybrid(จากแพ็คเกจ PM-utils) เป็นต้น

BTW, หมายเลขกุญแจวิเศษเช่นKEY_SUSPEND = 205ข้างต้นถูกกำหนดไว้ใน/usr/share/acpi-support/key-constants(อื่น ๆ ที่น่าสนใจน่าจะเป็นKEY_SLEEP = 142 )


นั่นดูดีมาก! แต่สามารถใช้กับ systemd timer แทน cron ได้ไหม? (ตัวอย่างที่นี่ ) ฉันอยู่ใน Solus OS ซึ่ง cron ไม่อยู่

@cipricus ฉันเดา แต่ฉันก็หลีกเลี่ยง systemd ดังนั้นจึงไม่สามารถยกตัวอย่างได้ ฉันดูเหมือนจะจำ systemd มีตัวจัดการพลังงาน ACPI ของตัวเองดังนั้นหากคุณติดอยู่กับ systemd คุณอาจต้องการหลีกเลี่ยงการปะทะกับสิ่งนั้น
Matija Nalis

ขอบคุณฉันได้พบทางเลือกที่เกี่ยวข้องuname: github.com/jerrinfrncs/batterynotif/blob/master/…

0

ผมชอบวิธีการแก้ปัญหานี้ว่าเป็นแรงบันดาลใจส่วนหนึ่งจากคำตอบอื่น ๆ : https://github.com/jerrinfrncs/batterynotifbatterynotif(uname).shคือสคริปต์

ดูสคริปต์ที่นี่: https://github.com/jerrinfrncs/batterynotif/blob/master/batterynotif%28uname%29.sh

systemctl hybrid-sleepสำหรับการใช้งานของตัวเองฉันมีการเปลี่ยนแปลงสคริปต์เพื่อเข้าสู่ไฮบริดนอนหลับแทนการปิดลงโดยการใช้คำสั่ง (ตัวเลือกนี้ต้องการพื้นที่สวอป)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.