GitHub Actions commited on
Commit
37698a6
·
1 Parent(s): a2da031

Deploy from GitHub Actions

Browse files
Files changed (3) hide show
  1. README.md +9 -7
  2. data_logger.py +13 -9
  3. hardware/esp32_sensor_code.ino +45 -5
README.md CHANGED
@@ -1,5 +1,6 @@
1
- title: Zodiac 1.0 Engine Monitor
2
- emoji: 🛥️
 
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 Monitoring
12
 
13
- This is an MVP of a predictive maintenance system for marine and automotive engines. It uses an AI model to analyze vibration data and detect the early signs of mechanical failure.
14
 
15
  ## How to Use This Demo
16
 
17
- 1. **Get Sample Data:** You can copy the sample data from the `data/raw_data.csv` file in the repository. You will need at least 51 rows.
18
- 2. **Paste Data:** Paste the copied CSV data into the input box.
19
- 3. **Get Prediction:** The model will analyze the last sequence of data and determine if it represents a "Normal" or "Anomalous" engine state.
 
 
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
- 'timestamp': [datetime.now().strftime('%Y-%m-%d %H:%M:%S')],
22
- 'ax': [data.get('ax')], 'ay': [data.get('ay')], 'az': [data.get('az')],
23
- 'gx': [data.get('gx')], 'gy': [data.get('gy')], 'gz': [data.get('gz')],
24
- 'temperature_c': [data.get('temperature_c')]
 
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
- void connectToWiFi() { /* ... connection logic ... */ }
22
- void setup() { /* ... sensor and wifi init ... */ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- String jsonPayload = "{\"ax\":" + String(a.acceleration.x) + ",\"ay\":" + String(a.acceleration.y) + ",\"az\":" + String(a.acceleration.z) + ",\"gx\":" + String(g.gyro.x) + ",\"gy\":" + String(g.gyro.y) + ",\"gz\":" + String(g.gyro.z) + ",\"temperature_c\":" + String(temperatureC) + "}";
 
 
 
 
 
 
 
 
 
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
+ }