diff --git a/QGCApplication.pro b/QGCApplication.pro
index 469e2400026bc93730a4abcc7f6b4a2dce5fbce9..15517ec3ea684caf76f42cabb2626f8e94038abc 100644
--- a/QGCApplication.pro
+++ b/QGCApplication.pro
@@ -565,6 +565,7 @@ HEADERS+= \
     src/AutoPilotPlugins/PX4/FlightModesComponent.h \
     src/AutoPilotPlugins/PX4/FlightModesComponentController.h \
     src/AutoPilotPlugins/PX4/PowerComponent.h \
+    src/AutoPilotPlugins/PX4/PowerComponentController.h \
     src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h \
     src/AutoPilotPlugins/PX4/PX4Component.h \
     src/AutoPilotPlugins/PX4/PX4ParameterLoader.h \
@@ -593,6 +594,7 @@ SOURCES += \
     src/AutoPilotPlugins/PX4/FlightModesComponent.cc \
     src/AutoPilotPlugins/PX4/FlightModesComponentController.cc \
     src/AutoPilotPlugins/PX4/PowerComponent.cc \
+    src/AutoPilotPlugins/PX4/PowerComponentController.cc \
     src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc \
     src/AutoPilotPlugins/PX4/PX4Component.cc \
     src/AutoPilotPlugins/PX4/PX4ParameterLoader.cc \
diff --git a/src/AutoPilotPlugins/PX4/PowerComponent.qml b/src/AutoPilotPlugins/PX4/PowerComponent.qml
index 61378e93c0ca0b6eaa1cdbeb7a90627526920385..f0c1b68a38c078485da9f11b00304cc878f5fec0 100644
--- a/src/AutoPilotPlugins/PX4/PowerComponent.qml
+++ b/src/AutoPilotPlugins/PX4/PowerComponent.qml
@@ -27,266 +27,321 @@
 
 import QtQuick 2.2
 import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
+import QtQuick.Dialogs 1.2
 
 import QGroundControl.FactSystem 1.0
 import QGroundControl.FactControls 1.0
 import QGroundControl.Palette 1.0
 import QGroundControl.Controls 1.0
 import QGroundControl.ScreenTools 1.0
+import QGroundControl.Controllers 1.0
 
-Rectangle {
-    QGCPalette { id: palette; colorGroupEnabled: true }
-
-    id: powerSettings
-    width:  600
-    height: 600
-    color:  palette.window
-
-    property int firstColumnWidth: 220
-    property int textEditWidth:    80
-
-    property Fact battNumCells: Fact { name: "BAT_N_CELLS" }
-    property Fact battHighVolt: Fact { name: "BAT_V_CHARGED" }
-    property Fact battLowVolt:  Fact { name: "BAT_V_EMPTY" }
-
-    property alias battHigh: battHighRow
-    property alias battLow:  battLowRow
-
-    function getBatteryImage()
-    {
-        switch(battNumCells.value) {
-            case 1:  return "/qml/PowerComponentBattery_01cell.svg";
-            case 2:  return "/qml/PowerComponentBattery_02cell.svg"
-            case 3:  return "/qml/PowerComponentBattery_03cell.svg"
-            case 4:  return "/qml/PowerComponentBattery_04cell.svg"
-            case 5:  return "/qml/PowerComponentBattery_05cell.svg"
-            case 6:  return "/qml/PowerComponentBattery_06cell.svg"
-            default: return "/qml/PowerComponentBattery_01cell.svg";
-        }
-    }
-
-    function drawArrowhead(ctx, x, y, radians)
-    {
-        ctx.save();
-        ctx.beginPath();
-        ctx.translate(x,y);
-        ctx.rotate(radians);
-        ctx.moveTo(0,0);
-        ctx.lineTo(5,10);
-        ctx.lineTo(-5,10);
-        ctx.closePath();
-        ctx.restore();
-        ctx.fill();
-    }
-
-    function drawLineWithArrow(ctx, x1, y1, x2, y2)
-    {
-        ctx.beginPath();
-        ctx.moveTo(x1, y1);
-        ctx.lineTo(x2, y2);
-        ctx.stroke();
-        var rd = Math.atan((y2 - y1) / (x2 - x1));
-        rd += ((x2 > x1) ? 90 : -90) * Math.PI/180;
-        drawArrowhead(ctx, x2, y2, rd);
-    }
-
-    Column {
-        anchors.fill: parent
-        spacing: 10
-
-        QGCLabel {
-            text: "POWER CONFIG"
-            font.pointSize: ScreenTools.fontPointFactor * (20);
-        }
-
-        QGCLabel {
-            text: "Battery"
-            color: palette.text
-            font.pointSize: ScreenTools.fontPointFactor * (20);
-        }
-
-        Rectangle {
-            width: parent.width
-            height: 120
-            color: palette.windowShade
+QGCView {
+    id:             rootQGCView
+    viewComponent:  view
+
+    Component {
+        id: view
+
+        QGCViewPanel {
+            id: viewPanel
+
+            QGCPalette { id: palette; colorGroupEnabled: enabled }
+
+            width:  600
+            height: 600
+            color:  palette.window
+
+            property int firstColumnWidth: 220
+            property int textEditWidth:    80
+
+            property Fact battNumCells: Fact { name: "BAT_N_CELLS"; onFactMissing: showMissingFactOverlay(name) }
+            property Fact battHighVolt: Fact { name: "BAT_V_CHARGED"; onFactMissing: showMissingFactOverlay(name) }
+            property Fact battLowVolt:  Fact { name: "BAT_V_EMPTY"; onFactMissing: showMissingFactOverlay(name) }
+
+            property alias battHigh: battHighRow
+            property alias battLow:  battLowRow
+
+            function getBatteryImage()
+            {
+                switch(battNumCells.value) {
+                    case 1:  return "/qml/PowerComponentBattery_01cell.svg";
+                    case 2:  return "/qml/PowerComponentBattery_02cell.svg"
+                    case 3:  return "/qml/PowerComponentBattery_03cell.svg"
+                    case 4:  return "/qml/PowerComponentBattery_04cell.svg"
+                    case 5:  return "/qml/PowerComponentBattery_05cell.svg"
+                    case 6:  return "/qml/PowerComponentBattery_06cell.svg"
+                    default: return "/qml/PowerComponentBattery_01cell.svg";
+                }
+            }
+
+            function drawArrowhead(ctx, x, y, radians)
+            {
+                ctx.save();
+                ctx.beginPath();
+                ctx.translate(x,y);
+                ctx.rotate(radians);
+                ctx.moveTo(0,0);
+                ctx.lineTo(5,10);
+                ctx.lineTo(-5,10);
+                ctx.closePath();
+                ctx.restore();
+                ctx.fill();
+            }
+
+            function drawLineWithArrow(ctx, x1, y1, x2, y2)
+            {
+                ctx.beginPath();
+                ctx.moveTo(x1, y1);
+                ctx.lineTo(x2, y2);
+                ctx.stroke();
+                var rd = Math.atan((y2 - y1) / (x2 - x1));
+                rd += ((x2 > x1) ? 90 : -90) * Math.PI/180;
+                drawArrowhead(ctx, x2, y2, rd);
+            }
+
+            PowerComponentController {
+                id:         controller
+                factPanel:  viewPanel
+
+                onOldFirmware:          showMessage("ESC Calibration", "QGroundControl cannot perform ESC Calibration with this version of firmware. You will need to upgrade to a newer firmware.", StandardButton.Ok)
+                onNewerFirmware:        showMessage("ESC Calibration", "QGroundControl cannot perform ESC Calibration with this version of firmware. You will need to upgrade QGroundControl.", StandardButton.Ok)
+                onBatteryConnected:     showMessage("ESC Calibration", "Performing calibration. This will take a few seconds..", 0)
+                onCalibrationFailed:    showMessage("ESC Calibration failed", errorMessage, StandardButton.Ok)
+                onCalibrationSuccess:   showMessage("ESC Calibration", "Calibration complete. You can disconnect your battery now if you like.", StandardButton.Ok)
+                onConnectBattery:       showMessage("ESC Calibration", "WARNING: Props must be removed from vehicle prior to performing ESC calibration.\n\nConnect the battery now and calibration will begin.", 0)
+            }
 
             Column {
-                id: batteryColumn
+                anchors.fill: parent
                 spacing: 10
-                anchors.verticalCenter: parent.verticalCenter
-                x: (parent.x + 20)
 
-                Row {
-                    spacing: 10
+                QGCLabel {
+                    text: "POWER CONFIG"
+                    font.pointSize: ScreenTools.largeFontPointSize
+                }
+
+                QGCLabel {
+                    text: "Battery"
+                    color: palette.text
+                    font.pointSize: ScreenTools.mediumFontPointSize
+                }
+
+                Rectangle {
+                    width: parent.width
+                    height: 120
+                    color: palette.windowShade
+
                     Column {
-                        id: voltageCol
+                        id: batteryColumn
                         spacing: 10
+                        anchors.verticalCenter: parent.verticalCenter
+                        x: (parent.x + 20)
+
                         Row {
                             spacing: 10
-                            QGCLabel { text: "Number of Cells (in Series)"; width: firstColumnWidth; anchors.baseline: cellsField.baseline}
-                            FactTextField {
-                                id: cellsField
-                                width: textEditWidth
-                                fact: Fact { name: "BAT_N_CELLS" }
-                                showUnits: true
+                            Column {
+                                id: voltageCol
+                                spacing: 10
+                                Row {
+                                    spacing: 10
+                                    QGCLabel { text: "Number of Cells (in Series)"; width: firstColumnWidth; anchors.baseline: cellsField.baseline}
+                                    FactTextField {
+                                        id: cellsField
+                                        width: textEditWidth
+                                        fact: Fact { name: "BAT_N_CELLS"; onFactMissing: showMissingFactOverlay(name) }
+                                        showUnits: true
+                                    }
+                                }
+                                Row {
+                                    id: battHighRow
+                                    spacing: 10
+                                    QGCLabel { text: "Full Voltage (per cell)"; width: firstColumnWidth; anchors.baseline: battHighField.baseline}
+                                    FactTextField {
+                                        id: battHighField
+                                        width: textEditWidth
+                                        fact: Fact { name: "BAT_V_CHARGED"; onFactMissing: showMissingFactOverlay(name) }
+                                        showUnits: true
+                                    }
+                                }
+                                Row {
+                                    id: battLowRow
+                                    spacing: 10
+                                    QGCLabel { text: "Empty Voltage (per cell)"; width: firstColumnWidth; anchors.baseline: battLowField.baseline}
+                                    FactTextField {
+                                        id: battLowField
+                                        width: textEditWidth
+                                        fact: Fact { name: "BAT_V_EMPTY"; onFactMissing: showMissingFactOverlay(name) }
+                                        showUnits: true
+                                    }
+                                }
                             }
-                        }
-                        Row {
-                            id: battHighRow
-                            spacing: 10
-                            QGCLabel { text: "Full Voltage (per cell)"; width: firstColumnWidth; anchors.baseline: battHighField.baseline}
-                            FactTextField {
-                                id: battHighField
-                                width: textEditWidth
-                                fact: Fact { name: "BAT_V_CHARGED" }
-                                showUnits: true
+                            Canvas {
+                                id: arrows
+                                height: voltageCol.height
+                                width: 40
+                                antialiasing: true
+                                Connections {
+                                    target: ScreenTools
+                                    onRepaintRequestedChanged: {
+                                        arrows.requestPaint();
+                                    }
+                                }
+                                onPaint: {
+                                    var y0 = voltageCol.mapFromItem(battHigh, 0, battHigh.height / 2).y;
+                                    var y1 = voltageCol.mapFromItem(battLow,  0, battLow.height  / 2).y;
+                                    var context = getContext("2d");
+                                    context.reset();
+                                    context.strokeStyle = palette.button;
+                                    context.fillStyle   = palette.button;
+                                    drawLineWithArrow(context, 0, y0, width, height * 0.25);
+                                    drawLineWithArrow(context, 0, y1, width, height * 0.85);
+                                }
                             }
-                        }
-                        Row {
-                            id: battLowRow
-                            spacing: 10
-                            QGCLabel { text: "Empty Voltage (per cell)"; width: firstColumnWidth; anchors.baseline: battLowField.baseline}
-                            FactTextField {
-                                id: battLowField
-                                width: textEditWidth
-                                fact: Fact { name: "BAT_V_EMPTY" }
-                                showUnits: true
+                            QGCColoredImage {
+                                height:   voltageCol.height
+                                width:    voltageCol.height * 0.75
+                                source:   getBatteryImage();
+                                fillMode: Image.PreserveAspectFit
+                                smooth:   true
+                                color:    palette.button
+                                cache:    false
+                            }
+                            Item { width: 20; height: 1; }
+                            Column {
+                                spacing: 10
+                                anchors.verticalCenter: parent.verticalCenter
+                                Row {
+                                    spacing: 10
+                                    QGCLabel {
+                                        text: "Battery Max:"
+                                        color: palette.text
+                                        width: 80
+                                    }
+                                    QGCLabel {
+                                        text: (battNumCells.value * battHighVolt.value).toFixed(1) + ' V'
+                                        color: palette.text
+                                    }
+                                }
+                                Row {
+                                    spacing: 10
+                                    QGCLabel {
+                                        text: "Battery Min:"
+                                        color: palette.text
+                                        width: 80
+                                    }
+                                    QGCLabel {
+                                        text: (battNumCells.value * battLowVolt.value).toFixed(1) + ' V'
+                                        color: palette.text
+                                    }
+                                }
                             }
                         }
                     }
-                    Canvas {
-                        id: arrows
-                        height: voltageCol.height
-                        width: 40
-                        antialiasing: true
-                        Connections {
-                            target: ScreenTools
-                            onRepaintRequestedChanged: {
-                                arrows.requestPaint();
-                            }
+                }
+
+                QGCLabel {
+                    text:           "ESC Calibration"
+                    font.pointSize: ScreenTools.mediumFontPointSize
+                }
+
+                Rectangle {
+                    width:              parent.width
+                    height:             80
+                    color:              palette.windowShade
+
+                    Column {
+                        anchors.margins:    10
+                        anchors.left:       parent.left
+                        anchors.right:      parent.right
+                        anchors.top:        parent.top
+                        anchors.bottom:     calibrateButton.bottom
+                        spacing:            10
+
+                        QGCLabel {
+                            text: "WARNING: Props must be removed from vehicle prior to performing ESC calibration."
                         }
-                        onPaint: {
-                            var y0 = voltageCol.mapFromItem(battHigh, 0, battHigh.height / 2).y;
-                            var y1 = voltageCol.mapFromItem(battLow,  0, battLow.height  / 2).y;
-                            var context = getContext("2d");
-                            context.reset();
-                            context.strokeStyle = palette.button;
-                            context.fillStyle   = palette.button;
-                            drawLineWithArrow(context, 0, y0, width, height * 0.25);
-                            drawLineWithArrow(context, 0, y1, width, height * 0.85);
+
+                        QGCButton {
+                            id:         calibrateButton
+                            text:       "Calibrate"
+                            onClicked:  controller.calibrateEsc()
                         }
                     }
-                    QGCColoredImage {
-                        height:   voltageCol.height
-                        width:    voltageCol.height * 0.75
-                        source:   getBatteryImage();
-                        fillMode: Image.PreserveAspectFit
-                        smooth:   true
-                        color:    palette.button
-                        cache:    false
+                }
+
+                /*
+                 * This is disabled for now
+                Row {
+                    width: parent.width
+                    spacing: 30
+                    visible: showAdvanced.checked
+                    Column {
+                        spacing: 10
+                        width: (parent.width / 2) - 5
+                        QGCLabel {
+                            text: "Propeller Function"
+                            color: palette.text
+                            font.pointSize: ScreenTools.fontPointFactor * (20);
+                        }
+                        Rectangle {
+                            width: parent.width
+                            height: 160
+                            color: palette.windowShade
+                        }
                     }
-                    Item { width: 20; height: 1; }
                     Column {
                         spacing: 10
-                        anchors.verticalCenter: parent.verticalCenter
-                        Row {
-                            spacing: 10
-                            QGCLabel {
-                                text: "Battery Max:"
-                                color: palette.text
-                                width: 80
-                            }
-                            QGCLabel {
-                                text: (battNumCells.value * battHighVolt.value).toFixed(1) + ' V'
-                                color: palette.text
-                            }
+                        width: (parent.width / 2) - 5
+                        QGCLabel {
+                            text: "Magnetometer Distortion"
+                            color: palette.text
+                            font.pointSize: ScreenTools.fontPointFactor * (20);
                         }
-                        Row {
-                            spacing: 10
-                            QGCLabel {
-                                text: "Battery Min:"
-                                color: palette.text
-                                width: 80
-                            }
-                            QGCLabel {
-                                text: (battNumCells.value * battLowVolt.value).toFixed(1) + ' V'
-                                color: palette.text
-                            }
+                        Rectangle {
+                            width: parent.width
+                            height: 160
+                            color: palette.windowShade
                         }
+
                     }
                 }
-            }
-        }
-        /*
-         * This is disabled for now
-        Row {
-            width: parent.width
-            spacing: 30
-            visible: showAdvanced.checked
-            Column {
-                spacing: 10
-                width: (parent.width / 2) - 5
-                QGCLabel {
-                    text: "Propeller Function"
-                    color: palette.text
-                    font.pointSize: ScreenTools.fontPointFactor * (20);
-                }
-                Rectangle {
-                    width: parent.width
-                    height: 160
-                    color: palette.windowShade
+                */
+
+                //-- Advanced Settings
+                QGCCheckBox {
+                    id: showAdvanced
+                    text: "Show Advanced Settings"
                 }
-            }
-            Column {
-                spacing: 10
-                width: (parent.width / 2) - 5
                 QGCLabel {
-                    text: "Magnetometer Distortion"
+                    text: "Advanced Power Settings"
                     color: palette.text
                     font.pointSize: ScreenTools.fontPointFactor * (20);
+                    visible: showAdvanced.checked
                 }
                 Rectangle {
                     width: parent.width
-                    height: 160
+                    height: 40
                     color: palette.windowShade
-                }
-
-            }
-        }
-        */
-        //-- Advanced Settings
-        QGCCheckBox {
-            id: showAdvanced
-            text: "Show Advanced Settings"
-        }
-        QGCLabel {
-            text: "Advanced Power Settings"
-            color: palette.text
-            font.pointSize: ScreenTools.fontPointFactor * (20);
-            visible: showAdvanced.checked
-        }
-        Rectangle {
-            width: parent.width
-            height: 40
-            color: palette.windowShade
-            visible: showAdvanced.checked
-            Column {
-                id: advBatteryColumn
-                spacing: 10
-                anchors.verticalCenter: parent.verticalCenter
-                x: (parent.x + 20)
-                Row {
-                    spacing: 10
-                    QGCLabel { text: "Voltage Drop on Full Load (per cell)"; width: firstColumnWidth; anchors.baseline: battDropField.baseline}
-                    FactTextField {
-                        id: battDropField
-                        width: textEditWidth
-                        fact: Fact { name: "BAT_V_LOAD_DROP" }
-                        showUnits: true
+                    visible: showAdvanced.checked
+                    Column {
+                        id: advBatteryColumn
+                        spacing: 10
+                        anchors.verticalCenter: parent.verticalCenter
+                        x: (parent.x + 20)
+                        Row {
+                            spacing: 10
+                            QGCLabel { text: "Voltage Drop on Full Load (per cell)"; width: firstColumnWidth; anchors.baseline: battDropField.baseline}
+                            FactTextField {
+                                id: battDropField
+                                width: textEditWidth
+                                fact: Fact { name: "BAT_V_LOAD_DROP"; onFactMissing: showMissingFactOverlay(name) }
+                                showUnits: true
+                            }
+                        }
                     }
                 }
-            }
-        }
-    }
+            } // Column
+        } // QGCViewPanel
+    } // Component - view
 }
diff --git a/src/AutoPilotPlugins/PX4/PowerComponentController.cc b/src/AutoPilotPlugins/PX4/PowerComponentController.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4b2c076a5c62a0605dcfce5e980b2626e31ef775
--- /dev/null
+++ b/src/AutoPilotPlugins/PX4/PowerComponentController.cc
@@ -0,0 +1,126 @@
+/*=====================================================================
+ 
+ QGroundControl Open Source Ground Control Station
+ 
+ (c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+ 
+ This file is part of the QGROUNDCONTROL project
+ 
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+ 
+ ======================================================================*/
+
+/// @file
+///     @author Don Gagne <don@thegagnes.com>
+
+#include "PowerComponentController.h"
+#include "QGCMAVLink.h"
+#include "UASManager.h"
+#include "QGCMessageBox.h"
+
+#include <QVariant>
+#include <QQmlProperty>
+
+PowerComponentController::PowerComponentController(void)
+{
+
+}
+
+PowerComponentController::~PowerComponentController()
+{
+    _stopCalibration();
+}
+
+void PowerComponentController::calibrateEsc(void)
+{
+    _warningMessages.clear();
+    connect(_uas, &UASInterface::textMessageReceived, this, &PowerComponentController::_handleUASTextMessage);
+    _uas->startCalibration(UASInterface::StartCalibrationEsc);
+}
+
+void PowerComponentController::_stopCalibration(void)
+{
+    disconnect(_uas, &UASInterface::textMessageReceived, this, &PowerComponentController::_handleUASTextMessage);
+}
+
+void PowerComponentController::_handleUASTextMessage(int uasId, int compId, int severity, QString text)
+{
+    Q_UNUSED(compId);
+    Q_UNUSED(severity);
+    
+    UASInterface* uas = _autopilot->uas();
+    Q_ASSERT(uas);
+    if (uasId != uas->getUASID()) {
+        return;
+    }
+    
+    // All calibration messages start with [cal]
+    QString calPrefix("[cal] ");
+    if (!text.startsWith(calPrefix)) {
+        return;
+    }
+    text = text.right(text.length() - calPrefix.length());
+
+    // Make sure we can understand this firmware rev
+    QString calStartPrefix("calibration started: ");
+    if (text.startsWith(calStartPrefix)) {
+        text = text.right(text.length() - calStartPrefix.length());
+        
+        // Split version number and cal type
+        QStringList parts = text.split(" ");
+        if (parts.count() != 2) {
+            emit incorrectFirmwareRevReporting();
+            return;
+        }
+        
+        int firmwareRev = parts[0].toInt();
+        if (firmwareRev < _neededFirmwareRev) {
+            emit oldFirmware();
+            return;
+        }
+        if (firmwareRev > _neededFirmwareRev) {
+            emit newerFirmware();
+            return;
+        }
+    }
+
+    if (text == "Connect battery now") {
+        emit connectBattery();
+        return;
+    }
+    
+    if (text == "Battery connected") {
+        emit batteryConnected();
+        return;
+    }
+
+    QString failedPrefix("calibration failed: ");
+    if (text.startsWith(failedPrefix)) {
+        _stopCalibration();
+        emit calibrationFailed(text.right(text.length() - failedPrefix.length()));
+        return;
+    }
+    
+    QString calCompletePrefix("calibration done:");
+    if (text.startsWith(calCompletePrefix)) {
+        _stopCalibration();
+        emit calibrationSuccess(_warningMessages);
+        return;
+    }
+    
+    QString warningPrefix("calibration warning: ");
+    if (text.startsWith(warningPrefix)) {
+        _warningMessages << text.right(text.length() - warningPrefix.length());
+    }
+}
diff --git a/src/AutoPilotPlugins/PX4/PowerComponentController.h b/src/AutoPilotPlugins/PX4/PowerComponentController.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c7704575d4c747c59b8e07f12570e174a8834c5
--- /dev/null
+++ b/src/AutoPilotPlugins/PX4/PowerComponentController.h
@@ -0,0 +1,66 @@
+/*=====================================================================
+ 
+ QGroundControl Open Source Ground Control Station
+ 
+ (c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
+ 
+ This file is part of the QGROUNDCONTROL project
+ 
+ QGROUNDCONTROL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ QGROUNDCONTROL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
+ 
+ ======================================================================*/
+
+/// @file
+///     @author Don Gagne <don@thegagnes.com>
+
+#ifndef PowerComponentController_H
+#define PowerComponentController_H
+
+#include <QObject>
+#include <QQuickItem>
+
+#include "UASInterface.h"
+#include "FactPanelController.h"
+
+/// Power Component MVC Controller for PowerComponent.qml.
+class PowerComponentController : public FactPanelController
+{
+    Q_OBJECT
+    
+public:
+    PowerComponentController(void);
+    ~PowerComponentController();
+    
+    Q_INVOKABLE void calibrateEsc(void);
+    
+signals:
+    void oldFirmware(void);
+    void newerFirmware(void);
+    void incorrectFirmwareRevReporting(void);
+    void connectBattery(void);
+    void batteryConnected(void);
+    void calibrationFailed(const QString& errorMessage);
+    void calibrationSuccess(const QStringList& warningMessages);
+    
+private slots:
+    void _handleUASTextMessage(int uasId, int compId, int severity, QString text);
+    
+private:
+    void _stopCalibration(void);
+    
+    QStringList _warningMessages;
+    static const int _neededFirmwareRev = 1;
+};
+
+#endif
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index ff533442c10890e963cc79fe38803ea841437993..b5df4aa71bbb28daf9bce8baf72145f69f822059 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -65,6 +65,7 @@
 #include "FlightModesComponentController.h"
 #include "AirframeComponentController.h"
 #include "SensorsComponentController.h"
+#include "PowerComponentController.h"
 
 #include "ScreenTools.h"
 #include "MavManager.h"
@@ -322,6 +323,7 @@ void QGCApplication::_initCommon(void)
     qmlRegisterType<FlightModesComponentController>("QGroundControl.Controllers", 1, 0, "FlightModesComponentController");
     qmlRegisterType<AirframeComponentController>("QGroundControl.Controllers", 1, 0, "AirframeComponentController");
     qmlRegisterType<SensorsComponentController>("QGroundControl.Controllers", 1, 0, "SensorsComponentController");
+    qmlRegisterType<PowerComponentController>("QGroundControl.Controllers", 1, 0, "PowerComponentController");
     
     //-- Create QML Singleton Interfaces
     qmlRegisterSingletonType<ScreenTools>("QGroundControl.ScreenTools", 1, 0, "ScreenTools", screenToolsSingletonFactory);
diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc
index 95622e68e6b5916f11e18c5a47f8eac8340c2b26..fabee6ee23a516d5409c35bfcc42b53450d1b234 100644
--- a/src/uas/UAS.cc
+++ b/src/uas/UAS.cc
@@ -1455,6 +1455,7 @@ void UAS::startCalibration(UASInterface::StartCalibrationType calType)
     int airspeedCal = 0;
     int radioCal = 0;
     int accelCal = 0;
+    int escCal = 0;
     
     switch (calType) {
         case StartCalibrationGyro:
@@ -1475,6 +1476,9 @@ void UAS::startCalibration(UASInterface::StartCalibrationType calType)
         case StartCalibrationLevel:
             accelCal = 2;
             break;
+        case StartCalibrationEsc:
+            escCal = 1;
+            break;
     }
     
     mavlink_message_t msg;
@@ -1491,7 +1495,7 @@ void UAS::startCalibration(UASInterface::StartCalibrationType calType)
                                   radioCal,                         // radio cal
                                   accelCal,                         // accel cal
                                   airspeedCal,                      // airspeed cal
-                                  0);                               // unused
+                                  escCal);                          // esc cal
     sendMessage(msg);
 }
 
diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h
index ecdf0683a73ca02db3f74ab3fefc8c70b7014fd7..c538a4ce4ce2fba9f64b1587c267d5d77ec959c3 100644
--- a/src/uas/UASInterface.h
+++ b/src/uas/UASInterface.h
@@ -244,7 +244,8 @@ public:
         StartCalibrationMag,
         StartCalibrationAirspeed,
         StartCalibrationAccel,
-        StartCalibrationLevel
+        StartCalibrationLevel,
+        StartCalibrationEsc
     };
     
     /// Starts the specified calibration