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