Skip to content

Commit 0e89741

Browse files
committed
added HW 4
1 parent 27eb981 commit 0e89741

File tree

7 files changed

+399
-5
lines changed

7 files changed

+399
-5
lines changed

crowd-sensing/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Crowd sensing
2+
- Check the previous guides: tutorial [1](README.md), tutorial [2](RIOT.md)
3+
- Watch my video on [YouTube](https://youtu.be/mMJN9AqVCzI)
4+
- Read my [blog-post](https://medium.com/@colasante.francesco/3-how-to-connect-an-iot-device-to-thingsboard-using-lorawan-the-thingsnetwork-and-riot-os-46ce20dc7d5b?sk=a74c2984c610f701e5035f5acff2643b) on Medium
5+
6+
# Architecture
7+
![Crowd sensing](https://cdn-images-1.medium.com/max/1200/1*MmoSdsb-oU7MYuFq9tXBZA.png)
8+
9+
## Linear Acceleration Sensor
10+
The LinearAccelerationSensor measures acceleration that is applied to the device hosting the sensor, excluding the contribution of a gravity force. When a device is at rest, for instance, lying flat on the table, the sensor would measure ≈ 0 m/s2 acceleration on three axes.
11+
12+
## Activity recognition Model
13+
After reading several papers about Human Activity recognition (HRA) [1] [2] I decided to use to build a simple model (PoC) using the Linear acceleration sensor sampling at 1 Hz, creating a 4 sampling window and analyzing two features:

crowd-sensing/src/cloud.html

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Cloud based Human Activity Recognition</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<meta name="author" content="Francesco Colasante">
8+
<meta name="description" content="Iot Assignment crowd sensing">
9+
<meta charset="UTF-8">
10+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
11+
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
12+
13+
</head>
14+
15+
<body>
16+
17+
<h7>Your local IP address is: </h7>
18+
<h7 id="ip"> ip address</h7>
19+
<script type="application/javascript">
20+
function getIP(json) {
21+
let ip = document.getElementById("ip");
22+
ip.innerHTML = json.ip;
23+
}
24+
</script>
25+
26+
<div class="jumbotron jumbotron-fluid">
27+
<div class="container">
28+
<h1 class="display-4">Crowd sensing</h1>
29+
<small>Francesco Colasante</small>
30+
</div>
31+
</div>
32+
<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
33+
<div class="card">
34+
<div class="card-header">
35+
Cloud based
36+
</div>
37+
<div class="card-body">
38+
<h5 class="card-title">Linear Accelerometer raw data</h5>
39+
<p ></p>
40+
<div class="card-text" id="lad">No data</div>
41+
<div class="progress">
42+
<div id="x" class="progress-bar bg-success" role="progressbar" style="width: 0%" aria-valuenow="100"
43+
aria-valuemin="0" aria-valuemax="100"></div>
44+
</div>
45+
<div class="progress">
46+
<div id="y" class="progress-bar bg-info" role="progressbar" style="width: 0%" aria-valuenow="100"
47+
aria-valuemin="0" aria-valuemax="100"></div>
48+
</div>
49+
<div class="progress">
50+
<div id="z" class="progress-bar bg-warning" role="progressbar" style="width: 0%" aria-valuenow="100"
51+
aria-valuemin="0" aria-valuemax="100"></div>
52+
</div>
53+
54+
<a href="https://demo.thingsboard.io:/dashboard/b61584a0-9466-11ea-9a66-358c6522b855?publicId=d2ff5950-6a96-11ea-8e0a-7d0ef2a682d3""
55+
class="btn btn-primary">Live Dashboard</a>
56+
</div>
57+
</div>
58+
59+
<div class="embed-responsive embed-responsive-4by3">
60+
<iframe class="embed-responsive-item"
61+
src="https://demo.thingsboard.io/dashboard/fffdb510-994d-11ea-8945-557a14320ccf?publicId=c81c0600-994e-11ea-8945-557a14320ccf"
62+
allowfullscreen></iframe>
63+
</iframe>
64+
</div>
65+
Console Log:
66+
<div id="cnsl" class="alert alert-dark" style="height: 100px;" role="alert">
67+
</div>
68+
<script>
69+
/*REPLACE ACCESS_TOKEN with yours.
70+
This is a private info and it should be not stored in Git.
71+
*/
72+
let access_token = 'qD0VYMtFyBPNCDj2Kol4';
73+
let lad = document.getElementById('lad');
74+
let stat = document.getElementById('stat');
75+
let ip = document.getElementById('ip').innerHTML;
76+
let cnsl = document.getElementById('cnsl');
77+
let x = document.getElementById('x');
78+
let y = document.getElementById('y');
79+
let z = document.getElementById('z');
80+
81+
/* functions used to print on HTML */
82+
function print(text, append = true) {
83+
if (append)
84+
cnsl.innerHTML += text;
85+
else
86+
cnsl.innerHTML = text;
87+
}
88+
print("Console is ready");
89+
90+
if ('LinearAccelerationSensor' in window) {
91+
92+
let las = new LinearAccelerationSensor({ frequency: 1 });
93+
las.addEventListener('reading', (la) => {
94+
//all stuff there
95+
});
96+
las.addEventListener('error', event =>{
97+
//check errors
98+
})
99+
las.start();
100+
}
101+
102+
if ('LinearAccelerationSensor' in window) {
103+
let win = 4;
104+
let data = [];
105+
let i = 0;
106+
107+
//initialize sensor with frequency 1Hz
108+
let las = new LinearAccelerationSensor({ frequency: 1 });
109+
las.addEventListener('reading', function (la) {
110+
//change values on progress bar
111+
x.style.width = la.target.x * 100 + "%";
112+
y.style.width = la.target.y * 100 + "%";
113+
z.style.width = la.target.z * 100 + "%";
114+
lad.innerHTML = 'x: ' + la.target.x + '<br> y: ' + la.target.y + '<br> z: ' + la.target.z;
115+
//print('x: ' + la.target.x + '<br> y: ' + la.target.y + '<br> z: ' + la.target.z);
116+
117+
if (i < win) {
118+
//save values in array
119+
data[i] = { x: Math.abs(la.target.x), y: Math.abs(la.target.y), z: Math.abs(la.target.z) };
120+
i++;
121+
print(i);
122+
} else {
123+
//build payload and send using HTTP-POST
124+
let payload = {
125+
ip: ip,
126+
data: data
127+
};
128+
let msg = JSON.stringify(payload);
129+
print(msg);
130+
131+
const Http = new XMLHttpRequest();
132+
const url = `https://demo.thingsboard.io/api/v1/${access_token}/telemetry`;
133+
Http.open("POST", url);
134+
Http.send(msg);
135+
Http.onreadystatechange = (e) => {
136+
print(Http.responseText, false)
137+
}
138+
//restart the time window
139+
i = 0;
140+
data[i]({ x: Math.abs(la.target.x), y: Math.abs(la.target.y), z: Math.abs(la.target.z) });
141+
}
142+
});
143+
//start sensor
144+
las.start();
145+
}
146+
//error messgae
147+
else lad.innerHTML = 'Linear Accelerometer not supported';
148+
</script>
149+
</body>
150+
</html>

crowd-sensing/src/index.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Edge based Human Activity Recognition</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<meta name="author" content="Francesco Colasante">
8+
<meta charset="UTF-8">
9+
<!-- CSS only -->
10+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
11+
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
12+
13+
</head>
14+
15+
<body>
16+
<div class="jumbotron jumbotron-fluid">
17+
<div class="container">
18+
<h1 class="display-4">Crowd sensing</h1>
19+
<small>In this assignment we will built a mobile application to provide a crowd-sensing extension to our
20+
application.
21+
We build on-top of the cloud-based and edge-based components developed in the first and second
22+
assignments.</small>
23+
</div>
24+
Francesco Colasante
25+
</div>
26+
<div class="container">
27+
<div class="column">
28+
<img src="https://cdn-images-1.medium.com/max/1200/1*MmoSdsb-oU7MYuFq9tXBZA.png" class="img-fluid" alt="Responsive image">
29+
</div>
30+
<div class="column">
31+
<div class="card" style="width: 18rem;">
32+
<img
33+
src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSM0v5sILGt6ytFmeQMB2stGh1OZ5rHjbAVrQcW3S2rsqhG0MH0&usqp=CAU"
34+
class="card-img-top" alt="...">
35+
<div class="card-body">
36+
<h5 class="card-title">Cloud based</h5>
37+
<p class="card-text">Deploy your activity recognition model to the cloud. Given the data arriving to the
38+
cloud,
39+
you should execute the model and provide a status for the state of the user either periodically
40+
(e.g., every minute / every hour, etc) or whenever new values arrive.</p>
41+
<a href="cloud.html" class="btn btn-primary stretched-link">Cloud deployment</a>
42+
</div>
43+
</div>
44+
<div class="card" style="width: 18rem;">
45+
<img src="https://theseoplatform.co.uk/wp-content/uploads/92.-JavaScript-logo.png" class="card-img-top"
46+
alt="...">
47+
<div class="card-body">
48+
<h5 class="card-title">Local deployment</h5>
49+
<p class="card-text">Deploy your activity recognition model to the mobile phone. Given the data collected by
50+
the mobile phone,
51+
the model should be executed locally to provide a status for the state of the user.</p>
52+
<a href="local.html" class="btn btn-primary stretched-link">Local deployment</a>
53+
</div>
54+
</div>
55+
</div>
56+
</div>
57+
58+
59+
</body>
60+
61+
</html>

crowd-sensing/src/local.html

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Edge based Human Activity Recognition</title>
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<meta name="author" content="Francesco Colasante">
7+
<meta charset="UTF-8">
8+
<!-- CSS only -->
9+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
10+
11+
</head>
12+
<body>
13+
14+
<div class="jumbotron jumbotron-fluid">
15+
<div class="container">
16+
<h1 class="display-4">Crowd sensing</h1>
17+
<small>Francesco Colasante</small>
18+
</div>
19+
</div>
20+
<h7>Your local IP address is: </h7>
21+
<h7 id="ip"> ip address</h7>
22+
<!--Get device public ip address -->
23+
<script type="application/javascript">
24+
function getIP(json) {
25+
let ip = document.getElementById("ip");
26+
ip.innerHTML = json.ip;
27+
}
28+
</script>
29+
<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
30+
31+
<div class="card">
32+
<div class="card-header">
33+
Edge-based
34+
</div>
35+
<div class="card-body">
36+
<h5 class="card-title">Linear Accelerometer raw data</h5>
37+
<p ></p>
38+
<div class="card-text" id="lad">No data</div>
39+
<div class="progress">
40+
<div id="x" class="progress-bar bg-success" role="progressbar" style="width: 0%" aria-valuenow="100"
41+
aria-valuemin="0" aria-valuemax="100"></div>
42+
</div>
43+
<div class="progress">
44+
<div id="y" class="progress-bar bg-info" role="progressbar" style="width: 0%" aria-valuenow="100"
45+
aria-valuemin="0" aria-valuemax="100"></div>
46+
</div>
47+
<div class="progress">
48+
<div id="z" class="progress-bar bg-warning" role="progressbar" style="width: 0%" aria-valuenow="100"
49+
aria-valuemin="0" aria-valuemax="100"></div>
50+
</div>
51+
<div id="k"> Can't compute standard deviation</div>
52+
<div id="stat" class="alert alert-success" role="alert">
53+
Waiting for data
54+
</div>
55+
56+
<a href="https://demo.thingsboard.io:/dashboard/b61584a0-9466-11ea-9a66-358c6522b855?publicId=d2ff5950-6a96-11ea-8e0a-7d0ef2a682d3""
57+
class="btn btn-primary">Live Dashboard</a>
58+
</div>
59+
</div>
60+
61+
<div class="embed-responsive embed-responsive-4by3">
62+
<iframe class="embed-responsive-item"
63+
src="https://demo.thingsboard.io:/dashboard/7c023c00-99ab-11ea-ba29-93c92b718da1?publicId=c81c0600-994e-11ea-8945-557a14320ccf"
64+
allowfullscreen></iframe>
65+
</iframe>
66+
</div>
67+
Console Log:
68+
<div id="cnsl" class="alert alert-dark" style="height: 100px;" role="alert">
69+
</div>
70+
71+
<script>
72+
let lad = document.getElementById('lad');
73+
let x = document.getElementById('x');
74+
let y = document.getElementById('y');
75+
let z = document.getElementById('z');
76+
let k = document.getElementById('k');
77+
let stat = document.getElementById('stat');
78+
let ip = document.getElementById('ip').innerHTML;
79+
80+
let cnsl = document.getElementById('cnsl');
81+
function print(text, append = true) {
82+
if (append)
83+
cnsl.innerHTML += text + '<br>';
84+
else
85+
cnsl.innerHTML = text;
86+
}
87+
print("Console is ready");
88+
89+
//thingsboard device access token
90+
let token = "BApw7f9Vxs5AhofNrRdf";
91+
92+
//check sensor on device
93+
if ( 'LinearAccelerationSensor' in window ) {
94+
//a window is formed by 4 relevation
95+
let win = 4;
96+
97+
//array for saving retrived data locally
98+
let data = [];
99+
100+
let i = 0;
101+
102+
//initialize sensor with frequency 1Hz
103+
let las = new LinearAccelerationSensor({frequency: 1});
104+
//function exectued at each detection
105+
las.addEventListener('reading', function(la) {
106+
// write values on html page
107+
x.style.width = la.target.x*100 + "%";
108+
y.style.width = la.target.y*100 + "%";
109+
z.style.width = la.target.z*100 + "%";
110+
111+
lad.innerHTML = 'x: ' + la.target.x + '<br> y: ' + la.target.y + '<br> z: ' + la.target.z;
112+
print('x: ' + la.target.x + '<br> y: ' + la.target.y + '<br> z: ' + la.target.z);
113+
if(i<win){
114+
//save values in the arrays
115+
data[i] = { x: Math.abs(la.target.x), y: Math.abs(la.target.y), z: Math.abs(la.target.z) };
116+
i++;
117+
}else{
118+
//compute standard deviation
119+
let j;
120+
print("Calculating data", false);
121+
print("Data" + JSON.stringify(data));
122+
//l_sma = 1/win * sum(x_i+y_i+z_i)
123+
let l_sma = data.map(val => val.x + val.y + val.z).reduce( (acc, val) => acc + val);
124+
l_sma /= win;
125+
print("LSMA:" + JSON.stringify(l_sma));
126+
let tmp = data.map( val => val.x + val.y + val.z - l_sma ).map( x => Math.pow(x, 2));
127+
let sosd = tmp.reduce( (acc, val) => acc + val);
128+
print("sosd:" + sosd);
129+
sosd /= win;
130+
sosd = Math.sqrt(sosd);
131+
//print standard deviation on html page
132+
k.innerHTML = "standard deviation: " + sosd;
133+
134+
//empirical treshold for standard deviation is 0.5
135+
if(sosd<0.5){
136+
stat.innerHTML = "Still";
137+
stat.className = 'alert alert-danger'
138+
}
139+
else{
140+
stat.innerHTML = "Moving";
141+
stat.className = 'alert alert-success'
142+
}
143+
144+
//cerate message to be sent
145+
let msg = `{\"user\":${ip},\"status\":\"${stat.innerHTML}\"}`;
146+
console.log("msg"+msg);
147+
148+
//TODO: send the message
149+
150+
const Http = new XMLHttpRequest();
151+
const url= `https://demo.thingsboard.io/api/v1/${token}/telemetry`;
152+
Http.open("POST",url);
153+
Http.send(msg);
154+
155+
//restert the loop
156+
i=0;
157+
data[i] = { x: Math.abs(la.target.x), y: Math.abs(la.target.y), z: Math.abs(la.target.z) };
158+
}
159+
});
160+
//start the sensor
161+
las.start();
162+
}
163+
164+
//error messgae
165+
else lad.innerHTML = 'Linear Accelerometer not supported';
166+
</script>
167+
</body>
168+
</html>

0 commit comments

Comments
 (0)