#define BLYNK_TEMPLATE_ID "TMPL6h4bHDOfr"
#define BLYNK_TEMPLATE_NAME "led exercise"
#define BLYNK_AUTH_TOKEN "emy_Ch3dQ7w7nqMLfqq1qvdW_knqe9WF"
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <BlynkSimpleEsp32.h>
#include "secret.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DHT.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#define SDA_PIN 17
#define SCL_PIN 16
#define DHTPIN 33
#define LED_PIN 19
#define LED_PIN2 27
#define BUZZpin 25
String inputStr = "";
bool newInput = false;
DHT dht(DHTPIN, DHT22);
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const String endpoint = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=" + String(API_KEY);
void connectWifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(400);
Serial.print(".");
}
}
String makeGeminiRequest(const String& userInput) {
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
String url = String(endpoint);
if(!http.begin(client, url)){
return "failed begin HTTP";
}
http.addHeader("Content-Type", "application/json");
/*siapkan data yang dikirim, dengan header (kasi tau ini JSON), prompt, dan integrasi user input,
hingga menjadi payload yang bisa dikirk
Yang akan digunakan :*/
String systemPrompt =
"kamu adalah seorang classifier "
"kamu akan diberikan suatu deskripsi keaadaan sekarang dan hanya boleh menjawab menggunakan 2 kata yang dipisahkan dengan koma "
"kata kata yang boleh digunakan ialah HIGH,LOW,PAGI,SIANG,MALAM,MALAMT. "
"Jika situasi yang di deskripsikan itu cuaca lagi terang/cerah/ada cahaya/tidak gelap, kamu jawab LOW , SIANG "
"Jika situasi yang di deskripsikan itu cuaca lagi terang/cerah/ada cahaya/tidak gelap, tapi di situasi tertera keterangan eksplisit bahwa itu pagi kamu jawab LOW , PAGI "
"Jika situasi yang di deskripsikan itu cuaca lagi gelap/tidak ada cahaya/tidak kelihatan apa apa/mendung/ada bulan , kamu jawab HIGH , MALAM"
"Jika situasi yang di deskripsikan itu cuaca lagi gelap/tidak ada cahaya/tidak kelihatan apa apa/mendung/ada bulan Dan ada perintah eksplisit bahwa Anak harus tidur kamu jawab HIGH , MALAMT"
"Jika situasi yang di deskripsikan itu cuaca lagi gelap/tidak ada cahaya/tidak kelihatan apa apa/mendung tetapi ada pernyataan eksplisit antara itu pagi / siang maka kamu menjawab HIGH , PAGI atau HIGH , SIANG sesuai pernyataanya"
"jika situasi yang di deskripsikan cerah tanpa memberitahu waktu harinya selalu asumsikan bahwa itu SIANG"
"format penjawaban selalu di pisahkan spasi koma spasi contoh HIGH , MALAM"
"tidak usah beri penjelasan hanya jawab saja";
String finalPrompt = systemPrompt + String("user input : " + userInput);
String payload = String("{\"contents\":[{\"parts\":[{\"text\":\"") +
finalPrompt + "\"}]}]}";
/*
format JSON yang akan dikirim "{\"contents\":[{\"parts\":[{\"text\":\"" +
finalPrompt + "\"}]}]}".
*/
//kirim payload, simoan kode status (integer) dan siapkan tempat untuk respon
int httpCode = http.POST(payload);
String response;
if(httpCode > 0){
response = http.getString();
}else{
response = String("HTTP error : ") + http.errorToString(httpCode);
}
http.end();
return response;
}
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
display.begin(SSD1306_SWITCHCAPVCC, 0x3c);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
dht.begin();
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(LED_PIN2, OUTPUT);
digitalWrite(LED_PIN2, LOW);
connectWifi();
Blynk.begin(BLYNK_AUTH_TOKEN, WIFI_SSID , WIFI_PASSWORD);
Serial.println("ESP32 siap terhubung ke Blynk dan Gemini.");
pinMode(BUZZpin , OUTPUT);
}
BLYNK_WRITE(V0) {
inputStr = param.asStr();
newInput = true;
Serial.print("Teks dari Blynk: ");
Serial.println(inputStr);
}
void loop() {
float temp = dht.readTemperature();
float hum = dht.readHumidity();
Blynk.run();
if (newInput) {
newInput = false;
Serial.println("Mengirim ke gemini : " + inputStr);
String resp = makeGeminiRequest(inputStr);
Serial.println("full respon : ");
Serial.println(resp);
DynamicJsonDocument doc(2048);
DeserializationError error= deserializeJson(doc, resp);
if (!error) {
const char* text = doc["candidates"][0]["content"]["parts"][0]["text"];
if (text) {
String answer = String(text);
answer.trim();
answer.toUpperCase();
Serial.println(answer);
if (answer == "HIGH , MALAM") {
digitalWrite(LED_PIN, HIGH);
digitalWrite(LED_PIN2, HIGH);
Serial.println("LED ON (HIGH)");
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Selamat Malam");
display.print("Suhu : "); display.print(temp); display.println(" C");
display.print("Humiditas : "); display.print(hum); display.println(" %");
display.print("Kamar kerja : "); display.println("Hidup");
display.print("Kamar tidur : "); display.println("Hidup");
display.display();
} else if (answer == "HIGH , MALAMT") {
digitalWrite(LED_PIN, LOW);
digitalWrite(LED_PIN2, HIGH);
Serial.println("LED OFF (LOW)");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Selamat Malam ");
display.print("Suhu : "); display.print(temp); display.println(" C");
display.print("Humiditas : "); display.print(hum); display.println(" %");
display.print("Kamar kerja : "); display.println("Hidup");
display.print("Kamar tidur : "); display.println("Mati");
display.println("BOCIL PADA TIDUR");
display.display();
} else if (answer == "LOW , SIANG") {
digitalWrite(LED_PIN, LOW);
digitalWrite(LED_PIN2, LOW);
Serial.println("LED OFF (LOW)");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Selamat Siang");
display.print("Suhu : "); display.print(temp); display.println(" C");
display.print("Humiditas : "); display.print(hum); display.println(" %");
display.print("Kamar kerja : "); display.println("Mati");
display.print("Kamar tidur : "); display.println("Mati");
display.display();
} else if (answer == "HIGH , SIANG") {
digitalWrite(LED_PIN, HIGH);
digitalWrite(LED_PIN2, HIGH);
Serial.println("LED OFF (LOW)");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Selamat Siang");
display.print("Suhu : "); display.print(temp); display.println(" C");
display.print("Humiditas : "); display.print(hum); display.println(" %");
display.print("Kamar kerja : "); display.println("Hidup");
display.print("Kamar tidur : "); display.println("Hidup");
display.display();
} else if (answer == "HIGH , PAGI") {
digitalWrite(LED_PIN, HIGH);
digitalWrite(LED_PIN2, HIGH);
Serial.println("LED OFF (LOW)");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Selamat Pagi");
display.print("Suhu : "); display.print(temp); display.println(" C");
display.print("Humiditas : "); display.print(hum); display.println(" %");
display.print("Kamar kerja : "); display.println("Hidup");
display.print("Kamar tidur : "); display.println("Hidup");
display.display();
unsigned long startTime = millis();
while (millis() - startTime < 10000) {
digitalWrite(BUZZpin, HIGH);
delay(200);
digitalWrite(BUZZpin, LOW);
delay(200);
}
} else if (answer == "LOW , PAGI") {
digitalWrite(LED_PIN, LOW);
digitalWrite(LED_PIN2, LOW);
Serial.println("LED OFF (LOW)");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Selamat Pagi");
display.print("Suhu : "); display.print(temp); display.println(" C");
display.print("Humiditas : "); display.print(hum); display.println(" %");
display.print("Kamar kerja : "); display.println("Mati");
display.print("Kamar tidur : "); display.println("Mati");
display.display();
unsigned long startTime = millis();
while (millis() - startTime < 10000) {
digitalWrite(BUZZpin, HIGH);
delay(200);
digitalWrite(BUZZpin, LOW);
delay(200);
}
} else {
Serial.println("Unknown : " + answer);
}
} else {
Serial.println("teks gaada");
}
} else {
Serial.println("JSON parsing gagal : ");
Serial.println(error.c_str());
}
}
}