🏠 Home Assistant integrace
🎯 Kompletní REST API
EaSun Multi-Senzor poskytuje kompletní JSON REST API pro snadnou integraci s Home Assistant a dalšími domácími automatizačními systémy.
📊 Dostupné API endpointy
🔗 /api/data
- Senzorová data: lux, temperature, dht22_temperature, dht22_humidity, category
- Identifikace: device_id, device_location, device_mac
- DS18B20 cache/outage: ds18b20_outage, ds18b20_last_valid_age_ms
- Status: uptime, memory_free, espnow_status, sensor_status
🔗 /api/error-log
- Event logy: Všechny systémové události
- Chyby: Detailní error reporting
- Diagnostika: Memory, WiFi, senzory
- Časové značky: NTP čas nebo uptime
🔧 JSON struktura /api/data
{
"device_id": 1,
"device_location": "Obývák",
"device_name": "Obývák",
"device_mac": "24:6F:28:12:34:56",
"lux": 77.50,
"temperature": 22.15,
"temperatures": [22.10, 22.20],
"temp_count": 2,
"dht22_temperature": 22.3,
"dht22_humidity": 45.2,
"category": "Šero",
"timestamp": 12345678,
"uptime": 3600,
"bh1750_available": true,
"ds18b20_available": true,
"ds18b20_outage": false,
"ds18b20_last_valid_age_ms": 0,
"api_mutex_timeout": false,
"dht22_available": true,
"sensor_status": "BH1750 luxmetr + DS18B20 teplota + DHT22 teplota/vlhkost",
"memory_free": 163932,
"espnow_enabled": true,
"espnow_total_sent": 150,
"espnow_total_failed": 2
}
🏠 Home Assistant konfigurace
Přidejte do souboru configuration.yaml:
# REST senzory pro EaSun Multi-Senzor
rest:
- resource: "http://IP_ADRESA_ESP32/api/data"
authentication: basic
username: "admin" # nebo vaše uživatelské jméno
password: "VASE_HESLO"
scan_interval: 30 # aktualizace každých 30 sekund
sensor:
# Identifikace zařízení
- name: "EaSun Device ID"
value_template: "{{ value_json.device_id }}"
icon: "mdi:identifier"
- name: "EaSun Místo"
value_template: "{{ value_json.device_location }}"
icon: "mdi:map-marker"
# Senzorová data s automatickým pojmenováním
- name: "{{ value_json.device_location }} Osvětlení"
unit_of_measurement: "lx"
device_class: "illuminance"
state_class: "measurement"
value_template: "{{ value_json.lux | round(2) }}"
icon: "mdi:brightness-6"
unique_id: "easun_{{ value_json.device_mac | replace(':', '_') }}_lux"
- name: "{{ value_json.device_location }} Teplota"
unit_of_measurement: "°C"
device_class: "temperature"
state_class: "measurement"
value_template: "{{ value_json.temperature | round(2) }}"
icon: "mdi:thermometer"
unique_id: "easun_{{ value_json.device_mac | replace(':', '_') }}_temp"
- name: "{{ value_json.device_location }} Kategorie"
value_template: "{{ value_json.category }}"
icon: "mdi:lightbulb-outline"
- name: "{{ value_json.device_location }} Uptime"
unit_of_measurement: "s"
value_template: "{{ value_json.uptime }}"
icon: "mdi:clock-outline"
binary_sensor:
- name: "{{ value_json.device_location }} BH1750"
value_template: "{{ value_json.bh1750_available }}"
device_class: "connectivity"
- name: "{{ value_json.device_location }} DS18B20"
value_template: "{{ value_json.ds18b20_available }}"
device_class: "connectivity"
- name: "{{ value_json.device_location }} DS18B20 výpadek"
value_template: "{{ value_json.ds18b20_outage }}"
device_class: "problem"
📱 Lovelace Dashboard
# Entity karta
type: entities
title: "EaSun Multi-Senzor"
entities:
- entity: sensor.obyvak_osvetleni
name: "Osvětlení"
- entity: sensor.obyvak_teplota
name: "Teplota"
- entity: sensor.obyvak_kategorie
name: "Kategorie světla"
- entity: binary_sensor.obyvak_bh1750
name: "BH1750 senzor"
- entity: binary_sensor.obyvak_ds18b20
name: "DS18B20 senzor"
---
# Graf historie
type: history-graph
entities:
- entity: sensor.obyvak_osvetleni
- entity: sensor.obyvak_teplota
hours_to_show: 24
refresh_interval: 0
🔄 Automatizace příklady
# Automatické rozsvícení při tmě
automation:
- alias: "EaSun světlo detekce"
trigger:
- platform: state
entity_id: sensor.obyvak_kategorie
to: "Tma"
action:
- service: light.turn_on
target:
entity_id: light.obyvak_hlavni
---
# Notifikace při výpadku senzoru
automation:
- alias: "EaSun senzor offline"
trigger:
- platform: state
entity_id: binary_sensor.obyvak_bh1750
to: "off"
for:
minutes: 5
action:
- service: notify.mobile_app
data:
message: "BH1750 senzor v obýváku je offline!"
🏷️ Více zařízení současně
✅ Automatická identifikace
Každé EaSun zařízení má jedinečnou identifikaci:
- device_id: Číselné ID (1-255) nastavené přes web
- device_location: Název místa ("Obývák", "Ložnice", "Garáž")
- device_mac: MAC adresa ESP32 (absolutně jedinečná)
Home Assistant automaticky vytvoří entity jako sensor.obyvak_osvetleni, sensor.loznice_teplota atd.
⚙️ Nastavení krok za krokem
- Najděte IP adresu ESP32 v sériovém monitoru nebo na routeru
- Nahraďte IP_ADRESA_ESP32 skutečnou IP adresou
- Nastavte správné heslo pro HTTP autentizaci
- Přidejte konfiguraci do
configuration.yaml
- Restartujte Home Assistant
- Přidejte entity do dashboard
- Vytvořte automatizace podle potřeby
⚠️ Důležité poznámky
- HTTP autentizace: API vyžaduje stejné přihlášení jako webové rozhraní
- Scan interval: Doporučujeme 30-60 sekund pro úsporu síťového provozu
- Unique ID: Používá MAC adresu pro jedinečnost napříč restarty
- Device class: Správné třídy pro automatické ikony a jednotky
📡 ESP-NOW komunikace s jinými ESP32
🎯 Co je ESP-NOW?
ESP-NOW je proprietární bezdrátový komunikační protokol od Espressif, který umožňuje přímou komunikaci mezi ESP32 zařízeními bez potřeby WiFi routeru.
⚡ Výhody ESP-NOW
- Dosah až 200m (bez překážek)
- Nízká latence (< 10ms)
- Minimální spotřeba energie
- Bez potřeby routeru
🔐 AES-128 šifrování
- Silné šifrování všech dat
- Automatická správa klíčů
- Webová správa PMK klíčů
- Kompatibilní se všemi ESP32
🔧 Nastavení ESP-NOW
-
Získání MAC adresy příjemce:
Na druhém ESP32 spusťte kód s WiFi.macAddress()
-
Konfigurace odesílatele:
Jděte na stránku "📡 ESP-NOW konfigurace"
-
Zadání MAC adresy:
Zadejte MAC adresu ve formátu AA:BB:CC:DD:EE:FF
-
Nastavení šifrování:
Na stránce "🔐 Šifrování" zapněte/vypněte AES-128
-
Kopírování kódu:
Zkopírujte vygenerovaný kód pro příjemce
🏷️ Identifikace zařízení (Device ID & Location)
Nové v2.4.1: Každé ESP32 zařízení nyní může mít jedinečné ID a název místa pro snadné rozpoznání na příjemci.
🆔 Webová konfigurace
- Otevřete webové rozhraní ESP32
- Klikněte na "📡 ESP-NOW"
- V sekci "Identifikace zařízení":
- Zadejte Device ID (1-255)
- Zadejte Název místa (max 19 znaků)
- Klikněte "💾 Uložit identifikaci"
📋 Příklady nastavení
- ID: 1, Místo: Obyvak - obývací pokoj
- ID: 2, Místo: Loznice - ložnice
- ID: 11, Místo: Garaz - garáž
- ID: 15, Místo: Sklep - sklep
Nastavení se ukládá do SPIFFS a načítá automaticky při restartu.
🔄 Schéma ESP-NOW komunikace
📡 ESP32 #1
ID: 1
Místo: Obyvak
MAC: 24:6F:28:...
🌡️ BH1750 (luxmetr)
🌡️ DS18B20 (teplota)
🖥️ ESP32 Příjemce
Webové rozhraní:
Obývák: 22.5°C, 250 lux
Garáž: 18.2°C, 45 lux
📡 ESP32 #11
ID: 11
Místo: Garaz
MAC: 24:6F:28:...
🌡️ BH1750 (luxmetr)
🌡️ DS18B20 (teplota)
✨ Klíčové výhody:
📏 Dosah: až 200m
⚡ Latence: < 10ms
🔋 Spotřeba: nízká
🔐 Šifrování: AES-128
🆔 Identifikace: automatická
🌐 Bez routeru: přímá komunikace
📊 Aktualizovaná struktura dat
typedef struct {
uint8_t device_id; // 🆔 ID zařízení (1-255) - pro rozpoznání odesílatele
char location[20]; // 🏠 Název místa (max 19 znaků) - např. "Garaz", "Obyvak"
float lux; // Hodnota osvětlení v luxech (0.0 - 100000.0)
float temperature; // Teplota v °C (-55.0 - 125.0, nebo -999.0 = neplatná)
char category[30]; // Textový popis osvětlení (např. "Pokojové osvětlení")
uint32_t timestamp; // Časová značka v milisekundách od startu ESP32
uint8_t battery_level; // Úroveň baterie v % (0-100, aktuálně vždy 100)
bool bh1750_available; // true = BH1750 luxmetr je připojen a funkční
bool ds18b20_available; // true = DS18B20 teplota je připojena a funkční
} sensor_data_t;
🔄 Jak funguje odesílání dat
⏱️ Časování odesílání
- Frekvence: Každou 1 sekundu
- Podmínka: Pouze pokud je alespoň jeden senzor připojen
- Dual-core: Běží na Core 1 (nezávisle na webovém rozhraní)
- Priorita: Vysoká - minimální latence
📡 Odesílaná data
- lux: Aktuální hodnota luxů (při výpadku poslední validní hodnota)
- temperature: Aktuální teplota (při výpadku poslední validní hodnota)
- category: "Pokojové osvětlení", "Tmavé" atd.
- timestamp: Čas od startu ESP32
- battery_level: Vždy 100% (napájení z USB)
- *_available: Které senzory jsou funkční
📋 Příklady odesílaných dat
🔹 Oba senzory připojeny:
{
lux: 245.83,
temperature: 23.45,
category: "Pokojové osvětlení",
timestamp: 12345678,
battery_level: 100,
bh1750_available: true,
ds18b20_available: true
}
🔹 Pouze BH1750 luxmetr:
{
lux: 1250.67,
temperature: 23.45, // Poslední validní hodnota DS18B20 (cache)
category: "Jasné osvětlení",
timestamp: 12345678,
battery_level: 100,
bh1750_available: true,
ds18b20_available: false // DS18B20 dočasně nedostupný
}
🔹 Pouze DS18B20 teplota:
{
lux: 45.20, // Poslední validní hodnota BH1750 (cache)
temperature: 25.12,
category: "Nízké osvětlení",
timestamp: 12345678,
battery_level: 100,
bh1750_available: false, // BH1750 dočasně nedostupný
ds18b20_available: true
}
📡 Příklad kódu pro příjemce
#include <esp_now.h>
#include <WiFi.h>
// PMK klíč (zkopírujte z webového rozhraní)
uint8_t pmk_key[16] = {0x2B,0x7E,0x15,0x16,0x28,0xAE,0xD2,0xA6,
0xAB,0xF7,0x15,0x88,0x09,0xCF,0x4F,0x3C};
// Struktura dat (stejná jako na odesílateli)
typedef struct {
float lux;
float temperature;
char category[30];
uint32_t timestamp;
uint8_t battery_level;
bool bh1750_available;
bool ds18b20_available;
} sensor_data_t;
// Callback pro příjem dat s rozpoznáním zařízení
void onDataReceived(const esp_now_recv_info_t *recv_info,
const uint8_t *data, int data_len) {
sensor_data_t receivedData;
memcpy(&receivedData, data, sizeof(receivedData));
// 🔍 Rozpoznání zařízení podle MAC adresy
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
recv_info->src_addr[0], recv_info->src_addr[1], recv_info->src_addr[2],
recv_info->src_addr[3], recv_info->src_addr[4], recv_info->src_addr[5]);
// 🏠 Rozpoznání podle Device ID a názvu místa
Serial.printf("📡 Data z: MAC=%s, ID=%d, Místo=%s\n",
macStr, receivedData.device_id, receivedData.location);
// 📊 Zpracování dat podle konkrétního zařízení
switch(receivedData.device_id) {
case 11:
Serial.printf("🏠 GARÁŽ: ");
break;
case 1:
Serial.printf("🏠 OBÝVÁK: ");
break;
case 2:
Serial.printf("🏠 LOŽNICE: ");
break;
default:
Serial.printf("🏠 %s (ID=%d): ", receivedData.location, receivedData.device_id);
break;
}
// Zobrazení naměřených dat
if (receivedData.bh1750_available) {
Serial.printf("💡 %.2f lx (%s)", receivedData.lux, receivedData.category);
}
if (receivedData.bh1750_available && receivedData.ds18b20_available) {
Serial.print(", ");
}
if (receivedData.ds18b20_available) {
Serial.printf("🌡️ %.2f °C", receivedData.temperature);
}
Serial.printf(" | ⏰ %lu ms\n", receivedData.timestamp);
// Zpracování dat podle potřeby
processReceivedData(receivedData);
}
🎯 Praktický příklad kompletního nastavení
📋 Scénář: Monitoring domu
- ESP32 #1: ID=1, Místo="Obyvak"
- ESP32 #2: ID=2, Místo="Loznice"
- ESP32 #11: ID=11, Místo="Garaz"
- ESP32 #15: ID=15, Místo="Sklep"
⚙️ Postup nastavení
- Nahrajte kód na všechna ESP32
- Připojte k WiFi
- Na každém nastavte Device ID a Místo
- Na příjemci získejte MAC adresu
- Na všech odesílatelích nastavte MAC příjemce
- Aktivujte šifrování na všech zařízeních
📺 Výsledek na sériovém monitoru příjemce
📡 Data z: MAC=24:6F:28:AB:CD:EF, ID=1, Místo=Obyvak
🏠 OBÝVÁK: 💡 250.50 lx (Pokojové osvětlení), 🌡️ 22.30 °C | ⏰ 123456 ms
📡 Data z: MAC=24:6F:28:12:34:56, ID=11, Místo=Garaz
🏠 GARÁŽ: 💡 45.20 lx (Nízké osvětlení), 🌡️ 18.50 °C | ⏰ 789012 ms
📡 Data z: MAC=24:6F:28:78:9A:BC, ID=2, Místo=Loznice
🏠 LOŽNICE: 💡 10.80 lx (Tma), 🌡️ 20.10 °C | ⏰ 345678 ms
// Funkce pro zpracování přijatých dat
void processReceivedData(sensor_data_t data) {
// Příklad zpracování dat
if (data.bh1750_available) {
// Uložení dat o osvětlení
float luxValue = data.lux;
String luxCategory = String(data.category);
// Zde můžete přidat vlastní logiku
if (luxValue < 50) {
Serial.println("⚠️ Nízké osvětlení - zapnout světla?");
}
}
if (data.ds18b20_available) {
// Uložení teplotních dat
float tempValue = data.temperature;
// Zde můžete přidat vlastní logiku
if (tempValue > 30) {
Serial.println("🔥 Vysoká teplota - zapnout ventilaci?");
} else if (tempValue < 15) {
Serial.println("❄️ Nízká teplota - zapnout topení?");
}
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Inicializace ESP-NOW
esp_now_init();
// Nastavení PMK klíče pro šifrování
esp_now_set_pmk(pmk_key);
// Registrace callback
esp_now_register_recv_cb(onDataReceived);
// Přidání odesílatele s šifrováním
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, odesílatel_MAC, 6);
peerInfo.channel = 0;
peerInfo.encrypt = true; // Zapnout šifrování
esp_now_add_peer(&peerInfo);
}