Raspberry Pi ちょっと便利なコマンドボタン(X DPMS)

Raspberry Pi OSは無操作が一定時間続くとモニターの画面をオフにします。
モニターの消費電力はボード自体より遥かに多いので省電力の観点からは有効な機能と言えます。
但し動画を視聴している時やモニターの画面を見ながら考え事をしている時に真っ暗になるのは頂けません。ターミナルからコマンドを実行することで解除できるのですが肝心のコマンドをど忘れしたりしたら顰蹙者です(よく忘れる・・当サイトの住人です!!)
前回のコマンドボタンの続きということで少しだけスマートに実行してみたいと思います。

xset dpms

https://wiki.archlinux.jp/index.php/Display_Power_Management_Signaling
DPMS を無効にして画面が消えないようにする

$ xset s off -dpms


上記のコマンドを実行することで解除できます。
時間は秒単位になっていますね。

前回のapp-menu.pyにボタンを追加してDPMSの有効(無効)を切り替えるようにします。


2つのアイコンを用意 x-color.png x-mono.png サイズ32×32

app-menu.py

xset qからDPMSを読んでボタンアイコンを表示します。
DPMSに変更があればapp-menu.pyを再起動してアイコンを切り替え
dvilspie2を実行してウインドウを巻き上げ(shade)
~/bin/app-menu.py 追記

# Button901 x-DPMS
command = ("xset -q | grep 'DPMS is Disabled'")
proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
if proc == "":
    x = 'x-color.png'; y = 0
else:
    x = 'x-mono.png'; y = 1
def x901():
    if y == 0:
        proc = messagebox.askyesno('Confirmation','X --DPMS (無効)')
        if proc == True:
            subprocess.run("xset s off -dpms", shell=True)
            exit()
        else:
            reload()
    if y == 1:
        proc = messagebox.askyesno('Confirmation','X +DPMS (有効)')
        if proc == True:
            subprocess.run("xset +dpms", shell=True)
            exit()
        else:
            reload()
icon901 = PhotoImage(file=dir+x)
button901 = ttk.Button(frame1,image=icon901,command=x901)
button901.grid(row=1,column=4)


デフォルトはDPMS有効で起動しています。
実行するとDPMS無効にするかと聞いてくるので Yes
app-menu.pyを再起動してアイコンを取り替えます。


DPMS Disabled アイコンが変わります。

Noはそのまま静かにウインドウを巻き上げます。

Raspberry Pi ちょっと便利なコマンドボタン(application menu)

アプリケーションランチャ(application menu)は以前から作成、設置しているものですがdevilspie2に変更したこと、ボタン作成ルールを設けたこともあって再度作成手直し、前回のsurfブラウザの起動にも対応してみたいと思います。

今回は取り敢えず3個のボタンを作成、pulse(surf)の起動またdevilspie2の設定補助ツールとして活用します。
一定の確認が取れれば自由にボタンを増やしていけると思います。

application menu作成

ボタンはテキストエディタのgeany pi4ボタン(pulse.php)そしてExitボタンとします。

ボタンは3個ですが一列5個を並べる予定
ファイルは~/bin/app-menu.pyとします

アイコンディレクトリは~/.icons/32×32/ アイコンファイルを用意サイズ32×32
ボタン番号などはボタンを増やしても被ることが無いよう適当な番号を割り振っています。
def 関数名はcommand=関数名の関係が合っていれば変更可
ボタンなし関数reloadを最後の方に記述しています。
~/bin/app-menu.py

#!/usr/bin/python3

from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import subprocess
import time

root = Tk()
root.title('Application Menu')
root.configure(background='#333333') # Background color
style = ttk.Style()
style.theme_use('default') #('clam', 'alt', 'default', 'classic')
style.configure('TButton', background='#D9D9D9') # Button color

# Frame as Widget Container
frame1 = ttk.Frame(
    root,
    padding=5)
frame1.grid()

# icon dir
dir = "~/.icons/32x32/"

# Button131 geany
def ed131():
    subprocess.run("geany 2>/dev/null &", shell=True)
icon131 = PhotoImage(file=dir+'geany.png')
button131 = ttk.Button(frame1,image=icon131,command=ed131)
button131.grid(row=1,column=1)

# Button408 pi4 surf_pulse
def mul408():
    subprocess.run("surf pi4://html/pulse.php 2>/dev/null &", shell=True)
    time.sleep(3)
    reload()
icon408 = PhotoImage(file=dir+'raspberrypi-bk.png')
button408 = ttk.Button(frame1,image=icon408,command=mul408)
button408.grid(row=1,column=3)

# Button exit
def exit():
    reload()
    subprocess.run("killall app_menu.py && ~/bin/app_menu.py &", shell=True)
icon115 = PhotoImage(file=dir+'exit.png')
button115 = ttk.Button(frame1,image=icon115,command=exit)
button115.grid(row=1,column=5)

# devilspie2 reload
def reload():
    subprocess.run("killall devilspie2 && sleep 0.5 && devilspie2 &", shell=True)

root.mainloop()

実行権限を与えてターミナルから実行

$ cd ~/bin
$ chmod 755 app-menu.py
$ ./app-menu.py

ボタンメニューが起動するはずです。エラーが出る場合はメッセージからエラー箇所を修正

devilspie2 application menu


設定ファイルの編集にはgeanyが便利
ボタンメニューからテキストエディターgeanyを起動、前回作成した~/.config/devilspie2/applications.luaを開いてApplication Menuを追加

window_name “Application Menu”はapp-menu.pyのroot.title(‘Application Menu’)

-- Application Menu
if (get_window_name()=="Application Menu") then
  set_window_geometry2 (797,24,225,52)
  pin_window()
  -- shade()
end

ボタン Exit

Exitボタンはdevilspie2,app-menu.pyを再起動

devilspie2を再起動することで設定した位置、サイズを適用、geometryを変更しながら目的の位置、サイズを追い込んでいきます。
app-menu.pyの再起動はメニューにボタンを追加、変更した際に設定が反映されます。app-menu.py編集後起動に失敗したらターミナルから実行、原因を特定修正

起動が確認できたらautostartに登録、OS再起動
~/.config/autostart/app-menu.desktop (新規作成)

[Desktop Entry]
Type=Application
Name=Application Menu
Exec=/home/pi/bin/app-menu.py


前回作成したPi4(音量コントロール)は実行後3秒のsleepを入れてdevilspie2を再起動することで設定値の位置、サイズ変更を実現しています。

当サイトではapp-menu.pyはpin_window() shade() を有効にしています。全ワークスペースに配置、タイトルバーのみで起動しています。
アプリケーションの実行後reload()を記述することでメニューを巻き上げ、devilspie2で設定起動しているアプリケーションは設定値に再配置されます。


当サイトでは9個のワークスペースを設置しています。
アプリケーションはdevilspie2で使いやすい位置、サイズを設定。shellスクリプト+xdotoolでワークスペースを切り替えながら4個のvncviewer 9個のターミナル、ほかアプリケーションをOS起動時に自動実行しています。
ターミナルはxtermで-geometryを指定、作業はできるだけvncserver側で実行するようにしているのでPi3がコケることも少なくなりました。

Raspberry Pi window matching utility devilspie2

アプリケーションによっては常に決まった位置、サイズ(スタイル)で起動したいものがあります。
Xアプリケーションのウインドウ位置、サイズなどをコントロールするユーティリティ devilspieは gdevilspieもインストール不可なことから中心はluaベースのdevilspie2に移っているようです。 devilspie自体はインストール、動作ともOKです。

機能としてはほぼ同じようですが開発者も違うことからデータの互換性は無いようです。
当サイトもdevilspie2に移行してみようと思います。

環境

Raspberry Pi 3 Raspberry Pi OS (32-bit) with desktop LXDE

devilspie2

# apt install devilspie2

なにかdevilspie2コマンドを実行するとディレクトリ~/.config/devilspie2が作成されます。

$ devilspie2 -v
Devilspie2 v0.42

参考サイト
スクリプトなどを紹介しています https://qiita.com/s-katsumata/items/318b4c58a9e32593553b
マニュアルはここ https://www.gusnan.se/scite/devilspie2/manual.php/

スクリプトの作成(ファイル名は適当に!devilspie2.lua以外ならいいと思う)
サイズの区切り文字を変更しています。
~/.config/devilspie2/devilspie2-debug.lua

debug_print( "window_name:        " .. get_window_name())
debug_print( "application_name:   " .. get_application_name())
debug_print( "instance_name:      " .. get_class_instance_name())
x, y, w, h = xywh()
debug_print( "xywh:               " .. x .. "," .. y .."," .. w .. "," .. h )
debug_print( "\n" )

スクリプト実行 (Ctrl-c 終了)

$ devilspie2 --debug


現在起動しているXアプリケーション全てが取得されます。
基本のウインドウ識別はgetで取得している3個の*name
xtermは3個とも同じネームなので複数のxtermを任意の位置に配置するのはdevilspie2では難しい。
chromium-browserはclass_instance_nameを使います。
pcmanfmは2箇所ありますがwindow_name: pi(ホームディレクトリ)がファイルマネージャー
もう一つはデスクトップになるので*name: pcmanfmを使うとデスクトップ全体が乱れることがあります。
その他window_name application_nameを使うのが多いと思います。

devilspie2起動
devilspie2はデーモンとして起動します。
=/.config/autostart/devilspie2.desktop 新規作成

[Desktop Entry]
Type=Application
Name=Devilspie2
Exec=devilspie2


lxsession
再起動するとdevilspie2は有効になっています。
pcmanfmからはNameのDevilspie2がファイルとして表示します。

設定ファイルの作成

準備ができたところで設定ファイルを作成
~/.config/devilspie2/applications.lua としておきます。

----------------------------------------------------
-- devilspie2 - Lua-based window matching utility --
----------------------------------------------------
-- get_window_name()
-- get_application_name()
-- get_class_instance_name()
-- pin_window() すべてのワークスペースにウィンドウを配置
-- shade() タイトルバーのみを表示
-- minimize() ウィンドウを最小化
-- set_window_workspace(x) x=workspace number
-----------------------------------------------------
-- pulseaudio Raspberry Pi 4
if (get_window_name()=="@cgDISVMf:- | pulseaudio Raspberry Pi 4") then
  set_window_geometry2 (600,24,340,100)
  pin_window()
  -- shade()
end

冒頭にマニュアルから当サイトで使いそうなコマンドを記載(– :コメント)しています。
例として当サイトで常時使っているpulse audio音量コントロールでテスト
devilspie2 –debugを実行しておくと記述に間違いがあればエラーを返します。

~/.config/devilspie2/以下の設定ファイルを再読込

$ killall devilspie2 && sleep 1 && devilspie2 &
$ surf pi4://html/pulse.php &

ディフォルトのsurfブラウザは800×600で起動します。
これをdevilspie2で340×100サイズまで小さくすのですが・・・ならないですね!
再度 killall devilspie2 && sleep 1 && devilspie2 &
小さくなりました。位置やpinも正常
これはdevilspieの時も同様でおそらくsurfがwindow_nameを取得するタイミングが遅いものと思っています。
ほかに起動しているdevilspie2で設定したアプリケーションは全て起動時に設定が反映されています。


起動(surf)の仕方は次回もう少しオシャレな方法でトライしてみたいと思います。

devilspieと比べるとdevilspie2は情報の取得や設定ファイルの作成はかなりわかりやすくなっていると思います。

Raspberry Pi OS (32-bit) with desktop multimedia

通常ラジオや音楽はmoOde audioで再生しています。
音声関連は全てpulseaudioサーバーのmoOde audioに送っていましたがmoOde audioのメンテ時などは音がなくなってしまうのでもう一つの選択肢としてRaspberry Pi4のi2Sデバイスから必要があればいつでも音を出せるようにしたいと思います。

構成としてはmoOde audio同様にpulseaudioサーバーとしてほかのマシンからの音声も再生可能とします。
Zeroで作成した設定ファイルなどはできるだけ利用(コピー)
moOde Playerが無い以外はZero(moOde audio)とほぼ同じような仕様にしてみたいと思います。

I2Sデバイス

/boot/config.txtに追記変更

