diff --git a/src/lang-br.js b/src/lang-br.js new file mode 100644 index 0000000..3338067 --- /dev/null +++ b/src/lang-br.js @@ -0,0 +1,105 @@ +export default { + card: { + name: "Cartão de Posição Solar", + description: "Posição do Sol e da Lua com imagens personalizadas." + }, + error: { + no_sun_entity: "Por favor, defina uma entidade solar.", + entity_not_found: "Entidade não encontrada: " + }, + sun_state: { + below_horizon: "Abaixo do Horizonte", + dawn: "Amanhecer", + dusk: "Entardecer", + morning: "Manhã", + noon: "Meio-dia", + afternoon: "Tarde", + evening: "Noite" + }, + moon_phase: { + new_moon: 'Lua Nova', + waxing_crescent: 'Lua Crescente', + first_quarter: 'Quarto Crescente', + waxing_gibbous: 'Gibosa Crescente', + full_moon: 'Lua Cheia', + waning_gibbous: 'Gibosa Minguante', + last_quarter: 'Quarto Minguante', + waning_crescent: 'Lua Minguante' + }, + weather_state: { + 'clear-night': 'Noite Limpa', + 'cloudy': 'Nublado', + 'fog': 'Névoa', + 'hail': 'Granizo', + 'lightning': 'Raios', + 'lightning-rainy': 'Chuva com Raios', + 'partlycloudy': 'Parcialmente Nublado', + 'pouring': 'Chuva Forte', + 'rainy': 'Chuvoso', + 'snowy': 'Nevando', + 'snowy-rainy': 'Chuva e Neve', + 'sunny': 'Ensolarado', + 'windy': 'Ventania', + 'windy-variant': 'Vento Variável', + 'exceptional': 'Excepcional' + }, + time_entry: { + current: "Atual", + azimuth: "Azimute", + elevation: "Elevação", + daylight_duration: "Duração da Luz do Dia", + day_comparison: "Comparação de Luz Solar", + next_rising: "Nascer do Sol", + next_setting: "Pôr do Sol", + next_dawn: "Alvorecer", + next_dusk: "Crepúsculo", + next_noon: "Meio-dia solar", + next_midnight: "Meia-noite", + moon_phase: "Fase da Lua", + weather: "Clima" + }, + editor: { + entity: "Entidade Solar", + moon_entity: "Entidade Lunar (Opcional)", + weather_entity: "Entidade de Clima (Opcional)", + temp_entity: "Entidade de Temperatura (Opcional, substitui clima)", + main_options: "Opções de Exibição", + view_mode: "Modo de Visualização", + view_mode_classic: "Clássico (6 Imagens)", + view_mode_calculated: "Calculado (Apenas elevação)", + view_mode_arc: "Arco (Movimento 180°)", + show_image: "Mostrar Posição do Sol (Imagem)", + show_weather_badge: "Mostrar Badge de Clima", + animate_images: "Animar Imagens (exceto imagem de manhã/crepúsculo)", + sun_size: "Tamanho do Sol/Lua (Apenas Arco)", + state_position: "Posição do Estado", + state_pos_above: "Acima da Imagem", + state_pos_in_list: "Na Lista", + state_pos_hide: "Ocultar", + moon_phase_position: "Posição da Fase da Lua", + hide_moon_phase_on_day: "Ocultar Fase da Lua durante o dia", + show_night_arc: "Mostrar Arco da Lua (180°)", + show_moon_icon_in_text: "Mostrar Ícone da Lua no texto", + show_dividers: "Mostrar Divisores", + show_degrees: "Mostrar Graus (Azimute/Elevação)", + show_degrees_in_list: "Mostrar Graus na Lista", + time_position: "Posição do Horário", + time_pos_below: "Abaixo da Imagem", + time_pos_above: "Acima da Imagem", + time_pos_right: "À Direita da Imagem", + time_list_format: "Alinhamento da Lista de Horários", + time_format_centered: "Centralizado", + time_format_block: "Bloco", + times_to_show: "Selecionar Horários", + use_12h_format: "Usar formato 12 horas (AM/PM)", + language: "Idioma", + language_auto: "Automático (Home Assistant)", + solar_entity: "Entidade de Energia Solar (Opcional, ex: sensor de clima)", + show_solar_badge: "Mostrar Badge de Energia Solar", + advanced_options: "Limites (Avançado)", + morning_azimuth: "Azimute da Manhã", + noon_azimuth: "Azimute do Meio-dia", + afternoon_azimuth: "Azimute da Tarde", + dusk_elevation: "Elevação do Entardecer" + } +}; diff --git a/src/lang-es.js b/src/lang-es.js new file mode 100644 index 0000000..8247961 --- /dev/null +++ b/src/lang-es.js @@ -0,0 +1,105 @@ +export default { + card: { + name: "Sun Position Card", + description: "Posición del Sol y la Luna con imágenes personalizadas.", + }, + error: { + no_sun_entity: "Por favor, define una entidad de sol.", + entity_not_found: "Entidad no encontrada: ", + }, + sun_state: { + below_horizon: "Bajo el horizonte", + dawn: "Alba", + dusk: "Crepúsculo", + morning: "Mañana", + noon: "Mediodía", + afternoon: "Tarde", + evening: "Anochecer", + }, + moon_phase: { + new_moon: "Luna nueva", + waxing_crescent: "Luna creciente", + first_quarter: "Cuarto creciente", + waxing_gibbous: "Gibosa creciente", + full_moon: "Luna llena", + waning_gibbous: "Gibosa menguante", + last_quarter: "Cuarto menguante", + waning_crescent: "Luna menguante", + }, + weather_state: { + "clear-night": "Despejado (noche)", + cloudy: "Nublado", + fog: "Niebla", + hail: "Granizo", + lightning: "Relámpagos", + "lightning-rainy": "Tormenta eléctrica", + partlycloudy: "Parcialmente nublado", + pouring: "Lluvia intensa", + rainy: "Lluvia", + snowy: "Nieve", + snowy-rainy: "Nieve y lluvia", + sunny: "Soleado", + windy: "Ventoso", + "windy-variant": "Ventoso", + exceptional: "Excepcional", + }, + time_entry: { + current: "Actual", + azimuth: "Azimut", + elevation: "Elevación", + daylight_duration: "Duración de luz diurna", + day_comparison: "Comparativa del día", + next_rising: "Amanecer", + next_setting: "Atardecer", + next_dawn: "Alba", + next_dusk: "Crepúsculo", + next_noon: "Mediodía", + next_midnight: "Medianoche", + moon_phase: "Fase lunar", + weather: "Tiempo", + }, + editor: { + entity: "Entidad de Sol", + moon_entity: "Entidad de Luna (Opcional)", + weather_entity: "Entidad de Tiempo (Opcional)", + temp_entity: "Entidad de Temperatura (Opcional, anula el tiempo)", + main_options: "Opciones de visualización", + view_mode: "Modo de vista", + view_mode_classic: "Clásico (6 Imágenes)", + view_mode_calculated: "Calculado (Solo elevación)", + view_mode_arc: "Arco (Movimiento 180°)", + show_image: "Mostrar posición del sol (Imagen)", + show_weather_badge: "Mostrar insignia del tiempo", + animate_images: "Animar imágenes (excepto mañana/crepúsculo)", + sun_size: "Tamaño Sol/Luna (Solo en Arco)", + state_position: "Posición del estado", + state_pos_above: "Sobre la imagen", + state_pos_in_list: "En la lista", + state_pos_hide: "Ocultar", + moon_phase_position: "Posición de la fase lunar", + hide_moon_phase_on_day: "Ocultar fase lunar durante el día", + show_night_arc: "Mostrar arco lunar (180°)", + show_moon_icon_in_text: "Mostrar icono de la luna en el texto", + show_dividers: "Mostrar divisores", + show_degrees: "Mostrar grados (Azimut/Elevación)", + show_degrees_in_list: "Mostrar grados en la lista", + time_position: "Posición de la hora", + time_pos_below: "Bajo la imagen", + time_pos_above: "Sobre la imagen", + time_pos_right: "A la derecha de la imagen", + time_list_format: "Alineación de la lista de horas", + time_format_centered: "Centrado", + time_format_block: "Bloque", + times_to_show: "Seleccionar horas", + use_12h_format: "Usar formato 12h (AM/PM)", + language: "Idioma", + language_auto: "Automático (Home Assistant)", + solar_entity: "Entidad de energía solar (Opcional)", + show_solar_badge: "Mostrar insignia de energía solar", + advanced_options: "Umbrales (Avanzado)", + morning_azimuth: "Azimut de la mañana", + noon_azimuth: "Azimut del mediodía", + afternoon_azimuth: "Azimut de la tarde", + dusk_elevation: "Elevación del crepúsculo", + }, + }; diff --git a/src/lang-se.js b/src/lang-se.js new file mode 100644 index 0000000..dd01619 --- /dev/null +++ b/src/lang-se.js @@ -0,0 +1,105 @@ +export default { + card: { + name: "Solpositionskort", + description: "Solens och månens position med anpassade bilder." + }, + error: { + no_sun_entity: "Vänligen ange en sol-entitet.", + entity_not_found: "Entitet hittades inte: " + }, + sun_state: { + below_horizon: "Under horisonten", + dawn: "Gryning", + dusk: "Skymning", + morning: "Förmiddag", + noon: "Middag", + afternoon: "Eftermiddag", + evening: "Kväll" + }, + moon_phase: { + new_moon: 'Nymåne', + waxing_crescent: 'Tilltagande måne', + first_quarter: 'Första kvarteret', + waxing_gibbous: 'Tilltagande gibbös', + full_moon: 'Fullmåne', + waning_gibbous: 'Avtagande gibbös', + last_quarter: 'Sista kvarteret', + waning_crescent: 'Avtagande måne' + }, + weather_state: { + 'clear-night': 'Klar natt', + 'cloudy': 'Molnigt', + 'fog': 'Dimma', + 'hail': 'Hagel', + 'lightning': 'Åska', + 'lightning-rainy': 'Åska och regn', + 'partlycloudy': 'Delvis molnigt', + 'pouring': 'Skyfall', + 'rainy': 'Regnigt', + 'snowy': 'Snöigt', + 'snowy-rainy': 'Snö och regn', + 'sunny': 'Soligt', + 'windy': 'Blåsigt', + 'windy-variant': 'Blåsigt', + 'exceptional': 'Extremt' + }, + time_entry: { + current: "Nuvarande", + azimuth: "Azimut", + elevation: "Elevation", + daylight_duration: "Dagens längd", + day_comparison: "Jämförelse av dagslängd", + next_rising: "Soluppgång", + next_setting: "Solnedgång", + next_dawn: "Gryning", + next_dusk: "Skymning", + next_noon: "Middag", + next_midnight: "Midnatt", + moon_phase: "Månfas", + weather: "Väder" + }, + editor: { + entity: "Sol-entitet", + moon_entity: "Mån-entitet (valfri)", + weather_entity: "Väder-entitet (valfri)", + temp_entity: "Temperatur-entitet (valfri, ersätter väder)", + main_options: "Visningsalternativ", + view_mode: "Visningsläge", + view_mode_classic: "Klassisk (6 bilder)", + view_mode_calculated: "Beräknad (endast elevation)", + view_mode_arc: "Båge (180° rörelse)", + show_image: "Visa solposition (bild)", + show_weather_badge: "Visa väderindikator", + animate_images: "Animera bilder (förutom morgon/skymningsbild)", + sun_size: "Sol/Måne-storlek (endast båge)", + state_position: "Statusposition", + state_pos_above: "Ovanför bild", + state_pos_in_list: "I lista", + state_pos_hide: "Dölj", + moon_phase_position: "Månfasposition", + hide_moon_phase_on_day: "Dölj månfas under dagen", + show_night_arc: "Visa månbåge (180°)", + show_moon_icon_in_text: "Visa månikon i text", + show_dividers: "Visa avdelare", + show_degrees: "Visa grader (azimut/elevation)", + show_degrees_in_list: "Visa grader i lista", + time_position: "Tidsposition", + time_pos_below: "Under bild", + time_pos_above: "Ovanför bild", + time_pos_right: "Till höger om bild", + time_list_format: "Justering av tidslista", + time_format_centered: "Centrerad", + time_format_block: "Block", + times_to_show: "Välj tider", + use_12h_format: "Använd 12-timmarsformat (AM/PM)", + language: "Språk", + language_auto: "Automatiskt (Home Assistant)", + solar_entity: "Solenergi-entitet (valfri, t.ex. vädersensor)", + show_solar_badge: "Visa solenergi-indikator", + advanced_options: "Tröskelvärden (avancerat)", + morning_azimuth: "Morgon-azimut", + noon_azimuth: "Middag-azimut", + afternoon_azimuth: "Eftermiddags-azimut", + dusk_elevation: "Skymnings-elevation" + } +}; diff --git a/src/sun-position-card-editor.js b/src/sun-position-card-editor.js index c0ab3ba..41c7f82 100644 --- a/src/sun-position-card-editor.js +++ b/src/sun-position-card-editor.js @@ -6,6 +6,10 @@ import ita from './lang-ita.js'; import nl from './lang-nl.js'; import pl from './lang-pl.js'; import cs from './lang-cs.js'; +import ru from './lang-ru.js'; +import br from './lang-br.js'; +import se from './lang-se.js'; +import es from './lang-es.js'; const fireEvent = (node, type, detail, options) => { options = options || {}; @@ -23,7 +27,7 @@ const fireEvent = (node, type, detail, options) => { class SunPositionCardEditor extends HTMLElement { constructor() { super(); - this.langs = { de, en, fr, it: ita, nl, pl, cs }; + this.langs = { de, en, fr, it: ita, nl, pl, cs, ru, br, se, es }; this._initialized = false; } @@ -351,7 +355,11 @@ class SunPositionCardEditor extends HTMLElement { { value: "it", label: "Italiano" }, { value: "nl", label: "Nederlands" }, { value: "pl", label: "Polski" }, - { value: "cs", label: "Čeština" } + { value: "cs", label: "Čeština" }, + { value: "ru", label: "Русский" }, + { value: "se", label: "Svenska" }, + { value: "es", label: "Español" }, + { value: "br", label: "Português do Brasil" } ], mode: "dropdown" } }; } diff --git a/src/sun-position-card.js b/src/sun-position-card.js index c258afe..023b036 100644 --- a/src/sun-position-card.js +++ b/src/sun-position-card.js @@ -6,6 +6,10 @@ import ita from './lang-ita.js'; import nl from './lang-nl.js'; import pl from './lang-pl.js'; import cs from './lang-cs.js'; +import ru from './lang-ru.js'; +import br from './lang-br.js'; +import se from './lang-se.js'; +import es from './lang-es.js'; console.log( "%c☀️ Sun-Position-Card v_2.2 ready", @@ -25,7 +29,7 @@ class SunPositionCard extends HTMLElement { super(); this._created = false; this._lastImage = null; - this.langs = { de, en, fr, it: ita, nl, pl, cs }; + this.langs = { de, en, fr, it: ita, nl, pl, cs, ru, br, se, es }; } _localize(key, lang = this.config?.language || this._hass?.locale?.language || 'en') { @@ -346,28 +350,25 @@ class SunPositionCard extends HTMLElement { const formatTime = (isoString) => { if (!isoString) return ''; - const date = new Date(isoString); - const currentLang = (config.language || hass.locale?.language || 'en').split('-')[0]; - const isEnglish = currentLang === 'en'; - - const serverTimeZone = hass.config?.time_zone; - - if (isEnglish && use12hFormat) { - return date.toLocaleTimeString('en-US', { - hour: 'numeric', - minute: '2-digit', - hour12: true, - ...(serverTimeZone && { timeZone: serverTimeZone }) - }); - } else { - return date.toLocaleTimeString(hass.locale?.language || 'en-US', { - hour: '2-digit', - minute: '2-digit', - hour12: false, - ...(serverTimeZone && { timeZone: serverTimeZone }) - }); - } + const date = new Date(Date.parse(isoString)); + + const locale = + config.language || + hass.locale?.language || + navigator.language || + 'en-US'; + + const timeZone = + hass.config?.time_zone || + Intl.DateTimeFormat().resolvedOptions().timeZone; + + return date.toLocaleTimeString(locale, { + hour: use12hFormat ? 'numeric' : '2-digit', + minute: '2-digit', + hour12: use12hFormat, + timeZone + }); }; const calculateDaylight = (sunrise, sunset) => { @@ -440,16 +441,29 @@ class SunPositionCard extends HTMLElement { if (weatherStateObj) { const cond = this._localize(`weather_state.${weatherStateObj.state}`); let temp = weatherStateObj.attributes.temperature; - let unit = hass.config.unit_system.temperature || '°C'; - if (tempStateObj && !isNaN(tempStateObj.state)) { + // Берем unit из weather entity если есть + let unit = + weatherStateObj.attributes.temperature_unit || + weatherStateObj.attributes.unit_of_measurement || + hass.config.unit_system.temperature || + '°C'; + + // temp_entity имеет приоритет + if (tempStateObj && !isNaN(parseFloat(tempStateObj.state))) { temp = tempStateObj.state; + if (tempStateObj.attributes.unit_of_measurement) { unit = tempStateObj.attributes.unit_of_measurement; } } - weatherTemp = `${temp}${unit}`; + const parsedTemp = parseFloat(temp); + + weatherTemp = !isNaN(parsedTemp) + ? `${parsedTemp.toFixed(1)}${unit}` + : `--${unit}`; + weatherText = `${cond}, ${weatherTemp}`; weatherIcon = this._getWeatherIcon(weatherStateObj.state); } @@ -578,7 +592,13 @@ class SunPositionCard extends HTMLElement { solarBadgeEl.style.display = 'flex'; const badgeBg = isDay ? 'rgba(21, 67, 108, 0.8)' : 'rgba(0, 0, 0, 0.8)'; solarBadgeEl.style.background = badgeBg; - const solarValue = solarStateObj.state; + const solarValue = parseFloat(solarStateObj.state); + + solarBadgeEl.innerHTML = + !isNaN(solarValue) + ? `${solarValue} ${solarUnit}` + : `--`; + const solarUnit = solarStateObj.attributes.unit_of_measurement || 'W'; solarBadgeEl.innerHTML = `${solarValue} ${solarUnit}`; } else {