Skip to content

Commit 016fbfb

Browse files
committed
Home Assistant integration via MQTT – automatic device discovery with station, equalizer, volume, play/stop, recording and LCD entities.
- MQTT broker auto-discovery via mDNS; manual broker address configurable from the web interface. - Free RAM info in the web interface – DMA, Internal and SPIRAM with manual refresh button.
1 parent 21f249d commit 016fbfb

14 files changed

+1270
-31
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
## [1.1.1] - 2026-03-05
10+
## [1.2.0] - 2026-03-05
11+
12+
### Added
13+
- **Home Assistant integration via MQTT** – automatic device discovery with station, equalizer, volume, play/stop, recording and LCD entities.
14+
- MQTT broker auto-discovery via mDNS; manual broker address configurable from the web interface.
15+
- Free RAM info in the web interface – DMA, Internal and SPIRAM with manual refresh button.
16+
17+
## [1.1.1] - 2026-03-04
1118

1219
### Fixed
1320
- Problem with storing volume levels greater than 63% solved.

README.md

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44

55
## 🌟 Main Features
66

7-
### 🌐 **Local Web Server - NEW!**
7+
### 🏠 **Home Assistant Integration via MQTT - NEW!**
8+
9+
- **Automatic MQTT discovery** – entities appear in Home Assistant without manual YAML configuration
10+
- **Full control** – station, equalizer, volume, play/stop, recording, LCD on/off
11+
- **Real-time state sync** – all changes (from buttons, web, or HA) are instantly reflected everywhere
12+
- **Easy setup** – broker found automatically via mDNS or set manually in the web interface
13+
14+
### 🌐 **Local Web Server**
815

916
- **Remote control** via a web browser: volume, station selection, equalizer adjustment
1017
- **Dedicated LCD on/off button** in the web interface for manual display control (visible only if display is present)
@@ -14,16 +21,6 @@
1421
- **Local access** without the need for an Internet connection
1522
- **Automatic SD card save** of the current station list
1623

17-
### Other Updates
18-
19-
- Reorder radio stations via the web interface
20-
- Automatically save the current station list from device flash memory (NVS) to the SD card
21-
- Download the current station list in `.csv` format via the browser
22-
- Equalizer selection via the web interface
23-
- Increased maximum number of stations to 50
24-
- Increased maximum number of equalizers to 20
25-
- More built-in equalizers (10 total)
26-
2724
### 📻 Audio Playback
2825

2926
- Supports many audio formats: **MP3, AAC, OGG, WAV, FLAC, OPUS, M4A, AMR**
@@ -63,6 +60,7 @@
6360
### 🔗 Connectivity
6461

6562
- **WiFi** with automatic provisioning via ESP SoftAP Prov app
63+
- **MQTT** for Home Assistant integration (auto-discovery via mDNS or manual broker address)
6664
- **mDNS/Bonjour, NetBIOS** for easy network discovery
6765
- **SNTP** for time synchronization
6866
- Configuration support via ESP SoftAP app
@@ -206,7 +204,39 @@ Always 10 EQ values in dB.
206204
- 📋 **Station selection** with full list
207205
- 📋 **Edit station list** without physical access
208206

