DS18B20 Sensor on Trixie with Python

1-Wire sensor

It was not as straight forward as I thought it would be, hence this short tutorial.

Step 1:
Enable the 1-Wire interface with the raspi-config tool, look for it under interface options, or advanced options:
sudo raspi-config

Step 2:
The Python script that loads the modules (if needed) and reads the sensor. In this case the result is written in JSON to a temporary directory.

import os
import glob
import time
import json

base_dir = '/sys/bus/w1/devices/'

# Try to detect DS18B20 sensor
device_folders = glob.glob(base_dir + '28*')

# If sensor not found, try loading kernel modules
if not device_folders:
    os.system('modprobe w1-gpio')
    os.system('modprobe w1-therm')
    time.sleep(1)
    device_folders = glob.glob(base_dir + '28*')

# If still not found, exit
if not device_folders:
    print("DS18B20 Sensor not found.")
    exit()

device_folder = device_folders[0]
device_file = device_folder + '/w1_slave'


def read_rom():
    name_file = device_folder + '/name'
    with open(name_file, 'r') as f:
        return f.readline().strip()


def read_temp_raw():
    with open(device_file, 'r') as f:
        return f.readlines()


def read_temp():
    lines = read_temp_raw()

    # Wait until valid reading
    retry_count = 5
    while lines[0].strip()[-3:] != 'YES' and retry_count > 0:
        time.sleep(0.2)
        lines = read_temp_raw()
        retry_count -= 1

    if lines[0].strip()[-3:] != 'YES':
        raise RuntimeError("Sensor CRC check failed")

    equals_pos = lines[1].find('t=')

    if equals_pos != -1:
        temp_string = lines[1][equals_pos + 2:]
        temp_c = float(temp_string) / 1000.0
        temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c, temp_f
    else:
        raise RuntimeError("Temperature data not found")


# Write JSON result
def writeresult(tempdict):
    json_object = json.dumps(tempdict)

    with open("/run/temperature.json", "w", encoding="utf-8") as outfile:
        outfile.write(json_object)
    
    os.chmod(path, 0o644)

try:
    temperature_c, temperature_f = read_temp()

    dictionary = {
        "time": str(int(time.time())),
        "tempC": round(temperature_c, 2),
        "tempF": round(temperature_f, 2)
    }

    writeresult(dictionary)

except Exception as e:
    print("Error:", e)