import os import platform import pygame import time import math import configparser import paho.mqtt.client as mqtt from DataObject import DataObject from Screen import Screen from elements.Text import Text, VariableText from elements.Textbox import Textbox from elements.Compass import OuterNeedle from elements.Line import draw_dashed_line, Point topic = "" def on_connect(client, userdata, flags, rc): print("Subscribe to {}".format(topic)) client.subscribe(topic) def splashscreen(screen, fadein, solid, fadeout, font_size): screen.background("white") size = screen.getSize() txt = Text("powered by NetWEB Systems", font_size) img = pygame.image.load("resources/NWS.bmp") imgSize = img.get_rect().size surface = pygame.Surface(size) surface.fill(pygame.Color("white")) surface.blit(img, (size[0]//2 - imgSize[0], size[1]//2 - imgSize[1])) surface.blit(txt.get(), (size[0]//2, size[1]//2)) if (fadein > 0): for alpha in range(0,255): #0 is transparent, 255 is opaque screen.reset() surface.set_alpha(alpha) screen.blit(surface,0,0) screen.update() time.sleep( fadein/255 ) screen.reset() screen.blit(surface,0,0) screen.update() time.sleep(solid) if (fadeout > 0): for alpha in range(0,255): #0 is transparent, 255 is opaque screen.reset() surface.set_alpha(255-alpha) screen.blit(surface,0,0) screen.update() time.sleep( fadeout/255 ) def getPos(angle, radius, offset): return ( int( radius * math.cos(angle) )+offset, int( radius * math.sin(angle) )+offset) def blitRotate(surf, image, pos, originPos, angle): # calcaulate the axis aligned bounding box of the rotated image w, h = image.get_size() box = [pygame.math.Vector2(p) for p in [(0, 0), (w, 0), (w, -h), (0, -h)]] box_rotate = [p.rotate(angle) for p in box] min_box = (min(box_rotate, key=lambda p: p[0])[0], min(box_rotate, key=lambda p: p[1])[1]) max_box = (max(box_rotate, key=lambda p: p[0])[0], max(box_rotate, key=lambda p: p[1])[1]) # calculate the translation of the pivot pivot = pygame.math.Vector2(originPos[0], -originPos[1]) pivot_rotate = pivot.rotate(angle) pivot_move = pivot_rotate - pivot # calculate the upper left origin of the rotated image origin = (pos[0] - originPos[0] + min_box[0] - pivot_move[0], pos[1] - originPos[1] - max_box[1] + pivot_move[1]) # get a rotated image rotated_image = pygame.transform.rotate(image, angle) # rotate and blit the image surf.blit(rotated_image, origin) def buildBackground( size, config ): surface = pygame.Surface( size, pygame.SRCALPHA) w = size[0] h = size[1] try: dashedLineColor = pygame.Color( config.get('CompassBackground','dashedLineColor') ) except: dashedLineColor = pygame.Color("Black") try: groundColor = pygame.Color( config.get('CompassBackground','groundColor')) except: groundColor = pygame.Color("Black") radius = min( w, h ) // 2 angle = config.getint('CompassBackground', 'angleOffset') angle = math.radians( angle ) dash_length = config.getint('CompassBackground','dashSize') #Kaimauer start = getPos( angle, radius, offset=radius ) end = getPos( angle+math.pi, radius, offset=radius ) draw_dashed_line(surface, dashedLineColor, start, end, width=2, dash_length= dash_length ) alpha = 2 * math.acos( 1-( (radius-10)/radius ) ) start = getPos( (math.pi/2) + (alpha/2) + angle, radius, offset=radius ) end = getPos( (math.pi/2) - (alpha/2) + angle, radius, offset=radius ) draw_dashed_line(surface, dashedLineColor, start, end, width=2, dash_length= dash_length ) start = getPos( angle+(math.pi/2), radius//10*8, offset=radius ) end = getPos( angle+(math.pi/2), radius//10*1, offset=radius ) #x1 = Point( start ) #x2 = Point( end ) #alpha = math.radians(20) #d = len(x1 - x2) #print(d) #length = d * (1/math.sin(math.pi+alpha)) #print(length) #x = d * math.cos( alpha ) #y = d * math.cos( alpha ) #print( x, y) #pygame.draw.line( surface, groundColor, start, (x,y) ) txt = Text( 'Terminal', 20 ) txt.setColor('Lightgrey') txt_surface = pygame.transform.rotate( txt.get(), -math.degrees(angle) ) pos = getPos(angle+(math.pi/2), radius/10*2, radius-txt.getWidth()//2) surface.blit( txt_surface, pos ) #circle_surface = pygame.Surface( size, pygame.SRCALPHA) #pygame.draw.circle( circle_surface, groundColor, (w//2, h//2), radius, width=0, draw_bottom_left=True) #pygame.draw.circle( circle_surface, groundColor, (w//2, h//2), radius, width=0, draw_bottom_right=True) #blitRotate(surface, circle_surface, (w//2,h//2), (w//2,h//2), -math.degrees(angle)) return surface if __name__ == "__main__": #load config config = configparser.ConfigParser() config.read("config.ini") fullscreen = config.getboolean('General', 'fullscreen') timeToEnd = config.getfloat('General','timetoend') screen = Screen(800,480, fullscreen) screen.setCaption("Windmessanlage") screen.background("white") #Splashscreen splashscreen(screen, config.getfloat('Splashscreen','fadein'), config.getfloat('Splashscreen','solid'), config.getfloat('Splashscreen','fadeout'), config.getint('Splashscreen','font_size')) #-average speed 2min size = ( int(config.get('AVG2Speed','width')), int(config.get('AVG2Speed','height')) ) x = int(config.get('AVG2Speed','x')) y = int(config.get('AVG2Speed','y')) averageSpeed2 = Textbox( size, x, y, int(config.get('AVG2Speed','font_size')) ) averageSpeed2.setText("Ø 2min:\n{}m/s") averageSpeed2.setBackgroundColor("Black") #-average speed 10min size = ( int(config.get('AVG10Speed','width')), int(config.get('AVG10Speed','height')) ) x = int(config.get('AVG10Speed','x')) y = int(config.get('AVG10Speed','y')) averageSpeed10 = Textbox( size, x, y, int(config.get('AVG10Speed','font_size')) ) averageSpeed10.setText("\nØ 10min:\n{}m/s") averageSpeed10.setBackgroundColor("Black") #-max speed 2min size = ( int(config.get('Max2Speed','width')), int(config.get('Max2Speed','height')) ) x = int(config.get('Max2Speed','x')) y = int(config.get('Max2Speed','y')) maxSpeed2 = Textbox( size, x, y, int(config.get('Max2Speed','font_size')) ) maxSpeed2.setText("Max 2min:\n{}m/s") maxSpeed2.setBackgroundColor("black") #-max speed 10min size = ( int(config.get('Max10Speed','width')), int(config.get('Max10Speed','height')) ) x = int(config.get('Max10Speed','x')) y = int(config.get('Max10Speed','y')) maxSpeed10 = Textbox( size, x, y, int(config.get('Max10Speed','font_size')) ) maxSpeed10.setText("\nMax 10min:\n{}m/s") maxSpeed10.setBackgroundColor("Black") #compass compass = OuterNeedle(int(config.get('Compass','font_size')), (int(config.get('Compass','width')), int(config.get('Compass','height'))) ) compass.setX( int(config.get('Compass','x')) ) compass.setY( int(config.get('Compass','y')) ) compass.setBackgroundColor( config.get('Compass', 'background') ) compass.setNeedleColor( config.get('Compass', 'needle_color') ) compass.setLineLength( config.getint('Compass', 'lineLength') ) compass.setBackgroundSurface( buildBackground( (int(config.get('Compass','width')), int(config.get('Compass','height'))), config ) ) #-Current speed currentSpeed = VariableText("", int(config.get('CurrentSpeed','font_size'))) currentSpeed.setX(int(config.get('CurrentSpeed','x'))) currentSpeed.setY(int(config.get('CurrentSpeed','y'))) currentSpeed.setUnit("m/s") currentSpeed.setColor("white") #MQTT topic = config.get('MQTT','topic') mqttc = mqtt.Client() mqttc.on_connect = on_connect data = DataObject() mqttc.message_callback_add( config.get('MQTT','topic'), data.data) mqttc.message_callback_add( config.get('MQTT','config'), data.config) mqtt_host = config.get('MQTT', 'host') mqtt_port = int(config.get('MQTT', 'port')) screen.reset() screen.blit( Text("Try to connect to MQTT server", 24).get(), 0, 0) screen.blit( Text("Server: {0}:{1}".format(mqtt_host, mqtt_port),24).get(), 0, 25) screen.update() pygame.mouse.set_visible(False) while(True): try: mqttc.connect(mqtt_host, port=mqtt_port, keepalive=int(config.get('MQTT', 'keepalive'))) break except (KeyboardInterrupt, SystemExit): print("KeyboardInterrupt or SystemExit") raise except: time.sleep(3) print("Try to reconnect") mqttc.loop_start() #limit framerate clock = pygame.time.Clock() time_start = 0 while True: e = pygame.event.poll() if e.type == pygame.QUIT: break if e.type == pygame.MOUSEBUTTONDOWN: time_start = time.time() if e.type == pygame.MOUSEBUTTONUP: if (time.time() - time_start > timeToEnd): print("{}s".format(time.time() - time_start)) break screen.reset() currentSpeed.update(data.currentSpeed) averageSpeed2.update(data.speed2AVG) averageSpeed10.update(data.speed2AVG) maxSpeed2.update(data.speed2Max) maxSpeed10.update(data.speed10Max) compass.update(data.compass) screen.blit( averageSpeed2.get(), averageSpeed2.getX(), averageSpeed2.getY() ) screen.blit( averageSpeed10.get(), averageSpeed10.getX(), averageSpeed10.getY() ) screen.blit( maxSpeed2.get(), maxSpeed2.getX(), maxSpeed2.getY() ) screen.blit( maxSpeed10.get(), maxSpeed10.getX(), maxSpeed10.getY() ) screen.blit( compass.get(), compass.getX(), compass.getY() ) screen.blit( currentSpeed.get(), currentSpeed.getX(), currentSpeed.getY() ) screen.update() #Limit to 30 fps clock.tick(30) screen.quit()