Added model memory
							
								
								
									
										344
									
								
								CG_scale.ino
									
									
									
									
									
								
							
							
						
						@@ -4,7 +4,7 @@
 | 
			
		||||
                      (c) 2019 by M. Lehmann
 | 
			
		||||
  ------------------------------------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#define CGSCALE_VERSION "1.0.58"
 | 
			
		||||
#define CGSCALE_VERSION "1.0.62"
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  ******************************************************************
 | 
			
		||||
@@ -58,6 +58,7 @@
 | 
			
		||||
#include <ESP8266WiFi.h>
 | 
			
		||||
#include <WiFiClient.h>
 | 
			
		||||
#include <ESP8266WebServer.h>
 | 
			
		||||
#include <ArduinoJson.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// load settings
 | 
			
		||||
@@ -76,6 +77,7 @@ HX711_ADC LoadCell_3(PIN_LOADCELL3_DOUT, PIN_LOADCELL3_PD_SCK);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
ESP8266WebServer server(80);
 | 
			
		||||
IPAddress apIP(ip[0], ip[1], ip[2], ip[3]);
 | 
			
		||||
File fsUploadFile;              // a File object to temporarily store the received file
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// serial menu
 | 
			
		||||
@@ -119,7 +121,8 @@ enum {
 | 
			
		||||
  P_PASSWORD_STA =                      P_SSID_STA + MAX_SSID_PW_LENGHT + 1,
 | 
			
		||||
  P_SSID_AP =                           P_PASSWORD_STA + MAX_SSID_PW_LENGHT + 1,
 | 
			
		||||
  P_PASSWORD_AP =                       P_SSID_AP + MAX_SSID_PW_LENGHT + 1,
 | 
			
		||||
  EEPROM_SIZE =                         P_PASSWORD_AP + MAX_SSID_PW_LENGHT + 1
 | 
			
		||||
  P_MODELNAME =                         P_PASSWORD_AP + MAX_SSID_PW_LENGHT + 1,
 | 
			
		||||
  EEPROM_SIZE =                         P_MODELNAME + MAX_MODELNAME_LENGHT + 1
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -195,42 +198,40 @@ bool updateMenu = true;
 | 
			
		||||
int menuPage = 0;
 | 
			
		||||
String errMsg[5] = "";
 | 
			
		||||
int errMsgCnt = 0;
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
char curModelName[MAX_MODELNAME_LENGHT + 1] = "";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Restart CPU
 | 
			
		||||
void(* resetCPU) (void) = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// reset to factory defaults
 | 
			
		||||
void resetDefault() {
 | 
			
		||||
  // reset eeprom
 | 
			
		||||
  for (int i = 0; i < EEPROM_SIZE; i++) {
 | 
			
		||||
    EEPROM.write(i, 0xFF);
 | 
			
		||||
  }
 | 
			
		||||
  Serial.end();
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
  resetCPU();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// save calibration factor
 | 
			
		||||
void saveCalFactor1() {
 | 
			
		||||
  LoadCell_1.setCalFactor(calFactorLoadcell1);
 | 
			
		||||
  EEPROM.put(P_LOADCELL1_CALIBRATION_FACTOR, calFactorLoadcell1);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void saveCalFactor2() {
 | 
			
		||||
  LoadCell_2.setCalFactor(calFactorLoadcell2);
 | 
			
		||||
  EEPROM.put(P_LOADCELL2_CALIBRATION_FACTOR, calFactorLoadcell2);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void saveCalFactor3() {
 | 
			
		||||
  LoadCell_3.setCalFactor(calFactorLoadcell3);
 | 
			
		||||
  EEPROM.put(P_LOADCELL3_CALIBRATION_FACTOR, calFactorLoadcell3);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -269,6 +270,7 @@ void setup() {
 | 
			
		||||
  Serial.begin(9600);
 | 
			
		||||
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
  // init filesystem
 | 
			
		||||
  SPIFFS.begin();
 | 
			
		||||
  EEPROM.begin(EEPROM_SIZE);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -339,11 +341,21 @@ void setup() {
 | 
			
		||||
    EEPROM.get(P_PASSWORD_AP, password_AP);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (EEPROM.read(P_MODELNAME) != 0xFF) {
 | 
			
		||||
    EEPROM.get(P_MODELNAME, curModelName);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // load current model
 | 
			
		||||
  if (!openModelJson(curModelName)) {
 | 
			
		||||
    curModelName[0] = '\0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Start by connecting to a WiFi network
 | 
			
		||||
  WiFi.mode(WIFI_STA);
 | 
			
		||||
  WiFi.begin(ssid_STA, password_STA);
 | 
			
		||||
 | 
			
		||||
  long timeoutWiFi = millis();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // init OLED display
 | 
			
		||||
@@ -379,7 +391,7 @@ void setup() {
 | 
			
		||||
  while ((loadcell_1_rdy + loadcell_2_rdy + loadcell_3_rdy) < 3) {
 | 
			
		||||
    loadcell_1_rdy = LoadCell_1.startMultiple(STABILISINGTIME);
 | 
			
		||||
    loadcell_2_rdy = LoadCell_2.startMultiple(STABILISINGTIME);
 | 
			
		||||
    if (nLoadcells > 2) {
 | 
			
		||||
    if (nLoadcells == 3) {
 | 
			
		||||
      loadcell_3_rdy = LoadCell_3.startMultiple(STABILISINGTIME);
 | 
			
		||||
    } else {
 | 
			
		||||
      loadcell_3_rdy = 1;
 | 
			
		||||
@@ -465,8 +477,15 @@ void setup() {
 | 
			
		||||
  server.on("/getParameter", getParameter);
 | 
			
		||||
  server.on("/getWiFiNetworks", getWiFiNetworks);
 | 
			
		||||
  server.on("/saveParameter", saveParameter);
 | 
			
		||||
  server.on("/resetDefault", resetDefault);
 | 
			
		||||
  server.on("/autoCalibrate", autoCalibrate);
 | 
			
		||||
  server.on("/saveModel", saveModel);
 | 
			
		||||
  server.on("/openModel", openModel);
 | 
			
		||||
  server.on("/deleteModel", deleteModel);
 | 
			
		||||
 | 
			
		||||
  // When the client upload file
 | 
			
		||||
  server.on("/models.html", HTTP_POST, []() {
 | 
			
		||||
    server.send(200, "text/plain", "");
 | 
			
		||||
  }, handleFileUpload);
 | 
			
		||||
 | 
			
		||||
  // If the client requests any URI
 | 
			
		||||
  server.onNotFound([]() {
 | 
			
		||||
@@ -607,36 +626,54 @@ void loop() {
 | 
			
		||||
          case MENU_LOADCELLS:
 | 
			
		||||
            nLoadcells = Serial.parseInt();
 | 
			
		||||
            EEPROM.put(P_NUMBER_LOADCELLS, nLoadcells);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_DISTANCE_X1:
 | 
			
		||||
            distanceX1 = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_DISTANCE_X1, distanceX1);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_DISTANCE_X2:
 | 
			
		||||
            distanceX2 = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_DISTANCE_X2, distanceX2);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_DISTANCE_X3:
 | 
			
		||||
            distanceX3 = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_DISTANCE_X3, distanceX3);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_REF_WEIGHT:
 | 
			
		||||
            refWeight = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_REF_WEIGHT, refWeight);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_REF_CG:
 | 
			
		||||
            refCG = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_REF_CG, refCG);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
@@ -668,12 +705,18 @@ void loop() {
 | 
			
		||||
          case MENU_RESISTOR_R1:
 | 
			
		||||
            resistorR1 = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_RESISTOR_R1, resistorR1);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_RESISTOR_R2:
 | 
			
		||||
            resistorR2 = Serial.parseFloat();
 | 
			
		||||
            EEPROM.put(P_RESISTOR_R2, resistorR2);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
@@ -684,6 +727,9 @@ void loop() {
 | 
			
		||||
              enableBatVolt = false;
 | 
			
		||||
            }
 | 
			
		||||
            EEPROM.put(P_ENABLE_BATVOLT, enableBatVolt);
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
            EEPROM.commit();
 | 
			
		||||
#endif
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
            break;
 | 
			
		||||
@@ -694,7 +740,19 @@ void loop() {
 | 
			
		||||
            break;
 | 
			
		||||
          case MENU_RESET_DEFAULT:
 | 
			
		||||
            if (Serial.read() == 'J') {
 | 
			
		||||
              resetDefault();
 | 
			
		||||
              // reset eeprom
 | 
			
		||||
              for (int i = 0; i < EEPROM_SIZE; i++) {
 | 
			
		||||
                EEPROM.write(i, 0xFF);
 | 
			
		||||
              }
 | 
			
		||||
              Serial.end();
 | 
			
		||||
#if defined(ESP8266)
 | 
			
		||||
              EEPROM.commit();
 | 
			
		||||
              // delete json model file
 | 
			
		||||
              if (SPIFFS.exists(MODEL_FILE)) {
 | 
			
		||||
                SPIFFS.remove(MODEL_FILE);
 | 
			
		||||
              }
 | 
			
		||||
#endif
 | 
			
		||||
              resetCPU();
 | 
			
		||||
            }
 | 
			
		||||
            menuPage = 0;
 | 
			
		||||
            updateMenu = true;
 | 
			
		||||
@@ -923,7 +981,30 @@ void getRawValue() {
 | 
			
		||||
 | 
			
		||||
// send parameters to client
 | 
			
		||||
void getParameter() {
 | 
			
		||||
  char buff[8];
 | 
			
		||||
  String response = "";
 | 
			
		||||
  float weightTotal_saved = 0;
 | 
			
		||||
  float CG_length_saved = 0;
 | 
			
		||||
  float CG_trans_saved = 0;
 | 
			
		||||
 | 
			
		||||
  StaticJsonBuffer<JSONBUFFER_SIZE> jsonBuffer;
 | 
			
		||||
  //DynamicJsonBuffer  jsonBuffer(JSONBUFFER_SIZE);
 | 
			
		||||
 | 
			
		||||
  if (SPIFFS.exists(MODEL_FILE)) {
 | 
			
		||||
    // read json file
 | 
			
		||||
    File f = SPIFFS.open(MODEL_FILE, "r");
 | 
			
		||||
    JsonObject& root = jsonBuffer.parseObject(f);
 | 
			
		||||
    f.close();
 | 
			
		||||
    // check if model exists
 | 
			
		||||
    if (root.success() && root.containsKey(curModelName)) {
 | 
			
		||||
      JsonObject& object = root[curModelName];
 | 
			
		||||
      weightTotal_saved = object["wt"];
 | 
			
		||||
      CG_length_saved = object["cg"];
 | 
			
		||||
      CG_trans_saved = object["cglr"];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // parameter list
 | 
			
		||||
  response += nLoadcells;
 | 
			
		||||
  response += "&";
 | 
			
		||||
  response += distanceX1;
 | 
			
		||||
@@ -959,6 +1040,18 @@ void getParameter() {
 | 
			
		||||
  response += ssid_AP;
 | 
			
		||||
  response += "&";
 | 
			
		||||
  response += password_AP;
 | 
			
		||||
  response += "&";
 | 
			
		||||
  response += curModelName;
 | 
			
		||||
  response += "&";
 | 
			
		||||
  dtostrf(weightTotal_saved, 5, 1, buff);
 | 
			
		||||
  response += buff;
 | 
			
		||||
  response += "g&";
 | 
			
		||||
  dtostrf(CG_length_saved, 5, 1, buff);
 | 
			
		||||
  response += buff;
 | 
			
		||||
  response += "mm&";
 | 
			
		||||
  dtostrf(CG_trans_saved, 5, 1, buff);
 | 
			
		||||
  response += buff;
 | 
			
		||||
  response += "mm";
 | 
			
		||||
  server.send(200, "text/html", response);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1020,14 +1113,53 @@ void saveParameter() {
 | 
			
		||||
  EEPROM.put(P_PASSWORD_AP, password_AP);
 | 
			
		||||
  EEPROM.commit();
 | 
			
		||||
 | 
			
		||||
  server.send(200, "text/html", "ok");
 | 
			
		||||
  // save current model to json
 | 
			
		||||
  saveModelJson(curModelName);
 | 
			
		||||
 | 
			
		||||
  server.send(200, "text/plain", "saved");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// calibrate cg scale
 | 
			
		||||
void autoCalibrate() {
 | 
			
		||||
  while (!runAutoCalibrate());
 | 
			
		||||
  server.send(200, "text/html", "ok");
 | 
			
		||||
  server.send(200, "text/plain", "parameters saved");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// save new model
 | 
			
		||||
void saveModel() {
 | 
			
		||||
  if (server.hasArg("modelname")) {
 | 
			
		||||
    if (saveModelJson(server.arg("modelname"))) {
 | 
			
		||||
      server.send(200, "text/plain", "saved");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  server.send(404, "text/plain", "404: Save model failed !");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// open model
 | 
			
		||||
void openModel() {
 | 
			
		||||
  if (server.hasArg("modelname")) {
 | 
			
		||||
    if (openModelJson(server.arg("modelname"))) {
 | 
			
		||||
      server.send(200, "text/plain", "opened");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  server.send(404, "text/plain", "404: Open model failed !");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// delete model
 | 
			
		||||
void deleteModel() {
 | 
			
		||||
  if (server.hasArg("modelname")) {
 | 
			
		||||
    if (deleteModelJson(server.arg("modelname"))) {
 | 
			
		||||
      server.send(200, "text/plain", "deleted");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  server.send(404, "text/plain", "404: Delete model failed !");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1046,6 +1178,7 @@ String getContentType(String filename) {
 | 
			
		||||
 | 
			
		||||
// send file to the client (if it exists)
 | 
			
		||||
bool handleFileRead(String path) {
 | 
			
		||||
 | 
			
		||||
  // If a folder is requested, send the index file
 | 
			
		||||
  if (path.endsWith("/")) path += "index.html";
 | 
			
		||||
  String contentType = getContentType(path);
 | 
			
		||||
@@ -1060,6 +1193,175 @@ bool handleFileRead(String path) {
 | 
			
		||||
    file.close();
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// upload a new file to the SPIFFS
 | 
			
		||||
void handleFileUpload() {
 | 
			
		||||
 | 
			
		||||
  HTTPUpload& upload = server.upload();
 | 
			
		||||
 | 
			
		||||
  if (upload.status == UPLOAD_FILE_START) {
 | 
			
		||||
    String filename = upload.filename;
 | 
			
		||||
    if (!filename.startsWith("/")) filename = "/" + filename;
 | 
			
		||||
    if (filename != MODEL_FILE ) server.send(500, "text/plain", "wrong file !");
 | 
			
		||||
    // Open the file for writing in SPIFFS (create if it doesn't exist)
 | 
			
		||||
    fsUploadFile = SPIFFS.open(filename, "w");
 | 
			
		||||
    filename = String();
 | 
			
		||||
  } else if (upload.status == UPLOAD_FILE_WRITE) {
 | 
			
		||||
    // Write the received bytes to the file
 | 
			
		||||
    fsUploadFile.write(upload.buf, upload.currentSize);
 | 
			
		||||
  } else if (upload.status == UPLOAD_FILE_END) {
 | 
			
		||||
    // If the file was successfully created
 | 
			
		||||
    if (fsUploadFile) {
 | 
			
		||||
      fsUploadFile.close();
 | 
			
		||||
      // Redirect the client to the success page
 | 
			
		||||
      server.sendHeader("Location", "/models.html");
 | 
			
		||||
      server.send(303);
 | 
			
		||||
    } else {
 | 
			
		||||
      server.send(500, "text/plain", "500: couldn't create file");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// save model to json file
 | 
			
		||||
bool saveModelJson(String modelName) {
 | 
			
		||||
 | 
			
		||||
  if (modelName.length() > MAX_MODELNAME_LENGHT) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  StaticJsonBuffer<JSONBUFFER_SIZE> jsonBuffer;
 | 
			
		||||
  //DynamicJsonBuffer  jsonBuffer(JSONBUFFER_SIZE);
 | 
			
		||||
 | 
			
		||||
  if (SPIFFS.exists(MODEL_FILE)) {
 | 
			
		||||
    // read json file
 | 
			
		||||
    File f = SPIFFS.open(MODEL_FILE, "r");
 | 
			
		||||
    JsonObject& root = jsonBuffer.parseObject(f);
 | 
			
		||||
    f.close();
 | 
			
		||||
    if (!root.success()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    // check if model exists
 | 
			
		||||
    if (root.containsKey(modelName)) {
 | 
			
		||||
      writeModelData(root[modelName]);
 | 
			
		||||
    } else {
 | 
			
		||||
      // otherwise create new
 | 
			
		||||
      writeModelData(root.createNestedObject(modelName));
 | 
			
		||||
    }
 | 
			
		||||
    // write to file
 | 
			
		||||
    if (root.success()) {
 | 
			
		||||
      f = SPIFFS.open(MODEL_FILE, "w");
 | 
			
		||||
      root.printTo(f);
 | 
			
		||||
      f.close();
 | 
			
		||||
    } else {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    // creat new json
 | 
			
		||||
    JsonObject& root = jsonBuffer.createObject();
 | 
			
		||||
    writeModelData(root.createNestedObject(modelName));
 | 
			
		||||
    // write to file
 | 
			
		||||
    if (root.success()) {
 | 
			
		||||
      File f = SPIFFS.open(MODEL_FILE, "w");
 | 
			
		||||
      root.printTo(f);
 | 
			
		||||
      f.close();
 | 
			
		||||
    } else {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// read model data from json file
 | 
			
		||||
bool openModelJson(String modelName) {
 | 
			
		||||
 | 
			
		||||
  StaticJsonBuffer<JSONBUFFER_SIZE> jsonBuffer;
 | 
			
		||||
  //DynamicJsonBuffer  jsonBuffer(JSONBUFFER_SIZE);
 | 
			
		||||
 | 
			
		||||
  if (SPIFFS.exists(MODEL_FILE)) {
 | 
			
		||||
    // read json file
 | 
			
		||||
    File f = SPIFFS.open(MODEL_FILE, "r");
 | 
			
		||||
    JsonObject& root = jsonBuffer.parseObject(f);
 | 
			
		||||
    f.close();
 | 
			
		||||
    if (!root.success()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    // check if model exists
 | 
			
		||||
    if (root.containsKey(modelName)) {
 | 
			
		||||
      JsonObject& object = root[modelName];
 | 
			
		||||
      // load parameters from model
 | 
			
		||||
      distanceX1 = object["x1"];
 | 
			
		||||
      distanceX2 = object["x2"];
 | 
			
		||||
      distanceX3 = object["x3"];
 | 
			
		||||
    } else {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // save current model name to eeprom
 | 
			
		||||
    modelName.toCharArray(curModelName, MAX_MODELNAME_LENGHT + 1);
 | 
			
		||||
    EEPROM.put(P_MODELNAME, curModelName);
 | 
			
		||||
    EEPROM.commit();
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// delete model from json file
 | 
			
		||||
bool deleteModelJson(String modelName) {
 | 
			
		||||
 | 
			
		||||
  StaticJsonBuffer<JSONBUFFER_SIZE> jsonBuffer;
 | 
			
		||||
  //DynamicJsonBuffer  jsonBuffer(JSONBUFFER_SIZE);
 | 
			
		||||
 | 
			
		||||
  if (SPIFFS.exists(MODEL_FILE)) {
 | 
			
		||||
    // read json file
 | 
			
		||||
    File f = SPIFFS.open(MODEL_FILE, "r");
 | 
			
		||||
    JsonObject& root = jsonBuffer.parseObject(f);
 | 
			
		||||
    f.close();
 | 
			
		||||
    if (!root.success()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    // check if model exists
 | 
			
		||||
    if (root.containsKey(modelName)) {
 | 
			
		||||
      root.remove(modelName);
 | 
			
		||||
    } else {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    // if no models in json, kill it
 | 
			
		||||
    if (root.size() == 0) {
 | 
			
		||||
      SPIFFS.remove(MODEL_FILE);
 | 
			
		||||
    } else {
 | 
			
		||||
      // write to file
 | 
			
		||||
      if (root.success()) {
 | 
			
		||||
        File f = SPIFFS.open(MODEL_FILE, "w");
 | 
			
		||||
        root.printTo(f);
 | 
			
		||||
        f.close();
 | 
			
		||||
      } else {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void writeModelData(JsonObject& object) {
 | 
			
		||||
  object["wt"] = weightTotal;
 | 
			
		||||
  object["cg"] = CG_length;
 | 
			
		||||
  object["cglr"] = CG_trans;
 | 
			
		||||
  object["x1"] = distanceX1;
 | 
			
		||||
  object["x2"] = distanceX2;
 | 
			
		||||
  object["x3"] = distanceX3;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 320 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/CG_scale_mechanics.png.gz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								data/airplane.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/home.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.9 KiB  | 
@@ -11,6 +11,8 @@
 | 
			
		||||
    <script>
 | 
			
		||||
        var CG_trans_visible = true;
 | 
			
		||||
        var batVolt_visible = true;
 | 
			
		||||
        var curModelName = "";
 | 
			
		||||
        
 | 
			
		||||
        function getHead(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
@@ -34,6 +36,7 @@
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        
 | 
			
		||||
                        if(value[0] == "2"){
 | 
			
		||||
                            CG_trans_visible = false;
 | 
			
		||||
                            document.getElementById("cglrContainer").outerHTML = "";
 | 
			
		||||
@@ -42,6 +45,16 @@
 | 
			
		||||
                            batVolt_visible = false;
 | 
			
		||||
                            document.getElementById("batContainer").outerHTML = "";
 | 
			
		||||
                        }
 | 
			
		||||
                        curModelName = value[16];
 | 
			
		||||
                        if (curModelName != "") {
 | 
			
		||||
                            document.getElementById("modelName").innerHTML = curModelName;
 | 
			
		||||
                            document.getElementById("saveButton").classList.remove('disabled');
 | 
			
		||||
                            document.getElementById("weightTotalSaved").innerHTML = value[17];
 | 
			
		||||
                            document.getElementById("CG_lengthSaved").innerHTML = value[18];
 | 
			
		||||
                            if(CG_trans_visible == true){
 | 
			
		||||
                                document.getElementById("CG_transSaved").innerHTML = value[19];
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -56,7 +69,7 @@
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        document.getElementById("weightTotal").innerHTML = value[0];
 | 
			
		||||
                        document.getElementById("CG_length").innerHTML = value[1];
 | 
			
		||||
                        document.getElementById("CG_length").innerHTML = value[1];                        
 | 
			
		||||
                        if(CG_trans_visible == true){
 | 
			
		||||
                            document.getElementById("CG_trans").innerHTML = value[2];
 | 
			
		||||
                        }
 | 
			
		||||
@@ -70,55 +83,98 @@
 | 
			
		||||
            request.send();
 | 
			
		||||
            setTimeout('getValue()', 1000);
 | 
			
		||||
        }
 | 
			
		||||
        function saveModel(){
 | 
			
		||||
            if (curModelName != "") {
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        alert(curModelName + " saved");
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not saved !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "saveModel?modelname=" + curModelName, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    </script>
 | 
			
		||||
</head>
 | 
			
		||||
<body onload=getValue()>
 | 
			
		||||
    <script>        
 | 
			
		||||
        getHead();
 | 
			
		||||
        getParameter();
 | 
			
		||||
    </script>
 | 
			
		||||
<body>
 | 
			
		||||
    <nav class="navbar navbar-dark fixed-top bg-dark">
 | 
			
		||||
        <div class="container-fluid">
 | 
			
		||||
            <div class="navbar-header">
 | 
			
		||||
                <a class="navbar-brand" href="#"><span id="ssid"></span></a>"
 | 
			
		||||
                <a class="navbar-brand" href="#"><span id="ssid"></span></a>
 | 
			
		||||
            </div>
 | 
			
		||||
            <ul class="nav navbar-nav navbar-right">
 | 
			
		||||
                <button type="button" onclick="location.href = '/settings.html'" class="btn btn-danger">
 | 
			
		||||
                    <img src="settings.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                </button>
 | 
			
		||||
                <form class="form-inline">            
 | 
			
		||||
                    <button type="button" onclick="location.href = '/models.html'" class="btn btn-primary navbar-btn mx-2">
 | 
			
		||||
                        <img src="airplane.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                        <span id="modelName"></span>
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <button type="button" onclick="location.href = '/settings.html'" class="btn btn-danger navbar-btn">
 | 
			
		||||
                        <img src="settings.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                    </button>
 | 
			
		||||
                </form>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
    <br><br><br>
 | 
			
		||||
    <main role="main" class="container">
 | 
			
		||||
    <main role="main" class="container" style="margin-top:100px">
 | 
			
		||||
        <div class="jumbotron">
 | 
			
		||||
            <div class="container" id="wgContainer">
 | 
			
		||||
                <div class="row mt-3">
 | 
			
		||||
                    <div class="col-xs-6"><img src="weight.png" class="pull-left mr-4" alt="Weight" style="width:auto;height:50px"></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center"><font size="6"><span id="weightTotal">-</span></font></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center">
 | 
			
		||||
                        <font size="6">
 | 
			
		||||
                            <span class="ml-4 mr-4" id="weightTotal">-</span>
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <small class="form-text text-muted" id="weightTotalSaved"></small>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="container" id="cgContainer">
 | 
			
		||||
                <div class="row mt-3">
 | 
			
		||||
                    <div class="col-xs-6"><img src="cg.png" class="pull-left mr-4" alt="CG" style="width:auto;height:50px"></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center"><font size="6"><span id="CG_length">-</span></font></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center">
 | 
			
		||||
                        <font size="6">
 | 
			
		||||
                            <span class="ml-4 mr-4" id="CG_length">-</span>
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <small class="form-text text-muted" id="CG_lengthSaved"></small>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div> 
 | 
			
		||||
            <div class="container" id="cglrContainer">
 | 
			
		||||
                <div class="row mt-3">
 | 
			
		||||
                    <div class="col-xs-6"><img src="cglr.png" class="pull-left mr-4" alt="CG left/right" style="width:auto;height:50px"></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center"><font size="6"><span id="CG_trans">-</span></font></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center">
 | 
			
		||||
                        <font size="6">
 | 
			
		||||
                            <span class="ml-4 mr-4" id="CG_trans">-</span>
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <small class="form-text text-muted" id="CG_transSaved"></small>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div> 
 | 
			
		||||
            <div class="container" id="batContainer">
 | 
			
		||||
                <div class="row mt-3">
 | 
			
		||||
                    <div class="col-xs-6"><img src="battery.png" class="pull-left mr-4" alt="Battery" style="width:auto;height:50px"></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center"><font size="6"><span id="batVolt">-</span></font></div>
 | 
			
		||||
                    <div class="col-xs-6 d-flex align-items-center">
 | 
			
		||||
                        <font size="6">
 | 
			
		||||
                            <span class="ml-4 mr-4" id="batVolt">-</span>
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="container"><font size="6"><span id="errMsg"></span></font></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="text-center">
 | 
			
		||||
            <button class="btn btn-success btn-lg disabled" onclick="saveModel()" id="saveButton">Save</button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </main>
 | 
			
		||||
    <p><font size="2"><center>(c) 2019 M. Lehmann - Version: <span id="cgscaleVersion">0.0</span></center></font></p>
 | 
			
		||||
    <script>        
 | 
			
		||||
        getHead();
 | 
			
		||||
        getParameter();
 | 
			
		||||
        getValue();
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								data/jquery-3.3.1.slim.min.js.gz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										199
									
								
								data/models.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						@@ -0,0 +1,199 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 | 
			
		||||
    <meta name="description" content="">
 | 
			
		||||
    <meta name="author" content="M. Lehmann">
 | 
			
		||||
    <title>CG scale by M. Lehmann</title>
 | 
			
		||||
    <link href="/bootstrap.min.css" rel="stylesheet">
 | 
			
		||||
    <script src="/bootstrap.min.js"></script>
 | 
			
		||||
    <script src="/jquery-3.3.1.slim.min.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
        var CG_trans_visible = true;
 | 
			
		||||
        var curModelName = "";
 | 
			
		||||
        
 | 
			
		||||
        function getHead(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        document.getElementById("ssid").innerHTML = value[0];
 | 
			
		||||
                        document.getElementById("cgscaleVersion").innerHTML = value[2];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getHead", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        function getParameter(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText != null){
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        if(value[0] == "2"){
 | 
			
		||||
                            CG_trans_visible = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        curModelName = value[16];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "getParameter", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        function getModels(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    var root = JSON.parse(this.responseText);
 | 
			
		||||
                    var table = document.getElementById("models");
 | 
			
		||||
                    if(CG_trans_visible == false){
 | 
			
		||||
                        document.getElementById("cgLRrow").outerHTML = "";
 | 
			
		||||
                        
 | 
			
		||||
                    }
 | 
			
		||||
                    for (name in root) {
 | 
			
		||||
                        var row = table.insertRow();
 | 
			
		||||
                        var cellName = row.insertCell(0);
 | 
			
		||||
                        var cellWeight = row.insertCell(1);
 | 
			
		||||
                        var cellCG = row.insertCell(2);
 | 
			
		||||
                        cellName.innerHTML = name;
 | 
			
		||||
                        cellWeight.innerHTML = root[name].wt;
 | 
			
		||||
                        cellCG.innerHTML = root[name].cg;
 | 
			
		||||
                        if(CG_trans_visible == true){
 | 
			
		||||
                            var cellcglr = row.insertCell(3);
 | 
			
		||||
                            var cellButton = row.insertCell(4);
 | 
			
		||||
                            cellcglr.innerHTML = root[name].cglr;
 | 
			
		||||
                        }else{
 | 
			
		||||
                            var cellButton = row.insertCell(3);
 | 
			
		||||
                        }
 | 
			
		||||
                        if(name != curModelName){
 | 
			
		||||
                            var htmlbutton = '<div class="btn-group"><button type="button" onclick="openModel(\'';
 | 
			
		||||
                            htmlbutton += name;
 | 
			
		||||
                            htmlbutton += '\')" class="btn btn-success">Open</button><button type="button" onclick="deleteModel(\'';
 | 
			
		||||
                            htmlbutton += name;
 | 
			
		||||
                            htmlbutton += '\')" class="btn btn-danger">Delete</button></div>';
 | 
			
		||||
                            cellButton.innerHTML = htmlbutton;
 | 
			
		||||
                        }else{
 | 
			
		||||
                            row.setAttribute("class", "table-active");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                    document.getElementById("backup").outerHTML = "";
 | 
			
		||||
                    //alert("No models saved !");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "models.json", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        function saveModel(){
 | 
			
		||||
            var modelname = prompt("Please enter new model name:");
 | 
			
		||||
            if (modelname != "") {
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not saved !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "saveModel?modelname=" + modelname, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        function openModel(modelname){
 | 
			
		||||
            if (modelname != "") {
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not open !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "openModel?modelname=" + modelname, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        function deleteModel(modelname){
 | 
			
		||||
            if (modelname != "" && confirm("Do you want to delete: " + modelname + "?")){
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        location.reload();
 | 
			
		||||
                    }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                        alert("Model not deleted !");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.open("GET", "deleteModel?modelname=" + modelname, true);
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        function download(file)
 | 
			
		||||
        {
 | 
			
		||||
         window.location=file;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    </script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <nav class="navbar navbar-dark fixed-top bg-dark">
 | 
			
		||||
        <div class="container-fluid">
 | 
			
		||||
            <div class="navbar-header">
 | 
			
		||||
                <a class="navbar-brand" href="#"><span id="ssid"></span></a>
 | 
			
		||||
            </div>
 | 
			
		||||
            <ul class="nav navbar-nav navbar-right">
 | 
			
		||||
                <form class="form-inline">            
 | 
			
		||||
                    <button type="button" onclick="location.href = '/'" class="btn btn-danger navbar-btn mx-2">
 | 
			
		||||
                        <img src="home.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <button type="button" onclick="location.href = '/settings.html'" class="btn btn-danger navbar-btn">
 | 
			
		||||
                        <img src="settings.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                    </button>
 | 
			
		||||
                </form>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
    <main role="main" class="container" style="margin-top:100px">
 | 
			
		||||
        <table class="table" id="models">
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th scope="col">Name</th>
 | 
			
		||||
                    <th scope="col">Weight [g]</th>
 | 
			
		||||
                    <th scope="col">CG [mm]</th>
 | 
			
		||||
                    <th scope="col" id="cgLRrow">CG left-right [mm]</th>
 | 
			
		||||
                    <th scope="col"></th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
        </table>
 | 
			
		||||
        <button type="button" onclick="saveModel()" class="btn btn-primary btn-lg">New model</button>
 | 
			
		||||
        <form method="post" enctype="multipart/form-data">
 | 
			
		||||
            <div class="custom-file mt-5">
 | 
			
		||||
                <input type="file" class="custom-file-input" id="customFile" name="filename">
 | 
			
		||||
                <label class="custom-file-label" for="customFile">Restore file...</label>
 | 
			
		||||
            </div>
 | 
			
		||||
            
 | 
			
		||||
            <script>
 | 
			
		||||
                $('.custom-file-input').on('change', function() { 
 | 
			
		||||
                    let fileName = $(this).val().split('\\').pop(); 
 | 
			
		||||
                    $(this).next('.custom-file-label').addClass("selected").html(fileName); 
 | 
			
		||||
                });
 | 
			
		||||
            </script>
 | 
			
		||||
 | 
			
		||||
            <div class="mt-4">
 | 
			
		||||
                <a class="btn btn-outline-success btn-lg" id="backup" role="button" href="models.json" download="models.json">Backup</a>
 | 
			
		||||
                <button type="submit" class="btn btn-outline-danger btn-lg">Restore</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form> 
 | 
			
		||||
    </main>
 | 
			
		||||
    <p><font size="2"><center>(c) 2019 M. Lehmann - Version: <span id="cgscaleVersion">0.0</span></center></font></p>
 | 
			
		||||
    <script>
 | 
			
		||||
        getHead();
 | 
			
		||||
        getParameter();
 | 
			
		||||
        getModels();
 | 
			
		||||
    </script>    
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
    <script src="/bootstrap.min.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
        var CG_trans_visible = true;
 | 
			
		||||
        
 | 
			
		||||
        function getHead(){
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
@@ -18,7 +19,6 @@
 | 
			
		||||
                        var responseString = this.responseText;
 | 
			
		||||
                        var value = responseString.split("&");
 | 
			
		||||
                        document.getElementById("ssid").innerHTML = value[0];
 | 
			
		||||
                        //document.getElementById("errMsg").innerHTML = value[1];
 | 
			
		||||
                        document.getElementById("cgscaleVersion").innerHTML = value[2];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -68,6 +68,7 @@
 | 
			
		||||
                        setValue("password_STA", value[13]);
 | 
			
		||||
                        setValue("ssid_AP", value[14]);
 | 
			
		||||
                        setValue("password_AP", value[15]);
 | 
			
		||||
                        document.getElementById("modelName").innerHTML = value[16];
 | 
			
		||||
                        if(value[0] == "2"){
 | 
			
		||||
                            CG_trans_visible = false;
 | 
			
		||||
                            document.getElementById("lc3_div").outerHTML = "";
 | 
			
		||||
@@ -117,52 +118,31 @@
 | 
			
		||||
            data += "&ssid_AP=" + document.getElementById("ssid_AP").value;
 | 
			
		||||
            data += "&password_AP=" + document.getElementById("password_AP").value;
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.open("GET", "saveParameter" + data, true);
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText == "ok"){
 | 
			
		||||
                        alert("Parameters saved");
 | 
			
		||||
                        getParameter();
 | 
			
		||||
                    }else{
 | 
			
		||||
                        alert("Save parameter failed !");
 | 
			
		||||
                    }
 | 
			
		||||
                    alert("Parameters saved");
 | 
			
		||||
                    getParameter();
 | 
			
		||||
                }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                    alert("Save parameter failed !");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "saveParameter" + data, true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        function autoCalibrate(){
 | 
			
		||||
            alert("Please put the reference weight on the scale.");
 | 
			
		||||
            var request = new XMLHttpRequest();
 | 
			
		||||
            request.open("GET", "autoCalibrate", true);
 | 
			
		||||
            request.onreadystatechange = function(){
 | 
			
		||||
                if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                    if(this.responseText == "ok"){
 | 
			
		||||
                        alert("Calibration successful");
 | 
			
		||||
                        getParameter();
 | 
			
		||||
                    }else{
 | 
			
		||||
                        alert("Calibration failed !");
 | 
			
		||||
                    }
 | 
			
		||||
                    alert("Calibration successful");
 | 
			
		||||
                    getParameter();
 | 
			
		||||
                }else if(this.readyState == 4 && this.status == 404){
 | 
			
		||||
                    alert("Calibration failed !");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            request.open("GET", "autoCalibrate", true);
 | 
			
		||||
            request.send();
 | 
			
		||||
        }
 | 
			
		||||
        function resetDefault(){
 | 
			
		||||
            if (confirm("Reset to factory defaults ?")) {
 | 
			
		||||
                var request = new XMLHttpRequest();
 | 
			
		||||
                request.open("GET", "resetDefault", true);
 | 
			
		||||
                request.onreadystatechange = function(){
 | 
			
		||||
                    if(this.readyState == 4 && this.status == 200){
 | 
			
		||||
                        if(this.responseText == "ok"){
 | 
			
		||||
                            alert("Reset to factory defaults successful");
 | 
			
		||||
                            getParameter();
 | 
			
		||||
                        }else{
 | 
			
		||||
                            alert("Reset to factory defaults failed !");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                request.send();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        function setValue(id, value)
 | 
			
		||||
        {    
 | 
			
		||||
            var element = document.getElementById(id);
 | 
			
		||||
@@ -174,24 +154,26 @@
 | 
			
		||||
        }
 | 
			
		||||
    </script>
 | 
			
		||||
</head>
 | 
			
		||||
<body onload=getRawValue()>
 | 
			
		||||
    <script>
 | 
			
		||||
        getHead();
 | 
			
		||||
        getWiFiNetworks();
 | 
			
		||||
        getParameter();
 | 
			
		||||
    </script>
 | 
			
		||||
<body>
 | 
			
		||||
    <nav class="navbar navbar-dark fixed-top bg-dark">
 | 
			
		||||
        <div class="container-fluid">
 | 
			
		||||
            <div class="navbar-header">
 | 
			
		||||
                <a class="navbar-brand" href="#"><span id="ssid"></span></a>"
 | 
			
		||||
                <a class="navbar-brand" href="#"><span id="ssid"></span></a>
 | 
			
		||||
            </div>
 | 
			
		||||
            <ul class="nav navbar-nav navbar-right">
 | 
			
		||||
                <button type="button" onclick="location.href = '/'" class="btn btn-danger">Home</button>
 | 
			
		||||
                <form class="form-inline">            
 | 
			
		||||
                    <button type="button" onclick="location.href = '/models.html'" class="btn btn-primary navbar-btn mx-2">
 | 
			
		||||
                        <img src="airplane.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                        <span id="modelName"></span>
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <button type="button" onclick="location.href = '/'" class="btn btn-danger navbar-btn">
 | 
			
		||||
                        <img src="home.png" alt="" style="width:auto;height:30px">
 | 
			
		||||
                    </button>
 | 
			
		||||
                </form>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
    <br><br><br>
 | 
			
		||||
    <main role="main" class="container">
 | 
			
		||||
    <main role="main" class="container" style="margin-top:100px">
 | 
			
		||||
        <h3>WiFi settings</h3>
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label>Home WiFi name (SSID):</label>
 | 
			
		||||
@@ -271,9 +253,8 @@
 | 
			
		||||
            </select>
 | 
			
		||||
        </div>
 | 
			
		||||
        <br><br>
 | 
			
		||||
        <button class="btn btn-success btn-lg" onclick="saveParameter()">save</button>
 | 
			
		||||
        <button class="btn btn-primary btn-lg" onclick="autoCalibrate()">auto calibrate</button>
 | 
			
		||||
        <button class="btn btn-danger btn-lg" onclick="resetDefault()">reset</button>
 | 
			
		||||
        <button class="btn btn-success btn-lg" onclick="saveParameter()">Save</button>
 | 
			
		||||
        <button class="btn btn-primary btn-lg" onclick="autoCalibrate()">Auto calibrate</button>
 | 
			
		||||
        <img src="CG_scale_mechanics.png" class="pull-left mr-4" alt="mechanics" style="width:100%">
 | 
			
		||||
        <font size="4">
 | 
			
		||||
            <div>
 | 
			
		||||
@@ -287,9 +268,13 @@
 | 
			
		||||
            </div>
 | 
			
		||||
        </font> 
 | 
			
		||||
        <br><br>
 | 
			
		||||
        <!--<p><font size="4"><center>Lc1: <span id="lc1">-</span> Lc2: <span id="lc2">-</span><div id="lc3_div"> Lc3: <span id="lc3">-</span></div></center></font></p>-->
 | 
			
		||||
    </main>
 | 
			
		||||
    <!--<div class="container"><font size="6"><span id="errMsg">-</span></font></div>-->
 | 
			
		||||
    <p><font size="2"><center>(c) 2019 M. Lehmann - Version: <span id="cgscaleVersion">0.0</span></center></font></p>
 | 
			
		||||
    <script>
 | 
			
		||||
        getHead();
 | 
			
		||||
        getWiFiNetworks();
 | 
			
		||||
        getParameter();
 | 
			
		||||
        getRawValue();
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.5 KiB  | 
							
								
								
									
										0
									
								
								data/weight.png
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB  | 
@@ -137,3 +137,10 @@ U8G2_SH1106_128X64_NONAME_1_HW_I2C oledDisplay(U8G2_R0, /* reset=*/ U8X8_PIN_NON
 | 
			
		||||
#define SSID_AP                     "CG scale"
 | 
			
		||||
#define PASSWORD_AP                 ""
 | 
			
		||||
const char ip[4] =                  {1,1,1,1};    // default IP address
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// **** Model memory settings ****
 | 
			
		||||
 | 
			
		||||
#define MAX_MODELNAME_LENGHT        15               // max chars 
 | 
			
		||||
#define MODEL_FILE                  "/models.json"   // file to store models
 | 
			
		||||
#define JSONBUFFER_SIZE             20000            // max file size in bytes
 | 
			
		||||
 
 | 
			
		||||