Set the power cap

Created toggle button to enable power cap and a text field to set
it. This form is similar to the set network form.
Moved logic for displaying the power cap as disabled to the
overview controller.

Resolves openbmc/openbmc#3221

Tested: Set the power cap on a Witherspoon
Change-Id: I62346fe3ed123b9df58d159cee2584937d46213c
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index a1fad8a..042dde4 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -1388,12 +1388,39 @@
                    withCredentials: true
                  })
               .then(function(response) {
-                var json = JSON.stringify(response.data);
-                var content = JSON.parse(json);
-
-                return (false == content.data.PowerCapEnable) ?
-                    Constants.POWER_CAP_TEXT.disabled :
-                    content.data.PowerCap + ' ' + Constants.POWER_CAP_TEXT.unit;
+                return response.data;
+              });
+        },
+        setPowerCapEnable: function(powerCapEnable) {
+          return $http({
+                   method: 'PUT',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCapEnable',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true,
+                   data: JSON.stringify({'data': powerCapEnable})
+                 })
+              .then(function(response) {
+                return response.data;
+              });
+        },
+        setPowerCap: function(powerCap) {
+          return $http({
+                   method: 'PUT',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCap',
+                   headers: {
+                     'Accept': 'application/json',
+                     'Content-Type': 'application/json'
+                   },
+                   withCredentials: true,
+                   data: JSON.stringify({'data': powerCap})
+                 })
+              .then(function(response) {
+                return response.data;
               });
         },
         setHostname: function(hostname) {
diff --git a/app/overview/controllers/system-overview-controller.js b/app/overview/controllers/system-overview-controller.js
index a16caf6..cb3f1ed 100644
--- a/app/overview/controllers/system-overview-controller.js
+++ b/app/overview/controllers/system-overview-controller.js
@@ -10,8 +10,8 @@
   'use strict';
 
   angular.module('app.overview').controller('systemOverviewController', [
-    '$scope', '$window', 'APIUtils', 'dataService', '$q',
-    function($scope, $window, APIUtils, dataService, $q) {
+    '$scope', '$window', 'APIUtils', 'dataService', 'Constants', '$q',
+    function($scope, $window, APIUtils, dataService, Constants, $q) {
       $scope.dataService = dataService;
       $scope.dropdown_selected = false;
       $scope.tmz = 'EDT';
@@ -88,7 +88,12 @@
 
         var getPowerCapPromise = APIUtils.getPowerCap().then(
             function(data) {
-              $scope.power_cap = data;
+              if (data.data.PowerCapEnable == false) {
+                $scope.power_cap = Constants.POWER_CAP_TEXT.disabled;
+              } else {
+                $scope.power_cap =
+                    data.data.PowerCap + ' ' + Constants.POWER_CAP_TEXT.unit;
+              }
             },
             function(error) {
               console.log(JSON.stringify(error));
diff --git a/app/server-control/controllers/power-usage-controller.html b/app/server-control/controllers/power-usage-controller.html
index c35ea93..793f5e9 100644
--- a/app/server-control/controllers/power-usage-controller.html
+++ b/app/server-control/controllers/power-usage-controller.html
@@ -1,22 +1,47 @@
 <loader loading="loading"></loader>
 <div id="power-usage">
-	<div class="row power__usage-metadata">
-		<div class="row column">
-			<h1>Manage Power Usage</h1>
-		</div>
-		<div class="page-header">
-			<h2 class="bold h4">Power information</h2>
-		</div>
-		<fieldset>
-			<div class="column large-8">
-				<ul class="power__usage-metadata-wrapper">
-					<li class="power__usage-metadata-block">
-						<p class="content-label">Power Consumption</p>
-						<p class="courier-bold">{{power_consumption}}</p>
-					</li>
-				</ul>
-			</div>
-		</fieldset>
+	<div class="row column">
+		<h1>Manage Power Usage</h1>
 	</div>
+	<form class="power-usage__form" role="form" action="">
+		<section class="row column">
+			<div class="page-header">
+				<h2 class="bold h4">Power information</h2>
+			</div>
+			<fieldset>
+					<ul class="power-usage__metadata-wrapper">
+						<li class="power-usage__metadata-block">
+							<p class="content-label">Power Consumption</p>
+							<p class="courier-bold">{{power_consumption}}</p>
+						</li>
+						<li class="power-usage__metadata-block">
+							<div class="toggle inline">
+								<input id="toggle__switch-round"
+												class="toggle-switch toggle-switch__round-flat"
+												type="checkbox"
+												tabindex="0"
+												ng-model="power_cap.PowerCapEnable"
+												ng-checked="power_cap.PowerCapEnable">
+								<label for="toggle__switch-round" tabindex="0">Server power cap setting is <span class="uid-switch__status">{{power_cap.PowerCapEnable ? "on" : "off"}}</span></label>
+							</div>
+							<div class="power-usage__switch-label inline">
+								<p>Server power cap setting is <span class="uid-switch__status">{{power_cap.PowerCapEnable ? "on" : "off"}}</span></p>
+								<p>Set a power cap to keep power consumption at or below the specified value in watts.</p>
+							</div>
+							<div class="small-12 large-4">
+								<p class="content-label power-cap-value-label">POWER CAP VALUE IN WATTS</p>
+								<input id="power-cap" type="number" min="100" max="10000" step="1" ng-disabled="!power_cap.PowerCapEnable"  ng-model="power_cap.PowerCap"/>
+							</div>
+						</li>
+					</ul>
+			</fieldset>
+			<div class="power-usage__submit-wrapper">
+				<button type="button" class="btn-primary inline" ng-click="setPowerCap()">Save settings</button>
+				<button type="button" class="btn-secondary inline" ng-click="refresh()">Cancel</button>
+			</div>
+			<p class="success-msg" ng-show="set_power_cap_success" role="alert">Success! Power cap changed!</p>
+			<p class="set_powercap_error error-msg" ng-show="set_power_cap_error" role="alert">Error setting Power Cap!</p>
+		</section>
+	</form>
 </div>
 
diff --git a/app/server-control/controllers/power-usage-controller.js b/app/server-control/controllers/power-usage-controller.js
index 5ba8bf0..f3042f9 100644
--- a/app/server-control/controllers/power-usage-controller.js
+++ b/app/server-control/controllers/power-usage-controller.js
@@ -10,15 +10,33 @@
   'use strict';
 
   angular.module('app.serverControl').controller('powerUsageController', [
-    '$scope', '$window', 'APIUtils', 'dataService', '$q',
-    function($scope, $window, APIUtils, dataService, $q) {
-      $scope.dataService = dataService;
+    '$scope', '$window', 'APIUtils', '$route', '$q',
+    function($scope, $window, APIUtils, $route, $q) {
       $scope.power_consumption = '';
+      $scope.power_cap = {};
+      $scope.set_power_cap_error = false;
+      $scope.set_power_cap_success = false;
       $scope.loading = false;
       loadPowerData();
 
       function loadPowerData() {
         $scope.loading = true;
+
+        var getPowerCapPromise = APIUtils.getPowerCap().then(
+            function(data) {
+              $scope.power_cap = data.data;
+              // TODO: openbmc/openbmc#3154 Rest server should return a proper
+              // JSON bool. Convert 0/1 to boolean in meantime.
+              if ($scope.power_cap.PowerCapEnable) {
+                $scope.power_cap.PowerCapEnable = true;
+              } else {
+                $scope.power_cap.PowerCapEnable = false;
+              }
+            },
+            function(error) {
+              console.log(JSON.stringify(error));
+            });
+
         var getPowerConsumptionPromise = APIUtils.getPowerConsumption().then(
             function(data) {
               $scope.power_consumption = data;
@@ -29,12 +47,60 @@
 
         var promises = [
           getPowerConsumptionPromise,
+          getPowerCapPromise,
         ];
 
         $q.all(promises).finally(function() {
           $scope.loading = false;
         });
       }
+
+      $scope.setPowerCap = function() {
+        $scope.set_power_cap_error = false;
+        $scope.set_power_cap_success = false;
+        // The power cap value will be undefined if outside range
+        if (!$scope.power_cap.PowerCap) {
+          $scope.set_power_cap_error = true;
+          return;
+        }
+        $scope.loading = true;
+        var promises = [
+          setPowerCapValue(),
+          setPowerCapEnable(),
+        ];
+
+        $q.all(promises).finally(function() {
+          $scope.loading = false;
+          if (!$scope.set_power_cap_error) {
+            $scope.set_power_cap_success = true;
+          }
+        });
+
+      };
+      $scope.refresh = function() {
+        $route.reload();
+      };
+
+      function setPowerCapValue() {
+        return APIUtils.setPowerCap($scope.power_cap.PowerCap)
+            .then(
+                function(data) {},
+                function(error) {
+                  $scope.set_power_cap_error = true;
+                  console.log(JSON.stringify(error));
+                });
+      }
+
+      function setPowerCapEnable() {
+        return APIUtils.setPowerCapEnable($scope.power_cap.PowerCapEnable)
+            .then(
+                function(data) {},
+                function(error) {
+                  $scope.set_power_cap_error = true;
+                  console.log(JSON.stringify(error));
+                });
+      }
+
     }
   ]);
 
diff --git a/app/server-control/styles/power-usage.scss b/app/server-control/styles/power-usage.scss
index 4c956e2..f45a510 100644
--- a/app/server-control/styles/power-usage.scss
+++ b/app/server-control/styles/power-usage.scss
@@ -1,25 +1,49 @@
 // Power Usage SCSS
+.power-usage__form {
 
-.power__usage-metadata {
-  border-bottom: 1px solid $medgrey;
-  padding: 1.8em 0 0 0;
-}
+  input {
+    height: 2.1em;
+    margin-bottom: 0em;
+  }
 
-.power__usage-metadata-wrapper {
-  margin: 0;
-  padding: 0;
-}
+  fieldset {
+    padding-left: 1.8em;
+  }
 
-.power__usage-metadata-block {
-  list-style-type: none;
-  min-width: 47%;
-  margin-bottom: 1.8em;
-  margin-right: .7em;
-  display: inline-block;
-  white-space: normal;
-  word-break: break-all;
-  @include mediaQuery(small) {
-    float: left;
+  .power-usage__switch-label {
+    padding-bottom: .5em;
+  }
+
+  .power-usage__switch-label p {
+    margin: 0;
+    &:first-child {font-weight: 700;}
+  }
+
+  .power-usage__metadata-wrapper {
+    margin: 0;
+    padding: 0;
+  }
+
+  .power-usage__metadata-block {
+    min-width: 47%;
+    margin-bottom: 1.8em;
+    margin-right: .7em;
+    display: inline-block;
+    white-space: normal;
+    word-break: break-all;
+    @include mediaQuery(small) {
+      float: left;
+    }
+  }
+
+  .power-usage__submit-wrapper {
+    width: 100%;
+    margin-top: 3em;
+    padding-top: 1em;
+    border-top: 1px solid $medgrey;
+    button {
+      float: right;
+      margin: .5em;
+    }
   }
 }
-