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 math
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import DomoticzEx as Domoticz # type: ignore
|
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
|
DEFAULT_POOLING = 60
|
||||||
|
|
||||||
|
class HeatzyUnit(IntEnum):
|
||||||
|
CONTROL = 1
|
||||||
|
SELECTOR = 2
|
||||||
|
|
||||||
class BasePlugin:
|
class BasePlugin:
|
||||||
"""Class for plugin"""
|
"""Class for plugin"""
|
||||||
debug = False
|
debug = False
|
||||||
@@ -114,20 +119,19 @@ class BasePlugin:
|
|||||||
self.did = self.get_heatzy_devices()
|
self.did = self.get_heatzy_devices()
|
||||||
|
|
||||||
# Create the child devices if these do not exist yet
|
# Create the child devices if these do not exist yet
|
||||||
if "Control" not in Devices:
|
for deviceid in self.did:
|
||||||
for did in self.did:
|
if deviceid not in Devices:
|
||||||
unit = self.did[did]["unit"]
|
alias = self.did[deviceid]["alias"]
|
||||||
Domoticz.Unit(Name=f"Heatzy {did} - Control", DeviceID="Control", Unit=unit, TypeName="Switch", Image=9, Used=1).Create()
|
#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:
|
#Selector switch
|
||||||
options = {"LevelActions": "||",
|
options = {"LevelActions": "||",
|
||||||
"LevelNames": HEATZY_MODE_NAME['OFF'] + "|" + HEATZY_MODE_NAME['FROSTFREE'] + "|" + HEATZY_MODE_NAME['ECONOMY'] + "|" + HEATZY_MODE_NAME['NORMAL'],
|
"LevelNames": HEATZY_MODE_NAME['OFF'] + "|" + HEATZY_MODE_NAME['FROSTFREE'] + "|" + HEATZY_MODE_NAME['ECONOMY'] + "|" + HEATZY_MODE_NAME['NORMAL'],
|
||||||
"LevelOffHidden": "false", #Bug with off mode...
|
"LevelOffHidden": "false", #Bug with off mode...
|
||||||
#"LevelOffHidden": "true",t
|
#"LevelOffHidden": "true",t
|
||||||
"SelectorStyle": "0"}
|
"SelectorStyle": "0"}
|
||||||
for did in self.did:
|
Domoticz.Unit(Name=f"Heatzy {alias} - Mode", DeviceID=deviceid, Unit=HeatzyUnit.SELECTOR,
|
||||||
unit = self.did[did]["unit"]
|
|
||||||
Domoticz.Unit(Name=f"Heatzy {did} - Mode", DeviceID="Mode", Unit=unit,
|
|
||||||
TypeName="Selector Switch", Switchtype=18, Image=15,
|
TypeName="Selector Switch", Switchtype=18, Image=15,
|
||||||
Options=options, Used=1).Create()
|
Options=options, Used=1).Create()
|
||||||
|
|
||||||
@@ -141,10 +145,10 @@ class BasePlugin:
|
|||||||
|
|
||||||
def on_command(self, DeviceID, Unit, Command, Level, Color): #pylint: disable=unused-argument
|
def on_command(self, DeviceID, Unit, Command, Level, Color): #pylint: disable=unused-argument
|
||||||
"""Send a command"""
|
"""Send a command"""
|
||||||
if DeviceID == "Control":
|
if Unit == HeatzyUnit.CONTROL:
|
||||||
self.on_off(Unit, Command)
|
self.on_off(DeviceID, Command)
|
||||||
elif DeviceID == "Mode":
|
elif Unit == HeatzyUnit.SELECTOR:
|
||||||
self.set_mode(Unit, Level)
|
self.set_mode(DeviceID, Level)
|
||||||
|
|
||||||
def on_heartbeat(self):
|
def on_heartbeat(self):
|
||||||
"""Time to heartbeat :)"""
|
"""Time to heartbeat :)"""
|
||||||
@@ -157,7 +161,7 @@ class BasePlugin:
|
|||||||
#Force refresh token/did
|
#Force refresh token/did
|
||||||
Domoticz.Status("Force refresh token and device id.")
|
Domoticz.Status("Force refresh token and device id.")
|
||||||
self.token = ""
|
self.token = ""
|
||||||
self.did = ""
|
self.did = {}
|
||||||
return
|
return
|
||||||
|
|
||||||
self.get_mode()
|
self.get_mode()
|
||||||
@@ -212,7 +216,7 @@ class BasePlugin:
|
|||||||
Domoticz.Error(f"Cannot get Heatzy Token: {error_message} ({error_code})\n{response}")
|
Domoticz.Error(f"Cannot get Heatzy Token: {error_message} ({error_code})\n{response}")
|
||||||
self.token = ""
|
self.token = ""
|
||||||
self.token_expire_at = 0
|
self.token_expire_at = 0
|
||||||
self.did = ""
|
self.did = {}
|
||||||
#Decrease retry
|
#Decrease retry
|
||||||
self.retry = self.retry - 1
|
self.retry = self.retry - 1
|
||||||
|
|
||||||
@@ -248,10 +252,11 @@ class BasePlugin:
|
|||||||
devices = response['devices']
|
devices = response['devices']
|
||||||
unit = 1
|
unit = 1
|
||||||
for device in devices:
|
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']
|
alias = device['dev_alias']
|
||||||
did = device['did']
|
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}")
|
Domoticz.Status(f"Devide Id from Heatzy API: {alias} - {did}")
|
||||||
unit = unit + 1
|
unit = unit + 1
|
||||||
|
|
||||||
@@ -263,7 +268,7 @@ class BasePlugin:
|
|||||||
response = ""
|
response = ""
|
||||||
|
|
||||||
self.token, self.token_expire_at = self.get_token(Parameters["Username"], Parameters["Password"])
|
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:
|
if self.retry<0:
|
||||||
return ""
|
return ""
|
||||||
@@ -274,10 +279,10 @@ class BasePlugin:
|
|||||||
'X-Gizwits-Application-Id': 'c70a66ff039d41b4a220e198b0fcc8b3',
|
'X-Gizwits-Application-Id': 'c70a66ff039d41b4a220e198b0fcc8b3',
|
||||||
}
|
}
|
||||||
|
|
||||||
for device_name in self.did:
|
for deviceid in self.did:
|
||||||
device = self.did[device_name]
|
device = self.did[deviceid]
|
||||||
did = device["did"]
|
did = device["did"]
|
||||||
unit = device["unit"]
|
alias = device["alias"]
|
||||||
|
|
||||||
url = f"https://euapi.gizwits.com/app/devdata/{did}/latest"
|
url = f"https://euapi.gizwits.com/app/devdata/{did}/latest"
|
||||||
try:
|
try:
|
||||||
@@ -308,39 +313,39 @@ class BasePlugin:
|
|||||||
|
|
||||||
if 'attr' in response and 'mode' in response['attr']:
|
if 'attr' in response and 'mode' in response['attr']:
|
||||||
mode = HEATZY_MODE[response['attr']['mode']]
|
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
|
#Reset retry counter
|
||||||
self.retry = self.max_retry
|
self.retry = self.max_retry
|
||||||
|
|
||||||
if Devices["Mode"].Units[unit].nValue != HEATZY_MODE_VALUE[mode]:
|
if Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue != HEATZY_MODE_VALUE[mode]:
|
||||||
Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode]} ({self.get_name(unit)})")
|
Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode]} ({alias})")
|
||||||
Devices["Mode"].Units[unit].nValue = HEATZY_MODE_VALUE[mode]
|
Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue = HEATZY_MODE_VALUE[mode]
|
||||||
Devices["Mode"].Units[unit].sValue = str(HEATZY_MODE_VALUE[mode])
|
Devices[deviceid].Units[HeatzyUnit.SELECTOR].sValue = str(HEATZY_MODE_VALUE[mode])
|
||||||
Devices["Mode"].Units[unit].Update()
|
Devices[deviceid].Units[HeatzyUnit.SELECTOR].Update()
|
||||||
|
|
||||||
if not self.bug:
|
if not self.bug:
|
||||||
if mode == 'OFF' and Devices["Control"].Units[unit].nValue != 0:
|
if mode == 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0:
|
||||||
Devices["Control"].Units[unit].nValue = 0
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0
|
||||||
Devices["Control"].Units[unit].sValue = "Off"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off"
|
||||||
elif mode != 'OFF' and Devices["Control"].Units[unit].nValue == 0:
|
elif mode != 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0:
|
||||||
Devices["Control"].Units[unit].nValue = 1
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1
|
||||||
Devices["Control"].Units[unit].sValue = "On"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On"
|
||||||
else:
|
else:
|
||||||
if mode in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue != 0:
|
if mode in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0:
|
||||||
Devices["Control"].Units[unit].nValue = 0
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0
|
||||||
Devices["Control"].Units[unit].sValue = "Off"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off"
|
||||||
elif mode not in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue == 0:
|
elif mode not in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0:
|
||||||
Devices["Control"].Units[unit].nValue = 1
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1
|
||||||
Devices["Control"].Units[unit].sValue = "On"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On"
|
||||||
Devices["Control"].Units[unit].Update()
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].Update()
|
||||||
else:
|
else:
|
||||||
#Decrease retry
|
#Decrease retry
|
||||||
self.retry = self.retry - 1
|
self.retry = self.retry - 1
|
||||||
|
|
||||||
error_code = "Unknown" if 'error_code' not in response else response['error_code']
|
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']
|
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:
|
if error_code == 9004:
|
||||||
#Invalid token
|
#Invalid token
|
||||||
self.token = ""
|
self.token = ""
|
||||||
@@ -348,17 +353,17 @@ class BasePlugin:
|
|||||||
elif 'attr' in response and len(response["attr"]) == 0:
|
elif 'attr' in response and len(response["attr"]) == 0:
|
||||||
#attr is empty...
|
#attr is empty...
|
||||||
Domoticz.Status("We force a setMode to try to get the correct mode at the next try...")
|
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 ""
|
return ""
|
||||||
|
|
||||||
# If mode = OFF and bug, then mode = FROSTFREE
|
# If mode = OFF and bug, then mode = FROSTFREE
|
||||||
if self.bug and mode == 'OFF':
|
if self.bug and mode == 'OFF':
|
||||||
Domoticz.Log(f"Switch to FROSTFREE because of the OFF bug...({device})")
|
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"
|
"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 = {
|
mode_str = {
|
||||||
HEATZY_MODE_VALUE['NORMAL']: 0, #'[1,1,0]',
|
HEATZY_MODE_VALUE['NORMAL']: 0, #'[1,1,0]',
|
||||||
HEATZY_MODE_VALUE['ECONOMY']: 1, #'[1,1,1]',
|
HEATZY_MODE_VALUE['ECONOMY']: 1, #'[1,1,1]',
|
||||||
@@ -373,8 +378,7 @@ class BasePlugin:
|
|||||||
}
|
}
|
||||||
#data = '{"raw": '+mode_str[mode]+'}'
|
#data = '{"raw": '+mode_str[mode]+'}'
|
||||||
data = '{"attrs": {"mode":' + str(mode_str[mode]) + '}}'
|
data = '{"attrs": {"mode":' + str(mode_str[mode]) + '}}'
|
||||||
device_name = self.get_name(unit)
|
did = self.did[deviceid]["did"]
|
||||||
did = self.did[device_name]["did"]
|
|
||||||
url = f"https://euapi.gizwits.com/app/control/{did}"
|
url = f"https://euapi.gizwits.com/app/control/{did}"
|
||||||
try:
|
try:
|
||||||
response = requests.post(url, headers=headers, data=data, timeout=3).json()
|
response = requests.post(url, headers=headers, data=data, timeout=3).json()
|
||||||
@@ -389,29 +393,30 @@ class BasePlugin:
|
|||||||
|
|
||||||
if response is not None:
|
if response is not None:
|
||||||
mode_str = HEATZY_MODE_VALUE_INV[mode]
|
mode_str = HEATZY_MODE_VALUE_INV[mode]
|
||||||
Devices["Mode"].Units[unit].nValue = int(mode)
|
Devices[deviceid].Units[HeatzyUnit.SELECTOR].nValue = int(mode)
|
||||||
Devices["Mode"].Units[unit].sValue = str(mode)
|
Devices[deviceid].Units[HeatzyUnit.SELECTOR].sValue = str(mode)
|
||||||
Devices["Mode"].Units[unit].Update()
|
Devices[deviceid].Units[HeatzyUnit.SELECTOR].Update()
|
||||||
Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode_str]} ({self.get_name(unit)})")
|
alias = self.did[deviceid]["alias"]
|
||||||
|
Domoticz.Status(f"New Heatzy Mode: {HEATZY_MODE_NAME[mode_str]} ({alias})")
|
||||||
if not self.bug:
|
if not self.bug:
|
||||||
if mode_str == 'OFF' and Devices["Control"].Units[unit].nValue != 0:
|
if mode_str == 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0:
|
||||||
Devices["Control"].Units[unit].nValue = 0
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0
|
||||||
Devices["Control"].Units[unit].sValue = "Off"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off"
|
||||||
elif mode_str != 'OFF' and Devices["Control"].Units[unit].nValue == 0:
|
elif mode_str != 'OFF' and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0:
|
||||||
Devices["Control"].Units[unit].nValue = 1
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1
|
||||||
Devices["Control"].Units[unit].sValue = "On"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On"
|
||||||
else:
|
else:
|
||||||
if mode_str in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue != 0:
|
if mode_str in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue != 0:
|
||||||
Devices["Control"].Units[unit].nValue = 0
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 0
|
||||||
Devices["Control"].Units[unit].sValue = "Off"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "Off"
|
||||||
elif mode_str not in ('OFF', 'FROSTFREE') and Devices["Control"].Units[unit].nValue == 0:
|
elif mode_str not in ('OFF', 'FROSTFREE') and Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue == 0:
|
||||||
Devices["Control"].Units[unit].nValue = 1
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].nValue = 1
|
||||||
Devices["Control"].Units[unit].sValue = "On"
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue = "On"
|
||||||
Devices["Control"].Units[unit].Update()
|
Devices[deviceid].Units[HeatzyUnit.CONTROL].Update()
|
||||||
else:
|
else:
|
||||||
error_code = "Unknown" if 'error_code' not in response else response['error_code']
|
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']
|
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:
|
if error_code == 9004:
|
||||||
#Invalid token
|
#Invalid token
|
||||||
self.token = ""
|
self.token = ""
|
||||||
@@ -421,24 +426,17 @@ class BasePlugin:
|
|||||||
#Device is correctly running ==> we reset the retry counter
|
#Device is correctly running ==> we reset the retry counter
|
||||||
self.retry = self.max_retry
|
self.retry = self.max_retry
|
||||||
|
|
||||||
def on_off(self, unit, command):
|
def on_off(self, deviceid, command):
|
||||||
"""Toggle device on/off"""
|
"""Toggle device on/off"""
|
||||||
if Devices["Control"].Units[unit].sValue != command:
|
if Devices[deviceid].Units[HeatzyUnit.CONTROL].sValue != command:
|
||||||
if command == "On":
|
if command == "On":
|
||||||
self.set_mode(unit, HEATZY_MODE_VALUE['NORMAL'])
|
self.set_mode(deviceid, HEATZY_MODE_VALUE['NORMAL'])
|
||||||
else:
|
else:
|
||||||
if not self.bug:
|
if not self.bug:
|
||||||
self.set_mode(unit, HEATZY_MODE_VALUE['OFF'])
|
self.set_mode(deviceid, HEATZY_MODE_VALUE['OFF'])
|
||||||
else:
|
else:
|
||||||
#Because of issue with the equipment (Off do not work...)
|
#Because of issue with the equipment (Off do not work...)
|
||||||
self.set_mode(unit, HEATZY_MODE_VALUE['FROSTFREE'])
|
self.set_mode(deviceid, 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"
|
|
||||||
|
|
||||||
_plugin = BasePlugin()
|
_plugin = BasePlugin()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user