Meteorological visibility from a sensor?

I really like being able to build stuff with ESPHome and esp8266 devices. Now that DarkSky was bought by Apple, I need to look at building a weather station so I can collect my own data. However, one of the most valuable pieces of data that DarkSky gives me is a visibility value, the number of miles you can see or how clear the day is. It varies a lot in my area because of fog. I’m wondering if there’s some way to use sensors with an esp8266 to gather this data automatically.

Anyone know?

Interesting question. Yes I saw that Apple will close down the DarkSky API in end of 2021. First of all, do you really need to know visibility? I mean, what do you do based on that data? Genuine question :smiley:

Technically, I’m not sure how you would build such a sensor. I’m thinking you would need some kind of optical sensor, perhaps if you could use a telescope to view a well defined object some distance (miles or a few km) away (say a tree, or a light pole or similar), and have an ESP32 camera focussed on the telescope eyepiece you could maybe come up with some kind of relative measure of visibility. Sounds a bit out of reach for the trusty ESP devices though. I know Raspberry Pi have some OCR software (some people have used it to read the numbers off their water / electricity / gas meters with a camera), or your could use some AI library (tensorflow lite) running on an RPi to do the image processing.

I imagine the visibility data for big weather services is a manually entered bit of data - do you know?

Loosely related - I am currently experimenting with a sensor to measure cloudiness. For this I have connected a MLX90614 infrared sensor and point it to the sky. It measures the ambient temperature and the object temperature - in this case the sky’s temperature - and then I calculate the delta of the two temperatures. The theory is that the cloudier it is, the more equal the temperatures are and thus the smaller the delta, while on a clear day (or night) the sky temperature is very low and thus the delta is very large.
It’s work in progress, and I will post on this forum when I get it working more reliably.

1 Like

Actually, I have a set of external security cameras and I use the visibility info to decide if I should turn them off. If it’s foggy the cameras start triggering like crazy.

Good question, it might be manually entered. I dunno.

I like the idea of using tensor flow but I don’t have any experience with it. I should probably just hook that directly up to my camera array so it can detect it and disable themselves or not trigger in the first place.

Wow, this is a very interesting idea. I like checking these kinds of things out too. It seems like it should be able to detect fog. I’d love to see your progress with it if you’re able to make it work.

The visibility is a manual number.
It’s done by humans and only a rough number. You can see this number in METAR reports of a nearby airport.

However, reading what you need it for. Can’t you use a humidity sensor?
Fog is water and very humid so I assume the humidity in fog is very easy to “see” with a sensor.

Actually, that’s a good question. I’ll have to check the humidity sensor next time it’s foggy outside. I might be able to do that.

A cheap man’s version is to replicate fog in the shower.
Not 100% accurate but it will give you a start to see if it’s feasible.

But I’m quite sure fog means 100% humidity.
Perhaps you can look at historical data?

How have you connected the MLX90614?
How did you configure it in ESPHome (I assume)?

Yes, I use the MLX90614 with ESPHome via I2C. It’s a custom component until I find the time for a proper contribution.

mlx90614_sensor.h

#include "esphome.h"
#include <Wire.h>
#include "Adafruit_MLX90614.h"

#define TAG "mlx90614"

class MLX90614Sensor : public PollingComponent {

  public:
    Adafruit_MLX90614 mlx;

    Sensor *ambient_temperature_sensor = new Sensor();
    Sensor *object_temperature_sensor = new Sensor();

    MLX90614Sensor() : PollingComponent(15000) { }

    void setup() override {
      ESP_LOGCONFIG(TAG, "Setting up MLX90614Sensor...");
      mlx.begin();
      LOG_SENSOR("  ", "Ambient temperature", this->ambient_temperature_sensor);
      LOG_SENSOR("  ", "Object temperature", this->object_temperature_sensor);
    }

    void update() override {
      double ambient_temperature = mlx.readAmbientTempC();
      double object_temperature = mlx.readObjectTempC();

      ESP_LOGD(TAG, "Ambient temperature measured: %f", ambient_temperature);
      ESP_LOGD(TAG, "Object temperature measured: %f", object_temperature);

      ambient_temperature_sensor->publish_state(ambient_temperature);
      object_temperature_sensor->publish_state(object_temperature);
    }
};

And in your device configuration:

esphome:
  ...
  includes:
    - "mlx90614_sensor.h"
  libraries:
    - "Adafruit MLX90614 Library"

i2c:

sensor:
  - platform: custom
    lambda: |-
      auto mlx90614_sensor = new MLX90614Sensor();
      App.register_component(mlx90614_sensor);
      return {mlx90614_sensor->ambient_temperature_sensor, mlx90614_sensor->object_temperature_sensor};
    sensors:
      - name: "Ambient Temperature"
        unit_of_measurement: °C
        accuracy_decimals: 1
      - name: "Object Temperature"
        unit_of_measurement: °C
        accuracy_decimals: 1
2 Likes

This looks very interesting!
What kind of sensor did you buy.
I see they come in different shapes, one is just the sensor and another is the sensor on a board with what looks like smt capacitor or resistor(s).
How did you calibrate it, or was it good enough when you got it?

I’m using this type of breakout board:
MLX90614

It came “factory calibrated” and at least the ambient temperature seems to be good enough.

I couldn’t find that type here locally.
I found the same type (by the looks) on wish.com.

I found this type in a store in my country.


But sadly they both have a very long delivery time. So I bought them both, lets see which one wins…

Thank you for your help!

1 Like

thanks for your great code, I waited for a long time who made this custom components thx again !!

1 Like

I have finally got the first sensor.

Where do I place the mlx90614_sensor.h and the Adafruit MLX90614 Library?
I read through the custom sensor components page of ESPHome but I could not see where to place the files so that the compiler finds them.

It says:

First, create a new file called my_custom_sensor.h in your configuration directory and copy the source code from above into that file.

I can’t find configuration as a directory. I see config, where all the yaml files are (?).
But I can’t find anything about libraries, only that it should be added in the yaml, nothing about where to put it.

Yes, you have to put the .h file into the same directory as the .yaml file.

You don’t have to put the library anywhere. This should be downloaded as part of the build process automatically.

1 Like

Ahh… Thats clever…

Thanks.

Got it working. Kind of…
I mean, it could be correct. It is rather hot in here

image

Even if I disconnect it I get the same result. I will have to keep trying tomorrow.

Please have a look at my latest code update where I built in a filter that discards any values outside of the specified range: esphome-customisations/mlx90614 at master · exxamalte/esphome-customisations · GitHub

1 Like

Will do, but I doubt that is the problem.
I could not get a single value below this value.