Tutorial: Unir dados do sensor com dados de previsão do tempo usando o Azure Notebooks (Python)

A energia eólica é uma fonte de energia alternativa para os combustíveis fósseis para combater as alterações climáticas. Como o vento não é consistente por natureza, os operadores de energia eólica precisam construir modelos de aprendizado de máquina (ML) para prever a capacidade de energia eólica. Esta previsão é necessária para satisfazer a procura de eletricidade e garantir a estabilidade da rede. Neste tutorial, explicamos como os dados de previsão do tempo do Azure Maps são combinados com dados de demonstração para leituras meteorológicas. Os dados da previsão do tempo são solicitados ligando para os serviços meteorológicos do Azure Maps.

Neste tutorial, vai:

  • Crie e execute um Jupyter Notebook no VS Code.
  • Carregue dados de demonstração do arquivo.
  • Chame as APIs REST do Azure Maps em Python.
  • Renderize dados de localização no mapa.
  • Enriqueça os dados de demonstração com os dados meteorológicos da Previsão Diária do Azure Maps.
  • Plotar dados de previsão em gráficos.

Nota

O arquivo do notebook Jupyter para este projeto pode ser baixado do repositório do Weather Maps Jupyter Notebook.

Pré-requisitos

Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.

Nota

Para obter mais informações sobre autenticação no Azure Maps, consulte gerenciar autenticação no Azure Maps.

Instalar pacotes de nível de projeto

O projeto EV Routing and Reachable Range tem dependências nas bibliotecas python aiohttp e IPython . Você pode instalá-los no terminal do Visual Studio usando pip:

pip install aiohttp
pip install ipython
pip install pandas

Abrir o Jupyter Notebook no Visual Studio Code

Faça o download e abra o Bloco de Anotações usado neste tutorial:

  1. Abra o arquivo weatherDataMaps.ipynb no repositório AzureMapsJupyterSamples no GitHub.

  2. Selecione o botão Baixar arquivo raw no canto superior direito da tela para salvar o arquivo localmente.

    Uma captura de tela mostrando como baixar o arquivo do Notebook chamado weatherDataMaps.ipynb do repositório GitHub.

  3. Abra o Bloco de Anotações baixado no Visual Studio Code clicando com o botão direito do mouse no arquivo e selecionando Abrir com > o Visual Studio Code ou por meio do VS Code File Explorer.

Carregue os módulos e estruturas necessários

Depois que o código for adicionado, você poderá executar uma célula usando o ícone Executar à esquerda da célula e a saída será exibida abaixo da célula de código.

Execute o script a seguir para carregar todos os módulos e estruturas necessários.

import aiohttp
import pandas as pd
import datetime
from IPython.display import Image, display

Uma captura de tela mostrando como baixar a primeira célula no Bloco de Anotações contendo as instruções de importação necessárias com o botão Executar realçado.

Importar dados meteorológicos

Este tutorial usa leituras de dados meteorológicos de sensores instalados em quatro turbinas eólicas diferentes. Os dados da amostra consistem em 30 dias de leituras meteorológicas. Estas leituras são recolhidas a partir de centros de dados meteorológicos perto de cada local da turbina. Os dados de demonstração contêm leituras de dados para temperatura, velocidade do vento e, direção. Você pode baixar os dados de demonstração contidos no weather_dataset_demo.csv do GitHub. O script abaixo importa dados de demonstração para o Bloco de Anotações do Azure.

df = pd.read_csv("./data/weather_dataset_demo.csv")

Solicitar dados de previsão diária

Em nosso cenário, gostaríamos de solicitar uma previsão diária para cada local do sensor. O script a seguir chama a API de Previsão Diária dos serviços meteorológicos do Azure Maps. Esta API devolve a previsão meteorológica para cada turbina eólica, para os próximos 15 dias a partir da data atual.

subscription_key = "Your Azure Maps key"

# Get a lists of unique station IDs and their coordinates 
station_ids = pd.unique(df[['StationID']].values.ravel())
coords = pd.unique(df[['latitude','longitude']].values.ravel())

years,months,days = [],[],[]
dates_check=set()
wind_speeds, wind_direction = [], []

