├── .gitattributes ├── .gitignore ├── Doxyfile ├── LICENSE ├── README.md ├── examples └── Basic │ └── Basic.ino ├── extras └── docs │ ├── api.md │ ├── html │ ├── _s_p_i_f_f_s_logger_8h.html │ ├── _s_p_i_f_f_s_logger_8h.js │ ├── _s_p_i_f_f_s_logger_8h_source.html │ ├── _s_p_i_f_f_s_logger_base_8cpp.html │ ├── _s_p_i_f_f_s_logger_base_8cpp.js │ ├── _s_p_i_f_f_s_logger_base_8h.html │ ├── _s_p_i_f_f_s_logger_base_8h_source.html │ ├── annotated.html │ ├── annotated_dup.js │ ├── bc_s.png │ ├── bdwn.png │ ├── class_s_p_i_f_f_s_logger-members.html │ ├── class_s_p_i_f_f_s_logger.html │ ├── class_s_p_i_f_f_s_logger.js │ ├── class_s_p_i_f_f_s_logger_base-members.html │ ├── class_s_p_i_f_f_s_logger_base.html │ ├── class_s_p_i_f_f_s_logger_base.js │ ├── classes.html │ ├── closed.png │ ├── dir_68267d1309a1af8e8297ef4c3efbcdba.html │ ├── dir_68267d1309a1af8e8297ef4c3efbcdba.js │ ├── doc.png │ ├── doxygen.css │ ├── doxygen.png │ ├── dynsections.js │ ├── files.html │ ├── files.js │ ├── files_dup.js │ ├── folderclosed.png │ ├── folderopen.png │ ├── functions.html │ ├── functions_func.html │ ├── functions_vars.html │ ├── globals.html │ ├── globals_vars.html │ ├── hierarchy.html │ ├── hierarchy.js │ ├── index.html │ ├── jquery.js │ ├── menu.js │ ├── menudata.js │ ├── nav_f.png │ ├── nav_g.png │ ├── nav_h.png │ ├── navtree.css │ ├── navtree.js │ ├── navtreedata.js │ ├── navtreeindex0.js │ ├── open.png │ ├── resize.js │ ├── splitbar.png │ ├── struct_s_p_i_f_f_s_log_data-members.html │ ├── struct_s_p_i_f_f_s_log_data.html │ ├── struct_s_p_i_f_f_s_log_data.js │ ├── sync_off.png │ ├── sync_on.png │ ├── tab_a.png │ ├── tab_b.png │ ├── tab_h.png │ ├── tab_s.png │ └── tabs.css │ └── xml │ ├── _s_p_i_f_f_s_logger_8h.xml │ ├── _s_p_i_f_f_s_logger_base_8cpp.xml │ ├── _s_p_i_f_f_s_logger_base_8h.xml │ ├── class_s_p_i_f_f_s_logger.xml │ ├── class_s_p_i_f_f_s_logger_base.xml │ ├── combine.xslt │ ├── compound.xsd │ ├── dir_68267d1309a1af8e8297ef4c3efbcdba.xml │ ├── index.xml │ ├── index.xsd │ └── struct_s_p_i_f_f_s_log_data.xml ├── library.properties └── src ├── SPIFFSLogger.h ├── SPIFFSLoggerBase.cpp └── SPIFFSLoggerBase.h /.gitattributes: -------------------------------------------------------------------------------- 1 | extras/docs/* linguist-documentation -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SPIFFSLogger 2 | A minimal library for binary data logging in ESP8266 systems. 3 | 4 | ## Features 5 | 6 | * Easy to use 7 | * Stores data in binary along with a UTC timestamp 8 | * Results in about 50% space spavings when compared to logging the same data in CSV 9 | * Splits data into daily files, allowing for efficient search 10 | * Automatically rotates files, deleting the ones that exceed the specified age 11 | * Uses built-in ESP/newlib time functions 12 | 13 | ## Installing 14 | 15 | 1. Download the [latest release](https://github.com/bitmario/SPIFFSLogger/releases/latest) 16 | 2. Extract it into your libraries folder 17 | 3. Rename the folder from `SPIFFSLogger-x.x.x` to `SPIFFSLogger` 18 | 19 | ## Getting started 20 | 21 | See the summary below and try the [example](examples/Basic/Basic.ino). You may also want to take a peek at our [documentation](extras/docs/api.md). 22 | 23 | ### Required includes 24 | 25 | ```cpp 26 | #include 27 | ``` 28 | 29 | ### The SPIFFSLogData struct 30 | 31 | This struct represents the data as stored in SPIFFS (including the timestamp). It is returned in any logger read operations. 32 | 33 | Definition: 34 | 35 | ```cpp 36 | template 37 | struct SPIFFSLogData 38 | { 39 | time_t timestampUTC; /** creation time in UTC */ 40 | T data; /** data of type T */ 41 | }; 42 | ``` 43 | 44 | ### The SPIFFSLogger class 45 | 46 | This is the core of the library. You can create your logger like so: 47 | 48 | ```cpp 49 | // store ints, saving files in /log/ and keeping today + 7 days of history 50 | SPIFFSLogger logger("/log", 7); 51 | ``` 52 | 53 | We can also store a struct (which is probably more useful!): 54 | 55 | ```cpp 56 | struct EnvData { 57 | float temperature; 58 | float humidity; 59 | uint16_t pressure; 60 | }; 61 | 62 | SPIFFSLogger logger("/log", 7); 63 | ``` 64 | 65 | #### Initializing the logger 66 | 67 | This library uses the ESP8266 SPIFFS and built-in time functions so you must initialize those components and then call `logger.init()`. 68 | 69 | Your `setup()` should look something like this: 70 | 71 | ```cpp 72 | void setup() { 73 | // configure time however you like, we use NTP here 74 | wifiSetup(); // ommitted for brevity 75 | configTime(0, 0, "pool.ntp.org"); 76 | 77 | // initialize SPIFFS 78 | SPIFFS.begin(); 79 | 80 | // initialize our logger 81 | logger.init(); 82 | } 83 | ``` 84 | 85 | #### Running required operations 86 | 87 | You must call `logger.process()` in your loop to run the required operations (file updates and rotation). E.g.: 88 | 89 | ```cpp 90 | void loop() { 91 | // your code is here 92 | 93 | logger.process(); 94 | } 95 | ``` 96 | 97 | #### Writing data 98 | 99 | Simply call `logger.write()` and the data will be logged with the current timestamp: 100 | 101 | ```cpp 102 | struct EnvData data = { 23.54, 50.67, 1020 }; 103 | logger.write(data); 104 | ``` 105 | 106 | #### Reading data 107 | 108 | Reading the first row of today's logfile: 109 | 110 | ```cpp 111 | SPIFFSLogData data; 112 | logger.readRows(&data, time(nullptr), 0, 1); 113 | Serial.printf("TS: %d, T: %.2f, H: %.2f, %u\n", 114 | data.timestampUTC, 115 | data.data.temperature, 116 | data.data.humidity, 117 | data.data.pressure); 118 | ``` 119 | 120 | Or the last row: 121 | 122 | ```cpp 123 | const time_t now = time(nullptr); 124 | const size_t rowCount = logger.rowCount(now); 125 | logger.readRows(&data, now, rowCount - 1, 1); 126 | ``` 127 | 128 | Or 25 rows starting at the 50th: 129 | 130 | ```cpp 131 | SPIFFSLogData data[25]; 132 | logger.readRows(data, time(nullptr), 49, 25); 133 | ``` 134 | 135 | #### Filtering data 136 | 137 | Retrieving data from the last 20 minutes: 138 | 139 | ```cpp 140 | SPIFFSLogData data[25]; 141 | size_t count = logger.readRowsBetween( 142 | &data, // output 143 | now - (60 * 20), // time start (inclusive) 144 | now, // time end (inclusive) 145 | 0, // start index within results 146 | 25 // max number of rows to fetch 147 | ); 148 | 149 | for (int i=0; i 2 | #include 3 | #include 4 | #include 5 | 6 | #define SSID "Lab" 7 | #define PSK "WifiPassword" 8 | 9 | #define LOGGING_INTERVAL 5000 10 | 11 | // struct that defines the data we would like to log 12 | struct MyData 13 | { 14 | float temp; 15 | float humidity; 16 | }; 17 | 18 | // create a new logger which will store records of our MyData type in files with names like 19 | // /log/mydata/YYYYMMDD, keeping 1 day of history 20 | SPIFFSLogger logger("/log/mydata", 1); 21 | 22 | unsigned long lastLog = 0; 23 | 24 | void setup() 25 | { 26 | Serial.begin(115200); 27 | 28 | // we need wifi+NTP (or local/RTC) ESP8266 time 29 | wifiSetup(); 30 | timeSetup(); 31 | 32 | // we must always initialize the SPIFFS before doing anything with the logger 33 | SPIFFS.begin(); 34 | 35 | // initialize our logger 36 | logger.init(); 37 | 38 | // our data record size 39 | Serial.printf("sizeof(MyData): %u\n", sizeof(MyData)); 40 | // time_t timestamp + our data, as stored in SPIFFS 41 | Serial.printf("sizeof(SPIFFSLogData): %u\n", sizeof(SPIFFSLogData)); 42 | } 43 | 44 | void loop() 45 | { 46 | const unsigned long currentMillis = millis(); 47 | 48 | if (currentMillis - lastLog > LOGGING_INTERVAL) 49 | { 50 | // this is where you would fetch the values, but we just generate them randomly 51 | struct MyData data = { 52 | random(200, 300) / 10.0, // temp 53 | random(300, 700) / 10.0 // humidity 54 | }; 55 | // log the data 56 | Serial.printf("Writing temp: %.1f, humidity: %.1f\n", data.temp, data.humidity); 57 | logger.write(data); 58 | 59 | // fetch and display last values 60 | const time_t now = time(nullptr); 61 | const size_t rowCount = logger.rowCount(now); 62 | struct SPIFFSLogData readback; 63 | 64 | // read 1 item starting at index rowCount-1 from the logfile corresponding to the date now 65 | // and into the readback variable 66 | logger.readRows(&readback, now, rowCount - 1, 1); 67 | Serial.printf("Readback time: %d, temp: %.1f, humidity: %.1f\n", 68 | readback.timestampUTC, 69 | readback.data.temp, 70 | readback.data.humidity); 71 | 72 | Serial.printf("Current logfile has %u rows.\n", rowCount); 73 | 74 | // filtering example 75 | logger.readRowsBetween(&readback, // output 76 | now - (60 * 5), // time start (inclusive) 77 | now, // time end (inclusive) 78 | 0, // start index 79 | 1 // max number of rows to fetch (size your output buffer accordingly!) 80 | ); 81 | Serial.printf("First record in the last 5 minutes: %d, temp: %.1f, humidity: %.1f\n", 82 | readback.timestampUTC, 83 | readback.data.temp, 84 | readback.data.humidity); 85 | 86 | Serial.println(); 87 | 88 | lastLog = currentMillis; 89 | } 90 | 91 | // Processes file name changes and old file deletion according to the interval set 92 | // at initialization. Should always be called in the loop. 93 | logger.process(); 94 | } 95 | 96 | void wifiSetup() 97 | { 98 | WiFi.begin(SSID, PSK); 99 | 100 | Serial.print("Connecting"); 101 | while (WiFi.status() != WL_CONNECTED) 102 | { 103 | delay(500); 104 | Serial.print("."); 105 | } 106 | Serial.println(); 107 | 108 | Serial.print("Connected, IP address: "); 109 | Serial.println(WiFi.localIP()); 110 | } 111 | 112 | void timeSetup() 113 | { 114 | // details on ESP8266 time: https://github.com/d-a-v/Arduino/blob/goodies/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino 115 | 116 | // automatically sync UTC time using NTP 117 | configTime(0, 0, "pool.ntp.org"); 118 | 119 | // optionally, we could set a timezone as well, e.g.: 120 | // setenv("TZ", "WET0CET-1,M3.5.0/2:00:00,M10.5.0/2:00:00", 1); 121 | // tzset(); 122 | } 123 | -------------------------------------------------------------------------------- /extras/docs/api.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | Members | Descriptions 4 | --------------------------------|--------------------------------------------- 5 | `class `[`SPIFFSLogger`](#class_s_p_i_f_f_s_logger) | Minimal class template for binary data logging in ESP8266 SPIFFS. 6 | `class `[`SPIFFSLoggerBase`](#class_s_p_i_f_f_s_logger_base) | Base class for the [SPIFFSLogger](#class_s_p_i_f_f_s_logger) template, implementing common methods. 7 | `struct `[`SPIFFSLogData`](#struct_s_p_i_f_f_s_log_data) | Represents a data element as stored in SPIFFS, along with the creation timestamp. 8 | 9 | # class `SPIFFSLogger` 10 | 11 | ``` 12 | class SPIFFSLogger 13 | : public SPIFFSLoggerBase 14 | ``` 15 | 16 | Minimal class template for binary data logging in ESP8266 SPIFFS. 17 | 18 | Makes it easy to read, write and keep logs of relevant data, such as sensor readings in an efficient way, by storing data in raw, binary format along with a time_t. One file is created per UTC day to store the respective data, and deleted once it has reached the defined maximum age. 19 | 20 | #### Parameters 21 | * `T` type to store, e.g. a struct. 22 | 23 | ## Summary 24 | 25 | Members | Descriptions 26 | --------------------------------|--------------------------------------------- 27 | `public `[`SPIFFSLogger`](#class_s_p_i_f_f_s_logger_1afa8152a5d5d29fedbb04265cb4589359)`(const char * directory,uint16_t daysToKeep,uint16_t processInterval)` | Default constructor for [SPIFFSLogger](#class_s_p_i_f_f_s_logger). 28 | `public size_t `[`write`](#class_s_p_i_f_f_s_logger_1a2e914dd1884de9900288564a41bc55a4)`(const T & value)` | Write the specified value to the end of the current log file, with the current timestamp. 29 | `public size_t `[`readRows`](#class_s_p_i_f_f_s_logger_1aeceb2db3a41feb387e874f247657e19c)`(`[`SPIFFSLogData`](#struct_s_p_i_f_f_s_log_data)`< T > * output,time_t date,size_t startIdx,size_t maxCount)` | Read data from a daily logfile into a buffer. 30 | `public size_t `[`readRowsBetween`](#class_s_p_i_f_f_s_logger_1a8d82d01f694528becba720e0612dc48d)`(`[`SPIFFSLogData`](#struct_s_p_i_f_f_s_log_data)`< T > * output,time_t fromTime,time_t toTime,size_t startIdx,size_t maxCount)` | 31 | `public size_t `[`rowCount`](#class_s_p_i_f_f_s_logger_1ac539407d1bfebe9443393ea2e4047e29)`(time_t date)` | Get the number of entries for the specified date. 32 | `public size_t `[`rowCount`](#class_s_p_i_f_f_s_logger_1a7b59fa85e65ec2ca2fa2b26f22d4e936)`(File & logFile)` | Get the number of entries in the specified file. 33 | `public void `[`init`](#class_s_p_i_f_f_s_logger_base_1ad2270960852a999b0340fa4eab50f063)`()` | Initialize the logger. 34 | `public void `[`process`](#class_s_p_i_f_f_s_logger_base_1a22fdd2b540717853ae403edbc0ed1b7f)`()` | Process the file rotation and other required operations according to the defined processInterval. 35 | `protected time_t `[`_today`](#class_s_p_i_f_f_s_logger_base_1a77a967ae68a680dea5a647200ba49815) | current date, set in the last processing run 36 | `protected unsigned long `[`_lastProcess`](#class_s_p_i_f_f_s_logger_base_1ac1b33a4c97b2a45b2b178a261ebbb12c) | last processing millis() 37 | `protected const uint16_t `[`_processInterval`](#class_s_p_i_f_f_s_logger_base_1a517fa4d3854283ba7b2dba9bf0d09c84) | ms between processing runs 38 | `protected const uint16_t `[`_daysToKeep`](#class_s_p_i_f_f_s_logger_base_1a8feb62f012879aca79d600cf217c2098) | number of days to keep logs for 39 | `protected bool `[`_processNow`](#class_s_p_i_f_f_s_logger_base_1a978f0a636ce4d7a7f1640df124cc25ff) | force processing now, even if the processing interval hasn't passed 40 | `protected char `[`_directory`](#class_s_p_i_f_f_s_logger_base_1a829da5d8bf3d83ed24e608bb60fc623c) | base directory for log files 41 | `protected char `[`_curPath`](#class_s_p_i_f_f_s_logger_base_1a7f79553c53c7b5b6c87aaaa104d5a1e3) | path for today's file 42 | `protected void `[`_pathFromDate`](#class_s_p_i_f_f_s_logger_base_1abfba26125f8b32b4c8e2e3d29d65b31f)`(char * output,time_t date)` | Converts a time_t to that day's file path. 43 | `protected void `[`_updateCurPath`](#class_s_p_i_f_f_s_logger_base_1aa5679e47e144e591b5fa90fb31b65cbd)`()` | Updates the current path to match today's date. 44 | `protected void `[`_runRotation`](#class_s_p_i_f_f_s_logger_base_1a2e9e45428e1ffbe989dd7679c5def4fe)`()` | Deletes files older than the defined age limit. 45 | 46 | ## Members 47 | 48 | #### `public `[`SPIFFSLogger`](#class_s_p_i_f_f_s_logger_1afa8152a5d5d29fedbb04265cb4589359)`(const char * directory,uint16_t daysToKeep,uint16_t processInterval)` 49 | 50 | Default constructor for [SPIFFSLogger](#class_s_p_i_f_f_s_logger). 51 | 52 | #### Parameters 53 | * `directory` char array with the base directory where files will be stored. Should not include trailing slash and should be 20 characters or less. 54 | 55 | * `daysToKeep` number of days to keep in flash. Once files are past this age, they are deleted. 56 | 57 | * `processInterval` milliseconds between file directory updates and file rotation. 58 | 59 | #### `public size_t `[`write`](#class_s_p_i_f_f_s_logger_1a2e914dd1884de9900288564a41bc55a4)`(const T & value)` 60 | 61 | Write the specified value to the end of the current log file, with the current timestamp. 62 | 63 | #### Parameters 64 | * `value` the value to write 65 | 66 | #### `public size_t `[`readRows`](#class_s_p_i_f_f_s_logger_1aeceb2db3a41feb387e874f247657e19c)`(`[`SPIFFSLogData`](#struct_s_p_i_f_f_s_log_data)`< T > * output,time_t date,size_t startIdx,size_t maxCount)` 67 | 68 | Read data from a daily logfile into a buffer. 69 | 70 | #### Parameters 71 | * `output` buffer where data will be written 72 | 73 | * `date` time_t representing the date of the file 74 | 75 | * `startIdx` 0-based index of the entries to read (row number) 76 | 77 | * `maxCount` maximum number of entries to read 78 | 79 | #### Returns 80 | number of entries read 81 | 82 | #### `public size_t `[`readRowsBetween`](#class_s_p_i_f_f_s_logger_1a8d82d01f694528becba720e0612dc48d)`(`[`SPIFFSLogData`](#struct_s_p_i_f_f_s_log_data)`< T > * output,time_t fromTime,time_t toTime,size_t startIdx,size_t maxCount)` 83 | 84 | #### `public size_t `[`rowCount`](#class_s_p_i_f_f_s_logger_1ac539407d1bfebe9443393ea2e4047e29)`(time_t date)` 85 | 86 | Get the number of entries for the specified date. 87 | 88 | #### Parameters 89 | * `date` a time_t representing the day to check 90 | 91 | #### Returns 92 | number of entries 93 | 94 | #### `public size_t `[`rowCount`](#class_s_p_i_f_f_s_logger_1a7b59fa85e65ec2ca2fa2b26f22d4e936)`(File & logFile)` 95 | 96 | Get the number of entries in the specified file. 97 | 98 | #### Parameters 99 | * `logFile` a File object for a valid logfile 100 | 101 | #### Returns 102 | number of entries 103 | 104 | #### `public void `[`init`](#class_s_p_i_f_f_s_logger_base_1ad2270960852a999b0340fa4eab50f063)`()` 105 | 106 | Initialize the logger. 107 | 108 | Should be called after initializing SPIFFS and before before any other method. 109 | 110 | #### `public void `[`process`](#class_s_p_i_f_f_s_logger_base_1a22fdd2b540717853ae403edbc0ed1b7f)`()` 111 | 112 | Process the file rotation and other required operations according to the defined processInterval. 113 | 114 | Should be called as often as possible, i.e. in loop(). 115 | 116 | #### `protected time_t `[`_today`](#class_s_p_i_f_f_s_logger_base_1a77a967ae68a680dea5a647200ba49815) 117 | 118 | current date, set in the last processing run 119 | 120 | #### `protected unsigned long `[`_lastProcess`](#class_s_p_i_f_f_s_logger_base_1ac1b33a4c97b2a45b2b178a261ebbb12c) 121 | 122 | last processing millis() 123 | 124 | #### `protected const uint16_t `[`_processInterval`](#class_s_p_i_f_f_s_logger_base_1a517fa4d3854283ba7b2dba9bf0d09c84) 125 | 126 | ms between processing runs 127 | 128 | #### `protected const uint16_t `[`_daysToKeep`](#class_s_p_i_f_f_s_logger_base_1a8feb62f012879aca79d600cf217c2098) 129 | 130 | number of days to keep logs for 131 | 132 | #### `protected bool `[`_processNow`](#class_s_p_i_f_f_s_logger_base_1a978f0a636ce4d7a7f1640df124cc25ff) 133 | 134 | force processing now, even if the processing interval hasn't passed 135 | 136 | #### `protected char `[`_directory`](#class_s_p_i_f_f_s_logger_base_1a829da5d8bf3d83ed24e608bb60fc623c) 137 | 138 | base directory for log files 139 | 140 | #### `protected char `[`_curPath`](#class_s_p_i_f_f_s_logger_base_1a7f79553c53c7b5b6c87aaaa104d5a1e3) 141 | 142 | path for today's file 143 | 144 | #### `protected void `[`_pathFromDate`](#class_s_p_i_f_f_s_logger_base_1abfba26125f8b32b4c8e2e3d29d65b31f)`(char * output,time_t date)` 145 | 146 | Converts a time_t to that day's file path. 147 | 148 | #### `protected void `[`_updateCurPath`](#class_s_p_i_f_f_s_logger_base_1aa5679e47e144e591b5fa90fb31b65cbd)`()` 149 | 150 | Updates the current path to match today's date. 151 | 152 | #### `protected void `[`_runRotation`](#class_s_p_i_f_f_s_logger_base_1a2e9e45428e1ffbe989dd7679c5def4fe)`()` 153 | 154 | Deletes files older than the defined age limit. 155 | 156 | # class `SPIFFSLoggerBase` 157 | 158 | Base class for the [SPIFFSLogger](#class_s_p_i_f_f_s_logger) template, implementing common methods. 159 | 160 | Should not be used directly. 161 | 162 | ## Summary 163 | 164 | Members | Descriptions 165 | --------------------------------|--------------------------------------------- 166 | `public void `[`init`](#class_s_p_i_f_f_s_logger_base_1ad2270960852a999b0340fa4eab50f063)`()` | Initialize the logger. 167 | `public void `[`process`](#class_s_p_i_f_f_s_logger_base_1a22fdd2b540717853ae403edbc0ed1b7f)`()` | Process the file rotation and other required operations according to the defined processInterval. 168 | `protected time_t `[`_today`](#class_s_p_i_f_f_s_logger_base_1a77a967ae68a680dea5a647200ba49815) | current date, set in the last processing run 169 | `protected unsigned long `[`_lastProcess`](#class_s_p_i_f_f_s_logger_base_1ac1b33a4c97b2a45b2b178a261ebbb12c) | last processing millis() 170 | `protected const uint16_t `[`_processInterval`](#class_s_p_i_f_f_s_logger_base_1a517fa4d3854283ba7b2dba9bf0d09c84) | ms between processing runs 171 | `protected const uint16_t `[`_daysToKeep`](#class_s_p_i_f_f_s_logger_base_1a8feb62f012879aca79d600cf217c2098) | number of days to keep logs for 172 | `protected bool `[`_processNow`](#class_s_p_i_f_f_s_logger_base_1a978f0a636ce4d7a7f1640df124cc25ff) | force processing now, even if the processing interval hasn't passed 173 | `protected char `[`_directory`](#class_s_p_i_f_f_s_logger_base_1a829da5d8bf3d83ed24e608bb60fc623c) | base directory for log files 174 | `protected char `[`_curPath`](#class_s_p_i_f_f_s_logger_base_1a7f79553c53c7b5b6c87aaaa104d5a1e3) | path for today's file 175 | `protected `[`SPIFFSLoggerBase`](#class_s_p_i_f_f_s_logger_base_1ace02cadd2e608c940728ae9f5242bbcc)`(const char * directory,uint16_t daysToKeep,uint16_t processInterval)` | 176 | `protected void `[`_pathFromDate`](#class_s_p_i_f_f_s_logger_base_1abfba26125f8b32b4c8e2e3d29d65b31f)`(char * output,time_t date)` | Converts a time_t to that day's file path. 177 | `protected void `[`_updateCurPath`](#class_s_p_i_f_f_s_logger_base_1aa5679e47e144e591b5fa90fb31b65cbd)`()` | Updates the current path to match today's date. 178 | `protected void `[`_runRotation`](#class_s_p_i_f_f_s_logger_base_1a2e9e45428e1ffbe989dd7679c5def4fe)`()` | Deletes files older than the defined age limit. 179 | 180 | ## Members 181 | 182 | #### `public void `[`init`](#class_s_p_i_f_f_s_logger_base_1ad2270960852a999b0340fa4eab50f063)`()` 183 | 184 | Initialize the logger. 185 | 186 | Should be called after initializing SPIFFS and before before any other method. 187 | 188 | #### `public void `[`process`](#class_s_p_i_f_f_s_logger_base_1a22fdd2b540717853ae403edbc0ed1b7f)`()` 189 | 190 | Process the file rotation and other required operations according to the defined processInterval. 191 | 192 | Should be called as often as possible, i.e. in loop(). 193 | 194 | #### `protected time_t `[`_today`](#class_s_p_i_f_f_s_logger_base_1a77a967ae68a680dea5a647200ba49815) 195 | 196 | current date, set in the last processing run 197 | 198 | #### `protected unsigned long `[`_lastProcess`](#class_s_p_i_f_f_s_logger_base_1ac1b33a4c97b2a45b2b178a261ebbb12c) 199 | 200 | last processing millis() 201 | 202 | #### `protected const uint16_t `[`_processInterval`](#class_s_p_i_f_f_s_logger_base_1a517fa4d3854283ba7b2dba9bf0d09c84) 203 | 204 | ms between processing runs 205 | 206 | #### `protected const uint16_t `[`_daysToKeep`](#class_s_p_i_f_f_s_logger_base_1a8feb62f012879aca79d600cf217c2098) 207 | 208 | number of days to keep logs for 209 | 210 | #### `protected bool `[`_processNow`](#class_s_p_i_f_f_s_logger_base_1a978f0a636ce4d7a7f1640df124cc25ff) 211 | 212 | force processing now, even if the processing interval hasn't passed 213 | 214 | #### `protected char `[`_directory`](#class_s_p_i_f_f_s_logger_base_1a829da5d8bf3d83ed24e608bb60fc623c) 215 | 216 | base directory for log files 217 | 218 | #### `protected char `[`_curPath`](#class_s_p_i_f_f_s_logger_base_1a7f79553c53c7b5b6c87aaaa104d5a1e3) 219 | 220 | path for today's file 221 | 222 | #### `protected `[`SPIFFSLoggerBase`](#class_s_p_i_f_f_s_logger_base_1ace02cadd2e608c940728ae9f5242bbcc)`(const char * directory,uint16_t daysToKeep,uint16_t processInterval)` 223 | 224 | #### `protected void `[`_pathFromDate`](#class_s_p_i_f_f_s_logger_base_1abfba26125f8b32b4c8e2e3d29d65b31f)`(char * output,time_t date)` 225 | 226 | Converts a time_t to that day's file path. 227 | 228 | #### `protected void `[`_updateCurPath`](#class_s_p_i_f_f_s_logger_base_1aa5679e47e144e591b5fa90fb31b65cbd)`()` 229 | 230 | Updates the current path to match today's date. 231 | 232 | #### `protected void `[`_runRotation`](#class_s_p_i_f_f_s_logger_base_1a2e9e45428e1ffbe989dd7679c5def4fe)`()` 233 | 234 | Deletes files older than the defined age limit. 235 | 236 | # struct `SPIFFSLogData` 237 | 238 | Represents a data element as stored in SPIFFS, along with the creation timestamp. 239 | 240 | #### Parameters 241 | * `T` type to store, e.g. a struct. 242 | 243 | ## Summary 244 | 245 | Members | Descriptions 246 | --------------------------------|--------------------------------------------- 247 | `public time_t `[`timestampUTC`](#struct_s_p_i_f_f_s_log_data_1a692b3adc90780d9388d6833d2170400c) | creation time in UTC 248 | `public T `[`data`](#struct_s_p_i_f_f_s_log_data_1a071121efdc7f6d95adc4dcdf736a84ec) | data of type T 249 | 250 | ## Members 251 | 252 | #### `public time_t `[`timestampUTC`](#struct_s_p_i_f_f_s_log_data_1a692b3adc90780d9388d6833d2170400c) 253 | 254 | creation time in UTC 255 | 256 | #### `public T `[`data`](#struct_s_p_i_f_f_s_log_data_1a071121efdc7f6d95adc4dcdf736a84ec) 257 | 258 | data of type T 259 | 260 | Generated by [Moxygen](https://sourcey.com/moxygen) -------------------------------------------------------------------------------- /extras/docs/html/_s_p_i_f_f_s_logger_8h.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: src/SPIFFSLogger.h File Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 | Classes
65 |
66 |
SPIFFSLogger.h File Reference
67 |
68 |
69 |
#include "SPIFFSLoggerBase.h"
70 |
71 |

