Skip to content

Commit b91e8db

Browse files
committed
Use binary data for websocket
1 parent ea34342 commit b91e8db

File tree

4 files changed

+50
-70
lines changed

4 files changed

+50
-70
lines changed

FastLEDManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ void FastLEDManagerClass::begin(Animation *animation)
224224
if (currentAnimation && currentAnimation->getName() == animation->getName())
225225
return;
226226

227-
clear();
227+
clear(true);
228228

229229
status = RUNNING;
230230
currentAnimation = animation;
@@ -252,7 +252,7 @@ void FastLEDManagerClass::stop()
252252
return;
253253

254254
status = STOPPED;
255-
clear();
255+
clear(true);
256256
currentAnimation = NULL;
257257

258258
WebSocket::broadcastStatus();

WebSocket.cpp

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -67,41 +67,7 @@ void handleText(String text, uint8_t id)
6767
text.toCharArray(textArray, text.length());
6868

6969
if (Config.parseJson(textArray))
70-
{
7170
Config.save();
72-
return;
73-
}
74-
75-
if (text.startsWith("toggle"))
76-
{
77-
String animation = text.substring(7);
78-
Fade::stop();
79-
FastLEDManager.toggle(FastLEDManager.getAnimation(animation));
80-
}
81-
else if (text == "stop")
82-
{
83-
if (FastLEDManager.currentAnimation)
84-
FastLEDManager.stop();
85-
}
86-
else if (text == "requesting_config")
87-
{
88-
DynamicJsonDocument doc(2048);
89-
doc = Config.getJson(doc);
90-
doc["status"] = String(FastLEDManager.status);
91-
doc["currentAnimation"] = FastLEDManager.currentAnimation ? FastLEDManager.currentAnimation->getName() : "";
92-
JsonArray animations = doc.createNestedArray("animations");
93-
for (uint8_t i = 0; i < FastLEDManager.animations.size(); i++)
94-
{
95-
animations.add(FastLEDManager.animations.get(i)->getName());
96-
}
97-
String buffer = "";
98-
serializeJson(doc, buffer);
99-
socket.sendTXT(id, buffer.c_str());
100-
}
101-
else
102-
{
103-
PRINTLN("Command '" + text + "' not found!");
104-
}
10571
}
10672

10773
void handleBinary(uint8_t *binary, uint8_t id)
@@ -111,30 +77,46 @@ void handleBinary(uint8_t *binary, uint8_t id)
11177
case 0: // Color
11278
Config.color = rgb2hex(binary[1], binary[2], binary[3]);
11379
FastLEDManager.begin(FastLEDManager.getAnimation("Color"));
114-
socket.sendTXT(id, String("ok").c_str());
11580
break;
116-
case 1: // Speed
117-
Config.speed = binary[1];
118-
socket.sendTXT(id, String("ok").c_str());
81+
case 1: // Toggle animation
82+
Fade::stop();
83+
FastLEDManager.toggle(FastLEDManager.getAnimation(binary[1]));
84+
break;
85+
case 2: // Stop
86+
FastLEDManager.stop();
11987
break;
120-
case 4: // Spectroscope data
88+
case 10: // Spectroscope data
12189
if (FastLEDManager.currentAnimation)
12290
FastLEDManager.stop();
12391
for (uint16_t i = 0; i < FastLEDManager.numLeds; i++)
124-
{
12592
FastLEDManager.leds[i] = CRGB(binary[1 + i * 3], binary[2 + i * 3], binary[3 + i * 3]);
126-
}
12793
break;
128-
case 5: // Saturation
129-
Config.saturation = binary[1];
130-
socket.sendTXT(id, String("ok").c_str());
131-
break;
132-
case 6: // linearSpectroscope data
94+
case 11: // linear spectroscope data
13395
Spectroscope::updateSpectroscope(binary + 1, false);
13496
break;
135-
case 7: // symmetricalSpectroscope data
97+
case 12: // Symmetrical spectroscope data
13698
Spectroscope::updateSpectroscope(binary + 1, true);
13799
break;
100+
case 20: // Speed
101+
Config.speed = binary[1];
102+
break;
103+
case 21: // Saturation
104+
Config.saturation = binary[1];
105+
break;
106+
case 30: // Request configuration
107+
DynamicJsonDocument doc(2048);
108+
doc = Config.getJson(doc);
109+
doc["status"] = String(FastLEDManager.status);
110+
doc["currentAnimation"] = FastLEDManager.currentAnimation ? FastLEDManager.currentAnimation->getName() : "";
111+
JsonArray animations = doc.createNestedArray("animations");
112+
for (uint8_t i = 0; i < FastLEDManager.animations.size(); i++)
113+
{
114+
animations.add(FastLEDManager.animations.get(i)->getName());
115+
}
116+
String buffer = "";
117+
serializeJson(doc, buffer);
118+
socket.sendTXT(id, buffer.c_str());
119+
break;
138120
}
139121
}
140122

data/index.htm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ <h1 style="text-align: center">FastLED Manager</h1>
3030
<div id="animationButtons">
3131
<button type="button" class="btn btn-secondary color no-alpha" id="colorButton">Color</button>
3232
<button type="button" class="btn btn-danger color no-alpha" id="stopButton"
33-
onclick="sendText('stop')">Stop</button>
33+
onclick="ws_pending_msg = [2]">Stop</button>
3434
</div>
3535

3636
<div class="speedSlider" id="speed"></div>

data/index.js

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ let currentAnimation = '';
22
let currentStatus = 0;
33
let currentColor = '';
44

5-
let websocketReady = false;
5+
let ws_pending_msg;
66
let ws_uri = 'ws://' + (location.hostname ? location.hostname : 'localhost') + ':81/';
77
let connection = new WebSocket(ws_uri, ['arduino']);
88
connection.binaryType = 'arraybuffer';
99

1010
connection.onopen = function (e) {
11-
sendText('requesting_config');
12-
11+
ws_pending_msg = [30]
1312
connectingOverlayText.innerHTML = 'Waiting for response...';
1413
refreshButton.style.display = 'none';
1514
};
@@ -27,7 +26,6 @@ connection.onclose = function (e) {
2726
connection.onmessage = function (e) {
2827
console.log('Received: ', e.data);
2928

30-
websocketReady = true;
3129
try {
3230
handleJsonData(JSON.parse(e.data));
3331

@@ -38,7 +36,7 @@ connection.onmessage = function (e) {
3836

3937
function handleJsonData(data) {
4038
if (data.hasOwnProperty('animations')) {
41-
data.animations.forEach(animation => {
39+
data.animations.forEach((animation, idx) => {
4240
// Fill animation dropdowns
4341
alarmAnimation.add(new Option(animation));
4442
postAlarmAnimation.add(new Option(animation));
@@ -50,7 +48,7 @@ function handleJsonData(data) {
5048
let btn = document.createElement('button');
5149
btn.classList.add('btn-secondary', 'btn');
5250
btn.innerHTML = animation;
53-
btn.onclick = () => { sendAnimationButton(animation); };
51+
btn.onclick = () => { sendAnimationButton(idx); };
5452
animationButtons.insertBefore(btn, stopButton);
5553
}
5654
})
@@ -164,18 +162,15 @@ function sendConfig() {
164162
}
165163

166164
function sendBytes() {
167-
if (connection.readyState == 1 && websocketReady) {
168-
let data = new Uint8Array(arguments.length);
169-
for (let i = 0; i < arguments.length; i++) {
170-
data[i] = arguments[i];
165+
if (connection.readyState == 1 && ws_pending_msg) {
166+
let data = new Uint8Array(ws_pending_msg.length);
167+
for (let i = 0; i < ws_pending_msg.length; i++) {
168+
data[i] = ws_pending_msg[i];
171169
}
170+
ws_pending_msg = undefined;
172171
connection.send(data.buffer);
173-
websocketReady = false;
174172
console.log('Sent bytes: ' + data);
175173
}
176-
else {
177-
console.log('Not connected. Data not sent!');
178-
}
179174
}
180175

181176
function sendText(text) {
@@ -189,7 +184,7 @@ function sendText(text) {
189184
}
190185

191186
function sendAnimationButton(animation) {
192-
sendText('toggle ' + animation);
187+
ws_pending_msg = [1, animation];
193188
}
194189

195190

@@ -219,7 +214,7 @@ let $customColorPicker = $('#colorButton').colorPicker({
219214
let newColor = this.color.colors.HEX + ''; // dereference by appending ''
220215
if (currentColor != newColor || toggled === true) {
221216
let newColorRGB = this.color.colors.RND.rgb;
222-
sendBytes(0, newColorRGB.r, newColorRGB.g, newColorRGB.b);
217+
ws_pending_msg = [0, newColorRGB.r, newColorRGB.g, newColorRGB.b];
223218
currentColor = newColor;
224219
document.querySelector('#colorButton').style.borderColor = '#' + newColor;
225220
}
@@ -229,19 +224,22 @@ let $customColorPicker = $('#colorButton').colorPicker({
229224
// Sliders
230225
noUiSlider.create(speed, { start: 128, step: 1, range: { 'min': 0, 'max': 255 } });
231226
noUiSlider.create(saturation, { start: 255, step: 1, range: { 'min': 110, 'max': 255 } });
232-
speed.noUiSlider.on('update', (values, handle) => { sendBytes(1, values[handle]); });
233-
saturation.noUiSlider.on('update', (values, handle) => { sendBytes(5, values[handle]); });
227+
speed.noUiSlider.on('update', (values, handle) => { ws_pending_msg = [20, values[handle]]; });
228+
saturation.noUiSlider.on('update', (values, handle) => { ws_pending_msg = [21, values[handle]]; });
234229
document.querySelector('#speed .noUi-handle').innerHTML = 'Speed';
235230
document.querySelector('#saturation .noUi-handle').innerHTML = 'Sat.';
236231

237232
// Close connection after being ianctive for 5 minutes
238233
let idleTime = 0;
239234
setInterval(() => {
240235
idleTime++;
241-
if (idleTime > 300)//s
236+
if (idleTime > 300) // in s
242237
connection.close();
243238
}, 1000);
244239

240+
// Rate limit websocket
241+
setInterval(sendBytes, 15);
242+
245243
document.addEventListener('mousemove', e => { idleTime = 0; });
246244
document.addEventListener('keypress', e => { idleTime = 0; });
247245
document.addEventListener('visibilitychange', () => {
@@ -252,4 +250,4 @@ document.addEventListener('visibilitychange', () => {
252250
else
253251
location.reload();
254252
}
255-
})
253+
})

0 commit comments

Comments
 (0)