Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth configuration tab in web-interface #244

Merged
merged 3 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions html/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"wifi": "WLAN",
"mqtt": "MQTT",
"ftp": "FTP",
"bluetooth": "Bluetooth",
"general": "Allgemein",
"tools": "Tools",
"forum": "Forum"
Expand Down Expand Up @@ -144,8 +145,8 @@
"111":"Wiederhole Titel (endlos)",
"120":"Dimme LEDs (Nachtmodus)",
"130":"Aktiviere/deaktive WLAN",
"140":"Bluetooth Lautsprecher aktivieren/deaktivieren",
"141":"Bluetooth Kopfhörer aktivieren/deaktivieren",
"140":"Bluetooth-Lautsprecher aktivieren/deaktivieren",
"141":"Bluetooth-Kopfhörer aktivieren/deaktivieren",
"150":"Aktiviere FTP",
"0":"Lösche Zuordnung",
"170":"Play/Pause",
Expand Down Expand Up @@ -204,6 +205,27 @@
"button": "FTP-Server starten"
}
},
"bt": {
"sink": {
"title": "ESPuino als Bluetooth-Lautsprecher",
"desc": "ESPuino wird als Bluetooth-Lautsprecher gestartet. Nach dem Wechsel in diesen Modus wird die Web-Schnittstelle nicht mehr zur Verfügung stehen, bis das System im normalen Modus neu gestartet wird.",
"button": "Als Bluetooth-Lautsprecher starten"
},
"source": {
"configtitle": "Bluetooth-Kopfhörer Einstellungen",
"title": "Mit Bluetooth-Kopfhörer verbinden",
"desc": "Das Gerät verbindet sich mit dem angegebenen Bluetooth-Kopfhörer. Nach dem Wechsel in diesen Modus wird die Web-Schnittstelle nicht mehr zur Verfügung stehen, bis das System im normalen Modus neu gestartet wird.",
"button": "Im Kopfhörer-Modus starten"
},
"device": {
"title": "Bluetooth-Gerät (Kopfhörer)",
"placeholder": "z.B. My POGS Wireless Headphone"
},
"pincode": {
"title": "Pairing PIN-Code",
"placeholder": "z.B. 0000"
}
},
"general": {
"volume": {
"title": "Lautstärke",
Expand Down
28 changes: 25 additions & 3 deletions html/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"wifi": "WiFi",
"mqtt": "MQTT",
"ftp": "FTP",
"bluetooth": "Bluetooth",
"general": "General",
"tools": "Tools",
"forum": "Forum"
Expand Down Expand Up @@ -65,7 +66,7 @@
"voldown": "Volume Down",
"volup": "Volume Up",
"current": "Current track",
"command": "Excecute Modification"
"command": "Execute Modification"
},
"files": {
"title": "Files",
Expand All @@ -91,7 +92,7 @@
"desc": "Start Upload",
"selectFolder": "Please select the upload location!",
"selectFile": "Please select files to upload!",
"success": "Upload successfull ({{elapsed}}, {{speed}} KB/s)",
"success": "Upload successful ({{elapsed}}, {{speed}} KB/s)",
"error": "Upload error",
"timeCalc": "Remaining time is being calculated..",
"minutes_one": "minute",
Expand Down Expand Up @@ -144,7 +145,7 @@
"111":"Loop track",
"120":"Dimm LEDs (nightmode)",
"130":"Toggle WiFi",
"140":"Toggle Bluetooth Speeker",
"140":"Toggle Bluetooth Speaker",
"141":"Toggle Bluetooth Headphones",
"150":"Enable FTP",
"0":"Remove assignment",
Expand Down Expand Up @@ -204,6 +205,27 @@
"button": "Start FTP-server"
}
},
"bt": {
"sink": {
"title": "ESPuino as Bluetooth speaker",
"desc": "ESPuino is started as a Bluetooth speaker. After switching to this mode, the web interface will no longer be available until the system is restarted in normal mode.",
"button": "Start as Bluetooth speaker"
},
"source": {
"configtitle": "Bluetooth headphone settings",
"title": "Connect with Bluetooth headphone",
"desc": "The device connects to the specified Bluetooth headset. After switching to this mode, the web interface will no longer be available until the system is restarted in normal mode.",
"button": "Start in headphone mode"
},
"device": {
"title": "Bluetooth device (headphone)",
"placeholder": "e.g. My POGS Wireless Headphone"
},
"pincode": {
"title": "Pairing PIN-Code",
"placeholder": "e.g. 0000"
}
},
"general": {
"volume": {
"title": "Volume",
Expand Down
52 changes: 52 additions & 0 deletions html/management.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
<a class="nav-item nav-link" id="nav-wifi-tab" data-toggle="tab" href="#nav-wifi" role="tab" aria-controls="nav-wifi" aria-selected="false"><i class="fas fa-wifi"></i><span class=".d-sm-none .d-md-block"><span data-i18n="nav.wifi">WiFi</span></a>
%SHOW_MQTT_TAB%
%SHOW_FTP_TAB%
%SHOW_BLUETOOTH_TAB%
<a class="nav-item nav-link" id="nav-general-tab" data-toggle="tab" href="#nav-general" role="tab" aria-controls="nav-general" aria-selected="false"><i class="fas fa-sliders-h"></i><span data-i18n="nav.general">General</span></a>
<a class="nav-item nav-link" id="nav-tools-tab" data-toggle="tab" href="#nav-tools" role="tab" aria-controls="nav-tools" aria-selected="false"><i class="fas fa-wrench"></i><span data-i18n="nav.tools">Tools</span></a>
<a class="nav-item nav-link" id="nav-forum-tab" data-toggle="tab" href="#nav-forum" role="tab" aria-controls="nav-forum" aria-selected="false"><i class="fas fa-comment"></i><span class=".d-sm-none .d-md-block"><span data-i18n="nav.forum">Forum</span></span></a>
Expand Down Expand Up @@ -487,6 +488,45 @@
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-bt" role="tabpanel" aria-labelledby="nav-bt-tab">
<div class="container" id="btConfig">
<form action="#btConfig" method="POST" onsubmit="btSettings('btConfig'); return false">
<div class="form-group col-md-12">
<legend data-i18n="bt.source.configtitle"></legend>
<label for="btDeviceName" data-i18n="[prepend]bt.device.title">:</label>
<input type="text" class="form-control" id="btDeviceName"
data-i18n="[placeholder]bt.device.placeholder" name="btDeviceName" value="%BT_DEVICE_NAME%"><br>
<label for="btPinCode" data-i18n="[prepend]bt.pincode.title">:</label>
<input type="text" class="form-control" id="btPinCode"
data-i18n="[placeholder]bt.pincode.placeholder" name="btPinCode" value="%BT_PINCODE%">
</div>
<br>
<div class="text-center">
<button type="submit" class="btn btn-primary" data-i18n="submit"></button>
</div>
</form><br>
<div class="container" id="btStartSource">
<div class="form-group col-md-12">
<legend data-i18n="bt.source.title"></legend>
<div data-i18n="bt.source.desc"></div>
<br>
<div class="text-center">
<button type="button" class="btn btn-primary" onclick="sendControl(141)" data-i18n="bt.source.button"></button>
</div>
</div>
</div>
</div><br><br>
<div class="container" id="btStartSink">
<div class="form-group col-md-12">
<legend data-i18n="bt.sink.title"></legend>
<div data-i18n="bt.sink.desc"></div>
<br>
<div class="text-center">
<button type="button" class="btn btn-primary" onclick="sendControl(140)" data-i18n="bt.sink.button"></button>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-general" role="tabpanel" aria-labelledby="nav-general-tab">
<div class="container" id="generalConfig">

Expand Down Expand Up @@ -1460,6 +1500,18 @@
socket.send(myJSON);
}

function btSettings(clickedId) {
lastIdclicked = clickedId;
var myObj = {
"bluetooth": {
deviceName: document.getElementById('btDeviceName').value,
pinCode: document.getElementById('btPinCode').value
}
};
var myJSON = JSON.stringify(myObj);
socket.send(myJSON);
}

function removeTrSlash(str) {
if (str.substr(-1) === '/') {
return str.substr(0, str.length - 1);
Expand Down
11 changes: 8 additions & 3 deletions src/Bluetooth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,20 @@ void Bluetooth_Init(void) {
//a2dp_source->set_task_core(1); // task core
//a2dp_source->set_nvs_init(true); // erase/initialize NVS
//a2dp_source->set_ssp_enabled(true); // enable secure simple pairing
//a2dp_source->set_pin_code("0000"); // set pin code if needed, see https://forum.espuino.de/t/neues-feature-bluetooth-kopfhoerer/1293/30

// pairing pin-code, see https://forum.espuino.de/t/neues-feature-bluetooth-kopfhoerer/1293/30
String btPinCode = gPrefsSettings.getString("btPinCode", "");
if (btPinCode != "") {
a2dp_source->set_ssp_enabled(true);
a2dp_source->set_pin_code(btPinCode.c_str());
}
// start bluetooth source
a2dp_source->set_ssid_callback(scan_bluetooth_device_callback);
a2dp_source->start(get_data_channels);
// get device name
btDeviceName = nameBluetoothSourceDevice;
btDeviceName = "";
if (gPrefsSettings.isKey("btDeviceName")) {
btDeviceName = gPrefsSettings.getString("btDeviceName", nameBluetoothSourceDevice);
btDeviceName = gPrefsSettings.getString("btDeviceName", "");
}
Log_Printf(LOGLEVEL_INFO, "Bluetooth source started, connect to device: '%s'", (btDeviceName == "") ? "connect to first device found" : btDeviceName.c_str());
// connect events after startup
Expand Down
19 changes: 18 additions & 1 deletion src/Web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef struct {

const char mqttTab[] = "<a class=\"nav-item nav-link\" id=\"nav-mqtt-tab\" data-toggle=\"tab\" href=\"#nav-mqtt\" role=\"tab\" aria-controls=\"nav-mqtt\" aria-selected=\"false\"><i class=\"fas fa-network-wired\"></i><span data-i18n=\"nav.mqtt\"></span></a>";
const char ftpTab[] = "<a class=\"nav-item nav-link\" id=\"nav-ftp-tab\" data-toggle=\"tab\" href=\"#nav-ftp\" role=\"tab\" aria-controls=\"nav-ftp\" aria-selected=\"false\"><i class=\"fas fa-folder\"></i><span data-i18n=\"nav.ftp\"></span></a>";
const char bluetoothTab[] = "<a class=\"nav-item nav-link\" id=\"nav-bt-tab\" data-toggle=\"tab\" href=\"#nav-bt\" role=\"tab\" aria-controls=\"nav-bt\" aria-selected=\"false\"><i class=\"fab fa-bluetooth\"></i><span data-i18n=\"nav.bluetooth\"></span></a>";

AsyncWebServer wServer(80);
AsyncWebSocket ws("/ws");
Expand Down Expand Up @@ -494,6 +495,12 @@ String templateProcessor(const String &templ) {
#else
return String();
#endif
} else if (templ == "SHOW_BLUETOOTH_TAB") { // Only show Bluetooth-tab if Bluetooth-support was compiled
#ifdef BLUETOOTH_ENABLE
return bluetoothTab;
#else
return String();
#endif
} else if (templ == "INIT_LED_BRIGHTNESS") {
return String(gPrefsSettings.getUChar("iLedBrightness", 0));
} else if (templ == "NIGHT_LED_BRIGHTNESS") {
Expand Down Expand Up @@ -574,10 +581,14 @@ String templateProcessor(const String &templ) {
#ifdef MQTT_ENABLE
return String(gMqttPort);
#endif
} else if (templ == "BT_SOURCE_NAME") {
} else if (templ == "BT_DEVICE_NAME") {
if (gPrefsSettings.isKey("btDeviceName")) {
return gPrefsSettings.getString("btDeviceName", "");
}
} else if (templ == "BT_PIN_CODE") {
if (gPrefsSettings.isKey("btPinCode")) {
return gPrefsSettings.getString("btPinCode", "");
}
} else if (templ == "IPv4") {
return WiFi.localIP().toString();
} else if (templ == "RFID_TAG_ID") {
Expand Down Expand Up @@ -682,6 +693,12 @@ bool processJsonRequest(char *_serialJson) {
(!String(_mqttServer).equals(gPrefsSettings.getString("mqttServer", "-1")))) {
return false;
}
} else if (doc.containsKey("bluetooth")) {
// bluetooth settings
const char *_btDeviceName = doc["bluetooth"]["deviceName"];
gPrefsSettings.putString("btDeviceName", (String)_btDeviceName);
const char *btPinCode = doc["bluetooth"]["pinCode"];
gPrefsSettings.putString("btPinCode", (String)btPinCode);
} else if (doc.containsKey("rfidMod")) {
const char *_rfidIdModId = object["rfidMod"]["rfidIdMod"];
uint8_t _modId = object["rfidMod"]["modId"];
Expand Down
1 change: 0 additions & 1 deletion src/settings-override.h.sample
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@

// Bluetooth
constexpr const char nameBluetoothSinkDevice[] = "ESPuino"; // Name of your ESPuino as Bluetooth-device
constexpr const char nameBluetoothSourceDevice[] = "My POGS Wireless Headphone"; // Name of Bluetooth-device to connect to (BT-Headset name) (https://forum.espuino.de/t/neues-feature-bluetooth-kopfhoerer/1293/)

// Where to store the backup-file for NVS-records
constexpr const char backupFile[] = "/backup.txt"; // File is written every time a (new) RFID-assignment via GUI is done
Expand Down
1 change: 0 additions & 1 deletion src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@

// Bluetooth
constexpr const char nameBluetoothSinkDevice[] = "ESPuino"; // Name of your ESPuino as Bluetooth-device
constexpr const char nameBluetoothSourceDevice[] = "My POGS Wireless Headphone"; // Name of Bluetooth-device to connect to (BT-Headset name) (https://forum.espuino.de/t/neues-feature-bluetooth-kopfhoerer/1293/)

// Where to store the backup-file for NVS-records
constexpr const char backupFile[] = "/backup.txt"; // File is written every time a (new) RFID-assignment via GUI is done
Expand Down