Go to the source code of this file.

72 | 73 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |

74 | Classes

struct  SPIFFSLogData< T >
 Represents a data element as stored in SPIFFS, along with the creation timestamp. More...
 
class  SPIFFSLogger< T >
 Minimal class template for binary data logging in ESP8266 SPIFFS. More...
 
82 |
83 |
84 | 85 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /extras/docs/html/_s_p_i_f_f_s_logger_8h.js: -------------------------------------------------------------------------------- 1 | var _s_p_i_f_f_s_logger_8h = 2 | [ 3 | [ "SPIFFSLogData", "struct_s_p_i_f_f_s_log_data.html", "struct_s_p_i_f_f_s_log_data" ], 4 | [ "SPIFFSLogger", "class_s_p_i_f_f_s_logger.html", "class_s_p_i_f_f_s_logger" ] 5 | ]; -------------------------------------------------------------------------------- /extras/docs/html/_s_p_i_f_f_s_logger_base_8cpp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: src/SPIFFSLoggerBase.cpp File Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 | Variables
65 |
66 |
SPIFFSLoggerBase.cpp File Reference
67 |
68 |
69 |
#include "SPIFFSLoggerBase.h"
70 |
71 | 73 | 74 | 75 |

72 | Variables

const char _logFilenameFormat [] PROGMEM = "%s/%d%02d%02d"
 
