MycilaJSY 13.0.0
Arduino / ESP32 library for the JSY1031, JSY-MK-163, JSY-MK-193, JSY-MK-194, JSY-MK-227, JSY-MK-229, JSY-MK-333 families single-phase and three-phase AC bidirectional meters from Shenzhen Jiansiyan Technologies Co, Ltd.
Loading...
Searching...
No Matches
MycilaJSYMetrics.cpp
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright (C) 2023-2025 Mathieu Carbou
4 */
5#include "MycilaJSY.h"
6
7static constexpr float DEG_TO_RAD_F = static_cast<float>(DEG_TO_RAD);
8
9float Mycila::JSY::Metrics::thdi(float phi) const {
10 if (powerFactor == 0)
11 return NAN;
12 const float cosPhi = std::cos(phi * DEG_TO_RAD_F);
13 return 100.0f * std::sqrt((cosPhi * cosPhi) / (powerFactor * powerFactor) - 1);
14}
15
16float Mycila::JSY::Metrics::resistance() const { return current == 0 ? NAN : std::abs(activePower / (current * current)); }
17
18float Mycila::JSY::Metrics::dimmedVoltage() const { return current == 0 ? NAN : std::abs(activePower / current); }
19
20float Mycila::JSY::Metrics::nominalPower() const { return activePower == 0 ? NAN : std::abs(voltage * voltage * current * current / activePower); }
21
22void Mycila::JSY::Metrics::clear() {
23 frequency = NAN;
24 voltage = NAN;
25 current = NAN;
26 activePower = NAN;
27 reactivePower = NAN;
28 apparentPower = NAN;
29 powerFactor = NAN;
30 activeEnergy = 0;
31 activeEnergyImported = 0;
32 activeEnergyReturned = 0;
33 reactiveEnergy = 0;
34 reactiveEnergyImported = 0;
35 reactiveEnergyReturned = 0;
36 apparentEnergy = 0;
37 phaseAngleU = NAN;
38 phaseAngleI = NAN;
39 phaseAngleUI = NAN;
40 thdU = NAN;
41 thdI = NAN;
42}
43
44bool Mycila::JSY::Metrics::operator==(const Mycila::JSY::Metrics& other) const {
45 return (std::isnan(frequency) ? std::isnan(other.frequency) : frequency == other.frequency) &&
46 (std::isnan(voltage) ? std::isnan(other.voltage) : voltage == other.voltage) &&
47 (std::isnan(current) ? std::isnan(other.current) : current == other.current) &&
48 (std::isnan(activePower) ? std::isnan(other.activePower) : activePower == other.activePower) &&
49 (std::isnan(reactivePower) ? std::isnan(other.reactivePower) : reactivePower == other.reactivePower) &&
50 (std::isnan(apparentPower) ? std::isnan(other.apparentPower) : apparentPower == other.apparentPower) &&
51 (std::isnan(powerFactor) ? std::isnan(other.powerFactor) : powerFactor == other.powerFactor) &&
52 (activeEnergy == other.activeEnergy) &&
53 (activeEnergyImported == other.activeEnergyImported) &&
54 (activeEnergyReturned == other.activeEnergyReturned) &&
55 (reactiveEnergy == other.reactiveEnergy) &&
56 (reactiveEnergyImported == other.reactiveEnergyImported) &&
57 (reactiveEnergyReturned == other.reactiveEnergyReturned) &&
58 (apparentEnergy == other.apparentEnergy) &&
59 (std::isnan(phaseAngleU) ? std::isnan(other.phaseAngleU) : phaseAngleU == other.phaseAngleU) &&
60 (std::isnan(phaseAngleI) ? std::isnan(other.phaseAngleI) : phaseAngleI == other.phaseAngleI) &&
61 (std::isnan(phaseAngleUI) ? std::isnan(other.phaseAngleUI) : phaseAngleUI == other.phaseAngleUI) &&
62 (std::isnan(thdU) ? std::isnan(other.thdU) : thdU == other.thdU) &&
63 (std::isnan(thdI) ? std::isnan(other.thdI) : thdI == other.thdI);
64}
65
66Mycila::JSY::Metrics& Mycila::JSY::Metrics::operator+=(const Mycila::JSY::Metrics& other) {
67 // voltage, frequency, phase angle and thd are not aggregated
68 current += other.current;
69 activePower += other.activePower;
70 apparentPower += other.apparentPower;
71 activeEnergy += other.activeEnergy;
72 activeEnergyImported += other.activeEnergyImported;
73 activeEnergyReturned += other.activeEnergyReturned;
74 reactiveEnergy += other.reactiveEnergy;
75 reactiveEnergyImported += other.reactiveEnergyImported;
76 reactiveEnergyReturned += other.reactiveEnergyReturned;
77 apparentEnergy += other.apparentEnergy;
78 powerFactor = apparentPower == 0 ? NAN : abs(activePower / apparentPower);
79 reactivePower = std::sqrt(apparentPower * apparentPower - activePower * activePower);
80 return *this;
81}
82
83void Mycila::JSY::Metrics::operator=(const Metrics& other) {
84 frequency = other.frequency;
85 voltage = other.voltage;
86 current = other.current;
87 activePower = other.activePower;
88 reactivePower = other.reactivePower;
89 apparentPower = other.apparentPower;
90 powerFactor = other.powerFactor;
91 activeEnergy = other.activeEnergy;
92 activeEnergyImported = other.activeEnergyImported;
93 activeEnergyReturned = other.activeEnergyReturned;
94 reactiveEnergy = other.reactiveEnergy;
95 reactiveEnergyImported = other.reactiveEnergyImported;
96 reactiveEnergyReturned = other.reactiveEnergyReturned;
97 apparentEnergy = other.apparentEnergy;
98 phaseAngleU = other.phaseAngleU;
99 phaseAngleI = other.phaseAngleI;
100 phaseAngleUI = other.phaseAngleUI;
101 thdU = other.thdU;
102 thdI = other.thdI;
103}
104
105#ifdef MYCILA_JSON_SUPPORT
106void Mycila::JSY::Metrics::toJson(const JsonObject& root) const {
107 if (!std::isnan(frequency))
108 root["frequency"] = frequency;
109 if (!std::isnan(voltage))
110 root["voltage"] = voltage;
111 if (!std::isnan(current))
112 root["current"] = current;
113 if (!std::isnan(activePower))
114 root["active_power"] = activePower;
115 if (!std::isnan(reactivePower))
116 root["reactive_power"] = reactivePower;
117 if (!std::isnan(apparentPower))
118 root["apparent_power"] = apparentPower;
119 if (!std::isnan(powerFactor))
120 root["power_factor"] = powerFactor;
121 if (activeEnergy)
122 root["active_energy"] = activeEnergy;
123 if (apparentEnergy)
124 root["apparent_energy"] = apparentEnergy;
125 if (activeEnergyImported)
126 root["active_energy_imported"] = activeEnergyImported;
127 if (activeEnergyReturned)
128 root["active_energy_returned"] = activeEnergyReturned;
129 if (reactiveEnergy)
130 root["reactive_energy"] = reactiveEnergy;
131 if (reactiveEnergyImported)
132 root["reactive_energy_imported"] = reactiveEnergyImported;
133 if (reactiveEnergyReturned)
134 root["reactive_energy_returned"] = reactiveEnergyReturned;
135 if (!std::isnan(phaseAngleU))
136 root["phase_angle_u"] = phaseAngleU;
137 if (!std::isnan(phaseAngleI))
138 root["phase_angle_i"] = phaseAngleI;
139 if (!std::isnan(phaseAngleUI))
140 root["phase_angle_ui"] = phaseAngleUI;
141 if (!std::isnan(thdU))
142 root["thd_u"] = thdU;
143 if (!std::isnan(thdI))
144 root["thd_i"] = thdI;
145 float r = resistance();
146 float d = dimmedVoltage();
147 float n = nominalPower();
148 float t = thdi();
149 if (!std::isnan(r))
150 root["resistance"] = r;
151 if (!std::isnan(d))
152 root["dimmed_voltage"] = d;
153 if (!std::isnan(n))
154 root["nominal_power"] = n;
155 if (!std::isnan(t))
156 root["thdi_0"] = t;
157}
158#endif
float resistance() const
Compute the resistance of the load in ohms (R = P / I^2).
float apparentPower
Apparent power in volt-amperes (VA). Always positive.
Definition MycilaJSY.h:159
float powerFactor
Power factor. Positive value between 0 and 1.
Definition MycilaJSY.h:152
float thdi(float phi=0) const
Compute the total harmonic distortion percentage of current (THDi). This assumes THDu = 0 (perfect vo...
float nominalPower() const
Compute the nominal power of the load in watts (P = V^2 / R).
uint32_t reactiveEnergy
Reactive energy in volt-amperes reactive-hours (VArh).
Definition MycilaJSY.h:193
float activePower
Active power in watts (W). Can be positive or negative.
Definition MycilaJSY.h:146
uint32_t activeEnergyImported
Active energy imported in watt-hours (Wh), going to the load, when activePower > 0.
Definition MycilaJSY.h:180
float current
Current in amperes (A).
Definition MycilaJSY.h:140
uint32_t activeEnergy
Active energy in watt-hours (Wh).
Definition MycilaJSY.h:173
uint32_t activeEnergyReturned
Active energy returned in watt-hours (Wh), coming from the load, when activePower < 0.
Definition MycilaJSY.h:187
float voltage
Voltage in volts (V).
Definition MycilaJSY.h:134
uint32_t reactiveEnergyReturned
Reactive energy returned in volt-amperes reactive-hours (VArh), coming from the load,...
Definition MycilaJSY.h:207
uint32_t reactiveEnergyImported
Reactive energy imported in volt-amperes reactive-hours (VArh), going to the load,...
Definition MycilaJSY.h:200
float dimmedVoltage() const
Compute the dimmed voltage (V = P / I).
float frequency
Frequency in hertz (Hz).
Definition MycilaJSY.h:128
uint32_t apparentEnergy
Apparent energy in volt-amperes-hours (VAh).
Definition MycilaJSY.h:213