Tasmota: veml6070 UV light sensor add UV Index Level

Created on 19 Sep 2018  路  26Comments  路  Source: arendst/Tasmota

Have you look for this feature in other issues and in the wiki?

  • Yes, also the closed one.

Is your feature request related to a problem? Please describe.
_A clear and concise description of what the problem is._

  • I'm talking about the sensor here in Figure 1.
    sensor
  • Base: Add VEML6070 support - https://github.com/arendst/Sonoff-Tasmota/issues/1053
  • I only get a raw UV value what i have to calculate everytime by hand.
    That costs me and possible others who use this sensor time to calculate
    the real UV Index Level when i/they look at the values on the sonoff-device
    web page or via an e.g. I2C O-Led display.
  • Tested it yesterday again because at noon we had a 100% clear sky with hot
    burning sun which is rare in the Netherlands. All the values where between
    2500..3800 which is not an UV Index Level.
    Figure 2: UV Index
    uv index

Describe the solution you'd like
_A clear and concise description of what you want to happen._

  • I would add the right calculation to the driver, clean it a little bit
    up and get it running. Tests will be done with three the same sensors
    on three different sonoff devices.

Describe alternatives you've considered
_A clear and concise description of any alternative solutions or features you've considered._

  • There are a lot of different calculation outside tasmota on the internet
    or github. I had invetigate now for three long days (google, github, books)
    to find the best possible solution to get a so precise as possible UV Level Index.

Additional context
_Add any other context or screenshots about the feature request here._

  • The library from Adafruit makes it easy as possible but the latest datasheet
    show some other ways to go into a solution. I will test three different ways
    which i have found iin real books and github.
  • Possible i need some help with the mqtt_data part in 'Veml6070Show'
    but for that i will ask when it's working so far.

(Please, remember to close the issue when the problem has been addressed)

enhancement

Most helpful comment

So PR is out.
Hopefully Theo has some time to look in it.
When PR is done i will let stay the issue open for two more days, then i will close it

All 26 comments

The data sheet from Vishay makes it clear the table lookup for the conversion is going to depend on the integration time (which Tasmota can probably figure out) and the value of the resistor that is on the board. This value would need to be provided to Tasmota, or assumed. If assumed, it will be wrong for some implementations. This means there should be storage allocated and a method provided to save and set and show the resistor value.

@Frogmore42
Your idea is a good one. On the other side it needs more memory and i think i know (i hope) Theo enough in my short time of tasmota that he would say: please don't do it, but i can be wrong.

@all
1st i have added a fixed table now by hand calculated based on three different books and a friend of mine. He is a professor and has helped me out to get it right in the first way. Now the calculation is based on that and it works like a charm with a solar light source which i could lean for two weeks now. Jesus that thing is fun with white and yellow leds. Looks very expensive and i have to handle it with great care.

What works now with a little help from andrethomas ;-) for a return value. Because i stood in the front of all trees in my garden but i could not see them.

  • uv raw value so as now in the base driver
  • uv index 0..11
  • uv power in 碌W/cm虏
    This is the start and all are calculated based on the integration time.
    But i was thinking again about all the values that can be shown on the webpage. Possible i will test some #defines to show different values. But for that i need some response from here...
    The resistor value can be added in the user_config like #define veml5070_advanced. Then a define for the resistor and last but not least take this into the calculation. But that means that the nice litte driver from Theo will explode when i take a look at the used memeory as driver.

Next about the IT time which is fixed on 500ms (IT4) and in wont change it. Why..

  • i have tested and written so many applications for sensors the last 25 years that all shorter IT times are horrable when it comes to light.
  • i had worked for code in a light laboratory with many different light sources and sensors. But yeah that is around 15 years ago and this sensor here the veml6070 was new for me. There is another one the veml6075 which can messaure the UV-A, UV-B and parts of the UV-C when the ozone layer is damaged, oops! Yes that is possible and i will add this to the driver by time. Need more books and hardware for that.

Next part is the suspend and wakeup issue. I have a report in my hands of the design team which was working for the mini satelite cubes which where let out of the ISS and fall back to earth. Some of them where designed to meassure light. That report is not public but on personal visits i can show him.
Please understand because i have signed a non disclosure.
What important is that the senosr has a short lifetime when it comes to 24/7 messaauring times. It is something inside the sensor what it makes him old while using.
Another point is when you using the sensor and cpu on Lipo battery you need to shut it down to spare power. But in this case it's the lifetime issue and how the production process of that PCB was done. The flor time of 168h based on MSL-3 according to J-STD-020 means that we don't know what is done with
that tiny little smd sensor friend. So go safe.

You can find that suspend and wakeup procedure in many projects on github for that sensor. So i will take a look at the report again what they say about the procedure and qill compare with the many different ways which are used outside tasmota.

Testing hardware:
3x Wemos D1 (not mini)
3x VEML6070, ordered in three different shops (ali express, local and Adafruit)

SO that麓s all for this time. And thanks for understanding about the longer text...

Short upadate over the progess. LIttle screenshot what is shown right now on the web page.
It's not the end a good start and more is comming.
Figure 1:
1st

TBD, upcomming version:

  • Suspend and wakeup.
  • The whole base caculation tabel will be changed to float because the precission.
    -- I have seen really wide spread of outcomming data and that can be better.
  • Value UV Level will have the short for increments (inc).
  • Value UV Level will possible renamed to UV RawData, UV Raw...
    -- Because it is not really a level in the word only increments, technical spoken.
    -- Here your ideas (all the users here) for the UV RawData are very welcome
  • Value UV Index will have very short text after the index number
    -- Low
    -- MOD means Moderate ("MODerate." Abbreviations.com. STANDS4 LLC, 2018. Web. 21 Sep. 2018. )
    -- High
    -- 2High means Very High
    -- Extreme, cane be Xtrm, XR, EXTRM, ext, ES extreme scale or EE extreme environment
    --- Ideas or a select from these terms are very welcome, based on www.allacronyms.com
  • Value UV Power, at the end where you see the 渭W/cm2. The 2 will be uppercase.

TBD, in later versions:

  • Rset is possible so as Frogmore42 asked for it.
    -- A #define USE_VEML6070_RSET 270 for 270K resistor, because i can add that to the calculation.
    --- So no storage needed all only a define, simple solution.
    -- Have found a way to do so but must be tested longer.
  • Add the VEML6075 UV-A and B sensor to the driver.
    -- Is not that much more on memory use because it's nearly the same way of working.

Nice progress! My suggestion for: Value UV Index
-- Low
-- Mid
-- High
-- Danger
-- Burn
Mybe you could color it: Low and Mid green, High yellow, Danger and Burn red

Maybe UV Power in mW/cm2 ?

My suggestion for UV Level -> UV Raw or just not showing in standard setup.

P.S. Should 4495 uW/cm2 not be a UV Index < 1 ?

@Jason2866
Very good ideas...
The UV Index text value will i take today in coding.
Love the way of thinking...simple and good.

The coloring is something what i tought about in the last night, but i could not figure
out how to do that in tasmota because there is no place in the web server to do so.
But i love the idea to have a little colored square or arrow what angles with the level.
I can be wrong, so then hit me, softly

  • about the 4495 it's just around 15% above index 1. Default calulation with fixed values is:
    -- raw/4 then check table, Theo has started with 500ms. Some sources say it's ~750 by 270K
    --- Everytime when you double the resistor (IT 0.5, 1, 2, 3) you double the output so you have to
    recalculate the values. With integers you lose things. About that i will switch to float.
    -- 899 is 4 times the IT0.5 = 899/4 = 224,75 (no float at the moment)
    -- then look in the table and it's just above 187 (float = 186,73) so it's index 1
    -- and by power (Vishey data sheet) it's: 5 渭W/cm2/step=increment 5*899 = 4495 渭W/cm2

There is a different calculation but that's depending on V++ and Rset and other conditions.

  • Normaly and that is what i will do is:
    -- define V++ and Rset. Then you can calculate the base of the table coefficient.

When you will messaure more sientific you need a complete different sensor.
Addional you must know the time of the year, current local time (GMT+i) and
and the angle (degrees) in which the sensor is directed to the sun and the view
angle of the sensor self. Further you need some other information and these
are given by the nearest goverment of aerospace institute. Further i have
the lastest uv calculation table from meteo.lcd.lu and www.iuva.org. Both are
well know in that sector.

So as i said: it's a 1st attemp to get more out of the sensor and there is a lot more.
But step by step otherwise the code writing will hang it selfs up in reading,
waiting, reading again and get lots of errors.

