🤖 Jarvis 3/4: Conectando: Clima, Internet e Inteligência Artificial
🌐 Projeto CodeVerse Python – #46/2025
👋 Fala, galera dev! 🚀
Chegamos à terceira parte da fase final do nosso Projeto CodeVersePython2025, a montagem completa do J.A.R.V.I.S. Nos artigos anteriores (#44 e #45), criamos a base do nosso assistente: a voz, a interface visual (Tkinter) e os comandos locais para abrir programas, calcular e responder perguntas diretas. Mas agora é hora de ir além do desktop e conectar o nosso Jarvis ao mundo! 🌍
Neste artigo, vamos juntos adicionar integração com APIs reais e fazer o Jarvis se conectar à internet, acessar dados externos e responder com inteligência artificial. Com isso, ele poderá:
- Consultar o clima de qualquer cidade;
- Fazer pesquisas inteligentes com o Google Gemini;
- Criar respostas rápidas, naturais e personalizadas;
- E começar a se comportar como um verdadeiro assistente digital.
🦸 Vamos ver por uma outra perspectiva...
Lembra quando o Tony Stark diz “Jarvis, previsão do tempo para o voo”? E em segundos o sistema responde algo como “Céu limpo, ventos a 12 km/h, senhor”? Pois é exatamente essa funcionalidade que vamos buscar replicar aqui. Claro que não vaiser da mesma forma como o Tony Stark faz dentro de sua ramadura, afinal somos limitados em alguns requisitos, mas conseguimos deixar o mais proximo possível, e tudo através de código!
Nesse estágio, o Jarvis deixa de ser apenas um software que fala e ouve, ele passa a entender e processar informações do mundo real. Assim como o assistente de Stark consulta bancos de dados, redes e sensores, o nosso Jarvis usará APIs públicas e IA generativa para fazer o mesmo. Para nos trazer resposta a todas as perguntas que fizermos a ele, sim, ele terá resposta à tudo, através das APIs de previsão do tempo e de conexão com o google gemini.
🧠 O que vamos implementar neste artigo
Para essa terceira parte da montagem do projeto, vamos focar em três pilares principais que vamos adicionar ao código criado anteriormente, completandpo e juntando o restante das peças do quebra cabeças que aprendemos durante toda a jornada desse ano de 2025 neste newsletter semanal:
- 1️⃣ Integração com a API do OpenWeather → Permite consultar a temperatura e previsão do tempo de qualquer cidade. Apresentado com mais detalhes no artigo#31
- 2️⃣ Integração com a API do Google Gemini → Dá ao Jarvis o poder de pesquisar e responder perguntas com IA generativa. Apresentado com mais detalhes no artigo#32
- 3️⃣ Ampliação da estrutura de resposta → O Jarvis entenderá diferentes tipos de solicitações e retornará respostas faladas e visuais.
🐍 Entendo o Código...
Abaixo está o código desta etapa. Ele se conecta à internet, interpreta comandos de voz e responde com base nas informações retornadas pelas APIs. Preferi separar desta vez para que seja mais fácil de entender antes de juntarmos ao nosso código geral de nossa aplicação.
Sei também que eu poderia separar o código deste projeto por funções em arquivos diferentes para que seja mais fácil dar manutenção, aplicando boas práticas de produção de código, mas como é só um projeto experiemental, neste aqui, eu mantive tudo em um arquivo só. No próximo ano, irei dar continuidade a este projeto, dando maior robustez e modularizando as funções para adicionar novas funionalidades que estou pesquisando.
Mas vamos voltando a este código, vamos entender o que cada parte faz:
import requests
import google.generativeai as genai
import pyttsx3
import speech_recognition as sr
from datetime import datetime, timedelta
import random
# Inicializando componentes de voz e reconhecimento
engine = pyttsx3.init()
r = sr.Recognizer()
# Chaves das APIs
OPENWEATHER_KEY = "SUA_CHAVE_API_OPENWEATHER"
GEMINI_KEY = "SUA_CHAVE_API_GEMINI"
# Configuração da API Gemini
genai.configure(api_key=GEMINI_KEY)
def falar(texto):
engine.say(texto)
engine.runAndWait()
def obter_temperatura(cidade):
base_url = "http://api.openweathermap.org/data/2.5/weather?"
complete_url = base_url + "appid=" + OPENWEATHER_KEY + "&q=" + cidade
response = requests.get(complete_url)
if response.status_code == 200:
data = response.json()
temperatura = round(data["main"]["temp"] - 273.15, 1)
descricao = data["weather"][0]["description"]
return f"A temperatura em {cidade} é de {temperatura}°C com {descricao}."
else:
return "Desculpe, não consegui encontrar essa cidade."
def obter_previsao(cidade):
url_base = "http://api.openweathermap.org/data/2.5/forecast?"
url_completa = f"{url_base}appid={OPENWEATHER_KEY}&q={cidade}"
resposta = requests.get(url_completa)
if resposta.status_code == 200:
dados = resposta.json()
amanha = (datetime.now() + timedelta(days=1)).date()
previsao = [
item for item in dados["list"]
if datetime.fromtimestamp(item["dt"]).date() == amanha
]
temp = round(previsao[0]["main"]["temp"] - 273.15, 1)
descricao = previsao[0]["weather"][0]["description"]
return f"A previsão para amanhã em {cidade} é de {descricao}, com temperatura de {temp}°C."
else:
return "Não consegui obter a previsão, senhor."
def pesquisar_na_internet(pergunta):
regras = """
Responda como J.A.R.V.I.S., assistente do Tony Stark:
- Seja direto e educado.
- Use no máximo 30 palavras.
- Evite respostas vagas.
- Mantenha um toque levemente sarcástico.
"""
model = genai.GenerativeModel("gemini-2.5-flash")
chat = model.start_chat(history=[])
resposta = chat.send_message(regras + pergunta)
return resposta.text
def ouvir_comando():
with sr.Microphone() as source:
r.adjust_for_ambient_noise(source)
print("Ouvindo...")
audio = r.listen(source)
try:
comando = r.recognize_google(audio, language="pt-BR").lower()
return comando
except:
return ""
# Execução principal
falar("Sistema conectado, senhor. Estou pronto para consultas na internet.")
while True:
comando = ouvir_comando()
if "temperatura" in comando:
falar("Por favor, diga o nome da cidade.")
cidade = ouvir_comando()
clima = obter_temperatura(cidade)
falar(clima)
elif "previsão" in comando:
falar("Qual cidade deseja consultar?")
cidade = ouvir_comando()
previsao = obter_previsao(cidade)
falar(previsao)
elif "pesquisar" in comando:
pergunta = comando.replace("pesquisar", "").strip()
if not pergunta:
falar("Sobre o que deseja saber, senhor?")
pergunta = ouvir_comando()
resposta = pesquisar_na_internet(pergunta)
falar(resposta)
elif "encerrar" in comando or "desligar" in comando:
falar("Encerrando conexões, senhor. Até mais.")
break
elif comando:
respostas = [
"Desculpe, não encontrei essa informação.",
"Isso foge do meu protocolo atual.",
"Talvez o senhor queira reformular a pergunta.",
]
falar(random.choice(respostas))
🧩 Entendendo o código!
Vamos por partes, assim como Tony Stark desmontando o reator Arc. Vames demontar e dismistificar as partes desse código para que seja fácíl de entender, e caso queira saber em mais detalhes, veja o link dos artigos anterios que mostrei em detalhes a implementação dessas duas APIs.
- 🌦️ 1️⃣ OpenWeather API — O Sentido do Clima
A função obter_temperatura() conecta-se à API do OpenWeather, traduzindo dados meteorológicos brutos em frases compreensíveis. Ela converte a temperatura de Kelvin para Celsius e retorna uma frase como:
“A temperatura em São Paulo é de 26.5 graus com céu limpo.”
Já obter_previsao() faz algo parecido, mas coleta dados de previsão para o dia seguinte, simulando a resposta preditiva do Jarvis dos filmes.
- 💡 2️⃣ Google Gemini API — A Inteligência Artificial
A função pesquisar_na_internet() é o cérebro digital do assistente. Ela usa o modelo Gemini 1.5 Flash, da Google AI, para interpretar perguntas, gerar respostas inteligentes e falá-las com naturalidade. As “regras” no início definem o tom e a personalidade do Jarvis — direto, educado e um pouco sarcástico, como o original.
- 🗣️ 3️⃣ Loop de Comandos — A Conversa Viva
O loop principal escuta continuamente o microfone e identifica o tipo de comando:
- “Temperatura” → Chama a função de clima.
- “Previsão” → Obtém a previsão do tempo.
- “Pesquisar” → Faz uma pesquisa inteligente.
- “Encerrar” → Finaliza o assistente.
O restante das falas aleatórias mantém o tom humano e descontraído, evitando repetições robóticas. Mas antes de finalizarmos, vamos junatr essa parte de hoje ao nosso código criado anteriormente.
🐍 O Código em Ação — Versão Consolidada
Por fim, o Jarvis agora quase totalmente completo até esta fase (parte 3 de 4). Ele combina:
- Interface visual (Tkinter)
- Sistema de voz (pyttsx3 + SpeechRecognition)
- Comandos locais e automatizados
- Conexões externas com APIs e IA generativa
import os
import random
import time
import webbrowser
import tkinter as tk
from threading import Thread
from datetime import datetime, timedelta
import requests
import speech_recognition as sr
import pyttsx3
import google.generativeai as genai
class JarvisApp:
def __init__(self, root):
self.root = root
self.root.title("Jarvis - CodeVerse 2025")
self.root.geometry("220x200")
bg_color = "#0B3D2E"
fg_color = "#E6F2EF"
self.root.configure(bg=bg_color)
self.label = tk.Label(
root,
text="Assistente de Voz - J.A.R.V.I.S.",
bg=bg_color,
fg=fg_color,
font=("Helvetica", 9)
)
self.label.pack(pady=10)
# Círculo central (olho do Jarvis)
self.canvas = tk.Canvas(root, width=100, height=100, bg=bg_color, highlightthickness=0)
self.circle = self.canvas.create_oval(30, 30, 70, 70, outline="#00FFFF", width=5)
self.canvas.pack()
self.btn_iniciar = tk.Button(
root,
text="Iniciar Assistente",
command=self.iniciar_assistente,
bg=fg_color,
fg=bg_color,
font=("Helvetica", 9)
)
self.btn_iniciar.pack(pady=5)
self.running = False
self.speaking = False
def iniciar_assistente(self):
if not self.running:
self.running = True
thread = Thread(target=self.executar_assistente)
thread.start()
self.label.config(text="Assistente iniciado...")
def executar_assistente(self):
engine = pyttsx3.init()
r = sr.Recognizer()
# CHAVES DAS APIS
OPENWEATHER_KEY = "SUA_CHAVE_OPENWEATHER"
GEMINI_KEY = "SUA_CHAVE_GEMINI"
genai.configure(api_key=GEMINI_KEY)
# Funções auxiliares
def mudar_cor_circulo(cor):
self.canvas.itemconfig(self.circle, outline=cor)
def falar(texto):
mudar_cor_circulo("#00FF00")
engine.say(texto)
engine.runAndWait()
mudar_cor_circulo("#00FFFF")
def obter_temperatura(cidade):
base_url = "http://api.openweathermap.org/data/2.5/weather?"
complete_url = base_url + "appid=" + OPENWEATHER_KEY + "&q=" + cidade
response = requests.get(complete_url)
if response.status_code == 200:
data = response.json()
temp = round(data["main"]["temp"] - 273.15, 1)
descricao = data["weather"][0]["description"]
return f"A temperatura em {cidade} é de {temp}°C com {descricao}."
else:
return "Não consegui encontrar essa cidade, senhor."
def obter_previsao(cidade):
url = f"http://api.openweathermap.org/data/2.5/forecast?appid={OPENWEATHER_KEY}&q={cidade}"
response = requests.get(url)
if response.status_code == 200:
dados = response.json()
amanha = (datetime.now() + timedelta(days=1)).date()
previsao = [item for item in dados["list"] if datetime.fromtimestamp(item["dt"]).date() == amanha]
temp = round(previsao[0]["main"]["temp"] - 273.15, 1)
desc = previsao[0]["weather"][0]["description"]
return f"A previsão para amanhã em {cidade} é de {desc}, com temperatura de {temp}°C."
else:
return "Não consegui obter a previsão, senhor."
def pesquisar_na_internet(pergunta):
regras = """
Responda como J.A.R.V.I.S., assistente do Tony Stark:
- Seja direto e educado.
- Use no máximo 25 palavras.
- Mantenha o tom profissional e leve.
"""
model = genai.GenerativeModel("gemini-2.5-flash")
chat = model.start_chat(history=[])
resposta = chat.send_message(regras + pergunta)
return resposta.text
def apresentacao():
hora_atual = datetime.now().hour
if hora_atual < 12:
saudacao = "Bom dia"
elif hora_atual < 18:
saudacao = "Boa tarde"
else:
saudacao = "Boa noite"
falar(f"{saudacao}, senhor Carlos. Hoje é {datetime.now().strftime('%d/%m/%Y')}, "
f"são {datetime.now().strftime('%H:%M')}, {obter_temperatura('São Paulo')}. Me chamo Jarvis.")
self.label.config(text="Se precisar de mim, diga meu nome.")
falar("Se precisar de mim, diga meu nome, senhor.")
apresentacao()
while self.running:
with sr.Microphone() as source:
r.adjust_for_ambient_noise(source)
self.label.config(text="Ouvindo...")
audio = r.listen(source)
try:
comando = r.recognize_google(audio, language="pt-BR").lower()
print("Você disse:", comando)
if "jarvis" in comando:
respostas = [
"Sim, senhor?",
"Às ordens.",
"Estou aqui.",
"Pronto para ajudar."
]
falar(random.choice(respostas))
self.label.config(text="Aguardando comando...")
with sr.Microphone() as source:
audio = r.listen(source)
comando = r.recognize_google(audio, language="pt-BR").lower()
print("Comando:", comando)
# AÇÕES LOCAIS (ARTIGO #45)
if "abrir navegador" in comando:
os.system("start chrome.exe")
falar("Abrindo o navegador.")
elif "abrir calculadora" in comando:
os.system("start calc.exe")
falar("Abrindo a calculadora.")
elif "que horas são" in comando:
hora = datetime.now().strftime("%H:%M")
falar(f"Agora são {hora}.")
elif "que dia é hoje" in comando:
data = datetime.now().strftime("%d/%m/%Y")
falar(f"Hoje é {data}.")
# INTEGRAÇÕES (ARTIGO #46)
elif "temperatura" in comando:
falar("Qual cidade, senhor?")
with sr.Microphone() as source:
audio = r.listen(source)
cidade = r.recognize_google(audio, language="pt-BR")
falar(obter_temperatura(cidade))
elif "previsão" in comando:
falar("De qual cidade deseja saber?")
with sr.Microphone() as source:
audio = r.listen(source)
cidade = r.recognize_google(audio, language="pt-BR")
falar(obter_previsao(cidade))
elif "pesquisar" in comando:
assunto = comando.replace("pesquisar", "").strip()
if not assunto:
falar("Sobre o que deseja saber?")
with sr.Microphone() as source:
audio = r.listen(source)
assunto = r.recognize_google(audio, language="pt-BR")
falar("Um momento, pesquisando.")
resposta = pesquisar_na_internet(assunto)
falar(resposta)
elif "desligar" in comando:
falar("Encerrando o sistema. Até mais, senhor.")
self.running = False
break
else:
falar("Desculpe, não entendi o comando, senhor.")
except:
falar("Não consegui entender o que disse.")
root = tk.Tk()
app = JarvisApp(root)
root.mainloop()
⚙️ O que temos até aqui
Com essa versão consolidada, o Jarvis já é capaz de fazer quase tudo, faltando apenas executar comandos como salvar textos, abrir videos e playlists e memória temporária e permanete, mais isso vamos ver no próximo artigo:
- ✅ Falar e ouvir com precisão (speech-to-text e text-to-speech)
- ✅ Responder e reagir visualmente na interface Tkinter
- ✅ Executar comandos locais — abrir programas, informar hora e data
- ✅ Conectar-se à internet — buscar previsões e respostas inteligentes usando o modelo gemini-2.5-flash ou gemini-2.5-pro.
🔮 Conclusão
Chegamos a um ponto em que o Jarvis está praticamente completo. Agora ele fala, ouve, interage, executa comandos locais e busca informações online. Nos bastidores, você já montou uma estrutura modular e expansível, exatamente como um verdadeiro projeto de IA deve ser.
Um atento que devo citar aqui é que o modelo inicial que desenvolvi meu projeto, o gemini-1.5-flash não esta mais disponível e por isso tive de alterar as configurações incicias dos meus primeiros artigos. Outro adendo que faço aqui é que para deixar nossa aplicação mais fácil de entender não estou utilizando as melhroes formas de cotrole de fala e bibliotecas externas. Mas nos últimos artigos do ano, irei postar como esta ficando o meu projeto com todas as alterações que venho fazendo.
✅ No próximo e último artigo (#47), uniremos todas as peças restantes e assim finalizarmos nosso pequeno grande projeto que para mim, foi a realização de um sonho, poder criar algo que para mim, era tão distante e com um pouco de estudo consegui criar e apresnetar para toda a comunidade Dev. Mas por fim, no proximo artigo vamos ver:
- Sistema de playlists e música;
- Transcrição de voz para texto;
- Memória contextual e modo privado;
- E refinamentos finais para concluir o Jarvis 100% funcional.
“Não é sobre criar um assistente perfeito. É sobre criar um código que aprenda e evolua junto com você.” — CodeVerse Python 2025
Segue no LinkedIn e no GitHub para mais conteúdos como esse! Tmj!



