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.") else: 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="), afile.read().split(" ")))[0][2:7])/1000 afile.close() else: 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) f.close() # 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 w1_dir="/sys/bus/w1/devices" device_type="28-" map_file="sensor_map.json" my_dict = get_w1_devices(w1_dir,device_type) temperature_dict = compile_temps('sensor_map.json',my_dict) print(temperature_dict)
- 220 views