From 79e76bddfbba840ac64ce6ba9ee79bb9c71367a5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:28:09 +0200 Subject: [PATCH] Add support for HostedOta based on OtaUrl --- tasmota/tasmota_support/support_command.ino | 54 +++++++++++++------ .../tasmota_support/support_hosted_mcu.ino | 52 +++++++++--------- .../xdrv_01_9_webserver.ino | 2 +- 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 68491613c..ca36d2153 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -22,6 +22,9 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_SO_WIFINOSLEEP "|" // Other commands D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_RESTART "|" +#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED + D_CMND_HOSTEDOTA "|" +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED #ifndef FIRMWARE_MINIMAL D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_POWERLOCK "|" D_CMND_TIMEDPOWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_SLEEP "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_STATETEXT "|" D_CMND_SAVEDATA "|" @@ -62,9 +65,6 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #endif // ESP32 D_CMND_SETSENSOR "|" D_CMND_SENSOR "|" D_CMND_DRIVER "|" D_CMND_JSON "|" D_CMND_JSON_PP -#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED -"|" D_CMND_HOSTEDOTA -#endif //CONFIG_ESP_WIFI_REMOTE_ENABLED #endif //FIRMWARE_MINIMAL ; @@ -74,6 +74,9 @@ SO_SYNONYMS(kTasmotaSynonyms, void (* const TasmotaCommand[])(void) PROGMEM = { &CmndUpgrade, &CmndUpgrade, &CmndOtaUrl, &CmndSeriallog, &CmndRestart, +#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED + &CmdHostedOta, +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED #ifndef FIRMWARE_MINIMAL &CmndBacklog, &CmndDelay, &CmndPower, &CmndPowerLock, &CmndTimedPower, &CmndStatus, &CmndState, &CmndSleep, &CmndPowerOnState, &CmndPulsetime, &CmndBlinktime, &CmndBlinkcount, &CmndStateText, &CmndSavedata, @@ -114,9 +117,6 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #endif // ESP32 &CmndSetSensor, &CmndSensor, &CmndDriver, &CmndJson, &CmndJsonPP -#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED - , &CmdHostedOta -#endif //CONFIG_ESP_WIFI_REMOTE_ENABLED #endif //FIRMWARE_MINIMAL }; @@ -988,7 +988,7 @@ void CmndStatus(void) "\"CpuFrequency\":%d,\"Hardware\":\"%s\"" #ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED ",\"HostedMCU\":{\"Hardware\":\"" CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET"\",\"Version\":\"%s\"}" -#endif +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED "%s}}"), TasmotaGlobal.version, TasmotaGlobal.image_name, GetCodeCores().c_str(), GetBuildDateAndTime().c_str() #ifdef ESP8266 @@ -998,7 +998,7 @@ void CmndStatus(void) ESP.getCpuFreqMHz(), GetDeviceHardwareRevision().c_str(), #ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED GetHostedMCUFwVersion().c_str(), -#endif +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED GetStatistics().c_str()); CmndStatusResponse(2); } @@ -1341,6 +1341,36 @@ void CmndOtaUrl(void) ResponseCmndChar(SettingsText(SET_OTAURL)); } +#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED +void CmdHostedOta() { + // If OtaUrl = "https://ota.tasmota.com/tasmota32/tasmota32p4.bin" + // Then use "https://ota.tasmota.com/tasmota32/coprocessor/network_adapter_" CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET ".bin" + // As an option allow user to enter URL like: + // HostedOta https://ota.tasmota.com/tasmota32/coprocessor/network_adapter_esp32c6.bin + // HostedOta https://ota.tasmota.com/tasmota32/coprocessor/v2.0.14/network_adapter_esp32c6.bin + char full_ota_url[200]; + char *hosted_ota = XdrvMailbox.data; + if (!XdrvMailbox.data_len) { + // Replace https://ota.tasmota.com/tasmota32/tasmota32p4.bin with https://ota.tasmota.com/tasmota32/coprocessor/network_adapter_esp32c6.bin + char ota_url[TOPSZ]; + strlcpy(full_ota_url, GetOtaUrl(ota_url, sizeof(ota_url)), sizeof(full_ota_url)); + char *bch = strrchr(full_ota_url, '/'); // Only consider filename after last backslash + if (bch == nullptr) { bch = full_ota_url; } // No path found so use filename only + *bch = '\0'; // full_ota_url = https://ota.tasmota.com/tasmota32 + snprintf_P(full_ota_url, sizeof(full_ota_url), PSTR("%s/coprocessor/network_adapter_" CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET ".bin"), full_ota_url); + hosted_ota = full_ota_url; + } + int ret = OTAHostedMCU(hosted_ota); + if (ret == ESP_OK) { + // next lines are questionable, because currently the system will reboot immediately on succesful upgrade + ResponseCmndDone(); + } else { + snprintf_P(full_ota_url, sizeof(full_ota_url), PSTR("Upgrade failed with error %d"), ret); + ResponseCmndChar(full_ota_url); + } +} +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED + void CmndSeriallog(void) { if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) { @@ -3108,12 +3138,4 @@ void CmndTouchThres(void) { ResponseCmndNumber(Settings->touch_threshold); } #endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 - -void CmdHostedOta() { - if (XdrvMailbox.data_len > 0) { - OTAHostedMCU(XdrvMailbox.data); - } - ResponseCmndDone(); -} - #endif // ESP32 diff --git a/tasmota/tasmota_support/support_hosted_mcu.ino b/tasmota/tasmota_support/support_hosted_mcu.ino index fec22d2a4..5eaa1ea30 100644 --- a/tasmota/tasmota_support/support_hosted_mcu.ino +++ b/tasmota/tasmota_support/support_hosted_mcu.ino @@ -18,51 +18,53 @@ */ - #ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED #include "esp_hosted.h" #include "esp_hosted_api_types.h" #include "esp_hosted_ota.h" -String GetHostedMCUFwVersion(void) { - static int major1 = -1; - static int minor1; - static int patch1; +int GetFwVersionNumber(void) { + // Function is not yet implemented in Arduino Core so emulate it here + return 0x0200000E; // v2.0.14 +} + +int GetHostedMCUFwVersionNumber(void) { + static int version = -1; if (!esp_hosted_is_config_valid()) { - return String(""); + return 0; } - if (-1 == major1) { - major1 = 0; - minor1 = 0; - patch1 = 6; + if (-1 == version) { + version = 6; // v0.0.6 esp_hosted_coprocessor_fwver_t ver_info; - esp_err_t err = esp_hosted_get_coprocessor_fwversion(&ver_info); // This takes almost 4 seconds + esp_err_t err = esp_hosted_get_coprocessor_fwversion(&ver_info); // This takes almost 4 seconds on > 24; + uint8_t minor1 = version >> 16; + uint16_t patch1 = version; char data[40]; snprintf_P(data, sizeof(data), PSTR("%d.%d.%d"), major1, minor1, patch1); return String(data); } -void OTAHostedMCU(const char* image_url) { - AddLog(LOG_LEVEL_INFO, PSTR("OTA: co-processor OTA update started from %s"), image_url); - esp_err_t ret = esp_hosted_slave_ota(image_url); - // next lines are questionable, because ATM the system will reboot immediately - maybe we would see the failure - if (ret == ESP_OK) { - AddLog(LOG_LEVEL_INFO, PSTR("OTA: co-processor OTA update successful !!")); - } else { - AddLog(LOG_LEVEL_INFO, PSTR("OTA: co-processor OTA update failed: %d"), ret); - } +int OTAHostedMCU(const char* image_url) { + return esp_hosted_slave_ota(image_url); } - -#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED \ No newline at end of file +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED \ No newline at end of file diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 085d69af6..7f1ea56f5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -2985,7 +2985,7 @@ void HandleInformation(void) { WSContentSend_P(PSTR("}1 Hosted MCU }2 " CONFIG_ESP_HOSTED_IDF_SLAVE_TARGET "")); WSContentSend_P(PSTR("}1 Hosted Remote Fw }2%s"), GetHostedMCUFwVersion().c_str()); WSContentSeparatorIFat(); -#endif //CONFIG_ESP_WIFI_REMOTE_ENABLED +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED bool show_hr = false; if ((WiFi.getMode() >= WIFI_AP) && (static_cast(WiFi.softAPIP()) != 0)) { WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str());