WattWatch/FarbenVorigerNaechsertTag.py

162 lines
6.2 KiB
Python

# main.py
# Import statements
import kivy
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from datetime import datetime, date, timedelta
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.scrollview import ScrollView
from kivy.garden.matplotlib import FigureCanvasKivyAgg
from awattar import AwattarClient
# Create AwattarClient instance
client = AwattarClient('AT')
# Set initial date and get energy prices
date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
data = client.request(date)
hours = np.arange(24)
prices = np.array([item.marketprice/10 for item in data])
# Define DiagramWidget class
class DiagramWidget(FigureCanvasKivyAgg):
def __init__(self, figure, **kwargs):
super().__init__(figure, **kwargs)
self.ax = self.figure.axes[0]
figure.patch.set_facecolor('black')
self.minimum_height = 100 # Set a minimum height for the widget
self.ax.set_facecolor('black') # set background color to black
self.ax.tick_params(colors='white') # set tick color to white
for spine in self.ax.spines.values():
spine.set_edgecolor('white') # set spine edge color to white
spine.set_facecolor('black') # set spine face color to none
# Define MyBoxLayout widget
class MyBoxLayout(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Set widget properties
self.orientation = 'vertical'
self.background_color = (0, 0, 0, 1) # set background color to black
self.date_label = Label(text=date.strftime('%d.%m.%Y'), font_size='20sp', halign='left', valign='middle', size_hint=(1, None), height='50dp', pos_hint={'top': 1.0, 'x': 0.02})
self.add_widget(self.date_label)
# Define color map based on energy prices
cmap = mpl.colors.ListedColormap(['blue', 'green', 'yellow', 'red'])
bounds = [-float('inf'), 0, 5, 20, float('inf')] # Include 0 in color map bounds
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
color_map = cmap(norm(prices))
# Create plot figure
self.fig, self.ax = plt.subplots(figsize=(10, 5))
self.fig.subplots_adjust(left=0.075, bottom=0.175) # Adjust bottom margin to make space for buttons
# Add bars to plot using color map
for i in range(len(hours)):
self.ax.bar(hours[i], prices[i], width=0.5, edgecolor='white', linewidth=0.5, color=color_map[i])
# Set plot limits and ticks
self.ax.set(xlim=(-1, 24), xticks=hours)
# Create DiagramWidget and add it to the ScrollView
self.diagram_widget = DiagramWidget(figure=self.fig)
scroll_view = ScrollView(size_hint=(1, 0.6)) # Make ScrollView take up 60% of screen height
scroll_view.add_widget(self.diagram_widget)
self.add_widget(scroll_view)
# Add toggle buttons
toggle_box = BoxLayout(orientation='horizontal', size_hint=(1, 0.1)) # Make toggle_box take up 10% of screen height
toggle_box.spacing = '5dp'
toggle_box.padding = '5dp'
toggle_button1 = ToggleButton(text='Netto/Brutto')
toggle_button2 = ToggleButton(text='Stromherkunft einblenden')
toggle_box.add_widget(toggle_button1)
toggle_box.add_widget(toggle_button2)
self.add_widget(toggle_box)
# Add navigation buttons
button_box = BoxLayout(orientation='horizontal', size_hint=(1, 0.1)) # Make button_box take up 10% of screen height
button_box.spacing = '5dp'
button_box.padding = '5dp'
prev_button = ToggleButton(text='Prev Day')
prev_button.bind(on_press=self.previous_day)
next_button = ToggleButton(text='Next Day')
next_button.bind(on_press=self.next_day)
button_box.add_widget(prev_button)
button_box.add_widget(next_button)
self.add_widget(button_box)
# Update energy prices and plot
self.update_prices()
# Update energy prices and plot
def update_prices(self):
global prices, date
date_prices = client.request(date)
prices = np.array([item.marketprice/10 for item in date_prices])
# Define color map based on energy prices
cmap = mpl.colors.ListedColormap(['blue', 'green', 'yellow', 'red'])
bounds = [-float('inf'), 0, 5, 20, float('inf')] # Include 0 in color map bounds
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
color_map = cmap(norm(prices))
# Clear existing plot and add bars using color map
self.ax.clear()
for i in range(len(hours)):
self.ax.bar(hours[i], prices[i], width=0.5, edgecolor='white', linewidth=0.5, color=color_map[i])
# Set plot limits and ticks
self.ax.set(xlim=(-1, 24), xticks=hours)
self.date_label.text = date.strftime('%d.%m.%Y')
self.diagram_widget.draw()
# Navigate to previous day and update energy prices and plot
def previous_day(self, instance):
global date
date = date - timedelta(days=1)
self.update_prices()
# Navigate to next day and update energy prices and plot
def next_day(self, instance):
global date
date = date + timedelta(days=1)
self.update_prices()
# Dynamically adjust height of ScrollView and DiagramWidget
def on_size(self, *args):
self.diagram_widget.height = max(self.height * 0.6 - 100, self.diagram_widget.minimum_height) # Adjust height to make space for toggle_box and button_box
self.diagram_widget.width = self.width
# Define WattWatchMain widget
class WattWatchMain(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = MyBoxLayout()
self.add_widget(layout)
# Define WattWatchApp class
class WattWatchApp(App):
title = 'WattWatch'
icon = 'wwicon.png'
def build(self):
sm = ScreenManager()
my_screen = WattWatchMain(name='WattWatchMain')
sm.add_widget(my_screen)
sm.current = 'WattWatchMain'
return sm
# Run the app
if __name__ == '__main__':
WattWatchApp().run()