209-
## 🎠 Button Controls (OLED-less Mode)
207+
## � Home Assistant Integration
208+
209+
RadioJKK supports automatic integration with **Home Assistant** via MQTT discovery. All entities are created automatically — no manual YAML configuration needed.
210+
211+
![RadioJKK in Home Assistant](img/RadioJKK_HA.png)
212+
213+
### Discovered Entities
214+
215+
| Entity | Type | Description |
216+
|--------|------|-------------|
217+
| Station | Select | Choose from the configured station list |
218+
| Equalizer | Select | Choose equalizer preset |
219+
| Volume | Number | Volume level 0–100% |
220+
| Playback | Switch | Play / Stop with state indicator |
221+
| Recording | Switch | Start / Stop recording to SD card |
222+
| LCD | Switch | Display on / off |
223+
224+
### MQTT Broker Configuration
225+
226+
RadioJKK discovers the MQTT broker automatically via **mDNS** (service `_mqtt._tcp`). If your broker advertises this service (e.g. Mosquitto with Avahi), no manual configuration is needed.
227+
228+
To set the broker address manually:
229+
230+
1. Open the web interface: `http://radiojkk32.local`
231+
2. Enter the MQTT broker address (e.g. `mqtt://192.168.1.100:1883`)
232+
3. Save — the device will connect to the specified broker
233+
234+
### Requirements
235+
236+
- **MQTT broker** (e.g. Mosquitto) accessible on the local network
237+
- **Home Assistant** with [MQTT integration](https://www.home-assistant.io/integrations/mqtt/) enabled and connected to the same broker
238+
239+
## �🎠 Button Controls (OLED-less Mode)
210240

211241
| Button | Short Press | Long Press |
212242
| ------------- | -------------------- | ------------------ |

README_PL.md

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44

55
## 🌟 Główne funkcje
66

7-
### 🌐 **Lokalny serwer WWW - NOWOŚĆ!**
7+
### 🏠 **Integracja z Home Assistant przez MQTT - NOWOŚĆ!**
8+
9+
- **Automatyczne wykrywanie MQTT** – encje pojawiają się w Home Assistant bez ręcznej konfiguracji YAML
10+
- **Pełna kontrola** – stacja, equalizer, głośność, odtwarzanie/stop, nagrywanie, LCD on/off
11+
- **Synchronizacja stanu w czasie rzeczywistym** – zmiany z przycisków, WWW lub HA są natychmiast widoczne wszędzie
12+
- **Łatwa konfiguracja** – broker odnajdywany automatycznie przez mDNS lub ustawiany ręcznie w interfejsie WWW
13+
14+
### 🌐 **Lokalny serwer WWW**
815

916
- **Zdalne sterowanie** przez przeglądarkę internetową: głośność, wybór stacji, zmiana equalizera
1017
- **Dedykowany przycisk LCD on/off** w interfejsie WWW do ręcznego włączania/wyłączania wyświetlacza (widoczny tylko gdy wyświetlacz jest obecny)
@@ -14,16 +21,6 @@
1421
- **Dostęp lokalny** bez potrzeby połączenia z Internetem
1522
- **Automatyczny zapis na karcie SD** aktualnej listy stacji
1623

17-
### Inne nowości
18-
19-
- Zmiana kolejności stacji radiowych przez WWW
20-
- Automatyczny zapis aktualnej listy stacji z pamięci flash urządzenia (NVS) na kartę SD
21-
- Możliwość pobrania aktualnej listy stacji w formacie .csv przez przeglądarkę
22-
- Wybór equalizera w przeglądarce
23-
- Zwiększona maksymalna liczba stacji do 50
24-
- Maksymalna liczba equalizerów zwiększona do 20
25-
- Więcej wbudowanych equalizerów (10)
26-
2724
### 📻 Odtwarzanie audio
2825

2926
- Obsługa wielu formatów audio: **MP3, AAC, OGG, WAV, FLAC, OPUS, M4A, AMR**
@@ -63,6 +60,7 @@
6360
### 🔗 Łączność
6461

6562
- **WiFi** z automatycznym provisioningiem przez aplikację ESP SoftAP Prov
63+
- **MQTT** do integracji z Home Assistant (auto-discovery przez mDNS lub ręczny adres brokera)
6664
- **mDNS/Bonjour, NetBIOS** dla łatwego odnajdywania w sieci
6765
- **SNTP** dla synchronizacji czasu
6866
- Obsługa konfiguracji przez aplikację ESP SoftAP
@@ -210,7 +208,39 @@ Zawsze 10 ustawień korekcji w dB.
210208
- 📋 **Zmiana stacji** z pełną listą dostępnych opcji
211209
- 📋 **Edycja listy stacji** bez potrzeby fizycznego dostępu
212210

213-
## 🎠 Obsługa przycisków (tryb bez OLED)
211+
## � Integracja z Home Assistant
212+
213+
RadioJKK wspiera automatyczną integrację z **Home Assistant** przez MQTT discovery. Wszystkie encje tworzone są automatycznie — bez konieczności ręcznej konfiguracji YAML.
214+
215+
![RadioJKK w Home Assistant](img/RadioJKK_HA.png)
216+
217+
### Wykrywane encje
218+
219+
| Encja | Typ | Opis |
220+
|-------|-----|------|
221+
| Stacja | Select | Wybór z listy skonfigurowanych stacji |
222+
| Equalizer | Select | Wybór presetu equalizera |
223+
| Głośność | Number | Poziom głośności 0–100% |
224+
| Odtwarzanie | Switch | Play / Stop ze wskaźnikiem stanu |
225+
| Nagrywanie | Switch | Start / Stop nagrywania na kartę SD |
226+
| LCD | Switch | Włączanie / wyłączanie wyświetlacza |
227+
228+
### Konfiguracja brokera MQTT
229+
230+
RadioJKK automatycznie odnajduje broker MQTT przez **mDNS** (usługa `_mqtt._tcp`). Jeśli Twój broker ogłasza tę usługę (np. Mosquitto z Avahi), żadna ręczna konfiguracja nie jest potrzebna.
231+
232+
Aby ustawić adres brokera ręcznie:
233+
234+
1. Otwórz interfejs WWW: `http://radiojkk32.local`
235+
2. Wpisz adres brokera MQTT (np. `mqtt://192.168.1.100:1883`)
236+
3. Zapisz — urządzenie połączy się ze wskazanym brokerem
237+
238+
### Wymagania
239+
240+
- **Broker MQTT** (np. Mosquitto) dostępny w sieci lokalnej
241+
- **Home Assistant** z włączoną [integracją MQTT](https://www.home-assistant.io/integrations/mqtt/) podłączoną do tego samego brokera
242+
243+
## �🎠 Obsługa przycisków (tryb bez OLED)
214244

215245
| Przycisk | Krótkie naciśnięcie | Długie naciśnięcie |
216246
| ------------- | ------------------- | ------------------ |

img/RadioJKK_HA.png

64.9 KB
Loading
2.2 MB
Binary file not shown.
2.2 MB
Binary file not shown.

radioJKK32/index.html

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,5 +1064,87 @@ <h2>Wi‑Fi setup</h2>
10641064
</div>
10651065
<p id="wifi-msg" style="text-align: center; font-weight: bold; color: #333; margin: 0;"></p>
10661066
</div>
1067+
1068+
<!-- MQTT broker setup -->
1069+
<div class="form-container wifi-panel" style="margin: 1.5rem auto; max-width: 600px;">
1070+
<h2>MQTT Broker</h2>
1071+
<div class="form-group" style="display:flex; align-items:center; gap:0.5em;">
1072+
<input id="mqtt-enabled" type="checkbox" checked style="width:auto; margin:0;">
1073+
<label for="mqtt-enabled" style="margin:0; cursor:pointer;">MQTT enabled</label>
1074+
</div>
1075+
<div class="form-group">
1076+
<label for="mqtt-broker">Broker address (host or host:port)</label>
1077+
<input id="mqtt-broker" type="text" maxlength="79" placeholder="empty = mDNS auto-discovery">
1078+
</div>
1079+
<div class="form-buttons">
1080+
<button onclick="saveMqtt()">💾 Save</button>
1081+
<button onclick="loadMqtt()" style="background:#555;">🔄 Refresh</button>
1082+
</div>
1083+
<p id="mqtt-msg" style="text-align: center; font-weight: bold; color: #333; margin: 0;"></p>
1084+
</div>
1085+
1086+
<script>
1087+
function saveMqtt() {
1088+
const broker = document.getElementById('mqtt-broker').value.trim();
1089+
const enabled = document.getElementById('mqtt-enabled').checked ? 1 : 0;
1090+
const msg = document.getElementById('mqtt-msg');
1091+
msg.textContent = 'Saving...';
1092+
msg.style.color = '#333';
1093+
const body = `broker=${encodeURIComponent(broker)}&enabled=${enabled}`;
1094+
fetch('/mqtt_save', {
1095+
method: 'POST',
1096+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
1097+
body
1098+
}).then(r => r.text())
1099+
.then(t => { msg.textContent = t + (enabled ? '' : ' (MQTT disabled)'); msg.style.color = '#070'; })
1100+
.catch(() => { msg.textContent = 'Error saving MQTT'; msg.style.color = '#c00'; });
1101+
}
1102+
1103+
function loadMqtt() {
1104+
fetch('/mqtt_status')
1105+
.then(r => r.text())
1106+
.then(t => {
1107+
// Format: broker_addr;connected;enabled
1108+
const parts = t.split(';');
1109+
document.getElementById('mqtt-broker').value = parts[0] || '';
1110+
const connected = parts[1] === '1';
1111+
const enabled = parts[2] !== '0';
1112+
document.getElementById('mqtt-enabled').checked = enabled;
1113+
const msg = document.getElementById('mqtt-msg');
1114+
if (!enabled) {
1115+
msg.textContent = 'MQTT disabled';
1116+
msg.style.color = '#888';
1117+
} else if (connected) {
1118+
msg.textContent = '✅ Connected';
1119+
msg.style.color = '#070';
1120+
} else if (parts[0]) {
1121+
msg.textContent = 'Configured (not connected)';
1122+
msg.style.color = '#a80';
1123+
} else {
1124+
msg.textContent = 'mDNS auto-discovery active';
1125+
msg.style.color = '#555';
1126+
}
1127+
})
1128+
.catch(() => {});
1129+
}
1130+
loadMqtt();
1131+
</script>
1132+
1133+
<!-- RAM info -->
1134+
<div style="text-align:center; color:#888; font-size:0.85em; margin:1.5rem 0 0.5rem;">
1135+
<span id="ram-info">Loading RAM info...</span>
1136+
<button onclick="loadRam()" style="background:none; border:none; cursor:pointer; font-size:1em; vertical-align:middle; padding:0 0 0 0.3em;" title="Refresh">🔄</button>
1137+
</div>
1138+
<script>
1139+
function loadRam(){
1140+
document.getElementById('ram-info').textContent='Loading...';
1141+
fetch('/raminfo').then(r=>r.text()).then(t=>{
1142+
const [dma,int_,spi]=t.split(';');
1143+
document.getElementById('ram-info').textContent=
1144+
'Free RAM \u2014 DMA: '+dma+' KB \u00b7 Internal: '+int_+' KB \u00b7 SPIRAM: '+spi+' KB';
1145+
}).catch(()=>{ document.getElementById('ram-info').textContent='Error'; });
1146+
}
1147+
loadRam();
1148+
</script>
10671149
</body>
10681150
</html>

radioJKK32/main/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(srcs "radio_jkk.c"
66
"jkk_nvs.c"
77
"jkk_settings.c"
88
"web_server.c"
9+
"jkk_mqtt.c"
910
)
1011

1112
if(CONFIG_JKK_RADIO_USING_I2C_LCD)

0 commit comments

Comments
 (0)