交流电源断电时如何自动关机

交流电源断电时如何自动关机

我的旧笔记本电脑电池有问题,使用交流电时显示 100%,但拔掉电源后,电池电量在几秒钟内急剧下降到随机百分比,导致机器突然关机。我担心会损坏装有 Ubuntu 的 SSD(和 HDD)。

我想在交流电源断电时立即关闭电脑。我在这里搜索了一下,找到了。但我不明白该问题的答案,或者至少它与我的情况有关。

请解释一下如何在交流电源拔掉或断电时自动关闭笔记本电脑的方法。

答案1

打开终端并使用以下命令在 udev 中创建新规则:

gksu gedit /etc/udev/rules.d/50-ac-unplugged.rules

(如果你使用的是 Ubuntu 18.04 或更新版本,则gksu默认情况下不可用。在这种情况下,请参阅这个问题 或者使用上面的命令 sudo -H gedit /etc/udev/rules.d/50-ac-unplugged.rules

输入以下行:

SUBSYSTEM=="power_supply", ENV{POWER_SUPPLY_ONLINE}=="0", RUN+="/sbin/shutdown now"

保存文件然后重新启动 udev 服务:

sudo udevadm control --reload-rules

保存所有工作并拔掉电源。

答案2

介绍

评论中讨论的脚本是用 bash 编写的,而且是前不久写的。从那时起,我用 Python 对其进行了不同的实现,并使用了几个使用 dbus 的实用函数。抛开所有技术上的胡言乱语,下面的脚本基本上是该 Python 脚本的修改版本。

该过程的关键部分都是在main()函数中完成的。其他代码行都是实用函数,因此代码可能看起来有点吓人,但实际上并非如此,也没有做任何了不起的事情。为了以防万一,还进行了一些额外的错误检查。

它的工作原理很简单:

  1. 您登录后它立即启动。
  2. 主程序中的第一个 while 循环等待 AC 适配器插入(在这个特定情况下有点多余,但以防万一仍然使用)。如果 AC 适配器插入,我们进入下一步
  3. 第二个 while 循环等待 AC 适配器被移除。移除后,我们进入最后一步。
  4. shutdown_system() 函数将尝试关闭您的计算机。如果出现任何问题,您将看到一个带有错误消息的弹出窗口。

设置脚本

首先,获取脚本源代码并将其保存为文件,最好保存在您的主文件夹中,确切地说是~/bin。如果您的主目录中没有bin/文件夹,请创建一个。

将脚本另存为shutdown_monitor.py并确保它可以通过在文件管理器中右键单击或使用chmod +x ~/bin/shutdown_monitor.py终端中的命令来执行。

最后,让我们让脚本在您登录时自动启动。打开 Unity Dash 并找到Startup Applications. Add either full path to the command orpython /home/USERNAME/bin/shutdown_monitor.py` 作为新命令。

就是这样 !

脚本

也可作为GitHub 上的要点

#!/usr/bin/env python
"""
Author: Serg Kolo <[email protected]>
Date:   Nov 29 , 2016
Purpose:Script for shutting down Ubuntu system
        if AC adapter is removed 
Written for:http://askubuntu.com/q/844193/295286  
"""
import dbus
import time
import subprocess

def get_dbus_property(bus_type, obj, path, iface, prop):
    """ utility:reads properties defined on specific dbus interface"""
    if bus_type == "session":
        bus = dbus.SessionBus()
    if bus_type == "system":
        bus = dbus.SystemBus()
    proxy = bus.get_object(obj, path)
    aux = 'org.freedesktop.DBus.Properties'
    props_iface = dbus.Interface(proxy, aux)
    props = props_iface.Get(iface, prop)
    return props

def get_dbus_method(bus_type, obj, path, interface, method, arg):
    """ utility: executes dbus method on specific interface"""
    if bus_type == "session":
        bus = dbus.SessionBus()
    if bus_type == "system":
        bus = dbus.SystemBus()
    proxy = bus.get_object(obj, path)
    method = proxy.get_dbus_method(method, interface)
    if arg:
        return method(arg)
    else:
        return method()

def on_ac_power():
    adapter = get_adapter_path()
    call = ['system','org.freedesktop.UPower',adapter,
            'org.freedesktop.UPower.Device','Online'
    ]

    if get_dbus_property(*call): return True

def get_adapter_path():
    """ Finds dbus path of the ac adapter device """
    call = ['system', 'org.freedesktop.UPower',
            '/org/freedesktop/UPower','org.freedesktop.UPower',
            'EnumerateDevices',None
    ]
    devices = get_dbus_method(*call)
    for dev in devices:
        call = ['system','org.freedesktop.UPower',dev,
                'org.freedesktop.UPower.Device','Type'
        ]
        if get_dbus_property(*call) == 1:
            return dev

def shutdown_system():
    call = ['session', 'com.canonical.Unity', 
            '/com/canonical/Unity/Session', 'com.canonical.Unity.Session', 
            'Shutdown',None
    ]
    return get_dbus_method(*call)

def main():
    while not on_ac_power():
        time.sleep(1)

    while on_ac_power():
        time.sleep(1)

    try:
        shutdown_system()
    except Exception as e:
        error_msg = 'Ooops,' + __file__ + 'failed to shutdown your system.'
        error_msg = error_msg + 'Please show Serg this error so he can fix it:'
        subprocess.call(['zenity','--error',
                         '--text', error_msg + repr(e)
        ])

if __name__ == "__main__": main()

补充笔记

如果发现任何错误,请报告,最好在评论中或在 github 上

相关内容