1- """The Flatlib Natal Chart integration."""
1+ # __init__.py
22import logging
3- from datetime import timedelta
3+ from datetime import timedelta , datetime
4+ import pytz
5+
46from homeassistant .config_entries import ConfigEntry
57from homeassistant .core import HomeAssistant
68from homeassistant .helpers .aiohttp_client import async_get_clientsession
79from homeassistant .helpers .update_coordinator import DataUpdateCoordinator , UpdateFailed
8- from .const import DOMAIN
10+
11+ from .const import DOMAIN , PLATFORMS
912from .api import ApiClient , ApiError
1013
1114_LOGGER = logging .getLogger (__name__ )
12- PLATFORMS = ["sensor" ]
15+
16+ DAILY_INTERVAL = timedelta (hours = 24 )
17+ MONTHLY_INTERVAL = timedelta (hours = 24 )
18+ YEARLY_INTERVAL = timedelta (hours = 24 )
19+
20+ def _convert_timezone_to_offset (tz_name : str ) -> str :
21+ """Преобразует имя часового пояса в строковое смещение UTC в формате +HH:MM."""
22+ try :
23+ tz_object = pytz .timezone (tz_name )
24+ offset_seconds = tz_object .utcoffset (datetime .now ()).total_seconds ()
25+
26+ offset_hours = int (offset_seconds / 3600 )
27+ offset_minutes = int ((offset_seconds % 3600 ) / 60 )
28+
29+ sign = "+" if offset_seconds >= 0 else "-"
30+
31+ return f"{ sign } { abs (offset_hours ):02d} :{ abs (offset_minutes ):02d} "
32+ except (pytz .UnknownTimeZoneError , AttributeError ):
33+ return "+00:00"
34+
35+ def _get_api_payload (entry : ConfigEntry ) -> dict :
36+ """Создает полезную нагрузку для запроса API из данных конфигурации."""
37+ converted_tz = _convert_timezone_to_offset (entry .data .get ("time_zone" ))
38+
39+ # Теперь отправляем дату в стандартном формате YYYY-MM-DD,
40+ # который Home Assistant возвращает и который, как показывает ошибка, ожидает сервер.
41+ birth_date_str = entry .data .get ("birth_date" )
42+
43+ return {
44+ "date" : birth_date_str , # Отправляем дату как есть (YYYY-MM-DD)
45+ "time" : entry .data .get ("birth_time" ),
46+ "tz" : converted_tz ,
47+ "lat" : entry .data .get ("location" , {}).get ("latitude" ),
48+ "lon" : entry .data .get ("location" , {}).get ("longitude" ),
49+ }
1350
1451async def async_setup_entry (hass : HomeAssistant , entry : ConfigEntry ) -> bool :
15- """Set up Flatlib Natal Chart from a config entry."""
16- # Используем общую сессию aiohttp, управляемую Home Assistant
52+ """Настройка интеграции Flatlib из записи конфигурации."""
1753 session = async_get_clientsession (hass )
1854 api_client = ApiClient (session )
19-
20- # --- ИСПРАВЛЕНИЕ: Получаем данные напрямую, без сложной обработки ---
21- entry_data = entry .data
22- _LOGGER .debug ("Setting up Flatlib Natal for: %s" , entry_data ["name" ])
2355
24- async def async_update_data ():
25- """Fetch data from the flatlib-server API."""
56+ async def async_update_natal_data ():
57+ """Получить данные натальной карты."""
58+ payload = _get_api_payload (entry )
2659 try :
27- location_data = entry .data ["location" ]
28- # --- ИСПРАВЛЕНИЕ: Корректно форматируем дату и время ---
29- payload = {
30- "date" : entry_data ["birth_date" ],
31- "time" : entry_data ["birth_time" ],
32- "tz" : entry_data ["time_zone" ],
33- "lat" : str (location_data ["latitude" ]),
34- "lon" : str (location_data ["longitude" ]),
35- }
36- _LOGGER .debug ("Sending payload to API: %s" , payload )
3760 return await api_client .get_natal_chart (payload )
3861 except ApiError as err :
39- raise UpdateFailed (f"Error communicating with API: { err } " )
40- except KeyError as err :
41- raise UpdateFailed (f"Missing data in config entry: { err } " )
62+ raise UpdateFailed (f"Ошибка получения натальной карты: { err } " )
4263
43- coordinator = DataUpdateCoordinator (
64+ natal_coordinator = DataUpdateCoordinator (
4465 hass ,
4566 _LOGGER ,
46- name = f"flatlib_natal_{ entry_data ['name' ]} " ,
47- update_method = async_update_data ,
48- update_interval = timedelta ( hours = 24 ), # Обновляем раз в сутки
67+ name = f"flatlib_natal_{ entry . data ['name' ]} " ,
68+ update_method = async_update_natal_data ,
69+ update_interval = DAILY_INTERVAL ,
4970 )
5071
51- # Выполняем первое обновление при запуске
52- await coordinator .async_config_entry_first_refresh ()
72+ async def async_update_daily_data ():
73+ """Получить данные ежедневного предсказания."""
74+ payload = _get_api_payload (entry )
75+ try :
76+ return await api_client .async_get_daily_prediction (payload )
77+ except ApiError as err :
78+ raise UpdateFailed (f"Ошибка получения ежедневного предсказания: { err } " )
5379
54- hass .data .setdefault (DOMAIN , {})
55- hass .data [DOMAIN ][entry .entry_id ] = coordinator
80+ daily_prediction_coordinator = DataUpdateCoordinator (
81+ hass ,
82+ _LOGGER ,
83+ name = f"flatlib_daily_prediction_{ entry .data ['name' ]} " ,
84+ update_method = async_update_daily_data ,
85+ update_interval = DAILY_INTERVAL ,
86+ )
87+
88+ async def async_update_monthly_data ():
89+ """Получить данные ежемесячного предсказания."""
90+ payload = _get_api_payload (entry )
91+ try :
92+ return await api_client .async_get_monthly_prediction (payload )
93+ except ApiError as err :
94+ raise UpdateFailed (f"Ошибка получения ежемесячного предсказания: { err } " )
5695
57- await hass .config_entries .async_forward_entry_setups (entry , PLATFORMS )
96+ monthly_prediction_coordinator = DataUpdateCoordinator (
97+ hass ,
98+ _LOGGER ,
99+ name = f"flatlib_monthly_prediction_{ entry .data ['name' ]} " ,
100+ update_method = async_update_monthly_data ,
101+ update_interval = MONTHLY_INTERVAL ,
102+ )
58103
104+ async def async_update_yearly_data ():
105+ """Получить данные ежегодного предсказания."""
106+ payload = _get_api_payload (entry )
107+ try :
108+ return await api_client .async_get_yearly_prediction (payload )
109+ except ApiError as err :
110+ raise UpdateFailed (f"Ошибка получения ежегодного предсказания: { err } " )
111+
112+ yearly_prediction_coordinator = DataUpdateCoordinator (
113+ hass ,
114+ _LOGGER ,
115+ name = f"flatlib_yearly_prediction_{ entry .data ['name' ]} " ,
116+ update_method = async_update_yearly_data ,
117+ update_interval = YEARLY_INTERVAL ,
118+ )
119+
120+ await natal_coordinator .async_config_entry_first_refresh ()
121+ await daily_prediction_coordinator .async_config_entry_first_refresh ()
122+ await monthly_prediction_coordinator .async_config_entry_first_refresh ()
123+ await yearly_prediction_coordinator .async_config_entry_first_refresh ()
124+
125+ hass .data .setdefault (DOMAIN , {})[entry .entry_id ] = {
126+ "natal_coordinator" : natal_coordinator ,
127+ "daily_prediction_coordinator" : daily_prediction_coordinator ,
128+ "monthly_prediction_coordinator" : monthly_prediction_coordinator ,
129+ "yearly_prediction_coordinator" : yearly_prediction_coordinator ,
130+ }
131+
132+ await hass .config_entries .async_forward_entry_setups (entry , PLATFORMS )
59133 return True
60134
61135async def async_unload_entry (hass : HomeAssistant , entry : ConfigEntry ) -> bool :
62- """Unload a config entry ."""
136+ """Выгрузить запись конфигурации ."""
63137 unload_ok = await hass .config_entries .async_unload_platforms (entry , PLATFORMS )
64138 if unload_ok :
65139 hass .data [DOMAIN ].pop (entry .entry_id )
66-
67140 return unload_ok
0 commit comments