RaspberryPi 4 (Raspbian Buster)とiPadでKIOSK端末を作成する

この記事は以前投稿した「<a href="https://qiita.com/osprey74/items/3eea71c93ffe9c90c54c">RaspberryPiとiPadでKIOSK端末を作成する</a>」のアップグレード版となる。尚、記事中のスクリーンショット等は旧記事からの流用もある。ご了承願う。

執筆時点（2019/12/24）では対象となるRaspberry Pi 4 Model B 4GB版がUSB起動をサポートしておらず、`Raspberry Pi 4 Model B 4GB版`を用い、`SDカードを起動ストレージとして`運用、`SDカードの寿命延長を目的としてSWAPメモリの停止とログファイルをRAMDISKへ退避`する。

#サーバの構築
##OSの準備

サーバ機となるRaspberry Pi 4 Model BのOSとしてRaspbian Buster をインストールする。OSイメージを[公式サイト](https://www.raspberrypi.org/downloads/raspbian/ "RASPBIAN")からダウンロード（`Raspbian Buster Lite`）、SDカードにOSを書き込む（以下母艦となるmacOS環境下のterminalにて操作）。

- SDカードを母艦にマウントする。
- terminalにてマウント状況を確認。

```shell
$ diskutil list
～略～
/dev/disk4 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.5 GB    disk4
   1:             Windows_FAT_32 SONY_16W3               15.5 GB    disk4s1
```

- パーティションのマウントを解除

```shell
$ sudo diskutil umountDisk /dev/disk4s1
Password:
Unmount of all volumes on disk4 was successful
```

- OSを書き込む

```shell
$ sudo dd bs=1m if=/Users/ユーザ名/Downloads/2018-06-27-raspbian-stretch-lite.img of=/dev/rdisk4
1776+0 records in
1776+0 records out
1862270976 bytes transferred in 66.405962 secs (28043732 bytes/sec)
```

- ヘッドレスにて構築する為にSSH接続を有効化する。SDカード内`/boot`パーティション内に空ファイル`ssh`を作成。

<img width="324" alt="スクリーンショット 2019-12-24 16.07.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279688/95c376e4-e26e-9c15-aa6e-2b3ca8abc2b4.png">


##Raspberry Piの初期設定
Raspberry PiにLANケーブルとOSを書き込んだSDカード、電源コードを接続し起動する。
以下、母艦のterminalから操作。

```shell
ssh pi@raspberrypi.local
The authenticity of host 'raspberrypi.local (fe80::36dd:a2b8:dbd8:1f69%en0)' can't be established.
ECDSA key fingerprint is SHA256:Wg0y80N8knalmKWJE6b51wJXk5Q34sueLzuWoNzsT3U.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'raspberrypi.local,fe80::36dd:a2b8:dbd8:1f69%en0' (ECDSA) to the list of known hosts.
pi@raspberrypi.local's password: 
Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

pi@raspberrypi:~ $ 
```

今回は閉鎖環境下での運用であり、アクセスするユーザも限定されることからユーザの新規追加は行わず、デフォルトユーザ`pi`のパスワードを変更する。

```shell
pi@raspberrypi:~ $ sudo passwd pi
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
pi@raspberrypi:~ $ 
```

システムの初期設定やアップデートなどを行う。

```shell
pi@raspberrypi:~ $ sudo raspi-config

┌────────────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├────────────────┐
│                                                                                           │
│    1 Change User Password Change password for the current user                            │
│    2 Network Options      Configure network settings                                      │
│    3 Boot Options         Configure options for start-up                                  │
│    4 Localisation Options Set up language and regional settings to match your location    │
│    5 Interfacing Options  Configure connections to peripherals                            │
│    6 Overclock            Configure overclocking for your Pi                              │
│    7 Advanced Options     Configure advanced settings                                     │
│    8 Update               Update this tool to the latest version                          │
│    9 About raspi-config   Information about this configuration tool                       │
│                                                                                           │
│                                                                                           │
│                        <Select>                           <Finish>                        │
│                                                                                           │
└───────────────────────────────────────────────────────────────────────────────────────────┘
```

raspi-configで最低限必要な設定は以下4点。`Finish`を選択すると再起動する。

* 4 Localisation Options
    * **I4 Change Wi-fi Country**
      * JP Japan（※ Wi-Fiを使用するために使用国を設定する）
* 7 Advanced Options
    * **A1 Expand Filesystem**（※ ファイルシステムの最適化（為念））
    * **A3 Memory Split**
      * 2（※ 今回は用途としてGPUは使用しない為、メモリ割り当てを最低に設定する）
* **8 Update**

aptコマンドを用いて環境のアップデート。

```shell
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get upgrade
pi@raspberrypi:~ $ sudo apt-get dist-upgrade
```

Raspberry Piに表面実装されているLEDはpowerLED（赤）とaccessLED（緑）の2つ。サーバの稼働状況が判別しやすいよう、powerLEDをheartbeatモード（ここでは「powerLEDが1秒ごとに2回点滅する」ことを指す）に変更する。
適当なエディタで`/boot/config.txt`を開き、以下2行を追加する。

```shell:/boot/config.txt
# turn power LED into heartbeat
dtparam=pwr_led_trigger=heartbeat
```

サーバの再起動後、powerLEDがheartbeatモードに変更されていれば完了。

##サーバアプリケーションのインストール

###apache2

```shell
pi@raspberrypi:~ $ sudo apt-get install apache2
```

以下コマンドでapache2の稼働状況を確認する（`Active: active (running) `）。

```shell
pi@raspberrypi:~ $ systemctl status apache2
● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-08-14 06:28:53 UTC; 58s ago
～以下略～
```

適当なエディタで`/etc/apache2/apache2.conf`を開き、以下当該箇所を修正する。

```shell:/etc/apache2/apache2.conf
<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>
     ↓
<Directory /var/www/>
   Options FollowSymLinks
   AllowOverride All
   Require all granted
</Directory>
```

apache2を再起動後（`sudo service apache2 restart`）、母艦のブラウザから`http://raspberrypi.local`にアクセスしapache2デフォルト画面が表示されたら完了。
![apache2.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/f073efe4-2bfc-32ae-c956-bd78e8986795.jpeg)

以下コマンドを実行し、ウェブコンテンツの保存先フォルダーへ書き込み属性を追加する。

```shell
pi@raspberrypi:~ $ cd /var/www
pi@raspberrypi:~ $ sudo chmod 0755 *
pi@raspberrypi:~ $ cd html
pi@raspberrypi:~ $ sudo chmod 0644 *
```

###samba
更新：前回はsambaによるファイル共有を行ったが、今回はsftpを用いる。よってsambaのインストールは行わない。

###Wi-Fi アクセスポイント化
更新：前回の記事以降、ネットワーク周りの記述方法が大きく変更された。よって以下の通り内容を全面的に書き換える。

```shell
pi@raspberrypi:~ $ sudo apt-get install hostapd dnsmasq
```
※ 今回`dnsmasq`は簡易DHCPサーバとしてのみ使用する。

無線LANが有効か確認する。以下コマンドを実行し、`wlan0`を認識していることを確認する。

```shell
pi@raspberrypi:~ $ iwconfig
wlan0     IEEE 802.11  Mode:Master  Tx-Power=31 dBm   
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:on
          
eth0      no wireless extensions.

lo        no wireless extensions.

pi@raspberrypi:~ $ 
```

適当なエディタで`/etc/network/interfaces.d/wlan0`を新規ファイルとして作成、以下5行を追加する。

```shell:/etc/network/interfaces.d/wlan0（新規ファイル）
auto wlan0
iface wlan0 inet static
  post-up /usr/sbin/hostapd -B /etc/hostapd/hostapd.conf
  address 10.0.0.10
  netmask 255.255.255.0
```

なお、環境によって`hostapd`の起動後に`wlan0`が認識する場合がある。`wlan0`が起動された後に`hostapd`を起動しなおした。

適当なエディタで`/etc/hostapd/hostapd.conf`を新規ファイルとして作成、以下15行を書き込む。

```shell:/etc/hostapd/hostapd.conf（新規ファイル）
interface=wlan0
driver=nl80211
hw_mode=g
channel=6
ieee80211n=1
wmm_enabled=1
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
ssid=your-own-unique-SSID
wpa_passphrase=your-own-unique-passphrase
rsn_pairwise=CCMP
```

なお`ssid=your-own-unique-SSID`と`wpa_passphrase=your-own-unique-passphrase`は適宜適切な内容に変更する事。

適当なエディタで`/etc/default/hostapd`を開き、以下1行を書き込む。

```shell:/etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"
```

以下コマンドを実行し、設定が正常に成されているか確認する。

```shell
pi@raspberrypi:~ $ hostapd -d /etc/hostapd/hostapd.conf
```

システムの起動時に自動実行する様設定する。

```shell
pi@raspberrypi:~ $ sudo systemctl enable hostapd
```

サーバの再起動後、以下コマンドを実行し、正常に起動しているか確認する。

```shell
pi@raspberrypi:~ $ sudo systemctl status hostapd
● hostapd.service
   Loaded: masked (Reason: Unit hostapd.service is masked.)
   Active: inactive (dead)
pi@raspberrypi:~ $ 
```

以下コマンドを実行し、デフォルトの設定ファイルを別名保存する。

```shell
pi@raspberrypi:~ $ sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
```

適当なエディタで`/etc/dnsmasq.conf`を新規ファイルとして作成、以下6行を書き込む。

```shell:/etc/dnsmasq.conf（新規ファイル）
interface=wlan0
listen-address=10.0.0.10
bind-interfaces
domain-needed
bogus-priv
dhcp-range=10.0.0.20,10.0.0.30,24h

```

この際、`listen-address=10.0.0.10`で設定する`IPアドレス`は`/etc/network/interfaces.d/wlan0`で設定した`IPアドレス`と同一であることを確認する。

サーバの再起動後、設定したSSID／パスフレーズでのWi-Fi接続を確認する事。

##SWAPの無効化とログファイルをRAMDISKへ退避
###SWAP停止
SDカードへの書き込み回数を低減させる目的でSWAPメモリの無効化とログファイルの保存先をRAMDISKへ変更する。

以下一連のコマンドでSWAPメモリの無効化`sudo swapoff --all`とアンインストール`sudo apt-get remove dphys-swapfile`を行う。


```shell
pi@raspberrypi:~ $ free（SWAPメモリの確認）
              total        used        free      shared  buff/cache   available
Mem:        1000184       39280      869368       13336       91536      898628
Swap:        102396           0      102396

pi@raspberrypi:~ $ sudo swapoff --all（SWAPメモリの無効化）

pi@raspberrypi:~ $ free（SWAPメモリの再確認）
              total        used        free      shared  buff/cache   available
Mem:        1000184       38928      869032       13336       92224      899012
Swap:             0           0           0

pi@raspberrypi:~ $ sudo apt-get remove dphys-swapfile
```

サーバの再起動後、SWAPメモリが無効化されたのを確認する事。

###ログファイルをRAMDISKへ退避

適当なエディタで`/etc/fstab`を開き、各種ログファイルの保存先をRAMDISK化する設定（以下4行）を書き込む。

```shell:/etc/fstab
tmpfs /tmp tmpfs defaults,size=32m 0 0
tmpfs /var/tmp tmpfs defaults,size=16m 0 0
tmpfs /var/log tmpfs defaults,size=32m 0 0
tmpfs /var/www/mrtg tmpfs defaults,size=2m 0 0
```

サーバの再起動後`df -h`でtmpfsがマウントされているのを確認する。

```shell
pi@raspberrypi:~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        15G  1.6G   13G  12% /
devtmpfs        484M     0  484M   0% /dev
tmpfs           489M     0  489M   0% /dev/shm
tmpfs           489M   19M  470M   4% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           489M     0  489M   0% /sys/fs/cgroup
tmpfs            16M     0   16M   0% /var/tmp         ←←←
tmpfs           2.0M     0  2.0M   0% /var/www/mrtg    ←←←
tmpfs            32M  156K   32M   1% /var/log         ←←←
tmpfs            32M     0   32M   0% /tmp             ←←←
/dev/sda1        43M   22M   21M  52% /boot
tmpfs            98M     0   98M   0% /run/user/1000
```

システム起動時にテンポラリ上のログ格納ディレクトリを自動作成するスクリプトを以下内容で作成する。

```bash:/etc/init.d/make-varlog-files（新規ファイル）
#!/bin/bash
#
### BEGIN INIT INFO
# Provides:		  make-varlog-files
# Default-Start:	 2 3 4 5
# Default-Stop:	  0 1 6
# Required-Start:
# Required-Stop:
# Short-Description: Create /var/log/... files on tmpfs at startup
# Description:	   Create /var/log/... files needed by system daemon
### END INIT INFO

#
# main()
#
case "${1:-''}" in
	'start')

	############################
	# prepare /var/log subdir for ramdisk init on every boot

	mkdir -p /var/log/ConsoleKit
	mkdir -p /var/log/apache2
	mkdir -p /var/log/apt
	mkdir -p /var/log/fsck
	mkdir -p /var/log/ntpstats
	mkdir -p /var/log/samba

	chown root.adm /var/log/apache2
	chmod 750 /var/log/apache2
	chown ntp.ntp /var/log/ntpstats
	chown root.adm /var/log/samba

	############################
	# prepare /var/log file for ramdisk init on every boot

	touch /var/log/lastlog
	touch /var/log/wtmp
	touch /var/log/btmp
	touch /var/log/apache2/access.log
	touch /var/log/apache2/error.log
	touch /var/log/apache2/other_vhosts_access.log
	touch /var/log/apache2/ssl_access.log

	chown root.adm  /var/log/apache2
	chown root.adm /var/log/apache2/access.log
	chmod 640 /var/log/apache2/access.log
	chown root.adm /var/log/apache2/error.log
	chmod 640 /var/log/apache2/error.log
	chown root.utmp /var/log/lastlog
	chown root.utmp /var/log/wtmp
	chown root.utmp /var/log/btmp
	;;
	'stop')
	;;
	'restart')
	;;
	'reload'|'force-reload')
	;;
	'status')
	;;
	*)
	echo "Usage: $SELF start"
	exit 1
	;;
esac
```

スクリプトへ実行権限を付与、起動リンクを作成する。

```shell
pi@raspberrypi:~ $ sudo chmod 755 /etc/init.d/make-varlog-files

pi@raspberrypi:~ $ sudo update-rc.d make-varlog-files defaults 01 10
```

作成したスクリプトのランレベルをapache2より先にする。以下の例では`S01apache2`、`S01make-varlog-files`と同順となっているので`sudo mv S01apache2 S03apache2`とし、ランレベルをS03とした。

```shell
pi@raspberrypi:~ $ cd /etc/rc2.d

pi@raspberrypi:/etc/rc2.d $ ls -la
total 8
drwxr-xr-x  2 root root 4096 Aug 14 08:01 .
drwxr-xr-x 95 root root 4096 Aug 14 07:47 ..
lrwxrwxrwx  1 root root   29 Aug 14 06:28 K01apache-htcacheclean -> ../init.d/apache-htcacheclean
lrwxrwxrwx  1 root root   17 Aug 14 06:28 S01apache2 -> ../init.d/apache2
lrwxrwxrwx  1 root root   22 Jun 27 00:28 S01avahi-daemon -> ../init.d/avahi-daemon
lrwxrwxrwx  1 root root   19 Jun 27 00:26 S01bluetooth -> ../init.d/bluetooth
lrwxrwxrwx  1 root root   26 Jun 27 00:25 S01console-setup.sh -> ../init.d/console-setup.sh
lrwxrwxrwx  1 root root   14 Jun 27 00:11 S01cron -> ../init.d/cron
lrwxrwxrwx  1 root root   14 Jun 27 00:25 S01dbus -> ../init.d/dbus
lrwxrwxrwx  1 root root   16 Jun 27 00:30 S01dhcpcd -> ../init.d/dhcpcd
lrwxrwxrwx  1 root root   17 Aug 14 07:18 S01dnsmasq -> ../init.d/dnsmasq
lrwxrwxrwx  1 root root   24 Jun 27 00:27 S01dphys-swapfile -> ../init.d/dphys-swapfile
lrwxrwxrwx  1 root root   17 Aug 14 07:18 S01hostapd -> ../init.d/hostapd
lrwxrwxrwx  1 root root   27 Aug 14 08:01 S01make-varlog-files -> ../init.d/make-varlog-files
lrwxrwxrwx  1 root root   14 Aug 14 06:49 S01nmbd -> ../init.d/nmbd
lrwxrwxrwx  1 root root   17 Jun 27 00:11 S01paxctld -> ../init.d/paxctld
lrwxrwxrwx  1 root root   18 Jun 27 00:06 S01plymouth -> ../init.d/plymouth
lrwxrwxrwx  1 root root   22 Jun 27 00:17 S01raspi-config -> ../init.d/raspi-config
lrwxrwxrwx  1 root root   15 Jun 27 00:23 S01rsync -> ../init.d/rsync
lrwxrwxrwx  1 root root   17 Jun 27 00:11 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx  1 root root   21 Aug 14 06:49 S01samba-ad-dc -> ../init.d/samba-ad-dc
lrwxrwxrwx  1 root root   14 Aug 14 06:48 S01smbd -> ../init.d/smbd
lrwxrwxrwx  1 root root   13 Jun 27 00:28 S01ssh -> ../init.d/ssh
lrwxrwxrwx  1 root root   22 Jun 27 00:17 S01triggerhappy -> ../init.d/triggerhappy

pi@raspberrypi:/etc/rc2.d $ sudo mv S01apache2 S03apache2

pi@raspberrypi:/etc/rc2.d $ ls -la
total 8
drwxr-xr-x  2 root root 4096 Aug 14 08:03 .
drwxr-xr-x 95 root root 4096 Aug 14 07:47 ..
lrwxrwxrwx  1 root root   29 Aug 14 06:28 K01apache-htcacheclean -> ../init.d/apache-htcacheclean
lrwxrwxrwx  1 root root   22 Jun 27 00:28 S01avahi-daemon -> ../init.d/avahi-daemon
lrwxrwxrwx  1 root root   19 Jun 27 00:26 S01bluetooth -> ../init.d/bluetooth
lrwxrwxrwx  1 root root   26 Jun 27 00:25 S01console-setup.sh -> ../init.d/console-setup.sh
lrwxrwxrwx  1 root root   14 Jun 27 00:11 S01cron -> ../init.d/cron
lrwxrwxrwx  1 root root   14 Jun 27 00:25 S01dbus -> ../init.d/dbus
lrwxrwxrwx  1 root root   16 Jun 27 00:30 S01dhcpcd -> ../init.d/dhcpcd
lrwxrwxrwx  1 root root   17 Aug 14 07:18 S01dnsmasq -> ../init.d/dnsmasq
lrwxrwxrwx  1 root root   24 Jun 27 00:27 S01dphys-swapfile -> ../init.d/dphys-swapfile
lrwxrwxrwx  1 root root   17 Aug 14 07:18 S01hostapd -> ../init.d/hostapd
lrwxrwxrwx  1 root root   27 Aug 14 08:01 S01make-varlog-files -> ../init.d/make-varlog-files
lrwxrwxrwx  1 root root   14 Aug 14 06:49 S01nmbd -> ../init.d/nmbd
lrwxrwxrwx  1 root root   17 Jun 27 00:11 S01paxctld -> ../init.d/paxctld
lrwxrwxrwx  1 root root   18 Jun 27 00:06 S01plymouth -> ../init.d/plymouth
lrwxrwxrwx  1 root root   22 Jun 27 00:17 S01raspi-config -> ../init.d/raspi-config
lrwxrwxrwx  1 root root   15 Jun 27 00:23 S01rsync -> ../init.d/rsync
lrwxrwxrwx  1 root root   17 Jun 27 00:11 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx  1 root root   21 Aug 14 06:49 S01samba-ad-dc -> ../init.d/samba-ad-dc
lrwxrwxrwx  1 root root   14 Aug 14 06:48 S01smbd -> ../init.d/smbd
lrwxrwxrwx  1 root root   13 Jun 27 00:28 S01ssh -> ../init.d/ssh
lrwxrwxrwx  1 root root   22 Jun 27 00:17 S01triggerhappy -> ../init.d/triggerhappy
lrwxrwxrwx  1 root root   17 Aug 14 06:28 S03apache2 -> ../init.d/apache2
```

サーバを再起動しスクリプトを実行しておく。

##ホスト名を変更

適当なエディタで`/etc/hostname`および`/etc/hosts`の内容を適宜変更する。

```shell:/etc/hostname
raspberrypi
　↓
your-own-hostname
```

```shell:/etc/hosts
127.0.1.1       raspberrypi
　↓
127.0.1.1       your-own-hostname
```

サーバを再起動しホスト名が変更になったこと（sshでの接続先が変更）を確認する。

##終了／再起動／起動ボタンを実装する
薄膜パネルスイッチ [HC-543-3]の各ボタンへ以下のように機能を割り当てる。

- 赤: シャットダウン
- 黄: リセット
- 緑: 再開

薄膜パネルスイッチとRaspberry PiのGPIOを以下のように接続する。同時にケースへ格納する。

- GND：薄膜パネルスイッチ1番ピン（共通ピン）：ジャンパワイヤ（黒）
- GPI003：薄膜パネルスイッチ2番ピン（再開ボタン）：ジャンパワイヤ（緑）
- GPIO19：薄膜パネルスイッチ3番ピン（リセットボタン）ジャンパワイヤ（オレンジ）
- GPIO26：薄膜パネルスイッチ4番ピン（シャットダウンボタン）ジャンパワイヤ（赤）
- GPIO02：ケースファン（赤）
- GND：ケースファン（黒）

以下写真を参照の事。
![switch001.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/13a1ab82-baad-8583-2715-24140508e0c6.jpeg)
GND：薄膜パネルスイッチ1番ピン（共通ピン）：ジャンパワイヤ（黒）
GPI003：薄膜パネルスイッチ2番ピン（再開ボタン）：ジャンパワイヤ（緑）

![switch002.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/39c356f7-d1f6-9e51-395a-26a933d672c0.jpeg)
GPIO19：薄膜パネルスイッチ3番ピン（リセットボタン）ジャンパワイヤ（オレンジ）
GPIO26：薄膜パネルスイッチ4番ピン（シャットダウンボタン）ジャンパワイヤ（赤）

![switch003.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/638c1dae-7e36-6ded-8a3d-402661dc531c.jpeg)
GPIO02：ケースファン（赤）
GND：ケースファン（黒）

![switch004.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/f3eba75c-873f-105f-c220-57d43fe4490e.jpeg)
薄膜パネルスイッチのコネクタ部分

![inCase.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/0320dece-f9c3-30a9-24fa-544354cbad01.jpeg)
Raspberry Piをケースに固定した状態

![2018-08-14-13.06.jpg](https://qiita-image-store.s3.amazonaws.com/0/279688/df350f6c-faa4-b462-7e15-6c3d091bfc0e.jpeg)
ケースを閉じた状態（薄膜パネルスイッチは両面テープで貼付済）

以下コマンドを実行し、GPIOを制御するライブラリをインストールする。

```shell
pi@your-own-hostname:~ $ sudo apt-get install wiringpi
```

適当なエディタで`~/shutdown.py`および`~/reboot.py`を新規ファイルとして作成、それぞれに以下内容を書き込む。

```py:~/shutdown.py（新規ファイル）
#!/usr/bin/python
#coding:utf-8
import time
import RPi.GPIO as GPIO
import os

GPIO.setmode(GPIO.BCM)

#GPIO26pinを入力モードとし、pull up設定とします
GPIO.setup(26,GPIO.IN,pull_up_down=GPIO.PUD_UP)

GPIO.wait_for_edge(26, GPIO.FALLING)

os.system("sudo shutdown -h now")

GPIO.cleanup()
```

```py:~/reboot.py（新規ファイル）
#!/usr/bin/python
#coding:utf-8
import time
import RPi.GPIO as GPIO
import os

GPIO.setmode(GPIO.BCM)

#GPIO19pinを入力モードとし、pull up設定とします
GPIO.setup(19,GPIO.IN,pull_up_down=GPIO.PUD_UP)

GPIO.wait_for_edge(19, GPIO.FALLING)

os.system("sudo shutdown -r now")

GPIO.cleanup()
```

`~/shutdown.py`および`~/reboot.py`へ実行権限を付与、サービスとして登録する。

```shell
pi@your-own-hostname:~ $ sudo chmod 0755 ~/shudtown.py
pi@your-own-hostname:~ $ sudo chmod 0755 ~/reboot.py

pi@your-own-hostname:~ $ sudo mkdir /usr/lib/systemd/system
```

適当なエディタで`/usr/lib/systemd/system/shutdown_by_button.service`および`/usr/lib/systemd/system/reboot_by_button.service`を新規ファイルとして作成、それぞれに以下内容を書き込む。

```shell:/usr/lib/systemd/system/shutdown_by_button.service（新規ファイル）
[Unit]
Description=Shutdown raspberry pi by GPIO button input
Wants=network.target

[Service]
ExecStart=/home/pi/shutdown.py
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target
```

```shell:/usr/lib/systemd/system/reboot_by_button.service（新規ファイル）
[Unit]
Description=Reboot raspberry pi by GPIO button input
Wants=network.target

[Service]
ExecStart=/home/pi/reboot.py
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target
```

以下コマンドによりdaemonのリロードとサービスの実行を行う。

```shell
pi@your-own-hostname:~ $ sudo systemctl daemon-reload
pi@your-own-hostname:~ $ sudo systemctl start shutdown_by_button
pi@your-own-hostname:~ $ sudo systemctl enable shutdown_by_button
pi@your-own-hostname:~ $ sudo systemctl start reboot_by_button
pi@your-own-hostname:~ $ sudo systemctl enable reboot_by_button
```

以下コマンドによりシャットダウン／リブートサービスが稼働している（`Active: active (running)`）ことを確認する。

```shell
pi@your-own-hostname:~ $ sudo systemctl status shutdown_by_button
pi@your-own-hostname:~ $ sudo systemctl status reboot_by_button
```

同様に、赤ボタンを押下しシステムの終了、緑ボタンを押下しシステムの再開、黄ボタンを押下しシステムのリブートが行われることを確認する。

##watchdog（死活監視）の有効化
運用方法次第ではあるが、念のためwatchdogを有効化しておく。

```shell
pi@your-own-hostname:~ $ sudo apt-get install watchdog
```

適当なエディタで`/boot/config.txt`、`/etc/modprobe.d/bcm2835-wdt.conf（新規ファイル）`、`/etc/systemd/system.conf`を開き、 それぞれの内容を修正する。
設定内容としては`5秒ごとにheartbeatを発生、10秒間heartbeatが発生しなければ再起動`となる。

```shell:/boot/config.txt
dtparam=watchdog=on
```

```shell:/etc/modprobe.d/bcm2835-wdt.conf（新規ファイル）
options bcm2835_wdt heartbeat=10 nowayout=0
```

```shell:/etc/systemd/system.conf
RuntimeWatchdogSec=5
```

サーバの再起動後、watchdogの有効化を確認する。

```shell
pi@your-own-hostname:~ $ dmesg | grep bcm2835-wdt
```

---

#コンテンツ作成上の問題点

iPadを操作端末とした場合、ウェブサイト上で以下UIを制限したい。

- ピンチイン／ピンチアウトによる拡大縮小
- ダブルタップによる拡大
- コンテンツ上端／下端でのバウンススクロール

`ピンチインピンチアウトによる拡大縮小`と`ダブルタップによる拡大`はそれぞれ以下スクリプトで制限を行った。

```javascript
/* ピンチインピンチアウトによる拡大縮小を禁止 */
document.documentElement.addEventListener('touchstart', function (e) {
  if (e.touches.length >= 2) {e.preventDefault();}
}, false);
```

```javascript
/* ダブルタップによる拡大を禁止 */
var t = 0;
document.documentElement.addEventListener('touchend', function (e) {
  var now = new Date().getTime();
  if ((now - t) < 350){
    e.preventDefault();
  }
  t = now;
}, false);
```

`コンテンツ上端／下端でのバウンススクロール`は[iNoBounce](https://github.com/lazd/iNoBounce "iNoBounce")を導入する事により禁止する事が可能となった。

iOS上でvideoタグによる自動再生は（音声が含まれている場合）行えない為、`再生ボタン`を明示的に設置し再生を促す必要がある。同様に、動画ファイル1コマ目を画像化しposterに設定、動画の再生が終了したら0フレーム目に移動するようスクリプトを組んだ。
htmlのbodyタグ及び動画再生用のjavascriptのサンプルは以下。

```html:html
<body>
	<article class="mainContentsArticle">
		<video id="video" class="video1920" width="100%;" poster="./media/1920-1080_poster.png" src="./media/aspectSample_1920-1080.mp4" type="video/mp4" /></video>
		<div id="control">
			<p class="controlsP"><button id="play">再生</button>&nbsp;<button id="pause">一時停止</button>&nbsp;&nbsp;<button id="back">戻る</button></p>
		</div>
	</article>
<script src="./js/moviePlayer.js"></script>
</body>
```

```javascript:moviePlayer.js
// videoの取得
var video = document.getElementById('video');
// 自動再生
video.autoplay = false;
// ループ
video.loop = false;

// ビデオのダウンロードが完了したとき
video.addEventListener('canplaythrough', function() {
      video.currentTime = 0;
});

// 再生状態になったとき
video.addEventListener('play', function() {
    console.log('再生中');
});
// 停止状態になったとき
video.addEventListener('pause', function() {
    console.log('停止中');
    video.currentTime = 0;
});
 
// playボタンを押した時
var play = document.getElementById('play');
play.addEventListener('click', function () {
    video.play();
});
 
// pauseボタンを押した時
var pause = document.getElementById('pause');
pause.addEventListener('click', function () {
    video.pause();
});

// 戻るボタンを押した時
var back = document.getElementById('back');
back.addEventListener('click', function () {
    window.history.back(-1);
});
```

##コンテンツのPWA化##

コンテンツページへのブックマークをホーム画面上に保存すると、疑似的なPWA（Progressive Web Apps）として扱う事が出来る。その場合、html内に以下metaデータを登録する必要がある。

**2019/12/25 更新**
iPad OS 13.3 環境下では、HTTPS通信環境およびmanifest.jsonによるPWAの実現を行わない場合、２ページ目以降の表示に支障が発生する。
その解決方法を以下に投稿した。
<a href="https://qiita.com/osprey74/items/3938df3a353342880d2a">Raspberry Pi および iPad による PWA コンテンツの作成</a>

```html
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<link rel="apple-touch-icon" href="./img/apple-touch-icon-152x152.png" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
```

---
#参考としたウェブサイト

[アクセスポイント | goozenlab](https://goozenlab.com/blog/2019/03/hostapd-buster/)
[デジタルサイネージを作ったので学んだことを晒してみる Part.1-Qiita](https://qiita.com/Akoarum_K/items/7f65c67f78b2ed9edb6c)
[videoタグの再生終了後にposterを表示させる方法](https://pochi-web.github.io/entry/2017/09/12/223517/)
[JavaScriptでvideoを操作する](http://cly7796.net/wp/javascript/manipulate-the-video-in-javascript/)
[ファン付きアルミ製Raspberry Pi用ケース（黒）](https://www.switch-science.com/catalog/3057/)
[Raspberry Pi 3でウェブサーバーを建てる ③ Apache編 - 気まま研究所ブログ](https://aonasuzutsuki.hatenablog.jp/entry/2016/10/01/201321)
[Raspberry Pi 3 にファイル共有「Samba」をインストール](http://d-hanamaru.jp/2017/04/23/post-4323/)
[iNoBounce](https://github.com/lazd/iNoBounce)
[Raspberry PiのログをRAMDISKに置く方法 | キュア子の開発ブログ](https://curecode.jp/tech/raspberrypi-ramdisk/)
[Raspberry Pi 3 にシャットダウン/リブート/再開ボタンを追加する - はむ！の空想具現化したいブログ](http://hammmm.hatenablog.com/entry/2016/11/14/231337)
[Pi 3をWifi AccessPoint化（Raspbian stretch Lite 2018） - new_western_elec](http://nw-electric.way-nifty.com/blog/2018/05/pi-3wifi-access.html)
[WiringPi](http://wiringpi.com/)
[Raspberry Pi 3/ Zero / Zero W等で watchdogを有効化する - Qiita](https://qiita.com/hidenorly/items/a09486c4359e85d7583e)
[RaspberryPiでルーターを自作し無線AP化 - Qiita](https://qiita.com/wannabe/items/a66c4549e4a11491f9d5)

#Raspberry Pi 3 B+ のピン配列
![GPIO.png](https://qiita-image-store.s3.amazonaws.com/0/279688/432c4352-befc-bcb3-8bd4-76bff1d0f165.png)