Electrónica y Programación en Personal
«Si no se soluciona con un script en Python entonces no es viable»

por Yeison Cardona el 19 de marzo del 2014 a las 2:07 am UTC

Un proyecto similar ya lo he hecho, hace mas de un año, el cual ya no es funcional, Pinguino se ha actualizado mucho luego de eso, así que quise en un momento rehacer la entrada y actualizar el código.

Twitter

Objetivo

El objetivo es poder controlar una tarjeta Pinguino conectada a un computador con acceso a internet, mediante comandos enviados vía mensajes directos (DMs), para hacer un poco mas simple la interacción, enviaremos comandos como los usados en el IDE, es decir pinMode(13,OUTPUT) o digitalWrite(13,HIGH), entonces dicha acción se ejecutará en Pinguino (donde sea que esté).

Será necesario crear una cuenta para Pinguino, de la cual leerá los DMs, entonces es a ésta cuenta a la cual enviaremos los comandos desde cualquier otra cuenta.

Software necesario

  • Python (obviamente, que no sé usar otra cosa)
  • TweePy módulo Python para conectarse con Twitter
  • Pynguino módulo Python para interfazar Pinguino de manera sencilla
Suponiendo que estamos todos en GNU/Linux, bastaría con ejecutar (luego de tener instalado pip)
$ pip install tweepy pynguino

Preparando Pinguino

Primero debemos compilar y cargar en Pinguino el siguiente código:
para 8 bits:


para 32 bits:

Ahora Pinguino debe de estar conectado al computador y si todo va saliendo bien deberíamos de ver un dispositivo serial conectado, lo podemos verificar ejecutando:

$ ls /dev/ttyACM*
/dev/ttyACM0

El siguiente paso sería asegurarnos de conceder permisos de lectura y escritura a este puerto, entonces:

$ sudo chmod a+rw /dev/ttyACM0

Ahora vamos a hacer una prueba con Python y Pynguino, si recordarán, Pynguino es un módulo que desarrollé hace mucho tiempo, en el próximo post hablaré de él, por ahora no le prestaremos mayor importancia.
Desde el shell de Python:

>>> from pynguino import PynguinoCDC
>>> 
>>> pinguino = PynguinoCDC()
>>> pinguino.pinMode(0, "OUTPUT")
>>>
>>> pinguino.digitalWrite(0, "HIGH")
>>> pinguino.digitalWrite(0, "LOW")
>>> pinguino.digitalWrite(0, "HIGH")
>>> pinguino.digitalWrite(0, "LOW")

Y si los dioses de la programación están de nuestro lado, hemos visto como se encendía y apagaba un LED, (conectar un LED al puerto 0, o cualquier otro y modificar los comandos), eso significa que vamos bien :)

Preparando la aplicación de Twitter

Este paso no es necesario, ya que yo crearé esta aplicación y estará disponible para todos los usuarios a modo de ejemplo, por eso compartiré el CONSUMER_TOKEN y el CONSUMER_SECRET (que mala idea).
Si algún usuario desea implementar este ejemplo para algo serio y funcional debería crear su propia aplicación de Twitter (es muy sencillo) y mantener estos código secretos.

Lanzando el script en Python

El script Python es apenas una modificación del que usé en el anterior post:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from pynguino import PynguinoCDC
import tweepy
import pickle
#import webbrowser

import time

CONSUMER_TOKEN = "R6KpGitoJZtJZfy46Z0q8A"
CONSUMER_SECRET = "r6GvkfTL41Yq1JGfhLcgSDckjkVpR70VaDOeZ4Mw"


auth = tweepy.OAuthHandler(CONSUMER_TOKEN, CONSUMER_SECRET, secure=True)
auth_url = auth.get_authorization_url()

########################################################################
class PinguinoTweetControl(object):

    #----------------------------------------------------------------------
    def __init__(self):
        try: datos_cuenta=pickle.load(open("datos_cuenta"))
        except:
            #webbrowser.open_new_tab(auth_url)
            print(auth_url)
            verifier = raw_input('PIN: ')
            auth.get_access_token(verifier)

            ACCESS_KEY = auth.access_token.key
            ACCESS_SECRET = auth.access_token.secret

            datos_cuenta=[ACCESS_KEY,ACCESS_SECRET]
            pickle.dump(datos_cuenta, open("datos_cuenta", "w"))

        assert datos_cuenta

        ACCESS_KEY = datos_cuenta[0]
        ACCESS_SECRET = datos_cuenta[1]

        auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
        self.api = tweepy.API(auth)

    #----------------------------------------------------------------------
    def connect(self):
        self.pinguino = PynguinoCDC()


    #----------------------------------------------------------------------
    def run(self):
        self.connect()

        try:
            count = len(self.api.direct_messages())
        except tweepy.error.TweepError, M:
            print M[0][0]["message"]
            return


        while True:
            DMs = self.api.direct_messages()
            if len(DMs) > count:
                command = DMs[0].text
                command = command.replace(" ", "")
                print(command)
                self.pinguino.write(command)
                count = len(DMs)

            time.sleep(5)

if __name__ == "__main__":
    app = PinguinoTweetControl()
    app.run()

y lo ejecutamos desde una terminal así:
$ python pinguino_twitter.py
entonces nos predirá confirmar el acceso:
https://api.twitter.com/oauth/authorize?oauth_token=IlDzbJMxxTC6pIswZRU335kL2lrTeHU44rntz4sr1Gg
PIN: 
abrimos esta URL en un navegador y después de confirmar nos retornará un código que debemos de ingresar y presionar Enter
Autorización a la Aplicación de Twitter
Código de confirmación

https://api.twitter.com/oauth/authorize?oauth_token=IlDzbJMxxTC6pIswZRU335kL2lrTeHU44rntz4sr1Gg
PIN: 5193099
Y eso es todo, ya tenemos la interfaz creada y ejecutándose, las próximas ocasiones no será necesario conceder permisos, estos se recordarán automáticamente.

Probando la Interfaz

Como se ha visto, necesitamos entonces al menos dos cuentas, una para Pinguino (la que recibirá los DMs) y cualquier otra cuenta para enviarlos, teniendo esto entonces podremos enviar nuestros comandos así:

Intercambio de comandos con Pinguino

Conclusiones

Una modificación interesante consistiría en agregar comandos de consulta, es decir, digitalRead(0) y que el script en Python respondiera con un DM, ésta es una modificación que queda propuesta para el usuario que desee implementarla, también sería bueno responder con un mensaje de confirmación a cualquier comando enviado.
Hay muchas cosas que se pueden modificar y hacer de esto algo un poco mas útil (sí es que lo es ahora).

Rate limit exceeded

Este es un error que me sucedía constántemente a la hora de hacer pruebas, se debe a que tenemos un número limitado de consultas para acceder a los DM, entonces hay que aumentar las pausas entre consultas para satisfacer estos límites, de momentos la he dejado en 5 segundos (línea 69), pero debería modificarse.



Ya que estamos con esto de Twitter no olviden seguirme en mi cuenta @YeisonEng y también a Pinguino en @pinguinoide


También podría interesarte:

Añadir un comentario:
Si desean una respuesta para su comentario sólo deben agregarme en G+ y hacer una mención a Yeison Cardona, así les podré responder lo antes posible.