// ==========================================
// ضع الـ Template ID الخاص بك هنا
// ==========================================
// ==========================================
// املأ هذه البيانات من موقع Blynk Console
#define BLYNK_TEMPLATE_ID "TMPL6NaN_OiL6" // <--- امسح هذا النص وضع الكود الذي نسخته (يبدأ بـ TMPL)
// =============================================================
// تذكير: ضع بيانات Blynk الخاصة بك هنا
// =============================================================
#define BLYNK_TEMPLATE_ID "TMPLxxxxxxxxx" // <--- ضع الـ ID الخاص بك
#define BLYNK_TEMPLATE_NAME "Bulut Tabanlı Aydınlatma Yönetim Sistemleri"
#define BLYNK_AUTH_TOKEN "-2gX7LDcqt_I3qa5fI0tYZEIjEe9mPYx"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h> // ضرورية للاتصال I2C
#include <BH1750.h> // مكتبة الحساس الجديد
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// تعريف الحساس
BH1750 lightMeter;
// تعريف الأرجل
const int ledPins[] = {13, 12, 14, 27};
const int buttonPins[] = {26, 25, 33, 32};
// ملاحظة: ألغينا ldrPin لأننا نستخدم I2C (GPIO 21, 22)
// إعدادات PWM
const int freq = 5000;
const int resolution = 8;
// متغيرات النظام
bool ledState[] = {false, false, false, false};
bool lastButtonState[] = {HIGH, HIGH, HIGH, HIGH};
unsigned long roomTimer[4] = {0, 0, 0, 0};
const long maxDuration = 10000; // 10 ثواني
// متغيرات التكلفة
float bulbRating = 9.0;
float electricityPrice = 2.6;
double totalCost[] = {0.0, 0.0, 0.0, 0.0};
unsigned long lastCostUpdate = 0;
unsigned long lastGaugeUpdate = 0;
void updateRoomState(int roomIndex, int state) {
ledState[roomIndex] = state;
if (state) {
roomTimer[roomIndex] = millis();
Serial.print("Room "); Serial.print(roomIndex + 1); Serial.println(" ON.");
} else {
Serial.print("Room "); Serial.print(roomIndex + 1); Serial.println(" OFF.");
Blynk.virtualWrite(V8 + roomIndex, 0);
}
}
BLYNK_WRITE(V0) { updateRoomState(0, param.asInt()); }
BLYNK_WRITE(V1) { updateRoomState(1, param.asInt()); }
BLYNK_WRITE(V2) { updateRoomState(2, param.asInt()); }
BLYNK_WRITE(V3) { updateRoomState(3, param.asInt()); }
void setup() {
Serial.begin(115200);
// 1. تشغيل بروتوكول I2C والحساس
Wire.begin();
if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println(F("BH1750 Initialized Successfully!"));
} else {
Serial.println(F("Error initializing BH1750 - Check Connection!"));
}
for(int i=0; i<4; i++) ledcAttach(ledPins[i], freq, resolution);
for(int i=0; i<4; i++) pinMode(buttonPins[i], INPUT_PULLUP);
Serial.println("Connecting to Blynk...");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
Serial.println("System Connected!");
}
void loop() {
Blynk.run();
// 2. قراءة الحساس الجديد (الفرق الكبير هنا)
float lux = lightMeter.readLightLevel();
// طباعة القيمة للتأكد
static unsigned long lastPrint = 0;
if (millis() - lastPrint > 1000) {
Serial.print("Light Level: "); Serial.print(lux); Serial.println(" lx");
lastPrint = millis();
}
// تحويل اللوكس إلى سطوع (عكسي)
// افترضنا أن 1000 لوكس هو ضوء النهار القوي -> سطوع اللمبات 0
int targetBrightness;
if (lux >= 1000) {
targetBrightness = 0;
} else {
targetBrightness = map((long)lux, 0, 1000, 255, 0);
}
// 3. الأزرار اليدوية
for(int i=0; i<4; i++) {
bool currentReading = digitalRead(buttonPins[i]);
if (lastButtonState[i] == HIGH && currentReading == LOW) {
int newState = !ledState[i];
updateRoomState(i, newState);
Blynk.virtualWrite(V0 + i, newState);
}
lastButtonState[i] = currentReading;
}
// 4. المؤقتات والتشغيل
unsigned long currentMillis = millis();
bool shouldUpdateGauge = (currentMillis - lastGaugeUpdate >= 200);
for(int i=0; i<4; i++) {
if (ledState[i]) {
unsigned long elapsed = currentMillis - roomTimer[i];
if (elapsed >= maxDuration) {
ledState[i] = false;
ledcWrite(ledPins[i], 0);
Blynk.virtualWrite(V0 + i, 0);
Blynk.virtualWrite(V8 + i, 0);
} else {
// هنا نستخدم السطوع المحسوب من الحساس الجديد
ledcWrite(ledPins[i], targetBrightness);
if (shouldUpdateGauge) {
double hoursElapsed = ((double)elapsed / (double)maxDuration) * 12.0;
Blynk.virtualWrite(V8 + i, hoursElapsed);
}
}
} else {
ledcWrite(ledPins[i], 0);
}
}
if (shouldUpdateGauge) lastGaugeUpdate = currentMillis;
// 5. حساب التكلفة
if (currentMillis - lastCostUpdate >= 1000) {
float timeFactor = 1.0;
for(int i=0; i<4; i++) {
if (ledState[i]) {
float dimFactor = (float)targetBrightness / 255.0;
float currentWatts = bulbRating * dimFactor;
double costIncrement = (currentWatts / 1000.0) * timeFactor * electricityPrice;
totalCost[i] += costIncrement;
Blynk.virtualWrite(V4 + i, totalCost[i]);
}
}
lastCostUpdate = currentMillis;
}
delay(50);
}