MadPatrick / somfy

Tahoma/Conexoon plugin for IO blinds, this plugin require internet connexion and a Somfy account
GNU General Public License v3.0
14 stars 3 forks source link

Somfy Exterior Screens are continious updating when using beta 4.2.20 #56

Closed Rik60 closed 8 months ago

Rik60 commented 9 months ago

I am using 6 Somfy IO devices, 3 RollerShutter, 2 ExtoriorScreen and 1 Awning. In master version the Awning was not updating, see issue #53 and #55. Those issues where solved in Beta 4.2.20. But the modified plugin.py created another issue, the continious updating of the exterior screens. The problem is that the awning has 2 trigger events (OpenCloseState and DeploymentState), the exterior screens 3 (OpenCloseState, DeploymentState and ClosureState). I tried to modify the plugin.py but i have too little Python program skills to fix this problem. The problem is that the status of the exterior screens is constantly changing by the triggers OpenCloseState and DeplomentState. A solution could by that the DeploymentState is only triggert by the Awning, an extra If statement between the lines 383-386. I don't know how to insert that's the Awning who is triggering. I am running Domoticz 2023.2 32 bit, OS is Bullseye 32 bit on a PI3B

Rik60 commented 9 months ago

Problems are solved. I have modified 2 files, utils.py and plugin.py. In utils.py i modified the funcion: filter_states(data) by adding a variable 'deviceClass'. This variable is used to put the deviceclass (device["definition"]["uiClass"] into the statelist. This is used to select the right device in plugin.py. Modified utils.py:

`def filter_states(Data): """filters relevant state data from a device setup API reply""" logging.debug("start filter states") filtered_states = list() deviceURL = "" deviceClass = ""

for device in Data:
    stateList = list()
    deviceURL = device["deviceURL"]
    deviceClass = device["definition"]["uiClass"]
    if not "states" in device:
        continue
    for state in device["states"]:
        if state["name"] in stateSet:
            stateList.append(state)
    if len(stateList)>0:
        stateToAdd = {"deviceURL":deviceURL, 
            "deviceStates":stateList,
            "deviceClass":deviceClass,
            "name":"DeviceState"}
        filtered_states.append(stateToAdd)
    logging.debug("Device state: "+str(filtered_states))
return filtered_states`

In plugin.py i have modified the function: update_devices_status(self, Updated_devices) by adding a variable: deviceClassTrig = dataset["deviceClass"] .

Modified plugin.py, part of function: update_devices(self, `Updated_devices:

` def update_devices_status(self, Updated_devices): logging.debug("updating device status self.tahoma.startup = "+str(self.tahoma.startup)+" on num datasets: "+str(len(Updated_devices))) logging.debug("updating device status on data: "+str(Updated_devices)) if self.local: eventList = utils.filter_events(Updated_devices)

    else:
        eventList = Updated_devices
    num_updates = 0
    logging.debug("checking device updates for "+str(len(eventList))+" filtered events")
    for dataset in eventList:
        logging.debug("checking dataset: "+str(dataset))
        if dataset["deviceURL"] not in Devices:
            Domoticz.Error("device not found for URL: "+str(dataset["deviceURL"]))
            logging.error("device not found for URL: "+str(dataset["deviceURL"])+" while updating states")
            continue #no deviceURL found that matches to domoticz Devices, skip to next dataset
        if (dataset["deviceURL"].startswith("io://")):
            dev = dataset["deviceURL"]
            deviceClassTrig = dataset["deviceClass"]               
            level = 0
            status_num = 0
            status = None
            nValue = 0
            sValue = "0"

            states = dataset["deviceStates"]
            if not (dataset["name"] == "DeviceStateChangedEvent" or dataset["name"] == "DeviceState"):
                logging.debug("update_devices_status: dataset['name'] != DeviceStateChangedEvent: "+str(dataset["name"])+": breaking out")
                continue #dataset does not contain correct event, skip to next dataset

            for state in states:
                status_num = 0
                lumstatus_l = False

                if ((state["name"] == "core:ClosureState") or (state["name"] == "core:DeploymentState")):
                    if (deviceClassTrig == "Awning"):
                        level = int(state["value"]) #Don't invert open/close percentage for an Awning
                        status_num = 1
                    else:
                        level = int(state["value"])
                        level = 100 - level #invert open/close percentage
                        status_num = 1

                if ((state["name"] == "core:SlateOrientationState")):
                    level = int(state["value"])
                    #level = 100 - level 
                    status_num = 2`

These changes works for me.

MadPatrick commented 8 months ago

added to beta version. Thanks for the help