const Gpio = require("pigpio").Gpio; const schedule = require("./schedule.json"); const HZ = 10000; let ledRed = new Gpio(18, {mode: Gpio.OUTPUT}); let ledGreen = new Gpio(12, {mode: Gpio.OUTPUT}); let timings = schedule.times.reduce((result, time) => { result.push({start: time.time, color: time.color}); return result; }, []).sort((a, b) => a.start - b.start).map((timing, i, arr) => { timing.end = arr[(i+1) % arr.length].start; return timing; }); splitAtMidnight(timings); let state = { color: "red" } let updateState = setInterval(() => { let time = getTime(); let timing = timings.find(x => x.start <= time && x.end > time); if(timing.color !== state.color) { state = { color: timing.color }; } }, 1000); let render = setInterval(() => { switch(state.color) { case "red": if(ledGreen.digitalRead()) { return ledGreen.digitalWrite(0); } return ledRed.hardwarePwmWrite(HZ, getBrightness(Date.now())); break; case "green": if(ledRed.digitalRead()) { return ledRed.digitalWrite(0); } return ledGreen.hardwarePwmWrite(HZ, getBrightness(Date.now())); break; } }, 50); function getBrightness(x) { return Math.floor(breathingCurve(x, 3000, 1000000, 100000)); } function breathingCurve(x, interval = 3000, max, min) { let t = (x)/interval; let y = (Math.sin(t) + 1)/2; return ((max-min) * y) + min; } function splitAtMidnight(arr) { let last = arr[arr.length -1]; arr.unshift({ ...last, start: 0}); arr[arr.length - 1].end = 0; } function getTime() { let date = new Date(Date.now()); return (date.getHours() * 100) + date.getMinutes() + 1 }