Initialize docker stack repo
This commit is contained in:
261
homeassistant/config/custom_components/yandex_pogoda/const.py
Normal file
261
homeassistant/config/custom_components/yandex_pogoda/const.py
Normal file
@@ -0,0 +1,261 @@
|
||||
"""General constants."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import logging
|
||||
import pickle
|
||||
import zlib
|
||||
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_WEATHER_TEMPERATURE_UNIT,
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT,
|
||||
UNIT_CONVERSIONS,
|
||||
)
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.helpers import selector
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DOMAIN = "yandex_pogoda"
|
||||
DEFAULT_NAME = "Yandex Pogoda"
|
||||
ATTRIBUTION = "Data provided by Yandex Pogoda"
|
||||
MANUFACTURER = "Yandex"
|
||||
ENTRY_NAME = "name"
|
||||
UPDATER = "updater"
|
||||
|
||||
ATTR_API_TEMPERATURE = "temperature"
|
||||
ATTR_API_TEMPERATURE_MAX = "maxTemperature"
|
||||
ATTR_API_TEMPERATURE_MIN = "minTemperature"
|
||||
ATTR_API_FEELS_LIKE_TEMPERATURE = "feelsLike"
|
||||
ATTR_API_WIND_SPEED = "windSpeed"
|
||||
ATTR_API_WIND_BEARING = "windAngle"
|
||||
ATTR_API_DAYTIME = "daytime"
|
||||
ATTR_API_CONDITION = "condition"
|
||||
ATTR_API_IMAGE = "icon"
|
||||
ATTR_API_POLAR = "polar"
|
||||
ATTR_API_SERVER_TIME = "serverTime"
|
||||
ATTR_API_TIME = "time"
|
||||
ATTR_API_SUNRISE_BEGIN_TIME = "sunriseTime"
|
||||
ATTR_API_SUNRISE_END_TIME = "sunsetTime"
|
||||
ATTR_API_YA_CONDITION = "yandex_condition"
|
||||
ATTR_API_WIND_GUST = "windGust"
|
||||
|
||||
ATTR_FORECAST_DATA = "forecast"
|
||||
ATTR_FORECAST_DATA_COMPRESSED = "forecast_compressed"
|
||||
ATTR_FORECAST_HOURLY = "hourly"
|
||||
ATTR_FORECAST_HOURLY_ICONS = "forecast_hourly_icons"
|
||||
ATTR_FORECAST_TWICE_DAILY = "twice_daily"
|
||||
ATTR_FORECAST_TWICE_DAILY_ICONS = "forecast_twice_daily_icons"
|
||||
|
||||
ATTR_MIN_FORECAST_TEMPERATURE = "min_forecast_temperature"
|
||||
ATTR_WIND_INTERCARDINAL_DIRECTION = "wind_intercardinal"
|
||||
|
||||
UPDATE_LISTENER = "update_listener"
|
||||
PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
|
||||
|
||||
YA_CONDITIONS = [
|
||||
"CLEAR",
|
||||
"PARTLY_CLOUDY",
|
||||
"CLOUDY",
|
||||
"OVERCAST",
|
||||
"LIGHT_RAIN",
|
||||
"RAIN",
|
||||
"HEAVY_RAIN",
|
||||
"SHOWERS",
|
||||
"SLEET",
|
||||
"LIGHT_SNOW",
|
||||
"SNOW",
|
||||
"SNOWFALL",
|
||||
"HAIL",
|
||||
"THUNDERSTORM",
|
||||
"THUNDERSTORM_WITH_RAIN",
|
||||
"THUNDERSTORM_WITH_HAIL",
|
||||
]
|
||||
YA_CONDITION_STATE_MAP = {i: i.lower() for i in YA_CONDITIONS}
|
||||
"""Mapping for yandex states"""
|
||||
|
||||
YA_CONDITION_STATES = list(YA_CONDITION_STATE_MAP.values())
|
||||
|
||||
WEATHER_STATES_CONVERSION = {
|
||||
"CLEAR": {
|
||||
"day": "sunny",
|
||||
"night": "clear-night",
|
||||
},
|
||||
"PARTLY_CLOUDY": "partlycloudy",
|
||||
"CLOUDY": "cloudy",
|
||||
"OVERCAST": "cloudy",
|
||||
"LIGHT_RAIN": "rainy",
|
||||
"RAIN": "rainy",
|
||||
"HEAVY_RAIN": "pouring",
|
||||
"SHOWERS": "pouring",
|
||||
"SLEET": "snowy-rainy",
|
||||
"LIGHT_SNOW": "snowy",
|
||||
"SNOW": "snowy",
|
||||
"SNOWFALL": "snowy",
|
||||
"HAIL": "hail",
|
||||
"THUNDERSTORM": "lightning",
|
||||
"THUNDERSTORM_WITH_RAIN": "lightning-rainy",
|
||||
"THUNDERSTORM_WITH_HAIL": "lightning-rainy",
|
||||
}
|
||||
"""Map rich Yandex weather condition to ordinary HA"""
|
||||
|
||||
HA_WEATHER_STATES = [
|
||||
i for i in WEATHER_STATES_CONVERSION.values() if isinstance(i, str)
|
||||
] + list(WEATHER_STATES_CONVERSION["CLEAR"].values())
|
||||
|
||||
CONDITION_ICONS = {
|
||||
"CLEAR": {
|
||||
"day": "mdi:weather-sunny",
|
||||
"night": "mdi:weather-night",
|
||||
},
|
||||
"PARTLY_CLOUDY": {
|
||||
"day": "mdi:weather-partly-cloudy",
|
||||
"night": "mdi:weather-night-partly-cloudy",
|
||||
},
|
||||
"CLOUDY": "mdi:weather-cloudy",
|
||||
"OVERCAST": "mdi:weather-cloudy",
|
||||
"LIGHT_RAIN": "mdi:weather-rainy",
|
||||
"RAIN": "mdi:weather-rainy",
|
||||
"HEAVY_RAIN": "mdi:weather-pouring",
|
||||
"SHOWERS": "mdi:weather-pouring",
|
||||
"SLEET": "mdi:weather-snowy-rainy",
|
||||
"LIGHT_SNOW": "mdi:weather-snowy",
|
||||
"SNOW": "mdi:weather-snowy",
|
||||
"SNOWFALL": "mdi:weather-snowy-heavy",
|
||||
"HAIL": "mdi:weather-hail",
|
||||
"THUNDERSTORM": "mdi:weather-lightning",
|
||||
"THUNDERSTORM_WITH_RAIN": "mdi:weather-lightning-rainy",
|
||||
"THUNDERSTORM_WITH_HAIL": "mdi:weather-lightning-rainy",
|
||||
}
|
||||
"""Mapping for state icon"""
|
||||
|
||||
|
||||
TEMPERATURE_CONVERTER = UNIT_CONVERSIONS[ATTR_WEATHER_TEMPERATURE_UNIT]
|
||||
WIND_SPEED_CONVERTER = UNIT_CONVERSIONS[ATTR_WEATHER_WIND_SPEED_UNIT]
|
||||
|
||||
DEFAULT_UPDATES_PER_DAY = "standard"
|
||||
UPDATES_PER_DAY_MAP = {
|
||||
"rare": 6,
|
||||
"standard": 12,
|
||||
"often": 24,
|
||||
}
|
||||
UPDATES_PER_DAY = "updates_per_day"
|
||||
UPDATES_PER_DAY_SELECTOR = selector.SelectSelector(
|
||||
selector.SelectSelectorConfig(
|
||||
options=["rare", "standard", "often"],
|
||||
mode=selector.SelectSelectorMode.DROPDOWN,
|
||||
translation_key=UPDATES_PER_DAY,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def convert_unit_value(
|
||||
converter: Callable[[float, str, str], float],
|
||||
val: float | None,
|
||||
unit_from: str | None,
|
||||
unit_to: str | None,
|
||||
) -> float | None:
|
||||
"""Weather factor unit converter."""
|
||||
if val is not None and unit_from and unit_to:
|
||||
return converter(val, unit_from, unit_to)
|
||||
return None
|
||||
|
||||
|
||||
def map_state(src: str, is_day: bool, mapping: dict | None = None) -> str:
|
||||
"""Map weather condition based on WEATHER_STATES_CONVERSION.
|
||||
|
||||
:param src: str: Yandex weather state
|
||||
:param is_day: bool: Is it day? Used for icons
|
||||
:param mapping: use this dict for mapping
|
||||
:return: str: Home Assistant weather state
|
||||
"""
|
||||
if mapping is None:
|
||||
mapping = {}
|
||||
|
||||
try:
|
||||
result: str | dict[str, str] = mapping[src]
|
||||
except KeyError:
|
||||
result = src
|
||||
|
||||
if type(result) is dict:
|
||||
return result["day" if is_day else "night"]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_wind_intercardinal_direction(wind_direction_degree: int) -> str:
|
||||
"""Convert wind direction degree to named direction."""
|
||||
|
||||
if wind_direction_degree < 0 or wind_direction_degree > 360:
|
||||
_LOGGER.error("Angle should be in [0, 360] range")
|
||||
|
||||
if wind_direction_degree <= 22.5:
|
||||
return "n"
|
||||
|
||||
if wind_direction_degree <= 67.5:
|
||||
return "ne"
|
||||
|
||||
if wind_direction_degree <= 112.5:
|
||||
return "e"
|
||||
|
||||
if wind_direction_degree <= 157.5:
|
||||
return "se"
|
||||
|
||||
if wind_direction_degree <= 202.5:
|
||||
return "s"
|
||||
|
||||
if wind_direction_degree <= 247.5:
|
||||
return "sw"
|
||||
|
||||
if wind_direction_degree <= 292.5:
|
||||
return "w"
|
||||
|
||||
if wind_direction_degree <= 337.5:
|
||||
return "nw"
|
||||
|
||||
return "n"
|
||||
|
||||
|
||||
def compress_data(data: dict) -> str:
|
||||
"""Compress dict to string."""
|
||||
return base64.b64encode(zlib.compress(pickle.dumps(data))).decode("utf-8")
|
||||
|
||||
|
||||
def decompress_data(compressed: str | None) -> dict:
|
||||
"""Compress dict to string."""
|
||||
if not compressed:
|
||||
return {}
|
||||
|
||||
try:
|
||||
return pickle.loads(zlib.decompress(base64.b64decode(compressed)))
|
||||
except TypeError: # for backward compatibility
|
||||
return {}
|
||||
|
||||
|
||||
def is_daytime(
|
||||
hour: datetime,
|
||||
day: datetime,
|
||||
sunrise_begin: datetime,
|
||||
sunset_end: datetime,
|
||||
polar: str,
|
||||
) -> bool:
|
||||
"""returns whether it is daytime for a given hour of the day"""
|
||||
|
||||
if polar:
|
||||
if day == sunrise_begin and day == sunset_end:
|
||||
return polar == "DAY"
|
||||
|
||||
if day == sunrise_begin:
|
||||
return hour < sunset_end
|
||||
|
||||
if day == sunset_end:
|
||||
return hour >= sunrise_begin
|
||||
|
||||
if sunrise_begin <= sunset_end:
|
||||
return hour >= sunrise_begin and hour < sunset_end
|
||||
else:
|
||||
return hour < sunset_end or hour >= sunrise_begin
|
||||
Reference in New Issue
Block a user