Kaynağa Gözat

Add support for Goldair dehumidifiers

Nik Rolls 6 yıl önce
ebeveyn
işleme
15bbf3f9d1

+ 22 - 28
README.md

@@ -2,10 +2,11 @@ Home Assistant Goldair WiFi Climate component
 =============================================
 =============================================
 
 
 The `goldair_climate` component integrates 
 The `goldair_climate` component integrates 
-[Goldair WiFi-enabled heaters](http://www.goldair.co.nz/product-catalogue/heating/wifi-heaters) into Home Assistant, 
+[Goldair WiFi-enabled heaters](http://www.goldair.co.nz/product-catalogue/heating/wifi-heaters) and
+WiFi-enabled [dehumidifiers](http://www.goldair.co.nz/product-catalogue/heating/dehumidifiers) into Home Assistant,
 enabling control of setting the following parameters via the UI and the following services:
 enabling control of setting the following parameters via the UI and the following services:
 
 
-**Climate**
+**Heaters**
 * **power** (on/off)
 * **power** (on/off)
 * **mode** (Comfort, Eco, Anti-freeze)
 * **mode** (Comfort, Eco, Anti-freeze)
 * **target temperature** (`5`-`35` in Comfort mode, `5`-`21` in Eco mode, in °C)
 * **target temperature** (`5`-`35` in Comfort mode, `5`-`21` in Eco mode, in °C)
@@ -13,8 +14,12 @@ enabling control of setting the following parameters via the UI and the followin
 
 
 Current temperature is also displayed.
 Current temperature is also displayed.
 
 
-**Sensor**
-* **current temperature** (in °C)
+**Demudifiers**
+* **power** (on/off)
+* **mode** (Normal, Low, High, Dry clothes, Air clean)
+* **target humidity** (`30`-`80`%)
+
+Current temperature is displayed, and current humidity is available as a property.
 
 
 **Light**
 **Light**
 * **LED display** (on/off)
 * **LED display** (on/off)
@@ -22,13 +27,15 @@ Current temperature is also displayed.
 **Lock**
 **Lock**
 * **Child lock** (on/off)
 * **Child lock** (on/off)
 
 
+There was previously a sensor option, however this is easily achieved using a
+[template sensor](https://www.home-assistant.io/integrations/template/) and therefore is no longer supported.
+
 ---
 ---
 
 
 ### Warning
 ### Warning
-Please note, this component has currently only been tested with the Goldair GPPH (inverter) range, however theoretically 
-it should also work with GEPH and GPCV devices and any other Goldair heaters based on the Tuya platform.
-
-Work is in progress to support Goldair WiFi dehumidifiers.
+Please note, this component has currently only been tested with the Goldair GPPH (inverter) and GPDH420 (dehumidifier)
+range, however theoretically it should also work with GEPH and GPCV heater devices, the GPDH440 dehumidifier, and any
+other Goldair heaters or dehumidifiers based on the Tuya platform.
 
 
 ---
 ---
 
 
@@ -38,10 +45,8 @@ The preferred installation method is via [HACS](https://hacs.xyz/). Once you hav
 [instructions for adding a custom repository](https://hacs.xyz/docs/navigation/settings#custom-repositories) and then
 [instructions for adding a custom repository](https://hacs.xyz/docs/navigation/settings#custom-repositories) and then
 the integration will be available to install like any other.
 the integration will be available to install like any other.
 
 
-You can also use [Custom Updater](https://github.com/custom-components/custom_updater). Once you have Custom Updater set
-up, simply go to the dev-service page
-<img src="https://www.home-assistant.io/images/screenshots/developer-tool-services-icon.png" alt="The dev-service icon" width="30">
-and call the `custom_updater.install` service with this service data:
+You can also use [Custom Updater](https://github.com/custom-components/custom_updater). Once Custom Updater is  set
+up, go to the Developer Tools > Service page and call the `custom_updater.install` service with this service data:
 ```json
 ```json
 { "element": "goldair_climate" }
 { "element": "goldair_climate" }
 ```
 ```
@@ -59,7 +64,7 @@ goldair_climate:
     host: 1.2.3.4
     host: 1.2.3.4
     device_id: <your device id>
     device_id: <your device id>
     local_key: <your local key>
     local_key: <your local key>
-    type: 'heater'
+    type: heater
 ```
 ```
 
 
 ### Configuration variables
 ### Configuration variables
@@ -80,21 +85,13 @@ goldair_climate:
                                               [as per the instructions below](#finding-your-device-id-and-local-key).
                                               [as per the instructions below](#finding-your-device-id-and-local-key).
 
 
 #### type
 #### type
-&nbsp;&nbsp;&nbsp;&nbsp;*(string) (Required)* The type of Goldair device. Currently `heater` is the only option; a 
-                                              future update will add support for dehumidifiers and other devices, so
-                                              setting the type now will prevent the integration breaking when this
-                                              functionality is released.
+&nbsp;&nbsp;&nbsp;&nbsp;*(string) (Required)* The type of Goldair device: currently `heater` or `dehumidifier`.
 
 
 #### climate
 #### climate
 &nbsp;&nbsp;&nbsp;&nbsp;*(boolean) (Optional)* Whether to surface this heater as a climate device.
 &nbsp;&nbsp;&nbsp;&nbsp;*(boolean) (Optional)* Whether to surface this heater as a climate device.
 
 
 &nbsp;&nbsp;&nbsp;&nbsp;*Default value: true* 
 &nbsp;&nbsp;&nbsp;&nbsp;*Default value: true* 
 
 
-#### sensor
-&nbsp;&nbsp;&nbsp;&nbsp;*(boolean) (Optional)* Whether to surface this heater's thermometer as a temperature sensor.
-
-&nbsp;&nbsp;&nbsp;&nbsp;*Default value: false* 
-
 #### display_light
 #### display_light
 &nbsp;&nbsp;&nbsp;&nbsp;*(boolean) (Optional)* Whether to surface this heater's LED display control as a light.
 &nbsp;&nbsp;&nbsp;&nbsp;*(boolean) (Optional)* Whether to surface this heater's LED display control as a light.
 
 
@@ -105,9 +102,9 @@ goldair_climate:
 
 
 &nbsp;&nbsp;&nbsp;&nbsp;*Default value: false* 
 &nbsp;&nbsp;&nbsp;&nbsp;*Default value: false* 
 
 
-Gotchas
--------
-These heaters have individual target temperatures for their Comfort and Eco modes, whereas Home Assistant only supports
+Heater gotchas
+--------------
+Goldair heaters have individual target temperatures for their Comfort and Eco modes, whereas Home Assistant only supports
 a single target temperature. Therefore, when you're in Comfort mode you will set the Comfort temperature (`5`-`35`), and
 a single target temperature. Therefore, when you're in Comfort mode you will set the Comfort temperature (`5`-`35`), and
 when you're in Eco mode you will set the Eco temperature (`5`-`21`), just like you were using the heater's own control 
 when you're in Eco mode you will set the Eco temperature (`5`-`21`), just like you were using the heater's own control 
 panel. Bear this in mind when writing automations that change the operation mode and set a temperature at the same time: 
 panel. Bear this in mind when writing automations that change the operation mode and set a temperature at the same time: 
@@ -139,9 +136,6 @@ Next steps
 This component needs specs! Once they're written I'm considering submitting it to the HA team for inclusion in standard 
 This component needs specs! Once they're written I'm considering submitting it to the HA team for inclusion in standard 
 installations. Please report any issues and feel free to raise pull requests.
 installations. Please report any issues and feel free to raise pull requests.
 
 
-I also have a working integration for Goldair WiFi dehumidifiers; it needs to be re-worked to prevent duplicate code
-before releasing it to the wild.
-
 Acknowledgements
 Acknowledgements
 ----------------
 ----------------
 None of this would have been possible without some foundational discovery work to get me started:
 None of this would have been possible without some foundational discovery work to get me started:

+ 12 - 6
custom_components/goldair_climate/__init__.py

@@ -15,7 +15,7 @@ import homeassistant.helpers.config_validation as cv
 from homeassistant.const import (CONF_NAME, CONF_HOST, TEMP_CELSIUS)
 from homeassistant.const import (CONF_NAME, CONF_HOST, TEMP_CELSIUS)
 from homeassistant.helpers.discovery import load_platform
 from homeassistant.helpers.discovery import load_platform
 
 
-VERSION = '0.0.5'
+VERSION = '0.0.6'
 
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER = logging.getLogger(__name__)
 
 
@@ -26,8 +26,8 @@ CONF_DEVICE_ID = 'device_id'
 CONF_LOCAL_KEY = 'local_key'
 CONF_LOCAL_KEY = 'local_key'
 CONF_TYPE = 'type'
 CONF_TYPE = 'type'
 CONF_TYPE_HEATER = 'heater'
 CONF_TYPE_HEATER = 'heater'
+CONF_TYPE_DEHUMIDIFIER = 'dehumidifier'
 CONF_CLIMATE = 'climate'
 CONF_CLIMATE = 'climate'
-CONF_SENSOR = 'sensor'
 CONF_DISPLAY_LIGHT = 'display_light'
 CONF_DISPLAY_LIGHT = 'display_light'
 CONF_CHILD_LOCK = 'child_lock'
 CONF_CHILD_LOCK = 'child_lock'
 
 
@@ -36,9 +36,8 @@ PLATFORM_SCHEMA = vol.Schema({
     vol.Required(CONF_HOST): cv.string,
     vol.Required(CONF_HOST): cv.string,
     vol.Required(CONF_DEVICE_ID): cv.string,
     vol.Required(CONF_DEVICE_ID): cv.string,
     vol.Required(CONF_LOCAL_KEY): cv.string,
     vol.Required(CONF_LOCAL_KEY): cv.string,
-    vol.Required(CONF_TYPE): vol.In([CONF_TYPE_HEATER]),
+    vol.Required(CONF_TYPE): vol.In([CONF_TYPE_HEATER, CONF_TYPE_DEHUMIDIFIER]),
     vol.Optional(CONF_CLIMATE, default=True): cv.boolean,
     vol.Optional(CONF_CLIMATE, default=True): cv.boolean,
-    vol.Optional(CONF_SENSOR, default=False): cv.boolean,
     vol.Optional(CONF_DISPLAY_LIGHT, default=False): cv.boolean,
     vol.Optional(CONF_DISPLAY_LIGHT, default=False): cv.boolean,
     vol.Optional(CONF_CHILD_LOCK, default=False): cv.boolean,
     vol.Optional(CONF_CHILD_LOCK, default=False): cv.boolean,
 })
 })
@@ -64,8 +63,6 @@ def setup(hass, config):
 
 
         if device_config.get(CONF_CLIMATE) == True:
         if device_config.get(CONF_CLIMATE) == True:
             load_platform(hass, 'climate', DOMAIN, discovery_info, config)
             load_platform(hass, 'climate', DOMAIN, discovery_info, config)
-        if device_config.get(CONF_SENSOR) == True:
-            load_platform(hass, 'sensor', DOMAIN, discovery_info, config)
         if device_config.get(CONF_DISPLAY_LIGHT) == True:
         if device_config.get(CONF_DISPLAY_LIGHT) == True:
             load_platform(hass, 'light', DOMAIN, discovery_info, config)
             load_platform(hass, 'light', DOMAIN, discovery_info, config)
         if device_config.get(CONF_CHILD_LOCK) == True:
         if device_config.get(CONF_CHILD_LOCK) == True:
@@ -133,6 +130,15 @@ class GoldairTuyaDevice(object):
     def set_property(self, dps_id, value):
     def set_property(self, dps_id, value):
         self._set_properties({dps_id: value})
         self._set_properties({dps_id: value})
 
 
+    def anticipate_property_value(self, dps_id, value):
+        """
+        Update a value in the cached state only. This is good for when you know the device will reflect a new state in
+        the next update, but don't want to wait for that update for the device to represent this state.
+
+        The anticipated value will be cleared with the next update.
+        """
+        self._cached_state[dps_id] = value
+
     def _reset_cached_state(self):
     def _reset_cached_state(self):
         self._cached_state = {
         self._cached_state = {
             'updated_at': 0
             'updated_at': 0

+ 5 - 1
custom_components/goldair_climate/climate.py

@@ -3,12 +3,16 @@ Setup for different kinds of Goldair climate devices
 """
 """
 from homeassistant.const import CONF_HOST
 from homeassistant.const import CONF_HOST
 from custom_components.goldair_climate import (
 from custom_components.goldair_climate import (
-    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER
+    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER, CONF_TYPE_DEHUMIDIFIER
 )
 )
 from custom_components.goldair_climate.heater.climate import GoldairHeater
 from custom_components.goldair_climate.heater.climate import GoldairHeater
+from custom_components.goldair_climate.dehumidifier.climate import GoldairDehumidifier
+
 
 
 def setup_platform(hass, config, add_devices, discovery_info=None):
 def setup_platform(hass, config, add_devices, discovery_info=None):
     """Set up the Goldair climate device according to its type."""
     """Set up the Goldair climate device according to its type."""
     device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
     device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
     if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
     if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
         add_devices([GoldairHeater(device)])
         add_devices([GoldairHeater(device)])
+    elif discovery_info[CONF_TYPE] == CONF_TYPE_DEHUMIDIFIER:
+        add_devices([GoldairDehumidifier(device)])

+ 0 - 0
custom_components/goldair_climate/dehumidifier/__init__.py


+ 250 - 0
custom_components/goldair_climate/dehumidifier/climate.py

@@ -0,0 +1,250 @@
+"""
+Goldair WiFi Heater device.
+"""
+from homeassistant.const import (
+    ATTR_TEMPERATURE, TEMP_CELSIUS, STATE_UNAVAILABLE
+)
+from homeassistant.components.climate import ClimateDevice
+from homeassistant.components.climate.const import (
+    ATTR_FAN_MODE, ATTR_HUMIDITY, ATTR_HVAC_MODE, ATTR_PRESET_MODE,
+    FAN_OFF, FAN_LOW, FAN_HIGH,
+    HVAC_MODE_OFF, HVAC_MODE_DRY,
+    SUPPORT_TARGET_HUMIDITY, SUPPORT_PRESET_MODE, SUPPORT_FAN_MODE
+)
+from custom_components.goldair_climate import GoldairTuyaDevice
+
+ATTR_ON = 'on'
+ATTR_TARGET_HUMIDITY = 'target_humidity'
+ATTR_AIR_CLEAN_ON = 'air_clean_on'
+ATTR_CHILD_LOCK = 'child_lock'
+ATTR_FAULT = 'fault'
+ATTR_DISPLAY_ON = 'display_on'
+
+PRESET_NORMAL = 'Normal'
+PRESET_LOW = 'Low'
+PRESET_HIGH = 'High'
+PRESET_DRY_CLOTHES = 'Dry clothes'
+PRESET_AIR_CLEAN = 'Air clean'
+
+FAULT_NONE = 'No fault'
+FAULT_TANK = 'Tank full or missing'
+
+PROPERTY_TO_DPS_ID = {
+    ATTR_HVAC_MODE: '1',
+    ATTR_PRESET_MODE: '2',
+    ATTR_TARGET_HUMIDITY: '4',
+    ATTR_AIR_CLEAN_ON: '5',
+    ATTR_FAN_MODE: '6',
+    ATTR_CHILD_LOCK: '7',
+    ATTR_FAULT: '11',
+    ATTR_DISPLAY_ON: '102',
+    ATTR_TEMPERATURE: '103',
+    ATTR_HUMIDITY: '104'
+}
+
+HVAC_MODE_TO_DPS_MODE = {
+    HVAC_MODE_OFF: False,
+    HVAC_MODE_DRY: True
+}
+PRESET_MODE_TO_DPS_MODE = {
+    PRESET_NORMAL: '0',
+    PRESET_LOW: '1',
+    PRESET_HIGH: '2',
+    PRESET_DRY_CLOTHES: '3'
+}
+FAN_MODE_TO_DPS_MODE = {
+    FAN_LOW: '1',
+    FAN_HIGH: '3'
+}
+FAULT_CODE_TO_DPS_CODE = {
+    FAULT_NONE: 0,
+    FAULT_TANK: 8
+}
+
+SUPPORT_FLAGS = SUPPORT_TARGET_HUMIDITY | SUPPORT_PRESET_MODE | SUPPORT_FAN_MODE
+
+
+class GoldairDehumidifier(ClimateDevice):
+    """Representation of a Goldair WiFi dehumidifier."""
+
+    def __init__(self, device):
+        """Initialize the dehumidifier.
+        Args:
+            name (str): The device's name.
+            device (GoldairTuyaDevice): The device API instance."""
+        self._device = device
+
+        self._support_flags = SUPPORT_FLAGS
+
+        self._HUMIDITY_STEP = 5
+        self._HUMIDITY_LIMITS = {
+            'min': 30,
+            'max': 80
+        }
+
+    @property
+    def supported_features(self):
+        """Return the list of supported features."""
+        return self._support_flags
+
+    @property
+    def should_poll(self):
+        """Return the polling state."""
+        return True
+
+    @property
+    def name(self):
+        """Return the name of the climate device."""
+        return self._device.name
+
+    @property
+    def current_humidity(self):
+        """Return the current reading of the humidity sensor."""
+        return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HUMIDITY])
+
+    @property
+    def min_humidity(self):
+        """Return the minimum humidity setting."""
+        return self._HUMIDITY_LIMITS['min']
+
+    @property
+    def max_humidity(self):
+        """Return the maximum humidity setting."""
+        return self._HUMIDITY_LIMITS['max']
+
+    @property
+    def target_humidity(self):
+        """Return the current target humidity."""
+        return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TARGET_HUMIDITY])
+
+    def set_humidity(self, humidity):
+        """Set the device's target humidity."""
+        if self.preset_mode in [PRESET_AIR_CLEAN, PRESET_DRY_CLOTHES]:
+            raise ValueError('Humidity can only be changed while in Normal, Low or High preset modes.')
+        humidity = int(self._HUMIDITY_STEP * round(float(humidity) / self._HUMIDITY_STEP))
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_TARGET_HUMIDITY], humidity)
+
+    @property
+    def temperature_unit(self):
+        """Return the unit of measurement."""
+        return self._device.temperature_unit
+
+    @property
+    def min_temp(self):
+        """Return the minimum temperature setting."""
+        return None
+
+    @property
+    def max_temp(self):
+        """Return the maximum temperature setting."""
+        return None
+
+    @property
+    def current_temperature(self):
+        """Return the current temperature."""
+        return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TEMPERATURE])
+
+    @property
+    def hvac_mode(self):
+        """Return current HVAC mode, ie Dry or Off."""
+        dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
+
+        if dps_mode is not None:
+            return GoldairTuyaDevice.get_key_for_value(HVAC_MODE_TO_DPS_MODE, dps_mode)
+        else:
+            return STATE_UNAVAILABLE
+
+    @property
+    def hvac_modes(self):
+        """Return the list of available HVAC modes."""
+        return list(HVAC_MODE_TO_DPS_MODE.keys())
+
+    def set_hvac_mode(self, hvac_mode):
+        """Set new HVAC mode."""
+        dps_mode = HVAC_MODE_TO_DPS_MODE[hvac_mode]
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE], dps_mode)
+
+    @property
+    def preset_mode(self):
+        """Return current preset mode, ie Normal, Low, High, Dry Clothes, or Air Clean."""
+        air_clean_on = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_AIR_CLEAN_ON])
+        dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE])
+
+        if air_clean_on:
+            return PRESET_AIR_CLEAN
+        elif dps_mode is not None:
+            return GoldairTuyaDevice.get_key_for_value(PRESET_MODE_TO_DPS_MODE, dps_mode)
+        else:
+            return None
+
+    @property
+    def preset_modes(self):
+        """Return the list of available preset modes."""
+        return list(PRESET_MODE_TO_DPS_MODE.keys()) + [PRESET_AIR_CLEAN]
+
+    def set_preset_mode(self, preset_mode):
+        """Set new preset mode."""
+        if preset_mode == PRESET_AIR_CLEAN:
+            self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_AIR_CLEAN_ON], True)
+            self._device.anticipate_property_value(PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], FAN_HIGH)
+        else:
+            dps_mode = PRESET_MODE_TO_DPS_MODE[preset_mode]
+            self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_AIR_CLEAN_ON], False)
+            self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE], dps_mode)
+            if preset_mode == PRESET_LOW:
+                self._device.anticipate_property_value(PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], FAN_LOW)
+            elif preset_mode in [PRESET_HIGH, PRESET_DRY_CLOTHES]:
+                self._device.anticipate_property_value(PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], FAN_HIGH)
+
+    @property
+    def fan_mode(self):
+        """Return the fan mode."""
+        preset = self.preset_mode
+
+        if preset in [PRESET_HIGH, PRESET_DRY_CLOTHES, PRESET_AIR_CLEAN]:
+            return FAN_HIGH
+        elif preset == PRESET_LOW:
+            return FAN_LOW
+        else:
+            dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_FAN_MODE])
+            if dps_mode is not None:
+                return GoldairTuyaDevice.get_key_for_value(FAN_MODE_TO_DPS_MODE, dps_mode)
+            else:
+                return None
+
+    @property
+    def fan_modes(self):
+        """List of fan modes."""
+        preset = self.preset_mode
+
+        if preset in [PRESET_HIGH, PRESET_DRY_CLOTHES, PRESET_AIR_CLEAN]:
+            return [FAN_HIGH]
+        elif preset == PRESET_LOW:
+            return [FAN_LOW]
+        elif preset == PRESET_NORMAL:
+            return list(FAN_MODE_TO_DPS_MODE.keys())
+        else:
+            return []
+
+    def set_fan_mode(self, fan_mode):
+        """Set new fan mode."""
+        if self.preset_mode != PRESET_NORMAL:
+            raise ValueError('Fan mode can only be changed while in Normal preset mode.')
+
+        if fan_mode not in FAN_MODE_TO_DPS_MODE.keys():
+            raise ValueError(f'Invalid fan mode: {fan_mode}')
+
+        dps_mode = FAN_MODE_TO_DPS_MODE[fan_mode]
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], dps_mode)
+
+    @property
+    def fault(self):
+        """Get the current fault status."""
+        fault = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_FAULT])
+        if fault is None or fault == FAULT_NONE:
+            return None
+        else:
+            return GoldairTuyaDevice.get_key_for_value(FAULT_CODE_TO_DPS_CODE, fault)
+
+    def update(self):
+        self._device.refresh()

