├── .github ├── FUNDING.yml └── workflows │ ├── build-docker-image.yaml │ └── run-tests.yaml ├── .gitignore ├── .gitpod.Dockerfile ├── .gitpod.yml ├── .nvmrc ├── .vscode └── settings.json ├── ADVANCED.md ├── Dockerfile ├── FEATURES_DESC.md ├── LICENSE ├── README.md ├── TRANSLATION.md ├── __mocks__ ├── fs-extra.js └── simple-git │ └── promise.js ├── ansible ├── README.md ├── group_vars │ └── all │ │ └── vars.yaml ├── roles │ └── compile │ │ ├── files │ │ ├── esp32_c2 │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_c3 │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_c6 │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_generic │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_s2 │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_s3 │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_solo1 │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp32_webcam │ │ │ ├── platformio_override.ini │ │ │ └── user_config_override_minimal.h │ │ ├── esp8266_generic │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp8266_nodemcu4M │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ ├── esp8266_shelly │ │ │ ├── platformio_override.ini │ │ │ ├── user_config_override_minimal.h │ │ │ └── user_config_override_temphum.h │ │ └── esp8266_zigbee-bridge │ │ │ ├── platformio_override.ini │ │ │ └── user_config_override_minimal.h │ │ └── tasks │ │ └── main.yaml └── site.yaml ├── docs ├── images │ ├── brave-browserLang.png │ ├── chrome-browserLang.png │ ├── compile01.png │ ├── docker_advanced.png │ ├── edge-browserLang.png │ ├── firefox-browserLang.png │ ├── gitpod_advanced.png │ ├── gitpod_newtab.png │ ├── step01.png │ ├── step02.png │ ├── step03.png │ ├── step04.png │ └── step05.png └── logo │ ├── tasmocompiler-full.svg │ └── tasmocompiler-symbol.svg ├── jest.config.js ├── jestSetEnv.js ├── package-lock.json ├── package.json ├── public ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── flags │ ├── af.png │ ├── bg.png │ ├── br.png │ ├── cn.png │ ├── cz.png │ ├── de.png │ ├── es.png │ ├── fr.png │ ├── gb.png │ ├── gr.png │ ├── he.png │ ├── hu.png │ ├── it.png │ ├── ko.png │ ├── nl.png │ ├── pl.png │ ├── pt.png │ ├── ro.png │ ├── ru.png │ ├── se.png │ ├── sk.png │ ├── tr.png │ ├── tw.png │ ├── ua.png │ └── vn.png ├── img │ ├── github.svg │ ├── kofi.svg │ └── paypal.svg ├── index.html └── manifest.json ├── server ├── app.js ├── binaries │ └── tasmota-minimal.bin.gz ├── compile │ ├── __test__ │ │ └── compile.test.js │ └── compile.js ├── config │ └── config.js ├── git │ ├── __test__ │ │ └── git.test.js │ └── git.js ├── server.js ├── tests │ ├── server.offtest.js │ └── testSet.json └── utils │ ├── __mocks__ │ └── helpers.js │ └── helpers.js └── src ├── App.js ├── components ├── AppStepper │ ├── BackButton.js │ ├── ClearButton.js │ ├── CompileButton.js │ ├── CustomParametersStep.js │ ├── FeaturesStep │ │ ├── AvailableBoards.js │ │ ├── AvailableFeatures.js │ │ ├── FeaturesSelector.js │ │ └── FeaturesStep.js │ ├── NextButton.js │ ├── SourceStep.js │ ├── TextFieldComponent.js │ ├── VersionStep │ │ ├── Variables │ │ │ └── Languages.js │ │ ├── VersionSelector.js │ │ └── VersionStep.js │ └── WifiStep.js ├── DownloadLinks │ └── DownloadLinks.js ├── MessageBox │ └── MessageBox.js └── TopAppBar │ ├── TopAppBar.js │ └── __test__ │ └── TopAppBar.test.js ├── index.css ├── index.js ├── locales ├── __test__ │ └── locale.test.js ├── cs.json ├── de.json ├── en.json ├── es.json ├── fr.json ├── hu.json ├── it.json ├── languages.js ├── nl.json ├── pl.json └── pt.json ├── logo.svg ├── serviceWorker.js └── styles └── styles.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | ko_fi: benzino77 4 | custom: ['https://paypal.me/tasmocompiler'] 5 | github: ['benzino77'] 6 | -------------------------------------------------------------------------------- /.github/workflows/build-docker-image.yaml: -------------------------------------------------------------------------------- 1 | name: Build Docker Image 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | branch: 6 | description: 'Branch to build from' 7 | required: true 8 | type: choice 9 | default: 'master' 10 | options: 11 | - 'master' 12 | - 'development' 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v4 21 | with: 22 | ref: ${{ github.event.inputs.branch }} 23 | 24 | - name: Set up QEMU 25 | uses: docker/setup-qemu-action@v3 26 | 27 | - name: Set up Docker Buildx 28 | uses: docker/setup-buildx-action@v3 29 | 30 | - name: Load Buildx 31 | run: docker buildx create --name mybuilder --use 32 | if: runner.os == 'Linux' 33 | 34 | - name: Login to Docker Hub 35 | uses: docker/login-action@v3 36 | with: 37 | username: ${{ secrets.DOCKER_USERNAME }} 38 | password: ${{ secrets.DOCKER_ACCESS_TOKEN }} 39 | 40 | - name: Log into registry ghcr.io 41 | uses: docker/login-action@v3 42 | with: 43 | registry: ghcr.io 44 | username: ${{ github.actor }} 45 | password: ${{ secrets.GITHUB_TOKEN }} 46 | 47 | - name: Extract version from package.json 48 | if: ${{ github.event.inputs.branch == 'master' }} 49 | run: echo "DOCKER_TAG=$(jq -r '.version' package.json)" >> $GITHUB_ENV 50 | 51 | - name: Extract Docker metadata (master) 52 | if: ${{ github.event.inputs.branch == 'master' }} 53 | id: meta_m 54 | uses: docker/metadata-action@v5 55 | with: 56 | tags: | 57 | type=raw,value=latest 58 | type=raw,value=${{ env.DOCKER_TAG }} 59 | images: | 60 | ${{ github.repository }} 61 | ghcr.io/${{ github.repository }} 62 | 63 | - name: Extract Docker metadata (development) 64 | if: ${{ github.event.inputs.branch == 'development' }} 65 | id: meta_d 66 | uses: docker/metadata-action@v5 67 | with: 68 | tags: | 69 | type=raw,value=development 70 | images: | 71 | ${{ github.repository }} 72 | ghcr.io/${{ github.repository }} 73 | 74 | - name: Build and push production Docker image (master) 75 | if: ${{ github.event.inputs.branch == 'master' }} 76 | uses: docker/build-push-action@v5 77 | with: 78 | context: . 79 | platforms: linux/amd64,linux/arm64,linux/arm/v7 80 | push: true 81 | tags: ${{ steps.meta_m.outputs.tags }} 82 | labels: ${{ steps.meta_m.outputs.labels }} 83 | 84 | - name: Build and push production Docker image (development) 85 | if: ${{ github.event.inputs.branch == 'development' }} 86 | uses: docker/build-push-action@v5 87 | with: 88 | context: . 89 | platforms: linux/amd64,linux/arm64,linux/arm/v7 90 | push: true 91 | tags: ${{ steps.meta_d.outputs.tags }} 92 | labels: ${{ steps.meta_d.outputs.labels }} 93 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yaml: -------------------------------------------------------------------------------- 1 | name: Run compile tests 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '0 7 * * 0' 6 | 7 | jobs: 8 | run-tests: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v4 14 | with: 15 | ref: development 16 | 17 | - name: Clone Tasmota 18 | uses: actions/checkout@v4 19 | with: 20 | repository: arendst/Tasmota 21 | path: Tasmota 22 | 23 | - name: Install python packages 24 | run: | 25 | python3 -m venv .venv 26 | source .venv/bin/activate 27 | pip install platformio ansible 28 | 29 | - name: Run tests 30 | run: | 31 | source .venv/bin/activate 32 | ansible-playbook ansible/site.yaml --extra-vars "tasmota_dir=${GITHUB_WORKSPACE}/Tasmota" 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | /playground 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | /.venv 22 | /playground 23 | upload-firmware.sh 24 | qemu-arm-static 25 | qemu-aarch64-static 26 | 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | 31 | .local2docker.cmd 32 | -------------------------------------------------------------------------------- /.gitpod.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-bookworm-slim 2 | RUN apt-get update && apt-get install -y python3 python3-pip git 3 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.Dockerfile 3 | tasks: 4 | - init: npm ci 5 | command: npm run build && pip3 install --break-system-packages platformio && PATH=$PATH:$HOME/.local/bin && node server/app.js 6 | ports: 7 | - port: 3000 8 | onOpen: open-browser 9 | visibility: public 10 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v16 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.eol": "\n" 3 | } -------------------------------------------------------------------------------- /ADVANCED.md: -------------------------------------------------------------------------------- 1 | #### Advanced usage 2 | 3 | If you want to get access to files created before or after compilation form the console you are able to do this. Source code of Tasmota is located in `/tmp/Tasmota` 4 | 5 | ##### Gitpod 6 | 7 | 1. press `ctrl+c` at the gitpod console 8 | 2. change directory to `/tmp/Tasmota` by typing `cd /tmp/Tasmota` 9 | 3. Now you can check from terminal what for example is the content of `platformio.ini` or `user_config_override.h` files. 10 | 4. type this command to see last 10 lines of `user_config_override.h` file: `tail sonoff/user_config_override.h` 11 | 5. start TasmoCompiler again: `cd /workspace/tasmocompiler` and `node server/app.js` 12 | 13 | ![Gitpod Advanced](./docs/images/gitpod_advanced.png) 14 | 15 | ##### Docker 16 | 17 | If you have TasmoCompiler docker running (started by `docker run --rm --name tasmocompiler -p 3000:3000 benzino77/tasmocompiler`) open a new terminal tab/window and: 18 | 19 | 1. run this command to _get into_ container: `docker exec -it tasmocompiler /bin/bash` 20 | 2. change directory to `/tmp/Tasmota` by typing `cd /tmp/Tasmota` 21 | 3. Now you can check from terminal what for example is the content of `platformio.ini` or `user_config_override.h` files. 22 | 4. type this command to see last 10 lines of `user_config_override.h` file: `tail sonoff/user_config_override.h` 23 | 5. exit docker container shell by pressing `ctrl+d` 24 | 25 | ![Docker Advanced](./docs/images/docker_advanced.png) 26 | 27 | #### Compile someone fork of Tasmota code 28 | 29 | If you want to use someone fork of Tasmota project, and want to use TasmoCompiler to compile it, it is possible (at least with this one used in the example). The steps below, are based on [Stefan Bode](https://github.com/stefanbode/Sonoff-Tasmota) fork of Tasmota code. 30 | 31 | ##### Gitpod 32 | 33 | 1. start your gitpod workspace 34 | 2. close all tabs/windows with TasmoCompiler GUI (it is important, because the problem with WebSockets can arise) 35 | 3. in the gitpod console (bottom part of the view, where the information _Server started on port 3000_ is displayed) hit ctrl+c 36 | 4. type: `cd /tmp` 37 | 5. type: `rm -rf Tasmota` 38 | 6. type: `git clone https://github.com/stefanbode/Sonoff-Tasmota.git Tasmota` <- this is importatnt to clone to `Tasmota` folder 39 | 7. type: `cd Tasmota` 40 | 8. type: `git checkout -b development` 41 | 9. type: `cd /workspace/tasmocompiler` 42 | 10. type: `node server/app.js` 43 | 11. open TasmoCompiler GUI by clicking "Open Browser" (if it didn't open automatically) 44 | 45 | In step **8** the `development` branch is created from current master of [Stefan Bode](https://github.com/stefanbode/Sonoff-Tasmota) fork. You can also create `develepment` branch from any commit from the past by typing: 46 | 47 | `git checkout -b development ` 48 | 49 | _You can also copy and paste this oneliner:_ `cd /tmp && rm -rf Tasmota && git clone https://github.com/stefanbode/Sonoff-Tasmota.git Tasmota && cd Tasmota && git checkout -b development && cd /workspace/tasmocompiler && node server/app.js` 50 | 51 | ##### Docker 52 | 53 | 1. close all tabs/windows with TasmoCompiler GUI (it is important, because the problem with WebSockets can arise) 54 | 2. run `docker exec -it tasmocompiler /bin/bash` on machine where your container is running 55 | 3. type: `cd /tmp` 56 | 4. type: `rm -rf Tasmota` 57 | 5. type: `git clone https://github.com/stefanbode/Sonoff-Tasmota.git Tasmota` <- this is important to clone to `Tasmota` folder 58 | 6. type: `cd Tasmota` 59 | 7. type: `git checkout -b development` 60 | 8. exit docker container shell by pressing `ctrl+d` 61 | 9. point the browser to the address and port of your docker host 62 | 63 | _You can also copy and paste this oneliner:_ `cd /tmp && rm -rf Tasmota && git clone https://github.com/stefanbode/Sonoff-Tasmota.git Tasmota && cd Tasmota && git checkout -b development` 64 | 65 | ##### Notes 66 | 67 | At the _Select version and compile_ step, you will be able to choose only `development` version of Tasmota. If you want to see other versions, you have to create git tags (with names compatibile with original Tasmota tags) from commits in [Stefan Bode](https://github.com/stefanbode/) git repo. TasmoCompiler will only look at tags which names starts with `v6*, v7*` or `v8*`. 68 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-bookworm-slim 2 | LABEL maintainer="Piotr Antczak " 3 | 4 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y python3 git python3-setuptools && \ 5 | DEBIAN_FRONTEND=noninteractive apt-get install -y python3-pip && pip3 install --break-system-packages platformio && \ 6 | DEBIAN_FRONTEND=noninteractive apt-get clean && \ 7 | npm install -g nodemon && \ 8 | cd /tmp && git clone https://github.com/arendst/Tasmota.git && \ 9 | rm -rf /var/lib/apt/lists/* 10 | ADD public /tasmocompiler/public/ 11 | ADD server /tasmocompiler/server/ 12 | ADD src /tasmocompiler/src/ 13 | ADD package.json package-lock.json /tasmocompiler/ 14 | RUN cd /tasmocompiler && npm ci && npm run build 15 | ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 16 | WORKDIR /tasmocompiler 17 | ENTRYPOINT ["nodemon", "server/app.js"] 18 | EXPOSE 3000/tcp 19 | -------------------------------------------------------------------------------- /FEATURES_DESC.md: -------------------------------------------------------------------------------- 1 | #### This file includes description of sensors included in features group one could select. 2 | 3 | > [!Note] 4 | > 5 | > All of the features includes by default `USE_I2C` and `USE_SPI` 6 | 7 | | Energy sensors | Air sensors | Temperature/Humidity/Pressure Sensors | Displays | LVGL | Distance sensors | Light sensors | 8 | | ------------------ | ------------------ | ------------------------------------- | ------------------------ | --------------------------------- | ---------------- | -------------- | 9 | | `USE_HLW8012` | `USE_MHZ19` | `USE_SONOFF_SC` | `USE_DISPLAY_TM1637` | `USE_LVGL` | `USE_SR04` | `USE_BH1750` | 10 | | `USE_CSE7766` | `USE_SENSEAIR` | `USE_DS18x20` | `USE_DISPLAY_MAX7219` | `USE_MPU_ACCEL` | `USE_VL53L0X` | `USE_VEML6070` | 11 | | `USE_PZEM004T` | `USE_PMS5003` | `USE_DHT` | `USE_DISPLAY_MODES1TO5` | `USE_RTC_CHIPS` | `USE_HRXL` | `USE_TSL2561` | 12 | | `USE_MCP39F501` | `USE_MGS` | `USE_SHT` | `USE_DISPLAY_LCD ` | `USE_BM8563` | `USE_DYP` | `USE_SI1145` | 13 | | `USE_PZEM_AC` | `USE_NOVA_SDS` | `USE_HTU` | `USE_DISPLAY_MATRIX ` | `USE_XPT2046` | `USE_VL53L1X` | `USE_APDS9960` | 14 | | `USE_PZEM_DC` | `USE_SGP30` | `USE_BMP` | `USE_DISPLAY_TM1650 ` | `USE_FT5206` | `USE_VEML6075` | 15 | | `USE_ADE7953` | `USE_CCS811` | `USE_SHT3X` | `USE_DISPLAY_EPAPER_29 ` | `USE_GT911` | `USE_MAX44009` | 16 | | `USE_SDM120` | `USE_SCD30` | `USE_LM75AD` | `USE_DISPLAY_EPAPER_42` | `USE_CST816S` | `USE_TSL2591` | 17 | | `USE_DDS2382` | `USE_SPS30` | `USE_APDS9960` | `USE_DISPLAY_RA8876` | `USE_DISPLAY_LVGL_ONLY` | `USE_AS3935` | 18 | | `USE_SDM630` | `USE_HPMA` | `USE_AZ7798` | `USE_DISPLAY_SEVENSEG` | `USE_ENHANCED_GUI_WIFI_SCAN` | `USE_VEML7700` | 19 | | `USE_DDSU666` | `USE_IAQ` | `USE_MAX31855` | `USE_DISPLAY` | `ROTARY_V1` | | 20 | | `USE_SOLAX_X1` | `USE_T67XX` | `USE_MLX90614` | `USE_UNIVERSAL_DISPLAY` | `USE_BUZZER` | | 21 | | `USE_LE01MR` | `USE_VINDRIKTNING` | `USE_MAX31865` | `USE_UNIVERSAL_TOUCH` | `USE_LIGHT_PALETTE` | | 22 | | `USE_BL09XX` | `USE_SCD40` | `USE_HIH6` | `USE_TASMOTA_DISCOVERY` | `USE_SHELLY_PRO` | | 23 | | `USE_TELEINFO` | `USE_HM330X` | `USE_DHT12` | | `USE_SERIAL_BRIDGE` | | 24 | | `USE_IEM3000` | `USE_SEN5X` | `USE_DS1624` | | `USE_DISPLAY` | | 25 | | `USE_WE517` | `USE_SGP4X` | `USE_AHT1x` | | `USE_UNIVERSAL_DISPLAY` | | 26 | | `USE_ENERGY_DUMMY` | | `USE_HDC1080` | | `USE_UNIVERSAL_TOUCH` | | 27 | | `USE_IEM3000` | | `USE_MCP9808` | | `USE_TASMOTA_DISCOVERY` | | 28 | | | | `USE_LMT01` | | `SET_ESP32_STACK_SIZE` - editable | | 29 | | | | `USE_AM2320` | | | | 30 | | | | `USE_BME68X` | | | | 31 | 32 | | Alexa | Rules | Bluetooth | IO port expander | SD card/LittleFS | ModBus Bridge | Shutters and Blinds | 33 | | -------------------- | ---------------------- | --------------- | ---------------------------- | ---------------- | ---------------------- | ----------------------------------------- | 34 | | `USE_EMULATION` | `USE_RULES` | `USE_BLE_ESP32` | `USE_MCP230xx` | `USE_UFILESYS` | `USE_MODBUSBRIDGE` | `USE_SHUTTER` | 35 | | `USE_EMULATION_HUE` | `USE_EXPRESSION` | `USE_MI_ESP32` | `USE_MCP230xx_OUTPUT` | `USE_SDCARD` | `USE_MODBUSBRIDGE_TCP` | `SHUTTER_RELAY_OPERATION_TIME` - editable | 36 | | `USE_EMULATION_WEMO` | `SUPPORT_IF_STATEMENT` | | `USE_MCP230xx_DISPLAYOUTPUT` | `GUI_TRASH_FILE` | | `MOTOR_STOP_TIME` - editable | 37 | | | | | | `GUI_EDIT_FILE` | | `SHUTTER_CLEAR_PWM_ONSTOP` - editable | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 benzino77 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /TRANSLATION.md: -------------------------------------------------------------------------------- 1 | #### How to prepare TasmoCompiler web interface translation 2 | 3 | 1. copy `src/locales/en.json` file to `.json` (for example create `it.json` file to create Italian translation) 4 | 2. translate english text to your language: 5 | 6 | ##### before: 7 | 8 | ```javascript 9 | ... 10 | "stepWifiConfDesc": "Enter SSID and password for your WiFi network", 11 | ... 12 | ``` 13 | 14 | ##### after: 15 | 16 | ```javascript 17 | ... 18 | "stepWifiConfDesc": "YOUR TRANSLATION GOES HERE", 19 | ... 20 | ``` 21 | 22 | 3. edit `src/locales/language.js` file and add your language 23 | 24 | ##### before: 25 | 26 | ```javascript 27 | import localeEN from '../locales/en.json'; 28 | import localeES from '../locales/es.json'; 29 | import localePL from '../locales/pl.json'; 30 | 31 | const allMessages = { 32 | de: { 33 | source: localeDE, 34 | nativeName: 'Deutsch', 35 | flag: 'flags/de.png', 36 | browserLang: ['de', 'de-de'], 37 | }, 38 | en: { 39 | source: localeEN, 40 | nativeName: 'English', 41 | flag: 'flags/gb.png', 42 | browserLang: ['en', 'en-gb', 'en-us'], 43 | }, 44 | es: { 45 | source: localeES, 46 | nativeName: 'Español', 47 | flag: 'flags/es.png', 48 | browserLang: ['es', 'es-es'], 49 | }, 50 | }; 51 | ``` 52 | 53 | ##### after: 54 | 55 | ```javascript 56 | import localeEN from '../locales/en.json'; 57 | import localeES from '../locales/es.json'; 58 | import localePL from '../locales/pl.json'; 59 | import localeIT from '../locales/it.json'; // add this line 60 | 61 | const allMessages = { 62 | de: { 63 | source: localeDE, 64 | nativeName: 'Deutsch', 65 | flag: 'flags/de.png', 66 | browserLang: ['de', 'de-de'], 67 | }, 68 | en: { 69 | source: localeEN, 70 | nativeName: 'English', 71 | flag: 'flags/gb.png', 72 | browserLang: ['en', 'en-gb', 'en-us'], 73 | }, 74 | es: { 75 | source: localeES, 76 | nativeName: 'Español', 77 | flag: 'flags/es.png', 78 | browserLang: ['es', 'es-es'], 79 | }, 80 | // add this property 81 | it: { 82 | source: localeIT, 83 | nativeName: 'Italiano', 84 | flag: 'flags/it.png', 85 | browserLang: ['it'], 86 | }, 87 | }; 88 | ``` 89 | 90 | #### How to find values to be added to `browserLang` list? 91 | 92 | Open Firefex, Chrome, Edge, Brave, Opera, any other browser you have installed and press `F12` key. It will open `developmer tools`. Choose `console` and type: `navigator.language`. You should type this in the console of as many browsers as you can - some browsers have different language code than others. Remeber to add a value to `browserLang` list in lowercase. 93 | 94 | ##### Firefox 95 | 96 | ![Firefox](./docs/images/firefox-browserLang.png) 97 | 98 | ##### Chrome 99 | 100 | ![Chrome](./docs/images/chrome-browserLang.png) 101 | 102 | ##### Edge 103 | 104 | ![Edge](./docs/images/edge-browserLang.png) 105 | 106 | ##### Brave 107 | 108 | ![Brave](./docs/images/brave-browserLang.png) 109 | 110 | #### Flag 111 | 112 | The flag should be placed in `public/flags` folder. It should be 24px wide and PNG format. 113 | -------------------------------------------------------------------------------- /__mocks__/fs-extra.js: -------------------------------------------------------------------------------- 1 | const fs = jest.genMockFromModule('fs-extra'); 2 | 3 | let fsStatReject = true; 4 | let fsRemoveReject = true; 5 | let fsWriteFileReject = false; 6 | let retFsPathExistsSync = false; 7 | 8 | function __setFsStatReject(reject) { 9 | fsStatReject = reject; 10 | } 11 | 12 | function __setFsRemoveReject(reject) { 13 | fsRemoveReject = reject; 14 | } 15 | 16 | function __setFsWriteFileReject(reject) { 17 | fsWriteFileReject = reject; 18 | } 19 | 20 | function __setRetFsPathExistsSync(value) { 21 | retFsPathExistsSync = value; 22 | } 23 | 24 | fs.__setFsStatReject = __setFsStatReject; 25 | fs.__setFsRemoveReject = __setFsRemoveReject; 26 | fs.__setFsWriteFileReject = __setFsWriteFileReject; 27 | fs.__setRetFsPathExistsSync = __setRetFsPathExistsSync; 28 | 29 | fs.stat = jest.fn((path) => { 30 | if (fsStatReject) { 31 | return Promise.reject(); 32 | } 33 | return Promise.resolve(); 34 | }); 35 | 36 | fs.remove = jest.fn((path) => { 37 | if (fsRemoveReject) return Promise.reject(); 38 | return Promise.resolve(); 39 | }); 40 | 41 | fs.pathExistsSync = jest.fn((path) => { 42 | return retFsPathExistsSync; 43 | }); 44 | 45 | fs.writeFile = jest.fn((path, data) => { 46 | if (fsWriteFileReject) return Promise.reject(); 47 | return Promise.resolve(); 48 | }); 49 | 50 | module.exports = fs; 51 | -------------------------------------------------------------------------------- /__mocks__/simple-git/promise.js: -------------------------------------------------------------------------------- 1 | let gitIsRepoRet = true; 2 | let gitTagsReject = true; 3 | let gitCloneReject = true; 4 | let gitPullReject = true; 5 | let gitResetReject = true; 6 | let gitCleanReject = true; 7 | let gitBranchLocalReject = true; 8 | let gitCheckoutBranchReject = true; 9 | let gitCheckoutReject = true; 10 | let retTags = []; 11 | let retLocalBranches = {}; 12 | 13 | function __setGitIsRepoRet(value) { 14 | gitIsRepoRet = value; 15 | } 16 | 17 | function __setRepoTags(tags) { 18 | retTags = tags; 19 | } 20 | 21 | function __setGitTagsReject(reject) { 22 | gitTagsReject = reject; 23 | } 24 | 25 | function __setGitCloneReject(reject) { 26 | gitCloneReject = reject; 27 | } 28 | 29 | function __setGitPullReject(reject) { 30 | gitPullReject = reject; 31 | } 32 | 33 | function __setGitResetReject(reject) { 34 | gitResetReject = reject; 35 | } 36 | 37 | function __setGitCleanReject(reject) { 38 | gitCleanReject = reject; 39 | } 40 | 41 | function __setGitBranchLocalReject(reject) { 42 | gitBranchLocalReject = reject; 43 | } 44 | 45 | function __setLocalBranches(branches) { 46 | retLocalBranches = branches; 47 | } 48 | 49 | function __setGitCheckoutBranchReject(reject) { 50 | gitCheckoutBranchReject = reject; 51 | } 52 | 53 | function __setGitCheckoutReject(reject) { 54 | gitCheckoutReject = reject; 55 | } 56 | 57 | const gitObject = { 58 | checkIsRepo: jest.fn(() => Promise.resolve(gitIsRepoRet)), 59 | tags: jest.fn(() => { 60 | if (gitTagsReject) return Promise.reject(new Error('Test')); 61 | return Promise.resolve({ all: retTags }); 62 | }), 63 | clone: jest.fn((source, dest) => { 64 | if (gitCloneReject) return Promise.reject(new Error('Test')); 65 | 66 | return Promise.resolve(); 67 | }), 68 | pull: jest.fn(() => { 69 | if (gitPullReject) return Promise.reject(new Error('Test')); 70 | return Promise.resolve(); 71 | }), 72 | reset: jest.fn((type) => { 73 | if (gitResetReject) return Promise.reject(new Error('Test')); 74 | return Promise.resolve(); 75 | }), 76 | clean: jest.fn((opts) => { 77 | if (gitCleanReject) return Promise.reject(new Error('Test')); 78 | return Promise.resolve(); 79 | }), 80 | branchLocal: jest.fn(() => { 81 | if (gitBranchLocalReject) return Promise.reject(new Error('Test')); 82 | return Promise.resolve({ branches: retLocalBranches }); 83 | }), 84 | checkoutBranch: jest.fn((remote, local) => { 85 | if (gitCheckoutBranchReject) return Promise.reject(new Error('Test')); 86 | return Promise.resolve(); 87 | }), 88 | checkout: jest.fn(() => { 89 | if (gitCheckoutReject) return Promise.reject(new Error('Test')); 90 | return Promise.resolve(); 91 | }), 92 | }; 93 | 94 | const git = jest.fn((path) => { 95 | return gitObject; 96 | }); 97 | 98 | git.__setGitIsRepoRet = __setGitIsRepoRet; 99 | git.__setRepoTags = __setRepoTags; 100 | git.__setGitTagsReject = __setGitTagsReject; 101 | git.__setGitCloneReject = __setGitCloneReject; 102 | git.__setGitPullReject = __setGitPullReject; 103 | git.__setGitResetReject = __setGitResetReject; 104 | git.__setGitCleanReject = __setGitCleanReject; 105 | git.__setGitBranchLocalReject = __setGitBranchLocalReject; 106 | git.__setLocalBranches = __setLocalBranches; 107 | git.__setGitCheckoutBranchReject = __setGitCheckoutBranchReject; 108 | git.__setGitCheckoutReject = __setGitCheckoutReject; 109 | 110 | module.exports = git; 111 | -------------------------------------------------------------------------------- /ansible/README.md: -------------------------------------------------------------------------------- 1 | # Automatic compilation tests 2 | 3 | ## Description 4 | 5 | Here are the automation scripts, to check if TasmoCompiler is still able to compile Tasmota. It is using `user_config_override.h` and `platformio_override.ini` files generated by TasmoCompiler. Then it runs compilation for every supported/defined board. 6 | 7 | ## Requirements 8 | 9 | What is needed: 10 | 11 | - platformio is installed and is available in the `PATH` 12 | - ansible is installed and available in the `PATH` 13 | - source code of Tasmota is available at the location defined in `tasmota_dir` ansible variable (`group_vars/all/vars.yaml`) 14 | 15 | The easiest way to prepare testing environemnt is to use `python` virtualenv module: 16 | 17 | ```sh 18 | apt install python3-venv 19 | cd tasmocompiler 20 | python3 -m venv .venv # create new python virtualenv 21 | source .venv/bin/activate # active virtualenv 22 | pip install platformio ansible # install platformio and ansible in virtualenv 23 | cd ansible 24 | ansible-playbook site.yaml # run tests 25 | ``` 26 | 27 | ## Adding new board 28 | 29 | To add new board one need to add required files to `roles/compile/files/` and then add this board to test suite in `site.yaml` 30 | -------------------------------------------------------------------------------- /ansible/group_vars/all/vars.yaml: -------------------------------------------------------------------------------- 1 | tasmota_dir: /tmp/Tasmota 2 | tasmota_branch: development 3 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_c2/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32c2 3 | 4 | [env:tasmota32c2] 5 | extends = env:tasmota32_base 6 | board = esp32c2 7 | build_unflags = ${env:tasmota32_base.build_unflags} -mno-target-align 8 | build_flags = ${env:tasmota32_base.build_flags} 9 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_c3/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32c3 3 | 4 | [env:tasmota32c3] 5 | extends = env:tasmota32_base 6 | board = esp32c3 7 | build_unflags = ${env:tasmota32_base.build_unflags} -mno-target-align 8 | build_flags = ${env:tasmota32_base.build_flags} 9 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_c6/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32c6 3 | 4 | [env:tasmota32c6] 5 | extends = env:tasmota32_base 6 | board = esp32c6 7 | build_unflags = ${env:tasmota32_base.build_unflags} -mno-target-align 8 | build_flags = ${env:tasmota32_base.build_flags} -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_c6/user_config_override_minimal.h: -------------------------------------------------------------------------------- 1 | #ifndef _USER_CONFIG_OVERRIDE_H_ 2 | #define _USER_CONFIG_OVERRIDE_H_ 3 | 4 | #ifdef CODE_IMAGE_STR 5 | #undef CODE_IMAGE_STR 6 | #endif 7 | #define CODE_IMAGE_STR "TasmoCompiler-esp32c6" 8 | 9 | #ifdef USE_ENERGY_SENSOR 10 | #undef USE_ENERGY_SENSOR 11 | #endif 12 | 13 | #ifdef USE_MHZ19 14 | #undef USE_MHZ19 15 | #endif 16 | 17 | #ifdef USE_SENSEAIR 18 | #undef USE_SENSEAIR 19 | #endif 20 | 21 | #ifdef USE_PMS5003 22 | #undef USE_PMS5003 23 | #endif 24 | 25 | #ifdef USE_MGS 26 | #undef USE_MGS 27 | #endif 28 | 29 | #ifdef USE_NOVA_SDS 30 | #undef USE_NOVA_SDS 31 | #endif 32 | 33 | #ifdef USE_SGP30 34 | #undef USE_SGP30 35 | #endif 36 | 37 | #ifdef USE_CCS811 38 | #undef USE_CCS811 39 | #endif 40 | 41 | #ifdef USE_SCD30 42 | #undef USE_SCD30 43 | #endif 44 | 45 | #ifdef USE_SPS30 46 | #undef USE_SPS30 47 | #endif 48 | 49 | #ifdef USE_SGP4X 50 | #undef USE_SGP4X 51 | #endif 52 | 53 | #ifdef USE_SEN5X 54 | #undef USE_SEN5X 55 | #endif 56 | 57 | #ifdef USE_HPMA 58 | #undef USE_HPMA 59 | #endif 60 | 61 | #ifdef USE_IAQ 62 | #undef USE_IAQ 63 | #endif 64 | 65 | #ifdef USE_T67XX 66 | #undef USE_T67XX 67 | #endif 68 | 69 | #ifdef USE_VINDRIKTNING 70 | #undef USE_VINDRIKTNING 71 | #endif 72 | 73 | #ifdef USE_SCD40 74 | #undef USE_SCD40 75 | #endif 76 | 77 | #ifdef USE_HM330X 78 | #undef USE_HM330X 79 | #endif 80 | 81 | #ifdef USE_EMULATION 82 | #undef USE_EMULATION 83 | #endif 84 | 85 | #ifdef USE_EMULATION_HUE 86 | #undef USE_EMULATION_HUE 87 | #endif 88 | 89 | #ifdef USE_EMULATION_WEMO 90 | #undef USE_EMULATION_WEMO 91 | #endif 92 | 93 | #ifdef USE_TASMOTA_CLIENT 94 | #undef USE_TASMOTA_CLIENT 95 | #endif 96 | 97 | #ifdef USE_BERRY 98 | #undef USE_BERRY 99 | #endif 100 | #define USE_BERRY 101 | 102 | #ifdef USE_BERRY_PSRAM 103 | #undef USE_BERRY_PSRAM 104 | #endif 105 | #define USE_BERRY_PSRAM 106 | 107 | #ifdef USE_ADC_VCC 108 | #undef USE_ADC_VCC 109 | #endif 110 | 111 | #ifdef USE_SR04 112 | #undef USE_SR04 113 | #endif 114 | 115 | #ifdef USE_VL53L0X 116 | #undef USE_VL53L0X 117 | #endif 118 | 119 | #ifdef USE_HRXL 120 | #undef USE_HRXL 121 | #endif 122 | 123 | #ifdef USE_DYP 124 | #undef USE_DYP 125 | #endif 126 | 127 | #ifdef USE_VL53L1X 128 | #undef USE_VL53L1X 129 | #endif 130 | 131 | #ifdef USE_DOMOTICZ 132 | #undef USE_DOMOTICZ 133 | #endif 134 | 135 | #ifdef USE_HLW8012 136 | #undef USE_HLW8012 137 | #endif 138 | 139 | #ifdef USE_CSE7766 140 | #undef USE_CSE7766 141 | #endif 142 | 143 | #ifdef USE_PZEM004T 144 | #undef USE_PZEM004T 145 | #endif 146 | 147 | #ifdef USE_MCP39F501 148 | #undef USE_MCP39F501 149 | #endif 150 | 151 | #ifdef USE_PZEM_AC 152 | #undef USE_PZEM_AC 153 | #endif 154 | 155 | #ifdef USE_PZEM_DC 156 | #undef USE_PZEM_DC 157 | #endif 158 | 159 | #ifdef USE_ADE7953 160 | #undef USE_ADE7953 161 | #endif 162 | 163 | #ifdef USE_SDM120 164 | #undef USE_SDM120 165 | #endif 166 | 167 | #ifdef USE_DDS2382 168 | #undef USE_DDS2382 169 | #endif 170 | 171 | #ifdef USE_SDM630 172 | #undef USE_SDM630 173 | #endif 174 | 175 | #ifdef USE_DDSU666 176 | #undef USE_DDSU666 177 | #endif 178 | 179 | #ifdef USE_SOLAX_X1 180 | #undef USE_SOLAX_X1 181 | #endif 182 | 183 | #ifdef USE_LE01MR 184 | #undef USE_LE01MR 185 | #endif 186 | 187 | #ifdef USE_BL09XX 188 | #undef USE_BL09XX 189 | #endif 190 | 191 | #ifdef USE_TELEINFO 192 | #undef USE_TELEINFO 193 | #endif 194 | 195 | #ifdef USE_IEM3000 196 | #undef USE_IEM3000 197 | #endif 198 | 199 | #ifdef USE_WE517 200 | #undef USE_WE517 201 | #endif 202 | 203 | #ifdef USE_ENERGY_DUMMY 204 | #undef USE_ENERGY_DUMMY 205 | #endif 206 | 207 | #ifdef USE_HOME_ASSISTANT 208 | #undef USE_HOME_ASSISTANT 209 | #endif 210 | 211 | #ifdef USE_I2C 212 | #undef USE_I2C 213 | #endif 214 | 215 | #ifdef USE_MCP230xx 216 | #undef USE_MCP230xx 217 | #endif 218 | 219 | #ifdef USE_MCP230xx_OUTPUT 220 | #undef USE_MCP230xx_OUTPUT 221 | #endif 222 | 223 | #ifdef USE_MCP230xx_DISPLAYOUTPUT 224 | #undef USE_MCP230xx_DISPLAYOUTPUT 225 | #endif 226 | 227 | #ifdef USE_IR_REMOTE 228 | #undef USE_IR_REMOTE 229 | #endif 230 | 231 | #ifdef USE_IR_REMOTE_FULL 232 | #undef USE_IR_REMOTE_FULL 233 | #endif 234 | 235 | #ifdef USE_KNX 236 | #undef USE_KNX 237 | #endif 238 | 239 | #ifdef USE_BH1750 240 | #undef USE_BH1750 241 | #endif 242 | 243 | #ifdef USE_VEML6070 244 | #undef USE_VEML6070 245 | #endif 246 | 247 | #ifdef USE_TSL2561 248 | #undef USE_TSL2561 249 | #endif 250 | 251 | #ifdef USE_SI1145 252 | #undef USE_SI1145 253 | #endif 254 | 255 | #ifdef USE_APDS9960 256 | #undef USE_APDS9960 257 | #endif 258 | 259 | #ifdef USE_VEML6075 260 | #undef USE_VEML6075 261 | #endif 262 | 263 | #ifdef USE_MAX44009 264 | #undef USE_MAX44009 265 | #endif 266 | 267 | #ifdef USE_TSL2591 268 | #undef USE_TSL2591 269 | #endif 270 | 271 | #ifdef USE_AS3935 272 | #undef USE_AS3935 273 | #endif 274 | 275 | #ifdef USE_VEML7700 276 | #undef USE_VEML7700 277 | #endif 278 | 279 | #ifdef USE_DISCOVERY 280 | #undef USE_DISCOVERY 281 | #endif 282 | 283 | #ifdef USE_MODBUS_BRIDGE 284 | #undef USE_MODBUS_BRIDGE 285 | #endif 286 | 287 | #ifdef USE_MODBUS_BRIDGE_TCP 288 | #undef USE_MODBUS_BRIDGE_TCP 289 | #endif 290 | 291 | #ifdef USE_MQTT_TLS 292 | #undef USE_MQTT_TLS 293 | #endif 294 | 295 | #ifdef USE_RC_SWITCH 296 | #undef USE_RC_SWITCH 297 | #endif 298 | 299 | #ifdef USE_RULES 300 | #undef USE_RULES 301 | #endif 302 | #define USE_RULES 303 | 304 | #ifdef USE_EXPRESSION 305 | #undef USE_EXPRESSION 306 | #endif 307 | #define USE_EXPRESSION 308 | 309 | #ifdef SUPPORT_IF_STATEMENT 310 | #undef SUPPORT_IF_STATEMENT 311 | #endif 312 | #define SUPPORT_IF_STATEMENT 313 | 314 | #ifdef USE_SCRIPT 315 | #undef USE_SCRIPT 316 | #endif 317 | 318 | #ifdef USE_UFILESYS 319 | #undef USE_UFILESYS 320 | #endif 321 | #define USE_UFILESYS 322 | 323 | #ifdef USE_SDCARD 324 | #undef USE_SDCARD 325 | #endif 326 | #define USE_SDCARD 327 | 328 | #ifdef GUI_TRASH_FILE 329 | #undef GUI_TRASH_FILE 330 | #endif 331 | #define GUI_TRASH_FILE 332 | 333 | #ifdef GUI_EDIT_FILE 334 | #undef GUI_EDIT_FILE 335 | #endif 336 | #define GUI_EDIT_FILE 337 | 338 | #ifdef USE_SHUTTER 339 | #undef USE_SHUTTER 340 | #endif 341 | 342 | #ifdef USE_SPI 343 | #undef USE_SPI 344 | #endif 345 | #define USE_SPI 346 | 347 | #ifdef USE_SONOFF_SC 348 | #undef USE_SONOFF_SC 349 | #endif 350 | 351 | #ifdef USE_DS18x20 352 | #undef USE_DS18x20 353 | #endif 354 | 355 | #ifdef USE_DHT 356 | #undef USE_DHT 357 | #endif 358 | 359 | #ifdef USE_SHT 360 | #undef USE_SHT 361 | #endif 362 | 363 | #ifdef USE_HTU 364 | #undef USE_HTU 365 | #endif 366 | 367 | #ifdef USE_BMP 368 | #undef USE_BMP 369 | #endif 370 | 371 | #ifdef USE_SHT3X 372 | #undef USE_SHT3X 373 | #endif 374 | 375 | #ifdef USE_LM75AD 376 | #undef USE_LM75AD 377 | #endif 378 | 379 | #ifdef USE_AZ7798 380 | #undef USE_AZ7798 381 | #endif 382 | 383 | #ifdef USE_MAX31855 384 | #undef USE_MAX31855 385 | #endif 386 | 387 | #ifdef USE_MLX90614 388 | #undef USE_MLX90614 389 | #endif 390 | 391 | #ifdef USE_MAX31865 392 | #undef USE_MAX31865 393 | #endif 394 | 395 | #ifdef USE_HIH6 396 | #undef USE_HIH6 397 | #endif 398 | 399 | #ifdef USE_DHT12 400 | #undef USE_DHT12 401 | #endif 402 | 403 | #ifdef USE_DS1624 404 | #undef USE_DS1624 405 | #endif 406 | 407 | #ifdef USE_AHT1x 408 | #undef USE_AHT1x 409 | #endif 410 | 411 | #ifdef USE_HDC1080 412 | #undef USE_HDC1080 413 | #endif 414 | 415 | #ifdef USE_MCP9808 416 | #undef USE_MCP9808 417 | #endif 418 | 419 | #ifdef USE_HP303B 420 | #undef USE_HP303B 421 | #endif 422 | 423 | #ifdef USE_LMT01 424 | #undef USE_LMT01 425 | #endif 426 | 427 | #ifdef USE_AM2320 428 | #undef USE_AM2320 429 | #endif 430 | 431 | #ifdef USE_BME68X 432 | #undef USE_BME68X 433 | #endif 434 | 435 | #ifdef USE_TIMERS 436 | #undef USE_TIMERS 437 | #endif 438 | #define USE_TIMERS 439 | 440 | #ifdef USE_TUYA_MCU 441 | #undef USE_TUYA_MCU 442 | #endif 443 | 444 | #ifdef USE_WEBSERVER 445 | #undef USE_WEBSERVER 446 | #endif 447 | #define USE_WEBSERVER 448 | 449 | #ifdef USE_WS2812 450 | #undef USE_WS2812 451 | #endif 452 | 453 | #ifdef MY_LANGUAGE 454 | #undef MY_LANGUAGE 455 | #endif 456 | #define MY_LANGUAGE en_GB 457 | 458 | 459 | #endif 460 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_generic/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32 3 | 4 | [env:tasmota32] 5 | extends = env:tasmota32_base 6 | build_flags = ${env:tasmota32_base.build_flags} 7 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_s2/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32s2 3 | 4 | [env:tasmota32s2] 5 | extends = env:tasmota32_base 6 | board = esp32s2 7 | build_flags = ${env:tasmota32_base.build_flags} 8 | lib_extra_dirs = ${env:tasmota32_base.lib_extra_dirs} 9 | lib_ignore = ${env:tasmota32_base.lib_ignore} 10 | epdiy 11 | Micro-RTSP 12 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_s3/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32s3 3 | 4 | [env:tasmota32s3] 5 | extends = env:tasmota32_base 6 | board = esp32s3-qio_qspi 7 | build_flags = ${env:tasmota32_base.build_flags} 8 | lib_extra_dirs = ${env:tasmota32_base.lib_extra_dirs} 9 | lib_ignore = ${env:tasmota32_base.lib_ignore} 10 | Micro-RTSP 11 | epdiy 12 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_solo1/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32solo1 3 | 4 | [env:tasmota32solo1] 5 | extends = env:tasmota32_base 6 | board = esp32-solo1 7 | lib_extra_dirs = ${env:tasmota32_base.lib_extra_dirs} 8 | lib_ignore = ${env:tasmota32_base.lib_ignore} 9 | Micro-RTSP 10 | epdiy 11 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp32_webcam/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota32-webcam 3 | 4 | [env:tasmota32-webcam] 5 | extends = env:tasmota32_base 6 | build_flags = ${env:tasmota32_base.build_flags} 7 | board = esp32-fix 8 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp8266_generic/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota 3 | 4 | [env:tasmota] 5 | 6 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp8266_nodemcu4M/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota4M 3 | 4 | [env:tasmota4M] 5 | board = esp8266_4M2M 6 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp8266_shelly/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota2M 3 | 4 | [env:tasmota2M] 5 | board = esp8266_2M1M 6 | -------------------------------------------------------------------------------- /ansible/roles/compile/files/esp8266_zigbee-bridge/platformio_override.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | default_envs = tasmota-zbbridge 3 | 4 | [env:tasmota-zbbridge] 5 | board = esp8266_zbbridge 6 | build_flags = ${env.build_flags} 7 | -------------------------------------------------------------------------------- /ansible/roles/compile/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy platformio_override.ini file for {{ item.0 }} 3 | ansible.builtin.copy: 4 | src: '{{ item.0 }}/platformio_override.ini' 5 | dest: '{{ tasmota_dir }}' 6 | mode: '0644' 7 | - name: Copy user_config_override.h file for {{ item.0 }} {{ item.1 }} 8 | ansible.builtin.copy: 9 | src: '{{ item.0 }}/user_config_override_{{ item.1 }}.h' 10 | dest: '{{ tasmota_dir }}/tasmota/user_config_override.h' 11 | mode: '0644' 12 | - name: Compile {{ item.0 }} {{ item.1 }} 13 | ansible.builtin.command: 14 | cmd: pio run 15 | chdir: '{{ tasmota_dir }}' 16 | register: output 17 | changed_when: output.rc in [0, 1] 18 | failed_when: output.rc != 0 19 | -------------------------------------------------------------------------------- /ansible/site.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check compatibility with Tasmota 3 | hosts: localhost 4 | 5 | tasks: 6 | - name: Compile with one config 7 | ansible.builtin.include_role: 8 | name: compile 9 | loop: "{{ ['esp8266_zigbee-bridge', 'esp32_webcam'] | product(['minimal']) | list }}" 10 | 11 | - name: Compile with two configs 12 | ansible.builtin.include_role: 13 | name: compile 14 | loop: "{{ ['esp32_c2', 15 | 'esp32_c3', 16 | 'esp32_c6', 17 | 'esp32_generic', 18 | 'esp32_s2', 19 | 'esp32_s3', 20 | 'esp32_solo1', 21 | 'esp8266_generic', 22 | 'esp8266_nodemcu4M', 23 | 'esp8266_shelly'] | product(['minimal', 'temphum']) | list }}" 24 | -------------------------------------------------------------------------------- /docs/images/brave-browserLang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/brave-browserLang.png -------------------------------------------------------------------------------- /docs/images/chrome-browserLang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/chrome-browserLang.png -------------------------------------------------------------------------------- /docs/images/compile01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/compile01.png -------------------------------------------------------------------------------- /docs/images/docker_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/docker_advanced.png -------------------------------------------------------------------------------- /docs/images/edge-browserLang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/edge-browserLang.png -------------------------------------------------------------------------------- /docs/images/firefox-browserLang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/firefox-browserLang.png -------------------------------------------------------------------------------- /docs/images/gitpod_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/gitpod_advanced.png -------------------------------------------------------------------------------- /docs/images/gitpod_newtab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/gitpod_newtab.png -------------------------------------------------------------------------------- /docs/images/step01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/step01.png -------------------------------------------------------------------------------- /docs/images/step02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/step02.png -------------------------------------------------------------------------------- /docs/images/step03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/step03.png -------------------------------------------------------------------------------- /docs/images/step04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/step04.png -------------------------------------------------------------------------------- /docs/images/step05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/docs/images/step05.png -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | verbose: true, 5 | collectCoverage: true, 6 | setupFiles: [path.resolve(__dirname, 'jestSetEnv.js')], 7 | coverageReporters: ['text', 'text-summary'], // html reporter can be added to generate webpage with summary 8 | }; 9 | -------------------------------------------------------------------------------- /jestSetEnv.js: -------------------------------------------------------------------------------- 1 | process.env.WORKDIR = '/tmp/serverTest'; 2 | // process.env.DEBUG = 'server,git,compile'; 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tasmocompiler", 3 | "version": "12.6.1", 4 | "private": true, 5 | "proxy": "http://localhost:3001/", 6 | "dependencies": { 7 | "@emotion/react": "^11.13.3", 8 | "@emotion/styled": "^11.13.0", 9 | "@mui/icons-material": "^5.16.7", 10 | "@mui/material": "^5.16.7", 11 | "@mui/styles": "^5.16.7", 12 | "body-parser": "^1.20.3", 13 | "debug": "^4.3.7", 14 | "express": "^4.21.1", 15 | "fs-extra": "^11.2.0", 16 | "ini": "^4.1.3", 17 | "lodash": "^4.17.21", 18 | "prop-types": "^15.8.1", 19 | "react": "^17.0.2", 20 | "react-dom": "^17.0.2", 21 | "react-intl": "^6.4.4", 22 | "react-scripts": "^4.0.3", 23 | "semver": "^7.6.3", 24 | "shelljs": "^0.8.5", 25 | "simple-git": "^3.27.0", 26 | "socket.io": "^4.8.0", 27 | "socket.io-client": "^4.8.0" 28 | }, 29 | "scripts": { 30 | "start": "react-scripts start", 31 | "build": "react-scripts build", 32 | "test": "react-scripts test --env=jsdom-fourteen", 33 | "testbackend": "jest server/ ", 34 | "eject": "react-scripts eject", 35 | "startdev": "concurrently --kill-others \"PORT=3001 DEBUG=\"server,git,compile\" nodemon server/app.js\" \"npm start\"" 36 | }, 37 | "browserslist": [ 38 | ">0.2%", 39 | "not dead", 40 | "not ie <= 11", 41 | "not op_mini all" 42 | ], 43 | "devDependencies": { 44 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 45 | "@testing-library/jest-dom": "^5.14.1", 46 | "@testing-library/react": "^12.0.0", 47 | "concurrently": "^4.1.0", 48 | "jest-environment-jsdom-fourteen": "^1.0.1", 49 | "msw": "^0.32.0", 50 | "nodemon": "^2.0.2", 51 | "supertest": "^6.1.3" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/favicon.ico -------------------------------------------------------------------------------- /public/flags/af.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/af.png -------------------------------------------------------------------------------- /public/flags/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/bg.png -------------------------------------------------------------------------------- /public/flags/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/br.png -------------------------------------------------------------------------------- /public/flags/cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/cn.png -------------------------------------------------------------------------------- /public/flags/cz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/cz.png -------------------------------------------------------------------------------- /public/flags/de.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/de.png -------------------------------------------------------------------------------- /public/flags/es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/es.png -------------------------------------------------------------------------------- /public/flags/fr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/fr.png -------------------------------------------------------------------------------- /public/flags/gb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/gb.png -------------------------------------------------------------------------------- /public/flags/gr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/gr.png -------------------------------------------------------------------------------- /public/flags/he.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/he.png -------------------------------------------------------------------------------- /public/flags/hu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/hu.png -------------------------------------------------------------------------------- /public/flags/it.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/it.png -------------------------------------------------------------------------------- /public/flags/ko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/ko.png -------------------------------------------------------------------------------- /public/flags/nl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/nl.png -------------------------------------------------------------------------------- /public/flags/pl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/pl.png -------------------------------------------------------------------------------- /public/flags/pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/pt.png -------------------------------------------------------------------------------- /public/flags/ro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/ro.png -------------------------------------------------------------------------------- /public/flags/ru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/ru.png -------------------------------------------------------------------------------- /public/flags/se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/se.png -------------------------------------------------------------------------------- /public/flags/sk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/sk.png -------------------------------------------------------------------------------- /public/flags/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/tr.png -------------------------------------------------------------------------------- /public/flags/tw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/tw.png -------------------------------------------------------------------------------- /public/flags/ua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/ua.png -------------------------------------------------------------------------------- /public/flags/vn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/public/flags/vn.png -------------------------------------------------------------------------------- /public/img/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/kofi.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | Artboard 26 | 27 | 28 | 29 | 31 | 51 | 52 | Artboard 54 | Created with Sketch. 56 | 59 | 63 | 69 | 74 | 75 | 79 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /public/img/paypal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 20 | 21 | 30 | TasmoCompiler 31 | 32 | 33 | 34 |
35 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "TasmoCompiler", 3 | "name": "TasmoCompiler", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | const { server } = require('./server'); 2 | const { listenPort } = require('./config/config'); 3 | 4 | server.listen(listenPort, () => { 5 | console.log(`Server started on port ${listenPort}`); 6 | }); 7 | -------------------------------------------------------------------------------- /server/binaries/tasmota-minimal.bin.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benzino77/tasmocompiler/413887abcaae0cd76ab2e8ff335f8dba1958ccce/server/binaries/tasmota-minimal.bin.gz -------------------------------------------------------------------------------- /server/compile/__test__/compile.test.js: -------------------------------------------------------------------------------- 1 | const fsMock = require('fs-extra'); 2 | const { compileCode } = require('../compile'); 3 | const { minVersion } = require('../../config/config'); 4 | 5 | const testData = { 6 | version: { tasmotaVersion: minVersion }, 7 | }; 8 | 9 | const socket = { 10 | emit: jest.fn(), 11 | }; 12 | 13 | describe('compile.js test', () => { 14 | describe('testing compileCode', () => { 15 | beforeEach(() => { 16 | fsMock.writeFile.mockClear(); 17 | socket.emit.mockClear(); 18 | }); 19 | 20 | it('should throw an error on writeFile fail', async (done) => { 21 | fsMock.__setFsWriteFileReject(true); 22 | await compileCode(socket, testData); 23 | 24 | expect(socket.emit).toBeCalledTimes(2); 25 | expect(socket.emit).toHaveBeenNthCalledWith(2, 'finished', { ok: false }); 26 | done(); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /server/config/config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const WORKDIR = process.env.WORKDIR || '/tmp'; 4 | const tasmotaRepo = path.resolve(WORKDIR, 'Tasmota'); 5 | const githubRepo = 'https://github.com/arendst/Tasmota.git'; 6 | const minVersion = 'v14.0.0'; 7 | const maxVersion = 'v14.6.0'; 8 | const edgeBranch = 'development'; 9 | const userConfigOvewrite = path.resolve(tasmotaRepo, 'tasmota/user_config_override.h'); 10 | const userPlatformioOverrideIni = path.resolve(tasmotaRepo, 'platformio_override.ini'); 11 | const tasmotaVersionFile = path.resolve(tasmotaRepo, 'tasmota/tasmota_version.h'); 12 | const templatePlatformioIni = path.resolve(__dirname, '../compile/platformio.ini'); 13 | const tasmotaInoFile = path.resolve(tasmotaRepo, 'tasmota/tasmota.ino'); 14 | const tasmotaMinimalBinary = path.resolve(__dirname, '../binaries/tasmota-minimal.bin.gz'); 15 | const listenPort = process.env.PORT || 3000; 16 | 17 | module.exports = { 18 | tasmotaRepo, 19 | githubRepo, 20 | minVersion, 21 | maxVersion, 22 | edgeBranch, 23 | userConfigOvewrite, 24 | userPlatformioOverrideIni, 25 | tasmotaVersionFile, 26 | templatePlatformioIni, 27 | tasmotaInoFile, 28 | tasmotaMinimalBinary, 29 | listenPort, 30 | }; 31 | -------------------------------------------------------------------------------- /server/git/git.js: -------------------------------------------------------------------------------- 1 | const git = require('simple-git'); 2 | const fs = require('fs-extra'); 3 | const _ = require('lodash'); 4 | const debug = require('debug')('git'); 5 | const semver = require('semver'); 6 | const helpers = require('../utils/helpers'); 7 | 8 | const { tasmotaRepo, githubRepo, minVersion, maxVersion, edgeBranch } = require('../config/config'); 9 | 10 | const isGitRepoAvailable = async () => { 11 | try { 12 | await fs.stat(tasmotaRepo); 13 | } catch (e) { 14 | return false; // directory does not exists 15 | } 16 | 17 | const isRepo = await git(tasmotaRepo).checkIsRepo(); 18 | if (!isRepo) { 19 | // directory is not git repo, lets try to delete it 20 | debug(`${tasmotaRepo} is not git repo. Trying to delete it...`); 21 | try { 22 | await fs.remove(tasmotaRepo); 23 | debug('Directory deleted'); 24 | } catch (e) { 25 | const message = `Cannot remove directory: ${tasmotaRepo}`; 26 | debug(message); 27 | throw new Error(message); 28 | } 29 | } 30 | 31 | return isRepo; 32 | }; 33 | 34 | const getRepoTags = async () => { 35 | const isRepo = await isGitRepoAvailable(); 36 | const message = 'Unable to get TAGS'; 37 | const tcVersion = helpers.getTcVersion().toLowerCase(); 38 | 39 | if (isRepo) { 40 | try { 41 | if (tcVersion.includes('dev')) { 42 | return [edgeBranch]; 43 | } 44 | const allTags = await git(tasmotaRepo).tags(); 45 | let tags = allTags.all.filter((t) => t.startsWith('v')); 46 | tags = tags.filter((t) => semver.valid(t) && semver.gte(t, minVersion) && semver.lte(t, maxVersion)); 47 | return [...tags]; 48 | } catch (e) { 49 | debug(e.message); 50 | debug(message); 51 | throw new Error(message); 52 | } 53 | } 54 | 55 | debug(message); 56 | throw new Error(message); 57 | }; 58 | 59 | const switchToBranch = async (branch) => { 60 | const tags = await getRepoTags(); 61 | let notLocalBranches; 62 | 63 | try { 64 | await git(tasmotaRepo).reset('hard'); 65 | } catch (e) { 66 | const message = 'Unable to RESET repository'; 67 | debug(message); 68 | throw new Error(message); 69 | } 70 | 71 | try { 72 | await git(tasmotaRepo).clean('dfx'); 73 | } catch (e) { 74 | const message = 'Unable to CLEAN repository'; 75 | debug(message); 76 | throw new Error(message); 77 | } 78 | 79 | try { 80 | const summary = await git(tasmotaRepo).branchLocal(); 81 | const localBranches = Object.keys(summary.branches); 82 | notLocalBranches = _.difference(tags, localBranches); 83 | } catch (e) { 84 | const message = 'Cannot get the list of local BRANCHES'; 85 | debug(message); 86 | throw new Error(message); 87 | } 88 | 89 | if (_.indexOf(notLocalBranches, branch) > -1) { 90 | try { 91 | await git(tasmotaRepo).checkoutBranch(branch, branch); 92 | return branch; 93 | } catch (e) { 94 | throw new Error(`Switching to branch ${branch} failed`); 95 | } 96 | } 97 | 98 | try { 99 | await git(tasmotaRepo).checkout(branch); 100 | return branch; 101 | } catch (e) { 102 | throw new Error(`Switching to branch ${branch} failed`); 103 | } 104 | }; 105 | 106 | const cloneRepo = async () => { 107 | const isRepo = await isGitRepoAvailable(); 108 | if (!isRepo) { 109 | try { 110 | await git().clone(githubRepo, tasmotaRepo); 111 | debug('Repo cloned.'); 112 | } catch (e) { 113 | const message = 'Unable to CLONE git repository'; 114 | debug(message); 115 | throw new Error(message); 116 | } 117 | } 118 | 119 | const tags = await getRepoTags(); 120 | return tags; 121 | }; 122 | 123 | const pullRepo = async (refresh) => { 124 | const isRepo = await isGitRepoAvailable(); 125 | if (isRepo) { 126 | await switchToBranch(edgeBranch); 127 | 128 | try { 129 | await git(tasmotaRepo).pull(); 130 | debug('Branch %s is now up to date.', edgeBranch); 131 | } catch (e) { 132 | const message = 'Unable to PULL latest changes'; 133 | debug(message); 134 | throw new Error(message); 135 | } 136 | 137 | const tags = await getRepoTags(); 138 | return tags; 139 | } 140 | 141 | debug('There is no repository available. Trying to clone.'); 142 | const tags = await cloneRepo(); 143 | return tags; 144 | }; 145 | 146 | module.exports = { 147 | isGitRepoAvailable, 148 | getRepoTags, 149 | switchToBranch, 150 | cloneRepo, 151 | pullRepo, 152 | }; 153 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const path = require('path'); 4 | const _ = require('lodash'); 5 | const debug = require('debug')('server'); 6 | const pkg = require('../package.json'); 7 | 8 | const app = express(); 9 | 10 | const server = require('http').createServer(app); 11 | const io = require('socket.io')(server); 12 | 13 | const { isGitRepoAvailable, getRepoTags, cloneRepo, pullRepo } = require('./git/git'); 14 | const { compileCode } = require('./compile/compile'); 15 | const { tasmotaRepo, userPlatformioOverrideIni, userConfigOvewrite, tasmotaMinimalBinary } = require('./config/config'); 16 | 17 | const staticPath = path.join(__dirname, '../build'); 18 | let clientWSSocket; 19 | 20 | io.on('connection', (socket) => { 21 | clientWSSocket = socket; 22 | socket.emit('message', 'Welcome stranger!\n'); 23 | }); 24 | 25 | app.use(bodyParser.json()); 26 | // handle bodyParser error 27 | app.use((err, req, res, next) => { 28 | if (err) { 29 | res.status(400).send({ ok: false, message: 'Wrong JSON data passed.' }); 30 | } 31 | next(); 32 | }); 33 | app.use(express.static(staticPath)); 34 | 35 | app.get('/api/v1/tcversion', (req, res) => { 36 | res.send({ ok: true, version: pkg.version }); 37 | }); 38 | 39 | app.get('/api/v1/repoavailability', (req, res) => { 40 | isGitRepoAvailable() 41 | .then((result) => { 42 | // res.set('Access-Control-Allow-Origin', '*').send({ result }); 43 | res.send({ ok: true, result }); 44 | }) 45 | .catch((e) => { 46 | res.status(500).send({ ok: false, result: false, message: e.message }); 47 | }); 48 | }); 49 | 50 | app.get('/api/v1/repotags', (req, res) => { 51 | getRepoTags() 52 | .then((tags) => { 53 | res.send({ ok: true, tags }); 54 | }) 55 | .catch((e) => { 56 | res.status(500).send({ ok: false, tags: [], message: e.message }); 57 | }); 58 | }); 59 | 60 | app.get('/api/v1/clonerepo', (req, res) => { 61 | cloneRepo() 62 | .then((tags) => { 63 | res.send({ ok: true, tags }); 64 | }) 65 | .catch((e) => { 66 | res.status(500).send({ ok: false, tags: [], message: e.message }); 67 | }); 68 | }); 69 | 70 | app.get('/api/v1/pullrepo', (req, res) => { 71 | pullRepo() 72 | .then((tags) => { 73 | res.send({ ok: true, tags }); 74 | }) 75 | .catch((e) => { 76 | res.status(500).send({ ok: false, tags: [], message: e.message }); 77 | }); 78 | }); 79 | 80 | app.post('/api/v1/compile', (req, res) => { 81 | const requiredKeys = ['version', 'features', 'network']; 82 | if (_.isEmpty(req.body) || !requiredKeys.every((e) => e in req.body)) { 83 | res.status(400).send({ ok: false, message: 'Wrong JSON data passed.' }); 84 | } else { 85 | debug(JSON.stringify(req.body, undefined, 2)); 86 | res.send({ ok: true }); 87 | compileCode(clientWSSocket, req.body); 88 | } 89 | }); 90 | 91 | app.get('/download/:fileName', (req, res) => { 92 | if (req.params.fileName === 'platformio_override.ini') { 93 | res.download(userPlatformioOverrideIni); 94 | return; 95 | } 96 | 97 | if (req.params.fileName === 'user_config_override.h') { 98 | res.download(userConfigOvewrite); 99 | return; 100 | } 101 | 102 | if (req.params.fileName === tasmotaMinimalBinary.split('/').pop()) { 103 | res.download(tasmotaMinimalBinary); 104 | return; 105 | } 106 | 107 | const firmwareFile = path.resolve(tasmotaRepo, `build_output/firmware/${req.params.fileName}`); 108 | res.download(firmwareFile); 109 | }); 110 | 111 | module.exports = { server }; 112 | -------------------------------------------------------------------------------- /server/tests/testSet.json: -------------------------------------------------------------------------------- 1 | { 2 | "showDownloadLinks": false, 3 | "features": { 4 | "board": { 5 | "name": "esp8266generic", 6 | "chip_type": "esp8266", 7 | "description": "Generic", 8 | "default": true, 9 | "show": true, 10 | "platformio_entries": {}, 11 | "tooltip": "stepFeaturesBoard8266Tooltip", 12 | "include_features": ["rules"], 13 | "exclude_features": [], 14 | "defines": {} 15 | }, 16 | "airsensors": false, 17 | "USE_MHZ19": false, 18 | "USE_SENSEAIR": false, 19 | "USE_PMS5003": false, 20 | "USE_MGS": false, 21 | "USE_NOVA_SDS": false, 22 | "USE_SGP30": false, 23 | "USE_CCS811": false, 24 | "USE_SCD30": false, 25 | "USE_SPS30": false, 26 | "USE_HPMA": false, 27 | "USE_IAQ": false, 28 | "alexa": false, 29 | "USE_EMULATION": false, 30 | "USE_EMULATION_HUE": false, 31 | "USE_EMULATION_WEMO": false, 32 | "USE_TASMOTA_CLIENT": false, 33 | "displays": false, 34 | "USE_DISPLAY": false, 35 | "USE_DISPLAY_MODES1TO5": false, 36 | "USE_DISPLAY_LCD": false, 37 | "USE_DISPLAY_SSD1306": false, 38 | "USE_DISPLAY_MATRIX": false, 39 | "USE_DISPLAY_ILI9341": false, 40 | "USE_DISPLAY_EPAPER_29": false, 41 | "USE_DISPLAY_EPAPER_42": false, 42 | "USE_DISPLAY_SH1106": false, 43 | "USE_DISPLAY_ILI9488": false, 44 | "USE_DISPLAY_SSD1351": false, 45 | "USE_DISPLAY_RA8876": false, 46 | "USE_DISPLAY_SEVENSEG": false, 47 | "USE_DISPLAY_ST7789": false, 48 | "USE_DISPLAY_SSD1331": false, 49 | "precustom#displays": "", 50 | "USE_ADC_VCC": false, 51 | "USE_DOMOTICZ": false, 52 | "USE_ENERGY_SENSOR": false, 53 | "energysensors": false, 54 | "USE_HLW8012": false, 55 | "USE_CSE7766": false, 56 | "USE_PZEM004T": false, 57 | "USE_MCP39F501": false, 58 | "USE_PZEM_AC": false, 59 | "USE_PZEM_DC": false, 60 | "USE_ADE7953": false, 61 | "USE_SDM120": false, 62 | "USE_DDS2382": false, 63 | "USE_SDM630": false, 64 | "USE_DDSU666": false, 65 | "USE_SOLAX_X1": false, 66 | "USE_LE01MR": false, 67 | "USE_BL0940": false, 68 | "USE_TELEINFO": false, 69 | "USE_IEM3000": false, 70 | "USE_WE517": false, 71 | "USE_ENERGY_DUMMY": false, 72 | "temphumpressensors": false, 73 | "USE_SONOFF_SC": false, 74 | "USE_DS18x20": false, 75 | "USE_DHT": false, 76 | "USE_SHT": false, 77 | "USE_HTU": false, 78 | "USE_BMP": false, 79 | "USE_SHT3X": false, 80 | "USE_LM75AD": false, 81 | "USE_APDS9960": false, 82 | "USE_AZ7798": false, 83 | "USE_MAX31855": false, 84 | "USE_MLX90614": false, 85 | "USE_MAX31865": false, 86 | "USE_HIH6": false, 87 | "USE_DHT12": false, 88 | "USE_DS1624": false, 89 | "USE_AHT1x": false, 90 | "USE_HDC1080": false, 91 | "USE_MCP9808": false, 92 | "USE_HP303B": false, 93 | "USE_LMT01": false, 94 | "lightsensors": false, 95 | "USE_BH1750": false, 96 | "USE_VEML6070": false, 97 | "USE_TSL2561": false, 98 | "USE_SI1145": false, 99 | "USE_VEML6075": false, 100 | "USE_MAX44009": false, 101 | "USE_TSL2591": false, 102 | "USE_AS3935": false, 103 | "USE_VEML7700": false, 104 | "USE_HOME_ASSISTANT": false, 105 | "gpioexpanders": false, 106 | "USE_MCP230xx": false, 107 | "USE_MCP230xx_OUTPUT": false, 108 | "USE_MCP230xx_DISPLAYOUTPUT": false, 109 | "precustom#gpioexpanders": "", 110 | "USE_KNX": false, 111 | "USE_IR_REMOTE": false, 112 | "platformio_entries#USE_IR_REMOTE": {}, 113 | "USE_IR_REMOTE_FULL": false, 114 | "platformio_entries#USE_IR_REMOTE_FULL": {}, 115 | "USE_DISCOVERY": false, 116 | "USE_MQTT_TLS": false, 117 | "USE_RC_SWITCH": false, 118 | "rules": true, 119 | "USE_RULES": true, 120 | "USE_EXPRESSION": true, 121 | "SUPPORT_IF_STATEMENT": true, 122 | "USE_SCRIPT": false, 123 | "USE_TIMERS": true, 124 | "USE_TUYA_MCU": false, 125 | "distance": false, 126 | "USE_SR04": false, 127 | "USE_VL53L0X": false, 128 | "USE_HRXL": false, 129 | "USE_DYP": false, 130 | "USE_VL53L1X": false, 131 | "USE_WEBSERVER": true, 132 | "USE_WS2812": false, 133 | "ufilesys": false, 134 | "USE_UFILESYS": false, 135 | "USE_SDCARD": false, 136 | "GUI_TRASH_FILE": false, 137 | "GUI_EDIT_FILE": false, 138 | "USE_I2C": false, 139 | "USE_SPI": false 140 | }, 141 | "network": { 142 | "STA_SSID1": "", 143 | "STA_PASS1": "", 144 | "WIFI_IP_ADDRESS": "", 145 | "WIFI_SUBNETMASK": "", 146 | "WIFI_GATEWAY": "", 147 | "WIFI_DNS": "", 148 | "showPassword": false, 149 | "staticIPEnabled": false 150 | }, 151 | "version": { 152 | "tasmotaVersion": "development", 153 | "MY_LANGUAGE": "en_GB", 154 | "message": "" 155 | }, 156 | "customParams": "", 157 | "tcGUILanguage": "en" 158 | } 159 | -------------------------------------------------------------------------------- /server/utils/__mocks__/helpers.js: -------------------------------------------------------------------------------- 1 | const helpers = jest.genMockFromModule('../helpers'); 2 | let version = '100'; 3 | 4 | function __setReturnVersion(v) { 5 | version = v; 6 | } 7 | 8 | const getTcVersion = jest.fn(() => { 9 | return version; 10 | }); 11 | 12 | helpers.getTcVersion = getTcVersion; 13 | helpers.__setReturnVersion = __setReturnVersion; 14 | 15 | module.exports = helpers; 16 | -------------------------------------------------------------------------------- /server/utils/helpers.js: -------------------------------------------------------------------------------- 1 | const packageJson = require('../../package.json'); 2 | function getTcVersion() { 3 | return packageJson.version; 4 | } 5 | 6 | module.exports = { getTcVersion }; 7 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { ThemeProvider, createTheme } from '@mui/material/styles'; 4 | import { withStyles } from '@mui/styles'; 5 | import Stepper from '@mui/material/Stepper'; 6 | import io from 'socket.io-client'; 7 | import { IntlProvider } from 'react-intl'; 8 | 9 | import styles from './styles/styles'; 10 | import TopAppBar from './components/TopAppBar/TopAppBar'; 11 | import SourceStep from './components/AppStepper/SourceStep'; 12 | import VersionStep from './components/AppStepper/VersionStep/VersionStep'; 13 | import WifiStep from './components/AppStepper/WifiStep'; 14 | import FeaturesStep from './components/AppStepper/FeaturesStep/FeaturesStep'; 15 | import CustomParametersStep from './components/AppStepper/CustomParametersStep'; 16 | import MessageBox from './components/MessageBox/MessageBox'; 17 | import DownloadLinks from './components/DownloadLinks/DownloadLinks'; 18 | import { allMessages, defaultLanguage } from './locales/languages'; 19 | import { tasmotaGUILanguages } from './components/AppStepper/VersionStep/Variables/Languages'; 20 | import availableFeatures from './components/AppStepper/FeaturesStep/AvailableFeatures'; 21 | 22 | import { StyledEngineProvider } from '@mui/material/styles'; 23 | 24 | const browserLanguage = navigator.language.toLocaleLowerCase(); 25 | 26 | console.log(`Detected browser language: ${browserLanguage}`); 27 | 28 | let tcGUILanguage = defaultLanguage; 29 | 30 | Object.keys(allMessages).some((l) => { 31 | const found = allMessages[l].browserLang.includes(browserLanguage); 32 | if (found) { 33 | tcGUILanguage = l; 34 | } 35 | return found; 36 | }); 37 | 38 | console.log(`TasmoCompiler GUI language set to ${tcGUILanguage}`); 39 | 40 | const theme = createTheme({ 41 | palette: { 42 | primary: { 43 | main: '#3F51B5', 44 | }, 45 | secondary: { 46 | main: '#F50057', 47 | }, 48 | }, 49 | }); 50 | 51 | class App extends Component { 52 | constructor(props) { 53 | super(props); 54 | this.state = { 55 | activeStep: 0, 56 | tags: [], 57 | compiling: false, 58 | showMessageBox: false, 59 | showDownloadLinks: false, 60 | compileMessages: '', 61 | features: {}, 62 | network: {}, 63 | version: {}, 64 | customParams: '', 65 | tcGUILanguage, 66 | }; 67 | this.handleNext = this.handleNext.bind(this); 68 | this.handleBack = this.handleBack.bind(this); 69 | this.handleCompile = this.handleCompile.bind(this); 70 | this.changeLanguage = this.changeLanguage.bind(this); 71 | } 72 | 73 | componentDidMount() { 74 | const socket = io(); 75 | socket.on('message', (data) => { 76 | this.setState((state) => { 77 | let newMessages = state.compileMessages; 78 | newMessages = `${newMessages}${data}`; 79 | return { compileMessages: newMessages }; 80 | }); 81 | }); 82 | 83 | socket.on('finished', (data) => { 84 | this.setState({ compiling: false, showDownloadLinks: data.ok }); 85 | }); 86 | 87 | this.changeLanguage(this.state.tcGUILanguage); 88 | } 89 | 90 | handleNext = (data) => { 91 | this.setState((state) => ({ 92 | activeStep: state.activeStep + 1, 93 | ...data, 94 | })); 95 | }; 96 | 97 | handleBack = () => { 98 | this.setState((state) => ({ 99 | activeStep: state.activeStep - 1, 100 | compileMessages: '', 101 | showMessageBox: false, 102 | showDownloadLinks: false, 103 | })); 104 | }; 105 | 106 | handleCompile = (data) => { 107 | const uri = '/api/v1/compile'; 108 | 109 | this.setState( 110 | { 111 | compiling: true, 112 | showMessageBox: true, 113 | compileMessages: '', 114 | showDownloadLinks: false, 115 | ...data, 116 | }, 117 | () => { 118 | const { compiling, showMessageBox, message, activeStep, tags, compileMessages, ...postData } = this.state; 119 | 120 | fetch(uri, { 121 | method: 'POST', 122 | body: JSON.stringify(postData), 123 | headers: { 'Content-Type': 'application/json' }, 124 | }) 125 | .then((res) => res.json()) 126 | .then((json) => { 127 | if (!json.ok) { 128 | this.setState((state) => { 129 | let newMessages = state.compileMessages; 130 | newMessages = `${newMessages}${json.message}`; 131 | return { compileMessages: newMessages, compiling: false }; 132 | }); 133 | } 134 | }) 135 | .catch((error) => { 136 | this.setState({ compileMessages: error.message, compiling: false }); 137 | }); 138 | } 139 | ); 140 | }; 141 | 142 | changeLanguage = (lang) => { 143 | tasmotaGUILanguages.sort((a, b) => { 144 | return allMessages[lang]['source'][a.name].localeCompare(allMessages[lang]['source'][b.name]); 145 | }); 146 | availableFeatures.sort((a, b) => { 147 | return allMessages[lang]['source'][a.description].localeCompare(allMessages[lang]['source'][b.description]); 148 | }); 149 | this.setState({ tcGUILanguage: lang }); 150 | }; 151 | 152 | render() { 153 | const { classes } = this.props; 154 | 155 | const { activeStep, tags, compiling, showMessageBox, showDownloadLinks, compileMessages, tcGUILanguage, ...other } = 156 | this.state; 157 | 158 | const bnHandlersProps = { 159 | backHandler: this.handleBack, 160 | nextHandler: this.handleNext, 161 | }; 162 | 163 | return ( 164 | 165 | 166 | 167 |
168 | 169 | 170 | 171 | 172 | 173 | 174 | 182 | 183 | {showMessageBox && } 184 | {showDownloadLinks && } 185 |
186 |
187 |
188 |
189 | ); 190 | } 191 | } 192 | 193 | App.propTypes = { 194 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 195 | }; 196 | 197 | export default withStyles(styles(theme))(App); 198 | -------------------------------------------------------------------------------- /src/components/AppStepper/BackButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Button from '@mui/material/Button'; 4 | import { FormattedMessage } from 'react-intl'; 5 | 6 | function BackButton(props) { 7 | const { disabled, onClick } = props; 8 | return ( 9 | 12 | ); 13 | } 14 | 15 | BackButton.propTypes = { 16 | disabled: PropTypes.bool.isRequired, 17 | onClick: PropTypes.func.isRequired, 18 | }; 19 | 20 | export default BackButton; 21 | -------------------------------------------------------------------------------- /src/components/AppStepper/ClearButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Button from '@mui/material/Button'; 4 | import { FormattedMessage } from 'react-intl'; 5 | 6 | function ClearButton(props) { 7 | const { disabled, onClick } = props; 8 | return ( 9 | 12 | ); 13 | } 14 | 15 | ClearButton.propTypes = { 16 | disabled: PropTypes.bool.isRequired, 17 | onClick: PropTypes.func.isRequired, 18 | }; 19 | 20 | export default ClearButton; 21 | -------------------------------------------------------------------------------- /src/components/AppStepper/CompileButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Button from '@mui/material/Button'; 4 | import { FormattedMessage } from 'react-intl'; 5 | 6 | function CompileButton(props) { 7 | const { disabled, onClick } = props; 8 | return ( 9 | 12 | ); 13 | } 14 | 15 | CompileButton.propTypes = { 16 | disabled: PropTypes.bool.isRequired, 17 | onClick: PropTypes.func.isRequired, 18 | }; 19 | 20 | export default CompileButton; 21 | -------------------------------------------------------------------------------- /src/components/AppStepper/CustomParametersStep.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Step from '@mui/material/Step'; 4 | import StepLabel from '@mui/material/StepLabel'; 5 | import StepContent from '@mui/material/StepContent'; 6 | import TextField from '@mui/material/TextField'; 7 | import Typography from '@mui/material/Typography'; 8 | 9 | import NextButton from './NextButton'; 10 | import BackButton from './BackButton'; 11 | import { FormattedMessage } from 'react-intl'; 12 | 13 | class CustomParametersStep extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { 17 | customParams: '', 18 | }; 19 | this.handleChange = this.handleChange.bind(this); 20 | this.handleNext = this.handleNext.bind(this); 21 | this.handleBack = this.handleBack.bind(this); 22 | } 23 | 24 | componentDidUpdate(prevProps) { 25 | const { pstate } = this.props; 26 | 27 | const ncp = Object.keys(pstate.features) 28 | .filter((name) => name.startsWith('precustom#')) 29 | .reduce((acc, cval) => `${acc}\n${pstate.features[cval]}`, ''); 30 | 31 | const pcp = Object.keys(prevProps.pstate.features) 32 | .filter((name) => name.startsWith('precustom#')) 33 | .reduce((acc, cval) => `${acc}\n${prevProps.pstate.features[cval]}`, ''); 34 | 35 | if (ncp !== pcp) { 36 | this.setState({ customParams: ncp.trim() }); 37 | } 38 | } 39 | 40 | handleChange(event) { 41 | this.setState({ [event.target.name]: event.target.value }); 42 | } 43 | 44 | handleNext() { 45 | const { nextHandler } = this.props; 46 | nextHandler({ ...this.state }); 47 | } 48 | 49 | handleBack() { 50 | const { backHandler } = this.props; 51 | backHandler(); 52 | } 53 | 54 | render() { 55 | const { classes, nextHandler, backHandler, ...other } = this.props; 56 | const { customParams } = this.state; 57 | const placeholder = 58 | '#ifdef USE_MCP230xx\n #undef USE_MCP230xx\n#endif\n#define USE_MCP230xx\n\n' + 59 | '#ifdef USE_MCP230xx_ADDR\n #undef USE_MCP230xx_ADDR\n#endif\n#define USE_MCP230xx_ADDR 0x20\n'; 60 | 61 | return ( 62 | 63 | 64 | 65 | 66 | 67 | 68 | user_config_override.h }} id='stepCustomParamsDesc' /> 69 | 70 |
71 |
72 | } 77 | fullWidth 78 | multiline 79 | minRows={9} 80 | maxRows={9} 81 | className={classes.multiTextField} 82 | value={customParams} 83 | onChange={this.handleChange} 84 | margin='normal' 85 | InputProps={{ 86 | classes: { 87 | input: classes.inputFont, 88 | }, 89 | }} 90 | /> 91 |
92 |
93 |
94 |
95 | 96 |
97 |
98 | 99 |
100 |
101 |
102 |
103 | ); 104 | } 105 | } 106 | 107 | CustomParametersStep.propTypes = { 108 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 109 | pstate: PropTypes.oneOfType([PropTypes.object]).isRequired, 110 | nextHandler: PropTypes.func.isRequired, 111 | backHandler: PropTypes.func.isRequired, 112 | }; 113 | 114 | export default CustomParametersStep; 115 | -------------------------------------------------------------------------------- /src/components/AppStepper/FeaturesStep/FeaturesSelector.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import FormControlLabel from '@mui/material/FormControlLabel'; 4 | import Tooltip from '@mui/material/Tooltip'; 5 | import Checkbox from '@mui/material/Checkbox'; 6 | import { FormattedMessage } from 'react-intl'; 7 | 8 | function FeaturesSelector(props) { 9 | const { 10 | value, 11 | onChange, 12 | classes, 13 | item: { description, tooltip, name }, 14 | } = props; 15 | 16 | return ( 17 |
18 | : ''}> 19 | } 21 | label={} 22 | /> 23 | 24 |
25 | ); 26 | } 27 | 28 | FeaturesSelector.propTypes = { 29 | value: PropTypes.bool.isRequired, 30 | onChange: PropTypes.func.isRequired, 31 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 32 | item: PropTypes.shape({ 33 | description: PropTypes.string, 34 | tooltip: PropTypes.string, 35 | name: PropTypes.string, 36 | }).isRequired, 37 | }; 38 | 39 | export default FeaturesSelector; 40 | -------------------------------------------------------------------------------- /src/components/AppStepper/NextButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Button from '@mui/material/Button'; 4 | import { FormattedMessage } from 'react-intl'; 5 | 6 | function NextButton(props) { 7 | const { disabled, onClick } = props; 8 | return ( 9 | 12 | ); 13 | } 14 | 15 | NextButton.propTypes = { 16 | disabled: PropTypes.bool.isRequired, 17 | onClick: PropTypes.func.isRequired, 18 | }; 19 | 20 | export default NextButton; 21 | -------------------------------------------------------------------------------- /src/components/AppStepper/SourceStep.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Step from '@mui/material/Step'; 4 | import StepLabel from '@mui/material/StepLabel'; 5 | import StepContent from '@mui/material/StepContent'; 6 | import Button from '@mui/material/Button'; 7 | import CircularProgress from '@mui/material/CircularProgress'; 8 | import Typography from '@mui/material/Typography'; 9 | import { FormattedMessage } from 'react-intl'; 10 | 11 | import NextButton from './NextButton'; 12 | 13 | class SourceStep extends Component { 14 | constructor(props) { 15 | super(props); 16 | 17 | this.tags = []; 18 | this.state = { 19 | isRepo: false, 20 | message: '', 21 | cloning: false, 22 | gettingTags: false, 23 | }; 24 | 25 | this.handleClonePull = this.handleClonePull.bind(this); 26 | this.handleNext = this.handleNext.bind(this); 27 | } 28 | 29 | componentDidMount() { 30 | fetch('/api/v1/repoavailability') 31 | .then((res) => res.json()) 32 | .then((ret) => { 33 | this.setState({ isRepo: ret.result, message: '' }); 34 | }) 35 | .catch((error) => { 36 | this.setState({ isRepo: false, message: error.message }); 37 | }); 38 | } 39 | 40 | handleClonePull() { 41 | const { isRepo } = this.state; 42 | const uri = isRepo ? '/api/v1/pullrepo' : '/api/v1/clonerepo'; 43 | 44 | this.setState({ cloning: true }); 45 | fetch(uri) 46 | .then((res) => res.json()) 47 | .then((ret) => { 48 | if (!ret.ok) throw new Error(ret.message); 49 | this.tags = ret.tags; 50 | this.setState({ isRepo: true, cloning: false }); 51 | }) 52 | .catch((error) => { 53 | this.setState({ message: error.message, cloning: false }); 54 | }); 55 | } 56 | 57 | handleNext() { 58 | const { nextHandler } = this.props; 59 | 60 | if (this.tags.length === 0) { 61 | this.setState({ gettingTags: true }); 62 | fetch('/api/v1/repotags') 63 | .then((res) => res.json()) 64 | .then((ret) => { 65 | this.tags = ret.tags; 66 | this.setState({ gettingTags: false }); 67 | nextHandler({ tags: this.tags }); 68 | }) 69 | .catch((error) => { 70 | this.setState({ message: error.message, gettingTags: false }); 71 | }); 72 | } else { 73 | nextHandler({ tags: this.tags }); 74 | } 75 | } 76 | 77 | render() { 78 | const { classes, nextHandler, ...other } = this.props; 79 | 80 | const { isRepo, message, cloning, gettingTags } = this.state; 81 | 82 | return ( 83 | 84 | 0 && other.active} classes={{ label: classes.stepLabel }}> 85 | 86 | 87 | 88 | {isRepo ? ( 89 | 90 | 91 | 92 | ) : ( 93 | 94 | 95 | 96 | )} 97 |
98 |
99 | 108 | {cloning && } 109 |
110 |
111 | 112 | {gettingTags && } 113 |
114 |
115 | {message && ( 116 | 117 | Error: 118 | {message} 119 | 120 | )} 121 |
122 |
123 | ); 124 | } 125 | } 126 | 127 | SourceStep.propTypes = { 128 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 129 | nextHandler: PropTypes.func.isRequired, 130 | }; 131 | 132 | export default SourceStep; 133 | -------------------------------------------------------------------------------- /src/components/AppStepper/TextFieldComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import TextField from '@mui/material/TextField'; 4 | 5 | function TextFieldComponent(props) { 6 | const { name, label, classes, value, type, onChange, inputProps } = props; 7 | 8 | return ( 9 | 20 | ); 21 | } 22 | 23 | TextFieldComponent.propTypes = { 24 | name: PropTypes.string.isRequired, 25 | label: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired, 26 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 27 | inputProps: PropTypes.oneOfType([PropTypes.object]), 28 | value: PropTypes.string.isRequired, 29 | type: PropTypes.string, 30 | onChange: PropTypes.func.isRequired, 31 | }; 32 | 33 | TextFieldComponent.defaultProps = { 34 | type: 'text', 35 | }; 36 | 37 | export default TextFieldComponent; 38 | -------------------------------------------------------------------------------- /src/components/AppStepper/VersionStep/Variables/Languages.js: -------------------------------------------------------------------------------- 1 | // nativeName: https://www.internationalphoneticalphabet.org/languages/language-names-in-native-language/ 2 | 3 | const tasmotaGUILanguages = [ 4 | { 5 | name: 'Afrikaans', 6 | value: 'af_AF', 7 | nativeName: 'Afrikaans', 8 | flag: 'flags/af.png', 9 | browserLang: ['af', 'af-af'], 10 | }, 11 | { 12 | name: 'English', 13 | value: 'en_GB', 14 | nativeName: 'English', 15 | flag: 'flags/gb.png', 16 | browserLang: ['en', 'en-us', 'en-gb'], 17 | }, 18 | { 19 | name: 'Bulgarian', 20 | value: 'bg_BG', 21 | nativeName: 'Български', 22 | flag: 'flags/bg.png', 23 | browserLang: ['bg', 'bg-bg'], 24 | }, 25 | { 26 | name: 'Czech', 27 | value: 'cs_CZ', 28 | nativeName: 'Čeština', 29 | flag: 'flags/cz.png', 30 | browserLang: ['cs', 'cs-cz'], 31 | }, 32 | { 33 | name: 'German', 34 | value: 'de_DE', 35 | nativeName: 'Deutsch', 36 | flag: 'flags/de.png', 37 | browserLang: ['de', 'de-de'], 38 | }, 39 | { 40 | name: 'Greek', 41 | value: 'el_GR', 42 | nativeName: 'Ελληνικά', 43 | flag: 'flags/gr.png', 44 | browserLang: ['el', 'el-gr'], 45 | }, 46 | { 47 | name: 'Spanish', 48 | value: 'es_ES', 49 | nativeName: 'Español', 50 | flag: 'flags/es.png', 51 | browserLang: ['es', 'es-es'], 52 | }, 53 | { 54 | name: 'French', 55 | value: 'fr_FR', 56 | nativeName: 'Français', 57 | flag: 'flags/fr.png', 58 | browserLang: ['fr', 'fr-fr'], 59 | }, 60 | { 61 | name: 'Hebrew', 62 | value: 'he_HE', 63 | nativeName: 'עִבְרִית', 64 | flag: 'flags/he.png', 65 | browserLang: ['he', 'he-he'], 66 | }, 67 | { 68 | name: 'Hungarian', 69 | value: 'hu_HU', 70 | nativeName: 'Magyar', 71 | flag: 'flags/hu.png', 72 | browserLang: ['hu', 'hu-hu'], 73 | }, 74 | { 75 | name: 'Italian', 76 | value: 'it_IT', 77 | nativeName: 'Italiano', 78 | flag: 'flags/it.png', 79 | browserLang: ['it', 'it-it'], 80 | }, 81 | { 82 | name: 'Korean', 83 | value: 'ko_KO', 84 | nativeName: '한국어', 85 | flag: 'flags/ko.png', 86 | browserLang: ['ko', 'ko-kr'], 87 | }, 88 | { 89 | name: 'Dutch', 90 | value: 'nl_NL', 91 | nativeName: 'Nederlands', 92 | flag: 'flags/nl.png', 93 | browserLang: ['nl'], 94 | }, 95 | { 96 | name: 'Polish', 97 | value: 'pl_PL', 98 | nativeName: 'Polski', 99 | flag: 'flags/pl.png', 100 | browserLang: ['pl', 'pl-pl'], 101 | }, 102 | { 103 | name: 'Portuguese (Brazil)', 104 | value: 'pt_BR', 105 | nativeName: 'Português (Brasileiro)', 106 | flag: 'flags/br.png', 107 | browserLang: ['pt-br'], 108 | }, 109 | { 110 | name: 'Portuguese', 111 | value: 'pt_PT', 112 | nativeName: 'Português', 113 | flag: 'flags/pt.png', 114 | browserLang: ['pt', 'pt-pt'], 115 | }, 116 | { 117 | name: 'Romanian', 118 | value: 'ro_RO', 119 | nativeName: 'Română', 120 | flag: 'flags/ro.png', 121 | browserLang: ['ro', 'ro-ro'], 122 | }, 123 | { 124 | name: 'Russian', 125 | value: 'ru_RU', 126 | nativeName: 'Русский', 127 | flag: 'flags/ru.png', 128 | browserLang: ['ru', 'ru-ru'], 129 | }, 130 | { 131 | name: 'Slovak', 132 | value: 'sk_SK', 133 | nativeName: 'Slovenčina', 134 | flag: 'flags/sk.png', 135 | browserLang: ['sk', 'sk-sk'], 136 | }, 137 | { 138 | name: 'Swedish', 139 | value: 'sv_SE', 140 | nativeName: 'Svenska', 141 | flag: 'flags/se.png', 142 | browserLang: ['se', 'sv-se'], 143 | }, 144 | { 145 | name: 'Turkish', 146 | value: 'tr_TR', 147 | nativeName: 'Türkçe', 148 | flag: 'flags/tr.png', 149 | browserLang: ['tr'], 150 | }, 151 | { 152 | name: 'Ukrainian', 153 | value: 'uk_UA', 154 | nativeName: 'Українська', 155 | flag: 'flags/ua.png', 156 | browserLang: ['uk', 'uk-ua'], 157 | }, 158 | { 159 | name: 'Vietnam', 160 | value: 'vi_VN', 161 | nativeName: 'Tiếng việt', 162 | flag: 'flags/vn.png', 163 | browserLang: ['vi', 'vi-vn'], 164 | }, 165 | { 166 | name: 'Chinese (Simplified)', 167 | value: 'zh_CN', 168 | nativeName: '汉语', 169 | flag: 'flags/cn.png', 170 | browserLang: ['zh-cn'], 171 | }, 172 | { 173 | name: 'Chinese (Traditional)', 174 | value: 'zh_TW', 175 | nativeName: '漢語', 176 | flag: 'flags/tw.png', 177 | browserLang: ['zh-tw'], 178 | }, 179 | { 180 | name: 'Frisian', 181 | value: 'fy_NL', 182 | nativeName: 'Frysk', 183 | flag: 'flags/nl.png', 184 | browserLang: ['fy', 'fy-nl'], 185 | }, 186 | ]; 187 | 188 | // What default language should be selected for Tasmota GUI 189 | // it is based on user browser language setting 190 | const browserLanguage = navigator.language.toLocaleLowerCase(); 191 | 192 | let languageIndex = tasmotaGUILanguages.findIndex((element) => 193 | element.browserLang.includes(browserLanguage) 194 | ); 195 | 196 | // Set English as default 197 | if (languageIndex === -1) { 198 | languageIndex = tasmotaGUILanguages.findIndex((element) => 199 | element.value.includes('en_GB') 200 | ); 201 | } 202 | 203 | const preselectedTasmotaGUILanguage = tasmotaGUILanguages[languageIndex].value; 204 | 205 | export { tasmotaGUILanguages, preselectedTasmotaGUILanguage }; 206 | -------------------------------------------------------------------------------- /src/components/AppStepper/VersionStep/VersionSelector.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import InputLabel from '@mui/material/InputLabel'; 4 | import FormControl from '@mui/material/FormControl'; 5 | import Select from '@mui/material/Select'; 6 | import TextField from '@mui/material/TextField'; 7 | import MenuItem from '@mui/material/MenuItem'; 8 | import { FormattedMessage } from 'react-intl'; 9 | 10 | function VersionSelector(props) { 11 | const { name, classes, label, value, onChange, items, preselectedTasmotaGUILanguage } = props; 12 | 13 | const inProps = { 14 | name, 15 | id: `${name}-id`, 16 | }; 17 | 18 | return ( 19 | // 20 | // {label} 21 | // 50 | // 51 | ); 52 | } 53 | 54 | VersionSelector.propTypes = { 55 | name: PropTypes.string.isRequired, 56 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 57 | label: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired, 58 | value: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired, 59 | items: PropTypes.oneOfType([PropTypes.array]).isRequired, 60 | onChange: PropTypes.func.isRequired, 61 | preselectedTasmotaGUILanguage: PropTypes.string, 62 | }; 63 | 64 | export default VersionSelector; 65 | -------------------------------------------------------------------------------- /src/components/AppStepper/VersionStep/VersionStep.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Step from '@mui/material/Step'; 4 | import StepLabel from '@mui/material/StepLabel'; 5 | import StepContent from '@mui/material/StepContent'; 6 | import Typography from '@mui/material/Typography'; 7 | import Box from '@mui/material/Box'; 8 | import CircularProgress from '@mui/material/CircularProgress'; 9 | import { FormattedMessage } from 'react-intl'; 10 | 11 | import BackButton from '../BackButton'; 12 | import CompileButton from '../CompileButton'; 13 | import VersionSelector from './VersionSelector'; 14 | import { tasmotaGUILanguages, preselectedTasmotaGUILanguage } from './Variables/Languages'; 15 | 16 | class VersionStep extends Component { 17 | constructor(props) { 18 | super(props); 19 | 20 | this.state = { 21 | tasmotaVersion: 'development', 22 | MY_LANGUAGE: preselectedTasmotaGUILanguage, 23 | message: '', 24 | }; 25 | 26 | this.handleChange = this.handleChange.bind(this); 27 | this.handleCompile = this.handleCompile.bind(this); 28 | this.handleBack = this.handleBack.bind(this); 29 | } 30 | 31 | handleChange(event) { 32 | this.setState({ [event.target.name]: event.target.value }); 33 | } 34 | 35 | handleCompile() { 36 | const { compileHandler } = this.props; 37 | compileHandler({ version: this.state }); 38 | } 39 | 40 | handleBack() { 41 | const { backHandler } = this.props; 42 | backHandler(); 43 | } 44 | 45 | componentDidUpdate(prevProps, prevState) { 46 | const { repoTags } = this.props; 47 | if (repoTags.length !== prevProps.repoTags.length) { 48 | this.setState({ 49 | tasmotaVersion: repoTags[repoTags.length - 1], 50 | }); 51 | } 52 | } 53 | 54 | render() { 55 | const { message, tasmotaVersion, MY_LANGUAGE } = this.state; 56 | 57 | const { classes, backHandler, repoTags, compiling, compileHandler, ...other } = this.props; 58 | 59 | return ( 60 | 61 | 0 && other.active} classes={{ label: classes.stepLabel }}> 62 | 63 | 64 | 65 | 66 | 67 | 68 |
69 | } 74 | onChange={this.handleChange} 75 | classes={classes} 76 | /> 77 | } 82 | onChange={this.handleChange} 83 | classes={classes} 84 | preselectedTasmotaGUILanguage={preselectedTasmotaGUILanguage} 85 | /> 86 | 87 |
88 |
89 | 90 |
91 |
92 | 93 | {compiling && } 94 |
95 |
96 | {message && ( 97 | 98 | Error: 99 | {message} 100 | 101 | )} 102 |
103 |
104 | ); 105 | } 106 | } 107 | 108 | VersionStep.propTypes = { 109 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 110 | repoTags: PropTypes.oneOfType([PropTypes.array]).isRequired, 111 | compiling: PropTypes.bool.isRequired, 112 | compileHandler: PropTypes.func.isRequired, 113 | backHandler: PropTypes.func.isRequired, 114 | }; 115 | 116 | export default VersionStep; 117 | -------------------------------------------------------------------------------- /src/components/AppStepper/WifiStep.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Step from '@mui/material/Step'; 4 | import StepLabel from '@mui/material/StepLabel'; 5 | import StepContent from '@mui/material/StepContent'; 6 | import FormControlLabel from '@mui/material/FormControlLabel'; 7 | import Checkbox from '@mui/material/Checkbox'; 8 | import Typography from '@mui/material/Typography'; 9 | 10 | import NextButton from './NextButton'; 11 | import ClearButton from './ClearButton'; 12 | import BackButton from './BackButton'; 13 | import TextFieldComponent from './TextFieldComponent'; 14 | import InputAdornment from '@mui/material/InputAdornment'; 15 | import IconButton from '@mui/material/IconButton'; 16 | import Visibility from '@mui/icons-material/Visibility'; 17 | import VisibilityOff from '@mui/icons-material/VisibilityOff'; 18 | import { FormattedMessage } from 'react-intl'; 19 | 20 | class WifiStep extends Component { 21 | constructor(props) { 22 | super(props); 23 | this.state = { 24 | STA_SSID1: '', 25 | STA_PASS1: '', 26 | WIFI_IP_ADDRESS: '', 27 | WIFI_SUBNETMASK: '', 28 | WIFI_GATEWAY: '', 29 | WIFI_DNS: '', 30 | showPassword: false, 31 | staticIPEnabled: false, 32 | }; 33 | 34 | if (localStorage.getItem('network') !== null) { 35 | this.state = JSON.parse(window.localStorage.getItem('network')); 36 | // do not show password per default, ever 37 | this.state.showPassword = false; 38 | } 39 | 40 | this.handleChange = this.handleChange.bind(this); 41 | this.handleChangeCheckBox = this.handleChangeCheckBox.bind(this); 42 | this.handleNext = this.handleNext.bind(this); 43 | this.handleClear = this.handleClear.bind(this); 44 | this.handleBack = this.handleBack.bind(this); 45 | this.handleClickShowPassword = this.handleClickShowPassword.bind(this); 46 | this.handleMouseDownPassword = this.handleMouseDownPassword.bind(this); 47 | } 48 | 49 | handleChange(event) { 50 | this.setState({ [event.target.name]: event.target.value }); 51 | } 52 | 53 | handleChangeCheckBox(event) { 54 | // there is only one checkbox in this step 55 | this.setState({ 56 | staticIPEnabled: event.target.checked, 57 | WIFI_IP_ADDRESS: '', 58 | WIFI_SUBNETMASK: '', 59 | WIFI_GATEWAY: '', 60 | WIFI_DNS: '', 61 | }); 62 | } 63 | 64 | handleClickShowPassword(event) { 65 | this.setState({ showPassword: !this.state.showPassword }); 66 | } 67 | 68 | handleMouseDownPassword(event) { 69 | event.preventDefault(); 70 | } 71 | 72 | handleNext() { 73 | const { nextHandler } = this.props; 74 | window.localStorage.setItem('network', JSON.stringify(this.state)); 75 | 76 | nextHandler({ network: this.state }); 77 | } 78 | handleClear() { 79 | this.setState({ 80 | STA_SSID1: '', 81 | STA_PASS1: '', 82 | WIFI_IP_ADDRESS: '', 83 | WIFI_SUBNETMASK: '', 84 | WIFI_GATEWAY: '', 85 | WIFI_DNS: '', 86 | showPassword: false, 87 | staticIPEnabled: false, 88 | }); 89 | window.localStorage.removeItem('network'); 90 | } 91 | handleBack() { 92 | const { backHandler } = this.props; 93 | backHandler(); 94 | } 95 | 96 | render() { 97 | const { classes, backHandler, nextHandler, ...other } = this.props; 98 | 99 | const { 100 | STA_SSID1, 101 | STA_PASS1, 102 | staticIPEnabled, 103 | WIFI_IP_ADDRESS, 104 | WIFI_SUBNETMASK, 105 | WIFI_GATEWAY, 106 | WIFI_DNS, 107 | showPassword, 108 | } = this.state; 109 | 110 | return ( 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
120 |
121 | } 124 | classes={classes} 125 | value={STA_SSID1} 126 | onChange={this.handleChange} 127 | /> 128 | } 131 | classes={classes} 132 | type={showPassword ? 'text' : 'password'} 133 | value={STA_PASS1} 134 | onChange={this.handleChange} 135 | inputProps={{ 136 | endAdornment: ( 137 | 138 | 143 | {showPassword ? : } 144 | 145 | 146 | ), 147 | }} 148 | /> 149 |
150 |
151 | 159 | } 160 | label={} 161 | /> 162 |
163 | 164 | {staticIPEnabled && ( 165 |
166 | } 169 | classes={classes} 170 | value={WIFI_IP_ADDRESS} 171 | onChange={this.handleChange} 172 | /> 173 | } 176 | classes={classes} 177 | value={WIFI_SUBNETMASK} 178 | onChange={this.handleChange} 179 | /> 180 | } 183 | classes={classes} 184 | value={WIFI_GATEWAY} 185 | onChange={this.handleChange} 186 | /> 187 | } 190 | classes={classes} 191 | value={WIFI_DNS} 192 | onChange={this.handleChange} 193 | /> 194 |
195 | )} 196 |
197 |
198 |
199 | 200 |
201 |
202 | 203 |
204 |
205 | 206 |
207 |
208 |
209 |
210 | ); 211 | } 212 | } 213 | 214 | WifiStep.propTypes = { 215 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 216 | nextHandler: PropTypes.func.isRequired, 217 | backHandler: PropTypes.func.isRequired, 218 | }; 219 | 220 | export default WifiStep; 221 | -------------------------------------------------------------------------------- /src/components/DownloadLinks/DownloadLinks.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Typography from '@mui/material/Typography'; 4 | import Button from '@mui/material/Button'; 5 | import CloudDownloadIcon from '@mui/icons-material/CloudDownload'; 6 | import { FormattedMessage } from 'react-intl'; 7 | 8 | class DownloadLinks extends Component { 9 | constructor(props) { 10 | super(props); 11 | this.downloadLinksElement = React.createRef(); 12 | } 13 | 14 | componentDidMount() { 15 | // this.downloadLinksElement.current.scrollIntoView({ 16 | // block: 'end', 17 | // inline: 'nearest', 18 | // behavior: 'smooth' 19 | // }); 20 | this.downloadLinksElement.current.scrollIntoView(false); 21 | } 22 | 23 | render() { 24 | const { classes, features } = this.props; 25 | const isEsp8266 = features.board.chip_type === 'esp8266'; 26 | const isEsp32 = features.board.chip_type === 'esp32'; 27 | const envPath = features.board.platformio_env_name; 28 | 29 | return ( 30 |
31 |
32 | If TasmoCompiler is useful to You, please consider supporting the project: 33 | 34 | ko-fi 35 | 36 | 37 | github sponsor 38 | 39 | 40 | paypal 41 | 42 |
43 | 44 | 45 | 46 | 47 |
48 | 57 | {isEsp8266 && ( 58 | 67 | )} 68 | {isEsp32 && ( 69 | 78 | )} 79 | 88 | 97 |
98 |
99 | ); 100 | } 101 | } 102 | 103 | DownloadLinks.propTypes = { 104 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 105 | features: PropTypes.oneOfType([PropTypes.object]).isRequired, 106 | }; 107 | 108 | export default DownloadLinks; 109 | -------------------------------------------------------------------------------- /src/components/MessageBox/MessageBox.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import TextField from '@mui/material/TextField'; 4 | import { FormattedMessage } from 'react-intl'; 5 | 6 | class MessageBox extends Component { 7 | constructor(props) { 8 | super(props); 9 | this.messageBoxElement = React.createRef(); 10 | } 11 | 12 | componentDidUpdate() { 13 | this.messageBoxElement.current.scrollTop = this.messageBoxElement.current.scrollHeight; 14 | } 15 | 16 | render() { 17 | const { classes, compileMessages } = this.props; 18 | 19 | return ( 20 | } 23 | fullWidth 24 | multiline 25 | minRows={9} 26 | maxRows={9} 27 | className={classes.compileMessagesBox} 28 | value={compileMessages} 29 | variant='outlined' 30 | margin='normal' 31 | inputRef={this.messageBoxElement} 32 | InputProps={{ 33 | classes: { 34 | input: classes.inputFont, 35 | }, 36 | readOnly: true, 37 | }} 38 | /> 39 | ); 40 | } 41 | } 42 | 43 | MessageBox.propTypes = { 44 | // classes: PropTypes.object.isRequired, 45 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 46 | compileMessages: PropTypes.string.isRequired, 47 | }; 48 | 49 | export default MessageBox; 50 | -------------------------------------------------------------------------------- /src/components/TopAppBar/TopAppBar.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import AppBar from '@mui/material/AppBar'; 4 | import Toolbar from '@mui/material/Toolbar'; 5 | import Typography from '@mui/material/Typography'; 6 | import LanguageIcon from '@mui/icons-material/Language'; 7 | import GitHub from '@mui/icons-material/GitHub'; 8 | import Tooltip from '@mui/material/Tooltip'; 9 | import { FormattedMessage } from 'react-intl'; 10 | import { Menu, MenuItem } from '@mui/material'; 11 | import { allMessages } from '../../locales/languages'; 12 | 13 | class TopAppBar extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { version: '', anchorEl: null }; 17 | } 18 | 19 | componentDidMount() { 20 | fetch('/api/v1/tcversion') 21 | .then((res) => res.json()) 22 | .then((ret) => { 23 | this.setState({ version: `v${ret.version}` }); 24 | }) 25 | .catch((error) => { 26 | this.setState({ version: '' }); 27 | }); 28 | } 29 | 30 | handleOpen = (event) => { 31 | this.setState({ anchorEl: event.currentTarget }); 32 | }; 33 | 34 | handleClose = (lang, locale) => { 35 | if (lang && lang !== locale) { 36 | const { changeLanguage } = this.props; 37 | changeLanguage(lang); 38 | } 39 | this.setState({ anchorEl: null }); 40 | }; 41 | 42 | render() { 43 | const { classes, locale, changeLanguage, ...other } = this.props; 44 | const { version, anchorEl } = this.state; 45 | 46 | return ( 47 |
48 | {/* */} 49 | 50 | 51 | 52 | TasmoCompiler {version} 53 | 54 | 55 |
56 | }> 57 |
58 | 59 | 60 | 61 |
62 |
63 |
72 | 73 | {allMessages[locale].nativeName} 74 | 75 | 76 |
77 |
78 | this.handleClose()} 84 | anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} 85 | transformOrigin={{ vertical: 'top', horizontal: 'right' }} 86 | > 87 | {Object.keys(allMessages) 88 | .sort() 89 | .map((lang) => { 90 | return ( 91 | this.handleClose(lang, locale)} key={lang} selected={locale === lang}> 92 | 93 |
{allMessages[lang].nativeName}
94 |
95 | ); 96 | })} 97 |
98 |
99 |
100 |
101 | ); 102 | } 103 | } 104 | 105 | TopAppBar.propTypes = { 106 | classes: PropTypes.oneOfType([PropTypes.object]).isRequired, 107 | locale: PropTypes.string.isRequired, 108 | changeLanguage: PropTypes.func.isRequired, 109 | }; 110 | 111 | export default TopAppBar; 112 | -------------------------------------------------------------------------------- /src/components/TopAppBar/__test__/TopAppBar.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { rest } from 'msw'; 3 | import { setupServer } from 'msw/node'; 4 | import { 5 | render, 6 | fireEvent, 7 | waitFor, 8 | screen, 9 | getByTestId, 10 | } from '@testing-library/react'; 11 | import TopAppBar from '../TopAppBar'; 12 | import { allMessages } from '../../../locales/languages'; 13 | 14 | const expectedVersion = '6.0.2'; 15 | 16 | const server = setupServer( 17 | rest.get('/api/v1/tcversion', (req, res, ctx) => { 18 | return res(ctx.json({ ok: true, version: expectedVersion })); 19 | }) 20 | ); 21 | 22 | let supportedLocales = []; 23 | for (const l in allMessages) { 24 | supportedLocales.push(...allMessages[l].browserLang); 25 | } 26 | 27 | // hack until we can upgrade to react@16.9.0 28 | // https://github.com/testing-library/react-testing-library/issues/459 29 | const originalError = console.error; 30 | 31 | beforeAll(() => { 32 | // this is here to silence a warning temporarily 33 | // we'll fix it in the next exercise 34 | jest.spyOn(console, 'error').mockImplementation((...args) => { 35 | if ( 36 | typeof args[0] === 'string' && 37 | args[0].includes('Please upgrade to at least react-dom@16.9.0') 38 | ) { 39 | return; 40 | } 41 | return originalError.call(console, args); 42 | }); 43 | 44 | server.listen(); 45 | }); 46 | 47 | afterEach(() => server.resetHandlers()); 48 | afterAll(() => { 49 | console.error.mockRestore(); 50 | server.close(); 51 | }); 52 | 53 | it('should render TasmoCompiler version for language', async () => { 54 | const ret = render( 55 | {}} /> 56 | ); 57 | const regex = new RegExp(`${expectedVersion}`); 58 | const titleElement = await screen.findByText(regex); 59 | // console.log(titleElement); 60 | // screen.debug(); 61 | expect(titleElement).toBeInTheDocument; 62 | }); 63 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 5 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | font-display: 'swap'; 10 | } 11 | 12 | code { 13 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 14 | monospace; 15 | } 16 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('root') 10 | ); 11 | 12 | // If you want your app to work offline and load faster, you can change 13 | // unregister() to register() below. Note this comes with some pitfalls. 14 | // Learn more about service workers: https://bit.ly/CRA-PWA 15 | serviceWorker.unregister(); 16 | -------------------------------------------------------------------------------- /src/locales/__test__/locale.test.js: -------------------------------------------------------------------------------- 1 | import { allMessages, defaultLanguage } from '../languages'; 2 | const baseTranslationKeys = Object.keys( 3 | allMessages[defaultLanguage].source 4 | ).sort(); 5 | 6 | let translations = []; 7 | Object.keys(allMessages).forEach((l) => { 8 | if (l !== defaultLanguage) { 9 | translations.push([l, defaultLanguage, '']); 10 | } 11 | }); 12 | 13 | describe('locales test', () => { 14 | it.each(translations)( 15 | 'transalation %s should have the same amount of keys as base translation (%s)', 16 | (trans, base, expected) => { 17 | let otherTranslationKeys = Object.keys(allMessages[trans].source).sort(); 18 | 19 | expect(otherTranslationKeys.length).toBe(baseTranslationKeys.length); 20 | } 21 | ); 22 | 23 | it.each(translations)( 24 | 'transalation %s should have same translations as base translation (%s)', 25 | (trans, base, expected) => { 26 | let otherTranslationKeys = Object.keys(allMessages[trans].source).sort(); 27 | 28 | expect(otherTranslationKeys).toEqual( 29 | expect.arrayContaining(baseTranslationKeys) 30 | ); 31 | } 32 | ); 33 | }); 34 | -------------------------------------------------------------------------------- /src/locales/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Zdrojový kód Tasmota", 4 | "stepSourceDescRefresh": "Zdrojový kód můžete aktualizovat na nejnovějšíh verzi nebo přejít na další krok kliknutím na tlačítko DALŠÍ", 5 | "stepSourceDescDownload": "Než přejdete na další krok, musíte stáhnout zdrojový kód Tasmota", 6 | 7 | "btnDownloadSrc": "Stažení zdrojového kódu", 8 | "btnRefreshSrc": "Aktualizace zdrojového kódu", 9 | "btnNext": "Další", 10 | "btnClear": "Clear", 11 | "btnBack": "Zpět", 12 | "btnCompile": "Kompilace", 13 | 14 | "stepWifiConfTitle": "Konfigurace WiFi", 15 | "stepWifiConfDesc": "Zadejte SSID a heslo pro vaší WiFi síť", 16 | "stepWifiConfStaticIP": "Pevná IP", 17 | "stepWifiConfSSID": "Wifi SSID", 18 | "stepWifiConfPassword": "WiFi heslo", 19 | "stepWifiConfIP": "IP adresa", 20 | "stepWifiConfMask": "Maska", 21 | "stepWifiConfGateway": "Brána", 22 | "stepWifiConfDNS": "DNS server", 23 | 24 | "stepFeaturesTitle": "Výběr funkcí", 25 | "stepFeaturesBoardDesc": "Select board your project is based on", 26 | "stepFeaturesBoard8266Tooltip": "This is probably board you should choose", 27 | "stepFeaturesBoard82662MTooltip": "Zařízení založená na Shelly s 2MB Flash pamětí", 28 | "stepFeaturesBoard82664MTooltip": "4MB ESP8266 boards like Wemos D1 Mini, NodeMCU, ESP12F, etc..", 29 | "stepFeaturesDesc": "Jaké funkce chcete zahrnout do výsledného binárního FW?", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Senzory Vzduch/plyn", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino slave", 34 | "stepFeaturesArduinoSlaveTooltip": "Přidat podporu pro externí slave mikrokontroléru v sériovém režimu", 35 | "stepFeaturesDisplaysDesc": "Display (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Přidat podporu pro I2C a SPI diplaye", 37 | "stepFeaturesDispVccDesc": "Display Vcc", 38 | "stepFeaturesDispVccTooltip": "Zakázat použití Analogového vstupu", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Senzory energie", 41 | "stepFeaturesTempHumDesc": "Temp/Hum sensors", 42 | "stepFeaturesLightDesc": "Light sensors", 43 | "stepFeaturesLightTooltip": "Light intensity, light level, UV Index, etc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "Expandér portů IO", 46 | "stepFeaturesIOExpMCPTooltip": "Přidat podporu pro Input/Output pin expander: MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "Základní IR", 49 | "stepFeaturesIRBasicTooltip": "Základní podpora IR (menší binární a paměťové využití). Vylučuje použití plné IR podpory.", 50 | "stepFeaturesIRFullDesc": "IR support", 51 | "stepFeaturesIRFullTooltip": "Full infrared support", 52 | "stepFeaturesMDNSDesc": "mDNS discovery", 53 | "stepFeaturesMQTTTLSDesc": "MQTT přes TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Tato funkce bude fungovat s verzí 6.6.0.9 nebo novější (vč. nejnovější vývojové verze).", 55 | "stepFeaturesRFTransceiverDesc": "RF vysílač", 56 | "stepFeaturesRFTransceiverTooltip": "Podpora pro RF vysílače pomocí knihovny RcSwitch", 57 | "stepFeaturesRulesDesc": "Pravidla", 58 | "stepFeaturesRulesTooltip": "It includes IF STATEMENT and EXPRESSION. Rules exclude the use of scripts.", 59 | "stepFeaturesScriptDesc": "Skript", 60 | "stepFeaturesScriptTooltip": "Skript vylučuje použití pravidel", 61 | "stepFeaturesTimersDesc": "Časovače", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Distance sensors", 64 | "stepFeaturesWebInterfaceDesc": "Webové rozhraní", 65 | "stepFeaturesWebInterfaceTooltip": "Pro většinu uživatelů by toto mělo být povoleno. Zakažte v případě, že potřebujete menší velikost binárního FW a paměťově méně náročné využití. Pokud je zakázáno, bude interakce s firmwarem Tasmota možná pouze prostřednictvím zprostředkovatele MQTT.", 66 | "stepFeaturesWS2812Desc": "WS2812 Ledky", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Enable serial communication with Zigbee CC2530 flashed with ZNP or EFR32 EmberZNet devices (like Sonoff Zigbee Bridge) flashed with EZSP", 69 | "stepFeaturesUFSDesc": "SD card/LittleFS", 70 | "stepFeaturesUFSTooltip": "Enable driver for Universal File System", 71 | "stepFeaturesBerryDesc": "Berry scripting", 72 | "stepFeaturesBerryTooltip": "Add support for Berry scripting language", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Add ble and ble-bridge support", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Shutters and Blinds", 77 | "stepFeaturesI2CDesc": "Podpora I2C", 78 | "stepFeaturesSPIDesc": "Podpora SPI", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Vlastní parametry", 85 | "stepCustomParamsDesc": "Níže můžete zadat vlastní parametry, které budou zahrnuty na konec souboru {filename}. Pokud nevíte, o co se jedná, stačí kliknout na Další.", 86 | 87 | "stepVersionTitle": "Vyberte verzi a zkompilujte", 88 | "stepVersionDesc": "Select Tasmota version and language.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Verze Tasmota", 91 | "stepVersionLanguage": "Jazyk", 92 | 93 | "stepDownload": "You can now download custom compiled binary and files used during compilation:", 94 | 95 | "Afrikaans": "Afrikaans", 96 | "English": "Angličtina", 97 | "Bulgarian": "Bulharština", 98 | "Czech": "Čeština", 99 | "German": "Němčina", 100 | "Greek": "Řečtina", 101 | "Spanish": "Španělština", 102 | "French": "Francouzština", 103 | "Hebrew": "Hebrejština", 104 | "Hungarian": "Maďarština", 105 | "Italian": "Italština", 106 | "Korean": "Korejština", 107 | "Dutch": "Holandština", 108 | "Polish": "Polština", 109 | "Portuguese (Brazil)": "Portugalština (Brazílie)", 110 | "Portuguese": "Portugalština", 111 | "Romanian": "Romanian", 112 | "Russian": "Ruština", 113 | "Slovak": "Slovenština", 114 | "Swedish": "Švédština", 115 | "Turkish": "Turečtina", 116 | "Ukrainian": "Ukrajinština", 117 | "Chinese (Simplified)": "Čínština (Zjednodušená)", 118 | "Chinese (Traditional)": "Čínština (Tradiční)", 119 | "Vietnam": "Vietnam", 120 | "Frisian": "Frisian", 121 | 122 | "stepVersionCompProgress": "Průběh kompilace", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Tasmota Quellcode", 4 | "stepSourceDescRefresh": "Du kannst den Quellcode auf die neuste Version aktualisieren oder klick auf Weiter für den nächsten Schritt", 5 | "stepSourceDescDownload": "Bevor du zum nächsten Schritt übergehst, musst du den Quellcode von Tasmota herunterladen", 6 | 7 | "btnDownloadSrc": "Quellcode herunterladen", 8 | "btnRefreshSrc": "Quellcode aktualisieren", 9 | "btnNext": "Weiter", 10 | "btnClear": "Löschen", 11 | "btnBack": "Zurück", 12 | "btnCompile": "Kompilieren", 13 | 14 | "stepWifiConfTitle": "WiFi Einstellungen", 15 | "stepWifiConfDesc": "Gebe die SSID und das Password für dein WiFi Netzwerk ein", 16 | "stepWifiConfStaticIP": "Statische IP", 17 | "stepWifiConfSSID": "WiFi SSID", 18 | "stepWifiConfPassword": "WiFi Passwort", 19 | "stepWifiConfIP": "IP Adresse", 20 | "stepWifiConfMask": "Netzmaske", 21 | "stepWifiConfGateway": "Gateway", 22 | "stepWifiConfDNS": "DNS Server", 23 | 24 | "stepFeaturesTitle": "Wähle die Funktionen", 25 | "stepFeaturesBoardDesc": "Wähle die Hardware, auf dem dein Projekt basiert", 26 | "stepFeaturesBoard8266Tooltip": "Das ist vermutlich das Board, welches Du verwenden solltest", 27 | "stepFeaturesBoard82662MTooltip": "Shelly Geräte mit 2MB Flash Speicher", 28 | "stepFeaturesBoard82664MTooltip": "4MB ESP8266 basierend z.B. Wemos D1 Mini, NodeMCU, ESP12F, etc.", 29 | "stepFeaturesDesc": "Welche Funktionen sollen in der Firmware enthalten sein?", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Luft/ Gas Sensoren", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino Klient", 34 | "stepFeaturesArduinoSlaveTooltip": "Support für externen Microcontroller über Serial Port", 35 | "stepFeaturesDisplaysDesc": "Displays (I2C/ SPI)", 36 | "stepFeaturesDisplaysTooltip": "Unterstützung für I2C und SPI Displays hinzufügen", 37 | "stepFeaturesDispVccDesc": "Anzeige Versorgungsspannung", 38 | "stepFeaturesDispVccTooltip": "Muss deaktiviert werden, um den analogen Eingang nutzen zu können", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Stromsensoren", 41 | "stepFeaturesTempHumDesc": "Temperatur/ Luftfeuchtigkeitssensoren", 42 | "stepFeaturesLightDesc": "Lichtsensoren", 43 | "stepFeaturesLightTooltip": "Helligkeit, Intensität, UV Werte etc", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "I/O Erweiterungsboard", 46 | "stepFeaturesIOExpMCPTooltip": "Fügt Unterstützung für Eingang/ Ausgangserweiterungsplatinen (MCP230xx) hinzu", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR Grundfunktionen", 49 | "stepFeaturesIRBasicTooltip": "Grundfunktionen für Infrarot (kleinere Binärdatei und weniger Speicherbedarf). Deaktivieren, um die volle IR Unterstützung zu erhalten", 50 | "stepFeaturesIRFullDesc": "IR Unterstützung", 51 | "stepFeaturesIRFullTooltip": "Vollständige Infrarot Unterstützung", 52 | "stepFeaturesMDNSDesc": "mDNS Discovery", 53 | "stepFeaturesMQTTTLSDesc": "MQTT mit TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Dieses Feature benötigt Version 6.6.0.9 oder neuer", 55 | "stepFeaturesRFTransceiverDesc": "RF-Transceiver", 56 | "stepFeaturesRFTransceiverTooltip": "Unterstützung für RF-Transceiver (nutzt die RcSwitch Bibliothek)", 57 | "stepFeaturesRulesDesc": "Regeln", 58 | "stepFeaturesRulesTooltip": "Beinhaltet die IF STATEMENT und EXPRESSION. Regeln schließen die Unterstützung für Skripte aus.", 59 | "stepFeaturesScriptDesc": "Skript", 60 | "stepFeaturesScriptTooltip": "Skript schließen die Unterstützung von Regeln aus.", 61 | "stepFeaturesTimersDesc": "Timers", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Abstandssensoren", 64 | "stepFeaturesWebInterfaceDesc": "Web Interface", 65 | "stepFeaturesWebInterfaceTooltip": "Für die meisten Benutzer sollte dies aktiviert sein. Deaktivieren, wenn eine kleinere Binärdatei und weniger Speicherbedarf benötigt wird. Wenn deaktiviert, kann nur per MQTT mit der Firmware interagiert werden.", 66 | "stepFeaturesWS2812Desc": "WS2812 LEDs", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Aktiviert serielle Kommunikation mit Zigbee CC2530 Geräten, die mit ZNP geflashed wurden oder EFR32 EmberZNet Geräten (wie die Sonoff Zigbee Bridge), die mit EZSP geflashed wurden", 69 | "stepFeaturesUFSDesc": "SD Karte/ LittleFS", 70 | "stepFeaturesUFSTooltip": "Aktiviere Treiber für das Universal File System (UFS)", 71 | "stepFeaturesBerryDesc": "Berry-Skripte", 72 | "stepFeaturesBerryTooltip": "Unterstützung für Berry-Skriptsprache", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Fügt Bluetooth Low Energy und BLE-Bridge Support hinzu", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Shutters and Blinds", 77 | "stepFeaturesI2CDesc": "I2C Unterstützung", 78 | "stepFeaturesSPIDesc": "SPI Unterstützung", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Zusätzliche Parameter", 85 | "stepCustomParamsDesc": "Unterhalb kannst du individuelle Parameter eintragen, die am Ende der {filename} eingefügt werden. Wenn du nicht weisst, was das ist, klicke einfach Weiter.", 86 | 87 | "stepVersionTitle": "Wähle die Version und Erstelle", 88 | "stepVersionDesc": "Wähle die Tasmota Version und die Sprache.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Tasmota Version", 91 | "stepVersionLanguage": "Sprache", 92 | 93 | "stepDownload": "Dateien die zum Erstellen der Firmware benutzt wurden und die Binary herunterladen:", 94 | 95 | "Afrikaans": "Afrikanisch", 96 | "English": "Englisch", 97 | "Bulgarian": "Bulgarisch", 98 | "Czech": "Tschechisch", 99 | "German": "Deutsch", 100 | "Greek": "Griechisch", 101 | "Spanish": "Spanisch", 102 | "French": "Französisch", 103 | "Hebrew": "Hebräisch", 104 | "Hungarian": "Ungarisch", 105 | "Italian": "Italienisch", 106 | "Korean": "Koreanisch", 107 | "Dutch": "Niederländisch", 108 | "Polish": "Polnisch", 109 | "Portuguese (Brazil)": "Portugiesisch (Brasilien)", 110 | "Portuguese": "Portugiesisch", 111 | "Romanian": "Rumänisch", 112 | "Russian": "Russisch", 113 | "Slovak": "Slowakisch", 114 | "Swedish": "Schwedisch", 115 | "Turkish": "Türkisch", 116 | "Ukrainian": "Ukrainisch", 117 | "Chinese (Simplified)": "Chinesisch (Einfach)", 118 | "Chinese (Traditional)": "Chinesische (Traditional)", 119 | "Vietnam": "Vietnamesisch", 120 | "Frisian": "Frisian", 121 | 122 | "stepVersionCompProgress": "Fortschritt der Kompilierung", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Tasmota source code", 4 | "stepSourceDescRefresh": "You can refresh source code to the latest state or click NEXT to go to the next step", 5 | "stepSourceDescDownload": "Before you go to the next step, you have to download Tasmota source code", 6 | 7 | "btnDownloadSrc": "Download source", 8 | "btnRefreshSrc": "Refresh source", 9 | "btnNext": "Next", 10 | "btnClear": "Clear", 11 | "btnBack": "Back", 12 | "btnCompile": "Compile", 13 | 14 | "stepWifiConfTitle": "WiFi configuration", 15 | "stepWifiConfDesc": "Enter SSID and password for your WiFi network", 16 | "stepWifiConfStaticIP": "Static IP", 17 | "stepWifiConfSSID": "Wifi SSID", 18 | "stepWifiConfPassword": "WiFi password", 19 | "stepWifiConfIP": "IP address", 20 | "stepWifiConfMask": "Netmask", 21 | "stepWifiConfGateway": "Gateway", 22 | "stepWifiConfDNS": "DNS server", 23 | 24 | "stepFeaturesTitle": "Select features", 25 | "stepFeaturesBoardDesc": "Select board your project is based on", 26 | "stepFeaturesBoard8266Tooltip": "This is probably board you should choose", 27 | "stepFeaturesBoard82662MTooltip": "Shelly-based devices with 2MB Flash memory", 28 | "stepFeaturesBoard82664MTooltip": "4MB ESP8266 boards like Wemos D1 Mini, NodeMCU, ESP12F, etc.", 29 | "stepFeaturesDesc": "Which features should be included in final binary firmware?", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Air/gas sensors", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino slave", 34 | "stepFeaturesArduinoSlaveTooltip": "Support for external microcontroller slave on serial", 35 | "stepFeaturesDisplaysDesc": "Displays (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Add support for I2C and SPI displays", 37 | "stepFeaturesDispVccDesc": "Display Vcc", 38 | "stepFeaturesDispVccTooltip": "Disable for use Analog input", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Energy sensors", 41 | "stepFeaturesTempHumDesc": "Temp/Hum sensors", 42 | "stepFeaturesLightDesc": "Light sensors", 43 | "stepFeaturesLightTooltip": "Light intensity, light level, UV Index, etc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "IO port expander", 46 | "stepFeaturesIOExpMCPTooltip": "Add support for Input/Output pin expander: MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR basic", 49 | "stepFeaturesIRBasicTooltip": "Basic infrared support (smaller binary and memory usage). Exclude the use of full infrared support.", 50 | "stepFeaturesIRFullDesc": "IR support", 51 | "stepFeaturesIRFullTooltip": "Full infrared support", 52 | "stepFeaturesMDNSDesc": "mDNS discovery", 53 | "stepFeaturesMQTTTLSDesc": "MQTT over TLS", 54 | "stepFeaturesMQTTTLSTooltip": "This feature will work with version 6.6.0.9 or later (latest development).", 55 | "stepFeaturesRFTransceiverDesc": "RF transceiver", 56 | "stepFeaturesRFTransceiverTooltip": "Support for RF transceiver using library RcSwitch", 57 | "stepFeaturesRulesDesc": "Rules", 58 | "stepFeaturesRulesTooltip": "It includes IF STATEMENT and EXPRESSION. Rules exclude the use of scripts.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "Script excludes the use of rules", 61 | "stepFeaturesTimersDesc": "Timers", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Distance sensors", 64 | "stepFeaturesWebInterfaceDesc": "Web interface", 65 | "stepFeaturesWebInterfaceTooltip": "For most users this should be enabled. Disable in case you need smaller binary and less memory usage. If disabled, interaction with Tasmota firmware will only be possible via MQTT broker.", 66 | "stepFeaturesWS2812Desc": "WS2812 Leds", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Enable serial communication with Zigbee CC2530 flashed with ZNP or EFR32 EmberZNet devices (like Sonoff Zigbee Bridge) flashed with EZSP", 69 | "stepFeaturesUFSDesc": "SD card/LittleFS", 70 | "stepFeaturesUFSTooltip": "Enable driver for Universal File System", 71 | "stepFeaturesBerryDesc": "Berry scripting", 72 | "stepFeaturesBerryTooltip": "Add support for Berry scripting language", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Add ble and ble-bridge support", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Shutters and Blinds", 77 | "stepFeaturesI2CDesc": "I2C support", 78 | "stepFeaturesSPIDesc": "SPI support", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Custom parameters", 85 | "stepCustomParamsDesc": "Below you can enter custom parameters, which will be included at the end of {filename} file. If you don't know what it is, just click Next.", 86 | 87 | "stepVersionTitle": "Select version and compile", 88 | "stepVersionDesc": "Select Tasmota version and language.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Tasmota version", 91 | "stepVersionLanguage": "Tasmota UI language", 92 | 93 | "stepDownload": "You can now download custom compiled binary and files used during compilation:", 94 | 95 | "Afrikaans": "Afrikaans", 96 | "English": "English", 97 | "Bulgarian": "Bulgarian", 98 | "Czech": "Czech", 99 | "German": "German", 100 | "Greek": "Greek", 101 | "Spanish": "Spanish", 102 | "French": "French", 103 | "Hebrew": "Hebrew", 104 | "Hungarian": "Hungarian", 105 | "Italian": "Italian", 106 | "Korean": "Korean", 107 | "Dutch": "Dutch", 108 | "Polish": "Polish", 109 | "Portuguese (Brazil)": "Portuguese (Brazil)", 110 | "Portuguese": "Portuguese", 111 | "Romanian": "Romanian", 112 | "Russian": "Russian", 113 | "Slovak": "Slovak", 114 | "Swedish": "Swedish", 115 | "Turkish": "Turkish", 116 | "Ukrainian": "Ukrainian", 117 | "Chinese (Simplified)": "Chinese (Simplified)", 118 | "Chinese (Traditional)": "Chinese (Traditional)", 119 | "Vietnam": "Vietnam", 120 | "Frisian": "Frisian", 121 | 122 | "stepVersionCompProgress": "Compiling progress", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Código fuente de Tasmota", 4 | "stepSourceDescRefresh": "Actualizar el código fuente a la última versión o pulsar en SIGUIENTE para ir al siguiente paso", 5 | "stepSourceDescDownload": "Antes de ir al siguiente paso, se debe que descargar el código fuente de Tasmota", 6 | 7 | "btnDownloadSrc": "Descargar código", 8 | "btnRefreshSrc": "Actualizar código", 9 | "btnNext": "Siguiente", 10 | "btnClear": "Limpiar", 11 | "btnBack": "Atrás", 12 | "btnCompile": "Compilar", 13 | 14 | "stepWifiConfTitle": "Configuración Wifi", 15 | "stepWifiConfDesc": "Introducir el Nombre y Contraseña de la red WiFi", 16 | "stepWifiConfStaticIP": "IP Estática", 17 | "stepWifiConfSSID": "Nombre Red WiFi", 18 | "stepWifiConfPassword": "Contraseña WiFi", 19 | "stepWifiConfIP": "Dirección IP", 20 | "stepWifiConfMask": "Máscara de Red", 21 | "stepWifiConfGateway": "Puerta de Enlace", 22 | "stepWifiConfDNS": "Servidor DNS", 23 | 24 | "stepFeaturesTitle": "Selecionar Características", 25 | "stepFeaturesBoardDesc": "Seleccionar el tipo de hardware a usar", 26 | "stepFeaturesBoard8266Tooltip": "Recomendado para todos los dispositivos con ESP8266.", 27 | "stepFeaturesBoard82662MTooltip": "Dispositivos basados en Shelly con memoria flash de 2MB", 28 | "stepFeaturesBoard82664MTooltip": "Solo para uso avanzado y solo para dispositivos con ESP8266 y 4MB como Wemos D1 Mini, NodeMCU, ESP12F, etc.", 29 | "stepFeaturesDesc": "¿Qué características desea que se incluyan en el firmware personalizado?", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Sensores Aire/Gas", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "MCU Secundario Arduino", 34 | "stepFeaturesArduinoSlaveTooltip": "Soporte para microcontrolador externo en serie", 35 | "stepFeaturesDisplaysDesc": "Pantallas (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Añade soporte para pantallas I2C y SPI", 37 | "stepFeaturesDispVccDesc": "Mostrar Vcc", 38 | "stepFeaturesDispVccTooltip": "Desactiva el uso de la entrada analógica", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Sensores Energía", 41 | "stepFeaturesTempHumDesc": "Sensores de Temp/Hum", 42 | "stepFeaturesLightDesc": "Sensores de Luz", 43 | "stepFeaturesLightTooltip": "Intensidad de Luz, Nivel de Luz, Índice UV, etc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "Expansor de I/O", 46 | "stepFeaturesIOExpMCPTooltip": "Añade soporte para expansores Entrada/Salida: MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR Básico", 49 | "stepFeaturesIRBasicTooltip": "Soporte infrarrojos básico (usa menos memoria y los firmwares son más pequeños). Excluye el soporte de infrarojos al completo.", 50 | "stepFeaturesIRFullDesc": "IR Completo", 51 | "stepFeaturesIRFullTooltip": "Soporte infrarrojos completo (usa más memoria y los firmwares son más grandes). Excluye el soporte de infrarrojos básico.", 52 | "stepFeaturesMDNSDesc": "Habilitar mDNS", 53 | "stepFeaturesMQTTTLSDesc": "MQTT con TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Esta característica solo funciona con la versión 6.6.0.9 o posterior.", 55 | "stepFeaturesRFTransceiverDesc": "Transceptor RF", 56 | "stepFeaturesRFTransceiverTooltip": "Soporte para el transceptor de RF usando la biblioteca RcSwitch", 57 | "stepFeaturesRulesDesc": "Reglas", 58 | "stepFeaturesRulesTooltip": "Incluye IF STATEMENT y EXPRESSIONS. El uso de Reglas excluye a Scripts.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "Script excluye el uso de las Reglas", 61 | "stepFeaturesTimersDesc": "Temporizadores", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Sensores de Distancia", 64 | "stepFeaturesWebInterfaceDesc": "Interfaz Web", 65 | "stepFeaturesWebInterfaceTooltip": "Para la mayoría de los usuarios esto debería estar habilitado. Deshabilitarlo en caso de que necesite firmwares más pequeños y menos uso de memoria. Si está desactivado, la interacción con Tasmota sólo será posible a través de MQTT.", 66 | "stepFeaturesWS2812Desc": "Leds WS2812", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Habilitar comunicación serie con el chip Zigbee CC2530. El CC2530 debe tener el firmware ZNP o EZSP.", 69 | "stepFeaturesUFSDesc": "SD card/LittleFS", 70 | "stepFeaturesUFSTooltip": "Habilitar Controlador para el sistema de archivos universal.", 71 | "stepFeaturesBerryDesc": "Berry Scripting", 72 | "stepFeaturesBerryTooltip": "Agregar soporte a lenguaje Berry", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Agregar soporte a Ble y Ble-Bridge", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Shutters and Blinds", 77 | "stepFeaturesI2CDesc": "Soporte a I2C", 78 | "stepFeaturesSPIDesc": "Soporte a SPI", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Parámetros Personalizados", 85 | "stepCustomParamsDesc": "A continuación puede introducir los parámetros opcionales personalizados, que se incluirán al final del archivo {filename}.", 86 | 87 | "stepVersionTitle": "Selección de versión", 88 | "stepVersionDesc": "Selecionar la versión de Tasmota y el idioma que se quiere usar.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Versión Tasmota", 91 | "stepVersionLanguage": "Idioma", 92 | 93 | "stepDownload": "Ahora puede descargar su version compilada y los archivos usados durante la compilación:", 94 | 95 | "Afrikaans": "Africano", 96 | "English": "Inglés", 97 | "Bulgarian": "Bulgaro", 98 | "Czech": "Checo", 99 | "German": "Alemán", 100 | "Greek": "Griego", 101 | "Spanish": "Español", 102 | "French": "Francés", 103 | "Hebrew": "Hebreo", 104 | "Hungarian": "Húngaro", 105 | "Italian": "Italiano", 106 | "Korean": "Coreano", 107 | "Dutch": "Holandés", 108 | "Polish": "Polaco", 109 | "Portuguese (Brazil)": "Portugués (Brasil)", 110 | "Portuguese": "Portugués", 111 | "Romanian": "Rumano", 112 | "Russian": "Ruso", 113 | "Slovak": "Eslovaco", 114 | "Swedish": "Sueco", 115 | "Turkish": "Turco", 116 | "Ukrainian": "Ucraniano", 117 | "Chinese (Simplified)": "Chino (Simplificado)", 118 | "Chinese (Traditional)": "Chino (Tradicional)", 119 | "Vietnam": "Vietnamita", 120 | "Frisian": "Frisian", 121 | 122 | "stepVersionCompProgress": "Progreso de la compilación", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Code source de Tasmota", 4 | "stepSourceDescRefresh": "Vous pouvez mettre à jour le code source ou cliquer sur SUIVANT pour passer à l'étape suivante.", 5 | "stepSourceDescDownload": "Avant de continuer, vous devez télécharger le code source de Tasmota", 6 | 7 | "btnDownloadSrc": "Télécharger le code source", 8 | "btnRefreshSrc": "Rafraîchir le code source", 9 | "btnNext": "Suivant", 10 | "btnClear": "Effacer", 11 | "btnBack": "Retour", 12 | "btnCompile": "Compiler", 13 | 14 | "stepWifiConfTitle": "Configuration Wi-Fi", 15 | "stepWifiConfDesc": "Entrez le SSID et la clé de votre réseau Wi-Fi", 16 | "stepWifiConfStaticIP": "IP statique", 17 | "stepWifiConfSSID": "SSID Wi-Fi", 18 | "stepWifiConfPassword": "Clé Wi-Fi", 19 | "stepWifiConfIP": "Adresse IP", 20 | "stepWifiConfMask": "Masque de sous-réseau", 21 | "stepWifiConfGateway": "Passerelle", 22 | "stepWifiConfDNS": "Serveur DNS", 23 | 24 | "stepFeaturesTitle": "Choisir les caractéristiques", 25 | "stepFeaturesBoardDesc": "Sélectionnez la carte de votre projet", 26 | "stepFeaturesBoard8266Tooltip": "Recommandé pour les appareils avec ESP8266", 27 | "stepFeaturesBoard82662MTooltip": "Dispositifs basés sur le Shelly avec 2 Mo de mémoire Flash", 28 | "stepFeaturesBoard82664MTooltip": "Uniquement pour les appareils avec ESP8266 et 4 Mo de mémoire Flash, comme Wemos D1 Mini, NodeMCU, ESP12F, etc.", 29 | "stepFeaturesDesc": "Quelles fonctionnalités voulez-vous inclure dans le firmware personnalisé ?", 30 | "stepFeaturesAGDesc": "Capteurs d'air/gaz", 31 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino esclave", 34 | "stepFeaturesArduinoSlaveTooltip": "Support de microcontrôleur esclave sur le port série", 35 | "stepFeaturesDisplaysDesc": "Afficheur (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Support pour les écrans I2C et SPI", 37 | "stepFeaturesDispVccDesc": "Affichage tension Vcc", 38 | "stepFeaturesDispVccTooltip": "Désactivé pour utiliser l'entrée analogique ADC", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Capteurs d'énergie", 41 | "stepFeaturesTempHumDesc": "Capteurs de température/humidité", 42 | "stepFeaturesLightDesc": "Capteurs de lumière", 43 | "stepFeaturesLightTooltip": "Intensité lumineuse, niveau de lumière, indice UV, etc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "Extension de port d'E/S", 46 | "stepFeaturesIOExpMCPTooltip": "Support pour l'extension de broches d'entrée/sortie : MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR de base", 49 | "stepFeaturesIRBasicTooltip": "Support infrarouge de base (binaire et utilisation de la mémoire plus légers). Exclut le support infrarouge complet.", 50 | "stepFeaturesIRFullDesc": "IR complet", 51 | "stepFeaturesIRFullTooltip": "Support infrarouge complet", 52 | "stepFeaturesMDNSDesc": "mDNS discovery", 53 | "stepFeaturesMQTTTLSDesc": "MQTT avec TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Cette fonctionnalité fonctionnera avec la version 6.6.0.9 ou ultérieure.", 55 | "stepFeaturesRFTransceiverDesc": "Émetteur-récepteur RF", 56 | "stepFeaturesRFTransceiverTooltip": "Support d'un émetteur-récepteur RF à l'aide de la bibliothèque RcSwitch", 57 | "stepFeaturesRulesDesc": "Règles", 58 | "stepFeaturesRulesTooltip": "Comprend IF et EXPRESSION. Les règles excluent l'utilisation de scripts.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "Le script exclut l'utilisation des règles", 61 | "stepFeaturesTimersDesc": "Minuteurs", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Capteurs de distance", 64 | "stepFeaturesWebInterfaceDesc": "Interface web", 65 | "stepFeaturesWebInterfaceTooltip": "Activé pour la plupart des utilisateurs. Si vous avez besoin d'un binaire plus petit et d'une utilisation moindre de la mémoire, désactivez-la. Si elle est désactivée, l'interaction avec le firmware de Tasmota ne sera possible que via le broker MQTT.", 66 | "stepFeaturesWS2812Desc": "DEL WS2812", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Activer la communication série avec Zigbee CC2530 flashé avec ZNP ou EFR32 EmberZNet (comme Sonoff Zigbee Bridge) flashé avec EZSP", 69 | "stepFeaturesUFSDesc": "Carte SD/LittleFS", 70 | "stepFeaturesUFSTooltip": "Activer le pilote pour le système de fichiers universel", 71 | "stepFeaturesBerryDesc": "Berry scripting", 72 | "stepFeaturesBerryTooltip": "Support pour le langage Berry scripting", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Support de BLE et passerelle BLE", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Volets et stores", 77 | "stepFeaturesI2CDesc": "Support I2C", 78 | "stepFeaturesSPIDesc": "Support SPI", 79 | "stepFeaturesModbusBridgeDesc": "Passerelle Modbus", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Paramètres personnalisés", 85 | "stepCustomParamsDesc": "Vous pouvez saisir ci-dessous des paramètres personnalisés, qui seront inclus à la fin du fichier {filename}. Si vous ne savez pas ce que c'est, cliquez sur Suivant..", 86 | 87 | "stepVersionTitle": "Sélectionnez la version et compilez", 88 | "stepVersionDesc": "Sélectionnez la version et la langue de Tasmota.", 89 | "stepVersionDevelopment": "Développement", 90 | "stepVersionTasmota": "Version de Tasmota", 91 | "stepVersionLanguage": "Langue de l'interface utilisateur Tasmota", 92 | 93 | "stepDownload": "Vous pouvez maintenant télécharger le binaire compilé personnalisé et les fichiers utilisés lors de la compilation :", 94 | 95 | "Afrikaans": "Afrikaans", 96 | "English": "Anglais", 97 | "Bulgarian": "Bulgare", 98 | "Czech": "Tchèque", 99 | "German": "Allemand", 100 | "Greek": "Grec", 101 | "Spanish": "Espagnol", 102 | "French": "Français", 103 | "Hebrew": "Hébreu", 104 | "Hungarian": "Hongrois", 105 | "Italian": "Italien", 106 | "Korean": "Coréen", 107 | "Dutch": "Néerlandais", 108 | "Polish": "Polonais", 109 | "Portuguese (Brazil)": "Portugais (Brésil)", 110 | "Portuguese": "Portugais", 111 | "Romanian": "Roumain", 112 | "Russian": "Russe", 113 | "Slovak": "Slovaque", 114 | "Swedish": "Suédois", 115 | "Turkish": "Turc", 116 | "Ukrainian": "Ukrainien", 117 | "Chinese (Simplified)": "Chinois (simplifié)", 118 | "Chinese (Traditional)": "Chinois (traditionnel)", 119 | "Vietnam": "Vietnamien", 120 | "Frisian": "Frison", 121 | 122 | "stepVersionCompProgress": "Avancement de la compilation", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Tasmota forráskód", 4 | "stepSourceDescRefresh": "Frissítheti a forráskódot a legújabb állapotra, vagy a TOVÁBB gombra kattintva folytathatja a következő lépést", 5 | "stepSourceDescDownload": "Mielőtt folytatná a következő lépést, le kell töltenie a Tasmota forráskódot", 6 | 7 | "btnDownloadSrc": "Forrás letöltése", 8 | "btnRefreshSrc": "Forrás frissítése", 9 | "btnNext": "Tovább", 10 | "btnClear": "Tisztít", 11 | "btnBack": "Vissza", 12 | "btnCompile": "Fordítás", 13 | 14 | "stepWifiConfTitle": "WiFi beállítások", 15 | "stepWifiConfDesc": "Írja be a WiFi hálózat SSID-jét és jelszavát", 16 | "stepWifiConfStaticIP": "Statikus IP", 17 | "stepWifiConfSSID": "WiFi SSID", 18 | "stepWifiConfPassword": "WiFi jelszó", 19 | "stepWifiConfIP": "IP cím", 20 | "stepWifiConfMask": "Alhálózati maszk", 21 | "stepWifiConfGateway": "Átjáró", 22 | "stepWifiConfDNS": "DNS kiszolgáló", 23 | 24 | "stepFeaturesTitle": "Jellemzők kiválasztás", 25 | "stepFeaturesBoardDesc": "Válassza ki a alaplapot, amelyre a projekt épül", 26 | "stepFeaturesBoard8266Tooltip": "Ez valószínűleg az az alaplap, amelyet választania kell", 27 | "stepFeaturesBoard82662MTooltip": "Shelly alapú eszközök 2MB flash memóriával", 28 | "stepFeaturesBoard82664MTooltip": "4MB ESP8266 alaplapok, például Wemos D1 Mini, NodeMCU, ESP12F, stb.", 29 | "stepFeaturesDesc": "Mely tulajdonságokat kell tartalmaznia a végleges bináris firmware-nek?", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Levegő / gáz érzékelők", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino kliens", 34 | "stepFeaturesArduinoSlaveTooltip": "Külső soros mikrokontroller támogatása.", 35 | "stepFeaturesDisplaysDesc": "Kijelzők (I2C / SPI)", 36 | "stepFeaturesDisplaysTooltip": "I2C és SPI kijelzők támogatása", 37 | "stepFeaturesDispVccDesc": "Vcc mód", 38 | "stepFeaturesDispVccTooltip": "Tiltsa le az analóg bemenet használatához.", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Energiaérzékelők", 41 | "stepFeaturesTempHumDesc": "Hőmérséklet / páratartalom érzékelők", 42 | "stepFeaturesLightDesc": "Fényérzékelők", 43 | "stepFeaturesLightTooltip": "Fényintenzitás, fényszint, UV-index stb.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "IO port bővítő", 46 | "stepFeaturesIOExpMCPTooltip": "Támogatás hozzáadása az MCP230xx Input / Output bővítőhöz.", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR alap", 49 | "stepFeaturesIRBasicTooltip": "Alapvető infravörös támogatás (kisebb bináris és memóriahasználat). Kizárja a teljes IR támogatás használatát.", 50 | "stepFeaturesIRFullDesc": "IR támogatás", 51 | "stepFeaturesIRFullTooltip": "Teljes infravörös támogatás", 52 | "stepFeaturesMDNSDesc": "mDNS felfedezés", 53 | "stepFeaturesMQTTTLSDesc": "MQTT TLS-en keresztül", 54 | "stepFeaturesMQTTTLSTooltip": "Ez a szolgáltatás a 6.6.0.9 vagy újabb verzióval (legújabb fejlesztés) fog működni.", 55 | "stepFeaturesRFTransceiverDesc": "RF adó-vevő", 56 | "stepFeaturesRFTransceiverTooltip": "RF adó-vevők támogatása az RcSwitch könyvtár használatával.", 57 | "stepFeaturesRulesDesc": "Szabályok", 58 | "stepFeaturesRulesTooltip": "Ez magában foglalja a feltételek és kifejezések használatát. Kizárja a szkriptek használatát.", 59 | "stepFeaturesScriptDesc": "Szkriptek", 60 | "stepFeaturesScriptTooltip": "Kizárja a szabályok használatát", 61 | "stepFeaturesTimersDesc": "Időzítők", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Távolságérzékelők", 64 | "stepFeaturesWebInterfaceDesc": "Web felület", 65 | "stepFeaturesWebInterfaceTooltip": "A legtöbb felhasználónál ezt engedélyezni kell. Tiltsa le, ha kisebb bináris és kevesebb memória használatra van szüksége. Ha le van tiltva, akkor a Tasmota firmware-rel való interakció csak az MQTT szerveren keresztül lehetséges.", 66 | "stepFeaturesWS2812Desc": "WS2812 LEDek", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Soros kommunikáció engedélyezése Zigbee CC2530-al ZNP firmware-rel vagy EFR32 EmberZNet eszközök (például Sonoff Zigbee Bridge) EZSP firmware-rel", 69 | "stepFeaturesUFSDesc": "SD kártya / LittleFS", 70 | "stepFeaturesUFSTooltip": "UFS támogatás engedélyezése", 71 | "stepFeaturesBerryDesc": "Berry szkriptek", 72 | "stepFeaturesBerryTooltip": "Berry szkriptnyelv támogatása", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "BLE és BLE átjáró támogatás", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Shutters and Blinds", 77 | "stepFeaturesI2CDesc": "I2C támogatás", 78 | "stepFeaturesSPIDesc": "SPI támogatás", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Egyéni paraméterek", 85 | "stepCustomParamsDesc": "Az alábbiakban megadhat egyéni paramétereket, amelyek a {filename} fájl végén lesznek. Ha nem tudja, mi ez, kattintson a Tovább gombra.", 86 | 87 | "stepVersionTitle": "Verzió kiválasztása és lefordítása", 88 | "stepVersionDesc": "Válassza ki a Tasmota verziót és nyelvet.", 89 | "stepVersionDevelopment": "Fejlesztői", 90 | "stepVersionTasmota": "Tasmota verzió", 91 | "stepVersionLanguage": "Nyelv", 92 | 93 | "stepDownload": "Most már letöltheti a bináris firmware fájlt és a fordítás során használt fájlokat:", 94 | 95 | "Afrikaans": "Afrikaans (Búr)", 96 | "English": "Angol", 97 | "Bulgarian": "Bolgár", 98 | "Czech": "Cseh", 99 | "German": "Német", 100 | "Greek": "Görög", 101 | "Spanish": "Spanyol", 102 | "French": "Francia", 103 | "Hebrew": "Héber", 104 | "Hungarian": "Magyar", 105 | "Italian": "Olasz", 106 | "Korean": "Koreai", 107 | "Dutch": "Holland", 108 | "Polish": "Lengyel", 109 | "Portuguese (Brazil)": "Portugál (Brazil)", 110 | "Portuguese": "Portugál", 111 | "Romanian": "Román", 112 | "Russian": "Orosz", 113 | "Slovak": "Szlovák", 114 | "Swedish": "Svéd", 115 | "Turkish": "Török", 116 | "Ukrainian": "Ukrán", 117 | "Chinese (Simplified)": "Kínai (Egyszerűsített)", 118 | "Chinese (Traditional)": "Kínai (Hagyományos)", 119 | "Vietnam": "Vietnámi", 120 | "Frisian": "Fríz", 121 | 122 | "stepVersionCompProgress": "Fordítás állapota", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Pagina progetto su Github", 3 | "stepSourceTitle": "Codice sorgente Tasmota", 4 | "stepSourceDescRefresh": "Puoi aggiornare il codice sorgente alla versione più recente o selezionare 'Avanti' per andare allo step successivo", 5 | "stepSourceDescDownload": "Prima di passare allo step successivo scarica il codice sorgente Tasmota", 6 | 7 | "btnDownloadSrc": "Download codice sorgente", 8 | "btnRefreshSrc": "Aggiorna codice sorgente", 9 | "btnNext": "Avanti", 10 | "btnClear": "Azzera", 11 | "btnBack": "Indietro", 12 | "btnCompile": "Compila", 13 | 14 | "stepWifiConfTitle": "Configurazione WiFi", 15 | "stepWifiConfDesc": "Inserisci SSID e password della rete WiFi", 16 | "stepWifiConfStaticIP": "IP statico", 17 | "stepWifiConfSSID": "SSID", 18 | "stepWifiConfPassword": "Password", 19 | "stepWifiConfIP": "Indirizzo IP", 20 | "stepWifiConfMask": "Maschera rete", 21 | "stepWifiConfGateway": "Gateway", 22 | "stepWifiConfDNS": "Server DNS", 23 | 24 | "stepFeaturesTitle": "Selezione funzionalità", 25 | "stepFeaturesBoardDesc": "Seleziona il tipo di scheda su cui è basato il progetto", 26 | "stepFeaturesBoard8266Tooltip": "Questa è molto probabilmente la scheda che dovresti scegliere", 27 | "stepFeaturesBoard82662MTooltip": "Dispositivi basati su Shelly con 2MB di memoria flash", 28 | "stepFeaturesBoard82664MTooltip": "Scheda ESP8266 4MB come Wemos D1 Mini, NodeMCU, ESP12F, ecc..", 29 | "stepFeaturesDesc": "Quali funzionalità vuoi includere nel firmware?", 30 | "stepFeaturesDescriptionLinkTooltip": "Descrizione gruppo di funzioni", 31 | "stepFeaturesAGDesc": "Sensori aria/gas", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino (slave)", 34 | "stepFeaturesArduinoSlaveTooltip": "Supporto micro controller slave esterno su seriale", 35 | "stepFeaturesDisplaysDesc": "Display (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Supporto display I2C/SPI", 37 | "stepFeaturesDispVccDesc": "Display Vcc", 38 | "stepFeaturesDispVccTooltip": "Disabilitalo per ingresso analogico", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Sensori energia", 41 | "stepFeaturesTempHumDesc": "Sensori temperatura/umidità", 42 | "stepFeaturesLightDesc": "Sensori luci", 43 | "stepFeaturesLightTooltip": "Intensità luce, livello luce, indice UV, ecc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "Espansione porte I/O", 46 | "stepFeaturesIOExpMCPTooltip": "Supporto per espansione PIN input/output: MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR (base)", 49 | "stepFeaturesIRBasicTooltip": "Supporto base infrarossi (file binario e occupazione memoria più bassa). Non include il supporto infrarossi completo.", 50 | "stepFeaturesIRFullDesc": "IR (completo)", 51 | "stepFeaturesIRFullTooltip": "Supporto completo infrarossi", 52 | "stepFeaturesMDNSDesc": "Discovery mDNS", 53 | "stepFeaturesMQTTTLSDesc": "MQTT su TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Questa funzione è disponibile solo con la versione Tasmota 6.6.0.9 o successive.", 55 | "stepFeaturesRFTransceiverDesc": "Ricevitore RF", 56 | "stepFeaturesRFTransceiverTooltip": "Supporto per ricevitore RF usando la libreria RcSwitch", 57 | "stepFeaturesRulesDesc": "Regole", 58 | "stepFeaturesRulesTooltip": "Include 'IF' 'STATEMENT' e 'EXPRESSION'. Le regole escludono l'uso degli script.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "L'inclusione del modulo script esclude l'uso delle regole", 61 | "stepFeaturesTimersDesc": "Timer", 62 | "stepFeaturesTuyaMCUDesc": "MCU Tuya", 63 | "stepFeaturesDistanceDesc": "Sensori distanza", 64 | "stepFeaturesWebInterfaceDesc": "Interfaccia web", 65 | "stepFeaturesWebInterfaceTooltip": "Per la maggior parte degli utenti dovrebbe essere abilitata. Disabilitala in caso sia richiesto un file binario più piccolo e un'occupazione di memoria minore. Se disabilitata l'interazione con il firmware Tasmota sarà possibile solo via broker MQTT.", 66 | "stepFeaturesWS2812Desc": "Led WS2812", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Abilita la comunicazione seriale con Zigbee CC2530 flashato con ZNP o dispositivi EFR32 EmberZNet (tipo Sonoff Zigbee Bridge) flashati con EZSP", 69 | "stepFeaturesUFSDesc": "Scheda SD/LittleFS", 70 | "stepFeaturesUFSTooltip": "Abilita driver Universal File System", 71 | "stepFeaturesBerryDesc": "Script Berry", 72 | "stepFeaturesBerryTooltip": "Aggiunge supporto per linguaggio script Berry", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Aggiunge supporto ble e ble-bridge", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Otturatori e tendine", 77 | "stepFeaturesI2CDesc": "Supporto I2C", 78 | "stepFeaturesSPIDesc": "Supporto SPI", 79 | "stepFeaturesModbusBridgeDesc": "Bridge Modbus", 80 | "stepFeaturesMatterDesc": "Protocollo Matter", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Parametri personalizzati", 85 | "stepCustomParamsDesc": "Qui sotto puoi inserire i parametri personalizzati che verranno inclusi alla fine del file. Se non li conosci o non devi inserirli seleziona 'Avanti'.", 86 | 87 | "stepVersionTitle": "Selezione versione e compilazione", 88 | "stepVersionDesc": "Seleziona versione Tasmota e lingua.", 89 | "stepVersionDevelopment": "Sviluppatore", 90 | "stepVersionTasmota": "Versione Tasmota", 91 | "stepVersionLanguage": "Lingua", 92 | 93 | "stepDownload": "Ora puoi scaricare i file binari compilati e i file usati durante la compilazione:", 94 | 95 | "Afrikaans": "Afrikaan", 96 | "English": "Inglese", 97 | "Bulgarian": "Bulgaro", 98 | "Czech": "Ceco", 99 | "German": "Tedesco", 100 | "Greek": "Greco", 101 | "Spanish": "Spagnolo", 102 | "French": "Francese", 103 | "Hebrew": "Ebraico", 104 | "Hungarian": "Ungherese", 105 | "Italian": "Italiano", 106 | "Korean": "Coreano", 107 | "Dutch": "Olandese", 108 | "Polish": "Polacco", 109 | "Portuguese (Brazil)": "Portoghese (Brasile)", 110 | "Portuguese": "Portoghese", 111 | "Romanian": "Rumeno", 112 | "Russian": "Russo", 113 | "Slovak": "Slovacco", 114 | "Swedish": "Svedese", 115 | "Turkish": "Turco", 116 | "Ukrainian": "Ucraino", 117 | "Chinese (Simplified)": "Cinese (semplificato)", 118 | "Chinese (Traditional)": "Cinese (tradizionale)", 119 | "Vietnam": "Vietnamita", 120 | "Frisian": "Frisone", 121 | 122 | "stepVersionCompProgress": "Progresso compilazione", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/languages.js: -------------------------------------------------------------------------------- 1 | import localeDE from './de.json'; 2 | import localeEN from './en.json'; 3 | import localeES from './es.json'; 4 | import localeIT from './it.json'; 5 | import localePL from './pl.json'; 6 | import localeCS from './cs.json'; 7 | import localeHU from './hu.json'; 8 | import localePT from './pt.json'; 9 | import localeNL from './nl.json'; 10 | import localeFR from './fr.json'; 11 | 12 | // nativeName: Language native name https://www.internationalphoneticalphabet.org/languages/language-names-in-native-language/ 13 | // flag: PNG 24px width proportional icon name from public/flags folder for most typical country of this language 14 | const allMessages = { 15 | de: { 16 | source: localeDE, 17 | nativeName: 'Deutsch', 18 | flag: 'flags/de.png', 19 | browserLang: ['de', 'de-de'], 20 | }, 21 | en: { 22 | source: localeEN, 23 | nativeName: 'English', 24 | flag: 'flags/gb.png', 25 | browserLang: ['en', 'en-gb', 'en-us'], 26 | }, 27 | es: { 28 | source: localeES, 29 | nativeName: 'Español', 30 | flag: 'flags/es.png', 31 | browserLang: ['es', 'es-es'], 32 | }, 33 | it: { 34 | source: localeIT, 35 | nativeName: 'Italiano', 36 | flag: 'flags/it.png', 37 | browserLang: ['it', 'it-it'], 38 | }, 39 | pl: { 40 | source: localePL, 41 | nativeName: 'Polski', 42 | flag: 'flags/pl.png', 43 | browserLang: ['pl', 'pl-pl'], 44 | }, 45 | pt: { 46 | source: localePT, 47 | nativeName: 'Português', 48 | flag: 'flags/pt.png', 49 | browserLang: ['pt', 'pt-pt'], 50 | }, 51 | cs: { 52 | source: localeCS, 53 | nativeName: 'Čeština', 54 | flag: 'flags/cz.png', 55 | browserLang: ['cs', 'cs-cz'], 56 | }, 57 | hu: { 58 | source: localeHU, 59 | nativeName: 'Magyar', 60 | flag: 'flags/hu.png', 61 | browserLang: ['hu', 'hu-hu'], 62 | }, 63 | nl: { 64 | source: localeNL, 65 | nativeName: 'Nederlands', 66 | flag: 'flags/nl.png', 67 | browserLang: ['nl', 'nl-nl', 'nl-be'], 68 | }, 69 | fr: { 70 | source: localeFR, 71 | nativeName: 'Français', 72 | flag: 'flags/fr.png', 73 | browserLang: ['fr', 'fr-fr'], 74 | }, 75 | }; 76 | 77 | // source of truth 78 | const baseTranslation = 'en'; 79 | 80 | // get all defined translations other then source of truth 81 | // const translations = Object.keys(allMessages).filter( 82 | // (l) => l !== baseTranslation 83 | // ); 84 | 85 | // if particular translation does not have some translation, add the translation from baseTranslation 86 | // Object.keys(allMessages[baseTranslation].source).forEach((e) => { 87 | // translations.forEach((t) => { 88 | // if (!allMessages[t].source.hasOwnProperty(e)) { 89 | // allMessages[t].source[e] = allMessages[baseTranslation].source[e]; 90 | // } 91 | // }); 92 | // }); 93 | 94 | const defaultLanguage = baseTranslation; 95 | export { allMessages, defaultLanguage }; 96 | -------------------------------------------------------------------------------- /src/locales/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Tasmota bron code", 4 | "stepSourceDescRefresh": "U kan de brondcode vernieuwen naar de laatste versie of klik op volgene voor de volgende stap.", 5 | "stepSourceDescDownload": "Voor je verder kan gaan moet eerst de Tasmota broncode worden gedownload.", 6 | 7 | "btnDownloadSrc": "Download broncode", 8 | "btnRefreshSrc": "Refresh broncode", 9 | "btnNext": "Volgende", 10 | "btnClear": "Wissen", 11 | "btnBack": "Terug", 12 | "btnCompile": "Bouwen", 13 | 14 | "stepWifiConfTitle": "WiFi configuratie", 15 | "stepWifiConfDesc": "Geef uw wifi SSID en wachtwoord op (je kunt dit ook leeg laten en in tasmota zelf invullen)", 16 | "stepWifiConfStaticIP": "Statisch IP", 17 | "stepWifiConfSSID": "Wifi SSID", 18 | "stepWifiConfPassword": "WiFi wachtwoord", 19 | "stepWifiConfIP": "IP adres", 20 | "stepWifiConfMask": "Netwerk masker", 21 | "stepWifiConfGateway": "Gateway", 22 | "stepWifiConfDNS": "DNS server", 23 | 24 | "stepFeaturesTitle": "Selecteer functies", 25 | "stepFeaturesBoardDesc": "Selecteer het bord waar je project op gebasseerd is", 26 | "stepFeaturesBoard8266Tooltip": "Dit is waarschijnlijk de bord welke je moet kiezen", 27 | "stepFeaturesBoard82662MTooltip": "Shelly-gebasserde apparaten met 2MB Flash geheugen", 28 | "stepFeaturesBoard82664MTooltip": "4MB ESP8266 borden zoals Wemos D1 Mini, NodeMCU, ESP12F, etc.", 29 | "stepFeaturesDesc": "Welke functies moeten worden ingebouwd in de binaire firmware??", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Lucht/gas sensors", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino slave", 34 | "stepFeaturesArduinoSlaveTooltip": "Ondersteuning voor externe microcontroller slave via serieel", 35 | "stepFeaturesDisplaysDesc": "Schermen (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Voor ondersteuning voor I2C en SPI schermen toe", 37 | "stepFeaturesDispVccDesc": "Schermen Vcc", 38 | "stepFeaturesDispVccTooltip": "Blokkeer gebruik van analoge ingang", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Energie sensorsoren", 41 | "stepFeaturesTempHumDesc": "Temp/Vocht sensoren", 42 | "stepFeaturesLightDesc": "Licht sensoren", 43 | "stepFeaturesLightTooltip": "Light intensiteit, licht hoeveelheid, UV Index, etc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "IO poort uitbreiding", 46 | "stepFeaturesIOExpMCPTooltip": "Voor ondersteuning voor Input/Output pin uitbreiding: MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR basis", 49 | "stepFeaturesIRBasicTooltip": "Basis infrarood ondersteuning (minder flash en geheugen gebruik). Geen volledige infrarood ondersteuning.", 50 | "stepFeaturesIRFullDesc": "IR ondersteuning", 51 | "stepFeaturesIRFullTooltip": "Volledige Infrarood ondersteunig", 52 | "stepFeaturesMDNSDesc": "mDNS discovery", 53 | "stepFeaturesMQTTTLSDesc": "MQTT over TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Deze functie werk met versie 6.6.0.9 of later (laatste development).", 55 | "stepFeaturesRFTransceiverDesc": "RF ontvanger", 56 | "stepFeaturesRFTransceiverTooltip": "Ondersteuning voor RF ontvanger door gebruik van de RcSwitch bibliotheek", 57 | "stepFeaturesRulesDesc": "Rules", 58 | "stepFeaturesRulesTooltip": "Geeft ondersteunng voor IF STATEMENT en EXPRESSION. Rules blokkeren het gebruik van scripts.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "Script blokkeert het gebruik van rules", 61 | "stepFeaturesTimersDesc": "Timers", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Afstand sensoren", 64 | "stepFeaturesWebInterfaceDesc": "Web pagina", 65 | "stepFeaturesWebInterfaceTooltip": "Voor de meeste gebruikers moet dit ingeschakeld zijn. Schakel dit uit wanneer je een kleinere binary en minder geheugen gebruikt wilt. Indien uitgeschakeld, kan de interactie met Tasmota firmware alleen via de MQTT broker.", 66 | "stepFeaturesWS2812Desc": "WS2812 Leds", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Schakel seriele communicatie met Zigbee CC2530 geflashed met ZNP of EFR32 EmberZNet apparaten (zoals bijvoorbeeld Sonoff Zigbee Bridge) geflashed met EZSP", 69 | "stepFeaturesUFSDesc": "SD card/LittleFS", 70 | "stepFeaturesUFSTooltip": "Schakel driver voor het Universele File Systeem in", 71 | "stepFeaturesBerryDesc": "Berry scripting", 72 | "stepFeaturesBerryTooltip": "Voeg ondersteuning voor Berry scripting taal toe", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Voeg ble en ble-bridge ondersteuning toe", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Rolluiken en zonwering", 77 | "stepFeaturesI2CDesc": "I2C ondersteuning", 78 | "stepFeaturesSPIDesc": "SPI ondersteuning", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Optionele parameters", 85 | "stepCustomParamsDesc": "Hieronder kunt je optionele parameters toevoegen, welke worden toegevoegd aan het einde van het {filename} bestand. Als je niet weet wat dit is, klik op volgende.", 86 | 87 | "stepVersionTitle": "Selecteer versie and bouw", 88 | "stepVersionDesc": "Selecteer Tasmota versie en taal.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Tasmota versie", 91 | "stepVersionLanguage": "Tasmota UI taal", 92 | 93 | "stepDownload": "Je van nu de aangepaste gebouwde binary en bestanden downloaden gebruikt tijdens het bouwen:", 94 | 95 | "Afrikaans": "Afrikaans", 96 | "English": "Engels", 97 | "Bulgarian": "Bulgaars", 98 | "Czech": "Tsjechisch", 99 | "German": "Duits", 100 | "Greek": "Grieks", 101 | "Spanish": "Spaans", 102 | "French": "Frans", 103 | "Hebrew": "Hebreeuws", 104 | "Hungarian": "Hongaars", 105 | "Italian": "Italiaans", 106 | "Korean": "Koreaans", 107 | "Dutch": "Nederlands", 108 | "Polish": "Pools", 109 | "Portuguese (Brazil)": "Portugees (Brazilië)", 110 | "Portuguese": "Portugees", 111 | "Romanian": "Romaans", 112 | "Russian": "Russisch", 113 | "Slovak": "Slovaaks", 114 | "Swedish": "Zweeds", 115 | "Turkish": "Turks", 116 | "Ukrainian": "Oekraïens", 117 | "Chinese (Simplified)": "Chinees (Simplistisch)", 118 | "Chinese (Traditional)": "Chinees (Traditioneel)", 119 | "Vietnam": "Vietnamees", 120 | "Frisian": "Friesch", 121 | 122 | "stepVersionCompProgress": "Bouw voortgang", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Strona projektu na Github", 3 | "stepSourceTitle": "Kod źródłowy Tasmota'y", 4 | "stepSourceDescRefresh": "Możesz pobrać ostatnie zmiany w kodzie lub kliknąć NASTĘPNY, aby przejśc do następnego kroku", 5 | "stepSourceDescDownload": "Przed przejsciem do następnego kroku, muisz pobrać kod źródłowy Tasmota'y", 6 | 7 | "btnDownloadSrc": "Pobierz żródła", 8 | "btnRefreshSrc": "Odśwież źródła", 9 | "btnNext": "Następny", 10 | "btnClear": "Wyczyść", 11 | "btnBack": "Poprzedni", 12 | "btnCompile": "Kompiluj", 13 | 14 | "stepWifiConfTitle": "Konfiguracja WiFi", 15 | "stepWifiConfDesc": "Podaj SSID oraz hasło do swojej sieci WiFi", 16 | "stepWifiConfStaticIP": "Statyczne IP", 17 | "stepWifiConfSSID": "WiFi SSID", 18 | "stepWifiConfPassword": "Hasło WiFi", 19 | "stepWifiConfIP": "Adres IP", 20 | "stepWifiConfMask": "Maska", 21 | "stepWifiConfGateway": "Brama", 22 | "stepWifiConfDNS": "Serwer DNS", 23 | 24 | "stepFeaturesTitle": "Wybór funkcjonalności", 25 | "stepFeaturesBoardDesc": "Wybierz płytkę na której bazuje Twój projekt", 26 | "stepFeaturesBoard82662MTooltip": "Urządzenia oparte na Shelly z pamięcią flash 2MB", 27 | "stepFeaturesBoard8266Tooltip": "To jest płytka, którą najprawdopodobniej powinieneś wybrać", 28 | "stepFeaturesBoard82664MTooltip": "Płytki ESP8266 4MB takie jak Wemos D1 Mini, NodeMCU, ESP12F, itd..", 29 | "stepFeaturesDesc": "Jakie funkcjonalności zostaną zawarte w wynikowym firmware?", 30 | "stepFeaturesDescriptionLinkTooltip": "Opis grup funkcjonalności", 31 | "stepFeaturesAGDesc": "Czujniki powietrza/gazu", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "Arduino slave", 34 | "stepFeaturesArduinoSlaveTooltip": "Wsparcie komunikacji szeregowej z zewnętrznym mikrokontrolerem.", 35 | "stepFeaturesDisplaysDesc": "Wyświetlacze (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Wsparcie dla wyświetlaczy podłaczonych przez I2C oraz SPI", 37 | "stepFeaturesDispVccDesc": "Wyświetlaj Vcc", 38 | "stepFeaturesDispVccTooltip": "Wyłącz jeśli używasz wejscia analogowego", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Czujniki energii", 41 | "stepFeaturesTempHumDesc": "Czujniki Temp/Hum", 42 | "stepFeaturesLightDesc": "Czujniki światła", 43 | "stepFeaturesLightTooltip": "Intensywność światła, poziom oświetlenia, UV Index, itd.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "Ekspander portów IO", 46 | "stepFeaturesIOExpMCPTooltip": "Wsparcie dla ekspandera MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR podstawowe", 49 | "stepFeaturesIRBasicTooltip": "Podstawowe wsparcie dla protokołow IR (mniejszy obraz binarny oraz zużycie pamięci). Wyłącza użycie pełnego wsparcia IR.", 50 | "stepFeaturesIRFullDesc": "Obsługa IR", 51 | "stepFeaturesIRFullTooltip": "Pełne wsparcie dla protkołów IR", 52 | "stepFeaturesMDNSDesc": "Wykrywanie mDNS", 53 | "stepFeaturesMQTTTLSDesc": "MQTT z TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Ta funkcja będzie dizłać z wersją 6.6.0.9 lub późniejszą (np. ostatnia wersja development).", 55 | "stepFeaturesRFTransceiverDesc": "RF transceiver", 56 | "stepFeaturesRFTransceiverTooltip": "Wsparcie dla RF transceiver z wykrzystaiem biblioteki RcSwitch", 57 | "stepFeaturesRulesDesc": "Rules", 58 | "stepFeaturesRulesTooltip": "Zawiera IF STATEMENTS oraz EXPRESSION. Reguły wyłączają użycie Script.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "Script wyłącza użycie Rules", 61 | "stepFeaturesTimersDesc": "Timers", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Czujniki odległości", 64 | "stepFeaturesWebInterfaceDesc": "Interfejs Web", 65 | "stepFeaturesWebInterfaceTooltip": "Dla większości uzytkowników opcja powinna pozostać włączona. Opcję można wyłączyć, jeśli potrzebny jest mniejszy obraz firmware lub mniejsze zużycie pamięci. Jeśli zostanie wyłączone, komunikacja z Tasmota bedzie możliwa tylko przez broker MQTT.", 66 | "stepFeaturesWS2812Desc": "Ledy WS2812", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Szeregowa komunikacja z modułem Zigbee CC2530 z wgranym ZNP lub modułem EFR32 EmberZNet (np. Sonoff Zigbee Bridge) z wgranym EZSP", 69 | "stepFeaturesUFSDesc": "Karta SD/LittleFS", 70 | "stepFeaturesUFSTooltip": "Sterownik dla Universal File System", 71 | "stepFeaturesBerryDesc": "Skrypty Berry", 72 | "stepFeaturesBerryTooltip": "Obsługa języka Berry Scripting", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Obsługa ble oraz ble-bridge support", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Rolety i zasłony", 77 | "stepFeaturesI2CDesc": "I2C support", 78 | "stepFeaturesSPIDesc": "SPI support", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Protokół Matter", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Parametry użytkownika", 85 | "stepCustomParamsDesc": "Poniżej możesz wpisać własne parametry, które zostaną dodane na koniec pliku {filename}. Jeśli nie wiesz co to jest, po prostu kliknij NASTĘPNY.", 86 | 87 | "stepVersionTitle": "Wybierz wersje i kompiluj", 88 | "stepVersionDesc": "Wybierz wersję Tasmoty oraz języka.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Wersja Tasmoty", 91 | "stepVersionLanguage": "Język UI Tasmoty", 92 | 93 | "stepDownload": "Poniżej możesz pobrać nowy firmware oraz pliki użyte do jego zbudowania:", 94 | 95 | "Afrikaans": "Afrykański", 96 | "English": "Angielski", 97 | "Bulgarian": "Bułgarski", 98 | "Czech": "Czeski", 99 | "German": "Niemiecki", 100 | "Greek": "Grecki", 101 | "Spanish": "Hiszpański", 102 | "French": "Francuski", 103 | "Hebrew": "Hebrajski", 104 | "Hungarian": "Węgierski", 105 | "Italian": "Włoski", 106 | "Korean": "Koreański", 107 | "Dutch": "Holenderski", 108 | "Polish": "Polski", 109 | "Portuguese (Brazil)": "Portugalski (Brazylijski)", 110 | "Portuguese": "Portugalski", 111 | "Romanian": "Rumuński", 112 | "Russian": "Rosyjski", 113 | "Slovak": "Słowacki", 114 | "Swedish": "Szwedzki", 115 | "Turkish": "Turecki", 116 | "Ukrainian": "Ukraiński", 117 | "Chinese (Simplified)": "Chiński (uproszczony)", 118 | "Chinese (Traditional)": "Chiński (tradycyjny)", 119 | "Vietnam": "Wietnamski", 120 | "Frisian": "Fryzyjski", 121 | 122 | "stepVersionCompProgress": "Postęp kompilacji", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/locales/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | "headerProjectGithubPageTooltip": "Project Github page", 3 | "stepSourceTitle": "Código-fonte Tasmota", 4 | "stepSourceDescRefresh": "Você pode atualizar o código-fonte para o estado mais recente ou clicar em PRÓXIMO para ir para a próxima etapa", 5 | "stepSourceDescDownload": "Antes de ir para a próxima etapa, você deve baixar o código-fonte do Tasmota", 6 | 7 | "btnDownloadSrc": "Baixe o código fonte", 8 | "btnRefreshSrc": "Atualizar o código-fonte", 9 | "btnNext": "Próximo", 10 | "btnClear": "Limpar", 11 | "btnBack": "Voltar", 12 | "btnCompile": "Compilar", 13 | 14 | "stepWifiConfTitle": "Configuração WiFi", 15 | "stepWifiConfDesc": "Digite o Nome e a Senha da sua rede WiFi", 16 | "stepWifiConfStaticIP": "Endereço IP Estático", 17 | "stepWifiConfSSID": "Nome da rede WiFi", 18 | "stepWifiConfPassword": "Senha do WiFi", 19 | "stepWifiConfIP": "Endereço IP", 20 | "stepWifiConfMask": "Máscara de rede", 21 | "stepWifiConfGateway": "Porta de entrada", 22 | "stepWifiConfDNS": "Servidor DNS", 23 | 24 | "stepFeaturesTitle": "selecione Características", 25 | "stepFeaturesBoardDesc": "Selecione o tipo de hardware a ser usado", 26 | "stepFeaturesBoard8266Tooltip": "Recomendado para todos os dispositivos com ESP8266.", 27 | "stepFeaturesBoard82662MTooltip": "Dispositivos baseados em Shelly com memória flash de 2MB", 28 | "stepFeaturesBoard82664MTooltip": "Apenas para uso avançado e apenas para dispositivos com ESP8266 e 4 MB como Wemos D1 Mini, NodeMCU, ESP12F, etc.", 29 | "stepFeaturesDesc": "Quais recursos devem ser incluídos no firmware final?", 30 | "stepFeaturesDescriptionLinkTooltip": "Features group description", 31 | "stepFeaturesAGDesc": "Sensores de Ar/Gás", 32 | "stepFeaturesAlexaDesc": "Amazon Alexa", 33 | "stepFeaturesArduinoSlaveDesc": "MCU Secundário Arduino", 34 | "stepFeaturesArduinoSlaveTooltip": "Suporte para microcontrolador secundário externo na porta serial", 35 | "stepFeaturesDisplaysDesc": "Telas (I2C/SPI)", 36 | "stepFeaturesDisplaysTooltip": "Adicionar suporte para telas I2C e SPI", 37 | "stepFeaturesDispVccDesc": "Exibir Vcc", 38 | "stepFeaturesDispVccTooltip": "Desabilite para poder usar a entrada analógica", 39 | "stepFeaturesDomoticzDesc": "Domoticz", 40 | "stepFeaturesEnergyDesc": "Sensores de Energia", 41 | "stepFeaturesTempHumDesc": "Sensores de Temp e Umidade", 42 | "stepFeaturesLightDesc": "Sensores de Luz", 43 | "stepFeaturesLightTooltip": "Intensidade da luz, nível de luz, índice de UV, etc.", 44 | "stepFeaturesHomeAssistantDesc": "Home Assistant", 45 | "stepFeaturesIOExpMCPDesc": "Expansor de porta IO", 46 | "stepFeaturesIOExpMCPTooltip": "Adicionar suporte para expansor de porta de entrada/saída: MCP230xx", 47 | "stepFeaturesKNXDesc": "KNX", 48 | "stepFeaturesIRBasicDesc": "IR Básico", 49 | "stepFeaturesIRBasicTooltip": "Suporte infravermelho básico (usa menos memória e os firmwares são menores). Exclui suporte infravermelho completo.", 50 | "stepFeaturesIRFullDesc": "IR Completo", 51 | "stepFeaturesIRFullTooltip": "Suporte total a infravermelho (usa mais memória e firmware maior).", 52 | "stepFeaturesMDNSDesc": "Habilitar mDNS", 53 | "stepFeaturesMQTTTLSDesc": "MQTT com TLS", 54 | "stepFeaturesMQTTTLSTooltip": "Este recurso funciona apenas com a versão 6.6.0.9 ou posterior.", 55 | "stepFeaturesRFTransceiverDesc": "Transceptor RF", 56 | "stepFeaturesRFTransceiverTooltip": "Suporte para transceptor RF usando a biblioteca RcSwitch", 57 | "stepFeaturesRulesDesc": "Regras", 58 | "stepFeaturesRulesTooltip": "Inclui IF STATEMENT e EXPRESSION. As regras excluem o uso de scripts.", 59 | "stepFeaturesScriptDesc": "Script", 60 | "stepFeaturesScriptTooltip": "O script exclui o uso de regras", 61 | "stepFeaturesTimersDesc": "Cronômetros", 62 | "stepFeaturesTuyaMCUDesc": "Tuya MCU", 63 | "stepFeaturesDistanceDesc": "Sensores de distância", 64 | "stepFeaturesWebInterfaceDesc": "Interface WEB", 65 | "stepFeaturesWebInterfaceTooltip": "Para a maioria dos usuários, isso deve ser habilitado. Desative-o caso precise de um binário menor e menos uso de memória. Se desativado, a interação com Tasmota só será possível por meio do broker MQTT.", 66 | "stepFeaturesWS2812Desc": "LEDs WS2812", 67 | "stepFeaturesZigbeeDesc": "Zigbee", 68 | "stepFeaturesZigbeeTooltip": "Habilite a comunicação serial com o chip Zigbee CC2530. O CC2530 deve ter firmware ZNP ou EZSP.", 69 | "stepFeaturesUFSDesc": "SD card/LittleFS", 70 | "stepFeaturesUFSTooltip": "Habilitar driver para sistema de arquivos universal", 71 | "stepFeaturesBerryDesc": "Berry scripting", 72 | "stepFeaturesBerryTooltip": "Adicionar suporte para linguagem de script Berry", 73 | "stepFeaturesBluetoothDesc": "Bluetooth", 74 | "stepFeaturesBluetoothTooltip": "Adicionar suporte de BLE e ponte BLE", 75 | "stepFeaturesEthernetDesc": "Ethernet", 76 | "stepFeaturesShutterDesc": "Shutters and Blinds", 77 | "stepFeaturesI2CDesc": "suporte I2C", 78 | "stepFeaturesSPIDesc": "suporte SPI", 79 | "stepFeaturesModbusBridgeDesc": "Modbus Bridge", 80 | "stepFeaturesMatterDesc": "Matter protocol", 81 | "stepFeaturesLvglDesc": "LVGL", 82 | "stepFeaturesLvglTooltip": "Light and Versatile Embedded Graphics Library", 83 | 84 | "stepCustomParamsTitle": "Parâmetros personalizados", 85 | "stepCustomParamsDesc": "Abaixo, você pode inserir parâmetros personalizados, que serão incluídos no final do arquivo {filename}. Se você não sabe o que é, apenas clique em Avançar.", 86 | 87 | "stepVersionTitle": "Selecione a versão e compile", 88 | "stepVersionDesc": "Selecione a versão e o idioma do Tasmota.", 89 | "stepVersionDevelopment": "Development", 90 | "stepVersionTasmota": "Versão Tasmota", 91 | "stepVersionLanguage": "Idioma", 92 | 93 | "stepDownload": "Agora você pode baixar binários compilados personalizados e arquivos usados durante a compilação:", 94 | 95 | "Afrikaans": "Africano", 96 | "English": "Inglês", 97 | "Bulgarian": "Búlgaro", 98 | "Czech": "Tcheco", 99 | "German": "Alemão", 100 | "Greek": "Grego", 101 | "Spanish": "Espanhol", 102 | "French": "Francês", 103 | "Hebrew": "Hebraico", 104 | "Hungarian": "Húngaro", 105 | "Italian": "Italiano", 106 | "Korean": "Coreano", 107 | "Dutch": "Holandês", 108 | "Polish": "Polonês", 109 | "Portuguese (Brazil)": "Portugues (Brasil)", 110 | "Portuguese": "Português (Portugal)", 111 | "Romanian": "Romeno", 112 | "Russian": "Russo", 113 | "Slovak": "Eslovaco", 114 | "Swedish": "Sueco", 115 | "Turkish": "Turco", 116 | "Ukrainian": "Ucraniano", 117 | "Chinese (Simplified)": "Chinês (Simplificado)", 118 | "Chinese (Traditional)": "Chinês (Tradicional)", 119 | "Vietnam": "Vietnã", 120 | "Frisian": "Frisian", 121 | 122 | "stepVersionCompProgress": "Progresso da Compilação", 123 | 124 | "": "" 125 | } 126 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | function registerValidSW(swUrl, config) { 24 | navigator.serviceWorker 25 | .register(swUrl) 26 | .then((registration) => { 27 | registration.onupdatefound = () => { 28 | const installingWorker = registration.installing; 29 | if (installingWorker == null) { 30 | return; 31 | } 32 | installingWorker.onstatechange = () => { 33 | if (installingWorker.state === 'installed') { 34 | if (navigator.serviceWorker.controller) { 35 | // At this point, the updated precached content has been fetched, 36 | // but the previous service worker will still serve the older 37 | // content until all client tabs are closed. 38 | console.log( 39 | 'New content is available and will be used when all ' + 40 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 41 | ); 42 | 43 | // Execute callback 44 | if (config && config.onUpdate) { 45 | config.onUpdate(registration); 46 | } 47 | } else { 48 | // At this point, everything has been precached. 49 | // It's the perfect time to display a 50 | // "Content is cached for offline use." message. 51 | console.log('Content is cached for offline use.'); 52 | 53 | // Execute callback 54 | if (config && config.onSuccess) { 55 | config.onSuccess(registration); 56 | } 57 | } 58 | } 59 | }; 60 | }; 61 | }) 62 | .catch((error) => { 63 | console.error('Error during service worker registration:', error); 64 | }); 65 | } 66 | 67 | function checkValidServiceWorker(swUrl, config) { 68 | // Check if the service worker can be found. If it can't reload the page. 69 | fetch(swUrl) 70 | .then((response) => { 71 | // Ensure service worker exists, and that we really are getting a JS file. 72 | const contentType = response.headers.get('content-type'); 73 | if ( 74 | response.status === 404 || 75 | (contentType != null && contentType.indexOf('javascript') === -1) 76 | ) { 77 | // No service worker found. Probably a different app. Reload the page. 78 | navigator.serviceWorker.ready.then((registration) => { 79 | registration.unregister().then(() => { 80 | window.location.reload(); 81 | }); 82 | }); 83 | } else { 84 | // Service worker found. Proceed as normal. 85 | registerValidSW(swUrl, config); 86 | } 87 | }) 88 | .catch(() => { 89 | console.log( 90 | 'No internet connection found. App is running in offline mode.' 91 | ); 92 | }); 93 | } 94 | export function register(config) { 95 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 96 | // The URL constructor is available in all browsers that support SW. 97 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 98 | if (publicUrl.origin !== window.location.origin) { 99 | // Our service worker won't work if PUBLIC_URL is on a different origin 100 | // from what our page is served on. This might happen if a CDN is used to 101 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 102 | return; 103 | } 104 | 105 | window.addEventListener('load', () => { 106 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 107 | 108 | if (isLocalhost) { 109 | // This is running on localhost. Let's check if a service worker still exists or not. 110 | checkValidServiceWorker(swUrl, config); 111 | 112 | // Add some additional logging to localhost, pointing developers to the 113 | // service worker/PWA documentation. 114 | navigator.serviceWorker.ready.then(() => { 115 | console.log( 116 | 'This web app is being served cache-first by a service ' + 117 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 118 | ); 119 | }); 120 | } else { 121 | // Is not localhost. Just register service worker 122 | registerValidSW(swUrl, config); 123 | } 124 | }); 125 | } 126 | } 127 | 128 | export function unregister() { 129 | if ('serviceWorker' in navigator) { 130 | navigator.serviceWorker.ready 131 | .then((registration) => { 132 | registration.unregister(); 133 | }) 134 | .catch((error) => { 135 | console.log('Error during service worker unregister:', error); 136 | }); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/styles/styles.js: -------------------------------------------------------------------------------- 1 | const styles = (theme) => ({ 2 | toolbar: { 3 | display: 'flex', 4 | justifyContent: 'space-between', 5 | alignItems: 'center', 6 | }, 7 | toolbarRight: { 8 | display: 'flex', 9 | alignItems: 'center', 10 | justifyContent: 'center', 11 | }, 12 | projectPageContainer: { 13 | width: 24, 14 | height: 24, 15 | marginRight: theme.spacing(2), 16 | }, 17 | projectPageImg: { 18 | width: '100%', 19 | height: '100%', 20 | color: theme.palette.background.paper, 21 | // filter: 'invert(95%) sepia(100%) saturate(0%) hue-rotate(125deg) brightness(102%) contrast(101%)', 22 | }, 23 | language: { 24 | display: 'flex', 25 | justifyContent: 'flex-end', 26 | alignItems: 'center', 27 | cursor: 'pointer', 28 | }, 29 | languageList: { 30 | marginTop: theme.spacing(), 31 | }, 32 | flagIcon: { 33 | width: 24, 34 | borderWidth: 1, 35 | borderStyle: 'solid', 36 | borderColor: theme.palette.primary.dark, 37 | }, 38 | languageName: { 39 | marginLeft: theme.spacing(), 40 | }, 41 | root: { 42 | width: '100%', 43 | }, 44 | stepper: { 45 | marginLeft: theme.spacing(3), 46 | marginTop: theme.spacing(2), 47 | }, 48 | stepLabel: { 49 | fontSize: theme.typography.body1.fontSize, 50 | }, 51 | button: { 52 | marginTop: theme.spacing(), 53 | marginRight: theme.spacing(), 54 | }, 55 | buttonProgress: { 56 | color: 'default', 57 | position: 'absolute', 58 | top: '50%', 59 | left: '50%', 60 | marginTop: -12, 61 | marginLeft: -12, 62 | }, 63 | wrapper: { 64 | margin: theme.spacing(), 65 | position: 'relative', 66 | }, 67 | formControl: { 68 | margin: theme.spacing(), 69 | // display: 'flex', 70 | minWidth: 120, 71 | }, 72 | actionsContainer: { 73 | // marginBottom: theme.spacing(2), 74 | // marginTop: theme.spacing(), 75 | // marginRight: theme.spacing(), 76 | // marginLeft: theme.spacing(), 77 | margin: theme.spacing(2), 78 | minWidth: 240, 79 | maxWidth: '80%', 80 | display: 'flex', 81 | flexWrap: 'wrap', 82 | }, 83 | versionContainer: { 84 | margin: theme.spacing(), 85 | minWidth: 180, 86 | }, 87 | languageContainer: { 88 | margin: theme.spacing(), 89 | maxWidth: 440, 90 | minWidth: 180, 91 | }, 92 | tasmotaLangSelector: { 93 | display: 'flex', 94 | alignItems: 'center', 95 | }, 96 | textField: { 97 | // marginLeft: theme.spacing(), 98 | // marginRight: theme.spacing(), 99 | margin: theme.spacing(), 100 | width: 180, 101 | }, 102 | multiTextField: { 103 | margin: theme.spacing(), 104 | // width: 300, 105 | }, 106 | compileMessagesBox: { 107 | marginLeft: theme.spacing(3), 108 | marginTop: 0, 109 | maxWidth: '80%', 110 | }, 111 | inputFont: { 112 | // display: 'block', 113 | fontFamily: 'monospace', 114 | }, 115 | checkboxContainer: { 116 | marginBottom: 0, 117 | marginLeft: theme.spacing(), 118 | minWidth: 230, 119 | maxWidth: 230, 120 | }, 121 | radioContainer: { 122 | marginBottom: 0, 123 | marginLeft: theme.spacing(), 124 | minWidth: 230, 125 | maxWidth: 230, 126 | }, 127 | featuresHeaderContainer: { 128 | display: 'flex', 129 | gap: theme.spacing(), 130 | }, 131 | chipTypesContainer: {}, 132 | links: { 133 | marginLeft: theme.spacing(3), 134 | marginBottom: theme.spacing(3), 135 | }, 136 | donationLinks: { 137 | marginLeft: theme.spacing(3), 138 | marginTop: theme.spacing(3), 139 | marginBottom: theme.spacing(3), 140 | padding: theme.spacing(1), 141 | boxSizing: 'border-box', 142 | display: 'flex', 143 | alignItems: 'center', 144 | justifyContent: 'center', 145 | maxWidth: '80%', 146 | position: 'relative', 147 | borderWidth: 1, 148 | borderStyle: 'solid', 149 | borderColor: theme.palette.primary.dark, 150 | borderRadius: theme.shape.borderRadius, 151 | }, 152 | donationImage: { 153 | width: 36, 154 | marginLeft: theme.spacing(1), 155 | marginRight: theme.spacing(1), 156 | }, 157 | rightIcon: { 158 | marginLeft: theme.spacing(), 159 | }, 160 | leftIcon: { 161 | marginRight: theme.spacing(), 162 | }, 163 | downloadButtons: { 164 | marginRight: theme.spacing(2), 165 | marginTop: theme.spacing(), 166 | marginBottom: theme.spacing(), 167 | position: 'relative', 168 | }, 169 | boardsDivider: { 170 | marginTop: theme.spacing(), 171 | marginBottom: theme.spacing(), 172 | }, 173 | }); 174 | 175 | export default styles; 176 | --------------------------------------------------------------------------------