mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 07:06:36 +01:00
So far the serial output is a mix of \r\n for println() and \n for sprintf() and such. This commit consolidates this to a consistent \r\n. There should be no noticeable difference for users of terminals that auto-substitute a sole \n to \r\n. This will however make the serial output friendly to default behavior of various terminal emulators like 'screen' and 'minicom'. This commit doesn't touch anything that is not serial output and also leaves 'ets_printf' alone just in case. Co-authored-by: Thomas B. Rücker <thomas.ruecker@relexsolutions.com>
193 lines
5.6 KiB
C++
193 lines
5.6 KiB
C++
#pragma once
|
|
|
|
#include <Arduino.h>
|
|
#include <ArduinoJson.h>
|
|
#include <HTTPClient.h>
|
|
|
|
#include "system.h"
|
|
#include "web.h"
|
|
|
|
/// @brief Different utility functions
|
|
namespace util {
|
|
|
|
/// @brief Can be used to wrap a stream and see what's going on
|
|
class DebugStream : public Stream {
|
|
public:
|
|
DebugStream(Stream &stream) : _stream(stream) {}
|
|
|
|
int available() override {
|
|
return _stream.available();
|
|
}
|
|
|
|
int read() override {
|
|
int data = _stream.read();
|
|
Serial.write(data);
|
|
return data;
|
|
}
|
|
|
|
int peek() override {
|
|
int data = _stream.peek();
|
|
Serial.print("Peek: ");
|
|
Serial.println(data);
|
|
return data;
|
|
}
|
|
|
|
void flush() override {
|
|
_stream.flush();
|
|
Serial.println("Flush");
|
|
}
|
|
|
|
size_t write(uint8_t data) override {
|
|
Serial.write(data);
|
|
return _stream.write(data);
|
|
}
|
|
|
|
size_t write(const uint8_t *buffer, size_t size) override {
|
|
for (size_t i = 0; i < size; i++) {
|
|
Serial.print("Write: ");
|
|
Serial.println(buffer[i]);
|
|
}
|
|
return _stream.write(buffer, size);
|
|
}
|
|
|
|
private:
|
|
Stream &_stream;
|
|
};
|
|
|
|
/// @brief Prints free heap, allocatbale heap and free stack
|
|
static void printHeap() {
|
|
const uint32_t freeStack = uxTaskGetStackHighWaterMark(NULL);
|
|
Serial.printf("Free heap: %d allocatable: %d stack: %d\r\n", ESP.getFreeHeap(), ESP.getMaxAllocHeap(), freeStack);
|
|
}
|
|
|
|
/// @brief Prints the maximum continuous heap space
|
|
static void printLargestFreeBlock() {
|
|
Serial.println("Maximum Continuous Heap Space: " + String(heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)));
|
|
}
|
|
|
|
/// @brief Do a GET request to the given url and fill the given json with the response
|
|
/// @param url Request URL
|
|
/// @param json Json document to fill
|
|
/// @param timeout Request timeout
|
|
/// @return True on success, false on error (httpCode != 200 || deserialization error)
|
|
static bool httpGetJson(String &url, JsonDocument &json, const uint16_t timeout, JsonDocument *filter = nullptr) {
|
|
HTTPClient http;
|
|
// logLine("http httpGetJson " + url);
|
|
http.begin(url);
|
|
http.setTimeout(timeout);
|
|
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
|
const int httpCode = http.GET();
|
|
if (httpCode != 200) {
|
|
http.end();
|
|
wsErr(String("[httpGetJson] http ") + url + " code " + httpCode);
|
|
return false;
|
|
}
|
|
|
|
DeserializationError error;
|
|
if (filter) {
|
|
error = deserializeJson(json, http.getString(), DeserializationOption::Filter(*filter));
|
|
} else {
|
|
error = deserializeJson(json, http.getString());
|
|
}
|
|
http.end();
|
|
if (error) {
|
|
Serial.printf("[httpGetJson] JSON: %s\r\n", error.c_str());
|
|
wsErr("[httpGetJson] JSON: " + String(error.c_str()));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// @brief Check if the given string is empty or contains "null"
|
|
///
|
|
/// @param str String to check
|
|
/// @return True if empty or null, false if not
|
|
inline bool isEmptyOrNull(const String &str) {
|
|
return str.isEmpty() || str == "null";
|
|
}
|
|
|
|
/// @brief checks if the current time is between sleeptime1 and sleeptime2
|
|
///
|
|
/// @param sleeptime1 Start of time block
|
|
/// @param sleeptime2 End of time block
|
|
/// @return True if within time block, false is outside time block
|
|
static bool isSleeping(int sleeptime1, int sleeptime2) {
|
|
if (sleeptime1 == sleeptime2) return false;
|
|
|
|
struct tm timeinfo;
|
|
getLocalTime(&timeinfo);
|
|
int currentHour = timeinfo.tm_hour;
|
|
|
|
if (sleeptime1 < sleeptime2) {
|
|
return currentHour >= sleeptime1 && currentHour < sleeptime2;
|
|
} else {
|
|
return currentHour >= sleeptime1 || currentHour < sleeptime2;
|
|
}
|
|
}
|
|
|
|
/// @brief Get the time_t for midnight
|
|
/// @return time_t for midnight
|
|
inline time_t getMidnightTime() {
|
|
struct tm time_info;
|
|
getLocalTime(&time_info);
|
|
time_info.tm_hour = time_info.tm_min = time_info.tm_sec = 0;
|
|
time_info.tm_mday++;
|
|
return mktime(&time_info);
|
|
}
|
|
|
|
/// @brief Timer for kind of scheduling things
|
|
class Timer {
|
|
public:
|
|
/// @brief Construct a timer
|
|
/// @param interval Interval in ms at which @ref doRun() returns true
|
|
/// @param delay Delay in ms until first execution to defer start
|
|
Timer(const unsigned long interval, const unsigned long delay = 0) : m_interval(interval), m_nextMillis(millis() + delay) {}
|
|
|
|
/// @brief Change the interval
|
|
/// @param interval New interval in ms
|
|
void setInterval(const unsigned long interval) {
|
|
m_interval = interval;
|
|
}
|
|
|
|
/// @brief Check if interval is met
|
|
/// @param currentMillis Optionally provide the current time in millis
|
|
/// @return True if interval is met, false if not
|
|
bool doRun(const unsigned long currentMillis = millis()) {
|
|
if (currentMillis >= m_nextMillis) {
|
|
m_nextMillis = currentMillis + m_interval;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
/// @brief Timer interval in ms
|
|
unsigned long m_interval;
|
|
/// @brief Next timeer interval in ms
|
|
unsigned long m_nextMillis;
|
|
};
|
|
|
|
/// @brief Create a String from format
|
|
/// @param buffer Buffer to use for sprintf
|
|
/// @param format String format
|
|
/// @return String
|
|
template <size_t bufSize>
|
|
inline String formatString(char buffer[bufSize], const char *format, ...) {
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
const size_t size = vsnprintf(buffer, bufSize, format, args);
|
|
va_end(args);
|
|
|
|
return String(buffer, size);
|
|
}
|
|
|
|
} // namespace util
|
|
|
|
/// @brief Converts seconds to milliseconds
|
|
#define seconds(s) s * 1000
|
|
/// @brief Converts minutes to milliseconds
|
|
#define minutes(m) seconds(m * 60)
|
|
/// @brief Converts hours to milliseconds
|
|
#define hours(m) minutes(m * 60)
|