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

Add support for zhimi.heater.za2 #1301

Merged
merged 8 commits into from
Jan 22, 2022
Merged
Changes from 5 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
87 changes: 63 additions & 24 deletions miio/heater_miot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import enum
import logging
from typing import Any, Dict
from typing import Any, Dict, Union

import click

Expand All @@ -9,32 +9,66 @@
from .miot_device import DeviceStatus, MiotDevice

_LOGGER = logging.getLogger(__name__)
_MAPPING = {
# Source https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:heater:0000A01A:zhimi-mc2:1
# Heater (siid=2)
"power": {"siid": 2, "piid": 1},
"target_temperature": {"siid": 2, "piid": 5},
# Countdown (siid=3)
"countdown_time": {"siid": 3, "piid": 1},
# Environment (siid=4)
"temperature": {"siid": 4, "piid": 7},
# Physical Control Locked (siid=6)
"child_lock": {"siid": 5, "piid": 1},
# Alarm (siid=6)
"buzzer": {"siid": 6, "piid": 1},
# Indicator light (siid=7)
"led_brightness": {"siid": 7, "piid": 3},
_MAPPINGS = {
'zhimi.heater.mc2': {
# Source https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:heater:0000A01A:zhimi-mc2:1
# Heater (siid=2)
"power": {"siid": 2, "piid": 1},
"target_temperature": {"siid": 2, "piid": 5},
# Countdown (siid=3)
"countdown_time": {"siid": 3, "piid": 1},
# Environment (siid=4)
"temperature": {"siid": 4, "piid": 7},
# Physical Control Locked (siid=5)
"child_lock": {"siid": 5, "piid": 1},
# Alarm (siid=6)
"buzzer": {"siid": 6, "piid": 1},
# Indicator light (siid=7)
"led_brightness": {"siid": 7, "piid": 3},
},
'zhimi.heater.za2': {
# Source https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:heater:0000A01A:zhimi-za2:1
# Heater (siid=2)
"power": {"siid": 2, "piid": 2},
"target_temperature": {"siid": 2, "piid": 6},
# Countdown (siid=4)
"countdown_time": {"siid": 4, "piid": 1},
# Environment (siid=5)
"temperature": {"siid": 5, "piid": 8},
"relative_humidity": {"siid": 5, "piid": 7},
# Physical Control Locked (siid=7)
"child_lock": {"siid": 7, "piid": 1},
# Alarm (siid=3)
"buzzer": {"siid": 3, "piid": 1},
# Indicator light (siid=7)
"led_brightness": {"siid": 6, "piid": 1},
}
}

HEATER_PROPERTIES = {
"temperature_range": (18, 28),
"delay_off_range": (0, 12 * 3600),
'zhimi.heater.mc2': {
"temperature_range": (18, 28),
"delay_off_range": (0, 12 * 3600),
},
'zhimi.heater.za2': {
"temperature_range": (16, 28),
"delay_off_range": (0, 8 * 3600),
}
}


class LedBrightness(enum.Enum):
On = 0
Off = 1
"""Xiaomi Smart Space Heater S (zhimi.heater.mc2):
0 = On, 1 = Off

Xiaomi Smart Space Heater 1S (zhimi.heater.za2):
0 = On (Bright), 1 = On (Dim), 2 = Off
rytilahti marked this conversation as resolved.
Show resolved Hide resolved

For coverage, we use Bright/Dim/Off for both models.
"""
Bright = 0
Dim = 1
Off = 2


class HeaterMiotException(DeviceException):
Expand Down Expand Up @@ -85,6 +119,11 @@ def temperature(self) -> float:
"""Current temperature."""
return self.data["temperature"]

@property
def relative_humidity(self) -> Union[int, None]:
rytilahti marked this conversation as resolved.
Show resolved Hide resolved
"""Current relative humidity."""
return self.data.get("relative_humidity")

@property
def child_lock(self) -> bool:
"""True if child lock is on, False otherwise."""
Expand All @@ -102,9 +141,9 @@ def led_brightness(self) -> LedBrightness:


class HeaterMiot(MiotDevice):
"""Main class representing the Xiaomi Smart Space Heater S (zhimi.heater.mc2)."""
"""Main class representing the Xiaomi Smart Space Heater S (zhimi.heater.mc2) & 1S (zhimi.heater.za2)."""

mapping = _MAPPING
_mappings = _MAPPINGS

@command(
default_output=format_output(
Expand Down Expand Up @@ -146,7 +185,7 @@ def off(self):
)
def set_target_temperature(self, target_temperature: int):
"""Set target_temperature ."""
min_temp, max_temp = HEATER_PROPERTIES["temperature_range"]
min_temp, max_temp = HEATER_PROPERTIES[self.model]["temperature_range"]
if target_temperature < min_temp or target_temperature > max_temp:
raise HeaterMiotException(
"Invalid temperature: %s. Must be between %s and %s."
Expand Down Expand Up @@ -190,7 +229,7 @@ def set_led_brightness(self, brightness: LedBrightness):
)
def set_delay_off(self, seconds: int):
"""Set delay off seconds."""
min_delay, max_delay = HEATER_PROPERTIES["delay_off_range"]
min_delay, max_delay = HEATER_PROPERTIES[self.model]["delay_off_range"]
if seconds < min_delay or seconds > max_delay:
raise HeaterMiotException(
"Invalid scheduled turn off: %s. Must be between %s and %s"
Expand Down