+ 56 - 0
custom_components/goldair_climate/dehumidifier/light.py

@@ -0,0 +1,56 @@
+"""
+Platform to control the LED display light on Goldair WiFi-connected dehumidifiers.
+"""
+from homeassistant.components.light import Light
+from homeassistant.const import STATE_UNAVAILABLE
+from custom_components.goldair_climate import GoldairTuyaDevice
+from custom_components.goldair_climate.dehumidifier.climate import (
+    ATTR_DISPLAY_ON, PROPERTY_TO_DPS_ID, HVAC_MODE_TO_DPS_MODE
+)
+from homeassistant.components.climate import (
+    ATTR_HVAC_MODE, HVAC_MODE_OFF
+)
+
+
+class GoldairDehumidifierLedDisplayLight(Light):
+    """Representation of a Goldair WiFi-connected dehumidifier LED display."""
+
+    def __init__(self, device):
+        """Initialize the light.
+        Args:
+            device (GoldairTuyaDevice): The device API instance."""
+        self._device = device
+
+    @property
+    def should_poll(self):
+        """Return the polling state."""
+        return True
+
+    @property
+    def name(self):
+        """Return the name of the light."""
+        return self._device.name
+
+    @property
+    def is_on(self):
+        """Return the current state."""
+        dps_hvac_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
+        dps_display_on = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON])
+
+        if dps_hvac_mode is None or dps_hvac_mode == HVAC_MODE_TO_DPS_MODE[HVAC_MODE_OFF]:
+            return STATE_UNAVAILABLE
+        else:
+            return dps_display_on
+
+    def turn_on(self):
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON], True)
+
+    def turn_off(self):
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON], False)
+
+    def toggle(self):
+        dps_hvac_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
+        dps_display_on = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON])
+
+        if dps_hvac_mode != HVAC_MODE_TO_DPS_MODE[HVAC_MODE_OFF]:
+            self.turn_on() if not dps_display_on else self.turn_off()

