1. Latar Belakang & Motivasi
Permasalahan
Kualitas observasi astronomi sangat bergantung pada kondisi atmosfer yang tidak bisa dikontrol. Astronomer amatir sering menghadapi masalah: - Mempersiapkan peralatan hanya untuk menemukan kondisi langit buruk - Tidak ada sistem peringatan dini untuk perubahan cuaca mendadak - Kesulitan memprediksi kapan kondisi "seeing" optimal untuk observasi/astrophotography
Atmospheric Seeing
Seeing adalah ukuran degradasi citra astronomi akibat turbulensi atmosfer, diukur dalam satuan arcsecond ("). Seeing yang baik (<2") memungkinkan detail lebih tajam, sedangkan seeing buruk (>4") membuat citra blur meski teleskop berkualitas tinggi.
Faktor yang mempengaruhi seeing: - Gradien suhu antara permukaan dan atmosfer - Kecepatan dan arah angin - Kelembaban udara - Tekanan barometrik - Keberadaan awan
Gap Penelitian
Mayoritas penelitian prediksi seeing dilakukan di observatorium profesional dengan peralatan mahal (DIMM, MASS, dll). Belum ada solusi low-cost untuk astronomer amatir yang mengintegrasikan IoT dan machine learning untuk prediksi kondisi observasi.
2. Rumusan Masalah
- Bagaimana merancang sistem IoT low-cost untuk monitoring kondisi langit yang relevan dengan observasi astronomi?
- Bagaimana mengembangkan model machine learning untuk klasifikasi kondisi langit (clear, cloudy, moonlit)?
- Bagaimana membangun model prediksi kualitas seeing berdasarkan data meteorologi lokal?
- Seberapa akurat sistem yang dikembangkan dibandingkan dengan pengamatan visual?
3. Tujuan Penelitian
Tujuan Umum
Mengembangkan Smart Observatory Weather Station berbasis IoT dengan kemampuan prediksi kondisi observasi menggunakan machine learning.
Tujuan Khusus
- Membangun hardware weather station dengan sensor-sensor relevan untuk astronomi
- Mengembangkan backend system untuk data collection dan storage
- Melatih model ML untuk klasifikasi kondisi langit
- Membangun model prediksi seeing quality index
- Mengembangkan dashboard dan sistem notifikasi
4. Arsitektur Sistem
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SENSOR NODE (Outdoor) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β BME280 β βMLX90614 β β TSL2591 β βAnemometerβ β
β βTemp/Hum/ β βCloud/Sky β βLight/Lux β βWind Speedβ β
β βPressure β βTemp (IR) β βMeter β βDirection β β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ β
β β β β β β
β βββββββββββββββ΄βββββββ¬βββββββ΄ββββββββββββββ β
β β β
β ββββββββ΄βββββββ β
β β ESP32 β β
β β + WiFi β β
β ββββββββ¬βββββββ β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β MQTT/HTTP
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β EDGE SERVER (Raspberry Pi) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββ ββββββββββββββ ββββββββββββββ β
β β MQTT β β PostgreSQL β β Django β β
β β Broker β β TimescaleDBβ β REST API β β
β β(Mosquitto)β β β β β β
β βββββββ¬βββββββ βββββββ¬βββββββ βββββββ¬βββββββ β
β β β β β
β βββββββββββββββββ΄ββββββββ¬ββββββββ β
β β β
β βββββββββββββ΄ββββββββββββ β
β β ML Pipeline β β
β β - Feature Engineeringβ β
β β - Model Inference β β
β β - Prediction Service β β
β βββββββββββββ¬ββββββββββββ β
ββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT LAYER β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββ ββββββββββββββ ββββββββββββββ β
β β Web β β Telegram β β INDI β β
β β Dashboard β β Bot Alert β β Driver β β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
5. Komponen Hardware
5.1 Sensor Suite
| Sensor | Fungsi | Interface | Est. Harga |
|---|---|---|---|
| BME280 | Suhu, kelembaban, tekanan atmosfer | I2C | Rp 35.000 |
| MLX90614-BCF | Sky temperature (cloud detection) | I2C | Rp 85.000 |
| TSL2591 | Sky brightness (lux & IR) | I2C | Rp 65.000 |
| Wind Sensor Kit | Kecepatan & arah angin | Analog | Rp 150.000 |
| Rain Sensor | Deteksi hujan | Digital | Rp 15.000 |
5.2 Controller & Communication
| Komponen | Fungsi | Est. Harga |
|---|---|---|
| ESP32 DevKit | Microcontroller + WiFi | Rp 65.000 |
| Raspberry Pi 4 (2GB) | Edge server | Rp 750.000 |
| MCP3008 | ADC untuk sensor analog | Rp 25.000 |
5.3 Cloud Detection dengan MLX90614
Prinsip kerja: - Sensor IR mengukur suhu langit (sky temperature) - Langit cerah: suhu sangat rendah (-20Β°C sampai -40Β°C) - Berawan: suhu lebih tinggi (mendekati ambient)
Formula Cloud Index:
Sky_Delta = Ambient_Temp - Sky_Temp
Kondisi:
- Sky_Delta β€ 5Β°C β Heavily Cloudy (100%)
- Sky_Delta 5-11Β°C β Mostly Cloudy (75%)
- Sky_Delta 11-16Β°C β Partly Cloudy (50%)
- Sky_Delta 16-19Β°C β Mostly Clear (25%)
- Sky_Delta > 19Β°C β Clear Sky (0%)
5.4 Sky Quality Measurement dengan TSL2591
- Mengukur luminositas dalam lux dan magnitude/arcsecΒ²
- Konversi ke Bortle Scale (1-9) untuk klasifikasi light pollution
- Deteksi moonlight untuk klasifikasi "moonlit nights"
6. Metodologi Machine Learning
6.1 Dataset & Features
Data Collection Period: Minimum 60 hari (2 bulan) Sampling Rate: Setiap 1 menit
Feature Set:
| Feature | Sumber | Tipe |
|---|---|---|
ambient_temp |
BME280 | Continuous |
humidity |
BME280 | Continuous |
pressure |
BME280 | Continuous |
sky_temp |
MLX90614 | Continuous |
sky_delta |
Calculated | Continuous |
sky_brightness |
TSL2591 | Continuous |
wind_speed |
Anemometer | Continuous |
wind_direction |
Wind vane | Categorical |
pressure_trend_1h |
Calculated | Continuous |
temp_gradient_1h |
Calculated | Continuous |
hour_of_day |
System | Cyclical |
moon_phase |
Ephemeris API | Continuous |
moon_altitude |
Ephemeris API | Continuous |
6.2 Target Variables
Task 1: Sky Condition Classification - Class 0: Clear - Class 1: Partly Cloudy - Class 2: Cloudy/Overcast - Class 3: Clear Moonlit - Class 4: Cloudy Moonlit - Class 5: Rain/Unusable
Task 2: Seeing Quality Index Regression - Output: Seeing Quality Score (0-100) - 0-30: Poor (tidak disarankan observasi) - 30-50: Fair (visual observation OK) - 50-70: Good (imaging possible) - 70-100: Excellent (high-res imaging)
6.3 Model Selection
Untuk Klasifikasi (Sky Condition):
# Recommended: Random Forest
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=100,
max_depth=15,
min_samples_split=5,
class_weight='balanced'
)
Alasan: - Robust terhadap outliers - Handles imbalanced classes - Feature importance built-in - Sudah terbukti efektif untuk klasifikasi data SQM
Untuk Regresi (Seeing Index):
# Recommended: Gradient Boosting
from sklearn.ensemble import GradientBoostingRegressor
model = GradientBoostingRegressor(
n_estimators=200,
max_depth=5,
learning_rate=0.1,
loss='huber'
)
6.4 Training Pipeline
# Pseudo-code pipeline
class SeeingPredictionPipeline:
def preprocess(self, df):
# Handle missing values
# Encode cyclical features (hour, wind_direction)
# Calculate derived features
# Normalize continuous features
return processed_df
def extract_features(self, df):
# Statistical features over rolling windows
# 15-min, 30-min, 1-hour aggregations
features = {
'temp_mean_15m': df['ambient_temp'].rolling(15).mean(),
'pressure_std_30m': df['pressure'].rolling(30).std(),
'sky_delta_trend': df['sky_delta'].diff(30),
# ... more features
}
return features
def train(self, X, y):
# Cross-validation with TimeSeriesSplit
# Hyperparameter tuning
# Model selection
pass
def predict(self, current_data):
# Real-time inference
# Return prediction + confidence
pass
6.5 Evaluation Metrics
Klasifikasi: - Accuracy, Precision, Recall, F1-Score - Confusion Matrix - Focus on: Recall untuk class "Rain" (safety-critical)
Regresi: - RMSE (Root Mean Square Error) - MAE (Mean Absolute Error) - RΒ² Score - Target: RMSE < 15 untuk seeing index
7. Implementasi Software
7.1 ESP32 Firmware (MicroPython)
# sensor_node.py
import machine
import network
from umqtt.simple import MQTTClient
import json
import time
class WeatherStation:
def __init__(self):
self.i2c = machine.I2C(0, scl=22, sda=21)
self.bme280 = BME280(i2c=self.i2c)
self.mlx90614 = MLX90614(i2c=self.i2c)
self.tsl2591 = TSL2591(i2c=self.i2c)
def read_sensors(self):
return {
'timestamp': time.time(),
'ambient_temp': self.bme280.temperature,
'humidity': self.bme280.humidity,
'pressure': self.bme280.pressure,
'sky_temp': self.mlx90614.object_temp,
'sensor_temp': self.mlx90614.ambient_temp,
'lux': self.tsl2591.lux,
'ir': self.tsl2591.infrared
}
def publish(self, client, data):
topic = 'observatory/weather'
client.publish(topic, json.dumps(data))
7.2 Django Backend
# models.py
from django.db import models
from timescale.db.models.models import TimescaleModel
class WeatherReading(TimescaleModel):
timestamp = models.DateTimeField(primary_key=True)
ambient_temp = models.FloatField()
humidity = models.FloatField()
pressure = models.FloatField()
sky_temp = models.FloatField()
sky_brightness = models.FloatField()
wind_speed = models.FloatField(null=True)
wind_direction = models.IntegerField(null=True)
class Meta:
ordering = ['-timestamp']
class SkyConditionPrediction(TimescaleModel):
timestamp = models.DateTimeField(primary_key=True)
predicted_class = models.IntegerField()
confidence = models.FloatField()
seeing_index = models.FloatField()
# views.py (API)
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
class WeatherViewSet(viewsets.ModelViewSet):
queryset = WeatherReading.objects.all()
@action(detail=False, methods=['get'])
def current_conditions(self, request):
latest = self.queryset.first()
prediction = self.ml_service.predict(latest)
return Response({
'weather': WeatherSerializer(latest).data,
'prediction': prediction,
'recommendation': self.get_recommendation(prediction)
})
def get_recommendation(self, prediction):
if prediction['seeing_index'] > 70:
return "Excellent conditions! Great for astrophotography."
elif prediction['seeing_index'] > 50:
return "Good conditions for visual observation."
else:
return "Consider waiting for better conditions."
7.3 ML Service
# ml_service.py
import joblib
import numpy as np
from datetime import datetime
class MLPredictionService:
def __init__(self):
self.classifier = joblib.load('models/sky_classifier.pkl')
self.regressor = joblib.load('models/seeing_regressor.pkl')
self.scaler = joblib.load('models/feature_scaler.pkl')
def prepare_features(self, reading, historical_data):
"""Extract features from current and historical readings"""
features = {
'ambient_temp': reading.ambient_temp,
'humidity': reading.humidity,
'pressure': reading.pressure,
'sky_delta': reading.ambient_temp - reading.sky_temp,
'sky_brightness': reading.sky_brightness,
# Add rolling statistics from historical_data
'temp_trend_1h': self.calculate_trend(historical_data, 'ambient_temp'),
'pressure_trend_1h': self.calculate_trend(historical_data, 'pressure'),
}
return np.array(list(features.values())).reshape(1, -1)
def predict(self, reading, historical_data=None):
features = self.prepare_features(reading, historical_data)
scaled_features = self.scaler.transform(features)
sky_class = self.classifier.predict(scaled_features)[0]
sky_proba = self.classifier.predict_proba(scaled_features)[0]
seeing_index = self.regressor.predict(scaled_features)[0]
return {
'sky_condition': int(sky_class),
'sky_condition_label': self.CLASS_LABELS[sky_class],
'confidence': float(max(sky_proba)),
'seeing_index': float(seeing_index),
'seeing_quality': self.get_quality_label(seeing_index)
}
8. Ground Truth & Validation
8.1 Labeling Strategy
Karena tidak memiliki DIMM profesional, gunakan proxy measures:
- Visual Observation Log
- Catat kondisi langit setiap malam observasi
- Rating subjektif 1-5 untuk seeing
-
Foto referensi dengan smartphone
-
Astrophotography Quality
- Analisis FWHM dari star images
-
Bandingkan sharpness antar malam
-
Star Trail Analysis
- Rekam star trail pendek (30 detik)
- Analisis "wobble" sebagai proxy seeing
8.2 Validation Methods
# Cross-validation dengan TimeSeriesSplit
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
scores = []
for train_idx, test_idx in tscv.split(X):
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
scores.append(score)
9. Timeline Pengerjaan
| Minggu | Aktivitas |
|---|---|
| 1-2 | Perancangan sistem & pengadaan komponen |
| 3-4 | Assembly hardware & testing sensor |
| 5-6 | Development firmware ESP32 |
| 7-8 | Setup Raspberry Pi & Django backend |
| 9-12 | Data Collection Phase |
| 13-14 | Data preprocessing & feature engineering |
| 15-16 | Model training & hyperparameter tuning |
| 17-18 | Integration testing & dashboard development |
| 19-20 | Validation & penulisan laporan |
10. Estimasi Biaya
| Kategori | Item | Harga |
|---|---|---|
| Sensor | BME280, MLX90614, TSL2591, Wind kit, Rain | Rp 350.000 |
| Controller | ESP32 DevKit | Rp 65.000 |
| Server | Raspberry Pi 4 (2GB) + SD Card | Rp 850.000 |
| Enclosure | Weatherproof box, mounting | Rp 150.000 |
| Power | Power supply, cables | Rp 100.000 |
| Miscellaneous | PCB, connectors, tools | Rp 200.000 |
| Total | Rp 1.715.000 |
Note: Jika sudah punya Raspberry Pi, budget bisa dikurangi signifikan.
11. Referensi Utama
-
Priyatikanto et al. (2020). "Classification of Continuous Sky Brightness Data Using Random Forest." Advances in Astronomy. [Indonesia-based research]
-
Hou et al. (2023). "Machine learning-based seeing estimation and prediction using multi-layer meteorological data." arXiv:2304.03587
-
MDPI (2025). "Machine-Learning-Based Monitoring of Night Sky Brightness Using Sky Quality Meters." Remote Sensing
-
WeatherRadio Project - INDI Library (Open source astronomical weather station)
12. Potential Extensions
- All-Sky Camera Integration - Tambah fisheye camera untuk visual confirmation
- Satellite Data Fusion - Integrasikan data BMKG atau weather API
- Multi-node Network - Deploy di beberapa lokasi untuk coverage lebih luas
- Mobile App - Notifikasi push ke smartphone
- INDI Driver - Integrasi dengan software astronomi seperti KStars/Ekos
π¬ Comments (0)
Leave a Comment
π No comments yet. Be the first to share your thoughts!