Allow saving of LED Strip configuratiion via MSP. Requires firmware

with new MSP_SET_LED_STRIP_CONFIG.

Remove some .toUpperCase() duplication since it was only needed for the
CLI commands panel.
Minor CSS cleanups.
Some variable and class renaming to align with firmware code.
10.3.x-maintenance
Dominic Clifton 2015-01-16 00:15:41 +00:00
parent db68d567d3
commit 519de30f6e
9 changed files with 192 additions and 93 deletions

View File

@ -948,7 +948,9 @@
"ledStripHelp": {
"message": "The flight controller can control colors and effects of individual LEDs on a strip.<br />Configure LEDs on the grid, configure wiring order then attach LEDs on your aircraft according to grid positions."
},
"ledStripButtonSave": {
"message": "Save"
}
}

View File

@ -93,6 +93,9 @@ var MSP = {
callbacks: [],
packet_error: 0,
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
ledFunctionLetters: ['i', 'w', 'f', 'a', 't'], // in LSB bit order
read: function (readInfo) {
var data = new Uint8Array(readInfo.data);
@ -626,10 +629,9 @@ var MSP = {
offset += 2;
var directions = [];
var directionLetters = ['n', 'e', 's', 'w', 'u', 'd'];
for (var directionLetterIndex = 0; directionLetterIndex < directionLetters.length; directionLetterIndex++) {
for (var directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
if (bit_check(directionMask, directionLetterIndex)) {
directions.push(directionLetters[directionLetterIndex]);
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
}
}
@ -637,10 +639,9 @@ var MSP = {
offset += 2;
var functions = [];
var functionLetters = ['i', 'w', 'f', 'a', 't'];
for (var functionLetterIndex = 0; functionLetterIndex < functionLetters.length; functionLetterIndex++) {
for (var functionLetterIndex = 0; functionLetterIndex < MSP.ledFunctionLetters.length; functionLetterIndex++) {
if (bit_check(functionMask, functionLetterIndex)) {
functions.push(functionLetters[functionLetterIndex]);
functions.push(MSP.ledFunctionLetters[functionLetterIndex]);
}
}
@ -655,6 +656,10 @@ var MSP = {
}
break;
case MSP_codes.MSP_SET_LED_STRIP_CONFIG:
console.log('Led strip config saved');
break;
case MSP_codes.MSP_SET_MODE_RANGE:
console.log('Mode range saved');
@ -989,3 +994,53 @@ MSP.sendAdjustmentRanges = function(onCompleteCallback) {
}
};
MSP.sendLedStripConfig = function(onCompleteCallback) {
var nextFunction = send_next_led_strip_config;
var ledIndex = 0;
send_next_led_strip_config();
function send_next_led_strip_config() {
var led = LED_STRIP[ledIndex];
var buffer = [];
buffer.push(ledIndex);
var directionMask = 0;
for (var directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
var bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
if (bitIndex >= 0) {
directionMask = bit_set(directionMask, bitIndex);
}
}
buffer.push(specificByte(directionMask, 0));
buffer.push(specificByte(directionMask, 1));
var functionMask = 0;
for (var functionLetterIndex = 0; functionLetterIndex < led.functions.length; functionLetterIndex++) {
var bitIndex = MSP.ledFunctionLetters.indexOf(led.functions[functionLetterIndex]);
if (bitIndex >= 0) {
functionMask = bit_set(functionMask, bitIndex);
}
}
buffer.push(specificByte(functionMask, 0));
buffer.push(specificByte(functionMask, 1));
buffer.push(led.x);
buffer.push(led.y);
// prepare for next iteration
ledIndex++;
if (ledIndex == LED_STRIP.length) {
nextFunction = onCompleteCallback;
}
MSP.send_message(MSP_codes.MSP_SET_LED_STRIP_CONFIG, buffer, false, nextFunction);
}
}

View File

@ -98,10 +98,7 @@
}
.tab-adjustments > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-adjustments > .buttons a {

View File

@ -139,10 +139,7 @@
}
.tab-auxiliary > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-auxiliary > .buttons a {

View File

@ -140,13 +140,6 @@
margin-left: 15px;
}
.tab-auxiliary > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-configuration .save {
display: block;
float: right;

View File

@ -29,35 +29,35 @@
cursor: pointer;
}
.tab-led-strip .gPoint.mode-w { /* warning */
.tab-led-strip .gPoint.function-w { /* warning */
background: red;
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: red;
}
.tab-led-strip .gPoint.mode-f { /* flight mode & orientation */
.tab-led-strip .gPoint.function-f { /* flight mode & orientation */
background: rgb(50, 205, 50);
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: rgb(50, 205, 50);
}
.tab-led-strip .gPoint.mode-w.mode-f {
.tab-led-strip .gPoint.function-w.function-f {
background: linear-gradient(to bottom, #42c949 0%,#d2ff52 52%,#d2ff52 52%,#ff5454 52%,#ba3535 100%);
}
.tab-led-strip .gPoint.mode-i { /* indicator */
.tab-led-strip .gPoint.function-i { /* indicator */
background: yellow;
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: yellow;
}
.tab-led-strip .gPoint.mode-a { /* Armed Mode */
.tab-led-strip .gPoint.function-a { /* Armed Mode */
background: rgb(52, 155, 255);
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: rgb(52, 155, 255);
}
.tab-led-strip .gPoint.mode-t { /* Armed Mode */
.tab-led-strip .gPoint.function-t { /* Armed Mode */
background: orange;
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: orange;
@ -136,18 +136,13 @@
width: 32%;
}
.tab-led-strip .modeW.btnOn {background: red;}
.tab-led-strip .modeF.btnOn {background: rgb(50, 205, 50);}
.tab-led-strip .modeI.btnOn {background: yellow; color: #333;}
.tab-led-strip .modeA.btnOn {background: blue;}
.tab-led-strip .modeT.btnOn {background: orange;}
.tab-led-strip .functions .function-w.btnOn {background: red;}
.tab-led-strip .functions .function-f.btnOn {background: rgb(50, 205, 50);}
.tab-led-strip .functions .function-i.btnOn {background: yellow; color: #333;}
.tab-led-strip .functions .function-a.btnOn {background: blue;}
.tab-led-strip .functions .function-t.btnOn {background: orange;}
.tab-led-strip .dirN.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirE.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirS.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirW.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirU.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirD.btnOn {background: #FFF; color: #000;}
.tab-led-strip .directions .btnOn {background: #FFF; color: #000;}
.tab-led-strip .indicators {
position: relative;
@ -235,24 +230,24 @@
outline: none;
}
.tab-led-strip .orientation {
.tab-led-strip .directions {
width: 130px;
height: 100px;
position: relative;
}
.tab-led-strip .orientation button {
.tab-led-strip .directions button {
position: absolute;
width: 30px;
height: 30px;
}
.tab-led-strip .orientation .dirN {top: 0; left: 32px;}
.tab-led-strip .orientation .dirS {bottom: 0; left: 32px;}
.tab-led-strip .orientation .dirE {left: 64px; top: 32px;}
.tab-led-strip .orientation .dirW {left: 0; top: 32px;}
.tab-led-strip .orientation .dirU {right: 0; top: 15px;}
.tab-led-strip .orientation .dirD {right: 0; bottom: 15px;}
.tab-led-strip .directions .dir-n {top: 0; left: 32px;}
.tab-led-strip .directions .dir-s {bottom: 0; left: 32px;}
.tab-led-strip .directions .dir-e {left: 64px; top: 32px;}
.tab-led-strip .directions .dir-w {left: 0; top: 32px;}
.tab-led-strip .directions .dir-u {right: 0; top: 15px;}
.tab-led-strip .directions .dir-d {right: 0; bottom: 15px;}
.tab-led-strip .wires-remaining {
float: right;
@ -289,3 +284,26 @@
z-index: 100;
border: 1px dotted white;
}
.tab-led-strip > .buttons {
margin-top: 10px;
}
.tab-led-strip .save {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-led-strip.save:hover {
background-color: #dedcdc;
}

View File

@ -8,23 +8,23 @@
<div class="wires-remaining"><div></div>Remaining</div>
<button class="funcClear">Clear selected</button>
<div class="section">LED Modes</div>
<div class="modes">
<button class="modeW w50">Warnings</button>
<button class="modeF w50">Flight &amp; Orientation</button><br>
<button class="modeI w33">Indicator</button>
<button class="modeA w33">Arm State</button>
<button class="modeT w33">Thrust</button>
<div class="section">LED Functions</div>
<div class="functions">
<button class="function-w w50">Warnings</button>
<button class="function-f w50">Flight &amp; Orientation</button><br>
<button class="function-i w33">Indicator</button>
<button class="function-a w33">Arm State</button>
<button class="function-t w33">Thrust</button>
</div>
<div class="section">LED Orientation</div>
<div class="orientation">
<button class="dirN">N</button>
<button class="dirE">E</button>
<button class="dirS">S</button>
<button class="dirW">W</button>
<button class="dirU">U</button>
<button class="dirD">D</button>
<div class="directions">
<button class="dir-n">N</button>
<button class="dir-e">E</button>
<button class="dir-s">S</button>
<button class="dir-w">W</button>
<button class="dir-u">U</button>
<button class="dir-d">D</button>
</div>
@ -43,4 +43,9 @@
</div>
</div>
<div class="clear-both"></div>
<div class="buttons">
<a class="save" href="#" i18n="ledStripButtonSave"></a>
</div>
</div>

View File

@ -2,8 +2,8 @@
TABS.led_strip = {
wireMode: false,
flightModes: ['w', 'f', 'i', 'a', 't'],
ledOrientations: ['n', 'e', 's', 'w', 'u', 'd'],
functions: ['w', 'f', 'i', 'a', 't'],
directions: ['n', 'e', 's', 'w', 'u', 'd'],
};
TABS.led_strip.initialize = function (callback, scrollPosition) {
@ -71,11 +71,11 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
// Directional Buttons
$('.orientation').on('click', 'button', function() {
$('.directions').on('click', 'button', function() {
var that = this;
if ($('.ui-selected').length > 0) {
TABS.led_strip.ledOrientations.forEach(function(letter) {
if ($(that).is('.dir' + letter.toUpperCase())) {
TABS.led_strip.directions.forEach(function(letter) {
if ($(that).is('.dir-' + letter)) {
$(that).toggleClass('btnOn');
$('.ui-selected').toggleClass('dir-' + letter);
}
@ -87,13 +87,13 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
// Mode Buttons
$('.modes').on('click', 'button', function() {
$('.functions').on('click', 'button', function() {
var that = this;
if ($('.ui-selected').length > 0) {
TABS.led_strip.flightModes.forEach(function(letter) {
if ($(that).is('.mode' + letter.toUpperCase())) {
TABS.led_strip.functions.forEach(function(letter) {
if ($(that).is('.function-' + letter)) {
$(that).toggleClass('btnOn');
$('.ui-selected').toggleClass('mode-' + letter);
$('.ui-selected').toggleClass('function-' + letter);
}
});
@ -145,19 +145,19 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
var that = this;
TABS.led_strip.ledOrientations.forEach(function(letter) {
TABS.led_strip.directions.forEach(function(letter) {
if ($(that).is('.dir-' + letter)) {
$('.dir' + letter.toUpperCase()).addClass('btnOn');
$('.dir-' + letter).addClass('btnOn');
} else {
$('.dir' + letter.toUpperCase()).removeClass('btnOn');
$('.dir-' + letter).removeClass('btnOn');
}
});
TABS.led_strip.flightModes.forEach(function(letter) {
if ($(that).is('.mode-' + letter)) {
$('.mode' + letter.toUpperCase()).addClass('btnOn');
TABS.led_strip.functions.forEach(function(letter) {
if ($(that).is('.function-' + letter)) {
$('.function-' + letter).addClass('btnOn');
} else {
$('.mode' + letter.toUpperCase()).removeClass('btnOn');
$('.function-' + letter).removeClass('btnOn');
}
});
@ -191,7 +191,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
$(this).find('.wire').html(ledIndex);
for (var modeIndex = 0; modeIndex < led.functions.length; modeIndex++) {
$(this).addClass('mode-' + led.functions[modeIndex]);
$(this).addClass('function-' + led.functions[modeIndex]);
}
for (var directionIndex = 0; directionIndex < led.directions.length; directionIndex++) {
@ -201,6 +201,16 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
});
updateBulkCmd();
$('a.save').click(function () {
MSP.sendLedStripConfig(save_to_eeprom);
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
}
});
if (callback) callback();
}
@ -216,38 +226,50 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
function updateBulkCmd() {
$('.tempOutput').empty();
$('.tempOutput').html('# Copy and paste commands below into the CLI' + "\n\n");
$('.tempOutput').html('# CLI commands' + "\n\n");
var counter = 0;
var lines = [];
var ledStripLength = LED_STRIP.length;
LED_STRIP = [];
$('.gPoint').each(function(){
if ($(this).is('[class*="mode"]')) {
if ($(this).is('[class*="function"]')) {
var gridNumber = ($(this).index() + 1);
var row = Math.ceil(gridNumber / 16) - 1;
var col = gridNumber/16 % 1 * 16 - 1;
if (col < 0) {col = 15;}
var wireNumber = $(this).find('.wire').html();
var ledModes = '';
var functions = '';
var directions = '';
var that = this;
TABS.led_strip.flightModes.forEach(function(letter){
if ($(that).is('.mode-' + letter)) {
ledModes += letter.toUpperCase();
TABS.led_strip.functions.forEach(function(letter){
if ($(that).is('.function-' + letter)) {
functions += letter;
}
});
TABS.led_strip.ledOrientations.forEach(function(letter){
TABS.led_strip.directions.forEach(function(letter){
if ($(that).is('.dir-' + letter)) {
directions += letter.toUpperCase();
directions += letter;
}
});
if (wireNumber != '') {
var line = 'led ' + wireNumber + ' ' + col + ',' + row + ':' + directions + ':' + ledModes;
var line = 'led ' + wireNumber + ' ' + col + ',' + row + ':' + directions.toUpperCase() + ':' + functions.toUpperCase();
lines[wireNumber] = line;
var led = {
x: col,
y: row,
directions: directions,
functions: functions
}
LED_STRIP[wireNumber] = led;
}
counter++;
}
@ -255,9 +277,25 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
$('.tempOutput').append(lines.join("\n"));
var defaultLed = {
x: 0,
y: 0,
directions: '',
functions: ''
};
for (var i = 0; i < ledStripLength; i++) {
if (LED_STRIP[i]) {
continue;
}
LED_STRIP[i] = defaultLed;
}
console.log(LED_STRIP);
var usedWireNumbers = buildUsedWireNumbers();
var remaining = LED_STRIP.length - usedWireNumbers.length;
$('.wires-remaining div').html(remaining);
}

View File

@ -38,12 +38,6 @@
.tab-ports select {
border: 1px solid silver;
}
.tab-ports > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-ports .save {
display: block;