插入/拔出充电器时,如何使用notify-osd获得屏幕通知?
插入/拔出充电器时,如何使用notify-osd获得屏幕通知?
Answers:
交流电源和电池电源之间的切换应在D-Bus系统总线上产生一个事件。运行dbus-monitor --system
并查看系统上生成了什么事件。
#!/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
您还可以从获取事件acpi_listen
。
#!/bin/sh
acpi_listen |
while read -r what junk; do
[ "$what" = "ac_adapter" ] || continue
notify-send "$(acpi -a)"
done
当您想开始查看通知时将其运行,或将其添加到会话启动中。
有人报告说,当电源线插入时,我较早的udev解决方案发送通知的次数过多。我无法重现该通知,但我编写了此python脚本来使用dbus而不是udev。将其另存为.py
文件在硬盘上。通过运行以下命令将该文件标记为可执行文件:
sudo chmod +x yourFile.py
并将其添加到此处所述的启动应用程序中。此脚本要求acpi
安装软件包。
#!/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规则完成此任务。有人报告说它有时会多次发送通知,但我没有任何问题。YMMV。
创建具有以下内容的脚本:
#!/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
替换some_user
为您的用户名。通过运行以下命令将该文件标记为可执行文件:
sudo chmod +x /path/to/script.sh
替换/path/to/script.sh
为保存脚本的路径。
接下来创建一个/etc/udev/rules.d
名为的文件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"
再次替换/path/to/script.sh
为您先前创建的脚本的路径。
现在,通过运行以下命令重新加载udev规则:
sudo udevadm control --reload-rules
拔下电源线。您应该会收到通知。
XAUTHORITY
一些显示管理器,例如gdm。
dbus-monitor
。看我的答案。
脚本源
#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: 1047481448@qq.com
# 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
获取脚本
该脚本也已添加到我的github中;该版本将进行更新和开发。
您可以通过执行以下操作获得它:
sugo apt-get install git
cd /opt
git clone https://github.com/SergKolo/sergrep.git
该脚本将位于/opt/sergrep
目录中,名为notify_ac_change.sh
概念设计
关键问题是“我们如何检查交流适配器的存在?” 和“我们如何发现变化?”
嗯,这个问题早已由其他开发人员解决。Ubuntu默认带有一个名为on_ac_power的脚本,该脚本存储在中/usr/bin/on_ac_power
。可以在内核的不同子系统(ACPI或APM)下提到电源适配器,但是此脚本使我们的工作更简单-作者介绍了很多可能的变化。它仅返回退出状态,因此适合在if
语句中使用。
为什么on_ac_power
是好的选择?因为它依赖于检查多个子系统。它还提供了足够简单的命令来使用-结果为true或false。
这样我们就有了状态检测工具,但是逻辑呢?我们需要轮询状态并检测状态的变化。我们可以做的是存储退出状态,on_ac_power
并不断地将当前状态与保存的状态进行比较,一旦状态更改,则发送通知,再次保存状态,然后继续进行比较,循环。基本思想是使用标志。
简而言之,我们初始化状态的快照,然后连续轮询快照中的更改;一旦发生更改-通知并重置快照。