Skip to content
Snippets Groups Projects
Commit bef9999f authored by Robert Goldmann's avatar Robert Goldmann
Browse files

Fixed #37 - SensorLineChartTile: show warning icon if last measurement is...

Fixed #37 - SensorLineChartTile: show warning icon if last measurement is longer ago than a configurable timespan
parent 397ad963
No related branches found
No related tags found
No related merge requests found
...@@ -24,4 +24,7 @@ Babel = "==2.8.0" ...@@ -24,4 +24,7 @@ Babel = "==2.8.0"
icalendar = "==4.0.7" icalendar = "==4.0.7"
python-jenkins = "==1.5.0" python-jenkins = "==1.5.0"
# tiles
timeago = "==1.0.15"
[dev-packages] [dev-packages]
...@@ -42,8 +42,11 @@ ...@@ -42,8 +42,11 @@
padding-left: 5%; padding-left: 5%;
} }
.sensorLineChartTile i { .sensorLineChartTile .header-right {
margin-right: 5%; margin-right: 5%;
}
.sensorLineChartTile i {
{% if showAxes %} {% if showAxes %}
font-size: 2.5vmin; font-size: 2.5vmin;
{% else %} {% else %}
...@@ -51,6 +54,32 @@ ...@@ -51,6 +54,32 @@
{% endif %} {% endif %}
} }
.sensorLineChartTile .warning {
display: flex;
flex-direction: row;
color: #FF0000;
padding-right: 2vmin;
align-items: center;
align-self: flex-start;
flex-grow: 1;
justify-content: flex-end;
{% if showAxes %}
padding-top: 1%;
{% else %}
padding-top: 3%;
{% endif %}
}
.sensorLineChartTile .warning i {
font-size: 2.5vmin;
padding-right: 1vmin;
}
.sensorLineChartTile .warning-text {
font-size: 1.5vmin;
}
.sensorLineChartTile .title, .sensorLineChartTile .title,
.sensorLineChartTile .value { .sensorLineChartTile .value {
text-align: left; text-align: left;
...@@ -66,8 +95,16 @@ ...@@ -66,8 +95,16 @@
<div class="value">{{ latest }}{{ unit }}</div> <div class="value">{{ latest }}{{ unit }}</div>
{% endif %} {% endif %}
</div> </div>
{% if timeAgo %}
<div class="warning">
<i class="material-icons icon-warning">warning</i>
<div class="warning-text">{{ timeAgo }}</div>
</div>
{% endif %}
<div class="header-right">
<i class="wi {{ icon }}"></i> <i class="wi {{ icon }}"></i>
</div> </div>
</div>
<div class="chart" id="{{ chartId }}"></div> <div class="chart" id="{{ chartId }}"></div>
</div> </div>
......
...@@ -5,6 +5,7 @@ import uuid ...@@ -5,6 +5,7 @@ import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Dict, Tuple, List from typing import Dict, Tuple, List
from timeago import format
from TheCodeLabs_BaseUtils.MultiCacheKeyService import MultiCacheKeyService from TheCodeLabs_BaseUtils.MultiCacheKeyService import MultiCacheKeyService
from flask import Blueprint from flask import Blueprint
...@@ -30,7 +31,8 @@ class SensorLineChartTile(Tile): ...@@ -30,7 +31,8 @@ class SensorLineChartTile(Tile):
"decimals": 1, "decimals": 1,
"lineColor": "rgba(254, 151, 0, 1)", "lineColor": "rgba(254, 151, 0, 1)",
"fillColor": "rgba(254, 151, 0, 0.2)", "fillColor": "rgba(254, 151, 0, 0.2)",
"showAxes": True "showAxes": True,
"outdatedValueWarningLimitInSeconds": 300 # use -1 to disable warning
} }
UNIT_BY_SENSOR_TYPE = { UNIT_BY_SENSOR_TYPE = {
...@@ -68,7 +70,8 @@ class SensorLineChartTile(Tile): ...@@ -68,7 +70,8 @@ class SensorLineChartTile(Tile):
sensorData = storageLeafService.get_data(cacheKey, self._intervalInSeconds, serviceSettings) sensorData = storageLeafService.get_data(cacheKey, self._intervalInSeconds, serviceSettings)
x, y = self.__prepare_measurement_data(sensorData['sensorValue']) x, y = self.__prepare_measurement_data(sensorData['sensorValue'])
latest = y[-1] if y else '' latestTime = datetime.strptime(x[-1], self.DATE_FORMAT) if x else datetime(year=1970, month=1, day=1, hour=0, minute=0, second=0)
latestValue = y[-1] if y else ''
minValue, maxValue = self.__get_min_and_max(pageName, minValue, maxValue = self.__get_min_and_max(pageName,
sensorData['sensorInfo']['type'], sensorData['sensorInfo']['type'],
...@@ -87,14 +90,15 @@ class SensorLineChartTile(Tile): ...@@ -87,14 +90,15 @@ class SensorLineChartTile(Tile):
ghostTraceY = [minValue, minValue] ghostTraceY = [minValue, minValue]
return { return {
'latest': latest, 'latest': latestValue,
'x': x, 'x': x,
'y': y, 'y': y,
'sensorInfo': sensorData['sensorInfo'], 'sensorInfo': sensorData['sensorInfo'],
'min': minValue, 'min': minValue,
'max': maxValue, 'max': maxValue,
'ghostTraceX': ghostTraceX, 'ghostTraceX': ghostTraceX,
'ghostTraceY': ghostTraceY 'ghostTraceY': ghostTraceY,
'latestTime': latestTime
} }
def __get_min_and_max(self, pageName: str, sensorType: Dict, def __get_min_and_max(self, pageName: str, sensorType: Dict,
...@@ -152,6 +156,14 @@ class SensorLineChartTile(Tile): ...@@ -152,6 +156,14 @@ class SensorLineChartTile(Tile):
days = int(self._settings['numberOfHoursToShow'] / 24) days = int(self._settings['numberOfHoursToShow'] / 24)
title = f'{title} - {days} days' title = f'{title} - {days} days'
now = datetime.now()
timeAgo = ''
outdatedValueWarningLimitInSeconds = self._settings['outdatedValueWarningLimitInSeconds']
if outdatedValueWarningLimitInSeconds > 0:
timeDifference = now - data['latestTime']
if timeDifference.total_seconds() > outdatedValueWarningLimitInSeconds:
timeAgo = format(timeDifference)
return Tile.render_template(os.path.dirname(__file__), __class__.__name__, return Tile.render_template(os.path.dirname(__file__), __class__.__name__,
x=data['x'], x=data['x'],
y=data['y'], y=data['y'],
...@@ -167,7 +179,8 @@ class SensorLineChartTile(Tile): ...@@ -167,7 +179,8 @@ class SensorLineChartTile(Tile):
chartId=str(uuid.uuid4()), chartId=str(uuid.uuid4()),
ghostTraceX=data['ghostTraceX'], ghostTraceX=data['ghostTraceX'],
ghostTraceY=data['ghostTraceY'], ghostTraceY=data['ghostTraceY'],
showAxes=self._settings['showAxes']) showAxes=self._settings['showAxes'],
timeAgo=timeAgo)
def __format_date(self, dateTime: str): def __format_date(self, dateTime: str):
parsedDateTime = datetime.strptime(dateTime, self.DATE_FORMAT) parsedDateTime = datetime.strptime(dateTime, self.DATE_FORMAT)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<title>DashboardLeaf</title> <title>DashboardLeaf</title>
{% import 'macros.html' as macros %} {% import 'macros.html' as macros %}
{{ macros.header() }} {{ macros.header(true) }}
</head> </head>
<body> <body>
......
{% macro header() -%} {% macro header(addViewport) -%}
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
...@@ -6,5 +6,7 @@ ...@@ -6,5 +6,7 @@
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/> <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/>
{% if addViewport %}
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
{% endif%}
{%- endmacro %} {%- endmacro %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8">
<title>DashboardLeaf</title> <title>DashboardLeaf</title>
{% import 'macros.html' as macros %}
{{ macros.header(false) }}
<script src="../static/js/libs/socket.io.min.js"></script> <script src="../static/js/libs/socket.io.min.js"></script>
<script src="../static/js/libs/gridstack.min.js"></script> <script src="../static/js/libs/gridstack.min.js"></script>
<script src="../static/js/libs/plotly.min.js"></script> <script src="../static/js/libs/plotly.min.js"></script>
<script src="../static/js/libs/plotly.locale.de.min.js"></script> <script src="../static/js/libs/plotly.locale.de.min.js"></script>
<link type="text/css" rel="stylesheet" href="../static/css/libs/weather-icons.min.css" /> <link type="text/css" rel="stylesheet" href="../static/css/libs/weather-icons.min.css" />
<link type="text/css" rel="stylesheet" href="../static/css/libs/weather-icons-wind.min.css" /> <link type="text/css" rel="stylesheet" href="../static/css/libs/weather-icons-wind.min.css" />
<link type="text/css" rel="stylesheet" href="../static/css/libs/gridstack.min.css" /> <link type="text/css" rel="stylesheet" href="../static/css/libs/gridstack.min.css" />
<link type="text/css" rel="stylesheet" href="../static/css/main.css" />
</head> </head>
<body> <body>
<div class="grid-stack"> <div class="grid-stack">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment