diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..70d783b --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,160 @@ +name: ESPSomfy-RTS Release + +on: + release: + types: [created] + +env: + ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS: "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json" + ARDUINO_CLI_VERSION: "0.x" + ARDUINO_ESP32_VERSION: "2.0.10" + ARDUINO_JSON_VERSION: "6.21.3" + ESPTOOL_VERSION: "4.6" + LITTLEFS_VERSION: "v2.5.1" + MKLITTLEFS_VERSION: "3.1.0" + PUB_SUB_CLIENT_VERSION: "2.8.0" + PYTHON_VERSION: "3.10" + SMARTRC_CC1101_VERSION: "2.5.7" + WEB_SOCKET_VERSION: "2.4.0" + +jobs: + littlefs: + name: LittleFS + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v3 + + - name: Checkout mklittlefs + uses: actions/checkout@v3 + with: + repository: earlephilhower/mklittlefs + path: mklittlefs + ref: ${{ env.MKLITTLEFS_VERSION }} + + - name: Checkout LittleFS + uses: actions/checkout@v3 + with: + repository: littlefs-project/littlefs + path: mklittlefs/littlefs + ref: ${{ env.LITTLEFS_VERSION }} + + - name: Build mklittlefs + run: | + make -C mklittlefs + + - name: Create LittleFS + run: | + ./mklittlefs/mklittlefs --create data --size 1441792 SomfyController.littlefs.bin + + - name: Upload binaries + uses: actions/upload-artifact@v3 + with: + name: LittleFS + path: SomfyController.littlefs.bin + retention-days: 5 + + arduino: + name: ${{ matrix.name }} + needs: [littlefs] + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - board: esp32 + addr_bootloader: 0x1000 + chip: ESP32 + fqbn: esp32:esp32:esp32wrover + name: ESP32 + obname: SomfyController.onboard.esp32.bin + - board: esp32c3 + addr_bootloader: 0x0 + chip: ESP32-C3 + fqbn: esp32:esp32:esp32c3 + name: C3-mini + obname: SomfyController.onboard.esp32c3.bin + - board: esp32s2 + addr_bootloader: 0x1000 + chip: ESP32-S2 + fqbn: esp32:esp32:esp32s2 + name: S2-mini + obname: SomfyController.onboard.esp32s2.bin + - board: esp32s3 + addr_bootloader: 0x0 + chip: ESP32-S3 + fqbn: esp32:esp32:esp32s3 + name: S3-mini + obname: SomfyController.onboard.esp32s3.bin + steps: + - name: Get Release + id: get_release + uses: bruceadams/get-release@v1.3.2 + env: + GITHUB_TOKEN: ${{ github.token }} + + - name: Check out code + uses: actions/checkout@v3 + with: + path: SomfyController + + - name: Get LittleFS + uses: actions/download-artifact@v3 + with: + name: LittleFS + + - name: Install Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Upgrade pip + run: | + python -m pip install --upgrade pip + pip --version + + - name: Install ESPTool + run: | + pip install esptool==${{ env.ESPTOOL_VERSION }} + + - name: Install Arduino CLI + uses: arduino/setup-arduino-cli@v1 + with: + version: ${{ env.ARDUINO_CLI_VERSION }} + + - name: Configure Arduino CLI + run: | + arduino-cli core update-index + arduino-cli core install esp32:esp32@${{ env.ARDUINO_ESP32_VERSION }} + + - name: Configure Arduino Libraries + run: | + arduino-cli lib install ArduinoJson@${{ env.ARDUINO_JSON_VERSION }} + arduino-cli lib install PubSubClient@${{ env.PUB_SUB_CLIENT_VERSION }} + arduino-cli lib install SmartRC-CC1101-Driver-Lib@${{ env.SMARTRC_CC1101_VERSION }} + arduino-cli lib install WebSockets@${{ env.WEB_SOCKET_VERSION }} + + - name: Build ${{ matrix.name }} + run: | + mkdir -p build + arduino-cli compile --clean --output-dir build --fqbn ${{ matrix.fqbn }} --warnings default ./SomfyController + + - name: ${{ matrix.name }} Image + run: | + python -m esptool --chip ${{ matrix.chip }} \ + merge_bin -o build/${{ matrix.obname }} \ + ${{ matrix.addr_bootloader }} build/SomfyController.ino.bootloader.bin \ + 0x8000 build/SomfyController.ino.partitions.bin \ + 0x10000 build/SomfyController.ino.bin \ + 0x290000 SomfyController.littlefs.bin + + - name: Upload ${{ matrix.name }} + uses: actions/upload-release-asset@v1.0.2 + with: + upload_url: ${{ steps.get_release.outputs.upload_url }} + asset_name: ${{ matrix.name }} + asset_path: ./build/${{ matrix.obname }} + asset_content_type: application/octet-stream + diff --git a/.gitignore b/.gitignore index fed64a3..38d2b0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .theia/ debug_custom.json esp32.vsd +esp32s3.svd +debug.cfg +SomfyController.ino.esp32s3.bin diff --git a/ConfigSettings.cpp b/ConfigSettings.cpp index 06a28a9..84e7375 100644 --- a/ConfigSettings.cpp +++ b/ConfigSettings.cpp @@ -5,7 +5,7 @@ #include #include "ConfigSettings.h" #include "Utils.h" - +#include "esp_chip_info.h" Preferences pref; @@ -134,6 +134,35 @@ double BaseSettings::parseValueDouble(JsonObject &obj, const char *prop, double } bool ConfigSettings::begin() { uint32_t chipId = 0; + esp_chip_info_t ci; + esp_chip_info(&ci); + switch(ci.model) { + case esp_chip_model_t::CHIP_ESP32: + strcpy(this->chipModel, ""); + break; + case esp_chip_model_t::CHIP_ESP32S3: + strcpy(this->chipModel, "s3"); + break; + case esp_chip_model_t::CHIP_ESP32S2: + strcpy(this->chipModel, "s2"); + break; + case esp_chip_model_t::CHIP_ESP32C3: + strcpy(this->chipModel, "c3"); + break; +// case esp_chip_model_t::CHIP_ESP32C2: +// strcpy(this->chipModel, "c2"); +// break; +// case esp_chip_model_t::CHIP_ESP32C6: +// strcpy(this->chipModel, "c6"); +// break; + case esp_chip_model_t::CHIP_ESP32H2: + strcpy(this->chipModel, "h2"); + break; + default: + sprintf(this->chipModel, "UNK%d", static_cast(ci.model)); + break; + } + Serial.printf("Chip Model ESP32-%s\n", this->chipModel); this->fwVersion.parse(FW_VERSION); uint64_t mac = ESP.getEfuseMac(); for(int i=0; i<17; i=i+8) { @@ -198,6 +227,7 @@ bool ConfigSettings::toJSON(JsonObject &obj) { obj["ssdpBroadcast"] = this->ssdpBroadcast; obj["hostname"] = this->hostname; obj["connType"] = static_cast(this->connType); + obj["chipModel"] = this->chipModel; return true; } bool ConfigSettings::requiresAuth() { return this->Security.type != security_types::None; } diff --git a/ConfigSettings.h b/ConfigSettings.h index ead14cc..35a85f0 100644 --- a/ConfigSettings.h +++ b/ConfigSettings.h @@ -155,6 +155,7 @@ class ConfigSettings: BaseSettings { public: char serverId[10] = ""; char hostname[32] = "ESPSomfyRTS"; + char chipModel[10] = "ESP32"; conn_types connType = conn_types::unset; appver_t fwVersion; appver_t appVersion; diff --git a/GitOTA.cpp b/GitOTA.cpp index d812e00..73d66fb 100644 --- a/GitOTA.cpp +++ b/GitOTA.cpp @@ -18,7 +18,7 @@ extern Web webServer; #define MAX_BUFF_SIZE 4096 -void GitRelease::setProperty(const char *key, const char *val) { +void GitRelease::setReleaseProperty(const char *key, const char *val) { if(strcmp(key, "id") == 0) this->id = atol(val); else if(strcmp(key, "draft") == 0) this->draft = toBoolean(val, false); else if(strcmp(key, "prerelease") == 0) this->preRelease = toBoolean(val, false); @@ -32,6 +32,36 @@ void GitRelease::setProperty(const char *key, const char *val) { //Serial.println(this->releaseDate); } } +void GitRelease::setAssetProperty(const char *key, const char *val) { + if(strcmp(key, "name") == 0) { + Serial.println(val); + if(strstr(val, "littlefs.bin")) this->hasFS = true; + else if(strstr(val, "ino.esp32.bin")) { + if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); + strcat(this->hwVersions, "32"); + } + else if(strstr(val, "ino.esp32s3.bin")) { + if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); + strcat(this->hwVersions, "s3"); + } + else if(strstr(val, "ino.esp32c3.bin")) { + if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); + strcat(this->hwVersions, "c3"); + } + else if(strstr(val, "ino.esp32c2.bin")) { + if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); + strcat(this->hwVersions, "c2"); + } + else if(strstr(val, "ino.esp32c6.bin")) { + if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); + strcat(this->hwVersions, "c6"); + } + else if(strstr(val, "ino.esp32h2.bin")) { + if(strlen(this->hwVersions)) strcat(this->hwVersions, ","); + strcat(this->hwVersions, "h2"); + } + } +} bool GitRelease::toJSON(JsonObject &obj) { Timestamp ts; obj["id"] = this->id; @@ -40,6 +70,8 @@ bool GitRelease::toJSON(JsonObject &obj) { obj["draft"] = this->draft; obj["preRelease"] = this->preRelease; obj["main"] = this->main; + obj["hasFS"] = this->hasFS; + obj["hwVersions"] = this->hwVersions; JsonObject ver = obj.createNestedObject("version"); this->version.toJSON(ver); return true; @@ -79,6 +111,7 @@ int16_t GitRepo::getReleases(uint8_t num) { bool inElem = false; bool inValue = false; bool awaitValue = false; + bool inAss = false; while(https.connected() && (len > 0 || len == -1) && ndx < count) { size_t size = stream->available(); if(size) { @@ -87,19 +120,32 @@ int16_t GitRepo::getReleases(uint8_t num) { if(len > 0) len -= c; // Now we should have some data. for(uint8_t i = 0; i < c; i++) { + // Read the buffer a byte at a time until we have a key value pair. char ch = static_cast(buff[i]); - if(ch == '[') arrTok++; - else if(ch == ']') arrTok--; + if(ch == '[') { + arrTok++; + if(arrTok == 2 && strcmp(jsonElem, "assets") == 0) { + inElem = inValue = awaitValue = false; + inAss = true; + Serial.printf("%s: %d\n", jsonElem, arrTok); + } + else if(arrTok < 2) inAss = false; + } + else if(ch == ']') { + arrTok--; + if(arrTok < 2) inAss = false; + } else if(ch == '{') { objTok++; - if(objTok != 1) inElem = inValue = awaitValue = false; + if(objTok != 1 && !inAss) inElem = inValue = awaitValue = false; } else if(ch == '}') { objTok--; if(objTok == 0) ndx++; } - else if(objTok == 1) { + else if(objTok == 1 || inAss) { // We only want data from the root object. + //if(inAss) Serial.print(ch); if(ch == '\"') { inQuote = !inQuote; if(inElem) { @@ -110,7 +156,10 @@ int16_t GitRepo::getReleases(uint8_t num) { inValue = false; inElem = false; awaitValue = false; - this->releases[ndx].setProperty(jsonElem, jsonValue); + if(inAss) + this->releases[ndx].setAssetProperty(jsonElem, jsonValue); + else + this->releases[ndx].setReleaseProperty(jsonElem, jsonValue); memset(jsonElem, 0x00, sizeof(jsonElem)); memset(jsonValue, 0x00, sizeof(jsonValue)); } @@ -130,7 +179,10 @@ int16_t GitRepo::getReleases(uint8_t num) { else if((!inQuote && ch == ',') || ch == '\r' || ch == '\n') { inElem = inValue = awaitValue = false; if(strlen(jsonElem) > 0) { - this->releases[ndx].setProperty(jsonElem, jsonValue); + if(inAss) + this->releases[ndx].setAssetProperty(jsonElem, jsonValue); + else + this->releases[ndx].setReleaseProperty(jsonElem, jsonValue); } memset(jsonElem, 0x00, sizeof(jsonElem)); memset(jsonValue, 0x00, sizeof(jsonValue)); diff --git a/GitOTA.h b/GitOTA.h index e5e20b8..bb1b104 100644 --- a/GitOTA.h +++ b/GitOTA.h @@ -19,13 +19,16 @@ class GitRelease { bool draft = false; bool preRelease = false; bool main = false; + bool hasFS = false; + char hwVersions[128] = ""; time_t releaseDate; char name[32] = ""; appver_t version; - void setProperty(const char *key, const char *val); + void setReleaseProperty(const char *key, const char *val); + void setAssetProperty(const char *key, const char *val); bool toJSON(JsonObject &obj); + }; - class GitRepo { public: int16_t getReleases(uint8_t num = GIT_MAX_RELEASES); diff --git a/Somfy.cpp b/Somfy.cpp index db0ea89..3d6fc7f 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -4270,7 +4270,7 @@ void transceiver_config_t::apply() { } else { - ELECHOUSE_cc1101.setSidle(); + if(this->radioInit) ELECHOUSE_cc1101.setSidle(); somfy.transceiver.disableReceive(); this->radioInit = false; } diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index da361f8..29c4d37 100644 Binary files a/SomfyController.ino.esp32.bin and b/SomfyController.ino.esp32.bin differ diff --git a/Web.cpp b/Web.cpp index c396c30..275a775 100644 --- a/Web.cpp +++ b/Web.cpp @@ -890,7 +890,7 @@ void Web::handleDownloadFirmware(WebServer &server) { } } if(rel) { - DynamicJsonDocument sdoc(512); + DynamicJsonDocument sdoc(1024); JsonObject sobj = sdoc.to(); rel->toJSON(sobj); serializeJson(sdoc, g_content); diff --git a/data/appversion b/data/appversion index 7e541ae..6b4d157 100644 --- a/data/appversion +++ b/data/appversion @@ -1 +1 @@ -2.2.2 \ No newline at end of file +2.2.3 \ No newline at end of file diff --git a/data/index.html b/data/index.html index d07c5ee..fad959d 100644 --- a/data/index.html +++ b/data/index.html @@ -111,6 +111,10 @@