
バッテリーの状態に応じて、Dualshock 4 Gamecontroller LEDカラーバーを変更する簡単なスクリプトを作成しました(回答を使用)。https://gaming.stackexchange.com/questions/336934/how-to-set-default-color-and-brightness-of-leds-of-the-dualshock-4-controller-onとバッテリーの充電状態https://wiki.gentoo.org/wiki/Sony_DualShock):
#!/bin/bash
function float_to_int() {
echo $1 | cut -d. -f1 # or use -d, if decimals separator is ,
}
LED=$(echo "$1" | egrep -o '[[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4}\.[[:xdigit:]]{4}')
[[ -z "$LED" || ! -d "/sys/class/leds/$LED:global" ]] && exit
BRIGHTNESS=0.2
POWER=$(cat "/sys/class/power_supply/sony_controller_battery_$2/capacity")
GREEN=$(float_to_int $(echo "($POWER*255/100*$BRIGHTNESS)" | bc -l))
RED=$(float_to_int $(echo "((255 - $POWER*255/100)*$BRIGHTNESS)" | bc -l))
BLUE=0
echo $RED > /sys/class/leds/$LED:red/brightness
echo $GREEN > /sys/class/leds/$LED:green/brightness
echo $BLUE > /sys/class/leds/$LED:blue/brightness
コントローラが接続されたら、このスクリプトを実行する/etc/udev/rules.d/10-local.rulesの下に非常に単純なudevルールを作成しました。
ACTION=="add", SUBSYSTEM=="input", ATTRS{uniq}=="XX:XX:XX:XX:XX:XX" RUN+="/usr/local/bin/ds4led '%p' XX:XX:XX:XX:XX:XX"
これまではうまくいっています。今必要なのは、このスクリプトを毎分実行することです(そうしないと、バッテリーの状態は更新されません)。
私はこれを達成するためにいくつかの方法を試しました。
do-whileループでフルスクリプトを実行する
while :
do
// CODE
sleep 60
done
->バッテリーの状態を表示する機能は機能しますが、コントローラ自体は使用できなくなります。
バックグラウンドdo-whileループでフルスクリプトを実行する
これには角かっことアンパサンド構文を使用しました。
(
while :
do
// CODE
sleep 60
done
) &
- >原則として動作し、コントローラを使用することができます。ただし、コントローラの接続が失われると、スクリプトは引き続き実行され、エラーが発生します。さらに、スクリプトの複数のインスタンスが実行され続けるのは面倒です。
解決策?
複数のインスタンスが引き続き実行されますが、コントローラが切断された場合にスクリプトが実行され続ける問題を解決するにはどうすればよいですか?
もちろん、コントローラが削除されたときに実行される追加のスクリプトを作成して、実行中のスクリプトを最初から終了することもできます。しかし、現時点では、このソリューションは非常にエレガントではないようです。このスクリプトを毎分実行する簡単な方法はありませんか?毎分実行され、コントローラのプラグが抜かれるとすぐに停止するcronjobをこのスクリプトで生成したいのですが、それもそれほどエレガントに見えません。
答え1
私はあなたが間違った問題を解決しようとしていると信じています。サブシステムは、デバイスがudev
接続されたときに報告します(注意してください。デバイスが切断されたときも報告します)。一方、サブシステムはcron
プロセスを定期的に実行します。
したがって、2つの組み合わせを使用して、スクリプトがそのタスクを実行できるようにするトグルをudev
有効または無効にします。cron
簡単なレベルでは、次のようになります(いいえ、/tmp
権限と所有権で保護されていない限り、ロゴファイルを特に推奨しません)。
ウデブ
ACTION=="add" [...] RUN+="touch /tmp/.ds4led_on"
スケジュールされたジョブスクリプト
#!/bin/bash
#
[[ -f "/tmp/.ds4led_on" ]] || exit 0
# ...Code to perform the update...
答え2
roaimaの回答のおかげでついに成功しました。
私は3つの異なるスクリプトを作成しました/usr/local/bin
。
DS4LED
#!/bin/bash
function float_to_int() {
echo $1 | cut -d. -f1 # or use -d, if decimals separator is ,
}
function setrgb() {
LED=$(echo "$1" | egrep -o '[[:xdigit:]]{4}:[[:xdigit:]]{4}:[[:xdigit:]]{4}\.[[:xdigit:]]{4}')
[[ -z "$LED" || ! -d "/sys/class/leds/$LED:global" ]] && exit
BRIGHTNESS=0.2
POWER=$(cat "/sys/class/power_supply/sony_controller_battery_$2/capacity")
GREEN=$(float_to_int $(echo "($POWER*255/100*$BRIGHTNESS)" | bc -l))
RED=$(float_to_int $(echo "((255 - $POWER*255/100)*$BRIGHTNESS)" | bc -l))
BLUE=0
echo $RED > /sys/class/leds/$LED:red/brightness
echo $GREEN > /sys/class/leds/$LED:green/brightness
echo $BLUE > /sys/class/leds/$LED:blue/brightness
}
if [ "$#" -ne 2 ]
then
while read -r line; do
linesplit=($line)
LEDINPUT=${linesplit[0]}
POWERINPUT=${linesplit[1]}
setrgb $LEDINPUT $POWERINPUT
done < /tmp/ds4led
else
setrgb $1 $2
fi
ds4led_write
#!/bin/bash
/usr/local/bin/ds4led $1 $2
echo $1 $2 >> /tmp/ds4led
ds4led_delete
#!/bin/bash
sed "\!$1!d" /tmp/ds4led --in-place
私の/etc/udev/rules.d/20-ds4.rules
ファイル:
ACTION=="add", KERNEL=="event28", ATTRS{uniq}=="00:1f:e2:e5:c3:2e" RUN+="/usr/local/bin/ds4led_write '%p' 00:1f:e2:e5:c3:2e"
ACTION=="remove", KERNEL=="event28", ATTRS{uniq}=="00:1f:e2:e5:c3:2e" RUN+="/usr/local/bin/ds4led_remove '%p'"
sudo crontab -e
* * * * * /usr/local/bin/ds4led
説明する:
Dualshock 4コントローラーが接続されるたびに、シリアル番号とバッテリー識別子がファイルに書き込まれます/tmp/ds4led
。接続時にds4led
これらの識別子を使用してスクリプトを直接呼び出して、RGBストリップを正しい色にすぐに設定します。その後、1分ごとにcrontabを実行して、そのファイルの下に接続されている/tmp/ds4led
デバイスがあることを確認し、RGBバープロセスを実行します。コントローラの接続が切断されるたびに、ファイル内の対応するエントリが削除されます。
udevルール: Dualshock 4コントローラは、私の大まかなフィルタのために接続ごとに約8つのudevトリガーを生成するため、接続ごとに一度だけ実行されるudevイベントを見つけようとします。全体として、すべてのデバイスは以下をトリガします。
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input67 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input68 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input66 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input67/mouse3 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input66/js0 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input68/event27 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input66/event28 00:1f:e2:e5:c3:2e
/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7:1.0/bluetooth/hci0/hci0:256/0005:054C:09CC.0013/input/input67/event26 00:1f:e2:e5:c3:2e
フィルタとして「event28」を選択した理由は、一度だけ表示され、コントローラの実際のジョイスティック部分に関連付けられるためです(すべてのDualshockコントローラにタッチパッドや他のアナログデバイスが含まれていることを忘れないでください)。しかし、「event28」が正確に何であるかよくわかりません。