Como desligar automaticamente quando a energia AC não está disponível

5

Meu laptop antigo tem uma bateria defeituosa, que mostra 100% quando em corrente alternada, mas quando desconectado ele cai drasticamente para porcentagens aleatórias em segundos e faz a máquina desligar brutalmente. Eu tenho medo de danificar meu SSD (e meu HDD) no qual o Ubuntu é carregado.

Eu queria desligar o PC assim que a energia AC não estivesse disponível. Eu procurei aqui e encontrei this . Mas eu não entendo a resposta para essa pergunta ou pelo menos é relevante para a minha situação.

Por favor, explique-me uma maneira de desligar meu laptop automaticamente assim que a energia AC for desconectada ou quando houver uma falha de energia.

    
por Nuwan Thisara 28.11.2016 / 15:43

2 respostas

5

Crie uma nova regra no udev abrindo o terminal e usando:

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

(Se você estiver usando o Ubuntu 18.04 ou uma versão mais recente, gksu não estará disponível por padrão. Nessa situação, por favor, consulte esta questão ou use o comando acima como sudo -H gedit /etc/udev/rules.d/50-ac-unplugged.rules )

Coloque na seguinte linha:

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

Salve o arquivo e reinicie os serviços do udev com:

sudo udevadm control --reload-rules

Salve todo o seu trabalho e desconecte sua fonte de alimentação.

    
por WinEunuuchs2Unix 29.11.2016 / 02:00
2

Introdução

O script que foi discutido nos comentários foi escrito em bash e um tempo atrás. Desde então, fiz uma implementação diferente em Python e usando várias funções utilitárias que usam dbus. Todo o jargão técnico à parte, o script abaixo é basicamente uma versão modificada desse script Python.

As partes principais do processo são todas feitas na função main() . O monte de outras linhas de código são funções de utilidade, então o código pode parecer um pouco intimidador, mas na verdade não é e não está fazendo nada de espetacular. Há algumas verificações de erro extras feitas apenas no caso, também.

A ideia de como funciona é simples:

  1. Começa assim que você faz login.
  2. O primeiro loop while no principal aguarda até que o adaptador AC esteja conectado (o que neste caso em particular é um pouco redundante, mas apenas no caso ainda é usado). Se o adaptador CA estiver conectado, vamos para a próxima etapa
  3. Segundo, o loop aguarda até o adaptador AC ser removido. Uma vez removido, passamos para a etapa final.
  4. A função shutdown_system () tentará desligar o seu computador. Se algo der errado, você deverá ver um pop-up com uma mensagem de erro.

Configurando o script

Antes de mais nada, obtenha o código-fonte do script e salve-o como um arquivo, de preferência em sua pasta pessoal, em ~/bin para ser exato. Se você não tiver a pasta bin/ em seu diretório pessoal, crie uma.

Salve o script como shutdown_monitor.py e verifique se ele é executável clicando com o botão direito do mouse no gerenciador de arquivos ou usando o comando chmod +x ~/bin/shutdown_monitor.py no terminal.

Por fim, vamos fazer o script iniciar automaticamente quando você fizer login. Abra o Unity Dash e encontre Startup Applications. Add either full path to the command or python /home/USERNAME/bin/shutdown_monitor.py 'como novo comando.

É isso!

Script

Também disponível como gist no 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()

Notas adicionais

Por favor, relate bugs, se você encontrar algum, de preferência aqui nos comentários ou no github

    
por Sergiy Kolodyazhnyy 29.11.2016 / 08:29