Sunteți pe pagina 1din 19

Lucrarea L2

ANALIZA UNOR FUNCŢII DE BAZĂ: INDECŞI, TARIFE,


PROFILURI DE SARCINĂ

2.1. SCOPUL LUCRĂRII

Contoarele de energie electrică au ca principală utilitate măsurarea energiei


electrice consumate şi/sau produse în scopul facturării acesteia. Această lucrare de
laborator intenţionează sa familiarizeze studentul cu modul in care se construiesc
indecşii de energie electrică în contor pornind de la măsurarea puterii active şi
reactive, prin prelucrări diverse, cum ar fi integrarea şi sinteza de indecşi noi, cu
care să se pună la dispoziţie energiile reactive în patru cadrane, precum şi indecşii
tarifari de energie.
De asemenea, pentru o bună înţelegere a profilurilor de sarcină, atât indecşii
de energie primari cât si cei specifici diverselor tarife, pot fi utilizaţi în cadrul
lucrării pentru a realiza profiluri de sarcină.
Pentru demonstrarea principiilor de construire a indecşilor de energie, dar şi a
celor stocaţi în profiluri de sarcină, se va folosi un program open-source numit
OSiMe (Open Simulation Meter).
Programul OSiMe este listat în ultimul capitol al acestei lucrări de laborator,
putând fi consultat pentru dezvoltări ulterioare. Deoarece programul asigură doar
funcţiile de bază ale unui contor inteligent, legate de sinteza şi utilizarea indecşilor,
acesta poate fi folosit de studenţii care doresc să construiască aplicaţii mai
complexe, ca un punct de plecare. În acest sens, programul este disponibil ca
proiect Qt (https://www.qt.io/ ), ce poate fi modificat în mod incremental, pentru
realizarea de noi funcţionalităţi.

2.2. MODUL DE LUCRU

Pentru punerea în evidenţă a diverselor funcţionalităţi ale aplicaţiei OSiMe,


lucrarea de laborator va parcurge etape care să permită înţelegerea şi verificarea
clară a acestora.
Programul OSiMe se execută fie din cadrul mediului de dezvoltarea Qt, ca
proiect ce se încarcă, iar apoi se compilează şi se rulează, fie direct de pe copy-
disc. În urma rulării programului se afişează fereastra prezentată în figura 2.1.
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 16

Fig. 2.1. Panelul disponibil la pornire a programului OSiMe.

Puterile P şi Q simulate pentru contor sunt afişate sub etichetele P_meter [W]
şi Q_meter [VAr], ele fiind zero la pornirea programului. Sub fiecare căsuţă se află
valori de programare care se vor copia în căsuţele valorilor efective în urma
apăsării butonului „Set”.
În continuare se vor analiza regimuri de lucru ale contoarelor, care să pună în
evidenţă cele 4 combinaţii de puteri active şi reactive, bazate pe semnul acestora,
aspect ce ne permite analiza indecşilor în cele 4 cadrane:
– Setul de valori P > 0 şi Q > 0 corespunde cadranului 1 al planului PQ;
– Setul de valori P < 0 şi Q > 0 corespunde cadranului 2 al planului PQ;
– Setul de valori P < 0 şi Q < 0 corespunde cadranului 3 al planului PQ;
– Setul de valori P > 0 şi Q < 0 corespunde cadranului 4 al planului PQ.
Pentru a pune în evidenţă funcţionarea contorului în fiecare din cele 4
cadrane, se începe cu setarea puterilor active şi reactive, corespunzătoare
cadranului 1. În figura 2.2 se prezintă situaţia în care P şi Q au fost fixate pentru
valorile P = 850 W şi Q = 100 VAr. alte valori cu acelaşi semn putând fi setate în
timpul derulării lucrării de laborator. În stânga planului PQ se poate observa şi
graficul care arată poziţia punctului (P, Q), printr-o dreaptă ce îl uneşte cu originea
(0,0). De menţionat faptul că graficul permite afişarea corectă a punctului de lucru
în cazul în care atât P cât şi Q au valori absolute mai mici decât 1000.
În cadrul acestei etape, după fixarea puterilor active şi reactive se va apăsa
butonul „Main reset”, astfel încât toţi indecşii vor fi aduşi la zero. In figura 2.2 sunt
de interes în această etapă următorii indecşi esenţiali:
– Ap: corespunzătoare integrării puterii active P atunci când aceasta are
valoare pozitivă (P > 0);
17 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

– Am: corespunzătoare integrării puterii active P atunci când aceasta are


valoare negativă (P > 0);
– Rp: corespunzătoare integrării puterii reactive Q atunci când aceasta are
valoare pozitivă (Q > 0), corespunzătoare regimului inductiv;
– Rm: corespunzătoare integrării puterii reactive Q atunci când aceasta are
valoare pozitivă (Q > 0), corespunzătoare regimului capacitiv.

Fig. 2.2. Urmărirea evoluţiei indecşilor pentru P şi Q în primul cadran.

În afară de aceşti indecşi, ce rezultă direct din integrarea fiecărei mărimi (P,
respectiv Q), mai există unii indecşi sintetizaţi, care pun în valoare aşa numitele
energii reactive în 4 cadrane. Aceşti indecşi sunt derivaţi din indecşii de energie
reactivă RP şi Rm, dar fiecare din aceşti doi indecşi permite sintetizarea a încă doi
indecşi, respectiv pentru cazul în care puterea activă este pozitivă respectiv
negativă. Se obţin deci sintetic următorii indecşi suplimentari:
– Q1: corespunzătoare integrării puterii reactive Q atunci când aceasta are
valoare pozitivă (Q > 0), iar puterea activă este tot pozitivă (P > 0), care
corespunde energiei reactive pentru cazul punctului de funcţionare in
cadranul 1;
– Q2: corespunzătoare integrării puterii reactive Q atunci când aceasta are
valoare pozitivă (Q > 0), dar când puterea activă este negativă (P < 0),
care corespunde energiei reactive pentru cazul punctului de funcţionare în
cadranul 2;
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 18

– Q3: corespunzătoare integrării puterii reactive Q atunci când aceasta are


valoare negativă (Q < 0), dar puterea activă este tot negativă (P < 0), care
corespunde energiei reactive pentru cazul punctului de funcţionare în
cadranul 3;
– Q4: corespunzătoare integrării puterii reactive Q atunci când aceasta are
valoare negativă (Q < 0), dar când puterea activă este pozitivă (P > 0),
care corespunde energiei reactive pentru cazul punctului de funcţionare în
cadranul 4;
Analiza funcţionării în cadranul 1
În figura 2.2 se poate observa faptul că indexul Q1 este singurul care a
crescut în timp şi care este diferit de zero, având deci valoare egală cu Rp. În cadrul
lucrării de laborator se va verifica ca valorile indecşilor Rp şi Rip sunt egale
indiferent de avansul acestor indecşi.
De asemenea, se va face verificarea faptului că valorile pentru Ap, respectiv
pentru Rp şi Rip, corespund puterilor simulate la intrarea în contor. Acest lucru se
va face prin preluarea unei imagini snapshoot similară cu cea din figura 2.2 şi
calcularea off-line a energiilor aferente puterilor. Pentru valorile de putere alese în
figura 2.2 se obţine:
Ap = P_meter × T = 850 W × 76 s = 64600 Ws
sau
Ap = 850 W × 76 s / 3600 = 17.9444 Wh
respectiv,
Rp = Q_meter × T = 100 VAr × 76 s = 7600 VArs
sau
Rp = 100 VAr × 76 s / 3600 = 2.1111 VArh
Q1 = Rp
unde T este valoarea corespunzătoare etichetei „Time from main reset [s]”.
Analiza funcţionării în cadranul 2
În urma validării corectitudinii integrărilor se trece la analiza funcţionării în
cadranul 2. Pentru aceasta, se alege o valoare pozitivă pentru Q şi una negativă
pentru P. Situaţia corespunde cazului în care puterea activă este injectată în reţea,
deci corespunde situaţiei de generator. În figura 2.3 au fost alese valorile
P = –950 W si Q = 420 VAr.
Se poate observa faptul că graficul arată funcţionarea în cadranul 2, iar
indecşii corespunzători celor 4 cadrane sunt toţi zero, cu excepţia indexului Rcp.
De asemenea, indexul Rp este mereu egal cu indexul Rip.
Validarea indecşilor obţinuţi se face similar cu situaţia anterioară. Pentru valorile
alese se verifică următoarele calcule:
Am = –P_meter × T = 950 W × 75 s = 71250 Ws
sau
19 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

Am = 950 W × 75 s / 3600 = 19.7917 Wh


respectiv,
Rp = Q_meter × T = 420 VAr × 75 s = 3150 VArs
sau
Rp = 420 VAr × 75 s / 3600 = 8.7500 VArh
Q2 = Rp

Fig. 2.3 Urmărirea evoluţiei indecşilor – cazul când P şi Q sunt în al doilea cadran.

Analiza funcţionării în cadranul 3


În urma validării corectitudinii integrărilor în cadranul 2 se trece la analiza
funcţionării în cadranul 3. Pentru aceasta, se alege o valoare negativă atât pentru P
cât şi pentru Q. Situaţia corespunde tot cazului în care puterea activă este injectată
în reţea (generator). În figura 2.4 au fost alese P = –650 W şi Q = –820 VAr.
Graficul arată funcţionarea în cadranul 3, iar indecşii corespunzători celor 4
cadrane sunt toţi zero, cu excepţia indexului Rcm. De asemenea, indexul Rp este
egal cu indexul Rcm. Validarea indecşilor obţinuţi se face similar:
Am = –P_meter × T = 650 W × 125 s = 81250 Ws
sau
Am = 650 W × 125 s / 3600 = 22.5694 Wh
respectiv,
Rm = –Q_meter × T = 820 VAr × 125 s = 102500 VArs
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 20

sau
Rp = 820 VAr × 125 s / 3600 = 28.4722 VArh
Q3 = Rm

Fig. 2.4. Urmărirea evoluţiei indecşilor, P si Q sunt în al treilea cadran.

Analiza funcţionării în cadranul 4


În urma validării corectitudinii integrărilor în cadranul 3 se trece la analiza
funcţionării în ultimul cadran, respectiv cadranul 4. Pentru aceasta, se alege o
valoare pozitivă pentru P şi una negativă pentru Q. Situaţia corespunde cazului în
care puterea activă est absorbită din reţea (consumator), similar funcţionării în
cadranul 1. În figura 2.5 au fost alese valorile P = +350 W şi Q = -740 VAr.
Graficul arată funcţionarea în cadranul 4, iar indecşii corespunzători celor 4
cadrane sunt toţi zero, cu excepţia indexului Rim. De asemenea, Indexul Rm este
egal cu indexul Rim.
Validarea indecşilor obţinuţi se face similar cu modul în care s-a procedat
anterior:
Ap = P_meter × T = 350 W × 134 s = 46900 Ws
sau
Ap = 350 W × 134 s / 3600 = 13.0278 Wh
respectiv,
Rm = –Q_meter × T = 740 VAr × 134 s = 99160 VArs
sau
Rp = 740 VAr × 134 s / 3600 = 27.5444 VArh
Q4 = Rm
21 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

Testele efectuare au arătat modul în care se pot obţine din valorile de intrare
P şi Q indecşii de bază precum şi cei derivaţi, necesari punerii în valoare a
energiilor reactive în cele 4 cadrane.

Fig. 2.5. Urmărirea evoluţiei indecşilor, P si Q sunt in al patrulea cadran.

În continuare se pune în valoare modul în care se construiesc indecşii tarifari.


Fiecare index tarifar se caracterizează prind două tipuri de informaţii:
– O asociere la un index de bază sau a unuia derivat pentru cele 4 cadrane;
– O asociere cu perioade de timp prin care acest index creşte, iar indexul
asociat creşte şi el. Perioada de timp în care acest index tarifar creşte se
numeşte perioadă de utilizare a tarifului sau Time of USe (TOU).
În programul demonstrativ s-au ales 4 tarife diferite, pentru fiecare existând
un index tarifar. În partea de jos a figurii 2.6 se arată cele 4 tarife şi cele două tipuri
de informaţii: canalul şi descrierea TOU.
Tot în figura 2.7 este prezentată partea de tarifare. Descrierea timpului de
utilizare se face printr-un şir de caractere (string) care conţine datele necesare
pentru a descrie comutarea timpului până la rezoluţia de un minut.
Astfel, H1 şi M1 reprezintă ora şi minutul din ziua în care începe perioada
tarifară, iar H şi M2 reprezintă ora şi minutul de sfârşit a perioadei.
Indicativul DW (day of the week) este urmat de un şir de 5 caractere, care
corespund zilelor lucrătoare, urmate de încă două poziţii separate de primele prin
punct, desemnând cele doua zile libere (sâmbătă şi duminică). Poziţia având
valoarea 1 arată faptul că ziua este validă pentru respectivul tarif. În exemplul de
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 22

mai sus toate zilele sunt setate pe valoarea 1, ceea ce înseamnă că orele de început
şi de sfârşit sunt valabile pe toata perioada săptămânii.
MY se referă la luna din an, fiind patru grupuri de 3 luni, la fiecare putându-
se pune 1 sau 0.
Cd este identificator al condiţiei, putând exista mai multe condiţii distincte de
timp pentru acelaşi tarif, în regim SAU (oricare din condiţii este îndeplinită, tariful
devine activ). Tarifele active la un moment dat sunt afişate în căsuţa cu eticheta
„Tarif curent”.

Fig. 2.6. Urmărirea evoluţiei indecşilor pentru cele 4 tarife.

În cadrul lucrării de laborator se va urmări creştarea valorii indecşilor pentru


tarifele active, în cazul în care indecşii de bază selectaţi cresc la rândul lor.

Fig. 2.7. Detaliu asupra sistemului de tarifare.

Se va modifica în timp real ora şi/sau minutul unui tarif al cărui index
avansează, astfel încât să se verifice faptul că tariful poate fi dezactivat sau
23 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

reactivat, prin scoaterea sau readucerea tarifului în perioada în care se află ora
curentă (caseta din stânga sus afişează data şi ora curentă).

Fig. 2.8. Detaliere profiluri de sarcină.

Ultimele teste se referă la analizarea creării de curbe de sarcină. În partea din


dreapta sus a figurii 2.8 se poate vedea faptul ca sunt disponibile două seturi de
profiluri de sarcină (engl.: load profiles).
Pentru fiecare profil se pot valida diverşi indecşi care să poată fi memoraţi la
intervale egale de timpi. În testele anterioare nici un index nu a fost asociat
profilurilor, dar în cazul figurii 2.8 se poate observa faptul că primul profil, care
înregistrează date la fiecare 60 secunde (adică 1 minut), au fost asociaţi (validaţi)
indecşii Ap, Am, Rp, Rm. În figură se poate observa faptul că în zona de afişare de
sub valorile validate sunt deja memorate profilurile corespunzătoare unui anumit
minut (la ora 18:00). Totodată, profilul 2 are selectate Ap şi Am, dar şi toţi indecşii
tarifelor 1 pană la 4. în zona de afişare a profilurilor se văd 6 înregistrări, câte una
pentru fiecare index, înregistratele fiind realizate la fiecare 120 secunde (2 minute).
În figura 2.9 se poate observa faptul că au apărut noi înregistrări şi că în
profilul 2 au fost selectaţi toţi indecşii disponibili. Figura 2.10 ilustrează un detaliu
al zonei de selectare a indecşilor.
De reţinut că majoritatea contoarelor au posibilitatea să înregistreze indecşi în
unul sau două profiluri cu timpi diferiţi (în cazul nostru fiind 1 minut pentru primul
profil şi 2 minute pentru al doilea), iar pentru fiecare profil se pot parametriza
indecşii de bază ce se înregistrează. Lucrarea de laborator permite deci înţelegerea
uşoară a mecanismelor de realizare a pofilelor de sarcină.
In tabelul 1.1 sunt extrase înregistrările din exemplele de mai sus.
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 24

Fig. 2.9. Detaliere profiluri de sarcină, reconfigurare.

Fig. 2.10. Detaliere configuraţie pentru profilurile de sarcina.

Tabel 1.1. Înregistrări ale profilurilor de lucru.


Profil de lucru nr. 1, Profil de lucru nr. 2, înregistrări reale la
înregistrări reale fiecare 2 minute
17-5-21 22:7:0;Ap=0.0000 17-5-21 22:8:0;Ap=0.0000
17-5-21 22:7:0;Am=33.1644 17-5-21 22:8:0;Am=42.7311
17-5-21 22:7:0;Rp=16.7556 17-5-21 22:8:0;T01=0.0000
17-5-21 22:7:0;Rm=0.0000 17-5-21 22:8:0;T02=0.0000
17-5-21 22:8:0;Ap=0.0000 17-5-21 22:8:0;T03=21.5889
17-5-21 22:8:0;Am=42.7311 17-5-21 22:8:0;T04=42.7311
17-5-21 22:8:0;Rp=21.5889 17-5-21 22:10:0;Ap=0.0000
17-5-21 22:8:0;Rm=0.0000 17-5-21 22:10:0;Am=61.8644
17-5-21 22:9:0;Ap=0.0000 17-5-21 22:10:0;Rp=31.2556
17-5-21 22:9:0;Am=52.2978 17-5-21 22:10:0;Rm=0.0000
17-5-21 22:9:0;Rp=26.4222 17-5-21 22:10:0;T01=0.0000
17-5-21 22:9:0;Rm=0.0000 17-5-21 22:10:0;T02=0.0000
17-5-21 22:10:0;Ap=0.0000 17-5-21 22:10:0;T03=31.2556
17-5-21 22:10:0;Am=61.8644 17-5-21 22:10:0;T04=61.8644
17-5-21 22:10:0;Rp=31.2556
17-5-21 22:10:0;Rm=0.0000
25 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

Se poate observa faptul că pentru aceeaşi mărime, indecşii la fiecare 2 minute


înregistraţi în LP2 corespund cu indecşii aceluiaşi minut din LP1.
În cadrul lucrării de laborator se salvează pe calculator şi se analizează
coerenţa între indecşii celor două LP-uri.

2.3. CONCLUZII

Lucrarea de laborator analizează unele funcţii de bază ale contoarelor:


indecşi, tarife, profiluri de sarcină. Prin setarea interactivă a diverşilor parametri,
studentul are posibilitatea să înţeleagă aceste funcţionalităţi în timp real. Noi
funcţionalităţi se pot dezvolta ulterior de către studenţi în cadrul unor lucrări
dedicate, cu subiecte mai complicate.
Lucrarea are deci şi intenţia să creeze o bază de pornire, bazată pe aplicaţia
Open-source OSiMe, care să faciliteze studii mai aprofundate. În ultimul capitol
sunt listate liniile de cod pentru aplicaţia de bază.

2.4. PROGRAMUL DE CALCUL OsiMe

Sursa programului este listată în continuare, limbajul de calcul utilizat fiind


C++. Pentru analize și eventuale modificări, în cadrul laboratorului se va utiliza
mediul de lucru Qt, cu care se poate accesa proiectul NGOM.pro, ce conține
programul OsiMe utilizat în cadrul lucrării.
În cadrul programului se vor analiza în special rutinele
void NGOMeter::intr_1sec()
void NGOMeter::Find_crt_tarrif()
void NGOMeter::Make_load_profiles(int y1, int m1, int d1, int h1,
int min1, int sec1, int ms1)

unde se realizează prelucrările specifice determinării distribuţiilor de probabilitate.


Rutina
void NGOMeter::Display1()

realizează afișarea tuturor datelor în cadrul interfeței om-mașină.


Pentru dezvoltări ulterioare, în cadrul programului este disponibilă rutina
void NGOMeter::Qwrite_log1(QString sw, QString filename, bool
delete_file)

care, dacă este invocată, asigură salvarea pe hard-disc (HDD) a unor valori.
Studenții sunt încurajați să propună salvarea pe HDD a unor mărimi de interes și să
determine împreună cu cadrul didactic specializat locul în cadrul programului unde
trebuie invocată rutina și parametrii ce trebuie folosiți.
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 26

De remarcat faptul că programul deține câteva rutine orientate pe evenimente,


cu ar fi rutina principală ce este rulată la intervale de timp egale (la fiecare o
secundă):
void NGOMeter::intr_1sec()
și rutinele ce captează evenimente de apăsare de butoane pe interfața om-mașină:
void NGOMeter::on_pushButton_Reset_main_indexes_clicked()
void NGOMeter::on_pushButton_Set_PQ_clicked()
care sunt apelate la acțiuni de comandă a butoanelor „Main reset” și “Set” din
figurile 2.1 – 2.9.
-------------------------------------- NGOMeter.cpp ---------------------

#include <QTimer>
#include <QDateTime>
#include <QFile>
#include <fcntl.h>
#include <QtDebug>
#include <QtGui>
#include <cstdlib>
#include <stdlib.h>
#include <sstream>
#include <QString>
#include <QtCore/qmath.h>
#include <QGlobal.h>
#include "ngometer.h"
#include "ui_ngometer.h"

static int dt=1000; // pasul de timp pentru intrerupere


QTimer *t1sec;
QString stime1="";
struct OBIS_structures {
QString OBIS_code;
QString Value;
QString Quality;
int64_t Index;
};
double P_meter = 850; // [W] -> 120*3600 Ws
double P_meter_const = 10.0; // 0.1Wh: 10 units mean 1 Wh, then 1 unit =
0.1Wh
double Q_meter = 100; // [VAr]
double Q_meter_const = 10.0; //
double T_integr=1.0; // [s]
int64_t Time_from_main_reset = 0;
double Idx_d_Ap=0; double Idx_Old_d_Ap=0; double Idx_Dlt_d_Ap=0;
double Idx_d_Am=0; double Idx_Old_d_Am=0; double Idx_Dlt_d_Am=0;
double Idx_d_Rp=0; double Idx_Old_d_Rp=0; double Idx_Dlt_d_Rp=0;
double Idx_d_Rm=0; double Idx_Old_d_Rm=0; double Idx_Dlt_d_Rm=0;

// integer index of Active energy with (+), meaning consumption, stored in


the meter
// This index will never reset in a meter, but only recycle when max value
is reached
int64_t Idx_i64_Ap=0;
// integer index of Active energy with (-), meaning production, stored in
the meter
// This index will never reset in a meter, but only recycle when max value
is reached
int64_t Idx_i64_Am=0;
// integer index of Reactive energy with (+), stored in the meter
27 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

// This index will never reset in a meter, but only recycle when max value
is reached
int64_t Idx_i64_Rp=0;
// integer index of Reactive energy with (-), stored in the meter
// This index will never reset in a meter, but only recycle when max value
is reached
int64_t Idx_i64_Rm=0;
// indexes for 4 quadrant reactive energies
int64_t Idx_i64_Rip=0;
int64_t Idx_i64_Rcp=0;
int64_t Idx_i64_Rim=0;
int64_t Idx_i64_Rcm=0;

// registers used for calculating energies in 4 quadrants and for


tarrification
int64_t Idx_Old_i64_Ap=0; int64_t Idx_Dlt_i64_Ap=0;
int64_t Idx_Old_i64_Am=0; int64_t Idx_Dlt_i64_Am=0;
int64_t Idx_Old_i64_Rp=0; int64_t Idx_Dlt_i64_Rp=0;
int64_t Idx_Old_i64_Rm=0; int64_t Idx_Dlt_i64_Rm=0;

int Tarrif_crt=1;
double Idx_Tarrif_01=0;
double Idx_Tarrif_02=0;
double Idx_Tarrif_03=0;
double Idx_Tarrif_04=0;
double Idx_Tarrif_xy[10];
QString Tarrif_xy_TOU_text[10];
QString LP01_text_buffer="";
QString LP02_text_buffer="";
QString Tarif_curent_text="";

int64_t Idx_i64_Tarrif_01=0;
int64_t Idx_i64_Tarrif_02=0;
int64_t Idx_i64_Tarrif_03=0;
int64_t Idx_i64_Tarrif_04=0;
int64_t Idx_i64_Tarrif_xy[4];
OBIS_structures A_plus, A_minus;
OBIS_structures R_plus, R_minus;
OBIS_structures R_ind_plus, R_ind_minus, R_cap_plus, R_cap_minus;

NGOMeter::NGOMeter(QWidget *parent) :
// fereastra principala
QMainWindow(parent),
ui(new Ui::NGOMeter)
{
ui->setupUi(this);
t1sec = new QTimer(this);
t1sec->start(dt); // parametrul da numarul de milisecunde la care are
loc o intrerupere

connect(t1sec, SIGNAL(timeout()), this, SLOT(intr_1sec()));

ui->lineEdit_P_meter->setText(QString::number(0));
ui->lineEdit_Q_meter->setText(QString::number(0));
ui->lineEdit_P_meter_set->setText(QString::number(P_meter));
ui->lineEdit_Q_meter_set->setText(QString::number(Q_meter));

for(int i=0; i<10; i++) {


Idx_Tarrif_xy[i]=0;
Tarrif_xy_TOU_text[i]="";
}
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 28

Tarrif_xy_TOU_text[0]="Cd=01;YM=111.111.111.111;WD=11111.11;H1=15;M1=00;H2=2
2;M2=00";
ui->lineEdit_Tarrif_01_TOU->setText(Tarrif_xy_TOU_text[0]);

Tarrif_xy_TOU_text[1]="Cd=01;YM=111.111.111.111;WD=11111.11;H1=14;M1=00;H2=1
5;M2=18";
ui->lineEdit_Tarrif_02_TOU->setText(Tarrif_xy_TOU_text[1]);
}

void NGOMeter::intr_1sec() {
int y1, m1, d1, h1, min1, sec1, ms1;
// se calculeaza timpul scurs de la ultima intrerupere
QDateTime DT1;
QDate date = QDate::currentDate(); y1=date.year(); m1=date.month();
d1=date.day();
QTime time = QTime::currentTime(); h1=time.hour(); min1= time.minute();
sec1=time.second(); ms1 = time.msec();
QString s1 = QString::number(y1)+"-" + QString::number(m1)+"-" +
QString::number(d1)+" ";
s1 += QString::number(h1)+":" + QString::number(min1)+":" +
QString::number(sec1);//+":" + QString::number(ms1);
//stime1 = s1;
ui->lineEdit_Time->setText(s1);
P_meter = QString(ui->lineEdit_P_meter->text()).toDouble();
Q_meter = QString(ui->lineEdit_Q_meter->text()).toDouble();
Tarrif_crt = QString(ui->lineEdit_Tarrif_crt->text()).toInt();
// real-time functions in the T_integr interrupt
// Dividing by 3600 is for getting kWh
// Multipying by 1000 is for getting Wh
if(P_meter>0) Idx_i64_Ap += 1.0 * P_meter *P_meter_const * T_integr;
else Idx_i64_Am += -1.0 * P_meter *P_meter_const * T_integr;
if(Q_meter>0) Idx_i64_Rp += 1.0 * Q_meter *Q_meter_const * T_integr;
else Idx_i64_Rm += -1.0 * Q_meter *Q_meter_const * T_integr;
//***** real-time functions in the T_integr interrupt
// calculation of indexes advances
Idx_Dlt_i64_Ap = Idx_i64_Ap-Idx_Old_i64_Ap; Idx_Old_i64_Ap = Idx_i64_Ap;
Idx_Dlt_i64_Am = Idx_i64_Am-Idx_Old_i64_Am; Idx_Old_i64_Am = Idx_i64_Am;
Idx_Dlt_i64_Rp = Idx_i64_Rp-Idx_Old_i64_Rp; Idx_Old_i64_Rp = Idx_i64_Rp;
Idx_Dlt_i64_Rm = Idx_i64_Rm-Idx_Old_i64_Rm; Idx_Old_i64_Rm = Idx_i64_Rm;
// Four quadrant integration
if(P_meter>0) {
Idx_i64_Rip += Idx_Dlt_i64_Rp;
Idx_i64_Rim += Idx_Dlt_i64_Rm;
}
else {
Idx_i64_Rcp += Idx_Dlt_i64_Rp;
Idx_i64_Rcm += Idx_Dlt_i64_Rm;
}

Time_from_main_reset += T_integr;
Find_crt_tarrif();
Make_load_profiles(y1, m1, d1, h1, min1, sec1, ms1);

Display1();
update();
}

void NGOMeter::Find_crt_tarrif() {
//lineEdit_Tarrif_01_ch
int ch1=0;
// First tarif
29 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

// Sintaxa: Cd=01;YM=111.111.111.111;WD=11111.11;H1=16;M1=0;H2=16;M2=18
// Cd=conditia; YM=month of the year; DW=Day of the week;
// H1, H2= ora de iceput si de sfarsit; M1, M2 = minutul de inceput si
de sfarsit
QString s01;
bool time_ready=false;
Tarif_curent_text="";

for(int i1=0; i1<4; i1++) {


switch(i1) {
case 0: s01= ui->lineEdit_Tarrif_01_ch->text(); break;
case 1: s01= ui->lineEdit_Tarrif_02_ch->text(); break;
case 2: s01= ui->lineEdit_Tarrif_03_ch->text(); break;
case 3: s01= ui->lineEdit_Tarrif_04_ch->text(); break;
default: s01= ui->lineEdit_Tarrif_01_ch->text();
}

if(s01=="Ap") ch1=1; if(s01=="Am") ch1=2; if(s01=="Rp") ch1=3;


if(s01=="Rm") ch1=4;

//Tarrif_xy_TOU_text[0]="Cd=01;YM=111.111.111.111;WD=11111.11;H1=16;M1=00;H2
=17;M2=00";

QTime time = QTime::currentTime();


int h1crt=time.hour();
int min1crt= time.minute();
int min_crt= h1crt*60+min1crt;
int H1=0, M1=0, H2=0, M2=0;
QString H1s=""; QString H2s=""; QString M1s=""; QString M2s="";
QString delim1(";");
Tarrif_xy_TOU_text[0] = ui->lineEdit_Tarrif_01_TOU->text();
Tarrif_xy_TOU_text[1] = ui->lineEdit_Tarrif_02_TOU->text();
Tarrif_xy_TOU_text[2] = ui->lineEdit_Tarrif_03_TOU->text();
Tarrif_xy_TOU_text[3] = ui->lineEdit_Tarrif_04_TOU->text();

QStringList s2_list = Tarrif_xy_TOU_text[i1].split(delim1);


foreach (QString strl, s2_list) {
QString delim2("=");
QStringList s3_list = strl.split(delim2);
if(s3_list.value(0)=="H1") {
H1s=s3_list.value(1);
H1 = H1s.toInt();
}
if(s3_list.value(0)=="H2") { H2s=s3_list.value(1); H2 = H2s.toInt();
}
if(s3_list.value(0)=="M1") { M1s=s3_list.value(1); M1 = H1s.toInt();
}
if(s3_list.value(0)=="M2") { M2s=s3_list.value(1); M2 = H2s.toInt();
}
}
time_ready=false;
int min1_crt= H1*60+M1;
int min2_crt= H2*60+M2;
if(min_crt>=min1_crt) if(min_crt<min2_crt) time_ready=true;

if(time_ready==true) // daca ne aflam in dom. timp pt. tarif


{
Tarif_curent_text += QString::number(i1+1)+" ";
switch(ch1){
case 1: Idx_i64_Tarrif_xy[i1] += Idx_Dlt_i64_Ap; break;
case 2: Idx_i64_Tarrif_xy[i1] += Idx_Dlt_i64_Am; break;
case 3: Idx_i64_Tarrif_xy[i1] += Idx_Dlt_i64_Rp; break;
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 30

case 4: Idx_i64_Tarrif_xy[i1] += Idx_Dlt_i64_Rm; break;


}
}
}
}

int drw_x0=20, drw_y0=100, drw_x_len=200, drw_y_len=200, scale_height;


void NGOMeter::paintEvent(QPaintEvent *){
QString s2="";
QPainter painter(this);
painter.fillRect(drw_x0, drw_y0, drw_x_len, drw_y_len, Qt::white);
painter.setPen(Qt::black);
painter.drawLine(drw_x0,drw_y0+drw_y_len/2,
drw_x0+drw_x_len,drw_y0+drw_y_len/2);
painter.drawLine(drw_x0+drw_x_len/2,drw_y0,
drw_x0+drw_x_len/2,drw_y0+drw_y_len);
painter.setPen(Qt::blue);
painter.drawText(drw_x0+drw_x_len+3,drw_y0+drw_y_len/2+4, "P");
painter.setPen(Qt::blue);
painter.drawText(drw_x0+drw_x_len/2-3,drw_y0-7, "Q");

int dx1= P_meter / 1000 * drw_x_len / 2;


if(dx1>=drw_x_len/2) dx1 = drw_x_len/2;
if(dx1<=-drw_x_len/2) dx1 = -drw_x_len/2;
int dy1= - Q_meter / 1000 * drw_y_len / 2; //
if(dy1>=drw_y_len/2) dy1 = drw_y_len/2;
if(dy1<=-drw_y_len/2) dy1 = -drw_y_len/2;

painter.setPen(QPen(Qt::red,2));
painter.drawLine(drw_x0+drw_x_len/2,drw_y0+drw_y_len/2,
drw_x0+drw_x_len/2+dx1,drw_y0+drw_y_len/2+dy1);
}
void NGOMeter::Make_load_profiles(int y1, int m1, int d1, int h1, int min1,
int sec1, int ms1) {

double display_d1;
// Load profile No. 1
QString s1="";
QString st="";
if(sec1==0) {
st += QString::number(y1-2000)+"-" + QString::number(m1)+"-" +
QString::number(d1)+" ";
st += QString::number(h1)+":" + QString::number(min1)+":" +
QString::number(sec1)+";";
// Ap
display_d1 = Idx_i64_Ap / (3600/T_integr) / P_meter_const;
s1 = st+ "Ap=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Ap1->checkState()!= Qt::Unchecked) LP01_text_buffer
+= s1;
// Am
display_d1 = Idx_i64_Am / (3600/T_integr) / P_meter_const;
s1 = st+ "Am=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Am1->checkState()!= Qt::Unchecked) LP01_text_buffer
+= s1;
// Rp
display_d1 = Idx_i64_Rp / (3600/T_integr) / P_meter_const;
s1 = st+ "Rp=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Rp1->checkState()!= Qt::Unchecked) LP01_text_buffer
+= s1;
// Rm
display_d1 = Idx_i64_Rm / (3600/T_integr) / P_meter_const;
s1 = st+ "Rm=" + QString::number(display_d1,'%10g4',4)+"\t";
31 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

if(ui->checkBox_Rm1->checkState()!= Qt::Unchecked) LP01_text_buffer


+= s1;
// T01
display_d1 = Idx_i64_Tarrif_xy[0] / (3600/T_integr) / P_meter_const;
s1 = st+ "T01=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T01_1->checkState()!= Qt::Unchecked)
LP01_text_buffer += s1;
// T02
display_d1 = Idx_i64_Tarrif_xy[1] / (3600/T_integr) / P_meter_const;
s1 = st+ "T02=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T02_1->checkState()!= Qt::Unchecked)
LP01_text_buffer += s1;
// T03
display_d1 = Idx_i64_Tarrif_xy[2] / (3600/T_integr) / P_meter_const;
s1 = st+ "T03=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T03_1->checkState()!= Qt::Unchecked)
LP01_text_buffer += s1;
// T04
display_d1 = Idx_i64_Tarrif_xy[3] / (3600/T_integr) / P_meter_const;
s1 = st+ "T04=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T04_1->checkState()!= Qt::Unchecked)
LP01_text_buffer += s1;
}

// Load profile No. 2


s1=""; st="";
if(sec1==0) if((min1 % 2) == 0) {
st += QString::number(y1-2000)+"-" + QString::number(m1)+"-" +
QString::number(d1)+" ";
st += QString::number(h1)+":" + QString::number(min1)+":" +
QString::number(sec1)+";";
// Ap
display_d1 = Idx_i64_Ap / (3600/T_integr) / P_meter_const;
s1 = st + "Ap=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Ap2->checkState()!= Qt::Unchecked) LP02_text_buffer
+= s1;
// Am
display_d1 = Idx_i64_Am / (3600/T_integr) / P_meter_const;
s1 = st+ "Am=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Am2->checkState()!= Qt::Unchecked) LP02_text_buffer
+= s1;
// Rp
display_d1 = Idx_i64_Rp / (3600/T_integr) / P_meter_const;
s1 = st+ "Rp=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Rp2->checkState()!= Qt::Unchecked) LP02_text_buffer
+= s1;
// Rm
display_d1 = Idx_i64_Rm / (3600/T_integr) / P_meter_const;
s1 = st+ "Rm=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_Rm2->checkState()!= Qt::Unchecked) LP02_text_buffer
+= s1;
// T01
display_d1 = Idx_i64_Tarrif_xy[0] / (3600/T_integr) / P_meter_const;
s1 = st+ "T01=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T01_2->checkState()!= Qt::Unchecked)
LP02_text_buffer += s1;
// T02
display_d1 = Idx_i64_Tarrif_xy[1] / (3600/T_integr) / P_meter_const;
s1 = st+ "T02=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T02_2->checkState()!= Qt::Unchecked)
LP02_text_buffer += s1;
// T03
Elemente de utilizare avansată a contoarelor de energie electrică în sisteme electroenergetice 32

display_d1 = Idx_i64_Tarrif_xy[2] / (3600/T_integr) / P_meter_const;


s1 = st+ "T03=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T03_2->checkState()!= Qt::Unchecked)
LP02_text_buffer += s1;
// T04
display_d1 = Idx_i64_Tarrif_xy[3] / (3600/T_integr) / P_meter_const;
s1 = st+ "T04=" + QString::number(display_d1,'%10g4',4)+"\t";
if(ui->checkBox_T04_2->checkState()!= Qt::Unchecked)
LP02_text_buffer += s1;
}

//lineEdit_LP1_period
ui->lineEdit_LP1_period->setText("60");
ui->lineEdit_LP2_period->setText("120");
}

void NGOMeter::Display1() {
// display after the T_integer cycle
// ui->lineEdit_AFE_Ap->setText(QString::number(Idx_d_Ap,'%8g4',4));
double display_d1;
display_d1 = Idx_i64_Ap / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Ap-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Am / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Am-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Rp / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Rp-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Rm / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Rm-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Rip / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Rip-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Rcp / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Rcp-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Rim / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Rim-
>setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Rcm / (3600/T_integr) / P_meter_const;
ui->lineEdit_Main_index_Rcm-
>setText(QString::number(display_d1,'%10g4',4));
// Display tarrif indexes
display_d1 = Idx_i64_Tarrif_xy[0] / (3600/T_integr) / P_meter_const;
ui->lineEdit_Tarrif_01->setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Tarrif_xy[1] / (3600/T_integr) / P_meter_const;
ui->lineEdit_Tarrif_02->setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Tarrif_xy[2] / (3600/T_integr) / P_meter_const;
ui->lineEdit_Tarrif_03->setText(QString::number(display_d1,'%10g4',4));
display_d1 = Idx_i64_Tarrif_xy[3] / (3600/T_integr) / P_meter_const;
ui->lineEdit_Tarrif_04->setText(QString::number(display_d1,'%10g4',4));
// Load profiles
ui->textEdit_LP01->setText(LP01_text_buffer);
ui->textEdit_LP02->setText(LP02_text_buffer);
// lineEdit_Tarrif_crt
ui->lineEdit_Tarrif_crt->setText(Tarif_curent_text);
ui->lineEdit_Time_from_main_reset-
>setText(QString::number(Time_from_main_reset));
}
33 Analiza unor funcții de bază: indecși, tarife, profiluri de sarcină

void NGOMeter::Qwrite_log1(QString sw, QString filename, bool delete_file) {


QFile f(filename);
if(delete_file==true) {
f.open(QIODevice::ReadWrite|QIODevice::Text|QIODevice::Truncate); f.close();
return; }
else {
f.open(QIODevice::ReadWrite|QIODevice::Text|QIODevice::Append);
QString s1 = sw;
s1 += "\n";
QByteArray ba = s1.toLocal8Bit();
const char *c_str2 = ba.data();
//f.write(c_str2, strlen(c_str2));
f.write(c_str2, strlen(c_str2));
f.close();
}
}

NGOMeter::~NGOMeter()
{
delete ui;
}

void NGOMeter::on_pushButton_Reset_main_indexes_clicked()
{
// Reset of main indexes
Idx_i64_Ap=0; Idx_Old_i64_Ap=0;
Idx_i64_Am=0; Idx_Old_i64_Am=0;
Idx_i64_Rp=0; Idx_Old_i64_Rp=0;
Idx_i64_Rm=0; Idx_Old_i64_Rm=0;

// reset of 4-quadrant indexes


Idx_i64_Rip=0;
Idx_i64_Rcp=0;
Idx_i64_Rim=0;
Idx_i64_Rcm=0;

for(int i1=0; i1<4; i1++) Idx_i64_Tarrif_xy[i1]=0;

// Other reset functions


Time_from_main_reset = 0;
}

void NGOMeter::on_pushButton_Set_PQ_clicked()
{
ui->lineEdit_P_meter->setText(ui->lineEdit_P_meter_set->text());
ui->lineEdit_Q_meter->setText(ui->lineEdit_Q_meter_set->text());
}

S-ar putea să vă placă și