Kindle/Weather Display

From Wiki

Based on http://www.mpetroff.net/archives/2012/09/14/kindle-weather-display/

modified for Kindle Touch 5.1.2 / 5.3.2.1

Kindle

  • /mnt/us/scripts/weather-init.sh
#!/bin/sh
initctl stop framework &
sleep 3
initctl stop powerd &
sleep 5

/mnt/us/scripts/weather-display.sh >/dev/nul &


  • /mnt/us/scripts/weather-display.sh
#!/bin/sh
#
# This script will reload the display only if source png file changed
# log data is going to /tmp/weather-display

while  :
do
	rm weather-image.png
	if wget -q http://host/weather/kindle/weather-image.png
	then
		if [ ! -e weather-current.png ]
		then 
			cp weather-image.png  weather-current.png
		fi

		if [ "$(cat weather-image.png | md5sum)" != "$(cat weather-current.png | md5sum)" ]
		then
			echo $(date -Iseconds) "|" new file >> /tmp/weather-display
			rm weather-current.png
			cp weather-image.png weather-current.png
			eips -c
			eips -c
			eips -f -g weather-current.png
		else
			echo $(date -Iseconds) "|" no changes >> /tmp/weather-display
			#eips -g weather-current.png
		fi
	else
		echo $(date -Iseconds) "|" error >> /tmp/weather-display
		eips -g weather-image-error.png
	fi

	#echo $(date -Iseconds) "|" screen written >> /tmp/weather-display
	sleep 300
done

Server

  • apt-get install pngcrush librsvg2-bin
  • /etc/cron.d/kindle-weather
# m	h	dom	mon	dow	user	command
*/30	*	*	*	*	root	/usr/bin/python2 /srv/kindle-weather/weather-script.py
  • /srv/kindle-weather/weather-script.py
# -*- coding: utf-8 -*-
import urllib2
import datetime
import codecs
import os
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector

# Downloading wetter.com pages
html_current = urllib2.urlopen('http://www.wetter.com/wetter_aktuell/aktuelles_wetter/deutschland/bremen/DE0001516.html').read()
html_16dayforecast = urllib2.urlopen('http://www.wetter.com/wetter_aktuell/wettervorhersage/16_tagesvorhersage/?id=DE0001516').read()

# scraping current values
hxs = HtmlXPathSelector(text=html_current)
current_temp      = hxs.select('//div[@class="degree"]/text()').extract()[0].strip().strip("C").strip(u"°").strip()
current_icon     = hxs.select('//div[@class="status"]/text()').extract()[0].strip()
current_humidity = hxs.select('//table[@class="currentValuesTable"]/tr[2]/td[2]/text()').extract()[0].strip().strip("%").strip()
current_atmpressure = hxs.select('//table[@class="currentValuesTable"]/tr[2]/td[4]/text()').extract()[0].strip().strip("hPa").strip().strip("0").strip(",").strip()
current_windspeed = hxs.select('//table[@class="currentValuesTable"]/tr/td[4]/text()').extract()[0].strip().split()
current_windspeed = current_windspeed[0]
current_winddirection = hxs.select('//table[@class="currentValuesTable"]/tr/td[3]/text()').extract()[0].strip()

# scraping forecast values
hxs = HtmlXPathSelector(text=html_16dayforecast)
todays_date = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[1]/dl[2]/dd[1]/text()').extract()[1].strip()
forecast_0d_low = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[1]/dl[2]/dd[4]/span/span/text()').extract()[0].strip()
forecast_0d_high = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[1]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°").strip()
forecast_0d_icon = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[1]/dl[2]/dd[3]/strong/text()').extract()[0].strip()
forecast_1d_low = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[3]/dl[2]/dd[4]/span/span/text()').extract()[0].strip()
forecast_1d_high = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[3]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°").strip()
forecast_1d_icon = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[3]/dl[2]/dd[3]/strong/text()').extract()[0].strip()
forecast_2d_low = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[5]/dl[2]/dd[4]/span/span/text()').extract()[0].strip()
forecast_2d_high = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[5]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°").strip()
forecast_2d_icon = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[5]/dl[2]/dd[3]/strong/text()').extract()[0].strip()
forecast_3d_low = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[7]/dl[2]/dd[4]/span/span/text()').extract()[0].strip()
forecast_3d_high = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[7]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°").strip()
forecast_3d_icon = hxs.select('//div[@class="clearfix sixteendayBox first "]/table/tr/td[7]/dl[2]/dd[3]/strong/text()').extract()[0].strip()

