mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 12:46:34 +00:00
Compare commits
261 Commits
developmen
...
v14.0.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d8c53d48d1 | ||
![]() |
ba2ad90384 | ||
![]() |
e23fadf0f6 | ||
![]() |
103860f394 | ||
![]() |
4111b7883b | ||
![]() |
45d3124602 | ||
![]() |
a3fb17b4f1 | ||
![]() |
983694cc2b | ||
![]() |
ba58271219 | ||
![]() |
133cc25bdb | ||
![]() |
05e2444e6a | ||
![]() |
e617328051 | ||
![]() |
99e44a10af | ||
![]() |
3648ce5fda | ||
![]() |
8a08895110 | ||
![]() |
e6515883f0 | ||
![]() |
fb904a0610 | ||
![]() |
ff3e3e9360 | ||
![]() |
81c4e518a0 | ||
![]() |
2efefeb8a7 | ||
![]() |
2d97311c5c | ||
![]() |
01bb287436 | ||
![]() |
ed5d74a4f9 | ||
![]() |
41bd8bcd79 | ||
![]() |
9671d87b19 | ||
![]() |
5a7a82e975 | ||
![]() |
383855e1c1 | ||
![]() |
a435ec84b4 | ||
![]() |
654f4200a1 | ||
![]() |
0ced0c26e9 | ||
![]() |
bf5c886ee0 | ||
![]() |
80bf7e53cc | ||
![]() |
27e8617040 | ||
![]() |
bed113fd79 | ||
![]() |
91c635abc3 | ||
![]() |
34d15036e6 | ||
![]() |
04cff5fbff | ||
![]() |
6c65ac8d81 | ||
![]() |
e9e3b03dbb | ||
![]() |
ea592b918f | ||
![]() |
3f43db93f0 | ||
![]() |
8e820e90c6 | ||
![]() |
ca3045f68f | ||
![]() |
fbbf8ff781 | ||
![]() |
dafa28f8ba | ||
![]() |
669d016560 | ||
![]() |
4acd5d82e4 | ||
![]() |
f15971d9d3 | ||
![]() |
431e32b42b | ||
![]() |
e1a725f564 | ||
![]() |
e8edf976da | ||
![]() |
ac731d08fb | ||
![]() |
ae12ce727f | ||
![]() |
616c6859e3 | ||
![]() |
1507a51f64 | ||
![]() |
dce90f30d7 | ||
![]() |
6a9c3bf3e5 | ||
![]() |
0cb5edd2e0 | ||
![]() |
23cbdb93b0 | ||
![]() |
3919668fc5 | ||
![]() |
f7d227c280 | ||
![]() |
1e86a9a8cf | ||
![]() |
ac8a886988 | ||
![]() |
b07f6994c7 | ||
![]() |
4fb3d9cb41 | ||
![]() |
34f441ce7d | ||
![]() |
7b0c5e8adb | ||
![]() |
4135a4607d | ||
![]() |
98a100d0ab | ||
![]() |
e71235ea3a | ||
![]() |
930e659915 | ||
![]() |
8d52722941 | ||
![]() |
ca10e7b909 | ||
![]() |
806c5762bc | ||
![]() |
f5b2216361 | ||
![]() |
dfa2c25c03 | ||
![]() |
eed11319ac | ||
![]() |
e5310ad6e5 | ||
![]() |
9eb42b41d0 | ||
![]() |
4074d82ac7 | ||
![]() |
dc1605f96a | ||
![]() |
4ff60deafc | ||
![]() |
24757be59e | ||
![]() |
b44a87a3d8 | ||
![]() |
7bc7be56ee | ||
![]() |
fa03edbeb4 | ||
![]() |
c9cd367e53 | ||
![]() |
1cdd2be008 | ||
![]() |
d157b1c5e0 | ||
![]() |
ffc2352cd6 | ||
![]() |
41f7580210 | ||
![]() |
6e2592fe02 | ||
![]() |
0b25206f90 | ||
![]() |
4f2a59d27d | ||
![]() |
0cbc1681d2 | ||
![]() |
00227a45c6 | ||
![]() |
e8988e4b31 | ||
![]() |
64ea803ef1 | ||
![]() |
078fb0ea3a | ||
![]() |
efc2f54610 | ||
![]() |
942ebe1cf4 | ||
![]() |
c22d936f8c | ||
![]() |
a955827db9 | ||
![]() |
f09d6b5452 | ||
![]() |
9dd05501a8 | ||
![]() |
5254a26145 | ||
![]() |
02659ff1a5 | ||
![]() |
50f0101e59 | ||
![]() |
1ee598cefd | ||
![]() |
0c22b69bd0 | ||
![]() |
5057314977 | ||
![]() |
71c146ab35 | ||
![]() |
e5d576b507 | ||
![]() |
329d76346f | ||
![]() |
6d5227ba75 | ||
![]() |
0ccf7de945 | ||
![]() |
8c4ab12e9a | ||
![]() |
6decedbb31 | ||
![]() |
8d61740a9f | ||
![]() |
388db0e795 | ||
![]() |
d696c00d3f | ||
![]() |
1e3bc9f8be | ||
![]() |
b3a1fa99f2 | ||
![]() |
d7847061b9 | ||
![]() |
e2a8e39646 | ||
![]() |
9482079573 | ||
![]() |
f100430125 | ||
![]() |
c1d61c9eb0 | ||
![]() |
e96ce2f637 | ||
![]() |
838ab4f553 | ||
![]() |
cbc74ab873 | ||
![]() |
92994455c4 | ||
![]() |
1fe0160ef6 | ||
![]() |
15b75422b5 | ||
![]() |
1b40bfb336 | ||
![]() |
aacb37ecfc | ||
![]() |
9ac9e0460a | ||
![]() |
6f03368c85 | ||
![]() |
330a12efe4 | ||
![]() |
fab0cd88c2 | ||
![]() |
ed23cd8d95 | ||
![]() |
7defc325f1 | ||
![]() |
30cbc1b1e5 | ||
![]() |
61adb53da6 | ||
![]() |
9e008008c3 | ||
![]() |
f5d1594a6b | ||
![]() |
80d72ecbf5 | ||
![]() |
0150c9e809 | ||
![]() |
7e532a87f9 | ||
![]() |
4052903810 | ||
![]() |
04c1262bc2 | ||
![]() |
851c839c53 | ||
![]() |
c88152c14e | ||
![]() |
08fa219a88 | ||
![]() |
adbb5f8d53 | ||
![]() |
71268e5aae | ||
![]() |
9f21938c2c | ||
![]() |
ebb998ea06 | ||
![]() |
e6e00c80cc | ||
![]() |
7e3b7ddc69 | ||
![]() |
31c6075a84 | ||
![]() |
92c0eb000f | ||
![]() |
3f7071c6b9 | ||
![]() |
cabe894933 | ||
![]() |
b6f283d8d8 | ||
![]() |
5e3c1b6415 | ||
![]() |
96d4e60680 | ||
![]() |
488edab49c | ||
![]() |
45cd73940d | ||
![]() |
25033908cd | ||
![]() |
b75520cde9 | ||
![]() |
3374990115 | ||
![]() |
2b34c6843a | ||
![]() |
e7a27893b3 | ||
![]() |
d37b9db08d | ||
![]() |
c74c0d9d10 | ||
![]() |
4cc0f05cb1 | ||
![]() |
ec14623169 | ||
![]() |
dc73b67a61 | ||
![]() |
fa0e8867af | ||
![]() |
6afb2767f7 | ||
![]() |
6cb9b3ce80 | ||
![]() |
39f31d8cdf | ||
![]() |
e1d44b9dfa | ||
![]() |
0c36bcb25c | ||
![]() |
0489d3fc9a | ||
![]() |
3ba19e1552 | ||
![]() |
08ec5cecda | ||
![]() |
0d505baa0e | ||
![]() |
fd6a9fdc90 | ||
![]() |
386dbbd878 | ||
![]() |
797f82dc27 | ||
![]() |
c09f966f41 | ||
![]() |
829397f4ed | ||
![]() |
198ec55473 | ||
![]() |
1c24df6df8 | ||
![]() |
83f76e2432 | ||
![]() |
fa8a6bc0e5 | ||
![]() |
603f08291a | ||
![]() |
ae793c8f2d | ||
![]() |
556156f73f | ||
![]() |
e035bdb71f | ||
![]() |
16ffdb6f49 | ||
![]() |
76decfaa43 | ||
![]() |
b369e87385 | ||
![]() |
4f92d4984f | ||
![]() |
68f8ea6f39 | ||
![]() |
1838c582b3 | ||
![]() |
8255468f9c | ||
![]() |
e217ab49d9 | ||
![]() |
a73b2d1e09 | ||
![]() |
584ae41cb7 | ||
![]() |
e076b50dfc | ||
![]() |
e1df24be17 | ||
![]() |
b1782f32ca | ||
![]() |
61d6a1240b | ||
![]() |
c987f4357e | ||
![]() |
ed50401812 | ||
![]() |
ec4bc1fb98 | ||
![]() |
4c906a794a | ||
![]() |
20d545e873 | ||
![]() |
e84bbe9e64 | ||
![]() |
43b0831cb2 | ||
![]() |
92766df1a5 | ||
![]() |
8bac4981ea | ||
![]() |
a89f208da0 | ||
![]() |
3041f9dccb | ||
![]() |
fe3f705448 | ||
![]() |
33a44f7a39 | ||
![]() |
efd4a6b542 | ||
![]() |
69765f5706 | ||
![]() |
3195ce7b14 | ||
![]() |
b59a8a7966 | ||
![]() |
da704f4ecb | ||
![]() |
f14f1d7798 | ||
![]() |
99feefba84 | ||
![]() |
9a3307a73f | ||
![]() |
5b3d673dea | ||
![]() |
fddc15db70 | ||
![]() |
04263f3969 | ||
![]() |
e66f17c6bb | ||
![]() |
f10257fd29 | ||
![]() |
ae2c50cbe4 | ||
![]() |
c6b02fb1e1 | ||
![]() |
b5fb079228 | ||
![]() |
7e5f3aa006 | ||
![]() |
0fa559d143 | ||
![]() |
f2f8b5efa9 | ||
![]() |
11d37cc15b | ||
![]() |
99b15fe056 | ||
![]() |
19836d1136 | ||
![]() |
3e4975831a | ||
![]() |
cc8ae7c7a7 | ||
![]() |
10f2d17a5a | ||
![]() |
1198246572 | ||
![]() |
7138ddd80a | ||
![]() |
27bcc29421 | ||
![]() |
4c7283c292 | ||
![]() |
257f3d2808 | ||
![]() |
5e4c5f67e6 | ||
![]() |
4dab991d09 |
File diff suppressed because it is too large
Load Diff
@ -1,704 +0,0 @@
|
|||||||
# Berry for Tasmota
|
|
||||||
|
|
||||||
This document covers Tasmota-specific Berry features and extensions, complementing the general Berry language reference.
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
Berry is the next generation scripting language for Tasmota, embedded by default in all ESP32 based firmwares (NOT supported on ESP8266). It is used for advanced scripting, superseding Rules, and enables building drivers, automations, and UI extensions.
|
|
||||||
|
|
||||||
## Tasmota-Specific Modules
|
|
||||||
|
|
||||||
Beyond standard Berry modules, Tasmota provides additional modules:
|
|
||||||
|
|
||||||
| Module | Description | Import |
|
|
||||||
|--------|-------------|--------|
|
|
||||||
| `tasmota` | Core integration module | Automatically imported |
|
|
||||||
| `light` | Light control | Automatically imported |
|
|
||||||
| `mqtt` | MQTT operations | `import mqtt` |
|
|
||||||
| `webserver` | Web server extensions | `import webserver` |
|
|
||||||
| `gpio` | GPIO control | `import gpio` |
|
|
||||||
| `persist` | Data persistence | `import persist` |
|
|
||||||
| `path` | File system operations | `import path` |
|
|
||||||
| `energy` | Energy monitoring | Automatically imported |
|
|
||||||
| `display` | Display driver integration | `import display` |
|
|
||||||
| `crypto` | Cryptographic functions | `import crypto` |
|
|
||||||
| `re` | Regular expressions | `import re` |
|
|
||||||
| `mdns` | mDNS/Bonjour support | `import mdns` |
|
|
||||||
| `ULP` | Ultra Low Power coprocessor | `import ULP` |
|
|
||||||
| `uuid` | UUID generation | `import uuid` |
|
|
||||||
| `crc` | CRC calculations | `import crc` |
|
|
||||||
|
|
||||||
## Additional Resources
|
|
||||||
|
|
||||||
For Tasmota-specific Berry features and extensions, please refer to the companion document `BERRY_TASMOTA.md`.
|
|
||||||
|
|
||||||
### Tasmota Constants and Enums
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# GPIO constants (gpio module)
|
|
||||||
gpio.INPUT, gpio.OUTPUT, gpio.PULLUP, gpio.PULLDOWN
|
|
||||||
gpio.HIGH, gpio.LOW
|
|
||||||
gpio.REL1, gpio.KEY1, gpio.LED1, gpio.I2C_SCL, gpio.I2C_SDA
|
|
||||||
# ... many more GPIO function constants
|
|
||||||
|
|
||||||
# Serial constants
|
|
||||||
serial.SERIAL_8N1, serial.SERIAL_7E1, etc.
|
|
||||||
|
|
||||||
# Webserver constants
|
|
||||||
webserver.HTTP_GET, webserver.HTTP_POST, webserver.HTTP_OPTIONS, webserver.HTTP_ANY
|
|
||||||
webserver.HTTP_OFF, webserver.HTTP_USER, webserver.HTTP_ADMIN, webserver.HTTP_MANAGER
|
|
||||||
webserver.HTTP_MANAGER_RESET_ONLY
|
|
||||||
webserver.BUTTON_MAIN, webserver.BUTTON_CONFIGURATION, webserver.BUTTON_INFORMATION
|
|
||||||
webserver.BUTTON_MANAGEMENT, webserver.BUTTON_MODULE
|
|
||||||
```
|
|
||||||
|
|
||||||
### Console and REPL
|
|
||||||
|
|
||||||
Access Berry console via *Configuration* → *Berry Scripting Console*. The console supports:
|
|
||||||
- Multi-line input (press Enter twice or click "Run")
|
|
||||||
- Command history (arrow keys)
|
|
||||||
- Colorful syntax highlighting
|
|
||||||
- Berry VM restart with `BrRestart` command
|
|
||||||
|
|
||||||
### File System and Loading
|
|
||||||
|
|
||||||
Berry files can be source (`.be`) or pre-compiled bytecode (`.bec`):
|
|
||||||
|
|
||||||
```berry
|
|
||||||
load("filename") # Loads .be or .bec file
|
|
||||||
tasmota.compile("file.be") # Compiles .be to .bec
|
|
||||||
```
|
|
||||||
|
|
||||||
**Autostart**: Place `autoexec.be` in filesystem to run Berry code at boot.
|
|
||||||
|
|
||||||
### Tasmota Integration Functions
|
|
||||||
|
|
||||||
#### Core Tasmota Functions
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# System information
|
|
||||||
tasmota.get_free_heap() # Free heap bytes
|
|
||||||
tasmota.memory() # Memory stats map
|
|
||||||
tasmota.arch() # Architecture: "esp32", "esp32s2", etc.
|
|
||||||
tasmota.millis() # Milliseconds since boot
|
|
||||||
tasmota.yield() # Give time to low-level functions
|
|
||||||
tasmota.delay(ms) # Block execution for ms milliseconds
|
|
||||||
|
|
||||||
# Commands and responses
|
|
||||||
tasmota.cmd("command") # Execute Tasmota command
|
|
||||||
tasmota.resp_cmnd_done() # Respond "Done"
|
|
||||||
tasmota.resp_cmnd_error() # Respond "Error"
|
|
||||||
tasmota.resp_cmnd_str(msg) # Custom response string
|
|
||||||
tasmota.resp_cmnd(json) # Custom JSON response
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
tasmota.get_option(index) # Get SetOption value
|
|
||||||
tasmota.read_sensors() # Get sensor JSON string
|
|
||||||
tasmota.wifi() # WiFi connection info
|
|
||||||
tasmota.eth() # Ethernet connection info
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Rules and Events
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Add rules (similar to Tasmota Rules but more powerful)
|
|
||||||
tasmota.add_rule("trigger", function)
|
|
||||||
tasmota.add_rule(["trigger1", "trigger2"], function) # AND logic
|
|
||||||
tasmota.remove_rule("trigger")
|
|
||||||
|
|
||||||
# Rule function signature
|
|
||||||
def rule_function(value, trigger, msg)
|
|
||||||
# value: trigger value (%value% equivalent)
|
|
||||||
# trigger: full trigger string
|
|
||||||
# msg: parsed JSON map or original string
|
|
||||||
end
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
tasmota.add_rule("Dimmer>50", def() print("Bright!") end)
|
|
||||||
tasmota.add_rule("ANALOG#A1>300", def(val) print("ADC:", val) end)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Timers and Scheduling
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Timers (50ms resolution)
|
|
||||||
tasmota.set_timer(delay_ms, function)
|
|
||||||
tasmota.remove_timer(id)
|
|
||||||
tasmota.defer(function) # Run in next millisecond
|
|
||||||
|
|
||||||
# Cron scheduling
|
|
||||||
tasmota.add_cron("*/15 * * * * *", function, "id")
|
|
||||||
tasmota.remove_cron("id")
|
|
||||||
tasmota.next_cron("id") # Next execution timestamp
|
|
||||||
|
|
||||||
# Time functions
|
|
||||||
tasmota.rtc() # Current time info
|
|
||||||
tasmota.time_dump(timestamp) # Decompose timestamp
|
|
||||||
tasmota.time_str(timestamp) # ISO 8601 string
|
|
||||||
tasmota.strftime(format, timestamp)
|
|
||||||
tasmota.strptime(time_str, format)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Device Control
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Relays and Power
|
|
||||||
tasmota.get_power() # Array of relay states
|
|
||||||
tasmota.set_power(idx, state) # Set relay state
|
|
||||||
|
|
||||||
# Lights (use light module)
|
|
||||||
light.get() # Current light status
|
|
||||||
light.set({"power": true, "bri": 128, "hue": 120})
|
|
||||||
|
|
||||||
# Light attributes: power, bri (0-255), hue (0-360), sat (0-255),
|
|
||||||
# ct (153-500), rgb (hex string), channels (array)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Custom Commands
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Add custom Tasmota commands
|
|
||||||
def my_command(cmd, idx, payload, payload_json)
|
|
||||||
# cmd: command name, idx: command index
|
|
||||||
# payload: raw string, payload_json: parsed JSON
|
|
||||||
tasmota.resp_cmnd_done()
|
|
||||||
end
|
|
||||||
|
|
||||||
tasmota.add_cmd("MyCmd", my_command)
|
|
||||||
tasmota.remove_cmd("MyCmd")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tasmota Drivers
|
|
||||||
|
|
||||||
Create complete Tasmota drivers by implementing event methods:
|
|
||||||
|
|
||||||
```berry
|
|
||||||
class MyDriver
|
|
||||||
def every_second() # Called every second
|
|
||||||
end
|
|
||||||
|
|
||||||
def every_50ms() # Called every 50ms
|
|
||||||
end
|
|
||||||
|
|
||||||
def web_sensor() # Add to web UI
|
|
||||||
tasmota.web_send("{s}Sensor{m}Value{e}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def json_append() # Add to JSON teleperiod
|
|
||||||
tasmota.response_append(',"MySensor":{"Value":123}')
|
|
||||||
end
|
|
||||||
|
|
||||||
def web_add_main_button() # Add button to main page
|
|
||||||
import webserver
|
|
||||||
webserver.content_send("<button onclick='la(\"&myaction=1\");'>My Button</button>")
|
|
||||||
end
|
|
||||||
|
|
||||||
def button_pressed() # Handle button press
|
|
||||||
end
|
|
||||||
|
|
||||||
def mqtt_data(topic, idx, data, databytes) # Handle MQTT
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_before_restart() # Before restart
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Register driver
|
|
||||||
driver = MyDriver()
|
|
||||||
tasmota.add_driver(driver)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fast Loop
|
|
||||||
|
|
||||||
For near real-time events (200Hz, 5ms intervals):
|
|
||||||
|
|
||||||
```berry
|
|
||||||
def fast_function()
|
|
||||||
# High-frequency processing
|
|
||||||
end
|
|
||||||
|
|
||||||
tasmota.add_fast_loop(fast_function)
|
|
||||||
tasmota.remove_fast_loop(fast_function)
|
|
||||||
```
|
|
||||||
|
|
||||||
### GPIO Control
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import gpio
|
|
||||||
|
|
||||||
# GPIO detection and control
|
|
||||||
gpio.pin_used(gpio.REL1) # Check if GPIO is used
|
|
||||||
gpio.pin(gpio.REL1) # Get physical GPIO number
|
|
||||||
gpio.digital_write(pin, gpio.HIGH) # Set GPIO state
|
|
||||||
gpio.digital_read(pin) # Read GPIO state
|
|
||||||
gpio.pin_mode(pin, gpio.OUTPUT) # Set GPIO mode
|
|
||||||
|
|
||||||
# PWM control
|
|
||||||
gpio.set_pwm(pin, duty, phase) # Set PWM value
|
|
||||||
gpio.set_pwm_freq(pin, freq) # Set PWM frequency
|
|
||||||
|
|
||||||
# DAC (ESP32 GPIO 25-26, ESP32-S2 GPIO 17-18)
|
|
||||||
gpio.dac_voltage(pin, voltage_mv) # Set DAC voltage
|
|
||||||
|
|
||||||
# Counters
|
|
||||||
gpio.counter_read(counter) # Read counter value
|
|
||||||
gpio.counter_set(counter, value) # Set counter value
|
|
||||||
```
|
|
||||||
|
|
||||||
### I²C Communication
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Use wire1 or wire2 for I²C buses
|
|
||||||
wire1.scan() # Scan for devices
|
|
||||||
wire1.detect(addr) # Check if device present
|
|
||||||
wire1.read(addr, reg, size) # Read from device
|
|
||||||
wire1.write(addr, reg, val, size) # Write to device
|
|
||||||
wire1.read_bytes(addr, reg, size) # Read as bytes
|
|
||||||
wire1.write_bytes(addr, reg, bytes) # Write bytes
|
|
||||||
|
|
||||||
# Find device on any bus
|
|
||||||
wire = tasmota.wire_scan(addr, i2c_index)
|
|
||||||
```
|
|
||||||
|
|
||||||
### MQTT Integration
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import mqtt
|
|
||||||
|
|
||||||
# MQTT operations
|
|
||||||
mqtt.publish(topic, payload, retain)
|
|
||||||
mqtt.subscribe(topic, function) # Subscribe with callback
|
|
||||||
mqtt.unsubscribe(topic)
|
|
||||||
mqtt.connected() # Check connection status
|
|
||||||
|
|
||||||
# Callback function signature
|
|
||||||
def mqtt_callback(topic, idx, payload_s, payload_b)
|
|
||||||
# topic: full topic, payload_s: string, payload_b: bytes
|
|
||||||
return true # Return true if handled
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### Web Server Extensions
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import webserver
|
|
||||||
|
|
||||||
# In driver's web_add_handler() method
|
|
||||||
webserver.on("/my_page", def()
|
|
||||||
webserver.content_send("<html>My Page</html>")
|
|
||||||
end)
|
|
||||||
|
|
||||||
# Request handling
|
|
||||||
webserver.has_arg("param") # Check parameter exists
|
|
||||||
webserver.arg("param") # Get parameter value
|
|
||||||
webserver.arg_size() # Number of parameters
|
|
||||||
|
|
||||||
# Response functions
|
|
||||||
webserver.content_send(html) # Send HTML content
|
|
||||||
webserver.content_button() # Standard button
|
|
||||||
webserver.html_escape(str) # Escape HTML
|
|
||||||
```
|
|
||||||
|
|
||||||
### Persistence
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import persist
|
|
||||||
|
|
||||||
# Automatic persistence to _persist.json
|
|
||||||
persist.my_value = 123
|
|
||||||
persist.save() # Force save to flash
|
|
||||||
persist.has("key") # Check if key exists
|
|
||||||
persist.remove("key") # Remove key
|
|
||||||
persist.find("key", default) # Get with default
|
|
||||||
```
|
|
||||||
|
|
||||||
### Network Clients
|
|
||||||
|
|
||||||
#### HTTP/HTTPS Client
|
|
||||||
|
|
||||||
```berry
|
|
||||||
cl = webclient()
|
|
||||||
cl.begin("https://example.com/api")
|
|
||||||
cl.set_auth("user", "pass")
|
|
||||||
cl.add_header("Content-Type", "application/json")
|
|
||||||
|
|
||||||
result = cl.GET() # or POST(payload)
|
|
||||||
if result == 200
|
|
||||||
response = cl.get_string()
|
|
||||||
# or cl.write_file("filename") for binary
|
|
||||||
end
|
|
||||||
cl.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
#### TCP Client
|
|
||||||
|
|
||||||
```berry
|
|
||||||
tcp = tcpclient()
|
|
||||||
tcp.connect("192.168.1.100", 80)
|
|
||||||
tcp.write("GET / HTTP/1.0\r\n\r\n")
|
|
||||||
response = tcp.read()
|
|
||||||
tcp.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
#### UDP Communication
|
|
||||||
|
|
||||||
```berry
|
|
||||||
u = udp()
|
|
||||||
u.begin("", 2000) # Listen on port 2000
|
|
||||||
u.send("192.168.1.10", 2000, bytes("Hello"))
|
|
||||||
|
|
||||||
# Receive (polling)
|
|
||||||
packet = u.read() # Returns bytes or nil
|
|
||||||
if packet
|
|
||||||
print("From:", u.remote_ip, u.remote_port)
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### Serial Communication
|
|
||||||
|
|
||||||
```berry
|
|
||||||
ser = serial(rx_gpio, tx_gpio, baud, serial.SERIAL_8N1)
|
|
||||||
ser.write(bytes("Hello")) # Send data
|
|
||||||
data = ser.read() # Read available data
|
|
||||||
ser.available() # Check bytes available
|
|
||||||
ser.flush() # Flush buffers
|
|
||||||
ser.close() # Close port
|
|
||||||
```
|
|
||||||
|
|
||||||
### Cryptography
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import crypto
|
|
||||||
|
|
||||||
# AES encryption
|
|
||||||
aes = crypto.AES_GCM(key_32_bytes, iv_12_bytes)
|
|
||||||
encrypted = aes.encrypt(plaintext)
|
|
||||||
tag = aes.tag()
|
|
||||||
|
|
||||||
# Hashing
|
|
||||||
crypto.SHA256().update(data).finish() # SHA256 hash
|
|
||||||
crypto.MD5().update(data).finish() # MD5 hash
|
|
||||||
|
|
||||||
# HMAC
|
|
||||||
crypto.HMAC_SHA256(key).update(data).finish()
|
|
||||||
```
|
|
||||||
|
|
||||||
### File System Operations
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import path
|
|
||||||
|
|
||||||
path.exists("filename") # Check file exists
|
|
||||||
path.listdir("/") # List directory
|
|
||||||
path.remove("filename") # Delete file
|
|
||||||
path.mkdir("dirname") # Create directory
|
|
||||||
path.last_modified("file") # File timestamp
|
|
||||||
```
|
|
||||||
|
|
||||||
### Regular Expressions
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Pattern matching
|
|
||||||
matches = re.search("a.*?b(z+)", "aaaabbbzzz") # Returns matches array
|
|
||||||
all_matches = re.searchall('<([a-zA-Z]+)>', html) # All matches
|
|
||||||
parts = re.split('/', "path/to/file") # Split string
|
|
||||||
|
|
||||||
# Compiled patterns (faster for reuse)
|
|
||||||
pattern = re.compilebytes("\\d+")
|
|
||||||
matches = re.search(pattern, "abc123def")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Energy Monitoring
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Read energy values
|
|
||||||
energy.voltage # Main phase voltage
|
|
||||||
energy.current # Main phase current
|
|
||||||
energy.active_power # Active power (W)
|
|
||||||
energy.total # Total energy (kWh)
|
|
||||||
|
|
||||||
# Multi-phase access
|
|
||||||
energy.voltage_phases[0] # Phase 0 voltage
|
|
||||||
energy.current_phases[1] # Phase 1 current
|
|
||||||
|
|
||||||
# Berry energy driver (with OPTION_A 9 GPIO)
|
|
||||||
if energy.driver_enabled()
|
|
||||||
energy.voltage = 240
|
|
||||||
energy.current = 1.5
|
|
||||||
energy.active_power = 360 # This drives energy calculation
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### Display Integration
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import display
|
|
||||||
|
|
||||||
# Initialize display driver
|
|
||||||
display.start(display_ini_string)
|
|
||||||
display.started() # Check if initialized
|
|
||||||
display.dimmer(50) # Set brightness 0-100
|
|
||||||
display.driver_name() # Get driver name
|
|
||||||
|
|
||||||
# Touch screen updates
|
|
||||||
display.touch_update(touches, x, y, gesture)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Advanced Features
|
|
||||||
|
|
||||||
#### ULP (Ultra Low Power) Coprocessor
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import ULP
|
|
||||||
|
|
||||||
ULP.wake_period(0, 500000) # Configure wake timer
|
|
||||||
ULP.load(bytecode) # Load ULP program
|
|
||||||
ULP.run() # Execute ULP program
|
|
||||||
ULP.set_mem(addr, value) # Set RTC memory
|
|
||||||
ULP.get_mem(addr) # Get RTC memory
|
|
||||||
```
|
|
||||||
|
|
||||||
#### mDNS Support
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import mdns
|
|
||||||
|
|
||||||
mdns.start("hostname") # Start mDNS
|
|
||||||
mdns.add_service("_http", "_tcp", 80, {"path": "/"})
|
|
||||||
mdns.stop() # Stop mDNS
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error Handling Patterns
|
|
||||||
|
|
||||||
Many Tasmota functions return `nil` for errors rather than raising exceptions:
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Check return values
|
|
||||||
data = json.load(json_string)
|
|
||||||
if data == nil
|
|
||||||
print("Invalid JSON")
|
|
||||||
end
|
|
||||||
|
|
||||||
# Wire operations
|
|
||||||
result = wire1.read(addr, reg, 1)
|
|
||||||
if result == nil
|
|
||||||
print("I2C read failed")
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
### Best Practices for Tasmota
|
|
||||||
|
|
||||||
1. **Memory Management**: Use `tasmota.gc()` to monitor memory usage
|
|
||||||
2. **Non-blocking**: Use timers instead of `delay()` for long waits
|
|
||||||
3. **Error Handling**: Always check return values for `nil`
|
|
||||||
4. **Persistence**: Use `persist` module for settings that survive reboots
|
|
||||||
5. **Performance**: Use fast_loop sparingly, prefer regular driver events
|
|
||||||
6. **Debugging**: Enable `#define USE_BERRY_DEBUG` for development
|
|
||||||
|
|
||||||
## Common Tasmota Berry Patterns
|
|
||||||
|
|
||||||
### Simple Sensor Driver
|
|
||||||
|
|
||||||
```berry
|
|
||||||
class MySensor
|
|
||||||
var wire, addr
|
|
||||||
|
|
||||||
def init()
|
|
||||||
self.addr = 0x48
|
|
||||||
self.wire = tasmota.wire_scan(self.addr, 99) # I2C index 99
|
|
||||||
if self.wire
|
|
||||||
print("MySensor found on bus", self.wire.bus)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def every_second()
|
|
||||||
if !self.wire return end
|
|
||||||
var temp = self.wire.read(self.addr, 0x00, 2) # Read temperature
|
|
||||||
self.temperature = temp / 256.0 # Convert to Celsius
|
|
||||||
end
|
|
||||||
|
|
||||||
def web_sensor()
|
|
||||||
if !self.wire return end
|
|
||||||
import string
|
|
||||||
var msg = string.format("{s}MySensor Temp{m}%.1f °C{e}", self.temperature)
|
|
||||||
tasmota.web_send_decimal(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
def json_append()
|
|
||||||
if !self.wire return end
|
|
||||||
import string
|
|
||||||
var msg = string.format(',"MySensor":{"Temperature":%.1f}', self.temperature)
|
|
||||||
tasmota.response_append(msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sensor = MySensor()
|
|
||||||
tasmota.add_driver(sensor)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom Command with JSON Response
|
|
||||||
|
|
||||||
```berry
|
|
||||||
def my_status_cmd(cmd, idx, payload, payload_json)
|
|
||||||
import string
|
|
||||||
var response = {
|
|
||||||
"Uptime": tasmota.millis(),
|
|
||||||
"FreeHeap": tasmota.get_free_heap(),
|
|
||||||
"WiFi": tasmota.wifi("rssi")
|
|
||||||
}
|
|
||||||
tasmota.resp_cmnd(json.dump(response))
|
|
||||||
end
|
|
||||||
|
|
||||||
tasmota.add_cmd("MyStatus", my_status_cmd)
|
|
||||||
```
|
|
||||||
|
|
||||||
### MQTT Automation
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import mqtt
|
|
||||||
|
|
||||||
def handle_sensor_data(topic, idx, payload_s, payload_b)
|
|
||||||
var data = json.load(payload_s)
|
|
||||||
if data && data.find("temperature")
|
|
||||||
var temp = data["temperature"]
|
|
||||||
if temp > 25
|
|
||||||
tasmota.cmd("Power1 ON") # Turn on fan
|
|
||||||
elif temp < 20
|
|
||||||
tasmota.cmd("Power1 OFF") # Turn off fan
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
mqtt.subscribe("sensors/+/temperature", handle_sensor_data)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Web UI Button with Action
|
|
||||||
|
|
||||||
```berry
|
|
||||||
class WebButton
|
|
||||||
def web_add_main_button()
|
|
||||||
import webserver
|
|
||||||
webserver.content_send("<p><button onclick='la(\"&toggle_led=1\");'>Toggle LED</button></p>")
|
|
||||||
end
|
|
||||||
|
|
||||||
def web_sensor()
|
|
||||||
import webserver
|
|
||||||
if webserver.has_arg("toggle_led")
|
|
||||||
# Toggle GPIO2 (built-in LED on many ESP32 boards)
|
|
||||||
var pin = 2
|
|
||||||
var current = gpio.digital_read(pin)
|
|
||||||
gpio.digital_write(pin, !current)
|
|
||||||
print("LED toggled to", !current)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
button = WebButton()
|
|
||||||
tasmota.add_driver(button)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Scheduled Task with Persistence
|
|
||||||
|
|
||||||
```berry
|
|
||||||
import persist
|
|
||||||
|
|
||||||
class ScheduledTask
|
|
||||||
def init()
|
|
||||||
if !persist.has("task_count")
|
|
||||||
persist.task_count = 0
|
|
||||||
end
|
|
||||||
# Run every 5 minutes
|
|
||||||
tasmota.add_cron("0 */5 * * * *", /-> self.run_task(), "my_task")
|
|
||||||
end
|
|
||||||
|
|
||||||
def run_task()
|
|
||||||
persist.task_count += 1
|
|
||||||
print("Task executed", persist.task_count, "times")
|
|
||||||
|
|
||||||
# Do something useful
|
|
||||||
var sensors = tasmota.read_sensors()
|
|
||||||
print("Current sensors:", sensors)
|
|
||||||
|
|
||||||
persist.save() # Save counter to flash
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
task = ScheduledTask()
|
|
||||||
```
|
|
||||||
|
|
||||||
### HTTP API Client
|
|
||||||
|
|
||||||
```berry
|
|
||||||
class WeatherAPI
|
|
||||||
var api_key, city
|
|
||||||
|
|
||||||
def init(key, city_name)
|
|
||||||
self.api_key = key
|
|
||||||
self.city = city_name
|
|
||||||
tasmota.add_cron("0 0 * * * *", /-> self.fetch_weather(), "weather")
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_weather()
|
|
||||||
var cl = webclient()
|
|
||||||
var url = f"http://api.openweathermap.org/data/2.5/weather?q={self.city}&appid={self.api_key}"
|
|
||||||
|
|
||||||
cl.begin(url)
|
|
||||||
var result = cl.GET()
|
|
||||||
|
|
||||||
if result == 200
|
|
||||||
var response = cl.get_string()
|
|
||||||
var data = json.load(response)
|
|
||||||
if data
|
|
||||||
var temp = data["main"]["temp"] - 273.15 # Kelvin to Celsius
|
|
||||||
print(f"Weather in {self.city}: {temp:.1f}°C")
|
|
||||||
|
|
||||||
# Store in global for other scripts to use
|
|
||||||
import global
|
|
||||||
global.weather_temp = temp
|
|
||||||
end
|
|
||||||
end
|
|
||||||
cl.close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# weather = WeatherAPI("your_api_key", "London")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rule-based Automation
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Advanced rule that combines multiple conditions
|
|
||||||
tasmota.add_rule(["ANALOG#A0>500", "Switch1#State=1"],
|
|
||||||
def(values, triggers)
|
|
||||||
print("Both conditions met:")
|
|
||||||
print("ADC value:", values[0])
|
|
||||||
print("Switch state:", values[1])
|
|
||||||
tasmota.cmd("Power2 ON") # Activate something
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
# Time-based rule
|
|
||||||
tasmota.add_rule("Time#Minute=30",
|
|
||||||
def()
|
|
||||||
if tasmota.rtc()["hour"] == 18 # 6:30 PM
|
|
||||||
tasmota.cmd("Dimmer 20") # Dim lights for evening
|
|
||||||
end
|
|
||||||
end
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Best Practices and Tips
|
|
||||||
|
|
||||||
1. **Always check for nil returns** from Tasmota functions
|
|
||||||
2. **Use timers instead of delay()** to avoid blocking Tasmota
|
|
||||||
3. **Implement proper error handling** in I²C and network operations
|
|
||||||
4. **Use persist module** for settings that should survive reboots
|
|
||||||
5. **Test memory usage** with `tasmota.gc()` during development
|
|
||||||
6. **Use fast_loop sparingly** - it runs 200 times per second
|
|
||||||
7. **Prefer driver events** over polling when possible
|
|
||||||
8. **Use f-strings** for readable string formatting
|
|
||||||
9. **Import modules only when needed** to save memory
|
|
||||||
10. **Use `tasmota.wire_scan()`** instead of manual I²C bus detection
|
|
@ -1,175 +0,0 @@
|
|||||||
# Deep Analysis of Tasmota Documentation Repository
|
|
||||||
|
|
||||||
This file is a summary of the Tasmota Documentation for the "docs" repository. It is provided here for convenience for GenAI to read it easily.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Tasmota is a comprehensive open-source firmware for ESP8266/ESP8285 and ESP32-based IoT devices that provides local control, MQTT integration, and extensive customization capabilities. The documentation repository contains over 250 markdown files covering every aspect of the firmware, from basic installation to advanced development topics.
|
|
||||||
|
|
||||||
## Repository Structure
|
|
||||||
|
|
||||||
The documentation is organized into several key categories:
|
|
||||||
|
|
||||||
### Core Documentation
|
|
||||||
- **Getting Started**: Complete setup guide from hardware preparation to initial configuration
|
|
||||||
- **Commands**: Comprehensive reference of 200+ commands for device control
|
|
||||||
- **MQTT**: Central communication protocol documentation
|
|
||||||
- **Rules**: Flexible automation system documentation
|
|
||||||
- **Templates**: Device configuration system
|
|
||||||
- **Components**: GPIO mapping and peripheral management
|
|
||||||
|
|
||||||
### Hardware Support
|
|
||||||
- **ESP Platforms**: ESP8266, ESP8285, ESP32 (all variants including S2, S3, C3)
|
|
||||||
- **Supported Devices**: 125+ device-specific configuration files
|
|
||||||
- **Peripherals**: 85+ sensor and peripheral drivers documented
|
|
||||||
- **Pinouts**: Detailed GPIO mappings for common modules
|
|
||||||
|
|
||||||
### Advanced Features
|
|
||||||
- **Berry Scripting**: Modern scripting language for ESP32 (163KB documentation)
|
|
||||||
- **Scripting Language**: Legacy scripting for ESP8266 (93KB documentation)
|
|
||||||
- **Matter Protocol**: Thread/Matter support for modern IoT ecosystems
|
|
||||||
- **Zigbee**: Zigbee2Tasmota gateway functionality (100KB documentation)
|
|
||||||
- **Bluetooth**: BLE sensor integration and device control
|
|
||||||
|
|
||||||
### Integration Ecosystem
|
|
||||||
- **Home Assistant**: Native integration with autodiscovery
|
|
||||||
- **OpenHAB**: Configuration examples and best practices
|
|
||||||
- **Domoticz**: Integration guide
|
|
||||||
- **KNX**: Building automation protocol support
|
|
||||||
- **AWS IoT**: Cloud integration with certificates
|
|
||||||
- **Azure IoT**: Microsoft cloud platform integration
|
|
||||||
|
|
||||||
## Key Technical Insights
|
|
||||||
|
|
||||||
### Architecture Philosophy
|
|
||||||
Tasmota follows a modular architecture where:
|
|
||||||
- Core firmware provides basic functionality (WiFi, MQTT, web interface)
|
|
||||||
- Features are conditionally compiled based on `#define` directives
|
|
||||||
- GPIO mapping is completely flexible through templates
|
|
||||||
- All functionality is controllable via commands (MQTT, HTTP, serial, web console)
|
|
||||||
|
|
||||||
### Memory Management
|
|
||||||
- ESP8266: 80KB RAM total, ~25-30KB available for applications
|
|
||||||
- ESP32: Much more generous memory, supports advanced features
|
|
||||||
- Code size optimization is critical for ESP8266 OTA updates
|
|
||||||
- Flash memory partitioned for dual-boot OTA capability
|
|
||||||
|
|
||||||
### Communication Protocols
|
|
||||||
1. **MQTT** (Primary): All device control and telemetry
|
|
||||||
2. **HTTP**: Web interface and REST API
|
|
||||||
3. **Serial**: Direct console access
|
|
||||||
4. **WebSocket**: Real-time web interface updates
|
|
||||||
|
|
||||||
### Extensibility Mechanisms
|
|
||||||
1. **Rules**: Event-driven automation (up to 1536 characters)
|
|
||||||
2. **Berry Scripts**: Full programming language (ESP32 only)
|
|
||||||
3. **Scripting**: Legacy scripting system (ESP8266)
|
|
||||||
4. **Templates**: Device configuration sharing
|
|
||||||
5. **Custom Drivers**: C++ sensor/peripheral drivers
|
|
||||||
|
|
||||||
## Development Ecosystem
|
|
||||||
|
|
||||||
### Build System
|
|
||||||
- PlatformIO-based compilation
|
|
||||||
- Multiple build environments for different ESP variants
|
|
||||||
- Conditional compilation for feature selection
|
|
||||||
- OTA update system with safety mechanisms
|
|
||||||
|
|
||||||
### Driver Development
|
|
||||||
- Standardized sensor API with callback system
|
|
||||||
- I2C/SPI/UART peripheral support
|
|
||||||
- Memory-conscious development practices
|
|
||||||
- Extensive debugging and profiling tools
|
|
||||||
|
|
||||||
### Scripting Capabilities
|
|
||||||
- **Berry**: Modern language with object-oriented features, garbage collection
|
|
||||||
- **Rules**: Simple trigger-action automation
|
|
||||||
- **Legacy Scripting**: Procedural language for complex automation
|
|
||||||
|
|
||||||
### Integration APIs
|
|
||||||
- **JSON Status Responses**: Standardized telemetry format
|
|
||||||
- **Command Interface**: Unified control mechanism
|
|
||||||
- **Sensor API**: Standardized peripheral integration
|
|
||||||
- **Web Interface Extensions**: Custom UI components
|
|
||||||
|
|
||||||
## Notable Features
|
|
||||||
|
|
||||||
### Advanced Networking
|
|
||||||
- IPv6 support
|
|
||||||
- Wireguard VPN client
|
|
||||||
- Range extender functionality (NAPT)
|
|
||||||
- Multiple WiFi network support
|
|
||||||
- Ethernet support (ESP32)
|
|
||||||
|
|
||||||
### Security Features
|
|
||||||
- TLS/SSL support (ESP32)
|
|
||||||
- Certificate-based authentication
|
|
||||||
- Secure boot options
|
|
||||||
- Network isolation capabilities
|
|
||||||
|
|
||||||
### Display and UI
|
|
||||||
- Universal Display Driver supporting 50+ display types
|
|
||||||
- LVGL graphics library integration
|
|
||||||
- HASPmota: Advanced touch interface system
|
|
||||||
- Web interface customization
|
|
||||||
|
|
||||||
### Industrial Features
|
|
||||||
- Modbus bridge functionality
|
|
||||||
- KNX building automation
|
|
||||||
- Smart meter interfaces (P1, Teleinfo)
|
|
||||||
- Industrial sensor support (4-20mA, etc.)
|
|
||||||
|
|
||||||
## Documentation Quality Assessment
|
|
||||||
|
|
||||||
### Strengths
|
|
||||||
- **Comprehensive Coverage**: Every feature documented with examples
|
|
||||||
- **Practical Focus**: Heavy emphasis on real-world usage scenarios
|
|
||||||
- **Community-Driven**: Active contribution from users and developers
|
|
||||||
- **Multi-Level**: From beginner tutorials to advanced development guides
|
|
||||||
- **Well-Structured**: Logical organization with cross-references
|
|
||||||
|
|
||||||
### Areas for Improvement
|
|
||||||
- **Fragmentation**: Some information scattered across multiple files
|
|
||||||
- **Version Consistency**: Some docs may lag behind rapid development
|
|
||||||
- **Advanced Topics**: Some complex features could use more examples
|
|
||||||
|
|
||||||
## Community and Ecosystem
|
|
||||||
|
|
||||||
### Support Channels
|
|
||||||
- Discord server for real-time help
|
|
||||||
- GitHub discussions for feature requests
|
|
||||||
- Telegram and Matrix communities
|
|
||||||
- Reddit community
|
|
||||||
|
|
||||||
### Device Database
|
|
||||||
- Templates repository with 1000+ device configurations
|
|
||||||
- Community-contributed device support
|
|
||||||
- Standardized template sharing format
|
|
||||||
|
|
||||||
### Integration Ecosystem
|
|
||||||
- Native Home Assistant integration
|
|
||||||
- Multiple home automation platform support
|
|
||||||
- Cloud service integrations (AWS, Azure)
|
|
||||||
- Third-party tool ecosystem
|
|
||||||
|
|
||||||
## Development Trends
|
|
||||||
|
|
||||||
### Modern Features
|
|
||||||
- Matter protocol support for interoperability
|
|
||||||
- Berry scripting for advanced automation
|
|
||||||
- LVGL for rich user interfaces
|
|
||||||
- Machine learning integration (TensorFlow Lite)
|
|
||||||
|
|
||||||
### Hardware Evolution
|
|
||||||
- ESP32 as primary platform for new features
|
|
||||||
- ESP8266 maintained for compatibility
|
|
||||||
- Support for latest ESP32 variants (S2, S3, C3)
|
|
||||||
- Increasing focus on low-power applications
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
The Tasmota documentation represents one of the most comprehensive firmware documentation projects in the IoT space. It successfully bridges the gap between simple device control and advanced IoT development, providing pathways for users to grow from basic usage to sophisticated automation and custom development.
|
|
||||||
|
|
||||||
The documentation's strength lies in its practical approach, extensive hardware support coverage, and community-driven nature. It serves as both a user manual and a development reference, making Tasmota accessible to a wide range of users while providing the depth needed for serious IoT development.
|
|
||||||
|
|
||||||
The modular architecture, extensive command system, and multiple scripting options make Tasmota a powerful platform for IoT development, with documentation that adequately supports this complexity while remaining approachable for newcomers.
|
|
@ -1,977 +0,0 @@
|
|||||||
# Tasmota Developer Guide
|
|
||||||
|
|
||||||
This file is a summary of the Tasmota Documentation for the "docs" repository. It is provided here for convenience for GenAI to read it easily.
|
|
||||||
|
|
||||||
## How Tasmota Works
|
|
||||||
|
|
||||||
### Core Architecture
|
|
||||||
|
|
||||||
Tasmota is a modular firmware that transforms ESP8266/ESP8285 and ESP32 microcontrollers into intelligent IoT devices. The architecture follows these key principles:
|
|
||||||
|
|
||||||
#### 1. Event-Driven System
|
|
||||||
- Main loop processes events and callbacks
|
|
||||||
- Non-blocking operations to maintain responsiveness
|
|
||||||
- Callback system for sensors, drivers, and features
|
|
||||||
- Timer-based scheduling for periodic tasks
|
|
||||||
|
|
||||||
#### 2. Modular Design
|
|
||||||
- Core functionality always present (WiFi, MQTT, web interface)
|
|
||||||
- Optional features compiled conditionally using `#define` directives
|
|
||||||
- Plugin architecture for sensors and peripherals
|
|
||||||
- Template system for device configuration
|
|
||||||
|
|
||||||
#### 3. Communication Hub
|
|
||||||
- **MQTT**: Primary communication protocol for automation systems
|
|
||||||
- **HTTP**: Web interface and REST API
|
|
||||||
- **Serial**: Direct console access for debugging and configuration
|
|
||||||
- **WebSocket**: Real-time web interface updates
|
|
||||||
|
|
||||||
### Firmware Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
tasmota/
|
|
||||||
├── tasmota.ino # Main firmware file
|
|
||||||
├── tasmota_xdrv_driver/ # Driver files directory (187 files)
|
|
||||||
│ ├── xdrv_01_9_webserver.ino # Web server driver
|
|
||||||
│ ├── xdrv_02_9_mqtt.ino # MQTT driver
|
|
||||||
│ ├── xdrv_04_light.ino # Light driver
|
|
||||||
│ └── xdrv_##_name.ino # Other drivers
|
|
||||||
├── tasmota_xsns_sensor/ # Sensor files directory (143 files)
|
|
||||||
│ ├── xsns_01_counter.ino # Counter sensor
|
|
||||||
│ ├── xsns_02_analog.ino # Analog sensor
|
|
||||||
│ └── xsns_##_name.ino # Other sensors
|
|
||||||
├── tasmota_xlgt_light/ # Light driver files directory
|
|
||||||
├── tasmota_xnrg_energy/ # Energy monitoring files directory
|
|
||||||
├── tasmota_support/ # Support functions directory (29 files)
|
|
||||||
│ ├── support.ino # Core support functions
|
|
||||||
│ ├── settings.ino # Settings management
|
|
||||||
│ └── support_*.ino # Other support modules
|
|
||||||
├── include/ # Header files directory (18 files)
|
|
||||||
│ ├── tasmota.h # Main header
|
|
||||||
│ ├── tasmota_types.h # Type definitions
|
|
||||||
│ ├── tasmota_globals.h # Global variables
|
|
||||||
│ └── *.h # Other headers
|
|
||||||
└── my_user_config.h # User configuration overrides
|
|
||||||
```
|
|
||||||
|
|
||||||
### Command System
|
|
||||||
|
|
||||||
All Tasmota functionality is accessible through a unified command system:
|
|
||||||
|
|
||||||
- Commands can be sent via MQTT, HTTP, serial, or web console
|
|
||||||
- Format: `Command [parameter]`
|
|
||||||
- Response format: JSON for structured data
|
|
||||||
- Backlog support for multiple commands: `Backlog cmd1; cmd2; cmd3`
|
|
||||||
|
|
||||||
### GPIO Management
|
|
||||||
|
|
||||||
Tasmota uses a flexible GPIO assignment system:
|
|
||||||
|
|
||||||
1. **Templates**: Pre-defined GPIO configurations for specific devices
|
|
||||||
2. **Components**: Logical functions assigned to physical pins
|
|
||||||
3. **Modules**: Base hardware configurations
|
|
||||||
4. **Runtime Configuration**: GPIO can be reassigned without recompilation
|
|
||||||
|
|
||||||
## Development Environment Setup
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
1. **PlatformIO**: Primary build system
|
|
||||||
2. **Git**: Version control
|
|
||||||
3. **Python**: For build scripts and tools
|
|
||||||
4. **Serial Programmer**: For initial flashing
|
|
||||||
|
|
||||||
### Build Configuration
|
|
||||||
|
|
||||||
Create `platformio_tasmota_cenv.ini` for custom environments:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[env:tasmota32-custom]
|
|
||||||
extends = env:tasmota32
|
|
||||||
build_flags = ${env:tasmota32.build_flags}
|
|
||||||
-DUSE_MY_CUSTOM_FEATURE
|
|
||||||
```
|
|
||||||
|
|
||||||
### User Configuration
|
|
||||||
|
|
||||||
Create `tasmota/user_config_override.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#ifndef _USER_CONFIG_OVERRIDE_H_
|
|
||||||
#define _USER_CONFIG_OVERRIDE_H_
|
|
||||||
|
|
||||||
// Enable custom features
|
|
||||||
#define USE_CUSTOM_SENSOR
|
|
||||||
#define USE_BERRY_DEBUG
|
|
||||||
|
|
||||||
// Disable unused features to save space
|
|
||||||
#undef USE_DOMOTICZ
|
|
||||||
#undef USE_KNX
|
|
||||||
|
|
||||||
#endif
|
|
||||||
```
|
|
||||||
|
|
||||||
## Driver Development
|
|
||||||
|
|
||||||
### Sensor Driver Structure
|
|
||||||
|
|
||||||
All sensor drivers follow a standardized pattern:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#ifdef USE_MY_SENSOR
|
|
||||||
#define XSNS_XX XX // Unique sensor ID
|
|
||||||
|
|
||||||
bool MySensorDetected = false;
|
|
||||||
|
|
||||||
void MySensorInit(void) {
|
|
||||||
// Initialize sensor
|
|
||||||
if (sensor_detected) {
|
|
||||||
MySensorDetected = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MySensorEverySecond(void) {
|
|
||||||
// Read sensor data
|
|
||||||
}
|
|
||||||
|
|
||||||
void MySensorShow(bool json) {
|
|
||||||
if (json) {
|
|
||||||
ResponseAppend_P(PSTR(",\"MySensor\":{\"Temperature\":%d}"), temperature);
|
|
||||||
}
|
|
||||||
#ifdef USE_WEBSERVER
|
|
||||||
else {
|
|
||||||
WSContentSend_PD(HTTP_SNS_TEMP, "MySensor", temperature);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Xsns_XX(byte function) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (i2c_flg) { // Only for I2C sensors
|
|
||||||
switch (function) {
|
|
||||||
case FUNC_INIT:
|
|
||||||
MySensorInit();
|
|
||||||
break;
|
|
||||||
case FUNC_EVERY_SECOND:
|
|
||||||
MySensorEverySecond();
|
|
||||||
break;
|
|
||||||
case FUNC_JSON_APPEND:
|
|
||||||
MySensorShow(1);
|
|
||||||
break;
|
|
||||||
#ifdef USE_WEBSERVER
|
|
||||||
case FUNC_WEB_SENSOR:
|
|
||||||
MySensorShow(0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif // USE_MY_SENSOR
|
|
||||||
```
|
|
||||||
|
|
||||||
### Complete Driver Callback Functions Reference
|
|
||||||
|
|
||||||
**VERIFIED FROM SOURCE CODE**: `tasmota/include/tasmota.h` lines 433-454
|
|
||||||
|
|
||||||
#### Core System Callbacks (Functions WITHOUT return results)
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_SETTINGS_OVERRIDE` | Override default settings | Before settings load | None |
|
|
||||||
| `FUNC_SETUP_RING1` | Early setup phase 1 | System initialization | None |
|
|
||||||
| `FUNC_SETUP_RING2` | Early setup phase 2 | System initialization | None |
|
|
||||||
| `FUNC_PRE_INIT` | Pre-initialization | Before main init | None |
|
|
||||||
| `FUNC_INIT` | Initialize driver/sensor | Once at startup | None |
|
|
||||||
| `FUNC_ACTIVE` | Check if driver is active | Status queries | None |
|
|
||||||
| `FUNC_ABOUT_TO_RESTART` | Prepare for restart | Before system restart | None |
|
|
||||||
|
|
||||||
#### Loop and Timing Callbacks
|
|
||||||
|
|
||||||
| Function | Purpose | Frequency | Parameters |
|
|
||||||
|----------|---------|-----------|-----------|
|
|
||||||
| `FUNC_LOOP` | Main loop processing | Every loop cycle (~1ms) | None |
|
|
||||||
| `FUNC_SLEEP_LOOP` | Sleep mode processing | During sleep cycles | None |
|
|
||||||
| `FUNC_EVERY_50_MSECOND` | Fast polling operations | Every 50ms | None |
|
|
||||||
| `FUNC_EVERY_100_MSECOND` | Medium polling | Every 100ms | None |
|
|
||||||
| `FUNC_EVERY_200_MSECOND` | Slower polling | Every 200ms | None |
|
|
||||||
| `FUNC_EVERY_250_MSECOND` | Quarter second tasks | Every 250ms | None |
|
|
||||||
| `FUNC_EVERY_SECOND` | Regular updates | Every second | None |
|
|
||||||
|
|
||||||
#### Settings and Configuration Callbacks
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_RESET_SETTINGS` | Reset to defaults | Settings reset | None |
|
|
||||||
| `FUNC_RESTORE_SETTINGS` | Restore from backup | Settings restore | None |
|
|
||||||
| `FUNC_SAVE_SETTINGS` | Save current settings | Settings save | None |
|
|
||||||
| `FUNC_SAVE_AT_MIDNIGHT` | Midnight save operations | Daily at 00:00 | None |
|
|
||||||
| `FUNC_SAVE_BEFORE_RESTART` | Save critical data | Before restart | None |
|
|
||||||
|
|
||||||
#### Interrupt and System Control
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_INTERRUPT_STOP` | Stop interrupts | Before critical section | None |
|
|
||||||
| `FUNC_INTERRUPT_START` | Resume interrupts | After critical section | None |
|
|
||||||
| `FUNC_FREE_MEM` | Memory cleanup | Low memory conditions | None |
|
|
||||||
|
|
||||||
#### Telemetry and JSON Callbacks
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_AFTER_TELEPERIOD` | Post-telemetry cleanup | After TelePeriod | None |
|
|
||||||
| `FUNC_JSON_APPEND` | Add JSON telemetry | Every TelePeriod | None |
|
|
||||||
| `FUNC_TELEPERIOD_RULES_PROCESS` | Rules after telemetry | Post-TelePeriod | None |
|
|
||||||
|
|
||||||
#### Web Interface Callbacks
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_WEB_SENSOR` | Show sensor on web | Sensor page load | None |
|
|
||||||
| `FUNC_WEB_COL_SENSOR` | Column sensor display | Web page layout | None |
|
|
||||||
| `FUNC_WEB_ADD_BUTTON` | Add web buttons | Main page load | None |
|
|
||||||
| `FUNC_WEB_ADD_CONSOLE_BUTTON` | Add console button | Console page | None |
|
|
||||||
| `FUNC_WEB_ADD_MANAGEMENT_BUTTON` | Add config button | Config page | None |
|
|
||||||
| `FUNC_WEB_ADD_MAIN_BUTTON` | Add main menu button | Main page | None |
|
|
||||||
| `FUNC_WEB_GET_ARG` | Process web arguments | Form submission | None |
|
|
||||||
| `FUNC_WEB_ADD_HANDLER` | Add URL handlers | Web server init | None |
|
|
||||||
| `FUNC_WEB_STATUS_LEFT` | Left status column | Status page | None |
|
|
||||||
| `FUNC_WEB_STATUS_RIGHT` | Right status column | Status page | None |
|
|
||||||
|
|
||||||
#### MQTT and Communication Callbacks
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_MQTT_SUBSCRIBE` | Subscribe to MQTT topics | MQTT connect | None |
|
|
||||||
| `FUNC_MQTT_INIT` | Initialize MQTT | MQTT setup | None |
|
|
||||||
|
|
||||||
#### Power and Hardware Control
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_SET_POWER` | Handle power changes | Power state change | None |
|
|
||||||
| `FUNC_SHOW_SENSOR` | Display sensor data | Status request | None |
|
|
||||||
| `FUNC_ANY_KEY` | Handle any key press | Key event | None |
|
|
||||||
| `FUNC_LED_LINK` | Control link LED | Network state change | None |
|
|
||||||
| `FUNC_ENERGY_EVERY_SECOND` | Energy monitoring | Every second | None |
|
|
||||||
| `FUNC_ENERGY_RESET` | Reset energy counters | Reset command | None |
|
|
||||||
|
|
||||||
#### Advanced System Callbacks
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Parameters |
|
|
||||||
|----------|---------|-------------|-----------|
|
|
||||||
| `FUNC_SET_SCHEME` | Set color scheme | Theme change | None |
|
|
||||||
| `FUNC_HOTPLUG_SCAN` | Scan for hotplug devices | Device detection | None |
|
|
||||||
| `FUNC_TIME_SYNCED` | Time synchronization | NTP sync complete | None |
|
|
||||||
| `FUNC_DEVICE_GROUP_ITEM` | Device group processing | Group operations | None |
|
|
||||||
| `FUNC_NETWORK_UP` | Network connected | WiFi/Ethernet up | None |
|
|
||||||
| `FUNC_NETWORK_DOWN` | Network disconnected | WiFi/Ethernet down | None |
|
|
||||||
|
|
||||||
#### Callback Functions WITH Return Results (ID >= 200)
|
|
||||||
|
|
||||||
These functions are expected to return boolean results:
|
|
||||||
|
|
||||||
| Function | Purpose | When Called | Return Value |
|
|
||||||
|----------|---------|-------------|--------------|
|
|
||||||
| `FUNC_PIN_STATE` | GPIO state query | Pin state check | true if handled |
|
|
||||||
| `FUNC_MODULE_INIT` | Module initialization | Module setup | true if success |
|
|
||||||
| `FUNC_ADD_BUTTON` | Add button handler | Button config | true if added |
|
|
||||||
| `FUNC_ADD_SWITCH` | Add switch handler | Switch config | true if added |
|
|
||||||
| `FUNC_BUTTON_PRESSED` | Handle button press | Button event | true if handled |
|
|
||||||
| `FUNC_BUTTON_MULTI_PRESSED` | Multi-button press | Button combo | true if handled |
|
|
||||||
| `FUNC_SET_DEVICE_POWER` | Device power control | Power command | true if handled |
|
|
||||||
| `FUNC_MQTT_DATA` | Process MQTT data | MQTT message | true if handled |
|
|
||||||
| `FUNC_SERIAL` | Serial data processing | Serial input | true if handled |
|
|
||||||
| `FUNC_COMMAND` | Process commands | Command received | true if handled |
|
|
||||||
| `FUNC_COMMAND_SENSOR` | Sensor commands | Sensor command | true if handled |
|
|
||||||
| `FUNC_COMMAND_DRIVER` | Driver commands | Driver command | true if handled |
|
|
||||||
| `FUNC_RULES_PROCESS` | Process rules | Rule evaluation | true if handled |
|
|
||||||
| `FUNC_SET_CHANNELS` | Set PWM channels | Channel update | true if handled |
|
|
||||||
|
|
||||||
#### Callback Implementation Pattern
|
|
||||||
|
|
||||||
```c
|
|
||||||
bool Xdrv_XX(uint8_t function) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
switch (function) {
|
|
||||||
case FUNC_INIT:
|
|
||||||
MyDriverInit();
|
|
||||||
break;
|
|
||||||
case FUNC_EVERY_SECOND:
|
|
||||||
MyDriverEverySecond();
|
|
||||||
break;
|
|
||||||
case FUNC_COMMAND:
|
|
||||||
result = MyDriverCommand();
|
|
||||||
break;
|
|
||||||
case FUNC_JSON_APPEND:
|
|
||||||
MyDriverJsonAppend();
|
|
||||||
break;
|
|
||||||
case FUNC_WEB_SENSOR:
|
|
||||||
MyDriverWebSensor();
|
|
||||||
break;
|
|
||||||
case FUNC_SAVE_BEFORE_RESTART:
|
|
||||||
MyDriverSaveSettings();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
### I2C Development
|
|
||||||
|
|
||||||
```c
|
|
||||||
// I2C Helper Functions
|
|
||||||
bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
uint8_t I2cRead8(uint8_t addr, uint8_t reg);
|
|
||||||
uint16_t I2cRead16(uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cWrite8(uint8_t addr, uint8_t reg, uint8_t val);
|
|
||||||
|
|
||||||
// Device Detection Pattern
|
|
||||||
void MySensorDetect(void) {
|
|
||||||
if (MySensorDetected) return;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < SENSOR_MAX_ADDR; i++) {
|
|
||||||
uint8_t addr = SENSOR_BASE_ADDR + i;
|
|
||||||
if (I2cValidRead8(&sensor_id, addr, SENSOR_ID_REG)) {
|
|
||||||
if (sensor_id == EXPECTED_ID) {
|
|
||||||
MySensorDetected = true;
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("MySensor found at 0x%02X"), addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Scripting and Automation
|
|
||||||
|
|
||||||
### Rules System
|
|
||||||
|
|
||||||
Rules provide event-driven automation:
|
|
||||||
|
|
||||||
```
|
|
||||||
Rule1 ON Switch1#State DO Power1 %value% ENDON
|
|
||||||
ON Time#Minute=30 DO Publish stat/topic/alert {"time":"30min"} ENDON
|
|
||||||
```
|
|
||||||
|
|
||||||
### Berry Scripting (ESP32)
|
|
||||||
|
|
||||||
Berry is a modern scripting language for advanced automation:
|
|
||||||
|
|
||||||
```berry
|
|
||||||
# Simple sensor reading
|
|
||||||
import json
|
|
||||||
|
|
||||||
def read_sensor()
|
|
||||||
var temp = tasmota.read_sensors()
|
|
||||||
if temp.contains("Temperature")
|
|
||||||
print("Current temperature:", temp["Temperature"])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set up timer
|
|
||||||
tasmota.set_timer(5000, read_sensor)
|
|
||||||
|
|
||||||
# Web interface extension
|
|
||||||
def web_add_button()
|
|
||||||
webserver.content_send("<button onclick='la(\"&m_toggle=1\");'>Toggle</button>")
|
|
||||||
end
|
|
||||||
|
|
||||||
tasmota.add_driver(web_add_button)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Command Extensions
|
|
||||||
|
|
||||||
Add custom commands through Berry or C++:
|
|
||||||
|
|
||||||
```berry
|
|
||||||
def my_command(cmd, idx, payload)
|
|
||||||
if cmd == "MYCMD"
|
|
||||||
print("Custom command received:", payload)
|
|
||||||
tasmota.resp_cmnd_done()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
tasmota.add_cmd('MYCMD', my_command)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Complete Settings Structure Reference
|
|
||||||
|
|
||||||
### Settings Memory Layout
|
|
||||||
|
|
||||||
Tasmota uses a structured settings system stored in flash memory. The main settings structure is defined in `settings.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
typedef struct {
|
|
||||||
unsigned long cfg_holder; // 000 v6.0.0a
|
|
||||||
unsigned long save_flag; // 004
|
|
||||||
unsigned long version; // 008
|
|
||||||
unsigned short flag; // 00C
|
|
||||||
unsigned short save_data; // 00E
|
|
||||||
int8_t timezone; // 010
|
|
||||||
char ota_url[101]; // 011
|
|
||||||
char mqtt_prefix[3][11]; // 076
|
|
||||||
char serial_delimiter; // 09D
|
|
||||||
uint8_t seriallog_level; // 09E
|
|
||||||
uint8_t sta_config; // 09F
|
|
||||||
char sta_ssid[2][33]; // 0A0
|
|
||||||
char sta_pwd[2][65]; // 102
|
|
||||||
char hostname[33]; // 183
|
|
||||||
char syslog_host[33]; // 1A4
|
|
||||||
uint16_t syslog_port; // 1C5
|
|
||||||
uint8_t syslog_level; // 1C7
|
|
||||||
uint8_t webserver; // 1C8
|
|
||||||
uint8_t weblog_level; // 1C9
|
|
||||||
char mqtt_fingerprint[2][60]; // 1CA
|
|
||||||
char mqtt_host[33]; // 236
|
|
||||||
uint16_t mqtt_port; // 257
|
|
||||||
char mqtt_client[33]; // 259
|
|
||||||
char mqtt_user[33]; // 27A
|
|
||||||
char mqtt_pwd[33]; // 29B
|
|
||||||
char mqtt_topic[33]; // 2BC
|
|
||||||
char button_topic[33]; // 2DD
|
|
||||||
char mqtt_grptopic[33]; // 2FE
|
|
||||||
uint8_t display_model; // 31F
|
|
||||||
uint8_t display_mode; // 320
|
|
||||||
uint8_t display_refresh; // 321
|
|
||||||
uint8_t display_rows; // 322
|
|
||||||
uint8_t display_cols[2]; // 323
|
|
||||||
uint8_t display_address[8]; // 325
|
|
||||||
uint8_t display_dimmer; // 32D
|
|
||||||
uint8_t display_size; // 32E
|
|
||||||
uint16_t pwm_frequency; // 32F
|
|
||||||
power_t power; // 331
|
|
||||||
uint16_t pwm_value[MAX_PWMS]; // 335
|
|
||||||
int16_t altitude; // 345
|
|
||||||
uint16_t tele_period; // 347
|
|
||||||
uint8_t ledstate; // 349
|
|
||||||
uint8_t param[PARAM_MAX]; // 34A
|
|
||||||
int16_t toffset[2]; // 35A
|
|
||||||
uint8_t display_font; // 35E
|
|
||||||
} Settings;
|
|
||||||
|
|
||||||
### ESP8266 Constraints
|
|
||||||
|
|
||||||
- **Flash**: 1MB total, ~500KB available for firmware
|
|
||||||
- **RAM**: 80KB total, ~25-30KB available for application
|
|
||||||
- **Stack**: 4KB maximum
|
|
||||||
|
|
||||||
### Optimization Techniques
|
|
||||||
|
|
||||||
1. **Use PROGMEM for constants**:
|
|
||||||
```c
|
|
||||||
const char MyString[] PROGMEM = "Constant string";
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Minimize dynamic allocation**:
|
|
||||||
```c
|
|
||||||
// Avoid
|
|
||||||
String result = String(value1) + "," + String(value2);
|
|
||||||
|
|
||||||
// Prefer
|
|
||||||
char result[32];
|
|
||||||
snprintf(result, sizeof(result), "%d,%d", value1, value2);
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Use flash-efficient data types**:
|
|
||||||
```c
|
|
||||||
// Use uint32_t instead of uint8_t for local variables
|
|
||||||
// Use uint8_t only in structs to save memory
|
|
||||||
```
|
|
||||||
|
|
||||||
## Communication Protocols
|
|
||||||
|
|
||||||
### Command Context Structure
|
|
||||||
|
|
||||||
All command handlers receive context through the global XdrvMailbox structure:
|
|
||||||
|
|
||||||
```c
|
|
||||||
struct XDRVMAILBOX {
|
|
||||||
bool grpflg; // Group flag
|
|
||||||
bool usridx; // User index flag
|
|
||||||
uint16_t command_code; // Command code
|
|
||||||
uint32_t index; // Command index
|
|
||||||
uint32_t data_len; // Parameter length
|
|
||||||
int32_t payload; // Numeric parameter
|
|
||||||
char *topic; // MQTT topic
|
|
||||||
char *data; // Command parameters
|
|
||||||
char *command; // Command name
|
|
||||||
} XdrvMailbox;
|
|
||||||
```
|
|
||||||
|
|
||||||
**Key Fields:**
|
|
||||||
- `command`: The command name (e.g., "Power", "Status")
|
|
||||||
- `data`: Raw parameter string
|
|
||||||
- `payload`: Numeric value of first parameter
|
|
||||||
- `data_len`: Length of parameter string
|
|
||||||
- `index`: Command index for numbered commands (Power1, Power2, etc.)
|
|
||||||
|
|
||||||
### MQTT Integration
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Publish sensor data
|
|
||||||
void PublishSensorData(void) {
|
|
||||||
Response_P(PSTR("{\"MySensor\":{\"Value\":%d}}"), sensor_value);
|
|
||||||
MqttPublishTeleSensor();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe to commands
|
|
||||||
bool MyCommand(void) {
|
|
||||||
if (XdrvMailbox.data_len > 0) {
|
|
||||||
// Process command
|
|
||||||
ResponseCmndDone();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
ResponseCmndNumber(current_value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Web Interface Extensions
|
|
||||||
|
|
||||||
```c
|
|
||||||
#ifdef USE_WEBSERVER
|
|
||||||
void MySensorWebShow(void) {
|
|
||||||
WSContentSend_PD(PSTR(
|
|
||||||
"{s}MySensor Temperature{m}%d°C{e}"
|
|
||||||
"{s}MySensor Humidity{m}%d%%{e}"),
|
|
||||||
temperature, humidity);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
```
|
|
||||||
|
|
||||||
## Advanced Features
|
|
||||||
|
|
||||||
### Template System
|
|
||||||
|
|
||||||
Templates define device GPIO configurations:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"NAME":"Custom Device",
|
|
||||||
"GPIO":[416,0,418,0,417,2720,0,0,2624,32,2656,224,0,0],
|
|
||||||
"FLAG":0,
|
|
||||||
"BASE":45
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Matter Protocol Support
|
|
||||||
|
|
||||||
For ESP32 devices, Matter provides standardized IoT communication:
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Matter endpoint configuration
|
|
||||||
matter.add_endpoint(1, 0x0100); // On/Off Light
|
|
||||||
matter.add_endpoint(2, 0x0106); // Light with dimming
|
|
||||||
```
|
|
||||||
|
|
||||||
### Display Integration
|
|
||||||
|
|
||||||
Universal Display Driver supports 50+ display types:
|
|
||||||
|
|
||||||
```
|
|
||||||
DisplayModel 1 # Select display type
|
|
||||||
DisplayMode 1 # Text mode
|
|
||||||
DisplayText [s1l1]Hello World
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing and Debugging
|
|
||||||
|
|
||||||
### Debug Options
|
|
||||||
|
|
||||||
Enable debugging in `user_config_override.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define DEBUG_TASMOTA_CORE
|
|
||||||
#define DEBUG_TASMOTA_DRIVER
|
|
||||||
#define USE_DEBUG_DRIVER
|
|
||||||
```
|
|
||||||
|
|
||||||
### Serial Debugging
|
|
||||||
|
|
||||||
```c
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("Debug: value=%d"), value);
|
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("Detailed info: %s"), info_string);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Memory Monitoring
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Check free heap
|
|
||||||
uint32_t free_heap = ESP.getFreeHeap();
|
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("Free heap: %d"), free_heap);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
### Code Organization
|
|
||||||
|
|
||||||
1. **Use consistent naming**: `MySensor` prefix for all functions
|
|
||||||
2. **Follow callback patterns**: Implement standard driver callbacks
|
|
||||||
3. **Handle errors gracefully**: Check return values and sensor presence
|
|
||||||
4. **Document thoroughly**: Include usage examples and pin assignments
|
|
||||||
|
|
||||||
### Performance Considerations
|
|
||||||
|
|
||||||
1. **Minimize blocking operations**: Use state machines for long operations
|
|
||||||
2. **Cache sensor readings**: Don't read sensors more often than necessary
|
|
||||||
3. **Use appropriate data types**: Consider memory usage vs. precision
|
|
||||||
4. **Optimize for common cases**: Fast path for normal operations
|
|
||||||
|
|
||||||
### Security Guidelines
|
|
||||||
|
|
||||||
1. **Validate all inputs**: Check command parameters and sensor data
|
|
||||||
2. **Use secure defaults**: Enable security features by default
|
|
||||||
3. **Minimize attack surface**: Disable unused network services
|
|
||||||
4. **Regular updates**: Keep firmware and dependencies current
|
|
||||||
|
|
||||||
## Integration Examples
|
|
||||||
|
|
||||||
### Home Assistant Discovery
|
|
||||||
|
|
||||||
```c
|
|
||||||
void PublishDiscovery(void) {
|
|
||||||
Response_P(PSTR("{"
|
|
||||||
"\"name\":\"%s MySensor\","
|
|
||||||
"\"stat_t\":\"%s\","
|
|
||||||
"\"unit_of_meas\":\"°C\","
|
|
||||||
"\"dev_cla\":\"temperature\""
|
|
||||||
"}"), SettingsText(SET_DEVICENAME), GetStateTopic());
|
|
||||||
|
|
||||||
MqttPublish(GetDiscoveryTopic("sensor", "temperature"), true);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom Web Interface
|
|
||||||
|
|
||||||
```c
|
|
||||||
const char HTTP_MYSENSOR[] PROGMEM =
|
|
||||||
"{s}MySensor{m}"
|
|
||||||
"<input type='range' min='0' max='100' value='%d' "
|
|
||||||
"onchange='la(\"&mysensor_val=\"+this.value);'>"
|
|
||||||
"{e}";
|
|
||||||
|
|
||||||
void MySensorWebShow(void) {
|
|
||||||
WSContentSend_PD(HTTP_MYSENSOR, current_value);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This guide provides the foundation for understanding and extending Tasmota. The modular architecture, standardized APIs, and extensive documentation make it an excellent platform for IoT development, whether you're adding simple sensor support or implementing complex automation systems.
|
|
||||||
|
|
||||||
## Complete Command Reference
|
|
||||||
|
|
||||||
### Core System Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Status` | 0-11 | System status information | `Status 0` |
|
|
||||||
| `Reset` | 1-6 | Reset device with options | `Reset 1` |
|
|
||||||
| `Restart` | 1 | Restart device | `Restart 1` |
|
|
||||||
| `Upgrade` | 1 | Start OTA upgrade | `Upgrade 1` |
|
|
||||||
| `Upload` | 1 | Start file upload | `Upload 1` |
|
|
||||||
| `Otaurl` | url | Set OTA URL | `Otaurl http://ota.server/firmware.bin` |
|
|
||||||
| `Seriallog` | 0-4 | Set serial log level | `Seriallog 2` |
|
|
||||||
| `Syslog` | 0-4 | Set syslog level | `Syslog 2` |
|
|
||||||
| `Loghost` | hostname | Set syslog host | `Loghost 192.168.1.100` |
|
|
||||||
| `Logport` | port | Set syslog port | `Logport 514` |
|
|
||||||
| `Ipaddress` | x.x.x.x | Set IP address | `Ipaddress 192.168.1.100` |
|
|
||||||
| `Gateway` | x.x.x.x | Set gateway | `Gateway 192.168.1.1` |
|
|
||||||
| `Subnetmask` | x.x.x.x | Set subnet mask | `Subnetmask 255.255.255.0` |
|
|
||||||
| `Dnsserver` | x.x.x.x | Set DNS server | `Dnsserver 8.8.8.8` |
|
|
||||||
| `Mac` | - | Show MAC address | `Mac` |
|
|
||||||
| `Hostname` | name | Set hostname | `Hostname tasmota-device` |
|
|
||||||
|
|
||||||
### WiFi Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Ssid1` | ssid | Set WiFi SSID 1 | `Ssid1 MyNetwork` |
|
|
||||||
| `Ssid2` | ssid | Set WiFi SSID 2 | `Ssid2 BackupNetwork` |
|
|
||||||
| `Password1` | password | Set WiFi password 1 | `Password1 MyPassword` |
|
|
||||||
| `Password2` | password | Set WiFi password 2 | `Password2 BackupPassword` |
|
|
||||||
| `Ap` | 0-2 | Set AP mode | `Ap 1` |
|
|
||||||
| `WebServer` | 0-2 | Enable web server | `WebServer 1` |
|
|
||||||
| `WebPassword` | password | Set web password | `WebPassword admin` |
|
|
||||||
| `WifiConfig` | 0-7 | WiFi configuration mode | `WifiConfig 4` |
|
|
||||||
|
|
||||||
### MQTT Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `MqttHost` | hostname | Set MQTT broker | `MqttHost 192.168.1.100` |
|
|
||||||
| `MqttPort` | port | Set MQTT port | `MqttPort 1883` |
|
|
||||||
| `MqttUser` | username | Set MQTT username | `MqttUser myuser` |
|
|
||||||
| `MqttPassword` | password | Set MQTT password | `MqttPassword mypass` |
|
|
||||||
| `MqttClient` | clientid | Set MQTT client ID | `MqttClient tasmota-device` |
|
|
||||||
| `Topic` | topic | Set MQTT topic | `Topic tasmota` |
|
|
||||||
| `GroupTopic` | topic | Set group topic | `GroupTopic tasmotas` |
|
|
||||||
| `FullTopic` | template | Set full topic template | `FullTopic %prefix%/%topic%/` |
|
|
||||||
| `Prefix1` | prefix | Set command prefix | `Prefix1 cmnd` |
|
|
||||||
| `Prefix2` | prefix | Set status prefix | `Prefix2 stat` |
|
|
||||||
| `Prefix3` | prefix | Set telemetry prefix | `Prefix3 tele` |
|
|
||||||
| `Publish` | topic payload | Publish MQTT message | `Publish stat/topic/test Hello` |
|
|
||||||
| `MqttRetry` | seconds | Set MQTT retry time | `MqttRetry 10` |
|
|
||||||
| `StateText1` | text | Set OFF state text | `StateText1 OFF` |
|
|
||||||
| `StateText2` | text | Set ON state text | `StateText2 ON` |
|
|
||||||
| `StateText3` | text | Set TOGGLE state text | `StateText3 TOGGLE` |
|
|
||||||
| `StateText4` | text | Set HOLD state text | `StateText4 HOLD` |
|
|
||||||
|
|
||||||
### Power and Relay Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Power` | 0/1/2 | Control main power | `Power 1` |
|
|
||||||
| `Power1` | 0/1/2 | Control power 1 | `Power1 ON` |
|
|
||||||
| `Power2` | 0/1/2 | Control power 2 | `Power2 OFF` |
|
|
||||||
| `Power3` | 0/1/2 | Control power 3 | `Power3 TOGGLE` |
|
|
||||||
| `Power4` | 0/1/2 | Control power 4 | `Power4 1` |
|
|
||||||
| `PowerOnState` | 0-4 | Set power on state | `PowerOnState 1` |
|
|
||||||
| `PulseTime` | 1-111 | Set pulse time | `PulseTime1 10` |
|
|
||||||
| `BlinkTime` | 2-3600 | Set blink time | `BlinkTime 10` |
|
|
||||||
| `BlinkCount` | 0-32000 | Set blink count | `BlinkCount 5` |
|
|
||||||
| `Interlock` | 0/1 | Enable interlock | `Interlock 1` |
|
|
||||||
| `Ledstate` | 0-8 | Set LED state | `Ledstate 1` |
|
|
||||||
| `LedPower` | 0-2 | Control LED power | `LedPower 1` |
|
|
||||||
| `LedMask` | hex | Set LED mask | `LedMask 0xFF00` |
|
|
||||||
|
|
||||||
### Sensor Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `TelePeriod` | 10-3600 | Set telemetry period | `TelePeriod 300` |
|
|
||||||
| `Resolution` | 0-3 | Set sensor resolution | `Resolution 2` |
|
|
||||||
| `HumRes` | 0-3 | Set humidity resolution | `HumRes 1` |
|
|
||||||
| `TempRes` | 0-3 | Set temperature resolution | `TempRes 2` |
|
|
||||||
| `PressRes` | 0-3 | Set pressure resolution | `PressRes 1` |
|
|
||||||
| `EnergyRes` | 0-5 | Set energy resolution | `EnergyRes 3` |
|
|
||||||
| `SpeedUnit` | 1-4 | Set speed unit | `SpeedUnit 1` |
|
|
||||||
| `WeightRes` | 0-3 | Set weight resolution | `WeightRes 2` |
|
|
||||||
| `FreqRes` | 0-3 | Set frequency resolution | `FreqRes 2` |
|
|
||||||
|
|
||||||
### Timer Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Timer1` | parameters | Configure timer 1 | `Timer1 {"Enable":1,"Time":"06:00","Days":"1111100","Repeat":1,"Action":1}` |
|
|
||||||
| `Timer2` | parameters | Configure timer 2 | `Timer2 {"Enable":1,"Time":"22:00","Action":0}` |
|
|
||||||
| `Timers` | 0/1 | Enable/disable timers | `Timers 1` |
|
|
||||||
| `Latitude` | degrees | Set latitude | `Latitude 52.520008` |
|
|
||||||
| `Longitude` | degrees | Set longitude | `Longitude 13.404954` |
|
|
||||||
| `Sunrise` | - | Show sunrise time | `Sunrise` |
|
|
||||||
| `Sunset` | - | Show sunset time | `Sunset` |
|
|
||||||
|
|
||||||
### GPIO and Template Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Gpio` | pin,function | Set GPIO function | `Gpio 14,21` |
|
|
||||||
| `Gpios` | - | Show GPIO configuration | `Gpios` |
|
|
||||||
| `Template` | json | Set device template | `Template {"NAME":"Generic","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":1,"BASE":18}` |
|
|
||||||
| `Module` | 0-255 | Set device module | `Module 1` |
|
|
||||||
| `Modules` | - | Show available modules | `Modules` |
|
|
||||||
| `I2CScan` | - | Scan I2C bus | `I2CScan` |
|
|
||||||
| `I2CDriver` | driver | Enable I2C driver | `I2CDriver10 1` |
|
|
||||||
|
|
||||||
### Display Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Display` | - | Show display info | `Display` |
|
|
||||||
| `DisplayModel` | 1-16 | Set display model | `DisplayModel 2` |
|
|
||||||
| `DisplayMode` | 0-5 | Set display mode | `DisplayMode 1` |
|
|
||||||
| `DisplayDimmer` | 0-100 | Set display brightness | `DisplayDimmer 50` |
|
|
||||||
| `DisplaySize` | 1-4 | Set display size | `DisplaySize 2` |
|
|
||||||
| `DisplayRotate` | 0-3 | Set display rotation | `DisplayRotate 2` |
|
|
||||||
| `DisplayText` | text | Display text | `DisplayText [s1l1]Hello World` |
|
|
||||||
| `DisplayClear` | - | Clear display | `DisplayClear` |
|
|
||||||
|
|
||||||
### Rule Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Rule1` | rule | Set rule 1 | `Rule1 ON Switch1#State DO Power1 %value% ENDON` |
|
|
||||||
| `Rule2` | rule | Set rule 2 | `Rule2 ON Time#Minute=30 DO Publish stat/alert 30min ENDON` |
|
|
||||||
| `Rule3` | rule | Set rule 3 | `Rule3 ON Button1#State DO Backlog Power1 TOGGLE; Delay 10; Power2 TOGGLE ENDON` |
|
|
||||||
| `RuleTimer1` | 0-3600 | Set rule timer 1 | `RuleTimer1 60` |
|
|
||||||
| `RuleTimer2` | 0-3600 | Set rule timer 2 | `RuleTimer2 120` |
|
|
||||||
| `Mem1` | value | Set memory 1 | `Mem1 Hello` |
|
|
||||||
| `Mem2` | value | Set memory 2 | `Mem2 World` |
|
|
||||||
| `Var1` | value | Set variable 1 | `Var1 42` |
|
|
||||||
| `Var2` | value | Set variable 2 | `Var2 3.14` |
|
|
||||||
| `CalcRes` | 0-7 | Set calculation resolution | `CalcRes 2` |
|
|
||||||
|
|
||||||
### Berry Script Commands (ESP32)
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `Br` | code | Execute Berry code | `Br print("Hello")` |
|
|
||||||
| `BrLoad` | filename | Load Berry file | `BrLoad autoexec.be` |
|
|
||||||
| `BrRun` | filename | Run Berry file | `BrRun script.be` |
|
|
||||||
| `BrRestart` | - | Restart Berry VM | `BrRestart` |
|
|
||||||
|
|
||||||
### Energy Monitoring Commands
|
|
||||||
|
|
||||||
| Command | Parameters | Description | Example |
|
|
||||||
|---------|------------|-------------|---------|
|
|
||||||
| `PowerCal` | value | Calibrate power | `PowerCal 12530` |
|
|
||||||
| `VoltageCal` | value | Calibrate voltage | `VoltageCal 1950` |
|
|
||||||
| `CurrentCal` | value | Calibrate current | `CurrentCal 3500` |
|
|
||||||
| `PowerSet` | watts | Set power reading | `PowerSet 100` |
|
|
||||||
| `VoltageSet` | volts | Set voltage reading | `VoltageSet 230` |
|
|
||||||
| `CurrentSet` | amps | Set current reading | `CurrentSet 0.43` |
|
|
||||||
| `FrequencySet` | hz | Set frequency reading | `FrequencySet 50` |
|
|
||||||
| `EnergyReset1` | kWh | Reset energy total | `EnergyReset1 0` |
|
|
||||||
| `EnergyReset2` | kWh | Reset energy yesterday | `EnergyReset2 0` |
|
|
||||||
| `EnergyReset3` | kWh | Reset energy today | `EnergyReset3 0` |
|
|
||||||
| `MaxPower` | watts | Set max power | `MaxPower 3500` |
|
|
||||||
| `MaxPowerHold` | seconds | Set max power hold | `MaxPowerHold 10` |
|
|
||||||
| `MaxPowerWindow` | seconds | Set max power window | `MaxPowerWindow 30` |
|
|
||||||
| `SafePower` | watts | Set safe power | `SafePower 3000` |
|
|
||||||
| `SafePowerHold` | seconds | Set safe power hold | `SafePowerHold 10` |
|
|
||||||
| `SafePowerWindow` | seconds | Set safe power window | `SafePowerWindow 30` |
|
|
||||||
|
|
||||||
## Complete Logging and Debug Reference
|
|
||||||
|
|
||||||
### Log Levels
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define LOG_LEVEL_NONE 0 // No logging
|
|
||||||
#define LOG_LEVEL_ERROR 1 // Critical errors only
|
|
||||||
#define LOG_LEVEL_INFO 2 // Errors and info
|
|
||||||
#define LOG_LEVEL_DEBUG 3 // Errors, info and debug
|
|
||||||
#define LOG_LEVEL_DEBUG_MORE 4 // All logging
|
|
||||||
```
|
|
||||||
|
|
||||||
### Logging Functions
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Main logging function
|
|
||||||
void AddLog(uint32_t loglevel, const char* formatP, ...);
|
|
||||||
|
|
||||||
// Convenience macros
|
|
||||||
#define AddLog_P(loglevel, formatP, ...) AddLog(loglevel, PSTR(formatP), ##__VA_ARGS__)
|
|
||||||
#define AddLog_P2(loglevel, formatP, ...) AddLog(loglevel, formatP, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
// Debug logging (only in debug builds)
|
|
||||||
#ifdef DEBUG_TASMOTA_CORE
|
|
||||||
#define DEBUG_CORE_LOG(...) AddLog(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define DEBUG_CORE_LOG(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_TASMOTA_DRIVER
|
|
||||||
#define DEBUG_DRIVER_LOG(...) AddLog(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define DEBUG_DRIVER_LOG(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_TASMOTA_SENSOR
|
|
||||||
#define DEBUG_SENSOR_LOG(...) AddLog(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define DEBUG_SENSOR_LOG(...)
|
|
||||||
#endif
|
|
||||||
```
|
|
||||||
|
|
||||||
### Debug Build Options
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Enable in user_config_override.h for debugging
|
|
||||||
#define DEBUG_TASMOTA_CORE // Core system debugging
|
|
||||||
#define DEBUG_TASMOTA_DRIVER // Driver debugging
|
|
||||||
#define DEBUG_TASMOTA_SENSOR // Sensor debugging
|
|
||||||
#define USE_DEBUG_DRIVER // Enable debug driver
|
|
||||||
#define DEBUG_TASMOTA_PORT Serial // Debug output port
|
|
||||||
```
|
|
||||||
|
|
||||||
### Memory Debugging
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Memory monitoring functions
|
|
||||||
uint32_t ESP_getFreeHeap(void);
|
|
||||||
uint32_t ESP_getMaxAllocHeap(void);
|
|
||||||
uint8_t ESP_getHeapFragmentation(void);
|
|
||||||
uint32_t ESP_getFreeContStack(void);
|
|
||||||
|
|
||||||
// Memory debugging macros
|
|
||||||
#define SHOW_FREE_MEM(x) AddLog(LOG_LEVEL_DEBUG, PSTR(x " free mem: %d"), ESP_getFreeHeap())
|
|
||||||
#define CHECK_OOM() if (ESP_getFreeHeap() < 1000) AddLog(LOG_LEVEL_ERROR, PSTR("Low memory: %d"), ESP_getFreeHeap())
|
|
||||||
```
|
|
||||||
|
|
||||||
## Complete I2C Reference
|
|
||||||
|
|
||||||
### I2C Configuration
|
|
||||||
|
|
||||||
```c
|
|
||||||
// I2C pins (can be changed via GPIO configuration)
|
|
||||||
#define I2C_SDA_PIN 4 // Default SDA pin
|
|
||||||
#define I2C_SCL_PIN 5 // Default SCL pin
|
|
||||||
|
|
||||||
// I2C speeds
|
|
||||||
#define I2C_SPEED_SLOW 50000 // 50kHz
|
|
||||||
#define I2C_SPEED_STANDARD 100000 // 100kHz
|
|
||||||
#define I2C_SPEED_FAST 400000 // 400kHz
|
|
||||||
#define I2C_SPEED_FAST_PLUS 1000000 // 1MHz
|
|
||||||
```
|
|
||||||
|
|
||||||
### I2C Helper Functions
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Basic I2C operations
|
|
||||||
bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size);
|
|
||||||
bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cValidRead16LE(uint16_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cValidReadS32(int32_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
bool I2cValidReadS32_LE(int32_t *data, uint8_t addr, uint8_t reg);
|
|
||||||
|
|
||||||
uint8_t I2cRead8(uint8_t addr, uint8_t reg);
|
|
||||||
uint16_t I2cRead16(uint8_t addr, uint8_t reg);
|
|
||||||
uint16_t I2cRead16LE(uint8_t addr, uint8_t reg);
|
|
||||||
int32_t I2cRead24(uint8_t addr, uint8_t reg);
|
|
||||||
int32_t I2cReadS32(uint8_t addr, uint8_t reg);
|
|
||||||
int32_t I2cReadS32_LE(uint8_t addr, uint8_t reg);
|
|
||||||
|
|
||||||
bool I2cWrite8(uint8_t addr, uint8_t reg, uint8_t val);
|
|
||||||
bool I2cWrite16(uint8_t addr, uint8_t reg, uint16_t val);
|
|
||||||
bool I2cWrite16LE(uint8_t addr, uint8_t reg, uint16_t val);
|
|
||||||
|
|
||||||
// Buffer operations
|
|
||||||
uint8_t I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len);
|
|
||||||
uint8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len);
|
|
||||||
|
|
||||||
// Device detection
|
|
||||||
bool I2cActive(uint8_t addr);
|
|
||||||
void I2cScan(char *devs, unsigned int devs_len);
|
|
||||||
void I2cResetActive(uint8_t addr, uint8_t count = 1);
|
|
||||||
void I2cSetActive(uint8_t addr, uint8_t count = 1);
|
|
||||||
void I2cSetActiveFound(uint8_t addr, const char *types);
|
|
||||||
```
|
|
||||||
|
|
||||||
### I2C Device Detection Pattern
|
|
||||||
|
|
||||||
```c
|
|
||||||
void MySensorDetect(void) {
|
|
||||||
if (MySensorDetected) return;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < SENSOR_MAX_ADDR; i++) {
|
|
||||||
uint8_t addr = SENSOR_BASE_ADDR + i;
|
|
||||||
if (I2cActive(addr)) continue; // Address already in use
|
|
||||||
|
|
||||||
if (I2cValidRead8(&sensor_id, addr, SENSOR_ID_REG)) {
|
|
||||||
if (sensor_id == EXPECTED_SENSOR_ID) {
|
|
||||||
I2cSetActiveFound(addr, "MySensor");
|
|
||||||
MySensorDetected = true;
|
|
||||||
MySensorAddress = addr;
|
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("MySensor found at address 0x%02X"), addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This comprehensive developer reference provides all the essential information needed to understand, extend, and debug Tasmota firmware. The detailed callback system, complete command reference, GPIO configuration options, and debugging tools give developers everything needed to create robust IoT solutions.
|
|
File diff suppressed because it is too large
Load Diff
1
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@ -32,7 +32,6 @@ _Make sure your have performed every step and checked the applicable boxes befor
|
|||||||
- [ ] Searched the problem in [discussions](https://github.com/arendst/Tasmota/discussions)
|
- [ ] Searched the problem in [discussions](https://github.com/arendst/Tasmota/discussions)
|
||||||
- [ ] Searched the problem in the [docs](https://tasmota.github.io/docs/FAQ)
|
- [ ] Searched the problem in the [docs](https://tasmota.github.io/docs/FAQ)
|
||||||
- [ ] Searched the problem in the [chat](https://discord.gg/Ks2Kzd4)
|
- [ ] Searched the problem in the [chat](https://discord.gg/Ks2Kzd4)
|
||||||
- [ ] Problem is not scripter related, in this case open a discussion and tag gemu2015
|
|
||||||
- [ ] Device used (e.g., Sonoff Basic): _____
|
- [ ] Device used (e.g., Sonoff Basic): _____
|
||||||
- [ ] Tasmota binary firmware version number used: _____
|
- [ ] Tasmota binary firmware version number used: _____
|
||||||
- [ ] Pre-compiled
|
- [ ] Pre-compiled
|
||||||
|
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -6,8 +6,8 @@
|
|||||||
- [ ] The pull request is done against the latest development branch
|
- [ ] The pull request is done against the latest development branch
|
||||||
- [ ] Only relevant files were touched
|
- [ ] Only relevant files were touched
|
||||||
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
|
- [ ] 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.8
|
- [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.6
|
||||||
- [ ] The code change is tested and works with Tasmota core ESP32 V.3.1.3.250712
|
- [ ] The code change is tested and works with Tasmota core ESP32 V.3.0.0
|
||||||
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
|
- [ ] 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**_
|
_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_
|
||||||
|
142
.github/workflows/Tasmota_build_devel.yml
vendored
142
.github/workflows/Tasmota_build_devel.yml
vendored
@ -24,32 +24,36 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
|
- name: Install clang compiler
|
||||||
- name: Make Berry and Solidify code
|
run: |
|
||||||
|
sudo apt-get install -f clang
|
||||||
|
- name: Make Berry and Tasmota Berry code
|
||||||
run: |
|
run: |
|
||||||
cd lib/libesp32/berry
|
cd lib/libesp32/berry
|
||||||
make
|
make
|
||||||
cd ../berry_tasmota
|
cd ../berry_tasmota
|
||||||
../berry/berry -s -g solidify_all.be
|
../berry/berry -s -g solidify_all.be
|
||||||
cd ../berry_matter
|
- name: Matter Berry Code
|
||||||
|
run: |
|
||||||
|
cd lib/libesp32/berry_matter
|
||||||
../berry/berry -s -g solidify_all.be
|
../berry/berry -s -g solidify_all.be
|
||||||
cd ../berry_animate
|
- name: Berry Animate Code
|
||||||
|
run: |
|
||||||
|
cd lib/libesp32/berry_animate
|
||||||
../berry/berry -s -g solidify_all.be
|
../berry/berry -s -g solidify_all.be
|
||||||
cd ../../libesp32_lvgl/lv_binding_berry
|
- name: LVGL Berry Code
|
||||||
|
run: |
|
||||||
|
cd lib/libesp32_lvgl/lv_binding_berry
|
||||||
../../libesp32/berry/berry -s -g solidify_all.be
|
../../libesp32/berry/berry -s -g solidify_all.be
|
||||||
cd ../lv_haspmota
|
- name: HASPmota Berry Code
|
||||||
|
run: |
|
||||||
|
cd lib/libesp32_lvgl/lv_haspmota
|
||||||
../../libesp32/berry/berry -s -g solidify_all.be
|
../../libesp32/berry/berry -s -g solidify_all.be
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: berry
|
name: '["berry_tasmota", "berry_matter", "berry_animate", "berry_lvgl", "berry_haspmota", "berry_header"]'
|
||||||
path: |
|
path: '["./lib/libesp32/berry_tasmota/src/solidify", "./lib/libesp32/berry_matter/src/solidify", "./lib/libesp32/berry_animate/src/solidify", "./lib/libesp32_lvgl/lv_binding_berry/src/solidify", "./lib/libesp32_lvgl/lv_haspmota/src/solidify", "./lib/libesp32/berry/generate"]'
|
||||||
./lib/libesp32/berry_tasmota/src/solidify
|
|
||||||
./lib/libesp32/berry_matter/src/solidify
|
|
||||||
./lib/libesp32/berry_animate/src/solidify
|
|
||||||
./lib/libesp32_lvgl/lv_binding_berry/src/solidify
|
|
||||||
./lib/libesp32_lvgl/lv_haspmota/src/solidify
|
|
||||||
./lib/libesp32/berry/generate
|
|
||||||
|
|
||||||
push_solidified:
|
push_solidified:
|
||||||
needs: be_solidify
|
needs: be_solidify
|
||||||
@ -61,20 +65,23 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- uses: actions/download-artifact@v4
|
- uses: jason2866/download-artifact@v3.0.4
|
||||||
with:
|
with:
|
||||||
pattern: berry
|
name: |
|
||||||
path: berry
|
berry_tasmota
|
||||||
- name: Move solidified Berry files back
|
berry_matter
|
||||||
run: |
|
berry_animate
|
||||||
ls -R ./berry
|
berry_lvgl
|
||||||
mv berry/berry/libesp32/berry_tasmota/src/solidify/* ./lib/libesp32/berry_tasmota/src/solidify
|
berry_haspmota
|
||||||
mv berry/berry/libesp32/berry_matter/src/solidify/* ./lib/libesp32/berry_matter/src/solidify
|
berry_header
|
||||||
mv berry/berry/libesp32/berry_animate/src/solidify/* ./lib/libesp32/berry_animate/src/solidify
|
path: |
|
||||||
mv berry/berry/libesp32_lvgl/lv_binding_berry/src/solidify/* ./lib/libesp32_lvgl/lv_binding_berry/src/solidify
|
./lib/libesp32/berry_tasmota/src/solidify
|
||||||
mv berry/berry/libesp32_lvgl/lv_haspmota/src/solidify/* ./lib/libesp32_lvgl/lv_haspmota/src/solidify
|
./lib/libesp32/berry_matter/src/solidify
|
||||||
mv berry/berry/libesp32/berry/generate/* ./lib/libesp32/berry/generate
|
./lib/libesp32/berry_animate/src/solidify
|
||||||
|
./lib/libesp32_lvgl/lv_binding_berry/src/solidify
|
||||||
|
./lib/libesp32_lvgl/lv_haspmota/src/solidify
|
||||||
|
./lib/libesp32/berry/generate
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
with:
|
with:
|
||||||
commit_message: Solidified Code updated
|
commit_message: Solidified Code updated
|
||||||
@ -98,8 +105,6 @@ jobs:
|
|||||||
- tasmota32s3ser-safeboot
|
- tasmota32s3ser-safeboot
|
||||||
- tasmota32c6-safeboot
|
- tasmota32c6-safeboot
|
||||||
- tasmota32c6ser-safeboot
|
- tasmota32c6ser-safeboot
|
||||||
- tasmota32p4-safeboot
|
|
||||||
- tasmota32p4ser-safeboot
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -107,11 +112,11 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Add SHA to footer
|
- name: Add SHA to footer
|
||||||
run: |
|
run: |
|
||||||
@ -119,17 +124,14 @@ jobs:
|
|||||||
SHA=${COMMIT_SHA_LONG::7}
|
SHA=${COMMIT_SHA_LONG::7}
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
#- name: Use esp32-solo1 safeboot for esp32 too
|
#- name: Use esp32-solo1 safeboot for esp32 too
|
||||||
#run: |
|
#run: |
|
||||||
#cp ./build_output/firmware/tasmota32solo1-safeboot.bin ./build_output/firmware/tasmota32-safeboot.bin
|
#cp ./build_output/firmware/tasmota32solo1-safeboot.bin ./build_output/firmware/tasmota32-safeboot.bin
|
||||||
- name: Upload safeboot firmware artifacts
|
- name: Upload safeboot firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware_safeboot
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
base-images:
|
base-images:
|
||||||
@ -157,25 +159,22 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
- name: Add SHA to footer
|
- name: Add SHA to footer
|
||||||
run: |
|
run: |
|
||||||
COMMIT_SHA_LONG=$(git rev-parse --short HEAD || echo "")
|
COMMIT_SHA_LONG=$(git rev-parse --short HEAD || echo "")
|
||||||
SHA=${COMMIT_SHA_LONG::7}
|
SHA=${COMMIT_SHA_LONG::7}
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- name: Upload firmware artifacts
|
- name: Upload firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
base32-images:
|
base32-images:
|
||||||
@ -197,7 +196,6 @@ jobs:
|
|||||||
- tasmota32c2
|
- tasmota32c2
|
||||||
- tasmota32c3
|
- tasmota32c3
|
||||||
- tasmota32c6
|
- tasmota32c6
|
||||||
- tasmota32p4
|
|
||||||
- tasmota32s2
|
- tasmota32s2
|
||||||
- tasmota32s2cdc
|
- tasmota32s2cdc
|
||||||
- tasmota32s3
|
- tasmota32s3
|
||||||
@ -209,35 +207,28 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Download safeboot firmwares
|
- name: Download safeboot firmwares
|
||||||
uses: actions/download-artifact@v4
|
uses: jason2866/download-artifact@v3.0.4
|
||||||
with:
|
with:
|
||||||
pattern: tasmota32*
|
name: firmware_safeboot
|
||||||
path: ./temp
|
path: ./firmware
|
||||||
- name: Move safeboot files
|
|
||||||
run: |
|
|
||||||
mkdir -p ./firmware/firmware
|
|
||||||
find ./temp -type f -exec cp -t ./firmware/firmware {} +
|
|
||||||
- name: Add SHA to footer
|
- name: Add SHA to footer
|
||||||
run: |
|
run: |
|
||||||
COMMIT_SHA_LONG=$(git rev-parse --short HEAD || echo "")
|
COMMIT_SHA_LONG=$(git rev-parse --short HEAD || echo "")
|
||||||
SHA=${COMMIT_SHA_LONG::7}
|
SHA=${COMMIT_SHA_LONG::7}
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- name: Upload firmware artifacts
|
- name: Upload firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
language-images:
|
language-images:
|
||||||
@ -248,7 +239,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
variant: [ tasmota, tasmota32 ]
|
variant: [ tasmota, tasmota32 ]
|
||||||
language: [ AD, AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, LT, 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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -256,35 +247,28 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Download safeboot firmwares
|
- name: Download safeboot firmwares
|
||||||
uses: actions/download-artifact@v4
|
uses: jason2866/download-artifact@v3.0.4
|
||||||
with:
|
with:
|
||||||
pattern: tasmota32*
|
name: firmware_safeboot
|
||||||
path: ./temp
|
path: ./firmware
|
||||||
- name: Move safeboot files
|
|
||||||
run: |
|
|
||||||
mkdir -p ./firmware/firmware
|
|
||||||
find ./temp -type f -exec cp -t ./firmware/firmware {} +
|
|
||||||
- name: Add SHA to footer
|
- name: Add SHA to footer
|
||||||
run: |
|
run: |
|
||||||
COMMIT_SHA_LONG=$(git rev-parse --short HEAD || echo "")
|
COMMIT_SHA_LONG=$(git rev-parse --short HEAD || echo "")
|
||||||
SHA=${COMMIT_SHA_LONG::7}
|
SHA=${COMMIT_SHA_LONG::7}
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT $SHA-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
|
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
|
||||||
- name: Upload language firmware artifacts
|
- name: Upload language firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}-${{ matrix.language }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
Start_final_copy:
|
Start_final_copy:
|
||||||
|
103
.github/workflows/Tasmota_build_master.yml
vendored
103
.github/workflows/Tasmota_build_master.yml
vendored
@ -32,8 +32,6 @@ jobs:
|
|||||||
- tasmota32s3ser-safeboot
|
- tasmota32s3ser-safeboot
|
||||||
- tasmota32c6-safeboot
|
- tasmota32c6-safeboot
|
||||||
- tasmota32c6ser-safeboot
|
- tasmota32c6ser-safeboot
|
||||||
- tasmota32p4-safeboot
|
|
||||||
- tasmota32p4ser-safeboot
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -41,24 +39,21 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Add "release" to footer
|
- name: Add "release" to footer
|
||||||
run: |
|
run: |
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- name: Upload safeboot firmware artifacts
|
- name: Upload safeboot firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware_safeboot
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
base-images:
|
base-images:
|
||||||
@ -85,24 +80,21 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Add "release" to footer
|
- name: Add "release" to footer
|
||||||
run: |
|
run: |
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- name: Upload firmware artifacts
|
- name: Upload firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
base32-images:
|
base32-images:
|
||||||
@ -124,7 +116,6 @@ jobs:
|
|||||||
- tasmota32c2
|
- tasmota32c2
|
||||||
- tasmota32c3
|
- tasmota32c3
|
||||||
- tasmota32c6
|
- tasmota32c6
|
||||||
- tasmota32p4
|
|
||||||
- tasmota32s2
|
- tasmota32s2
|
||||||
- tasmota32s2cdc
|
- tasmota32s2cdc
|
||||||
- tasmota32s3
|
- tasmota32s3
|
||||||
@ -136,33 +127,29 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Download safeboot firmwares
|
- name: Download safeboot firmwares
|
||||||
uses: actions/download-artifact@v4
|
uses: jason2866/download-artifact@v3.0.4
|
||||||
with:
|
with:
|
||||||
pattern: tasmota32*
|
name: firmware_safeboot
|
||||||
path: ./temp
|
path: ./firmware
|
||||||
- name: Move safeboot files
|
- name: Display downloaded files
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ./firmware/firmware
|
ls -R ./firmware/
|
||||||
find ./temp -type f -exec cp -t ./firmware/firmware {} +
|
|
||||||
- name: Add "release" to footer
|
- name: Add "release" to footer
|
||||||
run: |
|
run: |
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- name: Upload firmware artifacts
|
- name: Upload firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
language-images:
|
language-images:
|
||||||
@ -173,7 +160,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
variant: [ tasmota, tasmota32 ]
|
variant: [ tasmota, tasmota32 ]
|
||||||
language: [ AD, AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, LT, 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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -181,33 +168,29 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
pip install -U platformio
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Download safeboot firmwares
|
- name: Download safeboot firmwares
|
||||||
uses: actions/download-artifact@v4
|
uses: jason2866/download-artifact@v3.0.4
|
||||||
with:
|
with:
|
||||||
pattern: tasmota32*
|
name: firmware_safeboot
|
||||||
path: ./temp
|
path: ./firmware
|
||||||
- name: Move safeboot files
|
- name: Display downloaded files
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ./firmware/firmware
|
ls -R ./firmware/
|
||||||
find ./temp -type f -exec cp -t ./firmware/firmware {} +
|
|
||||||
- name: Add "release" to footer
|
- name: Add "release" to footer
|
||||||
run: |
|
run: |
|
||||||
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
|
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
|
||||||
- name: Upload language firmware artifacts
|
- name: Upload language firmware artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}-${{ matrix.language }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
Release:
|
Release:
|
||||||
@ -216,24 +199,28 @@ jobs:
|
|||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Download all Tasmota artifacts
|
- name: Download Tasmota firmwares
|
||||||
uses: actions/download-artifact@v4
|
uses: jason2866/download-artifact@v3.0.4
|
||||||
with:
|
with:
|
||||||
pattern: tasmota*
|
name: firmware
|
||||||
path: ./temp
|
path: ./mv_firmware
|
||||||
- name: Move files
|
- name: Download safeboot firmwares
|
||||||
run: |
|
uses: jason2866/download-artifact@v3.0.4
|
||||||
mkdir -p ./release
|
with:
|
||||||
find ./temp -type f -exec cp -t ./release {} +
|
name: firmware_safeboot
|
||||||
|
path: ./mv_firmware
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -R ./release/
|
run: ls -R ./mv_firmware/
|
||||||
|
- name: Zip all map.gz files in one file -> map_all.zip
|
||||||
|
run: 7z a -mx=9 -tzip -xr'!.*' map_all.zip mv_firmware/map
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: jason2866/action-gh-release@v1.2
|
uses: jason2866/action-gh-release@v1.2
|
||||||
#if: startsWith(github.ref, 'refs/tags/')
|
#if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.run_number }}
|
tag_name: ${{ github.run_number }}
|
||||||
files: |
|
files: |
|
||||||
./release/tasmota*
|
./mv_firmware/firmware/*
|
||||||
|
map_all.zip
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
110
.github/workflows/build_all_the_things.yml
vendored
110
.github/workflows/build_all_the_things.yml
vendored
@ -19,35 +19,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
os-check-win:
|
os-check-win:
|
||||||
runs-on: windows-latest
|
runs-on: windows-2019
|
||||||
if: github.repository == 'arendst/Tasmota'
|
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
variant:
|
|
||||||
- tasmota32-webcam
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.13'
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
pip install uv
|
|
||||||
uv pip install --system platformio
|
|
||||||
- name: Run PlatformIO
|
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.variant }}
|
|
||||||
path: ./build_output
|
|
||||||
|
|
||||||
os-check-mac:
|
|
||||||
runs-on: macos-14
|
|
||||||
if: github.repository == 'arendst/Tasmota'
|
if: github.repository == 'arendst/Tasmota'
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
@ -59,19 +31,47 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
#python -m pip install --upgrade pip
|
||||||
|
pip install -U platformio
|
||||||
|
#platformio upgrade --dev
|
||||||
|
#platformio update
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware
|
||||||
|
path: ./build_output
|
||||||
|
|
||||||
|
os-check-mac:
|
||||||
|
runs-on: macos-14
|
||||||
|
if: github.repository == 'arendst/Tasmota'
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
variant:
|
||||||
|
- tasmota32-webcam
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.12'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install wheel
|
||||||
|
#python -m pip install --upgrade pip
|
||||||
|
pip install -U platformio
|
||||||
|
#platformio upgrade --dev
|
||||||
|
#platformio update
|
||||||
|
- name: Run PlatformIO
|
||||||
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
|
- uses: jason2866/upload-artifact@v2.0.3
|
||||||
|
with:
|
||||||
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
base-images:
|
base-images:
|
||||||
@ -95,7 +95,6 @@ jobs:
|
|||||||
- tasmota32c2
|
- tasmota32c2
|
||||||
- tasmota32c3
|
- tasmota32c3
|
||||||
- tasmota32c6
|
- tasmota32c6
|
||||||
- tasmota32p4
|
|
||||||
- tasmota32s2
|
- tasmota32s2
|
||||||
- tasmota32s2cdc
|
- tasmota32s2cdc
|
||||||
- tasmota32s3
|
- tasmota32s3
|
||||||
@ -113,26 +112,25 @@ jobs:
|
|||||||
- tasmota32c2-safeboot
|
- tasmota32c2-safeboot
|
||||||
- tasmota32c3-safeboot
|
- tasmota32c3-safeboot
|
||||||
- tasmota32c6-safeboot
|
- tasmota32c6-safeboot
|
||||||
- tasmota32p4-safeboot
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
#python -m pip install --upgrade pip
|
||||||
|
pip install -U platformio
|
||||||
|
#platformio upgrade --dev
|
||||||
|
#platformio update
|
||||||
cp ./platformio_override_sample.ini ./platformio_override.ini
|
cp ./platformio_override_sample.ini ./platformio_override.ini
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}
|
run: platformio run -e ${{ matrix.variant }}
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
|
||||||
language-images:
|
language-images:
|
||||||
@ -142,23 +140,23 @@ jobs:
|
|||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
variant: [ tasmota ]
|
variant: [ tasmota ]
|
||||||
language: [ AD, AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, LT, 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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.x'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
pip install uv
|
pip install wheel
|
||||||
uv pip install --system platformio
|
#python -m pip install --upgrade pip
|
||||||
|
pip install -U platformio
|
||||||
|
#platformio upgrade --dev
|
||||||
|
#platformio update
|
||||||
- name: Run PlatformIO
|
- name: Run PlatformIO
|
||||||
env:
|
|
||||||
PYTHONIOENCODING: utf-8
|
|
||||||
PYTHONUTF8: '1'
|
|
||||||
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
|
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: jason2866/upload-artifact@v2.0.3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.variant }}-${{ matrix.language }}
|
name: firmware
|
||||||
path: ./build_output
|
path: ./build_output
|
||||||
|
15
.gitignore
vendored
15
.gitignore
vendored
@ -8,25 +8,17 @@
|
|||||||
*.o
|
*.o
|
||||||
*.gcno
|
*.gcno
|
||||||
*.gcda
|
*.gcda
|
||||||
dependencies.lock
|
|
||||||
|
|
||||||
## Project files ######
|
## Project files ######
|
||||||
managed_components
|
|
||||||
.platformio
|
.platformio
|
||||||
.pio
|
.pio
|
||||||
.clang_complete
|
.clang_complete
|
||||||
.gcc-flags.json
|
.gcc-flags.json
|
||||||
.cache
|
.cache
|
||||||
.dummy
|
|
||||||
sdkconfig.*
|
|
||||||
sdkconfig.defaults
|
|
||||||
CMakeLists.txt
|
|
||||||
data
|
data
|
||||||
unpacked_fs
|
unpacked_fs
|
||||||
unpacked_boards
|
unpacked_boards
|
||||||
tasmota/user_config_override.h
|
tasmota/user_config_override.h
|
||||||
tasmota/include/local_ca_data.h
|
|
||||||
tasmota/include/local_ca_descriptor.h
|
|
||||||
variants
|
variants
|
||||||
variants3
|
variants3
|
||||||
build
|
build
|
||||||
@ -50,10 +42,3 @@ lib/libesp32/berry/berry
|
|||||||
.vscode/extensions.json
|
.vscode/extensions.json
|
||||||
*.bak
|
*.bak
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
||||||
## IntelliJ ######
|
|
||||||
.idea
|
|
||||||
|
|
||||||
## Python virtual environments for Platformio ##
|
|
||||||
venv
|
|
||||||
.venv
|
|
||||||
|
4
.gitpod.Dockerfile
vendored
4
.gitpod.Dockerfile
vendored
@ -1,5 +1,3 @@
|
|||||||
FROM gitpod/workspace-python-3.13
|
FROM gitpod/workspace-python-3.11
|
||||||
|
|
||||||
RUN python -m pip install --break-system-packages uv
|
|
||||||
|
|
||||||
USER gitpod
|
USER gitpod
|
||||||
|
43
BUILDS.md
43
BUILDS.md
@ -8,19 +8,16 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | --------------------------- |
|
| ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | --------------------------- |
|
||||||
| MY_LANGUAGE en_GB | x | x / x | x | x | x | x |
|
| MY_LANGUAGE en_GB | x | x / x | x | x | x | x |
|
||||||
| USE_IMPROV | x | x / x | x | x | x | x |
|
| USE_IMPROV | x | x / x | x | x | x | x |
|
||||||
| USE_UFILESYS | - | - / x | - | - | - | - | Every ESP8266 > 1MB |
|
| USE_UFILESYS | - | - / x | - | - | - | - |
|
||||||
| USE_ARDUINO_OTA | - | - / - | - | - | - | - |
|
| USE_ARDUINO_OTA | - | - / - | - | - | - | - |
|
||||||
| USE_DOMOTICZ | - | x / x | x | x | x | - |
|
| USE_DOMOTICZ | - | x / x | x | x | x | - |
|
||||||
| USE_HOME_ASSISTANT | - | - / - | - | - | - | - |
|
| USE_HOME_ASSISTANT | - | - / - | - | - | - | - |
|
||||||
| USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x |
|
| USE_TASMOTA_DISCOVERY | x | x / x | x | x | x | x |
|
||||||
| USE_MQTT_TLS\* | - | - / x | - | - | - | - |
|
| USE_MQTT_TLS\* | - | - / x | - | - | - | - |
|
||||||
| USE_MQTT_CLIENT_CERT | - | - / - | - | - | - | - |
|
|
||||||
| USE_MQTT_AWS_IOT | - | - / - | - | - | - | - |
|
| USE_MQTT_AWS_IOT | - | - / - | - | - | - | - |
|
||||||
| USE_4K_RSA | - | - / - | - | - | - | - |
|
| USE_4K_RSA | - | - / - | - | - | - | - |
|
||||||
| USE_TELEGRAM | - | - / - | - | - | - | - |
|
| USE_TELEGRAM | - | - / - | - | - | - | - |
|
||||||
| USE_KNX | - | - / x | x | - | - | - |
|
| USE_KNX | - | - / x | x | - | - | - |
|
||||||
| USE_TELNET | - | - / - | - | - | - | - |
|
|
||||||
| USE_XYZMODEM | - | - / - | - | - | - | - |
|
|
||||||
| USE_WEBSERVER | x | x / x | x | x | x | x |
|
| USE_WEBSERVER | x | x / x | x | x | x | x |
|
||||||
| USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - |
|
| USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - |
|
||||||
| USE_EMULATION_HUE | x | x / x | - | x | - | - |
|
| USE_EMULATION_HUE | x | x / x | - | x | - | - |
|
||||||
@ -33,14 +30,11 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| USE_SUNRISE | x | x / x | x | x | x | x |
|
| USE_SUNRISE | x | x / x | x | x | x | x |
|
||||||
| USE_RULES | x | x / x | x | x | x | x |
|
| USE_RULES | x | x / x | x | x | x | x |
|
||||||
| USE_SCRIPT | - | - / - | - | - | - | - |
|
| USE_SCRIPT | - | - / - | - | - | - | - |
|
||||||
| USE_EXPRESSION | - | x / x | - | - | - | - |
|
| USE_EXPRESSION | - | - / x | - | - | - | - | Every ESP32 + ESP8266 > 1MB |
|
||||||
| SUPPORT_IF_STATEMENT | - | x / x | - | - | - | - |
|
| SUPPORT_IF_STATEMENT | - | - / x | - | - | - | - | Every ESP32 + ESP8266 > 1MB |
|
||||||
| USE_HOTPLUG | - | - / - | - | - | - | - |
|
| USE_HOTPLUG | - | - / - | - | - | - | - |
|
||||||
| USE_PROMETHEUS | - | - / - | - | - | - | - |
|
| USE_PROMETHEUS | - | - / - | - | - | - | - |
|
||||||
| USE_PING | - | - / - | - | - | - | - |
|
| USE_PING | - | - / - | - | - | - | - |
|
||||||
| USE_HDMI_CEC | - | - / - | - | - | - | - |
|
|
||||||
| USE_MAGIC_SWITCH | - | - / x | - | - | - | - |
|
|
||||||
| USE_GPIO_VIEWER | - | - / x | - | - | - | - |
|
|
||||||
| | | | | | | |
|
| | | | | | | |
|
||||||
| **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** |
|
| **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** |
|
||||||
| ROTARY_V1 | - | x / x | - | x | - | - |
|
| ROTARY_V1 | - | x / x | - | x | - | - |
|
||||||
@ -107,19 +101,10 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| | | | | | | |
|
| | | | | | | |
|
||||||
| **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** |
|
| **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** |
|
||||||
| USE_I2C | - | x / x | x | x | - | x |
|
| USE_I2C | - | x / x | x | x | - | x |
|
||||||
| USE_RTC_CHIPS | - | - / x | - | - | - | - |
|
|
||||||
| -USE_BM8563 | - | - / x | - | - | - | - |
|
|
||||||
| -USE_DS3231 | - | - / - | - | - | - | - |
|
|
||||||
| -USE_PCF85063 | - | - / - | - | - | - | - |
|
|
||||||
| -USE_PCF85363 | - | - / - | - | - | - | - |
|
|
||||||
| -USE_RX8010 | - | - / - | - | - | - | - |
|
|
||||||
| USE_SHT | - | - / x | - | x | - | - |
|
| USE_SHT | - | - / x | - | x | - | - |
|
||||||
| USE_HTU | - | - / x | - | x | - | - |
|
| USE_HTU | - | - / x | - | x | - | - |
|
||||||
| USE_BMP | - | - / x | - | x | - | - |
|
| USE_BMP | - | - / x | - | x | - | - |
|
||||||
| -USE_BME68X | - | - / x | - | x | - | - |
|
| USE_BME68X | - | - / x | - | x | - | - |
|
||||||
| USE_AMSX915 | - | - / - | - | - | - | - |
|
|
||||||
| USE_SPL06_007 | - | - / - | - | - | - | - |
|
|
||||||
| USE_QMP6988 | - | - / - | - | - | - | - |
|
|
||||||
| USE_BH1750 | - | - / x | - | x | - | - |
|
| USE_BH1750 | - | - / x | - | x | - | - |
|
||||||
| USE_VEML6070 | - | - / x | - | x | - | - |
|
| USE_VEML6070 | - | - / x | - | x | - | - |
|
||||||
| USE_ADS1115 | - | - / x | - | x | - | - |
|
| USE_ADS1115 | - | - / x | - | x | - | - |
|
||||||
@ -148,6 +133,7 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| USE_ENS16x | - | - / - | - | - | - | - |
|
| USE_ENS16x | - | - / - | - | - | - | - |
|
||||||
| USE_ENS210 | - | - / - | - | - | - | - |
|
| USE_ENS210 | - | - / - | - | - | - | - |
|
||||||
| USE_MPU6050 | - | - / - | - | - | - | - |
|
| USE_MPU6050 | - | - / - | - | - | - | - |
|
||||||
|
| USE_DS3231 | - | - / - | - | - | - | - |
|
||||||
| USE_MGC3130 | - | - / - | - | - | - | - |
|
| USE_MGC3130 | - | - / - | - | - | - | - |
|
||||||
| USE_MAX44009 | - | - / - | - | - | - | - |
|
| USE_MAX44009 | - | - / - | - | - | - | - |
|
||||||
| USE_SCD30 | - | - / x | - | x | - | - |
|
| USE_SCD30 | - | - / x | - | x | - | - |
|
||||||
@ -195,22 +181,22 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| USE_EZORTD | - | - / - | - | - | - | - |
|
| USE_EZORTD | - | - / - | - | - | - | - |
|
||||||
| USE_SEESAW_SOIL | - | - / - | - | - | - | - |
|
| USE_SEESAW_SOIL | - | - / - | - | - | - | - |
|
||||||
| USE_TOF10120 | - | - / - | - | - | - | - |
|
| USE_TOF10120 | - | - / - | - | - | - | - |
|
||||||
|
| USE_BM8563 | - | - / - | - | - | - | - |
|
||||||
| USE_AM2320 | - | - / - | - | - | - | - |
|
| USE_AM2320 | - | - / - | - | - | - | - |
|
||||||
| USE_T67XX | - | - / - | - | - | - | - |
|
| USE_T67XX | - | - / - | - | - | - | - |
|
||||||
| USE_HM330X | - | - / - | - | - | - | - |
|
| USE_HM330X | - | - / - | - | - | - | - |
|
||||||
| USE_HDC2010 | - | - / - | - | - | - | - |
|
| USE_HDC2010 | - | - / - | - | - | - | - |
|
||||||
|
| USE_PCF85363 | - | - / - | - | - | - | - |
|
||||||
| USE_DS3502 | - | - / - | - | - | - | - |
|
| USE_DS3502 | - | - / - | - | - | - | - |
|
||||||
| USE_HYT | - | - / - | - | - | - | - |
|
| USE_HYT | - | - / - | - | - | - | - |
|
||||||
| USE_LUXV30B | - | - / - | - | - | - | - |
|
| USE_LUXV30B | - | - / - | - | - | - | - |
|
||||||
| USE_HMC5883L | - | - / - | - | - | - | - |
|
| USE_HMC5883L | - | - / - | - | - | - | - |
|
||||||
| USE_QMC5883L | - | - / - | - | - | - | - |
|
| USE_QMC5883L | - | - / - | - | - | - | - |
|
||||||
| USE_MAX17043 | - | - / - | - | - | - | - |
|
|
||||||
| | | | | | | |
|
| | | | | | | |
|
||||||
| **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** |
|
| **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** |
|
||||||
| USE_SPI | - | - / x | - | - | - | x |
|
| USE_SPI | - | - / - | - | - | - | x |
|
||||||
| USE_RC522 | - | - / - | - | - | - | - |
|
| USE_RC522 | - | - / - | - | - | - | - |
|
||||||
| USE_CANSNIFFER | - | - / - | - | - | - | - |
|
| USE_CANSNIFFER | - | - / - | - | - | - | - |
|
||||||
| USE_SPI_LORA | - | - / x | - | - | - | - |
|
|
||||||
| USE_MHZ19 | - | - / x | - | x | - | - |
|
| USE_MHZ19 | - | - / x | - | x | - | - |
|
||||||
| USE_SENSEAIR | - | - / x | - | x | - | - |
|
| USE_SENSEAIR | - | - / x | - | x | - | - |
|
||||||
| USE_PMS5003 | - | - / x | - | x | - | - |
|
| USE_PMS5003 | - | - / x | - | x | - | - |
|
||||||
@ -231,15 +217,9 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| USE_MIEL_HVAC | - | - / - | - | - | - | - |
|
| USE_MIEL_HVAC | - | - / - | - | - | - | - |
|
||||||
| USE_PROJECTOR_CTRL | - | - / - | - | - | - | - |
|
| USE_PROJECTOR_CTRL | - | - / - | - | - | - | - |
|
||||||
| USE_AS608 | - | - / - | - | - | - | - |
|
| USE_AS608 | - | - / - | - | - | - | - |
|
||||||
| USE_LD2402 | - | - / - | - | - | - | - |
|
|
||||||
| USE_LD2410 | - | - / - | - | - | - | - |
|
| USE_LD2410 | - | - / - | - | - | - | - |
|
||||||
| USE_LD2410S | - | - / - | - | - | - | - |
|
|
||||||
| USE_GM861 | - | - / - | - | - | - | - |
|
| USE_GM861 | - | - / - | - | - | - | - |
|
||||||
| USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge / zbbrdgpro |
|
| USE_TCP_BRIDGE | - | - / - | - | - | - | - | zbbridge / zbbrdgpro |
|
||||||
| USE_HC8 | - | - / - | - | - | - | - |
|
|
||||||
| USE_PIPSOLAR | - | - / - | - | - | - | - |
|
|
||||||
| USE_WOOLIIS | - | - / - | - | - | - | - |
|
|
||||||
| USE_C8_CO2_5K | - | - / - | - | - | - | - |
|
|
||||||
| | | | | | | |
|
| | | | | | | |
|
||||||
| USE_NRF24 | - | - / - | - | - | - | - |
|
| USE_NRF24 | - | - / - | - | - | - | - |
|
||||||
| USE_MIBLE | - | - / - | - | - | - | - |
|
| USE_MIBLE | - | - / - | - | - | - | - |
|
||||||
@ -251,14 +231,11 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| USE_IR_RECEIVE | - | x / - | x | x | x | x |
|
| USE_IR_RECEIVE | - | x / - | x | x | x | x |
|
||||||
| USE_IR_REMOTE_FULL | - | - / - | - | - | x | - | Enable ALL protocols |
|
| USE_IR_REMOTE_FULL | - | - / - | - | - | x | - | Enable ALL protocols |
|
||||||
| | | | | | | |
|
| | | | | | | |
|
||||||
| USE_WIZMOTE | - | - / - | - | - | - | - |
|
|
||||||
| | | | | | | |
|
|
||||||
| USE_SR04 | - | - / - | - | x | - | - |
|
| USE_SR04 | - | - / - | - | x | - | - |
|
||||||
| USE_ME007 | - | - / - | - | - | - | - |
|
| USE_ME007 | - | - / - | - | - | - | - |
|
||||||
| USE_DYP | - | - / - | - | - | - | - |
|
| USE_DYP | - | - / - | - | - | - | - |
|
||||||
| USE_TM1638 | - | - / x | - | x | - | - |
|
| USE_TM1638 | - | - / x | - | x | - | - |
|
||||||
| USE_HX711 | - | - / x | - | x | - | - |
|
| USE_HX711 | - | - / x | - | x | - | - |
|
||||||
| -USE_HX711_M5SCALES | - | - / - | - | - | - | - |
|
|
||||||
| USE_TX2x_WIND_SENSOR | - | - / - | - | - | - | - |
|
| USE_TX2x_WIND_SENSOR | - | - / - | - | - | - | - |
|
||||||
| USE_WINDMETER | - | - / - | - | - | - | - |
|
| USE_WINDMETER | - | - / - | - | - | - | - |
|
||||||
| USE_RC_SWITCH | - | - / x | - | x | - | - |
|
| USE_RC_SWITCH | - | - / x | - | x | - | - |
|
||||||
@ -290,11 +267,11 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the
|
|||||||
| USE_WEBCAM | | / - | | | | |
|
| USE_WEBCAM | | / - | | | | |
|
||||||
| USE_ETHERNET | | / x | | | | |
|
| USE_ETHERNET | | / x | | | | |
|
||||||
| USE_I2S_AUDIO | | / - | | | | |
|
| USE_I2S_AUDIO | | / - | | | | |
|
||||||
|
| USE_TTGO_WATCH | | / - | | | | |
|
||||||
| USE_SONOFF_SPM | | / x | | | | |
|
| USE_SONOFF_SPM | | / x | | | | |
|
||||||
| USE_DISPLAY_TM1621_SONOFF | | / x | | | | |
|
| USE_DISPLAY_TM1621_SONOFF | | / x | | | | |
|
||||||
| USE_SHELLY_PRO | | / x | | | | |
|
| USE_SHELLY_PRO | | / x | | | | |
|
||||||
| USE_ESP32_TWAI | | / x | | | | |
|
| USE_DALI | | / - | | | | |
|
||||||
| USE_DALI | | / x | | | | |
|
|
||||||
| USE_DINGTIAN_RELAY | | / - | | | | |
|
| USE_DINGTIAN_RELAY | | / - | | | | |
|
||||||
| USE_MATTER_DEVICE | | / x | | | | | See SetOption151 |
|
| USE_MATTER_DEVICE | | / x | | | | | See SetOption151 |
|
||||||
|
|
||||||
|
877
CHANGELOG.md
877
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@ -1,8 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.16.0)
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
|
||||||
|
|
||||||
project(tasmota)
|
|
||||||
|
|
||||||
if(CONFIG_IDF_TARGET_ESP32C2)
|
|
||||||
include(relinker)
|
|
||||||
endif()
|
|
@ -85,13 +85,12 @@ In addition to @arendst the following code is mainly owned by:
|
|||||||
| xdrv_71_magic_switch | @barbudor
|
| xdrv_71_magic_switch | @barbudor
|
||||||
| xdrv_72_pipsolar | @chefpro
|
| xdrv_72_pipsolar | @chefpro
|
||||||
| xdrv_73_lora | @arendst
|
| xdrv_73_lora | @arendst
|
||||||
| xdrv_74_lorawan | @arendst
|
| xdrv_74 |
|
||||||
| xdrv_75_dali | @eeak, @arendst
|
| xdrv_75 |
|
||||||
| xdrv_76_serial_i2c | @s-hadinger
|
| xdrv_76 |
|
||||||
| xdrv_77_wizmote | @arendst
|
| xdrv_77 |
|
||||||
| xdrv_78_telnet | @arendst
|
| xdrv_78 |
|
||||||
| xdrv_79_esp32_ble | @staars, @btsimonh
|
| xdrv_79_esp32_ble | @staars, @btsimonh
|
||||||
| xdrv_80_wireguard_client | @s-hadinger
|
|
||||||
| xdrv_81_esp32_webcam | @gemu, @philrich
|
| xdrv_81_esp32_webcam | @gemu, @philrich
|
||||||
| xdrv_82_esp32_ethernet | @arendst
|
| xdrv_82_esp32_ethernet | @arendst
|
||||||
| xdrv_83_esp32_watch | @gemu
|
| xdrv_83_esp32_watch | @gemu
|
||||||
@ -99,15 +98,13 @@ In addition to @arendst the following code is mainly owned by:
|
|||||||
| xdrv_86_esp32_sonoff_spm | @arendst
|
| xdrv_86_esp32_sonoff_spm | @arendst
|
||||||
| xdrv_87_esp32_sonoff_tm1621 | @arendst
|
| xdrv_87_esp32_sonoff_tm1621 | @arendst
|
||||||
| xdrv_88_esp32_shelly_pro | @arendst
|
| xdrv_88_esp32_shelly_pro | @arendst
|
||||||
| xdrv_89_ |
|
| xdrv_89_esp32_dali | @eeak
|
||||||
| xdrv_90_esp32_dingtian_relay | @barbudor
|
| xdrv_90_esp32_dingtian_relay | @barbudor
|
||||||
| xdrv_91_esp32_twai | @arendst
|
| xdrv_91_ |
|
||||||
| xdrv_92_ |
|
| xdrv_92_ |
|
||||||
| xdrv_93_ |
|
| xdrv_93_ |
|
||||||
| xdrv_94_ |
|
| xdrv_94_ |
|
||||||
| |
|
| |
|
||||||
| xdrv_119_i2c_ap33772s | @arendst
|
|
||||||
| xdrv_120_xyzmodem | @arendst
|
|
||||||
| xdrv_121_gpioviewer | @arendst
|
| xdrv_121_gpioviewer | @arendst
|
||||||
| xdrv_122_file_settings_demo | @arendst
|
| xdrv_122_file_settings_demo | @arendst
|
||||||
| xdrv_122_file_json_settings_demo | @arendst
|
| xdrv_122_file_json_settings_demo | @arendst
|
||||||
@ -142,7 +139,7 @@ In addition to @arendst the following code is mainly owned by:
|
|||||||
| xsns_25_spl06-007_sensor | @rai68
|
| xsns_25_spl06-007_sensor | @rai68
|
||||||
| xsns_26_lm75ad | Andre Thomas
|
| xsns_26_lm75ad | Andre Thomas
|
||||||
| xsns_27_apds9960 | Shawn Hymel
|
| xsns_27_apds9960 | Shawn Hymel
|
||||||
| xsns_28_qmp6988 | @arendst
|
| xsns_28 |
|
||||||
| xsns_29_mcp230xx | Andre Thomas
|
| xsns_29_mcp230xx | Andre Thomas
|
||||||
| xsns_30_mpr121 | Rene 'Renne' Bartsch
|
| xsns_30_mpr121 | Rene 'Renne' Bartsch
|
||||||
| xsns_31_ccs811 | Gerhard Mutz
|
| xsns_31_ccs811 | Gerhard Mutz
|
||||||
@ -232,8 +229,6 @@ In addition to @arendst the following code is mainly owned by:
|
|||||||
| xsns_112_ens210 | Christoph Friese
|
| xsns_112_ens210 | Christoph Friese
|
||||||
| xsns_113_hc8 | Daniel Maier
|
| xsns_113_hc8 | Daniel Maier
|
||||||
| xsns_114_amsx915 | Bastian Urschel
|
| xsns_114_amsx915 | Bastian Urschel
|
||||||
| xsns_115_wooliis | Luca Melette
|
|
||||||
| xsns_117_c8_co2_5k | @jeroenvermeulen
|
|
||||||
| |
|
| |
|
||||||
| xsns_127_esp32_sensors | @arendst
|
| xsns_127_esp32_sensors | @arendst
|
||||||
| |
|
| |
|
||||||
|
@ -14,11 +14,11 @@ If you like **Tasmota**, give it a star, or fork it and contribute!
|
|||||||
[](https://github.com/arendst/Tasmota/network)
|
[](https://github.com/arendst/Tasmota/network)
|
||||||
[](https://paypal.me/tasmota)
|
[](https://paypal.me/tasmota)
|
||||||
|
|
||||||
See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/CHANGELOG.md) for changes since last release.
|
See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/CHANGELOG.md) for changes since last release.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
[](https://github.com/arendst/Tasmota)
|
[](https://github.com/arendst/Tasmota)
|
||||||
[](http://ota.tasmota.com/tasmota/)
|
[](http://ota.tasmota.com/tasmota/)
|
||||||
[](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22)
|
[](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22)
|
||||||
[](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22)
|
[](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22)
|
||||||
|
@ -32,7 +32,7 @@ Index | Define | Driver | Device | Address(es) | Bus2 | Descrip
|
|||||||
13 | USE_ADS1115 | xsns_12 | ADS1115 | 0x48 - 0x4B | Yes | 4-channel 16-bit A/D converter
|
13 | USE_ADS1115 | xsns_12 | ADS1115 | 0x48 - 0x4B | Yes | 4-channel 16-bit A/D converter
|
||||||
14 | USE_INA219 | xsns_13 | INA219 | 0x40 - 0x41, 0x44 - 0x45 | | Low voltage current sensor
|
14 | USE_INA219 | xsns_13 | INA219 | 0x40 - 0x41, 0x44 - 0x45 | | Low voltage current sensor
|
||||||
15 | USE_SHT3X | xsns_14 | SHT3X | 0x44 - 0x45 | Yes | Temperature and Humidity sensor
|
15 | USE_SHT3X | xsns_14 | SHT3X | 0x44 - 0x45 | Yes | Temperature and Humidity sensor
|
||||||
15 | USE_SHT3X | xsns_14 | SHT4X | 0x44 - 0x46 | Yes | Temperature and Humidity sensor
|
15 | USE_SHT3X | xsns_14 | SHT4X | 0x44 - 0x45 | Yes | Temperature and Humidity sensor
|
||||||
15 | USE_SHT3X | xsns_14 | SHTCX | 0x70 | Yes | Temperature and Humidity sensor
|
15 | USE_SHT3X | xsns_14 | SHTCX | 0x70 | Yes | Temperature and Humidity sensor
|
||||||
16 | USE_TSL2561 | xsns_16 | TSL2561 | 0x29, 0x39, 0x49 | | Light intensity sensor
|
16 | USE_TSL2561 | xsns_16 | TSL2561 | 0x29, 0x39, 0x49 | | Light intensity sensor
|
||||||
17 | USE_MGS | xsns_19 | Grove | 0x04 | | Multichannel gas sensor
|
17 | USE_MGS | xsns_19 | Grove | 0x04 | | Multichannel gas sensor
|
||||||
@ -123,14 +123,7 @@ Index | Define | Driver | Device | Address(es) | Bus2 | Descrip
|
|||||||
83 | USE_MAX17043 | xsns_110 | MAX17043 | 0x36 | | Fuel-gauge for 3.7 Volt Lipo battery
|
83 | USE_MAX17043 | xsns_110 | MAX17043 | 0x36 | | Fuel-gauge for 3.7 Volt Lipo battery
|
||||||
84 | USE_ENS16x | xsns_111 | ENS16x | 0x52 - 0x53 | | Gas (TVOC, eCO2) and air quality sensor
|
84 | USE_ENS16x | xsns_111 | ENS16x | 0x52 - 0x53 | | Gas (TVOC, eCO2) and air quality sensor
|
||||||
85 | USE_ENS210 | xsns_112 | ENS210 | 0x43 - 0x44 | | Temperature and humidity sensor
|
85 | USE_ENS210 | xsns_112 | ENS210 | 0x43 - 0x44 | | Temperature and humidity sensor
|
||||||
|
86 | USE_AMSX915 | xsns_114 | AMS5915 | 0x28 | | Pressure (absolute/differential) and temperature sensor
|
||||||
86 | USE_AMSX915 | xsns_114 | AMS6915 | 0x28 | | Pressure (absolute/differential) and temperature sensor
|
86 | USE_AMSX915 | xsns_114 | AMS6915 | 0x28 | | Pressure (absolute/differential) and temperature sensor
|
||||||
87 | USE_SPL06_007 | xsns_25 | SPL06-007 | 0x76 | | Pressure and temperature sensor
|
87 | USE_SPL06_007 | xsns_25 | SPL06-007 | 0x76 | | Pressure and temperature sensor
|
||||||
88 | USE_QMP6988 | xsns_28 | QMP6988 | 0x56, 0x70 | Yes | Pressure and temperature sensor
|
|
||||||
89 | USE_HX711_M5SCALES | xsns_34 | M5SCALES | 0x26 | Yes | M5Unit (Mini)Scales(HX711 STM32) U177
|
|
||||||
90 | USE_RX8010 | xdrv_56 | RX8010 | 0x32 | Yes | RX8010 RTC from IOTTIMER
|
|
||||||
91 | USE_MS5837 | xsns_116 | MS5837 | 0x76 | | Pressure and temperature sensor
|
|
||||||
92 | USE_PCF85063 | xdrv_56 | PCF85063 | 0x51 | | PCF85063 Real time clock
|
|
||||||
93 | USE_AS33772S | xdrv_119 | AS33772S | 0x52 | Yes | AS33772S USB PD Sink Controller
|
|
||||||
94 | USE_RV3028 | xdrv_56 | RV3028 | 0x52 | Yes | RV-3028-C7 RTC Controller
|
|
||||||
|
|
||||||
NOTE: Bus2 supported on ESP32 only.
|
NOTE: Bus2 supported on ESP32 only.
|
||||||
|
@ -94,4 +94,4 @@ Module | LCode | Description
|
|||||||
06 TTGO Watch | x | TTGO Watch
|
06 TTGO Watch | x | TTGO Watch
|
||||||
07 M5Stack Core2 | x | M5Stack Core2
|
07 M5Stack Core2 | x | M5Stack Core2
|
||||||
|
|
||||||
Over 2800 additional devices are supported using [templates](TEMPLATES.md).
|
Over 2500 additional devices are supported using [templates](TEMPLATES.md).
|
||||||
|
@ -31,7 +31,7 @@ Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
[](https://github.com/arendst/Tasmota)
|
[](https://github.com/arendst/Tasmota)
|
||||||
[](http://ota.tasmota.com/tasmota/)
|
[](http://ota.tasmota.com/tasmota/)
|
||||||
[](https://github.com/arendst/Tasmota/actions/workflows/build_all_the_things.yml)
|
[](https://github.com/arendst/Tasmota/actions/workflows/build_all_the_things.yml)
|
||||||
[](https://github.com/arendst/Tasmota/actions/workflows/Tasmota_build_devel.yml)
|
[](https://github.com/arendst/Tasmota/actions/workflows/Tasmota_build_devel.yml)
|
||||||
|
172
RELEASENOTES.md
172
RELEASENOTES.md
@ -34,11 +34,16 @@ While fallback or downgrading is common practice it was never supported due to S
|
|||||||
|
|
||||||
## Supported Core versions
|
## Supported Core versions
|
||||||
|
|
||||||
This release will be supported from ESP8266/Arduino library Core version **2.7.8** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
|
This release will be supported from ESP8266/Arduino library Core version **2.7.6** 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 **v3.1.3.250504**.
|
This release will be supported from ESP32/Arduino library Core version **3.0.0**.
|
||||||
|
|
||||||
Support of ESP8266 Core versions before 2.7.8 and ESP32 Core versions before v3.1.3.250504 have been removed.
|
Support of ESP8266 Core versions before 2.7.6 and ESP32 Core versions before 3.0.0 have been removed.
|
||||||
|
|
||||||
|
### Known issues with v14.0.0
|
||||||
|
|
||||||
|
Due to the change from ESP32 Arduino Core2/IDF4 to Arduino Core3/IDF5 not all functionality has been restored. The following features are known not to work on ESP32:
|
||||||
|
- Wifi Range Extender [#21200](https://github.com/arendst/Tasmota/issues/21200)
|
||||||
|
|
||||||
## Support of TLS
|
## Support of TLS
|
||||||
|
|
||||||
@ -55,7 +60,7 @@ Easy initial installation of Tasmota can be performed using the [Tasmota WebInst
|
|||||||
## Provided Binary Downloads
|
## Provided Binary Downloads
|
||||||
|
|
||||||
### ESP8266 or ESP8285 based
|
### ESP8266 or ESP8285 based
|
||||||
The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.8**.
|
The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.6**.
|
||||||
|
|
||||||
- **tasmota.bin** = The Tasmota version with most drivers for 1M+ flash. **RECOMMENDED RELEASE BINARY**
|
- **tasmota.bin** = The Tasmota version with most drivers for 1M+ flash. **RECOMMENDED RELEASE BINARY**
|
||||||
- **tasmota-4M.bin** = The Tasmota version with most drivers and filesystem for 4M+ flash.
|
- **tasmota-4M.bin** = The Tasmota version with most drivers and filesystem for 4M+ flash.
|
||||||
@ -75,12 +80,12 @@ Latest released binaries can be downloaded from
|
|||||||
- http://ota.tasmota.com/tasmota/release
|
- http://ota.tasmota.com/tasmota/release
|
||||||
|
|
||||||
Historical binaries can be downloaded from
|
Historical binaries can be downloaded from
|
||||||
- http://ota.tasmota.com/tasmota/release-15.0.1
|
- http://ota.tasmota.com/tasmota/release-14.0.0
|
||||||
|
|
||||||
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
|
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
|
||||||
|
|
||||||
### ESP32, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-S2 and ESP32-S3 based
|
### ESP32, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-S2 and ESP32-S3 based
|
||||||
The following binary downloads have been compiled with ESP32/Arduino library core version **v3.1.3.250504**.
|
The following binary downloads have been compiled with ESP32/Arduino library core version **3.0.0**.
|
||||||
|
|
||||||
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
|
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
|
||||||
- **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash.
|
- **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash.
|
||||||
@ -88,7 +93,7 @@ The following binary downloads have been compiled with ESP32/Arduino library cor
|
|||||||
- **tasmota32s2cdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial over embedded USB CDC only and 4M+ flash.
|
- **tasmota32s2cdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial over embedded USB CDC only and 4M+ flash.
|
||||||
- **tasmota32s3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S3 with USB HWCDC and fallback to serial and 4M+ flash.
|
- **tasmota32s3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S3 with USB HWCDC and fallback to serial and 4M+ flash.
|
||||||
- **tasmota32c2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with serial and 4M+ flash.
|
- **tasmota32c2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with serial and 4M+ flash.
|
||||||
- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 with USB HWCDC and fallback to serial and 4M+ flash.
|
- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with USB HWCDC and fallback to serial and 4M+ flash.
|
||||||
- **tasmota32c6.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C6 with USB HWCDC and fallback to serial and 4M+ flash.
|
- **tasmota32c6.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C6 with USB HWCDC and fallback to serial and 4M+ flash.
|
||||||
- **tasmota32-AD.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash.
|
- **tasmota32-AD.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash.
|
||||||
- **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash.
|
- **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash.
|
||||||
@ -104,7 +109,7 @@ Latest released binaries can be downloaded from
|
|||||||
- https://ota.tasmota.com/tasmota32/release
|
- https://ota.tasmota.com/tasmota32/release
|
||||||
|
|
||||||
Historical binaries can be downloaded from
|
Historical binaries can be downloaded from
|
||||||
- https://ota.tasmota.com/tasmota32/release-15.0.1
|
- https://ota.tasmota.com/tasmota32/release-14.0.0
|
||||||
|
|
||||||
The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin``
|
The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin``
|
||||||
|
|
||||||
@ -114,38 +119,137 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||||||
|
|
||||||
[Complete list](BUILDS.md) of available feature and sensors.
|
[Complete list](BUILDS.md) of available feature and sensors.
|
||||||
|
|
||||||
## Changelog v15.0.1.2
|
## Changelog v14.0.0 Rodney
|
||||||
### Added
|
### Added
|
||||||
- Commands `LoRaWanDecoder "` and `LoRaWanName "` to clear name [#23394](https://github.com/arendst/Tasmota/issues/23394)
|
- PlatformIO target reset [#21292](https://github.com/arendst/Tasmota/issues/21292)
|
||||||
- Command `I2sPause` [#23646](https://github.com/arendst/Tasmota/issues/23646)
|
- Command ``Wifi 6`` to enable 11ax on ESP32
|
||||||
- Support for RV3028 RTC [#23672](https://github.com/arendst/Tasmota/issues/23672)
|
- Command ``PowerLock`` to disable power control of selected outputs [#21081](https://github.com/arendst/Tasmota/issues/21081)
|
||||||
- Internal function 'WSContentSendRaw_P' [#23641](https://github.com/arendst/Tasmota/issues/23641)
|
- Command ``Publish3`` to send binary data encoded as Hex, disabled in safeboot [#21329](https://github.com/arendst/Tasmota/issues/21329)
|
||||||
- Universal display driver for ZJY169S0800TG01 ST7789 280x240 [#23638](https://github.com/arendst/Tasmota/issues/23638)
|
- Support for calculated heat index if temperature and humidity is available with ``#define USE_HEAT_INDEX`` [#4771](https://github.com/arendst/Tasmota/issues/4771)
|
||||||
- NeoPool add Redox tank alarm [#19811](https://github.com/arendst/Tasmota/issues/19811)
|
- Support for LoRa and single channel EU863-870 LoRaWanBridge [#17790](https://github.com/arendst/Tasmota/issues/17790)
|
||||||
- I2S additions [#23543](https://github.com/arendst/Tasmota/issues/23543)
|
- Support for AMS5915/AMS6915 temperature and pressure sensors [#20814](https://github.com/arendst/Tasmota/issues/20814)
|
||||||
- Basic support for ESP32-P4 [#23663](https://github.com/arendst/Tasmota/issues/23663)
|
- Support for LWT messages in TasMesh [#20392](https://github.com/arendst/Tasmota/issues/20392)
|
||||||
- ESP32-P4 command `HostedOta` [#23675](https://github.com/arendst/Tasmota/issues/23675)
|
- Support IR data larger than 64 bits [#20831](https://github.com/arendst/Tasmota/issues/20831)
|
||||||
- Berry f-strings now support ':' in expression [#23618](https://github.com/arendst/Tasmota/issues/23618)
|
- Support for MCP23S08 [#20971](https://github.com/arendst/Tasmota/issues/20971)
|
||||||
|
- Support for ESP32-S3 120Mhz [#20973](https://github.com/arendst/Tasmota/issues/20973)
|
||||||
|
- Support Azure iothub direct method [#21013](https://github.com/arendst/Tasmota/issues/21013)
|
||||||
|
- Support for Domoticz non-persistent ``DzIdx5`` to ``DzIdx32`` and disabling DOMOTICZ_OUT_TOPIC subscribe using command ``DzIdx0 0`` [#21019](https://github.com/arendst/Tasmota/issues/21019)
|
||||||
|
- Support SPI GPIO configuration for Universal Touch Screen [#21025](https://github.com/arendst/Tasmota/issues/21025)
|
||||||
|
- Support for SPL06_007 pressure and temperature sensor [#21185](https://github.com/arendst/Tasmota/issues/21185)
|
||||||
|
- Support for AHT30 Temperature and Humidity Sensor [#19922](https://github.com/arendst/Tasmota/issues/19922)
|
||||||
|
- Support for compile time hostname with `#define WIFI_DEFAULT_HOSTNAME` (#21236)[#21236](https://github.com/arendst/Tasmota/issues/21236)
|
||||||
|
- GPIOViewer pin mode support
|
||||||
|
- Zigbee support for attributes of type `uint48` used by energy monitoring [#20992](https://github.com/arendst/Tasmota/issues/20992)
|
||||||
|
- QMC5883l check for overflow and scale reading [#20643](https://github.com/arendst/Tasmota/issues/20643)
|
||||||
|
- TCP Serial bridge GPIO type `TCP Tx En` [#21269](https://github.com/arendst/Tasmota/issues/21269)
|
||||||
|
- ESP32 esp32_partition_app3904k_fs3392k partition scheme for 8MB ESP32S3 [#21241](https://github.com/arendst/Tasmota/issues/21241)
|
||||||
|
- ESP32 Compile option disabling PSRam check to avoid "blinking" of GPIO 16/17 at startup [#21282](https://github.com/arendst/Tasmota/issues/21282)
|
||||||
|
- Berry explicit error log when memory allocation fails [#20807](https://github.com/arendst/Tasmota/issues/20807)
|
||||||
|
- Berry `path.rename()` [#20840](https://github.com/arendst/Tasmota/issues/20840)
|
||||||
|
- Berry `string.startswith`, `string.endswith` and `%q` format [#20909](https://github.com/arendst/Tasmota/issues/20909)
|
||||||
|
- Berry `close()` to class `serial` [#21042](https://github.com/arendst/Tasmota/issues/21042)
|
||||||
|
- Berry `flash.current_ota` [#21097](https://github.com/arendst/Tasmota/issues/21097)
|
||||||
|
- Berry `webserver.content_close()` [#21276](https://github.com/arendst/Tasmota/issues/21276)
|
||||||
|
- Berry wave file recorder [#21315](https://github.com/arendst/Tasmota/issues/21315)
|
||||||
|
- Berry `after_teleperiod` event matching `FUNC_AFTER_TELEPERIOD` [#21351](https://github.com/arendst/Tasmota/issues/21351)
|
||||||
|
- LVGL and HASPmota typicons font [#20742](https://github.com/arendst/Tasmota/issues/20742)
|
||||||
|
- LVGL `lv.draw_label_dsc` and `lv_bar.get_indic_area` [#20936](https://github.com/arendst/Tasmota/issues/20936)
|
||||||
|
- HASPmota `p<x>b<y>.delete` to delete an object [#20735](https://github.com/arendst/Tasmota/issues/20735)
|
||||||
|
- HASPmota improve arc and img [#20894](https://github.com/arendst/Tasmota/issues/20894)
|
||||||
|
- HASPmota support for scale, percentages [#20974](https://github.com/arendst/Tasmota/issues/20974)
|
||||||
|
- HASPmota `dropdown_list` and fixes [#21208](https://github.com/arendst/Tasmota/issues/21208)
|
||||||
|
- HASPmota demo of Renaissance Watch for 480x480 displays [#21290](https://github.com/arendst/Tasmota/issues/21290)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
- Drop support for old (insecure) fingerprint format [#20842](https://github.com/arendst/Tasmota/issues/20842)
|
||||||
|
- Removed dedicated touch drivers in favour of Universal Touch driver [#21146](https://github.com/arendst/Tasmota/issues/21146)
|
||||||
|
- ESP32-C3 OTA binary name from `tasmota32c3cdc.bin` to `tasmota32c3.bin` with USB HWCDC and fallback to serial [#21212](https://github.com/arendst/Tasmota/issues/21212)
|
||||||
|
- ESP32-C6 OTA binary name from `tasmota32c6cdc.bin` to `tasmota32c6.bin` with USB HWCDC and fallback to serial [#21212](https://github.com/arendst/Tasmota/issues/21212)
|
||||||
|
- ESP32-S3 OTA binary name from `tasmota32s3cdc.bin` to `tasmota32s3.bin` with USB HWCDC and fallback to serial [#21212](https://github.com/arendst/Tasmota/issues/21212)
|
||||||
|
- Berry loading .be file does not generated .bec anymore [#21075](https://github.com/arendst/Tasmota/issues/21075)
|
||||||
|
- LVGL remove embedded typicons font [#20872](https://github.com/arendst/Tasmota/issues/20872)
|
||||||
|
- LVGL remove `textarea` and `spinbox` from binaries [#20916](https://github.com/arendst/Tasmota/issues/20916)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- ESP32 Platform from 2025.05.30 to 2025.07.31, Framework (Arduino Core) from v3.1.3.250504 to v3.1.3.250712 and IDF from v5.3.3.250501 to v5.3.3.250707 [#23685](https://github.com/arendst/Tasmota/issues/23685)
|
- ESP32 Framework (Arduino Core) from v2.0.14 to v3.0.0
|
||||||
- ESP8266 platform update from 2025.05.00 to 2025.07.00 [#23700](https://github.com/arendst/Tasmota/issues/23700)
|
- ESP32 platform update from 2024.01.12 to 2024.05.11 [#21381](https://github.com/arendst/Tasmota/issues/21381)
|
||||||
- OpenTherm library from v0.9.0 to v1.1.5 [#23704](https://github.com/arendst/Tasmota/issues/23704)
|
- ESP32 LVGL library from v9.0.0 to v9.1.0 [#21008](https://github.com/arendst/Tasmota/issues/21008)
|
||||||
- Library names [#23560](https://github.com/arendst/Tasmota/issues/23560)
|
- GPIOViewer from v1.5.0 to v1.5.2
|
||||||
- CSS uses named colors variables [#23597](https://github.com/arendst/Tasmota/issues/23597)
|
- Seriallog set to `SERIAL_LOG_LEVEL` at boot [#21363](https://github.com/arendst/Tasmota/issues/21363)
|
||||||
- VEML6070 and AHT2x device detection [#23581](https://github.com/arendst/Tasmota/issues/23581)
|
- TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 [#21352](https://github.com/arendst/Tasmota/issues/21352)
|
||||||
- Domoticz supports persistent settings for all relays, keys and switches when filesystem `#define USE_UFILESYS` is enabled
|
- Command ``Pixels`` initiates a restart before activation due to changed NeoPixelBus library [#21406](https://github.com/arendst/Tasmota/issues/21406)
|
||||||
- ESP32 LoRaWan decoding won't duplicate non-decoded message if `SO147 0`
|
- Command ``EthType`` option selection [#21317](https://github.com/arendst/Tasmota/issues/21317)
|
||||||
- BLE updates for esp-nimble-cpp v2.x [#23553](https://github.com/arendst/Tasmota/issues/23553)
|
- Refactor Platformio script `post_esp32.py` [#20966](https://github.com/arendst/Tasmota/issues/20966)
|
||||||
|
- SGP4x Domoticz air quality value from raw to computed [#18880](https://github.com/arendst/Tasmota/issues/18880)
|
||||||
|
- NeoPool webUI pH alarms (4 & 5) completed [#20743](https://github.com/arendst/Tasmota/issues/20743)
|
||||||
|
- Prevent shutter MQTT broadcast with activated ShutterLock [#20827](https://github.com/arendst/Tasmota/issues/20827)
|
||||||
|
- Some `display.ini` to utouch [#21029](https://github.com/arendst/Tasmota/issues/21029)
|
||||||
|
- KNX format of energy to match specifications [#21074](https://github.com/arendst/Tasmota/issues/21074)
|
||||||
|
- Internal macro `APP_SLEEP` to `TASMOTA_SLEEP` to specify default sleep in ms [#21324](https://github.com/arendst/Tasmota/issues/21324)
|
||||||
|
- uDisplay fast drawing on RGB displays [#21257](https://github.com/arendst/Tasmota/issues/21257)
|
||||||
|
- HDMI CEC synchronously sends messages [#21270](https://github.com/arendst/Tasmota/issues/21270)
|
||||||
|
- Refactor I2S [#21291](https://github.com/arendst/Tasmota/issues/21291)
|
||||||
|
- Zigbee startup event triggered after plugins are loaded [#21320](https://github.com/arendst/Tasmota/issues/21320)
|
||||||
|
- Refactor Tensorflow [#21327](https://github.com/arendst/Tasmota/issues/21327)
|
||||||
|
- ESP32 refactored Wifi for ESP32 Core3 release [#21106](https://github.com/arendst/Tasmota/issues/21106)
|
||||||
|
- ESP32 WiFi phy modes 11n and 11ax represented as HT20, HT40 and HE20 [#19350](https://github.com/arendst/Tasmota/issues/19350)
|
||||||
|
- berry.exe (pre-compiled for Windows) updated to latest Berry patches [#21024](https://github.com/arendst/Tasmota/issues/21024)
|
||||||
|
- Berry class `int64` made immutable [#20727](https://github.com/arendst/Tasmota/issues/20727)
|
||||||
|
- Berry `Leds` uses native WS2812 driver by default [#21406](https://github.com/arendst/Tasmota/issues/21406)
|
||||||
|
- Matter reduce memory usage when reading with wildcards [#20809](https://github.com/arendst/Tasmota/issues/20809)
|
||||||
|
- LVGL make lv_touch_3_buttons more responsive [#20728](https://github.com/arendst/Tasmota/issues/20728)
|
||||||
|
- LVGL optimize fonts and add icons [#20880](https://github.com/arendst/Tasmota/issues/20880)
|
||||||
|
- LVGL improved readability of montserrat-10 [#20900](https://github.com/arendst/Tasmota/issues/20900)
|
||||||
|
- HASPmota fix and improve demo with pixel-perfect fonts [#20734](https://github.com/arendst/Tasmota/issues/20734)
|
||||||
|
- HASPmota more attributes [#20744](https://github.com/arendst/Tasmota/issues/20744)
|
||||||
|
- HASPmota support for spangroup (styled text) [#20852](https://github.com/arendst/Tasmota/issues/20852)
|
||||||
|
- HASPmota support for led [#20857](https://github.com/arendst/Tasmota/issues/20857)
|
||||||
|
- HASPmota moved to a distinct library `lv_haspmota` [#20929](https://github.com/arendst/Tasmota/issues/20929)
|
||||||
|
- HASPmota solidify server-side [#20938](https://github.com/arendst/Tasmota/issues/20938)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- AHT30 sensor start with null values after deep sleep [#23624](https://github.com/arendst/Tasmota/issues/23624)
|
- Filesystem save of JSON settings data
|
||||||
- Berry vulnerability in JSON parsing for unicode [#23603](https://github.com/arendst/Tasmota/issues/23603)
|
- Fade out on CCT bulb with `SO92 1` [#21159](https://github.com/arendst/Tasmota/issues/21159)
|
||||||
- Berry security issues in `int64` and improve documentation [#23605](https://github.com/arendst/Tasmota/issues/23605)
|
- Shutter inverted using internal commands [#20752](https://github.com/arendst/Tasmota/issues/20752)
|
||||||
- Berry security issues in `berry_mapping` and improve documentation [#23606](https://github.com/arendst/Tasmota/issues/23606)
|
- TuyaV2 suppressed dimmer updates from MQTT [#20950](https://github.com/arendst/Tasmota/issues/20950)
|
||||||
- Berry Hue regression from #23429 [#23623](https://github.com/arendst/Tasmota/issues/23623)
|
- Scripter google char memory leak [#20995](https://github.com/arendst/Tasmota/issues/20995)
|
||||||
- LVGL restore `lv_chart.set_range` removed in LVGL 9.3.0 in favor of `lv_chart.set_axis_range` [#23567](https://github.com/arendst/Tasmota/issues/23567)
|
- Too restrictive checksum checks in Lib_teleinfo [#21033](https://github.com/arendst/Tasmota/issues/21033)
|
||||||
|
- Color swap option for rgb displaytext [#21049](https://github.com/arendst/Tasmota/issues/21049)
|
||||||
|
- NeoPool hydrolysis unit for Hidrolife, Bionet and Generic device [#21098](https://github.com/arendst/Tasmota/issues/21098)
|
||||||
|
- Neopool prevent possible multiple bus requests [#21267](https://github.com/arendst/Tasmota/issues/21267)
|
||||||
|
- Async HMDI CEC [#21287](https://github.com/arendst/Tasmota/issues/21287)
|
||||||
|
- ESP8266 physical button/switch control when no rules activated [#21187](https://github.com/arendst/Tasmota/issues/21187)
|
||||||
|
- jpeg compile core3 [#21387](https://github.com/arendst/Tasmota/issues/21387)
|
||||||
|
- ESP32 PWM activity on unconfigured PWM GPIOs [#20732](https://github.com/arendst/Tasmota/issues/20732)
|
||||||
|
- Avoid unwanted OTA upgrade when safeboot starts for the first time [#21360](https://github.com/arendst/Tasmota/issues/21360)
|
||||||
|
- BTHome, prep BLE5 [#20989](https://github.com/arendst/Tasmota/issues/20989)
|
||||||
|
- Conflicting log_level definitions in NimBLE [#21337](https://github.com/arendst/Tasmota/issues/21337)
|
||||||
|
- Berry Memory leak in `import re` [#20823](https://github.com/arendst/Tasmota/issues/20823)
|
||||||
|
- Berry bug when parsing ternary operator [#20839](https://github.com/arendst/Tasmota/issues/20839)
|
||||||
|
- Berry walrus with member or index [#20939](https://github.com/arendst/Tasmota/issues/20939)
|
||||||
|
- Berry walrus bug when assigning to self [#21015](https://github.com/arendst/Tasmota/issues/21015)
|
||||||
|
- Berry `web_add_handler` called before `Webserver` is initialized [#21272](https://github.com/arendst/Tasmota/issues/21272)
|
||||||
|
- Berry `math.inf`, `math.isinf()` and fixed json ouput for `inf` and `nan` [#21304](https://github.com/arendst/Tasmota/issues/21304)
|
||||||
|
- Berry `gpio.dac_voltage()` [#21403](https://github.com/arendst/Tasmota/issues/21403)
|
||||||
|
- Matter broken NOCStruct types preventing pairing with HA [#21365](https://github.com/arendst/Tasmota/issues/21365)
|
||||||
|
- LVGL restore `lv_palette` functions [#21232](https://github.com/arendst/Tasmota/issues/21232)
|
||||||
|
- LVGL fix memory allocation of flush buffers [#21256](https://github.com/arendst/Tasmota/issues/21256)
|
||||||
|
- HASPmota PSRAM memory leak [#20818](https://github.com/arendst/Tasmota/issues/20818)
|
||||||
|
- HASPmota widgets line, btnmatrix, qrcode, bar, checkbox [#20881](https://github.com/arendst/Tasmota/issues/20881)
|
||||||
|
- HASPmota demo and robotocondensed fonts [#21014](https://github.com/arendst/Tasmota/issues/21014)
|
||||||
|
- HASPmota dropdown class "options" attribute [#21203](https://github.com/arendst/Tasmota/issues/21203)
|
||||||
|
- HASPmota `align` attribute and expand PNG cache [#21228](https://github.com/arendst/Tasmota/issues/21228)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- Support for ESP32 Arduino Core 2 [#21180](https://github.com/arendst/Tasmota/issues/21180)
|
||||||
|
- Unused `#define MQTT_DATA_STRING` support
|
||||||
|
- ILI9341 driver replaced with uDisplay [#21169](https://github.com/arendst/Tasmota/issues/21169)
|
||||||
|
- SSD1306 driver replaced with uDisplay [#21176](https://github.com/arendst/Tasmota/issues/21176)
|
||||||
|
- SSD1331 driver replaced with uDisplay [#21177](https://github.com/arendst/Tasmota/issues/21177)
|
||||||
|
- SSH1106 driver replaced with uDisplay [#21183](https://github.com/arendst/Tasmota/issues/21183)
|
||||||
|
- SSD1351 driver replaced with uDisplay [#21184](https://github.com/arendst/Tasmota/issues/21184)
|
||||||
|
- ST7789 driver replaced with uDisplay [#21184](https://github.com/arendst/Tasmota/issues/21184)
|
||||||
|
- ESP32 IDF 4.4 based I2S code [#21188](https://github.com/arendst/Tasmota/issues/21188)
|
||||||
|
- Crash recorder from safeboot [#21332](https://github.com/arendst/Tasmota/issues/21332)
|
||||||
|
- Berry `print "a"` syntax no longer supported [#21048](https://github.com/arendst/Tasmota/issues/21048)
|
||||||
|
- LVGL disabled vector graphics [#21242](https://github.com/arendst/Tasmota/issues/21242)
|
||||||
|
77
TEMPLATES.md
77
TEMPLATES.md
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
# Templates
|
# Templates
|
||||||
|
|
||||||
Find below the available templates as of June 2025. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)
|
Find below the available templates as of May 2024. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)
|
||||||
|
|
||||||
## Adapter Board
|
## Adapter Board
|
||||||
```
|
```
|
||||||
@ -97,7 +97,7 @@ Iotton 9W 700lm {"NAME":"Iotton Light","GPIO":[0,0,0,0,416,417,0,0,
|
|||||||
iQtech 10W 900lm {"NAME":"iQ-Tech CCT 10W 900LM","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
iQtech 10W 900lm {"NAME":"iQ-Tech CCT 10W 900LM","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
iView 10W 1050lm {"NAME":"iView ISB1000-D","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
iView 10W 1050lm {"NAME":"iView ISB1000-D","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan 10W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48}
|
Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan 10W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48}
|
||||||
Kogan 4.5W 330lm 110° {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Kogan 4.5W 330lm 110 {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Kogan 5W {"NAME":"Kogan Co/Wa","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
Kogan 5W {"NAME":"Kogan Co/Wa","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Kruidvat A60 9W 806lm {"NAME":"Kruidvat E27 806 Lumens","GPIO":[0,0,0,0,416,449,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":48}
|
Kruidvat A60 9W 806lm {"NAME":"Kruidvat E27 806 Lumens","GPIO":[0,0,0,0,416,449,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":48}
|
||||||
Laser 10W 1000lm {"NAME":"Laser 10W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48}
|
Laser 10W 1000lm {"NAME":"Laser 10W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48}
|
||||||
@ -131,7 +131,7 @@ Nedis C10 350lm {"NAME":"WIFILW10WTE14","GPIO":[0,0,0,0,0,416,0,0,0
|
|||||||
Nedis G125 5.5W 350lm Twisted Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
|
Nedis G125 5.5W 350lm Twisted Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis PAR16 4,5W 380lm {"NAME":"Nedis WIFILW10WTGU10","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Nedis PAR16 4,5W 380lm {"NAME":"Nedis WIFILW10WTGU10","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis PAR16 4.5W 330lm 110° {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Nedis PAR16 4.5W 330lm 110 {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nous P2 {"NAME":"NOUS-P2","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":37}
|
Nous P2 {"NAME":"NOUS-P2","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":37}
|
||||||
Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,417,0,0,416,0,0],"FLAG":0,"BASE":48}
|
Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,417,0,0,416,0,0],"FLAG":0,"BASE":48}
|
||||||
Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,417,0,0,416,0,0],"FLAG":0,"BASE":48}
|
Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,417,0,0,416,0,0],"FLAG":0,"BASE":48}
|
||||||
@ -150,7 +150,7 @@ Sulion Morgan C37 5W 470lm {"NAME":"Sulion Bombilla C37","GPIO":[0,0,0,0,0,0,0
|
|||||||
Swisstone 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18}
|
Swisstone 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Swisstone SH 310 {"NAME":"Swisstone SH 310","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
Swisstone SH 310 {"NAME":"Swisstone SH 310","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Treatlife A19 9W 800lm {"NAME":"Treatlife SL20","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
Treatlife A19 9W 800lm {"NAME":"Treatlife SL20","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
V-Tac PAR16 4.5W 300lm 110° {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
|
V-Tac PAR16 4.5W 300lm 110 {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Wipro Garnet NS9100 810lm {"NAME":"Wipro 9W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48}
|
Wipro Garnet NS9100 810lm {"NAME":"Wipro 9W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48}
|
||||||
Wyze A19 800lm {"NAME":"Wyze Bulb","GPIO":[5728,0,0,0,0,0,0,0,0,416,417,0,0,0],"FLAG":0,"BASE":48}
|
Wyze A19 800lm {"NAME":"Wyze Bulb","GPIO":[5728,0,0,0,0,0,0,0,0,416,417,0,0,0],"FLAG":0,"BASE":48}
|
||||||
@ -186,6 +186,7 @@ LE lampUX 15W RGBCCT {"NAME":"LE lampUX 15W","GPIO":[0,0,0,0,416,419,0,0
|
|||||||
LightZone MeLiTec {"NAME":"LightZone MeLiTec D114 Light ","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
LightZone MeLiTec {"NAME":"LightZone MeLiTec D114 Light ","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
Lohas ZN026CL10 RGBCCT {"NAME":"Lohas LED Lamp","GPIO":[0,0,0,0,417,416,0,0,419,418,420,0,0,0],"FLAG":0,"BASE":18}
|
Lohas ZN026CL10 RGBCCT {"NAME":"Lohas LED Lamp","GPIO":[0,0,0,0,417,416,0,0,419,418,420,0,0,0],"FLAG":0,"BASE":18}
|
||||||
LOLAsmart Uranus White 70 cm {"NAME":"lola smart","GPIO":[0,0,0,1088,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
LOLAsmart Uranus White 70 cm {"NAME":"lola smart","GPIO":[0,0,0,1088,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
|
LSC 20W 1400lm White Ambiance {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Luminea 24W CCT {"NAME":"Luminea NX6205-944","GPIO":[0,0,0,0,0,0,0,0,449,0,416,0,0,0],"FLAG":0,"BASE":48}
|
Luminea 24W CCT {"NAME":"Luminea NX6205-944","GPIO":[0,0,0,0,0,0,0,0,449,0,416,0,0,0],"FLAG":0,"BASE":48}
|
||||||
LVL 300mm Round {"NAME":"LVL 300m Round 24W Ceiling LED","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":48}
|
LVL 300mm Round {"NAME":"LVL 300m Round 24W Ceiling LED","GPIO":[0,0,0,0,0,416,0,0,0,449,0,0,0,0],"FLAG":0,"BASE":48}
|
||||||
Nedis CCT 800lm {"NAME":"NEDIS WIFILAW10WT","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
|
Nedis CCT 800lm {"NAME":"NEDIS WIFILAW10WT","GPIO":[0,0,0,0,0,0,0,0,417,0,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -265,9 +266,6 @@ EARU DIN Circuit Breaker 2P 63/80A eWeLink White {"NAME":"RDCBC-2P","GPIO":[32,
|
|||||||
Hoch Circuit Breaker 1P {"NAME":"HOCH ZJSB9","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
|
Hoch Circuit Breaker 1P {"NAME":"HOCH ZJSB9","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Ketotek Single Phase Energy Monitor {"NAME":"Ketotek KTEM06","GPIO":[0,2272,0,2304,0,0,0,0,0,0,320,0,32,0],"FLAG":0,"BASE":54}
|
Ketotek Single Phase Energy Monitor {"NAME":"Ketotek KTEM06","GPIO":[0,2272,0,2304,0,0,0,0,0,0,320,0,32,0],"FLAG":0,"BASE":54}
|
||||||
Martin Jerry 30A Circuit Breaker {"NAME":"30A Breaker","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18}
|
Martin Jerry 30A Circuit Breaker {"NAME":"30A Breaker","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18}
|
||||||
Nous DIN Smart Switch 16A {"NAME":"Nous D1T","GPIO":[32,1,9312,1,1,320,1,1,9313,8160,3200,544,1,1,1,1,0,1,1,1,0,0,1,1,0,0,0,0,1,1,4736,1,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
Nous DIN Smart Switch 20A {"NAME":"Nous D1T","GPIO":[32,1,9312,1,1,320,1,1,9313,8160,3200,544,1,1,1,1,0,1,1,1,0,0,1,1,0,0,0,0,1,1,4736,1,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
Nous DIN Smart Switch 25A {"NAME":"Nous D1T","GPIO":[32,1,9312,1,1,320,1,1,9313,8160,3200,544,1,1,1,1,0,1,1,1,0,0,1,1,0,0,0,0,1,1,4736,1,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[32,0,1,0,0,224,0,0,0,0,0,0,320,0],"FLAG":0,"BASE":18}
|
OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[32,0,1,0,0,224,0,0,0,0,0,0,320,0],"FLAG":0,"BASE":18}
|
||||||
RocketController ASTRA Controller {"NAME":"ASTRA R4A4","GPIO":[1,1,1,1,576,1,1,1,480,1,1,1,3232,3200,1,1,0,640,608,1,0,224,225,1152,0,0,0,0,227,226,160,161,162,0,0,163],"FLAG":0,"BASE":1}
|
RocketController ASTRA Controller {"NAME":"ASTRA R4A4","GPIO":[1,1,1,1,576,1,1,1,480,1,1,1,3232,3200,1,1,0,640,608,1,0,224,225,1152,0,0,0,0,227,226,160,161,162,0,0,163],"FLAG":0,"BASE":1}
|
||||||
Shelly Pro 1 {"NAME":"Shelly Pro 1","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
|
Shelly Pro 1 {"NAME":"Shelly Pro 1","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
|
||||||
@ -313,7 +311,7 @@ LilyGo 4G GPS {"NAME":"LiLyGo A7608EH","GPIO":[1,1,672,1,226,225,
|
|||||||
LilyGO RGB LED Ring Encoder {"NAME":"T-Encoder","GPIO":[0,0,1,0,1,0,0,0,1,1,1,1,0,0,0,480,6212,0,0,0,0,449,450,448,0,0,0,0,0,0,0,0,3296,3264,32,0],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"}
|
LilyGO RGB LED Ring Encoder {"NAME":"T-Encoder","GPIO":[0,0,1,0,1,0,0,0,1,1,1,1,0,0,0,480,6212,0,0,0,0,449,450,448,0,0,0,0,0,0,0,0,3296,3264,32,0],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"}
|
||||||
LilyGO T7 Mini32 V1.5 {"NAME":"LilyGO T7 V1.5","GPIO":[1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,544,0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,4704,1,0,0,1],"FLAG":0,"BASE":1}
|
LilyGO T7 Mini32 V1.5 {"NAME":"LilyGO T7 V1.5","GPIO":[1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,544,0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,4704,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
LilyGO TTGO ESP32 Ethernet {"NAME":"T-Internet-POE v1.2","GPIO":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"EthType 0|EthClockMode 1|EthAddress 0"}
|
LilyGO TTGO ESP32 Ethernet {"NAME":"T-Internet-POE v1.2","GPIO":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"EthType 0|EthClockMode 1|EthAddress 0"}
|
||||||
M5Stack Atom Lite ESP32 {"NAME":"M5Stack Atom Lite","GPIO":[0,0,0,0,0,0,0,0,1056,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1376,0,0,0,0,1,1,1,0,0,0,0,32],"FLAG":0,"BASE":1}
|
M5Stack Atom Lite ESP32 {"NAME":"M5Stack Atom Lite","GPIO":[1,1,1,1,1,1,1,1,1056,1,1,1,1,1,1,1,0,1,1,1,0,1,640,1376,0,0,0,0,608,1,1,1,1,0,0,32],"FLAG":0,"BASE":1}
|
||||||
M5Stack AtomU USB-A ESP32 "Not available"
|
M5Stack AtomU USB-A ESP32 "Not available"
|
||||||
Mostly Robots Wemos D1 4 Channel MOSFET Shield {"NAME":"MOSFET","GPIO":[1,1,288,1,1,1,1,1,226,225,227,224,1,1],"FLAG":0,"BASE":18}
|
Mostly Robots Wemos D1 4 Channel MOSFET Shield {"NAME":"MOSFET","GPIO":[1,1,288,1,1,1,1,1,226,225,227,224,1,1],"FLAG":0,"BASE":18}
|
||||||
Olimex ESP32-POE Ethernet {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
Olimex ESP32-POE Ethernet {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
@ -397,12 +395,13 @@ Nedis A60 Warm White 9W 800lm {"NAME":"WIFILW11WTE27","GPIO":[0,0,0,0,0,416,0,0
|
|||||||
Nedis G125 Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
|
Nedis G125 Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis PAR16 330lm {"NAME":"Nedis WIFILW31","GPIO":[0,0,0,0,0,416,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Nedis PAR16 330lm {"NAME":"Nedis WIFILW31","GPIO":[0,0,0,0,0,416,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis ST64 5W 500lm Filament {"NAME":"WIFILF10GDST64","GPIO":[0,0,0,0,0,0,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
|
Nedis ST64 5W 500lm Filament {"NAME":"WIFILF10GDST64","GPIO":[0,0,0,0,0,0,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Positivo Smart Lâmpada Retrô {"NAME":"POSITIVO SMART LAMPADA RETRO","GPIO":[0,0,0,0,0,0,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
|
Positivo Smart Lampada Retro {"NAME":"POSITIVO SMART LAMPADA RETRO","GPIO":[0,0,0,0,0,0,0,0,0,0,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Sealight Vintage Edison A19 {"NAME":"SealightEdison","GPIO":[0,0,0,0,0,416,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Sealight Vintage Edison A19 {"NAME":"SealightEdison","GPIO":[0,0,0,0,0,416,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Shelly Vintage 4W 260lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Shelly Vintage 4W 260lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
SmartDGM 9W 806lm {"NAME":"L-WB9W1","GPIO":[0,0,0,0,0,416,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18}
|
SmartDGM 9W 806lm {"NAME":"L-WB9W1","GPIO":[0,0,0,0,0,416,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
|
Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Smitch 10W 6500K {"NAME":"Smitch 10W 6500K Dimmable Bulb (SB0110 - E27)","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":1}
|
Smitch 10W 6500K {"NAME":"Smitch 10W 6500K Dimmable Bulb (SB0110 - E27)","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
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 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}
|
||||||
@ -463,7 +462,7 @@ QS-WiFi-D01-TRIAC 150W {"NAME":"QS-WiFi-D01-TRIAC","GPIO":[0,3200,0,3232,0
|
|||||||
RJWF-02A {"NAME":"RJWF-02A","GPIO":[32,2272,0,2304,0,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":54}
|
RJWF-02A {"NAME":"RJWF-02A","GPIO":[32,2272,0,2304,0,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":54}
|
||||||
Shelly Dimmer {"NAME":"Shelly Dimmer 1","GPIO":[0,3200,0,3232,5568,5600,0,0,192,0,193,288,0,4736],"FLAG":0,"BASE":18}
|
Shelly Dimmer {"NAME":"Shelly Dimmer 1","GPIO":[0,3200,0,3232,5568,5600,0,0,192,0,193,288,0,4736],"FLAG":0,"BASE":18}
|
||||||
Shelly Dimmer 2 {"NAME":"Shelly Dimmer 2","GPIO":[0,3200,0,3232,5568,5600,0,0,193,0,192,0,320,4736],"FLAG":0,"BASE":18}
|
Shelly Dimmer 2 {"NAME":"Shelly Dimmer 2","GPIO":[0,3200,0,3232,5568,5600,0,0,193,0,192,0,320,4736],"FLAG":0,"BASE":18}
|
||||||
Shelly Plus 0-10V Dimmer {"NAME":"Shelly Plus 0-10V Dimmer","GPIO":[288,0,0,0,192,0,0,0,0,0,0,0,0,0,193,1,0,0,0,0,0,32,448,0,0,0,0,0,4736,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
Shelly Plus 0-10V Dimmer {"NAME":"Shelly Plus 0-10V Dimmer","GPIO":[288,0,0,0,192,0,0,0,0,0,0,0,0,0,193,1,0,0,0,0,0,32,416,0,0,0,0,0,4736,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Sonoff D1 {"NAME":"Sonoff D1","GPIO":[1,3200,0,3232,0,0,0,0,0,320,0,0,0,0],"FLAG":0,"BASE":74}
|
Sonoff D1 {"NAME":"Sonoff D1","GPIO":[1,3200,0,3232,0,0,0,0,0,320,0,0,0,0],"FLAG":0,"BASE":74}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -559,7 +558,7 @@ Goldair SleepSmart GCPF315 {"NAME":"Goldair Fan","GPIO":[0,0,0,0,0,0,0,0,0,230
|
|||||||
Holmes 36" Oscillating Tower {"NAME":"Generic","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":54,"CMND":"TuyaMcu 11,1 | TuyaMcu 12,5 | WebButton1 Power | WebButton2 Oscillation "}
|
Holmes 36" Oscillating Tower {"NAME":"Generic","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":54,"CMND":"TuyaMcu 11,1 | TuyaMcu 12,5 | WebButton1 Power | WebButton2 Oscillation "}
|
||||||
Lucci Connect Remote Control {"NAME":"Lucci Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
|
Lucci Connect Remote Control {"NAME":"Lucci Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
|
||||||
QuietCool Gable Mount Attic {"NAME":"QuietCool-AFG-SMT-PRO-2.0","GPIO":[0,0,0,0,0,224,0,0,0,0,0,0,0,0,640,608,0,0,0,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Interlock 1|WebButton1 Low|WebButton2 High|SO8 1"}
|
QuietCool Gable Mount Attic {"NAME":"QuietCool-AFG-SMT-PRO-2.0","GPIO":[0,0,0,0,0,224,0,0,0,0,0,0,0,0,640,608,0,0,0,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Interlock 1|WebButton1 Low|WebButton2 High|SO8 1"}
|
||||||
Sichler Haushaltsgeräte Column {"NAME":"Sichler Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
Sichler Haushaltsgeraete Column {"NAME":"Sichler Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
Technical Pro {"NAME":"FXA16 Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 12,8"}
|
Technical Pro {"NAME":"FXA16 Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 12,8"}
|
||||||
Zemismart Bladeless {"NAME":"Bladeless Fan","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54}
|
Zemismart Bladeless {"NAME":"Bladeless Fan","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54}
|
||||||
```
|
```
|
||||||
@ -602,7 +601,6 @@ EBERG ROT 720 Infrared {"NAME":"Tuya MCU","GPIO":[0,2272,0,2304,0,0,0,0,0,
|
|||||||
Klarstein Bornholm Smart 2000W {"NAME":"Klarstein Bornholm","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
Klarstein Bornholm Smart 2000W {"NAME":"Klarstein Bornholm","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
Kogan 1500W Panel {"NAME":"Kogan Panel Heater","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
|
Kogan 1500W Panel {"NAME":"Kogan Panel Heater","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54}
|
||||||
LSC Smart Connect 500W IR Panel {"NAME":"LSC Connect Smart IR Panel Heater","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
LSC Smart Connect 500W IR Panel {"NAME":"LSC Connect Smart IR Panel Heater","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
Mursche 450W Infrared Heater {"NAME":"Mursche Infrared Heater","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
|
||||||
SmartMi Electric Air {"NAME":"ZNNFJ07ZM","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,3200,3232,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}
|
SmartMi Electric Air {"NAME":"ZNNFJ07ZM","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,3200,3232,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}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -658,10 +656,6 @@ Uniplay Universal Remote {"NAME":"Uniplay IR","GPIO":[1,3200,1,3232,576,1088
|
|||||||
YTF 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}
|
YTF 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}
|
||||||
```
|
```
|
||||||
|
|
||||||
## IR Remote
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
## Illuminance Sensor
|
## Illuminance Sensor
|
||||||
```
|
```
|
||||||
Tuya {"NAME":"Lightsensor","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
Tuya {"NAME":"Lightsensor","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
@ -879,7 +873,7 @@ PCI-e Desktop PC Remote Control {"NAME":"PC-Switch-01","GPIO":[32,0,0,0,0,0,0,0
|
|||||||
Petoneer Smart Dot Cat Toy {"NAME":"Petoneer Smart Dot","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
Petoneer Smart Dot Cat Toy {"NAME":"Petoneer Smart Dot","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
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}
|
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"}
|
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,160,224,0,161,162,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SO114 1 | Pulsetime 10 | SwitchMode1 2 | SwitchMode2 2 | SwitchMode3 2"}
|
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":[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"}
|
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"}
|
||||||
Sinilink XY-Clock Clock Alarm Module {"NAME":"XY-Clock","GPIO":[288,0,289,0,0,416,32,33,608,640,0,0,34,0],"FLAG":0,"BASE":18}
|
Sinilink XY-Clock Clock Alarm Module {"NAME":"XY-Clock","GPIO":[288,0,289,0,0,416,32,33,608,640,0,0,34,0],"FLAG":0,"BASE":18}
|
||||||
Sunbeam LoftTec Electric Blanket {"NAME":"Sunbeam Heated Blanket","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
Sunbeam LoftTec Electric Blanket {"NAME":"Sunbeam Heated Blanket","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
@ -929,7 +923,7 @@ Zemismart Updated RF Remote Roller Shade {"NAME":"Zemismart M515EGB","GPIO":[1,
|
|||||||
## Other
|
## Other
|
||||||
```
|
```
|
||||||
Kogan SmarterHome 1.9L Pet Water Fountain {"NAME":"WaterFountain","GPIO":[257,0,259,0,576,32,0,0,224,161,0,480,226,4704],"FLAG":0,"BASE":18}
|
Kogan SmarterHome 1.9L Pet Water Fountain {"NAME":"WaterFountain","GPIO":[257,0,259,0,576,32,0,0,224,161,0,480,226,4704],"FLAG":0,"BASE":18}
|
||||||
Tetra® Connect Automatic Feeder {"NAME":"Tetra Connect","GPIO":[0,0,0,0,224,288,0,0,98,96,97,0,289,0],"FLAG":0,"BASE":18}
|
Tetra Connect Automatic Feeder {"NAME":"Tetra Connect","GPIO":[0,0,0,0,224,288,0,0,98,96,97,0,289,0],"FLAG":0,"BASE":18}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Outdoor Plug
|
## Outdoor Plug
|
||||||
@ -991,8 +985,6 @@ Merkury {"NAME":"Merkury Switch","GPIO":[0,0,0,0,32,0,0,0,0
|
|||||||
Meross MSS620 16A IP44 {"NAME":"MSS620","GPIO":[0,320,0,320,225,0,0,0,224,576,32,0,0,0],"FLAG":0,"BASE":18}
|
Meross MSS620 16A IP44 {"NAME":"MSS620","GPIO":[0,320,0,320,225,0,0,0,224,576,32,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Minoston MP22W {"NAME":"Minoston MP22W","GPIO":[0,0,0,0,320,0,0,0,224,64,0,0,0,0],"FLAG":0,"BASE":18}
|
Minoston MP22W {"NAME":"Minoston MP22W","GPIO":[0,0,0,0,320,0,0,0,224,64,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis PO120 IP44 {"NAME":"WIFIPO120FWT","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
|
Nedis PO120 IP44 {"NAME":"WIFIPO120FWT","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
|
||||||
Nous A6T Smart Socket {"NAME":"NOUS A5T","GPIO":[0,3072,544,3104,0,259,0,0,225,226,224,0,35,4704],"FLAG":1,"BASE":18}
|
|
||||||
Nous Dual Smart Socket {"NAME":"NOUS A4T","GPIO":[0,2624,0,576,2656,2720,0,0,224,225,32,0,0,0],"FLAG":0,"BASE":18}
|
|
||||||
Obi Stecker IP44 {"NAME":"OBI-Outdoor-Socket2","GPIO":[0,0,0,0,224,32,0,0,576,288,1,1,1,1],"FLAG":0,"BASE":18}
|
Obi Stecker IP44 {"NAME":"OBI-Outdoor-Socket2","GPIO":[0,0,0,0,224,32,0,0,576,288,1,1,1,1],"FLAG":0,"BASE":18}
|
||||||
Oittm IP44 15A {"NAME":"Oittm Outdoor","GPIO":[576,0,320,0,2688,2656,0,0,224,2592,0,0,0,0],"FLAG":0,"BASE":57}
|
Oittm IP44 15A {"NAME":"Oittm Outdoor","GPIO":[576,0,320,0,2688,2656,0,0,224,2592,0,0,0,0],"FLAG":0,"BASE":57}
|
||||||
Oittm Outdoor {"NAME":"Oittm Outdoor","GPIO":[32,0,0,0,0,0,0,0,0,0,320,224,1,0],"FLAG":0,"BASE":18}
|
Oittm Outdoor {"NAME":"Oittm Outdoor","GPIO":[32,0,0,0,0,0,0,0,0,0,320,224,1,0],"FLAG":0,"BASE":18}
|
||||||
@ -1077,7 +1069,6 @@ Arlec Twin Socket with Energy Meter {"NAME":"Arlec PC287HA","GPIO":[0,32,0,320,
|
|||||||
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 {"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 PG05-AU16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Athom 16A AU {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A AU {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A AU V3 {"NAME":"Athom Plug V3","GPIO":[0,0,0,32,0,224,576,0,0,0,0,0,0,0,0,0,0,0,0,0,3104,0],"FLAG":0,"BASE":1}
|
|
||||||
Athom 16A BR V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A BR V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A Brazil {"NAME":"Athom PG05-BR16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1}
|
Athom 16A Brazil {"NAME":"Athom PG05-BR16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Athom 16A EU V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A EU V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -1087,10 +1078,8 @@ Athom 16A Italy {"NAME":"Athom PG05-IT16A","GPIO":[0,0,0,32,2720,26
|
|||||||
Athom 16A Switzerland v2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A Switzerland v2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A UK {"NAME":"Athom PG04-UK16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A UK {"NAME":"Athom PG04-UK16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A UK V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A UK V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A UK V3 {"NAME":"Athom Plug V3","GPIO":[0,0,0,32,0,224,576,0,0,0,0,0,0,0,0,0,0,0,0,0,3104,0],"FLAG":0,"BASE":1}
|
|
||||||
Athom 16A US {"NAME":"Athom PG03-US16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A US {"NAME":"Athom PG03-US16A","GPIO":[0,0,0,32,2720,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A US V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
Athom 16A US V2 {"NAME":"Athom Plug V2","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 16A US V3 {"NAME":"Athom Plug V3","GPIO":[0,0,0,32,0,224,576,0,0,0,0,0,0,0,0,0,0,0,0,0,3104,0],"FLAG":0,"BASE":1}
|
|
||||||
Atlantis {"NAME":"Atlantis Smart Plug","GPIO":[32,0,0,0,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18}
|
Atlantis {"NAME":"Atlantis Smart Plug","GPIO":[32,0,0,0,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Atomi AT1217 {"NAME":"AT1217","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
|
Atomi AT1217 {"NAME":"AT1217","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Aubess 16A {"NAME":"Aubess 16A Power Monitoring Plug","GPIO":[0,32,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
|
Aubess 16A {"NAME":"Aubess 16A Power Monitoring Plug","GPIO":[0,32,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -1232,8 +1221,8 @@ Epicka {"NAME":"Epicka","GPIO":[1,1,1,1,321,320,0,0,224,32
|
|||||||
Eques Elf Smart Plug {"NAME":"EQP01WTGY","GPIO":[0,0,0,320,0,0,0,0,96,0,0,224,0,0],"FLAG":0,"BASE":18}
|
Eques Elf Smart Plug {"NAME":"EQP01WTGY","GPIO":[0,0,0,320,0,0,0,0,96,0,0,224,0,0],"FLAG":0,"BASE":18}
|
||||||
Esicoo JSM-WF02 {"NAME":"Esicoo Plug","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
|
Esicoo JSM-WF02 {"NAME":"Esicoo Plug","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Estink C178 {"NAME":"Estink C178","GPIO":[0,0,0,0,288,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
|
Estink C178 {"NAME":"Estink C178","GPIO":[0,0,0,0,288,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
|
Etekcity 15A {"NAME":"ESW15-US","GPIO":[0,0,0,0,0,224,0,0,2656,2688,32,2592,288,0],"FLAG":0,"BASE":18}
|
||||||
Etekcity 8A {"NAME":"ESW01-USA","GPIO":[0,0,0,0,224,544,0,0,2656,2688,32,2592,288,0],"FLAG":0,"BASE":55}
|
Etekcity 8A {"NAME":"ESW01-USA","GPIO":[0,0,0,0,224,544,0,0,2656,2688,32,2592,288,0],"FLAG":0,"BASE":55}
|
||||||
ETEKCITY Voltson Smart Wi-Fi Outlet {"NAME":"ESW15-USA","GPIO":[0,0,0,0,416,224,0,0,2656,2688,32,2592,544,4704],"FLAG":0,"BASE":18}
|
|
||||||
EU3S {"NAME":"AWOW BSD33","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18}
|
EU3S {"NAME":"AWOW BSD33","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18}
|
||||||
Eva Logik {"NAME":"EVA LOGIK Plug","GPIO":[1,32,1,1,1,1,0,0,1,288,224,1,1,0],"FLAG":0,"BASE":18}
|
Eva Logik {"NAME":"EVA LOGIK Plug","GPIO":[1,32,1,1,1,1,0,0,1,288,224,1,1,0],"FLAG":0,"BASE":18}
|
||||||
Ewelink EU 20A {"NAME":"Ewelink Smart Socket 20A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
|
Ewelink EU 20A {"NAME":"Ewelink Smart Socket 20A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -1465,7 +1454,6 @@ Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[1,1,1,1,1,1,1,1,224,288
|
|||||||
Nivian {"NAME":"Nivian Smart Socket","GPIO":[0,0,320,0,0,2688,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18}
|
Nivian {"NAME":"Nivian Smart Socket","GPIO":[0,0,320,0,0,2688,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18}
|
||||||
Nous A1 {"NAME":"NOUS A1","GPIO":[320,0,576,0,2656,2720,0,0,2624,32,0,224,0,0],"FLAG":0,"BASE":45}
|
Nous A1 {"NAME":"NOUS A1","GPIO":[320,0,576,0,2656,2720,0,0,2624,32,0,224,0,0],"FLAG":0,"BASE":45}
|
||||||
Nous A1T 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
|
Nous A1T 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49}
|
||||||
Nous A8T 10A {"NAME":"NOUS A8T","GPIO":[1,1,320,1,32,1,1,1,1,224,2624,1,1,1,1,1,0,1,1,1,0,1,2656,2720,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,2720,2656,0,0,576,32,2592,224,0,0],"FLAG":0,"BASE":45}
|
NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,2720,2656,0,0,576,32,2592,224,0,0],"FLAG":0,"BASE":45}
|
||||||
NX-SM200 {"NAME":"NX-SM200","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18}
|
NX-SM200 {"NAME":"NX-SM200","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18}
|
||||||
NX-SM210 {"NAME":"NX-SM210","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
|
NX-SM210 {"NAME":"NX-SM210","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -1841,7 +1829,6 @@ ZLD64-EU-W {"NAME":"ZLD64-EU-W","GPIO":[0,320,0,32,225,224,0,0
|
|||||||
|
|
||||||
## Presence Sensor
|
## Presence Sensor
|
||||||
```
|
```
|
||||||
Athom Human Presence Sensor {"NAME":"Athom PS01 Sensor","GPIO":[32,0,0,0,640,608,0,0,161,3232,160,3200,576,0],"FLAG":0,"BASE":18}
|
|
||||||
Everything Presence Lite {"NAME":"Everything Presence Lite","GPIO":[0,0,0,0,0,0,0,0,0,0,544,0,3232,3200,160,161,0,640,608,0,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
Everything Presence Lite {"NAME":"Everything Presence Lite","GPIO":[0,0,0,0,0,0,0,0,0,0,544,0,3232,3200,160,161,0,640,608,0,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Everything Presence One {"NAME":"Everything Presence One","GPIO":[0,0,0,0,0,0,0,0,0,3200,3232,160,0,1,1,1,0,0,1,1,0,608,640,0,0,0,0,0,544,161,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"SO114 1 | SwitchMode1 1 | SwitchMode2 1"}
|
Everything Presence One {"NAME":"Everything Presence One","GPIO":[0,0,0,0,0,0,0,0,0,3200,3232,160,0,1,1,1,0,0,1,1,0,608,640,0,0,0,0,0,544,161,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"SO114 1 | SwitchMode1 1 | SwitchMode2 1"}
|
||||||
Tuya mmWave {"NAME":"ZY-M100","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"SO97 1 | TuyaMCU 99,1 | TuyaMCU 75,104"}
|
Tuya mmWave {"NAME":"ZY-M100","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"SO97 1 | TuyaMCU 99,1 | TuyaMCU 75,104"}
|
||||||
@ -2046,7 +2033,7 @@ Teckin SB53 1300lm {"NAME":"Teckin SB53","GPIO":[0,0,0,0,416,419,0,0,4
|
|||||||
Treatlife A19 8W 650lm {"NAME":"Treatlife RGBW","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18}
|
Treatlife A19 8W 650lm {"NAME":"Treatlife RGBW","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18}
|
||||||
V-TAC 10W 806lm {"NAME":"V-TAC VT-5119","GPIO":[0,0,0,0,4032,0,0,0,0,0,4064,0,0,0],"FLAG":0,"BASE":18}
|
V-TAC 10W 806lm {"NAME":"V-TAC VT-5119","GPIO":[0,0,0,0,4032,0,0,0,0,0,4064,0,0,0],"FLAG":0,"BASE":18}
|
||||||
V-Tac A60 10W 806lm {"NAME":"V-Tac A60","GPIO":[0,0,0,0,416,417,0,0,418,419,420,0,0,0],"FLAG":0,"BASE":18,"CMND":"SetOption37 13"}
|
V-Tac A60 10W 806lm {"NAME":"V-Tac A60","GPIO":[0,0,0,0,416,417,0,0,418,419,420,0,0,0],"FLAG":0,"BASE":18,"CMND":"SetOption37 13"}
|
||||||
V-Tac PAR16 4.5W 400lm 100° {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18}
|
V-Tac PAR16 4.5W 400lm 100 {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Vizia 5W GU10 {"NAME":"Vizia RGBWW","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,1],"FLAG":0,"BASE":18}
|
Vizia 5W GU10 {"NAME":"Vizia RGBWW","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,1],"FLAG":0,"BASE":18}
|
||||||
WdtPro 8W 800lm {"NAME":"WdtPro","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18}
|
WdtPro 8W 800lm {"NAME":"WdtPro","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Wipro Garnet 9W 810lm {"NAME":"Wipro","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
Wipro Garnet 9W 810lm {"NAME":"Wipro","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -2149,7 +2136,7 @@ Kainsy 600lm {"NAME":"KAINSY","GPIO":[32,0,0,0,3008,3040,0,0,0,0
|
|||||||
Kkmoon 9W 800lm {"NAME":"KKMOON V21","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18}
|
Kkmoon 9W 800lm {"NAME":"KKMOON V21","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Koaanw 650lm {"NAME":"KOAANW Bulb","GPIO":[0,0,0,0,3008,3040,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":27}
|
Koaanw 650lm {"NAME":"KOAANW Bulb","GPIO":[0,0,0,0,3008,3040,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":27}
|
||||||
Kogan 10W Ambient 1050lm {"NAME":"Kogan RGB","GPIO":[0,0,0,0,2912,416,0,0,0,0,2944,0,0,0],"FLAG":0,"BASE":18}
|
Kogan 10W Ambient 1050lm {"NAME":"Kogan RGB","GPIO":[0,0,0,0,2912,416,0,0,0,0,2944,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Kogan 4.5W 330lm 110° {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,0],"FLAG":0,"BASE":18}
|
Kogan 4.5W 330lm 110 {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Kogan Ambient Candle {"NAME":"Kogan_E14","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
|
Kogan Ambient Candle {"NAME":"Kogan_E14","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Kuled 800lm {"NAME":"KULED 60W RGB","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,4704],"FLAG":0,"BASE":18}
|
Kuled 800lm {"NAME":"KULED 60W RGB","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,4704],"FLAG":0,"BASE":18}
|
||||||
Laideyi 7W {"NAME":"7W-E14-RGBW-La","GPIO":[0,0,0,0,417,416,0,0,418,0,419,0,0,0],"FLAG":0,"BASE":18}
|
Laideyi 7W {"NAME":"7W-E14-RGBW-La","GPIO":[0,0,0,0,417,416,0,0,418,0,419,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -2218,7 +2205,7 @@ Rogoei EBE-QPZ04 6.5W 450lm {"NAME":"EBE-QPZ04","GPIO":[0,0,0,0,4032,0,0,0,0,0,
|
|||||||
Saudio 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
Saudio 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Sengled {"NAME":"Sengled RGBW","GPIO":[0,0,0,0,0,0,0,0,417,416,419,418,0,0],"FLAG":0,"BASE":18}
|
Sengled {"NAME":"Sengled RGBW","GPIO":[0,0,0,0,0,0,0,0,417,416,419,418,0,0],"FLAG":0,"BASE":18}
|
||||||
Shelly Duo RGBW 5W 400lm {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18}
|
Shelly Duo RGBW 5W 400lm {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Shelly Duo RGBW 9W 800lm {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,4736],"FLAG":0,"BASE":18,"CMND":"AdcParam 2, 32000, 1000, 3950|SetOption37 128|SetOption106 1|SetOption107 0|WebButton1 COLOR|WebButton2 WHITE|SetOption42 85|Fade ON|Speed 2|SetOption91 1|Rule1 ON POWER2#state=1 DO POWER1 OFF ENDON ON POWER1#state=1 DO POWER2 OFF ENDON ON Dimmer1#State DO POWER2 OFF ENDON ON Dimmer2#State DO POWER1 OFF ENDON|Rule1 ON"}
|
Shelly Duo RGBW 9W 800lm {"NAME":"Shelly Duo RGBW","GPIO":[0,0,0,0,0,419,0,0,417,416,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Smart 810lm {"NAME":"OOOLED 60W RGB","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,4704],"FLAG":0,"BASE":18}
|
Smart 810lm {"NAME":"OOOLED 60W RGB","GPIO":[0,0,0,0,418,419,0,0,416,0,417,0,0,4704],"FLAG":0,"BASE":18}
|
||||||
SmartLED 9W 400lm {"NAME":"SmartLED RGBWW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
SmartLED 9W 400lm {"NAME":"SmartLED RGBWW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Smartyfi 600lm {"NAME":"SMARTYFI 9W","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
|
Smartyfi 600lm {"NAME":"SMARTYFI 9W","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -2275,13 +2262,11 @@ Anmbest 2 Channel Inching Self-locking Switch Module {"NAME":"Generic","GPIO":[
|
|||||||
Aptinex IOT RelayNode 4 Channel {"NAME":"APTINEX","GPIO":[0,0,1,0,0,0,0,0,224,225,226,227,0,0],"FLAG":0,"BASE":18}
|
Aptinex IOT RelayNode 4 Channel {"NAME":"APTINEX","GPIO":[0,0,1,0,0,0,0,0,224,225,226,227,0,0],"FLAG":0,"BASE":18}
|
||||||
Armtronix Quad {"NAME":"Armtronix Wifi Four Relay Board","GPIO":[1,0,0,0,224,1,0,0,225,226,227,0,1,0],"FLAG":0,"BASE":7}
|
Armtronix Quad {"NAME":"Armtronix Wifi Four Relay Board","GPIO":[1,0,0,0,224,1,0,0,225,226,227,0,1,0],"FLAG":0,"BASE":7}
|
||||||
Athom 1Ch Inching/Self-locking {"NAME":"Athom R01","GPIO":[1,1,1,1,1,224,1,1,1,1,1,1,576,0],"FLAG":0,"BASE":18}
|
Athom 1Ch Inching/Self-locking {"NAME":"Athom R01","GPIO":[1,1,1,1,1,224,1,1,1,1,1,1,576,0],"FLAG":0,"BASE":18}
|
||||||
Athom 8Ch Inching/Self-locking 10A {"NAME":"Athom 8CH Relay Board","GPIO":[0,0,228,0,229,230,1,1,226,227,225,544,1,1152,231,0,0,0,0,0,0,33,32,224,0,0,0,0,35,34,37,36,39,0,0,38],"FLAG":0,"BASE":1}
|
Athom 8Ch Inching/Self-locking 10A {"NAME":"Athom R08","GPIO":[229,1,1,1,230,231,1,1,226,227,225,228,224,0],"FLAG":0,"BASE":18}
|
||||||
Claudy 5V {"NAME":"CLAUDY","GPIO":[0,0,225,0,0,0,0,0,0,0,0,224,0,0],"FLAG":0,"BASE":18}
|
Claudy 5V {"NAME":"CLAUDY","GPIO":[0,0,225,0,0,0,0,0,0,0,0,224,0,0],"FLAG":0,"BASE":18}
|
||||||
Devantech 8x16A {"NAME":"ESP32LR88","GPIO":[0,0,231,0,32,35,0,0,229,230,228,0,33,34,36,37,0,38,39,544,0,225,226,227,0,0,0,0,0,224,3232,3200,0,0,0,0],"FLAG":0,"BASE":1}
|
Devantech 8x16A {"NAME":"ESP32LR88","GPIO":[0,0,231,0,32,35,0,0,229,230,228,0,33,34,36,37,0,38,39,544,0,225,226,227,0,0,0,0,0,224,3232,3200,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Dingtian 16 Channel {"NAME":"Dingtian DT-R008","GPIO":[1,9408,1,9440,1,1,1,1,1,9760,9729,9856,9792,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,9824,9952,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
Dingtian 16 Channel {"NAME":"Dingtian DT-R008","GPIO":[1,9408,1,9440,1,1,1,1,1,9760,9729,9856,9792,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,9824,9952,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
Dingtian 2 Channel {"NAME":"Dingtian DT-R002","GPIO":[5536,9408,225,9440,0,0,0,0,0,9952,0,0,224,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,576,0,0,0,160,0,0,161],"FLAG":0,"BASE":1}
|
|
||||||
Dingtian 32 Channel {"NAME":"Dingtian DT-R008","GPIO":[1,9408,1,9440,1,1,1,1,1,9760,9731,9856,9792,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,9824,9952,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
Dingtian 32 Channel {"NAME":"Dingtian DT-R008","GPIO":[1,9408,1,9440,1,1,1,1,1,9760,9731,9856,9792,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,9824,9952,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
Dingtian 4 Channel {"NAME":"Dingtian DT-R004","GPIO":[0,9408,225,9440,0,0,0,0,227,9952,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,162,0,163,160,0,0,161],"FLAG":0,"BASE":1}
|
|
||||||
Dingtian 8 Channel {"NAME":"Dingtian DT-R008","GPIO":[1,9408,1,9440,1,1,1,1,1,9760,9728,9856,9792,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,9824,9952,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
Dingtian 8 Channel {"NAME":"Dingtian DT-R008","GPIO":[1,9408,1,9440,1,1,1,1,1,9760,9728,9856,9792,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,9824,9952,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
DoHome HomeKit DIY Switch {"NAME":"DoHome DIY","GPIO":[1,1,0,1,96,544,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":1}
|
DoHome HomeKit DIY Switch {"NAME":"DoHome DIY","GPIO":[1,1,0,1,96,544,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Eachen ST-DC2 {"NAME":"Garage Control","GPIO":[162,0,0,0,226,225,33,0,224,288,163,227,0,4704],"FLAG":0,"BASE":18}
|
Eachen ST-DC2 {"NAME":"Garage Control","GPIO":[162,0,0,0,226,225,33,0,224,288,163,227,0,4704],"FLAG":0,"BASE":18}
|
||||||
@ -2330,7 +2315,7 @@ LC Technology 5V/8-80V 1 Channel {"NAME":"LC-Relay-ESP12-1R-MV","GPIO":[1,1,544
|
|||||||
LC Technology 5V/8-80V 1 Channel {"NAME":"LC-Relay-ESP12-1R-D8","GPIO":[1,1,544,1,1,224,1,1,1,1,1,1,321,1],"FLAG":0,"BASE":18}
|
LC Technology 5V/8-80V 1 Channel {"NAME":"LC-Relay-ESP12-1R-D8","GPIO":[1,1,544,1,1,224,1,1,1,1,1,1,321,1],"FLAG":0,"BASE":18}
|
||||||
LC Technology AC90V-250V 1 Channel {"NAME":"ESP32_Relay_AC_X1","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,224,1,1,1,0,1,1,544,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
LC Technology AC90V-250V 1 Channel {"NAME":"ESP32_Relay_AC_X1","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,224,1,1,1,0,1,1,544,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
LC Technology DC5-60V 1 Channel {"NAME":"ESP32_Relay_X1","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,224,1,1,1,0,1,1,544,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
LC Technology DC5-60V 1 Channel {"NAME":"ESP32_Relay_X1","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,224,1,1,1,0,1,1,544,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
LC Technology DC5-60V 2 Channel {"NAME":"ESP32_Relay_X2","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,224,225,0,0,0,0,0,544,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
LC Technology DC5-60V 2 Channel {"NAME":"ESP32_Relay_X2","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,544,0,225,224,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
LC Technology DC5-60V 4 Channel {"NAME":"ESP32_Relay_X4","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,544,0,226,227,1,0,0,0,0,224,225,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
LC Technology DC5-60V 4 Channel {"NAME":"ESP32_Relay_X4","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,544,0,226,227,1,0,0,0,0,224,225,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
LC Technology ESP8266 5V {"NAME":"ESP8266-01S","GPIO":[224,3200,0,3232,0,0,0,0,0,0,0,0,0,4704],"FLAG":0,"BASE":18}
|
LC Technology ESP8266 5V {"NAME":"ESP8266-01S","GPIO":[224,3200,0,3232,0,0,0,0,0,0,0,0,0,4704],"FLAG":0,"BASE":18}
|
||||||
LilyGo T-Relay 5V 8 Channel {"NAME":"LilyGo ESP32 Relay 8","GPIO":[1,1,1,1,1,231,1,1,227,226,1,1,1,1,230,229,0,228,1,1,0,544,1,1,0,0,0,0,225,224,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
LilyGo T-Relay 5V 8 Channel {"NAME":"LilyGo ESP32 Relay 8","GPIO":[1,1,1,1,1,231,1,1,227,226,1,1,1,1,230,229,0,228,1,1,0,544,1,1,0,0,0,0,225,224,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
||||||
@ -2375,10 +2360,6 @@ Connex Smart Indoor {"NAME":"Connex Siren","GPIO":[0,2272,0,2304,0,0,0,
|
|||||||
NEO Coolcam Temperature and Humidity 3in1 Alarm {"NAME":"Neo Siren 3in1","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
NEO Coolcam Temperature and Humidity 3in1 Alarm {"NAME":"Neo Siren 3in1","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Smart Meter
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
## Smoke Sensor
|
## Smoke Sensor
|
||||||
```
|
```
|
||||||
Nedis Smoke Detector {"NAME":"Nedis WIFIDS10WT","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
Nedis Smoke Detector {"NAME":"Nedis WIFIDS10WT","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
@ -2455,6 +2436,7 @@ Connect SmartHome 3 Gang Wall Switch () {"NAME":"CSH-SWTCH3","GPIO":[0,0,288,0,
|
|||||||
Csmart US-B2 {"NAME":"Csmart US-B2","GPIO":[0,544,0,33,32,0,0,0,0,225,224,0,0,0],"FLAG":0,"BASE":18}
|
Csmart US-B2 {"NAME":"Csmart US-B2","GPIO":[0,544,0,33,32,0,0,0,0,225,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Delock WLAN EASY-USB {"NAME":"Delock 11828","GPIO":[0,0,0,32,0,0,0,0,0,576,224,0,0,0],"FLAG":0,"BASE":53}
|
Delock WLAN EASY-USB {"NAME":"Delock 11828","GPIO":[0,0,0,32,0,0,0,0,0,576,224,0,0,0],"FLAG":0,"BASE":53}
|
||||||
Deta 1 Gang {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,544,0,0,0,0,224,0,0,64,0],"FLAG":0,"BASE":18}
|
Deta 1 Gang {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,544,0,0,0,0,224,0,0,64,0],"FLAG":0,"BASE":18}
|
||||||
|
Deta 2 Gang {"NAME":"DETA 2G Switch","GPIO":[0,0,0,0,544,0,0,0,65,224,225,0,64,0],"FLAG":0,"BASE":18}
|
||||||
Deta 3 Gang {"NAME":"DETA 3G Switch","GPIO":[544,0,0,66,65,224,0,0,226,0,225,0,64,0],"FLAG":0,"BASE":18}
|
Deta 3 Gang {"NAME":"DETA 3G Switch","GPIO":[544,0,0,66,65,224,0,0,226,0,225,0,64,0],"FLAG":0,"BASE":18}
|
||||||
Deta 4 Gang {"NAME":"Deta 4G Switch","GPIO":[576,0,0,34,33,224,0,0,226,35,225,227,32,0],"FLAG":0,"BASE":18}
|
Deta 4 Gang {"NAME":"Deta 4G Switch","GPIO":[576,0,0,34,33,224,0,0,226,35,225,227,32,0],"FLAG":0,"BASE":18}
|
||||||
DETA Mechanism {"NAME":"Deta 6014HA","GPIO":[0,0,0,0,0,0,0,0,320,0,32,0,224,0],"FLAG":0,"BASE":18}
|
DETA Mechanism {"NAME":"Deta 6014HA","GPIO":[0,0,0,0,0,0,0,0,320,0,32,0,224,0],"FLAG":0,"BASE":18}
|
||||||
@ -2603,7 +2585,7 @@ Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[576,0,0,33,225,0,0,0,
|
|||||||
NEO Coolcam 2Ch Touch Light {"NAME":"Neo NAS-SC01W-2","GPIO":[0,0,0,0,225,0,0,0,32,224,33,0,544,0],"FLAG":0,"BASE":18}
|
NEO Coolcam 2Ch Touch Light {"NAME":"Neo NAS-SC01W-2","GPIO":[0,0,0,0,225,0,0,0,32,224,33,0,544,0],"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 {"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}
|
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 Botão {"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 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}
|
||||||
PNI SmartHome 1 Key {"NAME":"Tuya Switch 1 key","GPIO":[544,1,1,32,224,1,1,1,1,1,288,1,1,1],"FLAG":0,"BASE":18}
|
PNI SmartHome 1 Key {"NAME":"Tuya Switch 1 key","GPIO":[544,1,1,32,224,1,1,1,1,1,288,1,1,1],"FLAG":0,"BASE":18}
|
||||||
PNI SmartHome 2 Keys {"NAME":"Tuya switch 2 key","GPIO":[544,0,289,0,0,32,0,0,33,225,0,224,288,0],"FLAG":0,"BASE":18}
|
PNI SmartHome 2 Keys {"NAME":"Tuya switch 2 key","GPIO":[544,0,289,0,0,32,0,0,33,225,0,224,288,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}
|
Prosto {"NAME":"Prosto WFS-T10","GPIO":[0,0,0,0,0,224,0,0,320,0,64,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -2616,7 +2598,7 @@ QNCX Smart Breaker {"NAME":"QNCX Smart breaker","GPIO":[0,0,0,0,160,22
|
|||||||
Qualitel 1 Gang {"NAME":"Qualitel 1 Gang","GPIO":[544,0,0,160,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18}
|
Qualitel 1 Gang {"NAME":"Qualitel 1 Gang","GPIO":[544,0,0,160,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Qualitel 2-Gang {"NAME":"Qualitel 2 Gang","GPIO":[544,0,289,0,0,161,0,0,160,224,0,225,288,0],"FLAG":0,"BASE":18}
|
Qualitel 2-Gang {"NAME":"Qualitel 2 Gang","GPIO":[544,0,289,0,0,161,0,0,160,224,0,225,288,0],"FLAG":0,"BASE":18}
|
||||||
Qualitel 3 Gang {"NAME":"Qualitel 3 Gang","GPIO":[544,0,290,161,225,162,0,0,160,224,289,226,288,0],"FLAG":0,"BASE":18}
|
Qualitel 3 Gang {"NAME":"Qualitel 3 Gang","GPIO":[544,0,290,161,225,162,0,0,160,224,289,226,288,0],"FLAG":0,"BASE":18}
|
||||||
Refoss AC/DC {"NAME":"Refoss-R10","GPIO":[1,1,0,1,224,192,0,0,2656,2720,32,1,2624,4736],"FLAG":0,"BASE":18}
|
Refoss AC/DC {"NAME":"Refoss-R10","GPIO":[0,1,3104,0,224,192,0,0,2720,0,0,0,0,4736],"FLAG":0,"BASE":18}
|
||||||
RY-RSM104 Light Touch {"NAME":"RY-RSM104","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
RY-RSM104 Light Touch {"NAME":"RY-RSM104","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
|
||||||
Sainko 1-Way {"NAME":"SAINKO 1CH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28}
|
Sainko 1-Way {"NAME":"SAINKO 1CH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28}
|
||||||
Sainko 2 Way {"NAME":"Sainko 2-Way","GPIO":[0,1,320,0,0,32,0,0,224,225,0,0,33,0],"FLAG":0,"BASE":18}
|
Sainko 2 Way {"NAME":"Sainko 2-Way","GPIO":[0,1,320,0,0,32,0,0,224,225,0,0,33,0],"FLAG":0,"BASE":18}
|
||||||
@ -2649,7 +2631,7 @@ Smatrul 5A RF433MHz 4 Gang Touch {"NAME":"Smatrul RF433MHz 3 Gang Touch Switch
|
|||||||
Smatrul Infrared Sensor {"NAME":"WHS-2","GPIO":[0,0,0,160,288,0,0,0,0,224,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SwitchMode1 4 | SO13 1"}
|
Smatrul Infrared Sensor {"NAME":"WHS-2","GPIO":[0,0,0,160,288,0,0,0,0,224,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"SwitchMode1 4 | SO13 1"}
|
||||||
Sonoff IW101 {"NAME":"Sonoff IW101","GPIO":[32,3072,0,3104,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":41}
|
Sonoff IW101 {"NAME":"Sonoff IW101","GPIO":[32,3072,0,3104,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":41}
|
||||||
Sonoff SwitchMan M5-1C 1 Gang {"NAME":"Sonoff SwitchMan M5-1C-86","GPIO":[32,0,0,0,288,576,0,0,0,0,0,0,0,0,416,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
Sonoff SwitchMan M5-1C 1 Gang {"NAME":"Sonoff SwitchMan M5-1C-86","GPIO":[32,0,0,0,288,576,0,0,0,0,0,0,0,0,416,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Sonoff SwitchMan M5-2C 2 Gang {"NAME":"Sonoff SwitchMan 2C","GPIO":[0,0,0,0,32,576,0,0,0,0,0,33,0,0,416,225,0,0,289,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,288],"FLAG":0,"BASE":1}
|
Sonoff SwitchMan M5-2C 2 Gang {"NAME":"Sonoff SwitchMan 2C","GPIO":[0,0,0,0,32,576,0,0,0,0,0,33,0,0,416,225,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Sonoff SwitchMan M5-3C 3 Gang {"NAME":"Sonoff M5-3C","GPIO":[33,0,0,0,32,576,0,0,0,0,0,34,0,0,416,225,0,0,226,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
Sonoff SwitchMan M5-3C 3 Gang {"NAME":"Sonoff M5-3C","GPIO":[33,0,0,0,32,576,0,0,0,0,0,34,0,0,416,225,0,0,226,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Sonoff T1 EU 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28}
|
Sonoff T1 EU 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28}
|
||||||
Sonoff T1 EU 2 Gang {"NAME":"Sonoff T1 2CH","GPIO":[32,1,1,1,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":29}
|
Sonoff T1 EU 2 Gang {"NAME":"Sonoff T1 2CH","GPIO":[32,1,1,1,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":29}
|
||||||
@ -2752,12 +2734,12 @@ ZUCZUG 3 Gang {"NAME":"2ph105626a x3","GPIO":[0,288,0,32,34,33,0,
|
|||||||
## Switch Module
|
## Switch Module
|
||||||
```
|
```
|
||||||
2 CH Smart Switch {"NAME":"Generic","GPIO":[32,1,1,1,1,225,33,1,224,288,1,1,1,1],"FLAG":0,"BASE":18}
|
2 CH Smart Switch {"NAME":"Generic","GPIO":[32,1,1,1,1,225,33,1,224,288,1,1,1,1],"FLAG":0,"BASE":18}
|
||||||
AGL Módulo Relé 01 Canal {"NAME":"AGL-Basic","GPIO":[0,1,0,0,224,32,0,0,0,0,320,0,0,0],"FLAG":0,"BASE":18}
|
AGL Modulo Relay 01 Canal {"NAME":"AGL-Basic","GPIO":[0,1,0,0,224,32,0,0,0,0,320,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Albohes 2 Channel {"NAME":"Albohes SH-08","GPIO":[0,3200,33,3232,321,320,0,0,224,544,32,0,225,1],"FLAG":0,"BASE":18}
|
Albohes 2 Channel {"NAME":"Albohes SH-08","GPIO":[0,3200,33,3232,321,320,0,0,224,544,32,0,225,1],"FLAG":0,"BASE":18}
|
||||||
Athom 10A {"NAME":"CB01-TAS-1","GPIO":[0,0,0,32,320,0,0,0,0,224,0,0,0,1],"FLAG":0,"BASE":18}
|
Athom 10A {"NAME":"CB01-TAS-1","GPIO":[0,0,0,32,320,0,0,0,0,224,0,0,0,1],"FLAG":0,"BASE":18}
|
||||||
Athom 2Ch Inching/Self-locking {"NAME":"Athom 2CH Relay Board","GPIO":[0,0,0,0,0,0,1,1,0,0,225,544,1,1152,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,32,0,0,33],"FLAG":0,"BASE":1}
|
Athom 2Ch Inching/Self-locking {"NAME":"Athom R02","GPIO":[1,1,1,1,225,224,1,1,1,1,1,1,576,0],"FLAG":0,"BASE":18}
|
||||||
Athom 3-Way Mini Relay {"NAME":"RS01-TAS-1","GPIO":[0,0,0,32,576,0,0,0,0,224,160,0,0,0],"FLAG":0,"BASE":18}
|
Athom 3-Way Mini Relay {"NAME":"RS01-TAS-1","GPIO":[0,0,0,32,576,0,0,0,0,224,160,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Athom 4Ch Inching/Self-locking 10A {"NAME":"Athom 4CH Relay Board","GPIO":[0,0,0,0,0,0,1,1,226,227,225,544,1,1152,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,34,35,32,0,0,33],"FLAG":0,"BASE":1}
|
Athom 4Ch Inching/Self-locking 10A {"NAME":"Athom R04","GPIO":[1,1,1,1,32,576,1,1,226,227,225,1,224,0],"FLAG":0,"BASE":18}
|
||||||
Athom 4Ch Inching/Self-locking 30A {"NAME":"Athom R04-30A","GPIO":[1,1,1,1,32,576,1,1,226,227,225,1,224,0],"FLAG":0,"BASE":18}
|
Athom 4Ch Inching/Self-locking 30A {"NAME":"Athom R04-30A","GPIO":[1,1,1,1,32,576,1,1,226,227,225,1,224,0],"FLAG":0,"BASE":18}
|
||||||
ATMS1601 230VAC DIN Timer/Switch {"NAME":"ATMS1601","GPIO":[1,1,1,1,544,320,1,1,224,32,1,1,1,1],"FLAG":0,"BASE":18}
|
ATMS1601 230VAC DIN Timer/Switch {"NAME":"ATMS1601","GPIO":[1,1,1,1,544,320,1,1,224,32,1,1,1,1],"FLAG":0,"BASE":18}
|
||||||
Aubess Power Monitor Switch 16A {"NAME":"Aubess with (BL0942)","GPIO":[0,3200,0,7520,0,0,0,0,160,0,224,0,0,0],"FLAG":0,"BASE":18}
|
Aubess Power Monitor Switch 16A {"NAME":"Aubess with (BL0942)","GPIO":[0,3200,0,7520,0,0,0,0,160,0,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -2771,7 +2753,7 @@ Century Aoke Smart Switch {"NAME":"CenturyAoke","GPIO":[0,1,0,1,224,0,0,0,32,
|
|||||||
Deta 6000HA Smart Inline Switch {"NAME":"DETA-6000HA","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
|
Deta 6000HA Smart Inline Switch {"NAME":"DETA-6000HA","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18}
|
||||||
dewenwils Outdoor Timer Box {"NAME":"Dewenwils50054","GPIO":[0,0,290,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
|
dewenwils Outdoor Timer Box {"NAME":"Dewenwils50054","GPIO":[0,0,290,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18}
|
||||||
EDM Low Voltage {"NAME":"HVAC Switch","GPIO":[0,0,0,0,288,321,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18}
|
EDM Low Voltage {"NAME":"HVAC Switch","GPIO":[0,0,0,0,288,321,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
eMylo 2 Channel {"NAME":"eMylo XL9252WI","GPIO":[0,1,0,0,320,225,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18}
|
eMylo 2 Channel {"NAME":"eMylo XL9252WI","GPIO":[0,1,0,0,320,225,0,0,224,0,163,0,0,0],"FLAG":0,"BASE":18}
|
||||||
eMylo Single Channel Switch {"NAME":"eMylo XL9251WI","GPIO":[0,1,0,0,320,0,0,0,224,0,35,0,0,0],"FLAG":0,"BASE":18}
|
eMylo Single Channel Switch {"NAME":"eMylo XL9251WI","GPIO":[0,1,0,0,320,0,0,0,224,0,35,0,0,0],"FLAG":0,"BASE":18}
|
||||||
eMylo 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}
|
eMylo 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}
|
||||||
eMylo SS-8839-03 {"NAME":"SS-8839-03","GPIO":[0,1,0,1,288,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18}
|
eMylo SS-8839-03 {"NAME":"SS-8839-03","GPIO":[0,1,0,1,288,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18}
|
||||||
@ -2795,11 +2777,8 @@ Moes {"NAME":"Moes MS-104B","GPIO":[0,0,32,0,480,0,0,0,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}
|
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}
|
||||||
Moes Mini 3 Gang 1/2 Way {"NAME":"Moes MS-104C","GPIO":[0,0,0,34,32,33,0,0,224,225,226,0,0,0],"FLAG":0,"BASE":18}
|
Moes Mini 3 Gang 1/2 Way {"NAME":"Moes MS-104C","GPIO":[0,0,0,34,32,33,0,0,224,225,226,0,0,0],"FLAG":0,"BASE":18}
|
||||||
Nedis 10A {"NAME":"Nedis WIFIPS10WT","GPIO":[0,0,0,0,224,0,0,0,32,321,0,288,0,0],"FLAG":0,"BASE":18}
|
Nedis 10A {"NAME":"Nedis WIFIPS10WT","GPIO":[0,0,0,0,224,0,0,0,32,321,0,288,0,0],"FLAG":0,"BASE":18}
|
||||||
Nous 1 Channel {"NAME":"NOUS B1T","GPIO":[544,0,1,0,32,160,1,1,224,0,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
Nous 1 Channel Touch {"NAME":"NOUS L1T","GPIO":[544,0,1,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
|
Nous 1 Channel Touch {"NAME":"NOUS L1T","GPIO":[544,0,1,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Nous 1/2 Channel {"NAME":"NOUS L13T Smart Switch Module","GPIO":[1,161,1,160,225,224,1,1,544,1,32,1,1,1],"FLAG":0,"BASE":18}
|
Nous 1/2 Channel {"NAME":"NOUS L13T Smart Switch Module","GPIO":[1,161,1,160,225,224,1,1,544,1,32,1,1,1],"FLAG":0,"BASE":18}
|
||||||
Nous 2 Channel {"NAME":"NOUS B2T","GPIO":[544,3200,1,8160,32,160,1,1,224,0,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
Nous 2 Channel / Curtain {"NAME":"NOUS B3T","GPIO":[544,3200,1,8128,32,160,1,1,224,225,0,1,1,1,161,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,0,0,1],"FLAG":0,"BASE":1}
|
|
||||||
Nous 2 Channel Touch {"NAME":"NOUS L2T","GPIO":[544,289,1,32,225,33,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
|
Nous 2 Channel Touch {"NAME":"NOUS L2T","GPIO":[544,289,1,32,225,33,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1}
|
||||||
Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,1,0,1,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
|
Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,1,0,1,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18}
|
||||||
ONiOFF Smart Switch {"NAME":"ONOFF SmartSwitch","GPIO":[1,320,1,1,1,32,0,0,224,1,1,0,0,0],"FLAG":0,"BASE":1}
|
ONiOFF Smart Switch {"NAME":"ONOFF SmartSwitch","GPIO":[1,320,1,1,1,32,0,0,224,1,1,0,0,0],"FLAG":0,"BASE":1}
|
||||||
@ -2953,10 +2932,6 @@ Xenon {"NAME":"Xenon SM-PM801-K1","GPIO":[0,320,0,32,2720
|
|||||||
Xenon 2AC 1USB {"NAME":"Xenon SM-PW801-U1","GPIO":[0,0,0,0,288,32,0,0,224,0,225,0,226,0],"FLAG":0,"BASE":18}
|
Xenon 2AC 1USB {"NAME":"Xenon SM-PW801-U1","GPIO":[0,0,0,0,288,32,0,0,224,0,225,0,226,0],"FLAG":0,"BASE":18}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Wall Switch
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
## Water Sensor
|
## Water Sensor
|
||||||
```
|
```
|
||||||
Nedis SmartLife Water Detector {"NAME":"Nedis WIFIDW10WT","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 51,21"}
|
Nedis SmartLife Water Detector {"NAME":"Nedis WIFIDW10WT","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 51,21"}
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
"openocd_target": "esp32.cfg"
|
"openocd_target": "esp32.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32 >= 4M Flash, PSRAM with fix, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32 >= 4M Flash, PSRAM with fix, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
"openocd_target": "esp32.cfg"
|
"openocd_target": "esp32.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
"openocd_target": "esp32-solo-1.cfg"
|
"openocd_target": "esp32-solo-1.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-solo1 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-solo1 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
@ -41,11 +40,6 @@
|
|||||||
"download": {
|
"download": {
|
||||||
"speed": 230400
|
"speed": 230400
|
||||||
},
|
},
|
||||||
"espidf": {
|
|
||||||
"custom_sdkconfig": [
|
|
||||||
"CONFIG_FREERTOS_UNICORE=y"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"url": "https://www.espressif.com/sites/default/files/documentation/esp32-solo-1_datasheet_en.pdf",
|
"url": "https://www.espressif.com/sites/default/files/documentation/esp32-solo-1_datasheet_en.pdf",
|
||||||
"vendor": "Espressif"
|
"vendor": "Espressif"
|
||||||
}
|
}
|
@ -17,8 +17,7 @@
|
|||||||
"openocd_target": "esp32c2.cfg"
|
"openocd_target": "esp32c2.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-C2 = 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-C2 = 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
@ -39,6 +38,6 @@
|
|||||||
"download": {
|
"download": {
|
||||||
"speed": 230400
|
"speed": 230400
|
||||||
},
|
},
|
||||||
"url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp8684/esp8684-devkitm-1/user_guide.html",
|
"url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html",
|
||||||
"vendor": "Espressif"
|
"vendor": "Espressif"
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
"openocd_target": "esp32c2.cfg"
|
"openocd_target": "esp32c2.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-C2 = 2M Flash, Tasmota 1245kB Code/OTA, 64k FS",
|
"name": "Espressif Generic ESP32-C2 = 2M Flash, Tasmota 1245kB Code/OTA, 64k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
@ -39,6 +38,6 @@
|
|||||||
"download": {
|
"download": {
|
||||||
"speed": 230400
|
"speed": 230400
|
||||||
},
|
},
|
||||||
"url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp8684/esp8684-devkitm-1/user_guide.html",
|
"url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html",
|
||||||
"vendor": "Espressif"
|
"vendor": "Espressif"
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,14 @@
|
|||||||
"bluetooth"
|
"bluetooth"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32c3.cfg"
|
"openocd_target": "esp32c3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
"openocd_target": "esp32c3.cfg"
|
"openocd_target": "esp32c3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -14,11 +14,14 @@
|
|||||||
"bluetooth"
|
"bluetooth"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32c6.cfg"
|
"openocd_target": "esp32c6.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-C6 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-C6 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
"openocd_target": "esp32c6.cfg"
|
"openocd_target": "esp32c6.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-C6 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-C6 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"core": "esp32",
|
|
||||||
"extra_flags": [
|
|
||||||
"-DARDUINO_TASMOTA -DESP32P4 -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DUSE_USB_CDC_CONSOLE"
|
|
||||||
],
|
|
||||||
"f_cpu": "360000000L",
|
|
||||||
"f_flash": "80000000L",
|
|
||||||
"flash_mode": "qio",
|
|
||||||
"mcu": "esp32p4",
|
|
||||||
"variant": "esp32p4",
|
|
||||||
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
|
||||||
},
|
|
||||||
"connectivity": [
|
|
||||||
"wifi",
|
|
||||||
"bluetooth",
|
|
||||||
"openthread",
|
|
||||||
"ethernet"
|
|
||||||
],
|
|
||||||
"debug": {
|
|
||||||
"openocd_target": "esp32p4.cfg"
|
|
||||||
},
|
|
||||||
"frameworks": [
|
|
||||||
"arduino",
|
|
||||||
"espidf"
|
|
||||||
],
|
|
||||||
"name": "Espressif Generic ESP32-P4 >= 4M Flash, Tasmota 2880k Code/OTA, >= 320k FS",
|
|
||||||
"upload": {
|
|
||||||
"arduino": {
|
|
||||||
"flash_extra_images": [
|
|
||||||
[
|
|
||||||
"0x10000",
|
|
||||||
"tasmota32p4-safeboot.bin"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"flash_size": "4MB",
|
|
||||||
"maximum_ram_size": 768000,
|
|
||||||
"maximum_size": 4194304,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 1500000
|
|
||||||
},
|
|
||||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html",
|
|
||||||
"vendor": "Espressif"
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"core": "esp32",
|
|
||||||
"extra_flags": [
|
|
||||||
"-DARDUINO_TASMOTA -DESP32P4 -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DUSE_USB_CDC_CONSOLE"
|
|
||||||
],
|
|
||||||
"f_cpu": "360000000L",
|
|
||||||
"f_flash": "80000000L",
|
|
||||||
"flash_mode": "qio",
|
|
||||||
"mcu": "esp32p4",
|
|
||||||
"variant": "esp32p4",
|
|
||||||
"partitions": "partitions/esp32_partition_app3904k_fs3392k.csv"
|
|
||||||
},
|
|
||||||
"connectivity": [
|
|
||||||
"wifi",
|
|
||||||
"bluetooth",
|
|
||||||
"openthread",
|
|
||||||
"ethernet"
|
|
||||||
],
|
|
||||||
"debug": {
|
|
||||||
"openocd_target": "esp32p4.cfg"
|
|
||||||
},
|
|
||||||
"frameworks": [
|
|
||||||
"arduino",
|
|
||||||
"espidf"
|
|
||||||
],
|
|
||||||
"name": "Espressif ESP32-P4 Function EV Board",
|
|
||||||
"upload": {
|
|
||||||
"arduino": {
|
|
||||||
"flash_extra_images": [
|
|
||||||
[
|
|
||||||
"0x10000",
|
|
||||||
"tasmota32p4-safeboot.bin"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"flash_size": "16MB",
|
|
||||||
"maximum_ram_size": 768000,
|
|
||||||
"maximum_size": 16777216,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 1500000
|
|
||||||
},
|
|
||||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html",
|
|
||||||
"vendor": "Espressif"
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"core": "esp32",
|
|
||||||
"extra_flags": [
|
|
||||||
"-DARDUINO_TASMOTA -DESP32P4 -DBOARD_HAS_PSRAM"
|
|
||||||
],
|
|
||||||
"f_cpu": "360000000L",
|
|
||||||
"f_flash": "80000000L",
|
|
||||||
"flash_mode": "qio",
|
|
||||||
"mcu": "esp32p4",
|
|
||||||
"variant": "esp32p4",
|
|
||||||
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
|
||||||
},
|
|
||||||
"connectivity": [
|
|
||||||
"wifi",
|
|
||||||
"bluetooth",
|
|
||||||
"openthread",
|
|
||||||
"ethernet"
|
|
||||||
],
|
|
||||||
"debug": {
|
|
||||||
"openocd_target": "esp32p4.cfg"
|
|
||||||
},
|
|
||||||
"frameworks": [
|
|
||||||
"arduino",
|
|
||||||
"espidf"
|
|
||||||
],
|
|
||||||
"name": "Espressif Generic ESP32-P4 >= 4M Flash, Tasmota 2880k Code/OTA, >= 320k FS",
|
|
||||||
"upload": {
|
|
||||||
"arduino": {
|
|
||||||
"flash_extra_images": [
|
|
||||||
[
|
|
||||||
"0x10000",
|
|
||||||
"tasmota32p4-safeboot.bin"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"flash_size": "4MB",
|
|
||||||
"maximum_ram_size": 768000,
|
|
||||||
"maximum_size": 4194304,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 1500000
|
|
||||||
},
|
|
||||||
"url": "https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html",
|
|
||||||
"vendor": "Espressif"
|
|
||||||
}
|
|
@ -16,8 +16,7 @@
|
|||||||
"openocd_target": "esp32s2.cfg"
|
"openocd_target": "esp32s2.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
"openocd_target": "esp32s2.cfg"
|
"openocd_target": "esp32s2.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "dout",
|
"flash_mode": "dout",
|
||||||
|
"hwids": [
|
||||||
|
[
|
||||||
|
"0x303A",
|
||||||
|
"0x1001"
|
||||||
|
]
|
||||||
|
],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "esp32s3",
|
"variant": "esp32s3",
|
||||||
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
||||||
@ -18,11 +24,14 @@
|
|||||||
"ethernet"
|
"ethernet"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
"ethernet"
|
"ethernet"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"hwids": [
|
||||||
|
[
|
||||||
|
"0x303A",
|
||||||
|
"0x1001"
|
||||||
|
]
|
||||||
|
],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "esp32s3",
|
"variant": "esp32s3",
|
||||||
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
||||||
@ -18,11 +24,14 @@
|
|||||||
"ethernet"
|
"ethernet"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
"ethernet"
|
"ethernet"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M QIO Flash + OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M QIO Flash + OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
"flash_mode": "qio",
|
"flash_mode": "qio",
|
||||||
|
"hwids": [
|
||||||
|
[
|
||||||
|
"0x303A",
|
||||||
|
"0x1001"
|
||||||
|
]
|
||||||
|
],
|
||||||
"mcu": "esp32s3",
|
"mcu": "esp32s3",
|
||||||
"variant": "esp32s3",
|
"variant": "esp32s3",
|
||||||
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
|
||||||
@ -18,11 +24,14 @@
|
|||||||
"ethernet"
|
"ethernet"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
"ethernet"
|
"ethernet"
|
||||||
],
|
],
|
||||||
"debug": {
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": [
|
||||||
|
"esp-builtin"
|
||||||
|
],
|
||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M QIO Flash + QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M QIO Flash + QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M OPI Flash + PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M QIO Flash + OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M QIO Flash + OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
"openocd_target": "esp32s3.cfg"
|
"openocd_target": "esp32s3.cfg"
|
||||||
},
|
},
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"arduino",
|
"arduino"
|
||||||
"espidf"
|
|
||||||
],
|
],
|
||||||
"name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
"name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
|
||||||
"upload": {
|
"upload": {
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
// SPI_MOSI_DLEN_REG is not defined anymore in esp32s3
|
// SPI_MOSI_DLEN_REG is not defined anymore in esp32s3
|
||||||
#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
|
#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
|
||||||
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4
|
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6
|
||||||
#define SPI_HOST SPI1_HOST
|
#define SPI_HOST SPI1_HOST
|
||||||
#define HSPI_HOST SPI2_HOST
|
#define HSPI_HOST SPI2_HOST
|
||||||
#define VSPI_HOST SPI2_HOST /* No SPI3_host on C2/C6 */
|
#define VSPI_HOST SPI2_HOST /* No SPI3_host on C2/C6 */
|
||||||
@ -70,10 +70,3 @@
|
|||||||
#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
|
#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x)
|
||||||
|
|
||||||
#endif // TARGET
|
#endif // TARGET
|
||||||
|
|
||||||
// This trick makes sure that 'lto' optimizer does not inline `delay()
|
|
||||||
// so we can override it with `-Wl,--wrap=delay` linker directive
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
#endif // _cplusplus
|
|
||||||
void delay(__UINT32_TYPE__ ms) __attribute__((noinline)) __attribute__ ((noclone));
|
|
||||||
|
@ -177,22 +177,6 @@ char * ToBinary(uint32_t value, char *str, int32_t digits) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * U64toStr(uint64_t value, char *str) {
|
|
||||||
// str must be at least 24 bytes long
|
|
||||||
uint32_t i = 23;
|
|
||||||
str[--i] = 0; // end of string
|
|
||||||
do {
|
|
||||||
uint64_t m = value;
|
|
||||||
value /= 10;
|
|
||||||
char c = m - 10 * value;
|
|
||||||
str[--i] = c < 10 ? c + '0' : c + 'A' - 10;
|
|
||||||
} while (value);
|
|
||||||
if (i) {
|
|
||||||
memmove(str, str +i, 23 -i);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * U64toHex(uint64_t value, char *str, uint32_t zeroleads) {
|
char * U64toHex(uint64_t value, char *str, uint32_t zeroleads) {
|
||||||
// str must be at least 17 bytes long
|
// str must be at least 17 bytes long
|
||||||
str[16] = 0; // end of string
|
str[16] = 0; // end of string
|
||||||
@ -326,7 +310,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'B': // Pointer to SBuffer
|
case 'B': // Pointer to SBuffer
|
||||||
{
|
{
|
||||||
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
||||||
@ -343,7 +326,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// '%_b' outputs a uint32_t to binary
|
// '%_b' outputs a uint32_t to binary
|
||||||
// '%8_b' outputs a uint8_t to binary
|
// '%8_b' outputs a uint8_t to binary
|
||||||
case 'b': // Binary, decimals indicates the zero prefill
|
case 'b': // Binary, decimals indicates the zero prefill
|
||||||
@ -434,7 +416,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// '%_X' outputs a 64 bits unsigned int to uppercase HEX with 16 digits
|
// '%_X' outputs a 64 bits unsigned int to uppercase HEX with 16 digits
|
||||||
case 'X': // input is `uint64_t*`, printed as 16 hex digits (no prefix 0x)
|
case 'X': // input is `uint64_t*`, printed as 16 hex digits (no prefix 0x)
|
||||||
{
|
{
|
||||||
@ -448,20 +429,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// '%_U' outputs a 64 bits unsigned int to decimal
|
|
||||||
case 'U': // input is `uint64_t*`, printed as decimal
|
|
||||||
{
|
|
||||||
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
|
||||||
else {
|
|
||||||
U64toStr(*(uint64_t*)cur_val, hex);
|
|
||||||
new_val_str = copyStr(hex);
|
|
||||||
if (new_val_str == nullptr) { goto free_allocs; }
|
|
||||||
allocs[alloc_idx++] = new_val_str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
*cur_val_ptr = new_val_str;
|
*cur_val_ptr = new_val_str;
|
||||||
*fmt = 's'; // replace `%_X` with `%0s` to display a string instead
|
*fmt = 's'; // replace `%_X` with `%0s` to display a string instead
|
||||||
|
@ -66,14 +66,11 @@ void test_ext_snprintf_P(void) {
|
|||||||
Serial.printf("--> out=%s\n", c);
|
Serial.printf("--> out=%s\n", c);
|
||||||
ext_snprintf_P(c, sizeof(c), "Float default=%*_f, int(3)=%*_f, int(3)=%*_f, int(3)=%*_f, 6dec=%*_f", 1, &fpi, 4, &f3, -4, &f3, -4, &f31, -8, &fpi);
|
ext_snprintf_P(c, sizeof(c), "Float default=%*_f, int(3)=%*_f, int(3)=%*_f, int(3)=%*_f, 6dec=%*_f", 1, &fpi, 4, &f3, -4, &f3, -4, &f31, -8, &fpi);
|
||||||
Serial.printf("--> out=%s\n", c);
|
Serial.printf("--> out=%s\n", c);
|
||||||
|
uint64_t u641 = 0x1122334455667788LL;
|
||||||
uint64_t u641 = 0x1122334455667788LL; // 1234605616436508552
|
uint64_t u642 = 0x0123456789ABCDEFLL;
|
||||||
uint64_t u642 = 0x0123456789ABCDEFLL; // 81985529216486895
|
uint64_t u643 = 0xFEDCBA9876543210LL;
|
||||||
uint64_t u643 = 0xFEDCBA9876543210LL; // 18364758544493064720
|
|
||||||
ext_snprintf_P(c, sizeof(c), "Int64 0x%_X 0x%_X 0x%_X", &u641, &u642, &u643);
|
ext_snprintf_P(c, sizeof(c), "Int64 0x%_X 0x%_X 0x%_X", &u641, &u642, &u643);
|
||||||
Serial.printf("--> out=%s\n", c);
|
Serial.printf("--> out=%s\n", c);
|
||||||
ext_snprintf_P(c, sizeof(c), "Int64 decimal %_U %_U %_U", &u641, &u642, &u643);
|
|
||||||
Serial.printf("--> out=%s\n", c);
|
|
||||||
|
|
||||||
// ext_snprintf_P(c, sizeof(c), "Float default=%*_f, int(3)=%*_f, int(3)=%*_f, int(3)=%*_f, 6dec=%*_f", &fpi, &f3, &f3, &f31, &fpi);
|
// ext_snprintf_P(c, sizeof(c), "Float default=%*_f, int(3)=%*_f, int(3)=%*_f, int(3)=%*_f, 6dec=%*_f", &fpi, &f3, &f3, &f31, &fpi);
|
||||||
|
|
||||||
|
@ -123,9 +123,7 @@ void TasmotaSerial::end(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TasmotaSerial::~TasmotaSerial(void) {
|
TasmotaSerial::~TasmotaSerial(void) {
|
||||||
if (m_valid) {
|
end();
|
||||||
end();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TasmotaSerial::isValidGPIOpin(int pin) {
|
bool TasmotaSerial::isValidGPIOpin(int pin) {
|
||||||
@ -138,12 +136,7 @@ bool TasmotaSerial::isValidGPIOpin(int pin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TasmotaSerial::setTransmitEnablePin(int tx_enable_pin) {
|
void TasmotaSerial::setTransmitEnablePin(int tx_enable_pin) {
|
||||||
#ifdef ESP8266
|
|
||||||
if ((tx_enable_pin > -1) && (isValidGPIOpin(tx_enable_pin) || (16 == tx_enable_pin))) {
|
|
||||||
#endif
|
|
||||||
#ifdef ESP32
|
|
||||||
if ((tx_enable_pin > -1) && isValidGPIOpin(tx_enable_pin)) {
|
if ((tx_enable_pin > -1) && isValidGPIOpin(tx_enable_pin)) {
|
||||||
#endif
|
|
||||||
m_tx_enable_pin = tx_enable_pin;
|
m_tx_enable_pin = tx_enable_pin;
|
||||||
pinMode(m_tx_enable_pin, OUTPUT);
|
pinMode(m_tx_enable_pin, OUTPUT);
|
||||||
digitalWrite(m_tx_enable_pin, LOW);
|
digitalWrite(m_tx_enable_pin, LOW);
|
||||||
@ -152,9 +145,9 @@ void TasmotaSerial::setTransmitEnablePin(int tx_enable_pin) {
|
|||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
bool TasmotaSerial::freeUart(void) {
|
bool TasmotaSerial::freeUart(void) {
|
||||||
for (uint32_t i = SOC_UART_HP_NUM -1; i >= 0; i--) {
|
for (uint32_t i = SOC_UART_NUM -1; i >= 0; i--) {
|
||||||
if (0 == bitRead(tasmota_serial_uart_bitmap, i)) {
|
if (0 == bitRead(tasmota_serial_uart_bitmap, i)) {
|
||||||
m_uart = uart_port_t(i);
|
m_uart = i;
|
||||||
bitSet(tasmota_serial_uart_bitmap, m_uart);
|
bitSet(tasmota_serial_uart_bitmap, m_uart);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -168,25 +161,15 @@ void TasmotaSerial::Esp32Begin(void) {
|
|||||||
if (m_speed <= 9600) {
|
if (m_speed <= 9600) {
|
||||||
// At 9600, 10 chars are ~10ms
|
// At 9600, 10 chars are ~10ms
|
||||||
uart_set_rx_full_threshold(m_uart, 10);
|
uart_set_rx_full_threshold(m_uart, 10);
|
||||||
} else {
|
|
||||||
// At 19200, 120 chars are ~60ms
|
|
||||||
// At 76800, 120 chars are ~15ms
|
|
||||||
uart_set_rx_full_threshold(m_uart, 120);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
} else if (m_speed < 115200) {
|
} else if (m_speed < 115200) {
|
||||||
// At 19200, 120 chars are ~60ms
|
// At 19200, 120 chars are ~60ms
|
||||||
// At 76800, 120 chars are ~15ms
|
// At 76800, 120 chars are ~15ms
|
||||||
uart_set_rx_full_threshold(m_uart, 120);
|
uart_set_rx_full_threshold(m_uart, 120);
|
||||||
} else if (m_speed == 115200) {
|
} else {
|
||||||
// At 115200, 256 chars are ~20ms
|
// At 115200, 256 chars are ~20ms
|
||||||
// Zigbee requires to keep frames together, i.e. 256 bytes max
|
// Zigbee requires to keep frames together, i.e. 256 bytes max
|
||||||
uart_set_rx_full_threshold(m_uart, 256);
|
uart_set_rx_full_threshold(m_uart, 256);
|
||||||
} else {
|
|
||||||
// At even higher speeds set 75% of the buffer
|
|
||||||
uart_set_rx_full_threshold(m_uart, serial_buffer_size * 3 / 4);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
|
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
|
||||||
if (m_speed < 115200) {
|
if (m_speed < 115200) {
|
||||||
// At 76800 the timeout is ~1ms
|
// At 76800 the timeout is ~1ms
|
||||||
@ -486,42 +469,6 @@ size_t TasmotaSerial::write(uint8_t b) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
// Add ability to change parity on the fly, for RS-485
|
|
||||||
// See https://github.com/arendst/Tasmota/discussions/22272
|
|
||||||
int32_t TasmotaSerial::setConfig(uint32_t config) {
|
|
||||||
|
|
||||||
uint32_t data_bits_before = (m_config & 0xc) >> 2;
|
|
||||||
uint32_t parity_before = m_config & 0x3;
|
|
||||||
uint32_t stop_bits_before = (m_config & 0x30) >> 4;
|
|
||||||
|
|
||||||
uint32_t data_bits = (config & 0xc) >> 2;
|
|
||||||
uint32_t parity = config & 0x3;
|
|
||||||
uint32_t stop_bits = (config & 0x30) >> 4;
|
|
||||||
|
|
||||||
esp_err_t err;
|
|
||||||
|
|
||||||
if (data_bits_before != data_bits) {
|
|
||||||
if (err = uart_set_word_length(m_uart, (uart_word_length_t) data_bits)) {
|
|
||||||
return (int32_t) err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parity_before != parity) {
|
|
||||||
if (err = uart_set_parity(m_uart, (uart_parity_t) parity)) {
|
|
||||||
return (int32_t) err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stop_bits_before != stop_bits) {
|
|
||||||
if (err = uart_set_stop_bits(m_uart, (uart_stop_bits_t) stop_bits)) {
|
|
||||||
return (int32_t) err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_config = config;
|
|
||||||
return 0; // no error
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
void IRAM_ATTR TasmotaSerial::rxRead(void) {
|
void IRAM_ATTR TasmotaSerial::rxRead(void) {
|
||||||
if (!m_nwmode) {
|
if (!m_nwmode) {
|
||||||
|
@ -33,12 +33,6 @@
|
|||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
#include <HardwareSerial.h>
|
#include <HardwareSerial.h>
|
||||||
|
|
||||||
// IDF 5.2 has changed counting UART channels, SOC_UART_NUM includes now LP UARTS too for ESP32-C6 and -P4
|
|
||||||
#ifndef SOC_UART_HP_NUM
|
|
||||||
#define SOC_UART_HP_NUM SOC_UART_NUM // Set new define SOC_UART_HP_NUM in pre IDF 5.2 to SOC_UART_NUM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class TasmotaSerial : public Stream {
|
class TasmotaSerial : public Stream {
|
||||||
@ -72,7 +66,6 @@ class TasmotaSerial : public Stream {
|
|||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
uint32_t getUart(void) const { return m_uart; }
|
uint32_t getUart(void) const { return m_uart; }
|
||||||
HardwareSerial *getesp32hws(void) { return TSerial; }
|
HardwareSerial *getesp32hws(void) { return TSerial; }
|
||||||
int32_t setConfig(uint32_t config);
|
|
||||||
#endif
|
#endif
|
||||||
bool isValid(void) { return m_valid; }
|
bool isValid(void) { return m_valid; }
|
||||||
bool overflow(void);
|
bool overflow(void);
|
||||||
@ -116,7 +109,7 @@ class TasmotaSerial : public Stream {
|
|||||||
uint32_t m_speed;
|
uint32_t m_speed;
|
||||||
uint32_t m_config;
|
uint32_t m_config;
|
||||||
HardwareSerial *TSerial;
|
HardwareSerial *TSerial;
|
||||||
uart_port_t m_uart = uart_port_t(0);
|
int m_uart = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
name=Unishox (De)Compressor
|
name=Unishox Compressor Decompressor highly customized and optimized for ESP8266 and Tasmota
|
||||||
version=1.0
|
version=1.0
|
||||||
author=Arundale Ramanathan, Stephan Hadinger
|
author=Arundale Ramanathan, Stephan Hadinger
|
||||||
maintainer=Arun <arun@siara.cc>, Stephan <stephan.hadinger@gmail.com>
|
maintainer=Arun <arun@siara.cc>, Stephan <stephan.hadinger@gmail.com>
|
||||||
sentence=Unishox compression for Tasmota Rules
|
sentence=Unishox compression for Tasmota Rules
|
||||||
paragraph=It is based on Unishox hybrid encoding technique. This Tasmota version has specific Unicode code removed for size.
|
paragraph=It is based on Unishox hybrid encoding technique. This version has specific Unicode code removed for size.
|
||||||
url=https://github.com/siara-cc/Unishox
|
url=https://github.com/siara-cc/Unishox
|
||||||
architectures=esp8266,esp32
|
architectures=esp8266,esp32
|
@ -59,7 +59,7 @@ typedef enum WiFiPhyMode
|
|||||||
class WiFiHelper {
|
class WiFiHelper {
|
||||||
public:
|
public:
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int ttls_phase2_type=-1, int32_t channel=0, const uint8_t* bssid=0, bool connect=true);
|
static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true);
|
||||||
#endif
|
#endif
|
||||||
static wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
static wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
||||||
static wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
static wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
||||||
@ -83,13 +83,6 @@ public:
|
|||||||
// With ESP32 Core3, the WiFi mac address is not valid until the wifi is actually started
|
// With ESP32 Core3, the WiFi mac address is not valid until the wifi is actually started
|
||||||
// this helper function always provide a valid mac address
|
// this helper function always provide a valid mac address
|
||||||
static String macAddress(void);
|
static String macAddress(void);
|
||||||
|
|
||||||
// Auto-fix zone
|
|
||||||
//
|
|
||||||
// After a reconnect, the zone id may not be valid anymore
|
|
||||||
// In such case we detect any "%st<n>" or "%en<n>" zone identifier
|
|
||||||
// and replace with the current zone id
|
|
||||||
static void IPv6ZoneAutoFix(IPAddress &addr, const char* aHostname);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,21 +27,19 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D
|
|||||||
|
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
ip_addr_t dns_save4[2] = {}; // IPv4 DNS servers
|
ip_addr_t dns_save4[DNS_MAX_SERVERS] = {}; // IPv4 DNS servers
|
||||||
ip_addr_t dns_save6[2] = {}; // IPv6 DNS servers
|
ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers
|
||||||
#endif // USE_IPV6
|
#endif // USE_IPV6
|
||||||
|
|
||||||
#include "tasmota_options.h"
|
#include "tasmota_options.h"
|
||||||
#include "lwip/dns.h"
|
#include "lwip/dns.h"
|
||||||
|
|
||||||
#if CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT
|
wl_status_t WiFiHelper::begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool connect) {
|
||||||
wl_status_t WiFiHelper::begin(const char *wpa2_ssid, wpa2_auth_method_t method, const char *wpa2_identity, const char *wpa2_username, const char *wpa2_password, const char *ca_pem, const char *client_crt, const char *client_key, int ttls_phase2_type, int32_t channel, const uint8_t *bssid, bool connect) {
|
|
||||||
WiFiHelper::scrubDNS();
|
WiFiHelper::scrubDNS();
|
||||||
wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, ttls_phase2_type, channel, bssid, connect);
|
wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, channel, bssid, connect);
|
||||||
WiFiHelper::scrubDNS();
|
WiFiHelper::scrubDNS();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT
|
|
||||||
|
|
||||||
wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) {
|
wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) {
|
||||||
WiFiHelper::scrubDNS();
|
WiFiHelper::scrubDNS();
|
||||||
@ -76,72 +74,48 @@ extern bool WifiHasIPv6(void);
|
|||||||
extern bool EthernetHasIPv6(void);
|
extern bool EthernetHasIPv6(void);
|
||||||
|
|
||||||
void WiFiHelper::scrubDNS(void) {
|
void WiFiHelper::scrubDNS(void) {
|
||||||
// AddLog(LOG_LEVEL_DEBUG, "IP>1: dns_save4 %s %s dns_save6 %s %s",
|
|
||||||
// IPAddress(&dns_save4[0]).toString().c_str(),IPAddress(&dns_save4[1]).toString().c_str(),
|
|
||||||
// IPAddress(&dns_save6[0]).toString().c_str(),IPAddress(&dns_save6[1]).toString().c_str());
|
|
||||||
// String dns_entry0 = IPAddress(dns_getserver(0)).toString();
|
// String dns_entry0 = IPAddress(dns_getserver(0)).toString();
|
||||||
// String dns_entry1 = IPAddress(dns_getserver(1)).toString();
|
// String dns_entry1 = IPAddress(dns_getserver(1)).toString();
|
||||||
|
|
||||||
// scan DNS entries
|
// scan DNS entries
|
||||||
bool has_v4 = WifiHasIPv4() || EthernetHasIPv4();
|
bool has_v4 = WifiHasIPv4() || EthernetHasIPv4();
|
||||||
bool has_v6 = false;
|
bool has_v6 = false;
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
has_v6 = WifiHasIPv6() || EthernetHasIPv6();
|
has_v6 = WifiHasIPv6() || EthernetHasIPv6();
|
||||||
#endif
|
#endif
|
||||||
// AddLog(LOG_LEVEL_DEBUG, "IP>1: DNS: (%s %s) has4/6:%i-%i", dns_entry0.c_str(), dns_entry1.c_str(), has_v4, has_v6);
|
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
// First pass, save values
|
// First pass, save values
|
||||||
for (uint32_t i=0; i<2; i++) {
|
for (uint32_t i=0; i<DNS_MAX_SERVERS; i++) {
|
||||||
|
#ifdef USE_IPV6
|
||||||
const IPAddress ip_dns = IPAddress(dns_getserver(i));
|
const IPAddress ip_dns = IPAddress(dns_getserver(i));
|
||||||
// Step 1. save valid values from DNS
|
// Step 1. save valid values from DNS
|
||||||
if (!ip_addr_isany_val((const ip_addr_t &)ip_dns)) {
|
if (!ip_addr_isany_val((const ip_addr_t &)ip_dns)) {
|
||||||
if (ip_dns.type() == IPv4 && (has_v4 || !has_v6)) {
|
if (ip_dns.type() == IPv4 && has_v4) {
|
||||||
ip_dns.to_ip_addr_t(&dns_save4[i]); // dns entry is populated, save it in v4 slot
|
ip_dns.to_ip_addr_t(&dns_save4[i]);
|
||||||
|
// dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot
|
||||||
} else if (has_v6) {
|
} else if (has_v6) {
|
||||||
ip_dns.to_ip_addr_t(&dns_save6[i]); // dns entry is populated, save it in v6 slot
|
ip_dns.to_ip_addr_t(&dns_save6[i]);
|
||||||
|
// dns_save6[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v6 slot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2. scrub addresses not supported
|
// Step 2. scrub addresses not supported
|
||||||
if (!has_v4 && has_v6) { // v6 only
|
if (!has_v4) { dns_save4[i] = *IP4_ADDR_ANY; }
|
||||||
dns_save4[0] = *IP4_ADDR_ANY;
|
if (!has_v6) { dns_save6[i] = *IP_ADDR_ANY; }
|
||||||
dns_save4[1] = *IP4_ADDR_ANY;
|
|
||||||
}
|
|
||||||
if (!has_v6) {
|
|
||||||
dns_save6[0] = *IP_ADDR_ANY;
|
|
||||||
dns_save6[1] = *IP_ADDR_ANY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3. restore saved value
|
// Step 3. restore saved value
|
||||||
if (has_v4 && has_v6) { // if both IPv4 and IPv6 are active, prefer IPv4 for first and IPv6 for second
|
if (has_v4 && has_v6) { // if both IPv4 and IPv6 are active, prefer IPv4
|
||||||
if (!ip_addr_isany_val(dns_save4[0])) {
|
if (!ip_addr_isany_val(dns_save4[i])) { dns_setserver(i, &dns_save4[i]); }
|
||||||
// First DNS IPv4
|
else { dns_setserver(i, &dns_save6[i]); }
|
||||||
dns_setserver(0, &dns_save4[0]);
|
} else if (has_v4) {
|
||||||
if (!ip_addr_isany_val(dns_save6[0])) {
|
dns_setserver(i, &dns_save4[i]);
|
||||||
dns_setserver(1, &dns_save6[0]); // take first IPv6 as second DNS
|
} else if (has_v6) {
|
||||||
} else {
|
dns_setserver(i, &dns_save6[i]);
|
||||||
dns_setserver(1, &dns_save4[1]); // or revert to second IPv4
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// If no DNS IPv4, use IPv6
|
dns_setserver(i, IP4_ADDR_ANY);
|
||||||
dns_setserver(0, &dns_save6[0]);
|
|
||||||
dns_setserver(1, &dns_save6[1]);
|
|
||||||
}
|
}
|
||||||
} else if (has_v6) { // v6 and no v4
|
|
||||||
dns_setserver(0, &dns_save6[0]);
|
|
||||||
dns_setserver(1, &dns_save6[1]);
|
|
||||||
} else { // no v6, we use v4 even if not connected
|
|
||||||
dns_setserver(0, &dns_save4[0]);
|
|
||||||
dns_setserver(1, &dns_save4[1]);
|
|
||||||
}
|
|
||||||
#endif // USE_IPV6
|
#endif // USE_IPV6
|
||||||
// AddLog(LOG_LEVEL_DEBUG, "IP>2: DNS: from(%s %s) to (%s %s) has4/6:%i-%i", dns_entry0.c_str(), dns_entry1.c_str(), IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString().c_str(), has_v4, has_v6);
|
}
|
||||||
|
// AddLog(LOG_LEVEL_DEBUG, "IP>: DNS: from(%s %s) to (%s %s) has4/6:%i-%i", dns_entry0.c_str(), dns_entry1.c_str(), IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString().c_str(), has_v4, has_v6);
|
||||||
// AddLog(LOG_LEVEL_DEBUG, "IP>2: dns_save4 %s %s dns_save6 %s %s",
|
|
||||||
// IPAddress(&dns_save4[0]).toString().c_str(),IPAddress(&dns_save4[1]).toString().c_str(),
|
|
||||||
// IPAddress(&dns_save6[0]).toString().c_str(),IPAddress(&dns_save6[1]).toString().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,10 +140,6 @@ int WiFiHelper::getPhyMode() {
|
|||||||
WIFI_PHY_MODE_HE20, // PHY mode for Bandwidth HE20 (11ax)
|
WIFI_PHY_MODE_HE20, // PHY mode for Bandwidth HE20 (11ax)
|
||||||
} wifi_phy_mode_t;
|
} wifi_phy_mode_t;
|
||||||
*/
|
*/
|
||||||
#ifndef SOC_WIFI_SUPPORTED
|
|
||||||
// ESP32-P4 does not support PHY modes, return 0
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
int phy_mode = 0; // "low rate|11b|11g|HT20|HT40|HE20"
|
int phy_mode = 0; // "low rate|11b|11g|HT20|HT40|HE20"
|
||||||
wifi_phy_mode_t WiFiMode;
|
wifi_phy_mode_t WiFiMode;
|
||||||
if (esp_wifi_sta_get_negotiated_phymode(&WiFiMode) == ESP_OK) {
|
if (esp_wifi_sta_get_negotiated_phymode(&WiFiMode) == ESP_OK) {
|
||||||
@ -179,13 +149,9 @@ int WiFiHelper::getPhyMode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return phy_mode;
|
return phy_mode;
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiHelper::setPhyMode(WiFiPhyMode_t mode) {
|
bool WiFiHelper::setPhyMode(WiFiPhyMode_t mode) {
|
||||||
# ifndef SOC_WIFI_SUPPORTED
|
|
||||||
return false; // ESP32-P4 does not support PHY modes
|
|
||||||
# else
|
|
||||||
uint8_t protocol_bitmap = WIFI_PROTOCOL_11B; // 1
|
uint8_t protocol_bitmap = WIFI_PROTOCOL_11B; // 1
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
@ -195,7 +161,6 @@ bool WiFiHelper::setPhyMode(WiFiPhyMode_t mode) {
|
|||||||
case 2: protocol_bitmap |= WIFI_PROTOCOL_11G; // 2
|
case 2: protocol_bitmap |= WIFI_PROTOCOL_11G; // 2
|
||||||
}
|
}
|
||||||
return (ESP_OK == esp_wifi_set_protocol(WIFI_IF_STA, protocol_bitmap));
|
return (ESP_OK == esp_wifi_set_protocol(WIFI_IF_STA, protocol_bitmap));
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32P4
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiHelper::setOutputPower(int n) {
|
void WiFiHelper::setOutputPower(int n) {
|
||||||
@ -275,44 +240,6 @@ static void wifi32_dns_found_callback(const char *name, const ip_addr_t *ipaddr,
|
|||||||
// AddLog(LOG_LEVEL_DEBUG, "WIF: dns_found=%s", ipaddr ? IPAddress(*ipaddr).toString().c_str() : "<null>");
|
// AddLog(LOG_LEVEL_DEBUG, "WIF: dns_found=%s", ipaddr ? IPAddress(*ipaddr).toString().c_str() : "<null>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-fix zone
|
|
||||||
//
|
|
||||||
// After a reconnect, the zone id may not be valid anymore
|
|
||||||
// In such case we detect any "%st<n>" or "%en<n>" zone identifier
|
|
||||||
// and replace with the current zone id
|
|
||||||
extern bool WifiGetIPv6LinkLocal(IPAddress *ip);
|
|
||||||
extern bool EthernetGetIPv6LinkLocal(IPAddress *ip);
|
|
||||||
void WiFiHelper::IPv6ZoneAutoFix(IPAddress &addr, const char* aHostname) {
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
if ((addr.type() == IPv6) && (addr.zone() == 0)) {
|
|
||||||
// check if hostname contains '%'
|
|
||||||
const char *zone_identifier = strchr(aHostname, '%');
|
|
||||||
if (zone_identifier != nullptr) {
|
|
||||||
uint8_t zone_id = 0;
|
|
||||||
// check if zone id is valid
|
|
||||||
if (strncmp(zone_identifier, "%st", 3) == 0) {
|
|
||||||
IPAddress wifi_link_local;
|
|
||||||
if (WifiGetIPv6LinkLocal(&wifi_link_local)) {
|
|
||||||
zone_id = wifi_link_local.zone();
|
|
||||||
}
|
|
||||||
} else if (strncmp(zone_identifier, "%en", 3) == 0) {
|
|
||||||
IPAddress eth_link_local;
|
|
||||||
if (EthernetGetIPv6LinkLocal(ð_link_local)) {
|
|
||||||
zone_id = eth_link_local.zone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (zone_id) {
|
|
||||||
// convert to ip_addr_t which is currently the only way to change the zone_id
|
|
||||||
ip_addr_t ip_addr;
|
|
||||||
addr.to_ip_addr_t(&ip_addr);
|
|
||||||
ip_addr.u_addr.ip6.zone = zone_id;
|
|
||||||
addr = IPAddress(&ip_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the given hostname to an IP address.
|
* Resolve the given hostname to an IP address.
|
||||||
* @param aHostname Name to be resolved
|
* @param aHostname Name to be resolved
|
||||||
@ -354,7 +281,6 @@ int WiFiHelper::hostByName(const char* aHostname, IPAddress& aResult, int32_t ti
|
|||||||
if (!ip_addr_isany_val(dns_ipaddr)) {
|
if (!ip_addr_isany_val(dns_ipaddr)) {
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
aResult.from_ip_addr_t(&dns_ipaddr);
|
aResult.from_ip_addr_t(&dns_ipaddr);
|
||||||
WiFiHelper::IPv6ZoneAutoFix(aResult, aHostname);
|
|
||||||
#else // USE_IPV6
|
#else // USE_IPV6
|
||||||
aResult = ip_addr_get_ip4_u32(&dns_ipaddr);
|
aResult = ip_addr_get_ip4_u32(&dns_ipaddr);
|
||||||
#endif // USE_IPV6
|
#endif // USE_IPV6
|
||||||
@ -379,11 +305,8 @@ String WiFiHelper::macAddress(void) {
|
|||||||
#else
|
#else
|
||||||
uint8_t mac[6] = {0,0,0,0,0,0};
|
uint8_t mac[6] = {0,0,0,0,0,0};
|
||||||
char macStr[18] = { 0 };
|
char macStr[18] = { 0 };
|
||||||
#ifdef CONFIG_SOC_HAS_WIFI
|
|
||||||
esp_read_mac(mac, ESP_MAC_WIFI_STA);
|
esp_read_mac(mac, ESP_MAC_WIFI_STA);
|
||||||
#else
|
|
||||||
esp_read_mac(mac, ESP_MAC_BASE);
|
|
||||||
#endif // CONFIG_SOC_HAS_WIFI
|
|
||||||
snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||||
return String(macStr);
|
return String(macStr);
|
||||||
#endif
|
#endif
|
||||||
|
@ -77,6 +77,4 @@ String WiFiHelper::macAddress(void) {
|
|||||||
return WiFi.macAddress();
|
return WiFi.macAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiHelper::IPv6ZoneAutoFix(IPAddress &addr, const char* aHostname) {
|
|
||||||
}
|
|
||||||
#endif // ESP8266
|
#endif // ESP8266
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
/**
|
|
||||||
* Base64 encoding and decoding of strings. Uses '+' for 62, '/' for 63, '=' for padding
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "base64.hpp"
|
|
||||||
|
|
||||||
unsigned char binary_to_base64(unsigned char v) {
|
|
||||||
// Capital letters - 'A' is ascii 65 and base64 0
|
|
||||||
if(v < 26) return v + 'A';
|
|
||||||
|
|
||||||
// Lowercase letters - 'a' is ascii 97 and base64 26
|
|
||||||
if(v < 52) return v + 71;
|
|
||||||
|
|
||||||
// Digits - '0' is ascii 48 and base64 52
|
|
||||||
if(v < 62) return v - 4;
|
|
||||||
|
|
||||||
// '+' is ascii 43 and base64 62
|
|
||||||
if(v == 62) return '+';
|
|
||||||
|
|
||||||
// '/' is ascii 47 and base64 63
|
|
||||||
if(v == 63) return '/';
|
|
||||||
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char base64_to_binary(unsigned char c) {
|
|
||||||
// Capital letters - 'A' is ascii 65 and base64 0
|
|
||||||
if('A' <= c && c <= 'Z') return c - 'A';
|
|
||||||
|
|
||||||
// Lowercase letters - 'a' is ascii 97 and base64 26
|
|
||||||
if('a' <= c && c <= 'z') return c - 71;
|
|
||||||
|
|
||||||
// Digits - '0' is ascii 48 and base64 52
|
|
||||||
if('0' <= c && c <= '9') return c + 4;
|
|
||||||
|
|
||||||
// '+' is ascii 43 and base64 62
|
|
||||||
if(c == '+') return 62;
|
|
||||||
|
|
||||||
// '/' is ascii 47 and base64 63
|
|
||||||
if(c == '/') return 63;
|
|
||||||
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int encode_base64_length(unsigned int input_length) {
|
|
||||||
return (input_length + 2)/3*4;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int decode_base64_length(unsigned char input[]) {
|
|
||||||
unsigned char *start = input;
|
|
||||||
|
|
||||||
while(base64_to_binary(input[0]) < 64) {
|
|
||||||
++input;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int input_length = input - start;
|
|
||||||
|
|
||||||
unsigned int output_length = input_length/4*3;
|
|
||||||
|
|
||||||
switch(input_length % 4) {
|
|
||||||
default: return output_length;
|
|
||||||
case 2: return output_length + 1;
|
|
||||||
case 3: return output_length + 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[]) {
|
|
||||||
unsigned int full_sets = input_length/3;
|
|
||||||
|
|
||||||
// While there are still full sets of 24 bits...
|
|
||||||
for(unsigned int i = 0; i < full_sets; ++i) {
|
|
||||||
output[0] = binary_to_base64( input[0] >> 2);
|
|
||||||
output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
|
|
||||||
output[2] = binary_to_base64((input[1] & 0x0F) << 2 | input[2] >> 6);
|
|
||||||
output[3] = binary_to_base64( input[2] & 0x3F);
|
|
||||||
|
|
||||||
input += 3;
|
|
||||||
output += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(input_length % 3) {
|
|
||||||
case 0:
|
|
||||||
output[0] = '\0';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
output[0] = binary_to_base64( input[0] >> 2);
|
|
||||||
output[1] = binary_to_base64((input[0] & 0x03) << 4);
|
|
||||||
output[2] = '=';
|
|
||||||
output[3] = '=';
|
|
||||||
output[4] = '\0';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
output[0] = binary_to_base64( input[0] >> 2);
|
|
||||||
output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
|
|
||||||
output[2] = binary_to_base64((input[1] & 0x0F) << 2);
|
|
||||||
output[3] = '=';
|
|
||||||
output[4] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return encode_base64_length(input_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int decode_base64(unsigned char input[], unsigned char output[]) {
|
|
||||||
unsigned int output_length = decode_base64_length(input);
|
|
||||||
|
|
||||||
// While there are still full sets of 24 bits...
|
|
||||||
for(unsigned int i = 2; i < output_length; i += 3) {
|
|
||||||
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
|
|
||||||
output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
|
|
||||||
output[2] = base64_to_binary(input[2]) << 6 | base64_to_binary(input[3]);
|
|
||||||
|
|
||||||
input += 4;
|
|
||||||
output += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(output_length % 3) {
|
|
||||||
case 1:
|
|
||||||
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
|
|
||||||
output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output_length;
|
|
||||||
}
|
|
@ -69,4 +69,127 @@ unsigned int encode_base64(unsigned char input[], unsigned int input_length, uns
|
|||||||
*/
|
*/
|
||||||
unsigned int decode_base64(unsigned char input[], unsigned char output[]);
|
unsigned int decode_base64(unsigned char input[], unsigned char output[]);
|
||||||
|
|
||||||
|
unsigned char binary_to_base64(unsigned char v) {
|
||||||
|
// Capital letters - 'A' is ascii 65 and base64 0
|
||||||
|
if(v < 26) return v + 'A';
|
||||||
|
|
||||||
|
// Lowercase letters - 'a' is ascii 97 and base64 26
|
||||||
|
if(v < 52) return v + 71;
|
||||||
|
|
||||||
|
// Digits - '0' is ascii 48 and base64 52
|
||||||
|
if(v < 62) return v - 4;
|
||||||
|
|
||||||
|
// '+' is ascii 43 and base64 62
|
||||||
|
if(v == 62) return '+';
|
||||||
|
|
||||||
|
// '/' is ascii 47 and base64 63
|
||||||
|
if(v == 63) return '/';
|
||||||
|
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char base64_to_binary(unsigned char c) {
|
||||||
|
// Capital letters - 'A' is ascii 65 and base64 0
|
||||||
|
if('A' <= c && c <= 'Z') return c - 'A';
|
||||||
|
|
||||||
|
// Lowercase letters - 'a' is ascii 97 and base64 26
|
||||||
|
if('a' <= c && c <= 'z') return c - 71;
|
||||||
|
|
||||||
|
// Digits - '0' is ascii 48 and base64 52
|
||||||
|
if('0' <= c && c <= '9') return c + 4;
|
||||||
|
|
||||||
|
// '+' is ascii 43 and base64 62
|
||||||
|
if(c == '+') return 62;
|
||||||
|
|
||||||
|
// '/' is ascii 47 and base64 63
|
||||||
|
if(c == '/') return 63;
|
||||||
|
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int encode_base64_length(unsigned int input_length) {
|
||||||
|
return (input_length + 2)/3*4;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int decode_base64_length(unsigned char input[]) {
|
||||||
|
unsigned char *start = input;
|
||||||
|
|
||||||
|
while(base64_to_binary(input[0]) < 64) {
|
||||||
|
++input;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int input_length = input - start;
|
||||||
|
|
||||||
|
unsigned int output_length = input_length/4*3;
|
||||||
|
|
||||||
|
switch(input_length % 4) {
|
||||||
|
default: return output_length;
|
||||||
|
case 2: return output_length + 1;
|
||||||
|
case 3: return output_length + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int encode_base64(unsigned char input[], unsigned int input_length, unsigned char output[]) {
|
||||||
|
unsigned int full_sets = input_length/3;
|
||||||
|
|
||||||
|
// While there are still full sets of 24 bits...
|
||||||
|
for(unsigned int i = 0; i < full_sets; ++i) {
|
||||||
|
output[0] = binary_to_base64( input[0] >> 2);
|
||||||
|
output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
|
||||||
|
output[2] = binary_to_base64((input[1] & 0x0F) << 2 | input[2] >> 6);
|
||||||
|
output[3] = binary_to_base64( input[2] & 0x3F);
|
||||||
|
|
||||||
|
input += 3;
|
||||||
|
output += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(input_length % 3) {
|
||||||
|
case 0:
|
||||||
|
output[0] = '\0';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
output[0] = binary_to_base64( input[0] >> 2);
|
||||||
|
output[1] = binary_to_base64((input[0] & 0x03) << 4);
|
||||||
|
output[2] = '=';
|
||||||
|
output[3] = '=';
|
||||||
|
output[4] = '\0';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
output[0] = binary_to_base64( input[0] >> 2);
|
||||||
|
output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
|
||||||
|
output[2] = binary_to_base64((input[1] & 0x0F) << 2);
|
||||||
|
output[3] = '=';
|
||||||
|
output[4] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encode_base64_length(input_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int decode_base64(unsigned char input[], unsigned char output[]) {
|
||||||
|
unsigned int output_length = decode_base64_length(input);
|
||||||
|
|
||||||
|
// While there are still full sets of 24 bits...
|
||||||
|
for(unsigned int i = 2; i < output_length; i += 3) {
|
||||||
|
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
|
||||||
|
output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
|
||||||
|
output[2] = base64_to_binary(input[2]) << 6 | base64_to_binary(input[3]);
|
||||||
|
|
||||||
|
input += 4;
|
||||||
|
output += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(output_length % 3) {
|
||||||
|
case 1:
|
||||||
|
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
|
||||||
|
output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_length;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ifndef
|
#endif // ifndef
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||||
#define PWDN_GPIO_NUM -1
|
#define PWDN_GPIO_NUM -1
|
||||||
#define RESET_GPIO_NUM -1
|
#define RESET_GPIO_NUM -1
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#define Y4_GPIO_NUM 18
|
#define Y4_GPIO_NUM 18
|
||||||
#define Y3_GPIO_NUM 5
|
#define Y3_GPIO_NUM 5
|
||||||
#define Y2_GPIO_NUM 4
|
#define Y2_GPIO_NUM 4
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 25
|
#define VSYNC_GPIO_NUM 25
|
||||||
#define HREF_GPIO_NUM 23
|
#define HREF_GPIO_NUM 23
|
||||||
#define PCLK_GPIO_NUM 22
|
#define PCLK_GPIO_NUM 22
|
||||||
@ -33,12 +33,12 @@
|
|||||||
#define Y4_GPIO_NUM 14
|
#define Y4_GPIO_NUM 14
|
||||||
#define Y3_GPIO_NUM 13
|
#define Y3_GPIO_NUM 13
|
||||||
#define Y2_GPIO_NUM 34
|
#define Y2_GPIO_NUM 34
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 5
|
#define VSYNC_GPIO_NUM 5
|
||||||
#define HREF_GPIO_NUM 27
|
#define HREF_GPIO_NUM 27
|
||||||
#define PCLK_GPIO_NUM 25
|
#define PCLK_GPIO_NUM 25
|
||||||
|
|
||||||
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||||
|
|
||||||
#define PWDN_GPIO_NUM -1
|
#define PWDN_GPIO_NUM -1
|
||||||
#define RESET_GPIO_NUM -1
|
#define RESET_GPIO_NUM -1
|
||||||
#define XCLK_GPIO_NUM 15
|
#define XCLK_GPIO_NUM 15
|
||||||
@ -73,7 +73,6 @@
|
|||||||
#define Y4_GPIO_NUM 34
|
#define Y4_GPIO_NUM 34
|
||||||
#define Y3_GPIO_NUM 35
|
#define Y3_GPIO_NUM 35
|
||||||
#define Y2_GPIO_NUM 32
|
#define Y2_GPIO_NUM 32
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 22
|
#define VSYNC_GPIO_NUM 22
|
||||||
#define HREF_GPIO_NUM 26
|
#define HREF_GPIO_NUM 26
|
||||||
#define PCLK_GPIO_NUM 21
|
#define PCLK_GPIO_NUM 21
|
||||||
@ -93,7 +92,6 @@
|
|||||||
#define Y4_GPIO_NUM 34
|
#define Y4_GPIO_NUM 34
|
||||||
#define Y3_GPIO_NUM 35
|
#define Y3_GPIO_NUM 35
|
||||||
#define Y2_GPIO_NUM 32
|
#define Y2_GPIO_NUM 32
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 25
|
#define VSYNC_GPIO_NUM 25
|
||||||
#define HREF_GPIO_NUM 26
|
#define HREF_GPIO_NUM 26
|
||||||
#define PCLK_GPIO_NUM 21
|
#define PCLK_GPIO_NUM 21
|
||||||
@ -113,7 +111,6 @@
|
|||||||
#define Y4_GPIO_NUM 34
|
#define Y4_GPIO_NUM 34
|
||||||
#define Y3_GPIO_NUM 35
|
#define Y3_GPIO_NUM 35
|
||||||
#define Y2_GPIO_NUM 32
|
#define Y2_GPIO_NUM 32
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 25
|
#define VSYNC_GPIO_NUM 25
|
||||||
#define HREF_GPIO_NUM 26
|
#define HREF_GPIO_NUM 26
|
||||||
#define PCLK_GPIO_NUM 21
|
#define PCLK_GPIO_NUM 21
|
||||||
@ -133,7 +130,6 @@
|
|||||||
#define Y4_GPIO_NUM 34
|
#define Y4_GPIO_NUM 34
|
||||||
#define Y3_GPIO_NUM 35
|
#define Y3_GPIO_NUM 35
|
||||||
#define Y2_GPIO_NUM 17
|
#define Y2_GPIO_NUM 17
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 22
|
#define VSYNC_GPIO_NUM 22
|
||||||
#define HREF_GPIO_NUM 26
|
#define HREF_GPIO_NUM 26
|
||||||
#define PCLK_GPIO_NUM 21
|
#define PCLK_GPIO_NUM 21
|
||||||
@ -153,7 +149,6 @@
|
|||||||
#define Y4_GPIO_NUM 34
|
#define Y4_GPIO_NUM 34
|
||||||
#define Y3_GPIO_NUM 35
|
#define Y3_GPIO_NUM 35
|
||||||
#define Y2_GPIO_NUM 32
|
#define Y2_GPIO_NUM 32
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 22
|
#define VSYNC_GPIO_NUM 22
|
||||||
#define HREF_GPIO_NUM 26
|
#define HREF_GPIO_NUM 26
|
||||||
#define PCLK_GPIO_NUM 21
|
#define PCLK_GPIO_NUM 21
|
||||||
@ -173,7 +168,6 @@
|
|||||||
#define Y4_GPIO_NUM 19
|
#define Y4_GPIO_NUM 19
|
||||||
#define Y3_GPIO_NUM 18
|
#define Y3_GPIO_NUM 18
|
||||||
#define Y2_GPIO_NUM 5
|
#define Y2_GPIO_NUM 5
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 25
|
#define VSYNC_GPIO_NUM 25
|
||||||
#define HREF_GPIO_NUM 23
|
#define HREF_GPIO_NUM 23
|
||||||
#define PCLK_GPIO_NUM 22
|
#define PCLK_GPIO_NUM 22
|
||||||
@ -193,7 +187,6 @@
|
|||||||
#define Y4_GPIO_NUM 4
|
#define Y4_GPIO_NUM 4
|
||||||
#define Y3_GPIO_NUM 14
|
#define Y3_GPIO_NUM 14
|
||||||
#define Y2_GPIO_NUM 5
|
#define Y2_GPIO_NUM 5
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 27
|
#define VSYNC_GPIO_NUM 27
|
||||||
#define HREF_GPIO_NUM 25
|
#define HREF_GPIO_NUM 25
|
||||||
#define PCLK_GPIO_NUM 19
|
#define PCLK_GPIO_NUM 19
|
||||||
@ -213,7 +206,6 @@
|
|||||||
#define Y4_GPIO_NUM 14
|
#define Y4_GPIO_NUM 14
|
||||||
#define Y3_GPIO_NUM 13
|
#define Y3_GPIO_NUM 13
|
||||||
#define Y2_GPIO_NUM 34
|
#define Y2_GPIO_NUM 34
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 5
|
#define VSYNC_GPIO_NUM 5
|
||||||
#define HREF_GPIO_NUM 27
|
#define HREF_GPIO_NUM 27
|
||||||
#define PCLK_GPIO_NUM 25
|
#define PCLK_GPIO_NUM 25
|
||||||
@ -233,7 +225,6 @@
|
|||||||
#define Y4_GPIO_NUM 14
|
#define Y4_GPIO_NUM 14
|
||||||
#define Y3_GPIO_NUM 13
|
#define Y3_GPIO_NUM 13
|
||||||
#define Y2_GPIO_NUM 34
|
#define Y2_GPIO_NUM 34
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 5
|
#define VSYNC_GPIO_NUM 5
|
||||||
#define HREF_GPIO_NUM 27
|
#define HREF_GPIO_NUM 27
|
||||||
#define PCLK_GPIO_NUM 25
|
#define PCLK_GPIO_NUM 25
|
||||||
@ -253,7 +244,6 @@
|
|||||||
#define Y4_GPIO_NUM 4
|
#define Y4_GPIO_NUM 4
|
||||||
#define Y3_GPIO_NUM 14
|
#define Y3_GPIO_NUM 14
|
||||||
#define Y2_GPIO_NUM 5
|
#define Y2_GPIO_NUM 5
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 27
|
#define VSYNC_GPIO_NUM 27
|
||||||
#define HREF_GPIO_NUM 25
|
#define HREF_GPIO_NUM 25
|
||||||
#define PCLK_GPIO_NUM 19
|
#define PCLK_GPIO_NUM 19
|
||||||
@ -273,7 +263,6 @@
|
|||||||
#define Y4_GPIO_NUM 4
|
#define Y4_GPIO_NUM 4
|
||||||
#define Y3_GPIO_NUM 14
|
#define Y3_GPIO_NUM 14
|
||||||
#define Y2_GPIO_NUM 5
|
#define Y2_GPIO_NUM 5
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 27
|
#define VSYNC_GPIO_NUM 27
|
||||||
#define HREF_GPIO_NUM 25
|
#define HREF_GPIO_NUM 25
|
||||||
#define PCLK_GPIO_NUM 19
|
#define PCLK_GPIO_NUM 19
|
||||||
@ -293,7 +282,6 @@
|
|||||||
#define Y4_GPIO_NUM 26
|
#define Y4_GPIO_NUM 26
|
||||||
#define Y3_GPIO_NUM 13
|
#define Y3_GPIO_NUM 13
|
||||||
#define Y2_GPIO_NUM 34
|
#define Y2_GPIO_NUM 34
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 5
|
#define VSYNC_GPIO_NUM 5
|
||||||
#define HREF_GPIO_NUM 27
|
#define HREF_GPIO_NUM 27
|
||||||
#define PCLK_GPIO_NUM 25
|
#define PCLK_GPIO_NUM 25
|
||||||
@ -314,12 +302,12 @@
|
|||||||
#define Y4_GPIO_NUM 8
|
#define Y4_GPIO_NUM 8
|
||||||
#define Y3_GPIO_NUM 9
|
#define Y3_GPIO_NUM 9
|
||||||
#define Y2_GPIO_NUM 11
|
#define Y2_GPIO_NUM 11
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 6
|
#define VSYNC_GPIO_NUM 6
|
||||||
#define HREF_GPIO_NUM 7
|
#define HREF_GPIO_NUM 7
|
||||||
#define PCLK_GPIO_NUM 13
|
#define PCLK_GPIO_NUM 13
|
||||||
|
|
||||||
#elif defined(CAMERA_MODEL_TTGO_T_CAM_SIM)
|
#elif defined(CAMERA_MODEL_TTGO_T_CAM_SIM)
|
||||||
|
|
||||||
#define PWDN_GPIO_NUM -1
|
#define PWDN_GPIO_NUM -1
|
||||||
#define RESET_GPIO_NUM 18
|
#define RESET_GPIO_NUM 18
|
||||||
#define XCLK_GPIO_NUM 14
|
#define XCLK_GPIO_NUM 14
|
||||||
@ -334,7 +322,6 @@
|
|||||||
#define Y4_GPIO_NUM 8
|
#define Y4_GPIO_NUM 8
|
||||||
#define Y3_GPIO_NUM 9
|
#define Y3_GPIO_NUM 9
|
||||||
#define Y2_GPIO_NUM 11
|
#define Y2_GPIO_NUM 11
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 6
|
#define VSYNC_GPIO_NUM 6
|
||||||
#define HREF_GPIO_NUM 7
|
#define HREF_GPIO_NUM 7
|
||||||
#define PCLK_GPIO_NUM 13
|
#define PCLK_GPIO_NUM 13
|
||||||
@ -345,27 +332,6 @@
|
|||||||
#define PCIE_TX_PIN 45
|
#define PCIE_TX_PIN 45
|
||||||
#define PCIE_RX_PIN 46
|
#define PCIE_RX_PIN 46
|
||||||
#define PCIE_LED_PIN 21
|
#define PCIE_LED_PIN 21
|
||||||
|
|
||||||
#elif defined(CAMERA_MODEL_XIAO_ESP32S3_SENSE)
|
|
||||||
#define PWDN_GPIO_NUM -1
|
|
||||||
#define RESET_GPIO_NUM -1
|
|
||||||
#define XCLK_GPIO_NUM 10
|
|
||||||
#define SIOD_GPIO_NUM 40
|
|
||||||
#define SIOC_GPIO_NUM 39
|
|
||||||
|
|
||||||
#define Y9_GPIO_NUM 48
|
|
||||||
#define Y8_GPIO_NUM 11
|
|
||||||
#define Y7_GPIO_NUM 12
|
|
||||||
#define Y6_GPIO_NUM 14
|
|
||||||
#define Y5_GPIO_NUM 16
|
|
||||||
#define Y4_GPIO_NUM 18
|
|
||||||
#define Y3_GPIO_NUM 17
|
|
||||||
#define Y2_GPIO_NUM 15
|
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM 38
|
|
||||||
#define HREF_GPIO_NUM 47
|
|
||||||
#define PCLK_GPIO_NUM 13
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define PWDN_GPIO_NUM -1
|
#define PWDN_GPIO_NUM -1
|
||||||
#define RESET_GPIO_NUM -1
|
#define RESET_GPIO_NUM -1
|
||||||
@ -381,7 +347,6 @@
|
|||||||
#define Y4_GPIO_NUM -1
|
#define Y4_GPIO_NUM -1
|
||||||
#define Y3_GPIO_NUM -1
|
#define Y3_GPIO_NUM -1
|
||||||
#define Y2_GPIO_NUM -1
|
#define Y2_GPIO_NUM -1
|
||||||
|
|
||||||
#define VSYNC_GPIO_NUM -1
|
#define VSYNC_GPIO_NUM -1
|
||||||
#define HREF_GPIO_NUM -1
|
#define HREF_GPIO_NUM -1
|
||||||
#define PCLK_GPIO_NUM -1
|
#define PCLK_GPIO_NUM -1
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
// #define strcmp_P(x, y) strcmp(x,y)
|
||||||
|
// #define strcasecmp_P(x,y) strcasecmp(x,y)
|
||||||
|
// #define pgm_read_byte(x) (*(uint8_t*)(x))
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,15 +45,17 @@ bool AudioFileSourceICYStream::open(const char *url)
|
|||||||
{
|
{
|
||||||
static const char *hdr[] = { "icy-metaint", "icy-name", "icy-genre", "icy-br" };
|
static const char *hdr[] = { "icy-metaint", "icy-name", "icy-genre", "icy-br" };
|
||||||
pos = 0;
|
pos = 0;
|
||||||
if (!http.begin(client, url)) {
|
http.begin(client, url);
|
||||||
cb.st(STATUS_HTTPFAIL, PSTR("Can't connect to url"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
http.addHeader("Icy-MetaData", "1");
|
http.addHeader("Icy-MetaData", "1");
|
||||||
http.collectHeaders( hdr, 4 );
|
http.collectHeaders( hdr, 4 );
|
||||||
http.setReuse(true);
|
http.setReuse(true);
|
||||||
http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
|
http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
|
||||||
int code = http.GET();
|
int code = http.GET();
|
||||||
|
if (code != HTTP_CODE_OK) {
|
||||||
|
http.end();
|
||||||
|
cb.st(STATUS_HTTPFAIL, PSTR("Can't open HTTP request"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (http.hasHeader(hdr[0])) {
|
if (http.hasHeader(hdr[0])) {
|
||||||
String ret = http.header(hdr[0]);
|
String ret = http.header(hdr[0]);
|
||||||
icyMetaInt = ret.toInt();
|
icyMetaInt = ret.toInt();
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma GCC optimize ("Os")
|
#pragma GCC optimize ("O3")
|
||||||
|
|
||||||
#include "AudioGeneratorAAC.h"
|
#include "AudioGeneratorAAC.h"
|
||||||
|
|
||||||
|
@ -58,10 +58,6 @@
|
|||||||
|
|
||||||
#include "AudioGeneratorMIDI.h"
|
#include "AudioGeneratorMIDI.h"
|
||||||
|
|
||||||
#if defined(ESP32)
|
|
||||||
// Do not build, Espressif's GCC8+ has a compiler bug
|
|
||||||
#else // __GNUC__ == 8
|
|
||||||
|
|
||||||
#pragma GCC optimize ("O3")
|
#pragma GCC optimize ("O3")
|
||||||
|
|
||||||
#define TSF_NO_STDIO
|
#define TSF_NO_STDIO
|
||||||
@ -641,4 +637,3 @@ void AudioGeneratorMIDI::MakeStreamFromAFS(AudioFileSource *src, tsf_stream *afs
|
|||||||
afs->size = &afs_size;
|
afs->size = &afs_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //__GNUC__ == 8
|
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#ifndef _AUDIOGENERATORMIDI_H
|
#ifndef _AUDIOGENERATORMIDI_H
|
||||||
#define _AUDIOGENERATORMIDI_H
|
#define _AUDIOGENERATORMIDI_H
|
||||||
|
|
||||||
#if defined(ESP32)
|
|
||||||
// Do not build, Espressif's GCC8+ has a compiler bug
|
|
||||||
#else // __GNUC__ == 8
|
|
||||||
|
|
||||||
#include "AudioGenerator.h"
|
#include "AudioGenerator.h"
|
||||||
|
|
||||||
#define TSF_NO_STDIO
|
#define TSF_NO_STDIO
|
||||||
@ -94,7 +90,7 @@ class AudioGeneratorMIDI : public AudioGenerator
|
|||||||
unsigned long earliest_time = 0;
|
unsigned long earliest_time = 0;
|
||||||
|
|
||||||
struct tonegen_status { /* current status of a tone generator */
|
struct tonegen_status { /* current status of a tone generator */
|
||||||
bool playing; /* is it playing? */
|
bool playing; /* is it playing? */
|
||||||
char track; /* if so, which track is the note from? */
|
char track; /* if so, which track is the note from? */
|
||||||
char note; /* what note is playing? */
|
char note; /* what note is playing? */
|
||||||
char instrument; /* what instrument? */
|
char instrument; /* what instrument? */
|
||||||
@ -180,7 +176,6 @@ class AudioGeneratorMIDI : public AudioGenerator
|
|||||||
short samplesRendered[256];
|
short samplesRendered[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__GNUC__ == 8
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -186,9 +186,7 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2])
|
|||||||
// If we're here, we have one decoded frame and sent 0 or more samples out
|
// If we're here, we have one decoded frame and sent 0 or more samples out
|
||||||
if (samplePtr < synth->pcm.length) {
|
if (samplePtr < synth->pcm.length) {
|
||||||
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
|
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
|
||||||
if(lastChannels == 2) {
|
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
|
||||||
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
|
|
||||||
}
|
|
||||||
samplePtr++;
|
samplePtr++;
|
||||||
} else {
|
} else {
|
||||||
samplePtr = 0;
|
samplePtr = 0;
|
||||||
@ -202,9 +200,7 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2])
|
|||||||
}
|
}
|
||||||
// for IGNORE and CONTINUE, just play what we have now
|
// for IGNORE and CONTINUE, just play what we have now
|
||||||
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
|
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
|
||||||
if(lastChannels == 2) {
|
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
|
||||||
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
|
|
||||||
}
|
|
||||||
samplePtr++;
|
samplePtr++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -190,7 +190,7 @@ bool AudioOutputMixer::loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (avail) {
|
if (avail) {
|
||||||
int16_t s[2] = {0};
|
int16_t s[2];
|
||||||
if (leftAccum[readPtr] > 32767) {
|
if (leftAccum[readPtr] > 32767) {
|
||||||
s[LEFTCHANNEL] = 32767;
|
s[LEFTCHANNEL] = 32767;
|
||||||
} else if (leftAccum[readPtr] < -32767) {
|
} else if (leftAccum[readPtr] < -32767) {
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
#define AAC_ENABLE_SBR 1
|
#define AAC_ENABLE_SBR 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma GCC optimize ("Os")
|
#pragma GCC optimize ("O3")
|
||||||
|
|
||||||
#include "aacdec.h"
|
#include "aacdec.h"
|
||||||
#include "statname.h"
|
#include "statname.h"
|
||||||
|
@ -482,7 +482,7 @@ static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
|
|||||||
int pitch_index;
|
int pitch_index;
|
||||||
VARDECL( opus_val16, lp_pitch_buf );
|
VARDECL( opus_val16, lp_pitch_buf );
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
|
opus_val16 *lp_pitch_buf = (opus_val16*)malloc((DECODE_BUFFER_SIZE>>1) * sizeof(opus_val16)); //ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
|
||||||
pitch_downsample(decode_mem, lp_pitch_buf,
|
pitch_downsample(decode_mem, lp_pitch_buf,
|
||||||
DECODE_BUFFER_SIZE, C, arch);
|
DECODE_BUFFER_SIZE, C, arch);
|
||||||
pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
|
pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
|
||||||
@ -490,6 +490,7 @@ static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
|
|||||||
PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch);
|
PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch);
|
||||||
pitch_index = PLC_PITCH_LAG_MAX-pitch_index;
|
pitch_index = PLC_PITCH_LAG_MAX-pitch_index;
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
|
free(lp_pitch_buf);
|
||||||
return pitch_index;
|
return pitch_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,3 +207,4 @@
|
|||||||
# define __restrict__
|
# define __restrict__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
@ -171,7 +171,7 @@ extern "C" {
|
|||||||
#define OPUS_GET_IN_DTX_REQUEST 4049
|
#define OPUS_GET_IN_DTX_REQUEST 4049
|
||||||
|
|
||||||
/** Defines for the presence of extended APIs. */
|
/** Defines for the presence of extended APIs. */
|
||||||
// #define OPUS_HAVE_OPUS_PROJECTION_H
|
#define OPUS_HAVE_OPUS_PROJECTION_H
|
||||||
|
|
||||||
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
|
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
|
||||||
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
||||||
|
@ -239,21 +239,30 @@ opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus
|
|||||||
|
|
||||||
int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
|
int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
|
||||||
{
|
{
|
||||||
OpusRepacketizer rp;
|
OpusRepacketizer *rp = (OpusRepacketizer*)malloc(sizeof(OpusRepacketizer));
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
if (len < 1)
|
if (len < 1) {
|
||||||
|
free(rp);
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
if (len==new_len)
|
}
|
||||||
|
if (len==new_len) {
|
||||||
|
free(rp);
|
||||||
return OPUS_OK;
|
return OPUS_OK;
|
||||||
else if (len > new_len)
|
}
|
||||||
|
else if (len > new_len) {
|
||||||
|
free(rp);
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
opus_repacketizer_init(&rp);
|
}
|
||||||
|
opus_repacketizer_init(rp);
|
||||||
/* Moving payload to the end of the packet so we can do in-place padding */
|
/* Moving payload to the end of the packet so we can do in-place padding */
|
||||||
OPUS_MOVE(data+new_len-len, data, len);
|
OPUS_MOVE(data+new_len-len, data, len);
|
||||||
ret = opus_repacketizer_cat(&rp, data+new_len-len, len);
|
ret = opus_repacketizer_cat(rp, data+new_len-len, len);
|
||||||
if (ret != OPUS_OK)
|
if (ret != OPUS_OK) {
|
||||||
|
free(rp);
|
||||||
return ret;
|
return ret;
|
||||||
ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1);
|
}
|
||||||
|
ret = opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, new_len, 0, 1);
|
||||||
|
free(rp);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
return OPUS_OK;
|
return OPUS_OK;
|
||||||
else
|
else
|
||||||
@ -262,15 +271,20 @@ int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
|
|||||||
|
|
||||||
opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)
|
opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)
|
||||||
{
|
{
|
||||||
OpusRepacketizer rp;
|
OpusRepacketizer *rp = (OpusRepacketizer*)malloc(sizeof(OpusRepacketizer));
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
if (len < 1)
|
if (len < 1) {
|
||||||
|
free(rp);
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
opus_repacketizer_init(&rp);
|
}
|
||||||
ret = opus_repacketizer_cat(&rp, data, len);
|
opus_repacketizer_init(rp);
|
||||||
if (ret < 0)
|
ret = opus_repacketizer_cat(rp, data, len);
|
||||||
|
if (ret < 0) {
|
||||||
|
free(rp);
|
||||||
return ret;
|
return ret;
|
||||||
ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0);
|
}
|
||||||
|
ret = opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, len, 0, 0);
|
||||||
|
free(rp);
|
||||||
celt_assert(ret > 0 && ret <= len);
|
celt_assert(ret > 0 && ret <= len);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -312,12 +326,14 @@ opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, in
|
|||||||
unsigned char toc;
|
unsigned char toc;
|
||||||
opus_int16 size[48];
|
opus_int16 size[48];
|
||||||
opus_int32 packet_offset;
|
opus_int32 packet_offset;
|
||||||
OpusRepacketizer rp;
|
OpusRepacketizer *rp = (OpusRepacketizer*)malloc(sizeof(OpusRepacketizer));
|
||||||
unsigned char *dst;
|
unsigned char *dst;
|
||||||
opus_int32 dst_len;
|
opus_int32 dst_len;
|
||||||
|
|
||||||
if (len < 1)
|
if (len < 1){
|
||||||
|
free(rp);
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
|
}
|
||||||
dst = data;
|
dst = data;
|
||||||
dst_len = 0;
|
dst_len = 0;
|
||||||
/* Unpad all frames */
|
/* Unpad all frames */
|
||||||
@ -325,25 +341,34 @@ opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, in
|
|||||||
{
|
{
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
int self_delimited = s!=nb_streams-1;
|
int self_delimited = s!=nb_streams-1;
|
||||||
if (len<=0)
|
if (len<=0) {
|
||||||
|
free(rp);
|
||||||
return OPUS_INVALID_PACKET;
|
return OPUS_INVALID_PACKET;
|
||||||
opus_repacketizer_init(&rp);
|
}
|
||||||
|
opus_repacketizer_init(rp);
|
||||||
ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
|
ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
|
||||||
size, NULL, &packet_offset);
|
size, NULL, &packet_offset);
|
||||||
if (ret<0)
|
if (ret<0) {
|
||||||
|
free(rp);
|
||||||
return ret;
|
return ret;
|
||||||
ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited);
|
}
|
||||||
if (ret < 0)
|
ret = opus_repacketizer_cat_impl(rp, data, packet_offset, self_delimited);
|
||||||
|
if (ret < 0) {
|
||||||
|
free(rp);
|
||||||
return ret;
|
return ret;
|
||||||
ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0);
|
}
|
||||||
if (ret < 0)
|
ret = opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, dst, len, self_delimited, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
free(rp);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
dst_len += ret;
|
dst_len += ret;
|
||||||
dst += ret;
|
dst += ret;
|
||||||
data += packet_offset;
|
data += packet_offset;
|
||||||
len -= packet_offset;
|
len -= packet_offset;
|
||||||
}
|
}
|
||||||
|
free(rp);
|
||||||
return dst_len;
|
return dst_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +80,11 @@ void silk_NLSF2A(
|
|||||||
};
|
};
|
||||||
const unsigned char *ordering;
|
const unsigned char *ordering;
|
||||||
opus_int k, i, dd;
|
opus_int k, i, dd;
|
||||||
opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ];
|
opus_int32 *cos_LSF_QA = (opus_int32*)malloc(sizeof(opus_int32) * SILK_MAX_ORDER_LPC );
|
||||||
opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
opus_int32 *P = (opus_int32*)malloc(sizeof(opus_int32) * (SILK_MAX_ORDER_LPC / 2 + 1));
|
||||||
|
opus_int32 *Q= (opus_int32*)malloc(sizeof(opus_int32) * (SILK_MAX_ORDER_LPC / 2 + 1));
|
||||||
opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
|
opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
|
||||||
opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
|
opus_int32 *a32_QA1 = (opus_int32*)malloc(sizeof(opus_int32) * SILK_MAX_ORDER_LPC );
|
||||||
|
|
||||||
silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
||||||
celt_assert( d==10 || d==16 );
|
celt_assert( d==10 || d==16 );
|
||||||
@ -137,5 +138,9 @@ void silk_NLSF2A(
|
|||||||
a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
|
a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(cos_LSF_QA);
|
||||||
|
free(P);
|
||||||
|
free(Q);
|
||||||
|
free(a32_QA1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,12 +57,12 @@ void silk_burg_modified_c(
|
|||||||
opus_int k, n, s, lz, rshifts, reached_max_gain;
|
opus_int k, n, s, lz, rshifts, reached_max_gain;
|
||||||
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
||||||
const opus_int16 *x_ptr;
|
const opus_int16 *x_ptr;
|
||||||
opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
|
opus_int32 *C_first_row = (opus_int32*)malloc(sizeof(opus_int32) * SILK_MAX_ORDER_LPC);
|
||||||
opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
|
opus_int32 *C_last_row = (opus_int32*)malloc(sizeof(opus_int32) * SILK_MAX_ORDER_LPC);
|
||||||
opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
|
opus_int32 *Af_QA = (opus_int32*)malloc(sizeof(opus_int32) * SILK_MAX_ORDER_LPC);
|
||||||
opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
|
opus_int32 *CAf = (opus_int32*)malloc(sizeof(opus_int32) * (SILK_MAX_ORDER_LPC+1));
|
||||||
opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
opus_int32 *CAb = (opus_int32*)malloc(sizeof(opus_int32) * (SILK_MAX_ORDER_LPC+1));
|
||||||
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
|
opus_int32 *xcorr = (opus_int32*)malloc(sizeof(opus_int32) * SILK_MAX_ORDER_LPC);
|
||||||
opus_int64 C0_64;
|
opus_int64 C0_64;
|
||||||
|
|
||||||
celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||||
@ -277,4 +277,10 @@ void silk_burg_modified_c(
|
|||||||
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
||||||
*res_nrg_Q = -rshifts;
|
*res_nrg_Q = -rshifts;
|
||||||
}
|
}
|
||||||
|
free(C_first_row);
|
||||||
|
free(C_last_row);
|
||||||
|
free(Af_QA);
|
||||||
|
free(CAf);
|
||||||
|
free(CAb);
|
||||||
|
free(xcorr);
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ void silk_warped_autocorrelation_FIX_c(
|
|||||||
{
|
{
|
||||||
opus_int n, i, lsh;
|
opus_int n, i, lsh;
|
||||||
opus_int32 tmp1_QS, tmp2_QS;
|
opus_int32 tmp1_QS, tmp2_QS;
|
||||||
opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
opus_int32 *state_QS = (opus_int32*)calloc(MAX_SHAPE_LPC_ORDER + 1, sizeof(opus_int32));
|
||||||
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
opus_int64 *corr_QC = (opus_int64*)calloc(MAX_SHAPE_LPC_ORDER + 1, sizeof(opus_int64));
|
||||||
|
|
||||||
/* Order must be even */
|
/* Order must be even */
|
||||||
celt_assert( ( order & 1 ) == 0 );
|
celt_assert( ( order & 1 ) == 0 );
|
||||||
@ -88,5 +88,7 @@ void silk_warped_autocorrelation_FIX_c(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
||||||
|
free(state_QS);
|
||||||
|
free(corr_QC);
|
||||||
}
|
}
|
||||||
#endif /* OVERRIDE_silk_warped_autocorrelation_FIX_c */
|
#endif /* OVERRIDE_silk_warped_autocorrelation_FIX_c */
|
||||||
|
@ -48,7 +48,8 @@ void silk_resampler_down2_3(
|
|||||||
opus_int32 *buf_ptr;
|
opus_int32 *buf_ptr;
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
|
|
||||||
ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 );
|
// ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 );
|
||||||
|
opus_int32 *buf = (opus_int32*)malloc((RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR) * sizeof(opus_int32));
|
||||||
|
|
||||||
/* Copy buffered samples to start of buffer */
|
/* Copy buffered samples to start of buffer */
|
||||||
silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) );
|
silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) );
|
||||||
@ -99,5 +100,6 @@ void silk_resampler_down2_3(
|
|||||||
|
|
||||||
/* Copy last part of filtered signal to the state for the next call */
|
/* Copy last part of filtered signal to the state for the next call */
|
||||||
silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
|
silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
|
||||||
|
free(buf);
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
}
|
}
|
||||||
|
@ -42,16 +42,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ESP32 as of 3.x has a compiler bug in this section, with the G++ generated assembly
|
|
||||||
// being illegal. There's nothing wrong with the code here, it just looks like an
|
|
||||||
// Xtensa backend issue. Until that's fixed, no MIDI for you!
|
|
||||||
///home/earle/Arduino/libraries/ESP8266Audio/src/libtinysoundfont/tsf.h: In function 'void tsf_channel_midi_control(tsf*, int, int, int)':
|
|
||||||
// /home/earle/Arduino/libraries/ESP8266Audio/src/libtinysoundfont/tsf.h:2101:1: error: insn does not satisfy its constraints:
|
|
||||||
// 2101 | }
|
|
||||||
// | ^
|
|
||||||
|
|
||||||
#if !defined(ESP32)
|
|
||||||
|
|
||||||
#ifndef TSF_INCLUDE_TSF_INL
|
#ifndef TSF_INCLUDE_TSF_INL
|
||||||
#define TSF_INCLUDE_TSF_INL
|
#define TSF_INCLUDE_TSF_INL
|
||||||
|
|
||||||
@ -2159,5 +2149,3 @@ TSFDEF float tsf_channel_get_tuning(tsf* f, int channel)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //TSF_IMPLEMENTATION
|
#endif //TSF_IMPLEMENTATION
|
||||||
|
|
||||||
#endif // ! ESP32
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
BasedOnStyle: Google
|
|
||||||
AlignTrailingComments: false
|
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
|
|
||||||
# A separate 'Other libraries' grouping is added before libwebm's headers for
|
|
||||||
# gtest and gmock includes. This is based on the suggested grouping in the
|
|
||||||
# Google C++ Style Guide:
|
|
||||||
# https://google.github.io/styleguide/cppguide.html#Names_and_Order_of_Includes
|
|
||||||
# The other categories come from `clang-format-14 --dump-config --style=Google`.
|
|
||||||
# See the clang-format documentation for more information on this option:
|
|
||||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html#includecategories
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^<ext/.*\.h>'
|
|
||||||
Priority: 2
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
- Regex: '^<.*\.h>'
|
|
||||||
Priority: 1
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
- Regex: '^<.*'
|
|
||||||
Priority: 2
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
- Regex: '^((<|")(gtest|gmock)/)'
|
|
||||||
Priority: 3
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
||||||
- Regex: '.*'
|
|
||||||
Priority: 4
|
|
||||||
SortPriority: 0
|
|
||||||
CaseSensitive: false
|
|
@ -1,6 +0,0 @@
|
|||||||
*.sln eol=crlf
|
|
||||||
*.vcproj eol=crlf
|
|
||||||
*.vsprops eol=crlf
|
|
||||||
*.vcxproj eol=crlf
|
|
||||||
*.mkv -text -diff
|
|
||||||
*.webm -text -diff
|
|
@ -1,36 +0,0 @@
|
|||||||
*.MKV
|
|
||||||
*.a
|
|
||||||
*.cmake
|
|
||||||
*.d
|
|
||||||
*.exe
|
|
||||||
*.mkv
|
|
||||||
*.ncb
|
|
||||||
*.o
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.so*
|
|
||||||
*.suo
|
|
||||||
*.swp
|
|
||||||
*.user
|
|
||||||
*~
|
|
||||||
.vscode
|
|
||||||
/*.webm
|
|
||||||
CMakeCache.txt
|
|
||||||
CMakeFiles
|
|
||||||
Debug
|
|
||||||
Makefile
|
|
||||||
Release
|
|
||||||
core
|
|
||||||
dumpvtt
|
|
||||||
ipch
|
|
||||||
mkvmuxer_sample
|
|
||||||
mkvmuxer_tests
|
|
||||||
mkvparser_sample
|
|
||||||
mkvparser_tests
|
|
||||||
vp9_header_parser_tests
|
|
||||||
vp9_level_stats_tests
|
|
||||||
vttdemux
|
|
||||||
webm2pes
|
|
||||||
webm2pes_tests
|
|
||||||
webm2ts
|
|
||||||
webm_info
|
|
@ -1,6 +0,0 @@
|
|||||||
Hui Su <huisu@google.com>
|
|
||||||
Matthew Heaney <matthewjheaney@google.com>
|
|
||||||
Neil Birkbeck <birkbeck@google.com>
|
|
||||||
Patrik Carlsson <patrik2.carlsson@sonymobile.com>
|
|
||||||
Roberto Alanis Baez <alanisbaez@google.com>
|
|
||||||
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
|
@ -1,441 +0,0 @@
|
|||||||
# This Pylint rcfile contains a best-effort configuration to uphold the
|
|
||||||
# best-practices and style described in the Google Python style guide:
|
|
||||||
# https://google.github.io/styleguide/pyguide.html
|
|
||||||
#
|
|
||||||
# Its canonical open-source location is:
|
|
||||||
# https://google.github.io/styleguide/pylintrc
|
|
||||||
|
|
||||||
[MASTER]
|
|
||||||
|
|
||||||
# Files or directories to be skipped. They should be base names, not paths.
|
|
||||||
ignore=third_party
|
|
||||||
|
|
||||||
# Files or directories matching the regex patterns are skipped. The regex
|
|
||||||
# matches against base names, not paths.
|
|
||||||
ignore-patterns=
|
|
||||||
|
|
||||||
# Pickle collected data for later comparisons.
|
|
||||||
persistent=no
|
|
||||||
|
|
||||||
# List of plugins (as comma separated values of python modules names) to load,
|
|
||||||
# usually to register additional checkers.
|
|
||||||
load-plugins=
|
|
||||||
|
|
||||||
# Use multiple processes to speed up Pylint.
|
|
||||||
jobs=4
|
|
||||||
|
|
||||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
|
||||||
# active Python interpreter and may run arbitrary code.
|
|
||||||
unsafe-load-any-extension=no
|
|
||||||
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
|
||||||
|
|
||||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
|
||||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
|
||||||
confidence=
|
|
||||||
|
|
||||||
# Enable the message, report, category or checker with the given id(s). You can
|
|
||||||
# either give multiple identifier separated by comma (,) or put this option
|
|
||||||
# multiple time (only on the command line, not in the configuration file where
|
|
||||||
# it should appear only once). See also the "--disable" option for examples.
|
|
||||||
#enable=
|
|
||||||
|
|
||||||
# Disable the message, report, category or checker with the given id(s). You
|
|
||||||
# can either give multiple identifiers separated by comma (,) or put this
|
|
||||||
# option multiple times (only on the command line, not in the configuration
|
|
||||||
# file where it should appear only once).You can also use "--disable=all" to
|
|
||||||
# disable everything first and then reenable specific checks. For example, if
|
|
||||||
# you want to run only the similarities checker, you can use "--disable=all
|
|
||||||
# --enable=similarities". If you want to run only the classes checker, but have
|
|
||||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
|
||||||
# --disable=W"
|
|
||||||
disable=abstract-method,
|
|
||||||
apply-builtin,
|
|
||||||
arguments-differ,
|
|
||||||
attribute-defined-outside-init,
|
|
||||||
backtick,
|
|
||||||
bad-option-value,
|
|
||||||
basestring-builtin,
|
|
||||||
buffer-builtin,
|
|
||||||
c-extension-no-member,
|
|
||||||
consider-using-enumerate,
|
|
||||||
cmp-builtin,
|
|
||||||
cmp-method,
|
|
||||||
coerce-builtin,
|
|
||||||
coerce-method,
|
|
||||||
delslice-method,
|
|
||||||
div-method,
|
|
||||||
duplicate-code,
|
|
||||||
eq-without-hash,
|
|
||||||
execfile-builtin,
|
|
||||||
file-builtin,
|
|
||||||
filter-builtin-not-iterating,
|
|
||||||
fixme,
|
|
||||||
getslice-method,
|
|
||||||
global-statement,
|
|
||||||
hex-method,
|
|
||||||
idiv-method,
|
|
||||||
implicit-str-concat-in-sequence,
|
|
||||||
import-error,
|
|
||||||
import-self,
|
|
||||||
import-star-module-level,
|
|
||||||
inconsistent-return-statements,
|
|
||||||
input-builtin,
|
|
||||||
intern-builtin,
|
|
||||||
invalid-str-codec,
|
|
||||||
locally-disabled,
|
|
||||||
long-builtin,
|
|
||||||
long-suffix,
|
|
||||||
map-builtin-not-iterating,
|
|
||||||
misplaced-comparison-constant,
|
|
||||||
missing-function-docstring,
|
|
||||||
metaclass-assignment,
|
|
||||||
next-method-called,
|
|
||||||
next-method-defined,
|
|
||||||
no-absolute-import,
|
|
||||||
no-else-break,
|
|
||||||
no-else-continue,
|
|
||||||
no-else-raise,
|
|
||||||
no-else-return,
|
|
||||||
no-init, # added
|
|
||||||
no-member,
|
|
||||||
no-name-in-module,
|
|
||||||
no-self-use,
|
|
||||||
nonzero-method,
|
|
||||||
oct-method,
|
|
||||||
old-division,
|
|
||||||
old-ne-operator,
|
|
||||||
old-octal-literal,
|
|
||||||
old-raise-syntax,
|
|
||||||
parameter-unpacking,
|
|
||||||
print-statement,
|
|
||||||
raising-string,
|
|
||||||
range-builtin-not-iterating,
|
|
||||||
raw_input-builtin,
|
|
||||||
rdiv-method,
|
|
||||||
reduce-builtin,
|
|
||||||
relative-import,
|
|
||||||
reload-builtin,
|
|
||||||
round-builtin,
|
|
||||||
setslice-method,
|
|
||||||
signature-differs,
|
|
||||||
standarderror-builtin,
|
|
||||||
suppressed-message,
|
|
||||||
sys-max-int,
|
|
||||||
too-few-public-methods,
|
|
||||||
too-many-ancestors,
|
|
||||||
too-many-arguments,
|
|
||||||
too-many-boolean-expressions,
|
|
||||||
too-many-branches,
|
|
||||||
too-many-instance-attributes,
|
|
||||||
too-many-locals,
|
|
||||||
too-many-nested-blocks,
|
|
||||||
too-many-public-methods,
|
|
||||||
too-many-return-statements,
|
|
||||||
too-many-statements,
|
|
||||||
trailing-newlines,
|
|
||||||
unichr-builtin,
|
|
||||||
unicode-builtin,
|
|
||||||
unnecessary-pass,
|
|
||||||
unpacking-in-except,
|
|
||||||
useless-else-on-loop,
|
|
||||||
useless-object-inheritance,
|
|
||||||
useless-suppression,
|
|
||||||
using-cmp-argument,
|
|
||||||
wrong-import-order,
|
|
||||||
xrange-builtin,
|
|
||||||
zip-builtin-not-iterating,
|
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
|
||||||
|
|
||||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
|
||||||
# (visual studio) and html. You can also give a reporter class, eg
|
|
||||||
# mypackage.mymodule.MyReporterClass.
|
|
||||||
output-format=text
|
|
||||||
|
|
||||||
# Put messages in a separate file for each module / package specified on the
|
|
||||||
# command line instead of printing them on stdout. Reports (if any) will be
|
|
||||||
# written in a file name "pylint_global.[txt|html]". This option is deprecated
|
|
||||||
# and it will be removed in Pylint 2.0.
|
|
||||||
files-output=no
|
|
||||||
|
|
||||||
# Tells whether to display a full report or only the messages
|
|
||||||
reports=no
|
|
||||||
|
|
||||||
# Python expression which should return a note less than 10 (10 is the highest
|
|
||||||
# note). You have access to the variables errors warning, statement which
|
|
||||||
# respectively contain the number of errors / warnings messages and the total
|
|
||||||
# number of statements analyzed. This is used by the global evaluation report
|
|
||||||
# (RP0004).
|
|
||||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
|
||||||
|
|
||||||
# Template used to display messages. This is a python new-style format string
|
|
||||||
# used to format the message information. See doc for all details
|
|
||||||
#msg-template=
|
|
||||||
|
|
||||||
|
|
||||||
[BASIC]
|
|
||||||
|
|
||||||
# Good variable names which should always be accepted, separated by a comma
|
|
||||||
good-names=main,_,PRESUBMIT
|
|
||||||
|
|
||||||
# Bad variable names which should always be refused, separated by a comma
|
|
||||||
bad-names=
|
|
||||||
|
|
||||||
# Colon-delimited sets of names that determine each other's naming style when
|
|
||||||
# the name regexes allow several styles.
|
|
||||||
name-group=
|
|
||||||
|
|
||||||
# Include a hint for the correct naming format with invalid-name
|
|
||||||
include-naming-hint=no
|
|
||||||
|
|
||||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
|
||||||
# to this list to register other decorators that produce valid properties.
|
|
||||||
property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
|
|
||||||
|
|
||||||
# Regular expression matching correct function names
|
|
||||||
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct variable names
|
|
||||||
variable-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct constant names
|
|
||||||
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
|
||||||
|
|
||||||
# Regular expression matching correct attribute names
|
|
||||||
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct argument names
|
|
||||||
argument-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct class attribute names
|
|
||||||
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
|
||||||
|
|
||||||
# Regular expression matching correct inline iteration names
|
|
||||||
inlinevar-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct class names
|
|
||||||
class-rgx=^_?[A-Z][a-zA-Z0-9]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct module names
|
|
||||||
module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$
|
|
||||||
|
|
||||||
# Regular expression matching correct method names
|
|
||||||
method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression which should only match function or class names that do
|
|
||||||
# not require a docstring.
|
|
||||||
no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$
|
|
||||||
|
|
||||||
# Minimum line length for functions/classes that require docstrings, shorter
|
|
||||||
# ones are exempt.
|
|
||||||
docstring-min-length=10
|
|
||||||
|
|
||||||
|
|
||||||
[TYPECHECK]
|
|
||||||
|
|
||||||
# List of decorators that produce context managers, such as
|
|
||||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
|
||||||
# produce valid context managers.
|
|
||||||
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
|
|
||||||
|
|
||||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
|
||||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
|
||||||
ignore-mixin-members=yes
|
|
||||||
|
|
||||||
# List of module names for which member attributes should not be checked
|
|
||||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
|
||||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
|
||||||
# supports qualified module names, as well as Unix pattern matching.
|
|
||||||
ignored-modules=
|
|
||||||
|
|
||||||
# List of class names for which member attributes should not be checked (useful
|
|
||||||
# for classes with dynamically set attributes). This supports the use of
|
|
||||||
# qualified names.
|
|
||||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
|
||||||
|
|
||||||
# List of members which are set dynamically and missed by pylint inference
|
|
||||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
|
||||||
# expressions are accepted.
|
|
||||||
generated-members=
|
|
||||||
|
|
||||||
|
|
||||||
[FORMAT]
|
|
||||||
|
|
||||||
# Maximum number of characters on a single line.
|
|
||||||
max-line-length=80
|
|
||||||
|
|
||||||
# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
|
|
||||||
# lines made too long by directives to pytype.
|
|
||||||
|
|
||||||
# Regexp for a line that is allowed to be longer than the limit.
|
|
||||||
ignore-long-lines=(?x)(
|
|
||||||
^\s*(\#\ )?<?https?://\S+>?$|
|
|
||||||
^\s*(from\s+\S+\s+)?import\s+.+$)
|
|
||||||
|
|
||||||
# Allow the body of an if to be on the same line as the test if there is no
|
|
||||||
# else.
|
|
||||||
single-line-if-stmt=yes
|
|
||||||
|
|
||||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
|
||||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
|
||||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
|
||||||
# `empty-line` allows space-only lines.
|
|
||||||
no-space-check=
|
|
||||||
|
|
||||||
# Maximum number of lines in a module
|
|
||||||
max-module-lines=99999
|
|
||||||
|
|
||||||
# String used as indentation unit. The internal Google style guide mandates 2
|
|
||||||
# spaces. Google's externaly-published style guide says 4, consistent with
|
|
||||||
# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google
|
|
||||||
# projects (like TensorFlow).
|
|
||||||
indent-string=' '
|
|
||||||
|
|
||||||
# Number of spaces of indent required inside a hanging or continued line.
|
|
||||||
indent-after-paren=4
|
|
||||||
|
|
||||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
|
||||||
expected-line-ending-format=
|
|
||||||
|
|
||||||
|
|
||||||
[MISCELLANEOUS]
|
|
||||||
|
|
||||||
# List of note tags to take in consideration, separated by a comma.
|
|
||||||
notes=TODO
|
|
||||||
|
|
||||||
|
|
||||||
[STRING]
|
|
||||||
|
|
||||||
# This flag controls whether inconsistent-quotes generates a warning when the
|
|
||||||
# character used as a quote delimiter is used inconsistently within a module.
|
|
||||||
check-quote-consistency=yes
|
|
||||||
|
|
||||||
|
|
||||||
[VARIABLES]
|
|
||||||
|
|
||||||
# Tells whether we should check for unused import in __init__ files.
|
|
||||||
init-import=no
|
|
||||||
|
|
||||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
|
||||||
# not used).
|
|
||||||
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
|
|
||||||
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
|
||||||
# you should avoid to define new builtins when possible.
|
|
||||||
additional-builtins=
|
|
||||||
|
|
||||||
# List of strings which can identify a callback function by name. A callback
|
|
||||||
# name must start or end with one of those strings.
|
|
||||||
callbacks=cb_,_cb
|
|
||||||
|
|
||||||
# List of qualified module names which can have objects that can redefine
|
|
||||||
# builtins.
|
|
||||||
redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools
|
|
||||||
|
|
||||||
|
|
||||||
[LOGGING]
|
|
||||||
|
|
||||||
# Logging modules to check that the string format arguments are in logging
|
|
||||||
# function parameter format
|
|
||||||
logging-modules=logging,absl.logging,tensorflow.io.logging
|
|
||||||
|
|
||||||
|
|
||||||
[SIMILARITIES]
|
|
||||||
|
|
||||||
# Minimum lines number of a similarity.
|
|
||||||
min-similarity-lines=4
|
|
||||||
|
|
||||||
# Ignore comments when computing similarities.
|
|
||||||
ignore-comments=yes
|
|
||||||
|
|
||||||
# Ignore docstrings when computing similarities.
|
|
||||||
ignore-docstrings=yes
|
|
||||||
|
|
||||||
# Ignore imports when computing similarities.
|
|
||||||
ignore-imports=no
|
|
||||||
|
|
||||||
|
|
||||||
[SPELLING]
|
|
||||||
|
|
||||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
|
||||||
# install python-enchant package.
|
|
||||||
spelling-dict=
|
|
||||||
|
|
||||||
# List of comma separated words that should not be checked.
|
|
||||||
spelling-ignore-words=
|
|
||||||
|
|
||||||
# A path to a file that contains private dictionary; one word per line.
|
|
||||||
spelling-private-dict-file=
|
|
||||||
|
|
||||||
# Tells whether to store unknown words to indicated private dictionary in
|
|
||||||
# --spelling-private-dict-file option instead of raising a message.
|
|
||||||
spelling-store-unknown-words=no
|
|
||||||
|
|
||||||
|
|
||||||
[IMPORTS]
|
|
||||||
|
|
||||||
# Deprecated modules which should not be used, separated by a comma
|
|
||||||
deprecated-modules=regsub,
|
|
||||||
TERMIOS,
|
|
||||||
Bastion,
|
|
||||||
rexec,
|
|
||||||
sets
|
|
||||||
|
|
||||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
|
||||||
# given file (report RP0402 must not be disabled)
|
|
||||||
import-graph=
|
|
||||||
|
|
||||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
ext-import-graph=
|
|
||||||
|
|
||||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
int-import-graph=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of the standard
|
|
||||||
# compatibility libraries.
|
|
||||||
known-standard-library=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of a third party library.
|
|
||||||
known-third-party=enchant, absl
|
|
||||||
|
|
||||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
|
||||||
# 3 compatible code, which means that the block might have code that exists
|
|
||||||
# only in one or another interpreter, leading to false positives when analysed.
|
|
||||||
analyse-fallback-blocks=no
|
|
||||||
|
|
||||||
|
|
||||||
[CLASSES]
|
|
||||||
|
|
||||||
# List of method names used to declare (i.e. assign) instance attributes.
|
|
||||||
defining-attr-methods=__init__,
|
|
||||||
__new__,
|
|
||||||
setUp
|
|
||||||
|
|
||||||
# List of member names, which should be excluded from the protected access
|
|
||||||
# warning.
|
|
||||||
exclude-protected=_asdict,
|
|
||||||
_fields,
|
|
||||||
_replace,
|
|
||||||
_source,
|
|
||||||
_make
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a class method.
|
|
||||||
valid-classmethod-first-arg=cls,
|
|
||||||
class_
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a metaclass class method.
|
|
||||||
valid-metaclass-classmethod-first-arg=mcs
|
|
||||||
|
|
||||||
|
|
||||||
[EXCEPTIONS]
|
|
||||||
|
|
||||||
# Exceptions that will emit a warning when being caught. Defaults to
|
|
||||||
# "Exception"
|
|
||||||
overgeneral-exceptions=StandardError,
|
|
||||||
Exception,
|
|
||||||
BaseException
|
|
@ -1,5 +0,0 @@
|
|||||||
# Names should be added to this file like so:
|
|
||||||
# Name or Organization <email address>
|
|
||||||
|
|
||||||
Google Inc.
|
|
||||||
Elijah Cirioli <eli.cirioli@gmail.com>
|
|
@ -1,41 +0,0 @@
|
|||||||
# How to Contribute
|
|
||||||
|
|
||||||
We'd love to accept your patches and contributions to this project. There are
|
|
||||||
just a few small guidelines you need to follow.
|
|
||||||
|
|
||||||
## Contributor License Agreement
|
|
||||||
|
|
||||||
Contributions to this project must be accompanied by a Contributor License
|
|
||||||
Agreement. You (or your employer) retain the copyright to your contribution;
|
|
||||||
this simply gives us permission to use and redistribute your contributions as
|
|
||||||
part of the project. Head over to <https://cla.developers.google.com/> to see
|
|
||||||
your current agreements on file or to sign a new one.
|
|
||||||
|
|
||||||
You generally only need to submit a CLA once, so if you've already submitted one
|
|
||||||
(even if it was for a different project), you probably don't need to do it
|
|
||||||
again.
|
|
||||||
|
|
||||||
## Code reviews
|
|
||||||
|
|
||||||
All submissions, including submissions by project members, require review. We
|
|
||||||
use a [Gerrit](https://www.gerritcodereview.com) instance hosted at
|
|
||||||
https://chromium-review.googlesource.com for this purpose. See the
|
|
||||||
[WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/)
|
|
||||||
for additional details.
|
|
||||||
|
|
||||||
## Code Style
|
|
||||||
|
|
||||||
The C++ code style is based on the
|
|
||||||
[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) and
|
|
||||||
`clang-format --style=Google`. `clang-format -i --style=file` can be used to
|
|
||||||
format individual files, it will use the settings from `.clang-format`.
|
|
||||||
|
|
||||||
CMake files are formatted with
|
|
||||||
[cmake-format](https://cmake-format.readthedocs.io/en/latest/). `cmake-format
|
|
||||||
-i` can be used to format individual files, it will use the settings from
|
|
||||||
`.cmake-format.py`.
|
|
||||||
|
|
||||||
## Community Guidelines
|
|
||||||
|
|
||||||
This project follows
|
|
||||||
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).
|
|
@ -1,30 +0,0 @@
|
|||||||
Copyright (c) 2010, Google Inc. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in
|
|
||||||
the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
* Neither the name of Google nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
Additional IP Rights Grant (Patents)
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
"These implementations" means the copyrightable works that implement the WebM
|
|
||||||
codecs distributed by Google as part of the WebM Project.
|
|
||||||
|
|
||||||
Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
|
|
||||||
royalty-free, irrevocable (except as stated in this section) patent license to
|
|
||||||
make, have made, use, offer to sell, sell, import, transfer, and otherwise
|
|
||||||
run, modify and propagate the contents of these implementations of WebM, where
|
|
||||||
such license applies only to those patent claims, both currently owned by
|
|
||||||
Google and acquired in the future, licensable by Google that are necessarily
|
|
||||||
infringed by these implementations of WebM. This grant does not include claims
|
|
||||||
that would be infringed only as a consequence of further modification of these
|
|
||||||
implementations. If you or your agent or exclusive licensee institute or order
|
|
||||||
or agree to the institution of patent litigation or any other patent
|
|
||||||
enforcement activity against any entity (including a cross-claim or
|
|
||||||
counterclaim in a lawsuit) alleging that any of these implementations of WebM
|
|
||||||
or any code incorporated within any of these implementations of WebM
|
|
||||||
constitute direct or contributory patent infringement, or inducement of
|
|
||||||
patent infringement, then any patent rights granted to you under this License
|
|
||||||
for these implementations of WebM shall terminate as of the date such
|
|
||||||
litigation is filed.
|
|
@ -1,202 +0,0 @@
|
|||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
"""Top-level presubmit script for libwebm.
|
|
||||||
|
|
||||||
See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
|
|
||||||
details on the presubmit API built into depot_tools.
|
|
||||||
"""
|
|
||||||
import re
|
|
||||||
import subprocess2
|
|
||||||
|
|
||||||
USE_PYTHON3 = True
|
|
||||||
_BASH_INDENTATION = "2"
|
|
||||||
_GIT_COMMIT_SUBJECT_LENGTH = 65
|
|
||||||
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
|
|
||||||
_INCLUDE_SOURCE_FILES_ONLY = [r".*\.(c|cc|[hc]pp|h)$"]
|
|
||||||
_LIBWEBM_MAX_LINE_LENGTH = 80
|
|
||||||
|
|
||||||
|
|
||||||
def _CheckCommitSubjectLength(input_api, output_api):
|
|
||||||
"""Ensures commit's subject length is no longer than 65 chars."""
|
|
||||||
name = "git-commit subject"
|
|
||||||
cmd = ["git", "log", "-1", "--pretty=%s"]
|
|
||||||
start = input_api.time.time()
|
|
||||||
proc = subprocess2.Popen(
|
|
||||||
cmd,
|
|
||||||
stderr=subprocess2.PIPE,
|
|
||||||
stdout=subprocess2.PIPE,
|
|
||||||
universal_newlines=True)
|
|
||||||
|
|
||||||
stdout, _ = proc.communicate()
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
|
|
||||||
if not re.match(r"^Revert",
|
|
||||||
stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
|
|
||||||
failure_msg = (
|
|
||||||
"The commit subject: %s is too long (%d chars)\n"
|
|
||||||
"Try to keep this to 50 or less (up to 65 is permitted for "
|
|
||||||
"non-reverts).\n"
|
|
||||||
"https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
|
|
||||||
"Project#_commit_guidelines") % (stdout, len(stdout) - 1)
|
|
||||||
return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
|
|
||||||
(name, duration, failure_msg))
|
|
||||||
|
|
||||||
return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
|
|
||||||
|
|
||||||
|
|
||||||
def _GetFilesToSkip(input_api):
|
|
||||||
"""Skips libwebm-specific files."""
|
|
||||||
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
|
|
||||||
r"\.pylintrc$",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def _CheckChangeLintsClean(input_api, output_api):
|
|
||||||
"""Makes sure that libwebm/ code is cpplint clean."""
|
|
||||||
sources = lambda x: input_api.FilterSourceFile(
|
|
||||||
x, files_to_check=_INCLUDE_SOURCE_FILES_ONLY, files_to_skip=None)
|
|
||||||
return input_api.canned_checks.CheckChangeLintsClean(input_api, output_api,
|
|
||||||
sources)
|
|
||||||
|
|
||||||
|
|
||||||
def _RunShellCheckCmd(input_api, output_api, bash_file):
|
|
||||||
"""shellcheck command wrapper."""
|
|
||||||
cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file]
|
|
||||||
name = "Check %s file." % bash_file
|
|
||||||
start = input_api.time.time()
|
|
||||||
output, rc = subprocess2.communicate(
|
|
||||||
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
if rc == 0:
|
|
||||||
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
|
||||||
(name, " ".join(cmd), duration))
|
|
||||||
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
|
||||||
(name, " ".join(cmd), duration, output[1]))
|
|
||||||
|
|
||||||
|
|
||||||
def _RunShfmtCheckCmd(input_api, output_api, bash_file):
|
|
||||||
"""shfmt command wrapper."""
|
|
||||||
cmd = [
|
|
||||||
"shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d",
|
|
||||||
bash_file
|
|
||||||
]
|
|
||||||
name = "Check %s file." % bash_file
|
|
||||||
start = input_api.time.time()
|
|
||||||
output, rc = subprocess2.communicate(
|
|
||||||
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
if rc == 0:
|
|
||||||
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
|
||||||
(name, " ".join(cmd), duration))
|
|
||||||
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
|
||||||
(name, " ".join(cmd), duration, output[1]))
|
|
||||||
|
|
||||||
|
|
||||||
def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check):
|
|
||||||
"""Ensure that libwebm/ files are clean."""
|
|
||||||
file_filter = lambda x: input_api.FilterSourceFile(
|
|
||||||
x, files_to_check=files_to_check, files_to_skip=None)
|
|
||||||
|
|
||||||
affected_files = input_api.change.AffectedFiles(file_filter=file_filter)
|
|
||||||
results = [
|
|
||||||
run_cmd(input_api, output_api, f.AbsoluteLocalPath())
|
|
||||||
for f in affected_files
|
|
||||||
]
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def _CommonChecks(input_api, output_api):
|
|
||||||
results = []
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
|
|
||||||
input_api, output_api))
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api))
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
|
|
||||||
input_api, output_api))
|
|
||||||
results.append(_CheckCommitSubjectLength(input_api, output_api))
|
|
||||||
|
|
||||||
source_file_filter = lambda x: input_api.FilterSourceFile(
|
|
||||||
x, files_to_skip=_GetFilesToSkip(input_api))
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckLongLines(
|
|
||||||
input_api,
|
|
||||||
output_api,
|
|
||||||
maxlen=_LIBWEBM_MAX_LINE_LENGTH,
|
|
||||||
source_file_filter=source_file_filter))
|
|
||||||
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckPatchFormatted(
|
|
||||||
input_api,
|
|
||||||
output_api,
|
|
||||||
check_clang_format=True,
|
|
||||||
check_python=True,
|
|
||||||
result_factory=output_api.PresubmitError))
|
|
||||||
results.extend(_CheckChangeLintsClean(input_api, output_api))
|
|
||||||
|
|
||||||
# Run pylint.
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.RunPylint(
|
|
||||||
input_api,
|
|
||||||
output_api,
|
|
||||||
files_to_skip=_GetFilesToSkip(input_api),
|
|
||||||
pylintrc=".pylintrc",
|
|
||||||
version="2.7"))
|
|
||||||
|
|
||||||
# Binaries shellcheck and shfmt are not installed in depot_tools.
|
|
||||||
# Installation is needed
|
|
||||||
try:
|
|
||||||
subprocess2.communicate(["shellcheck", "--version"])
|
|
||||||
results.extend(
|
|
||||||
_RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd,
|
|
||||||
_INCLUDE_BASH_FILES_ONLY))
|
|
||||||
print("shfmt")
|
|
||||||
subprocess2.communicate(["shfmt", "-version"])
|
|
||||||
results.extend(
|
|
||||||
_RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd,
|
|
||||||
_INCLUDE_BASH_FILES_ONLY))
|
|
||||||
except OSError as os_error:
|
|
||||||
results.append(
|
|
||||||
output_api.PresubmitPromptWarning(
|
|
||||||
"%s\nPlease install missing binaries locally." % os_error.args[0]))
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def CheckChangeOnUpload(input_api, output_api):
|
|
||||||
results = []
|
|
||||||
results.extend(_CommonChecks(input_api, output_api))
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def CheckChangeOnCommit(input_api, output_api):
|
|
||||||
results = []
|
|
||||||
results.extend(_CommonChecks(input_api, output_api))
|
|
||||||
return results
|
|
@ -1,148 +0,0 @@
|
|||||||
Building Libwebm
|
|
||||||
|
|
||||||
To build libwebm you must first create project files. To do this run cmake
|
|
||||||
and pass it the path to your libwebm repo.
|
|
||||||
|
|
||||||
Makefile.unix can be used as a fallback on systems that cmake does not
|
|
||||||
support.
|
|
||||||
|
|
||||||
|
|
||||||
CMake Basics
|
|
||||||
|
|
||||||
To generate project/make files for the default toolchain on your system simply
|
|
||||||
run cmake with the path to the libwebm repo:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm
|
|
||||||
|
|
||||||
On Windows the above command will produce Visual Studio project files for the
|
|
||||||
newest Visual Studio detected on the system. On Mac OS X and Linux systems, the
|
|
||||||
above command will produce a makefile.
|
|
||||||
|
|
||||||
To control what types of projects are generated the -G parameter is added to
|
|
||||||
the cmake command line. This argument must be followed by the name of a
|
|
||||||
generator. Running cmake with the --help argument will list the available
|
|
||||||
generators for your system.
|
|
||||||
|
|
||||||
On Mac OS X you would run the following command to generate Xcode projects:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm -G Xcode
|
|
||||||
|
|
||||||
On a Windows box you would run the following command to generate Visual Studio
|
|
||||||
2013 projects:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm -G "Visual Studio 12"
|
|
||||||
|
|
||||||
To generate 64-bit Windows Visual Studio 2013 projects:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm "Visual Studio 12 Win64"
|
|
||||||
|
|
||||||
|
|
||||||
CMake Makefiles: Debugging and Optimization
|
|
||||||
|
|
||||||
Unlike Visual Studio and Xcode projects, the build configuration for make builds
|
|
||||||
is controlled when you run cmake. The following examples demonstrate various
|
|
||||||
build configurations.
|
|
||||||
|
|
||||||
Omitting the build type produces makefiles that use build flags containing
|
|
||||||
neither optimization nor debug flags:
|
|
||||||
$ cmake path/to/libwebm
|
|
||||||
|
|
||||||
A makefile using release (optimized) flags is produced like this:
|
|
||||||
$ cmake path/to/libwebm -DCMAKE_BUILD_TYPE=release
|
|
||||||
|
|
||||||
A release build with debug info can be produced as well:
|
|
||||||
$ cmake path/to/libwebm -DCMAKE_BUILD_TYPE=relwithdebinfo
|
|
||||||
|
|
||||||
And your standard debug build will be produced using:
|
|
||||||
$ cmake path/to/libwebm -DCMAKE_BUILD_TYPE=debug
|
|
||||||
|
|
||||||
|
|
||||||
Tests
|
|
||||||
|
|
||||||
To enable libwebm tests add -DENABLE_TESTS=ON CMake generation command line. For
|
|
||||||
example:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm -G Xcode -DENABLE_TESTS=ON
|
|
||||||
|
|
||||||
Libwebm tests depend on googletest. By default googletest is expected to be a
|
|
||||||
sibling directory of the Libwebm repository. To change that, update your CMake
|
|
||||||
command to be similar to the following:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm -G Xcode -DENABLE_TESTS=ON \
|
|
||||||
-DGTEST_SRC_DIR=/path/to/googletest
|
|
||||||
|
|
||||||
The tests rely upon the LIBWEBM_TEST_DATA_PATH environment variable to locate
|
|
||||||
test input. The following example demonstrates running the muxer tests from the
|
|
||||||
build directory:
|
|
||||||
|
|
||||||
$ LIBWEBM_TEST_DATA_PATH=path/to/libwebm/testing/testdata ./mkvmuxer_tests
|
|
||||||
|
|
||||||
Note: Libwebm Googletest integration was built with googletest from
|
|
||||||
https://github.com/google/googletest.git at git revision
|
|
||||||
ddb8012eb48bc203aa93dcc2b22c1db516302b29.
|
|
||||||
|
|
||||||
|
|
||||||
CMake Include-what-you-use integration
|
|
||||||
|
|
||||||
Include-what-you-use is an analysis tool that helps ensure libwebm includes the
|
|
||||||
C/C++ header files actually in use. To enable the integration support
|
|
||||||
ENABLE_IWYU must be turned on at cmake run time:
|
|
||||||
|
|
||||||
$ cmake path/to/libwebm -G "Unix Makefiles" -DENABLE_IWYU=ON
|
|
||||||
|
|
||||||
This adds the iwyu target to the build. To run include-what-you-use:
|
|
||||||
|
|
||||||
$ make iwyu
|
|
||||||
|
|
||||||
The following requirements must be met for ENABLE_IWYU to enable the iwyu
|
|
||||||
target:
|
|
||||||
|
|
||||||
1. include-what-you-use and iwyu_tool.py must be in your PATH.
|
|
||||||
2. A python interpreter must be on the system and available to CMake.
|
|
||||||
|
|
||||||
The values of the following variables are used to determine if the requirements
|
|
||||||
have been met. Values to the right of the equals sign are what a successful run
|
|
||||||
might look like:
|
|
||||||
iwyu_path=/path/to/iwyu_tool.py
|
|
||||||
iwyu_tool_path=/path/to/include-what-you-use
|
|
||||||
PYTHONINTERP_FOUND=TRUE
|
|
||||||
|
|
||||||
An empty PYTHONINTERP_FOUND, or iwyu_path/iwyu_tool_path suffixed with NOTFOUND
|
|
||||||
are failures.
|
|
||||||
|
|
||||||
For Include-what-you-use setup instructions, see:
|
|
||||||
https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/InstructionsForUsers.md
|
|
||||||
|
|
||||||
If, when building the iwyu target, compile errors reporting failures loading
|
|
||||||
standard include files occur, one solution can be found here:
|
|
||||||
https://github.com/include-what-you-use/include-what-you-use/issues/100
|
|
||||||
|
|
||||||
|
|
||||||
CMake cross compile
|
|
||||||
To cross compile libwebm for Windows using mingw-w64 run cmake with the
|
|
||||||
following arguments:
|
|
||||||
|
|
||||||
$ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/libwebm/build/mingw-w64_toolchain.cmake \
|
|
||||||
path/to/libwebm
|
|
||||||
|
|
||||||
Note1: As of this writing googletest will not build via mingw-w64 without
|
|
||||||
disabling pthreads.
|
|
||||||
googletest hash: d225acc90bc3a8c420a9bcd1f033033c1ccd7fe0
|
|
||||||
|
|
||||||
To build with tests when using mingw-w64 use the following arguments when
|
|
||||||
running CMake:
|
|
||||||
|
|
||||||
$ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/libwebm/build/mingw-w64_toolchain.cmake \
|
|
||||||
-DENABLE_TESTS=ON -Dgtest_disable_pthreads=ON path/to/libwebm
|
|
||||||
|
|
||||||
Note2: i686-w64-mingw32 is the default compiler. This can be controlled using
|
|
||||||
the MINGW_PREFIX variable:
|
|
||||||
|
|
||||||
$ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/libwebm/build/mingw-w64_toolchain.cmake \
|
|
||||||
-DMINGW_PREFIX=x86_64-w64-mingw32 path/to/libwebm
|
|
||||||
|
|
||||||
Bug reports
|
|
||||||
|
|
||||||
Bug reports can be filed in the libwebm issue tracker:
|
|
||||||
https://issues.webmproject.org/.
|
|
||||||
For security reports, select 'Security report' from the Template dropdown.
|
|
@ -1,4 +0,0 @@
|
|||||||
# This file is used by git cl to get repository specific information.
|
|
||||||
GERRIT_HOST: True
|
|
||||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
|
||||||
GERRIT_SQUASH_UPLOADS: False
|
|
@ -1,193 +0,0 @@
|
|||||||
// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the LICENSE file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
|
|
||||||
#ifndef COMMON_WEBMIDS_H_
|
|
||||||
#define COMMON_WEBMIDS_H_
|
|
||||||
|
|
||||||
namespace libwebm {
|
|
||||||
|
|
||||||
enum MkvId {
|
|
||||||
kMkvEBML = 0x1A45DFA3,
|
|
||||||
kMkvEBMLVersion = 0x4286,
|
|
||||||
kMkvEBMLReadVersion = 0x42F7,
|
|
||||||
kMkvEBMLMaxIDLength = 0x42F2,
|
|
||||||
kMkvEBMLMaxSizeLength = 0x42F3,
|
|
||||||
kMkvDocType = 0x4282,
|
|
||||||
kMkvDocTypeVersion = 0x4287,
|
|
||||||
kMkvDocTypeReadVersion = 0x4285,
|
|
||||||
kMkvVoid = 0xEC,
|
|
||||||
kMkvSignatureSlot = 0x1B538667,
|
|
||||||
kMkvSignatureAlgo = 0x7E8A,
|
|
||||||
kMkvSignatureHash = 0x7E9A,
|
|
||||||
kMkvSignaturePublicKey = 0x7EA5,
|
|
||||||
kMkvSignature = 0x7EB5,
|
|
||||||
kMkvSignatureElements = 0x7E5B,
|
|
||||||
kMkvSignatureElementList = 0x7E7B,
|
|
||||||
kMkvSignedElement = 0x6532,
|
|
||||||
// segment
|
|
||||||
kMkvSegment = 0x18538067,
|
|
||||||
// Meta Seek Information
|
|
||||||
kMkvSeekHead = 0x114D9B74,
|
|
||||||
kMkvSeek = 0x4DBB,
|
|
||||||
kMkvSeekID = 0x53AB,
|
|
||||||
kMkvSeekPosition = 0x53AC,
|
|
||||||
// Segment Information
|
|
||||||
kMkvInfo = 0x1549A966,
|
|
||||||
kMkvTimecodeScale = 0x2AD7B1,
|
|
||||||
kMkvDuration = 0x4489,
|
|
||||||
kMkvDateUTC = 0x4461,
|
|
||||||
kMkvTitle = 0x7BA9,
|
|
||||||
kMkvMuxingApp = 0x4D80,
|
|
||||||
kMkvWritingApp = 0x5741,
|
|
||||||
// Cluster
|
|
||||||
kMkvCluster = 0x1F43B675,
|
|
||||||
kMkvTimecode = 0xE7,
|
|
||||||
kMkvPrevSize = 0xAB,
|
|
||||||
kMkvBlockGroup = 0xA0,
|
|
||||||
kMkvBlock = 0xA1,
|
|
||||||
kMkvBlockDuration = 0x9B,
|
|
||||||
kMkvReferenceBlock = 0xFB,
|
|
||||||
kMkvLaceNumber = 0xCC,
|
|
||||||
kMkvSimpleBlock = 0xA3,
|
|
||||||
kMkvBlockAdditions = 0x75A1,
|
|
||||||
kMkvBlockMore = 0xA6,
|
|
||||||
kMkvBlockAddID = 0xEE,
|
|
||||||
kMkvBlockAdditional = 0xA5,
|
|
||||||
kMkvDiscardPadding = 0x75A2,
|
|
||||||
// Track
|
|
||||||
kMkvTracks = 0x1654AE6B,
|
|
||||||
kMkvTrackEntry = 0xAE,
|
|
||||||
kMkvTrackNumber = 0xD7,
|
|
||||||
kMkvTrackUID = 0x73C5,
|
|
||||||
kMkvTrackType = 0x83,
|
|
||||||
kMkvFlagEnabled = 0xB9,
|
|
||||||
kMkvFlagDefault = 0x88,
|
|
||||||
kMkvFlagForced = 0x55AA,
|
|
||||||
kMkvFlagLacing = 0x9C,
|
|
||||||
kMkvDefaultDuration = 0x23E383,
|
|
||||||
kMkvMaxBlockAdditionID = 0x55EE,
|
|
||||||
kMkvName = 0x536E,
|
|
||||||
kMkvLanguage = 0x22B59C,
|
|
||||||
kMkvCodecID = 0x86,
|
|
||||||
kMkvCodecPrivate = 0x63A2,
|
|
||||||
kMkvCodecName = 0x258688,
|
|
||||||
kMkvCodecDelay = 0x56AA,
|
|
||||||
kMkvSeekPreRoll = 0x56BB,
|
|
||||||
// video
|
|
||||||
kMkvVideo = 0xE0,
|
|
||||||
kMkvFlagInterlaced = 0x9A,
|
|
||||||
kMkvStereoMode = 0x53B8,
|
|
||||||
kMkvAlphaMode = 0x53C0,
|
|
||||||
kMkvPixelWidth = 0xB0,
|
|
||||||
kMkvPixelHeight = 0xBA,
|
|
||||||
kMkvPixelCropBottom = 0x54AA,
|
|
||||||
kMkvPixelCropTop = 0x54BB,
|
|
||||||
kMkvPixelCropLeft = 0x54CC,
|
|
||||||
kMkvPixelCropRight = 0x54DD,
|
|
||||||
kMkvDisplayWidth = 0x54B0,
|
|
||||||
kMkvDisplayHeight = 0x54BA,
|
|
||||||
kMkvDisplayUnit = 0x54B2,
|
|
||||||
kMkvAspectRatioType = 0x54B3,
|
|
||||||
kMkvColourSpace = 0x2EB524,
|
|
||||||
kMkvFrameRate = 0x2383E3,
|
|
||||||
// end video
|
|
||||||
// colour
|
|
||||||
kMkvColour = 0x55B0,
|
|
||||||
kMkvMatrixCoefficients = 0x55B1,
|
|
||||||
kMkvBitsPerChannel = 0x55B2,
|
|
||||||
kMkvChromaSubsamplingHorz = 0x55B3,
|
|
||||||
kMkvChromaSubsamplingVert = 0x55B4,
|
|
||||||
kMkvCbSubsamplingHorz = 0x55B5,
|
|
||||||
kMkvCbSubsamplingVert = 0x55B6,
|
|
||||||
kMkvChromaSitingHorz = 0x55B7,
|
|
||||||
kMkvChromaSitingVert = 0x55B8,
|
|
||||||
kMkvRange = 0x55B9,
|
|
||||||
kMkvTransferCharacteristics = 0x55BA,
|
|
||||||
kMkvPrimaries = 0x55BB,
|
|
||||||
kMkvMaxCLL = 0x55BC,
|
|
||||||
kMkvMaxFALL = 0x55BD,
|
|
||||||
// mastering metadata
|
|
||||||
kMkvMasteringMetadata = 0x55D0,
|
|
||||||
kMkvPrimaryRChromaticityX = 0x55D1,
|
|
||||||
kMkvPrimaryRChromaticityY = 0x55D2,
|
|
||||||
kMkvPrimaryGChromaticityX = 0x55D3,
|
|
||||||
kMkvPrimaryGChromaticityY = 0x55D4,
|
|
||||||
kMkvPrimaryBChromaticityX = 0x55D5,
|
|
||||||
kMkvPrimaryBChromaticityY = 0x55D6,
|
|
||||||
kMkvWhitePointChromaticityX = 0x55D7,
|
|
||||||
kMkvWhitePointChromaticityY = 0x55D8,
|
|
||||||
kMkvLuminanceMax = 0x55D9,
|
|
||||||
kMkvLuminanceMin = 0x55DA,
|
|
||||||
// end mastering metadata
|
|
||||||
// end colour
|
|
||||||
// projection
|
|
||||||
kMkvProjection = 0x7670,
|
|
||||||
kMkvProjectionType = 0x7671,
|
|
||||||
kMkvProjectionPrivate = 0x7672,
|
|
||||||
kMkvProjectionPoseYaw = 0x7673,
|
|
||||||
kMkvProjectionPosePitch = 0x7674,
|
|
||||||
kMkvProjectionPoseRoll = 0x7675,
|
|
||||||
// end projection
|
|
||||||
// audio
|
|
||||||
kMkvAudio = 0xE1,
|
|
||||||
kMkvSamplingFrequency = 0xB5,
|
|
||||||
kMkvOutputSamplingFrequency = 0x78B5,
|
|
||||||
kMkvChannels = 0x9F,
|
|
||||||
kMkvBitDepth = 0x6264,
|
|
||||||
// end audio
|
|
||||||
// ContentEncodings
|
|
||||||
kMkvContentEncodings = 0x6D80,
|
|
||||||
kMkvContentEncoding = 0x6240,
|
|
||||||
kMkvContentEncodingOrder = 0x5031,
|
|
||||||
kMkvContentEncodingScope = 0x5032,
|
|
||||||
kMkvContentEncodingType = 0x5033,
|
|
||||||
kMkvContentCompression = 0x5034,
|
|
||||||
kMkvContentCompAlgo = 0x4254,
|
|
||||||
kMkvContentCompSettings = 0x4255,
|
|
||||||
kMkvContentEncryption = 0x5035,
|
|
||||||
kMkvContentEncAlgo = 0x47E1,
|
|
||||||
kMkvContentEncKeyID = 0x47E2,
|
|
||||||
kMkvContentSignature = 0x47E3,
|
|
||||||
kMkvContentSigKeyID = 0x47E4,
|
|
||||||
kMkvContentSigAlgo = 0x47E5,
|
|
||||||
kMkvContentSigHashAlgo = 0x47E6,
|
|
||||||
kMkvContentEncAESSettings = 0x47E7,
|
|
||||||
kMkvAESSettingsCipherMode = 0x47E8,
|
|
||||||
kMkvAESSettingsCipherInitData = 0x47E9,
|
|
||||||
// end ContentEncodings
|
|
||||||
// Cueing Data
|
|
||||||
kMkvCues = 0x1C53BB6B,
|
|
||||||
kMkvCuePoint = 0xBB,
|
|
||||||
kMkvCueTime = 0xB3,
|
|
||||||
kMkvCueTrackPositions = 0xB7,
|
|
||||||
kMkvCueTrack = 0xF7,
|
|
||||||
kMkvCueClusterPosition = 0xF1,
|
|
||||||
kMkvCueBlockNumber = 0x5378,
|
|
||||||
// Chapters
|
|
||||||
kMkvChapters = 0x1043A770,
|
|
||||||
kMkvEditionEntry = 0x45B9,
|
|
||||||
kMkvChapterAtom = 0xB6,
|
|
||||||
kMkvChapterUID = 0x73C4,
|
|
||||||
kMkvChapterStringUID = 0x5654,
|
|
||||||
kMkvChapterTimeStart = 0x91,
|
|
||||||
kMkvChapterTimeEnd = 0x92,
|
|
||||||
kMkvChapterDisplay = 0x80,
|
|
||||||
kMkvChapString = 0x85,
|
|
||||||
kMkvChapLanguage = 0x437C,
|
|
||||||
kMkvChapCountry = 0x437E,
|
|
||||||
// Tags
|
|
||||||
kMkvTags = 0x1254C367,
|
|
||||||
kMkvTag = 0x7373,
|
|
||||||
kMkvSimpleTag = 0x67C8,
|
|
||||||
kMkvTagName = 0x45A3,
|
|
||||||
kMkvTagString = 0x4487
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace libwebm
|
|
||||||
|
|
||||||
#endif // COMMON_WEBMIDS_H_
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,28 +0,0 @@
|
|||||||
// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the LICENSE file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
|
|
||||||
#ifndef MKVMUXER_MKVMUXERTYPES_H_
|
|
||||||
#define MKVMUXER_MKVMUXERTYPES_H_
|
|
||||||
|
|
||||||
namespace mkvmuxer {
|
|
||||||
typedef unsigned char uint8;
|
|
||||||
typedef short int16;
|
|
||||||
typedef int int32;
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
typedef long long int64;
|
|
||||||
typedef unsigned long long uint64;
|
|
||||||
} // namespace mkvmuxer
|
|
||||||
|
|
||||||
// Copied from Chromium basictypes.h
|
|
||||||
// A macro to disallow the copy constructor and operator= functions
|
|
||||||
// This should be used in the private: declarations for a class
|
|
||||||
#define LIBWEBM_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
|
||||||
TypeName(const TypeName&); \
|
|
||||||
void operator=(const TypeName&)
|
|
||||||
|
|
||||||
#endif // MKVMUXER_MKVMUXERTYPES_HPP_
|
|
@ -1,739 +0,0 @@
|
|||||||
// Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the LICENSE file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
|
|
||||||
#include "mkvmuxerutil.h"
|
|
||||||
#ifdef ESP32
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <ctime>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "../common/webmids.h"
|
|
||||||
#include "mkvmuxer.h"
|
|
||||||
#include "mkvwriter.h"
|
|
||||||
|
|
||||||
namespace mkvmuxer {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Date elements are always 8 octets in size.
|
|
||||||
const int kDateElementSize = 8;
|
|
||||||
|
|
||||||
uint64 WriteBlock(IMkvWriter* writer, const Frame* const frame, int64 timecode,
|
|
||||||
uint64 timecode_scale) {
|
|
||||||
uint64 block_additional_elem_size = 0;
|
|
||||||
uint64 block_addid_elem_size = 0;
|
|
||||||
uint64 block_more_payload_size = 0;
|
|
||||||
uint64 block_more_elem_size = 0;
|
|
||||||
uint64 block_additions_payload_size = 0;
|
|
||||||
uint64 block_additions_elem_size = 0;
|
|
||||||
if (frame->additional()) {
|
|
||||||
block_additional_elem_size =
|
|
||||||
EbmlElementSize(libwebm::kMkvBlockAdditional, frame->additional(),
|
|
||||||
frame->additional_length());
|
|
||||||
block_addid_elem_size = EbmlElementSize(
|
|
||||||
libwebm::kMkvBlockAddID, static_cast<uint64>(frame->add_id()));
|
|
||||||
|
|
||||||
block_more_payload_size =
|
|
||||||
block_addid_elem_size + block_additional_elem_size;
|
|
||||||
block_more_elem_size =
|
|
||||||
EbmlMasterElementSize(libwebm::kMkvBlockMore, block_more_payload_size) +
|
|
||||||
block_more_payload_size;
|
|
||||||
block_additions_payload_size = block_more_elem_size;
|
|
||||||
block_additions_elem_size =
|
|
||||||
EbmlMasterElementSize(libwebm::kMkvBlockAdditions,
|
|
||||||
block_additions_payload_size) +
|
|
||||||
block_additions_payload_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 discard_padding_elem_size = 0;
|
|
||||||
if (frame->discard_padding() != 0) {
|
|
||||||
discard_padding_elem_size =
|
|
||||||
EbmlElementSize(libwebm::kMkvDiscardPadding,
|
|
||||||
static_cast<int64>(frame->discard_padding()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64 reference_block_timestamp =
|
|
||||||
frame->reference_block_timestamp() / timecode_scale;
|
|
||||||
uint64 reference_block_elem_size = 0;
|
|
||||||
if (!frame->is_key()) {
|
|
||||||
reference_block_elem_size =
|
|
||||||
EbmlElementSize(libwebm::kMkvReferenceBlock, reference_block_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64 duration = frame->duration() / timecode_scale;
|
|
||||||
uint64 block_duration_elem_size = 0;
|
|
||||||
if (duration > 0)
|
|
||||||
block_duration_elem_size =
|
|
||||||
EbmlElementSize(libwebm::kMkvBlockDuration, duration);
|
|
||||||
|
|
||||||
const uint64 block_payload_size = 4 + frame->length();
|
|
||||||
const uint64 block_elem_size =
|
|
||||||
EbmlMasterElementSize(libwebm::kMkvBlock, block_payload_size) +
|
|
||||||
block_payload_size;
|
|
||||||
|
|
||||||
const uint64 block_group_payload_size =
|
|
||||||
block_elem_size + block_additions_elem_size + block_duration_elem_size +
|
|
||||||
discard_padding_elem_size + reference_block_elem_size;
|
|
||||||
|
|
||||||
if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockGroup,
|
|
||||||
block_group_payload_size)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlock, block_payload_size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, frame->track_number()))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (SerializeInt(writer, timecode, 2))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// For a Block, flags is always 0.
|
|
||||||
if (SerializeInt(writer, 0, 1))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (writer->Write(frame->frame(), static_cast<uint32>(frame->length())))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (frame->additional()) {
|
|
||||||
if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockAdditions,
|
|
||||||
block_additions_payload_size)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockMore,
|
|
||||||
block_more_payload_size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!WriteEbmlElement(writer, libwebm::kMkvBlockAddID,
|
|
||||||
static_cast<uint64>(frame->add_id())))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!WriteEbmlElement(writer, libwebm::kMkvBlockAdditional,
|
|
||||||
frame->additional(), frame->additional_length())) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame->discard_padding() != 0 &&
|
|
||||||
!WriteEbmlElement(writer, libwebm::kMkvDiscardPadding,
|
|
||||||
static_cast<int64>(frame->discard_padding()))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!frame->is_key() && !WriteEbmlElement(writer, libwebm::kMkvReferenceBlock,
|
|
||||||
reference_block_timestamp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (duration > 0 &&
|
|
||||||
!WriteEbmlElement(writer, libwebm::kMkvBlockDuration, duration)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return EbmlMasterElementSize(libwebm::kMkvBlockGroup,
|
|
||||||
block_group_payload_size) +
|
|
||||||
block_group_payload_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 WriteSimpleBlock(IMkvWriter* writer, const Frame* const frame,
|
|
||||||
int64 timecode) {
|
|
||||||
if (WriteID(writer, libwebm::kMkvSimpleBlock))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const int32 size = static_cast<int32>(frame->length()) + 4;
|
|
||||||
if (WriteUInt(writer, size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, static_cast<uint64>(frame->track_number())))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (SerializeInt(writer, timecode, 2))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint64 flags = 0;
|
|
||||||
if (frame->is_key())
|
|
||||||
flags |= 0x80;
|
|
||||||
|
|
||||||
if (SerializeInt(writer, flags, 1))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (writer->Write(frame->frame(), static_cast<uint32>(frame->length())))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return GetUIntSize(libwebm::kMkvSimpleBlock) + GetCodedUIntSize(size) + 4 +
|
|
||||||
frame->length();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
int32 GetCodedUIntSize(uint64 value) {
|
|
||||||
if (value < 0x000000000000007FULL)
|
|
||||||
return 1;
|
|
||||||
else if (value < 0x0000000000003FFFULL)
|
|
||||||
return 2;
|
|
||||||
else if (value < 0x00000000001FFFFFULL)
|
|
||||||
return 3;
|
|
||||||
else if (value < 0x000000000FFFFFFFULL)
|
|
||||||
return 4;
|
|
||||||
else if (value < 0x00000007FFFFFFFFULL)
|
|
||||||
return 5;
|
|
||||||
else if (value < 0x000003FFFFFFFFFFULL)
|
|
||||||
return 6;
|
|
||||||
else if (value < 0x0001FFFFFFFFFFFFULL)
|
|
||||||
return 7;
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 GetUIntSize(uint64 value) {
|
|
||||||
if (value < 0x0000000000000100ULL)
|
|
||||||
return 1;
|
|
||||||
else if (value < 0x0000000000010000ULL)
|
|
||||||
return 2;
|
|
||||||
else if (value < 0x0000000001000000ULL)
|
|
||||||
return 3;
|
|
||||||
else if (value < 0x0000000100000000ULL)
|
|
||||||
return 4;
|
|
||||||
else if (value < 0x0000010000000000ULL)
|
|
||||||
return 5;
|
|
||||||
else if (value < 0x0001000000000000ULL)
|
|
||||||
return 6;
|
|
||||||
else if (value < 0x0100000000000000ULL)
|
|
||||||
return 7;
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 GetIntSize(int64 value) {
|
|
||||||
// Doubling the requested value ensures positive values with their high bit
|
|
||||||
// set are written with 0-padding to avoid flipping the signedness.
|
|
||||||
const uint64 v = (value < 0) ? value ^ -1LL : value;
|
|
||||||
return GetUIntSize(2 * v);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlMasterElementSize(uint64 type, uint64 value) {
|
|
||||||
// Size of EBML ID
|
|
||||||
int32 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += GetCodedUIntSize(value);
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, int64 value) {
|
|
||||||
// Size of EBML ID
|
|
||||||
int32 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += GetIntSize(value);
|
|
||||||
|
|
||||||
// Size of Datasize
|
|
||||||
ebml_size++;
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, uint64 value) {
|
|
||||||
return EbmlElementSize(type, value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, uint64 value, uint64 fixed_size) {
|
|
||||||
// Size of EBML ID
|
|
||||||
uint64 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += (fixed_size > 0) ? fixed_size : GetUIntSize(value);
|
|
||||||
|
|
||||||
// Size of Datasize
|
|
||||||
ebml_size++;
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, float /* value */) {
|
|
||||||
// Size of EBML ID
|
|
||||||
uint64 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += sizeof(float);
|
|
||||||
|
|
||||||
// Size of Datasize
|
|
||||||
ebml_size++;
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, const char* value) {
|
|
||||||
if (!value)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Size of EBML ID
|
|
||||||
uint64 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += strlen(value);
|
|
||||||
|
|
||||||
// Size of Datasize
|
|
||||||
ebml_size += GetCodedUIntSize(strlen(value));
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) {
|
|
||||||
if (!value)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Size of EBML ID
|
|
||||||
uint64 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += size;
|
|
||||||
|
|
||||||
// Size of Datasize
|
|
||||||
ebml_size += GetCodedUIntSize(size);
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 EbmlDateElementSize(uint64 type) {
|
|
||||||
// Size of EBML ID
|
|
||||||
uint64 ebml_size = GetUIntSize(type);
|
|
||||||
|
|
||||||
// Datasize
|
|
||||||
ebml_size += kDateElementSize;
|
|
||||||
|
|
||||||
// Size of Datasize
|
|
||||||
ebml_size++;
|
|
||||||
|
|
||||||
return ebml_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) {
|
|
||||||
if (!writer || size < 1 || size > 8)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (int32 i = 1; i <= size; ++i) {
|
|
||||||
const int32 byte_count = size - i;
|
|
||||||
const int32 bit_count = byte_count * 8;
|
|
||||||
|
|
||||||
const int64 bb = value >> bit_count;
|
|
||||||
const uint8 b = static_cast<uint8>(bb);
|
|
||||||
|
|
||||||
const int32 status = writer->Write(&b, 1);
|
|
||||||
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 SerializeFloat(IMkvWriter* writer, float f) {
|
|
||||||
if (!writer)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
assert(sizeof(uint32) == sizeof(float));
|
|
||||||
// This union is merely used to avoid a reinterpret_cast from float& to
|
|
||||||
// uint32& which will result in violation of strict aliasing.
|
|
||||||
union U32 {
|
|
||||||
uint32 u32;
|
|
||||||
float f;
|
|
||||||
} value;
|
|
||||||
value.f = f;
|
|
||||||
|
|
||||||
for (int32 i = 1; i <= 4; ++i) {
|
|
||||||
const int32 byte_count = 4 - i;
|
|
||||||
const int32 bit_count = byte_count * 8;
|
|
||||||
|
|
||||||
const uint8 byte = static_cast<uint8>(value.u32 >> bit_count);
|
|
||||||
|
|
||||||
const int32 status = writer->Write(&byte, 1);
|
|
||||||
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 WriteUInt(IMkvWriter* writer, uint64 value) {
|
|
||||||
if (!writer)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int32 size = GetCodedUIntSize(value);
|
|
||||||
|
|
||||||
return WriteUIntSize(writer, value, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size) {
|
|
||||||
if (!writer || size < 0 || size > 8)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (size > 0) {
|
|
||||||
const uint64 bit = 1LL << (size * 7);
|
|
||||||
|
|
||||||
if (value > (bit - 2))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
value |= bit;
|
|
||||||
} else {
|
|
||||||
size = 1;
|
|
||||||
int64 bit;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
bit = 1LL << (size * 7);
|
|
||||||
const uint64 max = bit - 2;
|
|
||||||
|
|
||||||
if (value <= max)
|
|
||||||
break;
|
|
||||||
|
|
||||||
++size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size > 8)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
value |= bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SerializeInt(writer, value, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 WriteID(IMkvWriter* writer, uint64 type) {
|
|
||||||
if (!writer)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
writer->ElementStartNotify(type, writer->Position());
|
|
||||||
|
|
||||||
const int32 size = GetUIntSize(type);
|
|
||||||
|
|
||||||
return SerializeInt(writer, type, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 type, uint64 size) {
|
|
||||||
if (!writer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) {
|
|
||||||
return WriteEbmlElement(writer, type, value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value,
|
|
||||||
uint64 fixed_size) {
|
|
||||||
if (!writer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint64 size = GetUIntSize(value);
|
|
||||||
if (fixed_size > 0) {
|
|
||||||
if (size > fixed_size)
|
|
||||||
return false;
|
|
||||||
size = fixed_size;
|
|
||||||
}
|
|
||||||
if (WriteUInt(writer, size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (SerializeInt(writer, value, static_cast<int32>(size)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, int64 value) {
|
|
||||||
if (!writer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const uint64 size = GetIntSize(value);
|
|
||||||
if (WriteUInt(writer, size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (SerializeInt(writer, value, static_cast<int32>(size)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value) {
|
|
||||||
if (!writer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, 4))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (SerializeFloat(writer, value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value) {
|
|
||||||
if (!writer || !value)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const uint64 length = strlen(value);
|
|
||||||
if (WriteUInt(writer, length))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (writer->Write(value, static_cast<uint32>(length)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const uint8* value,
|
|
||||||
uint64 size) {
|
|
||||||
if (!writer || !value || size < 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, size))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (writer->Write(value, static_cast<uint32>(size)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value) {
|
|
||||||
if (!writer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteID(writer, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, kDateElementSize))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (SerializeInt(writer, value, kDateElementSize))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 WriteFrame(IMkvWriter* writer, const Frame* const frame,
|
|
||||||
Cluster* cluster) {
|
|
||||||
if (!writer || !frame || !frame->IsValid() || !cluster ||
|
|
||||||
!cluster->timecode_scale())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Technically the timecode for a block can be less than the
|
|
||||||
// timecode for the cluster itself (remember that block timecode
|
|
||||||
// is a signed, 16-bit integer). However, as a simplification we
|
|
||||||
// only permit non-negative cluster-relative timecodes for blocks.
|
|
||||||
const int64 relative_timecode = cluster->GetRelativeTimecode(
|
|
||||||
frame->timestamp() / cluster->timecode_scale());
|
|
||||||
if (relative_timecode < 0 || relative_timecode > kMaxBlockTimecode)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return frame->CanBeSimpleBlock()
|
|
||||||
? WriteSimpleBlock(writer, frame, relative_timecode)
|
|
||||||
: WriteBlock(writer, frame, relative_timecode,
|
|
||||||
cluster->timecode_scale());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
|
|
||||||
if (!writer)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Subtract one for the void ID and the coded size.
|
|
||||||
uint64 void_entry_size = size - 1 - GetCodedUIntSize(size - 1);
|
|
||||||
uint64 void_size = EbmlMasterElementSize(libwebm::kMkvVoid, void_entry_size) +
|
|
||||||
void_entry_size;
|
|
||||||
|
|
||||||
if (void_size != size)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const int64 payload_position = writer->Position();
|
|
||||||
if (payload_position < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (WriteID(writer, libwebm::kMkvVoid))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (WriteUInt(writer, void_entry_size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const uint8 value = 0;
|
|
||||||
for (int32 i = 0; i < static_cast<int32>(void_entry_size); ++i) {
|
|
||||||
if (writer->Write(&value, 1))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int64 stop_position = writer->Position();
|
|
||||||
if (stop_position < 0 ||
|
|
||||||
stop_position - payload_position != static_cast<int64>(void_size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return void_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetVersion(int32_t* major, int32_t* minor, int32_t* build, int32_t* revision) {
|
|
||||||
*major = 0;
|
|
||||||
*minor = 3;
|
|
||||||
*build = 3;
|
|
||||||
*revision = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 MakeUID(unsigned int* seed) {
|
|
||||||
uint64 uid = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < 7; ++i) { // avoid problems with 8-byte values
|
|
||||||
uid <<= 8;
|
|
||||||
|
|
||||||
// TODO(fgalligan): Move random number generation to platform specific code.
|
|
||||||
#ifdef _WIN32
|
|
||||||
(void)seed;
|
|
||||||
const int32 nn = rand();
|
|
||||||
#elif defined(__ANDROID__)
|
|
||||||
(void)seed;
|
|
||||||
int32 temp_num = 1;
|
|
||||||
int fd = open("/dev/urandom", O_RDONLY);
|
|
||||||
if (fd != -1) {
|
|
||||||
read(fd, &temp_num, sizeof(temp_num));
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
const int32 nn = temp_num;
|
|
||||||
#else
|
|
||||||
const int32 nn = rand_r(seed);
|
|
||||||
#endif
|
|
||||||
const int32 n = 0xFF & (nn >> 4); // throw away low-order bits
|
|
||||||
|
|
||||||
uid |= n;
|
|
||||||
}
|
|
||||||
|
|
||||||
return uid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsMatrixCoefficientsValueValid(uint64_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case mkvmuxer::Colour::kGbr:
|
|
||||||
case mkvmuxer::Colour::kBt709:
|
|
||||||
case mkvmuxer::Colour::kUnspecifiedMc:
|
|
||||||
case mkvmuxer::Colour::kReserved:
|
|
||||||
case mkvmuxer::Colour::kFcc:
|
|
||||||
case mkvmuxer::Colour::kBt470bg:
|
|
||||||
case mkvmuxer::Colour::kSmpte170MMc:
|
|
||||||
case mkvmuxer::Colour::kSmpte240MMc:
|
|
||||||
case mkvmuxer::Colour::kYcocg:
|
|
||||||
case mkvmuxer::Colour::kBt2020NonConstantLuminance:
|
|
||||||
case mkvmuxer::Colour::kBt2020ConstantLuminance:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsChromaSitingHorzValueValid(uint64_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case mkvmuxer::Colour::kUnspecifiedCsh:
|
|
||||||
case mkvmuxer::Colour::kLeftCollocated:
|
|
||||||
case mkvmuxer::Colour::kHalfCsh:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsChromaSitingVertValueValid(uint64_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case mkvmuxer::Colour::kUnspecifiedCsv:
|
|
||||||
case mkvmuxer::Colour::kTopCollocated:
|
|
||||||
case mkvmuxer::Colour::kHalfCsv:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsColourRangeValueValid(uint64_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case mkvmuxer::Colour::kUnspecifiedCr:
|
|
||||||
case mkvmuxer::Colour::kBroadcastRange:
|
|
||||||
case mkvmuxer::Colour::kFullRange:
|
|
||||||
case mkvmuxer::Colour::kMcTcDefined:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsTransferCharacteristicsValueValid(uint64_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case mkvmuxer::Colour::kIturBt709Tc:
|
|
||||||
case mkvmuxer::Colour::kUnspecifiedTc:
|
|
||||||
case mkvmuxer::Colour::kReservedTc:
|
|
||||||
case mkvmuxer::Colour::kGamma22Curve:
|
|
||||||
case mkvmuxer::Colour::kGamma28Curve:
|
|
||||||
case mkvmuxer::Colour::kSmpte170MTc:
|
|
||||||
case mkvmuxer::Colour::kSmpte240MTc:
|
|
||||||
case mkvmuxer::Colour::kLinear:
|
|
||||||
case mkvmuxer::Colour::kLog:
|
|
||||||
case mkvmuxer::Colour::kLogSqrt:
|
|
||||||
case mkvmuxer::Colour::kIec6196624:
|
|
||||||
case mkvmuxer::Colour::kIturBt1361ExtendedColourGamut:
|
|
||||||
case mkvmuxer::Colour::kIec6196621:
|
|
||||||
case mkvmuxer::Colour::kIturBt202010bit:
|
|
||||||
case mkvmuxer::Colour::kIturBt202012bit:
|
|
||||||
case mkvmuxer::Colour::kSmpteSt2084:
|
|
||||||
case mkvmuxer::Colour::kSmpteSt4281Tc:
|
|
||||||
case mkvmuxer::Colour::kAribStdB67Hlg:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsPrimariesValueValid(uint64_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case mkvmuxer::Colour::kReservedP0:
|
|
||||||
case mkvmuxer::Colour::kIturBt709P:
|
|
||||||
case mkvmuxer::Colour::kUnspecifiedP:
|
|
||||||
case mkvmuxer::Colour::kReservedP3:
|
|
||||||
case mkvmuxer::Colour::kIturBt470M:
|
|
||||||
case mkvmuxer::Colour::kIturBt470Bg:
|
|
||||||
case mkvmuxer::Colour::kSmpte170MP:
|
|
||||||
case mkvmuxer::Colour::kSmpte240MP:
|
|
||||||
case mkvmuxer::Colour::kFilm:
|
|
||||||
case mkvmuxer::Colour::kIturBt2020:
|
|
||||||
case mkvmuxer::Colour::kSmpteSt4281P:
|
|
||||||
case mkvmuxer::Colour::kJedecP22Phosphors:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mkvmuxer
|
|
||||||
#endif // ESP32
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user