├── Code
├── android
│ └── rtes
│ │ ├── app
│ │ ├── .gitignore
│ │ ├── src
│ │ │ ├── main
│ │ │ │ ├── res
│ │ │ │ │ ├── values
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ ├── colors.xml
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── drawable
│ │ │ │ │ │ ├── safe.PNG
│ │ │ │ │ │ ├── unsafe.PNG
│ │ │ │ │ │ └── ic_launcher_background.xml
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ ├── safe_icon.png
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ ├── safe_icon.png
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ ├── safe_icon.png
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ ├── safe_icon.png
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ ├── safe_icon.png
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ │ ├── layout
│ │ │ │ │ │ ├── activity_splash.xml
│ │ │ │ │ │ └── activity_main.xml
│ │ │ │ │ └── drawable-v24
│ │ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── java
│ │ │ │ │ └── com
│ │ │ │ │ │ └── abi
│ │ │ │ │ │ └── rtes
│ │ │ │ │ │ ├── base
│ │ │ │ │ │ ├── NetworkInitiateFactory.java
│ │ │ │ │ │ └── NetworkInitiateSingleton.java
│ │ │ │ │ │ ├── ui
│ │ │ │ │ │ └── activity
│ │ │ │ │ │ │ ├── home
│ │ │ │ │ │ │ ├── HomePresenter.java
│ │ │ │ │ │ │ ├── HomeView.java
│ │ │ │ │ │ │ ├── HomePresenterImpl.java
│ │ │ │ │ │ │ └── HomeActivity.java
│ │ │ │ │ │ │ └── SplashActivity.java
│ │ │ │ │ │ ├── constants
│ │ │ │ │ │ ├── ConstantsURL.java
│ │ │ │ │ │ └── Constants.java
│ │ │ │ │ │ ├── BaseApplication.java
│ │ │ │ │ │ ├── data
│ │ │ │ │ │ └── api
│ │ │ │ │ │ │ ├── RtesAPI.java
│ │ │ │ │ │ │ └── channel
│ │ │ │ │ │ │ ├── ChannelFeedData.java
│ │ │ │ │ │ │ ├── Feed.java
│ │ │ │ │ │ │ └── Channel.java
│ │ │ │ │ │ ├── utils
│ │ │ │ │ │ ├── Utils.java
│ │ │ │ │ │ └── ProgressUtils.java
│ │ │ │ │ │ └── preference
│ │ │ │ │ │ └── IAPreference.java
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── test
│ │ │ │ └── java
│ │ │ │ │ └── com
│ │ │ │ │ └── abi
│ │ │ │ │ └── rtes
│ │ │ │ │ └── ExampleUnitTest.java
│ │ │ └── androidTest
│ │ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── abi
│ │ │ │ └── rtes
│ │ │ │ └── ExampleInstrumentedTest.java
│ │ ├── proguard-rules.pro
│ │ └── build.gradle
│ │ ├── settings.gradle
│ │ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── .idea
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── runConfigurations.xml
│ │ └── gradle.xml
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── gradle.properties
│ │ ├── gradlew.bat
│ │ └── gradlew
├── Node-RED flows
│ └── flows.json
├── ESP32-MPU6050
│ ├── ThingspeakClient.ino
│ └── MQTTClient.ino
└── Grafana-JSON
│ └── Intrusion data-1564143087749.json
├── Documentation
├── InfluxDB.md
├── Grafana.md
├── Node-RED.md
└── Android.md
└── README.md
/Code/android/rtes/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/Code/android/rtes/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Intrusion Detection
3 |
4 |
--------------------------------------------------------------------------------
/Code/android/rtes/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/drawable/safe.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/drawable/safe.PNG
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/drawable/unsafe.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/drawable/unsafe.PNG
--------------------------------------------------------------------------------
/Code/android/rtes/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-hdpi/safe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-hdpi/safe_icon.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-mdpi/safe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-mdpi/safe_icon.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xhdpi/safe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xhdpi/safe_icon.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/safe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/safe_icon.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/safe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/safe_icon.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/droidthings/IntrusionDetection/HEAD/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/base/NetworkInitiateFactory.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.base;
2 |
3 | import com.abi.rtes.data.api.RtesAPI;
4 |
5 |
6 | public abstract class NetworkInitiateFactory {
7 | protected abstract RtesAPI initiateOkHttp();
8 | }
--------------------------------------------------------------------------------
/Code/android/rtes/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
--------------------------------------------------------------------------------
/Code/android/rtes/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jul 19 18:26:33 CEST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/ui/activity/home/HomePresenter.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.ui.activity.home;
2 |
3 | import com.abi.rtes.data.api.channel.ChannelFeedData;
4 |
5 | public interface HomePresenter {
6 |
7 | void getChannelFeeds();
8 |
9 | void detectIntrusion(ChannelFeedData channelFeedData);
10 | }
11 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/constants/ConstantsURL.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.constants;
2 |
3 | public class ConstantsURL {
4 |
5 | public static String BASE_URL = "https://api.thingspeak.com/channels/790451/";
6 |
7 | //https://api.thingspeak.com/channels/790451/feeds.json?api_key=0YOTCS4MZRKZBFDV&results=2
8 |
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #001A35
4 | #000A15
5 | #323A43
6 |
7 | #8B0000
8 | #008000
9 |
10 |
--------------------------------------------------------------------------------
/Code/android/rtes/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/constants/Constants.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.constants;
2 |
3 | public class Constants {
4 | public static int SPLASH_TIME_OUT = 2000;
5 | public final static int CHANNEL_INTERVAL = 1000 * 60 * 1; //1 minutes
6 |
7 | //shared preference
8 | public static final String SP_ACC_X = "acc_x";
9 | public static final String SP_ACC_Y = "acc_y";
10 | }
11 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes;
2 |
3 | import android.app.Application;
4 |
5 | import com.abi.rtes.preference.IAPreference;
6 |
7 | public class BaseApplication extends Application {
8 | @Override
9 | public void onCreate() {
10 | super.onCreate();
11 | IAPreference.startWith(getApplicationContext());
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/ui/activity/home/HomeView.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.ui.activity.home;
2 |
3 | import com.abi.rtes.data.api.channel.ChannelFeedData;
4 |
5 | public interface HomeView {
6 | void onSuccess(ChannelFeedData channelFeedData);
7 |
8 | void onError(String localizedMessage);
9 |
10 | void onIntrusion(boolean isIntruded, ChannelFeedData channelFeedData);
11 | }
12 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/test/java/com/abi/rtes/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/Code/android/rtes/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/Code/android/rtes/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Code/android/rtes/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.4.1'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/data/api/RtesAPI.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.data.api;
2 |
3 |
4 | import com.abi.rtes.data.api.channel.ChannelFeedData;
5 |
6 | import java.util.List;
7 |
8 | import retrofit.http.Field;
9 | import retrofit.http.FormUrlEncoded;
10 | import retrofit.http.GET;
11 | import retrofit.http.POST;
12 | import retrofit.http.Path;
13 | import retrofit.http.Query;
14 | import rx.Observable;
15 |
16 | //https://api.thingspeak.com/channels/790451/feeds.json?api_key=0YOTCS4MZRKZBFDV&results=2
17 |
18 | public interface RtesAPI {
19 |
20 | @GET("feeds.json?api_key=0YOTCS4MZRKZBFDV&results=1")
21 | Observable getChannelFeeds();
22 |
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/data/api/channel/ChannelFeedData.java:
--------------------------------------------------------------------------------
1 |
2 | package com.abi.rtes.data.api.channel;
3 |
4 | import java.util.List;
5 | import com.google.gson.annotations.Expose;
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | public class ChannelFeedData {
9 |
10 | @SerializedName("channel")
11 | @Expose
12 | private Channel channel;
13 | @SerializedName("feeds")
14 | @Expose
15 | private List feeds = null;
16 |
17 | public Channel getChannel() {
18 | return channel;
19 | }
20 |
21 | public void setChannel(Channel channel) {
22 | this.channel = channel;
23 | }
24 |
25 | public List getFeeds() {
26 | return feeds;
27 | }
28 |
29 | public void setFeeds(List feeds) {
30 | this.feeds = feeds;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/androidTest/java/com/abi/rtes/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.InstrumentationRegistry;
6 | import androidx.test.runner.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getTargetContext();
24 |
25 | assertEquals("com.abi.rtes", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.utils;
2 |
3 | import android.text.format.Time;
4 |
5 | import java.text.DateFormat;
6 | import java.text.ParseException;
7 | import java.text.SimpleDateFormat;
8 | import java.time.format.DateTimeFormatter;
9 | import java.util.Date;
10 | import java.util.Locale;
11 | import java.util.TimeZone;
12 |
13 | public class Utils {
14 |
15 | public static String convertDate(String epochDate) {
16 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
17 | DateFormat dateFormat = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
18 | sdf.setTimeZone(TimeZone.getTimeZone("CET"));
19 | String data = "";
20 | try {
21 | data= dateFormat.format(sdf.parse(epochDate));
22 | } catch (ParseException e) {
23 | e.printStackTrace();
24 | }
25 | return data;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/ui/activity/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.ui.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 |
7 | import androidx.appcompat.app.AppCompatActivity;
8 |
9 | import com.abi.rtes.R;
10 | import com.abi.rtes.constants.Constants;
11 | import com.abi.rtes.ui.activity.home.HomeActivity;
12 |
13 | public class SplashActivity extends AppCompatActivity {
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_splash);
19 |
20 | new Handler().postDelayed(new Runnable() {
21 | @Override
22 | public void run() {
23 | startActivity(new Intent(SplashActivity.this, HomeActivity.class));
24 | finish();
25 | }
26 | }, Constants.SPLASH_TIME_OUT);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/utils/ProgressUtils.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.utils;
2 |
3 | import android.app.Activity;
4 | import android.app.ProgressDialog;
5 |
6 | /**
7 | * Created by Abhilash on 29/03/2018.
8 | */
9 |
10 | public class ProgressUtils {
11 |
12 | public static ProgressDialog mProgressDialog = null;
13 |
14 | public static void showProgress(Activity activity, String message, boolean cancelable) {
15 |
16 | mProgressDialog = new ProgressDialog(activity);
17 | mProgressDialog.setCancelable(false);
18 |
19 | if (mProgressDialog != null && !mProgressDialog.isShowing()) {
20 | mProgressDialog.setMessage(message);
21 | mProgressDialog.setCancelable(false);
22 | mProgressDialog.show();
23 | }
24 | }
25 |
26 | public static void showProgress(Activity activity, String message) {
27 | showProgress(activity, message, false);
28 | }
29 |
30 | public static void hideProgress() {
31 | if (mProgressDialog != null && mProgressDialog.isShowing()) {
32 | mProgressDialog.dismiss();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Code/android/rtes/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
17 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/data/api/channel/Feed.java:
--------------------------------------------------------------------------------
1 |
2 | package com.abi.rtes.data.api.channel;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class Feed {
8 |
9 | @SerializedName("created_at")
10 | @Expose
11 | private String createdAt;
12 | @SerializedName("entry_id")
13 | @Expose
14 | private Integer entryId;
15 | @SerializedName("field1")
16 | @Expose
17 | private String field1;
18 | @SerializedName("field2")
19 | @Expose
20 | private String field2;
21 |
22 | public String getCreatedAt() {
23 | return createdAt;
24 | }
25 |
26 | public void setCreatedAt(String createdAt) {
27 | this.createdAt = createdAt;
28 | }
29 |
30 | public Integer getEntryId() {
31 | return entryId;
32 | }
33 |
34 | public void setEntryId(Integer entryId) {
35 | this.entryId = entryId;
36 | }
37 |
38 | public String getField1() {
39 | return field1;
40 | }
41 |
42 | public void setField1(String field1) {
43 | this.field1 = field1;
44 | }
45 |
46 | public String getField2() {
47 | return field2;
48 | }
49 |
50 | public void setField2(String field2) {
51 | this.field2 = field2;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/base/NetworkInitiateSingleton.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.base;
2 |
3 | import com.abi.rtes.constants.ConstantsURL;
4 | import com.abi.rtes.data.api.RtesAPI;
5 | import com.squareup.okhttp.OkHttpClient;
6 |
7 | import java.util.concurrent.TimeUnit;
8 |
9 | import retrofit.GsonConverterFactory;
10 | import retrofit.Retrofit;
11 | import retrofit.RxJavaCallAdapterFactory;
12 |
13 |
14 | public class NetworkInitiateSingleton extends NetworkInitiateFactory {
15 | private static NetworkInitiateSingleton ourInstance = new NetworkInitiateSingleton();
16 |
17 | private NetworkInitiateSingleton() {
18 | }
19 |
20 | public static NetworkInitiateSingleton getInstance() {
21 | return ourInstance;
22 | }
23 |
24 | public RtesAPI initiateOkHttp() {
25 | OkHttpClient okHttpClient = new OkHttpClient();
26 | okHttpClient.setConnectTimeout(20, TimeUnit.SECONDS);
27 | okHttpClient.setReadTimeout(20, TimeUnit.SECONDS);
28 | okHttpClient.setWriteTimeout(60, TimeUnit.SECONDS);
29 | Retrofit retrofit = new Retrofit.Builder().baseUrl(ConstantsURL.BASE_URL)
30 | .client(okHttpClient)
31 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
32 | .addConverterFactory(GsonConverterFactory.create())
33 | .build();
34 | ///making object of RestAdapter
35 | return retrofit.create(RtesAPI.class);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.0"
6 | defaultConfig {
7 | applicationId "com.abi.rtes"
8 | minSdkVersion 19
9 | targetSdkVersion 29
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation fileTree(dir: 'libs', include: ['*.jar'])
24 | implementation 'androidx.appcompat:appcompat:1.0.2'
25 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
26 |
27 | implementation 'com.squareup.retrofit:retrofit:2.0.0-beta2'
28 | implementation 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
29 | implementation 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
30 |
31 | implementation 'com.google.code.gson:gson:2.4'
32 |
33 | implementation 'com.squareup.okhttp:okhttp:2.4.0'
34 |
35 | //RxAndroid
36 | implementation 'io.reactivex:rxjava:1.0.16'
37 | implementation 'io.reactivex:rxandroid:1.0.1'
38 |
39 | implementation 'com.jakewharton:butterknife:8.7.0'
40 |
41 | implementation 'com.android.support:cardview-v7:25.1.1'
42 |
43 | testImplementation 'junit:junit:4.12'
44 | androidTestImplementation 'androidx.test:runner:1.2.0'
45 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
46 | }
47 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/Code/android/rtes/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/data/api/channel/Channel.java:
--------------------------------------------------------------------------------
1 |
2 | package com.abi.rtes.data.api.channel;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | public class Channel {
8 |
9 | @SerializedName("id")
10 | @Expose
11 | private Integer id;
12 | @SerializedName("name")
13 | @Expose
14 | private String name;
15 | @SerializedName("description")
16 | @Expose
17 | private String description;
18 | @SerializedName("latitude")
19 | @Expose
20 | private String latitude;
21 | @SerializedName("longitude")
22 | @Expose
23 | private String longitude;
24 | @SerializedName("field1")
25 | @Expose
26 | private String field1;
27 | @SerializedName("field2")
28 | @Expose
29 | private String field2;
30 | @SerializedName("created_at")
31 | @Expose
32 | private String createdAt;
33 | @SerializedName("updated_at")
34 | @Expose
35 | private String updatedAt;
36 | @SerializedName("last_entry_id")
37 | @Expose
38 | private Integer lastEntryId;
39 |
40 | public Integer getId() {
41 | return id;
42 | }
43 |
44 | public void setId(Integer id) {
45 | this.id = id;
46 | }
47 |
48 | public String getName() {
49 | return name;
50 | }
51 |
52 | public void setName(String name) {
53 | this.name = name;
54 | }
55 |
56 | public String getDescription() {
57 | return description;
58 | }
59 |
60 | public void setDescription(String description) {
61 | this.description = description;
62 | }
63 |
64 | public String getLatitude() {
65 | return latitude;
66 | }
67 |
68 | public void setLatitude(String latitude) {
69 | this.latitude = latitude;
70 | }
71 |
72 | public String getLongitude() {
73 | return longitude;
74 | }
75 |
76 | public void setLongitude(String longitude) {
77 | this.longitude = longitude;
78 | }
79 |
80 | public String getField1() {
81 | return field1;
82 | }
83 |
84 | public void setField1(String field1) {
85 | this.field1 = field1;
86 | }
87 |
88 | public String getField2() {
89 | return field2;
90 | }
91 |
92 | public void setField2(String field2) {
93 | this.field2 = field2;
94 | }
95 |
96 | public String getCreatedAt() {
97 | return createdAt;
98 | }
99 |
100 | public void setCreatedAt(String createdAt) {
101 | this.createdAt = createdAt;
102 | }
103 |
104 | public String getUpdatedAt() {
105 | return updatedAt;
106 | }
107 |
108 | public void setUpdatedAt(String updatedAt) {
109 | this.updatedAt = updatedAt;
110 | }
111 |
112 | public Integer getLastEntryId() {
113 | return lastEntryId;
114 | }
115 |
116 | public void setLastEntryId(Integer lastEntryId) {
117 | this.lastEntryId = lastEntryId;
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/Documentation/InfluxDB.md:
--------------------------------------------------------------------------------
1 | # InfluxDb
2 | The setup and query structure invlolved here is little different compared to that of a Relational database management system (RDBMS).
3 |
4 | ## Installation
5 |
6 | Download InfluxDb from [SetUp]. Unzip the contents onto a preferred folder on your pc/laptop.
7 |
8 | ![UnZip]
9 |
10 | Click on _influxd.exe_ to start the InfluxDB server, by deault it runs on port **8086**. It can be changed in _influxdb.conf_ file under _bind_address_ according to user preference.
11 |
12 | Below figure indicates that the server is running.
13 | ![Influx-Server]
14 |
15 | Now click on _influx.exe_ to run the influxDB client. To create databases, query the data etc.
16 | ![Influx-Client]
17 |
18 | Sample InfluxDB queries.
19 | ```
20 | >CREATE DATABASE IntrusionRTESDB
21 | ```
22 | ```
23 | >USE IntrusionRTESDB
24 | ```
25 | In order to insert to data to a table however it is a different procedure
26 | ```
27 | >INSERT intrusionMeasurements, esp32/XAcc=10 esp32/XGyro=12 esp32/YAcc=560 esp32/YGyro=456 esp32/ZAcc=678 esp32/ZGyro=33
28 | ```
29 | This query will create a table _intrusionMeasurements_ along with columns which are mentioned in the query. If the timestamp is not specified in the query the primary key of the table will be the time stamp generated by influxDB in epoch format.
30 | In case if you want to have a custome time stamp, In the influx CLI, you can add the timestamp at the end of the line, in nanosecond-precision Unix time,
31 | ```
32 | > insert log value=1 1504225728000123456
33 | ```
34 | In this project the data is being inserted from Node-RED nodes, refer [here](/Documentation/Node-RED.md).
35 |
36 |
37 |
38 | ----
39 |
40 |
41 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)
42 |
43 |
44 | [SetUp]:
45 | [UnZip]:
46 | [Influx-Server]:
47 | [Influx-Client]:
48 | [markdown-it]:
49 | [Ace Editor]:
50 | [node.js]:
51 | [Twitter Bootstrap]:
52 | [jQuery]:
53 | [@tjholowaychuk]:
54 | [express]:
55 | [AngularJS]:
56 | [Gulp]:
57 |
58 | [PlDb]:
59 | [PlGh]:
60 | [PlGd]:
61 | [PlOd]:
62 | [PlMe]:
63 | [PlGa]:
64 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/ui/activity/home/HomePresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.ui.activity.home;
2 |
3 | import android.util.Log;
4 |
5 | import com.abi.rtes.base.NetworkInitiateSingleton;
6 | import com.abi.rtes.constants.Constants;
7 | import com.abi.rtes.data.api.RtesAPI;
8 | import com.abi.rtes.data.api.channel.ChannelFeedData;
9 | import com.abi.rtes.preference.IAPreference;
10 |
11 | import rx.functions.Action1;
12 | import rx.schedulers.Schedulers;
13 |
14 | import static rx.android.schedulers.AndroidSchedulers.mainThread;
15 |
16 | public class HomePresenterImpl implements HomePresenter {
17 | private HomeView mHomeView;
18 |
19 | public HomePresenterImpl(HomeView homeView) {
20 | this.mHomeView = homeView;
21 | }
22 |
23 | @Override
24 | public void getChannelFeeds() {
25 | RtesAPI restInterface = NetworkInitiateSingleton.getInstance().initiateOkHttp();
26 | restInterface.getChannelFeeds()
27 | .observeOn(mainThread())
28 | .subscribeOn(Schedulers.io())
29 | .subscribe(new Action1() {
30 | @Override
31 | public void call(ChannelFeedData channelFeedData) {
32 | mHomeView.onSuccess(channelFeedData);
33 | }
34 | }, new Action1() {
35 | @Override
36 | public void call(Throwable throwable) {
37 | mHomeView.onError(throwable.getLocalizedMessage());
38 | }
39 | });
40 | }
41 |
42 | @Override
43 | public void detectIntrusion(ChannelFeedData channelFeedData) {
44 |
45 | if (channelFeedData != null) {
46 | Log.d("Actual Value", String.valueOf(Math.abs(Integer.valueOf(channelFeedData.getFeeds().get(0).getField2()))));
47 | Log.d("Actual Value", String.valueOf(Math.abs(Integer.valueOf(channelFeedData.getFeeds().get(0).getField1()))));
48 | if(IAPreference.getString(Constants.SP_ACC_X) != null && IAPreference.getString(Constants.SP_ACC_Y) != null){
49 | Log.d("Calc ValueX", String.valueOf(Math.abs(Integer.valueOf(IAPreference.getString(Constants.SP_ACC_X)) -
50 | Integer.valueOf(channelFeedData.getFeeds().get(0).getField1()))));
51 | Log.d("Calc ValueY", String.valueOf(Math.abs(Integer.valueOf(IAPreference.getString(Constants.SP_ACC_Y)) -
52 | Integer.valueOf(channelFeedData.getFeeds().get(0).getField2()))));
53 | if (Math.abs(Integer.valueOf(IAPreference.getString(Constants.SP_ACC_X)) -
54 | Integer.valueOf(channelFeedData.getFeeds().get(0).getField1())) > 500) {
55 | mHomeView.onIntrusion(true, channelFeedData);
56 | } else if (Math.abs(Integer.valueOf(IAPreference.getString(Constants.SP_ACC_Y)) -
57 | Integer.valueOf(channelFeedData.getFeeds().get(0).getField2())) > 700) {
58 | mHomeView.onIntrusion(true, channelFeedData);
59 | } else {
60 | mHomeView.onIntrusion(false, channelFeedData);
61 | }
62 | }else{
63 | mHomeView.onIntrusion(false, channelFeedData);
64 | }
65 | } else {
66 | mHomeView.onError("Something went wrong!");
67 | }
68 | IAPreference.setString(Constants.SP_ACC_X, channelFeedData.getFeeds().get(0).getField1());
69 | IAPreference.setString(Constants.SP_ACC_Y, channelFeedData.getFeeds().get(0).getField2());
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/Documentation/Grafana.md:
--------------------------------------------------------------------------------
1 | # Grafana
2 |
3 | ## Installation
4 |
5 | Download the grafana server-client executables from [Grafana-Get]
6 |
7 | Unzip the package, navigate to _bin_ folder launch _grafana-server.exe_ to launch grafana server.
8 |
9 | By Default Grafana runs on port **3000**, it can be modified in file _/grafana-6.2.5/conf/defaults.ini_ file.
10 | ```
11 | # The http port to use
12 | http_port = 9000
13 | ```
14 | In this project it has been modified to **9000**
15 |
16 | User credentials also are default values to login to dashboard.
17 | ```
18 | [security]
19 | # default admin user, created on startup
20 | admin_user = admin
21 |
22 | # default admin password, can be changed before first start of grafana, or in profile settings
23 | admin_password = admin
24 | ```
25 | ![G-1]
26 |
27 | ## Data Source configuration
28 |
29 | First-step on the grafana console is to add datasource for the dashboard.
30 | Under _configuration_ on left menu bar goto _Data Sources_, click on _Add data source_ and select _InfluxDB_
31 | ![G-2]
32 |
33 | ## Dashboard pannel
34 |
35 | ### Choosing the suitable visualisation
36 | Click on _Add_ icon or select _Add new panel_ from the top bar, select _Choose Visualisation_. Wide varieties in graphical representations can be choosen
37 | ![G-3]
38 |
39 | ### Querying the data from source
40 | From the _Query_ panel select the data source from the dropdown, select the measurement/table and can start selecting the field values necessary to represent on the chosen graph.
41 | ![G-4]
42 |
43 | Grafana also provides an option to inspect the queries where we can see the flow of data from our data source
44 | ![G-5]
45 |
46 | Grafana comes with most advanced setting for any graphical representations available. It allows changes to mode of the graph as bars, points and lines. Various color spectrums are available to mark the values. User can modify the tooltips and many more.
47 | Threshold setting is one of the settings included, which allows user to set different threshold limits and set the color gradient accordingly.
48 |
49 | ![G-6]
50 |
51 | In this project we have selected Graphs, heatmaps and Gauge visualisation to represent the 3-axis accelerometer and 3-axis
52 | gyroscope data.
53 |
54 | ![G-7]
55 |
56 | The implementation and mechanisms involved in Granfa and influxDB are much more. It can be extended to various other application as related to IoT. Follow the below links to get a better understanding via videos of the technologies used in this project.
57 |
58 | https://www.youtube.com/results?search_query=influxdb-grafana
59 |
60 | https://www.youtube.com/watch?v=DmIWgkawcw4&list=PLoVvAgF6geYMb029jpxqMuz5dRDtO0ydM
61 |
62 | https://www.youtube.com/watch?v=5JrT1DPlu0c&t=325s
63 |
64 | ----
65 |
66 |
67 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)
68 |
69 |
70 | [Grafana-Get]:
71 | [G-1]:
72 | [G-2]:
73 | [G-3]:
74 | [G-4]:
75 | [G-5]:
76 | [G-6]:
77 | [G-7]:
78 | [jQuery]:
79 | [@tjholowaychuk]:
80 | [express]:
81 | [AngularJS]:
82 | [Gulp]:
83 |
84 | [PlDb]:
85 | [PlGh]:
86 | [PlGd]:
87 | [PlOd]:
88 | [PlMe]:
89 | [PlGa]:
90 |
--------------------------------------------------------------------------------
/Code/Node-RED flows/flows.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "c25876d4.ce1fc8",
4 | "type": "mqtt in",
5 | "z": "ba7c6c83.2251f",
6 | "name": "Acc_X",
7 | "topic": "esp32/XAcc",
8 | "qos": "0",
9 | "datatype": "utf8",
10 | "broker": "9ce35c9b.4536e",
11 | "x": 150,
12 | "y": 80,
13 | "wires": [
14 | [
15 | "7807f0c5.675a8"
16 | ]
17 | ]
18 | },
19 | {
20 | "id": "bbd8f925.e07018",
21 | "type": "mqtt in",
22 | "z": "ba7c6c83.2251f",
23 | "name": "Acc_Y",
24 | "topic": "esp32/YAcc",
25 | "qos": "0",
26 | "datatype": "utf8",
27 | "broker": "9ce35c9b.4536e",
28 | "x": 130,
29 | "y": 160,
30 | "wires": [
31 | [
32 | "7807f0c5.675a8"
33 | ]
34 | ]
35 | },
36 | {
37 | "id": "2126c6f5.54891a",
38 | "type": "mqtt in",
39 | "z": "ba7c6c83.2251f",
40 | "name": "Acc_Z",
41 | "topic": "esp32/ZAcc",
42 | "qos": "0",
43 | "datatype": "utf8",
44 | "broker": "9ce35c9b.4536e",
45 | "x": 130,
46 | "y": 240,
47 | "wires": [
48 | [
49 | "7807f0c5.675a8"
50 | ]
51 | ]
52 | },
53 | {
54 | "id": "5f5a8067.83228",
55 | "type": "mqtt in",
56 | "z": "ba7c6c83.2251f",
57 | "name": "Gyro_X",
58 | "topic": "esp32/XGyro",
59 | "qos": "0",
60 | "datatype": "utf8",
61 | "broker": "9ce35c9b.4536e",
62 | "x": 130,
63 | "y": 300,
64 | "wires": [
65 | [
66 | "7807f0c5.675a8"
67 | ]
68 | ]
69 | },
70 | {
71 | "id": "f69eac01.e78cd",
72 | "type": "mqtt in",
73 | "z": "ba7c6c83.2251f",
74 | "name": "Gyro_Y",
75 | "topic": "esp32/YGyro",
76 | "qos": "0",
77 | "datatype": "utf8",
78 | "broker": "9ce35c9b.4536e",
79 | "x": 130,
80 | "y": 380,
81 | "wires": [
82 | [
83 | "7807f0c5.675a8"
84 | ]
85 | ]
86 | },
87 | {
88 | "id": "184ce45e.7213ec",
89 | "type": "mqtt in",
90 | "z": "ba7c6c83.2251f",
91 | "name": "Gyro_Z",
92 | "topic": "esp32/ZGyro",
93 | "qos": "0",
94 | "datatype": "utf8",
95 | "broker": "9ce35c9b.4536e",
96 | "x": 110,
97 | "y": 440,
98 | "wires": [
99 | [
100 | "7807f0c5.675a8"
101 | ]
102 | ]
103 | },
104 | {
105 | "id": "7807f0c5.675a8",
106 | "type": "join",
107 | "z": "ba7c6c83.2251f",
108 | "name": "Join Sensor Data",
109 | "mode": "custom",
110 | "build": "object",
111 | "property": "payload",
112 | "propertyType": "msg",
113 | "key": "topic",
114 | "joiner": "\\n",
115 | "joinerType": "str",
116 | "accumulate": false,
117 | "timeout": "",
118 | "count": "6",
119 | "reduceRight": false,
120 | "reduceExp": "",
121 | "reduceInit": "",
122 | "reduceInitType": "",
123 | "reduceFixup": "",
124 | "x": 410,
125 | "y": 240,
126 | "wires": [
127 | [
128 | "ae677d0.256668"
129 | ]
130 | ]
131 | },
132 | {
133 | "id": "ae677d0.256668",
134 | "type": "influxdb out",
135 | "z": "ba7c6c83.2251f",
136 | "influxdb": "85eca9c0.6e2a38",
137 | "name": "InfuxDB-Intrusion-Data",
138 | "measurement": "intrusionMeasurement",
139 | "precision": "",
140 | "retentionPolicy": "",
141 | "x": 620,
142 | "y": 300,
143 | "wires": []
144 | },
145 | {
146 | "id": "9ce35c9b.4536e",
147 | "type": "mqtt-broker",
148 | "z": "",
149 | "name": "",
150 | "broker": "192.168.0.38",
151 | "port": "1883",
152 | "clientid": "ESP8266ClientVindi",
153 | "usetls": false,
154 | "compatmode": true,
155 | "keepalive": "60",
156 | "cleansession": true,
157 | "birthTopic": "",
158 | "birthQos": "0",
159 | "birthPayload": "",
160 | "closeTopic": "",
161 | "closeQos": "0",
162 | "closePayload": "",
163 | "willTopic": "",
164 | "willQos": "0",
165 | "willPayload": ""
166 | },
167 | {
168 | "id": "85eca9c0.6e2a38",
169 | "type": "influxdb",
170 | "z": "",
171 | "hostname": "192.168.0.38",
172 | "port": "8086",
173 | "protocol": "http",
174 | "database": "IntrusionRTES",
175 | "name": "InfuxDB-Intrusion-Data",
176 | "usetls": false,
177 | "tls": ""
178 | }
179 | ]
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/ui/activity/home/HomeActivity.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.ui.activity.home;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.content.Context;
7 | import android.os.Bundle;
8 | import android.os.Handler;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 | import android.widget.Toast;
12 | import androidx.appcompat.app.AppCompatActivity;
13 | import androidx.core.app.NotificationCompat;
14 | import androidx.core.content.ContextCompat;
15 |
16 | import com.abi.rtes.R;
17 | import com.abi.rtes.constants.Constants;
18 | import com.abi.rtes.data.api.channel.ChannelFeedData;
19 | import com.abi.rtes.utils.ProgressUtils;
20 | import com.abi.rtes.utils.Utils;
21 |
22 | import org.w3c.dom.Text;
23 |
24 | public class HomeActivity extends AppCompatActivity implements HomeView {
25 |
26 | HomePresenter homePresenter;
27 | TextView mTextChannelName;
28 | TextView mTextChannelDesc;
29 | TextView mTextAccX;
30 | TextView mTextAccY;
31 | TextView mDateCreated;
32 | ImageView mImageIntr;
33 | TextView mTextIntr;
34 | Handler mHandler;
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.activity_main);
40 | mTextChannelName = (TextView) this.findViewById(R.id.channel_name);
41 | mTextChannelDesc = (TextView) this.findViewById(R.id.channel_desc);
42 | mDateCreated = (TextView) this.findViewById(R.id.date_created);
43 | mTextAccX = (TextView) this.findViewById(R.id.channel_accX);
44 | mTextAccY = (TextView) this.findViewById(R.id.channel_accY);
45 | mImageIntr = (ImageView)this.findViewById(R.id.intr_image);
46 | mTextIntr = (TextView)this.findViewById(R.id.intr_text);
47 | mHandler = new Handler();
48 | homePresenter = new HomePresenterImpl(this);
49 | ProgressUtils.showProgress(this, "Loading Channel Data");
50 | homePresenter.getChannelFeeds();
51 | mHandler.postDelayed(channelRunnable, Constants.CHANNEL_INTERVAL);
52 | }
53 |
54 | @Override
55 | protected void onResume() {
56 | super.onResume();
57 | }
58 |
59 | Runnable channelRunnable = new Runnable() {
60 | @Override
61 | public void run() {
62 | ProgressUtils.showProgress(HomeActivity.this, "Loading Channel Data");
63 | homePresenter.getChannelFeeds();
64 | mHandler.postDelayed(channelRunnable, Constants.CHANNEL_INTERVAL);
65 | }
66 | };
67 |
68 |
69 | @Override
70 | public void onSuccess(ChannelFeedData channelFeedData) {
71 | ProgressUtils.hideProgress();
72 | mTextChannelName.setText(channelFeedData.getChannel().getName());
73 | mTextChannelDesc.setText(channelFeedData.getChannel().getDescription());
74 | mDateCreated.setText(Utils.convertDate(channelFeedData.getFeeds().get(0).getCreatedAt()));
75 | mTextAccX.setText(channelFeedData.getFeeds().get(0).getField1());
76 | mTextAccY.setText(channelFeedData.getFeeds().get(0).getField2());
77 |
78 | homePresenter.detectIntrusion(channelFeedData);
79 | //sendNotification(channelFeedData.getChannel().getDescription());
80 | }
81 |
82 | @Override
83 | public void onError(String localizedMessage) {
84 | ProgressUtils.hideProgress();
85 | Toast.makeText(this, localizedMessage, Toast.LENGTH_SHORT).show();
86 | }
87 |
88 | @Override
89 | public void onIntrusion(boolean isIntruded, ChannelFeedData channelFeedData) {
90 | if(isIntruded){
91 | mImageIntr.setBackgroundResource(R.drawable.unsafe);
92 | mTextIntr.setText("INTRUDER ALERT!!!");
93 | mTextIntr.setTextColor(ContextCompat.getColor(this, R.color.colorDanger));
94 | sendNotification(channelFeedData.getChannel().getDescription());
95 | }else{
96 | mImageIntr.setBackgroundResource(R.drawable.safe);
97 | mTextIntr.setText("SAFE ENVIRONMENT");
98 | mTextIntr.setTextColor(ContextCompat.getColor(this, R.color.colorSafe));
99 | }
100 | }
101 |
102 | public void sendNotification(String description) {
103 |
104 | NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
105 | NotificationCompat.Builder builder = null;
106 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
107 | int importance = NotificationManager.IMPORTANCE_DEFAULT;
108 | NotificationChannel notificationChannel = new NotificationChannel("ID", "Name", importance);
109 | notificationManager.createNotificationChannel(notificationChannel);
110 | builder = new NotificationCompat.Builder(getApplicationContext(), notificationChannel.getId());
111 | } else {
112 | builder = new NotificationCompat.Builder(getApplicationContext());
113 | }
114 |
115 | builder = builder
116 | .setSmallIcon(R.mipmap.safe_icon)
117 | .setColor(ContextCompat.getColor(this, R.color.colorAccent))
118 | .setContentTitle("Intruder alert!!")
119 | .setContentText("Intruder at " + description)
120 | .setDefaults(Notification.DEFAULT_ALL)
121 | .setAutoCancel(true);
122 | notificationManager.notify(1, builder.build());
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/Documentation/Node-RED.md:
--------------------------------------------------------------------------------
1 | # Node-RED
2 |
3 | ## Installation
4 |
5 | Node-RED is built on Node.js. Download Node.js from [nodejs.org] according to your operating system. NPM modules will be installed globally.
6 |
7 | Install Node-RED
8 | ```
9 | npm install node-red -g
10 | ```
11 | From the cli run,
12 | ```
13 | > node-red
14 | ```
15 | ![nr-cli]
16 |
17 | Open the link _http://127.0.0.1:1880/_ the default port link for Node-RED portal.
18 |
19 | ![nr-1]
20 |
21 | On the left side we have menu which is called Node palletes. We can drag components (nodes) and configure them according to the requirement.
22 |
23 | ## The current architecture flow
24 | ![nr-6]
25 |
26 | Node-RED console also provides an option to import/export the flows in JSON format so that it can be shared with everyone else in the development team.
27 | Click on the _hamburger_ icon on the top right corner and you can see the options to export/import the flow.
28 |
29 | The current flow for this implementation can be found [flows]. It can be imported into Node-RED console for further evaluation.
30 |
31 | ## Node pallette examples
32 |
33 | ### Inject Node
34 | ![nr-3]
35 | Inject node helps to input a certain value which can be number, string, object.
36 | For eg - In the below figure _Payload_ is a string and it is publishing the payload via _sensorX_ topic through the MQTT broker.
37 |
38 | ![nr-2]
39 |
40 | ### MQTT Node
41 | ![nr-4]
42 | MQTT node, configure the broker according to the broker parameters which will be running on your system.
43 | The subscriber on the Node-RED will be waiting for all the published sensor readings for a particular topic name specified.
44 |
45 | ![nr-5]
46 |
47 | ### Join Node
48 | ![nr-7]
49 | Join node helps to join all the data coming from various MQTT subscribers.
50 |
51 | Combine all the sensor reading as key/value object so that we can insert the data directly to InfluxDB. The beauty of the InfluxDB is that it will automatically create columns according to the keys from the join node.
52 | ![nr-8]
53 |
54 | Output from the Join node
55 | ![nr-13]
56 |
57 | InfluxDB node will interpret this as
58 | ```
59 | insert intrusionMeasurement, esp32/XAcc=-2572, esp32/YAcc= 120, esp32/ZAcc= -18524, esp32/XGyro= 626, esp32/YGyro= -15, esp32/ZGyro= -280 currentdefaultTimestamp
60 | ```
61 |
62 | ### InfluxDB Node
63 | There are many nodes which don't exist on the default Node pallette and InfluxDB node is one among them.
64 | Goto _Settings_ from _menu_ icon from top right, Select _pallette_, Click _install_ search for _node-red-contrib-influxdb_ and install them.
65 |
66 | ![nr-9]
67 |
68 | #### configuration
69 | After we run the _influxd.exe_ we can connect this node to our database.
70 |
71 | ![nr-10]
72 | ![nr-11]
73 |
74 | Measurement (Table name) can be mentioned in the configuration pallette as well
75 | ![nr-12]
76 |
77 | Debug console on the right side enables to see all the debug messages/payloads
78 |
79 | ----
80 |
81 |
82 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)
83 |
84 |
85 | [downloads]:
86 | [nr-cli]:
87 | [nr-1]:
88 | [nr-2]:
89 | [nr-3]:
90 | [nr-4]:
91 | [nr-5]:
92 | [nr-6]:
93 | [nr-7]:
94 | [nr-8]:
95 | [flows]:
96 | [nr-9]:
97 | [nr-10]:
98 | [nr-11]:
99 | [nr-12]:
100 | [nr-13]:
101 |
102 | [PlDb]:
103 | [PlGh]:
104 | [PlGd]:
105 | [PlOd]:
106 | [PlMe]:
107 | [PlGa]:
108 |
--------------------------------------------------------------------------------
/Code/ESP32-MPU6050/ThingspeakClient.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
5 | // for both classes must be in the include path of your project
6 | #include "I2Cdev.h"
7 | #include "MPU6050.h"
8 |
9 | // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
10 | // is used in I2Cdev.h
11 | //#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
12 | #include "Wire.h"
13 | //#endif
14 |
15 | // class default I2C address is 0x68
16 | // specific I2C addresses may be passed as a parameter here
17 | // AD0 low = 0x68 (default for InvenSense evaluation board)
18 | // AD0 high = 0x69
19 | MPU6050 accelgyro;
20 | //MPU6050 accelgyro(0x69); // <-- use for AD0 high
21 |
22 | int16_t ax, ay, az;
23 | int16_t gx, gy, gz;
24 |
25 | // uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
26 | // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
27 | // not so easy to parse, and slow(er) over UART.
28 | #define OUTPUT_READABLE_ACCELGYRO
29 |
30 | String apiKey = "write_apikey"; // Enter your Write API key from ThingSpeak
31 |
32 | const char *ssid = "WiFi_SSID"; // replace with your wifi ssid and password
33 | const char *pass = "WiFi_Password";
34 | const char* server = "api.thingspeak.com";
35 |
36 | long channelId = 790451;//ID for particular channel in Thingspeak
37 | WiFiClient client;
38 |
39 | void setup() {
40 | setup_wifi();
41 | // join I2C bus (I2Cdev library doesn't do this automatically)
42 | Wire.begin();
43 |
44 | // initialize serial communication
45 | Serial.begin(115200);
46 |
47 | // initialize device
48 | delay(2000);
49 | Serial.println("Initializing I2C devices...");
50 | accelgyro.initialize();
51 | delay(2000);
52 | // verify connection
53 | Serial.println("Testing device connections...");
54 | Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
55 | delay(500);
56 | // use the code below to change accel/gyro offset values
57 |
58 | set_sensor_offset();
59 |
60 | }
61 |
62 | //Set offsets as per requirement
63 | void set_sensor_offset() {
64 | // use the code below to change accel/gyro offset values
65 | Serial.println("Updating internal sensor offsets...");
66 | // -76 -2359 1688 0 0 0
67 | Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
68 | Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
69 | Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
70 | Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
71 | Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
72 | Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
73 | Serial.print("\n");
74 | accelgyro.setXGyroOffset(220);
75 | accelgyro.setYGyroOffset(76);
76 | accelgyro.setZGyroOffset(-85);
77 | Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
78 | Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
79 | Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
80 | Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
81 | Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
82 | Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
83 | Serial.print("\n");
84 | }
85 |
86 | //Setup wifi connection
87 | void setup_wifi() {
88 | Serial.println("Connecting to ");
89 | Serial.println(ssid);
90 | WiFi.begin(ssid, pass);
91 | while (WiFi.status() != WL_CONNECTED)
92 | {
93 | delay(500);
94 | Serial.print(".");
95 | }
96 | Serial.println("");
97 | Serial.println("WiFi connected");
98 | }
99 |
100 | void loop() {
101 |
102 | if (client.connect(server,80)) { // "184.106.153.149" or api.thingspeak.com
103 |
104 | String postStr = readAccelData();
105 | delay(500);
106 | postData(postStr);
107 | delay(500);
108 |
109 | }
110 | client.stop();
111 | Serial.println("Waiting...");
112 | delay(10000);
113 | }
114 |
115 |
116 |
117 | String readAccelData(){
118 |
119 | // read raw accel/gyro measurements from device
120 | accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
121 |
122 | // these methods (and a few others) are also available
123 | //accelgyro.getAcceleration(&ax, &ay, &az);
124 | //accelgyro.getRotation(&gx, &gy, &gz);
125 |
126 | #ifdef OUTPUT_READABLE_ACCELGYRO
127 | // display tab-separated accel/gyro x/y/z values
128 | Serial.print("a/g:\t");
129 | Serial.print(ax); Serial.print("\t");
130 | Serial.print(ay); Serial.print("\t");
131 | Serial.print(az); Serial.print("\t");
132 | Serial.print(gx); Serial.print("\t");
133 | Serial.print(gy); Serial.print("\t");
134 | Serial.println(gz);
135 | #endif
136 | delay(500);
137 |
138 | //Create a string with values to be posted to particular fields in ThingSpeak
139 | String postStr = apiKey;
140 | postStr +="&field1=";
141 | postStr += String(ax);
142 | postStr += "&field2=";
143 | postStr += String(ay);
144 |
145 | return postStr;
146 |
147 | }
148 |
149 |
150 | void postData(String postStr) {
151 |
152 | client.print("POST /update HTTP/1.1\n");
153 | client.print("Host: api.thingspeak.com\n");
154 | client.print("Connection: close\n");
155 | client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
156 | client.print("Content-Type: application/x-www-form-urlencoded\n");
157 | client.print("Content-Length: ");
158 | client.print(postStr.length());
159 | client.print("\n\n");
160 | client.print(postStr);
161 | delay(500);
162 | Serial.print("Posted to Thingspeak");
163 | }
164 |
--------------------------------------------------------------------------------
/Code/android/rtes/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/Code/ESP32-MPU6050/MQTTClient.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
5 | // for both classes must be in the include path of your project
6 | #include "I2Cdev.h"
7 | #include "MPU6050.h"
8 |
9 | // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
10 | // is used in I2Cdev.h
11 | //#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
12 | #include "Wire.h"
13 | //#endif
14 |
15 | // class default I2C address is 0x68
16 | // specific I2C addresses may be passed as a parameter here
17 | // AD0 low = 0x68 (default for InvenSense evaluation board)
18 | // AD0 high = 0x69
19 | MPU6050 accelgyro;
20 | //MPU6050 accelgyro(0x69); // <-- use for AD0 high
21 |
22 | int16_t ax, ay, az;
23 | int16_t gx, gy, gz;
24 |
25 | // Add your MQTT Broker IP address, for example with Mosquitto Broker:
26 | //const char* mqtt_server = "192.168.0.192";
27 | const char* mqtt_server = "local_IPv4_addr";
28 |
29 |
30 | WiFiClient espClient;
31 | PubSubClient client(espClient);
32 | long lastMsg = 0;
33 | char msg[50];
34 | int value = 0;
35 |
36 | // uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
37 | // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
38 | // not so easy to parse, and slow(er) over UART.
39 | #define OUTPUT_READABLE_ACCELGYRO
40 |
41 |
42 | const char *ssid = "WiFi_SSID"; // replace with your wifi ssid and wpa2 key
43 | const char *pass = "WiFi_Password";
44 |
45 |
46 | //Setup Wifi, MPU6050, Start
47 | void setup() {
48 | Serial.begin(115200);
49 | delay(10);
50 |
51 | setup_wifi();
52 | client.setServer(mqtt_server, 1883);
53 |
54 | // join I2C bus (I2Cdev library doesn't do this automatically)
55 | Wire.begin();
56 |
57 | // initialize serial communication
58 | Serial.begin(115200);
59 |
60 | // initialize device
61 | delay(2000);
62 | Serial.println("Initializing I2C devices...");
63 | accelgyro.initialize();
64 | delay(2000);
65 | // verify connection
66 | Serial.println("Testing device connections...");
67 | Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
68 | delay(500);
69 | //Set accel/gyro offsets
70 | set_sensor_offset();
71 |
72 |
73 | }
74 |
75 | void set_sensor_offset() {
76 | // use the code below to change accel/gyro offset values
77 | Serial.println("Updating internal sensor offsets...");
78 | // -76 -2359 1688 0 0 0
79 | Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
80 | Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
81 | Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
82 | Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
83 | Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
84 | Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
85 | Serial.print("\n");
86 | accelgyro.setXGyroOffset(220);
87 | accelgyro.setYGyroOffset(76);
88 | accelgyro.setZGyroOffset(-85);
89 | Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
90 | Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
91 | Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
92 | Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
93 | Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
94 | Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
95 | Serial.print("\n");
96 | }
97 |
98 | void setup_wifi() {
99 | Serial.println("Connecting to ");
100 | Serial.println(ssid);
101 | WiFi.begin(ssid, pass);
102 | while (WiFi.status() != WL_CONNECTED)
103 | {
104 | delay(500);
105 | Serial.print(".");
106 | }
107 | Serial.println("");
108 | Serial.println("WiFi connected");
109 | }
110 |
111 | void reconnect() {
112 | // Loop until we're reconnected
113 | while (!client.connected()) {
114 | Serial.print("Attempting MQTT connection...");
115 | // Attempt to connect
116 | if (client.connect("ESP8266ClientVindi")) {
117 | Serial.println("connected");
118 | } else {
119 | Serial.print("failed, rc=");
120 | Serial.print(client.state());
121 | Serial.println(" try again in 5 seconds");
122 | // Wait 5 seconds before retrying
123 | delay(5000);
124 | }
125 | }
126 | }
127 |
128 | void loop() {
129 | if (!client.connected()) {
130 | reconnect();
131 | }
132 | client.loop();
133 | accelgyro.getAcceleration(&ax, &ay, &az);
134 |
135 | long now = millis();
136 | if (now - lastMsg > 10000) {
137 | lastMsg = now;
138 | readData();
139 |
140 | client.publish("esp32/XAcc", String(ax).c_str(), true);
141 | client.publish("esp32/YAcc", String(ay).c_str(), true);
142 | client.publish("esp32/ZAcc", String(az).c_str(), true);
143 | client.publish("esp32/XGyro", String(gx).c_str(), true);
144 | client.publish("esp32/YGyro", String(gy).c_str(), true);
145 | client.publish("esp32/ZGyro", String(gz).c_str(), true);
146 |
147 | }
148 | }
149 |
150 |
151 | void readData(){
152 |
153 | // read raw accel/gyro measurements from device
154 | accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
155 |
156 | // these methods (and a few others) are also available
157 | //accelgyro.getAcceleration(&ax, &ay, &az);
158 | //accelgyro.getRotation(&gx, &gy, &gz);
159 |
160 | #ifdef OUTPUT_READABLE_ACCELGYRO
161 | // display tab-separated accel/gyro x/y/z values
162 | Serial.print("a/g:\t");
163 | Serial.print(ax); Serial.print("\t");
164 | Serial.print(ay); Serial.print("\t");
165 | Serial.print(az); Serial.print("\t");
166 | Serial.print(gx); Serial.print("\t");
167 | Serial.print(gy); Serial.print("\t");
168 | Serial.println(gz);
169 | #endif
170 | delay(500);
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/Documentation/Android.md:
--------------------------------------------------------------------------------
1 | # Android
2 |
3 | ## Installation
4 |
5 | Download the latest version of [Android] studio according to your preferred operating system. Install the latest Android SDK (API 29) once the Android studio is installed.
6 | The current Android application targets
7 | ```
8 | minSdkVersion 19
9 | targetSdkVersion 29
10 | ```
11 | It runs on devices with os from Android KitKat till Android Q.
12 |
13 | ## Data source configuration
14 | As it is explained in architecture of the application the data source for the Android application is [ThingSpeak] analytics portal.
15 |
16 | ### Configuration
17 | The API exposed from ThingSpeak portal
18 | ```
19 | https://api.thingspeak.com/channels/790451/feeds.json?api_key=0YOTCS4MZRKZBFDV&results=1
20 | ```
21 |
22 | Using Retrofit HTTP client for Android we can configure the API in a singleton class so that api can be accessed from anywhere in the application.
23 |
24 | ```
25 | public static String BASE_URL = "https://api.thingspeak.com/channels/790451/";
26 | ```
27 |
28 | ```
29 | public interface RtesAPI {
30 | @GET("feeds.json?api_key=0YOTCS4MZRKZBFDV&results=1")
31 | Observable getChannelFeeds();
32 |
33 | }
34 | ```
35 |
36 | _ChannelFeedData_ will have all the objects of the JSON data which it is receiving from ThingSpeak network.
37 |
38 | ```
39 | {
40 | "channel": {
41 | "id": 790451,
42 | "name": "ESP32 Test channel",
43 | "description": "Testing to connect ESP32",
44 | "latitude": "0.0",
45 | "longitude": "0.0",
46 | "field1": "X",
47 | "field2": "Y",
48 | "created_at": "2019-05-29T09:51:24Z",
49 | "updated_at": "2019-07-20T14:33:11Z",
50 | "last_entry_id": 671
51 | },
52 | "feeds": [
53 | {
54 | "created_at": "2019-07-25T22:16:52Z",
55 | "entry_id": 671,
56 | "field1": "908",
57 | "field2": "236"
58 | }
59 | ]
60 | }
61 | ```
62 |
63 | Set-up the base Retrofit API necessary for the application
64 |
65 | ```
66 | public class NetworkInitiateSingleton extends NetworkInitiateFactory {
67 | private static NetworkInitiateSingleton ourInstance = new NetworkInitiateSingleton();
68 |
69 | private NetworkInitiateSingleton() {
70 | }
71 |
72 | public static NetworkInitiateSingleton getInstance() {
73 | return ourInstance;
74 | }
75 |
76 | public RtesAPI initiateOkHttp() {
77 | OkHttpClient okHttpClient = new OkHttpClient();
78 | okHttpClient.setConnectTimeout(20, TimeUnit.SECONDS);
79 | okHttpClient.setReadTimeout(20, TimeUnit.SECONDS);
80 | okHttpClient.setWriteTimeout(60, TimeUnit.SECONDS);
81 | Retrofit retrofit = new Retrofit.Builder().baseUrl(ConstantsURL.BASE_URL)
82 | .client(okHttpClient)
83 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
84 | .addConverterFactory(GsonConverterFactory.create())
85 | .build();
86 | ///making object of RestAdapter
87 | return retrofit.create(RtesAPI.class);
88 | }
89 | }
90 | ```
91 |
92 | ## Implementation
93 |
94 | As this is a REST API, on the Andorid application we need to create a thread which runs in background every minute. Since, The ESP32 sends the data to ThingSpeak on per minute cycle. _CHANNEL_INTERVAL_ is set to 1 minute
95 |
96 | ```
97 | Runnable channelRunnable = new Runnable() {
98 | @Override
99 | public void run() {
100 | ProgressUtils.showProgress(HomeActivity.this, "Loading Channel Data");
101 | homePresenter.getChannelFeeds();
102 | mHandler.postDelayed(channelRunnable, Constants.CHANNEL_INTERVAL);
103 | }
104 | ```
105 |
106 | When the data is received for the first time it is stored on Android [SharedPreference] which is a local key-value storage interface.
107 | And then sent to display on UI. When the data is received in next minute it is compared with previously stored data, if the difference between acceleration values is more than 500 units (X-axis) or 700 units (Y-axis) it is considered as an intrusion and at this point there will be a spike on the ThingSpeak graph which shows sudden imbalance in the values and user is notified.
108 |
109 | ![mob-1]
110 |
111 | Since the app is just a prototype only X and Y axis values are considered. The calculations are made on the state graph on ThingSpeak.
112 | Might not be 100% accurate in terms of detecting intrusion as values need to be studied to arrive at the difference between consecutive values to be considered an intrusion.
113 |
114 |
115 | ----
116 |
117 |
118 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)
119 |
120 |
121 | [Android]:
122 | [ThingSpeak]:
123 | [Retrofit]:
124 | [SharedPreference]:
125 | [mob-1]:
126 |
127 | [nr-6]:
128 | [nr-7]:
129 | [nr-8]:
130 | [flows]:
131 | [nr-9]:
132 | [nr-10]:
133 | [nr-11]:
134 | [nr-12]:
135 | [nr-13]:
136 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
47 |
48 |
53 |
54 |
60 |
61 |
62 |
70 |
71 |
72 |
78 |
79 |
85 |
86 |
94 |
95 |
96 |
97 |
102 |
103 |
109 |
110 |
111 |
119 |
120 |
121 |
126 |
127 |
133 |
134 |
135 |
143 |
144 |
145 |
146 |
147 |
154 |
155 |
159 |
160 |
161 |
162 |
163 |
169 |
170 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/Code/android/rtes/app/src/main/java/com/abi/rtes/preference/IAPreference.java:
--------------------------------------------------------------------------------
1 | package com.abi.rtes.preference;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.SharedPreferences.Editor;
6 |
7 | /**
8 | * Created by Abhilash on 29/03/2018.
9 | */
10 |
11 |
12 | public class IAPreference {
13 |
14 | public static final String DB_SHARED_PREF_NAME = "IAAppSettings";
15 |
16 | /**
17 | * SharedPreferences object that will be used for storing persistent data
18 | */
19 | private static SharedPreferences mSharedPreferences;
20 |
21 | public static void startWith(Context applicationContext) {
22 | mSharedPreferences = applicationContext.getSharedPreferences(DB_SHARED_PREF_NAME, Context.MODE_PRIVATE);
23 | }
24 |
25 | /**
26 | * Gets an integer from persistent storage
27 | *
28 | * @param variable Variable name in string
29 | * @return returns the value that is stored if available, 0 otherwise
30 | */
31 | public static int getInt(String variable) {
32 | return getInt(variable, 0);
33 | }
34 |
35 | /**
36 | * Gets an integer from persistent storage
37 | *
38 | * @param variable Variable name in string
39 | * @param defaultValue If this variable is not initialized, this default value will be returned instead
40 | * @return returns the value that is stored if available, defaultValue otherwise
41 | */
42 | public static int getInt(String variable, int defaultValue) {
43 | if (mSharedPreferences == null)
44 | return defaultValue;
45 | return mSharedPreferences.getInt(variable, defaultValue);
46 | }
47 |
48 | /**
49 | * Sets an integer in persistent storage
50 | *
51 | * @param variable Variable name in string
52 | * @param value Value to be set
53 | */
54 | public static void setInt(String variable, int value) {
55 | if (mSharedPreferences == null)
56 | return;
57 | Editor e = mSharedPreferences.edit();
58 | e.putInt(variable, value);
59 | e.commit();
60 | }
61 |
62 | /**
63 | * Gets a String from persistent storage
64 | *
65 | * @param variable Variable name in string
66 | * @return returns the value that is stored if available, null otherwise
67 | */
68 | public static String getString(String variable) {
69 | return getString(variable, null);
70 | }
71 |
72 | /**
73 | * Gets a String from persistent storage
74 | *
75 | * @param variable Variable name in string
76 | * @param defaultValue If this variable is not initialized, this default value will be returned instead
77 | * @return returns the value that is stored if available, defaultValue otherwise
78 | */
79 | public static String getString(String variable, String defaultValue) {
80 | if (mSharedPreferences == null)
81 | return defaultValue;
82 | return mSharedPreferences.getString(variable, defaultValue);
83 | }
84 |
85 | /**
86 | * Sets a String in persistent storage
87 | *
88 | * @param variable Variable name in string
89 | * @param value Value to be set
90 | */
91 | public static void setString(String variable, String value) {
92 | if (mSharedPreferences == null)
93 | return;
94 | Editor e = mSharedPreferences.edit();
95 | e.putString(variable, value);
96 | e.commit();
97 | }
98 |
99 | /**
100 | * Gets a boolean from persistent storage
101 | *
102 | * @param variable Variable name in string
103 | * @return returns the value that is stored if available, false otherwise
104 | */
105 | public static boolean getBoolean(String variable) {
106 | return getBoolean(variable, false);
107 | }
108 |
109 | /**
110 | * Gets a boolean from persistent storage
111 | *
112 | * @param variable Variable name in string
113 | * @param defaultValue If this variable is not initialized, this default value will be returned instead
114 | * @return returns the value that is stored if available, defaultValue otherwise
115 | */
116 | public static boolean getBoolean(String variable, boolean defaultValue) {
117 | if (mSharedPreferences == null)
118 | return defaultValue;
119 | return mSharedPreferences.getBoolean(variable, defaultValue);
120 | }
121 |
122 | /**
123 | * Sets a boolean in persistent storage
124 | *
125 | * @param variable Variable name in string
126 | * @param value Value to be set
127 | */
128 | public static void setBoolean(String variable, boolean value) {
129 | if (mSharedPreferences == null)
130 | return;
131 | Editor e = mSharedPreferences.edit();
132 | e.putBoolean(variable, value);
133 | e.commit();
134 | }
135 |
136 | /**
137 | * Gets a float from persistent storage
138 | *
139 | * @param variable Variable name in string
140 | * @return returns the value that is stored if available, 0.0f otherwise
141 | */
142 | public static float getFloat(String variable) {
143 | return getFloat(variable, 0.0f);
144 | }
145 |
146 | /**
147 | * Gets a float from persistent storage
148 | *
149 | * @param variable Variable name in string
150 | * @param defaultValue If this variable is not initialized, this default value will be returned instead
151 | * @return returns the value that is stored if available, defaultValue otherwise
152 | */
153 | public static float getFloat(String variable, float defaultValue) {
154 | if (mSharedPreferences == null)
155 | return defaultValue;
156 | return mSharedPreferences.getFloat(variable, defaultValue);
157 | }
158 |
159 | /**
160 | * Sets a float in persistent storage
161 | *
162 | * @param variable Variable name in string
163 | * @param value Value to be set
164 | */
165 | public static void setFloat(String variable, float value) {
166 | if (mSharedPreferences == null)
167 | return;
168 | Editor e = mSharedPreferences.edit();
169 | e.putFloat(variable, value);
170 | e.commit();
171 | }
172 |
173 | /**
174 | * Gets a long from persistent storage
175 | *
176 | * @param variable Variable name in string
177 | * @return returns the value that is stored if available, 0L otherwise
178 | */
179 | public static long getLong(String variable) {
180 | return getLong(variable, 0L);
181 | }
182 |
183 | /**
184 | * Gets a long from persistent storage
185 | *
186 | * @param variable Variable name in string
187 | * @param defaultValue If this variable is not initialized, this default value will be returned instead
188 | * @return returns the value that is stored if available, defaultValue otherwise
189 | */
190 | public static long getLong(String variable, long defaultValue) {
191 | if (mSharedPreferences == null)
192 | return defaultValue;
193 | return mSharedPreferences.getLong(variable, defaultValue);
194 | }
195 |
196 | /**
197 | * Sets a long in persistent storage
198 | *
199 | * @param variable Variable name in string
200 | * @param value Value to be set
201 | */
202 | public static void setLong(String variable, long value) {
203 | if (mSharedPreferences == null)
204 | return;
205 | Editor e = mSharedPreferences.edit();
206 | e.putLong(variable, value);
207 | e.commit();
208 | }
209 |
210 | }
211 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Intrusuion Detection with MQTT and Grafana monitoring
2 | MPU6050 MQTT based intrusion detection system
3 |
4 |
5 | This Github page contains the documentation and codebase of the project "Intrusion detection with MQTT and Grafana Monitoring". The project is an effort of the students Abhilash Malleshappa Bhajantri (26119) and Vineeth Vijaykumar Chitragi (26213) in the study course Real Time Embedded System 2018-19 at Hochschule Rhein-Waal. The application involves
6 |
7 | - Develop a prototype sensor system with [ESP32] and [MPU6050] which can publish/send the acceleration and gyroscope 6 axial data.
8 | - Subscribe for the data the store it in [InfluxDB]
9 | - Post the data to [ThingSpeak] Portal
10 | - Monitor the 6 axial (3-axis gyroscope and a 3-axis accelerometer) data on [Grafana]
11 |
12 | ___
13 |
14 |
15 | - [1. Introduction](#1-introduction)
16 | - [2. Architecture overview](#2-architecture-overview)
17 | - [3. Technology review](#3-technology-review)
18 | * [3.1 ESP32](#31-esp32)
19 | * [3.2 Accelerometer and Gyroscope sensors](#32-accelerometer-and-gyroscope-sensors)
20 | * [3.3 Node-RED](#33-node-red)
21 | * [3.4 MQTT](#34-mqtt)
22 | - [3.4.1 Installation](#341-installation)
23 | * [3.5 InfluxDB](#35-influxdb)
24 | * [3.6 Grafana](#36-grafana)
25 |
26 | ### 1. Introduction
27 |
28 | Compact I2C devices like Gyroscope Sensor can help in the axial monitoring system which detects the parameters and shares it to user through MQTT and can be monitored on [Grafana] or can be controlled via mobile devices. This motion tracking system can also help to detect intrusions at homes or any commercial building with proper implementation. This project is prototype of such a system where the data is visualised on [Grafana]. In addition the project also has an Andorid application which notifies the user in case of any intrusion.
29 |
30 | #### 2. Architecture overview
31 | ![Arc1]
32 | The current application has two parts implementation
33 | 1. Publish the sensor readings and subscribe for the values via [MQTT] broker on [Node-RED]. Join all the sensor data and insert it into [InfluxDB] which is a time series database and finally we query the data on [Grafana] for monitoring and visualising.
34 | 2. Post the sensor data to [ThingSpeak] portal which in turn will give an REST api. This api can be configured in Android. Based on the 3-Axis accelerometer the user will recceive the notification in case of any intrusion detection.
35 |
36 | The first approach via MQTT broker has been the primary focus of this project. However the instruction set for the Android project can be found [here](/Documentation/Android.md)
37 |
38 | ### 3. Technology Review
39 |
40 |
41 | #### 3.1 ESP32
42 | ESP32 is a low power system on chip microcontroller with integrated Wi-Fi and dual bluetooth modes. Its low power design is suitable for IoT application. For this implementation we have chosen, WIFI Lora 32 provided by Heltec which has a ESP32 microprocessor with integrated WiFi, LoRa and Bluetooth connectivity modules. This board has been chosen for its ability to communicate over Wi-Fi, making it easier to send data to either [ThingSpeak] or utilize [MQTT] broker to publish data to chosen topics. It also supports Arduino Development environment, making it easier to program codes with Arduino IDE. The steps to setup ESP32 with Arduino IDE can be found [here](https://github.com/v2h/ESP32_WiFi_Demo)
43 |
44 | #### 3.2 Accelerometer and Gyroscope sensors
45 | MPU6050 is used for reading accelerometer and gyroscope readings. It provides a 3-axis gyroscope and a 3-axis accelerometer readings. The digital output is via I²C protocol. To establish communication between this sensor and the board we have to use the [Wire](https://www.arduino.cc/en/reference/wire) library provided by Arduino. Below code is used to read data from the sensor.
46 | ```
47 | MPU6050 accelgyro;
48 | int16_t ax, ay, az;
49 | int16_t gx, gy, gz;
50 | ...
51 | accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
52 | ```
53 | The connections between the Heltec board and MPU6050 is as below:
54 |
55 | | MPU6050 | Heltec ESP32 |
56 | |---------|--------------|
57 | |VCC|3V3|
58 | |GND|GND|
59 | |SCL|22|
60 | |SDA|21|
61 |
62 | Install the following libraries for the implementation:
63 | - MPU6050 - Library to use MPU6050 functionalities in IDE
64 | - PubSubClient - For MQTT connections
65 | - ThingSpeak - For connecting to ThingSpeak
66 | - WireData - To simplify data sending over I²C
67 |
68 | In Arduino IDE navigate to Tools -> Manage Libraries... and search for the following libraries and install them.
69 |
70 | #### 3.3 Node-RED
71 |
72 | Node-RED is a light-weight programming tool built on Node.js for wiring the hardware components together as nodes, APIs and online service in a new and interesting way. It provides a browser-based flow editor that makes it easy to wire together flows using the wide range of nodes in the palette. This makes it ideal to run at the edge of the network on low-cost hardware such as the Raspberry Pi as well as in the cloud.The flows created in Node-RED are stored using JSON which can be easily imported and exported for sharing with others. An online flow library allows you to share your best flows with the world.
73 |
74 | The complete installation guide, instruction sets, different types of nodes used and the wiring mechanism can be found [here](/Documentation/Node-RED.md) in detail.
75 |
76 | #### 3.4 MQTT
77 |
78 | MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol [MQTT]. It stands for MQ Telemetry Transport but previously was known as Message Queuing Telemetry Transport. It's a lightweight publish/subscribe messaging protocol designed for M2M (machine to machine) telemetry in low bandwidth environments.MQTT is fast becoming one of the main protocols for IOT (internet of things) deployments. See [MQTT vs HTTP] for the comparison of performances.
79 |
80 | #### 3.4.1 Installation
81 |
82 | Download the suitable MQTT broker from [MOSQUITTO] and install it on your PC/Laptop.
83 |
84 | Once installation is done navigate to _C:\Program Files\mosquitto_(_on windows_) or wherever the broker is installed and run _mosquitto.exe_
85 |
86 | By default the mosquitto broker runs on port **1883**, but it can be modified inside _C:\Program Files\mosquitto\mosquitto.conf_
87 |
88 | You can now connect to the broker using your machine's IP along with post number ,
89 | ```
90 | #include
91 | #include
92 | WiFiClient espClient;
93 | PubSubClient client(espClient);
94 |
95 | //Ip address of your machine
96 | const char* mqtt_server = "local_IPv4_addr";
97 |
98 | void setup() {
99 | .
100 | .
101 | setup_wifi();
102 | client.setServer(mqtt_server, 1883);
103 | .
104 | .
105 | }
106 |
107 | void loop() {
108 | .
109 | .
110 | client.publish("esp32/XAcc", String(ax).c_str(), true);
111 | client.publish("esp32/YAcc", String(ax).c_str(), true);
112 | client.publish("esp32/XGyr", String(ax).c_str(), true);
113 | .
114 | .
115 | ```
116 | Complete code can be found [here](/Code/ESP32-MPU6050/MQTTClient.ino). Once you run the program on your board you will be able to subscribe to above mentioned sensor readings in the code snippet.
117 |
118 |
119 | #### 3.5 InfluxDB
120 | InfluxDB is an open source time series database platform. This includes APIs for storing and querying data, processing it in the background for ETL or monitoring and alerting purposes, user dashboards, and visualizing and exploring the data and more. InfluxDB is very easy to start and scale time series data gives deep insights for unified metrics and events. It has diverted the industry focus from Relational database like SQL and has become vital for IoT based businesses to capture and analyze untapped data from virtual and physical assets to seize new opportunities.
121 |
122 | The complete installation guide, instruction sets and set up can be found [here](/Documentation/InfluxDB.md) in detail.
123 |
124 |
125 | #### 3.6 Grafana
126 | Grafana is the leading open source software for time series analytics. The tool for beautiful monitoring and metric analytics & dashboards for Graphite, InfluxDB & Prometheus & More [Grafana].
127 | Head to [doc-grafana](/Documentation/Grafana.md) for documentation and its implementation in the current project.
128 |
129 | ----
130 |
131 |
132 | [//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)
133 |
134 |
135 | [ThingSpeak]:
136 | [Grafana]: https://grafana.com/
137 | [InfluxDB]:
138 | [MPU6050]:
139 | [ESP32]:
140 | [Heltec WiFi LoRa 32]:
141 | [MQTT]:
142 | [Node-RED]:
143 | [MQTT vs HTTP]:
144 | [MOSQUITTO]:
145 | [@tjholowaychuk]:
146 | [express]:
147 | [AngularJS]:
148 | [Gulp]:
149 |
150 | [Arc1]:
151 | [PlGh]:
152 | [PlGd]:
153 | [PlOd]:
154 | [PlMe]:
155 | [PlGa]:
156 |
--------------------------------------------------------------------------------
/Code/Grafana-JSON/Intrusion data-1564143087749.json:
--------------------------------------------------------------------------------
1 | {
2 | "__inputs": [
3 | {
4 | "name": "DS_INFLUXDB-MQTT",
5 | "label": "InfluxDB-MQTT",
6 | "description": "",
7 | "type": "datasource",
8 | "pluginId": "influxdb",
9 | "pluginName": "InfluxDB"
10 | }
11 | ],
12 | "__requires": [
13 | {
14 | "type": "panel",
15 | "id": "bargauge",
16 | "name": "Bar Gauge",
17 | "version": ""
18 | },
19 | {
20 | "type": "grafana",
21 | "id": "grafana",
22 | "name": "Grafana",
23 | "version": "6.2.5"
24 | },
25 | {
26 | "type": "panel",
27 | "id": "graph",
28 | "name": "Graph",
29 | "version": ""
30 | },
31 | {
32 | "type": "panel",
33 | "id": "heatmap",
34 | "name": "Heatmap",
35 | "version": ""
36 | },
37 | {
38 | "type": "datasource",
39 | "id": "influxdb",
40 | "name": "InfluxDB",
41 | "version": "1.0.0"
42 | }
43 | ],
44 | "annotations": {
45 | "list": [
46 | {
47 | "builtIn": 1,
48 | "datasource": "-- Grafana --",
49 | "enable": true,
50 | "hide": true,
51 | "iconColor": "rgba(0, 211, 255, 1)",
52 | "name": "Annotations & Alerts",
53 | "type": "dashboard"
54 | }
55 | ]
56 | },
57 | "editable": true,
58 | "gnetId": null,
59 | "graphTooltip": 0,
60 | "id": null,
61 | "links": [],
62 | "panels": [
63 | {
64 | "datasource": "${DS_INFLUXDB-MQTT}",
65 | "gridPos": {
66 | "h": 8,
67 | "w": 12,
68 | "x": 0,
69 | "y": 0
70 | },
71 | "id": 8,
72 | "links": [],
73 | "options": {
74 | "displayMode": "lcd",
75 | "fieldOptions": {
76 | "calcs": [
77 | "first"
78 | ],
79 | "defaults": {
80 | "max": 100,
81 | "min": 0,
82 | "unit": "accG"
83 | },
84 | "mappings": [],
85 | "override": {},
86 | "thresholds": [
87 | {
88 | "color": "dark-green",
89 | "index": 0,
90 | "value": null
91 | },
92 | {
93 | "color": "light-green",
94 | "index": 1,
95 | "value": 20
96 | },
97 | {
98 | "color": "#EAB839",
99 | "index": 2,
100 | "value": 40
101 | },
102 | {
103 | "color": "dark-red",
104 | "index": 3,
105 | "value": 80
106 | }
107 | ],
108 | "values": false
109 | },
110 | "orientation": "horizontal"
111 | },
112 | "pluginVersion": "6.2.5",
113 | "targets": [
114 | {
115 | "groupBy": [],
116 | "measurement": "intrusionMeasurement",
117 | "orderByTime": "ASC",
118 | "policy": "default",
119 | "refId": "A",
120 | "resultFormat": "time_series",
121 | "select": [
122 | [
123 | {
124 | "params": [
125 | "esp32/XGyro"
126 | ],
127 | "type": "field"
128 | }
129 | ],
130 | [
131 | {
132 | "params": [
133 | "esp32/YGyro"
134 | ],
135 | "type": "field"
136 | }
137 | ],
138 | [
139 | {
140 | "params": [
141 | "esp32/ZGyro"
142 | ],
143 | "type": "field"
144 | }
145 | ]
146 | ],
147 | "tags": []
148 | }
149 | ],
150 | "timeFrom": null,
151 | "timeShift": null,
152 | "title": "3 Axial Gyro guage",
153 | "transparent": true,
154 | "type": "bargauge"
155 | },
156 | {
157 | "datasource": "${DS_INFLUXDB-MQTT}",
158 | "gridPos": {
159 | "h": 9,
160 | "w": 12,
161 | "x": 12,
162 | "y": 0
163 | },
164 | "id": 6,
165 | "links": [],
166 | "options": {
167 | "displayMode": "lcd",
168 | "fieldOptions": {
169 | "calcs": [
170 | "last"
171 | ],
172 | "defaults": {
173 | "max": 100,
174 | "min": 0,
175 | "title": "",
176 | "unit": "accG"
177 | },
178 | "mappings": [
179 | {
180 | "from": "",
181 | "id": 1,
182 | "operator": "",
183 | "text": "",
184 | "to": "",
185 | "type": 1,
186 | "value": ""
187 | }
188 | ],
189 | "override": {},
190 | "thresholds": [
191 | {
192 | "color": "dark-green",
193 | "index": 0,
194 | "value": null
195 | },
196 | {
197 | "color": "semi-dark-green",
198 | "index": 1,
199 | "value": 40
200 | },
201 | {
202 | "color": "dark-yellow",
203 | "index": 2,
204 | "value": 80
205 | },
206 | {
207 | "color": "dark-red",
208 | "index": 3,
209 | "value": 90
210 | }
211 | ],
212 | "values": false
213 | },
214 | "orientation": "horizontal"
215 | },
216 | "targets": [
217 | {
218 | "groupBy": [],
219 | "measurement": "intrusionMeasurement",
220 | "orderByTime": "ASC",
221 | "policy": "default",
222 | "refId": "A",
223 | "resultFormat": "time_series",
224 | "select": [
225 | [
226 | {
227 | "params": [
228 | "esp32/XAcc"
229 | ],
230 | "type": "field"
231 | }
232 | ],
233 | [
234 | {
235 | "params": [
236 | "esp32/YAcc"
237 | ],
238 | "type": "field"
239 | }
240 | ],
241 | [
242 | {
243 | "params": [
244 | "esp32/ZAcc"
245 | ],
246 | "type": "field"
247 | }
248 | ]
249 | ],
250 | "tags": []
251 | }
252 | ],
253 | "timeFrom": null,
254 | "timeShift": null,
255 | "title": "3 Axial Acceleration Guage",
256 | "transparent": true,
257 | "type": "bargauge"
258 | },
259 | {
260 | "cards": {
261 | "cardPadding": null,
262 | "cardRound": null
263 | },
264 | "color": {
265 | "cardColor": "#b4ff00",
266 | "colorScale": "sqrt",
267 | "colorScheme": "interpolateWarm",
268 | "exponent": 0.5,
269 | "mode": "spectrum"
270 | },
271 | "dataFormat": "timeseries",
272 | "datasource": "${DS_INFLUXDB-MQTT}",
273 | "gridPos": {
274 | "h": 8,
275 | "w": 12,
276 | "x": 0,
277 | "y": 8
278 | },
279 | "heatmap": {},
280 | "hideZeroBuckets": false,
281 | "highlightCards": true,
282 | "id": 12,
283 | "legend": {
284 | "show": true
285 | },
286 | "links": [],
287 | "options": {},
288 | "reverseYBuckets": false,
289 | "targets": [
290 | {
291 | "groupBy": [],
292 | "measurement": "intrusionMeasurement",
293 | "orderByTime": "ASC",
294 | "policy": "default",
295 | "refId": "A",
296 | "resultFormat": "time_series",
297 | "select": [
298 | [
299 | {
300 | "params": [
301 | "esp32/XGyro"
302 | ],
303 | "type": "field"
304 | }
305 | ],
306 | [
307 | {
308 | "params": [
309 | "esp32/YGyro"
310 | ],
311 | "type": "field"
312 | }
313 | ],
314 | [
315 | {
316 | "params": [
317 | "esp32/ZGyro"
318 | ],
319 | "type": "field"
320 | }
321 | ]
322 | ],
323 | "tags": []
324 | }
325 | ],
326 | "timeFrom": null,
327 | "timeShift": null,
328 | "title": "Gyro Heatmap",
329 | "tooltip": {
330 | "show": true,
331 | "showHistogram": false
332 | },
333 | "transparent": true,
334 | "type": "heatmap",
335 | "xAxis": {
336 | "show": true
337 | },
338 | "xBucketNumber": null,
339 | "xBucketSize": null,
340 | "yAxis": {
341 | "decimals": null,
342 | "format": "short",
343 | "logBase": 1,
344 | "max": null,
345 | "min": null,
346 | "show": true,
347 | "splitFactor": null
348 | },
349 | "yBucketBound": "auto",
350 | "yBucketNumber": null,
351 | "yBucketSize": null
352 | },
353 | {
354 | "cards": {
355 | "cardPadding": null,
356 | "cardRound": null
357 | },
358 | "color": {
359 | "cardColor": "#b4ff00",
360 | "colorScale": "sqrt",
361 | "colorScheme": "interpolatePlasma",
362 | "exponent": 0.5,
363 | "mode": "spectrum"
364 | },
365 | "dataFormat": "timeseries",
366 | "datasource": "${DS_INFLUXDB-MQTT}",
367 | "gridPos": {
368 | "h": 8,
369 | "w": 12,
370 | "x": 12,
371 | "y": 9
372 | },
373 | "heatmap": {},
374 | "hideZeroBuckets": false,
375 | "highlightCards": true,
376 | "id": 10,
377 | "legend": {
378 | "show": true
379 | },
380 | "links": [],
381 | "options": {},
382 | "reverseYBuckets": false,
383 | "targets": [
384 | {
385 | "groupBy": [],
386 | "measurement": "intrusionMeasurement",
387 | "orderByTime": "ASC",
388 | "policy": "default",
389 | "refId": "A",
390 | "resultFormat": "time_series",
391 | "select": [
392 | [
393 | {
394 | "params": [
395 | "esp32/XAcc"
396 | ],
397 | "type": "field"
398 | }
399 | ],
400 | [
401 | {
402 | "params": [
403 | "esp32/YAcc"
404 | ],
405 | "type": "field"
406 | }
407 | ],
408 | [
409 | {
410 | "params": [
411 | "esp32/ZAcc"
412 | ],
413 | "type": "field"
414 | }
415 | ]
416 | ],
417 | "tags": []
418 | }
419 | ],
420 | "timeFrom": null,
421 | "timeShift": null,
422 | "title": "Acceleration heatmap",
423 | "tooltip": {
424 | "show": true,
425 | "showHistogram": false
426 | },
427 | "transparent": true,
428 | "type": "heatmap",
429 | "xAxis": {
430 | "show": true
431 | },
432 | "xBucketNumber": null,
433 | "xBucketSize": null,
434 | "yAxis": {
435 | "decimals": null,
436 | "format": "short",
437 | "logBase": 1,
438 | "max": null,
439 | "min": null,
440 | "show": true,
441 | "splitFactor": null
442 | },
443 | "yBucketBound": "auto",
444 | "yBucketNumber": null,
445 | "yBucketSize": null
446 | },
447 | {
448 | "aliasColors": {},
449 | "bars": true,
450 | "dashLength": 10,
451 | "dashes": false,
452 | "datasource": "${DS_INFLUXDB-MQTT}",
453 | "description": "Gyro scope data over all 3 axis",
454 | "fill": 1,
455 | "gridPos": {
456 | "h": 8,
457 | "w": 12,
458 | "x": 0,
459 | "y": 16
460 | },
461 | "id": 4,
462 | "legend": {
463 | "avg": false,
464 | "current": false,
465 | "max": false,
466 | "min": false,
467 | "show": true,
468 | "total": false,
469 | "values": false
470 | },
471 | "lines": true,
472 | "linewidth": 1,
473 | "links": [],
474 | "nullPointMode": "null",
475 | "options": {},
476 | "percentage": false,
477 | "pointradius": 2,
478 | "points": false,
479 | "renderer": "flot",
480 | "seriesOverrides": [],
481 | "spaceLength": 10,
482 | "stack": false,
483 | "steppedLine": false,
484 | "targets": [
485 | {
486 | "groupBy": [],
487 | "measurement": "intrusionMeasurement",
488 | "orderByTime": "ASC",
489 | "policy": "default",
490 | "refId": "A",
491 | "resultFormat": "time_series",
492 | "select": [
493 | [
494 | {
495 | "params": [
496 | "esp32/XGyro"
497 | ],
498 | "type": "field"
499 | }
500 | ],
501 | [
502 | {
503 | "params": [
504 | "esp32/YGyro"
505 | ],
506 | "type": "field"
507 | }
508 | ],
509 | [
510 | {
511 | "params": [
512 | "esp32/ZGyro"
513 | ],
514 | "type": "field"
515 | }
516 | ]
517 | ],
518 | "tags": []
519 | }
520 | ],
521 | "thresholds": [
522 | {
523 | "colorMode": "critical",
524 | "fill": true,
525 | "line": true,
526 | "op": "gt",
527 | "value": 1500,
528 | "yaxis": "left"
529 | },
530 | {
531 | "colorMode": "warning",
532 | "fill": true,
533 | "line": true,
534 | "op": "gt",
535 | "value": 1000,
536 | "yaxis": "left"
537 | },
538 | {
539 | "colorMode": "ok",
540 | "fill": true,
541 | "line": true,
542 | "op": "gt",
543 | "value": 500,
544 | "yaxis": "left"
545 | }
546 | ],
547 | "timeFrom": null,
548 | "timeRegions": [],
549 | "timeShift": null,
550 | "title": "3 Axial Gyo",
551 | "tooltip": {
552 | "shared": true,
553 | "sort": 0,
554 | "value_type": "individual"
555 | },
556 | "transparent": true,
557 | "type": "graph",
558 | "xaxis": {
559 | "buckets": null,
560 | "mode": "time",
561 | "name": null,
562 | "show": true,
563 | "values": []
564 | },
565 | "yaxes": [
566 | {
567 | "format": "short",
568 | "label": null,
569 | "logBase": 1,
570 | "max": null,
571 | "min": null,
572 | "show": true
573 | },
574 | {
575 | "format": "short",
576 | "label": null,
577 | "logBase": 1,
578 | "max": null,
579 | "min": null,
580 | "show": true
581 | }
582 | ],
583 | "yaxis": {
584 | "align": false,
585 | "alignLevel": null
586 | }
587 | },
588 | {
589 | "aliasColors": {
590 | "intrusionMeasurement.esp32/XAcc": "dark-green",
591 | "intrusionMeasurement.esp32/YAcc": "dark-yellow",
592 | "intrusionMeasurement.esp32/ZAcc": "dark-blue"
593 | },
594 | "bars": true,
595 | "dashLength": 10,
596 | "dashes": false,
597 | "datasource": "${DS_INFLUXDB-MQTT}",
598 | "description": "Graph shows the 3 axial (X,Y, Z) acceleration over the course of a time.",
599 | "fill": 1,
600 | "gridPos": {
601 | "h": 9,
602 | "w": 12,
603 | "x": 12,
604 | "y": 17
605 | },
606 | "id": 2,
607 | "legend": {
608 | "avg": false,
609 | "current": false,
610 | "max": false,
611 | "min": false,
612 | "show": true,
613 | "total": false,
614 | "values": false
615 | },
616 | "lines": true,
617 | "linewidth": 1,
618 | "links": [],
619 | "nullPointMode": "null",
620 | "options": {},
621 | "percentage": false,
622 | "pointradius": 2,
623 | "points": false,
624 | "renderer": "flot",
625 | "seriesOverrides": [],
626 | "spaceLength": 10,
627 | "stack": false,
628 | "steppedLine": false,
629 | "targets": [
630 | {
631 | "groupBy": [],
632 | "measurement": "intrusionMeasurement",
633 | "orderByTime": "ASC",
634 | "policy": "default",
635 | "refId": "A",
636 | "resultFormat": "time_series",
637 | "select": [
638 | [
639 | {
640 | "params": [
641 | "esp32/XAcc"
642 | ],
643 | "type": "field"
644 | }
645 | ],
646 | [
647 | {
648 | "params": [
649 | "esp32/YAcc"
650 | ],
651 | "type": "field"
652 | }
653 | ],
654 | [
655 | {
656 | "params": [
657 | "esp32/ZAcc"
658 | ],
659 | "type": "field"
660 | }
661 | ]
662 | ],
663 | "tags": []
664 | }
665 | ],
666 | "thresholds": [
667 | {
668 | "colorMode": "critical",
669 | "fill": true,
670 | "line": true,
671 | "op": "gt",
672 | "value": 5000,
673 | "yaxis": "left"
674 | },
675 | {
676 | "colorMode": "warning",
677 | "fill": true,
678 | "line": true,
679 | "op": "gt",
680 | "value": 3000,
681 | "yaxis": "left"
682 | },
683 | {
684 | "colorMode": "ok",
685 | "fill": true,
686 | "line": true,
687 | "op": "gt",
688 | "value": 1000,
689 | "yaxis": "left"
690 | }
691 | ],
692 | "timeFrom": null,
693 | "timeRegions": [],
694 | "timeShift": null,
695 | "title": "3-Axial Acceleration",
696 | "tooltip": {
697 | "shared": true,
698 | "sort": 0,
699 | "value_type": "individual"
700 | },
701 | "transparent": true,
702 | "type": "graph",
703 | "xaxis": {
704 | "buckets": null,
705 | "mode": "time",
706 | "name": null,
707 | "show": true,
708 | "values": []
709 | },
710 | "yaxes": [
711 | {
712 | "format": "short",
713 | "label": null,
714 | "logBase": 1,
715 | "max": null,
716 | "min": null,
717 | "show": true
718 | },
719 | {
720 | "format": "short",
721 | "label": null,
722 | "logBase": 1,
723 | "max": null,
724 | "min": null,
725 | "show": true
726 | }
727 | ],
728 | "yaxis": {
729 | "align": false,
730 | "alignLevel": null
731 | }
732 | }
733 | ],
734 | "refresh": false,
735 | "schemaVersion": 18,
736 | "style": "dark",
737 | "tags": [],
738 | "templating": {
739 | "list": []
740 | },
741 | "time": {
742 | "from": "2019-07-26T08:13:52.536Z",
743 | "to": "2019-07-26T12:15:26.488Z"
744 | },
745 | "timepicker": {
746 | "refresh_intervals": [
747 | "5s",
748 | "10s",
749 | "30s",
750 | "1m",
751 | "5m",
752 | "15m",
753 | "30m",
754 | "1h",
755 | "2h",
756 | "1d"
757 | ],
758 | "time_options": [
759 | "5m",
760 | "15m",
761 | "1h",
762 | "6h",
763 | "12h",
764 | "24h",
765 | "2d",
766 | "7d",
767 | "30d"
768 | ]
769 | },
770 | "timezone": "",
771 | "title": "Intrusion data",
772 | "uid": "zA9SYwHWz",
773 | "version": 15
774 | }
--------------------------------------------------------------------------------