Skip to content

Commit

Permalink
Merge branch 'develop' into veml7700
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjiU committed Sep 2, 2024
2 parents 408ae5c + 57b1b21 commit 110ab37
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 103 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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, YF-DN50 or others (`flowsensor`)
- 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`)
Expand Down
18 changes: 10 additions & 8 deletions mqtt_io/modules/sensor/flowsensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
sensor_inputs:
- name: flow_rate1
module: flowsensor
module: yfs201
pin: 0
digits: 0
interval: 10
Expand Down Expand Up @@ -45,7 +45,7 @@ class FLOWSENSOR:
Multiple instances support multiple sensors on different pins
"""

def __init__(self, gpiozero, name: str, pin: int) -> None: # type: ignore[no-untyped-def]
def __init__(self, gpiozero, name: str, pin: int) -> None: # type: ignore[no-untyped-def]
self.name = name
self.pin = gpiozero.DigitalInputDevice(pin)
self.pin.when_activated = self.count_pulse
Expand Down Expand Up @@ -75,7 +75,7 @@ def flow_rate(self, sample_window: int, factor: float) -> float:

def get_value(self, interval: int, factor: float) -> float:
"""Return flow rate in L/min over interval seconds and reset count."""
flow_rate = self.flow_rate(interval,factor)
flow_rate = self.flow_rate(interval, factor)
self.reset_count()
return flow_rate

Expand All @@ -87,20 +87,20 @@ class Sensor(GenericSensor):

SENSOR_SCHEMA: CerberusSchemaType = {
"pin": {
"type": 'integer',
"type": "integer",
"required": True,
"empty": False,
},
"interval": {
"type": 'integer',
"type": "integer",
"required": True,
"empty": False,
},
"factor": {
"type": 'float',
"type": "float",
"required": True,
"empty": False,
}
},
}

def setup_module(self) -> None:
Expand All @@ -117,4 +117,6 @@ def setup_sensor(self, sens_conf: ConfigType) -> None:
self.sensors[sensor.name] = sensor

def get_value(self, sens_conf: ConfigType) -> SensorValueType:
return self.sensors[sens_conf["name"]].get_value(sens_conf["interval"],sens_conf["factor"])
return self.sensors[sens_conf["name"]].get_value(
sens_conf["interval"], sens_conf["factor"]
)
107 changes: 107 additions & 0 deletions mqtt_io/modules/sensor/tsl2561.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""
TSL2561 luminosity sensor
"""
from typing import cast

from ...types import CerberusSchemaType, ConfigType, SensorValueType
from . import GenericSensor

REQUIREMENTS = ("adafruit-circuitpython-tsl2561",)
CONFIG_SCHEMA: CerberusSchemaType = {
"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,
},
}


class Sensor(GenericSensor):
"""
Implementation of Sensor class for the Adafruit_ADS1x15.
"""

SENSOR_SCHEMA: CerberusSchemaType = {
"type": {
"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 # type: ignore
# Create the I2C bus
self.i2c = busio.I2C(board.SCL, board.SDA)

# Convert sensor address from hex to dec
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
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)
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

#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:
# 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

return cast(
float,
data[sens_type],
)
90 changes: 90 additions & 0 deletions mqtt_io/modules/sensor/veml6075.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""
VEML 6075 UV sensor
"""

import logging
from mqtt_io.types import ConfigType, SensorValueType
from . import GenericSensor

REQUIREMENTS = ("smbus2", "veml6075",)

CONFIG_SCHEMA = {
"i2c_bus_num": {"type": "integer", "required": True, "empty": False},
}


# UV COEFFICIENTS AND RESPONSIVITY
# More details here :
# https://web.archive.org/web/20190416120825/http://www.vishay.com/docs/84339/designingveml6075.pdf
# For more details
##################################################################################
# Configuration # a # b # c # d # UVAresp # UVBresp #
##################################################################################
# No teflon (open air) # 2.22 # 1.33 # 2.95 # 1.74 # 0.001461 # 0.002591 #
# 0.1 mm teflon 4.5 mm window # 2.22 # 1.33 # 2.95 # 1.74 # 0.002303 # 0.004686 #
# 0.1 mm teflon 5.5 mm window # 2.22 # 1.33 # 2.95 # 1.74 # 0.002216 # 0.005188 #
# 0.1 mm teflon 10 mm window # 2.22 # 1.33 # 2.95 # 1.74 # 0.002681 # 0.004875 #
# 0.25 mm teflon 10 mm window # 2.22 # 1.33 # 2.95 # 1.74 # 0.002919 # 0.009389 #
# 0.4 mm teflon 10 mm window # 2.22 # 1.17 # 2.95 # 1.58 # 0.004770 # 0.006135 #
# 0.7 mm teflon 10 mm window # 2.22 # 1.17 # 2.95 # 1.58 # 0.007923 # 0.008334 #
# 1.0 mm teflon 5.5 mm window # 2.55 # 1.00 # 3.80 # 1.10 # 0.006000 # 0.003100 #
##################################################################################

_LOG = logging.getLogger(__name__)


class Sensor(GenericSensor):
"""
Implementation of Sensor class for the VEML 6075 UV sensor.
"""

SENSOR_SCHEMA = {
"a": {"type": "float", "required": False, "empty": False, "default": 2.22},
"b": {"type": "float", "required": False, "empty": False, "default": 1.33},
"c": {"type": "float", "required": False, "empty": False, "default": 2.95},
"d": {"type": "float", "required": False, "empty": False, "default": 1.74},
"UVAresp": {"type": "float", "required": False, "empty": False, "default": 0.001461},
"UVBresp": {"type": "float", "required": False, "empty": False, "default": 0.002591},
}

def setup_module(self) -> None:
# pylint: disable=import-outside-toplevel,import-error
from smbus2 import SMBus # type: ignore
from veml6075 import VEML6075 # type: ignore

self.bus = SMBus(self.config["i2c_bus_num"])
self.sensor = VEML6075(i2c_dev=self.bus)
self.sensor.set_shutdown(True)
self.sensor.set_high_dynamic_range(False)
self.sensor.set_integration_time('100ms')
self.sensor.set_shutdown(False)


def calculate_uv_index(self, sens_conf: ConfigType, \
uva: float, uvb: float, uv_comp1: float, uv_comp2: float) -> float:

"""
Calculate the UV index from received values.
"""

_LOG.debug("UVA: %f UVB: %f UV_comp1: %f UV_comp2: %f)", uva, uvb, uv_comp1, uv_comp2)
uva_calc = uva - (sens_conf["a"] * uv_comp1) - (sens_conf["b"] * uv_comp2)
uvb_calc = uvb - (sens_conf["c"] * uv_comp1) - (sens_conf["d"] * uv_comp2)
_LOG.debug("uva_calc: %f uvb_calc: %f", uva_calc, uvb_calc)
uva_index = uva_calc * sens_conf["UVAresp"]
uvb_index = uvb_calc * sens_conf["UVBresp"]
_LOG.debug("uva_index: %f uvb_index: %f", uva_index, uvb_index)
uv_index: float = (uva_index + uvb_index) / 2.0
return uv_index

def get_value(self, sens_conf: ConfigType) -> SensorValueType:
"""
Get the UV index from the sensor
"""

# Fetch the values
uva, uvb = self.sensor.get_measurements()
uv_comp1, uv_comp2 = self.sensor.get_comparitor_readings()

# Calculate and return the UV index
return self.calculate_uv_index(sens_conf, uva, uvb, uv_comp1, uv_comp2)
94 changes: 0 additions & 94 deletions mqtt_io/modules/sensor/yfs201.py

This file was deleted.

0 comments on commit 110ab37

Please sign in to comment.