Пример #1
0
    def _init_data(self):
        """Initialize a data object."""
        conf = self._config

        if self.track_home:
            latitude = self.hass.config.latitude
            longitude = self.hass.config.longitude
            elevation = self.hass.config.elevation
        else:
            latitude = conf[CONF_LATITUDE]
            longitude = conf[CONF_LONGITUDE]
            elevation = conf[CONF_ELEVATION]

        if not self._is_metric:
            elevation = int(
                round(convert_distance(elevation, LENGTH_FEET, LENGTH_METERS)))
        coordinates = {
            "lat": str(latitude),
            "lon": str(longitude),
            "msl": str(elevation),
        }
        self._weather_data = metno.MetWeatherData(
            coordinates, async_get_clientsession(self.hass), URL)
Пример #2
0
    "windDirection": 180,
    "visibility": 10000,
    "textDescription": "A long description",
    "station": "ABC",
    "timestamp": "2019-08-12T23:53:00+00:00",
    "iconTime": "day",
    "iconWeather": (("Fair/clear", None), ),
}

EXPECTED_OBSERVATION_IMPERIAL = {
    ATTR_WEATHER_TEMPERATURE:
    round(convert_temperature(10, TEMP_CELSIUS, TEMP_FAHRENHEIT)),
    ATTR_WEATHER_WIND_BEARING:
    180,
    ATTR_WEATHER_WIND_SPEED:
    round(convert_distance(10, LENGTH_METERS, LENGTH_MILES) * 3600),
    ATTR_WEATHER_PRESSURE:
    round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2),
    ATTR_WEATHER_VISIBILITY:
    round(convert_distance(10000, LENGTH_METERS, LENGTH_MILES)),
    ATTR_WEATHER_HUMIDITY:
    10,
}

EXPECTED_OBSERVATION_METRIC = {
    ATTR_WEATHER_TEMPERATURE:
    10,
    ATTR_WEATHER_WIND_BEARING:
    180,
    ATTR_WEATHER_WIND_SPEED:
    round(convert_distance(10, LENGTH_METERS, LENGTH_KILOMETERS) * 3600),
Пример #3
0
)
from homeassistant.util.pressure import convert as convert_pressure
from homeassistant.util.distance import convert as convert_distance
from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM
from homeassistant.util.temperature import convert as convert_temperature
from homeassistant.setup import async_setup_component

from tests.common import load_fixture, assert_setup_component

EXP_OBS_IMP = {
    ATTR_WEATHER_TEMPERATURE: round(
        convert_temperature(26.7, TEMP_CELSIUS, TEMP_FAHRENHEIT)
    ),
    ATTR_WEATHER_WIND_BEARING: 190,
    ATTR_WEATHER_WIND_SPEED: round(
        convert_distance(2.6, LENGTH_METERS, LENGTH_MILES) * 3600
    ),
    ATTR_WEATHER_PRESSURE: round(
        convert_pressure(101040, PRESSURE_PA, PRESSURE_INHG), 2
    ),
    ATTR_WEATHER_VISIBILITY: round(
        convert_distance(16090, LENGTH_METERS, LENGTH_MILES)
    ),
    ATTR_WEATHER_HUMIDITY: 64,
}

