Open nirkons opened 5 years ago
Hi, i got the sensor working using the Custom Sensor Tutorial.
First you need to create the file "tsl2591.h" in your ESPHome directory. The content of "tsl2591. h" should be:
#include "esphome.h"
#include "Adafruit_TSL2591.h"
class Tsl2591 : public PollingComponent, public Sensor {
public:
// constructor
Tsl2591() : PollingComponent(15000) {}
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);
void setup() override {
if (!tsl.begin())
{
ESP_LOGD("ERROR","Could not find a TSL2591 Sensor. Did you configure I2C?");
}
tsl.setGain(TSL2591_GAIN_LOW); //We use the lowest possible gain.
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); //We use the longest possible Integration Time for accurate Results.
//For more details on Gain and Integration Time see the Adafruit Repository for the TSL2591 Sensor
}
void update() override {
uint16_t x = tsl.getLuminosity(TSL2591_VISIBLE); //We only measure the visible light
publish_state(x);
}
};
We also need to make sure all dependencys of our code are fulfilled. Our code uses the Adafruit TSL2591 Library which can be installed using pio lib install "Adafruit TSL2591 Library"
. We also need to install the Adafruit Unified Sensor Library pio lib install "Adafruit Unified Sensor"
.
Now we can create the configuration file for our sensor node. Make sure to include the dependencies:
esphome:
includes:
- tsl2591.h
libraries:
- "Adafruit TSL2591 Library"
Add the Sensor (I added a filter which doesnt publish measurements that are zero, because the sensor would occasionally report zero when it got to bright):
sensor:
- platform: custom
lambda: |-
auto my_sensor = new Tsl2591();
App.register_component(my_sensor);
return {my_sensor};
sensors:
name: "TSL2591 Brightness"
unit_of_measurement: lux
filters:
- filter_out: 0
Also make sure to use and configure the i2c component according to your device. (Example for ESP8266/Wemos D1 Mini Pro)
i2c:
sda: 4
scl: 5
Feel free to message me if something is unclear. English is not my first language.
Thank you for this. Helped me getting it working. I have 2 of these sensors. One works perfectly and the other one now and then shoots to 65535 lux when it is dark and the middle of the night. Any reason why it would do that ?
Thank you @NotaLabs for your very helpful guide. I'm confused by this step pio lib install "Adafruit TSL2591 Library"
- where do I run it from? Is it within HASS.IO somehow?
My installation follows this very helpful guide https://gist.github.com/frenck/32b4f74919ca6b95b30c66f85976ec58 and runs hass.io on Ubuntu 18.04.1 LTS
Apologies if this is documented somewhere - I've not been able to find it.
Hi @RGN01,
like the commands provided in your guide, you should be able to run my commands in the Linux terminal. pio is short for plattformio and is the framework that esphome uses. By running pio lib install "Adafruit TSL2591 Library"
the librarys get installed by plattformio and can be used by esphome.
Unfortunately that didn't work. Running it from the Ubuntu console gave errors and I ebentually tried the --global optionm which installed it but it did not work in HASS.IO
I also tried a terminal option on HASSIO direct but that will not work either.
I'll keep trying
If you running esphome as an addon to hassio, you would need to run it within the esphome container. That is how I got it to work. Unfortunately it seems that you need to re run it everytime you restart if you want to make changes.
Thank you @w1tw0lf - please could you explain how you "run it within the esphome container" Is that via the hassio front end?
Apologies for the questions but I'm very confused about this at the moment.
@OttoWinter, it would be great if this could be included into the mainstream esphome at some time please.
@RGN01 Installed portainer with in the terminal of Ubuntu:
sudo docker run -dit --restart unless-stopped -d -p 8000:8000 -p 9999:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
Once installed accessed portainer via http://"Ubuntu ip":9999 and connected to the console of the esphome container. Run this from the console:
platformio lib --global install "Adafruit TSL2591 Library" && platformio lib --global install "Adafruit Unified Sensor"
Thank you so much, @w1tw0lf - I really appreciate the help!
Fantastic - that seems to have installed. Now to test the esphome code.
OK, it has compiled so now to test. Again, @w1tw0lf I just want to say how grateful I am - this morning I was considering using an Arduino for the tsl2591 and then using MQTT or serial UART to send the data to my esphome node! This is SOO much more elegant and I have you to thank.
Pleasure @RGN01 not my hard work. Just guiding you in the right direction.
Just as fyi, added a filter for 65535 as mentioned for 0 and solved the issue as well.
Thanks again - I have done that!
Thank you for this guide. Like @RGN01 i'm a little bite confused with the commands. I run hass.io on virtual box so i'm not sure if the same solution apply. Any help would be appreciated
@smnlevesque if you have the addon running via hass.io for esphome, just follow my guide here: https://github.com/esphome/feature-requests/issues/267#issuecomment-578031579
For reference: I was able to install the library by logging into my HassOS supervisor using these instructions.
After logging in as root and using the login
command, you can find your esphome container and log into it:
docker exec -it `docker ps | grep esphome | awk '{print $1}'` /bin/bash
Once you've successfully logged into the container, you can install the libraries as described above:
platformio lib --global install "Adafruit TSL2591 Library" && platformio lib --global install "Adafruit Unified Sensor"
I want to clear something up here
None of that platformio lib install
is not required.
Adding the library to the libraries
var in the esphome:
section will already install the library in the project. If that's not the case, it's an error and please report it.
Hello, could you please help me with the similar Waveshare TSL2581 sensor ?
FWIW, I had to include a minimal spi
definition even though I am not using SPI at all. Otherwise, compilation failed looking for SPI.h
.
My TSL2591 arrived today, and this custom sensor implementation worked first time. Thanks @nirkons!
That's right before I learned that platform: custom
doesn't support update_interval
. (While experimenting with the sensor, I have to wait 15s for each fresh value.) I opened feature request #782 to ask for it. [Edit: I later realized that the polling interval is given in the superclass constructor in tls2591.h. I didn't notice that before.]
FWIW, I had to include a minimal
spi
definition even though I am not using SPI at all. Otherwise, compilation failed looking forSPI.h
.
I'm trying to get it to work following @OttoWinter advice above and have an SPI error so please could you share what you mean by "minimal 'spi' definition'?
Much appreciated.
could you share what you mean by "minimal 'spi' definition'?
I used a block like this (at the same YAML level as my i2c:
block). Since I wasn't actually using SPI, I just picked some GPIO numbers that I wasn't using for anything. I don't know if that matters, so later I looked up the actual pin numbers for my board and used them.
spi:
clk_pin: 12
miso_pin: 13
I started with just the spi:
line, and the helpful error messages in the esphome dashboard config editor told me what config items I still needed. I stopped when it stopped complaining. :-)
Thank you - that was very helpful. I did the same but as I'm using an ESP-01 there are not many spare pins so I ended up with the following, which seems to work OK!
spi:
clk_pin: GPIO1
mosi_pin: GPIO1
miso_pin: GPIO1
My config. Calculate "TRUE" full luminocity value but Im not sure about Visible & Infrared
esphome\tsl2591.h
#include "esphome.h"
#include "Adafruit_TSL2591.h"
class Tsl2591 : public PollingComponent, public Sensor {
public:
// constructor
Tsl2591(uint8_t channel) : PollingComponent(60000) {
Channel = channel;
}
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);
uint8_t Channel;
void setup() override {
ESP_LOGD("tsl2591","Setup");
if (!tsl.begin())
{
ESP_LOGD("ERROR","Could not find a TSL2591 Sensor. Did you configure I2C?");
}
//tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light)
tsl.setGain(TSL2591_GAIN_MED); // 25x gain
//tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); //We use the longest possible Integration Time for accurate Results.
//For more details on Gain and Integration Time see the Adafruit Repository for the TSL2591 Sensor
}
void update() override {
uint32_t lum = tsl.getFullLuminosity();
uint16_t ir, full;
ir = lum >> 16;
full = lum & 0xFFFF;
uint32_t lux;
switch(Channel)
{
case TSL2591_VISIBLE: // = 2
// lux = tsl.calculateLux(full - ir, 0);
ESP_LOGD("tsl2591","===> Luminocity: %d x (Raw, Visible)", full - ir);
publish_state(full - ir);
break;
case TSL2591_INFRARED: // = 1
// lux = tsl.calculateLux(ir, 0);
ESP_LOGD("tsl2591","===> Luminocity Raw: %d x (Raw, Infrared)", ir);
publish_state(ir);
break;
default: // Full: // = 0
lux = tsl.calculateLux(full, ir);
ESP_LOGD("tsl2591","===> Luminocity: %d Lux (Corrected, Full)", lux);
publish_state(lux);
break;
}
}
};
esphome\nodemcu_v3_01.yaml
esphome:
name: nodemcu_v3_01
platform: ESP8266
board: nodemcuv2
includes:
- tsl2591.h
libraries:
- "Adafruit TSL2591 Library"
# it seems that working well without this ????
# i2c:
# sda: D2
# scl: D1
# spi:
# clk_pin: GPIO1
# mosi_pin: GPIO1
# miso_pin: GPIO1
sensor:
- platform: custom
lambda: |-
auto visible = new Tsl2591(TSL2591_VISIBLE);
App.register_component(visible);
auto infrared = new Tsl2591(TSL2591_INFRARED);
App.register_component(infrared);
auto full = new Tsl2591(0);
App.register_component(full);
return {visible, infrared, full};
sensors:
- name: "NodeMcuV3.01 TSL2591 Visible Lux"
unit_of_measurement: x
icon: mdi:brightness-5
filters:
- filter_out: 65535
- name: "NodeMcuV3.01 TSL2591 Infrared Lux"
unit_of_measurement: x
icon: mdi:brightness-5
filters:
- filter_out: 65535
- name: "NodeMcuV3.01 TSL2591 Lux"
unit_of_measurement: lux
icon: mdi:brightness-5
filters:
- filter_out: 65535
Hi, i got the sensor working using the Custom Sensor Tutorial.
First you need to [...]
I can confirm above instructions work like a charm. Would be great to get official ESPHome support for this sensor, though.
For reference this is the code I am using
#include "esphome.h"
#include "Adafruit_TSL2591.h"
class Tsl2591 : public PollingComponent, public Sensor {
public:
Tsl2591() : PollingComponent(1000) {}
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591);
void setup() override {
if (!tsl.begin())
{
ESP_LOGD("ERROR","Could not find a TSL2591 Sensor. Did you configure I2C?");
}
tsl.setGain(TSL2591_GAIN_MED);
tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);
}
void update() override {
uint32_t full = tsl.getFullLuminosity();
uint16_t ch0 = full & 0xffff;
uint16_t ch1 = full >> 16;
float lux = tsl.calculateLux(ch0, ch1);
publish_state(lux);
}
};
I've just submitted PRs for adding TSL2591 support to ESPHome. You should see the links just above this comment. If you are able and willing, feel free to take that for a spin. If you hit problems, let me know. (If you comment in this thread, I will see it.)
A couple of notes about some things mentioned in this thread.
I re-implemented the integration to use ESPHome I2C instead of the Adafruit library. That eliminates the faux transitive dependency on SPI and also provides some other ESPHome I2C benefits. Those changes are reflected in the current state of the PRs mentioned above.
I had been using the Adafruit library for about a year without realizing it had built into it a big delay (600ms) when taking a reading. Luckily, my ESP8266 only had 2 pollable sensor components, so the delay didn't matter. But it's a pretty big delay if you have other stuff on your ESP device. I did some stuff to deal with that in my code changes. If you are interested, you can read about it these commit comments: https://github.com/esphome/esphome/pull/2131/commits/babb9a389e1e6f1730c45c4d927846a979818a4c
Thank you @wjcarpenter
updated to the beta that was release and moved over to the TSL2591 support through ESPHome. All look good so far. No issues from me on this.
Only thing I had to do was change
glass_attenuation_factor: 14.4
to
glass_attenuation_factor: 28.8
from the example, as it was halving the lux reading I had before. In otherwords, where I use to get a reading of 100 lux it was giving me 50 lux.
That's unexpected. With the default values of 53 for device factor and 7.7 for glass attenuation factor, the calculated lux should come out to about the same values as the Adafruit library. (There is a small difference if you are using high or max gain values, on the order of less than 10% difference.)
~But I can see now I've got some misplaced parentheses in my calculation. I'll correct that.~
No, I take it back. Double-checking, I see that my calculation does match the Adafruit calculation.
So now I'm not too sure why you saw what you saw, w1tw0lf. The 14.4 in the example was just an example. The default is 7.7. It would make sense if you said you needed to divide 14.4 in half, but not doubling it.
FYI, following a suggestion from @oxan, I modified the code to use set_interval
to take readings with power save mode. (Actually, always, but it only matters for power save mode.) So, you can safely use power save mode (the default) without impacting the global ESPHome update loop.
@wjcarpenter clean built after making changes and not seeing any changes. Lux reporting same results as just before.
@wjcarpenter here is a screenshot of the past 8 hours.
white: old way shared here.
red: glass_attenuation_factor @ 14.4
green: glass_attenuation_factor @ 28.8
Thanks for following up. I've been looking at the code a bit and still haven't spotted why it would be that different in the lux calculation. But, at least you have a workaround. I'm glad I decided to expose those 2 factors as config items.
I apologize for posting well over a year after the last comment, but I wasn't sure this warranted a new issue/feature request.
I've been using the TSL2591 Sensor Component (https://esphome.io/components/sensor/tsl2591.html) for a while and it has been working well. My only inquiry is to why the active gain being used in "auto" mode isn't published as a value by the component.
When transitioning between extremes (very dark, to very bright or vice-versa) the auto gain mode appears to function correctly; however, without a "gain" readout for what is being used to determine the raw values/lux, it can create a misleading situation where a low light level reads as higher than a high light level.
As far as I can tell, without publishing the component's current gain for readings, relative brightness/values can become rather meaningless when the component is set to auto gain.
Is there a reason this isn't exposed, or can this component be updated to publish the active gain when set to "auto"?
That's a good question. What you've said makes sense. The "auto" gain was not in the original support for the component but was added later by another developer. Even though you were hesitant, I think you should open another issue, as a bug or a feature request, so it gets better attention. Anybody who has the time and inclination could add emitting that value.
went ahead and opened an issue: https://github.com/esphome/issues/issues/4031
Thanks!
Describe the problem you have/What new integration you would like
The TSL2561 is currently supported, however it is discontinued (by adafruit at least) and replaced by the TSL2591. Please describe your use case for this integration and alternatives you've tried:
LUX measurements Additional context
thanks