def test_convert_invalid_unit():
    """Test exception is thrown for invalid units."""
    with pytest.raises(ValueError):
        temperature_util.convert(5, INVALID_SYMBOL, VALID_SYMBOL)

    with pytest.raises(ValueError):
        temperature_util.convert(5, VALID_SYMBOL, INVALID_SYMBOL)
Ejemplo n.º 2
0
    async def execute(self, command, params):
        """Execute a temperature point or mode command."""
        # All sent in temperatures are always in Celsius
        unit = self.hass.config.units.temperature_unit
        min_temp = self.state.attributes[climate.ATTR_MIN_TEMP]
        max_temp = self.state.attributes[climate.ATTR_MAX_TEMP]

        if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT:
            temp = temp_util.convert(params['thermostatTemperatureSetpoint'],
                                     TEMP_CELSIUS, unit)

            if temp < min_temp or temp > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Temperature should be between {} and {}".format(min_temp,
                                                                     max_temp))

            await self.hass.services.async_call(
                climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    climate.ATTR_TEMPERATURE: temp
                }, blocking=True)

        elif command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE:
            temp_high = temp_util.convert(
                params['thermostatTemperatureSetpointHigh'], TEMP_CELSIUS,
                unit)

            if temp_high < min_temp or temp_high > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Upper bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            temp_low = temp_util.convert(
                params['thermostatTemperatureSetpointLow'], TEMP_CELSIUS, unit)

            if temp_low < min_temp or temp_low > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Lower bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            await self.hass.services.async_call(
                climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    climate.ATTR_TARGET_TEMP_HIGH: temp_high,
                    climate.ATTR_TARGET_TEMP_LOW: temp_low,
                }, blocking=True)

        elif command == COMMAND_THERMOSTAT_SET_MODE:
            await self.hass.services.async_call(
                climate.DOMAIN, climate.SERVICE_SET_OPERATION_MODE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    climate.ATTR_OPERATION_MODE:
                        self.google_to_hass[params['thermostatMode']],
                }, blocking=True)
Ejemplo n.º 3
0
    def query_attributes(self):
        """Return temperature point and modes query attributes."""
        attrs = self.state.attributes
        response = {}

        operation = attrs.get(climate.ATTR_OPERATION_MODE)
        supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)

        if (supported & climate.SUPPORT_ON_OFF
                and self.state.state == STATE_OFF):
            response['thermostatMode'] = 'off'
        elif (supported & climate.SUPPORT_OPERATION_MODE and
              operation in self.hass_to_google):
            response['thermostatMode'] = self.hass_to_google[operation]
        elif supported & climate.SUPPORT_ON_OFF:
            response['thermostatMode'] = 'on'

        unit = self.hass.config.units.temperature_unit

        current_temp = attrs.get(climate.ATTR_CURRENT_TEMPERATURE)
        if current_temp is not None:
            response['thermostatTemperatureAmbient'] = \
                round(temp_util.convert(current_temp, unit, TEMP_CELSIUS), 1)

        current_humidity = attrs.get(climate.ATTR_CURRENT_HUMIDITY)
        if current_humidity is not None:
            response['thermostatHumidityAmbient'] = current_humidity

        if operation == climate.STATE_AUTO:
            if (supported & climate.SUPPORT_TARGET_TEMPERATURE_HIGH and
                    supported & climate.SUPPORT_TARGET_TEMPERATURE_LOW):
                response['thermostatTemperatureSetpointHigh'] = \
                    round(temp_util.convert(
                        attrs[climate.ATTR_TARGET_TEMP_HIGH],
                        unit, TEMP_CELSIUS), 1)
                response['thermostatTemperatureSetpointLow'] = \
                    round(temp_util.convert(
                        attrs[climate.ATTR_TARGET_TEMP_LOW],
                        unit, TEMP_CELSIUS), 1)
            else:
                target_temp = attrs.get(ATTR_TEMPERATURE)
                if target_temp is not None:
                    target_temp = round(
                        temp_util.convert(target_temp, unit, TEMP_CELSIUS), 1)
                    response['thermostatTemperatureSetpointHigh'] = target_temp
                    response['thermostatTemperatureSetpointLow'] = target_temp
        else:
            target_temp = attrs.get(ATTR_TEMPERATURE)
            if target_temp is not None:
                response['thermostatTemperatureSetpoint'] = round(
                    temp_util.convert(target_temp, unit, TEMP_CELSIUS), 1)

        return response
