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.

113 lines
2.9 KiB

  1. /*
  2. DS18B20 MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if ENABLE_DS18B20
  6. #include <OneWire.h>
  7. #include <DallasTemperature.h>
  8. OneWire oneWire(DS_PIN);
  9. DallasTemperature ds18b20(&oneWire);
  10. bool _dsIsConnected = false;
  11. double _dsTemperature = 0;
  12. char _dsTemperatureStr[6];
  13. // -----------------------------------------------------------------------------
  14. // DS18B20
  15. // -----------------------------------------------------------------------------
  16. double getDSTemperature() {
  17. return _dsTemperature;
  18. }
  19. const char* getDSTemperatureStr() {
  20. if (!_dsIsConnected)
  21. return "NOT CONNECTED";
  22. return _dsTemperatureStr;
  23. }
  24. void dsSetup() {
  25. ds18b20.begin();
  26. ds18b20.setWaitForConversion(false);
  27. apiRegister(DS_TEMPERATURE_TOPIC, DS_TEMPERATURE_TOPIC, [](char * buffer, size_t len) {
  28. dtostrf(_dsTemperature, len-1, 1, buffer);
  29. });
  30. }
  31. void dsLoop() {
  32. // Check if we should read new data
  33. static unsigned long last_update = 0;
  34. static bool requested = false;
  35. if ((millis() - last_update > DS_UPDATE_INTERVAL) || (last_update == 0)) {
  36. if (!requested) {
  37. ds18b20.requestTemperatures();
  38. requested = true;
  39. /* Requesting takes time,
  40. * so data will probably not be available in this round */
  41. return;
  42. }
  43. /* Check if requested data is already available */
  44. if (!ds18b20.isConversionComplete()) {
  45. return;
  46. }
  47. requested = false;
  48. last_update = millis();
  49. unsigned char tmpUnits = getSetting("tmpUnits", TMP_UNITS).toInt();
  50. // Read sensor data
  51. double t = (tmpUnits == TMP_CELSIUS) ? ds18b20.getTempCByIndex(0) : ds18b20.getTempFByIndex(0);
  52. // Check if readings are valid
  53. if (isnan(t) || t < -50) {
  54. DEBUG_MSG_P(PSTR("[DS18B20] Error reading sensor\n"));
  55. } else {
  56. _dsTemperature = t;
  57. if ((tmpUnits == TMP_CELSIUS && _dsTemperature == DEVICE_DISCONNECTED_C) ||
  58. (tmpUnits == TMP_FAHRENHEIT && _dsTemperature == DEVICE_DISCONNECTED_F))
  59. _dsIsConnected = false;
  60. else
  61. _dsIsConnected = true;
  62. dtostrf(t, 5, 1, _dsTemperatureStr);
  63. DEBUG_MSG_P(PSTR("[DS18B20] Temperature: %s%s\n"),
  64. getDSTemperatureStr(),
  65. (_dsIsConnected ? ((tmpUnits == TMP_CELSIUS) ? "ºC" : "ºF") : ""));
  66. // Send MQTT messages
  67. mqttSend(getSetting("dsTmpTopic", DS_TEMPERATURE_TOPIC).c_str(), _dsTemperatureStr);
  68. // Send to Domoticz
  69. #if ENABLE_DOMOTICZ
  70. domoticzSend("dczTmpIdx", 0, _dsTemperatureStr);
  71. #endif
  72. // Update websocket clients
  73. char buffer[100];
  74. sprintf_P(buffer, PSTR("{\"dsVisible\": 1, \"dsTmp\": %s, \"tmpUnits\": %d}"), getDSTemperatureStr(), tmpUnits);
  75. wsSend(buffer);
  76. }
  77. }
  78. }
  79. #endif