DIY circadian rhythm based lighting

I was thinking for 7.4.x. But I have 7.3.0 installed.

I’m in no rush to get the circadian lighting in place, hence I can wait for stable 7.4.x before I try anything.

Seems easier to skip the 7.3.0 method and go straight for the 7.4.0 method when it’s available. Right?

For the script in relation with the Homey firmware version v7.3.0 an additional app (Better Logic) is necessary. This app is not necessary with firmware version v7.4.x.

I just finished the process for 7.3.0 with the Better Logic app and it seems to be working. Thank you!

Looking forward to an updated tutorial on 7.4.0 without the Better Logic app :slight_smile:

Looking backward is maybe better by starting to read the posts :upside_down_face:

This is the entire updated script for Homey firmware v7.4.x, based on the script in post #16, which I modified a little bit in comparison to the original script:

/** 
 * 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 = 'Circadian';
const MIN_BRIGHTNESS = 0.40;
const MAX_BRIGHTNESS = 0.75;
const MIN_TEMPERATURE = 0.3;
const MAX_TEMPERATURE = 0.8;

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 = MIN_TEMPERATURE; // 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)}%`);

// color temperature transitions from 1 to 0 to 1 during the day
temperature = roundDecimals((MAX_TEMPERATURE - (MAX_TEMPERATURE - MIN_TEMPERATURE) * getTemperaturePoint(dayProgress)));
console.log(`${VARIABLE_PREFIX}_Temperatur:\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}_Helligkeit:\t`, brightness);

await Homey.logic.updateVariable({id: 'b042b591-48f9-4803-a9af-3d115ac2a95b', variable: { value: temperature } });
await Homey.logic.updateVariable({id: '2074ddcf-92b2-42eb-a4f2-2c32de90a96a', variable: { value: brightness } });

return true;

The Homey logic variables I use are called:
– Circadian_Helligkeit
– Circadian_Temperatur

If you want to rename the variables, then the following red marked words must be changed:

const VARIABLE_PREFIX = 'Circadian';
console.log(`${VARIABLE_PREFIX}_Temperatur:\t`, temperature);
console.log(`${VARIABLE_PREFIX}_Helligkeit:\t`, brightness);

In these two lines the IDs of the variable must be entered:

await Homey.logic.updateVariable({id: 'b042b591-48f9-4803-a9af-3d115ac2a95b', variable: { value: temperature } });
await Homey.logic.updateVariable({id: '2074ddcf-92b2-42eb-a4f2-2c32de90a96a', variable: { value: brightness } });

The variable IDs are received by running the following script:

Homey.logic.getVariables().then(r => log(r))
5 Likes

Thanks, but that wasn’t what I was asking for. I was asking for one post with the complete instructions, as @DirkG just served me in post #45. Being new to Homey, HomeyScript and scripting in general - I can’t add previous posts together to find the solution.

Much appreciated :heart_eyes:

Will test as soon as I recieve 7.4.x. on my Homey!

EDIT 220511: Just tested with 7.4.1 - working great. Thank you!