Skip to content

Commit

Permalink
Adding ATN state as a new plot
Browse files Browse the repository at this point in the history
  • Loading branch information
thdfw committed Jan 5, 2025
1 parent fbb7243 commit 575415f
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 31 deletions.
11 changes: 9 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

try {
const response = await fetch(`https://visualizer.electricity.works/plots`, {
// const response = await fetch('http://localhost:8000/download_excel', {
// const response = await fetch('http://localhost:8000/plots', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
Expand Down Expand Up @@ -204,6 +204,7 @@
const plotsDiv6 = document.getElementById('Plot6');
const plotsDiv7 = document.getElementById('Plot7');
const plotsDiv8 = document.getElementById('Plot8');
const plotsDiv9 = document.getElementById('Plot9');
const plotsDivPng = document.getElementById('PlotPng');
plotsDiv1.innerHTML = '';
plotsDiv2.innerHTML = '';
Expand All @@ -213,6 +214,7 @@
plotsDiv6.innerHTML = '';
plotsDiv7.innerHTML = '';
plotsDiv8.innerHTML = '';
plotsDiv9.innerHTML = '';
plotsDivPng.innerHTML = '';

let iframeCount = 0;
Expand Down Expand Up @@ -246,6 +248,8 @@
plotsDiv7.appendChild(iframe);
} else if (iframeCount === 7) {
plotsDiv8.appendChild(iframe);
} else if (iframeCount === 8) {
plotsDiv9.appendChild(iframe);
}
iframeCount++;
} else if (filename.endsWith('.png')) {
Expand Down Expand Up @@ -431,6 +435,7 @@
const plotsDiv6 = document.getElementById('Plot6');
const plotsDiv7 = document.getElementById('Plot7');
const plotsDiv8 = document.getElementById('Plot8');
const plotsDiv9 = document.getElementById('Plot9');
const plotsDivPng = document.getElementById('PlotPng');
plotsDiv1.innerHTML = '';
plotsDiv2.innerHTML = '';
Expand All @@ -440,6 +445,7 @@
plotsDiv6.innerHTML = '';
plotsDiv7.innerHTML = '';
plotsDiv8.innerHTML = '';
plotsDiv9.innerHTML = '';
plotsDivPng.innerHTML = '';
const toggleButton = document.getElementById('toggle-mode');
document.body.classList.toggle('dark-mode');
Expand Down Expand Up @@ -496,7 +502,7 @@
font-family: 'Montserrat';
}

#PlotPng, #Plot1, #Plot2, #Plot3, #Plot4, #Plot5, #Plot6, #Plot7, #Plot8 {
#PlotPng, #Plot1, #Plot2, #Plot3, #Plot4, #Plot5, #Plot6, #Plot7, #Plot8, #Plot9 {
display: flex;
justify-content: center;
padding-bottom:15px;
Expand Down Expand Up @@ -1013,6 +1019,7 @@ <h2 id="houseAliasHeader"></h2>
<div id="Plot6"></div>
<div id="Plot7"></div>
<div id="Plot8"></div>
<div id="Plot9"></div>
<div id="PlotPng"></div>
</div>

Expand Down
169 changes: 140 additions & 29 deletions visualizer_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,19 @@ def to_hex(rgba):
}
top_modes_order = ['HomeAlone', 'Atn', 'Dormant']

aa_modes_colors_hex = {
'HpOffStoreDischarge': '#EF553B',
'HpOffStoreOff': '#00CC96',
'HpOnStoreOff': '#636EFA',
'HpOnStoreCharge': '#feca52',
'WaitingNoElec': '#a3a3a3',
'WaitingElec': '#4f4f4f',
'Dormant': '#4f4f4f'
}
aa_modes_order = [
'HpOffStoreDischarge', 'HpOffStoreOff', 'HpOnStoreOff', 'HpOnStoreCharge', 'WaitingNoElec', 'WaitingElec', 'Dormant'
]

# ------------------------------
# Pull data from journaldb
# ------------------------------
Expand All @@ -167,14 +180,14 @@ def get_data(request):
"success": False,
"message": "Wrong password.",
"reload":True
}, 0, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0

if request.house_alias == '':
return {
"success": False,
"message": "Please enter a house alias.",
"reload": True
}, 0, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0

if not request.continue_option:
if (request.end_ms - request.start_ms)/1000/60/60/24 > MAX_DAYS_WARNING:
Expand All @@ -186,22 +199,22 @@ def get_data(request):
"message": warning_message,
"reload":False,
"continue_option": True,
}, 0, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0

