I’ve decided to go with the Ulanzi TC001. The Echo Show 5 has a more “boring” look, and it also looks like (what it more or less is, namely) a smartphone with a speaker. And I want to ban the smartphone from the bedroom.
Unfortunately, the Ulanzi TC001 won’t be delivered before Thursday. That’s unfortunate, since I’ve got time before Thursday, but less so as from Thursday. But it is what it is: I’ll try to prepare what I can.
What I hope to achieve is that the Ulanzi will display the current time 24/7 (so I hope I can disable all the other Ulanzi/Awtrix “apps”), and an alarm clock icon or something like it, if my DateTime Item wekker_eerstvolgende isn’t NULL. If I press one of the Ulanzi’s buttons, the value of said Item appears, showing me when my next alarm will go off. If it goes off, the other button would let me “snooze” for x minutes. Another button press would “dismiss” the alarm clock, and set wekker_eerstvolgende to NULL. (I’ve got the impresson only two buttons of the Ulanzi can be set for some use, so I might have to rethink something…)
Since I need the time of the next alarm clock, I don’t think a cron based rule would work, so I created a bunch of DateTime Items, a few switches and a (rather convoluted, sadly) rule (see below). Some context for the rule: I’ve got my “days off” marked in my Google Calendar, which I extract with the iCalendar binding. If such a period is ongoing, the switch wekker_schoolwekkers_actief is OFF; the first day of the next period of “days off” is DateTime Item begin_volgende_schoolvakantie; the last day of the currently ongoing period of “days off” is DateTime Item einde_huidige_schoolvakantie. Script melding_gsm_DBE contains actions.NotificationAction.sendNotification(). Switch Item wekker_vakantiewekkers_actief is something I’ll switch on or off manually (but is switched off in the rule below when my “time off” will be over tomorrow).
I’ve created a DateTime Item for every weekday in the “working period” (e.g. wekker_school_maandag), one for every weekday in the “days off period” (e.g. wekker_vakantie_maandag), and a few for “one-off events” (e.g. wekker_eenmalig_01). I’ve also got a Group Item wekker_openhab, which contains all my DateTime “alarm clock” Items:
version: 1
items:
wekker_openhab:
type: Group
group:
type: DateTime
label: Wekkers in openHAB
This is the rule, running daily at 18h00:
var controleperiode = 18; // in uren
var weekdagen = ["maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag", "zondag"];
var allewekkers = items["wekker_openhab"].members;
var wekker_schoolwekkers_actief = items["wekker_schoolwekkers_actief"];
var wekker_vakantiewekkers_actief = items["wekker_vakantiewekkers_actief"];
var begin_volgende_schoolvakantie = items["begin_volgende_schoolvakantie"];
var einde_huidige_schoolvakantie = items["einde_huidige_schoolvakantie"];
var wekkersoorten = {
"school": "wekker_school_",
"eenmalig": "wekker_eenmalig_",
"vakantie": "wekker_vakantie_"
};
function wekkersSorteren(a, b) {
if (time.toZDT(a).isBefore(time.toZDT(b))) {
return -1;
} else {
return 1;
}
}
function wekkerSelecteren(wekkers) {
if (wekkers.length > 1) {
var melding = "Er is voor morgen meer dan één wekker ingesteld; enkel de vroegste wordt geactiveerd."
console.log(melding);
rules.runRule("melding_gsm_DBE", { 'melding': melding });
wekkers.sort(wekkersSorteren);
}
return wekkers[0];
}
function schoolWekkerActief() {
if
(
(
wekker_schoolwekkers_actief.state == "ON"
&&
(
(
begin_volgende_schoolvakantie.state != "NULL"
&&
!time.toZDT(begin_volgende_schoolvakantie).toLocalDate().equals(time.toZDT().plusDays(1).toLocalDate())
)
||
begin_volgende_schoolvakantie.state == "NULL"
)
)
||
(einde_huidige_schoolvakantie.state != "NULL" && time.toZDT(einde_huidige_schoolvakantie).toLocalDate().equals(time.toZDT().toLocalDate()))
) {
wekker_vakantiewekkers_actief.sendCommandIfDifferent("OFF");
return true;
} else {
return false;
}
}
function main() {
var nu = time.toZDT();
var schoolwekkeractief = schoolWekkerActief();
var eenderwelkewekkermorgen = false;
var wekkersmorgen = {
schoolwekkermorgen: false,
schoolwekkers: [],
vakantiewekkermorgen: false,
vakantiewekkers: [],
eenmaligewekkermorgen: false,
eenmaligewekkers: []
};
for (var x = 0; x < allewekkers.length; x++) {
var dezewekker = allewekkers[x];
if (dezewekker.state != "NULL") {
if (dezewekker.name.includes(weekdagen[nu.dayOfWeek().value()-2]) && (dezewekker.name.includes(wekkersoorten["school"]) || dezewekker.name.includes(wekkersoorten["vakantie"]))) {
dezewekker.sendCommand(time.toZDT(dezewekker).plusDays(7));
} else if (time.toZDT(dezewekker).isBefore(nu.plusHours(controleperiode))) {
eenderwelkewekkermorgen = true;
if (schoolwekkeractief && dezewekker.name.includes(wekkersoorten["school"])) {
wekkersmorgen["schoolwekkermorgen"] = true;
wekkersmorgen["schoolwekkers"].push(dezewekker);
} else if (wekker_vakantiewekkers_actief.state == "ON" && dezewekker.name.includes(wekkersoorten["vakantie"])) {
eenderwelkewekkermorgen = true;
wekkersmorgen["vakantiewekkermorgen"] = true;
wekkersmorgen["vakantiewekkers"].push(dezewekker);
} else if (dezewekker.name.includes(wekkersoorten["eenmalig"])) {
eenderwelkewekkermorgen = true;
wekkersmorgen["eenmaligewekkermorgen"] = true;
wekkersmorgen["eenmaligewekkers"].push(dezewekker);
}
}
}
}
if (eenderwelkewekkermorgen) {
if (wekkersmorgen["eenmaligewekkermorgen"]) {
var uiteindelijkewekker = wekkerSelecteren(wekkersmorgen["eenmaligewekkers"]);
items["wekker_eerstvolgende"].sendCommand(uiteindelijkewekker.state);
if (wekkersmorgen["schoolwekkermorgen"]) {
var melding = "Er is voor morgen een eenmalige wekker ingesteld; de normale schoolwekker wordt dus genegeerd."
console.log(melding);
rules.runRule("melding_gsm_DBE", { 'melding': melding });
}
} else if (wekkersmorgen["schoolwekkermorgen"]) {
var uiteindelijkewekker = wekkerSelecteren(wekkersmorgen["schoolwekkers"]);
items["wekker_eerstvolgende"].sendCommand(uiteindelijkewekker.state);
} else if (wekkersmorgen["vakantiewekkermorgen"]) {
var uiteindelijkewekker = wekkerSelecteren(wekkersmorgen["eenmaligewekkers"]);
items["wekker_eerstvolgende"].sendCommand(uiteindelijkewekker.state);
}
}
}
main();
Now onto finding out how these Ulanzi/Awtrix “apps” work…
I’ve also started to explore Tasker, so that another Ulanzi/Awtrix “app” can make some noise or something when one of my starred contacts tries to call me. Additionally, it would be great if I could also control the alarm on my Android phone, and snooze it when I press the “snooze” button on the Ulanzi.
In order to make this all manageable in the UI, I’d like to make a page with collapsable “sections”, so each alarm clock has its own time-picker (or how is it called), and a button to set it to NULL.
I’ll keep you - the reader, or the non-reading world - posted.