Skip to content

Commit

Permalink
feat: create alert screen pages
Browse files Browse the repository at this point in the history
  • Loading branch information
chloeskt committed Mar 28, 2021
1 parent 4862c33 commit 3839b4b
Show file tree
Hide file tree
Showing 9 changed files with 490 additions and 76 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ venv.bak/
.spyderproject
.spyproject

# Pycharm project settings
.idea/

# Rope project settings
.ropeproject

Expand Down
229 changes: 210 additions & 19 deletions app/alert_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.

"""
The following Python file is dedicated to the big screen of the web application.
The big screen corresponds to a web page which will be displayed on a big screen in the CODIS room. There will be no
The following Python file is dedicated to the alert screen of the web application.
The alert screen corresponds to a web page which will be displayed on a big screen in the CODIS room. There will be no
interaction with the user. The main use of this page is to display a "sober" screen when there are no alerts. When an
alert pops out, the screen will automatically change to display various information.
Expand All @@ -20,34 +20,225 @@
import dash_core_components as dcc
import dash_html_components as html

# From navbar.py to add the navigation bar at the top of the page
from navbar import Navbar

# Importing alerts map builder from alerts.py
from alerts import build_alerts_map
# ----------------------------------------------------------------------------------------------------------------------
# CONTENT
def build_no_alert_detected_screen():
"""
The following function builds the no alert screen.
"""
# background image as style
style = {
"backgroundImage": 'url("/assets/pyro_alert_off.png")',
"backgroundRepeat": "no-repeat",
"backgroundPosition": "center",
"backgroundSize": "cover",
"position": "fixed",
"height": "100%",
"width": "100%",
}

# Importing risks map and opacity slider builders from risks.py
from risks import build_risks_map, build_opacity_slider
return style

# Importing plotly fig objects from graphs.py
from graphs import generate_meteo_fig

# Importing layer style button builder and fetched API data from utils.py
from utils import build_layer_style_button, build_live_alerts_metadata
def build_alert_detected_screen(img_url, alert_metadata, last_alert):
"""
This function is used in the main.py file to create the alert screen when its on, i.e. when there is an alert
ongoing.
It takes as arguments:
# ----------------------------------------------------------------------------------------------------------------------
# CONTENT
- 'img_url': the URL address of the alert frame to be displayed on the left of the map;
- 'alert_metadata': a dictionary containing metadata about the ongoing alert
- 'last_alert': pd.DataFrame of the last alert
All these inputs are instantiated in the main.py file via a call to the API.
"""
# Get lat and lon from last_alert
lat, lon = last_alert["lat"], last_alert["lon"]

# Get device id for last_alert
device_id = last_alert["device_id"]

# Background image
background_image = html.Img(
id="alert_background",
src="/assets/pyro_alert_on.png",
style={
"position": "fixed",
"width": "100vw",
"height": "100vh",
},
)

# Fire icon
fire_icon = html.Img(
id="fire_icon",
src="/assets/pyro_fire_logo.png",
className="blink-image",
style={"height": "100%"},
)

# Detection frames
alert_frame = html.Img(
id="alert_frame",
src=img_url,
style={
"position": "relative",
"width": "100%",
"height": "100%",
"object-fit": "contain",
},
)

# Fire alert image div (right of the screen)
# Multiple frames are rendered here (to make it look like a GIF)
fire_images_div = html.Div(
id="fire_alert_div",
children=[
alert_frame,
dcc.Interval(id="interval-component-img-refresh", interval=3 * 1000),
],
style={"display": "flex", "height": "100%", "width": "100%"},
)

# Alert metadata div
alert_metadata_div = html.Div(
children=[
html.P("Tour: {}".format(alert_metadata["site_name"])),
html.P("Coordonnées de la tour: {}, {}".format(lat, lon)),
html.P("Id de caméra: {}".format(device_id)),
html.P("Azimuth: {}".format(alert_metadata["azimuth"])),
]
)

# Fire text div (left part of screen)
fire_text_div = html.Div(
id="fire_text_div",
children=[
html.Div(
html.P(
"DFCI: KD62D6.5",
),
style={
"font-size": "2vw",
"color": "#054546",
"font-weight": "bold",
},
),
html.Div(
alert_metadata_div,
style={
"font-size": "1.75vw",
"color": "#054546",
},
),
],
style={
"margin-top": "5%",
},
)

# Final layout: one row containing 2 columns, and each column contains two rows
layout_div = [
background_image,
dbc.Row(
children=[
dbc.Col(
id="col_fire_text",
children=[
dbc.Row(
id="fire_icon_rwo",
children=fire_icon,
style={
"display": "flex",
"justify-content": "center",
"height": "30%",
},
),
dbc.Row(
id="fire_text_row",
children=fire_text_div,
style={
"display": "flex",
"justify-content": "center",
"margin-right": "2.5%",
},
),
],
style={
"width": "50%",
"margin": "2.5%",
},
),
dbc.Col(
id="col_image_fire",
children=[
dbc.Row(
html.Div(
html.Div(
html.P("DÉPART DE FEU"),
style={
"font-size": "4vw",
"color": "#fd4848",
"font-weight": "bold",
},
className="blink-image",
),
),
style={
"display": "flex",
"justify-content": "center",
"padding-bottom": "7%",
},
),
dbc.Row(
id="fire_images_row",
children=fire_images_div,
style={
"display": "flex",
"justify-content": "center",
"margin-right": "2.5%",
},
),
],
style={
"width": "50%",
"margin": "2.5%",
},
),
],
style={
"height": "100%",
},
),
]

style = {
"height": "100%",
"width": "100%",
"position": "fixed",
}

return layout_div, style


# ----------------------------------------------------------------------------------------------------------------------
# App layout
# The following block gathers elements defined above and returns them via the BigScreen function


def Bigscreen():
# The following block gathers elements defined above and returns them via the alert_screen function
def alert_screen():
"""
The following function is used in the main.py file to build the layout of the big screen page.
"""
raise NotImplementedError
layout = html.Div(
children=[
dcc.Interval(id="interval-component-alert-screen", interval=3 * 1000),
html.Div(id="core_layout_alert_screen", children=[]),
],
style={
"height": "100%",
"width": "100%",
"position": "fixed",
},
)
return layout
Binary file added app/assets/pyro_alert_on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/pyro_fire_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions app/assets/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Firefox old */
@-moz-keyframes blink {
0% {
opacity: 1;
}

50% {
opacity: 0;
}

100% {
opacity: 1;
}
}

@-webkit-keyframes blink {
0% {
opacity: 1;
}

50% {
opacity: 0;
}

100% {
opacity: 1;
}
}

/* IE */
/* csslint ignore:start */
@-ms-keyframes blink {
0% {
opacity: 1;
}

50% {
opacity: 0;
}

100% {
opacity: 1;
}
}
/* csslint ignore:end */

/* Opera and prob css3 final iteration */
@keyframes blink {
0% {
opacity: 1;
}

50% {
opacity: 0;
}

100% {
opacity: 1;
}
}

.blink-image {
-moz-animation: blink normal 1s infinite ease-in-out; /* Firefox */
-webkit-animation: blink normal 1s infinite ease-in-out; /* Webkit */
-ms-animation: blink normal 1s infinite ease-in-out; /* IE */
animation: blink normal 1s infinite ease-in-out; /* Opera and prob css3 final iteration */
}
6 changes: 0 additions & 6 deletions app/homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,6 @@ def Homepage():
# Map object added here
html.Div(build_alerts_map(), id='hp_map'),

# Interval object triggering api calls every 10 seconds
dcc.Interval(
id='interval-component',
interval=10 * 1000, # Timestep in milliseconds
n_intervals=0),

# Two placeholders updated by callbacks in main.py to trigger a change in map style
html.Div(id='map_style_btn_switch_view'), # Associated with the main map style button
html.Div(id='alert_btn_switch_view'), # Associated with the alert banner in risks mode
Expand Down
Loading

0 comments on commit 3839b4b

Please sign in to comment.