From aae0d96072f7c8a37f8b10c3152869125f063e85 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Wed, 17 Apr 2019 18:40:47 +0200 Subject: [PATCH] decode-config.py: adapt settings & fixes - add LedMask (led_mask) - add WebColor (web_color) - adapt Interlock (interlock) flag (6.4.1.11) - fix Sensor20 range (novasds_period) - fix PulseTime values - fix readonly bitstruct - fix wrong EnergyReset cmnd/values - cleanup rename vars having conflict with keywords (PEP 8) --- tools/decode-config.py | 395 +++++++++++++++++++++++++++-------------- 1 file changed, 258 insertions(+), 137 deletions(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 161cc850d..5bc7b1b54 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.0023' +VER = '2.1.0024' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -433,7 +433,7 @@ Setting_5_10_0 = { 'pwm_control': ('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) ), + '_': ('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: groups.add(group) - if isinstance(format, dict): - subgroups = GetGroupList(format) + if isinstance(format_, dict): + subgroups = GetGroupList(format_) if subgroups is not None and len(subgroups) > 0: for group in subgroups: groups.add(group) @@ -1478,8 +1493,11 @@ 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) + c.setopt(c.WRITEDATA, buffer_) c.setopt(c.POST, 1) c.setopt(c.URL, MakeUrl(host, port, 'u2')) if username is not None and password is not None: @@ -1506,6 +1524,7 @@ def PushTasmotaConfig(encode_cfg, host, port, username=DEFAULTS['source']['usern responsecode = c.getinfo(c.RESPONSE_CODE) except Exception, e: return e[0], e[1] + c.close() if responsecode >= 400: @@ -1513,6 +1532,21 @@ def PushTasmotaConfig(encode_cfg, host, port, username=DEFAULTS['source']['usern elif header.contenttype() != 'text/html': return ExitCode.UPLOAD_CONFIG_ERROR, "Device did not response properly, may be Tasmota webserver admin mode is disabled (WebServer 2)" + body = buffer_.getvalue() + + findUpload = body.find("Upload") + if findUpload < 0: + return ExitCode.UPLOAD_CONFIG_ERROR, "Device did not response properly with upload result page" + + body = body[findUpload:] + findSuccessful = body.find("Successful") + if findSuccessful < 0: + errmatch = re.search("(\S*)

(.*)
", body) + reason = "Unknown error" + if errmatch and len(errmatch.groups()) > 1: + reason = errmatch.group(2) + return ExitCode.UPLOAD_CONFIG_ERROR, reason + return 0, 'OK' @@ -1556,7 +1590,7 @@ def GetSettingsCrc(dobj): return crc & 0xffff -def GetFieldDef(fielddef, fields="format, addrdef, baseaddr, bits, bitshift, datadef, arraydef, validate, cmd, group, tasmotacmnd, converter, readconverter, writeconverter"): +def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, datadef, arraydef, validate, cmd, group, tasmotacmnd, converter, readconverter, writeconverter"): """ Get field definition items @@ -1570,7 +1604,7 @@ def GetFieldDef(fielddef, fields="format, addrdef, baseaddr, bits, bitshift, dat @return: set of values defined in """ - format = addrdef = baseaddr = datadef = arraydef = validate = cmd = group = tasmotacmnd = converter = readconverter = writeconverter = None + format_ = addrdef = baseaddr = datadef = arraydef = validate = cmd = group = tasmotacmnd = converter = readconverter = writeconverter = None bits = bitshift = 0 # calling with nothing is wrong @@ -1581,20 +1615,20 @@ def GetFieldDef(fielddef, fields="format, addrdef, baseaddr, bits, bitshift, dat # get top level items if len(fielddef) == 3: # converter not present - format, addrdef, datadef = fielddef + format_, addrdef, datadef = fielddef elif len(fielddef) == 4: # converter present - format, addrdef, datadef, converter = fielddef + format_, addrdef, datadef, converter = fielddef else: print >> sys.stderr, 'wrong {} length ({}) in setting'.format(fielddef, len(fielddef)) raise SyntaxError(' error') # ignore calls with 'root' setting - if isinstance(format, dict) and baseaddr is None and datadef is None: + if isinstance(format_, dict) and baseaddr is None and datadef is None: return eval(fields) - if not isinstance(format, (unicode,str,dict)): - print >> sys.stderr, 'wrong {} type {} in {}'.format(format, type(format), fielddef) + if not isinstance(format_, (unicode,str,dict)): + print >> sys.stderr, 'wrong {} type {} in {}'.format(format_, type(format_), fielddef) raise SyntaxError(' error') # extract addrdef items @@ -1604,16 +1638,16 @@ def GetFieldDef(fielddef, fields="format, addrdef, baseaddr, bits, bitshift, dat # baseaddr bit definition baseaddr, bits, bitshift = baseaddr if not isinstance(bits, int): - print >> sys.stderr, ' must be a integer in {}'.format(bits, fielddef) + print >> sys.stderr, ' must be defined as integer in {}'.format(bits, fielddef) raise SyntaxError(' error') if not isinstance(bitshift, int): - print >> sys.stderr, ' must be a integer in {}'.format(bitshift, fielddef) + print >> sys.stderr, ' must be defined as integer in {}'.format(bitshift, fielddef) raise SyntaxError(' error') else: print >> sys.stderr, 'wrong {} length ({}) in {}'.format(addrdef, len(addrdef), fielddef) raise SyntaxError(' error') if not isinstance(baseaddr, int): - print >> sys.stderr, ' must be a integer in {}'.format(baseaddr, fielddef) + print >> sys.stderr, ' must be defined as integer in {}'.format(baseaddr, fielddef) raise SyntaxError(' error') # extract datadef items @@ -1742,11 +1776,7 @@ def CmndConverter(valuemapping, value, idx, fielddef): evalstr = tasmotacmnd.replace('$','value').replace('#','idx').replace('@','valuemapping') else: evalstr = tasmotacmnd.replace('$','value').replace('@','valuemapping') - # ~ try: result = eval(evalstr) - # ~ except: - # ~ print evalstr - # ~ print value elif callable(tasmotacmnd): # use as format function if idx is not None: @@ -1790,6 +1820,46 @@ def ValidateValue(value, fielddef): return valid +def GetFormatCount(format_): + """ + Get format prefix count + + @param format_: + format specifier + + @return: + prefix count or 1 if not specified + """ + + if isinstance(format_, str): + match = re.search("\s*(\d+)", format_) + if match: + return int(match.group(0)) + + return 1 + + +def GetFormatType(format_): + """ + Get format type and bitsize without prefix + + @param format_: + format specifier + + @return: + (format_, 0) or (format without prefix, bitsize) + """ + + formattype = format_ + bitsize = 0 + if isinstance(format_, str): + match = re.search("\s*(\D+)", format_) + if match: + formattype = match.group(0) + bitsize = struct.calcsize(formattype) * 8 + return formattype, bitsize + + def GetFieldMinMax(fielddef): """ Get minimum, maximum of field based on field format definition @@ -1800,33 +1870,33 @@ def GetFieldMinMax(fielddef): @return: min, max """ - minmax = {'c': (0, 1), - '?': (0, 1), - 'b': (~0x7f, 0x7f), - 'B': (0, 0xff), - 'h': (~0x7fff, 0x7fff), - 'H': (0, 0xffff), - 'i': (~0x7fffffff, 0x7fffffff), - 'I': (0, 0xffffffff), - 'l': (~0x7fffffff, 0x7fffffff), - 'L': (0, 0xffffffff), + minmax = {'c': (0, 0xff), + '?': (0, 1), + 'b': (~0x7f, 0x7f), + 'B': (0, 0xff), + 'h': (~0x7fff, 0x7fff), + 'H': (0, 0xffff), + 'i': (~0x7fffffff, 0x7fffffff), + 'I': (0, 0xffffffff), + 'l': (~0x7fffffff, 0x7fffffff), + 'L': (0, 0xffffffff), 'q': (~0x7fffffffffffffff, 0x7fffffffffffffff), 'Q': (0, 0x7fffffffffffffff), - 'f': (sys.float_info.min, sys.float_info.max), - 'd': (sys.float_info.min, sys.float_info.max), + 'f': (sys.float_info.min, sys.float_info.max), + 'd': (sys.float_info.min, sys.float_info.max), } - format = GetFieldDef(fielddef, fields='format') - _min = 0 - _max = 0 - - if format[-1:] in minmax: - _min, _max = minmax[format[-1:]] - elif format[-1:] in ['s','p']: + format_ = GetFieldDef(fielddef, fields='format_') + min_ = 0 + max_ = 0 + + if format_[-1:] in minmax: + min_, max_ = minmax[format_[-1:]] + max_ *= GetFormatCount(format_) + elif format_[-1:] in ['s','p']: # s and p may have a prefix as length - match = re.search("\s*(\d+)", format) - if match: - _max=int(match.group(0)) - return _min,_max + max_ = GetFormatCount(format_) + + return min_,max_ def GetFieldLength(fielddef): @@ -1841,7 +1911,7 @@ def GetFieldLength(fielddef): """ length=0 - format, addrdef, arraydef = GetFieldDef(fielddef, fields='format, addrdef, arraydef') + format_, addrdef, arraydef = GetFieldDef(fielddef, fields='format_, addrdef, arraydef') # contains a integer list if isinstance(arraydef, list) and len(arraydef) > 0: @@ -1850,15 +1920,15 @@ def GetFieldLength(fielddef): for i in range(0, arraydef[0]): subfielddef = GetSubfieldDef(fielddef) if len(arraydef) > 1: - length += GetFieldLength( (format, addrdef, subfielddef) ) + length += GetFieldLength( (format_, addrdef, subfielddef) ) # single array else: - length += GetFieldLength( (format, addrdef, None) ) + length += GetFieldLength( (format_, addrdef, None) ) - elif isinstance(format, dict): + elif isinstance(format_, dict): # -> iterate through format addr = None - setting = format + setting = format_ for name in setting: baseaddr, bits, bitshift = GetFieldDef(setting[name], fields='baseaddr, bits, bitshift') _len = GetFieldLength(setting[name]) @@ -1867,20 +1937,8 @@ def GetFieldLength(fielddef): length += _len # a simple value - elif isinstance(format, str): - if format[-1:] in ['b','B','c','?']: - length=1 - elif format[-1:] in ['h','H']: - length=2 - elif format[-1:] in ['i','I','l','L','f']: - length=4 - elif format[-1:] in ['q','Q','d']: - length=8 - elif format[-1:] in ['s','p']: - # s and p may have a prefix as length - match = re.search("\s*(\d+)", format) - if match: - length=int(match.group(0)) + elif isinstance(format_, str): + length = struct.calcsize(format_) return length @@ -1896,7 +1954,7 @@ def GetSubfieldDef(fielddef): subfield definition """ - format, addrdef, datadef, arraydef, validate, cmd, converter = GetFieldDef(fielddef, fields='format, addrdef, datadef, arraydef, validate, cmd, converter') + format_, addrdef, datadef, arraydef, validate, cmd, converter = GetFieldDef(fielddef, fields='format_, addrdef, datadef, arraydef, validate, cmd, converter') # create new arraydef if len(arraydef) > 1: @@ -1916,9 +1974,9 @@ def GetSubfieldDef(fielddef): # set new field def subfielddef = None if converter is not None: - subfielddef = (format, addrdef, datadef, converter) + subfielddef = (format_, addrdef, datadef, converter) else: - subfielddef = (format, addrdef, datadef) + subfielddef = (format_, addrdef, datadef) return subfielddef @@ -1941,6 +1999,79 @@ def IsFilterGroup(group): return True +def GetFieldValue(fielddef, dobj, addr): + """ + Get single field value from definition + + @param fielddef: + see Settings desc + @param dobj: + decrypted binary config data + @param addr + addr within dobj + + @return: + value read from dobj + """ + + format_, bits, bitshift = GetFieldDef(fielddef, fields='format_, bits, bitshift') + + value_ = 0 + unpackedvalue = struct.unpack_from(format_, dobj, addr) + singletype, bitsize = GetFormatType(format_) + + if not format_[-1:].lower() in ['s','p']: + for val in unpackedvalue: + value_ <<= bitsize + value_ = value_ + val + value_ = bitsRead(value_, bitshift, bits) + else: + value_ = unpackedvalue[0] + s = str(value_).split('\0')[0] # use left string until \0 + value_ = unicode(s, errors='ignore') # remove character > 127 + + return value_ + + +def SetFieldValue(fielddef, dobj, addr, value): + """ + Set single field value from definition + + @param fielddef: + see Settings desc + @param dobj: + decrypted binary config data + @param addr + addr within dobj + @param value + new value + + @return: + new decrypted binary config data + """ + + format_, bits, bitshift = GetFieldDef(fielddef, fields='format_, bits, bitshift') + 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) + if not format_[-1:].lower() in ['s','p']: + addr += (bitsize / 8) * formatcnt + for _ in range(0, formatcnt): + addr -= (bitsize / 8) + val = value & ((2**bitsize) - 1) + if args.debug >= 3: + print >> sys.stderr, "SetFieldValue(): Single type - fielddef {}, addr 0x{:04x} value {} singletype {} bitsize {}".format(fielddef,addr,val,singletype,bitsize) + struct.pack_into(singletype, dobj, addr, val) + value >>= bitsize + else: + if args.debug >= 3: + print >> sys.stderr, "SetFieldValue(): String type - fielddef {}, addr 0x{:04x} value {} format_ {}".format(fielddef,addr,value,format_) + struct.pack_into(format_, dobj, addr, value) + + return dobj + + def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0): """ Get field value from definition @@ -1966,7 +2097,7 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0): valuemapping = None # get field definition - format, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd = GetFieldDef(fielddef, fields='format, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd') + format_, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd = GetFieldDef(fielddef, fields='format_, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd') # filter groups if not IsFilterGroup(group): @@ -1985,36 +2116,24 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0): offset += length # contains a dict - elif isinstance(format, dict): + elif isinstance(format_, dict): mapping_value = {} # -> iterate through format - for name in format: + for name in format_: value = None - value = GetField(dobj, name, format[name], raw=raw, addroffset=addroffset) + value = GetField(dobj, name, format_[name], raw=raw, addroffset=addroffset) if value is not None: mapping_value[name] = value # copy complete returned mapping valuemapping = copy.deepcopy(mapping_value) # a simple value - elif isinstance(format, (str, bool, int, float, long)): + elif isinstance(format_, (str, bool, int, float, long)): if GetFieldLength(fielddef) != 0: - valuemapping = struct.unpack_from(format, dobj, baseaddr+addroffset)[0] - - if not format[-1:].lower() in ['s','p']: - valuemapping = bitsRead(valuemapping, bitshift, bits) - - # additional processing for strings - if format[-1:].lower() in ['s','p']: - # use left string until \0 - s = str(valuemapping).split('\0')[0] - # remove character > 127 - valuemapping = unicode(s, errors='ignore') - - valuemapping = ReadWriteConverter(valuemapping, fielddef, read=True, raw=raw) + valuemapping = ReadWriteConverter(GetFieldValue(fielddef, dobj, baseaddr+addroffset), fielddef, read=True, raw=raw) else: - exit(ExitCode.INTERNAL_ERROR, "Wrong mapping format definition: '{}'".format(format), typ=LogType.WARNING, doexit=not args.ignorewarning, line=inspect.getlineno(inspect.currentframe())) + exit(ExitCode.INTERNAL_ERROR, "Wrong mapping format definition: '{}'".format(format_), typ=LogType.WARNING, doexit=not args.ignorewarning, line=inspect.getlineno(inspect.currentframe())) return valuemapping @@ -2039,7 +2158,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): @return: new decrypted binary config data """ - format, baseaddr, bits, bitshift, arraydef, group, writeconverter = GetFieldDef(fielddef, fields='format, baseaddr, bits, bitshift, arraydef, group, writeconverter') + format_, baseaddr, bits, bitshift, arraydef, group, writeconverter = GetFieldDef(fielddef, fields='format_, baseaddr, bits, bitshift, arraydef, group, writeconverter') # cast unicode fieldname = str(fieldname) @@ -2049,8 +2168,8 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): # do not write readonly values if writeconverter is False: - if args.debug: - print >> sys.stderr, "SetField(): Readonly '{}' using '{}'/{}{} @{} skipped".format(fieldname, format, arraydef, bits, hex(baseaddr+addroffset)) + if args.debug >= 2: + print >> sys.stderr, "SetField(): Readonly '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset)) return dobj # contains a list @@ -2069,23 +2188,23 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): offset += length # contains a dict - elif isinstance(format, dict): - for name in format: # -> iterate through format + elif isinstance(format_, dict): + for name in format_: # -> iterate through format if name in restore: - dobj = SetField(dobj, name, format[name], restore[name], addroffset=addroffset, filename=filename) + dobj = SetField(dobj, name, format_[name], restore[name], addroffset=addroffset, filename=filename) # a simple value - elif isinstance(format, (str, bool, int, float, long)): + elif isinstance(format_, (str, bool, int, float, long)): valid = True err = "" errformat = "" - _min, _max = GetFieldMinMax(fielddef) + min_, max_ = GetFieldMinMax(fielddef) value = _value = None skip = False # simple char value - if format[-1:] in ['c']: + if format_[-1:] in ['c']: try: value = ReadWriteConverter(restore.encode(STR_ENCODING)[0], fielddef, read=False) except Exception, e: @@ -2093,7 +2212,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): valid = False # bool - elif format[-1:] in ['?']: + elif format_[-1:] in ['?']: try: value = ReadWriteConverter(bool(restore), fielddef, read=False) except Exception, e: @@ -2101,7 +2220,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): valid = False # integer - elif format[-1:] in ['b','B','h','H','i','I','l','L','q','Q','P']: + elif format_[-1:] in ['b','B','h','H','i','I','l','L','q','Q','P']: value = ReadWriteConverter(restore, fielddef, read=False) if isinstance(value, (str, unicode)): value = int(value, 0) @@ -2110,16 +2229,17 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): # bits if bits != 0: bitvalue = value - value = struct.unpack_from(format, dobj, baseaddr+addroffset)[0] + value = struct.unpack_from(format_, dobj, baseaddr+addroffset)[0] # validate restore value valid = ValidateValue(bitvalue, fielddef) if not valid: err = "valid bit range exceeding" + value = bitvalue else: mask = (1< mask: - _min = 0 - _max = mask + min_ = 0 + max_ = mask _value = bitvalue valid = False else: @@ -2142,19 +2262,19 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): _value = value # float - elif format[-1:] in ['f','d']: + elif format_[-1:] in ['f','d']: try: value = ReadWriteConverter(float(restore), fielddef, read=False) except: valid = False # string - elif format[-1:] in ['s','p']: + elif format_[-1:] in ['s','p']: value = ReadWriteConverter(restore.encode(STR_ENCODING), fielddef, read=False) err = "string length exceeding" if value is not None: - _max -= 1 - valid = _min <= len(value) <= _max + max_ -= 1 + valid = min_ <= len(value) <= max_ else: skip = True valid = True @@ -2165,7 +2285,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): if valid is None and not skip: # validate against object type size - valid = _min <= value <= _max + valid = min_ <= value <= max_ if not valid: err = "type range exceeding" errformat = " [{smin},{smax}]" @@ -2179,21 +2299,22 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""): if valid: if not skip: - if args.debug: - if bits: - sbits=" {} bits shift {}".format(bits, bitshift) - else: - sbits = "" - print >> sys.stderr, "SetField(): Set '{}' using '{}'/{}{} @{} to {}".format(fieldname, format, arraydef, sbits, hex(baseaddr+addroffset), _value) - if fieldname != 'cfg_crc': - prevvalue = struct.unpack_from(format, dobj, baseaddr+addroffset)[0] - struct.pack_into(format, dobj, baseaddr+addroffset, value) - curvalue = struct.unpack_from(format, dobj, baseaddr+addroffset)[0] + 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) + if fieldname != 'cfg_crc' and fieldname != '_': + prevvalue = GetFieldValue(fielddef, dobj, baseaddr+addroffset) + dobj = SetFieldValue(fielddef, dobj, baseaddr+addroffset, value) + curvalue = GetFieldValue(fielddef, dobj, baseaddr+addroffset) if prevvalue != curvalue and args.verbose: message("Value for '{}' changed from {} to {}".format(fieldname, prevvalue, curvalue), typ=LogType.INFO) + else: + if args.debug >= 2: + print >> sys.stderr, "SetField(): Special field '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset)) 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), typ=LogType.WARNING, doexit=not args.ignorewarning) + exit(ExitCode.RESTORE_DATA_ERROR, sformat.format(sfile=filename, sname=fieldname, serror=err, svalue=_value, smin=min_, smax=max_), typ=LogType.WARNING, doexit=not args.ignorewarning) return dobj @@ -2220,7 +2341,7 @@ def SetCmnd(cmnds, fieldname, fielddef, valuemapping, mappedvalue, addroffset=0, @return: new Tasmota command mapping """ - format, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd, writeconverter = GetFieldDef(fielddef, fields='format, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd, writeconverter') + format_, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd, writeconverter = GetFieldDef(fielddef, fields='format_, baseaddr, bits, bitshift, arraydef, group, tasmotacmnd, writeconverter') # cast unicode fieldname = str(fieldname) @@ -2245,13 +2366,13 @@ def SetCmnd(cmnds, fieldname, fielddef, valuemapping, mappedvalue, addroffset=0, offset += length # contains a dict - elif isinstance(format, dict): - for name in format: # -> iterate through format + elif isinstance(format_, dict): + for name in format_: # -> iterate through format if name in mappedvalue: - cmnds = SetCmnd(cmnds, name, format[name], valuemapping, mappedvalue[name], addroffset=addroffset, idx=idx) + cmnds = SetCmnd(cmnds, name, format_[name], valuemapping, mappedvalue[name], addroffset=addroffset, idx=idx) # a simple value - elif isinstance(format, (str, bool, int, float, long)): + elif isinstance(format_, (str, bool, int, float, long)): cmnd = CmndConverter(valuemapping, mappedvalue, idx, fielddef) if group is not None and cmnd is not None: @@ -2804,7 +2925,7 @@ def ParseArgs(): info = parser.add_argument_group('Info','Extra information') info.add_argument('-D', '--debug', dest='debug', - action='store_true', + action='count', help=configargparse.SUPPRESS) info.add_argument('-h', '--help', dest='shorthelp', @@ -2823,7 +2944,7 @@ def ParseArgs(): args = parser.parse_args() - if args.debug: + if args.debug >= 1: print >> sys.stderr, parser.format_values() print >> sys.stderr, "Settings:" for k in args.__dict__: