Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for LittleFS #699

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
- run: platformio ci ./examples/SingleButton --board=esp01_1m --board=nodemcuv2 --board=esp32dev
- run: platformio ci ./examples/SonoffDualShutters --board=esp01_1m --board=nodemcuv2 --board=esp32dev
- run: platformio ci ./examples/TemperatureSensor --board=esp01_1m --board=nodemcuv2 --board=esp32dev
- run: platformio ci ./examples/Broadcast -O "build_flags = -D HOMIE_LITTLEFS" --board=esp01_1m --board=nodemcuv2 --board=esp32dev

lint:
working_directory: ~/code
Expand Down
6 changes: 6 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
},
{
"name": "ESP Async WebServer"
},
{
"owner": "lorol",
"name": "LittleFS_esp32",
"version": "^1.0.5",
"platforms": ["espressif32"]
}
],
"export": {
Expand Down
6 changes: 3 additions & 3 deletions src/Homie/Boot/BootConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,15 @@ void BootConfig::_onCaptivePortal(AsyncWebServerRequest *request) {
Interface::get().getLogger() << F("Proxy") << endl;
_proxyHttpRequest(request);
}
} else if (request->url() == "/" && !SPIFFS.exists(CONFIG_UI_BUNDLE_PATH)) {
} else if (request->url() == "/" && !_fs.exists(CONFIG_UI_BUNDLE_PATH)) {
// UI File not found
String msg = String(F("UI bundle not loaded. See Configuration API usage: http://homieiot.github.io/homie-esp8266"));
Interface::get().getLogger() << msg << endl;
request->send(404, F("text/plain"), msg);
} else if (request->url() == "/" && SPIFFS.exists(CONFIG_UI_BUNDLE_PATH)) {
} else if (request->url() == "/" && _fs.exists(CONFIG_UI_BUNDLE_PATH)) {
// Respond with UI
Interface::get().getLogger() << F("UI bundle found") << endl;
AsyncWebServerResponse *response = request->beginResponse(SPIFFS.open(CONFIG_UI_BUNDLE_PATH, "r"), F("index.html"), F("text/html"));
AsyncWebServerResponse *response = request->beginResponse(_fs.open(CONFIG_UI_BUNDLE_PATH, "r"), F("index.html"), F("text/html"));
request->send(response);
} else {
// Faild to find request
Expand Down
2 changes: 1 addition & 1 deletion src/Homie/Boot/BootConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <WiFi.h>
#include <HTTPClient.h>
#include <AsyncTCP.h>
#include <SPIFFS.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
Expand Down Expand Up @@ -40,6 +39,7 @@ class BootConfig : public Boot {
void loop();

private:
FS _fs;
AsyncWebServer _http;
HTTPClient _httpClient;
DNSServer _dns;
Expand Down
50 changes: 19 additions & 31 deletions src/Homie/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,24 @@

using namespace HomieInternals;

HomieInternals::FS Config::_fs = HomieInternals::FS();

Config::Config()
: _configStruct()
, _spiffsBegan(false)
, _valid(false) {
}

bool Config::_spiffsBegin() {
if (!_spiffsBegan) {
#ifdef ESP32
_spiffsBegan = SPIFFS.begin(true);
#elif defined(ESP8266)
_spiffsBegan = SPIFFS.begin();
#endif
if (!_spiffsBegan) Interface::get().getLogger() << F("✖ Cannot mount filesystem") << endl;
}

return _spiffsBegan;
}

bool Config::load() {
if (!_spiffsBegin()) { return false; }
if (!_fs.begin()) { return false; }

_valid = false;

if (!SPIFFS.exists(CONFIG_FILE_PATH)) {
if (!_fs.exists(CONFIG_FILE_PATH)) {
Interface::get().getLogger() << F("✖ ") << CONFIG_FILE_PATH << F(" doesn't exist") << endl;
return false;
}

File configFile = SPIFFS.open(CONFIG_FILE_PATH, "r");
File configFile = _fs.open(CONFIG_FILE_PATH, "r");
if (!configFile) {
Interface::get().getLogger() << F("✖ Cannot open config file") << endl;
return false;
Expand Down Expand Up @@ -148,7 +136,7 @@ bool Config::load() {
}

char* Config::getSafeConfigFile() const {
File configFile = SPIFFS.open(CONFIG_FILE_PATH, "r");
File configFile = _fs.open(CONFIG_FILE_PATH, "r");
size_t configSize = configFile.size();

char buf[MAX_JSON_CONFIG_FILE_SIZE];
Expand All @@ -170,19 +158,19 @@ char* Config::getSafeConfigFile() const {
}

void Config::erase() {
if (!_spiffsBegin()) { return; }
if (!_fs.begin()) { return; }

SPIFFS.remove(CONFIG_FILE_PATH);
SPIFFS.remove(CONFIG_NEXT_BOOT_MODE_FILE_PATH);
_fs.remove(CONFIG_FILE_PATH);
_fs.remove(CONFIG_NEXT_BOOT_MODE_FILE_PATH);
}

void Config::setHomieBootModeOnNextBoot(HomieBootMode bootMode) {
if (!_spiffsBegin()) { return; }
if (!_fs.begin()) { return; }

if (bootMode == HomieBootMode::UNDEFINED) {
SPIFFS.remove(CONFIG_NEXT_BOOT_MODE_FILE_PATH);
_fs.remove(CONFIG_NEXT_BOOT_MODE_FILE_PATH);
} else {
File bootModeFile = SPIFFS.open(CONFIG_NEXT_BOOT_MODE_FILE_PATH, "w");
File bootModeFile = _fs.open(CONFIG_NEXT_BOOT_MODE_FILE_PATH, "w");
if (!bootModeFile) {
Interface::get().getLogger() << F("✖ Cannot open NEXTMODE file") << endl;
return;
Expand All @@ -195,9 +183,9 @@ void Config::setHomieBootModeOnNextBoot(HomieBootMode bootMode) {
}

HomieBootMode Config::getHomieBootModeOnNextBoot() {
if (!_spiffsBegin()) { return HomieBootMode::UNDEFINED; }
if (!_fs.begin()) { return HomieBootMode::UNDEFINED; }

File bootModeFile = SPIFFS.open(CONFIG_NEXT_BOOT_MODE_FILE_PATH, "r");
File bootModeFile = _fs.open(CONFIG_NEXT_BOOT_MODE_FILE_PATH, "r");
if (bootModeFile) {
int v = bootModeFile.parseInt();
bootModeFile.close();
Expand All @@ -208,11 +196,11 @@ HomieBootMode Config::getHomieBootModeOnNextBoot() {
}

void Config::write(const JsonObject config) {
if (!_spiffsBegin()) { return; }
if (!_fs.begin()) { return; }

SPIFFS.remove(CONFIG_FILE_PATH);
_fs.remove(CONFIG_FILE_PATH);

File configFile = SPIFFS.open(CONFIG_FILE_PATH, "w");
File configFile = _fs.open(CONFIG_FILE_PATH, "w");
if (!configFile) {
Interface::get().getLogger() << F("✖ Cannot open config file") << endl;
return;
Expand All @@ -222,7 +210,7 @@ void Config::write(const JsonObject config) {
}

bool Config::patch(const char* patch) {
if (!_spiffsBegin()) { return false; }
if (!_fs.begin()) { return false; }

StaticJsonDocument<MAX_JSON_CONFIG_ARDUINOJSON_BUFFER_SIZE> patchJsonDoc;

Expand All @@ -232,7 +220,7 @@ bool Config::patch(const char* patch) {
}

JsonObject patchObject = patchJsonDoc.as<JsonObject>();
File configFile = SPIFFS.open(CONFIG_FILE_PATH, "r");
File configFile = _fs.open(CONFIG_FILE_PATH, "r");
if (!configFile) {
Interface::get().getLogger() << F("✖ Cannot open config file") << endl;
return false;
Expand Down
7 changes: 2 additions & 5 deletions src/Homie/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
#include "Arduino.h"

#include <ArduinoJson.h>
#ifdef ESP32
#include <SPIFFS.h>
#endif // ESP32
#include "FS.h"
#include "FS.hpp"
#include "Datatypes/Interface.hpp"
#include "Datatypes/ConfigStruct.hpp"
#include "Utils/DeviceId.hpp"
Expand Down Expand Up @@ -34,7 +31,7 @@ class Config {

private:
ConfigStruct _configStruct;
bool _spiffsBegan;
static FS _fs;
bool _valid;

bool _spiffsBegin();
Expand Down
22 changes: 22 additions & 0 deletions src/Homie/Constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@
#define HOMIE_CONFIG 1
#endif

// config mode requires SPIFFS as ESP Async Webserver only works with SPIFFS
#if HOMIE_CONFIG
#ifndef HOMIE_SPIFFS
#define HOMIE_SPIFFS
#endif
#endif

// default should be SPIFFS, except using LittleFS is explicitely defined
#ifndef HOMIE_LITTLEFS
#ifndef HOMIE_SPIFFS
#define HOMIE_SPIFFS
#endif
#endif

// fail if none or both are defined
#if defined(HOMIE_SPIFFS) && defined(HOMIE_LITTLEFS)
#error "Only one of HOMIE_SPIFFS and HOMIE_LITTLEFS must be defined. HOMIE_CONFIG requires HOMIE_SPIFFS."
#endif
#if !(defined(HOMIE_SPIFFS) || defined(HOMIE_LITTLEFS))
#error "At least one of HOMIE_SPIFFS or HOMIE_LITTLEFS needs to be defined."
#endif

namespace HomieInternals {
const char HOMIE_VERSION[] = "3.0.1";
const char HOMIE_ESP8266_VERSION[] = "3.0.0";
Expand Down
47 changes: 47 additions & 0 deletions src/Homie/FS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "FS.hpp"

#include "Datatypes/Interface.hpp"

HomieInternals::FS::FS()
: _began(false) {
}

bool HomieInternals::FS::begin() {
if (!_began) {
#if defined(HOMIE_SPIFFS)
#if defined(ESP8266)
_began = SPIFFS.begin();
#elif defined(ESP32)
_began = SPIFFS.begin(true);
#endif
#elif defined(HOMIE_LITTLEFS)
_began = LittleFS.begin();
#endif
if (!_began) Interface::get().getLogger() << F("✖ Cannot mount filesystem") << endl;
}
return _began;
}

bool HomieInternals::FS::exists(const char *filepath) {
#if defined(HOMIE_SPIFFS)
return SPIFFS.exists(filepath);
#elif defined(HOMIE_LITTLEFS)
return LittleFS.exists(filepath);
#endif
}

File HomieInternals::FS::open(const char* path, const char* mode) {
#if defined(HOMIE_SPIFFS)
return SPIFFS.open(path, mode);
#elif defined(HOMIE_LITTLEFS)
return LittleFS.open(path, mode);
#endif
}

bool HomieInternals::FS::remove(const char* path) {
#if defined(HOMIE_SPIFFS)
return SPIFFS.remove(path);
#elif defined(HOMIE_LITTLEFS)
return LittleFS.remove(path);
#endif
}
31 changes: 31 additions & 0 deletions src/Homie/FS.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "Constants.hpp"

#if defined(HOMIE_SPIFFS)
#if defined(ESP8266)
#include <FS.h>
#elif defined(ESP32)
#include <SPIFFS.h>
#endif
#elif defined(HOMIE_LITTLEFS)
#if defined(ESP8266)
#include <LittleFS.h>
#elif defined(ESP32)
#include <LITTLEFS.h>
#endif
#endif

namespace HomieInternals {
class FS {
public:
FS();
bool begin();
bool exists(const char *filepath);
File open(const char* path, const char* mode);
bool remove(const char* path);

private:
bool _began;
};
} // namespace HomieInternals