From a2fc96d4bf02ad2ba77d4bf399734e74c477089f Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Fri, 2 Aug 2024 08:34:07 +0200 Subject: [PATCH 1/5] Add tsl2561 light sensor --- README.md | 5 +- mqtt_io/modules/sensor/tsl2561.py | 107 ++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 mqtt_io/modules/sensor/tsl2561.py diff --git a/README.md b/README.md index 4e67401d..d8497fb5 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ Hardware support is provided by specific GPIO, Sensor and Stream modules. It's e - DHT11/DHT22/AM2302 temperature and humidity sensors (`dht22`) - DS18S20/DS1822/DS18B20/DS1825/DS28EA00/MAX31850K temperature sensors (`ds18b`) - ENS160 digital multi-gas sensor with multiple IAQ data (TVOC, eCO2, AQI) (`ens160`) + - FREQUENCYCOUNTER Counts pulses from GPIOs and return the frequency in Hz (`frequencycounterr`) + - FLOWSENSOR generic flow rate sensor like YF-S201, YF-DN50 or others (`flowsensor`) - HCSR04 ultrasonic range sensor (connected to the Raspberry Pi on-board GPIO) (`hcsr04`) - INA219 DC current sensor (`ina219`) - LM75 temperature sensor (`lm75`) @@ -45,9 +47,8 @@ Hardware support is provided by specific GPIO, Sensor and Stream modules. It's e - ADXl345 3-axis accelerometer up to ±16g (`adxl345`) - PMS5003 particulate sensor (`pms5003`) - SHT40/SHT41/SHT45 temperature and humidity sensors (`sht4x`) + - TLSl2561 light level sensor (`tsl2561`) - YF-S201 flow rate sensor (`yfs201`) - - FREQUENCYCOUNTER Counts pulses from GPIOs and return the frequency in Hz (frequencycounter) - - FLOWSENSOR generic flow rate sensor like YF-S201 or YF-DN50 (`flowsensor`) ### Streams diff --git a/mqtt_io/modules/sensor/tsl2561.py b/mqtt_io/modules/sensor/tsl2561.py new file mode 100644 index 00000000..a58c8e9a --- /dev/null +++ b/mqtt_io/modules/sensor/tsl2561.py @@ -0,0 +1,107 @@ +""" +TSL2561 luminosity sensor +""" +import threading + +from typing import cast + +from ...types import CerberusSchemaType, ConfigType, SensorValueType +from . import GenericSensor + +REQUIREMENTS = ("adafruit-circuitpython-tsl2561",) +CONFIG_SCHEMA: CerberusSchemaType = { + "chip_addr": dict(type="integer", required=False, empty=False, default=0x48), + "integration_time": dict( + required=False, + empty=False, + allowed=[13.7, 101, 402], + default=101, + ), + "gain": dict( + required=False, + empty=False, + allowed=[1, 16], + default=1, + ), +} + + +class Sensor(GenericSensor): + """ + Implementation of Sensor class for the Adafruit_ADS1x15. + """ + + SENSOR_SCHEMA: CerberusSchemaType = { + "type": dict( + type="string", + required=False, + empty=False, + allowed=["broadband", "infrared", "lux"], + default="lux", + ), + } + + def setup_module(self) -> None: + # pylint: disable=import-outside-toplevel,attribute-defined-outside-init + # pylint: disable=import-error,no-member + import board # type: ignore + import busio # type: ignore + import adafruit_tsl2561 + # Create the I2C bus + self.i2c = busio.I2C(board.SCL, board.SDA) + + # Convert sensor address from hex to dec + self.address = 57 + if self.config["chip_addr"] == 0x39: + self.address = 57 + elif self.config["chip_addr"] == 0x49: + self.address = 73 + elif self.config["chip_addr"] == 0x29: + self.address = 41 + + self.tsl = adafruit_tsl2561.TSL2561(self.i2c, self.address) + + + # Set gain 0=1x, 1=16x + if self.config["gain"] == 1: + self.tsl.gain = 0 + elif self.config["gain"] == 16: + self.tsl.gain = 1 + + # Set integration time (0=13.7ms, 1=101ms, 2=402ms, or 3=manual) + if self.config["integration_time"] == 13.7: + self.tsl.integration_time = 0 + elif self.config["integration_time"] == 101: + self.tsl.integration_time = 1 + elif self.config["integration_time"] == 402: + self.tsl.integration_time = 2 + + self.tsl.enabled = True + + #print("tsl2561 Enabled = {}".format(self.tsl.enabled)) + #print("tsl2561 Gain = {}".format(self.tsl.gain)) + #print("tsl2561 Integration time = {}".format(self.tsl.integration_time)) + + def get_value(self, sens_conf: ConfigType) -> SensorValueType: + import time + """ + Get the values from the sensor + """ + self.tsl.enabled = True # Enable sensor + time.sleep(1) + + sens_type = sens_conf["type"] + data = dict( + broadband=self.tsl.broadband, + infrared=self.tsl.infrared, + lux=self.tsl.lux + ) + if data[sens_type] is None: # Possible sensor underrange or overrange. + data[sens_type] = -1 + + self.tsl.enabled = False # Disable for energy savings + + return cast( + float, + data[sens_type], + ) From 017478b02b4bbc0dd922d247770c3b92a99d6d5f Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Mon, 5 Aug 2024 05:59:12 +0200 Subject: [PATCH 2/5] fix pylint issues --- mqtt_io/modules/sensor/tsl2561.py | 62 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/mqtt_io/modules/sensor/tsl2561.py b/mqtt_io/modules/sensor/tsl2561.py index a58c8e9a..273c3dc8 100644 --- a/mqtt_io/modules/sensor/tsl2561.py +++ b/mqtt_io/modules/sensor/tsl2561.py @@ -1,8 +1,6 @@ """ TSL2561 luminosity sensor """ -import threading - from typing import cast from ...types import CerberusSchemaType, ConfigType, SensorValueType @@ -10,19 +8,23 @@ REQUIREMENTS = ("adafruit-circuitpython-tsl2561",) CONFIG_SCHEMA: CerberusSchemaType = { - "chip_addr": dict(type="integer", required=False, empty=False, default=0x48), - "integration_time": dict( - required=False, - empty=False, - allowed=[13.7, 101, 402], - default=101, - ), - "gain": dict( - required=False, - empty=False, - allowed=[1, 16], - default=1, - ), + "chip_addr": { + "type": 'integer', + "required": False, + "empty": False, + "default": '0x48'}, + "integration_time": { + "required": False, + "empty": False, + "allowed": [13.7, 101, 402], + "default": 101, + }, + "gain": { + "required": False, + "empty": False, + "allowed": [1, 16], + "default": 1, + }, } @@ -32,13 +34,13 @@ class Sensor(GenericSensor): """ SENSOR_SCHEMA: CerberusSchemaType = { - "type": dict( - type="string", - required=False, - empty=False, - allowed=["broadband", "infrared", "lux"], - default="lux", - ), + "type": { + "type": 'string', + "required": False, + "empty": False, + "allowed": ['broadband', 'infrared', 'lux'], + "default": 'lux', + }, } def setup_module(self) -> None: @@ -83,24 +85,18 @@ def setup_module(self) -> None: #print("tsl2561 Integration time = {}".format(self.tsl.integration_time)) def get_value(self, sens_conf: ConfigType) -> SensorValueType: - import time """ Get the values from the sensor """ - self.tsl.enabled = True # Enable sensor - time.sleep(1) - sens_type = sens_conf["type"] - data = dict( - broadband=self.tsl.broadband, - infrared=self.tsl.infrared, - lux=self.tsl.lux - ) + data = { + "broadband": self.tsl.broadband, + "infrared": self.tsl.infrared, + "lux": self.tsl.lux + } if data[sens_type] is None: # Possible sensor underrange or overrange. data[sens_type] = -1 - self.tsl.enabled = False # Disable for energy savings - return cast( float, data[sens_type], From 503a44b529ce6012e795117c8af5c6439ed25dca Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Mon, 5 Aug 2024 06:02:59 +0200 Subject: [PATCH 3/5] fix pylint issues --- mqtt_io/modules/sensor/tsl2561.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mqtt_io/modules/sensor/tsl2561.py b/mqtt_io/modules/sensor/tsl2561.py index 273c3dc8..bbd5f229 100644 --- a/mqtt_io/modules/sensor/tsl2561.py +++ b/mqtt_io/modules/sensor/tsl2561.py @@ -6,7 +6,7 @@ from ...types import CerberusSchemaType, ConfigType, SensorValueType from . import GenericSensor -REQUIREMENTS = ("adafruit-circuitpython-tsl2561",) +REQUIREMENTS = ("adafruit-circuitpython-tsl2561",) # type: ignore CONFIG_SCHEMA: CerberusSchemaType = { "chip_addr": { "type": 'integer', From e4636bc73f73d4af8c528b2e83f34a2696c01321 Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Mon, 5 Aug 2024 06:11:25 +0200 Subject: [PATCH 4/5] fix pylint issues --- mqtt_io/modules/sensor/tsl2561.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mqtt_io/modules/sensor/tsl2561.py b/mqtt_io/modules/sensor/tsl2561.py index bbd5f229..615ef05f 100644 --- a/mqtt_io/modules/sensor/tsl2561.py +++ b/mqtt_io/modules/sensor/tsl2561.py @@ -6,7 +6,7 @@ from ...types import CerberusSchemaType, ConfigType, SensorValueType from . import GenericSensor -REQUIREMENTS = ("adafruit-circuitpython-tsl2561",) # type: ignore +REQUIREMENTS = ("adafruit-circuitpython-tsl2561",) CONFIG_SCHEMA: CerberusSchemaType = { "chip_addr": { "type": 'integer', @@ -48,7 +48,7 @@ def setup_module(self) -> None: # pylint: disable=import-error,no-member import board # type: ignore import busio # type: ignore - import adafruit_tsl2561 + import adafruit_tsl2561 # type: ignore # Create the I2C bus self.i2c = busio.I2C(board.SCL, board.SDA) @@ -63,7 +63,6 @@ def setup_module(self) -> None: self.tsl = adafruit_tsl2561.TSL2561(self.i2c, self.address) - # Set gain 0=1x, 1=16x if self.config["gain"] == 1: self.tsl.gain = 0 @@ -85,15 +84,22 @@ def setup_module(self) -> None: #print("tsl2561 Integration time = {}".format(self.tsl.integration_time)) def get_value(self, sens_conf: ConfigType) -> SensorValueType: - """ - Get the values from the sensor - """ + # pylint: disable=import-outside-toplevel,attribute-defined-outside-init + # pylint: disable=import-error,no-member + import time + + self.tsl.enabled = True + time.sleep(1) + sens_type = sens_conf["type"] data = { "broadband": self.tsl.broadband, "infrared": self.tsl.infrared, "lux": self.tsl.lux } + + self.tsl.enabled = False + if data[sens_type] is None: # Possible sensor underrange or overrange. data[sens_type] = -1 From fcf823eda21ce0a29c04cf0e7572af21de457596 Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Fri, 9 Aug 2024 18:34:07 +0200 Subject: [PATCH 5/5] Code CleanUp --- mqtt_io/modules/sensor/tsl2561.py | 34 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/mqtt_io/modules/sensor/tsl2561.py b/mqtt_io/modules/sensor/tsl2561.py index 615ef05f..dd13c387 100644 --- a/mqtt_io/modules/sensor/tsl2561.py +++ b/mqtt_io/modules/sensor/tsl2561.py @@ -53,29 +53,28 @@ def setup_module(self) -> None: self.i2c = busio.I2C(board.SCL, board.SDA) # Convert sensor address from hex to dec - self.address = 57 - if self.config["chip_addr"] == 0x39: - self.address = 57 - elif self.config["chip_addr"] == 0x49: - self.address = 73 - elif self.config["chip_addr"] == 0x29: - self.address = 41 + self.address = int(0x48) + if 'chip_addr' in self.config: + self.address = int(self.config['chip_addr']) self.tsl = adafruit_tsl2561.TSL2561(self.i2c, self.address) # Set gain 0=1x, 1=16x - if self.config["gain"] == 1: - self.tsl.gain = 0 - elif self.config["gain"] == 16: - self.tsl.gain = 1 + gains = { + "1": 0, + "16": 1, + } + if 'gain' in self.config: + self.tsl.gain = gains[str(self.config["gain"])] # Set integration time (0=13.7ms, 1=101ms, 2=402ms, or 3=manual) - if self.config["integration_time"] == 13.7: - self.tsl.integration_time = 0 - elif self.config["integration_time"] == 101: - self.tsl.integration_time = 1 - elif self.config["integration_time"] == 402: - self.tsl.integration_time = 2 + ints = { + "13.7": 0, + "101": 1, + "402": 2, + } + if 'integration_time' in self.config: + self.tsl.integration_time = ints[str(self.config["integration_time"])] self.tsl.enabled = True @@ -87,7 +86,6 @@ def get_value(self, sens_conf: ConfigType) -> SensorValueType: # pylint: disable=import-outside-toplevel,attribute-defined-outside-init # pylint: disable=import-error,no-member import time - self.tsl.enabled = True time.sleep(1)