Resolved conflit and Updated the code Skop dimmer packets for non-dimmer configuration

1. Rsolved the build conflict on sonoff/_changelog.ino
tools/decode-config.py

2. Updated the code Skop dimmer packets for non-dimmer configuration
This commit is contained in:
thirug010 2019-05-22 01:28:38 -05:00
parent 86af0df712
commit ab9baf2ac0
3 changed files with 71 additions and 53 deletions

View File

@ -1,15 +1,25 @@
/* /*
* 6.5.0.14 20190520 * 6.5.0.13 20190517
* Updated xdrv_16_tuyadimmer.ino repalced TuyGetPower with bitRead()
*
* 6.5.0.12 20190517
* Add command SetOption65 (tuya_show_dimmer) to enable or disable dimmer Slider ( for 4 Gang Tuya switch) * Add command SetOption65 (tuya_show_dimmer) to enable or disable dimmer Slider ( for 4 Gang Tuya switch)
* Added Seeting.pram9 to define no of Tuya MCU devices * Added Seeting.pram9 to define no of Tuya MCU devices
* Updated xdrv_01_webserver.ino to check for the tuya_show_dimmer option to display slider2 * Updated xdrv_01_webserver.ino to check for the tuya_show_dimmer option to display slider2
* Updated xdrv_16_tuyadimmer.ino create bool serial packet based on the Device Id and set the power status based on the Device id from MCU packet * Updated xdrv_16_tuyadimmer.ino create bool serial packet based on the Device Id and set the power status based on the Device id from MCU packet
* Updated xdrv_16_tuyadimmer.ino skip dimmer packets for device configured as non - dimmer
*
* 6.5.0.12 20190521
* Add AriLux RF control GPIO option "ALux IrSel" (159) replacing "Led4i" (59) for full LED control (#5709)
* Add LED GPIO option "LedLink" (157) and "LedLinki" (158) to select dedicated link status LED (#5709)
* Add support for up to four LEDs related to four power outputs. Enabled when "LedLink(i)" is configured too (#5709)
* Add extended LED power control using command LedPowerX where X is 1 to 4. Enabled when "LedLink(i)" is configured too (#5709)
* *
* 6.5.0.11 20190517 * 6.5.0.11 20190517
* Add command SetOption64 0/1 to switch between "-" or "_" as sensor index separator impacting DS18X20, DHT, BMP and SHT3X sensor names (#5689) * Add command SetOption64 0/1 to switch between "-" or "_" as sensor index separator impacting DS18X20, DHT, BMP and SHT3X sensor names (#5689)
* Add initial support for Scripts as replacement for Rules. Default disabled but can be enabled in my_user_config.h (#5689)
* Add rule System#Save executed just before a planned restart
* Add HX711 weight restore after controlled restart or after power restore just before executing command Sensor34 7 (#5367, #5786)
* Remove define USE_EMULATION from my_user_config.h (#5826)
* Add defines USE_EMULATION_WEMO and USE_EMULATION_HUE to my_user_config.h to control emulation features at compile time (#5826)
* Add support for SPS30 Particle sensor thanks to Gerhard Mutz (#5830)
* *
* 6.5.0.10 20190513 * 6.5.0.10 20190513
* Enable ADC0 by default in my_user_config.h (#5671) * Enable ADC0 by default in my_user_config.h (#5671)

View File

@ -207,21 +207,23 @@ void TuyaPacketProcess(void)
else if (tuya_buffer[5] == 8) { // dim packet else if (tuya_buffer[5] == 8) { // dim packet
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), tuya_buffer[13]); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), tuya_buffer[13]);
if(Settings.flag3.tuya_show_dimmer == 0) //
{
if (!Settings.param[P_TUYA_DIMMER_ID]) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Autoconfiguring Dimmer ID %d"), tuya_buffer[6]);
Settings.param[P_TUYA_DIMMER_ID] = tuya_buffer[6];
}
if (!Settings.param[P_TUYA_DIMMER_ID]) { tuya_new_dim = round(tuya_buffer[13] * (100. / 255.));
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Autoconfiguring Dimmer ID %d"), tuya_buffer[6]); if((power || Settings.flag3.tuya_apply_o20) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 1)) {
Settings.param[P_TUYA_DIMMER_ID] = tuya_buffer[6];
}
tuya_new_dim = round(tuya_buffer[13] * (100. / 255.)); snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), tuya_new_dim );
if((power || Settings.flag3.tuya_apply_o20) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 1)) {
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER " %d"), tuya_new_dim ); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send CMND_DIMMER_STR=%s"), scmnd );
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send CMND_DIMMER_STR=%s"), scmnd ); tuya_ignore_dim = true;
ExecuteCommand(scmnd, SRC_SWITCH);
tuya_ignore_dim = true; }
ExecuteCommand(scmnd, SRC_SWITCH);
} }
} }
break; break;

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
VER = '2.2.0025' VER = '2.2.0026'
""" """
decode-config.py - Backup/Restore Sonoff-Tasmota configuration data decode-config.py - Backup/Restore Sonoff-Tasmota configuration data
@ -29,7 +29,7 @@ Requirements:
Instructions: Instructions:
Execute command with option -d to retrieve config data from a host Execute command with option -d to retrieve config data from a host
or use -f to read a configuration file saved using Tasmota Web-UI or use -f to read a configuration file saved using Tasmota Web-UI
For further information read 'decode-config.md' For further information read 'decode-config.md'
For help execute command with argument -h (or -H for advanced help) For help execute command with argument -h (or -H for advanced help)
@ -263,7 +263,7 @@ exitcode = 0
Settings dictionary describes the config file fields definition: Settings dictionary describes the config file fields definition:
<setting> = { <name> : <def> } <setting> = { <name> : <def> }
<name>: "string" <name>: "string"
a python valid dictionary key (string) a python valid dictionary key (string)
@ -333,12 +333,12 @@ Settings dictionary describes the config file fields definition:
to convert value from JSON back to binary object to convert value from JSON back to binary object
Common definitions Common definitions
<function>: <functionname> | <string> | None <function>: <functionname> | <string> | None
function to be called or string to evaluate: function to be called or string to evaluate:
<functionname>: <functionname>:
A function name will be called with one or two parameter: A function name will be called with one or two parameter:
The value to be processed The value to be processed
(optional) the current array index (1,n) (optional) the current array index (1,n)
<string> <string>
A string will be evaluate as is. The following A string will be evaluate as is. The following
@ -358,7 +358,7 @@ Settings dictionary describes the config file fields definition:
numbers in the range -2147483648 through 2147483647 numbers in the range -2147483648 through 2147483647
<uint>: unsigned integer <uint>: unsigned integer
numbers in the range 0 through 4294967295 numbers in the range 0 through 4294967295
""" """
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Settings helper # Settings helper
@ -370,16 +370,16 @@ def passwordwrite(value):
def bitsRead(x, n=0, c=1): def bitsRead(x, n=0, c=1):
""" """
Reads bit(s) of a number Reads bit(s) of a number
@param x: @param x:
the number from which to read the number from which to read
@param n: @param n:
which bit position to read which bit position to read
@param c: @param c:
how many bits to read (1 if omitted) how many bits to read (1 if omitted)
@return: @return:
the bit value(s) the bit value(s)
""" """
@ -396,14 +396,14 @@ def bitsRead(x, n=0, c=1):
x &= (1<<c)-1 x &= (1<<c)-1
return x return x
def MqttFingerprint(value, idx=None): def MqttFingerprint(value, idx=None):
fingerprint = "" fingerprint = ""
for i in value: for i in value:
fingerprint += "{:02x} ".format(ord(i)) fingerprint += "{:02x} ".format(ord(i))
return "MqttFingerprint{} {}".format('' if idx is None else idx, fingerprint.strip()) return "MqttFingerprint{} {}".format('' if idx is None else idx, fingerprint.strip())
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Tasmota configuration data definition # Tasmota configuration data definition
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -871,7 +871,7 @@ Setting_6_4_1_16.update({
'pullup': ('B', (0x73C,1,1), (None, None, ('Management', None)) ), 'pullup': ('B', (0x73C,1,1), (None, None, ('Management', None)) ),
}, 0x73C, (None, None, ('Management', None)) }, 0x73C, (None, None, ('Management', None))
), ),
}, 0x720, (None, None, ('Management', None)) }, 0x720, (None, None, ('Management', None))
), ),
}) })
# ====================================================================== # ======================================================================
@ -903,14 +903,20 @@ Setting_6_5_0_9['flag3'][0].update ({
'no_power_feedback': ('<L', (0x3A0,1,13), (None, None, ('SetOption', '"SetOption63 {}".format($)')) ), 'no_power_feedback': ('<L', (0x3A0,1,13), (None, None, ('SetOption', '"SetOption63 {}".format($)')) ),
}) })
# ====================================================================== # ======================================================================
# ======================================================================
Setting_6_5_0_10 = copy.deepcopy(Setting_6_5_0_9) Setting_6_5_0_10 = copy.deepcopy(Setting_6_5_0_9)
Setting_6_5_0_10['flag3'][0].update ({ Setting_6_5_0_10['flag3'][0].update ({
'use_underscore': ('<L', (0x3A0,1,14), (None, None, ('SetOption', '"SetOption64 {}".format($)')) ),
})
# ======================================================================
# ======================================================================
Setting_6_5_0_11 = copy.deepcopy(Setting_6_5_0_10)
Setting_6_5_0_11['flag3'][0].update ({
'tuya_show_dimmer': ('<L', (0x3A0,1,15), (None, None, ('SetOption', '"SetOption65 {}".format($)')) ), 'tuya_show_dimmer': ('<L', (0x3A0,1,15), (None, None, ('SetOption', '"SetOption65 {}".format($)')) ),
}) })
# ====================================================================== # ======================================================================
Settings = [ Settings = [
(0x6050010, 0xe00, Setting_6_5_0_10), (0x605000B, 0xe00, Setting_6_5_0_11),
(0x605000B, 0xe00, Setting_6_5_0_10),
(0x6050009, 0xe00, Setting_6_5_0_9), (0x6050009, 0xe00, Setting_6_5_0_9),
(0x6050007, 0xe00, Setting_6_5_0_7), (0x6050007, 0xe00, Setting_6_5_0_7),
(0x6050006, 0xe00, Setting_6_5_0_6), (0x6050006, 0xe00, Setting_6_5_0_6),
@ -1132,7 +1138,7 @@ def GetTemplateSetting(decode_cfg):
def GetGroupList(setting): def GetGroupList(setting):
""" """
Get all avilable group definition from setting Get all avilable group definition from setting
@return: @return:
configargparse.parse_args() result configargparse.parse_args() result
""" """
@ -1142,17 +1148,17 @@ def GetGroupList(setting):
dev = setting[name] dev = setting[name]
format_, group = GetFieldDef(dev, fields="format_, group") format_, group = GetFieldDef(dev, fields="format_, group")
if group is not None and len(group) > 0: if group is not None and len(group) > 0:
groups.add(group) groups.add(group.title())
if isinstance(format_, dict): if isinstance(format_, dict):
subgroups = GetGroupList(format_) subgroups = GetGroupList(format_)
if subgroups is not None and len(subgroups) > 0: if subgroups is not None and len(subgroups) > 0:
for group in subgroups: for group in subgroups:
groups.add(group) groups.add(group.title())
groups=list(groups) groups=list(groups)
groups.sort() groups.sort()
return groups return groups
class FileType: class FileType:
FILE_NOT_FOUND = None FILE_NOT_FOUND = None
@ -1347,7 +1353,7 @@ def MakeUrl(host, port=80, location=''):
def LoadTasmotaConfig(filename): def LoadTasmotaConfig(filename):
""" """
Load config from Tasmota file Load config from Tasmota file
@param filename: @param filename:
filename to load filename to load
@ -1420,7 +1426,7 @@ def TasmotaGet(cmnd, host, port, username=DEFAULTS['source']['username'], passwo
body = buffer.getvalue() body = buffer.getvalue()
except: except:
pass pass
return responsecode, body return responsecode, body
@ -1605,7 +1611,7 @@ def GetSettingsCrc(dobj):
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 Get field definition items
@ -1723,7 +1729,7 @@ def GetFieldDef(fielddef, fields="format_, addrdef, baseaddr, bits, bitshift, da
else: else:
print >> sys.stderr, 'wrong <converter> {} length ({}) in <fielddef> {}'.format(converter, len(converter), fielddef) print >> sys.stderr, 'wrong <converter> {} length ({}) in <fielddef> {}'.format(converter, len(converter), fielddef)
raise SyntaxError('<fielddef> error') raise SyntaxError('<fielddef> error')
return eval(fields) return eval(fields)
@ -1798,13 +1804,13 @@ def CmndConverter(valuemapping, value, idx, fielddef):
else: else:
evalstr = tasmotacmnd.replace('$','value').replace('@','valuemapping') evalstr = tasmotacmnd.replace('$','value').replace('@','valuemapping')
result = eval(evalstr) result = eval(evalstr)
elif callable(tasmotacmnd): # use as format function elif callable(tasmotacmnd): # use as format function
if idx is not None: if idx is not None:
result = tasmotacmnd(value, idx) result = tasmotacmnd(value, idx)
else: else:
result = tasmotacmnd(value) result = tasmotacmnd(value)
return result return result
@ -1821,7 +1827,7 @@ def ValidateValue(value, fielddef):
True if value is valid, False if invalid True if value is valid, False if invalid
""" """
validate = GetFieldDef(fielddef, fields='validate') validate = GetFieldDef(fielddef, fields='validate')
if value == 0: if value == 0:
# can not complete all validate condition # can not complete all validate condition
# some Tasmota values are not allowed to be 0 on input # some Tasmota values are not allowed to be 0 on input
@ -1918,7 +1924,7 @@ def GetFieldMinMax(fielddef):
max_ = GetFormatCount(format_) max_ = GetFormatCount(format_)
return min_,max_ return min_,max_
def GetFieldLength(fielddef): def GetFieldLength(fielddef):
""" """
@ -2039,7 +2045,7 @@ def GetFieldValue(fielddef, dobj, addr):
""" """
format_, bits, bitshift = GetFieldDef(fielddef, fields='format_, bits, bitshift') format_, bits, bitshift = GetFieldDef(fielddef, fields='format_, bits, bitshift')
value_ = 0 value_ = 0
unpackedvalue = struct.unpack_from(format_, dobj, addr) unpackedvalue = struct.unpack_from(format_, dobj, addr)
singletype, bitsize = GetFormatType(format_) singletype, bitsize = GetFormatType(format_)
@ -2076,7 +2082,7 @@ def SetFieldValue(fielddef, dobj, addr, value):
format_, bits, bitshift = GetFieldDef(fielddef, fields='format_, bits, bitshift') format_, bits, bitshift = GetFieldDef(fielddef, fields='format_, bits, bitshift')
formatcnt = GetFormatCount(format_) formatcnt = GetFormatCount(format_)
singletype, bitsize = GetFormatType(format_) singletype, bitsize = GetFormatType(format_)
if args.debug >= 2: if args.debug >= 2:
print >> sys.stderr, "SetFieldValue(): fielddef {}, addr 0x{:04x} value {} formatcnt {} singletype {} bitsize {} ".format(fielddef,addr,value,formatcnt,singletype,bitsize) 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']: if not format_[-1:].lower() in ['s','p']:
@ -2138,7 +2144,7 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0):
value = GetField(dobj, fieldname, subfielddef, raw=raw, addroffset=addroffset+offset) value = GetField(dobj, fieldname, subfielddef, raw=raw, addroffset=addroffset+offset)
valuemapping.append(value) valuemapping.append(value)
offset += length offset += length
# <format> contains a dict # <format> contains a dict
elif isinstance(format_, dict): elif isinstance(format_, dict):
mapping_value = {} mapping_value = {}
@ -2333,7 +2339,7 @@ def SetField(dobj, fieldname, fielddef, restore, addroffset=0, filename=""):
curvalue = GetFieldValue(fielddef, dobj, baseaddr+addroffset) curvalue = GetFieldValue(fielddef, dobj, baseaddr+addroffset)
if prevvalue != curvalue and args.verbose: if prevvalue != curvalue and args.verbose:
message("Value for '{}' changed from {} to {}".format(fieldname, prevvalue, curvalue), typ=LogType.INFO) message("Value for '{}' changed from {} to {}".format(fieldname, prevvalue, curvalue), typ=LogType.INFO)
else: else:
if args.debug >= 2: if args.debug >= 2:
print >> sys.stderr, "SetField(): Special field '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset)) print >> sys.stderr, "SetField(): Special field '{}' using '{}'/{}{} @{} skipped".format(fieldname, format_, arraydef, bits, hex(baseaddr+addroffset))
else: else:
@ -2502,14 +2508,14 @@ def Mapping2Bin(decode_cfg, jsonconfig, filename=""):
restore data mapping restore data mapping
@param filename: @param filename:
name of the restore file (for error output only) name of the restore file (for error output only)
@return: @return:
changed binary config data (decrypted) or None on error changed binary config data (decrypted) or None on error
""" """
if isinstance(decode_cfg, str): if isinstance(decode_cfg, str):
decode_cfg = bytearray(decode_cfg) decode_cfg = bytearray(decode_cfg)
# get binary header data to use the correct version template from device # get binary header data to use the correct version template from device
version, size, setting = GetTemplateSetting(decode_cfg) version, size, setting = GetTemplateSetting(decode_cfg)
@ -2549,13 +2555,13 @@ def Mapping2Cmnd(decode_cfg, valuemapping, filename=""):
data mapping data mapping
@param filename: @param filename:
name of the restore file (for error output only) name of the restore file (for error output only)
@return: @return:
Tasmota command mapping {group: [cmnd <,cmnd <,...>>]} Tasmota command mapping {group: [cmnd <,cmnd <,...>>]}
""" """
if isinstance(decode_cfg, str): if isinstance(decode_cfg, str):
decode_cfg = bytearray(decode_cfg) decode_cfg = bytearray(decode_cfg)
# get binary header data to use the correct version template from device # get binary header data to use the correct version template from device
version, size, setting = GetTemplateSetting(decode_cfg) version, size, setting = GetTemplateSetting(decode_cfg)
@ -2782,7 +2788,7 @@ def OutputTasmotaCmnds(tasmotacmnds):
print print
print "# {}:".format(group) print "# {}:".format(group)
OutputTasmotaSubCmnds(cmnds) OutputTasmotaSubCmnds(cmnds)
else: else:
cmnds = [] cmnds = []
for group in groups: for group in groups:
@ -2793,7 +2799,7 @@ def OutputTasmotaCmnds(tasmotacmnds):
def ParseArgs(): def ParseArgs():
""" """
Program argument parser Program argument parser
@return: @return:
configargparse.parse_args() result configargparse.parse_args() result
""" """
@ -3056,5 +3062,5 @@ if __name__ == "__main__":
if args.outputformat == 'cmnd' or args.outputformat == 'command': if args.outputformat == 'cmnd' or args.outputformat == 'command':
tasmotacmnds = Mapping2Cmnd(decode_cfg, configmapping) tasmotacmnds = Mapping2Cmnd(decode_cfg, configmapping)
OutputTasmotaCmnds(tasmotacmnds) OutputTasmotaCmnds(tasmotacmnds)
sys.exit(exitcode) sys.exit(exitcode)