Merge remote-tracking branch 'origin/v3.4' into dev

This commit is contained in:
proddy
2022-01-23 17:56:52 +01:00
parent 02e2b51814
commit 77e1898512
538 changed files with 32282 additions and 38655 deletions

View File

@@ -48,7 +48,7 @@ void APSettingsService::manageAP() {
void APSettingsService::startAP() {
WiFi.softAPConfig(_state.localIP, _state.gatewayIP, _state.subnetMask);
esp_wifi_set_bandwidth(ESP_IF_WIFI_AP, WIFI_BW_HT20);
WiFi.softAP(_state.ssid.c_str(), _state.password.c_str());
WiFi.softAP(_state.ssid.c_str(), _state.password.c_str(), _state.channel, _state.ssidHidden, _state.maxClients);
if (!_dnsServer) {
IPAddress apIp = WiFi.softAPIP();
emsesp::EMSESP::logger().info(F("Starting Access Point with captive portal on %s"), apIp.toString().c_str());

View File

@@ -8,16 +8,6 @@
#include <DNSServer.h>
#include <IPAddress.h>
#include <uuid/common.h> // proddy added for get_uptime()
#define MANAGE_NETWORK_DELAY 10000
#define AP_MODE_ALWAYS 0
#define AP_MODE_DISCONNECTED 1
#define AP_MODE_NEVER 2
#define DNS_PORT 53
#ifndef FACTORY_AP_PROVISION_MODE
#define FACTORY_AP_PROVISION_MODE AP_MODE_DISCONNECTED
#endif
@@ -27,7 +17,7 @@
#endif
#ifndef FACTORY_AP_PASSWORD
#define FACTORY_AP_PASSWORD "esp-react"
#define FACTORY_AP_PASSWORD "ems-esp-neo"
#endif
#ifndef FACTORY_AP_LOCAL_IP
@@ -42,29 +32,56 @@
#define FACTORY_AP_SUBNET_MASK "255.255.255.0"
#endif
#ifndef FACTORY_AP_CHANNEL
#define FACTORY_AP_CHANNEL 1
#endif
#ifndef FACTORY_AP_SSID_HIDDEN
#define FACTORY_AP_SSID_HIDDEN false
#endif
#ifndef FACTORY_AP_MAX_CLIENTS
#define FACTORY_AP_MAX_CLIENTS 4
#endif
#define AP_SETTINGS_FILE "/config/apSettings.json"
#define AP_SETTINGS_SERVICE_PATH "/rest/apSettings"
#define AP_MODE_ALWAYS 0
#define AP_MODE_DISCONNECTED 1
#define AP_MODE_NEVER 2
#define MANAGE_NETWORK_DELAY 10000
#define DNS_PORT 53
enum APNetworkStatus { ACTIVE = 0, INACTIVE, LINGERING };
class APSettings {
public:
uint8_t provisionMode;
String ssid;
String password;
uint8_t provisionMode;
String ssid;
String password;
uint8_t channel;
bool ssidHidden;
uint8_t maxClients;
IPAddress localIP;
IPAddress gatewayIP;
IPAddress subnetMask;
bool operator==(const APSettings & settings) const {
return provisionMode == settings.provisionMode && ssid == settings.ssid && password == settings.password && localIP == settings.localIP
&& gatewayIP == settings.gatewayIP && subnetMask == settings.subnetMask;
return provisionMode == settings.provisionMode && ssid == settings.ssid && password == settings.password && channel == settings.channel
&& ssidHidden == settings.ssidHidden && maxClients == settings.maxClients && localIP == settings.localIP && gatewayIP == settings.gatewayIP
&& subnetMask == settings.subnetMask;
}
static void read(APSettings & settings, JsonObject & root) {
root["provision_mode"] = settings.provisionMode;
root["ssid"] = settings.ssid;
root["password"] = settings.password;
root["channel"] = settings.channel;
root["ssid_hidden"] = settings.ssidHidden;
root["max_clients"] = settings.maxClients;
root["local_ip"] = settings.localIP.toString();
root["gateway_ip"] = settings.gatewayIP.toString();
root["subnet_mask"] = settings.subnetMask.toString();
@@ -81,8 +98,11 @@ class APSettings {
default:
newSettings.provisionMode = AP_MODE_ALWAYS;
}
newSettings.ssid = root["ssid"] | FACTORY_AP_SSID;
newSettings.password = root["password"] | FACTORY_AP_PASSWORD;
newSettings.ssid = root["ssid"] | FACTORY_AP_SSID;
newSettings.password = root["password"] | FACTORY_AP_PASSWORD;
newSettings.channel = root["channel"] | FACTORY_AP_CHANNEL;
newSettings.ssidHidden = root["ssid_hidden"] | FACTORY_AP_SSID_HIDDEN;
newSettings.maxClients = root["max_clients"] | FACTORY_AP_MAX_CLIENTS;
JsonUtils::readIP(root, "local_ip", newSettings.localIP, FACTORY_AP_LOCAL_IP);
JsonUtils::readIP(root, "gateway_ip", newSettings.gatewayIP, FACTORY_AP_GATEWAY_IP);
@@ -122,4 +142,4 @@ class APSettingsService : public StatefulService<APSettings> {
void handleDNS();
};
#endif // end APSettingsConfig_h
#endif

View File

@@ -22,4 +22,4 @@ class APStatus {
void apStatus(AsyncWebServerRequest * request);
};
#endif // end APStatus_h
#endif

View File

@@ -44,4 +44,4 @@ void AuthenticationService::signIn(AsyncWebServerRequest * request, JsonVariant
request->send(response);
}
#endif // end FT_ENABLED(FT_SECURITY)
#endif

View File

@@ -25,5 +25,6 @@ class AuthenticationService {
void verifyAuthorization(AsyncWebServerRequest * request);
};
#endif // end FT_ENABLED(FT_SECURITY)
#endif // end SecurityManager_h
#endif
#endif

View File

@@ -42,11 +42,6 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
});
}
});
// only added for local testing (CORS)
// DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization");
// DefaultHeaders::Instance().addHeader("Access-Control-Allow-Credentials", "true");
// DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
}
void ESP8266React::begin() {

View File

@@ -10,4 +10,4 @@ class ESPUtils {
}
};
#endif // end ESPUtils
#endif

View File

@@ -35,9 +35,11 @@ class FSPersistence {
// debug added by Proddy
#if defined(EMSESP_DEBUG)
#if defined(EMSESP_USE_SERIAL)
Serial.printf("Reading file: %s: ", _filePath);
serializeJson(jsonDocument, Serial);
Serial.println();
#endif
#endif
_statefulService->updateWithoutPropagation(jsonObject, _stateUpdater);
@@ -68,9 +70,11 @@ class FSPersistence {
// debug added by Proddy
#if defined(EMSESP_DEBUG)
#if defined(EMSESP_USE_SERIAL)
Serial.printf("Writing to file: %s: ", _filePath);
serializeJson(jsonDocument, Serial);
Serial.println();
#endif
#endif
// serialize the data to the file
@@ -111,4 +115,4 @@ class FSPersistence {
}
};
#endif // end FSPersistence
#endif

View File

@@ -22,4 +22,4 @@ class FactoryResetService {
void handleRequest(AsyncWebServerRequest * request);
};
#endif // end FactoryResetService_h
#endif

View File

@@ -106,14 +106,17 @@ class HttpPostEndpoint {
if (outcome == StateUpdateResult::ERROR) {
request->send(400);
return;
}
if (outcome == StateUpdateResult::CHANGED) {
} else if ((outcome == StateUpdateResult::CHANGED) || (outcome == StateUpdateResult::CHANGED_RESTART)) {
request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); });
}
AsyncJsonResponse * response = new AsyncJsonResponse(false, _bufferSize);
jsonObject = response->getRoot().to<JsonObject>();
_statefulService->read(jsonObject, _stateReader);
response->setLength();
if (outcome == StateUpdateResult::CHANGED_RESTART) {
response->setCode(202); // added by proddy
}
request->send(response);
}
};
@@ -144,4 +147,4 @@ class HttpEndpoint : public HttpGetEndpoint<T>, public HttpPostEndpoint<T> {
}
};
#endif // end HttpEndpoint
#endif

