282 lines
9.9 KiB
Python
282 lines
9.9 KiB
Python
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()
|