# Call azure maps Weather services to get daily forecast data for 15 days from current date
session = aiohttp.ClientSession()
j=-1
for i in range(0, len(coords), 2):
    wind_speeds.append([])
    wind_direction.append([])
    
    query = str(coords[i])+', '+str(coords[i+1])
    forecast_response = await(await session.get("https://atlas.microsoft.com/weather/forecast/daily/json?query={}&api-version=1.0&subscription-key={Your-Azure-Maps-Subscription-key}&duration=15".format(query, subscription_key))).json()
    j+=1
    for day in range(len(forecast_response['forecasts'])):
            date = forecast_response['forecasts'][day]['date'][:10]
            wind_speeds[j].append(forecast_response['forecasts'][day]['day']['wind']['speed']['value'])
            wind_direction[j].append(forecast_response['forecasts'][day]['day']['windGust']['direction']['degrees'])
            
            if date not in dates_check:
                year,month,day= date.split('-')
                years.append(year)
                months.append(month)
                days.append(day)
                dates_check.add(date)
            
await session.close()

O script a seguir renderiza os locais da turbina no mapa chamando o serviço Obter Imagem de Mapa.

# Render the turbine locations on the map by calling the Azure Maps Get Map Image service
session = aiohttp.ClientSession()

pins="default|la-25+60|ls12|lc003C62|co9B2F15||'Location A'{} {}|'Location B'{} {}|'Location C'{} {}|'Location D'{} {}".format(coords[1],coords[0],coords[3],coords[2],coords[5],coords[4], coords[7],coords[6])

image_response = "https://atlas.microsoft.com/map/static/png?subscription-key={Your-Azure-Maps-Subscription-key}&api-version=1.0&layer=basic&style=main&zoom=6&center={},{}&pins={}".format(subscription_key,coords[7],coords[6],pins)

static_map_response = await session.get(image_response)

poi_range_map = await static_map_response.content.read()

await session.close()

display(Image(poi_range_map))

Uma captura de tela mostrando os locais das turbinas em um mapa.

Agrupe os dados de previsão com os dados de demonstração com base no ID da estação. O ID da estação é para o centro de dados meteorológicos. Este agrupamento aumenta os dados de demonstração com os dados de previsão.

# Group forecasted data for all locations
df = df.reset_index(drop=True)
forecast_data = pd.DataFrame(columns=['StationID','latitude','longitude','Year','Month','Day','DryBulbCelsius','WetBulbFarenheit','WetBulbCelsius','DewPointFarenheit','DewPointCelsius','RelativeHumidity','WindSpeed','WindDirection'])

for i in range(len(station_ids)):
    loc_forecast = pd.DataFrame({'StationID':station_ids[i], 'latitude':coords[0], 'longitude':coords[1], 'Year':years, 'Month':months, 'Day':days, 'WindSpeed':wind_speeds[i], 'WindDirection':wind_direction[i]})
    forecast_data = pd.concat([forecast_data,loc_forecast], axis=0, sort=False)
    
combined_weather_data = pd.concat([df,forecast_data])
grouped_weather_data = combined_weather_data.groupby(['StationID'])

A tabela a seguir exibe os dados históricos e de previsão combinados para um dos locais da turbina.

# Display data for first location
grouped_weather_data.get_group(station_ids[0]).reset_index()

Dados agrupados

Plotar dados de previsão

Plote os valores previstos em relação aos dias para os quais eles estão previstos. Este gráfico permite-nos ver as mudanças de velocidade e direção do vento para os próximos 15 dias.

# Plot wind speed
curr_date = datetime.datetime.now().date()
windsPlot_df = pd.DataFrame({ 'Location A': wind_speeds[0], 'Location B': wind_speeds[1], 'Location C': wind_speeds[2], 'Location D': wind_speeds[3]}, index=pd.date_range(curr_date,periods=15))
windsPlot = windsPlot_df.plot.line()
windsPlot.set_xlabel("Date")
windsPlot.set_ylabel("Wind speed")
#Plot wind direction 
windsPlot_df = pd.DataFrame({ 'Location A': wind_direction[0], 'Location B': wind_direction[1], 'Location C': wind_direction[2], 'Location D': wind_direction[3]}, index=pd.date_range(curr_date,periods=15))
windsPlot = windsPlot_df.plot.line()
windsPlot.set_xlabel("Date")
windsPlot.set_ylabel("Wind direction")

Os gráficos a seguir visualizam os dados de previsão. Para a mudança da velocidade do vento, veja o gráfico à esquerda. Para a mudança na direção do vento, consulte o gráfico à direita. Estes dados são previstos para os próximos 15 dias a partir do dia em que os dados são solicitados.

Uma captura de tela mostrando gráficos de velocidade do vento.

Uma captura de tela mostrando gráficos de direção do vento.

Neste tutorial, você aprendeu a chamar APIs REST do Azure Maps para obter dados de previsão do tempo. Você também aprendeu a visualizar os dados em gráficos.

Para explorar as APIs do Azure Maps usadas neste tutorial, consulte:

Para obter uma lista completa das APIs REST do Azure Maps, consulte APIs REST do Azure Maps.

Próximos passos