├── Code ├── ESP32-MPU6050 │ ├── MQTTClient.ino │ └── ThingspeakClient.ino ├── Grafana-JSON │ └── Intrusion data-1564143087749.json ├── Node-RED flows │ └── flows.json └── android │ └── rtes │ ├── .gitignore │ ├── .idea │ ├── encodings.xml │ ├── gradle.xml │ ├── misc.xml │ └── runConfigurations.xml │ ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── abi │ │ │ └── rtes │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── abi │ │ │ │ └── rtes │ │ │ │ ├── BaseApplication.java │ │ │ │ ├── base │ │ │ │ ├── NetworkInitiateFactory.java │ │ │ │ └── NetworkInitiateSingleton.java │ │ │ │ ├── constants │ │ │ │ ├── Constants.java │ │ │ │ └── ConstantsURL.java │ │ │ │ ├── data │ │ │ │ └── api │ │ │ │ │ ├── RtesAPI.java │ │ │ │ │ └── channel │ │ │ │ │ ├── Channel.java │ │ │ │ │ ├── ChannelFeedData.java │ │ │ │ │ └── Feed.java │ │ │ │ ├── preference │ │ │ │ └── IAPreference.java │ │ │ │ ├── ui │ │ │ │ └── activity │ │ │ │ │ ├── SplashActivity.java │ │ │ │ │ └── home │ │ │ │ │ ├── HomeActivity.java │ │ │ │ │ ├── HomePresenter.java │ │ │ │ │ ├── HomePresenterImpl.java │ │ │ │ │ └── HomeView.java │ │ │ │ └── utils │ │ │ │ ├── ProgressUtils.java │ │ │ │ └── Utils.java │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ ├── safe.PNG │ │ │ └── unsafe.PNG │ │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ └── activity_splash.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── safe_icon.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── safe_icon.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── safe_icon.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── safe_icon.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── safe_icon.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── abi │ │ └── rtes │ │ └── ExampleUnitTest.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── Documentation ├── Android.md ├── Grafana.md ├── InfluxDB.md └── Node-RED.md └── README.md /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 | -------------------------------------------------------------------------------- /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/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 | } -------------------------------------------------------------------------------- /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/.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/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Code/android/rtes/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /Code/android/rtes/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /Code/android/rtes/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /Code/android/rtes/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /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/drawable/safe.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/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/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/drawable/unsafe.PNG -------------------------------------------------------------------------------- /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/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /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/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-hdpi/safe_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-hdpi/safe_icon.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-mdpi/safe_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-mdpi/safe_icon.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xhdpi/safe_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xhdpi/safe_icon.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xxhdpi/safe_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xxhdpi/safe_icon.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/safe_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/app/src/main/res/mipmap-xxxhdpi/safe_icon.png -------------------------------------------------------------------------------- /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/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Intrusion Detection 3 | 4 | -------------------------------------------------------------------------------- /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/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/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/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/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/droidthings/IntrusionDetection/2a0dc5a36880abb74b7447b9594aed106e0a9c2b/Code/android/rtes/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /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/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/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/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------