image

Accede a bootcamps ilimitados y a más de 650 cursos para siempre

75
%OFF
Article image
Carlos CGS
Carlos CGS17/11/2025 07:35
Compartir

🤖 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.

    image

    🔮 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!

    image

    Compartir
    Recomendado para ti
    CAIXA - Inteligência Artificial na Prática
    Binance - Blockchain Developer with Solidity 2025
    Neo4J - Análise de Dados com Grafos
    Comentarios (0)