276 lines
7.7 KiB
TypeScript
276 lines
7.7 KiB
TypeScript
import {
|
|
mdiAlertCircleOutline,
|
|
mdiEye,
|
|
mdiGauge,
|
|
mdiThermometer,
|
|
mdiWaterPercent,
|
|
mdiWeatherCloudy,
|
|
mdiWeatherFog,
|
|
mdiWeatherHail,
|
|
mdiWeatherLightning,
|
|
mdiWeatherLightningRainy,
|
|
mdiWeatherNight,
|
|
mdiWeatherPartlyCloudy,
|
|
mdiWeatherPouring,
|
|
mdiWeatherRainy,
|
|
mdiWeatherSnowy,
|
|
mdiWeatherSnowyRainy,
|
|
mdiWeatherSunny,
|
|
mdiWeatherWindy,
|
|
mdiWeatherWindyVariant,
|
|
} from "@mdi/js";
|
|
import { HassEntity } from "home-assistant-js-websocket";
|
|
import {
|
|
css,
|
|
CSSResultGroup,
|
|
html,
|
|
LitElement,
|
|
PropertyValues,
|
|
TemplateResult,
|
|
} from "lit";
|
|
import { customElement, property } from "lit/decorators";
|
|
import { formatDateWeekday } from "../../../common/datetime/format_date";
|
|
import { formatTimeWeekday } from "../../../common/datetime/format_time";
|
|
import { formatNumber } from "../../../common/number/format_number";
|
|
import "../../../components/ha-svg-icon";
|
|
import { getWeatherUnit, getWind } from "../../../data/weather";
|
|
import { HomeAssistant } from "../../../types";
|
|
|
|
const weatherIcons = {
|
|
"clear-night": mdiWeatherNight,
|
|
cloudy: mdiWeatherCloudy,
|
|
exceptional: mdiAlertCircleOutline,
|
|
fog: mdiWeatherFog,
|
|
hail: mdiWeatherHail,
|
|
lightning: mdiWeatherLightning,
|
|
"lightning-rainy": mdiWeatherLightningRainy,
|
|
partlycloudy: mdiWeatherPartlyCloudy,
|
|
pouring: mdiWeatherPouring,
|
|
rainy: mdiWeatherRainy,
|
|
snowy: mdiWeatherSnowy,
|
|
"snowy-rainy": mdiWeatherSnowyRainy,
|
|
sunny: mdiWeatherSunny,
|
|
windy: mdiWeatherWindy,
|
|
"windy-variant": mdiWeatherWindyVariant,
|
|
};
|
|
|
|
@customElement("more-info-weather")
|
|
class MoreInfoWeather extends LitElement {
|
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
|
|
@property() public stateObj?: HassEntity;
|
|
|
|
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
|
if (changedProps.has("stateObj")) {
|
|
return true;
|
|
}
|
|
|
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
|
if (
|
|
!oldHass ||
|
|
oldHass.locale !== this.hass.locale ||
|
|
oldHass.config.unit_system !== this.hass.config.unit_system
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected render(): TemplateResult {
|
|
if (!this.hass || !this.stateObj) {
|
|
return html``;
|
|
}
|
|
|
|
return html`
|
|
<div class="flex">
|
|
<ha-svg-icon .path=${mdiThermometer}></ha-svg-icon>
|
|
<div class="main">
|
|
${this.hass.localize("ui.card.weather.attributes.temperature")}
|
|
</div>
|
|
<div>
|
|
${formatNumber(
|
|
this.stateObj.attributes.temperature,
|
|
this.hass.locale
|
|
)}
|
|
${getWeatherUnit(this.hass, "temperature")}
|
|
</div>
|
|
</div>
|
|
${this._showValue(this.stateObj.attributes.pressure)
|
|
? html`
|
|
<div class="flex">
|
|
<ha-svg-icon .path=${mdiGauge}></ha-svg-icon>
|
|
<div class="main">
|
|
${this.hass.localize("ui.card.weather.attributes.air_pressure")}
|
|
</div>
|
|
<div>
|
|
${formatNumber(
|
|
this.stateObj.attributes.pressure,
|
|
this.hass.locale
|
|
)}
|
|
${getWeatherUnit(this.hass, "pressure")}
|
|
</div>
|
|
</div>
|
|
`
|
|
: ""}
|
|
${this._showValue(this.stateObj.attributes.humidity)
|
|
? html`
|
|
<div class="flex">
|
|
<ha-svg-icon .path=${mdiWaterPercent}></ha-svg-icon>
|
|
<div class="main">
|
|
${this.hass.localize("ui.card.weather.attributes.humidity")}
|
|
</div>
|
|
<div>
|
|
${formatNumber(
|
|
this.stateObj.attributes.humidity,
|
|
this.hass.locale
|
|
)}
|
|
%
|
|
</div>
|
|
</div>
|
|
`
|
|
: ""}
|
|
${this._showValue(this.stateObj.attributes.wind_speed)
|
|
? html`
|
|
<div class="flex">
|
|
<ha-svg-icon .path=${mdiWeatherWindy}></ha-svg-icon>
|
|
<div class="main">
|
|
${this.hass.localize("ui.card.weather.attributes.wind_speed")}
|
|
</div>
|
|
<div>
|
|
${getWind(
|
|
this.hass,
|
|
this.stateObj.attributes.wind_speed,
|
|
this.stateObj.attributes.wind_bearing
|
|
)}
|
|
</div>
|
|
</div>
|
|
`
|
|
: ""}
|
|
${this._showValue(this.stateObj.attributes.visibility)
|
|
? html`
|
|
<div class="flex">
|
|
<ha-svg-icon .path=${mdiEye}></ha-svg-icon>
|
|
<div class="main">
|
|
${this.hass.localize("ui.card.weather.attributes.visibility")}
|
|
</div>
|
|
<div>
|
|
${formatNumber(
|
|
this.stateObj.attributes.visibility,
|
|
this.hass.locale
|
|
)}
|
|
${getWeatherUnit(this.hass, "length")}
|
|
</div>
|
|
</div>
|
|
`
|
|
: ""}
|
|
${this.stateObj.attributes.forecast
|
|
? html`
|
|
<div class="section">
|
|
${this.hass.localize("ui.card.weather.forecast")}:
|
|
</div>
|
|
${this.stateObj.attributes.forecast.map(
|
|
(item) => html`
|
|
<div class="flex">
|
|
${item.condition
|
|
? html`
|
|
<ha-svg-icon
|
|
.path=${weatherIcons[item.condition]}
|
|
></ha-svg-icon>
|
|
`
|
|
: ""}
|
|
${!this._showValue(item.templow)
|
|
? html`
|
|
<div class="main">
|
|
${formatTimeWeekday(
|
|
new Date(item.datetime),
|
|
this.hass.locale
|
|
)}
|
|
</div>
|
|
`
|
|
: ""}
|
|
${this._showValue(item.templow)
|
|
? html`
|
|
<div class="main">
|
|
${formatDateWeekday(
|
|
new Date(item.datetime),
|
|
this.hass.locale
|
|
)}
|
|
</div>
|
|
<div class="templow">
|
|
${formatNumber(item.templow, this.hass.locale)}
|
|
${getWeatherUnit(this.hass, "temperature")}
|
|
</div>
|
|
`
|
|
: ""}
|
|
<div class="temp">
|
|
${this._showValue(item.temperature)
|
|
? `${formatNumber(item.temperature, this.hass.locale)}
|
|
${getWeatherUnit(this.hass, "temperature")}`
|
|
: ""}
|
|
</div>
|
|
</div>
|
|
`
|
|
)}
|
|
`
|
|
: ""}
|
|
${this.stateObj.attributes.attribution
|
|
? html`
|
|
<div class="attribution">
|
|
${this.stateObj.attributes.attribution}
|
|
</div>
|
|
`
|
|
: ""}
|
|
`;
|
|
}
|
|
|
|
static get styles(): CSSResultGroup {
|
|
return css`
|
|
ha-svg-icon {
|
|
color: var(--paper-item-icon-color);
|
|
}
|
|
.section {
|
|
margin: 16px 0 8px 0;
|
|
font-size: 1.2em;
|
|
}
|
|
|
|
.flex {
|
|
display: flex;
|
|
height: 32px;
|
|
align-items: center;
|
|
}
|
|
|
|
.main {
|
|
flex: 1;
|
|
margin-left: 24px;
|
|
}
|
|
|
|
.temp,
|
|
.templow {
|
|
min-width: 48px;
|
|
text-align: right;
|
|
}
|
|
|
|
.templow {
|
|
margin: 0 16px;
|
|
color: var(--secondary-text-color);
|
|
}
|
|
|
|
.attribution {
|
|
color: var(--secondary-text-color);
|
|
text-align: center;
|
|
}
|
|
`;
|
|
}
|
|
|
|
private _showValue(item: string): boolean {
|
|
return typeof item !== "undefined" && item !== null;
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"more-info-weather": MoreInfoWeather;
|
|
}
|
|
}
|