remove cloud stuff for standalone mode #16

pull/1/head
Thomas Ballmann 4 years ago
parent 79c1aa5f87
commit c0bb7f6237

1
.gitignore vendored

@ -5,3 +5,4 @@
.vscode/ipch
.DS_Store
/data/dist
/test

@ -1,7 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

@ -5,6 +5,44 @@
"istream": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"functional": "cpp"
"functional": "cpp",
"array": "cpp",
"bitset": "cpp",
"initializer_list": "cpp",
"regex": "cpp",
"utility": "cpp",
"deque": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"cstdint": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"limits": "cpp",
"memory": "cpp",
"new": "cpp",
"numeric": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
}
}

@ -12,4 +12,15 @@ yarn --cwd app build
# upload to device filesystem
platformio run --target uploadfs
```
# send a picture to display over json
curl -F 'myImage=@blackPNG.png' http://192.168.178.62/api/face
# erase flash memory
pio run --target erase
```
## access fs over http
> get photos from calendar face
http://192.168.178.65/fs/calendarPhoto.png

@ -8,7 +8,7 @@ module.exports = {
devServer: {
proxy: {
'^/': {
target: 'http://192.168.178.62:80',
target: 'http://192.168.178.65:80',
ws: true,
changeOrigin: true
},

@ -0,0 +1,6 @@
#ifndef DOWNLOAD_H
#define DOWNLOAD_H
bool downloadFile(String url, const char *path);
#endif

@ -1,6 +1,24 @@
#ifndef FACE_WEATHER_H
#define FACE_WEATHER_H
// TODO
struct faceWeatherData
{
//char hostname[64];
//int port;
char current_icon[4];
char current_description[20];
char location[20];
// current
int current_temp;
int today_min;
int today_max;
// forecast
};
void setupFaceWeather();
void loopFaceWeather();

@ -3,7 +3,13 @@ platform = espressif32
board = lolin32
framework = arduino
monitor_speed = 115200
; https://camo.githubusercontent.com/62eafe3a5c9bf3cdc31d6db740b7e58eaa1a3ab1/687474703a2f2f7777772e6275696c646c6f672e6e65742f626c6f672f77702d636f6e74656e742f75706c6f6164732f323032302f30322f6964655f73732e706e67
; https://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
; https://github.com/espressif/arduino-esp32/tree/master/tools/partitions
; https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/partition-tables.html
board_build.partitions = no_ota.csv
# OTA
;upload_port = 192.168.178.60
# lolin32
@ -12,7 +18,9 @@ monitor_speed = 115200
# lolin32 lite
upload_speed = 115200
upload_port = /dev/cu.wchusbserial1460
;upload_port = /dev/cu.wchusbserial1460
upload_port = /dev/cu.wchusbserial1410
lib_deps =
GxEPD2@~1.2.4

@ -20,7 +20,6 @@ const char *setting_HeaderKeys[] = {
// execute firmware update url
"X-UpdateFirmware"};
HTTPClient http;
void requestCloud();
bool isCloudSetupComplete();
@ -28,6 +27,8 @@ void updateInterval(unsigned long interval);
void setupCloud()
{
HTTPClient http;
Serial.println("setup cloud");
updateInterval(10);
@ -106,6 +107,9 @@ void updateInterval(unsigned long interval)
*/
void requestCloud()
{
/*
HTTPClient http;
String config_Url = NVS.getString("cloud.url");
Serial.println(config_Url);
@ -260,4 +264,5 @@ void requestCloud()
// clean up
http.end();
*/
}

@ -0,0 +1,93 @@
#include <HTTPClient.h>
#include <SPIFFS.h>
#include "download.h"
HTTPClient http;
bool downloadFile(String url, const char *path)
{
// @note duration time: 200kb = 35sec write to flash
Serial.println("Download file: " + url);
bool hasError = false;
String tmpFile = path;
tmpFile += ".tmp";
http.useHTTP10(true); // http1.1 chunked übertragung funktioniert irgendwie nicht
http.setTimeout(7000);
http.begin(url);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK)
{
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode != HTTP_CODE_OK && httpCode).c_str());
hasError = true;
}
else
{
// track duration
long startMills = millis();
// get lenght of document (is -1 when Server sends no Content-Length header)
int len = http.getSize();
// create buffer for read
uint8_t buff[1024] = {0};
// get tcp stream
WiFiClient *stream = http.getStreamPtr();
// persist image
SPIFFS.begin();
File file = SPIFFS.open(tmpFile, FILE_WRITE);
if (!file)
{
Serial.println("Failed to open file for writing");
hasError = true;
}
// read all data from server
while (http.connected() && (len > 0 || len == -1))
{
// get available data size
size_t size = stream->available();
if (size)
{
// read up to xxx byte
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
// write to storage
if (file)
{
file.write(buff, c);
}
if (len > 0)
{
len -= c;
}
}
delay(1);
}
// done
if (file)
{
file.close();
SPIFFS.remove(path);
SPIFFS.rename(tmpFile, path);
SPIFFS.end();
}
Serial.print("download completed in: ");
Serial.println(millis() - startMills);
}
// clean up
http.end();
return !hasError;
}

@ -1,23 +1,27 @@
#include <HTTPClient.h>
#include <SPIFFS.h>
#include <pngle.h>
#include "faceCalendar.h"
#include "display.h"
#include "datetime.h"
#include "SPIFFS.h"
#include "pngle.h"
#include "tools.h"
#include "image.h"
#include "download.h"
#include <Fonts/FreeMono12pt7b.h> // weekday - month year
#include <Fonts/FreeSansBold24pt7b.h> // current day
void downloadRandomePicture();
void showFaceCalendar();
void display_calender();
void display_picture();
void display_time();
void on_draw2(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]);
using std::uint8_t;
const char faceCalendarPicture[] = "/calendarPhoto.png";
// TODO use dynamic display width
static constexpr int MAX_WIDTH = 640 - 250;
static constexpr int MAX_HEIGHT = 384;
static int16_t curRowDelta[MAX_WIDTH + 1];
static int16_t nextRowDelta[MAX_WIDTH + 1];
@ -27,22 +31,20 @@ void setupFaceCalendar()
void loopFaceCalendar()
{
EVERY_N_SECONDS(300)
{
Serial.println("TODO download new image");
}
// TODO update picture every x seconds
showFaceCalendar();
}
void showFaceCalendar()
{
display.setRotation(0);
display.setFullWindow();
display.firstPage();
display.fillScreen(GxEPD_WHITE);
// draw...
display_picture();
display_calender();
Serial.println("displayFlush");
display.nextPage();
}
@ -50,7 +52,21 @@ void downloadRandomePicture()
{
// https://images.unsplash.com/photo-1580886349729-1bd109928600?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDM0OH0&w=640&h=200&fm=png&fit=crop
// https://images.unsplash.com/photo-1580886349729-1bd109928600?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDM0OH0&w=390&h=384&fm=png&fit=crop&colorquant=2
// https://images.unsplash.com/photo-1581307385098-a0338263e357?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDM0OH0&w=640&h=384&fm=png&fit=crop&duotone=000000,FFFFFF
// final filter: &w=390&h=384&fm=png&fit=crop&duotone=000000,FFFFFF
Serial.println("TODO download new image");
// TODO download json file
String pictureUrl = "https://images.unsplash.com/photo-1582910587039-b4f085805c86?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDM0OH0";
pictureUrl += "&w=390&h=384"; // size
pictureUrl += "&fm=png"; // format
pictureUrl += "&fit=crop"; // crop to needed size
pictureUrl += "&duotone=000000,FFFFFF"; // grayscale to save bytes
downloadFile(pictureUrl, faceCalendarPicture); // /face/calendar/bg.png
Serial.println("TODO download new image ---- done");
}
void display_calender()
@ -129,7 +145,7 @@ void display_picture()
pngle_t *pngle = pngle_new();
pngle_set_draw_callback(pngle, on_draw2);
File file = SPIFFS.open("/calendarPhoto.png", "r");
File file = SPIFFS.open(faceCalendarPicture, "r");
if (!file)
{
Serial.println(" file not found");
@ -143,12 +159,14 @@ void display_picture()
}
file.close();
/*
Serial.print(" width: ");
Serial.print(pngle_get_width(pngle));
Serial.print(" height: ");
Serial.println(pngle_get_height(pngle));
Serial.println(" read png done");
*/
pngle_destroy(pngle);
}

@ -1,11 +1,16 @@
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <SPIFFS.h>
#include "faceWeather.h"
#include "faceWeatherIcons.h"
#include "display.h"
#include "download.h"
#include <Fonts/FreeSansBold24pt7b.h> // current day
const char faceWeatherCurrent[] = "/weatherCurrent.json";
const char faceWeatherForecast[] = "/weatherForecast.json";
faceWeatherData weatherData;
// TODO use theme color
void display_current();
@ -15,6 +20,27 @@ void setupFaceWeather()
{
}
void updateData()
{
String url;
// http://api.openweathermap.org/data/2.5/weather?id=2766824&APPID=883b3c87223430d6f3a399645f8ba12b&lang=de&cnt=3&units=metric
// http://api.openweathermap.org/data/2.5/forecast?id=2766824&APPID=883b3c87223430d6f3a399645f8ba12b&lang=de
// https://openweathermap.org/current
url = "http://api.openweathermap.org/data/2.5/weather?";
url += "APPID=883b3c87223430d6f3a399645f8ba12b"; // api key
url += "&id=2766824"; // location
url += "&lang=de&units=metric"; // settings
downloadFile(url, faceWeatherCurrent);
// https://openweathermap.org/forecast5
url = "http://api.openweathermap.org/data/2.5/forecast?";
url += "APPID=883b3c87223430d6f3a399645f8ba12b"; // api key
url += "&id=2766824"; // location
url += "&lang=de&cnt=3&units=metric"; // settings
downloadFile(url, faceWeatherForecast);
}
void loopFaceWeather()
{
display.setRotation(0);
@ -24,15 +50,12 @@ void loopFaceWeather()
display.setTextColor(GxEPD_WHITE);
display.setTextSize(1);
display_current();
display_forecast();
display.nextPage();
}
void display_current()
{
// temperature
@ -42,19 +65,17 @@ void display_current()
display.println("");
// icon
const uint *icon = getIconById("02n", 192); // 192
const uint *icon = getIconById("02n", 192); // 192
if (icon)
{
display.drawBitmap(272, 30, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
// text
display.setTextSize(1);
display.setCursor(400, 300);
//display.println("Ein paar Wolken");
// high
display.setTextSize(1);
display.setCursor(500, 30);
@ -63,10 +84,8 @@ void display_current()
// low
display.setCursor(500, 60);
display.println("-3°");
}
void display_forecast()
{
const uint *icon;
@ -79,70 +98,66 @@ void display_forecast()
display.drawLine(420, 250, 420, 384, GxEPD_WHITE);
// 210 per block
// day +1
icon = getIconById("03d", 96);
if (icon)
{
display.drawBitmap(0 +57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
display.drawBitmap(0 + 57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
// day +2
icon = getIconById("09d", 96);
if (icon)
{
display.drawBitmap(210 +57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
display.drawBitmap(210 + 57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
// day +3
icon = getIconById("13d", 96);
if (icon)
{
display.drawBitmap(410 +57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
display.drawBitmap(410 + 57, 260, (uint8_t *)icon + 4, icon[0], icon[1], GxEPD_WHITE);
}
}
/*
bool loadWeatherData(const char *type)
void loadConfiguration()
{
HTTPClient http;
String url = "http://api.openweathermap.org/data/2.5/forecast?"; // weather | forecast
url += "id=2766824";
url += "&lang=de";
url += "&cnt=3";
url += "&units=metric";
url += "&APPID=883b3c87223430d6f3a399645f8ba12b";
// "/data/2.5/" + RequestType + "?q=" + City + "," + Country + "&APPID=" + apikey + "&mode=json&units=" + units + "&lang=" + Language;
//http.begin(client, server, 80, uri);
http.begin(url);
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK)
SPIFFS.begin();
File file;
DeserializationError error;
// current weather
file = SPIFFS.open(faceWeatherCurrent);
StaticJsonDocument<976> docCurrent; // Use arduinojson.org/v6/assistant to compute the capacity.
error = deserializeJson(docCurrent, file);
if (error)
{
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode != HTTP_CODE_OK && httpCode).c_str());
Serial.println(F("Failed to read file, using default configuration"));
}
else
// TODO Copy values from the JsonDocument to the Config
weatherData.current_temp = 12;
/*
config.port = doc["port"] | 2731;
strlcpy(config.hostname, // <- destination
doc["hostname"] | "example.com", // <- source
sizeof(config.hostname)); // <- destination's capacity
*/
file.close();
// forecast
file = SPIFFS.open(faceWeatherForecast);
StaticJsonDocument<2180> docForecast; // Use arduinojson.org/v6/assistant to compute the capacity.
error = deserializeJson(docForecast, file);
if (error)
{
// TODO read...
DynamicJsonDocument doc(1024 * 35);
DeserializationError error = deserializeJson(doc, http.getStream());
if (error)
{
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
return false;
}
JsonObject root = doc.as<JsonObject>();
Serial.println(F("Failed to read file, using default configuration"));
}
http.end();
}
// TODO get values
file.close();
*/
SPIFFS.end();
}

@ -4,17 +4,17 @@
#include "wlan.h"
#include "display.h"
#include "settings.h"
#include "cloud.h"
//#include "cloud.h"
#include "datetime.h"
#include "playlist.h"
#include "app.h"
#include "imagePNG.h"
#include "imageWBMP.h"
void gotoDeepSleep();
String getWakeupReason();
void setup()
{
// put your setup code here, to run once:
@ -26,18 +26,21 @@ void setup()
Serial.println();
setupDisplay();
//setupImagePNG();
//setupImageWBMP();
setupSettings();
setupDevice();
setupWlan();
if (wlan_isConnected())
{
setupCloud();
if (!setupDateTime())
{
// re-try
setupDateTime();
}
setupPlaylist();
//setupCloud();
}
setupApp();
@ -52,8 +55,9 @@ void loop()
if (wlan_isConnected())
{
loopCloud();
loopPlaylist();
//loopCloud();
}
loopDevice();
//loopDevice();
}
Loading…
Cancel
Save