Bonjour
Pour commencer, mon « configuration.yaml » pour splitter les fichiers (créée un dossier packages):
############################################
## Organisation des fichiers par packages ##
############################################
homeassistant:
packages: !include_dir_merge_named packages/
Ensuite, dans le dossier packages, j’organise mes differents yaml :
packages/aldes/aldes.yaml =>
aldes_modbus:
modbus:
- name: vmc_modbus
#id: vmc_modbus
type: serial
baudrate: 115200
bytesize: 8
method: rtu
parity: E
# port: /dev/ttyUSB0
port: /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A603D7VH-if00-port0
stopbits: 1
# delay: 5
# timeout: 5
# retries: 5
# retry_on_empty: true
sensors:
# # Identification:
#_____________________________________________________________________________________
#| ADDR | SIZE | NOM DATA | REMARQUES | L/E |
#|______|______|____________________________|___________________________________|_____|
#| 1 | 2 | Code ID Machine | Code SAP | r |
#| 3 | 4 | Numéro de série | | r |
#| 12 | 1 | Version Logiciel | | r |
#| 20 | 1 | Ordre Sauvegarde Parmètres | Mémorisation temporisée Réglages: | r-w |
#| | | | 1s: $5678 / 5s: $1234 / 15s: $7890| |
#|______|______|____________________________|___________________________________|_____|
# word swap
# AABB CCDD > CCDD AABB
# byte swap
# AABB CCDD > BBAA DDCC
# word byte swap
# AABB CCDD > DDCC BBAA
#
- unique_id: vmc_identification_code_id_machine
name: "VMC Code ID Machine"
slave: 2
scan_interval: 3600
data_type: int32
address: 1
count: 2
- unique_id: vmc_identification_serial
name: "VMC Numéro de série"
slave: 2
scan_interval: 3600
data_type: int64
address: 3
count: 4
- unique_id: vmc_identification_version_logiciel
name: "VMC Version Logiciel"
slave: 2
scan_interval: 3600
data_type: int16
address: 12
- unique_id: vmc_identification_ordre_sauvegarde_parametres
name: "VMC Mémorisation Temporisée Réglages"
slave: 2
scan_interval: 3600
data_type: int16
address: 20
# # Mode de fonctionnement:
#_________________________________________________________________________________________
#| ADDR | SIZE | NOM DATA | REMARQUES | L/E |
#|______|______|____________________________|_______________________________________|_____|
#| 256 | 1 | Mode de Régulation | 0:Auto 1:Hydro 2:VitesseConstante | r-w |
#| 257 | 1 | Vitesse Ventilation | 0:Vacances 1:Normal 2:Boost 3:Invités | r-w |
#| 258 | 1 | not used | | |
#| 259 | 1 | Gestion Bypass Echangeur | 0:Off 1:Auto 2:Optimisation Hiver | r-w |
#| | | | 3:Optimisation Eté 4:Ouvert | |
#|______|______|____________________________|_______________________________________|_____|
#
- name: "VMC Mode de fonctionnement"
unique_id: vmc_mode_de_fonctionnement
# input_type: holding
data_type: custom
slave: 2
address: 256
count: 4
scan_interval: 2
structure: ">4h"
# # Tempo de fonctionnement:
#_________________________________________________________________________________________
#| ADDR | SIZE | NOM DATA | REMARQUES | L/E |
#|______|______|____________________________|_______________________________________|_____|
#| 264 | 1 | Durée Vacances | 0:infini nb*5min Max:113 jours 32544| r-w |
#| 265 | 1 | Durée pointe Cuisine | 0:infini nb*5min Max:113 jours | r-w |
#| 266 | 1 | Durée Boost | 0:infini nb*5min Max:113 jours | r-w |
#| 267 | 1 | Durée de vie du filtreur | en mois max: 255 | r-w |
#|______|______|____________________________|_______________________________________|_____|
#
- name: "VMC Tempo de fonctionnement"
unique_id: vmc_tempo_de_fonctionnement
# input_type: holding
data_type: custom
slave: 2
address: 264
count: 4
scan_interval: 5
structure: ">4h"
# # Configuration de fonctionnement:
#___________________________________________________________________________________________
#| ADDR | SIZE | NOM DATA | REMARQUES | L/E |
#|______|______|______________________________|_______________________________________|_____|
#| 272 | 1 | Consigne Débit Extraction | | r-w |
#| 273 | 1 | Consigne Débit Insuflation | | r |
#| 274 | 1 | Consigne Pression Extraction | | r-w |
#| 275 | 1 | Consigne Pression Insuflation| | r |
#| 276 | 1 | Consigne Vitesse Extraction | | r-w |
#| 277 | 1 | Consigne Vitesse Insuflation | | r |
#| 278 | 1 | Balance Débit | | r-w |
#| | | Insuflation/Extraction | | |
#|______|______|______________________________|_______________________________________|_____|
#| 282 | 1 | Consigne Temp. Confort Eté | | r-w |
#| 284 | 1 | Paramètre 0-10V U1 | | r-w |
#| 285 | 1 | Paramètre 0-10V U2 | | r-w |
#|______|______|______________________________|_______________________________________|_____|
#
- name: "VMC Configuration de fonctionnement"
unique_id: vmc_configuration_de_fonctionnement
# input_type: holding
data_type: custom
slave: 2
address: 272
count: 7
scan_interval: 10
structure: ">7h"
- unique_id: vmc_consigne_temp_confort_ete
name: "VMC Consigne Temp. Confort Eté "
slave: 2
scan_interval: 10
data_type: int16
address: 282
- name: "VMC Paramètre 0-10V"
unique_id: vmc_0_10v
# input_type: holding
data_type: custom
slave: 2
address: 284
count: 2
scan_interval: 3600
structure: ">2h"
# # Principales Entrées:
#____________________________________________________________________________________________
#| ADDR | SIZE | NOM DATA | REMARQUES | L/E |
#|______|______|______________________________|________________________________________|_____|
#| 337 | 1 | Tension Alimentation | | r |
#| 338 | 1 | Entrée 0-10V | | r |
#| 339 | 1 | Etats Switchs | b0 = SW1 ... b7 = SW8 | r |
#| 344 | 1 | HIM Installateur | IHM > b0:Clav.Eco à Membrane b1:Coeur | r |
#| 346 | 1 | % Usage Filtre | % | r |
#| 347 | 1 | Temps depuis Reset | Heures | r |
#| 348 | 1 | Etat ByPass | 0:Fermé 1:Ouvert 2:en fermeture | r |
#| | | | 3:en ouverture 4:en court-circuit | |
#| | | | 5:en circuit ouvert 6:sous alimentation| |
#| 349 | 1 | Courant consommé par ByPass | 0 ou >0 | r |
#| 350 | 1 | Température Air Neuf | Sonde Température Ext. x0.01°C | r |
#| 351 | 1 | Température Air Intérieur | Sonde Température Int. x0.01°C | r |
#|______|______|______________________________|________________________________________|_____|
#| 384 | 1 | Code Erreur Actuel | | r |
#|______|______|______________________________|_ ______________________________________|_____|
#
- name: "VMC Principales Entrées"
unique_id: vmc_principales_entrees
# input_type: holding
data_type: custom
slave: 2
address: 337
count: 15
scan_interval: 10
structure: ">15h"
- name: "VMC Code Erreur Actuel"
unique_id: vmc_code_erreur_actuel
data_type: int16
slave: 2
address: 384
scan_interval: 30
timer:
vmc_aldes_duree_timer:
name: "VMC Timer"
duration: 9763200
restore: true
# vmc_aldes_duree_cuisine:
# name: "VMC Timer Cuisine"
# duration: 9763200
# restore: true
# vmc_aldes_duree_boost:
# name: "VMC Timer Boost"
# duration: 9763200
# restore: true
# input_number:
# timer_end:
# name: TimerDateEnd
# min: 0
# max: 9999999999999999999999999999999999999999
sensor:
- platform: template
sensors:
vmc_aldes:
unique_id: vmc_aldes
friendly_name: "VMC Aldes"
value_template: >
{% set val = states('sensor.vmc_mode_de_fonctionnement').split(',')[1] %}
{% if val == "0" %} Vacances {% endif %}
{% if val == "1" %} Normal {% endif %}
{% if val == "2" %} Boost {% endif %}
{% if val == "3" %} Invités {% endif %}
attribute_templates:
id_machine: "{{ states('sensor.vmc_code_id_machine') }}"
serial: "{{ states('sensor.vmc_numero_de_serie') }}"
version_logiciel: "{{ states('sensor.vmc_version_logiciel') }}"
ordre_sauvegarde_parametres: "{{ states('sensor.vmc_memorisation_temporisee_reglages') }}"
mode_de_fonctionnement: "{{ states('sensor.vmc_mode_de_fonctionnement') }}"
tempo_de_fonctionnement: "{{ states('sensor.vmc_tempo_de_fonctionnement') }}"
configuration_de_fonctionnement: "{{ states('sensor.vmc_configuration_de_fonctionnement') }}"
consigne_temp_confort_ete: "{{ states('sensor.vmc_consigne_temp_confort_ete') }}"
vmc_0_10v: "{{ states('sensor.vmc_parametre_0_10v') }}"
principales_entrees: "{{ states('sensor.vmc_principales_entrees') }}"
code_erreur_actuel: "{{ states('sensor.vmc_code_erreur_actuel') }}"
Je regroupe plusieurs infos sur une seul lecture pour éviter de surcharger les appels Modbus. Je divise les infos reçues par le suite dans le code de la carte js.
Dans le dossier www/community je crée un fichier js (kgd-VMC_Aldes-card.js) que j’intègre dans HA
code de la carte:
import { LitElement, html, css, unsafeCSS } from "https://unpkg.com/lit-element@2.5.1/lit-element.js?module";
class KGD_AldesCard extends HTMLElement {
//Selectionnable dans lovelace
static getConfigElement() {
return document.createElement("KGD-Aldes-Card-Editor");
};
static getStubConfig() {
return {
entity: "sensor.vmc_aldes",
timer: "timer.vmc_aldes_duree_timers"
};
};
set hass(hass) {
let _this = this;
const _config = this.config;
const _state = hass.states[_config.entity];
let _title = _config.title ? _config.title : "VMC Aldes";
const _timer = _config.timer;
const _serial = _state.attributes.serial ? _state.attributes.serial : "N/A";
let _vitesse_ventilation = _state.attributes.mode_de_fonctionnement ? _state.attributes.mode_de_fonctionnement.toString().split(",")[1] : "N/A";
let _mode_regulation = _state.attributes.mode_de_fonctionnement ? _state.attributes.mode_de_fonctionnement.toString().split(',')[0] : "N/A";
let _gestion_bypass = _state.attributes.mode_de_fonctionnement ? _state.attributes.mode_de_fonctionnement.toString().split(",")[3] : "N/A";
let _duree_vacances = _state.attributes.tempo_de_fonctionnement ? parseInt(_state.attributes.tempo_de_fonctionnement.toString().split(',')[0], 10) * 5 : "N/A";
let _duree_cuisine = _state.attributes.tempo_de_fonctionnement ? parseInt(_state.attributes.tempo_de_fonctionnement.toString().split(',')[1], 10) * 5 : "N/A";
let _duree_boost = _state.attributes.tempo_de_fonctionnement ? parseInt(_state.attributes.tempo_de_fonctionnement.toString().split(',')[2], 10) * 5 : "N/A";
let _duree_vie_filtre = _state.attributes.tempo_de_fonctionnement ? _state.attributes.tempo_de_fonctionnement.toString().split(',')[3] : "N/A";
let _pourcentage_filtre = _state.attributes.principales_entrees ? _state.attributes.principales_entrees.toString().split(',')[9] : "N/A";
if (!this.vitesseVentilation) {
this.innerHTML = `
<ha-card id="${_serial}">
<!--
CARTE LOVELACE
-->
<h1 id="KGD-CardHeader">
<div class="name"> ${_title} </div>
<div class="header-icon">
<!-- ha-icon name="info" icon="mdi:information-variant-circle-outline"></ha-icon -->
<ha-icon name="param" icon="mdi:cog"></ha-icon>
</div>
</h1>
<div id="KGD-CardvitesseVentilation">
<input id="vacances" type="radio" name="vitesseVentilation" value='0' />
<input id="normal" type="radio" name="vitesseVentilation" value='1' checked />
<input id="boost" type="radio" name="vitesseVentilation" value='2' />
<input id="invites" type="radio" name="vitesseVentilation" value='3' />
<ha-icon id="AlarmeFiltre" icon="mdi:air-filter"></ha-icon>
<div class="circle">
<div id="a" class="rotate">
<label for="vacances">
<ha-icon icon="mdi:beach"></ha-icon>
</label>
</div>
<div id="b" class="rotate">
<label for="normal">
<ha-icon icon="mdi:sofa-single"></ha-icon>
</label>
</div>
<div id="c" class="rotate">
<label for="program">
<ha-icon icon="mdi:clock-outline"></ha-icon>
</label>
</div>
<div id="d" class="rotate">
<label for="boost">
<ha-icon icon="mdi:chef-hat"></ha-icon>
</label>
</div>
<div id="e" class="rotate">
<label for="invites">
<ha-icon icon="mdi:account-group"></ha-icon>
</label>
</div>
<div class="mode-de-fonctionnement">
<h1>Mode</br>${_state.state}</h1>
<div role="spinner"></div>
<div class="timer">
<hui-timer-entity-row>
<hui-generic-entity-row>
<div class="text-content">
</div>
</hui-generic-entity-row>
</hui-timer-entity-row>
</div>
</div>
</div>
</div>
<!--
CARTE DIALOG PARAMETRES
-->
<ha-dialog id="KGD-DialogParametres" hideactions flexcontent>
<h1>
<span>${_title}</span>
<ha-icon name="fermer" icon="mdi:close"></ha-icon>
</h1>
<div class="content">
<div id="KGD-ModeDeFonctionnement" class="ModFonctionnement">
<div id="KGD-ModeRegulation" class='KGD-Border'>
<sablier><sable></sable></sablier>
<input id="MRAuto" type="radio" name="MR" value='0' />
<input id="MRHydro" type="radio" name="MR" value='1' checked />
<input id="MRVitesse" type="radio" name="MR" value='2' />
<div role="dropdown" class="dropdown">
<h2>MODE DE</br>REGULATION</h2>
<button><ha-icon></ha-icon><span class="arrow-down"></span></button>
<div role="dropdown-content" class="dropdown-content" tabindex="-1">
<label for="MRAuto"><ha-icon icon='mdi:fan-auto'></ha-icon>Auto</label>
<label for="MRHydro"><ha-icon icon='mdi:water-opacity'></ha-icon>Hydro</label>
<label for="MRVitesse"><ha-icon icon='mdi:speedometer'></ha-icon>Vitesse</label>
</div>
</div>
</div>
<div id="KGD-GestionBypass" class='KGD-Border'>
<sablier><sable></sable></sablier>
<input id="GBOff" type="radio" name="GB" value='0' />
<input id="GBAuto" type="radio" name="GB" value="1" checked />
<input id="GBHiver" type="radio" name="GB" value="2" />
<input id="GBEte" type="radio" name="GB" value="3" />
<input id="GBOuvert" type="radio" name="GB" value="4" />
<div role="dropdown" class="dropdown">
<h2>GESTION</br>BYPASS</h2>
<button><ha-icon></ha-icon><span class="arrow-down"></span></button>
<div role="dropdown-content" class="dropdown-content" tabindex="-1">
<label for="GBOff"><ha-icon icon='mdi:valve-closed'></ha-icon>Off</label>
<label for="GBAuto"><ha-icon icon='mdi:sun-snowflake-variant'></ha-icon>Auto</label>
<label for="GBHiver"><ha-icon icon='mdi:snowflake'></ha-icon>Hivers</label>
<label for="GBEte"><ha-icon icon='mdi:weather-sunny'></ha-icon>Eté</label>
<label for="GBOuvert"><ha-icon icon='mdi:valve-open'></ha-icon>Ouvert</label>
</div>
</div>
</div>
</div>
<div id="DureeVacances" class='KGD-Border KGD-DureeFonctionnement'>
<h2>DUREE DU MODE VACANCES</h2>
<sablier><sable></sable></sablier>
<div>
<div role="button" class="KGD-Hidden" action="restore">
<ha-icon icon="mdi:restore"></ha-icon>
</div>
<div class="KGD-Selecteur">
<span>J</span>
<button target="days" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="days" min=0 max=112 maxlength=3 size=3 step=1 value="000" onfocus="this.select()"/>
<button target="days" value='-'><span class="arrow-down"></span></button>
</div>
<div class="KGD-Selecteur">
<span>H</span>
<button target="hours" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="hours" min=0 max=23 maxlength=2 size=2 step=1 value="00" onfocus="this.select()"/>
<button target="hours" value='-'><span class="arrow-down"></span></button>
</div>
<div class="KGD-Selecteur">
<span>M</span>
<button target="minutes" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="minutes" min=0 max=55 maxlength=2 size="2" step=5 value="00" onfocus="this.select()"/>
<button target="minutes" value='-'><span class="arrow-down"></span></button>
</div>
<div role="button" class="KGD-Hidden" action="valide">
<ha-icon icon="mdi:check"></ha-icon>
</div>
</div>
</div>
<div id="DureeCuisine" class='KGD-Border KGD-DureeFonctionnement'>
<h2>DUREE DU MODE CUISINE</h2>
<sablier><sable></sable></sablier>
<div>
<div role="button" class="KGD-Hidden" action="restore">
<ha-icon icon="mdi:restore"></ha-icon>
</div>
<div class="KGD-Selecteur">
<span>J</span>
<button target="days" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="days" min=0 max=112 maxlength=3 size=3 step=1 value="000" onfocus="this.select()"/>
<button target="days" value='-'><span class="arrow-down"></span></button>
</div>
<div class="KGD-Selecteur">
<span>H</span>
<button target="hours" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="hours" min=0 max=23 maxlength=2 size=2 step=1 value="00" onfocus="this.select()"/>
<button target="hours" value='-'><span class="arrow-down"></span></button>
</div>
<div class="KGD-Selecteur">
<span>M</span>
<button target="minutes" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="minutes" min=0 max=55 maxlength=2 size="2" step=5 value="00" onfocus="this.select()"/>
<button target="minutes" value='-'><span class="arrow-down"></span></button>
</div>
<div role="button" class="KGD-Hidden" action="valide">
<ha-icon icon="mdi:check"></ha-icon>
</div>
</div>
</div>
<div id="DureeBoost" class='KGD-Border KGD-DureeFonctionnement'>
<h2>DUREE DU MODE BOOST</h2>
<sablier><sable></sable></sablier>
<div>
<div role="button" class="KGD-Hidden" action="restore">
<ha-icon icon="mdi:restore"></ha-icon>
</div>
<div class="KGD-Selecteur">
<span>J</span>
<button target="days" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="days" min=0 max=112 maxlength=3 size=3 step=1 value="000" onfocus="this.select()"/>
<button target="days" value='-'><span class="arrow-down"></span></button>
</div>
<div class="KGD-Selecteur">
<span>H</span>
<button target="hours" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="hours" min=0 max=23 maxlength=2 size=2 step=1 value="00" onfocus="this.select()"/>
<button target="hours" value='-'><span class="arrow-down"></span></button>
</div>
<div class="KGD-Selecteur">
<span>M</span>
<button target="minutes" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="minutes" min=0 max=55 maxlength=2 size="2" step=5 value="00" onfocus="this.select()"/>
<button target="minutes" value='-'><span class="arrow-down"></span></button>
</div>
<div role="button" class="KGD-Hidden" action="valide">
<ha-icon icon="mdi:check"></ha-icon>
</div>
</div>
</div>
<div id="DureeFiltre" class='KGD-Border KGD-DureeFonctionnement'>
<h2>DUREE DU FILTRE</h2>
<sablier><sable></sable></sablier>
<div>
<div role="button" class="KGD-Hidden" action="restore">
<ha-icon icon="mdi:restore"></ha-icon>
</div>
<div class="KGD-Selecteur">
<span>Mois</span>
<button target="months" value='+'><span class="arrow-up"></span></button>
<input disabled type="number" name="months" min=0 max=24 maxlength=2 size=2 step=1 value="00" onfocus="this.select()"/>
<button target="months" value='-'><span class="arrow-down"></span></button>
</div>
<div id="UtilisationFiltre" role="gauge">
<span>Utilisation</span>
<KGD-Gauge style=" --gauge-color: red;
--gauge-background: lightgray;
--value: 90deg;">
<svg viewBox="-50 -50 100 50" class="gauge">
<path class="dial" d="M -40 0 A 40 40 0 0 1 40 0"></path>
<path class="value" d="M -40 0 A 40 40 0 1 0 40 0" style="transform: rotate(var(--value));"></path>
</svg>
<span class="strtext">
<span class="text">3</span><span> %</span>
</span>
</KGD-Gauge>
</div>
<div role="button" class="KGD-Hidden" action="valide">
<ha-icon icon="mdi:check"></ha-icon>
</div>
</div>
</div>
</div>
</ha-dialog>
</ha-card>
`;
_this.header = this.querySelector('#KGD-CardHeader');
_this.vitesseVentilation = this.querySelector('#KGD-CardvitesseVentilation');
_this.vitesseVentilation.value = _this.vitesseVentilation.querySelector("input[name='vitesseVentilation']:checked").value;
_this.alarmeFiltre = _this.vitesseVentilation.querySelector('#AlarmeFiltre');
_this.spinner = _this.vitesseVentilation.querySelector('div[role="spinner"]');
_this.dialogParametres = this.querySelector('#KGD-DialogParametres');
_this.modeFonctionnement = this.querySelector("#KGD-ModeDeFonctionnement");
_this.modeRegulation = this.querySelector('#KGD-ModeRegulation');
_this.modeRegulation.registre = 256;
_this.modeRegulation.value = _this.modeRegulation.querySelector("input[name='MR']:checked").value;
_this.gestionByPass = this.querySelector('#KGD-GestionBypass');
_this.gestionByPass.registre = 259;
_this.gestionByPass.value = _this.gestionByPass.querySelector("input[name='GB']:checked").value;
_this.dureeVacances = this.querySelector('#DureeVacances');
_this.dureeVacances.registre = 264;
_this.dureeVacances.days = _this.dureeVacances.querySelector("input[name='days']");
_this.dureeVacances.hours = _this.dureeVacances.querySelector("input[name='hours']");
_this.dureeVacances.minutes = _this.dureeVacances.querySelector("input[name='minutes']");
_this.dureeCuisine = this.querySelector('#DureeCuisine');
_this.dureeCuisine.registre = 265;
_this.dureeCuisine.days = _this.dureeCuisine.querySelector("input[name='days']");
_this.dureeCuisine.hours = _this.dureeCuisine.querySelector("input[name='hours']");
_this.dureeCuisine.minutes = _this.dureeCuisine.querySelector("input[name='minutes']");
_this.dureeBoost = this.querySelector('#DureeBoost');
_this.dureeBoost.registre = 266;
_this.dureeBoost.days = _this.dureeBoost.querySelector("input[name='days']");
_this.dureeBoost.hours = _this.dureeBoost.querySelector("input[name='hours']");
_this.dureeBoost.minutes = _this.dureeBoost.querySelector("input[name='minutes']");
_this.dureeFiltre = this.querySelector('#DureeFiltre');
_this.dureeFiltre.registre = 267;
_this.dureeFiltre.months = _this.dureeFiltre.querySelector("input[name='months']");
_this.utilisationFiltre = this.querySelector("#UtilisationFiltre");
_this.utilisationFiltre.pourcent = _this.utilisationFiltre.querySelector(".text");
_this.utilisationFiltre.gauge = _this.utilisationFiltre.querySelector("KGD-Gauge").style;
const cssstyle = document.createElement('style');
cssstyle.setAttribute("type","text/css");
cssstyle.textContent = this.getStyles(_serial);
this.appendChild(cssstyle);
};
// BOUTON VITESSE VENTILATION
this.vitesseVentilation.querySelectorAll('input[name="vitesseVentilation"]').forEach( e => {
e.onclick = function () {
if (e.value !== 'P' && e.value !== _vitesse_ventilation) {
if (hass.states[_timer] && hass.states[_timer].state !== "idle") {
hass.callService('timer', 'cancel', { entity_id: _timer });
};
if (typeof _this.interval !== 'undefined' && _this.interval !== null) {
clearInterval(_this.interval);
_this.interval = null;
};
_this.vitesseVentilation.value = _this.vitesseVentilation.querySelector("input[name='vitesseVentilation']:checked").value;
_this.vitesseVentilation.changed = true;
hass.callService('modbus', 'write_register', { hub: 'vmc_modbus', slave: 2, address: 257, value: [e.value] });
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement h1').innerHTML = `Mode</br>${_state.state}`;
_this.spinner.classList.remove('KGD-Hidden');
//start timer
if (parseInt(_this.vitesseVentilation.value) !== 1) {
let _duree = _this.vitesseVentilation.value == 0 ? _duree_vacances * 60 :
_this.vitesseVentilation.value == 2 ? _duree_cuisine * 60:
_duree_boost * 60;
hass.callService('timer', 'start', { entity_id: _timer, duration: _duree });
};
};
};
});
// BOUTON PARAMETRE => Affiche DialogParametres
this.header.querySelectorAll('ha-icon[name="param"]').forEach( element => {
element.style.cursor = 'pointer';
element.onclick = function () {
_this.dialogParametres.setAttribute('open', '');
}
});
// BOUTON FERMER PARAMETRE
this.dialogParametres.querySelectorAll('ha-icon[name="fermer"]').forEach( element => {
element.style.cursor = 'pointer';
element.onclick = function () {
_this.dialogParametres.removeAttribute('open');
}
});
// BOUTON MODE REGULATION && BYPASS
this.modeFonctionnement.querySelectorAll('input').forEach( ipt => {
ipt.style.display = "none";
ipt.onclick = function() {
if (ipt.name == 'MR') {
if (ipt.value !== _mode_regulation) {
if (_this.modeRegulation.querySelector("sablier").style.display == "none") {
_this.modeRegulation.changed = true;
_this.modeRegulation.value = _this.modeRegulation.querySelector("input:checked").value;
hass.callService('modbus', 'write_register', { hub: 'vmc_modbus', slave: 2, address: _this.modeRegulation.registre, value: [ipt.value] });
_this.modeRegulation.querySelector('sablier').style.display = "block";
let _val = ['Auto','Hydro','Vitesse'];
let _ico = ['mdi:fan-auto','mdi:water-opacity','mdi:speedometer'];
_this.modeRegulation.querySelector('button').innerHTML = `<ha-icon icon='${_ico[ipt.value]}'></ha-icon>${_val[ipt.value]}<span class="arrow-down"></span>`;
};
};
};
if (ipt.name == 'GB') {
if (ipt.value !== _gestion_bypass) {
if (_this.gestionByPass.querySelector("sablier").style.display == "none") {
_this.gestionByPass.changed = true;
_this.gestionByPass.value = _this.gestionByPass.querySelector("input:checked").value;
hass.callService('modbus', 'write_register', { hub: 'vmc_modbus', slave: 2, address: _this.gestionByPass.registre, value: [ipt.value] });
_this.gestionByPass.querySelector('sablier').style.display = "block";
let _val = ['Off','Auto','Hivers','Eté','Ouvert'];
let _ico = ['mdi:valve-closed','mdi:sun-snowflake-variant','mdi:snowflake','mdi:weather-sunny','mdi:valve-open'];
_this.gestionByPass.querySelector('button').innerHTML = `<ha-icon icon='${_ico[ipt.value]}'></ha-icon>${_val[ipt.value]}<span class="arrow-down"></span>`;
};
};
};
};
});
this.modeFonctionnement.querySelectorAll('div[role="dropdown"]').forEach( mF => {
mF.addEventListener('focusin', ()=>{
mF.querySelector('div[role="dropdown-content"]').style.display = 'block';
mF.querySelector('div[role="dropdown-content"]').focus();
mF.querySelectorAll('div[role="dropdown-content"]').forEach( dropdown => {
dropdown.addEventListener('focusout', function(){
dropdown.style.display = 'none';
});
dropdown.querySelectorAll('label').forEach( label =>{
label.onclick = function(){
dropdown.style.display = "none";
};
});
});
});
});
// DUREE DE FONCTIONNEMENT
this.dialogParametres.querySelectorAll('.KGD-DureeFonctionnement').forEach(div => {
div.querySelectorAll('button').forEach(e => {
e.onclick = function() {
let _t = div.getAttribute('id') == 'DureeVacances' ?
[_this.dureeVacances, _duree_vacances] :
div.getAttribute('id') == 'DureeCuisine' ?
[_this.dureeCuisine, _duree_cuisine] :
div.getAttribute('id') == 'DureeBoost' ?
[_this.dureeBoost, _duree_boost] :
[_this.dureeFiltre, _duree_vie_filtre];
if (_t[0].querySelector("sablier").style.display == "none") {
_t[0].changed = true;
_t[0].querySelectorAll('div[role="button"]').forEach(bt => {
bt.style.cursor = 'pointer';
bt.classList.remove("KGD-Hidden");
bt.onclick = function() {
if(bt.getAttribute("action") == "restore") {
try {_t[0].days.value = Math.floor(_t[1] * 60 / 86400);} catch {};
try {_t[0].hours.value = String(Math.floor((_t[1] * 60 % 86400) / 3600)).padStart( 2, '0')} catch {};
try {_t[0].minutes.value = String(Math.floor((_t[1] * 60 % 3600) / 60)).padStart( 2, '0')} catch {};
try {_t[0].months.value = parseInt(_t[1])} catch {};
_t[0].querySelectorAll('div[role="button"]').forEach(d => {d.classList.add("KGD-Hidden");});
_t[0].changed = false;
};
if(bt.getAttribute("action") == "valide") {
_t[0].querySelectorAll('div[role="button"]').forEach(d => {d.classList.add("KGD-Hidden");});
_t[0].querySelector("sablier").style.display = 'block';
hass.callService('modbus', 'write_register', { hub: 'vmc_modbus', slave: 2, address: _t[0].registre, value: [_this.getDuree(_t[0])] });
};
};
});
switch (e.getAttribute('target')) {
case "days":
_t[0].days.value = e.value == '+' ?
Math.min(Math.max(_t[0].days.min, Math.round((parseInt(_t[0].days.value) + parseInt(_t[0].days.step)) / _t[0].days.step) * _t[0].days.step), _t[0].days.max):
Math.min(Math.max(_t[0].days.min, Math.round((parseInt(_t[0].days.value) - parseInt(_t[0].days.step)) / _t[0].days.step) * _t[0].days.step), _t[0].days.max);
break;
case "hours":
_t[0].hours.value = e.value == '+' ?
String(Math.min(Math.max(_t[0].hours.min, Math.round((parseInt(_t[0].hours.value) + parseInt(_t[0].hours.step)) / _t[0].hours.step) * _t[0].hours.step), _t[0].hours.max)).padStart( 2, '0'):
String(Math.min(Math.max(_t[0].hours.min, Math.round((parseInt(_t[0].hours.value) - parseInt(_t[0].hours.step)) / _t[0].hours.step) * _t[0].hours.step), _t[0].hours.max)).padStart( 2, '0');
break;
case "minutes":
_t[0].minutes.value = e.value == '+' ?
String(Math.min(Math.max(_t[0].minutes.min, Math.round((parseInt(_t[0].minutes.value) + parseInt(_t[0].minutes.step)) / _t[0].minutes.step) * _t[0].minutes.step), _t[0].minutes.max)).padStart( 2, '0'):
String(Math.min(Math.max(_t[0].minutes.min, Math.round((parseInt(_t[0].minutes.value) - parseInt(_t[0].minutes.step)) / _t[0].minutes.step) * _t[0].minutes.step), _t[0].minutes.max)).padStart( 2, '0');
break;
case "months":
_t[0].months.value = e.value == '+' ?
Math.min(Math.max(_t[0].months.min, Math.round((parseInt(_t[0].months.value) + parseInt(_t[0].months.step)) / _t[0].months.step) * _t[0].months.step), _t[0].months.max):
Math.min(Math.max(_t[0].months.min, Math.round((parseInt(_t[0].months.value) - parseInt(_t[0].months.step)) / _t[0].months.step) * _t[0].months.step), _t[0].months.max);
break;
default:
break;
};
};
};
});
});
// MAJ
///////
if(!this.isUpdating) {
try {
// MODE REGULATION
let _val, _ico;
_val = ['Auto','Hydro','Vitesse'];
_ico = ['mdi:fan-auto','mdi:water-opacity','mdi:speedometer'];
if (_this.modeRegulation.changed === true) {
if (_this.modeRegulation.value == _mode_regulation) {
_this.modeRegulation.changed = false;
_this.modeRegulation.querySelector("sablier").style.display = "none";
_this.modeRegulation.querySelector('button').innerHTML = `<ha-icon icon='${_ico[_mode_regulation]}'></ha-icon>${_val[_mode_regulation]}<span class="arrow-down"></span>`;
}
} else {
_this.modeRegulation.value = _mode_regulation;
_this.modeRegulation.querySelector("sablier").style.display = "none";
_this.modeRegulation.querySelector('button').innerHTML = `<ha-icon icon='${_ico[_mode_regulation]}'></ha-icon>${_val[_mode_regulation]}<span class="arrow-down"></span>`;
};
// GESTION BYPASS
_val = ['Off','Auto','Hivers','Eté','Ouvert'];
_ico = ['mdi:valve-closed','mdi:sun-snowflake-variant','mdi:snowflake','mdi:weather-sunny','mdi:valve-open'];
if (_this.gestionByPass.changed === true) {
if (_this.gestionByPass.value == _gestion_bypass) {
_this.gestionByPass.changed = false;
_this.gestionByPass.querySelector("sablier").style.display = "none";
_this.gestionByPass.querySelector('button').innerHTML = `<ha-icon icon='${_ico[_gestion_bypass]}'></ha-icon>${_val[_gestion_bypass]}<span class="arrow-down"></span>`;
}
} else {
_this.gestionByPass.value = _gestion_bypass;
_this.gestionByPass.querySelector("sablier").style.display = "none";
_this.gestionByPass.querySelector('button').innerHTML = `<ha-icon icon='${_ico[_gestion_bypass]}'></ha-icon>${_val[_gestion_bypass]}<span class="arrow-down"></span>`;
};
// DUREE VACANCES
if (_this.dureeVacances.changed === true) {
if (_this.dureeVacances.days.value == Math.floor(_duree_vacances * 60 / 86400) &&
_this.dureeVacances.hours.value == String(Math.floor((_duree_vacances * 60 % 86400) / 3600)).padStart( 2, '0') &&
_this.dureeVacances.minutes.value == String(Math.floor((_duree_vacances * 60 % 3600) / 60)).padStart( 2, '0'))
{
_this.dureeVacances.changed = false;
_this.dureeVacances.querySelectorAll('div[role="button"]').forEach(d => {d.classList.add("KGD-Hidden");});
_this.dureeVacances.querySelector("sablier").style.display = "none";
}
} else {
_this.dureeVacances.days.value = Math.floor(_duree_vacances * 60 / 86400);
_this.dureeVacances.hours.value = String(Math.floor((_duree_vacances * 60 % 86400) / 3600)).padStart( 2, '0');
_this.dureeVacances.minutes.value = String(Math.floor((_duree_vacances * 60 % 3600) / 60)).padStart( 2, '0');
_this.dureeVacances.querySelector("sablier").style.display = "none";
};
// DUREE CUISINE
if (_this.dureeCuisine.changed === true) {
if (_this.dureeCuisine.days.value == Math.floor(_duree_cuisine * 60 / 86400) &&
_this.dureeCuisine.hours.value == String(Math.floor((_duree_cuisine * 60 % 86400) / 3600)).padStart( 2, '0') &&
_this.dureeCuisine.minutes.value == String(Math.floor((_duree_cuisine * 60 % 3600) / 60)).padStart( 2, '0'))
{
_this.dureeCuisine.changed = false;
_this.dureeCuisine.querySelectorAll('div[role="button"]').forEach(d => {d.classList.add("KGD-Hidden");});
_this.dureeCuisine.querySelector("sablier").style.display = "none";
}
} else {
_this.dureeCuisine.days.value = Math.floor(_duree_cuisine * 60 / 86400);
_this.dureeCuisine.hours.value = String(Math.floor((_duree_cuisine * 60 % 86400) / 3600)).padStart( 2, '0');
_this.dureeCuisine.minutes.value = String(Math.floor((_duree_cuisine * 60 % 3600) / 60)).padStart( 2, '0');
_this.dureeCuisine.querySelector("sablier").style.display = "none";
};
// DUREE BOOST
if (_this.dureeBoost.changed === true) {
if (_this.dureeBoost.days.value == Math.floor(_duree_boost * 60 / 86400) &&
_this.dureeBoost.hours.value == String(Math.floor((_duree_boost * 60 % 86400) / 3600)).padStart( 2, '0') &&
_this.dureeBoost.minutes.value == String(Math.floor((_duree_boost * 60 % 3600) / 60)).padStart( 2, '0'))
{
_this.dureeBoost.changed = false;
_this.dureeBoost.querySelectorAll('div[role="button"]').forEach(d => {d.classList.add("KGD-Hidden");});
_this.dureeBoost.querySelector("sablier").style.display = "none";
}
} else {
_this.dureeBoost.days.value = Math.floor(_duree_boost * 60 / 86400);
_this.dureeBoost.hours.value = String(Math.floor((_duree_boost * 60 % 86400) / 3600)).padStart( 2, '0');
_this.dureeBoost.minutes.value = String(Math.floor((_duree_boost * 60 % 3600) / 60)).padStart( 2, '0');
_this.dureeBoost.querySelector("sablier").style.display = "none";
};
// DUREE FILTRE
if (_this.dureeFiltre.changed === true) {
if (parseInt(_this.dureeFiltre.months.value) == parseInt(_duree_vie_filtre)) {
_this.dureeFiltre.changed = false;
_this.dureeFiltre.querySelectorAll('div[role="button"]').forEach(d => {d.classList.add("KGD-Hidden");});
_this.dureeFiltre.querySelector("sablier").style.display = "none";
}
} else {
_this.dureeFiltre.months.value = _duree_vie_filtre;
_this.dureeFiltre.querySelector("sablier").style.display = "none";
};
// GAUGE FILTRE
_this.utilisationFiltre.pourcent.innerHTML = parseInt(_pourcentage_filtre);
let _deg = parseInt(_pourcentage_filtre)*1.8 + 'deg';
_this.utilisationFiltre.gauge.setProperty('--value', _deg);
let _color = parseInt(_pourcentage_filtre) > 90 ? 'red' : parseInt(_pourcentage_filtre) > 75 ? 'orange' : parseInt(_pourcentage_filtre) > 50 ? 'yellow' : 'green';
_this.utilisationFiltre.gauge.setProperty('--gauge-color', _color);
_this.alarmeFiltre.style.display = parseInt(_pourcentage_filtre) >= 90 ? 'block' : 'none';
// VITESSE VENTILATION
if (_this.vitesseVentilation.changed === true) {
if (_this.vitesseVentilation.value == _vitesse_ventilation) {
_this.vitesseVentilation.changed = false;
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement h1').innerHTML = `Mode</br>${_state.state}`;
_this.spinner.classList.add('KGD-Hidden');
//creation affichage timer
if (parseInt(_this.vitesseVentilation.value) == 1) {
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement .timer').innerHTML = null;
if (typeof _this.interval !== 'undefined' && _this.interval !== null) {
clearInterval(_this.interval);
_this.interval = null;
}
} else {
if (typeof _this.interval == 'undefined' || _this.interval == null) {
_this.interval = setInterval( function() {
let _millis = Date.parse(hass.states[_timer].attributes.finishes_at) - Date.now();
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement .timer').innerHTML = _this.convertDHMS(_millis);
}, 500);
};
};
};
} else {
if (_this.vitesseVentilation.querySelector(`input[name="vitesseVentilation"]:checked`).value !== _vitesse_ventilation) {
if (typeof _this.interval !== 'undefined' && _this.interval !== null) {
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement .timer').innerHTML = null;
clearInterval(_this.interval);
_this.interval = null;
};
};
_this.vitesseVentilation.querySelectorAll(`input[name="vitesseVentilation"]`)[_vitesse_ventilation].checked = true;
_this.vitesseVentilation.value = _this.vitesseVentilation.querySelector(`input[name="vitesseVentilation"]:checked`).value;
_this.spinner.classList.add('KGD-Hidden');
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement h1').innerHTML = `Mode</br>${_state.state}`;
//creation affichage timer
if (parseInt(_this.vitesseVentilation.value) == 1) {
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement .timer').innerHTML = null;
if (typeof _this.interval !== 'undefined' && _this.interval !== null) {
clearInterval(_this.interval);
_this.interval = null;
}
} else {
if (typeof _this.interval == 'undefined' || _this.interval == null) {
_this.interval = setInterval( function() {
let _millis = Date.parse(hass.states[_timer].attributes.finishes_at) - Date.now();
_this.vitesseVentilation.querySelector('.mode-de-fonctionnement .timer').innerHTML = _this.convertDHMS(_millis);
}, 500);
};
};
};
} catch (err) {};
};
};
setConfig(config) {
this.config = config;
this.isUpdating = false;
};
getCardSize() {
return 2;
};
getDuree(target) {
let D, H, M, V;
//Add = target == _this.dureeVacances ? 264 : target == _this.dureeCuisine ? 265 : target == _this.dureeBoost ? 266 : 267;
if (target.registre === 264 || target.registre === 265 || target.registre === 266) {
D = target.days.value * 24 * 60;
H = target.hours.value * 60;
M = target.minutes.value;
V = (parseInt(D) + parseInt(H) + parseInt(M)) / 5;
}
if (target.registre === 267) {
V = parseInt(target.months.value);
}
return V;
};
convertDHMS(milliseconds, style) {
const totalSeconds = Math.floor(milliseconds / 1000);
let days = Math.floor(totalSeconds / 86400);
const hours = Math.floor((totalSeconds % 86400) / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
if (style == 'number') {
days = `${String(days).padStart(3, '0')}:`;
}else{
if (days == 0) { days = ''; }
if (days == 1) { days = `${days} jour - ` }
if (days > 1) { days = `${days} jours - ` }
}
return `${days}${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};
getStyles(_serial) {
const _background_color = '#80B4DE88';
const ha = `ha-card[id='${_serial}']`;
let _style = `
${ha} button {
cursor: pointer;
}
${ha} #KGD-ModeDeFonctionnement {
display: flex;
min-width: 325px;
}
${ha} div[role="dropdown"] button {
--mdc-icon-size 32px;
width: -webkit-fill-available;
height: auto;
border-radius: 8px;
padding: 4px;
padding-right: 8px;
margin: 12px 8px;
cursor: pointer;
display: flex;
align-items: center;
font-size: 14px;
font-weight: bold;
justify-content: space-between;
background-color: ${_background_color};
border: 2px outset ${_background_color};
}
${ha} div[role="dropdown-content"] {
display: none;
position: absolute;
margin: 0;
padding: 0;
background-color: var(--secondary-background-color);
width: 38%;
max-height: 248px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
border-radius: 5px;
border-color: var(--primary-text-color)
}
${ha} div[role="dropdown-content"] label {
padding: 10px 20px;
cursor: pointer;
display: flex;
align-items: center;
font-size: 14px;
font-weight: bold;
justify-content: space-between;
}
${ha} div[role="gauge"] {
display: flex;
flex-direction: column;
align-items: stretch;
margin: 2px 8px;
}
${ha} div[role="gauge"] KGD-Gauge {
width: 100%;
max-width: 250px;
display: block;
height: -webkit-fill-available;
padding: 8px 0 0 0;
}
${ha} div[role="gauge"] .value {
fill: none;
stroke-width: 15;
stroke: var(--gauge-color);
transition: all 1s ease 0s;
}
${ha} div[role="gauge"] .dial {
fill: none;
stroke: var(--gauge-background);
stroke-width: 15;
}
${ha} div[role="gauge"] .strtext {
top: -10px;
position: relative;
}
${ha} .KGD-Hidden {
display: none;
}
${ha} sablier {
z-index: 1;
position: relative;
top: 65px;
margin: -20px;
width: fit-content;
box-sizing: border-box;
border-top: 7px solid;
border-bottom: 7px solid;
border-left: 0;
border-right: 0;
border-color: var(--accent-color) transparent var(--accent-color) transparent;
animation: sablier-anim 2.5s linear infinite;
}
${ha} sablier sable {
display: block;
height: 0;
width: 0;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
border: 14px solid;
border-color: var(--accent-color) transparent var(--accent-color) transparent;
}
${ha} div[role="spinner"] {
width: 24px;
height: 24px;
border: 4px solid;
border-color: #3d5af1 transparent #3d5af1 transparent;
border-radius: 50%;
animation: spin-anim 1.2s linear infinite;
}
@keyframes spin-anim {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes sablier-anim {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(360deg);
}
100% {
transform: rotate(360deg);
}
}
${ha} #KGD-CardHeader {
background-color: ${_background_color};
margin: 0;
padding: 16px 12px 12px 12px;
border-radius: 8px 8px 0 0;
display: flex;
justify-content: space-between;
}
${ha} input[name="vitesseVentilation"] {
display: none;
}
${ha} .circle {
height: 250px;
width: 250px;
display: flex;
justify-content: center;
align-items: center;
margin: 36px auto;
position: relative;
}
${ha} .mode-de-fonctionnement{
text-align: center;
line-height: 2em;
margin-top: -16px;
display: flex;
flex-direction: column;
align-items: center;
}
${ha} #AlarmeFiltre {
right: 24px;
float: right;
color: red;
position: absolute;
-webkit-animation: fadeinout 3s infinite forwards;
animation: fadeinout 3s infinite forwards;
opacity: 0;
}
@-webkit-keyframes fadeinout {
75% { opacity: 1; }
}
@keyframes fadeinout {
75% { opacity: 1; }
}
${ha} .rotate {
height: 149px;
position: absolute;
top: 125px;
left: 125px;
width: 56px;
margin-left: -28px;
display: flex;
align-items: flex-end;
}
${ha} .rotate ha-icon {
border-radius: 50%;
border: solid 1px ${_background_color};
height: 56px;
width: 56px;
display: flex;
align-items: center;
justify-content: center;
background: ${_background_color};
}
${ha} #a, ${ha} #a ha-icon ,
${ha} #b , ${ha} #b ha-icon ,
${ha} #c, ${ha} #c ha-icon,
${ha} #d, ${ha} #d ha-icon,
${ha} #e, ${ha} #e ha-icon {
transition:1s;
}
${ha} #a,
${ha} #b,
${ha} #c,
${ha} #d,
${ha} #e {
transform-origin: 28px 0;
}
${ha} #a{
z-index:1;
}
${ha} label{
cursor:pointer
}
/* vacances */
${ha} #vacances:checked ~ .circle #a {transform: rotate(+180deg);}
${ha} #vacances:checked ~ .circle #a ha-icon {transform: rotate(-180deg);}
${ha} #vacances:checked ~ .circle #b {transform: rotate(-45deg);}
${ha} #vacances:checked ~ .circle #b ha-icon {transform: rotate(+45deg);}
${ha} #vacances:checked ~ .circle #c {transform: rotate(-15deg);}
${ha} #vacances:checked ~ .circle #c ha-icon {transform: rotate(+15deg);}
${ha} #vacances:checked ~ .circle #d {transform: rotate(+15deg);}
${ha} #vacances:checked ~ .circle #d ha-icon {transform: rotate(-15deg);}
${ha} #vacances:checked ~ .circle #e {transform: rotate(+45deg);}
${ha} #vacances:checked ~ .circle #e ha-icon {transform: rotate(-45deg);}
/* normal */
${ha} #normal:checked ~ .circle #b {transform: rotate(-180deg);}
${ha} #normal:checked ~ .circle #b ha-icon {transform: rotate(+180deg);}
${ha} #normal:checked ~ .circle #c {transform: rotate(-45deg);}
${ha} #normal:checked ~ .circle #c ha-icon {transform: rotate(+45deg);}
${ha} #normal:checked ~ .circle #d {transform: rotate(-15deg);}
${ha} #normal:checked ~ .circle #d ha-icon {transform: rotate(+15deg);}
${ha} #normal:checked ~ .circle #e {transform: rotate(+15deg);}
${ha} #normal:checked ~ .circle #e ha-icon {transform: rotate(-15deg);}
${ha} #normal:checked ~ .circle #a {transform: rotate(+45deg);}
${ha} #normal:checked ~ .circle #a ha-icon {transform: rotate(-45deg);}
/* program */
${ha} #program:checked ~ .circle #c {transform: rotate(-180deg);}
${ha} #program:checked ~ .circle #c ha-icon {transform: rotate(+180deg);}
${ha} #program:checked ~ .circle #d {transform: rotate(-45deg);}
${ha} #program:checked ~ .circle #d ha-icon {transform: rotate(+45deg);}
${ha} #program:checked ~ .circle #e {transform: rotate(-15deg);}
${ha} #program:checked ~ .circle #e ha-icon {transform: rotate(+15deg);}
${ha} #program:checked ~ .circle #a {transform: rotate(+15deg);}
${ha} #program:checked ~ .circle #a ha-icon {transform: rotate(-15deg);}
${ha} #program:checked ~ .circle #b {transform: rotate(-315deg);}
${ha} #program:checked ~ .circle #b ha-icon {transform: rotate(+315deg);}
/* boost */
${ha} #boost:checked ~ .circle #d {transform: rotate(-180deg);}
${ha} #boost:checked ~ .circle #d ha-icon {transform: rotate(+180deg);}
${ha} #boost:checked ~ .circle #e {transform: rotate(-45deg);}
${ha} #boost:checked ~ .circle #e ha-icon {transform: rotate(+45deg);}
${ha} #boost:checked ~ .circle #a {transform: rotate(-15deg);}
${ha} #boost:checked ~ .circle #a ha-icon {transform: rotate(+15deg);}
${ha} #boost:checked ~ .circle #b {transform: rotate(-345deg);}
${ha} #boost:checked ~ .circle #b ha-icon {transform: rotate(+345deg);}
${ha} #boost:checked ~ .circle #c {transform: rotate(-315deg);}
${ha} #boost:checked ~ .circle #c ha-icon {transform: rotate(+315deg);}
/* invites */
${ha} #invites:checked ~ .circle #e {transform: rotate(-180deg);}
${ha} #invites:checked ~ .circle #e ha-icon {transform: rotate(+180deg);}
${ha} #invites:checked ~ .circle #a {transform: rotate(-45deg);}
${ha} #invites:checked ~ .circle #a ha-icon {transform: rotate(+45deg);}
${ha} #invites:checked ~ .circle #b {transform: rotate(-375deg);}
${ha} #invites:checked ~ .circle #b ha-icon {transform: rotate(+375deg);}
${ha} #invites:checked ~ .circle #c {transform: rotate(-345deg);}
${ha} #invites:checked ~ .circle #c ha-icon {transform: rotate(+345deg);}
${ha} #invites:checked ~ .circle #d {transform: rotate(-315deg);}
${ha} #invites:checked ~ .circle #d ha-icon {transform: rotate(+315deg);}
${ha} ha-dialog h1 {
background-color: ${_background_color};
margin: -24px -24px 0 -24px;
padding: 16px 12px 12px 12px;
border-radius: 8px 8px 0 0;
display: flex;
justify-content: space-between;
}
${ha} #KGD-DialogParametres {
overflow: hidden;
}
${ha} #KGD-DialogParametres .content {
overflow-y: auto;
overflow-x: hidden;
margin-top: 12px;
}
${ha} .KGD-Border {
border-radius: 16px;
border: 2px inset ${_background_color};
padding: 0;
text-align: -webkit-center;
width: -webkit-fill-available;
margin: 0 4px;
}
${ha} h2 {
background-color: ${_background_color};
padding : 4px;
margin: 0px;
border-radius: 14px 14px 0 0;
width: -webkit-fill-available;
font-size: 14px;
}
${ha} .KGD-DureeFonctionnement {
margin: 4px;
}
${ha} .KGD-DureeFonctionnement>div{
display: flex;
justify-content: center;
padding: 8px;
}
${ha} .KGD-DureeFonctionnement>div div[role="button"][action="restore"],
${ha} .KGD-DureeFonctionnement>div div[role="button"][action="valide"] {
margin: auto;
background-color: #F00A;
cursor: pointer;
--mdc-icon-size: 28px;
padding: 8px;
border-radius: 40%;
}
${ha} .KGD-DureeFonctionnement>div div[role="button"][action="valide"] {
background-color: #0F0A;
}
${ha} .KGD-Selecteur {
display: flex;
flex-direction: column;
align-items: stretch;
margin: 2px;
}
${ha} button {
background-color: ${_background_color};
border: 2px outset ${_background_color};
}
${ha} .arrow-down {
width: 0;
height: 0;
display: inline-block;
vertical-align: middle;
border-style: solid;
border-width: 8px 8px 0 8px;
border-color: var(--primary-text-color) transparent transparent transparent;
}
${ha} .arrow-up {
width: 0;
height: 0;
display: inline-block;
vertical-align: middle;
border-style: solid;
border-width: 0px 8px 8px 8px;
border-color: transparent transparent var(--primary-text-color) transparent;
}
${ha} .KGD-Selecteur input {
user-select: none;
font-size: large;
text-align: center;
-moz-appearance: textfield;
appearance: textfield;
width: 38px;
padding: 2px 0 0 0;
}
${ha} .KGD-Selecteur input::-webkit-inner-spin-button,
${ha} .KGD-Selecteur input::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
`;
return css`${unsafeCSS(_style)}`;
};
};
customElements.define('KGD-Aldes-Card', KGD_AldesCard);
////////////////////////////////////////////////////
class KGD_AldesCardEditor extends LitElement {
};
customElements.define("KGD-Aldes-Card-Editor", KGD_AldesCardEditor);
window.customCards = window.customCards || [];
window.customCards.push({
type: "kgd-aldes-card",
name: "KGD Aldes Card",
preview: true, // Optional - defaults to false
description: "Carte Aldes VMC", // Optional
configurable: true, // Optional - defaults to false
});
Gros travaille toujours en cours.
Je dois encore faire la consigne de température été/hivers,…
Toutes vos remarques sont les bienvenu.
Je n’ai pas réussi à trouver comment réinitialiser le filtre, du coup je le fais sur la VMC (comme j’y suis pour le changement…)
Si ce contenu peu aider ![]()
