fixed starting and stopping of animations
This commit is contained in:
parent
9ceb501265
commit
b6c2e04db2
2 changed files with 51 additions and 42 deletions
|
@ -1,8 +1,6 @@
|
||||||
const logger = require('./logger');
|
const logger = require('./logger');
|
||||||
const blinkstick = require('blinkstick');
|
const blinkstick = require('blinkstick');
|
||||||
|
|
||||||
const LED_ANIMATED = 0;
|
|
||||||
|
|
||||||
const LEDS_ALL = 'all';
|
const LEDS_ALL = 'all';
|
||||||
|
|
||||||
const MODE_SET = 'set';
|
const MODE_SET = 'set';
|
||||||
|
@ -11,9 +9,9 @@ const MODE_BLINK = 'blink';
|
||||||
const MODE_PULSE = 'pulse';
|
const MODE_PULSE = 'pulse';
|
||||||
const MODE_POWEROFF = 'poweroff';
|
const MODE_POWEROFF = 'poweroff';
|
||||||
|
|
||||||
const LEDS = new Map();
|
const LEDS_ANIMATED = [];
|
||||||
|
const LEDS_STOP = [];
|
||||||
|
|
||||||
let stop = false;
|
|
||||||
|
|
||||||
// find connected blinkstick(s)
|
// find connected blinkstick(s)
|
||||||
async function findBlinkstick(index) {
|
async function findBlinkstick(index) {
|
||||||
|
@ -31,12 +29,12 @@ async function findBlinkstick(index) {
|
||||||
|
|
||||||
// simple animation (set the color / morph to color)
|
// simple animation (set the color / morph to color)
|
||||||
async function simple(config) {
|
async function simple(config) {
|
||||||
await forceStop();
|
await stopLedsAccordingly(config);
|
||||||
config.timestamp = new Date().getTime();
|
config.timestamp = new Date().getTime();
|
||||||
let indices = getIndices(config);
|
let indices = getIndices(config);
|
||||||
for (let index = 0; index < indices.length; index++) {
|
for (let index = 0; index < indices.length; index++) {
|
||||||
try {
|
try {
|
||||||
await setLedState(indices[index], LED_ANIMATED);
|
await setLedAnimated(indices[index]);
|
||||||
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
||||||
} finally {
|
} finally {
|
||||||
await clearLedState(indices[index]);
|
await clearLedState(indices[index]);
|
||||||
|
@ -53,7 +51,7 @@ async function simple(config) {
|
||||||
// complex animation (pulse / blink)
|
// complex animation (pulse / blink)
|
||||||
async function complex(config) {
|
async function complex(config) {
|
||||||
if (config.timestamp === undefined) {
|
if (config.timestamp === undefined) {
|
||||||
await powerOff({id: Math.random(), mode: MODE_POWEROFF, color: '#000000', options: {index: LEDS_ALL}});
|
await stopLedsAccordingly(config);
|
||||||
config.timestamp = new Date().getTime();
|
config.timestamp = new Date().getTime();
|
||||||
}
|
}
|
||||||
let indices = getIndices(config);
|
let indices = getIndices(config);
|
||||||
|
@ -62,7 +60,7 @@ async function complex(config) {
|
||||||
if (shouldLedFinish(config)) {
|
if (shouldLedFinish(config)) {
|
||||||
return {status: 'ok', time: (new Date().getTime() - config.timestamp) + 'ms'};
|
return {status: 'ok', time: (new Date().getTime() - config.timestamp) + 'ms'};
|
||||||
}
|
}
|
||||||
await setLedState(indices[index], LED_ANIMATED);
|
await setLedAnimated(indices[index]);
|
||||||
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
||||||
config.repetitions.done++;
|
config.repetitions.done++;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -74,9 +72,9 @@ async function complex(config) {
|
||||||
|
|
||||||
// power the blinkstick (or just a specific led) off
|
// power the blinkstick (or just a specific led) off
|
||||||
async function powerOff(config) {
|
async function powerOff(config) {
|
||||||
await forceStop();
|
|
||||||
config.timestamp = new Date().getTime();
|
config.timestamp = new Date().getTime();
|
||||||
let indices = getIndices(config);
|
let indices = getIndices(config);
|
||||||
|
await forceStop(indices);
|
||||||
for (let index = 0; index < indices.length; index++) {
|
for (let index = 0; index < indices.length; index++) {
|
||||||
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
await singleAnimation(JSON.parse(JSON.stringify(config)), indices[index]);
|
||||||
logger.info('led \'' + indices[index] + '\' powered off');
|
logger.info('led \'' + indices[index] + '\' powered off');
|
||||||
|
@ -121,22 +119,28 @@ async function singleAnimation(config, index) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function stopLedsAccordingly(config) {
|
||||||
|
if (config.options.index === LEDS_ALL) {
|
||||||
|
return await powerOff({id: Math.random(), mode: MODE_POWEROFF, color: '#000000', options: {index: LEDS_ALL}});
|
||||||
|
}
|
||||||
|
return stopLedAnimation(config.options.index);
|
||||||
|
}
|
||||||
|
|
||||||
async function forceStop() {
|
async function forceStop() {
|
||||||
return new Promise((resolve, reject) => {
|
LEDS_STOP.push(LEDS_ALL);
|
||||||
stop = true;
|
return await new Promise((resolve, reject) => {
|
||||||
waitForAllAnimationsEnd(() => {
|
waitForAllAnimationsEnd(() => {
|
||||||
stop = false;
|
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldLedFinish(config) {
|
function shouldLedFinish(config) {
|
||||||
if (stop) {
|
if (isLedStopping(config.options.index)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (config.mode === MODE_BLINK && config.mode === MODE_PULSE) {
|
if (config.mode === MODE_BLINK || config.mode === MODE_PULSE) {
|
||||||
return config.repetitions.max !== 0 && config.repetitions.done >= config.repetitions.max
|
return config.repetitions.max !== 0 && config.repetitions.done >= config.repetitions.max;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -149,23 +153,41 @@ function getIndices(blinkstickConfig) {
|
||||||
return [blinkstickConfig.options.index];
|
return [blinkstickConfig.options.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setLedState(index, state) {
|
function setLedAnimated(index) {
|
||||||
await stopLedAnimation(index);
|
if (isLedAnimated(index)) {
|
||||||
LEDS.set(index, state);
|
return;
|
||||||
|
}
|
||||||
|
LEDS_ANIMATED.push(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLedStopping(index) {
|
||||||
|
if (!isLedAnimated(index) || isLedStopping(index)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LEDS_STOP.push(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearLedState(index) {
|
function clearLedState(index) {
|
||||||
return new Promise((resolve, reject) => {
|
if (index === LEDS_ALL) {
|
||||||
LEDS.delete(index);
|
LEDS_ANIMATED.length = 0;
|
||||||
resolve();
|
return;
|
||||||
});
|
}
|
||||||
|
LEDS_ANIMATED.splice(LEDS_ANIMATED.indexOf(index), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLedAnimated(index) {
|
function isLedAnimated(index) {
|
||||||
return (LEDS.get(index) || LEDS.get(LEDS_ALL)) !== undefined;
|
return LEDS_ANIMATED.includes(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLedStopping(index) {
|
||||||
|
if (LEDS_STOP.includes(LEDS_ALL)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return LEDS_STOP.includes(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopLedAnimation(index) {
|
function stopLedAnimation(index) {
|
||||||
|
setLedStopping(index);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
waitForAnimationEnd(index, () => {
|
waitForAnimationEnd(index, () => {
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -175,6 +197,7 @@ function stopLedAnimation(index) {
|
||||||
|
|
||||||
function waitForAnimationEnd(index, callback) {
|
function waitForAnimationEnd(index, callback) {
|
||||||
if (!isLedAnimated(index)) {
|
if (!isLedAnimated(index)) {
|
||||||
|
LEDS_STOP.splice(LEDS_STOP.indexOf(index), 1);
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -183,7 +206,8 @@ function waitForAnimationEnd(index, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForAllAnimationsEnd(callback) {
|
function waitForAllAnimationsEnd(callback) {
|
||||||
if (LEDS.size === 0) {
|
if (LEDS_ANIMATED.length === 0) {
|
||||||
|
LEDS_STOP.length = 0;
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -37,15 +37,15 @@ function parseRequest(requestBody, mode) {
|
||||||
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
|
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
|
||||||
break;
|
break;
|
||||||
case MODE_BLINK:
|
case MODE_BLINK:
|
||||||
config.options.repeats = parseRepeats(requestBody.repeats, config.options.index);
|
config.options.repeats = 1;
|
||||||
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
||||||
config.options.delay = parseDelay(requestBody.delay);
|
config.options.delay = parseDelay(requestBody.delay);
|
||||||
break;
|
break;
|
||||||
case MODE_PULSE:
|
case MODE_PULSE:
|
||||||
|
config.options.repeats = 1;
|
||||||
|
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
||||||
config.options.duration = parseDuration(requestBody.duration, config.options.index, MODE_PULSE);
|
config.options.duration = parseDuration(requestBody.duration, config.options.index, MODE_PULSE);
|
||||||
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
|
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
|
||||||
config.options.repeats = parseRepeats(requestBody.repeats, config.options.index);
|
|
||||||
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
|
@ -93,23 +93,8 @@ function parseSteps(steps, duration) {
|
||||||
return steps;
|
return steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the repeats
|
|
||||||
function parseRepeats(repeats, index) {
|
|
||||||
if (index === LEDS_ALL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
repeats = parseInt(repeats);
|
|
||||||
if (repeats !== repeats) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return repeats;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the repetitions
|
// parse the repetitions
|
||||||
function parseRepetitions(repeats, index) {
|
function parseRepetitions(repeats, index) {
|
||||||
if (index !== LEDS_ALL) {
|
|
||||||
return {done: 0, max: 1};
|
|
||||||
}
|
|
||||||
repeats = parseInt(repeats);
|
repeats = parseInt(repeats);
|
||||||
if (repeats !== repeats) {
|
if (repeats !== repeats) {
|
||||||
repeats = 0;
|
repeats = 0;
|
||||||
|
|
Loading…
Reference in a new issue