fixed bug when selecting station for alarm
Browse files
reachy_mini_radio/alarm_manager.py
CHANGED
|
@@ -28,6 +28,12 @@ class AlarmManager:
|
|
| 28 |
|
| 29 |
def save_settings(self, new_settings=None):
|
| 30 |
if new_settings:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
self.settings.update(new_settings)
|
| 32 |
|
| 33 |
try:
|
|
|
|
| 28 |
|
| 29 |
def save_settings(self, new_settings=None):
|
| 30 |
if new_settings:
|
| 31 |
+
# Reset trigger flag if we are enabling the alarm or changing the time
|
| 32 |
+
if new_settings.get("enabled") is True:
|
| 33 |
+
self._triggered_today = False
|
| 34 |
+
elif "time" in new_settings and new_settings["time"] != self.settings.get("time"):
|
| 35 |
+
self._triggered_today = False
|
| 36 |
+
|
| 37 |
self.settings.update(new_settings)
|
| 38 |
|
| 39 |
try:
|
reachy_mini_radio/alarm_settings.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
{
|
| 2 |
-
"enabled":
|
| 3 |
"alarm_mode": false,
|
| 4 |
-
"time": "
|
| 5 |
-
"station_url": "https://
|
| 6 |
-
"station_name": "
|
| 7 |
"timezone": "America/Los_Angeles"
|
| 8 |
}
|
|
|
|
| 1 |
{
|
| 2 |
+
"enabled": true,
|
| 3 |
"alarm_mode": false,
|
| 4 |
+
"time": "01:25",
|
| 5 |
+
"station_url": "https://streaming.smartradio.ch:9502/stream",
|
| 6 |
+
"station_name": "A Fine Jazz Gumbo Radio",
|
| 7 |
"timezone": "America/Los_Angeles"
|
| 8 |
}
|
reachy_mini_radio/static/main.js
CHANGED
|
@@ -38,6 +38,7 @@ function renderSelected() {
|
|
| 38 |
if (!selectedStations.length) {
|
| 39 |
selectedBox.textContent = "No stations selected yet.";
|
| 40 |
updateCountBadge();
|
|
|
|
| 41 |
return;
|
| 42 |
}
|
| 43 |
selectedStations.forEach((st, idx) => {
|
|
@@ -71,6 +72,7 @@ function renderSelected() {
|
|
| 71 |
selectedBox.appendChild(item);
|
| 72 |
});
|
| 73 |
updateCountBadge();
|
|
|
|
| 74 |
}
|
| 75 |
|
| 76 |
function renderResults(stations) {
|
|
@@ -211,6 +213,134 @@ clearBtn.onclick = () => {
|
|
| 211 |
saveStatus.className = "status";
|
| 212 |
};
|
| 213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
// Initial load
|
| 215 |
loadSelectedFromServer().then(() => {
|
| 216 |
loadAlarmSettings();
|
|
|
|
| 38 |
if (!selectedStations.length) {
|
| 39 |
selectedBox.textContent = "No stations selected yet.";
|
| 40 |
updateCountBadge();
|
| 41 |
+
if (typeof updateAlarmStationDropdown === "function") updateAlarmStationDropdown();
|
| 42 |
return;
|
| 43 |
}
|
| 44 |
selectedStations.forEach((st, idx) => {
|
|
|
|
| 72 |
selectedBox.appendChild(item);
|
| 73 |
});
|
| 74 |
updateCountBadge();
|
| 75 |
+
if (typeof updateAlarmStationDropdown === "function") updateAlarmStationDropdown();
|
| 76 |
}
|
| 77 |
|
| 78 |
function renderResults(stations) {
|
|
|
|
| 213 |
saveStatus.className = "status";
|
| 214 |
};
|
| 215 |
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
function updateAlarmStationDropdown() {
|
| 219 |
+
// Save current selection
|
| 220 |
+
const currentVal = alarmStation.value;
|
| 221 |
+
|
| 222 |
+
alarmStation.innerHTML = "";
|
| 223 |
+
const defaultOpt = document.createElement("option");
|
| 224 |
+
defaultOpt.value = "";
|
| 225 |
+
defaultOpt.textContent = "-- Select Station --";
|
| 226 |
+
alarmStation.appendChild(defaultOpt);
|
| 227 |
+
|
| 228 |
+
selectedStations.forEach(st => {
|
| 229 |
+
const opt = document.createElement("option");
|
| 230 |
+
opt.value = st.url;
|
| 231 |
+
opt.textContent = st.name || st.url;
|
| 232 |
+
alarmStation.appendChild(opt);
|
| 233 |
+
});
|
| 234 |
+
|
| 235 |
+
// Restore selection if possible
|
| 236 |
+
if (currentVal) {
|
| 237 |
+
alarmStation.value = currentVal;
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
function updateAlarmUI(enabled) {
|
| 244 |
+
if (enabled) {
|
| 245 |
+
setAlarmBtn.style.display = "none";
|
| 246 |
+
cancelAlarmBtn.style.display = "inline-block";
|
| 247 |
+
alarmStatus.textContent = "Alarm is set. Reachy is sleeping.";
|
| 248 |
+
alarmStatus.className = "status ok";
|
| 249 |
+
// Disable inputs
|
| 250 |
+
alarmTime.disabled = true;
|
| 251 |
+
|
| 252 |
+
alarmStation.disabled = true;
|
| 253 |
+
} else {
|
| 254 |
+
setAlarmBtn.style.display = "inline-block";
|
| 255 |
+
cancelAlarmBtn.style.display = "none";
|
| 256 |
+
alarmStatus.textContent = "Alarm not set.";
|
| 257 |
+
alarmStatus.className = "status";
|
| 258 |
+
// Enable inputs
|
| 259 |
+
alarmTime.disabled = false;
|
| 260 |
+
|
| 261 |
+
alarmStation.disabled = false;
|
| 262 |
+
}
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
async function loadAlarmSettings() {
|
| 266 |
+
try {
|
| 267 |
+
const res = await fetch(buildApiUrl("api/alarm"));
|
| 268 |
+
if (!res.ok) return;
|
| 269 |
+
const data = await res.json();
|
| 270 |
+
|
| 271 |
+
if (data.time) alarmTime.value = data.time;
|
| 272 |
+
|
| 273 |
+
if (data.station_url) alarmStation.value = data.station_url;
|
| 274 |
+
|
| 275 |
+
updateAlarmUI(data.enabled);
|
| 276 |
+
|
| 277 |
+
} catch (err) {
|
| 278 |
+
console.error("Failed to load alarm settings", err);
|
| 279 |
+
}
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
async function setAlarm() {
|
| 283 |
+
if (!alarmTime.value || !alarmStation.value) {
|
| 284 |
+
alarmStatus.textContent = "Please select time and station.";
|
| 285 |
+
alarmStatus.className = "status err";
|
| 286 |
+
return;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
alarmStatus.textContent = "Setting alarm...";
|
| 290 |
+
alarmStatus.className = "status";
|
| 291 |
+
|
| 292 |
+
const settings = {
|
| 293 |
+
enabled: true,
|
| 294 |
+
alarm_mode: true, // Always enable sleep mode when setting alarm this way
|
| 295 |
+
time: alarmTime.value,
|
| 296 |
+
|
| 297 |
+
station_url: alarmStation.value,
|
| 298 |
+
station_name: alarmStation.options[alarmStation.selectedIndex]?.textContent || ""
|
| 299 |
+
};
|
| 300 |
+
|
| 301 |
+
try {
|
| 302 |
+
const res = await fetch(buildApiUrl("api/alarm"), {
|
| 303 |
+
method: "POST",
|
| 304 |
+
headers: { "Content-Type": "application/json" },
|
| 305 |
+
body: JSON.stringify(settings)
|
| 306 |
+
});
|
| 307 |
+
if (!res.ok) throw new Error("HTTP " + res.status);
|
| 308 |
+
|
| 309 |
+
updateAlarmUI(true);
|
| 310 |
+
} catch (err) {
|
| 311 |
+
console.error(err);
|
| 312 |
+
alarmStatus.textContent = "Failed to set alarm.";
|
| 313 |
+
alarmStatus.className = "status err";
|
| 314 |
+
}
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
async function cancelAlarm() {
|
| 318 |
+
alarmStatus.textContent = "Cancelling...";
|
| 319 |
+
|
| 320 |
+
const settings = {
|
| 321 |
+
enabled: false,
|
| 322 |
+
alarm_mode: false
|
| 323 |
+
};
|
| 324 |
+
|
| 325 |
+
try {
|
| 326 |
+
const res = await fetch(buildApiUrl("api/alarm"), {
|
| 327 |
+
method: "POST",
|
| 328 |
+
headers: { "Content-Type": "application/json" },
|
| 329 |
+
body: JSON.stringify(settings)
|
| 330 |
+
});
|
| 331 |
+
if (!res.ok) throw new Error("HTTP " + res.status);
|
| 332 |
+
|
| 333 |
+
updateAlarmUI(false);
|
| 334 |
+
} catch (err) {
|
| 335 |
+
console.error(err);
|
| 336 |
+
alarmStatus.textContent = "Failed to cancel alarm.";
|
| 337 |
+
alarmStatus.className = "status err";
|
| 338 |
+
}
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
setAlarmBtn.onclick = setAlarm;
|
| 342 |
+
cancelAlarmBtn.onclick = cancelAlarm;
|
| 343 |
+
|
| 344 |
// Initial load
|
| 345 |
loadSelectedFromServer().then(() => {
|
| 346 |
loadAlarmSettings();
|
reachy_mini_radio/webradios.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
[
|
| 2 |
{
|
| 3 |
-
"name": "
|
| 4 |
-
"url": "https://
|
| 5 |
}
|
| 6 |
]
|
|
|
|
| 1 |
[
|
| 2 |
{
|
| 3 |
+
"name": "A Fine Jazz Gumbo Radio",
|
| 4 |
+
"url": "https://streaming.smartradio.ch:9502/stream"
|
| 5 |
}
|
| 6 |
]
|