leds/lights.js

82 lines
2.0 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 || 10;
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) {
return ((r << 8) + g) << 8 + b;
}
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
for (let i = 0; i < cfg.leds; i++) {
var r = Math.floor(Math.random() * 100)
var g = Math.floor(Math.random() * 100);
var b = Math.floor(Math.random() * 100);
next_pattern[i] = ((r << 8) + g) << 8 + b;
}
}
export function tick() {
var changed = false;
for (let i = 0; i < cfg.leds; i++) {
if (next_pattern[i] != pixels[i]) {
changed = true;
fade(i);
}
}
if (!changed) {
tick_pattern();
}
ws281x.render(pixels);
ws281x.sleep(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_g = final.g - original.g;
var diff_b = final.b - original.b;
var interval_r = diff_r / fade_ticks;
var interval_g = diff_g / fade_ticks;
var interval_b = diff_b / fade_ticks;
if (Math.abs(final.r - current.r) < interval_r &&
Math.abs(final.g - current.g) < interval_g &&
Math.abs(final.b - current.b) < interval_b
) {
pixels[index] = next_pattern[index];
pixel_cache[index] = next_pattern[index];
}
else {
pixels[index] = rgb_to_int(current.r + interval_r,
current.g + interval_g,
current.b + interval_b);
}
}