📑

ArchLinuxとミニPCで構築する最強の地震監視システム

2025/02/14に公開

JQuakeとは

皆さんはJQuakeを使用していますでしょうか?
JQuakeは日本各地の揺れをリアルタイムに監視するためのフリーソフトです。

防災科学技術研究所(NIED)の利用条件の更新に伴って、緊急地震速報はProject DM-D.S.Sに加入していない状態では利用できなくなってしまいましたが、月額550円とそこまでお高くはないので加入しても損はないと思います。

https://jquake.net/

しかしWindowsで動かすとWindowsアップデート等で勝手に再起動されてしまったり、Windows自体を長時間起動させっぱなしだと不安定になりがちです。地震監視システムにおいて安定動作はマストな要件なのでWindowsは不向きだったりします。

なので私は軽量さとシンプルさに重点を置いているArchLinux上でJQuakeを動作させて安定動作を狙っています。ArchLinuxは他のLinuxディストリビューションと違って不要なパッケージを勝手に入れてくるようなことはなく、すべて自分で必要なパッケージを入れてインストールする方式なので余計なものは入れずに欲しいものだけをインストールすることができます。

https://wiki.archlinux.jp

今回はJQuakeをArchLinux上で安定して動かすための最強の地震監視システムを構築するノウハウを伝授します。※半分ArchLinuxのインストール備忘録になっています。

最終的なシステムは以下のような感じになります。Windowsと違ってウィンドウタイトルバーまで消してフルスクリーンにできるので解像度が低いモニターでも有効活用できます。


ウィンドウタイトルバーが無しで全画面表示しているデモ(1366x768)

使用するミニPC

地震監視ということで24時間365日動かすことになるため省電力かつ比較的高性能なCPUで最近流行りのIntel N100プロセッサを搭載したGMKtec社のNucBox G3を採用しました。

今はIntel N150を搭載したNucBox G3 Plusが販売されているようです。

消費電力はアイドル状態で実測8Wほどでしたので1ヶ月あたりおよそ6kWhで運用できます。

唯一の残念ポイントはAC電源が給電された際に自動で起動することができない点です。Wake on LANには対応しているので救済の手立てはありますが少し面倒にはなってしまいます。停電から復帰後の自動起動は課題です。 ←UEFI設定の深いところにありました

参考までに購入した商品のAmazonページのリンクを貼っておきます。
https://amzn.asia/d/2GMayq0

また注意点としてメモリとSSDのメーカーが出荷時期やロットによってバラバラのようです。
心配な方は自前でメモリとSSDを用意して交換するとよいと思います。

参考までに私が購入した際のメモリとSSDは以下のものが刺さっていました。

  • メモリ: Lexar社 DDR4-3200 8GB (LD4S08G32C22ST-HGN)
  • SSD: ZETTASTONE社 NVMe M.2 PCIe3.0 CP200 256GB

特にSSDに関しては安定性や信頼性に関わる部分ですので有名なメーカ品に交換することをおすすめします。(ZETTASTONEはGMKtecのミニPCでよく使われる中華SSDです...)

※過去に別のミニPCの内臓のeMMCで運用していた際にディスクが故障した結果I/O Errorが頻発してOSがフリーズする事態になったことがありましたのでストレージの重要さを痛感しました。

今回はトランセンド社の産業用SSDを購入しました。
温度拡張品かつpSLCモードで動作するのでこういう用途には最適かと思います。
24時間365日稼働するので安心を買うためにも産業用を採用しました。

https://amzn.asia/d/5aKrYbk

20GBで5000円ほどしますが産業用なのでこの程度の値段で妥当かと思います。
※ArchLinuxは軽量なので20GBでも余裕でインストールできます。


OS全体で4GBという脅威の軽量さ

M.2(SATA)の2242を搭載できるスロットがありますのでそちらに取り付けて元々のSSDは取り外します。

またWi-Fiを使用する予定がないのであれば、消費電力を削減する意味でも無線カードを取り外しておくと良いです。取り外した際はアンテナの端子が基板に接触してショートしないようにカプトンテープなどで巻いておきましょう。(下記画像右下)

その他のデバイス

また周辺機器として以下のデバイスで構築しました。

  • モニター: ASUS VH168D (1366 x 768)
  • キーボード: ELECOM TK-FDM105TBK
  • マウス: Logicool M546
  • スピーカー: サンワサプライ MM-SPU17BKN

個人的にはアナログD-SUBかつ単一入力のモニターが画面スリープ状態から復帰した際に映像が映るまでの時間がとても速いのでこういった用途にはおすすめです。(VH168Dは復帰まで1.5秒ほど)

機種にもよるかもしれませんが複数入力端子があるものは入力自動検出をオフにして入力固定にしておいたほうが復帰時の速度が速くなるかもしれません。(要調査)

電源投入時の自動起動設定

地震監視PCなので停電から復帰時にも自動で起動してもらう必要があります。今回購入したGMKtec G3は電源投入時の自動起動に対応しているので設定しておきます。

電源投入時にDelキーを連打してUEFIに入った後以下の項目を変更します。

  • Chipsetタブ
    • PCH-IO Configuration
      • Wake on Power (Automatic On)
        S5 StateからS0 Stateに変更します。

ArchLinuxのインストール

ArchLinux公式のダウンロードリンクから最新のISOイメージをダウンロードしてUSBメモリに書き込んでください。
古いイメージの場合インストール時にPGP鍵の検証エラーが発生することがありますので最新のISOイメージを使うことを推奨します。

※PGP鍵の検証エラーが出た際の対処法
pacman-key --init && pacman -Sy archlinux-keyring && pacman -Syu

ISOイメージの書き込み方法はググってください。WindowsであればRufusがおすすめです。

前提環境

インストールの解説では前提条件として以下の要件とします。

  • 有線LANによるイーサネット接続(DHCP環境)
  • UEFIマシン(最近のマシンであればすべてUEFIです)
  • セキュアブートは無効化

セキュアブートの無効化はNucBox G3の場合以下の手順で無効化できます。

  1. 起動時にDelキーを連打してUEFIに入る
  2. Securityタブに移動する
  3. SecureBootに入る
  4. Attempt Secure BootをDisableに設定する

この手順はお使いのパソコンによって異なるのでマニュアル等を参考にしてください。

インストールUSBから起動する

GMKtec G3の場合は起動時にF7キーを押すとブートメニューが出てきます。

ISOイメージを書き込んだUSBメモリから起動してArch Linux install medium (x86_64, UEFI)を選択して起動します。しばらく待つとarchisoの画面が表示されてプロンプトが出てきます。

この地点でインターネットに疎通できるかどうか確認しておきましょう。

# ping archlinux.jp

SSH経由のセットアップ

この画面だとこの記事からコマンドのコピペができないためSSH接続してセットアップをしましょう。

パスワードの設定およびSSHの有効化、IPアドレスを確認してください。
有線LANアダプタはenp1s0のような名前で出てくると思います。

# passwd
# systemctl start sshd
# ip a

実行した後は同じLAN内の別のパソコンからSSH接続をします。IPアドレスは各自で読み換えてください。

$ ssh root@192.168.0.2 -o PreferredAuthentications=password

※筆者は1password SSH agentを使用しているため-o PreferredAuthentications=passwordを付与しています。これを付けないとパスワード認証にもかかわらずエージェントの公開鍵を使おうとしてToo many authentication failuresというエラーになってしまいます。

システムクロックの更新

ライブ環境ではデフォルトでNTPが有効になっているのでインターネットに接続されれば自動で時刻が補正されるはずです。念のために正しい時刻になっているか確認してください。

# timedatectl status

パーティーション分割

まずPC上のストレージ一覧を表示します。

# lsblk

ここは環境によって異なりますがnvme0n1sdaが表示されると思いますのでお使いの環境に合わせて読み替えてください。

パーティーションテーブルはUEFI環境なのでGPTを使用します。
先ほど確認したデバイス名で以下のコマンドでパーティーションを分割してください。

# cgdisk /dev/sda

私は以下のようにパーティーションを分割しました。

マウントポイント パーティーション パーティーションタイプ サイズ
/mnt/boot /dev/efi_system_partition EFI system partition(ef00) 1GiB
/mnt /dev/root_partition Linux filesystem (8300) 残り容量すべて
swap /dev/swap_partition Linux Swap (8200) 2GiB

パーティーションのフォーマット&マウント

作成したパーティーションをフォーマットします。ここでは無難にext4を採用します。

# mkfs.fat -F 32 /dev/sda1
# mkfs.ext4 /dev/sda2
# mkswap /dev/sda3

続けてフォーマットしたパーティーションをマウントをします。

# mount /dev/sda2 /mnt
# mount --mkdir /dev/sda1 /mnt/boot
# swapon /dev/sda3

インストール

インストール前にパッケージのミラーリストを日本のミラーに更新しておきます。

# reflector --country Japan --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist

必要なパッケージ群をまとめてインストールします。
安定性重視のためLinuxカーネルは最新版ではなくLTS版を採用します。

今回はIntel CPUを使っているのでintel-ucodeとしています、AMDのCPUをお使いの方はamd-ucodeに読み替えてください。
またテキストエディタもvim以外に使いたいものがあればそちらをインストールしてください。

# pacstrap /mnt base linux-lts linux-firmware vim sudo openssh intel-ucode 

システム設定

まずはfstabを生成します。

# genfstab -U /mnt >> /mnt/etc/fstab

インストールしたシステム内に入って続きの設定を行います。

# arch-chroot /mnt

タイムゾーンの設定をします。日本に住んでいる場合は以下の通りです。

# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

続けてシステムの時刻をRTCに書き込みます。

# hwclock --systohc

ロケール設定

/etc/locale.genを開いて次の内容を先頭に追記してください。

en_US.UTF-8 UTF-8
ja_JP.UTF-8 UTF-8

次のコマンドでロケールを生成します。

# locale-gen

続いてLANG環境変数とキーマップを設定します。

# echo LANG=en_US.UTF-8 > /etc/locale.conf
# echo KEYMAP=jp106 > /etc/vconsole.conf

ネットワーク設定

ホスト名を設定します。ここではgmktec-g3というホスト名とします。

# echo gmktec-g3 > /etc/hostname

続いてhostsファイルを編集します。

/etc/hosts
127.0.0.1    localhost
::1    localhost
127.0.1.1    gmktec-g3

続いてIPアドレスを固定化しておきます。DHCP運用でも可能ですがIPアドレスが変わる可能性があるため固定IPアドレスにしておくことをおすすめします。

まずは有線LANのネットワークカードのMACアドレスを確認して控えておきます。
※アダプタ名でも可能ですがudevで変わる可能性があるため不変のMACアドレスをおすすめします。

# ip a

ネットワーク設定には標準でインストールされているsystemd-netorkdを使用します。

/etc/systemd/network/20-wired.networkというファイルを作成して以下のように記述します。
MACアドレス、IPアドレス、ゲートウェイアドレスは環境に合わせて読み替えてください。

/etc/systemd/network/20-wired.network
[Match]
MACAddress=xx:xx:xx:xx:xx:xx

[Network]
Address=192.168.0.100/24
Gateway=192.168.0.254
DNS=1.1.1.1
DNS=1.0.0.1

次回の起動時にサービスが自動で起動するようにします。

# systemctl enable systemd-networkd
# systemctl enable systemd-resolved

ユーザーの作成

地震監視システムということでサイネージのような用途に使うことになるため管理者ユーザーと自動ログインさせる表示専用ユーザーの2つを作成します。

今回は以下のユーザーを作成しました。

用途 ユーザー名 グループ 権限
管理者 owner users root昇格可能
表示専用 eqwatch users
# useradd -m -g users -G wheel -s /bin/bash owner
# useradd -m -g users -s /bin/bash eqwatch

続けてパスワードを設定します。

# passwd owner
# passwd eqwatch

管理者ユーザーはsudoを使用して特権を使用できるようにsudoersを編集しておきます。

# EDITOR=vim visudo

以下の部分をアンコメントします。

/etc/sudoers
## uncomment to allow members of group wheel to execute any command
%wheel ALL=(ALL:ALL) ALL

表示専用ユーザーにsuコマンド経由でログインするとXDG_RUNTIME_DIRが正しく設定されず、後述のコマンドでエラーが発生するので.bashrcで正しく設定されるようにしておきましょう。

$ su - eqwatch
$ echo "export XDG_RUNTIME_DIR=/run/user/$(id -u)" >> ~/.bashrc
$ exit

SSHの公開鍵認証設定

先ほど作成したユーザーでSSH接続ができるように公開鍵認証の設定をしておきます。
その前にsshdサービスが自動起動するようになっていないのでサービスを有効化します。

# systemctl enable sshd

作成した管理者ユーザーに切り替えます。

# su - owner

続いて公開鍵認証の設定ファイルを作成します。
【SSH公開鍵】の部分は接続元マシンの公開鍵に読み替えてください。

# mkdir .ssh
# chmod 700 .ssh
# echo 【SSH公開鍵】 >> .ssh/authorized_keys
# chmod 600 .ssh/authorized_keys

設定を終えたらexitコマンドで管理者ユーザーからログアウトしてください。

# exit

ブートローダーのインストール

今回はUEFIシステムのためgrubより高速でシンプルなsystemd-bootを使用します。

以下のコマンドでEFI システムパーティションに systemd-boot をインストールします。

# bootctl install

続いてローダーの設定をします。
/boot/loader/loader.confに以下を追記してください。

/boot/loader/loader.conf
default arch
editor no

続いてローダーの起動エントリを作成します。
ここではディスクのUUIDを記述する必要がありますがコピペするのは面倒なので最初にコマンドでUUIDを書き込んだベースのファイルを作成しておきます。

# blkid -s UUID -o value /dev/sda2 > /boot/loader/entries/arch.conf

/boot/loader/entries/arch.confを編集します。
先ほど書き込んだUUIDをうまく活用して編集してください。
マイクロコードの部分は環境に合わせて適宜読み替えてください。(AMDユーザーのみ)

/boot/loader/entries/arch.conf
title   Arch Linux
linux   /vmlinuz-linux-lts
initrd  /intel-ucode.img
initrd  /initramfs-linux-lts.img
options root=UUID=【ディスクのUUID】 rw
options quiet loglevel=3

最後にUEFI ブートマネージャを自動で更新するようにサービスを有効化しておきます。

# systemctl enable systemd-boot-update

以上で基本のインストールは完了です。chrootから抜けて再起動します。

# exit
# reboot

以降、インストールUSBは抜いても大丈夫です。万が一起動しない場合はもう一度インストールUSBから起動してディスクのマウントとarch-chrootでシステムに入った後、設定等に間違いがないか確認して下さい。

インストール後の設定

まずは対象のマシンに公開鍵認証でSSH接続できるか確認します。

$ ssh owner@192.168.0.100

ログインができたらパスワード認証を無効化しておきます。

$ echo "PasswordAuthentication no" | sudo tee /etc/ssh/sshd_config.d/disable_password_auth.conf

続いて追加のネットワーク設定をします。
まずはsystemd-resolvedの設定ファイルのリンクを行います。

$ sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

次にNTPを利用して時刻同期を自動で行うようにします。
/etc/systemd/timesyncd.confを以下のように編集してください。

/etc/systemd/timesyncd.conf
[Time]
NTP=ntp.nict.jp
FallbackNTP=ntp1.jst.mfeed.ad.jp ntp2.jst.mfeed.ad.jp ntp3.jst.mfeed.ad.jp

ここではNICTのNTPを使用するように設定しましたが使いたいNTPサーバーがあれば適宜読み替えてください。

続いてsystemd-timesyncdサービスを有効化します。

$ sudo systemctl enable systemd-timesyncd

SSD環境であればTRIMを定期的に実行するようにしておきます。

$ sudo systemctl enable fstrim.timer

ファイアーウォールはufwを使います。

$ sudo pacman -S ufw

デフォルトで接続を拒否してSSHのポートだけ許可しておきます。

$ sudo ufw default deny
$ sudo ufw allow 22
$ sudo ufw enable

GUI環境の設定

今回は軽量なGUI環境を目指して以下のアプリを採用しました。

  • ディスプレイマネージャ: LightDM
  • ウィンドウマネージャ: OpenBox

サイネージ用途なので高度なデスクトップ環境は不要で基本的なウィンドウを出せるだけの最低限の環境で十分です。

まずは必要なパッケージをインストールしてディスプレイマネージャを有効化しておきます。

$ sudo pacman -S lightdm openbox obconf xorg-xset
$ sudo systemctl enable lightdm

次に自動ログイン機能を使うために表示専用ユーザーをautologinグループに追加します。

$ sudo groupadd -r autologin
$ sudo gpasswd -a eqwatch autologin

/etc/lightdm/lightdm.confを編集して自動ログインの設定を行います。
次の行をコメントアウトして設定します。

/etc/lightdm/lightdm.conf
[Seat:*]
autologin-user=eqwatch
autologin-session=openbox

一旦システムを再起動してGUI環境が表示されるかどうかテストします。

$ sudo reboot

正しくインストールされていれば表示専用ユーザーが自動ログインし、マウスカーソルが表示されてデスクトップ上を右クリックするとメニューが出てくるはずです。

JQuakeのインストール

続いて本題のJQuakeを導入していきます。
まずは必要なパッケージをまとめてインストールします。

$ sudo pacman -S wget unzip jre-openjdk firefox gvfs otf-ipafont noto-fonts pipewire wireplumber pipewire-alsa pipewire-pulse pipewire-jack curl jq

JQuake単体を動かすだけであればオーディオサーバは無くても大丈夫ですがブラウザで何か再生したい用途もあるかと思いますのでここではPipewireをインストールしています。
※PulseAudioだとJQuakeで音の末尾が途切れる謎の問題が発生しました...

インストール後は一度再起動をして下さい。

$ sudo reboot

表示専用ユーザーに切り替えてから作業を続けます。

$ su - eqwatch

JQuake本体をダウンロードして解凍します。

$ wget https://fleneindre.github.io/downloads/JQuake_1.8.5_linux.zip
$ unzip JQuake_1.8.5_linux.zip -d JQuake

次に解凍した中にあるJQuake.shを以下のものに置き換えてください。

~/JQuake/JQuake.sh
#!/usr/bin/env bash

cd ~/JQuake

JAVA_PID=""
MONITOR_PID=""

BASE_URL="https://api.dmdata.jp/v2"

# DM-D.S.S WebSocket cleanup
function dmdata_cleanup() {
  echo "Checking DM-D.S.S WebSocket."

  response=$(curl -fsSL -H "$AUTH_HEADER" "$BASE_URL/socket?status=open")
  if [ $? -ne 0 ]; then
    echo "Failed to check socket."
    return
  fi

  socket_ids=$(echo "$response" | jq -r '.items[].id')

  for id in $socket_ids; do
    curl -fsSL -X DELETE -H "$AUTH_HEADER" "$BASE_URL/socket/$id"

    if [ $? -ne 0 ]; then
      echo "Failed to close socket ID: $id"
    else
      echo "Closed socket ID: $id"
    fi
  done
}

# Monitoring DM-D.S.S WebSocket
function dmdata_monitoring() {
  local initial_check=true

  while true; do
    if [ "$initial_check" = true ]; then
      sleep 15
      initial_check=false
    else
      sleep 60
    fi

    response=$(curl -fsSL -H "$AUTH_HEADER" "$BASE_URL/socket?status=open")
    if [ $? -ne 0 ]; then
      continue
    fi

    item_count=$(echo "$response" | jq '.items | length')

    if [ "$item_count" -eq 0 ]; then
      if [ -n "$ALERT_EMAIL" ]; then
        echo "Sending alert email."

        BODY="Subject: 【異常】地震監視PC: DM-D.S.S接続異常
DM-D.S.SのWebSocket接続に異常が発生しています。

異常発生時刻: $(date "+%Y-%m-%d %H:%M:%S")
"

        systemd-run --user --no-block bash -c "echo -e \"$BODY\" | msmtp \"$ALERT_EMAIL\"" > /dev/null 2>&1
      fi
      cleanup
    fi
  done
}

# Trap Signal
function cleanup() {
  echo "Performing cleanup..."

  if [ -n "$MONITOR_PID" ]; then
    echo "Stopping monitoring process (PID: $MONITOR_PID)"
    kill $MONITOR_PID 2>/dev/null || true
    wait $MONITOR_PID 2>/dev/null || true
  fi

  if [ -n "$JAVA_PID" ]; then
    echo "Stopping Java process (PID: $JAVA_PID)"
    kill $JAVA_PID 2>/dev/null || true
    wait $JAVA_PID 2>/dev/null || true
  fi

  exit 1
}

trap cleanup SIGINT SIGTERM

if [ -f .env ]; then
  source .env
fi

if [ -n "$API_KEY" ]; then
  AUTH_HEADER="Authorization: Basic $(echo -n "${API_KEY}:" | base64)"
  dmdata_cleanup
fi

echo "Launching JQuake."

java -Xmx200m -Xms32m -Xmn2m -Djava.net.preferIPv4Stack=true -Dawt.useSystemAAFontSettings=gasp -jar JQuake.jar > /dev/null &
JAVA_PID=$!

if [ -n "$API_KEY" ]; then
  dmdata_monitoring &
  MONITOR_PID=$!
fi

wait $JAVA_PID
EXIT_CODE=$?

if [ -n "$MONITOR_PID" ]; then
  echo "Stopping monitoring process (PID: $MONITOR_PID)"
  kill $MONITOR_PID 2>/dev/null || true
  wait $MONITOR_PID 2>/dev/null || true
fi

exit $EXIT_CODE

元々のスクリプトから色々改造していますが詳しくはDM-D.S.Sのモニタリング機能セクションで解説してあります。元のスクリプトから変えたところは実質的には以下の部分です。

java -Xmx200m -Xms32m -Xmn2m -Djava.net.preferIPv4Stack=true -Dawt.useSystemAAFontSettings=gasp -jar JQuake.jar > /dev/null &

追加したJavaオプションはフォントのアンチエイリアスを設定しています。
これを設定しないとフォントの縁がガタガタになってしまうので設定することを推奨します。
Javaの標準出力は後述のサービス化の際にjournalログを圧迫してしまうので/dev/nullにリダイレクトしておきます。

Linux版だけなぜか-jarオプションが最初に来ていてオプションがすべて効かなくなっていますがおそらくミスでしょう...(オプションを先に書かないとすべて無視されてしまいます)

Linux環境だとJQuakeがあるディレクトリではなくホームディレクトリにLibraryというディレクトリで設定ファイルができてしまい邪魔なのでこれを修正しておきます。

$ echo $HOME/.config/JQuake > ~/JQuake/SettingsPath.properties

スクリプトに実行権限がついていないので付与しておきます。

$ chmod +x ~/JQuake/JQuake.sh

JVMのチューニング

デフォルトだとJVMのメモリオプションが-Xmx200m -Xms32m -Xmn2mになっています。

特に-Xms32mは明らかに足りておらず起動時にFull GCしまくるので上げた方がよいと思います。また-Xmn2mも非常に小さくGCが大量に走るのでこちらも上げます。

この設定だとPause Timeが2秒を超えるようなGCが平気で起きます ← この後何回も検証しましたがなぜか再現しませんでした...とはいえGCが走りすぎでパフォーマンスが非常に悪いです。アイドル時でも毎秒3回を超えるGCが発生しているほか、地図を動かしたり緊急地震速報受信時は毎秒30回を超えるようなGCが起きました。

またJQuake内部で1分おきにSystem.gc()を呼び出しているためFull GCが何度も発生します。
作者様に何か意図があるのかはわかりませんがJVMに自動でGCさせてよい気がします。


デフォルト設定のヒープおよびGCログ

私の環境でチューニングした後のJVMオプションを示します。

-XX:+DisableExplicitGC -XX:+ExitOnOutOfMemoryError -XX:+UseZGC -XX:+AlwaysPreTouch -Xmx1G -Xms1G

内部のSystem.gc()を抑制してJVMにGC管理を任せてZGCを有効にしてあります。
ヒープメモリ割り当てを1GBにしていますが地震監視専用PCとするので8GBもメモリがあればこれくらい割り当てても余裕で余ると思います。また、万が一OOMになった際はプロセスが落ちるようにしておきます。

JVMのスループットも実測で99.27%から99.9997%まで改善できました。

サウンドデバイスの設定

JQuakeの動作テストをする前にサウンドデバイスの設定をしておきます。
まずは以下のコマンドを実行してスピーカーから音が出るか確認してください。

$ paplay ~/JQuake/sounds/jp/Shindo1.wav # 地震検知時
$ paplay ~/JQuake/sounds/jp/info/female/1.wav # 地震情報お知らせ
音が鳴らない or 音が小さい場合は....

出力先が間違っている、または音量が不適切な可能性があるので以下を確認してください。

wpctl statusを実行してAudio => Sinksの*が適切なデバイスになっているか確認
正しい出力先でない場合はwpctl set-default [ID]でデバイスを変更して試してみる。
音量が小さい場合はwpctl set-volume [ID] [音量]で音量を大きくしてみる。
※音量は0.00~1.00の範囲で指定します
設定変更後は場合によって再起動する必要があるかもしれません。
設定が正しいのにならない場合は再起動も試してください。

音の再生が確認出来たら一度JQuakeが起動するかどうかテストしておきましょう。

$ export DISPLAY=:0
$ ~/JQuake/JQuake.sh

動作確認

  • 地震履歴の地球儀マークをクリックしたときにブラウザが正しく起動するかどうかもチェックしてください。ブラウザが起動しない場合はgvfsが正しくインストールされていない可能性があります。
  • 設定画面の揺れ検出時タブのテスト再生をクリックして正しくスピーカーから音が出るか確認してください。

JQuakeの設定からのユーザーの緯度経度設定も忘れずにしておきましょう。
緊急地震速報受信時または地震検知時に画面スリープを解除するはONがおすすめです。

Project DM-D.S.Sに加入している方はもれなくアカウントとの連携をしておきましょう。

その他の設定はお好みに応じて調整してください。

systemdサービス化

JQuakeをsystemdのユーザーサービスとして登録しておきます。

systemdに管理させておけば起動時に自動で起動できますし何らかの原因で落ちた場合でも自動でアプリケーションを再起動させることができるので便利です。

起動時にDNS解決ができないと地震情報が読み込めなかったりDM-D.S.Sの接続が行われなくなる場合があるのでExecStartPredmdata.jpのDNS解決ができるまで待機しています。(nss-lookup.targetを追加するだけではなぜか待機してくれませんでした)

~/.config/systemd/user/jquake.serviceを作成して以下のように編集してください。

~/.config/systemd/user/jquake.service
[Unit]
Description=JQuake
Wants=network-online.target
After=network-online.target nss-lookup.target graphical.target

[Service]
ExecStartPre=/usr/bin/sh -c 'until resolvectl query dmdata.jp > /dev/null 2>&1; do sleep 1; done'
ExecStart=%h/JQuake/JQuake.sh
Environment=DISPLAY=:0
Restart=always

[Install]
WantedBy=default.target

作成後はユニットファイルを再読み込みしてサービスを有効化します。

$ systemctl --user daemon-reload
$ systemctl --user enable --now jquake

これで画面上にJQuakeのウィンドウが表示されたら成功です。
JQuakeが起動しない場合はsystemctl --user status jquakeでエラーを確認して下さい。

念のため再起動後に自動起動するかどうか、および×ボタンで閉じた際に自動で再度立ち上がるかどうかをチェックしておいてください。

DM-D.S.Sのモニタリング機能

JQuakeはDM-D.S.Sを使用して緊急地震速報を受信しますがWebSocket接続がごくまれに切れたり再起動後に自動で接続しなかったりすることがあります。

ほかにもJQuakeが異常終了したなどの理由でWebSocketを解放せずに接続枠を確保したままになることで、再起動した際にWebSocket同時接続数エラーとなってしまいリトライもしないので緊急地震速報が受信できなくなってしまう可能性があります。
※JQuake専用契約では同時接続上限が1です。

そのため改変したJQuake.shには接続状況のモニタリングおよび接続のクリーンアップ処理が追加されています。使用するには以下の手順を行ってください。

  1. APIを有効化する
    DM-D.S.Sコントロールパネルを開いてアカウントタブの利用種別をAPI利用(開発者)にします。

  2. APIキーを発行
    APIキー・OAuthタブを開いてAPIキーの新規作成をクリックします。
    APIキー名は任意でOKです。権限はsocket.listsocket.closeにチェックを入れてください。
    APIキーは後からでも確認できますのでこのまま保存して大丈夫です。

  3. APIキーを保存

    $ echo "API_KEY={APIキー}" >> ~/JQuake/.env
    

動作確認

  1. JQuakeサービスを停止する

    $ systemctl --user stop jquake
    
  2. 手動でJQuakeを起動する

    $ export DISPLAY=:0
    $ ~/JQuake/JQuake.sh &
    

    起動後はDM-D.S.SのWebSocketがつながっていることを確認してください。

  3. JQuakeサービスを開始する

    $ systemctl --user start jquake
    

手動で起動させたJQuakeのWebSocketが切断されてJQuakeサービスで起動したJQuakeがWebSocketに接続できていればOKです。手動で起動させた方はWebSocket接続が切断されるためモニタリング機能で最大でも1分以内にJQuakeが自動的に終了されます。※実際には終了するとsystemdの機能で自動的に再起動されます。

おまけ機能

msmtpをインストールしてメールサーバーの設定した状態で.envALERT_EMAILを設定しておくとWebSocket接続の異常が発生した際にメール通知をすることができます。

OpenBoxの調整

設定のためにOpenBoxの設定ファイルをコピーしておきます。

$ mkdir -p ~/.config/openbox
$ cp -a /etc/xdg/openbox ~/.config/

運用上便利なショートカットやUIの調整、設定例を置いておきます。
必要に応じてカスタマイズして使ってください。

  1. Ctrl + Alt + Del 押下時に再起動をする設定
    ~/.config/openbox/rc.xml<!-- Keybindings for running applications -->の次に以下のように記述してください。

https://github.com/njm2360/jquake-dotfiles/blob/article/.config/openbox/rc.xml#L318-L323

  1. JQuakeのウィンドウを全画面表示にする
    ~/.config/openbox/rc.xml<applications>の次に以下のように記述してください。

https://github.com/njm2360/jquake-dotfiles/blob/article/.config/openbox/rc.xml#L779-L781

  1. OpenBox右クリック時のメニュー
    筆者の環境で使用しているメニューの設定ファイルです。
    最低限のメニューしか用意していないのでお好みでカスタマイズしてください。

    設定ファイル: ~/.config/openbox/menu.xml

https://github.com/njm2360/jquake-dotfiles/blob/article/.config/openbox/menu.xml

  1. DPMSでモニターがオフになる時間を調整
    筆者はスクリーンセーバーオフ、タイムアウト5分で運用しています。

    ~/.config/openbox/autostartに以下を追記

https://github.com/njm2360/jquake-dotfiles/blob/article/.config/openbox/autostart#L15-L16

カーネルパラメータの調整

SSDの書き込みを抑制してカーネルパニック、OOM発生時に自動で再起動するようにしておきます。

/etc/sysctl.conf
vm.swappiness=0
kernel.panic=10
vm.panic_on_oom=1

TigerVNCのセットアップ(任意)

任意にはなりますがTigerVNCを使って別のPCから画面が見れるようにしておくと便利です。

管理者ユーザーでTigerVNCをインストールしておきます。

$ sudo pacman -S tigervnc

表示専用ユーザーに切り替えた後VNCパスワードと自動起動の設定をします。

$ vncpasswd

VNCサーバー自動起動のユニットファイル作成

~/.config/systemd/user/x0vncserver.service
[Unit]
Description=Remote desktop service (VNC)

[Service]
Type=simple
ExecStartPre=/bin/sh -c 'while ! pgrep -U "$USER" openbox; do sleep 2; done'
ExecStart=/usr/bin/x0vncserver -display :0 -rfbport 5900 -rfbauth %E/tigervnc/passwd
Restart=always

[Install]
WantedBy=default.target

サービスの有効化

$ systemctl --user daemon-reload
$ systemctl --user enable --now x0vncserver

ファイアウォールの許可設定

$ sudo ufw allow 5900

任意のVNCクライアントから接続が確認できたら完了です。

時報の設定(任意)

スピーカーの故障に備えて特定の時刻に時報を鳴らすようにしておくとスピーカーが故障した際に気づけて便利です。防災無線の音楽も故障していないかを点検する意味合いで鳴らしているようなのでそれを実装します。

鳴らす音声は表示専用ユーザーの~/jihou/sound.wavに用意してあり、鳴らす時間は毎日17時として設定サンプルを置いてあります。ここは各自お好みの時間に読み替えてください。

まずは音声を再生するためにメディアプレイヤーをインストールします。

$ sudo pacman -S mpv

表示専用ユーザーに切り替えてから特定時刻に音声を鳴らすためのユーザーサービスを作成します。

.config/systemd/user/jihou.service
[Unit]
Description=Jihou Service

[Service]
WorkingDirectory=%h/jihou
ExecStart=mpv --quiet sound.wav --volume=100
Type=simple

[Install]
WantedBy=default.target
.config/systemd/user/jihou.timer
[Unit]
Description=Jihou Timer

[Timer]
OnCalendar=*-*-* 17:00:00
AccuracySec=1s

[Install]
WantedBy=timers.target

最後にサービスを有効化します。

$ systemctl --user daemon-reload
$ systemctl --user enable jihou.timer

さいごに

この記事をもとにした手元の環境の設定ファイルは以下のリポジトリで公開しています。
必要に応じてお使いください。

https://github.com/njm2360/jquake-dotfiles/tree/article

長い記事になってしまいましたがこれでみなさんも快適な地震監視ライフが送れますね???
そして良いArchLinuxライフを楽しんでいきましょう。それではまた。

Discussion