Raspberry Pi ZERO アプリケーションランチャ

前回作成したウィンドウマネージャの切り換えは若干使い勝手が悪いのでもう少しシンプルにアプリケーションランチャとしても応用ができるよう変更してみました。

style

参考にしたサイトのサンプルはtkinter.ttkモジュールを使用しています。
ボタンだけの確認ですが少し試してみました。
~/bin/style.pyを作成して実行

from tkinter import *
from tkinter import ttk
style = ttk.Style()
all_theme = style.theme_names()
print(all_theme)

$ python3 style.py
('clam', 'alt', 'default', 'classic')

ディフォルトでは4つのテーマが使えるようです。下記のプログラム10行目附近に設定を入れています。

左上から
default
alt
clam
classic(下)
影が付いたりボタンの間隔が違っています。ほかの要素が入ればもう少しはっきりわかると思います。

プログラム

ウインドウマネージャの切り換えはボタンのクリックでxstartupをコピー即reboot動作に入るようにしました。
shutdownボタンでパワーオフ、exitボタンはなにもしないで終了します。
shutdownボタン、exitボタンの画像は100×48で適当に作成しました。
サンプルプログラムは画像でボタンの大きさが決まります。

~/bin/wm.py

#!/usr/bin/python3

from tkinter import *
from tkinter import ttk
import os

root = Tk()
root.title('WM Select')
# style
style = ttk.Style()
style.theme_use('default') #('clam', 'alt', 'default', 'classic')

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

# Button 1
def dwm():
    os.system("cp ~/.vnc/xstartup.dwm ~/.vnc/xstartup")
    os.system("sudo reboot")
icon1 = PhotoImage(file='~/.icons/dwm.png')
button1 = ttk.Button(
    frame1,
    image=icon1,
    command=dwm)
button1.grid(row=1,column=1)

# Button 2
def openbox():
    os.system("cp ~/.vnc/xstartup.openbox ~/.vnc/xstartup")
    os.system("sudo reboot")
icon2 = PhotoImage(file='~/.icons/openbox.png')
button2 = ttk.Button(
    frame1,
    image=icon2,
    command=openbox)
button2.grid(row=1,column=2)

# Button 3
def shutdown():
    os.system("sudo poweroff")
icon3 = PhotoImage(file='~/.icons/power100x48.png')
button3 = ttk.Button(
    frame1,
    image=icon3,
    command=shutdown)
button3.grid(row=2,column=1)

# Button 4
def cancel():
    root.quit()
icon4 = PhotoImage(file='~/.icons/exit100x48.png')
button4 = ttk.Button(
    frame1,
    image=icon4,
    command=cancel)
button4.grid(row=2,column=2)

root.mainloop()

ランチャ

ランチャのアイコンは/usr/share/icons/以下から32×32サイズを適当に拾ってきました。
横に並べるか縦に並べるかはrow=1にするかcolumn=1にするかで決まります。
実行はos.system(“pcmanfm &”) (&を入れないとランチャに制御が戻らない)

# Button 2
def pcmanfm():
    os.system("pcmanfm &")
icon2 = PhotoImage(file='~/.icons/pcmanfm.png')
button2 = ttk.Button(
    frame1,
    image=icon2,
    command=pcmanfm)
button2.grid(row=1,column=2)


ちょっとした用途にはいろいろ応用が効くと思います。

Raspberry Pi ZERO ウィンドウマネージャを切り換える

ZEROのウィンドウマネージャはopenboxとdwmがインストールされています。スタック型かタイル型かは使い勝って、好み次第と思いますがどちらも一長一短があります。

ZEROではdwmをメインに使っていますがPi3と比較することもあることから簡単に切り換えできるようにしてみたいと思います。

xstartup

ウィンドウマネージャを変更するには~/.vnc/xstartupを編集することで切り換えることができます。
具体的な内容は前回までに掲載しています。異なる箇所を挙げるとopenboxはデフォルトのウィンドウマネージャに設定されているのでlxpanelを起動、dwmはlxpanelを外してdwmを明示的に記載することで変更することができます。
それぞれを別ファイルとして保存します。
xstartup.openbox
xstartup.dwm
切替時は$ cp xstartup.openbox xstartupとかしてrebootすればそれぞれのウィンドウマネージャで立ち上がることになります。

python3

上記の動作は簡単なスクリプトでも可能ですが今回はpythonを使ってみました。
pythonはウルトラの初心者ですが勉強のためpythonで作成しようと思います。
といってもweb上の記事(サンプル)を参考にしているだけですが(-。-;)

