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.

151 lines
4.1 KiB

  1. /*
  2. DS18B20 MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if DS18B20_SUPPORT
  6. #include <OneWire.h>
  7. #include <DallasTemperature.h>
  8. OneWire oneWire(DS18B20_PIN);
  9. DallasTemperature ds18b20(&oneWire);
  10. bool _dsIsConnected = false;
  11. double _dsTemperature = 0;
  12. char _dsTemperatureStr[6];
  13. // -----------------------------------------------------------------------------
  14. // Private
  15. // -----------------------------------------------------------------------------
  16. void _dsWebSocketOnSend(JsonObject& root) {
  17. root["dsVisible"] = 1;
  18. root["dsTmp"] = getDSTemperatureStr();
  19. }
  20. // -----------------------------------------------------------------------------
  21. // DS18B20
  22. // -----------------------------------------------------------------------------
  23. double getDSTemperature() {
  24. return _dsTemperature;
  25. }
  26. const char* getDSTemperatureStr() {
  27. if (!_dsIsConnected)
  28. return "NOT CONNECTED";
  29. return _dsTemperatureStr;
  30. }
  31. void dsSetup() {
  32. ds18b20.begin();
  33. ds18b20.setWaitForConversion(false);
  34. #if WEB_SUPPORT
  35. wsOnSendRegister(_dsWebSocketOnSend);
  36. apiRegister(DS18B20_TEMPERATURE_TOPIC, DS18B20_TEMPERATURE_TOPIC, [](char * buffer, size_t len) {
  37. dtostrf(_dsTemperature, 1-len, 1, buffer);
  38. });
  39. #endif
  40. }
  41. void dsLoop() {
  42. // Check if we should read new data
  43. static unsigned long last_update = 0;
  44. static bool requested = false;
  45. static double last_temperature = 0.0;
  46. bool send_update = false;
  47. if ((millis() - last_update > DS18B20_UPDATE_INTERVAL) || (last_update == 0)) {
  48. if (!requested) {
  49. ds18b20.requestTemperatures();
  50. requested = true;
  51. /* Requesting takes time,
  52. * so data will probably not be available in this round */
  53. return;
  54. }
  55. /* Check if requested data is already available */
  56. if (!ds18b20.isConversionComplete()) {
  57. return;
  58. }
  59. requested = false;
  60. last_update = millis();
  61. // Read sensor data
  62. unsigned char tmpUnits = getSetting("tmpUnits", TMP_UNITS).toInt();
  63. double t = (tmpUnits == TMP_CELSIUS) ? ds18b20.getTempCByIndex(0) : ds18b20.getTempFByIndex(0);
  64. // apply temperature reading correction
  65. double correction = getSetting("tmpCorrection", TEMPERATURE_CORRECTION).toFloat();
  66. t = t + correction;
  67. // Check if readings are valid
  68. if (isnan(t) || t < -50) {
  69. DEBUG_MSG_P(PSTR("[DS18B20] Error reading sensor\n"));
  70. } else {
  71. //If the new temperature is different from the last
  72. if (fabs(t - last_temperature) >= DS18B20_UPDATE_ON_CHANGE) {
  73. last_temperature = t;
  74. send_update = true;
  75. }
  76. _dsTemperature = t;
  77. if ((tmpUnits == TMP_CELSIUS && _dsTemperature == DEVICE_DISCONNECTED_C) ||
  78. (tmpUnits == TMP_FAHRENHEIT && _dsTemperature == DEVICE_DISCONNECTED_F))
  79. _dsIsConnected = false;
  80. else
  81. _dsIsConnected = true;
  82. dtostrf(t, 1-sizeof(_dsTemperatureStr), 1, _dsTemperatureStr);
  83. DEBUG_MSG_P(PSTR("[DS18B20] Temperature: %s%s\n"),
  84. getDSTemperatureStr(),
  85. (_dsIsConnected ? ((tmpUnits == TMP_CELSIUS) ? "ºC" : "ºF") : ""));
  86. if (send_update) {
  87. // Send MQTT messages
  88. mqttSend(getSetting("dsTmpTopic", DS18B20_TEMPERATURE_TOPIC).c_str(), _dsTemperatureStr);
  89. // Send to Domoticz
  90. #if DOMOTICZ_SUPPORT
  91. domoticzSend("dczTmpIdx", 0, _dsTemperatureStr);
  92. #endif
  93. #if INFLUXDB_SUPPORT
  94. idbSend(getSetting("dsTmpTopic", DS18B20_TEMPERATURE_TOPIC).c_str(), _dsTemperatureStr);
  95. #endif
  96. }
  97. // Update websocket clients
  98. #if WEB_SUPPORT
  99. char buffer[100];
  100. snprintf_P(buffer, sizeof(buffer), PSTR("{\"dsVisible\": 1, \"dsTmp\": %s, \"tmpUnits\": %d}"), getDSTemperatureStr(), tmpUnits);
  101. wsSend(buffer);
  102. #endif
  103. }
  104. }
  105. }
  106. #endif