Last active
September 3, 2024 02:04
-
-
Save suhajdab/2f162833369751a07239b6736ddb6d5f to your computer and use it in GitHub Desktop.
Calculate Color Temperature and Brightness for current time in HomeyScript
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
/** | |
* Adjust Color temperature and Brightness based on time of day | |
* as if it were April 16th, a nice long spring day in southern Sweden | |
*/ | |
const VARIABLE_PREFIX = 'CircadianRhythm_'; | |
const MIN_BRIGHTNESS = 0.12; | |
const MAX_BRIGHTNESS = 1; | |
const sys = await Homey.system.getInfo(); | |
// hack because sys date no longer returns local time, but rather UTC :( | |
const regex = /(\d\d):(\d\d):(\d\d)/; | |
const timeMatches = sys.dateHuman.match(regex) | |
const solarNoon = 0.546 // on April 16 is 13:06 | |
// defaults | |
let temperature = 1; // Homey color temperature: 0 (coolest, midday) to 1 (warmest, sunset/sunrise) | |
let brightness = MIN_BRIGHTNESS; // [0-1] | |
// used standard normal distribution curve to derive equation [https://en.wikipedia.org/wiki/Normal_distribution#Standard_normal_distribution] | |
// equations adjusted for color temperature and brightness [https://codepen.io/suhajdab/pen/wvzpqdQ?editors=0010] | |
getTemperaturePoint = x => { | |
const r = 0.20; // adjust curve width | |
return Math.pow(Math.E, -0.3 * Math.pow((x - solarNoon) / r, 4)); | |
} | |
getBrightnessPoint = x => { | |
const r = 0.28; // adjust curve width | |
return Math.min(1 * Math.pow(Math.E, -0.3 * Math.pow((x - solarNoon) / r, 8)), 1); | |
} | |
// round to 2 decimal places to avoid 'invalid token error' when reading in a flow | |
const roundDecimals = (num, places = 2) => { | |
return Math.round(num * Math.pow(10, places)) / Math.pow(10, places); | |
} | |
const dayStart = new Date(sys.date).setHours(0, 0); | |
const dayEnd = new Date(sys.date).setHours(23, 59); | |
const now = new Date(sys.date).setHours(timeMatches[1]); // adjust for borked timezones in Homey v5 | |
const dayProgress = roundDecimals((now - dayStart) / (dayEnd - dayStart), 4); | |
console.log('At', new Date(now).toLocaleTimeString([], { hour12: false })); | |
console.log('Day progress:\t\t', `${Math.round(dayProgress * 100)}%`); | |
// use Better Logic app to store values and use later in Flows | |
let BLApp = await Homey.apps.getApp({ id: 'net.i-dev.betterlogic' }); | |
// color temperature transitions from 1 to 0 to 1 during the day | |
temperature = roundDecimals(1 - getTemperaturePoint(dayProgress)); | |
console.log(`${VARIABLE_PREFIX}_temperature:\t`, temperature); | |
// brightness transitions from MIN to MAX to MIN during day | |
brightness = roundDecimals((MIN_BRIGHTNESS + (MAX_BRIGHTNESS - MIN_BRIGHTNESS) * getBrightnessPoint(dayProgress))); | |
console.log(`${VARIABLE_PREFIX}_brightness:\t`, brightness); | |
BLApp.apiPut(`${VARIABLE_PREFIX}temperature/${temperature}`); | |
BLApp.apiPut(`${VARIABLE_PREFIX}brightness/${brightness}`); | |
return true; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
Just discovered your script and immediately packed in homeyscript!
But I still have some questions:
which flows have you made? Do you let homey do the
script every second?
Which flow did you create so that the temperature etc. are retrieved? Are they stored in a logic?
Definitely want to have this :slight_smile:
Maybe you could share your flows on this?
I would be mega grateful to you 😉
Nice work!