Esempio n. 1
0
async def test_ordered_list_percentage_round_trip():
    """Test we can round trip."""
    for ordered_list in (SMALL_ORDERED_LIST, LARGE_ORDERED_LIST):
        for i in range(1, 100):
            ordered_list_item_to_percentage(
                ordered_list, percentage_to_ordered_list_item(ordered_list,
                                                              i)) == i
Esempio n. 2
0
 def turn_on(self, speed=None, percentage=None, preset_mode=None, **kwargs):
     ret = False
     if not self.is_on:
         ret = self.set_property(self._prop_power, True)
     if self._prop_percentage:
         if not percentage and speed:
             percentage = ordered_list_item_to_percentage(self.speed_list, speed)
         if percentage:
             ret = self.set_property(self._prop_percentage, percentage)
         elif percentage is not None:
             _LOGGER.warning('Set fan speed percentage to %s failed: %s', self.name, {
                 'speed': speed,
                 'percentage': percentage,
             })
     elif self._prop_speed:
         if not speed and percentage:
             speed = percentage_to_ordered_list_item(self.speed_list, percentage)
         val = self._prop_speed.list_first(speed) if speed else None
         if val is None and self._prop_speed.value_range:
             if speed is not None:
                 val = int(speed)
         if val is not None:
             ret = self.set_property(self._prop_speed, val)
         elif speed is not None:
             _LOGGER.warning('Set fan speed level to %s failed: %s', self.name, {
                 'speed': speed,
                 'percentage': percentage,
                 'value':  val,
             })
     if preset_mode and self._prop_mode:
         val = self._prop_mode.list_first(preset_mode)
         if val is not None:
             ret = self.set_property(self._prop_mode, val)
     return ret
Esempio n. 3
0
 def percentage(self):
     """Return the current speed percentage."""
     if self._state is None:
         return None
     if self._state == 0:
         return 0
     return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS, self._state)
Esempio n. 4
0
    async def async_turn_on(self, speed: str = None, **kwargs):
        """Turn on the fan."""
        if speed is None:
            speed = FAN_SPEEDS[0]

        await self.async_set_percentage(
            ordered_list_item_to_percentage(FAN_SPEEDS, speed))
Esempio n. 5
0
 def percentage(self) -> Optional[int]:
     for speed, status_pattern in self._available_speeds.items():
         for k, v in status_pattern.items():
             if self._device_status.get(k) != v:
                 break
         else:
             return ordered_list_item_to_percentage(self._speeds, speed)
Esempio n. 6
0
File: fan.py Progetto: wwtlong/core
        def speed_received(msg):
            """Handle new received MQTT message for the speed."""
            speed_payload = self._value_templates[ATTR_SPEED](msg.payload)
            if speed_payload == self._payload["SPEED_LOW"]:
                speed = SPEED_LOW
            elif speed_payload == self._payload["SPEED_MEDIUM"]:
                speed = SPEED_MEDIUM
            elif speed_payload == self._payload["SPEED_HIGH"]:
                speed = SPEED_HIGH
            elif speed_payload == self._payload["SPEED_OFF"]:
                speed = SPEED_OFF
            else:
                speed = None

            if speed and speed in self._legacy_speeds_list:
                self._speed = speed
            else:
                _LOGGER.warning(
                    "'%s' received on topic %s is not a valid speed",
                    msg.payload,
                    msg.topic,
                )
                return

            if not self._implemented_percentage:
                if speed in self._speeds_list:
                    self._percentage = ordered_list_item_to_percentage(
                        self._speeds_list, speed)
                elif speed == SPEED_OFF:
                    self._percentage = 0

            self.async_write_ha_state()
Esempio n. 7
0
    async def set_state(self, data: RequestData, state: dict[str, Any]):
        """Set device state."""
        yandex_mode = state['value']

        if self.modes_map:
            ha_modes = self.modes_map.get(yandex_mode)
            if not ha_modes:
                raise SmartHomeError(
                    ERR_INVALID_VALUE,
                    f'Unsupported mode "{yandex_mode}" for {self.instance} instance of {self.state.entity_id}. '
                    f'Check \"modes\" setting for this entity')

            ha_mode = self._convert_mapping_speed_value(ha_modes[0])
        else:
            ha_mode = ordered_list_item_to_percentage(self.supported_ha_modes,
                                                      yandex_mode)

        await self.hass.services.async_call(
            fan.DOMAIN,
            fan.SERVICE_SET_PERCENTAGE, {
                ATTR_ENTITY_ID: self.state.entity_id,
                fan.ATTR_PERCENTAGE: ha_mode
            },
            blocking=True,
            context=data.context)
Esempio n. 8
0
File: fan.py Progetto: jcgoette/core
class WiLightFan(WiLightDevice, FanEntity):
    """Representation of a WiLights fan."""

    _attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.DIRECTION

    def __init__(self, api_device, index, item_name):
        """Initialize the device."""
        super().__init__(api_device, index, item_name)
        # Initialize the WiLights fan.
        self._direction = WL_DIRECTION_FORWARD

    @property
    def icon(self):
        """Return the icon of device based on its type."""
        return "mdi:fan"

    @property
    def is_on(self):
        """Return true if device is on."""
        return self._status.get("direction",
                                WL_DIRECTION_OFF) != WL_DIRECTION_OFF

    @property
    def percentage(self) -> int | None:
        """Return the current speed percentage."""
        if ("direction" in self._status
                and self._status["direction"] == WL_DIRECTION_OFF):
            return 0

        if (wl_speed := self._status.get("speed")) is None:
            return None
        return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS,
                                               wl_speed)
Esempio n. 9
0
def cvt_battery(val: int | None) -> int | None:
    """Convert battery to percentage."""
    if val is None:
        return None
    if val > 0:
        return percentage.ordered_list_item_to_percentage([1, 2, 3, 4], val)
    return 0
Esempio n. 10
0
File: fan.py Progetto: wwtlong/core
    async def async_set_preset_mode(self, preset_mode: str) -> None:
        """Set the preset mode of the fan.

        This method is a coroutine.
        """
        if preset_mode not in self.preset_modes:
            _LOGGER.warning("'%s'is not a valid preset mode", preset_mode)
            return
        # Legacy are deprecated in the schema, support will be removed after a quarter (2021.7)
        if preset_mode in self._legacy_speeds_list:
            await self.async_set_speed(speed=preset_mode)
        if not self._implemented_percentage and preset_mode in self.speed_list:
            self._percentage = ordered_list_item_to_percentage(
                self.speed_list, preset_mode)
        mqtt_payload = self._command_templates[ATTR_PRESET_MODE](preset_mode)

        mqtt.async_publish(
            self.hass,
            self._topic[CONF_PRESET_MODE_COMMAND_TOPIC],
            mqtt_payload,
            self._config[CONF_QOS],
            self._config[CONF_RETAIN],
        )

        if self._optimistic_preset_mode:
            self._preset_mode = preset_mode
        self.async_write_ha_state()
Esempio n. 11
0
    def speed_to_percentage(self, speed: str) -> int:
        """
        Map a speed to a percentage.

        Officially this should only have to deal with the 4 pre-defined speeds:

        return {
            SPEED_OFF: 0,
            SPEED_LOW: 33,
            SPEED_MEDIUM: 66,
            SPEED_HIGH: 100,
        }[speed]

        Unfortunately lots of fans make up their own speeds. So the default
        mapping is more dynamic.
        """
        if speed in OFF_SPEED_VALUES:
            return 0

        speed_list = self._speed_list_without_preset_modes

        if speed_list and speed not in speed_list:
            raise NotValidSpeedError(
                f"The speed {speed} is not a valid speed.")

        try:
            return ordered_list_item_to_percentage(speed_list, speed)
        except ValueError as ex:
            raise NoValidSpeedsError(
                f"The speed_list {speed_list} does not contain any valid speeds."
            ) from ex
Esempio n. 12
0
    def percentage(self) -> int:
        """Return the current percentage."""

        if self._fan_speed != "0":
            percentage = ordered_list_item_to_percentage(
                self._speed_names, self._fan_speed)
            return percentage
Esempio n. 13
0
 def percentage(self) -> Optional[int]:
     """Return the current speed."""
     if not self.is_on:
         return 0
     if self.speeds is None:
         return None
     return ordered_list_item_to_percentage(self.speeds, self._tuya.speed())
Esempio n. 14
0
    async def async_turn_on(self, percentage: int = None, **kwargs):
        """Turn on the fan."""
        if percentage is None:
            percentage = ordered_list_item_to_percentage(
                self._speed_list, self._last_on_speed or self._speed_list[0])

        await self.async_set_percentage(percentage)
Esempio n. 15
0
 def percentage(self) -> int | None:
     """Return the current speed percentage."""
     if self._device.speed == 0:
         return 0
     if self._device.speed not in ORDERED_NAMED_FAN_SPEEDS:
         return None
     return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS,
                                            self._device.speed)
Esempio n. 16
0
 def speed_to_percentage(self, speed: str) -> int:  # pylint: disable=no-self-use
     """Map a legacy speed to a percentage."""
     if speed in OFF_SPEED_VALUES:
         return 0
     if speed not in LEGACY_SPEED_LIST:
         raise NotValidSpeedError(
             f"The speed {speed} is not a valid speed.")
     return ordered_list_item_to_percentage(LEGACY_SPEED_LIST, speed)
Esempio n. 17
0
 def percentage(self) -> Optional[int]:
     """Return the current speed percentage."""
     if self._device["fan_speed"] is None:
         return None
     if self._device["fan_speed"] == FAN_OFF:
         return 0
     return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS,
                                            self._device["fan_speed"])
Esempio n. 18
0
 async def async_turn_on(self,
                         speed=None,
                         percentage=None,
                         preset_mode=None,
                         **kwargs):
     """Turn the fan on."""
     # Tasmota does not support turning a fan on with implicit speed
     await self.async_set_percentage(
         percentage or ordered_list_item_to_percentage(
             ORDERED_NAMED_FAN_SPEEDS, tasmota_const.FAN_SPEED_MEDIUM))
Esempio n. 19
0
 def percentage(self) -> str:
     """Return the current speed percentage."""
     if "direction" in self._status:
         if self._status["direction"] == WL_DIRECTION_OFF:
             return 0
     wl_speed = self._status.get("speed")
     if wl_speed is None:
         return None
     return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS,
                                            wl_speed)
Esempio n. 20
0
 def percentage(self) -> int | None:
     """Return the current speed percentage."""
     if not self._api.state.is_on:
         return 0
     if self.speed_count == 0:
         return 100
     if self._api.state.fan_speed is None:
         return None
     return ordered_list_item_to_percentage(self._device.fan_speeds,
                                            self._api.state.fan_speed)
Esempio n. 21
0
 def percentage(self):
     """Return the current speed as a percentage."""
     if self._prop_percentage:
         val = self._prop_percentage.from_dict(self._state_attrs)
         if val is not None:
             return val
     lst = [v for v in self.speed_list if v not in OFF_SPEED_VALUES]
     try:
         return ordered_list_item_to_percentage(lst, self.speed)
     except ValueError:
         return None
Esempio n. 22
0
    def percentage(self) -> int | None:
        """Return the current speed percentage."""
        if not self._static_info.supports_speed:
            return None

        if not self._supports_speed_levels:
            return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS,
                                                   self._state.speed)

        return ranged_value_to_percentage(
            (1, self._static_info.supported_speed_levels),
            self._state.speed_level)
Esempio n. 23
0
File: fan.py Progetto: iprak/winix
 def percentage(self) -> Union[int, None]:
     """Return the current speed percentage."""
     state = self._wrapper.get_state()
     if state is None:
         return None
     elif self._wrapper.is_sleep or self._wrapper.is_auto:
         return None
     elif state.get(ATTR_AIRFLOW) is None:
         return None
     else:
         return ordered_list_item_to_percentage(
             ORDERED_NAMED_FAN_SPEEDS, state.get(ATTR_AIRFLOW)
         )
Esempio n. 24
0
    def speed_to_percentage(self, speed: str) -> int:
        """Convert speed to percentage.

        Legacy fan support.
        """
        if speed == SPEED_OFF:
            return 0

        if speed not in LEGACY_SPEED_TO_DECONZ:
            speed = SPEED_MEDIUM

        return ordered_list_item_to_percentage(ORDERED_NAMED_FAN_SPEEDS,
                                               LEGACY_SPEED_TO_DECONZ[speed])
Esempio n. 25
0
    def percentage(self) -> int:
        """Return the current speed."""
        if not self.is_on:
            return 0

        if self.tuya_device.category == "kj":
            if self.air_purifier_speed_range_len > 1:
                if not self.air_purifier_speed_range_enum:
                    # if air-purifier speed enumeration is supported we will prefer it.
                    return ordered_list_item_to_percentage(
                        self.air_purifier_speed_range_enum,
                        self.tuya_device.status.get(DPCODE_AP_FAN_SPEED_ENUM,
                                                    0))

        return self.tuya_device.status.get(DPCODE_FAN_SPEED, 0)
