Wie kann ich mit Notify-OSD eine Benachrichtigung erhalten, wenn das Ladegerät eingesetzt / entfernt wird?

9

Wie kann ich mit notify-osd eine Benachrichtigung auf dem Bildschirm erhalten, wenn ich das Ladegerät ein- oder ausstecke?

kernel_panic
quelle
Ich könnte ein Skript erstellen, um dies zu tun. Aber das ist keine sehr elegante Lösung.
Seth
@ Seth Wie würde ein solches Skript aussehen? Könnten Sie es in einer Antwort posten? Ich bin speziell daran interessiert, wie Sie ein Ereignis "Ladegerät nicht angeschlossen" identifizieren ...
landroni
@landroni Oh, wusste nicht, dass du nicht der OP bist. Ich habe unten eine Antwort gepostet. Es funktioniert gut für mich, aber einige meiner Freunde haben Probleme. Lassen Sie mich wissen, wenn es bei Ihnen nicht funktioniert. Ich arbeite an einem besseren Weg, während wir sprechen.
Seth
@ Seth Vielen Dank, dass Sie sich damit befasst haben. Zufällig ist meine Batterie bei mir sehr schnell leer, daher ist meine Anfrage mittlerweile ein bisschen umstritten. Aber ich werde diese Lösung für die Zukunft im Auge behalten.
Landroni

Antworten:

6

Das Umschalten zwischen Wechselstrom und Batteriestrom sollte ein Ereignis auf dem D-Bus -Systembus erzeugen . Führen Sie aus dbus-monitor --systemund beobachten Sie, welche Ereignisse auf Ihrem System generiert werden.

Wenn Sie upower laufen lassen, erhalten Sie spezialisiertere Benachrichtigungen von 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

Sie können auch Ereignisse von erhalten acpi_listen.

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

Führen Sie dieses Skript aus, wenn Sie Benachrichtigungen anzeigen möchten, oder fügen Sie es Ihrem Sitzungsstart hinzu.

Gilles 'SO - hör auf böse zu sein'
quelle
6

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

dbus

Einige Leute berichteten, dass meine frühere udev-Lösung die Benachrichtigung zu oft gesendet hat, als das Netzkabel eingesteckt war. Ich konnte das nicht reproduzieren, aber ich habe dieses Python-Skript geschrieben, um dbus anstelle von udev zu verwenden. Speichern Sie es als .pyDatei irgendwo auf Ihrer Festplatte. Markieren Sie die ausführbare Datei, indem Sie Folgendes ausführen:

sudo chmod +x yourFile.py  

und fügen Sie es wie hier beschrieben zu Ihren Startanwendungen hinzu . Für dieses Skript muss das Paket acpiinstalliert sein.

#!/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

Mit ein wenig Experimentieren (und ein wenig Hilfe) konnte ich eine udev- Regel verwenden, um dies zu erreichen. Einige Leute haben berichtet, dass es die Benachrichtigung manchmal mehr als einmal sendet, aber ich hatte keine Probleme. YMMV.

Erstellen Sie ein Skript mit folgenden Inhalten:

#!/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

Ersetzen some_userdurch Ihren Benutzernamen. Markieren Sie die ausführbare Datei, indem Sie Folgendes ausführen:

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

Ersetzen /path/to/script.shdurch den Pfad, in dem Sie das Skript gespeichert haben.

Als nächstes erstellen Sie eine Datei mit dem /etc/udev/rules.dNamen 10-power.rules:

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"

Ersetzen Sie ihn erneut durch /path/to/script.shden Pfad zu dem zuvor erstellten Skript.

Laden Sie nun die udev-Regeln neu, indem Sie Folgendes ausführen:

sudo udevadm control --reload-rules                              

Ziehen Sie das Netzkabel ab. Sie sollten eine Benachrichtigung erhalten.

Seth
quelle
Das funktioniert, erfordert jedoch Root-Zugriff und komplexe Maschinen, um die Benachrichtigung an den Desktop zu senden oder den Benutzer wie Sie fest zu codieren. Ich glaube , Sie auch brauchen werden SetXAUTHORITY mit einigen Display - Manager wie gdm.
Gilles 'SO - hör auf böse zu sein'
@ Gilles IMO "erfordert root" und der hartcodierte Benutzer sind ziemlich dumme Trottel, aber ich werde der Vollständigkeit halber später eine Cron-Lösung hinzufügen, wenn Sie der Meinung sind, dass dies so wichtig ist. Ich bin hübsch, dass dies unter GDM funktioniert, aber ich werde es noch einmal überprüfen.
Seth
1
Ich schaue mir auch die dbus-Messaging-API von python-dbus und udev an, um möglicherweise einen Daemon zu erstellen, der das Gleiche wie diese udev-Regeln tut. Das einzige Problem ist jedoch, dass er ständig ausgeführt und auf jedem neu gestartet werden muss Ausfälle, von denen ich glaube, dass sie einer bereits recht anständigen Lösung eine höhere Komplexität verleihen. Wenn es jedoch bessere Lösungen gibt, würde ich mich freuen, sie zu hören.
Joshumax
Nicht jeder betreibt Ubuntu als Einzelbenutzersystem. Cron ist hier nicht nützlich. Ich weiß, dass Sie den zusätzlichen Schritt benötigen, um den Speicherort der X-Cookie-Datei älterer Versionen von Gdm zu finden. Ich weiß nichts über aktuelle Versionen, aber ich denke, das hat sich nicht geändert. Gleiches Problem mit KDM . @joshumax Sie können die Informationen aus anderen Quellen abrufen, und sogar über dbus können Sie dies über die Shell mit tun dbus-monitor. Siehe meine Antwort.
Gilles 'SO - hör auf böse zu sein'
2

Skriptquelle

#!/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 

Das Skript abrufen

Das Skript wird auch meinem Github hinzugefügt . Diese Version wird ein bisschen mehr aktualisiert und weiterentwickelt.

Sie können es erhalten, indem Sie Folgendes tun:

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

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

Das Skript befindet sich im /opt/sergrepVerzeichnis mit dem Namennotify_ac_change.sh

Konzeptentwicklung

Die wichtigsten Fragen lauten: "Wie überprüfen wir das Vorhandensein des Netzteils?" und "Wie erkennen wir Veränderungen?"

Nun, dieses Problem wurde vor langer Zeit von anderen Entwicklern gelöst. Ubuntu wird standardmäßig mit einem Skript namens on_ac_power geliefert , das in gespeichert ist /usr/bin/on_ac_power. Das Netzteil kann unter verschiedenen Subsystemen im Kernel (ACPI oder APM) erwähnt werden, aber dieses Skript vereinfacht unsere Arbeit - die Autoren haben viele mögliche Variationen behandelt. Es gibt nur den Exit-Status zurück, sodass es für die Verwendung in ifAnweisungen geeignet ist .

Warum ist on_ac_powereine gute Wahl? Weil es auf der Überprüfung mehrerer Subsysteme beruht. Es bietet auch einen Befehl, der einfach genug ist, um damit zu arbeiten - das Ergebnis ist entweder wahr oder falsch.

Wir haben also ein Tool zur Anwesenheitserkennung, aber was ist mit der Logik? Wir müssen das Vorhandensein abfragen und Veränderungen im Zustand feststellen. Was wir tun können, ist, den Exit-Status von zu speichern on_ac_powerund den aktuellen Status kontinuierlich mit dem zu vergleichen, was wir gespeichert haben, sobald er sich ändert - Benachrichtigung senden, Status erneut speichern und erneut vergleichen, Schleife. Grundidee ist die Verwendung von Flags.

Kurz gesagt, wir initialisieren einen Snapshot des Status und fragen dann kontinuierlich nach Änderungen vom Snapshot ab. Sobald eine Änderung eintritt, benachrichtigen Sie den Snapshot und setzen Sie ihn zurück.

Sergiy Kolodyazhnyy
quelle