Commit 7c5a2eff authored by Levin Zimmermann's avatar Levin Zimmermann

playbook: Fix sensor installation for Debian 11

Previously it only worked with Debian 10. This commit reflects the
removal of the apt package 'python-pip' in Debian 11 and the change
of the i2c bus number.
parent 90ea4d1c
- name: Install apt package dependencies - name: Install apt package dependencies
apt: apt:
pkg: pkg:
- python - python3
- python-pip - python3-pip
- i2c-tools - i2c-tools
- python-smbus - python3-smbus
state: present state: present
- name: Install setuptools - name: Install setuptools
pip: pip:
name: setuptools name: setuptools
executable: pip2 executable: pip3
- name: Install bme280 - name: Install bme280
pip: pip:
name: bme280 name: bme280
executable: pip2 executable: pip3
# We need to set a different bus number depending
# on the debian version. For Debian 12 we may
# need another number again.
- name: Set bus number for debian bullseye
set_fact:
i2c_bus_number: 3
when: ansible_distribution == 'Debian' and ansible_distribution_release == 'Buster'
  • @levin.zimmermann I think there's a typo here, it's not 'Buster', it is 'buster' :

    $ ansible localhost -m setup | grep ansible_distribution_release
            "ansible_distribution_release": "buster",

    if I understood "it works" because the condition is false, so the default from https://lab.nexedi.com/nexedi/slapos.package/blob/7c5a2effb5d7f25d3753f31db3bb7fcf44f2ebd2/playbook/roles/olimex-sensor/vars/main.yml#L1 is used.

    If that's correct, then maybe we can remove all this block:

    - name: Set bus number for debian bullseye
      set_fact:
        i2c_bus_number: 3
      when: ansible_distribution == 'Debian' and ansible_distribution_release == 'Buster'
    Edited by Jérome Perrin
  • Thanks for catching this @jerome! Ah, right it perhaps works because of the default value. Maybe it's even better to remove the default value and fix the typo (+ the name), because I don't know if it would actually work on any different OS (version), so the default value may be useless in this case. AFAIK Olimex officially only support Debian images anyway. Plus it would make the code easier to understand when rereading it, if everything is actually in one place. What do you think?

  • Yes, that makes sense, so in the case of for example debian 12, running the playbook would throw an error with a message lik "unknown i2c bus number" ? I don't know at all how this bus number is assigned so I cannot really confirm this is the best thing to do, but this sounds reasonable.

    BTW, instead of using the distribution code names (buster, bullseye, etc) we can use ansible_distribution_major_version like we do in https://lab.nexedi.com/nexedi/slapos.package/blob/0619932c3e0ec45a630a9a353b028c70c848d2f1/playbook/roles/repository/tasks/main.yml , this gives us a version number like 10, 11, that's probably easier to understand

  • Yes, that makes sense, so in the case of for example debian 12, running the playbook would throw an error with a message lik "unknown i2c bus number" ?

    Maybe I could even provide a custom exception with a better explaining message.

    I don't know at all how this bus number is assigned

    I neither know it, I only empirically tried it with two different computers, once both with debian 10 and then both with debian 11 (and both had the same i2c bus number for the sensor which was different depending on the debian version).

    Because we're already rethinking this, I found this unsatisfying and researched a bit.

    In the i2c dev interface documentation it says:

    Adapter numbers are assigned somewhat dynamically, so you can not assume much about them. They can even change from one boot to the next.

    But someone on stackexchange noted:

    Though often i2c bus numbers are assigned dynamically, on some platforms Linux will use information from a devicetree to assign specific numbers to an i2c adaptor. Presumably, some motherboards can similarly have platform drivers that request a particular bus number, to better represent the hardware layout.

    I found the name of the device tree file used for the specific Olimex board in the image building git repo of Olimex:

    https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts

    And this device tree again includes another device tree. And I think here it statically declares which pin the adapter number 3 is assigned to.

    Therefore to say it depends on ansible_distribution_release and ansible_distribution is not exactly true. It seems that Olimex changed the devicetree between their custom Debian 10 image and their custom Debian 11 image which I used. It could also be that in future Debian images they won't change i2c adapter number mapping (or, even though perhaps unlikely, they could change the i2c adapter mapping in a new image with the same major Debian release, with which the current if clause would become meaningless).

    Concluding from there, I think the most reasonable proposal would be to remove all the when blocks, to only leave the default value and to add a remark or note to the Wendelin learning track (something like, "if this doesn't work, please run the following command in order to verify the i2c adapter number is still valid"). I think the Debian 10 Image I used was very old. In their current release page Olimex only provide the most recent images. This playbook is only used in a tutorial through which people usually go through once, why it doesn't seem to be very important to support older versions. But even if we would like to support older versions, we would have to verify first that all custom Debian 10 Olimex images use the same devicetree or otherwise find a more clever when clause..

  • Thanks for taking the time to do this analysis and explanation ! It sounds very reasonable to have only the default value (then it would be 2, right ?) and a comment explaining this, maybe linking to this discussion.

  • For reference, changes have finally been applied with 125d10ff. Now there is also a hint in troubleshoot section of the learning track itself.

    (Thanks for hinting to default value = 2, I confused it, perhaps because of using distribution code names instead of numbers ;) )

Please register or sign in to reply
- name: Set bus number for debian bullseye
set_fact:
i2c_bus_number: 2
when: ansible_distribution == 'Debian' and ansible_distribution_release == 'bullseye'
- name: Solve python template to read sensor - name: Solve python template to read sensor
template: template:
...@@ -27,8 +41,8 @@ ...@@ -27,8 +41,8 @@
set_olimex_sensor_permission_path: /usr/bin/olimex-sensor-set-sensor-permission set_olimex_sensor_permission_path: /usr/bin/olimex-sensor-set-sensor-permission
- name: Move script to grant access to sensor to file path - name: Move script to grant access to sensor to file path
copy: template:
src: olimex-sensor-set-sensor-permission.sh src: olimex-sensor-set-sensor-permission.j2
dest: "{{ set_olimex_sensor_permission_path }}" dest: "{{ set_olimex_sensor_permission_path }}"
mode: 755 mode: 755
......
#!/bin/bash
chgrp slapsoft /dev/i2c-{{ i2c_bus_number }}
...@@ -6,9 +6,9 @@ from bme280 import bme280_i2c ...@@ -6,9 +6,9 @@ from bme280 import bme280_i2c
from bme280.bme280 import read_all from bme280.bme280 import read_all
bme280_i2c.set_default_i2c_address(int("0x77", 0)) # address of sensor 0x77 bme280_i2c.set_default_i2c_address(int("0x77", 0)) # address of sensor 0x77
bme280_i2c.set_default_bus(int({{ i2c_bus_number }})) # i2c bus number 3 (i2c-3) bme280_i2c.set_default_bus(int({{ i2c_bus_number }})) # depends on distro version
bme280.setup() bme280.setup()
data = bme280.read_all() data = bme280.read_all()
print("{}\t{}\t{}".format(data.pressure,data.humidity,data.temperature)) print("{}\t{}\t{}".format(data.pressure, data.humidity, data.temperature))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment