diff --git a/client/libs/DS18B20/DS18B20.cpp b/client/libs/DS18B20/DS18B20.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..850951f6d559def960e5338667fcba9022eece2c
--- /dev/null
+++ b/client/libs/DS18B20/DS18B20.cpp
@@ -0,0 +1,57 @@
+//
+// Created by zoe on 3/23/23.
+//
+
+#include "DS18B20.h"
+
+std::list<Measurement> DS18B20::readData() {
+    sensors.requestTemperatures();
+    float temperature = sensors.getTempC(sensorAddress);
+    if (temperature == DEVICE_DISCONNECTED_C) {
+        Serial.println("Error: Could not read temperature data");
+        // error measurement
+        auto errorMessage = Measurement(ERROR_VALUE, NO_CHANNEL, NO_I2C_ADDRESS, MeasurementType::TEMPERATURE,
+                                        ErrorType::SENSOR_NOT_CONNECTED);
+        return std::list<Measurement>{errorMessage};
+    }
+    auto measurement =
+        Measurement(temperature, NO_CHANNEL, NO_I2C_ADDRESS, MeasurementType::TEMPERATURE, ErrorType::DATA_OK);
+    return std::list<Measurement>{measurement};
+}
+
+std::list<Message> DS18B20::buildMessages() {
+    std::list<Message> messages;
+    auto measurements = readData();
+    for (auto measurement : measurements) {
+        messages.emplace_back(measurement, getSensorInformation(), Time::getInstance().getEpochSeconds());
+    }
+    return messages;
+}
+
+SensorInformation DS18B20::getSensorInformation() const {
+    return {HardwareName::DS18B20, SensorProtocol::OneWire};
+}
+
+void DS18B20::setup() {
+
+    ESP_LOGD("DS18B20", "Setting up DS18B20\n");
+
+    oneWire = OneWireSingleton::getInstance().getOneWire(33);
+    sensors = DallasTemperature(oneWire.get());
+    sensors.begin();
+    ESP_LOGD("DS18B20", "Found %d devices\n", sensors.getDeviceCount());
+    ESP_LOGD("DS18B20", "Parasite power is: %s\n", sensors.isParasitePowerMode() ? "ON" : "OFF");
+
+    // TODO: This is hardcoded to only use the first device
+    if (!sensors.getAddress(sensorAddress, 0)) {
+        ESP_LOGD("DS18B20", "Unable to find address for Device 0\n");
+    }
+    ESP_LOGD("DS18B20", "Device 0 Address: %s\n", getAddressString(sensorAddress).c_str());
+
+    // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
+    sensors.setResolution(sensorAddress, 9);
+
+    ESP_LOGD("DS18B20", "Device 0 Resolution: %d\n", sensors.getResolution(sensorAddress));
+
+    ESP_LOGD("DS18B20", "Setup complete\n");
+}
diff --git a/client/libs/DS18B20/DS18B20.h b/client/libs/DS18B20/DS18B20.h
new file mode 100644
index 0000000000000000000000000000000000000000..45dc6e70c2d90226040622827a8bd70725aea376
--- /dev/null
+++ b/client/libs/DS18B20/DS18B20.h
@@ -0,0 +1,41 @@
+//
+// Created by zoe on 3/23/23.
+//
+
+#ifndef CLIENT_SATELLITE_DS18B20_H
+#define CLIENT_SATELLITE_DS18B20_H
+
+#include <ForteSensor.hpp>
+#include "DallasTemperature.h"
+#include <OneWire.h>
+#include <OneWireSingleton.h>
+
+class DS18B20 : ForteSensor<std::list<Measurement>> {
+  public:
+    void setup() override;
+    std::list<Measurement> readData() override;
+    std::list<Message> buildMessages() override;
+    [[nodiscard]] SensorInformation getSensorInformation() const override;
+
+  private:
+    std::shared_ptr<OneWire> oneWire;
+    DallasTemperature sensors;
+    DeviceAddress sensorAddress;
+
+    // function to print a device address
+    String getAddressString(DeviceAddress deviceAddress) {
+        String addressString = "";
+
+        for (uint8_t i = 0; i < 8; i++) {
+            if (deviceAddress[i] < 16) {
+                addressString += "0";
+            }
+            char hexBuffer[3];
+            snprintf(hexBuffer, sizeof(hexBuffer), "%02X", deviceAddress[i]);
+            addressString += hexBuffer;
+        }
+        return addressString;
+    }
+};
+
+#endif // CLIENT_SATELLITE_DS18B20_H
diff --git a/client/libs/OneWireSingelton/OneWireSingleton.cpp b/client/libs/OneWireSingelton/OneWireSingleton.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4591b8012e0418a6571bca2151ab4d76053f9fd8
--- /dev/null
+++ b/client/libs/OneWireSingelton/OneWireSingleton.cpp
@@ -0,0 +1,12 @@
+//
+// Created by zoe on 3/23/23.
+//
+
+#include "OneWireSingleton.h"
+
+std::shared_ptr<OneWire> OneWireSingleton::getOneWire(int pin) {
+    if (oneWireMap.find(pin) == oneWireMap.end()) {
+        oneWireMap[pin] = std::make_shared<OneWire>(OneWire(pin));
+    }
+    return oneWireMap[pin];
+}
\ No newline at end of file
diff --git a/client/libs/OneWireSingelton/OneWireSingleton.h b/client/libs/OneWireSingelton/OneWireSingleton.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc63fc3cda5469dd104ff49e0cd563aaf019407f
--- /dev/null
+++ b/client/libs/OneWireSingelton/OneWireSingleton.h
@@ -0,0 +1,44 @@
+//
+// Created by zoe on 3/23/23.
+//
+
+#ifndef CLIENT_SATELLITE_ONEWIRESINGLETON_H
+#define CLIENT_SATELLITE_ONEWIRESINGLETON_H
+
+#include <OneWire.h>
+#include <memory>
+
+class OneWireSingleton {
+  public:
+    static OneWireSingleton &getInstance() {
+        static OneWireSingleton instance; // Guaranteed to be destroyed.
+                                          // Instantiated on first use.
+        return instance;
+    }
+
+    // This returns a shared pointer to the OneWire object. I made this shared so that the OneWire object is only
+    // cleared when not only the singleton is destroyed, but when the last reference to the OneWire object is
+    // destroyed.
+    std::shared_ptr<OneWire> getOneWire(int pin);
+
+  private:
+    OneWireSingleton() {} // Constructor? (the {} brackets) are needed here.
+
+    std::unordered_map<int, std::shared_ptr<OneWire>> oneWireMap;
+
+    // C++ 11
+    // =======
+    // We can use the better technique of deleting the methods
+    // we don't want.
+  public:
+    OneWireSingleton(OneWireSingleton const &) = delete;
+    void operator=(OneWireSingleton const &) = delete;
+
+    // Note: Scott Meyers mentions in his Effective Modern
+    //       C++ book, that deleted functions should generally
+    //       be public as it results in better error messages
+    //       due to the compilers behavior to check accessibility
+    //       before deleted status
+};
+
+#endif // CLIENT_SATELLITE_ONEWIRESINGLETON_H
diff --git a/client/libs/espnow/src/ESPNow.cpp b/client/libs/espnow/src/ESPNow.cpp
index 6ef9054a64321ec0318602b66b738fd7ccc4f3f9..8d046c875b97624549374878a9e1f44e5d2b7f0d 100644
--- a/client/libs/espnow/src/ESPNow.cpp
+++ b/client/libs/espnow/src/ESPNow.cpp
@@ -126,7 +126,7 @@ esp_err_t espnow_setup() {
   if (result != ESP_OK) {
     // initialization failed
     ESP_LOGE(TAG, "ESPNow setup failed");
-    return result; // not sure about this
+    return result;
   }
 
   get_host_mac(hostInfo.peer_addr); // check if there is a host saved in flash mem, broadcast otherwise
diff --git a/shared-libs/DataTransfer/HardwareNames.cpp b/shared-libs/DataTransfer/HardwareNames.cpp
index 94fbb405a8e7faf9fe22995f3720d12c9876b849..aebd8eedb7805b96b3dea185f575715c2f43cbbb 100644
--- a/shared-libs/DataTransfer/HardwareNames.cpp
+++ b/shared-libs/DataTransfer/HardwareNames.cpp
@@ -4,42 +4,44 @@
 
 #include "HardwareNames.h"
 namespace HardwareNames {
-std::string hardwareNameToString(HardwareName hardwareName) {
-  // switch
-  switch (hardwareName) {
-    case HardwareName::RS485:
-      return "RS485";
-    case HardwareName::INA219:
-      return "INA219";
-    case HardwareName::SCD30:
-      return "SCD30";
-    case HardwareName::RAIN_GAUGE:
-      return "RAIN_GAUGE";
-    case HardwareName::SOIL_MOISTURE_SENSOR:
-      return "SOIL_MOISTURE_SENSOR";
-    case HardwareName::SOIL_TEMPERATURE_SENSOR:
-      return "SOIL_TEMPERATURE_SENSOR";
-    case HardwareName::SOLAR_RADIATION_SENSOR:
-      return "SOLAR_RADIATION_SENSOR";
-    case HardwareName::SHT85:
-      return "SHT85";
-    case HardwareName::DRS26:
-      return "DRS26";
-    case HardwareName::DR26:
-      return "DR26";
-    case HardwareName::MOCK:
-      return "MOCK";
-    case HardwareName::NONE:
-      return "NONE";
-    case HardwareName::LC709203:
-      return "LC709203";
-    case HardwareName::SEM228A:
-      return "SEM228A";
-    case HardwareName::SEM225:
-      return "SEM225";
-    case HardwareName::SEM404:
-      return "SEM404";
-  }
-  return "UNKNOWN_HARDWARE_NAME";
-}
+    std::string hardwareNameToString(HardwareName hardwareName) {
+        // switch
+        switch (hardwareName) {
+        case HardwareName::RS485:
+            return "RS485";
+        case HardwareName::INA219:
+            return "INA219";
+        case HardwareName::SCD30:
+            return "SCD30";
+        case HardwareName::RAIN_GAUGE:
+            return "RAIN_GAUGE";
+        case HardwareName::SOIL_MOISTURE_SENSOR:
+            return "SOIL_MOISTURE_SENSOR";
+        case HardwareName::SOIL_TEMPERATURE_SENSOR:
+            return "SOIL_TEMPERATURE_SENSOR";
+        case HardwareName::SOLAR_RADIATION_SENSOR:
+            return "SOLAR_RADIATION_SENSOR";
+        case HardwareName::SHT85:
+            return "SHT85";
+        case HardwareName::DRS26:
+            return "DRS26";
+        case HardwareName::DR26:
+            return "DR26";
+        case HardwareName::MOCK:
+            return "MOCK";
+        case HardwareName::NONE:
+            return "NONE";
+        case HardwareName::LC709203:
+            return "LC709203";
+        case HardwareName::SEM228A:
+            return "SEM228A";
+        case HardwareName::SEM225:
+            return "SEM225";
+        case HardwareName::SEM404:
+            return "SEM404";
+        case HardwareName::DS18B20:
+            return "DS18B20";
+        }
+        return "UNKNOWN_HARDWARE_NAME";
+    }
 } // namespace HardwareNames
\ No newline at end of file
diff --git a/shared-libs/DataTransfer/HardwareNames.h b/shared-libs/DataTransfer/HardwareNames.h
index ee689f81c5fc58f810fc99d83a2cfa6340fa3b34..c58cea35fbac4ffeb4dc030a58808c23c04746d0 100644
--- a/shared-libs/DataTransfer/HardwareNames.h
+++ b/shared-libs/DataTransfer/HardwareNames.h
@@ -9,29 +9,29 @@
 
 // 32,767 possible values
 enum class HardwareName : short {
-  RS485, // TODO: THIS IS THE PROTOCOL NAME NOT THE HARDWARE NAME
-  INA219,
-  SCD30,
-  RAIN_GAUGE,
-  SOIL_MOISTURE_SENSOR,
-  SOIL_TEMPERATURE_SENSOR,
-  SOLAR_RADIATION_SENSOR,
-  SEM404,
-  SEM228A,
-  SEM225,
-  SHT85,
-  DRS26,
-  DR26,
-  MOCK,
-  NONE,
-  LC709203,
+    RS485, // TODO: THIS IS THE PROTOCOL NAME NOT THE HARDWARE NAME
+    INA219,
+    SCD30,
+    RAIN_GAUGE,
+    SOIL_MOISTURE_SENSOR,
+    SOIL_TEMPERATURE_SENSOR,
+    SOLAR_RADIATION_SENSOR,
+    SEM404,
+    SEM228A,
+    SEM225,
+    DS18B20,
+    SHT85,
+    DRS26,
+    DR26,
+    MOCK,
+    NONE,
+    LC709203,
 };
 
 // hardware name to string function
 
 namespace HardwareNames {
-std::string hardwareNameToString(HardwareName hardwareName);
+    std::string hardwareNameToString(HardwareName hardwareName);
 }
 
-
-#endif //CLIENT_MOCK_HARDWARENAMES_H
+#endif // CLIENT_MOCK_HARDWARENAMES_H
diff --git a/shared-libs/DataTransfer/SensorProtocol.cpp b/shared-libs/DataTransfer/SensorProtocol.cpp
index f2aa02da070bf93f3cdee9ca2682b792a6ee62cf..7e6fbbbab78d1da8071294135d0c4fa63ad17983 100644
--- a/shared-libs/DataTransfer/SensorProtocol.cpp
+++ b/shared-libs/DataTransfer/SensorProtocol.cpp
@@ -4,19 +4,21 @@
 
 #include "SensorProtocol.hpp"
 namespace SensorProtocols {
-std::string sensorProtocolToString(SensorProtocol sensorProtocol) {
-  switch (sensorProtocol) {
-    case SensorProtocol::I2C:
-      return "I2C";
-    case SensorProtocol::RS485:
-      return "RS485";
-    case SensorProtocol::Analog:
-      return "Analog";
-    case SensorProtocol::Mock:
-      return "Mock";
-    case SensorProtocol::NULL_PROTOCOL:
-      return "NULL_PROTOCOL";
-  }
-  return "UNKNOWN";
-}
-}
\ No newline at end of file
+    std::string sensorProtocolToString(SensorProtocol sensorProtocol) {
+        switch (sensorProtocol) {
+        case SensorProtocol::I2C:
+            return "I2C";
+        case SensorProtocol::RS485:
+            return "RS485";
+        case SensorProtocol::Analog:
+            return "Analog";
+        case SensorProtocol::Mock:
+            return "Mock";
+        case SensorProtocol::OneWire:
+            return "OneWire";
+        case SensorProtocol::NULL_PROTOCOL:
+            return "NULL_PROTOCOL";
+        }
+        return "UNKNOWN";
+    }
+} // namespace SensorProtocols
\ No newline at end of file
diff --git a/shared-libs/DataTransfer/SensorProtocol.hpp b/shared-libs/DataTransfer/SensorProtocol.hpp
index fb4d0b0f114cb2e10decb6a263044bc05ade7c3d..d8eade29927ee4946f05060bef9e08f6941818cb 100644
--- a/shared-libs/DataTransfer/SensorProtocol.hpp
+++ b/shared-libs/DataTransfer/SensorProtocol.hpp
@@ -6,7 +6,7 @@
 #define CLIENT_PROTOCOL_HPP
 
 #include <map>
-enum class SensorProtocol : short { I2C, RS485, Analog, Mock, NULL_PROTOCOL };
+enum class SensorProtocol : short { I2C, RS485, Analog, Mock, OneWire, NULL_PROTOCOL };
 
 namespace SensorProtocols {
 std::string sensorProtocolToString(SensorProtocol sensorProtocol);