Monthly Archives: December 2015

Output from multiple DS18B20 to Cacti

If you need to read multiple (variable number) of sensors into Cacti, the following python script will read the sensors and format the output ready for Cacti. Be aware though that the sensor numbering is based on their serial numbers - the order will change if sensors with different serial numbers are added or removed!!!


#!/usr/bin/env python

from os import path, listdir, system
from time import sleep


# Borrowing some elements from https://github.com/timofurrer/w1thermsensor/blob/master/w1thermsensor/core.py
THERM_SENSOR_DS18S20 = 0x10
THERM_SENSOR_DS1822 = 0x22
THERM_SENSOR_DS18B20 = 0x28
RESOLVE_TYPE_STR = {"10": THERM_SENSOR_DS18S20, "22": THERM_SENSOR_DS1822, "28": THERM_SENSOR_DS18B20}
BASE_DIRECTORY = "/sys/bus/w1/devices"
SLAVE_FILE = "w1_slave"

# function to find how many sensors are connected, works for 3 types of sensor
def get_available_sensors():
 types = [THERM_SENSOR_DS18S20, THERM_SENSOR_DS1822, THERM_SENSOR_DS18B20]
 is_sensor = lambda s: any(s.startswith(hex(x)[2:]) for x in types)
 return [(RESOLVE_TYPE_STR[s[:2]], s[3:]) for s in listdir(BASE_DIRECTORY) if is_sensor(s)]

# function to return the initial 2 letters of the device ID ("28" for DS18B20 sensors)
def slave_prefix(mytype):
 return "%s-" % hex(mytype)[2:]

# function that grabs the raw temperature data from a sensor, requires full path+filename
def read_temp_raw(device_file):
 f_1 = open(device_file, 'r')
 raw_reading = f_1.readlines()
 f_1.close()
 return raw_reading

# function that checks that the reading of a sensor was good and strips out the temperature
def read_temp(device_file):
 lines = read_temp_raw(device_file)
 while lines[0].strip()[-3:] != 'YES':
 time.sleep(0.2)
 lines = read_temp_raw(device_file)
 equals_pos = lines[1].find('t=')
 temp = float(lines[1][equals_pos+2:])/1000
 return temp

n = 0
for sensor in get_available_sensors():
 n = n +1
 sp = slave_prefix(sensor[0])
 sensorpath = path.join(BASE_DIRECTORY, sp + sensor[1], SLAVE_FILE)
 print('T'+str(n)+':'+str(read_temp(sensorpath))),

Reading multiple DS18B20 sensors

Some people have been asking for some Python code that can read multiple temperature sensors.
The following code will work for up to 10 sensors (maximum allowed under the kernel driver)



#!/usr/bin/env python

from os import path, listdir, system
from time import sleep


# Borrowing some elements from https://github.com/timofurrer/w1thermsensor/blob/master/w1thermsensor/core.py
THERM_SENSOR_DS18S20 = 0x10
THERM_SENSOR_DS1822 = 0x22
THERM_SENSOR_DS18B20 = 0x28
RESOLVE_TYPE_STR = {"10": THERM_SENSOR_DS18S20, "22": THERM_SENSOR_DS1822, "28": THERM_SENSOR_DS18B20}
BASE_DIRECTORY = "/sys/bus/w1/devices"
SLAVE_FILE = "w1_slave"

# function to find how many sensors are connected, works for 3 types of sensor
def get_available_sensors():
   types = [THERM_SENSOR_DS18S20, THERM_SENSOR_DS1822, THERM_SENSOR_DS18B20]
   is_sensor = lambda s: any(s.startswith(hex(x)[2:]) for x in types)
   return [(RESOLVE_TYPE_STR[s[:2]], s[3:]) for s in listdir(BASE_DIRECTORY) if is_sensor(s)]

# function to return the initial 2 letters of the device ID ("28" for DS18B20 sensors)
def slave_prefix(mytype):
   return "%s-" % hex(mytype)[2:]

# function that grabs the raw temperature data from a sensor, requires full path+filename
def read_temp_raw(device_file):
   f_1 = open(device_file, 'r')
   raw_reading = f_1.readlines()
   f_1.close()
   return raw_reading

# function that checks that the reading of a sensor was good and strips out the temperature
def read_temp(device_file):
   lines = read_temp_raw(device_file)
   while lines[0].strip()[-3:] != 'YES':
       time.sleep(0.2)
       lines = read_temp_raw(device_file)
   equals_pos = lines[1].find('t=')
   temp = float(lines[1][equals_pos+2:])/1000
   return temp

for sensor in get_available_sensors():
   sp = slave_prefix(sensor[0])
   sensorpath = path.join(BASE_DIRECTORY, sp + sensor[1], SLAVE_FILE)
   print("Sensor %s has a temperature %.3f" % (sensor[1], read_temp(sensorpath)))