But i stay open for suggestions and think about the amount of drivers we have
and the needed space when more then one driver is active. E.g. for a very good
weather station you need possible 6 or 7 drivers. But i tink that is more a thing
for a stand alone esp8266 application.

So let it come and we discusse it here, i think. Good to know that there are some
poeple who thinking twice before eating ;-).

Addon:
I had messaured 30 minutes ago a value of 15155渭W/cm2, that is converted 0.015155W/m2
Then look in table which i added here. Not 100% but very near. So you are right about < 1
and i have to look again in the code. Possible some littel errors. But first i have to change to
float values to be shure that nothing is lost in calculations.
table

@Jason2866
So as i said i take the advise with me Jason. Thank You:

define D_UV_INDEX_1 "Low" // sun->fun

define D_UV_INDEX_2 "Mid" // sun->glases advised

define D_UV_INDEX_3 "High" // sun->glases a must

define D_UV_INDEX_4 "Danger" // sun->skin burns lite once

define D_UV_INDEX_5 "BurnL1/2" // sun->skin burns level 1..2

define D_UV_INDEX_6 "BurnL3" // sun->skin burns with level 3, autsch

define D_UV_INDEX_7 "Unknown" // out of range

The information behind the // comes from the medical information about sun issues

I saw it right now:
Maybe UV Power in mW/cm2 ?

  • Possible in W/m2 because it's the standard value which is used in aerospace things.

My suggestion for UV Level -> UV Raw or just not showing in standard setup.

  • ha, i had the same thought. Jesus we must code together ;-). Will add that define!

I read this article: https://de.wikipedia.org/wiki/UV-Index
and that was the reason for my suggest for mW/cm2

And YES if you go further a lot of math....
and to make it even more complicated you could use Latitude and Longitude for your calculations ;-)
They are already there...

@Jason2866
define USE_VEML6070_SHOW_RAW is done ;-).

-> I read this article: https://de.wikipedia.org/wiki/UV-Index
-> and that was the reason for my suggest for mW/cm2
I know that one and a good one but he tells not all.
And yes it looks like wrong, but not smaller. WHen you look
at the table for W/m2 it was to low. Possible i have to take the
raw value for the calculation and don't divide it. For the UV Index
i have to take the smaller one or change the calculation a little bit.
Take the raw and re-calculate and then divide and all in float.

But for this:
const char HTTP_SNS_UV_LEVEL[] PROGMEM = "%s{s}VEML6070 " D_UV_LEVEL "{m}%d " D_UNIT_INCREMENTS "{e}";

Have i to cahnge that to: "{m}%f " D_UNIT_INCREMENTS , right?
You know i have forgotten to much, so help in that is welcome.

The other things is:

ifdef USE_DOMOTICZ

  if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, uvlevel);

endif // USE_DOMOTICZ

  • that i have to build with more. But may i change the things where
    the constants comes from: DZ_ILLUMINANCE ?

-> and to make it even more complicated you could use Latitude and Longitude for your calculations ;-)
You are really a funny guy. Do you mean that i have nothing else todo? ;-)

  • But it is an idea which i will take with me.

He @mike2nl
you are right dont take me too serious :-)
And sorry for programing i cant help you. I am a programing noob! And that do i mean serious.

@Frogmore42 and @all
Short Update:
The VEML6070 is a very good and linear sensor based on the used technic.
Based on that i have now a base coefficiant for resistor input in the user_config.h
(must be in Ohm, not KiloOhm) to fill a UV-raw-value table automaticly with calculation
values for UV Index and UV power.

Will test this for the next two days. Hopefully we get some automatic in the first step.
Later we can use LATITUDE & LONGITUDE so as the angle of the mounted sensor.

Jesus what a lot of math work. ;-)

There will be math!

@all:
So more than a little update about the progress.

1st - Thank You to andrethomas about you hit me, softly ;-), to the right direction about Serial.print function. It was unknown for me in that range because in industrial automation you have tracing, profiling, debugging, watch, and monitor tools for variable checks. Much and big tools i used now for more then 25 years. So something new to learn. Thank's Andre!

Whats working right now:

  • Automaticly filling of the uv compare table based on Rset, Vishay and some other math.
    -- is that one unknown or not defined in the user_config, the 270K value will be used
    -- that all is based on a coefficient calculation done by hand with some deep learning hours with
    my good friend the professor. He works in the aerospace industrie. So Thank You R.G.T.
  • Now it is possible to show or NOT show the uv raw value defined in the user_config.
  • Furture define will be use of LAT and LONG for angle calculation. Found very interesting stuff.
  • The power calculation has to be redone now because with the veml6070 sensor we have precisely 0.3W/m2 by index level 12 (Vishay data sheet). Public level goes to 11 but laboratory and aerospace goes to level 14/15. that is now included.
  • Next step will be the suspend and wake-up procedure to spare power and lifetime of that little guy.
    -- Seen the UV-A emitting power it would be the top solution to have a moving shutter over the sensor (motor shield & a little servo). Menas that when the measure is starting, move the shutter away and wake up the sensor, wait some seconds, measure around 10 cycles (500ms * 10), close the shutter and suspend the sensor. Then the life span of the sensor goes until years. I cannot say how many years because it is never done in that way for DIY use. That information i got from the professor too.
  • Include of the version history so as in the mp3 player.
    -- I have sopken with so many people the last years, and seen the version history which Theo is using in the changelog, ->version information<- that i think it is some basic we all can do. Not log into a special system. The most basic part will be enough. Add some text in the header of every driver and everyone can follow the development process and you can see which driver you have.
    --- Ah there i get a thought about a web page..? Whith short information which drivers and which version is used? Or only a command for the console and no other place. Ah, what stupid thoughts i get the last days. ;-)

Some more information:
The sensor we use is not the best one. All these sensors who say they messaure the UV-A, UV-B or UV-C emitting values meeassure the light intesity. So we calculate, lets say over the thumb with the quatlity of these types of sensors. But when i compare the leaned UV source with the calculated values based on the coefficient, it looks good. Better then all the values given for public uv meters that you can buy on ebay, aliexpress or self for 100$ in the nearest shop.
A real Spektrorradometer costs you hundreds and self thousends of dollars. So be friendly to our little guy and me ;-) when the value sometimes shows something else then your nearest weather station tells you. I mean not the personal weather stations you can log into that weather information system, i mean the real once.
I wrote that i had worked some time in a light laboratory but never so deep as the things i have learned now the last 10 days. The math around all these things is not so high placed as i thought it was. It's simply some little more complexe arrays or '*'or '/'calculations. But very important it is Yoda says: to calculate all things first by hand and then you calculate it in reverse order to see in the sience right or you thoughts are wrong. That was the most eye opening part of the project until now.

  • The base driver written by arendst was a very good start for me. Thank You Theo. And when you look now in the code it looks so simple at the end but all the by hand work behind that where much hours of head burning calculations.

...more to come...

@all
I forgot the most interesting thing.
http://www.segurancaetrabalho.com.br/download/uv_index_karel_vanicek.pdf

That document is interesting for all you you because it describes many things around
UV Index. Found by a intensvie google search. There you will find why i have added
the index level 15 also and by advise from my friend.

In the updated driver all calculations are based on Karel Vanicek, forgot that to say, sorry.

Last Update i think:
All is working so far.
Suspend and wake up is added and tested with uA meter.
Last tests tomorrow morning with two settings in the user_config and then
update my fork from tasmota, add the new stuff and viola the PR gets out.

Hopefully Theo has then a little bit time to look at it.
A friend of mine in germany has tested now the last version an hour ago
and it works very well. So hold the thumb and possible i can close the
issue or better new ideas thread here in one or two days.

Great :+1:

So PR is out.
Hopefully Theo has some time to look in it.
When PR is done i will let stay the issue open for two more days, then i will close it

  • Theo has merged the updated driver with some comments.
  • I had to change the language files again because i forgot some defines, autsch.
    Yes that happens with copy and paste when the head is not free, right Andre?
    I fixed that to but Theo found something again . Put my head down ;-). He has
    fixed it fast. Thanks Theo.

  • About Theo's comments i first stood in the front of my garden trees agan. Nerver was
    so often there. But after some learning in other drivers and i think for right used functions:
    -- e.g. boolean Xsns08(byte function) and some others,
    i saw what he means. And yes a very good example of structured code. Have to read
    it and will change mine step by step to get it right so as meaned. So the trees are gone.
    Oops, more wood for the fireplace, ha, ha.

  • And i found the 1st bug, argh. When i use the O-Led display i got the UV Power only.
    I had the BME280 running too in a little rule script and saw what it was. By building the
    mqtt messages and apend to webserver there it goes wrong. Changed it really quick and
    dirty for a test and yes there was the aha moment. Will change these things too.
  • So i will let this topic/issue stay open a little bit longer until i have it.
  • Use of the sensor:
    when the UV Index comes to high call all family members back inside the house, then close
    and lock all doors automaticly, so nobody can go out ;-).