if not RUNNING_LOCALLY:
if (request.end_ms - request.start_ms)/1000/60/60/24 > 5 and isinstance(request, DataRequest):
return {
"success": False,
"message": "That's too many days to plot.",
"reload": False,
}, 0, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0

if (request.end_ms - request.start_ms)/1000/60/60/24 > 21 and isinstance(request, CsvRequest):
return {
"success": False,
"message": "That's too many days of data to download.",
"reload": False,
}, 0, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0

if MESSAGE_SQL:

Expand All @@ -222,7 +235,7 @@ def get_data(request):
"success": False,
"message": f"No data found for house '{request.house_alias}' in the selected timeframe.",
"reload":False
}, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0

channels = {}
for message in messages:
Expand All @@ -231,7 +244,7 @@ def get_data(request):
"success": False,
"message": f"Timeout: getting the data took too much time.",
"reload":False
}, 0, 0, 0, 0, 0
}, 0, 0, 0, 0, 0, 0, 0
for channel in message.payload['ChannelReadingList']:
# Find the channel name
if message.message_type_name == 'report':
Expand Down Expand Up @@ -437,6 +450,24 @@ def get_data(request):
top_modes['all']['values'].append(top_modes_order.index(state))
top_modes[state]['times'].append(time)
top_modes[state]['values'].append(top_modes_order.index(state))
aa_modes = {}
if 'a.aa' in relays:
aa_modes['all'] = {}
aa_modes['all']['times'] = []
aa_modes['all']['values'] = []
formatted_times = [pendulum.from_timestamp(x/1000, tz='America/New_York') for x in relays['a.aa']['times']]
for state in [x for x in aa_modes_order if x in list(set(relays['a.aa']['values']))]:
aa_modes[state] = {}
aa_modes[state]['times'] = []
aa_modes[state]['values'] = []

for time, state in zip(formatted_times, relays['a.aa']['values']):
if state in aa_modes_order:
aa_modes['all']['times'].append(time)
aa_modes['all']['values'].append(aa_modes_order.index(state))
aa_modes[state]['times'].append(time)
aa_modes[state]['values'].append(aa_modes_order.index(state))
print(aa_modes.keys())

if "Dormant" in top_modes:
top_modes['Admin'] = top_modes['Dormant']
Expand All @@ -450,7 +481,7 @@ def get_data(request):
min_time_ms_dt = min_time_ms_dt.tz_convert('America/New_York').replace(tzinfo=None)
max_time_ms_dt = max_time_ms_dt.tz_convert('America/New_York').replace(tzinfo=None)

return "", channels, zones, modes, top_modes, min_time_ms_dt, max_time_ms_dt
return "", channels, zones, modes, top_modes, aa_modes, min_time_ms_dt, max_time_ms_dt

# ------------------------------
# Export as CSV
Expand All @@ -462,7 +493,7 @@ async def get_csv(request: CsvRequest, apirequest: Request):
try:
async with async_timeout.timeout(TIMEOUT_SECONDS):

error_msg, channels, _, __, ___, ____, _____ = await asyncio.to_thread(get_data, request)
error_msg, channels, _, __, ___, ____, _____, ______ = await asyncio.to_thread(get_data, request)
print(f"Time to fetch data: {round(time.time() - request_start,2)} sec")

if time.time() - request_start > TIMEOUT_SECONDS:
Expand Down Expand Up @@ -620,7 +651,7 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
try:
async with async_timeout.timeout(TIMEOUT_SECONDS):

error_msg, channels, zones, modes, top_modes, min_time_ms_dt, max_time_ms_dt = await asyncio.to_thread(get_data, request)
error_msg, channels, zones, modes, top_modes, aa_modes, min_time_ms_dt, max_time_ms_dt = await asyncio.to_thread(get_data, request)
print(f"Time to fetch data: {round(time.time() - request_start,2)} sec")

if error_msg != '':
Expand Down Expand Up @@ -1505,7 +1536,86 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
html_buffer6.seek(0)

# --------------------------------------
# PLOT 7: HomeAlone
# PLOT 7: Top State
# --------------------------------------

if time.time() - request_start > TIMEOUT_SECONDS:
raise asyncio.TimeoutError('Timed out')
if await apirequest.is_disconnected():
raise asyncio.CancelledError("Client disconnected.")

fig = go.Figure()

if top_modes!={}:

fig.add_trace(
go.Scatter(
x=top_modes['all']['times'],
y=top_modes['all']['values'],
mode='lines',
line=dict(color=home_alone_line, width=2),
opacity=0.3,
showlegend=False,
line_shape='hv'
)
)

for state in top_modes.keys():
if state != 'all' and state in top_modes_colors_hex:
fig.add_trace(
go.Scatter(
x=top_modes[state]['times'],
y=top_modes[state]['values'],
mode='markers',
marker=dict(color=top_modes_colors_hex[state], size=10),
opacity=0.8,
name=state,
)
)

fig.update_layout(
title=dict(text='Top State', x=0.5, xanchor='center'),
plot_bgcolor=plot_background_hex,
paper_bgcolor=plot_background_hex,
font_color=fontcolor_hex,
title_font_color=fontcolor_hex,
margin=dict(t=30, b=30),
xaxis=dict(
range=[min_time_ms_dt, max_time_ms_dt],
mirror=True,
ticks='outside',
showline=True,
linecolor=fontcolor_hex,
showgrid=False
),
yaxis=dict(
range = [-0.6, len(top_modes)-1+0.2],
mirror=True,
ticks='outside',
showline=True,
linecolor=fontcolor_hex,
zeroline=False,
showgrid=True,
gridwidth=1,
gridcolor=gridcolor_hex,
tickvals=list(range(len(top_modes)-1)),
),
legend=dict(
x=0,
y=1,
xanchor='left',
yanchor='top',
orientation='h',
bgcolor='rgba(0, 0, 0, 0)'
)
)

html_buffer7 = io.StringIO()
fig.write_html(html_buffer7)
html_buffer7.seek(0)

# --------------------------------------
# PLOT 8: HomeAlone
# --------------------------------------

if time.time() - request_start > TIMEOUT_SECONDS:
Expand Down Expand Up @@ -1579,12 +1689,12 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
)
)

html_buffer7 = io.StringIO()
fig.write_html(html_buffer7)
html_buffer7.seek(0)
html_buffer8 = io.StringIO()
fig.write_html(html_buffer8)
html_buffer8.seek(0)

# --------------------------------------
# PLOT 8: Top State
# PLOT 9: Atomic Ally
# --------------------------------------

if time.time() - request_start > TIMEOUT_SECONDS:
Expand All @@ -1594,12 +1704,12 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re

fig = go.Figure()

if top_modes!={}:
if aa_modes!={}:

fig.add_trace(
go.Scatter(
x=top_modes['all']['times'],
y=top_modes['all']['values'],
x=aa_modes['all']['times'],
y=aa_modes['all']['values'],
mode='lines',
line=dict(color=home_alone_line, width=2),
opacity=0.3,
Expand All @@ -1608,21 +1718,21 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
)
)

for state in top_modes.keys():
if state != 'all' and state in top_modes_colors_hex:
for state in aa_modes.keys():
if state != 'all' and state in aa_modes_colors_hex:
fig.add_trace(
go.Scatter(
x=top_modes[state]['times'],
y=top_modes[state]['values'],
x=aa_modes[state]['times'],
y=aa_modes[state]['values'],
mode='markers',
marker=dict(color=top_modes_colors_hex[state], size=10),
marker=dict(color=aa_modes_colors_hex[state], size=10),
opacity=0.8,
name=state,
)
)

fig.update_layout(
title=dict(text='Top State', x=0.5, xanchor='center'),
title=dict(text='AtomicAlly State', x=0.5, xanchor='center'),
plot_bgcolor=plot_background_hex,
paper_bgcolor=plot_background_hex,
font_color=fontcolor_hex,
Expand All @@ -1637,7 +1747,7 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
showgrid=False
),
yaxis=dict(
range = [-0.6, len(top_modes)-1+0.2],
range = [-0.6, 8-0.8],
mirror=True,
ticks='outside',
showline=True,
Expand All @@ -1646,7 +1756,7 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
showgrid=True,
gridwidth=1,
gridcolor=gridcolor_hex,
tickvals=list(range(len(top_modes)-1)),
tickvals=list(range(7)),
),
legend=dict(
x=0,
Expand All @@ -1658,9 +1768,9 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
)
)

html_buffer8 = io.StringIO()
fig.write_html(html_buffer8)
html_buffer8.seek(0)
html_buffer9 = io.StringIO()
fig.write_html(html_buffer9)
html_buffer9.seek(0)


except asyncio.TimeoutError:
Expand Down Expand Up @@ -1994,6 +2104,7 @@ async def get_plots(request: Union[DataRequest, DijkstraRequest], apirequest: Re
zip_file.writestr('plot6.html', html_buffer6.read())
zip_file.writestr('plot7.html', html_buffer7.read())
zip_file.writestr('plot8.html', html_buffer8.read())
zip_file.writestr('plot9.html', html_buffer9.read())
# if MATPLOTLIB_PLOT:
# zip_file.writestr(f'plot.png', img_buf.getvalue())
zip_buffer.seek(0)
Expand Down

0 comments on commit 575415f

Please sign in to comment.