Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
3.8 KiB

  1. /*
  2. SENSOR MODULE
  3. Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. Copyright (C) 2020 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
  5. */
  6. #pragma once
  7. #include "espurna.h"
  8. //--------------------------------------------------------------------------------
  9. namespace sensor {
  10. namespace type {
  11. enum Type : unsigned char {
  12. Base = 0,
  13. Emon = 1 << 0,
  14. Analog = 1 << 1
  15. };
  16. } // namespace type
  17. enum class Unit : int {
  18. Min_,
  19. None,
  20. Celcius,
  21. Farenheit,
  22. Kelvin,
  23. Percentage,
  24. Hectopascal,
  25. Ampere,
  26. Volt,
  27. Voltampere,
  28. Kilovoltampere,
  29. VoltampereReactive,
  30. KilovoltampereReactive,
  31. Watt,
  32. Kilowatt,
  33. WattSecond,
  34. Joule = WattSecond,
  35. KilowattHour,
  36. PartsPerMillion,
  37. Ohm,
  38. MicrogrammPerCubicMeter, // The concentration of an air pollutant
  39. MilligrammPerCubicMeter, //
  40. Lux,
  41. UltravioletIndex, // "measurement of the strength of sunburn-producing ultraviolet (UV) radiation at a particular place and time"
  42. // (XXX: Not a unit. Distinguish from None and specify decimals)
  43. CountsPerMinute, // Unit of local dose rate (Geiger counting)
  44. MicrosievertPerHour, // 2nd unit of local dose rate (Geiger counting)
  45. Meter,
  46. Hertz,
  47. Ph,
  48. Max_
  49. };
  50. // Base units are 32 bit since we are the fastest with them.
  51. struct Ws {
  52. Ws();
  53. Ws(uint32_t);
  54. uint32_t value;
  55. };
  56. struct Wh {
  57. Wh();
  58. Wh(Ws);
  59. Wh(uint32_t);
  60. uint32_t value;
  61. };
  62. struct KWh {
  63. KWh();
  64. KWh(Ws);
  65. KWh(Wh);
  66. KWh(uint32_t);
  67. uint32_t value;
  68. };
  69. struct Energy {
  70. constexpr static uint32_t KwhMultiplier = 3600000ul;
  71. constexpr static uint32_t KwhLimit = ((1ul << 31ul) / KwhMultiplier);
  72. Energy() = default;
  73. // TODO: while we accept ws >= the kwh conversion limit,
  74. // should this be dealt with on the unit level?
  75. Energy(double);
  76. Energy(KWh, Ws);
  77. Energy(KWh);
  78. Energy(Wh);
  79. Energy(Ws);
  80. // Sets internal counters to zero
  81. void reset();
  82. // Check whether we have *any* energy recorded. Can be zero:
  83. // - on cold boot
  84. // - on overflow
  85. // - when we call `reset()`
  86. operator bool();
  87. // Generic conversion as-is
  88. double asDouble();
  89. // Convert back to input unit, with overflow mechanics when kwh values goes over 32 bit
  90. Ws asWs();
  91. // Generic sensors output energy in joules / watt-second
  92. Energy& operator +=(Ws);
  93. Energy operator +(Ws);
  94. // But sometimes we want to accept asDouble() value back
  95. Energy& operator =(double);
  96. // We are storing a kind-of integral and fractional parts
  97. // Using watt-second to avoid loosing precision, we don't expect these to be accessed directly
  98. KWh kwh;
  99. Ws ws;
  100. };
  101. struct Value {
  102. double get();
  103. double last;
  104. double reported;
  105. unsigned char decimals;
  106. };
  107. }
  108. using MagnitudeReadHandler = void(*)(const String&, unsigned char, double, const char*);
  109. void sensorSetMagnitudeRead(MagnitudeReadHandler handler);
  110. void sensorSetMagnitudeReport(MagnitudeReadHandler handler);
  111. String magnitudeUnits(unsigned char index);
  112. String magnitudeDescription(unsigned char index);
  113. unsigned char magnitudeType(unsigned char index);
  114. unsigned char magnitudeIndex(unsigned char index);
  115. String magnitudeTopicIndex(unsigned char index);
  116. unsigned char magnitudeCount();
  117. sensor::Value magnitudeValue(unsigned char index);
  118. void magnitudeFormat(const sensor::Value& value, char* output, size_t size);
  119. // XXX: without param name it is kind of vague what exactly unsigned char is
  120. // consider adding stronger param type e.g. enum class
  121. String magnitudeTopic(unsigned char type);
  122. String magnitudeName(unsigned char type);
  123. String sensorError(unsigned char error);
  124. void sensorWebSocketMagnitudes(JsonObject& root, const String& prefix);
  125. unsigned char sensorCount();
  126. void sensorSetup();
  127. void sensorLoop();