Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

climate entity for Sonoff TRVZB #1569

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions custom_components/sonoff/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,120 @@ async def async_set_temperature(
params["targetTemp"] = temperature

await self.ewelink.send(self.device, params)


class XThermostatTRVZB(XEntity, ClimateEntity):
params = {"switch", "curTargetTemp", "manTargetTemp", "autoTargetTemp", "ecoTargetTemp", "temperature", "workMode", "workState"}

# @bwp91 https://github.com/AlexxIT/SonoffLAN/issues/358
_attr_hvac_modes = [HVACMode.OFF, HVACMode.HEAT, HVACMode.AUTO]
_attr_max_temp = 45
_attr_min_temp = 5
_attr_preset_modes = ["Manual", "Off", "Auto"]
# _attr_preset_mode = "manual"
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_target_temperature_step = 0.5

# https://developers.home-assistant.io/blog/2024/01/24/climate-climateentityfeatures-expanded
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.PRESET_MODE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF
)
_enable_turn_on_off_backwards_compatibility = False
else:
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
)

def TargetTempNameByMode(self):
wm = self.preset_modes.index(self._attr_preset_mode)

if wm==0:
return "manTargetTemp"
elif wm==1:
return "ecoTargetTemp"
elif wm==2:
return "autoTargetTemp"

return "none"

def set_state(self, params: dict):
cache = self.device["params"]
if cache != params:
cache.update(params)

#if cache["switch"] == "on":
# workState: 1=heating, 2=auto
# self._attr_hvac_mode = self.hvac_modes[int(cache["workState"])]
#else:
# self._attr_hvac_mode = HVACMode.OFF

if "workMode" in cache:
wm = int(cache["workMode"])
wm_to_hvac_mode = [HVACMode.HEAT, HVACMode.OFF, HVACMode.AUTO]
if wm in [0,1,2]:
self._attr_hvac_mode = wm_to_hvac_mode[wm]

self._attr_preset_mode = self.preset_modes[wm]

if "curTargetTemp" in cache:
self._attr_target_temperature = cache["curTargetTemp"]*0.1

if "temperature" in cache:
self._attr_current_temperature = cache["temperature"]*0.1

async def async_set_hvac_mode(self, hvac_mode: str) -> None:
i = self.hvac_modes.index(hvac_mode)

#print(hvac_mode, i)
# hvac = (off , heat, auto)
# workMode = ("manual", "off", "auto")
hvac_to_wm = [1, 0, 2]
if i in [0,1,2]:
# convert hvac to work mode
wm = hvac_to_wm[i]
else:
# off
wm = 1

params = {}
params["workMode"]=str(wm)

await self.ewelink.send_cloud(self.device, params)

async def async_set_preset_mode(self, preset_mode: str) -> None:
params = {}
wm = self.preset_modes.index(preset_mode)
params["workMode"]=str(wm)

#print(params)

await self.ewelink.send_cloud(self.device, params)

async def async_set_temperature(
self,
temperature: float = None,
hvac_mode: str = None,
preset_mode: str = None,
**kwargs
) -> None:
if hvac_mode is None:
params = {}
elif hvac_mode is HVACMode.OFF:
params = {"switch": "off"}
else:
i = self.hvac_modes.index(hvac_mode)
params = {"switch": "on", "workState": i}

if preset_mode is not None:
params["workMode"] = self.preset_modes.index(preset_mode)

if temperature is not None:
TargetTemp = self.TargetTempNameByMode()
params[TargetTemp] = temperature*10
print(TargetTemp)

await self.ewelink.send(self.device, params)
25 changes: 21 additions & 4 deletions custom_components/sonoff/core/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
XZigbeeMotion,
)
from ..button import XT5Button
from ..climate import XClimateNS, XClimateTH, XThermostat
from ..climate import XClimateNS, XClimateTH, XThermostat, XThermostatTRVZB
from ..core.entity import XEntity
from ..cover import XCover, XCover91, XCoverDualR3, XZigbeeCover
from ..fan import XDiffuserFan, XFan, XFanDualR3, XToggleFan
Expand Down Expand Up @@ -64,9 +64,11 @@
XTemperatureTH,
XUnknown,
XWiFiDoorBattery,
XHexVoltageTRVZB,
)
from ..switch import (
XBoolSwitch,
XBoolSwitchTRVZB,
XDetach,
XSwitch,
XSwitchPOWR3,
Expand Down Expand Up @@ -453,6 +455,7 @@ def spec(cls, base: str = None, enabled: bool = None, **kwargs) -> type:
], # https://github.com/AlexxIT/SonoffLAN/issues/1166
7016: [XHumanSensor, XLightSensor, XSensitivity, ZRSSI], # SNZB-06P
7017: [
XThermostatTRVZB,
spec(XSensor, param="workMode", uid="work_mode"),
spec(XSensor, param="workState", uid="work_state"),
spec(XSensor, param="temperature", multiply=0.1),
Expand Down Expand Up @@ -480,9 +483,23 @@ def spec(cls, base: str = None, enabled: bool = None, **kwargs) -> type:
multiply=0.1,
uid="eco_target_temperature",
),
spec(XBoolSwitch, param="childLock", uid="child_lock"),
spec(XBoolSwitch, param="windowSwitch", uid="window_switch"),
XSwitch,
spec(
XSensor,
param="tempCorrection",
multiply=0.1,
uid="temperature_correction",
),
spec(XBoolSwitchTRVZB, param="childLock", uid="child_lock"),
spec(XBoolSwitchTRVZB, param="windowSwitch", uid="window_switch"),
spec(XHexVoltageTRVZB, param="runVoltage", uid="run_voltage"),
spec(XHexVoltageTRVZB, param="limitVoltage", uid="limit_voltage"),
# spec(XSensor, param="mon"),
# spec(XSensor, param="tues"),
# spec(XSensor, param="wed"),
# spec(XSensor, param="thur"),
# spec(XSensor, param="fri"),
# spec(XSensor, param="sat"),
# spec(XSensor, param="sun"),
Battery,
ZRSSI,
],
Expand Down
15 changes: 15 additions & 0 deletions custom_components/sonoff/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,18 @@ def internal_update(self, params: dict = None):

if self.hass:
self._async_write_ha_state()


class XHexVoltageTRVZB(XSensor):
_attr_device_class = SensorDeviceClass.VOLTAGE
_attr_native_unit_of_measurement = UnitOfElectricPotential.VOLT

def set_state(self, params: dict = None, value: float = None):
try:
value = params[self.param]
value = int(value, 16) * 0.001

if value != 0:
XSensor.set_state(self, value=value)
except Exception:
XSensor.set_state(self)
13 changes: 13 additions & 0 deletions custom_components/sonoff/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,16 @@ async def async_turn_on(self, *args, **kwargs):

async def async_turn_off(self):
await self.ewelink.send(self.device, {"switch": False})


class XBoolSwitchTRVZB(XEntity, SwitchEntity):
params = {}

def set_state(self, params: dict):
self._attr_is_on = params[self.param]

async def async_turn_on(self, *args, **kwargs):
await self.ewelink.send(self.device, {self.param: True})

async def async_turn_off(self):
await self.ewelink.send(self.device, {self.param: False})