Merge branch 'development' into pre-release-12.0

This commit is contained in:
Theo Arends 2022-06-13 16:28:00 +02:00
commit 1cdd2be008
607 changed files with 32144 additions and 12706 deletions

View File

@ -32,19 +32,34 @@ jobs:
- tasmota-zbbridge
- tasmota-zigbee
- tasmota32
- tasmota32-zbbrdgpro
- tasmota32-webcam
- tasmota32-bluetooth
- tasmota32-nspanel
- tasmota32-display
- tasmota32-ir
- tasmota32-lvgl
- tasmota32c3
- tasmota32c3cdc
- tasmota32s2
- tasmota32s2cdc
- tasmota32s3
- tasmota32s3cdc
- tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: development
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
- name: Install dependencies
run: |
pip install -U platformio
@ -64,11 +79,11 @@ jobs:
variant: [ tasmota, tasmota32 ]
language: [ AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, NL, PL, PT, RO, RU, SE, SK, TR, TW, UK, VN ]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: development
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
- name: Install dependencies
run: |
pip install -U platformio
@ -114,10 +129,17 @@ jobs:
[ ! -f ./mv_firmware/firmware/tasmota32-lvgl.* ] || mv ./mv_firmware/firmware/tasmota32-lvgl.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-web*.* ] || mv ./mv_firmware/firmware/tasmota32-web*.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/firmware/tasmota32-odroidgo.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ] || mv ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-nspanel.* ] || mv ./mv_firmware/firmware/tasmota32-nspanel.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-core2.* ] || mv ./mv_firmware/firmware/tasmota32-core2.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-bluetooth.* ] || mv ./mv_firmware/firmware/tasmota32-bluetooth.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32c3*.* ] || mv ./mv_firmware/firmware/tasmota32c3*.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/languages/
[ ! -f ./mv_firmware/firmware/tasmota32s2*.* ] || mv ./mv_firmware/firmware/tasmota32s2*.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32s3*.* ] || mv ./mv_firmware/firmware/tasmota32s3*.* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-safeboot* ] || mv ./mv_firmware/firmware/tasmota32-safeboot* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-* ] || mv ./mv_firmware/firmware/tasmota32-* ./firmware/tasmota32/languages/
[ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota-minimal.bin ] || rm -rf ./mv_firmware/firmware/tasmota-minimal.bin
[ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./firmware/tasmota/languages/
- name: Display files to transfer
run: ls -R ./*
@ -136,7 +158,7 @@ jobs:
needs: Upload
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Creat trigger.txt
run: |
echo ${GITHUB_SHA} &> trigger.txt

View File

@ -31,19 +31,34 @@ jobs:
- tasmota-zbbridge
- tasmota-zigbee
- tasmota32
- tasmota32-zbbrdgpro
- tasmota32-webcam
- tasmota32-bluetooth
- tasmota32-nspanel
- tasmota32-display
- tasmota32-ir
- tasmota32-lvgl
- tasmota32c3
- tasmota32c3cdc
- tasmota32s2
- tasmota32s2cdc
- tasmota32s3
- tasmota32s3cdc
- tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: master
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
- name: Install dependencies
run: |
pip install -U platformio
@ -63,11 +78,11 @@ jobs:
variant: [ tasmota, tasmota32 ]
language: [ AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, NL, PL, PT, RO, RU, SE, SK, TR, TW, UK, VN ]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: master
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
- name: Install dependencies
run: |
pip install -U platformio
@ -83,7 +98,7 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/download-artifact@v2
with:
name: firmware
@ -121,11 +136,18 @@ jobs:
[ ! -f ./mv_firmware/firmware/tasmota32-display.* ] || mv ./mv_firmware/firmware/tasmota32-display.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-lvgl.* ] || mv ./mv_firmware/firmware/tasmota32-lvgl.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-web*.* ] || mv ./mv_firmware/firmware/tasmota32-web*.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ] || mv ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-nspanel.* ] || mv ./mv_firmware/firmware/tasmota32-nspanel.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/firmware/tasmota32-odroidgo.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-core2.* ] || mv ./mv_firmware/firmware/tasmota32-core2.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-bluetooth.* ] || mv ./mv_firmware/firmware/tasmota32-bluetooth.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32c3*.* ] || mv ./mv_firmware/firmware/tasmota32c3*.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32s2*.* ] || mv ./mv_firmware/firmware/tasmota32s2*.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32s3*.* ] || mv ./mv_firmware/firmware/tasmota32s3*.* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-safeboot* ] || mv ./mv_firmware/firmware/tasmota32-safeboot* ./release-firmware/tasmota32/
[ ! -f ./mv_firmware/firmware/tasmota32-* ] || mv ./mv_firmware/firmware/tasmota32-* ./release-firmware/tasmota32/languages/
[ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./release-firmware/tasmota32/languages/
[ ! -f ./mv_firmware/firmware/tasmota-minimal.bin ] || rm -rf ./mv_firmware/firmware/tasmota-minimal.bin
[ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./release-firmware/tasmota/languages/
- name: Display files to transfer
run: ls -R ./*
@ -144,7 +166,7 @@ jobs:
needs: Upload
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Creat trigger.txt
run: |
echo ${GITHUB_SHA} &> trigger.txt

View File

@ -32,17 +32,31 @@ jobs:
- tasmota-minimal
- tasmota-sensors
- tasmota-zbbridge
- tasmota32-zbbrdgpro
- tasmota-zigbee
- tasmota32
- tasmota32-webcam
- tasmota32-bluetooth
- tasmota32-core2
- tasmota32-nspanel
- tasmota32-display
- tasmota32-ir
- tasmota32-lvgl
- tasmota32s2
- tasmota32c3
- tasmota32c3cdc
- tasmota32s2
- tasmota32s2cdc
- tasmota32s3
- tasmota32s3cdc
- tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v2
- name: Set up Python

View File

@ -12,6 +12,7 @@ jobs:
copy_change:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
steps:
- uses: actions/checkout@v2
- name: Push I2CDevices.md to https://github.com/Tasmota/docs

6
.gitignore vendored
View File

@ -19,14 +19,10 @@ data
unpacked_fs
tasmota/user_config_override.h
build
build_output
build_output/*
firmware.map
firmware.asm
tasmota/tasmota.ino.cpp
tasmota*.bin
tasmota*.bin.gz
tasmota*.map
tasmota*.map.gz
platformio_override.ini
platformio_tasmota_cenv.ini

View File

@ -1,47 +0,0 @@
language: python
python:
- '3.7'
sudo: false
install:
- pip install -U platformio
- platformio upgrade --dev
- platformio update
cache: false
env:
- ENV=tasmota
- ENV=tasmota-minimal
- ENV=tasmota-lite
- ENV=tasmota-knx
- ENV=tasmota-sensors
- ENV=tasmota-display
- ENV=tasmota-ir
- ENV=tasmota-BG
- ENV=tasmota-BR
- ENV=tasmota-CN
- ENV=tasmota-CZ
- ENV=tasmota-DE
- ENV=tasmota-ES
- ENV=tasmota-FR
- ENV=tasmota-GR
- ENV=tasmota-HE
- ENV=tasmota-HU
- ENV=tasmota-IT
- ENV=tasmota-KO
- ENV=tasmota-NL
- ENV=tasmota-PL
- ENV=tasmota-PT
- ENV=tasmota-RO
- ENV=tasmota-RU
- ENV=tasmota-SE
- ENV=tasmota-SK
- ENV=tasmota-TR
- ENV=tasmota-TW
- ENV=tasmota-UK
- ENV=tasmota-VN
script:
- platformio run -e $ENV
before_deploy:
- for file in .pioenvs/*/firmware.bin; do cp $file ${file%/*}.bin; done

View File

@ -65,6 +65,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_MY92X1 | - | x / - | x | x | - | x |
| USE_SM16716 | - | x / - | x | x | - | x |
| USE_SM2135 | - | x / - | x | x | - | x |
| USE_BP5758D | - | x / - | x | x | - | x |
| USE_SONOFF_L1 | - | x / - | x | x | - | x |
| USE_ELECTRIQ_MOODL | - | x / - | x | x | - | x |
| | | | | | | |
@ -170,6 +171,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_HDC2010 | - | - / - | - | - | - | - |
| USE_PCF85363 | - | - / - | - | - | - | - |
| USE_DS3502 | - | - / - | - | - | - | - |
| USE_HYT | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_SPI | - | - / - | - | - | - | x |
@ -216,6 +218,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_HRE | - | - / x | - | x | - | - |
| USE_A4988_STEPPER | - | - / - | - | - | - | - |
| USE_NEOPOOL | - | - / - | - | - | - | - |
| USE_FLOWRATEMETER | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_DISPLAY | - | - / - | - | - | - | x |
@ -240,6 +243,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_MI_ESP32 | | / x | | | | | See SetOption115
| USE_IBEACON_ESP32 | | / - | | | | |
| USE_WEBCAM | | / - | | | | |
| USE_ETHERNET | | / - | | | | |
| USE_ETHERNET | | / x | | | | |
| USE_I2S_AUDIO | | / - | | | | |
| USE_TTGO_WATCH | | / - | | | | |
| USE_SONOFF_SPM | | / x | | | | |

View File

@ -3,6 +3,64 @@ All notable changes to this project will be documented in this file.
## [Released]
## [12.0.0] 20220615
- Release Paul
## [11.1.0.4] 20220615
### Added
- Support for HYTxxx temperature and humidity sensor (#15715)
- Support for Sensirion SHT4X using define USE_SHT3X (#15349)
- Command ``SSerialSend9 1`` to enable Serial Bridge console Tee for debugging purposes
- Command ``SetOption142 1`` to wait 1 second for wifi connection solving some FRITZ!Box modem issues (#14985)
### Changed
- Restructured tasmota source directories taking benefit from PlatformIO Core v6.0.2
- ESP32 increase Serial Bridge input buffer from 130 to 520 characters
### Fixed
- ESP32 Arduino Core WiFi timeout is changed from msec to seconds
- Reduce blocking by adding WifiPollDns before resolving NTP and/or MQTT server names (#14394)
- SHT1X driver hangs and wrong values on ESP32 (#15790)
## [11.1.0.3] 20220602
### Added
- Support for Sonoff SPM v1.2.0
- Support for Sonoff Zigbee Bridge Pro by Stephan Hadinger (#15701)
- Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules (#13447)
- Command ``SetOption141 1`` to disable display of module name in GUI header
- Support for 5-channel light dimmer driver BP5758D used in Tuya bulbs (#15713)
### Fixed
- Possible pin output toggle after power on (#15630)
## [11.1.0.2] 20220514
### Added
- ESP32 Command ``Restart 3`` to switch between SafeBoot and Production
### Changed
- Prepare to remove dedicated Home Assistant discovery in favour of Tasmota Discovery and hatasmota
- ESP32 Tasmota SafeBoot with changed partition scheme allowing larger binaries
## [11.1.0.1] 20220504
### Added
- Support for Sonoff MS01 soil moisture sensor (#15335)
- Support for daisy chaining MAX7219 displays (#15345)
- Support for light schemes via DDP as default for ESP32x (#15436)
- Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only (#13515)
- Sonoff SPM delayed SetPowerOnState (#13447)
- Command ``SetOption139 0/1`` to switch between pressure unit "mmHg" (0) or "inHg" (1) when ``SO24 1`` (#15350)
- Support for flowrate meters like YF-DN50 and similary (#15474)
- Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy (#15513)
- Command ``SetOption140 0/1`` to switch between MQTT Clean Session (0) or Persistent Session (1) (#15530)
### Fixed
- SCD40 start low power command (#15361)
- Improv initial or erase device installation failing to provide Configure WiFi option
- BL09xx negative power presentation (#15374)
### Removed
- Arduino IDE support
## [11.1.0] 20220413
- Release Ostara

97
CODE_OWNERS.md Normal file
View File

@ -0,0 +1,97 @@
<img src="/tools/logo/TASMOTA_FullLogo_Vector.svg" alt="Logo" align="right" height="76"/>
# Code Owners
In addition to @arendst the following code is mainly owned by:
| Code | Owner
|----------------------------|---------------------------
| Tasmota Drivers |
| |
| xdrv_01_webserver | @arendst
| xdrv_02_mqtt | @arendst
| xdrv_03_energy | @arendst
| xdrv_04_light | @s-hadinger
| xdrv_05_irremote | @s-hadinger
| xdrv_06_snfbridge | @arendst
| xdrv_07_domoticz | @arendst
| xdrv_08_serial_bridge | Dániel Zoltán Tolnai
| xdrv_09_timers | @arendst
| xdrv_10_rules | @arendst, @barbudor
| xdrv_10_scripter | @gemu
| xdrv_11_knx | @adrian
| xdrv_12_discovery | @arendst, @effelle, @emontnemery
| xdrv_13_display | @gemu, @s-hadinger
| xdrv_14_mp3 | @gemu, @mike2nl
| xdrv_15_pca9685 | Andre Thomas
| xdrv_16_tuyamcu | @btsimonh
| xdrv_17_rcswitch |
| xdrv_18_armtronix_dimmers | @wvdv2002
| xdrv_19_pz16dz_dimmer | Joel Stein
| xdrv_20_hue | @s-hadinger
| xdrv_21_wemo | @s-hadinger
| xdrv_22_sonoff_ifan | @arendst
| xdrv_23_zigbee | @s-hadinger
| xdrv_24_buzzer | @arendst
| xdrv_25_stepper | Tim Leuscher
| xdrv_26_ariluxrf | @arendst
| xdrv_27_shutter | @stefanbode
| xdrv_28_pcf8574 | @stefanbode
| xdrv_29_deepsleep | @stefanbode
| xdrv_30_exs_dimmer | Andreas Schultz
| xdrv_31_tasmota_client | Andre Thomas
| xdrv_32_hotplug | @BASM
| xdrv_33_nrf24l01 | @staars
| xdrv_34_wemos_motor | Peter Franck
| xdrv_35_pwm_dimmer | Paul C Diem
| xdrv_36_keeloq | he-so
| xdrv_37_sonoff_d1 | @arendst
| xdrv_38_ping | @s-hadinger
| xdrv_39_thermostat | Javier Argita
| xdrv_40_telegram | @arendst
| xdrv_41_tcp_bridge | @s-hadinger
| xdrv_42_i2s_audio | @gemu
| xdrv_43_mlx90640 | @staars
| xdrv_44_miel_hvac | David GWynne
| xdrv_45_shelly_dimmer | James Turton
| xdrv_46_ccloader | @staars
| xdrv_47_ftc532 | Peter Franck
| xdrv_48_timeprop | Colin Law, Thomas Herrmann
| xdrv_49_pid | Colin Law, Thomas Herrmann
| xdrv_50_filesystem | @gemu, @barbudor
| xdrv_51_bs814a2 | Peter Franck
| xdrv_52_berry | @s-hadinger
| xdrv_53_projector_ctrl | Jan Bubík
| xdrv_54_lvgl | @s-hadinger
| xdrv_55_touch | @gemu, @s-hadinger
| xdrv_56_rtc_chips | @arendst, @s-hadinger
| xdrv_57_tasmesh | @staars
| xdrv_58_range_extender | @sillyfrog
| xdrv_59_influxdb | @arendst
| xdrv_60_shift595 | Jacek Ziółkowski
| xdrv_61_ds3502 | f-reiling
| xdrv_62_improv | @arendst
| xdrv_79_esp32_ble | @staars, @btsimonh
| xdrv_81_esp32_webcam | @gemu, @philrich
| xdrv_82_esp32_ethernet | @arendst
| xdrv_83_esp32_watch | @gemu
| xdrv_85_esp32_ble_eq3_trv | @btsimonh
| xdrv_86_esp32_sonoff_spm | @arendst
| |
| Tasmota Sensors |
| |
| xsns_01_counter | @arendst, @stefanbode
| xsns_78_ezo | Christopher Tremblay
| |
| Libraries |
| |
| berry | @s-hadinger
| ext-printf | @s-hadinger
| jsmn | @s-hadinger
| unishox | @s-hadinger
| |
| PlatformIO |
| |
| all | @Jason2866
| |

View File

@ -31,7 +31,8 @@ Index | Define | Driver | Device | Address(es) | Description
13 | USE_ADS1115 | xsns_12 | ADS1115 | 0x48 - 0x4B | 4-channel 16-bit A/D converter
14 | USE_INA219 | xsns_13 | INA219 | 0x40 - 0x41, 0x44 - 0x45 | Low voltage current sensor
15 | USE_SHT3X | xsns_14 | SHT3X | 0x44 - 0x45 | Temperature and Humidity sensor
15 | USE_SHT3X | xsns_14 | SHTC3 | 0x70 | Temperature and Humidity sensor
15 | USE_SHT3X | xsns_14 | SHT4X | 0x44 - 0x45 | Temperature and Humidity sensor
15 | USE_SHT3X | xsns_14 | SHTCX | 0x70 | Temperature and Humidity sensor
16 | USE_TSL2561 | xsns_16 | TSL2561 | 0x29, 0x39, 0x49 | Light intensity sensor
17 | USE_MGS | xsns_19 | Grove | 0x04 | Multichannel gas sensor
18 | USE_SGP30 | xsns_21 | SGP30 | 0x58 | Gas (TVOC) and air quality sensor
@ -101,3 +102,4 @@ Index | Define | Driver | Device | Address(es) | Description
65 | USE_ADE7880 | xnrg_23 | ADE7880 | 0x38 | Energy monitor
66 | USE_PCF85363 | xsns_99 | PCF85363 | 0x51 | Real time clock
67 | USE_DS3502 | xdrv_61 | DS3502 | 0x28 - 0x2B | Digital potentiometer
68 | USE_HYT | xsns_97 | HYTxxx | 0x28 | Temperature and Humidity sensor

View File

@ -94,4 +94,4 @@ Module | LCode | Description
06 TTGO Watch | x | TTGO Watch
07 M5Stack Core2 | x | M5Stack Core2
Over 2300 additional devices are supported using [templates](TEMPLATES.md).
Over 2370 additional devices are supported using [templates](TEMPLATES.md).

View File

@ -1,7 +1,7 @@
![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg)
Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) and [ESP32](https://en.wikipedia.org/wiki/ESP32) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**.
_Written for PlatformIO with limited support for Arduino IDE._
_Written for PlatformIO._
[![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](http://ota.tasmota.com/tasmota/release)
[![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest)
@ -17,7 +17,7 @@ _Written for PlatformIO with limited support for Arduino IDE._
## Easy install
Easy initial installation of Tasmota can be performed using the [Tasmota WebInstaller](https://arendst.github.io/Tasmota-firmware/).
Easy initial installation of Tasmota can be performed using the [Tasmota WebInstaller](https://tasmota.github.io/install/).
If you like **Tasmota**, give it a star, or fork it and contribute!

View File

@ -33,9 +33,9 @@ While fallback or downgrading is common practice it was never supported due to S
This release will be supported from ESP8266/Arduino library Core version **2.7.4.9** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
This release will be supported from ESP32/Arduino library Core version **2.0.2.1**.
This release will be supported from ESP32/Arduino library Core version **2.0.3**.
Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.2 have been removed.
Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.3 have been removed.
## Support of TLS
@ -72,29 +72,32 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release
Historical binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release-11.1.0
- http://ota.tasmota.com/tasmota/release-12.0.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
### ESP32 based
### ESP32, ESP32-C3, ESP32-S2 and ESP32-S3 based
The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.3**.
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 and 4M+ flash.
- **tasmota32xy.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3/S2/S3 and 4M+ flash.
- **tasmota32xycdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3/S2/S3 with serial over embedded USB CDC only and 4M+ flash.
- **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash.
- **tasmota32-AF.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash.
- **tasmota32-ir.bin** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features for 4M+ flash.
- **tasmota32-display.bin** = The Display version without Energy Monitoring but adds display support for 4M+ flash.
- **tasmota32-lvgl.bin** = The LVGL version adds Light and Versatile Graphics Library (LVGL) display support for 4M+ flash.
- **tasmota32-webcam.bin** = The Webcam version adds webcam support for 4M+ flash.
- **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash.
- **tasmota32-display.bin** = The Display version without Energy Monitoring but adds display support for 4M+ flash.
- **tasmota32-ir.bin** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features for 4M+ flash.
- **tasmota32-lvgl.bin** = The LVGL version adds Light and Versatile Graphics Library (LVGL) display support for 4M+ flash.
- **tasmota32-nspanel.bin** = The Sonoff NSPanel Smart Scene Wall Switch version with HASPmota display support.
- **tasmota32-webcam.bin** = The Webcam version adds webcam support for 4M+ flash.
- **tasmota32-zbbridgepro.bin** - The Sonoff Zigbee Bridge Pro version with CC2652P firmware load support.
Latest released binaries can be downloaded from
- https://github.com/arendst/Tasmota-firmware/tree/main/release-firmware
- http://ota.tasmota.com/tasmota32/release
Historical binaries can be downloaded from
- http://ota.tasmota.com/tasmota32/release-11.1.0
- http://ota.tasmota.com/tasmota32/release-12.0.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota32/release/tasmota32.bin``
@ -104,65 +107,44 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
## Changelog v11.1.0 Ostara
## Changelog v12.0.0 Paul
### Added
- Command ``SetOption135 1`` to disable LVGL splash screen
- Command ``SetOption136 1`` to disable single sensor reports from Tuya devices while keeping teleperiod reports [#15216](https://github.com/arendst/Tasmota/issues/15216)
- Command ``SetOption137 1`` to avoid MQTT publish of defined Tuya CMDs if SO66 is active [#15267](https://github.com/arendst/Tasmota/issues/15267)
- Command ``SetOption138 1`` to switch GUI energy multi-column layout from left/center (0) to right (1) align [#15342](https://github.com/arendst/Tasmota/issues/15342)
- Command ``SspmMap 0`` to reset Sonoff SPM default mapping
- Command ``TcpConnect <port><ip_address>`` to add client connection mode [#14874](https://github.com/arendst/Tasmota/issues/14874)
- Command ``RfTimeout 100..60000`` to disable duplicate RfReceive. Default 1000 [#15061](https://github.com/arendst/Tasmota/issues/15061)
- Command ``IfxSensor 1`` to send non-teleperiod data to influxdb
- Commands ``Sensor12 D0 .. D5, S0 .. S5`` allowing differential or single-ended modes [#15001](https://github.com/arendst/Tasmota/issues/15001)
- Command ``Sensor34 10 0|1|<weight in gram>`` to set HX711 fixed tare (0 = use auto tare, 1 = use calibrated tare, Any other value is user selected tare)
- Commands ``Sensor34 11 <valueA>`` and ``Sensor34 12 <valueB>`` to use HX711 absolute weight conversion [#15292](https://github.com/arendst/Tasmota/issues/15292)
- NeoPool commands ``NPpHMin``, ``NPpHMax``, ``NPpH``, ``NPRedox``, ``NPHydrolysis``, ``NPIonization``, ``NPChlorine`` and ``NPControl`` [#15015](https://github.com/arendst/Tasmota/issues/15015)
- NeoPool system voltages display
- TasmotaSerial implement ``end()``
- Support for improv as used by esp-web-tools
- Support for up to four DS3502 digital potentiometers with command ``Wiper<x> 0..127``
- Support for ADE7880 3 phase energy monitor as used in Shelly 3EM [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Support for PCF85363 RTC as used in Shelly 3EM [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Full RTC chip integration and synchronisation when using UBX (=GPS), NTP or manual time
- NeoPool JSON modules, power module, cell info, chlorine, conductivity and ionization
- ESP32 Berry always enable rules
- ESP32 Berry bootloop protection
- ESP32 Support for OpenHASP v1.0 by Stephan Hadinger [#15307](https://github.com/arendst/Tasmota/issues/15307)
- ESP32 support for BLE Mi scale V1 [#13517](https://github.com/arendst/Tasmota/issues/13517)
- ESP32 integrate Homekit in Bluetooth binary [#14818](https://github.com/arendst/Tasmota/issues/14818)
- ESP32 Berry virtual Alexa hue device [#14833](https://github.com/arendst/Tasmota/issues/14833)
- ESP32 TasmotaSerial uart mapping to support multiple ``begin()`` and implement ``getUart()`` [#14981](https://github.com/arendst/Tasmota/issues/14981)
- Command ``SetOption139 0/1`` to switch between pressure unit "mmHg" (0) or "inHg" (1) when ``SO24 1`` [#15350](https://github.com/arendst/Tasmota/issues/15350)
- Command ``SetOption140 0/1`` to switch between MQTT Clean Session (0) or Persistent Session (1) [#15530](https://github.com/arendst/Tasmota/issues/15530)
- Command ``SetOption141 1`` to disable display of module name in GUI header
- Command ``SetOption142 1`` to wait 1 second for wifi connection solving some FRITZ!Box modem issues [#14985](https://github.com/arendst/Tasmota/issues/14985)
- Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy [#15513](https://github.com/arendst/Tasmota/issues/15513)
- Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules [#13447](https://github.com/arendst/Tasmota/issues/13447)
- Command ``SSerialSend9 0/1`` to enable Serial Bridge console Tee for debugging purposes
- Support for Sonoff MS01 soil moisture sensor [#15335](https://github.com/arendst/Tasmota/issues/15335)
- Support for daisy chaining MAX7219 displays [#15345](https://github.com/arendst/Tasmota/issues/15345)
- Support for Sensirion SHT4X using define USE_SHT3X [#15349](https://github.com/arendst/Tasmota/issues/15349)
- Support for Sonoff SPM v1.2.0
- Support for Sonoff Zigbee Bridge Pro by Stephan Hadinger [#15701](https://github.com/arendst/Tasmota/issues/15701)
- Support for Sonoff NSPanel Smart Scene Wall Switch
- Support for flowrate meters like YF-DN50 and similary [#15474](https://github.com/arendst/Tasmota/issues/15474)
- Support for 5-channel light dimmer driver BP5758D used in Tuya bulbs [#15713](https://github.com/arendst/Tasmota/issues/15713)
- Support for HYTxxx temperature and humidity sensor [#15715](https://github.com/arendst/Tasmota/issues/15715)
- Sonoff SPM delayed SetPowerOnState [#13447](https://github.com/arendst/Tasmota/issues/13447)
- ESP32 Command ``Restart 3`` to switch between SafeBoot and Production
### Breaking Changed
- Remove support for Internet Explorer by allowing ECMAScript6 syntax using less JavaScript code bytes [#15280](https://github.com/arendst/Tasmota/issues/15280)
### Changed
- Adafruit BusIO library from v1.0.10 to v1.11.0
- TasmotaSerial library from v3.4.0 to v3.5.0 [#14981](https://github.com/arendst/Tasmota/issues/14981)
- Sonoff SPM increase max number of relays supported to 32 (8 SPM-4Relay modules)
- Extent number of pulsetimers from 8 to 32 [#8266](https://github.com/arendst/Tasmota/issues/8266)
- Consolidate three RTC chip drivers (DS3231, BM8563, PCF85363) into one driver updating RTC as soon as possible after restart
- DS3231 I2C address define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS``
- Display of energy values in GUI use columns when define ``USE_ENERGY_COLUMN_GUI`` is enabled (default)
- ESP8266 Shrinked tasmota-minimal.bin by removing all commands except ``Upgrade``, ``Upload``, ``OtaUrl``, ``Seriallog``, ``Weblog`` and ``Restart``
- ESP32 Arduino core from v2.0.2.2 to v2.0.3
- ESP32 LVGL library from v8.1.0 to v8.2.0
- ESP32 NimBLE library from v1.3.3 to v1.3.6
- ESP32 update the internal Berry type system to sync with Skiars Berry repository. No expected impact on code, but .bec files need to be generated again [#14811](https://github.com/arendst/Tasmota/issues/14811)
- Restructured tasmota source directories taking benefit from PlatformIO Core v6.0.2
- Prepare to remove dedicated Home Assistant discovery in favour of Tasmota Discovery and hatasmota
- ESP32 Tasmota SafeBoot with changed partition scheme allowing larger binaries
- ESP32 increase Serial Bridge input buffer from 130 to 520 characters
### Fixed
- SSPM energy yesterday when zero
- NeoPool NPBit and NPRead/NPReadL output
- HX711 false readings by removing large deviations
- GPIO OptionE1 selection regression [#14821](https://github.com/arendst/Tasmota/issues/14821)
- BL0939, BL0940 and BL0942 energy monitoring buffer miscompares resulting in wrong daily energy values regression from v9.5.0.8 [#14829](https://github.com/arendst/Tasmota/issues/14829)
- Wiegand 34-bit rfid reading and presentation [#14834](https://github.com/arendst/Tasmota/issues/14834)
- Orno WE517 power meter phase 2 current reactive [#14841](https://github.com/arendst/Tasmota/issues/14841)
- TasMesh relaunch wifi on esp_now_init failure [#15334](https://github.com/arendst/Tasmota/issues/15334)
- ESP32 save settings after OTA upload regression from v10.0.0.3
- ESP32 PowerOnState [#15084](https://github.com/arendst/Tasmota/issues/15084)
- Improv initial or erase device installation failing to provide Configure WiFi option
- SCD40 start low power command [#15361](https://github.com/arendst/Tasmota/issues/15361)
- BL09xx negative power presentation [#15374](https://github.com/arendst/Tasmota/issues/15374)
- Possible pin output toggle after power on [#15630](https://github.com/arendst/Tasmota/issues/15630)
- Reduce blocking by adding WifiPollDns before resolving NTP and/or MQTT server names [#14394](https://github.com/arendst/Tasmota/issues/14394)
- SHT1X driver hangs and wrong values on ESP32 [#15790](https://github.com/arendst/Tasmota/issues/15790)
- ESP32 Arduino Core WiFi timeout is changed from msec to seconds
### Removed
- Command ``Sensor33`` and replaced by ``RtcNtpserver``
- Command ``Sensor34 7`` as now active tare is persistent resulting in calculated current weight
- Arduino IDE support

View File

@ -2,7 +2,7 @@
# Templates
Find below the available templates as of April 2022. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)
Find below the available templates as of June 2022. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)
## Addressable LED
```
@ -140,6 +140,11 @@ Wipro Garnet NS9100 810lm {"NAME":"Wipro 9W CCT","GPIO":[0,0,0,0,0,416,0,0,0,
Wyze A19 800lm {"NAME":"Wyze Bulb","GPIO":[5728,0,0,0,0,0,0,0,0,416,417,0,0,0],"FLAG":0,"BASE":48}
```
## Camera
```
M5Stack PSRAM Timer Camera (OV3660) {"NAME":"M5STACK CAM","GPIO":[0,0,0,0,0,5091,1,0,0,0,0,4960,1,0,5093,5095,0,5184,5120,5056,0,5024,5152,4992,0,0,0,0,5088,0,5090,5089,5094,0,0,5092],"FLAG":0,"BASE":2}
```
## Ceiling Light
```
BAZZ 14" RGBCCT {"NAME":"WF19129W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
@ -187,6 +192,7 @@ Zemismart Door Window {"NAME":"Zemismart","GPIO":[1,2272,1,2304,1,1,0,0,1
## Curtain Module
```
BlitzWolf {"NAME":"BlitzWolf SS6 2 Gang","GPIO":[0,0,32,0,480,0,0,0,161,160,224,225,0,0],"FLAG":0,"BASE":18}
LoraTap In-Wall {"NAME":"SC500W","GPIO":[0,0,0,576,160,161,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18}
LoraTap In-Wall {"NAME":"SC511WSC","GPIO":[0,1,0,320,32,34,0,0,224,33,226,225,0,0],"FLAG":0,"BASE":18}
MS-108 In-Wall {"NAME":"MS-108","GPIO":[0,0,0,0,161,160,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18}
@ -194,11 +200,6 @@ MS-108WR RF Curtain Module {"NAME":"MS-108WR","GPIO":[1,1,1,544,32,33,1,1,225,
QS-WIFI-C01-RF {"NAME":"Shutter-QS-WIFI-C01","GPIO":[0,0,1,0,288,0,0,0,32,33,224,225,0,0],"FLAG":0,"BASE":18}
```
## Curtain Motor
```
Steren {"NAME":"Steren_SHOME-155","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"SO54 1|SO20 1|TuyaMCU 61,1|TuyaMCU 21,2|TuyaMCU 27,3|TuyaMCU 97,5|TuyaMCU 11,6|TuyaMCU 62,7|TuyaMCU 63,8|TuyaMCU 81,9|TuyaMCU 98,10|TuyaMCU 82,11"}
```
## Curtain Switch
```
Anccy {"NAME":"Anccy Shutter","GPIO":[544,0,289,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18}
@ -215,6 +216,7 @@ LoraTap SC411WSC-EU RF Remote {"NAME":"Loratap","GPIO":[0,0,0,34,226,32,0,0,33,
Maxcio WF-CS01 {"NAME":"Maxcio","GPIO":[544,0,289,162,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18}
Moes RF {"NAME":"Moes WS-EUR-CW","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
SCS86-03AJAI {"NAME":"ESE86-03AJAI","GPIO":[544,227,289,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18}
Teekar 3rd Generation {"NAME":"Teekar-Tag","GPIO":[0,0,0,32,33,34,0,0,225,0,226,0,224,0],"FLAG":0,"BASE":18}
Teekar SYS-CS 01 {"NAME":"Teekar-Tag","GPIO":[320,0,544,33,225,162,0,0,0,224,321,258,32,0],"FLAG":0,"BASE":18}
Teepao {"NAME":"Teepao","GPIO":[576,322,226,33,225,34,0,0,320,224,321,0,32,0],"FLAG":0,"BASE":18}
WF-CS01 {"NAME":"ShutterSwitch","GPIO":[544,227,289,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18,"CMND":"Rule1 1"}
@ -246,13 +248,16 @@ Vacplus 50 Pint {"NAME":"VacPlus Dehumidifier","GPIO":[0,0,0,0,0,0,
## Development Board
```
Adafruit ESP32 Feather {"NAME":"HUZZAH32","GPIO":[0,0,0,0,4709,0,1,1,1,288,1,1,1,1,0,1,0,0,608,640,0,4705,4704,1,0,0,0,0,1,1,4706,4710,4708,0,0,4707],"FLAG":0,"BASE":1}
Adafruit HUZZAH {"NAME":"Huzzah","GPIO":[32,0,320,0,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":18}
Adafruit ESP32 Feather V2 {"NAME":"HUZZAH32v2","GPIO":[1376,0,3840,0,1,1,0,0,1,1,1,1,0,0,0,1,608,1,640,0,0,1,1,1,0,1,1,0,1,1,1,4704,1,1,0,1],"FLAG":0,"BASE":1}
Adafruit HUZZAH ESP8266 {"NAME":"Huzzah","GPIO":[32,0,320,0,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":18}
Adafruit HUZZAH32 ESP32 Feather {"NAME":"HUZZAH32","GPIO":[0,0,0,0,4709,0,1,1,1,288,1,1,1,1,0,1,0,0,608,640,0,4705,4704,1,0,0,0,0,1,1,4706,4710,4708,0,0,4707],"FLAG":0,"BASE":1}
Adafruit QT Py ESP32 Pico {"NAME":"QTPy ESP32 Pico","GPIO":[32,3200,0,3232,1,1376,0,0,1,1,1,1,0,0,0,608,0,0,640,0,0,1,1,1,0,1,3840,0,1,1,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Ai-Thinker Camera {"NAME":"AITHINKER CAM","GPIO":[4992,1,672,1,416,5088,1,1,1,6720,736,704,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,576,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":2}
AZ-Envy Environmental Sensor {"NAME":"AZ Envy","GPIO":[32,0,320,0,640,608,0,0,0,0,0,0,0,4704],"FLAG":0,"BASE":18}
ESP32 Lite V1.0.0 {"NAME":"ESP32 Lite V1.0.0","GPIO":[1,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,1,0,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0],"FLAG":0,"BASE":1}
Freenove ESP32-WROVER.DEV Camera {"NAME":"Freenove-WROVER-Cam","GPIO":[1,1,1,1,5088,5089,0,0,1,1,1,1,1,1,5090,5091,1,4992,5184,5152,1,5120,5024,5056,0,0,0,0,1,1,5094,5095,5092,1,1,5093],"FLAG":0,"BASE":1}
LC Technology MicroPython Maker {"NAME":"LC-ESP-Python","GPIO":[1,1,544,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18}
LilyGO RGB LED Ring Encoder {"NAME":"T-Encoder","GPIO":[0,0,1,0,1,0,0,0,1,1,1,1,0,0,0,480,6212,0,0,0,0,449,450,448,0,0,0,0,0,0,0,0,3296,3264,32,0],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"}
LilyGO T7 v1.5 {"NAME":"LilyGO T7 V1.5","GPIO":[1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,544,0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,4704,1,0,0,1],"FLAG":0,"BASE":1}
LilyGO TTGO ESP32 Ethernet {"NAME":"T-Internet-POE v1.2","GPIO":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"EthType 0|EthClockMode 1|EthAddress 0"}
M5Stack Atom Lite ESP32 {"NAME":"M5Stack Atom Lite","GPIO":[1,1,1,1,1,1,1,1,1056,1,1,1,1,1,1,1,0,1,1,1,0,1,640,1376,0,0,0,0,608,1,1,1,1,0,0,32],"FLAG":0,"BASE":1}
@ -374,7 +379,9 @@ Maxcio Rotary {"NAME":"EDM-1WAA-EU","GPIO":[1,1,1,1,1,1,0,0,1,1,1
Minoston 3-Way {"NAME":"MS10W","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54}
Moes {"NAME":"MOES DS01","GPIO":[1,1,1,1,1,1,0,0,1,2304,1,2272,1,0],"FLAG":0,"BASE":54}
PS-16-DZ {"NAME":"PS-16-DZ","GPIO":[1,3200,1,3232,1,1,0,0,1,288,1,1,1,0],"FLAG":0,"BASE":58}
Stitch {"NAME":"Stitch 35558","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 21,3|DimmerRange 21,255"}
Teekar UIW001-1 {"NAME":"Teekar UIW001-","GPIO":[0,3232,416,3200,640,608,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18}
Tessan 3 Way {"NAME":"Tessan-STD02","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"SO97 | TuyaMCU 11,1 | TuyaMCU 21,2 | DimmerRange 20,255"}
Tessan MJ-SD02 {"NAME":"MJ-SD02","GPIO":[34,33,0,323,576,322,0,0,321,416,320,96,256,0],"FLAG":0,"BASE":73}
TopGreener TGWF500D {"NAME":"TopGreener-Dimmer","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
TreatLife 400W {"NAME":"DS02S Dimmer","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
@ -414,9 +421,10 @@ LilyGO TTGO T-Camera {"NAME":"T-Camera","GPIO":[1,1,1,1,4992,5120,1,1,1,
LilyGO TTGO T-Display 1.14in {"NAME":"ESP32-ttgo-display","GPIO":[0,1,1,1,992,6592,1,1,1,1,1,1,6624,1,896,864,0,1,1,1024,0,1,1,1,0,0,0,0,1,1,1,33,1,0,0,1],"FLAG":0,"BASE":1}
LilyGO TTGO T-Watcher {"NAME":"TTGO T4 v1.3","GPIO":[35,1,672,1,992,1024,1,1,832,768,736,704,1,1,896,0,0,640,608,864,0,0,1,6368,0,0,0,0,6400,1,1,4704,1,32,33,34],"FLAG":0,"BASE":1}
LilyGO TTGO TO ESP8266 OLED SH1106 Weather Station {"NAME":"TTGO T12","GPIO":[1,1,1,1,608,640,0,0,32,34,33,1,1,1],"FLAG":0,"BASE":18}
Lolin TFT 2.4 Touch Shield Template {"NAME":"Lolin TFT 2.4 Touch Shield","GPIO":[224,225,226,1,1,6400,1,1,1,1,1,1,1,7264,736,672,0,1,992,704,0,1,6368,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
Lolin TFT 2.4 Touch Shield {"NAME":"Lolin TFT 2.4 Touch Shield","GPIO":[224,225,226,1,1,6400,1,1,1,1,1,1,1,7264,736,672,0,1,992,704,0,1,6368,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
M5Stack Core2 {"NAME":"M5Stack Core 2","GPIO":[6210,1,1,1,6720,768,0,0,0,1,1,800,0,0,736,1,0,641,609,704,0,0,0,1,0,0,0,0,640,608,1,1,1,0,672,0],"FLAG":0,"BASE":1}
M5Stack M5StickC {"NAME":"M5StickC","GPIO":[1,0,0,0,0,768,1056,576,0,736,0,704,0,0,1024,0,0,641,609,800,0,0,1,0,0,0,0,0,640,608,1,0,1,32,6210,33],"FLAG":0,"BASE":1}
M5Stack Tough {"NAME":"M5Stack Tough","GPIO":[6210,1,1,1,6720,768,0,0,0,1,1,800,0,0,736,1,0,641,609,704,0,0,0,1,0,0,0,0,640,608,1,1,1,0,672,7968],"FLAG":0,"BASE":1}
ODROID-GO Game Kit {"NAME":"ODROID-GO","GPIO":[32,3200,544,3232,608,768,0,0,6210,33,416,640,1,1,736,672,0,800,6720,704,0,0,0,34,0,0,0,0,164,165,3328,3329,4866,0,0,35],"FLAG":0,"BASE":3}
OLED Display Module 0.66" for Wemos D1 Mini {"NAME":"OLED 64x48","GPIO":[1,1,1,1,640,608,0,0,1,1,1,1,1024,1],"FLAG":0,"BASE":18}
Wireless Tag 3.5" Touch {"NAME":"WT32-SC01","GPIO":[6210,1,1,1,1,1,0,0,1,704,736,768,1,1,640,608,1,800,1024,992,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
@ -477,6 +485,7 @@ Anko HEGSM40 {"NAME":"Anko HEGSM40","GPIO":[0,0,0,0,0,0,0,0,0,23
Arlec 117cm Aurora Digital Tower {"NAME":"ATF4601HA","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54}
Arlec 45cm DC Pedestal {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 61,2 | TuyaMCU 64,3 | TuyaMCU 99,6 | TuyaMCU 12,101"}
Arlec Smart 45cm Smart DC Wall {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 61,2 | TuyaMCU 64,3 | TuyaMCU 99,6 | TuyaMCU 12,101"}
Duux Whisper Flex Battery Pack {"NAME":"Duux DXCF12","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 61,2 | TuyaMCU 62,3 | TuyaMCU 12,4 | TuyaMCU 13,5 | TuyaMCU 64,6"}
Duux Whisper Flex Smart {"NAME":"Duux Fan","GPIO":[0,0,0,0,0,0,0,0,0,0,2304,0,2272,0],"FLAG":0,"BASE":54}
Geek Aire 3D Oscillating Desktop {"NAME":"Geek Aire Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 12,4 | TuyaMCU 13,5"}
Goldair SleepSmart GCPF315 {"NAME":"Goldair Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
@ -535,6 +544,7 @@ A1 Universal Remote Control {"NAME":"A1 IR Controller","GPIO":[1,1,1,1,320,1088
AI Universal Remote {"NAME":"YTF IR Controller","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Alfawise KS1 {"NAME":"KS1","GPIO":[1,1792,32,1824,32,1088,0,0,320,0,1056,0,0,4704],"FLAG":0,"BASE":62}
Antsig Universal Remote Controller {"NAME":"Antsig Smart Wi-Fi IR","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Automate Things IR Bridge {"NAME":"AT-IRBR-1.4","GPIO":[1088,0,0,0,1056,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
auvisio S06 {"NAME":"NX-4519-675","GPIO":[0,0,0,0,288,1088,0,0,0,0,1056,0,0,0],"FLAG":0,"BASE":18}
Avatto Temperature and Humidity Sensor and {"NAME":"S08Pro","GPIO":[0,640,0,608,288,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":18}
BlitzWolf BW-RC1 {"NAME":"BW-RC1","GPIO":[0,0,0,0,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
@ -548,6 +558,7 @@ Jinvoo AC/TV Box {"NAME":"Jinvoo IR Controller","GPIO":[1,1,1,1,320,
JS-IR1 Universal Remote {"NAME":"JS-IR1","GPIO":[1,1,1,1,288,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":18}
Lenovo SE-741C {"NAME":"Lenovo IR","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Mirabella Genio I002577 {"NAME":"Genio IR TxRx","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Moes Tuya Remote Control {"NAME":"Moes IR Controller","GPIO":[1,1,1,1,1,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Nedis Universal Remote Control {"NAME":"Nedis IR Controller","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
NEO Coolcam Remote Controller {"NAME":"Neo Coolcam IR","GPIO":[1,3200,1,3232,576,1088,0,0,320,32,1056,0,0,0],"FLAG":0,"BASE":62}
Nivian Smart Infrared Controller {"NAME":"Nivian NVS-SMARTIR-W2","GPIO":[0,3200,0,3232,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
@ -557,6 +568,7 @@ RM mini {"NAME":"RM mini","GPIO":[1,1,1,1,320,1088,0,0,0,32
Smartpoint Smart Remote {"NAME":"Smartpoint SPCNTRL-WM","GPIO":[0,0,0,0,288,1088,0,0,0,0,1056,0,0,0],"FLAG":0,"BASE":18}
STITCH {"NAME":"Stitch 35753","GPIO":[0,0,0,0,288,1088,0,0,0,64,1056,0,0,0],"FLAG":0,"BASE":62}
SZMDLX IR Remote Controller {"NAME":"SZMDLX WiFi IR","GPIO":[0,0,0,0,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Tellur Remote Control {"NAME":"Tellur TLL331241","GPIO":[0,0,0,0,1056,1088,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Tuya Smart Remote {"NAME":"IR Controller","GPIO":[1,1,1,1,1,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
UFO R1 Universal Remote {"NAME":"UFO-R1","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
Uniplay Universal Remote {"NAME":"Uniplay IR","GPIO":[1,3200,1,3232,576,1088,0,0,320,32,1056,0,0,0],"FLAG":0,"BASE":62}
@ -565,7 +577,7 @@ YTF Universal Remote {"NAME":"YTF IR Controller","GPIO":[1,1,1,1,320,108
## IR Gateway
```
Automate Things IR Bridge {"NAME":"AT-IRBR-1","GPIO":[0,0,0,0,1056,1088,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Automate Things IR Bridge {"NAME":"AT-IRBR-1.0","GPIO":[0,0,0,0,1056,1088,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
```
## Illuminance Sensor
@ -626,6 +638,7 @@ RGB+CCT 12-24V {"NAME":"WS05","GPIO":[0,0,0,0,0,420,0,0,418,417,41
RGBW 12-24V {"NAME":"*WS04","GPIO":[0,0,0,0,0,0,0,0,417,418,416,419,0,0],"FLAG":0,"BASE":18}
Shelly RGBW2 {"NAME":"Shelly RGBW2","GPIO":[0,0,288,0,419,1,0,0,416,32,418,417,0,0],"FLAG":0,"BASE":18}
Spectrum Smart RGBCCT {"NAME":"Spectrum Smart WOJ+05641","GPIO":[32,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
Xunata Led Controller High Voltage 110/220V {"NAME":"KL-LED-WIFI-AC","GPIO":[0,0,0,0,0,0,0,0,0,416,0,0,0,0],"FLAG":0,"BASE":18}
ZJ-WF-ESP-A v1.1 {"NAME":"RGB2","GPIO":[0,0,0,0,0,0,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18}
```
@ -665,6 +678,7 @@ LSC RGBW {"NAME":"LSC RGBW Strip","GPIO":[1088,0,0,0,416,0,0
Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Maxonar Lightstrip Pro XS-SLD001 {"NAME":"Maxonar LED","GPIO":[0,0,0,0,0,416,0,0,418,32,417,0,0,0],"FLAG":0,"BASE":18}
MegaLight Smart RGB {"NAME":"MegaLight Smart LED-Stripe","GPIO":[0,0,0,0,417,1088,0,0,418,416,0,0,32,0],"FLAG":0,"BASE":18}
Merkury Innovations MI-EW003-999W {"NAME":"MI-EW003-999W ","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Mirabella Genio RGB+CW {"NAME":"MirabellaStrip","GPIO":[32,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
Monster Smart IlluminEssence {"NAME":"MI-EW003-999W ","GPIO":[32,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
@ -728,12 +742,13 @@ Novostella UT88835 20W Flood {"NAME":"Novo 20W Flood","GPIO":[0,0,0,0,416,419,0
Novostella UT88836 20W Flood {"NAME":"Novo 20W Flood","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Nue Vision Care Desk Lamp {"NAME":"Nue Vision Desk Lamp VC18","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 21,3 | TuyaMCU 23,4"}
Philips Wiz 24W LED White Batten {"NAME":"PHILIPS-wiz-24w","GPIO":[0,0,0,0,417,0,0,0,0,416,0,0,0,0],"FLAG":0,"BASE":18}
Polycab Hohm Avenir 20W Batten {"NAME":"PolycabBatten","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":18}
Sonoff {"NAME":"Sonoff BN-SZ","GPIO":[0,0,0,0,0,0,0,0,416,320,0,0,0,0],"FLAG":0,"BASE":22}
Spotlight 9cm RGB+W 7W {"NAME":"Spotlight RGBW","GPIO":[0,0,0,0,0,0,0,0,0,3008,0,3040,0,0],"FLAG":0,"BASE":27}
TCP WPAN Square 600X600mm 36W CCT Panel {"NAME":"TCPsmart LED Panel","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO92 1|DimmerRange 30,100"}
Teckin FL41 {"NAME":"Teckin FL41","GPIO":[0,0,0,0,0,32,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
Wipro 20W LED RGB Batten {"NAME":"Wipro RGBW Tubelight","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,1],"FLAG":0,"BASE":18}
Wipro Next Smart Batten 20W CCT {"NAME":"WIPROBatten","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,4704],"FLAG":0,"BASE":18}
Wipro Next Smart Batten 20W CCT {"NAME":"WIPROBatten","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":18}
Xiaomi Mi Computer Monitor Light Bar 1S {"NAME":"Mijia Desk Lamp 1S (MJGJD02YL)","GPIO":[0,0,0,0,3840,0,1,1,0,0,0,0,0,0,0,416,0,417,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"DimmerRange 45,255"}
Xiaomi Mi Desk Lamp Pro {"NAME":"Mi Desk Lamp Pro","GPIO":[6212,0,416,0,417,0,0,0,3840,0,0,0,160,640,608,0,0,0,0,0,0,0,3296,3264,0,0,0,0,0,32,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"DimmerRange 30,100"}
Xiaomi Mi LED Desk Lamp 1S {"NAME":"Mi LED Desk Lamp 1S","GPIO":[6212,0,416,0,417,0,0,0,3840,0,0,0,160,640,608,0,0,0,0,0,0,0,3264,3296,0,0,0,0,0,32,0,0,0,0,0,0],"FLAG":3,"BASE":66,"CMND":"DimmerRange 30,100|Fade 1|PowerOnFade 1|Speed 2"}
@ -751,7 +766,7 @@ Digital Body Fat Scale {"NAME":"TuyaScale","GPIO":[0,2272,0,2304,0,0,0,0,0
Dual-Pump Automatic Watering System {"NAME":"WD-01ADE","GPIO":[32,0,0,0,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
EaryKong Doorbell {"NAME":"Doorbell","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
electriQ 10000 BTU Wall Mounted Heat Pump Air Conditioner {"NAME":"electriQ IQOOL-SMART12HP","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
Eufy RoboVac C30 Robot Vacuum {"NAME":"Eufy Robovac","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,2 | TuyaMCU 12,101 | TuyaMCU 13,103"}
Eufy RoboVac C30 Robot Vacuum {"NAME":"Eufy Robovac","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,2 | TuyaMCU 12,101 | TuyaMCU 13,103 | SetOption97 1"}
Fujin Irrigation Timer {"NAME":"Fujin FJKB022-B4","GPIO":[0,0,0,0,32,0,0,0,288,0,224,0,0,0],"FLAG":0,"BASE":18}
iLONDA Fish Feeder {"NAME":"Feeder","GPIO":[0,0,0,0,32,320,0,0,352,0,224,0,0,0],"FLAG":0,"BASE":18}
Kogan 4.1kW Portable Air Conditioner (Reverse Cycle) {"NAME":"Kogan Panel Heater","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
@ -796,6 +811,7 @@ Tuya Alarm PIR {"NAME":"CT61W","GPIO":[0,0,0,0,0,0,0,0,0,160,480,2
## Motor
```
Steren Curtain {"NAME":"Steren_SHOME-155","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"SO54 1|SO20 1|TuyaMCU 61,1|TuyaMCU 21,2|TuyaMCU 27,3|TuyaMCU 97,5|TuyaMCU 11,6|TuyaMCU 62,7|TuyaMCU 63,8|TuyaMCU 81,9|TuyaMCU 98,10|TuyaMCU 82,11"}
Zemismart BCM300D-TY {"NAME":"Zemistart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
Zemismart Blinds Controller {"NAME":"Zemismart Blind","GPIO":[1,1,1,1,1,1,0,0,1,2304,1,2272,1],"FLAG":0,"BASE":54}
Zemismart Curtain {"NAME":"Zemismart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
@ -859,6 +875,7 @@ Merkury {"NAME":"Merkury Switch","GPIO":[0,0,0,0,32,0,0,0,0
Minoston MP22W {"NAME":"Minoston MP22W","GPIO":[0,0,0,0,320,0,0,0,224,64,0,0,0,0],"FLAG":0,"BASE":18}
Nedis PO120 IP44 {"NAME":"WIFIPO120FWT","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
Obi Stecker IP44 {"NAME":"OBI-Outdoor-Socket2","GPIO":[0,0,0,0,224,32,0,0,576,288,1,1,1,1],"FLAG":0,"BASE":18}
Oittm IP44 15A {"NAME":"Oittm Outdoor","GPIO":[576,0,320,0,2688,2656,0,0,224,2592,0,0,0,0],"FLAG":0,"BASE":57}
Oittm Outdoor {"NAME":"Oittm Outdoor","GPIO":[32,0,0,0,0,0,0,0,0,0,320,224,1,0],"FLAG":0,"BASE":18}
Peteme PS-1602 {"NAME":"Peteme Outdoor","GPIO":[32,0,0,0,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
Poweradd {"NAME":"POWERADD","GPIO":[0,0,0,0,320,321,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18}
@ -908,10 +925,9 @@ Alfawise PF1006 {"NAME":"PF1006","GPIO":[0,0,32,0,0,0,0,0,0,320,224
Alfawise PME1606 {"NAME":"PME1606","GPIO":[0,0,0,32,2688,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18}
Amped Wireless {"NAME":"AWP48W","GPIO":[0,0,0,0,320,32,0,0,0,289,224,0,0,0],"FLAG":0,"BASE":18}
Amysen JSM-WF02 {"NAME":"Amysen JSMWF02","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
Amysen YX-WS01 {"NAME":"Amysen YX-WS01","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
ANBES ABS-CZ004 {"NAME":"ANBES ABS-CZ00","GPIO":[0,0,0,0,224,2688,0,0,2624,32,2656,225,33,0],"FLAG":0,"BASE":18}
Anncoe C318 {"NAME":"Anncoe C318","GPIO":[64,3072,1,3104,0,0,0,0,224,289,0,0,0,0],"FLAG":0,"BASE":18}
Anoopsyche AWP08L {"NAME":"AWP08L-Annopsy","GPIO":[0,0,0,0,32,320,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18}
Anoopsyche AWP08L {"NAME":"ANOOPSYCHE AWP08L","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
Anoopsyche SP-G01 {"NAME":"SP-G01","GPIO":[0,3072,0,3104,0,0,0,0,32,320,224,0,0,0],"FLAG":0,"BASE":41}
Anoopsyche SP15 {"NAME":"Anoop SP15","GPIO":[0,0,0,0,320,224,0,0,0,32,0,0,0,0],"FLAG":0,"BASE":18}
Anoopsyche UK1D {"NAME":"UK1D","GPIO":[0,32,0,0,2688,2656,0,0,2592,288,224,0,0,0],"FLAG":0,"BASE":6}
@ -936,12 +952,16 @@ Arlec Twin PC288HA {"NAME":"Arlec Twin","GPIO":[0,32,0,225,0,0,0,0,0,3
Athom 16A {"NAME":"Athom Power Monitoring Plug","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,1],"FLAG":0,"BASE":18}
Athom 16A AU {"NAME":"Athom PG05-AU16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1}
Athom 16A AU {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Athom 16A BR V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Athom 16A Brazil {"NAME":"Athom PG05-BR16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1}
Athom 16A EU V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Athom 16A Israel {"NAME":"Athom Power Monitoring Plug","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,1],"FLAG":0,"BASE":18}
Athom 16A Israel v2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Athom 16A Italy {"NAME":"Athom PG05-IT16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1}
Athom 16A UK {"NAME":"Athom PG04-UK16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
Athom 16A UK V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Athom 16A US {"NAME":"Athom PG03-US16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18}
Athom 16A US V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Atlantis {"NAME":"Atlantis Smart Plug","GPIO":[32,0,0,0,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18}
Atomi AT1217 {"NAME":"AT1217","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Aukey {"NAME":"Aukey SH-PA2","GPIO":[0,0,0,0,576,320,0,0,32,0,224,0,0,0],"FLAG":0,"BASE":18}
@ -1037,8 +1057,8 @@ Deltaco SH-P01E {"NAME":"DELTACO SH-P01E","GPIO":[0,320,0,32,2720,2
Deltaco SH-P02 {"NAME":"Deltaco SH-P02","GPIO":[33,0,0,0,2720,2656,0,0,2624,320,224,225,32,0],"FLAG":0,"BASE":18}
Denver 16A {"NAME":"Denver SHP-100","GPIO":[0,0,0,32,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":65}
Denver Dual {"NAME":"Denver SHP-200","GPIO":[576,0,0,2624,32,2720,0,0,224,33,2656,225,0,0],"FLAG":0,"BASE":18}
DETA 62120HA Smart Plug Base {"NAME":"DetaPlugBase","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
Deta 6930HA {"NAME":"DetaSmartPlug","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
DETA Base {"NAME":"DetaPlugBase","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
Digital LCD BL6523 {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,8000,8032,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Digma DiPlug 100S {"NAME":"Digma DiPlug 100s","GPIO":[320,0,544,1,0,2720,1,1,1,32,2656,224,0,1],"FLAG":0,"BASE":18}
Digma DiPlug 160M {"NAME":"DiPlug 160M","GPIO":[0,320,0,32,2720,2656,0,0,2624,321,224,0,0,0],"FLAG":0,"BASE":55}
@ -1231,7 +1251,8 @@ Luminea NX-4491 {"NAME":"Luminea NX-449","GPIO":[320,0,576,0,0,0,0,
Luminea NX-4541 {"NAME":"NX-4451","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":55}
Luminea ZX-2820 {"NAME":"ZX2820-675","GPIO":[0,0,0,32,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":65}
Luminea ZX-2858 {"NAME":"ZX2858-675","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":65}
Lunvon {"NAME":"Lunvon Smart Plug","GPIO":[32,0,0,0,0,0,288,224,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Lunvon 2000W {"NAME":"Lunvon Smart Plug","GPIO":[32,0,0,0,0,0,288,224,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Lunvon 3000W {"NAME":"Lunvon Smart Plug","GPIO":[32,0,0,0,0,0,288,224,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Martin Jerry V01 {"NAME":"MJ V01","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Martin Jerry XS-SSA01 {"NAME":"MJ_XS-SSA01","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
Maxcio W-UK007S {"NAME":"Maxcio","GPIO":[320,0,1,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45}
@ -1252,7 +1273,7 @@ Minleaf W-DEXI {"NAME":"W-DEXI","GPIO":[0,32,0,0,2720,2656,0,0,262
Mirabella Genio {"NAME":"GenioGpo","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
Mirabella Genio 1002341 {"NAME":"Genio 1","GPIO":[0,0,320,0,0,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":1}
Mirabella Genio Double Plug with USB Ports {"NAME":"Genio I002932","GPIO":[0,320,1,32,0,0,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18}
Mirabella Genio Dual USB {"NAME":"Mirabella Genio Wi-Fi Power Plug with Dual USB Port","GPIO":[0,0,0,32,0,0,0,0,0,320,0,224,0,0],"FLAG":0,"BASE":18}
Mirabella Genio Dual USB {"NAME":"Mirabella Genio Wi-Fi Power Plug with Dual USB Port","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
Mirabella Genio USB {"NAME":"Mirabella Genio 1002826","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":1}
Mirabella Genio USB Port {"NAME":"Genio I002341","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":1}
Mistral {"NAME":"Mistral Smart ","GPIO":[320,0,0,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
@ -1333,6 +1354,7 @@ See Switches {"NAME":"SEESWITCHES SSPG01WH","GPIO":[321,1,320,1,
Shelly Plug {"NAME":"Shelly Plug EU","GPIO":[0,0,0,0,224,2688,0,0,96,288,289,0,290,0],"FLAG":0,"BASE":18}
Shelly Plug S {"NAME":"Shelly Plug S","GPIO":[320,1,576,1,1,2720,0,0,2624,32,2656,224,1,4736],"FLAG":0,"BASE":45}
Shelly Plug US {"NAME":"Shelly Plug US","GPIO":[288,0,321,0,224,2720,0,0,2624,32,2656,544,0,0],"FLAG":0,"BASE":45}
Sieges {"NAME":"Sieges FLHS-ZN01","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
SilentNight {"NAME":"SilentNightPlug","GPIO":[0,0,0,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Silvergear Slimme Stekker {"NAME":"Silvergear SmartHomePlug","GPIO":[0,0,0,96,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
SimpleHome {"NAME":"SimpleHome","GPIO":[289,0,0,0,0,0,0,0,224,320,32,0,0,0],"FLAG":0,"BASE":1}
@ -1425,6 +1447,7 @@ Vivanco 39625 Smart Home Power Adapter {"NAME":"Vivianco","GPIO":[0,0,0,32,2688
Vivitar {"NAME":"Vivitar HA1003","GPIO":[576,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
Vivitar HA-1006 {"NAME":"HA-1006","GPIO":[0,0,0,0,320,0,0,0,224,64,0,0,0,0],"FLAG":0,"BASE":18}
Vivitar HA-1006-AU {"NAME":"HA-1006-AU","GPIO":[0,0,0,0,320,0,0,0,224,64,0,0,0,0],"FLAG":0,"BASE":18}
Vivitar Plug {"NAME":"HA-1005N-AU","GPIO":[0,0,0,0,544,0,0,0,224,64,0,0,0,0],"FLAG":0,"BASE":18}
Vizia 16A {"NAME":"Vizia 16A","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
W-DE004 {"NAME":"W-DE004","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,4704],"FLAG":0,"BASE":18}
WAGA life CHCZ02MB {"NAME":"WAGA CHCZ02MB","GPIO":[321,0,0,2624,0,2720,0,0,224,32,2656,320,0,0],"FLAG":0,"BASE":68}
@ -1470,6 +1493,7 @@ YT-E002 {"NAME":"YT-E002","GPIO":[576,0,0,0,33,0,0,0,225,32
YT-E003 {"NAME":"YT-E003-SP202","GPIO":[32,0,0,0,2720,2656,0,0,2624,288,225,224,65,0],"FLAG":0,"BASE":64}
Yuanguo KS-501 {"NAME":"Yuanguo_KS-501","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
YX-DE01 {"NAME":"YX-DE01","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
YX-WS01 {"NAME":"Generic","GPIO":[1,32,1,1,1,1,1,1,1,320,224,1,1,1],"FLAG":0,"BASE":18}
YX-WS02 {"NAME":"Amysen YX-WS02","GPIO":[1,32,1,1,1,1,0,0,1,320,224,1,1,4704],"FLAG":0,"BASE":18}
ZBR-001 {"NAME":"ZBR-001","GPIO":[32,1,1,1,2688,2656,0,0,2592,320,224,1,321,4704],"FLAG":0,"BASE":18}
ZettaGuard {"NAME":"ZettaGuard S25","GPIO":[0,0,0,0,289,224,0,0,288,0,32,0,0,0],"FLAG":0,"BASE":18}
@ -1555,6 +1579,7 @@ Meross MSS425 {"NAME":"Meross MSS425","GPIO":[260,0,0,0,320,0,0,0
Mirabella Genio 4 Outlet Power Board with 2 USB {"NAME":"Genio i002340","GPIO":[320,0,0,0,224,225,0,0,226,32,227,228,0,0],"FLAG":0,"BASE":18}
Mirabella Genio Powerboard {"NAME":"Genio Powerboa","GPIO":[224,288,0,0,226,225,0,0,228,32,229,227,0,0],"FLAG":0,"BASE":18}
Nedis P310 {"NAME":"Nedis WIFIP310","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18}
Nous 15A 3AC 3USB {"NAME":"NOUS A5T","GPIO":[0,3072,544,3104,0,259,0,0,225,226,224,0,32,4704],"FLAG":0,"BASE":18}
Nozdom 3AC+2USB {"NAME":"NOZDOM SWB3","GPIO":[544,0,289,0,0,226,0,0,224,32,225,227,0,0],"FLAG":0,"BASE":18}
Pearl CHA1555 3AC 4USB {"NAME":"Pearl CHA1555","GPIO":[32,0,0,225,2720,2656,0,0,2624,227,226,224,320,0],"FLAG":0,"BASE":18}
Powertech 4AC 2USB {"NAME":"Ptech MS6107","GPIO":[0,288,0,32,224,225,0,0,227,228,226,0,0,0],"FLAG":0,"BASE":18}
@ -1574,9 +1599,9 @@ SWB2 3AC + 2USB {"NAME":"SWB2","GPIO":[576,1,0,1,0,226,0,0,224,32,2
TCP Smart 4AC+USB {"NAME":"TCP WPS4WUK","GPIO":[1,320,0,32,226,227,0,0,225,224,228,0,0,1],"FLAG":0,"BASE":18}
Teckin SS30 {"NAME":"Teckin SS30","GPIO":[288,1,1,321,256,32,0,0,258,257,259,1,228,0],"FLAG":0,"BASE":18}
Tellur 3AC 4USB {"NAME":"Tellur","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18}
Tessan A4L-BK {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,227,226,0,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18}
Tessan {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,227,226,0,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18}
Tonbux SM-SO301-U {"NAME":"Tonbux SM-SO30","GPIO":[320,0,0,0,256,0,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18}
Useelink {"NAME":"Useelink","GPIO":[320,0,0,0,256,0,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18}
Useelink {"NAME":"Useelink","GPIO":[288,0,0,321,256,32,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18}
Vivitar HA-1007 {"NAME":"Vivitar HA-1007 Power Strip","GPIO":[544,0,0,0,227,228,0,0,225,224,226,0,35,1],"FLAG":0,"BASE":18}
Vivitar HA-1007-AU {"NAME":"HA-1007-AU","GPIO":[320,32,0,322,256,321,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18}
wesmartify essentials 4AC+4USB {"NAME":"essential_4_po","GPIO":[320,0,0,0,227,228,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18}
@ -1607,7 +1632,7 @@ ZLD64-EU-W {"NAME":"ZLD64-EU-W","GPIO":[0,320,0,32,225,224,0,0
## RF Gateway
```
Sonoff RF Bridge 433 {"NAME":"Sonoff Bridge","GPIO":[32,3200,1,3232,1,1,0,0,1,320,1,0,0,0],"FLAG":0,"BASE":25}
Virage Labs VirageBridge 433MHz {"NAME":"VirageBridge","GPIO":[32,3200,255,3232,255,255,0,0,255,320,255,0,0],"FLAG":0,"BASE":25}
Virage Labs VirageBridge 433MHz {"NAME":"VirageBridge","GPIO":[32,3200,1,3232,1,1,0,0,1,320,1,0,0],"FLAG":0,"BASE":25}
```
## RGB
@ -1638,7 +1663,6 @@ Arlec Smart 9.5W 806lm {"NAME":"Arlec RGBWW","GPIO":[0,0,0,0,416,419,0,0,4
Athom 12W 1000lm {"NAME":"LB03-12W-E27-TAS","GPIO":[0,0,0,0,416,419,0,0,417,452,418,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO92 1 | DimmerRange 24,100"}
Athom 15W 1400lm {"NAME":"LB01-15W-E27-TAS","GPIO":[0,0,0,0,416,419,0,0,417,452,418,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO92 1 | DimmerRange 24 100"}
Athom 4.5W 300lm {"NAME":"Athom LB10-5W-TAS","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
ATHOM 7W 600lm {"NAME":"LB01-7W-B22-TAS","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Athom 7W 600lm {"NAME":"LB01-7W-E27-TAS","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Aunics 7W 600lm {"NAME":"Aunics RGBW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Avatar 8W 800lm {"NAME":"Avatar 8W RGBCW","GPIO":[1,1,1,1,416,419,1,1,417,420,418,1,1,1],"FLAG":0,"BASE":18}
@ -1855,6 +1879,7 @@ Fcmila 7W {"NAME":"FCMILA E27 0.1","GPIO":[0,0,0,0,416,419,0,
Fcmila Spotlight 460lm {"NAME":"Fcmila LED 6W","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18}
Feit Electric BR30 650lm {"NAME":"BR30/RGBW","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18}
FFHL 12W 900lm {"NAME":"FFHL RGBW Bulb","GPIO":[0,0,0,0,0,416,0,0,418,419,417,0,0,0],"FLAG":0,"BASE":18}
Frankever A21 {"NAME":"FrankEver RGBW Bulb","GPIO":[0,1,5729,2272,1,2304,0,0,832,3008,896,3040,256,0],"FLAG":0,"BASE":27}
Fulighture A60 810lm {"NAME":"Fulighture A60","GPIO":[0,0,0,0,417,416,0,0,0,418,419,0,0,0],"FLAG":0,"BASE":18}
Fulighture RGBW 15W {"NAME":"Fulighture RGBW 15W","GPIO":[0,0,0,0,0,0,0,0,0,3008,0,3040,0,0],"FLAG":0,"BASE":18}
Garsent 10W {"NAME":"Garsent 10W RGBW-Bulb","GPIO":[0,0,0,0,0,418,0,0,417,0,416,419,0,4704],"FLAG":0,"BASE":18}
@ -1967,6 +1992,7 @@ V-Tac A60 11W 1055lm {"NAME":"V-TAC LED A60 ","GPIO":[0,0,0,0,4032,0,0,0
V-Tac A66 15W 1300lm {"NAME":"V-TAC VT-5117","GPIO":[0,0,0,0,4032,0,0,0,0,0,4064,0,0,0],"FLAG":0,"BASE":18}
V-TAC A95 18W 1350lm {"NAME":"V-TAC VT-5021","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18}
V-TAC G45 4.5W 300lm {"NAME":"V-TAC VT-5124","GPIO":[0,0,0,0,0,0,0,0,4065,0,4032,0,0,0],"FLAG":0,"BASE":18}
Vivitar 1100lm {"NAME":"Vivitar (Tuya) RGBW Lamp","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
Wallfire WF-05 {"NAME":"Wallfire E27","GPIO":[32,0,0,0,0,0,0,0,0,3008,0,3040,0,0],"FLAG":0,"BASE":27}
Wixann C37 5W 450lm {"NAME":"WIXANNE12","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Woopower 460lm {"NAME":"Woopower E14","GPIO":[0,0,0,0,0,0,0,0,0,3008,0,3040,0,0],"FLAG":0,"BASE":27}
@ -1982,7 +2008,7 @@ Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,2912,416,0,0
## Relay
```
Shelly Plus 2PM {"NAME":"Shelly Plus 2PM","GPIO":[0,0,192,0,0,0,1,1,224,225,0,0,0,0,193,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Shelly Plus 2PM {"NAME":"Shelly Plus 2PM","GPIO":[320,0,192,0,0,0,1,1,225,224,0,0,0,0,193,0,0,0,0,0,0,608,3840,32,0,0,0,0,0,640,0,0,3456,4736,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,32000,40000,3350"}
```
## Relay Board
@ -2015,6 +2041,7 @@ eWeLink PSF-B04 5V 7-32V 4 Channel {"NAME":"eWeLink 4CH","GPIO":[160,0,0,0,226,
Geekcreit 5V DIY 4 Channel Jog Inching Self-Locking {"NAME":"Geekcreit-4ch","GPIO":[160,0,0,0,226,225,161,162,224,288,163,227,0,0],"FLAG":0,"BASE":18}
Geekcreit Module 220V 10A {"NAME":"DIY ESP8266 Re","GPIO":[0,0,544,0,224,32,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
HW-622 ESP8266 {"NAME":"HW-622","GPIO":[0,0,544,0,224,32,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Kincony 16 Channel {"NAME":"KC868-A16 rev 1.4","GPIO":[32,1,1,1,640,608,1,1,1,1,1,1,1,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
Kincony 8 Channel {"NAME":"KC868-A8","GPIO":[32,0,1120,0,640,608,0,0,0,1,1,1152,0,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"EthClockMode 3 | EthAddress 0 | EthType 0 | I2CDriver2 1"}
Kincony IR+RF 4 Channel {"NAME":"KC868-A4","GPIO":[32,0,227,0,224,225,0,0,0,1312,1,226,0,0,480,1152,0,1120,1056,1088,0,1,1,1,0,0,0,0,4706,4707,4704,4705,1,0,0,1],"FLAG":0,"BASE":1}
LC Technology 12V 4 Channel {"NAME":"LC Technology 4CH Relay","GPIO":[224,0,225,0,226,227,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
@ -2042,6 +2069,8 @@ Yunshan 7-30V 10A {"NAME":"Yunshan 10A","GPIO":[32,1,288,1,224,161,0,
## Sensor
```
Genesense IoT Controller {"NAME":"GNS24","GPIO":[32,1,1312,1,256,320,1,1,256,1216,160,3840,1,4704],"FLAG":0,"BASE":18}
IOT4 Environmental {"NAME":"IOT4SH01BME680","GPIO":[0,0,0,0,0,0,0,0,640,0,608,0,0,0],"FLAG":0,"BASE":18}
Shelly 3EM Power Monitoring Module {"NAME":"Shelly 3EM","GPIO":[1,1,288,1,32,8065,0,0,640,8064,608,224,8096,0],"FLAG":0,"BASE":18}
```
@ -2073,6 +2102,7 @@ SmartBase E0260 {"NAME":"SmartBaseE0260","GPIO":[0,0,0,0,320,0,0,0,
AGL 2 Gang {"NAME":"AGL WiFi 02","GPIO":[0,0,544,0,0,33,0,0,225,224,0,0,32,0],"FLAG":0,"BASE":18}
AGL 3 Gang {"NAME":"AGL WiFi 03","GPIO":[0,0,544,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18}
Aoycocr SW1 {"NAME":"Aoycocr SW1","GPIO":[576,1,321,1,1,1,1,1,320,32,1,224,1,1],"FLAG":0,"BASE":18}
APPIO 1 Gang Switch {"NAME":"Appio-9608","GPIO":[0,0,0,0,0,32,0,0,0,0,0,224,288,0],"FLAG":0,"BASE":18}
Athom 1 Gang {"NAME":"Athom SW011EU","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
Athom 1 Gang {"NAME":"Athom SW031US","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
Athom 1 Gang No Neutral {"NAME":"Athom SW111EU","GPIO":[576,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
@ -2107,10 +2137,12 @@ Cinlinele 4 Gang {"NAME":"Cinlinele","GPIO":[0,2272,0,2304,0,0,0,0,0
CloudFree Light {"NAME":"CloudFree SW1","GPIO":[32,1,0,1,0,0,0,0,224,320,1,0,0,0],"FLAG":0,"BASE":1}
CloudFree Motion Light {"NAME":"CloudFree SWM1","GPIO":[32,0,0,0,0,160,0,0,224,576,161,0,0,0],"FLAG":0,"BASE":18}
Connect SmartHome 2 Gang Wall {"NAME":"CSH-SWTCH2","GPIO":[0,0,288,0,0,33,0,0,225,224,0,0,32,0],"FLAG":0,"BASE":18}
Connect SmartHome 3 Gang Wall Switch () {"NAME":"CSH-SWTCH3","GPIO":[0,0,288,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18}
Deta 1 Gang {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,544,0,0,0,0,224,0,0,64,0],"FLAG":0,"BASE":18}
Deta 2 Gang {"NAME":"DETA 2G Switch","GPIO":[0,0,0,0,544,0,0,0,65,224,225,0,64,0],"FLAG":0,"BASE":18}
Deta 3 Gang {"NAME":"DETA 3G Switch","GPIO":[544,0,0,66,65,224,0,0,226,0,225,0,64,0],"FLAG":0,"BASE":18}
Deta 4 Gang {"NAME":"Deta 4G Switch","GPIO":[576,0,0,34,33,224,0,0,226,35,225,227,32,0],"FLAG":0,"BASE":18}
DETA Mechanism {"NAME":"Deta 6014HA","GPIO":[0,0,0,0,0,0,0,0,320,0,32,0,224,0],"FLAG":0,"BASE":18}
Dierya Touch Panel 2 Gang {"NAME":"CD301","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Dierya Touch Panel 2 Gang {"NAME":"CD302","GPIO":[544,0,0,33,225,0,0,0,32,224,321,0,320,0],"FLAG":0,"BASE":18}
Dierya Touch Panel 3 Gang {"NAME":"CD303","GPIO":[576,289,0,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18}
@ -2124,6 +2156,7 @@ DS-102 2 Gang {"NAME":"DS-102 2 Gang","GPIO":[576,321,0,32,225,33
DS-102 3 Gang {"NAME":"DS-102 3 Gang","GPIO":[576,322,0,33,225,34,0,0,32,224,321,226,320,0],"FLAG":0,"BASE":18}
DS-121 2 Gang No Neutral {"NAME":"2 Gang Switch","GPIO":[576,321,0,32,225,33,0,0,0,224,320,0,0,0],"FLAG":0,"BASE":18}
DS-121 4 Gang No Neutral {"NAME":"2 Gang Switch","GPIO":[576,321,0,32,225,33,0,0,0,224,320,0,0,0],"FLAG":0,"BASE":18}
Eachen 3CH {"NAME":"Eachen Smart Switch 3CH","GPIO":[34,0,0,0,224,225,33,32,226,320,0,0,0,0],"FLAG":0,"BASE":18}
Eachen CD303 3 Gang {"NAME":"ID Components","GPIO":[544,289,0,162,224,161,0,0,160,225,290,226,288,1],"FLAG":0,"BASE":18}
Eachen SWT-2Gang {"NAME":"ID Components","GPIO":[544,1,1,1,1,161,1,1,160,224,289,225,288,1],"FLAG":0,"BASE":18}
Earda 3-Way {"NAME":"ESW-1WAA-US","GPIO":[160,0,0,0,320,0,0,0,0,224,0,0,0,0],"FLAG":0,"BASE":18}
@ -2160,6 +2193,7 @@ Innens RF433 2 Gang 1 Way {"NAME":"Innens Light Switch 2G","GPIO":[0,0,289,0,
Jinvoo SM-SW101-1 {"NAME":"SM-SW101-1","GPIO":[288,0,0,33,0,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18}
Jinvoo SM-SW101-2 {"NAME":"SM-SW101-2","GPIO":[288,0,0,33,225,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18}
Jinvoo SM-SW101-3 {"NAME":"Jinvoo Wall Sw","GPIO":[288,0,0,33,225,34,0,0,32,224,0,226,0,4704],"FLAG":0,"BASE":18}
Kauf RGB Wall {"NAME":"Kauf SRF10","GPIO":[448,1,450,1,450,449,1,1,449,32,448,224,1,1],"FLAG":0,"BASE":18}
KingArt 1 Gang {"NAME":"KING-L1","GPIO":[0,0,0,0,0,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
KingArt 3 Gang {"NAME":"KING-L3","GPIO":[0,0,0,0,226,225,0,0,224,164,165,0,167,0],"FLAG":0,"BASE":18}
KMC 70008 {"NAME":"KMC 70008","GPIO":[32,1,1,0,0,1,0,0,0,320,224,1,1,0],"FLAG":0,"BASE":18}
@ -2184,6 +2218,7 @@ Lerlink 3 Gang {"NAME":"X803A","GPIO":[0,0,0,33,32,34,0,0,224,288,
Lerlink 3 Gang No Neutral {"NAME":"X803K-L 3 Gang","GPIO":[0,0,320,0,32,34,33,0,224,0,225,226,0,0],"FLAG":0,"BASE":18}
Lightstory WT02S {"NAME":"WT02S","GPIO":[0,0,0,0,321,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":50}
Linkind 2-Way {"NAME":"Linkind WS240010008","GPIO":[0,0,0,0,0,224,0,0,0,0,288,0,0,0,0,0,0,0,0,0,0,576,321,0,0,0,0,0,33,32,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Linkind Dimmer {"NAME":"Linkind Dimmer","GPIO":[6213,8448,0,0,640,0,0,0,0,0,288,0,0,0,0,0,0,608,0,0,0,0,544,0,0,0,0,0,33,32,0,0,0,0,0,0],"FLAG":0,"BASE":1}
LoGiX Multi Button RGB Scene Controller {"NAME":"Logix3","GPIO":[1,1,1,1,34,33,1,1,1376,32,1312,1,1,1],"FLAG":0,"BASE":18}
Lonsonho SK3-01 {"NAME":"Tuya 1 Channel","GPIO":[0,0,0,0,0,32,0,0,0,0,0,224,288,0],"FLAG":0,"BASE":18}
Lonsonho SK3-02 {"NAME":"Tuya 2 Channel","GPIO":[0,0,0,0,225,0,0,0,32,224,33,0,288,0],"FLAG":0,"BASE":18}
@ -2243,6 +2278,7 @@ Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[576,0,0,33,225,0,0,0,
Nexete DS-123 {"NAME":"DS-123","GPIO":[544,321,1,32,224,33,0,0,1,225,320,1,1,0],"FLAG":0,"BASE":18}
Nexete DS-123 Single {"NAME":"DS-123","GPIO":[544,0,1,33,0,32,0,0,1,224,320,1,1,0],"FLAG":0,"BASE":18}
Novadigital Interruptor Touch Led 1 Boto {"NAME":"Nova Digital Switch 1 Gang","GPIO":[544,0,0,32,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18}
Prosto {"NAME":"Prosto WFS-T10","GPIO":[0,0,0,0,0,224,0,0,320,0,64,0,0,0],"FLAG":0,"BASE":18}
Push Button 1/2/3/4 Gang {"NAME":"DS-122","GPIO":[321,0,0,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":18}
Q-touch 1 Gang {"NAME":"Qtouch","GPIO":[289,0,0,32,0,0,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":1}
Qualitel 1 Gang {"NAME":"Qualitel 1 Gang","GPIO":[544,0,0,160,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18}
@ -2265,7 +2301,7 @@ Shawader 3Ch Touch Light {"NAME":"ShawaderTuya3C","GPIO":[0,3872,0,66,64,65,
SK-A801-01-US 1 Gang {"NAME":"jsankou US Switch 1 Gang","GPIO":[544,0,0,0,0,0,0,0,32,256,0,0,0,0],"FLAG":0,"BASE":18}
SK-W803-01-US 3 Gang {"NAME":"jsankou US Switch 3 Gang","GPIO":[544,0,0,33,257,34,0,0,32,256,0,258,0,0],"FLAG":0,"BASE":18}
Smart 3 Gang Touch {"NAME":"ETERSKY KS601 3 Gang","GPIO":[0,0,544,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18}
SmartGrade {"NAME":"SmartGrade AC 5005","GPIO":[0,0,0,32,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
SmartGrade {"NAME":"SmartGrade AC 5005","GPIO":[0,0,0,32,2688,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18}
Smartlife Opard CD302 {"NAME":"CD302","GPIO":[0,0,0,0,288,321,0,0,256,32,0,0,0,0],"FLAG":0,"BASE":18}
SmartPlex 3 Gang {"NAME":"Tuya 3 Channel","GPIO":[1,1,1,1,224,33,0,0,34,226,32,225,1,0],"FLAG":0,"BASE":18}
SmartVU Home Double Touch Light {"NAME":"SHWSW2","GPIO":[544,0,288,0,0,32,0,0,33,225,0,224,289,0],"FLAG":0,"BASE":18}
@ -2414,7 +2450,7 @@ Shelly 1 {"NAME":"Shelly 1","GPIO":[1,1,0,1,224,192,0,0,0,0,
Shelly 1L No Neutral {"NAME":"Shelly 1L","GPIO":[320,0,0,0,192,224,0,0,0,0,193,0,0,4736],"FLAG":0,"BASE":18}
Shelly 1PM {"NAME":"Shelly 1PM","GPIO":[320,0,0,0,192,2720,0,0,0,0,0,224,0,4736],"FLAG":0,"BASE":18}
Shelly 2 {"NAME":"Shelly 2","GPIO":[0,2752,0,2784,224,225,0,0,160,0,161,2816,0,0],"FLAG":0,"BASE":47}
Shelly 2.5 {"NAME":"Shelly 2.5","GPIO":[320,0,32,0,224,193,0,0,640,192,608,225,3456,4736],"FLAG":0,"BASE":18}
Shelly 2.5 {"NAME":"Shelly 2.5","GPIO":[320,0,0,0,224,193,0,0,640,192,608,225,3456,4736],"FLAG":0,"BASE":18}
Shelly EM {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,640,3456,608,224,0,1],"FLAG":0,"BASE":18}
Shelly i3 Action and Scenes Activation Device {"NAME":"Shelly i3","GPIO":[0,0,0,0,0,320,0,0,193,194,192,0,0,4736],"FLAG":0,"BASE":18}
Shelly Plus 1 {"NAME":"Shelly Plus 1 ","GPIO":[0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
@ -2538,6 +2574,7 @@ Y09 {"NAME":"Y09","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0
```
Eachen eWeLink ZbBridge Pro Ethernet {"NAME":"ZB-GW03-V1.2","GPIO":[0,0,3552,0,3584,0,0,0,5793,5792,320,544,5536,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,608,640,32,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff ZBBridge {"NAME":"Sonoff ZbBridge","GPIO":[320,3552,0,3584,5312,0,0,0,640,576,608,0,32,0],"FLAG":0,"BASE":75}
Sonoff ZBBridge Pro {"NAME":"Sonoff Zigbee Pro","GPIO":[0,0,576,0,480,0,0,0,0,1,1,5792,0,0,0,3552,0,320,5793,3584,0,640,608,32,0,0,0,0,0,1,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Tube's CC2652P2 Ethernet {"NAME":"Tube ZB CC2652","GPIO":[0,0,0,3840,0,3584,0,0,0,0,0,0,5536,3552,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,3840,5792,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Tube's EFR32 Ethernet {"NAME":"Tube ZB EFR32","GPIO":[0,0,0,3840,0,3552,1,0,0,0,0,0,5536,3584,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,5793,5792,0,0,0,0,0,0],"FLAG":0,"BASE":1}
```

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "esp32_partition_app1856k_spiffs320k.csv"
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@ -25,8 +25,16 @@
"arduino",
"espidf"
],
"name": "AI Thinker ESP32-CAM, 4M Flash 4MB PSRAM, Tasmota 1856k Code/OTA, 320k FS",
"name": "AI Thinker ESP32-CAM, 4M Flash 4MB PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32",
"variant": "m5stack_core2",
"partitions": "esp32_partition_app2944k_spiffs10M.csv"
"partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
},
"connectivity": [
"wifi",

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32",
"variant": "odroid_esp32",
"partitions": "esp32_partition_app2944k_spiffs10M.csv"
"partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
},
"connectivity": [
"wifi",

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "esp32_partition_app2944k_spiffs10M.csv"
"partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
},
"connectivity": [
"wifi",

View File

@ -1,38 +1,46 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld"
"build": {
"arduino":{
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"core": "esp32",
"extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "esp32_partition_app1856k_spiffs320k.csv"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_target": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_target": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}

46
boards/esp32_4M_FS.json Normal file
View File

@ -0,0 +1,46 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "partitions/esp32_partition_app1856k_fs1344k.csv"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_target": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "esp32_partition_app2944k_spiffs2M.csv"
"partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
},
"connectivity": [
"wifi",

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32",
"variant": "esp32",
"partitions": "esp32_partition_app1856k_spiffs320k.csv"
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@ -25,8 +25,16 @@
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
"name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32solo1-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,

View File

@ -1,35 +1,43 @@
{
"build": {
"arduino":{
"ldscript": "esp32c3_out.ld"
"build": {
"arduino":{
"ldscript": "esp32c3_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3",
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32c3",
"variant": "esp32c3",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"core": "esp32",
"extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3",
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32c3",
"variant": "esp32c3",
"partitions": "esp32_partition_app1856k_spiffs320k.csv"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32c3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
"vendor": "Espressif"
}
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32c3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32c3-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
"vendor": "Espressif"
}

43
boards/esp32c3cdc.json Normal file
View File

@ -0,0 +1,43 @@
{
"build": {
"arduino":{
"ldscript": "esp32c3_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3 -DUSE_USB_CDC_CONSOLE",
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32c3",
"variant": "esp32c3",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32c3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32c3cdc-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
"vendor": "Espressif"
}

View File

@ -10,7 +10,7 @@
"flash_mode": "dout",
"mcu": "esp32s2",
"variant": "esp32s2",
"partitions": "esp32_partition_app1856k_spiffs320k.csv"
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi"
@ -22,8 +22,16 @@
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
"name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s2-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,

43
boards/esp32s2cdc.json Normal file
View File

@ -0,0 +1,43 @@
{
"build": {
"arduino":{
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_4M -DESP32S2",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32s2",
"variant": "esp32s2",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s2.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s2cdc-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
"vendor": "Espressif"
}

View File

@ -11,7 +11,7 @@
"flash_mode": "dio",
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "esp32_partition_app1856k_spiffs320k.csv"
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@ -25,8 +25,16 @@
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
"name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s3-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,

View File

@ -11,7 +11,7 @@
"flash_mode": "dio",
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "esp32_partition_app2944k_spiffs2M.csv"
"partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
},
"connectivity": [
"wifi",

46
boards/esp32s3cdc.json Normal file
View File

@ -0,0 +1,46 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s3cdc-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
"vendor": "Espressif"
}

View File

@ -21,6 +21,6 @@
#define __TASMOTA_INCLUDE__
#include "../tasmota/my_user_config.h"
#include "../tasmota/tasmota_configurations.h"
#include "../tasmota/include/tasmota_configurations.h"
#endif // __TASMOTA_INCLUDE__

View File

@ -48,7 +48,7 @@ public:
inline uint8_t *buf(size_t i = 0) const { return &_buf->buf[i]; }
inline char *charptr(size_t i = 0) const { return (char*) &_buf->buf[i]; }
virtual ~SBuffer(void) {
~SBuffer(void) {
delete[] _buf;
}
@ -258,6 +258,12 @@ public:
return buf2;
}
static SBuffer SBufferFromBytes(const uint8_t *bytes, size_t len2) {
SBuffer buf2(len2);
buf2.addBuffer(bytes, len2);
return buf2;
}
// nullptr accepted
static bool equalsSBuffer(const class SBuffer * buf1, const class SBuffer * buf2) {
if (buf1 == buf2) { return true; }
@ -290,18 +296,3 @@ protected:
SBuffer_impl * _buf;
} SBuffer;
typedef class PreAllocatedSBuffer : public SBuffer {
public:
PreAllocatedSBuffer(const size_t size, void * buffer) {
_buf = (SBuffer_impl*) buffer;
_buf->size = size - 4;
_buf->len = 0;
}
~PreAllocatedSBuffer(void) {
// don't deallocate
_buf = nullptr;
}
} PreAllocatedSBuffer;

View File

@ -153,6 +153,9 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
#ifdef ESP32
if (TSerial == nullptr) { // Allow for dynamic change in baudrate or config
if (freeUart()) { // We prefer UART1 and UART2 and keep UART0 for debugging
#ifdef ARDUINO_USB_CDC_ON_BOOT
TSerial = new HardwareSerial(m_uart);
#else
if (0 == m_uart) {
Serial.flush();
Serial.end();
@ -161,6 +164,7 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
} else {
TSerial = new HardwareSerial(m_uart);
}
#endif // ARDUINO_USB_CDC_ON_BOOT
if (serial_buffer_size > 256) { // RX Buffer can't be resized when Serial is already running (HardwareSerial.cpp)
TSerial->setRxBufferSize(serial_buffer_size);
}

View File

@ -252,7 +252,6 @@ int32_t Unishox::unishox_compress(const char *p_in, size_t p_len, char *p_out, s
out = p_out;
len_out = p_len_out;
char *ptr;
byte bits;
int ll;

View File

@ -391,7 +391,7 @@ static uint32_t json_encode_utf8(char* str, uint32_t val) {
void json_unescape(char* string) {
size_t outlength = 0;
uint32_t hexval, numbytes;
uint32_t numbytes;
char c;
for (uint32_t i = 0; (c = string[i]) != 0; i++) {

View File

@ -27,6 +27,10 @@
#include <Arduino.h>
#ifndef SPECIAL
#define SPECIAL 0xF0
#endif
#ifndef ESP32
class ESP8266SPIRAM {
@ -364,4 +368,4 @@ class ESP8266SPIRAM {
#endif // ESP32
#endif
#endif

View File

@ -13,6 +13,13 @@ remove in file `lib/lib_audio/ESP8266Audio/src/AudioFileSourceFS.cpp`
#endif
```
add in file `lib/lib_audio/ESP8266Audio/src/spiram-fast.h`
```
#ifndef SPECIAL
#define SPECIAL 0xF0
#endif
```
Files to delete:
```
lib/lib_audio/ESP8266Audio/src/AudioFileSourceSPIFFS.h

View File

@ -210,28 +210,12 @@ void directModeInput(IO_REG_TYPE pin)
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
//#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
// int8_t rtc_io = esp32_gpioMux[pin].rtc;
// uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
// if ( rtc_reg ) // RTC pins PULL settings
// {
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
// }
#endif
// Input
if ( pin < 32 )
GPIO.enable_w1tc = ((uint32_t)1 << pin);
else
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
// uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
// pinFunction |= FUN_IE; // input enable but required for output as well?
// pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
// ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
// GPIO.pin[pin].val = 0;
}
#endif
}
@ -252,28 +236,12 @@ void directModeOutput(IO_REG_TYPE pin)
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
}
//#elif ESP_IDF_VERSION_MAJOR > 3 // ESP32-S2 needs IDF 4.2 or later
// int8_t rtc_io = esp32_gpioMux[pin].rtc;
// uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
// if ( rtc_reg ) // RTC pins PULL settings
// {
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
// ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
// }
#endif
// Output
if ( pin < 32 )
GPIO.enable_w1ts = ((uint32_t)1 << pin);
else // already validated to pins <= 33
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
// uint32_t pinFunction((uint32_t)2 << FUN_DRV_S); // what are the drivers?
// pinFunction |= FUN_IE; // input enable but required for output as well?
// pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
// ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
// GPIO.pin[pin].val = 0;
}
#endif
}

View File

@ -1,11 +1,6 @@
# OneWire library
A modification of the Arduino OneWire library maintained by @PaulStoffregen. This modifications supports the ESP32 under the Arduino-esp32 Environment.
No changes are required for compatibility with Arduino coding.
A @stickbreaker @arendst modified version of the Arduino OneWire library maintained by @PaulStoffregen.
This modifications supports the ESP8266, ESP32, ESP32c3, ESP32s2 and ESP32s3 under the Arduino-esp32 Environment.
Original Source is Paul's 2.3 version. Forked 28DEC2017
@stickbreaker
V2.3.1 30APR2018 add IRAM_ATTR to read_bit() write_bit() to solve ICache miss timing failure.
thanks @everslick re: https://github.com/espressif/arduino-esp32/issues/1335
V2.3 28DEC2017 original mods to support ESP32
Original Source is Paul's 2.3 version.

View File

@ -34,7 +34,7 @@ typedef struct LVGL_PARAMS {
struct {
uint8_t use_dma : 1;
uint8_t swap_color : 1;
uint8_t resvd_0 : 1;
uint8_t async_dma : 1; // force DMA completion before returning, avoid conflict with other devices on same bus. If set you should make sure the display is the only device on the bus
uint8_t resvd_1 : 1;
uint8_t resvd_2 : 1;
uint8_t resvd_3 : 1;

View File

@ -465,7 +465,7 @@ Renderer *uDisplay::Init(void) {
uspi->begin(spi_clk, spi_miso, spi_mosi, -1);
if (lvgl_param.use_dma) {
spi_host = VSPI_HOST;
initDMA(spi_cs);
initDMA(lvgl_param.async_dma ? spi_cs : -1); // disable DMA CS if sync, we control it directly
}
} else if (spi_nr == 2) {
@ -473,7 +473,7 @@ Renderer *uDisplay::Init(void) {
uspi->begin(spi_clk, spi_miso, spi_mosi, -1);
if (lvgl_param.use_dma) {
spi_host = HSPI_HOST;
initDMA(spi_cs);
initDMA(lvgl_param.async_dma ? spi_cs : -1); // disable DMA CS if sync, we control it directly
}
} else {
pinMode(spi_clk, OUTPUT);
@ -1282,7 +1282,7 @@ void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) {
void uDisplay::setRotation(uint8_t rotation) {
cur_rot = rotation;
if (interface != _UDSP_SPI) {
if (interface != _UDSP_SPI || bpp < 16) {
Renderer::setRotation(cur_rot);
return;
}
@ -1974,24 +1974,13 @@ void uDisplay::beginTransaction(SPISettings s) {
#ifdef ESP32
if (lvgl_param.use_dma) {
dmaWait();
} else {
uspi->beginTransaction(s);
}
#else
uspi->beginTransaction(s);
#endif
uspi->beginTransaction(s);
}
void uDisplay::endTransaction(void) {
#ifdef ESP32
if (lvgl_param.use_dma) {
dmaBusy();
} else {
uspi->endTransaction();
}
#else
uspi->endTransaction();
#endif
}
@ -2002,7 +1991,7 @@ void uDisplay::endTransaction(void) {
** Function name: initDMA
** Description: Initialise the DMA engine - returns true if init OK
***************************************************************************************/
bool uDisplay::initDMA(bool ctrl_cs)
bool uDisplay::initDMA(int32_t ctrl_cs)
{
if (DMA_Enabled) return false;
@ -2018,9 +2007,6 @@ bool uDisplay::initDMA(bool ctrl_cs)
.intr_flags = 0
};
int8_t pin = -1;
if (ctrl_cs) pin = spi_cs;
spi_device_interface_config_t devcfg = {
.command_bits = 0,
.address_bits = 0,
@ -2031,7 +2017,7 @@ bool uDisplay::initDMA(bool ctrl_cs)
.cs_ena_posttrans = 0,
.clock_speed_hz = spi_speed*1000000,
.input_delay_ns = 0,
.spics_io_num = pin,
.spics_io_num = ctrl_cs,
.flags = SPI_DEVICE_NO_DUMMY, //0,
.queue_size = 1,
.pre_cb = 0, //dc_callback, //Callback to handle D/C line
@ -2119,6 +2105,9 @@ void uDisplay::pushPixelsDMA(uint16_t* image, uint32_t len) {
assert(ret == ESP_OK);
spiBusyCheck++;
if (!lvgl_param.async_dma) {
dmaWait();
}
}
/***************************************************************************************
@ -2145,6 +2134,9 @@ void uDisplay::pushPixels3DMA(uint8_t* image, uint32_t len) {
assert(ret == ESP_OK);
spiBusyCheck++;
if (!lvgl_param.async_dma) {
dmaWait();
}
}

View File

@ -233,7 +233,7 @@ class uDisplay : public Renderer {
spi_device_handle_t dmaHAL;
spi_host_device_t spi_host = VSPI_HOST;
// spi_host_device_t spi_host = VSPI_HOST;
bool initDMA(bool ctrl_cs);
bool initDMA(int32_t ctrl_cs);
void deInitDMA(void);
bool dmaBusy(void);
void dmaWait(void);

View File

@ -317,7 +317,7 @@ int FrogmoreScd40::readRegister(uint16_t registerAddress, uint16_t* pData)
void FrogmoreScd40::begin(TwoWire *pWire, uint8_t i2cAddress)
{
this->duringMeasurement = 0;
this->duringMeasurement = false;
this->i2cAddress = i2cAddress;
this->co2EAverage = 0;
if (pWire == NULL)
@ -373,10 +373,10 @@ int FrogmoreScd40::startPeriodicMeasurement(void)
snprintf_P(scd40log_data, sizeof(scd40log_data), "Start periodic measurement");
AddLog(LOG_LEVEL_DEBUG_MORE);
#endif
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
DuringMeasurement = 1;
duringMeasurement = true;
return(sendCommand(COMMAND_SCD40_START_PERIODIC_MEASUREMENT));
}
@ -387,7 +387,7 @@ int FrogmoreScd40::readMeasurement(
float *pHumidity
)
{
// Should only be called in DuringMeasurement mode or
// Should only be called in duringMeasurement mode or
// after calling measure_single_hot{,_rht_only}
// but this is currently not verified
bool isAvailable = false;
@ -522,16 +522,16 @@ int FrogmoreScd40::readMeasurement(
int FrogmoreScd40::forceStopPeriodicMeasurement(void)
{
DuringMeasurement = 0;
duringMeasurement = false;
return (sendCommand(COMMAND_SCD40_STOP_PERIODIC_MEASUREMENT));
}
int FrogmoreScd40::stopPeriodicMeasurement(void)
{
if (!DuringMeasurement) {
if (!duringMeasurement) {
return (ERROR_SCD40_NOT_IN_MEASUREMENT_MODE);
}
DuringMeasurement = 0;
duringMeasurement = false;
return (sendCommand(COMMAND_SCD40_STOP_PERIODIC_MEASUREMENT));
}
@ -541,7 +541,7 @@ int FrogmoreScd40::setTemperatureOffset(float offset_degC)
// influences RH and T readings. Does not influence CO2 measurement. Default is 4 degrees Celcius.
// to save setting to the EEPROM, call persistSetting()
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
if (offset_degC >= 0)
@ -557,7 +557,7 @@ int FrogmoreScd40::setTemperatureOffset(float offset_degC)
int FrogmoreScd40::setTemperatureOffset(uint16_t offset_centiDegC)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
uint16_t offset_xDegC = (uint16_t) (offset_centiDegC * 3.74491);
@ -566,7 +566,7 @@ int FrogmoreScd40::setTemperatureOffset(uint16_t offset_centiDegC)
int FrogmoreScd40::getTemperatureOffset(float *pOffset_degC)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
uint16_t value;
@ -581,7 +581,7 @@ int FrogmoreScd40::getTemperatureOffset(float *pOffset_degC)
int FrogmoreScd40::getTemperatureOffset(uint16_t *pOffset_centiDegC)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
uint16_t value;
@ -598,7 +598,7 @@ int FrogmoreScd40::setSensorAltitude(uint16_t height_meter)
// Default is 0 meter above sea-level;
// to save setting to the EEPROM, call persistSetting()
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (sendCommandArguments(COMMAND_SCD40_SET_SENSOR_ALTITUDE, height_meter));
@ -606,7 +606,7 @@ int FrogmoreScd40::setSensorAltitude(uint16_t height_meter)
int FrogmoreScd40::getSensorAltitude(uint16_t *pHeight_meter)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (readRegister(COMMAND_SCD40_GET_SENSOR_ALTITUDE, pHeight_meter));
@ -615,7 +615,7 @@ int FrogmoreScd40::getSensorAltitude(uint16_t *pHeight_meter)
int FrogmoreScd40::setAmbientPressure(uint16_t airPressure_mbar)
// Overrides any pressure compensation based on a previously set sensor altitude
{
// allowed DuringMeasurement
// allowed duringMeasurement
return (sendCommandArguments(COMMAND_SCD40_SET_AMBIENT_PRESSURE, airPressure_mbar));
}
@ -627,7 +627,7 @@ int FrogmoreScd40::performForcedRecalibration(uint16_t co2_ppm)
// issue stop_periodic_measurement, and then wait 500ms, before calling this function
// it takes 400ms for this command to complete
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
uint16_t FRC_result;
@ -642,7 +642,7 @@ int FrogmoreScd40::performForcedRecalibration(uint16_t co2_ppm)
int FrogmoreScd40::setAutomaticSelfCalibrationDisabled(void)
// to save setting to the EEPROM, call persistSetting()
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
bool isAuto = false;
@ -652,7 +652,7 @@ int FrogmoreScd40::setAutomaticSelfCalibrationDisabled(void)
int FrogmoreScd40::setAutomaticSelfCalibrationEnabled(void)
// to save setting to the EEPROM, call persistSetting()
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
bool isAuto = true;
@ -662,7 +662,7 @@ int FrogmoreScd40::setAutomaticSelfCalibrationEnabled(void)
int FrogmoreScd40::setAutomaticSelfCalibrationEnabled(bool isAuto)
// to save setting to the EEPROM, call persistSetting()
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
bool value = !!isAuto; // using NOT operator twice makes sure value is 0 or 1
@ -671,7 +671,7 @@ int FrogmoreScd40::setAutomaticSelfCalibrationEnabled(bool isAuto)
int FrogmoreScd40::getAutomaticSelfCalibrationEnabled(uint16_t *pIsAuto)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
uint16_t value = 0;
@ -688,16 +688,16 @@ int FrogmoreScd40::getAutomaticSelfCalibrationEnabled(uint16_t *pIsAuto)
int FrogmoreScd40::startLowPowerPeriodicMeasurement(void)
// Comment: unclear how to stop this operation mode?
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
duringMeasurement = true;
return (sendCommand(COMMAND_SCD40_START_LOW_POWER_PERIODIC_MEASUREMENT));
DuringMeasurement = 1;
}
int FrogmoreScd40::getDataReadyStatus(bool *pIsAvailable)
{
// allowed DuringMeasurement
// allowed duringMeasurement
uint16_t isDataAvailable = false;
int error = readRegister(COMMAND_SCD40_GET_DATA_READY_STATUS, &isDataAvailable);
if (!error)
@ -715,7 +715,7 @@ int FrogmoreScd40::persistSettings(void)
// EEPROM is guaranteed to endure at least 2000 write cycles before failure.
// The field calibration history (FRC and ASC) is stored in a separate EEPROM.
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (sendCommand(COMMAND_SCD40_PERSIST_SETTINGS));
@ -724,7 +724,7 @@ int FrogmoreScd40::persistSettings(void)
int FrogmoreScd40::getSerialNumber(uint16_t *pSerialNumberArray)
// Serialnr is 48 bits = 3 16-bit words
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
uint16_t value;
@ -734,7 +734,7 @@ int FrogmoreScd40::getSerialNumber(uint16_t *pSerialNumberArray)
int FrogmoreScd40::performSelfTest(uint16_t *pMalfunction)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (readRegister(COMMAND_SCD40_PERFORM_SELF_TEST, pMalfunction));
@ -744,7 +744,7 @@ int FrogmoreScd40::performFactoryReset(void)
// resets all configuration settings in EEPROM and
// erases FRC and ASC algorithm history
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (sendCommand(COMMAND_SCD40_PERFORM_FACTORY_RESET));
@ -753,7 +753,7 @@ int FrogmoreScd40::performFactoryReset(void)
int FrogmoreScd40::reinit(void)
// reinitailizes sensor from EEPROM user settings
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (sendCommand(COMMAND_SCD40_REINIT));
@ -764,7 +764,7 @@ int FrogmoreScd40::reinit(void)
int FrogmoreScd40::measureSingleShot(void)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (sendCommand(COMMAND_SCD40_MEASURE_SINGLE_SHOT));
@ -772,7 +772,7 @@ int FrogmoreScd40::measureSingleShot(void)
int FrogmoreScd40::measureSingleShotRhtOnly(void)
{
if (DuringMeasurement) {
if (duringMeasurement) {
return (ERROR_SCD40_BUSY_MEASURING);
}
return (sendCommand(COMMAND_SCD40_MEASURE_SINGLE_SHOT_RHT_ONLY));

View File

@ -93,14 +93,12 @@ class FrogmoreScd40
int measureSingleShotRhtOnly(void);
private:
uint8_t duringMeasurement;
bool duringMeasurement;
uint8_t i2cAddress;
TwoWire *pWire;
uint16_t co2AvgExtra;
uint16_t co2History[SCD40_MEDIAN_FILTER_SIZE];
uint16_t co2EAverage;
int8_t co2NewDataLocation; // location to put new CO2 data for median filter
bool DuringMeasurement;
uint8_t computeCRC8(uint8_t data[], uint8_t len);
uint16_t medianfilter(uint16_t * p);

View File

@ -117,7 +117,7 @@ String HTTPUpdateLight::getLastErrorString(void)
// error from Update class
if(_lastError > 0) {
StreamString error;
Update.printError(error);
TasUpdate.printError(error);
error.trim(); // remove line ending
return String("Update error: ") + error;
}
@ -418,14 +418,17 @@ bool HTTPUpdateLight::runUpdate(Stream& in, uint32_t size, String md5, int comma
StreamString error;
if (_cbProgress) {
Update.onProgress(_cbProgress);
TasUpdate.onProgress(_cbProgress);
}
if(!Update.begin(size, command, _ledPin, _ledOn)) {
_lastError = Update.getError();
Update.printError(error);
// Start Tasmota Factory patch
// if(!Update.begin(size, command, _ledPin, _ledOn)) {
if(!TasUpdate.begin(size, command, _ledPin, _ledOn, NULL, _factory)) {
// End Tasmota Factory patch
_lastError = TasUpdate.getError();
TasUpdate.printError(error);
error.trim(); // remove line ending
log_e("Update.begin failed! (%s)\n", error.c_str());
log_e("TasUpdate.begin failed! (%s)\n", error.c_str());
return false;
}
@ -434,20 +437,20 @@ bool HTTPUpdateLight::runUpdate(Stream& in, uint32_t size, String md5, int comma
}
if(md5.length()) {
if(!Update.setMD5(md5.c_str())) {
if(!TasUpdate.setMD5(md5.c_str())) {
_lastError = HTTP_UE_SERVER_FAULTY_MD5;
log_e("Update.setMD5 failed! (%s)\n", md5.c_str());
log_e("TasUpdate.setMD5 failed! (%s)\n", md5.c_str());
return false;
}
}
// To do: the SHA256 could be checked if the server sends it
if(Update.writeStream(in) != size) {
_lastError = Update.getError();
Update.printError(error);
if(TasUpdate.writeStream(in) != size) {
_lastError = TasUpdate.getError();
TasUpdate.printError(error);
error.trim(); // remove line ending
log_e("Update.writeStream failed! (%s)\n", error.c_str());
log_e("TasUpdate.writeStream failed! (%s)\n", error.c_str());
return false;
}
@ -455,11 +458,11 @@ bool HTTPUpdateLight::runUpdate(Stream& in, uint32_t size, String md5, int comma
_cbProgress(size, size);
}
if(!Update.end()) {
_lastError = Update.getError();
Update.printError(error);
if(!TasUpdate.end()) {
_lastError = TasUpdate.getError();
TasUpdate.printError(error);
error.trim(); // remove line ending
log_e("Update.end failed! (%s)\n", error.c_str());
log_e("TasUpdate.end failed! (%s)\n", error.c_str());
return false;
}

View File

@ -31,7 +31,7 @@
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include <HttpClientLight.h>
#include <Update.h>
#include <TasUpdate.h>
#include <HTTPUpdate.h>
/// note we use HTTP client errors too so we start at 100
@ -69,7 +69,7 @@ public:
{
_rebootOnUpdate = reboot;
}
/**
* set redirect follow mode. See `followRedirects_t` enum for avaliable modes.
* @param follow
@ -85,6 +85,13 @@ public:
_ledOn = ledOn;
}
// Start Tasmota Factory patch
void setFactory(bool factory = false)
{
_factory = factory;
}
// End Tasmota Factory patch
// t_httpUpdate_return update(WiFiClient& client, const String& url, const String& currentVersion = "");
// t_httpUpdate_return update(WiFiClient& client, const String& host, uint16_t port, const String& uri = "/",
@ -131,6 +138,9 @@ private:
int _ledPin;
uint8_t _ledOn;
// Start Tasmota Factory patch
bool _factory;
// End Tasmota Factory patch
};
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE)

View File

@ -0,0 +1,194 @@
#ifndef TASUPDATER_H
#define TASUPDATER_H
#include <Arduino.h>
#include <MD5Builder.h>
#include <functional>
#include "esp_partition.h"
#define UPDATE_ERROR_OK (0)
#define UPDATE_ERROR_WRITE (1)
#define UPDATE_ERROR_ERASE (2)
#define UPDATE_ERROR_READ (3)
#define UPDATE_ERROR_SPACE (4)
#define UPDATE_ERROR_SIZE (5)
#define UPDATE_ERROR_STREAM (6)
#define UPDATE_ERROR_MD5 (7)
#define UPDATE_ERROR_MAGIC_BYTE (8)
#define UPDATE_ERROR_ACTIVATE (9)
#define UPDATE_ERROR_NO_PARTITION (10)
#define UPDATE_ERROR_BAD_ARGUMENT (11)
#define UPDATE_ERROR_ABORT (12)
#define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF
#define U_FLASH 0
#define U_SPIFFS 100
#define U_AUTH 200
#define ENCRYPTED_BLOCK_SIZE 16
class TasUpdateClass {
public:
typedef std::function<void(size_t, size_t)> THandlerFunction_Progress;
TasUpdateClass();
/*
This callback will be called when Update is receiving data
*/
TasUpdateClass& onProgress(THandlerFunction_Progress fn);
/*
Call this to check the space needed for the update
Will return false if there is not enough space
*/
// Start Tasmota Factory patch
// bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL);
bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL, bool factory = false);
// End Tasmota Factory patch
/*
Writes a buffer to the flash and increments the address
Returns the amount written
*/
size_t write(uint8_t *data, size_t len);
/*
Writes the remaining bytes from the Stream to the flash
Uses readBytes() and sets UPDATE_ERROR_STREAM on timeout
Returns the bytes written
Should be equal to the remaining bytes when called
Usable for slow streams like Serial
*/
size_t writeStream(Stream &data);
/*
If all bytes are written
this call will write the config to eboot
and return true
If there is already an update running but is not finished and !evenIfRemaining
or there is an error
this will clear everything and return false
the last error is available through getError()
evenIfRemaining is helpfull when you update without knowing the final size first
*/
bool end(bool evenIfRemaining = false);
/*
Aborts the running update
*/
void abort();
/*
Prints the last error to an output stream
*/
void printError(Print &out);
const char * errorString();
/*
sets the expected MD5 for the firmware (hexString)
*/
bool setMD5(const char * expected_md5);
/*
returns the MD5 String of the successfully ended firmware
*/
String md5String(void){ return _md5.toString(); }
/*
populated the result with the md5 bytes of the successfully ended firmware
*/
void md5(uint8_t * result){ return _md5.getBytes(result); }
//Helpers
uint8_t getError(){ return _error; }
void clearError(){ _error = UPDATE_ERROR_OK; }
bool hasError(){ return _error != UPDATE_ERROR_OK; }
bool isRunning(){ return _size > 0; }
bool isFinished(){ return _progress == _size; }
size_t size(){ return _size; }
size_t progress(){ return _progress; }
size_t remaining(){ return _size - _progress; }
/*
Template to write from objects that expose
available() and read(uint8_t*, size_t) methods
faster than the writeStream method
writes only what is available
*/
template<typename T>
size_t write(T &data){
size_t written = 0;
if (hasError() || !isRunning())
return 0;
size_t available = data.available();
while(available) {
if(_bufferLen + available > remaining()){
available = remaining() - _bufferLen;
}
if(_bufferLen + available > 4096) {
size_t toBuff = 4096 - _bufferLen;
data.read(_buffer + _bufferLen, toBuff);
_bufferLen += toBuff;
if(!_writeBuffer())
return written;
written += toBuff;
} else {
data.read(_buffer + _bufferLen, available);
_bufferLen += available;
written += available;
if(_bufferLen == remaining()) {
if(!_writeBuffer()) {
return written;
}
}
}
if(remaining() == 0)
return written;
available = data.available();
}
return written;
}
/*
check if there is a firmware on the other OTA partition that you can bootinto
*/
bool canRollBack();
/*
set the other OTA partition as bootable (reboot to enable)
*/
bool rollBack();
private:
void _reset();
void _abort(uint8_t err);
bool _writeBuffer();
bool _verifyHeader(uint8_t data);
bool _verifyEnd();
bool _enablePartition(const esp_partition_t* partition);
uint8_t _error;
uint8_t *_buffer;
uint8_t *_skipBuffer;
size_t _bufferLen;
size_t _size;
THandlerFunction_Progress _progress_callback;
uint32_t _progress;
uint32_t _paroffset;
uint32_t _command;
const esp_partition_t* _partition;
String _target_md5;
MD5Builder _md5;
int _ledPin;
uint8_t _ledOn;
};
extern TasUpdateClass TasUpdate;
#endif // TASUPDATER_H

View File

@ -0,0 +1,404 @@
#include "TasUpdate.h"
#include "Arduino.h"
#include "esp_spi_flash.h"
#include "esp_ota_ops.h"
#include "esp_image_format.h"
static const char * _err2str(uint8_t _error){
if(_error == UPDATE_ERROR_OK){
return ("No Error");
} else if(_error == UPDATE_ERROR_WRITE){
return ("Flash Write Failed");
} else if(_error == UPDATE_ERROR_ERASE){
return ("Flash Erase Failed");
} else if(_error == UPDATE_ERROR_READ){
return ("Flash Read Failed");
} else if(_error == UPDATE_ERROR_SPACE){
return ("Not Enough Space");
} else if(_error == UPDATE_ERROR_SIZE){
return ("Bad Size Given");
} else if(_error == UPDATE_ERROR_STREAM){
return ("Stream Read Timeout");
} else if(_error == UPDATE_ERROR_MD5){
return ("MD5 Check Failed");
} else if(_error == UPDATE_ERROR_MAGIC_BYTE){
return ("Wrong Magic Byte");
} else if(_error == UPDATE_ERROR_ACTIVATE){
return ("Could Not Activate The Firmware");
} else if(_error == UPDATE_ERROR_NO_PARTITION){
return ("Partition Could Not be Found");
} else if(_error == UPDATE_ERROR_BAD_ARGUMENT){
return ("Bad Argument");
} else if(_error == UPDATE_ERROR_ABORT){
return ("Aborted");
}
return ("UNKNOWN");
}
static bool _partitionIsBootable(const esp_partition_t* partition){
uint8_t buf[ENCRYPTED_BLOCK_SIZE];
if(!partition){
return false;
}
if(!ESP.partitionRead(partition, 0, (uint32_t*)buf, ENCRYPTED_BLOCK_SIZE)) {
return false;
}
if(buf[0] != ESP_IMAGE_HEADER_MAGIC) {
return false;
}
return true;
}
bool TasUpdateClass::_enablePartition(const esp_partition_t* partition){
if(!partition){
return false;
}
return ESP.partitionWrite(partition, 0, (uint32_t*) _skipBuffer, ENCRYPTED_BLOCK_SIZE);
}
TasUpdateClass::TasUpdateClass()
: _error(0)
, _buffer(0)
, _bufferLen(0)
, _size(0)
, _progress_callback(NULL)
, _progress(0)
, _paroffset(0)
, _command(U_FLASH)
, _partition(NULL)
{
}
TasUpdateClass& TasUpdateClass::onProgress(THandlerFunction_Progress fn) {
_progress_callback = fn;
return *this;
}
void TasUpdateClass::_reset() {
if (_buffer)
delete[] _buffer;
_buffer = 0;
_bufferLen = 0;
_progress = 0;
_size = 0;
_command = U_FLASH;
if(_ledPin != -1) {
digitalWrite(_ledPin, !_ledOn); // off
}
}
bool TasUpdateClass::canRollBack(){
if(_buffer){ //Update is running
return false;
}
const esp_partition_t* partition = esp_ota_get_next_update_partition(NULL);
return _partitionIsBootable(partition);
}
bool TasUpdateClass::rollBack(){
if(_buffer){ //Update is running
return false;
}
const esp_partition_t* partition = esp_ota_get_next_update_partition(NULL);
return _partitionIsBootable(partition) && !esp_ota_set_boot_partition(partition);
}
// Start Tasmota Factory patch
//bool UpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, const char *label) {
bool TasUpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, const char *label, bool factory) {
// End Tasmota Factory patch
if(_size > 0){
log_w("already running");
return false;
}
_ledPin = ledPin;
_ledOn = !!ledOn; // 0(LOW) or 1(HIGH)
_reset();
_error = 0;
_target_md5 = emptyString;
_md5 = MD5Builder();
if(size == 0) {
_error = UPDATE_ERROR_SIZE;
return false;
}
if (command == U_FLASH) {
// Start Tasmota Factory patch
// _partition = esp_ota_get_next_update_partition(NULL);
if (factory) {
_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
} else {
_partition = esp_ota_get_next_update_partition(NULL);
}
// End Tasmota Factory patch
if(!_partition){
_error = UPDATE_ERROR_NO_PARTITION;
return false;
}
log_d("OTA Partition: %s", _partition->label);
}
else if (command == U_SPIFFS) {
_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, label);
_paroffset = 0;
if(!_partition){
_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL);
_paroffset = 0x1000; //Offset for ffat, assuming size is already corrected
if(!_partition){
_error = UPDATE_ERROR_NO_PARTITION;
return false;
}
}
}
else {
_error = UPDATE_ERROR_BAD_ARGUMENT;
log_e("bad command %u", command);
return false;
}
if(size == UPDATE_SIZE_UNKNOWN){
size = _partition->size;
} else if(size > _partition->size){
_error = UPDATE_ERROR_SIZE;
log_e("too large %u > %u", size, _partition->size);
return false;
}
//initialize
_buffer = (uint8_t*)malloc(SPI_FLASH_SEC_SIZE);
if(!_buffer){
log_e("malloc failed");
return false;
}
_size = size;
_command = command;
_md5.begin();
return true;
}
void TasUpdateClass::_abort(uint8_t err){
_reset();
_error = err;
}
void TasUpdateClass::abort(){
_abort(UPDATE_ERROR_ABORT);
}
bool TasUpdateClass::_writeBuffer(){
//first bytes of new firmware
uint8_t skip = 0;
if(!_progress && _command == U_FLASH){
//check magic
if(_buffer[0] != ESP_IMAGE_HEADER_MAGIC){
_abort(UPDATE_ERROR_MAGIC_BYTE);
return false;
}
//Stash the first 16 bytes of data and set the offset so they are
//not written at this point so that partially written firmware
//will not be bootable
skip = ENCRYPTED_BLOCK_SIZE;
_skipBuffer = (uint8_t*)malloc(skip);
if(!_skipBuffer){
log_e("malloc failed");
return false;
}
memcpy(_skipBuffer, _buffer, skip);
}
if (!_progress && _progress_callback) {
_progress_callback(0, _size);
}
if(!ESP.partitionEraseRange(_partition, _progress, SPI_FLASH_SEC_SIZE)){
_abort(UPDATE_ERROR_ERASE);
return false;
}
if (!ESP.partitionWrite(_partition, _progress + skip, (uint32_t*)_buffer + skip/sizeof(uint32_t), _bufferLen - skip)) {
_abort(UPDATE_ERROR_WRITE);
return false;
}
//restore magic or md5 will fail
if(!_progress && _command == U_FLASH){
_buffer[0] = ESP_IMAGE_HEADER_MAGIC;
}
_md5.add(_buffer, _bufferLen);
_progress += _bufferLen;
_bufferLen = 0;
if (_progress_callback) {
_progress_callback(_progress, _size);
}
return true;
}
bool TasUpdateClass::_verifyHeader(uint8_t data) {
if(_command == U_FLASH) {
if(data != ESP_IMAGE_HEADER_MAGIC) {
_abort(UPDATE_ERROR_MAGIC_BYTE);
return false;
}
return true;
} else if(_command == U_SPIFFS) {
return true;
}
return false;
}
bool TasUpdateClass::_verifyEnd() {
if(_command == U_FLASH) {
if(!_enablePartition(_partition) || !_partitionIsBootable(_partition)) {
_abort(UPDATE_ERROR_READ);
return false;
}
if(esp_ota_set_boot_partition(_partition)){
_abort(UPDATE_ERROR_ACTIVATE);
return false;
}
_reset();
return true;
} else if(_command == U_SPIFFS) {
_reset();
return true;
}
return false;
}
bool TasUpdateClass::setMD5(const char * expected_md5){
if(strlen(expected_md5) != 32)
{
return false;
}
_target_md5 = expected_md5;
return true;
}
bool TasUpdateClass::end(bool evenIfRemaining){
if(hasError() || _size == 0){
return false;
}
if(!isFinished() && !evenIfRemaining){
log_e("premature end: res:%u, pos:%u/%u\n", getError(), progress(), _size);
_abort(UPDATE_ERROR_ABORT);
return false;
}
if(evenIfRemaining) {
if(_bufferLen > 0) {
_writeBuffer();
}
_size = progress();
}
_md5.calculate();
if(_target_md5.length()) {
if(_target_md5 != _md5.toString()){
_abort(UPDATE_ERROR_MD5);
return false;
}
}
return _verifyEnd();
}
size_t TasUpdateClass::write(uint8_t *data, size_t len) {
if(hasError() || !isRunning()){
return 0;
}
if(len > remaining()){
_abort(UPDATE_ERROR_SPACE);
return 0;
}
size_t left = len;
while((_bufferLen + left) > SPI_FLASH_SEC_SIZE) {
size_t toBuff = SPI_FLASH_SEC_SIZE - _bufferLen;
memcpy(_buffer + _bufferLen, data + (len - left), toBuff);
_bufferLen += toBuff;
if(!_writeBuffer()){
return len - left;
}
left -= toBuff;
}
memcpy(_buffer + _bufferLen, data + (len - left), left);
_bufferLen += left;
if(_bufferLen == remaining()){
if(!_writeBuffer()){
return len - left;
}
}
return len;
}
size_t TasUpdateClass::writeStream(Stream &data) {
size_t written = 0;
size_t toRead = 0;
int timeout_failures = 0;
if(hasError() || !isRunning())
return 0;
if(!_verifyHeader(data.peek())) {
_reset();
return 0;
}
if(_ledPin != -1) {
pinMode(_ledPin, OUTPUT);
}
while(remaining()) {
if(_ledPin != -1) {
digitalWrite(_ledPin, _ledOn); // Switch LED on
}
size_t bytesToRead = SPI_FLASH_SEC_SIZE - _bufferLen;
if(bytesToRead > remaining()) {
bytesToRead = remaining();
}
/*
Init read&timeout counters and try to read, if read failed, increase counter,
wait 100ms and try to read again. If counter > 300 (30 sec), give up/abort
*/
toRead = 0;
timeout_failures = 0;
while(!toRead) {
toRead = data.readBytes(_buffer + _bufferLen, bytesToRead);
if(toRead == 0) {
timeout_failures++;
if (timeout_failures >= 300) {
_abort(UPDATE_ERROR_STREAM);
return written;
}
delay(100);
}
}
if(_ledPin != -1) {
digitalWrite(_ledPin, !_ledOn); // Switch LED off
}
_bufferLen += toRead;
if((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer())
return written;
written += toRead;
delay(1); // Fix solo WDT
}
return written;
}
void TasUpdateClass::printError(Print &out){
out.println(_err2str(_error));
}
const char * TasUpdateClass::errorString(){
return _err2str(_error);
}
TasUpdateClass TasUpdate;

View File

@ -45,7 +45,6 @@ extern void analogWritePhase(uint8_t pin, uint32_t duty, uint32_t phase = 0);
#define ETS_UART_INTR_ENABLE()
#define ESPhttpUpdate httpUpdate
#define getFlashChipRealSize() getFlashChipSize()
#define os_delay_us ets_delay_us
// Serial minimal type to hold the config

View File

@ -171,6 +171,9 @@ public:
operator bool() {
return (bool) _f;
}
bool setBufferSize(size_t size) {
return true;
}
protected:
File _f;
@ -226,6 +229,10 @@ public:
// do nothing
}
bool setBufferSize(size_t size) {
return true;
}
bool seek(uint32_t pos, SeekMode mode) {
// AddLog(LOG_LEVEL_DEBUG, "ZIP: seek pos=%i mode=%i", pos, mode);
if (SeekSet == mode) {
@ -386,8 +393,26 @@ bool ZipArchive::parse(void) {
**
********************************************************************/
/* get the FS corresponding to the prefix, typically /sd/ for sdcard */
FS * ZipReadFSImpl::getFS(const char *path) const {
if (_fs == nullptr) { return nullptr; }
if (_alt_fs == nullptr || _alt_fs_prefix == nullptr) { return *_fs; }
/* from now neither _fs not _alt_fs are null
/* if however they point to the same value, then we don't have an alternative FS */
if (*_fs == *_alt_fs) { return *_fs; }
/* check prefix */
if (strncmp(_alt_fs_prefix, path, strlen(_alt_fs_prefix))) {
return *_alt_fs;
} else {
return *_fs;
}
}
FileImplPtr ZipReadFSImpl::open(const char* path, const char* mode, const bool create) {
if (*_fs == nullptr) { return nullptr; }
FS * fs = getFS(path);
if (fs == nullptr) { return nullptr; }
if (strchr(path, '#')) {
// we don't support any other mode than "r" and no-create
@ -407,7 +432,7 @@ FileImplPtr ZipReadFSImpl::open(const char* path, const char* mode, const bool c
if (*suffix == '/') { suffix++; }
// AddLog(LOG_LEVEL_DEBUG, "ZIP: prefix=%s suffix=%s", prefix, suffix);
// parse ZIP archive
File zipfile = (*_fs)->open(prefix, "r", false);
File zipfile = fs->open(prefix, "r", false);
if ((bool)zipfile) {
// we could read the file
ZipArchive zip_archive = ZipArchive(&zipfile);
@ -417,7 +442,7 @@ FileImplPtr ZipReadFSImpl::open(const char* path, const char* mode, const bool c
if (entry.file_name.equals(suffix)) {
// found
// AddLog(LOG_LEVEL_DEBUG, "ZIP: file '%s' in archive (start=%i - len=%i - last_mod=%i)", suffix, entry.file_start, entry.file_len, entry.last_mod);
return ZipItemImplPtr(new ZipItemImpl((*_fs)->open(prefix, "r", false), entry.file_start, entry.file_len, entry.last_mod));
return ZipItemImplPtr(new ZipItemImpl(fs->open(prefix, "r", false), entry.file_start, entry.file_len, entry.last_mod));
}
}
return ZipReadFileImplPtr(); // return an error
@ -427,12 +452,13 @@ FileImplPtr ZipReadFSImpl::open(const char* path, const char* mode, const bool c
}
} else {
// simple file, do nothing
return ZipReadFileImplPtr(new ZipReadFileImpl((*_fs)->open(path, mode, create)));
return ZipReadFileImplPtr(new ZipReadFileImpl(fs->open(path, mode, create)));
}
}
bool ZipReadFSImpl::exists(const char* path) {
if (*_fs == nullptr) { return false; }
FS * fs = getFS(path);
if (fs == nullptr) { return false; }
if (strchr(path, '#')) {
// treat as a ZIP archive
@ -444,7 +470,7 @@ bool ZipReadFSImpl::exists(const char* path) {
char *prefix = strtok_r(sub_path, "#", &tok);
char *suffix = strtok_r(NULL, "", &tok);
// parse ZIP archive
File zipfile = (*_fs)->open(prefix, "r", false);
File zipfile = fs->open(prefix, "r", false);
if ((bool)zipfile) {
// we could read the file
ZipArchive zip_archive = ZipArchive(&zipfile);
@ -459,7 +485,7 @@ bool ZipReadFSImpl::exists(const char* path) {
return false;
} else {
// simple file, do nothing
return (*_fs)->exists(path);
return fs->exists(path);
}
}

View File

@ -17,40 +17,32 @@ typedef std::shared_ptr<FSImpl> ZipReadFSImplPtr;
class ZipReadFSImpl : public FSImpl {
public:
ZipReadFSImpl(FS **fs) : _fs(fs) {};
ZipReadFSImpl(FS **fs) : _fs(fs), _alt_fs(nullptr), _alt_fs_prefix(nullptr) {};
ZipReadFSImpl(FS **fs, const char *alt_fs_prefix, FS **alt_fs) : _fs(fs), _alt_fs(alt_fs), _alt_fs_prefix(alt_fs_prefix) {};
virtual ~ZipReadFSImpl();
/* get the FS corresponding to the prefix, typically /sd/ for sdcard */
FS * getFS(const char *path) const;
FileImplPtr open(const char* path, const char* mode, const bool create);
bool exists(const char* path);
bool rename(const char* pathFrom, const char* pathTo) {
if (*_fs) {
return (*_fs)->rename(pathFrom, pathTo);
} else {
return false;
}
FS * fs = getFS(pathFrom);
return fs ? fs->rename(pathFrom, pathTo) : false;
}
bool remove(const char* path) {
if (*_fs) {
return (*_fs)->remove(path);
} else {
return false;
}
FS * fs = getFS(path);
return fs ? fs->remove(path) : false;
}
bool mkdir(const char *path) {
if (*_fs) {
return (*_fs)->mkdir(path);
} else {
return false;
}
FS * fs = getFS(path);
return fs ? fs->mkdir(path) : false;
}
bool rmdir(const char *path) {
if (*_fs) {
return (*_fs)->rmdir(path);
} else {
return false;
}
FS * fs = getFS(path);
return fs ? fs->rmdir(path) : false;
}
void mountpoint(const char *) {
};
@ -60,6 +52,8 @@ public:
private:
FS **_fs;
FS **_alt_fs;
const char *_alt_fs_prefix;
};
#endif // ESP32

View File

@ -46,13 +46,19 @@ be_extern_native_module(hue_ntv);
be_extern_native_module(hue_bridge);
be_extern_native_module(uuid);
be_extern_native_module(animate);
be_extern_native_module(partition_core);
be_extern_native_module(crc);
be_extern_native_module(crypto);
#ifdef USE_ZIGBEE
be_extern_native_module(zigbee);
#endif // USE_ZIGBEE
#ifdef USE_LVGL
be_extern_native_module(lv);
be_extern_native_module(lv_extra);
be_extern_native_module(lv_tasmota);
#ifdef USE_LVGL_OPENHASP
be_extern_native_module(openhasp);
#endif // USE_LVGL_OPENHASP
#ifdef USE_LVGL_HASPMOTA
be_extern_native_module(haspmota);
#endif // USE_LVGL_HASPMOTA
#endif // USE_LVGL
/* user-defined modules declare start */
@ -135,9 +141,9 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
&be_native_module(lv),
&be_native_module(lv_extra),
&be_native_module(lv_tasmota),
#ifdef USE_LVGL_OPENHASP
&be_native_module(openhasp),
#endif // USE_LVGL_OPENHASP
#ifdef USE_LVGL_HASPMOTA
&be_native_module(haspmota),
#endif // USE_LVGL_HASPMOTA
#endif // USE_LVGL
#ifdef USE_ENERGY_SENSOR
&be_native_module(energy),
@ -145,7 +151,15 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_WEBSERVER
&be_native_module(webserver),
#endif // USE_WEBSERVER
#ifdef USE_ZIGBEE
&be_native_module(zigbee),
#endif // USE_ZIGBEE
&be_native_module(flash),
&be_native_module(partition_core),
&be_native_module(crc),
#ifdef USE_ALEXA_AVS
&be_native_module(crypto),
#endif
/* user-defined modules register end */
NULL /* do not remove */
@ -179,6 +193,7 @@ be_extern_native_class(md5);
be_extern_native_class(udp);
be_extern_native_class(webclient);
be_extern_native_class(tcpclient);
be_extern_native_class(energy_struct);
// BLE
be_extern_native_class(MI32);
be_extern_native_class(BLE);
@ -230,6 +245,9 @@ BERRY_LOCAL bclass_array be_class_table = {
&be_native_class(Leds),
&be_native_class(Leds_animator),
#endif // USE_WS2812
#ifdef USE_ENERGY_SENSOR
&be_native_class(energy_struct),
#endif // USE_ENERGY_SENSOR
#ifdef USE_LVGL
&be_native_class(LVGL_glob),
@ -266,7 +284,6 @@ BERRY_LOCAL bclass_array be_class_table = {
NULL, /* do not remove */
};
extern void be_load_crypto_lib(bvm *vm);
extern void be_load_ctypes_energy_definitions_lib(bvm *vm);
/* this code loads the native class definitions */
@ -278,10 +295,4 @@ BERRY_API void be_load_custom_libs(bvm *vm)
#if !BE_USE_PRECOMPILED_OBJECT
/* be_load_xxxlib(vm); */
#endif
#ifdef USE_ALEXA_AVS
be_load_crypto_lib(vm); // sub-module
#endif
#ifdef USE_ENERGY_SENSOR
be_load_ctypes_energy_definitions_lib(vm); // ctype class
#endif // USE_ENERGY_SENSOR
}

View File

@ -12,7 +12,7 @@
#ifdef COMPILE_BERRY_LIB
#include "my_user_config.h"
#include "tasmota_configurations.h"
#include "include/tasmota_configurations.h"
#endif
/* Macro: BE_DEBUG
@ -175,6 +175,14 @@
**/
#define BE_USE_DEBUG_GC 0
/* Macro: BE_USE_DEBUG_STACK
* Enable Stack Resize debug mode. At each function call
* the stack is reallocated at a different memory location
* and the previous location is cleared with toxic data.
* Default: 0
**/
#define BE_USE_DEBUG_STACK 0
/* Macro: BE_USE_MEM_ALIGNED
* Some embedded processors have special memory areas
* with read/write constraints of being aligned to 32 bits boundaries.

View File

@ -1,2 +1,8 @@
#!/bin/bash
#
# generate all precompiled Berry structures from multiple modules
#
# Should be eventually included in the build process
#
rm generate/be_*.h
python3 tools/pycoc/main.py -o generate src default ../berry_tasmota/src ../berry_mapping/src ../berry_int64/src ../../libesp32_lvgl/lv_binding_berry/src ../../libesp32_lvgl/lv_binding_berry/generate -c default/berry_conf.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioFileSource_map) {
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key_weak(_X2Ep, -1), be_const_var(0) },
};
static be_define_const_map(

View File

@ -1,8 +1,8 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioFileSourceFS_map) {
{ be_const_key(deinit, -1), be_const_func(i2s_file_source_fs_deinit) },
{ be_const_key(init, -1), be_const_func(i2s_file_source_fs_init) },
{ be_const_key_weak(deinit, -1), be_const_func(i2s_file_source_fs_deinit) },
{ be_const_key_weak(init, -1), be_const_func(i2s_file_source_fs_init) },
};
static be_define_const_map(

View File

@ -1,7 +1,7 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioGenerator_map) {
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key_weak(_X2Ep, -1), be_const_var(0) },
};
static be_define_const_map(

View File

@ -1,12 +1,12 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioGeneratorMP3_map) {
{ be_const_key(begin, -1), be_const_func(i2s_generator_mp3_begin) },
{ be_const_key(loop, -1), be_const_func(i2s_generator_mp3_loop) },
{ be_const_key(isrunning, -1), be_const_func(i2s_generator_mp3_isrunning) },
{ be_const_key(init, 1), be_const_func(i2s_generator_mp3_init) },
{ be_const_key(deinit, -1), be_const_func(i2s_generator_mp3_deinit) },
{ be_const_key(stop, -1), be_const_func(i2s_generator_mp3_stop) },
{ be_const_key_weak(begin, -1), be_const_func(i2s_generator_mp3_begin) },
{ be_const_key_weak(loop, -1), be_const_func(i2s_generator_mp3_loop) },
{ be_const_key_weak(isrunning, -1), be_const_func(i2s_generator_mp3_isrunning) },
{ be_const_key_weak(init, 1), be_const_func(i2s_generator_mp3_init) },
{ be_const_key_weak(deinit, -1), be_const_func(i2s_generator_mp3_deinit) },
{ be_const_key_weak(stop, -1), be_const_func(i2s_generator_mp3_stop) },
};
static be_define_const_map(

View File

@ -1,12 +1,12 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioGeneratorWAV_map) {
{ be_const_key(begin, -1), be_const_func(i2s_generator_wav_begin) },
{ be_const_key(loop, -1), be_const_func(i2s_generator_wav_loop) },
{ be_const_key(isrunning, -1), be_const_func(i2s_generator_wav_isrunning) },
{ be_const_key(init, 1), be_const_func(i2s_generator_wav_init) },
{ be_const_key(deinit, -1), be_const_func(i2s_generator_wav_deinit) },
{ be_const_key(stop, -1), be_const_func(i2s_generator_wav_stop) },
{ be_const_key_weak(begin, -1), be_const_func(i2s_generator_wav_begin) },
{ be_const_key_weak(loop, -1), be_const_func(i2s_generator_wav_loop) },
{ be_const_key_weak(isrunning, -1), be_const_func(i2s_generator_wav_isrunning) },
{ be_const_key_weak(init, 1), be_const_func(i2s_generator_wav_init) },
{ be_const_key_weak(deinit, -1), be_const_func(i2s_generator_wav_deinit) },
{ be_const_key_weak(stop, -1), be_const_func(i2s_generator_wav_stop) },
};
static be_define_const_map(

View File

@ -1,10 +1,10 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioOpusDecoder_map) {
{ be_const_key(deinit, -1), be_const_func(be_audio_opus_decoder_deinit) },
{ be_const_key(decode, 2), be_const_func(be_audio_opus_decoder_decode) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(init, 1), be_const_func(be_audio_opus_decoder_init) },
{ be_const_key_weak(deinit, -1), be_const_func(be_audio_opus_decoder_deinit) },
{ be_const_key_weak(decode, 2), be_const_func(be_audio_opus_decoder_decode) },
{ be_const_key_weak(_X2Ep, -1), be_const_var(0) },
{ be_const_key_weak(init, 1), be_const_func(be_audio_opus_decoder_init) },
};
static be_define_const_map(

View File

@ -1,18 +1,18 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioOutput_map) {
{ be_const_key(set_bits_per_sample, -1), be_const_func(be_audio_output_set_bits_per_sample) },
{ be_const_key(flush, -1), be_const_func(be_audio_output_flush) },
{ be_const_key(consume_stereo, -1), be_const_func(be_audio_output_consume_stereo) },
{ be_const_key(init, -1), be_const_func(be_audio_output_init) },
{ be_const_key(consume_mono, -1), be_const_func(be_audio_output_consume_mono) },
{ be_const_key(stop, -1), be_const_func(be_audio_output_stop) },
{ be_const_key(begin, -1), be_const_func(be_audio_output_begin) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(set_channels, -1), be_const_func(be_audio_output_set_channels) },
{ be_const_key(consume_silence, 4), be_const_func(be_audio_output_consume_silence) },
{ be_const_key(set_rate, 2), be_const_func(be_audio_output_set_rate) },
{ be_const_key(set_gain, 0), be_const_func(be_audio_output_set_gain) },
{ be_const_key_weak(set_bits_per_sample, -1), be_const_func(be_audio_output_set_bits_per_sample) },
{ be_const_key_weak(flush, -1), be_const_func(be_audio_output_flush) },
{ be_const_key_weak(consume_stereo, -1), be_const_func(be_audio_output_consume_stereo) },
{ be_const_key_weak(init, -1), be_const_func(be_audio_output_init) },
{ be_const_key_weak(consume_mono, -1), be_const_func(be_audio_output_consume_mono) },
{ be_const_key_weak(stop, -1), be_const_func(be_audio_output_stop) },
{ be_const_key_weak(begin, -1), be_const_func(be_audio_output_begin) },
{ be_const_key_weak(_X2Ep, -1), be_const_var(0) },
{ be_const_key_weak(set_channels, -1), be_const_func(be_audio_output_set_channels) },
{ be_const_key_weak(consume_silence, 4), be_const_func(be_audio_output_consume_silence) },
{ be_const_key_weak(set_rate, 2), be_const_func(be_audio_output_set_rate) },
{ be_const_key_weak(set_gain, 0), be_const_func(be_audio_output_set_gain) },
};
static be_define_const_map(

View File

@ -1,12 +1,12 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_AudioOutputI2S_map) {
{ be_const_key(INTERNAL_PDM, -1), be_const_int(AudioOutputI2S::INTERNAL_PDM) },
{ be_const_key(INTERNAL_DAC, 2), be_const_int(AudioOutputI2S::INTERNAL_DAC) },
{ be_const_key(init, -1), be_const_func(i2s_output_i2s_init) },
{ be_const_key(EXTERNAL_I2S, 1), be_const_int(AudioOutputI2S::EXTERNAL_I2S) },
{ be_const_key(deinit, -1), be_const_func(i2s_output_i2s_deinit) },
{ be_const_key(stop, -1), be_const_func(i2s_output_i2s_stop) },
{ be_const_key_weak(INTERNAL_PDM, -1), be_const_int(AudioOutputI2S::INTERNAL_PDM) },
{ be_const_key_weak(INTERNAL_DAC, 2), be_const_int(AudioOutputI2S::INTERNAL_DAC) },
{ be_const_key_weak(init, -1), be_const_func(i2s_output_i2s_init) },
{ be_const_key_weak(EXTERNAL_I2S, 1), be_const_int(AudioOutputI2S::EXTERNAL_I2S) },
{ be_const_key_weak(deinit, -1), be_const_func(i2s_output_i2s_deinit) },
{ be_const_key_weak(stop, -1), be_const_func(i2s_output_i2s_stop) },
};
static be_define_const_map(

View File

@ -1,14 +1,14 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_BLE_map) {
{ be_const_key(adv_block, -1), be_const_func(be_BLE_adv_block) },
{ be_const_key(conn_cb, -1), be_const_func(be_BLE_reg_conn_cb) },
{ be_const_key(adv_cb, 5), be_const_func(be_BLE_reg_adv_cb) },
{ be_const_key(set_MAC, -1), be_const_func(be_BLE_set_MAC) },
{ be_const_key(adv_watch, -1), be_const_func(be_BLE_adv_watch) },
{ be_const_key(run, -1), be_const_func(be_BLE_run) },
{ be_const_key(set_svc, 4), be_const_func(be_BLE_set_service) },
{ be_const_key(set_chr, 3), be_const_func(be_BLE_set_characteristic) },
{ be_const_key_weak(adv_block, -1), be_const_func(be_BLE_adv_block) },
{ be_const_key_weak(conn_cb, -1), be_const_func(be_BLE_reg_conn_cb) },
{ be_const_key_weak(adv_cb, 5), be_const_func(be_BLE_reg_adv_cb) },
{ be_const_key_weak(set_MAC, -1), be_const_func(be_BLE_set_MAC) },
{ be_const_key_weak(adv_watch, -1), be_const_func(be_BLE_adv_watch) },
{ be_const_key_weak(run, -1), be_const_func(be_BLE_run) },
{ be_const_key_weak(set_svc, 4), be_const_func(be_BLE_set_service) },
{ be_const_key_weak(set_chr, 3), be_const_func(be_BLE_set_characteristic) },
};
static be_define_const_map(

View File

@ -1,18 +1,18 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_OneWire_map) {
{ be_const_key(reset, -1), be_const_func(b_onewire_reset) },
{ be_const_key(search, 10), be_const_func(b_onewire_search) },
{ be_const_key(depower, -1), be_const_func(b_onewire_depower) },
{ be_const_key(init, 2), be_const_func(b_onewire_init) },
{ be_const_key(deinit, -1), be_const_func(b_onewire_deinit) },
{ be_const_key(reset_search, -1), be_const_func(b_onewire_reset_search) },
{ be_const_key(skip, -1), be_const_func(b_onewire_skip) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(write, -1), be_const_func(b_onewire_write) },
{ be_const_key(read, -1), be_const_func(b_onewire_read) },
{ be_const_key(select, 11), be_const_func(b_onewire_select) },
{ be_const_key(target_search, -1), be_const_func(b_onewire_target_search) },
{ be_const_key_weak(reset, -1), be_const_func(b_onewire_reset) },
{ be_const_key_weak(search, 10), be_const_func(b_onewire_search) },
{ be_const_key_weak(depower, -1), be_const_func(b_onewire_depower) },
{ be_const_key_weak(init, 2), be_const_func(b_onewire_init) },
{ be_const_key_weak(deinit, -1), be_const_func(b_onewire_deinit) },
{ be_const_key_weak(reset_search, -1), be_const_func(b_onewire_reset_search) },
{ be_const_key_weak(skip, -1), be_const_func(b_onewire_skip) },
{ be_const_key_weak(_X2Ep, -1), be_const_var(0) },
{ be_const_key_weak(write, -1), be_const_func(b_onewire_write) },
{ be_const_key_weak(read, -1), be_const_func(b_onewire_read) },
{ be_const_key_weak(select, 11), be_const_func(b_onewire_select) },
{ be_const_key_weak(target_search, -1), be_const_func(b_onewire_target_search) },
};
static be_define_const_map(

View File

@ -1,12 +1,12 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_aes_gcm_map) {
{ be_const_key(encrypt, 4), be_const_func(m_aes_gcm_encryt) },
{ be_const_key(_X2Ep2, -1), be_const_var(0) },
{ be_const_key(decrypt, -1), be_const_func(m_aes_gcm_decryt) },
{ be_const_key(init, -1), be_const_func(m_aes_gcm_init) },
{ be_const_key(_X2Ep1, -1), be_const_var(1) },
{ be_const_key(tag, -1), be_const_func(m_aes_gcm_tag) },
{ be_const_key_weak(encrypt, 4), be_const_func(m_aes_gcm_encryt) },
{ be_const_key_weak(_X2Ep2, -1), be_const_var(0) },
{ be_const_key_weak(decrypt, -1), be_const_func(m_aes_gcm_decryt) },
{ be_const_key_weak(init, -1), be_const_func(m_aes_gcm_init) },
{ be_const_key_weak(_X2Ep1, -1), be_const_var(1) },
{ be_const_key_weak(tag, -1), be_const_func(m_aes_gcm_tag) },
};
static be_define_const_map(

View File

@ -1,42 +1,44 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_bytes_map) {
{ be_const_key(deinit, -1), be_const_func(m_deinit) },
{ be_const_key(get, 5), be_const_func(m_getu) },
{ be_const_key(fromb64, 18), be_const_func(m_fromb64) },
{ be_const_key(copy, -1), be_const_func(m_copy) },
{ be_const_key(_buffer, -1), be_const_func(m_buffer) },
{ be_const_key(getfloat, -1), be_const_func(m_getfloat) },
{ be_const_key(getbits, -1), be_const_closure(getbits_closure) },
{ be_const_key(tob64, -1), be_const_func(m_tob64) },
{ be_const_key(item, -1), be_const_func(m_item) },
{ be_const_key(_X21_X3D, -1), be_const_func(m_nequal) },
{ be_const_key(clear, 28), be_const_func(m_clear) },
{ be_const_key(size, 4), be_const_func(m_size) },
{ be_const_key(fromstring, -1), be_const_func(m_fromstring) },
{ be_const_key(_X2Elen, 21), be_const_var(0) },
{ be_const_key(seti, -1), be_const_func(m_set) },
{ be_const_key(_X2B, 9), be_const_func(m_merge) },
{ be_const_key(_X2Esize, 13), be_const_var(1) },
{ be_const_key(setfloat, 6), be_const_func(m_setfloat) },
{ be_const_key(_X2Ep, -1), be_const_var(2) },
{ be_const_key(set, -1), be_const_func(m_set) },
{ be_const_key(asstring, 0), be_const_func(m_asstring) },
{ be_const_key(add, 24), be_const_func(m_add) },
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
{ be_const_key(_change_buffer, -1), be_const_func(m_change_buffer) },
{ be_const_key(_X3D_X3D, 15), be_const_func(m_equal) },
{ be_const_key(resize, 2), be_const_func(m_resize) },
{ be_const_key(tostring, -1), be_const_func(m_tostring) },
{ be_const_key(setbits, -1), be_const_closure(setbits_closure) },
{ be_const_key(_X2Elen, 0), be_const_var(0) },
{ be_const_key(tob64, 4), be_const_func(m_tob64) },
{ be_const_key(_X2E_X2E, -1), be_const_func(m_connect) },
{ be_const_key(setfloat, -1), be_const_func(m_setfloat) },
{ be_const_key(get, 2), be_const_func(m_getu) },
{ be_const_key(asstring, -1), be_const_func(m_asstring) },
{ be_const_key(getfloat, 24), be_const_func(m_getfloat) },
{ be_const_key(_buffer, -1), be_const_func(m_buffer) },
{ be_const_key(init, -1), be_const_func(m_init) },
{ be_const_key(_X2Esize, 23), be_const_var(1) },
{ be_const_key(tohex, 16), be_const_func(m_tohex) },
{ be_const_key(fromhex, -1), be_const_func(m_fromhex) },
{ be_const_key(setbits, 7), be_const_closure(setbits_closure) },
{ be_const_key(copy, 31), be_const_func(m_copy) },
{ be_const_key(size, 17), be_const_func(m_size) },
{ be_const_key(getbits, -1), be_const_closure(getbits_closure) },
{ be_const_key(fromb64, -1), be_const_func(m_fromb64) },
{ be_const_key(_change_buffer, -1), be_const_func(m_change_buffer) },
{ be_const_key(_X21_X3D, 30), be_const_func(m_nequal) },
{ be_const_key(clear, -1), be_const_func(m_clear) },
{ be_const_key(seti, 18), be_const_func(m_set) },
{ be_const_key(_X2B, -1), be_const_func(m_merge) },
{ be_const_key(add, 26), be_const_func(m_add) },
{ be_const_key(deinit, -1), be_const_func(m_deinit) },
{ be_const_key(tostring, -1), be_const_func(m_tostring) },
{ be_const_key(item, -1), be_const_func(m_item) },
{ be_const_key(geti, -1), be_const_func(m_geti) },
{ be_const_key(resize, -1), be_const_func(m_resize) },
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
{ be_const_key(_X2Ep, -1), be_const_var(2) },
{ be_const_key(fromstring, -1), be_const_func(m_fromstring) },
{ be_const_key(_X3D_X3D, -1), be_const_func(m_equal) },
};
static be_define_const_map(
be_class_bytes_map,
31
33
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -1,8 +1,8 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_ec_c25519_map) {
{ be_const_key(public_key, 1), be_const_func(m_ec_c25519_pubkey) },
{ be_const_key(shared_key, -1), be_const_func(m_ec_c25519_sharedkey) },
{ be_const_key_weak(public_key, 1), be_const_func(m_ec_c25519_pubkey) },
{ be_const_key_weak(shared_key, -1), be_const_func(m_ec_c25519_sharedkey) },
};
static be_define_const_map(

View File

@ -1,27 +1,28 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_webclient_map) {
{ be_const_key(close, -1), be_const_func(wc_close) },
{ be_const_key(get_string, 5), be_const_func(wc_getstring) },
{ be_const_key(_X2Ew, 11), be_const_var(0) },
{ be_const_key(_X2Ep, 13), be_const_var(1) },
{ be_const_key(add_header, 10), be_const_func(wc_addheader) },
{ be_const_key(url_encode, -1), be_const_func(wc_urlencode) },
{ be_const_key(POST, -1), be_const_func(wc_POST) },
{ be_const_key(GET, 6), be_const_func(wc_GET) },
{ be_const_key(deinit, -1), be_const_func(wc_deinit) },
{ be_const_key(get_size, -1), be_const_func(wc_getsize) },
{ be_const_key(set_timeouts, -1), be_const_func(wc_set_timeouts) },
{ be_const_key(set_auth, -1), be_const_func(wc_set_auth) },
{ be_const_key(set_useragent, -1), be_const_func(wc_set_useragent) },
{ be_const_key(init, 0), be_const_func(wc_init) },
{ be_const_key(write_file, 3), be_const_func(wc_writefile) },
{ be_const_key(begin, -1), be_const_func(wc_begin) },
{ be_const_key(write_file, -1), be_const_func(wc_writefile) },
{ be_const_key(_X2Ep, 16), be_const_var(0) },
{ be_const_key(set_useragent, -1), be_const_func(wc_set_useragent) },
{ be_const_key(get_size, -1), be_const_func(wc_getsize) },
{ be_const_key(set_auth, -1), be_const_func(wc_set_auth) },
{ be_const_key(write_flash, -1), be_const_func(wc_writeflash) },
{ be_const_key(get_string, -1), be_const_func(wc_getstring) },
{ be_const_key(init, -1), be_const_func(wc_init) },
{ be_const_key(GET, 0), be_const_func(wc_GET) },
{ be_const_key(_X2Ew, -1), be_const_var(1) },
{ be_const_key(deinit, -1), be_const_func(wc_deinit) },
{ be_const_key(set_timeouts, 1), be_const_func(wc_set_timeouts) },
{ be_const_key(close, 2), be_const_func(wc_close) },
{ be_const_key(add_header, -1), be_const_func(wc_addheader) },
{ be_const_key(url_encode, 8), be_const_func(wc_urlencode) },
{ be_const_key(POST, -1), be_const_func(wc_POST) },
};
static be_define_const_map(
be_class_webclient_map,
16
17
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -0,0 +1,23 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_zb_coord_ntv_map) {
{ be_const_key_weak(iter, -1), be_const_func(zc_iter) },
{ be_const_key_weak(zcl_frame, -1), be_const_class(be_class_zcl_frame) },
{ be_const_key_weak(zb_device, 3), be_const_class(be_class_zb_device) },
{ be_const_key_weak(info, -1), be_const_func(zc_info) },
{ be_const_key_weak(size, 1), be_const_ctype_func(zc_size) },
{ be_const_key_weak(item, -1), be_const_func(zc_item) },
{ be_const_key_weak(abort, 4), be_const_ctype_func(zc_abort) },
};
static be_define_const_map(
be_class_zb_coord_ntv_map,
7
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_zb_coord_ntv,
0,
NULL,
zb_coord_ntv
);

View File

@ -0,0 +1,20 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_zb_device_map) {
{ be_const_key_weak(init, -1), be_const_ctype_func(zd_init) },
{ be_const_key_weak(tostring, -1), be_const_closure(zb_device_tostring_closure) },
{ be_const_key_weak(_p, -1), be_const_var(0) },
{ be_const_key_weak(member, 0), be_const_func(zd_member) },
};
static be_define_const_map(
be_class_zb_device_map,
4
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_zb_device,
1,
NULL,
zb_device
);

View File

@ -0,0 +1,19 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_zcl_frame_ntv_map) {
{ be_const_key_weak(_set_bytes, -1), be_const_ctype_func(zfn_set_bytes) },
{ be_const_key_weak(_def, 2), be_const_comptr(&be_zigbee_zcl_frame_struct) },
{ be_const_key_weak(_get_bytes, -1), be_const_ctype_func(zfn_get_bytes) },
};
static be_define_const_map(
be_class_zcl_frame_ntv_map,
3
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_zcl_frame_ntv,
0,
(bclass *)&be_class_ctypes_bytes,
zcl_frame_ntv
);

View File

@ -0,0 +1,20 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libcrc_map) {
{ be_const_key(crc32, 1), be_const_ctype_func(c_crc32) },
{ be_const_key(sum, -1), be_const_ctype_func(c_sum) },
{ be_const_key(crc16, -1), be_const_ctype_func(c_crc16) },
{ be_const_key(crc8, -1), be_const_ctype_func(c_crc8) },
};
static be_define_const_map(
m_libcrc_map,
4
);
static be_define_const_module(
m_libcrc,
"crc"
);
BE_EXPORT_VARIABLE be_define_const_native_module(crc);

View File

@ -0,0 +1,18 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libcrypto_map) {
{ be_const_key_weak(AES_GCM, -1), be_const_class(be_class_aes_gcm) },
{ be_const_key_weak(EC_C25519, -1), be_const_class(be_class_ec_c25519) },
};
static be_define_const_map(
m_libcrypto_map,
2
);
static be_define_const_module(
m_libcrypto,
"crypto"
);
BE_EXPORT_VARIABLE be_define_const_native_module(crypto);

View File

@ -1,11 +1,11 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libdisplay_map) {
{ be_const_key(start, -1), be_const_func(be_ntv_display_start) },
{ be_const_key(started, 0), be_const_ctype_func(be_ntv_display_started) },
{ be_const_key(driver_name, -1), be_const_ctype_func(be_ntv_display_driver_name) },
{ be_const_key(touch_update, 2), be_const_ctype_func(be_ntv_display_touch_update) },
{ be_const_key(dimmer, -1), be_const_func(be_ntv_display_dimmer) },
{ be_const_key_weak(start, -1), be_const_func(be_ntv_display_start) },
{ be_const_key_weak(started, 0), be_const_ctype_func(be_ntv_display_started) },
{ be_const_key_weak(driver_name, -1), be_const_ctype_func(be_ntv_display_driver_name) },
{ be_const_key_weak(touch_update, 2), be_const_ctype_func(be_ntv_display_touch_update) },
{ be_const_key_weak(dimmer, -1), be_const_func(be_ntv_display_dimmer) },
};
static be_define_const_map(

View File

@ -1,14 +1,17 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libflash_map) {
{ be_const_key(id, 5), be_const_ctype_func(p_flashid) },
{ be_const_key(factory, 4), be_const_ctype_func(p_factory) },
{ be_const_key(write, -1), be_const_func(p_flash_write) },
{ be_const_key(read, -1), be_const_func(p_flash_read) },
{ be_const_key(erase, -1), be_const_func(p_flash_erase) },
{ be_const_key(write, -1), be_const_func(p_flash_write) },
{ be_const_key(size, -1), be_const_ctype_func(p_flashsize) },
};
static be_define_const_map(
m_libflash_map,
3
6
);
static be_define_const_module(

View File

@ -1,19 +1,19 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_liblv_tasmota_map) {
{ be_const_key(load_freetype_font, -1), be_const_func(lv0_load_freetype_font) },
{ be_const_key(seg7_font, -1), be_const_func(lv0_load_seg7_font) },
{ be_const_key(screenshot, 11), be_const_func(lv0_screenshot) },
{ be_const_key(font_seg7, 1), be_const_func(lv0_load_seg7_font) },
{ be_const_key(splash_init, 0), be_const_closure(lv_tasmota_splash_init_closure) },
{ be_const_key(register_button_encoder, -1), be_const_func(lv0_register_button_encoder) },
{ be_const_key(init, 7), be_const_closure(lv_tasmota_init_closure) },
{ be_const_key(splash_remove, -1), be_const_closure(lv_tasmota_splash_remove_closure) },
{ be_const_key(start, -1), be_const_func(lv0_start) },
{ be_const_key(font_montserrat, -1), be_const_func(lv0_load_montserrat_font) },
{ be_const_key(font_embedded, -1), be_const_func(lv0_load_font_embedded) },
{ be_const_key(montserrat_font, -1), be_const_func(lv0_load_montserrat_font) },
{ be_const_key(splash, 10), be_const_closure(lv_tasmota_splash_closure) },
{ be_const_key_weak(load_freetype_font, -1), be_const_func(lv0_load_freetype_font) },
{ be_const_key_weak(seg7_font, -1), be_const_func(lv0_load_seg7_font) },
{ be_const_key_weak(screenshot, 11), be_const_func(lv0_screenshot) },
{ be_const_key_weak(font_seg7, 1), be_const_func(lv0_load_seg7_font) },
{ be_const_key_weak(splash_init, 0), be_const_closure(lv_tasmota_splash_init_closure) },
{ be_const_key_weak(register_button_encoder, -1), be_const_func(lv0_register_button_encoder) },
{ be_const_key_weak(init, 7), be_const_closure(lv_tasmota_init_closure) },
{ be_const_key_weak(splash_remove, -1), be_const_closure(lv_tasmota_splash_remove_closure) },
{ be_const_key_weak(start, -1), be_const_func(lv0_start) },
{ be_const_key_weak(font_montserrat, -1), be_const_func(lv0_load_montserrat_font) },
{ be_const_key_weak(font_embedded, -1), be_const_func(lv0_load_font_embedded) },
{ be_const_key_weak(montserrat_font, -1), be_const_func(lv0_load_montserrat_font) },
{ be_const_key_weak(splash, 10), be_const_closure(lv_tasmota_splash_closure) },
};
static be_define_const_map(

View File

@ -1,14 +1,15 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libmqtt_map) {
{ be_const_key(unsubscribe, -1), be_const_ctype_func(be_mqtt_unsubscribe) },
{ be_const_key(subscribe, -1), be_const_ctype_func(be_mqtt_subscribe) },
{ be_const_key(publish, 1), be_const_func(be_mqtt_publish) },
{ be_const_key(publish, -1), be_const_func(be_mqtt_publish) },
{ be_const_key(_subscribe, -1), be_const_ctype_func(be_mqtt_subscribe) },
{ be_const_key(unsubscribe, 1), be_const_ctype_func(be_mqtt_unsubscribe) },
{ be_const_key(subscribe, -1), be_const_closure(subscribe_closure) },
};
static be_define_const_map(
m_libmqtt_map,
3
4
);
static be_define_const_module(

View File

@ -1,26 +1,27 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libwebserver_map) {
{ be_const_key(state, 5), be_const_func(w_webserver_state) },
{ be_const_key(member, 9), be_const_func(w_webserver_member) },
{ be_const_key(content_button, -1), be_const_func(w_webserver_content_button) },
{ be_const_key(content_start, -1), be_const_func(w_webserver_content_start) },
{ be_const_key(content_send, -1), be_const_func(w_webserver_content_send) },
{ be_const_key(content_flush, -1), be_const_func(w_webserver_content_flush) },
{ be_const_key(redirect, 8), be_const_func(w_webserver_redirect) },
{ be_const_key(check_privileged_access, 8), be_const_func(w_webserver_check_privileged_access) },
{ be_const_key(content_send, 14), be_const_func(w_webserver_content_send) },
{ be_const_key(content_send_style, -1), be_const_func(w_webserver_content_send_style) },
{ be_const_key(member, -1), be_const_func(w_webserver_member) },
{ be_const_key(content_response, -1), be_const_func(w_webserver_content_response) },
{ be_const_key(arg, -1), be_const_func(w_webserver_arg) },
{ be_const_key(content_stop, -1), be_const_func(w_webserver_content_stop) },
{ be_const_key(arg_name, -1), be_const_func(w_webserver_arg_name) },
{ be_const_key(has_arg, -1), be_const_func(w_webserver_has_arg) },
{ be_const_key(state, -1), be_const_func(w_webserver_state) },
{ be_const_key(content_button, 5), be_const_func(w_webserver_content_button) },
{ be_const_key(has_arg, 12), be_const_func(w_webserver_has_arg) },
{ be_const_key(arg_size, -1), be_const_func(w_webserver_argsize) },
{ be_const_key(check_privileged_access, 11), be_const_func(w_webserver_check_privileged_access) },
{ be_const_key(on, 3), be_const_func(w_webserver_on) },
{ be_const_key(content_flush, -1), be_const_func(w_webserver_content_flush) },
{ be_const_key(arg_name, 10), be_const_func(w_webserver_arg_name) },
{ be_const_key(on, -1), be_const_func(w_webserver_on) },
{ be_const_key(content_start, -1), be_const_func(w_webserver_content_start) },
{ be_const_key(redirect, -1), be_const_func(w_webserver_redirect) },
{ be_const_key(content_stop, 2), be_const_func(w_webserver_content_stop) },
};
static be_define_const_map(
m_libwebserver_map,
15
16
);
static be_define_const_module(

View File

@ -0,0 +1,17 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libzigbee_map) {
{ be_const_key_weak(init, -1), be_const_func(zigbee_init) },
};
static be_define_const_map(
m_libzigbee_map,
1
);
static be_define_const_module(
m_libzigbee,
"zigbee"
);
BE_EXPORT_VARIABLE be_define_const_native_module(zigbee);

View File

@ -214,8 +214,10 @@ static void save_proto_table(bvm *vm, void *fp, bproto *proto)
{
bproto **p = proto->ptab, **end;
save_long(fp, proto->nproto); /* proto count */
for (end = p + proto->nproto; p < end; ++p) {
save_proto(vm, fp, *p);
if (p) {
for (end = p + proto->nproto; p < end; ++p) {
save_proto(vm, fp, *p);
}
}
}
@ -223,9 +225,11 @@ static void save_upvals(void *fp, bproto *proto)
{
bupvaldesc *uv = proto->upvals, *end;
save_byte(fp, proto->nupvals); /* upvals count */
for (end = uv + proto->nupvals; uv < end; ++uv) {
save_byte(fp, uv->instack);
save_byte(fp, uv->idx);
if (uv) {
for (end = uv + proto->nupvals; uv < end; ++uv) {
save_byte(fp, uv->instack);
save_byte(fp, uv->idx);
}
}
}
@ -492,7 +496,7 @@ static void load_constant(bvm *vm, void *fp, bproto *proto, int version)
}
}
static void load_proto_table(bvm *vm, void *fp, bproto *proto, int version)
static void load_proto_table(bvm *vm, void *fp, bproto *proto, int info, int version)
{
int size = (int)load_long(fp); /* proto count */
if (size) {
@ -501,7 +505,7 @@ static void load_proto_table(bvm *vm, void *fp, bproto *proto, int version)
proto->ptab = p;
proto->nproto = size;
while (size--) {
load_proto(vm, fp, p++, -1, version);
load_proto(vm, fp, p++, info, version);
}
}
}
@ -538,7 +542,7 @@ static bbool load_proto(bvm *vm, void *fp, bproto **proto, int info, int version
}
load_bytecode(vm, fp, *proto, info);
load_constant(vm, fp, *proto, version);
load_proto_table(vm, fp, *proto, version);
load_proto_table(vm, fp, *proto, info, version);
load_upvals(vm, fp, *proto);
return btrue;
}

View File

@ -715,6 +715,24 @@ static int m_tostring(bvm *vm)
be_return(vm);
}
static int m_tohex(bvm *vm)
{
buf_impl attr = m_read_attributes(vm, 1);
if (attr.bufptr) { /* pointer looks valid */
int32_t len = attr.len;
size_t hex_len = len * 2 + 1;
char * hex_out = be_pushbuffer(vm, hex_len);
size_t l = tohex(hex_out, hex_len, attr.bufptr, len);
be_pushnstring(vm, hex_out, l); /* make escape string from buffer */
be_remove(vm, -2); /* remove buffer */
} else { /* pointer is null, don't try to dereference it as it would crash */
be_pushstring(vm, "");
}
be_return(vm);
}
/*
* Copy the buffer into a string without any changes
*/
@ -1184,6 +1202,45 @@ static int m_fromb64(bvm *vm)
be_return_nil(vm);
}
/*
* Converts hex to bytes()
*
* `bytes().fromhexx() -> bytes()`
*/
static int m_fromhex(bvm *vm)
{
int argc = be_top(vm);
if (argc >= 2 && be_isstring(vm, 2)) {
int32_t from = 0; // skip x chars
if (argc >= 3 && be_isint(vm, 3)) {
from = be_toint(vm, 3);
}
const char *s = be_tostring(vm, 2);
size_t s_len = strlen(s);
if (from < 0) { from = 0; }
if (from > s_len) { from = s_len; }
int32_t bin_len = (s_len - from) / 2;
buf_impl attr = m_read_attributes(vm, 1);
check_ptr(vm, &attr);
if (attr.fixed && attr.len != bin_len) {
be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE);
}
bytes_resize(vm, &attr, bin_len); /* resize if needed */
if (bin_len > attr.size) { /* avoid overflow */
be_raise(vm, "memory_error", "cannot allocate buffer");
}
attr.len = 0;
buf_add_hex(&attr, s + from, s_len - from);
be_pop(vm, 1); /* remove arg to leave instance */
m_write_attributes(vm, 1, &attr); /* update instance */
be_pop(vm, be_top(vm) - 1); /* leave instance on stack */
be_return(vm);
}
be_raise(vm, "type_error", "operand must be a string");
be_return_nil(vm);
}
/*
* Advanced API
@ -1497,11 +1554,15 @@ void be_load_byteslib(bvm *vm)
{ "fromstring", m_fromstring },
{ "tob64", m_tob64 },
{ "fromb64", m_fromb64 },
{ "fromhex", m_fromhex },
{ "tohex", m_tohex },
{ "add", m_add },
{ "get", m_getu },
{ "geti", m_geti },
{ "set", m_set },
{ "seti", m_set }, // setters for signed and unsigned are identical
{ "getfloat", m_getfloat },
{ "setfloat", m_setfloat },
{ "item", m_item },
{ "setitem", m_setitem },
{ "size", m_size },
@ -1536,6 +1597,8 @@ class be_class_bytes (scope: global, name: bytes) {
fromstring, func(m_fromstring)
tob64, func(m_tob64)
fromb64, func(m_fromb64)
fromhex, func(m_fromhex)
tohex, func(m_tohex)
add, func(m_add)
get, func(m_getu)
geti, func(m_geti)

View File

@ -27,14 +27,33 @@ extern "C" {
.type = (_t), \
.marked = GC_CONST
#define be_define_const_str_weak(_name, _s, _len) \
const bcstring be_const_str_##_name = { \
.next = NULL, \
.type = BE_STRING, \
.marked = GC_CONST, \
.extra = 0, \
.slen = _len, \
.hash = 0, \
.s = _s \
}
#define be_const_key(_str, _next) { \
.v.c = &be_const_str_##_str, \
.type = BE_STRING, \
.next = (uint32_t)(_next) & 0xFFFFFF \
}
/* try to use the predefined string in strtab, but don't create an instance if none is present */
/* the behavior is exactly the same as `be_const_key()` but it not detected by pycoc */
#define be_const_key_weak(_str, _next) { \
.v.c = &be_const_str_##_str, \
.type = BE_STRING, \
.next = (uint32_t)(_next) & 0xFFFFFF \
}
#define be_const_key_literal(_str, _next) { \
.v.c = be_str_literal(_str), \
.v.c = be_str_literal(#_str), \
.type = BE_STRING, \
.next = (uint32_t)(_next) & 0xFFFFFF \
}
@ -236,6 +255,13 @@ const bntvmodule be_native_module(_module) = { \
BE_STRING \
}
/* variant that does not trigger strtab */
#define be_nested_str_weak(_name_) \
{ \
{ .s=((bstring*)&be_const_str_##_name_) }, \
BE_STRING \
}
#define be_nested_str_literal(_name_) \
{ \
{ .s=(be_nested_const_str(_name_, _hash, sizeof(_name_)-1 ))\
@ -246,6 +272,9 @@ const bntvmodule be_native_module(_module) = { \
#define be_str_literal(_str) \
be_nested_const_str(_str, 0, sizeof(_str)-1 )
#define be_str_weak(_str) \
(bstring*) &be_const_str_##_str
#define be_nested_string(_str, _hash, _len) \
{ \
{ .s=(be_nested_const_str(_str, _hash, _len )) \
@ -262,12 +291,31 @@ const bntvmodule be_native_module(_module) = { \
#else
#define be_define_const_str_weak(_name, _s, _len) \
const bcstring be_const_str_##_name = { \
NULL, \
BE_STRING, \
GC_CONST, \
0, \
_len, \
0, \
_s \
}
#define be_const_key(_str, _next) { \
bvaldata(&be_const_str_##_str), \
BE_STRING, \
uint32_t((_next)&0xFFFFFF) \
}
/* try to use the predefined string in strtab, but don't create an instance if none is present */
/* the behavior is exactly the same as `be_const_key()` but it not detected by pycoc */
#define be_const_key_weak(_str, _next) { \
bvaldata(&be_const_str_##_str), \
BE_STRING, \
uint32_t((_next)&0xFFFFFF) \
}
#define be_const_key_int(_i, _next) { \
bvaldata(i), \
BE_INT, \

View File

@ -15,6 +15,7 @@
#include "be_bytecode.h"
#include "be_decoder.h"
#include <stdlib.h>
#include <string.h>
#if !BE_USE_SCRIPT_COMPILER && !BE_USE_BYTECODE_LOADER
#error no compiler or bytecode loader enabled.
@ -337,9 +338,13 @@ void be_stackpush(bvm *vm)
/* check that the stack is able to store `count` items, and increase stack if needed */
BERRY_API void be_stack_require(bvm *vm, int count)
{
#if BE_USE_DEBUG_STACK == 0
if (vm->top + count >= vm->stacktop) {
be_stack_expansion(vm, count);
}
#else
be_stack_expansion(vm, vm->top - vm->stacktop + count); /* force exact resize each time */
#endif
}
/* Scan the entire callstack and adjust all pointer by `offset` */
@ -372,7 +377,16 @@ static void stack_resize(bvm *vm, size_t size)
intptr_t offset;
bvalue *old = vm->stack; /* save original pointer of stack before resize */
size_t os = (vm->stacktop - old) * sizeof(bvalue); /* size of current stack allocated in bytes */
#if BE_USE_DEBUG_STACK == 0
vm->stack = be_realloc(vm, old, os, sizeof(bvalue) * size); /* reallocate with the new size */
#else /* force a reallocation */
size_t ns = sizeof(bvalue) * size;
vm->stack = be_malloc(vm, ns);
size_t transf = (os < ns) ? os : ns; /* min size */
memmove(vm->stack, old, transf); /* copy to new location */
memset(old, 0xFF, os); /* fill the structure with invalid pointers */
be_free(vm, old, os);
#endif
vm->stacktop = vm->stack + size; /* compute new stacktop */
offset = ptr_offset(vm->stack, old); /* compute the address difference between old and ne stack addresses */
/* update callframes */
@ -386,7 +400,7 @@ static void stack_resize(bvm *vm, size_t size)
/* Check if we are above the max allowed stack */
void be_stack_expansion(bvm *vm, int n)
{
size_t size = vm->stacktop - vm->stack;
int size = vm->stacktop - vm->stack; /* with debug enabled, stack increase may be negative */
/* check new stack size */
if (size + n > BE_STACK_TOTAL_MAX) {
/* ensure the stack is enough when generating error messages. */

View File

@ -47,7 +47,7 @@ if (!gc_isconst(o)) { \
#define gc_exmark(o) (((o)->marked >> 4) & 0x0F)
#define gc_setexmark(o, k) ((o)->marked |= (k) << 4)
#define be_isgcobj(o) (var_primetype(o) >= BE_GCOBJECT)
#define be_isgcobj(o) (var_primetype(o) >= BE_GCOBJECT && var_primetype(o) < BE_GCOBJECT_MAX)
#define be_gcnew(v, t, s) be_newgcobj((v), (t), sizeof(s))
#define set_fixed(s) bbool _was_fixed = be_gc_fix_set(vm, cast(bgcobject*, (s)), 1)

View File

@ -168,21 +168,9 @@ static int check_next(blexer *lexer, int c)
return 0;
}
static int char2hex(int c)
{
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'a' && c <= 'f') {
return c - 'a' + 0x0A;
} else if (c >= 'A' && c <= 'F') {
return c - 'A' + 0x0A;
}
return -1;
}
static int check2hex(blexer *lexer, int c)
{
c = char2hex(c);
c = be_char2hex(c);
if (c < 0) {
be_lexerror(lexer, "invalid hexadecimal number");
}
@ -333,7 +321,7 @@ static bint scan_hexadecimal(blexer *lexer)
{
bint res = 0;
int dig, num = 0;
while ((dig = char2hex(lgetc(lexer))) >= 0) {
while ((dig = be_char2hex(lgetc(lexer))) >= 0) {
res = ((bint)res << 4) + dig;
next(lexer);
++num;
@ -396,19 +384,44 @@ static btokentype scan_identifier(blexer *lexer)
return TokenId;
}
/* munch any delimeter and return 1 if any found */
static int skip_delimiter(blexer *lexer) {
int c = lgetc(lexer);
int delimeter_present = 0;
while (1) {
if (c == '\r' || c == '\n') {
skip_newline(lexer);
} else if (c == ' ' || c == '\t' || c == '\f' || c == '\v') {
next(lexer);
} else {
break;
}
c = lgetc(lexer);
delimeter_present = 1;
}
return delimeter_present;
}
static btokentype scan_string(blexer *lexer)
{
int c, end = lgetc(lexer);
next(lexer); /* skip '"' or '\'' */
while ((c = lgetc(lexer)) != EOS && (c != end)) {
save(lexer);
if (c == '\\') {
save(lexer); /* skip '\\.' */
while (1) { /* handle multiple string literals in a row */
int c;
int end = lgetc(lexer); /* string delimiter, either '"' or '\'' */
next(lexer); /* skip '"' or '\'' */
while ((c = lgetc(lexer)) != EOS && (c != end)) {
save(lexer);
if (c == '\\') {
save(lexer); /* skip '\\.' */
}
}
c = next(lexer); /* skip '"' or '\'' */
/* check if there's an additional string literal right after */
skip_delimiter(lexer);
c = lgetc(lexer);
if (c != '"' && c != '\'') { break; }
}
tr_string(lexer);
setstr(lexer, buf_tostr(lexer));
next(lexer); /* skip '"' or '\'' */
return TokenString;
}

View File

@ -21,6 +21,7 @@
#define BE_FUNCTION 6
#define BE_GCOBJECT 16 /* from this type can be gced */
#define BE_GCOBJECT_MAX (3<<5) /* from this type can't be gced */
#define BE_STRING 16
#define BE_CLASS 17
@ -44,7 +45,6 @@
/* values for bproto.varg */
#define BE_VA_VARARG (1 << 0) /* function has variable number of arguments */
#define BE_VA_METHOD (1 << 1) /* function is a method (this is only a hint) */
#define array_count(a) (sizeof(a) / sizeof((a)[0]))
#define bcommon_header \

View File

@ -170,16 +170,13 @@ static void m_solidify_map(bvm *vm, bbool str_literal, bmap * map, const char *c
if (node->key.type == BE_STRING) {
/* convert the string literal to identifier */
const char * key = str(node->key.v.s);
size_t id_len = toidentifier_length(key);
char id_buf[id_len];
toidentifier(id_buf, key);
if (!str_literal) {
size_t id_len = toidentifier_length(key);
char id_buf[id_len];
toidentifier(id_buf, key);
logfmt(" { be_const_key(%s, %i), ", id_buf, key_next);
} else {
size_t id_len = toliteral_length(key);
char id_buf[id_len];
toliteral(id_buf, key);
logfmt(" { be_const_key_literal(\"%s\", %i), ", id_buf, key_next);
logfmt(" { be_const_key_weak(%s, %i), ", id_buf, key_next);
}
m_solidify_bvalue(vm, str_literal, &node->value, class_name, str(node->key.v.s));
} else if (node->key.type == BE_INT) {
@ -249,16 +246,13 @@ static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const
if (len >= 255) {
be_raise(vm, "internal_error", "Strings greater than 255 chars not supported yet");
}
size_t id_len = toidentifier_length(str);
char id_buf[id_len];
toidentifier(id_buf, str);
if (!str_literal) {
size_t id_len = toidentifier_length(str);
char id_buf[id_len];
toidentifier(id_buf, str);
logfmt("be_nested_str(%s)", id_buf);
} else {
size_t id_len = toliteral_length(str);
char id_buf[id_len];
toliteral(id_buf, str);
logfmt("be_nested_str_literal(\"%s\")", id_buf);
logfmt("be_nested_str_weak(%s)", id_buf);
}
}
break;
@ -392,18 +386,14 @@ static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char
}
/* convert the string literal to identifier */
const char * key = str(pr->name);
size_t id_len = toidentifier_length(key);
char id_buf[id_len];
toidentifier(id_buf, key);
if (!str_literal) {
const char * key = str(pr->name);
size_t id_len = toidentifier_length(key);
char id_buf[id_len];
toidentifier(id_buf, key);
logfmt("%*s&be_const_str_%s,\n", indent, "", id_buf);
} else {
const char * key = str(pr->name);
size_t id_len = toliteral_length(key);
char id_buf[id_len];
toliteral(id_buf, key);
logfmt("%*sbe_str_literal(\"%s\"),\n", indent, "", id_buf);
logfmt("%*sbe_str_weak(%s),\n", indent, "", id_buf);
}
// hard-code source as "solidified" for solidified
logfmt("%*s&be_const_str_solidified,\n", indent, "");
@ -507,22 +497,18 @@ static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int buil
logfmt(" NULL,\n");
}
size_t id_len = toidentifier_length(class_name);
char id_buf[id_len];
toidentifier(id_buf, class_name);
if (!str_literal) {
size_t id_len = toidentifier_length(class_name);
char id_buf[id_len];
toidentifier(id_buf, class_name);
logfmt(" &be_const_str_%s,\n", id_buf);
logfmt(" (bstring*) &be_const_str_%s\n", id_buf);
} else {
size_t id_len = toliteral_length(class_name);
char id_buf[id_len];
toliteral(id_buf, class_name);
logfmt(" be_str_literal(\"%s\")\n", id_buf);
logfmt(" be_str_weak(%s)\n", id_buf);
}
logfmt(");\n");
}
static void m_solidify_class(bvm *vm, bbool str_literal, bclass *cl, int builtins)
{
const char * class_name = str(cl->name);

View File

@ -231,29 +231,54 @@ const char* be_pushvfstr(bvm *vm, const char *format, va_list arg)
return concat2(vm);
}
int be_char2hex(int c)
{
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'a' && c <= 'f') {
return c - 'a' + 0x0A;
} else if (c >= 'A' && c <= 'F') {
return c - 'A' + 0x0A;
}
return -1;
}
/*******************************************************************
* the function be_str2int():
* >>-+------------+--+-----+----digits----><
* '-whitespace-' +- + -+
* '- - -'
* >>-+------------+--+--+-----+----digits-------+----------------><
* '-whitespace-' | +- + -+ |
* | '- - -' |
* | |
* +- 0x or 0X ---hex_digits--+
*
*******************************************************************/
BERRY_API bint be_str2int(const char *str, const char **endstr)
{
int c, sign;
bint sum = 0;
skip_space(str);
sign = c = *str++;
if (c == '+' || c == '-') {
c = *str++;
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
/* hex literal */
str += 2; /* skip 0x or 0X */
while ((c = be_char2hex(*str++)) >= 0) {
sum = sum * 16 + c;
}
return sum;
} else {
/* decimal literal */
sign = c = *str++;
if (c == '+' || c == '-') {
c = *str++;
}
while (is_digit(c)) {
sum = sum * 10 + c - '0';
c = *str++;
}
if (endstr) {
*endstr = str - 1;
}
return sign == '-' ? -sum : sum;
}
while (is_digit(c)) {
sum = sum * 10 + c - '0';
c = *str++;
}
if (endstr) {
*endstr = str - 1;
}
return sign == '-' ? -sum : sum;
}
/*******************************************************************

View File

@ -19,6 +19,7 @@ bstring* be_strcat(bvm *vm, bstring *s1, bstring *s2);
int be_strcmp(bstring *s1, bstring *s2);
bstring* be_num2str(bvm *vm, bvalue *v);
void be_val2str(bvm *vm, int index);
int be_char2hex(int c);
size_t be_strlcpy(char *dst, const char *src, size_t size);
const char* be_splitpath(const char *path);
const char* be_splitname(const char *path);

View File

@ -12,6 +12,7 @@
#include "be_map.h"
#include "be_gc.h"
#include "be_class.h"
#include <string.h>
#define global(vm) ((vm)->gbldesc.global)
#define builtin(vm) ((vm)->gbldesc.builtin)
@ -55,7 +56,7 @@ static int global_native_class_find(bvm *vm, bstring *name)
/* class name matches */
int idx = be_global_new(vm, name);
bvalue *v = be_global_var(vm, idx);
var_setclass(v, cl);
var_setclass(v, (void*) cl);
return idx;
}
}

View File

@ -1207,11 +1207,12 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
for (v = vm->reg + argc; v <= end; ++v) {
var_setnil(v);
}
int v_offset = v - vm->stack; /* offset from stack base, stack may be reallocated */
if (proto->varg & BE_VA_VARARG) { /* there are vararg at the last argument, build the list */
/* code below uses mostly low-level calls for performance */
be_stack_require(vm, argc + 2); /* make sure we don't overflow the stack */
bvalue *top_save = vm->top; /* save original stack, we need fresh slots to create the 'list' instance */
vm->top = v; /* move top of stack right after last argument */
be_stack_require(vm, argc + 4); /* make sure we don't overflow the stack */
int top_save_offset = vm->top - vm->stack; /* save original stack, we need fresh slots to create the 'list' instance */
vm->top = vm->stack + v_offset; /* move top of stack right after last argument */
be_newobject(vm, "list"); /* this creates 2 objects on stack: list instance, BE_LIST object */
blist *list = var_toobj(vm->top-1); /* get low-level BE_LIST structure */
v = vm->reg + proto->argc - 1; /* last argument */
@ -1219,7 +1220,7 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
be_list_push(vm, list, v); /* push all varargs into list */
}
*(vm->reg + proto->argc - 1) = *(vm->top-2); /* change the vararg argument to now contain the list instance */
vm->top = top_save; /* restore top of stack pointer */
vm->top = vm->stack + top_save_offset; /* restore top of stack pointer */
}
}

View File

@ -84,6 +84,7 @@ struct bupval {
} u;
int refcnt;
};
struct bvm {
bglobaldesc gbldesc; /* global description */
bvalue *stack; /* stack space */

View File

@ -184,40 +184,9 @@ assert(b[-10..-5] == bytes("66778899AABB"))
assert(b[5..-10] == bytes("5566"))
assert(b[7..-12] == bytes())
#- floats little endian -#
#- float -#
b = bytes("00000000")
b.setfloat(0, 0)
assert(b == bytes("00000000"))
b.setfloat(0, 1)
assert(b == bytes("0000803F"))
b.setfloat(0, -1)
assert(b == bytes("000080BF"))
b.setfloat(0, 3.5)
assert(b == bytes("00006040"))
import math
b.setfloat(0, math.nan)
assert(b == bytes("0000C07F"))
assert(bytes("00000000").getfloat(0) == 0)
assert(bytes("0000803F").getfloat(0) == 1)
assert(bytes("000080BF").getfloat(0) == -1)
assert(bytes("00006040").getfloat(0) == 3.5)
#- floats big endian -#
b = bytes("00000000")
b.setfloat(0, 0, true)
assert(b == bytes("00000000"))
b.setfloat(0, 1, true)
assert(b == bytes("3F800000"))
b.setfloat(0, -1, true)
assert(b == bytes("BF800000"))
b.setfloat(0, 3.5, true)
assert(b == bytes("40600000"))
import math
b.setfloat(0, math.nan, true)
assert(b == bytes("7FC00000"))
assert(bytes("00000000").getfloat(0, true) == 0)
assert(bytes("3F800000").getfloat(0, true) == 1)
assert(bytes("BF800000").getfloat(0, true) == -1)
assert(bytes("40600000").getfloat(0, true) == 3.5)
b.setfloat(0, 0.33)
assert(b == bytes('C3F5A83E'))
b = bytes("0000C03F")
assert(b.getfloat(0) == 1.5)

View File

@ -45,3 +45,16 @@ assert(c2.C1 == C)
c3 = m.C2(m.C())
assert(type(c3.C1) == 'instance')
assert(classname(c3.C1) == 'C')
#- an instance member can be a class and called directly -#
class Test_class
var c
def init()
self.c = map
end
end
c4 = Test_class()
assert(type(c4.c) == 'class')
c5 = c4.c()
assert(type(c5) == 'instance')
assert(classname(c5) == 'map')

View File

@ -0,0 +1,14 @@
#- toint() converts any instance to int -#
class Test_int
def toint()
return 42
end
end
t=Test_int()
assert(int(t) == 42)
#- int can parse hex strings -#
assert(int("0x00") == 0)
assert(int("0X1") == 1)
assert(int("0x000000F") == 15)
assert(int("0x1000") == 0x1000)

View File

@ -26,3 +26,8 @@ assert(introspect.get(a, 'a') == nil)
introspect.set(a, 'a', 3)
assert(a.a == 3)
#- load module dynamically -#
import introspect
m = introspect.module("math") # load module `math`, assign to `m` and don't create a global variable
assert(type(m.pi) == 'real')

View File

@ -3,7 +3,6 @@
"displayName": "Berry Script Language",
"description": "A small embedded script language.",
"version": "0.1.0",
"icon": "berry-icon.png",
"publisher": "skiars",
"engines": {
"vscode": "^1.15.1"

View File

@ -1,4 +1,5 @@
import copy
import json
from hash_map import *
class block:
@ -21,6 +22,7 @@ class block_builder:
def __init__(self, obj, macro):
self.block = block()
self.strtab = []
self.strtab_weak = []
self.block.name = obj.name
if depend(obj, macro):
@ -28,19 +30,25 @@ class block_builder:
self.block.attr = obj.attr
if "name" in obj.attr:
self.strtab.append(obj.attr["name"])
if not self.get_strings_literal(self.block):
self.strtab.append(obj.attr["name"])
else:
self.strtab_weak.append(obj.attr["name"])
for key in obj.data_ordered:
second = obj.data[key]
if second.depend == None or macro.query(second.depend):
self.block.data[key] = second.value
self.strtab.append(key)
if not self.get_strings_literal(self.block):
self.strtab.append(key)
else:
self.strtab_weak.append(key)
self.block.data_ordered.append(key)
def block_tostring(self, block):
ostr = ""
if block.type == "map":
ostr += self.map_tostring(block, block.name)
ostr += self.map_tostring(block, block.name, False, self.get_strings_literal(block))
elif block.type == "class":
ostr += self.class_tostring(block)
elif block.type == "vartab":
@ -54,7 +62,7 @@ class block_builder:
hmap = hash_map(block.data)
map_name = block.name + "_map"
if len(block.data) > 0:
ostr += self.map_tostring(block, map_name, True) + "\n"
ostr += self.map_tostring(block, map_name, True, self.get_strings_literal(block)) + "\n"
ostr += self.scope(block) + " be_define_const_class(\n "
ostr += block.name + ",\n "
@ -63,12 +71,17 @@ class block_builder:
ostr += self.name(block) + "\n);\n"
return ostr
def map_tostring(self, block, name, local):
def map_tostring(self, block, name, local, literal):
hmap = hash_map(block.data)
entlist = hmap.entry_list()
ostr = "static be_define_const_map_slots(" + name + ") {\n"
ostr = ""
ostr += "static be_define_const_map_slots(" + name + ") {\n"
for ent in entlist:
ostr += " { be_const_key(" + ent.key + ", "
if literal:
ostr += " { be_const_key_weak(" + ent.key + ", "
else:
ostr += " { be_const_key(" + ent.key + ", "
ostr += str(ent.next) + "), " + ent.value + " },\n"
ostr += "};\n\n"
@ -92,7 +105,7 @@ class block_builder:
idxblk.data[key] = "int(" + str(index) + ")"
index += 1
ostr += self.map_tostring(idxblk, block.name + "_map", True) + "\n"
ostr += self.map_tostring(idxblk, block.name + "_map", True, False) + "\n"
ostr += "static const bvalue __vlist_array[] = {\n";
for it in varvec:
ostr += " be_const_" + it + ",\n"
@ -108,7 +121,7 @@ class block_builder:
name = "m_lib" + block.name
map_name = name + "_map"
ostr += self.map_tostring(block, map_name, True) + "\n"
ostr += self.map_tostring(block, map_name, True, self.get_strings_literal(block)) + "\n"
ostr += "static be_define_const_module(\n "
ostr += name + ",\n "
ostr += "\"" + block.name + "\"\n);\n"
@ -131,6 +144,13 @@ class block_builder:
else:
return "NULL"
def get_strings_literal(self, block):
if "strings" in block.attr:
a = block.attr["strings"]
return block.attr["strings"] == "weak"
else:
return False
def name(self, block):
if "name" in block.attr:
return block.attr["name"]

View File

@ -21,12 +21,16 @@ class coc_parser:
"""Parse text file"""
self.objects = []
self.strtab = set()
self.strtab_weak = set()
self.text = text
self.parsers = {
"@const_object_info_begin": self.parse_object,
"be_const_str_": self.parse_string,
"be_const_key(": self.parse_string,
"be_nested_str(": self.parse_string,
"be_const_key_weak(": self.parse_string_weak,
"be_nested_str_weak(": self.parse_string_weak,
"be_str_weak(": self.parse_string_weak,
}
while len(self.text) > 0:
@ -119,6 +123,14 @@ class coc_parser:
self.strtab.add(literal)
# print(f"str '{ident}' -> {literal}")
def parse_string_weak(self):
if not self.text[0].isalnum() and self.text[0] != '_': return # do not proceed, maybe false positive in solidify
ident = self.parse_word()
literal = unescape_operator(ident)
if not literal in self.strtab:
self.strtab_weak.add(literal)
# print(f"str '{ident}' -> {literal}")
#################################################################################
# Parse a block of definition like module, class...
#################################################################################

Some files were not shown because too many files have changed in this diff Show More