web-dev-qa-db-ja.com

AC電源が利用できないときに自動的にシャットダウンする方法

私の古いラップトップのバッテリーは故障しており、AC電源をオンにすると100%表示されますが、プラグを抜くと数秒以内に劇的にランダムな割合に低下し、マシンが残酷にオフになります。 UbuntuがロードされているSSD(およびHDD)を損傷することを恐れています。

AC電源が使用できなくなったらすぐにPCの電源をオフにしたかったのです。ここで検索して、 this を見つけました。しかし、私はその質問に対する答えを理解していないか、少なくとも私の状況に関連しています。

AC電源が切断されるか、停電が発生した場合にラップトップを自動的にシャットダウンする方法を教えてください。

5
Nuwan Thisara

ターミナルを開いて次を使用して、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

すべての作業を保存し、電源を抜きます。

5

前書き

コメントで議論されたスクリプトは、bashとしばらく前に書かれました。それ以来、私はPythonで別の実装を行い、dbusを使用するいくつかのユーティリティ関数を使用しました。技術的な意味不明な点はさておき、以下のスクリプトは基本的にそのPythonスクリプトの修正版です。

プロセスの主要部分はすべてmain()関数で実行されます。他の一連のコードはすべてユーティリティ関数なので、コードは少し威圧的に見えるかもしれませんが、実際にはそうではなく、壮観なことは何もしていません。念のために、いくつかの余分なエラーチェックもあります。

それがどのように機能するかのアイデアは簡単です:

  1. ログインするとすぐに開始されます。
  2. メインの最初のwhileループは、ACアダプターが差し込まれるまで待機します(この特定のケースでは少し冗長ですが、念のために使用しています)。 ACアダプターが接続されている場合は、次のステップに進みます
  3. 2番目のwhileループは、ACアダプターが取り外されるまで待機します。削除されたら、最後のステップに進みます。
  4. Shutdown_system()関数はコンピューターをシャットダウンしようとします。何か問題が発生した場合は、エラーメッセージを含むポップアップが表示されます。

スクリプトを設定する

まず、スクリプトのソースコードを取得し、ファイルとして(できればホームフォルダーの~/binに)正確に保存します。ホームディレクトリにbin/フォルダーがない場合は、作成します。

スクリプトをshutdown_monitor.pyとして保存し、ファイルマネージャーで右クリックするか、ターミナルでchmod +x ~/bin/shutdown_monitor.pyコマンドを使用して、スクリプトが実行可能であることを確認します。

最後に、ログイン時にスクリプトを自動的に開始させましょう。UnityDashを開き、新しいコマンドとして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 __== "__main__": main()

その他の注意事項

バグが見つかった場合は、できればコメントまたはgithubでバグを報告してください

2