76 |

Variable Documentation

77 | 78 |

◆ PROGMEM

79 | 80 |
81 |
82 | 83 | 84 | 85 | 86 |
const char _logFilenameFormat [] PROGMEM = "%s/%d%02d%02d"
87 |
88 | 89 |
90 |
91 |
92 |
93 | 94 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /extras/docs/html/_s_p_i_f_f_s_logger_base_8cpp.js: -------------------------------------------------------------------------------- 1 | var _s_p_i_f_f_s_logger_base_8cpp = 2 | [ 3 | [ "PROGMEM", "_s_p_i_f_f_s_logger_base_8cpp.html#af70a7c4bf0e665786ae633f14c7b351f", null ] 4 | ]; -------------------------------------------------------------------------------- /extras/docs/html/_s_p_i_f_f_s_logger_base_8h.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: src/SPIFFSLoggerBase.h File Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 | Classes
65 |
66 |
SPIFFSLoggerBase.h File Reference
67 |
68 |
69 |
#include <Arduino.h>
70 | #include <FS.h>
71 | #include <time.h>
72 |
73 |

Go to the source code of this file.

74 | 75 | 77 | 78 | 79 | 80 |

76 | Classes

class  SPIFFSLoggerBase
 Base class for the SPIFFSLogger template, implementing common methods. More...
 
81 |
82 |
83 | 84 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /extras/docs/html/annotated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Class List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
Class List
65 |
66 |
67 |
Here are the classes, structs, unions and interfaces with brief descriptions:
68 | 69 | 70 | 71 | 72 |
 CSPIFFSLogDataRepresents a data element as stored in SPIFFS, along with the creation timestamp
 CSPIFFSLoggerMinimal class template for binary data logging in ESP8266 SPIFFS
 CSPIFFSLoggerBaseBase class for the SPIFFSLogger template, implementing common methods
73 |
74 |
75 |
76 | 77 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /extras/docs/html/annotated_dup.js: -------------------------------------------------------------------------------- 1 | var annotated_dup = 2 | [ 3 | [ "SPIFFSLogData", "struct_s_p_i_f_f_s_log_data.html", "struct_s_p_i_f_f_s_log_data" ], 4 | [ "SPIFFSLogger", "class_s_p_i_f_f_s_logger.html", "class_s_p_i_f_f_s_logger" ], 5 | [ "SPIFFSLoggerBase", "class_s_p_i_f_f_s_logger_base.html", "class_s_p_i_f_f_s_logger_base" ] 6 | ]; -------------------------------------------------------------------------------- /extras/docs/html/bc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/bc_s.png -------------------------------------------------------------------------------- /extras/docs/html/bdwn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/bdwn.png -------------------------------------------------------------------------------- /extras/docs/html/class_s_p_i_f_f_s_logger-members.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Member List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
SPIFFSLogger< T > Member List
65 |
66 |
67 | 68 |

This is the complete list of members for SPIFFSLogger< T >, including all inherited members.

