HAN-FUN API  1.5.3
This project provides the common implementation of ULE Alliance's HAN-FUN application protocol.
simple_power_meter.h
Go to the documentation of this file.
1 // =============================================================================
15 // =============================================================================
16 #ifndef HF_ITF_SIMPLE_POWER_METER_H
17 #define HF_ITF_SIMPLE_POWER_METER_H
18 
19 #include "hanfun/common.h"
20 
21 #include "hanfun/protocol.h"
22 #include "hanfun/interface.h"
23 
24 // =============================================================================
25 // Configuration
26 // =============================================================================
27 
28 #if HF_ITF_SPM_REPORT_CMD
29 
30  #if !HF_ITF_SPM_REPORT_INTERVAL_ATTR
31  #define HF_ITF_SPM_REPORT_INTERVAL_ATTR 1
32  #endif
33 
34 #endif
35 
36 #if HF_ITF_SPM_RESET_CMD
37 
38  #if !HF_ITF_SPM_ENERGY_ATTR
39  #undef HF_ITF_SPM_ENERGY_ATTR
40  #define HF_ITF_SPM_ENERGY_ATTR 1
41  #endif
42 
43  #if !HF_ITF_SPM_ENERGY_AT_RESET_ATTR
44  #undef HF_ITF_SPM_ENERGY_AT_RESET_ATTR
45  #define HF_ITF_SPM_ENERGY_AT_RESET_ATTR 1
46  #endif
47 
48  #if !HF_ITF_SPM_TIME_AT_RESET_ATTR
49  #undef HF_ITF_SPM_TIME_AT_RESET_ATTR
50  #define HF_ITF_SPM_TIME_AT_RESET_ATTR 1
51  #endif
52 
53 #endif
54 
55 // =============================================================================
56 // Define
57 // =============================================================================
58 
60 #define ATTR_SETTER(__type, __arg, __uid) \
61  { \
62  __type old = __arg; \
63  \
64  __arg = value; \
65  \
66  HF::Attributes::Attribute<__type> *old_attr = \
67  static_cast<HF::Attributes::Attribute<__type> *>(create_attribute(__uid)); \
68  old_attr->set(old); \
69  \
70  HF::Attributes::Attribute<__type> *new_attr = \
71  static_cast<HF::Attributes::Attribute<__type> *>(attribute(__uid)); \
72  \
73  notify(*old_attr, *new_attr); \
74  \
75  delete old_attr; \
76  delete new_attr; \
77  }
78 
79 // =============================================================================
80 // API
81 // =============================================================================
82 
83 namespace HF
84 {
85  namespace Interfaces
86  {
87  // Forward declaration
88  namespace SimplePowerMeter
89  {
90  class Server;
91  }
92 
108  uint8_t uid);
109 
113  namespace SimplePowerMeter
114  {
123  typedef enum _CMD
125  {
126  REPORT_CMD = 0x01,
128  } CMD;
129 
133  typedef enum _Attributes
134  {
135  ENERGY_ATTR = 0x01,
138  POWER_ATTR = 0x04,
139  AVG_POWER_ATTR = 0x05,
141  VOLTAGE_ATTR = 0x07,
142  CURRENT_ATTR = 0x08,
143  FREQUENCY_ATTR = 0x09,
146  __LAST_ATTR__ = REPORT_INTERVAL_ATTR,
147  } Attributes;
148 
152  struct Measurement
153  {
155  static constexpr uint16_t min_size = sizeof(uint8_t) // Precision size.
156  + sizeof(uint32_t); // Value size.
157 
158  uint8_t unit;
159  uint32_t value;
160 
162  uint16_t size() const
163  {
164  return min_size;
165  }
166 
168  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const
169  {
170  HF_SERIALIZABLE_CHECK(array, offset, min_size);
171 
172  offset += array.write(offset, static_cast<uint8_t>(unit));
173  array.write(offset, value);
174 
175  return min_size;
176  }
177 
179  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0)
180  {
181  HF_SERIALIZABLE_CHECK(array, offset, min_size);
182 
183  uint8_t temp;
184  offset += array.read(offset, temp);
185 
186  unit = static_cast<Common::Precision>(temp);
187 
188  offset += array.read(offset, value);
189 
190  return min_size;
191  }
192 
198  int compare(const Measurement &other) const
199  {
200  int res = value - other.value;
201 
202  return res;
203  }
204 
210  float changed(const Measurement &other) const
211  {
212  return (((float) (value - other.value)) / other.value);
213  }
214  };
215 
222  struct Report
223  {
225 
228 
231 
233 
234  uint8_t power_factor;
235 
239 
244  std::array<bool, __LAST_ATTR__ + 1> enabled;
245 
246  Report();
247 
249  static constexpr uint16_t min_size = sizeof(uint8_t); // Number of attributes.
250 
252  uint16_t size() const;
253 
255  uint16_t pack(Common::ByteArray &array, uint16_t offset = 0) const;
256 
258  uint16_t unpack(const Common::ByteArray &array, uint16_t offset = 0);
259  };
260 
272 
278  struct Base: public Interface<HF::Interface::SIMPLE_POWER_METER>
279  {
280  protected:
281 
282  Base() {}
283 
285 
287  {
288  UNUSED(itf);
289  return payload_size_helper<Report>();
290  }
291  };
292 
300  class Server: public InterfaceRole<SimplePowerMeter::Base, HF::Interface::SERVER_ROLE>
301  {
302  protected:
303 
304  /* Attributes */
305 #if HF_ITF_SPM_ENERGY_ATTR
306  Measurement _energy;
307 #endif
308 
309 #if HF_ITF_SPM_ENERGY_AT_RESET_ATTR
310  Measurement _last_energy;
311 #endif
312 
313 #if HF_ITF_SPM_TIME_AT_RESET_ATTR
314  Measurement _last_time;
315 #endif
316 
317 #if HF_ITF_SPM_POWER_ATTR
318  Measurement _power;
319 #endif
320 
321 #if HF_ITF_SPM_AVG_POWER_ATTR
322  Measurement _avg_power;
323 #endif
324 
325 #if HF_ITF_SPM_AVG_POWER_INTERVAL_ATTR
326  uint16_t _avg_power_interval;
327 #endif
328 
329 #if HF_ITF_SPM_POWER_FACTOR_ATTR
330  uint8_t _power_factor;
331 #endif
332 
333 #if HF_ITF_SPM_VOLTAGE_ATTR
334  Measurement _voltage;
335 #endif
336 
337 #if HF_ITF_SPM_CURRENT_ATTR
338  Measurement _current;
339 #endif
340 
341 #if HF_ITF_SPM_FREQUENCY_ATTR
342  Measurement _frequency;
343 #endif
344 
345 #if HF_ITF_SPM_REPORT_CMD
346  uint16_t _report_interval;
347 
348  uint32_t _last_periodic;
349 #endif
350 
351  public:
352 
354  Server();
355 
356  // =============================================================================
357  // API
358  // =============================================================================
359 
360  void periodic(uint32_t time);
361 
362  // ======================================================================
363  // Getters & Setters
364  // ======================================================================
367 
368 #if HF_ITF_SPM_ENERGY_ATTR
369 
374  Measurement energy()
375  {
376  return _energy;
377  }
378 
384  void energy(Measurement &value)
385  {
387  }
388 #endif
389 
390 #if HF_ITF_SPM_ENERGY_AT_RESET_ATTR
391 
396  Measurement last_energy()
397  {
398  return _last_energy;
399  }
400 
406  void last_energy(Measurement &value)
407  {
409  }
410 #endif
411 
412 #if HF_ITF_SPM_TIME_AT_RESET_ATTR
413 
418  Measurement last_time()
419  {
420  return _last_time;
421  }
422 
428  void last_time(Measurement &value)
429  {
431  }
432 #endif
433 
434 #if HF_ITF_SPM_POWER_ATTR
435 
440  Measurement power()
441  {
442  return _power;
443  }
444 
450  void power(Measurement &value)
451  {
453  }
454 #endif
455 
456 #if HF_ITF_SPM_AVG_POWER_ATTR
457 
462  Measurement avg_power()
463  {
464  return _avg_power;
465  }
466 
472  void avg_power(Measurement &value)
473  {
474  ATTR_SETTER(Measurement, _avg_power, AVG_POWER_ATTR);
475  }
476 #endif
477 
478 #if HF_ITF_SPM_AVG_POWER_INTERVAL_ATTR
479 
484  uint16_t avg_power_interval()
485  {
486  return _avg_power_interval;
487  }
488 
494  void avg_power_interval(uint16_t value)
495  {
496  ATTR_SETTER(uint16_t, _avg_power_interval, AVG_POWER_INTERVAL_ATTR);
497  }
498 #endif
499 
500 #if HF_ITF_SPM_POWER_FACTOR_ATTR
501 
506  uint8_t power_factor()
507  {
508  return _power_factor;
509  }
510 
516  void power_factor(uint8_t value)
517  {
518  ATTR_SETTER(uint8_t, _power_factor, POWER_FACTOR_ATTR);
519  }
520 #endif
521 
522 #if HF_ITF_SPM_VOLTAGE_ATTR
523 
528  Measurement voltage()
529  {
530  return _voltage;
531  }
532 
538  void voltage(Measurement &value)
539  {
541  }
542 #endif
543 
544 #if HF_ITF_SPM_CURRENT_ATTR
545 
550  Measurement current()
551  {
552  return _current;
553  }
554 
560  void current(Measurement &value)
561  {
563  }
564 #endif
565 
566 #if HF_ITF_SPM_FREQUENCY_ATTR
567 
572  Measurement frequency()
573  {
574  return _frequency;
575  }
576 
582  void frequency(Measurement &value)
583  {
584  ATTR_SETTER(Measurement, _frequency, FREQUENCY_ATTR);
585  }
586 #endif
587 
588 #if HF_ITF_SPM_REPORT_CMD
589 
594  uint16_t report_interval()
595  {
596  return _report_interval;
597  }
598 
604  void report_interval(uint16_t value)
605  {
606  ATTR_SETTER(uint16_t, _report_interval, REPORT_INTERVAL_ATTR);
607  }
608 #endif
609 
611 
612  // =============================================================================
613  // Attribute API
614  // =============================================================================
615 
617 
618  HF::Attributes::UIDS attributes(uint8_t pack_id =
620 
621  protected:
622 
628  virtual Report *report();
629  };
630 
638  struct Client: public InterfaceRole<SimplePowerMeter::Base, HF::Interface::CLIENT_ROLE>
639  {
640  // ======================================================================
641  // Events
642  // ======================================================================
645 
652  virtual void report(Protocol::Address &source, Report &report)
653  {
654  UNUSED(source);
655  UNUSED(report);
656  }
657 
659  // =============================================================================
660 
661  protected:
662 
664  uint16_t offset);
665  };
666 
669  } // namespace SimplePowerMeter
670 
671  } // namespace Interfaces
672 
673 } // namespace HF
674 
680 // =============================================================================
681 // Stream Helpers
682 // =============================================================================
683 
692 std::ostream &operator<<(std::ostream &stream, const HF::Interfaces::SimplePowerMeter::CMD command);
693 
702 std::ostream &operator<<(std::ostream &stream,
704 
707 #endif /* HF_ITF_SIMPLE_POWER_METER */
HF::Attributes::IAttribute * attribute(uint8_t uid)
Return a pointer to the interface attribute with the given uid.
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
uint16_t write(uint16_t offset, uint8_t data)
Write a byte into the array at the given offset.
Simple Power Meter Interface : Server side implementation.
void periodic(uint32_t time)
Handle periodic processing.
Measurement voltage
Voltage measurement.
List of attributes UIDs.
Definition: attributes.h:176
Simple Power Meter Interface : Parent.
Instantaneous Power Attribute ID.
Return all mandatory attributes for the interface.
Definition: attributes.h:842
This file contains the common defines for the HAN-FUN library.
Measurement avg_power
Average Power measurement.
Common::Result handle_command(Protocol::Packet &packet, Common::ByteArray &payload, uint16_t offset)
Handle incoming messages from the network.
Helper class template for parent class implementation of the interfaces.
Definition: interface.h:371
This file contains the definitions for the HAN-FUN protocol messages.
uint8_t unit
Measurement precision/type.
int compare(const Measurement &other) const
Compare this attribute with the given attribute in other.
#define HF_SERIALIZABLE_CHECK(__array, __offset, __size)
Helper macro to check if the given __array has enough size so __size bytes can be written/read from t...
Precision
These constants represent precisions that a measurement can be in.
This file contains the definitions common to all interfaces.
This represents a measurement for a given attribute.
virtual Report * report()
Create a report message.
uint16_t size() const
Number bytes needed to serialize the message.
This class represents a byte array.
HF::Attributes::IAttribute * create_attribute(uint8_t uid)
Create an attribute object that can hold the attribute with the given uid. (HF::Interfaces::SimplePow...
uint16_t unpack(const Common::ByteArray &array, uint16_t offset=0)
Read a message from a ByteArray.
virtual void report(Protocol::Address &source, Report &report)
Receive a report message from a server.
Simple Power Meter Interface : Client side implementation.
Network Address.
Definition: protocol.h:201
uint16_t uid() const
This method returns the interface UID.
Definition: interface.h:374
Interface Address.
Definition: protocol.h:93
std::ostream & operator<<(std::ostream &stream, const HF::Interfaces::SimplePowerMeter::CMD command)
Convert the given command into a string and write it to the given stream.
Measurement energy
Energy measurement.
float changed(const Measurement &other) const
This method is used to get the percentage of change that the attribute has in relation to the value p...
uint16_t pack(Common::ByteArray &array, uint16_t offset=0) const
Write the object on to a ByteArray so it can be sent over the network.
HAN-FUN Protocol Packet.
Definition: protocol.h:298
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
static constexpr uint16_t min_size
Minimum pack/unpack required data size.
HF::Attributes::IAttribute * create_attribute(HF::Interfaces::Alert::Server *server, uint8_t uid)
Create an attribute object that can hold the attribute with the given uid.
Interface/Service Attribute API.
Definition: attributes.h:44
HF::Attributes::UIDS attributes(uint8_t pack_id=HF::Attributes::Pack::MANDATORY) const
Return a vector containing the attribute UIDs, for the given pack ID.
uint16_t read(uint16_t offset, uint8_t &data) const
Read the byte at offset into data.
Measurement current
Current measurement.
Helper class template for implementing a given interface role.
Definition: interface.h:394
#define UNUSED(x)
Helper macro to remove warning about unused function/method argument.
uint16_t pack(Common::ByteArray &array, uint16_t offset=0) const
Write the object on to a ByteArray so it can be sent over the network.
uint16_t avg_power_interval
Average Power Interval.
Measurement power
Instantaneous Power measurement.
uint16_t size() const
Number bytes needed to serialize the message.
Measurement last_energy
Energy measurement at last reset.
Measurement frequency
Frequency measurement.
Measurement last_time
Device time measurement at last reset.
#define ATTR_SETTER(__type, __arg, __uid)
Helper macro used to support attribute reporting.
Result
Commands result codes.
uint16_t payload_size(Protocol::Message::Interface &itf) const
Return the minimal payload size that a message should hold when addressed at the given interface...
std::array< bool, __LAST_ATTR__+1 > enabled
This array contains an indication of with attributes should be packed or were unpacked.
Top-level namespace for the HAN-FUN library.
Definition: attributes.h:22