Fixed scale tare
This commit is contained in:
parent
123c2a534b
commit
daa2454e71
|
@ -17,4 +17,4 @@ inline String toString(const T & t) {
|
||||||
return String(t);
|
return String(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define assert(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))
|
#define assert_msg(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef PLATFORM_ESP32
|
||||||
|
#include "SPIFFS.h"
|
||||||
|
|
||||||
|
namespace portablefs
|
||||||
|
{
|
||||||
|
using File = ::File;
|
||||||
|
|
||||||
|
class Dir
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dir() {}
|
||||||
|
Dir(const String &path)
|
||||||
|
: root_(SPIFFS.open(path))
|
||||||
|
{
|
||||||
|
//next();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool next()
|
||||||
|
{
|
||||||
|
file_ = root_.openNextFile();
|
||||||
|
return file_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFile()
|
||||||
|
{
|
||||||
|
return !file_.isDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDirectory()
|
||||||
|
{
|
||||||
|
return file_.isDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName() const
|
||||||
|
{
|
||||||
|
return file_.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fileSize() const
|
||||||
|
{
|
||||||
|
return file_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
File root_;
|
||||||
|
File file_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Dir openDir(const String &path)
|
||||||
|
{
|
||||||
|
return Dir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline File open(const char *name, const char *mode)
|
||||||
|
{
|
||||||
|
return SPIFFS.open(name, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool exists(const char *name)
|
||||||
|
{
|
||||||
|
return SPIFFS.exists(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool remove(const char *name)
|
||||||
|
{
|
||||||
|
return SPIFFS.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool mkdir(const char *name)
|
||||||
|
{
|
||||||
|
return SPIFFS.mkdir(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace portablefs
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PLATFORM_ESP8266
|
||||||
|
|
||||||
|
#include <FS.h>
|
||||||
|
|
||||||
|
namespace portablefs
|
||||||
|
{
|
||||||
|
using Dir;
|
||||||
|
} // namespace portablefs
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PLATFORM_NATIVE
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
#include "MockDtypes.h"
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
|
||||||
|
namespace portablefs
|
||||||
|
{
|
||||||
|
const std::string basePath = "./base";
|
||||||
|
|
||||||
|
class Dir
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dir() {}
|
||||||
|
Dir(const String &path)
|
||||||
|
: it_(fs::directory_iterator(path).begin()),
|
||||||
|
end_(fs::directory_iterator(path).end()),
|
||||||
|
firstIncremented_(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool next()
|
||||||
|
{
|
||||||
|
if (!firstIncremented_)
|
||||||
|
firstIncremented_ = true;
|
||||||
|
else
|
||||||
|
++it_;
|
||||||
|
|
||||||
|
return it_ != end_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFile()
|
||||||
|
{
|
||||||
|
return file.is_regular_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDirectory()
|
||||||
|
{
|
||||||
|
return it_.is_directory();
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName() const
|
||||||
|
{
|
||||||
|
return it_.path().filename().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t fileSize() const
|
||||||
|
{
|
||||||
|
return it_.file_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
fs::directory_iterator it_;
|
||||||
|
fs::directory_iterator end_;
|
||||||
|
bool firstIncremented_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Dir openDir(const String &path)
|
||||||
|
{
|
||||||
|
return Dir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline File open(const char *name, const char *mode)
|
||||||
|
{
|
||||||
|
if(mode == "r")
|
||||||
|
return fopen()
|
||||||
|
return SPIFFS.open(name, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool exists(const char *name)
|
||||||
|
{
|
||||||
|
return SPIFFS.exists(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool remove(const char *name)
|
||||||
|
{
|
||||||
|
return SPIFFS.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool mkdir(const char *name)
|
||||||
|
{
|
||||||
|
return SPIFFS.mkdir(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace portablefs
|
||||||
|
|
||||||
|
#endif
|
|
@ -7,6 +7,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
typedef uint32_t uint_t;
|
typedef uint32_t uint_t;
|
||||||
|
|
||||||
|
@ -39,4 +40,7 @@ inline std::string toString(const T & t) {
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class String : public std::string
|
||||||
|
{};
|
||||||
|
|
||||||
#define assert(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))
|
#define assert(EXPRESSION, MSG) ((EXPRESSION) ? (void)0 : _assert(#EXPRESSION, #MSG, __FILE__, __LINE__))
|
|
@ -4,14 +4,16 @@
|
||||||
class MockScale
|
class MockScale
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MockScale( uint16_t valueMin=0, uint16_t valueMax=50)
|
MockScale( uint16_t valueMin=0, uint16_t valueMax=10)
|
||||||
: valueMin_(valueMin), valueMax_(valueMax), currentValue_(valueMin), direction(1)
|
: valueMin_(valueMin), valueMax_(valueMax), currentValue_(valueMin), direction(1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool measure(uint16_t & measurementOut) {
|
bool measure(uint16_t & measurementOut) {
|
||||||
currentValue_ += direction;
|
currentValue_ += direction;
|
||||||
if ( currentValue_ >= valueMax_)
|
if ( currentValue_ >= valueMax_) {
|
||||||
direction = -1;
|
direction = -1;
|
||||||
|
valueMax_ += 2;
|
||||||
|
}
|
||||||
else if ( currentValue_ <= valueMin_ )
|
else if ( currentValue_ <= valueMin_ )
|
||||||
direction = +1;
|
direction = +1;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "HX711.h"
|
#include "HX711.h"
|
||||||
|
#include "ConfigHardware.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,8 +10,11 @@ public:
|
||||||
bool measure(uint16_t & measurementOut) {
|
bool measure(uint16_t & measurementOut) {
|
||||||
if (hx711_.is_ready())
|
if (hx711_.is_ready())
|
||||||
{
|
{
|
||||||
uint32_t value = hx711_.get_value(MEASUREMENT_AVG_COUNT);
|
long value = hx711_.read_average(CONFIG_MEASUREMENT_AVG_COUNT) - offset_;
|
||||||
measurementOut = (int16_t)(value / DIVIDER);
|
if(value > 0)
|
||||||
|
measurementOut = (int16_t)(value / DIVIDER);
|
||||||
|
else
|
||||||
|
measurementOut = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -22,9 +26,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void tare(uint32_t numMeasurementsToAverage=50) {
|
void tare(uint32_t numMeasurementsToAverage=50) {
|
||||||
hx711_.tare(numMeasurementsToAverage);
|
offset_ = hx711_.read_average(numMeasurementsToAverage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HX711 hx711_;
|
HX711 hx711_;
|
||||||
|
long offset_ = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
Serial.println("Starting session rotate");
|
Serial.println("Starting session rotate");
|
||||||
rotate();
|
rotate();
|
||||||
const bool secondInsertSuccess = currentChunk->addPoint(measurement);
|
const bool secondInsertSuccess = currentChunk->addPoint(measurement);
|
||||||
assert(secondInsertSuccess, "Session: insertion after rotation failed");
|
assert_msg(secondInsertSuccess, "Session: insertion after rotation failed");
|
||||||
// TODO check that there is place for file - remove old files
|
// TODO check that there is place for file - remove old files
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,7 +52,7 @@ public:
|
||||||
encoder.template sendArrayHeader<Measurement_T>(lastIdx - startIdx);
|
encoder.template sendArrayHeader<Measurement_T>(lastIdx - startIdx);
|
||||||
while(startIdx < lastIdx)
|
while(startIdx < lastIdx)
|
||||||
startIdx = serializeChunk(encoder, startIdx);
|
startIdx = serializeChunk(encoder, startIdx);
|
||||||
assert(startIdx == lastIdx, "Not all data was sent");
|
assert_msg(startIdx == lastIdx, "Not all data was sent");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getStartTime() const {
|
uint32_t getStartTime() const {
|
||||||
|
@ -88,18 +88,18 @@ private:
|
||||||
|
|
||||||
template< typename Encoder_T>
|
template< typename Encoder_T>
|
||||||
uint32_t serializeChunk(Encoder_T & encoder, uint32_t startIdx) const {
|
uint32_t serializeChunk(Encoder_T & encoder, uint32_t startIdx) const {
|
||||||
assert( startIdx < currentChunk->getStartIndex() + currentChunk->numMeasurements(),
|
assert_msg( startIdx < currentChunk->getStartIndex() + currentChunk->numMeasurements(),
|
||||||
"serializeChunk: invalid startIdx" );
|
"serializeChunk: invalid startIdx" );
|
||||||
|
|
||||||
if( startIdx >= currentChunk->getStartIndex() ) {
|
if( startIdx >= currentChunk->getStartIndex() ) {
|
||||||
const auto localStartIdx = startIdx - currentChunk->getStartIndex();
|
const auto localStartIdx = startIdx - currentChunk->getStartIndex();
|
||||||
const auto numElements = currentChunk->numMeasurements() - localStartIdx;
|
const auto numElements = currentChunk->numMeasurements() - localStartIdx;
|
||||||
assert(numElements <= currentChunk->numMeasurements(), "Internal problem in serializeChunk");
|
assert_msg(numElements <= currentChunk->numMeasurements(), "Internal problem in serializeChunk");
|
||||||
encoder.sendArrayPartialContents( currentChunk->getDataPointer() + localStartIdx, numElements );
|
encoder.sendArrayPartialContents( currentChunk->getDataPointer() + localStartIdx, numElements );
|
||||||
return currentChunk->getStartIndex() + currentChunk->numMeasurements();
|
return currentChunk->getStartIndex() + currentChunk->numMeasurements();
|
||||||
} else if( startIdx >= otherChunk->getStartIndex() && otherChunkFilled() ) {
|
} else if( startIdx >= otherChunk->getStartIndex() && otherChunkFilled() ) {
|
||||||
encoder.sendArrayPartialContents( otherChunk->getDataPointer(), otherChunk->numMeasurements() );
|
encoder.sendArrayPartialContents( otherChunk->getDataPointer(), otherChunk->numMeasurements() );
|
||||||
assert( otherChunk->numMeasurements(), CHUNK_SIZE );
|
assert_msg( otherChunk->numMeasurements(), CHUNK_SIZE );
|
||||||
return otherChunk->getStartIndex() + otherChunk->numMeasurements();
|
return otherChunk->getStartIndex() + otherChunk->numMeasurements();
|
||||||
} else {
|
} else {
|
||||||
if( encoder.getSizeCountMode() ) {
|
if( encoder.getSizeCountMode() ) {
|
||||||
|
|
|
@ -1,7 +1,43 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "StreamingMsgPackEncoder.h"
|
#include "StreamingMsgPackEncoder.h"
|
||||||
#include <FS.h>
|
#include "FilesystemAbstraction.h"
|
||||||
|
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
struct WriterAdaptor
|
||||||
|
{
|
||||||
|
File * f;
|
||||||
|
void write(const char * ptr, size_t size) {
|
||||||
|
f->write(reinterpret_cast<const uint8_t *>(ptr), size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpiffsStorageWriter {
|
||||||
|
public:
|
||||||
|
SpiffsStorageWriter(const String &fileName) :
|
||||||
|
f_(SPIFFS.open(fileName, "w")),
|
||||||
|
adaptor_{&f_},
|
||||||
|
encoder_(&adaptor_),
|
||||||
|
fileName_(fileName)
|
||||||
|
{
|
||||||
|
bool success = f_;
|
||||||
|
Serial.println(success);
|
||||||
|
}
|
||||||
|
~SpiffsStorageWriter() {
|
||||||
|
f_.close();
|
||||||
|
Serial.println(fileName_);
|
||||||
|
Serial.println(SPIFFS.exists(fileName_));
|
||||||
|
}
|
||||||
|
StreamingMsgPackEncoder<WriterAdaptor> &encoder() { return encoder_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
File f_;
|
||||||
|
WriterAdaptor adaptor_;
|
||||||
|
StreamingMsgPackEncoder<WriterAdaptor> encoder_;
|
||||||
|
String fileName_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
class SpiffsStorageWriter {
|
class SpiffsStorageWriter {
|
||||||
public:
|
public:
|
||||||
|
@ -26,6 +62,11 @@ private:
|
||||||
String fileName_;
|
String fileName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SpiffsStorageReader
|
class SpiffsStorageReader
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct DummyWriter {
|
||||||
void write(const void*, uint32_t) {}
|
void write(const void*, uint32_t) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CopyWriter {
|
class CopyWriter {
|
||||||
public:
|
public:
|
||||||
CopyWriter(uint8_t * bufferToWrite)
|
CopyWriter(uint8_t * bufferToWrite)
|
||||||
|
@ -193,8 +194,8 @@ public:
|
||||||
uint32_t elementsToSkip = 0;
|
uint32_t elementsToSkip = 0;
|
||||||
if( sentBytes_ < offsetToStart_ ) {
|
if( sentBytes_ < offsetToStart_ ) {
|
||||||
elementsToSkip = (offsetToStart_ - sentBytes_) / sizeof(T);
|
elementsToSkip = (offsetToStart_ - sentBytes_) / sizeof(T);
|
||||||
assert((offsetToStart_ - sentBytes_) % sizeof(T) == 0,
|
assert_msg((offsetToStart_ - sentBytes_) % sizeof(T) == 0,
|
||||||
"Looks like previous sent operation send fraction of an element.");
|
"Looks like previous sent operation send fraction of an element.");
|
||||||
}
|
}
|
||||||
if( elementsToSkip >= length) {
|
if( elementsToSkip >= length) {
|
||||||
sentBytes_ += sizeof(T) * length;
|
sentBytes_ += sizeof(T) * length;
|
||||||
|
@ -241,7 +242,7 @@ private:
|
||||||
if( sentBytes_ < offsetToStart_ ) {
|
if( sentBytes_ < offsetToStart_ ) {
|
||||||
// already sent
|
// already sent
|
||||||
sentBytes_ += sizeRequired;
|
sentBytes_ += sizeRequired;
|
||||||
assert( sentBytes_ <= offsetToStart_, "Partial sending not supported by this function" );
|
assert_msg( sentBytes_ <= offsetToStart_, "Partial sending not supported by this function" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
#include "UserDB.h"
|
||||||
|
#include "FilesystemAbstraction.h"
|
||||||
|
|
||||||
|
const String userDir = "/u/";
|
||||||
|
|
||||||
|
template <class ForwardIterator, class T>
|
||||||
|
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T &val)
|
||||||
|
{
|
||||||
|
ForwardIterator it;
|
||||||
|
iterator_traits<ForwardIterator>::difference_type count, step;
|
||||||
|
count = distance(first, last);
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
it = first;
|
||||||
|
step = count / 2;
|
||||||
|
advance(it, step);
|
||||||
|
if (*it < val)
|
||||||
|
{
|
||||||
|
first = ++it;
|
||||||
|
count -= step + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
count = step;
|
||||||
|
}
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String userFileName(const String &userName)
|
||||||
|
{
|
||||||
|
return userDir + userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool User::load(const String &name)
|
||||||
|
{
|
||||||
|
name_ = name;
|
||||||
|
assert(name_.length() > 0);
|
||||||
|
const auto fileName = userFileName(name_);
|
||||||
|
if (!portablefs::exists(fileName.c_str()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto file = portablefs::open(fileName.c_str(), "r");
|
||||||
|
|
||||||
|
size_t sessionsInFile;
|
||||||
|
file.read((uint8_t *)&sessionsInFile, sizeof(numSessions_));
|
||||||
|
|
||||||
|
init(name, sessionsInFile * 2);
|
||||||
|
|
||||||
|
size_t expectedSize = sizeof(SessionIdType) * numSessions_;
|
||||||
|
auto bytesRead = file.read((uint8_t *)sessionIds_, expectedSize);
|
||||||
|
numSessions_ = sessionsInFile;
|
||||||
|
|
||||||
|
assert(expectedSize == bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::init(const String &name, size_t sessionAllocateSize)
|
||||||
|
{
|
||||||
|
if (sessionIds_ != nullptr)
|
||||||
|
{
|
||||||
|
free(sessionIds_);
|
||||||
|
sessionIds_ = nullptr;
|
||||||
|
}
|
||||||
|
name_ = name;
|
||||||
|
numSessionsAllocated_ = sessionAllocateSize;
|
||||||
|
sessionIds_ = (SessionIdType *)ps_malloc(sizeof(SessionIdType) * numSessionsAllocated_);
|
||||||
|
numSessions_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::save()
|
||||||
|
{
|
||||||
|
if (!portablefs::exists(userDir.c_str()))
|
||||||
|
portablefs::mkdir(userDir.c_str());
|
||||||
|
|
||||||
|
auto file = portablefs::open(userFileName(name_).c_str(), "w");
|
||||||
|
file.write((uint8_t *)&numSessions_, sizeof(numSessions_));
|
||||||
|
file.write((uint8_t *)sessionIds_, sizeof(SessionIdType) * numSessions_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::freeResources()
|
||||||
|
{
|
||||||
|
if (sessionIds_ != nullptr)
|
||||||
|
{
|
||||||
|
free(sessionIds_);
|
||||||
|
sessionIds_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::remove()
|
||||||
|
{
|
||||||
|
portablefs::remove(userFileName(name_).c_str());
|
||||||
|
freeResources();
|
||||||
|
name_ = "";
|
||||||
|
numSessions_ = 0;
|
||||||
|
numSessionsAllocated_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::growSessionArrayIfNecessary()
|
||||||
|
{
|
||||||
|
assert(numSessions_ <= numSessionsAllocated_);
|
||||||
|
|
||||||
|
if (numSessions_ < numSessionsAllocated_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
numSessionsAllocated_ *= 2;
|
||||||
|
sessionIds_ = (SessionIdType *)ps_realloc(sessionIds_, numSessionsAllocated_);
|
||||||
|
|
||||||
|
assert(numSessions_ < numSessionsAllocated_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::insertSession(SessionIdType newSessionId)
|
||||||
|
{
|
||||||
|
growSessionArrayIfNecessary();
|
||||||
|
assert(numSessionsAllocated_ > numSessions_);
|
||||||
|
SessionIdType *insertPos = lower_bound(sessionIds_, sessionIds_ + numSessions_, newSessionId);
|
||||||
|
const size_t moveStartIdx = sessionIds_ + numSessions_ - insertPos;
|
||||||
|
for (size_t i = numSessions_ - 1; i >= moveStartIdx; --i)
|
||||||
|
sessionIds_[i + 1] = sessionIds_[i];
|
||||||
|
sessionIds_[moveStartIdx] = newSessionId;
|
||||||
|
numSessions_ += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool User::removeSession(SessionIdType sessionIdToRemove)
|
||||||
|
{
|
||||||
|
SessionIdType *removePos = lower_bound(sessionIds_, sessionIds_ + numSessions_, sessionIdToRemove);
|
||||||
|
const size_t removeIdx = sessionIds_ + numSessions_ - removePos;
|
||||||
|
if (sessionIds_[removeIdx] != sessionIdToRemove)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = removeIdx; i < numSessions_ - 1; ++i)
|
||||||
|
sessionIds_[i] = sessionIds_[i + 1];
|
||||||
|
|
||||||
|
numSessions_ -= 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
User *UserStorage::getUserInfo(const String &userName)
|
||||||
|
{
|
||||||
|
// index 0 is the unassigned user
|
||||||
|
for (size_t i = 1; i < numUsers_; ++i)
|
||||||
|
if (users_[i].name() == userName)
|
||||||
|
return &users_[i];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
User *UserStorage::getUnassignedUser()
|
||||||
|
{
|
||||||
|
return &users_[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
User *UserStorage::addNewUser(const String &userName)
|
||||||
|
{
|
||||||
|
if (numUsers_ >= MAX_USERS)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto userIdx = numUsers_;
|
||||||
|
numUsers_++;
|
||||||
|
assert(numUsers_ < MAX_USERS);
|
||||||
|
users_[userIdx].init(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserStorage::deleteUser(const String &userName)
|
||||||
|
{
|
||||||
|
User *userPtr = getUserInfo(userName);
|
||||||
|
|
||||||
|
if (userPtr == nullptr)
|
||||||
|
return false;
|
||||||
|
size_t userIdx = userPtr - users_;
|
||||||
|
userPtr->remove();
|
||||||
|
assert(numUsers_ > 0);
|
||||||
|
if (userIdx != numUsers_ - 1)
|
||||||
|
users_[userIdx] = users_[numUsers_ - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserStorage::fillFromFileSystem()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < numUsers_; ++i)
|
||||||
|
users_[i].freeResources();
|
||||||
|
|
||||||
|
numUsers_ = 1;
|
||||||
|
|
||||||
|
users_[0].load("_unassigned");
|
||||||
|
portablefs::Dir d(userDir);
|
||||||
|
while (d.next())
|
||||||
|
{
|
||||||
|
if (d.isFile() && d.fileName()[0] != '_')
|
||||||
|
{
|
||||||
|
users_[numUsers_].load(d.fileName());
|
||||||
|
++numUsers_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef PLATFORM_NATIVE
|
||||||
|
#include <Arduino.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
using SessionIdType = uint32_t;
|
||||||
|
constexpr size_t MAX_USERS = 64;
|
||||||
|
constexpr size_t INITIAL_SESSIONS_PER_USER = 128;
|
||||||
|
|
||||||
|
struct User
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
User() : numSessions_(0), numSessionsAllocated_(0), sessionIds_(nullptr) {}
|
||||||
|
|
||||||
|
void init(const String &name, size_t sessionAllocateSize = INITIAL_SESSIONS_PER_USER);
|
||||||
|
void freeResources();
|
||||||
|
|
||||||
|
bool load(const String &name);
|
||||||
|
void save();
|
||||||
|
void remove();
|
||||||
|
bool valid() const { return sessionIds_ != nullptr; }
|
||||||
|
|
||||||
|
void insertSession(SessionIdType sessionId);
|
||||||
|
bool removeSession(SessionIdType sessionId);
|
||||||
|
|
||||||
|
bool hasSession(SessionIdType sessionId) const;
|
||||||
|
|
||||||
|
const String &name() const { return name_; }
|
||||||
|
|
||||||
|
// session access
|
||||||
|
SessionIdType *sessionBegin() { return sessionIds_; }
|
||||||
|
SessionIdType *sessionEnd() { return sessionIds_ + numSessions_; }
|
||||||
|
|
||||||
|
const SessionIdType *sessionBegin() const { return sessionIds_; }
|
||||||
|
const SessionIdType *sessionEnd() const { return sessionIds_ + numSessions_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void growSessionArrayIfNecessary();
|
||||||
|
|
||||||
|
String name_;
|
||||||
|
size_t numSessions_;
|
||||||
|
size_t numSessionsAllocated_;
|
||||||
|
SessionIdType *sessionIds_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UserStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UserStorage()
|
||||||
|
: numUsers_(0)
|
||||||
|
{
|
||||||
|
fillFromFileSystem();
|
||||||
|
}
|
||||||
|
User *getUserInfo(const String &userName);
|
||||||
|
User *getUnassignedUser();
|
||||||
|
|
||||||
|
User *addNewUser(const String &userName);
|
||||||
|
bool deleteUser(const String &userName);
|
||||||
|
|
||||||
|
User *begin() { return &users_[0]; }
|
||||||
|
User *end() { return &users_[numUsers_]; }
|
||||||
|
|
||||||
|
const User *begin() const { return &users_[0]; }
|
||||||
|
const User *end() const { return &users_[numUsers_]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void fillFromFileSystem();
|
||||||
|
|
||||||
|
User users_[MAX_USERS];
|
||||||
|
size_t numUsers_;
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <FS.h>
|
#include "FilesystemAbstraction.h"
|
||||||
|
|
||||||
|
|
||||||
#define FLASH_TEXT(name) const char *name
|
#define FLASH_TEXT(name) const char *name
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ public:
|
||||||
WebdavFileListCallback(const String &path)
|
WebdavFileListCallback(const String &path)
|
||||||
: path_(path), headerWritten_(false), finished_(false)
|
: path_(path), headerWritten_(false), finished_(false)
|
||||||
{
|
{
|
||||||
dir_ = SPIFFS.openDir(path);
|
dir_ = portablefs::openDir(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t operator()(uint8_t *buffer, size_t maxLen, size_t index)
|
size_t operator()(uint8_t *buffer, size_t maxLen, size_t index)
|
||||||
|
@ -104,11 +105,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytesWritten = buffer - bufferStart;
|
size_t bytesWritten = buffer - bufferStart;
|
||||||
assert(bytesWritten < maxLen, "Written too much!");
|
assert_msg(bytesWritten < maxLen, "Written too much!");
|
||||||
Serial.print("Bytes written ");
|
//Serial.print("Bytes written ");
|
||||||
Serial.println(bytesWritten);
|
//Serial.println(bytesWritten);
|
||||||
Serial.print("Max bytes ");
|
//Serial.print("Max bytes ");
|
||||||
Serial.println(maxLen);
|
//Serial.println(maxLen);
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ private:
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
auto fileBase = fileZero.substring(0, fileZero.indexOf('_'));
|
auto fileBase = fileZero.substring(0, fileZero.indexOf('_'));
|
||||||
auto newDirInstance = SPIFFS.openDir(path_);
|
auto newDirInstance = portablefs::openDir(path_);
|
||||||
while (newDirInstance.next())
|
while (newDirInstance.next())
|
||||||
if (newDirInstance.isFile() && newDirInstance.fileName().startsWith(fileBase))
|
if (newDirInstance.isFile() && newDirInstance.fileName().startsWith(fileBase))
|
||||||
size += newDirInstance.fileSize();
|
size += newDirInstance.fileSize();
|
||||||
|
@ -136,7 +137,7 @@ private:
|
||||||
buffer += len;
|
buffer += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dir dir_;
|
portablefs::Dir dir_;
|
||||||
const String path_;
|
const String path_;
|
||||||
bool headerWritten_;
|
bool headerWritten_;
|
||||||
bool finished_;
|
bool finished_;
|
||||||
|
@ -147,7 +148,7 @@ bool deleteMeasurementFiles(const String &stName, const String &folder)
|
||||||
String baseName = folder + "/" + stName.substring(0, stName.indexOf("."));
|
String baseName = folder + "/" + stName.substring(0, stName.indexOf("."));
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
{
|
{
|
||||||
auto d = SPIFFS.openDir(folder);
|
auto d = portablefs::openDir(folder);
|
||||||
while (d.next())
|
while (d.next())
|
||||||
if (d.isFile() && d.fileName().startsWith(baseName))
|
if (d.isFile() && d.fileName().startsWith(baseName))
|
||||||
++counter;
|
++counter;
|
||||||
|
|
|
@ -1,11 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
|
//#define _HW_V_20
|
||||||
|
|
||||||
// HX711 load cell
|
// HX711 load cell
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
#ifdef _HW_V_20
|
||||||
|
const int CONFIG_SCALE_DOUT_PIN = 23;
|
||||||
|
const int CONFIG_SCALE_SCK_PIN = 22;
|
||||||
|
#else
|
||||||
|
const int CONFIG_SCALE_DOUT_PIN = 22;
|
||||||
|
const int CONFIG_SCALE_SCK_PIN = 23;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
const int CONFIG_SCALE_DOUT_PIN = D2;
|
const int CONFIG_SCALE_DOUT_PIN = D2;
|
||||||
const int CONFIG_SCALE_SCK_PIN = D3;
|
const int CONFIG_SCALE_SCK_PIN = D3;
|
||||||
const uint8_t CONFIG_TARE_AVG_COUNT = 50; // number of measurements in tare-phase (to find 0 )
|
#endif
|
||||||
const int CONFIG_VALUE_DIVIDER = 128; // uint32 measurements are divided by this factor, before stored in uint16_t
|
const uint8_t CONFIG_MEASUREMENT_AVG_COUNT = 1; // number of measurements in normal phase
|
||||||
|
const uint8_t CONFIG_TARE_AVG_COUNT = 6; // number of measurements in tare-phase (to find 0 )
|
||||||
const int CONFIG_MEASURE_DELAY = 100; // interval in ms between measurements
|
const int CONFIG_MEASURE_DELAY = 100; // interval in ms between measurements
|
||||||
|
//const int CONFIG_VALUE_DIVIDER = 8; // uint32 measurements are divided by this factor, before stored in uint16_t
|
||||||
|
const int CONFIG_VALUE_DIVIDER = 256; // uint32 measurements are divided by this factor, before stored in uint16_t
|
||||||
|
|
||||||
const uint32_t CONFIG_SESSION_CHUNK_SIZE = 1024; //1024*8 - 16 * sizeof(uint32_t);
|
const uint32_t CONFIG_SESSION_CHUNK_SIZE = 1024; //1024*8 - 16 * sizeof(uint32_t);
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
#include "SPIFFS.h"
|
||||||
|
#else
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void printDeviceInfo()
|
inline void printDeviceInfo()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
FSInfo fs_info;
|
FSInfo fs_info;
|
||||||
SPIFFS.info(fs_info);
|
SPIFFS.info(fs_info);
|
||||||
|
|
||||||
|
@ -66,4 +71,5 @@ inline void printDeviceInfo()
|
||||||
str += "\r\n";
|
str += "\r\n";
|
||||||
}
|
}
|
||||||
Serial.print(str);
|
Serial.print(str);
|
||||||
|
*/
|
||||||
}
|
}
|
|
@ -1,7 +1,13 @@
|
||||||
|
#define USE_ESP32
|
||||||
|
|
||||||
// Arduino & ESP headers
|
// Arduino & ESP headers
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
#include <WiFi.h>
|
||||||
|
#else
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESPAsyncTCP.h>
|
#include <ESPAsyncTCP.h>
|
||||||
|
#endif
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <WiFiUdp.h> // for NTP
|
#include <WiFiUdp.h> // for NTP
|
||||||
#include <NTPClient.h> // for NTP
|
#include <NTPClient.h> // for NTP
|
||||||
|
@ -9,6 +15,7 @@
|
||||||
// Own libs
|
// Own libs
|
||||||
#include "Dtypes.h"
|
#include "Dtypes.h"
|
||||||
#include "MockScale.h"
|
#include "MockScale.h"
|
||||||
|
#include "Scale.h"
|
||||||
#include "MeasurementSession.h"
|
#include "MeasurementSession.h"
|
||||||
#include "SpiffsStorage.h"
|
#include "SpiffsStorage.h"
|
||||||
#include "DeviceInfoLog.h"
|
#include "DeviceInfoLog.h"
|
||||||
|
@ -46,6 +53,7 @@ public:
|
||||||
|
|
||||||
void stopMeasurements() {
|
void stopMeasurements() {
|
||||||
measuring_ = false;
|
measuring_ = false;
|
||||||
|
session.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMeasuring() const {
|
bool isMeasuring() const {
|
||||||
|
@ -54,12 +62,14 @@ public:
|
||||||
|
|
||||||
void iteration() {
|
void iteration() {
|
||||||
if( ! measuring_ ) {
|
if( ! measuring_ ) {
|
||||||
|
//Serial.println("Disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t measurement;
|
uint16_t measurement=-1;
|
||||||
scale.measure(measurement);
|
scale.measure(measurement);
|
||||||
session.addPoint(measurement);
|
session.addPoint(measurement);
|
||||||
|
Serial.print("Measurement: ");
|
||||||
|
Serial.println(measurement);
|
||||||
if( lastCallTime_ != 0) {
|
if( lastCallTime_ != 0) {
|
||||||
const long cycleDuration = millis() - lastCallTime_;
|
const long cycleDuration = millis() - lastCallTime_;
|
||||||
if( cycleDuration <= CONFIG_MEASURE_DELAY)
|
if( cycleDuration <= CONFIG_MEASURE_DELAY)
|
||||||
|
@ -69,8 +79,7 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const long skipped = (cycleDuration / CONFIG_MEASURE_DELAY);
|
const long skipped = (cycleDuration / CONFIG_MEASURE_DELAY);
|
||||||
Serial.print("Warning: measurements skipped: ");
|
//Serial.printf("Warning: measurements skipped: %d, cycleDuration %d", skipped, cycleDuration);
|
||||||
Serial.println(skipped);
|
|
||||||
|
|
||||||
for(int i=0; i < skipped; ++i)
|
for(int i=0; i < skipped; ++i)
|
||||||
session.addPoint(measurement);
|
session.addPoint(measurement);
|
||||||
|
@ -84,7 +93,8 @@ public:
|
||||||
Session_T & getSession() { return session; }
|
Session_T & getSession() { return session; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MockScale scale;
|
Scale<CONFIG_VALUE_DIVIDER> scale;
|
||||||
|
//MockScale scale;
|
||||||
Session_T session;
|
Session_T session;
|
||||||
bool measuring_;
|
bool measuring_;
|
||||||
long lastCallTime_;
|
long lastCallTime_;
|
||||||
|
@ -100,12 +110,18 @@ template<typename Session_T>
|
||||||
void httpSetup(SessionManager<Session_T> * sessionManager)
|
void httpSetup(SessionManager<Session_T> * sessionManager)
|
||||||
{
|
{
|
||||||
server.on("/api/session/start", HTTP_POST | HTTP_GET, [sessionManager](AsyncWebServerRequest * req) {
|
server.on("/api/session/start", HTTP_POST | HTTP_GET, [sessionManager](AsyncWebServerRequest * req) {
|
||||||
req->send(200, "text/plain", F("OK"));
|
AsyncWebServerResponse *response = req->beginResponse(200, "text/plain", F("OK"));
|
||||||
|
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
req->send(response);
|
||||||
|
//req->send(200, "text/plain", F("OK"));
|
||||||
sessionManager->startMeasurements();
|
sessionManager->startMeasurements();
|
||||||
Serial.println("Started measurements");
|
Serial.println("Started measurements");
|
||||||
});
|
});
|
||||||
server.on("/api/session/stop", HTTP_POST | HTTP_GET, [sessionManager](AsyncWebServerRequest * req) {
|
server.on("/api/session/stop", HTTP_POST | HTTP_GET, [sessionManager](AsyncWebServerRequest * req) {
|
||||||
req->send(200, "text/plain", F("OK"));
|
AsyncWebServerResponse *response = req->beginResponse(200, "text/plain", F("OK"));
|
||||||
|
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
req->send(response);
|
||||||
|
//req->send(200, "text/plain", F("OK"));
|
||||||
sessionManager->stopMeasurements();
|
sessionManager->stopMeasurements();
|
||||||
Serial.println("Stopped measurements");
|
Serial.println("Stopped measurements");
|
||||||
});
|
});
|
||||||
|
@ -114,6 +130,8 @@ void httpSetup(SessionManager<Session_T> * sessionManager)
|
||||||
if( req->hasParam("startIdx") ) {
|
if( req->hasParam("startIdx") ) {
|
||||||
startIdx = req->getParam("startIdx")->value().toInt();
|
startIdx = req->getParam("startIdx")->value().toInt();
|
||||||
}
|
}
|
||||||
|
Serial.print("Data request, start index: ");
|
||||||
|
Serial.println(startIdx);
|
||||||
|
|
||||||
StreamingMsgPackEncoder<DummyWriter> encoderToDetermineSize(nullptr);
|
StreamingMsgPackEncoder<DummyWriter> encoderToDetermineSize(nullptr);
|
||||||
encoderToDetermineSize.setSizeCountMode(true);
|
encoderToDetermineSize.setSizeCountMode(true);
|
||||||
|
@ -122,18 +140,14 @@ void httpSetup(SessionManager<Session_T> * sessionManager)
|
||||||
Serial.print("Sending started of total size ");
|
Serial.print("Sending started of total size ");
|
||||||
Serial.println(totalSize);
|
Serial.println(totalSize);
|
||||||
auto callback = [=](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
|
auto callback = [=](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
|
||||||
Serial.print("Partial send maxLen ");
|
|
||||||
Serial.print(maxLen);
|
|
||||||
Serial.print(" index ");
|
|
||||||
Serial.println(index);
|
|
||||||
CopyWriter copyWriter(buffer);
|
CopyWriter copyWriter(buffer);
|
||||||
ChunkedStreamingMsgPackEncoder<CopyWriter> encoder(©Writer, index, index + maxLen);
|
ChunkedStreamingMsgPackEncoder<CopyWriter> encoder(©Writer, index, index + maxLen);
|
||||||
sessionManager->getSession().serialize(encoder, startIdx);
|
sessionManager->getSession().serialize(encoder, startIdx);
|
||||||
Serial.print("Bytes sent ");
|
|
||||||
Serial.println(encoder.sentBytes() - index);
|
|
||||||
return encoder.sentBytes() - index;
|
return encoder.sentBytes() - index;
|
||||||
};
|
};
|
||||||
AsyncWebServerResponse *response = req->beginResponse("application/x-msgpack", totalSize, callback);
|
AsyncWebServerResponse *response = req->beginResponse("application/x-msgpack", totalSize, callback);
|
||||||
|
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
auto sessionId = sessionManager->getSession().getStartTime();
|
auto sessionId = sessionManager->getSession().getStartTime();
|
||||||
response->addHeader("content-disposition", "attachment; filename=\"" + String(sessionId) + ".st\"");
|
response->addHeader("content-disposition", "attachment; filename=\"" + String(sessionId) + ".st\"");
|
||||||
req->send(response);
|
req->send(response);
|
||||||
|
@ -144,6 +158,38 @@ void httpSetup(SessionManager<Session_T> * sessionManager)
|
||||||
server.begin();
|
server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
|
||||||
|
Serial.printf("Listing directory: %s\r\n", dirname);
|
||||||
|
|
||||||
|
File root = fs.open(dirname);
|
||||||
|
if(!root){
|
||||||
|
Serial.println("- failed to open directory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!root.isDirectory()){
|
||||||
|
Serial.println(" - not a directory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = root.openNextFile();
|
||||||
|
while(file){
|
||||||
|
if(file.isDirectory()){
|
||||||
|
Serial.print(" DIR : ");
|
||||||
|
Serial.println(file.name());
|
||||||
|
if(levels){
|
||||||
|
listDir(fs, file.name(), levels -1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.print(" FILE: ");
|
||||||
|
Serial.print(file.name());
|
||||||
|
Serial.print("\tSIZE: ");
|
||||||
|
Serial.println(file.size());
|
||||||
|
}
|
||||||
|
file = root.openNextFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// Serial
|
// Serial
|
||||||
|
@ -153,14 +199,19 @@ void setup()
|
||||||
Serial.println("----- New start -----");
|
Serial.println("----- New start -----");
|
||||||
|
|
||||||
// File system
|
// File system
|
||||||
SPIFFS.begin();
|
bool spiffsResult = SPIFFS.begin(true);
|
||||||
|
Serial.printf("Spiffs begin %d\n", spiffsResult);
|
||||||
|
|
||||||
printDeviceInfo();
|
printDeviceInfo();
|
||||||
|
|
||||||
// WiFi
|
// WiFi
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.begin(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD);
|
WiFi.begin(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD);
|
||||||
WiFi.hostname(CONFIG_HOSTNAME);
|
#ifdef USE_ESP32
|
||||||
|
WiFi.setHostname(CONFIG_HOSTNAME);
|
||||||
|
#else
|
||||||
|
WIFI.hostname(CONFIG_HOSTNAME);
|
||||||
|
#endif
|
||||||
Serial.print(F("\n\n"));
|
Serial.print(F("\n\n"));
|
||||||
Serial.println(F("Waiting for WIFI connection..."));
|
Serial.println(F("Waiting for WIFI connection..."));
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
@ -178,6 +229,9 @@ void setup()
|
||||||
|
|
||||||
// HTTP & Websocket server
|
// HTTP & Websocket server
|
||||||
httpSetup(&sessionManager);
|
httpSetup(&sessionManager);
|
||||||
|
|
||||||
|
Serial.println("Spiffs listing:");
|
||||||
|
listDir(SPIFFS, "/", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
Loading…
Reference in New Issue