Paso 4: El código
Ahora, el código. La plataforma eléctrica imp le da todos los instrumentos para interactuar con el mundo entero API y webservices. Básicamente, el código está dividido en dos: un agente, que se ejecuta en los servidores de nube eléctrica de Imp, y un dispositivo, que es el electric Imp
[Copia y pega de la oficial documentación eléctrica Imp]
El objeto agente representa agente de imp: la ardilla de servidor, en servidores en nube de Imp eléctrico, que se ocupa de las solicitudes de Internet y las respuestas en nombre de la imp. El objeto de agente se usa para mediar la comunicación entre el imp y su agente.
El objeto de dispositivo representa la visión del agente de servidor de la imp y se usa para mediar la comunicación entre el agente y el diablillo.
[Fin de copiar y pegar]
Así que aquí vamos con nuestro código de agente. Se basa en la biblioteca de twitter útiles incluida en la referencia de webservices Imp eléctrico. También he añadido este pedazo de código para generar el evento tweet manualmente
// test function for manual hamster shakingfunction requestHandler(request, response) { try { // check if the user sent led as a query parameter if ("tweet" in request.query) { device.send("tweet", null); } // send a response back saying everything was OK. response.send(200, "tweet test ok"); } catch (ex) { response.send(500, "Internal Server Error: " + ex); } }// register the HTTP handler http.onrequest(requestHandler);
Para activar el twitter stream en tiempo real análisis, sólo necesita configurar estas constantes de twitter
// Twitter Keysconst API_KEY = ""; const API_SECRET = ""; const AUTH_TOKEN = ""; const TOKEN_SECRET = "";
y esta línea
twitter.stream(" onTweet);
que básicamente dice en el objeto de secuencia para todos los tweets que contengan la cadena"
Así que, aquí está el código completo del agente
// Copyright (c) 2013 Electric Imp// This file is licensed under the MIT License // http://opensource.org/licenses/MIT// Twitter Keys const API_KEY = ""; const API_SECRET = ""; const AUTH_TOKEN = ""; const TOKEN_SECRET = "";class Twitter { // OAuth _consumerKey = null; _consumerSecret = null; _accessToken = null; _accessSecret = null; // URLs streamUrl = "https://stream.twitter.com/1.1/"; tweetUrl = "https://api.twitter.com/1.1/statuses/update.json"; // Streaming streamingRequest = null; _reconnectTimeout = null; _buffer = null; constructor (consumerKey, consumerSecret, accessToken, accessSecret) { this._consumerKey = consumerKey; this._consumerSecret = consumerSecret; this._accessToken = accessToken; this._accessSecret = accessSecret; this._reconnectTimeout = 60; this._buffer = ""; } /*************************************************************************** * function: Tweet * Posts a tweet to the user's timeline * * Params: * status - the tweet * cb - an optional callback * * Return: * bool indicating whether the tweet was successful(if no cb was supplied) * nothing(if a callback was supplied) **************************************************************************/ function tweet(status, cb = null) { local headers = { }; local request = _oAuth1Request(tweetUrl, headers, { "status": status} ); if (cb == null) { local response = request.sendsync(); if (response && response.statuscode != 200) { server.log(format("Error updating_status tweet. HTTP Status Code %i:\r\n%s", response.statuscode, response.body)); return false; } else { return true; } } else { request.sendasync(cb); } } /*************************************************************************** * function: Stream * Opens a connection to twitter's streaming API * * Params: * searchTerms - what we're searching for * onTweet - callback function that executes whenever there is data * onError - callback function that executes whenever there is an error **************************************************************************/ function stream(searchTerms, onTweet, onError = null) { server.log("Opening stream for: " + searchTerms); // Set default error handler if (onError == null) onError = _defaultErrorHandler.bindenv(this); local method = "statuses/filter.json" local headers = { }; local post = { track = searchTerms }; local request = _oAuth1Request(streamUrl + method, headers, post); this.streamingRequest = request.sendasync( function(resp) { // connection timeout server.log("Stream Closed (" + resp.statuscode + ": " + resp.body +")"); // if we have autoreconnect set if (resp.statuscode == 28) { stream(searchTerms, onTweet, onError); } else if (resp.statuscode == 420) { imp.wakeup(_reconnectTimeout, function() { stream(searchTerms, onTweet, onError); }.bindenv(this)); _reconnectTimeout *= 2; } }.bindenv(this), function(body) { try { if (body.len() == 2) { _reconnectTimeout = 60; _buffer = ""; return; } local data = null; try { data = http.jsondecode(body); } catch(ex) { _buffer += body; try { data = http.jsondecode(_buffer); } catch (ex) { return; } } if (data == null) return; // if it's an error if ("errors" in data) { server.log("Got an error"); onError(data.errors); return; } else { if (_looksLikeATweet(data)) { onTweet(data); return; } } } catch(ex) { // if an error occured, invoke error handler onError([{ message = "Squirrel Error - " + ex, code = -1 }]); } }.bindenv(this) ); } /***** Private Function - Do Not Call *****/ function _encode(str) { return http.urlencode({ s = str }).slice(2); } function _oAuth1Request(postUrl, headers, data) { local time = time(); local nonce = time; local parm_string = http.urlencode({ oauth_consumer_key = _consumerKey }); parm_string += "&" + http.urlencode({ oauth_nonce = nonce }); parm_string += "&" + http.urlencode({ oauth_signature_method = "HMAC-SHA1" }); parm_string += "&" + http.urlencode({ oauth_timestamp = time }); parm_string += "&" + http.urlencode({ oauth_token = _accessToken }); parm_string += "&" + http.urlencode({ oauth_version = "1.0" }); parm_string += "&" + http.urlencode(data); local signature_string = "POST&" + _encode(postUrl) + "&" + _encode(parm_string); local key = format("%s&%s", _encode(_consumerSecret), _encode(_accessSecret)); local sha1 = _encode(http.base64encode(http.hash.hmacsha1(signature_string, key))); local auth_header = "oauth_consumer_key=\""+_consumerKey+"\", "; auth_header += "oauth_nonce=\""+nonce+"\", "; auth_header += "oauth_signature=\""+sha1+"\", "; auth_header += "oauth_signature_method=\""+"HMAC-SHA1"+"\", "; auth_header += "oauth_timestamp=\""+time+"\", "; auth_header += "oauth_token=\""+_accessToken+"\", "; auth_header += "oauth_version=\"1.0\""; local headers = { "Authorization": "OAuth " + auth_header }; local url = postUrl + "?" + http.urlencode(data); local request = http.post(url, headers, ""); return request; } function _looksLikeATweet(data) { return ( "created_at" in data && "id" in data && "text" in data && "user" in data ); } function _defaultErrorHandler(errors) { foreach(error in errors) { server.log("ERROR " + error.code + ": " + error.message); } }}twitter <- Twitter(API_KEY, API_SECRET, AUTH_TOKEN, TOKEN_SECRET);function onTweet(tweetData) { // log the tweet, and who tweeted it (there is a LOT more info in tweetData) server.log(format("%s - %s", tweetData.text, tweetData.user.screen_name)); device.send("tweet", null); }// test function for manual hamster shaking function requestHandler(request, response) { try { // check if the user sent led as a query parameter if ("tweet" in request.query) { device.send("tweet", null); } // send a response back saying everything was OK. response.send(200, "tweet test ok"); } catch (ex) { response.send(500, "Internal Server Error: " + ex); } }twitter.stream("yoursearchstring", onTweet);// register the HTTP handler http.onrequest(requestHandler);
Entonces, aquí está el código del dispositivo, basado en el electric Imp ejemplo PWM Servo
// These values may be different for your servoconst SERVO_MIN = 0.03; const SERVO_MAX = 0.1;// create global variable for servo and configure servo <- hardware.pin7; servo.configure(PWM_OUT, 0.02, SERVO_MIN);// assign pin9 to a global variable led <- hardware.pin9; // configure LED pin for DIGITAL_OUTPUT led.configure(DIGITAL_OUT);// global variable to track current state of LED pin state <- 0; // set LED pin to initial value (0 = off, 1 = on) led.write(state);// expects a value between 0.0 and 1.0 function SetServo(value) { local scaledValue = value * (SERVO_MAX-SERVO_MIN) + SERVO_MIN; servo.write(scaledValue); }// expects a value between -80.0 and 80.0 function SetServoDegrees(value) { local scaledValue = (value + 81) / 161.0 * (SERVO_MAX-SERVO_MIN) + SERVO_MIN; servo.write(scaledValue); }// current position (we'll flip between 0 and 1) position <- 0;function HamsterDance() { SetServoDegrees(-10); imp.sleep(0.5); SetServoDegrees(0); imp.sleep(0.2); SetServoDegrees(-15); imp.sleep(0.2); SetServoDegrees(5); imp.sleep(0.2); SetServoDegrees(-20); imp.sleep(0.2); SetServoDegrees(0); imp.sleep(0.2); SetServoDegrees(-78); } function ShakeRattleAndRoll(ledState){ server.log("Let's shake the hamster!"); // turn on the led for visual debugging led.write(1); // HamsterDance(); imp.sleep(2); // turn off the led led.write(0);} // initialize the servo to the start position SetServoDegrees(-78);//shake the hamster when got a tweet message from the Agent agent.on("tweet", ShakeRattleAndRoll);