Use of the sensor:
when the UV Index comes to high call all family members back inside the house, then close
and lock all doors automaticly, so nobody can go out ;-).

LOL

@arendst
@andrethomas
@Jason2866
@ascillato

About the very well meaned comments of Theo i started to thinking and searching.
I had read the veml6070 driver again, against the
xsns_23_sdm120.ini
xsns_29_mcp230xx.ino
xsns_24_si1145.ino
xsns_32_MPU_6050.ino, also with the old function FUNC_PREP_BEFORE_TELEPERIOD

So then i have done some thinking again and some copy and paste and some text.
The number following in the text is one type of working with flow. There are different
ones yes, but i know that way very well, old military style. 40 years ago. Jesus i'm too old.

Here are my ideas and please hit me softly again when this is wrong, because i have nothing
found in the wiki. No document what descriped what we have todo and what not. Possible
is my lets say mistake a good start to have one document. So here it comes based on the
veml6070 driver.

  • New way of working

    define XSNS_24

boolean Xsns24(byte function)
{
boolean result = false;

if (i2c_flg) {
switch (function) {
case FUNC_INIT:
VEML6070Init();
break;
case FUNC_EVERY_SECOND:
VEML6070Update();
break;
case FUNC_JSON_APPEND:
VEML6070Show(1);
break;

ifdef USE_WEBSERVER

  case FUNC_WEB_APPEND:
    VEML6070Show(0);
    break;

endif // USE_WEBSERVER

}

}
return result;
}

  • In numbering form the flow looks like this:

1 In FUNC_INIT i call
1.1 Veml6070Detect();
1.2 return-break

2 In FUNC_EVERY_SECOND i call
2.1 Veml6070Update()
2.1.1 in Veml6070Update() i call
2.1.1.1 Veml6070ModeCmd(1) = wakeup
2.1.1.2 Veml6070Detect()
2.1.1.3 Veml6070ReadUv()
2.1.1.4 Veml6070UvRiskLevel(uvlevel)
2.1.1.5 Veml6070UvPower(uvrisk)
2.1.1.6 Veml6070ModeCmd(0) = suspend
2.1.2 return
2.2 return-break

3 in FUNC_JSON_APPEND i call
3.1 Veml6070Show(1)
3.2 return-break

4 in FUNC_WEB_APPEND i call
4.1 Veml6070Show(0)
4.2 return-break

So and now hit me with new ideas, wrong done idea and Theo you too please.
I know you have nearly no time but we need it. You have seen it on my msitake
and in that way possible everyone can learn something new. Possible a wiki page
with infos like mine. So go...

And now not all at the same time ;-)

Another point what not know:

  • If Veml6070Detect() everytime needed?

This is becoming a Sisyphus task....

You have it almost nailed down. I just want to add some more background.

In FUNC_INIT, only executed at startup the connected sensor is being detected and a detection flag (sensor_type) is set for future actions.

In the FUNC_EVERY_SECOND up to four actions can be performed:
1) if a sensor needs an action which takes a long time, like more than 100mS, the action will be started here for future follow-up. Using the uptime variable for testing like (uptime &1) will happen every 2 seconds. An example is the DS18B20 driver where readings (conversions they call it) can take up to 800mS from the initial request.
2) if a sensor needed the previous action it is now time to gather the information and store it in a safe place to be used by FUNC_JSON_APPEND and/or FUNC_WEB_APPEND. Using the else function of the previous test (uptime &1) will happen every 2 seconds too but just 1 second later than the previous action.
3) If a sensor does not respond for 10 times the sensor detection flag could be reset which will stop further processing until the sensor is re-detected. Currently I do not use this as some users complaint about loosing sensors for what ever reason.
4) here comes the redetect function in action. By executing this once every 100 seconds (94 == (uptime %100)) a re-attached sensor can be detected without a restart of Tasmota. The 94 should be different for every sensor driver to make sure not all sensors start detection at the same time. Using the drivers index number should be a good starting point.