def test_convert_from_celsius():
    """Test conversion from C to other units."""
    celsius = 100
    assert temperature_util.convert(celsius, TEMP_CELSIUS,
                                    TEMP_FAHRENHEIT) == pytest.approx(212.0)
    assert temperature_util.convert(celsius, TEMP_CELSIUS,
                                    TEMP_KELVIN) == pytest.approx(373.15)
    # Interval
    assert temperature_util.convert(celsius, TEMP_CELSIUS, TEMP_FAHRENHEIT,
                                    True) == pytest.approx(180.0)
    assert temperature_util.convert(celsius, TEMP_CELSIUS, TEMP_KELVIN,
                                    True) == pytest.approx(100)
Ejemplo n.º 5
0
    def query_attributes(self):
        """Return temperature point and modes query attributes."""
        attrs = self.state.attributes
        response = {}

        operation = attrs.get(climate.ATTR_OPERATION_MODE)
        supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)

        if (supported & climate.SUPPORT_ON_OFF
                and self.state.state == STATE_OFF):
            response['thermostatMode'] = 'off'
        elif (supported & climate.SUPPORT_OPERATION_MODE
              and operation in self.hass_to_google):
            response['thermostatMode'] = self.hass_to_google[operation]
        elif supported & climate.SUPPORT_ON_OFF:
            response['thermostatMode'] = 'on'

        unit = self.hass.config.units.temperature_unit

        current_temp = attrs.get(climate.ATTR_CURRENT_TEMPERATURE)
        if current_temp is not None:
            response['thermostatTemperatureAmbient'] = \
                round(temp_util.convert(current_temp, unit, TEMP_CELSIUS), 1)

        current_humidity = attrs.get(climate.ATTR_CURRENT_HUMIDITY)
        if current_humidity is not None:
            response['thermostatHumidityAmbient'] = current_humidity

        if operation == climate.STATE_AUTO:
            if (supported & climate.SUPPORT_TARGET_TEMPERATURE_HIGH
                    and supported & climate.SUPPORT_TARGET_TEMPERATURE_LOW):
                response['thermostatTemperatureSetpointHigh'] = \
                    round(temp_util.convert(
                        attrs[climate.ATTR_TARGET_TEMP_HIGH],
                        unit, TEMP_CELSIUS), 1)
                response['thermostatTemperatureSetpointLow'] = \
                    round(temp_util.convert(
                        attrs[climate.ATTR_TARGET_TEMP_LOW],
                        unit, TEMP_CELSIUS), 1)
            else:
                target_temp = attrs.get(ATTR_TEMPERATURE)
                if target_temp is not None:
                    target_temp = round(
                        temp_util.convert(target_temp, unit, TEMP_CELSIUS), 1)
                    response['thermostatTemperatureSetpointHigh'] = target_temp
                    response['thermostatTemperatureSetpointLow'] = target_temp
        else:
            target_temp = attrs.get(ATTR_TEMPERATURE)
            if target_temp is not None:
                response['thermostatTemperatureSetpoint'] = round(
                    temp_util.convert(target_temp, unit, TEMP_CELSIUS), 1)

        return response
def test_convert_from_kelvin():
    """Test conversion from K to other units."""
    kelvin = 100
    assert temperature_util.convert(kelvin, TEMP_KELVIN,
                                    TEMP_CELSIUS) == pytest.approx(-173.15)
    assert temperature_util.convert(
        kelvin, TEMP_KELVIN,
        TEMP_FAHRENHEIT) == pytest.approx(-279.66999999999996)
    # Interval
    assert temperature_util.convert(kelvin, TEMP_KELVIN, TEMP_FAHRENHEIT,
                                    True) == pytest.approx(180.0)
    assert temperature_util.convert(kelvin, TEMP_KELVIN, TEMP_KELVIN,
                                    True) == pytest.approx(100)
def test_convert_from_fahrenheit():
    """Test conversion from F to other units."""
    fahrenheit = 100
    assert temperature_util.convert(
        fahrenheit, TEMP_FAHRENHEIT,
        TEMP_CELSIUS) == pytest.approx(37.77777777777778)
    assert temperature_util.convert(
        fahrenheit, TEMP_FAHRENHEIT,
        TEMP_KELVIN) == pytest.approx(310.92777777777775)
    # Interval
    assert temperature_util.convert(fahrenheit, TEMP_FAHRENHEIT, TEMP_CELSIUS,
                                    True) == pytest.approx(55.55555555555556)
    assert temperature_util.convert(fahrenheit, TEMP_FAHRENHEIT, TEMP_KELVIN,
                                    True) == pytest.approx(55.55555555555556)
