先週のレシピでは、
AquesTalk Piは、
筆者は、
Cubox-iへのUbuntuのインストール
まずはCubox-iへUbuntuをインストールしなければなりません。ARMマシンはx86のPCとは違い、
まずインストールするmicroSDHCカードにパーティションを切ります。カーネルを置く/dev/

最初はブートローダーを用意します。u-bootのソースをクローンし、
$ sudo apt-get install gcc-arm-linux-gnueabi u-boot-tools lzop build-essential $ export ARCH=arm $ export CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- $ git clone https://github.com/SolidRun/u-boot-imx6.git $ cd u-boot-imx6 $ make mx6_cubox-i_config $ make
ビルドが成功すると
$ sudo dd if=SPL of=/dev/sdX bs=1K seek=1 $ sudo dd if=u-boot.img of=/dev/sdX bs=1K seek=42
u-bootの次はカーネルです。SolidRunのリポジトリから、
$ git clone https://github.com/SolidRun/linux-imx6-3.14 $ cd linux-imx6-3.14 $ make imx_v7_cbi_hb_defconfig $ make zImage imx6q-cubox-i.dtb imx6dl-cubox-i.dtb imx6dl-hummingboard.dtb imx6q-hummingboard.dtb $ make modules $ mkdir ../modules $ make modules_install INSTALL_MOD_PATH=../modules
debootstrapでUbuntu 14.
$ sudo apt-get install debootstrap $ sudo debootstrap --verbose --foreign --arch=armhf --variant=minbase --include=module-init-tools,locales,udev,dialog,ifupdown,procps,iproute,iputils-ping,nano,wget,netbase,net-tools trusty cubox-i http://jp.archive.ubuntu.com/ports
x86マシンのchroot内でarmhfのバイナリを動かすため、
$ sudo apt-get install qemu-user-static $ sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/ $ sudo chroot rootfs # ./debootstrap/debootstrap --second-stage (各種設定) # exit $ sudo rm rootfs/usr/bin/qemu-arm-static
上記のdebootstrapで作成したrootfsは、
インストールは以上で終了です。ここから先の作業は、
USBスピーカーを接続する
Cubox-iには音声出力がS/
$ sudo apt-get install alsa-utils $ sudo gpassw -a mizuno audio
また筆者のケースでは、
$ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: imxspdif [imx-spdif], device 0: S/PDIF PCM snd-soc-dummy-dai-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: imxhdmisoc [imx-hdmi-soc], device 0: i.MX HDMI Audio Tx hdmi-hifi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 2: Speaker [USB Speaker], device 0: USB Audio [USB Audio] Subdevices: 1/1 Subdevice #0: subdevice #0
そして以下の内容で、
pcm.!default {
type plug
slave.pcm "dmixer"
}
pcm.dmixer {
type dmix
ipc_key 1024
slave {
pcm "hw:2,0" ← 先ほど調べたハードウェアの番号
period_time 0
period_size 1024
buffer_size 4096
rate 44100
}
bindings {
0 0
1 1
}
}
AquesTalk Piを使う
AquesTalk Piのページの使用許諾を読み、
AquesTalkPiコマンドに、
$ ./AquesTalkPi -b ゆっくりしていってね > yukkuri.wav ← wavファイルを作成 $ ./AquesTalkPi -b ゆっくりしていってね | aplay -q ← その場で音声を再生 $ echo ゆっくりしていってね | ./AquesTalkPi -b -f - | aplay -q ← 他のコマンドの出力をその場で読み上げ
日付と時刻をしゃべらせる
試しに使ってみるとわかるのですが、
まず発声とデバッグを簡単にするため、
#!/bin/bash
DEBUG=${DEBUG:-0}
ATP=/home/mizuno/aquestalkpi/AquesTalkPi
function yukkuri ()
{
if [ ${DEBUG} -eq 1 ];then
echo "$1"
else
echo "$1" | ${ATP} -s 90 -b -f - | aplay -q
sleep 0.3
fi
}
#!/bin/bash
. /home/mizuno/bin/yukkuri.sh
# 発生のため曜日をリストで持っておく
# date +%Aはロケールに依存するので使わない
declare -a DOW_LIST=("にちようび" "げつようび" "かようび" "すいようび" "もくようび" "きんようび" "どようび")
# APIは六曜を数字で返すので、リストを持っておく
declare -a ROKUYOU_LIST=("たいあん" "しゃっこう" "せんしょう" "ともびき" "せんぷ" "ぶつめつ")
# jqコマンドの存在確認
JQ=${JQ:-$(which jq)}
if [ ! -x "${JQ}" ]; then
echo "jq not exist." 1>&2
echo "Please install jq package." 1>&2
exit 1
fi
# ただしく発音させるために先頭のゼロ詰めを消す
YEAR=$(date +%Y)
MONTH=$(date +%m | sed -e 's/^0//')
DAY=$(date +%-e)
DOW=${DOW_LIST[$(date +%w)]}
HOUR=$(date +%H | sed -e 's/^0//')
MINUTE=$(date +%M | sed -e 's/^0//')
# 六曜を取得
ROKUYOU=${ROKUYOU_LIST[$(curl -s "http://api.sekido.info/qreki?output=json&year=${YEAR}&month=${MONTH}&day=${DAY}" | ${JQ} '.rokuyou')]}
# あいさつする
if [ ${HOUR} -lt 4 -o ${HOUR} -gt 17 ]; then
yukkuri "こんばんは。"
elif [ ${HOUR} -lt 11 ]; then
yukkuri "おはようございます。"
else
yukkuri "こんにちは。"
fi
# 現在時刻をしゃべる
yukkuri "ゆっくりが、${YEAR}年${MONTH}月${DAY}日、${DOW}、${ROKUYOU}、${HOUR}時${MINUTE}分くらいをお知らせします。"
# 引数があった場合、追加でそれをしゃべる
if [ -n "$1" ]; then
yukkuri "$1"
fi
今日の天気を調べる
皆さん、
天気は、
#!/bin/bash
. /home/mizuno/bin/yukkuri.sh
LOCATION=016010
CITY="さっぽろ"
TEMPER=/usr/local/bin/temper
# jqコマンドの存在確認
JQ=${JQ:-$(which jq)}
if [ ! -x "${JQ}" ]; then
echo "jq not exist." 1>&2
echo "Please install jq package." 1>&2
exit 1
fi
# UnicodeエスケープシーケンスをUnicode数値文字参照に置換した後nkfでUTF-8にする
TENKI=$(curl -s "http://weather.livedoor.com/forecast/webservice/json/v1?city=${LOCATION}" | sed -e 's/\\u\(....\)/\\1;/g' | nkf --numchar-input -w)
# 天気を取り出す
TELOP=$(echo ${TENKI} | ${JQ} '.forecasts[0].telop')
# 晴(はれ) 雪(ゆき)などを正しく訓読みで発音できないので置換する
TELOP=$(echo ${TELOP} | sed -e 's/雪/ゆき/g' -e 's/曇り*/くもり/g' -e 's/晴れ*/はれ/g' -e 's/雨/あめ/g' -e 's/時々/ときどき/g')
# 最高気温を取り出す
TEMP=$(echo ${TENKI} | ${JQ} '.forecasts[0].temperature.max.celsius')
# マイナスを発音できるように置換する
# 最高気温がマイナスにならない地域では不要かも
TEMP=$(echo ${TEMP} | sed -e 's/\-/マイナス/')
# 天気をしゃべる
if [ -n "${TELOP}" ]; then
yukkuri "今日の${CITY}の天気は、${TELOP}です。"
fi
# 気温をしゃべる
# 夜間など、APIを叩く時間帯によっては最高気温がnullで返ってくるので回避対応
if [ "${TEMP}" != "null" ]; then
yukkuri "最高気温は、${TEMP}度です。"
fi
# temperコマンドで室温が取れる場合は、室温もしゃべる
if [ -x "${TEMPER}" ]; then
ROOMTEMP=$(${TEMPER} | cut -d',' -f2 | sed -e 's/\.[0-9]*//')
yukkuri "現在の室内の温度は、${ROOMTEMP}度です。"
fi
ゴミ出しを忘れないために
朝、
最近は自治体のゴミカレンダーがデータとして提供されているケースも増えてきましたので、
while read line
do
case $line in
BEGIN:VEVENT*)
DATE=""
SUMMARY=""
;;
END:VEVENT*)
echo "$DATE,$SUMMARY"
;;
DTSTART*)
DATE=$(echo $line | sed -e 's/DTSTART;VALUE=DATE:\([0-9]*\)/\1/')
;;
SUMMARY:*)
SUMMARY=$(echo $line | sed -e 's/SUMMARY:\(.*\)/\1/')
;;
esac
done < (icalファイル)
#!/bin/bash
. /home/mizuno/bin/yukkuri.sh
# 「YYYYMMDD,収集内容」となっているCSV形式のゴミカレンダー
GOMICAL=/home/mizuno/gomical/gomical.csv
# ゴミカレンダーから今日の収集内容を取得
if [ -r "${GOMICAL}" ]; then
GOMI=$(grep $(date +%Y%m%d) ${GOMICAL} | cut -d',' -f2)
fi
# ゴミの収集予定をしゃべる
if [ -n "${GOMI}" ]; then
yukkuri "今日は、${GOMI}、のゴミ収集があります。ゴミ出しを忘れないようにしましょう。"
else
yukkuri "今日のゴミ収集はありません。"
fi
タスクリマインダーとして利用する
本連載357回で、
Taskwarriorがインストールされている場合、
#!/bin/bash
. /home/mizuno/bin/yukkuri.sh
TASK=${TASK:-$(which task)}
# 発声のためタスクのdescriptionだけを抽出するオプション
TASK_OPTIONS="rc.verbose=nothing rc.color=off rc.report.yukkuri.columns=description rc.report.yukkuri.filter=status:pending yukkuri"
# TaskWarriorがインストールされている場合、現在Pending中のタスクをしゃべる
if [ -x "${TASK}" ]; then
yukkuri "現在のタスクは"
# 複数行は発声できないため、読み込んだタスクを一行にまとめる
TASKS=$(${TASK} ${TASK_OPTIONS} | tr '\n' ' ')
if [ -n "${TASKS}" ]; then
yukkuri "${TASKS} です。"
else
yukkuri "ありません。"
fi
fi
cronで定時実行
ここまでに作成したシェルスクリプトを連続して呼び出すスクリプトを作成し、
$ cat /etc/cron.d/schedule
45 8 * * 1,2,3,4,5 mizuno /home/mizuno/bin/alerm.sh
30 9 * * 6,7 mizuno /home/mizuno/bin/alerm.sh
さらなる活用
基本は
筆者は実際にこのシステムをここ2週間ほど自宅で運用していますが、
0 10-19 * * * mizuno /home/mizuno/bin/datetime.sh
皆さんも、