const LitElement = Object.getPrototypeOf( customElements.get("ha-panel-lovelace") ); const html = LitElement.prototype.html; const weatherIconsDay = { clear: "day", "clear-night": "night", cloudy: "cloudy", fog: "cloudy", hail: "rainy-7", lightning: "thunder", "lightning-rainy": "thunder", partlycloudy: "cloudy-day-3", pouring: "rainy-6", rainy: "rainy-5", snowy: "snowy-6", "snowy-rainy": "rainy-7", sunny: "day", windy: "cloudy", "windy-variant": "cloudy-day-3", exceptional: "!!" }; const weatherIconsNight = { ...weatherIconsDay, clear: "night", sunny: "night", partlycloudy: "cloudy-night-3", "windy-variant": "cloudy-night-3" }; const windDirections = [ "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N" ]; const fireEvent = (node, type, detail, options) => { options = options || {}; detail = detail === null || detail === undefined ? {} : detail; const event = new Event(type, { bubbles: options.bubbles === undefined ? true : options.bubbles, cancelable: Boolean(options.cancelable), composed: options.composed === undefined ? true : options.composed }); event.detail = detail; node.dispatchEvent(event); return event; }; function hasConfigOrEntityChanged(element, changedProps) { if (changedProps.has("_config")) { return true; } const oldHass = changedProps.get("hass"); if (oldHass) { return ( oldHass.states[element._config.entity] !== element.hass.states[element._config.entity] || oldHass.states["sun.sun"] !== element.hass.states["sun.sun"] ); } return true; } class WeatherCard extends LitElement { static get properties() { return { _config: {}, hass: {} }; } static async getConfigElement() { await import("./weather-card-editor.js"); return document.createElement("weather-card-editor"); } static getStubConfig() { return {}; } setConfig(config) { if (!config.entity) { throw new Error("Please define a weather entity"); } this._config = config; } shouldUpdate(changedProps) { return hasConfigOrEntityChanged(this, changedProps); } render() { if (!this._config || !this.hass) { return html``; } const stateObj = this.hass.states[this._config.entity]; if (!stateObj) { return html`
Entity not available: ${this._config.entity}
`; } const lang = this.hass.selectedLanguage || this.hass.language; const next_rising = new Date( this.hass.states["sun.sun"].attributes.next_rising ); const next_setting = new Date( this.hass.states["sun.sun"].attributes.next_setting ); return html` ${this.renderStyle()} ${stateObj.state} ${ this._config.name ? html` ${this._config.name} ` : "" } ${ this.getUnit("temperature") == "°F" ? Math.round(stateObj.attributes.temperature) : stateObj.attributes.temperature } ${this.getUnit("temperature")} ${ stateObj.attributes.forecast && stateObj.attributes.forecast.length > 0 ? html`
${ stateObj.attributes.forecast.slice(0, 5).map( daily => html`
${ new Date(daily.datetime).toLocaleDateString( lang, { weekday: "short" } ) }

${daily.temperature}${ this.getUnit("temperature") } ${ typeof daily.templow !== 'undefined' ? html`
${daily.templow}${ this.getUnit("temperature") } ` : "" }
` ) }
` : "" }
`; } getWeatherIcon(condition, sun) { return `${ this._config.icons ? this._config.icons : "https://cdn.jsdelivr.net/gh/bramkragten/custom-ui@master/weather-card/icons/animated/" }${ sun && sun == "below_horizon" ? weatherIconsNight[condition] : weatherIconsDay[condition] }.svg`; } getUnit(measure) { const lengthUnit = this.hass.config.unit_system.length; switch (measure) { case "air_pressure": return lengthUnit === "km" ? "hPa" : "inHg"; case "length": return lengthUnit; case "precipitation": return lengthUnit === "km" ? "mm" : "in"; default: return this.hass.config.unit_system[measure] || ""; } } _handleClick() { fireEvent(this, "hass-more-info", { entityId: this._config.entity }); } getCardSize() { return 3; } renderStyle() { return html` `; } } customElements.define("weather-card", WeatherCard);