├── .gitignore ├── LICENSE.md ├── README.md ├── examples └── SparkFun │ └── sparkfun.ino ├── keywords.txt ├── library.properties └── src ├── Phant.cpp └── Phant.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | License Information 3 | ------------------- 4 | 5 | The hardware is released under [Creative Commons Share-alike 3.0](http://creativecommons.org/licenses/by-sa/3.0/). 6 | 7 | All other code is open source so please feel free to do anything you want with it; you buy me a beer if you use this and we meet someday ([Beerware license](http://en.wikipedia.org/wiki/Beerware)). 8 | 9 | ->Additional Licenses and attributions to original authors as needed.<- 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Phant is No Longer in Operation 2 | 3 | Unfortunately Phant, our data-streaming service, is no longer in service 4 | and has been discontinued. The system has reached capacity and, like a less-adventurous Cassini, 5 | has plunged conclusively into a fiery and permanent retirement. There are several 6 | other maker-friendly, data-streaming services and/or IoT platforms available 7 | as alternatives. The three we recommend are Blynk, ThingSpeak, and Cayenne. 8 | You can read our [blog post on the topic](https://www.sparkfun.com/news/2413) 9 | for an overview and helpful links for each platform. 10 | 11 | All secondary SparkFun repositories related to Phant have been [archived](https://github.com/blog/2460-archiving-repositories) 12 | and pulled in as a subtree in the main [Phant GitHub repository](https://github.com/sparkfun/phant/tree/master/archived_PhantRepos). 13 | 14 | --- 15 | 16 | # phant-arduino 17 | 18 | The goal of this library is to provide a simple interface for logging data to phant. 19 | It should take any data type, convert it to a `String`, and build a url. This 20 | library will not handle interaction with WiFi or ethernet shields, it's only purpose is 21 | to make it easier for users to build phant compatible requests without worrying about data 22 | types and string concatenation. 23 | 24 | ## Installation 25 | 26 | **Linux & Mac:** 27 | ```bash 28 | $ cd ~ 29 | $ git clone git@github.com:sparkfun/phant-arduino.git 30 | $ ln -s ~/phant-arduino/Phant/ ~/Documents/Arduino/libraries/Phant 31 | ``` 32 | 33 | **Windows:** :cry: 34 | 35 | ## Usage 36 | 37 | To create a new instance of the request builder, pass the server's `hostname`, your `public key`, 38 | and your `private key` to the `Phant` constructor. 39 | 40 | ``` 41 | Phant phant("data.sparkfun.com", "VGb2Y1jD4VIxjX3x196z", "9YBaDk6yeMtNErDNq4YM"); 42 | ``` 43 | 44 | To add data, you can make calls to `phant.add(key, value)`. The library will convert any value data type 45 | to a string, so there is no need for conversion before sending data. For example, if you have a stream 46 | with fields titled `wind`, `temp`, and `raining`, your code would add data to the request like this: 47 | 48 | ``` 49 | phant.add("wind", 12.0); 50 | phant.add("temp", 70.1); 51 | phant.add("raining", false); 52 | ``` 53 | 54 | To get the request string for adding data, you have two options `phant.url()` and `phant.post()`. 55 | Both methods will clear the current request data after building and returning the current request. Unless 56 | there is some compelling reason to do otherwise, you should always use `phant.post()` to get a 57 | [HTTP POST](http://en.wikipedia.org/wiki/POST_(HTTP)) request string. `phant.url()` will return a URL that you 58 | can use in your web browser to test data logging. 59 | 60 | In this example `client` would be an instance of whatever ethernet library you are using: 61 | 62 | ``` 63 | client.println(phant.post()); 64 | ``` 65 | 66 | To clear all of the data in your stream, you can use `phant.clear()` to get a `HTTP DELETE` request string. Clearing the 67 | data will not delete the stream definition, it will only delete the logged data. 68 | 69 | ``` 70 | client.println(phant.clear()); 71 | ``` 72 | 73 | If you would like to retrieve your logged data, `phant.get()` will return a [HTTP GET](http://en.wikipedia.org/wiki/GET_(HTTP)) 74 | request string that will cause the server to respond with your logged data in [CSV](http://en.wikipedia.org/wiki/Comma-separated_values) 75 | format. Parsing CSV is outside of the scope of this library. 76 | 77 | ``` 78 | client.println(phant.get()); 79 | ``` 80 | 81 | ## Output Example 82 | 83 | ### Sketch 84 | 85 | ```ino 86 | #include 87 | 88 | // Arduino example stream 89 | // http://data.sparkfun.com/streams/VGb2Y1jD4VIxjX3x196z 90 | // hostname, public key, private key 91 | Phant phant("data.sparkfun.com", "VGb2Y1jD4VIxjX3x196z", "9YBaDk6yeMtNErDNq4YM"); 92 | 93 | void setup() { 94 | Serial.begin(9600); 95 | } 96 | 97 | void loop() { 98 | 99 | phant.add("val1", "url"); 100 | phant.add("val2", 22); 101 | phant.add("val3", 0.1234); 102 | 103 | Serial.println("----TEST URL-----"); 104 | Serial.println(phant.url()); 105 | 106 | Serial.println(); 107 | 108 | phant.add("val1", "post"); 109 | phant.add("val2", false); 110 | phant.add("val3", 98.6); 111 | 112 | Serial.println("----HTTP POST----"); 113 | Serial.println(phant.post()); 114 | 115 | Serial.println(); 116 | 117 | Serial.println("----HTTP GET----"); 118 | Serial.println(phant.get()); 119 | 120 | Serial.println("----HTTP DELETE----"); 121 | Serial.println(phant.clear()); 122 | 123 | delay(2000); 124 | 125 | } 126 | ``` 127 | 128 | ### Output 129 | 130 | This example prints the following to the serial monitor: 131 | 132 | ``` 133 | ----TEST URL----- 134 | http://data.sparkfun.com/input/VGb2Y1jD4VIxjX3x196z.txt?private_key=9YBaDk6yeMtNErDNq4YM&val1=url&val2=22&val3=0.1234 135 | 136 | ----HTTP POST---- 137 | POST /input/VGb2Y1jD4VIxjX3x196z.txt HTTP/1.1 138 | Host: data.sparkfun.com 139 | Connection: close 140 | Content-Type: application/x-www-form-urlencoded 141 | Content-Length: 29 142 | 143 | val1=post&val2=0&val3=98.6000 144 | 145 | ----HTTP GET---- 146 | GET /output/VGb2Y1jD4VIxjX3x196z.csv HTTP/1.1 147 | Host: data.sparkfun.com 148 | Connection: close 149 | 150 | ----HTTP DELETE---- 151 | DELETE /input/VGb2Y1jD4VIxjX3x196z/clear.txt HTTP/1.1 152 | Host: data.sparkfun.com 153 | Phant-Private-Key: 9YBaDk6yeMtNErDNq4YM 154 | Connection: close 155 | ``` 156 | -------------------------------------------------------------------------------- /examples/SparkFun/sparkfun.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Arduino example stream 4 | // http://data.sparkfun.com/streams/VGb2Y1jD4VIxjX3x196z 5 | // host, public key, private key 6 | Phant phant("data.sparkfun.com", "VGb2Y1jD4VIxjX3x196z", "9YBaDk6yeMtNErDNq4YM"); 7 | 8 | void setup() { 9 | Serial.begin(9600); 10 | } 11 | 12 | void loop() { 13 | 14 | phant.add("val1", "url"); 15 | phant.add("val2", 22); 16 | phant.add("val3", 0.1234); 17 | 18 | Serial.println("----TEST URL-----"); 19 | Serial.println(phant.url()); 20 | 21 | Serial.println(); 22 | 23 | phant.add("val1", "post"); 24 | phant.add("val2", false); 25 | phant.add("val3", 98.6); 26 | 27 | Serial.println("----HTTP POST----"); 28 | Serial.println(phant.post()); 29 | 30 | Serial.println(); 31 | 32 | Serial.println("----HTTP GET----"); 33 | Serial.println(phant.get()); 34 | 35 | Serial.println("----HTTP DELETE----"); 36 | Serial.println(phant.clear()); 37 | 38 | delay(2000); 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | Phant KEYWORD1 2 | add KEYWORD2 3 | queryString KEYWORD2 4 | url KEYWORD2 5 | get KEYWORD2 6 | post KEYWORD2 7 | clear KEYWORD2 8 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Phant 2 | version=2.2.0 3 | author=SparkFun Electronics 4 | maintainer=SparkFun Electronics 5 | sentence=A simple interface to post data to a phant stream. 6 | paragraph=A simple interface to post, get, or clear data from a Phant stream (data.sparkfun.com). 7 | category=Other 8 | url=https://github.com/sparkfun/phant-arduino 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/Phant.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Phant.cpp 3 | * 4 | * .-.._ 5 | * __ /` '. 6 | * .-' `/ ( a \ 7 | * / ( \,_ \ 8 | * /| '---` |\ =| 9 | * ` \ /__.-/ / | | 10 | * | / / \ \ \ \_\ jgs 11 | * |__|_| |_|__\ 12 | * never forget. 13 | * 14 | * Author: Todd Treece 15 | * 16 | * Copyright (c) 2014 SparkFun Electronics. 17 | * Licensed under the GPL v3 license. 18 | * 19 | */ 20 | 21 | #include "Arduino.h" 22 | #include "Phant.h" 23 | 24 | #ifdef ARDUINO_ARCH_AVR 25 | #include 26 | #else 27 | #include "pgmspace.h" 28 | #endif 29 | 30 | static const char HEADER_POST_URL1[] PROGMEM = "POST /input/"; 31 | static const char HEADER_POST_URL2[] PROGMEM = ".txt HTTP/1.1\n"; 32 | static const char HEADER_PHANT_PRV_KEY[] PROGMEM = "Phant-Private-Key: "; 33 | static const char HEADER_CONNECTION_CLOSE[] PROGMEM = "Connection: close\n"; 34 | static const char HEADER_CONTENT_TYPE[] PROGMEM = "Content-Type: application/x-www-form-urlencoded\n"; 35 | static const char HEADER_CONTENT_LENGTH[] PROGMEM = "Content-Length: "; 36 | 37 | Phant::Phant(String host, String publicKey, String privateKey) { 38 | _host = host; 39 | _pub = publicKey; 40 | _prv = privateKey; 41 | _params = ""; 42 | } 43 | 44 | void Phant::add(String field, String data) { 45 | 46 | _params += "&" + field + "=" + data; 47 | 48 | } 49 | 50 | void Phant::add(const __FlashStringHelper *field, String data) { 51 | 52 | _params += "&"; 53 | addFlashString(field, _params); 54 | _params += "=" + data; 55 | 56 | } 57 | 58 | 59 | void Phant::add(String field, char data) { 60 | 61 | _params += "&" + field + "=" + String(data); 62 | 63 | } 64 | 65 | void Phant::add(const __FlashStringHelper *field, char data) { 66 | 67 | _params += "&"; 68 | addFlashString(field, _params); 69 | _params += "=" + String(data); 70 | 71 | } 72 | 73 | 74 | void Phant::add(String field, int data) { 75 | 76 | _params += "&" + field + "=" + String(data); 77 | 78 | } 79 | 80 | void Phant::add(const __FlashStringHelper *field, int data) { 81 | 82 | _params += "&"; 83 | addFlashString(field, _params); 84 | _params += '=' + String(data); 85 | 86 | } 87 | 88 | 89 | void Phant::add(String field, byte data) { 90 | 91 | _params += "&" + field + "=" + String(data); 92 | 93 | } 94 | 95 | void Phant::add(const __FlashStringHelper * field, byte data) { 96 | 97 | _params += "&"; 98 | addFlashString(field, _params); 99 | _params += "=" + String(data); 100 | 101 | } 102 | 103 | 104 | void Phant::add(String field, long data) { 105 | 106 | _params += "&" + field + "=" + String(data); 107 | 108 | } 109 | 110 | void Phant::add(const __FlashStringHelper * field, long data) { 111 | 112 | _params += "&"; 113 | addFlashString(field, _params); 114 | _params += "=" + String(data); 115 | 116 | } 117 | 118 | void Phant::add(String field, unsigned int data) { 119 | 120 | _params += "&" + field + "=" + String(data); 121 | 122 | } 123 | 124 | void Phant::add(const __FlashStringHelper * field, unsigned int data) { 125 | 126 | _params += "&"; 127 | addFlashString(field, _params); 128 | _params += "=" + String(data); 129 | 130 | } 131 | 132 | 133 | void Phant::add(String field, unsigned long data) { 134 | 135 | _params += "&" + field + "=" + String(data); 136 | 137 | } 138 | 139 | void Phant::add(const __FlashStringHelper * field, unsigned long data) { 140 | 141 | _params += "&"; 142 | addFlashString(field, _params); 143 | _params += "=" + String(data); 144 | 145 | } 146 | 147 | 148 | void Phant::add(String field, double data) { 149 | 150 | char tmp[30]; 151 | 152 | dtostrf(data, 1, 4, tmp); 153 | 154 | _params += "&" + field + "=" + String(tmp); 155 | 156 | } 157 | 158 | void Phant::add(const __FlashStringHelper * field, double data) { 159 | 160 | char tmp[30]; 161 | 162 | dtostrf(data, 1, 4, tmp); 163 | 164 | _params += "&"; 165 | addFlashString(field, _params); 166 | _params += "=" + String(tmp); 167 | 168 | } 169 | 170 | void Phant::add(String field, float data) { 171 | 172 | char tmp[30]; 173 | 174 | dtostrf(data, 1, 4, tmp); 175 | 176 | _params += "&" + field + "=" + String(tmp); 177 | 178 | } 179 | 180 | void Phant::add(const __FlashStringHelper * field, float data) { 181 | 182 | char tmp[30]; 183 | 184 | dtostrf(data, 1, 4, tmp); 185 | 186 | _params += "&"; 187 | addFlashString(field, _params); 188 | _params += "=" + String(tmp); 189 | 190 | } 191 | 192 | String Phant::queryString() { 193 | return String(_params); 194 | } 195 | 196 | String Phant::url() { 197 | 198 | String result = "http://" + _host + "/input/" + _pub + ".txt"; 199 | result += "?private_key=" + _prv + _params; 200 | 201 | _params = ""; 202 | 203 | return result; 204 | 205 | } 206 | 207 | String Phant::get() { 208 | 209 | String result = "GET /output/" + _pub + ".csv HTTP/1.1\n"; 210 | result += "Host: " + _host + "\n"; 211 | result += "Connection: close\n"; 212 | 213 | return result; 214 | 215 | } 216 | 217 | String Phant::post() { 218 | 219 | String params = _params.substring(1); 220 | String result; 221 | //String result = "POST /input/" + _pub + ".txt HTTP/1.1\n"; 222 | for (int i=0; i(string); 275 | size_t n = 0; 276 | while (1) 277 | { 278 | unsigned char c = pgm_read_byte(p++); 279 | if (c == 0) break; 280 | dest += (char)c; 281 | } 282 | 283 | } -------------------------------------------------------------------------------- /src/Phant.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Phant.h 3 | * 4 | * .-.._ 5 | * __ /` '. 6 | * .-' `/ ( a \ 7 | * / ( \,_ \ 8 | * /| '---` |\ =| 9 | * ` \ /__.-/ / | | 10 | * | / / \ \ \ \_\ jgs 11 | * |__|_| |_|__\ 12 | * never forget. 13 | * 14 | * Author: Todd Treece 15 | * 16 | * Copyright (c) 2014 SparkFun Electronics. 17 | * Licensed under the GPL v3 license. 18 | * 19 | */ 20 | 21 | #ifndef Phant_h 22 | #define Phant_h 23 | 24 | #include "Arduino.h" 25 | 26 | class Phant { 27 | 28 | public: 29 | Phant(String host, String publicKey, String privateKey); 30 | void add(String field, String data); 31 | void add(String field, char data); 32 | void add(String field, int data); 33 | void add(String field, byte data); 34 | void add(String field, long data); 35 | void add(String field, unsigned int data); 36 | void add(String field, unsigned long data); 37 | void add(String field, float data); 38 | void add(String field, double data); 39 | 40 | void add(const __FlashStringHelper * field, String data); 41 | void add(const __FlashStringHelper * field, char data); 42 | void add(const __FlashStringHelper * field, int data); 43 | void add(const __FlashStringHelper * field, byte data); 44 | void add(const __FlashStringHelper * field, long data); 45 | void add(const __FlashStringHelper * field, unsigned int data); 46 | void add(const __FlashStringHelper * field, unsigned long data); 47 | void add(const __FlashStringHelper * field, float data); 48 | void add(const __FlashStringHelper * field, double data); 49 | 50 | String queryString(); 51 | String url(); 52 | String get(); 53 | String post(); 54 | String clear(); 55 | 56 | private: 57 | String _pub; 58 | String _prv; 59 | String _host; 60 | String _params; 61 | 62 | void addFlashString(const __FlashStringHelper *string, String & dest); 63 | }; 64 | 65 | #endif 66 | --------------------------------------------------------------------------------