diff --git a/tools/decode-config.html b/tools/decode-config.html
index 68968f00d..4dc80286b 100644
--- a/tools/decode-config.html
+++ b/tools/decode-config.html
@@ -211,109 +211,109 @@ If you do not want using auto extensions use the --no-extension
par
For better reading each short written arg (minus sign -
) has a corresponding long version (two minus signs --
), eg. --device
for -d
or --file
for -f
(note: not even all --
arg has a corresponding -
one).
A short list of possible program args is displayed using -h
or --help
.
For advanced help use -H
or --full-help
:
usage: decode-config.py [-f <filename>] [-d <host>] [-P <port>]
- [-u <username>] [-p <password>] [-i <filename>]
- [-o <filename>] [-t json|bin|dmp] [-E] [-e] [-F]
- [--json-indent <indent>] [--json-compact]
- [--json-hide-pw] [--json-show-pw]
- [--cmnd-indent <indent>] [--cmnd-groups]
- [--cmnd-nogroups] [--cmnd-sort] [--cmnd-unsort]
- [-c <filename>] [-S] [-T json|cmnd|command]
- [-g {Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi} [{Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi} ...]]
- [--ignore-warnings] [-h] [-H] [-v] [-V]
+usage: decode-config.py [-f <filename>] [-d <host>] [-P <port>]
+ [-u <username>] [-p <password>] [-i <filename>]
+ [-o <filename>] [-t json|bin|dmp] [-E] [-e] [-F]
+ [--json-indent <indent>] [--json-compact]
+ [--json-hide-pw] [--json-show-pw]
+ [--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,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} ...]]
+ [--ignore-warnings] [-h] [-H] [-v] [-V]
-Backup/Restore Sonoff-Tasmota configuration data. Args that start with '--'
-(eg. -f) 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
-https://goo.gl/R74nmi). If an arg is specified in more than one place, then
-commandline values override config file values which override defaults.
+Backup/Restore Sonoff-Tasmota configuration data. Args that start with '--'
+(eg. -f) 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
+https://goo.gl/R74nmi). If an arg is specified in more than one place, then
+commandline values override config file values which override defaults.
-Source:
- Read/Write Tasmota configuration from/to
+Source:
+ Read/Write Tasmota configuration from/to
- -f, --file, --tasmota-file <filename>
- file to retrieve/write Tasmota configuration from/to
- (default: None)'
- -d, --device, --host <host>
- hostname or IP address to retrieve/send Tasmota
- configuration from/to (default: None)
- -P, --port <port> TCP/IP port number to use for the host connection
- (default: 80)
- -u, --username <username>
- host HTTP access username (default: admin)
- -p, --password <password>
- host HTTP access password (default: None)
+ -f, --file, --tasmota-file <filename>
+ file to retrieve/write Tasmota configuration from/to
+ (default: None)'
+ -d, --device, --host <host>
+ hostname or IP address to retrieve/send Tasmota
+ configuration from/to (default: None)
+ -P, --port <port> TCP/IP port number to use for the host connection
+ (default: 80)
+ -u, --username <username>
+ host HTTP access username (default: admin)
+ -p, --password <password>
+ host HTTP access password (default: None)
-Backup/Restore:
- Backup & restore specification
+Backup/Restore:
+ Backup & restore specification
- -i, --restore-file <filename>
- file to restore configuration from (default: None).
- Replacements: @v=firmware version from config,
- @f=device friendly name from config, @h=device
- hostname from config, @H=device hostname from device
- (-d arg only)
- -o, --backup-file <filename>
- file to backup configuration to (default: None).
- Replacements: @v=firmware version from config,
- @f=device friendly name from config, @h=device
- hostname from config, @H=device hostname from device
- (-d arg only)
- -t, --backup-type json|bin|dmp
- backup filetype (default: 'json')
- -E, --extension append filetype extension for -i and -o filename
- (default)
- -e, --no-extension do not append filetype extension, use -i and -o
+ -i, --restore-file <filename>
+ file to restore configuration from (default: None).
+ Replacements: @v=firmware version from config,
+ @f=device friendly name from config, @h=device
+ hostname from config, @H=device hostname from device
+ (-d arg only)
+ -o, --backup-file <filename>
+ file to backup configuration to (default: None).
+ Replacements: @v=firmware version from config,
+ @f=device friendly name from config, @h=device
+ hostname from config, @H=device hostname from device
+ (-d arg only)
+ -t, --backup-type json|bin|dmp
+ backup filetype (default: 'json')
+ -E, --extension append filetype extension for -i and -o filename
+ (default)
+ -e, --no-extension do not append filetype extension, use -i and -o
filename as passed
- -F, --force-restore force restore even configuration is identical
+ -F, --force-restore force restore even configuration is identical
-JSON output:
- JSON format specification
+JSON output:
+ JSON format specification
- --json-indent <indent>
- pretty-printed JSON output using indent level
- (default: 'None'). -1 disables indent.
- --json-compact compact JSON output by eliminate whitespace
- --json-hide-pw hide passwords
- --json-show-pw, --json-unhide-pw
- unhide passwords (default)
+ --json-indent <indent>
+ pretty-printed JSON output using indent level
+ (default: 'None'). -1 disables indent.
+ --json-compact compact JSON output by eliminate whitespace
+ --json-hide-pw hide passwords
+ --json-show-pw, --json-unhide-pw
+ unhide passwords (default)
-Tasmota command output:
- Tasmota command output format specification
+Tasmota command output:
+ Tasmota command output format specification
- --cmnd-indent <indent>
- Tasmota command grouping indent level (default: '2').
- 0 disables indent
- --cmnd-groups group Tasmota commands (default)
- --cmnd-nogroups leave Tasmota commands ungrouped
- --cmnd-sort sort Tasmota commands (default)
- --cmnd-unsort leave Tasmota commands unsorted
+ --cmnd-indent <indent>
+ Tasmota command grouping indent level (default: '2').
+ 0 disables indent
+ --cmnd-groups group Tasmota commands (default)
+ --cmnd-nogroups leave Tasmota commands ungrouped
+ --cmnd-sort sort Tasmota commands (default)
+ --cmnd-unsort leave Tasmota commands unsorted
-Common:
- Optional arguments
+Common:
+ Optional arguments
- -c, --config <filename>
- program config file - can be used to set default
- command args (default: None)
- -S, --output display output regardsless of backup/restore usage
- (default do not output on backup or restore usage)
- -T, --output-format json|cmnd|command
- display output format (default: 'json')
- -g, --group {Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi}
- limit data processing to command groups (default no
- filter)
- --ignore-warnings do not exit on warnings. Not recommended, used by your
+ -c, --config <filename>
+ program config file - can be used to set default
+ command args (default: None)
+ -S, --output display output regardsless of backup/restore usage
+ (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,MQTT,Management,Power,Rules,Sensor,Serial,SetOption,SonoffRF,System,Timer,Wifi}
+ limit data processing to command groups (default no
+ filter)
+ --ignore-warnings do not exit on warnings. Not recommended, used by your
own responsibility!
-Info:
- Extra information
+Info:
+ Extra information
- -h, --help show usage help message and exit
- -H, --full-help show full help message and exit
- -v, --verbose produce more output about what the program does
- -V, --version show program's version number and exit
+ -h, --help show usage help message and exit
+ -H, --full-help show full help message and exit
+ -v, --verbose produce more output about what the program does
+ -V, --version show program's version number and exit
-Either argument -d <host> or -f <filename> must be given.
+Either argument -d <host> or -f <filename> must be given.
Program parameter notes
decode-config.py
Examples
diff --git a/tools/decode-config.md b/tools/decode-config.md
index ca70d36e9..01b20a143 100644
--- a/tools/decode-config.md
+++ b/tools/decode-config.md
@@ -237,7 +237,7 @@ For advanced help use `-H` or `--full-help`:
[--cmnd-indent ] [--cmnd-groups]
[--cmnd-nogroups] [--cmnd-sort] [--cmnd-unsort]
[-c ] [-S] [-T json|cmnd|command]
- [-g {Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi} [{Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi} ...]]
+ [-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} ...]]
[--ignore-warnings] [-h] [-H] [-v] [-V]
Backup/Restore Sonoff-Tasmota configuration data. Args that start with '--'
@@ -317,7 +317,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 {Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi}
+ -g, --group {Control,Devices,Display,Domoticz,Internal,KNX,Light,MQTT,Management,Power,Rules,Sensor,Serial,SetOption,SonoffRF,System,Timer,Wifi}
limit data processing to command groups (default no
filter)
--ignore-warnings do not exit on warnings. Not recommended, used by your
diff --git a/tools/decode-config.py b/tools/decode-config.py
index 5bc7b1b54..d05b8ff49 100755
--- a/tools/decode-config.py
+++ b/tools/decode-config.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-VER = '2.1.0024'
+VER = '2.2.0025'
"""
decode-config.py - Backup/Restore Sonoff-Tasmota configuration data
@@ -43,7 +43,7 @@ Usage: decode-config.py [-f ] [-d ] [-P ]
[--cmnd-indent ] [--cmnd-groups]
[--cmnd-nogroups] [--cmnd-sort] [--cmnd-unsort]
[-c ] [-S] [-T json|cmnd|command]
- [-g {Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi} [{Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi} ...]]
+ [-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} ...]]
[--ignore-warnings] [-h] [-H] [-v] [-V]
Backup/Restore Sonoff-Tasmota configuration data. Args that start with '--'
@@ -123,7 +123,7 @@ Usage: decode-config.py [-f ] [-d ] [-P ]
(default do not output on backup or restore usage)
-T, --output-format json|cmnd|command
display output format (default: 'json')
- -g, --group {Display,Domoticz,Internal,KNX,Led,Logging,MCP230xx,MQTT,Main,Management,Pow,Sensor,Serial,SetOption,SonoffRF,System,Timers,Wifi}
+ -g, --group {Control,Devices,Display,Domoticz,Internal,KNX,Light,MQTT,Management,Power,Rules,Sensor,Serial,SetOption,SonoffRF,System,Timer,Wifi}
limit data processing to command groups (default no
filter)
--ignore-warnings do not exit on warnings. Not recommended, used by your
@@ -308,7 +308,7 @@ Settings dictionary describes the config file fields definition:
Tasmota command definition
:
command group string
- :
+ : | (,...)
convert data into Tasmota command function
: | (, )
@@ -407,7 +407,6 @@ def MqttFingerprint(value, idx=None):
# ----------------------------------------------------------------------
# Tasmota configuration data definition
# ----------------------------------------------------------------------
-Groups = ('Main','Sensor','Timers','Management','Wifi','MQTT','Serial','SetOption','Logging','Pow','Led','KNX','Domoticz','Display','MCP230xx')
Setting_5_10_0 = {
# , , [,]
'cfg_holder': ('0 and bitsRead($,0,11)>(12*60) else "",time=time.strftime("%H:%M",time.gmtime((bitsRead($,0,11) if bitsRead($,29,2)==0 else bitsRead($,0,11) if bitsRead($,0,11)<=(12*60) else bitsRead($,0,11)-(12*60))*60)),window=bitsRead($,11,4),repeat=bitsRead($,15),days="{:07b}".format(bitsRead($,16,7))[::-1],device=bitsRead($,23,4)+1,power=bitsRead($,27,2) )')), ('"0x{:08x}".format($)', False) ),
- 'time': ('0 and bitsRead($,0,11)>(12*60) else "",time=time.strftime("%H:%M",time.gmtime((bitsRead($,0,11) if bitsRead($,29,2)==0 else bitsRead($,0,11) if bitsRead($,0,11)<=(12*60) else bitsRead($,0,11)-(12*60))*60)),window=bitsRead($,11,4),repeat=bitsRead($,15),days="{:07b}".format(bitsRead($,16,7))[::-1],device=bitsRead($,23,4)+1,power=bitsRead($,27,2) )')), ('"0x{:08x}".format($)', False) ),
+ 'time': ('= 0 and args.device is not None:
device_hostname = GetTasmotaHostname(args.device, args.port, username=args.username, password=args.password)
if device_hostname is None:
@@ -1493,7 +1501,6 @@ def PushTasmotaConfig(encode_cfg, host, port, username=DEFAULTS['source']['usern
# post data
c = pycurl.Curl()
header = HTTPHeader()
- from StringIO import StringIO
buffer_ = io.BytesIO()
c.setopt(c.HEADERFUNCTION, header.store)
c.setopt(c.WRITEFUNCTION, lambda x: None)
@@ -1665,9 +1672,16 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
if group is not None and not isinstance(group, (str, unicode)):
print >> sys.stderr, 'wrong {} in {}'.format(group, fielddef)
raise SyntaxError(' error')
- if tasmotacmnd is not None and not callable(tasmotacmnd) and not isinstance(tasmotacmnd, (str, unicode)):
- print >> sys.stderr, 'wrong {} in {}'.format(tasmotacmnd, fielddef)
- raise SyntaxError(' 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 {} in {}'.format(tasmotacmnd, fielddef)
+ raise SyntaxError(' error')
+ else:
+ if tasmotacmnd is not None and not callable(tasmotacmnd) and not isinstance(tasmotacmnd, (str, unicode)):
+ print >> sys.stderr, 'wrong {} in {}'.format(tasmotacmnd, fielddef)
+ raise SyntaxError(' error')
else:
print >> sys.stderr, 'wrong {} length ({}) in {}'.format(cmd, len(cmd), fielddef)
raise SyntaxError(' error')
@@ -1991,10 +2005,13 @@ def IsFilterGroup(group):
@return:
True if group is in filter, otherwise False
"""
+
if args.filter is not None:
if group is None:
return False
- if group != INTERNAL and group != '*' and group not in args.filter:
+ if group == '*':
+ return False
+ if group.title() != INTERNAL.title() and group.title() not in (groupname.title() for groupname in args.filter):
return False
return True
@@ -2373,12 +2390,20 @@ def SetCmnd(cmnds, fieldname, fielddef, valuemapping, mappedvalue, addroffset=0,
# a simple value
elif isinstance(format_, (str, bool, int, float, long)):
- cmnd = CmndConverter(valuemapping, mappedvalue, idx, fielddef)
-
- if group is not None and cmnd is not None:
- if group not in cmnds:
- cmnds[group] = []
- cmnds[group].append(cmnd)
+ if isinstance(tasmotacmnd, tuple):
+ tasmotacmnds = tasmotacmnd
+ for tasmotacmnd in tasmotacmnds:
+ cmnd = CmndConverter(valuemapping, mappedvalue, idx, fielddef)
+ if group is not None and cmnd is not None:
+ if group not in cmnds:
+ cmnds[group] = []
+ cmnds[group].append(cmnd)
+ else:
+ cmnd = CmndConverter(valuemapping, mappedvalue, idx, fielddef)
+ if group is not None and cmnd is not None:
+ if group not in cmnds:
+ cmnds[group] = []
+ cmnds[group].append(cmnd)
return cmnds
@@ -2401,7 +2426,7 @@ def Bin2Mapping(decode_cfg):
# if we did not found a mathching setting
if setting is None:
- exit(ExitCode.UNSUPPORTED_VERSION, "Tasmota configuration version 0x{:x} not supported".format(version),line=inspect.getlineno(inspect.currentframe()))
+ exit(ExitCode.UNSUPPORTED_VERSION, "Tasmota configuration version {} not supported".format(version),line=inspect.getlineno(inspect.currentframe()))
if 'version' in setting:
cfg_version = GetField(decode_cfg, 'version', setting['version'], raw=True)
@@ -2655,7 +2680,7 @@ def Restore(restorefile, backupfileformat, encode_cfg, decode_cfg, configmapping
elif filetype == FileType.BIN:
if args.verbose:
- message("Reading restore file '{}' (binary format)".format(restorefilename), typ=LogType.INFO)
+ message("Reading restore file '{}' (Binary format)".format(restorefilename), typ=LogType.INFO)
try:
with open(restorefilename, "rb") as restorefp:
restorebin = restorefp.read()
@@ -2688,6 +2713,13 @@ def Restore(restorefile, backupfileformat, encode_cfg, decode_cfg, configmapping
exit(ExitCode.FILE_READ_ERROR, "File '{}' unknown error".format(restorefilename),line=inspect.getlineno(inspect.currentframe()))
if new_encode_cfg is not None:
+ if args.verbose:
+ new_decode_cfg = DecryptEncrypt(new_encode_cfg)
+ # get binary header and template to use
+ version, size, setting = GetTemplateSetting(new_decode_cfg)
+ # get config file version
+ cfg_version = GetField(new_decode_cfg, 'version', setting['version'], raw=True)
+ message("Config file contains data of Sonoff-Tasmota {}".format(GetVersionStr(cfg_version)), typ=LogType.INFO)
if args.forcerestore or new_encode_cfg != encode_cfg:
# write config direct to device via http
if args.device is not None:
@@ -2734,9 +2766,11 @@ def OutputTasmotaCmnds(tasmotacmnds):
for cmnd in cmnds:
print "{}{}".format(" "*args.cmndindent, cmnd)
+ groups = GetGroupList(Settings[0][2])
+
if args.cmndgroup:
- for group in Groups:
- if group in tasmotacmnds:
+ for group in groups:
+ if group.title() in (groupname.title() for groupname in tasmotacmnds):
cmnds = tasmotacmnds[group]
print
print "# {}:".format(group)
@@ -2744,8 +2778,8 @@ def OutputTasmotaCmnds(tasmotacmnds):
else:
cmnds = []
- for group in Groups:
- if group in tasmotacmnds:
+ for group in groups:
+ if group.title() in (groupname.title() for groupname in tasmotacmnds):
cmnds.extend(tasmotacmnds[group])
OutputTasmotaSubCmnds(cmnds)
@@ -2913,6 +2947,7 @@ def ParseArgs():
dest='filter',
choices=groups,
nargs='+',
+ type=lambda s : s.title(),
default=DEFAULTS['common']['filter'],
help="limit data processing to command groups (default {})".format("no filter" if DEFAULTS['common']['filter'] == None else DEFAULTS['common']['filter']) )
common.add_argument('--ignore-warnings',
@@ -2993,7 +3028,7 @@ if __name__ == "__main__":
# decode into mappings dictionary
configmapping = Bin2Mapping(decode_cfg)
if args.verbose and 'version' in configmapping:
- message("{} '{}' is using version {}".format('File' if args.tasmotafile is not None else 'Device',
+ message("{} '{}' is using Sonoff-Tasmota {}".format('File' if args.tasmotafile is not None else 'Device',
args.tasmotafile if args.tasmotafile is not None else args.device,
GetVersionStr(configmapping['version'])),
typ=LogType.INFO)