-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwebui.py
140 lines (116 loc) · 5.73 KB
/
webui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import taipy as tp, taipy.gui.builder as tgb
from threading import Thread
import time, random, gc
from datetime import datetime, timedelta
import db, mylib
import pandas as pd
# Gui refresh delay
delay = mylib.config_details_delay
# Global variables holding data to be shown on the gui
date = datetime.today().date()
realtime = db.pread_realtime()
daily_stats = db.pread_daily_details(date)
monthly_stats = db.pread_monthly_stats(date)
yearly_stats = db.pread_yearly_stats(date)
# Gui state ID (single user mode)
state_id = None
def create_page():
# Page layout
with tgb.Page() as page:
tgb.text("# PVM — PhotoVoltaic Monitor", mode="md")
with tgb.layout("2 5", gap="20px", class_name="align-column-center"):
tgb.text("⌚️ _{realtime['timestamp'].item()}_", mode="md")
with tgb.layout("5 1 1 1 20", class_name="align-columns-center"):
tgb.date("{date}", format="PP", on_change="change_date")
tgb.button(label="◀", hover_text="Day - 1", on_action="yesterday")
tgb.button(label="⏏︎", hover_text="Today", on_action="today")
tgb.button(label="▶", hover_text="Day + 1", on_action="tomorrow")
tgb.part()
with tgb.part():
tgb.text("#### ☀️ Generator", mode="md")
with tgb.layout("1 1", class_name="container align-columns-center"):
tgb.text("Power (W)", class_name="h5 color-primary")
tgb.text("{realtime['generator_power'].item()}", format="%.0f", class_name="h5 color-primary")
tgb.text("Status")
tgb.text("{realtime['status'].item()}")
tgb.text("Temperature (ºC)")
tgb.text("{realtime['device_temperature'].item()}", format="%.0f")
tgb.text("Voltage (V)")
tgb.text("{realtime['generator_voltage'].item()}", format="%.1f")
tgb.text("Current (A)")
tgb.text("{realtime['generator_current'].item()}", format="%.2f")
tgb.text("#### ⚡️ Grid", mode="md")
with tgb.layout("1 1", class_name="container align-columns-center"):
tgb.text("Voltage (V)")
tgb.text("{realtime['grid_voltage'].item()}", format="%.1f")
tgb.text("Current (A)")
tgb.text("{realtime['grid_current'].item()}", format="%.2f")
tgb.text("#### 🔋 Production", mode="md")
with tgb.layout("1 1", class_name="container align-columns-center"):
tgb.text("Delivered power (W)")
tgb.text("{realtime['delivered_power'].item()}", format="%.0f")
tgb.text("Daily yeld (W)")
tgb.text("{realtime['daily_yeld'].item()}", format="%.0f")
with tgb.part(width="900px"):
tgb.chart("{daily_stats}", mode="line", x="Time", y="Power", color="red", height="400px")
tgb.part(height="20px")
tgb.chart("{monthly_stats}", type="bar", x="Day", y__1="Daily production", y__2="Reference production", color__1="red", color__2="blue", height="400px")
tgb.part(height="20px")
tgb.chart("{yearly_stats}", type="bar", x="Month", y__1="Monthly production", y__2="Reference production", color__1="red", color__2="blue", height="400px")
return page
# Reader thread: read values and update the gui
class read(Thread):
def __init__(self, gui):
Thread.__init__(self)
self.gui = gui
def run(self):
global realtime, daily_stats, monthly_stats, yearly_stats
while True:
# Wait until the gui is running. Should wait only at startup
if hasattr(self.gui, "_server") and state_id:
tp.gui.invoke_callback(self.gui, state_id, update_values)
# Force garbage collector
gc.collect()
# Interval between gui updates
time.sleep(delay)
# Get the state id
def on_init(state):
global state_id
state_id = tp.gui.get_state_id(state)
# Initialize variables with the correct datatype
state.daily_stats = daily_stats
state.monthly_stats = monthly_stats
state.yearly_stats = yearly_stats
state.realtime = realtime
# Buttons callbacks. The date will be set by change_date
def yesterday(state): change_date(state, "yesterday", date)
def today(state): change_date(state, "today", date)
def tomorrow(state): change_date(state, "tomorrow", date)
# Update the values after a date change
def change_date(state, var, val):
global date
if var == "date":
date = val
elif var == "yesterday":
date -= timedelta(days=1)
elif var == "tomorrow":
date += timedelta(days=1)
elif var == "today":
date = datetime.today().date()
# Trigger gui refresh
update_values(state)
# Update the values within the state
def update_values(state):
# Read stats from DB. Updates graphs only if changed, to avoid unnecessary flickering
if not (daily_stats := db.pread_daily_details(date)).equals(state.daily_stats): state.daily_stats = daily_stats
if not (monthly_stats := db.pread_monthly_stats(date)).equals(state.monthly_stats): state.monthly_stats = monthly_stats
if not (yearly_stats := db.pread_yearly_stats(date)).equals(state.yearly_stats): state.yearly_stats = yearly_stats
state.realtime = db.pread_realtime()
state.date = date
if __name__ == "__main__":
# Create the gui object (here because needed by the read thread)
gui = tp.Gui(create_page())
# Start reader thread
read(gui).start()
# Start webui
tp.run(gui, title="PVM", favicon="favicon.png", single_client=True, host="0.0.0.0", port=9000)