From ec071c879201f3215599f1056d3b9c9a3535e2fc Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Sat, 10 Aug 2024 08:06:56 +0200 Subject: [PATCH 1/3] Add VEML7700 Light Level Sensor --- README.md | 5 +- mqtt_io/modules/sensor/veml7700.py | 106 +++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 mqtt_io/modules/sensor/veml7700.py diff --git a/README.md b/README.md index 4e67401d..ee977f7c 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`) + - FLOWSENSOR generic flow rate sensor like YF-S201 or YF-DN50 (`flowsensor`) + - FREQUENCYCOUNTER Counts pulses from GPIOs and return the frequency in Hz (frequencycounter) - 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`) + - VEML7700 light level sensor (`veml7700`) - 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/veml7700.py b/mqtt_io/modules/sensor/veml7700.py new file mode 100644 index 00000000..e01eb252 --- /dev/null +++ b/mqtt_io/modules/sensor/veml7700.py @@ -0,0 +1,106 @@ +""" +VEML7700 luminosity sensor +""" +from typing import cast + +from ...types import CerberusSchemaType, ConfigType, SensorValueType +from . import GenericSensor + +REQUIREMENTS = ("adafruit-circuitpython-veml7700",) +CONFIG_SCHEMA: CerberusSchemaType = { + "chip_addr": { + "type": 'integer', + "required": False, + "empty": False, + "default": '0x10'}, + "integration_time": { + "required": False, + "empty": False, + "allowed": [25, 50, 100, 200, 400, 800], + "default": 25, + }, + "gain": { + "required": False, + "empty": False, + "allowed": [0.125, 0.25, 1, 2], + "default": 0.125, + }, +} + + +class Sensor(GenericSensor): + """ + Implementation of Sensor class for the Adafruit_VEML7700 + """ + + SENSOR_SCHEMA: CerberusSchemaType = { + "type": { + "type": 'string', + "required": False, + "empty": False, + "allowed": ['light', 'lux', 'lux_corrected'], + "default": 'lux_corrected', + }, + } + + 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_veml7700 # type: ignore + # Create the I2C bus + self.i2c = busio.I2C(board.SCL, board.SDA) + + # Convert sensor address from hex to dec + self.address = int(0x10) + if self.config["chip_addr"]: + self.address = int(self.config["chip_addr"]) + + self.veml7700 = adafruit_veml7700.VEML7700(self.i2c, self.address) + + # Set gain + gains = { + "0.125": 'ALS_GAIN_1_8', + "0.25": 'ALS_GAIN_1_4', + "1": 'ALS_GAIN_1', + "2": 'ALS_GAIN_2', + } + if 'gain' in self.config: + self.veml7700.light_gain = getattr(self.veml7700, gains[str(self.config['gain'])]) + + # Set integration time + ints = { + "25": 'ALS_25MS', + "50": 'ALS_50MS', + "100": 'ALS_100MS', + "200": 'ALS_200MS', + "400": 'ALS_400MS', + "800": 'ALS_800MS', + } + if 'integration_time' in self.config: + self.veml7700.light_integration_time = getattr(self.veml7700, ints[str(self.config['integration_time'])]) + + #print("veml7700 Gain = {}".format(self.veml7700.light_gain)) + #print("veml7700 Integration time = {}".format(self.veml7700.light_integration_time)) + + def get_value(self, sens_conf: ConfigType) -> SensorValueType: + # pylint: disable=import-outside-toplevel,attribute-defined-outside-init + # pylint: disable=import-error,no-member + sens_type = sens_conf["type"] + data = { + "light": self.veml7700.light, + "lux": self.veml7700.lux, + "lux_corrected": "-1", + } + + # Correction formula according to https://www.vishay.com/docs/84323/designingveml7700.pdf for lux > 1000 + if data['lux'] > 1000: + data['lux_corrected'] = (6.0135e-13 * data['lux'] ** 4) + (-9.3924e-9 * data['lux'] ** 3) + (8.1488e-5 * data['lux'] ** 2) + (1.0023 * data['lux']) + else: + data['lux_corrected'] = data['lux'] + + return cast( + float, + data[sens_type], + ) From 7b64dc75b5ea70ea70eab70926dc98b1339b4151 Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Sat, 10 Aug 2024 12:01:28 +0200 Subject: [PATCH 2/3] Fix pylint errors --- mqtt_io/modules/sensor/veml7700.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mqtt_io/modules/sensor/veml7700.py b/mqtt_io/modules/sensor/veml7700.py index e01eb252..9a3c537a 100644 --- a/mqtt_io/modules/sensor/veml7700.py +++ b/mqtt_io/modules/sensor/veml7700.py @@ -79,7 +79,8 @@ def setup_module(self) -> None: "800": 'ALS_800MS', } if 'integration_time' in self.config: - self.veml7700.light_integration_time = getattr(self.veml7700, ints[str(self.config['integration_time'])]) + self.veml7700.light_integration_time = getattr(self.veml7700, + ints[str(self.config['integration_time'])]) #print("veml7700 Gain = {}".format(self.veml7700.light_gain)) #print("veml7700 Integration time = {}".format(self.veml7700.light_integration_time)) @@ -94,11 +95,11 @@ def get_value(self, sens_conf: ConfigType) -> SensorValueType: "lux_corrected": "-1", } - # Correction formula according to https://www.vishay.com/docs/84323/designingveml7700.pdf for lux > 1000 if data['lux'] > 1000: - data['lux_corrected'] = (6.0135e-13 * data['lux'] ** 4) + (-9.3924e-9 * data['lux'] ** 3) + (8.1488e-5 * data['lux'] ** 2) + (1.0023 * data['lux']) - else: - data['lux_corrected'] = data['lux'] + data['lux_corrected'] = (6.0135e-13 * data['lux'] ** 4) + \ + (-9.3924e-9 * data['lux'] ** 3) + \ + (8.1488e-5 * data['lux'] ** 2) + \ + (1.0023 * data['lux']) return cast( float, From 408ae5c524e8f0f124d5f0fd953e02d0c745df27 Mon Sep 17 00:00:00 2001 From: Michael Schlenstedt Date: Mon, 19 Aug 2024 06:52:33 +0200 Subject: [PATCH 3/3] Set lux_corrected if < 1000; corrected Readme --- README.md | 5 +++-- mqtt_io/modules/sensor/veml7700.py | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ee977f7c..d8779aa4 100644 --- a/README.md +++ b/README.md @@ -38,8 +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`) - - FLOWSENSOR generic flow rate sensor like YF-S201 or YF-DN50 (`flowsensor`) - - FREQUENCYCOUNTER Counts pulses from GPIOs and return the frequency in Hz (frequencycounter) + - FLOWSENSOR generic flow rate sensor like YF-S201, YF-DN50 or others (`flowsensor`) + - FREQUENCYCOUNTER Counts pulses from GPIOs and return the frequency in Hz (`frequencycounterr`) - HCSR04 ultrasonic range sensor (connected to the Raspberry Pi on-board GPIO) (`hcsr04`) - INA219 DC current sensor (`ina219`) - LM75 temperature sensor (`lm75`) @@ -47,6 +47,7 @@ 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`) - VEML7700 light level sensor (`veml7700`) - YF-S201 flow rate sensor (`yfs201`) diff --git a/mqtt_io/modules/sensor/veml7700.py b/mqtt_io/modules/sensor/veml7700.py index 9a3c537a..ea1baebc 100644 --- a/mqtt_io/modules/sensor/veml7700.py +++ b/mqtt_io/modules/sensor/veml7700.py @@ -100,6 +100,8 @@ def get_value(self, sens_conf: ConfigType) -> SensorValueType: (-9.3924e-9 * data['lux'] ** 3) + \ (8.1488e-5 * data['lux'] ** 2) + \ (1.0023 * data['lux']) + else: + data['lux_corrected'] = data['lux'] return cast( float,