Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
pipiche38 committed Dec 9, 2023
1 parent 6e26442 commit da29697
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 46 deletions.
6 changes: 4 additions & 2 deletions Modules/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,9 +694,9 @@ def mgtCommand(self, Devices, Unit, Command, Level, Color):

elif DeviceType == "ThermoOnOff":
if "Model" in self.ListOfDevices[NWKID] and self.ListOfDevices[NWKID]["Model"] in ("eTRV0100"):
danfoss_on_off(self, NWKID, 0x01)
danfoss_on_off(self, NWKID, 0x01)
else:
tuya_trv_onoff(self, NWKID, 0x01)
tuya_trv_onoff(self, NWKID, 0x01)
UpdateDevice_v2(self, Devices, Unit, 1, "On", BatteryLevel, SignalLevel, ForceUpdate_=forceUpdateDev)

elif DeviceType == "ShutterCalibration":
Expand Down Expand Up @@ -1360,6 +1360,8 @@ def mgtCommand(self, Devices, Unit, Command, Level, Color):

UpdateDevice_v2(self, Devices, Unit, 1, str(Level), BatteryLevel, SignalLevel, str(Color))



def get_previous_switch_level(self, NwkId, Ep):

if NwkId not in self.ListOfDevices:
Expand Down
112 changes: 69 additions & 43 deletions Modules/domoMaj.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
domo_read_nValue_sValue,
domo_read_SwitchType_SubType_Type,
domo_update_api,
find_widget_unit_from_WidgetID)
find_widget_unit_from_WidgetID,
is_dimmable_blind,
is_dimmable_light,
is_dimmable_switch)
from Modules.domoTools import (RetreiveSignalLvlBattery,
RetreiveWidgetTypeList, TypeFromCluster,
UpdateDevice_v2, remove_bad_cluster_type_entry)
Expand Down Expand Up @@ -66,7 +69,7 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col

model_name = self.ListOfDevices[NWKID].get("Model", "")

self.log.logging( "Widget", "Debug", "MajDomoDevice NwkId: %s Ep: %s ClusterId: %s Value: %s ValueType: %s Attribute: %s Color: %s ModelName: %s" % (
self.log.logging( "Widget", "Log", "MajDomoDevice NwkId: %s Ep: %s ClusterId: %s Value: %s ValueType: %s Attribute: %s Color: %s ModelName: %s" % (
NWKID, Ep, clusterID, value, type(value), Attribute_, Color_, model_name), NWKID, )

# Get the CluserType ( Action type) from Cluster Id
Expand Down Expand Up @@ -976,16 +979,25 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col

if ClusterType == "Switch" and WidgetType == "LvlControl":
# Called with ClusterID: 0x0006 but we have to update a Dimmer, so we need to keep the level
nValue = prev_nValue
sValue = prev_sValue
if switchType in (13, 16):
_dimmable_switch = is_dimmable_switch(self, Devices, device_id_ieee, DeviceUnit)
_dimmable_light = is_dimmable_light(self, Devices, device_id_ieee, DeviceUnit)
_dimmable_blind = is_dimmable_blind(self, Devices, device_id_ieee, DeviceUnit)

self.log.logging("Widget", "Log", "------> Switch _dimmable_switch: %s _dimmable_light: %s _dimmable_blind: %s prev_nValue: %s prev_sValue: %s newValue: %s" %(
_dimmable_switch, _dimmable_light, _dimmable_blind, prev_nValue, prev_sValue, value), NWKID)

if _dimmable_blind:
# Correct for Blinds where we have to display %
if value == "00":
nValue, sValue = 0, "0"
elif value == "01" and sValue == "100":
nValue, sValue = 1, "100"
else:
nValue = 2
nValue = _dimmable_blind
else:
nValue = 0 if int(value) == 0 else 1
sValue = prev_sValue

UpdateDevice_v2(self, Devices, DeviceUnit, nValue, sValue, BatteryLevel, SignalLevel)

elif ClusterType == "Switch" and WidgetType == "Alarm":
Expand Down Expand Up @@ -1182,14 +1194,15 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col
WidgetType, value, len(SWITCH_SELECTORS[WidgetType])), NWKID, )

