initial commit.
This commit is contained in:
commit
cd2198c411
5 changed files with 123 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
schedule.json
|
27
package-lock.json
generated
Normal file
27
package-lock.json
generated
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "sleeplight",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz",
|
||||
"integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew=="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
|
||||
"integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA=="
|
||||
},
|
||||
"pigpio": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pigpio/-/pigpio-1.2.0.tgz",
|
||||
"integrity": "sha512-DGopuMdjmRguqydLZ3A16PYOiJWtl705aGF3a48Tnc6woLyts4Zj01FklJYgTqFMCZy4ZBHg49xe+W5yG5+jOw==",
|
||||
"requires": {
|
||||
"bindings": "^1.3.0",
|
||||
"nan": "^2.11.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
package.json
Normal file
14
package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "sleeplight",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "runSchedule.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"pigpio": "^1.2.0"
|
||||
}
|
||||
}
|
68
runSchedule.js
Normal file
68
runSchedule.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
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
|
||||
}
|
12
schedule.json.example
Normal file
12
schedule.json.example
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"times": [
|
||||
{
|
||||
"time": 1915,
|
||||
"color": "red"
|
||||
},
|
||||
{
|
||||
"time": 700,
|
||||
"color": "green"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue