Compare commits
1 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
da3a0b09b9 |
|
|
@ -1,13 +0,0 @@
|
||||||
[submodule "Software/Display"]
|
|
||||||
path = Software/Display
|
|
||||||
url = http://git.strawhat-solutions.de/nits/worktree-test.git
|
|
||||||
branch = Display
|
|
||||||
[submodule "Software/Sensor"]
|
|
||||||
path = Software/Sensor
|
|
||||||
url = http://git.strawhat-solutions.de/nits/worktree-test.git
|
|
||||||
branch = Sensor
|
|
||||||
[submodule "Software/tig-stack"]
|
|
||||||
path = Software/tig-stack
|
|
||||||
url = http://git.strawhat-solutions.de/nits/worktree-test.git
|
|
||||||
branch = tig-stack
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,37 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
class DataObject():
|
||||||
|
def __init__(self):
|
||||||
|
self.currentSpeed = 0
|
||||||
|
self.speed2AVG = 0
|
||||||
|
self.speed10AVG = 0
|
||||||
|
self.speed2Max = 0
|
||||||
|
self.speed10Max = 0
|
||||||
|
self.compass = 0
|
||||||
|
|
||||||
|
def data(self, client, userdata, msg):
|
||||||
|
|
||||||
|
m_in= self.decode( msg.payload )
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.currentSpeed = m_in['windspeed']
|
||||||
|
self.speed2AVG = m_in['speed2AVG']
|
||||||
|
self.speed10AVG = m_in['speed10AVG']
|
||||||
|
self.speed2Max = m_in['speed2max']
|
||||||
|
self.speed10Max = m_in['speed10max']
|
||||||
|
self.compass = m_in['winddirection']
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def config(self, client, userdata, msg):
|
||||||
|
|
||||||
|
m_in= self.decode( msg.payload )
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.warning = m_in['warning_level']
|
||||||
|
self.alert = m_in['alert_level']
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def decode(self,payload):
|
||||||
|
return json.loads( payload.decode("utf-8", "ignore") )
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 131 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,100 @@
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class DriverException(Exception):
|
||||||
|
def __init__(self, driverName):
|
||||||
|
self.driverName = driverName
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return repr(self.driverName)
|
||||||
|
|
||||||
|
class Screen():
|
||||||
|
screen = None
|
||||||
|
bgColor = None
|
||||||
|
|
||||||
|
def __init__(self, width, height, fullscreen):
|
||||||
|
size = (width, height)
|
||||||
|
|
||||||
|
disp_no = os.getenv('DISPLAY')
|
||||||
|
if disp_no:
|
||||||
|
print ("I'm running under X display = {0}".format(disp_no))
|
||||||
|
self.screen = pygame.display.init()
|
||||||
|
else:
|
||||||
|
print("Try to run from framebuffer...")
|
||||||
|
drivers = ['fbcon','directfb', 'svgalib']
|
||||||
|
|
||||||
|
found = False
|
||||||
|
for driver in drivers:
|
||||||
|
print(driver)
|
||||||
|
if not os.getenv('SDL_VIDEODRIVER'):
|
||||||
|
os.putenv('SDL_VIDEODRIVER', driver)
|
||||||
|
try:
|
||||||
|
self.screen = pygame.display.init()
|
||||||
|
except pygame.error:
|
||||||
|
print("Driver: {0} failed.".format(driver))
|
||||||
|
continue
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
raise Exception('No suitable video driver found!')
|
||||||
|
|
||||||
|
self.realSize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
|
||||||
|
if size[0] > self.realSize[0]:
|
||||||
|
size = (self.realSize[0], size[1])
|
||||||
|
if size[1] > self.realSize[1]:
|
||||||
|
size = (size[0], self.realSize[1])
|
||||||
|
if not fullscreen:
|
||||||
|
self.screen = pygame.display.set_mode(size)
|
||||||
|
else:
|
||||||
|
self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN|pygame.DOUBLEBUF|pygame.HWSURFACE)
|
||||||
|
|
||||||
|
|
||||||
|
def quit(self):
|
||||||
|
pygame.display.quit()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
def blit(self, surface, x, y):
|
||||||
|
|
||||||
|
self.screen.blit( surface, (x, y) )
|
||||||
|
|
||||||
|
def background(self, color):
|
||||||
|
try:
|
||||||
|
self.screen.fill( pygame.Color(color) )
|
||||||
|
except:
|
||||||
|
self.screen.fill( pygame.Color("white"))
|
||||||
|
finally:
|
||||||
|
self.bgColor = color
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.background(self.bgColor)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def setCaption(self, title):
|
||||||
|
pygame.display.set_caption(title)
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
# Fill the screen with red (255, 0, 0)
|
||||||
|
self.screen.fill(pygame.Color("red"))
|
||||||
|
# Update the display
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def getSize(self):
|
||||||
|
return self.screen.get_size()
|
||||||
|
|
||||||
|
def getRealSize(self):
|
||||||
|
return self.realSize
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 30e78ce13f489f23ecb5506d6540848347ccf4de
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit e0114c34df01dbc4b70b8356614e3fd40b92f3d3
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,71 @@
|
||||||
|
[General]
|
||||||
|
fullscreen: True
|
||||||
|
timeToEnd: 5
|
||||||
|
|
||||||
|
[MQTT]
|
||||||
|
topic: DPW/STR/CRAN2/WIND
|
||||||
|
config: DPW/STR/CRAN2
|
||||||
|
host: localhost
|
||||||
|
port: 1884
|
||||||
|
keepalive: 60
|
||||||
|
|
||||||
|
[Color]
|
||||||
|
normal = Black
|
||||||
|
warning = Yellow
|
||||||
|
alert = Red
|
||||||
|
|
||||||
|
|
||||||
|
[CurrentSpeed]
|
||||||
|
font_size = 28
|
||||||
|
x = 386
|
||||||
|
y = 226
|
||||||
|
|
||||||
|
[AVG2Speed]
|
||||||
|
font_size = 28
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
width = 400
|
||||||
|
height = 240
|
||||||
|
|
||||||
|
[AVG10Speed]
|
||||||
|
font_size = 28
|
||||||
|
x = 0
|
||||||
|
y = 240
|
||||||
|
width = 400
|
||||||
|
height = 240
|
||||||
|
|
||||||
|
[Max2Speed]
|
||||||
|
font_size = 28
|
||||||
|
x = 400
|
||||||
|
y = 0
|
||||||
|
width = 400
|
||||||
|
height = 240
|
||||||
|
|
||||||
|
[Max10Speed]
|
||||||
|
font_size = 28
|
||||||
|
x = 400
|
||||||
|
y = 240
|
||||||
|
width = 400
|
||||||
|
height = 240
|
||||||
|
|
||||||
|
[Compass]
|
||||||
|
font_size = 20
|
||||||
|
width = 280
|
||||||
|
height = 280
|
||||||
|
x = 260
|
||||||
|
y = 100
|
||||||
|
background = Navy
|
||||||
|
needle_color = Deepskyblue
|
||||||
|
lineLength = 60
|
||||||
|
|
||||||
|
[CompassBackground]
|
||||||
|
dashedLineColor = Darkgrey
|
||||||
|
dashsize = 10
|
||||||
|
groundColor = Lightgrey
|
||||||
|
angleOffset = 13
|
||||||
|
|
||||||
|
[Splashscreen]
|
||||||
|
fadein = 0.5
|
||||||
|
fadeout = 0.5
|
||||||
|
solid = 0.5
|
||||||
|
font_size = 20
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo Starting display application
|
||||||
|
cd /home/pi/Windmessanlage/Software/Display/
|
||||||
|
DISPLAY=:0 python3 main.py
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
import pygame
|
||||||
|
import math
|
||||||
|
|
||||||
|
class Compass():
|
||||||
|
def __init__(self, font_size, size):
|
||||||
|
pygame.font.init()
|
||||||
|
self.textColor = pygame.Color("white")
|
||||||
|
self.backgroundColor = pygame.Color("White")
|
||||||
|
self.needleColor = pygame.Color("black")
|
||||||
|
|
||||||
|
self.font = pygame.font.Font(pygame.font.get_default_font(), font_size)
|
||||||
|
|
||||||
|
self.surface = pygame.Surface(size, pygame.SRCALPHA)
|
||||||
|
self.size = size
|
||||||
|
|
||||||
|
self.x = 0
|
||||||
|
self.y = 0
|
||||||
|
|
||||||
|
self.backgroundSurface = None
|
||||||
|
|
||||||
|
|
||||||
|
def setX(self, x):
|
||||||
|
self.x = x
|
||||||
|
def getX(self):
|
||||||
|
return self.x
|
||||||
|
|
||||||
|
def setY(self, y):
|
||||||
|
self.y = y
|
||||||
|
def getY(self):
|
||||||
|
return self.y
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.surface
|
||||||
|
|
||||||
|
def setTextColor(self, color):
|
||||||
|
try:
|
||||||
|
self.textColor = pygame.Color(color)
|
||||||
|
except:
|
||||||
|
self.textColor = pygame.Color("black")
|
||||||
|
|
||||||
|
def setBackgroundColor(self, color):
|
||||||
|
try:
|
||||||
|
self.backgroundColor = pygame.Color(color)
|
||||||
|
except:
|
||||||
|
self.backgroundColor = pygame.Color("white")
|
||||||
|
|
||||||
|
def setNeedleColor(self, color):
|
||||||
|
try:
|
||||||
|
self.needleColor = pygame.Color(color)
|
||||||
|
except:
|
||||||
|
self.needleColor = pygame.Color("black")
|
||||||
|
|
||||||
|
def update(self, value):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class MiddleNeedle(Compass):
|
||||||
|
def update(self, value):
|
||||||
|
radius = min(self.size[0]//2, self.size[1]//2)
|
||||||
|
pygame.draw.circle( self.surface, self.backgroundColor, (self.size[0]//2, self.size[1]//2), radius)
|
||||||
|
|
||||||
|
|
||||||
|
arrow = pygame.Surface( ((self.size[0]//100*60)//2, self.size[1]//100*60), pygame.SRCALPHA )
|
||||||
|
|
||||||
|
polygon_list = [
|
||||||
|
( arrow.get_width()//2, 0 ), #Middle top
|
||||||
|
( 0, arrow.get_height() ), #bottom left
|
||||||
|
( arrow.get_width()//2, (arrow.get_height()-arrow.get_height()//100*30) ), #middle pos
|
||||||
|
( arrow.get_width(), arrow.get_height() ), #bottom right
|
||||||
|
]
|
||||||
|
|
||||||
|
pygame.draw.polygon(arrow, self.needleColor, polygon_list)
|
||||||
|
arrow = pygame.transform.rotate( arrow, value )
|
||||||
|
self.surface.blit( arrow, ( (self.size[0]//2)-(arrow.get_width()//2), (self.size[1]//2)-(arrow.get_height()//2)))
|
||||||
|
|
||||||
|
text = self.font.render("N", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*10) - text.get_height()//2 ) )
|
||||||
|
|
||||||
|
text = self.font.render("W", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( int(self.size[0]/100*10) - (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||||||
|
|
||||||
|
text = self.font.render("O", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( int(self.size[0]/100*90)- (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||||||
|
|
||||||
|
text = self.font.render("S", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*90) - text.get_height()//2 ) )
|
||||||
|
|
||||||
|
|
||||||
|
class OuterNeedle(Compass):
|
||||||
|
def update(self, value):
|
||||||
|
radius = min(self.size[0]//2, self.size[1]//2)
|
||||||
|
pygame.draw.circle( self.surface, self.backgroundColor, (self.size[0]//2, self.size[1]//2), radius)
|
||||||
|
|
||||||
|
|
||||||
|
if self.backgroundSurface:
|
||||||
|
self.surface.blit( self.backgroundSurface, (0,0) )
|
||||||
|
|
||||||
|
if self.lineLength is None:
|
||||||
|
self.lineLength = 5
|
||||||
|
|
||||||
|
# 0 is down -> +90
|
||||||
|
# alpha = 2 * arcsin (s / 2r); s is bottom line
|
||||||
|
alpha = 2 * math.asin( self.lineLength / (2*radius) )
|
||||||
|
value = math.radians(value) + math.pi/2 #put 0 to bottom
|
||||||
|
bottom_left = self.getPos(value +alpha/2, radius)
|
||||||
|
bottom_left = ( int(bottom_left[0] + radius), bottom_left[1]+radius) #offset to screen middle
|
||||||
|
bottom_right = self.getPos(value -alpha/2, radius)
|
||||||
|
bottom_right = ( int(bottom_right[0] + radius), bottom_right[1]+radius)
|
||||||
|
height_of_segment = self.lineLength/2 * math.tan( alpha / 4 )
|
||||||
|
height_of_triangle = math.sqrt(3) /2 * self.lineLength
|
||||||
|
top = self.getPos(value, radius-height_of_segment-height_of_triangle)
|
||||||
|
top = ( int(top[0] + radius), top[1]+radius )
|
||||||
|
points = [ bottom_left, top, bottom_right ]
|
||||||
|
|
||||||
|
pygame.draw.lines( self.surface, self.needleColor, False, points,3)
|
||||||
|
|
||||||
|
text = self.font.render("N", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*10) - text.get_height()//2 ) )
|
||||||
|
|
||||||
|
text = self.font.render("W", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( int(self.size[0]/100*10) - (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||||||
|
|
||||||
|
text = self.font.render("O", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( int(self.size[0]/100*90)- (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
|
||||||
|
|
||||||
|
text = self.font.render("S", True, self.textColor)
|
||||||
|
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*90) - text.get_height()//2 ) )
|
||||||
|
|
||||||
|
def getPos(self, alpha, radius):
|
||||||
|
return ( int( radius * math.cos(alpha) ), int( radius * math.sin(alpha) ) )
|
||||||
|
|
||||||
|
def setLineLength(self, length):
|
||||||
|
self.lineLength = length
|
||||||
|
|
||||||
|
def setBackgroundSurface(self, surface):
|
||||||
|
self.backgroundSurface = surface
|
||||||
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import pygame
|
||||||
|
import math
|
||||||
|
|
||||||
|
class Point():
|
||||||
|
# constructed using a normal tupple
|
||||||
|
def __init__(self, point_t = (0,0)):
|
||||||
|
self.x = float(point_t[0])
|
||||||
|
self.y = float(point_t[1])
|
||||||
|
|
||||||
|
# define all useful operators
|
||||||
|
def __add__(self, other):
|
||||||
|
return Point((self.x + other.x, self.y + other.y))
|
||||||
|
def __sub__(self, other):
|
||||||
|
return Point((self.x - other.x, self.y - other.y))
|
||||||
|
def __mul__(self, scalar):
|
||||||
|
return Point((self.x*scalar, self.y*scalar))
|
||||||
|
def __truediv__(self, scalar):
|
||||||
|
return Point((self.x/scalar, self.y/scalar))
|
||||||
|
def __len__(self):
|
||||||
|
return int(math.sqrt(self.x**2 + self.y**2))
|
||||||
|
# get back values in original tuple format
|
||||||
|
def get(self):
|
||||||
|
return (self.x, self.y)
|
||||||
|
|
||||||
|
|
||||||
|
def draw_dashed_line(surf, color, start_pos, end_pos, width=1, dash_length=10):
|
||||||
|
origin = Point(start_pos)
|
||||||
|
target = Point(end_pos)
|
||||||
|
displacement = target - origin
|
||||||
|
length = len(displacement)
|
||||||
|
slope = displacement/length
|
||||||
|
|
||||||
|
for index in range(0, int(length/dash_length), 2):
|
||||||
|
start = origin + (slope * index * dash_length)
|
||||||
|
end = origin + (slope * (index + 1) * dash_length)
|
||||||
|
pygame.draw.line(surf, color, start.get(), end.get(), width)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
start =(50,50)
|
||||||
|
end =(100,50)
|
||||||
|
|
||||||
|
surface = pygame.Surface( (200,200) )
|
||||||
|
|
||||||
|
draw_dashed_line( surface, pygame.Color("Black"), start, end, width=1 )
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class Text():
|
||||||
|
def __init__(self,txt, font_size):
|
||||||
|
pygame.font.init()
|
||||||
|
self.color = pygame.Color("black")
|
||||||
|
self.txt = txt
|
||||||
|
self.font = pygame.font.Font(pygame.font.get_default_font(), font_size)
|
||||||
|
self.text = self.font.render(self.txt, True, self.color)
|
||||||
|
self.x = 0
|
||||||
|
self.y = 0
|
||||||
|
|
||||||
|
def setX(self, x):
|
||||||
|
self.x = x
|
||||||
|
def getX(self):
|
||||||
|
return self.x
|
||||||
|
|
||||||
|
def setY(self, y):
|
||||||
|
self.y = y
|
||||||
|
def getY(self):
|
||||||
|
return self.y
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
|
def getSize(self):
|
||||||
|
return self.text.get_size()
|
||||||
|
|
||||||
|
def getWidth(self):
|
||||||
|
return self.text.get_width()
|
||||||
|
|
||||||
|
def setColor(self, color):
|
||||||
|
try:
|
||||||
|
self.color = pygame.Color(color)
|
||||||
|
except:
|
||||||
|
self.color = pygame.Color("black")
|
||||||
|
self.text = self.font.render(self.txt, True, self.color)
|
||||||
|
|
||||||
|
|
||||||
|
class VariableText(Text):
|
||||||
|
def __init__(self, txt, font_size):
|
||||||
|
pygame.font.init()
|
||||||
|
self.color = pygame.Color("black")
|
||||||
|
self.txt = txt+"{}"
|
||||||
|
self.font = pygame.font.Font(pygame.font.get_default_font(), font_size)
|
||||||
|
self.text = self.font.render(self.txt.format(0), True, self.color)
|
||||||
|
|
||||||
|
def setUnit(self, unit):
|
||||||
|
self.txt = self.txt+unit
|
||||||
|
self.unit = unit
|
||||||
|
|
||||||
|
def update(self, value):
|
||||||
|
self.text = self.font.render(self.txt.format(value), True, self.color)
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
class Textbox():
|
||||||
|
def __init__(self, size, x, y, font_size):
|
||||||
|
self.background = pygame.Color("grey")
|
||||||
|
self.surface = pygame.Surface( size )
|
||||||
|
self.surface.fill( self.background )
|
||||||
|
|
||||||
|
self.color = pygame.Color("White")
|
||||||
|
self.fontsize = 20
|
||||||
|
pygame.font.init()
|
||||||
|
|
||||||
|
self.font = pygame.font.Font(pygame.font.get_default_font(), font_size)
|
||||||
|
text = self.font.render("", True, self.color)
|
||||||
|
self.surface.blit( text, (0,0) )
|
||||||
|
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
def setText(self, text):
|
||||||
|
self.lines = text.split('\n')
|
||||||
|
self.nr_of_lines = len(self.lines)
|
||||||
|
|
||||||
|
def setTextColor(self, color):
|
||||||
|
try:
|
||||||
|
self.color = pygame.Color(color)
|
||||||
|
except:
|
||||||
|
self.color = pygame.Color("black")
|
||||||
|
|
||||||
|
def setBackgroundColor(self, color):
|
||||||
|
try:
|
||||||
|
self.background = pygame.Color(color)
|
||||||
|
except:
|
||||||
|
self.background = pygame.Color("grey")
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.surface
|
||||||
|
|
||||||
|
def getX(self):
|
||||||
|
return self.x
|
||||||
|
|
||||||
|
def getY(self):
|
||||||
|
return self.y
|
||||||
|
|
||||||
|
def update(self, value):
|
||||||
|
self.surface.fill( self.background )
|
||||||
|
|
||||||
|
for lineNr, line in enumerate(self.lines):
|
||||||
|
text = self.font.render(line.format(value), True, self.color)
|
||||||
|
spacing = text.get_height()//10
|
||||||
|
x = self.surface.get_width()//2 - text.get_width()//2
|
||||||
|
height_total = self.nr_of_lines * (text.get_height() + spacing)
|
||||||
|
y = self.surface.get_height()//2 - height_total//2 + (lineNr * (text.get_height()+spacing))
|
||||||
|
self.surface.blit( text, (x,y) )
|
||||||
|
|
||||||
|
|
@ -0,0 +1,281 @@
|
||||||
|
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()
|
||||||
48
readme.md
48
readme.md
|
|
@ -1,48 +0,0 @@
|
||||||
#### WIND MESS ANLAGE BY NETWEBSYSTEMS®
|
|
||||||
##### BASIC INSTRUCTIONS FOR INSTALLATION FOR BEAGLEBONE
|
|
||||||
|
|
||||||
###### 1. PREPARE BEAGLEBONE:
|
|
||||||
* 1.1 INSTALL O.S.
|
|
||||||
* 1.2 CONNECT THROUGH SSH (192.168.7.2)\
|
|
||||||
- SSH password: Netweb4ever!
|
|
||||||
* 1.3 CONNECT TO WIFI
|
|
||||||
* 1.4 USE IFCONFIG TO CHECK IP AND USE THIS IP TO ACCESS REMOTELY
|
|
||||||
* 1.5 INSTALL 'minimalmodbus' and 'paho-mqtt' libraries WITH -H\
|
|
||||||
sudo -H pip3 install minimalmodbus paho-mqtt
|
|
||||||
###### 2. PREPARE THE SENSOR:
|
|
||||||
* 2.1 OPEN THIES DEVICE UTILITY
|
|
||||||
* 2.2 LOG AS ADMIN KY04711, CS1
|
|
||||||
* 2.3 CHANGE DUPLEX MODUS AND WIRING
|
|
||||||
* 2.4 SET TIME ZONE (TZ26) AND DAILY TIME UPDATE(RT03)
|
|
||||||
* 2.5 CHANGE TO MODBUS RTU INTERPRETER IN THE THIES DEVICE UTILITY
|
|
||||||
* 2.6 CONNECT THE SENSOR TO THE BEAGLEBONE (BR & YE = A, GR & WH = B, GRAY = GND)
|
|
||||||
###### 3. INSTALL THE SOFTWARE IN THE BEAGLEBONE
|
|
||||||
* 3.1 CLONE THE GIT REPOSITORY\
|
|
||||||
$ git clone http://git.strawhat-solutions.de/NetWEB/Windmessanlage.git
|
|
||||||
* 3.2 CREATE THE WORKING DIRECTORY AND COPY FILES:
|
|
||||||
* 3.3 EDIT THE CONFIG.INI FILE
|
|
||||||
|
|
||||||
###### 4. SET SERVICE AUTO-START
|
|
||||||
* 4.1 COPY SERVICE FILE INTO BEAGLE BONE SERVICE DIRECTORY\
|
|
||||||
$ sudo cp /var/lib/cloud9/Windmessanlage/Software/Sensor/wma.service /lib/systemd/
|
|
||||||
* 4.2 CREATE A SYMLINK in the /etc/systemd/system/ directory \
|
|
||||||
$ sudo ln -s /lib/systemd/wma.service /etc/systemd/system/wma.service
|
|
||||||
* 4.3 RELOAD DAEMON, ENABLE AND START THE SERVICE
|
|
||||||
|
|
||||||
###### 2. PREPARE DISPLAY:
|
|
||||||
|
|
||||||
* 1.1 POWER UP DISPLAY\
|
|
||||||
Connect the +24 and GND Wires to power up the Display
|
|
||||||
* 1.2 INSTALL 'pygame' and 'paho-mqtt' libraries WITH -H
|
|
||||||
* 1.3 CREATE CHANGE TO THE WORKING DIRECTORY\
|
|
||||||
$ sudo mkdir /home/pi/WMA/\
|
|
||||||
$ cd /home/pi/WMA/
|
|
||||||
* 2.2 CLONE THE GIT REPOSITORY
|
|
||||||
* 2.3 EDIT THE CONFIG.INI FILE FOR THE APPLICATION\
|
|
||||||
$ sudo nano /home/pi/WMA/Windmessanlage/Display/config.ini
|
|
||||||
|
|
||||||
###### 3. SET SERVICE AUTO-START
|
|
||||||
|
|
||||||
* 3.1 COPY SERVICE FILE INTO BEAGLE BONE SERVICE DIRECTORY\
|
|
||||||
$ sudo cp /home/pi/WMA/Windmessanlage/Display/display.service /etc/systemd/system/display.service
|
|
||||||
* 3.2 RELOAD DAEMON, ENABLE AND START THE SERVICE\
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
Loading…
Reference in New Issue