From 4ee2f78e48cb96446fc84b031cc7a87398161e6d Mon Sep 17 00:00:00 2001 From: Remy Moll Date: Thu, 15 Oct 2020 11:27:54 +0200 Subject: [PATCH] Now with weather showing capabilities --- bot/main.py | 12 ------ clock.py | 9 +++-- clock/api/clouds.pbm | 11 ------ clock/api/converter.py | 41 +++++++++----------- clock/api/hat/sim.py | 1 + clock/api/{led_out.py => led.py} | 64 ++++++++++++++++++------------- clock/api/weather-icons.bmp | Bin 0 -> 9272 bytes clock/main.py | 36 ++++++++--------- 8 files changed, 80 insertions(+), 94 deletions(-) delete mode 100644 clock/api/clouds.pbm rename clock/api/{led_out.py => led.py} (66%) create mode 100644 clock/api/weather-icons.bmp diff --git a/bot/main.py b/bot/main.py index aee7992..ff67c44 100644 --- a/bot/main.py +++ b/bot/main.py @@ -88,18 +88,6 @@ class ChatBot(): self.telegram = telegram.TelegramIO(self.persistence, self.commands) - # self.message_loop() - - - # def message_loop(self): - # """Calls the telegram entity regularly to check for activity""" - # while(True): - # result = self.telegram.fetch_updates() - # if len(result) != 0: - # command, params = self.telegram.handle_result(result) - # if command != "nothing": - # self.commands[command](params) - # time.sleep(5) def react_command(self, command, params): """""" diff --git a/clock.py b/clock.py index 8b1be1f..f987932 100644 --- a/clock.py +++ b/clock.py @@ -3,17 +3,17 @@ import datetime from threading import Thread import clock.main - +import bot.main class ModuleWrapper(): """Wrapper for the CLOCK-functionality""" def __init__(self, module_name): """""" self.clock = clock.main.ClockFace() - #import bot.main self.time_thread = Thread(target=self.mainloop) self.time_thread.start() + def mainloop(self): """Runs the showing of the clock-face periodically (better way?)""" prev_time = 0 @@ -23,4 +23,7 @@ class ModuleWrapper(): else: prev_time = datetime.datetime.now().strftime("%H:%M") - self.clock.set_face() + self.clock.set_face("sun") + + +test = ModuleWrapper("clock") diff --git a/clock/api/clouds.pbm b/clock/api/clouds.pbm deleted file mode 100644 index 31d4292..0000000 --- a/clock/api/clouds.pbm +++ /dev/null @@ -1,11 +0,0 @@ -P1 -# Cloud - non-standard p1! -16 8 -0000000000000000 -0000001111001000 -0000001001000000 -0000010000100000 -0000010000100000 -0000001001000000 -0000001111001000 -0000000000000000 diff --git a/clock/api/converter.py b/clock/api/converter.py index 95eb4c5..e7690f9 100644 --- a/clock/api/converter.py +++ b/clock/api/converter.py @@ -63,30 +63,25 @@ def date_converter(): pixels += lrow return pixels + def weather_converter(name): result = np.zeros((16,16)) - return result - equiv = { - "clouds" : "clouds.pbm", - "sun" : "sun.pbm", - "mix" : "mix.pbm", - "rain" : "rain.pbm", - "snow" : "snow.pbm", - } - if name in equiv: - fname = equiv[name] - else: - return np.zeros((8,16)) + cwd = __file__.replace("\\","/") # for windows + cwd = cwd.rsplit("/", 1)[0] # the current working directory (where this file is) + if len(cwd) == 0: + cwd = "." + icon_spritesheet = cwd + "/weather-icons.bmp" - f = open(fname,"r") - f.readline() - f.readline() - f.readline() + icons = Image.open(icon_spritesheet) + icons_full = np.array(icons) + print(name) + icon_loc = ["sun","moon","sun and clouds", "moon and clouds", "cloud","fog and clouds","2 clouds", "3 clouds", "rain and cloud", "rain and clouds", "thunder and cloud", "thunder and cloud and moon", "snow and cloud", "snow and cloud and moon", "fog","fog night"] + #ordered 1 2 \n 3 4 \ 5 5 ... + try: + iy, ix = int(icon_loc.index(name)/2), icon_loc.index(name)%2 + # x and y coords + except: + return np.zeros((16,16,3)) - result = np.zeros((16,16))#should be 8x16 - for i in range(8): - l = f.readline()[:-1] - for ind,bit in enumerate(l): - result[i][ind] = bit - - return result + icon_single = icons_full[16*iy:16*(iy + 1),16*ix:16*(ix + 1),...] + return icon_single diff --git a/clock/api/hat/sim.py b/clock/api/hat/sim.py index 39f3e5f..e5aa4a5 100644 --- a/clock/api/hat/sim.py +++ b/clock/api/hat/sim.py @@ -61,6 +61,7 @@ class UnicornHat(object): self.clear() self.draw() pygame.display.flip() + pygame.event.pump() #time.sleep(5) diff --git a/clock/api/led_out.py b/clock/api/led.py similarity index 66% rename from clock/api/led_out.py rename to clock/api/led.py index ae577e5..9d2b56f 100644 --- a/clock/api/led_out.py +++ b/clock/api/led.py @@ -19,11 +19,10 @@ class OutputHandler(): self.primary = [230, 230, 230] self.secondary = [10, 200, 10] self.red = [200, 10, 10] - self.weather_string = "" - self.weather_matrix = [] - def set_matrix(self, matrix, quadrant, colors = []): + + def set_matrix(self, matrix, quadrant = 1, colors = []): """assumes 1 for primary, 2 for secondary color (everything beyond is treated as an error) quadrant: 1,2,3,4 : 4|1 ___ @@ -32,6 +31,15 @@ class OutputHandler(): # reshape to the main size: (eg 32x16) (always aligns the given matrix on top left.) + + # add depth (rgb values) + r3 = self.matrix_add_depth(matrix,colors) + self.set_matrix_rgb(r3,quadrant) + + + def matrix_add_depth(self, matrix, colors = []): + """transforms a 2d-array with 0,1,2 to a 3d-array with the rgb values for primary and secondary color""" + c1 = self.primary c2 = self.secondary c3 = self.red @@ -44,21 +52,11 @@ class OutputHandler(): if len(colors) > 3: print("Too many colors") - result = np.zeros((self.height, self.width)) - if quadrant == 1: - result[:matrix.shape[0], self.width-matrix.shape[1]:] = matrix - elif quadrant == 2: - result[self.height-matrix.shape[0]:, self.width-matrix.shape[1]:] = matrix - elif quadrant == 3: - result[self.height-matrix.shape[0]:, :matrix.shape[1]] = matrix - else: # 4 or more - result[:matrix.shape[0], :matrix.shape[1]] = matrix - # add depth (rgb values) - r3 = np.zeros((self.height,self.width,3),dtype=int) - for i in range(self.height): - for j in range(self.width): - t = int(result[i, j]) + r3 = np.zeros((matrix.shape[0],matrix.shape[1],3),dtype=int) + for i in range(matrix.shape[0]): + for j in range(matrix.shape[1]): + t = int(matrix[i, j]) if t == 0: r3[i, j, :] = [0,0,0] elif t == 1: @@ -67,24 +65,38 @@ class OutputHandler(): r3[i, j, :] = c2 else: r3[i, j, :] = c3 - self.output.set_matrix(r3) + return r3 + + + + def set_matrix_rgb(self, matrix, quadrant=1): + result = np.zeros((self.height, self.width,3)) + if quadrant == 1: + result[:matrix.shape[0], self.width-matrix.shape[1]:,...] = matrix + elif quadrant == 2: + result[self.height-matrix.shape[0]:, self.width-matrix.shape[1]:,...] = matrix + elif quadrant == 3: + result[self.height-matrix.shape[0]:, :matrix.shape[1],...] = matrix + else: # 4 or more + result[:matrix.shape[0], :matrix.shape[1],...] = matrix + + self.output.set_matrix(result) def clock_face(self,weather): hour = converter.time_converter() day = converter.date_converter() face1 = hour + day + face1_3d = self.matrix_add_depth(face1) - if self.weather_matrix == [] or weather != self.weather_string: - self.weather_matrix = converter.weather_converter("clouds") - self.weather_string = weather - face2 = self.weather_matrix + face2_3d = converter.weather_converter(weather) + print("WEATHER",face2_3d.shape) + face = np.zeros((max(face1_3d.shape[0],face2_3d.shape[0]),face1_3d.shape[1]+face2_3d.shape[1],3)) - face = np.zeros((max(face1.shape[0],face2.shape[0]),face1.shape[1]+face2.shape[1])) - face[:face1.shape[0],:face1.shape[1]] = face1 - face[:face2.shape[0],face1.shape[1]:] = face2 - self.set_matrix(face, 4) + face[:face1_3d.shape[0],:face1_3d.shape[1],...] = face1_3d + face[:face2_3d.shape[0],face1_3d.shape[1]:,...] = face2_3d + self.set_matrix_rgb(face) def text_scroll(self, text, speed, color): diff --git a/clock/api/weather-icons.bmp b/clock/api/weather-icons.bmp new file mode 100644 index 0000000000000000000000000000000000000000..95be1fec6ae79ae3ae557dfc63f3bd13c53060fc GIT binary patch literal 9272 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 F{s*icsiXh^ literal 0 HcmV?d00001 diff --git a/clock/main.py b/clock/main.py index 6b6c4d1..d8962bb 100644 --- a/clock/main.py +++ b/clock/main.py @@ -1,18 +1,21 @@ import datetime import time import json -from clock.api import led_out from threading import Thread import numpy + +from clock.api import led import persistence.rw + + ################################################################################ #start of actual programm. class ClockFace(object): """Actual functions one might need for a clock""" def __init__(self, text_speed=10): - self.IO = led_out.OutputHandler(32,16) + self.IO = led.OutputHandler(32,16) self.tspeed = text_speed self.output_thread = "" @@ -42,9 +45,10 @@ class ClockFace(object): - def set_face(self): + def set_face(self, weather): """""" - self.run(self.IO.clock_face,("C")) + self.weather = weather + self.run(self.IO.clock_face,(weather,)) def text_scroll(self, text, color=""): @@ -66,7 +70,7 @@ class ClockFace(object): for i in range(20): ct = i/20 * gradient col = [int(x) for x in ct+start_color] - self.IO.set_matrix(ones,5,colors=[col]) + self.IO.set_matrix(ones,colors=[col]) time.sleep(duration / 20) @@ -83,24 +87,18 @@ class ClockFace(object): red = empty.copy() red[red == 0] = 3 for i in range(int(n)): - self.IO.set_matrix(red,5) + self.IO.set_matrix(red) time.sleep(1/frequency) - self.IO.set_matrix(empty,5) + self.IO.set_matrix(empty) time.sleep(1/frequency) - - - self.run(output,(duration, frequency)) - def image_show(self, image): - def output(): - self.output_threads.append("Showing: " + text) - self.IO.text_scroll(text, self.tspeed, color) - time.sleep(2) - self.output_threads.remove("Showing: " + text) - self.set_face() + def image_show(self, image, duratation): + """Shows a 16x32 image for duration seconds""" + def output(image, duratation): + self.IO.set_matrix_rgb(red) - scroll_thread = Thread(target = output) - scroll_thread.start() + + self.run(output,(image, duration))