以前の作ったKindle用の天気予報で使っていたArmbian入りのTV-boxのeMMCが使用不能になったので、今回はOpenWrtをサーバにしで作りました。前回と同じものでは面白くないのでレイアウトを変えてみました。
必要要件
- 少なくとも256M/100MのOpenWrtルーター
- USBポート x1
- LANポート x1
- OpenWeatherMapのAPI鍵
- One Call APIのサブスクリプション
- CloudConvertのAPI鍵
- Jailbroken Kindle 3
十分なメモリとTFカードが使えるOrangePi zeroを使用しました。
リポジトリー
https://github.com/Neelakurinji123/kindle-weather-display-for-openwrt.git
CloudConvertのAPI鍵の作成
ダッシュボードのCreate API keyのNameScopesを次の4箇所にチェックを入れてAPI鍵を作成します。
- user.read:View your user data
- user.write: Update your user data task.read:
- View your task and job data task.write:
- Update your task and job data
OpneWrtのセットアップ
Python3のインストール
# opkg install python3 python3-pytz python3-pip python3-requests imagemagick
# pip install wheel
# pip install --upgrade pip
# pip install --upgrade setuptools
# pip install cloudconvert
ネットワークインターフェース(usb)とファイヤーウォールゾーン(usb)の作成
USBデバイス用のネットワークとファイヤーウォールの設定をします。
- IPは
192.168.2.1/24
に設定 - インターフェースのファイヤーウォールゾーンは
usb
- ファイヤーウォールゾーンを
usb
に設定し全て閉じる usb
ゾーンをlan
にフォワードする- Traffic Rulesで
22/tcp
、123/udp
、53/udp
、icmpをincomingとoutgoingの両方を開ける 123/udp
、53/udp
、icmpをインターネットに通すためにsnat
を設定する
USBネットワークを有効にします。
# opkg install kmod-usb-net kmod-usb-net-rndis kmod-usb-net-cdc-ether usbutils
設定内容
firewall.@zone[2]=zone
firewall.@zone[2].name='usb'
firewall.@zone[2].network='usb'
firewall.@zone[2].forward='REJECT'
firewall.@zone[2].input='REJECT'
firewall.@zone[2].output='REJECT'
firewall.@rule[11]=rule
firewall.@rule[11].name='Allow-USB-ssh'
firewall.@rule[11].proto='tcp'
firewall.@rule[11].src='usb'
firewall.@rule[11].dest_port='22'
firewall.@rule[11].target='ACCEPT'
firewall.@rule[12]=rule
firewall.@rule[12].name='Allow-USB-NTP'
firewall.@rule[12].proto='udp'
firewall.@rule[12].src='usb'
firewall.@rule[12].dest_port='123'
firewall.@rule[12].target='ACCEPT'
firewall.@rule[13]=rule
firewall.@rule[13].name='Allow-USB-HTTP'
firewall.@rule[13].proto='tcp'
firewall.@rule[13].src='usb'
firewall.@rule[13].dest_port='80'
firewall.@rule[13].target='ACCEPT'
firewall.@rule[14]=rule
firewall.@rule[14].name='Allow-LAN-NTP'
firewall.@rule[14].proto='udp'
firewall.@rule[14].src='lan'
firewall.@rule[14].dest_port='123'
firewall.@rule[14].target='ACCEPT'
firewall.@nat[0]=nat
firewall.@nat[0].proto='udp'
firewall.@nat[0].src='lan'
firewall.@nat[0].dest_port='123'
firewall.@nat[0].target='SNAT'
firewall.@nat[0].name='SNAT-NTP'
firewall.@nat[0].src_ip='192.168.2.0/24'
firewall.@nat[0].snat_ip='<br-lan IP>'
firewall.@nat[0].device='br-lan'
firewall.@nat[1]=nat
firewall.@nat[1].name='SNAT-DNS'
firewall.@nat[1].proto='udp'
firewall.@nat[1].dest_port='53'
firewall.@nat[1].target='SNAT'
firewall.@nat[1].src='lan'
firewall.@nat[1].src_ip='192.168.2.0/24'
firewall.@nat[1].snat_ip='<br-lan IP>'
firewall.@nat[1].device='br-lan'
firewall.@nat[2]=nat
firewall.@nat[2].name='SNAT-PING'
firewall.@nat[2].target='SNAT'
firewall.@nat[2].src='lan'
firewall.@nat[2].src_ip='192.168.2.0/24'
firewall.@nat[2].snat_ip='<br-lan IP>'
firewall.@nat[2].device='br-lan'
firewall.@nat[2].proto='icmp'
firewall.@rule[15]=rule
firewall.@rule[15].name='Allow-USB-OUT-SSH'
firewall.@rule[15].proto='tcp'
firewall.@rule[15].dest='usb'
firewall.@rule[15].dest_port='22'
firewall.@rule[15].target='ACCEPT'
firewall.@rule[16]=rule
firewall.@rule[16].name='Allow-USB-OUT-NTP'
firewall.@rule[16].proto='udp'
firewall.@rule[16].dest='usb'
firewall.@rule[16].dest_port='123'
firewall.@rule[16].target='ACCEPT'
firewall.@rule[17]=rule
firewall.@rule[17].name='Alow-USB-OUT-PING'
firewall.@rule[17].proto='icmp'
firewall.@rule[17].dest='usb'
firewall.@rule[17].target='ACCEPT'
firewall.@rule[18]=rule
firewall.@rule[18].name='Allow-USB-PING'
firewall.@rule[18].proto='icmp'
firewall.@rule[18].target='ACCEPT'
firewall.@rule[18].src='usb'
firewall.@rule[19]=rule
firewall.@rule[19].name='Allow-USB-DNS'
firewall.@rule[19].proto='udp'
firewall.@rule[19].dest_port='53'
firewall.@rule[19].target='ACCEPT'
firewall.@rule[19].src='usb'
firewall.@rule[20]=rule
firewall.@rule[20].name='Allow-USB-OUT-DNS'
firewall.@rule[20].proto='udp'
firewall.@rule[20].dest_port='53'
firewall.@rule[20].target='ACCEPT'
firewall.@rule[20].src='usb'
firewall.@forwarding[1]=forwarding
firewall.@forwarding[1].src='usb'
firewall.@forwarding[1].dest='lan'
network.usb=interface
network.usb.proto='static'
network.usb.netmask='255.255.255.0'
network.usb.device='usb0'
network.usb.ipaddr='192.168.2.1'
system.@system[0].zonename='<Zone Name>'
system.@system[0].timezone='<Time Zone>'
Kindle Weather Displayのセットアップ
OpenWrt用のkindle-weather-display-for-openwrtをコピーします。
# opkg install unzip
# unzip kindle-weather-display-for-openwrt.zip
# mkdir /opt
# mv kindle-weather-display-for-openwrt/opt/kindle-weather-station /opt/
# cd /opt/kindle-weather-station
settings.json
とcloudconvert.json
を編集してOpenWeatherMapとcloudconvertのAPI鍵を書き込みます。
cronを編集し再起動します。
# crontab -e
0 * * * * sh -c "/opt/kindle-weather-station/kindle-weather.sh"
# /etc/init.d/cron stop
# /etc/init.d/cron start
毎時、createSVGv2.py
を実行してtmp
ディレクトリにKindleStation.svg
、KindleStation.png
そしてKindleStation_flatten.png
を作成します。
Kindleのセットアップ
Kindle用のkindle-weather-display-for-openwrtをKindleにコピーします。
# scp kindle-weather-display-for-openwrt.zip root@192.168.2.2:/tmp
Kindleにアクセスしてファイルを展開します。
# ssh root@192.168.2.2
# cd /tmp
# unzip kindle-weather-display-for-openwrt.zip
# mv kindle-weather-display-for-openwrt/kindle/kindle-weather /mnt/us
# mv kindle-weather-display-for-openwrt/kindle/launchpad /mnt/us
# cd /mnt/us/kindle-weather
# mv disable enable
tmpfsを作ります
# mntroot rw
# mkdir /tmp_data
# nano /etc/fstab
tmpfs /tmp_data tmpfs defaults,size=16m 0 0
# mount -a
ネットワークの設定追加します。
# nano /etc/resolv.conf
nameserver 8.8.8.8
nameserver 1.1.1.1
# ip r add default via 192.168.2.1
テストしてみます。
# sh -c "/usr/bin/ntpdate 0.jp.pool.ntp.org"
22 Feb 03:14:13 ntpdate[18859]: adjust time server 129.250.35.251 offset -0.007174 sec
crontabを編集します。毎時に時刻合わせと気象情報(KindleStation_flatten.png
)をOpenWrtからダウンロードして表示します。
# mntroot rw
# nano /etc/crontab/root
2 * * * * sh -c "/mnt/us/kindle-weather/weather-script.sh"
58 * * * * sh -c "/usr/bin/ntpdate 0.jp.pool.ntp.org"
# mntroot ro
# /etc/init.d/cron stop
# kill $(pidof crond)
# /etc/init.d/cron start
# pidof crond
KindleのsshのRSA鍵を作成します。
# mkdir /mnt/us/.ssh
# cd /mnt/us/.ssh
# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/tmp/root/../../../../../../mnt/us/usbnet/etc/dot.ssh/id_rsa): /mnt/us/.ssh/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /mnt/us/.ssh/id_rsa.
Your public key has been saved in /mnt/us/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:PoCOk8QP8ZqA0n/c+ON8IBPpBZ6SPba6cpCS7ru89Vc root@kindle
The key's randomart image is:
+---[RSA 2048]----+
| |
| . |
| . + + |
|.o oo.O . |
|+.=.o+.=S |
|+ooX .==.E |
|..*o+.+o=. |
|..o.+. +... |
|.*+o.o..+o |
+----[SHA256]-----+
# scp -i /mnt/us/.ssh/id_rsa id_rsa.pub root@192.168.2.1:/tmp
公開鍵をOpenWrtに登録します。
# cat /tmp/id_rsa.pub >> /etc/dropbear/authorized_keys
Kindle Weather Displayの停止
# ssh root@192.168.2.2
# cd /mnt/us/kindle-weather
# mv enable disable
cronを編集してweather-script.shの行を削除します。
# nano /etc/crontab/root
#2 * * * * sh -c "/mnt/us/kindle-weather/weather-script.sh"
#0 * * * * sh -c "/usr/bin/ntpdate 0.jp.pool.ntp.org"
Kindleのキーボードを素早くShift
、q
、q
を押すとリブートします。