mirror of https://github.com/arendst/Tasmota.git
Merge branch 'development' of https://github.com/arendst/Sonoff-Tasmota into colorpicker
This commit is contained in:
commit
a1dc8465bb
|
@ -12,6 +12,8 @@ tasmota/user_config_override.h
|
|||
build
|
||||
firmware.map
|
||||
firmware.asm
|
||||
tasmota*.bin
|
||||
tasmota*.map
|
||||
|
||||
## Visual Studio Code specific ######
|
||||
.vscode
|
||||
|
|
|
@ -163,7 +163,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||
| USE_BUZZER | - | - | x | x | x | - | - |
|
||||
| USE_ARILUX_RF | - | - | x | x | x | - | - |
|
||||
| USE_SHUTTER | - | - | - | - | - | - | - |
|
||||
| USE_DEEPSLEEP | - | - | - | - | - | - | - |
|
||||
| USE_DEEPSLEEP | - | - | x | - | x | - | - |
|
||||
| USE_EXS_DIMMER | - | - | x | x | - | - | - |
|
||||
| | | | | | | | |
|
||||
| Feature or Sensor | minimal | basic | tasmota | knx | sensors | ir | display | Remarks
|
||||
|
@ -276,11 +276,11 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||
|
||||
- Remove update support for versions before 6.0
|
||||
- Remove driver xsns_12_ads1115_i2cdev replaced by xsns_12_ads1115
|
||||
- Remove most IR protocols from non dedicated IR firmware except NEC, RC5 and RC6
|
||||
- Change repository name from Sonoff-Tasmota to Tasmota and all code references from Sonoff to Tasmota
|
||||
- Change default GUI to dark theme
|
||||
- Change ArduinoSlave to TasmotaSlave
|
||||
- Change IRremoteESP8266 library to v2.7.0
|
||||
- Change supported IR protocols in non dedicated IR firmware to NEC, RC5 and RC6 only
|
||||
- Change supported PCF8574 I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
|
||||
- Change supported PCF8574A I2C address range to 0x39 - 0x3F allowing other I2C devices with address 0x38 to be used at the same time
|
||||
- Change supported MCP230xx I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
|
||||
|
@ -291,12 +291,13 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
|||
- Add support for Honeywell I2C HIH series Humidity and Temperetaure sensor (#6808)
|
||||
- Add support for Honeywell HPMA115S0 particle concentration sensor by David Hunt (#6843)
|
||||
- Add support for I2C sensor TLS2591 Light Intensity sensor (#6873)
|
||||
- Add command ``WebColor19`` to control color of Module and Name (#6811)
|
||||
- Add command ``SetOption73 0/1`` to re-enable HTTP Cross-Origin Resource Sharing (CORS) now default disabled (#6767)
|
||||
- Add command ``SetOption74 0/1`` to enable DS18x20 internal pull-up and remove define DS18B20_INTERNAL_PULLUP (#6795)
|
||||
- Add command ``SetOption75 0/1`` to switch between grouptopic (0) using fulltopic replacing %topic% or (1) is cmnd/\<grouptopic\> (#6779)
|
||||
- Add command ``SetOption76 0/1`` to enable incrementing bootcount when deepsleep is enabled (#6930)
|
||||
- Add command ``I2cDriver`` for I2C driver runtime control using document I2CDEVICES.md
|
||||
- Add command ``TempOffset -12.6 .. 12.6`` to set global temperature sensor offset (#6958)
|
||||
- Add command ``WebColor19`` to control color of Module and Name (#6811)
|
||||
- Add command ``WifiPower 0 .. 20.5`` to set Wifi Output Power which will be default set to 17dBm
|
||||
- Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778)
|
||||
- Add hide Alexa objects with friendlyname starting with '$' (#6722, #6762)
|
||||
|
|
|
@ -127,7 +127,7 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||
if (_client->connected()) {
|
||||
result = 1;
|
||||
} else {
|
||||
if (domain != NULL) {
|
||||
if (domain.length() != 0) {
|
||||
result = _client->connect(this->domain.c_str(), this->port);
|
||||
} else {
|
||||
result = _client->connect(this->ip, this->port);
|
||||
|
@ -321,9 +321,10 @@ boolean PubSubClient::loop() {
|
|||
} else {
|
||||
buffer[0] = MQTTPINGREQ;
|
||||
buffer[1] = 0;
|
||||
_client->write(buffer,2);
|
||||
lastOutActivity = t;
|
||||
lastInActivity = t;
|
||||
if (_client->write(buffer,2) != 0) {
|
||||
lastOutActivity = t;
|
||||
lastInActivity = t;
|
||||
}
|
||||
pingOutstanding = true;
|
||||
}
|
||||
}
|
||||
|
@ -351,9 +352,9 @@ boolean PubSubClient::loop() {
|
|||
buffer[1] = 2;
|
||||
buffer[2] = (msgId >> 8);
|
||||
buffer[3] = (msgId & 0xFF);
|
||||
_client->write(buffer,4);
|
||||
lastOutActivity = t;
|
||||
|
||||
if (_client->write(buffer,4) != 0) {
|
||||
lastOutActivity = t;
|
||||
}
|
||||
} else {
|
||||
payload = buffer+llen+3+tl;
|
||||
callback(topic,payload,len-llen-3-tl);
|
||||
|
@ -456,11 +457,12 @@ boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsig
|
|||
for (i=0;i<plength;i++) {
|
||||
rc += _client->write((char)pgm_read_byte_near(payload + i));
|
||||
}
|
||||
|
||||
lastOutActivity = millis();
|
||||
if (rc > 0) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
|
||||
// Header (1 byte) + llen + identifier (2 bytes) + topic len + payload len
|
||||
const int expectedLength = 1 + llen + 2 + tlen + plength;
|
||||
const unsigned int expectedLength = 1 + llen + 2 + tlen + plength;
|
||||
return (rc == expectedLength);
|
||||
}
|
||||
|
||||
|
@ -475,7 +477,9 @@ boolean PubSubClient::beginPublish(const char* topic, unsigned int plength, bool
|
|||
}
|
||||
size_t hlen = buildHeader(header, buffer, plength+length-MQTT_MAX_HEADER_SIZE);
|
||||
uint16_t rc = _client->write(buffer+(MQTT_MAX_HEADER_SIZE-hlen),length-(MQTT_MAX_HEADER_SIZE-hlen));
|
||||
lastOutActivity = millis();
|
||||
if (rc > 0) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
return (rc == (length-(MQTT_MAX_HEADER_SIZE-hlen)));
|
||||
}
|
||||
return false;
|
||||
|
@ -486,19 +490,27 @@ int PubSubClient::endPublish() {
|
|||
}
|
||||
|
||||
size_t PubSubClient::write(uint8_t data) {
|
||||
lastOutActivity = millis();
|
||||
if (_client == nullptr) {
|
||||
return 0;
|
||||
lastOutActivity = millis();
|
||||
return 0;
|
||||
}
|
||||
return _client->write(data);
|
||||
size_t rc = _client->write(data);
|
||||
if (rc != 0) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
|
||||
lastOutActivity = millis();
|
||||
if (_client == nullptr) {
|
||||
return 0;
|
||||
lastOutActivity = millis();
|
||||
return 0;
|
||||
}
|
||||
return _client->write(buffer,size);
|
||||
size_t rc = _client->write(buffer,size);
|
||||
if (rc != 0) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
size_t PubSubClient::buildHeader(uint8_t header, uint8_t* buf, uint16_t length) {
|
||||
|
@ -544,7 +556,9 @@ boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
|||
return result;
|
||||
#else
|
||||
rc = _client->write(buf+(MQTT_MAX_HEADER_SIZE-hlen),length+hlen);
|
||||
lastOutActivity = millis();
|
||||
if (rc != 0) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
return (rc == hlen+length);
|
||||
#endif
|
||||
}
|
||||
|
@ -623,22 +637,19 @@ uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t po
|
|||
|
||||
|
||||
boolean PubSubClient::connected() {
|
||||
boolean rc;
|
||||
if (_client == NULL ) {
|
||||
rc = false;
|
||||
} else {
|
||||
rc = (int)_client->connected();
|
||||
if (!rc) {
|
||||
if (this->_state == MQTT_CONNECTED) {
|
||||
this->_state = MQTT_CONNECTION_LOST;
|
||||
_client->flush();
|
||||
_client->stop();
|
||||
}
|
||||
} else {
|
||||
return this->_state == MQTT_CONNECTED;
|
||||
}
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
return false;
|
||||
}
|
||||
return rc;
|
||||
if (_client->connected() == 0) {
|
||||
bool lastStateConnected = this->_state == MQTT_CONNECTED;
|
||||
this->disconnect();
|
||||
if (lastStateConnected) {
|
||||
this->_state = MQTT_CONNECTION_LOST;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return this->_state == MQTT_CONNECTED;
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
|
||||
|
|
|
@ -127,12 +127,12 @@ build_flags = ${esp82xx_defaults.build_flags}
|
|||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221
|
||||
; NONOSDK22x_190313
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190313
|
||||
; NONOSDK22x_190703
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
|
||||
; NONOSDK22x_191024
|
||||
; NONOSDK22x_190703 = 2.2.2-dev(38a443e) (Tasmota default)
|
||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
|
||||
; NONOSDK22x_191024 = 2.2.2-dev(5ab15d1)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191024
|
||||
; NONOSDK22x_191105 (Tasmota default)
|
||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
|
||||
; NONOSDK22x_191105 = 2.2.2-dev(bb83b9b)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
|
||||
; NONOSDK3V0 (known issues)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK3
|
||||
; lwIP 1.4
|
||||
|
@ -173,12 +173,12 @@ build_flags = ${esp82xx_defaults.build_flags}
|
|||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221
|
||||
; NONOSDK22x_190313
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190313
|
||||
; NONOSDK22x_190703
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
|
||||
; NONOSDK22x_191024
|
||||
; NONOSDK22x_190703 = 2.2.2-dev(38a443e) (Tasmota default)
|
||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
|
||||
; NONOSDK22x_191024 = 2.2.2-dev(5ab15d1)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191024
|
||||
; NONOSDK22x_191105 (Tasmota default)
|
||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
|
||||
; NONOSDK22x_191105 = 2.2.2-dev(bb83b9b)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
|
||||
; NONOSDK3V0 (known issues)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK3
|
||||
; lwIP 1.4
|
||||
|
|
755
scripter.md
755
scripter.md
|
@ -1,755 +0,0 @@
|
|||
**Script Language for Tasmota**
|
||||
|
||||
As an alternative to rules. (about 17k flash size, variable ram size)
|
||||
|
||||
In submenu Configuration =\> edit script
|
||||
1535 bytes max script size (uses rules buffer)
|
||||
|
||||
to enable:
|
||||
\#define USE_SCRIPT
|
||||
\#undef USE_RULES
|
||||
|
||||
|
||||
Up to 50 variables (45 numeric and 5 strings, maybe changed by #define)
|
||||
Freely definable variable names (all names are intentionally case sensitive)
|
||||
Nested if,then,else up to a level of 8
|
||||
Math operators **+,-,\*,/,%,&,|,^**
|
||||
all operators may be used in the op= form e.g. **+=**
|
||||
Left right evaluation with optional brackets
|
||||
all numbers are float
|
||||
e.g. temp=hum\*(100/37.5)+temp-(timer\*hum%10)
|
||||
no spaces allowed between math operations
|
||||
Comparison operators **==,!=,\>,\>=,<,<=**
|
||||
**and** , **or** support
|
||||
hexadecimal numbers are supported with prefix 0x
|
||||
|
||||
strings support **+** and **+=** operators
|
||||
string comparison **==,!=**
|
||||
max string size = 19 chars (default, can be increased or decreased by optional >D parameter)
|
||||
|
||||
**Comments** start with **;**
|
||||
|
||||
**Sections** defined:
|
||||
|
||||
>**\>D ssize**
|
||||
ssize = optional max stringsize (default=19)
|
||||
define and init variables here, must be the first section, no other code allowed
|
||||
**p:**vname specifies permanent vars (the number of permanent vars is limited by tasmota rules space (50 bytes)
|
||||
numeric var=4 bytes, string var=lenght of string+1)
|
||||
**t:**vname specifies countdown timers, if >0 they are decremented in seconds until zero is reached. see example below
|
||||
**i:**vname specifies auto increment counters if >=0 (in seconds)
|
||||
**m:**vname specifies a median filter variable with 5 entries (for elimination of outliers)
|
||||
**M:**vname specifies a moving average filter variable with 8 entries (for smoothing data)
|
||||
(max 5 filters in total m+M) optional another filter lenght (1..127) can be given after the definition.
|
||||
filter vars can be accessed also in indexed mode vname[x] (index = 1...N, index 0 returns current array index pointer)
|
||||
by this filter vars can be used as arrays
|
||||
|
||||
>all variable names length taken together may not exceed 256 characters, so keep variable names as short as possible.
|
||||
memory is dynamically allocated as a result of the D section.
|
||||
copying a string to a number or reverse is supported
|
||||
|
||||
>**\>B**
|
||||
executed on BOOT time and script save
|
||||
|
||||
>**\>T**
|
||||
executed on teleperiod time (**SENSOR** and **STATE**), get tele vars only in this section
|
||||
remark: json variable names (like all others) may not contain math operators like - , you should set setoption64 1 to replace - with underscore
|
||||
|
||||
>**\>F**
|
||||
executed every 100 ms
|
||||
|
||||
>**\>S**
|
||||
executed every second
|
||||
|
||||
>**\>E**
|
||||
executed e.g. on power change and mqtt **RESULT**
|
||||
|
||||
>**\>R**
|
||||
executed on restart, p vars are saved automatically after this call
|
||||
|
||||
|
||||
special variables (read only):
|
||||
|
||||
>**upsecs** = seconds since start
|
||||
**uptime** = minutes since start
|
||||
**time** = minutes since midnight
|
||||
**sunrise** = sunrise minutes since midnight
|
||||
**sunset** = sunset minutes since midnight
|
||||
**tper** = teleperiod (may be set also)
|
||||
**tstamp** = timestamp (local date and time)
|
||||
**topic** = mqtt topic
|
||||
**gtopic** = mqtt group topic
|
||||
**prefixn** = prefix n = 1-3
|
||||
**pwr[x]** = tasmota power state (x = 1-N)
|
||||
**pc[x]** = tasmota pulse counter value (x = 1-4)
|
||||
**tbut[x]** = touch screen button state (x = 1-N)
|
||||
**sw[x]** = tasmota switch state (x = 1-N)
|
||||
>**pin[x]** = gpio pin level (x = 0-16)
|
||||
**pn[x]** = pin number for sensor code x, 99 if none
|
||||
**pd[x]** = defined sensor for gpio pin nr x none=999
|
||||
**gtmp** = global temperature
|
||||
**ghum** = global humidity
|
||||
**gprs** = global pressure
|
||||
**pow(x y)** = calculates the power of x^y
|
||||
**med(n x)** = calculates a 5 value median filter of x (2 filters possible n=0,1)
|
||||
**int(x)** = gets the integer part of x (like floor)
|
||||
**hn(x)** = converts x (0..255) to a hex nibble string
|
||||
**st(svar c n)** = stringtoken gets the n th substring of svar separated by c
|
||||
**sl(svar)** = gets the length of a string
|
||||
**sb(svar p n)** = gets a substring from svar at position p (if p<0 counts from end) and length n
|
||||
**s(x)** = explicit conversion from number x to string
|
||||
**mqtts** = state of mqtt disconnected=0, connected>0
|
||||
**wifis** = state of wifi disconnected=0, connected>0
|
||||
|
||||
>**hours** = hours
|
||||
**mins** = mins
|
||||
**secs** = seconds
|
||||
**day** = day of month
|
||||
**wday** = day of week
|
||||
**month** = month
|
||||
**year** = year
|
||||
|
||||
these variables are cleared after reading true
|
||||
>**chg[var]** = true if a variables value was changed (numeric vars only)
|
||||
**upd[var]** = true if a variable was updated
|
||||
**boot** = true on BOOT
|
||||
**tinit** = true on time init
|
||||
**tset** = true on time set
|
||||
**mqttc** = true on mqtt connect
|
||||
**mqttd** = true on mqtt disconnect
|
||||
**wific** = true on wifi connect
|
||||
**wifid** = true on wifi disconnect
|
||||
|
||||
system vars (for debugging)
|
||||
>**stack** = stack size
|
||||
**heap** = heap size
|
||||
**ram** = used ram size
|
||||
**slen** = script length
|
||||
**micros** = running microseconds
|
||||
**millis** = running milliseconds
|
||||
**loglvl** = loglevel of script cmds, may be set also
|
||||
|
||||
remarks:
|
||||
if you define a variable with the same name as a special
|
||||
variable that special variable is discarded
|
||||
|
||||
|
||||
**Tasmota** cmds start with **=\>**
|
||||
within cmds you can replace text with variables with **%varname%**
|
||||
a single percent sign must be given as **%%**
|
||||
**->** is equivalent but doesnt send mqtt or any weblog (silent execute, usefull to reduce traffic)
|
||||
|
||||
**special** cmds:
|
||||
|
||||
>**print** or **=\>print** prints to info log for debugging
|
||||
|
||||
to save code space nearly no error messages are provided. However it is taken care of that at least it should not crash on syntax errors.
|
||||
if a variable does not exist a **???** is given on commands
|
||||
if a **SENSOR** or **STATUS** or **RESULT** message or a var does not exist the destination variable is NOT updated.
|
||||
|
||||
2 possibilities for conditionals:
|
||||
>**if** a==b
|
||||
**and** x==y
|
||||
**or** k==i
|
||||
**then** => do this
|
||||
**else** => do that
|
||||
**endif**
|
||||
|
||||
OR
|
||||
|
||||
>**if** a==b
|
||||
**and** x==y
|
||||
**or** k==i **{**
|
||||
=> do this
|
||||
**} else {**
|
||||
=> do that
|
||||
**}**
|
||||
|
||||
you may NOT mix both methods
|
||||
|
||||
also possible e.g.
|
||||
|
||||
>if var1-var2==var3*var4
|
||||
then
|
||||
|
||||
remarks:
|
||||
the last closing bracket must be on a single line
|
||||
the condition may be enclosed in brackets
|
||||
and on the same line conditions may be bracketed e.g. if ((a==b) and ((c==d) or (c==e)) and (s!="x"))
|
||||
|
||||
|
||||
>**break** exits a section or terminates a for next loop
|
||||
**dpx** sets decimal precision to x (0-9)
|
||||
**svars** save permanent vars
|
||||
**delay(x)** pauses x milliseconds (should be as short as possible)
|
||||
**spin(x m)** set gpio pin x (0-16) to value m (0,1) only the last bit is used, so even values set the pin to zero and uneven values set the pin to 1
|
||||
**spinm(x m)** set pin mode gpio pin x (0-16) to mode m (input=0,output=1,input with pullup=2)
|
||||
**ws2812(array)** copies an array (defined with m:name) to the WS2812 LED chain the array should be defined as long as the number of pixels. the color is coded as 24 bit RGB
|
||||
**hsvrgb(h s v)** converts hue (0-360), saturation (0-100) and value (0-100) to RGB color
|
||||
|
||||
>**#name** names a subroutine, subroutines are called with **=#name**
|
||||
**#name(param)** names a subroutines with a parameter is called with **=#name(param)**
|
||||
subroutines end with the next '#' or '>' line or break, may be nested
|
||||
params can be numbers or strings and on mismatch are converted
|
||||
**=(svar)** executes a script in a string variable (dynamic or self modifying code)
|
||||
|
||||
>**for var from to inc**
|
||||
**next**
|
||||
specifies a for next loop, (loop count must not be less then 1)
|
||||
|
||||
>**switch x**
|
||||
**case a**
|
||||
**case b**
|
||||
**ends**
|
||||
specifies a switch case selector (numeric or string)
|
||||
|
||||
**sd card support**
|
||||
enable by CARD_CS = gpio pin of card chip select (+ 10k flash)
|
||||
\#define USE_SCRIPT_FATFS CARD_CS
|
||||
sd card uses standard hardware spi gpios: mosi,miso,sclk
|
||||
max 4 files open at a time
|
||||
allows for e.g. logging sensors to a tab delimited file and then download (see example below)
|
||||
the download of files may be executed in a kind of "multitasking" when bit 7 of loglvl is set (128+loglevel)
|
||||
without multitasking 150kb/s (all processes are stopped during download), with multitasking 50kb/s (other tasmota processes are running)
|
||||
script itself is also stored on sdcard with a default size of 4096 chars
|
||||
|
||||
|
||||
enable sd card directory support (+ 1,2k flash)
|
||||
\#define SDCARD_DIR
|
||||
shows a web sdcard directory (submeu of scripter) where you can
|
||||
upload and download files to/from sd card
|
||||
|
||||
|
||||
>**fr=fo("fname" m)** open file fname, mode 0=read, 1=write (returns file reference (0-3) or -1 for error)
|
||||
**res=fw("text" fr)** writes text to (the end of) file fr, returns number of bytes written
|
||||
**res=fr(svar fr)** reads a string into svar, returns bytes read (string is read until delimiter \t \n \r or eof)
|
||||
**fc(fr)** close file
|
||||
**ff(fr)** flush file, writes cached data and updates directory
|
||||
**fd("fname")** delete file fname
|
||||
**flx(fname)** create download link for file (x=1 or 2) fname = file name of file to download
|
||||
**fsm** return 1 if filesystem is mounted, (valid sd card found)
|
||||
|
||||
extended commands (+0,9k flash)
|
||||
\#define USE_SCRIPT_FATFS_EXT
|
||||
>**fmd("fname")** make directory fname
|
||||
>**frd("fname")** remove directory fname
|
||||
>**fx("fname")** check if file fname exists
|
||||
>**fe("fname")** execute script fname (max 2048 bytes, script file must start with '>' char on the 1. line)
|
||||
|
||||
|
||||
**konsole script cmds**
|
||||
>**script 1 or 0** switch script on or off
|
||||
**script >cmdline** executes the script cmdline
|
||||
can be used e.g. to set variables e.g. **script >mintmp=15**
|
||||
more then one line may be executed seperated by a semicolon e.g. **script >mintmp=15;maxtemp=40**
|
||||
script itself cant be set because the size would not fit the mqtt buffers
|
||||
|
||||
**subscribe,unsubscribe**
|
||||
>if \#defined SUPPORT_MQTT_EVENT command subscribe and unsubscribe are supported. in contrast to rules no event is generated but the event name specifies a variable defined in D section and this variable is automatically set on transmission of the subscribed item
|
||||
|
||||
**summary of optional defines**
|
||||
>\#define USE_SCRIPT_FATFS CS_PIN : enables SD card support (on spi bus) also enables 4k script buffer
|
||||
\#define USE_SCRIPT_FATFS_EXT : enables additional FS commands
|
||||
\#define SDCARD_DIR : enables support for WEBUI for SD card directory up and download
|
||||
\#define USE_24C256 : enables use of 24C256 i2c eeprom to expand script buffer (defaults to 4k)
|
||||
\#define SUPPORT_MQTT_EVENT : enables support for subscribe unsubscribe
|
||||
\#define USE_TOUCH_BUTTONS : enable virtual touch button support with touch displays
|
||||
|
||||
|
||||
***example script***
|
||||
meant to show some of the possibilities
|
||||
(actually this code ist too large)
|
||||
|
||||
**\>D**
|
||||
; define all vars here
|
||||
p:mintmp=10 (p:means permanent)
|
||||
p:maxtmp=30
|
||||
t:timer1=30 (t:means countdown timer)
|
||||
t:mt=0
|
||||
i:count=0 (i:means auto counter)
|
||||
hello="hello world"
|
||||
string="xxx"
|
||||
url="[192.168.178.86]"
|
||||
hum=0
|
||||
temp=0
|
||||
timer=0
|
||||
dimmer=0
|
||||
sw=0
|
||||
rssi=0
|
||||
param=0
|
||||
|
||||
col=""
|
||||
ocol=""
|
||||
chan1=0
|
||||
chan2=0
|
||||
chan3=0
|
||||
|
||||
ahum=0
|
||||
atemp=0
|
||||
tcnt=0
|
||||
hour=0
|
||||
state=1
|
||||
m:med5=0
|
||||
M:movav=0
|
||||
; define array with 10 entries
|
||||
m:array=0 10
|
||||
|
||||
**\>B**
|
||||
|
||||
string=hello+"how are you?"
|
||||
=\>print BOOT executed
|
||||
=\>print %hello%
|
||||
=\>mp3track 1
|
||||
|
||||
; list gpio pin definitions
|
||||
for cnt 0 16 1
|
||||
tmp=pd[cnt]
|
||||
=>print %cnt% = %tmp%
|
||||
next
|
||||
|
||||
; get gpio pin for relais 1
|
||||
tmp=pn[21]
|
||||
=>print relais 1 is on pin %tmp%
|
||||
|
||||
; pulse relais over raw gpio
|
||||
spin(tmp 1)
|
||||
delay(100)
|
||||
spin(tmp 0)
|
||||
|
||||
; raw pin level
|
||||
=>print level of gpio1 %pin[1]%
|
||||
|
||||
; pulse over tasmota cmd
|
||||
=>power 1
|
||||
delay(100)
|
||||
=>power 0
|
||||
|
||||
**\>T**
|
||||
hum=BME280#Humidity
|
||||
temp=BME280#Temperature
|
||||
rssi=Wifi#RSSI
|
||||
string=SleepMode
|
||||
|
||||
; add to median filter
|
||||
median=temp
|
||||
; add to moving average filter
|
||||
movav=hum
|
||||
|
||||
; show filtered results
|
||||
=>print %median% %movav%
|
||||
|
||||
if chg[rssi]>0
|
||||
then =>print rssi changed to %rssi%
|
||||
endif
|
||||
|
||||
if temp\>30
|
||||
and hum\>70
|
||||
then =\>print damn hot!
|
||||
endif
|
||||
|
||||
**\>S**
|
||||
|
||||
; every second but not completely reliable time here
|
||||
; use upsecs and uptime or best t: for reliable timers
|
||||
|
||||
; arrays
|
||||
array[1]=4
|
||||
array[2]=5
|
||||
tmp=array[1]+array[2]
|
||||
|
||||
; call subrountines with parameters
|
||||
=#sub1("hallo")
|
||||
=#sub2(999)
|
||||
|
||||
; stop timer after expired
|
||||
if timer1==0
|
||||
then timer1=-1
|
||||
=>print timer1 expired
|
||||
endif
|
||||
|
||||
; auto counter with restart
|
||||
if count>=10
|
||||
then =>print 10 seconds over
|
||||
count=0
|
||||
endif
|
||||
|
||||
if upsecs%5==0
|
||||
then =\>print %upsecs% (every 5 seconds)
|
||||
endif
|
||||
|
||||
; not recommended for reliable timers
|
||||
timer+=1
|
||||
if timer\>=5
|
||||
then =\>print 5 seconds over (may be)
|
||||
timer=0
|
||||
endif
|
||||
|
||||
dimmer+=1
|
||||
if dimmer\>100
|
||||
then dimmer=0
|
||||
endif
|
||||
|
||||
=\>dimmer %dimmer%
|
||||
=\>WebSend %url% dimmer %dimmer%
|
||||
|
||||
; show on display
|
||||
dp0
|
||||
=\>displaytext [c1l1f1s2p20] dimmer=%dimmer%
|
||||
|
||||
=\>print %upsecs% %uptime% %time% %sunrise% %sunset% %tstamp%
|
||||
|
||||
if time\>sunset
|
||||
and time< sunrise
|
||||
then
|
||||
; night time
|
||||
if pwr[1]==0
|
||||
then =\>power1 1
|
||||
endif
|
||||
else
|
||||
; day time
|
||||
if pwr[1]\>0
|
||||
then =\>power1 0
|
||||
endif
|
||||
endif
|
||||
|
||||
; clr display on boot
|
||||
if boot\>0
|
||||
then =\>displaytext [z]
|
||||
endif
|
||||
|
||||
; frost warning
|
||||
if temp<0
|
||||
and mt<=0
|
||||
then =#sendmail("frost alert")
|
||||
; alarm only every 5 minutes
|
||||
mt=300
|
||||
=>mp3track 2
|
||||
endif
|
||||
|
||||
; var has been updated
|
||||
if upd[hello]>0
|
||||
then =>print %hello%
|
||||
endif
|
||||
|
||||
; send to Thingspeak every 60 seconds
|
||||
; average data in between
|
||||
if upsecs%60==0
|
||||
then
|
||||
ahum/=tcnt
|
||||
atemp/=tcnt
|
||||
=>Websend [184.106.153.149:80]/update?key=PYUZMVWCICBW492&field1=%atemp%&field2=%ahum%
|
||||
tcnt=0
|
||||
atemp=0
|
||||
ahum=0
|
||||
else
|
||||
ahum+=hum
|
||||
atemp+=temp
|
||||
tcnt+=1
|
||||
endif
|
||||
|
||||
hour=int(time/60)
|
||||
if chg[hour]>0
|
||||
then
|
||||
; exactly every hour
|
||||
=>print full hour reached
|
||||
endif
|
||||
|
||||
if time>5 {
|
||||
=>print more then 5 minutes after midnight
|
||||
} else {
|
||||
=>print less then 5 minutes after midnight
|
||||
}
|
||||
|
||||
|
||||
; publish abs hum every teleperiod time
|
||||
if mqtts>0
|
||||
and upsecs%tper==0
|
||||
then
|
||||
; calc abs humidity
|
||||
tmp=pow(2.718281828 (17.67\*temp)/(temp+243.5))
|
||||
tmp=(6.112\*tmp\*hum\*18.01534)/((273.15+temp)\*8.31447215)
|
||||
; publish median filtered value
|
||||
=>Publish tele/%topic%/SENSOR {"Script":{"abshum":%med(0 tmp)%}}
|
||||
endif
|
||||
|
||||
;switch case state machine
|
||||
switch state
|
||||
case 1
|
||||
=>print state=%state% , start
|
||||
state+=1
|
||||
case 2
|
||||
=>print state=%state%
|
||||
state+=1
|
||||
case 3
|
||||
=>print state=%state% , reset
|
||||
state=1
|
||||
ends
|
||||
|
||||
|
||||
; subroutines
|
||||
\#sub1(string)
|
||||
=>print sub1: %string%
|
||||
\#sub2(param)
|
||||
=>print sub2: %param%
|
||||
|
||||
\#sendmail(string)
|
||||
=>sendmail [smtp.gmail.com:465:user:passwd:<sender@gmail.de>:<rec@gmail.de>:alarm] %string%
|
||||
|
||||
**\>E**
|
||||
=\>print event executed!
|
||||
|
||||
; get HSBColor 1. component
|
||||
tmp=st(HSBColor , 1)
|
||||
|
||||
; check if switch changed state
|
||||
sw=sw[1]
|
||||
if chg[sw]>0
|
||||
then =\>power1 %sw%
|
||||
endif
|
||||
|
||||
hello="event occured"
|
||||
|
||||
; check for Color change (Color is a string)
|
||||
col=Color
|
||||
; color change needs 2 string vars
|
||||
if col!=ocol
|
||||
then ocol=col
|
||||
=>print color changed %col%
|
||||
endif
|
||||
|
||||
; or check change of color channels
|
||||
chan1=Channel[1]
|
||||
chan2=Channel[2]
|
||||
chan3=Channel[3]
|
||||
|
||||
if chg[chan1]>0
|
||||
or chg[chan2]>0
|
||||
or chg[chan3]>0
|
||||
then => color has changed
|
||||
endif
|
||||
|
||||
; compose color string for red
|
||||
col=hn(255)+hn(0)+hn(0)
|
||||
=>color %col%
|
||||
|
||||
**\>R**
|
||||
=\>print restarting now
|
||||
|
||||
**a log sensor example**
|
||||
; define all vars here
|
||||
; reserve large strings
|
||||
**\>D** 48
|
||||
hum=0
|
||||
temp=0
|
||||
fr=0
|
||||
res=0
|
||||
; moving average for 60 seconds
|
||||
M:mhum=0 60
|
||||
M:mtemp=0 60
|
||||
str=""
|
||||
|
||||
**\>B**
|
||||
; set sensor file download link
|
||||
fl1("slog.txt")
|
||||
; delete file in case we want to start fresh
|
||||
;fd("slog.txt")
|
||||
|
||||
|
||||
; list all files in root directory
|
||||
fr=fo("/" 0)
|
||||
for cnt 1 20 1
|
||||
res=fr(str fr)
|
||||
if res>0
|
||||
then
|
||||
=>print %cnt% : %str%
|
||||
else
|
||||
break
|
||||
endif
|
||||
next
|
||||
fc(fr)
|
||||
|
||||
|
||||
**\>T**
|
||||
; get sensor values
|
||||
temp=BME280#Temperature
|
||||
hum=BME280#Humidity
|
||||
|
||||
**\>S**
|
||||
; average sensor values every second
|
||||
mhum=hum
|
||||
mtemp=temp
|
||||
|
||||
; write average to sensor log every minute
|
||||
if upsecs%60==0
|
||||
then
|
||||
; open file for write
|
||||
fr=fo("slog.txt" 1)
|
||||
; compose string for tab delimited file entry
|
||||
str=s(upsecs)+"\t"+s(mhum)+"\t"+s(mtemp)+"\n"
|
||||
; write string to log file
|
||||
res=fw(str fr)
|
||||
; close file
|
||||
fc(fr)
|
||||
endif
|
||||
|
||||
**\>R**
|
||||
|
||||
|
||||
|
||||
**a real example**
|
||||
epaper 29 with sgp30 and bme280
|
||||
some vars are set from iobroker
|
||||
DisplayText substituted to save script space
|
||||
**\>D**
|
||||
hum=0
|
||||
temp=0
|
||||
press=0
|
||||
ahum=0
|
||||
tvoc=0
|
||||
eco2=0
|
||||
zwz=0
|
||||
wr1=0
|
||||
wr2=0
|
||||
wr3=0
|
||||
otmp=0
|
||||
pwl=0
|
||||
tmp=0
|
||||
DT="DisplayText"
|
||||
; preset units in case they are not available
|
||||
punit="hPa"
|
||||
tunit="C"
|
||||
|
||||
**\>B**
|
||||
;reset auto draw
|
||||
=>%DT% [zD0]
|
||||
;clr display and draw a frame
|
||||
=>%DT% [x0y20h296x0y40h296]
|
||||
|
||||
**\>T**
|
||||
; get tele vars
|
||||
temp=BME280#Temperature
|
||||
hum=BME280#Humidity
|
||||
press=BME280#Pressure
|
||||
tvoc=SGP30#TVOC
|
||||
eco2=SGP30#eCO2
|
||||
ahum=SGP30#aHumidity
|
||||
tunit=TempUnit
|
||||
punit=PressureUnit
|
||||
|
||||
**\>S**
|
||||
// update display every teleperiod time
|
||||
if upsecs%tper==0
|
||||
then
|
||||
dp2
|
||||
=>%DT% [f1p7x0y5]%temp% %tunit%
|
||||
=>%DT% [p5x70y5]%hum% %%[x250y5t]
|
||||
=>%DT% [p11x140y5]%press% %punit%
|
||||
=>%DT% [p10x30y25]TVOC: %tvoc% ppb
|
||||
=>%DT% [p10x160y25]eCO2: %eco2% ppm
|
||||
=>%DT% [p10c26l5]ahum: %ahum% g^m3
|
||||
|
||||
dp0
|
||||
=>%DT% [p25c1l5]WR 1 (Dach) : %wr1% W
|
||||
=>%DT% [p25c1l6]WR 2 (Garage): %-wr3% W
|
||||
=>%DT% [p25c1l7]WR 3 (Garten): %-wr2% W
|
||||
=>%DT% [p25c1l8]Aussentemperatur: %otmp% C
|
||||
=>%DT% [x170y95r120:30f2p6x185y100] %pwl% %%
|
||||
; now update screen
|
||||
=>%DT% [d]
|
||||
endif
|
||||
|
||||
|
||||
**\>E**
|
||||
|
||||
**\>R**
|
||||
|
||||
**another real example**
|
||||
ILI 9488 color LCD Display shows various energy graphs
|
||||
display switches on and off with proximity sensor
|
||||
BMP280 and vl5310x
|
||||
some vars are set from iobroker
|
||||
|
||||
**>D**
|
||||
temp=0
|
||||
press=0
|
||||
zwz=0
|
||||
wr1=0
|
||||
wr2=0
|
||||
wr3=0
|
||||
otmp=0
|
||||
pwl=0
|
||||
tmp=0
|
||||
dist=0
|
||||
DT="DisplayText"
|
||||
punit="hPa"
|
||||
tunit="C"
|
||||
hour=0
|
||||
|
||||
**>B**
|
||||
=>%DT% [z]
|
||||
|
||||
// define 2 graphs, 2. has 3 tracks
|
||||
=>%DT% [zCi1G2656:5:20:400:80:1440:-5000:5000:3Ci7f3x410y20]+5000 W[x410y95]-5000 W [Ci7f1x70y3] Zweirichtungsz~80hler - 24 Stunden
|
||||
=>%DT% [Ci1G2657:5:120:400:80:1440:0:5000:3Ci7f3x410y120]+5000 W[x410y195]0 W [Ci7f1x70y103] Wechselrichter 1-3 - 24 Stunden
|
||||
=>%DT% [Ci1G2658:5:120:400:80:1440:0:5000:16][Ci1G2659:5:120:400:80:1440:0:5000:5]
|
||||
=>%DT% [f1s1b0:260:260:100:50:2:11:4:2:Rel 1:b1:370:260:100:50:2:11:4:2:Dsp off:]
|
||||
=>mp3volume 100
|
||||
=>mp3track 4
|
||||
|
||||
**>T**
|
||||
; get some tele vars
|
||||
temp=BMP280#Temperature
|
||||
press=BMP280#Pressure
|
||||
tunit=TempUnit
|
||||
punit=PressureUnit
|
||||
dist=VL53L0X#Distance
|
||||
|
||||
; check proximity sensor to switch display on/off
|
||||
; to prevent burn in
|
||||
if dist>300
|
||||
then
|
||||
if pwr[2]>0
|
||||
then
|
||||
=>power2 0
|
||||
endif
|
||||
else
|
||||
if pwr[2]==0
|
||||
then
|
||||
=>power2 1
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
**>S**
|
||||
; update graph every teleperiod
|
||||
if upsecs%tper==0
|
||||
then
|
||||
dp2
|
||||
=>%DT% [f1Ci3x40y260w30Ci1]
|
||||
=>%DT% [Ci7x120y220t]
|
||||
=>%DT% [Ci7x180y220T]
|
||||
=>%DT% [Ci7p8x120y240]%temp% %tunit%
|
||||
=>%DT% [Ci7x120y260]%press% %punit%
|
||||
=>%DT% [Ci7x120y280]%dist% mm
|
||||
dp0
|
||||
=>%DT% [g0:%zwz%g1:%wr1%g2:%-wr2%g3:%-wr3%]
|
||||
if zwz>0
|
||||
then
|
||||
=>%DT% [p-8x410y55Ci2Bi0]%zwz% W
|
||||
else
|
||||
=>%DT% [p-8x410y55Ci3Bi0]%zwz% W
|
||||
endif
|
||||
=>%DT% [p-8x410y140Ci3Bi0]%wr1% W
|
||||
=>%DT% [p-8x410y155Ci16Bi0]%-wr2% W
|
||||
=>%DT% [p-8x410y170Ci5Bi0]%-wr3% W
|
||||
endif
|
||||
|
||||
; chime every full hour
|
||||
hour=int(time/60)
|
||||
if chg[hour]>0
|
||||
then =>mp3track 4
|
||||
endif
|
||||
|
||||
**>E**
|
||||
|
||||
**>R**
|
|
@ -1,4 +1,11 @@
|
|||
/*********************************************************************************************\
|
||||
* 7.0.0.5 20191118
|
||||
* Fix boot loop regression
|
||||
* Add command TempOffset -12.6 .. 12.6 to set global temperature sensor offset (#6958)
|
||||
* Fix check deepsleep for valid values in Settings (#6961)
|
||||
* Fix Wifi instability when light is on, due to sleep=0 (#6961, #6608)
|
||||
* Add hardware detection to be overruled with SetOption51 (#6969)
|
||||
*
|
||||
* 7.0.0.4 20191108
|
||||
* Add command WifiPower 0 .. 20.5 to set Wifi Output Power which will be default set to 17dBm
|
||||
* Change supported PCF8574 I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
|
||||
|
|
|
@ -290,6 +290,7 @@
|
|||
#define D_JSON_GPIO "GPIO"
|
||||
#define D_JSON_FLAG "FLAG"
|
||||
#define D_JSON_BASE "BASE"
|
||||
#define D_CMND_TEMPOFFSET "TempOffset"
|
||||
|
||||
// Commands xdrv_01_mqtt.ino
|
||||
#define D_CMND_MQTTLOG "MqttLog"
|
||||
|
|
|
@ -57,13 +57,13 @@
|
|||
#define D_AS "jak"
|
||||
#define D_AUTO "AUTO"
|
||||
#define D_BLINK "Miganie"
|
||||
#define D_BLINKOFF "MiganieWył"
|
||||
#define D_BOOT_COUNT "Licznik uruchomienia"
|
||||
#define D_BLINKOFF "Miganie - Wył."
|
||||
#define D_BOOT_COUNT "Licznik restartów"
|
||||
#define D_BRIGHTLIGHT "Jasny"
|
||||
#define D_BSSID "BSSId"
|
||||
#define D_BUTTON "Przycisk"
|
||||
#define D_BY "by" // Written by me
|
||||
#define D_BYTES "Bajtow"
|
||||
#define D_BYTES "Bajtów"
|
||||
#define D_CELSIUS "Celsiusza"
|
||||
#define D_CHANNEL "Kanał"
|
||||
#define D_CO2 "Dwutlenku węgla"
|
||||
|
@ -73,7 +73,7 @@
|
|||
#define D_CONNECTED "Połączony"
|
||||
#define D_COUNT "Licz"
|
||||
#define D_COUNTER "Licznik"
|
||||
#define D_CURRENT "Bieżący" // As in Voltage and Current
|
||||
#define D_CURRENT "Prąd" // As in Voltage and Current
|
||||
#define D_DATA "Data"
|
||||
#define D_DARKLIGHT "Ciemny"
|
||||
#define D_DEBUG "Debug"
|
||||
|
@ -84,18 +84,18 @@
|
|||
#define D_DST_TIME "DST"
|
||||
#define D_ECO2 "eCO2"
|
||||
#define D_EMULATION "Emulacja"
|
||||
#define D_ENABLED "Otwarty"
|
||||
#define D_ERASE "Nadpisz"
|
||||
#define D_ENABLED "Załączony"
|
||||
#define D_ERASE "Wyczyść"
|
||||
#define D_ERROR "Błąd"
|
||||
#define D_FAHRENHEIT "Fahrenheita"
|
||||
#define D_FAHRENHEIT "Fahrenheit"
|
||||
#define D_FAILED "Błędny"
|
||||
#define D_FALLBACK "Awaryjny"
|
||||
#define D_FALLBACK_TOPIC "Zastępczy temat"
|
||||
#define D_FALLBACK_TOPIC "Temat zastępczy"
|
||||
#define D_FALSE "Fałsz"
|
||||
#define D_FILE "Plik"
|
||||
#define D_FLOW_RATE "Flow rate"
|
||||
#define D_FLOW_RATE "Przepływ"
|
||||
#define D_FREE_MEMORY "Wolna pamięć"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_FREQUENCY "Częstotliwość"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Brama"
|
||||
#define D_GROUP "Grupa"
|
||||
|
@ -103,7 +103,7 @@
|
|||
#define D_HOSTNAME "Nazwa serwera"
|
||||
#define D_HUMIDITY "Wilgotność"
|
||||
#define D_ILLUMINANCE "Oświetlenie"
|
||||
#define D_IMMEDIATE "Natychmiastowe" // Button immediate
|
||||
#define D_IMMEDIATE "Natychmiastowy" // Button immediate
|
||||
#define D_INDEX "Indeks"
|
||||
#define D_INFO "Informacja"
|
||||
#define D_INFRARED "Podczerwień"
|
||||
|
@ -113,27 +113,27 @@
|
|||
#define D_LWT "LWT"
|
||||
#define D_MODULE "Moduł"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "wielokrotne-naciśnięcie"
|
||||
#define D_NOISE "Hałas"
|
||||
#define D_MULTI_PRESS "Wielokrotne naciśnięcie"
|
||||
#define D_NOISE "Szum"
|
||||
#define D_NONE "Brak"
|
||||
#define D_OFF "Wyłączony"
|
||||
#define D_OFFLINE "Nieaktywny"
|
||||
#define D_OK "Ok"
|
||||
#define D_ON "Włączony"
|
||||
#define D_ON "Załączony"
|
||||
#define D_ONLINE "Aktywny"
|
||||
#define D_PASSWORD "Hasło"
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Współczynik mocy"
|
||||
#define D_POWER_FACTOR "Cosinus fi"
|
||||
#define D_POWERUSAGE "Moc"
|
||||
#define D_POWERUSAGE_ACTIVE "Czynna Moc"
|
||||
#define D_POWERUSAGE_APPARENT "Pozorna Moc"
|
||||
#define D_POWERUSAGE_REACTIVE "Reaktywna Moc"
|
||||
#define D_POWERUSAGE_ACTIVE "Moc czynna"
|
||||
#define D_POWERUSAGE_APPARENT "Moc pozorna"
|
||||
#define D_POWERUSAGE_REACTIVE "Moc bierna"
|
||||
#define D_PRESSURE "Ciśnienie"
|
||||
#define D_PRESSUREATSEALEVEL "Ciśnienie na poziomie morza"
|
||||
#define D_PROGRAM_FLASH_SIZE "Wielkość programu flash"
|
||||
#define D_PROGRAM_SIZE "Wielkość programu"
|
||||
#define D_PROJECT "Projekt"
|
||||
#define D_RAIN "Rain"
|
||||
#define D_RAIN "Deszcz"
|
||||
#define D_RECEIVED "Otrzymany"
|
||||
#define D_RESTART "Restart"
|
||||
#define D_RESTARTING "Restartowanie"
|
||||
|
@ -148,8 +148,8 @@
|
|||
#define D_STD_TIME "STD"
|
||||
#define D_STOP "Stop"
|
||||
#define D_SUBNET_MASK "Maska podsieci"
|
||||
#define D_SUBSCRIBE_TO "Subskrybuj do"
|
||||
#define D_UNSUBSCRIBE_FROM "Unsubscribe from"
|
||||
#define D_SUBSCRIBE_TO "Subskrybuj"
|
||||
#define D_UNSUBSCRIBE_FROM "Nie subskrybuj"
|
||||
#define D_SUCCESSFUL "Powodzenie"
|
||||
#define D_SUNRISE "Wschód słońca"
|
||||
#define D_SUNSET "Zachód słońca"
|
||||
|
@ -157,7 +157,7 @@
|
|||
#define D_TO "do"
|
||||
#define D_TOGGLE "Przełącz"
|
||||
#define D_TOPIC "Temat"
|
||||
#define D_TOTAL_USAGE "Total Usage"
|
||||
#define D_TOTAL_USAGE "Całkowite użycie"
|
||||
#define D_TRANSMIT "Wyślij"
|
||||
#define D_TRUE "Prawda"
|
||||
#define D_TVOC "TVOC"
|
||||
|
@ -166,21 +166,21 @@
|
|||
#define D_UPTIME "Czas pracy"
|
||||
#define D_USER "Użytkownik"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_INDEX "Index UV"
|
||||
#define D_UV_INDEX_1 "Niski"
|
||||
#define D_UV_INDEX_2 "Średni"
|
||||
#define D_UV_INDEX_3 "Wysoki"
|
||||
#define D_UV_INDEX_4 "Niebezpieczny"
|
||||
#define D_UV_INDEX_5 "BurnL1/2"
|
||||
#define D_UV_INDEX_6 "BurnL3"
|
||||
#define D_UV_INDEX_5 "Burn L1/2"
|
||||
#define D_UV_INDEX_6 "Burn L3"
|
||||
#define D_UV_INDEX_7 "OoR"
|
||||
#define D_UV_LEVEL "Poziom UV"
|
||||
#define D_UV_POWER "UV Power"
|
||||
#define D_UV_POWER "Moc UV"
|
||||
#define D_VERSION "Wersja"
|
||||
#define D_VOLTAGE "Napięcie"
|
||||
#define D_WEIGHT "Weight"
|
||||
#define D_WARMLIGHT "Nagrzanie"
|
||||
#define D_WEB_SERVER "Web Serwer"
|
||||
#define D_WEIGHT "Waga"
|
||||
#define D_WARMLIGHT "Temperatura światła"
|
||||
#define D_WEB_SERVER "Serwer Web"
|
||||
|
||||
// tasmota.ino
|
||||
#define D_WARNING_MINIMAL_VERSION "UWAGA Ta wersja nie obsługuje zapisu ustawień"
|
||||
|
@ -192,21 +192,21 @@
|
|||
#define D_SET_BAUDRATE_TO "Ustaw szybkość transmisji na"
|
||||
#define D_RECEIVED_TOPIC "Otrzymany temat"
|
||||
#define D_DATA_SIZE "Wielkość danych"
|
||||
#define D_ANALOG_INPUT "Wej_analogowe"
|
||||
#define D_ANALOG_INPUT "Wejście analogowe"
|
||||
|
||||
// support.ino
|
||||
#define D_OSWATCH "osWatch"
|
||||
#define D_BLOCKED_LOOP "Pętla zablokowana"
|
||||
#define D_WPS_FAILED_WITH_STATUS "Błąd WPSconfig ze statusem"
|
||||
#define D_WPS_FAILED_WITH_STATUS "Błąd konfiguracji WPS ze statusem"
|
||||
#define D_ACTIVE_FOR_3_MINUTES "aktywny 3 minuty"
|
||||
#define D_FAILED_TO_START "nie udało się uruchomić"
|
||||
#define D_PATCH_ISSUE_2186 "Błąd łatki 2186"
|
||||
#define D_PATCH_ISSUE_2186 "Błąd poprawki 2186"
|
||||
#define D_CONNECTING_TO_AP "Łączenie z AP"
|
||||
#define D_IN_MODE "w trybie"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Połączenie nie powiodło sie, ponieważ nie otrzymano adresu IP"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Połączenie nie powiodło sie jako AP nie można osiągnać"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Połączenie nie powiodło sie z nieprawidlowym hasłem dostepu AP"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "Nie udało się nawiązac połączenia, limit czasu AP przekroczony"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Połączenie nie powiodło się, ponieważ nie otrzymano adresu IP."
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Połączenie nie powiodło się, AP nie osiągalny."
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Połączenie nie powiodło się, nieprawidlowe hasło."
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "Nie udało się nawiązac połączenia, limit czasu przekroczony."
|
||||
#define D_ATTEMPTING_CONNECTION "Próba połączenia..."
|
||||
#define D_CHECKING_CONNECTION "Sprawdzanie połączenia..."
|
||||
#define D_QUERY_DONE "Wykonano zapytanie. Znaleziono uslugi MQTT"
|
||||
|
@ -215,10 +215,10 @@
|
|||
#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nie znaleziony"
|
||||
|
||||
// settings.ino
|
||||
#define D_SAVED_TO_FLASH_AT "Zapisane do pamięci flash w"
|
||||
#define D_LOADED_FROM_FLASH_AT "Wczytane z pamięci flash z"
|
||||
#define D_SAVED_TO_FLASH_AT "Zapisano do pamięci flash w"
|
||||
#define D_LOADED_FROM_FLASH_AT "Wczytano z pamięci flash w"
|
||||
#define D_USE_DEFAULTS "Użyj domyślnych"
|
||||
#define D_ERASED_SECTOR "Wymazany sektor"
|
||||
#define D_ERASED_SECTOR "Sektor wymazany"
|
||||
|
||||
// xdrv_02_webserver.ino
|
||||
#define D_NOSCRIPT "Aby korzystać z Tasmota, włącz obsługę JavaScript"
|
||||
|
@ -235,19 +235,19 @@
|
|||
#define D_RESTART_IN "Zrestartuj"
|
||||
#define D_SECONDS "sekund"
|
||||
#define D_DEVICE_WILL_RESTART "Urządzenie zrestartuje sie za kilka sekund"
|
||||
#define D_BUTTON_TOGGLE "Przełącznik"
|
||||
#define D_BUTTON_TOGGLE "Załącz/Wyłącz"
|
||||
#define D_CONFIGURATION "Konfiguracja"
|
||||
#define D_INFORMATION "Informacje"
|
||||
#define D_FIRMWARE_UPGRADE "Aktualizacja oprogramowania"
|
||||
#define D_CONSOLE "Konsola"
|
||||
#define D_CONFIRM_RESTART "Potwierdź restart"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Konfiguruj moduł"
|
||||
#define D_CONFIGURE_WIFI "Konfiguruj WiFi"
|
||||
#define D_CONFIGURE_MQTT "Konfiguruj MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Konfiguruj Domoticz"
|
||||
#define D_CONFIGURE_LOGGING "Konfiguruj zapis dziennika"
|
||||
#define D_CONFIGURE_OTHER "Konfiguruj inne"
|
||||
#define D_CONFIGURE_MODULE "Konfiguracja modułu"
|
||||
#define D_CONFIGURE_WIFI "Konfiguracja WiFi"
|
||||
#define D_CONFIGURE_MQTT "Konfiguracja MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Konfiguracja Domoticza"
|
||||
#define D_CONFIGURE_LOGGING "Konfiguracja dziennika"
|
||||
#define D_CONFIGURE_OTHER "Konfiguracja innych"
|
||||
#define D_CONFIRM_RESET_CONFIGURATION "Potwierdź reset ustawień"
|
||||
#define D_RESET_CONFIGURATION "Reset ustawień"
|
||||
#define D_BACKUP_CONFIGURATION "Kopia ustawień"
|
||||
|
@ -256,18 +256,18 @@
|
|||
|
||||
#define D_MODULE_PARAMETERS "Parametry modułu"
|
||||
#define D_MODULE_TYPE "Typ modułu"
|
||||
#define D_PULLUP_ENABLE "No Button/Switch pull-up"
|
||||
#define D_PULLUP_ENABLE "Przełącznik pull-up"
|
||||
#define D_ADC "ADC"
|
||||
#define D_GPIO "GPIO"
|
||||
#define D_SERIAL_IN "Serial In"
|
||||
#define D_SERIAL_OUT "Serial Out"
|
||||
#define D_SERIAL_IN "Wejście rs"
|
||||
#define D_SERIAL_OUT "Wyjście rs"
|
||||
|
||||
#define D_WIFI_PARAMETERS "Parametry WiFi"
|
||||
#define D_WIFI_PARAMETERS "Parametry sieci WiFi"
|
||||
#define D_SCAN_FOR_WIFI_NETWORKS "Skanuj sieci WiFi"
|
||||
#define D_SCAN_DONE "Skan wykonany"
|
||||
#define D_SCAN_DONE "Skanowanie wykonane"
|
||||
#define D_NO_NETWORKS_FOUND "Nie znaleziono sieci"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Odswież aby ponownie zeskanowac"
|
||||
#define D_DUPLICATE_ACCESSPOINT "Kopiuj AP"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Odswież aby ponownie wyszukać sieci WiFi"
|
||||
#define D_DUPLICATE_ACCESSPOINT "Powiel AP"
|
||||
#define D_SKIPPING_LOW_QUALITY "Pominięto z powodu niskiej jakości sygnału"
|
||||
#define D_RSSI "RSSI"
|
||||
#define D_WEP "WEP"
|
||||
|
@ -283,11 +283,11 @@
|
|||
#define D_FULL_TOPIC "Pełny temat"
|
||||
|
||||
#define D_LOGGING_PARAMETERS "Opcje dziennika"
|
||||
#define D_SERIAL_LOG_LEVEL "Serial poziom dziennika"
|
||||
#define D_MQTT_LOG_LEVEL "Mqtt log level"
|
||||
#define D_WEB_LOG_LEVEL "Web poziom dziennika"
|
||||
#define D_SYS_LOG_LEVEL "System poziom dziennika"
|
||||
#define D_MORE_DEBUG "Więcej informacji debug"
|
||||
#define D_SERIAL_LOG_LEVEL "Serial - poziom dziennika"
|
||||
#define D_MQTT_LOG_LEVEL "Mqtt - poziom dziennika"
|
||||
#define D_WEB_LOG_LEVEL "Web - poziom dziennika"
|
||||
#define D_SYS_LOG_LEVEL "System - poziom dziennika"
|
||||
#define D_MORE_DEBUG "Więcej informacji dziennika"
|
||||
#define D_SYSLOG_HOST "Syslog host"
|
||||
#define D_SYSLOG_PORT "Syslog port"
|
||||
#define D_TELEMETRY_PERIOD "Okres telemetrii"
|
||||
|
@ -295,15 +295,15 @@
|
|||
#define D_OTHER_PARAMETERS "Inne parametry"
|
||||
#define D_TEMPLATE "Szablon"
|
||||
#define D_ACTIVATE "Aktywuj"
|
||||
#define D_WEB_ADMIN_PASSWORD "Hasło administratora Web"
|
||||
#define D_WEB_ADMIN_PASSWORD "Hasło administratora"
|
||||
#define D_MQTT_ENABLE "MQTT aktywne"
|
||||
#define D_FRIENDLY_NAME "Twoja nazwa"
|
||||
#define D_BELKIN_WEMO "Belkin WeMo"
|
||||
#define D_HUE_BRIDGE "Hue Bridge"
|
||||
#define D_SINGLE_DEVICE "pojedyncze urządzenie"
|
||||
#define D_MULTI_DEVICE "wiele urządzeń"
|
||||
#define D_HUE_BRIDGE "Mostek Hue"
|
||||
#define D_SINGLE_DEVICE "pojedyńcze urządzenie"
|
||||
#define D_MULTI_DEVICE "multi urządzenie"
|
||||
|
||||
#define D_CONFIGURE_TEMPLATE "Konfiguruj szablon"
|
||||
#define D_CONFIGURE_TEMPLATE "Konfiguracja szablonu"
|
||||
#define D_TEMPLATE_PARAMETERS "Parametry szablonu"
|
||||
#define D_TEMPLATE_NAME "Nazwa"
|
||||
#define D_BASE_TYPE "Na bazie"
|
||||
|
@ -317,11 +317,11 @@
|
|||
#define D_BUILD_DATE_AND_TIME "Dzień i godzina kompilacji"
|
||||
#define D_CORE_AND_SDK_VERSION "Wersja Core/SDK"
|
||||
#define D_FLASH_WRITE_COUNT "Liczba zapisów do pamięci"
|
||||
#define D_MAC_ADDRESS "Adres Mac"
|
||||
#define D_MAC_ADDRESS "Adres MAC"
|
||||
#define D_MQTT_HOST "Host MQTT"
|
||||
#define D_MQTT_PORT "Port MQTT"
|
||||
#define D_MQTT_CLIENT "Klient MQTT"
|
||||
#define D_MQTT_USER "Uzytkownik MQTT"
|
||||
#define D_MQTT_USER "Użytkownik MQTT"
|
||||
#define D_MQTT_TOPIC "Temat MQTT"
|
||||
#define D_MQTT_GROUP_TOPIC "Temat grupy MQTT"
|
||||
#define D_MQTT_FULL_TOPIC "Pełen temat MQTT"
|
||||
|
@ -329,21 +329,21 @@
|
|||
#define D_MDNS_ADVERTISE "Rozgłaszanie mDNS"
|
||||
#define D_ESP_CHIP_ID "ID ukladu ESP"
|
||||
#define D_FLASH_CHIP_ID "ID układu pamięci flash"
|
||||
#define D_FLASH_CHIP_SIZE "Rozmiar flash"
|
||||
#define D_FREE_PROGRAM_SPACE "Wolne miejsce programu"
|
||||
#define D_FLASH_CHIP_SIZE "Rozmiar pamięci flash"
|
||||
#define D_FREE_PROGRAM_SPACE "Wolna pamięć programu"
|
||||
|
||||
#define D_UPGRADE_BY_WEBSERVER "Aktualizacja z serwera Web"
|
||||
#define D_OTA_URL "URL OTA"
|
||||
#define D_OTA_URL "URL serwera"
|
||||
#define D_START_UPGRADE "Start aktualizacji"
|
||||
#define D_UPGRADE_BY_FILE_UPLOAD "Aktualizacja poprzez wgranie pliku"
|
||||
#define D_UPGRADE_BY_FILE_UPLOAD "Aktualizacja z pliku"
|
||||
#define D_UPLOAD_STARTED "Wgrywanie rozpoczęte"
|
||||
#define D_UPGRADE_STARTED "Aktualizacja rozpoczęta"
|
||||
#define D_UPLOAD_DONE "Wgrywanie zakończone"
|
||||
#define D_UPLOAD_ERR_1 "Nie wybrano pliku"
|
||||
#define D_UPLOAD_ERR_2 "Niewystarczająca ilość miejsca"
|
||||
#define D_UPLOAD_ERR_3 "Magiczny bajt jest inny niz 0xE9"
|
||||
#define D_UPLOAD_ERR_4 "Rozmiar programu jest większy niż rzeczywisty rozmiar pamieci flash"
|
||||
#define D_UPLOAD_ERR_5 "Wgrywanie, bufor niezgodnosci stanu porównywanych bitow"
|
||||
#define D_UPLOAD_ERR_4 "Rozmiar programu jest większy niż rzeczywisty rozmiar pamięci flash"
|
||||
#define D_UPLOAD_ERR_5 "Wgrywanie, bufor niezgodności stanu porównywanych bitow"
|
||||
#define D_UPLOAD_ERR_6 "Błąd wgrywania. Uruchomiono zapis do dziennika na poziomie 3"
|
||||
#define D_UPLOAD_ERR_7 "Wgrywanie przerwane"
|
||||
#define D_UPLOAD_ERR_8 "Błędny plik"
|
||||
|
@ -355,116 +355,116 @@
|
|||
#define D_UPLOAD_ERROR_CODE "Błąd wgrywania"
|
||||
|
||||
#define D_ENTER_COMMAND "Wprowadź polecenie"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Włącz poziom 2 zapisu Weblog, jeśli oczekiwana jest odpowiedź"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Włącz poziom 2 zapisu dziennika, jeśli oczekiwana jest odpowiedź"
|
||||
#define D_NEED_USER_AND_PASSWORD "Wymagany użytkownik=<username>&hasło=<password>"
|
||||
|
||||
// xdrv_01_mqtt.ino
|
||||
#define D_FINGERPRINT "Weryfikuj odcisk TLS..."
|
||||
#define D_TLS_CONNECT_FAILED_TO "Nieudane połączenie TLS do"
|
||||
#define D_RETRY_IN "Spróbuj ponownie"
|
||||
#define D_VERIFIED "Zweryfikowano odcisku"
|
||||
#define D_VERIFIED "Zweryfikowano odcisk"
|
||||
#define D_INSECURE "Nieprawidłowe połączenie z powodu błędnego odcisku TLS"
|
||||
#define D_CONNECT_FAILED_TO "Nie udało się nawiązać połączenia"
|
||||
|
||||
// xplg_wemohue.ino
|
||||
#define D_MULTICAST_DISABLED "Multicast jest wyłączony"
|
||||
#define D_MULTICAST_REJOINED "Multicast (re)dołączony"
|
||||
#define D_MULTICAST_JOIN_FAILED "Multicast nie powiodło się"
|
||||
#define D_MULTICAST_DISABLED "Multicast wyłączony"
|
||||
#define D_MULTICAST_REJOINED "Multicast dołączony"
|
||||
#define D_MULTICAST_JOIN_FAILED "Podłączenie Multicast nie powiodło się"
|
||||
#define D_FAILED_TO_SEND_RESPONSE "Nie udało się wysłać odpowiedzi"
|
||||
|
||||
#define D_WEMO "WeMo"
|
||||
#define D_WEMO_BASIC_EVENT "WeMo podstawowe zdarzenie"
|
||||
#define D_WEMO_EVENT_SERVICE "WeMo zdarzenie service"
|
||||
#define D_WEMO_META_SERVICE "WeMo meta service"
|
||||
#define D_WEMO_SETUP "WeMo setup"
|
||||
#define D_WEMO_BASIC_EVENT "Zdarzenie WeNo"
|
||||
#define D_WEMO_EVENT_SERVICE "Zdarzenie serwisowe WeMo"
|
||||
#define D_WEMO_META_SERVICE "Meta dane serwisowe WeMo"
|
||||
#define D_WEMO_SETUP "Ustawienia WeMo"
|
||||
#define D_RESPONSE_SENT "Odpowiedź wysłana"
|
||||
|
||||
#define D_HUE "Hue"
|
||||
#define D_HUE_BRIDGE_SETUP "Hue setup"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "Hue API nie zaimplementowane"
|
||||
#define D_HUE_API "Hue API"
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_HUE_BRIDGE_SETUP "Ustawienia Hue"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "Api Hue nie zaimplementowane"
|
||||
#define D_HUE_API "API Hue"
|
||||
#define D_HUE_POST_ARGS "POST argument Hue"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysyłane"
|
||||
|
||||
// xdrv_07_domoticz.ino
|
||||
#define D_DOMOTICZ_PARAMETERS "Parametry Domoticz"
|
||||
#define D_DOMOTICZ_IDX "Idx"
|
||||
#define D_DOMOTICZ_KEY_IDX "Key idx"
|
||||
#define D_DOMOTICZ_SWITCH_IDX "Przełącznik idx"
|
||||
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
|
||||
#define D_DOMOTICZ_TEMP "Temp"
|
||||
#define D_DOMOTICZ_TEMP_HUM "Temp,Wilg"
|
||||
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Wilg,Cis"
|
||||
#define D_DOMOTICZ_POWER_ENERGY "Moc,Energia"
|
||||
#define D_DOMOTICZ_ILLUMINANCE "Oświetl."
|
||||
#define D_DOMOTICZ_COUNT "Licznik/PM1"
|
||||
#define D_DOMOTICZ_VOLTAGE "Napięcie/PM2,5"
|
||||
#define D_DOMOTICZ_CURRENT "Prąd/PM10"
|
||||
#define D_DOMOTICZ_AIRQUALITY "AirQuality"
|
||||
#define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter"
|
||||
#define D_DOMOTICZ_SWITCH_IDX "Przełącznik Idx"
|
||||
#define D_DOMOTICZ_SENSOR_IDX "Sensor Idx"
|
||||
#define D_DOMOTICZ_TEMP "Temperatura"
|
||||
#define D_DOMOTICZ_TEMP_HUM "Temperatura, Wilgotność"
|
||||
#define D_DOMOTICZ_TEMP_HUM_BARO "Temperatura, Wilgotność, Ciśnienie"
|
||||
#define D_DOMOTICZ_POWER_ENERGY "Moc, Energia"
|
||||
#define D_DOMOTICZ_ILLUMINANCE "Oświetlenie"
|
||||
#define D_DOMOTICZ_COUNT "Licznik"
|
||||
#define D_DOMOTICZ_VOLTAGE "Napięcie"
|
||||
#define D_DOMOTICZ_CURRENT "Prąd"
|
||||
#define D_DOMOTICZ_AIRQUALITY "Jakość powietrza"
|
||||
#define D_DOMOTICZ_P1_SMART_METER "Miernik P1"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Zaktualizuj czasomierz"
|
||||
|
||||
// xdrv_09_timers.ino
|
||||
#define D_CONFIGURE_TIMER "Konfiguruj harmonogram"
|
||||
#define D_TIMER_PARAMETERS "Parametry harmonogramów"
|
||||
#define D_TIMER_ENABLE "Włącz Harmonogramy"
|
||||
#define D_CONFIGURE_TIMER "Konfiguracja harmonogramu"
|
||||
#define D_TIMER_PARAMETERS "Parametry harmonogramu"
|
||||
#define D_TIMER_ENABLE "Włącz harmonogram"
|
||||
#define D_TIMER_ARM "Włącz"
|
||||
#define D_TIMER_TIME "Według godziny"
|
||||
#define D_TIMER_TIME "Czas"
|
||||
#define D_TIMER_DAYS "Dni"
|
||||
#define D_TIMER_REPEAT "Powtarzaj"
|
||||
#define D_TIMER_OUTPUT "Wyjście"
|
||||
#define D_TIMER_ACTION "Akcja"
|
||||
|
||||
// xdrv_10_knx.ino
|
||||
#define D_CONFIGURE_KNX "Konfiguruj KNX"
|
||||
#define D_CONFIGURE_KNX "Konfiguracja KNX"
|
||||
#define D_KNX_PARAMETERS "Parametry KNX"
|
||||
#define D_KNX_GENERAL_CONFIG "Ogólne"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Adres Fizyczny"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Musi być unikalny w sieci KNX )"
|
||||
#define D_KNX_GENERAL_CONFIG "Konfiguracja ogólna"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Adres fizyczny"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "(Musi być unikalny w sieci KNX)"
|
||||
#define D_KNX_ENABLE "Włącz KNX"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Dane do wysłania do adresów grupowych"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Adresy grupowe do zapisu"
|
||||
#define D_ADD "Dodaj"
|
||||
#define D_DELETE "Usuń"
|
||||
#define D_REPLY "Odpowiedz"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Adresy grupowe do odbioru danych z"
|
||||
#define D_RECEIVED_FROM "Otrzymane od"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Adresy grupowe do odbioru"
|
||||
#define D_RECEIVED_FROM "Odebrane od"
|
||||
#define D_KNX_COMMAND_WRITE "Zapisz"
|
||||
#define D_KNX_COMMAND_READ "Czytaj"
|
||||
#define D_KNX_COMMAND_OTHER "Inne"
|
||||
#define D_SENT_TO "wysłane do"
|
||||
#define D_KNX_COMMAND_OTHER "Inna komenda"
|
||||
#define D_SENT_TO "Wysłane do"
|
||||
#define D_KNX_WARNING "Adres grupy (0/0/0) jest zarezerwowany i nie można go użyć."
|
||||
#define D_KNX_ENHANCEMENT "Usprawnienie Komunikacji"
|
||||
#define D_KNX_ENHANCEMENT "Rozszerzenia KNX"
|
||||
#define D_KNX_TX_SLOT "KNX TX"
|
||||
#define D_KNX_RX_SLOT "KNX RX"
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia Dzisiaj"
|
||||
#define D_ENERGY_YESTERDAY "Energia Wczoraj"
|
||||
#define D_ENERGY_TOTAL "Energia suma"
|
||||
#define D_ENERGY_TODAY "Energia dzisiaj"
|
||||
#define D_ENERGY_YESTERDAY "Energia wczoraj"
|
||||
#define D_ENERGY_TOTAL "Energia całkowita"
|
||||
|
||||
// xdrv_27_shutter.ino
|
||||
#define D_OPEN "Open"
|
||||
#define D_CLOSE "Close"
|
||||
#define D_DOMOTICZ_SHUTTER "Shutter"
|
||||
#define D_OPEN "Otwórz"
|
||||
#define D_CLOSE "Zamknij"
|
||||
#define D_DOMOTICZ_SHUTTER "Roleta"
|
||||
|
||||
// xdrv_28_pcf8574.ino
|
||||
#define D_CONFIGURE_PCF8574 "Configure PCF8574"
|
||||
#define D_PCF8574_PARAMETERS "PCF8574 parameters"
|
||||
#define D_INVERT_PORTS "Invert Ports"
|
||||
#define D_DEVICE "Device"
|
||||
#define D_DEVICE_INPUT "Input"
|
||||
#define D_DEVICE_OUTPUT "Output"
|
||||
#define D_CONFIGURE_PCF8574 "Konfiguracja PCF8574"
|
||||
#define D_PCF8574_PARAMETERS "Parametry PCF8574"
|
||||
#define D_INVERT_PORTS "Odwrócone porty"
|
||||
#define D_DEVICE "Urządzenie"
|
||||
#define D_DEVICE_INPUT "Wejście"
|
||||
#define D_DEVICE_OUTPUT "Wyjście"
|
||||
|
||||
// xsns_05_ds18b20.ino
|
||||
#define D_SENSOR_BUSY "Czujnik DS18x20 zajęty"
|
||||
#define D_SENSOR_CRC_ERROR "Czujnik DS18x20 błąd CRC"
|
||||
#define D_SENSORS_FOUND "Znaleziono Czujnik DS18x20"
|
||||
#define D_SENSORS_FOUND "Znaleziono czujnik DS18x20"
|
||||
|
||||
// xsns_06_dht.ino
|
||||
#define D_TIMEOUT_WAITING_FOR "Trwa oczekiwanie"
|
||||
#define D_START_SIGNAL_LOW "sygnał startowy niski"
|
||||
#define D_START_SIGNAL_HIGH "sygnał startowy wysoki"
|
||||
#define D_PULSE "pulse"
|
||||
#define D_PULSE "Impuls"
|
||||
#define D_CHECKSUM_FAILURE "Błędna suma kontrolna"
|
||||
|
||||
// xsns_07_sht1x.ino
|
||||
|
@ -486,12 +486,12 @@
|
|||
|
||||
// xsns_34_hx711.ino
|
||||
#define D_HX_CAL_REMOVE "Usuń wagę"
|
||||
#define D_HX_CAL_REFERENCE "Załaduj masę referencyjną"
|
||||
#define D_HX_CAL_REFERENCE "Załaduj wagę referencyjną"
|
||||
#define D_HX_CAL_DONE "Skalibrowany"
|
||||
#define D_HX_CAL_FAIL "Błąd Kalibracji"
|
||||
#define D_RESET_HX711 "Zresetuj Skalę"
|
||||
#define D_CONFIGURE_HX711 "Skonfiguruj Skalę"
|
||||
#define D_HX711_PARAMETERS "Parametry Skali"
|
||||
#define D_HX_CAL_FAIL "Błąd kalibracji"
|
||||
#define D_RESET_HX711 "Zresetuj skalę"
|
||||
#define D_CONFIGURE_HX711 "Skonfiguruj skalę"
|
||||
#define D_HX711_PARAMETERS "Parametry skali"
|
||||
#define D_ITEM_WEIGHT "Waga przedmiotu"
|
||||
#define D_REFERENCE_WEIGHT "Waga referencyjna"
|
||||
#define D_CALIBRATE "Skalibruj"
|
||||
|
@ -509,7 +509,7 @@
|
|||
|
||||
// tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box
|
||||
#define D_SENSOR_NONE "Brak"
|
||||
#define D_SENSOR_USER "User"
|
||||
#define D_SENSOR_USER "Użytkownik"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
#define D_SENSOR_SI7021 "SI7021"
|
||||
|
@ -517,15 +517,15 @@
|
|||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_DFR562 "Odtearzacz MP3"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Przela" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Przyci" // Suffix "1"
|
||||
#define D_SENSOR_RELAY "Przek" // Suffix "1i"
|
||||
#define D_SENSOR_SWITCH "Przełącznik" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Przycisk" // Suffix "1"
|
||||
#define D_SENSOR_RELAY "Przekaźnik" // Suffix "1i"
|
||||
#define D_SENSOR_LED "Led" // Suffix "1i"
|
||||
#define D_SENSOR_LED_LINK "LedLink" // Suffix "i"
|
||||
#define D_SENSOR_PWM "PWM" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Liczni" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Licznik" // Suffix "1"
|
||||
#define D_SENSOR_IRRECV "IRrecv"
|
||||
#define D_SENSOR_MHZ_RX "MHZ Rx"
|
||||
#define D_SENSOR_MHZ_TX "MHZ Tx"
|
||||
|
@ -623,8 +623,8 @@
|
|||
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
|
||||
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
|
||||
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
|
||||
#define D_SENSOR_DEEPSLEEP "DeepSleep"
|
||||
#define D_SENSOR_EXS_ENABLE "EXS Enable"
|
||||
#define D_SENSOR_DEEPSLEEP "Głęboko uśpiony"
|
||||
#define D_SENSOR_EXS_ENABLE "Załącz EXS"
|
||||
#define D_SENSOR_SLAVE_TX "Slave TX"
|
||||
#define D_SENSOR_SLAVE_RX "Slave RX"
|
||||
#define D_SENSOR_SLAVE_RESET "Slave RST"
|
||||
|
@ -664,37 +664,37 @@
|
|||
#define D_UNIT_WATT_METER_QUADRAT "W/m²"
|
||||
|
||||
//SDM220
|
||||
#define D_PHASE_ANGLE "Phase Angle"
|
||||
#define D_IMPORT_ACTIVE "Import Active"
|
||||
#define D_EXPORT_ACTIVE "Export Active"
|
||||
#define D_IMPORT_REACTIVE "Import Reactive"
|
||||
#define D_EXPORT_REACTIVE "Export Reactive"
|
||||
#define D_TOTAL_REACTIVE "Total Reactive"
|
||||
#define D_PHASE_ANGLE "Przesunięcie faz"
|
||||
#define D_IMPORT_ACTIVE "Czynna pobrana"
|
||||
#define D_EXPORT_ACTIVE "Czynna oddana"
|
||||
#define D_IMPORT_REACTIVE "Bierna pobrana"
|
||||
#define D_EXPORT_REACTIVE "Bierna oddana"
|
||||
#define D_TOTAL_REACTIVE "Całkowita bierna"
|
||||
#define D_UNIT_KWARH "kVArh"
|
||||
#define D_UNIT_ANGLE "Deg"
|
||||
|
||||
//SOLAXX1
|
||||
#define D_PV1_VOLTAGE "PV1 Voltage"
|
||||
#define D_PV1_CURRENT "PV1 Current"
|
||||
#define D_PV1_POWER "PV1 Power"
|
||||
#define D_PV2_VOLTAGE "PV2 Voltage"
|
||||
#define D_PV2_CURRENT "PV2 Current"
|
||||
#define D_PV2_POWER "PV2 Power"
|
||||
#define D_SOLAR_POWER "Solar Power"
|
||||
#define D_INVERTER_POWER "Inverter Power"
|
||||
#define D_PV1_VOLTAGE "Napięcie PV1"
|
||||
#define D_PV1_CURRENT "Prąd PV1"
|
||||
#define D_PV1_POWER "Moc PV1 "
|
||||
#define D_PV2_VOLTAGE "Napięcie PV2"
|
||||
#define D_PV2_CURRENT "Prąd PV2"
|
||||
#define D_PV2_POWER "Moc PV2"
|
||||
#define D_SOLAR_POWER "Moc PV"
|
||||
#define D_INVERTER_POWER "Moc invertera"
|
||||
#define D_STATUS "Status"
|
||||
#define D_WAITING "Waiting"
|
||||
#define D_CHECKING "Checking"
|
||||
#define D_WORKING "Working"
|
||||
#define D_FAILURE "Failure"
|
||||
#define D_SOLAX_ERROR_0 "No Error Code"
|
||||
#define D_SOLAX_ERROR_1 "Grid Lost Fault"
|
||||
#define D_SOLAX_ERROR_2 "Grid Voltage Fault"
|
||||
#define D_SOLAX_ERROR_3 "Grid Frequency Fault"
|
||||
#define D_SOLAX_ERROR_4 "Pv Voltage Fault"
|
||||
#define D_SOLAX_ERROR_5 "Isolation Fault"
|
||||
#define D_SOLAX_ERROR_6 "Over Temperature Fault"
|
||||
#define D_SOLAX_ERROR_7 "Fan Fault"
|
||||
#define D_SOLAX_ERROR_8 "Other Device Fault"
|
||||
#define D_WAITING "Oczekiwanie"
|
||||
#define D_CHECKING "Sprawdzanie"
|
||||
#define D_WORKING "Praca"
|
||||
#define D_FAILURE "Błąd"
|
||||
#define D_SOLAX_ERROR_0 "Błąd - brak kodu"
|
||||
#define D_SOLAX_ERROR_1 "Błąd - utrata sieci"
|
||||
#define D_SOLAX_ERROR_2 "Błąd - napięcie sieci"
|
||||
#define D_SOLAX_ERROR_3 "Błąd - częstotliwość sieci"
|
||||
#define D_SOLAX_ERROR_4 "Błąd - napięcie PV"
|
||||
#define D_SOLAX_ERROR_5 "Błąd - usterka izolacji"
|
||||
#define D_SOLAX_ERROR_6 "Błąd - przegrzanie"
|
||||
#define D_SOLAX_ERROR_7 "Błąd - wentylator"
|
||||
#define D_SOLAX_ERROR_8 "Błąd - inne urządzenie"
|
||||
|
||||
#endif // _LANGUAGE_PL_PL_D_H_
|
||||
|
|
|
@ -434,8 +434,9 @@ struct SYSCFG {
|
|||
uint32_t deepsleep; // E94
|
||||
uint16_t energy_power_delta; // E98
|
||||
uint8_t shutter_motordelay[MAX_SHUTTERS]; // E9A
|
||||
int8_t temp_comp; // E9E
|
||||
|
||||
uint8_t free_e9e[2]; // E9E
|
||||
uint8_t free_e9f[1]; // E9F
|
||||
|
||||
uint8_t web_color2[2][3]; // EA0 - Needs to be on integer / 3 distance from web_color
|
||||
|
||||
|
|
|
@ -314,7 +314,9 @@ void SetFlashModeDout(void)
|
|||
if (ESP.flashRead(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE)) {
|
||||
if (_buffer[2] != 3) { // DOUT
|
||||
_buffer[2] = 3;
|
||||
if (ESP.flashEraseSector(address / FLASH_SECTOR_SIZE)) ESP.flashWrite(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE);
|
||||
if (ESP.flashEraseSector(address / FLASH_SECTOR_SIZE)) {
|
||||
ESP.flashWrite(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] _buffer;
|
||||
|
@ -401,7 +403,7 @@ void UpdateQuickPowerCycle(bool update)
|
|||
if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AB0)) {
|
||||
uint32_t counter = ((pc_register & 0xF) << 1) & 0xF;
|
||||
if (0 == counter) { // 4 power cycles in a row
|
||||
SettingsErase(2); // Quickly reset all settings including QuickPowerCycle flag
|
||||
SettingsErase(3); // Quickly reset all settings including QuickPowerCycle flag
|
||||
EspRestart(); // And restart
|
||||
} else {
|
||||
pc_register = 0xFFA55AB0 | counter;
|
||||
|
@ -412,8 +414,9 @@ void UpdateQuickPowerCycle(bool update)
|
|||
else if (pc_register != 0xFFA55ABF) {
|
||||
pc_register = 0xFFA55ABF;
|
||||
// Assume flash is default all ones and setting a bit to zero does not need an erase
|
||||
ESP.flashEraseSector(pc_location);
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
if (ESP.flashEraseSector(pc_location)) {
|
||||
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset"));
|
||||
}
|
||||
}
|
||||
|
@ -464,8 +467,9 @@ void SettingsSave(uint8_t rotate)
|
|||
Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade
|
||||
Settings.cfg_crc32 = GetSettingsCrc32();
|
||||
|
||||
ESP.flashEraseSector(settings_location);
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
if (ESP.flashEraseSector(settings_location)) {
|
||||
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
|
||||
}
|
||||
|
||||
if (!stop_flash_rotate && rotate) {
|
||||
for (uint32_t i = 1; i < CFG_ROTATES; i++) {
|
||||
|
@ -571,29 +575,30 @@ void SettingsErase(uint8_t type)
|
|||
|
||||
0 = Erase from program end until end of flash as seen by SDK
|
||||
1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0xFCxxx - 0x0xFFFFF) solving possible wifi errors
|
||||
2 = Erase Tasmota settings (0x0xF3xxx - 0x0xFBFFF)
|
||||
2 = Erase Tasmota parameter area (0x0xF3xxx - 0x0xFBFFF)
|
||||
3 = Erase Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
|
||||
*/
|
||||
|
||||
#ifndef FIRMWARE_MINIMAL
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SDK: Flash size 0x%08X"), flashchip->chip_size);
|
||||
|
||||
uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1;
|
||||
uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE;
|
||||
// uint32_t _sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE;
|
||||
uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE; // Flash size as reported by hardware
|
||||
if (1 == type) {
|
||||
// source Esp.cpp and core_esp8266_phy.cpp
|
||||
_sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4;
|
||||
_sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4; // SDK parameter area
|
||||
}
|
||||
else if (2 == type) {
|
||||
_sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota parameter area (0x0F3xxx - 0x0FBFFF)
|
||||
_sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota parameter area (0x0F3xxx - 0x0FBFFF)
|
||||
_sectorEnd = SETTINGS_LOCATION +1;
|
||||
}
|
||||
else if (3 == type) {
|
||||
_sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
|
||||
_sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
|
||||
}
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart);
|
||||
|
||||
// EspErase(_sectorStart, _sectorEnd); // Arduino core and SDK - erases flash as seen by SDK
|
||||
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
|
||||
|
||||
// EspErase(_sectorStart, _sectorEnd); // Arduino core and SDK - erases flash as seen by SDK
|
||||
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
|
||||
#endif // FIRMWARE_MINIMAL
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
IPAddress syslog_host_addr; // Syslog host IP address
|
||||
uint32_t syslog_host_hash = 0; // Syslog host name hash
|
||||
|
||||
extern "C" {
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
|
||||
\*********************************************************************************************/
|
||||
|
@ -72,6 +76,26 @@ void OsWatchLoop(void)
|
|||
// while(1) delay(1000); // this will trigger the os watch
|
||||
}
|
||||
|
||||
bool OsWatchBlockedLoop(void)
|
||||
{
|
||||
return oswatch_blocked_loop;
|
||||
}
|
||||
|
||||
uint32_t ResetReason(void)
|
||||
{
|
||||
/*
|
||||
user_interface.h
|
||||
REASON_DEFAULT_RST = 0, // "Power on" normal startup by power on
|
||||
REASON_WDT_RST = 1, // "Hardware Watchdog" hardware watch dog reset
|
||||
REASON_EXCEPTION_RST = 2, // "Exception" exception reset, GPIO status won’t change
|
||||
REASON_SOFT_WDT_RST = 3, // "Software Watchdog" software watch dog reset, GPIO status won’t change
|
||||
REASON_SOFT_RESTART = 4, // "Software/System restart" software restart ,system_restart , GPIO status won’t change
|
||||
REASON_DEEP_SLEEP_AWAKE = 5, // "Deep-Sleep Wake" wake up from deep-sleep
|
||||
REASON_EXT_SYS_RST = 6 // "External System" external system reset
|
||||
*/
|
||||
return resetInfo.reason;
|
||||
}
|
||||
|
||||
String GetResetReason(void)
|
||||
{
|
||||
if (oswatch_blocked_loop) {
|
||||
|
@ -83,9 +107,10 @@ String GetResetReason(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool OsWatchBlockedLoop(void)
|
||||
String GetResetReasonInfo(void)
|
||||
{
|
||||
return oswatch_blocked_loop;
|
||||
// "Fatal exception:0 flag:2 (EXCEPTION) epc1:0x704022a7 epc2:0x00000000 epc3:0x00000000 excvaddr:0x00000000 depc:0x00000000"
|
||||
return (ResetReason() == REASON_EXCEPTION_RST) ? ESP.getResetInfo() : GetResetReason();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -371,7 +396,7 @@ char* NoAlNumToUnderscore(char* dest, const char* source)
|
|||
return dest;
|
||||
}
|
||||
|
||||
char IndexSeparator()
|
||||
char IndexSeparator(void)
|
||||
{
|
||||
/*
|
||||
// 20 bytes more costly !?!
|
||||
|
@ -394,7 +419,7 @@ void SetShortcutDefault(void)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t Shortcut()
|
||||
uint8_t Shortcut(void)
|
||||
{
|
||||
uint8_t result = 10;
|
||||
|
||||
|
@ -496,7 +521,7 @@ char* GetPowerDevice(char* dest, uint32_t idx, size_t size)
|
|||
return GetPowerDevice(dest, idx, size, 0);
|
||||
}
|
||||
|
||||
String GetDeviceHardware(void)
|
||||
bool IsEsp8285(void)
|
||||
{
|
||||
// esptool.py get_efuses
|
||||
uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
|
||||
|
@ -504,10 +529,22 @@ String GetDeviceHardware(void)
|
|||
// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
|
||||
// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("FUS: efuses 0x%08X 0x%08X, name %s"), efuse1, efuse2);
|
||||
|
||||
bool is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) );
|
||||
return String((is_8285) ? F("ESP8285") : F("ESP8266EX"));
|
||||
if (is_8285 && (ESP.getFlashChipRealSize() > 1048576)) {
|
||||
is_8285 = false; // ESP8285 can only have 1M flash
|
||||
}
|
||||
return is_8285;
|
||||
}
|
||||
|
||||
String GetDeviceHardware(void)
|
||||
{
|
||||
char buff[10];
|
||||
if (IsEsp8285()) {
|
||||
strcpy_P(buff, PSTR("ESP8285"));
|
||||
} else {
|
||||
strcpy_P(buff, PSTR("ESP8266EX"));
|
||||
}
|
||||
return String(buff);
|
||||
}
|
||||
|
||||
float ConvertTemp(float c)
|
||||
|
@ -520,6 +557,7 @@ float ConvertTemp(float c)
|
|||
if (!isnan(c) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
|
||||
result = c * 1.8 + 32; // Fahrenheit
|
||||
}
|
||||
result = result + (0.1 * Settings.temp_comp);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -530,6 +568,7 @@ float ConvertTempToCelsius(float c)
|
|||
if (!isnan(c) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
|
||||
result = (c - 32) / 1.8; // Celsius
|
||||
}
|
||||
result = result + (0.1 * Settings.temp_comp);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -899,7 +938,7 @@ int ResponseJsonEndEnd(void)
|
|||
* GPIO Module and Template management
|
||||
\*********************************************************************************************/
|
||||
|
||||
uint8_t ModuleNr()
|
||||
uint8_t ModuleNr(void)
|
||||
{
|
||||
// 0 = User module (255)
|
||||
// 1 up = Template module 0 up
|
||||
|
@ -931,7 +970,7 @@ String AnyModuleName(uint32_t index)
|
|||
}
|
||||
}
|
||||
|
||||
String ModuleName()
|
||||
String ModuleName(void)
|
||||
{
|
||||
return AnyModuleName(Settings.module);
|
||||
}
|
||||
|
@ -963,7 +1002,7 @@ void ModuleGpios(myio *gp)
|
|||
// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)gp, sizeof(myio));
|
||||
}
|
||||
|
||||
gpio_flag ModuleFlag()
|
||||
gpio_flag ModuleFlag(void)
|
||||
{
|
||||
gpio_flag flag;
|
||||
|
||||
|
@ -983,7 +1022,7 @@ void ModuleDefault(uint32_t module)
|
|||
memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt));
|
||||
}
|
||||
|
||||
void SetModuleType()
|
||||
void SetModuleType(void)
|
||||
{
|
||||
my_module_type = (USER_MODULE == Settings.module) ? Settings.user_template_base : Settings.module;
|
||||
}
|
||||
|
@ -998,11 +1037,14 @@ uint8_t ValidPin(uint32_t pin, uint32_t gpio)
|
|||
uint8_t result = gpio;
|
||||
|
||||
if (FlashPin(pin)) {
|
||||
result = GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
|
||||
result = GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
|
||||
}
|
||||
if ((WEMOS == Settings.module) && (!Settings.flag3.user_esp8285_enable)) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
if ((pin == 9) || (pin == 10)) { result = GPIO_NONE; } // Disable possible flash GPIO9 and GPIO10
|
||||
if (!IsEsp8285() && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
|
||||
if ((pin == 9) || (pin == 10)) {
|
||||
result = GPIO_NONE; // Disable possible flash GPIO9 and GPIO10
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1011,7 +1053,7 @@ bool ValidGPIO(uint32_t pin, uint32_t gpio)
|
|||
return (GPIO_USER == ValidPin(pin, gpio)); // Only allow GPIO_USER pins
|
||||
}
|
||||
|
||||
bool ValidAdc()
|
||||
bool ValidAdc(void)
|
||||
{
|
||||
gpio_flag flag = ModuleFlag();
|
||||
uint32_t template_adc0 = flag.data &15;
|
||||
|
@ -1111,7 +1153,7 @@ bool JsonTemplate(const char* dataBuf)
|
|||
return true;
|
||||
}
|
||||
|
||||
void TemplateJson()
|
||||
void TemplateJson(void)
|
||||
{
|
||||
Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name);
|
||||
for (uint32_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
|
||||
|
|
|
@ -26,7 +26,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
|
|||
D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|"
|
||||
D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|"
|
||||
D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|"
|
||||
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|"
|
||||
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|"
|
||||
#ifdef USE_I2C
|
||||
D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|"
|
||||
#endif
|
||||
|
@ -41,7 +41,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
|
|||
&CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialSend, &CmndBaudrate,
|
||||
&CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig,
|
||||
&CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
|
||||
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower,
|
||||
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset,
|
||||
#ifdef USE_I2C
|
||||
&CmndI2cScan, CmndI2cDriver,
|
||||
#endif
|
||||
|
@ -57,6 +57,13 @@ void ResponseCmndNumber(int value)
|
|||
Response_P(S_JSON_COMMAND_NVALUE, XdrvMailbox.command, value);
|
||||
}
|
||||
|
||||
void ResponseCmndFloat(float value, uint32_t decimals)
|
||||
{
|
||||
char stemp1[TOPSZ];
|
||||
dtostrfd(value, decimals, stemp1);
|
||||
Response_P(S_JSON_COMMAND_XVALUE, XdrvMailbox.command, stemp1); // Return float value without quotes
|
||||
}
|
||||
|
||||
void ResponseCmndIdxNumber(int value)
|
||||
{
|
||||
Response_P(S_JSON_COMMAND_INDEX_NVALUE, XdrvMailbox.command, XdrvMailbox.index, value);
|
||||
|
@ -362,7 +369,7 @@ void CmndStatus(void)
|
|||
D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\""
|
||||
D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url,
|
||||
GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep,
|
||||
GetResetReasonInfo().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep,
|
||||
Settings.cfg_holder, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
||||
}
|
||||
|
@ -496,6 +503,17 @@ void CmndState(void)
|
|||
#endif // USE_HOME_ASSISTANT
|
||||
}
|
||||
|
||||
void CmndTempOffset(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
int value = (int)(CharToFloat(XdrvMailbox.data) * 10);
|
||||
if ((value > -127) && (value < 127)) {
|
||||
Settings.temp_comp = value;
|
||||
}
|
||||
}
|
||||
ResponseCmndFloat((float)(Settings.temp_comp) / 10, 1);
|
||||
}
|
||||
|
||||
void CmndSleep(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) {
|
||||
|
@ -1540,9 +1558,7 @@ void CmndWifiPower(void)
|
|||
}
|
||||
WifiSetOutputPower();
|
||||
}
|
||||
char stemp1[TOPSZ];
|
||||
dtostrfd((float)(Settings.wifi_output_power) / 10, 1, stemp1);
|
||||
Response_P(S_JSON_COMMAND_XVALUE, XdrvMailbox.command, stemp1); // Return float value without quotes
|
||||
ResponseCmndFloat((float)(Settings.wifi_output_power) / 10, 1);
|
||||
}
|
||||
|
||||
#ifdef USE_I2C
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
* Functions not available in core 2.3.0
|
||||
\*********************************************************************************************/
|
||||
|
||||
// Functions not available in 2.3.0
|
||||
|
||||
// http://clc-wiki.net/wiki/C_standard_library:string.h:memchr
|
||||
void* memchr(const void* ptr, int value, size_t num)
|
||||
{
|
||||
|
@ -137,6 +135,15 @@ unsigned long long strtoull(const char *__restrict nptr, char **__restrict endpt
|
|||
return acc;
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
|
||||
|
||||
|
||||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2)
|
||||
/*********************************************************************************************\
|
||||
* Functions not available in core before 2.6.0
|
||||
\*********************************************************************************************/
|
||||
|
||||
// https://github.com/arendst/Tasmota/issues/6856#issuecomment-554258914
|
||||
void* memmove_P(void *dest, const void *src, size_t n)
|
||||
{
|
||||
|
@ -147,7 +154,4 @@ void* memmove_P(void *dest, const void *src, size_t n)
|
|||
}
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ESP8266_RELEASE_2_3_0
|
||||
/*********************************************************************************************\
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
#endif // ARDUINO_ESP8266_RELEASE < 2_6_0
|
||||
|
|
|
@ -217,7 +217,7 @@ void WifiBegin(uint8_t flag, uint8_t channel)
|
|||
#endif // LWIP_IPV6=1
|
||||
}
|
||||
|
||||
void WifiBeginAfterScan()
|
||||
void WifiBeginAfterScan(void)
|
||||
{
|
||||
static int8_t best_network_db;
|
||||
|
||||
|
@ -314,12 +314,12 @@ void WifiBeginAfterScan()
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t WifiLinkCount()
|
||||
uint16_t WifiLinkCount(void)
|
||||
{
|
||||
return Wifi.link_count;
|
||||
}
|
||||
|
||||
String WifiDowntime()
|
||||
String WifiDowntime(void)
|
||||
{
|
||||
return GetDuration(Wifi.downtime);
|
||||
}
|
||||
|
@ -615,7 +615,6 @@ void WifiShutdown(void)
|
|||
void EspRestart(void)
|
||||
{
|
||||
WifiShutdown();
|
||||
RtcRebootReset();
|
||||
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
|
||||
ESP.reset();
|
||||
}
|
||||
|
|
|
@ -100,7 +100,6 @@ const uint16_t PWM_MAX = 4000; // [PWM_MAX] Maximum frequency - Def
|
|||
const uint16_t PWM_MIN = 100; // [PWM_MIN] Minimum frequency - Default: 100
|
||||
// For Dimmers use double of your mains AC frequecy (100 for 50Hz and 120 for 60Hz)
|
||||
// For Controlling Servos use 50 and also set PWM_FREQ as 50 (DO NOT USE THESE VALUES FOR DIMMERS)
|
||||
//#define PWM_LIGHTSCHEME0_IGNORE_SLEEP // Do not change sleep value for LightAnimate() scheme 0
|
||||
|
||||
const uint16_t MAX_POWER_HOLD = 10; // Time in SECONDS to allow max agreed power
|
||||
const uint16_t MAX_POWER_WINDOW = 30; // Time in SECONDS to disable allow max agreed power
|
||||
|
|
|
@ -1500,10 +1500,6 @@ void GpioInit(void)
|
|||
XdrvCall(FUNC_PRE_INIT);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||
|
@ -1582,7 +1578,7 @@ void setup(void)
|
|||
Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic
|
||||
// Settings.last_module = SONOFF_BASIC;
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1605,7 +1601,7 @@ void setup(void)
|
|||
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
|
||||
SetDevicePower(1, SRC_RESTART);
|
||||
} else {
|
||||
if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) {
|
||||
if ((ResetReason() == REASON_DEFAULT_RST) || (ResetReason() == REASON_EXT_SYS_RST)) {
|
||||
switch (Settings.poweronstate) {
|
||||
case POWER_ALL_OFF:
|
||||
case POWER_ALL_OFF_PULSETIME_ON:
|
||||
|
@ -1665,7 +1661,7 @@ void setup(void)
|
|||
XsnsCall(FUNC_INIT);
|
||||
}
|
||||
|
||||
static void BacklogLoop()
|
||||
void BacklogLoop(void)
|
||||
{
|
||||
if (TimeReached(backlog_delay)) {
|
||||
if (!BACKLOG_EMPTY && !backlog_mutex) {
|
||||
|
|
|
@ -96,7 +96,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
|
|||
#define USE_BUZZER // Add support for a buzzer (+0k6 code)
|
||||
#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code, 252 iram (non 2.3.0))
|
||||
//#define USE_SHUTTER // Add Shutter support for up to 4 shutter with different motortypes (+6k code)
|
||||
//#define USE_DEEPSLEEP // Add support for deepsleep (+1k code)
|
||||
#define USE_DEEPSLEEP // Add support for deepsleep (+1k code)
|
||||
#define USE_EXS_DIMMER // Add support for EX-Store WiFi Dimmer
|
||||
|
||||
// -- Optional light modules ----------------------
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x07000004;
|
||||
const uint32_t VERSION = 0x07000005;
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
|
|
@ -733,7 +733,7 @@ void _WSContentSend(const String& content) // Low level sendContent for a
|
|||
DEBUG_CORE_LOG(PSTR("WEB: Chunk size %d"), len);
|
||||
}
|
||||
|
||||
void WSContentFlush()
|
||||
void WSContentFlush(void)
|
||||
{
|
||||
if (Web.chunk_buffer.length() > 0) {
|
||||
_WSContentSend(Web.chunk_buffer); // Flush chunk buffer
|
||||
|
|
|
@ -468,7 +468,7 @@ void MqttPublishPowerState(uint32_t device)
|
|||
#endif // USE_SONOFF_IFAN
|
||||
}
|
||||
|
||||
void MqttPublishAllPowerState()
|
||||
void MqttPublishAllPowerState(void)
|
||||
{
|
||||
for (uint32_t i = 1; i <= devices_present; i++) {
|
||||
MqttPublishPowerState(i);
|
||||
|
@ -493,7 +493,7 @@ void MqttPublishPowerBlinkState(uint32_t device)
|
|||
|
||||
/*********************************************************************************************/
|
||||
|
||||
uint16_t MqttConnectCount()
|
||||
uint16_t MqttConnectCount(void)
|
||||
{
|
||||
return Mqtt.connect_count;
|
||||
}
|
||||
|
@ -555,7 +555,7 @@ void MqttConnected(void)
|
|||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
||||
}
|
||||
#endif // USE_WEBSERVER
|
||||
Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), (GetResetReason() == "Exception") ? ESP.getResetInfo().c_str() : GetResetReason().c_str());
|
||||
Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), GetResetReasonInfo().c_str());
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"));
|
||||
MqttPublishAllPowerState();
|
||||
if (Settings.tele_period) {
|
||||
|
@ -1134,7 +1134,9 @@ void CmndTlsKey(void) {
|
|||
memcpy(spi_buffer + tls_obj_store_offset + entry->start, bin_buf, entry->len);
|
||||
}
|
||||
|
||||
TlsWriteSpiBuffer(spi_buffer);
|
||||
if (ESP.flashEraseSector(tls_spi_start_sector)) {
|
||||
ESP.flashWrite(tls_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
free(spi_buffer);
|
||||
free(bin_buf);
|
||||
}
|
||||
|
@ -1146,26 +1148,6 @@ void CmndTlsKey(void) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include "spi_flash.h"
|
||||
}
|
||||
|
||||
void TlsWriteSpiBuffer(uint8_t *buf) {
|
||||
bool ret = false;
|
||||
SpiFlashOpResult res;
|
||||
|
||||
noInterrupts();
|
||||
res = spi_flash_erase_sector(tls_spi_start_sector);
|
||||
if (SPI_FLASH_RESULT_OK == res) {
|
||||
res = spi_flash_write(tls_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) buf, SPI_FLASH_SEC_SIZE);
|
||||
if (SPI_FLASH_RESULT_OK == res) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
interrupts();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DUMP_TLS
|
||||
// Dump TLS Flash data - don't activate in production to protect your private keys
|
||||
uint32_t bswap32(uint32_t x) {
|
||||
|
|
|
@ -430,7 +430,7 @@ void EnergyMqttShow(void)
|
|||
}
|
||||
#endif // USE_ENERGY_MARGIN_DETECTION
|
||||
|
||||
void EnergyEverySecond()
|
||||
void EnergyEverySecond(void)
|
||||
{
|
||||
// Overtemp check
|
||||
if (global_update) {
|
||||
|
|
|
@ -1621,11 +1621,11 @@ void LightAnimate(void)
|
|||
}
|
||||
}
|
||||
else {
|
||||
#ifdef PWM_LIGHTSCHEME0_IGNORE_SLEEP
|
||||
sleep = (LS_POWER == Settings.light_scheme) ? Settings.sleep : 0; // If no animation then use sleep as is
|
||||
#else
|
||||
sleep = 0;
|
||||
#endif // PWM_LIGHTSCHEME0_IGNORE_SLEEP
|
||||
if (Settings.sleep > 10) {
|
||||
sleep = 10; // set a minimal value of 50 milliseconds to ensure that animations are smooth
|
||||
} else {
|
||||
sleep = Settings.sleep; // or keep the current sleep if it's lower than 50
|
||||
}
|
||||
switch (Settings.light_scheme) {
|
||||
case LS_POWER:
|
||||
light_controller.calcLevels();
|
||||
|
|
|
@ -66,7 +66,7 @@ IRrecv *irrecv = nullptr;
|
|||
|
||||
unsigned long ir_lasttime = 0;
|
||||
|
||||
void IrReceiveUpdateThreshold()
|
||||
void IrReceiveUpdateThreshold(void)
|
||||
{
|
||||
if (irrecv != nullptr) {
|
||||
if (Settings.param[P_IR_UNKNOW_THRESHOLD] < 6) { Settings.param[P_IR_UNKNOW_THRESHOLD] = 6; }
|
||||
|
|
|
@ -92,7 +92,7 @@ IRrecv *irrecv = nullptr;
|
|||
|
||||
unsigned long ir_lasttime = 0;
|
||||
|
||||
void IrReceiveUpdateThreshold()
|
||||
void IrReceiveUpdateThreshold(void)
|
||||
{
|
||||
if (irrecv != nullptr) {
|
||||
if (Settings.param[P_IR_UNKNOW_THRESHOLD] < 6) { Settings.param[P_IR_UNKNOW_THRESHOLD] = 6; }
|
||||
|
|
|
@ -80,7 +80,7 @@ int DomoticzRssiQuality(void)
|
|||
}
|
||||
|
||||
#ifdef USE_SONOFF_IFAN
|
||||
void MqttPublishDomoticzFanState()
|
||||
void MqttPublishDomoticzFanState(void)
|
||||
{
|
||||
if (Settings.flag.mqtt_enabled && Settings.domoticz_relay_idx[1]) { // SetOption3 - Enable MQTT
|
||||
char svalue[8]; // Fanspeed value
|
||||
|
@ -94,7 +94,7 @@ void MqttPublishDomoticzFanState()
|
|||
}
|
||||
}
|
||||
|
||||
void DomoticzUpdateFanState()
|
||||
void DomoticzUpdateFanState(void)
|
||||
{
|
||||
if (domoticz_update_flag) {
|
||||
MqttPublishDomoticzFanState();
|
||||
|
|
|
@ -497,9 +497,7 @@ void CmndLongitude(void)
|
|||
if (XdrvMailbox.data_len) {
|
||||
Settings.longitude = (int)(CharToFloat(XdrvMailbox.data) *1000000);
|
||||
}
|
||||
char lbuff[33];
|
||||
dtostrfd(((float)Settings.longitude) /1000000, 6, lbuff);
|
||||
ResponseCmndChar(lbuff);
|
||||
ResponseCmndFloat((float)(Settings.longitude) /1000000, 6);
|
||||
}
|
||||
|
||||
void CmndLatitude(void)
|
||||
|
@ -507,9 +505,7 @@ void CmndLatitude(void)
|
|||
if (XdrvMailbox.data_len) {
|
||||
Settings.latitude = (int)(CharToFloat(XdrvMailbox.data) *1000000);
|
||||
}
|
||||
char lbuff[33];
|
||||
dtostrfd(((float)Settings.latitude) /1000000, 6, lbuff);
|
||||
ResponseCmndChar(lbuff);
|
||||
ResponseCmndFloat((float)(Settings.latitude) /1000000, 6);
|
||||
}
|
||||
#endif // USE_SUNRISE
|
||||
|
||||
|
|
|
@ -1226,7 +1226,7 @@ float evaluateExpression(const char * expression, unsigned int len)
|
|||
#endif // USE_EXPRESSION
|
||||
|
||||
#ifdef SUPPORT_IF_STATEMENT
|
||||
void CmndIf()
|
||||
void CmndIf(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
char parameters[XdrvMailbox.data_len+1];
|
||||
|
|
|
@ -43,7 +43,7 @@ bool ifan_restart_flag = true;
|
|||
|
||||
/*********************************************************************************************/
|
||||
|
||||
bool IsModuleIfan()
|
||||
bool IsModuleIfan(void)
|
||||
{
|
||||
return ((SONOFF_IFAN02 == my_module_type) || (SONOFF_IFAN03 == my_module_type));
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ void Pcf8574SwitchRelay(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Pcf8574Init()
|
||||
void Pcf8574Init(void)
|
||||
{
|
||||
uint8_t pcf8574_address = PCF8574_ADDR1;
|
||||
while ((Pcf8574.max_devices < MAX_PCF8574) && (pcf8574_address < PCF8574_ADDR2 +8)) {
|
||||
|
@ -178,7 +178,7 @@ void HandlePcf8574(void)
|
|||
WSContentStop();
|
||||
}
|
||||
|
||||
void Pcf8574SaveSettings()
|
||||
void Pcf8574SaveSettings(void)
|
||||
{
|
||||
char stemp[7];
|
||||
char tmp[100];
|
||||
|
|
|
@ -30,12 +30,14 @@
|
|||
|
||||
#define XDRV_29 29
|
||||
|
||||
#define MAX_DEEPSLEEP_CYCLE 3600 // Maximum time for a deepsleep
|
||||
#define MIN_DEEPSLEEP_TIME 5
|
||||
|
||||
#define D_PRFX_DEEPSLEEP "DeepSleep"
|
||||
#define D_CMND_DEEPSLEEP_TIME "Time"
|
||||
|
||||
const uint32_t DEEPSLEEP_MAX = 10 * 366 * 24 * 60 * 60; // Allow max 10 years sleep
|
||||
const uint32_t DEEPSLEEP_MAX_CYCLE = 60 * 60; // Maximum time for a deepsleep as defined by chip hardware
|
||||
const uint32_t DEEPSLEEP_MIN_TIME = 5; // Allow 5 seconds skew
|
||||
const uint32_t DEEPSLEEP_START_COUNTDOWN = 4; // Allow 4 seconds to update web console before deepsleep
|
||||
|
||||
const char kDeepsleepCommands[] PROGMEM = D_PRFX_DEEPSLEEP "|"
|
||||
D_CMND_DEEPSLEEP_TIME ;
|
||||
|
||||
|
@ -47,28 +49,29 @@ uint8_t deepsleep_flag = 0;
|
|||
|
||||
bool DeepSleepEnabled(void)
|
||||
{
|
||||
if (Settings.deepsleep < 10) {
|
||||
return false;
|
||||
if ((Settings.deepsleep < 10) || (Settings.deepsleep > DEEPSLEEP_MAX)) {
|
||||
Settings.deepsleep = 0; // Issue #6961
|
||||
return false; // Disabled
|
||||
}
|
||||
|
||||
if (pin[GPIO_DEEPSLEEP] < 99) {
|
||||
pinMode(pin[GPIO_DEEPSLEEP], INPUT_PULLUP);
|
||||
return (digitalRead(pin[GPIO_DEEPSLEEP])); // Disable DeepSleep if user holds pin GPIO_DEEPSLEEP low
|
||||
return (digitalRead(pin[GPIO_DEEPSLEEP])); // Disable DeepSleep if user holds pin GPIO_DEEPSLEEP low
|
||||
}
|
||||
|
||||
return true;
|
||||
return true; // Enabled
|
||||
}
|
||||
|
||||
void DeepSleepInit(void)
|
||||
void DeepSleepReInit(void)
|
||||
{
|
||||
if (DeepSleepEnabled()) {
|
||||
RtcRebootReset();
|
||||
if ((RtcSettings.ultradeepsleep > MAX_DEEPSLEEP_CYCLE) && (RtcSettings.ultradeepsleep < 1700000000)) {
|
||||
if ((ResetReason() == REASON_DEEP_SLEEP_AWAKE) && DeepSleepEnabled()) {
|
||||
if ((RtcSettings.ultradeepsleep > DEEPSLEEP_MAX_CYCLE) && (RtcSettings.ultradeepsleep < 1700000000)) {
|
||||
// Go back to sleep after 60 minutes if requested deepsleep has not been reached
|
||||
RtcSettings.ultradeepsleep = RtcSettings.ultradeepsleep - MAX_DEEPSLEEP_CYCLE;
|
||||
RtcSettings.ultradeepsleep = RtcSettings.ultradeepsleep - DEEPSLEEP_MAX_CYCLE;
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DSL: Remain DeepSleep %d"), RtcSettings.ultradeepsleep);
|
||||
RtcSettingsSave();
|
||||
ESP.deepSleep(100 * RtcSettings.deepsleep_slip * (MAX_DEEPSLEEP_CYCLE < RtcSettings.ultradeepsleep ? MAX_DEEPSLEEP_CYCLE : RtcSettings.ultradeepsleep), WAKE_RF_DEFAULT);
|
||||
RtcRebootReset();
|
||||
ESP.deepSleep(100 * RtcSettings.deepsleep_slip * (DEEPSLEEP_MAX_CYCLE < RtcSettings.ultradeepsleep ? DEEPSLEEP_MAX_CYCLE : RtcSettings.ultradeepsleep), WAKE_RF_DEFAULT);
|
||||
yield();
|
||||
// Sleeping
|
||||
}
|
||||
|
@ -77,7 +80,7 @@ void DeepSleepInit(void)
|
|||
RtcSettings.ultradeepsleep = 0;
|
||||
}
|
||||
|
||||
void DeepSleepCheck(void)
|
||||
void DeepSleepPrepare(void)
|
||||
{
|
||||
// Deepsleep_slip is ideally 10.000 == 100%
|
||||
// Typically the device has up to 4% slip. Anything else is a wrong setting in the deepsleep_slip
|
||||
|
@ -87,8 +90,7 @@ void DeepSleepCheck(void)
|
|||
(RtcSettings.deepsleep_slip < 9000) ||
|
||||
(RtcSettings.deepsleep_slip > 11000) ||
|
||||
(RtcSettings.nextwakeup > (UtcTime() + Settings.deepsleep))) {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DSL: Reset wrong settings wakeup: %ld, slip %ld"),
|
||||
RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DSL: Reset wrong settings wakeup: %ld, slip %ld"), RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
|
||||
RtcSettings.nextwakeup = 0;
|
||||
RtcSettings.deepsleep_slip = 10000;
|
||||
}
|
||||
|
@ -109,15 +111,15 @@ void DeepSleepCheck(void)
|
|||
|
||||
// It may happen that wakeup in just <5 seconds in future
|
||||
// In this case also add deepsleep to nextwakeup
|
||||
if (RtcSettings.nextwakeup <= (UtcTime() - MIN_DEEPSLEEP_TIME)) {
|
||||
if (RtcSettings.nextwakeup <= (UtcTime() - DEEPSLEEP_MIN_TIME)) {
|
||||
// ensure nextwakeup is at least in the future
|
||||
RtcSettings.nextwakeup += (((UtcTime() + MIN_DEEPSLEEP_TIME - RtcSettings.nextwakeup) / Settings.deepsleep) + 1) * Settings.deepsleep;
|
||||
RtcSettings.nextwakeup += (((UtcTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings.deepsleep) + 1) * Settings.deepsleep;
|
||||
}
|
||||
|
||||
String dt = GetDT(RtcSettings.nextwakeup + LocalTime() - UtcTime()); // 2017-03-07T11:08:02
|
||||
// Limit sleeptime to MAX_DEEPSLEEP_CYCLE
|
||||
// uint32_t deepsleep_sleeptime = MAX_DEEPSLEEP_CYCLE < (RtcSettings.nextwakeup - UtcTime()) ? (uint32_t)MAX_DEEPSLEEP_CYCLE : RtcSettings.nextwakeup - UtcTime();
|
||||
deepsleep_sleeptime = tmin((uint32_t)MAX_DEEPSLEEP_CYCLE ,RtcSettings.nextwakeup - UtcTime());
|
||||
// Limit sleeptime to DEEPSLEEP_MAX_CYCLE
|
||||
// uint32_t deepsleep_sleeptime = DEEPSLEEP_MAX_CYCLE < (RtcSettings.nextwakeup - UtcTime()) ? (uint32_t)DEEPSLEEP_MAX_CYCLE : RtcSettings.nextwakeup - UtcTime();
|
||||
deepsleep_sleeptime = tmin((uint32_t)DEEPSLEEP_MAX_CYCLE ,RtcSettings.nextwakeup - UtcTime());
|
||||
|
||||
// stat/tasmota/STATUS = {"DeepSleep":{"Time":"2019-11-12T21:33:45","Epoch":1573590825}}
|
||||
Response_P(PSTR("{\"" D_PRFX_DEEPSLEEP "\":{\"" D_JSON_TIME "\":\"%s\",\"Epoch\":%d}}"), (char*)dt.c_str(), RtcSettings.nextwakeup);
|
||||
|
@ -144,9 +146,9 @@ void DeepSleepEverySecond(void)
|
|||
if (!deepsleep_flag) { return; }
|
||||
|
||||
if (DeepSleepEnabled()) {
|
||||
if (4 == deepsleep_flag) { // Allow 4 seconds to update web console before deepsleep
|
||||
if (DEEPSLEEP_START_COUNTDOWN == deepsleep_flag) { // Allow 4 seconds to update web console before deepsleep
|
||||
SettingsSaveAll();
|
||||
DeepSleepCheck();
|
||||
DeepSleepPrepare();
|
||||
}
|
||||
deepsleep_flag--;
|
||||
if (deepsleep_flag <= 0) {
|
||||
|
@ -164,10 +166,10 @@ void DeepSleepEverySecond(void)
|
|||
void CmndDeepsleepTime(void)
|
||||
{
|
||||
if ((0 == XdrvMailbox.payload) ||
|
||||
((XdrvMailbox.payload > 10) && (XdrvMailbox.payload < (10 * 366 * 24 * 60 * 60)))) { // Allow max 10 years sleep
|
||||
((XdrvMailbox.payload > 10) && (XdrvMailbox.payload < DEEPSLEEP_MAX))) {
|
||||
Settings.deepsleep = XdrvMailbox.payload;
|
||||
RtcSettings.nextwakeup = 0;
|
||||
deepsleep_flag = (0 == XdrvMailbox.payload) ? 0 : 4;
|
||||
deepsleep_flag = (0 == XdrvMailbox.payload) ? 0 : DEEPSLEEP_START_COUNTDOWN;
|
||||
if (deepsleep_flag) {
|
||||
if (!Settings.tele_period) {
|
||||
Settings.tele_period = TELE_PERIOD; // Need teleperiod to go back to sleep
|
||||
|
@ -190,15 +192,15 @@ bool Xdrv29(uint8_t function)
|
|||
DeepSleepEverySecond();
|
||||
break;
|
||||
case FUNC_AFTER_TELEPERIOD:
|
||||
if (!deepsleep_flag) {
|
||||
deepsleep_flag = 4; // Start deepsleep in 4 seconds
|
||||
if (DeepSleepEnabled() && !deepsleep_flag) {
|
||||
deepsleep_flag = DEEPSLEEP_START_COUNTDOWN; // Start deepsleep in 4 seconds
|
||||
}
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kDeepsleepCommands, DeepsleepCommand);
|
||||
break;
|
||||
case FUNC_PRE_INIT:
|
||||
DeepSleepInit();
|
||||
DeepSleepReInit();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -75,7 +75,10 @@ const char kDebugCommands[] PROGMEM = "|" // No prefix
|
|||
D_CMND_EXCEPTION "|"
|
||||
#endif
|
||||
D_CMND_FLASHDUMP "|" D_CMND_FLASHMODE "|" D_CMND_FREEMEM"|" D_CMND_HELP "|" D_CMND_RTCDUMP "|" D_CMND_SETSENSOR "|"
|
||||
D_CMND_I2CWRITE "|" D_CMND_I2CREAD "|" D_CMND_I2CSTRETCH "|" D_CMND_I2CCLOCK ;
|
||||
#ifdef USE_I2C
|
||||
D_CMND_I2CWRITE "|" D_CMND_I2CREAD "|" D_CMND_I2CSTRETCH "|" D_CMND_I2CCLOCK
|
||||
#endif
|
||||
;
|
||||
|
||||
void (* const DebugCommand[])(void) PROGMEM = {
|
||||
&CmndCfgDump, &CmndCfgPeek, &CmndCfgPoke,
|
||||
|
@ -90,7 +93,10 @@ void (* const DebugCommand[])(void) PROGMEM = {
|
|||
&CmndException,
|
||||
#endif
|
||||
&CmndFlashDump, &CmndFlashMode, &CmndFreemem, &CmndHelp, &CmndRtcDump, &CmndSetSensor,
|
||||
&CmndI2cWrite, &CmndI2cRead, &CmndI2cStretch, &CmndI2cClock };
|
||||
#ifdef USE_I2C
|
||||
&CmndI2cWrite, &CmndI2cRead, &CmndI2cStretch, &CmndI2cClock
|
||||
#endif
|
||||
};
|
||||
|
||||
uint32_t CPU_loops = 0;
|
||||
uint32_t CPU_last_millis = 0;
|
||||
|
@ -575,6 +581,7 @@ void CmndFlashDump(void)
|
|||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
#ifdef USE_I2C
|
||||
void CmndI2cWrite(void)
|
||||
{
|
||||
// I2cWrite <address>,<data>..
|
||||
|
@ -652,6 +659,7 @@ void CmndI2cClock(void)
|
|||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
#endif // USE_I2C
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
|
|
|
@ -47,7 +47,7 @@ extern uint8_t *buffer;
|
|||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void SSD1306InitDriver()
|
||||
void SSD1306InitDriver(void)
|
||||
{
|
||||
if (!Settings.display_model) {
|
||||
if (I2cSetDevice(OLED_ADDRESS1)) {
|
||||
|
|
|
@ -185,7 +185,7 @@ void Ade7953GetData(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Ade7953EnergyEverySecond()
|
||||
void Ade7953EnergyEverySecond(void)
|
||||
{
|
||||
if (Ade7953.init_step) {
|
||||
if (1 == Ade7953.init_step) {
|
||||
|
|
|
@ -201,7 +201,7 @@ uint16_t solaxX1_calculateCRC(uint8_t *bExternTxPackage, uint8_t bLen)
|
|||
return wChkSum;
|
||||
}
|
||||
|
||||
void solaxX1_SendInverterAddress()
|
||||
void solaxX1_SendInverterAddress(void)
|
||||
{
|
||||
source[0] = 0x00;
|
||||
destination[0] = 0x00;
|
||||
|
@ -213,7 +213,7 @@ void solaxX1_SendInverterAddress()
|
|||
solaxX1_RS485Send(24);
|
||||
}
|
||||
|
||||
void solaxX1_QueryLiveData()
|
||||
void solaxX1_QueryLiveData(void)
|
||||
{
|
||||
source[0] = 0x01;
|
||||
destination[0] = 0x00;
|
||||
|
|
|
@ -101,7 +101,7 @@ void AdcEvery250ms(void)
|
|||
}
|
||||
#endif // USE_RULES
|
||||
|
||||
uint16_t AdcGetLux()
|
||||
uint16_t AdcGetLux(void)
|
||||
{
|
||||
int adc = AdcRead(2);
|
||||
// Source: https://www.allaboutcircuits.com/projects/design-a-luxmeter-using-a-light-dependent-resistor/
|
||||
|
|
|
@ -90,7 +90,7 @@ bool HxIsReady(uint16_t timeout)
|
|||
return (digitalRead(Hx.pin_dout) == LOW);
|
||||
}
|
||||
|
||||
long HxRead()
|
||||
long HxRead(void)
|
||||
{
|
||||
if (!HxIsReady(HX_TIMEOUT)) { return -1; }
|
||||
|
||||
|
@ -241,7 +241,7 @@ bool HxCommand(void)
|
|||
|
||||
/*********************************************************************************************/
|
||||
|
||||
long HxWeight()
|
||||
long HxWeight(void)
|
||||
{
|
||||
return (Hx.calibrate_step < HX_CAL_FAIL) ? Hx.weight : 0;
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ void HxEvery100mSecond(void)
|
|||
}
|
||||
}
|
||||
|
||||
void HxSaveBeforeRestart()
|
||||
void HxSaveBeforeRestart(void)
|
||||
{
|
||||
Settings.energy_frequency_calibration = Hx.weight;
|
||||
Hx.sample_count = HX_SAMPLES +1; // Stop updating Hx.weight
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<li>can restore previously backup and changed <a href="http://www.json.org/">JSON</a>-format files,</li>
|
||||
<li>is able to create Tasmota compatible command list with related config parameter</li>
|
||||
</ul>
|
||||
<p>Comparing backup files created by <em>decode-config.py</em> and *.dmp files created by Tasmota "Backup/Restore Configuration": </p>
|
||||
<p>Comparing backup files created by <em>decode-config.py</em> and *.dmp files created by Tasmota "Backup/Restore Configuration":</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -75,23 +75,39 @@
|
|||
</ul>
|
||||
<h2 id="prerequisite">Prerequisite</h2>
|
||||
<ul>
|
||||
<li><p><a href="https://en.wikipedia.org/wiki/Python_(programming_language">Python</a>)<br>This program is written in <a href="https://en.wikipedia.org/wiki/Python_(programming_language">Python</a>) so you need to install a working python environment (for details see <a href="https://docs.python.org/2.7/using/index.html">Python Setup and Usage</a>)</p>
|
||||
</li>
|
||||
<li><p><a href="https://github.com/arendst/Tasmota">Tasmota</a> <a href="https://github.com/arendst/Tasmota/releases">Firmware</a> with Web-Server enabled:</p>
|
||||
<ul>
|
||||
<li>This program is written in <a href="https://en.wikipedia.org/wiki/Python_(programming_language">Python</a>) so you need to install a working python environment for your operating system.</li>
|
||||
</ul>
|
||||
<h3 id="linux">Linux</h3>
|
||||
<pre><code>sudo apt-<span class="hljs-built_in">get</span> install python python-pip libcurl4-openssl-<span class="hljs-built_in">dev</span> libssl-<span class="hljs-built_in">dev</span>
|
||||
</code></pre><pre><code>pip <span class="hljs-keyword">install</span> pycurl configargparse
|
||||
</code></pre><h3 id="windows-10">Windows 10</h3>
|
||||
<p>Install <a href="https://www.python.org/download/releases/2.7/">Python 2.7</a> then install dependencies. For PyCurl you need to <a href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#pycurl">download pycurl‑7.43.0.3‑cp27‑cp27m‑win_amd64.whl</a> for Windows 10 64bit.</p>
|
||||
<pre><code>pip install pycurl<span class="hljs-number">-7.43</span><span class="hljs-number">.0</span><span class="hljs-number">.3</span>-cp27-cp27m-win_amd64.whl configargparse
|
||||
<span class="hljs-comment">// run the command from the folder where you downloaded the file</span>
|
||||
|
||||
pip install configargparse
|
||||
</code></pre><ul>
|
||||
<li><a href="https://github.com/arendst/Tasmota">Tasmota</a> <a href="https://github.com/arendst/Tasmota/releases">Firmware</a> with Web-Server enabled:<ul>
|
||||
<li>To backup or restore configurations from or to a Tasmota device you need a firmare with enabled web-server in admin mode (command <a href="https://github.com/arendst/Tasmota/wiki/Commands#wifi">WebServer 2</a>). This is the Tasmota default.</li>
|
||||
<li>If using your own compiled firmware be aware to enable the web-server (<code>#define USE_WEBSERVER</code> and <code>#define WEB_SERVER 2</code>).</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="file-types">File Types</h2>
|
||||
<p><em>decode-config.py</em> can handle the following backup file types: </p>
|
||||
<p><em>decode-config.py</em> can handle the following backup file types:</p>
|
||||
<h3 id="-dmp-format">.dmp Format</h3>
|
||||
<p>Configuration data as used by Tasmota "Backup/Restore Configuration" web interface.<br>This format is binary and encrypted.</p>
|
||||
<p>Configuration data as used by Tasmota "Backup/Restore Configuration" web interface.
|
||||
This format is binary and encrypted.</p>
|
||||
<h3 id="-json-format">.json Format</h3>
|
||||
<p>Configuration data in <a href="http://www.json.org/">JSON</a>-format.<br>This format is decrypted, human readable and editable and can also be used for the <code>--restore-file</code> parameter.<br>This file will be created by <em>decode-config.py</em> using the <code>--backup-file</code> with <code>--backup-type json</code> parameter, this is the default.</p>
|
||||
<p>Configuration data in <a href="http://www.json.org/">JSON</a>-format.
|
||||
This format is decrypted, human readable and editable and can also be used for the <code>--restore-file</code> parameter.
|
||||
This file will be created by <em>decode-config.py</em> using the <code>--backup-file</code> with <code>--backup-type json</code> parameter, this is the default.</p>
|
||||
<h3 id="-bin-format">.bin Format</h3>
|
||||
<p>Configuration data in binary format.<br>This format is binary decryptet, editable (e.g. using a hex editor) and can also be used for <code>--restore-file</code> command.<br>It will be created by <em>decode-config.py</em> using <code>--backup-file</code> with <code>--backup-type bin</code>.<br>Note:<br>The .bin file contains the same information as the original .dmp file from Tasmota "Backup/Restore Configuration" but it is decrpted and 4 byte longer than an original (it is a prefix header at the beginning). .bin file data starting at address 4 contains the same as the <strong>struct SYSCFG</strong> from Tasmota <a href="https://github.com/arendst/Tasmota/blob/master/sonoff/settings.h">settings.h</a> in decrypted format.</p>
|
||||
<p>Configuration data in binary format.
|
||||
This format is binary decryptet, editable (e.g. using a hex editor) and can also be used for <code>--restore-file</code> command.
|
||||
It will be created by <em>decode-config.py</em> using <code>--backup-file</code> with <code>--backup-type bin</code>.
|
||||
Note:
|
||||
The .bin file contains the same information as the original .dmp file from Tasmota "Backup/Restore Configuration" but it is decrpted and 4 byte longer than an original (it is a prefix header at the beginning). .bin file data starting at address 4 contains the same as the <strong>struct SYSCFG</strong> from Tasmota <a href="https://github.com/arendst/Tasmota/blob/master/tasmota/settings.h">settings.h</a> in decrypted format.</p>
|
||||
<h4 id="file-extensions">File extensions</h4>
|
||||
<p>You don't need to append exensions for your file name as <em>decode-config.py</em> uses auto extension as default. The extension will be choose based on file contents and <code>--backup-type</code> parameter.
|
||||
If you do not want using auto extensions use the <code>--no-extension</code> parameter.</p>
|
||||
|
@ -99,13 +115,13 @@ If you do not want using auto extensions use the <code>--no-extension</code> par
|
|||
<p>After download don't forget to set the executable flag under linux with <code>chmod +x decode-config.py</code> or call the program using <code>python decode-config.py...</code>.</p>
|
||||
<h3 id="basics">Basics</h3>
|
||||
<p>At least pass a source where you want to read the configuration data from using <code>-f <filename></code> or <code>-d <host></code>:</p>
|
||||
<p>The source can be either </p>
|
||||
<p>The source can be either</p>
|
||||
<ul>
|
||||
<li>a Tasmota device hostname or IP using the <code>-d <host></code> parameter</li>
|
||||
<li>a Tasmota <code>*.dmp</code> configuration file using <code>-f <filename></code> parameter</li>
|
||||
</ul>
|
||||
<p>Example: </p>
|
||||
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d sonoff-<span class="hljs-number">4281</span>
|
||||
<p>Example:</p>
|
||||
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d tasmota-<span class="hljs-number">4281</span>
|
||||
</code></pre><p>will output a human readable configuration in <a href="http://www.json.org/">JSON</a>-format:</p>
|
||||
<pre><code>{
|
||||
<span class="hljs-string">"altitude"</span>: <span class="hljs-number">112</span>,
|
||||
|
@ -120,24 +136,24 @@ If you do not want using auto extensions use the <code>--no-extension</code> par
|
|||
]
|
||||
}
|
||||
</code></pre><h3 id="save-backup-file">Save backup file</h3>
|
||||
<p>To save the output as backup file use <code>--backup-file <filename></code>, you can use placeholder for Version, Friendlyname and Hostname: </p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">--backup-file</span> <span class="hljs-selector-tag">Config_</span>@<span class="hljs-keyword">f_</span>@<span class="hljs-keyword">v</span>
|
||||
<p>To save the output as backup file use <code>--backup-file <filename></code>, you can use placeholder for Version, Friendlyname and Hostname:</p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">tasmota-4281</span> <span class="hljs-selector-tag">--backup-file</span> <span class="hljs-selector-tag">Config_</span>@<span class="hljs-keyword">f_</span>@<span class="hljs-keyword">v</span>
|
||||
</code></pre><p>If you have setup a WebPassword within Tasmota, use</p>
|
||||
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d sonoff-<span class="hljs-number">4281</span> -<span class="hljs-selector-tag">p</span> <yourpassword> --backup-file Config_@f_@v
|
||||
</code></pre><p>will create a file like <code>Config_Sonoff_6.4.0.json</code> (the part <code>Sonoff</code> and <code>6.4.0</code> will choosen related to your device configuration). Because the default backup file format is JSON, you can read and change it with any raw text editor.</p>
|
||||
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d tasmota-<span class="hljs-number">4281</span> -<span class="hljs-selector-tag">p</span> <yourpassword> --backup-file Config_@f_@v
|
||||
</code></pre><p>will create a file like <code>Config_Tasmota_6.4.0.json</code> (the part <code>Tasmota</code> and <code>6.4.0</code> will choosen related to your device configuration). Because the default backup file format is JSON, you can read and change it with any raw text editor.</p>
|
||||
<h3 id="restore-backup-file">Restore backup file</h3>
|
||||
<p>Reading back a saved (and possible changed) backup file use the <code>--restore-file <filename></code> parameter. This will read the (changed) configuration data from this file and send it back to the source device or filename.</p>
|
||||
<p>To restore the previously save backup file <code>Config_Sonoff_6.2.1.json</code> to device <code>sonoff-4281</code> use: </p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">--restore-file</span> <span class="hljs-selector-tag">Config_Sonoff_6</span><span class="hljs-selector-class">.2</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.json</span>
|
||||
<p>To restore the previously save backup file <code>Config_Tasmota_6.2.1.json</code> to device <code>tasmota-4281</code> use:</p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">tasmota-4281</span> <span class="hljs-selector-tag">--restore-file</span> <span class="hljs-selector-tag">Config_Tasmota_6</span><span class="hljs-selector-class">.2</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.json</span>
|
||||
</code></pre><p>with password set by WebPassword:</p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">-p</span> <<span class="hljs-selector-tag">yourpassword</span>> <span class="hljs-selector-tag">--restore-file</span> <span class="hljs-selector-tag">Config_Sonoff_6</span><span class="hljs-selector-class">.2</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.json</span>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">tasmota-4281</span> <span class="hljs-selector-tag">-p</span> <<span class="hljs-selector-tag">yourpassword</span>> <span class="hljs-selector-tag">--restore-file</span> <span class="hljs-selector-tag">Config_Tasmota_6</span><span class="hljs-selector-class">.2</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.json</span>
|
||||
</code></pre><h3 id="output-to-screen">Output to screen</h3>
|
||||
<p>To force screen output use the <code>--output</code> parameter.</p>
|
||||
<p>Output to screen is default enabled when calling the program with a source parameter (-f or -d) but without any backup or restore parameter.</p>
|
||||
<h4 id="json-output">JSON output</h4>
|
||||
<p>The default output format is <a href="decode-config.md#-json-format">JSON</a>. You can force JSON output using the <code>--output-format json</code> parameter.</p>
|
||||
<p>Example:</p>
|
||||
<pre><code>decode-config.py -d sonoff<span class="hljs-number">-4281</span> -c my.conf -x <span class="hljs-symbol">Wifi</span> --output-format json
|
||||
<pre><code>decode-config.py -d tasmota<span class="hljs-number">-4281</span> -c my.conf -x <span class="hljs-symbol">Wifi</span> --output-format json
|
||||
|
||||
{
|
||||
...
|
||||
|
@ -171,7 +187,7 @@ If you do not want using auto extensions use the <code>--no-extension</code> par
|
|||
<h4 id="tasmota-command-output">Tasmota command output</h4>
|
||||
<p><em>decode-config.py</em> is able to translate the configuration data to (most all) Tasmota commands. To output your configuration as Tasmota commands use <code>--output-format cmnd</code> or <code>--output-format command</code>.</p>
|
||||
<p>Example:</p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">-c</span> <span class="hljs-selector-tag">my</span><span class="hljs-selector-class">.conf</span> <span class="hljs-selector-tag">-g</span> <span class="hljs-selector-tag">Wifi</span> <span class="hljs-selector-tag">--output-format</span> <span class="hljs-selector-tag">cmnd</span>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">tasmota-4281</span> <span class="hljs-selector-tag">-c</span> <span class="hljs-selector-tag">my</span><span class="hljs-selector-class">.conf</span> <span class="hljs-selector-tag">-g</span> <span class="hljs-selector-tag">Wifi</span> <span class="hljs-selector-tag">--output-format</span> <span class="hljs-selector-tag">cmnd</span>
|
||||
|
||||
# <span class="hljs-selector-tag">Wifi</span>:
|
||||
<span class="hljs-selector-tag">AP</span> 0
|
||||
|
@ -192,11 +208,11 @@ If you do not want using auto extensions use the <code>--no-extension</code> par
|
|||
<span class="hljs-selector-tag">WifiConfig</span> 5
|
||||
</code></pre><p>Note: A few very specific module commands like MPC230xx, KNX and some Display commands are not supported. These are still available by JSON output.</p>
|
||||
<h3 id="filter-data">Filter data</h3>
|
||||
<p>The huge number of Tasmota configuration data can be overstrained and confusing, so the most of the configuration data are grouped into categories. </p>
|
||||
<p>With <em>decode-config.py</em> the following categories are available: <code>Display</code>, <code>Domoticz</code>, <code>Internal</code>, <code>KNX</code>, <code>Led</code>, <code>Logging</code>, <code>MCP230xx</code>, <code>MQTT</code>, <code>Main</code>, <code>Management</code>, <code>Pow</code>, <code>Sensor</code>, <code>Serial</code>, <code>SetOption</code>, <code>SonoffRF</code>, <code>System</code>, <code>Timers</code>, <code>Wifi</code></p>
|
||||
<p>The huge number of Tasmota configuration data can be overstrained and confusing, so the most of the configuration data are grouped into categories.</p>
|
||||
<p>With <em>decode-config.py</em> the following categories are available: <code>Display</code>, <code>Domoticz</code>, <code>Internal</code>, <code>KNX</code>, <code>Led</code>, <code>Logging</code>, <code>MCP230xx</code>, <code>MQTT</code>, <code>Main</code>, <code>Management</code>, <code>Pow</code>, <code>Sensor</code>, <code>Serial</code>, <code>SetOption</code>, <code>RF</code>, <code>System</code>, <code>Timers</code>, <code>Wifi</code></p>
|
||||
<p>These are similary to the categories on <a href="Tasmota Command Wiki">https://github.com/arendst/Tasmota/wiki/Commands</a>.</p>
|
||||
<p>To filter outputs to a subset of groups use the <code>-g</code> or <code>--group</code> arg concatenating the grooup you want, e. g.</p>
|
||||
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d sonoff-<span class="hljs-number">4281</span> -c my<span class="hljs-selector-class">.conf</span> --output-format cmnd --group Main MQTT Management Wifi
|
||||
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d tasmota-<span class="hljs-number">4281</span> -c my<span class="hljs-selector-class">.conf</span> --output-format cmnd --group Main MQTT Management Wifi
|
||||
</code></pre><h3 id="configuration-file">Configuration file</h3>
|
||||
<p>Each argument that start with <code>--</code> (eg. <code>--file</code>) can also be set in a config file (specified via -c). Config file syntax allows: key=value, flag=true, stuff=[a,b,c] (for details, see syntax at <a href="https://pypi.org/project/ConfigArgParse/">https://pypi.org/project/ConfigArgParse</a>).</p>
|
||||
<p>If an argument is specified in more than one place, then commandline values override config file values which override defaults. This is usefull if you always use the same argument or a basic set of arguments.</p>
|
||||
|
@ -206,7 +222,7 @@ If you do not want using auto extensions use the <code>--no-extension</code> par
|
|||
<span class="hljs-attr">username</span> = admin
|
||||
<span class="hljs-attr">password</span> = myPaszxwo!z
|
||||
</code></pre><p>To make a backup file from example above you can now pass the config file instead using the password on command line:</p>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">-c</span> <span class="hljs-selector-tag">my</span><span class="hljs-selector-class">.conf</span> <span class="hljs-selector-tag">--backup-file</span> <span class="hljs-selector-tag">Config_</span>@<span class="hljs-keyword">f_</span>@<span class="hljs-keyword">v</span>
|
||||
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">tasmota-4281</span> <span class="hljs-selector-tag">-c</span> <span class="hljs-selector-tag">my</span><span class="hljs-selector-class">.conf</span> <span class="hljs-selector-tag">--backup-file</span> <span class="hljs-selector-tag">Config_</span>@<span class="hljs-keyword">f_</span>@<span class="hljs-keyword">v</span>
|
||||
</code></pre><h3 id="more-program-arguments">More program arguments</h3>
|
||||
<p>For better reading each short written arg (minus sign <code>-</code>) has a corresponding long version (two minus signs <code>--</code>), eg. <code>--device</code> for <code>-d</code> or <code>--file</code> for <code>-f</code> (note: not even all <code>--</code> arg has a corresponding <code>-</code> one).</p>
|
||||
<p>A short list of possible program args is displayed using <code>-h</code> or <code>--help</code>.</p>
|
||||
|
@ -219,7 +235,7 @@ If you do not want using auto extensions use the <code>--no-extension</code> par
|
|||
[--cmnd-indent <indent>] [--cmnd-groups]
|
||||
[--cmnd-nogroups] [--cmnd-<span class="hljs-keyword">sort</span>] [--cmnd-unsort]
|
||||
[-c <filename>] [-S] [-T json|cmnd|command]
|
||||
[-g {Control,Devices,Display,Domoticz,Internal,KNX,Light,MQTT,Management,Power,Rules,Sensor,Serial,SetOption,SonoffRF,System,Timer,Wifi} [{Control,Devices,Display,Domoticz,Internal,KNX,Light,MQTT,Management,Power,Rules,Sensor,Serial,SetOption,SonoffRF,System,Timer,Wifi} ...]]
|
||||
[-<span class="hljs-keyword">g</span> {Control,Devices,<span class="hljs-keyword">Display</span>,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,<span class="hljs-keyword">Timer</span>,Wifi} [{Control,Devices,<span class="hljs-keyword">Display</span>,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,<span class="hljs-keyword">Timer</span>,Wifi} ...]]
|
||||
[--ignore-warnings] [-<span class="hljs-keyword">h</span>] [-<span class="hljs-keyword">H</span>] [-v] [-V]
|
||||
|
||||
Backup/<span class="hljs-keyword">Restore</span> Tasmota configuration data. <span class="hljs-keyword">Args</span> that start with '--'
|
||||
|
@ -299,7 +315,7 @@ Common:
|
|||
(default <span class="hljs-keyword">do</span> not output <span class="hljs-keyword">on</span> backup or <span class="hljs-keyword">restore</span> usage)
|
||||
-T, --output-<span class="hljs-keyword">format</span> json|cmnd|command
|
||||
<span class="hljs-keyword">display</span> output <span class="hljs-keyword">format</span> (default: 'json')
|
||||
-g, --group {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi}
|
||||
-<span class="hljs-keyword">g</span>, --group {Control,Devices,<span class="hljs-keyword">Display</span>,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,<span class="hljs-keyword">Timer</span>,Wifi}
|
||||
limit data processing to command groups (default <span class="hljs-keyword">no</span>
|
||||
filter)
|
||||
--ignore-warnings <span class="hljs-keyword">do</span> not <span class="hljs-keyword">exit</span> <span class="hljs-keyword">on</span> warnings. Not recommended, used <span class="hljs-keyword">by</span> your
|
||||
|
@ -331,26 +347,29 @@ json-indent <span class="hljs-number">2</span>
|
|||
</code></pre><h4 id="using-tasmota-binary-configuration-files">Using Tasmota binary configuration files</h4>
|
||||
<ol>
|
||||
<li><p>Restore a Tasmota configuration file</p>
|
||||
<p> <code>decode-config.py -c my.conf -d sonoff --restore-file Config_Sonoff_6.2.1.dmp</code></p>
|
||||
<p> <code>decode-config.py -c my.conf -d tasmota --restore-file Config_Tasmota_6.2.1.dmp</code></p>
|
||||
</li>
|
||||
<li><p>Backup device using Tasmota configuration compatible format</p>
|
||||
<p>a) use file extension to choice the file format</p>
|
||||
<p> <code>decode-config.py -c my.conf -d sonoff --backup-file Config_@f_@v.dmp</code></p>
|
||||
<p> <code>decode-config.py -c my.conf -d tasmota --backup-file Config_@f_@v.dmp</code></p>
|
||||
<p>b) use args to choice the file format</p>
|
||||
<p> <code>decode-config.py -c my.conf -d sonoff --backup-type dmp --backup-file Config_@f_@v</code></p>
|
||||
<p> <code>decode-config.py -c my.conf -d tasmota --backup-type dmp --backup-file Config_@f_@v</code></p>
|
||||
</li>
|
||||
</ol>
|
||||
<h4 id="use-batch-processing">Use batch processing</h4>
|
||||
<pre><code><span class="hljs-keyword">for</span> device <span class="hljs-keyword">in</span> sonoff1 sonoff2 sonoff3; <span class="hljs-keyword">do</span> ./decode-config.py -c my.conf -d <span class="hljs-variable">$device</span> -o Config<span class="hljs-number">_</span><span class="hljs-variable">@f_</span><span class="hljs-variable">@v</span>
|
||||
<pre><code><span class="hljs-keyword">for</span> device <span class="hljs-keyword">in</span> tasmota1 tasmota2 tasmota3; <span class="hljs-keyword">do</span> ./decode-config.py -c my.conf -d <span class="hljs-variable">$device</span> -o Config<span class="hljs-number">_</span><span class="hljs-variable">@f_</span><span class="hljs-variable">@v</span>
|
||||
</code></pre><p>or under windows</p>
|
||||
<pre><code><span class="hljs-keyword">for</span> device <span class="hljs-keyword">in</span> (sonoff1 sonoff2 sonoff3) <span class="hljs-keyword">do</span> <span class="hljs-keyword">python</span> decode-config.py -c my.conf -d %device -o Config_@f_@v
|
||||
</code></pre><p>will produce JSON configuration files for host sonoff1, sonoff2 and sonoff3 using friendly name and Tasmota firmware version for backup filenames.</p>
|
||||
<pre><code><span class="hljs-keyword">for</span> device <span class="hljs-keyword">in</span> (tasmota1 tasmota2 tasmota3) <span class="hljs-keyword">do</span> <span class="hljs-keyword">python</span> decode-config.py -c my.conf -d %device -o Config_@f_@v
|
||||
</code></pre><p>will produce JSON configuration files for host tasmota1, tasmota2 and tasmota3 using friendly name and Tasmota firmware version for backup filenames.</p>
|
||||
<h2 id="notes">Notes</h2>
|
||||
<p>Some general notes:</p>
|
||||
<ul>
|
||||
<li>Filename replacement macros <strong>@h</strong> and <strong>@H</strong>:<ul>
|
||||
<li><strong>@h</strong><br>The <strong>@h</strong> replacement macro uses the hostname configured with the Tasomta Wifi <code>Hostname <host></code> command (defaults to <code>%s-%04d</code>). It will not use the network hostname of your device because this is not available when working with files only (e.g. <code>--file <filename></code> as source).<br>To prevent having a useless % in your filename, <strong>@h</strong> will not replaced by configuration data hostname if this contains '%' characters.</li>
|
||||
<li><strong>@H</strong><br>If you want to use the network hostname within your filename, use the <strong>@H</strong> replacement macro instead - but be aware this will only replaced if you are using a network device as source (<code>-d</code>, <code>--device</code>, <code>--host</code>); it will not work when using a file as source (<code>-f</code>, <code>--file</code>)</li>
|
||||
<li><strong>@h</strong>
|
||||
The <strong>@h</strong> replacement macro uses the hostname configured with the Tasomta Wifi <code>Hostname <host></code> command (defaults to <code>%s-%04d</code>). It will not use the network hostname of your device because this is not available when working with files only (e.g. <code>--file <filename></code> as source).
|
||||
To prevent having a useless % in your filename, <strong>@h</strong> will not replaced by configuration data hostname if this contains '%' characters.</li>
|
||||
<li><strong>@H</strong>
|
||||
If you want to use the network hostname within your filename, use the <strong>@H</strong> replacement macro instead - but be aware this will only replaced if you are using a network device as source (<code>-d</code>, <code>--device</code>, <code>--host</code>); it will not work when using a file as source (<code>-f</code>, <code>--file</code>)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -211,7 +211,7 @@ Note: A few very specific module commands like MPC230xx, KNX and some Display co
|
|||
### Filter data
|
||||
The huge number of Tasmota configuration data can be overstrained and confusing, so the most of the configuration data are grouped into categories.
|
||||
|
||||
With _decode-config.py_ the following categories are available: `Display`, `Domoticz`, `Internal`, `KNX`, `Led`, `Logging`, `MCP230xx`, `MQTT`, `Main`, `Management`, `Pow`, `Sensor`, `Serial`, `SetOption`, `SonoffRF`, `System`, `Timers`, `Wifi`
|
||||
With _decode-config.py_ the following categories are available: `Display`, `Domoticz`, `Internal`, `KNX`, `Led`, `Logging`, `MCP230xx`, `MQTT`, `Main`, `Management`, `Pow`, `Sensor`, `Serial`, `SetOption`, `RF`, `System`, `Timers`, `Wifi`
|
||||
|
||||
These are similary to the categories on [https://github.com/arendst/Tasmota/wiki/Commands](Tasmota Command Wiki).
|
||||
|
||||
|
@ -254,7 +254,7 @@ For advanced help use `-H` or `--full-help`:
|
|||
[--cmnd-indent <indent>] [--cmnd-groups]
|
||||
[--cmnd-nogroups] [--cmnd-sort] [--cmnd-unsort]
|
||||
[-c <filename>] [-S] [-T json|cmnd|command]
|
||||
[-g {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi} [{Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi} ...]]
|
||||
[-g {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,Timer,Wifi} [{Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,Timer,Wifi} ...]]
|
||||
[--ignore-warnings] [-h] [-H] [-v] [-V]
|
||||
|
||||
Backup/Restore Tasmota configuration data. Args that start with '--'
|
||||
|
@ -334,7 +334,7 @@ For advanced help use `-H` or `--full-help`:
|
|||
(default do not output on backup or restore usage)
|
||||
-T, --output-format json|cmnd|command
|
||||
display output format (default: 'json')
|
||||
-g, --group {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi}
|
||||
-g, --group {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,Timer,Wifi}
|
||||
limit data processing to command groups (default no
|
||||
filter)
|
||||
--ignore-warnings do not exit on warnings. Not recommended, used by your
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
VER = '2.3.0036'
|
||||
from __future__ import print_function
|
||||
VER = '2.4.0037'
|
||||
|
||||
"""
|
||||
decode-config.py - Backup/Restore Tasmota configuration data
|
||||
|
@ -43,7 +44,7 @@ Usage: decode-config.py [-f <filename>] [-d <host>] [-P <port>]
|
|||
[--cmnd-indent <indent>] [--cmnd-groups]
|
||||
[--cmnd-nogroups] [--cmnd-sort] [--cmnd-unsort]
|
||||
[-c <filename>] [-S] [-T json|cmnd|command]
|
||||
[-g {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi} [{Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi} ...]]
|
||||
[-g {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Rf,System,Timer,Wifi} [{Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Rf,System,Timer,Wifi} ...]]
|
||||
[--ignore-warnings] [-h] [-H] [-v] [-V]
|
||||
|
||||
Backup/Restore Tasmota configuration data. Args that start with '--'
|
||||
|
@ -123,7 +124,7 @@ Usage: decode-config.py [-f <filename>] [-d <host>] [-P <port>]
|
|||
(default do not output on backup or restore usage)
|
||||
-T, --output-format json|cmnd|command
|
||||
display output format (default: 'json')
|
||||
-g, --group {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Sonoffrf,System,Timer,Wifi}
|
||||
-g, --group {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rules,Sensor,Serial,Setoption,Shutter,Rf,System,Timer,Wifi}
|
||||
limit data processing to command groups (default no
|
||||
filter)
|
||||
--ignore-warnings do not exit on warnings. Not recommended, used by your
|
||||
|
@ -184,7 +185,7 @@ import io
|
|||
import sys, platform
|
||||
def ModuleImportError(module):
|
||||
er = str(module)
|
||||
print >> sys.stderr, "{}. Try 'pip install {}' to install it".format(er,er.split(' ')[len(er.split(' '))-1])
|
||||
print('{}, try "pip install {}"'.format(er,er.split(' ')[len(er.split(' '))-1]), file=sys.stderr)
|
||||
sys.exit(ExitCode.MODULE_NOT_FOUND)
|
||||
try:
|
||||
from datetime import datetime
|
||||
|
@ -198,8 +199,11 @@ try:
|
|||
import json
|
||||
import configargparse
|
||||
import pycurl
|
||||
import urllib2
|
||||
except ImportError, e:
|
||||
if sys.version_info.major==2:
|
||||
import urllib2
|
||||
else:
|
||||
import urllib
|
||||
except ImportError as e:
|
||||
ModuleImportError(e)
|
||||
|
||||
# ======================================================================
|
||||
|
@ -276,7 +280,7 @@ Settings dictionary describes the config file fields definition:
|
|||
defines the use of data at <addrdef>
|
||||
format is defined in 'struct module format string'
|
||||
see
|
||||
https://docs.python.org/2.7/library/struct.html#format-strings
|
||||
https://docs.python.org/3.8/library/struct.html#format-strings
|
||||
<setting>: <setting>
|
||||
A dictionary describes a (sub)setting dictonary
|
||||
and can recursively define another <setting>
|
||||
|
@ -556,7 +560,7 @@ Setting_5_10_0 = {
|
|||
'pulse_counter_type4': ('<H', (0x5D0,1,3), (None, None, ('Sensor', '"CounterType4 {}".format($)')) ),
|
||||
}, 0x5D0, (None, None, ('Sensor', None)), (None, None) ),
|
||||
'pulse_counter_debounce': ('<H', 0x5D2, (None, '0 <= $ <= 3200', ('Sensor', '"CounterDebounce {}".format($)')) ),
|
||||
'rf_code': ('B', 0x5D4, ([17,9],None, ('SonoffRF', None)), '"0x{:02x}".format($)'),
|
||||
'rf_code': ('B', 0x5D4, ([17,9],None, ('Rf', None)), '"0x{:02x}".format($)'),
|
||||
}
|
||||
# ======================================================================
|
||||
Setting_5_11_0 = copy.deepcopy(Setting_5_10_0)
|
||||
|
@ -1043,8 +1047,8 @@ Setting_6_6_0_14.update ({
|
|||
'mqttlog_level': ('B', 0x1E7, (None, None, ('Management', '"MqttLog {}".format($)')) ),
|
||||
'pcf8574_config': ('B', 0xE88, ([8], None, ('Devices', None)) ),
|
||||
'shutter_accuracy': ('B', 0x1E6, (None, None, ('Shutter', None)) ),
|
||||
'shutter_opentime': ('<H', 0xE40, ([4], None, ('Shutter', '"ShutterOpenDuration{} {:.1f}".format(#,$/10)')) ),
|
||||
'shutter_closetime': ('<H', 0xE48, ([4], None, ('Shutter', '"ShutterCloseDuration{} {:.1f}".format(#,$/10)')) ),
|
||||
'shutter_opentime': ('<H', 0xE40, ([4], None, ('Shutter', '"ShutterOpenDuration{} {:.1f}".format(#,$/10.0)')) ),
|
||||
'shutter_closetime': ('<H', 0xE48, ([4], None, ('Shutter', '"ShutterCloseDuration{} {:.1f}".format(#,$/10.0)')) ),
|
||||
'shuttercoeff': ('<H', 0xE50, ([5,4],None, ('Shutter', None)) ),
|
||||
'shutter_invert': ('B', 0xE78, ([4], None, ('Shutter', '"ShutterInvert{} {}".format(#,$)')) ),
|
||||
'shutter_set50percent': ('B', 0xE7C, ([4], None, ('Shutter', '"ShutterSetHalfway{} {}".format(#,$)')) ),
|
||||
|
@ -1081,7 +1085,55 @@ Setting_6_6_0_20.update ({
|
|||
'energy_power_delta': ('<H', 0xE98, (None, '0 <= $ < 32000', ('Power', '"PowerDelta {}".format($)')) ),
|
||||
})
|
||||
# ======================================================================
|
||||
Setting_6_6_0_21 = copy.deepcopy(Setting_6_6_0_20)
|
||||
Setting_6_6_0_21['flag'][0].pop('value_units',None)
|
||||
Setting_6_6_0_21['flag3'][0].pop('tuya_dimmer_range_255',None)
|
||||
Setting_6_6_0_21['flag3'][0].update ({
|
||||
'tuya_serial_mqtt_publish': ('<L', (0x3A0,1,16), (None, None, ('SetOption', '"SetOption66 {}".format($)')) ),
|
||||
})
|
||||
# ======================================================================
|
||||
Setting_7_0_0_1 = copy.deepcopy(Setting_6_6_0_21)
|
||||
Setting_7_0_0_1.pop('register8',None)
|
||||
Setting_7_0_0_1.update ({
|
||||
'shutter_motordelay': ('B', 0xE9A, ([4], None, ('Shutter', '"ShutterMotorDelay{} {:.1f}".format(#,$/20.0)')) ),
|
||||
'flag4': ('<L', 0x1E0, (None, None, ('System', None)), '"0x{:08x}".format($)' ),
|
||||
})
|
||||
Setting_7_0_0_1['flag3'][0].update ({
|
||||
'cors_enabled': ('<L', (0x3A0,1,23), (None, None, ('SetOption', '"SetOption73 {}".format($)')) ),
|
||||
'ds18x20_internal_pullup': ('<L', (0x3A0,1,24), (None, None, ('SetOption', '"SetOption74 {}".format($)')) ),
|
||||
'grouptopic_mode': ('<L', (0x3A0,1,25), (None, None, ('SetOption', '"SetOption75 {}".format($)')) ),
|
||||
})
|
||||
# ======================================================================
|
||||
Setting_7_0_0_2 = copy.deepcopy(Setting_7_0_0_1)
|
||||
Setting_7_0_0_2.update ({
|
||||
'web_color2': ('3B', 0xEA0, ([1], None, ('Wifi', '"WebColor{} {}{:06x}".format(#+18,chr(35),int($,0))')), '"0x{:06x}".format($)' ),
|
||||
})
|
||||
# ======================================================================
|
||||
Setting_7_0_0_3 = copy.deepcopy(Setting_7_0_0_2)
|
||||
Setting_7_0_0_3.update ({
|
||||
'i2c_drivers': ('<L', 0xFEC, ([3], None, ('Management', None)),'"0x{:08x}".format($)' ),
|
||||
})
|
||||
# ======================================================================
|
||||
Setting_7_0_0_4 = copy.deepcopy(Setting_7_0_0_3)
|
||||
Setting_7_0_0_4.update ({
|
||||
'wifi_output_power': ('B', 0x1E5, (None, None, ('Wifi', '"WifiPower {:.1f}".format($/10.0)')) ),
|
||||
})
|
||||
Setting_7_0_0_4['flag3'][0].update ({
|
||||
'bootcount_update': ('<L', (0x3A0,1,26), (None, None, ('SetOption', '"SetOption76 {}".format($)')) ),
|
||||
})
|
||||
# ======================================================================
|
||||
Setting_7_0_0_5 = copy.deepcopy(Setting_7_0_0_4)
|
||||
Setting_7_0_0_5.update ({
|
||||
'temp_comp': ('b', 0xE9E, (None, None, ('Sensor', '"TempOffset {:.1f}".format($/10.0)')) ),
|
||||
})
|
||||
# ======================================================================
|
||||
Settings = [
|
||||
(0x7000005,0x1000, Setting_7_0_0_5),
|
||||
(0x7000004,0x1000, Setting_7_0_0_4),
|
||||
(0x7000003,0x1000, Setting_7_0_0_3),
|
||||
(0x7000002,0x1000, Setting_7_0_0_2),
|
||||
(0x7000001,0x1000, Setting_7_0_0_1),
|
||||
(0x6060015,0x1000, Setting_6_6_0_21),
|
||||
(0x6060014,0x1000, Setting_6_6_0_20),
|
||||
(0x6060012,0x1000, Setting_6_6_0_18),
|
||||
(0x606000F,0x1000, Setting_6_6_0_15),
|
||||
|
@ -1162,13 +1214,14 @@ def message(msg, type_=None, status=None, line=None):
|
|||
@param status:
|
||||
status number
|
||||
"""
|
||||
print >> sys.stderr, '{styp}{sdelimiter}{sstatus}{slineno}{scolon}{smgs}'.format(\
|
||||
styp=type_ if type_ is not None else '',
|
||||
sdelimiter=' ' if status is not None and status > 0 and type_ is not None else '',
|
||||
sstatus=status if status is not None and status > 0 else '',
|
||||
scolon=': ' if type_ is not None or line is not None else '',
|
||||
smgs=msg,
|
||||
slineno=' (@{:04d})'.format(line) if line is not None else '')
|
||||
print('{styp}{sdelimiter}{sstatus}{slineno}{scolon}{smgs}'.format(\
|
||||
styp=type_ if type_ is not None else '',
|
||||
sdelimiter=' ' if status is not None and status > 0 and type_ is not None else '',
|
||||
sstatus=status if status is not None and status > 0 else '',
|
||||
scolon=': ' if type_ is not None or line is not None else '',
|
||||
smgs=msg,
|
||||
slineno=' (@{:04d})'.format(line) if line is not None else '')
|
||||
, file=sys.stderr)
|
||||
|
||||
|
||||
def exit(status=0, msg="end", type_=LogType.ERROR, src=None, doexit=True, line=None):
|
||||
|
@ -1200,11 +1253,11 @@ def ShortHelp(doexit=True):
|
|||
@param doexit:
|
||||
sys.exit with OK if True
|
||||
"""
|
||||
print parser.description
|
||||
print(parser.description)
|
||||
print
|
||||
parser.print_usage()
|
||||
print
|
||||
print "For advanced help use '{prog} -H' or '{prog} --full-help'".format(prog=os.path.basename(sys.argv[0]))
|
||||
print("For advanced help use '{prog} -H' or '{prog} --full-help'".format(prog=os.path.basename(sys.argv[0])))
|
||||
if doexit:
|
||||
sys.exit(ExitCode.OK)
|
||||
|
||||
|
@ -1554,8 +1607,8 @@ def LoadTasmotaConfig(filename):
|
|||
try:
|
||||
with open(filename, "rb") as tasmotafile:
|
||||
encode_cfg = tasmotafile.read()
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
|
||||
return encode_cfg
|
||||
|
||||
|
@ -1597,8 +1650,8 @@ def TasmotaGet(cmnd, host, port, username=DEFAULTS['source']['username'], passwo
|
|||
c.perform()
|
||||
responsecode = c.getinfo(c.RESPONSE_CODE)
|
||||
response = header.response()
|
||||
except Exception, e:
|
||||
exit(e[0], e[1],line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], e.args[1], line=inspect.getlineno(inspect.currentframe()))
|
||||
finally:
|
||||
c.close()
|
||||
|
||||
|
@ -1727,8 +1780,8 @@ def PushTasmotaConfig(encode_cfg, host, port, username=DEFAULTS['source']['usern
|
|||
try:
|
||||
c.perform()
|
||||
responsecode = c.getinfo(c.RESPONSE_CODE)
|
||||
except Exception, e:
|
||||
return e[0], e[1]
|
||||
except Exception as e:
|
||||
return e.args[0], e.args[1]
|
||||
|
||||
c.close()
|
||||
|
||||
|
@ -1839,7 +1892,7 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
|
||||
# calling with nothing is wrong
|
||||
if fielddef is None:
|
||||
print >> sys.stderr, '<fielddef> is None'
|
||||
print('<fielddef> is None', file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
# get top level items
|
||||
|
@ -1850,7 +1903,7 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
# converter present
|
||||
format_, addrdef, datadef, converter = fielddef
|
||||
else:
|
||||
print >> sys.stderr, 'wrong <fielddef> {} length ({}) in setting'.format(fielddef, len(fielddef))
|
||||
print('wrong <fielddef> {} length ({}) in setting'.format(fielddef, len(fielddef)), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
# ignore calls with 'root' setting
|
||||
|
@ -1858,7 +1911,7 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
return eval(fields)
|
||||
|
||||
if not isinstance(format_, (unicode,str,dict)):
|
||||
print >> sys.stderr, 'wrong <format> {} type {} in <fielddef> {}'.format(format_, type(format_), fielddef)
|
||||
print('wrong <format> {} type {} in <fielddef> {}'.format(format_, type(format_), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
# extract addrdef items
|
||||
|
@ -1868,16 +1921,16 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
# baseaddr bit definition
|
||||
baseaddr, bits, bitshift = baseaddr
|
||||
if not isinstance(bits, int):
|
||||
print >> sys.stderr, '<bits> must be defined as integer in <fielddef> {}'.format(bits, fielddef)
|
||||
print('<bits> must be defined as integer in <fielddef> {}'.format(bits, fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
if not isinstance(bitshift, int):
|
||||
print >> sys.stderr, '<bitshift> must be defined as integer in <fielddef> {}'.format(bitshift, fielddef)
|
||||
print('<bitshift> must be defined as integer in <fielddef> {}'.format(bitshift, fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
else:
|
||||
print >> sys.stderr, 'wrong <addrdef> {} length ({}) in <fielddef> {}'.format(addrdef, len(addrdef), fielddef)
|
||||
print('wrong <addrdef> {} length ({}) in <fielddef> {}'.format(addrdef, len(addrdef), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
if not isinstance(baseaddr, int):
|
||||
print >> sys.stderr, '<baseaddr> must be defined as integer in <fielddef> {}'.format(baseaddr, fielddef)
|
||||
print('<baseaddr> must be defined as integer in <fielddef> {}'.format(baseaddr, fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
# extract datadef items
|
||||
|
@ -1893,27 +1946,27 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
if isinstance(cmd, (tuple)) and len(cmd) == 2:
|
||||
group, tasmotacmnd = cmd
|
||||
if group is not None and not isinstance(group, (str, unicode)):
|
||||
print >> sys.stderr, 'wrong <group> {} in <fielddef> {}'.format(group, fielddef)
|
||||
print('wrong <group> {} in <fielddef> {}'.format(group, fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
if tasmotacmnd is isinstance(tasmotacmnd, tuple):
|
||||
tasmotacmnds = tasmotacmnd
|
||||
for tasmotacmnd in tasmotacmnds:
|
||||
if tasmotacmnd is not None and not callable(tasmotacmnd) and not isinstance(tasmotacmnd, (str, unicode)):
|
||||
print >> sys.stderr, 'wrong <tasmotacmnd> {} in <fielddef> {}'.format(tasmotacmnd, fielddef)
|
||||
print('wrong <tasmotacmnd> {} in <fielddef> {}'.format(tasmotacmnd, fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
else:
|
||||
if tasmotacmnd is not None and not callable(tasmotacmnd) and not isinstance(tasmotacmnd, (str, unicode)):
|
||||
print >> sys.stderr, 'wrong <tasmotacmnd> {} in <fielddef> {}'.format(tasmotacmnd, fielddef)
|
||||
print('wrong <tasmotacmnd> {} in <fielddef> {}'.format(tasmotacmnd, fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
else:
|
||||
print >> sys.stderr, 'wrong <cmd> {} length ({}) in <fielddef> {}'.format(cmd, len(cmd), fielddef)
|
||||
print('wrong <cmd> {} length ({}) in <fielddef> {}'.format(cmd, len(cmd), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
else:
|
||||
print >> sys.stderr, 'wrong <datadef> {} length ({}) in <fielddef> {}'.format(datadef, len(datadef), fielddef)
|
||||
print('wrong <datadef> {} length ({}) in <fielddef> {}'.format(datadef, len(datadef), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
if validate is not None and (not isinstance(validate, (unicode,str)) and not callable(validate)):
|
||||
print >> sys.stderr, 'wrong <validate> {} type {} in <fielddef> {}'.format(validate, type(validate), fielddef)
|
||||
print('wrong <validate> {} type {} in <fielddef> {}'.format(validate, type(validate), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
# convert single int into one-dimensional list
|
||||
|
@ -1921,7 +1974,7 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
arraydef = [arraydef]
|
||||
|
||||
if arraydef is not None and not isinstance(arraydef, (list)):
|
||||
print >> sys.stderr, 'wrong <arraydef> {} type {} in <fielddef> {}'.format(arraydef, type(arraydef), fielddef)
|
||||
print('wrong <arraydef> {} type {} in <fielddef> {}'.format(arraydef, type(arraydef), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
# get read/write converter items
|
||||
|
@ -1931,13 +1984,13 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
|
|||
# converter has read/write converter
|
||||
readconverter, writeconverter = converter
|
||||
if readconverter is not None and not isinstance(readconverter, (str,unicode)) and not callable(readconverter):
|
||||
print >> sys.stderr, 'wrong <readconverter> {} type {} in <fielddef> {}'.format(readconverter, type(readconverter), fielddef)
|
||||
print('wrong <readconverter> {} type {} in <fielddef> {}'.format(readconverter, type(readconverter), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
if writeconverter is not None and (not isinstance(writeconverter, (bool,str,unicode)) and not callable(writeconverter)):
|
||||
print >> sys.stderr, 'wrong <writeconverter> {} type {} in <fielddef> {}'.format(writeconverter, type(writeconverter), fielddef)
|
||||
print('wrong <writeconverter> {} type {} in <fielddef> {}'.format(writeconverter, type(writeconverter), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
else:
|
||||
print >> sys.stderr, 'wrong <converter> {} length ({}) in <fielddef> {}'.format(converter, len(converter), fielddef)
|
||||
print('wrong <converter> {} length ({}) in <fielddef> {}'.format(converter, len(converter), fielddef), file=sys.stderr)
|
||||
raise SyntaxError('<fielddef> error')
|
||||
|
||||
|
||||
|
@ -1975,8 +2028,8 @@ def ReadWriteConverter(value, fielddef, read=True, raw=False):
|
|||
return eval(conv.replace('$','value'))
|
||||
elif callable(conv): # use as format function
|
||||
return conv(value)
|
||||
except Exception, e:
|
||||
exit(e[0], e[1], type_=LogType.WARNING, line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], e.args[1], type_=LogType.WARNING, line=inspect.getlineno(inspect.currentframe()))
|
||||
|
||||
return value
|
||||
|
||||
|
@ -2294,7 +2347,7 @@ def SetFieldValue(fielddef, dobj, addr, value):
|
|||
formatcnt = GetFormatCount(format_)
|
||||
singletype, bitsize = GetFormatType(format_)
|
||||
if args.debug >= 2:
|
||||
print >> sys.stderr, "SetFieldValue(): fielddef {}, addr 0x{:04x} value {} formatcnt {} singletype {} bitsize {} ".format(fielddef,addr,value,formatcnt,singletype,bitsize)
|
||||
print("SetFieldValue(): fielddef {}, addr 0x{:04x} value {} formatcnt {} singletype {} bitsize {} ".format(fielddef,addr,value,formatcnt,singletype,bitsize), file=sys.stderr)
|
||||
if not format_[-1:].lower() in ['s','p']:
|
||||
addr += (bitsize / 8) * formatcnt
|
||||
for _ in range(0, formatcnt):
|
||||
|
@ -2305,7 +2358,7 @@ def SetFieldValue(fielddef, dobj, addr, value):
|
|||
if isinstance(value,int) and value < 0 and val > maxsigned:
|
||||
val = ((maxunsigned+1)-val) * (-1)
|
||||
if args.debug >= 3:
|
||||
print >> sys.stderr, "SetFieldValue(): Single type - fielddef {}, addr 0x{:04x} value {} singletype {} bitsize {}".format(fielddef,addr,val,singletype,bitsize)
|
||||
print("SetFieldValue(): Single type - fielddef {}, addr 0x{:04x} value {} singletype {} bitsize {}".format(fielddef,addr,val,singletype,bitsize), file=sys.stderr)
|
||||
try:
|
||||
struct.pack_into(singletype, dobj, addr, val)
|
||||
except struct.error as e:
|
||||
|
@ -2317,7 +2370,7 @@ def SetFieldValue(fielddef, dobj, addr, value):
|
|||
value >>= bitsize
|
||||
else:
|
||||
if args.debug >= 3:
|
||||
print >> sys.stderr, "SetFieldValue(): String type - fielddef {}, addr 0x{:04x} value {} format_ {}".format(fielddef,addr,value,format_)
|
||||
print("SetFieldValue(): String type - fielddef {}, addr 0x{:04x} value {} format_ {}".format(fielddef,addr,value,format_), file=sys.stderr)
|
||||
try:
|
||||
struct.pack_into(format_, dobj, addr, value)
|
||||
except struct.error as e:
|
||||
|
@ -2427,7 +2480,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""):
|
|||
# do not write readonly values
|
||||
if writeconverter is False:
|
||||
if args.debug >= 2:
|
||||
print >> sys.stderr, "SetField(): Readonly '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset))
|
||||
print("SetField(): Readonly '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset)), file=sys.stderr)
|
||||
return dobj
|
||||
|
||||
# <arraydef> contains a list
|
||||
|
@ -2465,16 +2518,16 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""):
|
|||
if format_[-1:] in ['c']:
|
||||
try:
|
||||
value = ReadWriteConverter(restore.encode(STR_ENCODING)[0], fielddef, read=False)
|
||||
except Exception, e:
|
||||
exit(e[0], e[1], type_=LogType.WARNING, line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], e.args[1], type_=LogType.WARNING, line=inspect.getlineno(inspect.currentframe()))
|
||||
valid = False
|
||||
|
||||
# bool
|
||||
elif format_[-1:] in ['?']:
|
||||
try:
|
||||
value = ReadWriteConverter(bool(restore), fielddef, read=False)
|
||||
except Exception, e:
|
||||
exit(e[0], e[1], type_=LogType.WARNING, line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], e.args[1], type_=LogType.WARNING, line=inspect.getlineno(inspect.currentframe()))
|
||||
valid = False
|
||||
|
||||
# integer
|
||||
|
@ -2560,7 +2613,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""):
|
|||
if args.debug >= 2:
|
||||
sbits = " {} bits shift {}".format(bits, bitshift) if bits else ""
|
||||
strvalue = "{} [{}]".format(_value, hex(value)) if isinstance(_value, int) else _value
|
||||
print >> sys.stderr, "SetField(): Set '{}' using '{}'/{}{} @{} to {}".format(fieldname, format_, arraydef, sbits, hex(baseaddr+addroffset), strvalue)
|
||||
print("SetField(): Set '{}' using '{}'/{}{} @{} to {}".format(fieldname, format_, arraydef, sbits, hex(baseaddr+addroffset), strvalue), file=sys.stderr)
|
||||
if fieldname != 'cfg_crc' and fieldname != '_':
|
||||
prevvalue = GetFieldValue(fielddef, dobj, baseaddr+addroffset)
|
||||
dobj = SetFieldValue(fielddef, dobj, baseaddr+addroffset, value)
|
||||
|
@ -2569,7 +2622,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""):
|
|||
message("Value for '{}' changed from {} to {}".format(fieldname, prevvalue, curvalue), type_=LogType.INFO)
|
||||
else:
|
||||
if args.debug >= 2:
|
||||
print >> sys.stderr, "SetField(): Special field '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset))
|
||||
print("SetField(): Special field '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset)), file=sys.stderr)
|
||||
else:
|
||||
sformat = "file '{sfile}' - {{'{sname}': {svalue}}} ({serror})"+errformat
|
||||
exit(ExitCode.RESTORE_DATA_ERROR, sformat.format(sfile=filename, sname=fieldname, serror=err, svalue=_value, smin=min_, smax=max_), type_=LogType.WARNING, doexit=not args.ignorewarning)
|
||||
|
@ -2871,8 +2924,8 @@ def Backup(backupfile, backupfileformat, encode_cfg, decode_cfg, configmapping):
|
|||
try:
|
||||
with open(backup_filename, "wb") as backupfp:
|
||||
backupfp.write(encode_cfg)
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(backup_filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(backup_filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
|
||||
# binary format
|
||||
elif backupfileformat.lower() == FileType.BIN.lower():
|
||||
|
@ -2884,8 +2937,8 @@ def Backup(backupfile, backupfileformat, encode_cfg, decode_cfg, configmapping):
|
|||
with open(backup_filename, "wb") as backupfp:
|
||||
backupfp.write(struct.pack('<L',BINARYFILE_MAGIC))
|
||||
backupfp.write(decode_cfg)
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(backup_filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(backup_filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
|
||||
# JSON format
|
||||
elif backupfileformat.lower() == FileType.JSON.lower():
|
||||
|
@ -2896,8 +2949,8 @@ def Backup(backupfile, backupfileformat, encode_cfg, decode_cfg, configmapping):
|
|||
try:
|
||||
with open(backup_filename, "w") as backupfp:
|
||||
json.dump(configmapping, backupfp, sort_keys=args.jsonsort, indent=None if args.jsonindent < 0 else args.jsonindent, separators=(',', ':') if args.jsoncompact else (', ', ': ') )
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(backup_filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(backup_filename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
|
||||
if args.verbose:
|
||||
srctype = 'device'
|
||||
|
@ -2940,8 +2993,8 @@ def Restore(restorefile, backupfileformat, encode_cfg, decode_cfg, configmapping
|
|||
try:
|
||||
with open(restorefilename, "rb") as restorefp:
|
||||
new_encode_cfg = restorefp.read()
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(restorefilename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(restorefilename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
|
||||
elif filetype == FileType.BIN:
|
||||
if args.verbose:
|
||||
|
@ -2949,8 +3002,8 @@ def Restore(restorefile, backupfileformat, encode_cfg, decode_cfg, configmapping
|
|||
try:
|
||||
with open(restorefilename, "rb") as restorefp:
|
||||
restorebin = restorefp.read()
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(restorefilename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(restorefilename, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
header = struct.unpack_from('<L', restorebin, 0)[0]
|
||||
if header == BINARYFILE_MAGIC:
|
||||
decode_cfg = restorebin[4:] # remove header from encrypted config file
|
||||
|
@ -3004,8 +3057,8 @@ def Restore(restorefile, backupfileformat, encode_cfg, decode_cfg, configmapping
|
|||
try:
|
||||
with open(args.tasmotafile, "wb") as outputfile:
|
||||
outputfile.write(new_encode_cfg)
|
||||
except Exception, e:
|
||||
exit(e[0], "'{}' {}".format(args.tasmotafile, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
except Exception as e:
|
||||
exit(e.args[0], "'{}' {}".format(args.tasmotafile, e[1]),line=inspect.getlineno(inspect.currentframe()))
|
||||
if args.verbose:
|
||||
message("Restore successful to file '{}' using restore file '{}'".format(args.tasmotafile, restorefilename), type_=LogType.INFO)
|
||||
|
||||
|
@ -3026,10 +3079,10 @@ def OutputTasmotaCmnds(tasmotacmnds):
|
|||
def OutputTasmotaSubCmnds(cmnds):
|
||||
if args.cmndsort:
|
||||
for cmnd in sorted(cmnds, key = lambda cmnd:[int(c) if c.isdigit() else c for c in re.split('(\d+)', cmnd)]):
|
||||
print "{}{}".format(" "*args.cmndindent, cmnd)
|
||||
print("{}{}".format(" "*args.cmndindent, cmnd))
|
||||
else:
|
||||
for cmnd in cmnds:
|
||||
print "{}{}".format(" "*args.cmndindent, cmnd)
|
||||
print("{}{}".format(" "*args.cmndindent, cmnd))
|
||||
|
||||
groups = GetGroupList(Settings[0][2])
|
||||
|
||||
|
@ -3038,7 +3091,7 @@ def OutputTasmotaCmnds(tasmotacmnds):
|
|||
if group.title() in (groupname.title() for groupname in tasmotacmnds):
|
||||
cmnds = tasmotacmnds[group]
|
||||
print
|
||||
print "# {}:".format(group)
|
||||
print("# {}:".format(group))
|
||||
OutputTasmotaSubCmnds(cmnds)
|
||||
|
||||
else:
|
||||
|
@ -3245,10 +3298,10 @@ def ParseArgs():
|
|||
args = parser.parse_args()
|
||||
|
||||
if args.debug >= 1:
|
||||
print >> sys.stderr, parser.format_values()
|
||||
print >> sys.stderr, "Settings:"
|
||||
print(parser.format_values(), file=sys.stderr)
|
||||
print("Settings:", file=sys.stderr)
|
||||
for k in args.__dict__:
|
||||
print >> sys.stderr, " "+str(k), "= ",eval('args.{}'.format(k))
|
||||
print(" "+str(k), "= ",eval('args.{}'.format(k)), file=sys.stderr)
|
||||
return args
|
||||
|
||||
|
||||
|
@ -3280,7 +3333,7 @@ if __name__ == "__main__":
|
|||
# no config source given
|
||||
ShortHelp(False)
|
||||
print
|
||||
print parser.epilog
|
||||
print(parser.epilog)
|
||||
sys.exit(ExitCode.OK)
|
||||
|
||||
if len(encode_cfg) == 0:
|
||||
|
@ -3309,7 +3362,7 @@ if __name__ == "__main__":
|
|||
# json screen output
|
||||
if (args.backupfile is None and args.restorefile is None) or args.output:
|
||||
if args.outputformat == 'json':
|
||||
print json.dumps(configmapping, sort_keys=args.jsonsort, indent=None if args.jsonindent<0 else args.jsonindent, separators=(',', ':') if args.jsoncompact else (', ', ': ') )
|
||||
print(json.dumps(configmapping, sort_keys=args.jsonsort, indent=None if args.jsonindent<0 else args.jsonindent, separators=(',', ':') if args.jsoncompact else (', ', ': ') ))
|
||||
|
||||
if args.outputformat == 'cmnd' or args.outputformat == 'command':
|
||||
tasmotacmnds = Mapping2Cmnd(decode_cfg, configmapping)
|
||||
|
|
Loading…
Reference in New Issue