69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
_curPathSPIFFSLoggerBaseprotected
_daysToKeepSPIFFSLoggerBaseprotected
_directorySPIFFSLoggerBaseprotected
_filenameToDate(const char *filename)SPIFFSLoggerBaseprotectedstatic
_lastProcessSPIFFSLoggerBaseprotected
_pathFromDate(char *output, time_t date)SPIFFSLoggerBaseprotected
_processIntervalSPIFFSLoggerBaseprotected
_processNowSPIFFSLoggerBaseprotected
_runRotation()SPIFFSLoggerBaseprotected
_timegm(struct tm *tm)SPIFFSLoggerBaseprotectedstatic
_todaySPIFFSLoggerBaseprotected
_updateCurPath()SPIFFSLoggerBaseprotected
init()SPIFFSLoggerBase
process()SPIFFSLoggerBase
readRows(SPIFFSLogData< T > *output, time_t date, size_t startIdx, size_t maxCount)SPIFFSLogger< T >
readRowsBetween(SPIFFSLogData< T > *output, time_t fromTime, time_t toTime, size_t startIdx, size_t maxCount)SPIFFSLogger< T >
rowCount(time_t date)SPIFFSLogger< T >
rowCount(File &logFile)SPIFFSLogger< T >
SPIFFSLogger(const char *directory, uint16_t daysToKeep=7, uint16_t processInterval=1000)SPIFFSLogger< T >
SPIFFSLoggerBase(const char *directory, uint16_t daysToKeep, uint16_t processInterval)SPIFFSLoggerBaseprotected
write(const T &value)SPIFFSLogger< T >
92 |
93 | 94 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /extras/docs/html/class_s_p_i_f_f_s_logger.js: -------------------------------------------------------------------------------- 1 | var class_s_p_i_f_f_s_logger = 2 | [ 3 | [ "SPIFFSLogger", "class_s_p_i_f_f_s_logger.html#afa8152a5d5d29fedbb04265cb4589359", null ], 4 | [ "_pathFromDate", "class_s_p_i_f_f_s_logger.html#abfba26125f8b32b4c8e2e3d29d65b31f", null ], 5 | [ "_runRotation", "class_s_p_i_f_f_s_logger.html#a2e9e45428e1ffbe989dd7679c5def4fe", null ], 6 | [ "_updateCurPath", "class_s_p_i_f_f_s_logger.html#aa5679e47e144e591b5fa90fb31b65cbd", null ], 7 | [ "init", "class_s_p_i_f_f_s_logger.html#ad2270960852a999b0340fa4eab50f063", null ], 8 | [ "process", "class_s_p_i_f_f_s_logger.html#a22fdd2b540717853ae403edbc0ed1b7f", null ], 9 | [ "readRows", "class_s_p_i_f_f_s_logger.html#aeceb2db3a41feb387e874f247657e19c", null ], 10 | [ "readRowsBetween", "class_s_p_i_f_f_s_logger.html#a8d82d01f694528becba720e0612dc48d", null ], 11 | [ "rowCount", "class_s_p_i_f_f_s_logger.html#ac539407d1bfebe9443393ea2e4047e29", null ], 12 | [ "rowCount", "class_s_p_i_f_f_s_logger.html#a7b59fa85e65ec2ca2fa2b26f22d4e936", null ], 13 | [ "write", "class_s_p_i_f_f_s_logger.html#a2e914dd1884de9900288564a41bc55a4", null ], 14 | [ "_curPath", "class_s_p_i_f_f_s_logger.html#a7f79553c53c7b5b6c87aaaa104d5a1e3", null ], 15 | [ "_daysToKeep", "class_s_p_i_f_f_s_logger.html#a8feb62f012879aca79d600cf217c2098", null ], 16 | [ "_directory", "class_s_p_i_f_f_s_logger.html#a829da5d8bf3d83ed24e608bb60fc623c", null ], 17 | [ "_lastProcess", "class_s_p_i_f_f_s_logger.html#ac1b33a4c97b2a45b2b178a261ebbb12c", null ], 18 | [ "_processInterval", "class_s_p_i_f_f_s_logger.html#a517fa4d3854283ba7b2dba9bf0d09c84", null ], 19 | [ "_processNow", "class_s_p_i_f_f_s_logger.html#a978f0a636ce4d7a7f1640df124cc25ff", null ], 20 | [ "_today", "class_s_p_i_f_f_s_logger.html#a77a967ae68a680dea5a647200ba49815", null ] 21 | ]; -------------------------------------------------------------------------------- /extras/docs/html/class_s_p_i_f_f_s_logger_base-members.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Member List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
SPIFFSLoggerBase Member List
65 |
66 |
67 | 68 |

This is the complete list of members for SPIFFSLoggerBase, including all inherited members.

69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
_curPathSPIFFSLoggerBaseprotected
_daysToKeepSPIFFSLoggerBaseprotected
_directorySPIFFSLoggerBaseprotected
_filenameToDate(const char *filename)SPIFFSLoggerBaseprotectedstatic
_lastProcessSPIFFSLoggerBaseprotected
_pathFromDate(char *output, time_t date)SPIFFSLoggerBaseprotected
_processIntervalSPIFFSLoggerBaseprotected
_processNowSPIFFSLoggerBaseprotected
_runRotation()SPIFFSLoggerBaseprotected
_timegm(struct tm *tm)SPIFFSLoggerBaseprotectedstatic
_todaySPIFFSLoggerBaseprotected
_updateCurPath()SPIFFSLoggerBaseprotected
init()SPIFFSLoggerBase
process()SPIFFSLoggerBase
SPIFFSLoggerBase(const char *directory, uint16_t daysToKeep, uint16_t processInterval)SPIFFSLoggerBaseprotected
86 |
87 | 88 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /extras/docs/html/class_s_p_i_f_f_s_logger_base.js: -------------------------------------------------------------------------------- 1 | var class_s_p_i_f_f_s_logger_base = 2 | [ 3 | [ "SPIFFSLoggerBase", "class_s_p_i_f_f_s_logger_base.html#ace02cadd2e608c940728ae9f5242bbcc", null ], 4 | [ "_pathFromDate", "class_s_p_i_f_f_s_logger_base.html#abfba26125f8b32b4c8e2e3d29d65b31f", null ], 5 | [ "_runRotation", "class_s_p_i_f_f_s_logger_base.html#a2e9e45428e1ffbe989dd7679c5def4fe", null ], 6 | [ "_updateCurPath", "class_s_p_i_f_f_s_logger_base.html#aa5679e47e144e591b5fa90fb31b65cbd", null ], 7 | [ "init", "class_s_p_i_f_f_s_logger_base.html#ad2270960852a999b0340fa4eab50f063", null ], 8 | [ "process", "class_s_p_i_f_f_s_logger_base.html#a22fdd2b540717853ae403edbc0ed1b7f", null ], 9 | [ "_curPath", "class_s_p_i_f_f_s_logger_base.html#a7f79553c53c7b5b6c87aaaa104d5a1e3", null ], 10 | [ "_daysToKeep", "class_s_p_i_f_f_s_logger_base.html#a8feb62f012879aca79d600cf217c2098", null ], 11 | [ "_directory", "class_s_p_i_f_f_s_logger_base.html#a829da5d8bf3d83ed24e608bb60fc623c", null ], 12 | [ "_lastProcess", "class_s_p_i_f_f_s_logger_base.html#ac1b33a4c97b2a45b2b178a261ebbb12c", null ], 13 | [ "_processInterval", "class_s_p_i_f_f_s_logger_base.html#a517fa4d3854283ba7b2dba9bf0d09c84", null ], 14 | [ "_processNow", "class_s_p_i_f_f_s_logger_base.html#a978f0a636ce4d7a7f1640df124cc25ff", null ], 15 | [ "_today", "class_s_p_i_f_f_s_logger_base.html#a77a967ae68a680dea5a647200ba49815", null ] 16 | ]; -------------------------------------------------------------------------------- /extras/docs/html/classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Class Index 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
Class Index
65 |
66 |
67 | 68 | 69 | 71 | 72 | 73 | 74 |
  s  
70 |
SPIFFSLogger   SPIFFSLoggerBase   
SPIFFSLogData   
75 | 76 |
77 |
78 | 79 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /extras/docs/html/closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/closed.png -------------------------------------------------------------------------------- /extras/docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: src Directory Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
src Directory Reference
65 |
66 |
67 | 68 | 70 | 71 | 72 | 73 | 74 | 75 | 76 |

69 | Files

file  SPIFFSLogger.h [code]
 
file  SPIFFSLoggerBase.cpp
 
file  SPIFFSLoggerBase.h [code]
 