Ejemplo n.º 8
0
    def temperature(self, temperature: float, from_unit: str) -> float:
        """Convert the given temperature to this unit system."""
        if not isinstance(temperature, Number):
            raise TypeError(f"{temperature!s} is not a numeric value.")

        return temperature_util.convert(temperature, from_unit,
                                        self.temperature_unit)
Ejemplo n.º 9
0
    def temperature(self, temperature: float, from_unit: str) -> float:
        """Convert the given temperature to this unit system."""
        if not isinstance(temperature, Number):
            raise TypeError(
                '{} is not a numeric value.'.format(str(temperature)))

        return temperature_util.convert(temperature,
                                        from_unit, self.temperature_unit)
Ejemplo n.º 10
0
    def temperature(self: object, temperature: float, from_unit: str) -> float:
        """Convert the given temperature to this unit system."""
        if not isinstance(temperature, Number):
            raise TypeError('{} is not a numeric value.'.format(
                str(temperature)))

        return temperature_util.convert(temperature, from_unit,
                                        self.temperature_unit)
Ejemplo n.º 11
0
    def create_vacation(self, service_data):
        """Create a vacation with user-specified parameters."""
        vacation_name = service_data[ATTR_VACATION_NAME]
        cool_temp = convert(
            service_data[ATTR_COOL_TEMP],
            self.hass.config.units.temperature_unit,
            TEMP_FAHRENHEIT,
        )
        heat_temp = convert(
            service_data[ATTR_HEAT_TEMP],
            self.hass.config.units.temperature_unit,
            TEMP_FAHRENHEIT,
        )
        start_date = service_data.get(ATTR_START_DATE)
        start_time = service_data.get(ATTR_START_TIME)
        end_date = service_data.get(ATTR_END_DATE)
        end_time = service_data.get(ATTR_END_TIME)
        fan_mode = service_data[ATTR_FAN_MODE]
        fan_min_on_time = service_data[ATTR_FAN_MIN_ON_TIME]

        kwargs = {
            key: value
            for key, value in {
                "start_date": start_date,
                "start_time": start_time,
                "end_date": end_date,
                "end_time": end_time,
                "fan_mode": fan_mode,
                "fan_min_on_time": fan_min_on_time,
            }.items()
            if value is not None
        }

        _LOGGER.debug(
            "Creating a vacation on thermostat %s with name %s, cool temp %s, heat temp %s, "
            "and the following other parameters: %s",
            self.name,
            vacation_name,
            cool_temp,
            heat_temp,
            kwargs,
        )
        self.data.ecobee.create_vacation(
            self.thermostat_index, vacation_name, cool_temp, heat_temp, **kwargs
        )
Ejemplo n.º 12
0
    def temperature(self, temperature: float, from_unit: str) -> float:
        """Convert the given temperature to this unit system."""
        if not isinstance(temperature, Number):
            raise TypeError("{} is not a numeric value.".format(str(temperature)))

        # type ignore: https://github.com/python/mypy/issues/7207
        return temperature_util.convert(  # type: ignore
            temperature, from_unit, self.temperature_unit
        )
Ejemplo n.º 13
0
    def temperature_set_service(service):
        """Set temperature on the target thermostats."""
        target_thermostats = component.extract_from_service(service)

        temperature = service.data[ATTR_TEMPERATURE]

        for thermostat in target_thermostats:
            converted_temperature = convert(
                temperature, hass.config.units.temperature_unit,
                thermostat.unit_of_measurement)

            thermostat.set_temperature(converted_temperature)
            thermostat.update_ha_state(True)
Ejemplo n.º 14
0
    def temperature_set_service(service):
        """Set temperature on the target thermostats."""
        target_thermostats = component.extract_from_service(service)

        temperature = service.data[ATTR_TEMPERATURE]

        for thermostat in target_thermostats:
            converted_temperature = convert(temperature,
                                            hass.config.units.temperature_unit,
                                            thermostat.unit_of_measurement)

            thermostat.set_temperature(converted_temperature)
            thermostat.update_ha_state(True)
