Home Assistant Git Exporter
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
if (!customElements.get("paper-input")) {
|
||||
console.log("imported", "paper-input");
|
||||
import("https://unpkg.com/@polymer/paper-input/paper-input.js?module");
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
const LitElement = Object.getPrototypeOf(
|
||||
customElements.get("ha-panel-lovelace")
|
||||
);
|
||||
const html = LitElement.prototype.html;
|
||||
|
||||
export class WeatherCardEditor extends LitElement {
|
||||
setConfig(config) {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return { hass: {}, _config: {} };
|
||||
}
|
||||
|
||||
get _entity() {
|
||||
return this._config.entity || "";
|
||||
}
|
||||
|
||||
get _rainChanceEntity() {
|
||||
return this._config.rainChanceEntity || "";
|
||||
}
|
||||
|
||||
get _cloudCoverEntity() {
|
||||
return this._config.cloudCoverEntity || "";
|
||||
}
|
||||
|
||||
get _snowChanceEntity() {
|
||||
return this._config.snowChanceEntity || "";
|
||||
}
|
||||
|
||||
get _freezeChanceEntity() {
|
||||
return this._config.freezeChanceEntity || "";
|
||||
}
|
||||
|
||||
|
||||
get _alertEntity() {
|
||||
return this._config.alertEntity || "";
|
||||
}
|
||||
|
||||
get _uvEntity() {
|
||||
return this._config.uvEntity || "";
|
||||
}
|
||||
|
||||
get _rainForecastEntity() {
|
||||
return this._config.rainForecastEntity || "";
|
||||
}
|
||||
|
||||
get _name() {
|
||||
return this._config.name || "";
|
||||
}
|
||||
|
||||
get _icons() {
|
||||
return this._config.icons || "";
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.hass) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="card-config">
|
||||
<div class="side-by-side">
|
||||
<paper-input
|
||||
label="Nom"
|
||||
.value="${this._name}"
|
||||
.configValue="${"name"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<paper-input
|
||||
label="Icônes"
|
||||
.value="${this._icons}"
|
||||
.configValue="${"icons"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._entity}"
|
||||
.configValue=${"entity"}
|
||||
domain-filter="weather"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Météo"
|
||||
.value="${this._entity}"
|
||||
.configValue="${"entity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._rainChanceEntity}"
|
||||
.configValue=${"rainChanceEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Risque de pluie"
|
||||
.value="${this._rainChanceEntity}"
|
||||
.configValue="${"rainChanceEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._uvEntity}"
|
||||
.configValue=${"uvEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="UV"
|
||||
.value="${this._uvEntity}"
|
||||
.configValue="${"uvEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._cloudCoverEntity}"
|
||||
.configValue=${"cloudCoverEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Couverture nuageuse"
|
||||
.value="${this._cloudCoverEntity}"
|
||||
.configValue="${"cloudCoverEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._freezeChanceEntity}"
|
||||
.configValue=${"freezeChanceEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Risque de gel"
|
||||
.value="${this._freezeChanceEntity}"
|
||||
.configValue="${"freezeChanceEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._snowChanceEntity}"
|
||||
.configValue=${"snowChanceEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Risque de neige"
|
||||
.value="${this._snowChanceEntity}"
|
||||
.configValue="${"snowChanceEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._alertEntity}"
|
||||
.configValue=${"alertEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Vigilance Météo"
|
||||
.value="${this._alertEntity}"
|
||||
.configValue="${"alertEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
${
|
||||
customElements.get("ha-entity-picker")
|
||||
? html`
|
||||
<ha-entity-picker
|
||||
.hass="${this.hass}"
|
||||
.value="${this._rainForecastEntity}"
|
||||
.configValue=${"rainForecastEntity"}
|
||||
domain-filter="sensor"
|
||||
@change="${this._valueChanged}"
|
||||
allow-custom-entity
|
||||
></ha-entity-picker>
|
||||
`
|
||||
: html`
|
||||
<paper-input
|
||||
label="Pluie dans l'heure"
|
||||
.value="${this._rainForecastEntity}"
|
||||
.configValue="${"rainForecastEntity"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
_valueChanged(ev) {
|
||||
if (!this._config || !this.hass) {
|
||||
return;
|
||||
}
|
||||
const target = ev.target;
|
||||
if (this[`_${target.configValue}`] === target.value) {
|
||||
return;
|
||||
}
|
||||
if (target.configValue) {
|
||||
if (target.value === "") {
|
||||
delete this._config[target.configValue];
|
||||
} else {
|
||||
this._config = {
|
||||
...this._config,
|
||||
[target.configValue]: target.value
|
||||
};
|
||||
}
|
||||
}
|
||||
fireEvent(this, "config-changed", { config: this._config });
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("meteo-france-weather-card-editor", WeatherCardEditor);
|
||||
@@ -0,0 +1,724 @@
|
||||
const LitElement = Object.getPrototypeOf(
|
||||
customElements.get("ha-panel-lovelace")
|
||||
);
|
||||
const html = LitElement.prototype.html;
|
||||
|
||||
const weatherIconsDay = {
|
||||
clear: "day",
|
||||
"clear-night": "day",
|
||||
"nuit claire": "day",
|
||||
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",
|
||||
"clear-night": "night",
|
||||
sunny: "night",
|
||||
"nuit claire": "night",
|
||||
partlycloudy: "cloudy-night-3",
|
||||
"windy-variant": "cloudy-night-3"
|
||||
};
|
||||
|
||||
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 getWindDirectionRotation(direction) {
|
||||
let windDirections = [
|
||||
"N",//0
|
||||
"NNE",
|
||||
"NE",
|
||||
"ENE",
|
||||
"E",//90
|
||||
"ESE",
|
||||
"SE",
|
||||
"SSE",
|
||||
"S",//180
|
||||
"SSO",
|
||||
"SO",
|
||||
"OSO",
|
||||
"O",//270
|
||||
"ONO",
|
||||
"NO",
|
||||
"NNO"
|
||||
];
|
||||
|
||||
let name = windDirections[Math.round(direction/22.5)%16];
|
||||
return name;
|
||||
}
|
||||
|
||||
function getVigilance(color, alertEntity) {
|
||||
let phenomenaIcons = {
|
||||
"Vent violent": "mdi:weather-windy",
|
||||
"Pluie-inondation": "mdi:weather-pouring",
|
||||
"Orages": "mdi:weather-lightning",
|
||||
"Inondation": "mdi:home-flood",
|
||||
"Neige-verglas": "mdi:weather-snowy-heavy",
|
||||
"Canicule": "mdi:weather-sunny-alert",
|
||||
"Grand-froid": "mdi:snowflake",
|
||||
"Avalanches": "mdi:image-filter-hdr",
|
||||
"Vagues-submersion": "mdi:waves"
|
||||
};
|
||||
|
||||
if(alertEntity == undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let phenomenaList = [];
|
||||
for (const [currentPhenomenon, currentPhenomenonColor] of Object.entries(alertEntity.attributes)) {
|
||||
if(currentPhenomenonColor == color) {
|
||||
phenomenaList.push([currentPhenomenon, phenomenaIcons[currentPhenomenon]]);
|
||||
}
|
||||
}
|
||||
|
||||
return phenomenaList;
|
||||
}
|
||||
|
||||
function getRainForecast(rainForecastEntity) {
|
||||
|
||||
let rainForecastColors = new Map([
|
||||
['Temps sec', 0.1],
|
||||
['Pluie faible', 0.4],
|
||||
['Pluie modérée', 0.7],
|
||||
['Pluie forte', 1]
|
||||
]);
|
||||
|
||||
let rainForecastList = [];
|
||||
for (let [time, value] of Object.entries(rainForecastEntity.attributes['1_hour_forecast'])) {
|
||||
if(time != undefined && time.match(/[0-9]*min/g)) {
|
||||
time = time.replace('min', '').trim();
|
||||
rainForecastList.push([time, rainForecastColors.get(value), value]);
|
||||
}
|
||||
}
|
||||
|
||||
return rainForecastList;
|
||||
}
|
||||
|
||||
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("./meteo-france-weather-card-editor.js");
|
||||
return document.createElement("meteo-france-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];
|
||||
const rainChanceObj = this.hass.states[this._config.rainChanceEntity];
|
||||
const cloudCoverObj = this.hass.states[this._config.cloudCoverEntity];
|
||||
const snowChanceObj = this.hass.states[this._config.snowChanceEntity];
|
||||
const freezeChanceObj = this.hass.states[this._config.freezeChanceEntity];
|
||||
const alertObj = this.hass.states[this._config.alertEntity];
|
||||
const rainForecastObj = this.hass.states[this._config.rainForecastEntity];
|
||||
const uvObj = this.hass.states[this._config.uvEntity];
|
||||
|
||||
if (!stateObj) {
|
||||
return html`
|
||||
<style>
|
||||
.not-found {
|
||||
flex: 1;
|
||||
background-color: yellow;
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
<ha-card>
|
||||
<div class="not-found">
|
||||
Entity not available: ${this._config.entity}
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
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()}
|
||||
<ha-card @click="${this._handleClick}">
|
||||
<span
|
||||
class="icon bigger"
|
||||
style="background: none, url(${
|
||||
this.getWeatherIcon(
|
||||
stateObj.state.toLowerCase(),
|
||||
this.hass.states["sun.sun"].state
|
||||
)
|
||||
}) no-repeat; background-size: contain;"
|
||||
>${stateObj.state}
|
||||
</span>
|
||||
${
|
||||
this._config.name
|
||||
? html`
|
||||
<span class="title"> ${this._config.name} </span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
<span class="temp"
|
||||
>${
|
||||
this.getUnit("temperature") == "°F"
|
||||
? Math.round(stateObj.attributes.temperature)
|
||||
: stateObj.attributes.temperature
|
||||
}</span
|
||||
>
|
||||
<span class="tempc"> ${this.getUnit("temperature")}</span>
|
||||
<span>
|
||||
<ul class="variations">
|
||||
<li>
|
||||
${
|
||||
rainChanceObj != undefined
|
||||
? html`
|
||||
<span title="${rainChanceObj.attributes.friendly_name}" class="ha-icon"
|
||||
><ha-icon icon="${rainChanceObj.attributes.icon === undefined ? 'mdi:weather-rainy' : rainChanceObj.attributes.icon}"></ha-icon
|
||||
></span>
|
||||
${rainChanceObj.state}<span class="unit"> ${rainChanceObj.attributes.unit_of_measurement} </span>
|
||||
<br />
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
${
|
||||
cloudCoverObj != undefined
|
||||
? html`
|
||||
<span title="${cloudCoverObj.attributes.friendly_name}" class="ha-icon"
|
||||
><ha-icon icon="${cloudCoverObj.attributes.icon === undefined ? 'mdi:weather-cloudy' : cloudCoverObj.attributes.icon}"></ha-icon
|
||||
></span>
|
||||
${cloudCoverObj.state}<span class="unit"> ${cloudCoverObj.attributes.unit_of_measurement} </span>
|
||||
<br />
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
${
|
||||
snowChanceObj != undefined
|
||||
? html`
|
||||
<span title="${snowChanceObj.attributes.friendly_name}" class="ha-icon"
|
||||
><ha-icon icon="${snowChanceObj.attributes.icon === undefined ? 'mdi:weather-snowy' : snowChanceObj.attributes.icon}"></ha-icon
|
||||
></span>
|
||||
${snowChanceObj.state}<span class="unit"> ${snowChanceObj.attributes.unit_of_measurement} </span>
|
||||
<br />
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
${
|
||||
freezeChanceObj != undefined
|
||||
? html`
|
||||
<span title="${freezeChanceObj.attributes.friendly_name}" class="ha-icon"
|
||||
><ha-icon icon="${freezeChanceObj.attributes.icon === undefined ? 'mdi:snowflake' : freezeChanceObj.attributes.icon}"></ha-icon
|
||||
></span>
|
||||
${freezeChanceObj.state}<span class="unit"> ${freezeChanceObj.attributes.unit_of_measurement} </span>
|
||||
<br />
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
<br />
|
||||
<span class="ha-icon"
|
||||
><ha-icon icon="mdi:weather-sunset-up"></ha-icon
|
||||
></span>
|
||||
${next_rising.toLocaleTimeString()}
|
||||
</li>
|
||||
<li>
|
||||
<span class="ha-icon"
|
||||
><ha-icon icon="mdi:weather-windy"></ha-icon
|
||||
></span>
|
||||
${stateObj.attributes.wind_speed}<span class="unit">
|
||||
${this.getUnit("length")}/h
|
||||
</span>
|
||||
<br />
|
||||
${
|
||||
stateObj.attributes.wind_bearing != undefined
|
||||
? html`
|
||||
<span class="ha-icon"
|
||||
><ha-icon icon="mdi:navigation" style="transform: rotate(${stateObj.attributes.wind_bearing - 180}deg); display: inline-block;"></ha-icon
|
||||
></span>
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
${
|
||||
stateObj.attributes.wind_bearing != undefined
|
||||
? html`
|
||||
${getWindDirectionRotation(stateObj.attributes.wind_bearing)}
|
||||
<br />
|
||||
<div style="height: 24px;" ></div>
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
${
|
||||
uvObj != undefined
|
||||
? html`
|
||||
<span title="${uvObj.attributes.friendly_name}" class="ha-icon"
|
||||
><ha-icon icon="${uvObj.attributes.icon === undefined ? 'mdi:sunglasses' : uvObj.attributes.icon}"></ha-icon
|
||||
></span>
|
||||
UV ${uvObj.state}
|
||||
<br />
|
||||
`
|
||||
: html`<div style="height: 24px;" ></div>`
|
||||
}
|
||||
<br />
|
||||
<span class="ha-icon"
|
||||
><ha-icon icon="mdi:weather-sunset-down"></ha-icon
|
||||
></span>
|
||||
${next_setting.toLocaleTimeString()}
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
${
|
||||
rainForecastObj != undefined
|
||||
? html`
|
||||
<div class="pluie">
|
||||
${
|
||||
html`
|
||||
${
|
||||
getRainForecast(rainForecastObj).map(
|
||||
forecast => html`
|
||||
<div class="pluie-element" style="opacity: ${forecast[1]}" title="${forecast[2] + " " + (forecast[0] == 0 ? "actuellement" : "dans " + forecast[0] + " min")}">
|
||||
</div>
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
`
|
||||
}
|
||||
</div>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
getVigilance("Jaune", alertObj).length > 0
|
||||
? html`
|
||||
<span class="vigilance jaune">
|
||||
<ha-icon icon="mdi:alert"></ha-icon>Vigilance jaune en cours
|
||||
<div class="vigilance-list">
|
||||
${
|
||||
getVigilance("Jaune", alertObj).map(
|
||||
phenomenon => html`
|
||||
<ha-icon icon="${phenomenon[1]}" title="${phenomenon[0]}"></ha-icon>
|
||||
`
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
getVigilance("Orange", alertObj).length > 0
|
||||
? html`
|
||||
<span class="vigilance orange">
|
||||
<ha-icon icon="mdi:alert"></ha-icon>Vigilance orange en cours
|
||||
<div class="vigilance-list">
|
||||
${
|
||||
getVigilance("Orange", alertObj).map(
|
||||
phenomenon => html`
|
||||
<ha-icon icon="${phenomenon[1]}" title="${phenomenon[0]}"></ha-icon>
|
||||
`
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
getVigilance("Rouge", alertObj).length > 0
|
||||
? html`
|
||||
<span class="vigilance rouge">
|
||||
<ha-icon icon="mdi:alert"></ha-icon>Vigilance rouge en cours
|
||||
<div class="vigilance-list">
|
||||
${
|
||||
getVigilance("Rouge", alertObj).map(
|
||||
phenomenon => html`
|
||||
<ha-icon icon="${phenomenon[1]}" title="${phenomenon[0]}"></ha-icon>
|
||||
`
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
stateObj.attributes.forecast &&
|
||||
stateObj.attributes.forecast.length > 0
|
||||
? html`
|
||||
<div class="forecast clear">
|
||||
${
|
||||
stateObj.attributes.forecast.slice(0, 5).map(
|
||||
daily => html`
|
||||
<div class="day">
|
||||
<span class="dayname"
|
||||
>${
|
||||
new Date(daily.datetime).toLocaleDateString(
|
||||
lang,
|
||||
{
|
||||
weekday: "short"
|
||||
}
|
||||
)
|
||||
}</span
|
||||
>
|
||||
<br /><i
|
||||
class="icon"
|
||||
style="background: none, url(${
|
||||
this.getWeatherIcon(daily.condition.toLowerCase())
|
||||
}) no-repeat; background-size: contain;"
|
||||
></i>
|
||||
<br /><span class="highTemp"
|
||||
>${daily.temperature}${
|
||||
this.getUnit("temperature")
|
||||
}</span
|
||||
>
|
||||
${
|
||||
typeof daily.templow !== 'undefined'
|
||||
? html`
|
||||
<br /><span class="lowTemp"
|
||||
>${daily.templow}${
|
||||
this.getUnit("temperature")
|
||||
}</span
|
||||
>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
typeof daily.precipitation !== 'undefined'
|
||||
? html`
|
||||
<br /><span class="rainForcast"
|
||||
>${daily.precipitation}${
|
||||
this.getUnit("precipitation")
|
||||
}</span
|
||||
>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
`
|
||||
)
|
||||
}
|
||||
</div>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
getWeatherIcon(condition, sun) {
|
||||
let icon = `${
|
||||
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`;
|
||||
return icon;
|
||||
}
|
||||
|
||||
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`
|
||||
<style>
|
||||
ha-card {
|
||||
cursor: pointer;
|
||||
margin: auto;
|
||||
padding-top: 2.5em;
|
||||
padding-bottom: 1.3em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pluie {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
height: 15px;
|
||||
padding: 0px;
|
||||
color: var(--primary-text-color);
|
||||
margin: 10px 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pluie-element {
|
||||
width: 100%;
|
||||
background-color: var(--paper-item-icon-color);
|
||||
border-right: 1px solid var(
|
||||
--lovelace-background,
|
||||
var(--primary-background-color)
|
||||
);
|
||||
}
|
||||
|
||||
.pluie-element:first-child {
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
.pluie-element:last-child {
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.ha-icon {
|
||||
height: 18px;
|
||||
margin-right: 5px;
|
||||
color: var(--paper-item-icon-color);
|
||||
}
|
||||
|
||||
.vigilance {
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
padding: 5px 10px;
|
||||
font-weight: 600;
|
||||
color: var(--primary-text-color);
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.vigilance ha-icon {
|
||||
margin: 0px 10px 0px 0px;
|
||||
}
|
||||
|
||||
.vigilance-list ha-icon {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.vigilance-list {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.vigilance.jaune {
|
||||
background-color: rgba(255,235,0,0.5);
|
||||
}
|
||||
|
||||
.vigilance.orange {
|
||||
background-color: rgba(255,152,0,0.5);
|
||||
}
|
||||
|
||||
.vigilance.rouge {
|
||||
background-color: rgba(244,67,54,0.5);
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
left: 3em;
|
||||
top: 0.9em;
|
||||
font-weight: 300;
|
||||
font-size: 3em;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.temp {
|
||||
font-weight: 300;
|
||||
font-size: 4em;
|
||||
color: var(--primary-text-color);
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 0.7em;
|
||||
}
|
||||
|
||||
.tempc {
|
||||
font-weight: 300;
|
||||
font-size: 1.5em;
|
||||
vertical-align: super;
|
||||
color: var(--primary-text-color);
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
margin-top: -14px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.variations {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
font-weight: 300;
|
||||
color: var(--primary-text-color);
|
||||
list-style: none;
|
||||
margin-top: 4.5em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.variations li {
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
.variations li:first-child {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.variations li:last-child {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.unit {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.forecast {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
height: 11em;
|
||||
}
|
||||
|
||||
.day {
|
||||
display: block;
|
||||
width: 20%;
|
||||
float: left;
|
||||
text-align: center;
|
||||
color: var(--primary-text-color);
|
||||
border-right: 0.1em solid #d9d9d9;
|
||||
line-height: 2;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.dayname {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.forecast .day:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.forecast .day:nth-last-child(1) {
|
||||
border-right: none;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.highTemp {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lowTemp {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.rainForcast {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.icon.bigger {
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
margin-top: -8.5em;
|
||||
position: absolute;
|
||||
left: 0em;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background-size: contain;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
text-indent: -9999px;
|
||||
}
|
||||
|
||||
.weather {
|
||||
font-weight: 300;
|
||||
font-size: 1.5em;
|
||||
color: var(--primary-text-color);
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
top: -0.5em;
|
||||
left: 6em;
|
||||
word-wrap: break-word;
|
||||
width: 30%;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define("meteo-france-weather-card", WeatherCard);
|
||||
Reference in New Issue
Block a user