Skip to content

Commit

Permalink
Fix forecast (#133)
Browse files Browse the repository at this point in the history
🐛 Fixes :
- Manage upgrade of hourly & daily integrations
- French translation
- `paper-input` deprecated
- Reordering fields in UI
- Added défault value to all fields
- Use local path to PNG

📝 Docs :
- Copy README.md to info.md

---------

Signed-off-by: Emmanuel Berthier <[email protected]>
Co-authored-by: Emmanuel Berthier <[email protected]>
  • Loading branch information
dx44 and manu3b1 authored Apr 8, 2024
1 parent 152894c commit 7d1538d
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 131 deletions.
63 changes: 34 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ Les informations affichées :
- informations météorologiques détaillées,
- pluviométrie dans l'heure (prévisions à 5 puis 10 minutes),
- alertes météos en cours (inondations, vents violents, etc) en rapport à votre département,
- prévisions météo quotidienne de 1 à 15 jours maximum (réglable) ou des prévisions horaires de 1 à x heures (réglable),
- prévisions météo quotidiennes de 1 à 15 jours maximum (réglable) et des prévisions horaires de 1 à x heures (réglable),
- sélection des informations à afficher pour personnaliser votre carte.

Un exemple de rendu :

![Weather Card](https://github.com/hacf-fr/lovelace-meteofrance-weather-card/blob/Meteo-France/meteofrance-weather-card.png)
![Weather Card](meteofrance-weather-card.png)

## Installation

Expand Down Expand Up @@ -59,21 +59,17 @@ Vous trouverez la carte dans la liste des cartes personnalisées (en fin de list

Une fois choisi, sa configuration est la suivante :

1. **Définir un nom** pour la carte (généralement la ville, comme pour l'intégration).
1. **Sélectionner l'entité météo** que vous avez défini avec l'intégration (par défaut la carte en choisit une mais ce n'est pas forcément l'entité météo france que vous avez configuré).

2. **Sélectionner l'entité météo** que vous avez définit avec l'intégration (par défaut la carte en choisit une mais ce n'est pas forcément l'entité météo france que vous avez configuré).
2. Toutes les autres entités **sont automatiquement définies** mais vous pouvez les redéfinir ou les supprimer à votre guise.

3. Toutes les autres entités **sont automatiquement définies** mais vous pouvez les redéfinir ou les supprimer à votre guise.
3. **Sélectionner les éléments** de la carte **à afficher** (vous pouvez ainsi avoir plusieurs cartes avec des affichages différents).

4. Seule l'entité pour **les alertes est à préciser manuellement**.
4. **Préciser les nombres d'heures et de jours de prévision** à afficher.

5. **Sélectionner les parties** de la carte **à afficher** (vous pouvez ainsi avoir plusieurs cartes avec des affichages différents).
5. `Enregistrer` votre configuration.

6. **Préciser le nombre de jours de prévision** à afficher en bas de carte, maximum 5.

7. `Enregistrer` votre configuration.

![Weather Card Configuration](https://github.com/hacf-fr/lovelace-meteofrance-weather-card/blob/Meteo-France/meteofrance-weather-card-editor.png)
![Weather Card Configuration](meteofrance-weather-card-editor.png)

### Installation manuelle (utilisateurs avancés)

Expand Down Expand Up @@ -117,23 +113,32 @@ Ci-dessous les éléments de configuration avec pour exemple l'usage d'une inté
view:
cards:
- type: "custom:meteofrance-weather-card"
name: Nantes # nom de la carte, peut être différent du nom de l'intégration
entity: weather.nantes # Entité météo principale
# Les entités annexes de météo france
cloudCoverEntity: sensor.nantes_cloud_cover
rainChanceEntity: sensor.nantes_rain_chance
freezeChanceEntity: sensor.nantes_freeze_chance
snowChanceEntity: sensor.nantes_snow_chance
uvEntity: sensor.nantes_uv
rainForecastEntity: sensor.nantes_next_rain
alertEntity: sensor.44_weather_alert
number_of_forecasts: "5"
# Les switches pour afficher ou non les différentes zones.
current: true
details: true
one_hour_forecast: true
alert_forecast: true
forecast: true
entity: weather.nantes # Entité météo principale
name: Nantes # nom de la carte, peut être différent du nom de l'intégration
# Les switches pour afficher ou non les différentes zones.
current: true
details: true
alert_forecast: true
one_hour_forecast: true
daily_forecast: true
hourly_forecast: true
humidity_forecast: true
wind_forecast_icons: true
animated_icons: true
# Les curseurs
number_of_hourly_forecasts: "5"
number_of_daily_forecasts: "5"
# Les entités annexes de météo france
detailEntity: sensor.nantes_daily_precipitation
cloudCoverEntity: sensor.nantes_cloud_cover
rainChanceEntity: sensor.nantes_rain_chance
freezeChanceEntity: sensor.nantes_freeze_chance
snowChanceEntity: sensor.nantes_snow_chance
uvEntity: sensor.nantes_uv
rainForecastEntity: sensor.nantes_next_rain
alertEntity: sensor.44_weather_alert
# Chemin
icons: /local/community/lovelace-meteofrance-weather-card/icons/
```

#### options avancées via YAML
Expand Down
149 changes: 100 additions & 49 deletions dist/meteofrance-weather-card-editor.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const css = LitElement.prototype.css;
const HELPERS = window.loadCardHelpers();

const DefaultSensors = new Map([
["detailEntity", "_rain_chance"],
["cloudCoverEntity", "_cloud_cover"],
["rainChanceEntity", "_rain_chance"],
["freezeChanceEntity", "_freeze_chance"],
Expand All @@ -42,6 +43,12 @@ const DefaultSensors = new Map([
export class MeteofranceWeatherCardEditor extends LitElement {
setConfig(config) {
this._config = { ...config };

// Set default sub-entities at first Init (when there are only "entity" & "type" in config)
if (Object.keys(config).length === 2 && config.entity !== undefined) {
this._weatherEntityChanged(config.entity.split(".")[1]);
fireEvent(this, "config-changed", { config: this._config });
}
}

static get properties() {
Expand All @@ -68,12 +75,20 @@ export class MeteofranceWeatherCardEditor extends LitElement {
return this._config.details !== false;
}

get _forecast() {
return this._config.forecast !== false;
get _daily_forecast() {
return this._config.daily_forecast !== false;
}

get _number_of_forecasts() {
return this._config.number_of_forecasts || 5;
get _number_of_daily_forecasts() {
return this._config.number_of_daily_forecasts || 5;
}

get _hourly_forecast() {
return this._config.hourly_forecast !== false;
}

get _number_of_hourly_forecasts() {
return this._config.number_of_hourly_forecasts || 5;
}

// Météo France
Expand All @@ -97,7 +112,7 @@ export class MeteofranceWeatherCardEditor extends LitElement {
get _humidity_forecast() {
return this._config.humidity_forecast !== false;
}
// Config value

get _alertEntity() {
return this._config.alertEntity || "";
}
Expand Down Expand Up @@ -146,70 +161,57 @@ export class MeteofranceWeatherCardEditor extends LitElement {
return html`
<div class="card-config">
<div>
<paper-input
label="Name"
.value="${this._name}"
.configValue="${"name"}"
@value-changed="${this._valueChanged}"
></paper-input>
<!-- Primary weather entity -->
${this.renderWeatherPicker("Entité", this._entity, "entity")}
${this.renderTextField("Nom", this._name, "name")}
${this.renderSensorPicker(
"Détail",
this._detailEntity,
"detailEntity"
)}
<paper-input
label="Icons location"
.value="${this._icons}"
.configValue="${"icons"}"
@value-changed="${this._valueChanged}"
></paper-input>
<!-- Primary weather entity -->
${this.renderWeatherPicker("Entity", this._entity, "entity")}
<!-- Switches -->
<ul class="switches">
${this.renderSwitchOption("Show current", this._current, "current")}
${this.renderSwitchOption("Show details", this._details, "details")}
${this.renderSwitchOption("Météo actuelle", this._current, "current")}
${this.renderSwitchOption("Détails", this._details, "details")}
${this.renderSwitchOption(
"Show one hour forecast",
"Alertes",
this._alert_forecast,
"alert_forecast"
)}
${this.renderSwitchOption(
"Pluie dans l'heure",
this._one_hour_forecast,
"one_hour_forecast"
)}
${this.renderSwitchOption(
"Show alert",
this._alert_forecast,
"alert_forecast"
"Prévisions par heure",
this._hourly_forecast,
"hourly_forecast"
)}
${this.renderSwitchOption(
"Show forecast",
this._forecast,
"forecast"
"Prévisions par jour",
this._daily_forecast,
"daily_forecast"
)}
${this.renderSwitchOption(
"Use animated icons",
this._animated_icons,
"animated_icons"
"Humidité",
this._humidity_forecast,
"humidity_forecast"
)}
${this.renderSwitchOption(
"Show wind icons",
"Girouette",
this._wind_forecast_icons,
"wind_forecast_icons"
)}
)}
${this.renderSwitchOption(
"Show humidity forecast",
this._humidity_forecast,
"humidity_forecast"
)}
"Icones animées",
this._animated_icons,
"animated_icons"
)}
</ul>
<!-- -->
<paper-input
label="Number of future forcasts"
type="number"
min="1"
max="8"
value=${this._number_of_forecasts}
.configValue="${"number_of_forecasts"}"
@value-changed="${this._valueChanged}"
></paper-input>
${this.renderNumberField("Nombres d'heures", this._number_of_hourly_forecasts, "number_of_hourly_forecasts")}
${this.renderNumberField("Nombres de jours", this._number_of_daily_forecasts, "number_of_daily_forecasts")}
<!-- Meteo France weather entities -->
${this.renderSensorPicker(
"Risque de pluie",
Expand Down Expand Up @@ -242,11 +244,32 @@ export class MeteofranceWeatherCardEditor extends LitElement {
this._rainForecastEntity,
"rainForecastEntity"
)}
${this.renderTextField("Répertoire des icones", this._icons, "icons")}
</div>
</div>
`;
}

renderTextField(label, state, configAttr) {
return this.renderField(label, state, configAttr, "text");
}

renderNumberField(label, state, configAttr) {
return this.renderField(label, state, configAttr, "number");
}

renderField(label, state, configAttr, type) {
return html`
<ha-textfield
label="${label}"
.value="${state}"
type="${type}"
.configValue=${configAttr}
@input=${this._valueChanged}
></ha-textfield>
`;
}

renderWeatherPicker(label, entity, configAttr) {
return this.renderPicker(label, entity, configAttr, "weather");
}
Expand Down Expand Up @@ -283,14 +306,42 @@ export class MeteofranceWeatherCardEditor extends LitElement {
`;
}

_weatherEntityChanged(entityName) {
_weatherEntityChanged(weatherEntityName) {
const weatherEntityNameFull = "weather." + weatherEntityName;
const state = this.hass.states[weatherEntityNameFull];
if (state !== undefined) {
// Set default Name
const friendly_name = state.attributes.friendly_name;
this._config = {
...this._config,
["name"]: friendly_name ? friendly_name : "",
};

// Set default Alert sensor
// Find Alert Sensor related to its parent device
const entity = this.hass.entities[weatherEntityNameFull];
const parent_device_id = entity.device_id;
Object.keys(this.hass.entities).forEach(entityName => {
const entity = this.hass.entities[entityName];
if (entity !== undefined && entity.device_id === parent_device_id && entityName.split(".")[1].includes("_weather_alert")) {
this._config = {
...this._config,
["alertEntity"]: entityName,
};
return;
}
});
};

// Set default Sensors
DefaultSensors.forEach((sensorSuffix, configAttribute) => {
const entity = "sensor." + entityName + sensorSuffix;
if (this.hass.states[entity] !== undefined)
const entity = "sensor." + weatherEntityName + sensorSuffix;
if (this.hass.states[entity] !== undefined) {
this._config = {
...this._config,
[configAttribute]: entity,
};
};
});
}

Expand Down
Loading

0 comments on commit 7d1538d

Please sign in to comment.