From 1752c5d39d89428a2c42c132c1a5916f8b37f949 Mon Sep 17 00:00:00 2001 From: Hydra Date: Sat, 1 Apr 2017 22:01:16 +0100 Subject: [PATCH] CF/BF - Initial port of power/battery tab from CF 1.x. The voltage and amperage meters cannot yet be configured and are disabled. --- _locales/en/messages.json | 128 +++++++++++++ images/icons/cf_icon_power_grey.svg | 14 ++ images/icons/cf_icon_power_white.svg | 14 ++ js/gui.js | 1 + js/msp/MSPHelper.js | 46 ++--- main.css | 13 ++ main.html | 4 + main.js | 3 + tabs/power.css | 80 ++++++++ tabs/power.html | 167 ++++++++++++++++ tabs/power.js | 275 +++++++++++++++++++++++++++ 11 files changed, 723 insertions(+), 22 deletions(-) create mode 100644 images/icons/cf_icon_power_grey.svg create mode 100644 images/icons/cf_icon_power_white.svg create mode 100644 tabs/power.css create mode 100644 tabs/power.html create mode 100644 tabs/power.js diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 4ec3b646..649af5a2 100755 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -100,6 +100,9 @@ "tabOsd": { "message": "OSD" }, + "tabPower": { + "message": "Power & Battery" + }, "tabGPS": { "message": "GPS" }, @@ -556,6 +559,9 @@ "featureOSD": { "message": "On Screen Display" }, + "featureVTX": { + "message": "Video Transmitter" + }, "featureFAILSAFE": { "message": "Enable Failsafe Stage 2" }, @@ -1885,6 +1891,128 @@ "failsafeKillSwitchHelp": { "message": "Set this option to make the failsafe switch, configured in the modes tab, act as a direct kill switch, bypassing the selected failsafe procedure. Note: Arming is blocked with the failsafe kill switch in the ON position" }, + "powerFirmwareUpgradeRequired": { + "message": "Firmware upgrade required. Battery/Amperage/Voltage configurations using API < 1.22.0 is not supported." + }, + + "powerButtonSave": { + "message": "Save" + }, + + "powerVoltageHead": { + "message": "Voltage" + }, + "powerVoltageValue": { + "message": "$1 V" + }, + "powerAmperageValue": { + "message": "$1 A" + }, + "powerVoltageId10": { + "message": "Battery" + }, + "powerVoltageId20": { + "message": "5V" + }, + "powerVoltageId30": { + "message": "9V" + }, + "powerVoltageId40": { + "message": "12V" + }, + "powerVoltageId50": { + "message": "ESC Combined" + }, + "powerVoltageId60": { + "message": "ESC Motor 1" + }, + "powerVoltageId61": { + "message": "ESC Motor 2" + }, + "powerVoltageId62": { + "message": "ESC Motor 3" + }, + "powerVoltageId63": { + "message": "ESC Motor 4" + }, + "powerVoltageId80": { + "message": "Cell 1" + }, + "powerVoltageId81": { + "message": "Cell 2" + }, + "powerVoltageId82": { + "message": "Cell 3" + }, + "powerVoltageId83": { + "message": "Cell 4" + }, + "powerVoltageId84": { + "message": "Cell 5" + }, + "powerVoltageId85": { + "message": "Cell 6" + }, + + + "powerVoltageScale": { + "message": "Scale" + }, + "powerVoltageDivider": { + "message": "Divider Value" + }, + "powerVoltageMultiplier": { + "message": "Multiplier Value" + }, + + "powerAmperageHead": { + "message": "Amperage" + }, + "powerAmperageId10": { + "message": "Battery" + }, + "powerAmperageId50": { + "message": "ESC Combined" + }, + "powerAmperageId80": { + "message": "Virtual" + }, + "powerMahValue": { + "message": "$1 mAh" + }, + + "powerAmperageScale": { + "message": "Scale the output voltage to milliamps [1/10th mV/A]" + }, + "powerAmperageOffset": { + "message": "Offset in millivolt steps" + }, + + "powerBatteryHead": { + "message": "Battery" + }, + "powerBatteryConnected": { + "message": "Connected" + }, + "powerBatteryConnectedValueYes": { + "message": "Yes (Cells: $1)" + }, + "powerBatteryConnectedValueNo": { + "message": "No" + }, + "powerBatteryVoltage": { + "message": "Voltage" + }, + "powerBatteryCurrentDrawn": { + "message": "mAh used" + }, + "powerBatteryAmperage": { + "message": "Amperage" + }, + "powerBatteryCapacity": { + "message": "Capacity (mAh)" + }, + "mainHelpArmed": { "message": "Motor Arming" }, diff --git a/images/icons/cf_icon_power_grey.svg b/images/icons/cf_icon_power_grey.svg new file mode 100644 index 00000000..2cb96635 --- /dev/null +++ b/images/icons/cf_icon_power_grey.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/images/icons/cf_icon_power_white.svg b/images/icons/cf_icon_power_white.svg new file mode 100644 index 00000000..1af9f1f7 --- /dev/null +++ b/images/icons/cf_icon_power_white.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/js/gui.js b/js/gui.js index bd28f75d..1767ae8c 100644 --- a/js/gui.js +++ b/js/gui.js @@ -21,6 +21,7 @@ var GUI_control = function () { 'failsafe', 'transponder', 'osd', + 'power', 'adjustments', 'auxiliary', 'cli', diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js index f3245091..e2d47803 100644 --- a/js/msp/MSPHelper.js +++ b/js/msp/MSPHelper.js @@ -158,27 +158,29 @@ MspHelper.prototype.process_data = function(dataHandler) { ANALOG.amperage = data.read16() / 100; // A ANALOG.last_received_timestamp = Date.now(); break; -// case MSPCodes.MSP_VOLTAGE_METERS: -// VOLTAGE_METERS = []; -// for (var i = 0; i < (message_length); i++) { -// var voltageMeter = {}; -// voltageMeter.voltage = data.readU8() / 10.0; -// -// VOLTAGE_METERS.push(voltageMeter) -// } -// break; -// case MSPCodes.MSP_CURRENT_METERS: -// CURRENT_METERS = []; -// for (var i = 0; i < (message_length / 6); i++) { -// var amperageMeter = {}; -// amperageMeter.amperage = data.read16() / 1000; // A -// offset += 2; -// amperageMeter.mAhDrawn = data.readU32(); // A -// offset += 4; -// -// CURRENT_METERS.push(amperageMeter); -// } -// break; + case MSPCodes.MSP_VOLTAGE_METERS: + VOLTAGE_METERS = []; + var voltageMeterLength = 2; + for (var i = 0; i < (data.byteLength / voltageMeterLength); i++) { + var voltageMeter = {}; + voltageMeter.id = data.readU8(); + voltageMeter.voltage = data.readU8() / 10.0; + + VOLTAGE_METERS.push(voltageMeter) + } + break; + case MSPCodes.MSP_CURRENT_METERS: + CURRENT_METERS = []; + var currentMeterLength = 5; + for (var i = 0; i < (data.byteLength / currentMeterLength); i++) { + var currentMeter = {}; + currentMeter.id = data.readU8(); + currentMeter.mAhDrawn = data.readU16(); // mAh + currentMeter.amperage = data.readU16() / 1000; // A + + CURRENT_METERS.push(currentMeter); + } + break; case MSPCodes.MSP_BATTERY_STATE: BATTERY_STATE.cellCount = data.readU8(); BATTERY_STATE.capacity = data.readU16(); // mAh @@ -1232,7 +1234,7 @@ MspHelper.prototype.crunch = function(code) { buffer.push8(Math.round(BATTERY_CONFIG.vbatmincellvoltage * 10)) .push8(Math.round(BATTERY_CONFIG.vbatmaxcellvoltage * 10)) .push8(Math.round(BATTERY_CONFIG.vbatwarningcellvoltage * 10)) - .push16(BATTERY_CONFIG.batterycapacity) + .push16(BATTERY_CONFIG.capacity) .push8(BATTERY_CONFIG.voltageMeterSource) .push8(BATTERY_CONFIG.currentMeterSource); break; diff --git a/main.css b/main.css index 5255facc..ca7290c6 100644 --- a/main.css +++ b/main.css @@ -811,6 +811,19 @@ li.active .ic_transponder { background-image: url(images/icons/icon_osd_white.svg); } +.ic_power { + background-image: url(images/icons/cf_icon_power_grey.svg); + background-position-y: 9px; +} + +.ic_power:hover { + background-image: url(images/icons/cf_icon_power_white.svg); +} + +li.active .ic_power { + background-image: url(images/icons/cf_icon_power_white.svg); +} + /* SPARE Tab-Icons */ .ic_failsafe { background-image: url(images/icons/cf_icon_failsafe_grey.svg); diff --git a/main.html b/main.html index 8937488d..d3d187fe 100755 --- a/main.html +++ b/main.html @@ -27,6 +27,7 @@ + @@ -87,6 +88,7 @@ + @@ -216,6 +218,8 @@
  • +
  • +
    + + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +

    +
    +
    +
    +
    +
    + +
    +
    + + +
    + + + + + + + + +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    ?
    + +
    +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/tabs/power.js b/tabs/power.js new file mode 100644 index 00000000..142ff05f --- /dev/null +++ b/tabs/power.js @@ -0,0 +1,275 @@ +'use strict'; + +TABS.power = { + supported: false, +}; + +TABS.power.initialize = function (callback) { + var self = this; + + if (GUI.active_tab != 'power') { + GUI.active_tab = 'power'; + googleAnalytics.sendAppView('Power'); + } + + function load_status() { + MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_voltage_meters); + } + + function load_voltage_meters() { + MSP.send_message(MSPCodes.MSP_VOLTAGE_METERS, false, false, load_current_meters); + } + + function load_current_meters() { + MSP.send_message(MSPCodes.MSP_CURRENT_METERS, false, false, load_current_meter_configs); + } + + function load_current_meter_configs() { + MSP.send_message(MSPCodes.MSP_CURRENT_METER_CONFIG, false, false, load_voltage_meter_configs); + } + + function load_voltage_meter_configs() { + MSP.send_message(MSPCodes.MSP_VOLTAGE_METER_CONFIG, false, false, load_battery_state); + } + + function load_battery_state() { + MSP.send_message(MSPCodes.MSP_BATTERY_STATE, false, false, load_battery_config); + } + + function load_battery_config() { + MSP.send_message(MSPCodes.MSP_BATTERY_CONFIG, false, false, load_html); + } + + function load_html() { + $('#content').load("./tabs/power.html", process_html); + } + + this.supported = semver.gte(CONFIG.apiVersion, "1.22.0"); + + if (!this.supported) { + load_html(); + } else { + load_status(); + } + + function update_ui() { + if (!TABS.power.supported) { + $(".tab-power").removeClass("supported"); + return; + } + $(".tab-power").addClass("supported"); + + // voltage meters + + var template = $('#tab-power-templates .voltage-meters .voltage-meter'); + var destination = $('.tab-power .voltage-meters'); + + for (var index = 0; index < VOLTAGE_METERS.length; index++) { + var meterElement = template.clone(); + $(meterElement).attr('id', 'voltage-meter-' + index); + + var message = chrome.i18n.getMessage('powerVoltageId' + VOLTAGE_METERS[index].id); + $(meterElement).find('.label').text(message) + destination.append(meterElement); + } + + var template = $('#tab-power-templates .voltage-configuration'); + for (var index = 0; index < VOLTAGE_METER_CONFIGS.length; index++) { + var destination = $('#voltage-meter-' + index + ' .configuration'); + var element = template.clone(); + + var attributeNames = ["vbatscale", "vbatresdivval", "vbatresdivmultiplier"]; + for (let attributeName of attributeNames) { + $(element).find('input[name="' + attributeName + '"]').attr('name', attributeName + '-' + index); + } + destination.append(element); + + $('input[name="vbatscale-' + index + '"]').val(VOLTAGE_METER_CONFIGS[index].vbatscale).attr('disabled','disabled'); + $('input[name="vbatresdivval-' + index + '"]').val(VOLTAGE_METER_CONFIGS[index].vbatresdivval).attr('disabled','disabled'); + $('input[name="vbatresdivmultiplier-' + index + '"]').val(VOLTAGE_METER_CONFIGS[index].vbatresdivmultiplier).attr('disabled','disabled'); + } + + // amperage meters + + var template = $('#tab-power-templates .amperage-meters .amperage-meter'); + var destination = $('.tab-power .amperage-meters'); + + for (var index = 0; index < CURRENT_METERS.length; index++) { + var meterElement = template.clone(); + $(meterElement).attr('id', 'amperage-meter-' + index); + + var message = chrome.i18n.getMessage('powerAmperageId' + CURRENT_METERS[index].id); + $(meterElement).find('.label').text(message) + destination.append(meterElement); + } + + var template = $('#tab-power-templates .amperage-configuration'); + for (var index = 0; index < CURRENT_METER_CONFIGS.length; index++) { + var destination = $('#amperage-meter-' + index + ' .configuration'); + var element = template.clone(); + + var attributeNames = ["amperagescale", "amperageoffset"]; + for (let attributeName of attributeNames) { + $(element).find('input[name="' + attributeName + '"]').attr('name', attributeName + '-' + index); + } + destination.append(element); + + $('input[name="amperagescale-' + index + '"]').val(CURRENT_METER_CONFIGS[index].scale).attr('disabled','disabled'); + $('input[name="amperageoffset-' + index + '"]').val(CURRENT_METER_CONFIGS[index].offset).attr('disabled','disabled'); + } + + + // battery + + var template = $('#tab-power-templates .battery-states .battery-state'); + var destination = $('.tab-power .battery-state'); + var element = template.clone(); + $(element).find('.connection-state').attr('id', 'battery-connection-state'); + $(element).find('.voltage').attr('id', 'battery-voltage'); + $(element).find('.mah-drawn').attr('id', 'battery-mah-drawn'); + $(element).find('.amperage').attr('id', 'battery-amperage'); + + destination.append(element.children()); + + var template = $('#tab-power-templates .battery-configuration'); + var destination = $('.tab-power .battery .configuration'); + var element = template.clone(); + destination.append(element); + + $('input[name="mincellvoltage"]').val(BATTERY_CONFIG.vbatmincellvoltage); + $('input[name="maxcellvoltage"]').val(BATTERY_CONFIG.vbatmaxcellvoltage); + $('input[name="warningcellvoltage"]').val(BATTERY_CONFIG.vbatwarningcellvoltage); + $('input[name="capacity"]').val(BATTERY_CONFIG.capacity); + + var batteryMeterTypes = [ + 'None', + 'Onboard ADC', + 'ESC Sensor' + ]; + + var batteryMeterType_e = $('select.batterymetersource'); + for (var i = 0; i < batteryMeterTypes.length; i++) { + batteryMeterType_e.append(''); + } + + batteryMeterType_e.change(function () { + BATTERY_CONFIG.voltageMeterSource = parseInt($(this).val()); + }); + batteryMeterType_e.val(BATTERY_CONFIG.voltageMeterSource).change(); + + // fill current + var currentMeterTypes = [ + 'None', + 'Onboard ADC', + 'Virtual', + 'ESC Sensor' + ]; + + var currentMeterType_e = $('select.currentmetersource'); + for (var i = 0; i < currentMeterTypes.length; i++) { + currentMeterType_e.append(''); + } + + currentMeterType_e.change(function () { + BATTERY_CONFIG.currentMeterSource = parseInt($(this).val()); + }); + currentMeterType_e.val(BATTERY_CONFIG.currentMeterSource).change(); + + + + function get_slow_data() { + MSP.send_message(MSPCodes.MSP_VOLTAGE_METERS, false, false, function () { + for (var i = 0; i < VOLTAGE_METERS.length; i++) { + var elementName = '#voltage-meter-' + i + ' .value'; + var element = $(elementName); + element.text(chrome.i18n.getMessage('powerVoltageValue', [VOLTAGE_METERS[i].voltage])); + } + }); + + MSP.send_message(MSPCodes.MSP_CURRENT_METERS, false, false, function () { + for (var i = 0; i < CURRENT_METERS.length; i++) { + var elementName = '#amperage-meter-' + i + ' .value'; + var element = $(elementName); + element.text(chrome.i18n.getMessage('powerAmperageValue', [CURRENT_METERS[i].amperage.toFixed(2)])); + } + }); + + MSP.send_message(MSPCodes.MSP_BATTERY_STATE, false, false, function () { + var elementPrefix = '#battery'; + var element; + + element = $(elementPrefix + '-connection-state .value'); + element.text(BATTERY_STATE.cellCount > 0 ? chrome.i18n.getMessage('powerBatteryConnectedValueYes', [BATTERY_STATE.cellCount]) : chrome.i18n.getMessage('powerBatteryConnectedValueNo')); + element = $(elementPrefix + '-voltage .value'); + element.text(chrome.i18n.getMessage('powerVoltageValue', [BATTERY_STATE.voltage])); + element = $(elementPrefix + '-mah-drawn .value'); + element.text(chrome.i18n.getMessage('powerMahValue', [BATTERY_STATE.mAhDrawn])); + element = $(elementPrefix + '-amperage .value'); + element.text(chrome.i18n.getMessage('powerAmperageValue', [BATTERY_STATE.amperage])); + }); + + } + + $('a.save').click(function () { + + /* FIXME update for api 1.33.0 + for (var index = 0; index < VOLTAGE_METER_CONFIGS.length; index++) { + VOLTAGE_METER_CONFIGS[index].vbatscale = parseInt($('input[name="vbatscale-' + index + '"]').val()); + VOLTAGE_METER_CONFIGS[index].vbatresdivval = parseInt($('input[name="vbatresdivval-' + index + '"]').val()); + VOLTAGE_METER_CONFIGS[index].vbatresdivmultiplier = parseInt($('input[name="vbatresdivmultiplier-' + index + '"]').val()); + } + + for (var index = 0; index < CURRENT_METER_CONFIGS.length; index++) { + CURRENT_METER_CONFIGS[index].scale = parseInt($('input[name="amperagescale-' + index + '"]').val()); + CURRENT_METER_CONFIGS[index].offset = parseInt($('input[name="amperageoffset-' + index + '"]').val()); + } + */ + + BATTERY_CONFIG.vbatmincellvoltage = parseFloat($('input[name="mincellvoltage"]').val()); + BATTERY_CONFIG.vbatmaxcellvoltage = parseFloat($('input[name="maxcellvoltage"]').val()); + BATTERY_CONFIG.vbatwarningcellvoltage = parseFloat($('input[name="warningcellvoltage"]').val()); + BATTERY_CONFIG.capacity = parseInt($('input[name="capacity"]').val()); + + /* FIXME update for api 1.33.0 + function save_voltage_config() { + MSP.sendVoltageMeterConfigs(save_amperage_config); + } + + function save_amperage_config() { + MSP.sendAmperageMeterConfigs(save_battery_config); + } + */ + + function save_battery_config() { + MSP.send_message(MSPCodes.MSP_SET_BATTERY_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BATTERY_CONFIG), false, save_to_eeprom); + } + + function save_to_eeprom() { + MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, save_completed); + } + + function save_completed() { + GUI.log(chrome.i18n.getMessage('configurationEepromSaved')); + + TABS.power.initialize(); + } + + save_battery_config(); + }); + + GUI.interval_add('setup_data_pull_slow', get_slow_data, 200, true); // 5hz + } + + function process_html() { + update_ui(); + + // translate to user-selected language + localize(); + + GUI.content_ready(callback); + } +}; + +TABS.power.cleanup = function (callback) { + if (callback) callback(); +};