I guess the main actions for now is to find out how long it takes for the sensor to present it's data once requested. If that takes more than 100mSec I suggest to start using the FUNC_EVERY_SECOND approach I documented above.

Phew, it's starting to look like your write-ups ;-)

BTW for better examples look at the low numbered sensor drivers as they were already un-FUNC_PREP_BEFORE_TELEPERIOD-ed. Sorry for the once you looked at. They are either not updated or use a very different way of doing things. I suggest to take a look at sensor drivers 05, 06, 07, 08, 09 and 10.

@arendst

Phew, it's starting to look like your write-ups

Not in vain - I was updating the sensor API and added some of your Sisyphus to it ;)

@arendst @Jason2866 @andrethomas @ascillato
Oh yeah, we come closer and closer.

Theo, you wrote:
-> I guess the main actions for now is to find out how long it takes for the sensor to present it's data once requested.

  • It takes not so much effort to find it out i think. Before or when the 1st request is done, copy the start time into a variable. when the data are arrived copy a second time and when the update of data incl. calculation is done copy the last time and calculate them from the firt time, and all done via serail.print and you are there i think. That time messaurent can stay in the code with a define for DEBUG_REQUEST_TIMING and later you can use it always again when you have to change things. Ah, will do some tests do get it out. Possible also a thing for the doument what i will write when this is over and it works so as expected to add it to the wiki to have something so that others so as me can work with. I found all possoble commands and will look further into it.

Thanks Theo, for the detailed information.

@mike2nl when you enable the debug tools there is a timing option available to measure how long the driver takes to provide info.

To use it needs another course though ;-).

Look for file xdrv_99_debug.ino.

Theo you wrote:
-> Phew, it's starting to look like your write-ups ;-)
Ha, ha , then you have not seen my code for the port in rotterdam.
There i have made a write-up, ha, ha.

@arendst
Hi Theo,
next write-up ;-)...
i had taken a deeper look in the xsns sensor drivers 05, 06, 07, 08, 09 and 10. It's about the FUNC_EVERY_SECOND case.

Some of the drivers using the index number 90, 91 and 92.
One of them uses no index number, he use: if (uptime &1) and one use: if (sht_type && !(uptime %4)).

  • About the drivers index number
    When i understand your posting right then the sensors index number is, as example here
    the xsns_11_veml6070.ino driver, sensor index number 11.
    But then not one of these drivers are using the right index number. I had searched for a sensor
    index define somewhere in the files in the sonoff directory and found nothing.
    So i think, in my eyes, the wrong used index number comes from the 1st PR. The user made a
    driver and had named it e.g. xsns_90_bh1750.ino and you merged it in the system with the right index number. Then it is a left over and must be changed and checked in every driver, right?

  • What looks good to me and it is 100% clear for me
    The xsns_10_bh1750.ino driver looks good to me when is see the code for FUNC_EVERY_SECOND.
    void Bh1750EverySecond()
    {
    if (90 == (uptime %100)) { !!! he uses the wrong index number too !!!
    // 1mS
    Bh1750Detect();
    .....if (!Bh1750Read()) {..

So he detects again in that case the sensor to be sure he is still there, OK.
And goes that wrong he writes an error - AddLogMissed, OK. Current max_miss is 5:

define SENSOR_MAX_MISS 5

So my index number is then 11, means for me then: if (11 == (uptime %100)) {

The rest is combine some code for calculation and go on to test used times to get data.
I had done that in version 1.0.0.1 already to see how much time i need for suspend and
wakeup. So that is not a big deal to find out what's going on

so, it looks like mit is done so far.
For the one who needs Domotica values, we have to talk about it. Please open then an issue.
Json and web server output so as needed:
"VEML6070":{"UvLevel":6212,"UvIndex":8.32,"UvIndexText":Danger,"UvPower":0.208}}

Tested it with an OLED display from 128x64 pixel with the driver for I2C.
And that works too with all values on screen.

From time to time i will put some updates. E.g. LAT and LONG calculations and with a little servo and two light intensity sensors we can calculate the angle too. But i think that goes a little bit to far.

So have fun and some feedback is allways welcome. And Thank You to the tasmota team for the help i needed to get some i stay in the front of the trees solution. So enough wood for the winter i have ;-).
And now i will close the issue.

Was this page helpful?
0 / 5 - 0 ratings