Change the way the devices are organized in the plugin
This commit is contained in:
160
plugin.py
160
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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user