supla-device
Loading...
Searching...
No Matches
electricity_meter.h
1// SPDX-FileCopyrightText: AC SOFTWARE SP. Z O.O.
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#ifndef SRC_SUPLA_SENSOR_ELECTRICITY_METER_H_
5#define SRC_SUPLA_SENSOR_ELECTRICITY_METER_H_
6
7#include <supla-common/srpc.h>
8#include <supla/action_handler.h>
9#include <supla/element_with_channel_actions.h>
10
11#include "../channel_extended.h"
12#include "../local_action.h"
13
14#define MAX_PHASES 3
15
16namespace Supla {
17namespace Sensor {
18
19#pragma pack(push, 1)
21 union {
22 _supla_int64_t totalFwdActEnergy = 0;
23 _supla_int64_t fwdActEnergy;
24 };
25 union {
26 _supla_int64_t totalRvrActEnergy = 0;
27 _supla_int64_t rvrActEnergy;
28 };
29 union {
30 _supla_int64_t totalFwdReactEnergy = 0;
31 _supla_int64_t fwdReactEnergy;
32 };
33 union {
34 _supla_int64_t totalRvrReactEnergy = 0;
35 _supla_int64_t rvrReactEnergy;
36 };
37};
38
40 _supla_int64_t fwdActEnergyBalanced = 0;
41 _supla_int64_t rvrActEnergyBalanced = 0;
42};
43#pragma pack(pop)
44
45#define EM_VAR_ALL_ENERGY_REGISTERS \
46 (EM_VAR_FORWARD_ACTIVE_ENERGY | EM_VAR_REVERSE_ACTIVE_ENERGY | \
47 EM_VAR_FORWARD_REACTIVE_ENERGY | EM_VAR_REVERSE_REACTIVE_ENERGY | \
48 EM_VAR_FORWARD_ACTIVE_ENERGY_BALANCED | \
49 EM_VAR_REVERSE_ACTIVE_ENERGY_BALANCED)
50
52 public ActionHandler {
53 public:
55
56 virtual void updateChannelValues();
57
58 // energy in 0.00001 kWh
59 void setFwdActEnergy(int phase, unsigned _supla_int64_t energy);
60
61 // energy in 0.00001 kWh
62 void setRvrActEnergy(int phase, unsigned _supla_int64_t energy);
63
64 // energy in 0.00001 kWh
65 void setFwdReactEnergy(int phase, unsigned _supla_int64_t energy);
66
67 // energy in 0.00001 kWh
68 void setRvrReactEnergy(int phase, unsigned _supla_int64_t energy);
69
70 // Vector balanced forward energy
71 // energy in 0.00001 kWh
72 void setFwdBalancedEnergy(uint64_t energy);
73
74 // Vector balanced reverse energy
75 // energy in 0.00001 kWh
76 void setRvrBalancedEnergy(uint64_t energy);
77
78 // voltage in 0.01 V
79 void setVoltage(int phase, unsigned _supla_int16_t voltage);
80
81 // current in 0.001 A
82 void setCurrent(int phase, unsigned _supla_int_t current);
83
84 // Frequency in 0.01 Hz
85 void setFreq(unsigned _supla_int16_t freq);
86
87 // power in 0.00001 W
88 void setPowerActive(int phase, int64_t power);
89
90 // power in 0.00001 var
91 void setPowerReactive(int phase, int64_t power);
92
93 // power in 0.00001 VA
94 void setPowerApparent(int phase, int64_t power);
95
96 // power in 0.001
97 void setPowerFactor(int phase, _supla_int_t powerFactor);
98
99 // phase angle in 0.1 degree
100 void setPhaseAngle(int phase, _supla_int_t phaseAngle);
101
102 // voltage phase angle between phase 1 and 2
103 void setVoltagePhaseAngle12(unsigned _supla_int16_t voltagePhaseAngle);
104
105 // voltage phase angle between phase 1 and 3
106 void setVoltagePhaseAngle13(unsigned _supla_int16_t voltagePhaseAngle);
107
108 // sets voltage phase sequence to clockwise or counterclockwise
109 void setVoltagePhaseSequence(bool clockwise);
110
111 // sets current phase sequence to clockwise or counterclockwise
112 void setCurrentPhaseSequence(bool clockwise);
113
119
125
126 // energy 1 == 0.00001 kWh
127 unsigned _supla_int64_t getFwdActEnergy(int phase);
128
129 // energy 1 == 0.00001 kWh
130 unsigned _supla_int64_t getRvrActEnergy(int phase);
131
132 // energy 1 == 0.00001 kWh
133 uint64_t getFwdBalancedActEnergy();
134
135 // energy 1 == 0.00001 kWh
136 uint64_t getRvrBalancedActEnergy();
137
138 // energy 1 == 0.00001 kWh
139 unsigned _supla_int64_t getFwdReactEnergy(int phase);
140
141 // energy 1 == 0.00001 kWh
142 unsigned _supla_int64_t getRvrReactEnergy(int phase);
143
144 // voltage 1 == 0.01 V
145 unsigned _supla_int16_t getVoltage(int phase);
146
147 // current 1 == 0.001 A
148 unsigned _supla_int_t getCurrent(int phase);
149
150 // Frequency 1 == 0.01 Hz
151 unsigned _supla_int16_t getFreq();
152
153 // power 1 == 0.00001 W
154 int64_t getPowerActive(int phase);
155
156 // power 1 == 0.00001 var
157 int64_t getPowerReactive(int phase);
158
159 // power 1 == 0.00001 VA
160 int64_t getPowerApparent(int phase);
161
162 // power 1 == 0.001
163 _supla_int_t getPowerFactor(int phase);
164
165 // phase angle 1 == 0.1 degree
166 _supla_int_t getPhaseAngle(int phase);
167
168 // Phase angle between voltage phase 1 and 2 in 0.1 degree, 0..360
169 uint16_t getVoltagePhaseAngle12() const;
170
171 // Phase angle between voltage phase 1 and 3 in 0.1 degree, 0..360
172 uint16_t getVoltagePhaseAngle13() const;
173
174 // Returns true when voltage phase sequence is set
175 bool isVoltagePhaseSequenceSet() const;
176
177 // Voltage phase sequence clockwise or counterclockwise
178 bool isVoltagePhaseSequenceClockwise() const;
179
180 // Returns true when current phase sequence is set
181 bool isCurrentPhaseSequenceSet() const;
182
183 // Current phase sequence clockwise or counterclockwise
184 bool isCurrentPhaseSequenceClockwise() const;
185
186 // energy 1 == 0.00001 kWh
187 static unsigned _supla_int64_t
188 getFwdActEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue,
189 int phase);
190
191 // energy 1 == 0.00001 kWh
192 static unsigned _supla_int64_t
193 getTotalFwdActEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue);
194
195 // energy 1 == 0.00001 kWh
196 static uint64_t
197 getFwdBalancedActEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue);
198
199 // energy 1 == 0.00001 kWh
200 static unsigned _supla_int64_t
201 getRvrActEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue,
202 int phase);
203
204 // energy 1 == 0.00001 kWh
205 static unsigned _supla_int64_t
206 getTotalRvrActEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue);
207
208 // energy 1 == 0.00001 kWh
209 static uint64_t
210 getRvrBalancedActEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue);
211
212 // energy 1 == 0.00001 kWh
213 static unsigned _supla_int64_t
214 getFwdReactEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue,
215 int phase);
216
217 // energy 1 == 0.00001 kWh
218 static unsigned _supla_int64_t
219 getRvrReactEnergy(const TElectricityMeter_ExtendedValue_V3 &emValue,
220 int phase);
221
222 // voltage 1 == 0.01 V
223 static unsigned _supla_int16_t
224 getVoltage(const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
225
226 // current 1 == 0.001 A
227 static unsigned _supla_int_t
228 getCurrent(const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
229
230 // Frequency 1 == 0.01 Hz
231 static unsigned _supla_int16_t
232 getFreq(const TElectricityMeter_ExtendedValue_V3 &emValue);
233
234 // power 1 == 0.00001 W
235 static int64_t getPowerActive(
236 const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
237
238 // power 1 == 0.00001 var
239 static int64_t getPowerReactive(
240 const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
241
242 // power 1 == 0.00001 VA
243 static int64_t getPowerApparent(
244 const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
245
246 // power 1 == 0.001
247 static _supla_int_t getPowerFactor(
248 const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
249
250 // phase angle 1 == 0.1 degree
251 static _supla_int_t getPhaseAngle(
252 const TElectricityMeter_ExtendedValue_V3 &emValue, int phase);
253
254 // Phase angle between voltage phase 1 and 2 in 0.1 degree, 0..360
255 static uint16_t getVoltagePhaseAngle12(
257
258 // Phase angle between voltage phase 1 and 3 in 0.1 degree, 0..360
259 static uint16_t getVoltagePhaseAngle13(
261
262 // Returns true when voltage phase sequence is set
263 static bool isVoltagePhaseSequenceSet(
265
266 // Voltage phase sequence clockwise or counterclockwise
267 static bool isVoltagePhaseSequenceClockwise(
269
270 // Returns true when current phase sequence is set
271 static bool isCurrentPhaseSequenceSet(
273
274 // Current phase sequence clockwise or counterclockwise
275 static bool isCurrentPhaseSequenceClockwise(
277
278 static bool isVoltagePhaseAngle12Used(
280
281 static bool isVoltagePhaseAngle13Used(
283
284 static bool isFwdActEnergyUsed(
286
287 static bool isRvrActEnergyUsed(
289
290 static bool isFwdReactEnergyUsed(
292
293 static bool isRvrReactEnergyUsed(
295
296 static bool isFwdBalancedActEnergyUsed(
298
299 static bool isRvrBalancedActEnergyUsed(
301
302 static bool isVoltageUsed(
304
305 static bool isCurrentUsed(
307
308 static bool isFreqUsed(
310
311 static bool isPowerActiveUsed(
313
314 static bool isPowerReactiveUsed(
316
317 static bool isPowerApparentUsed(
319
320 static bool isPowerFactorUsed(
322
323 static bool isPhaseAngleUsed(
325
326 void resetReadParameters();
327 void resetReadParametersForPhase(int phase);
328
329 // Please implement this class for reading value from elecricity meter device.
330 // It will be called every 5 s. Use set methods defined above in order to
331 // set values on channel. Don't use any other method to modify channel values.
332 virtual void readValuesFromDevice();
333
334 void onRegistered(Supla::Protocol::SuplaSrpc *suplaSrpc) override;
335 void onLoadConfig(SuplaDeviceClass *sdc) override;
336 Supla::ApplyConfigResult applyChannelConfig(TSD_ChannelConfig *config,
337 bool local) override;
338 void fillChannelConfig(void *channelConfig,
339 int *size,
340 uint8_t configType) override;
341
342 // Put here initialization code for electricity meter device.
343 // It will be called within SuplaDevce.begin method.
344 // It should also read first data set, so at the end it should call those two
345 // methods:
346 // readValuesFromDevice();
347 // updateChannelValues();
348 void onInit() override;
349
350 void iterateAlways() override;
351
352 // Implement this method to reset stored energy value (i.e. to set energy
353 // counter back to 0 kWh
354 virtual void resetStorage();
355
356 // default calcfg implementation allows to resetStorage remotely.
357 // If you override it please remember to implement this functionality
358 // or call this method from base classs.
359 int handleCalcfgFromServer(TSD_DeviceCalCfgRequest *request) override;
360
361 void handleAction(int event, int action) override;
362
363 void setRefreshRate(unsigned int sec);
364
365 void sendDataWithDelay(int delayMs = 0);
366
367 Channel *getChannel() override;
368 const Channel *getChannel() const override;
369 void purgeConfig() override;
370
371 void enableChannelConfig();
372 void addCtType(uint64_t ctType);
373 void addPhaseLedType(uint64_t ledType);
374 bool isCtTypeSupported(uint64_t ctType) const;
375
376 int8_t getPhaseLedType() const;
377 int32_t getLedVoltageLow() const;
378 int32_t getLedVoltageHigh() const;
379 int32_t getLedPowerLow() const;
380 int32_t getLedPowerHigh() const;
381 bool isPhaseLedTypeSupported(uint64_t ledType) const;
382
383 protected:
385 ChannelExtended extChannel;
386 uint32_t lastChannelUpdateTime = 0;
387 uint32_t rawCurrent[MAX_PHASES] = {};
388 int64_t rawActivePower[MAX_PHASES] = {};
389 int64_t rawReactivePower[MAX_PHASES] = {};
390 int64_t rawApparentPower[MAX_PHASES] = {};
391
392 uint32_t lastReadTime = 0;
393 uint16_t refreshRateSec = 5;
394 bool valueChanged = false;
395 bool currentMeasurementAvailable = false;
396 bool powerActiveMeasurementAvailable = false;
397 bool powerReactiveMeasurementAvailable = false;
398 bool powerApparentMeasurementAvailable = false;
399
400 uint64_t availableCtTypes = 0; // from proto EM_CT_TYPE_
401 uint64_t availablePhaseLedTypes = 0; // from proto EM_PHASE_LED_TYPE_
402 bool channelConfigUsed = false;
403 int8_t usedCtType = -1; // correspond with bit position of CT type
404 // Value -1 - default/not used
405 int8_t usedPhaseLedType = -1; // correspond with bit position of LED type
406 // Value -1 - default/not used
407 int32_t ledVoltageLow = 21000; // 210.00 V
408 int32_t ledVoltageHigh = 25000; // 250.00 V
409 int32_t ledPowerLow = -5000; // -50.00 W
410 int32_t ledPowerHigh = 5000; // 50.00 W
411};
412
413}; // namespace Sensor
414}; // namespace Supla
415
416#endif // SRC_SUPLA_SENSOR_ELECTRICITY_METER_H_
Definition SuplaDevice.h:167
Definition action_handler.h:8
Definition channel_extended.h:12
Definition channel.h:26
Definition element_with_channel_actions.h:66
Definition supla_srpc.h:47
Definition electricity_meter.h:52
void onLoadConfig(SuplaDeviceClass *sdc) override
First method called on element in SuplaDevice.begin().
Definition electricity_meter.cpp:424
int handleCalcfgFromServer(TSD_DeviceCalCfgRequest *request) override
Handles CALCFG requests from server.
Definition electricity_meter.cpp:899
void clearCurrentPhaseSequenceFlag()
Clears current phase sequence flag and value, so it won't be presented at all.
Definition electricity_meter.cpp:371
void iterateAlways() override
Method called on each SuplaDevice iteration.
Definition electricity_meter.cpp:731
void purgeConfig() override
Removes all configration data related to the element from Storage::Config.
Definition electricity_meter.cpp:1273
void onInit() override
Third method called on element in SuplaDevice.begin()
Definition electricity_meter.cpp:728
void clearVoltagePhaseSequenceFlag()
Clears voltage phase sequence flag and value, so it won't be presented at all.
Definition electricity_meter.cpp:362
void onRegistered(Supla::Protocol::SuplaSrpc *suplaSrpc) override
Method called each time when device successfully registers to Supla server.
Definition electricity_meter.cpp:1262
Definition electricity_meter.h:20
Definition electricity_meter.h:39
Definition proto.h:2014
Definition proto.h:3159
Definition proto.h:2315