Skip to content

Commit

Permalink
Merge pull request #130 from PampaWarro/add-wand
Browse files Browse the repository at this point in the history
Add wand
  • Loading branch information
catalanojuan authored Feb 14, 2023
2 parents e573483 + d2cf242 commit 60e4ea2
Show file tree
Hide file tree
Showing 21 changed files with 2,103 additions and 172 deletions.
4 changes: 2 additions & 2 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Warro lights",
"main": "./src/index.js",
"scripts": {
"start": "node -r ts-node/register --inspect --trace-uncaught --expose-gc --trace-gc --trace-gc-ignore-scavenger src/index.js $npm_package_warroLight_setup",
"start": "node -r ts-node/register --inspect --trace-uncaught --expose-gc --trace-gc --trace-gc-ignore-scavenger src/index.js fuego-2022",
"server": "node src/server.js conga",
"prettier": "prettier --write src/*.js src/**/*.js",
"merge-presets": "node src/mergepresets.js",
Expand All @@ -27,7 +27,7 @@
"gl-matrix": "^3.4.3",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"node-fetch": "^3.2.6",
"node-fetch": "^2.6.9",
"performance-now": "^2.1.0",
"pino": "^8.1.0",
"pino-pretty": "^9.1.1",
Expand Down
23 changes: 23 additions & 0 deletions server/setups/one-strip-wled.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"geometry": "wchica",
"shapeMapping": "wchica",
"lights": 150,
"outputDevices": {
"serial": {
"type": "udp-wled",
"params": {
"numberOfLights": 150,
"ip": "192.168.0.177",
"udpPort": 21324
}
}
},
"lightsToDevicesMapping": [
{
"from": 0,
"to": 150,
"baseIndex": 0,
"deviceName": "serial"
}
]
}
71 changes: 71 additions & 0 deletions server/setups/program-presets/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -1409,5 +1409,76 @@
"pote1": 0,
"pote2": 0
}
},
"wandMix": {
"circlesTap": {
"programs": [
{
"programName": "radial"
},
{
"programName": "djtap",
"config": {
"partyLength": 100,
"drumLength": 10
}
}
]
},
"radialStarsTapStars": {
"programs": [
{
"programName": "stars"
},
{
"programName": "radial",
"config": {
"velocidad": 20
}
},
{
"programName": "djtap",
"config": {
"partyLength": 100,
"effect": "stars"
}
}
],
"multiply": false
},
"radialStarsTapRelampejo": {
"programs": [
{
"programName": "stars"
},
{
"programName": "radial",
"config": {
"velocidad": 20
}
},
{
"programName": "djtap",
"config": {
"partyLength": 100
}
}
]
},
"MainWithWand": {
"programs": [
{
"programName": "PROGRAM_Main_fuego2022"
},
{
"programName": "wand-empty-canvas"
}
]
}
},
"DJTap": {
"DJTapStars": {
"effect": "stars"
}
}
}
4 changes: 4 additions & 0 deletions server/src/LightController.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const programNames = [
"warroBass",
"water-flood",
"waveform",
"DJTap",
"wand-empty-canvas",
"wandMix",
"wand-stars",
];

module.exports = class LightController extends EventEmitter {
Expand Down
2 changes: 1 addition & 1 deletion server/src/devices/encodings.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class RGBEncoder extends Encoder {
class WLEDRGBEncoder extends RGBEncoder {
writeHeader(lights) {
// See https://kno.wled.ge/interfaces/udp-realtime/
// 4 = DNRGB 489/packet
// 2 = DRGB Max 490 leds (TODO: Consider using 4 = DNRGB for multi packets with 489/packet)
// 2 = seconds until WLED returns to normal functioning
this.write([2, 2]);
}
Expand Down
97 changes: 6 additions & 91 deletions server/src/devices/udp-wled.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const dns = require('dns');
const dgram = require("dgram");
const now = require("performance-now");
const logger = require("pino")(require('pino-pretty')());
const fetch = import('node-fetch');
const fetch = require('node-fetch');

const { LightDevice } = require("./base");
const { WLEDRGBEncoder } = require("./encodings");
Expand All @@ -23,9 +23,9 @@ module.exports = class LightDeviceUDPWLED extends LightDevice {
}
});
}
this.remotePort = udpPort;
// 21324 is the default WLED port
this.remotePort = udpPort || 21324;
this.remoteAddress = ip;
// this.udpPort = udpPort;

this.encoder = new WLEDRGBEncoder();

Expand All @@ -43,11 +43,12 @@ module.exports = class LightDeviceUDPWLED extends LightDevice {
let res = await (await fetch(`http://${this.expectedIp}/json/info`, {timeout: 2000})).json()
this.updateStatus(this.STATUS_RUNNING);
this.connected = true;
this.wledName = res.name;
this.lastFps = res.leds.fps;
} catch(err) {
this.updateStatus(this.STATUS_ERROR);
}
setTimeout(() => this.fetchDeviceInfo(), 1000);
setTimeout(() => this.fetchDeviceInfo(), 2000);
}

sendNextFrame() {
Expand All @@ -61,39 +62,11 @@ module.exports = class LightDeviceUDPWLED extends LightDevice {
}
}

// handleArduinoData(data) {
// if (data) {
// data = data.replace(/[^\w]+/gi, "");
//
// if (data.startsWith("YEAH")) {
// logger.info("Reconnected");
// this.updateStatus(this.STATUS_RUNNING);
// } else if (data.startsWith("PERF")) {
// let perfCount = parseInt(data.substring(4) || 0);
// this.lastFps = perfCount;
// // logger.info("Perf ", perfCount)
// // logger.info(`ACK`)
// } else {
// logger.info(`UNEXPECTED MSG'${data}'`);
// }
// } else {
// logger.info(`No data received`);
// }
//
// clearTimeout(this.reconnectTimeout);
//
// this.reconnectTimeout = setTimeout(() => {
// this.connected = false;
// this.updateStatus(this.STATUS_CONNECTING);
// logger.info(`no data`);
// }, RECONNECT_TIME);
// }

// Override parent
logDeviceState() {
if (this.status === this.STATUS_RUNNING) {
if (now() - this.lastPrint > 250) {
logger.info(`FPS: ${this.lastFps}`.green);
logger.info(`FPS: ${this.lastFps} (${this.wledName || '-'})`.green);
this.lastPrint = now();
}
}
Expand Down Expand Up @@ -121,9 +94,6 @@ module.exports = class LightDeviceUDPWLED extends LightDevice {

setupCommunication() {
this.udpSocket = dgram.createSocket("udp4");

// this.udpSocket.on("listening", this.handleListening.bind(this));
// this.udpSocket.on("message", this.handleMessage.bind(this));
this.udpSocket.on("error", this.handleError.bind(this));
this.udpSocket.on("close", this.handleClose.bind(this));

Expand All @@ -139,39 +109,6 @@ module.exports = class LightDeviceUDPWLED extends LightDevice {
this.fetchDeviceInfo();
}

// handleListening() {
// const address = this.udpSocket.address();
// this.updateStatus(this.STATUS_CONNECTING);
// logger.info(
// "UDP Server listening on " + address.address + ":" + address.port
// );
// }

// handleMessage(message, remote) {
// // logger.info(message.toString(), remote.address)
// if (message.toString().startsWith("YEAH") &&
// !message.toString().endsWith(this.name)) {
// logger.warn("UDP message came from %s, expected %s",
// message.toString().substr(4), this.name);
// return;
// } else if (this.expectedIp && remote.address !== this.expectedIp) {
// logger.warn("UDP message came from %s, expected %s", remote.address,
// this.expectedIp);
// return;
// }
//
// this.remotePort = remote.port;
// this.remoteAddress = remote.address;
//
// if (!this.connected) {
// logger.info(`Connected to ${this.remoteAddress}:${this.remotePort}`);
// this.connected = true;
// this.updateStatus(this.STATUS_RUNNING);
// }
//
// this.handleArduinoData(message.toString());
// }

handleClose() {
this.handleError("socket closed. Falta manejarlo");
}
Expand All @@ -185,25 +122,3 @@ module.exports = class LightDeviceUDPWLED extends LightDevice {
setTimeout(() => this.setupCommunication(), 500);
}
};
//
//
// var client = dgram.createSocket('udp4');
// const _ = require('lodash')
// let i = 0;
// let send = () => {
// i = (i+1) % 120;
// let payload = Buffer.from([
// 2, 5,
// 100, 50, 50,
// ... _.flatten(new Array(i*1).fill([0,0,0])),
// // 0, 0, 50,
// // 0, 255, Math.floor(Math.random()*255),
// 255, 0, 255,
// 255, 0, 255,
// 255, 0, 255,
// 255, 0, 255,
// ]);
// client.send(payload, 0, payload.length, 21666, '192.168.0.255');
// }
//
// setTimeout(send, 20);
2 changes: 1 addition & 1 deletion server/src/light-programs/base-programs/LightProgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = class LightProgram {
throw new Error("Child classes should override drawFrame");
}

tap(clientId) {
tap(data) {
}

updateConfig(config) {
Expand Down
84 changes: 84 additions & 0 deletions server/src/light-programs/base-programs/TappableMixProgram.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const _ = require("lodash");
const LightProgram = require("./LightProgram");

module.exports = function mixTappablePrograms(...programs) {
return class TappableMixProgram extends LightProgram {
constructor(config, geometry, shapeMapping) {
super(config, geometry);
// Shallow copy of schedule
this.programs = [];

_.each(programs, scheduleItem => {
if (!_.isArray(scheduleItem)) {
scheduleItem = [scheduleItem, {}, 1];
}
let [Program, specificConfig, alpha] = scheduleItem;

this.programs.push({
programInstance: new Program(config, geometry, shapeMapping),
customConfig: specificConfig,
alpha: alpha || 1,
leds: new Array(this.numberOfLeds).fill([0, 0, 0]),
});
});
}

init() {
this.past = null;
this.programs.forEach(p => p.programInstance.init());
}

tap(data){
this.programs.forEach((p, i) => {
if (typeof p.programInstance.tap === "function"){
console.log('tappable mix tap')
p.programInstance.tap(data);
}
})
}

mix(frames, output) {
// TODO: clamp / divide final values?
frames[0].forEach((c, i) => {
let [r, g, b] = c;
for (let j = 1; j < frames.length; j++) {
r += frames[j][i][0];
g += frames[j][i][1];
b += frames[j][i][2];
}
output[i] = [r, g, b];
});
}

drawFrame(leds, context) {
let frames = [];
_.each(this.programs, (p, i) => {
// TODO: remove this forwarding somehow
p.programInstance.timeInMs = this.timeInMs;

p.leds.fill([0, 0, 0]);
p.programInstance.drawFrame(p.leds, context);
frames.push(p.leds);
});

this.mix(frames, leds);
}

updateConfig(config) {
this.config = config;
for (let item of this.programs) {
item.programInstance.updateConfig(config);
}
}

static configSchema() {
let schema = {};
_.each(programs, program => {
if (_.isArray(program)) program = program[0];

schema = _.extend(schema, program.configSchema());
});
return schema;
}
};
};
Loading

0 comments on commit 60e4ea2

Please sign in to comment.