Jak mogę uzyskać powiadomienie za pomocą funkcji Notify-OSD po włożeniu / wyjęciu ładowarki?

9

Jak mogę otrzymać powiadomienie na ekranie za pomocą powiadomienia-osd, kiedy podłączam / odłączam ładowarkę?

kernel_panic
źródło
Mógłbym zrobić skrypt, aby to zrobić ... ale to nie jest zbyt eleganckie rozwiązanie.
Seth
@Seth Jak wyglądałby taki skrypt? Czy możesz to opublikować w odpowiedzi? Szczególnie interesuje mnie to, jak rozpoznajesz zdarzenie „odłączony od ładowarki” ...
landroni
@landroni Och, nie zdawałem sobie sprawy, że nie jesteś OP. Poniżej zamieściłem odpowiedź. Działa to dla mnie dobrze, ale kilku moich przyjaciół ma problemy. Daj mi znać, jeśli to nie zadziała. Pracuję nad lepszym sposobem, gdy mówimy.
Seth
@Seth Dziękuję bardzo za przyjrzenie się temu. Tak się składa, że ​​moja bateria umarła na mnie bardzo szybko, więc moje zapytanie jest już trochę dyskusyjne. Ale będę pamiętać o tym rozwiązaniu na przyszłość.
landroni

Odpowiedzi:

6

Przełączanie między zasilaniem AC i akumulatorem powinno generować zdarzenie na magistrali systemowej D-Bus . Uruchom dbus-monitor --systemi obserwuj, jakie zdarzenia są generowane w twoim systemie.

Jeśli masz wyższą wydajność , otrzymujesz bardziej wyspecjalizowane powiadomienia od upower -m.

#!/bin/sh
upower -m |
while read -r _time _2 _3 device; do
  [ "$device" = "/org/freedesktop/UPower/devices/line_power_AC" ] || continue
  notify-send "$(acpi -a)"
done

Możesz także otrzymywać wydarzenia od acpi_listen.

#!/bin/sh
acpi_listen |
while read -r what junk; do
  [ "$what" = "ac_adapter" ] || continue
  notify-send "$(acpi -a)"
done

Uruchom ten skrypt, jeśli chcesz zacząć widzieć powiadomienia, lub dodaj go do uruchamiania sesji.

Gilles „SO- przestań być zły”
źródło
6

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

dbus

Niektóre osoby zgłosiły, że moje wcześniejsze rozwiązanie udev wysłało powiadomienie zbyt wiele razy, gdy kabel zasilający był podłączony. Nie mogłem tego odtworzyć, ale napisałem ten skrypt Pythona, aby używać dbus zamiast udev. Zapisz go jako .pyplik gdzieś na dysku twardym. Zaznacz plik wykonywalny, uruchamiając:

sudo chmod +x yourFile.py  

i dodaj go do aplikacji startowych zgodnie z opisem tutaj . Ten skrypt wymaga acpizainstalowania pakietu .

#!/usr/bin/python

import dbus
from dbus.mainloop.glib import DBusGMainLoop
import gobject
import subprocess


dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

onMessage="Power plugged in!"
offMessage="Power unplugged!"
onImage="/usr/share/icons/gnome/32x32/devices/ac-adapter.png"
offImage="/usr/share/icons/gnome/32x32/status/battery-full.png"

def callback():
    state = subprocess.check_output(["acpi", "-a"]).split(':')[1].strip()
    if state == "on-line":
        subprocess.call(["notify-send", "-i", onImage, onMessage])
    elif state == "off-line":
        subprocess.call(["notify-send", "-i", offImage, offMessage])

bus.add_signal_receiver(callback, 'Changed', 'org.freedesktop.UPower.Device', 'org.freedesktop.UPower', '/org/freedesktop/UPower/devices/line_power_AC')

loop = gobject.MainLoop()
loop.run()

udev

Przy odrobinie eksperymentów (i niewielkiej pomocy) udało mi się zastosować regułę udev, aby to osiągnąć. Niektóre osoby zgłosiły, że czasami wysyła powiadomienie więcej niż raz, ale nie miałem żadnych problemów. YMMV.

Utwórz skrypt o następującej treści:

#!/bin/bash

# Set this to your username
USER="some_user"

if [ "$POWER" == "on" ]
  then
  DISPLAY=:0 /bin/su $USER -c '/usr/bin/notify-send -i /usr/share/icons/gnome/32x32/devices/ac-adapter.png "Power cable plugged in."'
elif [ "$POWER" == "off" ]
  then
  DISPLAY=:0 /bin/su $USER -c '/usr/bin/notify-send -i /usr/share/icons/gnome/32x32/status/battery-full.png "Power cable unplugged."'
fi

zastępując some_userswoją nazwę użytkownika. Zaznacz plik wykonywalny, uruchamiając:

sudo chmod +x /path/to/script.sh  

zastępując /path/to/script.shścieżką do miejsca, w którym zapisałeś skrypt.

Następnie utwórz plik o /etc/udev/rules.dnazwie 10-power.rulesz zawartością:

SUBSYSTEM=="power_supply", ACTION=="change", ENV{POWER_SUPPLY_ONLINE}=="0", OPTIONS+="last_rule", RUN+="/path/to/script.sh" ENV{POWER}="off"
SUBSYSTEM=="power_supply", ACTION=="change", ENV{POWER_SUPPLY_ONLINE}=="1", OPTIONS+="last_rule", RUN+="/path/to/script.sh" ENV{POWER}="on"

