Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Too many open files: '/dev/i2c-1' #5

Closed
Rayn0r opened this issue Oct 16, 2020 · 4 comments
Closed

Too many open files: '/dev/i2c-1' #5

Rayn0r opened this issue Oct 16, 2020 · 4 comments
Labels
bug Something isn't working

Comments

@Rayn0r
Copy link

Rayn0r commented Oct 16, 2020

I'm trying to use the SGP30 sensor in a collectd plugin. The plugin is suppossed to write the eco2 value to an InfluxDB.
Therefore I'm initiliazing the sensor with:

#!/usr/bin/env python3
from sgp30 import SGP30
import sys

sgp30 = SGP30()
sgp30.start_measurement()

before starting collectd.

From within collectd the follwowing code is executed every 10 seconds.

    sgp30 = SGP30()
    eco2s, tvocs = sgp30.command('measure_air_quality')

and then written to the InfluxDB.
Sending the command seems to call SMBUS.open() implicitly in line 76:
self._i2c_dev.i2c_rdwr(msg_w)
But there is no self._i2c_dev.close().

In my case this left 11 file handles to /dev/i2c-1 open on every call of the plugin script.
So the file handle needs to be closed somewhere...

Where is the best place in the lib to cleanup the connection?
As a quick and dirty solution I added a close()-call at line 90 after verified = []

@Gadgetoid
Copy link
Member

If a bus number is passed to SMBus then it will open the i2c device there and then, eg: SMbus(1), see: https://github.com/kplindegaard/smbus2/blob/3074717ff02fa5214fc5f1f0d2e5a2827583d6ba/smbus2/smbus2.py#L278-L279

However you are correct, the lib does not do any explicit cleanup of the connection since most use cases implicitly close it when Python itself is closed.

Python has a __del__ magic method, or "class destructor" for when classes go out of scope and are cleaned up. I don't know if it would suffice to close the device here, but it might be worth a try:

def __del__(self):
    self._i2c_dev.close()

This is probably something I should roll out across all of our libraries, since they are not currently well suited to being used in this manner- ie as part of a plugin that creates/destroys the class repeatedly- but they probably should be.

@Gadgetoid Gadgetoid added the bug Something isn't working label Oct 16, 2020
@Rayn0r
Copy link
Author

Rayn0r commented Oct 18, 2020

@Gadgetoid

With your suggested patch applied:

diff --git a/library/sgp30/__init__.py b/library/sgp30/__init__.py
index e458bd4..32619d9 100644
--- a/library/sgp30/__init__.py
+++ b/library/sgp30/__init__.py
@@ -173,3 +173,7 @@ class SGP30:

     def set_baseline(self, eco2, tvoc):
         self.command('set_baseline', eco2, tvoc)
+
+    def __del__(self):
+        self._i2c_dev.close()
+

the open file count to /dev/i2c-1 remains at 11 all the time.
So I'd say this cures the problem quite nicely.

Thank you very much.

Gadgetoid added a commit that referenced this issue Oct 20, 2020
Gadgetoid added a commit that referenced this issue Oct 28, 2020
@Gadgetoid
Copy link
Member

Fix in v0.0.2

@mansooralmansoob
Copy link

in this sensor i have problem
the sensor address
before i run a code gives me address 0x58 by using i2cdetect -y 1
and not gives me any reading except eco2 400ppm and tvo 0ppb
and when i chick address doesn't give 0x58
however this sensor run in correct manner for many times before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants