Aller au contenu principal

Exemple 1 - Calcul de puissance, compteur d'énergie, valeurs journalières

Exemple 1a - Calcul de puissance​

Tâche :​

La puissance électrique d'un consommateur doit être calculée à partir des signaux de tension (LINEVOLT_1, LINEVOLT_2 en volts) et de courant (LINECURRENT en ampères) mesurés. La tension est mesurée de manière redondante, un point de mesure pouvant être désactivé. La sortie doit s'effectuer dans l'unité « kW ». Détermination de l'énergie absorbée et restituée en « kWh ».

Solution :​

// Konstanten zur Einheitenumrechnung
uConv_Ws2kWh = 1e-3 / 3600; // Ws -> kWh

LINEVOLT = max(LINEVOLT_1, LINEVOLT_2); // V
POWER = LINEVOLT * LINECURRENT; // W
POWER_KW = POWER / 1000.0; // kW
WAUF_KWH = integrate(max(POWER, 0.0), {storage: 'sto_WAUF'}) * uConv_Ws2kWh; // kWh
WABG_KWH = -integrate(min(POWER, 0.0), {storage: 'sto_WABG'}) * uConv_Ws2kWh; // kWh

Fonctions utilisées​

Explication :​

  • uConv_Ws2kWh : un facteur de conversion d'unités de Ws en kWh est d'abord défini. Cela améliore la lisibilité du code qui suit. Il est avantageux de placer de telles définitions de manière centralisée au début du jeu de formules.

  • LINEVOLT : le maximum des deux tensions réseau mesurées est retenu. Si l'une d'elles tombe en panne et passe à 0.0, l'autre fournit toujours une valeur plausible.

  • POWER et POWER_KW : la puissance électrique est d'abord calculée en W (watts), puis séparément en kW (kilowatts). Cette séparation est nécessaire, car la fonction d'intégration qui suit doit toujours être alimentée avec les unités de base SI du système « MKS », donc ici avec la puissance en W.

  • WAUF_KWH, WABG_KWH : la puissance calculée est répartie, selon son signe et donc selon le sens du flux de puissance, vers les deux intégrateurs integrate() au moyen des fonctions min() et max(). Les deux intégrateurs conservent leur état de compteur courant (en unités de base SI !) dans les emplacements de stockage indiqués. Par l'intégration, la dimension temps en s (seconde) s'ajoute à l'intégrande. La valeur intégrée a donc l'unité d'énergie « Ws » (wattseconde). Elle est convertie en kWh (kilowattheure) avec le facteur d'échelle calculé ci-dessus.

  • Si, par la suite, les unités des signaux de mesure à intégrer (kV, kA, mA) ou de la valeur intégrée (kJ, MWh, etc.) changent, la valeur stockée dans l'intégrateur peut facilement continuer à être utilisée, à condition qu'elle soit exprimée en unités de base SI. Seule une mise à l'échelle simple et compréhensible de la grandeur d'entrée ou de sortie est alors nécessaire, mais ni remise à l'échelle permanente de la valeur stockée dans l'intégrateur, ni redémarrage forcé qui en résulterait.

Exemple 1b - Valeurs intermédiaires du jour​

Tâche :​

Le calcul doit maintenant être étendu de sorte que les index de compteur journaliers à l'heure de fin d'exploitation, la consommation des 7 derniers jours et la consommation en cours du jour actuel soient fournis.

Solution :​

En complément de la formule de l'exemple 1a) :

#timezone Europe/Berlin
newDay = timer({ minute: 15, hour: 3, useTZ: true }); // Referenz-Zeit, Schichtwechsel

_hist_WAUF_KWH = buffer(WAUF_KWH, newDay, {size:8, storage:'sto_h_WAUF'});
WEEK_WAUF_KWH = _hist_WAUF_KWH[0] - _hist_WAUF_KWH[7];
YDAY_WAUF_KWH = _hist_WAUF_KWH[0] - _hist_WAUF_KWH[1];
TDAY_WAUF_KWH = WAUF_KWH - _hist_WAUF_KWH[0];

_hist_WABG_KWH = buffer(WABG_KWH, newDay, {size:8, storage:'sto_h_WABG'});
WEEK_WABG_KWH = _hist_WABG_KWH[0] - _hist_WABG_KWH[7];
YDAY_WABG_KWH = _hist_WABG_KWH[0] - _hist_WABG_KWH[1];
TDAY_WABG_KWH = WABG_KWH - _hist_WABG_KWH[0];

Fonctions utilisées​

Explication :​

  • Les variables à usage interne sont repérées par un _ comme premier caractère. Cela améliore la lisibilité.

  • newDay : la fonction timer() génère un signal impulsionnel qui, avec la configuration donnée, produit chaque matin à 3h15, heure locale de « Berlin », une brève impulsion. Cette impulsion sert ensuite à mémoriser les index de compteur.

  • _hist_WAUF_KWH, _hist_WABG_KWH : à l'aide de la fonction buffer(), les valeurs des compteurs d'énergie sont reprises dans un tampon circulaire de longueur 8. Chaque fois qu'un front montant est présent sur le signal newDay, les valeurs du tampon circulaire sont décalées d'une position vers l'arrière et la valeur actuelle WAUF_KWH ou WABG_KWH est placée à l'emplacement [0]. Ces tampons sauvegardent eux aussi leur contenu dans un emplacement persistant, afin de poursuivre le calcul avec les index de compteur déterminés jusque-là après un redémarrage.

  • WEEK_* : la consommation d'énergie des 7 derniers jours résulte de la différence entre la valeur relevée la nuit dernière et celle relevée 8 nuits auparavant [7].

  • YDAY_* : la consommation d'énergie du dernier jour (yesterday) résulte de la différence entre les valeurs relevées la dernière nuit [0] et l'avant-dernière nuit [1].

  • TDAY_* : la consommation d'énergie du jour en cours (today) est la différence entre la valeur absolue et la valeur mémorisée la nuit dernière.

Comme les valeurs historiques mémorisées ne changent qu'une fois par jour, la transmission des données vers le cloud ou vers des fichiers OSF est très efficace.

Exemple 1c - Valeurs de consommation par jour de la semaine ou par mois​

Tâche :​

L'exemple 1b) exige que le smartCORE soit en permanence en ligne et puisse générer les impulsions de déclenchement. À partir de la version de catalogue 13, la fonction memory() peut être utilisée pour contourner ce problème.

Solution :​

En complément de la formule de l'exemple 1a) :

_now = time();
_dateVec = decodeTime(_now);
_weekDay = int(_dateVec[7]);     // 0..6, starting on sunday
_yesterday = (_weekDay + 6) % 7;

_memECLatch = memory( false, _weekDay, WAUF_KWH
, {mode: latch, size:7
, storage: memECLatch_kWh});
_memStart = memory( false, _weekDay, _memECLatch[_yesterday]
, {mode: latch, size:7
, storage: memStart_kWh});
Consumption = _memECLatch - _memStart;

Consume_Sun = Consumption[0];
Consume_Mon = Consumption[1];
...
Consume_Sat = Consumption[6];

Fonctions utilisées :​

Explication :​

  • Le jour de la semaine _weekDay pour l'heure UTC actuelle _now est d'abord obtenu au moyen de la fonction decodeTime(). Il s'agit d'une valeur entière dans la plage [0..6][0 .. 6], 0 correspondant au dimanche.

  • Le jour de la semaine précédent _yesterDay est déterminé dans la même plage de valeurs au moyen d'une opération modulo.

  • La mémoire _memECLatch écrit en permanence l'index de compteur actuel à l'emplacement de stockage indexé par _weekDay (= élément du vecteur). Pour cela, elle est initialisée avec 7 emplacements et une mémoire persistante en mode latch. Pour chaque jour de la semaine, c'est donc toujours le dernier index de compteur du jour correspondant qui est conservé. L'entrée de commande control est pour cela toujours à false.

En principe, la consommation journalière résulte de la différence des index de compteur par rapport à la veille. Si l'on formait toutefois directement la différence, la valeur du 6e jour passé (par exemple le jeudi lorsque le jour actuel est un mercredi) serait erronée. En effet, l'état final de la valeur du mercredi (une semaine auparavant) est justement en train d'être écrasé en permanence.

  • C'est pourquoi une seconde mémoire _memStart, de structure identique, conserve toujours les valeurs de la veille _memECLatch[_yesterday] comme valeur de départ pour le jour en cours.

  • La différence entre les deux vecteurs (mémoires) donne la consommation journalière par jour de la semaine sous forme du vecteur Consumption, ou ventilée par jour de la semaine Consume_Sun, Consume_Mon, etc.

Un avantage par rapport à la méthode consistant à faire avancer un tampon circulaire buffer() au moyen d'impulsions de la fonction trigger() est que l'appareil n'a pas besoin d'être allumé au moment du déclenchement. Condition dans ce cas : au moins un calcul la veille.