Merge branch 'development' into pre-release-12.1

This commit is contained in:
Theo Arends 2022-08-11 15:05:51 +02:00
commit 9eb42b41d0
558 changed files with 65121 additions and 37156 deletions

View File

@ -7,7 +7,7 @@
- [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
- [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9
- [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.3
- [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.4.1
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_

View File

@ -77,7 +77,7 @@ jobs:
strategy:
matrix:
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 ]
language: [ AD, 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@v3
with:

View File

@ -76,7 +76,7 @@ jobs:
strategy:
matrix:
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 ]
language: [ AD, 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@v3
with:

View File

@ -80,7 +80,7 @@ jobs:
strategy:
matrix:
variant: [ tasmota ]
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 ]
language: [ AD, 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
- name: Set up Python

View File

@ -7,6 +7,5 @@ image:
vscode:
extensions:
- Atishay-Jain.All-Autocomplete
- CoenraadS.bracket-pair-colorizer
- esbenp.prettier-vscode
- shardulm94.trailing-spaces

172
BUILDS.md
View File

@ -13,8 +13,9 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_UFILESYS | - | - / x | - | - | - | - |
| USE_ARDUINO_OTA | - | - / - | - | - | - | - |
| USE_DOMOTICZ | - | x / x | x | x | x | - |
| USE_HOME_ASSISTANT | - | x / x | x | x | x | - |
| USE_MQTT_TLS | - | - / - | - | - | - | - |
| USE_HOME_ASSISTANT | - | - / - | - | - | - | - |
| USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x |
| USE_MQTT_TLS* | - | - / x | - | - | - | - |
| USE_MQTT_AWS_IOT | - | - / - | - | - | - | - |
| USE_4K_RSA | - | - / - | - | - | - | - |
| USE_TELEGRAM | - | - / - | - | - | - | - |
@ -65,6 +66,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_SM2335 | - | x / - | x | x | - | x |
| USE_BP5758D | - | x / - | x | x | - | x |
| USE_SONOFF_L1 | - | x / - | x | x | - | x |
| USE_ELECTRIQ_MOODL | - | x / - | x | x | - | x |
@ -166,84 +168,88 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_TOF10120 | - | - / - | - | - | - | - |
| USE_BM8563 | - | - / - | - | - | - | - |
| USE_AM2320 | - | - / - | - | - | - | - |
| USE_T67XX | - | - / - | - | - | - | - |
| USE_HM330X | - | - / - | - | - | - | - |
| USE_HDC2010 | - | - / - | - | - | - | - |
| USE_PCF85363 | - | - / - | - | - | - | - |
| USE_DS3502 | - | - / - | - | - | - | - |
| USE_HYT | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_SPI | - | - / - | - | - | - | x |
| USE_RC522 | - | - / - | - | - | - | - |
| USE_MHZ19 | - | - / x | - | x | - | - |
| USE_SENSEAIR | - | - / x | - | x | - | - |
| USE_PMS5003 | - | - / x | - | x | - | - |
| USE_NOVA_SDS | - | - / x | - | x | - | - |
| USE_HPMA | - | - / x | - | x | - | - |
| USE_SERIAL_BRIDGE | - | x / x | x | x | - | x |
| USE_MP3_PLAYER | - | - / x | - | x | - | - |
| USE_AZ7798 | - | - / - | - | - | - | - |
| USE_PN532_HSU | - | - / x | - | x | - | - |
| USE_RDM6300 | - | - / x | - | x | - | - |
| USE_IBEACON | - | - / x | - | x | - | - |
| USE_GPS | - | - / - | - | - | - | - |
| USE_HM10 | - | - / - | - | x | - | - |
| USE_HRXL | - | - / x | - | x | - | - |
| USE_TASMOTA_CLIENT | - | - / - | - | - | - | - |
| USE_OPENTHERM | - | - / - | - | - | - | - |
| USE_MIEL_HVAC | - | - / - | - | - | - | - |
| USE_PROJECTOR_CTRL | - | - / - | - | - | - | - |
| USE_AS608 | - | - / - | - | - | - | - |
| USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge
| | | | | | | |
| USE_NRF24 | - | - / - | - | - | - | - |
| USE_MIBLE | - | - / - | - | - | - | - |
| USE_ZIGBEE | - | - / - | - | - | - | - |
| USE_ZIGBEE_ZNP | - | - / - | - | - | - | - |
| USE_ZIGBEE_EZSP | - | - / - | - | - | - | - | Sonoff ZbBridge
| | | | | | | |
| USE_IR_REMOTE | - | x / - | x | x | x | x |
| USE_IR_RECEIVE | - | x / - | x | x | x | x |
| USE_IR_REMOTE_FULL | - | - / - | - | - | x | - | Enable ALL protocols
| | | | | | | |
| USE_SR04 | - | - / - | - | x | - | - |
| USE_DYP | - | - / - | - | - | - | - |
| USE_TM1638 | - | - / x | - | x | - | - |
| USE_HX711 | - | - / x | - | x | - | - |
| USE_TX2x_WIND_SENSOR | - | - / - | - | - | - | - |
| USE_WINDMETER | - | - / - | - | - | - | - |
| USE_RC_SWITCH | - | - / x | - | x | - | - |
| USE_RF_SENSOR | - | - / x | - | x | - | - | AlectoV2 only
| USE_HRE | - | - / x | - | x | - | - |
| USE_A4988_STEPPER | - | - / - | - | - | - | - |
| USE_NEOPOOL | - | - / - | - | - | - | - |
| USE_FLOWRATEMETER | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_DISPLAY | - | - / - | - | - | - | x |
| USE_DISPLAY_LCD | - | - / - | - | - | - | x |
| USE_DISPLAY_SSD1306 | - | - / - | - | - | - | x |
| USE_DISPLAY_MATRIX | - | - / - | - | - | - | x |
| USE_DISPLAY_SH1106 | - | - / - | - | - | - | x |
| USE_DISPLAY_ILI9341 | - | - / - | - | - | - | x |
| USE_DISPLAY_EPAPER_29 | - | - / - | - | - | - | x |
| USE_DISPLAY_EPAPER_42 | - | - / - | - | - | - | x |
| USE_DISPLAY_SSD1351 | - | - / - | - | - | - | x |
| USE_DISPLAY_RA8876 | - | - / - | - | - | - | x |
| USE_DISPLAY_ST7789 | - | - / - | - | - | - | x |
| USE_DISPLAY_TM1637 | - | - / - | - | - | - | x |
| | | | | | | |
| USE_FT5206 | - | - / - | - | - | - | - |
| USE_FTC532 | - | - / - | - | - | - | - |
| USE_BS814A2 | - | - / - | - | - | - | - |
| | | | | | | |
| ESP32 Feature | l | t | k | s | i | d | Remarks
| USE_HALLEFFECT | | / x | | | | |
| USE_MI_ESP32 | | / x | | | | | See SetOption115
| USE_IBEACON_ESP32 | | / - | | | | |
| USE_WEBCAM | | / - | | | | |
| USE_ETHERNET | | / x | | | | |
| USE_I2S_AUDIO | | / - | | | | |
| USE_TTGO_WATCH | | / - | | | | |
| USE_SONOFF_SPM | | / x | | | | |
| USE_T67XX | - | - / - | - | - | - | - |
| USE_HM330X | - | - / - | - | - | - | - |
| USE_HDC2010 | - | - / - | - | - | - | - |
| USE_PCF85363 | - | - / - | - | - | - | - |
| USE_DS3502 | - | - / - | - | - | - | - |
| USE_HYT | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_SPI | - | - / - | - | - | - | x |
| USE_RC522 | - | - / - | - | - | - | - |
| USE_MHZ19 | - | - / x | - | x | - | - |
| USE_SENSEAIR | - | - / x | - | x | - | - |
| USE_PMS5003 | - | - / x | - | x | - | - |
| USE_NOVA_SDS | - | - / x | - | x | - | - |
| USE_HPMA | - | - / x | - | x | - | - |
| USE_SERIAL_BRIDGE | - | x / x | x | x | - | x |
| USE_MODBUS_BRIDGE | - | - / x | - | - | - | - |
| USE_MP3_PLAYER | - | - / x | - | x | - | - |
| USE_AZ7798 | - | - / - | - | - | - | - |
| USE_PN532_HSU | - | - / x | - | x | - | - |
| USE_RDM6300 | - | - / x | - | x | - | - |
| USE_IBEACON | - | - / x | - | x | - | - |
| USE_GPS | - | - / - | - | - | - | - |
| USE_HM10 | - | - / - | - | x | - | - |
| USE_HRXL | - | - / x | - | x | - | - |
| USE_TASMOTA_CLIENT | - | - / - | - | - | - | - |
| USE_OPENTHERM | - | - / - | - | - | - | - |
| USE_MIEL_HVAC | - | - / - | - | - | - | - |
| USE_PROJECTOR_CTRL | - | - / - | - | - | - | - |
| USE_AS608 | - | - / - | - | - | - | - |
| USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge
| | | | | | | |
| USE_NRF24 | - | - / - | - | - | - | - |
| USE_MIBLE | - | - / - | - | - | - | - |
| USE_ZIGBEE | - | - / - | - | - | - | - |
| USE_ZIGBEE_ZNP | - | - / - | - | - | - | - |
| USE_ZIGBEE_EZSP | - | - / - | - | - | - | - | Sonoff ZbBridge
| | | | | | | |
| USE_IR_REMOTE | - | x / - | x | x | x | x |
| USE_IR_RECEIVE | - | x / - | x | x | x | x |
| USE_IR_REMOTE_FULL | - | - / - | - | - | x | - | Enable ALL protocols
| | | | | | | |
| USE_SR04 | - | - / - | - | x | - | - |
| USE_DYP | - | - / - | - | - | - | - |
| USE_TM1638 | - | - / x | - | x | - | - |
| USE_HX711 | - | - / x | - | x | - | - |
| USE_TX2x_WIND_SENSOR | - | - / - | - | - | - | - |
| USE_WINDMETER | - | - / - | - | - | - | - |
| USE_RC_SWITCH | - | - / x | - | x | - | - |
| USE_RF_SENSOR | - | - / x | - | x | - | - | AlectoV2 only
| USE_HRE | - | - / x | - | x | - | - |
| USE_A4988_STEPPER | - | - / - | - | - | - | - |
| USE_NEOPOOL | - | - / - | - | - | - | - |
| USE_FLOWRATEMETER | - | - / - | - | - | - | - |
| | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_DISPLAY | - | - / - | - | - | - | x |
| USE_DISPLAY_LCD | - | - / - | - | - | - | x |
| USE_DISPLAY_SSD1306 | - | - / - | - | - | - | x |
| USE_DISPLAY_MATRIX | - | - / - | - | - | - | x |
| USE_DISPLAY_SH1106 | - | - / - | - | - | - | x |
| USE_DISPLAY_ILI9341 | - | - / - | - | - | - | x |
| USE_DISPLAY_EPAPER_29 | - | - / - | - | - | - | x |
| USE_DISPLAY_EPAPER_42 | - | - / - | - | - | - | x |
| USE_DISPLAY_SSD1351 | - | - / - | - | - | - | x |
| USE_DISPLAY_RA8876 | - | - / - | - | - | - | x |
| USE_DISPLAY_ST7789 | - | - / - | - | - | - | x |
| USE_DISPLAY_TM1637 | - | - / - | - | - | - | x |
| USE_DISPLAY_TM1621_SONOFF | - | - / x | - | - | - | - |
| | | | | | | |
| USE_FT5206 | - | - / - | - | - | - | - |
| USE_FTC532 | - | - / - | - | - | - | - |
| USE_BS814A2 | - | - / - | - | - | - | - |
| | | | | | | |
| ESP32 Feature | l | t | k | s | i | d | Remarks
| USE_HALLEFFECT | | / x | | | | |
| USE_MI_ESP32 | | / x | | | | | See SetOption115
| USE_IBEACON_ESP32 | | / - | | | | |
| USE_WEBCAM | | / - | | | | |
| USE_ETHERNET | | / x | | | | |
| USE_I2S_AUDIO | | / - | | | | |
| USE_TTGO_WATCH | | / - | | | | |
| USE_SONOFF_SPM | | / x | | | | |
* USE_MQTT_TLS is enabled by default in every ESP32 variants

View File

@ -2,6 +2,55 @@
All notable changes to this project will be documented in this file.
## [Released]
## [12.1.0] 20220817
- Release Patricia
## [12.0.2.4] 20220817
### Added
- Command ``SetOption45 1..250`` to change default bistable latching relay pulse length of 40 milliseconds
- Support for Modbus bridge adding commands ``ModbusSend``, ``ModbusBaudrate`` and ``ModbusSerialConfig`` (#16013)
- Support for multiple ``IRsend`` GPIOs (#16138)
- Zigbee added recording of when the battery was last reported (#16146)
- Zigbee add Battery auto-probe (can be disabled with ``SetOption143 1``) (#16148)
- Zigbee include "BatteryPercentage" in all messages
- Commands ``WifiScan`` and ``WifiTest`` (#16141)
- Support for Catalan language translations by Albert Gonzalez (#16145)
- Zigbee ``SetOption144 1`` includes a timestamp in `ZbReceived` messages
### Changed
- ESP32 LVGL library from v8.2.0 to v8.3.0 (#16019)
- Tasmota ESP32 Arduino core from v2.0.4 to v2.0.4.1 (#16110)
### Fixed
- Restore EnergyToday after using command ``restart 2`` and power cycle (#16118)
- Fixed IR crash on ESP32 (#16173)
- Zigbee fix Tuya for writing attributes
## [12.0.2.3] 20220716
### Added
- Support for Sonoff POWR3xxD and THR3xxD (#15856)
- Support for bistable (latching) relays mixed with monostable relays using GPIO Relay_b or Relay_bi as used by Sonoff POWR320D and THR320D
- ESP32 Support for Ultra Low Power (ULP) coprocessor via Berry by Christian Staars (#15916)
- Command ``Sleep2 !`` to cancel pending one-shot speed setting (#15954)
### Changed
- Driver DHT v6 consolidation for both ESP8266 and ESP32 to support SI7021, THS01 and MS01 on ESP32 (#15856)
- Tasmota ESP32 Arduino core from v2.0.3 to v2.0.4 (#15940)
## [12.0.2.2] 20220701
### Added
- Command ``GlobalTemp2 1..250`` to select Global Temperature source indexed from teleperiod occurance data (#15834)
- Command ``GlobalHum2 1..250`` to select Global Humidity source indexed from teleperiod occurance data (#15834)
- Command ``GlobalPress2 1..250`` to select Global Pressure source indexed from teleperiod occurance data (#15834)
## [12.0.2.1] 20220622
### Added
- Support for 5-channel light dimmer driver SM2335 used in SwitchBot Color Bulbs (#15839)
### Fixed
- ESP32 SendMail not working over ethernet (#15794)
## [12.0.2] 20220620
- Release Paul
@ -10,13 +59,7 @@ All notable changes to this project will be documented in this file.
- Command ``DnsTimeout 100..20000`` to change default DNS timeout from 1000 msec blocking if no DNS server found
### Fixed
- MQTT rc -4 connections regression from v12.0.0 (#15809)
## [12.0.1] 20220617
- Release Paul
### Fixed
- Resolving NTP and/or MQTT server names regression from v12.0.0 (#15816)
- MQTT rc -4 on connections regression from v12.0.0 (#15809)
## [12.0.1] 20220617
- Release Paul

View File

@ -60,7 +60,7 @@ In addition to @arendst the following code is mainly owned by:
| xdrv_49_pid | Colin Law, Thomas Herrmann
| xdrv_50_filesystem | @gemu, @barbudor
| xdrv_51_bs814a2 | Peter Franck
| xdrv_52_berry | @s-hadinger
| xdrv_52_berry | @s-hadinger, @staars (ULP)
| xdrv_53_projector_ctrl | Jan Bubík
| xdrv_54_lvgl | @s-hadinger
| xdrv_55_touch | @gemu, @s-hadinger

View File

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

View File

@ -38,7 +38,7 @@ Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/
See [CHANGELOG.md](CHANGELOG.md) for detailed change information.
Unless your Tasmota powered device exhibits a problem or you need to make use of a feature that is not available in the Tasmota version currently installed on your device, leave your device alone - it works so don't make unnecessary changes! If the release version (i.e., the master branch) exhibits unexpected behaviour for your device and configuration, you should upgrade to the latest development version instead to see if your problem is resolved as some bugs in previous releases or development builds may already have been resolved.
Unless your Tasmota powered device exhibits a problem or lacks a feature that you need, leave your device alone - it works so dont make unnecessary changes! If the release version (i.e., the master branch) exhibits unexpected behaviour for your device and configuration, you should upgrade to the latest development version instead to see if your problem is resolved as some bugs in previous releases or development builds may already have been resolved.
Every commit made to the development branch, which is compiling successfuly, will post new binary files at http://ota.tasmota.com/tasmota/ (this web address can be used for OTA updates too). It is important to note that these binaries are based on the current development codebase. These commits are tested as much as is possible and are typically quite stable. However, it is infeasible to test on the hundreds of different types of devices with all the available configuration options permitted.
@ -168,4 +168,4 @@ People helping to keep the show on the road:
## License
This program is licensed under GPL-3.0
This program is licensed under GPL-3.0

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.3**.
This release will be supported from ESP32/Arduino library Core version **2.0.4.1**.
Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.3 have been removed.
Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.4.1 have been removed.
## Support of TLS
@ -77,7 +77,7 @@ Historical binaries can be downloaded from
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
### 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**.
The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.4.1**.
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota32xy.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3/S2/S3 and 4M+ flash.
@ -107,46 +107,35 @@ 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 v12.0.2 Paul
## Changelog v12.1.0 Patricia
### Added
- 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 ``DnsTimeout 100..20000`` to change default DNS timeout from 1000 msec blocking if no DNS server found
- 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
- Command ``SetOption45 1..250`` to change default bistable latching relay pulse length of 40 milliseconds
- Command ``SetOption144 1`` includes a timestamp in zigbee `ZbReceived` messages
- Command ``GlobalTemp2 1..250`` to select Global Temperature source indexed from teleperiod occurance data [#15834](https://github.com/arendst/Tasmota/issues/15834)
- Command ``GlobalHum2 1..250`` to select Global Humidity source indexed from teleperiod occurance data [#15834](https://github.com/arendst/Tasmota/issues/15834)
- Command ``GlobalPress2 1..250`` to select Global Pressure source indexed from teleperiod occurance data [#15834](https://github.com/arendst/Tasmota/issues/15834)
- Command ``Sleep2 !`` to cancel pending one-shot speed setting [#15954](https://github.com/arendst/Tasmota/issues/15954)
- Commands ``WifiScan`` and ``WifiTest`` [#16141](https://github.com/arendst/Tasmota/issues/16141)
- Support for 5-channel light dimmer driver SM2335 used in SwitchBot Color Bulbs [#15839](https://github.com/arendst/Tasmota/issues/15839)
- Support for Sonoff POWR3xxD and THR3xxD [#15856](https://github.com/arendst/Tasmota/issues/15856)
- Support for bistable (latching) relays mixed with monostable relays using GPIO Relay_b or Relay_bi as used by Sonoff POWR320D and THR320D
- Support for Modbus bridge adding commands ``ModbusSend``, ``ModbusBaudrate`` and ``ModbusSerialConfig`` [#16013](https://github.com/arendst/Tasmota/issues/16013)
- Support for multiple ``IRsend`` GPIOs [#16138](https://github.com/arendst/Tasmota/issues/16138)
- Support for Catalan language translations by Albert Gonzalez [#16145](https://github.com/arendst/Tasmota/issues/16145)
- Zigbee added recording of when the battery was last reported [#16146](https://github.com/arendst/Tasmota/issues/16146)
- Zigbee add Battery auto-probe (can be disabled with ``SetOption143 1``) [#16148](https://github.com/arendst/Tasmota/issues/16148)
- ESP32 Support for Ultra Low Power (ULP) coprocessor via Berry by Christian Staars [#15916](https://github.com/arendst/Tasmota/issues/15916)
### Breaking Changed
### Changed
- 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
- ESP32 Arduino core from v2.0.3 to v2.0.4.1 [#15940](https://github.com/arendst/Tasmota/issues/15940)
- ESP32 LVGL library from v8.2.0 to v8.3.0 [#16019](https://github.com/arendst/Tasmota/issues/16019)
- Driver DHT v6 consolidation for both ESP8266 and ESP32 to support SI7021, THS01 and MS01 on ESP32 [#15856](https://github.com/arendst/Tasmota/issues/15856)
### Fixed
- 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)
- SHT1X driver hangs and wrong values on ESP32 [#15790](https://github.com/arendst/Tasmota/issues/15790)
- Resolving NTP and/or MQTT server names regression from v12.0.0 [#15816](https://github.com/arendst/Tasmota/issues/15816)
- MQTT rc -4 connection regression from v12.0.0 [#15809](https://github.com/arendst/Tasmota/issues/15809)
- ESP32 Arduino Core WiFi timeout is changed from msec to seconds
- Restore EnergyToday after using command ``restart 2`` and power cycle [#16118](https://github.com/arendst/Tasmota/issues/16118)
- ESP32 SendMail not working over ethernet [#15794](https://github.com/arendst/Tasmota/issues/15794)
### Removed
- Arduino IDE support

View File

@ -2,7 +2,7 @@
# 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)
Find below the available templates as of August 2022. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)
## Addressable LED
```
@ -43,6 +43,7 @@ Syska 8W {"NAME":"Syska SMW-8W-C","GPIO":[0,0,0,0,420,419,0,
## CCT
```
AICase 800lm {"NAME":"AICase Smart L","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
AiYaTo 12W {"NAME":"AiYaTo CW","GPIO":[0,0,0,0,416,0,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
Ajax Online 380lm {"NAME":"AjaxOnline","GPIO":[32,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":38}
Ajax Online 7W Vintage {"NAME":"AjaxOnline-7W","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
Anoopsyche 9W 800lm {"NAME":"Anoop-CW-WW","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
@ -192,6 +193,7 @@ Zemismart Door Window {"NAME":"Zemismart","GPIO":[1,2272,1,2304,1,1,0,0,1
## Curtain Module
```
Athom {"NAME":"Athom Curtain Module","GPIO":[0,0,0,160,161,32,0,0,224,576,225,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO80 1 | ShutterMode 1 | SwitchDebounce 300 | ButtonDebounce 300"}
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}
@ -222,7 +224,7 @@ Teepao {"NAME":"Teepao","GPIO":[576,322,226,33,225,34,0,0,
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"}
WF-CS02 {"NAME":"WF-CS02 Tuya","GPIO":[544,0,289,162,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18}
WuyunElek {"NAME":"MILOS Jalousie","GPIO":[1,0,224,225,1,320,0,0,32,33,34,226,0,0],"FLAG":0,"BASE":18}
Zemismart {"NAME":"Zemismart","GPIO":[544,0,0,162,290,161,0,0,160,224,226,225,0,0],"FLAG":0,"BASE":18}
Zemismart {"NAME":"Zemismart","GPIO":[544,0,289,162,290,161,0,0,160,224,226,225,288,0],"FLAG":0,"BASE":18}
Zemismart Backlit {"NAME":"WF-CS01","GPIO":[544,227,289,34,226,161,0,0,160,224,290,225,288,0],"FLAG":0,"BASE":18}
```
@ -236,7 +238,8 @@ Sinotimer {"NAME":"Sinotimer TM60","GPIO":[0,0,0,0,0,288,0,0,
SMTONOFF 63A {"NAME":"SMTONOFF","GPIO":[32,0,0,3104,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":43}
Sohan DIN Circuit Breaker 1P 50A {"NAME":"RDCBC-1P","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff Smart Stackable Power Meter {"NAME":"Sonoff SPM","GPIO":[0,0,0,0,3200,5536,0,0,672,704,736,0,3232,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,544,0,0,32,0,0,0,0],"FLAG":0,"BASE":1}
TOMZN 2P 63/80A Circuit Breaker {"NAME":"TOMZN","GPIO":[0,0,0,0,0,0,0,0,64,224,0,0,288,0],"FLAG":0,"BASE":18}
TOMZN 2P 63A/80A Circuit Breaker {"NAME":"TOWBC-2P-T","GPIO":[0,0,0,0,0,0,0,0,64,224,0,0,288,0],"FLAG":0,"BASE":18}
TOMZN 4P 80A Circuit Breaker {"NAME":"TOWBC-4P-T","GPIO":[288,0,0,0,0,0,0,0,32,224,0,0,0,0],"FLAG":0,"BASE":18}
TOMZN 4P 80A Circuit Breaker {"NAME":"TOMZN4","GPIO":[32,0,0,0,0,0,0,0,224,288,0,0,0,0],"FLAG":0,"BASE":18}
```
@ -254,6 +257,7 @@ Adafruit HUZZAH32 ESP32 Feather {"NAME":"HUZZAH32","GPIO":[0,0,0,0,4709,0,1,1,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}
Coiaca Tasmota {"NAME":"AWR01t","GPIO":[576,1,1,128,0,0,0,0,0,0,0,0,0,0],"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}
@ -355,6 +359,7 @@ Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","GPIO":[0,0,0,0,4
TCP Smart 806lm Warm White {"NAME":"TCP Smart Clas","GPIO":[0,0,0,0,0,0,0,0,0,416,0,0,0,0],"FLAG":0,"BASE":1}
TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,448,0,0,0],"FLAG":0,"BASE":18}
TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,448,0,0,0],"FLAG":0,"BASE":18}
WiZ 8W 2700K {"NAME":"WiZ A60","GPIO":[0,0,416,0,0,0,0,0,0,0,0,0,0,0,0,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}
Xiaomi Philips MUE4088RT {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,0,0,0,416,0,0],"FLAG":0,"BASE":18}
```
@ -386,7 +391,7 @@ Tessan MJ-SD02 {"NAME":"MJ-SD02","GPIO":[34,33,0,323,576,322,0,0,3
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}
TreatLife 400W Single Pole {"NAME":"DS02S Dimmer","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
Treatlife Dual Outdoor Dimmer {"NAME":"DP12","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"SO97 1 | TuyaMCU 11,1 | TuyaMCU 12,7 | TuyaMCU 21,2 | TuyaMCU 22,8 | SO20 1 | SO54 1"}
Treatlife Dual Outdoor {"NAME":"DP12","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"SO97 1 | TuyaMCU 11,1 | TuyaMCU 12,7 | TuyaMCU 21,2 | TuyaMCU 22,8 | SO20 1 | SO54 1"}
TreatLife Light and Fan {"NAME":"DS03 Fan/Light","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
Virage Labs VirageDimmer {"NAME":"VirageDimmer","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
WF-DS01 {"NAME":"Dimmer WF-DS01","GPIO":[1,1,1,1,1,1,0,0,1,1,290,1,1,0],"FLAG":0,"BASE":54}
@ -413,7 +418,7 @@ Sonoff D1 {"NAME":"Sonoff D1","GPIO":[1,3200,0,3232,0,0,0,0,0
## Display
```
Heltec WiFi Kit 32 {"NAME":"WiFi Kit 32","GPIO":[1,1,1,1,640,1,1,1,1,1,1,608,3840,1,1,1,0,1,1,1,0,224,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
Heltec WiFi Kit 8 {"NAME":"HTIT-W8266","GPIO":[1,1,1,1,640,608,0,0,1,1,1,1,1024,1],"FLAG":0,"BASE":18}
Heltec WiFi Kit 8 {"NAME":"WifiKit8","GPIO":[1,1,1,1,640,608,1,1,1,1,1,1,1024,1],"FLAG":0,"BASE":18}
LilyGO T5 4.7 inch E-paper {"NAME":"LilyGO T5-4.7","GPIO":[0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,7616,0,0,0,0,0,0,0,0,0,0,33,34,4704,0,0,32],"FLAG":0,"BASE":1}
LilyGo TTGO ESP32 {"NAME":"TTGO T-Journal ESP32 Camera","GPIO":[4928,1,1,1,1,5091,1,1,1,608,640,4960,1,5088,5093,5095,0,5184,5120,5056,0,5024,5152,4992,0,0,0,0,1,1,5090,5089,5094,0,0,5092],"FLAG":0,"BASE":1}
LilyGO TTGO ESP8266 0.91 inch OLED SSD1306 {"NAME":"TTGO-0.91","GPIO":[1,1,640,1,1024,0,0,0,1,1,608,1,0,1],"FLAG":0,"BASE":18}
@ -502,6 +507,7 @@ BrilliantSmart Light and {"NAME":"Brilliant Fan","GPIO":[0,2272,0,2304,0,0,0
Qiachip 110V/220V Light and {"NAME":"Qiachip FLC","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 12,9 | TuyaMCU 81,7"}
Sonoff iFan02 Light and Ceiling {"NAME":"Sonoff iFan02","GPIO":[32,1,0,1,226,225,33,34,224,320,35,227,0,0],"FLAG":0,"BASE":44}
Sonoff iFan03 220V Light and Ceiling {"NAME":"SonoffiFan03","GPIO":[32,3200,0,3232,0,0,256,512,226,320,225,227,0,0],"FLAG":0,"BASE":71}
Sonoff iFan04-H 220V Light and Ceiling {"NAME":"iFan04-H","GPIO":[32,3200,0,3232,0,0,256,512,226,320,225,227,0,0],"FLAG":0,"BASE":71}
Sonoff iFan04-L 110V Light and Ceiling {"NAME":"iFan04-L","GPIO":[32,3200,0,3232,0,0,256,512,226,320,225,227,0,0],"FLAG":0,"BASE":71}
```
@ -544,7 +550,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}
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,"CMND":"Module 0"}
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}
@ -563,6 +569,7 @@ Nedis Universal Remote Control {"NAME":"Nedis IR Controller","GPIO":[1,1,1,1,32
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}
Orvibo Magic Cube {"NAME":"Orvibo CT10W","GPIO":[0,0,0,0,32,1088,0,0,288,0,1056,289,0,0],"FLAG":0,"BASE":18}
Phlipton Universal Remote {"NAME":"Phliptron IR","GPIO":[1,3200,1,3232,576,1088,0,0,320,32,1056,0,0,0],"FLAG":0,"BASE":62}
Remote Control {"NAME":"DC-QRA2","GPIO":[0,0,0,0,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
RM mini {"NAME":"RM mini","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62}
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}
@ -577,7 +584,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.0","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,"CMND":"Module 0"}
```
## Illuminance Sensor
@ -607,6 +614,7 @@ Athom RGB {"NAME":"LS5050C-TAS","GPIO":[32,0,0,0,417,0,0,0,41
Bakeey RGB {"NAME":"Bakeey Strip Controller","GPIO":[32,0,0,0,416,420,0,0,418,0,417,419,0,0],"FLAG":0,"BASE":18}
CCT 12-24V {"NAME":"WS02","GPIO":[0,0,0,0,0,0,0,0,0,417,416,0,0,0],"FLAG":0,"BASE":18}
CIN-03 96W RGB {"NAME":"CIN03-03 Strip","GPIO":[0,0,0,0,417,0,0,0,416,0,418,0,0,0],"FLAG":0,"BASE":18}
CIN04 240W {"NAME":"CIN04-03 Strip","GPIO":[0,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
DD001-MINI(G)-IR-V03 {"NAME":"WIFI-RGB","GPIO":[32,0,0,0,0,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":40}
DD001-MINI(G)-IR-V08 {"NAME":"WIFI-RGB","GPIO":[0,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
Electrodragon ESP LED Strip Board, Mosfet Drive {"NAME":"LEDBoard RGBW","GPIO":[0,0,0,0,0,0,0,0,418,417,419,416,288,0],"FLAG":0,"BASE":18}
@ -711,7 +719,7 @@ Arlec Smart 15W Security Floodlight {"NAME":"ArlecFlood","GPIO":[0,0,0,0,0,0,0,
Arlec Smart 20W Movement Activated Security {"NAME":"Arlec MAL300HA","GPIO":[0,0,0,0,224,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Arlec Smart 40W 4000lm LED Batten {"NAME":"Arlec Batten","GPIO":[0,0,0,0,0,416,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Arlec Smart Portable Floodlight 10.5W {"NAME":"Arlec GLD301HA","GPIO":[0,0,0,0,0,416,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
Arlec Smart Security Light {"NAME":"Arlec MAL315HA","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
Arlec Smart Security {"NAME":"Arlec MAL315HA","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
Arlec Smart Up & Down LED Wall {"NAME":"Arlec Up Down CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
BAZZ 4 in. RGB Recessed Fixture {"NAME":"SLMR4RGBWWFW","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18}
BAZZ 6 in. CCT Recessed Fixture {"NAME":"SLDSK6TNWWF","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
@ -779,7 +787,7 @@ PCI-e Desktop PC Remote Control {"NAME":"PC-Switch-01","GPIO":[32,0,0,0,0,0,0,0
Proscenic T21 Air Fryer {"NAME":"Proscenic T21","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
RainPoint Indoor Water Pump {"NAME":"RainPoint","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 81,107|TuyaMCU 12,109|TuyaMCU 11,1|TuyaMCU 82,104"}
Sinilink PCIe Computer Remote {"NAME":"XY-WPCE","GPIO":[1,1,320,1,32,224,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO114 1 | SwitchMode1 2"}
Sinilink USB Computer Remote {"NAME":"XY-WPCL","GPIO":[1,1,320,1,32,224,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO114 1 | SwitchMode1 2"}
Sinilink USB Computer Remote {"NAME":"XY-WPCL","GPIO":[0,0,320,0,0,224,0,32,160,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO114 1 | Pulsetime 10 | SwitchMode1 2"}
Xystec USB3.0 4 Port Hub {"NAME":"Xystec USB Hub","GPIO":[0,0,0,0,224,0,0,0,226,227,225,0,0,0],"FLAG":0,"BASE":18}
```
@ -796,6 +804,7 @@ ESP-M4 {"NAME":"ESP-M4","GPIO":[1,1,0,1,1,1,0,0,1,1,1,1,1,
ESP8266 5V UART Communication {"NAME":"ESP-WROOM-5V2L","GPIO":[0,1,0,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
LC Technology PSF-B04 Ewelink 4 Channel Switch {"NAME":"LC-EWL-B04-MB","GPIO":[1,1,1,1,1,1,0,0,1,288,1,1,0,0],"FLAG":0,"BASE":18}
M5Stack M5Stamp Pico {"NAME":"M5Stamp Pico","GPIO":[1,1,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1,0,1376,0,0,0,0,1,1,0,0,1,0,0,32],"FLAG":0,"BASE":1}
Moes 10A {"NAME":"Moes MS-101","GPIO":[0,0,0,0,0,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
MTools 16 Channel ESP32 Relay Driver 5V DC {"NAME":"16ch Board","GPIO":[1,1,237,1,232,1,1,1,228,231,1,1,233,230,234,235,0,238,239,236,0,224,227,226,0,0,0,0,229,225,1,1,1,0,0,1],"FLAG":0,"BASE":1}
Shelly Universal Input/Output {"NAME":"Shelly Uni","GPIO":[320,0,0,0,225,1216,0,0,192,193,0,224,0,4864],"FLAG":0,"BASE":18}
Sinilink MODBUS Interface {"NAME":"XY-WFPOW","GPIO":[0,1,0,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
@ -841,6 +850,8 @@ Brennenstuhl WA 3000 {"NAME":"WA 3000 XS02","GPIO":[0,0,0,0,224,32,0,0,5
C119 {"NAME":"Subosi C119","GPIO":[0,0,0,0,225,320,0,0,224,544,32,0,321,0],"FLAG":0,"BASE":18}
C137 IP55 {"NAME":"C137 Outdoor","GPIO":[0,32,0,320,2720,2656,0,0,224,2624,225,0,0,1],"FLAG":0,"BASE":18}
C168 IP64 {"NAME":"C188","GPIO":[320,0,321,0,33,0,0,0,224,32,544,225,0,0],"FLAG":0,"BASE":18}
Coolseer {"NAME":"Coolseer Plug (SK01WE)","GPIO":[0,3200,0,7520,0,32,0,0,0,544,224,0,0,0],"FLAG":0,"BASE":18}
Dewenwils Heavy Duty 40A {"NAME":"Dewenwils HOWT01A","GPIO":[0,0,544,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
ECF-SOP03 {"NAME":"Outdoor3Outlet","GPIO":[0,0,0,226,320,0,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18}
Ecoolbuy 4 Socket IP44 {"NAME":"ECCOLBUY 4","GPIO":[0,0,0,0,225,226,0,0,224,321,32,0,227,0],"FLAG":0,"BASE":18}
Edimax 2AC {"NAME":"EDI SP-1122WTO","GPIO":[0,0,0,0,225,576,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18}
@ -949,6 +960,7 @@ Arlec Smart 2.1A USB Charger {"NAME":"Arlec Single","GPIO":[0,0,0,0,321,0,0,0,2
Arlec Smart PC189HA {"NAME":"Arlec Single","GPIO":[0,0,0,0,321,0,0,0,224,0,64,0,0,0],"FLAG":0,"BASE":18}
Arlec Socket With USB {"NAME":"PC192HA","GPIO":[0,0,0,32,0,0,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18}
Arlec Twin PC288HA {"NAME":"Arlec Twin","GPIO":[0,32,0,225,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
Arlec Twin Socket with Energy Meter {"NAME":"Arlec PC287HA","GPIO":[0,32,0,320,2624,2656,0,0,224,2720,225,0,0,0],"FLAG":0,"BASE":18}
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}
@ -1101,6 +1113,7 @@ Febite {"NAME":"Febite","GPIO":[320,0,0,0,0,2720,0,0,224,3
Feit Electric PLUG/WIFI {"NAME":"Feit Wifi Plug","GPIO":[0,0,0,320,0,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18}
FK-PW901U {"NAME":"FK-PW901U","GPIO":[320,1,1,1,1,226,0,0,224,32,227,225,1,0],"FLAG":0,"BASE":18}
FLHS-ZN04 {"NAME":"FLHS-ZN04","GPIO":[321,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45}
Floureon {"NAME":"FLOUREON","GPIO":[0,0,0,0,320,0,1,1,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Fontastic 16A {"NAME":"P22-2036563-DZB117435","GPIO":[0,0,0,0,288,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Fontastic SH01 {"NAME":"Fontastic","GPIO":[1,0,1,0,320,0,0,0,224,32,0,0,0,4704],"FLAG":0,"BASE":18}
Foreet {"NAME":"Foreet_120V","GPIO":[0,0,0,0,224,32,0,0,289,288,0,0,0,0],"FLAG":0,"BASE":18}
@ -1156,6 +1169,7 @@ HaoDeng {"NAME":"HaoDeng","GPIO":[0,0,0,0,224,32,0,0,320,28
Hauppauge 01647 {"NAME":"SL-1642","GPIO":[0,0,0,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
HBN 13A {"NAME":"BNC-50/E75T","GPIO":[0,0,0,0,576,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
HBN BNC-60/U152T {"NAME":"BNC-60/U152T","GPIO":[0,0,0,0,320,0,1,1,224,32,0,0,0,0],"FLAG":0,"BASE":18}
HerePow {"NAME":"HerePow ZHX-ZNOC","GPIO":[0,544,0,2624,2720,2656,0,0,224,32,320,0,0,0],"FLAG":0,"BASE":68}
Heygo 02 {"NAME":"Heygo 02","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
HiHome WPP-10S1 {"NAME":"HIhome WPP-10S","GPIO":[320,0,576,1,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":49}
HiHome WPP-10S2 {"NAME":"HiHome WPP-10S","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
@ -1241,6 +1255,7 @@ Local Bytes (UK) {"NAME":"LocalBytes PM","GPIO":[0,0,0,32,2720,2656,
LogiLink {"NAME":"LogilinkPA0199","GPIO":[0,0,0,64,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
LogiLink PA0200 {"NAME":"LogilinkPA0200","GPIO":[0,0,0,64,0,0,0,0,0,320,224,0,0,4896],"FLAG":0,"BASE":18}
Lohas Nightlight + USB {"NAME":"Lohas LED Mini Plug","GPIO":[0,321,0,288,322,226,1,1,224,32,225,0,544,0],"FLAG":0,"BASE":18}
Lombex Actis Pro {"NAME":"U11-Socket","GPIO":[0,0,0,0,289,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Lonsonho 10A Type E {"NAME":"Lonsonho10ALed","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
LoraTap SP400W-IT {"NAME":"LoraTap SP400W","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,1],"FLAG":0,"BASE":18}
LSC Power {"NAME":"LSC Smart Plug","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
@ -1344,6 +1359,8 @@ RenPho RF-SM004 {"NAME":"RenPho RFSM004","GPIO":[0,0,0,0,544,320,0,
Robaxo {"NAME":"Robaxo RSP-025","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
RSH-WS005 {"NAME":"RSH-WS005 Energy Monitor","GPIO":[320,0,576,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18}
RSH-WS007-EU {"NAME":"RSH-WS007","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
RSmart {"NAME":"RSmart Plug","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
S-Link Swapp 16A {"NAME":"S-Link S01","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18}
S126 {"NAME":"tuya-plug","GPIO":[0,0,0,0,0,0,0,0,224,35,0,0,0,0],"FLAG":0,"BASE":8}
SA-001 {"NAME":"SA-001","GPIO":[32,3072,0,3104,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":41}
SA-P202A {"NAME":"SA-P202A","GPIO":[0,0,0,0,0,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
@ -1369,6 +1386,7 @@ Slitinto NX-SP202 {"NAME":"Slitinto SP202","GPIO":[32,0,0,0,2720,2656
SM-PW701K {"NAME":"SM-PW701K","GPIO":[0,0,0,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Smaho {"NAME":"SMAHO WiFi P.","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
Smart 15A {"NAME":"JH-G09U","GPIO":[0,0,0,0,224,32,0,0,288,0,0,0,0,0],"FLAG":0,"BASE":18}
Smart Plug {"NAME":"SO08WP","GPIO":[1,1,1,32,2688,2656,1,1,2624,288,224,1,1,1],"FLAG":0,"BASE":18}
SmartDGM PP-W162 {"NAME":"SmartDGM Plug","GPIO":[0,0,0,32,2720,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18}
SmartGrade {"NAME":"SmartGrade AC","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
SmartVU Home {"NAME":"SHWSP1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":52}
@ -1433,10 +1451,12 @@ TP20 {"NAME":"TP20","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0
TP24 {"NAME":"TP24","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
TP28Y {"NAME":"TP28Y","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
Treatlife Dimmable {"NAME":"DP20","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 21,2 | SO20 1 | SO54 1"}
Treatlife Smart {"NAME":"Treatlife SK50","GPIO":[1,1,1,1,320,576,1,1,224,1,32,1,1,1],"FLAG":0,"BASE":18}
Tuya 16A Nightlight {"NAME":"Nightlight","GPIO":[225,0,320,0,226,227,0,0,34,64,0,224,0,0],"FLAG":0,"BASE":18}
U10 Series {"NAME":"WIFI-Socket","GPIO":[1,32,1,1,1,1,1,1,1,320,224,1,1,4704],"FLAG":0,"BASE":18}
UltraBrite {"NAME":"UltraBrite Smart Plug","GPIO":[1,1,1,1,288,289,1,1,224,32,1,1,1,1],"FLAG":0,"BASE":18}
Ultralink UL-P01W {"NAME":"UL-P01W","GPIO":[0,288,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18}
Unlocked Automation 15A {"NAME":"UA 100","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,1],"FLAG":0,"BASE":18}
Upstone {"NAME":"UPSTONE","GPIO":[1,1,544,1,320,1,0,0,224,32,1,1,1,1],"FLAG":0,"BASE":18}
US212 {"NAME":"US212","GPIO":[320,0,0,2624,0,2720,0,0,224,32,2656,225,0,0],"FLAG":0,"BASE":18}
Varna Crafts 16A {"NAME":"VC Plug","GPIO":[544,0,0,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45}
@ -1573,6 +1593,7 @@ LeFun SK2 {"NAME":"LeFun SK2","GPIO":[0,0,0,32,225,224,0,0,22
LITEdge Smart Power Strip {"NAME":"LITEEdge Power Strip","GPIO":[227,0,0,0,288,289,0,0,224,32,225,226,228,0],"FLAG":0,"BASE":18}
Luminea 3AC+4USB 16A {"NAME":"Luminea-NX4473","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,0],"FLAG":0,"BASE":18}
Maxcio ZLD-34EU-W {"NAME":"MAXCIO","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18}
Merkury Innovations Smart Surge {"NAME":"Merkury Power Strip MIC-SW002-199L","GPIO":[288,0,289,0,228,32,0,0,225,224,226,0,259,0],"FLAG":0,"BASE":18}
Merkury Innovations SmartSurge {"NAME":"Merkury MI-SW001","GPIO":[288,0,289,0,228,32,0,0,225,224,226,0,227,0],"FLAG":0,"BASE":18}
Meross 4AC 4USB {"NAME":"HamaStrip","GPIO":[0,544,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18}
Meross MSS425 {"NAME":"Meross MSS425","GPIO":[260,0,0,0,320,0,0,0,224,32,225,226,259,0],"FLAG":0,"BASE":18}
@ -1591,6 +1612,7 @@ Prokord 4AC 4USB {"NAME":"PSH-WT003-EU","GPIO":[0,320,0,32,226,227,0
S2199EU {"NAME":"S2199EU","GPIO":[0,32,0,288,226,228,0,0,224,227,225,0,0,4704],"FLAG":0,"BASE":18}
SA-P402A {"NAME":"SA-P402A","GPIO":[0,32,0,320,226,228,224,227,225,0,0,0,0,4704],"FLAG":0,"BASE":18}
Smart Tech 4AC 4USB {"NAME":"ST-T-SPS1","GPIO":[0,576,320,0,228,225,0,0,227,32,226,224,0,0],"FLAG":0,"BASE":18}
SmartVU Home 4AC 2USB {"NAME":"SHWSP4","GPIO":[0,288,0,32,224,225,0,0,227,228,226,0,0,0],"FLAG":0,"BASE":18}
Soundance 3AC 2USB {"NAME":"Soundance C198","GPIO":[256,0,0,0,320,289,0,0,225,0,226,227,260,0],"FLAG":0,"BASE":18}
STITCH 4 AC, 2 Always-On USB {"NAME":"MP Stitch 34082","GPIO":[320,0,0,0,227,32,0,0,225,226,224,0,0,0],"FLAG":0,"BASE":18}
Surge Protector 3AC 2USB {"NAME":"C158","GPIO":[260,0,0,0,261,230,0,0,224,0,225,226,259,0],"FLAG":0,"BASE":18}
@ -1604,6 +1626,7 @@ Tonbux SM-SO301-U {"NAME":"Tonbux SM-SO30","GPIO":[320,0,0,0,256,0,0,
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 3-socket 2 USB {"NAME":"Essentials Smart Home 3-socket USB Power Strip","GPIO":[0,0,0,0,544,226,0,0,224,32,225,0,0,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}
Wipro Smart Extension {"NAME":"Generic","GPIO":[321,0,0,0,259,0,0,0,257,258,256,0,228,0],"FLAG":0,"BASE":18}
Wolf Armor 4AC 4USB {"NAME":"Wolf Armor SP26","GPIO":[0,320,0,32,227,226,0,0,224,228,225,0,0,0],"FLAG":0,"BASE":18}
@ -1655,9 +1678,11 @@ Wipro Garnet NS7001 480lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,416,419,0,
```
Aigital LE13 800lm {"NAME":"Aigital 9W RGB","GPIO":[0,0,0,0,420,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18}
Aisirer 10W 1000lm {"NAME":"Aisirer RGBCW","GPIO":[160,0,0,0,0,0,0,0,0,4032,4064,0,0,0],"FLAG":0,"BASE":18}
AiYaTo 12W {"NAME":"AiYaTo RGBCW","GPIO":[0,0,0,0,419,418,0,0,416,420,417,0,0,0],"FLAG":0,"BASE":18}
Alfawise LE12 9W 900LM {"NAME":"Alfawise LE12 ","GPIO":[0,0,0,0,420,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18}
Aoycocr JL81 5W 400lm {"NAME":"AoycocrJLB1","GPIO":[0,0,0,0,418,0,0,0,417,420,416,419,0,0],"FLAG":0,"BASE":18}
Aoycocr Q10CWM BR30 9W 720lm {"NAME":"AoycocrBR30","GPIO":[0,0,0,0,0,418,0,0,417,0,416,419,0,0],"FLAG":0,"BASE":18}
Arlec Smart 10W 830lm {"NAME":"Arlec GLD320HA","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Arlec Smart 9.5W 806lm {"NAME":"Arlec RGBWW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Arlec Smart 9.5W 806lm {"NAME":"Arlec RGBWW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
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"}
@ -1767,6 +1792,7 @@ LVWIT G45 5W 470Lm {"NAME":"LVWIT E14 5W G45 RGBWCCT","GPIO":[0,0,0,0,
Lyhope 7W 650lm {"NAME":"Lyhope 014BB06","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18}
MagicHome 7W {"NAME":"MagicHome E27","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Makion 7W 600lm {"NAME":"Makion Smart LED Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Melery MR16 {"NAME":"Melery MR16 GU5.3","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18}
Mirabella Genio 5W 450lm Candle {"NAME":"MiraBellaGenio","GPIO":[0,0,0,0,0,0,0,0,4068,0,4032,0,0,0],"FLAG":0,"BASE":18}
Moes 9W 800lm {"NAME":"Moes 9w","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
Nishica JBT 9W 806lm {"NAME":"Nishica","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18}
@ -2054,6 +2080,7 @@ LilyGO TTGO 4 Channel ESP32 {"NAME":"T-Relay ESP32","GPIO":[0,0,1,0,1,227,0,0,1
LinkNode R4 {"NAME":"LinkNode R4","GPIO":[0,0,0,0,0,0,0,0,224,225,226,0,227,0],"FLAG":0,"BASE":18}
LinkNode R8 {"NAME":"LinkNode R8","GPIO":[0,0,0,0,228,229,0,231,226,227,225,230,224,0],"FLAG":0,"BASE":18}
Mhcozy 5V {"NAME":"Portail","GPIO":[160,0,0,0,0,0,0,0,224,320,0,0,0,4704],"FLAG":0,"BASE":18}
Mhcozy 5V 2 Channel {"NAME":"MHCOZY RF 2ch","GPIO":[32,0,0,0,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
Sinilink 6-32V Real Time Clock {"NAME":"Sinilink XY-WFBJ","GPIO":[0,0,544,0,7584,224,0,0,608,640,32,0,288,0],"FLAG":0,"BASE":18}
Sinilink DC5V Module {"NAME":"Sinilink XY-WF5V","GPIO":[0,0,0,0,224,1,0,0,32,288,0,0,1,0],"FLAG":0,"BASE":18}
Sinilink DC6-36V Module {"NAME":"Sinilink XY-WF5V","GPIO":[0,0,0,0,224,1,0,0,32,288,0,0,1,0],"FLAG":0,"BASE":18}
@ -2218,7 +2245,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}
Linkind Dimmer {"NAME":"Linkind Dimmer WS240010108","GPIO":[6213,8448,0,0,640,0,0,0,0,0,288,0,0,0,0,0,0,0,608,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}
@ -2277,7 +2304,7 @@ NaamaSmart KS602 {"NAME":"KS-602","GPIO":[32,0,0,0,0,0,0,0,224,576,0
Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[576,0,0,33,225,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18}
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}
Novadigital Interruptor Touch Led 1 Botno {"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}
@ -2473,9 +2500,16 @@ Sonoff Dual R3 v2 {"NAME":"Sonoff Dual R3 v2","GPIO":[32,0,0,0,0,0,0,
Sonoff Mini {"NAME":"Sonoff Mini","GPIO":[32,0,0,0,160,0,0,0,224,320,0,0,1,0],"FLAG":0,"BASE":1}
Sonoff Mini R2 {"NAME":"Sonoff MINIR2","GPIO":[32,0,0,0,160,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff Pow {"NAME":"Sonoff Pow","GPIO":[32,0,0,0,0,2592,0,0,224,2656,2688,288,0,0],"FLAG":0,"BASE":6}
Sonoff POW Elite 16A {"NAME":"Sonoff POWR316D","GPIO":[32,0,0,0,0,576,0,0,0,224,9280,0,3104,0,320,0,0,0,0,0,0,9184,9248,9216,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff POW Elite 20A {"NAME":"Sonoff POWR320D","GPIO":[32,0,9313,0,9312,576,0,0,0,0,9280,0,3104,0,320,0,0,0,0,0,0,9184,9248,9216,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff POW Origin 16A {"NAME":"Sonoff POWR316","GPIO":[32,0,0,0,0,576,0,0,0,224,0,0,3104,0,320,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}
Sonoff Pow R2 {"NAME":"Sonoff Pow R2","GPIO":[32,3072,0,3104,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":43}
Sonoff POW R3 25A 5500W {"NAME":"Sonoff POWR3","GPIO":[32,3072,0,3104,0,0,0,0,256,320,0,1,1,1],"FLAG":0,"BASE":43}
Sonoff RF {"NAME":"Sonoff RF","GPIO":[32,1,1,1,1,0,0,0,224,320,1,0,0,0],"FLAG":0,"BASE":2}
Sonoff TH Elite 16A Temperature and Humidity Monitoring {"NAME":"Sonoff THR316D","GPIO":[32,0,0,0,225,9280,0,0,0,321,0,576,320,9184,9216,0,0,224,0,9248,0,1,0,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff TH Elite 20A Temperature and Humidity Monitoring {"NAME":"Sonoff THR320D","GPIO":[32,0,0,0,226,9280,0,0,0,321,0,576,320,9184,9216,9312,0,0,9313,9248,0,1,0,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff TH Origin 16A {"NAME":"Sonoff THR316","GPIO":[32,0,0,0,0,0,0,0,0,321,0,576,320,0,0,0,0,224,0,0,0,1,0,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff TH Origin 20A {"NAME":"Sonoff THR320","GPIO":[32,0,0,0,0,0,0,0,0,321,0,576,320,0,0,9312,0,0,9313,0,0,1,0,3840,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff TH10/TH16 {"NAME":"Sonoff TH","GPIO":[32,1,0,1,1,0,0,0,224,320,1,0,0,0],"FLAG":0,"BASE":4}
Splatura USB Device Power Switch {"NAME":"Splatura USB","GPIO":[0,0,288,0,0,0,0,0,0,224,0,96,0,0],"FLAG":0,"BASE":18}
SS-8839-02 {"NAME":"SS-8839-02","GPIO":[0,1,0,1,320,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18}
@ -2514,7 +2548,7 @@ Hoenyzy DN20 3/4 {"NAME":"DN20 Valve","GPIO":[288,0,0,0,0,0,0,0,32,2
Jinvoo SM-AW713 {"NAME":"Jinvoo Valve","GPIO":[0,0,0,0,0,288,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Jinvoo SM-PW713 {"NAME":"Jinvoo Valve","GPIO":[0,0,0,0,224,288,0,0,32,289,0,0,0,4704],"FLAG":0,"BASE":18}
Moes Gas-Water {"NAME":"MoesHouse WV-B","GPIO":[0,0,0,0,0,0,0,0,32,224,0,0,0,0],"FLAG":0,"BASE":18}
Owfeel EN71 {"NAME":"SmartValve","GPIO":[224,0,0,0,0,0,0,0,32,288,0,0,0,0],"FLAG":0,"BASE":18}
Owfeel EN71 {"NAME":"SmartValve","GPIO":[288,0,0,0,0,0,0,0,32,224,0,0,0,0],"FLAG":0,"BASE":18}
Steren Valvula {"NAME":"Steren_SHOME-150","GPIO":[0,0,0,0,0,0,0,0,544,0,32,0,224,0],"FLAG":0,"BASE":18}
Tuya Gas/Water {"NAME":"Valve FM101","GPIO":[320,0,0,0,224,0,0,0,0,0,32,0,225,0],"FLAG":0,"BASE":18}
```
@ -2523,6 +2557,7 @@ Tuya Gas/Water {"NAME":"Valve FM101","GPIO":[320,0,0,0,224,0,0,0,0
```
2AC 1USB {"NAME":"SM-SW801U","GPIO":[0,0,0,0,288,32,0,0,224,0,225,0,226,0],"FLAG":0,"BASE":18}
Aseer THWFS01 {"NAME":"ASEER-THWFS01","GPIO":[320,33,544,323,2720,2656,0,0,2624,225,321,224,32,0],"FLAG":0,"BASE":18}
Athom {"NAME":"Athom SK01","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
Bestten LO-2-W {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,576,32,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18}
BingoElec 16A {"NAME":"BingoElecPower","GPIO":[0,0,0,0,288,289,1,1,224,32,0,0,1,1],"FLAG":0,"BASE":18}
BlitzWolf SHP8 {"NAME":"SHP8","GPIO":[0,320,0,32,2720,2656,0,0,2624,289,224,0,0,0],"FLAG":0,"BASE":64}
@ -2546,6 +2581,7 @@ Makegood MG-AUWF01 {"NAME":"MG-AUWF01","GPIO":[320,161,544,323,2720,26
Makegood MG-UKWSG01 {"NAME":"Aseer 2-Gang","GPIO":[321,160,544,323,2720,2656,0,0,2624,224,320,225,161,0],"FLAG":0,"BASE":18}
Makegood MG-UKWSW/B {"NAME":"Aseer 1-Gang","GPIO":[320,0,544,321,2720,2656,0,0,2624,0,0,224,160,0],"FLAG":0,"BASE":18}
Master Contacto WiFi de pared {"NAME":"Master_IOT-WLSOCKET","GPIO":[32,0,0,0,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
Milfra UK Double USB Chager Twin {"NAME":"Milfra TBU02","GPIO":[0,0,0,0,288,33,0,0,257,256,258,0,32,0],"FLAG":0,"BASE":18}
Moes WWK Glass Panel {"NAME":"Smart Socket","GPIO":[0,0,0,0,288,289,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
Oittm 120 {"NAME":"Oittm WS01","GPIO":[32,0,0,0,0,2592,0,0,224,2656,2688,288,0,0],"FLAG":0,"BASE":18}
PS-1607 {"NAME":"PS-1607","GPIO":[32,0,0,0,0,225,33,0,224,0,0,0,0,0],"FLAG":0,"BASE":18}
@ -2578,3 +2614,8 @@ Sonoff ZBBridge Pro {"NAME":"Sonoff Zigbee Pro","GPIO":[0,0,576,0,480,0
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}
```
## module
```
Ewelink RF No Neutral 3 Channel {"NAME":"Ewelink 3 Gang Module","GPIO":[32,0,0,0,225,226,33,34,224,544,0,0,0,0],"FLAG":0,"BASE":18}
```

View File

@ -0,0 +1,38 @@
{
"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_fs320k.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": {
"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

@ -36,6 +36,7 @@
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"before_reset": "usb_reset",
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",

View File

@ -36,6 +36,7 @@
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"before_reset": "usb_reset",
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",

View File

@ -1,8 +1,7 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
"ldscript": "esp32s3_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 -DESP32_4M -DESP32S3",

View File

@ -1,8 +1,7 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
"ldscript": "esp32s3_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 -DESP32_8M -DESP32S3",

View File

@ -0,0 +1,40 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"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_16M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S3 16M Flash, Tasmota 2880k Code/OTA, 10M FS",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"before_reset": "usb_reset",
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
"vendor": "Espressif"
}

View File

@ -1,8 +1,7 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
"ldscript": "esp32s3_out.ld"
},
"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",
@ -39,6 +38,7 @@
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"before_reset": "usb_reset",
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",

37
lib/lib_audio/ESP8266Audio/src/AudioOutputI2S.cpp Normal file → Executable file
View File

@ -1,7 +1,7 @@
/*
AudioOutputI2S
Base class for I2S interface port
Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify
@ -29,7 +29,7 @@
#include "AudioOutputI2S.h"
#if defined(ESP32) || defined(ESP8266)
AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int use_apll)
AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int use_apll, uint8_t mult, uint32_t freq)
{
this->portNo = port;
this->i2sOn = false;
@ -49,6 +49,8 @@ AudioOutputI2S::AudioOutputI2S(int port, int output_mode, int dma_buf_count, int
bclkPin = 26;
wclkPin = 25;
doutPin = 22;
mcmult = mult;
mclk_freq = freq;
SetGain(1.0);
}
@ -59,10 +61,13 @@ bool AudioOutputI2S::SetPinout()
return false; // Not allowed
i2s_pin_config_t pins = {
.mck_io_num = mclkPin,
.bck_io_num = bclkPin,
.ws_io_num = wclkPin,
.data_out_num = doutPin,
.data_in_num = I2S_PIN_NO_CHANGE};
.data_in_num = dinPin
};
//.data_in_num = I2S_PIN_NO_CHANGE};
i2s_set_pin((i2s_port_t)portNo, &pins);
return true;
#else
@ -73,11 +78,14 @@ bool AudioOutputI2S::SetPinout()
#endif
}
bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout)
bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout, int mclk, int din)
{
bclkPin = bclk;
wclkPin = wclk;
doutPin = dout;
mclkPin = mclk;
dinPin = din;
if (i2sOn)
return SetPinout();
@ -178,7 +186,7 @@ bool AudioOutputI2S::begin(bool txDAC)
#if CONFIG_IDF_TARGET_ESP32
mode = (i2s_mode_t)(mode | I2S_MODE_DAC_BUILT_IN);
#else
return false;
return false;
#endif
}
else if (output_mode == INTERNAL_PDM)
@ -186,7 +194,7 @@ bool AudioOutputI2S::begin(bool txDAC)
#if CONFIG_IDF_TARGET_ESP32
mode = (i2s_mode_t)(mode | I2S_MODE_PDM);
#else
return false;
return false;
#endif
}
@ -212,6 +220,14 @@ bool AudioOutputI2S::begin(bool txDAC)
#endif
}
if (mclkPin != I2S_PIN_NO_CHANGE) {
use_apll = false;
}
if (dinPin != I2S_PIN_NO_CHANGE) {
mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX);
}
i2s_config_t i2s_config_dac = {
.mode = mode,
.sample_rate = 44100,
@ -221,7 +237,14 @@ bool AudioOutputI2S::begin(bool txDAC)
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // lowest interrupt priority
.dma_buf_count = dma_buf_count,
.dma_buf_len = 128,
.use_apll = use_apll // Use audio PLL
.use_apll = use_apll, // Use audio PLL
.tx_desc_auto_clear = true,
#ifdef ESP32
.fixed_mclk = (int)mclk_freq,
//.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
.mclk_multiple = (i2s_mclk_multiple_t)mcmult,
#endif
.bits_per_chan = I2S_BITS_PER_CHAN_16BIT
};
audioLogger->printf("+%d %p\n", portNo, &i2s_config_dac);
if (i2s_driver_install((i2s_port_t)portNo, &i2s_config_dac, 0, NULL) != ESP_OK)

28
lib/lib_audio/ESP8266Audio/src/AudioOutputI2S.h Normal file → Executable file
View File

@ -1,7 +1,7 @@
/*
AudioOutputI2S
Base class for an I2S output port
Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify
@ -19,15 +19,25 @@
*/
#pragma once
#ifdef ESP32
#include <driver/i2s.h>
#endif
#include "AudioOutput.h"
#ifndef I2S_PIN_NO_CHANGE
#define I2S_PIN_NO_CHANGE -1
#endif
#ifdef ESP8266
#define I2S_MCLK_MULTIPLE_DEFAULT 0
#endif
class AudioOutputI2S : public AudioOutput
{
public:
#if defined(ESP32) || defined(ESP8266)
AudioOutputI2S(int port=0, int output_mode=EXTERNAL_I2S, int dma_buf_count = 8, int use_apll=APLL_DISABLE);
bool SetPinout(int bclkPin, int wclkPin, int doutPin);
AudioOutputI2S(int port=0, int output_mode=EXTERNAL_I2S, int dma_buf_count = 8, int use_apll=APLL_DISABLE, uint8_t mult=I2S_MCLK_MULTIPLE_DEFAULT, uint32_t freq=0);
bool SetPinout(int bclkPin, int wclkPin, int doutPin, int mclk = I2S_PIN_NO_CHANGE, int din = I2S_PIN_NO_CHANGE);
enum : int { APLL_AUTO = -1, APLL_ENABLE = 1, APLL_DISABLE = 0 };
enum : int { EXTERNAL_I2S = 0, INTERNAL_DAC = 1, INTERNAL_PDM = 2 };
#elif defined(ARDUINO_ARCH_RP2040)
@ -41,10 +51,10 @@ class AudioOutputI2S : public AudioOutput
virtual bool ConsumeSample(int16_t sample[2]) override;
virtual void flush() override;
virtual bool stop() override;
bool begin(bool txDAC);
bool SetOutputModeMono(bool mono); // Force mono output no matter the input
bool SetLsbJustified(bool lsbJustified); // Allow supporting non-I2S chips, e.g. PT8211
bool SetLsbJustified(bool lsbJustified); // Allow supporting non-I2S chips, e.g. PT8211
protected:
bool SetPinout();
@ -59,8 +69,12 @@ class AudioOutputI2S : public AudioOutput
// We can restore the old values and free up these pins when in NoDAC mode
uint32_t orig_bck;
uint32_t orig_ws;
uint8_t bclkPin;
uint8_t wclkPin;
uint8_t doutPin;
int8_t dinPin;
int8_t mclkPin;
uint8_t mcmult;
uint32_t mclk_freq;
};

View File

@ -405,6 +405,17 @@ void IRrecv::disableIRIn(void) {
#endif // UNIT_TEST
}
/// Pause collection of received IR data.
/// @see IRrecv class constructor
void IRrecv::pause(void) {
params.rcvstate = kStopState;
params.rawlen = 0;
params.overflow = false;
#if defined(ESP32)
gpio_intr_disable((gpio_num_t)params.recvpin);
#endif // ESP32
}
/// Resume collection of received IR data.
/// @note This is required if `decode()` is successful and `save_buffer` was
/// not set when the class was instanciated.
@ -415,6 +426,7 @@ void IRrecv::resume(void) {
params.overflow = false;
#if defined(ESP32)
timerAlarmDisable(timer);
gpio_intr_enable((gpio_num_t)params.recvpin);
#endif // ESP32
}

View File

@ -137,6 +137,7 @@ class IRrecv {
uint8_t max_skip = 0, uint16_t noise_floor = 0);
void enableIRIn(const bool pullup = false);
void disableIRIn(void);
void pause(void);
void resume(void);
uint16_t getBufSize(void);
#if DECODE_HASH

View File

@ -330,7 +330,22 @@ void LedMatrix::refresh()
}
else // ORIENTATION_TURN_RIGHT || ORIENTATION_TURN_LEFT
{
// not implemented yet
col = addr % modulesPerRow;
pixelRow = (addr / modulesPerRow) * 8 + ledRow;
bufPos = pixelRow * modulesPerRow + col;
if (moduleOrientation == ORIENTATION_TURN_RIGHT)
{
// ORIENTATION_TURN_RIGHT
deviceDataBuff[addr] = buffer[bufPos];
deviceRow = ledRow;
}
else
{
// ORIENTATION_TURN_LEFT
deviceDataBuff[maxDevices - 1 - addr] = revereBitorder(buffer[bufPos]);
deviceRow = 7 - ledRow; // upside down
}
}
}
setRow_allDevices(deviceRow, deviceDataBuff);

View File

@ -62,6 +62,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
sa_mode = 16;
saw_3 = 0xff;
dim_op = 0xff;
bpmode = 0;
dsp_off = 0xff;
dsp_on = 0xff;
lutpsize = 0;
@ -305,6 +306,9 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
rotmap_ymin = next_val(&lp1);
rotmap_ymax = next_val(&lp1);
break;
case 'b':
bpmode = next_val(&lp1);
break;
}
}
}
@ -1344,7 +1348,7 @@ void uDisplay::DisplayOnff(int8_t on) {
pwr_cbp(on);
}
// udisp_bpwr(on);
#define AW_PWMRES 1024
if (interface == _UDSP_I2C) {
if (on) {
@ -1357,10 +1361,17 @@ void uDisplay::DisplayOnff(int8_t on) {
if (dsp_on != 0xff) spi_command_one(dsp_on);
if (bpanel >= 0) {
#ifdef ESP32
analogWrite(bpanel, dimmer10_gamma);
// ledcWrite(ESP32_PWM_CHANNEL, dimmer8_gamma);
if (!bpmode) {
analogWrite(bpanel, dimmer10_gamma);
} else {
analogWrite(bpanel, AW_PWMRES - dimmer10_gamma);
}
#else
digitalWrite(bpanel, HIGH);
if (!bpmode) {
digitalWrite(bpanel, HIGH);
} else {
digitalWrite(bpanel, LOW);
}
#endif
}
@ -1368,10 +1379,17 @@ void uDisplay::DisplayOnff(int8_t on) {
if (dsp_off != 0xff) spi_command_one(dsp_off);
if (bpanel >= 0) {
#ifdef ESP32
analogWrite(bpanel, 0);
// ledcWrite(ESP32_PWM_CHANNEL, 0);
if (!bpmode) {
analogWrite(bpanel, 0);
} else {
analogWrite(bpanel, AW_PWMRES - 1);
}
#else
digitalWrite(bpanel, LOW);
if (!bpmode) {
digitalWrite(bpanel, LOW);
} else {
digitalWrite(bpanel, HIGH);
}
#endif
}
}
@ -1417,7 +1435,12 @@ void uDisplay::dim10(uint8_t dim, uint16_t dim_gamma) { // dimmer with
#ifdef ESP32 // TODO should we also add a ESP8266 version for bpanel?
if (bpanel >= 0) { // is the BaclPanel GPIO configured
analogWrite(bpanel, dimmer10_gamma);
if (!bpmode) {
analogWrite(bpanel, dimmer10_gamma);
} else {
analogWrite(bpanel, AW_PWMRES - dimmer10_gamma);
}
// ledcWrite(ESP32_PWM_CHANNEL, dimmer8_gamma);
} else if (dim_cbp) {
dim_cbp(dim);

View File

@ -176,6 +176,7 @@ class uDisplay : public Renderer {
uint16_t bg_col;
uint16_t gxs;
uint16_t gys;
int8_t bpmode;
int8_t spi_cs;
int8_t spi_clk;
int8_t spi_mosi;

View File

@ -6,5 +6,5 @@ sentence=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors
paragraph=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors
category=Sensors
url=https://github.com/adafruit/DHT-sensor-library
architectures=*
architectures=esp32
depends=Adafruit Unified Sensor

View File

@ -11,7 +11,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ESP32
@ -26,6 +25,23 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
// ESP Stuff
// This is from Arduino code -- not sure why it is necessary
//Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz
//Need to be fixed in ESP-IDF
#ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK
#define LEDC_DEFAULT_CLK LEDC_USE_XTAL_CLK
#else
#define LEDC_DEFAULT_CLK LEDC_AUTO_CLK
#endif
#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM
// define our limits to ease any change from esp-idf
#define MAX_TIMERS LEDC_TIMER_MAX // 4 timers for all ESP32 variants
#ifdef SOC_LEDC_SUPPORT_HS_MODE
#define PWM_HAS_HIGHSPEED SOC_LEDC_SUPPORT_HS_MODE // are there 2 banks of timers/ledc
#endif
// replicated from `tasmota.h`
#if defined(CONFIG_IDF_TARGET_ESP32)
const uint8_t MAX_PWMS = 16; // ESP32: 16 ledc PWM channels in total - TODO for now
@ -39,42 +55,122 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
const uint8_t MAX_PWMS = 5; // Unknown - revert to 5 PWM max
#endif
// current configuration of timers: frequency and resolution
static uint32_t timer_freq_hz[MAX_TIMERS] = {0};
static uint8_t timer_duty_resolution[MAX_TIMERS] = {0};
// channel mapping
static uint8_t pwm_channel[MAX_PWMS];
static uint32_t pwm_frequency = 977; // Default 977Hz
static uint8_t pwm_bit_num = 10; // Default 1023
static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 }; // contains the channel assigned to each pin, 0 means unassigned, substract 1
static uint8_t pwm_timer[MAX_PWMS] = {0}; // contains the timer assigned to each channel
static const uint32_t pwm_def_frequency = 977; // Default 977Hz
static const ledc_timer_bit_t pwm_def_bit_num = LEDC_TIMER_10_BIT; // Default 1023
static bool pwm_impl_inited = false; // trigger initialization
/*********************************************************************************************\
* ESP32 analogWrite emulation support
\*********************************************************************************************/
// apply the configuration of timer number `timer` to the actual timer
// it should be called whenever you change the configuration of a Timer
void _analog_applyTimerConfig(int32_t timer) {
esp_err_t ret;
if (timer < 0 || timer >= MAX_TIMERS) { return; } // avoid overflow or underflow
// AddLog(LOG_LEVEL_INFO, "PWM: ledc_timer_config(res=%i timer=%i freq=%i)", timer_duty_resolution[timer], timer, timer_freq_hz[timer]);
// we apply configuration to timer
ledc_timer_config_t cfg = {
(ledc_mode_t) 0, // speed mode - first bank
(ledc_timer_bit_t) timer_duty_resolution[timer], // duty_resolution
(ledc_timer_t) timer, // timer_num
timer_freq_hz[timer], // freq_hz
LEDC_DEFAULT_CLK // clk_cfg
};
ret = ledc_timer_config(&cfg);
if (ret != ESP_OK) {
AddLog(LOG_LEVEL_ERROR, "PWM: ledc_timer_config %i failed ret=%i", timer, ret);
}
#ifdef PWM_HAS_HIGHSPEED
// apply the same parameter to the low-speed timer as well
cfg.speed_mode = (ledc_mode_t) 1; // first bank
ret = ledc_timer_config(&cfg);
if (ret != ESP_OK) {
AddLog(LOG_LEVEL_ERROR, "PWM: ledc_timer_config %i failed ret=%i", timer + MAX_TIMERS, ret);
}
#endif
}
// initialize all timers and memory structures
void _analogInit(void) {
if (pwm_impl_inited) return;
if (pwm_impl_inited) { return; }
// set all channels to unaffected (255)
for (uint32_t i = 0; i < MAX_PWMS; i++) {
pwm_channel[i] = 255;
// On ESP32 there are 2 groups of timers. 0..LEDC_TIMER_MAX-1 and LEDC_TIMER_MAX..2*LEDC_TIMER_MAX-1
for (uint32_t i = 0; i < MAX_TIMERS; i++) {
timer_freq_hz[i] = pwm_def_frequency;
timer_duty_resolution[i] = pwm_def_bit_num;
_analog_applyTimerConfig(i); // apply settings to Timer 0
}
pwm_impl_inited = true;
}
int32_t _analog_pin2chan(uint32_t pin) { // returns -1 if uallocated
_analogInit(); // make sure the mapping array is initialized
for (uint32_t channel = 0; channel < MAX_PWMS; channel++) {
if ((pwm_channel[channel] < 255) && (pwm_channel[channel] == pin)) {
return channel;
// set the timer number for a GPIO, ignore if the GPIO is not set or Timer number is invalid
// Timer range is 0..3
void ledcSetTimer(uint8_t chan, uint8_t timer) {
if (timer >= MAX_TIMERS || chan > MAX_PWMS) { return; }
uint8_t cur_timer = pwm_timer[chan];
if (timer != cur_timer) { // ignore if the timer number is the same
pwm_timer[chan] = timer; // change the timer value
// apply to hardware
uint8_t group=(chan/8);
uint8_t channel=(chan%8);
esp_err_t ret = ledc_bind_channel_timer((ledc_mode_t) group, (ledc_channel_t) channel, (ledc_timer_t) timer);
if (ret != ESP_OK) {
AddLog(LOG_LEVEL_ERROR, "PWM: ledc_bind_channel_timer %i failed ret=%i", timer, ret);
}
}
return -1;
}
void _analogWriteFreqRange(void) {
// return the channel number for a GPIO, -1 if none
int32_t analogGetChannel2(uint32_t pin) { // returns -1 if uallocated
if (pin >= SOC_GPIO_PIN_COUNT) { return -1; }
return pin_to_channel[pin] - 1;
}
/* Convert a GPIO number to the pointer of the Timer number */
int32_t _analog_pin2timer(uint32_t pin) { // returns -1 if uallocated
_analogInit(); // make sure the mapping array is initialized
for (uint32_t channel = 0; channel < MAX_PWMS; channel++) {
if (pwm_channel[channel] < 255) {
ledcSetup(channel, pwm_frequency, pwm_bit_num);
}
int chan = analogGetChannel2(pin);
if (chan < 0) { return -1; }
int32_t timer = pwm_timer[chan];
if (timer > MAX_TIMERS) { timer = 0; }
return timer;
}
// get the next unused timer, returns -1 if no free timer is available
// Keep in mind that Timer 0 is reserved, which leaves only 3 timers available
//
// This function does not reserve the timer, it is reserved only when you assign a GPIO to it
static int32_t analogNextFreeTimer() {
_analogInit(); // make sure the mapping array is initialized
bool assigned[MAX_TIMERS] = {};
assigned[0] = true;
for (uint32_t chan = 0; chan < MAX_PWMS; chan++) {
assigned[pwm_timer[chan]] = true;
}
// find first free
for (uint32_t j = 0; j < MAX_TIMERS; j++) {
if (!assigned[j]) {
// AddLog(LOG_LEVEL_INFO, "PWM: analogNextFreeTimer next_timer=%i", j);
return j;
}
}
// AddLog(LOG_LEVEL_INFO, "PWM: analogNextFreeTimer no free timer");
return -1; // none available
}
// input range is in full range, ledc needs bits
@ -87,51 +183,160 @@ uint32_t _analogGetResolution(uint32_t x) {
return bits;
}
void analogWriteRange(uint32_t range) {
pwm_bit_num = _analogGetResolution(range);
_analogWriteFreqRange();
void analogWriteRange(uint32_t range, int32_t pin) {
// AddLog(LOG_LEVEL_INFO, "PWM: analogWriteRange range=%i pin=%i", range, pin);
_analogInit(); // make sure the mapping array is initialized
int32_t timer = (pin < 0) ? 0 : _analog_pin2timer(pin);
if (timer < 0) { return; }
uint32_t pwm_bit_num = _analogGetResolution(range);
if (pwm_bit_num > LEDC_MAX_BIT_WIDTH || pwm_bit_num == 0) {
AddLog(LOG_LEVEL_ERROR, "PWM: range is invalid: %i", range);
return;
}
timer_duty_resolution[timer] = (ledc_timer_bit_t) pwm_bit_num;
_analog_applyTimerConfig(timer);
}
void analogWriteFreq(uint32_t freq) {
pwm_frequency = freq;
_analogWriteFreqRange();
// change both freq and range
// `0`: set to global value
// `-1`: keep unchanged
// if pin < 0 then change global value for timer 0
void analogWriteFreqRange(int32_t freq, int32_t range, int32_t pin) {
// AddLog(LOG_LEVEL_INFO, "PWM: analogWriteFreqRange freq=%i range=%i pin=%i", freq, range, pin);
_analogInit(); // make sure the mapping array is initialized
uint32_t timer0_freq = timer_freq_hz[0]; // global values
uint8_t timer0_res = timer_duty_resolution[0];
int32_t timer = 0;
int32_t res = timer0_res;
if (pin < 0) {
if (freq <= 0) { freq = timer0_freq; }
if (range > 0) {
res = _analogGetResolution(range);
if (res >= LEDC_TIMER_BIT_MAX) { return; }
}
} else {
int32_t chan = analogGetChannel2(pin);
if (chan < 0) { return; }
timer = pwm_timer[chan];
if (freq < 0) { freq = timer_freq_hz[timer]; }
if (freq == 0) { freq = timer0_freq; }
res = timer0_res;
if (range < 0) { res = timer_duty_resolution[timer]; }
if (range != 0) { res = _analogGetResolution(range); }
if (res >= LEDC_TIMER_BIT_MAX) { return; }
if (freq == timer0_freq && res == timer0_res) {
// settings match with the global value
if (timer != 0) {
ledcSetTimer(chan, 0);
timer = 0;
}
// else nothing to change
} else {
// specific (non-global) values, require a specific timer
if (timer == 0) { // currently using the global timer, need to change
// we need to allocate a new timer to this pin
int32_t next_timer = analogNextFreeTimer();
if (next_timer < 0) {
AddLog(LOG_LEVEL_ERROR, "PWM: failed to assign a timer to GPIO %i", pin);
} else {
ledcSetTimer(chan, next_timer);
timer = next_timer;
}
}
}
pwm_timer[chan] = timer;
}
// AddLog(LOG_LEVEL_INFO, "PWM: analogWriteFreq actual freq=%i res=%i pin=%i timer=%i", freq, res, pin, timer);
if (timer_freq_hz[timer] != freq || timer_duty_resolution[timer] != res) {
timer_freq_hz[timer] = freq;
timer_duty_resolution[timer] = res;
_analog_applyTimerConfig(timer);
}
}
// set the frequency, in pin == -1 then change the global value of timer 0
void analogWriteFreq(uint32_t freq, int32_t pin) {
analogWriteFreqRange(freq, 0, pin);
}
// find next unassigned channel, or -1 if none available
static int32_t findEmptyChannel() {
bool chan_used[MAX_PWMS] = {0};
for (uint32_t pin = 0; pin < SOC_GPIO_PIN_COUNT; pin++) {
if (pin_to_channel[pin] > 0) {
chan_used[pin_to_channel[pin] - 1] = true;
}
}
// find empty slot
for (uint32_t chan = 0; chan < MAX_PWMS; chan++) {
if (!chan_used[chan]) {
return chan;
}
}
return -1;
}
int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc channel used, or -1 if failed
_analogInit(); // make sure the mapping array is initialized
// Find if pin is already attached
int32_t chan = _analog_pin2chan(pin);
int32_t chan = analogGetChannel2(pin);
if (chan >= 0) { return chan; }
// Find an empty channel
for (chan = 0; chan < MAX_PWMS; chan++) {
if (255 == pwm_channel[chan]) {
pwm_channel[chan] = pin;
// ledcAttachPin(pin, channel); -- replicating here because we want the default duty
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
// AddLog(LOG_LEVEL_INFO, "PWM: ledc_channel pin=%i out_invert=%i", pin, output_invert);
ledc_channel_config_t ledc_channel = {
(int)pin, // gpio
(ledc_mode_t)group, // speed-mode
(ledc_channel_t)channel, // channel
(ledc_intr_type_t)LEDC_INTR_DISABLE, // intr_type
(ledc_timer_t)timer, // timer_sel
0, // duty
0, // hpoint
{ output_invert ? 1u : 0u },// output_invert
};
ledc_channel_config(&ledc_channel);
ledcSetup(channel, pwm_frequency, pwm_bit_num);
// Serial.printf("PWM: New attach pin %d to channel %d\n", pin, channel);
return channel;
}
chan = findEmptyChannel();
if (chan < 0) {
AddLog(LOG_LEVEL_INFO, "PWM: no more PWM (ledc) channel for GPIO %i", pin);
return -1;
}
// No more channels available
AddLog(LOG_LEVEL_INFO, "PWM: no more PWM (ledc) channel for GPIO %i", pin);
return -1;
// new channel attached to pin
pin_to_channel[pin] = chan + 1;
// ledcAttachPin(pin, channel); -- replicating here because we want the default duty
// timer0 used by default
uint8_t group=(chan/8);
uint8_t channel=(chan%8);
uint8_t timer=0;
// AddLog(LOG_LEVEL_INFO, "PWM: ledc_channel pin=%i out_invert=%i", pin, output_invert);
ledc_channel_config_t ledc_channel = {
(int)pin, // gpio
(ledc_mode_t)group, // speed-mode
(ledc_channel_t)channel, // channel
(ledc_intr_type_t)LEDC_INTR_DISABLE, // intr_type
(ledc_timer_t)timer, // timer_sel
0, // duty
0, // hpoint
{ output_invert ? 1u : 0u },// output_invert
};
ledc_channel_config(&ledc_channel);
// AddLog(LOG_LEVEL_INFO, "PWM: New attach pin %d to channel %d", pin, channel);
return chan;
}
extern "C" uint32_t ledcReadFreq2(uint8_t chan) {
// extern "C" uint32_t __wrap_ledcReadFreq(uint8_t chan) {
if (chan > MAX_PWMS) {
return 0; // wrong channel
}
int32_t timer = pwm_timer[chan];
int32_t freq = timer_freq_hz[timer];
return freq;
}
uint8_t ledcReadResolution(uint8_t chan) {
if (chan > MAX_PWMS) {
return 0; // wrong channel
}
int32_t timer = pwm_timer[chan];
int32_t res = timer_duty_resolution[timer];
return res;
}
// void analogWrite(uint8_t pin, int val);
@ -139,7 +344,6 @@ extern "C" void __wrap__Z11analogWritehi(uint8_t pin, int val) {
analogWritePhase(pin, val, 0); // if unspecified, use phase = 0
}
/*
The primary goal of this function is to add phase control to PWM ledc
functions.
@ -148,8 +352,7 @@ extern "C" void __wrap__Z11analogWritehi(uint8_t pin, int val) {
By default all phases are starting at the same moment. This means
the the power supply always takes a power hit at the start of each
new cycle, even if the average power is low.
Phase control is also of major importance for H-bridge where
Phase control is also of major importance for H-bridge where
both PWM lines should NEVER be active at the same time.
Unfortunately Arduino Core does not allow any customization nor
@ -160,17 +363,24 @@ extern "C" void __wrap__Z11analogWritehi(uint8_t pin, int val) {
implementation changes.
*/
// exported from Arduno Core
extern uint8_t channels_resolution[MAX_PWMS];
void analogWritePhase(uint8_t pin, uint32_t duty, uint32_t phase)
{
int32_t chan = _analog_pin2chan(pin);
int32_t chan = analogGetChannel2(pin);
if (chan < 0) { // not yet allocated, try to allocate
chan = analogAttach(pin);
if (chan < 0) { return; } // failed
if (chan < 0) {
AddLog(LOG_LEVEL_INFO, "PWM: analogWritePhase invalid chan=%i", chan);
return;
} // failed
}
// AddLog(LOG_LEVEL_INFO, "PWM: analogWritePhase pin=%i chan=%i duty=%03X phase=%03X", pin, chan, duty, phase);
int32_t timer = _analog_pin2timer(pin);
if (timer < 0) {
AddLog(LOG_LEVEL_INFO, "PWM: analogWritePhase invalid timer=%i", timer);
return;
}
int32_t pwm_bit_num = timer_duty_resolution[timer];
// AddLog(LOG_LEVEL_INFO, "PWM: analogWritePhase pin=%i chan=%i duty=%03X phase=%03X pwm_bit_num=%i", pin, chan, duty, phase, pwm_bit_num);
if (duty >> (pwm_bit_num-1) ) ++duty; // input is 0..1023 but PWM takes 0..1024 - so we skip at mid-range. It creates a small non-linearity
if (phase >> (pwm_bit_num-1) ) ++phase;
@ -178,7 +388,7 @@ void analogWritePhase(uint8_t pin, uint32_t duty, uint32_t phase)
uint8_t group=(chan/8), channel=(chan%8);
//Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t max_duty = (1 << channels_resolution[chan]) - 1;
uint32_t max_duty = (1 << pwm_bit_num) - 1;
phase = phase & max_duty;
esp_err_t err1, err2;
@ -187,4 +397,36 @@ void analogWritePhase(uint8_t pin, uint32_t duty, uint32_t phase)
// AddLog(LOG_LEVEL_INFO, "PWM: err1=%i err2=%i", err1, err2);
}
// get the timer number for a GPIO, -1 if not found
int32_t analogGetTimer(uint8_t pin) {
return _analog_pin2timer(pin);
}
int32_t analogGetTimerForChannel(uint8_t chan) {
_analogInit(); // make sure the mapping array is initialized
if (chan > MAX_PWMS) { return -1; }
int32_t timer = pwm_timer[chan];
if (timer > MAX_TIMERS) { timer = 0; }
return timer;
}
// get the next unused timer, returns -1 if no free timer is available
// Keep in mind that Timer 0 is reserved, which leaves only 3 timers available
//
// Get timer resolution (in bits) - default 10
uint8_t analogGetTimerResolution(uint8_t timer) {
_analogInit(); // make sure the mapping array is initialized
if (timer >= MAX_TIMERS) { timer = 0; }
return timer_duty_resolution[timer];
}
// Get timer frequency (in Hz) - default 977
uint32_t analogGetTimerFrequency(uint8_t timer) {
_analogInit(); // make sure the mapping array is initialized
if (timer >= MAX_TIMERS) { timer = 0; }
return timer_freq_hz[timer]; // TODO check validity of value
}
#endif // ESP32

View File

@ -23,16 +23,96 @@
//
#include <Esp.h>
/*******************************************************************************************\
* ESP32/S2/S3/C3... PWM analog support
*
* The following supersedes Arduino framework and provides more granular control:
* - fine grained phase control (in addition to duty cycle)
* - fine control of PWM frequency and resolution per GPIO
*
* By default, all PWM are using the same timer called Timer 0.
* Changes in frequency of resolution apply to all PWM using Timer 0.
*
* You can specify a different a different resolution/frequency for
* specific GPIOs, this will internally assign a new timer to the GPIO.
* The limit is 3 specific values in addition to the global value.
*
* Note: on ESP32-only, there are 2 groups of PWM and 2 groups of timers.
* Although there are internally 8 timers, to simplifiy management,
* Timer 4..7 are mirrored from Timer 0..3.
* So it all happens like if there were only 4 timers and a single group of PWM channels.
\*******************************************************************************************/
// input range is in full range, ledc needs bits
void analogWriteRange(uint32_t range);
void analogWriteFreq(uint32_t freq);
int32_t analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated
extern "C" uint32_t ledcReadFreq2(uint8_t chan);
uint8_t ledcReadResolution(uint8_t chan);
//
// analogAttach - attach a GPIO to a hardware PWM
//
// Calling explcitly analogAttach() allows to specify the `output_invert` flag
// However it is called implicitly if `analogWrite()` is called and the GPIO
// was not yet attached.
//
// Returns: hardware channel number, or -1 if it failed
int analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated
// change both freq and range
// `0`: set to global value
// `-1`: keep unchanged
// if pin < 0 then change global value for timer 0
//
// analogWriteFreqRange - change the range and/or frequency of a GPIO
//
// `void analogWriteFreqRange(int32_t freq, int32_t range, int32_t pin)`
//
// The range is converted to a number of bits, so range must be a power of 2 minus 1.
// By default, the resolution is 10 bits, i.e. a range of 1023.
//
// Special cases:
// - if `pin < 0`, changes the global value for Timer 0 and all PWM using default
// - if `range == 0` or `freq == 0`, revert to using Timer 0 (i.e. reassign to global values)
// - if `range < 0` or `freq < 0`, keep the previous value unchanged
// - if `pin` is unassigned, silently ignore
void analogWriteFreqRange(int32_t freq, int32_t range, int32_t pin = -1);
//
// analogWriteRange - change the range of PWM
//
// short-cut for:
// `analogWriteFreqRange(-1, range, pin)`
void analogWriteRange(uint32_t range, int32_t pin = -1);
//
// analogWriteFreq - change the frequency of PWM in Hz
//
// short-cut for:
// `analogWriteFreqRange(-1, range, pin)`
void analogWriteFreq(uint32_t freq, int32_t pin = -1);
//
// analogWrite - change the value of PWM
//
// val must be in range.
void analogWrite(uint8_t pin, int val);
// Extended version that also allows to change phase
extern void analogWritePhase(uint8_t pin, uint32_t duty, uint32_t phase = 0);
// return the channel assigned to a GPIO, or -1 if none
extern int32_t analogGetChannel2(uint32_t pin);
/*******************************************************************************************\
* Low-level Timer management
\*******************************************************************************************/
// get the timer number for a GPIO, -1 if not found
int32_t analogGetTimer(uint8_t pin);
int32_t analogGetTimerForChannel(uint8_t chan);
// Get timer resolution (in bits) - default 10
uint8_t analogGetTimerResolution(uint8_t timer);
// Get timer frequency (in Hz) - default 977
uint32_t analogGetTimerFrequency(uint8_t timer);
/*********************************************************************************************/

58
lib/libesp32/berry/Makefile Normal file → Executable file
View File

@ -1,26 +1,25 @@
CFLAGS = -Wall -Wextra -std=c99 -pedantic-errors -O2
LIBS = -lm
TARGET = berry
CC ?= gcc
MKDIR = mkdir
LFLAGS =
CFLAGS = -Wall -Wextra -std=c99 -pedantic-errors -O2
DEBUG_FLAGS = -O0 -g -DBE_DEBUG
TEST_FLAGS = $(DEBUG_FLAGS) --coverage -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined
LIBS = -lm
TARGET = berry
CC = gcc
MKDIR = mkdir
LFLAGS =
INCPATH = src default
SRCPATH = src default
GENERATE = generate
CONFIG = default/berry_conf.h
COC = tools/coc/coc
PY = python3
PYCOC = tools/pycoc/main.py
CONST_TAB = $(GENERATE)/be_const_strtab.h
MAKE_COC = $(MAKE) -C tools/coc
INCPATH = src default
SRCPATH = src default
GENERATE = generate
CONFIG = default/berry_conf.h
COC = tools/coc/coc
CONST_TAB = $(GENERATE)/be_const_strtab.h
ifeq ($(OS), Windows_NT) # Windows
CFLAGS += -Wno-format # for "%I64d" warning
LFLAGS += -Wl,--out-implib,berry.lib # export symbols lib for dll linked
TARGET := $(TARGET).exe
COC := $(COC).exe
PY := $(PY).exe
PYTHON ?= python # only for windows and need python3
COC := $(PYTHON) $(COC)
else
CFLAGS += -DUSE_READLINE_LIB
LIBS += -lreadline -ldl
@ -33,16 +32,10 @@ endif
ifneq ($(V), 1)
Q=@
MSG=@echo
MAKE_COC += -s Q=$(Q)
else
MSG=@true
endif
ifeq ($(TEST), 1)
CFLAGS += -fprofile-arcs -ftest-coverage
LFLAGS += -fprofile-arcs -ftest-coverage
endif
SRCS = $(foreach dir, $(SRCPATH), $(wildcard $(dir)/*.c))
OBJS = $(patsubst %.c, %.o, $(SRCS))
DEPS = $(patsubst %.c, %.d, $(SRCS))
@ -52,11 +45,11 @@ INCFLAGS = $(foreach dir, $(INCPATH), -I"$(dir)")
all: $(TARGET)
debug: CFLAGS += -O0 -g -DBE_DEBUG
debug: CFLAGS += $(DEBUG_FLAGS)
debug: all
test: CFLAGS += --coverage
test: LFLAGS += --coverage
test: CFLAGS += $(TEST_FLAGS)
test: LFLAGS += $(TEST_FLAGS)
test: all
$(MSG) [Run Testcases...]
$(Q) ./testall.be
@ -76,30 +69,25 @@ sinclude $(DEPS)
$(OBJS): $(CONST_TAB)
$(CONST_TAB): $(COC) $(GENERATE) $(SRCS) $(CONFIG)
$(CONST_TAB): $(GENERATE) $(SRCS) $(CONFIG)
$(MSG) [Prebuild] generate resources
$(Q) $(COC) -i $(SRCPATH) -c $(CONFIG) -o $(GENERATE)
$(Q) $(COC) -o $(GENERATE) $(SRCPATH) -c $(CONFIG)
$(GENERATE):
$(Q) $(MKDIR) $(GENERATE)
$(COC):
$(MSG) [Make] coc
$(Q) $(MAKE_COC)
install:
cp $(TARGET) /usr/local/bin
uninstall:
$(RM) /usr/local/bin/$(TARGET)
prebuild: $(COC) $(GENERATE)
prebuild: $(GENERATE)
$(MSG) [Prebuild] generate resources
$(Q) $(PY) $(PYCOC) -o $(GENERATE) $(SRCPATH) -c $(CONFIG)
$(Q) $(COC) -o $(GENERATE) $(SRCPATH) -c $(CONFIG)
$(MSG) done
clean:
$(MSG) [Clean...]
$(Q) $(RM) $(OBJS) $(DEPS) $(GENERATE)/* berry.lib
$(Q) $(MAKE_COC) clean
$(MSG) done

View File

@ -23,11 +23,9 @@ Berry has the following advantages:
## Documents
LaTeX documents repository: [https://github.com/Skiars/berry_doc](https://github.com/Skiars/berry_doc)
Reference Manual: [Wiki](https://github.com/berry-lang/berry/wiki/Reference)
Short Manual: [berry_short_manual.pdf](https://github.com/Skiars/berry_doc/releases/download/latest/berry_short_manual.pdf).
Reference Manual: [berry_rm_en_us.pdf](https://github.com/Skiars/berry_doc/releases/download/latest/berry_rm_en_us.pdf), [berry_rm_zh_cn.pdf](https://github.com/Skiars/berry_doc/releases/download/latest/berry_rm_zh_cn.pdf).
Short Manual (slightly outdated): [berry_short_manual.pdf](https://github.com/Skiars/berry_doc/releases/download/latest/berry_short_manual.pdf).
Berry's EBNF grammar definition: [tools/grammar/berry.ebnf](./tools/grammar/berry.ebnf)
@ -111,9 +109,9 @@ Berry's EBNF grammar definition: [tools/grammar/berry.ebnf](./tools/grammar/berr
make install
```
## Editor pulgins
## Editor plugins
[Visual Studio Code](https://code.visualstudio.com/) pulgin are in this directory: [./tools/pulgins/vscode](./tools/pulgins/vscode).
[Visual Studio Code](https://code.visualstudio.com/) plugin are in this directory: [./tools/plugins/vscode](./tools/plugins/vscode).
## Examples

View File

@ -50,6 +50,7 @@ be_extern_native_module(animate);
be_extern_native_module(partition_core);
be_extern_native_module(crc);
be_extern_native_module(crypto);
be_extern_native_module(ULP);
#ifdef USE_ZIGBEE
be_extern_native_module(zigbee);
#endif // USE_ZIGBEE
@ -162,6 +163,9 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_ALEXA_AVS
&be_native_module(crypto),
#endif
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
&be_native_module(ULP),
#endif // USE_BERRY_ULP
/* user-defined modules register end */
NULL /* do not remove */
@ -195,6 +199,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(tcpserver);
be_extern_native_class(energy_struct);
// BLE
be_extern_native_class(MI32);
@ -242,6 +247,9 @@ BERRY_LOCAL bclass_array be_class_table = {
&be_native_class(webclient),
&be_native_class(tcpclient),
#endif // USE_WEBCLIENT
#ifdef USE_BERRY_TCPSERVER
&be_native_class(tcpserver),
#endif // USE_BERRY_TCPSERVER
#ifdef USE_WS2812
&be_native_class(Leds_ntv),
&be_native_class(Leds),

View File

@ -5,4 +5,4 @@
# 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
python3 tools/coc/coc -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

View File

@ -230,12 +230,15 @@ extern const bcstring be_const_str__settings_ptr;
extern const bcstring be_const_str__subscribe;
extern const bcstring be_const_str__t;
extern const bcstring be_const_str__timers;
extern const bcstring be_const_str__unsubscribe;
extern const bcstring be_const_str__validate;
extern const bcstring be_const_str__write;
extern const bcstring be_const_str_a;
extern const bcstring be_const_str_abs;
extern const bcstring be_const_str_accept;
extern const bcstring be_const_str_acos;
extern const bcstring be_const_str_active_otadata;
extern const bcstring be_const_str_adc_config;
extern const bcstring be_const_str_add;
extern const bcstring be_const_str_add_anim;
extern const bcstring be_const_str_add_cb_event_closure;
@ -427,6 +430,7 @@ extern const bcstring be_const_str_fromptr;
extern const bcstring be_const_str_fromstring;
extern const bcstring be_const_str_full_state;
extern const bcstring be_const_str_full_status;
extern const bcstring be_const_str_fulltopic;
extern const bcstring be_const_str_function;
extern const bcstring be_const_str_gamma;
extern const bcstring be_const_str_gamma10;
@ -454,6 +458,7 @@ extern const bcstring be_const_str_get_image_size;
extern const bcstring be_const_str_get_input_power_status;
extern const bcstring be_const_str_get_light;
extern const bcstring be_const_str_get_log;
extern const bcstring be_const_str_get_mem;
extern const bcstring be_const_str_get_name;
extern const bcstring be_const_str_get_object_from_ptr;
extern const bcstring be_const_str_get_option;
@ -473,12 +478,14 @@ extern const bcstring be_const_str_getfloat;
extern const bcstring be_const_str_geti;
extern const bcstring be_const_str_global;
extern const bcstring be_const_str_gpio;
extern const bcstring be_const_str_gpio_init;
extern const bcstring be_const_str_group_def;
extern const bcstring be_const_str_groups;
extern const bcstring be_const_str_h;
extern const bcstring be_const_str_has;
extern const bcstring be_const_str_has_arg;
extern const bcstring be_const_str_has_factory;
extern const bcstring be_const_str_hasclient;
extern const bcstring be_const_str_height_def;
extern const bcstring be_const_str_hex;
extern const bcstring be_const_str_hour;
@ -519,6 +526,7 @@ extern const bcstring be_const_str_is_ota;
extern const bcstring be_const_str_is_running;
extern const bcstring be_const_str_is_spiffs;
extern const bcstring be_const_str_isinstance;
extern const bcstring be_const_str_ismapped;
extern const bcstring be_const_str_ismethod;
extern const bcstring be_const_str_isnan;
extern const bcstring be_const_str_issubclass;
@ -665,10 +673,12 @@ extern const bcstring be_const_str_remove;
extern const bcstring be_const_str_remove_cmd;
extern const bcstring be_const_str_remove_cron;
extern const bcstring be_const_str_remove_driver;
extern const bcstring be_const_str_remove_fast_loop;
extern const bcstring be_const_str_remove_light;
extern const bcstring be_const_str_remove_rule;
extern const bcstring be_const_str_remove_timer;
extern const bcstring be_const_str_remove_trailing_zeroes;
extern const bcstring be_const_str_replace;
extern const bcstring be_const_str_reset;
extern const bcstring be_const_str_resize;
extern const bcstring be_const_str_resolvecmnd;
@ -720,6 +730,7 @@ extern const bcstring be_const_str_set_ldo_enable;
extern const bcstring be_const_str_set_ldo_voltage;
extern const bcstring be_const_str_set_light;
extern const bcstring be_const_str_set_matrix_pixel_color;
extern const bcstring be_const_str_set_mem;
extern const bcstring be_const_str_set_mode_ct;
extern const bcstring be_const_str_set_mode_rgb;
extern const bcstring be_const_str_set_ota_max;
@ -745,6 +756,7 @@ extern const bcstring be_const_str_signal_change;
extern const bcstring be_const_str_sin;
extern const bcstring be_const_str_sinh;
extern const bcstring be_const_str_size;
extern const bcstring be_const_str_sleep;
extern const bcstring be_const_str_slots;
extern const bcstring be_const_str_solidified;
extern const bcstring be_const_str_spiffs;
@ -778,6 +790,7 @@ extern const bcstring be_const_str_tasmota_X2Eget_light_X28_X29_X20is_X20depreca
extern const bcstring be_const_str_tasmota_X2Eset_light_X28_X29_X20is_X20deprecated_X2C_X20use_X20light_X2Eset_X28_X29;
extern const bcstring be_const_str_tasmota_log_reader;
extern const bcstring be_const_str_tcpclient;
extern const bcstring be_const_str_tcpserver;
extern const bcstring be_const_str_tele;
extern const bcstring be_const_str_test;
extern const bcstring be_const_str_the_X20second_X20argument_X20is_X20not_X20a_X20function;
@ -822,6 +835,7 @@ extern const bcstring be_const_str_value_error;
extern const bcstring be_const_str_valuer_error;
extern const bcstring be_const_str_var;
extern const bcstring be_const_str_w;
extern const bcstring be_const_str_wake_period;
extern const bcstring be_const_str_wd;
extern const bcstring be_const_str_web_add_button;
extern const bcstring be_const_str_web_add_config_button;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libULP_map) {
{ be_const_key(sleep, -1), be_const_ctype_func(be_ULP_sleep) },
{ be_const_key(get_mem, 6), be_const_ctype_func(be_ULP_get_mem) },
{ be_const_key(run, -1), be_const_ctype_func(be_ULP_run) },
{ be_const_key(load, -1), be_const_ctype_func(be_ULP_load) },
{ be_const_key(adc_config, -1), be_const_ctype_func(be_ULP_adc_config) },
{ be_const_key(set_mem, -1), be_const_ctype_func(be_ULP_set_mem) },
{ be_const_key(gpio_init, 3), be_const_ctype_func(be_ULP_gpio_init) },
{ be_const_key(wake_period, -1), be_const_ctype_func(be_ULP_wake_up_period) },
};
static be_define_const_map(
m_libULP_map,
8
);
static be_define_const_module(
m_libULP,
"ULP"
);
BE_EXPORT_VARIABLE be_define_const_native_module(ULP);

View File

@ -1,44 +1,45 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_bytes_map) {
{ be_const_key(set, -1), be_const_func(m_set) },
{ 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(copy, 8), be_const_func(m_copy) },
{ be_const_key(setbits, -1), be_const_closure(setbits_closure) },
{ be_const_key(deinit, 18), be_const_func(m_deinit) },
{ 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(ismapped, -1), be_const_func(m_is_mapped) },
{ be_const_key(getbits, 30), be_const_closure(getbits_closure) },
{ be_const_key(getfloat, 17), be_const_func(m_getfloat) },
{ 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(tob64, -1), be_const_func(m_tob64) },
{ be_const_key(set, -1), be_const_func(m_set) },
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
{ be_const_key(_X2E_X2E, 6), be_const_func(m_connect) },
{ be_const_key(add, -1), be_const_func(m_add) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(_buffer, -1), be_const_func(m_buffer) },
{ be_const_key(_X21_X3D, 21), be_const_func(m_nequal) },
{ be_const_key(seti, 23), be_const_func(m_set) },
{ be_const_key(fromb64, -1), be_const_func(m_fromb64) },
{ be_const_key(asstring, 25), be_const_func(m_asstring) },
{ 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(init, -1), be_const_func(m_init) },
{ be_const_key(_X2Esize, 31), be_const_var(1) },
{ be_const_key(clear, -1), be_const_func(m_clear) },
{ be_const_key(_X2Elen, -1), be_const_var(2) },
{ be_const_key(_X2B, -1), be_const_func(m_merge) },
{ be_const_key(fromhex, -1), be_const_func(m_fromhex) },
{ be_const_key(get, -1), be_const_func(m_getu) },
{ be_const_key(size, 2), be_const_func(m_size) },
{ be_const_key(tohex, -1), be_const_func(m_tohex) },
{ 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(geti, -1), be_const_func(m_geti) },
{ be_const_key(fromstring, -1), be_const_func(m_fromstring) },
{ be_const_key(_X3D_X3D, -1), be_const_func(m_equal) },
{ be_const_key(_X3D_X3D, 5), be_const_func(m_equal) },
};
static be_define_const_map(
be_class_bytes_map,
33
34
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -1,98 +1,99 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tasmota_map) {
{ be_const_key(run_deferred, -1), be_const_closure(Tasmota_run_deferred_closure) },
{ be_const_key(_drivers, 42), be_const_var(0) },
{ be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) },
{ be_const_key(gen_cb, -1), be_const_closure(Tasmota_gen_cb_closure) },
{ be_const_key(yield, 20), be_const_func(l_yield) },
{ be_const_key(log, 21), be_const_func(l_logInfo) },
{ be_const_key(find_op, -1), be_const_closure(Tasmota_find_op_closure) },
{ be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
{ be_const_key(response_append, -1), be_const_func(l_respAppend) },
{ be_const_key(web_send, -1), be_const_func(l_webSend) },
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
{ be_const_key(resolvecmnd, 1), be_const_func(l_resolveCmnd) },
{ be_const_key(load, -1), be_const_closure(Tasmota_load_closure) },
{ be_const_key(_fl, -1), be_const_var(0) },
{ be_const_key(get_power, -1), be_const_func(l_getpower) },
{ be_const_key(add_rule, 32), be_const_closure(Tasmota_add_rule_closure) },
{ be_const_key(eth, 30), be_const_func(l_eth) },
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
{ be_const_key(exec_rules, -1), be_const_closure(Tasmota_exec_rules_closure) },
{ be_const_key(chars_in_string, -1), be_const_closure(Tasmota_chars_in_string_closure) },
{ be_const_key(cmd, -1), be_const_closure(Tasmota_cmd_closure) },
{ be_const_key(_rules, -1), be_const_var(1) },
{ be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) },
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
{ be_const_key(get_switches, 46), be_const_func(l_getswitch) },
{ be_const_key(global, -1), be_const_var(2) },
{ be_const_key(arch, -1), be_const_func(l_arch) },
{ be_const_key(wire1, -1), be_const_var(3) },
{ be_const_key(scale_uint, 15), be_const_func(l_scaleuint) },
{ be_const_key(millis, 8), be_const_func(l_millis) },
{ be_const_key(resp_cmnd_error, 64), be_const_func(l_respCmndError) },
{ be_const_key(publish, -1), be_const_func(l_publish) },
{ be_const_key(_settings_def, 75), be_const_comptr(&be_tasmota_settings_struct) },
{ be_const_key(init, -1), be_const_closure(Tasmota_init_closure) },
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
{ be_const_key(publish_rule, 57), be_const_func(l_publish_rule) },
{ be_const_key(remove_driver, 49), be_const_closure(Tasmota_remove_driver_closure) },
{ be_const_key(run_deferred, 25), be_const_closure(Tasmota_run_deferred_closure) },
{ be_const_key(read_sensors, 82), be_const_func(l_read_sensors) },
{ be_const_key(_timers, -1), be_const_var(4) },
{ be_const_key(set_light, -1), be_const_closure(Tasmota_set_light_closure) },
{ be_const_key(memory, 31), be_const_func(l_memory) },
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
{ be_const_key(get_light, -1), be_const_closure(Tasmota_get_light_closure) },
{ be_const_key(_cmd, 76), be_const_func(l_cmd) },
{ be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) },
{ be_const_key(find_key_i, -1), be_const_closure(Tasmota_find_key_i_closure) },
{ be_const_key(wifi, -1), be_const_func(l_wifi) },
{ be_const_key(rtc, -1), be_const_func(l_rtc) },
{ be_const_key(time_str, -1), be_const_closure(Tasmota_time_str_closure) },
{ be_const_key(resp_cmnd, 17), be_const_func(l_respCmnd) },
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
{ be_const_key(get_switch, -1), be_const_func(l_getswitch) },
{ be_const_key(save, -1), be_const_func(l_save) },
{ be_const_key(wire2, -1), be_const_var(5) },
{ be_const_key(run_cron, 0), be_const_closure(Tasmota_run_cron_closure) },
{ be_const_key(delay, -1), be_const_func(l_delay) },
{ be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) },
{ be_const_key(time_reached, -1), be_const_func(l_timereached) },
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
{ be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
{ be_const_key(_ccmd, -1), be_const_var(6) },
{ be_const_key(next_cron, 16), be_const_closure(Tasmota_next_cron_closure) },
{ be_const_key(cmd_res, -1), be_const_var(7) },
{ be_const_key(strftime, 80), be_const_func(l_strftime) },
{ be_const_key(event, -1), be_const_closure(Tasmota_event_closure) },
{ be_const_key(settings, -1), be_const_var(8) },
{ be_const_key(strptime, -1), be_const_func(l_strptime) },
{ be_const_key(resp_cmnd_done, 51), be_const_func(l_respCmndDone) },
{ be_const_key(strftime, -1), be_const_func(l_strftime) },
{ be_const_key(web_send_decimal, 49), be_const_func(l_webSendDecimal) },
{ be_const_key(yield, -1), be_const_func(l_yield) },
{ be_const_key(remove_cmd, -1), be_const_closure(Tasmota_remove_cmd_closure) },
{ be_const_key(try_rule, -1), be_const_closure(Tasmota_try_rule_closure) },
{ be_const_key(resp_cmnd_str, 59), be_const_func(l_respCmndStr) },
{ be_const_key(_drivers, -1), be_const_var(9) },
{ be_const_key(_crons, 56), be_const_var(10) },
{ be_const_key(check_not_method, 62), be_const_closure(Tasmota_check_not_method_closure) },
{ be_const_key(remove_cron, 65), be_const_closure(Tasmota_remove_cron_closure) },
{ be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
{ be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) },
{ be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
{ be_const_key(add_driver, -1), be_const_closure(Tasmota_add_driver_closure) },
{ be_const_key(_debug_present, -1), be_const_var(11) },
{ be_const_key(wd, 14), be_const_var(12) },
{ be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
{ be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
{ be_const_key(publish_result, -1), be_const_func(l_publish_result) },
{ be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) },
{ be_const_key(find_op, 50), be_const_closure(Tasmota_find_op_closure) },
{ be_const_key(try_rule, 68), be_const_closure(Tasmota_try_rule_closure) },
{ be_const_key(cmd_res, -1), be_const_var(1) },
{ be_const_key(eth, -1), be_const_func(l_eth) },
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
{ be_const_key(chars_in_string, -1), be_const_closure(Tasmota_chars_in_string_closure) },
{ be_const_key(global, 38), be_const_var(2) },
{ be_const_key(millis, 19), be_const_func(l_millis) },
{ be_const_key(settings, -1), be_const_var(3) },
{ be_const_key(fast_loop, -1), be_const_closure(Tasmota_fast_loop_closure) },
{ be_const_key(set_light, -1), be_const_closure(Tasmota_set_light_closure) },
{ be_const_key(remove_fast_loop, -1), be_const_closure(Tasmota_remove_fast_loop_closure) },
{ be_const_key(get_switch, 13), be_const_func(l_getswitch) },
{ be_const_key(_debug_present, 58), be_const_var(4) },
{ be_const_key(_cmd, -1), be_const_func(l_cmd) },
{ be_const_key(remove_timer, 2), be_const_closure(Tasmota_remove_timer_closure) },
{ be_const_key(publish, -1), be_const_func(l_publish) },
{ be_const_key(arch, -1), be_const_func(l_arch) },
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
{ be_const_key(add_driver, -1), be_const_closure(Tasmota_add_driver_closure) },
{ be_const_key(_timers, 11), be_const_var(5) },
{ be_const_key(add_cron, -1), be_const_closure(Tasmota_add_cron_closure) },
{ be_const_key(add_fast_loop, -1), be_const_closure(Tasmota_add_fast_loop_closure) },
{ be_const_key(remove_rule, -1), be_const_closure(Tasmota_remove_rule_closure) },
{ be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
{ be_const_key(check_not_method, -1), be_const_closure(Tasmota_check_not_method_closure) },
{ be_const_key(web_send, 63), be_const_func(l_webSend) },
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
{ be_const_key(time_str, -1), be_const_closure(Tasmota_time_str_closure) },
{ be_const_key(response_append, 26), be_const_func(l_respAppend) },
{ be_const_key(_fl, -1), be_const_var(6) },
{ be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
{ be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) },
{ be_const_key(rtc, 18), be_const_func(l_rtc) },
{ be_const_key(read_sensors, 52), be_const_func(l_read_sensors) },
{ be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) },
{ be_const_key(_crons, 51), be_const_var(7) },
{ be_const_key(publish_result, 34), be_const_func(l_publish_result) },
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
{ be_const_key(memory, -1), be_const_func(l_memory) },
{ be_const_key(wire1, -1), be_const_var(8) },
{ be_const_key(remove_driver, -1), be_const_closure(Tasmota_remove_driver_closure) },
{ be_const_key(get_light, -1), be_const_closure(Tasmota_get_light_closure) },
{ be_const_key(wifi, -1), be_const_func(l_wifi) },
{ be_const_key(run_cron, -1), be_const_closure(Tasmota_run_cron_closure) },
{ be_const_key(load, -1), be_const_closure(Tasmota_load_closure) },
{ be_const_key(wire_scan, 72), be_const_closure(Tasmota_wire_scan_closure) },
{ be_const_key(find_key_i, 76), be_const_closure(Tasmota_find_key_i_closure) },
{ be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
{ be_const_key(get_power, 69), be_const_func(l_getpower) },
{ be_const_key(_global_def, 56), be_const_comptr(&be_tasmota_global_struct) },
{ be_const_key(_ccmd, 60), be_const_var(9) },
{ be_const_key(cmd, 12), be_const_closure(Tasmota_cmd_closure) },
{ be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) },
{ be_const_key(resolvecmnd, 9), be_const_func(l_resolveCmnd) },
{ be_const_key(wire2, 5), be_const_var(10) },
{ be_const_key(get_switches, -1), be_const_func(l_getswitch) },
{ be_const_key(remove_rule, 53), be_const_closure(Tasmota_remove_rule_closure) },
{ be_const_key(next_cron, -1), be_const_closure(Tasmota_next_cron_closure) },
{ be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
{ be_const_key(publish_rule, -1), be_const_func(l_publish_rule) },
{ be_const_key(set_power, 70), be_const_func(l_setpower) },
{ be_const_key(strptime, -1), be_const_func(l_strptime) },
{ be_const_key(time_reached, -1), be_const_func(l_timereached) },
{ be_const_key(gen_cb, -1), be_const_closure(Tasmota_gen_cb_closure) },
{ be_const_key(delay, -1), be_const_func(l_delay) },
{ be_const_key(_rules, 33), be_const_var(11) },
{ be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
{ be_const_key(init, -1), be_const_closure(Tasmota_init_closure) },
{ be_const_key(wd, -1), be_const_var(12) },
{ be_const_key(remove_cron, -1), be_const_closure(Tasmota_remove_cron_closure) },
{ be_const_key(log, -1), be_const_func(l_logInfo) },
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
{ be_const_key(save, -1), be_const_func(l_save) },
{ be_const_key(_global_addr, 78), be_const_comptr(&TasmotaGlobal) },
{ be_const_key(add_fast_loop, 77), be_const_closure(Tasmota_add_fast_loop_closure) },
{ be_const_key(resp_cmnd_done, 47), be_const_func(l_respCmndDone) },
{ be_const_key(exec_rules, -1), be_const_closure(Tasmota_exec_rules_closure) },
{ be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
{ be_const_key(resp_cmnd_str, 17), be_const_func(l_respCmndStr) },
{ be_const_key(event, -1), be_const_closure(Tasmota_event_closure) },
};
static be_define_const_map(
be_class_tasmota_map,
87
88
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -1,16 +1,16 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tcpclient_map) {
{ be_const_key(write, 8), be_const_func(wc_tcp_write) },
{ be_const_key(close, -1), be_const_func(wc_tcp_close) },
{ be_const_key(connected, 3), be_const_func(wc_tcp_connected) },
{ be_const_key(deinit, -1), be_const_func(wc_tcp_deinit) },
{ be_const_key(_X2Ew, 0), be_const_var(0) },
{ be_const_key(close, -1), be_const_func(wc_tcp_close) },
{ be_const_key(connected, 0), be_const_func(wc_tcp_connected) },
{ be_const_key(_X2Ep, -1), be_const_var(0) },
{ be_const_key(available, 8), be_const_func(wc_tcp_available) },
{ be_const_key(init, -1), be_const_func(wc_tcp_init) },
{ be_const_key(readbytes, -1), be_const_func(wc_tcp_readbytes) },
{ be_const_key(connect, -1), be_const_func(wc_tcp_connect) },
{ be_const_key(available, -1), be_const_func(wc_tcp_available) },
{ be_const_key(read, -1), be_const_func(wc_tcp_read) },
{ be_const_key(write, -1), be_const_func(wc_tcp_write) },
{ be_const_key(read, 3), be_const_func(wc_tcp_read) },
};
static be_define_const_map(

View File

@ -0,0 +1,22 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tcpserver_map) {
{ be_const_key(init, -1), be_const_ctype_func(tcpserver_init) },
{ be_const_key(accept, -1), be_const_ctype_func(tcpserver_accept) },
{ be_const_key(_p, -1), be_const_var(0) },
{ be_const_key(close, 0), be_const_ctype_func(tcpserver_close) },
{ be_const_key(deinit, 5), be_const_ctype_func(tcpserver_deinit) },
{ be_const_key(hasclient, -1), be_const_ctype_func(tcpserver_hasclient) },
};
static be_define_const_map(
be_class_tcpserver_map,
6
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_tcpserver,
1,
NULL,
tcpserver
);

View File

@ -1,15 +1,17 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libmqtt_map) {
{ 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(unsubscribe, -1), be_const_closure(unsubscribe_closure) },
{ be_const_key(subscribe, -1), be_const_closure(subscribe_closure) },
{ be_const_key(publish, 3), be_const_func(be_mqtt_publish) },
{ be_const_key(_, -1), be_const_closure(__closure) },
{ be_const_key(_subscribe, -1), be_const_ctype_func(be_mqtt_subscribe) },
{ be_const_key(_unsubscribe, 1), be_const_ctype_func(be_mqtt_unsubscribe) },
};
static be_define_const_map(
m_libmqtt_map,
4
6
);
static be_define_const_module(

View File

@ -1,22 +1,23 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libstring_map) {
{ be_const_key(count, 4), be_const_func(str_count) },
{ be_const_key(byte, 6), be_const_func(str_byte) },
{ be_const_key(format, 8), be_const_func(str_format) },
{ be_const_key(split, -1), be_const_func(str_split) },
{ be_const_key(toupper, -1), be_const_func(str_toupper) },
{ be_const_key(char, -1), be_const_func(str_char) },
{ be_const_key(tr, -1), be_const_func(str_tr) },
{ be_const_key(count, 4), be_const_func(str_count) },
{ be_const_key(format, 7), be_const_func(str_format) },
{ be_const_key(escape, -1), be_const_func(str_escape) },
{ be_const_key(byte, -1), be_const_func(str_byte) },
{ be_const_key(toupper, -1), be_const_func(str_toupper) },
{ be_const_key(hex, -1), be_const_func(str_i2hex) },
{ be_const_key(replace, 1), be_const_func(str_replace) },
{ be_const_key(hex, 11), be_const_func(str_i2hex) },
{ be_const_key(tolower, 5), be_const_func(str_tolower) },
{ be_const_key(find, -1), be_const_func(str_find) },
{ be_const_key(split, 1), be_const_func(str_split) },
{ be_const_key(tolower, -1), be_const_func(str_tolower) },
{ be_const_key(escape, -1), be_const_func(str_escape) },
};
static be_define_const_map(
m_libstring_map,
11
12
);
static be_define_const_module(

View File

@ -1142,29 +1142,3 @@ BERRY_API bbool be_isge(bvm *vm)
be_assert(vm->reg + 2 <= vm->top);
return be_vm_isge(vm, vm->top - 2, vm->top - 1);
}
BERRY_API int be_register(bvm *vm, int index)
{
bvalue *v;
if (!vm->registry) {
vm->registry = be_list_new(vm);
be_list_pool_init(vm, vm->registry);
}
be_assert(vm->registry != NULL);
v = be_indexof(vm, index);
return be_list_pool_alloc(vm, vm->registry, v);
}
BERRY_API void be_unregister(bvm *vm, int id)
{
be_assert(vm->registry != NULL);
be_list_pool_free(vm->registry, id);
}
BERRY_API void be_getregister(bvm *vm, int id)
{
blist *reg = vm->registry;
be_assert(reg && id > 0 && id < be_list_count(reg));
var_setval(vm->top, be_list_at(reg, id));
be_incrtop(vm);
}

View File

@ -333,7 +333,6 @@ static int l_call(bvm *vm)
be_moveto(vm, top + 1, top + 1 + list_size);
be_moveto(vm, top, top + list_size);
be_refpush(vm, -2);
be_pushiter(vm, -1);
while (be_iter_hasnext(vm, -2)) {
be_iter_next(vm, -2);
@ -342,7 +341,6 @@ static int l_call(bvm *vm)
be_pop(vm, 1);
}
be_pop(vm, 1); /* remove iterator */
be_refpop(vm);
}
be_pop(vm, 2);
arg_count = arg_count - 1 + list_size;

View File

@ -1216,7 +1216,7 @@ static int m_fromhex(bvm *vm)
from = be_toint(vm, 3);
}
const char *s = be_tostring(vm, 2);
size_t s_len = strlen(s);
int32_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;
@ -1262,6 +1262,20 @@ static int m_buffer(bvm *vm)
be_return(vm);
}
/*
* Returns `btrue` if the buffer is mapped to memory
* or `bfalse` if memory was allocated by us.
*
* `ismapped() -> bool`
*/
static int m_is_mapped(bvm *vm)
{
buf_impl attr = m_read_attributes(vm, 1);
bbool mapped = (attr.mapped || (attr.bufptr == NULL));
be_pushbool(vm, mapped);
be_return(vm);
}
/*
* Change the pointer to a mapped buffer.
*
@ -1547,6 +1561,7 @@ void be_load_byteslib(bvm *vm)
{ ".len", NULL },
{ "_buffer", m_buffer },
{ "_change_buffer", m_change_buffer },
{ "ismapped", m_is_mapped },
{ "init", m_init },
{ "deinit", m_deinit },
{ "tostring", m_tostring },
@ -1590,6 +1605,7 @@ class be_class_bytes (scope: global, name: bytes) {
.len, var
_buffer, func(m_buffer)
_change_buffer, func(m_change_buffer)
ismapped, func(m_is_mapped)
init, func(m_init)
deinit, func(m_deinit)
tostring, func(m_tostring)

View File

@ -299,8 +299,8 @@ int be_instance_member(bvm *vm, binstance *instance, bstring *name, bvalue *dst)
return BE_NONE; /* if the return value is module `undefined`, consider it is an error */
}
}
var_clearstatic(dst);
return type;
var_clearstatic(dst);
return type;
}
}
}
@ -339,6 +339,20 @@ bbool be_instance_setmember(bvm *vm, binstance *o, bstring *name, bvalue *src)
vm->top += 4; /* prevent collection results */
be_dofunc(vm, top, 3); /* call method 'member' */
vm->top -= 4;
/* if return value is `false` or `undefined` signal an unknown attribute */
int type = var_type(vm->top);
if (type == BE_BOOL) {
bbool ret = var_tobool(vm->top);
if (!ret) {
return bfalse;
}
} else if (type == BE_MODULE) {
/* check if the module is named `undefined` */
bmodule *mod = var_toobj(vm->top);
if (strcmp(be_module_name(mod), "undefined") == 0) {
return bfalse; /* if the return value is module `undefined`, consider it is an error */
}
}
return btrue;
}
}

View File

@ -45,7 +45,7 @@ extern "C" {
}
/* 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 */
/* the behavior is exactly the same as `be_const_key()` but it not detected by coc */
#define be_const_key_weak(_str, _next) { \
.v.c = &be_const_str_##_str, \
.type = BE_STRING, \
@ -309,7 +309,7 @@ const bcstring be_const_str_##_name = { \
}
/* 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 */
/* the behavior is exactly the same as `be_const_key()` but it not detected by coc */
#define be_const_key_weak(_str, _next) { \
bvaldata(&be_const_str_##_str), \
BE_STRING, \

View File

@ -15,6 +15,7 @@
#include "be_strlib.h"
#include "be_exec.h"
#include "be_mem.h"
#include "be_sys.h"
#include <stdio.h>
#include <string.h>
@ -46,13 +47,17 @@ static const char* opc2str(bopcode op)
return op < array_count(opc_tab) ? opc_tab[op] : "ERROP";
}
void be_print_inst(binstruction ins, int pc)
void be_print_inst(binstruction ins, int pc, void* fout)
{
char __lbuf[INST_BUF_SIZE];
bopcode op = IGET_OP(ins);
logbuf(" %.4X ", pc);
be_writestring(__lbuf);
if (fout) {
be_fwrite(fout, __lbuf, strlen(__lbuf));
} else {
be_writestring(__lbuf);
}
switch (op) {
case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
case OP_MOD: case OP_LT: case OP_LE: case OP_EQ:
@ -132,8 +137,12 @@ void be_print_inst(binstruction ins, int pc)
logbuf("%s", opc2str(op));
break;
}
be_writestring(__lbuf);
be_writenewline();
logbuf("%s\n", __lbuf);
if (fout) {
be_fwrite(fout, __lbuf, strlen(__lbuf));
} else {
be_writestring(__lbuf);
}
}
#endif
@ -159,7 +168,7 @@ void be_dumpclosure(bclosure *cl)
logfmt("; line %d\n", (++lineinfo)->linenumber);
}
#endif
be_print_inst(*code++, pc);
be_print_inst(*code++, pc, NULL);
}
}
#endif

View File

@ -22,7 +22,7 @@ bbool be_debug_varname(bvm *vm, int level, int index);
bbool be_debug_upvname(bvm *vm, int level, int index);
#if BE_USE_DEBUG_MODULE
void be_print_inst(binstruction ins, int pc);
void be_print_inst(binstruction ins, int pc, void* fout);
#endif
#endif

View File

@ -61,6 +61,7 @@ struct pcall {
struct vmstate {
int top, reg, depth;
int refcount;
};
struct strbuf {
@ -125,6 +126,7 @@ static void vm_state_save(bvm *vm, struct vmstate *state)
state->depth = be_stack_count(&vm->callstack);
state->top = cast_int(vm->top - vm->stack);
state->reg = cast_int(vm->reg - vm->stack);
state->refcount = vm->refstack.count;
}
static void copy_exception(bvm *vm, int res, int dstindex)
@ -143,6 +145,7 @@ static void copy_exception(bvm *vm, int res, int dstindex)
static void vm_state_restore(bvm *vm, const struct vmstate *state, int res)
{
vm->reg = vm->stack + state->reg;
be_vector_resize(vm, &vm->refstack, state->refcount);
/* copy exception information to top */
copy_exception(vm, res, state->top);
be_assert(be_stack_count(&vm->callstack) >= state->depth);
@ -444,6 +447,7 @@ void be_except_block_setup(bvm *vm)
/* set longjmp() jump point */
frame->errjmp.status = 0;
frame->errjmp.prev = vm->errjmp; /* save long jump list */
frame->refcount = vm->refstack.count; /* save reference pointer */
vm->errjmp = &frame->errjmp;
fixup_exceptstack(vm, lbase);
}
@ -455,6 +459,7 @@ void be_except_block_resume(bvm *vm)
struct bexecptframe *frame = be_stack_top(&vm->exceptstack);
if (errorcode == BE_EXCEPTION) {
vm->errjmp = vm->errjmp->prev;
be_vector_resize(vm, &vm->refstack, frame->refcount);
/* jump to except instruction */
vm->ip = frame->ip + IGET_sBx(frame->ip[-1]);
if (be_stack_count(&vm->callstack) > frame->depth) {

View File

@ -45,6 +45,7 @@ struct bexecptframe {
struct blongjmp errjmp; /* long jump information */
int depth; /* function call stack depth */
binstruction *ip; /* instruction pointer */
int refcount; /* save object reference stack */
};
void be_throw(bvm *vm, int errorcode);

View File

@ -370,7 +370,6 @@ static void premark_internal(bvm *vm)
mark_gray(vm, gc_object(vm->module.loaded));
mark_gray(vm, gc_object(vm->module.path));
mark_gray(vm, gc_object(vm->ntvclass));
mark_gray(vm, gc_object(vm->registry));
#if BE_USE_DEBUG_HOOK
if (be_isgcobj(&vm->hook)) {
mark_gray(vm, gc_object(var_toobj(&vm->hook)));

View File

@ -72,7 +72,6 @@ static int m_setglobal(bvm *vm)
if (top >= 2 && be_isstring(vm, 1)) {
const char * name = be_tostring(vm, 1);
be_setglobal(vm, name);
be_return(vm);
}
be_return_nil(vm);
}

View File

@ -12,6 +12,7 @@
#include "be_exec.h"
#include "be_map.h"
#include "be_vm.h"
#include "be_strlib.h"
#define SHORT_STR_LEN 32
#define EOS '\0' /* end of source */
@ -336,7 +337,11 @@ static btokentype scan_decimal(blexer *lexer)
{
btokentype type = TokenInteger;
match(lexer, is_digit);
if (decimal_dots(lexer) | scan_realexp(lexer)) {
/* decimal_dots() and scan_realexp() have side effect, so we call each explicitly */
/* to prevent binary shortcut if the first is true */
bbool has_decimal_dots = decimal_dots(lexer);
bbool is_realexp = scan_realexp(lexer);
if (has_decimal_dots || is_realexp) {
type = TokenReal;
}
lexer->buf.s[lexer->buf.len] = '\0';
@ -414,6 +419,9 @@ static btokentype scan_string(blexer *lexer)
save(lexer); /* skip '\\.' */
}
}
if (c == EOS) {
be_lexerror(lexer, "unfinished string");
}
c = next(lexer); /* skip '"' or '\'' */
/* check if there's an additional string literal right after */
skip_delimiter(lexer);

View File

@ -339,7 +339,7 @@ int be_module_attr(bvm *vm, bmodule *module, bstring *attr, bvalue *dst)
bmodule *mod = var_toobj(dst);
if (strcmp(be_module_name(mod), "undefined") == 0) {
return BE_NONE; /* if the return value is module `undefined`, consider it is an error */
}
}
}
return type;
}
@ -373,6 +373,19 @@ bbool be_module_setmember(bvm *vm, bmodule *module, bstring *attr, bvalue *src)
vm->top += 3; /* prevent collection results */
be_dofunc(vm, top, 2); /* call method 'setmember' */
vm->top -= 3;
int type = var_type(vm->top);
if (type == BE_BOOL) {
bbool ret = var_tobool(vm->top);
if (!ret) {
return bfalse;
}
} else if (type == BE_MODULE) {
/* check if the module is named `undefined` */
bmodule *mod = var_toobj(vm->top);
if (strcmp(be_module_name(mod), "undefined") == 0) {
return bfalse; /* if the return value is module `undefined`, consider it is an error */
}
}
return btrue;
}
}

View File

@ -1446,26 +1446,32 @@ static void classdef_stmt(bparser *parser, bclass *c, bbool is_static)
static void classstatic_stmt(bparser *parser, bclass *c, bexpdesc *e)
{
bstring *name;
/* 'static' ID ['=' expr] {',' ID ['=' expr] } */
/* 'static' ['var'] ID ['=' expr] {',' ID ['=' expr] } */
/* 'static' 'def' ID '(' varlist ')' block 'end' */
scan_next_token(parser); /* skip 'static' */
if (next_type(parser) == KeyDef) { /* 'static' 'def' ... */
classdef_stmt(parser, c, btrue);
} else if (match_id(parser, name) != NULL) {
check_class_attr(parser, c, name);
be_class_member_bind(parser->vm, c, name, bfalse);
class_static_assignment_expr(parser, e, name);
while (match_skip(parser, OptComma)) { /* ',' */
if (match_id(parser, name) != NULL) {
check_class_attr(parser, c, name);
be_class_member_bind(parser->vm, c, name, bfalse);
class_static_assignment_expr(parser, e, name);
} else {
parser_error(parser, "class static error");
}
}
} else {
parser_error(parser, "class static error");
if (next_type(parser) == KeyVar) {
scan_next_token(parser); /* skip 'var' if any */
}
if (match_id(parser, name) != NULL) {
check_class_attr(parser, c, name);
be_class_member_bind(parser->vm, c, name, bfalse);
class_static_assignment_expr(parser, e, name);
while (match_skip(parser, OptComma)) { /* ',' */
if (match_id(parser, name) != NULL) {
check_class_attr(parser, c, name);
be_class_member_bind(parser->vm, c, name, bfalse);
class_static_assignment_expr(parser, e, name);
} else {
parser_error(parser, "class static error");
}
}
} else {
parser_error(parser, "class static error");
}
}
}

View File

@ -15,6 +15,7 @@
#include "be_map.h"
#include "be_vm.h"
#include "be_decoder.h"
#include "be_sys.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
@ -25,17 +26,22 @@ extern const bclass be_class_map;
#if BE_USE_SOLIDIFY_MODULE
#include <inttypes.h>
#define be_builtin_count(vm) \
be_vector_count(&(vm)->gbldesc.builtin.vlist)
#ifndef INST_BUF_SIZE
#define INST_BUF_SIZE 288
#endif
#define logbuf(...) snprintf(__lbuf, sizeof(__lbuf), __VA_ARGS__)
#define logfmt(...) \
do { \
char __lbuf[INST_BUF_SIZE]; \
logbuf(__VA_ARGS__); \
be_writestring(__lbuf); \
#define logfmt(...) \
do { \
char __lbuf[INST_BUF_SIZE]; \
snprintf(__lbuf, sizeof(__lbuf), __VA_ARGS__); \
if (fout) { \
be_fwrite(fout, __lbuf, strlen(__lbuf)); \
} else { \
be_writestring(__lbuf); \
} \
} while (0)
/********************************************************************\
@ -94,63 +100,9 @@ static void toidentifier(char *to, const char *p)
*to = 0; // final NULL
}
static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const char *classname, const char *key, void* fout);
/********************************************************************\
* Encode string as literals with simple rules
*
* Encode specifically \\, \n, \"
* All other characters outside of 0x20-0x7F is escaped with \x..
\********************************************************************/
static unsigned toliteral_length(const char *s)
{
unsigned len = 1;
const char * p = s;
while (*p) {
if (*p == '\n' || *p == '\\' || *p == '"') {
len += 2;
} else if (*p >= 0x20 && (*p & 0x80) == 0) {
len++;
} else {
len += 4; /* encode as \x.. */
}
p++;
}
return len;
}
static void toliteral(char *to, const char *p)
{
while (*p) {
if (*p == '\n') {
to[0] = '\\';
to[1] = 'n';
to += 2;
} else if (*p == '\\') {
to[0] = '\\';
to[1] = '\\';
to += 2;
} else if (*p == '"') {
to[0] = '\\';
to[1] = '"';
to += 2;
} else if (*p >= 0x20 && (*p & 0x80) == 0) {
*to = *p;
to++;
} else {
to[0] = '\\';
to[1] = 'x';
to[2] = hexdigit((*p & 0xF0) >> 4);
to[3] = hexdigit(*p & 0x0F);
to += 4;
}
p++;
}
*to = 0; // final NULL
}
static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const char *classname, const char *key);
static void m_solidify_map(bvm *vm, bbool str_literal, bmap * map, const char *class_name)
static void m_solidify_map(bvm *vm, bbool str_literal, bmap * map, const char *class_name, void* fout)
{
// compact first
be_map_compact(vm, map);
@ -178,10 +130,10 @@ static void m_solidify_map(bvm *vm, bbool str_literal, bmap * map, const char *c
} else {
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));
m_solidify_bvalue(vm, str_literal, &node->value, class_name, str(node->key.v.s), fout);
} else if (node->key.type == BE_INT) {
logfmt(" { be_const_key_int(%i, %i), ", node->key.v.i, key_next);
m_solidify_bvalue(vm, str_literal, &node->value, class_name, NULL);
logfmt(" { be_const_key_int(%lli, %i), ", node->key.v.i, key_next);
m_solidify_bvalue(vm, str_literal, &node->value, class_name, NULL, fout);
} else {
char error[64];
snprintf(error, sizeof(error), "Unsupported type in key: %i", node->key.type);
@ -194,21 +146,21 @@ static void m_solidify_map(bvm *vm, bbool str_literal, bmap * map, const char *c
}
static void m_solidify_list(bvm *vm, bbool str_literal, blist * list, const char *class_name)
static void m_solidify_list(bvm *vm, bbool str_literal, blist * list, const char *class_name, void* fout)
{
logfmt(" be_nested_list(%i,\n", list->count);
logfmt(" ( (struct bvalue*) &(const bvalue[]) {\n");
for (int i = 0; i < list->count; i++) {
logfmt(" ");
m_solidify_bvalue(vm, str_literal, &list->data[i], class_name, "");
m_solidify_bvalue(vm, str_literal, &list->data[i], class_name, "", fout);
logfmt(",\n");
}
logfmt(" }))"); // TODO need terminal comma?
}
// pass key name in case of class, or NULL if none
static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const char *classname, const char *key)
static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const char *classname, const char *key, void* fout)
{
int type = var_primetype(value);
switch (type) {
@ -297,16 +249,16 @@ static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const
} else {
logfmt(" be_const_list( * ");
}
m_solidify_bvalue(vm, str_literal, &ins->members[0], classname, key);
m_solidify_bvalue(vm, str_literal, &ins->members[0], classname, key, fout);
logfmt(" ) } ))");
}
}
break;
case BE_MAP:
m_solidify_map(vm, str_literal, (bmap *) var_toobj(value), classname);
m_solidify_map(vm, str_literal, (bmap *) var_toobj(value), classname, fout);
break;
case BE_LIST:
m_solidify_list(vm, str_literal, (blist *) var_toobj(value), classname);
m_solidify_list(vm, str_literal, (blist *) var_toobj(value), classname, fout);
break;
default:
{
@ -317,24 +269,24 @@ static void m_solidify_bvalue(bvm *vm, bbool str_literal, bvalue * value, const
}
}
static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int builtins);
static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, void* fout);
/* solidify any inner class */
static void m_solidify_proto_inner_class(bvm *vm, bbool str_literal, bproto *pr, int builtins)
static void m_solidify_proto_inner_class(bvm *vm, bbool str_literal, bproto *pr, void* fout)
{
// parse any class in constants to output it first
if (pr->nconst > 0) {
for (int k = 0; k < pr->nconst; k++) {
if (var_type(&pr->ktab[k]) == BE_CLASS) {
// output the class
m_solidify_subclass(vm, str_literal, (bclass*) var_toobj(&pr->ktab[k]), builtins);
m_solidify_subclass(vm, str_literal, (bclass*) var_toobj(&pr->ktab[k]), fout);
}
}
}
}
static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char * func_name, int builtins, int indent)
static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char * func_name, int indent, void* fout)
{
// const char * func_name = str(pr->name);
// const char * func_source = str(pr->source);
@ -364,7 +316,7 @@ static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char
size_t sub_len = strlen(func_name) + 10;
char sub_name[sub_len];
snprintf(sub_name, sizeof(sub_name), "%s_%d", func_name, i);
m_solidify_proto(vm, str_literal, pr->ptab[i], sub_name, builtins, indent+2);
m_solidify_proto(vm, str_literal, pr->ptab[i], sub_name, indent+2, fout);
logfmt(",\n");
}
logfmt("%*s}),\n", indent, "");
@ -377,7 +329,7 @@ static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char
logfmt("%*s( &(const bvalue[%2d]) { /* constants */\n", indent, "", pr->nconst);
for (int k = 0; k < pr->nconst; k++) {
logfmt("%*s/* K%-3d */ ", indent, "", k);
m_solidify_bvalue(vm, str_literal, &pr->ktab[k], NULL, NULL);
m_solidify_bvalue(vm, str_literal, &pr->ktab[k], NULL, NULL, fout);
logfmt(",\n");
}
logfmt("%*s}),\n", indent, "");
@ -402,12 +354,12 @@ static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char
for (int pc = 0; pc < pr->codesize; pc++) {
uint32_t ins = pr->code[pc];
logfmt("%*s 0x%08X, //", indent, "", ins);
be_print_inst(ins, pc);
be_print_inst(ins, pc, fout);
bopcode op = IGET_OP(ins);
if (op == OP_GETGBL || op == OP_SETGBL) {
// check if the global is in built-ins
int glb = IGET_Bx(ins);
if (glb > builtins) {
if (glb > be_builtin_count(vm)) {
// not supported
logfmt("\n===== unsupported global G%d\n", glb);
be_raise(vm, "internal_error", "Unsupported access to non-builtin global");
@ -420,7 +372,7 @@ static void m_solidify_proto(bvm *vm, bbool str_literal, bproto *pr, const char
}
static void m_solidify_closure(bvm *vm, bbool str_literal, bclosure *cl, const char * classname, int builtins)
static void m_solidify_closure(bvm *vm, bbool str_literal, bclosure *cl, const char * classname, void* fout)
{
bproto *pr = cl->proto;
const char * func_name = str(pr->name);
@ -432,7 +384,7 @@ static void m_solidify_closure(bvm *vm, bbool str_literal, bclosure *cl, const c
int indent = 2;
m_solidify_proto_inner_class(vm, str_literal, pr, builtins);
m_solidify_proto_inner_class(vm, str_literal, pr, fout);
logfmt("\n");
logfmt("/********************************************************************\n");
@ -448,7 +400,7 @@ static void m_solidify_closure(bvm *vm, bbool str_literal, bclosure *cl, const c
func_name_id);
}
m_solidify_proto(vm, str_literal, pr, func_name, builtins, indent);
m_solidify_proto(vm, str_literal, pr, func_name, indent, fout);
logfmt("\n");
// closure
@ -456,7 +408,7 @@ static void m_solidify_closure(bvm *vm, bbool str_literal, bclosure *cl, const c
logfmt("/*******************************************************************/\n\n");
}
static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int builtins)
static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, void* fout)
{
const char * class_name = str(cl->name);
@ -467,7 +419,7 @@ static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int buil
while ((node = be_map_next(cl->members, &iter)) != NULL) {
if (var_isstr(&node->key) && var_isclosure(&node->value)) {
bclosure *f = var_toobj(&node->value);
m_solidify_closure(vm, str_literal, f, class_name, builtins);
m_solidify_closure(vm, str_literal, f, class_name, fout);
}
}
}
@ -491,7 +443,7 @@ static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int buil
}
if (cl->members) {
m_solidify_map(vm, str_literal, cl->members, class_name);
m_solidify_map(vm, str_literal, cl->members, class_name, fout);
logfmt(",\n");
} else {
logfmt(" NULL,\n");
@ -509,10 +461,10 @@ static void m_solidify_subclass(bvm *vm, bbool str_literal, bclass *cl, int buil
}
static void m_solidify_class(bvm *vm, bbool str_literal, bclass *cl, int builtins)
static void m_solidify_class(bvm *vm, bbool str_literal, bclass *cl, void* fout)
{
const char * class_name = str(cl->name);
m_solidify_subclass(vm, str_literal, cl, builtins);
m_solidify_subclass(vm, str_literal, cl, fout);
logfmt("/*******************************************************************/\n\n");
logfmt("void be_load_%s_class(bvm *vm) {\n", class_name);
@ -522,7 +474,7 @@ static void m_solidify_class(bvm *vm, bbool str_literal, bclass *cl, int builtin
logfmt("}\n");
}
static void m_solidify_module(bvm *vm, bbool str_literal, bmodule *ml, int builtins)
static void m_solidify_module(bvm *vm, bbool str_literal, bmodule *ml, void* fout)
{
const char * module_name = be_module_name(ml);
if (!module_name) { module_name = ""; }
@ -534,11 +486,11 @@ static void m_solidify_module(bvm *vm, bbool str_literal, bmodule *ml, int built
while ((node = be_map_next(ml->table, &iter)) != NULL) {
if (var_isstr(&node->key) && var_isclosure(&node->value)) {
bclosure *f = var_toobj(&node->value);
m_solidify_closure(vm, str_literal, f, module_name, builtins);
m_solidify_closure(vm, str_literal, f, module_name, fout);
}
if (var_isstr(&node->key) && var_isclass(&node->value)) {
bclass *cl = var_toobj(&node->value);
m_solidify_subclass(vm, str_literal, cl, builtins);
m_solidify_subclass(vm, str_literal, cl, fout);
}
}
}
@ -553,7 +505,7 @@ static void m_solidify_module(bvm *vm, bbool str_literal, bmodule *ml, int built
logfmt(" \"%s\",\n", module_name);
if (ml->table) {
m_solidify_map(vm, str_literal, ml->table, module_name);
m_solidify_map(vm, str_literal, ml->table, module_name, fout);
logfmt("\n");
} else {
logfmt(" NULL,\n");
@ -564,23 +516,29 @@ static void m_solidify_module(bvm *vm, bbool str_literal, bmodule *ml, int built
}
#define be_builtin_count(vm) \
be_vector_count(&(vm)->gbldesc.builtin.vlist)
static int m_dump(bvm *vm)
{
if (be_top(vm) >= 1) {
int top = be_top(vm);
if (top >= 1) {
bvalue *v = be_indexof(vm, 1);
bbool str_literal = bfalse;
if (be_top(vm) >= 2) {
if (top >= 2) {
str_literal = be_tobool(vm, 2);
}
void* fout = NULL; /* output file */
if (top >= 3 && be_isinstance(vm, 3)) {
be_getmember(vm, 3, ".p");
if (be_iscomptr(vm, -1)) {
fout = be_tocomptr(vm, -1);
}
be_pop(vm, 1);
}
if (var_isclosure(v)) {
m_solidify_closure(vm, str_literal, var_toobj(v), NULL, be_builtin_count(vm));
m_solidify_closure(vm, str_literal, var_toobj(v), NULL, fout);
} else if (var_isclass(v)) {
m_solidify_class(vm, str_literal, var_toobj(v), be_builtin_count(vm));
m_solidify_class(vm, str_literal, var_toobj(v), fout);
} else if (var_ismodule(v)) {
m_solidify_module(vm, str_literal, var_toobj(v), be_builtin_count(vm));
m_solidify_module(vm, str_literal, var_toobj(v), fout);
} else {
be_raise(vm, "value_error", "unsupported type");
}

View File

@ -845,6 +845,26 @@ static int str_tr(bvm *vm)
be_return_nil(vm);
}
static int str_replace(bvm *vm)
{
int top = be_top(vm);
if (top >= 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isstring(vm, 3)) {
be_pushntvfunction(vm, &str_split);
be_pushvalue(vm, 1);
be_pushvalue(vm, 2);
be_call(vm, 2);
be_pop(vm, 2);
be_getmember(vm, -1, "concat"); /* get `concat` method of list */
be_pushvalue(vm, -2); /* get list instance as first arg */
be_pushvalue(vm, 3);
be_call(vm, 2);
be_pop(vm, 2);
be_return(vm);
}
be_return_nil(vm);
}
static int str_escape(bvm *vm)
{
int top = be_top(vm);
@ -876,6 +896,7 @@ be_native_module_attr_table(string) {
be_native_module_function("toupper", str_toupper),
be_native_module_function("tr", str_tr),
be_native_module_function("escape", str_escape),
be_native_module_function("replace", str_replace),
};
be_define_native_module(string, NULL);
@ -893,6 +914,7 @@ module string (scope: global, depend: BE_USE_STRING_MODULE) {
toupper, func(str_toupper)
tr, func(str_tr)
escape, func(str_escape)
replace, func(str_replace)
}
@const_object_info_end */
#include "../generate/be_fixed_string.h"

View File

@ -114,7 +114,13 @@
if (var_isint(a) && var_isint(b)) { \
res = ibinop(op, a, b); \
} else if (var_isnumber(a) && var_isnumber(b)) { \
res = var2real(a) op var2real(b); \
/* res = var2real(a) op var2real(b); */ \
union bvaldata x, y; /* TASMOTA workaround for ESP32 rev0 bug */ \
x.i = a->v.i;\
if (var_isint(a)) { x.r = (breal) x.i; }\
y.i = b->v.i;\
if (var_isint(b)) { y.r = (breal) y.i; }\
res = x.r op y.r; \
} else if (var_isstr(a) && var_isstr(b)) { \
bstring *s1 = var_tostr(a), *s2 = var_tostr(b); \
res = be_strcmp(s1, s2) op 0; \
@ -281,6 +287,12 @@ bbool be_value2bool(bvm *vm, bvalue *v)
return val2bool(v->v.i);
case BE_REAL:
return val2bool(v->v.r);
case BE_STRING:
return str_len(var_tostr(v)) != 0;
case BE_COMPTR:
return var_toobj(v) != NULL;
case BE_COMOBJ:
return ((bcommomobj*)var_toobj(v))->data != NULL;
case BE_INSTANCE:
return obj2bool(vm, v);
default:

View File

@ -102,7 +102,6 @@ struct bvm {
struct bstringtable strtab; /* short string table */
bstack tracestack; /* call state trace-stack */
bmap *ntvclass; /* native class table */
blist *registry; /* registry list */
struct bgc gc;
bctypefunc ctypefunc; /* handler to ctype_func */
bbyte compopt; /* compilation options */

View File

@ -580,11 +580,6 @@ BERRY_API void be_module_path_set(bvm *vm, const char *path);
BERRY_API void* be_pushbytes(bvm *vm, const void *buf, size_t len);
BERRY_API const void* be_tobytes(bvm *vm, int index, size_t *len);
/* registry operation */
BERRY_API int be_register(bvm *vm, int index);
BERRY_API void be_unregister(bvm *vm, int id);
BERRY_API void be_getregister(bvm *vm, int id);
/* debug APIs */
BERRY_API void be_sethook(bvm *vm, const char *mask);
BERRY_API void be_setntvhook(bvm *vm, bntvhook hook, void *data, int mask);

View File

@ -33,7 +33,11 @@ assert(bool(nil) == false)
assert(bool(-1) == true)
assert(bool(3.5) == true)
assert(bool('') == true)
assert(bool('') == false) # changed behavior
assert(bool('a') == true)
assert(bool(list) == true)
assert(bool(list()) == true)
import introspect
assert(bool(introspect.toptr(0x1000)) == true)
assert(bool(introspect.toptr(0)) == false)

View File

@ -190,3 +190,15 @@ b.setfloat(0, 0.33)
assert(b == bytes('C3F5A83E'))
b = bytes("0000C03F")
assert(b.getfloat(0) == 1.5)
#- fromhex -#
b = bytes("112233")
b.fromhex("FFFEAABBCC")
assert(b == bytes("FFFEAABBCC"))
b.fromhex("")
assert(b == bytes())
#- tohex -#
b = bytes("FFFEAABBCC")
assert(b.tohex() == "FFFEAABBCC")
assert(bytes().tohex() == "")

View File

@ -64,4 +64,5 @@ assert(b1 == b2)
b2.set(0,0xAABB,2)
assert(b2 == bytes("BBAA33445566"))
assert(b1 == bytes("BBAA33445566"))
assert(b1 == b2)
assert(b1 == b2)
assert(b1.ismapped() == false)

View File

@ -8,11 +8,11 @@ def assert_attribute_error(f)
end
class A
static a
static var a
def init() self.b = 2 end
def f() end
var b
static c, s, r
static var c, s, r
end
assert(A.a == nil)

View File

@ -8,11 +8,11 @@ def assert_attribute_error(f)
end
class A
static a
static a #- deprecated syntax -#
def init() self.b = 2 end
def f() end
var b
static c, s, r
static var c, s, r #- preferred syntax -#
end
assert(A.a == nil)

View File

@ -0,0 +1,31 @@
# try to exercise bug in reference
class failable
var fail # if 'true', tostring() raises an exception
def tostring()
if self.fail
raise "internal_error", "FAIL"
return "FAIL"
else
return "SUCCESS"
end
end
end
f = failable()
l1 = [1, 2, f]
l2 = ["foo", l1]
l1.push(l1)
assert(str(l2) == "['foo', [1, 2, SUCCESS, [...]]]")
assert(str(l1) == "[1, 2, SUCCESS, [...]]")
f.fail = true
try
print(str(l1))
except ..
end
f.fail = false
assert(str(l1) == "[1, 2, SUCCESS, [...]]") # FAILS

View File

@ -80,3 +80,11 @@ assert(string.tr("qwerty", "qwe", "_") == '_rty')
# the following should not crash
var s1 = 'A string of more than 128 bytes 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'
var s2 = string.format("%i, %s", 1, s1)
# replace
assert(string.replace("hello", "ll", "xx") == "hexxo")
assert(string.replace("hellollo", "ll", "xx") == "hexxoxxo")
assert(string.replace("hellollo", "aa", "xx") == "hellollo")
assert(string.replace("hello", "ll", "") == "heo")
assert(string.replace("hello", "", "xx") == "hello")
assert(string.replace("hello", "", "") == "hello")

View File

@ -32,9 +32,11 @@ assert_attribute_error(/-> t.c)
class T2 : T1
def member(n)
import undefined
if (n == 'f1') return / n -> n end
if (n == 'f2') return /-> 4 end
if (n == 'a1') return 10 end
if (n == 'h') return undefined end
end
end
t2 = T2()
@ -50,6 +52,7 @@ assert_attribute_error(/-> t2.h())
assert(t2.f1() == t2)
assert(t2.f2() == 4)
assert(t2.a1 == 10)
assert(t2.foo == nil)
#- module -#
m = module("m")
@ -59,8 +62,11 @@ assert(m.a == 1)
assert_attribute_error(/-> m.b)
m.member = def(n)
import undefined
if n == "b" return 2 end
if n == "c" return undefined end
end
assert(m.b == 2)
assert_attribute_error(/-> m.c)
assert(m.d == nil) #- returns nil if no response -#

View File

@ -1,4 +1,14 @@
#- virtual attributes -#
def assert_attribute_error(f)
try
f()
assert(false, 'unexpected execution flow')
except .. as e, m
assert(e == 'attribute_error')
end
end
class Ta
var a, b, virtual_c
def init()
@ -26,3 +36,4 @@ assert(ta.c == 3)
ta.c = 30
assert(ta.c == 30)
assert(ta.virtual_c == 30)
assert_attribute_error(def() ta.d = 0 end)

View File

@ -1,5 +1,4 @@
# python3 main.py -o out in
# coc
#! /usr/bin/env python3
import re
import os

View File

@ -17,7 +17,7 @@ func_body = '(' [arg_field {',' arg_field}] ')' block 'end';
arg_field = ['*'] ID;
(* class define statement *)
class_stmt = 'class' ID [':' ID] class_block 'end';
class_block = {'var' ID {',' ID} | 'static' ID ['=' expr] {',' ID ['=' expr] } | 'static' func_stmt | func_stmt};
class_block = {'var' ID {',' ID} | 'static' ['var'] ID ['=' expr] {',' ID ['=' expr] } | 'static' func_stmt | func_stmt};
import_stmt = 'import' (ID (['as' ID] | {',' ID}) | STRING 'as' ID);
(* exceptional handling statement *)
try_stmt = 'try' block except_block {except_block} 'end';
@ -28,12 +28,13 @@ throw_stmt = 'raise' expr [',' expr];
var_stmt = 'var' ID ['=' expr] {',' ID ['=' expr]};
(* expression define *)
expr_stmt = expr [assign_op expr];
expr = suffix_expr | unop expr | expr binop expr | cond_expr;
expr = suffix_expr | unop expr | expr binop expr | range_expr | cond_expr;
cond_expr = expr '?' expr ':' expr; (* conditional expression *)
assign_op = '=' | '+=' | '-=' | '*=' | '/=' |
'%=' | '&=' | '|=' | '^=' | '<<=' | '>>=';
binop = '..' | '<' | '<=' | '==' | '!=' | '>' | '>=' | '||' | '&&' |
binop = '<' | '<=' | '==' | '!=' | '>' | '>=' | '||' | '&&' |
'<<' | '>>' | '&' | '|' | '^' | '+' | '-' | '*' | '/' | '%';
range_expr = expr '..' [expr]
unop = '-' | '!' | '~';
suffix_expr = primary_expr {call_expr | ('.' ID) | '[' expr ']'};
primary_expr = '(' expr ')' | simple_expr | list_expr | map_expr | anon_func | lambda_expr;

View File

@ -0,0 +1,55 @@
/********************************************************************
* Tasmota lib
*
* To use: import ULP`
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
#include "esp32/ulp.h"
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
extern void be_ULP_run(int32_t entry);
BE_FUNC_CTYPE_DECLARE(be_ULP_run, "", "[i]");
extern void be_ULP_wake_up_period(int32_t period_index, int32_t period_us);
BE_FUNC_CTYPE_DECLARE(be_ULP_wake_up_period, "", "ii");
extern int32_t be_ULP_set_mem(int32_t pos, int32_t value);
BE_FUNC_CTYPE_DECLARE(be_ULP_set_mem, "i", "ii");
extern int32_t be_ULP_get_mem(int32_t pos);
BE_FUNC_CTYPE_DECLARE(be_ULP_get_mem, "i", "i");
extern int32_t be_ULP_gpio_init(gpio_num_t pin, rtc_gpio_mode_t mode);
BE_FUNC_CTYPE_DECLARE(be_ULP_gpio_init, "i", "ii");
extern void be_ULP_adc_config(struct bvm *vm, adc1_channel_t channel, adc_atten_t attenuation, adc_bits_width_t width);
BE_FUNC_CTYPE_DECLARE(be_ULP_adc_config, "", "@iii");
extern void be_ULP_sleep(int32_t wake_up_s);
BE_FUNC_CTYPE_DECLARE(be_ULP_sleep, "", "[i]"); // optional int arg
extern void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size);
BE_FUNC_CTYPE_DECLARE(be_ULP_load, "", "@(bytes)~"); // pass: 1/ vm, 2/ bytes point, 3/ bytes size
#include "be_fixed_ULP.h"
/* @const_object_info_begin
module ULP (scope: global) {
run, ctype_func(be_ULP_run)
load, ctype_func(be_ULP_load)
set_mem, ctype_func(be_ULP_set_mem)
get_mem, ctype_func(be_ULP_get_mem)
gpio_init, ctype_func(be_ULP_gpio_init)
wake_period, ctype_func(be_ULP_wake_up_period)
sleep, ctype_func(be_ULP_sleep)
adc_config, ctype_func(be_ULP_adc_config)
}
@const_object_info_end */
#endif // USE_BERRY_ULP

View File

@ -10,18 +10,24 @@
/*
def subscribe(topic, closure)
def _(action, topic, closure) # inner class for subscribe and unsubscribe
class mqtt_listener
var topic
var topic # topic as a list of subtopics
var fulltopic # fulltopic as string
var closure
def init(topic, closure)
import string
self.fulltopic = topic
self.topic = string.split(topic, '/')
self.closure = closure
tasmota.add_driver(self)
end
def remove()
tasmota.remove_driver(self)
end
def mqtt_data(topic, idx, payload_s, payload_b)
# check if the topic matches the patter
import string
@ -63,18 +69,151 @@ def subscribe(topic, closure)
end
import mqtt
mqtt._subscribe(topic)
if type(closure) == 'function'
tasmota.check_not_method(closure)
mqtt_listener(topic, closure)
if action
# subscribe
mqtt._subscribe(topic)
if type(closure) == 'function'
tasmota.check_not_method(closure)
mqtt_listener(topic, closure)
end
else
# unsubscribe
if topic != nil
mqtt._unsubscribe(topic)
end
# scan through drivers if any matches the topic
for d: tasmota._drivers.copy() # make a copy of the list since we might modify it on the fly
if isinstance(d, mqtt_listener)
# class of interest
# topic was specified
if topic != nil
if d.fulltopic == topic
d.remove()
end
else
# remove all topics
if d.fulltopic != topic # don't call again unsubscribe if we just did
mqtt._unsubscribe(d.fulltopic)
end
d.remove()
end
end
end
end
end
def subscribe(topic, closure)
import mqtt
mqtt._(true, topic, closure)
end
def unsubscribe(topic)
import mqtt
mqtt._(false, topic)
end
solidify.dump(_) solidify.dump(subscribe) solidify.dump(unsubscribe)
#-
# example
import mqtt
def p(a,b,c) print("mqtt",a,b,c) end
mqtt.subscribe("/a/b", p)
mqtt.subscribe("/a/b/c", p)
mqtt.subscribe("#", p)
print(">unsub /a/b")
mqtt.unsubscribe("/a/b")
print(">unsub all")
mqtt.unsubscribe()
-#
*/
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(mqtt_listener_init, /* name */
be_nested_proto(
8, /* nstack */
3, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 8]) { /* constants */
/* K0 */ be_nested_str(string),
/* K1 */ be_nested_str(fulltopic),
/* K2 */ be_nested_str(topic),
/* K3 */ be_nested_str(split),
/* K4 */ be_nested_str(_X2F),
/* K5 */ be_nested_str(closure),
/* K6 */ be_nested_str(tasmota),
/* K7 */ be_nested_str(add_driver),
}),
&be_const_str_init,
&be_const_str_solidified,
( &(const binstruction[13]) { /* code */
0xA40E0000, // 0000 IMPORT R3 K0
0x90020201, // 0001 SETMBR R0 K1 R1
0x8C100703, // 0002 GETMET R4 R3 K3
0x5C180200, // 0003 MOVE R6 R1
0x581C0004, // 0004 LDCONST R7 K4
0x7C100600, // 0005 CALL R4 3
0x90020404, // 0006 SETMBR R0 K2 R4
0x90020A02, // 0007 SETMBR R0 K5 R2
0xB8120C00, // 0008 GETNGBL R4 K6
0x8C100907, // 0009 GETMET R4 R4 K7
0x5C180000, // 000A MOVE R6 R0
0x7C100400, // 000B CALL R4 2
0x80000000, // 000C RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: remove
********************************************************************/
be_local_closure(mqtt_listener_remove, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(tasmota),
/* K1 */ be_nested_str(remove_driver),
}),
&be_const_str_remove,
&be_const_str_solidified,
( &(const binstruction[ 5]) { /* code */
0xB8060000, // 0000 GETNGBL R1 K0
0x8C040301, // 0001 GETMET R1 R1 K1
0x5C0C0000, // 0002 MOVE R3 R0
0x7C040400, // 0003 CALL R1 2
0x80000000, // 0004 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: mqtt_data
********************************************************************/
@ -162,70 +301,128 @@ be_local_closure(mqtt_listener_mqtt_data, /* name */
/********************************************************************
** Solidified function: init
** Solidified class: mqtt_listener
********************************************************************/
be_local_closure(mqtt_listener_init, /* name */
be_local_class(mqtt_listener,
3,
NULL,
be_nested_map(6,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(remove, -1), be_const_closure(mqtt_listener_remove_closure) },
{ be_const_key(mqtt_data, -1), be_const_closure(mqtt_listener_mqtt_data_closure) },
{ be_const_key(topic, -1), be_const_var(0) },
{ be_const_key(init, 0), be_const_closure(mqtt_listener_init_closure) },
{ be_const_key(closure, 1), be_const_var(2) },
{ be_const_key(fulltopic, -1), be_const_var(1) },
})),
(bstring*) &be_const_str_mqtt_listener
);
/********************************************************************
** Solidified function: _
********************************************************************/
be_local_closure(_, /* name */
be_nested_proto(
8, /* nstack */
10, /* nstack */
3, /* argc */
2, /* varg */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 7]) { /* constants */
/* K0 */ be_nested_str(string),
/* K1 */ be_nested_str(topic),
/* K2 */ be_nested_str(split),
/* K3 */ be_nested_str(_X2F),
/* K4 */ be_nested_str(closure),
/* K5 */ be_nested_str(tasmota),
/* K6 */ be_nested_str(add_driver),
( &(const bvalue[12]) { /* constants */
/* K0 */ be_const_class(be_class_mqtt_listener),
/* K1 */ be_nested_str(mqtt),
/* K2 */ be_nested_str(_subscribe),
/* K3 */ be_nested_str(function),
/* K4 */ be_nested_str(tasmota),
/* K5 */ be_nested_str(check_not_method),
/* K6 */ be_nested_str(_unsubscribe),
/* K7 */ be_nested_str(_drivers),
/* K8 */ be_nested_str(copy),
/* K9 */ be_nested_str(fulltopic),
/* K10 */ be_nested_str(remove),
/* K11 */ be_nested_str(stop_iteration),
}),
&be_const_str_init,
&be_const_str__,
&be_const_str_solidified,
( &(const binstruction[12]) { /* code */
0xA40E0000, // 0000 IMPORT R3 K0
0x8C100702, // 0001 GETMET R4 R3 K2
0x5C180200, // 0002 MOVE R6 R1
0x581C0003, // 0003 LDCONST R7 K3
0x7C100600, // 0004 CALL R4 3
0x90020204, // 0005 SETMBR R0 K1 R4
0x90020802, // 0006 SETMBR R0 K4 R2
0xB8120A00, // 0007 GETNGBL R4 K5
0x8C100906, // 0008 GETMET R4 R4 K6
0x5C180000, // 0009 MOVE R6 R0
0x7C100400, // 000A CALL R4 2
0x80000000, // 000B RET 0
( &(const binstruction[63]) { /* code */
0x580C0000, // 0000 LDCONST R3 K0
0xB4000000, // 0001 CLASS K0
0xA4120200, // 0002 IMPORT R4 K1
0x78020010, // 0003 JMPF R0 #0015
0x8C140902, // 0004 GETMET R5 R4 K2
0x5C1C0200, // 0005 MOVE R7 R1
0x7C140400, // 0006 CALL R5 2
0x60140004, // 0007 GETGBL R5 G4
0x5C180400, // 0008 MOVE R6 R2
0x7C140200, // 0009 CALL R5 1
0x1C140B03, // 000A EQ R5 R5 K3
0x78160007, // 000B JMPF R5 #0014
0xB8160800, // 000C GETNGBL R5 K4
0x8C140B05, // 000D GETMET R5 R5 K5
0x5C1C0400, // 000E MOVE R7 R2
0x7C140400, // 000F CALL R5 2
0x5C140600, // 0010 MOVE R5 R3
0x5C180200, // 0011 MOVE R6 R1
0x5C1C0400, // 0012 MOVE R7 R2
0x7C140400, // 0013 CALL R5 2
0x70020028, // 0014 JMP #003E
0x4C140000, // 0015 LDNIL R5
0x20140205, // 0016 NE R5 R1 R5
0x78160002, // 0017 JMPF R5 #001B
0x8C140906, // 0018 GETMET R5 R4 K6
0x5C1C0200, // 0019 MOVE R7 R1
0x7C140400, // 001A CALL R5 2
0x60140010, // 001B GETGBL R5 G16
0xB81A0800, // 001C GETNGBL R6 K4
0x88180D07, // 001D GETMBR R6 R6 K7
0x8C180D08, // 001E GETMET R6 R6 K8
0x7C180200, // 001F CALL R6 1
0x7C140200, // 0020 CALL R5 1
0xA8020018, // 0021 EXBLK 0 #003B
0x5C180A00, // 0022 MOVE R6 R5
0x7C180000, // 0023 CALL R6 0
0x601C000F, // 0024 GETGBL R7 G15
0x5C200C00, // 0025 MOVE R8 R6
0x5C240600, // 0026 MOVE R9 R3
0x7C1C0400, // 0027 CALL R7 2
0x781E0010, // 0028 JMPF R7 #003A
0x4C1C0000, // 0029 LDNIL R7
0x201C0207, // 002A NE R7 R1 R7
0x781E0005, // 002B JMPF R7 #0032
0x881C0D09, // 002C GETMBR R7 R6 K9
0x1C1C0E01, // 002D EQ R7 R7 R1
0x781E0001, // 002E JMPF R7 #0031
0x8C1C0D0A, // 002F GETMET R7 R6 K10
0x7C1C0200, // 0030 CALL R7 1
0x70020007, // 0031 JMP #003A
0x881C0D09, // 0032 GETMBR R7 R6 K9
0x201C0E01, // 0033 NE R7 R7 R1
0x781E0002, // 0034 JMPF R7 #0038
0x8C1C0906, // 0035 GETMET R7 R4 K6
0x88240D09, // 0036 GETMBR R9 R6 K9
0x7C1C0400, // 0037 CALL R7 2
0x8C1C0D0A, // 0038 GETMET R7 R6 K10
0x7C1C0200, // 0039 CALL R7 1
0x7001FFE6, // 003A JMP #0022
0x5814000B, // 003B LDCONST R5 K11
0xAC140200, // 003C CATCH R5 1 0
0xB0080000, // 003D RAISE 2 R0 R0
0x80000000, // 003E RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: mqtt_listener
********************************************************************/
be_local_class(mqtt_listener,
2,
NULL,
be_nested_map(4,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(topic, 1), be_const_var(0) },
{ be_const_key(mqtt_data, -1), be_const_closure(mqtt_listener_mqtt_data_closure) },
{ be_const_key(closure, -1), be_const_var(1) },
{ be_const_key(init, -1), be_const_closure(mqtt_listener_init_closure) },
})),
(bstring*) &be_const_str_mqtt_listener
);
/********************************************************************
** Solidified function: subscribe
********************************************************************/
be_local_closure(subscribe, /* name */
be_nested_proto(
7, /* nstack */
8, /* nstack */
2, /* argc */
0, /* varg */
0, /* has upvals */
@ -233,43 +430,57 @@ be_local_closure(subscribe, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 6]) { /* constants */
/* K0 */ be_const_class(be_class_mqtt_listener),
/* K1 */ be_nested_str(mqtt),
/* K2 */ be_nested_str(_subscribe),
/* K3 */ be_nested_str(function),
/* K4 */ be_nested_str(tasmota),
/* K5 */ be_nested_str(check_not_method),
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(mqtt),
/* K1 */ be_nested_str(_),
}),
&be_const_str_subscribe,
&be_const_str_solidified,
( &(const binstruction[20]) { /* code */
0x58080000, // 0000 LDCONST R2 K0
0xB4000000, // 0001 CLASS K0
0xA40E0200, // 0002 IMPORT R3 K1
0x8C100702, // 0003 GETMET R4 R3 K2
0x5C180000, // 0004 MOVE R6 R0
0x7C100400, // 0005 CALL R4 2
0x60100004, // 0006 GETGBL R4 G4
0x5C140200, // 0007 MOVE R5 R1
0x7C100200, // 0008 CALL R4 1
0x1C100903, // 0009 EQ R4 R4 K3
0x78120007, // 000A JMPF R4 #0013
0xB8120800, // 000B GETNGBL R4 K4
0x8C100905, // 000C GETMET R4 R4 K5
0x5C180200, // 000D MOVE R6 R1
0x7C100400, // 000E CALL R4 2
0x5C100400, // 000F MOVE R4 R2
0x5C140000, // 0010 MOVE R5 R0
0x5C180200, // 0011 MOVE R6 R1
0x7C100400, // 0012 CALL R4 2
0x80000000, // 0013 RET 0
( &(const binstruction[ 7]) { /* code */
0xA40A0000, // 0000 IMPORT R2 K0
0x8C0C0501, // 0001 GETMET R3 R2 K1
0x50140200, // 0002 LDBOOL R5 1 0
0x5C180000, // 0003 MOVE R6 R0
0x5C1C0200, // 0004 MOVE R7 R1
0x7C0C0800, // 0005 CALL R3 4
0x80000000, // 0006 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: unsubscribe
********************************************************************/
be_local_closure(unsubscribe, /* name */
be_nested_proto(
6, /* nstack */
1, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(mqtt),
/* K1 */ be_nested_str(_),
}),
&be_const_str_unsubscribe,
&be_const_str_solidified,
( &(const binstruction[ 6]) { /* code */
0xA4060000, // 0000 IMPORT R1 K0
0x8C080301, // 0001 GETMET R2 R1 K1
0x50100000, // 0002 LDBOOL R4 0 0
0x5C140000, // 0003 MOVE R5 R0
0x7C080600, // 0004 CALL R2 3
0x80000000, // 0005 RET 0
})
)
);
/*******************************************************************/
extern int be_mqtt_publish(bvm *vm);
@ -281,8 +492,10 @@ extern void be_mqtt_unsubscribe(const char* topic); BE_FUNC_CTYPE_DECLARE(be_m
module mqtt (scope: global) {
publish, func(be_mqtt_publish)
subscribe, closure(subscribe_closure)
unsubscribe, closure(unsubscribe_closure)
_, closure(__closure)
_subscribe, ctype_func(be_mqtt_subscribe)
unsubscribe, ctype_func(be_mqtt_unsubscribe)
_unsubscribe, ctype_func(be_mqtt_unsubscribe)
}
@const_object_info_end */
#include "be_fixed_mqtt.h"

View File

@ -735,6 +735,47 @@ be_local_closure(Tasmota_add_fast_loop, /* name */
);
/*******************************************************************/
/********************************************************************
** Solidified function: remove_fast_loop
********************************************************************/
be_local_closure(Tasmota_remove_fast_loop, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str(_fl),
/* K1 */ be_nested_str(find),
/* K2 */ be_nested_str(remove),
}),
&be_const_str_remove_fast_loop,
&be_const_str_solidified,
( &(const binstruction[15]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x740A0000, // 0001 JMPT R2 #0003
0x80000400, // 0002 RET 0
0x88080100, // 0003 GETMBR R2 R0 K0
0x8C080501, // 0004 GETMET R2 R2 K1
0x5C100200, // 0005 MOVE R4 R1
0x7C080400, // 0006 CALL R2 2
0x4C0C0000, // 0007 LDNIL R3
0x200C0403, // 0008 NE R3 R2 R3
0x780E0003, // 0009 JMPF R3 #000E
0x880C0100, // 000A GETMBR R3 R0 K0
0x8C0C0702, // 000B GETMET R3 R3 K2
0x5C140400, // 000C MOVE R5 R2
0x7C0C0400, // 000D CALL R3 2
0x80000000, // 000E RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: event
@ -2621,6 +2662,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
fast_loop, closure(Tasmota_fast_loop_closure)
add_fast_loop, closure(Tasmota_add_fast_loop_closure)
remove_fast_loop, closure(Tasmota_remove_fast_loop_closure)
cmd, closure(Tasmota_cmd_closure)
chars_in_string, closure(Tasmota_chars_in_string_closure)
find_key_i, closure(Tasmota_find_key_i_closure)

View File

@ -30,7 +30,7 @@ void be_load_tcpclient_lib(bvm *vm) {
/* @const_object_info_begin
class be_class_tcpclient (scope: global, name: tcpclient) {
.w, var
.p, var
init, func(wc_tcp_init)
deinit, func(wc_tcp_deinit)

View File

@ -0,0 +1,32 @@
/********************************************************************
* Tcp socket
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#include "be_ctypes.h"
#ifdef USE_BERRY_TCPSERVER
extern const void * tcpserver_init(struct bvm *vm, int32_t port); BE_FUNC_CTYPE_DECLARE(tcpserver_init, "+_p", "@i")
extern void tcpserver_deinit(void *server_tcp); BE_FUNC_CTYPE_DECLARE(tcpserver_deinit, "", ".")
extern void tcpserver_close(void *server); BE_FUNC_CTYPE_DECLARE(tcpserver_close, "", ".")
extern bbool tcpserver_hasclient(void *server); BE_FUNC_CTYPE_DECLARE(tcpserver_hasclient, "b", ".")
extern void * tcpserver_accept(struct bvm *vm, void *server); BE_FUNC_CTYPE_DECLARE(tcpserver_accept, "tcpclient", "@.")
#include "be_fixed_be_class_tcpserver.h"
/* @const_object_info_begin
class be_class_tcpserver (scope: global, name: tcpserver) {
_p, var
init, ctype_func(tcpserver_init)
deinit, ctype_func(tcpserver_deinit)
close, ctype_func(tcpserver_close)
hasclient, ctype_func(tcpserver_hasclient)
accept, ctype_func(tcpserver_accept)
}
@const_object_info_end */
#endif // USE_BERRY_TCPSERVER

View File

@ -628,6 +628,14 @@ class Tasmota
self._fl.push(cl)
end
def remove_fast_loop(cl)
if !self._fl return end
var idx = self._fl.find(cl)
if idx != nil
self._fl.remove(idx)
end
end
def event(event_type, cmd, idx, payload, raw)
import introspect
import string

View File

@ -70,6 +70,7 @@
#include "driver/ledc.h"
#include "sensor.h"
#include "sys/time.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
@ -91,6 +92,19 @@ typedef enum {
CAMERA_FB_IN_DRAM /*!< Frame buffer is placed in internal DRAM */
} camera_fb_location_t;
#if CONFIG_CAMERA_CONVERTER_ENABLED
/**
* @brief Camera RGB\YUV conversion mode
*/
typedef enum {
CONV_DISABLE,
RGB565_TO_YUV422,
YUV422_TO_RGB565,
YUV422_TO_YUV420
} camera_conv_mode_t;
#endif
/**
* @brief Configuration structure for camera initialization
*/
@ -124,6 +138,9 @@ typedef struct {
size_t fb_count; /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed) */
camera_fb_location_t fb_location; /*!< The location where the frame buffer will be allocated */
camera_grab_mode_t grab_mode; /*!< When buffers should be filled */
#if CONFIG_CAMERA_CONVERTER_ENABLED
camera_conv_mode_t conv_mode; /*!< RGB<->YUV Conversion mode */
#endif
} camera_config_t;
/**

View File

@ -26,6 +26,10 @@ typedef enum {
GC2145_PID = 0x2145,
GC032A_PID = 0x232a,
GC0308_PID = 0x9b,
BF3005_PID = 0x30,
BF20A6_PID = 0x20a6,
SC101IOT_PID = 0xda4a,
SC030IOT_PID = 0x9a46,
} camera_pid_t;
typedef enum {
@ -38,6 +42,10 @@ typedef enum {
CAMERA_GC2145,
CAMERA_GC032A,
CAMERA_GC0308,
CAMERA_BF3005,
CAMERA_BF20A6,
CAMERA_SC101IOT,
CAMERA_SC030IOT,
CAMERA_MODEL_MAX,
CAMERA_NONE,
} camera_model_t;
@ -52,11 +60,16 @@ typedef enum {
GC2145_SCCB_ADDR = 0x3C,// 0x78 >> 1
GC032A_SCCB_ADDR = 0x21,// 0x42 >> 1
GC0308_SCCB_ADDR = 0x21,// 0x42 >> 1
BF3005_SCCB_ADDR = 0x6E,
BF20A6_SCCB_ADDR = 0x6E,
SC101IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
SC030IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
} camera_sccb_addr_t;
typedef enum {
PIXFORMAT_RGB565, // 2BPP/RGB565
PIXFORMAT_YUV422, // 2BPP/YUV422
PIXFORMAT_YUV420, // 1.5BPP/YUV420
PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
PIXFORMAT_JPEG, // JPEG/COMPRESSED
PIXFORMAT_RGB888, // 3BPP/RGB888

View File

@ -1,12 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ["https://www.paypal.me/mobizt"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ["https://www.paypal.me/mobizt"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -1,17 +1,17 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 20
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 5
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 20
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 5
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -1,21 +1,21 @@
MIT License
Copyright (c) 2021 mobizt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
MIT License
Copyright (c) 2021 mobizt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

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