diff --git a/README.md b/README.md index dc49830..cbbf69b 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,46 @@ # Esp8266-Laser Wifi Host for the Arduino-Laser-Spirograph -HTTP endpoints: - /spirograph GET returns laser and motor values (0 at startup) - POST sets new value(s) - laser=1-128 (1:permanent, 2-127 pulse, 128 off) - motor1=1-128 - motor2=1-128 - motor3=1-128 - - - /wificonfig -> GET returns wifi settings - POST sets new wifi setting{s} - apMode=0: will try to connect to SSID first, 1: will directly start the AP - SSID=ssid - password=password - save=true will save config to spiffs, false will only change RAM variable (useful for onetime ap joins) - apply=true will reset wifi and try to connect with new param (buggy atm) - /saveconf -> POST write wificonfig to file (similar to wificonfig->save=true) - /resetwifi -> POST reconnect wifi (similar to wificonfig->apply=true) - /heap -> GET returns free heap of the ESP8266 - /files -> GET returns list of files +## HTTP endpoints: +* /spirograph + * **GET** returns laser and motor values (0 at startup) + * **POST** sets new value(s) + * laser=1-128 (1:permanent, 2-127 pulse, 128 off) + * motor1=1-128 + * motor2=1-128 + * motor3=1-128 + +* /preset + * **POST** sets new value(s) to Preset + * nr=presetNr (1-128) + * laser=1-128 (1:permanent, 2-127 pulse, 128 off) + * motor1=1-128 + * motor2=1-128 + * motor3=1-128 + * apply=true -> run preset + +* /presetMode + * **GET** returns current mode + * **POST** sets mode 0: presetsOff 1: cycle (not completed feature) + +* /presets + * **GET** returns /presets.json + +* /wificonfig + * **GET** returns wifi settings + * **POST** sets new wifi setting{s} + * apMode=0: will try to connect to SSID first, 1: will directly start the AP + * SSID=ssid + * password=password + * save=true will save config to spiffs, false will only change RAM variable (useful for onetime ap joins) + * apply=true will reset wifi and try to connect with new param (buggy atm) +* /heap + * **GET** returns free heap of the ESP8266 +* /files + * **GET** returns list of files + -# Install +## Install - install arduino ide (1.8.5) or PlatformIO (see Development section for further instructions) - follow this instruction @@ -42,8 +60,8 @@ You may also need to: - get and install driver for nodemcu https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers -# Development -PlatformIO +## Development +### PlatformIO ---------- The project is intended to run on PlatformIO and the build environment is configured for NodeMCU 1.0 (ESP-12E Module). More informations: http://docs.platformio.org/en/latest/platforms/espressif8266.html @@ -79,16 +97,16 @@ build:firmware upload:firmware ``` -Frontend +### Frontend -------- Frontend development requires NodeJS / npm. The development server watches all files in the frontend directory and automatically builds and copies the frontend code to the data folder. ``` -# run development server on port 8080 +### run development server on port 8080 npm run dev -# build distribution source to data folder +### build distribution source to data folder npm run build ``` \ No newline at end of file diff --git a/config/presets.json b/config/presets.json new file mode 100644 index 0000000..0466e8e --- /dev/null +++ b/config/presets.json @@ -0,0 +1,772 @@ +{ + "presets": { + "1": [ + 62, + 63, + 64, + 65 + ], + "2": [ + 67, + 68, + 69, + 70 + ], + "3": [ + 80, + 81, + 82, + 83 + ], + "4": [ + 73, + 74, + 75, + 76 + ], + "5": [ + 65, + 66, + 67, + 68 + ], + "6": [ + 22, + 23, + 24, + 25 + ], + "7": [ + 11, + 12, + 13, + 14 + ], + "8": [ + 44, + 45, + 46, + 47 + ], + "9": [ + 85, + 86, + 87, + 88 + ], + "10": [ + 47, + 48, + 49, + 50 + ], + "11": [ + 92, + 93, + 94, + 95 + ], + "12": [ + 8, + 9, + 10, + 11 + ], + "13": [ + 19, + 20, + 21, + 22 + ], + "14": [ + 77, + 78, + 79, + 80 + ], + "15": [ + 22, + 23, + 24, + 25 + ], + "16": [ + 119, + 120, + 121, + 122 + ], + "17": [ + 60, + 61, + 62, + 63 + ], + "18": [ + 111, + 112, + 113, + 114 + ], + "19": [ + 75, + 76, + 77, + 78 + ], + "20": [ + 21, + 22, + 23, + 24 + ], + "21": [ + 32, + 33, + 34, + 35 + ], + "22": [ + 67, + 68, + 69, + 70 + ], + "23": [ + 27, + 28, + 29, + 30 + ], + "24": [ + 3, + 4, + 5, + 6 + ], + "25": [ + 57, + 58, + 59, + 60 + ], + "26": [ + 56, + 57, + 58, + 59 + ], + "27": [ + 72, + 73, + 74, + 75 + ], + "28": [ + 114, + 115, + 116, + 117 + ], + "29": [ + 70, + 71, + 72, + 73 + ], + "30": [ + 86, + 87, + 88, + 89 + ], + "31": [ + 34, + 35, + 36, + 37 + ], + "32": [ + 8, + 9, + 10, + 11 + ], + "33": [ + 112, + 113, + 114, + 115 + ], + "34": [ + 37, + 38, + 39, + 40 + ], + "35": [ + 71, + 72, + 73, + 74 + ], + "36": [ + 8, + 9, + 10, + 11 + ], + "37": [ + 25, + 26, + 27, + 28 + ], + "38": [ + 14, + 15, + 16, + 17 + ], + "39": [ + 44, + 45, + 46, + 47 + ], + "40": [ + 115, + 116, + 117, + 118 + ], + "41": [ + 111, + 112, + 113, + 114 + ], + "42": [ + 59, + 60, + 61, + 62 + ], + "43": [ + 106, + 107, + 108, + 109 + ], + "44": [ + 31, + 32, + 33, + 34 + ], + "45": [ + 22, + 23, + 24, + 25 + ], + "46": [ + 14, + 15, + 16, + 17 + ], + "47": [ + 7, + 8, + 9, + 10 + ], + "48": [ + 110, + 111, + 112, + 113 + ], + "49": [ + 97, + 98, + 99, + 100 + ], + "50": [ + 49, + 50, + 51, + 52 + ], + "51": [ + 99, + 100, + 101, + 102 + ], + "52": [ + 14, + 15, + 16, + 17 + ], + "53": [ + 44, + 45, + 46, + 47 + ], + "54": [ + 112, + 113, + 114, + 115 + ], + "55": [ + 34, + 35, + 36, + 37 + ], + "56": [ + 10, + 11, + 12, + 13 + ], + "57": [ + 2, + 3, + 4, + 5 + ], + "58": [ + 48, + 49, + 50, + 51 + ], + "59": [ + 109, + 110, + 111, + 112 + ], + "60": [ + 44, + 45, + 46, + 47 + ], + "61": [ + 83, + 84, + 85, + 86 + ], + "62": [ + 15, + 16, + 17, + 18 + ], + "63": [ + 112, + 113, + 114, + 115 + ], + "64": [ + 5, + 6, + 7, + 8 + ], + "65": [ + 44, + 45, + 46, + 47 + ], + "66": [ + 68, + 69, + 70, + 71 + ], + "67": [ + 103, + 104, + 105, + 106 + ], + "68": [ + 118, + 119, + 120, + 121 + ], + "69": [ + 88, + 89, + 90, + 91 + ], + "70": [ + 16, + 17, + 18, + 19 + ], + "71": [ + 44, + 45, + 46, + 47 + ], + "72": [ + 18, + 19, + 20, + 21 + ], + "73": [ + 34, + 35, + 36, + 37 + ], + "74": [ + 112, + 113, + 114, + 115 + ], + "75": [ + 118, + 119, + 120, + 121 + ], + "76": [ + 63, + 64, + 65, + 66 + ], + "77": [ + 34, + 35, + 36, + 37 + ], + "78": [ + 120, + 121, + 122, + 123 + ], + "79": [ + 49, + 50, + 51, + 52 + ], + "80": [ + 111, + 112, + 113, + 114 + ], + "81": [ + 57, + 58, + 59, + 60 + ], + "82": [ + 102, + 103, + 104, + 105 + ], + "83": [ + 20, + 21, + 22, + 23 + ], + "84": [ + 18, + 19, + 20, + 21 + ], + "85": [ + 69, + 70, + 71, + 72 + ], + "86": [ + 45, + 46, + 47, + 48 + ], + "87": [ + 110, + 111, + 112, + 113 + ], + "88": [ + 9, + 10, + 11, + 12 + ], + "89": [ + 25, + 26, + 27, + 28 + ], + "90": [ + 92, + 93, + 94, + 95 + ], + "91": [ + 5, + 6, + 7, + 8 + ], + "92": [ + 20, + 21, + 22, + 23 + ], + "93": [ + 7, + 8, + 9, + 10 + ], + "94": [ + 106, + 107, + 108, + 109 + ], + "95": [ + 63, + 64, + 65, + 66 + ], + "96": [ + 25, + 26, + 27, + 28 + ], + "97": [ + 87, + 88, + 89, + 90 + ], + "98": [ + 72, + 73, + 74, + 75 + ], + "99": [ + 27, + 28, + 29, + 30 + ], + "100": [ + 53, + 54, + 55, + 56 + ], + "101": [ + 51, + 52, + 53, + 54 + ], + "102": [ + 6, + 7, + 8, + 9 + ], + "103": [ + 45, + 46, + 47, + 48 + ], + "104": [ + 91, + 92, + 93, + 94 + ], + "105": [ + 48, + 49, + 50, + 51 + ], + "106": [ + 15, + 16, + 17, + 18 + ], + "107": [ + 12, + 13, + 14, + 15 + ], + "108": [ + 6, + 7, + 8, + 9 + ], + "109": [ + 24, + 25, + 26, + 27 + ], + "110": [ + 99, + 100, + 101, + 102 + ], + "111": [ + 37, + 38, + 39, + 40 + ], + "112": [ + 86, + 87, + 88, + 89 + ], + "113": [ + 84, + 85, + 86, + 87 + ], + "114": [ + 90, + 91, + 92, + 93 + ], + "115": [ + 14, + 15, + 16, + 17 + ], + "116": [ + 121, + 122, + 123, + 124 + ], + "117": [ + 118, + 119, + 120, + 121 + ], + "118": [ + 17, + 18, + 19, + 20 + ], + "119": [ + 54, + 55, + 56, + 57 + ], + "120": [ + 118, + 119, + 120, + 121 + ], + "121": [ + 107, + 108, + 109, + 110 + ], + "122": [ + 90, + 91, + 92, + 93 + ], + "123": [ + 62, + 63, + 64, + 65 + ], + "124": [ + 32, + 33, + 34, + 35 + ], + "125": [ + 16, + 17, + 18, + 19 + ], + "126": [ + 123, + 124, + 125, + 126 + ], + "127": [ + 113, + 114, + 115, + 116 + ], + "128": [ + 106, + 107, + 108, + 109 + ] + } +} \ No newline at end of file diff --git a/data/presets.json b/data/presets.json new file mode 100644 index 0000000..0466e8e --- /dev/null +++ b/data/presets.json @@ -0,0 +1,772 @@ +{ + "presets": { + "1": [ + 62, + 63, + 64, + 65 + ], + "2": [ + 67, + 68, + 69, + 70 + ], + "3": [ + 80, + 81, + 82, + 83 + ], + "4": [ + 73, + 74, + 75, + 76 + ], + "5": [ + 65, + 66, + 67, + 68 + ], + "6": [ + 22, + 23, + 24, + 25 + ], + "7": [ + 11, + 12, + 13, + 14 + ], + "8": [ + 44, + 45, + 46, + 47 + ], + "9": [ + 85, + 86, + 87, + 88 + ], + "10": [ + 47, + 48, + 49, + 50 + ], + "11": [ + 92, + 93, + 94, + 95 + ], + "12": [ + 8, + 9, + 10, + 11 + ], + "13": [ + 19, + 20, + 21, + 22 + ], + "14": [ + 77, + 78, + 79, + 80 + ], + "15": [ + 22, + 23, + 24, + 25 + ], + "16": [ + 119, + 120, + 121, + 122 + ], + "17": [ + 60, + 61, + 62, + 63 + ], + "18": [ + 111, + 112, + 113, + 114 + ], + "19": [ + 75, + 76, + 77, + 78 + ], + "20": [ + 21, + 22, + 23, + 24 + ], + "21": [ + 32, + 33, + 34, + 35 + ], + "22": [ + 67, + 68, + 69, + 70 + ], + "23": [ + 27, + 28, + 29, + 30 + ], + "24": [ + 3, + 4, + 5, + 6 + ], + "25": [ + 57, + 58, + 59, + 60 + ], + "26": [ + 56, + 57, + 58, + 59 + ], + "27": [ + 72, + 73, + 74, + 75 + ], + "28": [ + 114, + 115, + 116, + 117 + ], + "29": [ + 70, + 71, + 72, + 73 + ], + "30": [ + 86, + 87, + 88, + 89 + ], + "31": [ + 34, + 35, + 36, + 37 + ], + "32": [ + 8, + 9, + 10, + 11 + ], + "33": [ + 112, + 113, + 114, + 115 + ], + "34": [ + 37, + 38, + 39, + 40 + ], + "35": [ + 71, + 72, + 73, + 74 + ], + "36": [ + 8, + 9, + 10, + 11 + ], + "37": [ + 25, + 26, + 27, + 28 + ], + "38": [ + 14, + 15, + 16, + 17 + ], + "39": [ + 44, + 45, + 46, + 47 + ], + "40": [ + 115, + 116, + 117, + 118 + ], + "41": [ + 111, + 112, + 113, + 114 + ], + "42": [ + 59, + 60, + 61, + 62 + ], + "43": [ + 106, + 107, + 108, + 109 + ], + "44": [ + 31, + 32, + 33, + 34 + ], + "45": [ + 22, + 23, + 24, + 25 + ], + "46": [ + 14, + 15, + 16, + 17 + ], + "47": [ + 7, + 8, + 9, + 10 + ], + "48": [ + 110, + 111, + 112, + 113 + ], + "49": [ + 97, + 98, + 99, + 100 + ], + "50": [ + 49, + 50, + 51, + 52 + ], + "51": [ + 99, + 100, + 101, + 102 + ], + "52": [ + 14, + 15, + 16, + 17 + ], + "53": [ + 44, + 45, + 46, + 47 + ], + "54": [ + 112, + 113, + 114, + 115 + ], + "55": [ + 34, + 35, + 36, + 37 + ], + "56": [ + 10, + 11, + 12, + 13 + ], + "57": [ + 2, + 3, + 4, + 5 + ], + "58": [ + 48, + 49, + 50, + 51 + ], + "59": [ + 109, + 110, + 111, + 112 + ], + "60": [ + 44, + 45, + 46, + 47 + ], + "61": [ + 83, + 84, + 85, + 86 + ], + "62": [ + 15, + 16, + 17, + 18 + ], + "63": [ + 112, + 113, + 114, + 115 + ], + "64": [ + 5, + 6, + 7, + 8 + ], + "65": [ + 44, + 45, + 46, + 47 + ], + "66": [ + 68, + 69, + 70, + 71 + ], + "67": [ + 103, + 104, + 105, + 106 + ], + "68": [ + 118, + 119, + 120, + 121 + ], + "69": [ + 88, + 89, + 90, + 91 + ], + "70": [ + 16, + 17, + 18, + 19 + ], + "71": [ + 44, + 45, + 46, + 47 + ], + "72": [ + 18, + 19, + 20, + 21 + ], + "73": [ + 34, + 35, + 36, + 37 + ], + "74": [ + 112, + 113, + 114, + 115 + ], + "75": [ + 118, + 119, + 120, + 121 + ], + "76": [ + 63, + 64, + 65, + 66 + ], + "77": [ + 34, + 35, + 36, + 37 + ], + "78": [ + 120, + 121, + 122, + 123 + ], + "79": [ + 49, + 50, + 51, + 52 + ], + "80": [ + 111, + 112, + 113, + 114 + ], + "81": [ + 57, + 58, + 59, + 60 + ], + "82": [ + 102, + 103, + 104, + 105 + ], + "83": [ + 20, + 21, + 22, + 23 + ], + "84": [ + 18, + 19, + 20, + 21 + ], + "85": [ + 69, + 70, + 71, + 72 + ], + "86": [ + 45, + 46, + 47, + 48 + ], + "87": [ + 110, + 111, + 112, + 113 + ], + "88": [ + 9, + 10, + 11, + 12 + ], + "89": [ + 25, + 26, + 27, + 28 + ], + "90": [ + 92, + 93, + 94, + 95 + ], + "91": [ + 5, + 6, + 7, + 8 + ], + "92": [ + 20, + 21, + 22, + 23 + ], + "93": [ + 7, + 8, + 9, + 10 + ], + "94": [ + 106, + 107, + 108, + 109 + ], + "95": [ + 63, + 64, + 65, + 66 + ], + "96": [ + 25, + 26, + 27, + 28 + ], + "97": [ + 87, + 88, + 89, + 90 + ], + "98": [ + 72, + 73, + 74, + 75 + ], + "99": [ + 27, + 28, + 29, + 30 + ], + "100": [ + 53, + 54, + 55, + 56 + ], + "101": [ + 51, + 52, + 53, + 54 + ], + "102": [ + 6, + 7, + 8, + 9 + ], + "103": [ + 45, + 46, + 47, + 48 + ], + "104": [ + 91, + 92, + 93, + 94 + ], + "105": [ + 48, + 49, + 50, + 51 + ], + "106": [ + 15, + 16, + 17, + 18 + ], + "107": [ + 12, + 13, + 14, + 15 + ], + "108": [ + 6, + 7, + 8, + 9 + ], + "109": [ + 24, + 25, + 26, + 27 + ], + "110": [ + 99, + 100, + 101, + 102 + ], + "111": [ + 37, + 38, + 39, + 40 + ], + "112": [ + 86, + 87, + 88, + 89 + ], + "113": [ + 84, + 85, + 86, + 87 + ], + "114": [ + 90, + 91, + 92, + 93 + ], + "115": [ + 14, + 15, + 16, + 17 + ], + "116": [ + 121, + 122, + 123, + 124 + ], + "117": [ + 118, + 119, + 120, + 121 + ], + "118": [ + 17, + 18, + 19, + 20 + ], + "119": [ + 54, + 55, + 56, + 57 + ], + "120": [ + 118, + 119, + 120, + 121 + ], + "121": [ + 107, + 108, + 109, + 110 + ], + "122": [ + 90, + 91, + 92, + 93 + ], + "123": [ + 62, + 63, + 64, + 65 + ], + "124": [ + 32, + 33, + 34, + 35 + ], + "125": [ + 16, + 17, + 18, + 19 + ], + "126": [ + 123, + 124, + 125, + 126 + ], + "127": [ + 113, + 114, + 115, + 116 + ], + "128": [ + 106, + 107, + 108, + 109 + ] + } +} \ No newline at end of file diff --git a/src/esp8266-laser.ino b/src/esp8266-laser.ino index cb20be9..0ba8739 100644 --- a/src/esp8266-laser.ino +++ b/src/esp8266-laser.ino @@ -34,9 +34,19 @@ const char *myHostname = "esplaser"; // SoftwareSerial(int receivePin, int transmitPin, bool inverse_logic = false, unsigned int buffSize = 64); SoftwareSerial laserSerial(14, 12, false, 256); +// Presets json buffer +const unsigned int maxPresets = 128; // 128 = 19496, 200 = 29864 + +// Preset cycleTime +unsigned int cycleTime = 5000; // ms /* End of hard coded config */ +const unsigned int presetsBufferSize = maxPresets * JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(maxPresets) + 1000; + +byte presets[maxPresets][4] = {1, 1, 1, 128}; +unsigned int activePreset = 0; +unsigned int presetMode = 0; String ssid = ""; String password = ""; @@ -105,6 +115,77 @@ void hFileList() { responseBuffer = String(); } +bool hReadPresets() +{ + // streamFile instead of rebuild json string + String path = "/presets.json"; + String contentType = getContentType(path); + if (SPIFFS.exists(path)) { + File file = SPIFFS.open(path, "r"); + size_t sent = server.streamFile(file, contentType); + file.close(); + return true; + } + return false; +} + +void hWritePreset() +{ + presetMode = 0; + int error = 0; + int presetNr = 0; + bool apply = false; + + StaticJsonBuffer<200> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + JsonObject& data = root.createNestedObject("preset"); + if (server.hasArg("nr") ) { + presetNr = server.arg("nr").toInt(); + data["nr"] = (String)presetNr; + } + else + { + error = 1; + } + if (server.hasArg("laser") && error == 0) { + presets[presetNr-1][0] = server.arg("laser").toInt(); + data["laser"] = (String)presets[presetNr-1][0]; + } + if (server.hasArg("motor1") && error == 0) { + presets[presetNr-1][1] = server.arg("motor1").toInt(); + data["motor1"] = (String)presets[presetNr-1][1]; + } + if (server.hasArg("motor2") && error == 0) { + presets[presetNr-1][2] = server.arg("motor2").toInt(); + data["motor2"] = (String) presets[presetNr-1][2]; + } + if (server.hasArg("motor3") && error == 0) { + presets[presetNr-1][3] = server.arg("motor3").toInt(); + data["motor3"] = (String) presets[presetNr-1][3]; + } + if (server.arg("apply") == "true" && error == 0) + { + apply = true; + data["apply"] = "true"; + presetToLaser(presetNr-1); + } + + error = savePresetFile() ? 0 : 1; + if(error == 0) + { + String responseBuffer = String(); + root.prettyPrintTo(responseBuffer); + server.send(200, "text/json", responseBuffer); + responseBuffer = String(); + } + else + { + server.send(400, "text/plain", "400 Bad Request"); + } + jsonBuffer.clear(); + +} + void hReadSpiro() { String responseBuffer = String(); @@ -123,6 +204,7 @@ void hReadSpiro() void hWriteSpiro() { + presetMode = 0; String responseBuffer = String(); StaticJsonBuffer<200> jsonBuffer; JsonObject& root = jsonBuffer.createObject(); @@ -130,34 +212,34 @@ void hWriteSpiro() if (server.hasArg("laser") ) { lmValues[0] = server.arg("laser").toInt(); data["laser"] = (String)lmValues[0]; - String msg = "AT SLV "; - msg += (String)lmValues[0]; - laserSerial.println(msg); - delay(20); + String msg = "AT SLV "; + msg += (String)lmValues[0]; + laserSerial.println(msg); + delay(20); } if (server.hasArg("motor1") ) { lmValues[1] = server.arg("motor1").toInt(); data["motor1"] = (String)lmValues[1]; - String msg = "AT SMS 1 "; - msg += (String)lmValues[1]; - laserSerial.println(msg); - delay(20); + String msg = "AT SMS 1 "; + msg += (String)lmValues[1]; + laserSerial.println(msg); + delay(20); } if (server.hasArg("motor2") ) { lmValues[2] = server.arg("motor2").toInt(); data["motor2"] = (String)lmValues[2]; - String msg = "AT SMS 2 "; - msg += (String)lmValues[2]; - laserSerial.println(msg); - delay(20); + String msg = "AT SMS 2 "; + msg += (String)lmValues[2]; + laserSerial.println(msg); + delay(20); } if (server.hasArg("motor3") ) { lmValues[3] = server.arg("motor3").toInt(); data["motor3"] = (String)lmValues[3]; - String msg = "AT SMS 3 "; - msg += (String)lmValues[3]; - laserSerial.println(msg); - delay(20); + String msg = "AT SMS 3 "; + msg += (String)lmValues[3]; + laserSerial.println(msg); + delay(20); } root.prettyPrintTo(responseBuffer); server.send(200, "text/json", responseBuffer); @@ -219,7 +301,7 @@ void hWriteWifi() //root.prettyPrintTo(Serial); server.send(200, "text/json", responseBuffer); if (save) { - saveConfigFile(); + saveWifiConfig(); } if (apply) { setupWifi(); @@ -228,14 +310,67 @@ void hWriteWifi() responseBuffer = String(); } -bool saveConfigFile() { - StaticJsonBuffer<200> jsonBuffer; - JsonObject& json = jsonBuffer.createObject(); - json["apMode"] = apMode; - json["SSID"] = ssid; - json["Password"] = password; +boolean readPresetsFile() { + Serial.println("Reading presets.json"); + File configFile = SPIFFS.open("/presets.json", "r"); + if (!configFile) { + Serial.println("Failed to open config file"); + return false; + } + size_t size = configFile.size(); + if (size > 10024) { + Serial.println("Config file size is too large"); + return false; + } + // Allocate a buffer to store contents of the file. + std::unique_ptr buf(new char[size]); - File configFile = SPIFFS.open("/wifi.json", "w"); + DynamicJsonBuffer presetsBuffer(presetsBufferSize); + configFile.readBytes(buf.get(), size); + + JsonObject& root = presetsBuffer.parseObject(buf.get()); + //root.prettyPrintTo(Serial); + + JsonObject& sets = root["presets"]; + + for (JsonObject::iterator it = sets.begin(); it != sets.end(); ++it) + { + const char* keyStr = it->key; + unsigned int key = atoi(it->key); + + // it->value contains the JsonVariant which can be casted as usual + const char* value = it->value; + + JsonArray& values = sets[keyStr]; + for (int x = 0; x < 4; x++) + { + presets[key-1][x] = values[x]; + } + } + + if (!root.success()) { + Serial.println("Failed to parse preset config file"); + return false; + } + return true; +} + +bool savePresetFile() { + DynamicJsonBuffer presetsBuffer(presetsBufferSize); + JsonObject& json = presetsBuffer.createObject(); + JsonObject& sets = json.createNestedObject("presets"); + for (int i = 0; i < maxPresets; i++) + { + int b = i+1; + JsonArray& set = sets.createNestedArray((String)b); + for (int x = 0; x < 4; x++) + { + set.add(presets[i][x]); + } + } + //json.prettyPrintTo(Serial); + + File configFile = SPIFFS.open("/presets.json", "w"); if (!configFile) { //Serial.println("Failed to open config file for writing"); return false; @@ -244,19 +379,7 @@ bool saveConfigFile() { return true; } -void hSaveConf() { - bool success = saveConfigFile(); - if (success) - { - server.send(200, "text/plain", "saved config to file,
reset or /resetwifi to apply settings"); - } - else - { - server.send(500, "text/plain", "error saving file"); - } -} - -boolean readConfigFile() { +boolean readWifiConfig() { Serial.println("Reading wifi.json"); File configFile = SPIFFS.open("/wifi.json", "r"); if (!configFile) { @@ -294,6 +417,44 @@ boolean readConfigFile() { return true; } +bool saveWifiConfig() { + StaticJsonBuffer<200> jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + json["apMode"] = apMode; + json["SSID"] = ssid; + json["Password"] = password; + + File configFile = SPIFFS.open("/wifi.json", "w"); + if (!configFile) { + //Serial.println("Failed to open config file for writing"); + return false; + } + json.printTo(configFile); + return true; +} + +void presetToLaser(int nr) +{ + String msg = "AT SLV "; + msg += (String)presets[nr][0]; + laserSerial.println(msg); + delay(20); + msg = "AT SMS 1 "; + msg += (String)presets[nr][1]; + laserSerial.println(msg); + delay(20); + msg = "AT SMS 2 "; + msg += (String)presets[nr][2]; + laserSerial.println(msg); + delay(20); + msg = "AT SMS 3 "; + msg += (String)presets[nr][3]; + laserSerial.println(msg); + delay(20); + Serial.print("writenPresetToLaser: "); + Serial.println(nr); +} + void setupWifi() { WiFi.disconnect(); @@ -362,15 +523,18 @@ void setup(void) { - if (!readConfigFile()) + if (!readWifiConfig()) { Serial.println("reading wifi config failed, start SoftAP"); _apMode = 1; } delay(100); - + setupWifi(); - + + // loading presets + readPresetsFile(); + // Setup MDNS responder if (!MDNS.begin(myHostname)) { Serial.println("Error setting up MDNS responder!"); @@ -383,19 +547,10 @@ void setup(void) { //SERVER INIT //list directory - server.on("/files", HTTP_GET, hFileList); + server.on("/files", HTTP_GET, hFileList); server.on("/files", HTTP_POST, []() { server.send(400, "text/plain", "400 Bad Request"); - }); - server.on("/saveconf", HTTP_GET, []() { - server.send(400, "text/plain", "400 Bad Request"); }); - server.on("/saveconf", HTTP_POST, hSaveConf); - - server.on("/resetwifi", HTTP_GET, []() { - server.send(400, "text/plain", "400 Bad Request"); - }); - server.on("/resetwifi", HTTP_POST, setupWifi); server.on("/wificonfig", HTTP_GET, hReadWifi); server.on("/wificonfig", HTTP_POST, hWriteWifi); @@ -403,20 +558,50 @@ void setup(void) { server.on("/spirograph", HTTP_GET, hReadSpiro); server.on("/spirograph", HTTP_POST, hWriteSpiro); + + server.on("/presets", HTTP_GET, hReadPresets); + server.on("/presets", HTTP_POST, []() { + server.send(400, "text/plain", "400 Bad Request"); + }); + server.on("/preset", HTTP_GET, []() { + server.send(400, "text/plain", "400 Bad Request"); + }); + server.on("/preset", HTTP_POST, hWritePreset); + + + server.on("/presetMode", HTTP_GET, []() { + String json = "{"; + json += "\"presetMode\":" + String(presetMode); + json += "}"; + server.send(200, "text/json", json); + json = String(); + }); + server.on("/presetMode", HTTP_POST, []() { + if (server.hasArg("presetMode") ) { + presetMode = server.arg("presetMode").toInt(); + } + String json = "{"; + json += "\"presetMode\":" + String(presetMode); + json += "}"; + server.send(200, "text/json", json); + json = String(); + }); + server.on("/heap", HTTP_GET, []() { String json = "{"; json += "\"heap\":" + String(ESP.getFreeHeap()); json += "}"; server.send(200, "text/json", json); json = String(); - }); + }); server.on("/heap", HTTP_POST, []() { server.send(400, "text/plain", "400 Bad Request"); }); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP server started"); + } void handleNotFound() { @@ -437,5 +622,23 @@ void handleNotFound() { void loop(void) { server.handleClient(); + + if (presetMode == 1) + { + if (millis() - previousMillis >= cycleTime) + { + presetToLaser(activePreset); + if (activePreset < 128) + { + activePreset++; + } + else + { + activePreset = 0; + } + previousMillis = millis(); + } + } } +