if "WindowCovering" in ClusterType: # 0x0102
_dimmable_blind = is_dimmable_blind(self, Devices, device_id_ieee, DeviceUnit)
if _dimmable_blind is None:
self.log.logging( "Widget", "Debug", "------> %s/%s ClusterType: %s Wrong Widget Type %s" % (
NWKID, Ep, ClusterType, WidgetType), NWKID, )

if WidgetType in ("VenetianInverted", "Venetian", "Vanne", "VanneInverted", "WindowCovering", "Curtain", "CurtainInverted", "Blind"):
_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", "CurtainInverted"):
_value = 100 - _value
self.log.logging("Widget", "Debug", "------> Patching %s/%s Value: %s" % (NWKID, Ep, _value), NWKID)
Expand All @@ -1199,51 +1212,60 @@ def MajDomoDevice(self, Devices, NWKID, Ep, clusterID, value, Attribute_="", Col
elif _value == 100:
nValue = 1
else:
nValue = 17 if switchType in (4, 15) else 2
nValue = _dimmable_blind
self.log.logging("Widget", "Debug", "------> %s %s/%s Value: %s:%s" % (WidgetType, NWKID, Ep, nValue, _value), NWKID)
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", ) ):
# Closed: nValue = 1 and sValue = 100
# partially opened: nValue = 2 and sValue = 1-99
# Open: nValue = 0 and sValue = 0

self.log.logging("Widget", "Debug", "------> LvlControl analogValue: -> %s" % value, NWKID)
_dimmable_switch = is_dimmable_switch(self, Devices, device_id_ieee, DeviceUnit)
_dimmable_light = is_dimmable_light(self, Devices, device_id_ieee, DeviceUnit)
_dimmable_blind = is_dimmable_blind(self, Devices, device_id_ieee, DeviceUnit)

self.log.logging("Widget", "Log", "------> LvlControl _dimmable_switch: %s _dimmable_light: %s _dimmable_blind: %s prev_nValue: %s prev_sValue: %s newValue: %s" %(
_dimmable_switch, _dimmable_light, _dimmable_blind, prev_nValue, prev_sValue, value), NWKID)

if WidgetType in ( "ColorControlRGB", "ColorControlWW", "ColorControlRGBWW", "ColorControlFull", "ColorControl", ):
nValue, sValue = getDimmerLevelOfColor(self, value)
update_domoticz_widget = prev_nValue != 0 or prev_sValue != "Off"

self.log.logging("Widget", "Log", "------> %s prev_nValue: %s prev_sValue: %s newValue: %s nValue: %s sValue: %s update_domoticz_widget: %s" %(
WidgetType, prev_nValue, prev_sValue, value, nValue, sValue, update_domoticz_widget), NWKID)

if update_domoticz_widget:
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, str(sValue), BatteryLevel, SignalLevel, Color_)

elif WidgetType == "LvlControl" or ( WidgetType in ( "BSO-Volet", "Blind", ) ):
normalized_value = normalized_lvl_value(self, Devices, device_id_ieee, DeviceUnit, value)
self.log.logging("Widget", "Debug", "------> LvlControl new sValue: -> %s old nValue/sValue %s:%s" % (
normalized_value, prev_nValue, prev_sValue), NWKID)
update_domoticz_widget = prev_nValue != 0 and (prev_sValue != "Off" and prev_sValue != str(normalized_value))

self.log.logging("Widget", "Debug", "------> LvlControl new sValue: -> %s old nValue/sValue %s:%s update_domoticz_widget: %s" % (
normalized_value, prev_nValue, prev_sValue, update_domoticz_widget), NWKID)

# In case we reach 0% or 100%, we shouldn't switch Off or On, except in the case of Shutter/Blind
if normalized_value == 0 or normalized_value == 100:
# In case we reach 0% or 100%, we shouldn't switch Off or On, except in the case of Shutter/Blind
nValue = 0 if normalized_value == 0 else 1

