Chris Mullins пре 8 година
родитељ
комит
be13776f28
4 измењених фајлова са 104 додато и 6 уклоњено
  1. 21 0
      lib/Settings/Settings.cpp
  2. 12 1
      lib/Settings/Settings.h
  3. 1 1
      src/main.cpp
  4. 70 4
      web/index.html

+ 21 - 0
lib/Settings/Settings.cpp

@@ -14,6 +14,21 @@ void Settings::deserialize(Settings& settings, JsonObject& parsedSettings) {
     settings.adminPassword = parsedSettings.get<String>("admin_password");
     settings.cePin = parsedSettings["ce_pin"];
     settings.csnPin = parsedSettings["csn_pin"];
+    
+    JsonArray& arr = parsedSettings["device_ids"];
+    settings.updateDeviceIds(arr);
+  }
+}
+
+void Settings::updateDeviceIds(JsonArray& arr) {
+  if (arr.success()) {
+    if (this->deviceIds) {
+      delete this->deviceIds;
+    }
+    
+    this->deviceIds = new uint16_t[arr.size()];
+    this->numDeviceIds = arr.size();
+    arr.copyTo(this->deviceIds, arr.size());
   }
 }
 
@@ -56,6 +71,12 @@ void Settings::serialize(Stream& stream, const bool prettyPrint) {
   root["ce_pin"] = this->cePin;
   root["csn_pin"] = this->csnPin;
   
+  if (this->deviceIds) {
+    JsonArray& arr = jsonBuffer.createArray();
+    arr.copyFrom(this->deviceIds, this->numDeviceIds);
+    root["device_ids"] = arr;
+  }
+  
   if (prettyPrint) {
     root.prettyPrintTo(stream);
   } else {

+ 12 - 1
lib/Settings/Settings.h

@@ -17,8 +17,16 @@ public:
     adminPassword(""),
     // CE and CSN pins from nrf24l01
     cePin(D0),
-    csnPin(D8)
+    csnPin(D8),
+    deviceIds(NULL),
+    numDeviceIds(0)
   { }
+  
+  ~Settings() {
+    if (deviceIds) {
+      delete deviceIds;
+    }
+  }
 
   static void deserialize(Settings& settings, String json);
   static void deserialize(Settings& settings, JsonObject& json);
@@ -27,11 +35,14 @@ public:
   void save();
   String toJson(const bool prettyPrint = true);
   void serialize(Stream& stream, const bool prettyPrint = false);
+  void updateDeviceIds(JsonArray& arr);
   
   String adminUsername;
   String adminPassword;
   uint8_t cePin;
   uint8_t csnPin;
+  uint16_t *deviceIds;
+  size_t numDeviceIds;
 };
 
 #endif 

+ 1 - 1
src/main.cpp

@@ -143,7 +143,7 @@ ESP8266WebServer::THandlerFunction handleUpdateFile(const char* filename) {
     if (upload.status == UPLOAD_FILE_START) {
       updateFile = SPIFFS.open(filename, "w");
     } else if(upload.status == UPLOAD_FILE_WRITE){
-      if (updateFile.write(upload.buf, upload.currentSize)) {
+      if (updateFile.write(upload.buf, upload.currentSize) != upload.currentSize) {
         Serial.println("Error updating web file");
       }
     } else if (upload.status == UPLOAD_FILE_END) {

+ 70 - 4
web/index.html

@@ -11,6 +11,7 @@
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
   <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
   <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.0/css/bootstrap-slider.min.css" rel="stylesheet"/>
+  <link href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/css/selectize.bootstrap3.min.css" rel="stylesheet"/>
 
   <!--[if lt IE 9]>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
@@ -24,6 +25,10 @@
     .command-buttons li { display: inline-block; margin-right: 1em; }
     .form-entry { margin: 0 0 20px 0; }
     .form-entry .form-control { width: 20em; }
+    label:not(.error) .error-info { display: none; }
+    .error-info { color: #f00; font-size: 0.7em; }
+    .error-info:before { content: '('; }
+    .error-info:after { content: ')'; }
     .btn-secondary { 
       background-color: #fff; 
       border: 1px solid #ccc;
@@ -64,12 +69,15 @@
   <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.0/bootstrap-slider.min.js"></script>
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.4/js/standalone/selectize.min.js"></script>
   
   <script lang="text/javascript">
     var FORM_SETTINGS = ["admin_username", "admin_password", "ce_pin", "csn_pin"];
+    
+    var selectize;
   
     var activeUrl = function() {
-      var deviceId = $('input[name="deviceId"]').val()
+      var deviceId = $('#deviceId option:selected').val()
         , groupId = $('#groupId input:checked').data('value');
         
       if (deviceId == "") {
@@ -106,11 +114,33 @@
     var loadSettings = function() {
       $.getJSON('/settings', function(val) {
         Object.keys(val).forEach(function(k) {
-          $('#settings input[name="' + k + '"]').val(val[k]);
+          var field = $('#settings input[name="' + k + '"]');
+          
+          if (field.length > 0) {
+            field.val(val[k]);
+          }
         });
+        
+        if (val.device_ids) {
+          selectize.clearOptions();
+          val.device_ids.forEach(function(v) {
+            var inHex = "0x" + (v).toString(16).toUpperCase();
+            selectize.addOption({text: inHex, value: v});
+          });
+          selectize.refreshOptions();
+        }
       });
     };
     
+    var deviceIdError = function(v) {
+      if (!v) {
+        $('#device-id-label').removeClass('error');
+      } else {
+        $('#device-id-label').addClass('error');
+        $('#device-id-label .error-info').html(v);
+      }
+    };
+    
     $(function() {
       $('.radio-option').click(function() {
         $(this).prev().prop('checked', true);
@@ -174,6 +204,29 @@
         }
       });
       
+      selectize = $('#deviceId').selectize({
+        create: true,
+        sortField: 'text',
+        createFilter: function(v) {
+          if (! v.match(/^(0x[a-fA-F0-9]{1,4}|[0-9]{1,5})$/)) {
+            deviceIdError("Must be an integer between 0x0000 and 0xFFFF");
+            return false;
+          }
+          
+          var value = parseInt(v);
+          
+          if (! (0 <= v && v <= 0xFFFF)) {
+            deviceIdError("Must be an integer between 0x0000 and 0xFFFF");
+            return false;
+          } 
+          
+          deviceIdError(false);
+          
+          return true;
+        }
+      });
+      selectize = selectize[0].selectize;
+      
       var settings = "";
       
       FORM_SETTINGS.forEach(function(k) {
@@ -187,10 +240,19 @@
       $('#settings').prepend(settings);
       $('#settings').submit(function(e) {
         var obj = {};
+        
         FORM_SETTINGS.forEach(function(k) {
           obj[k] = $('#settings input[name="' + k + '"]').val();
         });
         
+        // pretty hacky. whatever.
+        obj.device_ids = _.map(
+          $('.selectize-control .option'),
+          function(x) { 
+            return parseInt($(x).data('value'), 16)
+          }
+        );
+        
         $.ajax(
           "/settings",
           {
@@ -221,8 +283,12 @@
     
     <div class="row">
       <div class="col-sm-4">
-        <label for="deviceId">Device Id</label>
-        <input type="text" class="form-control" name="deviceId" />
+        <label for="deviceId" id="device-id-label">
+          Device Id
+          <span class="error-info"></span>
+        </label>
+        <select id="deviceId" placeholder="Enter hub ID">
+				</select>
       </div>
       
       <div class="col-sm-8">