Simplified reading of values from 1-Wire devices (in Python)

Simplified reading of values from 1-Wire devices (in Python)

1-Wire is an interesting technology for Raspberry sensors since it requires only one pin to establish a directly bus to multiple devices.

The devices get presented as directories in /sys/bus/w1/devices.
Every device has a unique id like 28-26c6eb0264ff for my DS18B20 digital temperature sensors.
The value of the sensor (temperature in my case) gets stored in a file in /sys/bus/w1/devices/28-26c6eb0264ff/w1_slave
The file content looks like:

87 01 55 00 7f ff 0c 10 8a : crc=8a YES
87 01 55 00 7f ff 0c 10 8a t=24437

This means that my sensor is currently detecting a temperature of 24.437 degrees Celsius.
The only thing I'm actually interested is the temperature.
The Python routine below simplifies reading of the temperature.
Any 1-Wire device has a hard coded unique identifier, which is a kind of tricky to remember.
The idea is to map the device identifiers in a json files to names which are simpler to remember.

JSON file for 1-Wire device to vanity name association

My JSON file is named sensor_map.json. I'm mapping two temperature sensors for my cool and my warm cylinder sensor:

   "DS18B20": [
         "device_id" : "28-92dceb0264ff",
         "device_name": "cool_cyl_temp"
         "device_id" : "28-26c6eb0264ff",
         "device_name": "warm_cyl_temp"

The Python routine needs this file to map the device to the vanity name (cool_cyl_temp) in my case.

The sample code work with Python 3.7. It requires the json and the os package.
the method compile_temps() generates a dictionary which can be uses for the further processing. It's IOT in my case.
The resulting directory looks as follows:

{'cool_cyl_temp': 25.125, 'warm_cyl_temp': 25.625}

I'll get the values of all my sensors whenever I call the routine.

Here's an example of my two routines with a short main program. The program will require individual customization. The device type for my DS18B20 ist 28_ . That's how all directories of this device type start . You will want to connect sensors of one class at a time and check for the new directories which appear in the device directory.

import json
import os

def get_w1_devices(w1_dir,device_type):
    # This functions exploits the one wire technology
    # It reads a directory and searches it for a device type. All devices of the same type start with the same string
    # It'll return a dictionary with device ids and the value
    if (not os.path.exists(w1_dir)):
       print("W1 directory " + w1_dir + " does not exist.")
       dir_list = os.listdir(w1_dir)
       # Keep only files starting with 28
       dir_list = list(filter(lambda x:x.startswith(device_type),dir_list))
    my_dict = {}
    for var in dir_list:
       my_file = Path(w1_dir + "/" + var + "/w1_slave")
       if my_file.is_file():
          # Open each file, read it, tokenize it, get a record which starts with "t="
          # Drop the t= and the carriage return
          # Get the temperature in Celsius.
          # create a dictionary with the device id and the temperature
          afile = open(w1_dir + "/" + var + "/w1_slave","r")
          my_dict[var] = int(list(filter(lambda x:x.startswith("t=")," ")))[0][2:7])/1000
          print("Error: W1 device " + w1_dir + "/" + var + " doesn't exist.")
          my_dict[var] = 1

    return my_dict

def compile_temps(file_name,temperatur_device_dict):
   # Opening JSON file
   f = open(file_name)
   # returns JSON object as
   # a dictionary
   data = json.load(f)
   # Iterating through the json
   # list the result
   temp_dict = {}
   for i in data['DS18B20']:
      temp_dict[i['device_name']] = temperatur_device_dict[i['device_id']]
   return temp_dict

#### temperature sensor paramater
my_dict = get_w1_devices(w1_dir,device_type)
temperature_dict = compile_temps('sensor_map.json',my_dict)
Stefan Schneider Mon, 10/17/2022 - 14:13