|
|
@ -46,62 +46,61 @@ Module.register("clock", {
|
|
|
|
Log.info("Starting module: " + this.name);
|
|
|
|
Log.info("Starting module: " + this.name);
|
|
|
|
|
|
|
|
|
|
|
|
// Schedule update interval.
|
|
|
|
// Schedule update interval.
|
|
|
|
var self = this;
|
|
|
|
this.second = moment().second();
|
|
|
|
self.second = moment().second();
|
|
|
|
this.minute = moment().minute();
|
|
|
|
self.minute = moment().minute();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Calculate how many ms should pass until next update depending on if seconds is displayed or not
|
|
|
|
// Calculate how many ms should pass until next update depending on if seconds is displayed or not
|
|
|
|
var delayCalculator = function (reducedSeconds) {
|
|
|
|
const delayCalculator = (reducedSeconds) => {
|
|
|
|
var EXTRA_DELAY = 50; //Deliberate imperceptable delay to prevent off-by-one timekeeping errors
|
|
|
|
const EXTRA_DELAY = 50; // Deliberate imperceptible delay to prevent off-by-one timekeeping errors
|
|
|
|
|
|
|
|
|
|
|
|
if (self.config.displaySeconds) {
|
|
|
|
if (this.config.displaySeconds) {
|
|
|
|
return 1000 - moment().milliseconds() + EXTRA_DELAY;
|
|
|
|
return 1000 - moment().milliseconds() + EXTRA_DELAY;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return (60 - reducedSeconds) * 1000 - moment().milliseconds() + EXTRA_DELAY;
|
|
|
|
return (60 - reducedSeconds) * 1000 - moment().milliseconds() + EXTRA_DELAY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//A recursive timeout function instead of interval to avoid drifting
|
|
|
|
// A recursive timeout function instead of interval to avoid drifting
|
|
|
|
var notificationTimer = function () {
|
|
|
|
const notificationTimer = () => {
|
|
|
|
self.updateDom();
|
|
|
|
this.updateDom();
|
|
|
|
|
|
|
|
|
|
|
|
//If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent)
|
|
|
|
// If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent)
|
|
|
|
if (self.config.displaySeconds) {
|
|
|
|
if (this.config.displaySeconds) {
|
|
|
|
self.second = moment().second();
|
|
|
|
this.second = moment().second();
|
|
|
|
if (self.second !== 0) {
|
|
|
|
if (this.second !== 0) {
|
|
|
|
self.sendNotification("CLOCK_SECOND", self.second);
|
|
|
|
this.sendNotification("CLOCK_SECOND", this.second);
|
|
|
|
setTimeout(notificationTimer, delayCalculator(0));
|
|
|
|
setTimeout(notificationTimer, delayCalculator(0));
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification
|
|
|
|
// If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification
|
|
|
|
self.minute = moment().minute();
|
|
|
|
this.minute = moment().minute();
|
|
|
|
self.sendNotification("CLOCK_MINUTE", self.minute);
|
|
|
|
this.sendNotification("CLOCK_MINUTE", this.minute);
|
|
|
|
setTimeout(notificationTimer, delayCalculator(0));
|
|
|
|
setTimeout(notificationTimer, delayCalculator(0));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//Set the initial timeout with the amount of seconds elapsed as reducedSeconds so it will trigger when the minute changes
|
|
|
|
// Set the initial timeout with the amount of seconds elapsed as reducedSeconds so it will trigger when the minute changes
|
|
|
|
setTimeout(notificationTimer, delayCalculator(self.second));
|
|
|
|
setTimeout(notificationTimer, delayCalculator(this.second));
|
|
|
|
|
|
|
|
|
|
|
|
// Set locale.
|
|
|
|
// Set locale.
|
|
|
|
moment.locale(config.language);
|
|
|
|
moment.locale(config.language);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Override dom generator.
|
|
|
|
// Override dom generator.
|
|
|
|
getDom: function () {
|
|
|
|
getDom: function () {
|
|
|
|
var wrapper = document.createElement("div");
|
|
|
|
const wrapper = document.createElement("div");
|
|
|
|
|
|
|
|
|
|
|
|
/************************************
|
|
|
|
/************************************
|
|
|
|
* Create wrappers for DIGITAL clock
|
|
|
|
* Create wrappers for DIGITAL clock
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
var dateWrapper = document.createElement("div");
|
|
|
|
const dateWrapper = document.createElement("div");
|
|
|
|
var timeWrapper = document.createElement("div");
|
|
|
|
const timeWrapper = document.createElement("div");
|
|
|
|
var secondsWrapper = document.createElement("sup");
|
|
|
|
const secondsWrapper = document.createElement("sup");
|
|
|
|
var periodWrapper = document.createElement("span");
|
|
|
|
const periodWrapper = document.createElement("span");
|
|
|
|
var sunWrapper = document.createElement("div");
|
|
|
|
const sunWrapper = document.createElement("div");
|
|
|
|
var moonWrapper = document.createElement("div");
|
|
|
|
const moonWrapper = document.createElement("div");
|
|
|
|
var weekWrapper = document.createElement("div");
|
|
|
|
const weekWrapper = document.createElement("div");
|
|
|
|
// Style Wrappers
|
|
|
|
// Style Wrappers
|
|
|
|
dateWrapper.className = "date normal medium";
|
|
|
|
dateWrapper.className = "date normal medium";
|
|
|
|
timeWrapper.className = "time bright large light";
|
|
|
|
timeWrapper.className = "time bright large light";
|
|
|
@ -114,14 +113,13 @@ Module.register("clock", {
|
|
|
|
// The moment().format("h") method has a bug on the Raspberry Pi.
|
|
|
|
// The moment().format("h") method has a bug on the Raspberry Pi.
|
|
|
|
// So we need to generate the timestring manually.
|
|
|
|
// So we need to generate the timestring manually.
|
|
|
|
// See issue: https://github.com/MichMich/MagicMirror/issues/181
|
|
|
|
// See issue: https://github.com/MichMich/MagicMirror/issues/181
|
|
|
|
var timeString;
|
|
|
|
let timeString;
|
|
|
|
var now = moment();
|
|
|
|
const now = moment();
|
|
|
|
this.lastDisplayedMinute = now.minute();
|
|
|
|
|
|
|
|
if (this.config.timezone) {
|
|
|
|
if (this.config.timezone) {
|
|
|
|
now.tz(this.config.timezone);
|
|
|
|
now.tz(this.config.timezone);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var hourSymbol = "HH";
|
|
|
|
let hourSymbol = "HH";
|
|
|
|
if (this.config.timeFormat !== 24) {
|
|
|
|
if (this.config.timeFormat !== 24) {
|
|
|
|
hourSymbol = "h";
|
|
|
|
hourSymbol = "h";
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -160,7 +158,7 @@ Module.register("clock", {
|
|
|
|
* @returns {string} The formatted time string
|
|
|
|
* @returns {string} The formatted time string
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
function formatTime(config, time) {
|
|
|
|
function formatTime(config, time) {
|
|
|
|
var formatString = hourSymbol + ":mm";
|
|
|
|
let formatString = hourSymbol + ":mm";
|
|
|
|
if (config.showPeriod && config.timeFormat !== 24) {
|
|
|
|
if (config.showPeriod && config.timeFormat !== 24) {
|
|
|
|
formatString += config.showPeriodUpper ? "A" : "a";
|
|
|
|
formatString += config.showPeriodUpper ? "A" : "a";
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -170,7 +168,7 @@ Module.register("clock", {
|
|
|
|
if (this.config.showSunTimes) {
|
|
|
|
if (this.config.showSunTimes) {
|
|
|
|
const sunTimes = SunCalc.getTimes(now, this.config.lat, this.config.lon);
|
|
|
|
const sunTimes = SunCalc.getTimes(now, this.config.lat, this.config.lon);
|
|
|
|
const isVisible = now.isBetween(sunTimes.sunrise, sunTimes.sunset);
|
|
|
|
const isVisible = now.isBetween(sunTimes.sunrise, sunTimes.sunset);
|
|
|
|
var nextEvent;
|
|
|
|
let nextEvent;
|
|
|
|
if (now.isBefore(sunTimes.sunrise)) {
|
|
|
|
if (now.isBefore(sunTimes.sunrise)) {
|
|
|
|
nextEvent = sunTimes.sunrise;
|
|
|
|
nextEvent = sunTimes.sunrise;
|
|
|
|
} else if (now.isBefore(sunTimes.sunset)) {
|
|
|
|
} else if (now.isBefore(sunTimes.sunset)) {
|
|
|
@ -198,7 +196,7 @@ Module.register("clock", {
|
|
|
|
const moonIllumination = SunCalc.getMoonIllumination(now.toDate());
|
|
|
|
const moonIllumination = SunCalc.getMoonIllumination(now.toDate());
|
|
|
|
const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon);
|
|
|
|
const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon);
|
|
|
|
const moonRise = moonTimes.rise;
|
|
|
|
const moonRise = moonTimes.rise;
|
|
|
|
var moonSet;
|
|
|
|
let moonSet;
|
|
|
|
if (moment(moonTimes.set).isAfter(moonTimes.rise)) {
|
|
|
|
if (moment(moonTimes.set).isAfter(moonTimes.rise)) {
|
|
|
|
moonSet = moonTimes.set;
|
|
|
|
moonSet = moonTimes.set;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -224,6 +222,7 @@ Module.register("clock", {
|
|
|
|
/****************************************************************
|
|
|
|
/****************************************************************
|
|
|
|
* Create wrappers for ANALOG clock, only if specified in config
|
|
|
|
* Create wrappers for ANALOG clock, only if specified in config
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
const clockCircle = document.createElement("div");
|
|
|
|
|
|
|
|
|
|
|
|
if (this.config.displayType !== "digital") {
|
|
|
|
if (this.config.displayType !== "digital") {
|
|
|
|
// If it isn't 'digital', then an 'analog' clock was also requested
|
|
|
|
// If it isn't 'digital', then an 'analog' clock was also requested
|
|
|
@ -232,12 +231,11 @@ Module.register("clock", {
|
|
|
|
if (this.config.timezone) {
|
|
|
|
if (this.config.timezone) {
|
|
|
|
now.tz(this.config.timezone);
|
|
|
|
now.tz(this.config.timezone);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var second = now.seconds() * 6,
|
|
|
|
const second = now.seconds() * 6,
|
|
|
|
minute = now.minute() * 6 + second / 60,
|
|
|
|
minute = now.minute() * 6 + second / 60,
|
|
|
|
hour = ((now.hours() % 12) / 12) * 360 + 90 + minute / 12;
|
|
|
|
hour = ((now.hours() % 12) / 12) * 360 + 90 + minute / 12;
|
|
|
|
|
|
|
|
|
|
|
|
// Create wrappers
|
|
|
|
// Create wrappers
|
|
|
|
var clockCircle = document.createElement("div");
|
|
|
|
|
|
|
|
clockCircle.className = "clockCircle";
|
|
|
|
clockCircle.className = "clockCircle";
|
|
|
|
clockCircle.style.width = this.config.analogSize;
|
|
|
|
clockCircle.style.width = this.config.analogSize;
|
|
|
|
clockCircle.style.height = this.config.analogSize;
|
|
|
|
clockCircle.style.height = this.config.analogSize;
|
|
|
@ -252,14 +250,14 @@ Module.register("clock", {
|
|
|
|
} else if (this.config.analogFace !== "none") {
|
|
|
|
} else if (this.config.analogFace !== "none") {
|
|
|
|
clockCircle.style.border = "2px solid white";
|
|
|
|
clockCircle.style.border = "2px solid white";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var clockFace = document.createElement("div");
|
|
|
|
const clockFace = document.createElement("div");
|
|
|
|
clockFace.className = "clockFace";
|
|
|
|
clockFace.className = "clockFace";
|
|
|
|
|
|
|
|
|
|
|
|
var clockHour = document.createElement("div");
|
|
|
|
const clockHour = document.createElement("div");
|
|
|
|
clockHour.id = "clockHour";
|
|
|
|
clockHour.id = "clockHour";
|
|
|
|
clockHour.style.transform = "rotate(" + hour + "deg)";
|
|
|
|
clockHour.style.transform = "rotate(" + hour + "deg)";
|
|
|
|
clockHour.className = "clockHour";
|
|
|
|
clockHour.className = "clockHour";
|
|
|
|
var clockMinute = document.createElement("div");
|
|
|
|
const clockMinute = document.createElement("div");
|
|
|
|
clockMinute.id = "clockMinute";
|
|
|
|
clockMinute.id = "clockMinute";
|
|
|
|
clockMinute.style.transform = "rotate(" + minute + "deg)";
|
|
|
|
clockMinute.style.transform = "rotate(" + minute + "deg)";
|
|
|
|
clockMinute.className = "clockMinute";
|
|
|
|
clockMinute.className = "clockMinute";
|
|
|
@ -269,7 +267,7 @@ Module.register("clock", {
|
|
|
|
clockFace.appendChild(clockMinute);
|
|
|
|
clockFace.appendChild(clockMinute);
|
|
|
|
|
|
|
|
|
|
|
|
if (this.config.displaySeconds) {
|
|
|
|
if (this.config.displaySeconds) {
|
|
|
|
var clockSecond = document.createElement("div");
|
|
|
|
const clockSecond = document.createElement("div");
|
|
|
|
clockSecond.id = "clockSecond";
|
|
|
|
clockSecond.id = "clockSecond";
|
|
|
|
clockSecond.style.transform = "rotate(" + second + "deg)";
|
|
|
|
clockSecond.style.transform = "rotate(" + second + "deg)";
|
|
|
|
clockSecond.className = "clockSecond";
|
|
|
|
clockSecond.className = "clockSecond";
|
|
|
@ -312,14 +310,14 @@ Module.register("clock", {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Both clocks have been configured, check position
|
|
|
|
// Both clocks have been configured, check position
|
|
|
|
var placement = this.config.analogPlacement;
|
|
|
|
const placement = this.config.analogPlacement;
|
|
|
|
|
|
|
|
|
|
|
|
var analogWrapper = document.createElement("div");
|
|
|
|
const analogWrapper = document.createElement("div");
|
|
|
|
analogWrapper.id = "analog";
|
|
|
|
analogWrapper.id = "analog";
|
|
|
|
analogWrapper.style.cssFloat = "none";
|
|
|
|
analogWrapper.style.cssFloat = "none";
|
|
|
|
analogWrapper.appendChild(clockCircle);
|
|
|
|
analogWrapper.appendChild(clockCircle);
|
|
|
|
|
|
|
|
|
|
|
|
var digitalWrapper = document.createElement("div");
|
|
|
|
const digitalWrapper = document.createElement("div");
|
|
|
|
digitalWrapper.id = "digital";
|
|
|
|
digitalWrapper.id = "digital";
|
|
|
|
digitalWrapper.style.cssFloat = "none";
|
|
|
|
digitalWrapper.style.cssFloat = "none";
|
|
|
|
digitalWrapper.appendChild(dateWrapper);
|
|
|
|
digitalWrapper.appendChild(dateWrapper);
|
|
|
@ -328,8 +326,8 @@ Module.register("clock", {
|
|
|
|
digitalWrapper.appendChild(moonWrapper);
|
|
|
|
digitalWrapper.appendChild(moonWrapper);
|
|
|
|
digitalWrapper.appendChild(weekWrapper);
|
|
|
|
digitalWrapper.appendChild(weekWrapper);
|
|
|
|
|
|
|
|
|
|
|
|
var appendClocks = function (condition, pos1, pos2) {
|
|
|
|
const appendClocks = (condition, pos1, pos2) => {
|
|
|
|
var padding = [0, 0, 0, 0];
|
|
|
|
const padding = [0, 0, 0, 0];
|
|
|
|
padding[placement === condition ? pos1 : pos2] = "20px";
|
|
|
|
padding[placement === condition ? pos1 : pos2] = "20px";
|
|
|
|
analogWrapper.style.padding = padding.join(" ");
|
|
|
|
analogWrapper.style.padding = padding.join(" ");
|
|
|
|
if (placement === condition) {
|
|
|
|
if (placement === condition) {
|
|
|
|