+ 50 - 0
custom_components/goldair_climate/dehumidifier/lock.py

@@ -0,0 +1,50 @@
+"""
+Platform to control the child lock on Goldair WiFi-connected dehumidifiers.
+"""
+from homeassistant.components.lock import (STATE_LOCKED, STATE_UNLOCKED, LockDevice)
+from homeassistant.const import STATE_UNAVAILABLE
+from custom_components.goldair_climate import GoldairTuyaDevice
+from custom_components.goldair_climate.dehumidifier.climate import (
+    ATTR_CHILD_LOCK, PROPERTY_TO_DPS_ID
+)
+
+
+class GoldairDehumidifierChildLock(LockDevice):
+    """Representation of a Goldair WiFi-connected dehumidifier child lock."""
+
+    def __init__(self, device):
+        """Initialize the lock.
+        Args:
+            device (GoldairTuyaDevice): The device API instance."""
+        self._device = device
+
+    @property
+    def should_poll(self):
+        """Return the polling state."""
+        return True
+
+    @property
+    def name(self):
+        """Return the name of the lock."""
+        return self._device.name
+
+    @property
+    def state(self):
+        """Return the current state."""
+        if self.is_locked is None:
+            return STATE_UNAVAILABLE
+        else:
+            return STATE_LOCKED if self.is_locked else STATE_UNLOCKED
+
+    @property
+    def is_locked(self):
+        """Return the a boolean representing whether the child lock is on or not."""
+        return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK])
+
+    def lock(self, **kwargs):
+        """Turn on the child lock."""
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK], True)
+
+    def unlock(self, **kwargs):
+        """Turn off the child lock."""
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK], False)

+ 30 - 39
custom_components/goldair_climate/heater/climate.py

@@ -4,10 +4,10 @@ Goldair WiFi Heater device.
 from homeassistant.const import (
 from homeassistant.const import (
     ATTR_TEMPERATURE, TEMP_CELSIUS, STATE_UNAVAILABLE
     ATTR_TEMPERATURE, TEMP_CELSIUS, STATE_UNAVAILABLE
 )
 )
-from homeassistant.components.climate import (
-  ClimateDevice, ATTR_HVAC_MODE, ATTR_PRESET_MODE, ATTR_TEMPERATURE, HVAC_MODE_OFF, HVAC_MODE_HEAT
-)
+from homeassistant.components.climate import ClimateDevice
 from homeassistant.components.climate.const import (
 from homeassistant.components.climate.const import (
+    ATTR_HVAC_MODE, ATTR_PRESET_MODE,
+    HVAC_MODE_OFF, HVAC_MODE_HEAT,
     SUPPORT_TARGET_TEMPERATURE, SUPPORT_PRESET_MODE, SUPPORT_SWING_MODE
     SUPPORT_TARGET_TEMPERATURE, SUPPORT_PRESET_MODE, SUPPORT_SWING_MODE
 )
 )
 from custom_components.goldair_climate import GoldairTuyaDevice
 from custom_components.goldair_climate import GoldairTuyaDevice
@@ -19,8 +19,6 @@ ATTR_FAULT = 'fault'
 ATTR_POWER_MODE_AUTO = 'auto'
 ATTR_POWER_MODE_AUTO = 'auto'
 ATTR_POWER_MODE_USER = 'user'
 ATTR_POWER_MODE_USER = 'user'
 ATTR_POWER_LEVEL = 'power_level'
 ATTR_POWER_LEVEL = 'power_level'
-ATTR_TIMER_MINUTES = 'timer_minutes'
-ATTR_TIMER_ON = 'timer_on'
 ATTR_DISPLAY_ON = 'display_on'
 ATTR_DISPLAY_ON = 'display_on'
 ATTR_POWER_MODE = 'power_mode'
 ATTR_POWER_MODE = 'power_mode'
 ATTR_ECO_TARGET_TEMPERATURE = 'eco_' + ATTR_TARGET_TEMPERATURE
 ATTR_ECO_TARGET_TEMPERATURE = 'eco_' + ATTR_TARGET_TEMPERATURE
@@ -29,7 +27,7 @@ STATE_COMFORT = 'Comfort'
 STATE_ECO = 'Eco'
 STATE_ECO = 'Eco'
 STATE_ANTI_FREEZE = 'Anti-freeze'
 STATE_ANTI_FREEZE = 'Anti-freeze'
 
 
-GOLDAIR_PROPERTY_TO_DPS_ID = {
+PROPERTY_TO_DPS_ID = {
     ATTR_HVAC_MODE: '1',
     ATTR_HVAC_MODE: '1',
     ATTR_TARGET_TEMPERATURE: '2',
     ATTR_TARGET_TEMPERATURE: '2',
     ATTR_TEMPERATURE: '3',
     ATTR_TEMPERATURE: '3',
@@ -37,23 +35,21 @@ GOLDAIR_PROPERTY_TO_DPS_ID = {
     ATTR_CHILD_LOCK: '6',
     ATTR_CHILD_LOCK: '6',
     ATTR_FAULT: '12',
     ATTR_FAULT: '12',
     ATTR_POWER_LEVEL: '101',
     ATTR_POWER_LEVEL: '101',
-    ATTR_TIMER_MINUTES: '102',
-    ATTR_TIMER_ON: '103',
     ATTR_DISPLAY_ON: '104',
     ATTR_DISPLAY_ON: '104',
     ATTR_POWER_MODE: '105',
     ATTR_POWER_MODE: '105',
     ATTR_ECO_TARGET_TEMPERATURE: '106'
     ATTR_ECO_TARGET_TEMPERATURE: '106'
 }
 }
 
 
-GOLDAIR_MODE_TO_HVAC_MODE = {
+HVAC_MODE_TO_DPS_MODE = {
     HVAC_MODE_OFF: False,
     HVAC_MODE_OFF: False,
     HVAC_MODE_HEAT: True
     HVAC_MODE_HEAT: True
 }
 }
-GOLDAIR_MODE_TO_PRESET_MODE = {
+PRESET_MODE_TO_DPS_MODE = {
     STATE_COMFORT: 'C',
     STATE_COMFORT: 'C',
     STATE_ECO: 'ECO',
     STATE_ECO: 'ECO',
     STATE_ANTI_FREEZE: 'AF'
     STATE_ANTI_FREEZE: 'AF'
 }
 }
-GOLDAIR_POWER_LEVEL_TO_DPS_LEVEL = {
+POWER_LEVEL_TO_DPS_LEVEL = {
     'Stop': 'stop',
     'Stop': 'stop',
     '1': '1',
     '1': '1',
     '2': '2',
     '2': '2',
@@ -62,10 +58,10 @@ GOLDAIR_POWER_LEVEL_TO_DPS_LEVEL = {
     '5': '5',
     '5': '5',
     'Auto': 'auto'
     'Auto': 'auto'
 }
 }
-GOLDAIR_POWER_MODES = [ATTR_POWER_MODE_USER, ATTR_POWER_MODE_USER]
 
 
 SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE | SUPPORT_SWING_MODE
 SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE | SUPPORT_SWING_MODE
 
 
+
 class GoldairHeater(ClimateDevice):
 class GoldairHeater(ClimateDevice):
     """Representation of a Goldair WiFi heater."""
     """Representation of a Goldair WiFi heater."""
 
 
@@ -105,11 +101,6 @@ class GoldairHeater(ClimateDevice):
         """Return the name of the climate device."""
         """Return the name of the climate device."""
         return self._device.name
         return self._device.name
 
 
-    @property
-    def state(self):
-        """Return the state of the climate device."""
-        return self.hvac_mode
-
     @property
     @property
     def temperature_unit(self):
     def temperature_unit(self):
         """Return the unit of measurement."""
         """Return the unit of measurement."""
@@ -119,9 +110,9 @@ class GoldairHeater(ClimateDevice):
     def target_temperature(self):
     def target_temperature(self):
         """Return the temperature we try to reach."""
         """Return the temperature we try to reach."""
         if self.preset_mode == STATE_COMFORT:
         if self.preset_mode == STATE_COMFORT:
-            return self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_TARGET_TEMPERATURE])
+            return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TARGET_TEMPERATURE])
         elif self.preset_mode == STATE_ECO:
         elif self.preset_mode == STATE_ECO:
