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.

123 lines
2.9 KiB

  1. /*
  2. EMON MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if ENABLE_EMON
  6. #include <EmonLiteESP.h>
  7. EmonLiteESP emon;
  8. double current;
  9. char power[8];
  10. // -----------------------------------------------------------------------------
  11. // EMON
  12. // -----------------------------------------------------------------------------
  13. void setCurrentRatio(float value) {
  14. emon.setCurrentRatio(value);
  15. }
  16. char * getPower() {
  17. return power;
  18. }
  19. double getCurrent() {
  20. return current;
  21. }
  22. unsigned int currentCallback() {
  23. return analogRead(EMON_CURRENT_PIN);
  24. }
  25. void powerMonitorSetup() {
  26. // backwards compatibility
  27. String tmp;
  28. tmp = getSetting("pwMainsVoltage", EMON_MAINS_VOLTAGE);
  29. setSetting("emonMains", tmp);
  30. delSetting("pwMainsVoltage");
  31. tmp = getSetting("pwCurrentRatio", EMON_CURRENT_RATIO);
  32. setSetting("emonRatio", tmp);
  33. delSetting("pwCurrentRatio");
  34. emon.initCurrent(
  35. currentCallback,
  36. EMON_ADC_BITS,
  37. EMON_REFERENCE_VOLTAGE,
  38. getSetting("emonRatio", EMON_CURRENT_RATIO).toFloat()
  39. );
  40. emon.setPrecision(EMON_CURRENT_PRECISION);
  41. apiRegister("/api/power", "power", getPower);
  42. }
  43. void powerMonitorLoop() {
  44. static unsigned long next_measurement = millis();
  45. static bool warmup = true;
  46. static byte measurements = 0;
  47. static double max = 0;
  48. static double min = 0;
  49. static double sum = 0;
  50. if (!mqttConnected()) return;
  51. if (warmup) {
  52. warmup = false;
  53. emon.warmup();
  54. }
  55. if (millis() > next_measurement) {
  56. // Safety check: do not read current if relay is OFF
  57. if (!relayStatus(0)) {
  58. current = 0;
  59. } else {
  60. current = emon.getCurrent(EMON_SAMPLES);
  61. current -= EMON_CURRENT_OFFSET;
  62. if (current < 0) current = 0;
  63. }
  64. if (measurements == 0) {
  65. max = min = current;
  66. } else {
  67. if (current > max) max = current;
  68. if (current < min) min = current;
  69. }
  70. sum += current;
  71. ++measurements;
  72. float mainsVoltage = getSetting("emonMains", EMON_MAINS_VOLTAGE).toFloat();
  73. //DEBUG_MSG("[ENERGY] Power now: %dW\n", int(current * mainsVoltage));
  74. // Update websocket clients
  75. char text[20];
  76. sprintf_P(text, PSTR("{\"emonPower\": %d}"), int(current * mainsVoltage));
  77. wsSend(text);
  78. // Send MQTT messages averaged every EMON_MEASUREMENTS
  79. if (measurements == EMON_MEASUREMENTS) {
  80. double p = (sum - max - min) * mainsVoltage / (measurements - 2);
  81. sprintf(power, "%d", int(p));
  82. mqttSend(getSetting("emonPowerTopic", EMON_POWER_TOPIC).c_str(), power);
  83. #if ENABLE_DOMOTICZ
  84. domoticzSend("dczPowIdx", power);
  85. #endif
  86. sum = 0;
  87. measurements = 0;
  88. }
  89. next_measurement += EMON_INTERVAL;
  90. }
  91. }
  92. #endif