forecast_4d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[1]/dl[2]/dd[4]/span/span/text()').extract()[0]
forecast_4d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[1]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°")
forecast_5d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[3]/dl[2]/dd[4]/span/span/text()').extract()[0]
forecast_5d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[3]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°")
forecast_6d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[5]/dl[2]/dd[4]/span/span/text()').extract()[0]
forecast_6d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[5]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°")
forecast_7d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[7]/dl[2]/dd[4]/span/span/text()').extract()[0]
forecast_7d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[7]/dl[2]/dd[4]/span/text()').extract()[0].strip(" /C").strip(u"°")
forecast_8d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[1]/dl[2]/dd[4]/span/span/text()').extract()[1]
forecast_8d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[1]/dl[2]/dd[4]/span/text()').extract()[1].strip(" /C").strip(u"°")
forecast_9d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[3]/dl[2]/dd[4]/span/span/text()').extract()[1]
forecast_9d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[3]/dl[2]/dd[4]/span/text()').extract()[1].strip(" /C").strip(u"°")
forecast_10d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[5]/dl[2]/dd[4]/span/span/text()').extract()[1]
forecast_10d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[5]/dl[2]/dd[4]/span/text()').extract()[1].strip(" /C").strip(u"°")
forecast_11d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[7]/dl[2]/dd[4]/span/span/text()').extract()[1]
forecast_11d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[7]/dl[2]/dd[4]/span/text()').extract()[1].strip(" /C").strip(u"°")
forecast_12d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[1]/dl[2]/dd[4]/span/span/text()').extract()[2]
forecast_12d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[1]/dl[2]/dd[4]/span/text()').extract()[2].strip(" /C").strip(u"°")
forecast_13d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[3]/dl[2]/dd[4]/span/span/text()').extract()[2]
forecast_13d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[3]/dl[2]/dd[4]/span/text()').extract()[2].strip(" /C").strip(u"°")
forecast_14d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[5]/dl[2]/dd[4]/span/span/text()').extract()[2]
forecast_14d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[5]/dl[2]/dd[4]/span/text()').extract()[2].strip(" /C").strip(u"°")
forecast_15d_low = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[7]/dl[2]/dd[4]/span/span/text()').extract()[2]
forecast_15d_high = hxs.select('//div[@class="clearfix sixteendayBox nonfirst"]/table/tr/td[7]/dl[2]/dd[4]/span/text()').extract()[2].strip(" /C").strip(u"°")


# print scraped data
print ("Aktuelles Datum              :    " + todays_date)
print ("Aktuelle Temperatur          :    " + current_temp)
print ("Aktuelle Luftfeuchte         :    " + current_humidity)
print ("Aktueller Luftdruck          :    " + current_atmpressure)
print ("Aktuelle Windgeschwindigkeit :    " + current_windspeed)
print ("Aktuelle Windrichtung        :    " + current_winddirection)
print ("Aktuelle Wetterlage          :    " + current_icon)

print ("")
print ("")

print ("today : " + forecast_0d_low + " - " + forecast_0d_high + "   / " + forecast_0d_icon)
print ("1d    : " + forecast_1d_low + " - " + forecast_1d_high + "   / " + forecast_1d_icon)
print ("2d    : " + forecast_2d_low + " - " + forecast_2d_high + "   / " + forecast_2d_icon)
print ("3d    : " + forecast_3d_low + " - " + forecast_3d_high + "   / " + forecast_3d_icon)
print ("4d    : " + forecast_4d_low + " - " + forecast_4d_high)
print ("5d    : " + forecast_5d_low + " - " + forecast_5d_high)
print ("6d    : " + forecast_6d_low + " - " + forecast_6d_high)
print ("7d    : " + forecast_7d_low + " - " + forecast_7d_high)
print ("8d    : " + forecast_8d_low + " - " + forecast_8d_high)
print ("9d    : " + forecast_9d_low + " - " + forecast_9d_high)
print ("10d   : " + forecast_10d_low + " - " + forecast_10d_high)
print ("11d   : " + forecast_11d_low + " - " + forecast_11d_high)
print ("12d   : " + forecast_12d_low + " - " + forecast_12d_high)
print ("13d   : " + forecast_13d_low + " - " + forecast_13d_high)
print ("14d   : " + forecast_14d_low + " - " + forecast_14d_high)
print ("15d   : " + forecast_15d_low + " - " + forecast_15d_high)

# Process SVG
output = codecs.open('weather-script-preprocess.svg', 'r', encoding='utf-8').read()

output = output.replace('CURRENT_TEMP',str(current_temp)).replace('CURRENT_HUMIDITY',str(current_humidity)).replace('CURRENT_ATMPRESSURE',str(current_atmpressure)).replace('CURRENT_WINDSPEED',str(current_windspeed))
output = output.replace('HIGH_ZERO',str(forecast_0d_high)).replace('HIGH_ONE',str(forecast_1d_high)).replace('HIGH_TWO',str(forecast_2d_high)).replace('HIGH_THREE',str(forecast_3d_high))
output = output.replace('LOW_ZERO',str(forecast_0d_low)).replace('LOW_ONE',str(forecast_1d_low)).replace('LOW_TWO',str(forecast_2d_low)).replace('LOW_THREE',str(forecast_3d_low))

day_one = datetime.datetime.strptime(todays_date, '%d.%m.%Y')
one_day = datetime.timedelta(days=1)
days_of_week = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag']
output = output.replace('DAY_ONE',days_of_week[(day_one + one_day).weekday()]).replace('DAY_TWO',days_of_week[(day_one + 2*one_day).weekday()]).replace('DAY_THREE',days_of_week[(day_one + 3*one_day).weekday()])
output = output.replace('DAY_ZERO',days_of_week[(day_one).weekday()] + ", " + todays_date)

codecs.open('weather-script-output.svg', 'w', encoding='utf-8').write(output)

# Convert SVG to PNG
os.system("rsvg-convert --background-color=white -o weather-script-output.png weather-script-output.svg")

# Rotate PNG
os.system("convert weather-script-output.png -rotate 270 weather-script-output.png")

# Compress PNG
os.system("pngcrush -c 0 -ow weather-script-output.png weather-image.png")