diff --git a/mudpi/extensions/ds18b20/__init__.py b/mudpi/extensions/ds18b20/__init__.py
new file mode 100644
index 0000000..15b1738
--- /dev/null
+++ b/mudpi/extensions/ds18b20/__init__.py
@@ -0,0 +1,12 @@
+"""
+ DS18B20 Extension
+ Includes sensor interface for DS18B20.
+ Works for Dallas 1-wire temperature sensors.
+"""
+from mudpi.extensions import BaseExtension
+
+
+class Extension(BaseExtension):
+ namespace = 'ds18b20'
+ update_interval = 60
+
diff --git a/mudpi/extensions/ds18b20/docs.html b/mudpi/extensions/ds18b20/docs.html
new file mode 100644
index 0000000..b5a1f94
--- /dev/null
+++ b/mudpi/extensions/ds18b20/docs.html
@@ -0,0 +1,41 @@
+# DS18B20
+The `ds18b20` extension connects to a DS18B20 device to gather temperature readings. The sensor will return `temperature`.
+
+This extension does not take an extension level configs and is focused on [interfaces.]({{url('docs/developers-interfaces')}})
+
+---
+
+
+## Sensor Interface
+Provides a [sensor]({{url('docs/sensors')}}) that returns a DS18B20 readings.
+
+
+| Option | Type | Required | Description |
+
+ | key | [String] | Yes | Unique slug id for the component |
+ | name | [String] | No | Friendly display name of component. Useful for UI. |
+ | one_wire_ID | [String] | No | The address of the DS18B20 sensor. This should be set if using mulitple DS18B20 sensors and can be found as a directory in `/sys/bus/w1/devices/` in the format of `28-XXXXXXXXXXXXX` . Default 10 |
+
+
+
+### Config Examples
+Here is a config of a complete example sensor.
+
+```json
+"sensor": [{
+ "key": "ds18b20_outside",
+ "interface": "ds18b20",
+ "name": "Outside temperature",
+ "one_wire_ID": "28-0000000000001"
+}]
+```
+
+### Data
+Here is an example of the data returned by the DS18B20:
+
+```json
+{
+ "temperature": 50
+}
+```
+---
\ No newline at end of file
diff --git a/mudpi/extensions/ds18b20/extension.json b/mudpi/extensions/ds18b20/extension.json
new file mode 100644
index 0000000..a46ca2e
--- /dev/null
+++ b/mudpi/extensions/ds18b20/extension.json
@@ -0,0 +1,9 @@
+{
+ "name": "DS18B20 1-Wire Temperature Sensor",
+ "namespace": "ds18b20",
+ "details": {
+ "description": "Provides interface for ds18b20 sensors to take tempurature readings.",
+ "documentation": "https://mudpi.app/docs/sensors/ds18b20"
+ },
+ "requirements": ["glob2", "python-time"]
+}
diff --git a/mudpi/extensions/ds18b20/sensor.py b/mudpi/extensions/ds18b20/sensor.py
new file mode 100644
index 0000000..95b8e0c
--- /dev/null
+++ b/mudpi/extensions/ds18b20/sensor.py
@@ -0,0 +1,133 @@
+"""
+ DS18B20 Sensor Interface
+ Connects to a DS18B20 device to get
+ temperature readings.
+"""
+import os
+import glob
+import time
+
+from mudpi.constants import METRIC_SYSTEM
+from mudpi.extensions import BaseInterface
+from mudpi.extensions.sensor import Sensor
+from mudpi.logger.Logger import Logger, LOG_LEVEL
+from mudpi.exceptions import MudPiError, ConfigError
+
+os.system('modprobe w1-gpio')
+os.system('modprobe w1-therm')
+
+
+#device_folder = '/sys/bus/w1/devices/28-XXXXXXXXXXXXX'
+#device_folder = glob.glob(base_dir + '/28*')[0]
+#device_file = device_folder + '/w1_slave'
+
+class Interface(BaseInterface):
+
+ def load(self, config):
+ """ Load DS18B20 sensor component from configs """
+ sensor = ds18b20(self.mudpi, config)
+ self.add_component(sensor)
+ return True
+
+ def validate(self, config):
+ if not isinstance(config, list):
+ config = [config]
+
+ for conf in config:
+ """ See if 1-wire ID was passed by the user in the config file """
+ if not conf.get('one_wire_ID'):
+ Logger.log(
+ LOG_LEVEL["debug"],
+ 'DS18B20 one_wire_ID not set. Will search for device.'
+ )
+
+ return config
+
+class ds18b20(Sensor):
+ """ DS18B20 Sensor get readings temperature. """
+
+ """ Properties """
+ @property
+ def id(self):
+ """ Return a unique id for the component """
+ return self.config['key']
+
+ @property
+ def name(self):
+ """ Return the display name of the component """
+ return self.config.get('name') or f"{self.id.replace('_', ' ').title()}"
+
+ @property
+ def state(self):
+ """ Return the state of the component (from memory, no IO!) """
+ return self._state
+
+ @property
+ def classifier(self):
+ """ Classification further describing it, effects the data formatting """
+ return 'temperature'
+
+ @property
+ def one_wire_ID(self):
+ return self.config['one_wire_ID']
+
+
+ """ Methods """
+ def init(self):
+ """To support multiple 1-wire devices check to see if the ID is set in the config.
+ If the ID is not set, there should only be a single 28-xxxxxxxxx directory in the base directory, so we use that. """
+
+ base_dir = '/sys/bus/w1/devices'
+
+ if self.config.get('one_wire_ID') and os.path.isdir(base_dir + '/' + self.config.get('one_wire_ID')):
+ self.device_file = base_dir + '/' + self.config.get('one_wire_ID') + '/w1_slave'
+ Logger.log(
+ LOG_LEVEL["debug"],
+ 'Setting device file to ' + self.device_file
+ )
+ else:
+ Logger.log(
+ LOG_LEVEL["debug"],
+ 'DS18B20 one_wire_ID not set or not found.'
+ )
+ """ Make sure 1-wire device directory exists """
+ try:
+ device_folder = glob.glob(base_dir + '/28*')[0]
+ except:
+ Logger.log(
+ LOG_LEVEL["error"],
+ 'Failed to find 1-wire device directory. Ensure device is connected and one_wire_ID corret..'
+ )
+ else:
+ self.device_file = device_folder + '/w1_slave'
+ return True
+
+ def update(self):
+
+ def read_temp_raw():
+ f = open(self.device_file, 'r')
+ lines = f.readlines()
+ f.close()
+ return lines
+
+ lines = read_temp_raw()
+ while lines[0].strip()[-3:] != 'YES':
+ time.sleep(0.2)
+ lines = read_temp_raw()
+ equals_pos = lines[1].find('t=')
+ if equals_pos != -1:
+ temp_string = lines[1][equals_pos+2:]
+ temperature_c = float(temp_string) / 1000.0
+ temperature_f = temperature_c * 9.0 / 5.0 + 32.0
+ _temperature = round(temperature_c if self.mudpi.unit_system == METRIC_SYSTEM else temperature_f, 2)
+ readings = {
+ 'temperature': _temperature,
+ }
+ self._state = readings
+ return readings
+ else:
+ Logger.log(
+ LOG_LEVEL["error"],
+ 'Failed to get reading [DS18B20]. Try again!'
+ )
+ return None