Esempio n. 26
0
    def percentage(self) -> int | None:
        """Return the current speed."""
        if not self.is_on:
            return 0

        if (self.tuya_device.category == "kj"
                and self.air_purifier_speed_range_len > 1
                and not self.air_purifier_speed_range_enum
                and DPCODE_AP_FAN_SPEED_ENUM in self.tuya_device.status):
            # if air-purifier speed enumeration is supported we will prefer it.
            return ordered_list_item_to_percentage(
                self.air_purifier_speed_range_enum,
                self.tuya_device.status[DPCODE_AP_FAN_SPEED_ENUM],
            )

        # some type may not have the fan_speed_percent key
        return self.tuya_device.status.get(DPCODE_FAN_SPEED)
Esempio n. 27
0
File: fan.py Progetto: wwtlong/core
        def preset_mode_received(msg):
            """Handle new received MQTT message for preset mode."""
            preset_mode = self._value_templates[ATTR_PRESET_MODE](msg.payload)
            if preset_mode not in self.preset_modes:
                _LOGGER.warning(
                    "'%s' received on topic %s is not a valid preset mode",
                    msg.payload,
                    msg.topic,
                )
                return

            self._preset_mode = preset_mode
            if not self._implemented_percentage and (preset_mode
                                                     in self.speed_list):
                self._percentage = ordered_list_item_to_percentage(
                    self.speed_list, preset_mode)
            self.async_write_ha_state()
Esempio n. 28
0
    def _update_from_device_data(self, data: State | None) -> None:
        """Handle data update."""
        if not data:
            self._percentage = 0
            return

        if data.fan_speed:
            self._percentage = ordered_list_item_to_percentage(
                ORDERED_NAMED_FAN_SPEEDS, str(data.fan_speed))
        else:
            self._percentage = 0

        if data.after_cooking_on:
            if data.after_cooking_fan_speed:
                self._preset_mode = PRESET_MODE_AFTER_COOKING_MANUAL
            else:
                self._preset_mode = PRESET_MODE_AFTER_COOKING_AUTO
        else:
            self._preset_mode = PRESET_MODE_NORMAL
Esempio n. 29
0
 def turn_on(self, speed=None, percentage=None, preset_mode=None, **kwargs):
     ret = False
     if not self.is_on:
         ret = self.set_property(self._prop_power.full_name, True)
     if self._prop_percentage:
         if not percentage and speed:
             percentage = ordered_list_item_to_percentage(self.speed_list, speed)
         if percentage:
             ret = self.set_property(self._prop_percentage.full_name, percentage)
     elif self._prop_speed:
         if not speed and percentage:
             speed = percentage_to_ordered_list_item(self.speed_list, percentage)
         val = self._prop_speed.list_first(speed) if speed else None
         if val is not None:
             ret = self.set_property(self._prop_speed.full_name, val)
     if preset_mode and self._prop_mode:
         val = self._prop_mode.list_first(preset_mode)
         if val is not None:
             ret = self.set_property(self._prop_mode.full_name, val)
     return ret
Esempio n. 30
0
    def status_updated(self):
        """Get state of Tuya fan."""
        self._is_on = self.dps(self._dp_id)

        current_speed = self.dps_conf(CONF_FAN_SPEED_CONTROL)
        if self._use_ordered_list:
            _LOGGER.debug(
                "Fan current_speed ordered_list_item_to_percentage: %s from %s",
                current_speed,
                self._ordered_list,
            )
            if current_speed is not None:
                self._percentage = ordered_list_item_to_percentage(
                    self._ordered_list, current_speed)

        else:
            _LOGGER.debug(
                "Fan current_speed ranged_value_to_percentage: %s from %s",
                current_speed,
                self._speed_range,
            )
            if current_speed is not None:
                self._percentage = ranged_value_to_percentage(
                    self._speed_range, int(current_speed))

        _LOGGER.debug("Fan current_percentage: %s", self._percentage)

        if self.has_config(CONF_FAN_OSCILLATING_CONTROL):
            self._oscillating = self.dps_conf(CONF_FAN_OSCILLATING_CONTROL)
            _LOGGER.debug("Fan current_oscillating : %s", self._oscillating)

        if self.has_config(CONF_FAN_DIRECTION):
            value = self.dps_conf(CONF_FAN_DIRECTION)
            if value is not None:
                if value == self._config.get(CONF_FAN_DIRECTION_FWD):
                    self._direction = DIRECTION_FORWARD

                if value == self._config.get(CONF_FAN_DIRECTION_REV):
                    self._direction = DIRECTION_REVERSE
            _LOGGER.debug("Fan current_direction : %s > %s", value,
                          self._direction)