ponownie zastępując /path/to/script.shścieżką do wcześniej utworzonego skryptu.

Teraz ponownie załaduj reguły udev, uruchamiając:

sudo udevadm control --reload-rules                              

Odłącz kabel zasilający. Powinieneś otrzymać powiadomienie.

Seth
źródło
To działa, ale wymaga dostępu do konta root i skomplikowanych maszyn, aby otrzymać powiadomienie na pulpit lub na stałe zakodować użytkownika. Myślę, że będziesz musiał ustawićXAUTHORITY kilka menedżerów wyświetlania, takich jak gdm.
Gilles 'SO - przestań być zły'
@Gilles IMO „wymaga roota”, a użytkownik zakodowany na stałe jest dość głupimi kretynami, ale dodam później rozwiązanie cron ze względu na kompletność, jeśli uważasz, że jest to tak ważne. Jestem ładna, to działa pod GDM, ale sprawdzę dwukrotnie.
Seth
1
Zajmuję się również python-dbus i interfejsem API przesyłania komunikatów dev dla udev, aby być może stworzyć demona, który będzie robił to samo, co te reguły udev, ale jedynym problemem jest to, że będzie musiał stale działać i uruchamiać się ponownie na dowolnym awarie, co moim zdaniem zwiększa złożoność i tak już dość przyzwoitego rozwiązania. Jeśli są jednak jakieś lepsze rozwiązania, chętnie je usłyszę.
joshumax
Nie wszyscy używają Ubuntu jako systemu dla jednego użytkownika. Cron nie jest tu przydatny. Wiem, że potrzebowałeś dodatkowego kroku, aby znaleźć lokalizację pliku cookie X starszych wersji Gdm, nie wiem o ostatnich wersjach, ale myślę, że to się nie zmieniło. Ten sam problem z KDM . @ joshumax Możesz uzyskać informacje z innych źródeł, a nawet przez dbus, możesz to zrobić z poziomu powłoki dbus-monitor. Zobacz moją odpowiedź.
Gilles „SO- przestań być zły”
2

Źródło skryptu

#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: [email protected] 
# Date: March 11, 2016
# Purpose: Script to detect connection/disconnection
#          of the ac adapter
#          
# 
# Written for: http://askubuntu.com/q/542986/295286
# Tested on: Ubuntu 14.04 LTS
# Version: 0.2
###########################################################
# Copyright: Serg Kolo , 2016
#    
#     Permission to use, copy, modify, and distribute this software is hereby granted
#     without fee, provided that  the copyright notice above and this permission statement
#     appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
#     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#     DEALINGS IN THE SOFTWARE.
#set -x
ARGV0="$0"
ARGC=$#

test_presence()
{
  on_ac_power
  echo $?
}

notify_change()
{
   pgrep -f '/usr/bin/X' > /dev/null && GUI=true
   connected='AC adapter connected'
   disconnected='AC adapter disconnected'

   if [ $1 -eq 0 ]
   then
           wall <<< $connected        
           $GUI && DISPLAY=:0 notify-send 'AC adapter connected'

   else
           wall <<< $connected
           $GUI && DISPLAY=:0 notify-send 'AC adapter disconnected'
   fi
}

main()
{
  FLAG=$(test_presence)

  while true
  do
     STATUS=$(test_presence)

     if [ $STATUS -eq $FLAG   ]
     then
        continue
     else
        notify_change $STATUS
        FLAG=$STATUS
     fi

  sleep 3 #0.25
  done
}  

main 

Zdobycie skryptu

Skrypt został również dodany do mojego github ; ta wersja zostanie zaktualizowana i opracowana nieco więcej.

Możesz to zrobić, wykonując następujące czynności:

  1. sugo apt-get install git
  2. cd /opt

  3. git clone https://github.com/SergKolo/sergrep.git

Skrypt będzie w /opt/sergrepkatalogu o nazwienotify_ac_change.sh

Projekt koncepcji

Kluczowe pytania brzmią: „Jak sprawdzamy obecność zasilacza sieciowego?” i „Jak wykrywamy zmiany?”

Cóż, ten problem został rozwiązany dawno temu przez innych programistów. Ubuntu jest domyślnie wyposażony w skrypt o nazwie on_ac_power , w którym jest przechowywany /usr/bin/on_ac_power. Zasilacz można wymienić w różnych podsystemach jądra (ACPI lub APM), ale ten skrypt upraszcza naszą pracę - autorzy opisali wiele możliwych wariantów. Zwraca tylko status wyjścia, więc jest odpowiedni do użycia w ifinstrukcjach.

Dlaczego warto on_ac_powerwybrać? Ponieważ polega na sprawdzeniu wielu podsystemów. Zapewnia również wystarczająco proste polecenie do pracy - wynik jest albo prawdziwy, albo fałszywy.

Mamy więc narzędzie do wykrywania obecności, ale co z logiką? Musimy sondować obecność i wykryć zmianę stanu. Co możemy zrobić, to przechowywać status wyjścia on_ac_poweri stale porównywać aktualny stan z tym, co zapisaliśmy, gdy się zmieni - wyślij powiadomienie, zapisz ponownie status i kontynuuj porównywanie, zapętlając. Podstawowym pomysłem jest użycie flag.

Krótko mówiąc, inicjalizujemy migawkę stanu, a następnie stale odpytujemy o zmianę z migawki; gdy nastąpi zmiana - powiadom i przywróć migawkę.

Sergiy Kolodyazhnyy
źródło