Search code examples
pythonalgorithmopencvraspberry-picamera

Calculate the estimated time of arrival (ETA) of the clouds by using Python?


I'm working in a project for a weather station but I got stuck in something which is the estimated time of arrival (ETA) so, I would like to also apply a method that estimates the arrival time of the clouds to a certain spot, for example, I will have a solar station and then there will be clouds but before they reach the solar station I want to calculate the estimated time of arrival to the station? It shouldn't be that accurate though.

Here is the data that I'm having currently.

From spot A to spot B >> 1km

Wind speed changes between >> 1.5 - 3.6 m/s

Here is the code for weather forecasting:

import pyowm
import os
from datetime import datetime
import warnings

warnings.filterwarnings("ignore", category=DeprecationWarning) 
APIKEY=''
OpenWMap=pyowm.OWM(APIKEY)
Weather=OpenWMap.weather_at_place('Location')
Data=Weather.get_weather()
Weatherforecast = OpenWMap.three_hours_forecast('Location')

date_time = datetime.now().strftime("%d %b %Y | %I:%M:%S")

print ("-------------------------------------------------------------")
print ("Weather Status for - Location || {}".format(date_time))
print ("-------------------------------------------------------------")

temp = Data.get_temperature(unit='celsius')
print ("Average Temp. Currently ", temp['temp'] , '°C')
print ("Max Temp. Currently ", temp['temp_max'], '°C')
print ("Min Temp. Currently ", temp['temp_min'], '°C')


humidity = Data.get_humidity()
print ("Humidity : ",humidity, '%')


wind = Data.get_wind()
print ("Wind Speed : ",wind['speed'], 'm/s')
print ("Wind Direction in Deg : ",wind['deg'],'°')


cloud = Data.get_clouds()
print ("Cloud Coverage Percentage : ",cloud, '%')

weatherstatus = Data.get_status()
weatherstatusdetailed = Data.get_detailed_status()
print ("Weather status : ",weatherstatus)
print ("Weather status with details :",weatherstatusdetailed)

rain=Weatherforecast.will_have_rain()
sun=Weatherforecast.will_have_sun()
cloud=Weatherforecast.will_have_clouds() 

print("There will be rain :",rain)
print("There will be sun :",sun)
print("There will be clouds :",cloud) 

I'm also using camera pi with OpenCV library to mask the clouds,

Here is the part of the cloud coverage which will indicate when the ETA calculation must start so when the percentage of the cloud coverage is 50% or more it will start. CODE:

# determine the cloud coverage
    cloud_pixels   = np.count_nonzero(inverted == 255)
    total_pixels   = result.size
    cloud_coverage = cloud_pixels / total_pixels

    # create a mask of where the clouds are
    cloud_image_mask = np.zeros(mask.shape, dtype=np.uint8)
    cloud_image_mask[mask] = inverted.flatten()

    print('Coverage is {:.3f}%'.format(cloud_coverage*100))
    print(datetime.now() - startTime)

    last_dot  = imagepath.rindex('.')
    save_path = imagepath[:last_dot] + '-mask' + imagepath[last_dot:]
    cv2.imwrite(save_path, cloud_image_mask)

    return(cloud_coverage)

And here is the code for the wind speed so it's changing every few minutes or hours and when it changes I want it to be applied. CODE:

wind = Data.get_wind()
print ("Wind Speed : ",wind['speed'], 'm/s')
print ("Wind Direction in Deg : ",wind['deg'],'°')

Here is the calculation math:

The simplified case is quite obvious:

  • The distance d is 1000m
  • the speed s is 3.6 to 1.5 m/s
  • ETA is in d/s = 278 to 667 seconds

Solution

  • This is just my solution to your problem, simplified however.

    while True:
        If cloud_coverage >= 0.5: # if the cloud coverage is 50% or greater
            eta = d/wind["speed"] # calculate the eta
    
        if abs(wind["speed"] - Data.get_wind()["speed"]) > variance_tolerance: 
        #if the absolute value of the difference between wind["speed"] and an updated wind speed 
        #is greater then the tolerance
            wind = Data.get_wind() #reassign the wind variable
            #recalculate d
            eta = d/wind["speed] #recalculate the eta