Ejemplo n.º 15
0
    def query_attributes(self):
        """Return temperature point and modes query attributes."""
        attrs = self.state.attributes
        response = {}

        operation = attrs.get(climate.ATTR_OPERATION_MODE)
        if operation is not None and operation in self.hass_to_google:
            response['thermostatMode'] = self.hass_to_google[operation]

        unit = self.hass.config.units.temperature_unit

        current_temp = attrs.get(climate.ATTR_CURRENT_TEMPERATURE)
        if current_temp is not None:
            response['thermostatTemperatureAmbient'] = \
                round(temp_util.convert(current_temp, unit, TEMP_CELSIUS), 1)

        current_humidity = attrs.get(climate.ATTR_CURRENT_HUMIDITY)
        if current_humidity is not None:
            response['thermostatHumidityAmbient'] = current_humidity

        if (operation == climate.STATE_AUTO and
                climate.ATTR_TARGET_TEMP_HIGH in attrs and
                climate.ATTR_TARGET_TEMP_LOW in attrs):
            response['thermostatTemperatureSetpointHigh'] = \
                round(temp_util.convert(attrs[climate.ATTR_TARGET_TEMP_HIGH],
                                        unit, TEMP_CELSIUS), 1)
            response['thermostatTemperatureSetpointLow'] = \
                round(temp_util.convert(attrs[climate.ATTR_TARGET_TEMP_LOW],
                                        unit, TEMP_CELSIUS), 1)
        else:
            target_temp = attrs.get(climate.ATTR_TEMPERATURE)
            if target_temp is not None:
                response['thermostatTemperatureSetpoint'] = round(
                    temp_util.convert(target_temp, unit, TEMP_CELSIUS), 1)

        return response
Ejemplo n.º 16
0
    async def async_set_smart_mode(
        self,
        auto_comfort: str = None,
        cool_temp: float = None,
        cool_min_speed: int = None,
        cool_max_speed: int = None,
    ) -> None:
        """Configure smart_mode settings"""
        if auto_comfort is not None:
            self._device.fan_smartmode = auto_comfort.upper()

        if cool_temp is not None:
            self._device.fan_cooltemp = convert(
                cool_temp,
                self.hass.config.units.temperature_unit,
                TEMP_CELSIUS,
            )

        if cool_min_speed is not None:
            self._device.fan_coolminspeed = cool_min_speed

        if cool_max_speed is not None:
            self._device.fan_coolmaxspeed = cool_max_speed
Ejemplo n.º 17
0
 def max_temp(self):
     """Return the maximum temperature - 30.5 means on."""
     return convert(30.5, TEMP_CELSIUS, self.unit_of_measurement)
Ejemplo n.º 18
0
 def min_temp(self):
     """Return the minimum temperature - 4.5 means off."""
     return convert(4.5, TEMP_CELSIUS, self.unit_of_measurement)
Ejemplo n.º 19
0
def temperature_to_homekit(temperature: float | int, unit: str) -> float:
    """Convert temperature to Celsius for HomeKit."""
    return round(temp_util.convert(temperature, unit, TEMP_CELSIUS), 1)
Ejemplo n.º 20
0
def temperature_to_states(temperature: float | int, unit: str) -> float:
    """Convert temperature back from Celsius to Home Assistant unit."""
    return round(temp_util.convert(temperature, TEMP_CELSIUS, unit) * 2) / 2
Ejemplo n.º 21
0
STATISTICS_BAKERY = "recorder_statistics_bakery"
STATISTICS_META_BAKERY = "recorder_statistics_meta_bakery"
STATISTICS_SHORT_TERM_BAKERY = "recorder_statistics_short_term_bakery"


# Convert pressure and temperature statistics from the native unit used for statistics
# to the units configured by the user
UNIT_CONVERSIONS = {
    PRESSURE_PA: lambda x, units: pressure_util.convert(
        x, PRESSURE_PA, units.pressure_unit
    )
    if x is not None
    else None,
    TEMP_CELSIUS: lambda x, units: temperature_util.convert(
        x, TEMP_CELSIUS, units.temperature_unit
    )
    if x is not None
    else None,
    VOLUME_CUBIC_METERS: lambda x, units: volume_util.convert(
        x, VOLUME_CUBIC_METERS, _configured_unit(VOLUME_CUBIC_METERS, units)
    )
    if x is not None
    else None,
}

_LOGGER = logging.getLogger(__name__)


def split_statistic_id(entity_id: str) -> list[str]:
    """Split a state entity ID into domain and object ID."""
Ejemplo n.º 22
0
 def max_temp(self):
     """Return the maximum temperature."""
     return convert(self._thermostat.max_temp, TEMP_CELSIUS,
                    self.unit_of_measurement)
Ejemplo n.º 23
0
 def max_temp(self):
     """Return the maximum temperature."""
     return convert(self._thermostat.max_temp, TEMP_CELSIUS,
                    self.unit_of_measurement)
Ejemplo n.º 24
0
def temperature_to_homekit(temperature, unit):
    """Convert temperature to Celsius for HomeKit."""
    return round(temp_util.convert(temperature, unit, TEMP_CELSIUS), 1)