77 |
78 |
79 | 80 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /extras/docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.js: -------------------------------------------------------------------------------- 1 | var dir_68267d1309a1af8e8297ef4c3efbcdba = 2 | [ 3 | [ "SPIFFSLogger.h", "_s_p_i_f_f_s_logger_8h.html", [ 4 | [ "SPIFFSLogData", "struct_s_p_i_f_f_s_log_data.html", "struct_s_p_i_f_f_s_log_data" ], 5 | [ "SPIFFSLogger", "class_s_p_i_f_f_s_logger.html", "class_s_p_i_f_f_s_logger" ] 6 | ] ], 7 | [ "SPIFFSLoggerBase.cpp", "_s_p_i_f_f_s_logger_base_8cpp.html", "_s_p_i_f_f_s_logger_base_8cpp" ], 8 | [ "SPIFFSLoggerBase.h", "_s_p_i_f_f_s_logger_base_8h.html", [ 9 | [ "SPIFFSLoggerBase", "class_s_p_i_f_f_s_logger_base.html", "class_s_p_i_f_f_s_logger_base" ] 10 | ] ] 11 | ]; -------------------------------------------------------------------------------- /extras/docs/html/doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/doc.png -------------------------------------------------------------------------------- /extras/docs/html/doxygen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/doxygen.png -------------------------------------------------------------------------------- /extras/docs/html/dynsections.js: -------------------------------------------------------------------------------- 1 | function toggleVisibility(linkObj) 2 | { 3 | var base = $(linkObj).attr('id'); 4 | var summary = $('#'+base+'-summary'); 5 | var content = $('#'+base+'-content'); 6 | var trigger = $('#'+base+'-trigger'); 7 | var src=$(trigger).attr('src'); 8 | if (content.is(':visible')===true) { 9 | content.hide(); 10 | summary.show(); 11 | $(linkObj).addClass('closed').removeClass('opened'); 12 | $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); 13 | } else { 14 | content.show(); 15 | summary.hide(); 16 | $(linkObj).removeClass('closed').addClass('opened'); 17 | $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); 18 | } 19 | return false; 20 | } 21 | 22 | function updateStripes() 23 | { 24 | $('table.directory tr'). 25 | removeClass('even').filter(':visible:even').addClass('even'); 26 | } 27 | 28 | function toggleLevel(level) 29 | { 30 | $('table.directory tr').each(function() { 31 | var l = this.id.split('_').length-1; 32 | var i = $('#img'+this.id.substring(3)); 33 | var a = $('#arr'+this.id.substring(3)); 34 | if (l 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: File List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
File List
65 |
66 |
67 |
Here is a list of all files with brief descriptions:
68 |
[detail level 12]
69 | 70 | 71 | 72 | 73 |
  src
 SPIFFSLogger.h
 SPIFFSLoggerBase.cpp
 SPIFFSLoggerBase.h
74 |
75 |
76 |
77 | 78 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /extras/docs/html/files.js: -------------------------------------------------------------------------------- 1 | var files = 2 | [ 3 | [ "src", "dir_68267d1309a1af8e8297ef4c3efbcdba.html", "dir_68267d1309a1af8e8297ef4c3efbcdba" ] 4 | ]; -------------------------------------------------------------------------------- /extras/docs/html/files_dup.js: -------------------------------------------------------------------------------- 1 | var files_dup = 2 | [ 3 | [ "src", "dir_68267d1309a1af8e8297ef4c3efbcdba.html", "dir_68267d1309a1af8e8297ef4c3efbcdba" ] 4 | ]; -------------------------------------------------------------------------------- /extras/docs/html/folderclosed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/folderclosed.png -------------------------------------------------------------------------------- /extras/docs/html/folderopen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/folderopen.png -------------------------------------------------------------------------------- /extras/docs/html/functions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Class Members 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
Here is a list of all class members with links to the classes they belong to:
131 |
132 |
133 | 134 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /extras/docs/html/functions_func.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Class Members - Functions 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |   104 |
105 |
106 | 107 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /extras/docs/html/functions_vars.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Class Members - Variables 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |   92 |
93 |
94 | 95 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /extras/docs/html/globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: File Members 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
Here is a list of all file members with links to the files they belong to:
68 |
69 |
70 | 71 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /extras/docs/html/globals_vars.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: File Members 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |   68 |
69 |
70 | 71 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /extras/docs/html/hierarchy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Class Hierarchy 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
Class Hierarchy
65 |
66 |
67 |
This inheritance list is sorted roughly, but not completely, alphabetically:
68 |
[detail level 12]
69 | 70 | 71 | 72 |
 CSPIFFSLogData< T >Represents a data element as stored in SPIFFS, along with the creation timestamp
 CSPIFFSLoggerBaseBase class for the SPIFFSLogger template, implementing common methods
 CSPIFFSLogger< T >Minimal class template for binary data logging in ESP8266 SPIFFS
73 |
74 |
75 |
76 | 77 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /extras/docs/html/hierarchy.js: -------------------------------------------------------------------------------- 1 | var hierarchy = 2 | [ 3 | [ "SPIFFSLogData< T >", "struct_s_p_i_f_f_s_log_data.html", null ], 4 | [ "SPIFFSLoggerBase", "class_s_p_i_f_f_s_logger_base.html", [ 5 | [ "SPIFFSLogger< T >", "class_s_p_i_f_f_s_logger.html", null ] 6 | ] ] 7 | ]; -------------------------------------------------------------------------------- /extras/docs/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Main Page 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | 33 | 34 | 35 |
28 |
SPIFFSLogger 29 |  v0.1.2 30 |
31 |
A minimal library for binary data logging in ESP8266
32 |
36 |
37 | 38 | 39 | 40 | 41 | 46 | 47 |
48 |
49 | 54 |
56 |
57 |
58 | 61 |
62 |
63 |
64 |
SPIFFSLogger Documentation
65 |
66 |
67 |
68 |
69 | 70 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /extras/docs/html/menu.js: -------------------------------------------------------------------------------- 1 | function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { 2 | function makeTree(data,relPath) { 3 | var result=''; 4 | if ('children' in data) { 5 | result+=''; 12 | } 13 | return result; 14 | } 15 | 16 | $('#main-nav').append(makeTree(menudata,relPath)); 17 | $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); 18 | if (searchEnabled) { 19 | if (serverSide) { 20 | $('#main-menu').append('
  • '); 21 | } else { 22 | $('#main-menu').append('
  • '); 23 | } 24 | } 25 | $('#main-menu').smartmenus(); 26 | } 27 | -------------------------------------------------------------------------------- /extras/docs/html/menudata.js: -------------------------------------------------------------------------------- 1 | var menudata={children:[ 2 | {text:"Main Page",url:"index.html"}, 3 | {text:"Classes",url:"annotated.html",children:[ 4 | {text:"Class List",url:"annotated.html"}, 5 | {text:"Class Index",url:"classes.html"}, 6 | {text:"Class Hierarchy",url:"hierarchy.html"}, 7 | {text:"Class Members",url:"functions.html",children:[ 8 | {text:"All",url:"functions.html"}, 9 | {text:"Functions",url:"functions_func.html"}, 10 | {text:"Variables",url:"functions_vars.html"}]}]}, 11 | {text:"Files",url:"files.html",children:[ 12 | {text:"File List",url:"files.html"}, 13 | {text:"File Members",url:"globals.html",children:[ 14 | {text:"All",url:"globals.html"}, 15 | {text:"Variables",url:"globals_vars.html"}]}]}]} 16 | -------------------------------------------------------------------------------- /extras/docs/html/nav_f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/nav_f.png -------------------------------------------------------------------------------- /extras/docs/html/nav_g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/nav_g.png -------------------------------------------------------------------------------- /extras/docs/html/nav_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/nav_h.png -------------------------------------------------------------------------------- /extras/docs/html/navtree.css: -------------------------------------------------------------------------------- 1 | #nav-tree .children_ul { 2 | margin:0; 3 | padding:4px; 4 | } 5 | 6 | #nav-tree ul { 7 | list-style:none outside none; 8 | margin:0px; 9 | padding:0px; 10 | } 11 | 12 | #nav-tree li { 13 | white-space:nowrap; 14 | margin:0px; 15 | padding:0px; 16 | } 17 | 18 | #nav-tree .plus { 19 | margin:0px; 20 | } 21 | 22 | #nav-tree .selected { 23 | background-image: url('tab_a.png'); 24 | background-repeat:repeat-x; 25 | color: #fff; 26 | text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); 27 | } 28 | 29 | #nav-tree img { 30 | margin:0px; 31 | padding:0px; 32 | border:0px; 33 | vertical-align: middle; 34 | } 35 | 36 | #nav-tree a { 37 | text-decoration:none; 38 | padding:0px; 39 | margin:0px; 40 | outline:none; 41 | } 42 | 43 | #nav-tree .label { 44 | margin:0px; 45 | padding:0px; 46 | font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; 47 | } 48 | 49 | #nav-tree .label a { 50 | padding:2px; 51 | } 52 | 53 | #nav-tree .selected a { 54 | text-decoration:none; 55 | color:#fff; 56 | } 57 | 58 | #nav-tree .children_ul { 59 | margin:0px; 60 | padding:0px; 61 | } 62 | 63 | #nav-tree .item { 64 | margin:0px; 65 | padding:0px; 66 | } 67 | 68 | #nav-tree { 69 | padding: 0px 0px; 70 | background-color: #FAFAFF; 71 | font-size:14px; 72 | overflow:auto; 73 | } 74 | 75 | #doc-content { 76 | overflow:auto; 77 | display:block; 78 | padding:0px; 79 | margin:0px; 80 | -webkit-overflow-scrolling : touch; /* iOS 5+ */ 81 | } 82 | 83 | #side-nav { 84 | padding:0 6px 0 0; 85 | margin: 0px; 86 | display:block; 87 | position: absolute; 88 | left: 0px; 89 | width: 250px; 90 | } 91 | 92 | .ui-resizable .ui-resizable-handle { 93 | display:block; 94 | } 95 | 96 | .ui-resizable-e { 97 | background-image:url("splitbar.png"); 98 | background-size:100%; 99 | background-repeat:no-repeat; 100 | background-attachment: scroll; 101 | cursor:ew-resize; 102 | height:100%; 103 | right:0; 104 | top:0; 105 | width:6px; 106 | } 107 | 108 | .ui-resizable-handle { 109 | display:none; 110 | font-size:0.1px; 111 | position:absolute; 112 | z-index:1; 113 | } 114 | 115 | #nav-tree-contents { 116 | margin: 6px 0px 0px 0px; 117 | } 118 | 119 | #nav-tree { 120 | background-image:url('nav_h.png'); 121 | background-repeat:repeat-x; 122 | background-color: #F7F8F7; 123 | -webkit-overflow-scrolling : touch; /* iOS 5+ */ 124 | } 125 | 126 | #nav-sync { 127 | position:absolute; 128 | top:5px; 129 | right:24px; 130 | z-index:0; 131 | } 132 | 133 | #nav-sync img { 134 | opacity:0.3; 135 | } 136 | 137 | #nav-sync img:hover { 138 | opacity:0.9; 139 | } 140 | 141 | @media print 142 | { 143 | #nav-tree { display: none; } 144 | div.ui-resizable-handle { display: none; position: relative; } 145 | } 146 | 147 | -------------------------------------------------------------------------------- /extras/docs/html/navtree.js: -------------------------------------------------------------------------------- 1 | var navTreeSubIndices = new Array(); 2 | var arrowDown = '▼'; 3 | var arrowRight = '►'; 4 | 5 | function getData(varName) 6 | { 7 | var i = varName.lastIndexOf('/'); 8 | var n = i>=0 ? varName.substring(i+1) : varName; 9 | return eval(n.replace(/\-/g,'_')); 10 | } 11 | 12 | function stripPath(uri) 13 | { 14 | return uri.substring(uri.lastIndexOf('/')+1); 15 | } 16 | 17 | function stripPath2(uri) 18 | { 19 | var i = uri.lastIndexOf('/'); 20 | var s = uri.substring(i+1); 21 | var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); 22 | return m ? uri.substring(i-6) : s; 23 | } 24 | 25 | function hashValue() 26 | { 27 | return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); 28 | } 29 | 30 | function hashUrl() 31 | { 32 | return '#'+hashValue(); 33 | } 34 | 35 | function pathName() 36 | { 37 | return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); 38 | } 39 | 40 | function localStorageSupported() 41 | { 42 | try { 43 | return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; 44 | } 45 | catch(e) { 46 | return false; 47 | } 48 | } 49 | 50 | 51 | function storeLink(link) 52 | { 53 | if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { 54 | window.localStorage.setItem('navpath',link); 55 | } 56 | } 57 | 58 | function deleteLink() 59 | { 60 | if (localStorageSupported()) { 61 | window.localStorage.setItem('navpath',''); 62 | } 63 | } 64 | 65 | function cachedLink() 66 | { 67 | if (localStorageSupported()) { 68 | return window.localStorage.getItem('navpath'); 69 | } else { 70 | return ''; 71 | } 72 | } 73 | 74 | function getScript(scriptName,func,show) 75 | { 76 | var head = document.getElementsByTagName("head")[0]; 77 | var script = document.createElement('script'); 78 | script.id = scriptName; 79 | script.type = 'text/javascript'; 80 | script.onload = func; 81 | script.src = scriptName+'.js'; 82 | if ($.browser.msie && $.browser.version<=8) { 83 | // script.onload does not work with older versions of IE 84 | script.onreadystatechange = function() { 85 | if (script.readyState=='complete' || script.readyState=='loaded') { 86 | func(); if (show) showRoot(); 87 | } 88 | } 89 | } 90 | head.appendChild(script); 91 | } 92 | 93 | function createIndent(o,domNode,node,level) 94 | { 95 | var level=-1; 96 | var n = node; 97 | while (n.parentNode) { level++; n=n.parentNode; } 98 | if (node.childrenData) { 99 | var imgNode = document.createElement("span"); 100 | imgNode.className = 'arrow'; 101 | imgNode.style.paddingLeft=(16*level).toString()+'px'; 102 | imgNode.innerHTML=arrowRight; 103 | node.plus_img = imgNode; 104 | node.expandToggle = document.createElement("a"); 105 | node.expandToggle.href = "javascript:void(0)"; 106 | node.expandToggle.onclick = function() { 107 | if (node.expanded) { 108 | $(node.getChildrenUL()).slideUp("fast"); 109 | node.plus_img.innerHTML=arrowRight; 110 | node.expanded = false; 111 | } else { 112 | expandNode(o, node, false, false); 113 | } 114 | } 115 | node.expandToggle.appendChild(imgNode); 116 | domNode.appendChild(node.expandToggle); 117 | } else { 118 | var span = document.createElement("span"); 119 | span.className = 'arrow'; 120 | span.style.width = 16*(level+1)+'px'; 121 | span.innerHTML = ' '; 122 | domNode.appendChild(span); 123 | } 124 | } 125 | 126 | var animationInProgress = false; 127 | 128 | function gotoAnchor(anchor,aname,updateLocation) 129 | { 130 | var pos, docContent = $('#doc-content'); 131 | var ancParent = $(anchor.parent()); 132 | if (ancParent.hasClass('memItemLeft') || 133 | ancParent.hasClass('fieldname') || 134 | ancParent.hasClass('fieldtype') || 135 | ancParent.is(':header')) 136 | { 137 | pos = ancParent.position().top; 138 | } else if (anchor.position()) { 139 | pos = anchor.position().top; 140 | } 141 | if (pos) { 142 | var dist = Math.abs(Math.min( 143 | pos-docContent.offset().top, 144 | docContent[0].scrollHeight- 145 | docContent.height()-docContent.scrollTop())); 146 | animationInProgress=true; 147 | docContent.animate({ 148 | scrollTop: pos + docContent.scrollTop() - docContent.offset().top 149 | },Math.max(50,Math.min(500,dist)),function(){ 150 | if (updateLocation) window.location.href=aname; 151 | animationInProgress=false; 152 | }); 153 | } 154 | } 155 | 156 | function newNode(o, po, text, link, childrenData, lastNode) 157 | { 158 | var node = new Object(); 159 | node.children = Array(); 160 | node.childrenData = childrenData; 161 | node.depth = po.depth + 1; 162 | node.relpath = po.relpath; 163 | node.isLast = lastNode; 164 | 165 | node.li = document.createElement("li"); 166 | po.getChildrenUL().appendChild(node.li); 167 | node.parentNode = po; 168 | 169 | node.itemDiv = document.createElement("div"); 170 | node.itemDiv.className = "item"; 171 | 172 | node.labelSpan = document.createElement("span"); 173 | node.labelSpan.className = "label"; 174 | 175 | createIndent(o,node.itemDiv,node,0); 176 | node.itemDiv.appendChild(node.labelSpan); 177 | node.li.appendChild(node.itemDiv); 178 | 179 | var a = document.createElement("a"); 180 | node.labelSpan.appendChild(a); 181 | node.label = document.createTextNode(text); 182 | node.expanded = false; 183 | a.appendChild(node.label); 184 | if (link) { 185 | var url; 186 | if (link.substring(0,1)=='^') { 187 | url = link.substring(1); 188 | link = url; 189 | } else { 190 | url = node.relpath+link; 191 | } 192 | a.className = stripPath(link.replace('#',':')); 193 | if (link.indexOf('#')!=-1) { 194 | var aname = '#'+link.split('#')[1]; 195 | var srcPage = stripPath(pathName()); 196 | var targetPage = stripPath(link.split('#')[0]); 197 | a.href = srcPage!=targetPage ? url : "javascript:void(0)"; 198 | a.onclick = function(){ 199 | storeLink(link); 200 | if (!$(a).parent().parent().hasClass('selected')) 201 | { 202 | $('.item').removeClass('selected'); 203 | $('.item').removeAttr('id'); 204 | $(a).parent().parent().addClass('selected'); 205 | $(a).parent().parent().attr('id','selected'); 206 | } 207 | var anchor = $(aname); 208 | gotoAnchor(anchor,aname,true); 209 | }; 210 | } else { 211 | a.href = url; 212 | a.onclick = function() { storeLink(link); } 213 | } 214 | } else { 215 | if (childrenData != null) 216 | { 217 | a.className = "nolink"; 218 | a.href = "javascript:void(0)"; 219 | a.onclick = node.expandToggle.onclick; 220 | } 221 | } 222 | 223 | node.childrenUL = null; 224 | node.getChildrenUL = function() { 225 | if (!node.childrenUL) { 226 | node.childrenUL = document.createElement("ul"); 227 | node.childrenUL.className = "children_ul"; 228 | node.childrenUL.style.display = "none"; 229 | node.li.appendChild(node.childrenUL); 230 | } 231 | return node.childrenUL; 232 | }; 233 | 234 | return node; 235 | } 236 | 237 | function showRoot() 238 | { 239 | var headerHeight = $("#top").height(); 240 | var footerHeight = $("#nav-path").height(); 241 | var windowHeight = $(window).height() - headerHeight - footerHeight; 242 | (function (){ // retry until we can scroll to the selected item 243 | try { 244 | var navtree=$('#nav-tree'); 245 | navtree.scrollTo('#selected',0,{offset:-windowHeight/2}); 246 | } catch (err) { 247 | setTimeout(arguments.callee, 0); 248 | } 249 | })(); 250 | } 251 | 252 | function expandNode(o, node, imm, showRoot) 253 | { 254 | if (node.childrenData && !node.expanded) { 255 | if (typeof(node.childrenData)==='string') { 256 | var varName = node.childrenData; 257 | getScript(node.relpath+varName,function(){ 258 | node.childrenData = getData(varName); 259 | expandNode(o, node, imm, showRoot); 260 | }, showRoot); 261 | } else { 262 | if (!node.childrenVisited) { 263 | getNode(o, node); 264 | } if (imm || ($.browser.msie && $.browser.version>8)) { 265 | // somehow slideDown jumps to the start of tree for IE9 :-( 266 | $(node.getChildrenUL()).show(); 267 | } else { 268 | $(node.getChildrenUL()).slideDown("fast"); 269 | } 270 | node.plus_img.innerHTML = arrowDown; 271 | node.expanded = true; 272 | } 273 | } 274 | } 275 | 276 | function glowEffect(n,duration) 277 | { 278 | n.addClass('glow').delay(duration).queue(function(next){ 279 | $(this).removeClass('glow');next(); 280 | }); 281 | } 282 | 283 | function highlightAnchor() 284 | { 285 | var aname = hashUrl(); 286 | var anchor = $(aname); 287 | if (anchor.parent().attr('class')=='memItemLeft'){ 288 | var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); 289 | glowEffect(rows.children(),300); // member without details 290 | } else if (anchor.parent().attr('class')=='fieldname'){ 291 | glowEffect(anchor.parent().parent(),1000); // enum value 292 | } else if (anchor.parent().attr('class')=='fieldtype'){ 293 | glowEffect(anchor.parent().parent(),1000); // struct field 294 | } else if (anchor.parent().is(":header")) { 295 | glowEffect(anchor.parent(),1000); // section header 296 | } else { 297 | glowEffect(anchor.next(),1000); // normal member 298 | } 299 | gotoAnchor(anchor,aname,false); 300 | } 301 | 302 | function selectAndHighlight(hash,n) 303 | { 304 | var a; 305 | if (hash) { 306 | var link=stripPath(pathName())+':'+hash.substring(1); 307 | a=$('.item a[class$="'+link+'"]'); 308 | } 309 | if (a && a.length) { 310 | a.parent().parent().addClass('selected'); 311 | a.parent().parent().attr('id','selected'); 312 | highlightAnchor(); 313 | } else if (n) { 314 | $(n.itemDiv).addClass('selected'); 315 | $(n.itemDiv).attr('id','selected'); 316 | } 317 | if ($('#nav-tree-contents .item:first').hasClass('selected')) { 318 | $('#nav-sync').css('top','30px'); 319 | } else { 320 | $('#nav-sync').css('top','5px'); 321 | } 322 | showRoot(); 323 | } 324 | 325 | function showNode(o, node, index, hash) 326 | { 327 | if (node && node.childrenData) { 328 | if (typeof(node.childrenData)==='string') { 329 | var varName = node.childrenData; 330 | getScript(node.relpath+varName,function(){ 331 | node.childrenData = getData(varName); 332 | showNode(o,node,index,hash); 333 | },true); 334 | } else { 335 | if (!node.childrenVisited) { 336 | getNode(o, node); 337 | } 338 | $(node.getChildrenUL()).css({'display':'block'}); 339 | node.plus_img.innerHTML = arrowDown; 340 | node.expanded = true; 341 | var n = node.children[o.breadcrumbs[index]]; 342 | if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); 414 | else hash=''; 415 | } 416 | if (hash.match(/^#l\d+$/)) { 417 | var anchor=$('a[name='+hash.substring(1)+']'); 418 | glowEffect(anchor.parent(),1000); // line number 419 | hash=''; // strip line number anchors 420 | } 421 | var url=root+hash; 422 | var i=-1; 423 | while (NAVTREEINDEX[i+1]<=url) i++; 424 | if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index 425 | if (navTreeSubIndices[i]) { 426 | gotoNode(o,i,root,hash,relpath) 427 | } else { 428 | getScript(relpath+'navtreeindex'+i,function(){ 429 | navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); 430 | if (navTreeSubIndices[i]) { 431 | gotoNode(o,i,root,hash,relpath); 432 | } 433 | },true); 434 | } 435 | } 436 | 437 | function showSyncOff(n,relpath) 438 | { 439 | n.html(''); 440 | } 441 | 442 | function showSyncOn(n,relpath) 443 | { 444 | n.html(''); 445 | } 446 | 447 | function toggleSyncButton(relpath) 448 | { 449 | var navSync = $('#nav-sync'); 450 | if (navSync.hasClass('sync')) { 451 | navSync.removeClass('sync'); 452 | showSyncOff(navSync,relpath); 453 | storeLink(stripPath2(pathName())+hashUrl()); 454 | } else { 455 | navSync.addClass('sync'); 456 | showSyncOn(navSync,relpath); 457 | deleteLink(); 458 | } 459 | } 460 | 461 | function initNavTree(toroot,relpath) 462 | { 463 | var o = new Object(); 464 | o.toroot = toroot; 465 | o.node = new Object(); 466 | o.node.li = document.getElementById("nav-tree-contents"); 467 | o.node.childrenData = NAVTREE; 468 | o.node.children = new Array(); 469 | o.node.childrenUL = document.createElement("ul"); 470 | o.node.getChildrenUL = function() { return o.node.childrenUL; }; 471 | o.node.li.appendChild(o.node.childrenUL); 472 | o.node.depth = 0; 473 | o.node.relpath = relpath; 474 | o.node.expanded = false; 475 | o.node.isLast = true; 476 | o.node.plus_img = document.createElement("span"); 477 | o.node.plus_img.className = 'arrow'; 478 | o.node.plus_img.innerHTML = arrowRight; 479 | 480 | if (localStorageSupported()) { 481 | var navSync = $('#nav-sync'); 482 | if (cachedLink()) { 483 | showSyncOff(navSync,relpath); 484 | navSync.removeClass('sync'); 485 | } else { 486 | showSyncOn(navSync,relpath); 487 | } 488 | navSync.click(function(){ toggleSyncButton(relpath); }); 489 | } 490 | 491 | $(window).load(function(){ 492 | navTo(o,toroot,hashUrl(),relpath); 493 | showRoot(); 494 | }); 495 | 496 | $(window).bind('hashchange', function(){ 497 | if (window.location.hash && window.location.hash.length>1){ 498 | var a; 499 | if ($(location).attr('hash')){ 500 | var clslink=stripPath(pathName())+':'+hashValue(); 501 | a=$('.item a[class$="'+clslink.replace(/=desktop_vp) { 61 | if (!collapsed) { 62 | collapseExpand(); 63 | } 64 | } else if (width>desktop_vp && collapsedWidth0) { 76 | restoreWidth(0); 77 | collapsed=true; 78 | } 79 | else { 80 | var width = readCookie('width'); 81 | if (width>200 && width<$(window).width()) { restoreWidth(width); } else { restoreWidth(200); } 82 | collapsed=false; 83 | } 84 | } 85 | 86 | header = $("#top"); 87 | sidenav = $("#side-nav"); 88 | content = $("#doc-content"); 89 | navtree = $("#nav-tree"); 90 | footer = $("#nav-path"); 91 | $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); 92 | $(sidenav).resizable({ minWidth: 0 }); 93 | $(window).resize(function() { resizeHeight(); }); 94 | var device = navigator.userAgent.toLowerCase(); 95 | var touch_device = device.match(/(iphone|ipod|ipad|android)/); 96 | if (touch_device) { /* wider split bar for touch only devices */ 97 | $(sidenav).css({ paddingRight:'20px' }); 98 | $('.ui-resizable-e').css({ width:'20px' }); 99 | $('#nav-sync').css({ right:'34px' }); 100 | barWidth=20; 101 | } 102 | var width = readCookie('width'); 103 | if (width) { restoreWidth(width); } else { resizeWidth(); } 104 | resizeHeight(); 105 | var url = location.href; 106 | var i=url.indexOf("#"); 107 | if (i>=0) window.location.hash=url.substr(i); 108 | var _preventDefault = function(evt) { evt.preventDefault(); }; 109 | $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); 110 | $(".ui-resizable-handle").dblclick(collapseExpand); 111 | $(window).load(resizeHeight); 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /extras/docs/html/splitbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/splitbar.png -------------------------------------------------------------------------------- /extras/docs/html/struct_s_p_i_f_f_s_log_data-members.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: Member List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
    23 |
    24 | 25 | 26 | 27 | 33 | 34 | 35 |
    28 |
    SPIFFSLogger 29 |  v0.1.2 30 |
    31 |
    A minimal library for binary data logging in ESP8266
    32 |
    36 |
    37 | 38 | 39 | 40 | 41 | 46 | 47 |
    48 |
    49 | 54 |
    56 |
    57 |
    58 | 61 |
    62 |
    63 |
    64 |
    SPIFFSLogData< T > Member List
    65 |
    66 |
    67 | 68 |

    This is the complete list of members for SPIFFSLogData< T >, including all inherited members.

    69 | 70 | 71 | 72 |
    dataSPIFFSLogData< T >
    timestampUTCSPIFFSLogData< T >
    73 |
    74 | 75 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /extras/docs/html/struct_s_p_i_f_f_s_log_data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SPIFFSLogger: SPIFFSLogData< T > Struct Template Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 |
    23 |
    24 | 25 | 26 | 27 | 33 | 34 | 35 |
    28 |
    SPIFFSLogger 29 |  v0.1.2 30 |
    31 |
    A minimal library for binary data logging in ESP8266
    32 |
    36 |
    37 | 38 | 39 | 40 | 41 | 46 | 47 |
    48 |
    49 | 54 |
    56 |
    57 |
    58 | 61 |
    62 |
    63 | 66 |
    67 |
    SPIFFSLogData< T > Struct Template Reference
    68 |
    69 |
    70 | 71 |

    Represents a data element as stored in SPIFFS, along with the creation timestamp. 72 | More...

    73 | 74 |

    #include <SPIFFSLogger.h>

    75 | 76 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |

    77 | Public Attributes

    time_t timestampUTC
     creation time in UTC More...
     
    data
     data of type T More...
     
    85 |

    Detailed Description

    86 |

    template<class T>
    87 | struct SPIFFSLogData< T >

    88 | 89 |

    Represents a data element as stored in SPIFFS, along with the creation timestamp.

    90 |
    Template Parameters
    91 | 92 | 93 |
    Ttype to store, e.g. a struct.
    94 |
    95 |
    96 |

    Member Data Documentation

    97 | 98 |

    ◆ data

    99 | 100 |
    101 |
    102 |
    103 | template<class T>
    104 | 105 | 106 | 107 | 108 |
    T SPIFFSLogData< T >::data
    109 |
    110 | 111 |

    data of type T

    112 | 113 |
    114 |
    115 | 116 |

    ◆ timestampUTC

    117 | 118 |
    119 |
    120 |
    121 | template<class T>
    122 | 123 | 124 | 125 | 126 |
    time_t SPIFFSLogData< T >::timestampUTC
    127 |
    128 | 129 |

    creation time in UTC

    130 | 131 |
    132 |
    133 |
    The documentation for this struct was generated from the following file: 136 |
    137 |
    138 | 139 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /extras/docs/html/struct_s_p_i_f_f_s_log_data.js: -------------------------------------------------------------------------------- 1 | var struct_s_p_i_f_f_s_log_data = 2 | [ 3 | [ "data", "struct_s_p_i_f_f_s_log_data.html#a071121efdc7f6d95adc4dcdf736a84ec", null ], 4 | [ "timestampUTC", "struct_s_p_i_f_f_s_log_data.html#a692b3adc90780d9388d6833d2170400c", null ] 5 | ]; -------------------------------------------------------------------------------- /extras/docs/html/sync_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/sync_off.png -------------------------------------------------------------------------------- /extras/docs/html/sync_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/sync_on.png -------------------------------------------------------------------------------- /extras/docs/html/tab_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/tab_a.png -------------------------------------------------------------------------------- /extras/docs/html/tab_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/tab_b.png -------------------------------------------------------------------------------- /extras/docs/html/tab_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/tab_h.png -------------------------------------------------------------------------------- /extras/docs/html/tab_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitmario/SPIFFSLogger/34b4eeb661e414e744dba9fd7b21e416f74bcb6e/extras/docs/html/tab_s.png -------------------------------------------------------------------------------- /extras/docs/html/tabs.css: -------------------------------------------------------------------------------- 1 | .sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:transparent}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} 2 | -------------------------------------------------------------------------------- /extras/docs/xml/_s_p_i_f_f_s_logger_base_8h.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SPIFFSLoggerBase.h 5 | Arduino.h 6 | FS.h 7 | time.h 8 | src/SPIFFSLogger.h 9 | src/SPIFFSLoggerBase.cpp 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | SPIFFSLoggerBase 50 | 51 | 52 | 53 | 54 | 55 | /* 56 | SPIFFSLogger-AminimallibraryforbinarydatalogginginESP8266 57 | Copyright(C)2018MarioFalcao 58 | 59 | Thisprogramisfreesoftware:youcanredistributeitand/ormodify 60 | itunderthetermsoftheGNULesserGeneralPublicLicenseaspublished 61 | bytheFreeSoftwareFoundation,eitherversion3oftheLicense,or 62 | (atyouroption)anylaterversion. 63 | 64 | Thisprogramisdistributedinthehopethatitwillbeuseful, 65 | butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof 66 | MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe 67 | GNUGeneralPublicLicenseformoredetails. 68 | 69 | YoushouldhavereceivedacopyoftheGNULesserGeneralPublicLicense 70 | alongwiththisprogram.Ifnot,see<http://www.gnu.org/licenses/>. 71 | */ 72 | 73 | #ifndef__SPIFFSLOGGERBASE_H__ 74 | #define__SPIFFSLOGGERBASE_H__ 75 | 76 | #include<Arduino.h> 77 | #include<FS.h> 78 | #include<time.h> 79 | 80 | classSPIFFSLoggerBase 81 | { 82 | public: 83 | voidinit(); 84 | 85 | voidprocess(); 86 | 87 | protected: 88 | time_t_today=0; 89 | unsignedlong_lastProcess=0; 90 | constuint16_t_processInterval; 91 | constuint16_t_daysToKeep; 92 | bool_processNow=true; 93 | char_directory[21]; 94 | char_curPath[32]; 95 | SPIFFSLoggerBase(constchar*directory,uint16_tdaysToKeep,uint16_tprocessInterval); 96 | 97 | void_pathFromDate(char*output,time_tdate); 98 | 99 | void_updateCurPath(); 100 | 101 | void_runRotation(); 102 | 103 | statictime_t_filenameToDate(constchar*filename); 104 | 105 | statictime_t_timegm(structtm*tm); 106 | }; 107 | 108 | #endif//__SPIFFSLOGGERBASE_H__ 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /extras/docs/xml/combine.xslt: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /extras/docs/xml/dir_68267d1309a1af8e8297ef4c3efbcdba.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | src 5 | SPIFFSLogger.h 6 | SPIFFSLoggerBase.cpp 7 | SPIFFSLoggerBase.h 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /extras/docs/xml/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | SPIFFSLogData 4 | timestampUTC 5 | data 6 | 7 | SPIFFSLogger 8 | SPIFFSLogger 9 | write 10 | readRows 11 | readRowsBetween 12 | rowCount 13 | rowCount 14 | init 15 | process 16 | _today 17 | _lastProcess 18 | _processInterval 19 | _daysToKeep 20 | _processNow 21 | _directory 22 | _curPath 23 | _pathFromDate 24 | _updateCurPath 25 | _runRotation 26 | _filenameToDate 27 | _timegm 28 | 29 | SPIFFSLoggerBase 30 | _today 31 | _lastProcess 32 | _processInterval 33 | _daysToKeep 34 | _processNow 35 | _directory 36 | _curPath 37 | init 38 | process 39 | SPIFFSLoggerBase 40 | _pathFromDate 41 | _updateCurPath 42 | _runRotation 43 | _filenameToDate 44 | _timegm 45 | 46 | SPIFFSLogger.h 47 | 48 | SPIFFSLoggerBase.cpp 49 | PROGMEM 50 | 51 | SPIFFSLoggerBase.h 52 | 53 | src 54 | 55 | 56 | -------------------------------------------------------------------------------- /extras/docs/xml/index.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /extras/docs/xml/struct_s_p_i_f_f_s_log_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SPIFFSLogData 5 | SPIFFSLogger.h 6 | 7 | 8 | class 9 | T 10 | T 11 | 12 | 13 | 14 | 15 | time_t 16 | time_t SPIFFSLogData< T >::timestampUTC 17 | 18 | timestampUTC 19 | 20 | creation time in UTC 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | T 29 | T SPIFFSLogData< T >::data 30 | 31 | data 32 | 33 | data of type T 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Represents a data element as stored in SPIFFS, along with the creation timestamp. 43 | 44 | 45 | 46 | T 47 | 48 | 49 | type to store, e.g. a struct. 50 | 51 | 52 | 53 | 54 | 55 | SPIFFSLogDatadata 56 | SPIFFSLogDatatimestampUTC 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=SPIFFSLogger 2 | version=0.1.3 3 | author=Mario Falcao 4 | maintainer=Mario Falcao 5 | sentence=A minimal library for binary data logging in ESP8266. 6 | paragraph=Makes it easy to read, write and keep logs of relevant data, such as sensor readings in an efficient way, by storing data in raw, binary format along with a time_t. Depending on the data, this should offer about 50% space savings vs. saving the same data in CSV. Daily file rotation is performed automatically. 7 | category=Data Storage 8 | url=https://github.com/bitmario/SPIFFSLogger 9 | architectures=esp8266 10 | includes=SPIFFSLogger.h -------------------------------------------------------------------------------- /src/SPIFFSLogger.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPIFFSLogger - A minimal library for binary data logging in ESP8266 3 | Copyright (C) 2018 Mario Falcao 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef __SPIFFSLOGGER_H__ 20 | #define __SPIFFSLOGGER_H__ 21 | 22 | #include "SPIFFSLoggerBase.h" 23 | 24 | /** 25 | * Represents a data element as stored in SPIFFS, along with the creation timestamp. 26 | * 27 | * @tparam T type to store, e.g. a struct. 28 | */ 29 | template 30 | struct SPIFFSLogData 31 | { 32 | time_t timestampUTC; /**< creation time in UTC */ 33 | T data; /**< data of type T */ 34 | }; 35 | 36 | /** 37 | * Minimal class template for binary data logging in ESP8266 SPIFFS. 38 | * 39 | * Makes it easy to read, write and keep logs of relevant data, such as sensor readings in an efficient way, 40 | * by storing data in raw, binary format along with a time_t. One file is created per UTC day to store the 41 | * respective data, and deleted once it has reached the defined maximum age. 42 | * 43 | * @tparam T type to store, e.g. a struct. 44 | */ 45 | template 46 | class SPIFFSLogger : public SPIFFSLoggerBase 47 | { 48 | public: 49 | /** 50 | * Default constructor for SPIFFSLogger. 51 | * 52 | * @param directory char array with the base directory where files will be stored. Should not include 53 | * trailing slash and should be 20 characters or less. 54 | * @param daysToKeep number of days to keep in flash. Once files are past this age, they are deleted. 55 | * @param processInterval milliseconds between file directory updates and file rotation. 56 | */ 57 | SPIFFSLogger(const char *directory, uint16_t daysToKeep = 7, uint16_t processInterval = 1000); 58 | 59 | /** 60 | * Write the specified value to the end of the current log file, with the current timestamp. 61 | * 62 | * @param value the value to write 63 | */ 64 | size_t write(const T &value); 65 | 66 | /** 67 | * Read data from a daily logfile into a buffer. 68 | * 69 | * @param output buffer where data will be written 70 | * @param date time_t representing the date of the file 71 | * @param startIdx 0-based index of the entries to read (row number) 72 | * @param maxCount maximum number of entries to read 73 | * @return number of entries read 74 | */ 75 | size_t readRows(SPIFFSLogData *output, time_t date, size_t startIdx, size_t maxCount); 76 | 77 | size_t readRowsBetween(SPIFFSLogData *output, time_t fromTime, time_t toTime, size_t startIdx, size_t maxCount); 78 | 79 | /** 80 | * Get the number of entries for the specified date. 81 | * 82 | * @param date a time_t representing the day to check 83 | * @return number of entries 84 | */ 85 | size_t rowCount(time_t date); 86 | 87 | /** 88 | * Get the number of entries in the specified file. 89 | * 90 | * @param logFile a File object for a valid logfile 91 | * @return number of entries 92 | */ 93 | size_t rowCount(File &logFile); 94 | }; 95 | 96 | template 97 | SPIFFSLogger::SPIFFSLogger(const char *directory, uint16_t daysToKeep, uint16_t processInterval) 98 | : SPIFFSLoggerBase(directory, daysToKeep, processInterval) 99 | { 100 | } 101 | 102 | template 103 | size_t SPIFFSLogger::write(const T &value) 104 | { 105 | struct SPIFFSLogData data; 106 | data.timestampUTC = time(nullptr); 107 | data.data = value; 108 | 109 | File f = SPIFFS.open(this->_curPath, "a"); 110 | f.write((uint8_t *)&data, sizeof(data)); 111 | f.close(); 112 | } 113 | 114 | template 115 | size_t SPIFFSLogger::readRows(SPIFFSLogData *output, time_t date, size_t startIdx, size_t maxCount) 116 | { 117 | char path[32]; 118 | this->_pathFromDate(path, date); 119 | 120 | if (!SPIFFS.exists(path)) 121 | return 0; 122 | 123 | File f = SPIFFS.open(path, "r"); 124 | maxCount = min((int32_t)maxCount, (int32_t)(f.size() / sizeof(SPIFFSLogData)) - (int32_t)startIdx); 125 | if (maxCount <= 0) 126 | return maxCount; 127 | 128 | f.seek(startIdx * sizeof(SPIFFSLogData)); 129 | f.read((uint8_t *)output, maxCount * sizeof(SPIFFSLogData)); 130 | f.close(); 131 | return maxCount; 132 | } 133 | 134 | template 135 | size_t SPIFFSLogger::readRowsBetween(SPIFFSLogData *output, time_t fromTime, time_t toTime, size_t startIdx, size_t maxCount) 136 | { 137 | const time_t startDay = fromTime / 86400 * 86400; 138 | const uint8_t dirLen = strlen(this->_directory); 139 | Dir logDir = SPIFFS.openDir(this->_directory); 140 | 141 | size_t hits = 0; 142 | size_t copied = 0; 143 | 144 | while (logDir.next() && copied < maxCount) 145 | { 146 | const char *dateStart = logDir.fileName().c_str() + dirLen + 1; 147 | const time_t midnight = SPIFFSLoggerBase::_filenameToDate(dateStart); 148 | 149 | if (midnight < startDay || midnight > toTime) 150 | continue; 151 | 152 | size_t idx = 0; 153 | File f = logDir.openFile("r"); 154 | const size_t rowCount = this->rowCount(f); 155 | time_t currentTime; 156 | 157 | while (idx < rowCount && copied < maxCount) 158 | { 159 | f.seek(idx * sizeof(SPIFFSLogData)); 160 | f.read((uint8_t *)¤tTime, sizeof(time_t)); // read only the timestamp 161 | 162 | if (currentTime > toTime) 163 | break; // we got all we needed from this file 164 | if (currentTime >= fromTime) 165 | { // match 166 | hits++; 167 | if (hits > startIdx) 168 | { 169 | SPIFFSLogData *curOutput = output + copied; 170 | 171 | // copy the timestamp 172 | memcpy(curOutput, ¤tTime, sizeof(time_t)); 173 | 174 | // read the remaining data directly 175 | f.read((uint8_t *)curOutput + sizeof(time_t), sizeof(SPIFFSLogData) - sizeof(time_t)); 176 | 177 | copied++; 178 | } 179 | } 180 | 181 | idx++; 182 | } 183 | 184 | f.close(); 185 | } 186 | 187 | return copied; 188 | } 189 | 190 | template 191 | size_t SPIFFSLogger::rowCount(time_t date) 192 | { 193 | char path[32]; 194 | this->_pathFromDate(path, date); 195 | 196 | if (!SPIFFS.exists(path)) 197 | return 0; 198 | 199 | File f = SPIFFS.open(path, "r"); 200 | const size_t rows = this->rowCount(f); 201 | f.close(); 202 | 203 | return rows; 204 | } 205 | 206 | template 207 | size_t SPIFFSLogger::rowCount(File &logFile) 208 | { 209 | return logFile.size() / sizeof(SPIFFSLogData); 210 | } 211 | 212 | #endif // __SPIFFSLOGGER_H__ 213 | -------------------------------------------------------------------------------- /src/SPIFFSLoggerBase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPIFFSLogger - A minimal library for binary data logging in ESP8266 3 | Copyright (C) 2018 Mario Falcao 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "SPIFFSLoggerBase.h" 20 | 21 | // internal strings stored in flash for efficiency 22 | const char _logFilenameFormat[] PROGMEM = "%s/%d%02d%02d"; 23 | 24 | SPIFFSLoggerBase::SPIFFSLoggerBase(const char *directory, uint16_t daysToKeep, uint16_t processInterval) 25 | : _daysToKeep(daysToKeep), _processInterval(processInterval) 26 | { 27 | strncpy(this->_directory, directory, sizeof(this->_directory) - 1); 28 | } 29 | 30 | void SPIFFSLoggerBase::init() 31 | { 32 | this->process(); 33 | } 34 | 35 | void SPIFFSLoggerBase::process() 36 | { 37 | const unsigned long currentMillis = millis(); 38 | if (currentMillis - this->_lastProcess > this->_processInterval || this->_processNow) 39 | { 40 | const time_t now = time(nullptr); 41 | const time_t today = now / 86400 * 86400; // remove the time part 42 | if (this->_today != today) 43 | { // we have switched to another day, let's run the required updates 44 | this->_today = today; 45 | this->_updateCurPath(); 46 | this->_runRotation(); 47 | } 48 | 49 | this->_lastProcess = currentMillis; 50 | this->_processNow = false; 51 | } 52 | } 53 | 54 | void SPIFFSLoggerBase::_pathFromDate(char *output, time_t date) 55 | { 56 | if (date <= 0) 57 | date = this->_today; 58 | 59 | struct tm *tinfo = gmtime(&date); 60 | sprintf_P(output, 61 | _logFilenameFormat, 62 | this->_directory, 63 | 1900 + tinfo->tm_year, 64 | tinfo->tm_mon + 1, 65 | tinfo->tm_mday); 66 | } 67 | 68 | void SPIFFSLoggerBase::_updateCurPath() 69 | { 70 | SPIFFSLoggerBase::_pathFromDate(this->_curPath, this->_today); 71 | } 72 | 73 | void SPIFFSLoggerBase::_runRotation() 74 | { 75 | const uint8_t dirLen = strlen(this->_directory); 76 | Dir tempDir = SPIFFS.openDir(this->_directory); 77 | 78 | while (tempDir.next()) 79 | { 80 | const char *dateStart = tempDir.fileName().c_str() + dirLen + 1; 81 | const time_t midnight = SPIFFSLoggerBase::_filenameToDate(dateStart); 82 | 83 | // check if file is too old and, if so, delete it 84 | if (midnight < (this->_today - this->_daysToKeep * 86400)) 85 | SPIFFS.remove(tempDir.fileName()); 86 | } 87 | } 88 | 89 | time_t SPIFFSLoggerBase::_filenameToDate(const char *filename) 90 | { 91 | // we do a manual conversion since strptime() acts funny with YYYYMMDD dates 92 | // https://github.com/esp8266/Arduino/issues/5141 93 | struct tm tm = {0}; 94 | char datePart[5] = {0}; 95 | 96 | strncpy(datePart, filename, 4); 97 | tm.tm_year = atoi(datePart) - 1900; 98 | 99 | strncpy(datePart, filename + 4, 2); 100 | datePart[2] = '\0'; 101 | tm.tm_mon = atoi(datePart) - 1; 102 | 103 | strncpy(datePart, filename + 6, 2); 104 | tm.tm_mday = atoi(datePart); 105 | 106 | return SPIFFSLoggerBase::_timegm(&tm) / 86400 * 86400; 107 | } 108 | 109 | time_t SPIFFSLoggerBase::_timegm(struct tm *tm) 110 | { 111 | struct tm start2000 = { 112 | 0, // tm_sec 113 | 0, // tm_min 114 | 0, // tm_hour 115 | 1, // tm_mday 116 | 0, // tm_mon 117 | 100, // tm_year 118 | 0, // tm_wday 119 | 0, // tm_yday 120 | 0, // tm_isdst 121 | }; 122 | 123 | return mktime(tm) - (mktime(&start2000) - 946684800); 124 | } 125 | -------------------------------------------------------------------------------- /src/SPIFFSLoggerBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPIFFSLogger - A minimal library for binary data logging in ESP8266 3 | Copyright (C) 2018 Mario Falcao 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef __SPIFFSLOGGERBASE_H__ 20 | #define __SPIFFSLOGGERBASE_H__ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | /** 27 | * Base class for the SPIFFSLogger template, implementing common methods. Should not be used directly. 28 | */ 29 | class SPIFFSLoggerBase 30 | { 31 | public: 32 | /** 33 | * Initialize the logger. Should be called after initializing SPIFFS and before before any other method. 34 | */ 35 | void init(); 36 | 37 | /** 38 | * Process the file rotation and other required operations according to the defined processInterval. 39 | * Should be called as often as possible, i.e. in loop(). 40 | */ 41 | void process(); 42 | 43 | protected: 44 | time_t _today = 0; /**< current date, set in the last processing run */ 45 | unsigned long _lastProcess = 0; /**< last processing millis() */ 46 | const uint16_t _processInterval; /**< ms between processing runs */ 47 | const uint16_t _daysToKeep; /**< number of days to keep logs for */ 48 | bool _processNow = true; /**< force processing now, even if the processing interval hasn't passed */ 49 | char _directory[21]; /**< base directory for log files */ 50 | char _curPath[32]; /**< path for today's file */ 51 | 52 | SPIFFSLoggerBase(const char *directory, uint16_t daysToKeep, uint16_t processInterval); 53 | 54 | /** 55 | * Converts a time_t to that day's file path. 56 | */ 57 | void _pathFromDate(char *output, time_t date); 58 | 59 | /** 60 | * Updates the current path to match today's date. 61 | */ 62 | void _updateCurPath(); 63 | 64 | /** 65 | * Deletes files older than the defined age limit. 66 | */ 67 | void _runRotation(); 68 | 69 | /** 70 | * Converts a filename in YYYYMMDD format to a time_t. 71 | */ 72 | static time_t _filenameToDate(const char *filename); 73 | 74 | /** 75 | * Simple timegm function, since one is not available in the ESP libs. 76 | */ 77 | static time_t _timegm(struct tm *tm); 78 | }; 79 | 80 | #endif // __SPIFFSLOGGERBASE_H__ 81 | --------------------------------------------------------------------------------