'use strict'; const path = require('path'); const wNumb = require('wnumb/wNumb') const Store = require('electron-store'); const store = new Store(); const mspHelper = require('./../js/msp/MSPHelper'); const MSPCodes = require('./../js/msp/MSPCodes'); const MSP = require('./../js/msp'); const { GUI, TABS } = require('./../js/gui'); const FC = require('./../js/fc'); const adjustBoxNameIfPeripheralWithModeID = require('./../js/peripherals'); const i18n = require('./../js/localization'); const interval = require('./../js/intervals'); var ORIG_AUX_CONFIG_IDS = []; TABS.auxiliary = {}; TABS.auxiliary.initialize = function (callback) { GUI.active_tab_ref = this; GUI.active_tab = 'auxiliary'; let LOCAL_AUX_CONFIG = []; let LOCAL_AUX_CONFIG_IDS = []; let prevChannelsValues = null; MSP.send_message(MSPCodes.MSP_MODE_RANGES, false, false, get_box_ids); function get_box_ids() { MSP.send_message(MSPCodes.MSP_BOXIDS, false, false, function () { FC.generateAuxConfig(); //Copy global settings into local ones LOCAL_AUX_CONFIG = Array.from(FC.AUX_CONFIG); LOCAL_AUX_CONFIG_IDS = Array.from(FC.AUX_CONFIG_IDS); get_rc_data(); }); } function get_rc_data() { MSP.send_message(MSPCodes.MSP_RC, false, false, load_html); } function load_html() { sort_modes_for_display(); GUI.load(path.join(__dirname, "auxiliary.html"), process_html); } // This object separates out the dividers. This is also used to order the modes const modeSections = {}; modeSections["Arming"] = ["ARM", "PREARM"]; modeSections["Flight Modes"] = ["ANGLE", "HORIZON", "MANUAL", "ANGLE HOLD"]; modeSections["Navigation Modes"] = ["NAV COURSE HOLD", "NAV CRUISE", "NAV POSHOLD", "NAV RTH", "NAV WP", "GCS NAV"]; modeSections["Flight Mode Modifiers"] = ["NAV ALTHOLD", "HEADING HOLD", "AIR MODE", "SOARING", "SURFACE", "TURN ASSIST"]; modeSections["Fixed Wing"] = ["AUTO TUNE", "SERVO AUTOTRIM", "AUTO LEVEL TRIM", "NAV LAUNCH", "LOITER CHANGE", "FLAPERON"]; modeSections["Multi-rotor"] = ["FPV ANGLE MIX", "TURTLE", "MC BRAKING", "HEADFREE", "HEADADJ"]; modeSections["OSD Modes"] = ["OSD OFF", "OSD ALT 1", "OSD ALT 2", "OSD ALT 3"]; modeSections["FPV Camera Modes"] = ["CAMSTAB", "CAMERA CONTROL 1", "CAMERA CONTROL 2", "CAMERA CONTROL 3"]; modeSections["VTOL"] = ["MIXER PROFILE 2", "MIXER TRANSITION"]; modeSections["Beeper"] = ["BEEPER", "BEEPER MUTE"]; modeSections["Gimbal"] = ["GIMBAL LEVEL TILT", "GIMBAL LEVEL ROLL", "GIMBAL LEVEL PAN", "GIMBAL HEADTRACKER", "GIMBAL CENTER"]; modeSections["Misc Modes"] = ["LEDS OFF", "LIGHTS", "HOME RESET", "WP PLANNER", "MISSION CHANGE", "BLACKBOX", "FAILSAFE", "KILLSWITCH", "TELEMETRY", "MSP RC OVERRIDE", "USER1", "USER2", "USER3", "USER4"]; function sort_modes_for_display() { // Sort the modes var tmpAUX_CONFIG = []; var tmpAUX_CONFIG_IDS =[]; var found = false; var sortedID = 0; for (let i=0; i LOCAL_AUX_CONFIG.length) { for (let i=0; i 2100) { channelPosition = 2100; } var percentage = (channelPosition - 900) / (2100-900) * 100; $('.modes .ranges .range').each( function () { var auxChannelCandidateIndex = $(this).find('.channel').val(); if (auxChannelCandidateIndex != auxChannelIndex) { return; } $(this).find('.marker').css('left', percentage + '%'); }); } // data pulling functions used inside interval timer function get_rc_data() { MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui); } function update_ui() { let hasUsedMode = false; let acroEnabled = true; let acroFail = ["ANGLE", "HORIZON", "MANUAL", "ANGLE HOLD", "NAV RTH", "NAV POSHOLD", "NAV CRUISE", "NAV COURSE HOLD", "NAV WP", "GCS NAV"]; var auxChannelCount = FC.RC.active_channels - 4; for (var i = 0; i < (auxChannelCount); i++) { update_marker(i, FC.RC.channels[i + 4]); } for (var i = 0; i < LOCAL_AUX_CONFIG.length; i++) { var modeElement = $('#mode-' + i); let inRange = false; if (modeElement.find(' .range').length == 0) { // if the mode is unused, skip it modeElement.removeClass('off').removeClass('on'); continue; } if (FC.isModeBitSet(modeElement.data('origId'))) { // The flight controller can activate the mode $('.mode .name').eq(modeElement.data('index')).data('modeElement').addClass('on').removeClass('inRange').removeClass('off'); if (jQuery.inArray(modeElement.data('modeName'), acroFail) !== -1) { acroEnabled = false; } } else { // Check to see if the mode is in range var modeRanges = modeElement.find(' .range'); for (let r = 0; r < modeRanges.length; r++) { var rangeLow = $(modeRanges[r]).find('.lowerLimitValue').html(); var rangeHigh = $(modeRanges[r]).find('.upperLimitValue').html(); var markerPosition = $(modeRanges[r]).find('.marker')[0].style.left; markerPosition = markerPosition.substring(0, markerPosition.length-1); rangeLow = (rangeLow - 900) / (2100-900) * 100; rangeHigh = (rangeHigh - 900) / (2100-900) * 100; if ((markerPosition >= rangeLow) && (markerPosition <= rangeHigh)) { inRange = true; } } if (inRange) { $('.mode .name').eq(modeElement.data('index')).data('modeElement').removeClass('on').addClass('inRange').removeClass('off'); if (jQuery.inArray(modeElement.data('modeName'), acroFail) !== -1) { acroEnabled = false; } } else { // If not, it is shown as disabled. $('.mode .name').eq(modeElement.data('index')).data('modeElement').removeClass('on').removeClass('inRange').addClass('off'); } } hasUsedMode = true; } if (acroEnabled) { $('.acroEnabled').addClass('on').removeClass('off'); } else { $('.acroEnabled').removeClass('on').addClass('off'); } let hideUnused = hideUnusedModes && hasUsedMode; for (let i = 0; i < LOCAL_AUX_CONFIG.length; i++) { let modeElement = $('#mode-' + i); if (modeElement.find(' .range').length == 0) { modeElement.toggle(!hideUnused); } } auto_select_channel(FC.RC.channels, FC.RC.active_channels, FC.MISC.rssi_channel); $(".modeSection").each(function() { $(this).toggle(!hideUnused); }); } /** * Autodetect channel based on maximum deference with previous value * minimum value to autodetect is 100 */ function auto_select_channel(RC_channels, activeChannels, RSSI_channel) { const auto_option = $('.tab-auxiliary select.channel option[value="-1"]:selected'); if (auto_option.length === 0) { prevChannelsValues = null; return; } const fillPrevChannelsValues = function () { prevChannelsValues = RC_channels.slice(0); //clone array }; if (!prevChannelsValues || RC_channels.length === 0) return fillPrevChannelsValues(); let diff_array = RC_channels.map(function(currentValue, index) { return Math.abs(prevChannelsValues[index] - currentValue); }); diff_array = diff_array.slice(0, activeChannels); const largest = diff_array.reduce(function(x,y){ return (x > y) ? x : y; }, 0); //minimum change to autoselect is 100 if (largest < 100) return fillPrevChannelsValues(); const indexOfMaxValue = diff_array.indexOf(largest); if (indexOfMaxValue >= 4 && indexOfMaxValue != RSSI_channel - 1){ //set channel auto_option.parent().val(indexOfMaxValue - 4); } return fillPrevChannelsValues(); } let hideUnusedModes = false; let hideUnusedModesStore = store.get('hideUnusedModes', false); $("input#switch-toggle-unused") .on('change', function () { hideUnusedModes = $(this).prop("checked"); store.set('hideUnusedModes', hideUnusedModes); update_ui(); }) .prop("checked", !!hideUnusedModesStore) .trigger('change'); // update ui instantly on first load update_ui(); // enable data pulling interval.add('aux_data_pull', get_rc_data, 50); $(".tab-auxiliary .acroEnabled").width($("#mode-0 .info").width()); GUI.content_ready(callback); } }; TABS.auxiliary.cleanup = function (callback) { if (callback) callback(); }; $(window).on('resize', function(){ $(".tab-auxiliary .acroEnabled").width($("#mode-0 .info").width()); });