raspbian-liteにはpython2.7とpython3.5が含まれています。

python --version
Python 2.7.13

ディフォルトはPython2ですね。python3系に変更することも可能ですがraspbianではfile managerのrangerがpython2系になっているためディフォルトはPython2のままにして明示的にpython3で実行します。
次期raspbianのBusterでは間違いなくpython3系がディフォルトになると思います。

raspbian-liteでは必要なモジュールが含まれていないのでインストールします。

# apt install python3-pip python3-tk python3-rpi.gpio

参考サイト Python 入門 Button – Tkinter のウィジェット
参考サイトからtkinterを使用して少し見栄えのいいUIにします。

画像付きのボタンをクリックでxstartupのコピーを実行します。
選択したラベルを表示
Rebootボタンで再起動

~/bin/wm.py

#!/usr/bin/python3

from tkinter import *
from tkinter import ttk
import os

root = Tk()
root.title('WM Select')
s = StringVar()

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

# Button 1
def dwm():
    button1.state(['pressed'])
    button2.state(['!pressed'])
    s.set("WM: dwm")
    os.system("cp ~/.vnc/xstartup.dwm ~/.vnc/xstartup")
icon1 = PhotoImage(file='~/.icons/dwm.png')
button1 = ttk.Button(
    frame1,
    image=icon1,
    command=dwm)
button1.grid(row=1,column=1)

# Button 2
def openbox():
    button1.state(['!pressed'])
    button2.state(['pressed'])
    s.set("WM: openbox")
    os.system("cp ~/.vnc/xstartup.openbox ~/.vnc/xstartup")
icon2 = PhotoImage(file='~/.icons/openbox.png')
button2 = ttk.Button(
    frame1,
    image=icon2,
    command=openbox)
button2.grid(row=1,column=2)

# Button 3
def button3_clicked():
    os.system("sudo reboot")
button3 = ttk.Button(
    frame1,
    width=13,
    text='Reboot',
    command=button3_clicked)
button3.grid(row=3,column=1)

# Button 4
def button4_clicked():
    os.system("sudo reboot")
button4 = ttk.Button(
    frame1,
    width=13,
    text='Reboot',
    command=button4_clicked)
button4.grid(row=3,column=2)

# Button 5
def button5_clicked():
    os.system("sudo poweroff")
button5 = ttk.Button(
    frame1,
    width=13,
    text='Power OFF',
    command=button5_clicked)
button5.grid(row=4,column=1)

# Button 6
def button6_clicked():
    root.quit()
button6 = ttk.Button(
    frame1,
    width=13,
    text='Cancel',
    command=button6_clicked)
button6.grid(row=4,column=2)

# Label 1
label1 = ttk.Label(
    frame1,
    font='monospace, 16',
    foreground='#E71794',
    textvariable=s)
label1.grid(row=2,column=1,columnspan=2)

root.mainloop()
$ chmod 755 ~/bin/wm.py


画像ファイルは~/.iconsに入れておきます。
Cancelで終了、但し一旦書き込んだxstartupは元に戻さないので取り消すには再度書き込んでやります。
Rebootボタンは2個ありますがどちらも同じです。

起動はxbindkeysからファンクションキーに割り当てました。
openboxは更にlxpanelに登録しています。
メニューエディタをインストール、登録してアプリケーションランチャに登録しています。
~/.config/lxpanel/を直接編集してもいいでしょう。

# apt install alacarte

Raspberry Pi ZERO サブシステム(インストール 設定)

作成したPi ZERO サブシステムは前回のzero wと基本同じ構成をとっています。
Pi ZEROをX環境下で軽快に動作させるには
過度な装飾は避ける
動画は再生しない
大物のアプリケーションはインストールしない
Xorgはそれほど大きなプログラムでも無いので目的、用途を絞って使えばX環境でもある程度快適に使用できるものと思います。

Xorg

# apt update && apt upgrade
# reboot
$ df -m
ファイルシス   1M-ブロック  使用 使用可 使用% マウント位置
/dev/root             7402  1037   6032   15% /

xorgインストール

# apt install xorg
# reboot
$ df -m
ファイルシス   1M-ブロック  使用 使用可 使用% マウント位置
/dev/root             7402  1138   5932   17% /

x11-apps(xclock,xcalcなど)も含まれているのでxorg本体としては100MBを切っています。

今回は–no-install-recommends xserver-xorgからインストールしてみました。

# apt install --no-install-recommends xserver-xorg
# reboot
$ df -m
ファイルシス   1M-ブロック  使用 使用可 使用% マウント位置
/dev/root             7402  1056   6013   15% /

xtermや日本語入力などインストールしていくと依存関係でどんどん追加されていきます。
結果的にxorgからインストールしたものと比べると8割位は導入されるようです。
統合環境(LXDE,XFCE4など)は様々なアプリケーション、ユーティリティが走っているのでシステム全体としては大きく重くなっています。

WM(ウィンドウマネージャ)

ZERO Wではopenboxとdwmを導入しましたが今回も同様にインストールしています。
dwmをメインにしていますが切り替えはxstartupを少し変更するのみで可能です。
dwmはZERO Wでコンパイルしたものを/usr/local/binにコピーしています。
特にパッケージからインストールしなくても前回の手法でalternativesに登録できます。

Ethernet(イーサネット)

ケースにはNO:9700のシールがあったのですが何かと思ったらSR9700というチップが載っているですね。

ZEROから認識するのはいいのですが速度が出ないようです。音楽用途には使えません。
当サイトではネットワークの実験用、raspbian以外のOS用を想定しているので取り敢えずはヨシとしときましょう。
貧乏でジャンク好きの性と言ったところでしょうか!

$ lsusb
Bus 001 Device 007: ID 0fe6:9700 Kontron (Industrial Computer Source / ICS Advent) DM9601 Fast Ethernet Adapter

やはりこいつは大分評判が良くないようです。

raspbianのdhcpcd.confでは特にデバイス名を指定していないのでwifiの代わりにケーブルを接続すると同じアドレスが割り当てられます。wifiドングルは起動前に挿し込んでおく必要があります。起動後に挿し込むとリブートします。

Run(reset) Shutdown

Run(reset)ボタン
取り出したRun Pinはタクトスイッチに接続しています。
Shutdown後はこのスイッチで起動を開始します。ハングアップした際はRebootします。

Shutdownボタン
GPIOを利用してShutdownを実行します。

# apt install wiringpi

shutdownプログラムは以下のサイトを参考にさせて頂きました。
http://jellyware.jp/kurage/raspi/shutdown_button.html

~/bin/shutdown.py

#!/usr/bin/python 

import RPi.GPIO as GPIO
import time
import os

pinnumber=21
GPIO.setmode(GPIO.BCM)

# GPIO 21(BCM) pull up
GPIO.setup(pinnumber,GPIO.IN,pull_up_down=GPIO.PUD_UP)

while True:
  GPIO.wait_for_edge(pinnumber, GPIO.FALLING)
  count = 0 

  while True:
    sw_status = GPIO.input(pinnumber)
    if sw_status == 0:
      count = count + 1 
      if count >= 20: 
        os.system("sudo shutdown -h now")
        break
    time.sleep(0.1)
$ chmod 755 ~/bin/shutdown.py

実行は~/.vnc/xstartupに書いておきます。

shutdown.py &

ここでリブート

$ gpio readall
GPIO21(BCM)実ピン40が 1 IN になっていれば正常に読み込んでいます。
ディフォルトがこの値になっていると思います。
2秒の長押しでshutdownを開始します。
pythonはインデントを認識します。編集する際は正しく合わせてください。

Auto Mount

ZEROを使う目的のひとつに新規カード作成作業があります。
Pi3ではSSDが/dev/sdbとして認識されていますがひとつ間違えるとそこで痔エンドとなってしまいます。
オートマウントがあると便利です。

# apt install udiskie

udisks2は依存関係でインストールされます。
ユーザー権限でマウントするにはPolicyKitを設定します。(URL下の方を設定)
https://github.com/coldfix/udiskie/wiki/Permissions
raspbianではunix-group:plugdevに変更します。
/etc/polkit-1/localauthority/50-local.d/10-udisks.pkla(新規作成)

[udisks1]
Identity=unix-group:plugdev
Action=org.freedesktop.udisks.filesystem-mount;org.freedesktop.udisks.luks-unlock;org.freedesktop.udisks.drive-eject;org.freedesktop.udisks.drive-detach
ResultAny=yes

[udisks2]
Identity=unix-group:plugdev
Action=org.freedesktop.udisks2.filesystem-mount;org.freedesktop.udisks2.encrypted-unlock;org.freedesktop.udisks2.eject-media;org.freedesktop.udisks2.power-off-drive
ResultAny=yes

[udisks2-other-seat]
Identity=unix-group:plugdev
Action=org.freedesktop.udisks2.filesystem-mount-other-seat;org.freedesktop.udisks2.filesystem-unmount-others;org.freedesktop.udisks2.encrypted-unlock-other-seat;org.freedesktop.udisks2.eject-media-other-seat;org.freedesktop.udisks2.power-off-drive-other-seat
ResultAny=yes

デフォルトは/media/USER/以下にマウントします。
/media/以下に直接マウントしたい場合は
/etc/udev/rules.d/99-udisks2.rules(新規作成)

ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{UDISKS_FILESYSTEM_SHARED}="1"

udisks2を有効に

# systemctl enable udisks2

udiskieの起動はxstartupから
~/.vnc/xstartup (現在のxstartup)

#!/bin/csh
xmodmap -e "keysym Meta_L = Super_L"
xmodmap -e "keysym Meta_R = Super_R"
xrdb $HOME/.Xresources
xsetroot -solid black
xsetroot -cursor_name left_ptr
shutdown.py &
autocutsel &
date.sh &
xbindkeys &
xterm -e ranger --confdir=~/.config/ranger &
udiskie &
dwm &
scim -d
/etc/X11/Xsession

設定が終わったらリブート

LXDEとは挙動は違いますがUSB(カード)を挿し込むだけでマウントします。
pcmanfmのmediaはブックマークに登録しています。

特にアンマウントする必要も無さそうでfdisk実行時も自動でアンマウント、終了で再マウントしているようです。

マイクロUSBからも正常に認識、読み込みをしています。

今回Ethernetははずれでしたが個人的には今回の作品は気に入ってます。
これでddも気兼ねなくできそうです。

Raspberry Pi ZERO サブシステムを構築する

現在Raspberry Pi Zero(Zero W)は在庫も豊富で特にZeroは798円(648+150 スイッチサイエンス)と求めやすい価格で入手することができます。
手元にはPi1B,Pi2で使用してきたWiFiドングルがあります。またセリアの100均ハブ(現在入手不可)も使えるものがあります。
前回のZero Wは主にエマージェンシー目的で構築しましたがそれらを含めて当サイトのメインマシンPi3のサブシステムとして常時利用するため新たにPi ZEROで作成してみようと思います。

Raspberry Pi ZERO

手持ちの中にロングのピンヘッダがあります。
今回は上下(表裏)からGPIOを利用、固定するため下側にも同じ長さを切りそろえます。
ベースの基板は70×50の標準基板

Zeroには外部へUSBコネクタを引き出すためのランドが用意されています。このランドを利用してUSBハブを接続します。
公式Schematicsを見るとpp22,pp23は単に既存のUSB端子D+,D-のラインになっています。
したがってここに接続した場合はZero側のUSB端子は利用不可になります。

USB HUB

*セリアの100均ハブは現在入手不可のため参考程度に願います。
USBオスは外してピンヘッダに換装
裏の空きパターンに接続することで4ポート仕様になります。
ひとつは有線Lanをもう一つはマイクロUSB(B)タイプを増設

イーサネット

USB 2.0 to RJ45 Ethernet Lan Network Adapter AliExpress $1.77で購入
中身を取り出してピンヘッダに付け替えます。

ベースボード

いきなり完成形になってしまいましたが中央のピンソケットにZeroを差し込みます。
ZeroにはRun(Reset) Pinも取り付けています。タクトスイッチでRun(Reset)
電源入力用にマイクロUSB端子を取り付けGPIO 5Vラインに供給しています。この端子からの入力はトグルスイッチで物理的にオフすることができます。Zero本体からの供給も可能です。
またもう一つのタクトスイッチはGPIOを利用してシャットダウンを実行します。
マイクロUSB端子はAliExpressで1個あたり10円くらいで入手できます。
USB端子のVUSB,GNDはベース基板の5V,GNDに接続

HUBのUSB端子上面には絶縁用シールを貼り付けておきます。またHUBの半田面はICより低くしてICを基板に密着させピンヘッダの高さを合わせはんだ付けで固定
Lanアダプタはフラットな部分にゴム板を敷いて両面テープで貼り付けます。
底板は適当に詰物をしてポリカプラダンを貼り付けています。


Zero単体よりはスペースを取ってしまいますがそれでもPi3と比べるとずっとコンパクトになっています。WiFiを使用すれば紐付きは電源コード1本となりGPIOの実験など非常に取り回しが良くなります。

基本のインストール手順、設定は前回のZERO Wと同じですがGPIOの設定、少々追加の機能など次回にまとめてみたいと思います。

Raspberry Pi ZERO W (dwm コンパイル)

