import epaper import microbmp import time import random import os import storage import gc gc.enable() epd_resolution = [600, 448] epd_colormap = [ [0x00, 0x00, 0x00], # black [0xff, 0xff, 0xff], # white [0x00, 0x90, 0x10], # green [0x00, 0x00, 0xee], # blue [0xff, 0x00, 0x00], # red [0xff, 0xdd, 0x00], # yellow [0xff, 0x77, 0x00], # orange ] max_free_height = 200 def init_display(): #print("ePaper init ", str(time.localtime())) epd = epaper.EPD_5in65() epd.fill(epd.White) return epd def draw_image(filename): global epd global epd_colormap global free_x, free_y, free_width, free_height offset_x = 0 offset_y = 0 free_x = 0 free_y = 0 free_width = 0 free_height = 0 color_map = {} def header_callback(header): #print("header callback: ", str(header)) global epd_resolution global offset_x, offset_y global free_x, free_y, free_width, free_height global max_free_height w = header[0] h = header[1] rest_x = (epd_resolution[0] - w) rest_y = (epd_resolution[1] - h) free_x = 0 free_y = max(h, epd_resolution[1] - max_free_height) free_width = epd_resolution[0] free_height = min(rest_y, max_free_height) offset_x = rest_x//2 offset_y = max(0, rest_y - max_free_height)//2 def pixel_callback(x, y, color): global epd global epd_colormap global offset_x, offset_y # translate color to color index color_index = 0 color_key = color[0] + color[1] << 8 + color[2] << 16 if color_key in color_map: color_index = color_map[color_key] else: # search for the best color best_index = 0 best_score = 1000 for index in range(len(epd_colormap)): c1 = epd_colormap[index] c2 = color score = abs(c1[0] - c2[0]) + abs(c1[1] - c2[1]) + abs(c1[2] - c2[2]) if score < best_score: best_score = score best_index = index if score < 10: break color_index = best_index color_map[color_key] = color_index epd.pixel(offset_x + x, offset_y + y, color_index) def pixel_row_callback(x, y, colors): pass #global epd #print("PXL ", str([color, r,g,b, pixel])) #for i in range(len(colors)): # epd.pixel(offset_x + x + i, offset_y + y, color_to_index(colors[i])) #print(str(time.localtime()), " BMP ", filename, " loading") time_start = time.ticks_ms() epd.fill(epd.White) microbmp.MicroBMP(header_callback=header_callback, data_callback=pixel_callback).load(filename) time_loaded = time.ticks_ms() print(" time to load: ", (time_loaded - time_start) / 1000, " s") #print(str(time.localtime()), " BMP loaded") #epd.EPD_5IN65F_Display(epd.buffer) #print(str(time.localtime()), " ePaper printed") return [free_x, free_y, free_width, free_height] def draw_pattern(): global epd global epd_resolution free_x = 0 free_y = 400 free_width = epd_resolution[0] free_height = epd_resolution[1] - free_y epd.fill_rect(0, 0, epd_resolution[0], free_y, random.randrange(2,7)) return [free_x, free_y, free_width, free_height] def load_joke(root): filename = root + "/jokes.json" num_lines = sum(1 for line in open(filename)) with open(filename, mode="r") as f: joke = None start_pattern = "\"joke\": \"" end_pattern = "\"" for i in range(random.randrange(num_lines)): line = f.readline() for i in range(10): line = f.readline() joke_start = line.find(start_pattern) joke_end = line.rfind(end_pattern) if joke_start >= 0 and joke_end >= 0: joke = line[joke_start+len(start_pattern):joke_end] return joke return None def print_text(text, region, center=False): global epd fnt = 8 x = region[0] y = region[1] w = region[2] h = region[3] if center: x = (w - len(text)*fnt) // 2 epd.text(text, x, y, epd.Black) def draw_extra(region, caption): fnt = 8 region[0] += 5 region[1] += 8 if region[2] < fnt or region[3] < fnt: print("Not enough space for extra: ", str(region)) return #epd.rect(region[0], region[1], region[2], region[3], epd.Black) #region[0] += random.randrange(50) #print_text(str(time.localtime()), region, center=True) if caption is not None: #region[1] += fnt * 2 print_text(caption, region) print("Caption: ", caption) else: print("No caption") # MAIN epd = init_display() disk = storage.Storage() while True: disk.mount() images = list(filter(lambda x : x.endswith(".bmp"), os.listdir(disk.get_root_path()))) epd.EPD_5IN65F_Init() epd.fill(epd.White) filename = random.choice(images) print("TV drawing image ", filename) free_space = [0,0,0,0] try: free_space = draw_image(disk.get_root_path() + "/" + filename) except Exception as e: print("Failed drawing image from disk: ", e) try: free_space = draw_image("tiny.bmp") except Exception as e: print("Failed drawing fallback image: ", e) free_space = draw_pattern() caption = None try: caption = load_joke(disk.get_root_path()) except Exception as e: print("Failed loading a joke: ", e) try: draw_extra(free_space, caption) except Exception as e: print("Failed drawing extra: ", e) time_render_start = time.ticks_ms() epd.EPD_5IN65F_Display(epd.buffer) time_render_stop = time.ticks_ms() print(" time to render: ", (time_render_stop - time_render_start) / 1000, " s") print("TV showing ", filename) epd.Sleep() disk.umount() print("") gc.collect() epd.delay_ms(60000 * 1)