Spaces:
Runtime error
Runtime error
# Note: Main must be imported even though it is not used. | |
from h2o_wave import Q, ui, app, main, data, on | |
import numpy as np | |
import pandas as pd | |
import random | |
import time | |
import asyncio | |
NUMBER_SENSORS = 4 | |
LIMIT_LEN_SHOWING = 20 | |
REALTIME_UPDATE = 5 # seconds | |
list_data = [] | |
line_charts_data = [] # [(sensor_id, [data]), ...] | |
for i in range(NUMBER_SENSORS): | |
line_charts_data.append((i, [])) | |
start_year = 1991 | |
while True: | |
for i in range(NUMBER_SENSORS): | |
random_value = random.uniform(1, 50) # Generate a random value between 1 and 50 | |
value = (str(start_year), random_value) | |
line_charts_data[i][1].append(value) | |
start_year += 1 | |
if start_year == 2021: | |
break | |
async def update_value(q: Q): | |
while True: | |
time.sleep(REALTIME_UPDATE) | |
# TODO: Update realtime values for current stats cards | |
# value_counts = random.randint(0, 100) | |
# percentages = random.random() | |
percentages = np.random.random(NUMBER_SENSORS) | |
value_counts = np.random.randint(0, 100, NUMBER_SENSORS) | |
show_multiple_stats_cards(q, value_counts, percentages) | |
await q.page.save() | |
async def api_get_data(): | |
global list_data, line_charts_data, start_year | |
while True: | |
for i in range(NUMBER_SENSORS): | |
random_value = random.uniform(1, 50) # Generate a random value between 1 and 50 | |
value = (str(start_year), random_value) | |
line_charts_data[i][1].append(value) | |
start_year += 1 | |
await asyncio.sleep(REALTIME_UPDATE) | |
async def update_charts(q: Q): | |
global line_charts_data | |
while True: | |
time.sleep(REALTIME_UPDATE) | |
for sensor_data in line_charts_data: | |
sensor_id = str(sensor_data[0]) | |
data = sensor_data[1] | |
limites_showing_data = LIMIT_LEN_SHOWING if len(data) > LIMIT_LEN_SHOWING else len(data) | |
show_line_graph(q, sensor_id, data[-limites_showing_data:]) | |
percentages = np.random.random(NUMBER_SENSORS) | |
value_counts = np.random.randint(0, 100, NUMBER_SENSORS) | |
show_multiple_stats_cards(q, value_counts, percentages) | |
await q.page.save() | |
def on_startup(): | |
print('App started!') | |
def on_shutdown(): | |
print('App stopped!') | |
task_data = asyncio.create_task(api_get_data()) | |
async def sever(q: Q): | |
apply_layout(q) | |
show_homepage(q) | |
# show_histograms(q, df, index=[1, 7, 8]) | |
# await update_value(q) | |
await update_charts(q) | |
# await q.page.save() | |
def show_homepage(q: Q): | |
q.page['header'] = ui.header_card( | |
box=ui.box('header', width='100%', height='86px'), | |
icon='Video360Generic', | |
icon_color='White', | |
title='AgroTrack Application', | |
subtitle='๋ด์๋์ ๊ธฐ์ ์ผํฐ') | |
q.page['footer'] = ui.footer_card( | |
box='footer', | |
caption='Copyright (C) [AISeed](https://sprout-fibre-be6.notion.site/AISEED-40e62bb70c024a2c974c0a7051aca86f?pvs=4) Designed by [Blackhole](https://github.com/andrewlee1807/)') | |
def apply_layout(q: Q): | |
q.page['meta'] = ui.meta_card(box='', theme='oceanic', title="SmartFarm's Sensor Dashboard", | |
layouts=[ | |
ui.layout( | |
breakpoint='xl', | |
width='1600px', | |
zones=[ | |
ui.zone('header'), | |
ui.zone('body', direction=ui.ZoneDirection.ROW, zones=[ | |
ui.zone('content', direction=ui.ZoneDirection.COLUMN, zones=[ | |
ui.zone('section1'), | |
ui.zone('top', size='300px', direction=ui.ZoneDirection.ROW), | |
ui.zone('section2'), | |
ui.zone('bottom', direction=ui.ZoneDirection.ROW), | |
ui.zone('chart1', direction=ui.ZoneDirection.ROW), | |
]), | |
]), | |
ui.zone('footer') | |
]), | |
]) | |
## Making stats cards | |
def make_stats_card_data(q: Q, column): | |
value_counts = column.value_counts() | |
total = value_counts.sum() | |
return value_counts[1], total | |
# Randomly generate data for stats cards: percentage and value (randomly generated) | |
def show_stats_card(q: Q, name, value_count, percentage): | |
q.page['stat_' + name] = ui.tall_gauge_stat_card( | |
box=ui.box('top', width='12.5%'), | |
title='Number of houses with ' + name, | |
value='={{intl one}}', | |
aux_value='={{intl perc style="percent" minimum_fraction_digits=2 maximum_fraction_digits=2 }}', | |
progress=percentage, | |
data=dict(one=int(value_count), perc=float(percentage)), | |
plot_color='$red' | |
) | |
def show_multiple_stats_cards(q: Q, value_counts, percentages): | |
for i, j in enumerate(zip(value_counts, percentages)): | |
name = "feature_" + str(i) | |
value_count, percentage = j | |
show_stats_card(q, name, value_count, percentage) | |
# Making histograms | |
def make_histogram_data(values): | |
count, division = np.histogram(values) | |
return [(x, y) for x, y in zip(division.tolist(), count.tolist())] | |
def show_histogram(q: Q, values, variable_name, index): | |
q.page['feat' + str(index)] = ui.tall_series_stat_card( | |
box=ui.box('bottom', width='25%'), | |
title='Linear tall series' + variable_name, | |
value='=${{intl qux minimum_fraction_digits=2 maximum_fraction_digits=2}}', | |
aux_value='={{intl quux style="percent" minimum_fraction_digits=1 maximum_fraction_digits=1}}', | |
data=dict(qux=800, quux=80 / 100), | |
plot_type='area', | |
plot_category='foo', | |
plot_value='qux', | |
plot_color='$yellow', | |
plot_data=data('foo qux', 3, rows=[[90, 0.9], [50, 0.5], [80, 0.8]]), | |
plot_zero_value=0, | |
plot_curve='smooth', | |
) | |
def show_line_graph(q: Q, name, data_rows): | |
q.page['section2'] = ui.section_card(box='section2', | |
title='Plot of the data', | |
subtitle='') | |
position = 'bottom' if int(name) < 2 else 'chart1' | |
q.page[name] = ui.plot_card( | |
box=ui.box(position, width='50%'), | |
title='Sensor ' + name, | |
animate=True, | |
data=data('time value', LIMIT_LEN_SHOWING, rows=data_rows), | |
events=['select_marks'], | |
plot=ui.plot([ | |
ui.mark(type='line', | |
x_scale='time', | |
x='=time', | |
y='=value', | |
y_min=0, interactive=True), | |
ui.mark(type='point', | |
x='=time', | |
# x='={{intl year type="time" month="numeric" day="numeric" hour="numeric" minute="numeric" hourCycle="h24" }}', | |
y='=value', | |
size=4, | |
fill_color='#FFFF28', | |
x_title='Time', y_title='Value', | |
interactive=True), | |
]), | |
) | |
async def on_marks_selected(q: Q): | |
print("Click") | |