add streaming stuff

This commit is contained in:
2018-10-03 13:32:23 +02:00
parent dff8545d65
commit 9c6ec9b231
12 changed files with 413 additions and 102 deletions

View File

@@ -1,7 +1,7 @@
{ {
"pin": 4, "pin": 4,
"length": 60, "length": 300,
"brightness": 64, "brightness": 64,
"updateInterval": 150, "updateInterval": 50,
"defaultColor": 100 "defaultColor": 100
} }

View File

@@ -39,7 +39,7 @@
data-name="pattern" data-name="pattern"
data-topic="pixels/pattern" data-topic="pixels/pattern"
data-default="0" 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"}]'
></li> ></li>
<li class="form-row ParamSlider" <li class="form-row ParamSlider"
data-name="brightness" data-name="brightness"
@@ -53,7 +53,7 @@
data-name="totalSteps" data-name="totalSteps"
data-min="1" data-min="1"
data-max="255" data-max="255"
data-value="255" data-value="16"
data-topic="pixels/totalSteps" data-topic="pixels/totalSteps"
data-label="Steps"> data-label="Steps">
</li> </li>

View File

@@ -10798,17 +10798,17 @@ __WEBPACK_IMPORTED_MODULE_0_jquery___default()(() => {
let colors = payload.split(','); let colors = payload.split(',');
let msg = JSON.stringify({ let msg = JSON.stringify({
topic: 'pixels/state', topic: 'pixels/state',
broadcast: "1", broadcast: 1,
payload: JSON.stringify({ payload: JSON.stringify({
brightness: 64, //brightness: 64,
color: parseInt(colors[0].replace('#', '0x'), 16), color: parseInt(colors[0].replace('#', '0x'), 16),
color2: parseInt(colors[1].replace('#', '0x'), 16), color2: parseInt(colors[1].replace('#', '0x'), 16),
totalSteps: 128, //totalSteps: 64,
pattern: 5 pattern: 5
}) })
}); });
app.mediator.trigger('pixels/brightness', 64); //app.mediator.trigger('pixels/brightness', 64);
app.mediator.trigger('pixels/totalSteps', 128); //app.mediator.trigger('pixels/totalSteps', 64);
app.mediator.trigger('pixels/pattern', 5); app.mediator.trigger('pixels/pattern', 5);
app.mediator.trigger('pixels/color', colors[0]); app.mediator.trigger('pixels/color', colors[0]);
app.mediator.trigger('pixels/color2', colors[1]); app.mediator.trigger('pixels/color2', colors[1]);

106
data/www/test-controls.html Normal file
View File

@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html>
<head>
<title>ESP Kit</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-32x32.png">
<link rel="stylesheet" type="text/css" href="styles.css">
<script src="script.js"></script>
</head>
<body class="sui">
<div class="content">
<!-- <form class="param-control container open collapsible">
<span class="heading">Debug</span>
<div class="content">
<ul>
<li class="form-row ParamWs"
data-name="scrollText"
data-label="Audio"
data-placeholder="some scroll text"
data-endpoint="audiosprocket.lan/audio">
</li>
</ul>
<br>
</div>
</form> -->
<form class="param-control container collapsible open" action="#" method="POST">
<span class="heading">Strip</span>
<div class="content">
<ul>
<li class="form-row ParamColor"
data-mode="2"
data-name="color"
data-label="Color">
</li>
<li class="form-row ParamColor"
data-mode="2"
data-name="color2"
data-label="Color 2">
</li>
<li class="form-row ParamSelect"
data-label="Pattern"
data-name="pattern"
></li>
<li class="form-row LedStripPatternSwitch"
data-group="stripPattern"
data-id="1"
data-mode="3"
data-name="Rainbow"
data-label="Rainbow">
</li>
<li class="form-row LedStripPatternSwitch"
data-group="stripPattern"
data-name="TheaterChase"
data-label="Theater Chase"
data-id="2"
data-mode="3">
</li>
<li class="form-row LedStripPatternSwitch"
data-group="stripPattern"
data-name="Scanner"
data-label="Scanner"
data-id="4"
data-mode="3">
</li>
</ul>
</div>
</form>
<div class="settings container collapsible open">
<span class="heading">WiFi Settings</span>
<div class="content">
<!-- <div class="Form" data-name="configForm" data-endpoint="/config.json"></div> -->
<form action="/wifiConfig" method="POST">
<!-- <li class="form-row">
<label for="ap">AP Mode</label>
<label class="switch ap-mode">
<input type="checkbox" name="apMode">
<span class="slider round" data-bind="apMode" data-state="false"></span>
</label>
</li -->
<li class="form-row">
<label for="ssid">SSID</label>
<input type="text" name="ssid" placeholder="Default AP: Th1ngs4P">
</li>
<li class="form-row">
<label for="password">PW</label>
<input type="password" name="password" placeholder="Default: th3r31sn0sp00n">
</li>
<li class="form-row">
<label for="hostName">Hostname</label>
<input type="text" name="hostName" placeholder="Default: 192.168.1.143">
</li>
<li class="form-row">
<button type="submit">Save</button>
</li>
</ul>
</form>
</div>
</div>
</div>
</body>
</html>

View File

@@ -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__ #ifndef __NeoPattern_INCLUDED__
#define __NeoPattern_INCLUDED__ #define __NeoPattern_INCLUDED__
@@ -5,94 +17,122 @@
using namespace std; using namespace std;
using namespace std::placeholders; 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: // 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: // Patern directions supported:
enum direction { FORWARD, REVERSE }; enum direction
{
FORWARD,
REVERSE
};
// NeoPattern Class - derived from the Adafruit_NeoPixel class // NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPattern : public Adafruit_NeoPixel class NeoPattern : public Adafruit_NeoPixel
{ {
public: public:
// Member Variables:
// Member Variables: pattern ActivePattern = RAINBOW_CYCLE; // which pattern is running
pattern ActivePattern = RAINBOW_CYCLE; // which pattern is running direction Direction = FORWARD; // direction to run the pattern
direction Direction = FORWARD; // direction to run the pattern
unsigned long Interval = 150; // milliseconds between updates
unsigned long Interval = 150; // milliseconds between updates
unsigned long lastUpdate = 0; // last update of position unsigned long lastUpdate = 0; // last update of position
uint32_t Color1 = 0; uint32_t Color1 = 0;
uint32_t Color2 = 0; // What colors are in use uint32_t Color2 = 0; // What colors are in use
uint16_t TotalSteps = 32; // total number of steps in the pattern uint16_t TotalSteps = 32; // total number of steps in the pattern
uint16_t Index; // current step within the pattern uint16_t Index; // current step within the pattern
uint16_t completed = 0; 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 // Constructor - calls base-class constructor to initialize strip
NeoPattern(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)(int)) 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; OnComplete = callback;
TotalSteps = numPixels(); TotalSteps = numPixels();
} }
NeoPattern(uint16_t pixels, uint8_t pin, uint8_t type) 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(); TotalSteps = numPixels();
} }
void onCompleteDefault(int pixels) { void handleStream(uint8_t *data, size_t len)
//Serial.println("onCompleteDefault"); {
// FIXME no specific code //const uint16_t *data16 = (uint16_t *)data;
if(ActivePattern == THEATER_CHASE){ 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; return;
} }
Reverse(); Reverse();
//Serial.println("pattern completed"); //Serial.println("pattern completed");
} }
// Update the pattern // Update the pattern
void Update() void Update()
{ {
switch(ActivePattern) switch (ActivePattern)
{ {
case RAINBOW_CYCLE: case RAINBOW_CYCLE:
RainbowCycleUpdate(); RainbowCycleUpdate();
break; break;
case THEATER_CHASE: case THEATER_CHASE:
TheaterChaseUpdate(); TheaterChaseUpdate();
break; break;
case COLOR_WIPE: case COLOR_WIPE:
ColorWipeUpdate(); ColorWipeUpdate();
break; break;
case SCANNER: case SCANNER:
ScannerUpdate(); ScannerUpdate();
break; break;
case FADE: case FADE:
FadeUpdate(); FadeUpdate();
break; break;
default: default:
break; if(bufferSize > 0){
drawFrameBuffer(TotalSteps, frameBuffer, bufferSize);
}
break;
} }
} }
void UpdateScheduled() void UpdateScheduled()
{ {
if((millis() - lastUpdate) > Interval) // time to update if ((millis() - lastUpdate) > Interval) // time to update
{ {
lastUpdate = millis(); lastUpdate = millis();
Update(); Update();
@@ -105,15 +145,17 @@ class NeoPattern : public Adafruit_NeoPixel
completed = 0; completed = 0;
if (Direction == FORWARD) if (Direction == FORWARD)
{ {
Index++; Index++;
if (Index >= TotalSteps) if (Index >= TotalSteps)
{ {
Index = 0; Index = 0;
completed = 1; completed = 1;
if (OnComplete != NULL) if (OnComplete != NULL)
{ {
OnComplete(numPixels()); // call the comlpetion callback OnComplete(numPixels()); // call the comlpetion callback
} else { }
else
{
onCompleteDefault(numPixels()); onCompleteDefault(numPixels());
} }
} }
@@ -123,25 +165,27 @@ class NeoPattern : public Adafruit_NeoPixel
--Index; --Index;
if (Index <= 0) if (Index <= 0)
{ {
Index = TotalSteps-1; Index = TotalSteps - 1;
completed = 1; completed = 1;
if (OnComplete != NULL) if (OnComplete != NULL)
{ {
OnComplete(numPixels()); // call the comlpetion callback OnComplete(numPixels()); // call the comlpetion callback
} else { }
else
{
onCompleteDefault(numPixels()); onCompleteDefault(numPixels());
} }
} }
} }
} }
// Reverse pattern direction // Reverse pattern direction
void Reverse() void Reverse()
{ {
if (Direction == FORWARD) if (Direction == FORWARD)
{ {
Direction = REVERSE; Direction = REVERSE;
Index = TotalSteps-1; Index = TotalSteps - 1;
} }
else else
{ {
@@ -149,7 +193,7 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0; Index = 0;
} }
} }
// Initialize for a RainbowCycle // Initialize for a RainbowCycle
void RainbowCycle(uint8_t interval, direction dir = FORWARD) void RainbowCycle(uint8_t interval, direction dir = FORWARD)
{ {
@@ -159,18 +203,18 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0; Index = 0;
Direction = dir; Direction = dir;
} }
// Update the Rainbow Cycle Pattern // Update the Rainbow Cycle Pattern
void RainbowCycleUpdate() void RainbowCycleUpdate()
{ {
for(int i=0; i< numPixels(); i++) for (int i = 0; i < numPixels(); i++)
{ {
setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255)); setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
} }
show(); show();
Increment(); Increment();
} }
// Initialize for a Theater Chase // Initialize for a Theater Chase
void TheaterChase(uint32_t color1, uint32_t color2, uint16_t interval, direction dir = FORWARD) 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; Color2 = color2;
Index = 0; Index = 0;
Direction = dir; Direction = dir;
} }
// Update the Theater Chase Pattern // Update the Theater Chase Pattern
void TheaterChaseUpdate() void TheaterChaseUpdate()
{ {
for(int i=0; i< numPixels(); i++) for (int i = 0; i < numPixels(); i++)
{ {
if ((i + Index) % 3 == 0) if ((i + Index) % 3 == 0)
{ {
@@ -200,7 +244,7 @@ class NeoPattern : public Adafruit_NeoPixel
show(); show();
Increment(); Increment();
} }
// Initialize for a ColorWipe // Initialize for a ColorWipe
void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD) void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
{ {
@@ -211,7 +255,7 @@ class NeoPattern : public Adafruit_NeoPixel
Index = 0; Index = 0;
Direction = dir; Direction = dir;
} }
// Update the Color Wipe Pattern // Update the Color Wipe Pattern
void ColorWipeUpdate() void ColorWipeUpdate()
{ {
@@ -219,7 +263,7 @@ class NeoPattern : public Adafruit_NeoPixel
show(); show();
Increment(); Increment();
} }
// Initialize for a SCANNNER // Initialize for a SCANNNER
void Scanner(uint32_t color1, uint8_t interval) void Scanner(uint32_t color1, uint8_t interval)
{ {
@@ -229,29 +273,29 @@ class NeoPattern : public Adafruit_NeoPixel
Color1 = color1; Color1 = color1;
Index = 0; Index = 0;
} }
// Update the Scanner Pattern // Update the Scanner Pattern
void ScannerUpdate() void ScannerUpdate()
{ {
for (int i = 0; i < numPixels(); i++) 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 else if (i == TotalSteps - Index) // Scan Pixel to the left
{ {
setPixelColor(i, Color1); setPixelColor(i, Color1);
} }
else // Fading tail else // Fading tail
{ {
setPixelColor(i, DimColor(getPixelColor(i))); setPixelColor(i, DimColor(getPixelColor(i)));
} }
} }
show(); show();
Increment(); Increment();
} }
// Initialize for a Fade // Initialize for a Fade
void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD) 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; Index = 0;
Direction = dir; Direction = dir;
} }
// Update the Fade Pattern // Update the Fade Pattern
void FadeUpdate() void FadeUpdate()
{ {
@@ -272,12 +316,12 @@ class NeoPattern : public Adafruit_NeoPixel
uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps; uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(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; uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;
ColorSet(Color(red, green, blue)); ColorSet(Color(red, green, blue));
show(); show();
Increment(); Increment();
} }
// Calculate 50% dimmed version of a color (used by ScannerUpdate) // Calculate 50% dimmed version of a color (used by ScannerUpdate)
uint32_t DimColor(uint32_t color) 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); uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
return dimColor; return dimColor;
} }
// Set all pixels to a color (synchronously) // Set all pixels to a color (synchronously)
void ColorSet(uint32_t color) void ColorSet(uint32_t color)
{ {
@@ -295,36 +339,36 @@ class NeoPattern : public Adafruit_NeoPixel
} }
show(); show();
} }
// Returns the Red component of a 32-bit color // Returns the Red component of a 32-bit color
uint8_t Red(uint32_t color) uint8_t Red(uint32_t color)
{ {
return (color >> 16) & 0xFF; return (color >> 16) & 0xFF;
} }
// Returns the Green component of a 32-bit color // Returns the Green component of a 32-bit color
uint8_t Green(uint32_t color) uint8_t Green(uint32_t color)
{ {
return (color >> 8) & 0xFF; return (color >> 8) & 0xFF;
} }
// Returns the Blue component of a 32-bit color // Returns the Blue component of a 32-bit color
uint8_t Blue(uint32_t color) uint8_t Blue(uint32_t color)
{ {
return color & 0xFF; return color & 0xFF;
} }
// Input a value 0 to 255 to get a color value. // Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r. // The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) uint32_t Wheel(byte WheelPos)
{ {
//if(WheelPos == 0) return Color(0,0,0); //if(WheelPos == 0) return Color(0,0,0);
WheelPos = 255 - WheelPos; WheelPos = 255 - WheelPos;
if(WheelPos < 85) if (WheelPos < 85)
{ {
return Color(255 - WheelPos * 3, 0, WheelPos * 3); return Color(255 - WheelPos * 3, 0, WheelPos * 3);
} }
else if(WheelPos < 170) else if (WheelPos < 170)
{ {
WheelPos -= 85; WheelPos -= 85;
return Color(0, WheelPos * 3, 255 - WheelPos * 3); return Color(0, WheelPos * 3, 255 - WheelPos * 3);

41
package-lock.json generated Normal file
View File

@@ -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"
}
}
}
}

View File

@@ -50,4 +50,16 @@ framework = ${common.framework}
build_flags = -Wl,-Teagle.flash.4m1m.ld build_flags = -Wl,-Teagle.flash.4m1m.ld
-DSPROCKET_PRINT=0 -DSPROCKET_PRINT=0
lib_deps = ${common.lib_deps} lib_deps = ${common.lib_deps}
https://gitlab.com/wirelos/sprocket-core.git#master 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

View File

@@ -28,6 +28,7 @@ class IlluCat : public MeshSprocket {
NeoPatternDto state; NeoPatternDto state;
AsyncWebServer* server; AsyncWebServer* server;
AsyncWebSocket* ws; AsyncWebSocket* ws;
AsyncWebSocket* wsStream;
NeoPixelConfig pixelConfig; NeoPixelConfig pixelConfig;
SprocketConfig sprocketConfig; SprocketConfig sprocketConfig;
@@ -72,6 +73,7 @@ class IlluCat : public MeshSprocket {
pixels = new NeoPattern(pixelConfig.length, pixelConfig.pin, NEO_GRB + NEO_KHZ800); pixels = new NeoPattern(pixelConfig.length, pixelConfig.pin, NEO_GRB + NEO_KHZ800);
server = new AsyncWebServer(80); server = new AsyncWebServer(80);
ws = new AsyncWebSocket("/pixel"); ws = new AsyncWebSocket("/pixel");
wsStream = new AsyncWebSocket("/stream");
// add plugins // add plugins
addPlugin(new OtaTcpPlugin(otaConfig)); addPlugin(new OtaTcpPlugin(otaConfig));
@@ -89,6 +91,8 @@ class IlluCat : public MeshSprocket {
server->on("/pixel/api", HTTP_POST, bind(&IlluCat::patternWebRequestHandler, this, _1)); server->on("/pixel/api", HTTP_POST, bind(&IlluCat::patternWebRequestHandler, this, _1));
ws->onEvent(bind(&IlluCat::onWsEvent, this, _1, _2, _3, _4, _5, _6)); ws->onEvent(bind(&IlluCat::onWsEvent, this, _1, _2, _3, _4, _5, _6));
server->addHandler(ws); server->addHandler(ws);
wsStream->onEvent(bind(&IlluCat::onStream, this, _1, _2, _3, _4, _5, _6));
server->addHandler(wsStream);
return MeshSprocket::activate(scheduler, network); return MeshSprocket::activate(scheduler, network);
} using MeshSprocket::activate; } using MeshSprocket::activate;
@@ -101,6 +105,15 @@ class IlluCat : public MeshSprocket {
return defaultValue; 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) { void patternWebRequestHandler(AsyncWebServerRequest *request) {
PRINT_MSG(Serial, SPROCKET_TYPE, "POST /pixel/api"); PRINT_MSG(Serial, SPROCKET_TYPE, "POST /pixel/api");
currentMessage.topic = getRequestParameterOrDefault(request, "topic", ""); currentMessage.topic = getRequestParameterOrDefault(request, "topic", "");

View File

@@ -25,6 +25,7 @@ class PixelPlugin : public Plugin {
pixels = neoPattern; pixels = neoPattern;
pixels->begin(); pixels->begin();
pixels->setBrightness(pixelConfig.brightness); pixels->setBrightness(pixelConfig.brightness);
} }
void activate(Scheduler* userScheduler, Network* network){ void activate(Scheduler* userScheduler, Network* network){
subscribe("pixels/colorWheel", bind(&PixelPlugin::colorWheel, this, _1)); 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/totalSteps", bind(&PixelPlugin::setTotalSteps, this, _1));
subscribe("pixels/brightness", bind(&PixelPlugin::setBrightness, this, _1)); subscribe("pixels/brightness", bind(&PixelPlugin::setBrightness, this, _1));
subscribe("pixels/state", bind(&PixelPlugin::setState, 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)); animation.set(TASK_MILLISECOND * pixelConfig.updateInterval, TASK_FOREVER, bind(&PixelPlugin::animate, this));
userScheduler->addTask(animation); userScheduler->addTask(animation);
animation.enable(); animation.enable();
PRINT_MSG(Serial, SPROCKET_TYPE, "NeoPixels activated"); PRINT_MSG(Serial, SPROCKET_TYPE, "NeoPixels activated");
} }
void stream(String msg){
// TODO handle LED byte array stream
}
void setState(String msg) { void setState(String msg) {
PRINT_MSG(Serial, SPROCKET_TYPE, msg.c_str()); PRINT_MSG(Serial, SPROCKET_TYPE, msg.c_str());
state.fromJsonString(msg); state.fromJsonString(msg);

2
test/.gitignore vendored
View File

@@ -1 +1 @@
node_modules/ node_modules/

45
test/package-lock.json generated
View File

@@ -7,11 +7,56 @@
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" "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": { "coolhue": {
"version": "1.0.9", "version": "1.0.9",
"resolved": "https://registry.npmjs.org/coolhue/-/coolhue-1.0.9.tgz", "resolved": "https://registry.npmjs.org/coolhue/-/coolhue-1.0.9.tgz",
"integrity": "sha512-4+ctEja6XNJ8GrV+OLbioHWssC8tT/IUSZlS6i/RXc0R+ef7g6jNGmLC4VwhEKCJXTKPQ0FqbwojYLDtpPXs1w==" "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": { "ws": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz",

52
test/stream.js Normal file
View File

@@ -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));