Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix group cpr412 #1653

Merged
merged 6 commits into from
Oct 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 41 additions & 21 deletions Classes/GroupMgtv2/GrpDomoticz.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from Classes.GroupMgtv2.GrpCommands import (set_hue_saturation,
set_kelvin_color, set_rgb_color)
from Classes.GroupMgtv2.GrpDatabase import update_due_to_nwk_id_change
from Modules.tools import Hex_Format
from Modules.tools import Hex_Format, is_hex
from Modules.zigateConsts import ADDRESS_MODE, LEGRAND_REMOTES, ZIGATE_EP
from Zigbee.zclCommands import (zcl_group_level_move_to_level,
zcl_group_move_to_level_with_onoff,
Expand All @@ -19,6 +19,7 @@
zcl_group_onoff_on,
zcl_group_window_covering_off,
zcl_group_window_covering_on,
zcl_group_move_to_level_stop,
zcl_group_window_covering_stop)

WIDGET_STYLE = {
Expand Down Expand Up @@ -185,6 +186,7 @@ def best_group_widget(self, GroupId):
# }

GroupWidgetType = None
GroupWidgetStyle = None

self.logging("Debug", "best_group_widget Device - %s" % str(self.ListOfGroups[GroupId]["Devices"]))
for NwkId, devEp, iterIEEE in self.ListOfGroups[GroupId]["Devices"]:
Expand All @@ -194,7 +196,7 @@ def best_group_widget(self, GroupId):
if NwkId == "0000":
continue

self.logging("debug", "bestGroupWidget - Group: %s processing %s" % (GroupId, NwkId))
self.logging("Debug", "bestGroupWidget - Group: %s processing %s" % (GroupId, NwkId))
if NwkId not in self.ListOfDevices:
# We have some inconsistency !
continue
Expand All @@ -207,9 +209,13 @@ def best_group_widget(self, GroupId):
WidgetType = self.ListOfDevices[NwkId]["Ep"][devEp]["ClusterType"][DomoDeviceUnit]
self.logging("Debug", "------------ GroupWidget: %s WidgetType: %s" % (GroupWidgetType, WidgetType))

if WidgetType == "LvlControl" and "Blind" in self.ListOfDevices[NwkId]["Type"]:
GroupWidgetStyle = "BlindPercentInverted"

if WidgetType in ("VenetianInverted", "VanneInverted", "CurtainInverted"):
# Those widgets are commanded via cluster Level Control
GroupWidgetType = "LvlControl"
GroupWidgetStyle = "VenetianInverted"
continue

if GroupWidgetType is None and WidgetType in WIDGET_STYLE:
Expand Down Expand Up @@ -245,7 +251,6 @@ def best_group_widget(self, GroupId):
GroupWidgetType = WidgetType
continue


if WidgetType in ("Venetian", "WindowCovering", "BlindPercentInverted"):
GroupWidgetType = WidgetType

Expand Down Expand Up @@ -281,13 +286,13 @@ def best_group_widget(self, GroupId):
else:
self.ListOfGroups[GroupId]["Cluster"] = ""

self.logging(
"Debug",
"best_group_widget for GroupId: %s Found WidgetType: %s Widget: %s"
% (GroupId, GroupWidgetType, WIDGET_STYLE.get(GroupWidgetType, WIDGET_STYLE["ColorControlFull"])),
)
self.logging( "Debug", "best_group_widget for GroupId: %s Found WidgetType: %s Widget: %s" % (
GroupId, GroupWidgetType, WIDGET_STYLE.get(GroupWidgetType, WIDGET_STYLE["ColorControlFull"])), )

return WIDGET_STYLE.get(GroupWidgetType, WIDGET_STYLE["ColorControlFull"])
if GroupWidgetStyle is None:
GroupWidgetStyle = GroupWidgetType

return WIDGET_STYLE.get(GroupWidgetStyle, WIDGET_STYLE["ColorControlFull"])


def update_domoticz_group_device(self, GroupId):
Expand Down Expand Up @@ -317,7 +322,7 @@ def update_domoticz_group_device(self, GroupId):
if "Cluster" in self.ListOfGroups[GroupId]:
Cluster = self.ListOfGroups[GroupId]["Cluster"]

countOn = countOff = 0
countStop = countOn = countOff = 0
nValue = 0 if self.pluginconf.pluginConf["OnIfOneOn"] else 1
sValue = level = None
for NwkId, Ep, IEEE in self.ListOfGroups[GroupId]["Devices"]:
Expand Down Expand Up @@ -347,11 +352,13 @@ def update_domoticz_group_device(self, GroupId):
and Cluster in ("0006", "0008", "0300")
and "0006" in self.ListOfDevices[NwkId]["Ep"][Ep]
and "0000" in self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]
and str(self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"]).isdigit()
and is_hex( str(self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"]) )
):
self.logging( "Debug", "update_domoticz_group_device - Cluster ON/OFF Group: %s NwkId: %s Ep: %s Value: %s" %(
GroupId, NwkId, Ep, self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"]))
if int(self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"]) != 0:
if str(self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"]) == "f0":
countStop += 1
elif int(self.ListOfDevices[NwkId]["Ep"][Ep]["0006"]["0000"]) != 0:
countOn += 1
else:
countOff += 1
Expand Down Expand Up @@ -381,23 +388,31 @@ def update_domoticz_group_device(self, GroupId):
level = lvl_value if level is None else (level + lvl_value) // 2
nValue, sValue = ValuesForVenetian(level)

self.logging( "Debug", "update_domoticz_group_device - Processing: Group: %s %s/%s On: %s, Off: %s level: %s" % (
GroupId, NwkId, Ep, countOn, countOff, level), )
self.logging( "Debug", "update_domoticz_group_device - Processing: Group: %s %s/%s On: %s, Off: %s Stop: %s, level: %s" % (
GroupId, NwkId, Ep, countOn, countOff, countStop, level), )

if self.pluginconf.pluginConf["OnIfOneOn"]:
if countStop > 0:
nValue = 17
elif self.pluginconf.pluginConf["OnIfOneOn"]:
if countOn > 0:
nValue = 1
elif countOff > 0:
nValue = 0
self.logging( "Debug", "update_domoticz_group_device - Processing: Group: %s == > nValue: %s, level: %s" % (
GroupId, nValue, level), )


# At that stage
# nValue == 0 if Off
# nValue == 1 if Open/On
# nValue == 17 if Stop
# level is None, so we use nValue/sValue
# level is not None; so we have a LvlControl
if sValue is None and level:
if nValue == 17:
# Stop
sValue = "0"

elif sValue is None and level:
if self.Devices[unit].SwitchType not in (13, 14, 15, 16):
# Not a Shutter/Blind
analogValue = level
Expand Down Expand Up @@ -439,11 +454,8 @@ def update_domoticz_group_device(self, GroupId):
else:
sValue = "On"

self.logging(
"Debug",
"update_domoticz_group_device - Processing: Group: %s == > from %s:%s to %s:%s"
% (GroupId, self.Devices[unit].nValue, self.Devices[unit].sValue, nValue, sValue),
)
self.logging( "Debug", "update_domoticz_group_device - Processing: Group: %s == > from %s:%s to %s:%s" % (
GroupId, self.Devices[unit].nValue, self.Devices[unit].sValue, nValue, sValue), )
if nValue != self.Devices[unit].nValue or sValue != self.Devices[unit].sValue:
self.logging("Log", "UpdateGroup - (%15s) %s:%s" % (self.Devices[unit].Name, nValue, sValue))
self.Devices[unit].Update(nValue, sValue)
Expand Down Expand Up @@ -680,6 +692,14 @@ def processCommand(self, unit, GrpId, Command, Level, Color_):
sValue = "On"
self.Devices[unit].Update(nValue=int(nValue), sValue=str(sValue))

elif Command in ( "Stop",) and self.ListOfGroups[GrpId]["Cluster"] == "0102":
# Windowscovering Stop
zcl_group_window_covering_stop(self, GrpId, "01", EPout)

elif Command in ( "Stop",) and self.ListOfGroups[GrpId]["Cluster"] == "0008":
# SetLevel Off
zcl_group_move_to_level_stop(self, GrpId, EPout)

elif Command == "Set Level":
# Level: % value of move
# Converted to value , raw value from 0 to 255
Expand Down
41 changes: 21 additions & 20 deletions Modules/domoMaj.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,14 +1184,27 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col
# We do update only if this is a On/off
UpdateDevice_v2(self, Devices, DeviceUnit, 1, "On", BatteryLevel, SignalLevel)

elif WidgetType == "VenetianInverted" and model_name in ( "PR412", "CPR412", "CPR412-E") and clusterID == "0006":
self.log.logging( "Widget", "Debug", "--++-> %s/%s ClusterType: %s Updating %s Value: %s" % (NWKID, Ep, ClusterType, WidgetType, value), NWKID, )
# nValue will depends if we are on % or not
if value == '01':
nValue = 0
sValue = "0"

elif value == '00':
nValue = 1
sValue = "100"

elif value == 'f0':
nValue = 17
sValue = "0"

self.log.logging("Widget", "Debug", "------> %s %s/%s Value: %s:%s" % (WidgetType, NWKID, Ep, nValue, sValue), NWKID)
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, sValue, BatteryLevel, SignalLevel)

elif WidgetType in ("VenetianInverted", "Venetian", "WindowCovering", "VanneInverted", "Vanne", "Curtain", "CurtainInverted"):
_value = int(value, 16)
self.log.logging(
"Widget",
"Debug",
"------> %s/%s ClusterType: %s Updating %s Value: %s" % (NWKID, Ep, ClusterType, WidgetType, _value),
NWKID,
)
self.log.logging( "Widget", "Debug", "------> %s/%s ClusterType: %s Updating %s Value: %s" % (NWKID, Ep, ClusterType, WidgetType, _value), NWKID, )
if WidgetType in ("VenetianInverted", "VanneInverted"):
_value = 100 - _value
self.log.logging("Widget", "Debug", "------> Patching %s/%s Value: %s" % (NWKID, Ep, _value), NWKID)
Expand Down Expand Up @@ -1258,13 +1271,7 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, str(_value), BatteryLevel, SignalLevel)

if "LvlControl" in ClusterType: # LvlControl ( 0x0008)
if WidgetType == "LvlControl" or (
WidgetType
in (
"BSO-Volet",
"Blind",
)
):
if WidgetType == "LvlControl" or ( WidgetType in ( "BSO-Volet", "Blind", ) ):
# We need to handle the case, where we get an update from a Read Attribute or a Reporting message
# We might get a Level, but the device is still Off and we shouldn't make it On .
nValue = None
Expand Down Expand Up @@ -1320,13 +1327,7 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col
nValue, normalized_value, Devices[DeviceUnit].SwitchType), NWKID, )
UpdateDevice_v2( self, Devices, DeviceUnit, Devices[DeviceUnit].nValue, str(normalized_value), BatteryLevel, SignalLevel, )

elif WidgetType in (
"ColorControlRGB",
"ColorControlWW",
"ColorControlRGBWW",
"ColorControlFull",
"ColorControl",
):
elif WidgetType in ( "ColorControlRGB", "ColorControlWW", "ColorControlRGBWW", "ColorControlFull", "ColorControl", ):
if Devices[DeviceUnit].nValue != 0 or Devices[DeviceUnit].sValue != "Off":
nValue, sValue = getDimmerLevelOfColor(self, value)
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, str(sValue), BatteryLevel, SignalLevel, Color_)
Expand Down
3 changes: 2 additions & 1 deletion Modules/readZclClusters.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,8 @@ def majdomodevice_possiblevalues( self, MsgSrcEp, MsgClusterId, MsgAttrID, model
return True
eval_result = eval( _majdomodeviceValidValues )

self.log.logging("ZclClusters", "Debug", " . majdomodevice_possiblevalues: %s -> %s" %( eval_result, _majdomodeviceValidValues))
self.log.logging("ZclClusters", "Debug", " . majdomodevice_possiblevalues: >%s<(%s) %s -> %s" %(
value, type(value), eval_result, _majdomodeviceValidValues))
return eval_result


Expand Down
11 changes: 10 additions & 1 deletion Zigbee/zclCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,11 @@ def zcl_move_to_level_with_onoff(self, nwkid, EPout, OnOff, level, transition="0
return send_zigatecmd_zcl_noack(self, nwkid, "0081", data)
return send_zigatecmd_zcl_ack(self, nwkid, "0081", data)

def zcl_move_to_level_stop(self, nwkid, EPout, ackIsDisabled=DEFAULT_ACK_MODE):
self.log.logging("zclCommand", "Debug", "zcl_move_to_level_stop %s %s" % (nwkid, EPout, ))
zcl_command_formated_logging( self, "zcl_move_to_level_stop", nwkid, EPout, "0008", "Stop", ackIsDisabled)
if "ControllerInRawMode" in self.pluginconf.pluginConf and self.pluginconf.pluginConf["ControllerInRawMode"]:
return zcl_raw_level_move_to_level(self, nwkid, ZIGATE_EP, EPout, "Stop")

def zcl_group_move_to_level_with_onoff(self, nwkid, EPout, OnOff, level, transition="0000", ackIsDisabled=DEFAULT_ACK_MODE):
self.log.logging("zclCommand", "Debug", "zcl_move_to_level_with_onoff %s %s %s %s %s" % (nwkid, EPout, OnOff, level, transition))
Expand All @@ -457,7 +462,11 @@ def zcl_group_move_to_level_with_onoff(self, nwkid, EPout, OnOff, level, transit
data = "%02d" % ADDRESS_MODE["group"] + nwkid + ZIGATE_EP + EPout + OnOff + level + transition
return send_zigatecmd_raw(self, "0081", data)


def zcl_group_move_to_level_stop(self, nwkid, EPout, ackIsDisabled=DEFAULT_ACK_MODE):
self.log.logging("zclCommand", "Debug", "zcl_move_to_level_stop %s %s" % (nwkid, EPout, ))
zcl_command_formated_logging( self, "zcl_move_to_level_stop", nwkid, EPout, "0008", "Stop", ackIsDisabled)
if "ControllerInRawMode" in self.pluginconf.pluginConf and self.pluginconf.pluginConf["ControllerInRawMode"]:
return zcl_raw_level_move_to_level(self, nwkid, ZIGATE_EP, EPout, "Stop", groupaddrmode=True)

# Cluster 0102 ( Window Covering )
##################################
Expand Down
Loading