diff --git a/data/pixelConfig.json b/data/pixelConfig.json
index 788cf46..4a0d066 100644
--- a/data/pixelConfig.json
+++ b/data/pixelConfig.json
@@ -1,7 +1,7 @@
{
"pin": 4,
- "length": 60,
+ "length": 300,
"brightness": 64,
- "updateInterval": 150,
+ "updateInterval": 50,
"defaultColor": 100
}
\ No newline at end of file
diff --git a/data/www/index.html b/data/www/index.html
index b513d70..508a322 100644
--- a/data/www/index.html
+++ b/data/www/index.html
@@ -39,7 +39,7 @@
data-name="pattern"
data-topic="pixels/pattern"
data-default="0"
- data-entries='[{"text": "None", "value": "0"}, {"text": "Rainbow", "value": "1"}, {"text": "TheaterChase", "value": "2"}, {"text": "Fade", "value": "5"}]'
+ data-entries='[{"text": "None", "value": "0"}, {"text": "Rainbow", "value": "1"}, {"text": "TheaterChase", "value": "2"}, {"text": "Color Wipe", "value": "3"}, {"text": "Scanner", "value": "4"}, {"text": "Fade", "value": "5"}]'
>
diff --git a/data/www/script.js b/data/www/script.js
index 306c910..424603a 100644
--- a/data/www/script.js
+++ b/data/www/script.js
@@ -10798,17 +10798,17 @@ __WEBPACK_IMPORTED_MODULE_0_jquery___default()(() => {
let colors = payload.split(',');
let msg = JSON.stringify({
topic: 'pixels/state',
- broadcast: "1",
+ broadcast: 1,
payload: JSON.stringify({
- brightness: 64,
+ //brightness: 64,
color: parseInt(colors[0].replace('#', '0x'), 16),
color2: parseInt(colors[1].replace('#', '0x'), 16),
- totalSteps: 128,
+ //totalSteps: 64,
pattern: 5
})
});
- app.mediator.trigger('pixels/brightness', 64);
- app.mediator.trigger('pixels/totalSteps', 128);
+ //app.mediator.trigger('pixels/brightness', 64);
+ //app.mediator.trigger('pixels/totalSteps', 64);
app.mediator.trigger('pixels/pattern', 5);
app.mediator.trigger('pixels/color', colors[0]);
app.mediator.trigger('pixels/color2', colors[1]);
diff --git a/data/www/test-controls.html b/data/www/test-controls.html
new file mode 100644
index 0000000..974e650
--- /dev/null
+++ b/data/www/test-controls.html
@@ -0,0 +1,106 @@
+
+
+
+
+ ESP Kit
+
+
+
+
+
+
+
+
+
+
+
+
+
WiFi Settings
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/NeoPattern/NeoPattern.cpp b/lib/NeoPattern/NeoPattern.cpp
index 478fe72..8d54c0a 100644
--- a/lib/NeoPattern/NeoPattern.cpp
+++ b/lib/NeoPattern/NeoPattern.cpp
@@ -1,3 +1,15 @@
+/**
+ * Original NeoPattern code by Bill Earl
+ * https://learn.adafruit.com/multi-tasking-the-arduino-part-3/overview
+ *
+ * TODO
+ * - cleanup the mess
+ * - fnc table for patterns to replace switch case
+ *
+ * Custom modifications by 0x1d:
+ * - default OnComplete callback that sets pattern to reverse
+ * - separate animation update from timer; Update now updates directly, UpdateScheduled uses timer
+ */
#ifndef __NeoPattern_INCLUDED__
#define __NeoPattern_INCLUDED__
@@ -5,94 +17,122 @@
using namespace std;
using namespace std::placeholders;
-
-/**
- * Original NeoPattern code by Bill Earl
- * https://learn.adafruit.com/multi-tasking-the-arduino-part-3/overview
- *
- * Custom modifications by 0x1d:
- * - default OnComplete callback that sets pattern to reverse
- * - separate animation update from timer; Update now updates directly, UpdateScheduled uses timer
- */
// Pattern types supported:
-enum pattern { NONE = 0, RAINBOW_CYCLE = 1, THEATER_CHASE = 2, COLOR_WIPE = 3, SCANNER = 4, FADE = 5 };
+enum pattern
+{
+ NONE = 0,
+ RAINBOW_CYCLE = 1,
+ THEATER_CHASE = 2,
+ COLOR_WIPE = 3,
+ SCANNER = 4,
+ FADE = 5
+};
// Patern directions supported:
-enum direction { FORWARD, REVERSE };
-
+enum direction
+{
+ FORWARD,
+ REVERSE
+};
+
// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPattern : public Adafruit_NeoPixel
{
- public:
-
- // Member Variables:
- pattern ActivePattern = RAINBOW_CYCLE; // which pattern is running
- direction Direction = FORWARD; // direction to run the pattern
-
- unsigned long Interval = 150; // milliseconds between updates
+ public:
+ // Member Variables:
+ pattern ActivePattern = RAINBOW_CYCLE; // which pattern is running
+ direction Direction = FORWARD; // direction to run the pattern
+
+ unsigned long Interval = 150; // milliseconds between updates
unsigned long lastUpdate = 0; // last update of position
-
+
uint32_t Color1 = 0;
- uint32_t Color2 = 0; // What colors are in use
- uint16_t TotalSteps = 32; // total number of steps in the pattern
- uint16_t Index; // current step within the pattern
+ uint32_t Color2 = 0; // What colors are in use
+ uint16_t TotalSteps = 32; // total number of steps in the pattern
+ uint16_t Index; // current step within the pattern
uint16_t completed = 0;
- void (*OnComplete)(int); // Callback on completion of pattern
-
+ // FIXME return current NeoPatternState
+ void (*OnComplete)(int); // Callback on completion of pattern
+
+ uint8_t *frameBuffer;
+ int bufferSize = 0;
+
// Constructor - calls base-class constructor to initialize strip
NeoPattern(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)(int))
- :Adafruit_NeoPixel(pixels, pin, type)
+ : Adafruit_NeoPixel(pixels, pin, type)
{
+ frameBuffer = (uint8_t*)malloc(768);
OnComplete = callback;
TotalSteps = numPixels();
}
NeoPattern(uint16_t pixels, uint8_t pin, uint8_t type)
- :Adafruit_NeoPixel(pixels, pin, type)
+ : Adafruit_NeoPixel(pixels, pin, type)
{
- //OnComplete = bind(&NeoPattern::onCompleteDefault, this, _1);
+ frameBuffer = (uint8_t*)malloc(768);
TotalSteps = numPixels();
}
- void onCompleteDefault(int pixels) {
- //Serial.println("onCompleteDefault");
- // FIXME no specific code
- if(ActivePattern == THEATER_CHASE){
+ void handleStream(uint8_t *data, size_t len)
+ {
+ //const uint16_t *data16 = (uint16_t *)data;
+ bufferSize = len;
+ memcpy(frameBuffer, data, len);
+ }
+
+ void drawFrameBuffer(int w, uint8_t *frame, int length){
+ for (int i = 0; i < length; i++){
+ uint8_t r = frame[i];
+ uint8_t g = frame[++i];
+ uint8_t b = frame[++i];
+ setPixelColor(i, r ,g, b);
+ }
+ }
+
+ void onCompleteDefault(int pixels)
+ {
+ //Serial.println("onCompleteDefault");
+ // FIXME no specific code
+ if (ActivePattern == THEATER_CHASE)
+ {
return;
}
Reverse();
//Serial.println("pattern completed");
}
-
+
// Update the pattern
void Update()
{
- switch(ActivePattern)
+ switch (ActivePattern)
{
- case RAINBOW_CYCLE:
- RainbowCycleUpdate();
- break;
- case THEATER_CHASE:
- TheaterChaseUpdate();
- break;
- case COLOR_WIPE:
- ColorWipeUpdate();
- break;
- case SCANNER:
- ScannerUpdate();
- break;
- case FADE:
- FadeUpdate();
- break;
- default:
- break;
+ case RAINBOW_CYCLE:
+ RainbowCycleUpdate();
+ break;
+ case THEATER_CHASE:
+ TheaterChaseUpdate();
+ break;
+ case COLOR_WIPE:
+ ColorWipeUpdate();
+ break;
+ case SCANNER:
+ ScannerUpdate();
+ break;
+ case FADE:
+ FadeUpdate();
+ break;
+ default:
+ if(bufferSize > 0){
+ drawFrameBuffer(TotalSteps, frameBuffer, bufferSize);
+ }
+ break;
}
}
-
+
void UpdateScheduled()
{
- if((millis() - lastUpdate) > Interval) // time to update
+ if ((millis() - lastUpdate) > Interval) // time to update
{
lastUpdate = millis();
Update();
@@ -105,15 +145,17 @@ class NeoPattern : public Adafruit_NeoPixel
completed = 0;
if (Direction == FORWARD)
{
- Index++;
- if (Index >= TotalSteps)
+ Index++;
+ if (Index >= TotalSteps)
{
Index = 0;
completed = 1;
if (OnComplete != NULL)
{
OnComplete(numPixels()); // call the comlpetion callback
- } else {
+ }
+ else
+ {
onCompleteDefault(numPixels());
}
}
@@ -123,25 +165,27 @@ class NeoPattern : public Adafruit_NeoPixel
--Index;
if (Index <= 0)
{
- Index = TotalSteps-1;
+ Index = TotalSteps - 1;
completed = 1;
if (OnComplete != NULL)
{
OnComplete(numPixels()); // call the comlpetion callback
- } else {
+ }
+ else
+ {
onCompleteDefault(numPixels());
}
}
}
}
-
+
// Reverse pattern direction
void Reverse()
{
if (Direction == FORWARD)
{
Direction = REVERSE;
- Index = TotalSteps-1;
+ Index = TotalSteps - 1;
}
else
{
@@ -149,7 +193,7 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0;
}
}
-
+
// Initialize for a RainbowCycle
void RainbowCycle(uint8_t interval, direction dir = FORWARD)
{
@@ -159,18 +203,18 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0;
Direction = dir;
}
-
+
// Update the Rainbow Cycle Pattern
void RainbowCycleUpdate()
{
- for(int i=0; i< numPixels(); i++)
+ for (int i = 0; i < numPixels(); i++)
{
setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
}
show();
Increment();
}
-
+
// Initialize for a Theater Chase
void TheaterChase(uint32_t color1, uint32_t color2, uint16_t interval, direction dir = FORWARD)
{
@@ -181,12 +225,12 @@ class NeoPattern : public Adafruit_NeoPixel
Color2 = color2;
Index = 0;
Direction = dir;
- }
-
+ }
+
// Update the Theater Chase Pattern
void TheaterChaseUpdate()
{
- for(int i=0; i< numPixels(); i++)
+ for (int i = 0; i < numPixels(); i++)
{
if ((i + Index) % 3 == 0)
{
@@ -200,7 +244,7 @@ class NeoPattern : public Adafruit_NeoPixel
show();
Increment();
}
-
+
// Initialize for a ColorWipe
void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
{
@@ -211,7 +255,7 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0;
Direction = dir;
}
-
+
// Update the Color Wipe Pattern
void ColorWipeUpdate()
{
@@ -219,7 +263,7 @@ class NeoPattern : public Adafruit_NeoPixel
show();
Increment();
}
-
+
// Initialize for a SCANNNER
void Scanner(uint32_t color1, uint8_t interval)
{
@@ -229,29 +273,29 @@ class NeoPattern : public Adafruit_NeoPixel
Color1 = color1;
Index = 0;
}
-
+
// Update the Scanner Pattern
void ScannerUpdate()
- {
+ {
for (int i = 0; i < numPixels(); i++)
{
- if (i == Index) // Scan Pixel to the right
+ if (i == Index) // Scan Pixel to the right
{
- setPixelColor(i, Color1);
+ setPixelColor(i, Color1);
}
else if (i == TotalSteps - Index) // Scan Pixel to the left
{
- setPixelColor(i, Color1);
+ setPixelColor(i, Color1);
}
else // Fading tail
{
- setPixelColor(i, DimColor(getPixelColor(i)));
+ setPixelColor(i, DimColor(getPixelColor(i)));
}
}
show();
Increment();
}
-
+
// Initialize for a Fade
void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
{
@@ -263,7 +307,7 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0;
Direction = dir;
}
-
+
// Update the Fade Pattern
void FadeUpdate()
{
@@ -272,12 +316,12 @@ class NeoPattern : public Adafruit_NeoPixel
uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;
-
+
ColorSet(Color(red, green, blue));
show();
Increment();
}
-
+
// Calculate 50% dimmed version of a color (used by ScannerUpdate)
uint32_t DimColor(uint32_t color)
{
@@ -285,7 +329,7 @@ class NeoPattern : public Adafruit_NeoPixel
uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
return dimColor;
}
-
+
// Set all pixels to a color (synchronously)
void ColorSet(uint32_t color)
{
@@ -295,36 +339,36 @@ class NeoPattern : public Adafruit_NeoPixel
}
show();
}
-
+
// Returns the Red component of a 32-bit color
uint8_t Red(uint32_t color)
{
return (color >> 16) & 0xFF;
}
-
+
// Returns the Green component of a 32-bit color
uint8_t Green(uint32_t color)
{
return (color >> 8) & 0xFF;
}
-
+
// Returns the Blue component of a 32-bit color
uint8_t Blue(uint32_t color)
{
return color & 0xFF;
}
-
+
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos)
{
//if(WheelPos == 0) return Color(0,0,0);
WheelPos = 255 - WheelPos;
- if(WheelPos < 85)
+ if (WheelPos < 85)
{
return Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
- else if(WheelPos < 170)
+ else if (WheelPos < 170)
{
WheelPos -= 85;
return Color(0, WheelPos * 3, 255 - WheelPos * 3);
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..d2b053d
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,41 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "color-string": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+ "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+ "requires": {
+ "color-name": "1.1.4",
+ "simple-swizzle": "0.2.2"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ },
+ "neopixel-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/neopixel-utils/-/neopixel-utils-1.0.2.tgz",
+ "integrity": "sha1-e2IJvR3kmEaRu5nR46iv+8h1Zh4=",
+ "requires": {
+ "color-string": "1.5.3"
+ }
+ },
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "requires": {
+ "is-arrayish": "0.3.2"
+ }
+ }
+ }
+}
diff --git a/platformio.ini b/platformio.ini
index 13300eb..d08fb07 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -50,4 +50,16 @@ framework = ${common.framework}
build_flags = -Wl,-Teagle.flash.4m1m.ld
-DSPROCKET_PRINT=0
lib_deps = ${common.lib_deps}
- https://gitlab.com/wirelos/sprocket-core.git#master
\ No newline at end of file
+ https://gitlab.com/wirelos/sprocket-core.git#master
+
+
+[env:nodemcu]
+platform = ${common.platform}
+board = nodemcu
+upload_speed = ${common.upload_speed}
+monitor_baud = ${common.monitor_baud}
+framework = ${common.framework}
+build_flags = -Wl,-Teagle.flash.4m1m.ld
+ -DSPROCKET_PRINT=1
+lib_deps = ${common.lib_deps}
+ https://gitlab.com/wirelos/sprocket-core.git#develop
\ No newline at end of file
diff --git a/src/IlluCat.h b/src/IlluCat.h
index 654c6ab..e34e4f8 100644
--- a/src/IlluCat.h
+++ b/src/IlluCat.h
@@ -28,6 +28,7 @@ class IlluCat : public MeshSprocket {
NeoPatternDto state;
AsyncWebServer* server;
AsyncWebSocket* ws;
+ AsyncWebSocket* wsStream;
NeoPixelConfig pixelConfig;
SprocketConfig sprocketConfig;
@@ -72,6 +73,7 @@ class IlluCat : public MeshSprocket {
pixels = new NeoPattern(pixelConfig.length, pixelConfig.pin, NEO_GRB + NEO_KHZ800);
server = new AsyncWebServer(80);
ws = new AsyncWebSocket("/pixel");
+ wsStream = new AsyncWebSocket("/stream");
// add plugins
addPlugin(new OtaTcpPlugin(otaConfig));
@@ -89,6 +91,8 @@ class IlluCat : public MeshSprocket {
server->on("/pixel/api", HTTP_POST, bind(&IlluCat::patternWebRequestHandler, this, _1));
ws->onEvent(bind(&IlluCat::onWsEvent, this, _1, _2, _3, _4, _5, _6));
server->addHandler(ws);
+ wsStream->onEvent(bind(&IlluCat::onStream, this, _1, _2, _3, _4, _5, _6));
+ server->addHandler(wsStream);
return MeshSprocket::activate(scheduler, network);
} using MeshSprocket::activate;
@@ -101,6 +105,15 @@ class IlluCat : public MeshSprocket {
return defaultValue;
}
+
+ void onStream(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
+ if(type == WS_EVT_DATA){
+ PRINT_MSG(Serial, SPROCKET_TYPE, WsUtils::parseFrameAsString(type, arg, data, len, 0).c_str());
+ pixels->ActivePattern = NONE;
+ pixels->handleStream(data, len);
+ }
+ }
+
void patternWebRequestHandler(AsyncWebServerRequest *request) {
PRINT_MSG(Serial, SPROCKET_TYPE, "POST /pixel/api");
currentMessage.topic = getRequestParameterOrDefault(request, "topic", "");
diff --git a/src/PixelPlugin.h b/src/PixelPlugin.h
index e2baecf..ae9f331 100644
--- a/src/PixelPlugin.h
+++ b/src/PixelPlugin.h
@@ -25,6 +25,7 @@ class PixelPlugin : public Plugin {
pixels = neoPattern;
pixels->begin();
pixels->setBrightness(pixelConfig.brightness);
+
}
void activate(Scheduler* userScheduler, Network* network){
subscribe("pixels/colorWheel", bind(&PixelPlugin::colorWheel, this, _1));
@@ -34,16 +35,13 @@ class PixelPlugin : public Plugin {
subscribe("pixels/totalSteps", bind(&PixelPlugin::setTotalSteps, this, _1));
subscribe("pixels/brightness", bind(&PixelPlugin::setBrightness, this, _1));
subscribe("pixels/state", bind(&PixelPlugin::setState, this, _1));
- subscribe("pixels/stream", bind(&PixelPlugin::stream, this, _1));
animation.set(TASK_MILLISECOND * pixelConfig.updateInterval, TASK_FOREVER, bind(&PixelPlugin::animate, this));
userScheduler->addTask(animation);
animation.enable();
PRINT_MSG(Serial, SPROCKET_TYPE, "NeoPixels activated");
}
- void stream(String msg){
- // TODO handle LED byte array stream
- }
+
void setState(String msg) {
PRINT_MSG(Serial, SPROCKET_TYPE, msg.c_str());
state.fromJsonString(msg);
diff --git a/test/.gitignore b/test/.gitignore
index c2658d7..40b878d 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -1 +1 @@
-node_modules/
+node_modules/
\ No newline at end of file
diff --git a/test/package-lock.json b/test/package-lock.json
index 8d15fc7..79a6ad8 100644
--- a/test/package-lock.json
+++ b/test/package-lock.json
@@ -7,11 +7,56 @@
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
},
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "color-string": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+ "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.4",
+ "simple-swizzle": "0.2.2"
+ }
+ },
"coolhue": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/coolhue/-/coolhue-1.0.9.tgz",
"integrity": "sha512-4+ctEja6XNJ8GrV+OLbioHWssC8tT/IUSZlS6i/RXc0R+ef7g6jNGmLC4VwhEKCJXTKPQ0FqbwojYLDtpPXs1w=="
},
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "dev": true
+ },
+ "neopixel-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/neopixel-utils/-/neopixel-utils-1.0.2.tgz",
+ "integrity": "sha1-e2IJvR3kmEaRu5nR46iv+8h1Zh4=",
+ "dev": true,
+ "requires": {
+ "color-string": "1.5.3"
+ }
+ },
+ "ramda": {
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz",
+ "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ=="
+ },
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "0.3.2"
+ }
+ },
"ws": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz",
diff --git a/test/stream.js b/test/stream.js
new file mode 100644
index 0000000..3c0e626
--- /dev/null
+++ b/test/stream.js
@@ -0,0 +1,52 @@
+const WebSocket = require('ws');
+const { times, min, max } = require('ramda');
+const cmdWs = new WebSocket('ws://192.168.1.247/stream');
+const {Strip} = require('neopixel-utils');
+
+const randomColor = () => Math.floor(Math.random() * 255);
+
+let strip = Strip(8);
+//strip.setPixelColor(0, [randomColor(), randomColor(), randomColor()]);
+//console.log(strip.getPixelColor(0));
+
+/* const color = (r, g, b) => {
+ return uint16_t((r & 0xF8) << 8)
+ | uint16_t((g & 0xFC) << 3)
+ | uint16_t(b >> 3);
+} */
+
+/* const color = (r, g, b) => {
+ return ((r & 0xF8) << 8)
+ | ((g & 0xFC) << 3)
+ | (b >> 3);
+}
+
+const createTest = (ws, items) => () => {
+ console.log(`Items: ${items}`)
+ let array = new Uint16Array(items);
+ times(index => {
+ const r = index === 0 ? 255 : Math.floor(Math.random() * 255)
+ const g = index === 0 ? 0 : Math.floor(Math.random() * 255)
+ const b = index === 0 ? 255 : Math.floor(Math.random() * 255)
+ const number = color(r, g, b)
+ console.log(`R: ${r} G: ${g} B: ${b}`)
+ //const number = Math.floor(Math.random() * 65535);
+ array[index] = number
+ console.log(number)
+ }
+ , items);
+ ws.send(array);
+}
+ */
+
+const createTest = (ws, items) => () => {
+ console.log(`Items: ${items}`)
+ times(index => {
+ strip.setPixelColor(index, [randomColor(), randomColor(), randomColor()]);
+ } , items);
+ console.log(strip.buffer);
+ ws.send(strip.buffer);
+}
+
+cmdWs.on('message', console.log);
+cmdWs.on('open', createTest(cmdWs, 5));
\ No newline at end of file