Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
curzon01 committed Dec 12, 2023
2 parents b76c608 + 3a408bc commit 096465c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
# Install pip and pyinstaller
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies
Expand Down
12 changes: 6 additions & 6 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-v13.2.0.0-blue.svg)](https://github.com/tasmota/decode-config/tree/master)
[![master](https://img.shields.io/badge/master-v13.3.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 Down Expand Up @@ -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-v13.2.0.1-blue.svg)](https://github.com/tasmota/decode-config/tree/development)
[![development version](https://img.shields.io/badge/development-v13.3.0.0-blue.svg)](https://github.com/tasmota/decode-config/tree/development)

## Table of contents
<details>
Expand Down Expand Up @@ -337,7 +337,7 @@ Example:
decode-config -c my.conf -s tasmota-4281 --backup-file Config_@d_@v
```

This will create a file like `Config_Tasmota_13.2.json` (the part `Tasmota` and `13.2` will choosen related to your device configuration).
This will create a file like `Config_Tasmota_13.3.json` (the part `Tasmota` and `13.3` will choosen related to your device configuration).

#### Save multiple backup at once

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

creates three backup files:

* `Config_Tasmota_13.2.json` using JSON format
* `Config_Tasmota_13.3.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_13.2.json` to device `tasmota-4281` use:
To restore the previously save backup file `Config_Tasmota_13.3.json` to device `tasmota-4281` use:

```bash
decode-config -c my.conf -s tasmota-4281 --restore-file Config_Tasmota_13.2
decode-config -c my.conf -s tasmota-4281 --restore-file Config_Tasmota_13.3
```

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
62 changes: 33 additions & 29 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': '13.2.0.0',
'VERSION': '13.3.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 @@ -137,7 +137,7 @@ def module_import_error(module):
sys.exit(ExitCode.UNSUPPORTED_VERSION)
import platform
try:
from datetime import datetime
from datetime import datetime, timezone
import base64
import time
import copy
Expand Down Expand Up @@ -2110,7 +2110,7 @@ def match(self, setting_hardware, config_version):
'zb_topic_endpoint': (HARDWARE.ESP, '<L', (0xFB4,1, 6), (None, None, ('SetOption', '"SO120 {}".format($)')) ),
})
# ======================================================================
SETTING_9_2_0_5 = copy.copy(SETTING_9_2_0_4)
SETTING_9_2_0_5 = copy.deepcopy(SETTING_9_2_0_4)
SETTING_9_2_0_5.update ({
'power_esp32': (HARDWARE.ESP32, '<L', 0x2E8, (None, '0 <= $ <= 0b1111111111111111111111111111',
('Control', 'list("Power{} {}".format(i+1, (int($,0)>>i & 1) ) for i in range(0, 28))')),'"0x{:08x}".format($)' ),
Expand Down Expand Up @@ -2339,12 +2339,12 @@ def match(self, setting_hardware, config_version):
'sserial_config': (HARDWARE.ESP, 'B', 0x33E, (None, None, ('Serial', '"SSerialConfig {}".format(("5N1","6N1","7N1","8N1","5N2","6N2","7N2","8N2","5E1","6E1","7E1","8E1","5E2","6E2","7E2","8E2","5O1","6O1","7O1","8O1","5O2","6O2","7O2","8O2")[$ % 24])')) ),
})
# ======================================================================
SETTING_10_1_0_5 = copy.copy(SETTING_10_1_0_3)
SETTING_10_1_0_5 = copy.deepcopy(SETTING_10_1_0_3)
SETTING_10_1_0_5.update ({
'eth_ipv4_address': (HARDWARE.ESP32, '<L', 0xF88, ([5], None, ('Wifi', 'list("{} {}".format(["EthIPAddress","EthGateway","EthSubnetmask","EthDNSServer","EthDNSServer2"][i], socket.inet_ntoa(struct.pack("<L", @["eth_ipv4_address"][i]))) for i in range(0, len(@["eth_ipv4_address"])))')), ("socket.inet_ntoa(struct.pack('<L', $))", "struct.unpack('<L', socket.inet_aton($))[0]") ),
})
# ======================================================================
SETTING_10_1_0_6 = copy.copy(SETTING_10_1_0_5)
SETTING_10_1_0_6 = copy.deepcopy(SETTING_10_1_0_5)
SETTING_10_1_0_6.update ({
'web_time_start': (HARDWARE.ESP, 'B', 0x33C, (None, None, ('Management', '"WebTime {},{}".format($,@["web_time_end"])')) ),
'web_time_end': (HARDWARE.ESP, 'B', 0x33D, (None, None, ('Management', None)) ),
Expand Down Expand Up @@ -2468,7 +2468,7 @@ def match(self, setting_hardware, config_version):
'pwm_force_same_phase': (HARDWARE.ESP, '<L', (0xFB4,1,20), (None, None, ('SetOption', '"SO134 {}".format($)')) ),
})
# ======================================================================
SETTING_11_0_0_3 = copy.copy(SETTING_10_1_0_6)
SETTING_11_0_0_3 = copy.deepcopy(SETTING_10_1_0_6)
SETTING_11_0_0_3.update ({
'pulse_timer': (HARDWARE.ESP, '<H', 0x57C, ([32], '0 <= $ <= 65535', ('Control', '"PulseTime{} {}".format(#+1,$)')) ),
'rf_duplicate_time': (HARDWARE.ESP, '<H', 0x522, (None, '10 <= $ <= 65535', ('Rf', '"RfTimeOut {}".format($)')) ),
Expand All @@ -2489,7 +2489,7 @@ def match(self, setting_hardware, config_version):
'tuya_exclude_heartbeat': (HARDWARE.ESP, '<L', (0xFB4,1,23), (None, None, ('SetOption', '"SO137 {}".format($)')) ),
})
# ======================================================================
SETTING_11_0_0_5 = copy.copy(SETTING_11_0_0_4)
SETTING_11_0_0_5 = copy.deepcopy(SETTING_11_0_0_4)
SETTING_11_0_0_5.update ({
'weight_absconv_a': (HARDWARE.ESP, '<l', 0x524, (None, None, ('Sensor', None)) ),
'weight_absconv_b': (HARDWARE.ESP, '<l', 0x528, (None, None, ('Sensor', None)) ),
Expand All @@ -2502,13 +2502,13 @@ def match(self, setting_hardware, config_version):
'tuya_exclude_from_mqtt': (HARDWARE.ESP, '<L', (0xFB4,1,23), (None, None, ('SetOption', '"SO137 {}".format($)')) ),
})
# ======================================================================
SETTING_11_0_0_6 = copy.copy(SETTING_11_0_0_5)
SETTING_11_0_0_6 = copy.deepcopy(SETTING_11_0_0_5)
SETTING_11_0_0_6.update ({
'weight_absconv_a': (HARDWARE.ESP, '<l', 0x524, (None, None, ('Sensor', '"Sensor34 10 {}".format($)')) ),
'weight_absconv_b': (HARDWARE.ESP, '<l', 0x528, (None, None, ('Sensor', '"Sensor34 11 {}".format($)')) ),
})
# ======================================================================
SETTING_11_0_0_7 = copy.copy(SETTING_11_0_0_6)
SETTING_11_0_0_7 = copy.deepcopy(SETTING_11_0_0_6)
SETTING_11_0_0_7.update ({
'weight_offset': (HARDWARE.ESP, '<l', 0x578, (None, None, ('Sensor', None)) ),
'weight_user_tare': (HARDWARE.ESP, '<l', 0x338, (None, None, ('Sensor', '"Sensor34 10 {}".format($)')) ),
Expand Down Expand Up @@ -2547,7 +2547,7 @@ def match(self, setting_hardware, config_version):
'flowratemeter_unit': (HARDWARE.ESP, 'B', (0x717,1, 1), (None, '0 <= $ <= 1', ('Sensor', '"Sensor96 0 {}".format($)')) ),
})
# ======================================================================
SETTING_11_1_0_2 = copy.copy(SETTING_11_1_0_1)
SETTING_11_1_0_2 = copy.deepcopy(SETTING_11_1_0_1)
SETTING_11_1_0_2.update ({
'webcam_config2': (HARDWARE.ESP32, {
'wb_mode': (HARDWARE.ESP32, '<L', (0x730,3, 0), (None, '0 <= $ <= 6', ('Control', '"WCWBMode {}".format($)')) ),
Expand Down Expand Up @@ -2611,7 +2611,7 @@ def match(self, setting_hardware, config_version):
'mqtt_persistent': (HARDWARE.ESP, '<L', (0xFB4,1,26), (None, None, ('SetOption', '"SO140 {}".format($)')) ),
})
# ======================================================================
SETTING_11_1_0_3 = copy.copy(SETTING_11_1_0_2)
SETTING_11_1_0_3 = copy.deepcopy(SETTING_11_1_0_2)
SETTING_11_1_0_3.update ({
'flag6': (HARDWARE.ESP, '<L', 0xF74, (None, None, (INTERNAL, None)), '"0x{:08x}".format($)' ),
})
Expand Down Expand Up @@ -2653,12 +2653,12 @@ def match(self, setting_hardware, config_version):
SETTING_12_0_2_4.pop('energy_kWhyesterday',None)
SETTING_12_0_2_4.pop('energy_kWhtotal',None)
# ======================================================================
SETTING_12_1_0_1 = copy.copy(SETTING_12_0_2_4)
SETTING_12_1_0_1 = copy.deepcopy(SETTING_12_0_2_4)
SETTING_12_1_0_1['flag5'][1].update ({
'mqtt_status_retain': (HARDWARE.ESP, '<L', (0xFB4,1,31), (None, None, ('MQTT', '"StatusRetain {}".format($)')) ),
})
# ======================================================================
SETTING_12_1_1_1 = copy.copy(SETTING_12_1_0_1)
SETTING_12_1_1_1 = copy.deepcopy(SETTING_12_1_0_1)
SETTING_12_1_1_1.update ({
'flag6': (HARDWARE.ESP, {
'use_esp32_temperature': (HARDWARE.ESP, '<L', (0xF74,1, 0), (None, None, ('SetOption', '"SO146 {}".format($)')) ),
Expand All @@ -2685,7 +2685,7 @@ def match(self, setting_hardware, config_version):
'webcam_clk': (HARDWARE.ESP32, 'B', 0x72F, (None, '10 <= $ <= 200', ('Control', '"WcClock {}".format($)')) ),
})
# ======================================================================
SETTING_12_2_0_2 = copy.copy(SETTING_12_1_1_6)
SETTING_12_2_0_2 = copy.deepcopy(SETTING_12_1_1_6)
SETTING_12_2_0_2.update ({
'energy_power_calibration2': (HARDWARE.ESP, '<L', 0x370, (None, None, ('Power', '"PowerSet2 {}".format($)')) ),
'energy_voltage_calibration2': (HARDWARE.ESP, '<L', 0x374, (None, None, ('Power', '"VoltageSet2 {}".format($)')) ),
Expand Down Expand Up @@ -2714,12 +2714,12 @@ def match(self, setting_hardware, config_version):
'shutter_motorstop': (HARDWARE.ESP, '<H', 0x738, (None, None, ('Shutter', '"ShutterMotorStop {}".format($)')) ),
})
# ======================================================================
SETTING_12_3_1_1 = copy.copy(SETTING_12_2_0_6)
SETTING_12_3_1_1 = copy.deepcopy(SETTING_12_2_0_6)
SETTING_12_3_1_1['flag6'][1].update ({
'dns_ipv6_priority': (HARDWARE.ESP, '<L', (0xF74,1, 3), (None, None, ('SetOption', '"SO149 {}".format($)')) ),
})
# ======================================================================
SETTING_12_3_1_5 = copy.copy(SETTING_12_3_1_1)
SETTING_12_3_1_5 = copy.deepcopy(SETTING_12_3_1_1)
SETTING_12_3_1_5['flag6'][1].update ({
'no_voltage_common': (HARDWARE.ESP, '<L', (0xF74,1, 4), (None, None, ('SetOption', '"SO150 {}".format($)')) ),
'matter_enabled': (HARDWARE.ESP, '<L', (0xF74,1, 5), (None, None, ('SetOption', '"SO151 {}".format($)')) ),
Expand All @@ -2733,31 +2733,31 @@ def match(self, setting_hardware, config_version):
'show_stats': (HARDWARE.ESP, '<L', (0xFA4,1,12), (None, None, ('Power', None)) ),
})
# ======================================================================
SETTING_12_5_0_1 = copy.copy(SETTING_12_4_0_2)
SETTING_12_5_0_1 = copy.deepcopy(SETTING_12_4_0_2)
SETTING_12_5_0_1['flag6'][1].update ({
'bistable_single_pin': (HARDWARE.ESP, '<L', (0xF74,1, 6), (None, None, ('SetOption', '"SO152 {}".format($)')) ),
})
# ======================================================================
SETTING_12_5_0_3 = copy.copy(SETTING_12_5_0_1)
SETTING_12_5_0_3 = copy.deepcopy(SETTING_12_5_0_1)
SETTING_12_5_0_3['flag6'][1].update ({
'berry_no_autoexec': (HARDWARE.ESP, '<L', (0xF74,1, 7), (None, None, ('SetOption', '"SO153 {}".format($)')) ),
'berry_light_scheme': (HARDWARE.ESP, '<L', (0xF74,1, 8), (None, None, ('SetOption', '"SO154 {}".format($)')) ),
})
# ======================================================================
SETTING_13_0_0_1 = copy.copy(SETTING_12_5_0_3)
SETTING_13_0_0_1 = copy.deepcopy(SETTING_12_5_0_3)
SETTING_13_0_0_1.update ({
'zcdimmerset': (HARDWARE.ESP, '<H', 0xEA6, ([5], None, ('Light', '"ZCDimmerSet{} {}".format(#+1,$/100)')) ),
})
SETTING_13_0_0_1['flag6'][1].update ({
'zcfallingedge': (HARDWARE.ESP, '<L', (0xF74,1, 9), (None, None, ('SetOption', '"SO155 {}".format($)')) ),
})
# ======================================================================
SETTING_13_0_0_2 = copy.copy(SETTING_13_0_0_1)
SETTING_13_0_0_2 = copy.deepcopy(SETTING_13_0_0_1)
SETTING_13_0_0_2.update ({
'battery_level_percent': (HARDWARE.ESP, 'B', 0x73A, (None, '0 <= $ <= 101', ('Zigbee', '"BatteryPercentage {}".format($)')) ),
})
# ======================================================================
SETTING_13_1_0_1 = copy.copy(SETTING_13_0_0_2)
SETTING_13_1_0_1 = copy.deepcopy(SETTING_13_0_0_2)
SETTING_13_1_0_1.update ({
'my_gp_esp32c2': (HARDWARE.ESP32C2,
'<H', 0x3AC, ([21], None, ('Management', '"Gpio{} {}".format(#, $)')) ),
Expand All @@ -2782,7 +2782,7 @@ def match(self, setting_hardware, config_version):
'sen5x_passive_mode': (HARDWARE.ESP, '<L', (0xF74,1,10), (None, None, ('SetOption', '"SO156 {}".format($)')) ),
})
# ======================================================================
SETTING_13_1_0_2 = copy.copy(SETTING_13_1_0_1)
SETTING_13_1_0_2 = copy.deepcopy(SETTING_13_1_0_1)
SETTING_13_1_0_2.update ({
'hdmi_addr': (HARDWARE.ESP, '<H', 0x73B, (None, None, ('Hdmi', '"HdmiAddr {}".format($)')) ),
'hdmi_cec_device_type': (HARDWARE.ESP, 'B', 0xF61, (None, None, ('Hdmi', '"HdmiType {}".format($)')) ),
Expand All @@ -2793,10 +2793,16 @@ def match(self, setting_hardware, config_version):
'windmeter_measure_intvl': (HARDWARE.ESP, 'B', 0xF63, (None, None, ('Sensor', '"Sensor68 6,{}".format($)')) ),
})
# ======================================================================
SETTING_13_2_0_0 = copy.copy(SETTING_13_1_0_4)
SETTING_13_2_0_1 = copy.copy(SETTING_13_1_0_4)
SETTING_13_2_0_1['flag6'][1].update ({
'neopool_outputsensitive': (HARDWARE.ESP, '<L', (0xF74,1,11), (None, None, ('SetOption', '"SO157 {}".format($)')) ),
})
# ======================================================================
SETTING_13_3_0_0 = copy.copy(SETTING_13_2_0_1)
# ======================================================================
SETTINGS = [
(0x0D020000,0x1000, SETTING_13_2_0_0),
(0x0D030000,0x1000, SETTING_13_3_0_0),
(0x0D020001,0x1000, SETTING_13_2_0_1),
(0x0D010004,0x1000, SETTING_13_1_0_4),
(0x0D010002,0x1000, SETTING_13_1_0_2),
(0x0D010001,0x1000, SETTING_13_1_0_1),
Expand Down Expand Up @@ -3024,7 +3030,7 @@ def message(msg, type_=None, status=None, line=None):
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 if LogType.ERROR==type_ else sys.stdout)
file=sys.stderr)

if src is not None:
msg = '{} ({})'.format(src, msg)
Expand All @@ -3037,9 +3043,7 @@ def message(msg, type_=None, status=None, line=None):
if LogType.ERROR == type_ and doexit is None:
doexit = True
if doexit:
message(msg="Premature exit - #{} {}".format(status, ExitCode.str(status)), type_=None, status=None, line=None)
if EXIT_CODE > len(ExitCode.STR):
EXIT_CODE = -1
log(msg="Premature exit - #{} {}".format(status, ExitCode.str(status)), type_=None, status=None, line=None)
sys.exit(EXIT_CODE)

def shorthelp(doexit=True):
Expand Down Expand Up @@ -5919,7 +5923,7 @@ def bin2mapping(config, raw=False):

# add header info
valuemapping['header'] = {
'timestamp':datetime.utcfromtimestamp(cfg_timestamp).strftime("%Y-%m-%d %H:%M:%S"),
'timestamp':datetime.fromtimestamp(cfg_timestamp, tz=timezone.utc).strftime("%Y-%m-%d %H:%M:%S"),
'data': {
'crc': hex(get_settingcrc(config['decode'][:config['info']['template_size']])),
'size': len(config['decode']),
Expand Down

0 comments on commit 096465c

Please sign in to comment.