From 07240a16931a1153576615cadeade250c78f10f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20JUMELLE?= Date: Mon, 9 Dec 2024 22:40:40 +0100 Subject: [PATCH] Change the way the devices are organized in the plugin --- plugin.py | 160 +++++++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 81 deletions(-) diff --git a/plugin.py b/plugin.py index 92e91bf..edf6e6b 100755 --- a/plugin.py +++ b/plugin.py @@ -31,6 +31,7 @@ import math import time from datetime import datetime +from enum import IntEnum import requests import DomoticzEx as Domoticz # type: ignore @@ -69,6 +70,10 @@ HEATZY_MODE_VALUE_INV = {v: k for k, v in HEATZY_MODE_VALUE.items()} DEFAULT_POOLING = 60 +class HeatzyUnit(IntEnum): + CONTROL = 1 + SELECTOR = 2 + class BasePlugin: """Class for plugin""" debug = False @@ -114,20 +119,19 @@ class BasePlugin: self.did = self.get_heatzy_devices() # Create the child devices if these do not exist yet - if "Control" not in Devices: - for did in self.did: - unit = self.did[did]["unit"] - Domoticz.Unit(Name=f"Heatzy {did} - Control", DeviceID="Control", Unit=unit, TypeName="Switch", Image=9, Used=1).Create() + for deviceid in self.did: + if deviceid not in Devices: + alias = self.did[deviceid]["alias"] + #Control + Domoticz.Unit(Name=f"Heatzy {alias} - Control", DeviceID=deviceid, Unit=HeatzyUnit.CONTROL, TypeName="Switch", Image=9, Used=1).Create() - if "Mode" not in Devices: - options = {"LevelActions": "||", - "LevelNames": HEATZY_MODE_NAME['OFF'] + "|" + HEATZY_MODE_NAME['FROSTFREE'] + "|" + HEATZY_MODE_NAME['ECONOMY'] + "|" + HEATZY_MODE_NAME['NORMAL'], - "LevelOffHidden": "false", #Bug with off mode... - #"LevelOffHidden": "true",t - "SelectorStyle": "0"} - for did in self.did: - unit = self.did[did]["unit"] - Domoticz.Unit(Name=f"Heatzy {did} - Mode", DeviceID="Mode", Unit=unit, + #Selector switch + options = {"LevelActions": "||", + "LevelNames": HEATZY_MODE_NAME['OFF'] + "|" + HEATZY_MODE_NAME['FROSTFREE'] + "|" + HEATZY_MODE_NAME['ECONOMY'] + "|" + HEATZY_MODE_NAME['NORMAL'], + "LevelOffHidden": "false", #Bug with off mode... + #"LevelOffHidden": "true",t + "SelectorStyle": "0"} + Domoticz.Unit(Name=f"Heatzy {alias} - Mode", DeviceID=deviceid, Unit=HeatzyUnit.SELECTOR, TypeName="Selector Switch", Switchtype=18, Image=15, Options=options, Used=1).Create() @@ -141,10 +145,10 @@ class BasePlugin: def on_command(self, DeviceID, Unit, Command, Level, Color): #pylint: disable=unused-argument """Send a command""" - if DeviceID == "Control": - self.on_off(Unit, Command) - elif DeviceID == "Mode": - self.set_mode(Unit, Level) + if Unit == HeatzyUnit.CONTROL: + self.on_off(DeviceID, Command) + elif Unit == HeatzyUnit.SELECTOR: + self.set_mode(DeviceID, Level) def on_heartbeat(self): """Time to heartbeat :)""" @@ -157,7 +161,7 @@ class BasePlugin: #Force refresh token/did Domoticz.Status("Force refresh token and device id.") self.token = "" - self.did = "" + self.did = {} return self.get_mode() @@ -212,7 +216,7 @@ class BasePlugin: Domoticz.Error(f"Cannot get Heatzy Token: {error_message} ({error_code})\n{response}") self.token = "" self.token_expire_at = 0 - self.did = "" + self.did = {} #Decrease retry self.retry = self.retry - 1 @@ -248,10 +252,11 @@ class BasePlugin: devices = response['devices'] unit = 1 for device in devices: - if "dev_alias" in device and "did" in device: + if "dev_alias" in device and "did" in device and "product_key" in device: + product_key = device['product_key'] alias = device['dev_alias'] did = device['did'] - self.did[alias] = {"did":did, "unit":unit, "last_update":0} + self.did[product_key] = {"did":did, "alias":alias, "last_update":0} Domoticz.Status(f"Devide Id from Heatzy API: {alias} - {did}") unit = unit + 1 @@ -263,7 +268,7 @@ class BasePlugin: response = "" self.token, self.token_expire_at = self.get_token(Parameters["Username"], Parameters["Password"]) - self.did = self.get_heatzy_devices() + #self.did = self.get_heatzy_devices() #Not really needed if self.retry<0: return "" @@ -274,10 +279,10 @@ class BasePlugin: 'X-Gizwits-Application-Id': 'c70a66ff039d41b4a220e198b0fcc8b3', } - for device_name in self.did: - device = self.did[device_name] + for deviceid in self.did: + device = self.did[deviceid] did = device["did"] - unit = device["unit"] + alias = device["alias"] url = f"https://euapi.gizwits.com/app/devdata/{did}/latest" try: @@ -308,39 +313,39 @@ class BasePlugin: if 'attr' in response and 'mode' in response['attr']: mode = HEATZY_MODE[response['attr']['mode']] - Domoticz.Debug(f"Current Heatzy Mode: {HEATZY_MODE_NAME[mode]} ({self.get_name(unit)})") + Domoticz.Debug(f"Current Heatzy Mode: {HEATZY_MODE_NAME[mode]} ({alias})") #Reset retry counter self.retry = self.max_retry - if Devices["Mode"].Units[unit].nValue != HEATZY_MODE_VALUE[mode]: - Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode]} ({self.get_name(unit)})") - Devices["Mode"].Units[unit].nValue = HEATZY_MODE_VALUE[mode] - Devices["Mode"].Units[unit].sValue = str(HEATZY_MODE_VALUE[mode]) - Devices["Mode"].Units[unit].Update() + if Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue != HEATZY_MODE_VALUE[mode]: + Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode]} ({alias})") + Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue = HEATZY_MODE_VALUE[mode] + Devices[deviceid].Units[HeatzyUnit.SELECTOR].sValue = str(HEATZY_MODE_VALUE[mode]) + Devices[deviceid].Units[HeatzyUnit.SELECTOR].Update() if not self.bug: - if mode == 'OFF' and Devices["Control"].Units[unit].nValue != 0: - Devices["Control"].Units[unit].nValue = 0 - Devices["Control"].Units[unit].sValue = "Off" - elif mode != 'OFF' and Devices["Control"].Units[unit].nValue == 0: - Devices["Control"].Units[unit].nValue = 1 - Devices["Control"].Units[unit].sValue = "On" + if mode == 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off" + elif mode != 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On" else: - if mode in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue != 0: - Devices["Control"].Units[unit].nValue = 0 - Devices["Control"].Units[unit].sValue = "Off" - elif mode not in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue == 0: - Devices["Control"].Units[unit].nValue = 1 - Devices["Control"].Units[unit].sValue = "On" - Devices["Control"].Units[unit].Update() + if mode in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off" + elif mode not in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On" + Devices[deviceid].Units[HeatzyUnit.CONTROL].Update() else: #Decrease retry self.retry = self.retry - 1 error_code = "Unknown" if 'error_code' not in response else response['error_code'] error_message = "Unknown" if 'error_message' not in response else response['error_message'] - Domoticz.Error(f"Cannot get Heatzy Mode: {error_message} ({error_code})\n{response}\nToken: {self.token}\nDeviceId: {self.did}") + Domoticz.Error(f"Cannot get Heatzy Mode: {error_message} ({error_code})\n{response}\nToken: {self.token}\nDeviceId: {did}") if error_code == 9004: #Invalid token self.token = "" @@ -348,17 +353,17 @@ class BasePlugin: elif 'attr' in response and len(response["attr"]) == 0: #attr is empty... Domoticz.Status("We force a setMode to try to get the correct mode at the next try...") - self.set_mode(unit, HEATZY_MODE_VALUE['FROSTFREE']) + self.set_mode(deviceid, HEATZY_MODE_VALUE['FROSTFREE']) return "" # If mode = OFF and bug, then mode = FROSTFREE if self.bug and mode == 'OFF': Domoticz.Log(f"Switch to FROSTFREE because of the OFF bug...({device})") - self.set_mode(unit, HEATZY_MODE_VALUE['FROSTFREE']) + self.set_mode(deviceid, HEATZY_MODE_VALUE['FROSTFREE']) - def set_mode(self, unit, mode): + def set_mode(self, deviceid, mode): "Set the device mode using the Heatzy API" - if Devices["Mode"].Units[unit].nValue != mode: + if Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue != mode: mode_str = { HEATZY_MODE_VALUE['NORMAL']: 0, #'[1,1,0]', HEATZY_MODE_VALUE['ECONOMY']: 1, #'[1,1,1]', @@ -373,8 +378,7 @@ class BasePlugin: } #data = '{"raw": '+mode_str[mode]+'}' data = '{"attrs": {"mode":' + str(mode_str[mode]) + '}}' - device_name = self.get_name(unit) - did = self.did[device_name]["did"] + did = self.did[deviceid]["did"] url = f"https://euapi.gizwits.com/app/control/{did}" try: response = requests.post(url, headers=headers, data=data, timeout=3).json() @@ -389,29 +393,30 @@ class BasePlugin: if response is not None: mode_str = HEATZY_MODE_VALUE_INV[mode] - Devices["Mode"].Units[unit].nValue = int(mode) - Devices["Mode"].Units[unit].sValue = str(mode) - Devices["Mode"].Units[unit].Update() - Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode_str]} ({self.get_name(unit)})") + Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue = int(mode) + Devices[deviceid].Units[HeatzyUnit.SELECTOR].sValue = str(mode) + Devices[deviceid].Units[HeatzyUnit.SELECTOR].Update() + alias = self.did[deviceid]["alias"] + Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode_str]} ({alias})") if not self.bug: - if mode_str == 'OFF' and Devices["Control"].Units[unit].nValue != 0: - Devices["Control"].Units[unit].nValue = 0 - Devices["Control"].Units[unit].sValue = "Off" - elif mode_str != 'OFF' and Devices["Control"].Units[unit].nValue == 0: - Devices["Control"].Units[unit].nValue = 1 - Devices["Control"].Units[unit].sValue = "On" + if mode_str == 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off" + elif mode_str != 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On" else: - if mode_str in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue != 0: - Devices["Control"].Units[unit].nValue = 0 - Devices["Control"].Units[unit].sValue = "Off" - elif mode_str not in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue == 0: - Devices["Control"].Units[unit].nValue = 1 - Devices["Control"].Units[unit].sValue = "On" - Devices["Control"].Units[unit].Update() + if mode_str in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off" + elif mode_str not in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0: + Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1 + Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On" + Devices[deviceid].Units[HeatzyUnit.CONTROL].Update() else: error_code = "Unknown" if 'error_code' not in response else response['error_code'] error_message = "Unknown" if 'error_message' not in response else response['error_message'] - Domoticz.Error(f"Cannot set Heatzy Mode: {error_message} ({error_code})\n{response}\nToken: {self.token}\nDeviceId: {self.did}") + Domoticz.Error(f"Cannot set Heatzy Mode: {error_message} ({error_code})\n{response}\nToken: {self.token}\nDeviceId: {did}") if error_code == 9004: #Invalid token self.token = "" @@ -421,24 +426,17 @@ class BasePlugin: #Device is correctly running ==> we reset the retry counter self.retry = self.max_retry - def on_off(self, unit, command): + def on_off(self, deviceid, command): """Toggle device on/off""" - if Devices["Control"].Units[unit].sValue != command: + if Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue != command: if command == "On": - self.set_mode(unit, HEATZY_MODE_VALUE['NORMAL']) + self.set_mode(deviceid, HEATZY_MODE_VALUE['NORMAL']) else: if not self.bug: - self.set_mode(unit, HEATZY_MODE_VALUE['OFF']) + self.set_mode(deviceid, HEATZY_MODE_VALUE['OFF']) else: #Because of issue with the equipment (Off do not work...) - self.set_mode(unit, HEATZY_MODE_VALUE['FROSTFREE']) - - def get_name(self, unit): - """get device name form unit""" - for device_name in self.did: - if self.did[device_name]["unit"] == unit: - return device_name - return "Not found" + self.set_mode(deviceid, HEATZY_MODE_VALUE['FROSTFREE']) _plugin = BasePlugin()