suncalc
suncalc copied to clipboard
Result for Moonrise/set when not alwaysUp or alwaysDown give undefined instead of false
As stated in the header the output for these 2 results is undefined as you never set them. Add something like in .getMoonTimes result[alwaysUp] = false; result[alwaysDown] = false; To test it I have my lat en lon and local time are lat = 51.871513, lon = 4.665949; Date 2019-02-11;00:00:00 (slightly off for privacy) Now result for me is undefined for that position and time and also for a lot of others, causing Node-RED to fail.
Greetings gentlemen,
I have a fix for function SunCalc.getMoonTimes, in next commented code.
//==================================================// SunCalc.getMoonTimes = function (date, lat, lng, inUTC) { var t = new Date(date); if (inUTC) t.setUTCHours(0, 0, 0, 0); else t.setHours(0, 0, 0, 0);
var hc = 0.133 * rad,
h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;
// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
for (var i = 1; i <= 2*24; i += 2) { //===tge===20190731===extend in two 24-hours===
h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;
a = (h0 + h2) / 2 - h1;
b = (h2 - h0) / 2;
xe = -b / (2 * a);
ye = (a * xe + b) * xe + h1;
d = b * b - 4 * a * h1;
roots = 0;
if (d >= 0) {
dx = Math.sqrt(d) / (Math.abs(a) * 2);
x1 = xe - dx;
x2 = xe + dx;
if (Math.abs(x1) <= 1) roots++;
if (Math.abs(x2) <= 1) roots++;
if (x1 < -1) x1 = x2;
}
if (roots === 1) {
if (h0 < 0) rise = i + x1; // finds one : rise or set and store it
else set = i + x1; // until finds the second.
// a problem occurs when first find set.
// ( set < rise ????? )
} else if (roots === 2) {
rise = i + (ye < 0 ? x2 : x1);
set = i + (ye < 0 ? x1 : x2);
}
if ( set && !rise ) set = null; //===tge===20190731===
// if find set, but not rise, then set canceled.
// so first find rise and then
// find set over night
if (rise && set) {
// console.log(i, rise, set, set - rise);
if ( set < rise ){ //===tge===20190731===if found
set = null; // the impossible ( set < rise ), then set canceled.
}else{ // else
break; // brake the loop, we have solution
}
}
h0 = h2;
}
var result = {};
if (rise) result.rise = hoursLater(t, rise);
if (set) result.set = hoursLater(t, set);
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
return result;
}; //==================================================//
Regards Evangelos