Ejemplo n.º 25
0
    def query_attributes(self):
        """Return temperature point and modes query attributes."""
        response = {}
        attrs = self.state.attributes
        domain = self.state.domain
        unit = self.hass.config.units.temperature_unit
        if domain == sensor.DOMAIN:
            device_class = attrs.get(ATTR_DEVICE_CLASS)
            if device_class == sensor.DEVICE_CLASS_TEMPERATURE:
                current_temp = self.state.state
                if current_temp is not None:
                    response["thermostatTemperatureAmbient"] = round(
                        temp_util.convert(float(current_temp), unit,
                                          TEMP_CELSIUS), 1)

        elif domain == climate.DOMAIN:
            operation = self.state.state
            preset = attrs.get(climate.ATTR_PRESET_MODE)
            supported = attrs.get(ATTR_SUPPORTED_FEATURES, 0)

            if preset in self.preset_to_google:
                response["thermostatMode"] = self.preset_to_google[preset]
            else:
                response["thermostatMode"] = self.hvac_to_google.get(operation)

            current_temp = attrs.get(climate.ATTR_CURRENT_TEMPERATURE)
            if current_temp is not None:
                response["thermostatTemperatureAmbient"] = round(
                    temp_util.convert(current_temp, unit, TEMP_CELSIUS), 1)

            current_humidity = attrs.get(climate.ATTR_CURRENT_HUMIDITY)
            if current_humidity is not None:
                response["thermostatHumidityAmbient"] = current_humidity

            if operation in (climate.HVAC_MODE_AUTO,
                             climate.HVAC_MODE_HEAT_COOL):
                if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
                    response["thermostatTemperatureSetpointHigh"] = round(
                        temp_util.convert(attrs[climate.ATTR_TARGET_TEMP_HIGH],
                                          unit, TEMP_CELSIUS),
                        1,
                    )
                    response["thermostatTemperatureSetpointLow"] = round(
                        temp_util.convert(attrs[climate.ATTR_TARGET_TEMP_LOW],
                                          unit, TEMP_CELSIUS),
                        1,
                    )
                else:
                    target_temp = attrs.get(ATTR_TEMPERATURE)
                    if target_temp is not None:
                        target_temp = round(
                            temp_util.convert(target_temp, unit, TEMP_CELSIUS),
                            1)
                        response[
                            "thermostatTemperatureSetpointHigh"] = target_temp
                        response[
                            "thermostatTemperatureSetpointLow"] = target_temp
            else:
                target_temp = attrs.get(ATTR_TEMPERATURE)
                if target_temp is not None:
                    response["thermostatTemperatureSetpoint"] = round(
                        temp_util.convert(target_temp, unit, TEMP_CELSIUS), 1)

        return response
Ejemplo n.º 26
0
def temperature_to_homekit(temperature, unit):
    """Convert temperature to Celsius for HomeKit."""
    return round(temp_util.convert(temperature, unit, TEMP_CELSIUS), 1)
Ejemplo n.º 27
0
 def max_temp(self):
     """Return the maximum temperature - 30.5 means on."""
     return convert(30.5, TEMP_CELSIUS, self.unit_of_measurement)
Ejemplo n.º 28
0
 def min_temp(self):
     """Return the minimum temperature - 4.5 means off."""
     return convert(4.5, TEMP_CELSIUS, self.unit_of_measurement)
Ejemplo n.º 29
0
def temperature_to_states(temperature, unit):
    """Convert temperature back from Celsius to Home Assistant unit."""
    return round(temp_util.convert(temperature, TEMP_CELSIUS, unit), 1)
def test_convert_nonnumeric_value():
    """Test exception is thrown for nonnumeric type."""
    with pytest.raises(TypeError):
        temperature_util.convert("a", TEMP_CELSIUS, TEMP_FAHRENHEIT)
Ejemplo n.º 31
0
    StatisticsMeta.id,
    StatisticsMeta.statistic_id,
]

STATISTICS_BAKERY = "recorder_statistics_bakery"
STATISTICS_META_BAKERY = "recorder_statistics_meta_bakery"
STATISTICS_SHORT_TERM_BAKERY = "recorder_statistics_short_term_bakery"

# Convert pressure and temperature statistics from the native unit used for statistics
# to the units configured by the user
UNIT_CONVERSIONS = {
    PRESSURE_PA:
    lambda x, units: pressure_util.convert(x, PRESSURE_PA, units.pressure_unit)
    if x is not None else None,
    TEMP_CELSIUS:
    lambda x, units: temperature_util.convert(
        x, TEMP_CELSIUS, units.temperature_unit) if x is not None else None,
    VOLUME_CUBIC_METERS:
    lambda x, units: volume_util.convert(
        x, VOLUME_CUBIC_METERS, _configured_unit(VOLUME_CUBIC_METERS, units))
    if x is not None else None,
}

