timofurrer / w1thermsensor

A Python package and CLI tool to work with w1 temperature sensors like DS1822, DS18S20 & DS18B20 on the Raspberry Pi, Beagle Bone and other devices.
MIT License
493 stars 113 forks source link

Proper error handling #8

Closed ultima-originem closed 9 years ago

ultima-originem commented 9 years ago

I'm using the w1thermsensor module in a program to debug the hardware of my 9 sensor temperature logger which has recently started to behave erratically. I'm currently using the following code as a starting point in debugging the hardware:

class TemperatureSensor:

   def __init__(self, id = "", name = "", calibration = 0, connected = 1):
        self.id = id
        self.name = name
        self.calibration = calibration
        self.connected = connected

sensors = [] # create an empty sensor list

# populate the sensor list with known sensors
sensors.append(TemperatureSensor("000005e4d76b", "radiator aanvoer", 0.0, 0))
sensors.append(TemperatureSensor("000005e4f2fd", "radiator retour", 0.0, 0))
sensors.append(TemperatureSensor("000005e5f606", "CV retour", 0.0, 1))
sensors.append(TemperatureSensor("000005e77695", "tapwater", 0.0, 1))
sensors.append(TemperatureSensor("000005fab05d", "CV ruimte", 0.0, 1))
sensors.append(TemperatureSensor("000005fab2e0", "vloer aanvoer", 0.0, 1))
sensors.append(TemperatureSensor("000005fab89c", "vloer retour", 0.0, 1))
sensors.append(TemperatureSensor("000005fb03d6", "CV aanvoer", 0.0, 1))
sensors.append(TemperatureSensor("0000061be3e2", "buitentemperatuur", 0.0, 1))

degree = u'\N{DEGREE SIGN}'
degreeCelsius = u'{0}'.format(degree).encode('ISO-8859-1') + "C"

for i in range (1, len(sensors)):
    if sensors[i].connected:
        sensor = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, sensors[i].id)
        temperature = sensor.get_temperature()
        print '{:17s} {:5.1f} {:2s}'.format(sensors[i].name, temperature + sensors[i].calibration, degreeCelsius)

Occasionally, when one of the sensors is acting up, the program terminates with:

CV retour          21.7 ▒C
tapwater           24.4 ▒C
Traceback (most recent call last):
  File "t5.py", line 29, in <module>
    sensor = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, sensors[i].id)
  File "/usr/local/lib/python2.7/dist-packages/w1thermsensor/__init__.py", line 86, in __init__
    self._sensorpath = self.sensorpath
  File "/usr/local/lib/python2.7/dist-packages/w1thermsensor/__init__.py", line 123, in sensorpath
    raise NoSensorFoundError(self._type, self._id)
w1thermsensor.NoSensorFoundError: No DS18B20 temperature sensor with id '000005fab05d' found

I would like to embed this code in a larger program that will repeatedly read the sensors. The problem is that I haven't been able to figure out how to properly catch the errors, which I would like to write to an error log. This is probably trivial if you are an experienced Python developer but I haven't been able to figure it out.

Can you give me an example I can build on? Any help is welcome.

timofurrer commented 9 years ago

Hi! As you can see in your traceback the exception was raised on line 29. You can except this Exception with the W1ThermSensorError:

try:
    sensor = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, sensors[i].id)
except W1ThermSensorError as e:
    sys.stderr.write("An error occured during init of sensor %s: '%s'\n" % (sensors[i].id, e))
    continue

Does this help?

ultima-originem commented 9 years ago

This certainly helps and I'm now continuing development of my test program which I plan to run overnight.

There is however, something I don't understand about your module. I would expect a sensor that I have declared in my code but not physically connected, to raise NoSensorFoundError but it doesn't and the program doesn't generate any output for that sensor at all.

What am I missing?

EDIT: I found the answer to the above question: index error [used "1" instead of "0"]

timofurrer commented 9 years ago

Where did this IndexError occure? Can you provide some more information. Actually this should work! If the sensor is not present it will raise a NoSensorFoundError Exception at init. If then the sensor does not exist anymore while reading temperature the same exception is raised. And if the sensor is connected but not ready - it will raise a SensorNotReady exception!

ultima-originem commented 9 years ago

Timo, the problem was entirely in my code. I've since developed a test program, using your code, that works flawlessly. In the end it turned out that my Pi must have been faulty since I had replaced everything else [SD card, USB stick, OS].

Sample output of the test program running on the presumably faulty Pi:

2015-05-06 16:53:39 ......... 2015-05-06 16:53:55 ......... 2015-05-06 16:54:12 .x....... 2015-05-06 16:54:27 .x....... 2015-05-06 16:54:44 .x....... 2015-05-06 16:55:58 xx....... 2015-05-06 16:56:13 xx....... 2015-05-06 16:56:28 xx....... 2015-05-06 16:56:43 xx....... 2015-05-06 16:56:58 xx....... 2015-05-06 16:57:14 xx....... 2015-05-06 16:57:29 xx....... 2015-05-06 16:57:45 xx....... 2015-05-06 16:57:59 xx....... 2015-05-06 16:58:14 xx....... 2015-05-06 16:58:31 xx....... 2015-05-06 16:58:46 xx....... 2015-05-06 17:45:55 xx..x..x. 2015-05-06 17:46:08 xx..x..x. 2015-05-06 17:46:23 xx..x..x. 2015-05-06 17:46:36 xx.xx..x. 2015-05-06 17:46:49 xx.xx..x. 2015-05-06 17:47:02 xx.xx..x. 2015-05-06 17:47:16 xx.x..... 2015-05-06 17:47:31 xx....... 2015-05-06 17:47:48 .x....... 2015-05-06 17:48:04 .x....... 2015-05-06 17:48:20 .x.......

where every dot is a known sensor and every 'x' is a sensor that has disappeared.

This is sample output after moving the sensors to a another Pi:

2015-05-09 11:55:33 ......... 2015-05-09 11:55:41 ......... 2015-05-09 11:55:48 ......... 2015-05-09 11:55:56 ......... 2015-05-09 11:56:03 ......... 2015-05-09 11:56:11 ......... 2015-05-09 11:56:18 ......... 2015-05-09 11:56:25 ......... 2015-05-09 11:56:33 ......... 2015-05-09 11:56:40 ......... 2015-05-09 11:56:49 ......... 2015-05-09 11:56:56 ......... 2015-05-09 11:57:04 ......... 2015-05-09 11:57:11 ......... 2015-05-09 11:57:19 ......... 2015-05-09 11:57:26 ......... 2015-05-09 11:57:34 ......... 2015-05-09 11:57:41 ......... 2015-05-09 11:57:49 ......... 2015-05-09 11:57:56 ......... 2015-05-09 11:58:04 ......... 2015-05-09 11:58:11 ......... 2015-05-09 11:58:19 ......... 2015-05-09 11:58:26 ......... 2015-05-09 11:58:34 ......... 2015-05-09 11:58:41 ......... 2015-05-09 11:58:49 ......... 2015-05-09 11:58:56 ......... 2015-05-09 11:59:04 .........

Flawless; I let it run overnight with zero errors.

Based on this experience I've changed my temperature logger to only use explicitly declared sensors and not detect them automatically.

timofurrer commented 9 years ago

Okay, cool! So, i close this issue. Thanks for the contribution :beers: