Spaces:
Sleeping
Sleeping
GitHub Actions
commited on
Commit
·
37698a6
1
Parent(s):
a2da031
Deploy from GitHub Actions
Browse files- README.md +9 -7
- data_logger.py +13 -9
- hardware/esp32_sensor_code.ino +45 -5
README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
| 3 |
colorFrom: blue
|
| 4 |
colorTo: green
|
| 5 |
sdk: gradio
|
|
@@ -8,12 +9,13 @@ app_file: app.py
|
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
-
# Zodiac 1.0: Predictive Engine
|
| 12 |
|
| 13 |
-
This is an MVP of a predictive maintenance system for
|
| 14 |
|
| 15 |
## How to Use This Demo
|
| 16 |
|
| 17 |
-
1. **
|
| 18 |
-
2. **
|
| 19 |
-
3. **Get Prediction:** The model will
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: Zodiac 1.0 Engine Diagnostics
|
| 3 |
+
emoji: 🛠️
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: green
|
| 6 |
sdk: gradio
|
|
|
|
| 9 |
pinned: false
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Zodiac 1.0: Predictive Engine Diagnostics
|
| 13 |
|
| 14 |
+
This is an MVP of a predictive maintenance system for engines. It uses a regression-based AI model (XGBoost) to predict the normal vibration of an engine based on its current operating conditions.
|
| 15 |
|
| 16 |
## How to Use This Demo
|
| 17 |
|
| 18 |
+
1. **Set Operating Conditions:** Use the sliders and dropdowns for input the engine's current RPM, the ambient temperature, fuel level, and sea state.
|
| 19 |
+
2. **Enter Actual Vibration:** In the final box, enter the vibration reading you would get from a real-world sensor.
|
| 20 |
+
3. **Get Prediction:** The model will compare the predicted "normal" vibration to the actual value and determine if it's an anomaly.
|
| 21 |
+
|
data_logger.py
CHANGED
|
@@ -1,36 +1,40 @@
|
|
| 1 |
-
# --- data_logger.py ---
|
| 2 |
-
from flask import Flask, request
|
| 3 |
import pandas as pd
|
| 4 |
import os
|
| 5 |
from datetime import datetime
|
|
|
|
| 6 |
|
| 7 |
app = Flask(__name__)
|
| 8 |
|
| 9 |
-
# Define the data directory and the full path for the CSV file
|
| 10 |
DATA_DIR = 'data'
|
| 11 |
CSV_FILE = os.path.join(DATA_DIR, 'raw_data.csv')
|
| 12 |
|
| 13 |
@app.route('/data', methods=['POST'])
|
| 14 |
def receive_data():
|
| 15 |
try:
|
| 16 |
-
# Ensure the data directory exists
|
| 17 |
os.makedirs(DATA_DIR, exist_ok=True)
|
| 18 |
-
|
| 19 |
data = request.get_json()
|
|
|
|
|
|
|
| 20 |
log_data = {
|
| 21 |
-
'
|
| 22 |
-
'
|
| 23 |
-
'
|
| 24 |
-
'
|
|
|
|
| 25 |
}
|
|
|
|
| 26 |
df_new = pd.DataFrame(log_data)
|
| 27 |
|
| 28 |
if not os.path.exists(CSV_FILE):
|
| 29 |
df_new.to_csv(CSV_FILE, index=False, header=True)
|
| 30 |
else:
|
| 31 |
df_new.to_csv(CSV_FILE, mode='a', index=False, header=False)
|
|
|
|
|
|
|
| 32 |
return "Data received successfully", 200
|
| 33 |
except Exception as e:
|
|
|
|
| 34 |
return "Error", 400
|
| 35 |
|
| 36 |
if __name__ == '__main__':
|
|
|
|
| 1 |
+
# --- data_logger.py (Regression Version) ---
|
|
|
|
| 2 |
import pandas as pd
|
| 3 |
import os
|
| 4 |
from datetime import datetime
|
| 5 |
+
from flask import Flask, request
|
| 6 |
|
| 7 |
app = Flask(__name__)
|
| 8 |
|
|
|
|
| 9 |
DATA_DIR = 'data'
|
| 10 |
CSV_FILE = os.path.join(DATA_DIR, 'raw_data.csv')
|
| 11 |
|
| 12 |
@app.route('/data', methods=['POST'])
|
| 13 |
def receive_data():
|
| 14 |
try:
|
|
|
|
| 15 |
os.makedirs(DATA_DIR, exist_ok=True)
|
|
|
|
| 16 |
data = request.get_json()
|
| 17 |
+
|
| 18 |
+
# Define the columns to match the new hardware output and training script
|
| 19 |
log_data = {
|
| 20 |
+
'rpm': [data.get('rpm')],
|
| 21 |
+
'ambient_temp_c': [data.get('ambient_temp_c')],
|
| 22 |
+
'fuel_level_percent': [data.get('fuel_level_percent')],
|
| 23 |
+
'sea_state': [data.get('sea_state')],
|
| 24 |
+
'az_vibration_actual': [data.get('az_vibration_actual')]
|
| 25 |
}
|
| 26 |
+
|
| 27 |
df_new = pd.DataFrame(log_data)
|
| 28 |
|
| 29 |
if not os.path.exists(CSV_FILE):
|
| 30 |
df_new.to_csv(CSV_FILE, index=False, header=True)
|
| 31 |
else:
|
| 32 |
df_new.to_csv(CSV_FILE, mode='a', index=False, header=False)
|
| 33 |
+
|
| 34 |
+
print(f"Logged: {log_data}")
|
| 35 |
return "Data received successfully", 200
|
| 36 |
except Exception as e:
|
| 37 |
+
print(f"Error: {e}")
|
| 38 |
return "Error", 400
|
| 39 |
|
| 40 |
if __name__ == '__main__':
|
hardware/esp32_sensor_code.ino
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
// --- hardware/esp32_sensor_code.ino ---
|
| 2 |
#include <WiFi.h>
|
| 3 |
#include <HTTPClient.h>
|
| 4 |
#include <Wire.h>
|
|
@@ -18,10 +18,39 @@ Adafruit_MPU6050 mpu;
|
|
| 18 |
OneWire oneWire(ONEWIRE_BUS);
|
| 19 |
DallasTemperature sensors(&oneWire);
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
void loop() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
if(WiFi.status() == WL_CONNECTED) {
|
| 26 |
HTTPClient http;
|
| 27 |
sensors_event_t a, g, temp_event;
|
|
@@ -29,12 +58,23 @@ void loop() {
|
|
| 29 |
sensors.requestTemperatures();
|
| 30 |
float temperatureC = sensors.getTempCByIndex(0);
|
| 31 |
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
http.begin(serverName);
|
| 35 |
http.addHeader("Content-Type", "application/json");
|
| 36 |
http.POST(jsonPayload);
|
| 37 |
http.end();
|
|
|
|
|
|
|
| 38 |
}
|
| 39 |
delay(2000);
|
| 40 |
-
}
|
|
|
|
| 1 |
+
// --- hardware/esp32_sensor_code.ino (Regression Version) ---
|
| 2 |
#include <WiFi.h>
|
| 3 |
#include <HTTPClient.h>
|
| 4 |
#include <Wire.h>
|
|
|
|
| 18 |
OneWire oneWire(ONEWIRE_BUS);
|
| 19 |
DallasTemperature sensors(&oneWire);
|
| 20 |
|
| 21 |
+
// --- Variables for Simulating Conditions ---
|
| 22 |
+
long lastStateChange = 0;
|
| 23 |
+
int rpms[] = {800, 2500, 4000}; // Idle, Cruise, High
|
| 24 |
+
int sea_states[] = {0, 1, 2}; // Calm, Choppy, Stormy
|
| 25 |
+
int current_rpm = 800;
|
| 26 |
+
int current_sea_state = 0;
|
| 27 |
+
float current_fuel = 100.0;
|
| 28 |
+
|
| 29 |
+
void setup() {
|
| 30 |
+
Serial.begin(115200);
|
| 31 |
+
// Initialize sensors and connect to WiFi (full code in previous tutorials)
|
| 32 |
+
WiFi.begin(ssid, password);
|
| 33 |
+
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
|
| 34 |
+
Serial.println("\nWiFi Connected");
|
| 35 |
+
mpu.begin();
|
| 36 |
+
sensors.begin();
|
| 37 |
+
|
| 38 |
+
lastStateChange = millis();
|
| 39 |
+
randomSeed(analogRead(0)); // Seed for random numbers
|
| 40 |
+
}
|
| 41 |
|
| 42 |
void loop() {
|
| 43 |
+
// --- Simulate Changing Conditions every 15 seconds for varied data ---
|
| 44 |
+
if (millis() - lastStateChange > 15000) {
|
| 45 |
+
current_rpm = rpms[random(3)]; // Pick a random RPM state
|
| 46 |
+
current_sea_state = sea_states[random(3)]; // Pick a random sea state
|
| 47 |
+
current_fuel -= random(1, 5); // Simulate fuel consumption
|
| 48 |
+
if (current_fuel < 10) { current_fuel = 100; } // Refuel
|
| 49 |
+
|
| 50 |
+
lastStateChange = millis();
|
| 51 |
+
Serial.println("--- SIMULATING NEW CONDITIONS ---");
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
if(WiFi.status() == WL_CONNECTED) {
|
| 55 |
HTTPClient http;
|
| 56 |
sensors_event_t a, g, temp_event;
|
|
|
|
| 58 |
sensors.requestTemperatures();
|
| 59 |
float temperatureC = sensors.getTempCByIndex(0);
|
| 60 |
|
| 61 |
+
// --- Create JSON payload with REAL and SIMULATED data ---
|
| 62 |
+
String jsonPayload = "{";
|
| 63 |
+
jsonPayload += "\"rpm\":" + String(current_rpm) + ",";
|
| 64 |
+
// NOTE: We use the real sensor temp for 'ambient_temp_c' for this test
|
| 65 |
+
jsonPayload += "\"ambient_temp_c\":" + String(temperatureC) + ",";
|
| 66 |
+
jsonPayload += "\"fuel_level_percent\":" + String(current_fuel) + ",";
|
| 67 |
+
jsonPayload += "\"sea_state\":" + String(current_sea_state) + ",";
|
| 68 |
+
// This is the actual, real vibration reading from the sensor
|
| 69 |
+
jsonPayload += "\"az_vibration_actual\":" + String(a.acceleration.z);
|
| 70 |
+
jsonPayload += "}";
|
| 71 |
|
| 72 |
http.begin(serverName);
|
| 73 |
http.addHeader("Content-Type", "application/json");
|
| 74 |
http.POST(jsonPayload);
|
| 75 |
http.end();
|
| 76 |
+
|
| 77 |
+
Serial.println(jsonPayload);
|
| 78 |
}
|
| 79 |
delay(2000);
|
| 80 |
+
}
|