View File

@@ -15,4 +15,4 @@ class IPUtils {
}
};
#endif // end IPUtils_h
#endif

View File

@@ -27,4 +27,4 @@ class JsonUtils {
}
};
#endif // end JsonUtils
#endif

View File

@@ -160,4 +160,4 @@ class MqttPubSub : public MqttPub<T>, public MqttSub<T> {
}
};
#endif // end MqttPubSub
#endif

View File

@@ -172,9 +172,10 @@ void MqttSettings::read(MqttSettings & settings, JsonObject & root) {
root["publish_time_sensor"] = settings.publish_time_sensor;
root["mqtt_qos"] = settings.mqtt_qos;
root["mqtt_retain"] = settings.mqtt_retain;
root["ha_climate_format"] = settings.ha_climate_format;
root["ha_enabled"] = settings.ha_enabled;
root["nested_format"] = settings.nested_format;
root["discovery_prefix"] = settings.discovery_prefix;
root["publish_single"] = settings.publish_single;
root["send_response"] = settings.send_response;
}
@@ -202,10 +203,11 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
newSettings.publish_time_other = root["publish_time_other"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_sensor = root["publish_time_sensor"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.ha_climate_format = root["ha_climate_format"] | EMSESP_DEFAULT_HA_CLIMATE_FORMAT;
newSettings.ha_enabled = root["ha_enabled"] | EMSESP_DEFAULT_HA_ENABLED;
newSettings.nested_format = root["nested_format"] | EMSESP_DEFAULT_NESTED_FORMAT;
newSettings.send_response = root["send_response"] | EMSESP_DEFAULT_SEND_RESPONSE;
newSettings.ha_enabled = root["ha_enabled"] | EMSESP_DEFAULT_HA_ENABLED;
newSettings.nested_format = root["nested_format"] | EMSESP_DEFAULT_NESTED_FORMAT;
newSettings.discovery_prefix = root["discovery_prefix"] | EMSESP_DEFAULT_DISCOVERY_PREFIX;
newSettings.publish_single = root["publish_single"] | EMSESP_DEFAULT_PUBLISH_SINGLE;
newSettings.send_response = root["send_response"] | EMSESP_DEFAULT_SEND_RESPONSE;
if (newSettings.enabled != settings.enabled) {
changed = true;
@@ -220,12 +222,15 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
changed = true;
}
if (newSettings.send_response != settings.send_response) {
if (newSettings.discovery_prefix != settings.discovery_prefix) {
changed = true;
}
if (newSettings.ha_climate_format != settings.ha_climate_format) {
emsesp::EMSESP::mqtt_.ha_climate_format(newSettings.ha_climate_format);
if (newSettings.publish_single != settings.publish_single) {
changed = true;
}
if (newSettings.send_response != settings.send_response) {
changed = true;
}

View File

@@ -86,9 +86,10 @@ class MqttSettings {
uint16_t publish_time_sensor;
uint8_t mqtt_qos;
bool mqtt_retain;
uint8_t ha_climate_format;
bool ha_enabled;
uint8_t nested_format;
String discovery_prefix;
bool publish_single;
bool send_response;
static void read(MqttSettings & settings, JsonObject & root);
@@ -138,4 +139,4 @@ class MqttSettingsService : public StatefulService<MqttSettings> {
void configureMqtt();
};
#endif // end MqttSettingsService_h
#endif

View File

@@ -20,4 +20,4 @@ class MqttStatus {
void mqttStatus(AsyncWebServerRequest * request);
};
#endif // end MqttStatus_h
#endif

View File

@@ -69,4 +69,4 @@ class NTPSettingsService : public StatefulService<NTPSettings> {
void configureTime(AsyncWebServerRequest * request, JsonVariant & json);
};
#endif // end NTPSettingsService_h
#endif

View File

@@ -22,4 +22,4 @@ class NTPStatus {
void ntpStatus(AsyncWebServerRequest * request);
};
#endif // end NTPStatus_h
#endif

View File

@@ -35,17 +35,16 @@ void OTASettingsService::configureArduinoOTA() {
_arduinoOTA->setPort(_state.port);
_arduinoOTA->setPassword(_state.password.c_str());
_arduinoOTA->onStart([]() {
Serial.println(F("Starting"));
emsesp::EMSESP::system_.upload_status(true);
});
_arduinoOTA->onEnd([]() {
Serial.println(F("\r\nEnd"));
emsesp::EMSESP::system_.upload_status(false);
});
_arduinoOTA->onStart([]() { emsesp::EMSESP::system_.upload_status(true); });
_arduinoOTA->onEnd([]() { emsesp::EMSESP::system_.upload_status(false); });
_arduinoOTA->onProgress([](unsigned int progress, unsigned int total) { Serial.printf_P(PSTR("Progress: %u%%\r\n"), (progress / (total / 100))); });
_arduinoOTA->onProgress([](unsigned int progress, unsigned int total) {
#if defined(EMSESP_USE_SERIAL)
Serial.printf("Progress: %u%%\r\n", (progress / (total / 100)));
#endif
});
_arduinoOTA->onError([](ota_error_t error) {
#if defined(EMSESP_USE_SERIAL)
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR)
Serial.println(F("Auth Failed"));
@@ -57,6 +56,7 @@ void OTASettingsService::configureArduinoOTA() {
Serial.println(F("Receive Failed"));
else if (error == OTA_END_ERROR)
Serial.println(F("End Failed"));
#endif
});
_arduinoOTA->setMdnsEnabled(false); // disable as handled in NetworkSettingsService.cpp. https://github.com/emsesp/EMS-ESP32/issues/161

View File

@@ -12,7 +12,7 @@
#endif
#ifndef FACTORY_OTA_PASSWORD
#define FACTORY_OTA_PASSWORD "esp-react"
#define FACTORY_OTA_PASSWORD "ems-esp-neo"
#endif
#ifndef FACTORY_OTA_ENABLED
@@ -58,4 +58,4 @@ class OTASettingsService : public StatefulService<OTASettings> {
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info);
};
#endif // end OTASettingsService_h
#endif

View File

@@ -23,4 +23,4 @@ class RestartService {
void restart(AsyncWebServerRequest * request);
};
#endif // end RestartService_h
#endif

View File

@@ -104,4 +104,4 @@ class SecurityManager {
virtual ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction onRequest, AuthenticationPredicate predicate) = 0;
};
#endif // end SecurityManager_h
#endif

View File

@@ -115,5 +115,5 @@ class SecuritySettingsService : public SecurityManager {
ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction onRequest, AuthenticationPredicate predicate);
};
#endif // end FT_ENABLED(FT_SECURITY)
#endif // end SecuritySettingsService_h
#endif
#endif

View File

@@ -18,9 +18,10 @@
#endif
enum class StateUpdateResult {
CHANGED = 0, // The update changed the state and propagation should take place if required
UNCHANGED, // The state was unchanged, propagation should not take place
ERROR // There was a problem updating the state, propagation should not take place
CHANGED = 0, // The update changed the state and propagation should take place if required
CHANGED_RESTART, // a restart of the device is needed - added by proddy
UNCHANGED, // The state was unchanged, propagation should not take place
ERROR // There was a problem updating the state, propagation should not take place
};
template <typename T>
@@ -139,4 +140,4 @@ class StatefulService {
std::list<StateUpdateHandlerInfo_t> _updateHandlers;
};
#endif // end StatefulService_h
#endif

View File

@@ -21,4 +21,4 @@ class SystemStatus {
void systemStatus(AsyncWebServerRequest * request);
};
#endif // end SystemStatus_h
#endif

View File

@@ -24,4 +24,4 @@ class UploadFirmwareService {
static void handleEarlyDisconnect();
};
#endif // end UploadFirmwareService_h
#endif

View File

@@ -22,4 +22,4 @@ class WiFiScanner {
void listNetworks(AsyncWebServerRequest * request);
};
#endif // end WiFiScanner_h
#endif