-            return self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_ECO_TARGET_TEMPERATURE])
+            return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_ECO_TARGET_TEMPERATURE])
         else:
         else:
             return None
             return None
 
 
@@ -168,77 +159,77 @@ class GoldairHeater(ClimateDevice):
             )
             )
 
 
         if preset_mode == STATE_COMFORT:
         if preset_mode == STATE_COMFORT:
-            self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_TARGET_TEMPERATURE], target_temperature)
+            self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_TARGET_TEMPERATURE], target_temperature)
         elif preset_mode == STATE_ECO:
         elif preset_mode == STATE_ECO:
-            self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_ECO_TARGET_TEMPERATURE], target_temperature)
+            self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_ECO_TARGET_TEMPERATURE], target_temperature)
 
 
     @property
     @property
     def current_temperature(self):
     def current_temperature(self):
         """Return the current temperature."""
         """Return the current temperature."""
-        return self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_TEMPERATURE])
+        return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TEMPERATURE])
 
 
     @property
     @property
     def hvac_mode(self):
     def hvac_mode(self):
         """Return current HVAC mode, ie Heat or Off."""
         """Return current HVAC mode, ie Heat or Off."""
-        dps_mode = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
+        dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
 
 
         if dps_mode is not None:
         if dps_mode is not None:
-            return GoldairTuyaDevice.get_key_for_value(GOLDAIR_MODE_TO_HVAC_MODE, dps_mode)
+            return GoldairTuyaDevice.get_key_for_value(HVAC_MODE_TO_DPS_MODE, dps_mode)
         else:
         else:
             return STATE_UNAVAILABLE
             return STATE_UNAVAILABLE
 
 
     @property
     @property
     def hvac_modes(self):
     def hvac_modes(self):
         """Return the list of available HVAC modes."""
         """Return the list of available HVAC modes."""
-        return list(GOLDAIR_MODE_TO_HVAC_MODE.keys())
+        return list(HVAC_MODE_TO_DPS_MODE.keys())
 
 
     def set_hvac_mode(self, hvac_mode):
     def set_hvac_mode(self, hvac_mode):
         """Set new HVAC mode."""
         """Set new HVAC mode."""
-        dps_mode = GOLDAIR_MODE_TO_HVAC_MODE[hvac_mode]
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE], dps_mode)
+        dps_mode = HVAC_MODE_TO_DPS_MODE[hvac_mode]
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE], dps_mode)
 
 
     @property
     @property
     def preset_mode(self):
     def preset_mode(self):
         """Return current preset mode, ie Comfort, Eco, Anti-freeze."""
         """Return current preset mode, ie Comfort, Eco, Anti-freeze."""
-        dps_mode = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE])
+        dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE])
         if dps_mode is not None:
         if dps_mode is not None:
-            return GoldairTuyaDevice.get_key_for_value(GOLDAIR_MODE_TO_PRESET_MODE, dps_mode)
+            return GoldairTuyaDevice.get_key_for_value(PRESET_MODE_TO_DPS_MODE, dps_mode)
         else:
         else:
             return None
             return None
 
 
     @property
     @property
     def preset_modes(self):
     def preset_modes(self):
         """Return the list of available preset modes."""
         """Return the list of available preset modes."""
-        return list(GOLDAIR_MODE_TO_PRESET_MODE.keys())
+        return list(PRESET_MODE_TO_DPS_MODE.keys())
 
 
     def set_preset_mode(self, preset_mode):
     def set_preset_mode(self, preset_mode):
         """Set new preset mode."""
         """Set new preset mode."""
-        dps_mode = GOLDAIR_MODE_TO_PRESET_MODE[preset_mode]
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE], dps_mode)
+        dps_mode = PRESET_MODE_TO_DPS_MODE[preset_mode]
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE], dps_mode)
 
 
     @property
     @property
     def swing_mode(self):
     def swing_mode(self):
         """Return the power level."""
         """Return the power level."""
-        dps_mode = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_POWER_MODE])
+        dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_POWER_MODE])
         if dps_mode == ATTR_POWER_MODE_USER:
         if dps_mode == ATTR_POWER_MODE_USER:
-            return self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_POWER_LEVEL])
+            return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_POWER_LEVEL])
         elif dps_mode == ATTR_POWER_MODE_AUTO:
         elif dps_mode == ATTR_POWER_MODE_AUTO:
-            return GoldairTuyaDevice.get_key_for_value(GOLDAIR_POWER_LEVEL_TO_DPS_LEVEL, dps_mode)
+            return GoldairTuyaDevice.get_key_for_value(POWER_LEVEL_TO_DPS_LEVEL, dps_mode)
         else:
         else:
             return None
             return None
 
 
     @property
     @property
     def swing_modes(self):
     def swing_modes(self):
         """List of power levels."""
         """List of power levels."""
-        return list(GOLDAIR_POWER_LEVEL_TO_DPS_LEVEL.keys())
+        return list(POWER_LEVEL_TO_DPS_LEVEL.keys())
 
 
     def set_swing_mode(self, swing_mode):
     def set_swing_mode(self, swing_mode):
         """Set new power level."""
         """Set new power level."""
         new_level = swing_mode
         new_level = swing_mode
