w1thermsensor

repository·master·Indexed 19 days ago

https://github.com/timofurrer/w1thermsensor

A Python package and CLI tool for working with 1-Wire (w1) compatible temperature sensors, such as DS18B20, DS18S20, and DS1822, on Raspberry Pi, Beagle Bone, and other devices. It provides the W1ThermSensor class for synchronous readings and AsyncW1ThermSensor for asyncio applications. Features include sensor discovery, resolution management, calibration data support, and a CLI for listing sensors and retrieving temperatures.

Tokens
8.2K
Snippets
46
Records
49
Agent score
66%

What's inside w1thermsensor

  1. Configure Raspberry Pi hardware for 1-Wire

    master

    To use 1-Wire sensors on a Raspberry Pi, you must modify /boot/config.txt and reboot.

    • For a regular connection: add dtoverlay=w1-gpio.
    • For a parasitic connection: add dtoverlay=w1-gpio,pullup="y".

    By default, the data pin is GPIO4 (Raspberry Pi connector pin 7). To use a different pin, use dtoverlay=w1-gpio,gpiopin=x where x is your chosen pin.

  2. Use w1thermsensor as a CLI tool

    master

    The w1thermsensor module can be used as a command-line interface (CLI) tool (available since version 0.3.0).

    Note: The CLI tool is only installed when using the Raspbian Python 3 package via sudo apt-get install python3-w1thermsensor.

    $ w1thermsensor ls
  3. Install w1thermsensor via PIP

    master

    You can install the package on any distribution using pip. To enable support for asyncio and the AsyncW1ThermSensor class, install the async extra.

    Note: Root privileges may be required for installation.

    # Standard installation
    pip install w1thermsensor
    
    # Installation with asyncio support
    pip install w1thermsensor[async]
  4. Disable automatic kernel module loading

    master

    By default, importing w1thermsensor attempts to load w1-therm and w1-gpio kernel modules, which requires the process to run as root. If you want to manage module loading manually, set the W1THERMSENSOR_NO_KERNEL_MODULE environment variable to 1.

    # Set for the current shell session
    export W1THERMSENSOR_NO_KERNEL_MODULE=1
    
    # Set specifically for a Python process
    W1THERMSENSOR_NO_KERNEL_MODULE=1 python my_awesome_thermsensor_script.py
  5. Verify 1-Wire device connection

    master

    Before using the Python library, verify that the kernel sees your sensors.

    1. Check device files: Run ls -l /sys/bus/w1/devices. You should see filenames starting with 28-. If you see filenames starting with 00-, your pull-up resistor might be missing.
    2. Test reading raw data: Run the following loop to attempt a direct read from the kernel driver:
    for i in /sys/bus/w1/devices/28-*; do cat $i/w1_slave; done
    ls -l /sys/bus/w1/devices
    
    for i in /sys/bus/w1/devices/28-*; do cat $i/w1_slave; done
  6. Set sensor resolution

    master

    Some sensors allow you to change the temperature reading resolution using set_resolution(resolution, persist=False).

    • persist=False (default): The resolution is stored in volatile SRAM and is reset when the sensor is power-cycled.
    • persist=True: The resolution is stored in the EEPROM. Warning: EEPROM has limited write cycles (~50k), so use this sparingly.

    Note: This requires Linux Kernel 4.7+ and root privileges.

    sensor = W1ThermSensor(sensor_type=Sensor.DS18B20, sensor_id="00000588806a")
    
    # Set resolution to 9-bit (volatile)
    sensor.set_resolution(9)
    
    # Set resolution to 9-bit (persistent in EEPROM)
    sensor.set_resolution(9, persist=True)
  7. Use the AsyncW1ThermSensor interface

    master

    For asyncio applications, use the AsyncW1ThermSensor class. It provides asynchronous versions of the standard reading methods. Ensure you have installed the async extra via pip (pip install w1thermsensor[async]).

    Supported async methods:

    • get_temperature()
    • get_temperatures()
    • get_resolution()
    from w1thermsensor import AsyncW1ThermSensor, Unit
    
    async def main():
        sensor = AsyncW1ThermSensor()
        
        # Await the asynchronous temperature readings
        temp_c = await sensor.get_temperature()
        temp_f = await sensor.get_temperature(Unit.DEGREES_F)
        all_units = await sensor.get_temperatures([Unit.DEGREES_C, Unit.KELVIN])
  8. Access a specific sensor by ID

    master

    To target a specific sensor instead of the first one found, provide the sensor_type (using the Sensor enum) and the unique sensor_id to the W1ThermSensor constructor.

    from w1thermsensor import W1ThermSensor, Sensor
    
    # Target a specific DS18B20 sensor by its ID
    sensor = W1ThermSensor(sensor_type=Sensor.DS18B20, sensor_id="00000588806a")
    temperature_in_celsius = sensor.get_temperature()
  9. Calibrate temperature sensors

    master

    You can correct sensor readings by providing CalibrationData. This is useful for compensating for inaccuracies by measuring known reference points (like the melting and boiling points of water).

    Use the get_corrected_temperature() and get_corrected_temperatures() methods to retrieve the calibrated values.

    from w1thermsensor.calibration_data import CalibrationData
    from w1thermsensor import W1ThermSensor, Unit
    
    # Define calibration points based on physical measurements
    calibration_data = CalibrationData(
        measured_high_point=measured_high_point,
        measured_low_point=measured_low_point,
        reference_high_point=reference_high_point,
        reference_low_point=0.0, # defaults to 0.0
    )
    
    sensor = W1ThermSensor(calibration_data=calibration_data)
    
    # Get corrected readings
    corrected_temp_c = sensor.get_corrected_temperature()
    corrected_temp_f = sensor.get_corrected_temperature(Unit.DEGREES_F)
  10. Basic usage with W1ThermSensor

    master

    The W1ThermSensor class provides a simple interface for reading temperatures. By default, the constructor attempts to automatically load the necessary kernel modules (w1-therm and w1-gpio), which requires root privileges.

    If no arguments are passed, the class will use the first sensor it finds.

    from w1thermsensor import W1ThermSensor, Unit
    
    sensor = W1ThermSensor()
    
    # Get temperature in Celsius
    temperature_in_celsius = sensor.get_temperature()
    
    # Get temperature in Fahrenheit
    temperature_in_fahrenheit = sensor.get_temperature(Unit.DEGREES_F)
    
    # Get temperatures in multiple units
    temperature_in_all_units = sensor.get_temperatures([
        Unit.DEGREES_C,
        Unit.DEGREES_F,
        Unit.KELVIN])