¿Cómo puedo obtener una notificación usando Notify-OSD cuando el cargador se inserta / retira?

9

¿Cómo puedo obtener una notificación en pantalla usando notify-osd cuando enchufo / desconecto el cargador?

panico kernel
fuente
Podría hacer un script para hacer esto ... pero esa no es una solución muy elegante.
Seth
@Seth ¿Cómo se vería tal script? ¿Podría publicarlo en una respuesta? Estoy interesado específicamente en la forma de identificar un "cargador desenchufado" evento ...
landroni
@landroni Oh, no me di cuenta de que no eras el OP. Publiqué una respuesta a continuación. A mí me funciona bien, pero algunos de mis amigos tienen problemas. Avísame si no te funciona. Estoy trabajando en una mejor manera mientras hablamos.
Seth
@Seth Muchas gracias por investigar esto. Como sucede, mi batería se agotó en mí muy rápidamente, por lo que mi consulta es un poco discutible por ahora. Pero tendré esta solución en mente para el futuro.
landroni

Respuestas:

6

Cambiar entre la alimentación de CA y la energía de la batería debería generar un evento en el bus del sistema D-Bus . Ejecute dbus-monitor --systemy observe qué eventos se generan en su sistema.

Si tienes upower ejecutándose, recibirás notificaciones más especializadas 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

También puede obtener eventos de acpi_listen.

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

Ejecute este script cuando desee comenzar a ver notificaciones o agréguelo al inicio de su sesión.

Gilles 'SO- deja de ser malvado'
fuente
6

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

dbus

Algunas personas informaron que mi solución anterior de udev envió la notificación demasiadas veces cuando se enchufó el cable de alimentación. No pude reproducir eso, pero escribí este script de Python para utilizar dbus en lugar de udev. Guárdelo como un .pyarchivo en algún lugar de su disco duro. Marque el archivo ejecutable ejecutando:

sudo chmod +x yourFile.py  

y agréguelo a sus aplicaciones de inicio como se describe aquí . Este script requiere que el paquete acpiesté instalado.

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

Con un poco de experimentación (y un poco de ayuda) pude utilizar una regla udev para lograr esto. Algunas personas han informado que a veces envía la notificación más de una vez, pero no he tenido ningún problema. YMMV.

Cree un script con los siguientes contenidos:

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

reemplazando some_usercon su nombre de usuario. Marque el archivo ejecutable ejecutando:

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

reemplazando /path/to/script.shcon la ruta a donde guardó el script.

A continuación, cree un archivo con /etc/udev/rules.dnombre 10-power.rulescon el contenido:

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"

nuevamente reemplazando /path/to/script.shcon la ruta al script que creó anteriormente.

Ahora vuelva a cargar las reglas de udev ejecutando:

sudo udevadm control --reload-rules                              

Desenchufe el cable de alimentación. Deberías recibir una notificación.

Seth
fuente
Eso funciona, pero requiere acceso de root y maquinaria compleja para enviar la notificación al escritorio o codificar al usuario como lo hizo. Creo que también necesitará configurarXAUTHORITY algunos administradores de pantalla como gdm.
Gilles 'SO- deja de ser malvado'
@Gilles IMO "requiere root" y el usuario codificado son muy tontos, pero agregaré una solución cron más tarde por razones de integridad si crees que es tan importante. Estoy bastante bien, esto funciona bajo GDM, pero lo comprobaré dos veces.
Seth
1
También estoy echando un vistazo a python-dbus y la API de mensajería dbus de udev para quizás crear un demonio que haga lo mismo que estas reglas de udev, pero el único problema es que deberá ejecutarse constantemente y reiniciarse en cualquier fallas, algo que creo agrega una mayor complejidad a una solución ya bastante decente. Sin embargo, si hay mejores soluciones, me encantaría escucharlas.
joshumax 01 de
No todos ejecutan Ubuntu como un sistema de usuario único. Cron no es útil aquí. Sé que necesitabas el paso adicional de encontrar la ubicación de las versiones anteriores del archivo de cookies X de Gdm, no sé sobre las versiones recientes, pero creo que esto no ha cambiado. Mismo problema con KDM . @joshumax Puede obtener la información de otras fuentes, e incluso a través de dbus, puede hacerlo desde el shell con dbus-monitor. Mira mi respuesta.
Gilles 'SO- deja de ser malvado'
2

Fuente de script

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

Obteniendo el guión

El script también se agrega a mi github ; esa versión será actualizada y desarrollada un poquito más.

Puede obtenerlo haciendo lo siguiente:

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

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

El script estará en el /opt/sergrepdirectorio, llamadonotify_ac_change.sh

Diseño conceptual

Las preguntas clave son "¿Cómo verificamos la presencia del adaptador de CA?" y "¿Cómo detectamos cambios?"

Bueno, este problema ha sido resuelto hace mucho tiempo por otros desarrolladores. Ubuntu viene por defecto con un script llamado on_ac_power , que se almacena en /usr/bin/on_ac_power. El adaptador de corriente se puede mencionar en diferentes subsistemas en el núcleo (ACPI o APM), pero este script simplifica nuestro trabajo: los autores han cubierto muchas variaciones posibles. Solo devuelve el estado de salida, por lo que es apropiado para su uso en ifdeclaraciones.

¿Por qué es on_ac_poweruna buena elección? Porque se basa en verificar múltiples subsistemas. También proporciona un comando lo suficientemente simple para trabajar: el resultado es verdadero o falso.

Por lo tanto, tenemos una herramienta de detección de presencia, pero ¿qué pasa con la lógica? Necesitamos sondear la presencia y detectar cambios en el estado. Lo que podemos hacer es almacenar el estado de salida on_ac_powery comparar continuamente el estado actual con lo que hemos guardado, una vez que cambia: enviar notificación, guardar el estado nuevamente y seguir comparando nuevamente, haciendo un bucle. La idea básica es el uso de banderas.

En resumen, inicializamos una instantánea del estado y luego sondeamos continuamente el cambio desde la instantánea; Una vez que se produce el cambio, notifique y restablezca la instantánea.

Sergiy Kolodyazhnyy
fuente