Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
curzon01 committed Aug 14, 2024
2 parents 5b39682 + e9b8207 commit c2ef26e
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 29 deletions.
40 changes: 22 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Convert, backup and restore configuration data of devices flashed with [Tasmota
<img src="https://github.com/tasmota/decode-config/blob/master/media/pic/decode-config.png" alt="Overview" title="decode-config Overview" width="600">

<!-- markdownlint-disable MD033 -->
[![master](https://img.shields.io/badge/master-v14.1.0.0-blue.svg)](https://github.com/tasmota/decode-config/tree/master)
[![master](https://img.shields.io/badge/master-v14.2.0.0-blue.svg)](https://github.com/tasmota/decode-config/tree/master)
[![GitHub download](https://img.shields.io/github/downloads/tasmota/decode-config/total.svg)](https://github.com/tasmota/decode-config/releases/latest)
[![PyPI version](https://badge.fury.io/py/decode-config.svg)](https://badge.fury.io/py/decode-config)
![PyPI downloads](https://img.shields.io/pypi/dm/decode-config?label=pypi%20downloads)
Expand All @@ -23,8 +23,8 @@ In comparison with the [Tasmota](https://github.com/arendst/Tasmota) build-in "*
* uses a human readable and editable [JSON](http://www.json.org/)-format for backup/restore
* can restore previously backed up and modified JSON-format files
* is able to process any subsets of configuration data
* can convert data from older Tasmota versions (from version v5.10.0) to a newer one and vice versa
* is able to create Tasmota compatible command list for the most available commands
* can convert data from older Tasmota versions (starting with early v5.10.0) to a newer and current one and vice versa
* is able to create Tasmota command list for the most available configuration data related commands

Comparing backup files created by **decode-config** and [.dmp](#dmp-format) files created by Tasmota "*Backup Configuration*" / "*Restore Configuration*":

Expand All @@ -43,7 +43,7 @@ Comparing backup files created by **decode-config** and [.dmp](#dmp-format) file
Using the latest development version of decode-config is only necessary if you also use the latest development version of Tasmota.

<!-- markdownlint-disable MD033 -->
[![development version](https://img.shields.io/badge/development-v14.1.0.0-blue.svg)](https://github.com/tasmota/decode-config/tree/development)
[![development version](https://img.shields.io/badge/development-v14.2.0.0-blue.svg)](https://github.com/tasmota/decode-config/tree/development)

## Table of contents
<details>
Expand Down Expand Up @@ -116,7 +116,7 @@ decode-config.py

#### Prerequisite

Since **decode-config.py** is a Python program, it requires an installed [Python](https://en.wikipedia.org/wiki/Python_%28programming_language%29) environment.
Since **decode-config.py** is a [Python](https://en.wikipedia.org/wiki/Python_%28programming_language%29) program, it requires an installed [Python](https://www.python.org) environment.

##### Linux

Expand All @@ -128,11 +128,11 @@ sudo apt-get install python3 python3-pip

##### Windows

Install [Python 3.x](https://www.python.org/downloads/windows/) as described
Install [Python 3.x for Windows](https://www.python.org/downloads/windows/) as described

##### MacOS

Install [Python 3.x](https://www.python.org/downloads/mac-osx/) as described
Install [Python 3.x for macOS](https://www.python.org/downloads/mac-osx/) as described

## Usage

Expand Down Expand Up @@ -338,7 +338,7 @@ Example:
decode-config -c my.conf -s tasmota-4281 --backup-file Config_@d_@v
```

This will create a file like `Config_Tasmota_14.1.json` (the part `Tasmota` and `14.1` will choosen related to your device configuration).
This will create a file like `Config_Tasmota_14.2.json` (the part `Tasmota` and `14.2` will choosen related to your device configuration).

#### Save multiple backup at once

Expand All @@ -350,18 +350,18 @@ decode-config -c my.conf -s tasmota-4281 -o Config_@d_@v -o [email protected] -o Ba

creates three backup files:

* `Config_Tasmota_14.1.json` using JSON format
* `Config_Tasmota_14.2.json` using JSON format
* `Backup_tasmota-4281.json` using JSON format
* `Backup_tasmota-4281.dmp` using Tasmota configuration file format

### Restore backup

Reading back a previously saved backup file, use the `--restore-file <filename>` parameter.

To restore the previously save backup file `Config_Tasmota_14.1.json` to device `tasmota-4281` use:
To restore the previously save backup file `Config_Tasmota_14.2.json` to device `tasmota-4281` use:

```bash
decode-config -c my.conf -s tasmota-4281 --restore-file Config_Tasmota_14.1
decode-config -c my.conf -s tasmota-4281 --restore-file Config_Tasmota_14.2
```

Restore operation also allows placeholders **@v**, **@d**, **@f**, **@h** or **@H** like in backup filenames so we can use the same naming as for the backup process:
Expand Down Expand Up @@ -393,6 +393,9 @@ Set this location for a device:
decode-config -c my.conf -s tasmota-4281 -i location
```

> **Note**
When using JSON subsets on ESP32 chip types, always keep the key `config_version` in the JSON data, otherwise an error will occur stating that the file is for ESP82xx.

> **Hint**
Keep the JSON-format valid e.g. when cutting unnecessary content from a given JSON backup file, consider to remove the last comma on same indent level:
Invalid JSON (useless comma in line 3: `...2.294442,`):<pre>{
Expand Down Expand Up @@ -594,18 +597,17 @@ becomes to

The huge number of Tasmota configuration data can be overstrained and confusing, so the most of the configuration data are grouped into categories.

The following groups are available: `Control`, `Display`, `Domoticz`, `Internal`, `Knx`, `Light`, `Management`, `Mqtt`, `Power`, `Rf`, `Rules`, `Sensor`, `Serial`, `Setoption`, `Shutter`, `System`, `Timer`, `Wifi`, `Zigbee`
Filtering by groups affects the entire output, regardless of whether this is the screen or a json backup file. The output of a dmp or bin file cannot be filtered. These binary file types must always contain the entire configuration.

The following groups are available: `Control`, `Display`, `Domoticz`, `Hdmi`, `Internal`, `Knx`, `Light`, `Management`, `Mqtt`, `Power`, `Rf`, `Rules`, `Sensor`, `Serial`, `Setoption`, `Settings`, `Shutter`, `System`, `Telegram`, `Timer`, `Usf`, `Wifi`, `Zigbee`

These are similary to the categories on [Tasmota Command Documentation](https://tasmota.github.io/docs/Commands/).

To filter outputs to a subset of groups, use the `-g` or `--group` parameter, concatenating the groups you want, e. g.

```bash
decode-config -s tasmota-4281 -c my.conf --output-format cmnd --group Main MQTT Management Wifi
decode-config -s tasmota-4281 -c my.conf --output-format cmnd --group Control Management MQTT Wifi
```

Filtering by groups affects the entire output, regardless of whether screen output or backup file.

## Usage examples

### Using Tasmota binary configuration files
Expand Down Expand Up @@ -924,6 +926,7 @@ These Tasmota commands are unsupported and not implemented in **decode-config**
| | LedPwmOff | | |
| | LedState | | |
| | Power<x\> | | |
| | PowerLock<x\> | | |
| | PowerOnState | | |
| | PulseTime<x\> | | |
| | SwitchDebounce | | |
Expand Down Expand Up @@ -1019,8 +1022,9 @@ These Tasmota commands are unsupported and not implemented in **decode-config**
| | RgxState | | |
| | RgxSubnet | | |
| | Ssid<x\> | | |
| | WebColor<x\> | | |
| | WebPassword | | |
| | WebCanvas | | |
| | WebColor<x\> | | |
| | WebRefresh | | |
| | WebSensor<x\> | | |
| | WebServer | | |
Expand Down Expand Up @@ -1167,7 +1171,7 @@ These Tasmota commands are unsupported and not implemented in **decode-config**
| | SerialConfig | | |
| | SerialDelimiter | | |
| | SSerialConfig | | |
| | SSerialSend9 | | |
| | SSerialMode | | |
| | TCPBaudrate | | |
| | TCPConfig | | |
| **Domoticz** | DomoticzIdx<x\> | | |
Expand Down
51 changes: 40 additions & 11 deletions decode-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
METADATA = {
'VERSION': '14.1.0.0',
'VERSION': '14.2.0.0',
'DESCRIPTION': 'Backup/restore and decode configuration tool for Tasmota',
'CLASSIFIER': 'Development Status :: 5 - Production/Stable',
'URL': 'https://github.com/tasmota/decode-config',
Expand Down Expand Up @@ -2366,7 +2366,7 @@ def match(self, setting_hardware, config_version):
'B', 0x450, (None, '0 <= $ <= 31', ('Wifi', '"EthAddress {}".format($)')) ),
'eth_address_esp32s3': (HARDWARE.ESP32S3,
'B', 0x45E, (None, '0 <= $ <= 31', ('Wifi', '"EthAddress {}".format($)')) ),
'module': (HARDWARE.ESP32 ^ HARDWARE.ESP32S3,
'module_esp32': (HARDWARE.ESP32 ^ HARDWARE.ESP32S3,
'B', 0x474, (None, None, ('Management', '"Module {}".format($+1 & 0xff)')) ),
'module_esp32s3': (HARDWARE.ESP32S3,
'B', 0x45F, (None, None, ('Management', '"Module {}".format($+1 & 0xff)')) ),
Expand Down Expand Up @@ -2834,7 +2834,7 @@ def match(self, setting_hardware, config_version):
# ======================================================================
SETTING_13_4_0_4 = copy.copy(SETTING_13_3_0_5)
SETTING_13_4_0_4.update ({
'power_lock': (HARDWARE.ESP, '<L', 0xF9C, (None, None, ('Power', '"PowerLock0 0" if 0==int($) else "PowerLock0 1" if 0xffffffff==int($) else list("PowerLock{} {}".format(i+1, (int($)>>i & 1) ) for i in range(0, 32))')) ),
'power_lock': (HARDWARE.ESP, '<L', 0xF9C, (None, None, ('Control', '"PowerLock0 0" if 0==int($) else "PowerLock0 1" if 0xffffffff==int($) else list("PowerLock{} {}".format(i+1, (int($)>>i & 1) ) for i in range(0, 32))')) ),
})
# ======================================================================
SETTING_14_0_0_2 = copy.copy(SETTING_13_4_0_4)
Expand All @@ -2847,10 +2847,28 @@ def match(self, setting_hardware, config_version):
'tcp_baudrate': (HARDWARE.ESP, '<H', 0x540, (None, None, ('Serial', '"TCPBaudrate {}".format($)')), ('$ * 1200','$ // 1200') ),
})
# ======================================================================
SETTING_14_1_0_0 = copy.copy(SETTING_14_0_0_4)
SETTING_14_1_0_2 = copy.copy(SETTING_14_0_0_4)
SETTING_14_1_0_2['sbflag1'][1].pop('serbridge_console',None)
SETTING_14_1_0_2.pop('tcp_baudrate',None)
SETTING_14_1_0_2.update ({
'sserial_mode': (HARDWARE.ESP, 'B', 0xF41, (None, '0 <= $ <= 3', ('Serial', '"SSerialMode {}".format($)')) ),
})
# ======================================================================
SETTING_14_1_0_3 = copy.copy(SETTING_14_1_0_2)
SETTING_14_1_0_3.update ({
'energy_max_power_safe_limit': (HARDWARE.ESP, '<H', 0x38C, (None, None, (INTERNAL, None)), ),
'energy_max_power_safe_limit_hold':
(HARDWARE.ESP, '<H', 0x38E, (None, None, (INTERNAL, None)), ),
'energy_max_power_safe_limit_window':
(HARDWARE.ESP, '<H', 0x390, (None, None, (INTERNAL, None)), ),
})
# ======================================================================
SETTING_14_2_0_0 = copy.copy(SETTING_14_1_0_3)
# ======================================================================
SETTINGS = [
(0x0E010000,0x1000, SETTING_14_1_0_0),
(0x0E020000,0x1000, SETTING_14_2_0_0),
(0x0E010003,0x1000, SETTING_14_1_0_3),
(0x0E010002,0x1000, SETTING_14_1_0_2),
(0x0E000004,0x1000, SETTING_14_0_0_4),
(0x0E000002,0x1000, SETTING_14_0_0_2),
(0x0D040004,0x1000, SETTING_13_4_0_4),
Expand Down Expand Up @@ -4262,6 +4280,8 @@ def on_message(client, userdata, msg):
base64_data = ""
rcv_id = 0

if ARGS.debug:
print("{}: on_message - payload {}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), msg.payload.decode(STR_CODING)))
try:
root = json.loads(msg.payload.decode(STR_CODING))
if root:
Expand All @@ -4286,8 +4306,6 @@ def on_message(client, userdata, msg):
err_str ="Receive code "+rcv_code
err_flag = True
return
if "Done" in rcv_code:
time.sleep(0.1)
if "Command" in root:
rcv_code = root["Command"]
if rcv_code == "Error":
Expand All @@ -4309,11 +4327,15 @@ def on_message(client, userdata, msg):
except:
pass

if dobj is None and rcv_id > 0 and file_size > 0 and file_type > 0 and file_name:
if ARGS.debug:
print("{}: on_message - use_base64={}, file_id={}, rcv_id={}, file_type={}, file_size={}, file_md5={}, in_hash_md5={}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), use_base64, file_id, rcv_id, file_type, file_size, file_md5, in_hash_md5.hexdigest()))

if dobj is None and file_id == 0 and rcv_id > 0 and file_size > 0 and file_type > 0 and file_name:
file_id = rcv_id
dobj = bytearray()
else:
if use_base64 and file_id > 0 and file_id != rcv_id:
if use_base64 and file_id > 0 and file_id != rcv_id and "Id" in rcv_code:
err_str = "FileID mismatch ({}!={})".format(file_id, rcv_id)
err_flag = True
return

Expand All @@ -4338,6 +4360,7 @@ def on_message(client, userdata, msg):

def wait_for_ack():
nonlocal err_flag
nonlocal err_str

timeout = MQTT_TIMEOUT/10
while ack_flag and not err_flag and timeout > 0:
Expand Down Expand Up @@ -4404,19 +4427,27 @@ def wait_for_connect():
in_hash_md5 = hashlib.md5()

data = {"Password":tasmota_mqtt_password, "Type":MQTT_FILETYPE}
if ARGS.debug:
data_dbg = {"Password":HIDDEN_PASSWORD, "Type":MQTT_FILETYPE}
if not use_base64:
data["Binary"] = 1
client.publish(topic_publish, json.dumps(data))
if ARGS.debug:
print("{}: client.publish({}, {})".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), topic_publish, json.dumps(data_dbg)))

ack_flag = True
run_flag = True
while run_flag:
if wait_for_ack(): # We use Ack here
client.publish(topic_publish, "0") # Abort any failed download
if ARGS.debug:
print('{}: client.publish({}, "0")'.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), topic_publish))
run_flag = False
else:
if file_md5 == "": # Request chunk
client.publish(topic_publish, "?")
if ARGS.debug:
print('{}: client.publish({}, "?")'.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"), topic_publish))
ack_flag = True
else:
run_flag = False
Expand Down Expand Up @@ -4502,8 +4533,6 @@ def on_message(client, userdata, msg):
err_str ="Receive code "+rcv_code
err_flag = True
return
if "Done" in rcv_code:
time.sleep(0.1)
if "Command" in root:
rcv_code = root["Command"]
if rcv_code == "Error":
Expand Down

0 comments on commit c2ef26e

Please sign in to comment.