Kindle Weather Display for OpenWrt

以前の作った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/tcp123/udp53/udp、icmpをincomingとoutgoingの両方を開ける
  • 123/udp53/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.jsoncloudconvert.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.svgKindleStation.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のキーボードを素早くShiftqqを押すとリブートします。

This entry was posted in kindle, OpenWrt. Bookmark the permalink.