leds/lights.js

138 lines
No EOL
4.2 KiB
JavaScript

import ws281x from 'rpi-ws281x'
import * as fs from 'fs'
const cfg = JSON.parse(fs.readFileSync('./config.json'));
const fade_ticks = cfg.fade_ticks || 20;
var pixels = new Uint32Array(cfg.leds);
var pixel_cache = new Uint32Array(cfg.leds);
var next_pattern = new Uint32Array(cfg.leds);
var pattern = {}
function rgb_to_int(r, g, b) {
let rgb = r;
rgb = (rgb << 8) + g;
rgb = (rgb << 8) + b;
return rgb;
}
function int_to_rgb(int) {
var r = (int >> 16) & 0xFF;
var g = (int >> 8) & 0xFF;
var b = (int) & 0xFF;
return { r: r, g: g, b: b };
}
ws281x.configure({
leds: cfg.leds || 300,
brightness: cfg.brightness || 200,
gpio: cfg.gpio || 18,
stripType: cfg.type || 'grb'
});
export function set_pattern(pat) {
pattern = pat
}
function tick_pattern() {
// do the parsing stuff here
console.log("TICKING PATTERN")
for (let i = 0; i < cfg.leds; i++) {
var r = Math.floor(Math.random() * 256)
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
next_pattern[i] = rgb_to_int(r, g, b);
}
}
export function tick() {
var changed = false;
for (let i = 0; i < cfg.leds; i++) {
if (next_pattern[i] != pixels[i]) {
if (next_pattern[i] == pixel_cache[i]) {
console.log("INCONGRUENCE WITH " + i);
pixels[i] = next_pattern[i];
}
else {
changed = true;
fade(i);
}
}
else if (pixel_cache[i] != pixels[i]) {
console.log("PATTERN NOT STORED " + i);
pixel_cache[i] = pixels[i];
}
}
if (!changed) {
tick_pattern();
}
else {
ws281x.render(pixels);
}
ws281x.sleep(cfg.sleep_time || 500);
}
function fade(index) {
var original = int_to_rgb(pixel_cache[index]);
var current = int_to_rgb(pixels[index]);
var final = int_to_rgb(next_pattern[index]);
var diff_r = final.r - original.r;
var diff_cr = current.r - original.r;
var diff_g = final.g - original.g;
var diff_cg = current.g - original.g;
var diff_b = final.b - original.b;
var diff_cb = current.b - original.b;
var sign_r = diff_r === Math.abs(diff_r) ? 1 : -1;
var sign_g = diff_g === Math.abs(diff_g) ? 1 : -1;
var sign_b = diff_b === Math.abs(diff_b) ? 1 : -1;
console.log(`${diff_r} ${sign_r} ${diff_g} ${sign_g} ${diff_b} ${sign_b}`);
var interval_r = sign_r * Math.ceil(Math.abs(diff_r) / fade_ticks);
var interval_g = sign_g * Math.ceil(Math.abs(diff_g) / fade_ticks);
var interval_b = sign_b * Math.ceil(Math.abs(diff_b) / fade_ticks);
console.log(`t ${Math.abs(diff_r) / fade_ticks} ${Math.ceil(Math.abs(diff_r) / fade_ticks)}` +
`${Math.abs(diff_g) / fade_ticks} ${Math.ceil(Math.abs(diff_g) / fade_ticks)}` +
`${Math.abs(diff_b) / fade_ticks} ${Math.ceil(Math.abs(diff_b) / fade_ticks)}`);
var current_tick_r = Math.floor(Math.abs(diff_cr / diff_r) * fade_ticks);
var current_tick_g = Math.floor(Math.abs(diff_cg / diff_g) * fade_ticks);
var current_tick_b = Math.floor(Math.abs(diff_cb / diff_b) * fade_ticks);
if (diff_r == 0 ||
current.r + interval_r >= final.r ||
current_tick_r + 1 >= fade_ticks) {
current.r = final.r;
interval_r = 0;
current_tick_r = fade_ticks;
}
if (diff_g == 0 ||
current.g + interval_g >= final.g ||
current_tick_g + 1 >= fade_ticks) {
current.g = final.g;
interval_g = 0;
current_tick_g = fade_ticks;
}
if (diff_b == 0 ||
current.b + interval_b >= final.b ||
current_tick_b + 1 >= fade_ticks) {
current.b = final.b;
interval_b = 0;
current_tick_b = fade_ticks;
}
if (current_tick_r + 1 >= fade_ticks &&
current_tick_g + 1 >= fade_ticks &&
current_tick_b + 1 >= fade_ticks) {
console.log("FINISHED");
pixel_cache[index] = next_pattern[index];
}
else {
pixels[index] = rgb_to_int(current.r + interval_r,
current.g + interval_g,
current.b + interval_b);
let prev = int_to_rgb(pixel_cache[index]);
console.log(`${current_tick_r} ${current_tick_g} ${current_tick_b}: `
+ `CURRENT COLOR: ${current.r} ${current.g} ${current.b} NEW COLOR: ${current.r + interval_r} ${current.g + interval_g} ${current.b + interval_b} ` +
`FINAL: ${final.r} ${final.g} ${final.b} ` +
`\nINTERVAL: ${interval_r} ${interval_g} ${interval_b} ` +
`PREVIOUS: ${prev.r} ${prev.g} ${prev.b}`);
}
}