diff --git a/.gitignore b/.gitignore index 75ec3f0..806e4a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.vscode/* \ No newline at end of file +.vscode/* +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 08d0a36..2bd0b27 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,26 @@ 1. Enter your `username` and `password` in the appropriate fields. - use the country code for the phone number e.g. `+91XXXXXX` 2. Submit the form. + +## Caveats +HomeAssistant does not provide separate functionality to horizontal and vertical swings so they have been clubbed together to function correctly but with reduced observation as follows: + +The Vertical states are preferred over horizontal states unless the vertical state is set to V0(auto). +You can take a look at the following table to understand the outcome. +| Mode set in UI | Mode set in AC | Mode displayed on UI when vertical swing is on auto mode | Mode displayed on UI when vertical swing is NOT on auto mode | +|---|---|---|---| +| V0 | V0 | V0 | V0 | +| V1 | V1 | V1 | V1 | +| V2 | V2 | V2 | V2 | +| V3 | V3 | V3 | V3 | +| V4 | V4 | V4 | V4 | +| V5 | V5 | V5 | V5 | +| H0 | H0 | H0 | Vx | +| H1 | H1 | H1 | Vx | +| H2 | H2 | H2 | Vx | +| H3 | H3 | H3 | Vx | +| H4 | H4 | H4 | Vx | +| H5 | H5 | H5 | Vx | + +Here `Vx` is the vertical swing mode set before and x can be either of 1, 2, 3, 4, 5. +Note: Even with `Vx` being displayed on the UI the AC would still be set to proper Horizontal swing mode so you can use your automation to control the horizontal swing mode but might not be able to watch for mode changes in horizontal mode. \ No newline at end of file diff --git a/custom_components/miraie/climate.py b/custom_components/miraie/climate.py index f34c9fa..1fa502e 100644 --- a/custom_components/miraie/climate.py +++ b/custom_components/miraie/climate.py @@ -9,6 +9,7 @@ FanMode, SwingMode, PresetMode, + ConvertiMode, ) from homeassistant.components.climate import ( @@ -35,12 +36,26 @@ from .const import ( DOMAIN, - SWING_ON, - SWING_ONE, - SWING_TWO, - SWING_THREE, - SWING_FOUR, - SWING_FIVE, + V0, + V1, + V2, + V3, + V4, + V5, + H0, + H1, + H2, + H3, + H4, + H5, + PRESET_CONVERTI_C110, + PRESET_CONVERTI_C100, + PRESET_CONVERTI_C90, + PRESET_CONVERTI_C80, + PRESET_CONVERTI_C70, + PRESET_CONVERTI_C55, + PRESET_CONVERTI_C40, + PRESET_CONVERTI_C0, ) async def async_setup_entry( @@ -67,7 +82,7 @@ def __init__(self, device: MirAIeDevice) -> None: HVACMode.DRY, HVACMode.FAN_ONLY, ] - self._attr_preset_modes = [PRESET_NONE, PRESET_ECO, PRESET_BOOST] + self._attr_preset_modes = [PRESET_NONE, PRESET_ECO, PRESET_BOOST, PRESET_CONVERTI_C110, PRESET_CONVERTI_C100, PRESET_CONVERTI_C90, PRESET_CONVERTI_C80, PRESET_CONVERTI_C70, PRESET_CONVERTI_C55, PRESET_CONVERTI_C40, PRESET_CONVERTI_C0] self._attr_fan_mode = FAN_OFF self._attr_fan_modes = [ FAN_AUTO, @@ -76,7 +91,7 @@ def __init__(self, device: MirAIeDevice) -> None: FAN_HIGH, FAN_OFF, ] - self._attr_swing_modes = [SWING_ON, SWING_ONE, SWING_TWO, SWING_THREE, SWING_FOUR, SWING_FIVE] + self._attr_swing_modes = [V0, V1, V2, V3, V4, V5, H0, H1, H2, H3, H4, H5] self._attr_max_temp = 30.0 self._attr_min_temp = 16.0 self._attr_target_temperature_step = 1 @@ -98,6 +113,11 @@ def __init__(self, device: MirAIeDevice) -> None: def name(self) -> str: """Return the display name of this light.""" return self.device.friendly_name + + @property + def translation_key(self) -> str: + """Return the translation key.""" + return DOMAIN @property def icon(self) -> str | None: @@ -148,7 +168,9 @@ def target_temperature(self) -> float | None: @property def preset_mode(self) -> str | None: - return self.device.status.preset_mode.value + if self.device.status.converti_mode == ConvertiMode.OFF: + return self.device.status.preset_mode.value + return f"cv {self.device.status.converti_mode.value}" @property def fan_mode(self) -> str | None: @@ -163,20 +185,36 @@ def fan_mode(self) -> str | None: @property def swing_mode(self) -> str | None: - mode = self.device.status.swing_mode.value + mode = self.device.status.v_swing_mode.value if mode == 1: - return SWING_ONE + return V1 + elif mode == 2: + return V2 + elif mode == 3: + return V3 + elif mode == 4: + return V4 + elif mode == 5: + return V5 + + # In case the Vertial swing is set to auto, we can show horizontal swing + mode = self.device.status.h_swing_mode.value + if mode == 0: + # Signifies that both horizontal and vertical swing are enabled. + return H0 + elif mode == 1: + return H1 elif mode == 2: - return SWING_TWO + return H2 elif mode == 3: - return SWING_THREE + return H3 elif mode == 4: - return SWING_FOUR + return H4 elif mode == 5: - return SWING_FIVE + return H5 - return SWING_ON + return V0 async def async_turn_off(self) -> None: await self.async_set_hvac_mode(HVACMode.OFF) @@ -209,21 +247,40 @@ async def async_set_fan_mode(self, fan_mode: str) -> None: async def async_set_swing_mode(self, swing_mode: str) -> None: - if swing_mode == SWING_ONE: - await self.device.set_swing_mode(SwingMode(1)) - elif swing_mode == SWING_TWO: - await self.device.set_swing_mode(SwingMode(2)) - elif swing_mode == SWING_THREE: - await self.device.set_swing_mode(SwingMode(3)) - elif swing_mode == SWING_FOUR: - await self.device.set_swing_mode(SwingMode(4)) - elif swing_mode == SWING_FIVE: - await self.device.set_swing_mode(SwingMode(5)) - else: - await self.device.set_swing_mode(SwingMode(0)) + if swing_mode.startswith('V'): + if swing_mode == V1: + await self.device.set_v_swing_mode(SwingMode(1)) + elif swing_mode == V2: + await self.device.set_v_swing_mode(SwingMode(2)) + elif swing_mode == V3: + await self.device.set_v_swing_mode(SwingMode(3)) + elif swing_mode == V4: + await self.device.set_v_swing_mode(SwingMode(4)) + elif swing_mode == V5: + await self.device.set_v_swing_mode(SwingMode(5)) + else: + await self.device.set_v_swing_mode(SwingMode(0)) + + elif swing_mode.startswith('H'): + if swing_mode == H1: + await self.device.set_h_swing_mode(SwingMode(1)) + elif swing_mode == H2: + await self.device.set_h_swing_mode(SwingMode(2)) + elif swing_mode == H3: + await self.device.set_h_swing_mode(SwingMode(3)) + elif swing_mode == H4: + await self.device.set_h_swing_mode(SwingMode(4)) + elif swing_mode == H5: + await self.device.set_h_swing_mode(SwingMode(5)) + else: + await self.device.set_h_swing_mode(SwingMode(0)) async def async_set_preset_mode(self, preset_mode: str) -> None: - await self.device.set_preset_mode(PresetMode(preset_mode)) + if preset_mode.startswith("cv"): + preset_mode = int(preset_mode.split(" ")[1]) + await self.device.set_converti_mode(ConvertiMode(preset_mode)) + else: + await self.device.set_preset_mode(PresetMode(preset_mode)) async def async_added_to_hass(self) -> None: """Run when this Entity has been added to HA.""" diff --git a/custom_components/miraie/const.py b/custom_components/miraie/const.py index b467e90..42c84f3 100644 --- a/custom_components/miraie/const.py +++ b/custom_components/miraie/const.py @@ -3,9 +3,26 @@ DOMAIN = "miraie" # Possible swing state -SWING_ON = "0" -SWING_ONE = "1" -SWING_TWO = "2" -SWING_THREE = "3" -SWING_FOUR = "4" -SWING_FIVE = "5" \ No newline at end of file +H0 = "H0" +H1 = "H1" +H2 = "H2" +H3 = "H3" +H4 = "H4" +H5 = "H5" + +V0 = "V0" +V1 = "V1" +V2 = "V2" +V3 = "V3" +V4 = "V4" +V5 = "V5" + +# Preset for Converti +PRESET_CONVERTI_C110 = "cv 110" +PRESET_CONVERTI_C100 = "cv 100" +PRESET_CONVERTI_C90 = "cv 90" +PRESET_CONVERTI_C80 = "cv 80" +PRESET_CONVERTI_C70 = "cv 70" +PRESET_CONVERTI_C55 = "cv 55" +PRESET_CONVERTI_C40 = "cv 40" +PRESET_CONVERTI_C0 = "cv 0" \ No newline at end of file diff --git a/custom_components/miraie/icons.json b/custom_components/miraie/icons.json new file mode 100644 index 0000000..51daedd --- /dev/null +++ b/custom_components/miraie/icons.json @@ -0,0 +1,39 @@ +{ + "entity": { + "climate": { + "miraie": { + "state_attributes": { + "swing_mode": { + "state": { + "V0": "mdi:swap-vertical", + "V1": "mdi:arrow-up-thin", + "V2": "mdi:format-vertical-align-top", + "V3": "mdi:format-vertical-align-center", + "V4": "mdi:format-vertical-align-bottom", + "V5": "mdi:arrow-down-thin", + "H0": "mdi:swap-horizontal", + "H1": "mdi:format-horizontal-align-center", + "H2": "mdi:arrow-left-thin", + "H3": "mdi:arrow-expand-left", + "H4": "mdi:arrow-expand-right", + "H5": "mdi:arrow-right-thin" + } + }, + "preset_mode": { + "state": { + "none": "mdi:air-conditioner", + "cv 110": "mdi:alpha-h-circle", + "cv 100": "mdi:alpha-f-circle", + "cv 90": "mdi:circle-slice-7", + "cv 80": "mdi:circle-slice-6", + "cv 70": "mdi:circle-slice-5", + "cv 55": "mdi:circle-slice-4", + "cv 40": "mdi:circle-slice-3", + "cv 0": "mdi:circle-outline" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/custom_components/miraie/manifest.json b/custom_components/miraie/manifest.json index 26816ad..a9d3a78 100644 --- a/custom_components/miraie/manifest.json +++ b/custom_components/miraie/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/miraie", "requirements": [ - "miraie-ac==1.0.3", + "miraie-ac==1.0.4", "asyncio>=3.4.3", "aiomqtt>=2.0.1" ], @@ -16,5 +16,5 @@ "@Kir4Kun" ], "iot_class": "cloud_push", - "version": "1.0.3" + "version": "1.0.4" }