# Enable audio (loads snd_bcm2835)
dtparam=audio=off
dtoverlay=hifiberry-dac


内蔵音源をoff
I2Sデバイスを有効
I2Sデバイスは以前Zeroで作成したpcm5102aを使用
アンプへは3.5mmステレオジャックを差し替えます。
Zero(moOde audio)はスペック的にもまたmoOdeの仕様上安易に変更することは困難なことからマルチメディアの実験環境としても使用の予定です。

インストール

要点だけ記載(詳細は過去記事のどっかにあります)
player

# apt install mpv mplayer libxml2-utils rtmpdump swftools
# apt remove youtube-dl

youtube-dlは別途最新版をインストール
pulseaudio

# apt install pulseaudio

/etc/pulse/default.pa 末尾追記(ネットワーク帯は各自の環境)

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/24 auth-anonymous=1
set-default-source alsa_output.platform-soc_sound.stereo-fallback.monitor
set-default-sink alsa_output.platform-soc_sound.stereo-fallback

mpd

# apt install mpd mpc ncmpcpp pavucontrol
# systemctl disable mpd

mpdはユーザーで起動しています。
~/.config/mpd/mpd.conf の出力はpulseaudio

---
audio_output {
    type  "pulse"
    name  "pulse audio"
}

www-data

Zeroと同様にローカルからpulseaudioをコントロールするためweb serverを建てます。
web serverはnginx-lightをインストール

# apt -y install nginx-light php7.3-fpm surf

Zeroのカードから/var/www/htmlをパーミッションを維持したままコピー
nginx.confも頂戴します。 nginx.conf
カードは/mntにマウント

# cp -Rp /mnt/var/www/html /var/www
# cp /mnt/etc/nginx/nginx.conf /etc/nginx

www-data設定

# visudo
www-data  ALL=(ALL) NOPASSWD: ALL 追記
# gpasswd -a www-data audio
ユーザ www-data をグループ audio に追加
# systemctl stop nginx php7.3-fpm
# usermod -s /bin/bash www-data -d /var/www/html/www-data
# systemctl start nginx php7.3-fpm

pulse/client.conf

~/.config/pulse/client.conf

autospawn = no
daemon-binary = /bin/true
default-server = 127.0.0.1

default-serverを設定することで現在のユーザー(pi)はpulseaudioをスタートできなくなります。
www-dataからスタート
今までsudo -u www-data pulseaudio –startを実行していましたが正解はこっちですね。(起動はする)変なエラーがなくなります。

$ sudo runuser -l www-data -c 'pulseaudio --start'

pulseaudioセレクトメニュー

音声の出力先を決めるのは~/.config/pulse/client.confのdefault-serverになります。
moOde audioと同様にpulseaudioがスタートしていないと(I2Sデバイス)自ホストからの再生は100%で出力します。
確実にpulseaudioサーバーを切り替えできるようpulseaudioセレクトメニューを作成

pulse-select.py
作成したpulse-select.pyを実行、チェックボタンで現在の設定を確認
client.confはmoOde audioに設定 pulseaudioは –kill
pavucontrolを起動するとclient.confに設定しているアドレスのマシン状態を表示
moOde audioはpulseaudioを–killしているので表示なし


白Piボタンを実行
client.confを自ホストに書き換えてpulseaudio –start
pavucontrolを起動、pulse.phpにアクセス
pulse.phpはpulseaudioが–startしていれば自ホストにアクセス
I2SデバイスがBuilt-in Audio Stereo、pulse.phpの音量コントロールで連動して動いていればOK


pavucontrolは常時起動しておく必要があります。
www-dataがスタートするpulseaudioはアクセスが無いと–killします。pavucontrolを起動しておくことでスタート状態を保持します。アンプに接続、再生確認
moOdeボタンは再度client.confを書き換えてmoOde audioに切り替え(pulseaudio –kill)


各マシンもclient.confのdefault-serverをPi4のアドレスに切り替えることでPi4で再生
Pi3もメニューを作成
赤Piボタンを実行


Pi4の/var/www/html/pulse.php
動画再生時もリモートで音量コントロールが可能です。

Raspberry Pi OS (32-bit) with desktop CUPS Server

