Skip to content

Commit 76894b7

Browse files
committed
Add Temporal Chart
1 parent 1992710 commit 76894b7

4 files changed

Lines changed: 163 additions & 27 deletions

File tree

app/app.js

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,31 +51,29 @@ app.use(express.urlencoded({ extended: false }));
5151
app.use(cookieParser());
5252
app.use(flash());
5353

54-
if (!sessionOff) {
55-
if (process.env.NODE_ENV === 'production') {
56-
// Use Mongo-DB to store session data.
57-
app.use(
58-
session({
59-
resave: false,
60-
saveUninitialized: true,
61-
secret: SECRET,
62-
store: MongoStore.create({
63-
mongoUrl: MONGO_DB + '/sessions',
64-
mongooseConnection: mongoose.connection,
65-
ttl: 14 * 24 * 60 * 60 // save session for 14 days
66-
})
67-
})
68-
);
69-
} else {
70-
// Use Memstore for session data.
71-
app.use(
72-
session({
73-
secret: SECRET,
74-
resave: false,
75-
saveUninitialized: true
54+
if (process.env.NODE_ENV === 'production' && !sessionOff) {
55+
// Use Mongo-DB to store session data.
56+
app.use(
57+
session({
58+
resave: false,
59+
saveUninitialized: true,
60+
secret: SECRET,
61+
store: MongoStore.create({
62+
mongoUrl: MONGO_DB + '/sessions',
63+
mongooseConnection: mongoose.connection,
64+
ttl: 14 * 24 * 60 * 60 // save session for 14 days
7665
})
77-
);
78-
}
66+
})
67+
);
68+
} else {
69+
// Use Memstore for session data.
70+
app.use(
71+
session({
72+
secret: SECRET,
73+
resave: false,
74+
saveUninitialized: true
75+
})
76+
);
7977
}
8078

8179
app.use(express.static(path.join(__dirname, 'public')));

app/controllers/ngsi-ld/agri-device.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,48 @@ async function displayAgriDevice(req, res) {
1818
{ options: 'keyValues' },
1919
ngsiLD.setHeaders(req.session.access_token, LinkHeader)
2020
);
21-
return res.render('agri-device', { title: device.name, device });
21+
22+
const controlledProperties = device.controlledProperty;
23+
const chartData = {};
24+
let timeseries = null;
25+
26+
try {
27+
timeseries = await ngsiLD.readTemporalEntity(
28+
req.params.id,
29+
{
30+
options: 'temporalValues',
31+
attrs: device.controlledProperty.join(',')
32+
},
33+
ngsiLD.setHeaders(req.session.access_token, LinkHeader)
34+
);
35+
36+
controlledProperties.forEach((key) => {
37+
let addData = false;
38+
39+
if (Array.isArray(timeseries[key].values)) {
40+
addData = timeseries[key].values[0].length === 2;
41+
}
42+
43+
if (addData) {
44+
const data = [];
45+
const labels = [];
46+
const color = [];
47+
48+
const values = timeseries[key].values.reverse();
49+
values.forEach((element) => {
50+
const date = new Date(element[1]);
51+
data.push({ t: element[1], y: element[0] });
52+
labels.push(date.toISOString().slice(11, 16));
53+
color.push('#45d3dd');
54+
});
55+
56+
chartData[key] = { data, labels, color };
57+
}
58+
});
59+
} catch (e) {
60+
debug(e);
61+
}
62+
return res.render('agri-device', { title: device.name, device, timeseries, chartData });
2263
} catch (error) {
2364
const errorDetail = error.error | error;
2465
debug(errorDetail);

app/lib/ngsi-ld.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,28 @@ function listEntities(opts, headers = {}) {
184184
});
185185
}
186186

187+
function readTemporalEntity(entityId, opts, headers = {}) {
188+
return fetch(`${BASE_PATH}/temporal/entities/${entityId}/?${new URLSearchParams(opts)}`, {
189+
method: 'GET',
190+
headers
191+
})
192+
.then((r) => parse(r).then((data) => ({ status: r.status, body: data })))
193+
.then((data) => {
194+
if (data.status !== 200) {
195+
throw new Error('', { cause: data.body });
196+
}
197+
return data.body;
198+
});
199+
}
200+
187201
module.exports = {
188202
createAttribute,
189203
readAttribute,
190204
updateAttribute,
191205
deleteAttribute,
192206
createEntity,
193207
readEntity,
208+
readTemporalEntity,
194209
updateEntity,
195210
deleteEntity,
196211
listEntities,

app/views/agri-device.pug

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ extends layout
33
block content
44
h1= title
55

6+
script(src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js')
7+
script(src='https://cdn.jsdelivr.net/npm/chart.js@2.7.2/dist/Chart.min.js')
8+
script(src='https://code.jquery.com/jquery-1.11.1.js')
9+
610
div.row
711
div.col
812
div(class="card m-2")
@@ -53,10 +57,88 @@ block content
5357
dt.col-lg-3 Status:
5458
dd.col-lg-9 #{device.status}
5559

60+
- if (timeseries)
61+
div()
62+
- if (device.heartRate)
63+
div(style="float: left;")
64+
h2 Heart Rate
65+
canvas(id="heartRate" width="800px" height="400px")
66+
- if (device.humidity)
67+
div(style="float: left;")
68+
h2 Humidity
69+
canvas(id="humidity" width="800px" height="400px")
70+
- if (device.fillingLevel)
71+
div(style="float: left;")
72+
h2 Filling Level
73+
canvas(id="fillingLevel" width="800px" height="400px")
74+
- if (device.temperature)
75+
div(style="float: left;")
76+
h2 Temperature
77+
canvas(id="temperature" width="800px" height="400px")
78+
div(style="clear: both;")
79+
5680
div.row
5781
div.col
5882
div(class="card m-2")
5983
div.card-body
60-
summary.list-unstyled
84+
summary.list-unstyled Entity
6185
details
62-
pre #{JSON.stringify(device, null, 4)}
86+
pre #{JSON.stringify(device, null, 4)}
87+
88+
- if (timeseries)
89+
div.row
90+
div.col
91+
div(class="card m-2")
92+
div.card-body
93+
summary.list-unstyled Temporal Entity
94+
details
95+
pre #{JSON.stringify(timeseries, null, 4)}
96+
97+
98+
- if (timeseries)
99+
script(type='text/javascript').
100+
101+
var chartData =!{JSON.stringify(chartData)};
102+
103+
var text = {
104+
heartRate : "bpm",
105+
humidity: "%",
106+
temperature: "C",
107+
fillingLevel: '%'
108+
109+
}
110+
111+
Object.keys(chartData).forEach((key) => {
112+
var values = chartData[key];
113+
var ctx = document.getElementById(key);
114+
var barChart = new Chart(ctx, {
115+
type: "line",
116+
data: {
117+
labels: values.labels,
118+
datasets: [{
119+
fill: false,
120+
label: text[key] || '%',
121+
data: values.data,
122+
backgroundColor : '#45d3dd',
123+
borderColor : '#45d3dd',
124+
pointRadius : 5
125+
}]
126+
},
127+
options: {
128+
responsive: false,
129+
scales: {
130+
xAxes: [{
131+
ticks: {
132+
source: "labels"
133+
}
134+
}],
135+
yAxes: [{
136+
ticks: {
137+
beginAtZero: true
138+
}
139+
}]
140+
}
141+
}
142+
});
143+
var chart = new Chart(ctx, cfg);
144+
});

0 commit comments

Comments
 (0)