ESP32 Bench
Boards: ESP32, S3, C3
Flash and monitor: Web Serial
← All projects

Home Assistant temperature

Publish a DS18B20 reading over MQTT every 30 seconds. Home Assistant finds the sensor by itself through MQTT discovery.

Intermediate30 min115200 baud
Board
Fig. 1. Pins this project uses on the ESP32-DevKitC V4, 38 pin. USB connector at the bottom.

Wiring

FromTo boardNote
DS18B20 VDD (red)3V3
DS18B20 GND (black)GND
DS18B20 DATA (yellow)GPIO 44.7 kΩ pull-up from DATA to 3V3

Tested on this board

Not run on this board yet. Treat the wiring and code as a first draft.

Firmware, Arduino sketch for ESP32 Dev Module

#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

const char* WIFI_NAME = "your-network";
const char* WIFI_PASS = "your-password";
const char* MQTT_HOST = "192.168.1.10";  // your broker, often the Home Assistant machine
const int MQTT_PORT = 1883;
const char* MQTT_USER = "";  // leave empty if the broker allows anonymous clients
const char* MQTT_PASS = "";

OneWire oneWire(4);
DallasTemperature probes(&oneWire);
WiFiClient net;
PubSubClient mqtt(net);

String id, stateTopic, statusTopic;
unsigned long lastSend = 0;

// Tell Home Assistant about the sensor. Retained, so it survives a restart.
void announce() {
  String config = String("{\"name\":\"Temperature\",\"device_class\":\"temperature\",")
    + "\"state_class\":\"measurement\",\"unit_of_measurement\":\"°C\","
    + "\"state_topic\":\"" + stateTopic + "\","
    + "\"availability_topic\":\"" + statusTopic + "\","
    + "\"unique_id\":\"" + id + "_temperature\","
    + "\"device\":{\"identifiers\":[\"" + id + "\"],\"name\":\"ESP32 Bench " + id + "\"}}";
  String topic = String("homeassistant/sensor/") + id + "/temperature/config";
  mqtt.publish(topic.c_str(), config.c_str(), true);
}

void connectMqtt() {
  const char* user = strlen(MQTT_USER) > 0 ? MQTT_USER : nullptr;
  const char* pass = strlen(MQTT_PASS) > 0 ? MQTT_PASS : nullptr;
  while (!mqtt.connected()) {
    Serial.printf("mqtt connecting to %s\n", MQTT_HOST);
    // The last will marks the sensor unavailable if the board drops off.
    if (mqtt.connect(id.c_str(), user, pass, statusTopic.c_str(), 1, true, "offline")) {
      mqtt.publish(statusTopic.c_str(), "online", true);
      announce();
      Serial.printf("mqtt ok as %s, discovery sent\n", id.c_str());
    } else {
      Serial.printf("mqtt failed, state %d, retry in 5 s\n", mqtt.state());
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  probes.begin();

  Serial.printf("wifi joining %s\n", WIFI_NAME);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_NAME, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(300);
  Serial.printf("wifi ok %s\n", WiFi.localIP().toString().c_str());

  String mac = WiFi.macAddress();
  mac.replace(":", "");
  mac.toLowerCase();
  id = String("esp32bench-") + mac.substring(6);
  stateTopic = String("esp32bench/") + id + "/temperature";
  statusTopic = String("esp32bench/") + id + "/status";

  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setBufferSize(512);  // the discovery message is longer than the 256-byte default
}

void loop() {
  if (!mqtt.connected()) connectMqtt();
  mqtt.loop();

  if (lastSend != 0 && millis() - lastSend < 30000) return;
  lastSend = millis();

  probes.requestTemperatures();
  float c = probes.getTempCByIndex(0);
  if (c == DEVICE_DISCONNECTED_C) {
    Serial.println("no probe: check the data wire and the 4.7 kOhm pull-up");
    return;
  }
  char value[16];
  snprintf(value, sizeof value, "%.2f", c);
  mqtt.publish(stateTopic.c_str(), value);
  Serial.printf("%s %s\n", stateTopic.c_str(), value);
}

Parts

QuantityPartWhere to buy
1×ESP32 dev boardBuy at Amazon
1×DS18B20 waterproof probeBuy at Adafruit
1×4.7 kΩ resistor, pull-up for the data lineBuy at Amazon
1×An MQTT broker, such as the Mosquitto add-on in Home Assistant

Amazon buy links may include an Associates tag, and this site may earn a commission from qualifying Amazon purchases at no extra cost to you. Adafruit links are direct.

Libraries

PubSubClient (Nick O'Leary), OneWire, DallasTemperature, WiFi (built in)

Load it

  1. In the Arduino IDE, install the esp32 board package and pick the board named above the sketch.
  2. Install the libraries listed above from the Library Manager.
  3. Paste the sketch, choose the board's port and upload. Hold BOOT if the upload stalls at Connecting.
  4. Close the IDE's serial monitor, then open the bench here to watch the output.

Field notes

  • Home Assistant needs the MQTT integration set up and pointed at the same broker. The sensor then appears under Settings, Devices and services, MQTT.
  • mqtt failed, state -2 means the broker could not be reached: check MQTT_HOST and that port 1883 is open. State 4 or 5 means the user name or password was refused.
  • The sketch raises PubSubClient's buffer to 512 bytes. With the default 256 the discovery message is silently dropped and nothing appears in Home Assistant.
  • The device id comes from the board's MAC address, so each board shows up as its own device.

Not tested yet

  • Not tested on hardware or with Home Assistant yet. Compiles for every board listed with Arduino-ESP32 core 3.3.12.