-        if new_level not in GOLDAIR_POWER_LEVEL_TO_DPS_LEVEL.keys():
+        if new_level not in POWER_LEVEL_TO_DPS_LEVEL.keys():
             raise ValueError(f'Invalid power level: {new_level}')
             raise ValueError(f'Invalid power level: {new_level}')
-        dps_level = GOLDAIR_POWER_LEVEL_TO_DPS_LEVEL[new_level]
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_POWER_LEVEL], dps_level)
+        dps_level = POWER_LEVEL_TO_DPS_LEVEL[new_level]
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_POWER_LEVEL], dps_level)
 
 
     def update(self):
     def update(self):
         self._device.refresh()
         self._device.refresh()

+ 10 - 12
custom_components/goldair_climate/heater/light.py

@@ -5,14 +5,12 @@ from homeassistant.components.light import Light
 from homeassistant.const import STATE_UNAVAILABLE
 from homeassistant.const import STATE_UNAVAILABLE
 from custom_components.goldair_climate import GoldairTuyaDevice
 from custom_components.goldair_climate import GoldairTuyaDevice
 from custom_components.goldair_climate.heater.climate import (
 from custom_components.goldair_climate.heater.climate import (
-  ATTR_DISPLAY_ON, GOLDAIR_PROPERTY_TO_DPS_ID, GOLDAIR_MODE_TO_HVAC_MODE
+    ATTR_DISPLAY_ON, PROPERTY_TO_DPS_ID, HVAC_MODE_TO_DPS_MODE
 )
 )
 from homeassistant.components.climate import (
 from homeassistant.components.climate import (
-  ATTR_HVAC_MODE, HVAC_MODE_OFF
+    ATTR_HVAC_MODE, HVAC_MODE_OFF
 )
 )
 
 
-import logging
-_LOGGER = logging.getLogger(__name__)
 
 
 class GoldairHeaterLedDisplayLight(Light):
 class GoldairHeaterLedDisplayLight(Light):
     """Representation of a Goldair WiFi-connected heater LED display."""
     """Representation of a Goldair WiFi-connected heater LED display."""
@@ -36,23 +34,23 @@ class GoldairHeaterLedDisplayLight(Light):
     @property
     @property
     def is_on(self):
     def is_on(self):
         """Return the current state."""
         """Return the current state."""
-        dps_hvac_mode = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
-        dps_display_on = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON])
+        dps_hvac_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
+        dps_display_on = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON])
 
 
-        if dps_hvac_mode is None or dps_hvac_mode == GOLDAIR_MODE_TO_HVAC_MODE[HVAC_MODE_OFF]:
+        if dps_hvac_mode is None or dps_hvac_mode == HVAC_MODE_TO_DPS_MODE[HVAC_MODE_OFF]:
             return STATE_UNAVAILABLE
             return STATE_UNAVAILABLE
         else:
         else:
             return dps_display_on
             return dps_display_on
 
 
     def turn_on(self):
     def turn_on(self):
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON], True)
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON], True)
 
 
     def turn_off(self):
     def turn_off(self):
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON], False)
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON], False)
 
 
     def toggle(self):
     def toggle(self):
-        dps_hvac_mode = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
-        dps_display_on = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON])
+        dps_hvac_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
+        dps_display_on = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_DISPLAY_ON])
 
 
-        if dps_hvac_mode != GOLDAIR_MODE_TO_HVAC_MODE[HVAC_MODE_OFF]:
+        if dps_hvac_mode != HVAC_MODE_TO_DPS_MODE[HVAC_MODE_OFF]:
             self.turn_on() if not dps_display_on else self.turn_off()
             self.turn_on() if not dps_display_on else self.turn_off()

+ 5 - 4
custom_components/goldair_climate/heater/lock.py

@@ -5,9 +5,10 @@ from homeassistant.components.lock import (STATE_LOCKED, STATE_UNLOCKED, LockDev
 from homeassistant.const import STATE_UNAVAILABLE
 from homeassistant.const import STATE_UNAVAILABLE
 from custom_components.goldair_climate import GoldairTuyaDevice
 from custom_components.goldair_climate import GoldairTuyaDevice
 from custom_components.goldair_climate.heater.climate import (
 from custom_components.goldair_climate.heater.climate import (
-  ATTR_CHILD_LOCK, GOLDAIR_PROPERTY_TO_DPS_ID, GOLDAIR_MODE_TO_HVAC_MODE
+    ATTR_CHILD_LOCK, PROPERTY_TO_DPS_ID
 )
 )
 
 
+
 class GoldairHeaterChildLock(LockDevice):
 class GoldairHeaterChildLock(LockDevice):
     """Representation of a Goldair WiFi-connected heater child lock."""
     """Representation of a Goldair WiFi-connected heater child lock."""
 
 
@@ -38,12 +39,12 @@ class GoldairHeaterChildLock(LockDevice):
     @property
     @property
     def is_locked(self):
     def is_locked(self):
         """Return the a boolean representing whether the child lock is on or not."""
         """Return the a boolean representing whether the child lock is on or not."""
-        return self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK])
+        return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK])
 
 
     def lock(self, **kwargs):
     def lock(self, **kwargs):
         """Turn on the child lock."""
         """Turn on the child lock."""
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK], True)
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK], True)
 
 
     def unlock(self, **kwargs):
     def unlock(self, **kwargs):
         """Turn off the child lock."""
         """Turn off the child lock."""
-        self._device.set_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK], False)
+        self._device.set_property(PROPERTY_TO_DPS_ID[ATTR_CHILD_LOCK], False)

+ 0 - 41
custom_components/goldair_climate/heater/sensor.py

@@ -1,41 +0,0 @@
-"""
-Platform to sense the current temperature at a Goldair WiFi-connected heaters and panels.
-"""
-from homeassistant.helpers.entity import Entity
-from homeassistant.const import (
-    STATE_UNAVAILABLE, ATTR_TEMPERATURE
-)
-from custom_components.goldair_climate import GoldairTuyaDevice
-from custom_components.goldair_climate.heater.climate import GOLDAIR_PROPERTY_TO_DPS_ID
-
-class GoldairHeaterTemperatureSensor(Entity):
-    """Representation of a Goldair WiFi-connected heater thermometer."""
-
-    def __init__(self, device):
-        """Initialize the lock.
-        Args:
-            device (GoldairTuyaDevice): The device API instance."""
-        self._device = device
-
-    @property
-    def should_poll(self):
-        """Return the polling state."""
-        return True
-
-    @property
-    def name(self):
-        """Return the name of the sensor."""
-        return self._device.name
-
-    @property
-    def state(self):
-        """Return the current temperature."""
-        current_temperature = self._device.get_property(GOLDAIR_PROPERTY_TO_DPS_ID[ATTR_TEMPERATURE])
-        if current_temperature is None:
-            return STATE_UNAVAILABLE
-        else:
-            return current_temperature
-
-    @property
-    def unit_of_measurement(self):
-        return self._device.temperature_unit

