Created
September 25, 2017 21:33
-
-
Save Hypfer/c7fa63a4f6d99e0fd856247adf81fae2 to your computer and use it in GitHub Desktop.
somewhat hackish node-red flow to set the color temperature via deconz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"id": "e74a5914.c69128", | |
"type": "interval", | |
"z": "7e4e4efe.436b7", | |
"name": "interval", | |
"interval": "5", | |
"onstart": true, | |
"msg": "{}", | |
"showstatus": false, | |
"unit": "seconds", | |
"statusformat": "YYYY-MM-D HH:mm:ss", | |
"x": 225.0000343322754, | |
"y": 699.7500114440918, | |
"wires": [ | |
[ | |
"861422b3.2fc46" | |
] | |
] | |
}, | |
{ | |
"id": "a08c9357.b93af", | |
"type": "function", | |
"z": "7e4e4efe.436b7", | |
"name": "MakePayload", | |
"func": "newpayload = {};\nnewpayload.ct = msg.payload.ct;\n\nmsg.payload = newpayload;\nreturn msg;", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 972.7500762939453, | |
"y": 632.0000095367432, | |
"wires": [ | |
[ | |
"c7c2d61.c11e328" | |
] | |
] | |
}, | |
{ | |
"id": "34ef6f14.b55c4", | |
"type": "http request", | |
"z": "7e4e4efe.436b7", | |
"name": "", | |
"method": "PUT", | |
"ret": "txt", | |
"url": "http://URL_OF_DECONZ/api/APIKEY/groups/2/action", | |
"tls": "", | |
"x": 1284.500015258789, | |
"y": 476.25000762939453, | |
"wires": [ | |
[ | |
"1d078756.7832a9" | |
] | |
] | |
}, | |
{ | |
"id": "c7c2d61.c11e328", | |
"type": "rbe", | |
"z": "7e4e4efe.436b7", | |
"name": "", | |
"func": "rbe", | |
"gap": "", | |
"start": "", | |
"inout": "out", | |
"x": 1163.0001392364502, | |
"y": 603.5000076293945, | |
"wires": [ | |
[ | |
"34ef6f14.b55c4", | |
"1d078756.7832a9" | |
] | |
] | |
}, | |
{ | |
"id": "861422b3.2fc46", | |
"type": "json", | |
"z": "7e4e4efe.436b7", | |
"name": "", | |
"x": 408.75003814697266, | |
"y": 695.0000114440918, | |
"wires": [ | |
[ | |
"e34d9eb9.5571" | |
] | |
] | |
}, | |
{ | |
"id": "e34d9eb9.5571", | |
"type": "function", | |
"z": "7e4e4efe.436b7", | |
"name": "Calculate Color Temperature for deCONZ", | |
"func": "function sunCalc(){\n// shortcuts for easier to read formulas\n\nvar PI = Math.PI,\n sin = Math.sin,\n cos = Math.cos,\n tan = Math.tan,\n asin = Math.asin,\n atan = Math.atan2,\n acos = Math.acos,\n rad = PI / 180;\n\n// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas\n\n\n// date/time constants and conversions\n\nvar dayMs = 1000 * 60 * 60 * 24,\n J1970 = 2440588,\n J2000 = 2451545;\n\nfunction toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }\nfunction fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); }\nfunction toDays(date) { return toJulian(date) - J2000; }\n\n\n// general calculations for position\n\nvar e = rad * 23.4397; // obliquity of the Earth\n\nfunction rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }\nfunction declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }\n\nfunction azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }\nfunction altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }\n\nfunction siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }\n\nfunction astroRefraction(h) {\n if (h < 0) // the following formula works for positive altitudes only.\n h = 0; // if h = -0.08901179 a div/0 would occur.\n\n // formula 16.4 of \"Astronomical Algorithms\" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.\n // 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad:\n return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179));\n}\n\n// general sun calculations\n\nfunction solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }\n\nfunction eclipticLongitude(M) {\n\n var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center\n P = rad * 102.9372; // perihelion of the Earth\n\n return M + C + P + PI;\n}\n\nfunction sunCoords(d) {\n\n var M = solarMeanAnomaly(d),\n L = eclipticLongitude(M);\n\n return {\n dec: declination(L, 0),\n ra: rightAscension(L, 0)\n };\n}\n\n\nvar SunCalc = {};\n\n\n// calculates sun position for a given date and latitude/longitude\n\nSunCalc.getPosition = function (date, lat, lng) {\n\n var lw = rad * -lng,\n phi = rad * lat,\n d = toDays(date),\n\n c = sunCoords(d),\n H = siderealTime(d, lw) - c.ra;\n\n return {\n azimuth: azimuth(H, phi, c.dec),\n altitude: altitude(H, phi, c.dec)\n };\n};\n\n\n// sun times configuration (angle, morning name, evening name)\n\nvar times = SunCalc.times = [\n [-0.833, 'sunrise', 'sunset' ],\n [ -0.3, 'sunriseEnd', 'sunsetStart' ],\n [ -6, 'dawn', 'dusk' ],\n [ -12, 'nauticalDawn', 'nauticalDusk'],\n [ -18, 'nightEnd', 'night' ],\n [ 6, 'goldenHourEnd', 'goldenHour' ]\n];\n\n// adds a custom time to the times config\n\nSunCalc.addTime = function (angle, riseName, setName) {\n times.push([angle, riseName, setName]);\n};\n\n\n// calculations for sun times\n\nvar J0 = 0.0009;\n\nfunction julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }\n\nfunction approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }\nfunction solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }\n\nfunction hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }\n\n// returns set time for the given sun altitude\nfunction getSetJ(h, lw, phi, dec, n, M, L) {\n\n var w = hourAngle(h, phi, dec),\n a = approxTransit(w, lw, n);\n return solarTransitJ(a, M, L);\n}\n\n\n// calculates sun times for a given date and latitude/longitude\n\nSunCalc.getTimes = function (date, lat, lng) {\n\n var lw = rad * -lng,\n phi = rad * lat,\n\n d = toDays(date),\n n = julianCycle(d, lw),\n ds = approxTransit(0, lw, n),\n\n M = solarMeanAnomaly(ds),\n L = eclipticLongitude(M),\n dec = declination(L, 0),\n\n Jnoon = solarTransitJ(ds, M, L),\n\n i, len, time, Jset, Jrise;\n\n\n var result = {\n solarNoon: fromJulian(Jnoon),\n nadir: fromJulian(Jnoon - 0.5)\n };\n\n for (i = 0, len = times.length; i < len; i += 1) {\n time = times[i];\n\n Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L);\n Jrise = Jnoon - (Jset - Jnoon);\n\n result[time[1]] = fromJulian(Jrise);\n result[time[2]] = fromJulian(Jset);\n }\n\n return result;\n};\n\n\n// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas\n\nfunction moonCoords(d) { // geocentric ecliptic coordinates of the moon\n\n var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude\n M = rad * (134.963 + 13.064993 * d), // mean anomaly\n F = rad * (93.272 + 13.229350 * d), // mean distance\n\n l = L + rad * 6.289 * sin(M), // longitude\n b = rad * 5.128 * sin(F), // latitude\n dt = 385001 - 20905 * cos(M); // distance to the moon in km\n\n return {\n ra: rightAscension(l, b),\n dec: declination(l, b),\n dist: dt\n };\n}\n\nSunCalc.getMoonPosition = function (date, lat, lng) {\n\n var lw = rad * -lng,\n phi = rad * lat,\n d = toDays(date),\n\n c = moonCoords(d),\n H = siderealTime(d, lw) - c.ra,\n h = altitude(H, phi, c.dec),\n // formula 14.1 of \"Astronomical Algorithms\" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.\n pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H));\n\n h = h + astroRefraction(h); // altitude correction for refraction\n\n return {\n azimuth: azimuth(H, phi, c.dec),\n altitude: h,\n distance: c.dist,\n parallacticAngle: pa\n };\n};\n\n\n// calculations for illumination parameters of the moon,\n// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and\n// Chapter 48 of \"Astronomical Algorithms\" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.\n\nSunCalc.getMoonIllumination = function (date) {\n\n var d = toDays(date || new Date()),\n s = sunCoords(d),\n m = moonCoords(d),\n\n sdist = 149598000, // distance from Earth to Sun in km\n\n phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)),\n inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)),\n angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) -\n cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra));\n\n return {\n fraction: (1 + cos(inc)) / 2,\n phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI,\n angle: angle\n };\n};\n\n\nfunction hoursLater(date, h) {\n return new Date(date.valueOf() + h * dayMs / 24);\n}\n\n// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article\n\nSunCalc.getMoonTimes = function (date, lat, lng, inUTC) {\n var t = new Date(date);\n if (inUTC) t.setUTCHours(0, 0, 0, 0);\n else t.setHours(0, 0, 0, 0);\n\n var hc = 0.133 * rad,\n h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,\n h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;\n\n // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)\n for (var i = 1; i <= 24; i += 2) {\n h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;\n h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;\n\n a = (h0 + h2) / 2 - h1;\n b = (h2 - h0) / 2;\n xe = -b / (2 * a);\n ye = (a * xe + b) * xe + h1;\n d = b * b - 4 * a * h1;\n roots = 0;\n\n if (d >= 0) {\n dx = Math.sqrt(d) / (Math.abs(a) * 2);\n x1 = xe - dx;\n x2 = xe + dx;\n if (Math.abs(x1) <= 1) roots++;\n if (Math.abs(x2) <= 1) roots++;\n if (x1 < -1) x1 = x2;\n }\n\n if (roots === 1) {\n if (h0 < 0) rise = i + x1;\n else set = i + x1;\n\n } else if (roots === 2) {\n rise = i + (ye < 0 ? x2 : x1);\n set = i + (ye < 0 ? x1 : x2);\n }\n\n if (rise && set) break;\n\n h0 = h2;\n }\n\n var result = {};\n\n if (rise) result.rise = hoursLater(t, rise);\n if (set) result.set = hoursLater(t, set);\n\n if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;\n\n return result;\n}\n\nreturn SunCalc;\n}\n\nvar SunCalc = sunCalc();\n\n//500-153 = 347\n\nvar ct;\nvar diff;\nvar step;\nvar times;\nvar now;\n\nnow = new Date();\ntimes = SunCalc.getTimes(now, LAT, LONG); //Mein Haus\n\nif(now > times.dawn && now < times.sunriseEnd) {\n diff = new Date(times.sunriseEnd) - new Date(times.dawn);\n step = 347/diff;\n\n ct = 500-((now - new Date(times.dawn))*step); //denn 500 = warm\n}else if(now > times.sunsetStart && now < times.dusk) {\n diff = new Date(times.dusk) - new Date(times.sunsetStart);\n step = 347/diff;\n\n ct = 500-((new Date(times.dusk) - now)*step);\n} else if(now > times.dusk || now < times.dawn) {\n ct = 500; //nacht\n} else {\n ct = 153; //tag\n}\nct = Math.floor(ct);\nif(ct > 500) {\n ct = 500;\n}\nif(ct < 153) {\n ct = 153;\n}\n\nmsg.payload.ct = ct;\n\nreturn msg;", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 675.7500686645508, | |
"y": 693.7500095367432, | |
"wires": [ | |
[ | |
"a08c9357.b93af", | |
"1d078756.7832a9" | |
] | |
] | |
}, | |
{ | |
"id": "1d078756.7832a9", | |
"type": "debug", | |
"z": "7e4e4efe.436b7", | |
"name": "", | |
"active": true, | |
"console": "false", | |
"complete": "false", | |
"x": 1260.0000190734863, | |
"y": 727.5000133514404, | |
"wires": [] | |
} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment