├── linky.png
├── content-card-linky.png
├── hacs.json
├── content-card-linky-editor.png
├── .github
└── workflows
│ └── main.yml
├── LICENSE
├── README.md
└── dist
├── content-card-linky-editor.js
└── content-card-linky.js
/linky.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/saniho/content-card-linky/HEAD/linky.png
--------------------------------------------------------------------------------
/content-card-linky.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/saniho/content-card-linky/HEAD/content-card-linky.png
--------------------------------------------------------------------------------
/hacs.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Linky Content Card",
3 | "country": "FR",
4 | "render_readme": true
5 | }
6 |
--------------------------------------------------------------------------------
/content-card-linky-editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/saniho/content-card-linky/HEAD/content-card-linky-editor.png
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Validate for HACS
2 |
3 | on:
4 | push:
5 | pull_request:
6 | schedule:
7 | - cron: '0 0 * * *'
8 |
9 | jobs:
10 | hacs:
11 | name: HACS Action
12 | runs-on: "ubuntu-latest"
13 | steps:
14 | - uses: "actions/checkout@v2"
15 | - name: HACS Action
16 | uses: "hacs/action@main"
17 | with:
18 | category: "plugin"
19 | ignore: "brands"
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Project based on https://github.com/saniho/content-card-linky.
2 |
3 | MIT License
4 |
5 | Copyright (c) 2021 Nicolas Bourasseau
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pré-avis: cette carte est en train d'être abandonné en faveur de son successor (copie) dans le domain de MyElectricalData
2 | Pour en profiter, il faut désinstaller cette carte et reïnstaller https://github.com/MyElectricalData/content-card-linky
3 |
4 | -
5 | -
6 | -
7 | -
8 | -
9 | -
10 |
11 |
12 |
13 | ## content-card-linky
14 | [](https://github.com/custom-components/hacs)
15 |
16 | **Cette carte est compatible avec l'integration : [MyElectricalData](https://github.com/MyElectricalData/myelectricaldata)**
17 |
18 | Depuis Aout 2023: avec le changement vers MyElectricalData, cette carte **n'est plus garanti d'être compatible** avec l'integration : [MyEnedis](https://github.com/saniho/apiEnedis)
19 |
20 | **Un question ? Un problème ? Une demande ? Venez en parler sur le [forum HACF](https://forum.hacf.fr/).**
21 |
22 | ## Bienvenue !
23 |
24 | Cette carte est initialement inspirée de [@royto](https://github.com/royto/linky-card)
25 |
26 | Avant de pouvoir utiliser cette intégration, assurez vous :
27 | * D'avoir validé l'installation correcte de [MyElectricalData](https://github.com/MyElectricalData/myelectricaldata)
28 |
29 | ## Installer la carte
30 |
31 | Via HACS (mise à jour en un clic) :
32 |
33 | * Ouvrez HACS, cliquez sur `Frontend`, puis selectionnez le menu 3 points en haut à droite.
34 |
35 | *si vous n'avez pas HACS, pour l'installer cela se passe ici : [HACS : Ajoutez des modules et des cartes personnalisées](https://forum.hacf.fr/t/hacs-ajoutez-des-modules-et-des-cartes-personnalisees/359)
36 |
37 | * Ajoutez le dépot personnalisé : `https://github.com/saniho/content-card-linky`
38 |
39 | * Choisir la catégorie `Lovelace`
40 |
41 | * Cliquez sur le bouton `Installer` de la carte
42 |
43 | * Cliquez sur le bouton `Installer` de la popup
44 |
45 | * La carte est maintenant rouge, signifiant qu'un redémarrage du serveur Home Assistant est nécessaire
46 |
47 | * Accédez à la vue `Contrôle du serveur` (`Configuration` -> `Contrôle du serveur`), puis cliquez sur le bouton `Redémarrer` dans la zone `Gestion du serveur`
48 |
49 |
50 |
51 | Manuellement (à faire à chaque mise à jour)
52 | * Telecharger le fichier [content-card-linky.js](https://github.com/saniho/content-card-linky/blob/main/content-card-linky.js) et le dossier [images](https://github.com/saniho/content-card-linky/tree/main/images)
53 |
54 | * Les mettre dans votre repertoire `www` et l'ajouter dans l'interface ressource
55 |
56 | * Configurez la ressource dans votre fichier de configuration.
57 |
58 | ```
59 | resources:
60 | - url: /hacsfiles/content-card-linky/content-card-linky.js
61 | type: module
62 | ```
63 |
64 |
65 | ## Ajouter la carte
66 |
67 | Via l'interface graphique
68 | * Ajoutez une carte via l'interface graphique, et configurez les options comme vous le désirez.
69 |
70 |
71 |
72 | En YAML
73 | * Dans votre éditeur lovelace, ajouter ceci :
74 |
75 | ````
76 | type: 'custom:content-card-linky'
77 | entity: sensor.xxx_myelctricaldata_xxxx
78 | ````
79 |
80 |
81 | ### Redémarrer votre serveur Home Assistant
82 |
83 | ## Options disponibles
84 |
85 | ````
86 | type: custom:content-card-linky Type de la carte
87 | nbJoursAffichage: '7' Nombre de jour historique
88 | titleName: Consommation d'hier Titre
89 | entity: sensor.myelectricaldata_123456 Sensor de l'integration MyElectricalData
90 | ewEntity: sensor.myelectricaldata_123456_J0 Sensor de l'intégration Ecowatt J+0 via (!) MyElectricalData (sensor dispo dès MyElectricaldata v0.9.1)
91 | ewEntityJ1: sensor.myelectricaldata_123456_J1 Sensor de l'intégration Ecowatt J+1 via (!) MyElectricalData (sensor dispo dès MyElectricaldata v0.9.1)
92 | ewEntityJ2: sensor.myelectricaldata_123456_J2 Sensor de l'intégration Ecowatt J+2 via (!) MyElectricalData (sensor dispo dès MyElectricaldata v0.9.1)
93 | tempoInfo: sensor.myelec..._tempoinfo Sensor de l'intégratoin Tempo, contient des prix et jours restant par couleur (sensor dispo dès v0.9.2 ou en dev 0.9.2.b4)
94 | tempoEntityJ0: sensor.myelec..._tempotoday Sensor de l'intégration Tempo aujourd'hui
95 | tempoEntityJ1: sensor.myelec..._tempotomorrow Sensor de l'intégration Tempo demain
96 | showIcon: false Affiche l'icon Linky
97 | showHistory: true Affiche l'historique sur plusieurs jours
98 | showInTableUnit: false
99 | showDayPriceHCHP: false
100 | showDayHCHP: false
101 | showMonthRatio: false
102 | showTitle: true
103 | showPeakOffPeak: false
104 | showDayPrice: true
105 | showPrice: true Affiche le prix de l'historique
106 | showCurrentMonthRatio: true
107 | showWeekRatio: true
108 | showDayName: short Affichage des jours de la semaine : "short", "narrow", "long"
109 | showDayMaxPower: true Affichage MaxPower avec indication si dépassé
110 | showTitreLigne: true
111 | showEcoWatt: true Affichage EcoWatt pour ajourd'hui
112 | showEcoWattJ12: false Affichage EcoWatt pour demains et après (sensor dispo dès MyElectricaldata v0.9.1)
113 | showTempo: false Affichage Tempo
114 | ````
115 |
116 | 
117 |
118 |
119 |
120 | **************
121 |
122 | N'hésitez pas à aller faire un tour sur ce forum ou vous trouverez pleins d'informations
123 |
124 | https://forum.hacf.fr/t/hacs-ajoutez-des-modules-et-des-cartes-personnalisees/359
125 |
126 | *************
127 |
--------------------------------------------------------------------------------
/dist/content-card-linky-editor.js:
--------------------------------------------------------------------------------
1 | const fireEvent = (node, type, detail, options) => {
2 | options = options || {};
3 | detail = detail === null || detail === undefined ? {} : detail;
4 | const event = new Event(type, {
5 | bubbles: options.bubbles === undefined ? true : options.bubbles,
6 | cancelable: Boolean(options.cancelable),
7 | composed: options.composed === undefined ? true : options.composed,
8 | });
9 | event.detail = detail;
10 | node.dispatchEvent(event);
11 | return event;
12 | };
13 |
14 | if (
15 | !customElements.get("ha-switch") &&
16 | customElements.get("paper-toggle-button")
17 | ) {
18 | customElements.define("ha-switch", customElements.get("paper-toggle-button"));
19 | }
20 |
21 | if (!customElements.get("ha-entity-picker")) {
22 | (customElements.get("hui-entities-card")).getConfigElement();
23 | }
24 |
25 | const LitElement = customElements.get("hui-masonry-view") ? Object.getPrototypeOf(customElements.get("hui-masonry-view")) : Object.getPrototypeOf(customElements.get("hui-view"));
26 | const html = LitElement.prototype.html;
27 | const css = LitElement.prototype.css;
28 |
29 | const HELPERS = window.loadCardHelpers();
30 |
31 | export class contentCardLinkyEditor extends LitElement {
32 | setConfig(config) {
33 | this._config = { ...config };
34 | }
35 |
36 | static get properties() {
37 | return { hass: {}, _config: {} };
38 | }
39 |
40 | get _entity() {
41 | return this._config.entity || "";
42 | }
43 |
44 | get _ewEntity() {
45 | return this._config.ewEntity || "";
46 | }
47 |
48 | get _ewEntityJ1() {
49 | return this._config.ewEntityJ1 || "";
50 | }
51 |
52 | get _ewEntityJ2() {
53 | return this._config.ewEntityJ2 || "";
54 | }
55 |
56 | get _tempoEntity() {
57 | return this._config.tempoEntityInfo || "";
58 | }
59 |
60 | get _tempoEntityJ0() {
61 | return this._config.tempoEntityJ0 || "";
62 | }
63 |
64 | get _tempoEntityJ1() {
65 | return this._config.tempoEntityJ1 || "";
66 | }
67 |
68 | get _name() {
69 | return this._config.name || "";
70 | }
71 |
72 | get _showIcon() {
73 | return this._config.showIcon !== false;
74 | }
75 |
76 | get _showHeader() {
77 | return this._config.showHeader !== false;
78 | }
79 |
80 | get _showHistory() {
81 | return this._config.showHistory !== false;
82 | }
83 |
84 | get _showPeakOffPeak() {
85 | return this._config.showPeakOffPeak !== false;
86 | }
87 |
88 | get _showInTableUnit() {
89 | return this._config.showInTableUnit !== false;
90 | }
91 |
92 | get _showDayPrice() {
93 | return this._config.showDayPrice !== false;
94 | }
95 |
96 | get _showDayPriceHCHP() {
97 | return this._config.showDayPriceHCHP !== false;
98 | }
99 |
100 | get _showDayMaxPower() {
101 | return this._config.showDayMaxPower !== false;
102 | }
103 |
104 | get _showPrice() {
105 | return this._config.showPrice !== false;
106 | }
107 |
108 | get _showTitle() {
109 | return this._config.showTitle !== false;
110 | }
111 |
112 | get _showDayHCHP() {
113 | return this._config.showDayHCHP !== false;
114 | }
115 |
116 | get _showCurrentMonthRatio() {
117 | return this._config.showCurrentMonthRatio !== false;
118 | }
119 |
120 | get _showMonthRatio() {
121 | return this._config.showMonthRatio !== false;
122 | }
123 |
124 | get _showYearRatio() {
125 | return this._config.showYearRatio !== false;
126 | }
127 |
128 | get _showWeekRatio() {
129 | return this._config.showWeekRatio !== false;
130 | }
131 |
132 | get _showYesterdayRatio() {
133 | return this._config.showYesterdayRatio !== false;
134 | }
135 | get _showError() {
136 | return this._config.showError !== false;
137 | }
138 | get _showTitreLigne() {
139 | return this._config.showTitreLigne !== false;
140 | }
141 | get _showEcoWatt() {
142 | return this._config.showEcoWatt !== false;
143 | }
144 | get _showEcoWattJ12() {
145 | return this._config.showEcoWattJ12 !== false;
146 | }
147 |
148 | get _showTempo() {
149 | return this._config.showTempo !== false;
150 | }
151 |
152 | get _title() {
153 | return this._config.showTitle !== false;
154 | }
155 |
156 | get _current() {
157 | return this._config.current !== false;
158 | }
159 |
160 | get _details() {
161 | return this._config.details !== false;
162 | }
163 |
164 | get _nbJoursAffichage() {
165 | return this._config.nbJoursAffichage || 7;
166 | }
167 |
168 | get _showDayName() {
169 | return this._config.showDayName;
170 | }
171 |
172 | get _titleName() {
173 | return this._config.titleName || "";
174 | }
175 |
176 | firstUpdated() {
177 | HELPERS.then(help => {
178 | if (help.importMoreInfoControl) {
179 | help.importMoreInfoControl("fan");
180 | }
181 | })
182 | }
183 |
184 | render() {
185 | if (!this.hass) {
186 | return html``;
187 | }
188 |
189 | return html`
190 |
191 |
192 |
198 | ${this.renderSensorPicker("Entity", this._entity, "entity")}
199 | ${this.renderSensorPicker("EcoWatt", this._ewEntity, "ewEntity")}
200 | ${this.renderSensorPicker("EcoWattJ1", this._ewEntityJ1, "ewEntityJ1")}
201 | ${this.renderSensorPicker("EcoWattJ2", this._ewEntityJ2, "ewEntityJ2")}
202 | ${this.renderSensorPicker("TempoInfo", this._tempoEntityInfo, "tempoEntityInfo")}
203 | ${this.renderSensorPicker("TempoJ0", this._tempoEntityJ0, "tempoEntityJ0")}
204 | ${this.renderSensorPicker("TempoJ1", this._tempoEntityJ1, "tempoEntityJ1")}
205 |
206 |
207 | ${this.renderSwitchOption("Show icon", this._showIcon, "showIcon")}
208 | ${this.renderSwitchOption("Show titre", this._showTitle, "showTitle")}
209 | ${this.renderSwitchOption("Show history", this._showHistory, "showHistory")}
210 | ${this.renderSwitchOption("Show Heures Creuses", this._showPeakOffPeak, "showPeakOffPeak")}
211 | ${this.renderSwitchOption("Show unité", this._showInTableUnit, "showInTableUnit")}
212 | ${this.renderSwitchOption("Show prix/jour", this._showDayPrice, "showDayPrice")}
213 | ${this.renderSwitchOption("Show prix HC/HP", this._showDayPriceHCHP, "showDayPriceHCHP")}
214 | ${this.renderSwitchOption("Show prix", this._showPrice, "showPrice")}
215 | ${this.renderSwitchOption("Show jours HC/HP", this._showDayHCHP, "showDayHCHP")}
216 | ${this.renderSwitchOption("Show jours Max Puissance", this._showDayMaxPower, "showDayMaxPower")}
217 | ${this.renderSwitchOption("Show ratio year", this._showYearRatio, "showYearRatio")}
218 | ${this.renderSwitchOption("Show ratio mois", this._showCurrentMonthRatio, "showCurrentMonthRatio")}
219 | ${this.renderSwitchOption("Show ratio mois precedent", this._showMonthRatio, "showMonthRatio")}
220 | ${this.renderSwitchOption("Show ratio semaine", this._showWeekRatio, "showWeekRatio")}
221 | ${this.renderSwitchOption("Show ratio hier", this._showYesterdayRatio, "showYesterdayRatio")}
222 | ${this.renderSwitchOption("Show titre ligne", this._showTitreLigne, "showTitreLigne")}
223 | ${this.renderSwitchOption("Show error", this._showError, "showError")}
224 | ${this.renderSwitchOption("Show header", this._showHeader, "showHeader")}
225 | ${this.renderSwitchOption("Show EcoWatt J", this._showEcoWatt, "showEcoWatt")}
226 | ${this.renderSwitchOption("Show EcoWatt J+1 et J+2", this._showEcoWattJ12, "showEcoWattJ12")}
227 | ${this.renderSwitchOption("Show Tempo", this._showTempo, "showTempo")}
228 |
229 |
230 |
239 |
245 |
246 |
247 | `;
248 | }
249 |
250 | renderSensorPicker(label, entity, configAttr) {
251 | return this.renderPicker(label, entity, configAttr, "sensor");
252 | }
253 |
254 | renderPicker(label, entity, configAttr, domain) {
255 | return html`
256 |
265 | `
266 | }
267 |
268 | renderSwitchOption(label, state, configAttr) {
269 | return html`
270 |
271 |
275 | ${label}
276 |
277 |
278 | `
279 | }
280 | _valueChanged(ev) {
281 | if (!this._config || !this.hass) {
282 | return;
283 | }
284 | const target = ev.target;
285 | if (target.configValue) {
286 | if (target.value === "") {
287 | delete this._config[target.configValue];
288 | } else {
289 | this._config = {
290 | ...this._config,
291 | [target.configValue]:
292 | target.checked !== undefined ? target.checked : target.value,
293 | };
294 | }
295 | }
296 | fireEvent(this, "config-changed", { config: this._config });
297 | }
298 |
299 | static get styles() {
300 | return css`
301 | .switches {
302 | margin: 8px 0;
303 | display: flex;
304 | flex-flow: row wrap;
305 | list-style: none;
306 | padding: 0;
307 | }
308 | .switch {
309 | display: flex;
310 | align-items: center;
311 | width: 50%;
312 | height: 40px;
313 | }
314 | .switches span {
315 | padding: 0 16px;
316 | }
317 | `;
318 | }
319 | }
320 |
321 | customElements.define("content-card-linky-editor", contentCardLinkyEditor);
322 |
--------------------------------------------------------------------------------
/dist/content-card-linky.js:
--------------------------------------------------------------------------------
1 | const LitElement = Object.getPrototypeOf(
2 | customElements.get("ha-panel-lovelace")
3 | );
4 | const html = LitElement.prototype.html;
5 | const css = LitElement.prototype.css;
6 |
7 |
8 | window.customCards = window.customCards || [];
9 | window.customCards.push({
10 | type: "content-card-linky",
11 | name: "Carte Enedis1",
12 | description: "Carte pour l'intégration myElectricalData.",
13 | preview: true,
14 | documentationURL: "https://github.com/saniho/content-card-linky",
15 | });
16 | const fireEvent = (node, type, detail, options) => {
17 | options = options || {};
18 | detail = detail === null || detail === undefined ? {} : detail;
19 | const event = new Event(type, {
20 | bubbles: options.bubbles === undefined ? true : options.bubbles,
21 | cancelable: Boolean(options.cancelable),
22 | composed: options.composed === undefined ? true : options.composed,
23 | });
24 | event.detail = detail;
25 | node.dispatchEvent(event);
26 | return event;
27 | };
28 |
29 | const ecoWattForecastValues = new Map([
30 | ["Pas de valeur", "green"],
31 | [1, "green"],
32 | [2, "yellow"],
33 | [3, "red"],
34 | ]);
35 |
36 | const tempoValues = new Map([
37 | ["unknown", "grey"],
38 | ["Inconnu", "grey"],
39 | ["BLUE", "blue"],
40 | ["WHITE", "white"],
41 | ["RED", "red"],
42 | ]);
43 |
44 |
45 | function hasConfigOrEntityChanged(element, changedProps) {
46 | if (changedProps.has("config")) {
47 | return true;
48 | }
49 |
50 | const oldHass = changedProps.get("hass");
51 | if (oldHass) {
52 | return (
53 | oldHass.states[element.config.entity] !==
54 | element.hass.states[element.config.entity]
55 | );
56 | }
57 |
58 | return true;
59 | }
60 |
61 | class ContentCardLinky extends LitElement {
62 | static get properties() {
63 | return {
64 | config: {},
65 | hass: {}
66 | };
67 | }
68 |
69 | static async getConfigElement() {
70 | await import("./content-card-linky-editor.js");
71 | return document.createElement("content-card-linky-editor");
72 | }
73 |
74 | render() {
75 | if (!this.config || !this.hass) {
76 | return html``;
77 | }
78 |
79 | const stateObj = this.hass.states[this.config.entity];
80 |
81 | if (!stateObj) {
82 | return html`
83 |
84 |
85 |
86 |
87 |
88 | Linky : donnees inaccessible pour ${this.config.entity}
89 |
90 |
91 |
92 |
93 | `
94 | }
95 |
96 | const attributes = stateObj.attributes;
97 | const modeCompteur = attributes["typeCompteur"];
98 |
99 | if (stateObj) {
100 | if (( modeCompteur === "consommation" ) || ( !modeCompteur )){
101 | return html`
102 |
103 | ${this.addEventListener('click', event => { this._showDetails(this.config.entity); })}
104 | ${this.renderTitle(this.config)}
105 |
106 | ${this.renderHeader(attributes, this.config, stateObj)}
107 |
108 | ${this.config.showYearRatio
109 | ? html `
110 |
111 |
112 |
113 |
114 |
115 |
116 | ${Math.round(attributes.yearly_evolution)} %par rapport à ${this.previousYear()}
117 | A-1 : ${attributes.current_year_last_year}
A : ${attributes.current_year}
118 |
119 | `
120 | : html ``
121 | }
122 | ${this.config.showMonthRatio
123 | ? html `
124 |
125 |
126 |
127 |
128 |
129 |
130 | ${Math.round(attributes.monthly_evolution)} %par rapport à ${this.previousMonth()}
131 | Mois Precedent A-1 : ${attributes.last_month_last_year}
Mois Precedent : ${attributes.last_month}
132 |
133 | `
134 | : html ``
135 | }
136 | ${this.config.showCurrentMonthRatio
137 | ? html `
138 |
139 |
140 |
141 |
142 |
143 |
144 | ${Math.round(attributes.current_month_evolution)} %par rapport à ${this.currentMonth()}
145 | Mois A-1 : ${attributes.current_month_last_year}
Mois : ${attributes.current_month}
146 |
147 | `
148 | : html ``
149 | }
150 | ${this.config.showWeekRatio
151 | ? html `
152 |
153 |
154 |
155 |
156 |
157 |
158 | ${Math.round(attributes.current_week_evolution)} %par rapport à ${this.weekBefore()}
159 | Semaine dernière : ${attributes.last_week}
Semaine courante : ${attributes.current_week}
160 |
161 | `
162 | : html ``
163 | }
164 | ${this.config.showYesterdayRatio
165 | ? html `
166 |
167 |
168 |
169 |
170 |
171 |
172 | ${Math.round(attributes.yesterday_evolution)} %par rapport à ${this.dayBeforeYesterday()}
173 | Avant-hier : ${attributes.day_2}
Hier : ${attributes.yesterday}
174 |
175 | `
176 | : html ``
177 | }
178 | ${this.config.showPeakOffPeak
179 | ? html `
180 |
181 |
182 |
183 |
184 | ${Math.round(attributes.peak_offpeak_percent)} % HP
185 | `
186 | : html ``
187 | }
188 |
189 |
190 | ${this.renderHistory(attributes.daily, attributes.unit_of_measurement, attributes.dailyweek, attributes.dailyweek_cost, attributes.dailyweek_costHC, attributes.dailyweek_costHP, attributes.dailyweek_HC, attributes.dailyweek_HP, attributes.dailyweek_MP, attributes.dailyweek_MP_over, attributes.dailyweek_MP_time, this.config)}
191 | ${this.renderEcoWatt(attributes, this.config)}
192 | ${this.renderTempo(attributes, this.config)}
193 | ${this.renderError(attributes.errorLastCall, this.config)}
194 | ${this.renderVersion(attributes.versionUpdateAvailable, attributes.versionGit)}
195 | ${this.renderInformation(attributes, this.config)}
196 |
197 | `
198 | }
199 | if ( modeCompteur === "production" ){
200 | return html`
201 |
202 |
203 |
204 | ${this.config.showIcon
205 | ? html`
206 |
207 |
208 |
`
209 | : html ``
210 | }
211 |
212 | ${this.toFloat(stateObj.state)}
213 | ${attributes.unit_of_measurement}
214 |
215 |
216 | ${this.renderError(attributes.errorLastCall, this.config)}
217 |
218 | `
219 | }
220 | }
221 | }
222 | _showDetails(myEntity) {
223 | const event = new Event('hass-more-info', {
224 | bubbles: true,
225 | cancelable: false,
226 | composed: true
227 | });
228 | event.detail = {
229 | entityId: myEntity
230 | };
231 | this.dispatchEvent(event);
232 | return event;
233 | }
234 | renderTitle(config) {
235 | if (this.config.showTitle === true) {
236 | return html
237 | `
238 |
239 |
240 | ${this.config.titleName}
241 |
242 |
`
243 | }
244 | }
245 | renderHeader(attributes, config, stateObj) {
246 | if (this.config.showHeader === true) {
247 | if( config.showPeakOffPeak ) {
248 | return html`
249 |
250 | ${this.renderIcon(attributes, config)}
251 |
252 | ${this.toFloat(attributes.yesterday_HC)} ${attributes.unit_of_measurement} (en HC)
253 | ${this.toFloat(attributes.yesterday_HP)} ${attributes.unit_of_measurement} (en HP)
254 |
255 | ${this.renderPrice(attributes, config)}
256 |
`
257 | }
258 | else{
259 | return html`
260 |
261 | ${this.renderIcon(attributes, config)}
262 |
263 | ${this.toFloat(stateObj.state)}
264 | ${attributes.unit_of_measurement}
265 |
266 | ${this.renderPrice(attributes, config)}
267 |
`
268 | }
269 | }
270 | }
271 | renderIcon(attributes, config) {
272 | if ( this.config.showIcon ){
273 | return html `
274 |
275 |
276 |
`
277 | }
278 | else{
279 | return html ``
280 | }
281 | }
282 | renderPrice(attributes, config) {
283 | if ( this.config.showPrice ){
284 | return html `
285 |
286 | ${this.toFloat(attributes.daily_cost, 2)} €
287 |
`
288 | }
289 | else{
290 | return html ``
291 | }
292 | }
293 | renderError(errorMsg, config) {
294 | if (this.config.showError === true) {
295 | if ( errorMsg != "" ){
296 | return html
297 | `
298 |
299 |
300 | ${errorMsg}
301 |
302 | `
303 | }
304 | }
305 | }
306 | renderInformation(attributes, config) {
307 | if (attributes.serviceEnedis === undefined ) {
308 | return html ``
309 | }
310 | else{
311 | if ( attributes.serviceEnedis !== "myElectricalData" ){
312 | return html `
313 |
314 |
315 | Merci de migrer sur myElectricalData.
316 | EnedisGateway sera desactivé courant 2023.
317 |
318 | `
319 | }
320 | }
321 | }
322 | renderVersion(versionUpdateAvailable, versionGit) {
323 | if ( versionUpdateAvailable === true ){
324 | return html
325 | `
326 |
327 |
328 | Nouvelle version disponible ${versionGit}
329 |
330 | `
331 | }
332 | else{
333 | return html ``
334 | }
335 | }
336 |
337 | renderHistory(daily, unit_of_measurement, dailyweek, dailyweek_cost, dailyweek_costHC, dailyweek_costHP, dailyweek_HC, dailyweek_HP, dailyweek_MP, dailyweek_MP_over, dailyweek_MP_time, config) {
338 | if (this.config.showHistory === true) {
339 | if ( dailyweek != undefined){
340 | var nbJours = dailyweek.toString().split(",").length ;
341 | if ( config.nbJoursAffichage <= nbJours ) { nbJours = config.nbJoursAffichage }
342 | return html
343 | `
344 |
345 | ${this.renderTitreLigne(config)}
346 | ${daily.slice(0, nbJours).reverse().map((day, index) => this.renderDay(day, nbJours-index, unit_of_measurement, dailyweek, dailyweek_cost, dailyweek_costHC, dailyweek_costHP,
347 | dailyweek_HC, dailyweek_HP, dailyweek_MP, dailyweek_MP_over, dailyweek_MP_time, config))}
348 |
349 | `
350 | }
351 | }
352 | }
353 |
354 | renderDay(day, dayNumber, unit_of_measurement, dailyweek, dailyweek_cost, dailyweek_costHC, dailyweek_costHP, dailyweek_HC, dailyweek_HP, dailyweek_MP, dailyweek_MP_over, dailyweek_MP_time, config) {
355 | return html
356 | `
357 |
358 | ${this.renderDailyWeek(dailyweek, dayNumber, config)}
359 | ${this.renderDailyValue(day, dayNumber, unit_of_measurement, config)}
360 | ${this.renderDayPrice(dailyweek_cost, dayNumber, config)}
361 | ${this.renderDayPriceHCHP(dailyweek_costHC, dayNumber, config)}
362 | ${this.renderDayPriceHCHP(dailyweek_costHP, dayNumber, config)}
363 | ${this.renderDayHCHP(dailyweek_HC, dayNumber, unit_of_measurement, config)}
364 | ${this.renderDayHCHP(dailyweek_HP, dayNumber, unit_of_measurement, config)}
365 | ${this.renderDayMaxPower(dailyweek_MP, dayNumber, dailyweek_MP_over, dailyweek_MP_time, config)}
366 |
367 | `
368 | }
369 | renderDailyWeekTitre( maConfig, monTitre ){
370 | if (maConfig === true) {
371 | return html
372 | `${monTitre}
373 | `
374 | }
375 | else{
376 | return html
377 | `
378 | `
379 | }
380 | }
381 | renderTitreLigne(config) {
382 | if (this.config.showTitreLigne === true) {
383 | return html
384 | `
385 |
386 | ${this.renderDailyWeekTitre(true, "")}
387 | ${this.renderDailyWeekTitre(true, "Conso")}
388 | ${this.renderDailyWeekTitre(this.config.showDayPrice, "Prix")}
389 | ${this.renderDailyWeekTitre(this.config.showDayPriceHCHP, "Prix HC")}
390 | ${this.renderDailyWeekTitre(this.config.showDayPriceHCHP, "Prix HP")}
391 | ${this.renderDailyWeekTitre(this.config.showDayHCHP, "HC")}
392 | ${this.renderDailyWeekTitre(this.config.showDayHCHP, "HP")}
393 | ${this.renderDailyWeekTitre(this.config.showDayMaxPower, "MP")}
394 | ${this.renderDailyWeekTitre(this.config.showDayMaxPowerTime, "MPtime")}
395 |
396 | `
397 | }
398 | }
399 | r_enderTitreLigne(config) {
400 | if (this.config.showTitreLigne === true) {
401 | return html
402 | `
403 |
404 |
Conso.
405 | ${this.config.showDayPrice
406 | ? html `
407 |
Prix`
408 | : html ``
409 | }
410 | ${this.config.showDayPriceHCHP
411 | ? html `
412 |
Prix HC`
413 | : html ``
414 | }
415 | ${this.config.showDayPriceHCHP
416 | ? html `
417 |
Prix HP`
418 | : html ``
419 | }
420 | ${this.config.showDayHCHP
421 | ? html `
422 |
HC`
423 | : html ``
424 | }
425 | ${this.config.showDayHCHP
426 | ? html `
427 |
HP`
428 | : html ``
429 | }
430 | ${this.config.showDayMaxPower
431 | ? html `
432 |
MP`
433 | : html ``
434 | }
435 | ${this.config.showDayMaxPower
436 | ? html `
437 |
MPtime`
438 | : html ``
439 | }
440 |
441 | `;
442 | }
443 | }
444 | renderDailyWeek(value, dayNumber, config) {
445 | return html
446 | `
447 | ${new Date(value.toString().split(",")[dayNumber-1]).toLocaleDateString('fr-FR', {weekday: config.showDayName})}
448 | `;
449 | }
450 | renderNoData(){
451 | return html
452 | `
453 |
454 | ` ;
455 | }
456 | renderDailyValue(day, dayNumber, unit_of_measurement, config) {
457 | if ( day === -1 ){
458 | return this.renderNoData();
459 | }
460 | else{
461 | return html
462 | `
463 |
${this.toFloat(day)}
464 | ${this.config.showInTableUnit
465 | ? html `
466 | ${unit_of_measurement}`
467 | : html ``
468 | }
469 | `;
470 | }
471 | }
472 | renderDayPrice(value, dayNumber, config) {
473 | if (config.kWhPrice) {
474 | return html
475 | `
476 |
${this.toFloat(value * config.kWhPrice, 2)} €
477 | `;
478 | }
479 | if (config.showDayPrice) {
480 | const valeur = value.toString().split(",")[dayNumber-1] ;
481 | if ( valeur === "-1" ){
482 | return this.renderNoData();
483 | }
484 | else{
485 | return html
486 | `
487 |
${this.toFloat(valeur)} €
488 | `;
489 | }
490 | }
491 | }
492 | renderDayPriceHCHP(value, dayNumber, config) {
493 | if (config.showDayPriceHCHP) {
494 | const valeur = value.toString().split(",")[dayNumber-1] ;
495 | if ( valeur === "-1" ){
496 | return this.renderNoData();
497 | }
498 | else{
499 | return html
500 | `
501 |
${this.toFloat(valeur, 2)} €
502 | `;
503 | }
504 | }
505 | }
506 | renderDayHCHP(value, dayNumber, unit_of_measurement, config) {
507 | if (config.showDayHCHP) {
508 | const valeur = value.toString().split(",")[dayNumber-1] ;
509 | if ( valeur === "-1" ){
510 | return this.renderNoData();
511 | }
512 | else{
513 | return html
514 | `
515 |
${this.toFloat(valeur, 2)}
516 | ${this.config.showInTableUnit
517 | ? html `
518 | ${unit_of_measurement}`
519 | : html ``
520 | }
521 | `;
522 | }
523 | }
524 | }
525 | renderDayMaxPower(value, dayNumber, overMP, MPtime, config) {
526 | if (config.showDayMaxPower) {
527 | const valeur = value.toString().split(",")[dayNumber-1] ;
528 | const over = overMP.toString().split(",")[dayNumber-1];
529 | if ( valeur === "-1" ){
530 | return this.renderNoData();
531 | }
532 | else{
533 | if ( over === "true") {
534 | return html
535 | `
536 |
${this.toFloat(valeur, 2)}
537 |
${new Date(MPtime.toString().split(",")[dayNumber-1]).toLocaleTimeString('fr-FR', { hour: "2-digit", minute: "2-digit" }) }
538 | `;
539 | }
540 | else {
541 | return html
542 | `
543 |
${this.toFloat(valeur, 2)}
544 |
${new Date(MPtime.toString().split(",")[dayNumber-1]).toLocaleTimeString('fr-FR', { hour: "2-digit", minute: "2-digit" }) }
545 | `;
546 | }
547 | }
548 | }
549 | }
550 |
551 | renderDayMaxPowerTime(value, dayNumber, overMP, config) {
552 | if (config.showDayMaxPower) {
553 | const valeur = value.toString.split(",")[dayNumber-1] ;
554 | const over = overMP.toString().split(",")[dayNumber-1];
555 | if ( valeur === "-1" ){
556 | return this.renderNoData();
557 | }
558 | else{
559 | if ( over === "true") {
560 | return html
561 | `
562 |
${this.toFloat(valeur, 2)}
563 | `;
564 | }
565 | else {
566 | return html
567 | `
568 |
${this.toFloat(valeur, 2)}
569 | `;
570 | }
571 | }
572 | }
573 | }
574 |
575 | getOneDayForecastTime(ecoWattForecast) {
576 | let ecoWattForecastDate = new Date(ecoWattForecast.attributes["date"]);
577 | return [ecoWattForecastDate];
578 | }
579 |
580 | getOneDayNextEcoWattText(ecoWattForecastEntity) {
581 | let forecastDate = new Date(ecoWattForecastEntity.attributes["date"]);
582 | for (let [time, value] of Object.entries(
583 | ecoWattForecastEntity.attributes["forecast"]
584 | )) {
585 | if ( time != undefined && ecoWattForecastValues.get(value) !== "green" ) {
586 | let timeStr = time.replace(/([345])5/g, "$10");
587 | return html `Actuellement: ${ecoWattForecastValues.get(value)}`;
588 | } else
589 | {
590 | return html `Ecowatt ${ forecastDate.toLocaleDateString('fr-FR', {weekday: 'long', day: 'numeric'}) }`;
591 | }
592 | }
593 | return ""
594 | }
595 |
596 | getOneDayNextEcoWatt(ecoWattForecastEntity) {
597 | let ecoWattForecastList = [];
598 | for (let [time, value] of Object.entries(
599 | ecoWattForecastEntity.attributes["forecast"]
600 | )) {
601 | if (time != undefined) {
602 | time = time.replace("h", "").trim();
603 | time = time.replace("min", "").trim();
604 | ecoWattForecastList.push([time, ecoWattForecastValues.get(value), value]);
605 | }
606 | }
607 |
608 | return ecoWattForecastList;
609 | }
610 |
611 | renderEcoWatt(attributes, config) {
612 | if (attributes.serviceEnedis === undefined ){
613 | return html ``;
614 | }
615 | if ( attributes.serviceEnedis !== "myElectricalData" ){
616 | return html `EcoWatt : uniquement disponible avec myElectricData`;
617 | }
618 |
619 | let sensorName = this.config.ewEntity;
620 | const ecoWattForecast = this.hass.states[sensorName];
621 | let sensorNameJ1 = this.config.ewEntityJ1;
622 | const ecoWattForecastJ1 = this.hass.states[sensorNameJ1];
623 | let sensorNameJ2 = this.config.ewEntityJ2;
624 | const ecoWattForecastJ2 = this.hass.states[sensorNameJ2];
625 |
626 | return html`
627 |
628 | ${this.config.showEcoWatt
629 | ? html`
630 |
631 | | J+0 |
632 |
633 |
634 | ${html`
635 | ${this.getOneDayNextEcoWatt(ecoWattForecast).map(
636 | (forecast) => html`
637 | `
638 | )}
639 | `}
640 |
641 | |
642 |
`
643 | : html ``}
644 | ${this.config.showEcoWattJ12
645 | ? html`
646 |
647 | | J+1 |
648 |
649 |
650 | ${html`
651 | ${this.getOneDayNextEcoWatt(ecoWattForecastJ1).map(
652 | (forecast) => html`
653 | `
654 | )}
655 | `}
656 |
657 | |
658 |
659 |
660 | | J+2 |
661 |
662 |
663 | ${html`
664 | ${this.getOneDayNextEcoWatt(ecoWattForecastJ2).map(
665 | (forecast) => html`
666 | `
667 | )}
668 | `}
669 |
670 | |
671 |
672 |
673 | | |
674 |
675 |
676 | ${html`
677 | ${this.getOneDayNextEcoWatt(ecoWattForecastJ2).map(
678 | (forecast) => html`
679 | - ${(forecast[0]%2==1) ? forecast[0] : ''}
`
680 | )}
681 | `}
682 |
683 | |
684 |
685 | `
686 | : html``}
687 | `;
688 | }
689 |
690 | getTempoDateValue(tempoEntity) {
691 | let tempoDate = new Date(tempoEntity.attributes["date"]);
692 | let tempoValue = tempoEntity.state;
693 | return [tempoDate, tempoValues.get(tempoValue), tempoValue];
694 | }
695 |
696 | getTempoRemainingDays(tempoEntity) {
697 | let tempoRemainingRed = tempoEntity.attributes["days_red"];
698 | let tempoRemainingWhite = tempoEntity.attributes["days_white"];
699 | let tempoRemainingBlue = tempoEntity.attributes["days_blue"];
700 | return [tempoRemainingRed, tempoRemainingWhite, tempoRemainingBlue];
701 | }
702 |
703 | renderTempo(attributes, config) {
704 | if (attributes.serviceEnedis === undefined ){
705 | return html ``;
706 | }
707 | if ( attributes.serviceEnedis !== "myElectricalData" ){
708 | return html `EcoWatt : uniquement disponible avec myElectricData`;
709 | }
710 | if (this.config.showTempo === false ){
711 | return html ``;
712 | }
713 | let sensorName = this.config.tempoEntityInfo;
714 | const tempoInfo = this.hass.states[sensorName];
715 | let sensorNameJ0 = this.config.tempoEntityJ0;
716 | const tempoJ0 = this.hass.states[sensorNameJ0];
717 | let sensorNameJ1 = this.config.tempoEntityJ1;
718 | const tempoJ1 = this.hass.states[sensorNameJ1];
719 |
720 | if (!tempoJ0 || tempoJ0.length === 0 || !tempoJ1 || tempoJ1.length === 0) {
721 | return html `Tempo: sensor(s) J0 et/ou J1 indisponible ou incorrecte`;
722 | }
723 | if (!tempoInfo || tempoInfo.length === 0) {
724 | return html `Tempo: sensor 'info' indisponible ou incorrecte`;
725 | }
726 |
727 | let [dateJ0, valueJ0, stateJ0] = this.getTempoDateValue(tempoJ0);
728 | let [dateJ1, valueJ1, stateJ1] = this.getTempoDateValue(tempoJ1);
729 | let [remainingRed, remainingWhite, remainingBlue] = this.getTempoRemainingDays(tempoInfo);
730 |
731 | return html`
732 |
733 |
734 | | ${ (new Date(dateJ0)).toLocaleDateString('fr-FR', {weekday: 'long', day: 'numeric'})} |
735 | ${ (new Date(dateJ1)).toLocaleDateString('fr-FR', {weekday: 'long', day: 'numeric'})} |
736 |
737 |
738 |
739 |
740 | | ${remainingBlue} |
741 | ${remainingWhite} |
742 | ${remainingRed} |
743 |
744 |
745 |
746 | `
747 |
748 | }
749 |
750 | setConfig(config) {
751 | if (!config.entity) {
752 | throw new Error('You need to define an entity');
753 | }
754 |
755 | if (config.kWhPrice && isNaN(config.kWhPrice)) {
756 | throw new Error('kWhPrice should be a number')
757 | }
758 |
759 | const defaultConfig = {
760 | showHistory: true,
761 | showHeader: true,
762 | showPeakOffPeak: true,
763 | showIcon: false,
764 | showInTableUnit: false,
765 | showDayPrice: false,
766 | showDayPriceHCHP: false,
767 | showDayMaxPower: false,
768 | showDayHCHP: false,
769 | showDayName: "long",
770 | showError: true,
771 | shoInformation: true,
772 | showPrice: true,
773 | showTitle: false,
774 | showCurrentMonthRatio: true,
775 | showMonthRatio: true,
776 | showWeekRatio: false,
777 | showYesterdayRatio: false,
778 | showTitreLigne: false,
779 | showEcoWatt: false,
780 | showEcoWattJ12: false,
781 | showTempo: false,
782 | titleName: "",
783 | nbJoursAffichage: 7,
784 | kWhPrice: undefined,
785 | }
786 |
787 | this.config = {
788 | ...defaultConfig,
789 | ...config
790 | };
791 | }
792 |
793 | shouldUpdate(changedProps) {
794 | return hasConfigOrEntityChanged(this, changedProps);
795 | }
796 |
797 | // @TODO: This requires more intelligent logic
798 | getCardSize() {
799 | return 3;
800 | }
801 |
802 | toFloat(value, decimals = 1) {
803 | return Number.parseFloat(value).toFixed(decimals);
804 | }
805 |
806 | previousYear() {
807 | var d = new Date();
808 | d.setFullYear(d.getFullYear()-1 );
809 |
810 | return d.toLocaleDateString('fr-FR', {year: "numeric"});
811 | }
812 |
813 | previousMonth() {
814 | var d = new Date();
815 | d.setMonth(d.getMonth()-1) ;
816 | d.setFullYear(d.getFullYear()-1 );
817 |
818 | return d.toLocaleDateString('fr-FR', {month: "long", year: "numeric"});
819 | }
820 | currentMonth() {
821 | var d = new Date();
822 | d.setFullYear(d.getFullYear()-1 );
823 |
824 | return d.toLocaleDateString('fr-FR', {month: "long", year: "numeric"});
825 | }
826 | weekBefore() {
827 | return "semaine";
828 | }
829 | dayBeforeYesterday() {
830 | return "avant-hier";
831 | }
832 |
833 |
834 | static get styles() {
835 | return css`
836 | .card {
837 | margin: auto;
838 | padding: 1.5em 1em 1em 1em;
839 | position: relative;
840 | cursor: pointer;
841 | }
842 |
843 | ha-card ul {
844 | list-style: none;
845 | padding: 0;
846 | margin: 0;
847 | }
848 |
849 | .main-title {
850 | margin: auto;
851 | text-align: center;
852 | font-weight: 200;
853 | font-size: 2em;
854 | justify-content: space-between;
855 | }
856 | .main-info {
857 | display: flex;
858 | overflow: hidden;
859 | align-items: center;
860 | justify-content: space-between;
861 | height: 75px;
862 | }
863 |
864 | .ha-icon {
865 | margin-right: 5px;
866 | color: var(--paper-item-icon-color);
867 | }
868 |
869 | .cout-block {
870 | }
871 |
872 | .cout {
873 | font-weight: 300;
874 | font-size: 3.5em;
875 | }
876 |
877 | .cout-unit {
878 | font-weight: 300;
879 | font-size: 1.2em;
880 | display: inline-block;
881 | }
882 |
883 | .conso-hp, .conso-hc {
884 | font-weight: 200;
885 | font-size: 2em;
886 | }
887 |
888 | .conso-unit-hc, .conso-unit-hp {
889 | font-weight: 100;
890 | font-size: 1em;
891 | }
892 |
893 | .more-unit {
894 | font-style: italic;
895 | font-size: 0.8em;
896 | }
897 |
898 | .variations {
899 | display: flex;
900 | justify-content: space-between;
901 | overflow: hidden;
902 | }
903 |
904 | .variations-linky {
905 | display: inline-block;
906 | font-weight: 300;
907 | margin: 0px 0px 5px;
908 | overflow: hidden;
909 | }
910 |
911 | .unit {
912 | font-size: .8em;
913 | }
914 |
915 | .week-history {
916 | display: flex;
917 | overflow: hidden;
918 | }
919 |
920 | .day {
921 | flex: auto;
922 | text-align: center;
923 | border-right: .1em solid var(--divider-color);
924 | line-height: 2;
925 | box-sizing: border-box;
926 | }
927 |
928 | .dayname {
929 | font-weight: bold;
930 | text-transform: capitalize;
931 | }
932 |
933 | .week-history .day:last-child {
934 | border-right: none;
935 | }
936 |
937 | .cons-val {
938 | //font-weight: bold;
939 | }
940 |
941 | .year {
942 | font-size: 0.8em;
943 | font-style: italic;
944 | margin-left: 5px;
945 | }
946 | .previous-month {
947 | font-size: 0.8em;
948 | font-style: italic;
949 | margin-left: 5px;
950 | }
951 | .current-month {
952 | font-size: 0.8em;
953 | font-style: italic;
954 | margin-left: 5px;
955 | }
956 | .icon-block {
957 | }
958 | .linky-icon.bigger {
959 | width: 6em;
960 | height: 5em;
961 | display: inline-block;
962 | }
963 | .error {
964 | font-size: 0.8em;
965 | font-style: bold;
966 | margin-left: 5px;
967 | }
968 | .tooltip .tooltiptext {
969 | visibility: hidden;
970 | background: var( --ha-card-background, var(--card-background-color, white) );
971 | box-shadow: 2px 2px 6px -4px #999;
972 | cursor: default;
973 | font-size: 14px;
974 | opacity: 1;
975 | pointer-events: none;
976 | position: absolute;
977 | display: flex;
978 | flex-direction: column;
979 | overflow: hidden;
980 | z-index: 12;
981 | transition: 0.15s ease all;
982 | padding: 5px;
983 | border: 1px solid #cecece;
984 | border-radius: 3px;
985 | }
986 | .tooltip .tooltiptext::after {
987 | content: "";
988 | position: absolute;
989 | top: 100%;
990 | left: 50%;
991 | margin-left: -5px;
992 | border-width: 5px;
993 | border-style: solid;
994 | border-color: #555 transparent transparent transparent;
995 | }
996 | .tooltip:hover .tooltiptext {
997 | visibility: visible;
998 | opacity: 1;
999 | }
1000 |
1001 | .flow-row {
1002 | display: flex;
1003 | flex-flow: row wrap;
1004 | }
1005 | /* One Hour Forecast */
1006 | .oneHour {
1007 | height: 1em;
1008 | }
1009 | .oneHour > li {
1010 | background-color: var(--paper-item-icon-color);
1011 | border-right: 1px solid var(--lovelace-background, var(--primary-background-color));
1012 | }
1013 | .oneHour > li:first-child {
1014 | border-top-left-radius: 5px;
1015 | border-bottom-left-radius: 5px;
1016 | }
1017 | .oneHour > li:last-child {
1018 | border-top-right-radius: 5px;
1019 | border-bottom-right-radius: 5px;
1020 | border: 0;
1021 | }
1022 | /* One Hour Labels */
1023 | .ecowatt-00, .ecowatt-01, .ecowatt-02, .ecowatt-03, .ecowatt-04, .ecowatt-05, .ecowatt-06, .ecowatt-07{
1024 | flex: 2 1 0;
1025 | }
1026 | .ecowatt-08, .ecowatt-09, .ecowatt-10, .ecowatt-11, .ecowatt-12, .ecowatt-13, .ecowatt-14, .ecowatt-15 {
1027 | flex: 2 1 0;
1028 | }
1029 | .ecowatt-16, .ecowatt-17, .ecowatt-18, .ecowatt-19, .ecowatt-20, .ecowatt-21, .ecowatt-22, .ecowatt-23 {
1030 | flex: 2 1 0;
1031 | }
1032 |
1033 | .oneHourLabel > li:first-child {
1034 | flex: 0.70 1 0;
1035 | }
1036 | .oneHourLabel > li {
1037 | flex: 1 1 0;
1038 | text-align: left;
1039 | }
1040 | /* One Hour Header */
1041 | .oneHourHeader {
1042 | justify-content: space-between;
1043 | }
1044 | .oneHourHeader li:last-child {
1045 | text-align: right;
1046 | }
1047 | .tempo-days {
1048 | width:100%;
1049 | border-spacing: 2px;
1050 | }
1051 | .tempo-color {
1052 | width:100%;
1053 | border-spacing: 2px;
1054 | }
1055 | .tempo-blue {
1056 | color: white;
1057 | text-align: center;
1058 | background: #009dfa;
1059 | border: 2px solid var(--divider-color);
1060 | box-shadow: var(--ha-card-box-shadow,none);
1061 |
1062 | }
1063 | .tempo-white {
1064 | color: #002654;
1065 | text-align: center;
1066 | background: white;
1067 | border: 2px solid var(--divider-color);
1068 | box-shadow: var(--ha-card-box-shadow,none);
1069 |
1070 | }
1071 | .tempo-red {
1072 | color: white;
1073 | text-align: center;
1074 | background: #ff2700;
1075 | border: 2px solid var(--divider-color);
1076 | box-shadow: var(--ha-card-box-shadow,none);
1077 | }
1078 | .tempo-grey {
1079 | color: white;
1080 | text-align: center;
1081 | background: grey;
1082 | border: 2px solid var(--divider-color);
1083 | box-shadow: var(--ha-card-box-shadow,none);
1084 | background-image: linear-gradient(45deg, #d6d6d6 25%, #dedede 25%, #dedede 50%, #d6d6d6 50%, #d6d6d6 75%, #dedede 75%, #dedede 100%);
1085 | background-size: 28.28px 28.28px;
1086 | }
1087 | `;
1088 | }
1089 | }
1090 | customElements.define('content-card-linky', ContentCardLinky);
1091 |
--------------------------------------------------------------------------------