+ 5 - 1
custom_components/goldair_climate/light.py

@@ -3,12 +3,16 @@ Setup for different kinds of Goldair climate devices
 """
 """
 from homeassistant.const import CONF_HOST
 from homeassistant.const import CONF_HOST
 from custom_components.goldair_climate import (
 from custom_components.goldair_climate import (
-    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER
+    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER, CONF_TYPE_DEHUMIDIFIER
 )
 )
 from custom_components.goldair_climate.heater.light import GoldairHeaterLedDisplayLight
 from custom_components.goldair_climate.heater.light import GoldairHeaterLedDisplayLight
+from custom_components.goldair_climate.dehumidifier.light import GoldairDehumidifierLedDisplayLight
+
 
 
 def setup_platform(hass, config, add_devices, discovery_info=None):
 def setup_platform(hass, config, add_devices, discovery_info=None):
     """Set up the Goldair climate device according to its type."""
     """Set up the Goldair climate device according to its type."""
     device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
     device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
     if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
     if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
         add_devices([GoldairHeaterLedDisplayLight(device)])
         add_devices([GoldairHeaterLedDisplayLight(device)])
+    elif discovery_info[CONF_TYPE] == CONF_TYPE_DEHUMIDIFIER:
+        add_devices([GoldairDehumidifierLedDisplayLight(device)])

+ 5 - 1
custom_components/goldair_climate/lock.py

@@ -3,12 +3,16 @@ Setup for different kinds of Goldair climate devices
 """
 """
 from homeassistant.const import CONF_HOST
 from homeassistant.const import CONF_HOST
 from custom_components.goldair_climate import (
 from custom_components.goldair_climate import (
-    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER
+    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER, CONF_TYPE_DEHUMIDIFIER
 )
 )
 from custom_components.goldair_climate.heater.lock import GoldairHeaterChildLock
 from custom_components.goldair_climate.heater.lock import GoldairHeaterChildLock
+from custom_components.goldair_climate.dehumidifier.lock import GoldairDehumidifierChildLock
+
 
 
 def setup_platform(hass, config, add_devices, discovery_info=None):
 def setup_platform(hass, config, add_devices, discovery_info=None):
     """Set up the Goldair climate device according to its type."""
     """Set up the Goldair climate device according to its type."""
     device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
     device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
     if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
     if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
         add_devices([GoldairHeaterChildLock(device)])
         add_devices([GoldairHeaterChildLock(device)])
+    if discovery_info[CONF_TYPE] == CONF_TYPE_DEHUMIDIFIER:
+        add_devices([GoldairDehumidifierChildLock(device)])

+ 6 - 2
custom_components/goldair_climate/manifest.json

@@ -3,7 +3,11 @@
   "name": "Goldair WiFi climate devices",
   "name": "Goldair WiFi climate devices",
   "documentation": "https://github.com/nikrolls/homeassistant-goldair-climate",
   "documentation": "https://github.com/nikrolls/homeassistant-goldair-climate",
   "dependencies": [],
   "dependencies": [],
-  "codeowners": ["@nikrolls"],
-  "requirements": ["pytuya>=7.0.5"],
+  "codeowners": [
+    "@nikrolls"
+  ],
+  "requirements": [
+    "pytuya>=7.0.5"
+  ],
   "homeassistant": "0.96.0"
   "homeassistant": "0.96.0"
 }
 }

+ 0 - 14
custom_components/goldair_climate/sensor.py

@@ -1,14 +0,0 @@
-"""
-Setup for different kinds of Goldair climate devices
-"""
-from homeassistant.const import CONF_HOST
-from custom_components.goldair_climate import (
-    DOMAIN, CONF_TYPE, CONF_TYPE_HEATER
-)
-from custom_components.goldair_climate.heater.sensor import GoldairHeaterTemperatureSensor
-
-def setup_platform(hass, config, add_devices, discovery_info=None):
-    """Set up the Goldair climate device according to its type."""
-    device = hass.data[DOMAIN][discovery_info[CONF_HOST]]
-    if discovery_info[CONF_TYPE] == CONF_TYPE_HEATER:
-        add_devices([GoldairHeaterTemperatureSensor(device)])

+ 5 - 3
custom_updater.json

@@ -1,6 +1,6 @@
 {
 {
     "goldair_climate": {
     "goldair_climate": {
-        "version": "0.0.5",
+        "version": "0.0.6",
         "local_location": "/custom_components/goldair_climate/__init__.py",
         "local_location": "/custom_components/goldair_climate/__init__.py",
         "remote_location": "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/__init__.py",
         "remote_location": "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/__init__.py",
         "visit_repo": "https://github.com/nikrolls/homeassistant-goldair-climate",
         "visit_repo": "https://github.com/nikrolls/homeassistant-goldair-climate",
@@ -11,12 +11,14 @@
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/climate.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/climate.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/light.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/light.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/lock.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/lock.py",
-            "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/sensor.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/__init__.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/__init__.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/climate.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/climate.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/light.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/light.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/lock.py",
             "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/lock.py",
-            "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/heater/sensor.py"
+            "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/dehumidifier/__init__.py",
+            "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/dehumidifier/climate.py",
+            "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/dehumidifier/light.py",
+            "https://raw.githubusercontent.com/nikrolls/homeassistant-goldair-climate/master/custom_components/goldair_climate/dehumidifier/lock.py"
         ]
         ]
     }
     }
 }
 }

+ 14 - 0
hacs.json

@@ -0,0 +1,14 @@
+{
+  "name": "Goldair WiFi climate devices",
+  "render_readme": true,
+  "domains": [
+    "climate",
+    "light",
+    "lock"
+  ],
+  "country": [
+    "NZ",
+    "AU"
+  ],
+  "homeassistant": "0.96.0"
+}