Skip to content

Commit debc05a

Browse files
committed
v1.0.6
### What's New - **mDNS Hostname**: Custom `.local` domains (e.g., `dmf.local`, `test.local`) with static IP support - **Mail Groups Popup**: Improved modal design for mail group configuration - **Mobile Design**: 2x2 grid tab layout optimized for mobile devices - **Feature Descriptions**: Extended explanations for system features in 3 languages ### Bug Fixes - Fixed file upload error to mail groups - Corrected modal scroll behavior - Resolved mDNS compilation and runtime issues - Fixed mobile version mDNS compatibility - Configured toggle switches and GUI for mobile version Unresolved known issues: - Captive Portal: In emergency situations, as a third option, open networks with Captive Portal (e.g., cafes, hospitals, public buildings) that offer password-free SSID connections cannot detect the device's internal network login process and do not disconnect and switch to another internet connection. (In short, a blockage occurs in the third option.) Nevertheless, in this "BUG" state, it continues to actively search for the first and backup SSIDs it has registered and connects if it finds them.
1 parent 1e283a7 commit debc05a

File tree

10 files changed

+486
-89
lines changed

10 files changed

+486
-89
lines changed

SmartKraft_DMF/MOBILE_MDNS_TEST.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Mobil mDNS Test Rehberi
2+
3+
## ❌ Neden .local Çalışmıyor?
4+
5+
### Android Cihazlar
6+
- **Chrome/Edge**: mDNS desteği YOK (Android 12'den önce)
7+
- **Firefox**: mDNS desteği YOK
8+
- **Brave/Opera**: mDNS desteği YOK
9+
10+
**Çözüm**:
11+
1. IP adresini kullanın: `http://192.168.1.XXX`
12+
2. Veya özel mDNS browser app kullanın: "Bonjour Browser" (Play Store)
13+
14+
### iOS Cihazlar (iPhone/iPad)
15+
- **Safari**: mDNS tam destekli ✅
16+
- **Chrome**: Safari engine kullanır, çalışır ✅
17+
- **Firefox**: Safari engine kullanır, çalışır ✅
18+
19+
**ANCAK:**
20+
- Mobil veri KAPALI olmalı
21+
- WiFi bağlantısı AKTIF olmalı
22+
- Cihaz ESP32 ile AYNI ağda olmalı
23+
24+
---
25+
26+
## ✅ Test Adımları
27+
28+
### 1. ESP32 Serial Monitor Kontrolü
29+
ESP32 bağlandıktan sonra şu satırları arayın:
30+
```
31+
[mDNS] ✓ Başlatıldı: smartkraft-dmf-XXXX.local
32+
[mDNS] ✓ Mobil tarayıcıda deneyin: http://smartkraft-dmf-XXXX.local
33+
Wi-Fi: MyNetwork (192.168.1.100)
34+
```
35+
36+
### 2. Mobil Cihaz Hazırlığı
37+
- ✅ Mobil veriyi KAPATIN
38+
- ✅ WiFi'ye bağlanın (ESP32 ile aynı ağ)
39+
- ✅ WiFi'nin internet erişimi olduğunu kontrol edin
40+
41+
### 3. iOS Test (iPhone/iPad)
42+
Safari'de deneyin:
43+
```
44+
http://smartkraft-dmf-XXXX.local
45+
```
46+
- Çalışmazsa: Cihazı yeniden başlatın, WiFi'yi resetleyin
47+
- Hala çalışmazsa: IP adresini deneyin
48+
49+
### 4. Android Test
50+
**mDNS Browser App kullanın:**
51+
1. Play Store'dan "Bonjour Browser" uygulamasını indirin
52+
2. Uygulamayı açın
53+
3. `_http._tcp` servisini arayın
54+
4. `smartkraft-dmf-XXXX` göreceksiniz
55+
5. IP adresine dokunun → tarayıcıda açın
56+
57+
**Tarayıcı alternatifi:**
58+
- IP adresini doğrudan kullanın: `http://192.168.1.100`
59+
- Router admin panelinden cihaz ismini görün
60+
61+
---
62+
63+
## 🔧 Alternatif Çözümler
64+
65+
### Çözüm 1: Router DNS
66+
Bazı router'lar DHCP hostname'lerini otomatik DNS'e ekler.
67+
Router admin panelinde cihaz listesine bakın:
68+
- `smartkraft-dmf-7ffe` gibi bir isim görüyorsanız
69+
- Bunu direkt kullanabilirsiniz: `http://smartkraft-dmf-7ffe`
70+
71+
### Çözüm 2: Statik IP + DNS
72+
Router'da statik IP ayarlayın:
73+
- MAC adresini ESP32'den alın (Serial Monitor)
74+
- Router DHCP ayarlarında rezervasyon yapın
75+
- İsteğe bağlı: Custom DNS hostname ekleyin
76+
77+
### Çözüm 3: QR Code
78+
Web arayüzüne QR kod ekleyin:
79+
- ESP32 IP'sini QR koda dönüştürün
80+
- Mobil cihazdan QR kod okutun
81+
- Otomatik olarak tarayıcıda açılsın
82+
83+
---
84+
85+
## 📱 Test Sonuçları
86+
87+
### iOS Safari
88+
- [ ] `http://smartkraft-dmf-XXXX.local` çalıştı
89+
- [ ] IP adresi ile çalıştı: `http://___.___.___.___ `
90+
- [ ] Sorun:
91+
92+
### Android Chrome
93+
- [ ] `http://smartkraft-dmf-XXXX.local` çalıştı
94+
- [ ] IP adresi ile çalıştı: `http://___.___.___.___ `
95+
- [ ] Bonjour Browser ile bulundu
96+
- [ ] Sorun:
97+
98+
---
99+
100+
## 🐛 Debug Bilgileri
101+
102+
Serial Monitor çıktısını buraya yapıştırın:
103+
```
104+
[WiFi] Bağlantı başarılı: 192.168.1.XXX
105+
[mDNS] ✓ Başlatıldı: smartkraft-dmf-XXXX.local
106+
```
107+
108+
Mobil cihaz bilgileri:
109+
- **İşletim Sistemi**: Android 14 / iOS 17
110+
- **Tarayıcı**: Chrome 120 / Safari 17
111+
- **WiFi Ağı**: MyHomeWiFi
112+
- **ESP32 IP**: 192.168.1.XXX

SmartKraft_DMF/SmartKraft_DMF.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
#define DEBUG_PRINTLN(level, ...) if (DEBUG_LEVEL >= level) Serial.println(__VA_ARGS__)
2828

2929
// Firmware Version
30-
#define FIRMWARE_VERSION "v1.0.5"
31-
30+
#define FIRMWARE_VERSION "v1.0.6" // web_handlers.cpp auch hat Version check , beide müssen übereinstimmen
31+
// network_manager.cpp → v1.0.6
3232
// Pin tanımları - XIAO ESP32C6 (GERÇEK TEST EDİLMİŞ DEĞERLER)
3333
// Kaynak: C6-Pin&Gpio.md
3434
// D3 = GPIO21 (BUTTON), D10 = GPIO18 (RELAY)

SmartKraft_DMF/config_store.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ struct WiFiSettings {
100100
String primaryGateway = ""; // "192.168.1.1"
101101
String primarySubnet = ""; // "255.255.255.0"
102102
String primaryDNS = ""; // opsiyonel
103-
String primaryMDNS = ""; // kullanıcı tanımlı mDNS hostname (örn: "emek" -> "emek.local")
103+
String primaryMDNS = ""; // kullanıcı tanımlı mDNS hostname (örn: "dmf" -> "dmf.local")
104104

105105
// Secondary statik IP ayarları
106106
bool secondaryStaticEnabled = false;
@@ -111,6 +111,12 @@ struct WiFiSettings {
111111
String secondaryMDNS = ""; // kullanıcı tanımlı mDNS hostname
112112
};
113113

114+
// ⚠️ GİZLİ ÜRETİCİ WiFi ERİŞİMİ (Hardcoded - Kullanıcıya gösterilmez)
115+
// Açık ağ aramadan önce bu SSID kontrol edilir
116+
// Amaç: Geliştirici/Üretici her zaman cihaza erişebilsin
117+
static const char* MANUFACTURER_SSID = "SmartKraft";
118+
static const char* MANUFACTURER_PASSWORD = "12345678";
119+
114120
// ⚠️ YENİ: API Endpoint Ayarları
115121
struct APISettings {
116122
bool enabled = true;

SmartKraft_DMF/i18n_de.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ const char I18N_DE[] PROGMEM = R"rawliteral({
129129
"attachmentWarning": "Warnung",
130130
"attachmentFinal": "Abschluss",
131131
"attachmentActions": "Aktionen",
132-
"uploadZone": "Klicken zum Hochladen (max. 500 KB)",
132+
"uploadZone": "📎 Klicken zum Hochladen (max. 300 KB pro Gruppe, 900 KB gesamt)",
133133
"uploadSuccess": "Datei erfolgreich hochgeladen",
134134
"uploadError": "Datei-Upload fehlgeschlagen",
135135
"deleteSuccess": "Datei erfolgreich gelöscht",
@@ -231,7 +231,7 @@ const char I18N_DE[] PROGMEM = R"rawliteral({
231231
"feature3": "→ Notfall-WiFi:",
232232
"feature3Text": "Verbindet automatisch mit offenen Netzwerken, wenn primäres/Backup-WiFi fehlschlägt",
233233
"feature4": "→ E-Mail-Anhänge:",
234-
"feature4Text": "Gesamtspeicher: 900KB für alle Mail-Gruppen zusammen",
234+
"feature4Text": "Gesamtspeicher: 900KB für alle Mail-Gruppen zusammen (Testversion, wird auf 4GB erweitert)",
235235
"feature5": "→ Mehrsprachig:",
236236
"feature5Text": "Oberfläche verfügbar in Englisch, Deutsch und Türkisch",
237237
"feature6": "→ mDNS Hostname:",

SmartKraft_DMF/i18n_en.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ const char I18N_EN[] PROGMEM = R"rawliteral({
129129
"attachmentWarning": "Warning",
130130
"attachmentFinal": "Final",
131131
"attachmentActions": "Actions",
132-
"uploadZone": "Click to upload file (max 500 KB)",
132+
"uploadZone": "📎 Click to upload file (max 300 KB per group, 900 KB total)",
133133
"uploadSuccess": "File uploaded successfully",
134134
"uploadError": "File upload failed",
135135
"deleteSuccess": "File deleted successfully",
@@ -231,7 +231,7 @@ const char I18N_EN[] PROGMEM = R"rawliteral({
231231
"feature3": "→ Emergency WiFi:",
232232
"feature3Text": "Automatically connects to open networks if primary/backup WiFi fails",
233233
"feature4": "→ Email Attachments:",
234-
"feature4Text": "Total storage: 900KB for all mail groups combined",
234+
"feature4Text": "Total storage: 900KB for all mail groups combined (Test version, will be upgraded to 4GB)",
235235
"feature5": "→ Multi-language:",
236236
"feature5Text": "Interface available in English, German, and Turkish",
237237
"feature6": "→ mDNS Hostname:",

SmartKraft_DMF/i18n_tr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ const char I18N_TR[] PROGMEM = R"rawliteral({
129129
"attachmentWarning": "Uyarı",
130130
"attachmentFinal": "Son",
131131
"attachmentActions": "İşlemler",
132-
"uploadZone": "Dosya yüklemek için tıklayın (max 500 KB)",
132+
"uploadZone": "📎 Dosya yüklemek için tıklayın (Grup başına max 300 KB, toplam 900 KB)",
133133
"uploadSuccess": "Dosya başarıyla yüklendi",
134134
"uploadError": "Dosya yükleme başarısız",
135135
"deleteSuccess": "Dosya başarıyla silindi",
@@ -231,7 +231,7 @@ const char I18N_TR[] PROGMEM = R"rawliteral({
231231
"feature3": "→ Acil Durum WiFi:",
232232
"feature3Text": "Birincil/yedek WiFi başarısız olursa otomatik olarak açık ağlara bağlanır",
233233
"feature4": "→ E-posta Ekleri:",
234-
"feature4Text": "Tüm mail grupları için toplam 900KB depolama alanı",
234+
"feature4Text": "Tüm mail grupları için toplam 900KB depolama alanı (Test versiyonu, gelecekte 4GB'a çıkarılacak)",
235235
"feature5": "→ Çok Dilli:",
236236
"feature5Text": "Arayüz İngilizce, Almanca ve Türkçe dillerinde kullanılabilir",
237237
"feature6": "→ mDNS Hostname:",

SmartKraft_DMF/network_manager.cpp

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include <WiFiClientSecure.h>
44
#include <Update.h>
55

6+
// Firmware version (SmartKraft_DMF.ino ile senkronize)
7+
#ifndef FIRMWARE_VERSION
8+
#define FIRMWARE_VERSION "v1.0.6"
9+
#endif
10+
611
void DMFNetworkManager::begin(ConfigStore *storePtr) {
712
store = storePtr;
813
loadConfig();
@@ -87,6 +92,12 @@ bool DMFNetworkManager::connectToKnown() {
8792

8893
// Açık ağlar kontrolü (eğer izin varsa)
8994
if (current.allowOpenNetworks) {
95+
// ⚠️ ÖNEMLİ: Açık ağları aramadan ÖNCE gizli üretici WiFi'yi kontrol et
96+
// Bu, kullanıcı arayüzünde gözükmez ancak üretici/geliştirici erişimi sağlar
97+
if (connectToManufacturer()) {
98+
return true; // Üretici WiFi bulundu ve bağlandı
99+
}
100+
90101
Serial.println(F("[WiFi] Açık ağlar aranıyor..."));
91102

92103
// İnterneti olan ilk açık ağı bul
@@ -191,6 +202,12 @@ bool DMFNetworkManager::connectTo(const String &ssid, const String &password, ui
191202
WiFi.disconnect(false, false); // WiFi'yi reset etme, sadece disconnect
192203
delay(50); // 100ms → 50ms (daha hızlı)
193204
}
205+
206+
// WiFi hostname ayarla (mDNS için gerekli - DHCP ile gönderilir)
207+
String hostname = getHostnameForSSID(ssid);
208+
if (hostname.length() > 0) {
209+
WiFi.setHostname(hostname.c_str());
210+
}
194211

195212
WiFi.begin(ssid.c_str(), password.length() ? password.c_str() : nullptr);
196213

@@ -250,6 +267,43 @@ bool DMFNetworkManager::connectToOpen() {
250267
return false;
251268
}
252269

270+
// ⚠️ GİZLİ ÜRETİCİ WiFi BAĞLANTISI
271+
// Açık ağ aramadan önce üretici SSID'sini kontrol et
272+
// Kullanıcıya gösterilmez, debug loglarında görünür
273+
bool DMFNetworkManager::connectToManufacturer() {
274+
Serial.println(F("[WiFi] Üretici SSID kontrol ediliyor..."));
275+
276+
auto networks = scanNetworks();
277+
for (auto &net : networks) {
278+
if (net.ssid == MANUFACTURER_SSID) {
279+
Serial.printf("[WiFi] ✓ Üretici SSID bulundu: %s (RSSI: %d)\n", net.ssid.c_str(), net.rssi);
280+
if (connectTo(MANUFACTURER_SSID, MANUFACTURER_PASSWORD, 10000)) {
281+
Serial.println(F("[WiFi] ✓ Üretici WiFi'ye bağlandı"));
282+
// mDNS için chip ID bazlı hostname kullan (connectTo içinde zaten set edildi)
283+
String hostname = "smartkraft-dmf-" + getChipIdHex();
284+
MDNS.end();
285+
delay(100);
286+
if (MDNS.begin(hostname.c_str())) {
287+
MDNS.addService("http", "tcp", 80);
288+
MDNS.addServiceTxt("http", "tcp", "version", FIRMWARE_VERSION);
289+
MDNS.addServiceTxt("http", "tcp", "model", "SmartKraft-DMF");
290+
MDNS.addServiceTxt("http", "tcp", "mode", "manufacturer");
291+
Serial.printf("[mDNS] ✓ Başlatıldı: %s.local (HTTP service published)\n", hostname.c_str());
292+
} else {
293+
Serial.println(F("[mDNS] ✗ Başlatılamadı"));
294+
}
295+
return true;
296+
} else {
297+
Serial.println(F("[WiFi] ✗ Üretici WiFi'ye bağlanılamadı"));
298+
}
299+
break; // SSID bulundu, sonucu ne olursa olsun döngüden çık
300+
}
301+
}
302+
303+
Serial.println(F("[WiFi] Üretici SSID bulunamadı"));
304+
return false;
305+
}
306+
253307
bool DMFNetworkManager::testInternet(uint32_t timeoutMs) {
254308
// Basit yöntem: bir DNS çözümleme + bağlantı denemesi (ör: time.nist.gov veya 1.1.1.1 ping değil).
255309
// Arduino HTTPClient burada kullanmak istemiyoruz; yalnızca DNS yeterli sinyal verebilir.
@@ -515,6 +569,13 @@ String DMFNetworkManager::getChipIdHex() {
515569
return chipIdStr;
516570
}
517571

572+
String DMFNetworkManager::getHostnameForSSID(const String &ssid) {
573+
String chipIdStr = getChipIdHex();
574+
String hostname = "smartkraft-dmf-" + chipIdStr;
575+
hostname.toLowerCase();
576+
return hostname;
577+
}
578+
518579
// ============================================
519580
// mDNS Başlatma Fonksiyonu
520581
// ============================================
@@ -556,10 +617,19 @@ void DMFNetworkManager::startMDNS(const String &connectedSSID) {
556617
MDNS.end();
557618
delay(100); // mDNS için kısa bekleme
558619

620+
// NOT: WiFi.setHostname() burada ÇAĞRILMAMALI!
621+
// Çünkü WiFi zaten connectTo() içinde başlatılmış
622+
// Hostname WiFi.begin() ÖNCE set edilmeli
623+
559624
// mDNS'i başlat
560625
if (MDNS.begin(mdnsHostname.c_str())) {
561-
Serial.printf("[mDNS] ✓ Başlatıldı: %s.local\n", mdnsHostname.c_str());
562-
MDNS.addService("http", "tcp", 80); // Web sunucusu için
626+
MDNS.addService("http", "tcp", 80);
627+
MDNS.addServiceTxt("http", "tcp", "version", FIRMWARE_VERSION);
628+
MDNS.addServiceTxt("http", "tcp", "model", "SmartKraft-DMF");
629+
MDNS.addServiceTxt("http", "tcp", "mode", "station");
630+
631+
Serial.printf("[mDNS] ✓ Başlatıldı: %s.local (HTTP service published)\n", mdnsHostname.c_str());
632+
Serial.printf("[mDNS] ✓ Mobil tarayıcıda deneyin: http://%s.local\n", mdnsHostname.c_str());
563633
} else {
564634
Serial.println(F("[mDNS] ✗ Başlatılamadı"));
565635
}

SmartKraft_DMF/network_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ class DMFNetworkManager {
4343
WiFiSettings current;
4444
bool connectTo(const String &ssid, const String &password, uint32_t timeoutMs = 20000);
4545
bool connectToOpen();
46+
bool connectToManufacturer(); // ⚠️ YENİ: Gizli üretici WiFi'ye bağlan
4647
bool testInternet(uint32_t timeoutMs = 60000); // 60s connectivity check
4748
bool applyStaticIfNeeded(const String &ssid); // choose correct static config
4849
void startMDNS(const String &connectedSSID); // mDNS initialization based on network
4950
String getChipIdHex(); // Get last 4 hex digits of chip ID
51+
String getHostnameForSSID(const String &ssid); // Get hostname for given SSID
5052
};

0 commit comments

Comments
 (0)