forked from adafruit/Python-Thermal-Printer
-
Notifications
You must be signed in to change notification settings - Fork 2
/
timetemp.py
executable file
·167 lines (147 loc) · 6.43 KB
/
timetemp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/python
# Current time and temperature display for Raspberry Pi w/Adafruit Mini
# Thermal Printer. Retrieves data from Yahoo! weather, prints current
# conditions and time using large, friendly graphics.
# See forecast.py for a different weather example that's all text-based.
# Written by Adafruit Industries. MIT license.
#
# Required software includes Adafruit_Thermal, Python Imaging and PySerial
# libraries. Other libraries used are part of stock Python install.
#
# Resources:
# http://www.adafruit.com/products/597 Mini Thermal Receipt Printer
# http://www.adafruit.com/products/600 Printer starter pack
from __future__ import print_function
from Adafruit_Thermal import *
from xml.dom.minidom import parseString
import Image, ImageDraw, time, urllib
# WOEID indicates the geographic location for the forecast. It is
# not a ZIP code or other common indicator. Instead, it can be found
# by 'manually' visiting http://weather.yahoo.com, entering a location
# and requesting a forecast, then copy the number from the end of the
# current URL string and paste it here.
WOEID = '2459115'
# Fetch weather data from Yahoo!, parse resulting XML
dom = parseString(urllib.urlopen(
'http://weather.yahooapis.com/forecastrss?w=' + WOEID).read())
# Extract values relating to current temperature, humidity, wind
temperature = int(dom.getElementsByTagName(
'yweather:condition')[0].getAttribute('temp'))
humidity = int(dom.getElementsByTagName(
'yweather:atmosphere')[0].getAttribute('humidity'))
windSpeed = int(dom.getElementsByTagName(
'yweather:wind')[0].getAttribute('speed'))
windDir = int(dom.getElementsByTagName(
'yweather:wind')[0].getAttribute('direction'))
windUnits = dom.getElementsByTagName(
'yweather:units')[0].getAttribute('speed')
# Although the Python Imaging Library does have nice font support,
# I opted here to use a raster bitmap for all of the glyphs instead.
# This allowed lots of control over kerning and such, and I didn't
# want to spend a lot of time hunting down a suitable font with a
# permissive license.
symbols = Image.open("gfx/timetemp.png") # Bitmap w/all chars & symbols
img = Image.new("1", [330, 117], "white") # Working 'background' image
draw = ImageDraw.Draw(img)
# These are the widths of certain glyphs within the 'symbols' bitmap
TimeDigitWidth = [ 38, 29, 38, 36, 40, 35, 37, 37, 38, 37, 13 ]
TempDigitWidth = [ 33, 25, 32, 31, 35, 30, 32, 32, 33, 32, 17, 14 ]
DateDigitWidth = [ 16, 13, 16, 15, 17, 15, 16, 16, 16, 16 ]
HumiDigitWidth = [ 14, 10, 14, 13, 15, 12, 13, 13, 13, 13, 18 ]
DayWidth = [ 104, 109, 62, 110, 88, 110, 95 ]
MonthWidth = [ 53, 52, 60, 67, 59, 63, 59, 56, 51, 48, 54, 53 ]
DirWidth = [ 23, 35, 12, 27, 15, 33, 19, 41, 23 ]
DirAngle = [ 23, 68, 113, 157, 203, 247, 293, 336 ]
# Generate a list of sub-image glyphs cropped from the symbols image
def croplist(widths, x, y, height):
list = []
for i in range(len(widths)):
list.append(symbols.crop(
[x, y+i*height, x+widths[i], y+(i+1)*height]))
return list
# Crop glyph lists (digits, days of week, etc.)
TimeDigit = croplist(TimeDigitWidth, 0, 0, 44)
TempDigit = croplist(TempDigitWidth, 40, 0, 39)
DateDigit = croplist(DateDigitWidth, 75, 0, 18)
HumiDigit = croplist(HumiDigitWidth, 75, 180, 16)
Day = croplist(DayWidth , 93, 0, 25)
Month = croplist(MonthWidth , 93, 175, 24)
Dir = croplist(DirWidth , 162, 175, 21)
# Crop a few odds-and-ends glyphs (not in lists)
Wind = symbols.crop([ 93, 463, 157, 479 ])
Humidity = symbols.crop([ 93, 479, 201, 500 ])
Kph = symbols.crop([ 156, 366, 196, 386 ])
Mph = symbols.crop([ 156, 387, 203, 407 ])
# Draw top & bottom bars
draw.rectangle([42, 0, 330, 3], fill="black")
draw.rectangle([42, 113, 330, 116], fill="black")
x = 42 # Initial drawing position
y = 12
# Paste a series of glyphs (mostly numbers) from string to img
def drawNums(str, x, y, list):
for i in range(len(str)):
d = ord(str[i]) - ord('0')
img.paste(list[d], (x, y))
x += list[d].size[0] + 1
return x
# Determine total width of a series of glyphs in string
def numWidth(str, list):
w = 0 # Cumulative width
for i in range(len(str)):
d = ord(str[i]) - ord('0')
if i > 0: w += 1 # Space between digits
w += list[d].size[0] # Digit width
return w
# Render current time (always 24 hour XX:XX format)
t = time.localtime()
drawNums(time.strftime("%H:%M", t), x, y, TimeDigit)
# Determine wider of day-of-week or date (for alignment)
s = str(t.tm_mday) # Convert day of month to a string
w = MonthWidth[t.tm_mon - 1] + 6 + numWidth(s, DateDigit)
if DayWidth[t.tm_wday] > w: w = DayWidth[t.tm_wday]
# Draw day-of-week and date
x = img.size[0] - w # Left alignment for two lines
img.paste(Day[t.tm_wday], (x, y)) # Draw day of week word
y += 27 # Next line
img.paste(Month[t.tm_mon - 1], (x, y)) # Draw month word
x += MonthWidth[t.tm_mon - 1] + 6 # Advance past month
drawNums(s, x, y, DateDigit) # Draw day of month
x = 42 # Position for temperature
y = 67
# Degrees to string, remap '-' glyph, append degrees glyph
s = str(temperature).replace('-', ';') + ':'
drawNums(s, x, y, TempDigit)
# Determine wider of humidity or wind info
s = str(humidity) + ':' # Appends percent glyph
s2 = str(windSpeed)
winDirNum = 0 # Wind direction glyph number
if windSpeed > 0:
for winDirNum in range(len(DirAngle) - 1):
if windDir < DirAngle[winDirNum]: break
w = Humidity.size[0] + 5 + numWidth(s, HumiDigit)
w2 = Wind.size[0] + 5 + numWidth(s2, HumiDigit)
if windSpeed > 0:
w2 += 3 + Dir[winDirNum].size[0]
if windUnits == 'kph': w2 += 3 + Kph.size[0]
else: w2 += 3 + Mph.size[0]
if w2 > w: w = w2
# Draw humidity and wind
x = img.size[0] - w # Left-align the two lines
y = 67
img.paste(Humidity, (x, y))
x += Humidity.size[0] + 5
drawNums(s, x, y, HumiDigit)
x = img.size[0] - w # Left-align again
y += 23 # And advance to next line
img.paste(Wind, (x, y))
x += Wind.size[0] + 5
if windSpeed > 0:
img.paste(Dir[winDirNum], (x, y))
x += Dir[winDirNum].size[0] + 3
x = drawNums(s2, x, y, HumiDigit) + 3
if windUnits == 'kph': img.paste(Kph, (x, y))
else: img.paste(Mph, (x, y))
# Open connection to printer and print image
printer = Adafruit_Thermal("/dev/ttyAMA0", 19200, timeout=5)
printer.printImage(img, True)
printer.feed(3)