Pi ZERO Wにインストールしたデスクトップ環境はNexus7からも操作可能な7インチ相当の画面サイズですがタイル型WMにはどうかと思ったのですが思った以上に好結果を得ることができました。画面を有効に活用できるタイル型は小さな画面にも最適と思います。

今後ローカル内で運用するサーバー、実験環境にもX + tightvncを導入する予定でいます。

さて実際使ってみるとやはり若干気になる箇所もあります。

バーの文字が小さい
バーの色も変更したい
ウインドウ同士の間に妙な隙間ができる。中央では出ない
一部キーを変更したい

dwmの設定を変更するにはソース(config.h)を編集してmakeしなければいけません。
開発元のsuckless.orgにはdwm 6.2がリリースされています。

ライブラリのインストール

# apt install make gcc libx11-dev libxinerama-dev libxft-dev

ソースのダウンロード、編集

適当なディレクトリにダウンロード、展開

$ wget https://dl.suckless.org/dwm/dwm-6.2.tar.gz
$ tar -xvf dwm-6.2.tar.gz
$ cd dwm-6.2
$ cp config.def.h config.h

config.hの編集をするのですがエラーが出てしまうのでdrw.cの編集をします。

FC_COLORなんたらでエラーになります。
当サイトのスキルでは理解不能なのでなんちゃってコンパイルになってしまいますがこの項目をパスすることにします。

drw.c 以下コメントにします

142 /*
143   FcBool iscol;
144   if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
145     XftFontClose(drw->dpy, xfont);
146     return NULL;
147   }
148 */

354 //      FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);

config.hの編集
参考サイト https://wiki.mma.club.uec.ac.jp/clear/dwm

フォントサイズ
  8 static const char *fonts[]          = { "monospace:size=11.5" };
  9 static const char dmenufont[]       = "monospace:size=11.5";
バーカラー
 14 static const char col_cyan[]        = "#3259A8";
ウィンドウ比率 0.55 から 0.50
 35 static const float mfact     = 0.50;
resizehints 1 を 0
 37 static const int resizehints = 0;
モードキー Mod1Mask から Mod4Mask
 47 #define MODKEY Mod4Mask
moodekey +d を moodekey +u
 70   { MODKEY,                       XK_u,      incnmaster,     {.i = -1 } },
moodekey + shife +c を moodekey +c
 75   { MODKEY,                       XK_c,      killclient,     {0} },

コンパイル実行

# make clean install

Pi ZERO Wで20秒位 エラーなくmake通りました
実行ファイルは/usr/loca/bin/dwm
パッケージからインストールしたdwmは/usr/bin/dwmなのでalternativesに登録します。

$ sudo update-alternatives --install /usr/bin/dwm dwm /usr/local/bin/dwm 90
$ sudo update-alternatives --config dwm
  0            /usr/bin/dwm.default      100       自動モード
  1            /usr/bin/dwm.default      100       手動モード
  2            /usr/bin/dwm.maintainer   50        手動モード
  3            /usr/bin/dwm.web          50        手動モード
* 4            /usr/bin/dwm.winkey       50        手動モード
  5            /usr/local/bin/dwm        90        手動モード

5 /usr/local/bin/dwm を選択


一通り試しましたが特に問題無さそうです。


mod4+f フロートでアプリケーションを起動すると通常のサイズで起動
mod4+mouseで移動可能 終了はq


ウインドウ同士もピッタリくっつきました。
キーはお好みで。
縦分割、横分割はmod4+iに対して隣のmod4+uに変更。自分にとってはわかりやすい

作成した3個の色違いは再利用できるようalternativesに登録しておきます。
コンパイルが完了したら都度わかりやすいファイル名でコピーを取ります。

# cp dwm /usr/local/bin/dwm_B
---
# update-alternatives --install /usr/bin/dwm dwm /usr/local/bin/dwm_B 80
# update-alternatives --install /usr/bin/dwm dwm /usr/local/bin/dwm_G 80
# update-alternatives --install /usr/bin/dwm dwm /usr/local/bin/dwm_R 80

呼び出す時は

$ sudo update-alternatives --config dwm


再コンパイル時は
5 /usr/local/bin/dwm を選択しておきます。

右隅に簡易な時計を表示(表示フォーマット、sleepは適当に)
~/bin/date.sh (chmod 755)

#!/bin/sh
while true; do
  xsetroot -name "$(date +"%R")"
  sleep 10
done

~/.vnc/xstartup 適当に追記

date.sh &

Top