2021-04-26 18:51:21 +00:00
# Copyright (C) 2020 Daniel Richardson richardson.daniel@hotmail.co.uk
#
# This file is part of stockTicker project for justinodunn.
#
# stockTicker can not be copied and/or distributed without the express
# permission of Daniel Richardson
2021-04-28 19:39:30 +00:00
2021-05-01 10:39:20 +00:00
import sys , select
2021-04-26 18:51:21 +00:00
import os
import threading
from PIL import Image , ImageDraw , ImageFont
import time
import csv
2021-04-28 19:39:30 +00:00
import requests
2021-05-05 14:44:43 +00:00
import pexpect
2021-04-27 18:29:14 +00:00
from rgbmatrix import RGBMatrix , RGBMatrixOptions
2021-05-14 10:31:14 +00:00
from rgbmatrix . graphics import *
2021-05-14 12:55:43 +00:00
from multiprocessing import Process
2021-06-02 15:37:31 +00:00
import traceback
2021-06-03 20:56:25 +00:00
import json
from datetime import datetime
2021-06-02 15:37:31 +00:00
2021-05-14 12:02:22 +00:00
2021-05-01 10:39:20 +00:00
def getInput ( Block = False ) :
if Block or select . select ( [ sys . stdin ] , [ ] , [ ] , 0 ) == ( [ sys . stdin ] , [ ] , [ ] ) :
msg = sys . stdin . read ( 1 )
#sys.stdin.flush()
else :
msg = ' '
return msg
2021-05-05 14:44:43 +00:00
2021-05-01 10:39:20 +00:00
2021-04-26 19:27:34 +00:00
class StockTicker ( ) :
def __init__ ( self ) :
#Define global resources
self . symbols = [ ]
2021-05-05 14:44:43 +00:00
2021-04-26 19:27:34 +00:00
self . greenORred = ( 255 , 255 , 255 )
2021-05-03 10:39:31 +00:00
#self.blank = Image.open('logos/blank.png')
2021-06-09 18:06:21 +00:00
self . blank = Image . new ( ' RGB ' , ( 15 , 32 ) )
2021-04-26 19:27:34 +00:00
self . running = True
2021-04-27 18:29:14 +00:00
self . brightness = 1.0
2021-05-03 10:39:31 +00:00
self . delay = 0.02
2021-04-27 18:29:14 +00:00
# Configuration for the matrix
options = RGBMatrixOptions ( )
2021-05-04 16:39:16 +00:00
options . rows = 32
2021-04-27 18:29:14 +00:00
options . cols = 64
2021-05-04 20:55:28 +00:00
options . chain_length = 2
2021-04-27 18:29:14 +00:00
options . parallel = 1
options . hardware_mapping = ' adafruit-hat ' # If you have an Adafruit HAT: 'adafruit-hat'
2021-04-28 19:39:30 +00:00
options . gpio_slowdown = 3
2021-04-27 18:29:14 +00:00
self . matrix = RGBMatrix ( options = options )
2021-05-25 18:57:34 +00:00
self . points = True # display crypto change in points or percent
2021-05-05 14:44:43 +00:00
2021-04-27 18:29:14 +00:00
def openImage ( self , image_file ) :
image = Image . open ( image_file )
# Make image fit our screen.
#image.thumbnail((self.matrix.width, self.matrix.height), Image.ANTIALIAS)
image = image . convert ( ' RGB ' )
return image
2021-06-08 20:16:08 +00:00
def degreesToCompass ( self , deg ) :
dirs = [ ' N ' , ' NE ' , ' E ' , ' SE ' , ' S ' , ' SW ' , ' W ' , ' NW ' ]
return dirs [ int ( ( deg + 22.5 ) / / 45 ) % 8 ]
2021-04-27 18:29:14 +00:00
2021-06-08 20:16:08 +00:00
def setImage ( self , image , offset_x = 0 , offset_y = 0 , unsafe = False , min_x = 0 , max_x = 128 , min_y = 0 , max_y = 32 ) :
2021-04-27 18:29:14 +00:00
if ( image . mode != " RGB " ) :
raise Exception ( " Currently, only RGB mode is supported for SetImage(). Please create images with mode ' RGB ' or convert first with image = image.convert( ' RGB ' ). Pull requests to support more modes natively are also welcome :) " )
if unsafe :
2021-05-01 10:39:20 +00:00
#In unsafe mode we directly acceshow to send commands to running python processs the underlying PIL image array
2021-04-27 18:29:14 +00:00
#in cython, which is considered unsafe pointer accecss,
#however it's super fast and seems to work fine
#https://groups.google.com/forum/#!topic/cython-users/Dc1ft5W6KM4
img_width , img_height = image . size
2021-04-28 19:39:30 +00:00
2021-04-27 18:29:14 +00:00
self . matrix . SetPixelsPillow ( offset_x , offset_y , img_width , img_height , image )
else :
# First implementation of a SetImage(). OPTIMIZE_ME: A more native
# implementation that directly reads the buffer and calls the underlying
# C functions can certainly be faster.
img_width , img_height = image . size
pixels = image . load ( )
2021-06-09 18:13:48 +00:00
for y in range ( max ( 0 , - offset_y ) , min ( img_height , self . matrix . height - offset_y ) ) :
for x in range ( max ( 0 , - offset_x ) , min ( img_width , self . matrix . width - offset_x ) ) :
2021-06-08 20:16:08 +00:00
2021-06-09 18:13:48 +00:00
2021-04-27 18:29:14 +00:00
( r , g , b ) = pixels [ x , y ]
2021-06-08 20:16:08 +00:00
if min_x < = x + offset_x < = max_x and min_y < = y + offset_y < = max_y :
self . matrix . SetPixel ( x + offset_x , y + offset_y , r * self . brightness , g * self . brightness , b * self . brightness )
2021-04-26 19:27:34 +00:00
2021-05-23 09:34:06 +00:00
def scrollImage ( self , image , offset_x = 0 , offset_y = 0 ) :
2021-04-27 18:59:25 +00:00
img_width , img_height = image . size
2021-04-27 18:29:14 +00:00
2021-05-14 12:55:43 +00:00
2021-04-27 18:59:25 +00:00
while offset_x > - img_width :
offset_x - = 1
2021-05-03 10:39:31 +00:00
self . setImage ( image , offset_x = offset_x , offset_y = offset_y )
2021-05-21 13:24:37 +00:00
2021-05-31 11:22:56 +00:00
# remove the ppixels behind the image, to stop trailing
for x in range ( offset_x + img_width , 128 ) :
for y in range ( self . matrix . height ) :
self . matrix . SetPixel ( x , y , 0 , 0 , 0 )
2021-05-21 13:24:37 +00:00
try :
msg = getInput ( )
if msg == ' K ' :
self . resetMatrix ( )
return True
self . process_msg ( msg )
except KeyboardInterrupt :
sys . stdout . flush ( )
pass
time . sleep ( self . delay )
return False
2021-05-23 09:34:06 +00:00
def scrollImageStacked ( self , image , offset_x = 0 , offset_y = 0 ) :
img_width , img_height = image . size
while offset_x > - img_width - 128 :
offset_x - = 1
self . setImage ( image , offset_x = offset_x + 128 , offset_y = offset_y )
2021-05-23 10:28:46 +00:00
self . setImage ( image , offset_x = offset_x , offset_y = offset_y + 20 )
2021-05-23 09:34:06 +00:00
try :
msg = getInput ( )
if msg == ' K ' :
self . resetMatrix ( )
return True
self . process_msg ( msg )
except KeyboardInterrupt :
sys . stdout . flush ( )
pass
time . sleep ( self . delay )
return False
2021-04-27 18:59:25 +00:00
2021-05-14 10:31:14 +00:00
def scrollImageTransition ( self , image_files , offset_x = 0 , offset_y = 0 , stocks = True ) :
2021-04-27 18:59:25 +00:00
# use two image files and switch between them with a seemless transition
current_img = 1
2021-06-07 20:10:38 +00:00
image1 = self . openImage ( image_files [ 0 ] )
image2 = self . openImage ( image_files [ 1 ] )
2021-05-05 14:44:43 +00:00
kill = False
2021-05-04 21:36:40 +00:00
while True :
2021-04-27 18:59:25 +00:00
2021-05-04 21:36:40 +00:00
if current_img == 1 :
2021-05-14 12:55:43 +00:00
if stocks :
update_process = Process ( target = self . getFullStockImage , args = ( 1 , ) )
update_process . start ( )
2021-06-07 20:10:38 +00:00
image1 = self . openImage ( image_files [ 0 ] )
image2 = self . openImage ( image_files [ 1 ] )
2021-05-14 12:55:43 +00:00
2021-05-04 21:36:40 +00:00
elif current_img == 2 :
2021-05-14 12:55:43 +00:00
if stocks :
update_process = Process ( target = self . getFullStockImage , args = ( 2 , ) )
update_process . start ( )
2021-06-07 20:10:38 +00:00
image1 = self . openImage ( image_files [ 1 ] )
image2 = self . openImage ( image_files [ 0 ] )
2021-05-14 12:55:43 +00:00
2021-05-05 14:44:43 +00:00
img_width , img_height = image1 . size
2021-05-14 10:31:14 +00:00
2021-05-01 10:39:20 +00:00
2021-05-04 21:36:40 +00:00
while offset_x > - img_width :
offset_x - = 1
2021-05-05 14:44:43 +00:00
self . setImage ( image1 , offset_x = offset_x , offset_y = offset_y )
if offset_x + img_width < self . matrix . width : # if the image is ending
self . setImage ( image2 , offset_x = offset_x + img_width , offset_y = offset_y )
2021-05-04 21:36:40 +00:00
time . sleep ( self . delay )
try :
msg = getInput ( )
2021-05-21 13:24:37 +00:00
2021-05-04 21:36:40 +00:00
if msg == ' K ' :
self . resetMatrix ( )
2021-05-05 14:44:43 +00:00
kill = True
2021-05-21 13:24:37 +00:00
image1 . close ( )
image2 . close ( )
2021-05-04 21:36:40 +00:00
break
2021-05-03 10:39:31 +00:00
2021-05-05 15:22:01 +00:00
self . process_msg ( msg )
2021-05-04 21:36:40 +00:00
except KeyboardInterrupt :
sys . stdout . flush ( )
pass
2021-06-07 20:10:38 +00:00
if stocks :
image1 . close ( )
image2 . close ( )
2021-05-21 13:24:37 +00:00
2021-05-05 14:44:43 +00:00
if kill : break
2021-05-01 10:39:20 +00:00
2021-05-14 12:55:43 +00:00
if stocks :
update_process . join ( )
2021-05-04 21:36:40 +00:00
if current_img == 1 :
current_img = 2
elif current_img == 2 :
current_img = 1
offset_x = 0
2021-05-23 09:34:06 +00:00
2021-06-03 20:56:25 +00:00
def textImage ( self , text , font , r = 255 , g = 255 , b = 255 , matrix_height = False , buff = 0 ) :
2021-05-23 09:34:06 +00:00
'''
creates and returns a ppm image containing the text in the supplied font and colour
'''
width , height = self . get_text_dimensions ( text , font )
2021-05-23 10:28:46 +00:00
if matrix_height :
height = 32
2021-06-03 20:56:25 +00:00
img = Image . new ( ' RGB ' , ( width + buff + 3 , height + 3 ) )
2021-05-23 09:34:06 +00:00
d = ImageDraw . Draw ( img )
2021-05-05 19:26:56 +00:00
2021-05-23 10:28:46 +00:00
d . text ( ( 0 , 0 ) , text , fill = ( r , g , b ) , font = font )
2021-05-23 09:34:06 +00:00
return img
2021-05-21 13:24:37 +00:00
2021-05-23 09:34:06 +00:00
def displayUserText ( self ) :
'''
displays the text entered in the webpage by the user .
'''
2021-05-21 13:24:37 +00:00
2021-05-14 10:31:14 +00:00
f = open ( ' csv/scroll_text.csv ' , ' r ' )
CSV = csv . reader ( f )
text , r , g , b = next ( CSV )
f . close ( )
2021-05-31 12:06:57 +00:00
font = ImageFont . load ( " ./fonts/texgyre-27.pil " )
2021-05-14 10:31:14 +00:00
2021-06-03 20:56:25 +00:00
img = self . textImage ( text , font , int ( r ) , int ( g ) , int ( b ) , True , buff = 50 )
2021-05-14 10:31:14 +00:00
img . save ( ' scroll_text.ppm ' )
self . scrollImageTransition ( [ ' scroll_text.ppm ' , ' scroll_text.ppm ' ] , offset_x = 128 , offset_y = 0 , stocks = False )
2021-05-21 10:20:39 +00:00
2021-05-21 13:24:37 +00:00
def displayNews ( self ) :
2021-05-31 10:35:37 +00:00
headline_font = ImageFont . load ( " ./fonts/10x20.pil " )
source_font = ImageFont . load ( " ./fonts/10x20.pil " )
2021-05-21 13:24:37 +00:00
while True :
headlines = [ ]
2021-05-27 19:10:57 +00:00
source_date_times = [ ]
2021-05-21 13:24:37 +00:00
f = open ( ' csv/news.csv ' , ' r ' )
CSV = csv . reader ( f )
next ( CSV )
for row in CSV :
2021-05-27 19:10:57 +00:00
headline , source , date , time = row
headlines . append ( headline )
source_date_times . append ( source + ' : ' + date + ' ' + time )
2021-05-21 13:24:37 +00:00
f . close ( )
2021-05-27 19:10:57 +00:00
if len ( headlines ) > 0 :
for i , headline in enumerate ( headlines ) :
headline = headline . replace ( " ^ " , " , " )
headline = headline . replace ( " ’ " , " ' " )
headline = headline . replace ( " ‘ " , " ' " )
headline = headline . replace ( ' “ ' , ' " ' )
headline = headline . replace ( ' ” ' , ' " ' )
headline_img = self . textImage ( headline , headline_font , matrix_height = True )
source_img = self . textImage ( source_date_times [ i ] , source_font , r = 255 , g = 255 , b = 0 , matrix_height = True )
try :
logos_path = os . path . join ( os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' logos ' ) , ' news_logos ' )
logo = Image . open ( os . path . join ( logos_path , ' techcrunch ' + ' .png ' ) )
2021-06-15 18:35:04 +00:00
2021-05-27 19:10:57 +00:00
img = Image . new ( ' RGB ' , ( headline_img . size [ 0 ] , 32 ) )
2021-05-31 10:35:37 +00:00
img . paste ( headline_img , ( 2 , - 3 ) )
2021-05-27 19:10:57 +00:00
img . paste ( source_img , ( 2 , 16 ) )
img = self . stitchImage ( [ logo , img ] )
except Exception as e :
print ( e )
img = Image . new ( ' RGB ' , ( headline_img . size [ 0 ] , 32 ) )
img . paste ( headline_img , ( 0 , 0 ) )
img . paste ( source_img , ( 0 , 16 ) )
img . save ( ' image.ppm ' )
killed = self . scrollImage ( img , offset_x = 128 , offset_y = 0 )
#killed = self.scrollImageStacked(img, offset_x = 128, offset_y = 0)
if killed : break
else :
print ( ' new failed ' )
2021-05-23 09:34:06 +00:00
if killed : break
2021-05-21 13:24:37 +00:00
2021-05-31 11:22:56 +00:00
def displayGIF ( self , gif ) :
# To iterate through the entire gif
i = 0
while True :
2021-05-21 10:20:39 +00:00
try :
2021-05-31 11:22:56 +00:00
gif . seek ( i )
except EOFError :
print ( ' finished ' )
i = 0
gif . seek ( i )
# do something to im
self . setImage ( gif . convert ( ' RGB ' ) )
time . sleep ( 0.5 )
i + = 1
try :
msg = getInput ( )
if msg == ' K ' :
gif . close ( )
self . resetMatrix ( )
2021-06-02 15:37:31 +00:00
2021-05-31 11:22:56 +00:00
break
self . process_msg ( msg )
except KeyboardInterrupt :
sys . stdout . flush ( )
pass
2021-05-21 13:24:37 +00:00
2021-05-31 11:22:56 +00:00
def scrollGIF ( self , gif , offset_x = 0 , offset_y = 0 ) :
# To iterate through the entire gif
i = 0
img_width , img_height = gif . size
while offset_x > - img_width :
offset_x - = 1
try :
gif . seek ( i )
except EOFError :
print ( ' finished ' )
2021-05-21 10:20:39 +00:00
i = 0
2021-05-31 11:22:56 +00:00
gif . seek ( i )
# do something to im
self . setImage ( gif . convert ( ' RGB ' ) , offset_x = offset_x )
time . sleep ( self . delay )
if offset_x % 20 == 0 :
i + = 1
for x in range ( offset_x + img_width , 128 ) :
for y in range ( self . matrix . height ) :
self . matrix . SetPixel ( x , y , 0 , 0 , 0 )
try :
msg = getInput ( )
if msg == ' K ' :
gif . close ( )
self . resetMatrix ( )
2021-06-02 15:37:31 +00:00
return True
2021-05-31 11:22:56 +00:00
self . process_msg ( msg )
except KeyboardInterrupt :
sys . stdout . flush ( )
pass
2021-06-02 15:37:31 +00:00
return False
2021-06-03 20:56:25 +00:00
2021-04-26 19:27:34 +00:00
#Using change between min and day price give appropriate arrow
#and set the overall change colour
def getArrow ( self , CHANGE ) :
self . greenORred
2021-05-04 16:39:16 +00:00
logos_path = os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' logos ' )
2021-04-26 19:27:34 +00:00
if ( CHANGE > 0 ) :
2021-05-04 16:39:16 +00:00
Arrow = Image . open ( os . path . join ( logos_path , ' up.png ' ) )
2021-04-26 19:27:34 +00:00
self . greenORred = ( 0 , 255 , 0 )
return Arrow , CHANGE
2021-05-04 16:39:16 +00:00
Arrow = Image . open ( os . path . join ( logos_path , ' down.png ' ) )
2021-04-26 19:27:34 +00:00
self . greenORred = ( 255 , 0 , 0 )
CHANGE = ( CHANGE * - 1 )
2021-04-26 18:51:21 +00:00
return Arrow , CHANGE
2021-04-26 19:27:34 +00:00
def get_text_dimensions ( self , text_string , font ) :
2021-05-14 10:31:14 +00:00
canvas = Image . new ( ' RGB ' , ( 10000 , 100 ) )
2021-04-26 19:27:34 +00:00
draw = ImageDraw . Draw ( canvas )
monospace = font
text = text_string
white = ( 255 , 255 , 255 )
2021-05-23 10:28:46 +00:00
draw . text ( ( 0 , 0 ) , text , font = monospace , fill = white )
2021-04-26 19:27:34 +00:00
bbox = canvas . getbbox ( )
width = bbox [ 2 ] - bbox [ 0 ]
height = bbox [ 3 ] - bbox [ 1 ]
return width , height
#Draw Ticker, current and change onto one image
def textToImage ( self , TICKER , CURRENT , CHANGE , ARROW ) :
2021-05-01 11:09:21 +00:00
font = ImageFont . load ( " ./fonts/10x20.pil " )
2021-05-24 19:59:42 +00:00
text_width_current , text_height = self . get_text_dimensions ( CURRENT , font )
img = Image . new ( ' RGB ' , ( text_width_current + 100 , 32 ) )
2021-04-26 19:27:34 +00:00
d = ImageDraw . Draw ( img )
2021-04-28 19:39:30 +00:00
d . text ( ( 4 , 0 ) , TICKER , fill = ( 255 , 255 , 255 ) , font = font )
2021-05-03 10:39:31 +00:00
d . text ( ( 4 , 16 ) , CURRENT , fill = self . greenORred , font = font )
2021-04-26 19:27:34 +00:00
2021-05-24 19:59:42 +00:00
2021-04-26 19:27:34 +00:00
img . paste ( ARROW , ( ( text_width_current + 9 ) , 18 ) )
2021-05-03 10:39:31 +00:00
d . text ( ( ( text_width_current + 29 ) , 16 ) , CHANGE , fill = self . greenORred , font = font )
2021-04-26 19:27:34 +00:00
text_width_change , text_height = self . get_text_dimensions ( CHANGE , font )
newWidth = ( text_width_current + 29 ) + ( text_width_change )
img . crop ( ( 0 , 0 , newWidth , 32 ) )
return img
#Stitch the logo & prices picture into one image
2021-05-03 10:39:31 +00:00
def stitchImage ( self , image_list ) :
widths , heights = zip ( * ( i . size for i in image_list ) )
2021-04-26 19:27:34 +00:00
total_width = sum ( widths )
max_height = max ( heights )
new_im = Image . new ( ' RGB ' , ( total_width , max_height ) )
x_offset = 0
2021-05-03 10:39:31 +00:00
for im in image_list :
2021-04-26 19:27:34 +00:00
new_im . paste ( im , ( x_offset , 0 ) )
x_offset + = im . size [ 0 ]
2021-05-14 10:31:14 +00:00
2021-04-26 19:27:34 +00:00
return new_im
2021-05-01 10:39:20 +00:00
def resetMatrix ( self ) :
for x in range ( self . matrix . width ) :
for y in range ( self . matrix . height ) :
self . matrix . SetPixel ( x , y , 0 , 0 , 0 )
2021-04-26 19:27:34 +00:00
#Connect all the pieces togeather creating 1 long final stock image
2021-05-06 18:23:17 +00:00
def getFullStockImage ( self , updated_img ) :
2021-04-26 19:27:34 +00:00
2021-05-03 10:39:31 +00:00
image_list = [ ]
2021-04-28 19:39:30 +00:00
2021-05-03 10:39:31 +00:00
start = time . time ( )
2021-05-05 14:44:43 +00:00
self . readCSV ( )
2021-05-03 10:39:31 +00:00
2021-06-09 18:06:21 +00:00
2021-05-05 14:44:43 +00:00
for i , symbol in enumerate ( self . symbols ) :
info = self . stock_info [ symbol ]
change = float ( info [ 0 ] ) - float ( info [ 1 ] ) #TEXT
ticker = symbol #TEXT
current = ' %.2f ' % float ( info [ 0 ] ) #TEXT
2021-05-05 19:26:56 +00:00
2021-05-05 14:44:43 +00:00
arrow , change = self . getArrow ( change )
change = ' %.2f ' % change
midFrame = self . textToImage ( ticker , current , change , arrow ) #IMAGE THE TEXT
2021-05-05 19:26:56 +00:00
try :
logos_path = os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' logos ' )
2021-05-14 12:06:19 +00:00
2021-05-05 19:26:56 +00:00
logo = Image . open ( os . path . join ( logos_path , ticker + ' .png ' ) )
stitchedStock = self . stitchImage ( [ logo , midFrame ] )
except :
2021-05-14 12:06:19 +00:00
2021-05-05 19:26:56 +00:00
stitchedStock = midFrame
2021-05-14 12:02:22 +00:00
image_list . append ( self . blank )
image_list . append ( stitchedStock )
for i , coin in enumerate ( self . coins ) :
info = self . coin_info [ coin ]
2021-06-15 18:35:04 +00:00
2021-05-25 18:57:34 +00:00
change = float ( info [ 3 ] ) #TEXT
2021-05-24 19:59:42 +00:00
ticker = info [ 0 ] #TEXT
2021-05-25 18:57:34 +00:00
current = float ( info [ 2 ] ) #TEXT
base = info [ 1 ] . upper ( )
2021-05-14 12:02:22 +00:00
2021-05-25 18:57:34 +00:00
if self . points :
# convert percent to points
change = change / 100 * current
current = ' %.2f ' % current
2021-05-14 12:02:22 +00:00
arrow , change = self . getArrow ( change )
change = ' %.2f ' % change
2021-05-25 18:57:34 +00:00
midFrame = self . textToImage ( ticker + ' ( ' + base + ' ) ' , current , change , arrow ) #IMAGE THE TEXT
2021-05-14 12:02:22 +00:00
try :
2021-05-24 19:59:42 +00:00
logos_path = os . path . join ( os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' logos ' ) , ' crypto ' )
2021-05-14 12:06:19 +00:00
2021-05-14 12:02:22 +00:00
logo = Image . open ( os . path . join ( logos_path , ticker + ' .png ' ) )
stitchedStock = self . stitchImage ( [ logo , midFrame ] )
except :
2021-05-14 12:06:19 +00:00
2021-05-14 12:02:22 +00:00
stitchedStock = midFrame
2021-05-05 14:44:43 +00:00
image_list . append ( self . blank )
image_list . append ( stitchedStock )
2021-06-09 18:06:21 +00:00
base , currency_info = json . load ( open ( ' csv/currency.json ' , ' r ' ) )
for i , currency in enumerate ( [ ' AUD ' , ' CAD ' , ' CHF ' , ' EUR ' , ' GBP ' , ' JPY ' , ' NZD ' ] ) :
current , yesterday = currency_info [ currency ]
2021-06-15 18:35:04 +00:00
2021-06-09 18:06:21 +00:00
change = 1 / current - 1 / yesterday
2021-06-15 18:35:04 +00:00
2021-06-09 18:06:21 +00:00
current = 1 / current
2021-06-09 18:13:48 +00:00
current = ' %.3f ' % current
2021-06-09 18:06:21 +00:00
arrow , change = self . getArrow ( change )
2021-06-09 18:13:48 +00:00
change = ' %.6f ' % change
2021-06-09 18:06:21 +00:00
midFrame = self . textToImage ( currency + ' ( ' + base + ' ) ' , current , change , arrow ) #IMAGE THE TEXT
try :
logos_path = os . path . join ( os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' logos ' ) , ' currencies ' )
logo = Image . open ( os . path . join ( logos_path , currency . lower ( ) + ' .png ' ) )
bse = Image . open ( os . path . join ( logos_path , base . lower ( ) + ' .png ' ) )
2021-06-10 18:55:23 +00:00
new_im = Image . new ( ' RGB ' , ( 32 , 32 ) )
2021-06-09 18:06:21 +00:00
for im in image_list :
new_im . paste ( bse , ( 0 , 10 ) , bse . convert ( ' RGBA ' ) )
new_im . paste ( logo , ( 10 , 0 ) , logo . convert ( ' RGBA ' ) )
stitchedStock = self . stitchImage ( [ new_im , midFrame ] )
except :
2021-05-03 10:39:31 +00:00
2021-06-09 18:06:21 +00:00
stitchedStock = midFrame
image_list . append ( self . blank )
image_list . append ( stitchedStock )
2021-05-05 14:44:43 +00:00
finalDisplayImage = self . stitchImage ( image_list )
2021-05-06 18:23:17 +00:00
if updated_img == 1 :
finalDisplayImage . save ( ' final.ppm ' )
elif updated_img == 2 :
finalDisplayImage . save ( ' final1.ppm ' )
2021-05-05 14:44:43 +00:00
2021-06-15 18:35:04 +00:00
def getLeagueImage ( self ) :
img = Image . new ( ' RGB ' , ( 10000 , 32 ) )
league_info = json . load ( open ( ' /home/pi/Desktop/stock_ticker/csv/sports/premier_league/past_games.json ' , ' r ' ) )
print ( league_info [ 0 ] . keys ( ) )
small_font = ImageFont . load ( " ./fonts/5x7.pil " )
large_font = ImageFont . load ( " ./fonts/10x20.pil " )
buff_size = 20
x_offset = 0
print ( len ( league_info ) )
for match in league_info [ - 15 : ] :
home_team = match [ ' home_team ' ]
away_team = match [ ' away_team ' ]
home_score = match [ ' home_score ' ]
away_score = match [ ' away_score ' ]
date = match [ ' date ' ]
rond = match [ ' round ' ]
try :
home_logo = Image . open ( ' /home/pi/Desktop/stock_ticker/logos/sports/premier_league/ ' + home_team + ' .png ' )
except :
home_logo = self . textImage ( home_team . replace ( ' ' , ' \n ' ) , small_font , r = 255 , g = 255 , b = 255 )
print ( home_team )
try :
away_logo = Image . open ( ' /home/pi/Desktop/stock_ticker/logos/sports/premier_league/ ' + away_team + ' .png ' )
except :
away_logo = self . textImage ( away_team . replace ( ' ' , ' \n ' ) , small_font , r = 255 , g = 255 , b = 255 )
home_timage = self . textImage ( home_team , small_font , r = 255 , g = 255 , b = 255 )
away_timage = self . textImage ( away_team , small_font , r = 255 , g = 255 , b = 255 )
date_timage = self . textImage ( date , small_font , r = 255 , g = 255 , b = 0 )
round_timage = self . textImage ( ' round: ' + rond , small_font , r = 255 , g = 255 , b = 255 )
score_image = self . textImage ( home_score + ' - ' + away_score , large_font , r = 255 , g = 255 , b = 255 )
img . paste ( home_logo , ( x_offset , 0 ) )
x_offset + = home_logo . size [ 0 ] + 2
#img.paste(home_timage, (x_offset, 0))
#img.paste(away_timage, (x_offset, 5))
img . paste ( date_timage , ( x_offset , 0 ) )
img . paste ( round_timage , ( x_offset + 7 , 8 ) )
img . paste ( score_image , ( x_offset + 10 , 15 ) )
#x_offset += max(home_timage.size[0], away_timage.size[0], date_timage.size[0], round_timage.size[0], score_image.size[0])
x_offset + = max ( date_timage . size [ 0 ] , round_timage . size [ 0 ] , score_image . size [ 0 ] )
img . paste ( away_logo , ( x_offset , 0 ) )
x_offset + = away_logo . size [ 0 ] + 2
x_offset + = buff_size
img = img . crop ( ( 0 , 0 , x_offset , 32 ) )
return img
def getTeamsImage ( self ) :
img = Image . new ( ' RGB ' , ( 10000 , 32 ) )
team_info = json . load ( open ( ' /home/pi/Desktop/stock_ticker/csv/sports/premier_league/team_stats.json ' , ' r ' ) )
small_font = ImageFont . load ( " ./fonts/5x7.pil " )
med_font = ImageFont . load ( " ./fonts/7x14.pil " )
large_font = ImageFont . load ( " ./fonts/10x20.pil " )
buff_size = 20
x_offset = 0
for team in team_info :
try :
logo = Image . open ( ' /home/pi/Desktop/stock_ticker/logos/sports/premier_league/ ' + team [ ' name ' ] + ' .png ' )
img . paste ( logo , ( x_offset , 0 ) )
x_offset + = logo . size [ 0 ] + 2
except :
print ( ' no logo for: ' , team [ ' name ' ] )
name_timage = self . textImage ( team [ ' name ' ] , med_font , r = 255 , g = 255 , b = 0 )
wins_timage = self . textImage ( ' Wins: ' + team [ ' wins ' ] , small_font , r = 0 , g = 255 , b = 0 )
loss_timage = self . textImage ( ' Losses: ' + team [ ' loss ' ] , small_font , r = 255 , g = 0 , b = 0 )
draw_timage = self . textImage ( ' Draws: ' + team [ ' draw ' ] , small_font , r = 0 , g = 0 , b = 255 )
points_timage = self . textImage ( ' Points: ' + team [ ' points ' ] , small_font , r = 255 , g = 255 , b = 255 )
standing_timage = self . textImage ( ' Standing: ' + team [ ' standing ' ] , small_font , r = 255 , g = 255 , b = 255 )
img . paste ( name_timage , ( x_offset , - 2 ) )
img . paste ( wins_timage , ( x_offset , 11 ) )
img . paste ( loss_timage , ( x_offset , 18 ) )
img . paste ( draw_timage , ( x_offset , 25 ) )
x_offset + = max ( wins_timage . size [ 0 ] , loss_timage . size [ 0 ] , draw_timage . size [ 0 ] )
img . paste ( points_timage , ( x_offset , 14 ) )
img . paste ( standing_timage , ( x_offset , 22 ) )
x_offset + = max ( points_timage . size [ 0 ] , standing_timage . size [ 0 ] ) + buff_size
img = img . crop ( ( 0 , 0 , x_offset , 32 ) )
return img
2021-06-07 20:03:03 +00:00
def getTodayWeatherImage ( self ) :
2021-06-14 18:17:07 +00:00
img = Image . new ( ' RGB ' , ( 200 , 32 ) )
2021-06-03 20:56:25 +00:00
2021-06-09 18:06:21 +00:00
f = open ( " csv/weather_location.txt " , ' r ' )
location = f . read ( )
f . close ( )
2021-06-15 18:35:04 +00:00
2021-06-03 20:56:25 +00:00
current_weather = json . load ( open ( ' csv/current_weather.json ' , ' r ' ) )
2021-06-07 20:03:03 +00:00
small_font = ImageFont . load ( " ./fonts/5x7.pil " )
large_font = ImageFont . load ( " ./fonts/10x20.pil " )
2021-06-03 20:56:25 +00:00
2021-06-08 20:16:08 +00:00
location_img = self . textImage ( location , small_font , r = 255 , g = 255 , b = 0 )
2021-06-03 20:56:25 +00:00
2021-06-07 20:03:03 +00:00
img . paste ( location_img , ( 5 , 0 ) )
2021-06-03 20:56:25 +00:00
main = current_weather [ ' main_weather ' ]
if main == ' Clouds ' :
main = current_weather [ ' description ' ]
weather_ids = { ' Clear ' : ' 01 ' , ' few clouds ' : ' 02 ' , ' scattered clouds ' : ' 03 ' , ' broken clouds ' : ' 04 ' , ' overcast clouds ' : ' 04 ' , ' Drizzle ' : ' 09 ' ,
' Rain ' : ' 10 ' , ' Thunderstorm ' : ' 11 ' , ' Snow ' : ' 13 ' , ' Mist ' : ' 50 ' , ' Smoke ' : ' 50 ' , ' Haze ' : ' 50 ' , ' Dust ' : ' 50 ' , ' Fog ' : ' 50 ' ,
' Sand ' : ' 50 ' , ' Ash ' : ' 50 ' , ' Squall ' : ' 50 ' , ' Tornado ' : ' 50 ' }
weather_dir = ' ./logos/weather_icons '
2021-06-07 20:03:03 +00:00
2021-06-03 20:56:25 +00:00
weather_img = Image . open ( weather_dir + ' /weather_type_icons/ ' + weather_ids [ main ] + ' .png ' )
2021-06-09 18:06:21 +00:00
img . paste ( weather_img , ( 5 , 9 ) )
2021-06-03 20:56:25 +00:00
2021-06-10 18:55:23 +00:00
temp_img = self . textImage ( str ( " {0:.0f} " . format ( current_weather [ ' temp ' ] ) ) , large_font )
2021-06-14 18:17:07 +00:00
img . paste ( temp_img , ( 36 , 9 ) )
2021-06-03 20:56:25 +00:00
2021-06-10 18:55:23 +00:00
deg_img = self . textImage ( ' o ' , small_font )
2021-06-15 18:35:04 +00:00
2021-06-14 18:17:07 +00:00
img . paste ( deg_img , ( 56 , 8 ) )
2021-06-03 20:56:25 +00:00
main = current_weather [ ' main_weather ' ]
main_img = self . textImage ( main , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( main_img , ( 34 , 26 ) )
2021-06-03 20:56:25 +00:00
2021-06-10 18:55:23 +00:00
feels_img = self . textImage ( ' Feels like: ' + str ( " {0:.0f} " . format ( current_weather [ ' feels_like ' ] ) ) , small_font )
img . paste ( feels_img , ( location_img . size [ 0 ] + 10 , 0 ) )
2021-06-03 20:56:25 +00:00
2021-06-07 20:03:03 +00:00
min_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' min_temp ' ] ) , small_font , r = 0 , g = 0 , b = 255 )
2021-06-14 18:17:07 +00:00
img . paste ( min_img , ( 66 , 12 ) )
2021-06-03 20:56:25 +00:00
2021-06-07 20:03:03 +00:00
max_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' max_temp ' ] ) , small_font , r = 255 , g = 0 , b = 0 )
2021-06-14 18:19:52 +00:00
img . paste ( max_img , ( 66 , 21 ) )
2021-06-03 20:56:25 +00:00
hum_img = Image . open ( weather_dir + ' /humidity.png ' )
2021-06-14 18:17:07 +00:00
img . paste ( hum_img , ( 82 , 8 ) )
2021-06-03 20:56:25 +00:00
htext_img = self . textImage ( str ( current_weather [ ' humidity ' ] ) + ' % ' , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( htext_img , ( 95 , 10 ) )
2021-06-03 20:56:25 +00:00
uv_img = Image . open ( weather_dir + ' /uv.png ' )
2021-06-14 18:17:07 +00:00
img . paste ( uv_img , ( 82 , 22 ) )
2021-06-03 20:56:25 +00:00
utext_img = self . textImage ( str ( current_weather [ ' uv ' ] ) , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( utext_img , ( 95 , 23 ) )
2021-06-03 20:56:25 +00:00
weekdays = [ ' Mon ' , ' Tue ' , ' Wed ' , ' Thu ' , ' Fri ' , ' Sat ' , ' Sun ' ]
months = [ ' Jan ' , ' Feb ' , ' Mar ' , ' Apr ' , ' May ' , ' Jun ' , ' Jul ' , ' Aug ' , ' Sep ' , ' Oct ' , ' Nov ' , ' Dec ' ]
month = months [ int ( datetime . now ( ) . strftime ( ' % m ' ) ) ]
date = str ( int ( datetime . now ( ) . strftime ( ' %d ' ) ) )
weekday = weekdays [ datetime . today ( ) . weekday ( ) ]
2021-06-07 20:03:03 +00:00
2021-06-03 20:56:25 +00:00
2021-06-08 20:16:08 +00:00
date_img = self . textImage ( month + ' ' + date + ' , ' + weekday , small_font )
2021-06-07 20:03:03 +00:00
img . paste ( date_img , ( 132 , 0 ) )
2021-06-03 20:56:25 +00:00
rain_img = Image . open ( weather_dir + ' /rain-chance.png ' )
2021-06-14 18:17:07 +00:00
img . paste ( rain_img , ( 118 , 8 ) )
2021-06-07 20:03:03 +00:00
2021-06-03 20:56:25 +00:00
2021-06-10 18:55:23 +00:00
rtext_img = self . textImage ( str ( int ( current_weather [ ' rain_chance ' ] * 100 ) ) + ' % ' , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( rtext_img , ( 131 , 10 ) )
2021-06-03 20:56:25 +00:00
cloud_img = Image . open ( weather_dir + ' /clouds.png ' )
2021-06-14 18:17:07 +00:00
img . paste ( cloud_img , ( 118 , 20 ) )
2021-06-03 20:56:25 +00:00
ctext_img = self . textImage ( str ( current_weather [ ' clouds ' ] ) + ' % ' , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( ctext_img , ( 131 , 22 ) )
2021-06-03 20:56:25 +00:00
wind_img = Image . open ( weather_dir + ' /wind.png ' )
2021-06-14 18:17:07 +00:00
img . paste ( wind_img , ( 154 , 8 ) )
2021-06-08 20:16:08 +00:00
wtext_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' wind_speed ' ] ) + ' m/s ' , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( wtext_img , ( 168 , 10 ) )
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
wdir_img = self . textImage ( self . degreesToCompass ( current_weather [ ' wind_direction ' ] ) , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( wdir_img , ( 183 , 10 ) )
2021-06-03 20:56:25 +00:00
vis_img = Image . open ( weather_dir + ' /visibility.png ' )
2021-06-14 18:17:07 +00:00
img . paste ( vis_img , ( 154 , 20 ) )
2021-06-07 20:03:03 +00:00
vtext_img = self . textImage ( str ( current_weather [ ' visibility ' ] / 1000 ) + ' km ' , small_font )
2021-06-14 18:17:07 +00:00
img . paste ( vtext_img , ( 168 , 22 ) )
2021-06-08 20:16:08 +00:00
2021-06-07 20:03:03 +00:00
return img
2021-06-03 20:56:25 +00:00
2021-06-10 18:55:23 +00:00
def getDailyWeatherImageAlt ( self ) :
2021-06-07 20:03:03 +00:00
2021-06-09 18:06:21 +00:00
f = open ( " csv/weather_location.txt " , ' r ' )
location = f . read ( )
f . close ( )
2021-06-08 20:16:08 +00:00
img = Image . new ( ' RGB ' , ( 128 , 32 ) )
current_weather = json . load ( open ( ' csv/current_weather.json ' , ' r ' ) )
2021-06-07 20:03:03 +00:00
small_font = ImageFont . load ( " ./fonts/5x7.pil " )
2021-06-08 20:16:08 +00:00
extra_small_font = ImageFont . load ( " ./fonts/4x6.pil " )
2021-06-07 20:03:03 +00:00
large_font = ImageFont . load ( " ./fonts/10x20.pil " )
2021-06-09 18:06:21 +00:00
location_img = self . textImage ( location , extra_small_font , r = 255 , g = 255 , b = 0 )
2021-06-08 20:16:08 +00:00
main = current_weather [ ' main_weather ' ]
if main == ' Clouds ' :
main = current_weather [ ' description ' ]
weather_ids = { ' Clear ' : ' 01 ' , ' few clouds ' : ' 02 ' , ' scattered clouds ' : ' 03 ' , ' broken clouds ' : ' 04 ' , ' overcast clouds ' : ' 04 ' , ' Drizzle ' : ' 09 ' ,
' Rain ' : ' 10 ' , ' Thunderstorm ' : ' 11 ' , ' Snow ' : ' 13 ' , ' Mist ' : ' 50 ' , ' Smoke ' : ' 50 ' , ' Haze ' : ' 50 ' , ' Dust ' : ' 50 ' , ' Fog ' : ' 50 ' ,
' Sand ' : ' 50 ' , ' Ash ' : ' 50 ' , ' Squall ' : ' 50 ' , ' Tornado ' : ' 50 ' }
weather_dir = ' ./logos/weather_icons '
weather_img = Image . open ( weather_dir + ' /weather_type_icons/ ' + weather_ids [ main ] + ' .png ' )
temp_img = self . textImage ( str ( " {0:.0f} " . format ( current_weather [ ' temp ' ] ) ) , large_font )
deg_img = self . textImage ( ' o ' , small_font )
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
min_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' min_temp ' ] ) , small_font , r = 0 , g = 0 , b = 255 )
max_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' max_temp ' ] ) , small_font , r = 255 , g = 0 , b = 0 )
main = current_weather [ ' main_weather ' ]
main_img = self . textImage ( main , small_font )
2021-06-07 20:03:03 +00:00
weekdays = [ ' Mon ' , ' Tue ' , ' Wed ' , ' Thu ' , ' Fri ' , ' Sat ' , ' Sun ' ]
months = [ ' Jan ' , ' Feb ' , ' Mar ' , ' Apr ' , ' May ' , ' Jun ' , ' Jul ' , ' Aug ' , ' Sep ' , ' Oct ' , ' Nov ' , ' Dec ' ]
month = months [ int ( datetime . now ( ) . strftime ( ' % m ' ) ) ]
date = str ( int ( datetime . now ( ) . strftime ( ' %d ' ) ) )
weekday = weekdays [ datetime . today ( ) . weekday ( ) ]
2021-06-08 20:16:08 +00:00
date_img = self . textImage ( month + ' ' + date + ' , ' + weekday , extra_small_font )
rain_img = Image . open ( weather_dir + ' /rain-chance.png ' )
2021-06-07 20:03:03 +00:00
2021-06-09 18:39:04 +00:00
rtext_img = self . textImage ( str ( int ( current_weather [ ' rain_chance ' ] * 100 ) ) + ' % ' , extra_small_font )
2021-05-14 12:06:19 +00:00
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
hum_img = Image . open ( weather_dir + ' /humidity.png ' )
htext_img = self . textImage ( str ( current_weather [ ' humidity ' ] ) + ' % ' , extra_small_font )
uv_img = Image . open ( weather_dir + ' /uv.png ' )
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
utext_img = self . textImage ( str ( current_weather [ ' uv ' ] ) , extra_small_font )
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
wind_img = Image . open ( weather_dir + ' /wind.png ' )
wtext_img = self . textImage ( str ( current_weather [ ' wind_speed ' ] ) + ' m/s ' , extra_small_font )
2021-06-15 18:35:04 +00:00
2021-06-08 20:16:08 +00:00
img . paste ( location_img , ( 0 , 0 ) )
img . paste ( weather_img , ( 0 , 12 ) )
img . paste ( temp_img , ( 30 , 9 ) )
img . paste ( deg_img , ( 50 , 8 ) )
2021-06-08 20:30:48 +00:00
img . paste ( min_img , ( 55 , 10 ) )
2021-06-08 20:16:08 +00:00
img . paste ( main_img , ( 30 , 26 ) )
2021-06-14 18:19:52 +00:00
img . paste ( max_img , ( 55 , 19 ) )
2021-06-08 20:16:08 +00:00
img . paste ( date_img , ( location_img . size [ 0 ] , 1 ) )
img . paste ( rain_img , ( 75 , 0 ) )
img . paste ( rtext_img , ( 88 , 1 ) )
img . paste ( hum_img , ( 102 , 0 ) )
img . paste ( htext_img , ( 113 , 1 ) )
#img.paste(uv_img, ( 96, 0))
#img.paste(utext_img, (109, 0))
#img.paste(wind_img, (96,0))
#img.paste(wtext_img, (109,0))
img0 = img
img = Image . new ( ' RGB ' , ( 1000 , 32 ) )
daily_weather = json . load ( open ( ' csv/daily_weather.json ' , ' r ' ) )
#img.paste(date_img, (70, 0))
x_offset = 64
for i in range ( 0 , len ( daily_weather ) - 1 ) :
weekday = weekdays [ ( datetime . today ( ) . weekday ( ) + i ) % 7 ]
day_img = self . textImage ( weekday , small_font )
2021-06-07 20:03:03 +00:00
weather = daily_weather [ i ]
main = weather [ ' main_weather ' ]
if main == ' Clouds ' :
main = weather [ ' description ' ]
2021-06-08 20:16:08 +00:00
weather_img = Image . open ( weather_dir + ' /small_icons/ ' + weather_ids [ main ] + ' .png ' )
2021-06-07 20:03:03 +00:00
min_img = self . textImage ( " {0:.0f} " . format ( weather [ ' min_temp ' ] ) , small_font , r = 0 , g = 0 , b = 255 )
max_img = self . textImage ( " {0:.0f} " . format ( weather [ ' max_temp ' ] ) , small_font , r = 255 , g = 0 , b = 0 )
2021-06-08 20:16:08 +00:00
img . paste ( day_img , ( x_offset + 5 , 9 ) )
img . paste ( weather_img , ( x_offset + 5 , 16 ) )
img . paste ( min_img , ( x_offset + 25 , 10 ) )
2021-06-14 18:19:52 +00:00
img . paste ( max_img , ( x_offset + 25 , 20 ) )
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
x_offset + = 35
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
img1 = img . crop ( ( 64 , 0 , x_offset , 32 ) )
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
img1 . save ( ' weather.ppm ' )
return img0 , img1
2021-06-07 20:03:03 +00:00
2021-06-10 18:55:23 +00:00
def getDailyWeatherImage ( self ) :
f = open ( " csv/weather_location.txt " , ' r ' )
location = f . read ( )
f . close ( )
img = Image . new ( ' RGB ' , ( 1000 , 32 ) )
current_weather = json . load ( open ( ' csv/current_weather.json ' , ' r ' ) )
small_font = ImageFont . load ( " ./fonts/5x7.pil " )
extra_small_font = ImageFont . load ( " ./fonts/4x6.pil " )
large_font = ImageFont . load ( " ./fonts/10x20.pil " )
location_img = self . textImage ( location , extra_small_font , r = 255 , g = 255 , b = 0 )
main = current_weather [ ' main_weather ' ]
if main == ' Clouds ' :
main = current_weather [ ' description ' ]
weather_ids = { ' Clear ' : ' 01 ' , ' few clouds ' : ' 02 ' , ' scattered clouds ' : ' 03 ' , ' broken clouds ' : ' 04 ' , ' overcast clouds ' : ' 04 ' , ' Drizzle ' : ' 09 ' ,
' Rain ' : ' 10 ' , ' Thunderstorm ' : ' 11 ' , ' Snow ' : ' 13 ' , ' Mist ' : ' 50 ' , ' Smoke ' : ' 50 ' , ' Haze ' : ' 50 ' , ' Dust ' : ' 50 ' , ' Fog ' : ' 50 ' ,
' Sand ' : ' 50 ' , ' Ash ' : ' 50 ' , ' Squall ' : ' 50 ' , ' Tornado ' : ' 50 ' }
weather_dir = ' ./logos/weather_icons '
weather_img = Image . open ( weather_dir + ' /weather_type_icons/ ' + weather_ids [ main ] + ' .png ' )
temp_img = self . textImage ( str ( " {0:.0f} " . format ( current_weather [ ' temp ' ] ) ) , large_font )
deg_img = self . textImage ( ' o ' , small_font )
min_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' min_temp ' ] ) , small_font , r = 0 , g = 0 , b = 255 )
max_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' max_temp ' ] ) , small_font , r = 255 , g = 0 , b = 0 )
main = current_weather [ ' main_weather ' ]
main_img = self . textImage ( main , small_font )
weekdays = [ ' Mon ' , ' Tue ' , ' Wed ' , ' Thu ' , ' Fri ' , ' Sat ' , ' Sun ' ]
months = [ ' Jan ' , ' Feb ' , ' Mar ' , ' Apr ' , ' May ' , ' Jun ' , ' Jul ' , ' Aug ' , ' Sep ' , ' Oct ' , ' Nov ' , ' Dec ' ]
month = months [ int ( datetime . now ( ) . strftime ( ' % m ' ) ) ]
date = str ( int ( datetime . now ( ) . strftime ( ' %d ' ) ) )
weekday = weekdays [ datetime . today ( ) . weekday ( ) ]
date_img = self . textImage ( month + ' ' + date + ' , ' + weekday , extra_small_font )
rain_img = Image . open ( weather_dir + ' /rain-chance.png ' )
rtext_img = self . textImage ( str ( int ( current_weather [ ' rain_chance ' ] * 100 ) ) + ' % ' , extra_small_font )
hum_img = Image . open ( weather_dir + ' /humidity.png ' )
htext_img = self . textImage ( str ( current_weather [ ' humidity ' ] ) + ' % ' , extra_small_font )
uv_img = Image . open ( weather_dir + ' /uv.png ' )
utext_img = self . textImage ( str ( current_weather [ ' uv ' ] ) , extra_small_font )
wind_img = Image . open ( weather_dir + ' /wind.png ' )
wtext_img = self . textImage ( str ( current_weather [ ' wind_speed ' ] ) + ' m/s ' , extra_small_font )
uv_img = Image . open ( weather_dir + ' /uv.png ' )
utext_img = self . textImage ( str ( current_weather [ ' uv ' ] ) , small_font )
cloud_img = Image . open ( weather_dir + ' /clouds.png ' )
ctext_img = self . textImage ( str ( current_weather [ ' clouds ' ] ) + ' % ' , small_font )
wind_img = Image . open ( weather_dir + ' /wind.png ' )
wtext_img = self . textImage ( " {0:.0f} " . format ( current_weather [ ' wind_speed ' ] ) + ' m/s ' , small_font )
wdir_img = self . textImage ( self . degreesToCompass ( current_weather [ ' wind_direction ' ] ) , small_font )
vis_img = Image . open ( weather_dir + ' /visibility.png ' )
vtext_img = self . textImage ( str ( current_weather [ ' visibility ' ] / 1000 ) + ' km ' , small_font )
img . paste ( location_img , ( 0 , 0 ) )
img . paste ( weather_img , ( 0 , 12 ) )
img . paste ( temp_img , ( 30 , 9 ) )
img . paste ( deg_img , ( 50 , 8 ) )
img . paste ( min_img , ( 55 , 10 ) )
img . paste ( main_img , ( 30 , 26 ) )
2021-06-14 18:19:52 +00:00
img . paste ( max_img , ( 55 , 19 ) )
2021-06-10 18:55:23 +00:00
img . paste ( date_img , ( location_img . size [ 0 ] , 1 ) )
img . paste ( rain_img , ( 90 , 0 ) )
img . paste ( rtext_img , ( 103 , 1 ) )
img . paste ( hum_img , ( 117 , 0 ) )
img . paste ( htext_img , ( 128 , 1 ) )
img . paste ( uv_img , ( 143 , 0 ) )
img . paste ( utext_img , ( 156 , 1 ) )
img . paste ( cloud_img , ( 169 , 0 ) )
img . paste ( ctext_img , ( 182 , 1 ) )
img . paste ( wind_img , ( 205 , 0 ) )
img . paste ( wtext_img , ( 218 , 1 ) )
img . paste ( wdir_img , ( 231 , 1 ) )
img . paste ( vis_img , ( 243 , 0 ) )
img . paste ( vtext_img , ( 256 , 1 ) )
#img.paste(uv_img, ( 96, 0))
#img.paste(utext_img, (109, 0))
#img.paste(wind_img, (96,0))
#img.paste(wtext_img, (109,0))
daily_weather = json . load ( open ( ' csv/daily_weather.json ' , ' r ' ) )
#img.paste(date_img, (70, 0))
x_offset = 70
for i in range ( 1 , len ( daily_weather ) - 1 ) :
weekday = weekdays [ ( datetime . today ( ) . weekday ( ) + i ) % 7 ]
day_img = self . textImage ( weekday , small_font )
weather = daily_weather [ i ]
main = weather [ ' main_weather ' ]
if main == ' Clouds ' :
main = weather [ ' description ' ]
weather_img = Image . open ( weather_dir + ' /small_icons/ ' + weather_ids [ main ] + ' .png ' )
min_img = self . textImage ( " {0:.0f} " . format ( weather [ ' min_temp ' ] ) , small_font , r = 0 , g = 0 , b = 255 )
max_img = self . textImage ( " {0:.0f} " . format ( weather [ ' max_temp ' ] ) , small_font , r = 255 , g = 0 , b = 0 )
img . paste ( day_img , ( x_offset + 5 , 9 ) )
img . paste ( weather_img , ( x_offset + 5 , 16 ) )
img . paste ( min_img , ( x_offset + 25 , 10 ) )
2021-06-14 18:19:52 +00:00
img . paste ( max_img , ( x_offset + 25 , 20 ) )
2021-06-10 18:55:23 +00:00
x_offset + = 40
img1 = img . crop ( ( 0 , 0 , x_offset , 32 ) )
return img1
2021-05-21 13:24:37 +00:00
2021-05-05 14:44:43 +00:00
#Retrieve symbols and stock info from the csv file
def readCSV ( self ) :
2021-04-26 18:51:21 +00:00
2021-04-26 19:27:34 +00:00
self . symbols = [ ]
2021-05-05 14:44:43 +00:00
self . stock_info = { }
f = open ( ' csv/tickers.csv ' , ' r ' )
CSV = csv . reader ( f )
2021-05-06 19:59:27 +00:00
next ( CSV )
2021-04-26 19:27:34 +00:00
for row in CSV :
2021-05-14 12:55:43 +00:00
2021-05-05 14:44:43 +00:00
try :
symbol , current_price , opening_price = row
self . symbols . append ( symbol )
self . stock_info [ symbol ] = [ current_price , opening_price ]
except :
2021-05-25 18:57:34 +00:00
pass # we dont want to include incomplete information
2021-05-05 14:44:43 +00:00
f . close ( )
2021-05-14 12:02:22 +00:00
self . coins = [ ]
self . coin_info = { }
f = open ( ' csv/crypto.csv ' , ' r ' )
CSV = csv . reader ( f )
next ( CSV )
for row in CSV :
2021-05-14 12:55:43 +00:00
2021-05-14 12:02:22 +00:00
try :
2021-05-25 18:57:34 +00:00
symbol , coin , base , current_price , day_change = row
2021-05-14 12:02:22 +00:00
self . coins . append ( coin )
2021-05-25 18:57:34 +00:00
self . coin_info [ coin ] = [ symbol , base , current_price , day_change ]
2021-05-14 12:02:22 +00:00
except :
2021-05-25 18:57:34 +00:00
pass
2021-05-14 12:02:22 +00:00
f . close ( )
2021-05-24 19:59:42 +00:00
2021-05-01 10:39:20 +00:00
2021-06-10 18:55:23 +00:00
def displayDailyWeatherAlt ( self ) :
img0 , img1 = self . getDailyWeatherImageAlt ( )
2021-06-08 20:16:08 +00:00
#img = stock_ticker.getTodayWeatherImage()
while True :
self . setImage ( img0 , offset_x = 0 , offset_y = 0 )
image = img1
img_width , img_height = image . size
offset_x = 64
offset_y = 0
while offset_x > 64 - img_width :
offset_x - = 1
self . setImage ( image , offset_x = offset_x , offset_y = offset_y , min_x = 64 , min_y = 9 )
if offset_x + img_width < self . matrix . width : # if the image is ending
self . setImage ( image , offset_x = offset_x + img_width , offset_y = offset_y , min_x = 64 , min_y = 9 )
try :
msg = getInput ( )
if msg == ' K ' :
self . resetMatrix ( )
return True
self . process_msg ( msg )
except KeyboardInterrupt :
sys . stdout . flush ( )
pass
2021-06-08 20:30:48 +00:00
time . sleep ( self . delay * 1.1 )
2021-06-08 20:16:08 +00:00
2021-06-15 18:35:04 +00:00
def displayStocks ( self ) :
self . scrollImageTransition ( [ ' final.ppm ' , ' final.ppm ' ] , offset_x = 0 , offset_y = 0 )
2021-05-05 15:22:01 +00:00
def process_msg ( self , msg ) :
2021-05-21 10:20:39 +00:00
if msg == ' S ' : # stocks
2021-05-06 18:23:17 +00:00
self . getFullStockImage ( 1 )
2021-05-14 10:31:14 +00:00
self . displayStocks ( )
2021-05-05 15:22:01 +00:00
2021-05-21 13:24:37 +00:00
elif msg == ' N ' : #news
self . displayNews ( )
2021-05-21 10:20:39 +00:00
# speed settings
2021-05-05 15:22:01 +00:00
elif msg == ' s ' :
self . delay = 0.03
elif msg == ' m ' :
self . delay = 0.01
elif msg == ' f ' :
self . delay = 0.005
2021-05-21 10:20:39 +00:00
elif msg in [ ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' ] : # birghtness ettings
2021-05-05 15:22:01 +00:00
self . brightness = min ( 1.0 , float ( msg ) / 10 + 0.1 )
2021-05-21 10:20:39 +00:00
elif msg == ' T ' : # text
2021-05-23 09:34:06 +00:00
self . displayUserText ( )
2021-05-21 10:20:39 +00:00
elif msg == ' I ' : # image
image = self . openImage ( os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' display_image ' ) )
2021-05-31 11:22:56 +00:00
#self.setImage( image)
while True :
kill = self . scrollImage ( image , offset_x = 128 )
if kill :
break
2021-05-21 10:20:39 +00:00
elif msg == ' G ' : # gif
2021-05-31 11:22:56 +00:00
gif = Image . open ( os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , ' display_gif ' ) )
#self.displayGIF(gif)
while True :
kill = self . scrollGIF ( gif , offset_x = 128 )
if kill :
break
2021-06-07 20:03:03 +00:00
elif msg == ' W ' : # weather
img = stock_ticker . getTodayWeatherImage ( )
img . save ( ' weather.ppm ' )
2021-06-08 20:16:08 +00:00
self . scrollImageTransition ( [ ' weather.ppm ' , ' weather.ppm ' ] , stocks = False )
2021-05-21 10:20:39 +00:00
2021-06-07 20:03:03 +00:00
elif msg == ' D ' : # daily weather
2021-06-10 18:55:23 +00:00
#self.displayDailyWeatherAlt()
img = self . getDailyWeatherImage ( )
img . save ( ' weather.ppm ' )
#self.setImage( image)
self . scrollImageTransition ( [ ' weather.ppm ' , ' weather.ppm ' ] , stocks = False )
2021-06-15 18:35:04 +00:00
elif msg == ' L ' : # league
img = self . getLeagueImage ( )
img . save ( ' league.ppm ' )
stock_ticker . scrollImageTransition ( [ ' league.ppm ' , ' league.ppm ' ] , stocks = False )
elif msg == ' t ' : #teams
img = self . getTeamsImage ( )
img . save ( ' teams.ppm ' )
stock_ticker . scrollImageTransition ( [ ' teams.ppm ' , ' teams.ppm ' ] , stocks = False )
2021-05-21 13:24:37 +00:00
2021-05-21 10:20:39 +00:00
elif msg == ' K ' : # kill
self . resetMatrix ( )
2021-05-01 10:39:20 +00:00
if __name__ == ' __main__ ' :
2021-06-15 18:35:04 +00:00
2021-05-31 11:22:56 +00:00
with open ( ' log.txt ' , " w " ) as log :
try :
stock_ticker = StockTicker ( )
2021-06-15 18:35:04 +00:00
#img = stock_ticker.getLeagueImage()
#img.save('league.ppm')
#stock_ticker.scrollImageTransition(['league.ppm', 'league.ppm'], stocks = False)
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
#img0, img1 = stock_ticker.getDailyWeatherImage()
2021-06-07 20:03:03 +00:00
#img = stock_ticker.getTodayWeatherImage()
#img.save('weather.ppm')
2021-06-08 20:16:08 +00:00
#stock_ticker.process_msg('S')
#stock_ticker.process_msg('W')
#stock_ticker.displayDailyWeather()
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
#stock_ticker.delay = 10
#stock_ticker.scrollImageTransition(['weather.ppm', 'weather.ppm'], stocks = False)
2021-06-07 20:03:03 +00:00
2021-06-08 20:16:08 +00:00
2021-06-07 20:03:03 +00:00
2021-05-31 11:22:56 +00:00
#stock_ticker.process_msg('G')
#stock_ticker.scrollImageTransition([os.path.join(os.path.dirname(os.path.abspath(__file__)), 'display_image'), os.path.join(os.path.dirname(os.path.abspath(__file__)), 'display_image')], stocks = False)
#stock_ticker.readCSV()
#stock_ticker.displayUserText()
#
#stock_ticker.displayNews()
#stock_ticker.displayGIF('/home/pi/Desktop/stock_ticker/gifs/open.gif')
#stock_ticker.displayGIF('/home/pi/Desktop/stock_ticker/gifs/close.gif')
#stock_ticker.process_msg(brightness)
#stock_ticker.process_msg(speed)
#stock_ticker.displayText()
2021-06-09 18:13:48 +00:00
#stock_ticker.getFullStockImage(1)
#stock_ticker.process_msg('f')
#stock_ticker.displayStocks()
2021-05-31 11:22:56 +00:00
#stock_ticker.displayStocks()
#stock_ticker.delay = 0.001
#stock_ticker.scrollImageTransition(['final.ppm', 'final.ppm'], offset_x = 0, offset_y = 0)
while True :
msg = getInput ( )
stock_ticker . process_msg ( msg )
except Exception as e :
2021-06-03 20:56:25 +00:00
2021-05-31 11:22:56 +00:00
exc_type , exc_obj , exc_tb = sys . exc_info ( )
fname = os . path . split ( exc_tb . tb_frame . f_code . co_filename ) [ 1 ]
log . write ( str ( e ) )
log . write ( ' . file: ' + fname )
log . write ( ' . line: ' + str ( exc_tb . tb_lineno ) )
log . write ( ' . type: ' + str ( exc_type ) )
2021-06-02 15:37:31 +00:00
log . write ( ' \n ' + " " . join ( traceback . format_exception ( sys . exc_info ( ) [ 0 ] , sys . exc_info ( ) [ 1 ] , sys . exc_info ( ) [ 2 ] ) ) )
2021-06-03 20:56:25 +00:00
raise ( e )
2021-05-01 10:39:20 +00:00