今回はRaspberry Pi4にプリンタを接続、ローカルのネットワークプリンタ(CUPS Server)として設定してみます。

プリンタは相変わらずの激安プリンタCanon iP2700を接続、Pi4から印刷そしてローカルのマシンはRaspberry Pi3,Windows(ASUS X200MA)からの印刷を試してみたいと思います。

Canon iP2700

iP2700も旧品番となってしまいました。

$ lsusb
Bus 001 Device 003: ID 04a9:10d3 Canon, Inc.

CUPS

# apt install cups

cupsを設定するためにユーザーをlpadminに加えます。

$ sudo gpasswd -a pi lpadmin
ユーザ pi をグループ lpadmin に追加
$ id pi
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(input),109(netdev),999(spi),998(i2c),997(gpio),121(lpadmin)

Pi4のwebブラウザからアクセス

http://localhost:631/


外部からアクセスする時は
hostname:631
ipaddress:631


管理 パスワード入力


プリンターの追加 Canon iP2700


名前 説明 場所 適当に
共有 チェック
続ける


モデルを選んでプリンターの追加


デフォルトオプションの設定 クリック


プリンターが追加されて待機中の画面になります。
メンテナンスからテストページの印刷ができます。

CUPS 設定ツール system-config-printer

CUPSの状態はsystem-config-printerからもみれます。

# apt install system-config-printer


vncserver上では制約があります。
プロパティはダブルクリックすると現れます。
デバイスURl: usb://Canon/iP2700%20series?serial=39AE02
製造元とモデル: Canon iP2700 series – CUPS+Gutenprint v5.3.1
ここまでPi4からは印刷可能ですが外部のマシンからは印刷できません。

ネットワークプリンター

外部のマシンから印刷を許可するためにcupsd.confを編集します。
16行目 Listen localhost:631
デフォルトはローカルホストからのみ印刷を受ける設定になっています。
Port 631とすることで外部からもListenします。
その他 Location のアクセス設定がありますが取り敢えず4箇所とも許可しました。
/etc/cups/cupsd.conf (変更箇所)

# Only listen for connections from the local machine.
Port 631
Listen /run/cups/cups.sock

# Restrict access to the server...
<Location />
  Order allow,deny
  Allow @Local
</Location>

# Restrict access to the admin pages...
<Location /admin>
  Order allow,deny
  Allow @Local
</Location>

# Restrict access to configuration files...
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
  Allow @Local
</Location>

# Restrict access to log files...
<Location /admin/log>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
  Allow @Local
</Location>

cups再スタート

# systemctl restart cups

cupsクライアント

クライアント側も同様にcupsとsystem-config-printerをインストール

# apt install cups system-config-printer
# gpasswd -a pi lpadmin


Pi3からsystem-config-printerを起動するとプリンターが見えています。(印刷可能)


デバイスURl: implicitclass://Canon_iP2700_series_pi4/
製造元とモデル: Remote printer: Canon iP2700 series – CUPS+Gutenprint v5.3.1
cupsを新規にインストールするとcupsのバックエンドで動いている何かが自動でimplicitclassを設定するようです。


プリンターを削除したり既存のsystem-config-printerから新たに追加する場合はimplicitclassは見当たらない(設定できない?)
ロックを解除してADD
ネットワークプリンターを検索。
自動で検出しているDNS-SD経由のプリンターはRemote printerとして認識してくれません。
ホスト名にホストネームかIPアドレスを入れてFind


ippで接続します。


プリンター登録
印刷OK


OSによって表示は多少違いますがRaspberryではRemote printerとして表示(認識)してないとネットワークプリンターには接続できないようです。


WindowsではCanonのドライバーを入れた記憶があります。
あとはBonjour Print Servicesをインストール、実行することですぐつながるはずです。

Pi4-プリンター間は2m位離れているのでUSB延長ケーブルでつないでいます。
これまではPi1BをCUPSサーバーにしていたのですがWindowsからの印刷速度は早いのですがRaspberryからは遅い。やはりメーカー製ドライバーの違いでしょうか!
Pi4では馬力があるせいかずいぶん改善しました。

Top