_LOGGER = logging.getLogger(__name__)


def split_statistic_id(entity_id: str) -> list[str]:
    """Split a state entity ID into domain and object ID."""
    return entity_id.split(":", 1)


VALID_STATISTIC_ID = re.compile(
Ejemplo n.º 32
0
def temperature_to_states(temperature, unit):
    """Convert temperature back from Celsius to Home Assistant unit."""
    return round(temp_util.convert(temperature, TEMP_CELSIUS, unit), 1)
Ejemplo n.º 33
0
    async def execute(self, command, data, params, challenge):
        """Execute a temperature point or mode command."""
        domain = self.state.domain
        if domain == sensor.DOMAIN:
            raise SmartHomeError(ERR_NOT_SUPPORTED,
                                 "Execute is not supported by sensor")

        # All sent in temperatures are always in Celsius
        unit = self.hass.config.units.temperature_unit
        min_temp = self.state.attributes[climate.ATTR_MIN_TEMP]
        max_temp = self.state.attributes[climate.ATTR_MAX_TEMP]

        if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT:
            temp = temp_util.convert(params["thermostatTemperatureSetpoint"],
                                     TEMP_CELSIUS, unit)
            if unit == TEMP_FAHRENHEIT:
                temp = round(temp)

            if temp < min_temp or temp > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Temperature should be between {} and {}".format(
                        min_temp, max_temp),
                )

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_TEMPERATURE,
                {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    ATTR_TEMPERATURE: temp
                },
                blocking=True,
                context=data.context,
            )

        elif command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE:
            temp_high = temp_util.convert(
                params["thermostatTemperatureSetpointHigh"], TEMP_CELSIUS,
                unit)
            if unit == TEMP_FAHRENHEIT:
                temp_high = round(temp_high)

            if temp_high < min_temp or temp_high > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Upper bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp),
                )

            temp_low = temp_util.convert(
                params["thermostatTemperatureSetpointLow"], TEMP_CELSIUS, unit)
            if unit == TEMP_FAHRENHEIT:
                temp_low = round(temp_low)

            if temp_low < min_temp or temp_low > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Lower bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp),
                )

            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
            svc_data = {ATTR_ENTITY_ID: self.state.entity_id}

            if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
                svc_data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
                svc_data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
            else:
                svc_data[ATTR_TEMPERATURE] = (temp_high + temp_low) / 2

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_TEMPERATURE,
                svc_data,
                blocking=True,
                context=data.context,
            )

        elif command == COMMAND_THERMOSTAT_SET_MODE:
            target_mode = params["thermostatMode"]
            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)

            if target_mode == "on":
                await self.hass.services.async_call(
                    climate.DOMAIN,
                    SERVICE_TURN_ON,
                    {ATTR_ENTITY_ID: self.state.entity_id},
                    blocking=True,
                    context=data.context,
                )
                return

            if target_mode == "off":
                await self.hass.services.async_call(
                    climate.DOMAIN,
                    SERVICE_TURN_OFF,
                    {ATTR_ENTITY_ID: self.state.entity_id},
                    blocking=True,
                    context=data.context,
                )
                return

            if target_mode in self.google_to_preset:
                await self.hass.services.async_call(
                    climate.DOMAIN,
                    climate.SERVICE_SET_PRESET_MODE,
                    {
                        climate.ATTR_PRESET_MODE:
                        self.google_to_preset[target_mode],
                        ATTR_ENTITY_ID:
                        self.state.entity_id,
                    },
                    blocking=True,
                    context=data.context,
                )
                return

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_HVAC_MODE,
                {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    climate.ATTR_HVAC_MODE: self.google_to_hvac[target_mode],
                },
                blocking=True,
                context=data.context,
            )
Ejemplo n.º 34
0
    async def execute(self, command, data, params):
        """Execute a temperature point or mode command."""
        # All sent in temperatures are always in Celsius
        unit = self.hass.config.units.temperature_unit
        min_temp = self.state.attributes[climate.ATTR_MIN_TEMP]
        max_temp = self.state.attributes[climate.ATTR_MAX_TEMP]

        if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT:
            temp = temp_util.convert(
                params['thermostatTemperatureSetpoint'], TEMP_CELSIUS,
                unit)
            if unit == TEMP_FAHRENHEIT:
                temp = round(temp)

            if temp < min_temp or temp > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Temperature should be between {} and {}".format(min_temp,
                                                                     max_temp))

            await self.hass.services.async_call(
                climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    ATTR_TEMPERATURE: temp
                }, blocking=True, context=data.context)

        elif command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE:
            temp_high = temp_util.convert(
                params['thermostatTemperatureSetpointHigh'], TEMP_CELSIUS,
                unit)
            if unit == TEMP_FAHRENHEIT:
                temp_high = round(temp_high)

            if temp_high < min_temp or temp_high > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Upper bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            temp_low = temp_util.convert(
                params['thermostatTemperatureSetpointLow'], TEMP_CELSIUS,
                unit)
            if unit == TEMP_FAHRENHEIT:
                temp_low = round(temp_low)

            if temp_low < min_temp or temp_low > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Lower bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
            svc_data = {
                ATTR_ENTITY_ID: self.state.entity_id,
            }

            if(supported & climate.SUPPORT_TARGET_TEMPERATURE_HIGH and
               supported & climate.SUPPORT_TARGET_TEMPERATURE_LOW):
                svc_data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
                svc_data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
            else:
                svc_data[ATTR_TEMPERATURE] = (temp_high + temp_low) / 2

            await self.hass.services.async_call(
                climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE, svc_data,
                blocking=True, context=data.context)

        elif command == COMMAND_THERMOSTAT_SET_MODE:
            target_mode = params['thermostatMode']
            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)

            if (target_mode in [STATE_ON, STATE_OFF] and
                    supported & climate.SUPPORT_ON_OFF):
                await self.hass.services.async_call(
                    climate.DOMAIN,
                    (SERVICE_TURN_ON
                     if target_mode == STATE_ON
                     else SERVICE_TURN_OFF),
                    {ATTR_ENTITY_ID: self.state.entity_id},
                    blocking=True, context=data.context)
            elif supported & climate.SUPPORT_OPERATION_MODE:
                await self.hass.services.async_call(
                    climate.DOMAIN, climate.SERVICE_SET_OPERATION_MODE, {
                        ATTR_ENTITY_ID: self.state.entity_id,
                        climate.ATTR_OPERATION_MODE:
                            self.google_to_hass[target_mode],
                    }, blocking=True, context=data.context)
Ejemplo n.º 35
0
def temperature_to_states(temperature, unit):
    """Convert temperature back from Celsius to Safegate Pro unit."""
    return round(temp_util.convert(temperature, TEMP_CELSIUS, unit) * 2) / 2
def test_convert_same_unit():
    """Test conversion from any unit to same unit."""
    assert temperature_util.convert(2, TEMP_CELSIUS, TEMP_CELSIUS) == 2
    assert temperature_util.convert(3, TEMP_FAHRENHEIT, TEMP_FAHRENHEIT) == 3
    assert temperature_util.convert(4, TEMP_KELVIN, TEMP_KELVIN) == 4
Ejemplo n.º 37
0
    async def execute(self, command, data, params):
        """Execute a temperature point or mode command."""
        # All sent in temperatures are always in Celsius
        unit = self.hass.config.units.temperature_unit
        min_temp = self.state.attributes[climate.ATTR_MIN_TEMP]
        max_temp = self.state.attributes[climate.ATTR_MAX_TEMP]

        if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT:
            temp = temp_util.convert(params['thermostatTemperatureSetpoint'],
                                     TEMP_CELSIUS, unit)
            if unit == TEMP_FAHRENHEIT:
                temp = round(temp)

            if temp < min_temp or temp > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Temperature should be between {} and {}".format(
                        min_temp, max_temp))

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_TEMPERATURE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    ATTR_TEMPERATURE: temp
                },
                blocking=True,
                context=data.context)

        elif command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE:
            temp_high = temp_util.convert(
                params['thermostatTemperatureSetpointHigh'], TEMP_CELSIUS,
                unit)
            if unit == TEMP_FAHRENHEIT:
                temp_high = round(temp_high)

            if temp_high < min_temp or temp_high > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Upper bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            temp_low = temp_util.convert(
                params['thermostatTemperatureSetpointLow'], TEMP_CELSIUS, unit)
            if unit == TEMP_FAHRENHEIT:
                temp_low = round(temp_low)

            if temp_low < min_temp or temp_low > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Lower bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
            svc_data = {
                ATTR_ENTITY_ID: self.state.entity_id,
            }

            if (supported & climate.SUPPORT_TARGET_TEMPERATURE_HIGH
                    and supported & climate.SUPPORT_TARGET_TEMPERATURE_LOW):
                svc_data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
                svc_data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
            else:
                svc_data[ATTR_TEMPERATURE] = (temp_high + temp_low) / 2

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_TEMPERATURE,
                svc_data,
                blocking=True,
                context=data.context)

        elif command == COMMAND_THERMOSTAT_SET_MODE:
            target_mode = params['thermostatMode']
            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)

            if (target_mode in [STATE_ON, STATE_OFF]
                    and supported & climate.SUPPORT_ON_OFF):
                await self.hass.services.async_call(
                    climate.DOMAIN, (SERVICE_TURN_ON if target_mode == STATE_ON
                                     else SERVICE_TURN_OFF),
                    {ATTR_ENTITY_ID: self.state.entity_id},
                    blocking=True,
                    context=data.context)
            elif supported & climate.SUPPORT_OPERATION_MODE:
                await self.hass.services.async_call(
                    climate.DOMAIN,
                    climate.SERVICE_SET_OPERATION_MODE, {
                        ATTR_ENTITY_ID:
                        self.state.entity_id,
                        climate.ATTR_OPERATION_MODE:
                        self.google_to_hass[target_mode],
                    },
                    blocking=True,
                    context=data.context)
Ejemplo n.º 38
0
    async def execute(self, command, data, params, challenge):
        """Execute a temperature point or mode command."""
        domain = self.state.domain
        if domain == sensor.DOMAIN:
            raise SmartHomeError(ERR_NOT_SUPPORTED,
                                 'Execute is not supported by sensor')

        # All sent in temperatures are always in Celsius
        unit = self.hass.config.units.temperature_unit
        min_temp = self.state.attributes[climate.ATTR_MIN_TEMP]
        max_temp = self.state.attributes[climate.ATTR_MAX_TEMP]

        if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT:
            temp = temp_util.convert(params['thermostatTemperatureSetpoint'],
                                     TEMP_CELSIUS, unit)
            if unit == TEMP_FAHRENHEIT:
                temp = round(temp)

            if temp < min_temp or temp > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Temperature should be between {} and {}".format(
                        min_temp, max_temp))

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_TEMPERATURE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    ATTR_TEMPERATURE: temp
                },
                blocking=True,
                context=data.context)

        elif command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE:
            temp_high = temp_util.convert(
                params['thermostatTemperatureSetpointHigh'], TEMP_CELSIUS,
                unit)
            if unit == TEMP_FAHRENHEIT:
                temp_high = round(temp_high)

            if temp_high < min_temp or temp_high > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Upper bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            temp_low = temp_util.convert(
                params['thermostatTemperatureSetpointLow'], TEMP_CELSIUS, unit)
            if unit == TEMP_FAHRENHEIT:
                temp_low = round(temp_low)

            if temp_low < min_temp or temp_low > max_temp:
                raise SmartHomeError(
                    ERR_VALUE_OUT_OF_RANGE,
                    "Lower bound for temperature range should be between "
                    "{} and {}".format(min_temp, max_temp))

            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
            svc_data = {
                ATTR_ENTITY_ID: self.state.entity_id,
            }

            if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
                svc_data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
                svc_data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
            else:
                svc_data[ATTR_TEMPERATURE] = (temp_high + temp_low) / 2

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_TEMPERATURE,
                svc_data,
                blocking=True,
                context=data.context)

        elif command == COMMAND_THERMOSTAT_SET_MODE:
            target_mode = params['thermostatMode']
            supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)

            if target_mode in self.google_to_preset:
                await self.hass.services.async_call(
                    climate.DOMAIN,
                    climate.SERVICE_SET_PRESET_MODE, {
                        climate.ATTR_PRESET_MODE:
                        self.google_to_preset[target_mode],
                        ATTR_ENTITY_ID:
                        self.state.entity_id
                    },
                    blocking=True,
                    context=data.context)
                return

            if target_mode == 'on':
                # When targetting 'on', we're going to try best effort.
                modes = [
                    m for m in self.climate_google_modes
                    if m != climate.HVAC_MODE_OFF
                ]

                if len(modes) == 1:
                    target_mode = modes[0]
                elif 'auto' in modes:
                    target_mode = 'auto'
                elif 'heatcool' in modes:
                    target_mode = 'heatcool'
                else:
                    raise SmartHomeError(
                        ERR_FUNCTION_NOT_SUPPORTED,
                        "Unable to translate 'on' to a HVAC mode.")

            await self.hass.services.async_call(
                climate.DOMAIN,
                climate.SERVICE_SET_HVAC_MODE, {
                    ATTR_ENTITY_ID: self.state.entity_id,
                    climate.ATTR_HVAC_MODE: self.google_to_hvac[target_mode],
                },
                blocking=True,
                context=data.context)