if switchType:
self.log.logging("Widget", "Debug", "------> LvlControl UpdateDevice: -> %s/%s SwitchType: %s" % (
self.log.logging("Widget", "Log", "------> LvlControl UpdateDevice: -> %s/%s SwitchType: %s" % (
nValue, normalized_value, switchType), NWKID)
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, str(normalized_value), BatteryLevel, SignalLevel)

else:
if prev_nValue == 0 and (prev_sValue == "Off" or prev_sValue == str(normalized_value)):
pass
else:
self.log.logging("Widget", "Debug", "------> LvlControl UpdateDevice: -> %s/%s" % (nValue, normalized_value), NWKID)
if update_domoticz_widget:
self.log.logging("Widget", "Log", "------> LvlControl UpdateDevice: -> %s/%s" % (nValue, normalized_value), NWKID)
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, str(normalized_value), BatteryLevel, SignalLevel)
else:
if prev_nValue == 0 and (prev_sValue == "Off" or prev_sValue == str(normalized_value)):
pass
elif switchType in (13, 14, 15, 16):
self.log.logging("Widget", "Debug", "------> LvlControl UpdateDevice: -> %s/%s SwitchType: %s" % (
2, normalized_value, switchType), NWKID)
UpdateDevice_v2(self, Devices, DeviceUnit, 2, str(normalized_value), BatteryLevel, SignalLevel)
else:
# Just update the Level if Needed
self.log.logging("Widget", "Debug", "------> LvlControl UpdateDevice: -> %s/%s SwitchType: %s" % (
prev_nValue, normalized_value, switchType), NWKID)
UpdateDevice_v2(self, Devices, DeviceUnit, prev_nValue, str(normalized_value), BatteryLevel, SignalLevel)



else:
if update_domoticz_widget:
value_to_update = _dimmable_blind if _dimmable_blind else prev_nValue

elif WidgetType in ( "ColorControlRGB", "ColorControlWW", "ColorControlRGBWW", "ColorControlFull", "ColorControl", ):
if prev_nValue != 0 or prev_sValue != "Off":
nValue, sValue = getDimmerLevelOfColor(self, value)
UpdateDevice_v2(self, Devices, DeviceUnit, nValue, str(sValue), BatteryLevel, SignalLevel, Color_)
self.log.logging("Widget", "Log", "------> LvlControl UpdateDevice: -> %s/%s SwitchType: %s" % (
value_to_update, normalized_value, switchType), NWKID)
UpdateDevice_v2(self, Devices, DeviceUnit, value_to_update, str(normalized_value), BatteryLevel, SignalLevel)

elif WidgetType == "LegrandSelector":
self.log.logging("Widget", "Debug", "------> LegrandSelector : Value -> %s" % value, NWKID)
Expand Down Expand Up @@ -1487,6 +1509,7 @@ def get_dimmer_level_of_color(self, value):

return nValue, sValue


def check_erratic_value(self, NwkId, value_type, value, expected_min, expected_max):
"""
Check if the value is in the range or not. If out of range and disableTrackingValue not set, will check for 5 consecutive errors to log as an error.
Expand Down Expand Up @@ -1524,6 +1547,7 @@ def check_erratic_value(self, NwkId, value_type, value, expected_min, expected_m
value_type, value, expected_min, expected_max, NwkId, consecutive_erratic_value), NwkId)
return True


def check_set_meter_widget( self, Devices, DeviceId, Unit, mode):
# Mode = 0 - From device (default)
# Mode = 1 - Computed
Expand All @@ -1543,7 +1567,6 @@ def check_set_meter_widget( self, Devices, DeviceId, Unit, mode):
domo_update_api(self, Devices, DeviceId, Unit, oldnValue, oldsValue, Options=Options ,)



def retrieve_data_from_current(self, Devices, DeviceID, Unit, _format):
"""
Retrieve data from current.
Expand Down Expand Up @@ -1622,6 +1645,7 @@ def getDimmerLevelOfColor(self, value):

return nValue, sValue


def check_and_update_db_status( self, NWKID):
if (
"Status" in self.ListOfDevices[NWKID]
Expand All @@ -1633,6 +1657,7 @@ def check_and_update_db_status( self, NWKID):
# simply put the device back
self.ListOfDevices[NWKID]["Status"] = "inDB"


def is_PowerNegative_widget( ClusterTypeList):
return any( _widget_type == "ProdMeter" for _, _, _widget_type in ClusterTypeList )

Expand All @@ -1644,7 +1669,8 @@ def calculate_humidity_status(humidity_value):
return 1
else:
return 3



def calculate_baro_forecast(baroValue):

if baroValue < 1000:
Expand Down
46 changes: 45 additions & 1 deletion Modules/domoticzAbstractLayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

DELAY_BETWEEN_TOUCH = 30


def load_list_of_domoticz_widget(self, Devices):
"""Use at plugin start to creat an index of Domoticz Widget. It is also called after a Widget removal and when a new device has been paired.
Expand Down Expand Up @@ -419,4 +420,47 @@ def timeout_widget_api(self, Devices, DeviceId_, Unit_, timeout_value):

def domoticz_log_api( message):

Domoticz.Log( message )
Domoticz.Log( message )

def is_dimmable_switch(self, Devices, DeviceId, Unit):
_switchType, _subType, _type = domo_read_SwitchType_SubType_Type(self, Devices, DeviceId, Unit)
if check_widget(_switchType, _subType, _type) == "Dimmable_Switch":
return find_partially_opened_nValue(_switchType, _subType, _type)
return None


def is_dimmable_light(self, Devices, DeviceId, Unit):
_switchType, _subType, _type = domo_read_SwitchType_SubType_Type(self, Devices, DeviceId, Unit)
if check_widget(_switchType, _subType, _type) == "Dimmable_Light":
return find_partially_opened_nValue(_switchType, _subType, _type)
return None


def is_dimmable_blind(self, Devices, DeviceId, Unit):
_switchType, _subType, _type = domo_read_SwitchType_SubType_Type(self, Devices, DeviceId, Unit)
if check_widget(_switchType, _subType, _type) == "Blind":
return find_partially_opened_nValue(_switchType, _subType, _type)
return None


DIMMABLE_WIDGETS = {
(7, 1, 241): { "Widget": "Dimmable_Light", "Name": "RGBW", "partially_opened_nValue": 15},
(7, 2, 241): { "Widget": "Dimmable_Light", "Name": "RGB", "partially_opened_nValue": 15},
(7, 4, 241): { "Widget": "Dimmable_Light", "Name": "RGBWW", "partially_opened_nValue": 15},
(7, 7, 241): { "Widget": "Dimmable_Light", "Name": "RGBWWZ", "partially_opened_nValue": 15},
(7, 8, 241): { "Widget": "Dimmable_Light", "Name": "WW Switch", "partially_opened_nValue": 15},
(7, 73, 244): { "Widget": "Dimmable_Switch", "Name": "Dimmer", "partially_opened_nValue": 2},
(14, 73, 244): { "Widget": "Blind", "Name": "Venetian Blinds US", "partially_opened_nValue": 17},
(13, 73, 244): { "Widget": "Blind", "Name": "Blind Percentage", "partially_opened_nValue": 2},
(15, 73, 244): { "Widget": "Blind", "Name": "Venetian Blinds EU", "partially_opened_nValue": 17},
(21, 73, 244): { "Widget": "Blind", "Name": "Blinds + Stop", "partially_opened_nValue": 2},
}

def find_partially_opened_nValue(switch_type, sub_type, widget_type):
key = (switch_type, sub_type, widget_type)
return DIMMABLE_WIDGETS.get(key).get("partially_opened_nValue")


def check_widget(switch_type, sub_type, widget_type):
key = (switch_type, sub_type, widget_type)
return DIMMABLE_WIDGETS.get(key).get("Widget")

0 comments on commit da29697

Please sign in to comment.