EXP_OBS_METR = {
    ATTR_WEATHER_TEMPERATURE: round(26.7),
    ATTR_WEATHER_WIND_BEARING: 190,
    ATTR_WEATHER_WIND_SPEED: round(
        convert_distance(2.6, LENGTH_METERS, LENGTH_KILOMETERS) * 3600
Пример #4
0
    "heatIndex": str(round(convert_temperature(15, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
    "relativeHumidity": "10",
    "windSpeed": str(
        round(convert_speed(10, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR))
    ),
    "windGust": str(
        round(convert_speed(20, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR))
    ),
    "windDirection": "180",
    "barometricPressure": str(
        round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2)
    ),
    "seaLevelPressure": str(
        round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2)
    ),
    "visibility": str(round(convert_distance(10000, LENGTH_METERS, LENGTH_MILES))),
}

WEATHER_EXPECTED_OBSERVATION_IMPERIAL = {
    ATTR_WEATHER_TEMPERATURE: round(
        convert_temperature(10, TEMP_CELSIUS, TEMP_FAHRENHEIT)
    ),
    ATTR_WEATHER_WIND_BEARING: 180,
    ATTR_WEATHER_WIND_SPEED: round(
        convert_speed(10, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR), 2
    ),
    ATTR_WEATHER_PRESSURE: round(
        convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2
    ),
    ATTR_WEATHER_VISIBILITY: round(
        convert_distance(10000, LENGTH_METERS, LENGTH_MILES), 2
Пример #5
0
    "visibility": "10000",
}

SENSOR_EXPECTED_OBSERVATION_IMPERIAL = {
    "dewpoint":
    str(round(convert_temperature(5, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
    "temperature":
    str(round(convert_temperature(10, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
    "windChill":
    str(round(convert_temperature(5, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
    "heatIndex":
    str(round(convert_temperature(15, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
    "relativeHumidity":
    "10",
    "windSpeed":
    str(round(convert_distance(10, LENGTH_KILOMETERS, LENGTH_MILES))),
    "windGust":
    str(round(convert_distance(20, LENGTH_KILOMETERS, LENGTH_MILES))),
    "windDirection":
    "180",
    "barometricPressure":
    str(round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2)),
    "seaLevelPressure":
    str(round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2)),
    "visibility":
    str(round(convert_distance(10000, LENGTH_METERS, LENGTH_MILES))),
}

WEATHER_EXPECTED_OBSERVATION_IMPERIAL = {
    ATTR_WEATHER_TEMPERATURE:
    round(convert_temperature(10, TEMP_CELSIUS, TEMP_FAHRENHEIT)),
Пример #6
0
async def test_backwards_compatibility_convert_values(
        hass: HomeAssistant, enable_custom_integrations) -> None:
    """Test backward compatibility for converting values."""
    wind_speed_value = 5
    wind_speed_unit = SPEED_METERS_PER_SECOND
    pressure_value = 110000
    pressure_unit = PRESSURE_PA
    temperature_value = 20
    temperature_unit = TEMP_CELSIUS
    visibility_value = 11
    visibility_unit = LENGTH_KILOMETERS
    precipitation_value = 1
    precipitation_unit = LENGTH_MILLIMETERS

    hass.config.units = IMPERIAL_SYSTEM

    platform: WeatherPlatform = getattr(hass.components, "test.weather")
    platform.init(empty=True)
    platform.ENTITIES.append(
        platform.MockWeatherMockForecastCompat(
            name="Test",
            condition=ATTR_CONDITION_SUNNY,
            temperature=temperature_value,
            temperature_unit=temperature_unit,
            wind_speed=wind_speed_value,
            wind_speed_unit=wind_speed_unit,
            pressure=pressure_value,
            pressure_unit=pressure_unit,
            visibility=visibility_value,
            visibility_unit=visibility_unit,
            precipitation=precipitation_value,
            precipitation_unit=precipitation_unit,
            unique_id="very_unique",
        ))

    entity0 = platform.ENTITIES[0]
    assert await async_setup_component(hass, "weather",
                                       {"weather": {
                                           "platform": "test"
                                       }})
    await hass.async_block_till_done()

    state = hass.states.get(entity0.entity_id)

    expected_wind_speed = round(
        convert_speed(wind_speed_value, wind_speed_unit, SPEED_MILES_PER_HOUR),
        ROUNDING_PRECISION,
    )
    expected_temperature = convert_temperature(temperature_value,
                                               temperature_unit,
                                               TEMP_FAHRENHEIT)
    expected_pressure = round(
        convert_pressure(pressure_value, pressure_unit, PRESSURE_INHG),
        ROUNDING_PRECISION,
    )
    expected_visibility = round(
        convert_distance(visibility_value, visibility_unit, LENGTH_MILES),
        ROUNDING_PRECISION,
    )
    expected_precipitation = round(
        convert_distance(precipitation_value, precipitation_unit,
                         LENGTH_INCHES),
        ROUNDING_PRECISION,
    )

    assert state.attributes == {
        ATTR_FORECAST: [{
            ATTR_FORECAST_PRECIPITATION:
            approx(expected_precipitation, rel=0.1),
            ATTR_FORECAST_PRESSURE:
            approx(expected_pressure, rel=0.1),
            ATTR_FORECAST_TEMP:
            approx(expected_temperature, rel=0.1),
            ATTR_FORECAST_TEMP_LOW:
            approx(expected_temperature, rel=0.1),
            ATTR_FORECAST_WIND_BEARING:
            None,
            ATTR_FORECAST_WIND_SPEED:
            approx(expected_wind_speed, rel=0.1),
        }],
        ATTR_FRIENDLY_NAME:
        "Test",
        ATTR_WEATHER_PRECIPITATION_UNIT:
        LENGTH_INCHES,
        ATTR_WEATHER_PRESSURE:
        approx(expected_pressure, rel=0.1),
        ATTR_WEATHER_PRESSURE_UNIT:
        PRESSURE_INHG,
        ATTR_WEATHER_TEMPERATURE:
        approx(expected_temperature, rel=0.1),
        ATTR_WEATHER_TEMPERATURE_UNIT:
        TEMP_FAHRENHEIT,
        ATTR_WEATHER_VISIBILITY:
        approx(expected_visibility, rel=0.1),
        ATTR_WEATHER_VISIBILITY_UNIT:
        LENGTH_MILES,
        ATTR_WEATHER_WIND_SPEED:
        approx(expected_wind_speed, rel=0.1),
        ATTR_WEATHER_WIND_SPEED_UNIT:
        SPEED_MILES_PER_HOUR,
    }
Пример #7
0
async def test_custom_units(hass: HomeAssistant,
                            enable_custom_integrations) -> None:
    """Test custom unit."""
    wind_speed_value = 5
    wind_speed_unit = SPEED_METERS_PER_SECOND
    pressure_value = 110
    pressure_unit = PRESSURE_HPA
    temperature_value = 20
    temperature_unit = TEMP_CELSIUS
    visibility_value = 11
    visibility_unit = LENGTH_KILOMETERS
    precipitation_value = 1.1
    precipitation_unit = LENGTH_MILLIMETERS

    set_options = {
        "wind_speed_unit": SPEED_MILES_PER_HOUR,
        "precipitation_unit": LENGTH_INCHES,
        "pressure_unit": PRESSURE_INHG,
        "temperature_unit": TEMP_FAHRENHEIT,
        "visibility_unit": LENGTH_MILES,
    }

    entity_registry = er.async_get(hass)

    entry = entity_registry.async_get_or_create("weather", "test",
                                                "very_unique")
    entity_registry.async_update_entity_options(entry.entity_id, "weather",
                                                set_options)
    await hass.async_block_till_done()

    platform: WeatherPlatform = getattr(hass.components, "test.weather")
    platform.init(empty=True)
    platform.ENTITIES.append(
        platform.MockWeatherMockForecast(
            name="Test",
            condition=ATTR_CONDITION_SUNNY,
            native_temperature=temperature_value,
            native_temperature_unit=temperature_unit,
            native_wind_speed=wind_speed_value,
            native_wind_speed_unit=wind_speed_unit,
            native_pressure=pressure_value,
            native_pressure_unit=pressure_unit,
            native_visibility=visibility_value,
            native_visibility_unit=visibility_unit,
            native_precipitation=precipitation_value,
            native_precipitation_unit=precipitation_unit,
            unique_id="very_unique",
        ))

    entity0 = platform.ENTITIES[0]
    assert await async_setup_component(hass, "weather",
                                       {"weather": {
                                           "platform": "test"
                                       }})
    await hass.async_block_till_done()

    state = hass.states.get(entity0.entity_id)
    forecast = state.attributes[ATTR_FORECAST][0]

    expected_wind_speed = round(
        convert_speed(wind_speed_value, wind_speed_unit, SPEED_MILES_PER_HOUR),
        ROUNDING_PRECISION,
    )
    expected_temperature = convert_temperature(temperature_value,
                                               temperature_unit,
                                               TEMP_FAHRENHEIT)
    expected_pressure = round(
        convert_pressure(pressure_value, pressure_unit, PRESSURE_INHG),
        ROUNDING_PRECISION,
    )
    expected_visibility = round(
        convert_distance(visibility_value, visibility_unit, LENGTH_MILES),
        ROUNDING_PRECISION,
    )
    expected_precipitation = round(
        convert_distance(precipitation_value, precipitation_unit,
                         LENGTH_INCHES),
        ROUNDING_PRECISION,
    )

    assert float(state.attributes[ATTR_WEATHER_WIND_SPEED]) == approx(
        expected_wind_speed)
    assert float(state.attributes[ATTR_WEATHER_TEMPERATURE]) == approx(
        expected_temperature, rel=0.1)
    assert float(
        state.attributes[ATTR_WEATHER_PRESSURE]) == approx(expected_pressure)
    assert float(state.attributes[ATTR_WEATHER_VISIBILITY]) == approx(
        expected_visibility)
    assert float(forecast[ATTR_FORECAST_PRECIPITATION]) == approx(
        expected_precipitation, rel=1e-2)

    assert (state.attributes[ATTR_WEATHER_PRECIPITATION_UNIT] ==
            set_options["precipitation_unit"])
    assert state.attributes[ATTR_WEATHER_PRESSURE_UNIT] == set_options[
        "pressure_unit"]
    assert (state.attributes[ATTR_WEATHER_TEMPERATURE_UNIT] ==
            set_options["temperature_unit"])
    assert (state.attributes[ATTR_WEATHER_VISIBILITY_UNIT] ==
            set_options["visibility_unit"])
    assert (state.attributes[ATTR_WEATHER_WIND_SPEED_UNIT] ==
            set_options["wind_speed_unit"])
Пример #8
0
    async def async_update(self, *_):
        """Get the latest data"""
        def try_again(err: str):
            """Retry"""
            _LOGGER.error("Will try again shortly: %s", err)
            async_call_later(self.hass, 2 * 60, self.async_update)

        try:
            websession = async_get_clientsession(self.hass)
            with async_timeout.timeout(10, loop=self.hass.loop):
                resp = await websession.get(self._url)
            if resp.status != 200:
                try_again('{} returned {}'.format(resp.url, resp.status))
                return
            text = await resp.text()

        except (asyncio.TimeoutError, aiohttp.ClientError) as err:
            try_again(err)
            return

        try:
            self.data = text.split(' ')

            if len(self.data) < 115:
                raise ValueError('Could not parse the file')
        except (ExpatError, IndexError) as err:
            try_again(err)
            return

        if not self.data:
            return

        # Update all devices
        tasks = []

        for dev in self.devices:
            new_state = None

            if dev.type == 'symbol':
                new_state = int(self.data[48])

            elif dev.type == 'daily_rain':
                rain = float(self.data[7])

                if not self.hass.config.units.is_metric:
                    rain = rain * 0.0393700787

                new_state = round(rain, 2)

            elif dev.type == 'rain_rate':
                rate = float(self.data[10])

                if not self.hass.config.units.is_metric:
                    rate = rate * 0.0393700787

                new_state = round(rate, 2)

            elif dev.type == 'temp':
                temperature = float(self.data[4])

                if not self.hass.config.units.is_metric:
                    temperature = convert_temperature(temperature,
                                                      TEMP_CELSIUS,
                                                      TEMP_FAHRENHEIT)

                new_state = round(temperature, 2)

            elif dev.type == 'wind_speed':
                speed = float(self.data[1])

                if self.hass.config.units.is_metric:
                    new_state = speed * 1.85166
                else:
                    new_state = speed * 1.1507794

                new_state = round(speed, 2)

            elif dev.type == 'wind_gust':
                gust = float(self.data[2])

                if self.hass.config.units.is_metric:
                    new_state = gust * 1.85166
                else:
                    new_state = gust * 1.1507794

                new_state = round(gust, 2)

            elif dev.type == 'pressure':
                pressure = float(self.data[6])

                if not self.hass.config.units.is_metric:
                    pressure = round(
                        convert_pressure(pressure, PRESSURE_HPA,
                                         PRESSURE_INHG), 2)

                new_state = round(pressure, 2)

            elif dev.type == 'wind_degrees':
                new_state = float(self.data[3])

            elif dev.type == 'wind_dir':
                direction = float(self.data[3])
                val = int((direction / 22.5) + .5)
                arr = [
                    "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S",
                    "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"
                ]
                new_state = arr[(val % 16)]

            elif dev.type == 'humidity':
                new_state = float(self.data[5])

            elif dev.type == 'cloud_height':
                height = float(self.data[73])

                if not self.hass.config.units.is_metric:
                    height = convert_distance(height, LENGTH_METERS,
                                              LENGTH_FEET)

                new_state = round(height, 2)

            elif dev.type == 'dewpoint':
                temperature = float(self.data[72])

                if not self.hass.config.units.is_metric:
                    temperature = convert_temperature(temperature,
                                                      TEMP_CELSIUS,
                                                      TEMP_FAHRENHEIT)

                new_state = round(temperature, 2)

            elif dev.type == 'heat_index':
                temperature = float(self.data[112])

                if not self.hass.config.units.is_metric:
                    temperature = convert_temperature(temperature,
                                                      TEMP_CELSIUS,
                                                      TEMP_FAHRENHEIT)

                new_state = round(temperature, 2)

            elif dev.type == 'humidex':
                temperature = float(self.data[44])

                if not self.hass.config.units.is_metric:
                    temperature = convert_temperature(temperature,
                                                      TEMP_CELSIUS,
                                                      TEMP_FAHRENHEIT)

                new_state = round(temperature, 2)

            elif dev.type == 'forecast':
                val = int(self.data[15])
                arr = [
                    "sunny", "clearnight", "cloudy", "cloudy2", "night cloudy",
                    "dry", "fog", "haze", "heavyrain", "mainlyfine", "mist",
                    "night fog", "night heavyrain", "night overcast",
                    "night rain", "night showers", "night snow", "night",
                    "thunder", "overcast", "partlycloudy", "rain", "rain2",
                    "showers2", "sleet", "sleetshowers", "snow", "snowmelt",
                    "snowshowers2", "sunny", "thundershowers",
                    "thundershowers2", "thunderstorms", "tornado", "windy",
                    "stopped", "rainning", "wind + rain"
                ]
                new_state = arr[(val)] if val < len(arr) else "unknown"

            _LOGGER.debug("%s %s", dev.type, new_state)

            # pylint: disable=protected-access
            if new_state != dev._state:
                dev._state = new_state
                tasks.append(dev.async_update_ha_state())

        if tasks:
            await asyncio.wait(tasks, loop=self.hass.loop)

        async_call_later(self.hass, self._interval * 60, self.async_update)
Пример #9
0
    "windDirection": 180,
    "visibility": 10000,
    "textDescription": "A long description",
    "station": "ABC",
    "timestamp": "2019-08-12T23:53:00+00:00",
    "iconTime": "day",
    "iconWeather": (("Fair/clear", None),),
}

EXPECTED_OBSERVATION_IMPERIAL = {
    ATTR_WEATHER_TEMPERATURE: round(
        convert_temperature(10, TEMP_CELSIUS, TEMP_FAHRENHEIT)
    ),
    ATTR_WEATHER_WIND_BEARING: 180,
    ATTR_WEATHER_WIND_SPEED: round(
        convert_distance(10, LENGTH_KILOMETERS, LENGTH_MILES)
    ),
    ATTR_WEATHER_PRESSURE: round(
        convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2
    ),
    ATTR_WEATHER_VISIBILITY: round(
        convert_distance(10000, LENGTH_METERS, LENGTH_MILES)
    ),
    ATTR_WEATHER_HUMIDITY: 10,
}

EXPECTED_OBSERVATION_METRIC = {
    ATTR_WEATHER_TEMPERATURE: 10,
    ATTR_WEATHER_WIND_BEARING: 180,
    ATTR_WEATHER_WIND_SPEED: 10,
    ATTR_WEATHER_PRESSURE: round(convert_pressure(100000, PRESSURE_PA, PRESSURE_HPA)),