mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 19:12:10 +01:00
Chunk web responses
This commit is contained in:
parent
ad5c64c4c2
commit
a81d1b843d
11 changed files with 154 additions and 84 deletions
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
|
|
@ -83,7 +83,7 @@ jobs:
|
||||||
- board: esp32
|
- board: esp32
|
||||||
addr_bootloader: 0x1000
|
addr_bootloader: 0x1000
|
||||||
chip: ESP32
|
chip: ESP32
|
||||||
fqbn: esp32:esp32:esp32:FlashMode=qio,FlashFreq=80,DebugLevel=none
|
fqbn: esp32:esp32:esp32:PartitionScheme=default,FlashMode=qio,FlashFreq=80,DebugLevel=none
|
||||||
# esp32:esp32:esp32wrover:PartitionScheme=default,FlashMode=qio,FlashFreq=80,UploadSpeed=921600,DebugLevel=none,EraseFlash=none
|
# esp32:esp32:esp32wrover:PartitionScheme=default,FlashMode=qio,FlashFreq=80,UploadSpeed=921600,DebugLevel=none,EraseFlash=none
|
||||||
name: ESP32
|
name: ESP32
|
||||||
obname: SomfyController.onboard.esp32.bin
|
obname: SomfyController.onboard.esp32.bin
|
||||||
|
|
@ -105,7 +105,7 @@ jobs:
|
||||||
- board: esp32s3
|
- board: esp32s3
|
||||||
addr_bootloader: 0x0
|
addr_bootloader: 0x0
|
||||||
chip: ESP32-S3
|
chip: ESP32-S3
|
||||||
fqbn: esp32:esp32:esp32s3:USBMode=hwcdc,CDCOnBoot=cdc
|
fqbn: esp32:esp32:esp32s3:JTAGAdapter=default,USBMode=hwcdc,CDCOnBoot=cdc,DebugLevel=none,FlashMode=qio,PartitionScheme=default
|
||||||
# esp32:esp32:esp32s3:JTAGAdapter=default,PSRAM=disabled,FlashMode=qio,FlashSize=4M,LoopCore=1,EventsCore=1,USBMode=hwcdc,CDCOnBoot=cdc,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PartitionScheme=default,CPUFreq=240,UploadSpeed=921600,DebugLevel=none,EraseFlash=none
|
# esp32:esp32:esp32s3:JTAGAdapter=default,PSRAM=disabled,FlashMode=qio,FlashSize=4M,LoopCore=1,EventsCore=1,USBMode=hwcdc,CDCOnBoot=cdc,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PartitionScheme=default,CPUFreq=240,UploadSpeed=921600,DebugLevel=none,EraseFlash=none
|
||||||
name: ESP32S3
|
name: ESP32S3
|
||||||
fwname: SomfyController.ino.esp32s3.bin
|
fwname: SomfyController.ino.esp32s3.bin
|
||||||
|
|
@ -161,7 +161,7 @@ jobs:
|
||||||
- name: Build ${{ matrix.name }}
|
- name: Build ${{ matrix.name }}
|
||||||
run: |
|
run: |
|
||||||
mkdir -p build${{ matrix.name }}
|
mkdir -p build${{ matrix.name }}
|
||||||
arduino-cli compile --clean --output-dir build${{ matrix.name }} --fqbn ${{ matrix.fqbn }} --warnings default ./SomfyController
|
arduino-cli compile --clean --output-dir build${{ matrix.name }} --fqbn ${{ matrix.fqbn }} --warnings none ./SomfyController
|
||||||
|
|
||||||
- name: ${{ matrix.name }} Image
|
- name: ${{ matrix.name }} Image
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ class ConfigSettings: BaseSettings {
|
||||||
appver_t fwVersion;
|
appver_t fwVersion;
|
||||||
appver_t appVersion;
|
appver_t appVersion;
|
||||||
bool ssdpBroadcast = true;
|
bool ssdpBroadcast = true;
|
||||||
|
bool checkForUpdate = true;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
IPSettings IP;
|
IPSettings IP;
|
||||||
WifiSettings WIFI;
|
WifiSettings WIFI;
|
||||||
|
|
|
||||||
16
GitOTA.cpp
16
GitOTA.cpp
|
|
@ -29,7 +29,6 @@ void GitRelease::setReleaseProperty(const char *key, const char *val) {
|
||||||
else if(strcmp(key, "published_at") == 0) {
|
else if(strcmp(key, "published_at") == 0) {
|
||||||
//Serial.printf("Key:[%s] Value:[%s]\n", key, val);
|
//Serial.printf("Key:[%s] Value:[%s]\n", key, val);
|
||||||
this->releaseDate = Timestamp::parseUTCTime(val);
|
this->releaseDate = Timestamp::parseUTCTime(val);
|
||||||
//Serial.println(this->releaseDate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GitRelease::setAssetProperty(const char *key, const char *val) {
|
void GitRelease::setAssetProperty(const char *key, const char *val) {
|
||||||
|
|
@ -85,6 +84,7 @@ bool GitRelease::toJSON(JsonObject &obj) {
|
||||||
int16_t GitRepo::getReleases(uint8_t num) {
|
int16_t GitRepo::getReleases(uint8_t num) {
|
||||||
WiFiClientSecure sclient;
|
WiFiClientSecure sclient;
|
||||||
sclient.setInsecure();
|
sclient.setInsecure();
|
||||||
|
sclient.setHandshakeTimeout(3);
|
||||||
uint8_t ndx = 0;
|
uint8_t ndx = 0;
|
||||||
uint8_t count = min((uint8_t)GIT_MAX_RELEASES, num);
|
uint8_t count = min((uint8_t)GIT_MAX_RELEASES, num);
|
||||||
char url[128];
|
char url[128];
|
||||||
|
|
@ -241,8 +241,11 @@ bool GitRepo::toJSON(JsonObject &obj) {
|
||||||
|
|
||||||
void GitUpdater::loop() {
|
void GitUpdater::loop() {
|
||||||
if(this->status == GIT_STATUS_READY) {
|
if(this->status == GIT_STATUS_READY) {
|
||||||
if(this->lastCheck == 0) this->lastCheck = millis();
|
//if(this->lastCheck == 0)
|
||||||
else if(this->lastCheck + 14400000 < millis() && !rebootDelay.reboot) { // 4 hours
|
//this->lastCheck = millis();
|
||||||
|
//else
|
||||||
|
if(settings.checkForUpdate &&
|
||||||
|
(this->lastCheck + 14400000 < millis() || this->lastCheck == 0) && !rebootDelay.reboot) { // 4 hours
|
||||||
this->checkForUpdate();
|
this->checkForUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,9 +268,9 @@ void GitUpdater::checkForUpdate() {
|
||||||
Serial.println("Check github for updates...");
|
Serial.println("Check github for updates...");
|
||||||
this->status = GIT_STATUS_CHECK;
|
this->status = GIT_STATUS_CHECK;
|
||||||
settings.printAvailHeap();
|
settings.printAvailHeap();
|
||||||
|
this->lastCheck = millis();
|
||||||
if(this->checkInternet() == 0) {
|
if(this->checkInternet() == 0) {
|
||||||
GitRepo repo;
|
GitRepo repo;
|
||||||
this->lastCheck = millis();
|
|
||||||
this->updateAvailable = false;
|
this->updateAvailable = false;
|
||||||
this->error = repo.getReleases(2);
|
this->error = repo.getReleases(2);
|
||||||
if(this->error == 0) { // Get 2 releases so we can filter our pre-releases
|
if(this->error == 0) { // Get 2 releases so we can filter our pre-releases
|
||||||
|
|
@ -320,6 +323,7 @@ int GitUpdater::checkInternet() {
|
||||||
uint32_t t = millis();
|
uint32_t t = millis();
|
||||||
WiFiClientSecure client;
|
WiFiClientSecure client;
|
||||||
client.setInsecure();
|
client.setInsecure();
|
||||||
|
client.setHandshakeTimeout(3);
|
||||||
HTTPClient *https = new HTTPClient();
|
HTTPClient *https = new HTTPClient();
|
||||||
https->setReuse(false);
|
https->setReuse(false);
|
||||||
if(https->begin(client, "https://github.com/rstrouse/ESPSomfy-RTS")) {
|
if(https->begin(client, "https://github.com/rstrouse/ESPSomfy-RTS")) {
|
||||||
|
|
@ -328,11 +332,11 @@ int GitUpdater::checkInternet() {
|
||||||
int httpCode = https->sendRequest("HEAD");
|
int httpCode = https->sendRequest("HEAD");
|
||||||
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) {
|
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) {
|
||||||
err = 0;
|
err = 0;
|
||||||
Serial.printf("Check Internet Success: %ldms\n", millis() - t);
|
Serial.printf("Internet is Available: %ldms\n", millis() - t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err = httpCode;
|
err = httpCode;
|
||||||
Serial.printf("Check Internet Error: %d: %ldms\n", err, millis() - t);
|
Serial.printf("Internet is Unavailable: %d: %ldms\n", err, millis() - t);
|
||||||
}
|
}
|
||||||
https->end();
|
https->end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,6 @@ void setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
if(!rebootDelay.reboot) git.loop();
|
|
||||||
|
|
||||||
// put your main code here, to run repeatedly:
|
// put your main code here, to run repeatedly:
|
||||||
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
|
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
|
||||||
Serial.print("Rebooting after ");
|
Serial.print("Rebooting after ");
|
||||||
|
|
@ -55,6 +53,7 @@ void loop() {
|
||||||
if(millis() - timing > 100) Serial.printf("Timing Somfy: %ldms\n", millis() - timing);
|
if(millis() - timing > 100) Serial.printf("Timing Somfy: %ldms\n", millis() - timing);
|
||||||
timing = millis();
|
timing = millis();
|
||||||
if(net.connected()) {
|
if(net.connected()) {
|
||||||
|
if(!rebootDelay.reboot) git.loop();
|
||||||
webServer.loop();
|
webServer.loop();
|
||||||
if(millis() - timing > 200) Serial.printf("Timing WebServer: %ldms\n", millis() - timing);
|
if(millis() - timing > 200) Serial.printf("Timing WebServer: %ldms\n", millis() - timing);
|
||||||
timing = millis();
|
timing = millis();
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
193
Web.cpp
193
Web.cpp
|
|
@ -22,7 +22,8 @@ extern MQTTClass mqtt;
|
||||||
extern GitUpdater git;
|
extern GitUpdater git;
|
||||||
extern Network net;
|
extern Network net;
|
||||||
|
|
||||||
#define WEB_MAX_RESPONSE 34768
|
//#define WEB_MAX_RESPONSE 34768
|
||||||
|
#define WEB_MAX_RESPONSE 8192
|
||||||
static char g_content[WEB_MAX_RESPONSE];
|
static char g_content[WEB_MAX_RESPONSE];
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -225,16 +226,94 @@ void Web::handleStreamFile(WebServer &server, const char *filename, const char *
|
||||||
server.streamFile(file, encoding);
|
server.streamFile(file, encoding);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
void Web::chunkRoomsResponse(WebServer &server, const char * elem) {
|
||||||
|
uint8_t ndx = 0;
|
||||||
|
if(elem && strlen(elem) > 0) {
|
||||||
|
sprintf(g_content, "\"%s\"", elem);
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
for(uint8_t i = 0; i < SOMFY_MAX_ROOMS; i++) {
|
||||||
|
if(somfy.rooms[i].roomId != 0) {
|
||||||
|
DynamicJsonDocument doc(512);
|
||||||
|
JsonObject obj = doc.to<JsonObject>();
|
||||||
|
somfy.rooms[i].toJSON(obj);
|
||||||
|
strcpy(g_content, ndx++ != 0 ? "," : "[");
|
||||||
|
serializeJson(doc, &g_content[strlen(g_content)], sizeof(g_content) - strlen(g_content));
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.sendContent(ndx == 0 ? "[]" : "]");
|
||||||
|
}
|
||||||
|
void Web::chunkShadesResponse(WebServer &server, const char * elem) {
|
||||||
|
uint8_t ndx = 0;
|
||||||
|
if(elem && strlen(elem) > 0) {
|
||||||
|
sprintf(g_content, "\"%s\"", elem);
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
|
||||||
|
if(somfy.shades[i].getShadeId() != 255) {
|
||||||
|
DynamicJsonDocument doc(1024);
|
||||||
|
JsonObject obj = doc.to<JsonObject>();
|
||||||
|
somfy.shades[i].toJSON(obj);
|
||||||
|
strcpy(g_content, ndx++ != 0 ? "," : "[");
|
||||||
|
serializeJson(doc, &g_content[strlen(g_content)], sizeof(g_content) - strlen(g_content));
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.sendContent(ndx == 0 ? "[]" : "]");
|
||||||
|
}
|
||||||
|
void Web::chunkGroupsResponse(WebServer &server, const char * elem) {
|
||||||
|
uint8_t ndx = 0;
|
||||||
|
if(elem && strlen(elem) > 0) {
|
||||||
|
sprintf(g_content, "\"%s\"", elem);
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
for(uint8_t i = 0; i < SOMFY_MAX_GROUPS; i++) {
|
||||||
|
if(somfy.groups[i].getGroupId() != 255) {
|
||||||
|
DynamicJsonDocument doc(1024);
|
||||||
|
JsonObject obj = doc.to<JsonObject>();
|
||||||
|
somfy.groups[i].toJSON(obj);
|
||||||
|
strcpy(g_content, ndx++ != 0 ? "," : "[");
|
||||||
|
serializeJson(doc, &g_content[strlen(g_content)], sizeof(g_content) - strlen(g_content));
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.sendContent(ndx == 0 ? "[]" : "]");
|
||||||
|
}
|
||||||
void Web::handleController(WebServer &server) {
|
void Web::handleController(WebServer &server) {
|
||||||
webServer.sendCORSHeaders(server);
|
webServer.sendCORSHeaders(server);
|
||||||
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
||||||
HTTPMethod method = server.method();
|
HTTPMethod method = server.method();
|
||||||
settings.printAvailHeap();
|
settings.printAvailHeap();
|
||||||
if (method == HTTP_POST || method == HTTP_GET) {
|
if (method == HTTP_POST || method == HTTP_GET) {
|
||||||
DynamicJsonDocument doc(min((uint32_t)WEB_MAX_RESPONSE, ESP.getMaxAllocHeap() - 512));
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
somfy.toJSON(doc);
|
// Alright lets chunk our response.
|
||||||
serializeJson(doc, g_content);
|
snprintf(g_content, sizeof(g_content), "{\"maxRooms\":%d,\"maxShades\":%d,\"maxGroups\":%d,\"maxGroupedShades\":%d,\"maxLinkedRemotes\":%d,\"startingAddress\":%d,\"transceiver\":",
|
||||||
server.send(200, _encoding_json, g_content);
|
SOMFY_MAX_ROOMS, SOMFY_MAX_SHADES, SOMFY_MAX_GROUPS, SOMFY_MAX_GROUPED_SHADES, SOMFY_MAX_LINKED_REMOTES, somfy.startingAddress);
|
||||||
|
server.send_P(200, _encoding_json, g_content);
|
||||||
|
{
|
||||||
|
DynamicJsonDocument doc(1024);
|
||||||
|
JsonObject trans = doc.to<JsonObject>();
|
||||||
|
somfy.transceiver.toJSON(trans);
|
||||||
|
serializeJson(doc, g_content);
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
DynamicJsonDocument doc(512);
|
||||||
|
JsonObject fw = doc.to<JsonObject>();
|
||||||
|
git.toJSON(fw);
|
||||||
|
server.sendContent(",\"version\":");
|
||||||
|
serializeJson(doc, g_content);
|
||||||
|
server.sendContent(g_content);
|
||||||
|
}
|
||||||
|
server.sendContent(",\"rooms\":");
|
||||||
|
this->chunkRoomsResponse(server);
|
||||||
|
server.sendContent(",\"shades\":");
|
||||||
|
this->chunkShadesResponse(server);
|
||||||
|
server.sendContent(",\"groups\":");
|
||||||
|
this->chunkGroupsResponse(server);
|
||||||
|
server.sendContent("}");
|
||||||
|
server.sendContent("", 0);
|
||||||
}
|
}
|
||||||
else server.send(404, _encoding_text, _response_404);
|
else server.send(404, _encoding_text, _response_404);
|
||||||
}
|
}
|
||||||
|
|
@ -257,11 +336,10 @@ void Web::handleGetRooms(WebServer &server) {
|
||||||
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
||||||
HTTPMethod method = server.method();
|
HTTPMethod method = server.method();
|
||||||
if (method == HTTP_POST || method == HTTP_GET) {
|
if (method == HTTP_POST || method == HTTP_GET) {
|
||||||
DynamicJsonDocument doc(16384);
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
JsonArray arr = doc.to<JsonArray>();
|
server.send_P(200, _encoding_json, " ");
|
||||||
somfy.toJSONRooms(arr);
|
this->chunkRoomsResponse(server);
|
||||||
serializeJson(doc, g_content);
|
server.sendContent("", 0);
|
||||||
server.send(200, _encoding_json, g_content);
|
|
||||||
}
|
}
|
||||||
else server.send(404, _encoding_text, _response_404);
|
else server.send(404, _encoding_text, _response_404);
|
||||||
}
|
}
|
||||||
|
|
@ -270,11 +348,10 @@ void Web::handleGetShades(WebServer &server) {
|
||||||
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
||||||
HTTPMethod method = server.method();
|
HTTPMethod method = server.method();
|
||||||
if (method == HTTP_POST || method == HTTP_GET) {
|
if (method == HTTP_POST || method == HTTP_GET) {
|
||||||
DynamicJsonDocument doc(16384);
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
JsonArray arr = doc.to<JsonArray>();
|
server.send_P(200, _encoding_json, " ");
|
||||||
somfy.toJSONShades(arr);
|
this->chunkShadesResponse(server);
|
||||||
serializeJson(doc, g_content);
|
server.sendContent("", 0);
|
||||||
server.send(200, _encoding_json, g_content);
|
|
||||||
}
|
}
|
||||||
else server.send(404, _encoding_text, _response_404);
|
else server.send(404, _encoding_text, _response_404);
|
||||||
}
|
}
|
||||||
|
|
@ -283,11 +360,10 @@ void Web::handleGetGroups(WebServer &server) {
|
||||||
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
||||||
HTTPMethod method = server.method();
|
HTTPMethod method = server.method();
|
||||||
if (method == HTTP_POST || method == HTTP_GET) {
|
if (method == HTTP_POST || method == HTTP_GET) {
|
||||||
DynamicJsonDocument doc(16384);
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
JsonArray arr = doc.to<JsonArray>();
|
server.send_P(200, _encoding_json, " ");
|
||||||
somfy.toJSONGroups(arr);
|
this->chunkGroupsResponse(server);
|
||||||
serializeJson(doc, g_content);
|
server.sendContent("", 0);
|
||||||
server.send(200, _encoding_json, g_content);
|
|
||||||
}
|
}
|
||||||
else server.send(404, _encoding_text, _response_404);
|
else server.send(404, _encoding_text, _response_404);
|
||||||
}
|
}
|
||||||
|
|
@ -713,27 +789,22 @@ void Web::handleDiscovery(WebServer &server) {
|
||||||
HTTPMethod method = apiServer.method();
|
HTTPMethod method = apiServer.method();
|
||||||
if (method == HTTP_POST || method == HTTP_GET) {
|
if (method == HTTP_POST || method == HTTP_GET) {
|
||||||
Serial.println("Discovery Requested");
|
Serial.println("Discovery Requested");
|
||||||
DynamicJsonDocument doc(min((uint32_t)WEB_MAX_RESPONSE, ESP.getMaxAllocHeap() - 512));
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
JsonObject obj = doc.to<JsonObject>();
|
// Alright lets chunk our response.
|
||||||
obj["serverId"] = settings.serverId;
|
char connType[10] = "Unknown";
|
||||||
obj["version"] = settings.fwVersion.name;
|
if(net.connType == conn_types::ethernet) strcpy(connType, "Ethernet");
|
||||||
obj["latest"] = git.latest.name;
|
else if(net.connType == conn_types::wifi) strcpy(connType, "Wifi");
|
||||||
obj["model"] = "ESPSomfyRTS";
|
snprintf(g_content, sizeof(g_content), "{\"serverId\":\"%s\",\"version\":\"%s\",\"latest\":\"%s\",\"model\":\"%s\",\"hostname\":\"%s\",\"authType\":%d,\"permissions\":%d,\"chipModel\":\"%s\",\"connType:\":\"%s\"",
|
||||||
obj["hostname"] = settings.hostname;
|
settings.serverId, settings.fwVersion.name, git.latest.name, "ESPSomfyRTS", settings.hostname, static_cast<uint8_t>(settings.Security.type), settings.Security.permissions, settings.chipModel, connType);
|
||||||
obj["authType"] = static_cast<uint8_t>(settings.Security.type);
|
server.send_P(200, _encoding_json, g_content);
|
||||||
obj["permissions"] = settings.Security.permissions;
|
server.sendContent(",\"rooms\":");
|
||||||
obj["chipModel"] = settings.chipModel;
|
this->chunkRoomsResponse(server);
|
||||||
if(net.connType == conn_types::ethernet) obj["connType"] = "Ethernet";
|
server.sendContent(",\"shades\":");
|
||||||
else if(net.connType == conn_types::wifi) obj["connType"] = "Wifi";
|
this->chunkShadesResponse(server);
|
||||||
else obj["connType"] = "Unknown";
|
server.sendContent(",\"groups\":");
|
||||||
JsonArray arrRooms = obj.createNestedArray("rooms");
|
this->chunkGroupsResponse(server);
|
||||||
somfy.toJSONRooms(arrRooms);
|
server.sendContent("}");
|
||||||
JsonArray arrShades = obj.createNestedArray("shades");
|
server.sendContent("", 0);
|
||||||
somfy.toJSONShades(arrShades);
|
|
||||||
JsonArray arrGroups = obj.createNestedArray("groups");
|
|
||||||
somfy.toJSONGroups(arrGroups);
|
|
||||||
serializeJson(doc, g_content);
|
|
||||||
server.send(200, _encoding_json, g_content);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
server.send(500, _encoding_text, "Invalid http method");
|
server.send(500, _encoding_text, "Invalid http method");
|
||||||
|
|
@ -768,6 +839,7 @@ void Web::handleBackup(WebServer &server, bool attach) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Serial.println("Error opening shades.cfg");
|
Serial.println("Error opening shades.cfg");
|
||||||
server.send(500, _encoding_text, "shades.cfg");
|
server.send(500, _encoding_text, "shades.cfg");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
server.streamFile(file, _encoding_text);
|
server.streamFile(file, _encoding_text);
|
||||||
file.close();
|
file.close();
|
||||||
|
|
@ -1988,34 +2060,22 @@ void Web::begin() {
|
||||||
Serial.print("Scanned ");
|
Serial.print("Scanned ");
|
||||||
Serial.print(n);
|
Serial.print(n);
|
||||||
Serial.println(" networks");
|
Serial.println(" networks");
|
||||||
DynamicJsonDocument doc(16384);
|
// Ok we need to chunk this response as well.
|
||||||
JsonObject obj = doc.to<JsonObject>();
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
JsonObject connected = obj.createNestedObject("connected");
|
// Alright lets chunk our response to this because we cannot allocate all that memory.
|
||||||
connected["name"] = settings.WIFI.ssid;
|
snprintf(g_content, sizeof(g_content), "{\"connected\":{\"name\":\"%s\",\"passphrase\":\"%s\",\"strength\":%d,\"channel\":%d},\"accessPoints\":[",
|
||||||
connected["passphrase"] = settings.WIFI.passphrase;
|
settings.WIFI.ssid, settings.WIFI.passphrase, WiFi.RSSI(), WiFi.channel());
|
||||||
connected["strength"] = WiFi.RSSI();
|
server.send_P(200, _encoding_json, g_content);
|
||||||
connected["channel"] = WiFi.channel();
|
bool bFirst = true;
|
||||||
JsonArray arr = obj.createNestedArray("accessPoints");
|
|
||||||
for(int i = 0; i < n; ++i) {
|
for(int i = 0; i < n; ++i) {
|
||||||
if(WiFi.SSID(i).length() == 0 || WiFi.RSSI(i) < -95) continue; // Ignore hidden and weak networks that we cannot connect to anyway.
|
if(WiFi.SSID(i).length() == 0 || WiFi.RSSI(i) < -95) continue; // Ignore hidden and weak networks that we cannot connect to anyway.
|
||||||
JsonObject a = arr.createNestedObject();
|
snprintf(g_content, sizeof(g_content), "%s{\"name\":\"%s\",\"channel\":%d,\"encryption\":\"%s\",\"strength\":%d,\"macAddress\":\"%s\"}",
|
||||||
a["name"] = WiFi.SSID(i);
|
bFirst ? "" : ",", WiFi.SSID(i).c_str(), WiFi.channel(i), settings.WIFI.mapEncryptionType(WiFi.encryptionType(i)).c_str(), WiFi.RSSI(i), WiFi.BSSIDstr(i).c_str());
|
||||||
a["channel"] = WiFi.channel(i);
|
server.sendContent(g_content);
|
||||||
a["encryption"] = settings.WIFI.mapEncryptionType(WiFi.encryptionType(i));
|
bFirst = false;
|
||||||
a["strength"] = WiFi.RSSI(i);
|
|
||||||
a["macAddress"] = WiFi.BSSIDstr(i);
|
|
||||||
}
|
}
|
||||||
serializeJson(doc, g_content);
|
server.sendContent("]}");
|
||||||
/*
|
server.sendContent("", 0);
|
||||||
String content = "{\"connected\": {\"name\":\"" + String(settings.WIFI.ssid) + "\",\"passphrase\":\"" + String(settings.WIFI.passphrase) + "\",\"strength\":" + WiFi.RSSI() + ",\"channel\":" + WiFi.channel() + "}, \"accessPoints\":[";
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
if (i != 0) content += ",";
|
|
||||||
content += "{\"name\":\"" + WiFi.SSID(i) + "\",\"channel\":" + WiFi.channel(i) + ",\"encryption\":\"" + settings.WIFI.mapEncryptionType(WiFi.encryptionType(i)) + "\",\"strength\":" + WiFi.RSSI(i) + ",\"macAddress\":\"" + WiFi.BSSIDstr(i) + "\"}";
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
content += "]}";
|
|
||||||
*/
|
|
||||||
server.send(statusCode, "application/json", g_content);
|
|
||||||
});
|
});
|
||||||
server.on("/reboot", []() { webServer.handleReboot(server);});
|
server.on("/reboot", []() { webServer.handleReboot(server);});
|
||||||
server.on("/saveSecurity", []() {
|
server.on("/saveSecurity", []() {
|
||||||
|
|
@ -2380,7 +2440,6 @@ void Web::begin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/shadeSortOrder", []() {
|
server.on("/shadeSortOrder", []() {
|
||||||
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
|
||||||
DynamicJsonDocument doc(512);
|
DynamicJsonDocument doc(512);
|
||||||
|
|
|
||||||
5
Web.h
5
Web.h
|
|
@ -39,5 +39,10 @@ class Web {
|
||||||
bool createAPIPinToken(const IPAddress ipAddress, const char *pin, char *token);
|
bool createAPIPinToken(const IPAddress ipAddress, const char *pin, char *token);
|
||||||
bool createAPIPasswordToken(const IPAddress ipAddress, const char *username, const char *password, char *token);
|
bool createAPIPasswordToken(const IPAddress ipAddress, const char *username, const char *password, char *token);
|
||||||
bool isAuthenticated(WebServer &server, bool cfg = false);
|
bool isAuthenticated(WebServer &server, bool cfg = false);
|
||||||
|
|
||||||
|
void chunkRoomsResponse(WebServer &server, const char *elem = nullptr);
|
||||||
|
void chunkShadesResponse(WebServer &server, const char *elem = nullptr);
|
||||||
|
void chunkGroupsResponse(WebServer &server, const char *elem = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="main.css?v=2.3.2a" type="text/css" />
|
<link rel="stylesheet" href="main.css?v=2.3.2b" type="text/css" />
|
||||||
<link rel="stylesheet" href="widgets.css?v=2.3.2a" type="text/css" />
|
<link rel="stylesheet" href="widgets.css?v=2.3.2b" type="text/css" />
|
||||||
<link rel="stylesheet" href="icons.css?v=2.3.2a" type="text/css" />
|
<link rel="stylesheet" href="icons.css?v=2.3.2b" type="text/css" />
|
||||||
<link rel="icon" type="image/png" href="favicon.png" />
|
<link rel="icon" type="image/png" href="favicon.png" />
|
||||||
<script type="text/javascript" src="index.js?v=2.3.2a"></script>
|
<script type="text/javascript" src="index.js?v=2.3.2b"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="divContainer" class="container main" data-auth="false">
|
<div id="divContainer" class="container main" data-auth="false">
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,6 @@ function getJSON(url, cb) {
|
||||||
function getJSONSync(url, cb) {
|
function getJSONSync(url, cb) {
|
||||||
let overlay = ui.waitMessage(document.getElementById('divContainer'));
|
let overlay = ui.waitMessage(document.getElementById('divContainer'));
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
console.log({ get: url });
|
|
||||||
xhr.responseType = 'json';
|
xhr.responseType = 'json';
|
||||||
xhr.onload = () => {
|
xhr.onload = () => {
|
||||||
let status = xhr.status;
|
let status = xhr.status;
|
||||||
|
|
@ -285,10 +284,12 @@ function getJSONSync(url, cb) {
|
||||||
cb(xhr.response, null);
|
cb(xhr.response, null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
console.log({ get: url, obj:xhr.response });
|
||||||
cb(null, xhr.response);
|
cb(null, xhr.response);
|
||||||
}
|
}
|
||||||
if (typeof overlay !== 'undefined') overlay.remove();
|
if (typeof overlay !== 'undefined') overlay.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onerror = (evt) => {
|
xhr.onerror = (evt) => {
|
||||||
let err = {
|
let err = {
|
||||||
htmlError: xhr.status || 500,
|
htmlError: xhr.status || 500,
|
||||||
|
|
@ -1956,6 +1957,7 @@ class Somfy {
|
||||||
this.setRoomsList(somfy.rooms);
|
this.setRoomsList(somfy.rooms);
|
||||||
this.setShadesList(somfy.shades);
|
this.setShadesList(somfy.shades);
|
||||||
this.setGroupsList(somfy.groups);
|
this.setGroupsList(somfy.groups);
|
||||||
|
if (typeof somfy.version !== 'undefined') firmware.procFwStatus(somfy.version);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -2755,7 +2757,7 @@ class Somfy {
|
||||||
while (sel.firstChild) sel.removeChild(sel.firstChild);
|
while (sel.firstChild) sel.removeChild(sel.firstChild);
|
||||||
let cm = document.getElementById('divContainer').getAttribute('data-chipmodel');
|
let cm = document.getElementById('divContainer').getAttribute('data-chipmodel');
|
||||||
let pm = this.pinMaps.find(x => x.name === cm) || { name: '', maxPins: 39, inputs: [0, 1, 6, 7, 8, 9, 10, 11, 37, 38], outputs: [3, 6, 7, 8, 9, 10, 11, 34, 35, 36, 37, 38, 39] };
|
let pm = this.pinMaps.find(x => x.name === cm) || { name: '', maxPins: 39, inputs: [0, 1, 6, 7, 8, 9, 10, 11, 37, 38], outputs: [3, 6, 7, 8, 9, 10, 11, 34, 35, 36, 37, 38, 39] };
|
||||||
console.log({ cm: cm, pm: pm });
|
//console.log({ cm: cm, pm: pm });
|
||||||
for (let i = 0; i <= pm.maxPins; i++) {
|
for (let i = 0; i <= pm.maxPins; i++) {
|
||||||
if (type.includes('in') && pm.inputs.includes(i)) continue;
|
if (type.includes('in') && pm.inputs.includes(i)) continue;
|
||||||
if (type.includes('out') && pm.outputs.includes(i)) continue;
|
if (type.includes('out') && pm.outputs.includes(i)) continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue