├── lasote ├── arduino_http │ ├── bii │ │ └── dependencies.bii │ ├── example │ │ ├── post.cpp │ │ ├── item_detector.cpp │ │ └── cc3000 │ │ │ ├── item_detector.cpp │ │ │ └── post.cpp │ ├── http_client.h │ ├── readme.md │ └── http_client.cpp └── weather │ ├── weather_client.h │ ├── readme.md │ ├── examples │ └── main.cpp │ └── weather_client.cpp └── InteractionTemperature.ino /lasote/arduino_http/bii/dependencies.bii: -------------------------------------------------------------------------------- 1 | example/cc3000/post.cpp - example/item_detector.cpp 2 | example/cc3000/post.cpp - example/post.cpp 3 | example/cc3000/item_detector.cpp - example/item_detector.cpp 4 | example/cc3000/item_detector.cpp - example/post.cpp 5 | 6 | 7 | -------------------------------------------------------------------------------- /lasote/weather/weather_client.h: -------------------------------------------------------------------------------- 1 | /* 2 | * weather_reader.h 3 | * 4 | * Created on: 05/03/2014 5 | * Author: laso 6 | */ 7 | #include "http_client.h" 8 | 9 | #ifndef WEATHER_READER_H_ 10 | #define WEATHER_READER_H_ 11 | 12 | namespace lasote { 13 | 14 | struct weather{ 15 | char description[30]; 16 | float min_temp; 17 | float max_temp; 18 | }; 19 | 20 | 21 | class WeatherClient { 22 | public: 23 | WeatherClient(Client& aClient, Stream& serial); 24 | virtual ~WeatherClient(); 25 | bool get_weather(weather&, const char* city, int future_days=0); 26 | private: 27 | bool get_current_weather(weather&, const char* city); 28 | bool get_forecast(weather& we, const char* city, int future_days); 29 | char* get_current_weather_uri(const char* city); 30 | bool call_and_receive(char uri[], const char* queries[], weather& we); 31 | HttpClient* http_client; 32 | Stream& stream; 33 | 34 | }; 35 | 36 | } /* namespace weather_reader */ 37 | #endif /* WEATHER_READER_H_ */ 38 | -------------------------------------------------------------------------------- /lasote/weather/readme.md: -------------------------------------------------------------------------------- 1 | # lasote/weather 2 | 3 | ### What is it? 4 | An Arduino client to check an online [weather service][1]. 5 | It uses [`lasote/arduino_http`][2] block for access service, so it can be used with any hardware adaptor. 6 | WeatherClient can check current weather and forecast of X future days. 7 | 8 | ### How can i use it? 9 | * Instance hardware client and init weather_client 10 | * Setup hardware 11 | * Call to get_weather 12 | 13 | 14 | //Our hardware adapter is Enc28J60 HanRun module 15 | EthernetClient client; 16 | 17 | //Instance a weather client for check weather 18 | WeatherClient weather_client(client, Serial); 19 | 20 | //LOOP 21 | bool ret = weather_client.get_weather(w, city, future_days); 22 | if(ret){ 23 | Serial.println(w.description); Serial.print(F("Max temp:")); 24 | Serial.println(w.max_temp); Serial.print(F("Min temp:")); 25 | Serial.println(w.min_temp); 26 | } 27 | 28 | Check the full example in examples/main.cpp file! 29 | 30 | Enjoy it!!! 31 | 32 | 33 | [1]: http://openweathermap.org/ 34 | [2]: https://www.biicode.com/lasote/blocks/lasote/arduino_http/branches/master 35 | -------------------------------------------------------------------------------- /lasote/arduino_http/example/post.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ntruchsess/arduino_uip/uipethernet.h" 3 | #include "lasote/arduino_http/http_client.h" 4 | #include "lasote/stream_finder_processor/stream_finder_processor.h" 5 | #include "lasote/stream_recorder/stream_recorder.h" 6 | 7 | using namespace lasote; 8 | 9 | EthernetClient client; 10 | char response_buffer[20]; 11 | StreamRecorderProcessor response_recorder(response_buffer, 20); //Capture response in buffer 12 | HttpClient http_client(client, Serial); 13 | int led = 12; 14 | 15 | // the setup routine runs once when you press reset: 16 | void setup() { 17 | Serial.begin(9600); 18 | Serial.println("************* SETUP ****************"); 19 | pinMode(led, OUTPUT); // initialize the digital pin as an output. 20 | uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; 21 | Ethernet.begin(mac); 22 | http_client.processors.add_item(&response_recorder); 23 | 24 | } 25 | 26 | // the loop routine runs over and over again forever: 27 | void loop() { 28 | 29 | delay(5000); 30 | Serial.println("--- SENDING POST---"); 31 | 32 | http_client.reset(); //Reset processors and custom headers 33 | //We can add custom headers to the request 34 | http_client.add_custom_header("Content-Type", "application/json"); 35 | 36 | int sent = http_client.post(IPAddress(192, 168, 1, 100), "/", "{\"uno\":1, \"dos\":[2,2,2,2]}", 8080); 37 | if(sent){ 38 | if(short int ret_code = http_client.receive()){ 39 | if(ret_code == 200){ 40 | Serial.println("Code 200 OK!"); 41 | Serial.println(response_buffer); 42 | } 43 | else{ 44 | Serial.print("Http Error:"); 45 | Serial.println(ret_code); 46 | } 47 | } 48 | else{ 49 | Serial.println(F("Error receiving!")); 50 | } 51 | } 52 | else{ 53 | Serial.println(F("ERROR CONNECTING... retrying")); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lasote/arduino_http/example/item_detector.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ntruchsess/arduino_uip/uipethernet.h" 3 | #include "lasote/arduino_http/http_client.h" 4 | #include "lasote/stream_finder_processor/stream_finder_processor.h" 5 | 6 | using namespace lasote; 7 | 8 | 9 | int led = 13; 10 | EthernetClient client; 11 | HttpClient http_client(client, Serial); 12 | StreamFinderProcessor item_finder("MicroSD", "64GB", 50); 13 | 14 | 15 | 16 | // the setup routine runs once when you press reset: 17 | void setup() { 18 | Serial.begin(9600); 19 | Serial.println(F("************* SETUP ****************")); 20 | pinMode(led, OUTPUT); // initialize the digital pin as an output. 21 | uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; 22 | Ethernet.begin(mac); 23 | 24 | http_client.processors.add_item(&item_finder); 25 | 26 | Serial.print(F("localIP: ")); 27 | Serial.println(Ethernet.localIP()); 28 | Serial.print(F("subnetMask: ")); 29 | Serial.println(Ethernet.subnetMask()); 30 | Serial.print(F("gatewayIP: ")); 31 | Serial.println(Ethernet.gatewayIP()); 32 | Serial.print(F("dnsServerIP: ")); 33 | Serial.println(Ethernet.dnsServerIP()); 34 | 35 | } 36 | 37 | 38 | void loop() { 39 | 40 | //Reset status and processors for new clean website check 41 | http_client.reset(); 42 | delay(4000); 43 | Serial.println(F("---Checking website!---")); 44 | int ret = http_client.get("bargainshop.es", "/"); 45 | if(ret){ 46 | Serial.println("Connected"); 47 | int ret_code = http_client.receive(); 48 | if(ret_code==200){ 49 | Serial.println(F("Page loaded ok...")); 50 | if(item_finder.found){ 51 | Serial.println(F("MicroSD 64GB Found!")); 52 | } 53 | else{ 54 | Serial.println(F("No MicroSD 64GB today")); 55 | } 56 | 57 | } 58 | else{ 59 | Serial.println(F("Error code!")); 60 | } 61 | } 62 | else{ 63 | Serial.println(F("ERROR CONNECTING... retrying")); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /lasote/weather/examples/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ntruchsess/arduino_uip/uipethernet.h" 3 | #include 4 | #include 5 | 6 | #define STATUS_PIN 13 7 | #define DELAY_SECONDS 5//Time between calls to api 8 | 9 | using namespace lasote; 10 | 11 | //Our hardware adapter is Enc28J60 HanRun module 12 | EthernetClient client; 13 | //Instance a weather client for check weather 14 | WeatherClient weather_client(client, Serial); 15 | //Init lcd 16 | LiquidCrystal lcd(2, 3, 8, 9, 10, 11); 17 | 18 | bool get_weather(const char* city, int future_days){ 19 | //reset previous status for a clean request 20 | Serial.println(F("Lets check weather!")); 21 | 22 | //weather object 23 | weather w; 24 | bool ret = weather_client.get_weather(w, city, future_days); 25 | if(ret){ 26 | Serial.println(w.description); Serial.print(F("Max temp:")); 27 | Serial.println(w.max_temp); Serial.print(F("Min temp:")); 28 | Serial.println(w.min_temp); 29 | 30 | lcd.clear(); 31 | lcd.setCursor(0, 0); 32 | if(strlen(w.description) > 16){ 33 | w.description[15] = '\0'; 34 | } 35 | lcd.print(w.description); 36 | lcd.setCursor(0, 1); 37 | lcd.print(w.min_temp); 38 | lcd.print("-"); 39 | lcd.print(w.max_temp); 40 | } 41 | else{ 42 | lcd.print(w.description); 43 | lcd.setCursor(0, 1); 44 | lcd.print("ERROR"); 45 | } 46 | } 47 | 48 | 49 | 50 | void setup() { 51 | Serial.begin(9600); 52 | Serial.println(F("***********SETUP****************")); 53 | 54 | //MAC init 55 | uint8_t mac[6] = {0x10,0x31,0x02,0x33,0x04,0x65}; 56 | Ethernet.begin(mac); 57 | 58 | pinMode(STATUS_PIN, OUTPUT); 59 | 60 | // initialize the library with the numbers of the interface pins 61 | lcd.begin(16, 2); 62 | delay(4000); 63 | } 64 | 65 | 66 | void loop() { 67 | lcd.clear(); 68 | lcd.setCursor(0, 0); 69 | lcd.write("Now..."); 70 | //For today 71 | get_weather("Madrid", 0); 72 | 73 | delay(DELAY_SECONDS * 1000); 74 | lcd.clear(); 75 | lcd.setCursor(0, 0); 76 | lcd.write("Tomorrow..."); 77 | //For tomorrow 78 | get_weather("Madrid", 1); //Tomorrow 79 | 80 | 81 | delay(DELAY_SECONDS * 1000); 82 | 83 | } 84 | 85 | -------------------------------------------------------------------------------- /lasote/arduino_http/http_client.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_client.h 3 | * 4 | * Created on: 28/03/2014 5 | * Author: laso 6 | */ 7 | 8 | #ifndef HTTP_CLIENT_H_ 9 | #define HTTP_CLIENT_H_ 10 | 11 | #include 12 | #include 13 | #include "Client.h" 14 | #include "lasote/linked_list/linked_list.h" 15 | #include "lasote/http_response_processor/http_response_processor.h" 16 | 17 | #define CANT_CONNECT -1 18 | #define RESPONSE_TIMEOUT -2 19 | #define LOST_CONNECTION -3 20 | #define BAD_BODY -4 21 | #define OK 1 22 | 23 | 24 | namespace lasote { 25 | 26 | class Header{ 27 | public: 28 | Header(const char *name,const char* value); 29 | ~Header(); 30 | const char* name; 31 | const char* value; 32 | }; 33 | 34 | 35 | class HttpClient { 36 | public: 37 | HttpClient(Client& aClient, Stream& stream); 38 | ~HttpClient(); 39 | uint8_t get(const char *host, const char *uri="/", uint16_t port=80); 40 | uint8_t get(IPAddress ip, const char *uri="/", uint16_t port=80); 41 | 42 | //Body direct 43 | uint8_t post(const char *host, const char *uri, const char* body, uint16_t port=80); 44 | uint8_t post(IPAddress ip, const char *uri, const char* body, uint16_t port=80); 45 | 46 | //Body streamed 47 | uint8_t post(const char *host, const char *uri, Stream& body, uint16_t port=80); 48 | uint8_t post(IPAddress ip, const char *uri, Stream& body, uint16_t port=80); 49 | 50 | //Custom headers helper 51 | void add_custom_header(const char* name, const char* value); 52 | 53 | //Receive response 54 | short int receive(); 55 | 56 | //Reset all 57 | void reset(); 58 | 59 | Client& aClient; 60 | LinkedList processors; 61 | LinkedList custom_headers; 62 | 63 | protected: 64 | uint8_t wait_for_response(unsigned int miliseconds); 65 | Stream& stream; 66 | 67 | void send_header(const char* header_name, const char* header_value); 68 | void send_all_headers(const char* method, const char* host, const char* header_value); 69 | void send_body(const char* body); 70 | void send_body(Stream& body); 71 | void end_request(); 72 | void end_headers(); 73 | 74 | 75 | private: 76 | void ip_to_string(IPAddress ip, char* buffer); 77 | }; 78 | 79 | } /* namespace arduino_http_client */ 80 | #endif /* HTTP_CLIENT_H_ */ 81 | -------------------------------------------------------------------------------- /lasote/arduino_http/example/cc3000/item_detector.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "lasote/arduino_http/http_client.h" 3 | #include "lasote/stream_finder_processor/stream_finder_processor.h" 4 | 5 | //For cc3000 adapter 6 | #include 7 | #include "diego/ardunet/cc3000client.h" 8 | #include "diego/ardunet/cc3000utils.h" 9 | 10 | using namespace lasote; 11 | 12 | //This file, located in your hive root folder must #define WLAN_SSID , WLAN_PASS and WLAN_SECURITY 13 | //of your wifi. It is not published in your block for obvious reasons. Example: 14 | #define WLAN_SSID "XXXXXXXX" 15 | #define WLAN_PASS "XXXXXXXXXXXXXXXXX" 16 | #define WLAN_SECURITY WLAN_SEC_WPA2 17 | 18 | // These are the interrupt and control pins 19 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 20 | // These can be any two pins 21 | #define ADAFRUIT_CC3000_VBAT 5 22 | #define ADAFRUIT_CC3000_CS 10 23 | 24 | int led = 13; 25 | 26 | 27 | //create CC3000 instance, and an SDK compatible Client 28 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, 29 | ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER); 30 | 31 | CC3000Client client(cc3000); 32 | 33 | HttpClient http_client(client, Serial); 34 | StreamFinderProcessor item_finder("MicroSD", "64GB", 50); 35 | 36 | 37 | // the setup routine runs once when you press reset: 38 | void setup() { 39 | Serial.begin(9600); 40 | Serial.println(F("************* SETUP ****************")); 41 | pinMode(led, OUTPUT); // initialize the digital pin as an output. 42 | startConnection(cc3000, WLAN_SSID, WLAN_PASS, WLAN_SECURITY); 43 | 44 | http_client.processors.add_item(&item_finder); 45 | 46 | } 47 | 48 | 49 | void loop() { 50 | 51 | //Reset status and processors for new clean website check 52 | http_client.reset(); 53 | delay(4000); 54 | Serial.println(F("---Checking website!---")); 55 | int ret = http_client.get("bargainshop.es", "/"); 56 | if(ret){ 57 | Serial.println("Connected"); 58 | int ret_code = http_client.receive(); 59 | if(ret_code==200){ 60 | Serial.println(F("Page loaded ok...")); 61 | if(item_finder.found){ 62 | Serial.println(F("MicroSD 64GB Found!")); 63 | } 64 | else{ 65 | Serial.println(F("No MicroSD 64GB today")); 66 | } 67 | 68 | } 69 | else{ 70 | Serial.println(F("Error code!")); 71 | } 72 | } 73 | else{ 74 | Serial.println(F("ERROR CONNECTING... retrying")); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /lasote/arduino_http/example/cc3000/post.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ntruchsess/arduino_uip/uipethernet.h" 3 | #include "lasote/arduino_http/http_client.h" 4 | 5 | #include "lasote/stream_finder_processor/stream_finder_processor.h" 6 | #include "lasote/stream_recorder/stream_recorder.h" 7 | #include "Arduino.h" 8 | 9 | //For cc3000 adapter 10 | #include 11 | #include "diego/ardunet/cc3000client.h" 12 | #include "diego/ardunet/cc3000utils.h" 13 | 14 | //This file, located in your hive root folder must #define WLAN_SSID , WLAN_PASS and WLAN_SECURITY 15 | //of your wifi. It is not published in your block for obvious reasons. Example: 16 | #define WLAN_SSID "XXXXXXXXXXX" 17 | #define WLAN_PASS "XXXXXXXXXXX" 18 | #define WLAN_SECURITY WLAN_SEC_WPA2 19 | 20 | // These are the interrupt and control pins 21 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 22 | // These can be any two pins 23 | #define ADAFRUIT_CC3000_VBAT 5 24 | #define ADAFRUIT_CC3000_CS 10 25 | 26 | 27 | using namespace lasote; 28 | 29 | //create CC3000 instance, and an SDK compatible Client 30 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, 31 | ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER); 32 | 33 | CC3000Client client(cc3000); 34 | 35 | char response_buffer[20]; 36 | StreamRecorderProcessor response_recorder(response_buffer, 20); //Capture response in buffer 37 | HttpClient http_client(client, Serial); 38 | int led = 12; 39 | 40 | // the setup routine runs once when you press reset: 41 | void setup() { 42 | Serial.begin(9600); 43 | Serial.println("************* SETUP ****************"); 44 | pinMode(led, OUTPUT); // initialize the digital pin as an output. 45 | startConnection(cc3000, WLAN_SSID, WLAN_PASS, WLAN_SECURITY); 46 | 47 | http_client.processors.add_item(&response_recorder); 48 | 49 | } 50 | 51 | // the loop routine runs over and over again forever: 52 | void loop() { 53 | 54 | delay(5000); 55 | Serial.println("--- SENDING POST---"); 56 | 57 | http_client.reset(); //Reset processors and custom headers 58 | //We can add custom headers to the request 59 | http_client.add_custom_header("Content-Type", "application/json"); 60 | 61 | int sent = http_client.post(IPAddress(192, 168, 1, 100), "/", "{\"uno\":1, \"dos\":[2,2,2,2]}", 8080); 62 | if(sent){ 63 | if(short int ret_code = http_client.receive()){ 64 | if(ret_code == 200){ 65 | Serial.println("Code 200 OK!"); 66 | Serial.println(response_buffer); 67 | } 68 | else{ 69 | Serial.print("Http Error:"); 70 | Serial.println(ret_code); 71 | } 72 | } 73 | else{ 74 | Serial.println(F("Error receiving!")); 75 | } 76 | } 77 | else{ 78 | Serial.println(F("ERROR CONNECTING... retrying")); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lasote/arduino_http/readme.md: -------------------------------------------------------------------------------- 1 | # lasote/arduino_http 2 | 3 | ### What is it? 4 | This is a simple but powerfull Arduino Client library. It works with low memory requirements using processors based on streaming text recognition. Only stores the very necessary data for work. Supports GET and POST requests. 5 | 6 | ### Tested on 7 | 8 | Its tested using a cheap Ethernet Enc28j60 module. 9 | 10 | HttpClient can work with other adapters that implements Client interface. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
**Board****Example**
Enc28j60 no-shield here
Adafruit Wifi cc3000 How to instance a client here.
Complete example coming soon...
Arduino Ethernet ShieldComing soon...
Arduino Wifi ShieldComing soon...
36 | 37 | ### How can i use it? 38 | 39 | Take a look to the *example/post.cpp* and *example/menu_detector* for full examples. 40 | Common steps are: 41 | * Instance the _Client object_ for your hardware adapter 42 | * Instance an HttpClient passing on the _Client object_ 43 | * Write init code of your _Client object_ in Setup method 44 | * Just call *http_client.post* or *http_client.get* 45 | 46 | 47 | EthernetClient client; 48 | HttpClient http_client(client, Serial); 49 | //Create the processors you want in order to parse the response 50 | StreamRecorderProcessor response_recorder(response_buffer, 100); //Capture response in buffer 51 | ... 52 | //SETUP: Add the processors to the http_client 53 | http_client.processors.add_item(&response_recorder); 54 | 55 | //LOOP: 56 | http_client.reset(); //Reset previous processors status and custom headers etc. 57 | http_client.get("www.google.com", "/webhp#q=biicode"); 58 | ... 59 | http_client.receive() 60 | ... 61 | //Now check the processor for the result! 62 | 63 | 64 | 65 | ### Advanced uses 66 | 67 | #### Using processors 68 | 69 | As I mentioned previously, this http client is based on stream processors for response parse in order to keep as low as possible memory requirements. This is a list of util processors. 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
**Name****Description****Include**
StreamJsonProcessorParse json from http response. You have an example in arduino_weather project.
Based on StreamJsonReader
#include "lasote/stream_processor/stream_json_processor.h"
StreamFinderProcessorChecks if a string in exists in a response. Based on a StreamFinder. Check the menu_detector example in block home page#include "lasote/stream_finder_processor/stream_finder_processor.h"
StreamRecorderProcessorJust record the whole response in a buffer. Check the post example#include "lasote/stream_recorder/stream_recorder.h"
92 | 93 | #### Using POST request 94 | 95 | Look the post.cpp example for POST request usage. 96 | 97 | 98 | -------------------------------------------------------------------------------- /lasote/weather/weather_client.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * weather_reader.cpp 3 | * 4 | * Created on: 05/03/2014 5 | * Author: laso 6 | */ 7 | #include "lasote/weather/weather_client.h" 8 | #include "lasote/stream_processor/stream_json_processor.h" 9 | #include /* atoi */ 10 | 11 | #define LOG_OUTPUT false 12 | 13 | namespace lasote { 14 | 15 | WeatherClient::WeatherClient(Client& aClient, Stream& serial) : stream(serial) { 16 | http_client = new HttpClient(aClient, serial); 17 | } 18 | 19 | WeatherClient::~WeatherClient() { 20 | delete http_client; 21 | } 22 | 23 | bool WeatherClient::get_weather(weather& w, const char* city, int future_days){ 24 | if(future_days < 1){ 25 | return get_current_weather(w, city); 26 | } 27 | else{ 28 | return get_forecast(w, city, future_days); 29 | } 30 | } 31 | 32 | bool WeatherClient::get_current_weather(weather& we, const char* city){ 33 | /** 34 | * {"coord":{"lon":-3.7,"lat":40.42}, 35 | * "sys":{"message":0.0447,"country":"ES","sunrise":1396245552,"sunset":1396291108}, 36 | * "weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}], 37 | * "base":"cmc stations", 38 | * "main":{"temp":12.1,"humidity":63,"pressure":1016,"temp_min":11,"temp_max":14.44}, 39 | * "wind":{"speed":2.06,"gust":4.11,"deg":153}, 40 | * "clouds":{"all":56}, 41 | * "dt":1396263911, 42 | * "id":3117735, 43 | * "name":"Madrid", 44 | * "cod":200} 45 | */ 46 | char tmp[strlen(city) + 35]; 47 | tmp[0] = '\0'; 48 | strcat_P(tmp, PSTR("/data/2.5/weather?q=")); 49 | strcat(tmp, city); 50 | strcat_P(tmp, PSTR("&units=metric")); 51 | const char* queries[] = { "weather.0.description", "main.temp_min", "main.temp_max" }; 52 | return call_and_receive(tmp, queries, we); 53 | }; 54 | 55 | bool WeatherClient::get_forecast(weather& we, const char* city, int future_days){ 56 | /** 57 | * { 58 | "cod":"200", 59 | "message":0.0047, 60 | "city":{ 61 | "id":1851632, 62 | "name":"Shuzenji", 63 | "coord":{ 64 | "lon":138.933334, 65 | "lat":34.966671 66 | }, 67 | "country":"JP", 68 | "population":0 69 | }, 70 | "cnt":10, 71 | "list":[ 72 | { 73 | "dt":1396317600, 74 | "temp":{ 75 | "day":287.73, 76 | "min":275.35, 77 | "max":287.73, 78 | "night":275.35, 79 | "eve":283.86, 80 | "morn":287.73 81 | }, 82 | "pressure":986.76, 83 | "humidity":37, 84 | "weather":[ 85 | { 86 | "id":801, 87 | "main":"Clouds", 88 | "description":"few clouds", 89 | "icon":"02d" 90 | } 91 | ], 92 | "speed":2.06, 93 | "deg":121, 94 | "clouds":24 95 | }, 96 | ] 97 | } 98 | */ 99 | 100 | char tmp_days[4]; 101 | sprintf(tmp_days, "%d", future_days); 102 | 103 | char uri[strlen(city) + 50]; 104 | uri[0] = '\0'; 105 | strcat_P(uri, PSTR("/data/2.5/forecast/daily?q=")); 106 | strcat(uri, city); 107 | strcat_P(uri, PSTR("&units=metric")); 108 | strcat_P(uri, PSTR("&cnt=")); 109 | strcat(uri, tmp_days); 110 | 111 | 112 | 113 | sprintf(tmp_days, "%d", future_days - 1); //for array 114 | 115 | const char* queries[3]; 116 | char query_0[27 + strlen(tmp_days) + 1]; query_0[0] = '\0'; 117 | strcat_P(query_0, PSTR("list.")); 118 | strcat(query_0, tmp_days); 119 | strcat_P(query_0, PSTR(".weather.0.description")); 120 | 121 | char query_1[14 + strlen(tmp_days) + 1]; query_1[0] = '\0'; 122 | strcat_P(query_1, PSTR("list.")); 123 | strcat(query_1, tmp_days); 124 | strcat_P(query_1, PSTR(".temp.min")); 125 | 126 | char query_2[14 + strlen(tmp_days) + 1]; query_2[0] = '\0'; 127 | strcat_P(query_2, PSTR("list.")); 128 | strcat(query_2, tmp_days); 129 | strcat_P(query_2, PSTR(".temp.max")); 130 | 131 | 132 | //Serial.println(uri); 133 | 134 | queries[0] = query_0; 135 | queries[1] = query_1; 136 | queries[2] = query_2; 137 | 138 | return call_and_receive(uri, queries, we); 139 | }; 140 | 141 | bool WeatherClient::call_and_receive(char uri[], const char* queries[], weather& we){ 142 | 143 | http_client->processors.reset(); 144 | http_client->reset(); 145 | 146 | StreamJsonProcessor processor(queries, 3, 20, 30, 30); 147 | http_client->processors.add_item(&processor); 148 | 149 | uint8_t connected = http_client->get("api.openweathermap.org", uri); 150 | if(connected){ 151 | stream.println(F("Connected ok!")); 152 | int http_code = http_client->receive(); 153 | stream.println(http_code); 154 | if(http_code==200){ //OK! 155 | if(processor.finished()){ 156 | strcpy(we.description, processor.results[0]); 157 | we.min_temp = atof(processor.results[1]); 158 | we.max_temp = atof(processor.results[2]); 159 | return true; 160 | } 161 | else{ 162 | stream.println(F("Return JSON not detected or queries not found!")); 163 | return false; 164 | } 165 | } 166 | else{ 167 | stream.println(F("Error receiving!")); 168 | return false; 169 | } 170 | } 171 | else{ 172 | stream.println(F("Error connecting weather client")); 173 | return false; 174 | } 175 | return false; 176 | } 177 | 178 | } /* namespace weather_reader */ 179 | -------------------------------------------------------------------------------- /InteractionTemperature.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | //#define COMMON_ANODE 10 | 11 | //using namespace ArduinoJson; 12 | //using namespace lasote; 13 | 14 | 15 | /* &APPID=53d2069076934085f5c518c513aee867 */ 16 | 17 | 18 | // Initialize client library 19 | 20 | //int rPin = 9; //red 21 | int rPin = 3; // Red Pin for Max Temp. 6 on board. 22 | 23 | //int gPin = 6; //green 24 | //int bPin = 10; //blue. 25 | 26 | int bPin = 5; // 9 on board. 27 | 28 | int rPin2 = 6; // Red Pin for Current Temp; 14 on board 29 | int bPin2 = 9; // Blue Pin for Current Temp; 17 on board 30 | 31 | int rPin3 = 10; // Red Pin for Min Temp 32 | int bPin3 = 11; // Blue Pin for Min Temp 33 | 34 | int temperature = 100; 35 | boolean hasPrecipitation = false; 36 | 37 | //JsonParser<64> parser; 38 | void setup() { 39 | Bridge.begin(); 40 | //Initialize serial and wait for port to open: 41 | setupLightPins(); 42 | Serial.begin(9600); 43 | while (!Serial); 44 | 45 | 46 | Serial.println("Testing Yun"); 47 | //delay(1000); 48 | } 49 | 50 | void getWeatherInfo() { 51 | HttpClient weatherClient; 52 | weatherClient.get("http://api.openweathermap.org/data/2.5/weather?q=South%20Bend,IN&units=imperial&APPID=53d2069076934085f5c518c513aee867"); 53 | String weatherString = ""; 54 | 55 | while(weatherClient.available()) { 56 | char c = weatherClient.read(); 57 | weatherString += c; 58 | } 59 | 60 | Serial.flush(); 61 | Serial.println(weatherString); 62 | Serial.println(weatherString.length()); 63 | int buffer_size = weatherString.length(); 64 | 65 | char jsonBuffer[buffer_size]; 66 | Serial.println(F("Attempting to print out jsonBuffer.")); 67 | 68 | 69 | weatherString.toCharArray(jsonBuffer, buffer_size); 70 | weatherString = ""; 71 | Serial.println(jsonBuffer); 72 | Serial.println(F("Buffer printed.")); 73 | 74 | Serial.println(F("Attempting to parse JSON.")); 75 | 76 | StaticJsonBuffer<500> weatherBuffer; 77 | JsonObject& root = weatherBuffer.parseObject(jsonBuffer); 78 | 79 | if(!root.success()) { 80 | Serial.println(F("Parsing failed.")); 81 | return; 82 | } else { 83 | //free(jsonBuffer); 84 | } 85 | 86 | JsonVariant &main = root.at("main"); 87 | JsonVariant &weather = root.at("weather"); 88 | 89 | Serial.println(F("Parsing successful!")); 90 | //root.prettyPrintTo(Serial); 91 | weather[0].prettyPrintTo(Serial); 92 | Serial.println(); 93 | main.prettyPrintTo(Serial); 94 | Serial.println(); 95 | const char* weatherDescription = weather[0]["description"]; 96 | Serial.println(weatherDescription); 97 | 98 | float weatherTemperature = (float) main["temp"]; 99 | float maxTemperature = (float) main["temp_max"] * 1.0; 100 | float minTemperature = (float) main["temp_min"] * 1.0; 101 | 102 | Serial.println(maxTemperature); 103 | Serial.println(weatherTemperature); 104 | Serial.println(minTemperature); 105 | 106 | if(maxTemperature <= 40) { 107 | setMaxColor(0, 255); 108 | } else if(maxTemperature > 40 && maxTemperature < 70) { 109 | setMaxColor(255, 255); 110 | } else { 111 | setMaxColor(255, 0); 112 | } 113 | 114 | if(weatherTemperature <= 40) { 115 | setCurrentColor(0, 255); 116 | } else if(weatherTemperature > 40 && weatherTemperature < 70) { 117 | setCurrentColor(255, 255); 118 | } else { 119 | setCurrentColor(255, 0); 120 | } 121 | 122 | 123 | if(minTemperature <= 40) { 124 | setMinColor(0, 255); 125 | } else if(minTemperature > 40 && minTemperature < 70) { 126 | setMinColor(255, 255); 127 | } else { 128 | setMinColor(255, 0); 129 | } 130 | } 131 | 132 | void loop() { 133 | getWeatherInfo(); 134 | delay(5000); 135 | 136 | //colorSwitchingStuff(); 137 | } 138 | 139 | void setColor(int red, int green, int blue) { 140 | #ifdef COMMON_ANODE 141 | red = 255 - red; 142 | green = 255 - green; 143 | blue = 255 - blue; 144 | #endif 145 | 146 | analogWrite(rPin, red); 147 | //analogWrite(gPin, green); 148 | analogWrite(bPin, blue); 149 | 150 | } 151 | 152 | void colorTest() { 153 | setColor(0,0,0); 154 | delay(500); 155 | setColor(255,0,0); 156 | delay(500); 157 | setColor(0,255,0); 158 | delay(500); 159 | setColor(0,0,255); 160 | } 161 | void updateColors(double maxTemp, double currentTemp, double minTemp) { 162 | 163 | 164 | } 165 | 166 | void setupLightPins() { 167 | pinMode(rPin, OUTPUT); 168 | pinMode(bPin, OUTPUT); 169 | 170 | pinMode(rPin2, OUTPUT); 171 | pinMode(bPin2, OUTPUT); 172 | 173 | pinMode(rPin3, OUTPUT); 174 | pinMode(bPin3, OUTPUT); 175 | 176 | 177 | setMaxColor(255, 0); 178 | setCurrentColor(255, 0); 179 | setMinColor(255,0); 180 | } 181 | 182 | void setMaxColor(int red, int blue) { 183 | analogWrite(rPin, red); 184 | analogWrite(bPin, blue); 185 | } 186 | 187 | void setCurrentColor(int red, int blue) { 188 | analogWrite(rPin2, red); 189 | analogWrite(bPin2, blue); 190 | } 191 | 192 | void setMinColor(int red, int blue) { 193 | analogWrite(rPin3, red); 194 | analogWrite(bPin3, blue); 195 | } 196 | 197 | void colorSwitchingStuff() { 198 | 199 | if (temperature <= 32) { 200 | setColor(0, 0, 255); 201 | } else if (temperature > 32 && temperature < 75) { 202 | setColor(255, 255, 0); 203 | } else { 204 | setColor(255, 0, 0); 205 | } 206 | 207 | if(hasPrecipitation) { 208 | delay(300); 209 | setColor(0, 0, 0); 210 | delay(100); 211 | } 212 | 213 | delay(500); 214 | /*if(temperature > 0) { 215 | }*/ 216 | 217 | temperature -= 10; 218 | 219 | if(temperature <= 32) { 220 | hasPrecipitation = true; 221 | } 222 | 223 | if(temperature < -50) { 224 | temperature = 100; 225 | hasPrecipitation = false; 226 | } 227 | 228 | delay(500); 229 | } 230 | -------------------------------------------------------------------------------- /lasote/arduino_http/http_client.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * http_client.cpp 3 | * 4 | * Created on: 28/03/2014 5 | * Author: laso 6 | */ 7 | 8 | #include "lasote/arduino_http/http_client.h" 9 | #include "lasote/stringutils/cstringutils.h" 10 | #include 11 | #include 12 | 13 | using namespace cstringutils; 14 | 15 | //#define DEBUGGING 1 16 | #define GET "GET" 17 | #define POST "POST" 18 | 19 | #ifdef DEBUGGING 20 | #define print_line(...) stream.println (__VA_ARGS__) 21 | #define print_string(...) stream.print (__VA_ARGS__) 22 | #else 23 | #define print_line(...) 0 24 | #define print_string(...) 0 25 | #endif 26 | 27 | namespace lasote { 28 | 29 | 30 | Header::Header(const char *name, const char* value) : name(name), value(value){ 31 | 32 | } 33 | Header::~Header(){ 34 | 35 | } 36 | 37 | 38 | HttpClient::HttpClient(Client& aClient, Stream& stream) : aClient(aClient), stream(stream){ 39 | } 40 | 41 | HttpClient::~HttpClient() { 42 | reset(); 43 | } 44 | 45 | void HttpClient::reset(){ 46 | //Deletes custom headers and reset processors 47 | for(int i=0; i < custom_headers.length; i++){ 48 | delete custom_headers[i]; 49 | } 50 | custom_headers.reset(); //empty list 51 | for(int i=0; i < processors.length; i++){ 52 | processors[i]->reset(); 53 | } 54 | } 55 | 56 | 57 | void HttpClient::add_custom_header(const char* name, const char* value){ 58 | Header* custom_header = new Header(name, value); 59 | custom_header->name = name; 60 | custom_header->value = value; 61 | custom_headers.add_item(custom_header); 62 | } 63 | 64 | void HttpClient::send_header(const char* header_name,const char* header_value){ 65 | aClient.print(header_name); 66 | aClient.print(": "); 67 | aClient.println(header_value); 68 | } 69 | 70 | void HttpClient::send_all_headers(const char* method, const char* host, const char* uri){ 71 | 72 | const char http[] = " HTTP/1.1"; 73 | const char labelhost[] = "Host: "; 74 | const char conn[] = "Connection: close"; 75 | print_string((char*) method); 76 | aClient.print(method); 77 | print_string(" "); 78 | aClient.print(" "); 79 | print_string((char*)uri); 80 | aClient.print(uri); 81 | print_line(http); 82 | aClient.println(http); 83 | print_string(labelhost); 84 | aClient.print(labelhost); 85 | print_line((char*)host); 86 | aClient.println(host); 87 | print_line((char*)conn); 88 | aClient.println(conn); 89 | 90 | //Add custom headers 91 | for(int i=0; i < custom_headers.length; i++){ 92 | Header* header = custom_headers[i]; 93 | print_string(header->name); 94 | print_string(": "); 95 | print_line(header->value); 96 | send_header(header->name, header->value); 97 | } 98 | 99 | print_line("Headers sent"); 100 | } 101 | 102 | void HttpClient::end_headers(){ 103 | aClient.write(0x0D); aClient.write(0x0A); 104 | } 105 | 106 | void HttpClient::end_request(){ 107 | aClient.write(0x0D); aClient.write(0x0A); 108 | aClient.flush(); 109 | } 110 | 111 | uint8_t HttpClient::get(IPAddress ip, const char *uri, uint16_t port){ 112 | uint8_t connected = aClient.connect(ip, port); 113 | if(aClient.connected()){ 114 | char host[17]; 115 | ip_to_string(ip, host); 116 | send_all_headers(GET, host, uri); 117 | end_request(); 118 | } 119 | return connected; 120 | } 121 | 122 | uint8_t HttpClient::get(const char *host, const char* uri, uint16_t port){ 123 | uint8_t connected = aClient.connect(host, port); 124 | if(aClient.connected()){ 125 | send_all_headers(GET, host, uri); 126 | end_request(); 127 | } 128 | return connected; 129 | } 130 | 131 | uint8_t HttpClient::post(IPAddress ip, const char *uri, const char *body, uint16_t port){ 132 | uint8_t connected = aClient.connect(ip, port); 133 | if(aClient.connected()){ 134 | char host[17]; 135 | ip_to_string(ip, host); 136 | send_all_headers(POST, host, uri); 137 | send_body(body); 138 | print_line(F("enviado")); 139 | } 140 | return connected; 141 | } 142 | 143 | uint8_t HttpClient::post(const char *host, const char* uri, const char *body, uint16_t port){ 144 | uint8_t connected = aClient.connect(host, port); 145 | if(aClient.connected()){ 146 | send_all_headers(POST, host, uri); 147 | send_body(body); 148 | print_line(F("enviado")); 149 | } 150 | return connected; 151 | } 152 | 153 | 154 | void HttpClient::send_body(const char* body){ 155 | char buff[10]; 156 | int_to_string(strlen(body), buff); 157 | send_header("Content-Length", buff); 158 | end_headers(); 159 | aClient.write((const uint8_t*) body, strlen(body)); 160 | //end_request(); 161 | } 162 | 163 | void HttpClient::send_body(Stream& body){ 164 | //Chunk size fixed to 20, TODO make configurable 165 | //Write header chunked before body 166 | send_header("Transfer-Encoding", "chunked"); 167 | end_headers(); 168 | static short int chunk_max_size = 20; 169 | 170 | char buff[chunk_max_size]; 171 | char chunk_size_hex[5]; 172 | 173 | while(1){ 174 | short int received = body.readBytes((char *)buff, chunk_max_size); 175 | sprintf(&chunk_size_hex[0], "%04x", received); 176 | 177 | aClient.write((const uint8_t*) chunk_size_hex, 4); aClient.write(0x0D); aClient.write(0x0A); 178 | aClient.write((const uint8_t*) buff, received); aClient.write(0x0D); aClient.write(0x0A); 179 | if(received < chunk_max_size){ 180 | break; 181 | } 182 | } 183 | aClient.write((const uint8_t*) "0", 1); aClient.write(0x0D); aClient.write(0x0A); 184 | end_request(); 185 | } 186 | 187 | 188 | void HttpClient::ip_to_string(IPAddress ip, char* buffer){ 189 | buffer[0] = '\0'; 190 | for(int i=0; i<4; i++){ 191 | char tmp[4]; 192 | int_to_string(ip[i], (char*) &tmp); 193 | if(i > 0){ 194 | append_to_string(buffer, '.', 16); 195 | } 196 | for(int j=0; j < strlen(tmp); j++){ 197 | append_to_string(buffer, tmp[j], 16); 198 | } 199 | } 200 | } 201 | 202 | uint8_t HttpClient::wait_for_response(unsigned int miliseconds){ 203 | int next = millis() + miliseconds; 204 | 205 | while(aClient.connected() && !aClient.available()){ 206 | int tmp = next - millis(); 207 | if (tmp < 0){ 208 | return RESPONSE_TIMEOUT; 209 | } 210 | } 211 | if(!aClient.connected()){ 212 | print_line(F("Not connected!")); 213 | return LOST_CONNECTION; 214 | } 215 | return true; 216 | } 217 | 218 | 219 | short int HttpClient::receive(){ 220 | unsigned char c[10]; 221 | //TODO let configure params 222 | unsigned int network_delay = 3 * 1000; // 3 seconds 223 | unsigned int response_delay = 1000 * 4; // 4 seconds 224 | // Whilst we haven't timed out & haven't reached the end of the body 225 | print_line(F("Wait for receive...")); 226 | aClient.flush(); 227 | if(!wait_for_response(response_delay)){ 228 | print_line(F("Response timeout!")); 229 | aClient.stop(); 230 | return RESPONSE_TIMEOUT; 231 | } 232 | 233 | HttpResponseProcessor http_response_processor; 234 | 235 | while(aClient.connected()){ 236 | 237 | if(!wait_for_response(response_delay)){ 238 | print_line(F("Response timeout on BODY!")); 239 | return RESPONSE_TIMEOUT; 240 | } 241 | int size = aClient.read((uint8_t*) c, 10); 242 | for(int i=0;iprocess_char(c[i]); 254 | } 255 | } 256 | else{ 257 | print_string((char)c[i]); 258 | } 259 | } 260 | 261 | if(http_response_processor.finished()){ 262 | break; 263 | } 264 | } 265 | 266 | if(!http_response_processor.finished()){ 267 | print_line(F("**Bad request")); 268 | aClient.stop(); 269 | return -1; 270 | } 271 | 272 | aClient.stop(); 273 | 274 | return http_response_processor.status_code; 275 | } 276 | } /* namespace arduino_http_client */ 277 | --------------------------------------------------------------------------------